feat: 移除 QCodeNode 相关代码;
This commit is contained in:
parent
7987aca85c
commit
c9b624d100
|
@ -9,6 +9,8 @@
|
|||
QConsoleIODevice::QConsoleIODevice(QConsoleWidget *w, QObject *parent)
|
||||
: QIODevice(parent), widget_(w), readpos_(0), writtenSinceLastEmit_(0),
|
||||
readSinceLastEmit_(0) {
|
||||
setCurrentWriteChannel(QConsoleWidget::StandardOutput);
|
||||
|
||||
open(QIODevice::ReadWrite | QIODevice::Unbuffered);
|
||||
}
|
||||
|
||||
|
@ -50,7 +52,11 @@ qint64 QConsoleIODevice::readData(char *data, qint64 len) {
|
|||
|
||||
qint64 QConsoleIODevice::writeData(const char *data, qint64 len) {
|
||||
QByteArray ba(data, (int)len);
|
||||
widget_->write(ba);
|
||||
int ch = currentWriteChannel();
|
||||
if (ch == QConsoleWidget::StandardError)
|
||||
widget_->writeStdErr(ba);
|
||||
else
|
||||
widget_->writeStdOut(ba);
|
||||
|
||||
writtenSinceLastEmit_ += len;
|
||||
if (!signalsBlocked()) {
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
#include "QConsoleWidget.h"
|
||||
#include "QConsoleIODevice.h"
|
||||
#include "class/skinmanager.h"
|
||||
|
||||
#include <KSyntaxHighlighting/Repository>
|
||||
#include <KSyntaxHighlighting/Theme>
|
||||
|
||||
#include <QAbstractItemView>
|
||||
#include <QApplication>
|
||||
|
@ -20,29 +16,24 @@
|
|||
#include <QTextDocumentFragment>
|
||||
|
||||
QConsoleWidget::QConsoleWidget(QWidget *parent)
|
||||
: WingCodeEdit(parent), mode_(Output) {
|
||||
|
||||
setAutoCloseChar(true);
|
||||
|
||||
switch (SkinManager::instance().currentTheme()) {
|
||||
case SkinManager::Theme::Dark:
|
||||
setTheme(syntaxRepo().defaultTheme(
|
||||
KSyntaxHighlighting::Repository::DarkTheme));
|
||||
break;
|
||||
case SkinManager::Theme::Light:
|
||||
setTheme(syntaxRepo().defaultTheme(
|
||||
KSyntaxHighlighting::Repository::LightTheme));
|
||||
break;
|
||||
}
|
||||
|
||||
: QPlainTextEdit(parent), mode_(Output), completer_(0) {
|
||||
iodevice_ = new QConsoleIODevice(this, this);
|
||||
|
||||
QTextCharFormat fmt = currentCharFormat();
|
||||
for (int i = 0; i < nConsoleChannels; i++)
|
||||
chanFormat_[i] = fmt;
|
||||
|
||||
// chanFormat_[StandardOutput];
|
||||
chanFormat_[StandardError].setForeground(Qt::red);
|
||||
|
||||
setTextInteractionFlags(Qt::TextEditorInteraction);
|
||||
setUndoRedoEnabled(false);
|
||||
}
|
||||
|
||||
QConsoleWidget::~QConsoleWidget() {}
|
||||
|
||||
QConsoleWidget::ConsoleMode QConsoleWidget::mode() const { return mode_; }
|
||||
|
||||
void QConsoleWidget::setMode(ConsoleMode m) {
|
||||
if (m == mode_)
|
||||
return;
|
||||
|
@ -51,6 +42,7 @@ void QConsoleWidget::setMode(ConsoleMode m) {
|
|||
QTextCursor cursor = textCursor();
|
||||
cursor.movePosition(QTextCursor::End);
|
||||
setTextCursor(cursor);
|
||||
setCurrentCharFormat(chanFormat_[StandardInput]);
|
||||
inpos_ = cursor.position();
|
||||
mode_ = Input;
|
||||
}
|
||||
|
@ -60,6 +52,27 @@ void QConsoleWidget::setMode(ConsoleMode m) {
|
|||
}
|
||||
}
|
||||
|
||||
QIODevice *QConsoleWidget::device() const { return iodevice_; }
|
||||
|
||||
QTextCharFormat QConsoleWidget::channelCharFormat(ConsoleChannel ch) const {
|
||||
return chanFormat_[ch];
|
||||
}
|
||||
|
||||
void QConsoleWidget::setChannelCharFormat(ConsoleChannel ch,
|
||||
const QTextCharFormat &fmt) {
|
||||
chanFormat_[ch] = fmt;
|
||||
}
|
||||
|
||||
const QStringList &QConsoleWidget::completionTriggers() const {
|
||||
return completion_triggers_;
|
||||
}
|
||||
|
||||
void QConsoleWidget::setCompletionTriggers(const QStringList &l) {
|
||||
completion_triggers_ = l;
|
||||
}
|
||||
|
||||
QSize QConsoleWidget::sizeHint() const { return QSize(600, 400); }
|
||||
|
||||
QString QConsoleWidget::getCommandLine() {
|
||||
if (mode_ == Output)
|
||||
return QString();
|
||||
|
@ -72,8 +85,6 @@ QString QConsoleWidget::getCommandLine() {
|
|||
return code;
|
||||
}
|
||||
|
||||
QConsoleWidget::History &QConsoleWidget::history() { return history_; }
|
||||
|
||||
void QConsoleWidget::handleReturnKey() {
|
||||
QString code = getCommandLine();
|
||||
|
||||
|
@ -89,6 +100,7 @@ void QConsoleWidget::handleReturnKey() {
|
|||
if (!code.isEmpty())
|
||||
history_.add(code);
|
||||
|
||||
// append the newline char and
|
||||
// send signal / update iodevice
|
||||
if (iodevice_->isOpen())
|
||||
iodevice_->consoleWidgetInput(code);
|
||||
|
@ -108,15 +120,109 @@ void QConsoleWidget::handleTabKey() {
|
|||
if (text.isEmpty()) {
|
||||
tc.insertText(" ");
|
||||
} else {
|
||||
// updateCompleter();
|
||||
// if (completer_ && completer_->completionCount() == 1) {
|
||||
// insertCompletion(completer_->currentCompletion());
|
||||
// completer_->popup()->hide();
|
||||
// }
|
||||
updateCompleter();
|
||||
if (completer_ && completer_->completionCount() == 1) {
|
||||
insertCompletion(completer_->currentCompletion());
|
||||
completer_->popup()->hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QConsoleWidget::updateCompleter() {
|
||||
if (!completer_)
|
||||
return;
|
||||
|
||||
// if the completer is first shown, mark
|
||||
// the text position
|
||||
QTextCursor textCursor = this->textCursor();
|
||||
if (!completer_->popup()->isVisible()) {
|
||||
completion_pos_ = textCursor.position();
|
||||
// qDebug() << "show completer, pos " << completion_pos_;
|
||||
}
|
||||
|
||||
// Get the text between the current cursor position
|
||||
// and the start of the input
|
||||
textCursor.setPosition(inpos_, QTextCursor::KeepAnchor);
|
||||
QString commandText = textCursor.selectedText();
|
||||
// qDebug() << "code to complete: " << commandText;
|
||||
|
||||
// Call the completer to update the completion model
|
||||
// Place and show the completer if there are available completions
|
||||
|
||||
if (completer_->updateCompletionModel(commandText)) {
|
||||
// qDebug() << "found " << count << " completions";
|
||||
|
||||
// Get a QRect for the cursor at the start of the
|
||||
// current word and then translate it down 8 pixels.
|
||||
textCursor = this->textCursor();
|
||||
textCursor.movePosition(QTextCursor::StartOfWord);
|
||||
QRect cr = this->cursorRect(textCursor);
|
||||
cr.translate(0, 8);
|
||||
cr.setWidth(
|
||||
completer_->popup()->sizeHintForColumn(0) +
|
||||
completer_->popup()->verticalScrollBar()->sizeHint().width());
|
||||
completer_->complete(cr);
|
||||
} else {
|
||||
// qDebug() << "no completions - hiding";
|
||||
completer_->popup()->hide();
|
||||
}
|
||||
}
|
||||
|
||||
void QConsoleWidget::checkCompletionTriggers(const QString &txt) {
|
||||
if (!completer_ || completion_triggers_.isEmpty() || txt.isEmpty())
|
||||
return;
|
||||
|
||||
foreach (const QString &tr, completion_triggers_) {
|
||||
if (tr.endsWith(txt)) {
|
||||
QTextCursor tc = this->textCursor();
|
||||
tc.movePosition(QTextCursor::Left, QTextCursor::KeepAnchor,
|
||||
tr.length());
|
||||
if (tc.selectedText() == tr) {
|
||||
updateCompleter();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QConsoleWidget::insertCompletion(const QString &completion) {
|
||||
QTextCursor tc = textCursor();
|
||||
tc.movePosition(QTextCursor::Left, QTextCursor::KeepAnchor,
|
||||
tc.position() - inpos_ - completer_->insertPos());
|
||||
tc.insertText(completion, chanFormat_[StandardInput]);
|
||||
setTextCursor(tc);
|
||||
}
|
||||
|
||||
void QConsoleWidget::setCompleter(QConsoleWidgetCompleter *c) {
|
||||
if (completer_) {
|
||||
completer_->setWidget(0);
|
||||
QObject::disconnect(completer_, SIGNAL(activated(const QString &)),
|
||||
this, SLOT(insertCompletion(const QString &)));
|
||||
}
|
||||
completer_ = c;
|
||||
if (completer_) {
|
||||
completer_->setWidget(this);
|
||||
QObject::connect(completer_, SIGNAL(activated(const QString &)), this,
|
||||
SLOT(insertCompletion(const QString &)));
|
||||
}
|
||||
}
|
||||
|
||||
void QConsoleWidget::keyPressEvent(QKeyEvent *e) {
|
||||
if (completer_ && completer_->popup()->isVisible()) {
|
||||
// The following keys are forwarded by the completer to the widget
|
||||
switch (e->key()) {
|
||||
case Qt::Key_Tab:
|
||||
case Qt::Key_Enter:
|
||||
case Qt::Key_Return:
|
||||
case Qt::Key_Escape:
|
||||
case Qt::Key_Backtab:
|
||||
e->ignore();
|
||||
return; // let the completer do default behavior
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
QTextCursor textCursor = this->textCursor();
|
||||
bool selectionInEditZone = isSelectionInEditZone();
|
||||
|
||||
|
@ -159,7 +265,7 @@ void QConsoleWidget::keyPressEvent(QKeyEvent *e) {
|
|||
QApplication::clipboard()->mimeData();
|
||||
const QString text = clipboard->text();
|
||||
if (!text.isNull()) {
|
||||
textCursor.insertText(text);
|
||||
textCursor.insertText(text, channelCharFormat(StandardInput));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,8 +276,8 @@ void QConsoleWidget::keyPressEvent(QKeyEvent *e) {
|
|||
int key = e->key();
|
||||
int shiftMod = e->modifiers() == Qt::ShiftModifier;
|
||||
|
||||
// if (history_.isActive() && key != Qt::Key_Up && key != Qt::Key_Down)
|
||||
// history_.deactivate();
|
||||
if (history_.isActive() && key != Qt::Key_Up && key != Qt::Key_Down)
|
||||
history_.deactivate();
|
||||
|
||||
// Force the cursor back to the interactive area
|
||||
// for all keys except modifiers
|
||||
|
@ -202,7 +308,7 @@ void QConsoleWidget::keyPressEvent(QKeyEvent *e) {
|
|||
|
||||
case Qt::Key_Left:
|
||||
if (textCursor.position() > inpos_)
|
||||
WingCodeEdit::keyPressEvent(e);
|
||||
QPlainTextEdit::keyPressEvent(e);
|
||||
else {
|
||||
QApplication::beep();
|
||||
e->accept();
|
||||
|
@ -218,7 +324,7 @@ void QConsoleWidget::keyPressEvent(QKeyEvent *e) {
|
|||
if (textCursor.position() < inpos_)
|
||||
QApplication::beep();
|
||||
else
|
||||
WingCodeEdit::keyPressEvent(e);
|
||||
QPlainTextEdit::keyPressEvent(e);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -231,7 +337,7 @@ void QConsoleWidget::keyPressEvent(QKeyEvent *e) {
|
|||
if (textCursor.position() <= inpos_)
|
||||
QApplication::beep();
|
||||
else
|
||||
WingCodeEdit::keyPressEvent(e);
|
||||
QPlainTextEdit::keyPressEvent(e);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -260,9 +366,20 @@ void QConsoleWidget::keyPressEvent(QKeyEvent *e) {
|
|||
|
||||
default:
|
||||
e->accept();
|
||||
WingCodeEdit::keyPressEvent(e);
|
||||
setCurrentCharFormat(chanFormat_[StandardInput]);
|
||||
QPlainTextEdit::keyPressEvent(e);
|
||||
// check if the last key triggers a completion
|
||||
checkCompletionTriggers(e->text());
|
||||
break;
|
||||
}
|
||||
|
||||
if (completer_ && completer_->popup()->isVisible()) {
|
||||
// if the completer is visible check if it should be updated
|
||||
if (this->textCursor().position() < completion_pos_)
|
||||
completer_->popup()->hide();
|
||||
else
|
||||
updateCompleter();
|
||||
}
|
||||
}
|
||||
|
||||
void QConsoleWidget::contextMenuEvent(QContextMenuEvent *event) {
|
||||
|
@ -312,14 +429,14 @@ void QConsoleWidget::replaceCommandLine(const QString &str) {
|
|||
textCursor.setPosition(inpos_, QTextCursor::KeepAnchor);
|
||||
|
||||
// ... and replace it with new string.
|
||||
textCursor.insertText(str);
|
||||
textCursor.insertText(str, chanFormat_[StandardInput]);
|
||||
|
||||
// move to the end of the document
|
||||
textCursor.movePosition(QTextCursor::End);
|
||||
setTextCursor(textCursor);
|
||||
}
|
||||
|
||||
void QConsoleWidget::write(const QString &message) {
|
||||
void QConsoleWidget::write(const QString &message, const QTextCharFormat &fmt) {
|
||||
QTextCharFormat currfmt = currentCharFormat();
|
||||
QTextCursor tc = textCursor();
|
||||
|
||||
|
@ -340,7 +457,7 @@ void QConsoleWidget::write(const QString &message) {
|
|||
tc.insertBlock();
|
||||
tc.movePosition(QTextCursor::PreviousBlock);
|
||||
|
||||
tc.insertText(message);
|
||||
tc.insertText(message, fmt);
|
||||
tc.movePosition(QTextCursor::End);
|
||||
// restore input pos
|
||||
inpos_ = tc.position() - inpos_;
|
||||
|
@ -359,7 +476,7 @@ void QConsoleWidget::write(const QString &message) {
|
|||
|
||||
// insert text
|
||||
setTextCursor(tc1);
|
||||
textCursor().insertText(message);
|
||||
textCursor().insertText(message, fmt);
|
||||
ensureCursorVisible();
|
||||
|
||||
// restore cursor if needed
|
||||
|
@ -368,13 +485,22 @@ void QConsoleWidget::write(const QString &message) {
|
|||
}
|
||||
}
|
||||
|
||||
QConsoleWidget::History &QConsoleWidget::history() { return history_; }
|
||||
|
||||
void QConsoleWidget::writeStdOut(const QString &s) {
|
||||
write(s, chanFormat_[StandardOutput]);
|
||||
}
|
||||
|
||||
void QConsoleWidget::writeStdErr(const QString &s) {
|
||||
write(s, chanFormat_[StandardError]);
|
||||
}
|
||||
|
||||
/////////////////// QConsoleWidget::History /////////////////////
|
||||
|
||||
QConsoleWidget::History QConsoleWidget::history_;
|
||||
|
||||
QConsoleWidget::History::History(void)
|
||||
: pos_(0), active_(false), maxsize_(10000) {}
|
||||
|
||||
QConsoleWidget::History::~History(void) {}
|
||||
|
||||
void QConsoleWidget::History::add(const QString &str) {
|
||||
|
@ -439,4 +565,15 @@ QTextStream &inputMode(QTextStream &s) {
|
|||
d->widget()->setMode(QConsoleWidget::Input);
|
||||
return s;
|
||||
}
|
||||
QTextStream &outChannel(QTextStream &s) { return s; }
|
||||
QTextStream &outChannel(QTextStream &s) {
|
||||
QConsoleIODevice *d = qobject_cast<QConsoleIODevice *>(s.device());
|
||||
if (d)
|
||||
d->setCurrentWriteChannel(QConsoleWidget::StandardOutput);
|
||||
return s;
|
||||
}
|
||||
QTextStream &errChannel(QTextStream &s) {
|
||||
QConsoleIODevice *d = qobject_cast<QConsoleIODevice *>(s.device());
|
||||
if (d)
|
||||
d->setCurrentWriteChannel(QConsoleWidget::StandardError);
|
||||
return s;
|
||||
}
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
#ifndef _QCONSOLEWIDGET_H_
|
||||
#define _QCONSOLEWIDGET_H_
|
||||
|
||||
#include "WingCodeEdit/wingcodeedit.h"
|
||||
#include <QCompleter>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QTextStream>
|
||||
|
||||
class QConsoleIODevice;
|
||||
class QConsoleWidgetCompleter;
|
||||
|
||||
class QConsoleWidget : public WingCodeEdit {
|
||||
class QConsoleWidget : public QPlainTextEdit {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
struct History {
|
||||
QStringList strings_;
|
||||
|
@ -32,21 +35,40 @@ public:
|
|||
enum ConsoleMode { Input, Output };
|
||||
Q_ENUM(ConsoleMode)
|
||||
|
||||
QConsoleWidget(QWidget *parent = 0);
|
||||
~QConsoleWidget();
|
||||
enum ConsoleChannel {
|
||||
StandardInput,
|
||||
StandardOutput,
|
||||
StandardError,
|
||||
nConsoleChannels
|
||||
};
|
||||
Q_ENUM(ConsoleChannel)
|
||||
|
||||
ConsoleMode mode() const { return mode_; }
|
||||
public:
|
||||
explicit QConsoleWidget(QWidget *parent = nullptr);
|
||||
virtual ~QConsoleWidget();
|
||||
|
||||
public:
|
||||
ConsoleMode mode() const;
|
||||
void setMode(ConsoleMode m);
|
||||
QIODevice *device() const { return (QIODevice *)iodevice_; }
|
||||
|
||||
virtual QSize sizeHint() const override { return QSize(600, 400); }
|
||||
QIODevice *device() const;
|
||||
QTextCharFormat channelCharFormat(ConsoleChannel ch) const;
|
||||
void setChannelCharFormat(ConsoleChannel ch, const QTextCharFormat &fmt);
|
||||
const QStringList &completionTriggers() const;
|
||||
void setCompletionTriggers(const QStringList &l);
|
||||
virtual QSize sizeHint() const override;
|
||||
// write a formatted message to the console
|
||||
void write(const QString &message);
|
||||
|
||||
void write(const QString &message, const QTextCharFormat &fmt);
|
||||
static History &history();
|
||||
void setCompleter(QConsoleWidgetCompleter *c);
|
||||
// get the current command line
|
||||
QString getCommandLine();
|
||||
|
||||
static History &history();
|
||||
public slots:
|
||||
|
||||
// write to StandardOutput
|
||||
void writeStdOut(const QString &s);
|
||||
// write to StandardError
|
||||
void writeStdErr(const QString &s);
|
||||
|
||||
signals:
|
||||
|
||||
|
@ -60,7 +82,8 @@ protected:
|
|||
bool canCut() const { return isSelectionInEditZone(); }
|
||||
void handleReturnKey();
|
||||
void handleTabKey();
|
||||
|
||||
void updateCompleter();
|
||||
void checkCompletionTriggers(const QString &txt);
|
||||
// reimp QPlainTextEdit functions
|
||||
void keyPressEvent(QKeyEvent *e) override;
|
||||
void contextMenuEvent(QContextMenuEvent *event) override;
|
||||
|
@ -71,17 +94,43 @@ protected:
|
|||
// replace the command line
|
||||
void replaceCommandLine(const QString &str);
|
||||
|
||||
protected slots:
|
||||
|
||||
// insert the completion from completer
|
||||
void insertCompletion(const QString &completion);
|
||||
|
||||
private:
|
||||
static History history_;
|
||||
ConsoleMode mode_;
|
||||
int inpos_;
|
||||
int inpos_, completion_pos_;
|
||||
QStringList completion_triggers_;
|
||||
QString currentMultiLineCode_;
|
||||
QConsoleIODevice *iodevice_;
|
||||
|
||||
static History history_;
|
||||
QTextCharFormat chanFormat_[nConsoleChannels];
|
||||
QConsoleWidgetCompleter *completer_;
|
||||
};
|
||||
|
||||
QTextStream &waitForInput(QTextStream &s);
|
||||
QTextStream &inputMode(QTextStream &s);
|
||||
QTextStream &outChannel(QTextStream &s);
|
||||
QTextStream &errChannel(QTextStream &s);
|
||||
|
||||
class QConsoleWidgetCompleter : public QCompleter {
|
||||
public:
|
||||
/*
|
||||
* Update the completion model given a string. The given string
|
||||
* is the current console text between the cursor and the start of
|
||||
* the line.
|
||||
*
|
||||
* Return the completion count
|
||||
*/
|
||||
virtual int updateCompletionModel(const QString &str) = 0;
|
||||
|
||||
/*
|
||||
* Return the position in the command line where the completion
|
||||
* should be inserted
|
||||
*/
|
||||
virtual int insertPos() = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -245,8 +245,8 @@ set(CLASS_SRC
|
|||
src/class/appmanager.h
|
||||
src/class/appmanager.cpp
|
||||
src/class/angelscripthelper.h
|
||||
src/class/qasparser.cpp
|
||||
src/class/qasparser.h
|
||||
src/class/asdatabase.cpp
|
||||
src/class/asdatabase.h
|
||||
src/class/qascodeparser.h
|
||||
src/class/qascodeparser.cpp
|
||||
src/class/ascompletion.cpp
|
||||
|
@ -255,8 +255,6 @@ set(CLASS_SRC
|
|||
src/class/asbuilder.cpp
|
||||
src/class/ascontextmgr.h
|
||||
src/class/ascontextmgr.cpp
|
||||
src/class/qcodenode.cpp
|
||||
src/class/qcodenode.h
|
||||
src/class/clangformatmanager.h
|
||||
src/class/clangformatmanager.cpp
|
||||
src/class/aspreprocesser.h
|
||||
|
@ -280,7 +278,8 @@ set(CLASS_SRC
|
|||
src/class/pluginsystem.cpp
|
||||
src/class/inspectqtloghelper.h
|
||||
src/class/inspectqtloghelper.cpp
|
||||
src/class/codeinfotip.h)
|
||||
src/class/codeinfotip.h
|
||||
src/class/codeinfotip.cpp)
|
||||
|
||||
set(INTERNAL_PLG_SRC
|
||||
src/class/wingangelapi.h src/class/wingangelapi.cpp
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -17,7 +17,7 @@
|
|||
|
||||
#include "ascompletion.h"
|
||||
|
||||
#include "qasparser.h"
|
||||
#include "asdatabase.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QLibraryInfo>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#define _AS_COMPLETION_H_
|
||||
|
||||
#include "WingCodeEdit/wingcompleter.h"
|
||||
#include "class/qasparser.h"
|
||||
#include "class/asdatabase.h"
|
||||
|
||||
class AsCompletion : public WingCompleter {
|
||||
Q_OBJECT
|
||||
|
@ -32,17 +32,15 @@ signals:
|
|||
void onFunctionTip(AsCompletion *cp, const QString &content);
|
||||
|
||||
private:
|
||||
void applyEmptyNsNode(QList<QCodeNode *> &nodes);
|
||||
// void applyEmptyNsNode(QList<QCodeNode *> &nodes);
|
||||
|
||||
// void parse(const QDocumentCursor &c);
|
||||
|
||||
QList<QCodeNode *> lookupNamespace(const QByteArrayList &ns);
|
||||
// QList<QCodeNode *> lookupNamespace(const QByteArrayList &ns);
|
||||
|
||||
private:
|
||||
QAsParser parser;
|
||||
ASDataBase parser;
|
||||
asIScriptEngine *_engine;
|
||||
|
||||
QList<QCodeNode *> _emptyNsNodes;
|
||||
};
|
||||
|
||||
#endif // _CPP_COMPLETION_H_
|
||||
|
|
|
@ -15,26 +15,57 @@
|
|||
** =============================================================================
|
||||
*/
|
||||
|
||||
#include "qasparser.h"
|
||||
#include "asdatabase.h"
|
||||
|
||||
#include "AngelScript/sdk/angelscript/source/as_objecttype.h"
|
||||
#include "AngelScript/sdk/angelscript/source/as_scriptengine.h"
|
||||
#include "AngelScript/sdk/angelscript/source/as_scriptfunction.h"
|
||||
#include "class/qcodenode.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
QAsParser::QAsParser(asIScriptEngine *engine)
|
||||
: AsPreprocesser(engine), _engine(engine) {
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
using qhash_result_t = uint;
|
||||
|
||||
// copying from QT6 source code for supporting QT5's qHashMulti
|
||||
namespace QtPrivate {
|
||||
template <typename T>
|
||||
inline constexpr bool QNothrowHashableHelper_v =
|
||||
noexcept(qHash(std::declval<const T &>()));
|
||||
|
||||
template <typename T, typename Enable = void>
|
||||
struct QNothrowHashable : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct QNothrowHashable<T, std::enable_if_t<QNothrowHashableHelper_v<T>>>
|
||||
: std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
constexpr inline bool QNothrowHashable_v = QNothrowHashable<T>::value;
|
||||
|
||||
} // namespace QtPrivate
|
||||
|
||||
template <typename... T>
|
||||
constexpr qhash_result_t
|
||||
qHashMulti(qhash_result_t seed, const T &...args) noexcept(
|
||||
std::conjunction_v<QtPrivate::QNothrowHashable<T>...>) {
|
||||
QtPrivate::QHashCombine hash;
|
||||
return ((seed = hash(seed, args)), ...), seed;
|
||||
}
|
||||
#else
|
||||
using qhash_result_t = size_t;
|
||||
#endif
|
||||
|
||||
inline qhash_result_t qHash(const ASDataBase::HeaderType &c,
|
||||
qhash_result_t seed) noexcept {
|
||||
return qHashMulti(seed, c.name, int(c.type));
|
||||
}
|
||||
|
||||
ASDataBase::ASDataBase(asIScriptEngine *engine) {
|
||||
addGlobalFunctionCompletion(engine);
|
||||
addClassCompletion(engine);
|
||||
addEnumCompletion(engine);
|
||||
_buffer.clear();
|
||||
_buffer.squeeze();
|
||||
|
||||
// generate keyword completion
|
||||
_keywordNode = new QCodeNode;
|
||||
_keywordNode->setNodeType(QCodeNode::Group);
|
||||
QStringList kws{
|
||||
"const", "in", "inout", "out", "auto", "public",
|
||||
"protected", "private", "void", "int8", "int16", "int",
|
||||
|
@ -48,27 +79,18 @@ QAsParser::QAsParser(asIScriptEngine *engine)
|
|||
"true", "null", "typename", "return", "typedef", "funcdef",
|
||||
"from", "import", "not", "xor", "or", "is"};
|
||||
for (auto &k : kws) {
|
||||
auto knode = new QCodeNode;
|
||||
knode->setParent(_keywordNode);
|
||||
knode->setNodeType(QCodeNode::KeyWord);
|
||||
knode->setRole(QCodeNode::Name, k.toUtf8());
|
||||
_keywordNode->children().append(knode);
|
||||
CodeInfoTip t;
|
||||
t.type = CodeInfoTip::Type::KeyWord;
|
||||
t.name = k;
|
||||
_keywordNode.append(t);
|
||||
}
|
||||
}
|
||||
|
||||
QAsParser::~QAsParser() {
|
||||
qDeleteAll(_headerNodes);
|
||||
_headerNodes.clear();
|
||||
qDeleteAll(_nodes);
|
||||
_nodes.clear();
|
||||
delete _keywordNode;
|
||||
qDeleteAll(_classNodes);
|
||||
_classNodes.clear();
|
||||
}
|
||||
ASDataBase::~ASDataBase() {}
|
||||
|
||||
QByteArray QAsParser::getFnParamDeclString(asIScriptFunction *fn,
|
||||
bool includeNamespace,
|
||||
bool includeParamNames) {
|
||||
QByteArray ASDataBase::getFnParamDeclString(asIScriptFunction *fn,
|
||||
bool includeNamespace,
|
||||
bool includeParamNames) {
|
||||
auto fun = dynamic_cast<asCScriptFunction *>(fn);
|
||||
if (fun == nullptr) {
|
||||
return {};
|
||||
|
@ -137,7 +159,7 @@ QByteArray QAsParser::getFnParamDeclString(asIScriptFunction *fn,
|
|||
return QByteArray(str.AddressOf(), QByteArray::size_type(str.GetLength()));
|
||||
}
|
||||
|
||||
QByteArray QAsParser::getFnRealName(asIScriptFunction *fn) {
|
||||
QByteArray ASDataBase::getFnRealName(asIScriptFunction *fn) {
|
||||
auto fun = dynamic_cast<asCScriptFunction *>(fn);
|
||||
if (fun == nullptr) {
|
||||
return {};
|
||||
|
@ -164,8 +186,8 @@ QByteArray QAsParser::getFnRealName(asIScriptFunction *fn) {
|
|||
return QByteArray(str.AddressOf(), QByteArray::size_type(str.GetLength()));
|
||||
}
|
||||
|
||||
QByteArray QAsParser::getFnRetTypeString(asIScriptFunction *fn,
|
||||
bool includeNamespace) {
|
||||
QByteArray ASDataBase::getFnRetTypeString(asIScriptFunction *fn,
|
||||
bool includeNamespace) {
|
||||
auto fun = dynamic_cast<asCScriptFunction *>(fn);
|
||||
if (fun == nullptr) {
|
||||
return {};
|
||||
|
@ -188,61 +210,35 @@ QByteArray QAsParser::getFnRetTypeString(asIScriptFunction *fn,
|
|||
return {};
|
||||
}
|
||||
|
||||
// bool QAsParser::parse(qsizetype offset, const QString &code,
|
||||
// const QString §ion) {
|
||||
// return ProcessScriptSection(code.toUtf8(), code.length(), section, 0);
|
||||
// }
|
||||
|
||||
const QList<QCodeNode *> &QAsParser::headerNodes() const {
|
||||
const QHash<ASDataBase::HeaderType, QList<CodeInfoTip>> &
|
||||
ASDataBase::headerNodes() const {
|
||||
return _headerNodes;
|
||||
}
|
||||
|
||||
void QAsParser::addGlobalFunctionCompletion(asIScriptEngine *engine) {
|
||||
void ASDataBase::addGlobalFunctionCompletion(asIScriptEngine *engine) {
|
||||
Q_ASSERT(engine);
|
||||
|
||||
QHash<QByteArray, QList<FnInfo>> _maps;
|
||||
|
||||
HeaderType nst;
|
||||
nst.type = CodeInfoTip::Type::Group;
|
||||
for (asUINT i = 0; i < engine->GetGlobalFunctionCount(); ++i) {
|
||||
auto fn = engine->GetGlobalFunctionByIndex(i);
|
||||
|
||||
FnInfo fnInfo;
|
||||
CodeInfoTip fnInfo;
|
||||
auto ns = fn->GetNamespace();
|
||||
fnInfo.retType = getFnRetTypeString(fn, true);
|
||||
fnInfo.fnName = fn->GetName();
|
||||
fnInfo.params = getFnParamDeclString(fn, false, true);
|
||||
fnInfo.isConst = fn->IsReadOnly();
|
||||
|
||||
_maps[ns] << fnInfo;
|
||||
}
|
||||
|
||||
auto node = getNewHeadNodePointer(QByteArray());
|
||||
node->setNodeType(QCodeNode::Group);
|
||||
for (auto p = _maps.keyBegin(); p != _maps.keyEnd(); p++) {
|
||||
if (p->isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
auto nsnode = new QCodeNode;
|
||||
nsnode->setNodeType(QCodeNode::Namespace);
|
||||
nsnode->setRole(QCodeNode::Name, *p);
|
||||
nsnode->attach(node);
|
||||
}
|
||||
|
||||
for (auto p = _maps.keyValueBegin(); p != _maps.keyValueEnd(); p++) {
|
||||
auto node = getNewHeadNodePointer(p->first);
|
||||
if (p->first.isEmpty()) {
|
||||
node->setNodeType(QCodeNode::Group);
|
||||
} else {
|
||||
node->setNodeType(QCodeNode::Namespace);
|
||||
}
|
||||
|
||||
for (auto &fn : p->second) {
|
||||
auto fnnode = newFnCodeNode(fn);
|
||||
fnnode->attach(node);
|
||||
}
|
||||
fnInfo.nameSpace = ns;
|
||||
fnInfo.name = fn->GetName();
|
||||
fnInfo.type = CodeInfoTip::Type::Function;
|
||||
fnInfo.args.insert(CodeInfoTip::RetType, getFnRetTypeString(fn, true));
|
||||
fnInfo.args.insert(CodeInfoTip::Args,
|
||||
getFnParamDeclString(fn, false, true));
|
||||
fnInfo.args.insert(CodeInfoTip::SuffixQualifier,
|
||||
fn->IsReadOnly() ? QStringLiteral("const")
|
||||
: QString());
|
||||
nst.name = ns;
|
||||
_headerNodes[nst].append(fnInfo);
|
||||
}
|
||||
}
|
||||
|
||||
void QAsParser::addEnumCompletion(asIScriptEngine *engine) {
|
||||
void ASDataBase::addEnumCompletion(asIScriptEngine *engine) {
|
||||
Q_ASSERT(engine);
|
||||
|
||||
QHash<QByteArray, QList<EnumInfo>> _maps;
|
||||
|
@ -265,23 +261,9 @@ void QAsParser::addEnumCompletion(asIScriptEngine *engine) {
|
|||
|
||||
_maps[ns] << einfo;
|
||||
}
|
||||
|
||||
for (auto p = _maps.keyValueBegin(); p != _maps.keyValueEnd(); p++) {
|
||||
auto node = getNewHeadNodePointer(p->first);
|
||||
if (p->first.isEmpty()) {
|
||||
node->setNodeType(QCodeNode::Group);
|
||||
} else {
|
||||
node->setNodeType(QCodeNode::Namespace);
|
||||
}
|
||||
|
||||
for (auto &e : p->second) {
|
||||
auto enode = newEnumCodeNode(e);
|
||||
enode->attach(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QAsParser::addClassCompletion(asIScriptEngine *engine) {
|
||||
void ASDataBase::addClassCompletion(asIScriptEngine *engine) {
|
||||
auto eng = dynamic_cast<asCScriptEngine *>(engine);
|
||||
Q_ASSERT(eng);
|
||||
|
||||
|
@ -349,119 +331,73 @@ void QAsParser::addClassCompletion(asIScriptEngine *engine) {
|
|||
_maps[ns] << cls;
|
||||
}
|
||||
|
||||
auto applyClsNode = [](const QList<ClassInfo> &clsinfos,
|
||||
bool isComplete) -> QList<QCodeNode *> {
|
||||
QList<QCodeNode *> ret;
|
||||
// auto applyClsNode = [](const QList<ClassInfo> &clsinfos,
|
||||
// bool isComplete) -> QList<QCodeNode *> {
|
||||
// QList<QCodeNode *> ret;
|
||||
|
||||
for (auto &cls : clsinfos) {
|
||||
QCodeNode *clsnode = new QCodeNode;
|
||||
clsnode->setNodeType(QCodeNode::Class);
|
||||
clsnode->setRole(QCodeNode::Name, cls.name);
|
||||
// for (auto &cls : clsinfos) {
|
||||
// QCodeNode *clsnode = new QCodeNode;
|
||||
// clsnode->setNodeType(QCodeNode::Class);
|
||||
// clsnode->setRole(QCodeNode::Name, cls.name);
|
||||
|
||||
for (auto &m : cls.methods) {
|
||||
if (isComplete) {
|
||||
if (m.fnName == cls.name) {
|
||||
continue;
|
||||
}
|
||||
if (m.fnName.startsWith('~')) {
|
||||
continue;
|
||||
}
|
||||
if (m.fnName.startsWith("op")) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// for (auto &m : cls.methods) {
|
||||
// if (isComplete) {
|
||||
// if (m.fnName == cls.name) {
|
||||
// continue;
|
||||
// }
|
||||
// if (m.fnName.startsWith('~')) {
|
||||
// continue;
|
||||
// }
|
||||
// if (m.fnName.startsWith("op")) {
|
||||
// continue;
|
||||
// }
|
||||
// }
|
||||
|
||||
auto node = newFnCodeNode(m);
|
||||
node->attach(clsnode);
|
||||
}
|
||||
// auto node = newFnCodeNode(m);
|
||||
// node->attach(clsnode);
|
||||
// }
|
||||
|
||||
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);
|
||||
// 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);
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
ret.append(clsnode);
|
||||
}
|
||||
// node->setRole(QCodeNode::Visibility, visibility);
|
||||
// node->setParent(clsnode);
|
||||
// clsnode->children().append(node);
|
||||
// }
|
||||
// ret.append(clsnode);
|
||||
// }
|
||||
|
||||
return ret;
|
||||
};
|
||||
// return ret;
|
||||
// };
|
||||
|
||||
for (auto p = _maps.keyValueBegin(); p != _maps.keyValueEnd(); p++) {
|
||||
auto node = getNewHeadNodePointer(p->first);
|
||||
if (p->first.isEmpty()) {
|
||||
node->setNodeType(QCodeNode::Group);
|
||||
} else {
|
||||
node->setNodeType(QCodeNode::Namespace);
|
||||
}
|
||||
auto nodes = applyClsNode(p->second, false);
|
||||
for (auto &n : nodes) {
|
||||
n->attach(node);
|
||||
}
|
||||
// for (auto p = _maps.keyValueBegin(); p != _maps.keyValueEnd(); p++) {
|
||||
// auto node = getNewHeadNodePointer(p->first);
|
||||
// if (p->first.isEmpty()) {
|
||||
// node->setNodeType(QCodeNode::Group);
|
||||
// } else {
|
||||
// node->setNodeType(QCodeNode::Namespace);
|
||||
// }
|
||||
// auto nodes = applyClsNode(p->second, false);
|
||||
// for (auto &n : nodes) {
|
||||
// n->attach(node);
|
||||
// }
|
||||
|
||||
_classNodes.append(applyClsNode(p->second, true));
|
||||
}
|
||||
// _classNodes.append(applyClsNode(p->second, true));
|
||||
// }
|
||||
}
|
||||
|
||||
QCodeNode *QAsParser::getNewHeadNodePointer(const QByteArray &name) {
|
||||
auto ptr = _buffer.value(name, nullptr);
|
||||
if (ptr) {
|
||||
return ptr;
|
||||
}
|
||||
auto node = new QCodeNode;
|
||||
node->setRole(QCodeNode::Name, name);
|
||||
_headerNodes.append(node);
|
||||
_buffer.insert(name, node);
|
||||
return node;
|
||||
const QList<CodeInfoTip> &ASDataBase::keywordNodes() const {
|
||||
return _keywordNode;
|
||||
}
|
||||
|
||||
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::classNodes() const { return _classNodes; }
|
||||
|
||||
QCodeNode *QAsParser::keywordNode() const { return _keywordNode; }
|
||||
|
||||
QList<QCodeNode *> QAsParser::codeNodes() const { return _nodes; }
|
|
@ -19,21 +19,17 @@
|
|||
#define _QAS_PARSER_H_
|
||||
|
||||
#include "angelscript.h"
|
||||
#include "class/aspreprocesser.h"
|
||||
#include "codeinfotip.h"
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QHash>
|
||||
#include <QList>
|
||||
#include <QScopedPointer>
|
||||
|
||||
class asCScriptCode;
|
||||
class asCScriptNode;
|
||||
class QCodeNode;
|
||||
|
||||
class QAsParser : protected AsPreprocesser {
|
||||
class ASDataBase {
|
||||
public:
|
||||
explicit QAsParser(asIScriptEngine *engine);
|
||||
virtual ~QAsParser();
|
||||
explicit ASDataBase(asIScriptEngine *engine);
|
||||
virtual ~ASDataBase();
|
||||
|
||||
private:
|
||||
struct FnInfo {
|
||||
|
@ -62,6 +58,16 @@ private:
|
|||
QList<PropertyInfo> properties;
|
||||
};
|
||||
|
||||
public:
|
||||
struct HeaderType {
|
||||
QString name;
|
||||
CodeInfoTip::Type type = CodeInfoTip::Type::Unknown;
|
||||
|
||||
bool operator==(const HeaderType &other) const {
|
||||
return name == other.name && type == other.type;
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
QByteArray getFnParamDeclString(asIScriptFunction *fn,
|
||||
bool includeNamespace,
|
||||
|
@ -72,37 +78,18 @@ private:
|
|||
QByteArray getFnRetTypeString(asIScriptFunction *fn, bool includeNamespace);
|
||||
|
||||
public:
|
||||
// bool parse(qsizetype offset, const QString &code, const QString
|
||||
// §ion);
|
||||
const QHash<HeaderType, QList<CodeInfoTip>> &headerNodes() const;
|
||||
|
||||
QList<QCodeNode *> codeNodes() const;
|
||||
|
||||
const QList<QCodeNode *> &headerNodes() const;
|
||||
|
||||
QCodeNode *keywordNode() const;
|
||||
|
||||
QList<QCodeNode *> classNodes() const;
|
||||
const QList<CodeInfoTip> &keywordNodes() const;
|
||||
|
||||
private:
|
||||
void addGlobalFunctionCompletion(asIScriptEngine *engine);
|
||||
void addEnumCompletion(asIScriptEngine *engine);
|
||||
void addClassCompletion(asIScriptEngine *engine);
|
||||
|
||||
QCodeNode *getNewHeadNodePointer(const QByteArray &name);
|
||||
|
||||
private:
|
||||
static QCodeNode *newFnCodeNode(const FnInfo &info);
|
||||
|
||||
static QCodeNode *newEnumCodeNode(const EnumInfo &info);
|
||||
|
||||
private:
|
||||
asIScriptEngine *_engine;
|
||||
QList<QCodeNode *> _nodes;
|
||||
|
||||
QHash<QString, QCodeNode *> _buffer;
|
||||
QList<QCodeNode *> _headerNodes;
|
||||
QList<QCodeNode *> _classNodes;
|
||||
QCodeNode *_keywordNode;
|
||||
QHash<HeaderType, QList<CodeInfoTip>> _headerNodes;
|
||||
QList<CodeInfoTip> _keywordNode;
|
||||
};
|
||||
|
||||
#endif // !_QCPP_PARSER_H_
|
|
@ -0,0 +1,131 @@
|
|||
/*==============================================================================
|
||||
** Copyright (C) 2024-2027 WingSummer
|
||||
**
|
||||
** 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 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.
|
||||
**
|
||||
** 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 "codeinfotip.h"
|
||||
|
||||
#include <QHash>
|
||||
|
||||
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 +
|
||||
QStringLiteral(".png"));
|
||||
}
|
||||
|
||||
QIcon CodeInfoTip::getDisplayIcon(Type type) {
|
||||
switch (type) {
|
||||
default:
|
||||
return {};
|
||||
case Type::KeyWord:
|
||||
return icon(ICON_KEYWORD);
|
||||
case Type::Group:
|
||||
return icon(ICON_NAMESPACE);
|
||||
case Type::Class:
|
||||
return icon(ICON_CLASS);
|
||||
case Type::Function:
|
||||
return icon(ICON_FUNCTION);
|
||||
case Type::Enum:
|
||||
return icon(ICON_ENUM);
|
||||
case Type::Variable:
|
||||
return icon(ICON_VARIABLE);
|
||||
}
|
||||
}
|
||||
|
||||
QIcon CodeInfoTip::icon(int cacheIndex) {
|
||||
static bool setup = false;
|
||||
|
||||
if (!setup) {
|
||||
// q_icon_cache[ICON_UNION] = QIcon(":/completion/CVunion.png");
|
||||
|
||||
(*q_icon_cache)[CodeInfoTip::ICON_ENUM] =
|
||||
getIcon(QStringLiteral("CVenum"));
|
||||
(*q_icon_cache)[CodeInfoTip::ICON_ENUMERATOR] =
|
||||
getIcon(QStringLiteral("CVenumerator"));
|
||||
|
||||
(*q_icon_cache)[CodeInfoTip::ICON_CLASS] =
|
||||
getIcon(QStringLiteral("CVclass"));
|
||||
|
||||
// q_icon_cache[ICON_STRUCT] = QIcon(":/completion/CVstruct.png");
|
||||
(*q_icon_cache)[CodeInfoTip::ICON_KEYWORD] =
|
||||
getIcon(QStringLiteral("CVKeyword"));
|
||||
|
||||
(*q_icon_cache)[CodeInfoTip::ICON_TYPEDEF] =
|
||||
getIcon(QStringLiteral("CVtypedef"));
|
||||
|
||||
(*q_icon_cache)[CodeInfoTip::ICON_NAMESPACE] =
|
||||
getIcon(QStringLiteral("CVnamespace"));
|
||||
|
||||
(*q_icon_cache)[CodeInfoTip::ICON_FUNCTION +
|
||||
CodeInfoTip::VISIBILITY_DEFAULT] =
|
||||
getIcon(QStringLiteral("CVglobal_meth"));
|
||||
|
||||
(*q_icon_cache)[CodeInfoTip::ICON_FUNCTION +
|
||||
CodeInfoTip::VISIBILITY_PUBLIC] =
|
||||
getIcon(QStringLiteral("CVpublic_meth"));
|
||||
|
||||
(*q_icon_cache)[CodeInfoTip::ICON_FUNCTION +
|
||||
CodeInfoTip::VISIBILITY_PROTECTED] =
|
||||
getIcon(QStringLiteral("CVprotected_meth"));
|
||||
|
||||
(*q_icon_cache)[CodeInfoTip::ICON_FUNCTION +
|
||||
CodeInfoTip::VISIBILITY_PRIVATE] =
|
||||
getIcon(QStringLiteral("CVprivate_meth"));
|
||||
|
||||
(*q_icon_cache)[CodeInfoTip::ICON_VARIABLE +
|
||||
CodeInfoTip::VISIBILITY_DEFAULT] =
|
||||
getIcon(QStringLiteral("CVglobal_var"));
|
||||
|
||||
(*q_icon_cache)[CodeInfoTip::ICON_VARIABLE +
|
||||
CodeInfoTip::VISIBILITY_PUBLIC] =
|
||||
getIcon(QStringLiteral("CVpublic_var"));
|
||||
|
||||
(*q_icon_cache)[CodeInfoTip::ICON_VARIABLE +
|
||||
CodeInfoTip::VISIBILITY_PROTECTED] =
|
||||
getIcon(QStringLiteral("CVprotected_var"));
|
||||
|
||||
(*q_icon_cache)[CodeInfoTip::ICON_VARIABLE +
|
||||
CodeInfoTip::VISIBILITY_PRIVATE] =
|
||||
getIcon(QStringLiteral("CVprivate_var"));
|
||||
|
||||
setup = true;
|
||||
}
|
||||
|
||||
return q_icon_cache->value(cacheIndex);
|
||||
}
|
||||
|
||||
QString CodeInfoTip::getTooltip() const {
|
||||
QString tip = name;
|
||||
if (!nameSpace.isEmpty()) {
|
||||
tip.prepend(QStringLiteral("::")).prepend(nameSpace);
|
||||
}
|
||||
|
||||
if (type == Type::Function) {
|
||||
tip.prepend(' ')
|
||||
.prepend(args.value(RetType))
|
||||
.append('(')
|
||||
.append(args.value(Args))
|
||||
.append(')');
|
||||
|
||||
auto cq = args.value(SuffixQualifier);
|
||||
if (!cq.isEmpty()) {
|
||||
tip.append(' ').append(cq);
|
||||
}
|
||||
}
|
||||
|
||||
return tip;
|
||||
}
|
|
@ -18,18 +18,62 @@
|
|||
#ifndef CODEINFOTIP_H
|
||||
#define CODEINFOTIP_H
|
||||
|
||||
#include <QIcon>
|
||||
#include <QMap>
|
||||
#include <QString>
|
||||
|
||||
class CodeInfoTip {
|
||||
public:
|
||||
enum class Type { Class, Function, Enum, Variable };
|
||||
enum class Type {
|
||||
Unknown,
|
||||
KeyWord,
|
||||
Group,
|
||||
Class,
|
||||
Function,
|
||||
Enum,
|
||||
Variable
|
||||
};
|
||||
|
||||
enum CacheIndex {
|
||||
ICON_ENUM,
|
||||
ICON_ENUMERATOR,
|
||||
// ICON_UNION,
|
||||
ICON_CLASS,
|
||||
// ICON_STRUCT,
|
||||
ICON_KEYWORD,
|
||||
ICON_TYPEDEF,
|
||||
ICON_NAMESPACE,
|
||||
ICON_FUNCTION = ICON_NAMESPACE + 2,
|
||||
ICON_VARIABLE = ICON_FUNCTION + 5
|
||||
};
|
||||
|
||||
enum CodeInfoVisibility {
|
||||
VISIBILITY_DEFAULT = -1,
|
||||
VISIBILITY_PUBLIC,
|
||||
VISIBILITY_PROTECTED,
|
||||
VISIBILITY_PRIVATE
|
||||
};
|
||||
|
||||
static QIcon getDisplayIcon(Type type);
|
||||
|
||||
static QIcon icon(int cacheIndex);
|
||||
|
||||
enum ArgsIndex {
|
||||
// for function
|
||||
RetType,
|
||||
Args,
|
||||
SuffixQualifier
|
||||
};
|
||||
|
||||
public:
|
||||
QString getTooltip() const;
|
||||
|
||||
public:
|
||||
QString name;
|
||||
Type type;
|
||||
Type type = Type::Unknown;
|
||||
QString nameSpace;
|
||||
|
||||
QString args; // only function use
|
||||
QMap<ArgsIndex, QString> args;
|
||||
};
|
||||
|
||||
#endif // CODEINFOTIP_H
|
||||
|
|
|
@ -19,8 +19,9 @@
|
|||
#define QASCODEPARSER_H
|
||||
|
||||
#include "AngelScript/sdk/angelscript/source/as_scriptnode.h"
|
||||
#include "class/qcodenode.h"
|
||||
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
#include <QString>
|
||||
|
||||
// This class is the modification of as_parser.
|
||||
|
@ -32,14 +33,6 @@
|
|||
* Qt creator or Visual Studio, PRs are welcomed !!!
|
||||
*/
|
||||
|
||||
// 这个类基于 as_parser 这个文件进行修改得到。
|
||||
// 你可以修改该类以支持更多的功能。
|
||||
/* 完美支持 AngelScript 代码智能提示是一个很复杂的事情。
|
||||
* 我只提供基础的局部或全局变量和函数的代码填充。
|
||||
* 如果你对实现一个像 Qt creator 或者 Visual Studio 一样功能丰富的智能提示,
|
||||
* 欢迎 PR !!!
|
||||
*/
|
||||
|
||||
class QAsCodeParser {
|
||||
public:
|
||||
QAsCodeParser(asCScriptEngine *engine);
|
||||
|
|
|
@ -1,416 +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 "qcodenode.h"
|
||||
|
||||
#include <QIcon>
|
||||
#include <QVariant>
|
||||
|
||||
enum CacheIndex {
|
||||
ICON_ENUM,
|
||||
ICON_ENUMERATOR,
|
||||
// ICON_UNION,
|
||||
ICON_CLASS,
|
||||
// ICON_STRUCT,
|
||||
ICON_KEYWORD,
|
||||
ICON_TYPEDEF,
|
||||
ICON_NAMESPACE,
|
||||
ICON_FUNCTION = ICON_NAMESPACE + 2,
|
||||
ICON_VARIABLE = ICON_FUNCTION + 5
|
||||
};
|
||||
|
||||
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 +
|
||||
QStringLiteral(".png"));
|
||||
}
|
||||
|
||||
static QIcon icon(int cacheIndex) {
|
||||
static bool setup = false;
|
||||
|
||||
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_CLASS] = getIcon(QStringLiteral("CVclass"));
|
||||
|
||||
// q_icon_cache[ICON_STRUCT] = QIcon(":/completion/CVstruct.png");
|
||||
(*q_icon_cache)[ICON_KEYWORD] = getIcon(QStringLiteral("CVKeyword"));
|
||||
|
||||
(*q_icon_cache)[ICON_TYPEDEF] = getIcon(QStringLiteral("CVtypedef"));
|
||||
|
||||
(*q_icon_cache)[ICON_NAMESPACE] =
|
||||
getIcon(QStringLiteral("CVnamespace"));
|
||||
|
||||
(*q_icon_cache)[ICON_FUNCTION + QCodeNode::VISIBILITY_DEFAULT] =
|
||||
getIcon(QStringLiteral("CVglobal_meth"));
|
||||
|
||||
(*q_icon_cache)[ICON_FUNCTION + QCodeNode::VISIBILITY_PUBLIC] =
|
||||
getIcon(QStringLiteral("CVpublic_meth"));
|
||||
|
||||
(*q_icon_cache)[ICON_FUNCTION + QCodeNode::VISIBILITY_PROTECTED] =
|
||||
getIcon(QStringLiteral("CVprotected_meth"));
|
||||
|
||||
(*q_icon_cache)[ICON_FUNCTION + QCodeNode::VISIBILITY_PRIVATE] =
|
||||
getIcon(QStringLiteral("CVprivate_meth"));
|
||||
|
||||
(*q_icon_cache)[ICON_VARIABLE + QCodeNode::VISIBILITY_DEFAULT] =
|
||||
getIcon(QStringLiteral("CVglobal_var"));
|
||||
|
||||
(*q_icon_cache)[ICON_VARIABLE + QCodeNode::VISIBILITY_PUBLIC] =
|
||||
getIcon(QStringLiteral("CVpublic_var"));
|
||||
|
||||
(*q_icon_cache)[ICON_VARIABLE + QCodeNode::VISIBILITY_PROTECTED] =
|
||||
getIcon(QStringLiteral("CVprotected_var"));
|
||||
|
||||
(*q_icon_cache)[ICON_VARIABLE + QCodeNode::VISIBILITY_PRIVATE] =
|
||||
getIcon(QStringLiteral("CVprivate_var"));
|
||||
|
||||
setup = true;
|
||||
}
|
||||
|
||||
return q_icon_cache->value(cacheIndex);
|
||||
}
|
||||
|
||||
QCodeNode::QCodeNode() : line(-1), _parent(nullptr) {}
|
||||
|
||||
QCodeNode::~QCodeNode() {
|
||||
QCodeNode::detach();
|
||||
_parent = nullptr;
|
||||
clear();
|
||||
}
|
||||
|
||||
void QCodeNode::attach(QCodeNode *p) {
|
||||
detach();
|
||||
|
||||
if (!p || p->_children.contains(this))
|
||||
return;
|
||||
|
||||
_parent = p;
|
||||
p->_children.append(this);
|
||||
}
|
||||
|
||||
void QCodeNode::detach() {
|
||||
if (!_parent)
|
||||
return;
|
||||
|
||||
int row = _parent->_children.indexOf(this);
|
||||
|
||||
if (row < 0)
|
||||
return;
|
||||
|
||||
_parent->_children.removeAt(row);
|
||||
_parent = 0;
|
||||
}
|
||||
|
||||
QCodeNode *QCodeNode::parent() const { return _parent; }
|
||||
|
||||
void QCodeNode::setParent(QCodeNode *newParent) { _parent = newParent; }
|
||||
|
||||
int QCodeNode::getLine() const { return line; }
|
||||
|
||||
void QCodeNode::setLine(int newLine) { line = newLine; }
|
||||
|
||||
void QCodeNode::clear() {
|
||||
if (_children.isEmpty())
|
||||
return;
|
||||
|
||||
for (auto &n : _children) {
|
||||
n->_parent = nullptr;
|
||||
n->clear();
|
||||
}
|
||||
|
||||
qDeleteAll(_children);
|
||||
_children.clear();
|
||||
}
|
||||
|
||||
int QCodeNode::type() const {
|
||||
return roles.value(NodeType, QByteArray(1, 0)).at(0);
|
||||
}
|
||||
|
||||
QByteArray QCodeNode::context() const {
|
||||
int t = type();
|
||||
|
||||
if ((t == Group) || (t == Namespace))
|
||||
return QByteArray();
|
||||
|
||||
const QCodeNode *p = this;
|
||||
|
||||
while (p->_parent) {
|
||||
int t = p->_parent->type();
|
||||
|
||||
if ((t == Group) || (t == Namespace))
|
||||
break;
|
||||
|
||||
p = p->_parent;
|
||||
}
|
||||
|
||||
return p ? p->role(Context) : role(Context);
|
||||
}
|
||||
|
||||
QByteArray QCodeNode::qualifiedBaseName(bool ext) const {
|
||||
int t = type();
|
||||
|
||||
if (t == Group)
|
||||
return QByteArray();
|
||||
|
||||
QByteArray cxt;
|
||||
if (ext) {
|
||||
if (_parent && _parent->type() == Namespace) {
|
||||
cxt += _parent->role(Name);
|
||||
cxt += "::";
|
||||
}
|
||||
}
|
||||
|
||||
cxt += role(Name);
|
||||
return cxt;
|
||||
}
|
||||
|
||||
QByteArray QCodeNode::qualifiedName(bool ext) const {
|
||||
int t = type();
|
||||
|
||||
if (t == Group)
|
||||
return QByteArray();
|
||||
|
||||
auto cxt = qualifiedBaseName(ext);
|
||||
|
||||
if (t == Function) {
|
||||
cxt += "(";
|
||||
cxt += role(Arguments);
|
||||
cxt += ")";
|
||||
}
|
||||
|
||||
return cxt;
|
||||
}
|
||||
|
||||
QVariant QCodeNode::data(int r) const {
|
||||
const int t = type();
|
||||
|
||||
switch (r) {
|
||||
case Qt::DisplayRole: {
|
||||
if (t == Function)
|
||||
return role(Name) + "(" + role(Arguments) + ")";
|
||||
|
||||
return role(Name);
|
||||
}
|
||||
|
||||
case Qt::ToolTipRole:
|
||||
case Qt::StatusTipRole: {
|
||||
switch (t) {
|
||||
case Class: {
|
||||
QByteArray d("class ");
|
||||
d += role(Name);
|
||||
|
||||
QByteArray a = role(Ancestors);
|
||||
|
||||
if (a.length())
|
||||
d += " : " + a;
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
// case Struct: {
|
||||
// QByteArray d("struct ");
|
||||
// d += role(Name);
|
||||
|
||||
// QByteArray a = role(Ancestors);
|
||||
|
||||
// if (a.length())
|
||||
// d += " : " + a;
|
||||
|
||||
// return d;
|
||||
// }
|
||||
|
||||
case Enum:
|
||||
return QByteArray("enum ") + role(Name);
|
||||
|
||||
case Enumerator:
|
||||
return role(Name) + " = " + role(Value);
|
||||
|
||||
// case Union:
|
||||
// return QByteArray("union ") + role(Name);
|
||||
|
||||
case Namespace:
|
||||
return QByteArray("namespace ") + role(Name);
|
||||
|
||||
case Typedef:
|
||||
return QByteArray("typedef ") + role(Alias) + " " + role(Name);
|
||||
|
||||
case Variable: {
|
||||
QByteArray signature, specifier;
|
||||
|
||||
signature += role(Type);
|
||||
signature += " ";
|
||||
signature += role(Name);
|
||||
|
||||
int m_visibility = role(Visibility).toInt();
|
||||
int m_specifiers = role(Specifiers).toInt();
|
||||
|
||||
// visibility (for class members)
|
||||
if (m_visibility == QCodeNode::VISIBILITY_PUBLIC)
|
||||
specifier = " public ";
|
||||
else if (m_visibility == QCodeNode::VISIBILITY_PROTECTED)
|
||||
specifier = " protected ";
|
||||
else
|
||||
specifier = " private ";
|
||||
|
||||
// storage class
|
||||
if (m_specifiers & QCodeNode::SPECIFIER_AUTO)
|
||||
specifier += " auto ";
|
||||
// else if (m_specifiers & QCodeNode::SPECIFIER_REGISTER)
|
||||
// specifier += " register ";
|
||||
else if (m_specifiers & QCodeNode::SPECIFIER_STATIC)
|
||||
specifier += " static ";
|
||||
else if (m_specifiers & QCodeNode::SPECIFIER_EXTERN)
|
||||
specifier += " extern ";
|
||||
// else if (m_specifiers & QCodeNode::SPECIFIER_MUTABLE)
|
||||
// specifier += " mutable ";
|
||||
|
||||
// cv qualifier (for class members)
|
||||
if (m_specifiers & QCodeNode::SPECIFIER_CONST)
|
||||
specifier += " const ";
|
||||
// else if (m_specifiers & QCodeNode::SPECIFIER_VOLATILE)
|
||||
// specifier += " volatile ";
|
||||
|
||||
if (specifier.length())
|
||||
signature += " [" + specifier.simplified() + "]";
|
||||
|
||||
return signature;
|
||||
// return role(Type) + " " + role(Name);
|
||||
}
|
||||
|
||||
case Function: {
|
||||
QByteArray signature, qualifier, ret = role(Return);
|
||||
|
||||
if (ret.length())
|
||||
signature += ret + " ";
|
||||
|
||||
signature += role(Name);
|
||||
|
||||
signature += "(";
|
||||
signature += role(Arguments);
|
||||
signature += ")";
|
||||
|
||||
int m_qualifiers = role(Qualifiers).toInt();
|
||||
|
||||
if (m_qualifiers & QCodeNode::QUALIFIER_CONST)
|
||||
qualifier += " const ";
|
||||
// else if (m_qualifiers & QCodeNode::QUALIFIER_VOLATILE)
|
||||
// qualifier += " volatile ";
|
||||
// else if (m_qualifiers & QCodeNode::QUALIFIER_STATIC)
|
||||
// qualifier += " static ";
|
||||
|
||||
/* if (m_qualifiers & QCodeNode::QUALIFIER_PURE_VIRTUAL)
|
||||
qualifier.prepend(" pure virtual ");
|
||||
else */
|
||||
if (m_qualifiers & QCodeNode::QUALIFIER_INLINE)
|
||||
qualifier.prepend(" inline ");
|
||||
// else if (m_qualifiers & QCodeNode::QUALIFIER_VIRTUAL)
|
||||
// qualifier.prepend(" virtual ");
|
||||
|
||||
int m_visibility = role(Visibility).toInt();
|
||||
|
||||
if (m_visibility == QCodeNode::VISIBILITY_PUBLIC)
|
||||
qualifier.prepend(" public ");
|
||||
else if (m_visibility == QCodeNode::VISIBILITY_PROTECTED)
|
||||
qualifier.prepend(" protected ");
|
||||
// else if (m_visibility == QCodeNode::VISIBILITY_SIGNAL)
|
||||
// qualifier.prepend(" signal ");
|
||||
else if (m_visibility == QCodeNode::VISIBILITY_PRIVATE)
|
||||
qualifier.prepend(" private ");
|
||||
else
|
||||
qualifier.prepend(" global ");
|
||||
|
||||
if (ret.isEmpty()) {
|
||||
if (role(Name).startsWith("~"))
|
||||
qualifier += " destructor ";
|
||||
else
|
||||
qualifier += " constructor ";
|
||||
}
|
||||
|
||||
if (qualifier.length())
|
||||
signature += " [" + qualifier.simplified() + "]";
|
||||
|
||||
// return role(Name) + " " + role(Name);
|
||||
return signature;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
case Qt::DecorationRole: {
|
||||
switch (t) {
|
||||
case Class:
|
||||
return icon(ICON_CLASS);
|
||||
|
||||
// case Struct:
|
||||
// return icon(ICON_STRUCT);
|
||||
|
||||
case KeyWord:
|
||||
return icon(ICON_KEYWORD);
|
||||
|
||||
case Enum:
|
||||
return icon(ICON_ENUM);
|
||||
|
||||
case Enumerator:
|
||||
return icon(ICON_ENUMERATOR);
|
||||
|
||||
// case Union:
|
||||
// return icon(ICON_UNION);
|
||||
|
||||
case Namespace:
|
||||
return icon(ICON_NAMESPACE);
|
||||
|
||||
case Typedef:
|
||||
return icon(ICON_TYPEDEF);
|
||||
|
||||
case Variable:
|
||||
return icon(ICON_VARIABLE + role(Visibility).toInt());
|
||||
|
||||
case Function:
|
||||
return icon(ICON_FUNCTION + role(Visibility).toInt());
|
||||
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QByteArray QCodeNode::role(RoleIndex r) const { return roles.value(r); }
|
||||
|
||||
void QCodeNode::setRole(RoleIndex r, const QByteArray &b) { roles[r] = b; }
|
||||
|
||||
QList<QCodeNode *> &QCodeNode::children() { return _children; }
|
||||
|
||||
void QCodeNode::setNodeType(DefaultNodeTypes t) {
|
||||
setRole(NodeType, QByteArray(1, t));
|
||||
}
|
|
@ -1,146 +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_NODE_H_
|
||||
#define _QCODE_NODE_H_
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
#include <QVariant>
|
||||
|
||||
class QCodeNode final {
|
||||
public:
|
||||
enum RoleIndex {
|
||||
NodeType = 0,
|
||||
Name = 1,
|
||||
|
||||
// common
|
||||
Visibility = Name + 2,
|
||||
Templates = Visibility + 1,
|
||||
|
||||
// class/struct
|
||||
Ancestors = Name + 1,
|
||||
Friends = Ancestors + 1,
|
||||
|
||||
// typedef
|
||||
Alias = Name + 1,
|
||||
|
||||
// enumerator
|
||||
Value = Name + 1,
|
||||
|
||||
// variables/members
|
||||
Type = Name + 1,
|
||||
Specifiers = Visibility + 1,
|
||||
|
||||
// function/methods
|
||||
Return = Name + 1,
|
||||
Qualifiers = Templates + 1,
|
||||
Arguments = Qualifiers + 1,
|
||||
|
||||
Context = -1
|
||||
};
|
||||
|
||||
enum DefaultNodeTypes : char {
|
||||
Group = 'g',
|
||||
|
||||
Class = 'c',
|
||||
// Struct = 's',
|
||||
|
||||
Function = 'f',
|
||||
|
||||
Variable = 'v',
|
||||
|
||||
Enum = 'e',
|
||||
Enumerator = 'r',
|
||||
|
||||
// Union = 'u',
|
||||
|
||||
Namespace = 'n',
|
||||
|
||||
Typedef = 't',
|
||||
KeyWord = 'k'
|
||||
};
|
||||
|
||||
enum NodeContent {
|
||||
CONTENT_NONE = 0,
|
||||
CONTENT_DEFINITION = 1,
|
||||
CONTENT_IMPLEMENTATION = 2,
|
||||
};
|
||||
|
||||
enum NodeVisibility {
|
||||
VISIBILITY_DEFAULT = -1,
|
||||
VISIBILITY_PUBLIC,
|
||||
VISIBILITY_PROTECTED,
|
||||
VISIBILITY_PRIVATE
|
||||
};
|
||||
|
||||
enum Specifier {
|
||||
SPECIFIER_NONE = 0,
|
||||
SPECIFIER_CONST = 1,
|
||||
SPECIFIER_AUTO = 2,
|
||||
SPECIFIER_STATIC = 4,
|
||||
SPECIFIER_EXTERN = 8
|
||||
};
|
||||
|
||||
typedef QFlags<Specifier> TypeSpecifier;
|
||||
|
||||
enum Qualifier {
|
||||
QUALIFIER_NONE = 0,
|
||||
QUALIFIER_CONST = 1,
|
||||
QUALIFIER_EXTERN = 2,
|
||||
QUALIFIER_VIRTUAL = 4,
|
||||
QUALIFIER_INLINE = 8
|
||||
};
|
||||
|
||||
typedef QFlags<Qualifier> FunctionQualifier;
|
||||
|
||||
public:
|
||||
QCodeNode();
|
||||
~QCodeNode();
|
||||
|
||||
int type() const;
|
||||
QByteArray context() const;
|
||||
QByteArray qualifiedBaseName(bool ext = false) const;
|
||||
QByteArray qualifiedName(bool ext = false) const;
|
||||
|
||||
QVariant data(int role) const;
|
||||
|
||||
QByteArray role(RoleIndex r) const;
|
||||
void setRole(RoleIndex r, const QByteArray &b);
|
||||
|
||||
QList<QCodeNode *> &children();
|
||||
|
||||
void setNodeType(DefaultNodeTypes t);
|
||||
|
||||
void clear();
|
||||
|
||||
void attach(QCodeNode *p);
|
||||
void detach();
|
||||
|
||||
QCodeNode *parent() const;
|
||||
void setParent(QCodeNode *newParent);
|
||||
|
||||
int getLine() const;
|
||||
void setLine(int newLine);
|
||||
|
||||
private:
|
||||
int line = -1;
|
||||
QMap<RoleIndex, QByteArray> roles;
|
||||
QCodeNode *_parent = nullptr;
|
||||
QList<QCodeNode *> _children;
|
||||
};
|
||||
|
||||
#endif // !_QCODE_NODE_H_
|
|
@ -259,7 +259,7 @@ ScriptManager::buildUpRibbonScriptRunner(RibbonButtonGroup *group) {
|
|||
void ScriptManager::runScript(const QString &filename) {
|
||||
Q_ASSERT(_console);
|
||||
_console->setMode(ScriptingConsole::Output);
|
||||
_console->write(tr("Excuting:") + filename);
|
||||
_console->stdWarn(tr("Excuting:") + filename);
|
||||
_console->newLine();
|
||||
_console->machine()->executeScript(filename);
|
||||
_console->appendCommandPrompt();
|
||||
|
|
|
@ -2092,7 +2092,7 @@ bool WingAngelAPI::execScriptCode(const WingHex::SenderInfo &sender,
|
|||
}
|
||||
|
||||
_console->setMode(ScriptingConsole::Output);
|
||||
_console->write(getSenderHeader(sender));
|
||||
_console->stdOut(getSenderHeader(sender));
|
||||
auto handles = _handles;
|
||||
_console->machine()->executeScript(f.fileName());
|
||||
cleanUpHandles(handles);
|
||||
|
@ -2106,7 +2106,7 @@ bool WingAngelAPI::execScriptCode(const WingHex::SenderInfo &sender,
|
|||
bool WingAngelAPI::execScript(const WingHex::SenderInfo &sender,
|
||||
const QString &fileName) {
|
||||
_console->setMode(ScriptingConsole::Output);
|
||||
_console->write(getSenderHeader(sender));
|
||||
_console->stdOut(getSenderHeader(sender));
|
||||
auto handles = _handles;
|
||||
auto ret = _console->machine()->executeScript(fileName);
|
||||
cleanUpHandles(handles);
|
||||
|
@ -2118,7 +2118,7 @@ bool WingAngelAPI::execScript(const WingHex::SenderInfo &sender,
|
|||
bool WingAngelAPI::execCode(const WingHex::SenderInfo &sender,
|
||||
const QString &code) {
|
||||
_console->setMode(ScriptingConsole::Output);
|
||||
_console->write(getSenderHeader(sender));
|
||||
_console->stdOut(getSenderHeader(sender));
|
||||
auto ret = _console->machine()->executeCode(code);
|
||||
_console->appendCommandPrompt();
|
||||
_console->setMode(ScriptingConsole::Input);
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
#include "asobjtreewidget.h"
|
||||
|
||||
#include "class/qasparser.h"
|
||||
#include "class/asdatabase.h"
|
||||
|
||||
#include <QHeaderView>
|
||||
|
||||
|
@ -35,10 +35,11 @@ void ASObjTreeWidget::setEngine(asIScriptEngine *engine) {
|
|||
return;
|
||||
}
|
||||
|
||||
QAsParser parser(engine);
|
||||
auto &nodes = parser.headerNodes();
|
||||
for (auto &node : nodes) {
|
||||
auto header = QString::fromUtf8(node->role(QCodeNode::Name));
|
||||
ASDataBase db(engine);
|
||||
auto &nodes = db.headerNodes();
|
||||
for (auto node = nodes.constKeyValueBegin();
|
||||
node != nodes.constKeyValueEnd(); node++) {
|
||||
QString header = node->first.name;
|
||||
|
||||
QTreeWidgetItem *item = nullptr;
|
||||
|
||||
|
@ -48,41 +49,31 @@ void ASObjTreeWidget::setEngine(asIScriptEngine *engine) {
|
|||
item = new QTreeWidgetItem({header});
|
||||
}
|
||||
|
||||
item->setToolTip(0, node->qualifiedBaseName(true));
|
||||
item->setIcon(0, node->data(Qt::DecorationRole).value<QIcon>());
|
||||
|
||||
createObjNodes(node->children(), item);
|
||||
item->setToolTip(0, header);
|
||||
item->setIcon(0, CodeInfoTip::getDisplayIcon(node->first.type));
|
||||
createObjNodes(node->second, item);
|
||||
addTopLevelItem(item);
|
||||
}
|
||||
|
||||
setSortingEnabled(true);
|
||||
}
|
||||
|
||||
QTreeWidgetItem *ASObjTreeWidget::createObjNode(QCodeNode *node,
|
||||
QTreeWidgetItem *ASObjTreeWidget::createObjNode(const CodeInfoTip &node,
|
||||
QTreeWidgetItem *parent) {
|
||||
Q_ASSERT(node && parent);
|
||||
QStringList contents{QString::fromUtf8(node->role(QCodeNode::Name)),
|
||||
node->data(Qt::ToolTipRole).toString()};
|
||||
Q_ASSERT(node.type != CodeInfoTip::Type::Unknown && parent);
|
||||
QStringList contents{node.name, node.getTooltip()};
|
||||
auto c = new QTreeWidgetItem(contents);
|
||||
c->setToolTip(0, contents.at(0));
|
||||
c->setToolTip(1, contents.at(1));
|
||||
c->setIcon(0, node->data(Qt::DecorationRole).value<QIcon>());
|
||||
c->setIcon(0, CodeInfoTip::getDisplayIcon(node.type));
|
||||
parent->addChild(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
void ASObjTreeWidget::createObjNodes(const QList<QCodeNode *> &children,
|
||||
void ASObjTreeWidget::createObjNodes(const QList<CodeInfoTip> &nodes,
|
||||
QTreeWidgetItem *parent) {
|
||||
for (auto &n : children) {
|
||||
for (auto &n : nodes) {
|
||||
// only for code namespace completion
|
||||
if (n->role(QCodeNode::NodeType).at(0) == QCodeNode::Namespace) {
|
||||
if (n->children().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
auto c = createObjNode(n, parent);
|
||||
if (!n->children().isEmpty()) {
|
||||
createObjNodes(n->children(), c);
|
||||
}
|
||||
createObjNode(n, parent);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#define ASOBJTREEWIDGET_H
|
||||
|
||||
#include "angelscript.h"
|
||||
#include "class/qcodenode.h"
|
||||
#include "class/codeinfotip.h"
|
||||
|
||||
#include <QHash>
|
||||
#include <QTreeWidget>
|
||||
|
@ -33,9 +33,10 @@ public:
|
|||
void setEngine(asIScriptEngine *engine);
|
||||
|
||||
private:
|
||||
QTreeWidgetItem *createObjNode(QCodeNode *node, QTreeWidgetItem *parent);
|
||||
QTreeWidgetItem *createObjNode(const CodeInfoTip &node,
|
||||
QTreeWidgetItem *parent);
|
||||
|
||||
void createObjNodes(const QList<QCodeNode *> &children,
|
||||
void createObjNodes(const QList<CodeInfoTip> &nodes,
|
||||
QTreeWidgetItem *parent);
|
||||
};
|
||||
|
||||
|
|
|
@ -17,4 +17,17 @@
|
|||
|
||||
#include "codeedit.h"
|
||||
|
||||
CodeEdit::CodeEdit(QWidget *parent) : WingCodeEdit(parent) {}
|
||||
CodeEdit::CodeEdit(QWidget *parent) : WingCodeEdit(parent) {
|
||||
setAutoIndent(true);
|
||||
setAutoCloseChar(true);
|
||||
setMatchBraces(true);
|
||||
setShowLongLineEdge(true);
|
||||
setShowIndentGuides(true);
|
||||
setShowLineNumbers(true);
|
||||
setShowFolding(true);
|
||||
setShowWhitespace(true);
|
||||
setShowSymbolMark(true);
|
||||
|
||||
connect(this->document(), &QTextDocument::modificationChanged, this,
|
||||
&CodeEdit::contentModified);
|
||||
}
|
||||
|
|
|
@ -28,8 +28,6 @@ public:
|
|||
|
||||
signals:
|
||||
void contentModified(bool b);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif // CODEEDIT_H
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include <QAction>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QPixmap>
|
||||
|
||||
#include <KSyntaxHighlighting/Definition>
|
||||
|
@ -44,15 +45,6 @@ ScriptEditor::ScriptEditor(QWidget *parent)
|
|||
this->setObjectName(QStringLiteral("ScriptEditor"));
|
||||
|
||||
m_editor = new CodeEdit(this);
|
||||
m_editor->setAutoIndent(true);
|
||||
m_editor->setMatchBraces(true);
|
||||
m_editor->setShowLongLineEdge(true);
|
||||
m_editor->setShowIndentGuides(true);
|
||||
m_editor->setShowLineNumbers(true);
|
||||
m_editor->setShowFolding(true);
|
||||
m_editor->setShowWhitespace(true);
|
||||
m_editor->setShowSymbolMark(true);
|
||||
m_editor->setAutoCloseChar(true);
|
||||
|
||||
switch (SkinManager::instance().currentTheme()) {
|
||||
case SkinManager::Theme::Dark:
|
||||
|
@ -68,13 +60,10 @@ ScriptEditor::ScriptEditor(QWidget *parent)
|
|||
m_editor->setSyntax(
|
||||
m_editor->syntaxRepo().definitionForName("AngelScript"));
|
||||
|
||||
connect(m_editor, &WingCodeEdit::symbolMarkLineMarginClicked, this,
|
||||
connect(m_editor, &CodeEdit::symbolMarkLineMarginClicked, this,
|
||||
&ScriptEditor::onToggleMark);
|
||||
|
||||
// connect(editor, &QEditor::titleChanged, this,
|
||||
// &ScriptEditor::processTitle); connect(editor, &QEditor::contentModified,
|
||||
// this,
|
||||
// &ScriptEditor::processTitle);
|
||||
connect(m_editor, &CodeEdit::contentModified, this,
|
||||
[this]() { processTitle(); });
|
||||
|
||||
this->setWidget(m_editor);
|
||||
}
|
||||
|
@ -94,6 +83,8 @@ bool ScriptEditor::openFile(const QString &filename) {
|
|||
}
|
||||
m_editor->setPlainText(QString::fromUtf8(f.readAll()));
|
||||
f.close();
|
||||
m_fileName = filename;
|
||||
processTitle();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -140,6 +131,8 @@ bool ScriptEditor::save(const QString &path) {
|
|||
}
|
||||
#endif
|
||||
|
||||
m_fileName = path;
|
||||
processTitle();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -151,10 +144,11 @@ void ScriptEditor::setReadOnly(bool b) {
|
|||
}
|
||||
|
||||
void ScriptEditor::processTitle() {
|
||||
QString filename = QFileInfo(m_fileName).fileName();
|
||||
if (m_editor->document()->isModified()) {
|
||||
// setWindowTitle(e->windowTitle());
|
||||
setWindowTitle(filename.prepend(QStringLiteral("* ")));
|
||||
} else {
|
||||
// setWindowTitle(e->name());
|
||||
setWindowTitle(filename);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,22 +18,25 @@
|
|||
#include "scriptingconsole.h"
|
||||
#include "class/logger.h"
|
||||
#include "class/scriptconsolemachine.h"
|
||||
#include "qregularexpression.h"
|
||||
|
||||
#include <KSyntaxHighlighting/Definition>
|
||||
#include <KSyntaxHighlighting/Repository>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QColor>
|
||||
#include <QKeyEvent>
|
||||
#include <QTextObject>
|
||||
#include <QRegularExpression>
|
||||
#include <QTextBlock>
|
||||
|
||||
ScriptingConsole::ScriptingConsole(QWidget *parent) : QConsoleWidget(parent) {
|
||||
setSyntax(syntaxRepo().definitionForName("AngelScript"));
|
||||
_warnCharFmt.setForeground(QColorConstants::Svg::gold);
|
||||
}
|
||||
|
||||
ScriptingConsole::~ScriptingConsole() {}
|
||||
|
||||
void ScriptingConsole::stdOut(const QString &str) { writeStdOut(str); }
|
||||
|
||||
void ScriptingConsole::stdErr(const QString &str) { writeStdErr(str); }
|
||||
|
||||
void ScriptingConsole::stdWarn(const QString &str) { write(str, _warnCharFmt); }
|
||||
|
||||
void ScriptingConsole::newLine() { _s << Qt::endl; }
|
||||
|
||||
void ScriptingConsole::init() {
|
||||
|
@ -51,14 +54,13 @@ void ScriptingConsole::init() {
|
|||
[=](ScriptConsoleMachine::MessageType type,
|
||||
const ScriptConsoleMachine::MessageInfo &message) {
|
||||
auto doc = this->document();
|
||||
auto lastLine =
|
||||
doc->findBlockByLineNumber(doc->blockCount() - 1);
|
||||
auto lastLine = doc->lastBlock();
|
||||
switch (type) {
|
||||
case ScriptMachine::MessageType::Info:
|
||||
if (lastLine.length()) {
|
||||
_s << Qt::endl;
|
||||
}
|
||||
write(tr("[Info]") + message.message);
|
||||
stdOut(tr("[Info]") + message.message);
|
||||
_s << Qt::flush;
|
||||
newLine();
|
||||
break;
|
||||
|
@ -66,7 +68,7 @@ void ScriptingConsole::init() {
|
|||
if (lastLine.length()) {
|
||||
_s << Qt::endl;
|
||||
}
|
||||
write(tr("[Warn]") + message.message);
|
||||
stdWarn(tr("[Warn]") + message.message);
|
||||
_s << Qt::flush;
|
||||
newLine();
|
||||
break;
|
||||
|
@ -74,7 +76,7 @@ void ScriptingConsole::init() {
|
|||
if (lastLine.length()) {
|
||||
_s << Qt::endl;
|
||||
}
|
||||
write(tr("[Error]") + message.message);
|
||||
stdErr(tr("[Error]") + message.message);
|
||||
_s << Qt::flush;
|
||||
newLine();
|
||||
break;
|
||||
|
@ -82,7 +84,7 @@ void ScriptingConsole::init() {
|
|||
// If running ouput in the console,
|
||||
// otherwise logging.
|
||||
if (_sp->isRunning()) {
|
||||
write(message.message);
|
||||
stdOut(message.message);
|
||||
} else {
|
||||
Logger::logPrint(Logger::packDebugStr(
|
||||
packUpLoggingStr(message.message)));
|
||||
|
@ -96,11 +98,11 @@ void ScriptingConsole::init() {
|
|||
}
|
||||
|
||||
void ScriptingConsole::initOutput() {
|
||||
_s << QStringLiteral(R"(""")") << Qt::endl;
|
||||
write(tr("Scripting console for WingHexExplorer"));
|
||||
stdWarn(tr("Scripting console for WingHexExplorer"));
|
||||
|
||||
_s << Qt::endl;
|
||||
write(tr(">>>> Powered by AngelScript <<<<"));
|
||||
_s << Qt::endl << QStringLiteral(R"(""")") << Qt::endl;
|
||||
stdWarn(tr(">>>> Powered by AngelScript <<<<"));
|
||||
_s << Qt::endl << Qt::endl;
|
||||
appendCommandPrompt();
|
||||
setMode(Input);
|
||||
}
|
||||
|
@ -112,19 +114,9 @@ void ScriptingConsole::clearConsole() {
|
|||
setMode(Input);
|
||||
}
|
||||
|
||||
void ScriptingConsole::pushInputCmd(const QString &cmd) {
|
||||
QMutexLocker locker(&_queueLocker);
|
||||
_cmdQueue.append(cmd);
|
||||
}
|
||||
|
||||
void ScriptingConsole::processKeyEvent(QKeyEvent *e) { keyPressEvent(e); }
|
||||
|
||||
void ScriptingConsole::runConsoleCommand(const QString &code) {
|
||||
if (_waitforRead) {
|
||||
_waitforRead = false;
|
||||
return;
|
||||
}
|
||||
|
||||
auto exec = code.trimmed();
|
||||
if (exec.endsWith('\\')) {
|
||||
static QRegularExpression ex(QStringLiteral("[\\\\\\s]+$"));
|
||||
|
@ -146,30 +138,10 @@ void ScriptingConsole::runConsoleCommand(const QString &code) {
|
|||
QString ScriptingConsole::getInput() {
|
||||
appendCommandPrompt(true);
|
||||
setMode(Input);
|
||||
_waitforRead = true;
|
||||
_s.device()->waitForReadyRead(-1);
|
||||
QString instr;
|
||||
|
||||
auto d = _s.device();
|
||||
d->skip(d->bytesAvailable());
|
||||
|
||||
do {
|
||||
{
|
||||
QMutexLocker locker(&_queueLocker);
|
||||
if (!_cmdQueue.isEmpty()) {
|
||||
instr = _cmdQueue.takeFirst();
|
||||
setMode(Output);
|
||||
write(instr);
|
||||
setMode(Input);
|
||||
break;
|
||||
}
|
||||
}
|
||||
qApp->processEvents();
|
||||
} while (!d->waitForReadyRead(100));
|
||||
|
||||
instr = _s.readAll();
|
||||
|
||||
_s >> instr;
|
||||
setMode(Output);
|
||||
|
||||
return instr;
|
||||
}
|
||||
|
||||
|
@ -191,10 +163,10 @@ void ScriptingConsole::appendCommandPrompt(bool storeOnly) {
|
|||
if (storeOnly) {
|
||||
commandPrompt += QStringLiteral("... > ");
|
||||
} else {
|
||||
auto cursor = this->cursor();
|
||||
// if (!cursor.atBlockStart()) {
|
||||
// commandPrompt = QStringLiteral("\n");
|
||||
// }
|
||||
auto cursor = this->textCursor();
|
||||
if (!cursor.atBlockStart()) {
|
||||
commandPrompt = QStringLiteral("\n");
|
||||
}
|
||||
if (_sp && _sp->isDebugMode()) {
|
||||
commandPrompt += QStringLiteral("[dbg] > ");
|
||||
} else {
|
||||
|
@ -204,7 +176,7 @@ void ScriptingConsole::appendCommandPrompt(bool storeOnly) {
|
|||
|
||||
_lastCommandPrompt = storeOnly;
|
||||
|
||||
appendPlainText(commandPrompt);
|
||||
stdOut(commandPrompt);
|
||||
}
|
||||
|
||||
ScriptMachine *ScriptingConsole::machine() const { return _sp; }
|
||||
|
|
|
@ -38,6 +38,9 @@ public:
|
|||
void appendCommandPrompt(bool storeOnly = false);
|
||||
|
||||
public slots:
|
||||
void stdOut(const QString &str);
|
||||
void stdErr(const QString &str);
|
||||
void stdWarn(const QString &str);
|
||||
void newLine();
|
||||
|
||||
void init();
|
||||
|
@ -46,8 +49,6 @@ public slots:
|
|||
|
||||
void clearConsole();
|
||||
|
||||
void pushInputCmd(const QString &cmd);
|
||||
|
||||
void processKeyEvent(QKeyEvent *e);
|
||||
|
||||
private:
|
||||
|
@ -67,10 +68,7 @@ private:
|
|||
bool _lastCommandPrompt = false;
|
||||
QString _codes;
|
||||
|
||||
QStringList _cmdQueue;
|
||||
QMutex _queueLocker;
|
||||
bool _waitforRead = false;
|
||||
|
||||
QTextCharFormat _warnCharFmt;
|
||||
std::function<QString(void)> _getInputFn;
|
||||
};
|
||||
|
||||
|
|
|
@ -305,6 +305,10 @@ MainWindow::MainWindow(SplashDialog *splash) : FramelessMainWindow() {
|
|||
if (splash)
|
||||
splash->setInfoText(tr("SetupWaiting"));
|
||||
|
||||
// others
|
||||
_showtxt = new ShowTextDialog(this);
|
||||
qApp->processEvents();
|
||||
|
||||
// update status
|
||||
updateEditModeEnabled();
|
||||
|
||||
|
@ -1464,6 +1468,9 @@ RibbonTabContent *MainWindow::buildViewPage(RibbonTabContent *tab) {
|
|||
m_editStateWidgets << addPannelAction(
|
||||
pannel, QStringLiteral("scalereset"), tr("ResetScale"),
|
||||
[this] { this->setCurrentHexEditorScale(1.0); });
|
||||
m_editStateWidgets << addPannelAction(pannel, QStringLiteral("viewtxt"),
|
||||
tr("ViewText"),
|
||||
&MainWindow::on_viewtxt);
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -2927,7 +2934,6 @@ void MainWindow::on_selectionChanged() {
|
|||
return;
|
||||
}
|
||||
|
||||
// 解码字符串
|
||||
auto cursor = hexeditor->cursor();
|
||||
QByteArrayList buffer;
|
||||
bool isPreview = false;
|
||||
|
@ -2956,7 +2962,6 @@ void MainWindow::on_selectionChanged() {
|
|||
.arg(total));
|
||||
}
|
||||
|
||||
// 如果不超过 10KB (默认)那么解码,防止太多卡死
|
||||
if (buffer.length() <= 1024 * _decstrlim) {
|
||||
m_txtDecode->insertPlainText(
|
||||
Utilities::decodingString(b, m_encoding));
|
||||
|
@ -2973,6 +2978,14 @@ void MainWindow::on_selectionChanged() {
|
|||
{QVariant::fromValue(buffer), isPreview});
|
||||
}
|
||||
|
||||
void MainWindow::on_viewtxt() {
|
||||
auto hexeditor = currentHexView();
|
||||
if (hexeditor == nullptr) {
|
||||
return;
|
||||
}
|
||||
_showtxt->load(hexeditor->document()->buffer());
|
||||
}
|
||||
|
||||
void MainWindow::on_fullScreen() {
|
||||
if (this->isFullScreen()) {
|
||||
this->showMaximized();
|
||||
|
@ -3110,8 +3123,7 @@ void MainWindow::on_update() {
|
|||
|
||||
QString MainWindow::saveLog() {
|
||||
QDir ndir(Utilities::getAppDataPath());
|
||||
ndir.mkpath(QStringLiteral("log")); // 确保日志存放目录存在
|
||||
|
||||
ndir.mkpath(QStringLiteral("log"));
|
||||
QFile lfile(ndir.absolutePath() + QDir::separator() +
|
||||
QStringLiteral("log") + QDir::separator() +
|
||||
QDateTime::currentDateTime().toString(
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include "dialog/showtextdialog.h"
|
||||
#include "dialog/splashdialog.h"
|
||||
#include "framelessmainwindow.h"
|
||||
|
||||
|
@ -196,6 +197,7 @@ private slots:
|
|||
void on_locChanged();
|
||||
void on_selectionChanged();
|
||||
|
||||
void on_viewtxt();
|
||||
void on_fullScreen();
|
||||
void on_saveLayout();
|
||||
void on_exportlog();
|
||||
|
@ -294,7 +296,7 @@ private:
|
|||
auto a = new QToolButton(pannel);
|
||||
#if QT_VERSION <= QT_VERSION_CHECK(6, 6, 0)
|
||||
if (menu) {
|
||||
a->setText(title + QStringLiteral(" ▼"));
|
||||
a->setText(title + QStringLiteral(" 闁充紮鎷<EFBFBD>"));
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
|
@ -569,6 +571,8 @@ private:
|
|||
QToolButton *m_sLocked = nullptr;
|
||||
QToolButton *m_sCanOver = nullptr;
|
||||
|
||||
ShowTextDialog *_showtxt = nullptr;
|
||||
|
||||
// cache icon
|
||||
QIcon _infoSaved, _infoUnsaved;
|
||||
QIcon _infoWriteable, _infoReadonly;
|
||||
|
@ -590,9 +594,11 @@ private:
|
|||
|
||||
// these variables will be invalid after restoring state
|
||||
ads::CDockAreaWidget *m_leftViewArea = nullptr;
|
||||
ads::CDockAreaWidget *m_rightViewArea = nullptr; // 该值使用时必不为空
|
||||
ads::CDockAreaWidget *m_rightViewArea =
|
||||
nullptr; // 閻犲洢鍎遍埀顒勬?婵炲洭鎮介妸锔筋槯闊洤鎳嶇粭澶嬬▔閾忓厜鏁<E58E9C>
|
||||
ads::CDockAreaWidget *m_topViewArea = nullptr;
|
||||
ads::CDockAreaWidget *m_bottomViewArea = nullptr; // 该值使用时必不为空
|
||||
ads::CDockAreaWidget *m_bottomViewArea =
|
||||
nullptr; // 閻犲洢鍎遍埀顒勬?婵炲洭鎮介妸锔筋槯闊洤鎳嶇粭澶嬬▔閾忓厜鏁<E58E9C>
|
||||
|
||||
//================================
|
||||
|
||||
|
|
|
@ -42,11 +42,8 @@ ShowTextDialog::ShowTextDialog(QWidget *parent) : FramelessDialogBase(parent) {
|
|||
layout->setSpacing(0);
|
||||
layout->addWidget(q_check_ptr(m_ribbon));
|
||||
|
||||
m_edit = new WingCodeEdit(this);
|
||||
// auto editor = m_edit->editor();
|
||||
// editor->setCodec(QStringLiteral("ASCII"));
|
||||
// connect(editor, &QEditor::needLoading, this,
|
||||
// [this]() { load(m_last.buffer, m_last.offset, m_last.size); });
|
||||
m_edit = new CodeEdit(this);
|
||||
m_edit->setShowLongLineEdge(false);
|
||||
|
||||
m_edit->setReadOnly(true);
|
||||
m_edit->setAcceptDrops(false);
|
||||
|
@ -94,14 +91,14 @@ void ShowTextDialog::load(QHexBuffer *buffer, qsizetype offset,
|
|||
return;
|
||||
}
|
||||
|
||||
// auto editor = m_edit->editor();
|
||||
// editor->setUpdatesEnabled(false);
|
||||
m_edit->setUpdatesEnabled(false);
|
||||
|
||||
// auto doc = editor->document();
|
||||
// auto orign = offset;
|
||||
|
||||
// editor->setUpdatesEnabled(true);
|
||||
m_edit->setUpdatesEnabled(true);
|
||||
// m_status->showMessage(editor->codecName());
|
||||
show();
|
||||
}
|
||||
|
||||
void ShowTextDialog::buildUpRibbonBar() {
|
||||
|
@ -146,7 +143,7 @@ RibbonTabContent *ShowTextDialog::buildViewPage(RibbonTabContent *tab) {
|
|||
}
|
||||
|
||||
void ShowTextDialog::on_copyfile() {
|
||||
// m_edit->editor()->copy();
|
||||
m_edit->copy();
|
||||
Toast::toast(this, NAMEICONRES(QStringLiteral("copy")),
|
||||
tr("CopyToClipBoard"));
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include "QWingRibbon/ribbonbuttongroup.h"
|
||||
#include "QWingRibbon/ribbontabcontent.h"
|
||||
|
||||
#include "WingCodeEdit/wingcodeedit.h"
|
||||
#include "control/codeedit.h"
|
||||
#include "framelessdialogbase.h"
|
||||
#include "utilities.h"
|
||||
|
||||
|
@ -122,7 +122,7 @@ private slots:
|
|||
|
||||
private:
|
||||
Ribbon *m_ribbon = nullptr;
|
||||
WingCodeEdit *m_edit = nullptr;
|
||||
CodeEdit *m_edit = nullptr;
|
||||
bool m_canceled = false;
|
||||
|
||||
QStatusBar *m_status = nullptr;
|
||||
|
|
Loading…
Reference in New Issue