Compare commits

...

5 Commits

148 changed files with 5081 additions and 5143 deletions

View File

@ -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

View File

@ -1,3 +0,0 @@
*.pro.user*

View File

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

View File

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

View File

@ -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:

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -1,9 +0,0 @@
INCLUDEPATH += $$PWD
DEPENDPATH += $$PWD
SOURCES += $$PWD/QConsoleWidget.cpp \
$$PWD/QConsoleIODevice.cpp
HEADERS += $$PWD/QConsoleWidget.h \
$$PWD/QConsoleIODevice.h

View File

@ -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

View File

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

View File

@ -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

View File

@ -1,7 +1,7 @@
#include "metaaddcommand.h"
MetaAddCommand::MetaAddCommand(QHexMetadata *hexmeta,
QHexMetadataAbsoluteItem &meta,
const QHexMetadataItem &meta,
QUndoCommand *parent)
: MetaCommand(hexmeta, meta, parent) {}

View File

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

View File

@ -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) {}

View File

@ -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

View File

@ -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) {}

View File

@ -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

View File

@ -1,7 +1,7 @@
#include "metaremovecommand.h"
MetaRemoveCommand::MetaRemoveCommand(QHexMetadata *hexmeta,
QHexMetadataAbsoluteItem &meta,
const QHexMetadataItem &meta,
QUndoCommand *parent)
: MetaCommand(hexmeta, meta, parent) {}

View File

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

View File

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

View File

@ -18,7 +18,7 @@ public:
protected:
QHexMetadata *m_hexmeta;
qsizetype m_pos;
QList<QHexMetadataAbsoluteItem> olditems;
QVector<QHexMetadataItem> olditems;
};
#endif // METAREMOVEPOSCOMMAND_H

View File

@ -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) {}

View File

@ -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

View File

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

View File

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

View File

@ -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;
}

View File

@ -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

View File

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

View File

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

View File

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

View File

@ -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

View File

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

View File

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

View File

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

View File

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

View File

@ -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);
}
/*!

View File

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

View File

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

View File

@ -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

View File

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

View File

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

View File

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

View File

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

View File

@ -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) {

View File

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

View File

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

View File

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

View File

@ -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:

View File

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

View File

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

View File

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

View File

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

View File

@ -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_

View File

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

BIN
images/codefmt.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
images/codeformat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
images/snippt.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@ -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>

19
src/TESTCODE.as Normal file
View File

@ -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;
}

View File

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

View File

@ -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

View File

@ -32,20 +32,24 @@
#include "control/qcodecompletionwidget.h"
const auto DOT_TRIGGER = QStringLiteral(".");
const auto SEMI_COLON_TRIGGER = QStringLiteral("::");
const auto LEFT_PARE_TRIGGER = QStringLiteral("(");
Q_GLOBAL_STATIC_WITH_ARGS(QString, DOT_TRIGGER, ("."))
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);

View File

@ -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_

View File

@ -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 &params,
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; }

View File

@ -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 &params, 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

66
src/class/langservice.cpp Normal file
View File

@ -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; }

42
src/class/langservice.h Normal file
View File

@ -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

View File

@ -19,8 +19,7 @@
#include "AngelScript/sdk/angelscript/source/as_builder.h"
#include "AngelScript/sdk/angelscript/source/as_parser.h"
#include "codemodel/qcodemodel.h"
#include "codemodel/qcodenode.h"
#include "class/qcodenode.h"
#include <QDebug>
@ -33,9 +32,9 @@
*/
QAsParser::QAsParser(asIScriptEngine *engine) : asBuilder(), _engine(engine) {
addGlobalFunctionCompletion(engine);
addClassCompletion(engine);
addEnumCompletion(engine);
addGlobalFunctionCompletion(engine);
}
QAsParser::~QAsParser() {
@ -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; }

View File

@ -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;
};

View File

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

View File

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

View File

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

View File

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

View File

@ -103,7 +103,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;
}
}

View File

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

View File

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

View File

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

View File

@ -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;
}

View File

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

View File

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

View File

@ -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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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) {

View File

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

View File

@ -21,8 +21,7 @@
#include "qdocumentline.h"
#include "qeditor.h"
#include "codemodel/qcodemodel.h"
#include "codemodel/qcodenode.h"
#include "class/qcodenode.h"
#include "class/ascompletion.h"
@ -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; }

View File

@ -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