mirror of
https://github.com/subsurface/subsurface.git
synced 2024-11-28 13:10:19 +00:00
ec1088f2cc
This prevents tags widgets (dive tags and buddy) from grabbing
focus on mouse wheel events but allows entering dive edit mode
on mouse click.
It was attempted earlier by Dirk (commit d117beca
), but edit mode
did not work properly.
Signed-off-by: Sergey Starosek <sergey.starosek@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
195 lines
4.7 KiB
C++
195 lines
4.7 KiB
C++
#include "tagwidget.h"
|
|
#include <QPair>
|
|
#include <QDebug>
|
|
#include <QAbstractItemView>
|
|
#include <QSettings>
|
|
#include <QFont>
|
|
|
|
TagWidget::TagWidget(QWidget *parent) : GroupedLineEdit(parent), m_completer(NULL)
|
|
{
|
|
connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(reparse()));
|
|
connect(this, SIGNAL(textChanged()), this, SLOT(reparse()));
|
|
|
|
QColor textColor = palette().color(QPalette::Text);
|
|
qreal h, s, l, a;
|
|
textColor.getHslF(&h, &s, &l, &a);
|
|
// I use dark themes
|
|
if (l <= 0.3 ) { // very dark text. get a brigth background
|
|
addColor( QColor(Qt::red).lighter(120) );
|
|
addColor( QColor(Qt::green).lighter(120) );
|
|
addColor( QColor(Qt::blue).lighter(120) );
|
|
} else if ( l <= 0.6 ) { // moderated dark text. get a somewhat brigth background
|
|
addColor( QColor(Qt::red).lighter(60) );
|
|
addColor( QColor(Qt::green).lighter(60) );
|
|
addColor( QColor(Qt::blue).lighter(60) );
|
|
} else {
|
|
addColor( QColor(Qt::red).darker(120) );
|
|
addColor( QColor(Qt::green).darker(120) );
|
|
addColor( QColor(Qt::blue).darker(120) );
|
|
} // light text. get a dark background.
|
|
setFocusPolicy(Qt::StrongFocus);
|
|
}
|
|
|
|
void TagWidget::setCompleter(QCompleter *completer)
|
|
{
|
|
m_completer = completer;
|
|
m_completer->setWidget(this);
|
|
connect(m_completer, SIGNAL(activated(QString)), this, SLOT(completionSelected(QString)));
|
|
connect(m_completer, SIGNAL(highlighted(QString)), this, SLOT(completionSelected(QString)));
|
|
}
|
|
|
|
QPair<int,int> TagWidget::getCursorTagPosition() {
|
|
int i = 0, start = 0, end = 0;
|
|
/* Parse string near cursor */
|
|
i = cursorPosition();
|
|
while (--i > 0) {
|
|
if (text().at(i) == ',') {
|
|
if (i > 0 && text().at(i-1) != '\\') {
|
|
i++;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
start = i;
|
|
while (++i < text().length()) {
|
|
if (text().at(i) == ',') {
|
|
if (i > 0 && text().at(i-1) != '\\')
|
|
break;
|
|
}
|
|
}
|
|
end = i;
|
|
if (start < 0 || end < 0) {
|
|
start = 0;
|
|
end = 0;
|
|
}
|
|
return qMakePair(start,end);
|
|
}
|
|
|
|
enum ParseState {FINDSTART, FINDEND};
|
|
|
|
void TagWidget::highlight() {
|
|
int i = 0, start = 0, end = 0;
|
|
ParseState state = FINDEND;
|
|
removeAllBlocks();
|
|
|
|
while(i < text().length()) {
|
|
if (text().at(i) == ',') {
|
|
if (state == FINDSTART) {
|
|
/* Detect empty tags */
|
|
} else if (state == FINDEND) {
|
|
/* Found end of tag */
|
|
if (i > 1) {
|
|
if (text().at(i-1) != '\\') {
|
|
addBlock(start, end);
|
|
state = FINDSTART;
|
|
}
|
|
} else {
|
|
state = FINDSTART;
|
|
}
|
|
}
|
|
} else if (text().at(i) == ' ') {
|
|
/* Handled */
|
|
} else {
|
|
/* Found start of tag */
|
|
if (state == FINDSTART) {
|
|
state = FINDEND;
|
|
start = i;
|
|
} else if (state == FINDEND) {
|
|
end = i;
|
|
}
|
|
}
|
|
i++;
|
|
}
|
|
if (state == FINDEND) {
|
|
if (end < start)
|
|
end = text().length()-1;
|
|
if (text().length() > 0)
|
|
addBlock(start, end);
|
|
}
|
|
}
|
|
|
|
void TagWidget::reparse()
|
|
{
|
|
highlight();
|
|
QPair<int,int> pos = getCursorTagPosition();
|
|
QString currentText;
|
|
if (pos.first >= 0 && pos.second > 0)
|
|
currentText = text().mid(pos.first, pos.second-pos.first).trimmed();
|
|
else
|
|
currentText = "";
|
|
if (m_completer) {
|
|
m_completer->setCompletionPrefix(currentText);
|
|
if (m_completer->completionCount() == 1) {
|
|
if (m_completer->currentCompletion() == currentText) {
|
|
QAbstractItemView *popup = m_completer->popup();
|
|
if (popup)
|
|
popup->hide();
|
|
} else {
|
|
m_completer->complete();
|
|
}
|
|
} else {
|
|
m_completer->complete();
|
|
}
|
|
}
|
|
}
|
|
|
|
void TagWidget::completionSelected(QString completion) {
|
|
QPair <int,int> pos;
|
|
pos = getCursorTagPosition();
|
|
if (pos.first >= 0 && pos.second > 0) {
|
|
setText(text().remove(pos.first, pos.second-pos.first).insert(pos.first, completion));
|
|
setCursorPosition(pos.first+completion.length());
|
|
} else {
|
|
setText(completion.append(", "));
|
|
setCursorPosition(text().length());
|
|
}
|
|
emit(textChanged());
|
|
}
|
|
|
|
void TagWidget::setCursorPosition(int position) {
|
|
blockSignals(true);
|
|
GroupedLineEdit::setCursorPosition(position);
|
|
blockSignals(false);
|
|
}
|
|
|
|
void TagWidget::setText(QString text) {
|
|
blockSignals(true);
|
|
GroupedLineEdit::setText(text);
|
|
blockSignals(false);
|
|
highlight();
|
|
}
|
|
|
|
void TagWidget::clear() {
|
|
blockSignals(true);
|
|
GroupedLineEdit::clear();
|
|
blockSignals(false);
|
|
}
|
|
|
|
void TagWidget::keyPressEvent(QKeyEvent *e) {
|
|
switch (e->key()) {
|
|
case Qt::Key_Return:
|
|
case Qt::Key_Enter:
|
|
case Qt::Key_Tab:
|
|
/*
|
|
* Fake the QLineEdit behaviour by simply
|
|
* closing the QAbstractViewitem
|
|
*/
|
|
if (m_completer) {
|
|
QAbstractItemView *popup = m_completer->popup();
|
|
if (popup)
|
|
popup->hide();
|
|
}
|
|
}
|
|
if (e->key() == Qt::Key_Tab) { // let's pretend this is a comma instead
|
|
QKeyEvent fakeEvent(e->type(), Qt::Key_Comma, e->modifiers(), QString(","));
|
|
GroupedLineEdit::keyPressEvent(&fakeEvent);
|
|
} else {
|
|
GroupedLineEdit::keyPressEvent(e);
|
|
}
|
|
}
|
|
|
|
void TagWidget::wheelEvent(QWheelEvent *event) {
|
|
if (hasFocus()) {
|
|
GroupedLineEdit::wheelEvent(event);
|
|
}
|
|
}
|