Compare commits
5 Commits
93a3a8aefd
...
d5a4095779
Author | SHA1 | Date |
---|---|---|
|
d5a4095779 | |
|
48cf02cfa9 | |
|
912dfaf227 | |
|
c08c2a859e | |
|
96fa55d930 |
|
@ -9,5 +9,5 @@ jobs:
|
|||
- name: Run clang-format style check for C/C++/Protobuf programs.
|
||||
uses: jidicula/clang-format-action@v4.13.0
|
||||
with:
|
||||
clang-format-version: '13'
|
||||
clang-format-version: '12'
|
||||
fallback-style: 'LLVM' # optional
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
*.pro.user*
|
||||
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
project(
|
||||
QConsoleWidget
|
||||
VERSION 2.14.1
|
||||
LANGUAGES CXX)
|
||||
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
|
||||
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)
|
||||
|
||||
if(MSVC)
|
||||
string(APPEND CMAKE_CXX_FLAGS " /utf-8")
|
||||
string(APPEND CMAKE_C_FLAGS " /utf-8")
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
|
||||
add_library(
|
||||
QConsoleWidget STATIC src/QConsoleIODevice.cpp src/QConsoleIODevice.h
|
||||
src/QConsoleWidget.cpp src/QConsoleWidget.h)
|
||||
|
||||
target_link_libraries(QConsoleWidget PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
|
|
@ -9,7 +9,7 @@
|
|||
QConsoleIODevice::QConsoleIODevice(QConsoleWidget *w, QObject *parent)
|
||||
: QIODevice(parent), widget_(w), readpos_(0), writtenSinceLastEmit_(0),
|
||||
readSinceLastEmit_(0) {
|
||||
setCurrentWriteChannel(QConsoleWidget::StandardOutput);
|
||||
setCurrentWriteChannel(STDOUT_FILENO);
|
||||
|
||||
open(QIODevice::ReadWrite | QIODevice::Unbuffered);
|
||||
}
|
||||
|
@ -53,10 +53,10 @@ qint64 QConsoleIODevice::readData(char *data, qint64 len) {
|
|||
qint64 QConsoleIODevice::writeData(const char *data, qint64 len) {
|
||||
QByteArray ba(data, (int)len);
|
||||
int ch = currentWriteChannel();
|
||||
if (ch == QConsoleWidget::StandardError)
|
||||
widget_->writeStdErr(ba);
|
||||
else
|
||||
if (ch == STDOUT_FILENO)
|
||||
widget_->writeStdOut(ba);
|
||||
else
|
||||
widget_->writeStdErr(ba);
|
||||
|
||||
writtenSinceLastEmit_ += len;
|
||||
if (!signalsBlocked()) {
|
|
@ -6,8 +6,15 @@
|
|||
|
||||
class QConsoleWidget;
|
||||
|
||||
class QConsoleIODevice : public QIODevice {
|
||||
#ifndef STDOUT_FILENO
|
||||
#define STDOUT_FILENO 1
|
||||
#endif
|
||||
|
||||
#ifndef STDERR_FILENO
|
||||
#define STDERR_FILENO 2
|
||||
#endif
|
||||
|
||||
class QConsoleIODevice : public QIODevice {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
|
@ -0,0 +1,447 @@
|
|||
#include "QConsoleWidget.h"
|
||||
|
||||
#include "class/ascompletion.h"
|
||||
#include "control/qcodecompletionwidget.h"
|
||||
#include "qdocumentline.h"
|
||||
#include "qformatscheme.h"
|
||||
#include "qlanguagefactory.h"
|
||||
#include "utilities.h"
|
||||
|
||||
#include "QConsoleIODevice.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QKeyEvent>
|
||||
#include <QMenu>
|
||||
#include <QMimeData>
|
||||
#include <QMouseEvent>
|
||||
#include <QScrollBar>
|
||||
|
||||
QConsoleWidget::QConsoleWidget(QWidget *parent)
|
||||
: QEditor(false, parent), mode_(Output) {
|
||||
iodevice_ = new QConsoleIODevice(this, this);
|
||||
setUndoRedoEnabled(false);
|
||||
}
|
||||
|
||||
QConsoleWidget::~QConsoleWidget() {}
|
||||
|
||||
void QConsoleWidget::setMode(ConsoleMode m) {
|
||||
if (m == mode_)
|
||||
return;
|
||||
|
||||
if (m == Input) {
|
||||
auto cursor = this->cursor();
|
||||
cursor.movePosition(QDocumentCursor::End);
|
||||
setCursor(cursor);
|
||||
inpos_ = cursor;
|
||||
mode_ = Input;
|
||||
}
|
||||
|
||||
if (m == Output) {
|
||||
mode_ = Output;
|
||||
}
|
||||
}
|
||||
|
||||
QString QConsoleWidget::getCommandLine() {
|
||||
if (mode_ == Output)
|
||||
return QString();
|
||||
auto textCursor = this->cursor();
|
||||
auto ltxt = textCursor.line().text();
|
||||
QString code = ltxt.mid(inpos_.columnNumber());
|
||||
return code.replace(QChar::ParagraphSeparator, QChar::LineFeed);
|
||||
}
|
||||
|
||||
void QConsoleWidget::clear() { document()->clear(); }
|
||||
|
||||
void QConsoleWidget::handleReturnKey() {
|
||||
QString code = getCommandLine();
|
||||
|
||||
// start new block
|
||||
auto textCursor = this->cursor();
|
||||
auto line = textCursor.line();
|
||||
textCursor.moveTo(line.lineNumber(), line.length());
|
||||
textCursor.insertLine();
|
||||
|
||||
setMode(Output);
|
||||
setCursor(textCursor);
|
||||
|
||||
// Update the history
|
||||
if (!code.isEmpty())
|
||||
history_.add(code);
|
||||
|
||||
// send signal / update iodevice
|
||||
if (iodevice_->isOpen())
|
||||
iodevice_->consoleWidgetInput(code);
|
||||
|
||||
emit consoleCommand(code);
|
||||
}
|
||||
|
||||
void QConsoleWidget::keyPressEvent(QKeyEvent *e) {
|
||||
if (mode() == Input) {
|
||||
auto ascom = dynamic_cast<AsCompletion *>(completionEngine());
|
||||
if (ascom) {
|
||||
auto cw = ascom->codeCompletionWidget();
|
||||
if (cw && cw->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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto textCursor = this->cursor();
|
||||
bool selectionInEditZone = isSelectionInEditZone();
|
||||
|
||||
// check for user abort request
|
||||
if (e->modifiers() & Qt::ControlModifier) {
|
||||
if (e->key() == Qt::Key_Q) // Ctrl-Q aborts
|
||||
{
|
||||
emit abortEvaluation();
|
||||
e->accept();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Allow copying anywhere in the console ...
|
||||
if (e->key() == Qt::Key_C && e->modifiers() == Qt::ControlModifier) {
|
||||
if (textCursor.hasSelection())
|
||||
copy();
|
||||
e->accept();
|
||||
return;
|
||||
}
|
||||
|
||||
// the rest of key events are ignored during output mode
|
||||
if (mode() != Input) {
|
||||
e->ignore();
|
||||
return;
|
||||
}
|
||||
|
||||
// Allow cut only if the selection is limited to the interactive area ...
|
||||
if (e->key() == Qt::Key_X && e->modifiers() == Qt::ControlModifier) {
|
||||
if (selectionInEditZone)
|
||||
cut();
|
||||
e->accept();
|
||||
return;
|
||||
}
|
||||
|
||||
// Allow paste only if the selection is in the interactive area ...
|
||||
if (e->key() == Qt::Key_V && e->modifiers() == Qt::ControlModifier) {
|
||||
if (selectionInEditZone || isCursorInEditZone()) {
|
||||
const QMimeData *const clipboard =
|
||||
QApplication::clipboard()->mimeData();
|
||||
const QString text = clipboard->text();
|
||||
if (!text.isNull()) {
|
||||
textCursor.insertText(text/*,
|
||||
channelCharFormat(StandardInput)*/);
|
||||
}
|
||||
}
|
||||
|
||||
e->accept();
|
||||
return;
|
||||
}
|
||||
|
||||
int key = e->key();
|
||||
// int shiftMod = e->modifiers() == Qt::ShiftModifier;
|
||||
|
||||
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
|
||||
if (!isCursorInEditZone() && key != Qt::Key_Control &&
|
||||
key != Qt::Key_Shift && key != Qt::Key_Alt) {
|
||||
auto line = textCursor.line();
|
||||
textCursor.moveTo(line.lineNumber(), line.length());
|
||||
setCursor(textCursor);
|
||||
}
|
||||
|
||||
switch (key) {
|
||||
case Qt::Key_Up:
|
||||
// Activate the history and move to the 1st matching history item
|
||||
if (!history_.isActive())
|
||||
history_.activate(getCommandLine());
|
||||
if (history_.move(true))
|
||||
replaceCommandLine(history_.currentValue());
|
||||
else
|
||||
QApplication::beep();
|
||||
e->accept();
|
||||
break;
|
||||
|
||||
case Qt::Key_Down:
|
||||
if (history_.move(false))
|
||||
replaceCommandLine(history_.currentValue());
|
||||
else
|
||||
QApplication::beep();
|
||||
e->accept();
|
||||
|
||||
case Qt::Key_Left:
|
||||
if (textCursor > inpos_)
|
||||
QEditor::keyPressEvent(e);
|
||||
else {
|
||||
QApplication::beep();
|
||||
e->accept();
|
||||
}
|
||||
break;
|
||||
|
||||
case Qt::Key_Delete:
|
||||
e->accept();
|
||||
if (selectionInEditZone)
|
||||
cut();
|
||||
else {
|
||||
// cursor must be in edit zone
|
||||
if (textCursor < inpos_)
|
||||
QApplication::beep();
|
||||
else
|
||||
QEditor::keyPressEvent(e);
|
||||
}
|
||||
break;
|
||||
|
||||
case Qt::Key_Backspace:
|
||||
e->accept();
|
||||
if (selectionInEditZone)
|
||||
cut();
|
||||
else {
|
||||
// cursor must be in edit zone
|
||||
if (textCursor <= inpos_)
|
||||
QApplication::beep();
|
||||
else
|
||||
QEditor::keyPressEvent(e);
|
||||
}
|
||||
break;
|
||||
|
||||
case Qt::Key_Home:
|
||||
e->accept();
|
||||
setCursor(inpos_);
|
||||
break;
|
||||
|
||||
case Qt::Key_Enter:
|
||||
case Qt::Key_Return:
|
||||
e->accept();
|
||||
handleReturnKey();
|
||||
break;
|
||||
|
||||
case Qt::Key_Escape:
|
||||
e->accept();
|
||||
replaceCommandLine(QString());
|
||||
break;
|
||||
|
||||
default:
|
||||
// setCurrentCharFormat(chanFormat_[StandardInput]);
|
||||
if (isCursorInEditZone()) {
|
||||
QEditor::keyPressEvent(e);
|
||||
} else {
|
||||
e->ignore();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void QConsoleWidget::contextMenuEvent(QContextMenuEvent *event) {
|
||||
// QMenu *menu = createStandardContextMenu();
|
||||
|
||||
// QAction *a;
|
||||
// if ((a = menu->findChild<QAction *>("edit-cut")))
|
||||
// a->setEnabled(canCut());
|
||||
// if ((a = menu->findChild<QAction *>("edit-delete")))
|
||||
// a->setEnabled(canCut());
|
||||
// if ((a = menu->findChild<QAction *>("edit-paste")))
|
||||
// a->setEnabled(canPaste());
|
||||
|
||||
// menu->exec(event->globalPos());
|
||||
// delete menu;
|
||||
}
|
||||
|
||||
bool QConsoleWidget::isSelectionInEditZone() const {
|
||||
auto textCursor = this->cursor();
|
||||
if (!textCursor.hasSelection())
|
||||
return false;
|
||||
|
||||
auto selectionStart = textCursor.selectionStart();
|
||||
auto selectionEnd = textCursor.selectionEnd();
|
||||
|
||||
return selectionStart > inpos_ && selectionEnd >= inpos_;
|
||||
}
|
||||
|
||||
bool QConsoleWidget::isCursorInEditZone() const { return cursor() >= inpos_; }
|
||||
|
||||
bool QConsoleWidget::canPaste() const {
|
||||
auto textCursor = this->cursor();
|
||||
if (textCursor < inpos_)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void QConsoleWidget::replaceCommandLine(const QString &str) {
|
||||
// Select the text after the last command prompt ...
|
||||
auto textCursor = this->cursor();
|
||||
auto line = textCursor.line();
|
||||
textCursor.moveTo(line.lineNumber(), line.length());
|
||||
|
||||
auto bcursor = inpos_;
|
||||
bcursor.setSelectionBoundary(textCursor);
|
||||
bcursor.replaceSelectedText(str);
|
||||
bcursor.movePosition(str.length());
|
||||
|
||||
setCursor(bcursor);
|
||||
}
|
||||
|
||||
QString QConsoleWidget::getHistoryPath() {
|
||||
QDir dir(Utilities::getAppDataPath());
|
||||
return dir.absoluteFilePath(QStringLiteral(".command_history.lst"));
|
||||
}
|
||||
|
||||
void QConsoleWidget::write(const QString &message, const QString &sfmtID) {
|
||||
auto tc = cursor();
|
||||
auto ascom = dynamic_cast<AsCompletion *>(completionEngine());
|
||||
Q_ASSERT(ascom);
|
||||
auto cw = ascom->codeCompletionWidget();
|
||||
|
||||
if (mode() == Output || (cw && cw->isCompleting())) {
|
||||
// in output mode or completion messages are appended
|
||||
auto tc1 = tc;
|
||||
tc1.movePosition(QDocumentCursor::End);
|
||||
|
||||
// check is cursor was not at the end
|
||||
// (e.g. had been moved per mouse action)
|
||||
bool needsRestore = tc1.position() != tc.position();
|
||||
|
||||
// insert text
|
||||
setCursor(tc1);
|
||||
tc.insertText(message, false, sfmtID);
|
||||
ensureCursorVisible();
|
||||
|
||||
// restore cursor if needed
|
||||
if (needsRestore)
|
||||
setCursor(tc);
|
||||
} else {
|
||||
// in Input mode output messages are inserted
|
||||
// before the edit block
|
||||
|
||||
// get offset of current pos from the end
|
||||
auto editpos = tc;
|
||||
auto line = editpos.line();
|
||||
tc.moveTo(line, 0);
|
||||
tc.insertLine();
|
||||
tc.insertText(message, false, sfmtID);
|
||||
setCursor(editpos);
|
||||
}
|
||||
}
|
||||
|
||||
void QConsoleWidget::writeStdOut(const QString &s) {
|
||||
write(s, QStringLiteral("stdout"));
|
||||
}
|
||||
|
||||
void QConsoleWidget::writeStdErr(const QString &s) {
|
||||
write(s, QStringLiteral("stderr"));
|
||||
}
|
||||
|
||||
/////////////////// QConsoleWidget::History /////////////////////
|
||||
|
||||
QConsoleWidget::History QConsoleWidget::history_;
|
||||
|
||||
QConsoleWidget::History::History(void)
|
||||
: pos_(0), active_(false), maxsize_(10000) {
|
||||
QFile f(QConsoleWidget::getHistoryPath());
|
||||
if (f.open(QFile::ReadOnly)) {
|
||||
QTextStream is(&f);
|
||||
while (!is.atEnd())
|
||||
add(is.readLine());
|
||||
}
|
||||
}
|
||||
QConsoleWidget::History::~History(void) {
|
||||
QFile f(QConsoleWidget::getHistoryPath());
|
||||
if (f.open(QFile::WriteOnly | QFile::Truncate)) {
|
||||
QTextStream os(&f);
|
||||
int n = strings_.size();
|
||||
while (n > 0)
|
||||
os << strings_.at(--n) << Qt::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void QConsoleWidget::History::add(const QString &str) {
|
||||
active_ = false;
|
||||
// if (strings_.contains(str)) return;
|
||||
if (strings_.size() == maxsize_)
|
||||
strings_.pop_back();
|
||||
strings_.push_front(str);
|
||||
}
|
||||
|
||||
void QConsoleWidget::History::activate(const QString &tk) {
|
||||
active_ = true;
|
||||
token_ = tk;
|
||||
pos_ = -1;
|
||||
}
|
||||
|
||||
bool QConsoleWidget::History::move(bool dir) {
|
||||
if (active_) {
|
||||
int next = indexOf(dir, pos_);
|
||||
if (pos_ != next) {
|
||||
pos_ = next;
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
int QConsoleWidget::History::indexOf(bool dir, int from) const {
|
||||
int i = from, to = from;
|
||||
if (dir) {
|
||||
while (i < strings_.size() - 1) {
|
||||
const QString &si = strings_.at(++i);
|
||||
if (si.startsWith(token_)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while (i > 0) {
|
||||
const QString &si = strings_.at(--i);
|
||||
if (si.startsWith(token_)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
return to;
|
||||
}
|
||||
|
||||
/////////////////// Stream manipulators /////////////////////
|
||||
|
||||
QTextStream &waitForInput(QTextStream &s) {
|
||||
QConsoleIODevice *d = qobject_cast<QConsoleIODevice *>(s.device());
|
||||
if (d)
|
||||
d->waitForReadyRead(-1);
|
||||
return s;
|
||||
}
|
||||
|
||||
QTextStream &inputMode(QTextStream &s) {
|
||||
QConsoleIODevice *d = qobject_cast<QConsoleIODevice *>(s.device());
|
||||
if (d && d->widget())
|
||||
d->widget()->setMode(QConsoleWidget::Input);
|
||||
return s;
|
||||
}
|
||||
QTextStream &outChannel(QTextStream &s) {
|
||||
QConsoleIODevice *d = qobject_cast<QConsoleIODevice *>(s.device());
|
||||
if (d)
|
||||
d->setCurrentWriteChannel(STDOUT_FILENO);
|
||||
return s;
|
||||
}
|
||||
QTextStream &errChannel(QTextStream &s) {
|
||||
QConsoleIODevice *d = qobject_cast<QConsoleIODevice *>(s.device());
|
||||
if (d)
|
||||
d->setCurrentWriteChannel(STDERR_FILENO);
|
||||
return s;
|
||||
}
|
|
@ -1,54 +1,41 @@
|
|||
#ifndef _QCONSOLEWIDGET_H_
|
||||
#define _QCONSOLEWIDGET_H_
|
||||
|
||||
#include <QCompleter>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QIODevice>
|
||||
#include <QTextCharFormat>
|
||||
#include <QTextStream>
|
||||
|
||||
class QConsoleIODevice;
|
||||
class QConsoleWidgetCompleter;
|
||||
#include "qeditor.h"
|
||||
#include "qlanguagefactory.h"
|
||||
|
||||
class QConsoleWidget : public QPlainTextEdit {
|
||||
class QConsoleIODevice;
|
||||
|
||||
class QConsoleWidget : public QEditor {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum ConsoleMode { Input, Output };
|
||||
Q_ENUM(ConsoleMode)
|
||||
|
||||
enum ConsoleChannel {
|
||||
StandardInput,
|
||||
StandardOutput,
|
||||
StandardError,
|
||||
nConsoleChannels
|
||||
};
|
||||
Q_ENUM(ConsoleChannel)
|
||||
|
||||
QConsoleWidget(QWidget *parent = 0);
|
||||
~QConsoleWidget();
|
||||
explicit QConsoleWidget(QWidget *parent = nullptr);
|
||||
virtual ~QConsoleWidget();
|
||||
|
||||
ConsoleMode mode() const { return mode_; }
|
||||
void setMode(ConsoleMode m);
|
||||
QIODevice *device() const { return (QIODevice *)iodevice_; }
|
||||
QTextCharFormat channelCharFormat(ConsoleChannel ch) const {
|
||||
return chanFormat_[ch];
|
||||
}
|
||||
void setChannelCharFormat(ConsoleChannel ch, const QTextCharFormat &fmt) {
|
||||
chanFormat_[ch] = fmt;
|
||||
}
|
||||
const QStringList &completionTriggers() const {
|
||||
return completion_triggers_;
|
||||
}
|
||||
void setCompletionTriggers(const QStringList &l) {
|
||||
completion_triggers_ = l;
|
||||
}
|
||||
|
||||
virtual QSize sizeHint() const override { return QSize(600, 400); }
|
||||
|
||||
// write a formatted message to the console
|
||||
void write(const QString &message, const QTextCharFormat &fmt);
|
||||
void write(const QString &message, const QString &sfmtID = {}) override;
|
||||
|
||||
static const QStringList &history() { return history_.strings_; }
|
||||
void setCompleter(QConsoleWidgetCompleter *c);
|
||||
|
||||
// get the current command line
|
||||
QString getCommandLine();
|
||||
|
||||
void clear();
|
||||
|
||||
public slots:
|
||||
|
||||
// write to StandardOutput
|
||||
|
@ -67,10 +54,7 @@ protected:
|
|||
bool canPaste() const;
|
||||
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;
|
||||
// Returns true if there is a selection in edit zone
|
||||
|
@ -82,11 +66,6 @@ protected:
|
|||
|
||||
static QString getHistoryPath();
|
||||
|
||||
protected slots:
|
||||
|
||||
// insert the completion from completer
|
||||
void insertCompletion(const QString &completion);
|
||||
|
||||
private:
|
||||
struct History {
|
||||
QStringList strings_;
|
||||
|
@ -109,12 +88,11 @@ private:
|
|||
|
||||
static History history_;
|
||||
ConsoleMode mode_;
|
||||
int inpos_, completion_pos_;
|
||||
QStringList completion_triggers_;
|
||||
QDocumentCursor inpos_;
|
||||
QString currentMultiLineCode_;
|
||||
QConsoleIODevice *iodevice_;
|
||||
QTextCharFormat chanFormat_[nConsoleChannels];
|
||||
QConsoleWidgetCompleter *completer_;
|
||||
|
||||
QLanguageFactory *m_language = nullptr;
|
||||
};
|
||||
|
||||
QTextStream &waitForInput(QTextStream &s);
|
||||
|
@ -122,22 +100,4 @@ 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
|
Binary file not shown.
Before Width: | Height: | Size: 57 KiB |
|
@ -1,577 +0,0 @@
|
|||
#include "QConsoleWidget.h"
|
||||
#include "QConsoleIODevice.h"
|
||||
|
||||
#include <QAbstractItemView>
|
||||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QKeyEvent>
|
||||
#include <QMenu>
|
||||
#include <QMimeData>
|
||||
#include <QMouseEvent>
|
||||
#include <QScrollBar>
|
||||
#include <QStandardPaths>
|
||||
#include <QStringListModel>
|
||||
#include <QTextBlock>
|
||||
#include <QTextCursor>
|
||||
#include <QTextDocumentFragment>
|
||||
|
||||
QConsoleWidget::QConsoleWidget(QWidget *parent)
|
||||
: 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].setForeground(Qt::darkBlue);
|
||||
chanFormat_[StandardError].setForeground(Qt::red);
|
||||
|
||||
setTextInteractionFlags(Qt::TextEditorInteraction);
|
||||
setUndoRedoEnabled(false);
|
||||
}
|
||||
|
||||
QConsoleWidget::~QConsoleWidget() {}
|
||||
|
||||
void QConsoleWidget::setMode(ConsoleMode m) {
|
||||
if (m == mode_)
|
||||
return;
|
||||
|
||||
if (m == Input) {
|
||||
QTextCursor cursor = textCursor();
|
||||
cursor.movePosition(QTextCursor::End);
|
||||
setTextCursor(cursor);
|
||||
setCurrentCharFormat(chanFormat_[StandardInput]);
|
||||
inpos_ = cursor.position();
|
||||
mode_ = Input;
|
||||
}
|
||||
|
||||
if (m == Output) {
|
||||
mode_ = Output;
|
||||
}
|
||||
}
|
||||
|
||||
QString QConsoleWidget::getCommandLine() {
|
||||
if (mode_ == Output)
|
||||
return QString();
|
||||
// select text in edit zone (from the input pos to the end)
|
||||
QTextCursor textCursor = this->textCursor();
|
||||
textCursor.movePosition(QTextCursor::End);
|
||||
textCursor.setPosition(inpos_, QTextCursor::KeepAnchor);
|
||||
QString code = textCursor.selectedText();
|
||||
code.replace(QChar::ParagraphSeparator, QChar::LineFeed);
|
||||
return code;
|
||||
}
|
||||
|
||||
void QConsoleWidget::handleReturnKey() {
|
||||
QString code = getCommandLine();
|
||||
|
||||
// start new block
|
||||
appendPlainText(QString());
|
||||
setMode(Output);
|
||||
|
||||
QTextCursor textCursor = this->textCursor();
|
||||
textCursor.movePosition(QTextCursor::End);
|
||||
setTextCursor(textCursor);
|
||||
|
||||
// Update the history
|
||||
if (!code.isEmpty())
|
||||
history_.add(code);
|
||||
|
||||
// send signal / update iodevice
|
||||
if (iodevice_->isOpen())
|
||||
iodevice_->consoleWidgetInput(code);
|
||||
|
||||
emit consoleCommand(code);
|
||||
}
|
||||
|
||||
void QConsoleWidget::handleTabKey() {
|
||||
QTextCursor tc = this->textCursor();
|
||||
int anchor = tc.anchor();
|
||||
int position = tc.position();
|
||||
tc.setPosition(inpos_);
|
||||
tc.setPosition(position, QTextCursor::KeepAnchor);
|
||||
QString text = tc.selectedText().trimmed();
|
||||
tc.setPosition(anchor, QTextCursor::MoveAnchor);
|
||||
tc.setPosition(position, QTextCursor::KeepAnchor);
|
||||
if (text.isEmpty()) {
|
||||
tc.insertText(" ");
|
||||
} else {
|
||||
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
|
||||
int count;
|
||||
if ((count = 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();
|
||||
|
||||
// check for user abort request
|
||||
if (e->modifiers() & Qt::ControlModifier) {
|
||||
if (e->key() == Qt::Key_Q) // Ctrl-Q aborts
|
||||
{
|
||||
emit abortEvaluation();
|
||||
e->accept();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Allow copying anywhere in the console ...
|
||||
if (e->key() == Qt::Key_C && e->modifiers() == Qt::ControlModifier) {
|
||||
if (textCursor.hasSelection())
|
||||
copy();
|
||||
e->accept();
|
||||
return;
|
||||
}
|
||||
|
||||
// the rest of key events are ignored during output mode
|
||||
if (mode() != Input) {
|
||||
e->ignore();
|
||||
return;
|
||||
}
|
||||
|
||||
// Allow cut only if the selection is limited to the interactive area ...
|
||||
if (e->key() == Qt::Key_X && e->modifiers() == Qt::ControlModifier) {
|
||||
if (selectionInEditZone)
|
||||
cut();
|
||||
e->accept();
|
||||
return;
|
||||
}
|
||||
|
||||
// Allow paste only if the selection is in the interactive area ...
|
||||
if (e->key() == Qt::Key_V && e->modifiers() == Qt::ControlModifier) {
|
||||
if (selectionInEditZone || isCursorInEditZone()) {
|
||||
const QMimeData *const clipboard =
|
||||
QApplication::clipboard()->mimeData();
|
||||
const QString text = clipboard->text();
|
||||
if (!text.isNull()) {
|
||||
textCursor.insertText(text, channelCharFormat(StandardInput));
|
||||
}
|
||||
}
|
||||
|
||||
e->accept();
|
||||
return;
|
||||
}
|
||||
|
||||
int key = e->key();
|
||||
int shiftMod = e->modifiers() == Qt::ShiftModifier;
|
||||
|
||||
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
|
||||
if (!isCursorInEditZone() && key != Qt::Key_Control &&
|
||||
key != Qt::Key_Shift && key != Qt::Key_Alt) {
|
||||
textCursor.movePosition(QTextCursor::End);
|
||||
setTextCursor(textCursor);
|
||||
}
|
||||
|
||||
switch (key) {
|
||||
case Qt::Key_Up:
|
||||
// Activate the history and move to the 1st matching history item
|
||||
if (!history_.isActive())
|
||||
history_.activate(getCommandLine());
|
||||
if (history_.move(true))
|
||||
replaceCommandLine(history_.currentValue());
|
||||
else
|
||||
QApplication::beep();
|
||||
e->accept();
|
||||
break;
|
||||
|
||||
case Qt::Key_Down:
|
||||
if (history_.move(false))
|
||||
replaceCommandLine(history_.currentValue());
|
||||
else
|
||||
QApplication::beep();
|
||||
e->accept();
|
||||
|
||||
case Qt::Key_Left:
|
||||
if (textCursor.position() > inpos_)
|
||||
QPlainTextEdit::keyPressEvent(e);
|
||||
else {
|
||||
QApplication::beep();
|
||||
e->accept();
|
||||
}
|
||||
break;
|
||||
|
||||
case Qt::Key_Delete:
|
||||
e->accept();
|
||||
if (selectionInEditZone)
|
||||
cut();
|
||||
else {
|
||||
// cursor must be in edit zone
|
||||
if (textCursor.position() < inpos_)
|
||||
QApplication::beep();
|
||||
else
|
||||
QPlainTextEdit::keyPressEvent(e);
|
||||
}
|
||||
break;
|
||||
|
||||
case Qt::Key_Backspace:
|
||||
e->accept();
|
||||
if (selectionInEditZone)
|
||||
cut();
|
||||
else {
|
||||
// cursor must be in edit zone
|
||||
if (textCursor.position() <= inpos_)
|
||||
QApplication::beep();
|
||||
else
|
||||
QPlainTextEdit::keyPressEvent(e);
|
||||
}
|
||||
break;
|
||||
|
||||
case Qt::Key_Tab:
|
||||
e->accept();
|
||||
handleTabKey();
|
||||
return;
|
||||
|
||||
case Qt::Key_Home:
|
||||
e->accept();
|
||||
textCursor.setPosition(inpos_, shiftMod ? QTextCursor::KeepAnchor
|
||||
: QTextCursor::MoveAnchor);
|
||||
setTextCursor(textCursor);
|
||||
break;
|
||||
|
||||
case Qt::Key_Enter:
|
||||
case Qt::Key_Return:
|
||||
e->accept();
|
||||
handleReturnKey();
|
||||
break;
|
||||
|
||||
case Qt::Key_Escape:
|
||||
e->accept();
|
||||
replaceCommandLine(QString());
|
||||
break;
|
||||
|
||||
default:
|
||||
e->accept();
|
||||
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) {
|
||||
QMenu *menu = createStandardContextMenu();
|
||||
|
||||
QAction *a;
|
||||
if ((a = menu->findChild<QAction *>("edit-cut")))
|
||||
a->setEnabled(canCut());
|
||||
if ((a = menu->findChild<QAction *>("edit-delete")))
|
||||
a->setEnabled(canCut());
|
||||
if ((a = menu->findChild<QAction *>("edit-paste")))
|
||||
a->setEnabled(canPaste());
|
||||
|
||||
menu->exec(event->globalPos());
|
||||
delete menu;
|
||||
}
|
||||
|
||||
bool QConsoleWidget::isSelectionInEditZone() const {
|
||||
QTextCursor textCursor = this->textCursor();
|
||||
if (!textCursor.hasSelection())
|
||||
return false;
|
||||
|
||||
int selectionStart = textCursor.selectionStart();
|
||||
int selectionEnd = textCursor.selectionEnd();
|
||||
|
||||
return selectionStart >= inpos_ && selectionEnd >= inpos_;
|
||||
}
|
||||
|
||||
bool QConsoleWidget::isCursorInEditZone() const {
|
||||
return textCursor().position() >= inpos_;
|
||||
}
|
||||
|
||||
bool QConsoleWidget::canPaste() const {
|
||||
QTextCursor textCursor = this->textCursor();
|
||||
if (textCursor.position() < inpos_)
|
||||
return false;
|
||||
if (textCursor.anchor() < inpos_)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void QConsoleWidget::replaceCommandLine(const QString &str) {
|
||||
|
||||
// Select the text after the last command prompt ...
|
||||
QTextCursor textCursor = this->textCursor();
|
||||
textCursor.movePosition(QTextCursor::End);
|
||||
textCursor.setPosition(inpos_, QTextCursor::KeepAnchor);
|
||||
|
||||
// ... and replace it with new string.
|
||||
textCursor.insertText(str, chanFormat_[StandardInput]);
|
||||
|
||||
// move to the end of the document
|
||||
textCursor.movePosition(QTextCursor::End);
|
||||
setTextCursor(textCursor);
|
||||
}
|
||||
|
||||
QString QConsoleWidget::getHistoryPath() {
|
||||
QDir dir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) +
|
||||
QDir::separator() + APP_NAME);
|
||||
return dir.absoluteFilePath(QStringLiteral(".command_history.lst"));
|
||||
}
|
||||
|
||||
void QConsoleWidget::write(const QString &message, const QTextCharFormat &fmt) {
|
||||
QTextCharFormat currfmt = currentCharFormat();
|
||||
QTextCursor tc = textCursor();
|
||||
|
||||
if (mode() == Input) {
|
||||
// in Input mode output messages are inserted
|
||||
// before the edit block
|
||||
|
||||
// get offset of current pos from the end
|
||||
int editpos = tc.position();
|
||||
tc.movePosition(QTextCursor::End);
|
||||
editpos = tc.position() - editpos;
|
||||
|
||||
// convert the input pos as relative from the end
|
||||
inpos_ = tc.position() - inpos_;
|
||||
|
||||
// insert block
|
||||
tc.movePosition(QTextCursor::StartOfBlock);
|
||||
tc.insertBlock();
|
||||
tc.movePosition(QTextCursor::PreviousBlock);
|
||||
|
||||
tc.insertText(message, fmt);
|
||||
tc.movePosition(QTextCursor::End);
|
||||
// restore input pos
|
||||
inpos_ = tc.position() - inpos_;
|
||||
// restore the edit pos
|
||||
tc.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, editpos);
|
||||
setTextCursor(tc);
|
||||
setCurrentCharFormat(currfmt);
|
||||
} else {
|
||||
// in output mode messages are appended
|
||||
QTextCursor tc1 = tc;
|
||||
tc1.movePosition(QTextCursor::End);
|
||||
|
||||
// check is cursor was not at the end
|
||||
// (e.g. had been moved per mouse action)
|
||||
bool needsRestore = tc1.position() != tc.position();
|
||||
|
||||
// insert text
|
||||
setTextCursor(tc1);
|
||||
textCursor().insertText(message, fmt);
|
||||
ensureCursorVisible();
|
||||
|
||||
// restore cursor if needed
|
||||
if (needsRestore)
|
||||
setTextCursor(tc);
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
QFile f(QConsoleWidget::getHistoryPath());
|
||||
if (f.open(QFile::ReadOnly)) {
|
||||
QTextStream is(&f);
|
||||
while (!is.atEnd())
|
||||
add(is.readLine());
|
||||
}
|
||||
}
|
||||
QConsoleWidget::History::~History(void) {
|
||||
QFile f(QConsoleWidget::getHistoryPath());
|
||||
if (f.open(QFile::WriteOnly | QFile::Truncate)) {
|
||||
QTextStream os(&f);
|
||||
int n = strings_.size();
|
||||
while (n > 0)
|
||||
os << strings_.at(--n) << Qt::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void QConsoleWidget::History::add(const QString &str) {
|
||||
active_ = false;
|
||||
// if (strings_.contains(str)) return;
|
||||
if (strings_.size() == maxsize_)
|
||||
strings_.pop_back();
|
||||
strings_.push_front(str);
|
||||
}
|
||||
|
||||
void QConsoleWidget::History::activate(const QString &tk) {
|
||||
active_ = true;
|
||||
token_ = tk;
|
||||
pos_ = -1;
|
||||
}
|
||||
|
||||
bool QConsoleWidget::History::move(bool dir) {
|
||||
if (active_) {
|
||||
int next = indexOf(dir, pos_);
|
||||
if (pos_ != next) {
|
||||
pos_ = next;
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
int QConsoleWidget::History::indexOf(bool dir, int from) const {
|
||||
int i = from, to = from;
|
||||
if (dir) {
|
||||
while (i < strings_.size() - 1) {
|
||||
const QString &si = strings_.at(++i);
|
||||
if (si.startsWith(token_)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while (i > 0) {
|
||||
const QString &si = strings_.at(--i);
|
||||
if (si.startsWith(token_)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
return to;
|
||||
}
|
||||
|
||||
/////////////////// Stream manipulators /////////////////////
|
||||
|
||||
QTextStream &waitForInput(QTextStream &s) {
|
||||
QConsoleIODevice *d = qobject_cast<QConsoleIODevice *>(s.device());
|
||||
if (d)
|
||||
d->waitForReadyRead(-1);
|
||||
return s;
|
||||
}
|
||||
|
||||
QTextStream &inputMode(QTextStream &s) {
|
||||
QConsoleIODevice *d = qobject_cast<QConsoleIODevice *>(s.device());
|
||||
if (d && d->widget())
|
||||
d->widget()->setMode(QConsoleWidget::Input);
|
||||
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,9 +0,0 @@
|
|||
INCLUDEPATH += $$PWD
|
||||
DEPENDPATH += $$PWD
|
||||
|
||||
|
||||
SOURCES += $$PWD/QConsoleWidget.cpp \
|
||||
$$PWD/QConsoleIODevice.cpp
|
||||
|
||||
HEADERS += $$PWD/QConsoleWidget.h \
|
||||
$$PWD/QConsoleIODevice.h
|
|
@ -75,7 +75,7 @@ add_library(
|
|||
set_target_properties(
|
||||
QHexView
|
||||
PROPERTIES AUTOMOC ON
|
||||
CXX_STANDARD 11
|
||||
CXX_STANDARD 17
|
||||
CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
target_link_libraries(QHexView PRIVATE Qt${QT_VERSION_MAJOR}::Widgets
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include "bookmarkclearcommand.h"
|
||||
|
||||
BookMarkClearCommand::BookMarkClearCommand(QHexDocument *doc,
|
||||
QList<BookMarkStruct> bookmarks,
|
||||
QUndoCommand *parent)
|
||||
BookMarkClearCommand::BookMarkClearCommand(
|
||||
QHexDocument *doc, const QMap<qsizetype, QString> &bookmarks,
|
||||
QUndoCommand *parent)
|
||||
: QUndoCommand(parent), m_doc(doc), m_bookmarks(bookmarks) {}
|
||||
|
||||
void BookMarkClearCommand::redo() { m_doc->clearBookMark(); }
|
||||
|
|
|
@ -2,12 +2,14 @@
|
|||
#define BOOKMARKCLEARCOMMAND_H
|
||||
|
||||
#include "document/qhexdocument.h"
|
||||
#include <QMap>
|
||||
#include <QObject>
|
||||
#include <QUndoCommand>
|
||||
|
||||
class BookMarkClearCommand : public QUndoCommand {
|
||||
public:
|
||||
BookMarkClearCommand(QHexDocument *doc, QList<BookMarkStruct> bookmarks,
|
||||
BookMarkClearCommand(QHexDocument *doc,
|
||||
const QMap<qsizetype, QString> &bookmarks,
|
||||
QUndoCommand *parent = nullptr);
|
||||
|
||||
void undo() override;
|
||||
|
@ -15,7 +17,7 @@ public:
|
|||
|
||||
protected:
|
||||
QHexDocument *m_doc;
|
||||
QList<BookMarkStruct> m_bookmarks;
|
||||
QMap<qsizetype, QString> m_bookmarks;
|
||||
};
|
||||
|
||||
#endif // BOOKMARKCLEARCOMMAND_H
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "metaaddcommand.h"
|
||||
|
||||
MetaAddCommand::MetaAddCommand(QHexMetadata *hexmeta,
|
||||
QHexMetadataAbsoluteItem &meta,
|
||||
const QHexMetadataItem &meta,
|
||||
QUndoCommand *parent)
|
||||
: MetaCommand(hexmeta, meta, parent) {}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
class MetaAddCommand : public MetaCommand {
|
||||
public:
|
||||
MetaAddCommand(QHexMetadata *hexmeta, QHexMetadataAbsoluteItem &meta,
|
||||
MetaAddCommand(QHexMetadata *hexmeta, const QHexMetadataItem &meta,
|
||||
QUndoCommand *parent = nullptr);
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "metaclearcommand.h"
|
||||
|
||||
MetaClearCommand::MetaClearCommand(QHexMetadata *hexmeta,
|
||||
QList<QHexMetadataAbsoluteItem> metas,
|
||||
const QVector<QHexMetadataItem> &metas,
|
||||
QUndoCommand *parent)
|
||||
: QUndoCommand(parent), m_hexmeta(hexmeta), m_metas(metas) {}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
class MetaClearCommand : public QUndoCommand {
|
||||
public:
|
||||
MetaClearCommand(QHexMetadata *hexmeta,
|
||||
QList<QHexMetadataAbsoluteItem> metas,
|
||||
const QVector<QHexMetadataItem> &metas,
|
||||
QUndoCommand *parent = nullptr);
|
||||
|
||||
void undo() override;
|
||||
|
@ -20,7 +20,7 @@ public:
|
|||
|
||||
protected:
|
||||
QHexMetadata *m_hexmeta;
|
||||
QList<QHexMetadataAbsoluteItem> m_metas;
|
||||
QVector<QHexMetadataItem> m_metas;
|
||||
};
|
||||
|
||||
#endif // METACLEARCOMMAND_H
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "metacommand.h"
|
||||
|
||||
MetaCommand::MetaCommand(QHexMetadata *hexmeta, QHexMetadataAbsoluteItem &meta,
|
||||
MetaCommand::MetaCommand(QHexMetadata *hexmeta, const QHexMetadataItem &meta,
|
||||
QUndoCommand *parent)
|
||||
: QUndoCommand(parent), m_hexmeta(hexmeta), m_meta(meta) {}
|
||||
|
|
|
@ -10,12 +10,12 @@
|
|||
|
||||
class MetaCommand : public QUndoCommand {
|
||||
public:
|
||||
MetaCommand(QHexMetadata *hexmeta, QHexMetadataAbsoluteItem &meta,
|
||||
MetaCommand(QHexMetadata *hexmeta, const QHexMetadataItem &meta,
|
||||
QUndoCommand *parent = nullptr);
|
||||
|
||||
protected:
|
||||
QHexMetadata *m_hexmeta;
|
||||
QHexMetadataAbsoluteItem m_meta;
|
||||
QHexMetadataItem m_meta;
|
||||
};
|
||||
|
||||
#endif // METACOMMAND_H
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "metaremovecommand.h"
|
||||
|
||||
MetaRemoveCommand::MetaRemoveCommand(QHexMetadata *hexmeta,
|
||||
QHexMetadataAbsoluteItem &meta,
|
||||
const QHexMetadataItem &meta,
|
||||
QUndoCommand *parent)
|
||||
: MetaCommand(hexmeta, meta, parent) {}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
class MetaRemoveCommand : public MetaCommand {
|
||||
public:
|
||||
MetaRemoveCommand(QHexMetadata *hexmeta, QHexMetadataAbsoluteItem &meta,
|
||||
MetaRemoveCommand(QHexMetadata *hexmeta, const QHexMetadataItem &meta,
|
||||
QUndoCommand *parent = nullptr);
|
||||
|
||||
void undo() override;
|
||||
|
|
|
@ -9,7 +9,7 @@ MetaRemovePosCommand::MetaRemovePosCommand(QHexMetadata *hexmeta, qsizetype pos,
|
|||
void MetaRemovePosCommand::redo() { m_hexmeta->removeMetadata(m_pos); }
|
||||
|
||||
void MetaRemovePosCommand::undo() {
|
||||
for (auto item : olditems)
|
||||
for (auto &item : olditems)
|
||||
m_hexmeta->metadata(item.begin, item.end, item.foreground,
|
||||
item.background, item.comment);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ public:
|
|||
protected:
|
||||
QHexMetadata *m_hexmeta;
|
||||
qsizetype m_pos;
|
||||
QList<QHexMetadataAbsoluteItem> olditems;
|
||||
QVector<QHexMetadataItem> olditems;
|
||||
};
|
||||
|
||||
#endif // METAREMOVEPOSCOMMAND_H
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include "metareplacecommand.h"
|
||||
|
||||
MetaReplaceCommand::MetaReplaceCommand(QHexMetadata *hexmeta,
|
||||
QHexMetadataAbsoluteItem &meta,
|
||||
QHexMetadataAbsoluteItem &oldmeta,
|
||||
const QHexMetadataItem &meta,
|
||||
const QHexMetadataItem &oldmeta,
|
||||
QUndoCommand *parent)
|
||||
: MetaCommand(hexmeta, meta, parent), m_old(oldmeta) {}
|
||||
|
||||
|
|
|
@ -6,14 +6,14 @@
|
|||
|
||||
class MetaReplaceCommand : public MetaCommand {
|
||||
public:
|
||||
MetaReplaceCommand(QHexMetadata *hexmeta, QHexMetadataAbsoluteItem &meta,
|
||||
QHexMetadataAbsoluteItem &oldmeta,
|
||||
MetaReplaceCommand(QHexMetadata *hexmeta, const QHexMetadataItem &meta,
|
||||
const QHexMetadataItem &oldmeta,
|
||||
QUndoCommand *parent = nullptr);
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
|
||||
private:
|
||||
QHexMetadataAbsoluteItem m_old;
|
||||
QHexMetadataItem m_old;
|
||||
};
|
||||
|
||||
#endif // METAREPLACECOMMAND_H
|
||||
|
|
|
@ -23,25 +23,29 @@
|
|||
/*======================*/
|
||||
// added by wingsummer
|
||||
|
||||
QList<qsizetype> QHexDocument::getsBookmarkPos(qsizetype line) {
|
||||
QList<qsizetype> QHexDocument::getLineBookmarksPos(qsizetype line) {
|
||||
QList<qsizetype> pos;
|
||||
auto begin = m_hexlinewidth * line;
|
||||
auto end = m_hexlinewidth + begin;
|
||||
for (auto item : bookmarks) {
|
||||
if (item.pos >= begin && item.pos <= end)
|
||||
pos.push_back(item.pos);
|
||||
|
||||
auto lbound = _bookmarks.lowerBound(begin);
|
||||
auto ubound = _bookmarks.upperBound(end);
|
||||
|
||||
for (auto p = lbound; p != ubound; ++p) {
|
||||
pos.append(p.key());
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
bool QHexDocument::lineHasBookMark(qsizetype line) {
|
||||
auto begin = m_hexlinewidth * line;
|
||||
auto end = m_hexlinewidth + begin;
|
||||
for (auto item : bookmarks) {
|
||||
if (item.pos >= begin && item.pos <= end)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
auto lbound = _bookmarks.lowerBound(begin);
|
||||
auto ubound = _bookmarks.upperBound(end);
|
||||
|
||||
return lbound != ubound;
|
||||
}
|
||||
|
||||
void QHexDocument::addUndoCommand(QUndoCommand *command) {
|
||||
|
@ -89,11 +93,13 @@ bool QHexDocument::metafgVisible() { return m_metafg; }
|
|||
|
||||
bool QHexDocument::metaCommentVisible() { return m_metacomment; }
|
||||
|
||||
bool QHexDocument::isDocSaved() { return m_undostack->isClean(); }
|
||||
bool QHexDocument::isDocSaved() { return m_isSaved; }
|
||||
|
||||
void QHexDocument::setDocSaved(bool b) {
|
||||
if (b) {
|
||||
m_undostack->setClean();
|
||||
}
|
||||
m_isSaved = b;
|
||||
emit documentSaved(b);
|
||||
}
|
||||
|
||||
|
@ -117,10 +123,8 @@ bool QHexDocument::setKeepSize(bool b) {
|
|||
return true;
|
||||
}
|
||||
|
||||
QList<BookMarkStruct> *QHexDocument::bookMarksPtr() { return &bookmarks; }
|
||||
|
||||
const QList<BookMarkStruct> &QHexDocument::bookMarks() const {
|
||||
return bookmarks;
|
||||
const QMap<qsizetype, QString> &QHexDocument::bookMarks() const {
|
||||
return _bookmarks;
|
||||
}
|
||||
|
||||
bool QHexDocument::AddBookMark(qsizetype pos, QString comment) {
|
||||
|
@ -130,25 +134,29 @@ bool QHexDocument::AddBookMark(qsizetype pos, QString comment) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool QHexDocument::RemoveBookMark(qsizetype pos) {
|
||||
m_undostack->push(new BookMarkRemoveCommand(this, pos, bookMark(pos)));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QHexDocument::ModBookMark(qsizetype pos, QString comment) {
|
||||
if (!m_keepsize)
|
||||
return false;
|
||||
m_undostack->push(
|
||||
new BookMarkReplaceCommand(this, pos, comment, bookMarkComment(pos)));
|
||||
new BookMarkReplaceCommand(this, pos, comment, bookMark(pos)));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QHexDocument::ClearBookMark() {
|
||||
if (!m_keepsize)
|
||||
return false;
|
||||
m_undostack->push(new BookMarkClearCommand(this, getAllBookMarks()));
|
||||
m_undostack->push(new BookMarkClearCommand(this, _bookmarks));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QHexDocument::addBookMark(qsizetype pos, QString comment) {
|
||||
if (m_keepsize && !existBookMark(pos)) {
|
||||
BookMarkStruct b{pos, comment};
|
||||
bookmarks.append(b);
|
||||
_bookmarks.insert(pos, comment);
|
||||
setDocSaved(false);
|
||||
emit documentChanged();
|
||||
emit bookMarkChanged();
|
||||
|
@ -157,97 +165,46 @@ bool QHexDocument::addBookMark(qsizetype pos, QString comment) {
|
|||
return false;
|
||||
}
|
||||
|
||||
QString QHexDocument::bookMarkComment(qsizetype pos) {
|
||||
if (pos > 0 && pos < m_buffer->length()) {
|
||||
for (auto item : bookmarks) {
|
||||
if (item.pos == pos) {
|
||||
return item.comment;
|
||||
}
|
||||
}
|
||||
}
|
||||
return QString();
|
||||
QString QHexDocument::bookMark(qsizetype pos) { return _bookmarks.value(pos); }
|
||||
|
||||
bool QHexDocument::bookMarkExists(qsizetype pos) {
|
||||
return _bookmarks.contains(pos);
|
||||
}
|
||||
|
||||
BookMarkStruct QHexDocument::bookMark(qsizetype pos) {
|
||||
if (pos > 0 && pos < m_buffer->length()) {
|
||||
for (auto item : bookmarks) {
|
||||
if (item.pos == pos) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
return BookMarkStruct{-1, ""};
|
||||
qsizetype QHexDocument::bookMarkPos(qsizetype index) {
|
||||
Q_ASSERT(index >= 0 && index < _bookmarks.size());
|
||||
return *(std::next(_bookmarks.keyBegin(), index));
|
||||
}
|
||||
|
||||
BookMarkStruct QHexDocument::bookMarkByIndex(qsizetype index) {
|
||||
if (index >= 0 && index < bookmarks.count()) {
|
||||
return bookmarks.at(index);
|
||||
} else {
|
||||
BookMarkStruct b;
|
||||
b.pos = -1;
|
||||
return b;
|
||||
}
|
||||
}
|
||||
|
||||
bool QHexDocument::RemoveBookMarks(QList<qsizetype> &pos) {
|
||||
bool QHexDocument::RemoveBookMarks(const QList<qsizetype> &pos) {
|
||||
if (!m_keepsize)
|
||||
return false;
|
||||
m_undostack->beginMacro("RemoveBookMarks");
|
||||
for (auto p : pos) {
|
||||
m_undostack->push(
|
||||
new BookMarkRemoveCommand(this, p, bookMarkComment(p)));
|
||||
m_undostack->push(new BookMarkRemoveCommand(this, p, bookMark(p)));
|
||||
}
|
||||
m_undostack->endMacro();
|
||||
emit documentChanged();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QHexDocument::RemoveBookMark(qsizetype index) {
|
||||
if (!m_keepsize)
|
||||
return false;
|
||||
auto b = bookmarks.at(index);
|
||||
m_undostack->push(new BookMarkRemoveCommand(this, b.pos, b.comment));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QHexDocument::removeBookMark(qsizetype pos) {
|
||||
if (m_keepsize && pos >= 0 && pos < m_buffer->length()) {
|
||||
int index = 0;
|
||||
for (auto item : bookmarks) {
|
||||
if (pos == item.pos) {
|
||||
bookmarks.removeAt(index);
|
||||
setDocSaved(false);
|
||||
emit documentChanged();
|
||||
emit bookMarkChanged();
|
||||
break;
|
||||
}
|
||||
index++;
|
||||
if (m_keepsize) {
|
||||
auto ret = _bookmarks.remove(pos) != 0;
|
||||
if (ret) {
|
||||
setDocSaved(false);
|
||||
}
|
||||
return true;
|
||||
return ret;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QHexDocument::removeBookMarkByIndex(qsizetype index) {
|
||||
if (m_keepsize && index >= 0 && index < bookmarks.count()) {
|
||||
bookmarks.removeAt(index);
|
||||
setDocSaved(false);
|
||||
emit documentChanged();
|
||||
emit bookMarkChanged();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QHexDocument::modBookMark(qsizetype pos, QString comment) {
|
||||
if (m_keepsize && pos > 0 && pos < m_buffer->length()) {
|
||||
for (auto &item : bookmarks) {
|
||||
if (item.pos == pos) {
|
||||
item.comment = comment;
|
||||
setDocSaved(false);
|
||||
emit bookMarkChanged();
|
||||
return true;
|
||||
}
|
||||
bool QHexDocument::modBookMark(qsizetype pos, const QString &comment) {
|
||||
if (m_keepsize) {
|
||||
if (_bookmarks.contains(pos)) {
|
||||
_bookmarks[pos] = comment;
|
||||
setDocSaved(false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -255,7 +212,7 @@ bool QHexDocument::modBookMark(qsizetype pos, QString comment) {
|
|||
|
||||
bool QHexDocument::clearBookMark() {
|
||||
if (m_keepsize) {
|
||||
bookmarks.clear();
|
||||
_bookmarks.clear();
|
||||
setDocSaved(false);
|
||||
emit documentChanged();
|
||||
emit bookMarkChanged();
|
||||
|
@ -265,22 +222,13 @@ bool QHexDocument::clearBookMark() {
|
|||
}
|
||||
|
||||
bool QHexDocument::existBookMark(qsizetype pos) {
|
||||
for (auto item : bookmarks) {
|
||||
if (item.pos == pos) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return _bookmarks.contains(pos);
|
||||
}
|
||||
|
||||
const QList<BookMarkStruct> &QHexDocument::getAllBookMarks() {
|
||||
return bookmarks;
|
||||
}
|
||||
qsizetype QHexDocument::bookMarksCount() const { return _bookmarks.count(); }
|
||||
|
||||
qsizetype QHexDocument::bookMarksCount() const { return bookmarks.count(); }
|
||||
|
||||
void QHexDocument::applyBookMarks(const QList<BookMarkStruct> &books) {
|
||||
bookmarks.append(books);
|
||||
void QHexDocument::applyBookMarks(const QMap<qsizetype, QString> &books) {
|
||||
_bookmarks = books;
|
||||
setDocSaved(false);
|
||||
emit documentChanged();
|
||||
}
|
||||
|
@ -391,8 +339,10 @@ QHexDocument::QHexDocument(QHexBuffer *buffer, bool readonly)
|
|||
m_metadata = new QHexMetadata(m_undostack, this);
|
||||
m_metadata->setLineWidth(m_hexlinewidth);
|
||||
|
||||
connect(m_metadata, &QHexMetadata::metadataChanged, this,
|
||||
&QHexDocument::metaDataChanged);
|
||||
connect(m_metadata, &QHexMetadata::metadataChanged, this, [this] {
|
||||
setDocSaved(false);
|
||||
emit metaDataChanged();
|
||||
});
|
||||
|
||||
/*=======================*/
|
||||
// added by wingsummer
|
||||
|
@ -424,9 +374,6 @@ void QHexDocument::setHexLineWidth(quint8 value) {
|
|||
}
|
||||
|
||||
QHexMetadata *QHexDocument::metadata() const { return m_metadata; }
|
||||
QByteArray QHexDocument::read(qsizetype offset, qsizetype len) {
|
||||
return m_buffer->read(offset, len);
|
||||
}
|
||||
|
||||
char QHexDocument::at(qsizetype offset) const {
|
||||
return char(m_buffer->at(offset));
|
||||
|
|
|
@ -9,16 +9,6 @@
|
|||
#include <QStorageInfo>
|
||||
#include <QUndoStack>
|
||||
|
||||
/*=========================*/
|
||||
// added by wingsummer
|
||||
|
||||
struct BookMarkStruct {
|
||||
qsizetype pos;
|
||||
QString comment;
|
||||
};
|
||||
|
||||
/*=========================*/
|
||||
|
||||
class QHexDocument : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -44,7 +34,7 @@ public:
|
|||
|
||||
void addUndoCommand(QUndoCommand *command);
|
||||
bool lineHasBookMark(qsizetype line);
|
||||
QList<qsizetype> getsBookmarkPos(qsizetype line);
|
||||
QList<qsizetype> getLineBookmarksPos(qsizetype line);
|
||||
|
||||
bool setLockedFile(bool b);
|
||||
bool setKeepSize(bool b);
|
||||
|
@ -54,28 +44,27 @@ public:
|
|||
|
||||
//----------------------------------
|
||||
bool AddBookMark(qsizetype pos, QString comment);
|
||||
bool RemoveBookMark(qsizetype index);
|
||||
bool RemoveBookMarks(QList<qsizetype> &pos);
|
||||
bool RemoveBookMark(qsizetype pos);
|
||||
bool RemoveBookMarks(const QList<qsizetype> &pos);
|
||||
bool ModBookMark(qsizetype pos, QString comment);
|
||||
bool ClearBookMark();
|
||||
//----------------------------------
|
||||
|
||||
bool addBookMark(qsizetype pos, QString comment);
|
||||
bool modBookMark(qsizetype pos, QString comment);
|
||||
bool modBookMark(qsizetype pos, const QString &comment);
|
||||
|
||||
BookMarkStruct bookMarkByIndex(qsizetype index);
|
||||
BookMarkStruct bookMark(qsizetype pos);
|
||||
QString bookMark(qsizetype pos);
|
||||
bool bookMarkExists(qsizetype pos);
|
||||
|
||||
// note: maybe changed when bookmarks are chaged
|
||||
qsizetype bookMarkPos(qsizetype index);
|
||||
|
||||
QString bookMarkComment(qsizetype pos);
|
||||
const QList<BookMarkStruct> &getAllBookMarks();
|
||||
qsizetype bookMarksCount() const;
|
||||
void applyBookMarks(const QList<BookMarkStruct> &books);
|
||||
bool removeBookMarkByIndex(qsizetype index);
|
||||
void applyBookMarks(const QMap<qsizetype, QString> &books);
|
||||
bool removeBookMark(qsizetype pos);
|
||||
bool clearBookMark();
|
||||
|
||||
QList<BookMarkStruct> *bookMarksPtr();
|
||||
const QList<BookMarkStruct> &bookMarks() const;
|
||||
const QMap<qsizetype, QString> &bookMarks() const;
|
||||
|
||||
bool existBookMark(qsizetype pos);
|
||||
|
||||
|
@ -101,7 +90,7 @@ public:
|
|||
/*======================*/
|
||||
|
||||
public:
|
||||
QByteArray read(qsizetype offset, qsizetype len = -1);
|
||||
QByteArray read(qsizetype offset, qsizetype len = -1) const;
|
||||
|
||||
char at(qsizetype offset) const;
|
||||
void SetBaseAddress(quintptr baseaddress);
|
||||
|
@ -122,7 +111,6 @@ public slots:
|
|||
bool Remove(QHexCursor *cursor, qsizetype offset, qsizetype len,
|
||||
int nibbleindex = 0);
|
||||
|
||||
QByteArray read(qsizetype offset, qsizetype len) const;
|
||||
bool saveTo(QIODevice *device, bool cleanUndo);
|
||||
|
||||
// qsizetype searchForward(const QByteArray &ba);
|
||||
|
@ -202,10 +190,12 @@ private:
|
|||
/*======================*/
|
||||
// added by wingsummer
|
||||
|
||||
bool m_isSaved = true;
|
||||
|
||||
bool m_readonly;
|
||||
bool m_keepsize;
|
||||
bool m_islocked;
|
||||
QList<BookMarkStruct> bookmarks;
|
||||
QMap<qsizetype, QString> _bookmarks;
|
||||
|
||||
bool m_metafg = true;
|
||||
bool m_metabg = true;
|
||||
|
|
|
@ -5,12 +5,22 @@
|
|||
#include "commands/meta/metaremoveposcommand.h"
|
||||
#include "commands/meta/metareplacecommand.h"
|
||||
|
||||
#include <QtAlgorithms>
|
||||
|
||||
QHexMetadata::QHexMetadata(QUndoStack *undo, QObject *parent)
|
||||
: QObject(parent), m_undo(undo) {}
|
||||
|
||||
const QHexLineMetadata &QHexMetadata::get(qsizetype line) const {
|
||||
auto it = m_metadata.find(line);
|
||||
return it.value();
|
||||
QHexLineMetadata QHexMetadata::get(qsizetype line) const {
|
||||
if (!m_linemeta.contains(line)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
QHexLineMetadata ret;
|
||||
for (auto &item : m_linemeta[line]) {
|
||||
ret.append(item);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*==================================*/
|
||||
|
@ -18,13 +28,12 @@ const QHexLineMetadata &QHexMetadata::get(qsizetype line) const {
|
|||
|
||||
//----------undo redo wrapper----------
|
||||
|
||||
void QHexMetadata::ModifyMetadata(QHexMetadataAbsoluteItem newmeta,
|
||||
QHexMetadataAbsoluteItem oldmeta) {
|
||||
void QHexMetadata::ModifyMetadata(QHexMetadataItem newmeta,
|
||||
QHexMetadataItem oldmeta) {
|
||||
m_undo->push(new MetaReplaceCommand(this, newmeta, oldmeta));
|
||||
}
|
||||
|
||||
void QHexMetadata::RemoveMetadatas(
|
||||
const QList<QHexMetadataAbsoluteItem> &items) {
|
||||
void QHexMetadata::RemoveMetadatas(const QList<QHexMetadataItem> &items) {
|
||||
m_undo->beginMacro("RemoveMetadatas");
|
||||
for (auto &item : items) {
|
||||
RemoveMetadata(item);
|
||||
|
@ -32,7 +41,7 @@ void QHexMetadata::RemoveMetadatas(
|
|||
m_undo->endMacro();
|
||||
}
|
||||
|
||||
void QHexMetadata::RemoveMetadata(QHexMetadataAbsoluteItem item) {
|
||||
void QHexMetadata::RemoveMetadata(QHexMetadataItem item) {
|
||||
m_undo->push(new MetaRemoveCommand(this, item));
|
||||
}
|
||||
|
||||
|
@ -43,81 +52,103 @@ void QHexMetadata::RemoveMetadata(qsizetype offset) {
|
|||
void QHexMetadata::Metadata(qsizetype begin, qsizetype end,
|
||||
const QColor &fgcolor, const QColor &bgcolor,
|
||||
const QString &comment) {
|
||||
QHexMetadataAbsoluteItem absi{begin, end, fgcolor, bgcolor, comment};
|
||||
QHexMetadataItem absi{begin, end, fgcolor, bgcolor, comment};
|
||||
m_undo->push(new MetaAddCommand(this, absi));
|
||||
}
|
||||
|
||||
void QHexMetadata::Clear() {
|
||||
m_undo->push(new MetaClearCommand(this, getallMetas()));
|
||||
m_undo->push(new MetaClearCommand(this, this->getAllMetadata()));
|
||||
}
|
||||
|
||||
//-------- the real function-----------
|
||||
void QHexMetadata::undo() { m_undo->undo(); }
|
||||
void QHexMetadata::redo() { m_undo->redo(); }
|
||||
bool QHexMetadata::canUndo() { return m_undo->canUndo(); }
|
||||
bool QHexMetadata::canRedo() { return m_undo->canRedo(); }
|
||||
|
||||
QList<QHexMetadataAbsoluteItem> QHexMetadata::getallMetas() {
|
||||
return m_absoluteMetadata;
|
||||
bool QHexMetadata::modifyMetadata(const QHexMetadataItem &newmeta,
|
||||
const QHexMetadataItem &oldmeta) {
|
||||
if (removeMetadata(oldmeta)) {
|
||||
metadata(newmeta.begin, newmeta.end, newmeta.foreground,
|
||||
newmeta.background, newmeta.comment);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const QList<QHexMetadataAbsoluteItem> &QHexMetadata::getallMetasPtr() {
|
||||
return m_absoluteMetadata;
|
||||
}
|
||||
|
||||
void QHexMetadata::modifyMetadata(QHexMetadataAbsoluteItem newmeta,
|
||||
QHexMetadataAbsoluteItem oldmeta) {
|
||||
removeMetadata(oldmeta);
|
||||
metadata(newmeta.begin, newmeta.end, newmeta.foreground, newmeta.background,
|
||||
newmeta.comment);
|
||||
}
|
||||
|
||||
void QHexMetadata::removeMetadata(QHexMetadataAbsoluteItem item) {
|
||||
auto firstRow = item.begin / m_lineWidth;
|
||||
auto lastRow = item.end / m_lineWidth;
|
||||
|
||||
for (auto i = firstRow; i <= lastRow; i++) {
|
||||
QList<QHexMetadataItem> delmeta;
|
||||
auto it = m_metadata.find(i);
|
||||
if (it != m_metadata.end()) {
|
||||
for (auto iitem : *it) {
|
||||
if (iitem.foreground == item.foreground &&
|
||||
iitem.background == item.background &&
|
||||
iitem.comment == item.comment) {
|
||||
delmeta.push_back(iitem);
|
||||
}
|
||||
}
|
||||
for (auto iitem : delmeta) {
|
||||
it->remove(iitem);
|
||||
}
|
||||
m_absoluteMetadata.removeOne(item);
|
||||
}
|
||||
bool QHexMetadata::removeMetadata(const QHexMetadataItem &item) {
|
||||
auto index = m_metadata.indexOf(item);
|
||||
if (index < 0) {
|
||||
return false;
|
||||
}
|
||||
m_metadata.removeAt(index);
|
||||
for (auto &l : m_linemeta) {
|
||||
l.remove(item);
|
||||
}
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
m_linemeta.erase(std::remove_if(
|
||||
m_linemeta.begin(), m_linemeta.end(),
|
||||
[](const QHash<QHexMetadataItem, QHexLineMetadata> &item) {
|
||||
return item.isEmpty();
|
||||
}));
|
||||
#else
|
||||
m_linemeta.removeIf(
|
||||
[](const QPair<qsizetype, QHash<QHexMetadataItem, QHexLineMetadata>>
|
||||
&item) { return item.second.isEmpty(); });
|
||||
#endif
|
||||
|
||||
emit metadataChanged();
|
||||
return true;
|
||||
}
|
||||
|
||||
void QHexMetadata::removeMetadata(qsizetype offset) {
|
||||
QList<QHexMetadataAbsoluteItem> delneeded;
|
||||
for (auto item : m_absoluteMetadata) {
|
||||
if (offset >= item.begin && offset <= item.end) {
|
||||
removeMetadata(item);
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
m_metadata.erase(
|
||||
std::remove_if(m_metadata.begin(), m_metadata.end(),
|
||||
[offset, this](const QHexMetadataItem &item) {
|
||||
auto r = offset >= item.begin && offset <= item.end;
|
||||
if (r) {
|
||||
for (auto &l : m_linemeta) {
|
||||
l.remove(item);
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}));
|
||||
#else
|
||||
m_metadata.removeIf([offset, this](const QHexMetadataItem &item) {
|
||||
auto r = offset >= item.begin && offset <= item.end;
|
||||
if (r) {
|
||||
for (auto &l : m_linemeta) {
|
||||
l.remove(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
return r;
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
QList<QHexMetadataAbsoluteItem> QHexMetadata::gets(qsizetype offset) {
|
||||
return m_absoluteMetadata;
|
||||
QVector<QHexMetadataItem> QHexMetadata::getAllMetadata() const {
|
||||
return m_metadata;
|
||||
}
|
||||
|
||||
void QHexMetadata::applyMetas(QList<QHexMetadataAbsoluteItem> metas) {
|
||||
for (auto item : metas) {
|
||||
metadata(item.begin, item.end, item.foreground, item.background,
|
||||
item.comment);
|
||||
}
|
||||
QVector<QHexMetadataItem> QHexMetadata::gets(qsizetype offset) {
|
||||
QVector<QHexMetadataItem> ret;
|
||||
|
||||
std::copy_if(
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
m_metadata.begin(), m_metadata.end(),
|
||||
#else
|
||||
m_metadata.constBegin(), m_metadata.constEnd(),
|
||||
#endif
|
||||
std::back_inserter(ret), [offset](const QHexMetadataItem &item) {
|
||||
return offset >= item.begin && offset <= item.end;
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool QHexMetadata::hasMetadata() { return m_absoluteMetadata.count() > 0; }
|
||||
void QHexMetadata::applyMetas(const QVector<QHexMetadataItem> &metas) {
|
||||
m_metadata = metas;
|
||||
}
|
||||
|
||||
bool QHexMetadata::hasMetadata() { return m_metadata.count() > 0; }
|
||||
|
||||
/*==================================*/
|
||||
|
||||
|
@ -145,13 +176,13 @@ QString QHexMetadata::comments(qsizetype line, qsizetype column) const {
|
|||
}
|
||||
|
||||
bool QHexMetadata::lineHasMetadata(qsizetype line) const {
|
||||
return m_metadata.contains(line);
|
||||
return m_linemeta.contains(line);
|
||||
}
|
||||
|
||||
qsizetype QHexMetadata::size() const { return m_absoluteMetadata.size(); }
|
||||
qsizetype QHexMetadata::size() const { return m_metadata.size(); }
|
||||
|
||||
void QHexMetadata::clear() {
|
||||
m_absoluteMetadata.clear();
|
||||
m_linemeta.clear();
|
||||
m_metadata.clear();
|
||||
emit metadataChanged();
|
||||
}
|
||||
|
@ -159,27 +190,59 @@ void QHexMetadata::clear() {
|
|||
void QHexMetadata::metadata(qsizetype begin, qsizetype end,
|
||||
const QColor &fgcolor, const QColor &bgcolor,
|
||||
const QString &comment) {
|
||||
QHexMetadataAbsoluteItem absi{begin, end, fgcolor, bgcolor, comment};
|
||||
m_absoluteMetadata.append(absi);
|
||||
setAbsoluteMetadata(absi);
|
||||
QHexMetadataItem absi{begin, end, fgcolor, bgcolor, comment};
|
||||
addMetadata(absi);
|
||||
emit metadataChanged();
|
||||
}
|
||||
|
||||
void QHexMetadata::setAbsoluteMetadata(const QHexMetadataAbsoluteItem &mai) {
|
||||
Q_ASSERT(m_lineWidth > 0);
|
||||
void QHexMetadata::setLineWidth(quint8 width) {
|
||||
if (width != m_lineWidth) {
|
||||
m_lineWidth = width;
|
||||
|
||||
const auto firstRow = mai.begin / m_lineWidth;
|
||||
const auto lastRow = mai.end / m_lineWidth;
|
||||
m_linemeta.clear();
|
||||
for (auto &item : m_metadata) {
|
||||
addMetadata(item);
|
||||
}
|
||||
|
||||
emit metadataChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void QHexMetadata::color(qsizetype begin, qsizetype end, const QColor &fgcolor,
|
||||
const QColor &bgcolor) {
|
||||
this->metadata(begin, end, fgcolor, bgcolor, QString());
|
||||
}
|
||||
|
||||
void QHexMetadata::foreground(qsizetype begin, qsizetype end,
|
||||
const QColor &fgcolor) {
|
||||
this->color(begin, end, fgcolor, QColor());
|
||||
}
|
||||
|
||||
void QHexMetadata::background(qsizetype begin, qsizetype end,
|
||||
const QColor &bgcolor) {
|
||||
this->color(begin, end, QColor(), bgcolor);
|
||||
}
|
||||
|
||||
void QHexMetadata::comment(qsizetype begin, qsizetype end,
|
||||
const QString &comment) {
|
||||
this->metadata(begin, end, QColor(), QColor(), comment);
|
||||
}
|
||||
|
||||
void QHexMetadata::addMetadata(const QHexMetadataItem &mi) {
|
||||
const auto firstRow = mi.begin / m_lineWidth;
|
||||
const auto lastRow = mi.end / m_lineWidth;
|
||||
|
||||
for (auto row = firstRow; row <= lastRow; ++row) {
|
||||
qsizetype start, length;
|
||||
if (row == firstRow) {
|
||||
start = mai.begin % m_lineWidth;
|
||||
Q_ASSERT(m_lineWidth > 0);
|
||||
start = mi.begin % m_lineWidth;
|
||||
} else {
|
||||
start = 0;
|
||||
}
|
||||
if (row == lastRow) {
|
||||
const int lastChar = mai.end % m_lineWidth;
|
||||
Q_ASSERT(m_lineWidth > 0);
|
||||
const int lastChar = mi.end % m_lineWidth;
|
||||
length = lastChar - start;
|
||||
} else {
|
||||
// fix the bug by wingsummer
|
||||
|
@ -190,69 +253,10 @@ void QHexMetadata::setAbsoluteMetadata(const QHexMetadataAbsoluteItem &mai) {
|
|||
}
|
||||
|
||||
if (length > 0) {
|
||||
setMetadata({row, start, length, mai.foreground, mai.background,
|
||||
mai.comment});
|
||||
m_linemeta[row][mi].append(
|
||||
{start, length, mi.foreground, mi.background, mi.comment});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QHexMetadata::setLineWidth(quint8 width) {
|
||||
if (width != m_lineWidth) {
|
||||
m_lineWidth = width;
|
||||
// clean m_metadata
|
||||
m_metadata.clear();
|
||||
// and regenerate with new line width size
|
||||
for (int i = 0; i < m_absoluteMetadata.size(); ++i) {
|
||||
setAbsoluteMetadata(m_absoluteMetadata[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QHexMetadata::metadata(qsizetype line, qsizetype start, qsizetype length,
|
||||
const QColor &fgcolor, const QColor &bgcolor,
|
||||
const QString &comment) {
|
||||
const qsizetype begin = qsizetype(line * m_lineWidth + uint(start));
|
||||
const qsizetype end = begin + length;
|
||||
// delegate to the new interface
|
||||
this->metadata(begin, end, fgcolor, bgcolor, comment);
|
||||
emit metadataChanged();
|
||||
}
|
||||
|
||||
void QHexMetadata::color(qsizetype line, qsizetype start, qsizetype length,
|
||||
const QColor &fgcolor, const QColor &bgcolor) {
|
||||
this->metadata(line, start, length, fgcolor, bgcolor, QString());
|
||||
}
|
||||
|
||||
void QHexMetadata::foreground(qsizetype line, qsizetype start, qsizetype length,
|
||||
const QColor &fgcolor) {
|
||||
this->color(line, start, length, fgcolor, QColor());
|
||||
}
|
||||
|
||||
void QHexMetadata::background(qsizetype line, qsizetype start, qsizetype length,
|
||||
const QColor &bgcolor) {
|
||||
this->color(line, start, length, QColor(), bgcolor);
|
||||
}
|
||||
|
||||
void QHexMetadata::comment(qsizetype line, qsizetype start, qsizetype length,
|
||||
const QString &comment) {
|
||||
this->metadata(line, start, length, QColor(), QColor(), comment);
|
||||
}
|
||||
|
||||
void QHexMetadata::setMetadata(const QHexMetadataItem &mi) {
|
||||
if (!m_metadata.contains(mi.line)) {
|
||||
QHexLineMetadata linemetadata;
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
||||
linemetadata << mi;
|
||||
#else
|
||||
linemetadata.push_back(mi);
|
||||
#endif
|
||||
m_metadata[mi.line] = linemetadata;
|
||||
} else {
|
||||
QHexLineMetadata &linemetadata = m_metadata[mi.line];
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
||||
linemetadata << mi;
|
||||
#else
|
||||
linemetadata.push_back(mi);
|
||||
#endif
|
||||
}
|
||||
m_metadata << mi;
|
||||
}
|
||||
|
|
|
@ -2,55 +2,80 @@
|
|||
#define QHEXMETADATA_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QtGlobal>
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
||||
#include <QLinkedList>
|
||||
#else
|
||||
#include <list>
|
||||
#endif
|
||||
|
||||
#include <QColor>
|
||||
#include <QHash>
|
||||
#include <QMap>
|
||||
#include <QUndoStack>
|
||||
#include <QVector>
|
||||
|
||||
struct QHexMetadataAbsoluteItem {
|
||||
qsizetype begin;
|
||||
qsizetype end;
|
||||
#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(size_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
|
||||
|
||||
struct QHexMetadataItem {
|
||||
qsizetype begin = -1;
|
||||
qsizetype end = -1;
|
||||
QColor foreground, background;
|
||||
QString comment;
|
||||
|
||||
// added by wingsummer
|
||||
bool operator==(const QHexMetadataAbsoluteItem &item) const {
|
||||
bool operator==(const QHexMetadataItem &item) const {
|
||||
return begin == item.begin && end == item.end &&
|
||||
foreground == item.foreground && background == item.background &&
|
||||
comment == item.comment;
|
||||
}
|
||||
};
|
||||
|
||||
struct QHexMetadataItem {
|
||||
qsizetype line;
|
||||
qsizetype start, length;
|
||||
inline qhash_result_t qHash(const QHexMetadataItem &c,
|
||||
qhash_result_t seed) noexcept {
|
||||
return qHashMulti(seed, c.begin, c.end, c.foreground.rgba(),
|
||||
c.background.rgba(), c.comment);
|
||||
}
|
||||
|
||||
// only for rendering
|
||||
struct QHexLineMetadataItem {
|
||||
qsizetype start = -1, length = 0;
|
||||
QColor foreground, background;
|
||||
QString comment;
|
||||
|
||||
// added by wingsummer
|
||||
bool operator==(const QHexMetadataItem &item) const {
|
||||
return line == item.line && start == item.start &&
|
||||
foreground == item.foreground && background == item.background &&
|
||||
comment == item.comment;
|
||||
}
|
||||
QHexMetadataItem *parent = nullptr;
|
||||
};
|
||||
|
||||
typedef std::list<QHexMetadataItem> QHexLineMetadata;
|
||||
typedef QList<QHexLineMetadataItem> QHexLineMetadata;
|
||||
|
||||
class QHexMetadata : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QHexMetadata(QUndoStack *undo, QObject *parent = nullptr);
|
||||
const QHexLineMetadata &get(qsizetype line) const;
|
||||
QHexLineMetadata get(qsizetype line) const;
|
||||
QString comments(qsizetype line, qsizetype column) const;
|
||||
bool lineHasMetadata(qsizetype line) const; // modified by wingsummer
|
||||
|
||||
|
@ -59,10 +84,9 @@ public:
|
|||
/*============================*/
|
||||
// added by wingsummer
|
||||
|
||||
void ModifyMetadata(QHexMetadataAbsoluteItem newmeta,
|
||||
QHexMetadataAbsoluteItem oldmeta);
|
||||
void RemoveMetadatas(const QList<QHexMetadataAbsoluteItem> &items);
|
||||
void RemoveMetadata(QHexMetadataAbsoluteItem item);
|
||||
void ModifyMetadata(QHexMetadataItem newmeta, QHexMetadataItem oldmeta);
|
||||
void RemoveMetadatas(const QList<QHexMetadataItem> &items);
|
||||
void RemoveMetadata(QHexMetadataItem item);
|
||||
void RemoveMetadata(qsizetype offset);
|
||||
void Metadata(qsizetype begin, qsizetype end, const QColor &fgcolor,
|
||||
const QColor &bgcolor, const QString &comment);
|
||||
|
@ -70,17 +94,15 @@ public:
|
|||
|
||||
//---------------------------------------------------------
|
||||
|
||||
void modifyMetadata(QHexMetadataAbsoluteItem newmeta,
|
||||
QHexMetadataAbsoluteItem oldmeta);
|
||||
void removeMetadata(QHexMetadataAbsoluteItem item);
|
||||
bool modifyMetadata(const QHexMetadataItem &newmeta,
|
||||
const QHexMetadataItem &oldmeta);
|
||||
bool removeMetadata(const QHexMetadataItem &item);
|
||||
void removeMetadata(qsizetype offset);
|
||||
QList<QHexMetadataAbsoluteItem> gets(qsizetype offset);
|
||||
void applyMetas(QList<QHexMetadataAbsoluteItem> metas);
|
||||
|
||||
void redo();
|
||||
void undo();
|
||||
bool canRedo();
|
||||
bool canUndo();
|
||||
QVector<QHexMetadataItem> getAllMetadata() const;
|
||||
QVector<QHexMetadataItem> gets(qsizetype offset);
|
||||
void applyMetas(const QVector<QHexMetadataItem> &metas);
|
||||
|
||||
bool hasMetadata();
|
||||
|
||||
/*============================*/
|
||||
|
@ -93,39 +115,25 @@ public:
|
|||
void metadata(qsizetype begin, qsizetype end, const QColor &fgcolor,
|
||||
const QColor &bgcolor, const QString &comment);
|
||||
|
||||
// old interface with line, start, length
|
||||
void metadata(qsizetype line, qsizetype start, qsizetype length,
|
||||
const QColor &fgcolor, const QColor &bgcolor,
|
||||
const QString &comment);
|
||||
|
||||
void color(qsizetype line, qsizetype start, qsizetype length,
|
||||
const QColor &fgcolor, const QColor &bgcolor);
|
||||
void foreground(qsizetype line, qsizetype start, qsizetype length,
|
||||
const QColor &fgcolor);
|
||||
void background(qsizetype line, qsizetype start, qsizetype length,
|
||||
const QColor &bgcolor);
|
||||
void comment(qsizetype line, qsizetype start, qsizetype length,
|
||||
const QString &comment);
|
||||
|
||||
QList<QHexMetadataAbsoluteItem>
|
||||
getallMetas(); // added by wingsummer to support workspace
|
||||
|
||||
const QList<QHexMetadataAbsoluteItem> &
|
||||
getallMetasPtr(); // added by wingsummer to support workspace
|
||||
void color(qsizetype begin, qsizetype end, const QColor &fgcolor,
|
||||
const QColor &bgcolor);
|
||||
void foreground(qsizetype begin, qsizetype end, const QColor &fgcolor);
|
||||
void background(qsizetype begin, qsizetype end, const QColor &bgcolor);
|
||||
void comment(qsizetype begin, qsizetype end, const QString &comment);
|
||||
|
||||
private:
|
||||
void setMetadata(const QHexMetadataItem &mi);
|
||||
void setAbsoluteMetadata(const QHexMetadataAbsoluteItem &mi);
|
||||
void addMetadata(const QHexMetadataItem &mi);
|
||||
|
||||
signals:
|
||||
void metadataChanged();
|
||||
|
||||
private:
|
||||
quint8 m_lineWidth;
|
||||
QHash<qsizetype, QHexLineMetadata> m_metadata;
|
||||
QList<QHexMetadataAbsoluteItem> m_absoluteMetadata;
|
||||
|
||||
QUndoStack *m_undo; // added by wingsummer
|
||||
QMap<qsizetype, QHash<QHexMetadataItem, QHexLineMetadata>> m_linemeta;
|
||||
QVector<QHexMetadataItem> m_metadata;
|
||||
|
||||
QUndoStack *m_undo = nullptr; // added by wingsummer
|
||||
};
|
||||
|
||||
#endif // QHEXMETADATA_H
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include <QTextCursor>
|
||||
#include <QWidget>
|
||||
#include <cctype>
|
||||
#include <cmath>
|
||||
#include <cwctype>
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
|
@ -23,21 +22,21 @@ bool QHexRenderer::stringVisible() { return m_asciiVisible; }
|
|||
|
||||
void QHexRenderer::setStringVisible(bool b) {
|
||||
m_asciiVisible = b;
|
||||
m_document->documentChanged();
|
||||
emit m_document->documentChanged();
|
||||
}
|
||||
|
||||
bool QHexRenderer::headerVisible() { return m_headerVisible; }
|
||||
|
||||
void QHexRenderer::setHeaderVisible(bool b) {
|
||||
m_headerVisible = b;
|
||||
m_document->documentChanged();
|
||||
emit m_document->documentChanged();
|
||||
}
|
||||
|
||||
bool QHexRenderer::addressVisible() { return m_addressVisible; }
|
||||
|
||||
void QHexRenderer::setAddressVisible(bool b) {
|
||||
m_addressVisible = b;
|
||||
m_document->documentChanged();
|
||||
emit m_document->documentChanged();
|
||||
}
|
||||
|
||||
QString QHexRenderer::encoding() {
|
||||
|
@ -66,7 +65,7 @@ bool QHexRenderer::setEncoding(const QString &encoding) {
|
|||
if (encoding.compare(QStringLiteral("ISO-8859-1"), Qt::CaseInsensitive) ==
|
||||
0) {
|
||||
m_encoding = QStringLiteral("ASCII");
|
||||
m_document->documentChanged();
|
||||
emit m_document->documentChanged();
|
||||
return true;
|
||||
}
|
||||
if (QStringConverter::encodingForName(enc.toUtf8())) {
|
||||
|
@ -74,7 +73,7 @@ bool QHexRenderer::setEncoding(const QString &encoding) {
|
|||
if (QTextCodec::codecForName(encoding.toUtf8())) {
|
||||
#endif
|
||||
m_encoding = encoding;
|
||||
m_document->documentChanged();
|
||||
emit m_document->documentChanged();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -406,7 +405,7 @@ void QHexRenderer::applyMetadata(QTextCursor &textcursor, qsizetype line,
|
|||
return;
|
||||
|
||||
const QHexLineMetadata &linemetadata = metadata->get(line);
|
||||
for (const QHexMetadataItem &mi : linemetadata) {
|
||||
for (auto &mi : linemetadata) {
|
||||
QTextCharFormat charformat;
|
||||
if (m_document->metabgVisible() && mi.background.isValid() &&
|
||||
mi.background.rgba())
|
||||
|
@ -577,7 +576,7 @@ void QHexRenderer::applyBookMark(QTextCursor &textcursor, qsizetype line,
|
|||
if (!m_document->lineHasBookMark(line))
|
||||
return;
|
||||
|
||||
auto pos = m_document->getsBookmarkPos(line);
|
||||
auto pos = m_document->getLineBookmarksPos(line);
|
||||
for (auto item : pos) {
|
||||
textcursor.setPosition(int((item % hexLineWidth()) * factor) + 2);
|
||||
auto charformat = textcursor.charFormat();
|
||||
|
|
|
@ -115,16 +115,16 @@ void QHexView::establishSignal(QHexDocument *doc) {
|
|||
&QHexView::canRedoChanged);
|
||||
connect(doc, &QHexDocument::documentSaved, this, &QHexView::documentSaved);
|
||||
connect(doc, &QHexDocument::metabgVisibleChanged, this, [=](bool b) {
|
||||
QHexView::metabgVisibleChanged(b);
|
||||
emit this->metaStatusChanged();
|
||||
emit metabgVisibleChanged(b);
|
||||
emit metaStatusChanged();
|
||||
});
|
||||
connect(doc, &QHexDocument::metafgVisibleChanged, this, [=](bool b) {
|
||||
QHexView::metafgVisibleChanged(b);
|
||||
emit this->metaStatusChanged();
|
||||
emit metafgVisibleChanged(b);
|
||||
emit metaStatusChanged();
|
||||
});
|
||||
connect(doc, &QHexDocument::metaCommentVisibleChanged, this, [=](bool b) {
|
||||
QHexView::metaCommentVisibleChanged(b);
|
||||
emit this->metaStatusChanged();
|
||||
emit metaCommentVisibleChanged(b);
|
||||
emit metaStatusChanged();
|
||||
});
|
||||
connect(doc, &QHexDocument::metaDataChanged, this,
|
||||
[=] { this->viewport()->update(); });
|
||||
|
@ -292,26 +292,6 @@ qsizetype QHexView::searchBackward(qsizetype begin, const QByteArray &ba) {
|
|||
return m_document->searchBackward(startPos, ba);
|
||||
}
|
||||
|
||||
void QHexView::gotoBookMark(qsizetype index) {
|
||||
if (index >= 0 && index < m_document->bookMarksCount()) {
|
||||
auto bookmark = m_document->bookMarkByIndex(index);
|
||||
m_cursor->moveTo(bookmark.pos);
|
||||
}
|
||||
}
|
||||
|
||||
bool QHexView::existBookMarkByIndex(qsizetype &index) {
|
||||
auto curpos = m_cursor->position().offset();
|
||||
int i = 0;
|
||||
for (auto &item : m_document->getAllBookMarks()) {
|
||||
if (item.pos == curpos) {
|
||||
index = i;
|
||||
return true;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QHexView::RemoveSelection(int nibbleindex) {
|
||||
if (!m_cursor->hasSelection())
|
||||
return false;
|
||||
|
@ -338,10 +318,6 @@ bool QHexView::atEnd() const {
|
|||
return m_cursor->position().offset() >= m_document->length();
|
||||
}
|
||||
|
||||
void QHexView::gotoMetaData(qsizetype index) {
|
||||
m_cursor->moveTo(m_document->metadata()->getallMetasPtr().at(index).begin);
|
||||
}
|
||||
|
||||
QByteArray QHexView::selectedBytes() const {
|
||||
if (!m_cursor->hasSelection())
|
||||
return QByteArray();
|
||||
|
|
|
@ -97,14 +97,10 @@ public:
|
|||
qsizetype searchForward(qsizetype begin, const QByteArray &ba);
|
||||
qsizetype searchBackward(qsizetype begin, const QByteArray &ba);
|
||||
|
||||
void gotoBookMark(qsizetype index);
|
||||
bool existBookMarkByIndex(qsizetype &index);
|
||||
bool RemoveSelection(int nibbleindex = 1);
|
||||
bool removeSelection();
|
||||
bool atEnd() const;
|
||||
|
||||
void gotoMetaData(qsizetype index);
|
||||
|
||||
QByteArray selectedBytes() const;
|
||||
|
||||
bool cut(bool hex);
|
||||
|
|
|
@ -54,12 +54,9 @@ set(SNIPPET_SRC
|
|||
lib/snippets/qsnippet_p.h
|
||||
lib/snippets/qsnippetbinding.cpp
|
||||
lib/snippets/qsnippetbinding.h
|
||||
lib/snippets/qsnippetedit.cpp
|
||||
lib/snippets/qsnippetedit.h
|
||||
lib/snippets/qsnippetmanager.cpp
|
||||
lib/snippets/qsnippetmanager.h
|
||||
lib/snippets/qsnippetpatternloader.h
|
||||
lib/snippets/snippetedit.ui)
|
||||
lib/snippets/qsnippetpatternloader.h)
|
||||
|
||||
set(SOURCE_FILES
|
||||
lib/qce-config.h
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -192,18 +192,15 @@ public:
|
|||
void flushMatches(int groupId);
|
||||
void addMatch(int groupId, int line, int pos, int len, int format);
|
||||
|
||||
static QFont font();
|
||||
static void setFont(const QFont &f);
|
||||
static const QFontMetrics &fontMetrics();
|
||||
QFont font();
|
||||
void setFont(const QFont &f);
|
||||
const QFontMetrics &fontMetrics();
|
||||
|
||||
static LineEnding defaultLineEnding();
|
||||
static void setDefaultLineEnding(LineEnding le);
|
||||
int tabStop();
|
||||
void setTabStop(int n);
|
||||
|
||||
static int tabStop();
|
||||
static void setTabStop(int n);
|
||||
|
||||
static WhiteSpaceMode showSpaces();
|
||||
static void setShowSpaces(WhiteSpaceMode y);
|
||||
WhiteSpaceMode showSpaces();
|
||||
void setShowSpaces(WhiteSpaceMode y);
|
||||
|
||||
static QFormatScheme *defaultFormatScheme();
|
||||
static void setDefaultFormatScheme(QFormatScheme *f);
|
||||
|
@ -214,7 +211,7 @@ public:
|
|||
static int screenLength(const QChar *d, int l, int tabStop);
|
||||
static QString screenable(const QChar *d, int l, int tabStop);
|
||||
|
||||
inline void markViewDirty() { formatsChanged(); }
|
||||
inline void markViewDirty() { emit formatsChanged(); }
|
||||
|
||||
bool isClean() const;
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ public:
|
|||
|
||||
void draw(QPainter *p, QDocument::PaintContext &cxt);
|
||||
|
||||
QDocumentLineHandle *lineForPosition(int &position) const;
|
||||
QDocumentLineHandle *lineForPosition(int position) const;
|
||||
int position(const QDocumentLineHandle *l) const;
|
||||
|
||||
QDocumentLineHandle *at(int line) const;
|
||||
|
@ -86,7 +86,7 @@ public:
|
|||
void setWidth();
|
||||
void setHeight();
|
||||
|
||||
static void setFont(const QFont &f);
|
||||
void setFont(const QFont &f);
|
||||
|
||||
void beginChangeBlock();
|
||||
void endChangeBlock();
|
||||
|
@ -120,7 +120,6 @@ public:
|
|||
|
||||
void setWidth(int width);
|
||||
|
||||
void emitFormatsChanged();
|
||||
void emitContentsChanged();
|
||||
|
||||
void emitLineDeleted(QDocumentLineHandle *h);
|
||||
|
@ -165,7 +164,7 @@ private:
|
|||
struct Match {
|
||||
int line;
|
||||
QFormatRange range;
|
||||
QDocumentLineHandle *h;
|
||||
QDocumentLineHandle *h = nullptr;
|
||||
};
|
||||
|
||||
struct MatchList : QList<Match> {
|
||||
|
@ -182,21 +181,19 @@ private:
|
|||
int m_width, m_height;
|
||||
|
||||
int m_tabStop;
|
||||
static int m_defaultTabStop;
|
||||
|
||||
static QFont *m_font;
|
||||
static bool m_fixedPitch;
|
||||
static QFontMetrics *m_fontMetrics;
|
||||
static int m_leftMargin;
|
||||
static QDocument::WhiteSpaceMode m_showSpaces;
|
||||
static QDocument::LineEnding m_defaultLineEnding;
|
||||
static int m_lineHeight;
|
||||
static int m_lineSpacing;
|
||||
static int m_spaceWidth;
|
||||
static int m_ascent;
|
||||
static int m_descent;
|
||||
static int m_leading;
|
||||
static int m_wrapMargin;
|
||||
QFont m_font;
|
||||
bool m_fixedPitch;
|
||||
QFontMetrics m_fontMetrics;
|
||||
int m_leftMargin;
|
||||
QDocument::WhiteSpaceMode m_showSpaces;
|
||||
int m_lineHeight;
|
||||
int m_lineSpacing;
|
||||
int m_spaceWidth;
|
||||
int m_ascent;
|
||||
int m_descent;
|
||||
int m_leading;
|
||||
int m_wrapMargin;
|
||||
|
||||
QFormatScheme *m_formatScheme;
|
||||
QLanguageDefinition *m_language;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
*/
|
||||
|
||||
#include "qdocument_p.h"
|
||||
#include "qformatscheme.h"
|
||||
|
||||
/*!
|
||||
\ingroup document
|
||||
|
@ -142,7 +143,8 @@ void QDocumentCommand::setUndoOffset(int off) { m_undoOffset = off; }
|
|||
This helper method is provided so that subclasses may actually
|
||||
modify the document contents without using private API.
|
||||
*/
|
||||
void QDocumentCommand::insertText(int line, int pos, const QString &s) {
|
||||
void QDocumentCommand::insertText(int line, int pos, const QString &s,
|
||||
const QString &sfmtID) {
|
||||
if (!m_doc)
|
||||
return;
|
||||
|
||||
|
@ -155,6 +157,19 @@ void QDocumentCommand::insertText(int line, int pos, const QString &s) {
|
|||
h->textBuffer().insert(pos, s);
|
||||
h->shiftOverlays(pos, s.length());
|
||||
|
||||
if (!sfmtID.isEmpty()) {
|
||||
auto fmt = m_doc->formatScheme();
|
||||
auto id = fmt->id(sfmtID);
|
||||
if (id) {
|
||||
QFormatRange range;
|
||||
range.format = id;
|
||||
range.offset = pos;
|
||||
range.length = s.length();
|
||||
|
||||
h->addOverlay(range);
|
||||
}
|
||||
}
|
||||
|
||||
pd->adjustWidth(line);
|
||||
}
|
||||
|
||||
|
@ -484,8 +499,9 @@ void QDocumentCommand::markUndone(QDocumentLineHandle *h) {
|
|||
QDocumentInsertCommand::QDocumentInsertCommand(int l, int offset,
|
||||
const QString &text,
|
||||
QDocument *doc,
|
||||
const QString &sfmtID,
|
||||
QDocumentCommand *p)
|
||||
: QDocumentCommand(Insert, doc, p) {
|
||||
: QDocumentCommand(Insert, doc, p), m_sfmtID(sfmtID) {
|
||||
QStringList lines = text.split(QLatin1Char('\n'), Qt::KeepEmptyParts);
|
||||
|
||||
if (!m_doc || text.isEmpty())
|
||||
|
@ -497,8 +513,9 @@ QDocumentInsertCommand::QDocumentInsertCommand(int l, int offset,
|
|||
m_data.begin = lines.takeAt(0);
|
||||
m_data.endOffset = lines.count() ? lines.last().length() : -1;
|
||||
|
||||
foreach (const QString &s, lines)
|
||||
for (auto &s : lines) {
|
||||
m_data.handles << new QDocumentLineHandle(s, m_doc);
|
||||
}
|
||||
|
||||
QDocumentLine bl = m_doc->line(l);
|
||||
|
||||
|
@ -541,7 +558,7 @@ void QDocumentInsertCommand::redo() {
|
|||
removeText(m_data.lineNumber, m_data.startOffset, m_data.end.length());
|
||||
}
|
||||
|
||||
insertText(m_data.lineNumber, m_data.startOffset, m_data.begin);
|
||||
insertText(m_data.lineNumber, m_data.startOffset, m_data.begin, m_sfmtID);
|
||||
|
||||
insertLines(m_data.lineNumber, m_data.handles);
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
QList<QDocumentLineHandle *> handles;
|
||||
};
|
||||
|
||||
QDocumentCommand(Command c, QDocument *d, QDocumentCommand *p = 0);
|
||||
QDocumentCommand(Command c, QDocument *d, QDocumentCommand *p = nullptr);
|
||||
virtual ~QDocumentCommand();
|
||||
|
||||
virtual int id() const;
|
||||
|
@ -77,7 +77,8 @@ protected:
|
|||
|
||||
void updateTarget(int l, int offset);
|
||||
|
||||
void insertText(int line, int pos, const QString &s);
|
||||
void insertText(int line, int pos, const QString &s,
|
||||
const QString &sfmtID = {});
|
||||
void removeText(int line, int pos, int length);
|
||||
|
||||
void insertLines(int after, const QList<QDocumentLineHandle *> &l);
|
||||
|
@ -102,7 +103,8 @@ Q_DECLARE_TYPEINFO(QDocumentCommand::TextCommandData, Q_MOVABLE_TYPE);
|
|||
class QCE_EXPORT QDocumentInsertCommand : public QDocumentCommand {
|
||||
public:
|
||||
QDocumentInsertCommand(int l, int offset, const QString &text,
|
||||
QDocument *doc, QDocumentCommand *p = 0);
|
||||
QDocument *doc, const QString &sfmtID = 0,
|
||||
QDocumentCommand *p = nullptr);
|
||||
|
||||
virtual ~QDocumentInsertCommand();
|
||||
|
||||
|
@ -113,12 +115,13 @@ public:
|
|||
|
||||
private:
|
||||
TextCommandData m_data;
|
||||
QString m_sfmtID;
|
||||
};
|
||||
|
||||
class QCE_EXPORT QDocumentEraseCommand : public QDocumentCommand {
|
||||
public:
|
||||
QDocumentEraseCommand(int bl, int bo, int el, int eo, QDocument *doc,
|
||||
QDocumentCommand *p = 0);
|
||||
QDocumentCommand *p = nullptr);
|
||||
|
||||
virtual ~QDocumentEraseCommand();
|
||||
|
||||
|
|
|
@ -418,16 +418,6 @@ void QDocumentCursor::shift(int offset) {
|
|||
m_handle->shift(offset);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Set the text position of the cursor (within the whole document)
|
||||
|
||||
Remark made about position() applies.
|
||||
*/
|
||||
void QDocumentCursor::setPosition(int pos, MoveMode m) {
|
||||
if (m_handle)
|
||||
m_handle->setPosition(pos, m);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Moves the cursor position
|
||||
\param offset number of times the selected move will be done
|
||||
|
@ -515,7 +505,7 @@ void QDocumentCursor::eraseLine() {
|
|||
*/
|
||||
void QDocumentCursor::insertLine(bool keepAnchor) {
|
||||
if (m_handle)
|
||||
m_handle->insertText("\n", keepAnchor);
|
||||
m_handle->insertText(QStringLiteral("\n"), keepAnchor);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -525,9 +515,10 @@ void QDocumentCursor::insertLine(bool keepAnchor) {
|
|||
|
||||
\note Nothing happens if \a s is empty
|
||||
*/
|
||||
void QDocumentCursor::insertText(const QString &s, bool keepAnchor) {
|
||||
void QDocumentCursor::insertText(const QString &s, bool keepAnchor,
|
||||
const QString &sfmtID) {
|
||||
if (m_handle)
|
||||
m_handle->insertText(s, keepAnchor);
|
||||
m_handle->insertText(s, keepAnchor, sfmtID);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
@ -132,7 +132,6 @@ public:
|
|||
QDocumentLine anchorLine() const;
|
||||
|
||||
void shift(int offset);
|
||||
void setPosition(int pos, MoveMode m = MoveAnchor);
|
||||
bool movePosition(int offset, MoveOperation op = NextCharacter,
|
||||
MoveMode m = MoveAnchor);
|
||||
|
||||
|
@ -142,7 +141,8 @@ public:
|
|||
|
||||
void eraseLine();
|
||||
void insertLine(bool keepAnchor = false);
|
||||
void insertText(const QString &s, bool keepAnchor = false);
|
||||
void insertText(const QString &s, bool keepAnchor = false,
|
||||
const QString &sfmtID = {});
|
||||
|
||||
QDocumentCursor selectionStart() const;
|
||||
QDocumentCursor selectionEnd() const;
|
||||
|
|
|
@ -90,10 +90,10 @@ public:
|
|||
int position() const;
|
||||
|
||||
void shift(int offset);
|
||||
void setPosition(int pos, int m);
|
||||
bool movePosition(int offset, int op, int m);
|
||||
|
||||
void insertText(const QString &s, bool keepAnchor = false);
|
||||
void insertText(const QString &s, bool keepAnchor = false,
|
||||
const QString &sfmtID = {});
|
||||
|
||||
QChar nextChar() const;
|
||||
QChar previousChar() const;
|
||||
|
|
|
@ -59,7 +59,7 @@ void addDataPath(const QString &path);
|
|||
template <typename Registerable>
|
||||
class Registar {
|
||||
public:
|
||||
Registar() { Registerable::_register(); }
|
||||
constexpr Registar() { Registerable::_register(); }
|
||||
};
|
||||
|
||||
// added by wingsummer
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -60,20 +60,7 @@
|
|||
#include <QTextStream>
|
||||
#include <QTimer>
|
||||
|
||||
// #define Q_GL_EDITOR
|
||||
|
||||
#ifdef _QMDI_
|
||||
#include "qmdiserver.h"
|
||||
#endif
|
||||
|
||||
#ifdef _EDYUK_
|
||||
#include "edyukapplication.h"
|
||||
#include "qshortcutmanager.h"
|
||||
|
||||
#define Q_SHORTCUT(a, s, c) EDYUK_SHORTCUT(a, tr(c), tr(s))
|
||||
#else
|
||||
#define Q_SHORTCUT(a, s, c) a->setShortcut(QKeySequence(tr(s, c)))
|
||||
#endif
|
||||
|
||||
#ifdef Q_GL_EDITOR
|
||||
#include <QtOpenGLWidgets/QOpenGLWidget>
|
||||
|
@ -216,7 +203,7 @@ QString QEditor::defaultInputBindingId() {
|
|||
void QEditor::registerInputBinding(QEditorInputBindingInterface *b) {
|
||||
m_registeredBindings[b->id()] = b;
|
||||
|
||||
for (QEditor *e : m_editors)
|
||||
for (auto &e : m_editors)
|
||||
e->updateBindingsMenu();
|
||||
}
|
||||
|
||||
|
@ -226,7 +213,7 @@ void QEditor::registerInputBinding(QEditorInputBindingInterface *b) {
|
|||
void QEditor::unregisterInputBinding(QEditorInputBindingInterface *b) {
|
||||
m_registeredBindings.remove(b->id());
|
||||
|
||||
for (QEditor *e : m_editors)
|
||||
for (auto &e : m_editors)
|
||||
e->updateBindingsMenu();
|
||||
}
|
||||
|
||||
|
@ -294,7 +281,7 @@ int QEditor::defaultFlags() { return m_defaultFlags; }
|
|||
void QEditor::setDefaultFlags(int flags) {
|
||||
m_defaultFlags = flags & Accessible;
|
||||
|
||||
for (QEditor *e : m_editors) {
|
||||
for (auto &e : m_editors) {
|
||||
bool ontoWrap = (m_defaultFlags & LineWrap) && !(e->m_state & LineWrap);
|
||||
bool outOfWrap =
|
||||
!(m_defaultFlags & LineWrap) && (e->m_state & LineWrap);
|
||||
|
@ -331,7 +318,7 @@ QString QEditor::defaultCodecName() { return m_defaultCodecName; }
|
|||
affected by the change of the default codecName.
|
||||
*/
|
||||
void QEditor::setDefaultCodec(const QString &name, int update) {
|
||||
for (QEditor *e : m_editors) {
|
||||
for (auto &e : m_editors) {
|
||||
if (e->codecName() == m_defaultCodecName) {
|
||||
if (update & UpdateOld)
|
||||
e->setCodec(name);
|
||||
|
@ -463,42 +450,35 @@ void QEditor::init(bool actions) {
|
|||
setAttribute(Qt::WA_KeyCompression, true);
|
||||
setAttribute(Qt::WA_InputMethodEnabled, true);
|
||||
|
||||
connect(this,
|
||||
SIGNAL(markChanged(QString, QDocumentLineHandle *, int, bool)),
|
||||
QLineMarksInfoCenter::instance(),
|
||||
SLOT(markChanged(QString, QDocumentLineHandle *, int, bool)));
|
||||
connect(this, &QEditor::markChanged, QLineMarksInfoCenter::instance(),
|
||||
&QLineMarksInfoCenter::markChanged);
|
||||
|
||||
m_doc = new QDocument(this);
|
||||
_docfont = m_doc->font();
|
||||
|
||||
connect(m_doc, SIGNAL(formatsChange(int, int)), this,
|
||||
SLOT(repaintContent(int, int)));
|
||||
connect(m_doc, &QDocument::formatsChange, this, &QEditor::repaintContent);
|
||||
|
||||
connect(m_doc, SIGNAL(contentsChange(int, int)), this,
|
||||
SLOT(updateContent(int, int)));
|
||||
connect(m_doc, &QDocument::contentsChange, this, &QEditor::updateContent);
|
||||
|
||||
connect(m_doc, SIGNAL(formatsChanged()), viewport(), SLOT(update()));
|
||||
connect(m_doc, &QDocument::formatsChanged, this,
|
||||
[=] { this->viewport()->update(); });
|
||||
|
||||
connect(m_doc, SIGNAL(widthChanged(int)), this,
|
||||
SLOT(documentWidthChanged(int)));
|
||||
connect(m_doc, &QDocument::widthChanged, this,
|
||||
&QEditor::documentWidthChanged);
|
||||
|
||||
connect(m_doc, SIGNAL(heightChanged(int)), this,
|
||||
SLOT(documentHeightChanged(int)));
|
||||
connect(m_doc, &QDocument::heightChanged, this,
|
||||
&QEditor::documentHeightChanged);
|
||||
|
||||
connect(m_doc, SIGNAL(cleanChanged(bool)), this,
|
||||
SLOT(setContentClean(bool)));
|
||||
connect(m_doc, &QDocument::cleanChanged, this, &QEditor::setContentClean);
|
||||
|
||||
connect(m_doc, SIGNAL(undoAvailable(bool)), this,
|
||||
SIGNAL(undoAvailable(bool)));
|
||||
connect(m_doc, &QDocument::undoAvailable, this, &QEditor::undoAvailable);
|
||||
|
||||
connect(m_doc, SIGNAL(redoAvailable(bool)), this,
|
||||
SIGNAL(redoAvailable(bool)));
|
||||
connect(m_doc, &QDocument::redoAvailable, this, &QEditor::redoAvailable);
|
||||
|
||||
connect(m_doc, SIGNAL(markChanged(QDocumentLineHandle *, int, bool)), this,
|
||||
SLOT(markChanged(QDocumentLineHandle *, int, bool)));
|
||||
connect(m_doc, &QDocument::markChanged, this, &QEditor::emitMarkChanged);
|
||||
|
||||
connect(m_doc, SIGNAL(lineEndingChanged(int)), this,
|
||||
SLOT(lineEndingChanged(int)));
|
||||
connect(m_doc, &QDocument::lineEndingChanged, this,
|
||||
&QEditor::lineEndingChanged);
|
||||
|
||||
m_cursor = QDocumentCursor(m_doc);
|
||||
m_cursor.setAutoUpdated(true);
|
||||
|
@ -516,8 +496,8 @@ void QEditor::init(bool actions) {
|
|||
a->setObjectName("undo");
|
||||
Q_SHORTCUT(a, "Ctrl+Z", "Edit");
|
||||
a->setEnabled(false);
|
||||
connect(this, SIGNAL(undoAvailable(bool)), a, SLOT(setEnabled(bool)));
|
||||
connect(a, SIGNAL(triggered()), this, SLOT(undo()));
|
||||
connect(this, &QEditor::undoAvailable, a, &QAction::setEnabled);
|
||||
connect(a, &QAction::triggered, this, &QEditor::undo);
|
||||
|
||||
addAction(a, "&Edit", "Edit");
|
||||
|
||||
|
@ -664,8 +644,8 @@ void QEditor::init(bool actions) {
|
|||
m_bindingsActions = new QActionGroup(m_bindingsMenu);
|
||||
// m_bindingsActions->setExclusive(true);
|
||||
|
||||
connect(m_bindingsActions, SIGNAL(triggered(QAction *)), this,
|
||||
SLOT(bindingSelected(QAction *)));
|
||||
connect(m_bindingsActions, &QActionGroup::triggered, this,
|
||||
&QEditor::bindingSelected);
|
||||
|
||||
aDefaultBinding = new QAction(tr("Default"), m_bindingsMenu);
|
||||
aDefaultBinding->setCheckable(true);
|
||||
|
@ -689,8 +669,8 @@ void QEditor::init(bool actions) {
|
|||
m_lineEndingsActions = new QActionGroup(m_lineEndingsMenu);
|
||||
m_lineEndingsActions->setExclusive(true);
|
||||
|
||||
connect(m_lineEndingsActions, SIGNAL(triggered(QAction *)), this,
|
||||
SLOT(lineEndingSelected(QAction *)));
|
||||
connect(m_lineEndingsActions, &QActionGroup::triggered, this,
|
||||
&QEditor::lineEndingSelected);
|
||||
|
||||
m_lineEndingsActions->addAction(tr("Conservative"))
|
||||
->setData("conservative");
|
||||
|
@ -701,7 +681,7 @@ void QEditor::init(bool actions) {
|
|||
|
||||
QList<QAction *> lle = m_lineEndingsActions->actions();
|
||||
|
||||
for (QAction *a : lle) {
|
||||
for (auto &a : lle) {
|
||||
a->setCheckable(true);
|
||||
m_lineEndingsMenu->addAction(a);
|
||||
}
|
||||
|
@ -766,12 +746,16 @@ void QEditor::setFlag(EditFlag f, bool b) {
|
|||
/*!
|
||||
\return whether it is possible to call undo()
|
||||
*/
|
||||
bool QEditor::canUndo() const { return m_doc ? m_doc->canUndo() : false; }
|
||||
bool QEditor::canUndo() const {
|
||||
return m_doc ? (m_undoRedoEnabled && m_doc->canUndo()) : false;
|
||||
}
|
||||
|
||||
/*!
|
||||
\return whether it is possible to call redo()
|
||||
*/
|
||||
bool QEditor::canRedo() const { return m_doc ? m_doc->canRedo() : false; }
|
||||
bool QEditor::canRedo() const {
|
||||
return m_doc ? (m_undoRedoEnabled && m_doc->canRedo()) : false;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Set line wrapping
|
||||
|
@ -1127,14 +1111,6 @@ void QEditor::retranslate() {
|
|||
|
||||
if (aDefaultBinding)
|
||||
aDefaultBinding->setText(tr("Default"));
|
||||
|
||||
#ifdef _QMDI_
|
||||
menus.setTranslation("&Edit", tr("&Edit"));
|
||||
menus.setTranslation("&Search", tr("&Search"));
|
||||
|
||||
toolbars.setTranslation("Edit", tr("Edit"));
|
||||
toolbars.setTranslation("Search", tr("Search"));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -1167,16 +1143,6 @@ void QEditor::addAction(QAction *a, const QString &menu,
|
|||
|
||||
if (pMenu && menu.size()) {
|
||||
pMenu->addAction(a);
|
||||
|
||||
#ifdef _QMDI_
|
||||
menus[menu]->addAction(a);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (toolbar.size()) {
|
||||
#ifdef _QMDI_
|
||||
toolbars[toolbar]->addAction(a);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1201,18 +1167,8 @@ void QEditor::removeAction(QAction *a, const QString &menu,
|
|||
if (pMenu)
|
||||
pMenu->removeAction(a);
|
||||
|
||||
#ifdef _QMDI_
|
||||
if (menu.count()) {
|
||||
menus[menu]->removeAction(a);
|
||||
}
|
||||
|
||||
if (toolbar.count()) {
|
||||
toolbars[toolbar]->removeAction(a);
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(menu)
|
||||
Q_UNUSED(toolbar)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -1381,7 +1337,7 @@ void QEditor::addInputBinding(QEditorInputBindingInterface *b) {
|
|||
|
||||
QList<QAction *> actions = m_bindingsActions->actions();
|
||||
|
||||
for (QAction *a : actions) {
|
||||
for (auto &a : actions) {
|
||||
if (a->data().toString() != id)
|
||||
a->setChecked(true);
|
||||
}
|
||||
|
@ -1404,7 +1360,7 @@ void QEditor::removeInputBinding(QEditorInputBindingInterface *b) {
|
|||
|
||||
QList<QAction *> actions = m_bindingsActions->actions();
|
||||
|
||||
for (QAction *a : actions) {
|
||||
for (auto &a : actions) {
|
||||
if (a->data().toString() != id)
|
||||
a->setChecked(false);
|
||||
}
|
||||
|
@ -1430,7 +1386,7 @@ void QEditor::setInputBinding(QEditorInputBindingInterface *b) {
|
|||
|
||||
QList<QAction *> actions = m_bindingsActions->actions();
|
||||
|
||||
for (QAction *a : actions) {
|
||||
for (auto &a : actions) {
|
||||
if (a)
|
||||
a->setChecked(a->data().toString() != id);
|
||||
}
|
||||
|
@ -1448,7 +1404,7 @@ void QEditor::updateBindingsMenu() {
|
|||
|
||||
aDefaultBinding->setChecked(m_bindings.contains(m_defaultBinding));
|
||||
|
||||
for (QAction *a : actions) {
|
||||
for (auto &a : actions) {
|
||||
int idx = bindings.indexOf(a->data().toString());
|
||||
|
||||
if (idx == -1) {
|
||||
|
@ -1458,7 +1414,7 @@ void QEditor::updateBindingsMenu() {
|
|||
} else {
|
||||
bindings.removeAt(idx);
|
||||
|
||||
for (QEditorInputBindingInterface *b : m_bindings)
|
||||
for (auto &b : m_bindings)
|
||||
if (a->data().toString() == b->id())
|
||||
a->setChecked(true);
|
||||
}
|
||||
|
@ -1576,7 +1532,6 @@ void QEditor::setCursor(const QDocumentCursor &c) {
|
|||
setFlag(CursorOn, true);
|
||||
repaintCursor();
|
||||
ensureCursorVisible();
|
||||
selectionChange();
|
||||
|
||||
updateMicroFocus();
|
||||
}
|
||||
|
@ -1733,6 +1688,8 @@ void QEditor::setPlaceHolder(int i) {
|
|||
viewport()->update();
|
||||
}
|
||||
|
||||
void QEditor::setUndoRedoEnabled(bool b) { m_undoRedoEnabled = b; }
|
||||
|
||||
/*!
|
||||
\brief Move to next placeholder
|
||||
|
||||
|
@ -1884,13 +1841,12 @@ void QEditor::emitCursorPositionChanged() {
|
|||
\brief Undo the last editing operation, if any on the stack
|
||||
*/
|
||||
void QEditor::undo() {
|
||||
if (m_doc) {
|
||||
if (m_doc && m_undoRedoEnabled) {
|
||||
if (m_definition)
|
||||
m_definition->clearMatches(m_doc);
|
||||
|
||||
m_doc->undo();
|
||||
|
||||
selectionChange();
|
||||
ensureCursorVisible();
|
||||
setFlag(CursorOn, true);
|
||||
emitCursorPositionChanged();
|
||||
|
@ -1902,13 +1858,12 @@ void QEditor::undo() {
|
|||
\brief Redo the last undone editing operation, if any on the stack
|
||||
*/
|
||||
void QEditor::redo() {
|
||||
if (m_doc) {
|
||||
if (m_doc && m_undoRedoEnabled) {
|
||||
if (m_definition)
|
||||
m_definition->clearMatches(m_doc);
|
||||
|
||||
m_doc->redo();
|
||||
|
||||
selectionChange();
|
||||
ensureCursorVisible();
|
||||
setFlag(CursorOn, true);
|
||||
emitCursorPositionChanged();
|
||||
|
@ -1972,34 +1927,6 @@ void QEditor::paste() {
|
|||
insertFromMimeData(d);
|
||||
}
|
||||
|
||||
static bool unindent(const QDocumentCursor &cur) {
|
||||
QDocumentLine beg(cur.line());
|
||||
int r = 0, n = 0, t = QDocument::tabStop();
|
||||
QString txt = beg.text().left(beg.firstChar());
|
||||
|
||||
while (txt.size() && (n < t)) {
|
||||
if (txt.at(txt.length() - 1) == '\t')
|
||||
n += t - (n % t);
|
||||
else
|
||||
++n;
|
||||
|
||||
++r;
|
||||
txt.chop(1);
|
||||
}
|
||||
|
||||
if (!r)
|
||||
return false;
|
||||
|
||||
QDocumentCursor c(cur);
|
||||
c.setSilent(true);
|
||||
c.movePosition(1, QDocumentCursor::StartOfBlock,
|
||||
QDocumentCursor::MoveAnchor);
|
||||
c.movePosition(r, QDocumentCursor::Right, QDocumentCursor::KeepAnchor);
|
||||
c.removeSelectedText();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void insert(const QDocumentCursor &cur, const QString &txt) {
|
||||
QDocumentCursor c(cur);
|
||||
c.setSilent(true);
|
||||
|
@ -2036,7 +1963,7 @@ void QEditor::indentSelection() {
|
|||
if (!protectedCursor(m_cursor))
|
||||
insert(m_cursor, txt);
|
||||
|
||||
for (const QDocumentCursor &m : m_mirrors)
|
||||
for (auto &m : m_mirrors)
|
||||
if (!protectedCursor(m))
|
||||
insert(m, txt);
|
||||
|
||||
|
@ -2076,7 +2003,7 @@ void QEditor::unindentSelection() {
|
|||
if (!protectedCursor(m_cursor))
|
||||
unindent(m_cursor);
|
||||
|
||||
for (const QDocumentCursor &m : m_mirrors)
|
||||
for (auto &m : m_mirrors)
|
||||
unindent(m);
|
||||
|
||||
m_doc->endMacro();
|
||||
|
@ -2115,7 +2042,7 @@ void QEditor::commentSelection() {
|
|||
if (!protectedCursor(m_cursor))
|
||||
insert(m_cursor, txt);
|
||||
|
||||
for (const QDocumentCursor &m : m_mirrors)
|
||||
for (auto &m : m_mirrors)
|
||||
if (!protectedCursor(m))
|
||||
insert(m, txt);
|
||||
|
||||
|
@ -2161,7 +2088,7 @@ void QEditor::uncommentSelection() {
|
|||
if (!protectedCursor(m_cursor))
|
||||
removeFromStart(m_cursor, txt);
|
||||
|
||||
for (const QDocumentCursor &m : m_mirrors)
|
||||
for (auto &m : m_mirrors)
|
||||
if (!protectedCursor(m))
|
||||
removeFromStart(m, txt);
|
||||
|
||||
|
@ -2193,7 +2120,6 @@ void QEditor::selectAll() {
|
|||
m_cursor.movePosition(1, QDocumentCursor::End, QDocumentCursor::KeepAnchor);
|
||||
|
||||
emitCursorPositionChanged();
|
||||
selectionChange(true);
|
||||
|
||||
viewport()->update();
|
||||
}
|
||||
|
@ -2259,7 +2185,7 @@ void QEditor::paintEvent(QPaintEvent *e) {
|
|||
}
|
||||
|
||||
// cursor mirrors :D
|
||||
for (const QDocumentCursor &m : m_mirrors) {
|
||||
for (auto &m : m_mirrors) {
|
||||
if (ctx.blinkingCursor)
|
||||
ctx.extra << m.handle();
|
||||
|
||||
|
@ -2371,7 +2297,12 @@ bool QEditor::protectedCursor(const QDocumentCursor &c) const {
|
|||
\internal
|
||||
*/
|
||||
void QEditor::keyPressEvent(QKeyEvent *e) {
|
||||
for (QEditorInputBindingInterface *b : m_bindings)
|
||||
if (flag(ReadOnly)) {
|
||||
e->ignore();
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto &b : m_bindings)
|
||||
if (b->keyPressEvent(e, this))
|
||||
return;
|
||||
|
||||
|
@ -2412,8 +2343,6 @@ void QEditor::keyPressEvent(QKeyEvent *e) {
|
|||
}
|
||||
}
|
||||
|
||||
selectionChange();
|
||||
|
||||
// placeholders handling
|
||||
bool bHandled = false;
|
||||
|
||||
|
@ -2481,7 +2410,6 @@ void QEditor::keyPressEvent(QKeyEvent *e) {
|
|||
viewport()->update();
|
||||
} else {
|
||||
repaintCursor();
|
||||
selectionChange();
|
||||
}
|
||||
|
||||
bHandled = true;
|
||||
|
@ -2494,7 +2422,7 @@ void QEditor::keyPressEvent(QKeyEvent *e) {
|
|||
bool pke = isProcessingKeyEvent(e, &offset);
|
||||
bool prot = protectedCursor(m_cursor);
|
||||
|
||||
for (const QDocumentCursor &c : m_mirrors)
|
||||
for (auto &c : m_mirrors)
|
||||
prot |= protectedCursor(c);
|
||||
|
||||
if (!pke || prot) {
|
||||
|
@ -2567,11 +2495,11 @@ void QEditor::keyPressEvent(QKeyEvent *e) {
|
|||
setFlag(CursorOn, true);
|
||||
ensureCursorVisible();
|
||||
repaintCursor();
|
||||
selectionChange();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
for (QEditorInputBindingInterface *b : m_bindings)
|
||||
for (auto &b : m_bindings)
|
||||
b->postKeyPressEvent(e, this);
|
||||
}
|
||||
|
||||
|
@ -2579,17 +2507,14 @@ void QEditor::keyPressEvent(QKeyEvent *e) {
|
|||
\internal
|
||||
*/
|
||||
void QEditor::inputMethodEvent(QInputMethodEvent *e) {
|
||||
for (QEditorInputBindingInterface *b : m_bindings)
|
||||
for (auto &b : m_bindings)
|
||||
if (b->inputMethodEvent(e, this))
|
||||
return;
|
||||
|
||||
/*
|
||||
if ( m_doc->readOnly() )
|
||||
{
|
||||
e->ignore();
|
||||
return;
|
||||
if (flag(ReadOnly)) {
|
||||
e->ignore();
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
m_cursor.beginEditBlock();
|
||||
|
||||
|
@ -2598,7 +2523,7 @@ void QEditor::inputMethodEvent(QInputMethodEvent *e) {
|
|||
|
||||
m_cursor.endEditBlock();
|
||||
|
||||
for (QEditorInputBindingInterface *b : m_bindings)
|
||||
for (auto &b : m_bindings)
|
||||
b->postInputMethodEvent(e, this);
|
||||
}
|
||||
|
||||
|
@ -2606,7 +2531,7 @@ void QEditor::inputMethodEvent(QInputMethodEvent *e) {
|
|||
\internal
|
||||
*/
|
||||
void QEditor::mouseMoveEvent(QMouseEvent *e) {
|
||||
for (QEditorInputBindingInterface *b : m_bindings)
|
||||
for (auto &b : m_bindings)
|
||||
if (b->mouseMoveEvent(e, this))
|
||||
return;
|
||||
|
||||
|
@ -2634,7 +2559,6 @@ void QEditor::mouseMoveEvent(QMouseEvent *e) {
|
|||
}
|
||||
|
||||
repaintCursor();
|
||||
selectionChange();
|
||||
|
||||
const QPoint mousePos = mapToContents(e->pos());
|
||||
|
||||
|
@ -2684,7 +2608,6 @@ void QEditor::mouseMoveEvent(QMouseEvent *e) {
|
|||
// setFlag(FoldedCursor, isCollapsed());
|
||||
}
|
||||
|
||||
selectionChange(true);
|
||||
ensureCursorVisible();
|
||||
// emit clearAutoCloseStack();
|
||||
emitCursorPositionChanged();
|
||||
|
@ -2693,7 +2616,7 @@ void QEditor::mouseMoveEvent(QMouseEvent *e) {
|
|||
break;
|
||||
}
|
||||
|
||||
for (QEditorInputBindingInterface *b : m_bindings)
|
||||
for (auto &b : m_bindings)
|
||||
b->postMouseMoveEvent(e, this);
|
||||
}
|
||||
|
||||
|
@ -2701,7 +2624,7 @@ void QEditor::mouseMoveEvent(QMouseEvent *e) {
|
|||
\internal
|
||||
*/
|
||||
void QEditor::mousePressEvent(QMouseEvent *e) {
|
||||
for (QEditorInputBindingInterface *b : m_bindings)
|
||||
for (auto &b : m_bindings)
|
||||
if (b->mousePressEvent(e, this))
|
||||
return;
|
||||
|
||||
|
@ -2715,7 +2638,6 @@ void QEditor::mousePressEvent(QMouseEvent *e) {
|
|||
setFlag(MaybeDrag, false);
|
||||
|
||||
repaintCursor();
|
||||
selectionChange();
|
||||
|
||||
if (m_click.isActive() &&
|
||||
((
|
||||
|
@ -2819,7 +2741,7 @@ void QEditor::mousePressEvent(QMouseEvent *e) {
|
|||
// emit clearAutoCloseStack();
|
||||
emitCursorPositionChanged();
|
||||
repaintCursor();
|
||||
selectionChange();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2838,7 +2760,6 @@ void QEditor::mouseReleaseEvent(QMouseEvent *e) {
|
|||
m_scroll.stop();
|
||||
|
||||
repaintCursor();
|
||||
selectionChange();
|
||||
|
||||
if (flag(MaybeDrag)) {
|
||||
setFlag(MousePressed, false);
|
||||
|
@ -2868,9 +2789,7 @@ void QEditor::mouseReleaseEvent(QMouseEvent *e) {
|
|||
if (m_drag.isActive())
|
||||
m_drag.stop();
|
||||
|
||||
selectionChange();
|
||||
|
||||
for (QEditorInputBindingInterface *b : m_bindings)
|
||||
for (auto &b : m_bindings)
|
||||
b->postMouseReleaseEvent(e, this);
|
||||
}
|
||||
|
||||
|
@ -2878,7 +2797,7 @@ void QEditor::mouseReleaseEvent(QMouseEvent *e) {
|
|||
\internal
|
||||
*/
|
||||
void QEditor::mouseDoubleClickEvent(QMouseEvent *e) {
|
||||
for (QEditorInputBindingInterface *b : m_bindings)
|
||||
for (auto &b : m_bindings)
|
||||
if (b->mouseDoubleClickEvent(e, this))
|
||||
return;
|
||||
|
||||
|
@ -2891,7 +2810,7 @@ void QEditor::mouseDoubleClickEvent(QMouseEvent *e) {
|
|||
setFlag(MaybeDrag, false);
|
||||
|
||||
repaintCursor();
|
||||
selectionChange();
|
||||
|
||||
clearCursorMirrors();
|
||||
setCursorPosition(mapToContents(e->pos()));
|
||||
|
||||
|
@ -2905,7 +2824,7 @@ void QEditor::mouseDoubleClickEvent(QMouseEvent *e) {
|
|||
emitCursorPositionChanged();
|
||||
|
||||
repaintCursor();
|
||||
selectionChange();
|
||||
|
||||
} else {
|
||||
// qDebug("invalid cursor");
|
||||
}
|
||||
|
@ -3037,8 +2956,6 @@ void QEditor::dropEvent(QDropEvent *e) {
|
|||
// m_cursor.endEditBlock();
|
||||
|
||||
m_doc->endMacro();
|
||||
|
||||
selectionChange();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -3163,46 +3080,17 @@ void QEditor::contextMenuEvent(QContextMenuEvent *e) {
|
|||
return;
|
||||
}
|
||||
|
||||
selectionChange();
|
||||
|
||||
e->accept();
|
||||
|
||||
pMenu->exec(e->globalPos());
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Close event
|
||||
|
||||
When build with qmdilib support (e.g in Edyuk) this check for
|
||||
modifications and a dialog pops up to offer various options
|
||||
(like saving, discarding or canceling)
|
||||
*/
|
||||
void QEditor::closeEvent(QCloseEvent *e) {
|
||||
#ifdef _QMDI_
|
||||
bool bOK = true;
|
||||
|
||||
if (isContentModified())
|
||||
bOK = server()->maybeSave(this);
|
||||
|
||||
if (bOK) {
|
||||
e->accept();
|
||||
notifyDeletion();
|
||||
} else {
|
||||
e->ignore();
|
||||
}
|
||||
#else
|
||||
QAbstractScrollArea::closeEvent(e);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef _QMDI_
|
||||
/*!
|
||||
\return Whether the document has been modified.
|
||||
*/
|
||||
bool QEditor::isContentModified() const {
|
||||
return m_doc ? !m_doc->isClean() : false;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
\brief Notify that the content is clean (modifications undone or
|
||||
|
@ -3218,10 +3106,6 @@ void QEditor::setContentClean(bool y) { setContentModified(!y); }
|
|||
\note Don't mess with this. The document knows better.
|
||||
*/
|
||||
void QEditor::setContentModified(bool y) {
|
||||
#ifdef _QMDI_
|
||||
qmdiClient::setContentModified(y);
|
||||
#endif
|
||||
|
||||
setWindowModified(y);
|
||||
emit contentModified(y);
|
||||
}
|
||||
|
@ -3246,12 +3130,8 @@ void QEditor::setFileName(const QString &f) {
|
|||
|
||||
watcher()->removeWatch(QString(), this);
|
||||
|
||||
#ifdef _QMDI_
|
||||
qmdiClient::setFileName(f);
|
||||
#else
|
||||
m_fileName = f;
|
||||
m_name = QFileInfo(f).fileName();
|
||||
#endif
|
||||
|
||||
// if ( fileName().count() )
|
||||
// m_watcher->addPath(fileName());
|
||||
|
@ -3278,7 +3158,6 @@ void QEditor::setTitle(const QString &title) {
|
|||
emit titleChanged(title);
|
||||
}
|
||||
|
||||
#ifndef _QMDI_
|
||||
/*!
|
||||
\return The name of the file being edited (without its path)
|
||||
*/
|
||||
|
@ -3288,7 +3167,6 @@ QString QEditor::name() const { return m_name; }
|
|||
\return The full filename of the file being edited
|
||||
*/
|
||||
QString QEditor::fileName() const { return m_fileName; }
|
||||
#endif
|
||||
|
||||
/*!
|
||||
\brief Prevent tab key press to be considered as widget navigation
|
||||
|
@ -3567,7 +3445,7 @@ void QEditor::pageUp(QDocumentCursor::MoveMode moveMode) {
|
|||
if (m_cursor.atStart())
|
||||
return;
|
||||
|
||||
int n = viewport()->height() / QDocument::fontMetrics().lineSpacing();
|
||||
int n = viewport()->height() / m_doc->fontMetrics().lineSpacing();
|
||||
|
||||
repaintCursor();
|
||||
m_cursor.movePosition(n, QDocumentCursor::Up, moveMode);
|
||||
|
@ -3589,7 +3467,7 @@ void QEditor::pageDown(QDocumentCursor::MoveMode moveMode) {
|
|||
if (m_cursor.atEnd())
|
||||
return;
|
||||
|
||||
int n = viewport()->height() / QDocument::fontMetrics().lineSpacing();
|
||||
int n = viewport()->height() / m_doc->fontMetrics().lineSpacing();
|
||||
|
||||
repaintCursor();
|
||||
m_cursor.movePosition(n, QDocumentCursor::Down, moveMode);
|
||||
|
@ -3734,8 +3612,6 @@ bool QEditor::processCursor(QDocumentCursor &c, QKeyEvent *e, bool &b) {
|
|||
}
|
||||
}
|
||||
|
||||
selectionChange();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -3789,7 +3665,8 @@ void QEditor::preInsert(QDocumentCursor &c, const QString &s) {
|
|||
This function is provided to keep indenting/outdenting working when
|
||||
editing
|
||||
*/
|
||||
void QEditor::insertText(QDocumentCursor &c, const QString &text) {
|
||||
void QEditor::insertText(QDocumentCursor &c, const QString &text,
|
||||
const QString &sfmtID) {
|
||||
if (protectedCursor(c))
|
||||
return;
|
||||
|
||||
|
@ -3810,11 +3687,11 @@ void QEditor::insertText(QDocumentCursor &c, const QString &text) {
|
|||
// TODO : replace tabs by spaces properly
|
||||
}
|
||||
|
||||
c.insertText(text);
|
||||
c.insertText(text, false, sfmtID);
|
||||
} else {
|
||||
|
||||
preInsert(c, lines.first());
|
||||
c.insertText(lines.takeFirst());
|
||||
c.insertText(lines.takeFirst(), false, sfmtID);
|
||||
|
||||
QString indent;
|
||||
// FIXME ? work on strings to make sure command grouping does not
|
||||
|
@ -3841,11 +3718,11 @@ void QEditor::insertText(QDocumentCursor &c, const QString &text) {
|
|||
}
|
||||
|
||||
c.insertLine();
|
||||
c.insertText(indent);
|
||||
c.insertText(indent, false, sfmtID);
|
||||
|
||||
preInsert(c, l);
|
||||
|
||||
c.insertText(l);
|
||||
c.insertText(l, false, sfmtID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3857,13 +3734,13 @@ void QEditor::insertText(QDocumentCursor &c, const QString &text) {
|
|||
from the outside and to keep them compatible with cursor
|
||||
mirrors.
|
||||
*/
|
||||
void QEditor::write(const QString &s) {
|
||||
void QEditor::write(const QString &s, const QString &sfmtID) {
|
||||
m_doc->beginMacro();
|
||||
|
||||
insertText(m_cursor, s);
|
||||
insertText(m_cursor, s, sfmtID);
|
||||
|
||||
for (int i = 0; i < m_mirrors.count(); ++i)
|
||||
insertText(m_mirrors[i], s);
|
||||
insertText(m_mirrors[i], s, sfmtID);
|
||||
|
||||
m_doc->endMacro();
|
||||
|
||||
|
@ -3871,7 +3748,6 @@ void QEditor::write(const QString &s) {
|
|||
setFlag(CursorOn, true);
|
||||
ensureCursorVisible();
|
||||
repaintCursor();
|
||||
selectionChange();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -3903,26 +3779,6 @@ void QEditor::setPanelMargins(int l, int t, int r, int b) {
|
|||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\deprecated
|
||||
\brief Does not do anything anymore...
|
||||
*/
|
||||
void QEditor::selectionChange(bool force) {
|
||||
Q_UNUSED(force)
|
||||
// TODO : repaint only selection rect
|
||||
/*
|
||||
if ( false )//force )
|
||||
{
|
||||
//qDebug("repainting selection... [%i]", force);
|
||||
viewport()->update();
|
||||
} else if ( m_cursor.hasSelection() ) {
|
||||
viewport()->update(selectionRect());
|
||||
}
|
||||
|
||||
m_selection = m_cursor.hasSelection();
|
||||
*/
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Request repaint (using QWidget::update()) for the region occupied
|
||||
by the cursor
|
||||
|
@ -3948,8 +3804,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());
|
||||
|
||||
|
@ -3969,7 +3825,7 @@ void QEditor::ensureCursorVisible() {
|
|||
|
||||
QPoint pos = m_cursor.documentPosition();
|
||||
|
||||
const int ls = QDocument::fontMetrics().lineSpacing();
|
||||
const int ls = m_doc->fontMetrics().lineSpacing();
|
||||
|
||||
int ypos = pos.y(), yval = verticalOffset(), ylen = viewport()->height(),
|
||||
yend = ypos + ls;
|
||||
|
@ -4001,7 +3857,7 @@ void QEditor::ensureVisible(int line) {
|
|||
if (!m_doc)
|
||||
return;
|
||||
|
||||
const int ls = QDocument::fontMetrics().lineSpacing();
|
||||
const int ls = m_doc->fontMetrics().lineSpacing();
|
||||
int ypos = m_doc->y(line), yval = verticalOffset(),
|
||||
ylen = viewport()->height(), yend = ypos + ls;
|
||||
|
||||
|
@ -4019,7 +3875,7 @@ void QEditor::ensureVisible(const QRect &rect) {
|
|||
if (!m_doc)
|
||||
return;
|
||||
|
||||
const int ls = QDocument::fontMetrics().lineSpacing();
|
||||
const int ls = m_doc->fontMetrics().lineSpacing();
|
||||
int ypos = rect.y(), yval = verticalOffset(), ylen = viewport()->height(),
|
||||
yend = ypos + rect.height();
|
||||
|
||||
|
@ -4047,7 +3903,8 @@ void QEditor::ensureVisible(const QRect &rect) {
|
|||
background whenever the cursor move from a line to another.
|
||||
*/
|
||||
QRect QEditor::cursorRect() const {
|
||||
return m_cursor.hasSelection() ? selectionRect() : cursorRect(m_cursor);
|
||||
return m_cursor.hasSelection() ? selectionRect()
|
||||
: QEditor::cursorRect(m_cursor);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -4062,13 +3919,14 @@ QRect QEditor::cursorRect() const {
|
|||
*/
|
||||
QRect QEditor::selectionRect() const {
|
||||
if (!m_cursor.hasSelection())
|
||||
return cursorRect(m_cursor);
|
||||
return QEditor::cursorRect(m_cursor);
|
||||
|
||||
QDocumentSelection s = m_cursor.selection();
|
||||
|
||||
if (s.startLine == s.endLine)
|
||||
return cursorRect(m_cursor);
|
||||
return QEditor::cursorRect(m_cursor);
|
||||
|
||||
Q_ASSERT(m_doc);
|
||||
int y = m_doc->y(s.startLine);
|
||||
QRect r = m_doc->lineRect(s.endLine);
|
||||
int height = r.y() + r.height() - y;
|
||||
|
@ -4119,7 +3977,7 @@ QRect QEditor::lineRect(const QDocumentLine &l) const {
|
|||
\return The line rect of the given cursor
|
||||
*/
|
||||
QRect QEditor::cursorRect(const QDocumentCursor &c) const {
|
||||
return lineRect(c.lineNumber());
|
||||
return QEditor::lineRect(c.lineNumber()).adjusted(0, -1, 0, 1);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -4279,6 +4137,36 @@ void QEditor::addCursorMirror(const QDocumentCursor &c) {
|
|||
m_mirrors.last().setAutoUpdated(true);
|
||||
}
|
||||
|
||||
bool QEditor::undoRedoEnabled() const { return m_undoRedoEnabled; }
|
||||
|
||||
bool QEditor::unindent(const QDocumentCursor &cur) {
|
||||
QDocumentLine beg(cur.line());
|
||||
int r = 0, n = 0, t = m_doc->tabStop();
|
||||
QString txt = beg.text().left(beg.firstChar());
|
||||
|
||||
while (txt.size() && (n < t)) {
|
||||
if (txt.at(txt.length() - 1) == '\t')
|
||||
n += t - (n % t);
|
||||
else
|
||||
++n;
|
||||
|
||||
++r;
|
||||
txt.chop(1);
|
||||
}
|
||||
|
||||
if (!r)
|
||||
return false;
|
||||
|
||||
QDocumentCursor c(cur);
|
||||
c.setSilent(true);
|
||||
c.movePosition(1, QDocumentCursor::StartOfBlock,
|
||||
QDocumentCursor::MoveAnchor);
|
||||
c.movePosition(r, QDocumentCursor::Right, QDocumentCursor::KeepAnchor);
|
||||
c.removeSelectedText();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
\brief Copy the selection to the clipboard
|
||||
|
@ -4443,7 +4331,7 @@ void QEditor::updateContent(int i, int n) {
|
|||
/*!
|
||||
\internal
|
||||
*/
|
||||
void QEditor::markChanged(QDocumentLineHandle *l, int mark, bool on) {
|
||||
void QEditor::emitMarkChanged(QDocumentLineHandle *l, int mark, bool on) {
|
||||
emit markChanged(fileName(), l, mark, on);
|
||||
}
|
||||
|
||||
|
|
|
@ -33,10 +33,6 @@
|
|||
#include "qdocument.h"
|
||||
#include "qdocumentcursor.h"
|
||||
|
||||
#ifdef _QMDI_
|
||||
#include "qmdiclient.h"
|
||||
#endif
|
||||
|
||||
class QMenu;
|
||||
class QAction;
|
||||
class QMimeData;
|
||||
|
@ -51,12 +47,7 @@ class QCodeCompletionEngine;
|
|||
|
||||
class QEditorInputBindingInterface;
|
||||
|
||||
class QCE_EXPORT QEditor : public QAbstractScrollArea
|
||||
#ifdef _QMDI_
|
||||
,
|
||||
public qmdiClient
|
||||
#endif
|
||||
{
|
||||
class QCE_EXPORT QEditor : public QAbstractScrollArea {
|
||||
friend class QEditConfig;
|
||||
friend class QEditorFactory;
|
||||
|
||||
|
@ -165,12 +156,10 @@ public:
|
|||
virtual QRect lineRect(const QDocumentLine &l) const;
|
||||
virtual QRect cursorRect(const QDocumentCursor &c) const;
|
||||
|
||||
#ifndef _QMDI_
|
||||
QString name() const;
|
||||
QString fileName() const;
|
||||
|
||||
bool isContentModified() const;
|
||||
#endif
|
||||
|
||||
bool isInConflict() const;
|
||||
|
||||
|
@ -248,7 +237,7 @@ public slots:
|
|||
|
||||
virtual void retranslate();
|
||||
|
||||
virtual void write(const QString &s);
|
||||
virtual void write(const QString &s, const QString &sfmtID = {});
|
||||
|
||||
void addAction(QAction *a, const QString &menu,
|
||||
const QString &toolbar = QString());
|
||||
|
@ -274,8 +263,6 @@ public slots:
|
|||
|
||||
void setScaleRate(qreal rate);
|
||||
|
||||
qreal scaleRate() const;
|
||||
|
||||
void setPanelMargins(int l, int t, int r, int b);
|
||||
void getPanelMargins(int *l, int *t, int *r, int *b) const;
|
||||
|
||||
|
@ -285,17 +272,21 @@ public slots:
|
|||
|
||||
void clearPlaceHolders();
|
||||
void removePlaceHolder(int i);
|
||||
void addPlaceHolder(const PlaceHolder &p, bool autoUpdate = true);
|
||||
|
||||
int placeHolderCount() const;
|
||||
int currentPlaceHolder() const;
|
||||
void addPlaceHolder(const QEditor::PlaceHolder &p, bool autoUpdate = true);
|
||||
|
||||
void nextPlaceHolder();
|
||||
void previousPlaceHolder();
|
||||
void setPlaceHolder(int i);
|
||||
|
||||
void setUndoRedoEnabled(bool b);
|
||||
|
||||
virtual void setFileName(const QString &f);
|
||||
|
||||
public:
|
||||
int placeHolderCount() const;
|
||||
int currentPlaceHolder() const;
|
||||
qreal scaleRate() const;
|
||||
|
||||
signals:
|
||||
void loaded(QEditor *e, const QString &s);
|
||||
void saved(QEditor *e, const QString &s);
|
||||
|
@ -356,8 +347,6 @@ protected:
|
|||
|
||||
virtual void contextMenuEvent(QContextMenuEvent *e);
|
||||
|
||||
virtual void closeEvent(QCloseEvent *e);
|
||||
|
||||
virtual bool focusNextPrevChild(bool next);
|
||||
|
||||
virtual bool moveKeyEvent(QDocumentCursor &c, QKeyEvent *e, bool *leave);
|
||||
|
@ -377,15 +366,14 @@ public:
|
|||
void pageUp(QDocumentCursor::MoveMode moveMode);
|
||||
void pageDown(QDocumentCursor::MoveMode moveMode);
|
||||
|
||||
void selectionChange(bool force = false);
|
||||
|
||||
void repaintCursor();
|
||||
void ensureCursorVisible();
|
||||
void ensureVisible(int line);
|
||||
void ensureVisible(const QRect &rect);
|
||||
|
||||
void preInsert(QDocumentCursor &c, const QString &text);
|
||||
void insertText(QDocumentCursor &c, const QString &text);
|
||||
void insertText(QDocumentCursor &c, const QString &text,
|
||||
const QString &sfmtID = {});
|
||||
|
||||
QDocumentLine lineAtPosition(const QPoint &p) const;
|
||||
QDocumentCursor cursorForPosition(const QPoint &p) const;
|
||||
|
@ -399,6 +387,11 @@ public:
|
|||
void clearCursorMirrors();
|
||||
void addCursorMirror(const QDocumentCursor &c);
|
||||
|
||||
bool undoRedoEnabled() const;
|
||||
|
||||
private:
|
||||
bool unindent(const QDocumentCursor &cur);
|
||||
|
||||
protected slots:
|
||||
void documentWidthChanged(int newWidth);
|
||||
void documentHeightChanged(int newWidth);
|
||||
|
@ -406,7 +399,7 @@ protected slots:
|
|||
void repaintContent(int i, int n);
|
||||
void updateContent(int i, int n);
|
||||
|
||||
void markChanged(QDocumentLineHandle *l, int mark, bool on);
|
||||
void emitMarkChanged(QDocumentLineHandle *l, int mark, bool on);
|
||||
|
||||
void bindingSelected(QAction *a);
|
||||
|
||||
|
@ -419,9 +412,7 @@ protected:
|
|||
void init(bool actions = true);
|
||||
void updateBindingsMenu();
|
||||
|
||||
#ifndef _QMDI_
|
||||
QString m_name, m_fileName;
|
||||
#endif
|
||||
|
||||
QMenu *pMenu;
|
||||
QHash<QString, QAction *> m_actions;
|
||||
|
@ -450,6 +441,8 @@ protected:
|
|||
int m_curPlaceHolder, m_cphOffset;
|
||||
QList<PlaceHolder> m_placeHolders;
|
||||
|
||||
bool m_undoRedoEnabled = true;
|
||||
|
||||
int m_state;
|
||||
bool m_selection;
|
||||
QRect m_crect, m_margins;
|
||||
|
|
|
@ -516,7 +516,7 @@ void QLineMarksInfoCenter::cursorMoved(QEditor *e) {
|
|||
\internal
|
||||
*/
|
||||
void QLineMarksInfoCenter::lineDeleted(QDocumentLineHandle *h) {
|
||||
QLineMarkHandleList::iterator i = m_lineMarks.begin();
|
||||
auto i = m_lineMarks.begin();
|
||||
|
||||
while (i != m_lineMarks.end()) {
|
||||
if (i->line == h) {
|
||||
|
|
|
@ -156,6 +156,8 @@ public slots:
|
|||
void toggleLineMark(const QLineMarkHandle &mark);
|
||||
void removeLineMark(const QLineMarkHandle &mark);
|
||||
|
||||
void lineDeleted(QDocumentLineHandle *h);
|
||||
|
||||
void flush(const QString &file);
|
||||
|
||||
signals:
|
||||
|
@ -168,7 +170,6 @@ protected:
|
|||
|
||||
protected slots:
|
||||
void cursorMoved(QEditor *e);
|
||||
void lineDeleted(QDocumentLineHandle *h);
|
||||
void markChanged(const QString &f, QDocumentLineHandle *h, int mark,
|
||||
bool on);
|
||||
|
||||
|
|
|
@ -243,17 +243,12 @@ QLayoutItem *QPanelLayout::takeAt(int idx) {
|
|||
\internal
|
||||
*/
|
||||
void QPanelLayout::setGeometry(const QRect &r) {
|
||||
// qDebug("laying out %i panels", count());
|
||||
#ifdef _PANEL_POSITION_FIX_
|
||||
QScrollBar *vb = m_parent->verticalScrollBar(),
|
||||
*hb = m_parent->horizontalScrollBar();
|
||||
|
||||
QRect rect(r.x(), r.y(),
|
||||
r.width() - (vb->isVisibleTo(m_parent) ? vb->width() : 0),
|
||||
r.height() - (hb->isVisibleTo(m_parent) ? hb->height() : 0));
|
||||
#else
|
||||
QRect rect(r.x(), r.y(), r.width(), r.height());
|
||||
#endif
|
||||
|
||||
int i, eastWidth = 0, westWidth = 0, northHeight = 0, southHeight = 0,
|
||||
centerHeight = 0;
|
||||
|
|
|
@ -69,7 +69,7 @@ void QSnippetManager::removeSnippet(int i, bool cleanup) {
|
|||
|
||||
QSnippet *snip = m_snippets.takeAt(i);
|
||||
|
||||
emit snippetRemoved(i);
|
||||
emit snippetRemovedByIndex(i);
|
||||
emit snippetRemoved(snip);
|
||||
|
||||
if (cleanup)
|
||||
|
@ -84,7 +84,7 @@ void QSnippetManager::removeSnippet(QSnippet *snip) {
|
|||
|
||||
m_snippets.removeAt(idx);
|
||||
|
||||
emit snippetRemoved(idx);
|
||||
emit snippetRemovedByIndex(idx);
|
||||
emit snippetRemoved(snip);
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ class QCE_EXPORT QSnippetManager : public QObject {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QSnippetManager(QObject *p = 0);
|
||||
explicit QSnippetManager(QObject *p = nullptr);
|
||||
virtual ~QSnippetManager();
|
||||
|
||||
int snippetCount() const;
|
||||
|
@ -58,7 +58,7 @@ public slots:
|
|||
signals:
|
||||
void snippetAdded(QSnippet *s);
|
||||
|
||||
void snippetRemoved(int i);
|
||||
void snippetRemovedByIndex(int i);
|
||||
void snippetRemoved(QSnippet *s);
|
||||
|
||||
private:
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -73,8 +73,6 @@ void QLineChangePanel::paint(QPainter *p, QEditor *e) {
|
|||
pageBottom = e->viewport()->height(),
|
||||
contentsY = e->verticalOffset();
|
||||
|
||||
QString txt;
|
||||
|
||||
QDocument *d = e->document();
|
||||
n = d->lineNumber(contentsY);
|
||||
posY = 2 + d->y(n) - contentsY;
|
||||
|
|
|
@ -82,17 +82,17 @@ void QLineNumberPanel::editorChange(QEditor *e) {
|
|||
}
|
||||
|
||||
if (e) {
|
||||
setFixedWidth(
|
||||
_fixWidth =
|
||||
QFontMetrics(e->document()->font())
|
||||
.horizontalAdvance(QString::number(e->document()->lines())) +
|
||||
5);
|
||||
5;
|
||||
|
||||
connect(e, SIGNAL(cursorPositionChanged()), this, SLOT(update()));
|
||||
connect(e, &QEditor::zoomed, this, [=] {
|
||||
setFixedWidth(QFontMetrics(e->document()->font())
|
||||
.horizontalAdvance(
|
||||
QString::number(e->document()->lines())) +
|
||||
5);
|
||||
_fixWidth = QFontMetrics(e->document()->font())
|
||||
.horizontalAdvance(
|
||||
QString::number(e->document()->lines())) +
|
||||
5;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -228,3 +228,5 @@ void QLineNumberPanel::paint(QPainter *p, QEditor *e) {
|
|||
}
|
||||
|
||||
/*! @} */
|
||||
|
||||
QSize QLineNumberPanel::sizeHint() const { return QSize(_fixWidth, 0); }
|
||||
|
|
|
@ -38,6 +38,8 @@ public:
|
|||
|
||||
virtual QString type() const;
|
||||
|
||||
virtual QSize sizeHint() const;
|
||||
|
||||
public slots:
|
||||
void setVerboseMode(bool y);
|
||||
|
||||
|
@ -47,6 +49,7 @@ protected:
|
|||
|
||||
bool m_verbose;
|
||||
int mutable m_minWidth = 0;
|
||||
int _fixWidth = 0;
|
||||
};
|
||||
|
||||
#endif // _QLINE_NUMBER_PANEL_H_
|
||||
|
|
|
@ -8,7 +8,7 @@ set(CMAKE_AUTORCC ON)
|
|||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(PROJECT_VERSION 1.0.0)
|
||||
set(PROJECT_VERSION "2.0.0-WIP")
|
||||
|
||||
find_package(
|
||||
QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets Network Concurrent
|
||||
|
@ -62,7 +62,6 @@ add_subdirectory(3rdparty/QHexView)
|
|||
add_subdirectory(3rdparty/qcodeedit2)
|
||||
add_subdirectory(3rdparty/Qt-Advanced-Docking-System)
|
||||
add_subdirectory(3rdparty/AngelScript/sdk/angelscript/projects/cmake)
|
||||
add_subdirectory(3rdparty/QConsoleWidget)
|
||||
add_subdirectory(3rdparty/QJsonModel)
|
||||
|
||||
set(ANGEL_SCRIPT_ADDON_ROOT
|
||||
|
@ -114,6 +113,12 @@ set(RIBBON_SRC
|
|||
set(QPATHEDIT_SRC 3rdparty/QPathEdit/qpathedit.cpp
|
||||
3rdparty/QPathEdit/qpathedit.h)
|
||||
|
||||
set(QCONSOLEWIDGET_SRC
|
||||
3rdparty/QConsoleWidget/QConsoleIODevice.cpp
|
||||
3rdparty/QConsoleWidget/QConsoleIODevice.h
|
||||
3rdparty/QConsoleWidget/QConsoleWidget.cpp
|
||||
3rdparty/QConsoleWidget/QConsoleWidget.h)
|
||||
|
||||
set(DIALOG_SRC
|
||||
src/dialog/framelessmainwindow.h
|
||||
src/dialog/framelessmainwindow.cpp
|
||||
|
@ -223,7 +228,13 @@ 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
|
||||
src/class/langservice.h
|
||||
src/class/langservice.cpp
|
||||
src/class/clangformatmanager.h
|
||||
src/class/clangformatmanager.cpp)
|
||||
|
||||
if(WINGHEX_USE_FRAMELESS)
|
||||
set(WIDGET_FRAME_SRC
|
||||
|
@ -259,6 +270,7 @@ set(MODEL_SRC
|
|||
src/model/dbgbreakpointmodel.cpp)
|
||||
|
||||
set(SETTING_SRC
|
||||
src/settings/settings.h
|
||||
src/settings/generalsettingdialog.h
|
||||
src/settings/generalsettingdialog.cpp
|
||||
src/settings/generalsettingdialog.ui
|
||||
|
@ -276,7 +288,10 @@ set(SETTING_SRC
|
|||
src/settings/scriptbehaviorsettingdialog.ui
|
||||
src/settings/othersettingsdialog.h
|
||||
src/settings/othersettingsdialog.cpp
|
||||
src/settings/othersettingsdialog.ui)
|
||||
src/settings/othersettingsdialog.ui
|
||||
src/settings/clangformatsetdialog.h
|
||||
src/settings/clangformatsetdialog.cpp
|
||||
src/settings/clangformatsetdialog.ui)
|
||||
|
||||
set(SCRIPT_ADDON_SRC
|
||||
src/scriptaddon/scriptqstring.h
|
||||
|
@ -300,19 +315,12 @@ set(CODEEDIT_WIDGET
|
|||
src/qcodeeditwidget/qeditconfig.ui
|
||||
src/qcodeeditwidget/qformatconfig.h
|
||||
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)
|
||||
src/qcodeeditwidget/qformatconfig.ui
|
||||
src/qcodeeditwidget/qsnippetedit.cpp
|
||||
src/qcodeeditwidget/qsnippetedit.h
|
||||
src/qcodeeditwidget/qsnippetedit.ui
|
||||
src/qcodeeditwidget/qdocumentswaptextcommand.h
|
||||
src/qcodeeditwidget/qdocumentswaptextcommand.cpp)
|
||||
|
||||
set(PLUGIN_SRC src/plugin/iwingplugin.h src/plugin/pluginsystem.cpp
|
||||
src/plugin/pluginsystem.h src/plugin/settingpage.h)
|
||||
|
@ -406,9 +414,9 @@ set(PROJECT_SOURCES
|
|||
main.cpp
|
||||
src/utilities.h
|
||||
src/dbghelper.h
|
||||
${QCONSOLEWIDGET_SRC}
|
||||
${QPATHEDIT_SRC}
|
||||
${WIDGET_FRAME_SRC}
|
||||
${CODE_MODEL}
|
||||
${RIBBON_SRC}
|
||||
${CLASS_SRC}
|
||||
${MODEL_SRC}
|
||||
|
@ -471,7 +479,6 @@ if(WINGHEX_USE_FRAMELESS)
|
|||
QCodeEditor2
|
||||
QJsonModel
|
||||
angelscript
|
||||
QConsoleWidget
|
||||
qt${QT_VERSION_MAJOR}advanceddocking)
|
||||
else()
|
||||
target_link_libraries(
|
||||
|
@ -488,7 +495,6 @@ else()
|
|||
QCodeEditor2
|
||||
QJsonModel
|
||||
angelscript
|
||||
QConsoleWidget
|
||||
qt${QT_VERSION_MAJOR}advanceddocking)
|
||||
endif()
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 6.7 KiB |
Binary file not shown.
After Width: | Height: | Size: 3.6 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.6 KiB |
File diff suppressed because it is too large
Load Diff
|
@ -45,7 +45,6 @@ def main():
|
|||
"folder", help="A folder that has contained the binary build")
|
||||
parser.add_argument("-c", "--cc", help="where ISCC.exe locates", default="C:\Program Files (x86)\Inno Setup 6\ISCC.exe")
|
||||
parser.add_argument("-o", "--output", help="where to put the installer")
|
||||
parser.add_argument("--no-build", action='store_false')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
|
@ -231,7 +230,7 @@ Source: {#MyAppExePath}; DestDir: "{app}"; Flags: ignoreversion
|
|||
"""
|
||||
|
||||
iss_content += r'Root: HKCR; Subkey: "*\shell\OpenWithWingHexExplorer"; ValueType: expandsz; ValueName: ""; ValueData: {cm:OpenWithWingHexExplorer}; Flags: uninsdeletekey' + '\n'
|
||||
iss_content += r'Root: HKCR; Subkey: "*\shell\WingHexExplorer"; ValueType: expandsz; ValueName: "Icon"; ValueData: {app}\{#MyAppExeName}; Flags: uninsdeletekey' + '\n'
|
||||
iss_content += r'Root: HKCR; Subkey: "*\shell\OpenWithWingHexExplorer"; ValueType: expandsz; ValueName: "Icon"; ValueData: {app}\{#MyAppExeName}; Flags: uninsdeletekey' + '\n'
|
||||
iss_content += r'Root: HKCR; Subkey: "*\shell\OpenWithWingHexExplorer\command"; ValueType: expandsz; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Flags: uninsdeletekey' + '\n'
|
||||
|
||||
iss_content += """
|
||||
|
@ -249,19 +248,18 @@ Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChang
|
|||
with codecs.open(script_src,'w', "utf-8-sig") as iss:
|
||||
iss.write(iss_content)
|
||||
|
||||
if(args.build):
|
||||
print(Fore.GREEN + ">> Copying finished, running ISCC building..." + Style.RESET_ALL)
|
||||
|
||||
pak_out = ""
|
||||
if args.output is None:
|
||||
pak_out = exeDebPath
|
||||
else:
|
||||
pak_out = args.output
|
||||
|
||||
ret = run_command_interactive([args.cc, f'/O{pak_out}', script_src])
|
||||
exit(ret)
|
||||
|
||||
exit(0)
|
||||
|
||||
print(Fore.GREEN + ">> Copying finished, running ISCC building..." + Style.RESET_ALL)
|
||||
|
||||
pak_out = ""
|
||||
if args.output is None:
|
||||
pak_out = exeDebPath
|
||||
else:
|
||||
pak_out = args.output
|
||||
|
||||
ret = run_command_interactive([args.cc, f'/O{pak_out}', script_src])
|
||||
exit(ret)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -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-cache", "/usr/share/icons/hicolor"])
|
||||
run_command_interactive(
|
||||
["update-desktop-database", "/usr/share/applications"])
|
||||
print(Fore.GREEN + ">> Installation finished..." + Style.RESET_ALL)
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
<file>images/clearhis.png</file>
|
||||
<file>images/clone.png</file>
|
||||
<file>images/closefile.png</file>
|
||||
<file>images/codefmt.png</file>
|
||||
<file>images/codeformat.png</file>
|
||||
<file>images/copy.png</file>
|
||||
<file>images/copyhex.png</file>
|
||||
<file>images/cut.png</file>
|
||||
|
@ -89,6 +91,7 @@
|
|||
<file>images/scriptfolderusr.png</file>
|
||||
<file>images/setting.png</file>
|
||||
<file>images/settingplugin.png</file>
|
||||
<file>images/snippt.png</file>
|
||||
<file>images/soft.png</file>
|
||||
<file>images/sponsor.png</file>
|
||||
<file>images/sum.png</file>
|
||||
|
@ -100,6 +103,7 @@
|
|||
<file>images/win.png</file>
|
||||
<file>images/workspace.png</file>
|
||||
<file>images/writable.png</file>
|
||||
<file>src/TESTCODE.as</file>
|
||||
</qresource>
|
||||
<qresource prefix="/qpathedit/icons">
|
||||
<file alias="dialog.ico">3rdparty/QPathEdit/Fatcow-Farm-Fresh-Dialog.ico</file>
|
||||
|
@ -114,14 +118,13 @@
|
|||
<file alias="copy.png">images/copy.png</file>
|
||||
<file alias="cut.png">images/cut.png</file>
|
||||
<file alias="find.png">images/find.png</file>
|
||||
<file alias="goto.png">images/goto.png</file>
|
||||
<file alias="paste.png">images/paste.png</file>
|
||||
<file alias="redo.png">images/redo.png</file>
|
||||
<file alias="replace.png">images/replace.png</file>
|
||||
<file alias="undo.png">images/undo.png</file>
|
||||
<file alias="goto.png">images/goto.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="/completion">
|
||||
<file>images/completion/classnew.png</file>
|
||||
<file>images/completion/CTvirtuals.png</file>
|
||||
<file>images/completion/CVclass.png</file>
|
||||
<file>images/completion/CVenum.png</file>
|
||||
|
@ -146,5 +149,6 @@
|
|||
<file>images/completion/CVstruct.png</file>
|
||||
<file>images/completion/CVtypedef.png</file>
|
||||
<file>images/completion/CVunion.png</file>
|
||||
<file>images/completion/classnew.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
#include <wingsummer>
|
||||
|
||||
class CMyClass {
|
||||
int method() { a++; return a; }
|
||||
int method() const { return a; }
|
||||
int a;
|
||||
}
|
||||
|
||||
int main() {
|
||||
// This is a script
|
||||
|
||||
for (int i = 0; i < 5; ++i){
|
||||
print("hello world!")
|
||||
}
|
||||
|
||||
print("AngelScript for WingHexExplorer2 by wingsummer.")
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
#include <QFont>
|
||||
|
||||
#include "class/clangformatmanager.h"
|
||||
#include "class/langservice.h"
|
||||
#include "class/logger.h"
|
||||
#include "languagemanager.h"
|
||||
#include "settingmanager.h"
|
||||
|
@ -58,6 +60,7 @@ AppManager::AppManager(int &argc, char *argv[])
|
|||
|
||||
SkinManager::instance();
|
||||
LanguageManager::instance();
|
||||
ClangFormatManager::instance();
|
||||
|
||||
_w = new MainWindow;
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ unsigned int asBuilder::GetSectionCount() const {
|
|||
}
|
||||
|
||||
QString asBuilder::GetSectionName(unsigned int idx) const {
|
||||
if (idx >= includedScripts.size())
|
||||
if (qsizetype(idx) >= qsizetype(includedScripts.size()))
|
||||
return {};
|
||||
|
||||
return includedScripts.at(idx);
|
||||
|
@ -189,12 +189,12 @@ int asBuilder::ProcessScriptSection(const QByteArray &script, int length,
|
|||
// shouldn't be compiled
|
||||
unsigned int pos = 0;
|
||||
int nested = 0;
|
||||
while (pos < modifiedScript.size()) {
|
||||
while (qsizetype(pos) < modifiedScript.size()) {
|
||||
asUINT len = 0;
|
||||
asETokenClass t = engine->ParseToken(modifiedScript.data() + pos,
|
||||
modifiedScript.size() - pos, &len);
|
||||
if (t == asTC_UNKNOWN && modifiedScript[pos] == '#' &&
|
||||
(pos + 1 < modifiedScript.size())) {
|
||||
(qsizetype(pos) + 1 < modifiedScript.size())) {
|
||||
int start = pos++;
|
||||
|
||||
// Is this an #if directive?
|
||||
|
@ -251,7 +251,7 @@ int asBuilder::ProcessScriptSection(const QByteArray &script, int length,
|
|||
|
||||
// Then check for meta data and pre-processor directives
|
||||
pos = 0;
|
||||
while (pos < modifiedScript.size()) {
|
||||
while (qsizetype(pos) < modifiedScript.size()) {
|
||||
asUINT len = 0;
|
||||
asETokenClass t = engine->ParseToken(modifiedScript.data() + pos,
|
||||
modifiedScript.size() - pos, &len);
|
||||
|
@ -276,7 +276,7 @@ int asBuilder::ProcessScriptSection(const QByteArray &script, int length,
|
|||
// Get the identifier after "class"
|
||||
do {
|
||||
pos += len;
|
||||
if (pos >= modifiedScript.size()) {
|
||||
if (qsizetype(pos) >= modifiedScript.size()) {
|
||||
t = asTC_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
@ -288,7 +288,7 @@ int asBuilder::ProcessScriptSection(const QByteArray &script, int length,
|
|||
currentClass = modifiedScript.mid(pos, len);
|
||||
|
||||
// Search until first { or ; is encountered
|
||||
while (pos < modifiedScript.length()) {
|
||||
while (qsizetype(pos) < modifiedScript.length()) {
|
||||
engine->ParseToken(modifiedScript.data() + pos,
|
||||
modifiedScript.size() - pos, &len);
|
||||
|
||||
|
@ -340,7 +340,7 @@ int asBuilder::ProcessScriptSection(const QByteArray &script, int length,
|
|||
(t == asTC_KEYWORD && modifiedScript.mid(pos, len) == "::"));
|
||||
|
||||
// Search until first { is encountered
|
||||
while (pos < modifiedScript.length()) {
|
||||
while (qsizetype(pos) < modifiedScript.length()) {
|
||||
engine->ParseToken(modifiedScript.data() + pos,
|
||||
modifiedScript.size() - pos, &len);
|
||||
|
||||
|
@ -359,7 +359,7 @@ int asBuilder::ProcessScriptSection(const QByteArray &script, int length,
|
|||
|
||||
// Check if end of namespace
|
||||
if (currentNamespace != "" && token == "}") {
|
||||
size_t found = currentNamespace.lastIndexOf("::");
|
||||
auto found = currentNamespace.lastIndexOf("::");
|
||||
if (found >= 0) {
|
||||
currentNamespace.remove(found, currentNamespace.size() - found);
|
||||
} else {
|
||||
|
@ -388,39 +388,85 @@ int asBuilder::ProcessScriptSection(const QByteArray &script, int length,
|
|||
} else
|
||||
#endif
|
||||
// Is this a preprocessor directive?
|
||||
if (token == "#" && (pos + 1 < modifiedScript.size())) {
|
||||
int start = pos++;
|
||||
if (token == "#" && (qsizetype(pos + 1) < modifiedScript.size())) {
|
||||
int start = pos++;
|
||||
|
||||
t = engine->ParseToken(modifiedScript.data() + pos,
|
||||
modifiedScript.size() - pos, &len);
|
||||
if (t == asTC_IDENTIFIER) {
|
||||
token = modifiedScript.mid(pos, len);
|
||||
if (token == "include") {
|
||||
t = engine->ParseToken(modifiedScript.data() + pos,
|
||||
modifiedScript.size() - pos, &len);
|
||||
if (t == asTC_IDENTIFIER) {
|
||||
token = modifiedScript.mid(pos, len);
|
||||
if (token == "include") {
|
||||
pos += len;
|
||||
t = engine->ParseToken(modifiedScript.data() + pos,
|
||||
modifiedScript.size() - pos, &len);
|
||||
if (t == asTC_WHITESPACE) {
|
||||
pos += len;
|
||||
t = engine->ParseToken(modifiedScript.data() + pos,
|
||||
modifiedScript.size() - pos,
|
||||
&len);
|
||||
if (t == asTC_WHITESPACE) {
|
||||
pos += len;
|
||||
t = engine->ParseToken(modifiedScript.data() + pos,
|
||||
modifiedScript.size() - pos,
|
||||
&len);
|
||||
}
|
||||
|
||||
if (t == asTC_VALUE && len > 2 &&
|
||||
(modifiedScript[pos] == '"' ||
|
||||
modifiedScript[pos] == '\'')) {
|
||||
// Get the include file
|
||||
QString includefile =
|
||||
modifiedScript.mid(pos + 1, len - 2);
|
||||
pos += len;
|
||||
|
||||
// Make sure the includeFile doesn't contain any
|
||||
// line breaks
|
||||
auto p = includefile.indexOf('\n');
|
||||
if (p >= 0) {
|
||||
// TODO: Show the correct line number for the
|
||||
// error
|
||||
auto str =
|
||||
QObject::tr("Invalid file name for #include; "
|
||||
"it contains a line-break: ") +
|
||||
QStringLiteral("'") + includefile.left(p) +
|
||||
QStringLiteral("'");
|
||||
engine->WriteMessage(sectionname.toUtf8(), 0, 0,
|
||||
asMSGTYPE_ERROR, str.toUtf8());
|
||||
} else {
|
||||
// Store it for later processing
|
||||
includes.append({includefile, true});
|
||||
|
||||
// Overwrite the include directive with space
|
||||
// characters to avoid compiler error
|
||||
OverwriteCode(start, pos - start);
|
||||
}
|
||||
}
|
||||
|
||||
if (t == asTC_KEYWORD && modifiedScript[pos] == '<') {
|
||||
pos += len;
|
||||
|
||||
// find the next '>'
|
||||
auto rpos = pos;
|
||||
bool found = false;
|
||||
for (; qsizetype(rpos) < modifiedScript.size();
|
||||
++rpos) {
|
||||
if (modifiedScript[rpos] == '>') {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
if (modifiedScript[rpos] == '\n') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (t == asTC_VALUE && len > 2 &&
|
||||
(modifiedScript[pos] == '"' ||
|
||||
modifiedScript[pos] == '\'')) {
|
||||
// Get the include file
|
||||
if (found) {
|
||||
QString includefile =
|
||||
modifiedScript.mid(pos + 1, len - 2);
|
||||
pos += len;
|
||||
modifiedScript.mid(pos, rpos - pos).trimmed();
|
||||
|
||||
pos = rpos + 1;
|
||||
|
||||
// Make sure the includeFile doesn't contain any
|
||||
// line breaks
|
||||
auto p = includefile.indexOf('\n');
|
||||
if (p >= 0) {
|
||||
// TODO: Show the correct line number for the
|
||||
// error
|
||||
auto ws = includefile.indexOf(' ');
|
||||
if (!includefile.isEmpty() && p >= 0 && ws >= 0) {
|
||||
// TODO: Show the correct line number for
|
||||
// the error
|
||||
auto str =
|
||||
QObject::tr(
|
||||
"Invalid file name for #include; "
|
||||
|
@ -432,124 +478,70 @@ int asBuilder::ProcessScriptSection(const QByteArray &script, int length,
|
|||
str.toUtf8());
|
||||
} else {
|
||||
// Store it for later processing
|
||||
includes.append({includefile, true});
|
||||
includes.append({includefile, false});
|
||||
|
||||
// Overwrite the include directive with space
|
||||
// characters to avoid compiler error
|
||||
// Overwrite the include directive with
|
||||
// space characters to avoid compiler error
|
||||
OverwriteCode(start, pos - start);
|
||||
}
|
||||
} else {
|
||||
auto str =
|
||||
QObject::tr("Invalid file name for #include; "
|
||||
"it contains a line-break or "
|
||||
"unpaired symbol");
|
||||
engine->WriteMessage(sectionname.toUtf8(), 0, 0,
|
||||
asMSGTYPE_ERROR, str.toUtf8());
|
||||
}
|
||||
}
|
||||
} else if (token == "pragma") {
|
||||
// Read until the end of the line
|
||||
pos += len;
|
||||
for (; qsizetype(pos) < modifiedScript.size() &&
|
||||
modifiedScript[pos] != '\n';
|
||||
pos++)
|
||||
;
|
||||
|
||||
if (t == asTC_KEYWORD && modifiedScript[pos] == '<') {
|
||||
pos += len;
|
||||
|
||||
// find the next '>'
|
||||
auto rpos = pos;
|
||||
bool found = false;
|
||||
for (; rpos < modifiedScript.size(); ++rpos) {
|
||||
if (modifiedScript[rpos] == '>') {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
if (modifiedScript[rpos] == '\n') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
QString includefile =
|
||||
modifiedScript.mid(pos, rpos - pos)
|
||||
.trimmed();
|
||||
|
||||
pos = rpos + 1;
|
||||
|
||||
// Make sure the includeFile doesn't contain any
|
||||
// line breaks
|
||||
auto p = includefile.indexOf('\n');
|
||||
auto ws = includefile.indexOf(' ');
|
||||
if (!includefile.isEmpty() && p >= 0 &&
|
||||
ws >= 0) {
|
||||
// TODO: Show the correct line number for
|
||||
// the error
|
||||
auto str =
|
||||
QObject::tr(
|
||||
"Invalid file name for #include; "
|
||||
"it contains a line-break: ") +
|
||||
QStringLiteral("'") +
|
||||
includefile.left(p) +
|
||||
QStringLiteral("'");
|
||||
engine->WriteMessage(sectionname.toUtf8(),
|
||||
0, 0, asMSGTYPE_ERROR,
|
||||
str.toUtf8());
|
||||
} else {
|
||||
// Store it for later processing
|
||||
includes.append({includefile, false});
|
||||
|
||||
// Overwrite the include directive with
|
||||
// space characters to avoid compiler error
|
||||
OverwriteCode(start, pos - start);
|
||||
}
|
||||
} else {
|
||||
auto str = QObject::tr(
|
||||
"Invalid file name for #include; "
|
||||
"it contains a line-break or "
|
||||
"unpaired symbol");
|
||||
engine->WriteMessage(sectionname.toUtf8(), 0, 0,
|
||||
asMSGTYPE_ERROR,
|
||||
str.toUtf8());
|
||||
}
|
||||
}
|
||||
} else if (token == "pragma") {
|
||||
// Read until the end of the line
|
||||
pos += len;
|
||||
for (; pos < modifiedScript.size() &&
|
||||
modifiedScript[pos] != '\n';
|
||||
pos++)
|
||||
;
|
||||
|
||||
// Call the pragma callback
|
||||
auto pragmaText =
|
||||
modifiedScript.mid(start + 7, pos - start - 7);
|
||||
int r =
|
||||
pragmaCallback
|
||||
// Call the pragma callback
|
||||
auto pragmaText =
|
||||
modifiedScript.mid(start + 7, pos - start - 7);
|
||||
int r = pragmaCallback
|
||||
? pragmaCallback(pragmaText, this, pragmaParam)
|
||||
: -1;
|
||||
if (r < 0) {
|
||||
// TODO: Report the correct line number
|
||||
engine->WriteMessage(
|
||||
sectionname.toUtf8(), 0, 0, asMSGTYPE_ERROR,
|
||||
QObject::tr("Invalid #pragma directive")
|
||||
.toUtf8());
|
||||
return r;
|
||||
}
|
||||
|
||||
// Overwrite the pragma directive with space characters
|
||||
// to avoid compiler error
|
||||
OverwriteCode(start, pos - start);
|
||||
if (r < 0) {
|
||||
// TODO: Report the correct line number
|
||||
engine->WriteMessage(
|
||||
sectionname.toUtf8(), 0, 0, asMSGTYPE_ERROR,
|
||||
QObject::tr("Invalid #pragma directive").toUtf8());
|
||||
return r;
|
||||
}
|
||||
} else {
|
||||
// Check for lines starting with #!, e.g. shebang
|
||||
// interpreter directive. These will be treated as comments
|
||||
// and removed by the preprocessor
|
||||
if (modifiedScript[pos] == '!') {
|
||||
// Read until the end of the line
|
||||
pos += len;
|
||||
for (; pos < modifiedScript.size() &&
|
||||
modifiedScript[pos] != '\n';
|
||||
pos++)
|
||||
;
|
||||
|
||||
// Overwrite the directive with space characters to
|
||||
// avoid compiler error
|
||||
OverwriteCode(start, pos - start);
|
||||
}
|
||||
// Overwrite the pragma directive with space characters
|
||||
// to avoid compiler error
|
||||
OverwriteCode(start, pos - start);
|
||||
}
|
||||
} else {
|
||||
// Check for lines starting with #!, e.g. shebang
|
||||
// interpreter directive. These will be treated as comments
|
||||
// and removed by the preprocessor
|
||||
if (modifiedScript[pos] == '!') {
|
||||
// Read until the end of the line
|
||||
pos += len;
|
||||
for (; qsizetype(pos) < modifiedScript.size() &&
|
||||
modifiedScript[pos] != '\n';
|
||||
pos++)
|
||||
;
|
||||
|
||||
// Overwrite the directive with space characters to
|
||||
// avoid compiler error
|
||||
OverwriteCode(start, pos - start);
|
||||
}
|
||||
}
|
||||
// Don't search for metadata/includes within statement blocks or
|
||||
// between tokens in statements
|
||||
else {
|
||||
pos = SkipStatement(pos);
|
||||
}
|
||||
}
|
||||
// Don't search for metadata/includes within statement blocks or
|
||||
// between tokens in statements
|
||||
else {
|
||||
pos = SkipStatement(pos);
|
||||
}
|
||||
}
|
||||
|
||||
// Build the actual script
|
||||
|
|
|
@ -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, ("."))
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QString, SEMI_COLON_TRIGGER, ("::"))
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QString, LEFT_PARE_TRIGGER, ("("))
|
||||
|
||||
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,32 +77,39 @@ QStringList AsCompletion::extensions() const {
|
|||
}
|
||||
|
||||
void AsCompletion::complete(const QDocumentCursor &c, const QString &trigger) {
|
||||
// TODO
|
||||
// TODO parse current code
|
||||
// auto codes = c.document()->text(true, false);
|
||||
// parser.parse(codes, this->editor()->fileName());
|
||||
|
||||
// QList<QCodeNode *> nodes = parser.codeNodes();
|
||||
auto txt = c.line().text().left(c.columnNumber());
|
||||
auto code = txt.toUtf8();
|
||||
auto txt = c.line().text();
|
||||
if (txt.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
auto code = txt.left(c.columnNumber()).toUtf8();
|
||||
|
||||
auto p = code.data();
|
||||
auto len = code.length();
|
||||
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,106 +117,186 @@ 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() && trigWordLen() <= r->content.length()) {
|
||||
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 {
|
||||
pPopup->hide();
|
||||
}
|
||||
}
|
||||
} else if (trigger == LEFT_PARE_TRIGGER) {
|
||||
if (r != tokens.rend()) {
|
||||
auto pr = std::next(r);
|
||||
if (pr->content == SEMI_COLON_TRIGGER) {
|
||||
return;
|
||||
} else if (eb.type == asTC_IDENTIFIER) {
|
||||
if (r != tokens.rend()) {
|
||||
auto pr = std::next(r);
|
||||
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;
|
||||
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;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
applyEmptyNsNode(nodes);
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
applyEmptyNsNode(nodes);
|
||||
}
|
||||
} else {
|
||||
applyEmptyNsNode(nodes);
|
||||
}
|
||||
} else {
|
||||
applyEmptyNsNode(nodes);
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
// pPopup->setTemporaryNodes(temp);
|
||||
pPopup->setPrefix(fn);
|
||||
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;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (trigger == *LEFT_PARE_TRIGGER) {
|
||||
if (r != tokens.rend()) {
|
||||
auto pr = std::next(r);
|
||||
if (pr != tokens.rend()) {
|
||||
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;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} 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->setPrefix({});
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
void AsCompletion::applyEmptyNsNode(QList<QCodeNode *> &nodes) {
|
||||
if (_emptyNsNodes.isEmpty()) {
|
||||
for (auto &n : parser.headerNodes()) {
|
||||
auto name = n->qualifiedName();
|
||||
if (name.isEmpty()) {
|
||||
// only one group for empty namespace
|
||||
_emptyNsNodes << n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nodes = _emptyNsNodes;
|
||||
}
|
||||
|
||||
QCodeCompletionWidget *AsCompletion::codeCompletionWidget() const {
|
||||
return pPopup;
|
||||
}
|
||||
|
||||
void AsCompletion::setEditor(QEditor *e) {
|
||||
QCodeCompletionEngine::setEditor(e);
|
||||
pPopup->setEditor(e);
|
||||
|
|
|
@ -33,19 +33,26 @@ public:
|
|||
virtual QCodeCompletionEngine *clone() override;
|
||||
|
||||
virtual QString language() const override;
|
||||
|
||||
virtual QStringList extensions() const override;
|
||||
|
||||
virtual void setEditor(QEditor *e) override;
|
||||
|
||||
QCodeCompletionWidget *codeCompletionWidget() const;
|
||||
|
||||
protected:
|
||||
virtual void complete(const QDocumentCursor &c,
|
||||
const QString &trigger) override;
|
||||
|
||||
private:
|
||||
void applyEmptyNsNode(QList<QCodeNode *> &nodes);
|
||||
|
||||
private:
|
||||
QAsParser parser;
|
||||
asIScriptEngine *_engine;
|
||||
QCodeCompletionWidget *pPopup;
|
||||
QPointer<QCodeModel> pModel;
|
||||
|
||||
QList<QCodeNode *> _emptyNsNodes;
|
||||
};
|
||||
|
||||
#endif // _CPP_COMPLETION_H_
|
||||
|
|
|
@ -0,0 +1,171 @@
|
|||
#include "clangformatmanager.h"
|
||||
#include "settings/settings.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QProcess>
|
||||
#include <QProcessEnvironment>
|
||||
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QString, CLANG_ENABLE_FMT, ("clang.enabled"))
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QString, CLANG_AUTO_FMT, ("clang.auto"))
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QString, CLANG_STYLE, ("clang.style"))
|
||||
|
||||
ClangFormatManager::ClangFormatManager() {
|
||||
// load config
|
||||
HANDLE_CONFIG;
|
||||
|
||||
READ_CONFIG_BOOL(m_enabled, CLANG_ENABLE_FMT, true);
|
||||
READ_CONFIG_BOOL(m_autoFmt, CLANG_AUTO_FMT, true);
|
||||
|
||||
auto styles = supportedStyles();
|
||||
READ_CONFIG_STRING(m_clangStyle, CLANG_STYLE, styles.first());
|
||||
|
||||
// ok find
|
||||
refind();
|
||||
}
|
||||
|
||||
ClangFormatManager &ClangFormatManager::instance() {
|
||||
static ClangFormatManager ins;
|
||||
return ins;
|
||||
}
|
||||
|
||||
bool ClangFormatManager::exists() { return !m_clangPath.isEmpty(); }
|
||||
|
||||
bool ClangFormatManager::refind() {
|
||||
m_clangPath.clear();
|
||||
|
||||
// Get the PATH environment variable
|
||||
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
||||
QString pathEnv = env.value("PATH");
|
||||
|
||||
// Split the PATH variable into individual directories
|
||||
QStringList paths = pathEnv.split(QDir::listSeparator());
|
||||
|
||||
auto name = getProgramName();
|
||||
for (auto &path : paths) {
|
||||
QDir dir(path);
|
||||
|
||||
auto pp = dir.absoluteFilePath(name);
|
||||
QFileInfo fileInfo(pp);
|
||||
|
||||
// Check if the file exists and is executable
|
||||
if (fileInfo.exists() && fileInfo.isExecutable()) {
|
||||
m_clangPath = pp;
|
||||
bool ok;
|
||||
auto ret = runClangFormat({"--version"}, QString(), ok);
|
||||
if (ok) {
|
||||
auto vstr = QStringLiteral("clang-format version ");
|
||||
if (ret.startsWith(vstr)) {
|
||||
m_clangVersion = ret.mid(vstr.length()).simplified();
|
||||
return true;
|
||||
} else {
|
||||
m_clangPath.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QString ClangFormatManager::getProgramName() {
|
||||
#ifdef Q_OS_WIN
|
||||
return QStringLiteral("clang-format.exe");
|
||||
#else
|
||||
return QStringLiteral("clang-format");
|
||||
#endif
|
||||
}
|
||||
|
||||
QStringList ClangFormatManager::supportedStyles() {
|
||||
static QStringList styles{"LLVM", "GNU", "Google", "Chromium",
|
||||
"Microsoft", "Mozilla", "WebKit", "Custom"};
|
||||
return styles;
|
||||
}
|
||||
|
||||
QString ClangFormatManager::formatCode(const QString &codes, bool &ok) {
|
||||
auto styles = supportedStyles();
|
||||
auto fmtind = styles.indexOf(m_clangStyle);
|
||||
Q_ASSERT(fmtind >= 0);
|
||||
if (fmtind != styles.size() - 1) {
|
||||
auto style =
|
||||
QStringLiteral("--style={BasedOnStyle: %1, IndentWidth: %2}")
|
||||
.arg(m_clangStyle)
|
||||
.arg(m_identWidth);
|
||||
auto ret = runClangFormat(
|
||||
{style, QStringLiteral("--assume-filename=wing.cpp")}, codes, ok);
|
||||
return ret;
|
||||
} else {
|
||||
return runClangFormat({}, codes, ok);
|
||||
}
|
||||
}
|
||||
|
||||
QString ClangFormatManager::runClangFormat(const QStringList ¶ms,
|
||||
const QString &stdinput, bool &ok) {
|
||||
if (!exists()) {
|
||||
ok = false;
|
||||
return {};
|
||||
}
|
||||
|
||||
QProcess process;
|
||||
process.setProgram(m_clangPath);
|
||||
process.setArguments(params);
|
||||
|
||||
process.start();
|
||||
if (!process.waitForStarted()) {
|
||||
process.kill(); // Kill the process if it timed out
|
||||
process.waitForFinished(); // Ensure process has terminated
|
||||
ok = false;
|
||||
return {};
|
||||
}
|
||||
|
||||
process.write(stdinput.toUtf8());
|
||||
process.closeWriteChannel();
|
||||
|
||||
bool finished = process.waitForFinished(-1);
|
||||
if (finished) {
|
||||
auto data = process.readAllStandardOutput();
|
||||
auto error = process.readAllStandardError();
|
||||
ok = error.isEmpty();
|
||||
if (ok) {
|
||||
return QString::fromUtf8(data);
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
} else {
|
||||
process.kill(); // Kill the process if it timed out
|
||||
process.waitForFinished(); // Ensure process has terminated
|
||||
ok = false;
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
quint32 ClangFormatManager::identWidth() const { return m_identWidth; }
|
||||
|
||||
void ClangFormatManager::setIdentWidth(quint32 newIdentWidth) {
|
||||
m_identWidth = newIdentWidth;
|
||||
}
|
||||
|
||||
QString ClangFormatManager::clangStyle() const { return m_clangStyle; }
|
||||
|
||||
void ClangFormatManager::setClangStyle(const QString &newClangStyle) {
|
||||
m_clangStyle = newClangStyle;
|
||||
}
|
||||
|
||||
bool ClangFormatManager::enabled() const { return m_enabled; }
|
||||
|
||||
void ClangFormatManager::setEnabled(bool newEnabled) { m_enabled = newEnabled; }
|
||||
|
||||
QString ClangFormatManager::path() const { return m_clangPath; }
|
||||
|
||||
QString ClangFormatManager::customStyleString() const {
|
||||
return m_customStyleString;
|
||||
}
|
||||
|
||||
void ClangFormatManager::setCustomStyleString(
|
||||
const QString &newCustomStyleString) {
|
||||
m_customStyleString = newCustomStyleString;
|
||||
}
|
||||
|
||||
QString ClangFormatManager::version() const { return m_clangVersion; }
|
||||
|
||||
int ClangFormatManager::runningTimeout() const { return m_timeout; }
|
||||
|
||||
void ClangFormatManager::setRunningTimeout(int msecs) { m_timeout = msecs; }
|
|
@ -0,0 +1,63 @@
|
|||
#ifndef CLANGFORMATMANAGER_H
|
||||
#define CLANGFORMATMANAGER_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
class ClangFormatManager {
|
||||
public:
|
||||
static ClangFormatManager &instance();
|
||||
|
||||
public:
|
||||
bool exists();
|
||||
|
||||
bool refind();
|
||||
|
||||
static QString getProgramName();
|
||||
|
||||
static QStringList supportedStyles();
|
||||
|
||||
QString formatCode(const QString &codes, bool &ok);
|
||||
|
||||
int runningTimeout() const;
|
||||
|
||||
void setRunningTimeout(int msecs);
|
||||
|
||||
QString version() const;
|
||||
|
||||
QString customStyleString() const;
|
||||
|
||||
void setCustomStyleString(const QString &newCustomStyleString);
|
||||
|
||||
QString path() const;
|
||||
|
||||
bool enabled() const;
|
||||
void setEnabled(bool newEnabled);
|
||||
|
||||
QString clangStyle() const;
|
||||
void setClangStyle(const QString &newClangStyle);
|
||||
|
||||
quint32 identWidth() const;
|
||||
void setIdentWidth(quint32 newIdentWidth);
|
||||
|
||||
private:
|
||||
explicit ClangFormatManager();
|
||||
|
||||
QString runClangFormat(const QStringList ¶ms, const QString &stdinput,
|
||||
bool &ok);
|
||||
|
||||
private:
|
||||
bool m_enabled = true;
|
||||
bool m_autoFmt = true;
|
||||
|
||||
quint32 m_identWidth = 4;
|
||||
|
||||
QString m_clangPath;
|
||||
QString m_clangVersion;
|
||||
QString m_clangStyle;
|
||||
|
||||
QString m_customStyleString;
|
||||
|
||||
int m_timeout = 5000;
|
||||
};
|
||||
|
||||
#endif // CLANGFORMATMANAGER_H
|
|
@ -0,0 +1,66 @@
|
|||
#include "langservice.h"
|
||||
|
||||
#include "class/ascompletion.h"
|
||||
#include "class/skinmanager.h"
|
||||
#include "qdocument.h"
|
||||
#include "qeditor.h"
|
||||
#include "qformat.h"
|
||||
#include "qformatscheme.h"
|
||||
#include "qsnippetmanager.h"
|
||||
|
||||
LangService &LangService::instance() {
|
||||
static LangService ins;
|
||||
return ins;
|
||||
}
|
||||
|
||||
void LangService::init(asIScriptEngine *engine) {
|
||||
QFormatScheme *format = nullptr;
|
||||
|
||||
switch (SkinManager::instance().currentTheme()) {
|
||||
case SkinManager::Theme::Dark:
|
||||
format =
|
||||
new QFormatScheme(QStringLiteral(":/qcodeedit/as_dark.qxf"), this);
|
||||
break;
|
||||
case SkinManager::Theme::Light:
|
||||
format =
|
||||
new QFormatScheme(QStringLiteral(":/qcodeedit/as_light.qxf"), this);
|
||||
break;
|
||||
}
|
||||
|
||||
// additional formats
|
||||
QFormat fmt;
|
||||
fmt.foreground = Qt::red;
|
||||
format->setFormat(QStringLiteral("stderr"), fmt);
|
||||
fmt.foreground = QColorConstants::Svg::gold;
|
||||
format->setFormat(QStringLiteral("stdwarn"), fmt);
|
||||
fmt.foreground = Qt::cyan;
|
||||
format->setFormat(QStringLiteral("stdout"), fmt);
|
||||
|
||||
QDocument::setDefaultFormatScheme(format);
|
||||
|
||||
m_language = new QLanguageFactory(format, this);
|
||||
m_language->addDefinitionPath(QStringLiteral(":/qcodeedit"));
|
||||
_completion = new AsCompletion(engine, this);
|
||||
m_language->addCompletionEngine(_completion);
|
||||
|
||||
m_snippetManager = new QSnippetManager(this);
|
||||
m_snipbind = new QSnippetBinding(m_snippetManager);
|
||||
}
|
||||
|
||||
LangService::LangService() : QObject(nullptr) {}
|
||||
|
||||
LangService::~LangService() { delete m_snipbind; }
|
||||
|
||||
QSnippetManager *LangService::snippetManager() const {
|
||||
return m_snippetManager;
|
||||
}
|
||||
|
||||
QLanguageFactory *LangService::languageFactory() const { return m_language; }
|
||||
|
||||
void LangService::applyLanguageSerivce(QEditor *editor) {
|
||||
Q_ASSERT(editor);
|
||||
m_language->setLanguage(editor, QStringLiteral("AngelScript"));
|
||||
editor->addInputBinding(m_snipbind);
|
||||
}
|
||||
|
||||
QSnippetBinding *LangService::snippetBinding() const { return m_snipbind; }
|
|
@ -0,0 +1,42 @@
|
|||
#ifndef LANGSERVICE_H
|
||||
#define LANGSERVICE_H
|
||||
|
||||
#include "class/ascompletion.h"
|
||||
#include "qlanguagefactory.h"
|
||||
#include "qsnippetbinding.h"
|
||||
|
||||
#include "angelscript.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class LangService : QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static LangService &instance();
|
||||
|
||||
void init(asIScriptEngine *engine);
|
||||
|
||||
QSnippetBinding *snippetBinding() const;
|
||||
|
||||
QLanguageFactory *languageFactory() const;
|
||||
|
||||
void applyLanguageSerivce(QEditor *editor);
|
||||
|
||||
QSnippetManager *snippetManager() const;
|
||||
|
||||
private:
|
||||
LangService();
|
||||
~LangService();
|
||||
|
||||
private:
|
||||
QSnippetBinding *m_snipbind = nullptr;
|
||||
QLanguageFactory *m_language = nullptr;
|
||||
QSnippetManager *m_snippetManager = nullptr;
|
||||
|
||||
AsCompletion *_completion = nullptr;
|
||||
|
||||
Q_DISABLE_COPY_MOVE(LangService)
|
||||
};
|
||||
|
||||
#endif // LANGSERVICE_H
|
|
@ -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() {
|
||||
|
@ -234,6 +233,20 @@ void QAsParser::addGlobalFunctionCompletion(asIScriptEngine *engine) {
|
|||
_maps[ns] << fnInfo;
|
||||
}
|
||||
|
||||
auto node = new QCodeNode;
|
||||
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->setParent(node);
|
||||
node->children().append(nsnode);
|
||||
}
|
||||
_headerNodes << node;
|
||||
|
||||
for (auto p = _maps.keyValueBegin(); p != _maps.keyValueEnd(); p++) {
|
||||
auto node = new QCodeNode;
|
||||
_headerNodes << node;
|
||||
|
@ -248,16 +261,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 +311,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 +394,80 @@ 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;
|
||||
_clsNodes << 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::classNodes() const { return _clsNodes; }
|
||||
|
||||
QList<QCodeNode *> QAsParser::codeNodes() const { return _nodes; }
|
||||
|
|
|
@ -75,15 +75,23 @@ public:
|
|||
|
||||
const QList<QCodeNode *> &headerNodes() const;
|
||||
|
||||
QList<QCodeNode *> classNodes() const;
|
||||
|
||||
private:
|
||||
void addGlobalFunctionCompletion(asIScriptEngine *engine);
|
||||
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;
|
||||
QList<QCodeNode *> _headerNodes;
|
||||
QList<QCodeNode *> _clsNodes;
|
||||
QList<QCodeNode *> _nodes;
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
};
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -103,7 +103,11 @@ bool ScriptEditorTheme::loadTheme(const QString &filename) {
|
|||
|
||||
if (readAttr(attr, QStringLiteral("fontfamily"),
|
||||
styleAttr)) {
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
if (QFontDatabase::hasFamily(styleAttr)) {
|
||||
#else
|
||||
if (QFontDatabase().hasFamily(styleAttr)) {
|
||||
#endif
|
||||
scheme.fontFamily = styleAttr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -182,9 +182,6 @@ bool ScriptMachine::configureEngine(asIScriptEngine *engine) {
|
|||
PluginSystem::instance().angelApi()->installAPI(
|
||||
engine, typeInfo(RegisteredType::tString));
|
||||
|
||||
// TODO TEST
|
||||
QAsParser varname(engine);
|
||||
|
||||
_immediateContext = engine->CreateContext();
|
||||
_immediateContext->SetExceptionCallback(
|
||||
asMETHOD(ScriptMachine, exceptionCallback), this, asCALL_THISCALL);
|
||||
|
|
|
@ -19,92 +19,52 @@
|
|||
|
||||
#include "class/logger.h"
|
||||
#include "class/skinmanager.h"
|
||||
#include "settings/settings.h"
|
||||
#include "utilities.h"
|
||||
#include <QFileInfo>
|
||||
#include <QMetaEnum>
|
||||
#include <QSettings>
|
||||
|
||||
#define HANDLE_CONFIG \
|
||||
QSettings set(QStringLiteral(APP_ORG), QStringLiteral(APP_NAME))
|
||||
|
||||
#define CONFIG set
|
||||
|
||||
#define WRITE_CONFIG(config, dvalue) \
|
||||
#define WRITE_CONFIG_SET(config, dvalue) \
|
||||
if (this->_setUnsaved.testFlag(SETTING_ITEM::config)) { \
|
||||
set.setValue(config, dvalue); \
|
||||
WRITE_CONFIG(config, dvalue); \
|
||||
_setUnsaved.setFlag(SettingManager::SETTING_ITEM::config, false); \
|
||||
}
|
||||
|
||||
#define READ_CONFIG(config, dvalue) set.value(config, dvalue)
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QString, DOCK_LAYOUT, ("dock.layout"))
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QString, SCRIPT_DOCK_LAYOUT, ("script.layout"))
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QString, APP_LASTUSED_PATH, ("app.lastusedpath"))
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QString, SKIN_THEME, ("skin.theme"))
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QString, APP_FONTFAMILY, ("app.fontfamily"))
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QString, APP_FONTSIZE, ("app.fontsize"))
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QString, APP_WINDOWSIZE, ("app.windowsize"))
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QString, APP_LANGUAGE, ("app.lang"))
|
||||
|
||||
#define READ_CONFIG_SAFE(var, config, dvalue, func) \
|
||||
{ \
|
||||
auto b = false; \
|
||||
var = READ_CONFIG(config, dvalue).func(&b); \
|
||||
if (!b) { \
|
||||
var = dvalue; \
|
||||
} \
|
||||
}
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QString, PLUGIN_ENABLE, ("plugin.enableplugin"))
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QString, PLUGIN_ENABLE_ROOT,
|
||||
("plugin.rootenableplugin"))
|
||||
|
||||
#define READ_CONFIG_INT(var, config, dvalue) \
|
||||
READ_CONFIG_SAFE(var, config, dvalue, toInt)
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QString, EDITOR_FONTSIZE, ("editor.fontsize"))
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QString, EDITOR_SHOW_ADDR, ("editor.showaddr"))
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QString, EDITOR_SHOW_COL, ("editor.showcol"))
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QString, EDITOR_SHOW_TEXT, ("editor.showtext"))
|
||||
|
||||
#define READ_CONFIG_BOOL(var, config, dvalue) \
|
||||
var = READ_CONFIG(config, dvalue).toBool()
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QString, EDITOR_ENCODING, ("editor.encoding"))
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QString, EDITOR_FIND_MAXCOUNT,
|
||||
("editor.findmaxcount"))
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QString, EDITOR_COPY_LIMIT, ("editor.copylimit"))
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QString, EDITOR_DECSTRLIMIT, ("editor.decstrlimit"))
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QString, EDITOR_RECENTFILES, ("editor.recentfiles"))
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QString, SCRIPT_RECENTFILES, ("script.recentfiles"))
|
||||
|
||||
#define READ_CONFIG_QSIZETYPE(var, config, dvalue) \
|
||||
READ_CONFIG_SAFE(var, config, dvalue, toLongLong)
|
||||
|
||||
#define READ_CONFIG_INT_POSITIVE(var, config, dvalue) \
|
||||
{ \
|
||||
Q_ASSERT(dvalue > 0); \
|
||||
READ_CONFIG_SAFE(var, config, dvalue, toInt); \
|
||||
if (var <= 0) { \
|
||||
var = dvalue; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define READ_CONFIG_DOUBLE_POSITIVE(var, config, dvalue) \
|
||||
{ \
|
||||
Q_ASSERT(dvalue > 0); \
|
||||
READ_CONFIG_SAFE(var, config, dvalue, toDouble); \
|
||||
if (var <= 0) { \
|
||||
var = dvalue; \
|
||||
} \
|
||||
}
|
||||
|
||||
const auto DOCK_LAYOUT = QStringLiteral("dock.layout");
|
||||
const auto SCRIPT_DOCK_LAYOUT = QStringLiteral("script.layout");
|
||||
const auto APP_LASTUSED_PATH = QStringLiteral("app.lastusedpath");
|
||||
|
||||
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");
|
||||
|
||||
const auto PLUGIN_ENABLE = QStringLiteral("plugin.enableplugin");
|
||||
const auto PLUGIN_ENABLE_ROOT = QStringLiteral("plugin.rootenableplugin");
|
||||
|
||||
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");
|
||||
|
||||
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,
|
||||
("script.allowUsrScriptRoot"))
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QString, SCRIPT_USRHIDECATS, ("script.usrHideCats"))
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QString, SCRIPT_SYSHIDECATS, ("script.sysHideCats"))
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QString, OTHER_USESYS_FILEDIALOG,
|
||||
("sys.nativeDialog"))
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QString, OTHER_USE_NATIVE_TITLEBAR,
|
||||
("sys.nativeTitleBar"))
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QString, OTHER_LOG_LEVEL, ("sys.loglevel"))
|
||||
|
||||
SettingManager::SettingManager() {
|
||||
_defaultFont = qApp->font();
|
||||
|
@ -129,11 +89,12 @@ 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();
|
||||
m_appFontFamily =
|
||||
READ_CONFIG(APP_FONTFAMILY, _defaultFont.family()).toString();
|
||||
READ_CONFIG_STRING(m_appFontFamily, APP_FONTFAMILY, _defaultFont.family());
|
||||
|
||||
// check font
|
||||
QFont fm(m_appFontFamily);
|
||||
if (!QFontInfo(fm).exactMatch()) {
|
||||
|
@ -361,79 +322,79 @@ void SettingManager::setDefaultWinState(Qt::WindowState newDefaultWinState) {
|
|||
|
||||
void SettingManager::save(SETTINGS cat) {
|
||||
HANDLE_CONFIG;
|
||||
WRITE_CONFIG(DOCK_LAYOUT, m_dockLayout);
|
||||
WRITE_CONFIG(SCRIPT_DOCK_LAYOUT, m_scriptDockLayout);
|
||||
WRITE_CONFIG(EDITOR_RECENTFILES, getVarList(m_recentHexFiles));
|
||||
WRITE_CONFIG(SCRIPT_RECENTFILES, getVarList(m_recentScriptFiles));
|
||||
WRITE_CONFIG(APP_LASTUSED_PATH, m_lastUsedPath);
|
||||
WRITE_CONFIG_SET(DOCK_LAYOUT, m_dockLayout);
|
||||
WRITE_CONFIG_SET(SCRIPT_DOCK_LAYOUT, m_scriptDockLayout);
|
||||
WRITE_CONFIG_SET(EDITOR_RECENTFILES, getVarList(m_recentHexFiles));
|
||||
WRITE_CONFIG_SET(SCRIPT_RECENTFILES, getVarList(m_recentScriptFiles));
|
||||
WRITE_CONFIG_SET(APP_LASTUSED_PATH, m_lastUsedPath);
|
||||
if (cat.testFlag(SETTING::APP)) {
|
||||
WRITE_CONFIG(SKIN_THEME, m_themeID);
|
||||
WRITE_CONFIG(APP_LANGUAGE, m_defaultLang);
|
||||
WRITE_CONFIG(APP_FONTFAMILY, m_appFontFamily);
|
||||
WRITE_CONFIG(APP_FONTSIZE, m_appfontSize);
|
||||
WRITE_CONFIG(APP_WINDOWSIZE, m_defaultWinState);
|
||||
WRITE_CONFIG_SET(SKIN_THEME, m_themeID);
|
||||
WRITE_CONFIG_SET(APP_LANGUAGE, m_defaultLang);
|
||||
WRITE_CONFIG_SET(APP_FONTFAMILY, m_appFontFamily);
|
||||
WRITE_CONFIG_SET(APP_FONTSIZE, m_appfontSize);
|
||||
WRITE_CONFIG_SET(APP_WINDOWSIZE, m_defaultWinState);
|
||||
}
|
||||
if (cat.testFlag(SETTING::PLUGIN)) {
|
||||
WRITE_CONFIG(PLUGIN_ENABLE, m_enablePlugin);
|
||||
WRITE_CONFIG(PLUGIN_ENABLE_ROOT, m_enablePlgInRoot);
|
||||
WRITE_CONFIG_SET(PLUGIN_ENABLE, m_enablePlugin);
|
||||
WRITE_CONFIG_SET(PLUGIN_ENABLE_ROOT, m_enablePlgInRoot);
|
||||
}
|
||||
if (cat.testFlag(SETTING::EDITOR)) {
|
||||
WRITE_CONFIG(EDITOR_FONTSIZE, m_editorfontSize);
|
||||
WRITE_CONFIG(EDITOR_SHOW_ADDR, m_editorShowHeader);
|
||||
WRITE_CONFIG(EDITOR_SHOW_COL, m_editorShowcol);
|
||||
WRITE_CONFIG(EDITOR_SHOW_TEXT, m_editorShowtext);
|
||||
WRITE_CONFIG(EDITOR_ENCODING, m_editorEncoding);
|
||||
WRITE_CONFIG(EDITOR_COPY_LIMIT, m_copylimit);
|
||||
WRITE_CONFIG(EDITOR_DECSTRLIMIT, m_decodeStrlimit);
|
||||
WRITE_CONFIG_SET(EDITOR_FONTSIZE, m_editorfontSize);
|
||||
WRITE_CONFIG_SET(EDITOR_SHOW_ADDR, m_editorShowHeader);
|
||||
WRITE_CONFIG_SET(EDITOR_SHOW_COL, m_editorShowcol);
|
||||
WRITE_CONFIG_SET(EDITOR_SHOW_TEXT, m_editorShowtext);
|
||||
WRITE_CONFIG_SET(EDITOR_ENCODING, m_editorEncoding);
|
||||
WRITE_CONFIG_SET(EDITOR_COPY_LIMIT, m_copylimit);
|
||||
WRITE_CONFIG_SET(EDITOR_DECSTRLIMIT, m_decodeStrlimit);
|
||||
}
|
||||
if (cat.testFlag(SETTING::SCRIPT)) {
|
||||
WRITE_CONFIG(SCRIPT_ALLOW_USRSCRIPT_INROOT, m_allowUsrScriptInRoot);
|
||||
WRITE_CONFIG(SCRIPT_USRHIDECATS, m_usrHideCats);
|
||||
WRITE_CONFIG(SCRIPT_SYSHIDECATS, m_sysHideCats);
|
||||
WRITE_CONFIG_SET(SCRIPT_ALLOW_USRSCRIPT_INROOT, m_allowUsrScriptInRoot);
|
||||
WRITE_CONFIG_SET(SCRIPT_USRHIDECATS, m_usrHideCats);
|
||||
WRITE_CONFIG_SET(SCRIPT_SYSHIDECATS, m_sysHideCats);
|
||||
}
|
||||
if (cat.testFlag(SETTING::OTHER)) {
|
||||
WRITE_CONFIG(OTHER_USESYS_FILEDIALOG, m_useNativeFileDialog);
|
||||
WRITE_CONFIG_SET(OTHER_USESYS_FILEDIALOG, m_useNativeFileDialog);
|
||||
#ifdef WINGHEX_USE_FRAMELESS
|
||||
WRITE_CONFIG(OTHER_USE_NATIVE_TITLEBAR, m_useNativeTitleBar);
|
||||
WRITE_CONFIG_SET(OTHER_USE_NATIVE_TITLEBAR, m_useNativeTitleBar);
|
||||
#endif
|
||||
WRITE_CONFIG(OTHER_LOG_LEVEL, m_logLevel);
|
||||
WRITE_CONFIG_SET(OTHER_LOG_LEVEL, m_logLevel);
|
||||
}
|
||||
}
|
||||
|
||||
void SettingManager::reset(SETTINGS cat) {
|
||||
HANDLE_CONFIG;
|
||||
if (cat.testFlag(SETTING::APP)) {
|
||||
WRITE_CONFIG(SKIN_THEME, 0);
|
||||
WRITE_CONFIG(APP_LANGUAGE, QString());
|
||||
WRITE_CONFIG(APP_FONTFAMILY, _defaultFont.family());
|
||||
WRITE_CONFIG(APP_FONTSIZE, _defaultFont.pointSize());
|
||||
WRITE_CONFIG(APP_WINDOWSIZE, Qt::WindowMaximized);
|
||||
WRITE_CONFIG_SET(SKIN_THEME, 0);
|
||||
WRITE_CONFIG_SET(APP_LANGUAGE, QString());
|
||||
WRITE_CONFIG_SET(APP_FONTFAMILY, _defaultFont.family());
|
||||
WRITE_CONFIG_SET(APP_FONTSIZE, _defaultFont.pointSize());
|
||||
WRITE_CONFIG_SET(APP_WINDOWSIZE, Qt::WindowMaximized);
|
||||
}
|
||||
if (cat.testFlag(SETTING::PLUGIN)) {
|
||||
WRITE_CONFIG(PLUGIN_ENABLE, true);
|
||||
WRITE_CONFIG(PLUGIN_ENABLE_ROOT, false);
|
||||
WRITE_CONFIG_SET(PLUGIN_ENABLE, true);
|
||||
WRITE_CONFIG_SET(PLUGIN_ENABLE_ROOT, false);
|
||||
}
|
||||
if (cat.testFlag(SETTING::EDITOR)) {
|
||||
WRITE_CONFIG(EDITOR_FONTSIZE, _defaultFont.pointSize());
|
||||
WRITE_CONFIG(EDITOR_SHOW_ADDR, true);
|
||||
WRITE_CONFIG(EDITOR_SHOW_COL, true);
|
||||
WRITE_CONFIG(EDITOR_SHOW_TEXT, true);
|
||||
WRITE_CONFIG(EDITOR_ENCODING, QStringLiteral("ASCII"));
|
||||
WRITE_CONFIG(EDITOR_FIND_MAXCOUNT, 100);
|
||||
WRITE_CONFIG(EDITOR_COPY_LIMIT, 100);
|
||||
WRITE_CONFIG(EDITOR_DECSTRLIMIT, 10);
|
||||
WRITE_CONFIG_SET(EDITOR_FONTSIZE, _defaultFont.pointSize());
|
||||
WRITE_CONFIG_SET(EDITOR_SHOW_ADDR, true);
|
||||
WRITE_CONFIG_SET(EDITOR_SHOW_COL, true);
|
||||
WRITE_CONFIG_SET(EDITOR_SHOW_TEXT, true);
|
||||
WRITE_CONFIG_SET(EDITOR_ENCODING, QStringLiteral("ASCII"));
|
||||
WRITE_CONFIG_SET(EDITOR_FIND_MAXCOUNT, 100);
|
||||
WRITE_CONFIG_SET(EDITOR_COPY_LIMIT, 100);
|
||||
WRITE_CONFIG_SET(EDITOR_DECSTRLIMIT, 10);
|
||||
}
|
||||
if (cat.testFlag(SETTING::SCRIPT)) {
|
||||
WRITE_CONFIG(SCRIPT_ALLOW_USRSCRIPT_INROOT, false);
|
||||
WRITE_CONFIG(SCRIPT_USRHIDECATS, QStringList());
|
||||
WRITE_CONFIG(SCRIPT_SYSHIDECATS, QStringList());
|
||||
WRITE_CONFIG_SET(SCRIPT_ALLOW_USRSCRIPT_INROOT, false);
|
||||
WRITE_CONFIG_SET(SCRIPT_USRHIDECATS, QStringList());
|
||||
WRITE_CONFIG_SET(SCRIPT_SYSHIDECATS, QStringList());
|
||||
}
|
||||
if (cat.testFlag(SETTING::OTHER)) {
|
||||
WRITE_CONFIG(OTHER_USESYS_FILEDIALOG, true);
|
||||
WRITE_CONFIG_SET(OTHER_USESYS_FILEDIALOG, true);
|
||||
#ifdef WINGHEX_USE_FRAMELESS
|
||||
WRITE_CONFIG(OTHER_USE_NATIVE_TITLEBAR, false);
|
||||
WRITE_CONFIG_SET(OTHER_USE_NATIVE_TITLEBAR, false);
|
||||
#endif
|
||||
WRITE_CONFIG(OTHER_LOG_LEVEL, Logger::defaultLevel());
|
||||
WRITE_CONFIG_SET(OTHER_LOG_LEVEL, Logger::defaultLevel());
|
||||
}
|
||||
load();
|
||||
}
|
||||
|
|
|
@ -43,7 +43,11 @@ SkinManager::SkinManager(QObject *parent) : QObject(parent) {
|
|||
break;
|
||||
}
|
||||
qss.open(QFile::ReadOnly | QFile::Text);
|
||||
#ifdef Q_OS_WIN
|
||||
qApp->setStyle(QStyleFactory::create("windowsvista"));
|
||||
#else
|
||||
qApp->setStyle(QStyleFactory::create("fusion"));
|
||||
#endif
|
||||
qApp->setStyleSheet(qss.readAll());
|
||||
qss.close();
|
||||
}
|
||||
|
|
|
@ -26,14 +26,11 @@
|
|||
|
||||
WingAngelAPI::WingAngelAPI() {
|
||||
qsizetype signalCount = 0;
|
||||
const QMetaObject *objs[]{this->metaObject(),
|
||||
this->reader.metaObject(),
|
||||
this->controller.metaObject(),
|
||||
this->msgbox.metaObject(),
|
||||
this->inputbox.metaObject(),
|
||||
this->filedlg.metaObject(),
|
||||
this->colordlg.metaObject(),
|
||||
this->visual.metaObject()};
|
||||
const QMetaObject *objs[]{
|
||||
WingAngelAPI::metaObject(), this->reader.metaObject(),
|
||||
this->controller.metaObject(), this->msgbox.metaObject(),
|
||||
this->inputbox.metaObject(), this->filedlg.metaObject(),
|
||||
this->colordlg.metaObject(), this->visual.metaObject()};
|
||||
for (auto &obj : objs) {
|
||||
for (auto i = obj->methodOffset(); i < obj->methodCount(); ++i) {
|
||||
if (obj->method(i).methodType() == QMetaMethod::Signal) {
|
||||
|
@ -423,38 +420,6 @@ void WingAngelAPI::installHexBaseType(asIScriptEngine *engine) {
|
|||
asCALL_THISCALL);
|
||||
Q_ASSERT(r >= 0);
|
||||
|
||||
// HexMetadataAbsoluteItem
|
||||
r = engine->RegisterObjectType(
|
||||
"HexMetadataAbsoluteItem", sizeof(WingHex::HexMetadataAbsoluteItem),
|
||||
asOBJ_VALUE | asOBJ_POD |
|
||||
asGetTypeTraits<WingHex::HexMetadataAbsoluteItem>());
|
||||
Q_ASSERT(r >= 0);
|
||||
|
||||
r = engine->RegisterObjectProperty(
|
||||
"HexMetadataAbsoluteItem", QSIZETYPE_WRAP("begin"),
|
||||
asOFFSET(WingHex::HexMetadataAbsoluteItem, begin));
|
||||
Q_ASSERT(r >= 0);
|
||||
|
||||
r = engine->RegisterObjectProperty(
|
||||
"HexMetadataAbsoluteItem", QSIZETYPE_WRAP("end"),
|
||||
asOFFSET(WingHex::HexMetadataAbsoluteItem, end));
|
||||
Q_ASSERT(r >= 0);
|
||||
|
||||
r = engine->RegisterObjectProperty(
|
||||
"HexMetadataAbsoluteItem", "color foreground",
|
||||
asOFFSET(WingHex::HexMetadataAbsoluteItem, foreground));
|
||||
Q_ASSERT(r >= 0);
|
||||
|
||||
r = engine->RegisterObjectProperty(
|
||||
"HexMetadataAbsoluteItem", "color background",
|
||||
asOFFSET(WingHex::HexMetadataAbsoluteItem, background));
|
||||
Q_ASSERT(r >= 0);
|
||||
|
||||
r = engine->RegisterObjectProperty(
|
||||
"HexMetadataAbsoluteItem", "string comment",
|
||||
asOFFSET(WingHex::HexMetadataAbsoluteItem, comment));
|
||||
Q_ASSERT(r >= 0);
|
||||
|
||||
// HexMetadataItem
|
||||
r = engine->RegisterObjectType(
|
||||
"HexMetadataItem", sizeof(WingHex::HexMetadataItem),
|
||||
|
@ -462,18 +427,12 @@ void WingAngelAPI::installHexBaseType(asIScriptEngine *engine) {
|
|||
Q_ASSERT(r >= 0);
|
||||
|
||||
r = engine->RegisterObjectProperty(
|
||||
"HexMetadataItem", QSIZETYPE_WRAP("line"),
|
||||
asOFFSET(WingHex::HexMetadataItem, line));
|
||||
"HexMetadataItem", QSIZETYPE_WRAP("begin"),
|
||||
asOFFSET(WingHex::HexMetadataItem, begin));
|
||||
Q_ASSERT(r >= 0);
|
||||
|
||||
r = engine->RegisterObjectProperty(
|
||||
"HexMetadataItem", "int start",
|
||||
asOFFSET(WingHex::HexMetadataItem, start));
|
||||
Q_ASSERT(r >= 0);
|
||||
|
||||
r = engine->RegisterObjectProperty(
|
||||
"HexMetadataItem", "int length",
|
||||
asOFFSET(WingHex::HexMetadataItem, length));
|
||||
r = engine->RegisterObjectProperty("HexMetadataItem", QSIZETYPE_WRAP("end"),
|
||||
asOFFSET(WingHex::HexMetadataItem, end));
|
||||
Q_ASSERT(r >= 0);
|
||||
|
||||
r = engine->RegisterObjectProperty(
|
||||
|
@ -690,13 +649,7 @@ void WingAngelAPI::installHexReaderAPI(asIScriptEngine *engine) {
|
|||
engine,
|
||||
std::bind(&WingAngelAPI::_HexReader_getMetadatas, this,
|
||||
std::placeholders::_1),
|
||||
"array<HexMetadataAbsoluteItem>@ getMetadatas(" QSIZETYPE ")");
|
||||
|
||||
registerAPI<CScriptArray *(qsizetype)>(
|
||||
engine,
|
||||
std::bind(&WingAngelAPI::_HexReader_getMetaLine, this,
|
||||
std::placeholders::_1),
|
||||
"array<HexMetadataItem>@ getMetaLine(" QSIZETYPE ")");
|
||||
"array<HexMetadataItem>@ getMetadatas(" QSIZETYPE ")");
|
||||
|
||||
registerAPI<bool(qsizetype)>(
|
||||
engine,
|
||||
|
@ -805,11 +758,11 @@ void WingAngelAPI::installHexControllerAPI(asIScriptEngine *engine) {
|
|||
std::placeholders::_2, std::placeholders::_3),
|
||||
"bool insert(" QSIZETYPE ", ? &out)");
|
||||
|
||||
registerAPI<bool(qsizetype, void *, int)>(
|
||||
engine,
|
||||
std::bind(&WingAngelAPI::_HexReader_append, this, std::placeholders::_1,
|
||||
std::placeholders::_2, std::placeholders::_3),
|
||||
"bool append(" QSIZETYPE ", ? &out)");
|
||||
registerAPI<bool(void *, int)>(engine,
|
||||
std::bind(&WingAngelAPI::_HexReader_append,
|
||||
this, std::placeholders::_1,
|
||||
std::placeholders::_2),
|
||||
"bool append(? &out)");
|
||||
|
||||
registerAPI<bool()>(engine,
|
||||
std::bind(&WingHex::WingPlugin::Controller::undo, ctl),
|
||||
|
@ -1024,18 +977,6 @@ void WingAngelAPI::installHexControllerAPI(asIScriptEngine *engine) {
|
|||
"bool metadata(" QSIZETYPE ", " QSIZETYPE
|
||||
", color &in, color &in, string &in)");
|
||||
|
||||
registerAPI<bool(qsizetype, qsizetype, qsizetype, const QColor &,
|
||||
const QColor &, const QString &)>(
|
||||
engine,
|
||||
std::bind(QOverload<qsizetype, qsizetype, qsizetype, const QColor &,
|
||||
const QColor &, const QString &>::
|
||||
of(&WingHex::WingPlugin::Controller::metadata),
|
||||
ctl, std::placeholders::_1, std::placeholders::_2,
|
||||
std::placeholders::_3, std::placeholders::_4,
|
||||
std::placeholders::_5, std::placeholders::_6),
|
||||
"bool metadata(" QSIZETYPE ", " QSIZETYPE ", " QSIZETYPE
|
||||
", color &in, color &in, string &in)");
|
||||
|
||||
registerAPI<bool(qsizetype)>(
|
||||
engine,
|
||||
std::bind(&WingHex::WingPlugin::Controller::removeMetadata, ctl,
|
||||
|
@ -1046,29 +987,26 @@ void WingAngelAPI::installHexControllerAPI(asIScriptEngine *engine) {
|
|||
engine, std::bind(&WingHex::WingPlugin::Controller::clearMetadata, ctl),
|
||||
"bool clearMetadata()");
|
||||
|
||||
registerAPI<bool(qsizetype, qsizetype, qsizetype, const QColor &)>(
|
||||
registerAPI<bool(qsizetype, qsizetype, const QColor &)>(
|
||||
engine,
|
||||
std::bind(&WingHex::WingPlugin::Controller::foreground, ctl,
|
||||
std::placeholders::_1, std::placeholders::_2,
|
||||
std::placeholders::_3, std::placeholders::_4),
|
||||
"bool foreground(" QSIZETYPE ", " QSIZETYPE ", " QSIZETYPE
|
||||
", color &in)");
|
||||
std::placeholders::_3),
|
||||
"bool foreground(" QSIZETYPE ", " QSIZETYPE ", color &in)");
|
||||
|
||||
registerAPI<bool(qsizetype, qsizetype, qsizetype, const QColor &)>(
|
||||
registerAPI<bool(qsizetype, qsizetype, const QColor &)>(
|
||||
engine,
|
||||
std::bind(&WingHex::WingPlugin::Controller::background, ctl,
|
||||
std::placeholders::_1, std::placeholders::_2,
|
||||
std::placeholders::_3, std::placeholders::_4),
|
||||
"bool background(" QSIZETYPE ", " QSIZETYPE ", " QSIZETYPE
|
||||
", color &in)");
|
||||
std::placeholders::_3),
|
||||
"bool background(" QSIZETYPE ", " QSIZETYPE ", color &in)");
|
||||
|
||||
registerAPI<bool(qsizetype, qsizetype, qsizetype, const QString &)>(
|
||||
registerAPI<bool(qsizetype, qsizetype, const QString &)>(
|
||||
engine,
|
||||
std::bind(&WingHex::WingPlugin::Controller::comment, ctl,
|
||||
std::placeholders::_1, std::placeholders::_2,
|
||||
std::placeholders::_3, std::placeholders::_4),
|
||||
"bool comment(" QSIZETYPE ", " QSIZETYPE ", " QSIZETYPE
|
||||
", string &in)");
|
||||
std::placeholders::_3),
|
||||
"bool comment(" QSIZETYPE ", " QSIZETYPE ", string &in)");
|
||||
|
||||
registerAPI<bool(bool)>(
|
||||
engine,
|
||||
|
@ -1118,31 +1056,31 @@ void WingAngelAPI::installHexControllerAPI(asIScriptEngine *engine) {
|
|||
std::placeholders::_1),
|
||||
"ErrFile openDriver(string &in)");
|
||||
|
||||
registerAPI<WingHex::ErrFile(const QString &, bool)>(
|
||||
registerAPI<WingHex::ErrFile(int, bool)>(
|
||||
engine,
|
||||
std::bind(&WingHex::WingPlugin::Controller::closeFile, ctl,
|
||||
std::placeholders::_1, std::placeholders::_2),
|
||||
"ErrFile closeFile(string &in, bool = false)");
|
||||
"ErrFile closeFile(int, bool = false)");
|
||||
|
||||
registerAPI<WingHex::ErrFile(const QString &, bool)>(
|
||||
registerAPI<WingHex::ErrFile(int, bool)>(
|
||||
engine,
|
||||
std::bind(&WingHex::WingPlugin::Controller::saveFile, ctl,
|
||||
std::placeholders::_1, std::placeholders::_2),
|
||||
"ErrFile saveFile(string &in, bool = false)");
|
||||
"ErrFile saveFile(int, bool = false)");
|
||||
|
||||
registerAPI<WingHex::ErrFile(const QString &, const QString &, bool)>(
|
||||
registerAPI<WingHex::ErrFile(int, const QString &, bool)>(
|
||||
engine,
|
||||
std::bind(&WingHex::WingPlugin::Controller::exportFile, ctl,
|
||||
std::placeholders::_1, std::placeholders::_2,
|
||||
std::placeholders::_3),
|
||||
"ErrFile exportFile(string &in, string &in, bool = false)");
|
||||
"ErrFile exportFile(int, string &in, bool = false)");
|
||||
|
||||
registerAPI<WingHex::ErrFile(const QString &, const QString &, bool)>(
|
||||
registerAPI<WingHex::ErrFile(int, const QString &, bool)>(
|
||||
engine,
|
||||
std::bind(&WingHex::WingPlugin::Controller::saveAsFile, ctl,
|
||||
std::placeholders::_1, std::placeholders::_2,
|
||||
std::placeholders::_3),
|
||||
"ErrFile saveasFile(string &in, string &in, bool = false)");
|
||||
"ErrFile saveasFile(int, string &in, bool = false)");
|
||||
|
||||
registerAPI<WingHex::ErrFile(bool)>(
|
||||
engine,
|
||||
|
@ -1215,11 +1153,11 @@ void WingAngelAPI::installHexControllerAPI(asIScriptEngine *engine) {
|
|||
engine, std::bind(&WingHex::WingPlugin::Controller::clearBookMark, ctl),
|
||||
"bool clearBookMark()");
|
||||
|
||||
registerAPI<bool(const QString &)>(
|
||||
registerAPI<WingHex::ErrFile(const QString &)>(
|
||||
engine,
|
||||
std::bind(&WingHex::WingPlugin::Controller::openWorkSpace, ctl,
|
||||
std::placeholders::_1),
|
||||
"bool openWorkSpace(string &in)");
|
||||
"ErrFile openWorkSpace(string &in)");
|
||||
|
||||
registerAPI<bool(const QString &)>(
|
||||
engine,
|
||||
|
@ -1316,30 +1254,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 +1331,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 +1432,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 +1464,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 +1481,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 +1501,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 +1534,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 +1551,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));
|
||||
}
|
||||
}
|
||||
|
@ -1614,7 +1563,7 @@ bool WingAngelAPI::_HexReader_insert(qsizetype offset, void *ref, int typeId) {
|
|||
}
|
||||
}
|
||||
|
||||
bool WingAngelAPI::_HexReader_append(qsizetype offset, void *ref, int typeId) {
|
||||
bool WingAngelAPI::_HexReader_append(void *ref, int typeId) {
|
||||
asIScriptContext *ctx = asGetActiveContext();
|
||||
if (ctx) {
|
||||
asIScriptEngine *engine = ctx->GetEngine();
|
||||
|
@ -1622,21 +1571,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 +1598,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 +1615,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));
|
||||
}
|
||||
}
|
||||
|
@ -1753,17 +1702,9 @@ CScriptArray *WingAngelAPI::_HexReader_findAllBytes(qsizetype begin,
|
|||
|
||||
CScriptArray *WingAngelAPI::_HexReader_getMetadatas(qsizetype offset) {
|
||||
return retarrayWrapperFunction(
|
||||
[this, offset]() -> QList<WingHex::HexMetadataAbsoluteItem> {
|
||||
[this, offset]() -> QList<WingHex::HexMetadataItem> {
|
||||
return emit reader.getMetadatas(offset);
|
||||
},
|
||||
"array<HexMetadataAbsoluteItem>");
|
||||
}
|
||||
|
||||
CScriptArray *WingAngelAPI::_HexReader_getMetaLine(qsizetype line) {
|
||||
return retarrayWrapperFunction(
|
||||
[this, line]() -> WingHex::HexLineMetadata {
|
||||
return emit reader.getMetaLine(line);
|
||||
},
|
||||
"array<HexMetadataItem>");
|
||||
}
|
||||
|
||||
|
@ -1853,7 +1794,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 +1808,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;
|
||||
}
|
||||
|
|
|
@ -104,7 +104,7 @@ private:
|
|||
|
||||
bool _HexReader_insert(qsizetype offset, void *ref, int typeId);
|
||||
|
||||
bool _HexReader_append(qsizetype offset, void *ref, int typeId);
|
||||
bool _HexReader_append(void *ref, int typeId);
|
||||
|
||||
qsizetype _HexReader_searchForward(qsizetype begin, const CScriptArray &ba);
|
||||
|
||||
|
@ -116,8 +116,6 @@ private:
|
|||
|
||||
CScriptArray *_HexReader_getMetadatas(qsizetype offset);
|
||||
|
||||
CScriptArray *_HexReader_getMetaLine(qsizetype line);
|
||||
|
||||
CScriptArray *_HexReader_getsBookmarkPos(qsizetype line);
|
||||
|
||||
CScriptArray *_HexReader_getBookMarks();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -23,9 +23,9 @@
|
|||
|
||||
WorkSpaceManager::WorkSpaceManager() {}
|
||||
|
||||
bool WorkSpaceManager::loadWorkSpace(QString filename, QString &file,
|
||||
QList<BookMarkStruct> &bookmarks,
|
||||
QList<QHexMetadataAbsoluteItem> &metas,
|
||||
bool WorkSpaceManager::loadWorkSpace(const QString &filename, QString &file,
|
||||
QMap<qsizetype, QString> &bookmarks,
|
||||
QVector<QHexMetadataItem> &metas,
|
||||
WorkSpaceInfo &infos) {
|
||||
bool b = false;
|
||||
QFile f(filename);
|
||||
|
@ -98,7 +98,7 @@ bool WorkSpaceManager::loadWorkSpace(QString filename, QString &file,
|
|||
auto fcolor = QColor::fromRgba(nf);
|
||||
auto bcolor = QColor::fromRgba(nb);
|
||||
|
||||
QHexMetadataAbsoluteItem metaitem;
|
||||
QHexMetadataItem metaitem;
|
||||
metaitem.begin = nbegin;
|
||||
metaitem.end = nend;
|
||||
metaitem.comment = comment.toString();
|
||||
|
@ -114,7 +114,8 @@ bool WorkSpaceManager::loadWorkSpace(QString filename, QString &file,
|
|||
}
|
||||
values = jobj.value("bookmarks");
|
||||
if (!values.isUndefined() && values.isArray()) {
|
||||
for (auto item : values.toArray()) {
|
||||
auto array = values.toArray();
|
||||
for (auto item : array) {
|
||||
if (!item.isUndefined() && item.isObject()) {
|
||||
auto sitem = item.toObject();
|
||||
auto pos = sitem.value("pos");
|
||||
|
@ -127,10 +128,8 @@ bool WorkSpaceManager::loadWorkSpace(QString filename, QString &file,
|
|||
pos.toString().toLongLong(&b);
|
||||
if (!b || ipos < 0 || ipos >= maxbytes)
|
||||
continue;
|
||||
BookMarkStruct book;
|
||||
book.pos = ipos;
|
||||
book.comment = comment.toString();
|
||||
bookmarks.append(book);
|
||||
bookmarks.insert(ipos,
|
||||
comment.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -138,7 +137,8 @@ bool WorkSpaceManager::loadWorkSpace(QString filename, QString &file,
|
|||
|
||||
values = jobj.value("plugindata");
|
||||
if (!values.isUndefined() && values.isArray()) {
|
||||
for (auto item : values.toArray()) {
|
||||
auto array = values.toArray();
|
||||
for (auto item : array) {
|
||||
if (!item.isUndefined() && item.isObject()) {
|
||||
auto sitem = item.toObject();
|
||||
auto plgobj = sitem.value("key");
|
||||
|
@ -168,28 +168,29 @@ bool WorkSpaceManager::loadWorkSpace(QString filename, QString &file,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool WorkSpaceManager::saveWorkSpace(QString filename, QString file,
|
||||
QList<BookMarkStruct> bookmarklist,
|
||||
QList<QHexMetadataAbsoluteItem> metalist,
|
||||
WorkSpaceInfo infos) {
|
||||
bool WorkSpaceManager::saveWorkSpace(
|
||||
const QString &filename, const QString &file,
|
||||
const QMap<qsizetype, QString> &bookmarklist,
|
||||
const QVector<QHexMetadataItem> &metalist, const WorkSpaceInfo &infos) {
|
||||
QFile f(filename);
|
||||
if (f.open(QFile::WriteOnly)) {
|
||||
QJsonObject jobj;
|
||||
jobj.insert("type", "workspace");
|
||||
|
||||
QString ff = file;
|
||||
QFileInfo fileInfo(file);
|
||||
if (fileInfo.isAbsolute()) {
|
||||
QDir dir(QFileInfo(f).absoluteDir());
|
||||
QFileInfo fi(file);
|
||||
file = dir.relativeFilePath(fi.absoluteFilePath());
|
||||
ff = dir.relativeFilePath(fi.absoluteFilePath());
|
||||
}
|
||||
|
||||
jobj.insert("file", file);
|
||||
jobj.insert("file", ff);
|
||||
jobj.insert("encoding", infos.encoding);
|
||||
jobj.insert("base", QString::number(infos.base));
|
||||
|
||||
QJsonArray metas;
|
||||
for (auto meta : metalist) {
|
||||
for (auto &meta : metalist) {
|
||||
QJsonObject obj;
|
||||
obj.insert("begin", QString::number(meta.begin));
|
||||
obj.insert("end", QString::number(meta.end));
|
||||
|
@ -201,12 +202,13 @@ bool WorkSpaceManager::saveWorkSpace(QString filename, QString file,
|
|||
jobj.insert("metas", metas);
|
||||
|
||||
QJsonArray bookmarks;
|
||||
for (auto item : bookmarklist) {
|
||||
for (auto p = bookmarklist.cbegin(); p != bookmarklist.cend(); ++p) {
|
||||
QJsonObject i;
|
||||
i.insert("pos", QString::number(item.pos));
|
||||
i.insert("comment", item.comment);
|
||||
i.insert("pos", QString::number(p.key()));
|
||||
i.insert("comment", p.value());
|
||||
bookmarks.append(i);
|
||||
}
|
||||
|
||||
jobj.insert("bookmarks", bookmarks);
|
||||
|
||||
// plugin data
|
||||
|
|
|
@ -18,17 +18,17 @@
|
|||
#ifndef WORKSPACEMANAGER_H
|
||||
#define WORKSPACEMANAGER_H
|
||||
|
||||
#include "../../QHexView/document/qhexdocument.h"
|
||||
#include "../../QHexView/document/qhexmetadata.h"
|
||||
#include "QHexView/document/qhexmetadata.h"
|
||||
|
||||
#include <QHash>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonValue>
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
#include <QObject>
|
||||
#include <QStringList>
|
||||
#include <QVector>
|
||||
|
||||
struct WorkSpaceInfo {
|
||||
QString encoding = QStringLiteral("ASCII");
|
||||
|
@ -40,13 +40,13 @@ class WorkSpaceManager {
|
|||
|
||||
public:
|
||||
explicit WorkSpaceManager();
|
||||
bool static saveWorkSpace(QString filename, QString file,
|
||||
QList<BookMarkStruct> bookmarks,
|
||||
QList<QHexMetadataAbsoluteItem> metas,
|
||||
WorkSpaceInfo infos);
|
||||
bool static loadWorkSpace(QString filename, QString &file,
|
||||
QList<BookMarkStruct> &bookmarks,
|
||||
QList<QHexMetadataAbsoluteItem> &metas,
|
||||
bool static saveWorkSpace(const QString &filename, const QString &file,
|
||||
const QMap<qsizetype, QString> &bookmarks,
|
||||
const QVector<QHexMetadataItem> &metas,
|
||||
const WorkSpaceInfo &infos);
|
||||
bool static loadWorkSpace(const QString &filename, QString &file,
|
||||
QMap<qsizetype, QString> &bookmarks,
|
||||
QVector<QHexMetadataItem> &metas,
|
||||
WorkSpaceInfo &infos);
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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_
|
|
@ -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));
|
||||
}
|
|
@ -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_
|
|
@ -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);
|
||||
}
|
|
@ -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 ¶ms);
|
||||
|
||||
protected:
|
||||
virtual void contextMenuEvent(QContextMenuEvent *e);
|
||||
|
||||
protected slots:
|
||||
void indexActivated(const QModelIndex &idx);
|
||||
|
||||
private:
|
||||
QCodeModel *m_model;
|
||||
};
|
||||
|
||||
#endif // !_QCODE_VIEW_H_
|
|
@ -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);
|
||||
}
|
|
@ -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_
|
|
@ -293,8 +293,8 @@ ErrFile EditorView::openWorkSpace(const QString &filename,
|
|||
}
|
||||
|
||||
QString file;
|
||||
QList<BookMarkStruct> bookmarks;
|
||||
QList<QHexMetadataAbsoluteItem> metas;
|
||||
QMap<qsizetype, QString> bookmarks;
|
||||
QVector<QHexMetadataItem> metas;
|
||||
WorkSpaceInfo infos;
|
||||
|
||||
if (WorkSpaceManager::loadWorkSpace(filename, file, bookmarks, metas,
|
||||
|
@ -407,11 +407,11 @@ ErrFile EditorView::openDriver(const QString &driver, const QString &encoding) {
|
|||
}
|
||||
|
||||
ErrFile EditorView::save(const QString &workSpaceName, const QString &path,
|
||||
bool isExport, SaveWorkSpaceAttr workSpaceAttr,
|
||||
bool ignoreMd5) {
|
||||
bool ignoreMd5, bool isExport,
|
||||
SaveWorkSpaceAttr workSpaceAttr) {
|
||||
if (isCloneFile()) {
|
||||
return this->cloneParent()->save(workSpaceName, path, isExport,
|
||||
workSpaceAttr, ignoreMd5);
|
||||
return this->cloneParent()->save(workSpaceName, path, ignoreMd5,
|
||||
isExport, workSpaceAttr);
|
||||
}
|
||||
auto fileName = path.isEmpty() ? m_fileName : path;
|
||||
auto doc = m_hex->document();
|
||||
|
@ -447,8 +447,8 @@ ErrFile EditorView::save(const QString &workSpaceName, const QString &path,
|
|||
infos.base = doc->baseAddress();
|
||||
|
||||
auto b = WorkSpaceManager::saveWorkSpace(
|
||||
workSpaceName, m_fileName, doc->getAllBookMarks(),
|
||||
doc->metadata()->getallMetas(), infos);
|
||||
workSpaceName, m_fileName, doc->bookMarks(),
|
||||
doc->metadata()->getAllMetadata(), infos);
|
||||
if (!b)
|
||||
return ErrFile::WorkSpaceUnSaved;
|
||||
if (!isExport) {
|
||||
|
@ -548,7 +548,7 @@ qsizetype EditorView::findAvailCloneIndex() {
|
|||
|
||||
bool EditorView::hasMeta() const {
|
||||
auto doc = m_hex->document();
|
||||
return doc->metadata()->hasMetadata() || doc->bookMarksPtr()->size() > 0;
|
||||
return doc->metadata()->hasMetadata() || doc->bookMarksCount() > 0;
|
||||
}
|
||||
|
||||
void EditorView::applyPluginData(const QHash<QString, QByteArray> &data) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
@ -108,9 +108,8 @@ public slots:
|
|||
const QString &encoding = QString());
|
||||
ErrFile
|
||||
save(const QString &workSpaceName, const QString &path = QString(),
|
||||
bool isExport = false,
|
||||
SaveWorkSpaceAttr workSpaceAttr = SaveWorkSpaceAttr::AutoWorkSpace,
|
||||
bool ignoreMd5 = false);
|
||||
bool ignoreMd5 = false, bool isExport = false,
|
||||
SaveWorkSpaceAttr workSpaceAttr = SaveWorkSpaceAttr::AutoWorkSpace);
|
||||
ErrFile reload();
|
||||
|
||||
void setCopyLimit(qsizetype sizeMB);
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
@ -81,7 +80,7 @@ void QCodeCompletionWidget::adjustGeometry() {
|
|||
QDocumentCursor cursor = e->cursor();
|
||||
QDocumentLine line = cursor.line();
|
||||
const QRect lrect = e->lineRect(cursor.lineNumber());
|
||||
const QFontMetrics fm = QDocument::fontMetrics();
|
||||
const QFontMetrics fm = e->document()->fontMetrics();
|
||||
|
||||
int h = 0, w = 300, ls = fm.lineSpacing(), y = lrect.y(),
|
||||
x = line.cursorToX(cursor.columnNumber() + offset);
|
||||
|
@ -162,12 +161,12 @@ void QCodeCompletionWidget::setCompletions(const QList<QCodeNode *> &nodes) {
|
|||
pModel->setFocusNodes(nodes);
|
||||
}
|
||||
|
||||
void QCodeCompletionWidget::setCursor(const QDocumentCursor &c) { m_begin = c; }
|
||||
|
||||
void QCodeCompletionWidget::setTemporaryNodes(const QList<QCodeNode *> &l) {
|
||||
m_temps = l;
|
||||
}
|
||||
|
||||
bool QCodeCompletionWidget::isCompleting() const { return _completing; }
|
||||
|
||||
void QCodeCompletionWidget::clear() { pModel->clear(); }
|
||||
|
||||
void QCodeCompletionWidget::popup() {
|
||||
|
@ -194,6 +193,8 @@ void QCodeCompletionWidget::popup() {
|
|||
}
|
||||
|
||||
void QCodeCompletionWidget::complete(const QModelIndex &index) {
|
||||
_completing = true;
|
||||
|
||||
QEditor *e = editor();
|
||||
|
||||
if (!index.isValid() || !e)
|
||||
|
@ -220,15 +221,17 @@ void QCodeCompletionWidget::complete(const QModelIndex &index) {
|
|||
if (prefix.length() && txt.startsWith(prefix))
|
||||
txt.remove(0, prefix.length());
|
||||
|
||||
// c.insertText(txt);
|
||||
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();
|
||||
|
||||
_completing = false;
|
||||
}
|
||||
|
||||
void QCodeCompletionWidget::showEvent(QShowEvent *e) {
|
||||
|
@ -366,8 +369,6 @@ void QCodeCompletionWidget::keyPressEvent(QKeyEvent *e) {
|
|||
|
||||
////////////////////////////////
|
||||
|
||||
// static char *_q_authenticate_string = "x-application/QCodeCompletionModel";
|
||||
|
||||
QCodeCompletionModel::QCodeCompletionModel(QObject *p)
|
||||
: QAbstractListModel(p), bUpdate(false) {}
|
||||
|
||||
|
@ -404,8 +405,6 @@ void QCodeCompletionModel::setFilter(QCodeCompletionWidget::Filter filter) {
|
|||
void QCodeCompletionModel::update() { bUpdate = true; }
|
||||
|
||||
void QCodeCompletionModel::forceUpdate() const {
|
||||
// qDebug("updating model");
|
||||
|
||||
m_visibles.clear();
|
||||
|
||||
foreach (QCodeNode *n, m_nodes) {
|
||||
|
@ -416,17 +415,15 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// qDebug("model updated");
|
||||
|
||||
emit const_cast<QCodeCompletionModel *>(this)->layoutChanged();
|
||||
bUpdate = false;
|
||||
emit const_cast<QCodeCompletionModel *>(this)->changed();
|
||||
}
|
||||
|
||||
QList<QCodeNode *> QCodeCompletionModel::focusNodes() const { return m_nodes; }
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include <QListView>
|
||||
#include <QPointer>
|
||||
|
||||
#include "codemodel/qcodenode.h"
|
||||
#include "class/qcodenode.h"
|
||||
#include "qdocumentcursor.h"
|
||||
#include "qeditor.h"
|
||||
|
||||
|
@ -76,10 +76,10 @@ public:
|
|||
QStringList completions() const;
|
||||
void setCompletions(const QList<QCodeNode *> &nodes);
|
||||
|
||||
void setCursor(const QDocumentCursor &c);
|
||||
|
||||
void setTemporaryNodes(const QList<QCodeNode *> &l);
|
||||
|
||||
bool isCompleting() const;
|
||||
|
||||
public slots:
|
||||
void popup();
|
||||
void clear();
|
||||
|
@ -101,10 +101,10 @@ private:
|
|||
void adjustGeometry();
|
||||
|
||||
int offset;
|
||||
QDocumentCursor m_begin;
|
||||
QCodeCompletionModel *pModel;
|
||||
QPointer<QObject> pEditor;
|
||||
QList<QCodeNode *> m_temps;
|
||||
bool _completing = false;
|
||||
};
|
||||
|
||||
#endif // _QCOMPLETION_WIDGET_H_
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue