feat: 更好的代码填充;移除冗余的组件;查找完毕强制弹出查找结果;

This commit is contained in:
寂静的羽夏 2024-11-03 22:49:27 +08:00
parent 5686edde5b
commit 93a3a8aefd
36 changed files with 840 additions and 1632 deletions

View File

@ -30,7 +30,7 @@
*/
QCodeCompletionEngine::QCodeCompletionEngine(QObject *p)
: QObject(p), m_max(0) {
: QObject(p), m_max(0), m_trigWordLen(-1) {
pForcedTrigger = new QAction(tr("&Trigger completion"), this);
connect(pForcedTrigger, SIGNAL(triggered()), this, SLOT(complete()));
@ -140,8 +140,14 @@ void QCodeCompletionEngine::textEdited(QKeyEvent *k) {
auto count = txt.length();
if (txt.isEmpty() || m_triggers.isEmpty())
if (txt.isEmpty()) {
return;
}
if (m_triggers.isEmpty()) {
triggerWordLenComplete();
return;
}
// qDebug("should trigger completion? (bis)");
@ -160,7 +166,6 @@ void QCodeCompletionEngine::textEdited(QKeyEvent *k) {
}
// qDebug("text : %s", qPrintable(txt));
for (auto &trig : m_triggers) {
if (txt.endsWith(trig)) {
cur = editor()->cursor();
@ -174,8 +179,11 @@ void QCodeCompletionEngine::textEdited(QKeyEvent *k) {
// trigger completion
complete(cur, trig);
return;
}
}
triggerWordLenComplete();
}
/*!
@ -249,3 +257,17 @@ void QCodeCompletionEngine::complete(const QDocumentCursor &c,
qWarning("QCodeCompletionEngine is not self-sufficient : subclasses should "
"reimplement at least one of the complete() method...");
}
void QCodeCompletionEngine::triggerWordLenComplete() {
if (m_trigWordLen > 0) {
QDocumentCursor cur = editor()->cursor();
emit completionTriggered({});
complete(cur, {});
}
}
qsizetype QCodeCompletionEngine::trigWordLen() const { return m_trigWordLen; }
void QCodeCompletionEngine::setTrigWordLen(qsizetype newTrigWordLen) {
m_trigWordLen = newTrigWordLen;
}

View File

@ -59,6 +59,9 @@ public:
virtual void retranslate();
qsizetype trigWordLen() const;
void setTrigWordLen(qsizetype newTrigWordLen);
signals:
void popup();
void cloned(QCodeCompletionEngine *e);
@ -74,8 +77,13 @@ protected:
virtual void complete(const QDocumentCursor &c, const QString &trigger);
private:
void triggerWordLenComplete();
private:
qsizetype m_max;
qsizetype m_trigWordLen;
QString m_trig;
QDocumentCursor m_cur;
QAction *pForcedTrigger;

View File

@ -3948,8 +3948,8 @@ void QEditor::repaintCursor() {
bool QEditor::isCursorVisible() const {
QPoint pos = m_cursor.documentPosition();
const QRect cursor(pos.x(), pos.y(), 1,
QDocument::fontMetrics().lineSpacing());
// const QRect cursor(pos.x(), pos.y(), 1,
// QDocument::fontMetrics().lineSpacing());
const QRect display(horizontalOffset(), verticalOffset(),
viewport()->width(), viewport()->height());

View File

@ -1,17 +1,19 @@
/****************************************************************************
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** Copyright (C) 2006-2009 fullmetalcoder <fullmetalcoder@hotmail.fr>
** This program is free software: you can redistribute it and/or modify it under
** the terms of the GNU Affero General Public License as published by the Free
** Software Foundation, version 3.
**
** This file is part of the Edyuk project <http://edyuk.org>
** 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 Affero General Public License for more
** details.
**
** This file may be used under the terms of the GNU General Public License
** version 3 as published by the Free Software Foundation and appearing in the
** file GPL.txt included in the packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
** You should have received a copy of the GNU Affero General Public License
** along with this program. If not, see <https://www.gnu.org/licenses/>.
** =============================================================================
*/
#include "qcalltip.h"
@ -23,6 +25,8 @@
#include <QMouseEvent>
#include <QPainter>
#include <QToolTip>
/*!
\class QCallTip
\brief A widget dedicated to calltips display
@ -32,6 +36,11 @@ QCallTip::QCallTip(QWidget *p) : QWidget(p), m_index(0) {
setCursor(Qt::ArrowCursor);
setFocusPolicy(Qt::StrongFocus);
setAttribute(Qt::WA_DeleteOnClose);
auto palette = QToolTip::palette();
_background = palette.color(QPalette::ToolTipBase);
_foreground = palette.color(QPalette::ToolTipText);
_borderColor = palette.color(QPalette::Shadow);
}
QCallTip::~QCallTip() {}
@ -49,6 +58,8 @@ void QCallTip::paintEvent(QPaintEvent *e) {
Q_UNUSED(e)
QPainter p(this);
p.setOpacity(_opacity);
QFontMetrics fm = fontMetrics();
m_up = m_down = QRect();
@ -66,21 +77,18 @@ void QCallTip::paintEvent(QPaintEvent *e) {
bg.setWidth(bg.width() + arrowWidth);
}
p.fillRect(bg, QColor(0xca, 0xff, 0x70));
p.fillRect(bg, _background);
// p.drawRect(bg);
p.save();
p.setPen(QColor(0x00, 0x00, 0x00));
p.setPen(_borderColor);
p.drawLine(0, height() - 1, bg.width() - 1, height() - 1);
p.drawLine(bg.width() - 1, height() - 1, bg.width() - 1, 0);
p.setPen(QColor(0xc0, 0xc0, 0xc0));
p.drawLine(0, height() - 1, 0, 0);
p.drawLine(0, 0, bg.width() - 1, 0);
p.restore();
int top = height() / 3, bottom = height() - height() / 3;
if (bPrev) {
@ -107,8 +115,11 @@ void QCallTip::paintEvent(QPaintEvent *e) {
offset += arrowWidth;
}
p.setPen(_foreground);
p.drawText(offset, fm.ascent() + 2, m_tips.at(m_index));
p.restore();
setFixedSize(bg.size() + QSize(1, 1));
}
@ -124,7 +135,7 @@ void QCallTip::keyPressEvent(QKeyEvent *e) {
return;
}
QString prefix, text = e->text();
QString text = e->text();
switch (e->key()) {
case Qt::Key_Escape:
@ -231,3 +242,39 @@ void QCallTip::mousePressEvent(QMouseEvent *e) {
}
void QCallTip::mouseReleaseEvent(QMouseEvent *e) { e->accept(); }
qreal QCallTip::opacity() const { return _opacity; }
void QCallTip::setOpacity(qreal newOpacity) {
if (qFuzzyCompare(_opacity, newOpacity))
return;
_opacity = newOpacity;
emit opacityChanged();
}
QColor QCallTip::borderColor() const { return _borderColor; }
void QCallTip::setBorderColor(const QColor &newBorderColor) {
if (_borderColor == newBorderColor)
return;
_borderColor = newBorderColor;
emit borderColorChanged();
}
QColor QCallTip::foreground() const { return _foreground; }
void QCallTip::setForeground(const QColor &newForeground) {
if (_foreground == newForeground)
return;
_foreground = newForeground;
emit foregroundChanged();
}
QColor QCallTip::background() const { return _background; }
void QCallTip::setBackground(const QColor &newBackground) {
if (_background == newBackground)
return;
_background = newBackground;
emit backgroundChanged();
}

View File

@ -1,17 +1,19 @@
/****************************************************************************
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** Copyright (C) 2006-2009 fullmetalcoder <fullmetalcoder@hotmail.fr>
** This program is free software: you can redistribute it and/or modify it under
** the terms of the GNU Affero General Public License as published by the Free
** Software Foundation, version 3.
**
** This file is part of the Edyuk project <http://edyuk.org>
** 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 Affero General Public License for more
** details.
**
** This file may be used under the terms of the GNU General Public License
** version 3 as published by the Free Software Foundation and appearing in the
** file GPL.txt included in the packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
** You should have received a copy of the GNU Affero General Public License
** along with this program. If not, see <https://www.gnu.org/licenses/>.
** =============================================================================
*/
#ifndef _QCALL_TIP_H_
#define _QCALL_TIP_H_
@ -26,6 +28,17 @@
#include <QWidget>
class QCE_EXPORT QCallTip : public QWidget {
Q_OBJECT
Q_PROPERTY(QColor background READ background WRITE setBackground NOTIFY
backgroundChanged FINAL)
Q_PROPERTY(QColor foreground READ foreground WRITE setForeground NOTIFY
foregroundChanged FINAL)
Q_PROPERTY(QColor borderColor READ borderColor WRITE setBorderColor NOTIFY
borderColorChanged FINAL)
Q_PROPERTY(
qreal opacity READ opacity WRITE setOpacity NOTIFY opacityChanged FINAL)
public:
QCallTip(QWidget *p = nullptr);
virtual ~QCallTip();
@ -33,18 +46,43 @@ public:
QStringList tips() const;
void setTips(const QStringList &l);
QColor background() const;
void setBackground(const QColor &newBackground);
QColor foreground() const;
void setForeground(const QColor &newForeground);
QColor borderColor() const;
void setBorderColor(const QColor &newBorderColor);
qreal opacity() const;
void setOpacity(qreal newOpacity);
signals:
void backgroundChanged();
void foregroundChanged();
void borderColorChanged();
void opacityChanged();
protected:
virtual void paintEvent(QPaintEvent *e);
virtual void keyPressEvent(QKeyEvent *e);
virtual void focusInEvent(QFocusEvent *e);
virtual void focusOutEvent(QFocusEvent *e);
virtual void mousePressEvent(QMouseEvent *e);
virtual void mouseReleaseEvent(QMouseEvent *e);
virtual void paintEvent(QPaintEvent *e) override;
virtual void keyPressEvent(QKeyEvent *e) override;
virtual void focusInEvent(QFocusEvent *e) override;
virtual void focusOutEvent(QFocusEvent *e) override;
virtual void mousePressEvent(QMouseEvent *e) override;
virtual void mouseReleaseEvent(QMouseEvent *e) override;
private:
int m_index;
QStringList m_tips;
QRect m_up, m_down;
QColor _background;
QColor _foreground;
QColor _borderColor;
qreal _opacity = 1;
};
#endif

View File

@ -223,7 +223,9 @@ set(CLASS_SRC
src/class/qdocumentsearch.cpp
src/class/qdocumentsearch.h
src/class/ascontextmgr.h
src/class/ascontextmgr.cpp)
src/class/ascontextmgr.cpp
src/class/qcodenode.cpp
src/class/qcodenode.h)
if(WINGHEX_USE_FRAMELESS)
set(WIDGET_FRAME_SRC
@ -302,18 +304,6 @@ set(CODEEDIT_WIDGET
src/qcodeeditwidget/qformatconfig.cpp
src/qcodeeditwidget/qformatconfig.ui)
set(CODE_MODEL
src/codemodel/qcodemodel.cpp
src/codemodel/qcodemodel.h
src/codemodel/qcodenode.cpp
src/codemodel/qcodenode.h
src/codemodel/qcodeproxymodel.cpp
src/codemodel/qcodeproxymodel.h
src/codemodel/qcodeview.cpp
src/codemodel/qcodeview.h
src/codemodel/qsourcecodewatcher.cpp
src/codemodel/qsourcecodewatcher.h)
set(PLUGIN_SRC src/plugin/iwingplugin.h src/plugin/pluginsystem.cpp
src/plugin/pluginsystem.h src/plugin/settingpage.h)
@ -408,7 +398,6 @@ set(PROJECT_SOURCES
src/dbghelper.h
${QPATHEDIT_SRC}
${WIDGET_FRAME_SRC}
${CODE_MODEL}
${RIBBON_SRC}
${CLASS_SRC}
${MODEL_SRC}

File diff suppressed because it is too large Load Diff

View File

@ -161,7 +161,7 @@ def update(build_path):
run_command_interactive(
["xdg-icon-resource", "forceupdate"])
run_command_interactive(
["update-icon-caches", "/usr/share/icons/hicolor"])
["gtk-update-icon-caches", "/usr/share/icons/hicolor"])
run_command_interactive(
["update-desktop-database", "/usr/share/applications"])
print(Fore.GREEN + ">> Installation finished..." + Style.RESET_ALL)

View File

@ -32,20 +32,24 @@
#include "control/qcodecompletionwidget.h"
const auto DOT_TRIGGER = QStringLiteral(".");
const auto SEMI_COLON_TRIGGER = QStringLiteral("::");
const auto LEFT_PARE_TRIGGER = QStringLiteral("(");
Q_GLOBAL_STATIC_WITH_ARGS(QString, DOT_TRIGGER, QStringLiteral("."))
Q_GLOBAL_STATIC_WITH_ARGS(QString, SEMI_COLON_TRIGGER, QStringLiteral("::"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, LEFT_PARE_TRIGGER, QStringLiteral("("))
AsCompletion::AsCompletion(asIScriptEngine *engine, QObject *p)
: QCodeCompletionEngine(p), parser(engine), _engine(engine),
pPopup(new QCodeCompletionWidget()) {
Q_ASSERT(engine);
addTrigger(DOT_TRIGGER);
addTrigger(SEMI_COLON_TRIGGER);
addTrigger(*DOT_TRIGGER);
addTrigger(*SEMI_COLON_TRIGGER);
// unleash the power of call tips
addTrigger(LEFT_PARE_TRIGGER);
addTrigger(*LEFT_PARE_TRIGGER);
// TODO parse the std aslib
setTrigWordLen(3);
}
AsCompletion::~AsCompletion() {}
@ -61,7 +65,7 @@ QCodeCompletionEngine *AsCompletion::clone() {
return e;
}
QString AsCompletion::language() const { return "AngelScript"; }
QString AsCompletion::language() const { return QStringLiteral("AngelScript"); }
QStringList AsCompletion::extensions() const {
QStringList l;
@ -73,7 +77,11 @@ QStringList AsCompletion::extensions() const {
}
void AsCompletion::complete(const QDocumentCursor &c, const QString &trigger) {
// TODO
if (pPopup->isVisible()) {
return;
}
// TODO parse current code
// auto codes = c.document()->text(true, false);
// parser.parse(codes, this->editor()->fileName());
@ -86,19 +94,23 @@ void AsCompletion::complete(const QDocumentCursor &c, const QString &trigger) {
auto end = p + len;
struct Token {
qsizetype pos;
asETokenClass type;
QByteArray content;
};
QVector<Token> tokens;
qsizetype pos = 0;
for (; p < end;) {
asUINT tokenLen = 0;
auto tt = _engine->ParseToken(p, len, &tokenLen);
Token token;
token.pos = pos;
token.type = tt;
token.content = QByteArray(p, tokenLen);
tokens << token;
p += tokenLen;
pos += tokenLen;
}
QByteArray fn;
@ -106,103 +118,151 @@ void AsCompletion::complete(const QDocumentCursor &c, const QString &trigger) {
auto r =
std::find_if(tokens.rbegin(), tokens.rend(), [](const Token &token) {
return token.type == asTC_IDENTIFIER || token.type == asTC_VALUE;
return token.type != asTC_WHITESPACE;
});
if (r == tokens.rend()) {
return;
}
QCodeCompletionWidget::Filter filter =
QCodeCompletionWidget::FilterFlag::KeepAll;
auto &_headerNodes = parser.headerNodes();
fn = r->content;
if (trigger == SEMI_COLON_TRIGGER) {
for (auto &n : _headerNodes) {
auto name = n->qualifiedName();
if (name == fn) {
nodes << n;
if (trigger.isEmpty()) {
auto eb = tokens.back();
if (eb.type == asTC_KEYWORD) {
// only support these
if (eb.content == *SEMI_COLON_TRIGGER) {
complete(c, *SEMI_COLON_TRIGGER);
} else if (eb.content == *DOT_TRIGGER) {
complete(c, *DOT_TRIGGER);
}
}
} else if (trigger == LEFT_PARE_TRIGGER) {
if (r != tokens.rend()) {
auto pr = std::next(r);
if (pr->content == SEMI_COLON_TRIGGER) {
if (pr != tokens.rend()) {
auto prr = std::next(pr);
auto ns = prr->content;
if (prr->type == asTC_IDENTIFIER) {
for (auto &n : _headerNodes) {
auto name = n->qualifiedName();
if (name == ns) {
nodes << n;
return;
} else if (eb.type == asTC_IDENTIFIER) {
if (r != tokens.rend()) {
auto pr = std::next(r);
if (pr->content == *SEMI_COLON_TRIGGER) {
if (pr != tokens.rend()) {
auto prr = std::next(pr);
auto ns = prr->content;
if (prr->type == asTC_IDENTIFIER) {
for (auto &n : _headerNodes) {
auto name = n->qualifiedName();
if (name == ns) {
nodes << n;
}
}
auto cur = c;
cur.movePosition(pr->pos + pr->content.length() -
txt.length());
pPopup->setCursor(cur);
} else {
return;
}
}
}
}
} else {
return;
}
// pPopup->setTemporaryNodes(temp);
pPopup->setFilter(filter);
pPopup->setCompletions(nodes);
pPopup->popup();
} else {
if (trigger == *SEMI_COLON_TRIGGER) {
for (auto &n : _headerNodes) {
auto name = n->qualifiedName();
if (name == fn) {
nodes << n;
}
}
} else if (trigger == *LEFT_PARE_TRIGGER) {
if (r != tokens.rend()) {
auto pr = std::next(r);
if (pr->content == *SEMI_COLON_TRIGGER) {
if (pr != tokens.rend()) {
auto prr = std::next(pr);
auto ns = prr->content;
if (prr->type == asTC_IDENTIFIER) {
for (auto &n : _headerNodes) {
auto name = n->qualifiedName();
if (name == ns) {
nodes << n;
}
}
} else {
return;
}
} else {
return;
}
}
}
}
}
// TODO
// QList<QCodeNode *> temp; // internal CodeNodes
int filter = QCodeCompletionWidget::FilterFlag::KeepAll;
if (nodes.count()) {
if (trigger == *LEFT_PARE_TRIGGER) {
QStringList tips;
if (nodes.count()) {
if (trigger == "(") {
QStringList tips;
// qDebug("fn %s", fn.constData());
// qDebug("fn %s", fn.constData());
for (auto &n : nodes) {
for (auto &f : n->children()) {
if (f->type() != QCodeNode::Function ||
f->role(QCodeNode::Name) != fn) {
continue;
}
for (auto &n : nodes) {
for (auto &f : n->children()) {
if (f->type() != QCodeNode::Function ||
f->role(QCodeNode::Name) != fn)
continue;
auto tip =
QString::fromUtf8(f->role(QCodeNode::Arguments))
.prepend('(')
.append(')');
auto tip = QString::fromUtf8(f->role(QCodeNode::Arguments))
.prepend('(')
.append(')');
if (!tips.contains(tip))
tips << tip;
if (!tips.contains(tip))
tips << tip;
}
}
}
if (!tips.isEmpty()) {
QRect r = editor()->cursorRect();
QDocumentCursor cursor = editor()->cursor();
QDocumentLine line = cursor.line();
if (!tips.isEmpty()) {
QRect r = editor()->cursorRect();
QDocumentCursor cursor = editor()->cursor();
QDocumentLine line = cursor.line();
int hx = editor()->horizontalOffset(),
cx = line.cursorToX(cursor.columnNumber());
int hx = editor()->horizontalOffset(),
cx = line.cursorToX(cursor.columnNumber());
auto ct = new QCallTip(editor()->viewport());
ct->move(cx - hx, r.y() + r.height());
ct->setTips(tips);
ct->show();
ct->setFocus();
auto ct = new QCallTip(editor()->viewport());
ct->move(cx - hx, r.y() + r.height());
ct->setTips(tips);
ct->show();
ct->setFocus();
#ifdef TRACE_COMPLETION
qDebug("parsing + scoping + search + pre-display : elapsed "
"%i ms",
time.elapsed());
#endif
}
} else {
// pPopup->setTemporaryNodes(temp);
pPopup->setFilter(QCodeCompletionWidget::Filter(filter));
pPopup->setCompletions(nodes);
#ifdef TRACE_COMPLETION
qDebug(
"parsing + scoping + search + pre-display : elapsed %i ms",
time.elapsed());
#endif
pPopup->popup();
}
} else {
// pPopup->setTemporaryNodes(temp);
pPopup->setFilter(QCodeCompletionWidget::Filter(filter));
pPopup->setCompletions(nodes);
#ifdef TRACE_COMPLETION
qDebug("parsing + scoping + search + pre-display : elapsed %i ms",
time.elapsed());
#endif
pPopup->popup();
// qDeleteAll(temp);
qDebug("completion failed");
}
} else {
// qDeleteAll(temp);
qDebug("completion failed");
}
}

View File

@ -45,7 +45,6 @@ private:
QAsParser parser;
asIScriptEngine *_engine;
QCodeCompletionWidget *pPopup;
QPointer<QCodeModel> pModel;
};
#endif // _CPP_COMPLETION_H_

View File

@ -19,8 +19,7 @@
#include "AngelScript/sdk/angelscript/source/as_builder.h"
#include "AngelScript/sdk/angelscript/source/as_parser.h"
#include "codemodel/qcodemodel.h"
#include "codemodel/qcodenode.h"
#include "class/qcodenode.h"
#include <QDebug>
@ -33,9 +32,9 @@
*/
QAsParser::QAsParser(asIScriptEngine *engine) : asBuilder(), _engine(engine) {
addGlobalFunctionCompletion(engine);
addClassCompletion(engine);
addEnumCompletion(engine);
addGlobalFunctionCompletion(engine);
}
QAsParser::~QAsParser() {
@ -248,16 +247,7 @@ void QAsParser::addGlobalFunctionCompletion(asIScriptEngine *engine) {
auto nodeParent = node;
for (auto &fn : p->second) {
auto node = new QCodeNode;
node->setNodeType(QCodeNode::Function);
node->setRole(QCodeNode::Return, fn.retType);
node->setRole(QCodeNode::Name, fn.fnName);
node->setRole(QCodeNode::Arguments, fn.params);
QByteArray qualifiers;
if (fn.isConst) {
qualifiers.setNum(QCodeNode::QUALIFIER_CONST);
}
node->setRole(QCodeNode::Qualifiers, qualifiers);
auto node = newFnCodeNode(fn);
node->setParent(nodeParent);
pnodes->append(node);
}
@ -307,20 +297,8 @@ void QAsParser::addEnumCompletion(asIScriptEngine *engine) {
node->setParent(nodeParent);
pnodes->append(node);
auto enode = new QCodeNode;
auto enode = newEnumCodeNode(e);
_headerNodes << enode;
enode->setNodeType(QCodeNode::Enum);
enode->setRole(QCodeNode::Name, e.name);
for (auto &ev : e.enums) {
auto node = new QCodeNode;
node->setNodeType(QCodeNode::Enumerator);
node->setRole(QCodeNode::Name, ev.first);
QByteArray value;
value.setNum(ev.second);
node->setRole(QCodeNode::Value, value);
node->setParent(enode);
enode->children().append(node);
}
}
}
}
@ -402,8 +380,78 @@ void QAsParser::addClassCompletion(asIScriptEngine *engine) {
}
node->setRole(QCodeNode::Name, p->first);
// TODO
auto pnodes = &node->children();
auto nodeParent = node;
for (auto &cls : p->second) {
auto node = new QCodeNode;
node->setNodeType(QCodeNode::Class);
node->setRole(QCodeNode::Name, cls.name);
node->setParent(nodeParent);
pnodes->append(node);
auto clsnode = new QCodeNode;
_headerNodes << clsnode;
clsnode->setNodeType(QCodeNode::Class);
clsnode->setRole(QCodeNode::Name, cls.name);
for (auto &m : cls.methods) {
auto node = newFnCodeNode(m);
node->setParent(clsnode);
clsnode->children().append(node);
}
for (auto &p : cls.properties) {
auto node = new QCodeNode;
node->setNodeType(QCodeNode::Variable);
node->setRole(QCodeNode::Name, p.name);
node->setRole(QCodeNode::Type, p.type);
QByteArray visibility;
if (p.isPrivate) {
visibility.setNum(QCodeNode::VISIBILITY_PRIVATE);
} else if (p.isProtected) {
visibility.setNum(QCodeNode::VISIBILITY_PROTECTED);
} else {
visibility.setNum(QCodeNode::VISIBILITY_PUBLIC);
}
node->setRole(QCodeNode::Visibility, visibility);
node->setParent(clsnode);
clsnode->children().append(node);
}
}
}
}
QCodeNode *QAsParser::newFnCodeNode(const FnInfo &info) {
auto node = new QCodeNode;
node->setNodeType(QCodeNode::Function);
node->setNodeType(QCodeNode::Function);
node->setRole(QCodeNode::Return, info.retType);
node->setRole(QCodeNode::Name, info.fnName);
node->setRole(QCodeNode::Arguments, info.params);
QByteArray qualifiers;
if (info.isConst) {
qualifiers.setNum(QCodeNode::QUALIFIER_CONST);
}
node->setRole(QCodeNode::Qualifiers, qualifiers);
return node;
}
QCodeNode *QAsParser::newEnumCodeNode(const EnumInfo &info) {
auto enode = new QCodeNode;
enode->setNodeType(QCodeNode::Enum);
enode->setRole(QCodeNode::Name, info.name);
for (auto &ev : info.enums) {
auto node = new QCodeNode;
node->setNodeType(QCodeNode::Enumerator);
node->setRole(QCodeNode::Name, ev.first);
QByteArray value;
value.setNum(ev.second);
node->setRole(QCodeNode::Value, value);
node->setParent(enode);
enode->children().append(node);
}
return enode;
}
QList<QCodeNode *> QAsParser::codeNodes() const { return _nodes; }

View File

@ -80,6 +80,11 @@ private:
void addEnumCompletion(asIScriptEngine *engine);
void addClassCompletion(asIScriptEngine *engine);
private:
QCodeNode *newFnCodeNode(const FnInfo &info);
QCodeNode *newEnumCodeNode(const EnumInfo &info);
private:
asIScriptEngine *_engine;
QScopedPointer<asCScriptCode> m_code;

View File

@ -18,9 +18,6 @@
#include <QIcon>
#include <QVariant>
#include "qcodemodel.h"
#include "qsourcecodewatcher.h"
enum CacheIndex {
ICON_ENUM,
ICON_ENUMERATOR,
@ -33,7 +30,8 @@ enum CacheIndex {
ICON_VARIABLE = ICON_FUNCTION + 5
};
static QHash<int, QIcon> q_icon_cache;
using IconHash = QHash<int, QIcon>;
Q_GLOBAL_STATIC(IconHash, q_icon_cache)
inline static QIcon getIcon(const QString &name) {
return QIcon(QStringLiteral(":/completion/images/completion/") + name +
@ -46,64 +44,60 @@ static QIcon icon(int cacheIndex) {
if (!setup) {
// q_icon_cache[ICON_UNION] = QIcon(":/completion/CVunion.png");
q_icon_cache[ICON_ENUM] = getIcon(QStringLiteral("CVenum"));
q_icon_cache[ICON_ENUMERATOR] = getIcon(QStringLiteral("CVenumerator"));
(*q_icon_cache)[ICON_ENUM] = getIcon(QStringLiteral("CVenum"));
(*q_icon_cache)[ICON_ENUMERATOR] =
getIcon(QStringLiteral("CVenumerator"));
q_icon_cache[ICON_CLASS] = getIcon(QStringLiteral("CVclass"));
(*q_icon_cache)[ICON_CLASS] = getIcon(QStringLiteral("CVclass"));
// q_icon_cache[ICON_STRUCT] = QIcon(":/completion/CVstruct.png");
q_icon_cache[ICON_TYPEDEF] = getIcon(QStringLiteral("CVtypedef"));
(*q_icon_cache)[ICON_TYPEDEF] = getIcon(QStringLiteral("CVtypedef"));
q_icon_cache[ICON_NAMESPACE] = getIcon(QStringLiteral("CVnamespace"));
(*q_icon_cache)[ICON_NAMESPACE] =
getIcon(QStringLiteral("CVnamespace"));
q_icon_cache[ICON_FUNCTION + QCodeNode::VISIBILITY_DEFAULT] =
(*q_icon_cache)[ICON_FUNCTION + QCodeNode::VISIBILITY_DEFAULT] =
getIcon(QStringLiteral("CVglobal_meth"));
q_icon_cache[ICON_FUNCTION + QCodeNode::VISIBILITY_PUBLIC] =
(*q_icon_cache)[ICON_FUNCTION + QCodeNode::VISIBILITY_PUBLIC] =
getIcon(QStringLiteral("CVpublic_meth"));
q_icon_cache[ICON_FUNCTION + QCodeNode::VISIBILITY_PROTECTED] =
(*q_icon_cache)[ICON_FUNCTION + QCodeNode::VISIBILITY_PROTECTED] =
getIcon(QStringLiteral("CVprotected_meth"));
q_icon_cache[ICON_FUNCTION + QCodeNode::VISIBILITY_PRIVATE] =
(*q_icon_cache)[ICON_FUNCTION + QCodeNode::VISIBILITY_PRIVATE] =
getIcon(QStringLiteral("CVprivate_meth"));
// q_icon_cache[ICON_FUNCTION + QCodeNode::VISIBILITY_SIGNAL] =
// QIcon(":/completion/CVprotected_signal.png");
q_icon_cache[ICON_VARIABLE + QCodeNode::VISIBILITY_DEFAULT] =
(*q_icon_cache)[ICON_VARIABLE + QCodeNode::VISIBILITY_DEFAULT] =
getIcon(QStringLiteral("CVglobal_var"));
q_icon_cache[ICON_VARIABLE + QCodeNode::VISIBILITY_PUBLIC] =
(*q_icon_cache)[ICON_VARIABLE + QCodeNode::VISIBILITY_PUBLIC] =
getIcon(QStringLiteral("CVpublic_var"));
q_icon_cache[ICON_VARIABLE + QCodeNode::VISIBILITY_PROTECTED] =
(*q_icon_cache)[ICON_VARIABLE + QCodeNode::VISIBILITY_PROTECTED] =
getIcon(QStringLiteral("CVprotected_var"));
q_icon_cache[ICON_VARIABLE + QCodeNode::VISIBILITY_PRIVATE] =
(*q_icon_cache)[ICON_VARIABLE + QCodeNode::VISIBILITY_PRIVATE] =
getIcon(QStringLiteral("CVprivate_var"));
setup = true;
}
return q_icon_cache.value(cacheIndex);
return q_icon_cache->value(cacheIndex);
}
QCodeNode::QCodeNode() : line(-1), _parent(0), _model(0) {}
QCodeNode::QCodeNode() : line(-1), _parent(nullptr) {}
QCodeNode::~QCodeNode() {
QCodeNode::detach();
_model = nullptr;
_parent = nullptr;
QCodeNode::clear();
QSourceCodeWatcher *w = QSourceCodeWatcher::watcher(this, nullptr);
if (w)
delete w;
clear();
}
void QCodeNode::attach(QCodeNode *p) {
@ -112,33 +106,10 @@ void QCodeNode::attach(QCodeNode *p) {
if (!p || p->_children.contains(this))
return;
bool modelChange = _model != p->_model;
if (modelChange) {
QStack<QCodeNode *> tree;
tree.push(this);
while (tree.length()) {
QCodeNode *n = tree.pop();
n->_model = p->_model;
foreach (QCodeNode *c, n->_children)
tree.push(c);
}
}
int row = p->_children.length();
if (_model)
_model->beginInsertRows(_model->index(p), row, row);
_parent = p;
p->_children.insert(row, this);
if (_model)
_model->endInsertRows();
}
void QCodeNode::detach() {
@ -150,35 +121,10 @@ void QCodeNode::detach() {
if (row < 0)
return;
if (_model)
_model->beginRemoveRows(_model->index(_parent), row, row);
_parent->_children.removeAt(row);
_parent = 0;
if (_model)
_model->endRemoveRows();
if (_model) {
QStack<QCodeNode *> tree;
tree.push(this);
while (tree.length()) {
QCodeNode *n = tree.pop();
n->_model = 0;
foreach (QCodeNode *c, n->_children)
tree.push(c);
}
}
}
QCodeModel *QCodeNode::model() const { return _model; }
void QCodeNode::setModel(QCodeModel *newModel) { _model = newModel; }
QCodeNode *QCodeNode::parent() const { return _parent; }
void QCodeNode::setParent(QCodeNode *newParent) { _parent = newParent; }
@ -199,18 +145,11 @@ void QCodeNode::removeAll() {
if (_children.isEmpty())
return;
if (_model)
_model->beginRemoveRows(_model->index(this), 0, _children.length() - 1);
foreach (QCodeNode *n, _children) {
n->_model = nullptr;
for (auto &n : _children) {
n->_parent = nullptr;
}
_children.clear();
if (_model)
_model->endRemoveRows();
}
int QCodeNode::type() const {
@ -270,9 +209,6 @@ QVariant QCodeNode::data(int r) const {
if (t == Function)
return role(Name) + "(" + role(Arguments) + ")";
// if ( t == Enumerator )
// ;
return role(Name);
}
@ -460,12 +396,6 @@ QVariant QCodeNode::data(int r) const {
return QVariant();
}
case QCodeModel::TypeRole:
return type();
case QCodeModel::VisibilityRole:
return role(Visibility).toInt();
default:
break;
}

View File

@ -21,9 +21,7 @@
#include <QMap>
#include <QVariant>
class QCodeModel;
class QCodeNode {
class QCodeNode final {
public:
enum RoleIndex {
NodeType = 0,
@ -110,7 +108,7 @@ public:
public:
QCodeNode();
virtual ~QCodeNode();
~QCodeNode();
int type() const;
QByteArray context() const;
@ -131,9 +129,6 @@ public:
void attach(QCodeNode *p);
void detach();
QCodeModel *model() const;
void setModel(QCodeModel *newModel);
QCodeNode *parent() const;
void setParent(QCodeNode *newParent);
@ -144,7 +139,6 @@ private:
int line = -1;
QMap<RoleIndex, QByteArray> roles;
QCodeNode *_parent = nullptr;
QCodeModel *_model = nullptr;
QList<QCodeNode *> _children;
};

View File

@ -23,7 +23,8 @@
#include <QFile>
#include <QMenu>
RecentFileManager::RecentFileManager(QMenu *menu) : QObject(), m_menu(menu) {
RecentFileManager::RecentFileManager(QMenu *menu, bool fileNameOnly)
: QObject(), m_menu(menu), _fileNameOnly(fileNameOnly) {
Q_ASSERT(menu);
menu->setToolTipsVisible(true);
}
@ -112,20 +113,24 @@ QString RecentFileManager::getDisplayFileName(const RecentInfo &info) {
}
QString RecentFileManager::getDisplayTooltip(const RecentInfo &info) {
auto tt = QStringLiteral("<p>") + tr("[file]") + info.fileName +
QString tt;
if (_fileNameOnly) {
tt = info.fileName;
} else {
tt = QStringLiteral("<p>") + tr("[file]") + info.fileName +
QStringLiteral("</p>");
tt += QStringLiteral("<p>") + tr("[isWorkSpace]") +
(info.isWorkSpace ? tr("True") : tr("False")) +
QStringLiteral("</p>");
tt += QStringLiteral("<p>") + tr("[isWorkSpace]") +
(info.isWorkSpace ? tr("True") : tr("False")) +
QStringLiteral("</p>");
if (info.start >= 0 && info.stop > 0) {
tt += QStringLiteral("<p>") + tr("[start]") +
QString::number(info.start) + QStringLiteral("</p>");
tt += QStringLiteral("<p>") + tr("[stop]") +
QString::number(info.stop) + QStringLiteral("</p>");
if (info.start >= 0 && info.stop > 0) {
tt += QStringLiteral("<p>") + tr("[start]") +
QString::number(info.start) + QStringLiteral("</p>");
tt += QStringLiteral("<p>") + tr("[stop]") +
QString::number(info.stop) + QStringLiteral("</p>");
}
}
return tt;
}

View File

@ -72,7 +72,7 @@ public:
};
public:
explicit RecentFileManager(QMenu *menu);
explicit RecentFileManager(QMenu *menu, bool fileNameOnly);
~RecentFileManager();
void addRecentFile(const RecentInfo &info);
void clearFile();
@ -81,7 +81,7 @@ public:
const QList<RecentInfo> &saveRecent() const;
signals:
void triggered(const RecentInfo &rinfo);
void triggered(const RecentFileManager::RecentInfo &rinfo);
private:
bool existsPath(const RecentInfo &info);
@ -93,6 +93,8 @@ private:
QWidget *m_parent;
QList<RecentInfo> m_recents;
QList<QAction *> hitems;
bool _fileNameOnly;
};
Q_DECLARE_METATYPE(RecentFileManager::RecentInfo)

View File

@ -103,7 +103,7 @@ bool ScriptEditorTheme::loadTheme(const QString &filename) {
if (readAttr(attr, QStringLiteral("fontfamily"),
styleAttr)) {
if (QFontDatabase().hasFamily(styleAttr)) {
if (QFontDatabase::hasFamily(styleAttr)) {
scheme.fontFamily = styleAttr;
}
}

View File

@ -24,6 +24,14 @@
#include <QMetaEnum>
#include <QSettings>
QString getRealContent(const QString &value) { return value; }
template <typename T>
QString getRealContent(QGlobalStatic<T> &value) {
static_assert(std::is_same<QString &, decltype(*value)>());
return *value;
}
#define HANDLE_CONFIG \
QSettings set(QStringLiteral(APP_ORG), QStringLiteral(APP_NAME))
@ -31,11 +39,11 @@
#define WRITE_CONFIG(config, dvalue) \
if (this->_setUnsaved.testFlag(SETTING_ITEM::config)) { \
set.setValue(config, dvalue); \
set.setValue(getRealContent(config), dvalue); \
_setUnsaved.setFlag(SettingManager::SETTING_ITEM::config, false); \
}
#define READ_CONFIG(config, dvalue) set.value(config, dvalue)
#define READ_CONFIG(config, dvalue) set.value(getRealContent(config), dvalue)
#define READ_CONFIG_SAFE(var, config, dvalue, func) \
{ \
@ -73,38 +81,58 @@
} \
}
const auto DOCK_LAYOUT = QStringLiteral("dock.layout");
const auto SCRIPT_DOCK_LAYOUT = QStringLiteral("script.layout");
const auto APP_LASTUSED_PATH = QStringLiteral("app.lastusedpath");
Q_GLOBAL_STATIC_WITH_ARGS(QString, DOCK_LAYOUT, QStringLiteral("dock.layout"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, SCRIPT_DOCK_LAYOUT,
QStringLiteral("script.layout"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, APP_LASTUSED_PATH,
QStringLiteral("app.lastusedpath"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, SKIN_THEME, QStringLiteral("skin.theme"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, APP_FONTFAMILY,
QStringLiteral("app.fontfamily"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, APP_FONTSIZE, QStringLiteral("app.fontsize"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, APP_WINDOWSIZE,
QStringLiteral("app.windowsize"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, APP_LANGUAGE, QStringLiteral("app.lang"))
const auto SKIN_THEME = QStringLiteral("skin.theme");
const auto APP_FONTFAMILY = QStringLiteral("app.fontfamily");
const auto APP_FONTSIZE = QStringLiteral("app.fontsize");
const auto APP_WINDOWSIZE = QStringLiteral("app.windowsize");
const auto APP_LANGUAGE = QStringLiteral("app.lang");
Q_GLOBAL_STATIC_WITH_ARGS(QString, PLUGIN_ENABLE,
QStringLiteral("plugin.enableplugin"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, PLUGIN_ENABLE_ROOT,
QStringLiteral("plugin.rootenableplugin"))
const auto PLUGIN_ENABLE = QStringLiteral("plugin.enableplugin");
const auto PLUGIN_ENABLE_ROOT = QStringLiteral("plugin.rootenableplugin");
Q_GLOBAL_STATIC_WITH_ARGS(QString, EDITOR_FONTSIZE,
QStringLiteral("editor.fontsize"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, EDITOR_SHOW_ADDR,
QStringLiteral("editor.showaddr"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, EDITOR_SHOW_COL,
QStringLiteral("editor.showcol"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, EDITOR_SHOW_TEXT,
QStringLiteral("editor.showtext"))
const auto EDITOR_FONTSIZE = QStringLiteral("editor.fontsize");
const auto EDITOR_SHOW_ADDR = QStringLiteral("editor.showaddr");
const auto EDITOR_SHOW_COL = QStringLiteral("editor.showcol");
const auto EDITOR_SHOW_TEXT = QStringLiteral("editor.showtext");
const auto EDITOR_ENCODING = QStringLiteral("editor.encoding");
const auto EDITOR_FIND_MAXCOUNT = QStringLiteral("editor.findmaxcount");
const auto EDITOR_COPY_LIMIT = QStringLiteral("editor.copylimit");
const auto EDITOR_DECSTRLIMIT = QStringLiteral("editor.decstrlimit");
const auto EDITOR_RECENTFILES = QStringLiteral("editor.recentfiles");
const auto SCRIPT_RECENTFILES = QStringLiteral("script.recentfiles");
Q_GLOBAL_STATIC_WITH_ARGS(QString, EDITOR_ENCODING,
QStringLiteral("editor.encoding"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, EDITOR_FIND_MAXCOUNT,
QStringLiteral("editor.findmaxcount"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, EDITOR_COPY_LIMIT,
QStringLiteral("editor.copylimit"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, EDITOR_DECSTRLIMIT,
QStringLiteral("editor.decstrlimit"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, EDITOR_RECENTFILES,
QStringLiteral("editor.recentfiles"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, SCRIPT_RECENTFILES,
QStringLiteral("script.recentfiles"))
const auto SCRIPT_ALLOW_USRSCRIPT_INROOT =
QStringLiteral("script.allowUsrScriptRoot");
const auto SCRIPT_USRHIDECATS = QStringLiteral("script.usrHideCats");
const auto SCRIPT_SYSHIDECATS = QStringLiteral("script.sysHideCats");
const auto OTHER_USESYS_FILEDIALOG = QStringLiteral("sys.nativeDialog");
const auto OTHER_USE_NATIVE_TITLEBAR = QStringLiteral("sys.nativeTitleBar");
const auto OTHER_LOG_LEVEL = QStringLiteral("sys.loglevel");
Q_GLOBAL_STATIC_WITH_ARGS(QString, SCRIPT_ALLOW_USRSCRIPT_INROOT,
QStringLiteral("script.allowUsrScriptRoot"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, SCRIPT_USRHIDECATS,
QStringLiteral("script.usrHideCats"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, SCRIPT_SYSHIDECATS,
QStringLiteral("script.sysHideCats"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, OTHER_USESYS_FILEDIALOG,
QStringLiteral("sys.nativeDialog"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, OTHER_USE_NATIVE_TITLEBAR,
QStringLiteral("sys.nativeTitleBar"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, OTHER_LOG_LEVEL,
QStringLiteral("sys.loglevel"))
SettingManager::SettingManager() {
_defaultFont = qApp->font();
@ -129,6 +157,7 @@ void SettingManager::load() {
m_themeID = qBound(0, m_themeID,
QMetaEnum::fromType<SkinManager::Theme>().keyCount());
m_defaultLang = READ_CONFIG(APP_LANGUAGE, QString()).toString();
m_dockLayout = READ_CONFIG(DOCK_LAYOUT, QByteArray()).toByteArray();
m_scriptDockLayout =
READ_CONFIG(SCRIPT_DOCK_LAYOUT, QByteArray()).toByteArray();

View File

@ -1316,30 +1316,32 @@ bool WingAngelAPI::read2Ref(qsizetype offset, void *ref, int typeId) {
if (typeId == asTYPEID_VOID)
return false;
else if (typeId == asTYPEID_BOOL)
*reinterpret_cast<bool *>(ref) = (reader.readInt8(offset) != 0);
*reinterpret_cast<bool *>(ref) =
(emit reader.readInt8(offset) != 0);
else if (typeId == asTYPEID_INT8)
*reinterpret_cast<qint8 *>(ref) = reader.readInt8(offset);
*reinterpret_cast<qint8 *>(ref) = emit reader.readInt8(offset);
else if (typeId == asTYPEID_INT16)
*reinterpret_cast<qint16 *>(ref) = reader.readInt16(offset);
*reinterpret_cast<qint16 *>(ref) = emit reader.readInt16(offset);
else if (typeId == asTYPEID_INT32)
*reinterpret_cast<qint32 *>(ref) = reader.readInt32(offset);
*reinterpret_cast<qint32 *>(ref) = emit reader.readInt32(offset);
else if (typeId == asTYPEID_INT64)
*reinterpret_cast<qint64 *>(ref) = reader.readInt64(offset);
*reinterpret_cast<qint64 *>(ref) = emit reader.readInt64(offset);
else if (typeId == asTYPEID_UINT8)
*reinterpret_cast<quint8 *>(ref) = quint8(reader.readInt8(offset));
*reinterpret_cast<quint8 *>(ref) =
quint8(emit reader.readInt8(offset));
else if (typeId == asTYPEID_UINT16)
*reinterpret_cast<quint16 *>(ref) =
quint16(reader.readInt16(offset));
quint16(emit reader.readInt16(offset));
else if (typeId == asTYPEID_UINT32)
*reinterpret_cast<quint32 *>(ref) =
quint32(reader.readInt32(offset));
quint32(emit reader.readInt32(offset));
else if (typeId == asTYPEID_UINT64)
*reinterpret_cast<quint64 *>(ref) =
quint64(reader.readInt64(offset));
quint64(emit reader.readInt64(offset));
else if (typeId == asTYPEID_FLOAT)
*reinterpret_cast<float *>(ref) = reader.readFloat(offset);
*reinterpret_cast<float *>(ref) = emit reader.readFloat(offset);
else if (typeId == asTYPEID_DOUBLE)
*reinterpret_cast<double *>(ref) = reader.readDouble(offset);
*reinterpret_cast<double *>(ref) = emit reader.readDouble(offset);
else if ((typeId & asTYPEID_MASK_OBJECT) == 0) {
bool ok = false;
// Check if the value matches one of the defined enums
@ -1391,7 +1393,7 @@ bool WingAngelAPI::read2Ref(qsizetype offset, void *ref, int typeId) {
// TODO support other type, now only string
if (type->GetTypeId() == (typeId & ~asTYPEID_OBJHANDLE)) {
*reinterpret_cast<QString *>(value) =
reader.readString(offset);
emit reader.readString(offset);
}
}
}
@ -1492,22 +1494,26 @@ bool WingAngelAPI::_HexReader_write(qsizetype offset, void *ref, int typeId) {
if (typeId == asTYPEID_VOID)
return false;
else if (typeId == asTYPEID_BOOL)
controller.writeInt8(offset,
*reinterpret_cast<bool *>(ref) ? 1 : 0);
emit controller.writeInt8(offset,
*reinterpret_cast<bool *>(ref) ? 1 : 0);
else if (typeId == asTYPEID_INT8 || typeId == asTYPEID_UINT8)
controller.writeInt8(offset, *reinterpret_cast<qint8 *>(ref));
emit controller.writeInt8(offset, *reinterpret_cast<qint8 *>(ref));
else if (typeId == asTYPEID_INT16 || typeId == asTYPEID_UINT16)
controller.writeInt16(offset, *reinterpret_cast<qint16 *>(ref));
emit controller.writeInt16(offset,
*reinterpret_cast<qint16 *>(ref));
else if (typeId == asTYPEID_INT32 || typeId == asTYPEID_UINT32)
controller.writeInt32(offset, *reinterpret_cast<qint32 *>(ref));
emit controller.writeInt32(offset,
*reinterpret_cast<qint32 *>(ref));
else if (typeId == asTYPEID_INT64 || typeId == asTYPEID_UINT64)
controller.writeInt64(offset, *reinterpret_cast<qint64 *>(ref));
emit controller.writeInt64(offset,
*reinterpret_cast<qint64 *>(ref));
else if (typeId == asTYPEID_FLOAT)
controller.writeFloat(offset, *reinterpret_cast<float *>(ref));
emit controller.writeFloat(offset, *reinterpret_cast<float *>(ref));
else if (typeId == asTYPEID_DOUBLE)
controller.writeDouble(offset, *reinterpret_cast<double *>(ref));
emit controller.writeDouble(offset,
*reinterpret_cast<double *>(ref));
else if ((typeId & asTYPEID_MASK_OBJECT) == 0)
controller.writeInt32(offset, *reinterpret_cast<int *>(ref));
emit controller.writeInt32(offset, *reinterpret_cast<int *>(ref));
else if (typeId & asTYPEID_SCRIPTOBJECT) {
// Dereference handles, so we can see what it points to
void *value = ref;
@ -1520,7 +1526,7 @@ bool WingAngelAPI::_HexReader_write(qsizetype offset, void *ref, int typeId) {
int enumVal;
t->GetEnumValueByIndex(n, &enumVal);
if (enumVal == *(int *)value) {
controller.writeInt32(offset, enumVal);
emit controller.writeInt32(offset, enumVal);
break;
}
}
@ -1537,7 +1543,7 @@ bool WingAngelAPI::_HexReader_write(qsizetype offset, void *ref, int typeId) {
if (value) {
// TODO support other type, now only string
if (type->GetTypeId() == (typeId & ~asTYPEID_OBJHANDLE)) {
controller.writeString(
emit controller.writeString(
offset, *reinterpret_cast<QString *>(value));
}
}
@ -1557,22 +1563,27 @@ bool WingAngelAPI::_HexReader_insert(qsizetype offset, void *ref, int typeId) {
if (typeId == asTYPEID_VOID)
return false;
else if (typeId == asTYPEID_BOOL)
controller.insertInt8(offset,
*reinterpret_cast<bool *>(ref) ? 1 : 0);
emit controller.insertInt8(offset,
*reinterpret_cast<bool *>(ref) ? 1 : 0);
else if (typeId == asTYPEID_INT8 || typeId == asTYPEID_UINT8)
controller.insertInt8(offset, *reinterpret_cast<qint8 *>(ref));
emit controller.insertInt8(offset, *reinterpret_cast<qint8 *>(ref));
else if (typeId == asTYPEID_INT16 || typeId == asTYPEID_UINT16)
controller.insertInt16(offset, *reinterpret_cast<qint16 *>(ref));
emit controller.insertInt16(offset,
*reinterpret_cast<qint16 *>(ref));
else if (typeId == asTYPEID_INT32 || typeId == asTYPEID_UINT32)
controller.insertInt32(offset, *reinterpret_cast<qint32 *>(ref));
emit controller.insertInt32(offset,
*reinterpret_cast<qint32 *>(ref));
else if (typeId == asTYPEID_INT64 || typeId == asTYPEID_UINT64)
controller.insertInt64(offset, *reinterpret_cast<qint64 *>(ref));
emit controller.insertInt64(offset,
*reinterpret_cast<qint64 *>(ref));
else if (typeId == asTYPEID_FLOAT)
controller.insertFloat(offset, *reinterpret_cast<float *>(ref));
emit controller.insertFloat(offset,
*reinterpret_cast<float *>(ref));
else if (typeId == asTYPEID_DOUBLE)
controller.insertDouble(offset, *reinterpret_cast<double *>(ref));
emit controller.insertDouble(offset,
*reinterpret_cast<double *>(ref));
else if ((typeId & asTYPEID_MASK_OBJECT) == 0)
controller.insertInt32(offset, *reinterpret_cast<int *>(ref));
emit controller.insertInt32(offset, *reinterpret_cast<int *>(ref));
else if (typeId & asTYPEID_SCRIPTOBJECT) {
// Dereference handles, so we can see what it points to
void *value = ref;
@ -1585,7 +1596,7 @@ bool WingAngelAPI::_HexReader_insert(qsizetype offset, void *ref, int typeId) {
int enumVal;
t->GetEnumValueByIndex(n, &enumVal);
if (enumVal == *(int *)value) {
controller.insertInt32(offset, enumVal);
emit controller.insertInt32(offset, enumVal);
break;
}
}
@ -1602,7 +1613,7 @@ bool WingAngelAPI::_HexReader_insert(qsizetype offset, void *ref, int typeId) {
if (value) {
// TODO support other type, now only string
if (type->GetTypeId() == (typeId & ~asTYPEID_OBJHANDLE)) {
controller.insertString(
emit controller.insertString(
offset, *reinterpret_cast<QString *>(value));
}
}
@ -1622,21 +1633,21 @@ bool WingAngelAPI::_HexReader_append(qsizetype offset, void *ref, int typeId) {
if (typeId == asTYPEID_VOID)
return false;
else if (typeId == asTYPEID_BOOL)
controller.appendInt8(*reinterpret_cast<bool *>(ref) ? 1 : 0);
emit controller.appendInt8(*reinterpret_cast<bool *>(ref) ? 1 : 0);
else if (typeId == asTYPEID_INT8 || typeId == asTYPEID_UINT8)
controller.appendInt8(*reinterpret_cast<qint8 *>(ref));
emit controller.appendInt8(*reinterpret_cast<qint8 *>(ref));
else if (typeId == asTYPEID_INT16 || typeId == asTYPEID_UINT16)
controller.appendInt16(*reinterpret_cast<qint16 *>(ref));
emit controller.appendInt16(*reinterpret_cast<qint16 *>(ref));
else if (typeId == asTYPEID_INT32 || typeId == asTYPEID_UINT32)
controller.appendInt32(*reinterpret_cast<qint32 *>(ref));
emit controller.appendInt32(*reinterpret_cast<qint32 *>(ref));
else if (typeId == asTYPEID_INT64 || typeId == asTYPEID_UINT64)
controller.appendInt64(*reinterpret_cast<qint64 *>(ref));
emit controller.appendInt64(*reinterpret_cast<qint64 *>(ref));
else if (typeId == asTYPEID_FLOAT)
controller.appendFloat(*reinterpret_cast<float *>(ref));
emit controller.appendFloat(*reinterpret_cast<float *>(ref));
else if (typeId == asTYPEID_DOUBLE)
controller.appendDouble(*reinterpret_cast<double *>(ref));
emit controller.appendDouble(*reinterpret_cast<double *>(ref));
else if ((typeId & asTYPEID_MASK_OBJECT) == 0)
controller.appendInt32(*reinterpret_cast<int *>(ref));
emit controller.appendInt32(*reinterpret_cast<int *>(ref));
else if (typeId & asTYPEID_SCRIPTOBJECT) {
// Dereference handles, so we can see what it points to
void *value = ref;
@ -1649,7 +1660,7 @@ bool WingAngelAPI::_HexReader_append(qsizetype offset, void *ref, int typeId) {
int enumVal;
t->GetEnumValueByIndex(n, &enumVal);
if (enumVal == *(int *)value) {
controller.appendInt32(enumVal);
emit controller.appendInt32(enumVal);
break;
}
}
@ -1666,7 +1677,7 @@ bool WingAngelAPI::_HexReader_append(qsizetype offset, void *ref, int typeId) {
if (value) {
// TODO support other type, now only string
if (type->GetTypeId() == (typeId & ~asTYPEID_OBJHANDLE)) {
controller.appendString(
emit controller.appendString(
*reinterpret_cast<QString *>(value));
}
}
@ -1853,7 +1864,7 @@ bool WingAngelAPI::_DataVisual_updateTextList(int stringID,
bool o = false;
auto ret = cArray2QStringList(data, stringID, &o);
if (o) {
return visual.updateTextList(ret);
return emit visual.updateTextList(ret);
} else {
return false;
}
@ -1867,7 +1878,7 @@ bool WingAngelAPI::_DataVisual_updateTextTable(
if (o) {
auto hn = cArray2QStringList(headerNames, stringID, &o);
if (o) {
return visual.updateTextTable(json, h, hn);
return emit visual.updateTextTable(json, h, hn);
} else {
return false;
}

View File

@ -59,7 +59,9 @@ void WingMessageBox::aboutQt(QWidget *parent, const QString &title) {
"information.</p>")
.arg(QStringLiteral("qt.io/licensing"), QStringLiteral("qt.io"));
auto msgbox = new QMessageBox(parent);
auto d = new FramelessDialogBase(parent);
auto msgbox = new QMessageBox;
msgbox->setText(translatedTextAboutQtCaption);
msgbox->setInformativeText(translatedTextAboutQtText);
@ -69,20 +71,19 @@ void WingMessageBox::aboutQt(QWidget *parent, const QString &title) {
msgbox->setWindowFlag(Qt::Widget);
FramelessDialogBase d(parent);
d.buildUpContent(msgbox);
d.setMaximumSize(0, 0);
d.setWindowTitle(title.isEmpty() ? QMessageBox::tr("About Qt") : title);
d->buildUpContent(msgbox);
d->setMaximumSize(0, 0);
d->setWindowTitle(title.isEmpty() ? QMessageBox::tr("About Qt") : title);
auto e = new EventFilter(QEvent::Resize, &d);
QObject::connect(e, &EventFilter::eventTriggered, &d,
[&d] { Utilities::moveToCenter(&d); });
d.installEventFilter(e);
auto e = new EventFilter(QEvent::Resize, d);
QObject::connect(e, &EventFilter::eventTriggered, d,
[d] { Utilities::moveToCenter(d); });
d->installEventFilter(e);
QObject::connect(msgbox, &QMessageBox::finished, &d,
QObject::connect(msgbox, &QMessageBox::finished, d,
&FramelessDialogBase::done);
d.exec();
d->exec();
}
QMessageBox::StandardButton

View File

@ -1,439 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2006-2009 fullmetalcoder <fullmetalcoder@hotmail.fr>
**
** This file is part of the Edyuk project <http://edyuk.org>
**
** This file may be used under the terms of the GNU General Public License
** version 3 as published by the Free Software Foundation and appearing in the
** file GPL.txt included in the packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
#include "qcodemodel.h"
/*!
\file qcodemodel.cpp
\brief Implementation of the QCodeModel class.
*/
#include "qcodenode.h"
#define Q_EXTRACT_INDEX(i, d) \
QCodeNode *d = static_cast<QCodeNode *>(i.internalPointer());
#include <QStack>
void QCodeModel::q_cache(QCodeNode *n, QByteArray cxt = QByteArray()) {
if (isCachable(n, cxt)) {
m_cache.insert(cxt, n);
// qDebug("Caching %s [0x%x] in 0x%x", cxt.constData(), n, this);
}
for (auto &child : n->children()) {
q_cache(child, cxt);
}
}
void QCodeModel::q_uncache(QCodeNode *n, QByteArray cxt = QByteArray()) {
if (isCachable(n, cxt)) {
m_cache.remove(cxt);
// qDebug("De-Caching %s", cxt.constData());
}
for (auto &child : n->children()) {
q_uncache(child, cxt);
}
}
/*!
\class QCodeModel
\brief Class used to store code hierarchies and display them through
model/view
*/
/*!
\brief ctor
*/
QCodeModel::QCodeModel(QObject *p) : QAbstractItemModel(p) {}
/*!
\brief dtor
*/
QCodeModel::~QCodeModel() { clearTopLevelNodes(); }
/*!
\return A list of code nodes occupying the top level of the model
(unparented ones)
*/
QList<QCodeNode *> QCodeModel::topLevelNodes() const { return m_topLevel; }
/*!
\brief Please read Qt docs on Model/View framework for more informations
*/
void QCodeModel::beginInsertRows(const QModelIndex idx, int beg, int end) {
QAbstractItemModel::beginInsertRows(idx, beg, end);
Q_EXTRACT_INDEX(idx, parent)
m_cache_ops.push(CacheOp(parent, beg, end));
}
/*!
\brief Please read Qt docs on Model/View framework for more informations
*/
void QCodeModel::beginRemoveRows(const QModelIndex idx, int beg, int end) {
QAbstractItemModel::beginRemoveRows(idx, beg, end);
Q_EXTRACT_INDEX(idx, parent)
const QList<QCodeNode *> &l = parent ? parent->children() : m_topLevel;
QByteArray cxt;
if (parent)
cxt = parent->qualifiedName();
// qDebug("uncaching %i out of %i", l.count(), end - beg + 1);
for (int i = beg; (i <= end) && (i < l.count()); ++i)
q_uncache(l.at(i), cxt);
}
/*!
\brief Please read Qt docs on Model/View framework for more informations
*/
void QCodeModel::endInsertRows() {
if (m_cache_ops.count()) {
CacheOp op = m_cache_ops.pop();
const QList<QCodeNode *> &l =
op.parent ? op.parent->children() : m_topLevel;
QByteArray cxt;
if (op.parent)
cxt = op.parent->qualifiedName();
for (int i = op.begin; i <= op.end; ++i)
q_cache(l.at(i), cxt);
} else {
qDebug("Odd things happenning over there...");
}
QAbstractItemModel::endInsertRows();
}
/*!
\brief Please read Qt docs on Model/View framework for more informations
*/
void QCodeModel::endRemoveRows() { QAbstractItemModel::endRemoveRows(); }
/*!
\brief Append a top level code node to the model
*/
void QCodeModel::appendTopLevelNode(QCodeNode *n) {
if (!n)
return;
int row = m_topLevel.count();
beginInsertRows(QModelIndex(), row, row);
m_topLevel.insert(row, n);
QStack<QCodeNode *> nodes;
nodes.push(n);
while (nodes.count()) {
n = nodes.pop();
n->setModel(this);
foreach (QCodeNode *c, n->children())
nodes.push(c);
}
endInsertRows();
}
/*!
\brief remove a top level code node from the model
*/
void QCodeModel::removeTopLevelNode(QCodeNode *n) {
int row = n ? m_topLevel.indexOf(n) : -1;
if (row == -1)
return;
beginRemoveRows(QModelIndex(), row, row);
m_topLevel.removeAt(row);
QStack<QCodeNode *> nodes;
nodes.push(n);
while (nodes.count()) {
n = nodes.pop();
n->setModel(nullptr);
for (auto &c : n->children()) {
nodes.push(c);
}
}
endRemoveRows();
}
/*!
\brief remove all top level nodes from the model
\warning All the nodes get DELETED.
*/
void QCodeModel::clearTopLevelNodes() {
int row = m_topLevel.count() - 1;
if (row == -1)
return;
beginRemoveRows(QModelIndex(), 0, row);
qDeleteAll(m_topLevel);
m_topLevel.clear();
/*
QCodeNode *n;
QStack<QCodeNode*> nodes;
foreach ( n, m_topLevel )
nodes.push(n);
while ( nodes.count() )
{
n = nodes.pop();
n->model = 0;
foreach ( QCodeNode *c, n->children )
nodes.push(c);
}
*/
endRemoveRows();
}
/*!
\brief Find a node in the internal cache
\param language concerned programming language
\param name bare name of the node (e.g class name, typedef, function
name, variable name, ...) \return the first node found or 0 if none matching
*/
QCodeNode *QCodeModel::findNode(const QByteArray &language,
const QByteArray &name) {
QByteArray id = name;
if (language.length())
id.prepend("::").prepend(language);
QHash<QByteArray, QCodeNode *>::const_iterator i = m_cache.constFind(id);
if (i != m_cache.constEnd()) {
// qDebug("%s found... [%s] : 0x%x", name.constData(), id.constData(),
// *i);
return *i;
}
// qDebug("%s not found... [%s]", name.constData(), id.constData());
return 0;
}
/*!
\brief Find nodes in the internal cache
\param name prefix to match against the bare name of the nodes (e.g
class name, typedef, function name, variable name, ...) \return the first
node found or 0 if none matching
*/
QList<QCodeNode *> QCodeModel::findRootNodes(const QByteArray &name) {
QList<QCodeNode *> l;
for (auto &g : m_topLevel) {
for (auto &r : g->children()) {
if (r->role(QCodeNode::Name) == name)
l << r;
}
}
return l;
}
/*!
\return whether the given node is worth caching
\param n node to test
\param cxt cache context
*/
bool QCodeModel::isCachable(QCodeNode *n, QByteArray &cxt) const {
int t = n->type();
QByteArray qn = n->role(QCodeNode::Name);
if (cxt.length())
qn.prepend("::");
if (cxt.isEmpty() && (t != QCodeNode::Group)) {
cxt += qn;
return true;
} else if ((t == QCodeNode::Enum) || /*(t == QCodeNode::Union) ||*/
(t == QCodeNode::Class) || /*(t == QCodeNode::Struct) ||*/
(t == QCodeNode::Typedef)) {
cxt += qn;
return true;
} else if (t == QCodeNode::Namespace) {
cxt += qn;
return true;
}
return false;
}
/*!
\brief Please read Qt docs on Model/View framework for more informations
*/
bool QCodeModel::hasChildren(const QModelIndex &parent) const {
return rowCount(parent);
}
/*!
\brief Please read Qt docs on Model/View framework for more informations
*/
int QCodeModel::rowCount(const QModelIndex &parent) const {
if (!parent.isValid())
return m_topLevel.count();
Q_EXTRACT_INDEX(parent, item)
return item ? item->children().count() : 0;
}
/*!
\brief Please read Qt docs on Model/View framework for more informations
*/
int QCodeModel::columnCount(const QModelIndex &) const { return 1; }
/*!
\brief Please read Qt docs on Model/View framework for more informations
*/
QVariant QCodeModel::data(const QModelIndex &index, int role) const {
if (!index.isValid() || index.column())
return QVariant();
Q_EXTRACT_INDEX(index, item)
return item ? item->data(role) : QVariant();
}
/*!
\brief Please read Qt docs on Model/View framework for more informations
*/
Qt::ItemFlags QCodeModel::flags(const QModelIndex &index) const {
if (!index.isValid())
return Qt::ItemIsEnabled;
return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
}
/*!
\brief Please read Qt docs on Model/View framework for more informations
*/
QVariant QCodeModel::headerData(int, Qt::Orientation, int) const {
return QVariant();
}
/*!
\brief Please read Qt docs on Model/View framework for more informations
*/
QCodeNode *QCodeModel::node(const QModelIndex &idx) const {
Q_EXTRACT_INDEX(idx, n)
return idx.isValid() ? n : 0;
}
/*!
\brief Please read Qt docs on Model/View framework for more informations
*/
QModelIndex QCodeModel::index(QCodeNode *n) const {
return n ? createIndex(n->parent() ? n->parent()->children().indexOf(n)
: m_topLevel.indexOf(n),
0, n)
: QModelIndex();
}
/*!
\brief Please read Qt docs on Model/View framework for more informations
*/
QModelIndex QCodeModel::index(int row, int column,
const QModelIndex &parent) const {
if ((row < 0) || column)
return QModelIndex();
Q_EXTRACT_INDEX(parent, item)
QCodeNode *abs = 0;
// qDebug("asking index...");
if (!parent.isValid() && (row < m_topLevel.count())) {
abs = m_topLevel.at(row);
} else if (item && (row < item->children().count())) {
abs = item->children().at(row);
}
#ifdef _TRACE_MODEL_
qDebug("%s(%i, %i) : %s",
item ? qPrintable(item->data(Qt::DisplayRole).toString()) : "root",
row, column,
abs ? qPrintable(abs->data(Qt::DisplayRole).toString()) : "!none!");
#endif
return abs ? createIndex(row, column, abs) : QModelIndex();
}
/*!
\brief Please read Qt docs on Model/View framework for more informations
*/
QModelIndex QCodeModel::parent(const QModelIndex &index) const {
if (!index.isValid()) {
return QModelIndex();
}
QCodeNode *parent = 0;
Q_EXTRACT_INDEX(index, child)
if (child)
parent = child->parent();
#ifdef _TRACE_MODEL_
qDebug("%s->parent() = %s",
child ? qPrintable(child->data(Qt::DisplayRole).toString())
: "@invalid@",
parent ? qPrintable(parent->data(Qt::DisplayRole).toString())
: "!none!");
#endif
if (!parent)
return QModelIndex();
const int row = parent->parent()
? parent->parent()->children().indexOf(parent)
: m_topLevel.indexOf(parent);
return createIndex(row, 0, parent);
}

View File

@ -1,89 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2006-2009 fullmetalcoder <fullmetalcoder@hotmail.fr>
**
** This file is part of the Edyuk project <http://edyuk.org>
**
** This file may be used under the terms of the GNU General Public License
** version 3 as published by the Free Software Foundation and appearing in the
** file GPL.txt included in the packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
#ifndef _QCODE_MODEL_H_
#define _QCODE_MODEL_H_
#include <QAbstractItemModel>
#include <QHash>
#include <QStack>
class QCodeNode;
class QCodeModel : public QAbstractItemModel {
Q_OBJECT
friend class QCodeNode;
public:
enum ExtraRoles { TypeRole = Qt::UserRole, VisibilityRole };
QCodeModel(QObject *p = nullptr);
virtual ~QCodeModel();
QVariant data(const QModelIndex &index, int role) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const;
QModelIndex index(QCodeNode *n) const;
QCodeNode *node(const QModelIndex &idx) const;
QModelIndex index(int row, int column,
const QModelIndex &parent = QModelIndex()) const;
QModelIndex parent(const QModelIndex &index) const;
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
bool hasChildren(const QModelIndex &parent = QModelIndex()) const;
QList<QCodeNode *> topLevelNodes() const;
void appendTopLevelNode(QCodeNode *n);
void removeTopLevelNode(QCodeNode *n);
void clearTopLevelNodes();
QList<QCodeNode *> findRootNodes(const QByteArray &name);
QCodeNode *findNode(const QByteArray &language, const QByteArray &name);
virtual bool isCachable(QCodeNode *n, QByteArray &cxt) const;
protected:
void beginInsertRows(const QModelIndex idx, int beg, int end);
void beginRemoveRows(const QModelIndex idx, int beg, int end);
void endInsertRows();
void endRemoveRows();
private:
struct CacheOp {
inline CacheOp() : parent(0), begin(-1), end(-1) {}
inline CacheOp(QCodeNode *n, int b, int e)
: parent(n), begin(b), end(e) {}
QCodeNode *parent;
int begin;
int end;
};
void q_cache(QCodeNode *n, QByteArray cxt);
void q_uncache(QCodeNode *n, QByteArray cxt);
QList<QCodeNode *> m_topLevel;
QStack<CacheOp> m_cache_ops;
QHash<QByteArray, QCodeNode *> m_cache;
};
#endif // !_QCODE_MODEL_H_

View File

@ -1,76 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2006-2009 fullmetalcoder <fullmetalcoder@hotmail.fr>
**
** This file is part of the Edyuk project <http://edyuk.org>
**
** This file may be used under the terms of the GNU General Public License
** version 3 as published by the Free Software Foundation and appearing in the
** file GPL.txt included in the packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
#include "qcodeproxymodel.h"
/*!
\file qcodeproxymodel.cpp
\brief Implementation of the QCodeProxyModel class.
*/
#include "qcodemodel.h"
#include "qcodenode.h"
static QList<int> priority = QList<int>()
<< QCodeNode::Group << QCodeNode::Namespace
<< QCodeNode::Class
// << QCodeNode::Struct << QCodeNode::Union
<< QCodeNode::Enum << QCodeNode::Typedef
<< QCodeNode::Function << QCodeNode::Variable;
/*!
\class QCodeProxyModel
\brief Special proxy model for code models
*/
QCodeProxyModel::QCodeProxyModel(QObject *p) : QSortFilterProxyModel(p) {
setDynamicSortFilter(true);
}
QCodeProxyModel::~QCodeProxyModel() {}
bool QCodeProxyModel::lessThan(const QModelIndex &left,
const QModelIndex &right) const {
int lt = priority.indexOf(
sourceModel()->data(left, QCodeModel::TypeRole).toInt()),
rt = priority.indexOf(
sourceModel()->data(right, QCodeModel::TypeRole).toInt());
// if ( lt == rt )
// return QSortFilterProxyModel::lessThan(left, right);
/*
foreach ( int p, priority )
{
if ( lt == p )
return false;
else if ( rt == p )
return true;
}
int lv = sourceModel()->data(left, QCodeModel::VisibilityRole).toInt(),
rv = sourceModel()->data(right, QCodeModel::VisibilityRole).toInt();
if ( lv != rv )
return lv > rv;
*/
QString ld = sourceModel()->data(left, Qt::DisplayRole).toString(),
rd = sourceModel()->data(right, Qt::DisplayRole).toString();
// return !((lt == rt) ? (QString::localeAwareCompare(ld, rd) < 0) : (lt <
// rt));
return !((lt == rt) ? (ld.toUpper() < rd.toUpper()) : (lt < rt));
}

View File

@ -1,38 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2006-2009 fullmetalcoder <fullmetalcoder@hotmail.fr>
**
** This file is part of the Edyuk project <http://edyuk.org>
**
** This file may be used under the terms of the GNU General Public License
** version 3 as published by the Free Software Foundation and appearing in the
** file GPL.txt included in the packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
#ifndef _QCODE_PROXY_MODEL_H_
#define _QCODE_PROXY_MODEL_H_
/*!
\file qcodeproxymodel.h
\brief Definition of the QCodeProxyModel class.
*/
#include <QSortFilterProxyModel>
class QCodeProxyModel : public QSortFilterProxyModel {
Q_OBJECT
public:
QCodeProxyModel(QObject *p = nullptr);
virtual ~QCodeProxyModel();
protected:
virtual bool lessThan(const QModelIndex &left,
const QModelIndex &right) const;
};
#endif // !_QCODE_PROXY_MODEL_H_

View File

@ -1,158 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2006-2009 fullmetalcoder <fullmetalcoder@hotmail.fr>
**
** This file is part of the Edyuk project <http://edyuk.org>
**
** This file may be used under the terms of the GNU General Public License
** version 3 as published by the Free Software Foundation and appearing in the
** file GPL.txt included in the packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
#include "qcodeview.h"
/*!
\file qcodeview.cpp
\brief Implementation of the QCodeView class.
*/
#include "qcodemodel.h"
#include "qcodenode.h"
#include <QAbstractProxyModel>
#include <QContextMenuEvent>
#include <QFileInfo>
/*!
\class QCodeView
\brief Specialized tree view to display code models
*/
QCodeView::QCodeView(QWidget *p) : QTreeView(p) {
setAutoScroll(true);
setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
connect(this, SIGNAL(activated(QModelIndex)), this,
SLOT(indexActivated(QModelIndex)));
}
QCodeView::QCodeView(QCodeModel *m, QWidget *p) : QTreeView(p), m_model(0) {
setAutoScroll(true);
setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
connect(this, SIGNAL(activated(QModelIndex)), this,
SLOT(indexActivated(QModelIndex)));
QCodeView::setModel(m);
}
QCodeView::~QCodeView() {}
void QCodeView::setModel(QAbstractItemModel *model) {
QAbstractProxyModel *proxy = qobject_cast<QAbstractProxyModel *>(model);
if (proxy) {
m_model = qobject_cast<QCodeModel *>(proxy->sourceModel());
} else {
m_model = qobject_cast<QCodeModel *>(model);
}
if (!m_model)
qFatal("QCodeView can only display a QCodeModel");
QTreeView::setModel(model);
}
void QCodeView::contextMenuEvent(QContextMenuEvent *e) {
e->accept();
QModelIndex idx = indexAt(e->pos());
if (!idx.isValid())
return;
}
void QCodeView::indexActivated(const QModelIndex &idx) {
static QStringList exts = QStringList() << "cpp"
<< "cxx"
<< "c"
<< "cc";
if (!m_model)
return;
QCodeNode *n = 0;
QAbstractProxyModel *proxy = qobject_cast<QAbstractProxyModel *>(model());
if (proxy) {
n = m_model->node(proxy->mapToSource(idx));
} else {
n = m_model->node(idx);
}
if (!n)
return;
QString cxt = n->context();
if (n->type() == QCodeNode::Function) {
// open the source file instead (after checking whether it lies in
// header...)
QFileInfo inf(cxt);
foreach (const QString &ext, exts) {
QString scxt = cxt;
scxt.chop(inf.suffix().length());
scxt += ext;
if (QFile::exists(scxt)) {
cxt = scxt;
break;
}
}
} else if (n->getLine() != -1) {
emit actionRequested("open", QStringList()
<< cxt << "-l"
<< QString::number(n->getLine()));
return;
}
int i;
QString ptp, rxp, qn = n->qualifiedName(false);
// qDebug("%s [%s] {%s}", qPrintable(qn),
// qPrintable(n->data(Qt::DisplayRole).toString()),
// n->role(QCodeNode::NodeType).constData());
// qn.remove(0, qn.indexOf("/") + 1);
ptp = qn;
rxp = QRegularExpression::escape(qn);
static QRegularExpression rxp_r(
"\\s*(::|\\\\[()\\[\\]{}|*$+.?^]|[,&<>])\\s*");
rxp.replace(rxp_r, "\\s*\\1\\s*");
rxp.replace(" ", "\\s+");
i = rxp.indexOf("(");
QString tmp = rxp.mid(i);
static QRegularExpression tmp_r(
"(\\\\s[+*])[\\w_]+\\\\s\\*(,|\\\\\\)\\\\s\\*$)");
tmp.replace(tmp_r, QStringLiteral("\\1[\\w_]*\\s*\\2"));
rxp = rxp.left(i) + tmp;
static QRegularExpression ptp_r(" (::|[()<>]) ");
ptp.replace(ptp_r, QStringLiteral("\\1"));
i = ptp.indexOf("(");
if (i != -1)
ptp = ptp.left(i);
emit actionRequested("open", QStringList()
<< cxt << "-s" << ptp << "-rx" << rxp);
}

View File

@ -1,51 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2006-2009 fullmetalcoder <fullmetalcoder@hotmail.fr>
**
** This file is part of the Edyuk project <http://edyuk.org>
**
** This file may be used under the terms of the GNU General Public License
** version 3 as published by the Free Software Foundation and appearing in the
** file GPL.txt included in the packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
#ifndef _QCODE_VIEW_H_
#define _QCODE_VIEW_H_
/*!
\file qcodeview.h
\brief Definition of the QCodeView class.
*/
#include <QTreeView>
class QCodeModel;
class QCodeView : public QTreeView {
Q_OBJECT
public:
QCodeView(QWidget *p = nullptr);
QCodeView(QCodeModel *m, QWidget *p = nullptr);
virtual ~QCodeView();
virtual void setModel(QAbstractItemModel *model);
signals:
void actionRequested(const QString &action, const QStringList &params);
protected:
virtual void contextMenuEvent(QContextMenuEvent *e);
protected slots:
void indexActivated(const QModelIndex &idx);
private:
QCodeModel *m_model;
};
#endif // !_QCODE_VIEW_H_

View File

@ -1,94 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2006-2009 fullmetalcoder <fullmetalcoder@hotmail.fr>
**
** This file is part of the Edyuk project <http://edyuk.org>
**
** This file may be used under the terms of the GNU General Public License
** version 3 as published by the Free Software Foundation and appearing in the
** file GPL.txt included in the packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
#include "qsourcecodewatcher.h"
#include "qcodemodel.h"
#include "qcodenode.h"
#include <QTimerEvent>
QList<QSourceCodeWatcher *> QSourceCodeWatcher::m_instances;
QSourceCodeWatcher *QSourceCodeWatcher::watcher(QCodeNode *t, QCodeParser *c) {
if (!t)
return nullptr;
for (int i = 0; i < m_instances.count(); ++i) {
if (m_instances.at(i)->m_target == t) {
return m_instances[i];
}
}
return c ? new QSourceCodeWatcher(t, c, t->model()) : 0;
}
QSourceCodeWatcher::QSourceCodeWatcher(QCodeNode *n, QCodeParser *c, QObject *p)
: QFileSystemWatcher(p), m_target(n), m_parser(c) {
connect(this, SIGNAL(fileChanged(QString)), this,
SLOT(sourceChanged(QString)));
m_instances << this;
// qDebug("%i watchers", m_instances.count());
}
QSourceCodeWatcher::~QSourceCodeWatcher() {
m_instances.removeAll(this);
// qDebug("%i watchers left", m_instances.count());
}
void QSourceCodeWatcher::timerEvent(QTimerEvent *e) {
if (e->timerId() != m_timer.timerId())
return QFileSystemWatcher::timerEvent(e);
if (!m_parser)
return;
QHash<QString, char>::iterator it = m_state.begin();
while (it != m_state.end()) {
if (*it & Duplicate) {
// postpone...
*it = Recent;
++it;
} else {
// process
// m_parser->update(m_target, it.key());
// TODO
it = m_state.erase(it);
}
}
if (m_state.count()) {
m_timer.start(50, this);
}
}
void QSourceCodeWatcher::sourceChanged(const QString &filepath) {
if (!m_target)
return;
m_timer.stop();
if (!m_state.contains(filepath)) {
m_state[filepath] = Recent;
} else {
m_state[filepath] = Recent | Duplicate;
}
m_timer.start(50, this);
}

View File

@ -1,55 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2006-2009 fullmetalcoder <fullmetalcoder@hotmail.fr>
**
** This file is part of the Edyuk project <http://edyuk.org>
**
** This file may be used under the terms of the GNU General Public License
** version 3 as published by the Free Software Foundation and appearing in the
** file GPL.txt included in the packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
#ifndef _QSOURCE_CODE_WATCHER_H_
#define _QSOURCE_CODE_WATCHER_H_
#include <QFileSystemWatcher>
#include <QHash>
#include <QTimer>
struct QCodeNode;
class QCodeParser;
class QSourceCodeWatcher : public QFileSystemWatcher {
friend struct QCodeNode;
Q_OBJECT
public:
static QSourceCodeWatcher *watcher(QCodeNode *t, QCodeParser *c = nullptr);
protected:
QSourceCodeWatcher(QCodeNode *n, QCodeParser *c, QObject *p = nullptr);
virtual ~QSourceCodeWatcher();
virtual void timerEvent(QTimerEvent *e);
private slots:
void sourceChanged(const QString &filepath);
private:
enum State { Recent = 1, Duplicate = 2 };
QHash<QString, char> m_state;
QBasicTimer m_timer;
QCodeNode *m_target;
QCodeParser *m_parser;
static QList<QSourceCodeWatcher *> m_instances;
};
#endif // !_QSOURCE_CODE_WATCHER_H_

View File

@ -87,7 +87,7 @@ public:
public slots:
EditorView *clone();
void registerView(WingEditorViewWidget *view);
void registerView(WingHex::WingEditorViewWidget *view);
void switchView(qsizetype index);
void registerQMenu(QMenu *menu);

View File

@ -21,8 +21,7 @@
#include "qdocumentline.h"
#include "qeditor.h"
#include "codemodel/qcodemodel.h"
#include "codemodel/qcodenode.h"
#include "class/qcodenode.h"
#include "class/ascompletion.h"
@ -220,12 +219,20 @@ void QCodeCompletionWidget::complete(const QModelIndex &index) {
if (prefix.length() && txt.startsWith(prefix))
txt.remove(0, prefix.length());
// c.insertText(txt);
if (m_begin.isValid() && c > m_begin) {
m_begin.movePosition(c.position() - m_begin.position(),
QDocumentCursor::NextCharacter,
QDocumentCursor::KeepAnchor);
m_begin.removeSelectedText();
m_begin = QDocumentCursor();
}
e->write(txt);
if (back) {
// TODO : move back generically...
// c.movePosition(1, QDocumentCursor::PreviousCharacter);
auto c = e->cursor();
c.movePosition(1, QDocumentCursor::PreviousCharacter);
e->setCursor(c);
}
e->setFocus();
@ -366,8 +373,6 @@ void QCodeCompletionWidget::keyPressEvent(QKeyEvent *e) {
////////////////////////////////
// static char *_q_authenticate_string = "x-application/QCodeCompletionModel";
QCodeCompletionModel::QCodeCompletionModel(QObject *p)
: QAbstractListModel(p), bUpdate(false) {}
@ -416,7 +421,7 @@ void QCodeCompletionModel::forceUpdate() const {
if (c->type() == QCodeNode::Enum) {
if (match(c, m_filter))
for (QCodeNode *ev : c->children())
for (auto &ev : c->children())
if (match(ev, m_filter, m_prefix))
m_visibles << ev;
}

View File

@ -19,7 +19,7 @@
#include <QListView>
#include <QPointer>
#include "codemodel/qcodenode.h"
#include "class/qcodenode.h"
#include "qdocumentcursor.h"
#include "qeditor.h"

View File

@ -74,7 +74,7 @@ MainWindow::MainWindow(QWidget *parent) : FramelessMainWindow(parent) {
// recent file manager init
m_recentMenu = new QMenu(this);
m_recentmanager = new RecentFileManager(m_recentMenu);
m_recentmanager = new RecentFileManager(m_recentMenu, false);
connect(m_recentmanager, &RecentFileManager::triggered, this,
[=](const RecentFileManager::RecentInfo &rinfo) {
AppManager::instance()->openFile(
@ -153,12 +153,14 @@ MainWindow::MainWindow(QWidget *parent) : FramelessMainWindow(parent) {
// connect settings signals
connect(&set, &SettingManager::sigEditorfontSizeChanged, this,
[this](int v) {
for (auto &p : m_views.keys()) {
auto views = m_views.keys();
for (auto &p : views) {
p->setFontSize(qreal(v));
}
});
connect(&set, &SettingManager::sigCopylimitChanged, this, [this](int v) {
for (auto &p : m_views.keys()) {
auto views = m_views.keys();
for (auto &p : views) {
p->setCopyLimit(v);
}
});
@ -390,6 +392,8 @@ MainWindow::buildUpFindResultDock(ads::CDockManager *dock,
auto dw = buildDockWidget(dock, QStringLiteral("FindResult"),
tr("FindResult"), m_findresult);
m_find = dw;
return dock->addDockWidget(area, dw, areaw);
}
@ -459,8 +463,6 @@ ads::CDockAreaWidget *
MainWindow::buildUpHashResultDock(ads::CDockManager *dock,
ads::DockWidgetArea area,
ads::CDockAreaWidget *areaw) {
QStringList hashNames = Utilities::supportedHashAlgorithmStringList();
m_hashtable = new QTableViewExt(this);
Utilities::applyTableViewProperty(m_hashtable);
m_hashtable->setColumnWidth(0, 350);
@ -1415,7 +1417,6 @@ void MainWindow::on_saveas() {
}
}
auto oldFileName = editor->fileName();
QString workspace = m_views.value(editor);
if (editor->change2WorkSpace()) {
workspace = editor->fileName() + PROEXT;
@ -1628,6 +1629,7 @@ void MainWindow::on_findfile() {
tr("MayTooMuchFindResult"));
break;
}
m_find->raise();
});
}
}
@ -2277,7 +2279,8 @@ ads::CDockWidget *MainWindow::buildDockWidget(ads::CDockManager *dock,
}
EditorView *MainWindow::findEditorView(const QString &filename) {
for (auto &p : m_views.keys()) {
auto views = m_views.keys();
for (auto &p : views) {
#ifdef Q_OS_WIN
if (p->fileName().compare(filename, Qt::CaseInsensitive) == 0) {
#else
@ -2801,7 +2804,8 @@ void MainWindow::closeEvent(QCloseEvent *event) {
this, qAppName(), tr("ConfirmAPPSave"),
QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
if (ret == QMessageBox::Yes) {
for (auto &p : m_views.keys()) {
auto views = m_views.keys();
for (auto &p : views) {
emit p->closeRequested();
}
m_isOnClosing = false;
@ -2810,7 +2814,8 @@ void MainWindow::closeEvent(QCloseEvent *event) {
return;
}
} else if (ret == QMessageBox::No) {
for (auto &p : m_views.keys()) {
auto views = m_views.keys();
for (auto &p : views) {
p->closeDockWidget(); // force close
}
m_isOnClosing = false;

View File

@ -30,7 +30,7 @@
#include <QTextBrowser>
#include <QToolButton>
#include <QTreeView>
#include <QtConcurrent/QtConcurrent>
#include <QtConcurrent/QtConcurrentRun>
#include "QWingRibbon/ribbon.h"
#include "QWingRibbon/ribbonbuttongroup.h"
@ -434,6 +434,7 @@ private:
ScriptingConsole *m_scriptConsole = nullptr;
QTableViewExt *m_varshowtable = nullptr;
ads::CDockWidget *m_find = nullptr;
QTableViewExt *m_findresult = nullptr;
FindResultModel *_findEmptyResult = nullptr;

View File

@ -49,7 +49,7 @@ ScriptingDialog::ScriptingDialog(QWidget *parent)
// recent file manager init
m_recentMenu = new QMenu(this);
m_recentmanager = new RecentFileManager(m_recentMenu);
m_recentmanager = new RecentFileManager(m_recentMenu, true);
connect(m_recentmanager, &RecentFileManager::triggered, this,
[=](const RecentFileManager::RecentInfo &rinfo) {
openFile(rinfo.fileName);
@ -231,7 +231,7 @@ void ScriptingDialog::initConsole() {
void ScriptingDialog::saveDockLayout() {
auto &set = SettingManager::instance();
set.setScriptDockLayout(m_dock->saveState());
set.setScriptDockLayout(_savedLayout);
set.save(SettingManager::NONE);
}
@ -706,7 +706,7 @@ void ScriptingDialog::registerEditorView(ScriptEditor *editor) {
if (m_dock->focusedDockWidget() == editor) {
if (!m_views.isEmpty()) {
for (auto p : m_views) {
for (auto &p : m_views) {
if (p != editor && p->isCurrentTab()) {
p->setFocus();
}
@ -1104,8 +1104,6 @@ void ScriptingDialog::on_saveas() {
return;
m_lastusedpath = QFileInfo(filename).absoluteDir().absolutePath();
auto oldFileName = editor->fileName();
auto res = editor->save(filename);
if (res) {
Toast::toast(this, NAMEICONRES(QStringLiteral("saveas")),
@ -1302,6 +1300,8 @@ void ScriptingDialog::closeEvent(QCloseEvent *event) {
on_stopscript();
}
_savedLayout = m_dock->saveState();
auto &set = SettingManager::instance();
set.setRecentScriptFiles(m_recentmanager->saveRecent());
set.save(SettingManager::NONE);

View File

@ -252,6 +252,7 @@ private:
QLanguageFactory *m_language = nullptr;
QByteArray _defaultLayout;
QByteArray _savedLayout;
ScriptEditor *m_curEditor = nullptr;
QList<QWidget *> m_editStateWidgets;

View File

@ -2972,3 +2972,11 @@ QEditor
background-color: #282a36;
selection-background-color: #44475a;
}
QCallTip
{
qproperty-borderColor: #eff0f1;
qproperty-background: #31363b;
qproperty-foreground: #eff0f1;
qproperty-opacity: 0.8;
}