QCodeEdit completer refactor and works fine!

This commit is contained in:
2020-09-10 21:39:24 +03:00
parent d65f09b1c5
commit be2870e116
4 changed files with 174 additions and 82 deletions

View File

@@ -1,4 +1,5 @@
#include "qcodeedit.h"
#include "qcodeedit_completer_p.h"
#include <QLayout>
#include <QBoxLayout>
#include <QScrollBar>
@@ -9,7 +10,6 @@
#include <QTextBlock>
#include <QAction>
#include <QApplication>
#include <QHeaderView>
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
# include <QWindow>
#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<int>(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);
}

View File

@@ -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();

View File

@@ -0,0 +1,106 @@
#include "qcodeedit_completer_p.h"
#include <QHeaderView>
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);
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef QCODEEDIT_COMPLETER_P_H
#define QCODEEDIT_COMPLETER_P_H
#include <QTreeWidget>
#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