mirror of
https://github.com/subsurface/subsurface.git
synced 2024-12-01 06:30:26 +00:00
1fc4fba69f
Maintab is one of our most complex classes, and it's something I'm not actually proud of. But it currently works and the idea of splitting it was in my head for quite a while. This is the third or fourth tentative of splitting it, and this time I let the most complex part of it untouched, the Notes and Equipment tab are way too complex to untangle right now on my limited time. A new class 'TabBase' should be used for any new tab that we may create, and added on the MainTab (see the new lines on the MainTab constructor). Also, Extra Info, Information, Photos and Statistics where ported to this new way helping reduce the number of lines and functions on the MainTab quite a bit. Overall this is a step in the right direction for the future. Signed-off-by: Tomaz Canabrava <tcanabrava@kde.org> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
210 lines
5.5 KiB
C++
210 lines
5.5 KiB
C++
#include "tagwidget.h"
|
|
#include "mainwindow.h"
|
|
#include "tab-widgets/maintab.h"
|
|
#include <QCompleter>
|
|
|
|
TagWidget::TagWidget(QWidget *parent) : GroupedLineEdit(parent), m_completer(NULL), lastFinishedTag(false)
|
|
{
|
|
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 bright 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(completionHighlighted(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);
|
|
}
|
|
|
|
void TagWidget::highlight()
|
|
{
|
|
removeAllBlocks();
|
|
int lastPos = 0;
|
|
Q_FOREACH (const QString& s, text().split(QChar(','), QString::SkipEmptyParts)) {
|
|
QString trimmed = s.trimmed();
|
|
if (trimmed.isEmpty())
|
|
continue;
|
|
int start = text().indexOf(trimmed, lastPos);
|
|
addBlock(start, trimmed.size() + start);
|
|
lastPos = trimmed.size() + start;
|
|
}
|
|
}
|
|
|
|
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();
|
|
|
|
/*
|
|
* Do not show the completer when not in edit mode - basically
|
|
* this returns when we are accepting or discarding the changes.
|
|
*/
|
|
if (MainWindow::instance()->information()->isEditing() == false || currentText.length() == 0) {
|
|
return;
|
|
}
|
|
|
|
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(const QString &completion)
|
|
{
|
|
completionHighlighted(completion);
|
|
emit textChanged();
|
|
}
|
|
|
|
void TagWidget::completionHighlighted(const QString &completion)
|
|
{
|
|
QPair<int, int> pos = getCursorTagPosition();
|
|
setText(text().remove(pos.first, pos.second - pos.first).insert(pos.first, completion));
|
|
setCursorPosition(pos.first + completion.length());
|
|
}
|
|
|
|
void TagWidget::setCursorPosition(int position)
|
|
{
|
|
blockSignals(true);
|
|
GroupedLineEdit::setCursorPosition(position);
|
|
blockSignals(false);
|
|
}
|
|
|
|
void TagWidget::setText(const QString &text)
|
|
{
|
|
blockSignals(true);
|
|
GroupedLineEdit::setText(text);
|
|
blockSignals(false);
|
|
highlight();
|
|
}
|
|
|
|
void TagWidget::clear()
|
|
{
|
|
blockSignals(true);
|
|
GroupedLineEdit::clear();
|
|
blockSignals(false);
|
|
}
|
|
|
|
void TagWidget::keyPressEvent(QKeyEvent *e)
|
|
{
|
|
QPair<int, int> pos;
|
|
QAbstractItemView *popup;
|
|
bool finishedTag = false;
|
|
switch (e->key()) {
|
|
case Qt::Key_Escape:
|
|
pos = getCursorTagPosition();
|
|
if (pos.first >= 0 && pos.second > 0) {
|
|
setText(text().remove(pos.first, pos.second - pos.first));
|
|
setCursorPosition(pos.first);
|
|
}
|
|
popup = m_completer->popup();
|
|
if (popup)
|
|
popup->hide();
|
|
return;
|
|
case Qt::Key_Return:
|
|
case Qt::Key_Enter:
|
|
case Qt::Key_Tab:
|
|
/*
|
|
* Fake the QLineEdit behaviour by simply
|
|
* closing the QAbstractViewitem
|
|
*/
|
|
if (m_completer) {
|
|
popup = m_completer->popup();
|
|
if (popup)
|
|
popup->hide();
|
|
}
|
|
finishedTag = true;
|
|
break;
|
|
case Qt::Key_Comma: { /* if this is the last key, and the previous string is empty, ignore the comma. */
|
|
QString temp = text();
|
|
if (temp.split(QChar(',')).last().trimmed().isEmpty()){
|
|
e->ignore();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
if (e->key() == Qt::Key_Tab && lastFinishedTag) { // if we already end in comma, go to next/prev field
|
|
MainWindow::instance()->information()->nextInputField(e); // by sending the key event to the MainTab widget
|
|
} else if (e->key() == Qt::Key_Tab || e->key() == Qt::Key_Return) { // otherwise let's pretend this is a comma instead
|
|
QKeyEvent fakeEvent(e->type(), Qt::Key_Comma, e->modifiers(), QString(","));
|
|
keyPressEvent(&fakeEvent);
|
|
} else {
|
|
GroupedLineEdit::keyPressEvent(e);
|
|
}
|
|
lastFinishedTag = finishedTag;
|
|
}
|
|
|
|
void TagWidget::wheelEvent(QWheelEvent *event)
|
|
{
|
|
if (hasFocus()) {
|
|
GroupedLineEdit::wheelEvent(event);
|
|
}
|
|
}
|
|
|
|
void TagWidget::fixPopupPosition(int delta)
|
|
{
|
|
if(m_completer->popup()->isVisible()){
|
|
QRect toGlobal = m_completer->popup()->geometry();
|
|
m_completer->popup()->setGeometry(toGlobal.x(), toGlobal.y() + delta +10, toGlobal.width(), toGlobal.height());
|
|
}
|
|
}
|