fix: 移除局部文件的支持;移除断点显示;修复文件编辑保存若干个问题;
This commit is contained in:
parent
1e3b24bca0
commit
557311c85f
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 |
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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}
|
||||
|
|
|
@ -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 |
BIN
images/openr.png
BIN
images/openr.png
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
|
@ -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]
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 ®ion, 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);
|
||||
|
|
|
@ -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 ®ion, qsizetype start = -1,
|
||||
qsizetype length = -1);
|
||||
void openWorkSpace(const QString &ws);
|
||||
|
||||
private:
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -24,6 +24,7 @@ enum CacheIndex {
|
|||
// ICON_UNION,
|
||||
ICON_CLASS,
|
||||
// ICON_STRUCT,
|
||||
ICON_KEYWORD,
|
||||
ICON_TYPEDEF,
|
||||
ICON_NAMESPACE,
|
||||
ICON_FUNCTION = ICON_NAMESPACE + 2,
|
||||
|
|
|
@ -70,7 +70,8 @@ public:
|
|||
|
||||
Namespace = 'n',
|
||||
|
||||
Typedef = 't'
|
||||
Typedef = 't',
|
||||
KeyWord = 'k'
|
||||
};
|
||||
|
||||
enum NodeContent {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
class QKeySequences {
|
||||
public:
|
||||
enum class Key {
|
||||
OPEN_REGION_FILE,
|
||||
OPEN_WORKSPACE,
|
||||
REDO,
|
||||
SAVE_AS,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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); }
|
|
@ -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
|
|
@ -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, {});
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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(); }
|
||||
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
<height>200</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>WaitCursor</cursorShape>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue