fix: 移除局部文件的支持;移除断点显示;修复文件编辑保存若干个问题;

This commit is contained in:
寂静的羽夏 2025-02-06 20:47:37 +08:00
parent 1e3b24bca0
commit 557311c85f
52 changed files with 1461 additions and 3141 deletions

View File

@ -13,8 +13,6 @@ add_library(
QHexView STATIC
document/buffer/qfilebuffer.cpp
document/buffer/qfilebuffer.h
document/buffer/qfileregionbuffer.cpp
document/buffer/qfileregionbuffer.h
document/buffer/qhexbuffer.cpp
document/buffer/qhexbuffer.h
document/buffer/qmemorybuffer.cpp

View File

@ -1,95 +0,0 @@
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** This program is free software: you can redistribute it and/or modify it under
** the terms of the GNU Affero General Public License as published by the Free
** Software Foundation, version 3.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
** details.
**
** You should have received a copy of the GNU Affero General Public License
** along with this program. If not, see <https://www.gnu.org/licenses/>.
**
** The original License is MIT from Dax89/QHexView. I have modified a lot so I
** decide to change the Open Source License. You can use the original library
** under MIT. Thanks for Dax89's efforts.
** =============================================================================
*/
#include "qfileregionbuffer.h"
#include <QFile>
#include <QFileInfo>
#ifdef Q_OS_LINUX
#include <unistd.h>
#endif
QFileRegionBuffer::QFileRegionBuffer(QObject *parent) : QHexBuffer(parent) {}
qsizetype QFileRegionBuffer::length() const { return buffer.length(); }
void QFileRegionBuffer::insert(qsizetype offset, const QByteArray &data) {
buffer.insert(offset, data);
return;
}
void QFileRegionBuffer::remove(qsizetype offset, qsizetype length) {
buffer.remove(offset, length);
}
QByteArray QFileRegionBuffer::read(qsizetype offset, qsizetype length) {
return buffer.mid(offset, length);
}
bool QFileRegionBuffer::read(QIODevice *iodevice) {
auto file = qobject_cast<QFile *>(iodevice);
if (file && file->open(QFile::ReadOnly)) {
#ifdef Q_OS_LINUX
lseek(file->handle(), offset,
SEEK_SET); // 有些特殊的文件 Qt 是不支持 seek 的,用原生函数
#else
file->seek(offset);
#endif
buffer = file->read(maxlength);
file->close();
return true;
}
return false;
}
#include <QDebug>
void QFileRegionBuffer::write(QIODevice *iodevice) {
auto file = qobject_cast<QFile *>(iodevice);
#ifdef Q_OS_LINUX
lseek(file->handle(), offset,
SEEK_SET); // 有些特殊的文件 Qt 是不支持 seek 的,用原生函数
#else
file->seek(offset);
#endif
file->write(buffer);
}
qsizetype QFileRegionBuffer::indexOf(const QByteArray &ba, qsizetype from) {
return buffer.indexOf(ba, int(from));
}
qsizetype QFileRegionBuffer::lastIndexOf(const QByteArray &ba, qsizetype from) {
return buffer.lastIndexOf(ba, int(from));
}
void QFileRegionBuffer::setReadOffset(qsizetype offset) {
this->offset = offset;
}
qsizetype QFileRegionBuffer::readOffset() { return offset; }
qsizetype QFileRegionBuffer::readMaxBytes() { return maxlength; }
void QFileRegionBuffer::setReadMaxBytes(qsizetype maxlength) {
if (maxlength)
this->maxlength = maxlength;
}

View File

@ -1,55 +0,0 @@
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** This program is free software: you can redistribute it and/or modify it under
** the terms of the GNU Affero General Public License as published by the Free
** Software Foundation, version 3.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
** details.
**
** You should have received a copy of the GNU Affero General Public License
** along with this program. If not, see <https://www.gnu.org/licenses/>.
**
** The original License is MIT from Dax89/QHexView. I have modified a lot so I
** decide to change the Open Source License. You can use the original library
** under MIT. Thanks for Dax89's efforts.
** =============================================================================
*/
#ifndef QFILEREGIONBUFFER_H
#define QFILEREGIONBUFFER_H
#include "qhexbuffer.h"
class QFileRegionBuffer : public QHexBuffer {
Q_OBJECT
public:
explicit QFileRegionBuffer(QObject *parent = nullptr);
public:
qsizetype length() const override;
void insert(qsizetype offset, const QByteArray &data) override;
void remove(qsizetype offset, qsizetype length) override;
QByteArray read(qsizetype offset, qsizetype length) override;
bool read(QIODevice *iodevice) override;
void write(QIODevice *iodevice) override;
qsizetype indexOf(const QByteArray &ba, qsizetype from) override;
qsizetype lastIndexOf(const QByteArray &ba, qsizetype from) override;
void setReadOffset(qsizetype offset);
qsizetype readOffset();
qsizetype readMaxBytes();
void setReadMaxBytes(qsizetype maxlength);
private:
qsizetype offset = 0;
qsizetype maxlength = 1024;
QByteArray buffer;
};
#endif // QFILEREGIONBUFFER_H

View File

@ -21,7 +21,6 @@
#include "qhexdocument.h"
#include "buffer/qfilebuffer.h"
#include "buffer/qfileregionbuffer.h"
#include "commands/baseaddrcommand.h"
#include "commands/bookmark/bookmarkaddcommand.h"
#include "commands/bookmark/bookmarkclearcommand.h"
@ -53,7 +52,10 @@ QList<qsizetype> QHexDocument::getLineBookmarksPos(qsizetype line) {
auto ubound = _bookmarks.upperBound(end);
for (auto p = lbound; p != ubound; ++p) {
pos.append(p.key());
auto off = p.key();
if (off >= begin && off < end) {
pos.append(off);
}
}
return pos;
@ -66,7 +68,14 @@ bool QHexDocument::lineHasBookMark(qsizetype line) {
auto lbound = _bookmarks.lowerBound(begin);
auto ubound = _bookmarks.upperBound(end);
return lbound != ubound;
for (auto p = lbound; p != ubound; ++p) {
auto off = p.key();
if (off >= begin && off < end) {
return true;
}
}
return false;
}
void QHexDocument::addUndoCommand(QUndoCommand *command) {
@ -345,6 +354,19 @@ bool QHexDocument::bookMarkExists(qsizetype pos) {
return _bookmarks.contains(pos);
}
QList<qsizetype> QHexDocument::bookMarkRange(qsizetype begin, qsizetype end) {
Q_ASSERT(end >= begin && begin >= 0);
auto it = _bookmarks.lowerBound(begin);
auto pend = _bookmarks.upperBound(end);
QList<qsizetype> ret;
while (it != pend) {
ret.append(it.key());
it++;
}
return ret;
}
qsizetype QHexDocument::bookMarkPos(qsizetype index) {
Q_ASSERT(index >= 0 && index < _bookmarks.size());
return *(std::next(_bookmarks.keyBegin(), index));
@ -431,23 +453,6 @@ void QHexDocument::findAllBytes(qsizetype begin, qsizetype end, QByteArray b,
}
}
QHexDocument *QHexDocument::fromRegionFile(QString filename, qsizetype start,
qsizetype length, bool readonly) {
QFile iodevice(filename);
auto hexbuffer = new QFileRegionBuffer;
hexbuffer->setReadOffset(start);
hexbuffer->setReadMaxBytes(length);
if (hexbuffer->read(&iodevice)) {
return new QHexDocument(hexbuffer, readonly);
} else {
delete hexbuffer;
}
return nullptr;
}
bool QHexDocument::insert(qsizetype offset, uchar b) {
if (m_keepsize || m_readonly || m_islocked ||
(offset < m_buffer->length() && m_metadata->hasMetadata()))
@ -654,7 +659,7 @@ void QHexDocument::Replace(QHexCursor *cursor, qsizetype offset,
bool QHexDocument::Remove(QHexCursor *cursor, qsizetype offset, qsizetype len,
int nibbleindex) {
if (m_keepsize || m_readonly || m_islocked || m_metadata->hasMetadata())
if (m_keepsize || m_readonly || m_islocked)
return false;
auto cmd = MakeRemove(nullptr, cursor, offset, len, nibbleindex);
if (cmd) {

View File

@ -88,6 +88,7 @@ public:
QString bookMark(qsizetype pos);
bool bookMarkExists(qsizetype pos);
QList<qsizetype> bookMarkRange(qsizetype begin, qsizetype end);
// note: maybe changed when bookmarks are chaged
qsizetype bookMarkPos(qsizetype index);
@ -204,10 +205,6 @@ public:
template <typename T>
static QHexDocument *fromFile(QString filename, bool readonly = false);
static QHexDocument *fromRegionFile(QString filename, qsizetype start,
qsizetype length,
bool readonly = false);
template <typename T>
static QHexDocument *fromMemory(char *data, int size,
bool readonly = false);

View File

@ -52,12 +52,14 @@ QHexLineMetadata QHexMetadata::get(qsizetype line) const {
//----------undo redo wrapper----------
void QHexMetadata::ModifyMetadata(const QHexMetadataItem &newmeta,
bool QHexMetadata::ModifyMetadata(const QHexMetadataItem &newmeta,
const QHexMetadataItem &oldmeta) {
auto cmd = MakeModifyMetadata(nullptr, newmeta, oldmeta);
if (cmd) {
m_undo->push(cmd);
return true;
}
return false;
}
void QHexMetadata::RemoveMetadatas(const QList<QHexMetadataItem> &items) {
@ -68,18 +70,22 @@ void QHexMetadata::RemoveMetadatas(const QList<QHexMetadataItem> &items) {
m_undo->endMacro();
}
void QHexMetadata::RemoveMetadata(const QHexMetadataItem &item) {
bool QHexMetadata::RemoveMetadata(const QHexMetadataItem &item) {
auto cmd = MakeRemoveMetadata(nullptr, item);
if (cmd) {
m_undo->push(cmd);
return true;
}
return false;
}
void QHexMetadata::RemoveMetadata(qsizetype offset) {
bool QHexMetadata::RemoveMetadata(qsizetype offset) {
auto cmd = MakeRemoveMetadata(nullptr, offset);
if (cmd) {
m_undo->push(cmd);
return true;
}
return false;
}
void QHexMetadata::Metadata(qsizetype begin, qsizetype end,

View File

@ -172,11 +172,11 @@ public:
void beginMarco(const QString &text);
void endMarco();
void ModifyMetadata(const QHexMetadataItem &newmeta,
bool ModifyMetadata(const QHexMetadataItem &newmeta,
const QHexMetadataItem &oldmeta);
void RemoveMetadatas(const QList<QHexMetadataItem> &items);
void RemoveMetadata(const QHexMetadataItem &item);
void RemoveMetadata(qsizetype offset);
bool RemoveMetadata(const QHexMetadataItem &item);
bool RemoveMetadata(qsizetype offset);
void Metadata(qsizetype begin, qsizetype end, const QColor &fgcolor,
const QColor &bgcolor, const QString &comment);
void Clear();

View File

@ -358,17 +358,19 @@ bool QHexView::RemoveSelection(int nibbleindex) {
return false;
auto total = m_cursor->selectionCount();
bool res = true;
m_document->beginMarco(QStringLiteral(""));
m_document->beginMarco(QStringLiteral("RemoveSelection"));
for (int i = 0; i < total; ++i) {
res &=
auto res =
m_document->Remove(m_cursor, m_cursor->selectionStart(i).offset(),
m_cursor->selectionLength(i), nibbleindex);
if (!res) {
break;
}
}
m_document->endMarco();
m_cursor->clearSelection();
return res;
return true;
}
bool QHexView::removeSelection() {
@ -417,16 +419,20 @@ QByteArrayList QHexView::selectedBytes() const {
void QHexView::paste(bool hex) {
QClipboard *c = qApp->clipboard();
QByteArray data = c->text().toUtf8();
QByteArray data;
if (hex) {
data = QByteArray::fromHex(c->text().toUtf8());
} else {
auto d = c->mimeData();
data = d->data(QStringLiteral("application/octet-stream"));
}
if (data.isEmpty())
return;
this->removeSelection();
if (hex)
data = QByteArray::fromHex(data);
auto pos = m_cursor->position().offset();
if (!m_document->isKeepSize()) {
m_document->insert(pos, data);
@ -451,19 +457,22 @@ bool QHexView::Cut(bool hex, int nibbleindex) {
}
}
void QHexView::Paste(int nibbleindex, bool hex) {
void QHexView::Paste(bool hex, int nibbleindex) {
QClipboard *c = qApp->clipboard();
QByteArray data = c->mimeData()->data(
QStringLiteral("application/octet-stream")); // don't use getText()
QByteArray data;
if (hex) {
data = QByteArray::fromHex(c->text().toUtf8());
} else {
auto d = c->mimeData();
data = d->data(QStringLiteral("application/octet-stream"));
}
if (data.isEmpty())
return;
this->RemoveSelection(nibbleindex);
if (hex)
data = QByteArray::fromHex(data);
auto pos = m_cursor->position().offset();
if (m_cursor->insertionMode() == QHexCursor::InsertionMode::InsertMode) {
m_document->Insert(m_cursor, pos, data, nibbleindex);
@ -511,13 +520,15 @@ bool QHexView::copy(bool hex) {
QByteArray bytes = this->selectedBytes().join();
if (hex)
if (hex) {
bytes = bytes.toHex(' ').toUpper();
auto mime = new QMimeData;
mime->setData(QStringLiteral("application/octet-stream"),
bytes); // don't use setText()
c->setMimeData(mime);
c->setText(bytes);
} else {
auto mime = new QMimeData;
mime->setData(QStringLiteral("application/octet-stream"),
bytes); // don't use setText()
c->setMimeData(mime);
}
// fix the bug by wingsummer
return true;

View File

@ -138,7 +138,7 @@ public:
void paste(bool hex = false);
bool Cut(bool hex = false, int nibbleindex = 0);
void Paste(int nibbleindex = 0, bool hex = false);
void Paste(bool hex = false, int nibbleindex = 0);
void Replace(qsizetype offset, uchar b, int nibbleindex);
void Replace(qsizetype offset, const QByteArray &data, int nibbleindex = 0);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -1,506 +0,0 @@
#include "qpathedit.h"
#include <QAction>
#include <QApplication>
#include <QCompleter>
#include <QDropEvent>
#include <QEvent>
#include <QFileSystemModel>
#include <QHBoxLayout>
#include <QKeyEvent>
#include <QLineEdit>
#include <QMimeData>
#include <QPainter>
#include <QRegularExpression>
#include <QRegularExpressionMatch>
#include <QStandardPaths>
#include <QTimer>
#include <QToolButton>
#include <QUrl>
#include <QValidator>
// HELPER CLASSES
QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Wpadded")
class PathValidator : public QValidator {
public:
PathValidator(QObject *parent);
void setMode(QPathEdit::PathMode mode);
void setAllowEmpty(bool allow);
State validate(QString &text, int &) const override;
private:
QPathEdit::PathMode mode;
bool allowEmpty;
};
QT_WARNING_POP
// QPATHEDIT IMPLEMENTATION
QPathEdit::QPathEdit(QWidget *parent, QPathEdit::Style style)
: QPathEdit(ExistingFile, parent, style) {}
QPathEdit::QPathEdit(QPathEdit::PathMode pathMode, QWidget *parent,
QPathEdit::Style style)
: QWidget(parent), edit(new QLineEdit(this)),
pathCompleter(new QCompleter(this)),
completerModel(new QFileSystemModel(this)),
pathValidator(new PathValidator(this)), dialog(new QFileDialog(this)),
currentValidPath(), wasPathValid(true), uiStyle(style),
mode(ExistingFile), defaultDir(QStandardPaths::writableLocation(
QStandardPaths::HomeLocation)),
allowEmpty(true), toolButton(new QToolButton(this)),
dialogAction(new QAction(getDefaultIcon(), tr("Open FileDialog"), this)),
hasCustomIcon(false) {
// setup dialog
dialog->setOptions(QFileDialog::Option(0));
setPathMode(pathMode);
connect(dialog, &QFileDialog::fileSelected, this,
&QPathEdit::dialogFileSelected);
// setup completer
completerModel->setRootPath(QString());
completerModel->setNameFilterDisables(false);
connect(completerModel, &QFileSystemModel::directoryLoaded, pathCompleter,
[this](const QString &) { pathCompleter->complete(); });
pathCompleter->setModel(completerModel);
wingdialog = new FramelessDialogBase(this);
dialog->setWindowFlag(Qt::Widget);
wingdialog->buildUpContent(dialog);
wingdialog->setWindowTitle(qAppName());
QObject::connect(dialog, &QFileDialog::finished, wingdialog,
&FramelessDialogBase::done);
// setup this
QHBoxLayout *layout = new QHBoxLayout(this);
layout->setContentsMargins(QMargins());
layout->setSpacing(0);
layout->addWidget(edit);
layout->addWidget(toolButton);
setLayout(layout);
// setup lineedit
edit->installEventFilter(this);
edit->setCompleter(pathCompleter);
edit->setValidator(pathValidator);
edit->setDragEnabled(true);
edit->setReadOnly(true);
connect(edit, &QLineEdit::editingFinished, this,
&QPathEdit::editTextUpdate);
connect(edit, &QLineEdit::textChanged, this, &QPathEdit::updateValidInfo);
// setup "button"
connect(dialogAction, &QAction::triggered, this, &QPathEdit::showDialog);
toolButton->setDefaultAction(dialogAction);
int height = edit->sizeHint().height();
#ifdef Q_OS_WIN
height += 2;
#endif
toolButton->setFixedSize(height, height);
QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Wimplicit-fallthrough")
QT_WARNING_DISABLE_CLANG("-Wimplicit-fallthrough")
switch (style) {
case JoinedButton:
edit->addAction(dialogAction, QLineEdit::TrailingPosition);
case NoButton:
toolButton->setVisible(false);
break;
default:
break;
}
QT_WARNING_POP
QWidget::setTabOrder(edit, toolButton);
setFocusPolicy(edit->focusPolicy());
setFocusProxy(edit);
setAcceptDrops(true);
}
QPathEdit::QPathEdit(QPathEdit::PathMode pathMode,
const QString &defaultDirectory, QWidget *parent,
QPathEdit::Style style)
: QPathEdit(pathMode, parent, style) {
setDefaultDirectory(defaultDirectory);
}
QPathEdit::PathMode QPathEdit::pathMode() const { return mode; }
void QPathEdit::setPathMode(PathMode pathMode) {
mode = pathMode;
pathValidator->setMode(pathMode);
currentValidPath.clear();
emit pathChanged(QString());
edit->clear();
switch (pathMode) {
case ExistingFile:
dialog->setAcceptMode(QFileDialog::AcceptOpen);
dialog->setFileMode(QFileDialog::ExistingFile);
completerModel->setFilter(QDir::AllEntries | QDir::AllDirs |
QDir::NoDotAndDotDot);
break;
case ExistingFolder:
dialog->setAcceptMode(QFileDialog::AcceptOpen);
dialog->setFileMode(QFileDialog::Directory);
completerModel->setFilter(QDir::Drives | QDir::Dirs |
QDir::NoDotAndDotDot);
break;
case AnyFile:
dialog->setAcceptMode(QFileDialog::AcceptSave);
dialog->setFileMode(QFileDialog::AnyFile);
completerModel->setFilter(QDir::AllEntries | QDir::AllDirs |
QDir::NoDotAndDotDot);
break;
}
}
QFileDialog::Options QPathEdit::dialogOptions() const {
return dialog->options();
}
void QPathEdit::setDialogOptions(QFileDialog::Options dialogOptions) {
dialog->setOptions(dialogOptions);
}
bool QPathEdit::isEmptyPathAllowed() const { return allowEmpty; }
void QPathEdit::setAllowEmptyPath(bool allowEmptyPath) {
allowEmpty = allowEmptyPath;
pathValidator->setAllowEmpty(allowEmptyPath);
}
QString QPathEdit::defaultDirectory() const { return defaultDir; }
void QPathEdit::setDefaultDirectory(const QString &defaultDirectory) {
defaultDir = defaultDirectory;
}
QString QPathEdit::path() const { return currentValidPath; }
QString QPathEdit::editPath() const { return edit->text(); }
QUrl QPathEdit::pathUrl() const {
return QUrl::fromLocalFile(currentValidPath);
}
bool QPathEdit::hasAcceptableInput() const { return wasPathValid; }
bool QPathEdit::setPath(QString path, bool allowInvalid) {
if (edit->text() == path)
return true;
if (allowInvalid)
edit->setText(path);
int pseudo = 0;
if (pathValidator->validate(path, pseudo) == QValidator::Acceptable) {
currentValidPath =
path.replace(QStringLiteral("\\"), QStringLiteral("/"));
if (!allowInvalid)
edit->setText(path);
emit pathChanged(path);
return true;
} else
return false;
}
void QPathEdit::clear() {
edit->clear();
currentValidPath.clear();
emit pathChanged(QString());
}
QString QPathEdit::placeholder() const { return edit->placeholderText(); }
void QPathEdit::setPlaceholder(const QString &placeholder) {
edit->setPlaceholderText(placeholder);
}
QStringList QPathEdit::nameFilters() const { return dialog->nameFilters(); }
void QPathEdit::setNameFilters(const QStringList &nameFilters) {
dialog->setNameFilters(nameFilters);
QStringList tmp = modelFilters(nameFilters);
completerModel->setNameFilters(tmp);
}
QStringList QPathEdit::mimeTypeFilters() const {
return dialog->mimeTypeFilters();
}
void QPathEdit::setMimeTypeFilters(const QStringList &mimeFilters) {
dialog->setMimeTypeFilters(mimeFilters);
QStringList tmp = modelFilters(dialog->nameFilters());
completerModel->setNameFilters(tmp);
}
bool QPathEdit::isEditable() const { return !edit->isReadOnly(); }
void QPathEdit::setEditable(bool editable) { edit->setReadOnly(!editable); }
bool QPathEdit::useCompleter() const { return edit->completer(); }
void QPathEdit::setUseCompleter(bool useCompleter) {
edit->setCompleter(useCompleter ? pathCompleter : nullptr);
}
QPathEdit::Style QPathEdit::style() const { return uiStyle; }
void QPathEdit::setStyle(QPathEdit::Style style,
QLineEdit::ActionPosition position) {
if (uiStyle == style)
return;
switch (style) {
case SeperatedButton:
edit->removeAction(dialogAction);
toolButton->setVisible(true);
break;
case JoinedButton:
edit->addAction(dialogAction, position);
toolButton->setVisible(false);
break;
case NoButton:
edit->removeAction(dialogAction);
toolButton->setVisible(false);
break;
}
uiStyle = style;
if (!hasCustomIcon)
dialogAction->setIcon(getDefaultIcon());
}
QIcon QPathEdit::dialogButtonIcon() const { return dialogAction->icon(); }
void QPathEdit::setDialogButtonIcon(const QIcon &icon) {
dialogAction->setIcon(icon);
hasCustomIcon = true;
}
void QPathEdit::resetDialogButtonIcon() {
dialogAction->setIcon(QPathEdit::getDefaultIcon());
hasCustomIcon = false;
}
void QPathEdit::showDialog() {
if (wingdialog->isVisible()) {
wingdialog->raise();
wingdialog->activateWindow();
return;
}
QString oldPath = edit->text();
if (oldPath.isEmpty())
dialog->setDirectory(defaultDir);
else {
if (mode == ExistingFolder)
dialog->setDirectory(oldPath);
else {
QFileInfo info(oldPath);
if (info.isDir())
dialog->setDirectory(oldPath);
else {
dialog->setDirectory(info.dir());
dialog->selectFile(info.fileName());
}
}
}
wingdialog->open();
}
void QPathEdit::updateValidInfo(const QString &path) {
emit editPathChanged(path);
completerModel->index(
QFileInfo(path).dir().absolutePath()); // enforce "directory loading"
if (edit->hasAcceptableInput()) {
if (!wasPathValid) {
wasPathValid = true;
edit->setPalette(palette());
emit acceptableInputChanged(wasPathValid);
}
} else {
if (wasPathValid) {
wasPathValid = false;
QPalette pal = palette();
pal.setColor(QPalette::Text, QColor(QStringLiteral("#B40404")));
edit->setPalette(pal);
emit acceptableInputChanged(wasPathValid);
}
}
}
void QPathEdit::editTextUpdate() {
if (edit->hasAcceptableInput()) {
QString newPath =
edit->text().replace(QStringLiteral("\\"), QStringLiteral("/"));
if (currentValidPath != newPath) {
currentValidPath = newPath;
emit pathChanged(currentValidPath);
}
}
}
void QPathEdit::dialogFileSelected(const QString &file) {
if (!file.isEmpty()) {
auto sels = dialog->selectedFiles();
edit->setText(
sels.first().replace(QStringLiteral("\\"), QStringLiteral("/")));
editTextUpdate();
}
}
QStringList QPathEdit::modelFilters(const QStringList &normalFilters) {
QStringList res;
foreach (QString filter, normalFilters) {
QRegularExpressionMatch match =
QRegularExpression(QStringLiteral("^.*\\((.*)\\)$")).match(filter);
if (match.hasMatch())
res.append(match.captured(1).split(
QRegularExpression(QStringLiteral("\\s"))));
}
return res;
}
QIcon QPathEdit::getDefaultIcon() {
switch (uiStyle) {
case SeperatedButton: {
QImage image(16, 16, QImage::Format_ARGB32);
image.fill(Qt::transparent);
QPainter painter(&image);
painter.setFont(font());
painter.setPen(palette().color(QPalette::ButtonText));
painter.setRenderHint(QPainter::TextAntialiasing);
painter.drawText(QRect(0, 0, 16, 16), Qt::AlignCenter, tr("..."));
return QPixmap::fromImage(image);
}
case JoinedButton:
return QIcon::fromTheme(
QStringLiteral("view-choose"),
QIcon(QStringLiteral(":/qpathedit/icons/dialog.ico")));
case NoButton:
return QIcon();
}
return QIcon();
}
bool QPathEdit::eventFilter(QObject *watched, QEvent *event) {
if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if (keyEvent->key() == Qt::Key_Space &&
keyEvent->modifiers() == Qt::ControlModifier) {
pathCompleter->complete();
return true;
} else
return QObject::eventFilter(watched, event);
} else if (event->type() == QEvent::Drop) {
QDropEvent *dropEvent = static_cast<QDropEvent *>(event);
if (dropEvent->mimeData()->hasUrls() &&
dropEvent->mimeData()->urls().count() == 1 &&
dropEvent->mimeData()->urls().first().isLocalFile()) {
QString filePath =
dropEvent->mimeData()->urls().first().toLocalFile();
bool matched = true;
QFileInfo fi(filePath);
if (!dialog->nameFilters().isEmpty() && fi.isFile() &&
mode == ExistingFile) {
const QString fileNameSuffix = fi.suffix();
if (!fileNameSuffix.isEmpty()) {
// regexp copied from Qt sources
// QPlatformFileDialogHelper::filterRegExp
static QRegularExpression regexp(
"^(.*)\\(([a-zA-Z0-9_.,*? "
"+;#\\-\\[\\]@\\{\\}/!<>\\$%&=^~:\\|]*)\\)$");
// Makes a ["*.png", "*.jpg", "*.bmp"] formatted list of
// filters from the extension filters in format ["Image
// Files (*.png *.jpg)",
// ""Bitmaps (*.bmp)]
QStringList extensionsFilters;
foreach (const QString &filter, dialog->nameFilters()) {
QString f = filter;
QRegularExpressionMatch match;
Q_UNUSED(filter.indexOf(regexp, 0, &match));
if (match.hasMatch())
f = match.captured(2);
#if QT_DEPRECATED_SINCE(5, 15)
extensionsFilters.append(
f.split(' ', Qt::SkipEmptyParts));
#elif
extensionsFilters.append(
f.split(' ', QString::SkipEmptyParts));
#endif
}
matched = false;
foreach (const QString &extensionFilter,
extensionsFilters) {
if (extensionFilter == QStringLiteral("*.*")) {
matched = true;
break;
}
const QString filterSuffix =
QFileInfo(extensionFilter).suffix();
if (!filterSuffix.isEmpty()) {
if (fileNameSuffix == filterSuffix) {
matched = true;
break;
}
}
}
}
}
if (matched)
setPath(filePath);
return true;
}
return false;
} else
return QObject::eventFilter(watched, event);
}
// HELPER CLASSES IMPLEMENTATION
PathValidator::PathValidator(QObject *parent)
: QValidator(parent), mode(QPathEdit::ExistingFile), allowEmpty(true) {}
void PathValidator::setMode(QPathEdit::PathMode mode) { this->mode = mode; }
void PathValidator::setAllowEmpty(bool allow) { allowEmpty = allow; }
QValidator::State PathValidator::validate(QString &text, int &) const {
// check if empty is accepted
if (text.isEmpty())
return allowEmpty ? QValidator::Acceptable : QValidator::Intermediate;
// nonexisting parent dir is not possible
QFileInfo pathInfo(text);
if (!pathInfo.dir().exists())
return QValidator::Invalid;
switch (mode) {
case QPathEdit::AnyFile: // acceptable, as long as it's not an directoy
if (pathInfo.isDir())
return QValidator::Intermediate;
else
return QValidator::Acceptable;
case QPathEdit::ExistingFile: // must be an existing file
if (pathInfo.exists() && pathInfo.isFile())
return QValidator::Acceptable;
else
return QValidator::Intermediate;
case QPathEdit::ExistingFolder: // must be an existing folder
if (pathInfo.exists() && pathInfo.isDir())
return QValidator::Acceptable;
else
return QValidator::Intermediate;
}
return QValidator::Invalid;
}

View File

@ -1,203 +0,0 @@
#ifndef QPATHEDIT_H
#define QPATHEDIT_H
#include "../src/dialog/framelessdialogbase.h"
#include <QFileDialog>
#include <QIcon>
#include <QLineEdit>
#include <QPointer>
#include <QString>
#include <QWidget>
class QLineEdit;
class QCompleter;
class PathValidator;
class QFileSystemModel;
class QToolButton;
//! The QPathEdit provides a simple way to get a path from the user as
//! comfortable as possible
class QPathEdit : public QWidget {
Q_OBJECT
//! Defines the Widgets appereance
Q_PROPERTY(Style style READ style WRITE setStyle)
//! Holds the icon to be used for the edits button
Q_PROPERTY(QIcon dialogButtonIcon READ dialogButtonIcon WRITE
setDialogButtonIcon RESET resetDialogButtonIcon)
//! Specifies the kind of path to be entered
Q_PROPERTY(PathMode pathMode READ pathMode WRITE setPathMode)
//! Options for the QFileDialog
Q_PROPERTY(QFileDialog::Options dialogOptions READ dialogOptions WRITE
setDialogOptions)
//! Specifies whether the path can be manually entered or not
Q_PROPERTY(bool editable READ isEditable WRITE setEditable)
//! Specifies whether an empty path is allowed or not
Q_PROPERTY(
bool allowEmptyPath READ isEmptyPathAllowed WRITE setAllowEmptyPath)
//! Turns the auto-completer for manual editing on and off
Q_PROPERTY(bool useCompleter READ useCompleter WRITE setUseCompleter)
//! Holds the default directory for the QFileDialog
Q_PROPERTY(QString defaultDirectory READ defaultDirectory WRITE
setDefaultDirectory)
//! Holds the currently entered, valid path
Q_PROPERTY(
QString path READ path WRITE setPath RESET clear NOTIFY pathChanged)
//! Holds the currently entered text which might not be a valid path
Q_PROPERTY(QString editPath READ editPath NOTIFY editPathChanged)
//! Holds the information, whether the current edits contents are a valid
//! path or not
Q_PROPERTY(bool acceptableInput READ hasAcceptableInput NOTIFY
acceptableInputChanged)
//! Specifiy a placeholder to be shown if no path is entered
Q_PROPERTY(QString placeholder READ placeholder WRITE setPlaceholder)
//! Holds name filters for the dialog and the completer
Q_PROPERTY(QStringList nameFilters READ nameFilters WRITE setNameFilters)
//! Holds mime filters for the dialog and the completer
Q_PROPERTY(QStringList mimeTypeFilters READ mimeTypeFilters WRITE
setMimeTypeFilters)
public:
//! Descibes various styles that the edit can take
enum Style {
SeperatedButton, //!< The button to open the dialog will be place next
//!< to the edit
JoinedButton, //!< The button to open the dialog will be placed inside
//!< the edit
NoButton //!< The QFileDialog is completly disabled and will never show.
//!< Thus, there is no button either
};
Q_ENUM(Style)
//! Describes modes for the kind of path
enum PathMode {
ExistingFile, //!< A single, existings file. This is basically "Open
//!< file"
ExistingFolder, //!< A single, existing directory. This is basically
//!< "Open Folder"
AnyFile //!< A single, valid file, no matter if exisiting or not (the
//!< directory, however, must exist). This is basically "Save
//!< File"
};
Q_ENUM(PathMode)
//! Constructs a new QPathEdit widget. The mode will be
//! QPathEdit::ExistingFile
explicit QPathEdit(QWidget *parent = nullptr,
Style style = SeperatedButton);
//! Constructs a new QPathEdit widget
explicit QPathEdit(PathMode pathMode, QWidget *parent = nullptr,
Style style = SeperatedButton);
//! Constructs a new QPathEdit widget with the given default directory
explicit QPathEdit(PathMode pathMode, const QString &defaultDirectory,
QWidget *parent = nullptr,
Style style = SeperatedButton);
//! READ-ACCESSOR for QPathEdit::pathMode
PathMode pathMode() const;
//! READ-ACCESSOR for QPathEdit::dialogOptions
QFileDialog::Options dialogOptions() const;
//! READ-ACCESSOR for QPathEdit::allowEmptyPath
bool isEmptyPathAllowed() const;
//! READ-ACCESSOR for QPathEdit::defaultDirectory
QString defaultDirectory() const;
//! READ-ACCESSOR for QPathEdit::path
QString path() const;
//! READ-ACCESSOR for QPathEdit::editPath
QString editPath() const;
//! Returns the entered path as an QUrl
QUrl pathUrl() const;
//! READ-ACCESSOR for QPathEdit::acceptableInput
bool hasAcceptableInput() const;
//! READ-ACCESSOR for QPathEdit::placeholder
QString placeholder() const;
//! READ-ACCESSOR for QPathEdit::nameFilters
QStringList nameFilters() const;
//! READ-ACCESSOR for QPathEdit::mimeTypeFilters
QStringList mimeTypeFilters() const;
//! READ-ACCESSOR for QPathEdit::editable
bool isEditable() const;
//! READ-ACCESSOR for QPathEdit::useCompleter
bool useCompleter() const;
//! READ-ACCESSOR for QPathEdit::style
Style style() const;
//! READ-ACCESSOR for QPathEdit::dialogButtonIcon
QIcon dialogButtonIcon() const;
//! WRITE-ACCESSOR for QPathEdit::pathMode
void setPathMode(PathMode pathMode);
//! WRITE-ACCESSOR for QPathEdit::dialogOptions
void setDialogOptions(QFileDialog::Options dialogOptions);
//! WRITE-ACCESSOR for QPathEdit::allowEmptyPath
void setAllowEmptyPath(bool allowEmptyPath);
//! WRITE-ACCESSOR for QPathEdit::defaultDirectory
void setDefaultDirectory(const QString &defaultDirectory);
//! WRITE-ACCESSOR for QPathEdit::path
bool setPath(QString path, bool allowInvalid = false);
//! RESET-ACCESSOR for QPathEdit::path
void clear();
//! WRITE-ACCESSOR for QPathEdit::placeholder
void setPlaceholder(const QString &placeholder);
//! WRITE-ACCESSOR for QPathEdit::nameFilters
void setNameFilters(const QStringList &nameFilters);
//! WRITE-ACCESSOR for QPathEdit::mimeTypeFilters
void setMimeTypeFilters(const QStringList &mimeTypeFilters);
//! WRITE-ACCESSOR for QPathEdit::editable
void setEditable(bool editable);
//! WRITE-ACCESSOR for QPathEdit::useCompleter
void setUseCompleter(bool useCompleter);
//! WRITE-ACCESSOR for QPathEdit::style
void
setStyle(Style style,
QLineEdit::ActionPosition position = QLineEdit::TrailingPosition);
//! WRITE-ACCESSOR for QPathEdit::dialogButtonIcon
void setDialogButtonIcon(const QIcon &icon);
//! RESET-ACCESSOR for QPathEdit::dialogButtonIcon
void resetDialogButtonIcon();
public slots:
//! Shows the QFileDialog so the user can select a path
void showDialog();
signals:
//! NOTIFY-ACCESSOR for QPathEdit::path
void pathChanged(QString path);
//! NOTIFY-ACCESSOR for QPathEdit::editPath
void editPathChanged(QString path);
//! NOTIFY-ACCESSOR for QPathEdit::acceptableInput
void acceptableInputChanged(bool acceptableInput);
private slots:
void updateValidInfo(const QString &path = QString());
void editTextUpdate();
void dialogFileSelected(const QString &file);
private:
QLineEdit *edit;
QCompleter *pathCompleter;
QFileSystemModel *completerModel;
PathValidator *pathValidator;
QFileDialog *dialog;
FramelessDialogBase *wingdialog;
QString currentValidPath;
bool wasPathValid;
Style uiStyle;
PathMode mode;
QString defaultDir;
bool allowEmpty;
QToolButton *toolButton;
QAction *dialogAction;
bool hasCustomIcon;
QStringList modelFilters(const QStringList &normalFilters);
QIcon getDefaultIcon();
bool eventFilter(QObject *watched, QEvent *event) override;
};
#endif // QPATHEDIT_H

View File

@ -118,9 +118,6 @@ set(RIBBON_SRC
3rdparty/QWingRibbon/ribbontabcontent.h
3rdparty/QWingRibbon/ribbontabcontent.ui)
set(QPATHEDIT_SRC 3rdparty/QPathEdit/qpathedit.cpp
3rdparty/QPathEdit/qpathedit.h)
set(QCONSOLEWIDGET_SRC
3rdparty/QConsoleWidget/QConsoleIODevice.cpp
3rdparty/QConsoleWidget/QConsoleIODevice.h
@ -150,8 +147,6 @@ set(DIALOG_SRC
src/dialog/metadialog.h
src/dialog/driverselectordialog.cpp
src/dialog/driverselectordialog.h
src/dialog/openregiondialog.cpp
src/dialog/openregiondialog.h
src/dialog/scriptingdialog.h
src/dialog/scriptingdialog.cpp
src/dialog/finddialog.cpp
@ -308,9 +303,7 @@ set(MODEL_SRC
src/model/dbgcallstackmodel.h
src/model/dbgcallstackmodel.cpp
src/model/dbgvarshowmodel.h
src/model/dbgvarshowmodel.cpp
src/model/dbgbreakpointmodel.h
src/model/dbgbreakpointmodel.cpp)
src/model/dbgvarshowmodel.cpp)
set(SETTING_SRC
src/settings/settings.h
@ -387,7 +380,6 @@ set(TRANSLATION_PATH
${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/QConsoleWidget
${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/QHexView
${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/QJsonModel
${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/QPathEdit
${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/qcodeedit2
${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/Qt-Advanced-Docking-System/src
${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/QWingRibbon
@ -455,7 +447,6 @@ set(PROJECT_SOURCES
src/dbghelper.h
src/define.h
${QCONSOLEWIDGET_SRC}
${QPATHEDIT_SRC}
${WIDGET_FRAME_SRC}
${RIBBON_SRC}
${CLASS_SRC}

View File

@ -102,3 +102,4 @@ END
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_ICON1 ICON "appicon.ico"
IDI_ICON2 ICON "pro.ico"

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -250,6 +250,9 @@ 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\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 += r'Root: HKCR; Subkey: ".wingpro"; ValueType: string; ValueName: ""; ValueData: "WingHexExplorer2" ;Flags: noerror uninsdeletevalue; ' + '\n'
iss_content += r'Root: HKCR; Subkey: "WingHexExplorer2\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},1"; Flags: noerror uninsdeletevalue; ' + '\n'
iss_content += r'Root: HKCR; Subkey: "WingHexExplorer2\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1""" ;Flags: noerror uninsdeletevalue; ' + '\n'
iss_content += """
[Icons]

BIN
pro.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 KiB

View File

@ -62,7 +62,6 @@
<file>images/openapp.png</file>
<file>images/opendriver.png</file>
<file>images/openother.png</file>
<file>images/openr.png</file>
<file>images/other.png</file>
<file>images/paste.png</file>
<file>images/pastehex.png</file>
@ -119,9 +118,6 @@
<file>src/components.md</file>
<file>src/translist.md</file>
</qresource>
<qresource prefix="/qpathedit/icons">
<file alias="dialog.ico">3rdparty/QPathEdit/Fatcow-Farm-Fresh-Dialog.ico</file>
</qresource>
<qresource prefix="/qcodeedit">
<file alias="as.qnfa">src/qxs/as.qnfa</file>
<file alias="as_dark.qxf">src/qxs/as_dark.qxf</file>
@ -140,6 +136,7 @@
</qresource>
<qresource prefix="/completion">
<file>images/completion/CTvirtuals.png</file>
<file>images/completion/CVKeyword.png</file>
<file>images/completion/CVclass.png</file>
<file>images/completion/CVenum.png</file>
<file>images/completion/CVenumerator.png</file>

View File

@ -139,8 +139,7 @@ AppManager *AppManager::instance() { return _instance; }
MainWindow *AppManager::mainWindow() const { return _w; }
void AppManager::openFile(const QString &file, bool autoDetect, qsizetype start,
qsizetype stop) {
void AppManager::openFile(const QString &file, bool autoDetect) {
EditorView *editor = nullptr;
Q_ASSERT(_w);
if (Utilities::isStorageDevice(file)) {
@ -151,11 +150,8 @@ void AppManager::openFile(const QString &file, bool autoDetect, qsizetype start,
ret = _w->openWorkSpace(file, &editor);
}
if (ret == ErrFile::Error) {
if (start >= 0 && stop > 0) {
ret = _w->openRegionFile(file, &editor, start, stop);
} else {
ret = _w->openFile(file, &editor);
}
ret = _w->openFile(file, &editor);
if (ret == ErrFile::AlreadyOpened) {
Q_ASSERT(editor);
if (_w->currentEditor() == editor) {
@ -213,23 +209,6 @@ void AppManager::openDriver(const QString &driver) {
}
}
void AppManager::openRegionFile(const QString &region, qsizetype start,
qsizetype length) {
EditorView *editor = nullptr;
Q_ASSERT(_w);
auto ret = _w->openRegionFile(region, &editor, start, length);
if (ret == ErrFile::AlreadyOpened) {
Q_ASSERT(editor);
if (_w->currentEditor() == editor) {
Toast::toast(_w, NAMEICONRES("openapp"), tr("AlreadyOpened"));
} else {
editor->raise();
}
editor->setFocus();
}
}
void AppManager::openWorkSpace(const QString &ws) {
EditorView *editor = nullptr;
Q_ASSERT(_w);

View File

@ -37,12 +37,9 @@ public:
}
public slots:
void openFile(const QString &file, bool autoDetect = true,
qsizetype start = -1, qsizetype stop = -1);
void openFile(const QString &file, bool autoDetect = true);
void openRawFile(const QString &file);
void openDriver(const QString &driver);
void openRegionFile(const QString &region, qsizetype start = -1,
qsizetype length = -1);
void openWorkSpace(const QString &ws);
private:

View File

@ -681,146 +681,6 @@ QString asDebugger::printValue(const QString &expr, asIScriptContext *ctx,
}
}
bool asDebugger::interpretCommand(const QString &cmd, asIScriptContext *ctx) {
if (cmd.length() == 0)
return true;
switch (cmd[0].toLatin1()) {
case 'c':
m_action = CONTINUE;
break;
case 's':
m_action = STEP_INTO;
break;
case 'n':
m_action = STEP_OVER;
m_lastCommandAtStackLevel = ctx ? ctx->GetCallstackSize() : 1;
break;
case 'o':
m_action = STEP_OUT;
m_lastCommandAtStackLevel = ctx ? ctx->GetCallstackSize() : 0;
break;
case 'b': {
// Set break point
// auto p = cmd.indexOf(cmdRegExp, 1);
// auto div = cmd.indexOf(':');
// if (div > 2 && p > 1) {
// auto file = cmd.mid(2, div - 2);
// auto line = cmd.mid(div + 1);
// int nbr = line.toInt();
// addFileBreakPoint(file, nbr);
// } else if (div < 0 && p > 1) {
// auto func = cmd.mid(p);
// addFuncBreakPoint(func);
// } else {
// outputString(tr(
// "Incorrect format for setting break point, expected one
// of:\n" " b <file name>:<line number>\n" " b <function
// name>"));
// }
}
// take more commands
return false;
case 'r': {
// Remove break point
// auto p = cmd.indexOf(cmdRegExp, 1);
// if (cmd.length() > 2 && p > 1) {
// auto br = cmd.mid(2);
// if (br == QStringLiteral("all")) {
// m_breakPoints.clear();
// outputString(tr("All break points have been removed"));
// } else {
// int nbr = br.toInt();
// if (nbr >= 0 && nbr < m_breakPoints.size())
// m_breakPoints.erase(m_breakPoints.begin() + nbr);
// }
// } else {
// outputString(
// "Incorrect format for removing break points, expected:\n"
// " r <all|number of break point>\n");
// }
}
// take more commands
return false;
case 'l': {
// List something
// bool printHelp = false;
// auto p = cmd.indexOf(cmdRegExp, 1);
// if (p > 1) {
// auto c = cmd.at(2);
// if (c == 'b') {
// // listBreakPoints();
// } else if (c == 'v') {
// // listLocalVariables(ctx);
// } else if (c == 'g') {
// // listGlobalVariables(ctx);
// } else if (c == 'm') {
// // listMemberProperties(ctx);
// } else if (c == 's') {
// // listStatistics(ctx);
// } else {
// outputString(tr("Unknown list option."));
// printHelp = true;
// }
// } else {
// outputString(tr("Incorrect format for list command."));
// printHelp = true;
// }
// if (printHelp) {
// outputString(tr("Expected format: \n"
// " l <list option>\n"
// "Available options: \n"
// " b - breakpoints\n"
// " v - local variables\n"
// " m - member properties\n"
// " g - global variables\n"
// " s - statistics"));
// }
}
// take more commands
return false;
case 'h':
// printHelp();
// take more commands
return false;
case 'p': {
// Print a value
// auto p = cmd.indexOf(cmdRegExp, 1);
// if (p > 1) {
// printValue(cmd.mid(p), ctx);
// } else {
// outputString(tr("Incorrect format for print, expected:\n"
// " p <expression>"));
// }
}
// take more commands
return false;
case 'a':
// abort the execution
if (ctx == nullptr) {
// outputString(tr("No script is running"));
return false;
}
ctx->Abort();
break;
}
// Continue execution
return true;
}
int asDebugger::expandMembers() const { return _expandMembers; }
void asDebugger::setExpandMembers(int newExpandMembers) {

View File

@ -132,9 +132,6 @@ private:
bool checkBreakPoint(asIScriptContext *ctx);
void listMemberProperties(asIScriptContext *ctx);
// Helpers
bool interpretCommand(const QString &cmd, asIScriptContext *ctx);
signals:
void breakPointChanged();
void onAdjustBreakPointLine(const BreakPoint &old, int newLineNr);

View File

@ -24,6 +24,7 @@ enum CacheIndex {
// ICON_UNION,
ICON_CLASS,
// ICON_STRUCT,
ICON_KEYWORD,
ICON_TYPEDEF,
ICON_NAMESPACE,
ICON_FUNCTION = ICON_NAMESPACE + 2,

View File

@ -70,7 +70,8 @@ public:
Namespace = 'n',
Typedef = 't'
Typedef = 't',
KeyWord = 'k'
};
enum NodeContent {

View File

@ -19,9 +19,6 @@
QKeySequences::QKeySequences() {
_kseqs = {
{Key::OPEN_REGION_FILE,
QKeySequence(Qt::KeyboardModifier::ControlModifier |
Qt::KeyboardModifier::ShiftModifier | Qt::Key_O)},
{Key::OPEN_WORKSPACE,
QKeySequence(Qt::KeyboardModifier::ControlModifier | Qt::Key_W)},
{Key::REDO,

View File

@ -24,7 +24,6 @@
class QKeySequences {
public:
enum class Key {
OPEN_REGION_FILE,
OPEN_WORKSPACE,
REDO,
SAVE_AS,

View File

@ -109,11 +109,6 @@ QString RecentFileManager::getDisplayFileName(const RecentInfo &info) {
displayName = finfo.fileName();
}
if (info.start >= 0 && info.length > 0) {
displayName +=
QStringLiteral(" [%1, %2]").arg(info.start).arg(info.length);
}
return displayName;
}
@ -129,13 +124,6 @@ QString RecentFileManager::getDisplayTooltip(const RecentInfo &info,
tt += QStringLiteral("<p>") + tr("[isWorkSpace]") +
(info.isWorkSpace ? tr("True") : tr("False")) +
QStringLiteral("</p>");
if (info.start >= 0 && info.length > 0) {
tt += QStringLiteral("<p>") + tr("[start]") +
QString::number(info.start) + QStringLiteral("</p>");
tt += QStringLiteral("<p>") + tr("[stop]") +
QString::number(info.length) + QStringLiteral("</p>");
}
}
return tt;
}

View File

@ -29,8 +29,6 @@ public:
struct RecentInfo {
QString fileName;
bool isWorkSpace = false;
qsizetype start = -1;
qsizetype length = -1;
bool operator==(const RecentInfo &info) const {
return
@ -39,8 +37,7 @@ public:
#else
this->fileName == info.fileName
#endif
&& this->isWorkSpace == info.isWorkSpace &&
this->start == info.start && this->length == info.length;
&& this->isWorkSpace == info.isWorkSpace;
}
bool operator!=(const RecentInfo &info) const {
return
@ -49,24 +46,19 @@ public:
#else
this->fileName != info.fileName
#endif
|| this->isWorkSpace != info.isWorkSpace ||
this->start != info.start || this->length != info.length;
|| this->isWorkSpace != info.isWorkSpace;
}
friend QDataStream &operator<<(QDataStream &arch,
const RecentInfo &object) {
arch << object.fileName;
arch << object.isWorkSpace;
arch << object.start;
arch << object.length;
return arch;
}
friend QDataStream &operator>>(QDataStream &arch, RecentInfo &object) {
arch >> object.fileName;
arch >> object.isWorkSpace;
arch >> object.start;
arch >> object.length;
return arch;
}
};

View File

@ -545,7 +545,7 @@ int ScriptMachine::pragmaCallback(const QByteArray &pragmaText,
auto pn = tokens.takeFirst();
if (PluginSystem::instance().dispatchEvent(
IWingPlugin::RegisteredEvent::ScriptPragma,
{quintptr(builder), sectionname, pn, tokens})) {
{sectionname, pn, tokens})) {
return 0;
}

View File

@ -1089,14 +1089,6 @@ void WingAngelAPI::installHexControllerAPI(asIScriptEngine *engine) {
std::placeholders::_1, std::placeholders::_2),
"ErrFile openExtFile(string &in ext, string &in file)");
registerAPI<WingHex::ErrFile(const QString &, qsizetype, qsizetype)>(
engine,
std::bind(&WingHex::WingPlugin::Controller::openRegionFile, ctl,
std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3),
"ErrFile openRegionFile(string &in filename, " QSIZETYPE
" start = 0, " QSIZETYPE " length = 1024)");
registerAPI<WingHex::ErrFile(const QString &)>(
engine,
std::bind(&WingHex::WingPlugin::Controller::openDriver, ctl,
@ -1115,27 +1107,23 @@ void WingAngelAPI::installHexControllerAPI(asIScriptEngine *engine) {
std::placeholders::_1),
"ErrFile closeHandle(int handle)");
registerAPI<WingHex::ErrFile(int, bool)>(
registerAPI<WingHex::ErrFile(int)>(
engine,
std::bind(&WingHex::WingPlugin::Controller::saveFile, ctl,
std::placeholders::_1, std::placeholders::_2),
"ErrFile saveFile(int handle, bool ignoreMd5 = false)");
std::placeholders::_1),
"ErrFile saveFile(int handle)");
registerAPI<WingHex::ErrFile(int, const QString &, bool)>(
registerAPI<WingHex::ErrFile(int, const QString &)>(
engine,
std::bind(&WingHex::WingPlugin::Controller::exportFile, ctl,
std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3),
"ErrFile exportFile(int handle, string &in savename, "
"bool ignoreMd5 = false)");
std::placeholders::_1, std::placeholders::_2),
"ErrFile exportFile(int handle, string &in savename)");
registerAPI<WingHex::ErrFile(int, const QString &, bool)>(
registerAPI<WingHex::ErrFile(int, const QString &)>(
engine,
std::bind(&WingHex::WingPlugin::Controller::saveAsFile, ctl,
std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3),
"ErrFile saveAsFile(int handle, string &in savename, "
"bool ignoreMd5 = false)");
std::placeholders::_1, std::placeholders::_2),
"ErrFile saveAsFile(int handle, string &in savename)");
registerAPI<WingHex::ErrFile()>(
engine, std::bind(&WingHex::WingPlugin::Controller::openCurrent, ctl),
@ -1147,23 +1135,21 @@ void WingAngelAPI::installHexControllerAPI(asIScriptEngine *engine) {
std::placeholders::_1),
"ErrFile closeCurrent(bool force = false)");
registerAPI<WingHex::ErrFile(bool)>(
engine,
std::bind(&WingHex::WingPlugin::Controller::saveCurrent, ctl,
std::placeholders::_1),
"ErrFile saveCurrent(bool ignoreMd5 = false)");
registerAPI<WingHex::ErrFile()>(
engine, std::bind(&WingHex::WingPlugin::Controller::saveCurrent, ctl),
"ErrFile saveCurrent()");
registerAPI<WingHex::ErrFile(const QString &, bool)>(
registerAPI<WingHex::ErrFile(const QString &)>(
engine,
std::bind(&WingHex::WingPlugin::Controller::saveAsCurrent, ctl,
std::placeholders::_1, std::placeholders::_2),
"ErrFile saveAsCurrent(string &in savename, bool ignoreMd5 = false)");
std::placeholders::_1),
"ErrFile saveAsCurrent(string &in savename)");
registerAPI<WingHex::ErrFile(const QString &, bool)>(
registerAPI<WingHex::ErrFile(const QString &)>(
engine,
std::bind(&WingHex::WingPlugin::Controller::exportCurrent, ctl,
std::placeholders::_1, std::placeholders::_2),
"ErrFile exportCurrent(string &in savename, bool ignoreMd5 = false)");
std::placeholders::_1),
"ErrFile exportCurrent(string &in savename)");
registerAPI<bool(qsizetype, const QString &)>(
engine,
@ -1673,13 +1659,11 @@ QVariant WingAngelAPI::qvariantGet(asIScriptEngine *engine, const void *raw,
if (qstrcmp(tname, "dictionary") == 0) {
auto values =
*getDereferencePointer<CScriptDictionary *>(raw, isHandle);
auto len = values->GetSize();
auto keys = values->GetKeys();
// QMap or QHash ?
if (flag) {
QVariantHash hash;
for (auto it : *values) {
for (auto &it : *values) {
// Determine the name of the key
auto key = it.GetKey();
@ -1692,7 +1676,7 @@ QVariant WingAngelAPI::qvariantGet(asIScriptEngine *engine, const void *raw,
return hash;
} else {
QVariantMap map;
for (auto it : *values) {
for (auto &it : *values) {
// Determine the name of the key
auto key = it.GetKey();
@ -1959,7 +1943,6 @@ void WingAngelAPI::script_unsafe_call(asIScriptGeneric *gen) {
fn->GetUserData(AsUserDataType::UserData_API));
auto id = reinterpret_cast<qsizetype>(
fn->GetUserData(AsUserDataType::UserData_PluginFn));
auto engine = fn->GetEngine();
Q_ASSERT(p);
Q_ASSERT(id >= 0 && id < p->_usfns.size());

View File

@ -8,7 +8,6 @@ The following components are all third-party components used by the software. Th
* [QCodeEditor2](https://sourceforge.net/projects/edyuk) (GPL, **FORK**)
* [QWingRibbon](https://github.com/martijnkoopman/Qt-Ribbon-Widget) (LGPL, **FORK**)
* [QtSingleApplication](https://github.com/qtproject/qt-solutions/tree/master/qtsingleapplication) (BSD-3-Clause)
* [QPathEdit](https://github.com/Skycoder42/QPathEdit) (MIT)
* [QWindowKit](https://github.com/stdware/qwindowkit) (Apache v2.0)
* [AngelScript](https://github.com/codecat/angelscript-mirror) (zlib license)
* [QConsoleWidget](https://github.com/gapost/qconsolewidget) (MIT, **FORK** -> AGPL-3.0)

View File

@ -18,16 +18,14 @@ QMenu *DockWidgetTab::buildContextMenu(QMenu *menu) {
auto dw = dockWidget();
auto v = qobject_cast<EditorView *>(dw);
if (v) {
if (v->isRegionFile() || v->isCommonFile()) {
if (v->isCommonFile()) {
initMenuItems(menu, v->fileName());
}
auto a = new QAction(ICONRES("info"), tr("FileInfo"), menu);
connect(a, &QAction::triggered, this, [this]() {
auto editor = qobject_cast<EditorView *>(dockWidget());
if (editor) {
FileInfoDialog d(editor->fileName(),
editor->documentType() ==
EditorView::DocumentType::RegionFile);
FileInfoDialog d(editor->fileName());
d.exec();
}
});
@ -47,7 +45,7 @@ QMenu *DockWidgetTab::buildContextMenu(QMenu *menu) {
void DockWidgetTab::initMenuItems(QMenu *menu, const QString &path) {
Q_ASSERT(menu);
auto a = new QAction(ICONRES("shell"), tr("ShowInShell"), menu);
connect(a, &QAction::triggered, this, [this, path]() {
connect(a, &QAction::triggered, this, [path]() {
ShowInShell::showInGraphicalShell(AppManager::instance()->mainWindow(),
path, false);
});

View File

@ -18,14 +18,11 @@
#include "editorview.h"
#include "QHexView/document/buffer/qfilebuffer.h"
#include "QHexView/document/buffer/qfileregionbuffer.h"
#include "QHexView/document/buffer/qmemorybuffer.h"
#include "Qt-Advanced-Docking-System/src/DockWidgetTab.h"
#include "class/eventfilter.h"
#include "class/qkeysequences.h"
#include "class/settingmanager.h"
#include "class/workspacemanager.h"
#include "dialog/fileinfodialog.h"
#include "plugin/pluginsystem.h"
#include "utilities.h"
@ -49,7 +46,8 @@ EditorView::EditorView(QWidget *parent)
this->setFeatures(
CDockWidget::DockWidgetFocusable | CDockWidget::DockWidgetMovable |
CDockWidget::DockWidgetClosable | CDockWidget::DockWidgetPinnable |
CDockWidget::CustomCloseHandling);
CDockWidget::CustomCloseHandling |
CDockWidget::DockWidgetDeleteOnClose);
this->setFocusPolicy(Qt::StrongFocus);
this->setObjectName(QStringLiteral("EditorView"));
@ -436,47 +434,6 @@ ErrFile EditorView::openWorkSpace(const QString &filename) {
return ErrFile::Error;
}
ErrFile EditorView::openRegionFile(QString filename, qsizetype start,
qsizetype length) {
if (isCloneFile()) {
return ErrFile::ClonedFile;
}
QFileInfo info(filename);
if (info.exists()) {
if (Q_UNLIKELY(!info.permission(QFile::ReadUser))) {
return ErrFile::Permission;
}
auto readonly = !Utilities::fileCanWrite(filename);
auto *p =
QHexDocument::fromRegionFile(filename, start, length, readonly);
if (Q_UNLIKELY(p == nullptr)) {
return ErrFile::Permission;
}
m_docType = DocumentType::RegionFile;
m_hex->setDocument(QSharedPointer<QHexDocument>(p));
m_hex->setLockedFile(readonly);
m_hex->setKeepSize(true);
p->setDocSaved();
m_fileName = info.absoluteFilePath();
m_isNewFile = false;
this->setWindowTitle(info.fileName());
connectDocSavedFlag(this);
auto tab = this->tabWidget();
tab->setIcon(Utilities::getIconFromFile(style(), m_fileName));
tab->setToolTip(m_fileName);
}
return ErrFile::Success;
}
ErrFile EditorView::openDriver(const QString &driver) {
if (isCloneFile()) {
return ErrFile::ClonedFile;
@ -515,11 +472,10 @@ ErrFile EditorView::openDriver(const QString &driver) {
}
ErrFile EditorView::save(const QString &workSpaceName, const QString &path,
bool ignoreMd5, bool isExport,
SaveWorkSpaceAttr workSpaceAttr) {
bool isExport, SaveWorkSpaceAttr workSpaceAttr) {
if (isCloneFile()) {
return this->cloneParent()->save(workSpaceName, path, ignoreMd5,
isExport, workSpaceAttr);
return this->cloneParent()->save(workSpaceName, path, isExport,
workSpaceAttr);
}
auto fileName = path.isEmpty() ? m_fileName : path;
auto doc = m_hex->document();
@ -583,24 +539,11 @@ ErrFile EditorView::save(const QString &workSpaceName, const QString &path,
_dev->close();
} else {
QFile file(fileName);
switch (m_docType) {
case DocumentType::RegionFile: {
if (!ignoreMd5 && Utilities::getMd5(m_fileName) != m_md5) {
return ErrFile::SourceFileChanged;
}
if (!file.open(QFile::ReadWrite)) {
return ErrFile::Permission;
}
} break;
default: {
if (!file.open(QFile::WriteOnly)) {
return ErrFile::Permission;
}
} break;
if (!file.open(QFile::WriteOnly)) {
return ErrFile::Permission;
}
if (doc->saveTo(&file, true)) {
if (doc->saveTo(&file, !isExport)) {
file.close();
if (!isExport) {
@ -615,7 +558,9 @@ ErrFile EditorView::save(const QString &workSpaceName, const QString &path,
}
return ErrFile::Permission;
} else {
doc->setDocSaved();
if (!isExport) {
doc->setDocSaved();
}
}
#ifdef Q_OS_LINUX
@ -662,12 +607,6 @@ ErrFile EditorView::reload() {
switch (documentType()) {
case DocumentType::File:
return openFile(m_fileName);
case DocumentType::RegionFile: {
auto doc = qobject_cast<QFileRegionBuffer *>(m_hex->document());
Q_ASSERT(doc);
return openRegionFile(m_fileName, doc->readOffset(),
doc->readMaxBytes());
}
case DocumentType::Driver:
return openDriver(m_fileName);
case DocumentType::Extension:
@ -893,7 +832,6 @@ EditorView *EditorView::clone() {
}
auto ev = new EditorView(this->parentWidget());
ev->setFeature(CDockWidget::CustomCloseHandling, false);
connect(ev, &EditorView::destroyed, this, [=] {
this->m_cloneChildren[this->m_cloneChildren.indexOf(ev)] = nullptr;
});
@ -959,13 +897,6 @@ bool EditorView::isExtensionFile() const {
return m_docType == EditorView::DocumentType::Extension;
}
bool EditorView::isRegionFile() const {
if (isCloneFile()) {
return this->cloneParent()->isRegionFile();
}
return m_docType == EditorView::DocumentType::RegionFile;
}
bool EditorView::isCommonFile() const {
if (isCloneFile()) {
return this->cloneParent()->isCommonFile();

View File

@ -38,14 +38,7 @@ class EditorView : public ads::CDockWidget {
Q_OBJECT
public:
enum class DocumentType {
InValid,
File,
RegionFile,
Driver,
Extension,
Cloned
};
enum class DocumentType { InValid, File, Driver, Extension, Cloned };
enum class FindError { Success, Busy, MayOutOfRange };
@ -70,7 +63,6 @@ public:
bool isCloneFile() const;
bool isDriver() const;
bool isExtensionFile() const;
bool isRegionFile() const;
bool isCommonFile() const;
FindResultModel *findResultModel() const;
@ -123,11 +115,10 @@ public slots:
ErrFile openFile(const QString &filename);
ErrFile openExtFile(const QString &ext, const QString &file);
ErrFile openWorkSpace(const QString &filename);
ErrFile openRegionFile(QString filename, qsizetype start, qsizetype length);
ErrFile openDriver(const QString &driver);
ErrFile
save(const QString &workSpaceName, const QString &path = QString(),
bool ignoreMd5 = false, bool isExport = false,
bool isExport = false,
SaveWorkSpaceAttr workSpaceAttr = SaveWorkSpaceAttr::AutoWorkSpace);
ErrFile reload();
ErrFile closeFile();

View File

@ -18,7 +18,10 @@
#include "scripteditor.h"
#include "qcodeeditwidget/qdocumentswaptextcommand.h"
#include "qeditor.h"
#ifdef Q_OS_LINUX
#include "utilities.h"
#endif
#include <QAction>
#include <QFile>
@ -52,8 +55,8 @@ ScriptEditor::ScriptEditor(QWidget *parent)
ScriptEditor::~ScriptEditor() {
auto e = editor();
e->disconnect();
e->document()->disconnect();
e->disconnect();
}
QString ScriptEditor::fileName() const { return editor()->fileName(); }
@ -66,7 +69,9 @@ bool ScriptEditor::openFile(const QString &filename) {
bool ScriptEditor::save(const QString &path) {
auto e = editor();
#ifdef Q_OS_LINUX
auto needAdjustFile = !QFile::exists(path);
#endif
auto clang = ClangFormatManager::instance();
if (clang.exists() && clang.autoFormat()) {

View File

@ -26,8 +26,7 @@
#include <QTextBrowser>
#include <QVBoxLayout>
FileInfoDialog::FileInfoDialog(QString filename, bool isRegionFile,
QWidget *parent)
FileInfoDialog::FileInfoDialog(QString filename, QWidget *parent)
: FramelessDialogBase(parent) {
static const QString dfmt("yyyy/MM/dd hh:mm:ss ddd");
@ -69,8 +68,6 @@ FileInfoDialog::FileInfoDialog(QString filename, bool isRegionFile,
.toString(dfmt));
b->append(tr("LastRead:") + finfo.lastRead().toString(dfmt));
b->append(tr("LastMod:") + finfo.lastModified().toString(dfmt));
b->append(tr("IsRegionFile:") +
(isRegionFile ? tr("True") : tr("False")));
}
auto availSizes = icon.availableSizes();

View File

@ -23,8 +23,7 @@
class FileInfoDialog : public FramelessDialogBase {
Q_OBJECT
public:
FileInfoDialog(QString filename, bool isRegionFile,
QWidget *parent = nullptr);
FileInfoDialog(QString filename, QWidget *parent = nullptr);
virtual ~FileInfoDialog();
};

View File

@ -45,7 +45,6 @@
#include "fileinfodialog.h"
#include "finddialog.h"
#include "metadialog.h"
#include "openregiondialog.h"
#include "plugin/pluginsystem.h"
#include "settings/editorsettingdialog.h"
#include "settings/generalsettingdialog.h"
@ -88,8 +87,7 @@ MainWindow::MainWindow(SplashDialog *splash) : FramelessMainWindow() {
connect(m_recentmanager, &RecentFileManager::triggered, this,
[=](const RecentFileManager::RecentInfo &rinfo) {
AppManager::instance()->openFile(rinfo.fileName,
rinfo.isWorkSpace, rinfo.start,
rinfo.length);
rinfo.isWorkSpace);
});
m_recentmanager->apply(this, SettingManager::instance().recentHexFiles());
@ -1233,11 +1231,6 @@ RibbonTabContent *MainWindow::buildFilePage(RibbonTabContent *tab) {
addPannelAction(pannel, QStringLiteral("open"), tr("OpenF"),
&MainWindow::on_openfile, QKeySequence::Open);
addPannelAction(
pannel, QStringLiteral("openr"), tr("OpenFR"),
&MainWindow::on_openregion,
shortcuts.keySequence(QKeySequences::Key::OPEN_REGION_FILE));
addPannelAction(
pannel, QStringLiteral("workspace"), tr("OpenWorkSpace"),
&MainWindow::on_openworkspace,
@ -1509,9 +1502,7 @@ RibbonTabContent *MainWindow::buildViewPage(RibbonTabContent *tab) {
auto doc = hexeditor->document();
auto b = !hexeditor->isKeepSize();
if ((!b && editor->documentType() ==
EditorView::DocumentType::RegionFile) ||
!hexeditor->setKeepSize(b)) {
if (!hexeditor->setKeepSize(b)) {
Toast::toast(this, _pixCannotOver, tr("ErrUnOver"));
}
});
@ -1937,38 +1928,6 @@ void MainWindow::on_openfile() {
}
}
void MainWindow::on_openregion() {
ScopeGuard g([this]() { showStatus(tr("RegionOpening...")); },
[this]() { showStatus({}); });
OpenRegionDialog d(m_lastusedpath);
if (d.exec()) {
auto res = d.getResult();
EditorView *editor = nullptr;
auto ret = openRegionFile(res.filename, &editor, res.start, res.length);
if (ret == ErrFile::NotExist) {
QMessageBox::critical(this, tr("Error"), tr("FileNotExist"));
return;
}
if (ret == ErrFile::Permission) {
QMessageBox::critical(this, tr("Error"), tr("FilePermission"));
return;
}
if (ret == ErrFile::AlreadyOpened) {
Q_ASSERT(editor);
editor->raise();
editor->setFocus();
return;
}
RecentFileManager::RecentInfo info;
info.fileName = res.filename;
info.start = res.start;
info.length = res.length;
m_recentmanager->addRecentFile(info);
}
}
void MainWindow::on_openworkspace() {
ScopeGuard g([this]() { showStatus(tr("WorkSpaceOpening...")); },
[this]() { showStatus({}); });
@ -2065,7 +2024,9 @@ void MainWindow::on_save() {
return;
}
auto res = saveEditor(editor, {}, false);
auto changedTo = editor->change2WorkSpace();
QString ws;
auto res = saveEditor(editor, {}, false, false, &ws);
auto isNewFile = editor->isNewFile();
if (isNewFile) {
@ -2073,32 +2034,21 @@ void MainWindow::on_save() {
return;
}
restart:
if (res == ErrFile::IsNewFile) {
on_saveas();
return;
}
if (res == ErrFile::Permission) {
WingMessageBox::critical(this, tr("Error"), tr("FilePermission"));
return;
}
if (res == ErrFile::SourceFileChanged) {
if (WingMessageBox::warning(this, tr("Warn"), tr("SourceChanged"),
QMessageBox::Yes | QMessageBox::No) ==
QMessageBox::Yes) {
res = saveEditor(editor, {}, true);
goto restart;
} else {
Toast::toast(this, NAMEICONRES(QStringLiteral("save")),
tr("SaveSourceFileError"));
}
}
if (res == ErrFile::WorkSpaceUnSaved) {
WingMessageBox::critical(this, NAMEICONRES(QStringLiteral("save")),
tr("SaveWSError"));
WingMessageBox::critical(this, tr("Error"), tr("SaveWSError"));
return;
}
if (changedTo) {
RecentFileManager::RecentInfo info;
info.fileName = ws;
info.isWorkSpace = true;
m_recentmanager->addRecentFile(info);
}
Toast::toast(this, NAMEICONRES(QStringLiteral("save")),
tr("SaveSuccessfully"));
}
@ -2114,18 +2064,13 @@ void MainWindow::on_convpro() {
return;
}
if (editor->isRegionFile()) {
Toast::toast(this, NAMEICONRES("convpro"), tr("UnsupportedProConv"));
return;
}
if (editor->isOriginWorkSpace()) {
Toast::toast(this, NAMEICONRES("convpro"), tr("AlreadyWorkSpace"));
return;
}
QString workspace;
auto ret = saveEditor(editor, {}, false, false, true, &workspace);
auto ret = saveEditor(editor, {}, false, true, &workspace);
if (ret == ErrFile::WorkSpaceUnSaved) {
WingMessageBox::critical(this, tr("Error"), tr("ConvWorkSpaceFailed"));
} else if (ret == ErrFile::Success) {
@ -2165,9 +2110,8 @@ void MainWindow::on_saveas() {
m_lastusedpath = QFileInfo(filename).absoluteDir().absolutePath();
bool isWorkspace = editor->isOriginWorkSpace();
auto res = saveEditor(editor, filename, false, false, isWorkspace);
auto res = saveEditor(editor, filename, false, isWorkspace);
restart:
switch (res) {
case ErrFile::Success: {
Toast::toast(this, NAMEICONRES(QStringLiteral("saveas")),
@ -2182,18 +2126,6 @@ restart:
WingMessageBox::critical(this, tr("Error"), tr("SaveWSError"));
break;
}
case ErrFile::SourceFileChanged: {
if (WingMessageBox::warning(this, tr("Warn"), tr("SourceChanged"),
QMessageBox::Yes | QMessageBox::No) ==
QMessageBox::Yes) {
res = saveEditor(editor, filename, true);
goto restart;
} else {
Toast::toast(this, NAMEICONRES(QStringLiteral("save")),
tr("SaveSourceFileError"));
}
break;
}
default: {
WingMessageBox::critical(this, tr("Error"), tr("SaveUnSuccessfully"));
break;
@ -2216,26 +2148,14 @@ void MainWindow::on_exportfile() {
return;
m_lastusedpath = QFileInfo(filename).absoluteDir().absolutePath();
auto res = saveEditor(editor, filename, false, true);
restart:
bool isWorkspace = editor->isOriginWorkSpace();
auto res = saveEditor(editor, filename, true, isWorkspace);
switch (res) {
case ErrFile::Success: {
Toast::toast(this, NAMEICONRES(QStringLiteral("export")),
tr("ExportSuccessfully"));
break;
}
case ErrFile::SourceFileChanged: {
if (QMessageBox::warning(this, tr("Warn"), tr("SourceChanged"),
QMessageBox::Yes | QMessageBox::No) ==
QMessageBox::Yes) {
res = saveEditor(editor, filename, true, true);
goto restart;
} else {
WingMessageBox::critical(this, tr("Error"),
tr("ExportSourceFileError"));
}
break;
}
default: {
WingMessageBox::critical(this, tr("Error"), tr("ExportUnSuccessfully"));
break;
@ -2325,7 +2245,13 @@ void MainWindow::on_delete() {
if (hexeditor == nullptr) {
return;
}
hexeditor->RemoveSelection();
if (hexeditor->RemoveSelection()) {
Toast::toast(this, NAMEICONRES(QStringLiteral("del")),
tr("DeleteSuccess"));
} else {
Toast::toast(this, NAMEICONRES(QStringLiteral("del")),
tr("DeleteFailed"));
}
}
void MainWindow::on_clone() {
@ -2467,9 +2393,7 @@ void MainWindow::on_fileInfo() {
if (editor == nullptr) {
return;
}
FileInfoDialog d(editor->fileName(),
editor->documentType() ==
EditorView::DocumentType::RegionFile);
FileInfoDialog d(editor->fileName());
d.exec();
}
@ -2506,7 +2430,7 @@ void MainWindow::on_pastehex() {
if (hexeditor == nullptr) {
return;
}
hexeditor->Paste();
hexeditor->Paste(true);
}
void MainWindow::on_fill() {
@ -2518,7 +2442,13 @@ void MainWindow::on_fill() {
auto in = WingInputDialog::getText(this, tr("Fill"), tr("PleaseInputFill"),
QLineEdit::Normal, QString(), &b);
if (b) {
auto ch = char(in.toULongLong(&b, 0));
auto v = in.toUInt(&b, 0);
auto limit = std::numeric_limits<uchar>().max();
if (v > limit) {
Toast::toast(this, NAMEICONRES(QStringLiteral("fill")),
tr("FillInputTruncWarn"));
}
auto ch = uchar(v);
if (b) {
auto doc = hexeditor->document();
if (doc->isEmpty() || !hexeditor->hasSelection())
@ -2527,9 +2457,10 @@ void MainWindow::on_fill() {
auto total = hexeditor->selectionCount();
doc->beginMarco(QStringLiteral("FillBytes"));
for (int i = 0; i < total; ++i) {
auto pos = hexeditor->cursor()->selectionStart(i).offset();
auto cursor = hexeditor->cursor();
auto pos = cursor->selectionStart(i).offset();
hexeditor->Replace(
pos, QByteArray(int(hexeditor->hasSelection()), char(ch)));
pos, QByteArray(cursor->selectionLength(i), char(ch)));
}
doc->endMarco();
} else {
@ -2553,8 +2484,7 @@ void MainWindow::on_fillzero() {
doc->beginMarco(QStringLiteral("FillZero"));
for (int i = 0; i < total; ++i) {
auto pos = cur->selectionStart(i).offset();
hexeditor->Replace(pos,
QByteArray(int(hexeditor->hasSelection()), char(0)));
hexeditor->Replace(pos, QByteArray(cur->selectionLength(i), char(0)));
}
doc->endMarco();
}
@ -2594,11 +2524,38 @@ void MainWindow::on_bookmarkdel() {
return;
}
auto doc = hexeditor->document();
auto pos = hexeditor->currentOffset();
auto cursor = hexeditor->cursor();
if (cursor->hasSelection()) {
QList<qsizetype> rmOff;
if (doc->bookMarkExists(pos)) {
doc->RemoveBookMark(pos);
auto total = cursor->selectionCount();
for (int i = 0; i < total; ++i) {
rmOff.append(doc->bookMarkRange(cursor->selectionStart(i).offset(),
cursor->selectionEnd(i).offset()));
}
if (!rmOff.isEmpty()) {
doc->beginMarco(QStringLiteral("BookMarkRmRange"));
for (auto &pos : rmOff) {
doc->RemoveBookMark(pos);
}
doc->endMarco();
Toast::toast(this, NAMEICONRES("bookmarkdel"),
tr("BookmarkDelSuccess"));
return;
}
} else {
auto pos = cursor->position().offset();
if (doc->bookMarkExists(pos)) {
if (doc->RemoveBookMark(pos)) {
Toast::toast(this, NAMEICONRES("bookmarkdel"),
tr("BookmarkDelSuccess"));
return;
}
}
}
Toast::toast(this, NAMEICONRES("bookmarkdel"), tr("BookmarkDelNoItem"));
}
void MainWindow::on_bookmarkcls() {
@ -2608,6 +2565,7 @@ void MainWindow::on_bookmarkcls() {
}
auto doc = hexeditor->document();
doc->ClearBookMark();
Toast::toast(this, NAMEICONRES("bookmarkdel"), tr("BookmarkClearSuccess"));
}
void MainWindow::on_metadata() {
@ -2688,8 +2646,17 @@ void MainWindow::on_metadatadel() {
}
auto doc = hexeditor->document();
auto meta = doc->metadata();
auto pos = hexeditor->cursor()->position().offset();
meta->RemoveMetadata(pos);
auto cursor = hexeditor->cursor();
if (cursor->hasSelection()) {
Toast::toast(this, NAMEICONRES("metadatadel"), tr("PleaseClearSel"));
return;
}
auto pos = cursor->position().offset();
if (meta->RemoveMetadata(pos)) {
Toast::toast(this, NAMEICONRES("metadatadel"), tr("MetaDelSuccess"));
} else {
Toast::toast(this, NAMEICONRES("metadatadel"), tr("MetaDelNoItem"));
}
}
void MainWindow::on_metadatacls() {
@ -2699,6 +2666,7 @@ void MainWindow::on_metadatacls() {
}
auto doc = hexeditor->document();
doc->metadata()->Clear();
Toast::toast(this, NAMEICONRES("metadatacls"), tr("MetaClearSuccess"));
}
void MainWindow::on_metadatafg(bool checked) {
@ -3245,17 +3213,17 @@ void MainWindow::registerEditorView(EditorView *editor, const QString &ws) {
}
}
auto ret = closeEditor(editor, m_isOnClosing);
auto ret = closeEditor(editor, false);
if (ret == ErrFile::UnSaved || ret == ErrFile::WorkSpaceUnSaved) {
auto ret = this->saveRequest();
if (ret == QMessageBox::Cancel) {
return;
} else if (ret == QMessageBox::Yes) {
auto ret = saveEditor(editor, {}, false);
auto ret = saveEditor(editor, {});
switch (ret) {
case WingHex::Success:
// ok, no need to report
closeEditor(editor, m_isOnClosing);
closeEditor(editor, false);
break;
case WingHex::Permission: {
auto btn = WingMessageBox::critical(
@ -3271,7 +3239,6 @@ void MainWindow::registerEditorView(EditorView *editor, const QString &ws) {
case WingHex::AlreadyOpened:
case WingHex::IsNewFile:
case WingHex::IsDirver:
case WingHex::SourceFileChanged:
case WingHex::ClonedFile:
case WingHex::InvalidFormat:
case WingHex::TooManyOpenedFile:
@ -3330,6 +3297,11 @@ void MainWindow::registerClonedEditorView(EditorView *editor) {
auto ta = editor->toggleViewAction();
menu->addAction(ta);
ev->setEnabled(true);
connect(editor, &EditorView::closeRequested, this, [=]() {
adjustEditorFocus(editor);
editor->closeDockWidget();
});
}
void MainWindow::connectEditorView(EditorView *editor) {
@ -3577,7 +3549,6 @@ ErrFile MainWindow::openExtFile(const QString &ext, const QString &file,
return ErrFile::AlreadyOpened;
}
auto dev = PluginSystem::instance().ext2Device(ext);
auto ev = new EditorView(this);
auto res = ev->openExtFile(ext, file);
@ -3665,49 +3636,15 @@ ErrFile MainWindow::openWorkSpace(const QString &file, EditorView **editor) {
return ErrFile::Success;
}
ErrFile MainWindow::openRegionFile(QString file, EditorView **editor,
qsizetype start, qsizetype length) {
auto e = findEditorView(file);
if (e) {
if (editor) {
*editor = e;
}
return ErrFile::AlreadyOpened;
}
// ok, going on
if (!newOpenFileSafeCheck()) {
return ErrFile::Error;
}
QFileInfo finfo(file);
auto filename = finfo.absoluteFilePath();
auto ev = new EditorView(this);
auto res = ev->openRegionFile(filename, start, length);
if (res != ErrFile::Success) {
delete ev;
return res;
}
registerEditorView(ev);
if (editor) {
*editor = ev;
}
m_dock->addDockWidget(ads::CenterDockWidgetArea, ev, editorViewArea());
return ErrFile::Success;
}
ErrFile MainWindow::saveEditor(EditorView *editor, const QString &filename,
bool ignoreMd5, bool isExport,
bool forceWorkspace, QString *ws) {
bool isExport, bool forceWorkspace,
QString *ws) {
if (editor == nullptr) {
return ErrFile::Error;
}
auto isNewFile = editor->isNewFile();
if (isNewFile && filename.isEmpty()) {
if (isNewFile) {
return ErrFile::IsNewFile;
}
@ -3716,13 +3653,14 @@ ErrFile MainWindow::saveEditor(EditorView *editor, const QString &filename,
}
auto oldName = editor->fileName();
auto newName = filename.isEmpty() ? oldName : filename;
QString workspace = m_views.value(editor);
if (forceWorkspace || workspace.isEmpty()) {
if (forceWorkspace || editor->change2WorkSpace()) {
QString curFile;
if (!editor->isDriver() && !editor->isExtensionFile()) {
curFile = editor->fileName() + PROEXT;
curFile = newName + PROEXT;
}
auto wsfile = getWorkSpaceFileName(curFile);
@ -3737,7 +3675,7 @@ ErrFile MainWindow::saveEditor(EditorView *editor, const QString &filename,
*ws = workspace;
}
auto ret = editor->save(workspace, filename, ignoreMd5, isExport,
auto ret = editor->save(workspace, filename, isExport,
forceWorkspace
? EditorView::SaveWorkSpaceAttr::ForceWorkSpace
: EditorView::SaveWorkSpaceAttr::AutoWorkSpace);
@ -3746,7 +3684,7 @@ ErrFile MainWindow::saveEditor(EditorView *editor, const QString &filename,
PluginSystem::instance().dispatchEvent(
IWingPlugin::RegisteredEvent::FileSaved,
{filename.isEmpty() ? oldName : filename, oldName, isExport,
{newName, oldName, isExport,
QVariant::fromValue(getEditorViewFileType(editor))});
}
return ret;
@ -3783,21 +3721,12 @@ ErrFile MainWindow::closeEditor(EditorView *editor, bool force) {
plgsys.dispatchEvent(
IWingPlugin::RegisteredEvent::FileClosed,
{fileName, QVariant::fromValue(getEditorViewFileType(editor))});
editor->deleteDockWidget();
editor->closeDockWidget();
m_toolBtneditors.value(ToolButtonIndex::EDITOR_VIEWS)
->setEnabled(m_views.size() != 0);
if (m_dock->focusedDockWidget() == editor) {
if (!m_views.isEmpty()) {
for (auto p = m_views.keyBegin(); p != m_views.keyEnd(); ++p) {
auto ev = *p;
if (ev != editor && ev->isCurrentTab()) {
ev->setFocus();
}
}
}
}
adjustEditorFocus(editor);
return ErrFile::Success;
}
@ -3807,8 +3736,6 @@ IWingPlugin::FileType MainWindow::getEditorViewFileType(EditorView *view) {
switch (view->documentType()) {
case EditorView::DocumentType::File:
return IWingPlugin::FileType::File;
case EditorView::DocumentType::RegionFile:
return IWingPlugin::FileType::RegionFile;
case EditorView::DocumentType::Driver:
return IWingPlugin::FileType::Driver;
case EditorView::DocumentType::Extension:
@ -3872,6 +3799,19 @@ EditorView *MainWindow::currentEditor() {
return m_curEditor;
}
void MainWindow::adjustEditorFocus(EditorView *closedEditor) {
if (m_dock->focusedDockWidget() == closedEditor) {
if (!m_views.isEmpty()) {
for (auto p = m_views.keyBegin(); p != m_views.keyEnd(); ++p) {
auto ev = *p;
if (ev != closedEditor && ev->isCurrentTab()) {
ev->setFocus();
}
}
}
}
}
QString MainWindow::getWorkSpaceFileName(const QString &curFile) {
return WingFileDialog::getSaveFileName(this, tr("SaveWorkSpace"), curFile,
tr("WingHexWorkSpace (*.wingpro)"));
@ -4044,21 +3984,18 @@ QJsonObject MainWindow::extractModelData(const QAbstractItemModel *model,
}
void MainWindow::closeEvent(QCloseEvent *event) {
m_isOnClosing = true;
// plugin first checking
auto closing = PluginSystem::instance().dispatchEvent(
IWingPlugin::RegisteredEvent::AppClosing, {});
if (!closing) {
event->ignore();
m_isOnClosing = false;
return;
}
// then checking the scripting dialog
if (!m_scriptDialog->about2Close()) {
event->ignore();
m_isOnClosing = false;
return;
}
@ -4083,7 +4020,7 @@ void MainWindow::closeEvent(QCloseEvent *event) {
}
for (auto &view : need2CloseView) {
emit view->closeRequested();
view->requestCloseDockWidget();
}
auto ret =
@ -4093,11 +4030,12 @@ void MainWindow::closeEvent(QCloseEvent *event) {
this, qAppName(), tr("ConfirmAPPSave"),
QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
if (ret == QMessageBox::Yes) {
auto views = m_views.keys();
for (auto &p : views) {
emit p->closeRequested();
for (auto pview = m_views.constKeyValueBegin();
pview != m_views.constKeyValueEnd(); ++pview) {
pview->first->save(pview->second, {});
pview->first->requestCloseDockWidget();
}
m_isOnClosing = false;
if (!m_views.isEmpty()) {
event->ignore();
return;
@ -4107,10 +4045,8 @@ void MainWindow::closeEvent(QCloseEvent *event) {
for (auto &p : views) {
p->closeDockWidget(); // force close
}
m_isOnClosing = false;
} else {
event->ignore();
m_isOnClosing = false;
return;
}
}

View File

@ -146,7 +146,6 @@ private:
private slots:
void on_newfile();
void on_openfile();
void on_openregion();
void on_openworkspace();
void on_opendriver();
void on_reload();
@ -219,15 +218,14 @@ public:
EditorView **editor);
ErrFile openDriver(const QString &driver, EditorView **editor);
ErrFile openWorkSpace(const QString &file, EditorView **editor);
ErrFile openRegionFile(QString file, EditorView **editor, qsizetype start,
qsizetype length);
ErrFile saveEditor(EditorView *editor, const QString &filename,
bool ignoreMd5, bool isExport = false,
bool forceWorkspace = false, QString *ws = nullptr);
bool isExport = false, bool forceWorkspace = false,
QString *ws = nullptr);
ErrFile closeEditor(EditorView *editor, bool force);
EditorView *currentEditor();
void adjustEditorFocus(EditorView *closedEditor);
QString getWorkSpaceFileName(const QString &curFile);
@ -629,7 +627,7 @@ private:
// for plugin system use
QHash<QString, RibbonTabContent *> m_ribbonMaps;
QList<QMenu *> m_hexContextMenu;
QMap<IWingPlugin *, QList<QSharedPointer<WingEditorViewWidget::Creator>>>
QHash<IWingPlugin *, QList<QSharedPointer<WingEditorViewWidget::Creator>>>
m_editorViewWidgets;
QHash<SettingPage *, bool> m_settingPages;
QList<PluginPage *> m_plgPages;
@ -644,7 +642,6 @@ private:
QString m_lastusedpath;
bool m_islittle = true;
bool m_enablePlugin = true;
bool m_isOnClosing = false;
ShowTextDialog *_showtxt = nullptr;

View File

@ -1,103 +0,0 @@
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** This program is free software: you can redistribute it and/or modify it under
** the terms of the GNU Affero General Public License as published by the Free
** Software Foundation, version 3.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
** details.
**
** You should have received a copy of the GNU Affero General Public License
** along with this program. If not, see <https://www.gnu.org/licenses/>.
** =============================================================================
*/
#include "openregiondialog.h"
#include "control/toast.h"
#include "utilities.h"
#include <QDialogButtonBox>
#include <QDir>
#include <QFileInfo>
#include <QLabel>
#include <QShortcut>
#include <QVBoxLayout>
OpenRegionDialog::OpenRegionDialog(const QString &filename, int start,
int length, QWidget *parent)
: FramelessDialogBase(parent) {
auto widget = new QWidget(this);
auto layout = new QVBoxLayout(widget);
layout->addWidget(new QLabel(tr("ChooseFile"), this));
layout->addSpacing(5);
filepath = new QPathEdit(this);
filepath->setDialogOptions(QFileDialog::Option::ShowDirsOnly);
filepath->setStyle(QPathEdit::Style::JoinedButton);
filepath->setPathMode(QPathEdit::PathMode::ExistingFolder);
filepath->setAllowEmptyPath(false);
connect(filepath, &QPathEdit::pathChanged, filepath,
&QPathEdit::setToolTip);
filepath->setPath(filename);
layout->addWidget(filepath);
layout->addSpacing(10);
layout->addWidget(new QLabel(tr("Start"), this));
layout->addSpacing(5);
sbStart = new QSpinBox(this);
sbStart->setRange(0, INT_MAX);
sbStart->setValue(start);
sbStart->setPrefix("0x");
sbStart->setDisplayIntegerBase(16);
layout->addWidget(sbStart);
layout->addSpacing(10);
layout->addWidget(new QLabel(tr("Len"), this));
layout->addSpacing(5);
sbLength = new QSpinBox(this);
sbLength->setRange(1, INT_MAX);
sbLength->setValue(length);
layout->addWidget(sbLength);
layout->addSpacing(20);
auto dbbox = new QDialogButtonBox(
QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
connect(dbbox, &QDialogButtonBox::accepted, this,
&OpenRegionDialog::on_accept);
connect(dbbox, &QDialogButtonBox::rejected, this,
&OpenRegionDialog::on_reject);
auto key = QKeySequence(Qt::Key_Return);
auto s = new QShortcut(key, this);
connect(s, &QShortcut::activated, this, &OpenRegionDialog::on_accept);
layout->addWidget(dbbox);
buildUpContent(widget);
this->setWindowTitle(tr("OpenRegion"));
}
RegionFileResult OpenRegionDialog::getResult() { return res; }
void OpenRegionDialog::on_accept() {
auto file = filepath->path();
if (file.length()) {
if (!QFile::exists(file)) {
Toast::toast(this, NAMEICONRES(QStringLiteral("open")),
tr("FileNotExist"));
}
} else {
Toast::toast(this, NAMEICONRES(QStringLiteral("open")),
tr("NoFileSelected"));
return;
}
res.filename = file;
res.start = sbStart->value();
res.length = sbLength->value();
done(1);
}
void OpenRegionDialog::on_reject() { done(0); }

View File

@ -1,52 +0,0 @@
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** This program is free software: you can redistribute it and/or modify it under
** the terms of the GNU Affero General Public License as published by the Free
** Software Foundation, version 3.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
** details.
**
** You should have received a copy of the GNU Affero General Public License
** along with this program. If not, see <https://www.gnu.org/licenses/>.
** =============================================================================
*/
#ifndef OPENREGIONDIALOG_H
#define OPENREGIONDIALOG_H
#include <QDialog>
#include <QMainWindow>
#include <QSpinBox>
#include "QPathEdit/qpathedit.h"
#include "framelessdialogbase.h"
struct RegionFileResult {
QString filename;
qsizetype start;
qsizetype length;
};
class OpenRegionDialog : public FramelessDialogBase {
Q_OBJECT
public:
OpenRegionDialog(const QString &filename, int start = 0, int length = 1024,
QWidget *parent = nullptr);
RegionFileResult getResult();
private:
void on_accept();
void on_reject();
private:
QPathEdit *filepath;
QSpinBox *sbStart, *sbLength;
RegionFileResult res;
};
#endif // OPENREGIONDIALOG_H

View File

@ -233,7 +233,6 @@ void ScriptingDialog::initConsole() {
});
connect(dbg, &asDebugger::onDebugActionExec, this,
[this]() { updateRunDebugMode(); });
m_breakpoints->setDebugger(dbg);
m_sym->setEngine(machine->engine());
}
@ -624,19 +623,6 @@ ScriptingDialog::buildUpVarShowDock(ads::CDockManager *dock,
return dock->addDockWidget(area, dw, areaw);
}
ads::CDockAreaWidget *
ScriptingDialog::buildUpBreakpointShowDock(ads::CDockManager *dock,
ads::DockWidgetArea area,
ads::CDockAreaWidget *areaw) {
auto bpview = new QTableView(this);
Utilities::applyTableViewProperty(bpview);
m_breakpoints = new DbgBreakpointModel(bpview);
bpview->setModel(m_breakpoints);
auto dw = buildDockWidget(dock, QStringLiteral("BreakPoints"),
tr("BreakPoints"), bpview);
return dock->addDockWidget(area, dw, areaw);
}
ads::CDockAreaWidget *
ScriptingDialog::buildUpOutputShowDock(ads::CDockManager *dock,
ads::DockWidgetArea area,
@ -736,9 +722,8 @@ void ScriptingDialog::buildUpDockSystem(QWidget *container) {
}
buildUpStackShowDock(m_dock, ads::RightDockWidgetArea, bottomArea);
auto rightArea = buildUpBreakpointShowDock(m_dock, ads::RightDockWidgetArea,
m_editorViewArea);
buildUpVarShowDock(m_dock, ads::CenterDockWidgetArea, rightArea);
auto rightArea =
buildUpVarShowDock(m_dock, ads::RightDockWidgetArea, m_editorViewArea);
buildSymbolShowDock(m_dock, ads::CenterDockWidgetArea, rightArea);
// set the first tab visible
@ -1046,6 +1031,14 @@ void ScriptingDialog::startDebugScript(const QString &fileName) {
m_consoleout->clear();
// add breakpoints
auto marks = QLineMarksInfoCenter::instance()->marks(
fileName, m_symID.value(Symbols::BreakPoint));
auto dbg = m_consoleout->machine()->debugger();
for (auto &bp : marks) {
dbg->addFileBreakPoint(bp.file, bp.line);
}
_DebugingScript = fileName;
PluginSystem::instance().dispatchEvent(
IWingPlugin::RegisteredEvent::ScriptPragmaInit, {});

View File

@ -29,11 +29,11 @@
#include "Qt-Advanced-Docking-System/src/DockWidget.h"
#include "class/recentfilemanager.h"
#include "control/scripteditor.h"
#include "model/dbgbreakpointmodel.h"
#include "model/dbgcallstackmodel.h"
#include "model/dbgvarshowmodel.h"
#include "utilities.h"
#include <QKeySequence>
#include <QMessageBox>
#include <QShortcut>
#include <QStatusBar>
@ -94,9 +94,6 @@ private:
buildUpVarShowDock(ads::CDockManager *dock, ads::DockWidgetArea area,
ads::CDockAreaWidget *areaw = nullptr);
ads::CDockAreaWidget *
buildUpBreakpointShowDock(ads::CDockManager *dock, ads::DockWidgetArea area,
ads::CDockAreaWidget *areaw = nullptr);
ads::CDockAreaWidget *
buildUpOutputShowDock(ads::CDockManager *dock, ads::DockWidgetArea area,
ads::CDockAreaWidget *areaw = nullptr);
ads::CDockAreaWidget *
@ -306,7 +303,6 @@ private:
ScriptingConsole *m_consoleout = nullptr;
DbgVarShowModel *m_varshow = nullptr;
DbgVarShowModel *m_gvarshow = nullptr;
DbgBreakpointModel *m_breakpoints = nullptr;
DbgCallStackModel *m_callstack = nullptr;
ASObjTreeWidget *m_sym = nullptr;

View File

@ -21,6 +21,7 @@
#include "class/wingmessagebox.h"
#include "class/wingprogressdialog.h"
#include "control/codeedit.h"
#include "control/toast.h"
#include "dialog/encodingdialog.h"
#include "qeditor.h"
@ -224,7 +225,11 @@ void ShowTextDialog::setCurrentEditorScale(qreal rate) {
m_edit->editor()->setScaleRate(rate);
}
void ShowTextDialog::on_copyfile() { m_edit->editor()->copy(); }
void ShowTextDialog::on_copyfile() {
m_edit->editor()->copy();
Toast::toast(this, NAMEICONRES(QStringLiteral("copy")),
tr("CopyToClipBoard"));
}
void ShowTextDialog::on_findfile() { m_edit->editor()->find(); }

View File

@ -10,6 +10,9 @@
<height>200</height>
</rect>
</property>
<property name="cursor">
<cursorShape>WaitCursor</cursorShape>
</property>
<property name="windowTitle">
<string notr="true"/>
</property>

View File

@ -1,76 +0,0 @@
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** This program is free software: you can redistribute it and/or modify it under
** the terms of the GNU Affero General Public License as published by the Free
** Software Foundation, version 3.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
** details.
**
** You should have received a copy of the GNU Affero General Public License
** along with this program. If not, see <https://www.gnu.org/licenses/>.
** =============================================================================
*/
#include "dbgbreakpointmodel.h"
#include <QFileInfo>
DbgBreakpointModel::DbgBreakpointModel(QObject *parent)
: QAbstractTableModel(parent) {}
int DbgBreakpointModel::rowCount(const QModelIndex &parent) const {
return _dbg ? _dbg->breakPoints().size() : 0;
}
int DbgBreakpointModel::columnCount(const QModelIndex &parent) const {
return 2;
}
QVariant DbgBreakpointModel::data(const QModelIndex &index, int role) const {
switch (role) {
case Qt::DisplayRole:
case Qt::ToolTipRole: {
auto r = index.row();
auto d = _dbg->breakPoints().at(r);
switch (index.column()) {
case 0: // line
return d.lineNbr;
case 1: // file
return role == Qt::ToolTipRole ? d.name
: QFileInfo(d.name).fileName();
}
}
case Qt::TextAlignmentRole:
return int(Qt::AlignCenter);
}
return QVariant();
}
QVariant DbgBreakpointModel::headerData(int section,
Qt::Orientation orientation,
int role) const {
if (role == Qt::DisplayRole) {
if (orientation == Qt::Horizontal) {
switch (section) {
case 0:
return tr("line");
case 1:
return tr("file");
}
} else {
return section + 1;
}
}
return QVariant();
}
void DbgBreakpointModel::setDebugger(asDebugger *dbg) {
Q_ASSERT(dbg);
connect(dbg, &asDebugger::breakPointChanged, this,
[=]() { emit layoutChanged(); });
_dbg = dbg;
}

View File

@ -1,45 +0,0 @@
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** This program is free software: you can redistribute it and/or modify it under
** the terms of the GNU Affero General Public License as published by the Free
** Software Foundation, version 3.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
** details.
**
** You should have received a copy of the GNU Affero General Public License
** along with this program. If not, see <https://www.gnu.org/licenses/>.
** =============================================================================
*/
#ifndef DBGBREAKPOINTMODEL_H
#define DBGBREAKPOINTMODEL_H
#include <QAbstractTableModel>
#include "class/asdebugger.h"
class DbgBreakpointModel : public QAbstractTableModel {
Q_OBJECT
public:
explicit DbgBreakpointModel(QObject *parent = nullptr);
// QAbstractItemModel interface
public:
virtual int rowCount(const QModelIndex &parent) const override;
virtual int columnCount(const QModelIndex &parent) const override;
virtual QVariant data(const QModelIndex &index, int role) const override;
virtual QVariant headerData(int section, Qt::Orientation orientation,
int role) const override;
public:
void setDebugger(asDebugger *dbg);
private:
asDebugger *_dbg = nullptr;
};
#endif // DBGBREAKPOINTMODEL_H

View File

@ -56,12 +56,11 @@ enum ErrFile : int {
IsNewFile = -6,
IsDirver = -7,
WorkSpaceUnSaved = -8,
SourceFileChanged = -9,
ClonedFile = -10,
InvalidFormat = -11,
TooManyOpenedFile = -12,
NotAllowedInNoneGUIThread = -13,
DevNotFound = -14,
ClonedFile = -9,
InvalidFormat = -10,
TooManyOpenedFile = -11,
NotAllowedInNoneGUIThread = -12,
DevNotFound = -13,
};
Q_ENUM_NS(ErrFile)
@ -248,29 +247,23 @@ signals:
Q_REQUIRED_RESULT WingHex::ErrFile newFile();
Q_REQUIRED_RESULT WingHex::ErrFile openFile(const QString &filename);
Q_REQUIRED_RESULT WingHex::ErrFile openDriver(const QString &driver);
Q_REQUIRED_RESULT WingHex::ErrFile openRegionFile(const QString &filename,
qsizetype start = 0,
qsizetype length = 1024);
Q_REQUIRED_RESULT WingHex::ErrFile openExtFile(const QString &ext,
const QString &file);
WingHex::ErrFile closeHandle(int handle);
WingHex::ErrFile closeFile(int handle, bool force = false);
Q_REQUIRED_RESULT WingHex::ErrFile saveFile(int handle,
bool ignoreMd5 = false);
Q_REQUIRED_RESULT WingHex::ErrFile
exportFile(int handle, const QString &savename, bool ignoreMd5 = false);
Q_REQUIRED_RESULT WingHex::ErrFile
saveAsFile(int handle, const QString &savename, bool ignoreMd5 = false);
Q_REQUIRED_RESULT WingHex::ErrFile saveFile(int handle);
Q_REQUIRED_RESULT WingHex::ErrFile exportFile(int handle,
const QString &savename);
Q_REQUIRED_RESULT WingHex::ErrFile saveAsFile(int handle,
const QString &savename);
Q_REQUIRED_RESULT WingHex::ErrFile openCurrent();
Q_REQUIRED_RESULT WingHex::ErrFile closeCurrent(bool force = false);
Q_REQUIRED_RESULT WingHex::ErrFile saveCurrent(bool ignoreMd5 = false);
Q_REQUIRED_RESULT WingHex::ErrFile exportCurrent(const QString &savename,
bool ignoreMd5 = false);
Q_REQUIRED_RESULT WingHex::ErrFile saveAsCurrent(const QString &savename,
bool ignoreMd5 = false);
Q_REQUIRED_RESULT WingHex::ErrFile saveCurrent();
Q_REQUIRED_RESULT WingHex::ErrFile exportCurrent(const QString &savename);
Q_REQUIRED_RESULT WingHex::ErrFile saveAsCurrent(const QString &savename);
// bookmark
Q_REQUIRED_RESULT bool addBookMark(qsizetype pos, const QString &comment);
@ -491,7 +484,7 @@ public:
PluginClosed
};
enum class FileType { Invalid, File, RegionFile, Driver, Extension };
enum class FileType { Invalid, File, Driver, Extension };
Q_ENUM(FileType)
public:

View File

@ -139,7 +139,6 @@ EditorView *PluginSystem::getCurrentPluginView(IWingPlugin *plg) {
}
auto fid = m_plgCurrentfid[plg];
auto &plgview = m_plgviewMap[plg];
auto ctx = pluginContextById(plg, fid);
if (ctx) {
return ctx->view;
@ -462,10 +461,8 @@ bool PluginSystem::dispatchEvent(IWingPlugin::RegisteredEvent event,
} break;
case WingHex::IWingPlugin::RegisteredEvent::ScriptPragma: {
Q_ASSERT(params.size() == 4);
auto pproc =
reinterpret_cast<AsPreprocesser *>(params.at(0).value<quintptr>());
auto section = params.at(1).toString();
auto plgID = params.at(2).toString();
auto section = params.at(0).toString();
auto plgID = params.at(1).toString();
auto &es = _evplgs[event];
auto r = std::find_if(
es.constBegin(), es.constEnd(),
@ -691,6 +688,7 @@ void PluginSystem::registerFns(IWingPlugin *plg) {
if (sig.isEmpty()) {
Logger::critical(tr("RegisterScriptFnUnSupportedTypes:") + id +
QStringLiteral("::") + p->first);
func->Release();
continue;
}
@ -699,7 +697,7 @@ void PluginSystem::registerFns(IWingPlugin *plg) {
_engine->defaultNamespace);
if (r < 0) {
Logger::critical(tr("RegisterScriptFnInvalidSig:") + sig);
func->funcType = asFUNC_DUMMY;
func->Release();
continue;
}
@ -707,7 +705,7 @@ void PluginSystem::registerFns(IWingPlugin *plg) {
_engine->defaultNamespace, false, false, false);
if (r < 0) {
Logger::critical(tr("RegisterScriptFnConflitSig:") + sig);
func->funcType = asFUNC_DUMMY;
func->Release();
continue;
}
@ -720,10 +718,8 @@ void PluginSystem::registerFns(IWingPlugin *plg) {
}
// clear the internal hacking functions
auto len = fnlist.size();
for (auto &fn : fnlist) {
_engine->RemoveScriptFunction(fn);
fn->Release();
}
_engine->SetDefaultNamespace("");
@ -759,8 +755,6 @@ void PluginSystem::registerUnSafeFns(IWingPlugin *plg) {
QHash<QString, IWingPlugin::UNSAFE_SCFNPTR> rfns;
for (auto p = fns.constKeyValueBegin(); p != fns.constKeyValueEnd(); ++p) {
auto func = new asCScriptFunction(_engine, nullptr, asFUNC_SYSTEM);
auto &fn = p->second;
auto sig = p->first;
auto r = c.ParseFunctionDeclaration(nullptr, sig.toLatin1(), func, true,
nullptr, nullptr,
@ -788,10 +782,8 @@ void PluginSystem::registerUnSafeFns(IWingPlugin *plg) {
}
// clear the internal hacking functions
auto len = fnlist.size();
for (auto &fn : fnlist) {
_engine->RemoveScriptFunction(fn);
fn->Release();
}
_engine->SetDefaultNamespace("");
@ -1987,7 +1979,7 @@ void PluginSystem::connectControllerInterface(IWingPlugin *plg) {
auto r = pluginContextByIdIt(plg, fid);
if (r) {
(*r)->cmd = new QUndoCommand;
(*r)->cmd = new QUndoCommand(txt);
}
return true;
});
@ -2024,7 +2016,6 @@ void PluginSystem::connectControllerInterface(IWingPlugin *plg) {
});
connect(pctl, &WingPlugin::Controller::writeBytes, _win,
[=](qsizetype offset, const QByteArray &data) -> bool {
QPair<EditorView *, QUndoCommand *> empty{nullptr, nullptr};
auto e = getCurrentPluginView(plg);
if (e) {
auto editor = e->hexEditor();
@ -2642,36 +2633,6 @@ void PluginSystem::connectControllerInterface(IWingPlugin *plg) {
}
});
connect(
pctl, &WingPlugin::Controller::openRegionFile, _win,
[=](const QString &filename, qsizetype start,
qsizetype length) -> ErrFile {
if (!checkThreadAff()) {
return ErrFile::NotAllowedInNoneGUIThread;
}
EditorView *view = nullptr;
if (!checkPluginCanOpenedFile(plg)) {
return ErrFile::TooManyOpenedFile;
}
auto ret = _win->openRegionFile(filename, &view, start, length);
if (view) {
if (ret == ErrFile::AlreadyOpened &&
checkPluginHasAlreadyOpened(plg, view)) {
return ErrFile::AlreadyOpened;
}
auto id = assginHandleForPluginView(plg, view);
m_plgCurrentfid[plg] = id;
auto handle = getUIDHandle(id);
PluginSystem::instance().dispatchEvent(
IWingPlugin::RegisteredEvent::PluginFileOpened,
{quintptr(plg), filename, handle,
QVariant::fromValue(_win->getEditorViewFileType(view))});
return ErrFile(handle);
} else {
return ret;
}
});
connect(
pctl, &WingPlugin::Controller::openDriver, _win,
[=](const QString &driver) -> ErrFile {
if (!checkThreadAff()) {
@ -2718,7 +2679,7 @@ void PluginSystem::connectControllerInterface(IWingPlugin *plg) {
return ErrFile::NotExist;
});
connect(pctl, &WingPlugin::Controller::saveFile, _win,
[=](int handle, bool ignoreMd5) -> ErrFile {
[=](int handle) -> ErrFile {
if (!checkThreadAff()) {
return ErrFile::NotAllowedInNoneGUIThread;
}
@ -2728,47 +2689,45 @@ void PluginSystem::connectControllerInterface(IWingPlugin *plg) {
}
if (view) {
_win->saveEditor(view, {}, ignoreMd5);
_win->saveEditor(view, {});
return ErrFile::Success;
}
return ErrFile::NotExist;
});
connect(
pctl, &WingPlugin::Controller::exportFile, _win,
[=](int handle, const QString &savename, bool ignoreMd5) -> ErrFile {
if (!checkThreadAff()) {
return ErrFile::NotAllowedInNoneGUIThread;
}
connect(pctl, &WingPlugin::Controller::exportFile, _win,
[=](int handle, const QString &savename) -> ErrFile {
if (!checkThreadAff()) {
return ErrFile::NotAllowedInNoneGUIThread;
}
auto view = handle2EditorView(plg, handle);
if (!checkPluginHasAlreadyOpened(plg, view)) {
return ErrFile::Error;
}
auto view = handle2EditorView(plg, handle);
if (!checkPluginHasAlreadyOpened(plg, view)) {
return ErrFile::Error;
}
if (view) {
_win->saveEditor(view, savename, ignoreMd5, true);
return ErrFile::Success;
}
return ErrFile::NotExist;
});
if (view) {
_win->saveEditor(view, savename, true);
return ErrFile::Success;
}
return ErrFile::NotExist;
});
connect(
pctl, &WingPlugin::Controller::saveAsFile, _win,
[=](int handle, const QString &savename, bool ignoreMd5) -> ErrFile {
if (!checkThreadAff()) {
return ErrFile::NotAllowedInNoneGUIThread;
}
auto view = handle2EditorView(plg, handle);
if (!checkPluginHasAlreadyOpened(plg, view)) {
return ErrFile::Error;
}
connect(pctl, &WingPlugin::Controller::saveAsFile, _win,
[=](int handle, const QString &savename) -> ErrFile {
if (!checkThreadAff()) {
return ErrFile::NotAllowedInNoneGUIThread;
}
auto view = handle2EditorView(plg, handle);
if (!checkPluginHasAlreadyOpened(plg, view)) {
return ErrFile::Error;
}
if (view) {
_win->saveEditor(view, savename, ignoreMd5);
return ErrFile::Success;
}
return ErrFile::NotExist;
});
if (view) {
_win->saveEditor(view, savename);
return ErrFile::Success;
}
return ErrFile::NotExist;
});
connect(pctl, &WingPlugin::Controller::openCurrent, _win, [=]() -> ErrFile {
if (!checkThreadAff()) {
return ErrFile::NotAllowedInNoneGUIThread;
@ -2807,26 +2766,24 @@ void PluginSystem::connectControllerInterface(IWingPlugin *plg) {
return _win->closeEditor(view, force);
});
connect(pctl, &WingPlugin::Controller::saveCurrent, _win,
[=](bool ignoreMd5) -> ErrFile {
if (!checkThreadAff()) {
return ErrFile::NotAllowedInNoneGUIThread;
}
auto view = getCurrentPluginView(plg);
if (!checkPluginHasAlreadyOpened(plg, view)) {
return ErrFile::Error;
}
connect(pctl, &WingPlugin::Controller::saveCurrent, _win, [=]() -> ErrFile {
if (!checkThreadAff()) {
return ErrFile::NotAllowedInNoneGUIThread;
}
auto view = getCurrentPluginView(plg);
if (!checkPluginHasAlreadyOpened(plg, view)) {
return ErrFile::Error;
}
if (view) {
auto ws = _win->m_views.value(view);
return view->save(
ws, {}, ignoreMd5, false,
EditorView::SaveWorkSpaceAttr::AutoWorkSpace);
}
return ErrFile::Error;
});
if (view) {
auto ws = _win->m_views.value(view);
return view->save(ws, {}, false,
EditorView::SaveWorkSpaceAttr::AutoWorkSpace);
}
return ErrFile::Error;
});
connect(pctl, &WingPlugin::Controller::saveAsCurrent, _win,
[=](const QString &savename, bool ignoreMd5) -> ErrFile {
[=](const QString &savename) -> ErrFile {
if (!checkThreadAff()) {
return ErrFile::NotAllowedInNoneGUIThread;
}
@ -2836,7 +2793,7 @@ void PluginSystem::connectControllerInterface(IWingPlugin *plg) {
}
if (view) {
_win->saveEditor(view, savename, ignoreMd5, true);
_win->saveEditor(view, savename, true);
return ErrFile::Success;
}
return ErrFile::Error;