diff --git a/libs/widgets/qcodeedit.cpp b/libs/widgets/qcodeedit.cpp index ae068fb..582f7ca 100644 --- a/libs/widgets/qcodeedit.cpp +++ b/libs/widgets/qcodeedit.cpp @@ -1,4 +1,5 @@ #include "qcodeedit.h" +#include "qcodeedit_completer_p.h" #include #include #include @@ -9,7 +10,6 @@ #include #include #include -#include #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) # include #endif @@ -54,21 +54,7 @@ QCodeEdit::QCodeEdit(QWidget * parent): QWidget(parent) { } lbl_help[1]->setIcon(QIcon(":/icons/f1.png")); lbl_help[1]->setText(tr("Press F1 for details")); - completer = new QTreeWidget(); - completer->setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); - completer->setFocusPolicy(Qt::NoFocus); - completer->setColumnCount(2); - completer->setRootIsDecorated(false); - completer->setHeaderHidden(true); - completer->header()->setDefaultAlignment(Qt::AlignCenter); - completer->header()-> -#if (QT_VERSION >= 0x050000) - setSectionResizeMode -#else - setResizeMode -#endif - (QHeaderView::ResizeToContents); -// completer->header()->setStretchLastSection(true); + completer = new QCodeEditCompleter(); ui->textCode->setCursorWidth(qMax(qRound(fontHeight() / 10.), 1)); ui->textLines->viewport()->setAutoFillBackground(false); @@ -447,7 +433,7 @@ bool QCodeEdit::eventFilter(QObject * o, QEvent * e) { break; case Qt::Key_Up: if (completer->isVisible()) { - previousCompletition(); + completer->previousCompletition(); return true; } completer->hide(); @@ -463,7 +449,7 @@ bool QCodeEdit::eventFilter(QObject * o, QEvent * e) { break; case Qt::Key_Down: if (completer->isVisible()) { - nextCompletition(); + completer->nextCompletition(); return true; } completer->hide(); @@ -646,30 +632,6 @@ void QCodeEdit::applyExtraSelection() { } -void QCodeEdit::nextCompletition() { - int ci = completer->currentIndex().row(); - if (ci >= completer->topLevelItemCount() - 1) return; - if (completer->topLevelItem(ci + 1)->flags().testFlag(Qt::ItemIsSelectable)) - completer->setCurrentItem(completer->topLevelItem(ci + 1)); - else { - if (ci >= completer->topLevelItemCount() - 2) return; - completer->setCurrentItem(completer->topLevelItem(ci + 2)); - } -} - - -void QCodeEdit::previousCompletition() { - int ci = completer->currentIndex().row(); - if (ci <= 0) return; - if (completer->topLevelItem(ci - 1)->flags().testFlag(Qt::ItemIsSelectable)) - completer->setCurrentItem(completer->topLevelItem(ci - 1)); - else { - if (ci <= 1) return; - completer->setCurrentItem(completer->topLevelItem(ci - 2)); - } -} - - void QCodeEdit::clearSearch() { es_search_list.clear(); applyExtraSelection(); @@ -1275,47 +1237,16 @@ void QCodeEdit::invokeAutoCompletition(bool force) { foreach (const ACPair & ac, acl) { if (ac.second.isEmpty()) continue; ACClass acc = ac_classes.value(ac.first); - QTreeWidgetItem * gi = new QTreeWidgetItem(); - gi->setText(0, acc.name); - gi->setTextAlignment(0, Qt::AlignCenter); - gi->setTextAlignment(1, Qt::AlignCenter); - gi->setFont(0, bf); - gi->setBackground(0, Qt::lightGray); - gi->setFlags(Qt::ItemIsEnabled); - completer->addTopLevelItem(gi); - gi->setFirstColumnSpanned(true); - foreach (const StringsPair & s, ac.second) { - QTreeWidgetItem * ni = new QTreeWidgetItem(); - ni->setIcon(0, acc.icon); - ni->setText(0, s.first); - ni->setText(1, s.second); - completer->addTopLevelItem(ni); - } + completer->addItems(bf, acc, ac); } - if (completer->topLevelItemCount() > 1) - completer->setCurrentItem(completer->topLevelItem(1)); - if (completer->isHidden()) - completer->move(ui->textCode->mapToGlobal(ui->textCode->cursorRect().bottomRight())); - if (completer->topLevelItemCount() > 0) { - completer->setVisible(true); - //qApp->processEvents(); - int sz = completer->verticalScrollBar()->width(); - sz += completer->sizeHint().width(); -// int sz = ((QAbstractItemView*)completer)->viewport()->width(); -// for (int i = 0; i < completer->header()->count(); ++i) { -// completer->resizeColumnToContents(i); -// sz += completer->columnWidth(i); -// } - completer->resize(sz, fontHeight() * 16); - } else - completer->hide(); + completer->invoke(ui->textCode->mapToGlobal(ui->textCode->cursorRect().bottomRight())); } void QCodeEdit::commitCompletition() { if (completer->currentItem() == 0) return; if (!completer->currentItem()->flags().testFlag(Qt::ItemIsSelectable)) return; - QString ins = completer->currentItem()->text(1), ret = completer->currentItem()->text(0); + QString ins = completer->currentValue(), ret = completer->currentReturn(); QTextCursor tc = ui->textCode->textCursor(), stc = tc; tc.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor); bool ins_br = true, shifted = false; @@ -1355,16 +1286,16 @@ void QCodeEdit::commitCompletition() { tc.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 2); } } - if (ins.endsWith(")") && !completer->currentItem()->text(1).endsWith("()")) { + if (ins.endsWith(")") && !completer->currentValue().endsWith("()")) { tc.movePosition(QTextCursor::Left); ui->textCode->setTextCursor(tc); } } else { - if (completer->currentItem()->text(1).endsWith(")")) { + if (completer->currentValue().endsWith(")")) { tc.movePosition(QTextCursor::Right); ui->textCode->setTextCursor(tc); } - if (completer->currentItem()->text(1).endsWith("()")) { + if (completer->currentValue().endsWith("()")) { tc.movePosition(QTextCursor::Right); ui->textCode->setTextCursor(tc); } diff --git a/libs/widgets/qcodeedit.h b/libs/widgets/qcodeedit.h index a5e31d8..dd8a599 100644 --- a/libs/widgets/qcodeedit.h +++ b/libs/widgets/qcodeedit.h @@ -31,6 +31,8 @@ namespace Ui { class QCodeEdit; } +class QCodeEditCompleter; + class QAD_WIDGETS_EXPORT QCodeEdit: public QWidget { @@ -40,6 +42,8 @@ class QAD_WIDGETS_EXPORT QCodeEdit: public QWidget Q_PROPERTY(bool showLineNumbers READ showLineNumbers WRITE setShowLineNumbers) Q_PROPERTY(bool wordCompletitionEnabled READ wordCompletitionEnabled WRITE setWordCompletitionEnabled) Q_PROPERTY(QFont editorFont READ editorFont WRITE setEditorFont) + + friend class QCodeEditCompleter; public: QCodeEdit(QWidget * parent = 0); @@ -105,7 +109,7 @@ private: QIcon icon; }; - QTreeWidget * completer; + QCodeEditCompleter * completer; IconedLabel * lbl_help[2]; QFrame * widget_help; QTextEdit::ExtraSelection es_line, es_cursor, es_bracket, es_range, es_search; @@ -123,8 +127,6 @@ private: void changeEvent(QEvent * e); void highlightBrackets(); void applyExtraSelection(); - void nextCompletition(); - void previousCompletition(); void clearSearch(); void moveToSearch(); int searchIndFromCursor(); diff --git a/libs/widgets/qcodeedit_completer_p.cpp b/libs/widgets/qcodeedit_completer_p.cpp new file mode 100644 index 0000000..7d8a02f --- /dev/null +++ b/libs/widgets/qcodeedit_completer_p.cpp @@ -0,0 +1,106 @@ +#include "qcodeedit_completer_p.h" +#include + + +QCodeEditCompleter::QCodeEditCompleter(QWidget * parent): QTreeWidget(parent) { + setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); + setFocusPolicy(Qt::NoFocus); + setColumnCount(2); + setRootIsDecorated(false); + setHeaderHidden(true); + setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + header()->setDefaultAlignment(Qt::AlignCenter); + header()-> +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + setSectionResizeMode +#else + setResizeMode +#endif + (QHeaderView::ResizeToContents); + header()->setStretchLastSection(false); + //connect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(adjust())); +} + + +QCodeEditCompleter::~QCodeEditCompleter() { +} + + +void QCodeEditCompleter::nextCompletition() { + int ci = currentIndex().row(); + if (ci >= topLevelItemCount() - 1) return; + if (topLevelItem(ci + 1)->flags().testFlag(Qt::ItemIsSelectable)) + setCurrentItem(topLevelItem(ci + 1)); + else { + if (ci >= topLevelItemCount() - 2) return; + setCurrentItem(topLevelItem(ci + 2)); + } +} + + +void QCodeEditCompleter::previousCompletition() { + int ci = currentIndex().row(); + if (ci <= 0) return; + if (topLevelItem(ci - 1)->flags().testFlag(Qt::ItemIsSelectable)) + setCurrentItem(topLevelItem(ci - 1)); + else { + if (ci <= 1) return; + setCurrentItem(topLevelItem(ci - 2)); + } +} + +void QCodeEditCompleter::addItems(QFont f, const QCodeEdit::ACClass & cl, const QCodeEdit::ACPair & items) { + QTreeWidgetItem * gi = new QTreeWidgetItem(); + gi->setText(0, cl.name); + gi->setTextAlignment(0, Qt::AlignCenter); + gi->setTextAlignment(1, Qt::AlignCenter); + gi->setFont(0, f); + gi->setBackground(0, Qt::lightGray); + gi->setFlags(Qt::ItemIsEnabled); + addTopLevelItem(gi); + gi->setFirstColumnSpanned(true); + foreach (const auto & s, items.second) { + QTreeWidgetItem * ni = new QTreeWidgetItem(); + ni->setIcon(0, cl.icon); + ni->setText(0, s.first); + ni->setText(1, s.second); + addTopLevelItem(ni); + } +} + + +bool QCodeEditCompleter::isEmpty() const { + return topLevelItemCount() <= 1; +} + + +void QCodeEditCompleter::invoke(QPoint global_pos) { + if (isEmpty()) { + hide(); + return; + } + setCurrentItem(topLevelItem(1)); + if (isHidden()) + move(global_pos); + setVisible(true); + adjust(); +} + + +QString QCodeEditCompleter::currentReturn() const { + if (!currentItem()) return QString(); + return currentItem()->text(0); +} + + +QString QCodeEditCompleter::currentValue() const { + if (!currentItem()) return QString(); + return currentItem()->text(1); +} + + +void QCodeEditCompleter::adjust() { + int sz = sizeHint().width(); + resize(sz, fontHeight() * 16); +} diff --git a/libs/widgets/qcodeedit_completer_p.h b/libs/widgets/qcodeedit_completer_p.h new file mode 100644 index 0000000..cd464b2 --- /dev/null +++ b/libs/widgets/qcodeedit_completer_p.h @@ -0,0 +1,53 @@ +/* + QAD - Qt ADvanced + + Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ + +#ifndef QCODEEDIT_COMPLETER_P_H +#define QCODEEDIT_COMPLETER_P_H + +#include +#include "qcodeedit.h" + + +class QCodeEditCompleter: public QTreeWidget +{ + Q_OBJECT +public: + QCodeEditCompleter(QWidget * parent = 0); + ~QCodeEditCompleter(); + + void nextCompletition(); + void previousCompletition(); + void addItems(QFont f, const QCodeEdit::ACClass & cl, const QCodeEdit::ACPair & items); + bool isEmpty() const; + void invoke(QPoint global_pos); + + QString currentReturn() const; + QString currentValue() const; + +private: + +private slots: + void adjust(); + +signals: + +}; + + +#endif // QCODEEDIT_COMPLETER_P_H