This commit is contained in:
寂静的羽夏 2022-07-16 20:55:25 +08:00
parent ca794cf910
commit bc84139179
20 changed files with 1032 additions and 9 deletions

View File

@ -14,6 +14,10 @@
## WingHexPy
  `WingHexPy`是一个强大的羽云十六进制编辑器插件,它具有对 Python3 脚本的支持,拥有即时交互控制台,使用脚本分析二进制有了可能。本插件支持所有的原生`IWingPlugin`的所有接口,于此同时也拥有自己独特的接口以供与插件进行交互。
  本插件基于 QCodeEditor 和 PythonQt 以及深度文本编辑器的部分代码(纯粹自己懒)进行开发。为了和深度主题适配所以有 DTK 依赖。
### 使用声明
1. 开发本软件目的是让羽云十六进制编辑器具有强大的脚本分析功能,使用 C++ 的 Python 拓展来弥补羽云十六进制编辑器相对于 010 Editor 的不足之处。

View File

@ -35,7 +35,12 @@ SOURCES += \
QCodeEditor/QLanguage.cpp \
scriptwindow.cpp \
recentfilemanager.cpp \
PythonQt/gui/PythonQtScriptingConsole.cpp
PythonQt/gui/PythonQtScriptingConsole.cpp \
findbar.cpp \
linebar.cpp \
replacebar.cpp \
aboutsoftwaredialog.cpp \
sponsordialog.cpp
HEADERS += \
winghexpy.h \
@ -78,7 +83,12 @@ HEADERS += \
PythonQt/PythonQtSystem.h \
PythonQt/PythonQtUtils.h \
PythonQt/PythonQtVariants.h \
PythonQt/gui/PythonQtScriptingConsole.h
PythonQt/gui/PythonQtScriptingConsole.h \
findbar.h \
linebar.h \
replacebar.h \
aboutsoftwaredialog.h \
sponsordialog.h
DISTFILES += WingHexPy.json

23
aboutsoftwaredialog.cpp Normal file
View File

@ -0,0 +1,23 @@
#include "aboutsoftwaredialog.h"
#include <DLabel>
#include <DTextBrowser>
#include <QPixmap>
AboutSoftwareDialog::AboutSoftwareDialog(DMainWindow *parent)
: DDialog(parent) {
QPixmap pic;
pic.load(":/img/author.jpg");
auto l = new DLabel(this);
l->setFixedSize(100, 100);
l->setScaledContents(true);
l->setPixmap(pic);
addContent(l, Qt::AlignHCenter);
addSpacing(10);
auto b = new DTextBrowser(this);
b->setSearchPaths(QStringList({":", ":/img"}));
b->setSource(QUrl("README.md"), QTextDocument::MarkdownResource);
b->setFixedSize(800, 500);
b->setOpenExternalLinks(true);
addContent(b);
}

20
aboutsoftwaredialog.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef ABOUTSOFTWAREDIALOG_H
#define ABOUTSOFTWAREDIALOG_H
#include <DDialog>
#include <DMainWindow>
#include <QObject>
DWIDGET_USE_NAMESPACE
class AboutSoftwareDialog : public DDialog {
Q_OBJECT
public:
explicit AboutSoftwareDialog(DMainWindow *parent = nullptr);
signals:
public slots:
};
#endif // ABOUTSOFTWAREDIALOG_H

188
findbar.cpp Normal file
View File

@ -0,0 +1,188 @@
/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*-
* -*- coding: utf-8 -*-
*
* Copyright (C) 2011 ~ 2018 Deepin, Inc.
*
* Author: Wang Yong <wangyong@deepin.com>
* Maintainer: Rekols <rekols@foxmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "findbar.h"
#include <QDebug>
FindBar::FindBar(QWidget *parent) : DFloatingWidget(parent) {
// Init.
// setWindowFlags(Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint);
hide();
setFixedHeight(60);
// Init layout and widgets.
m_layout = new QHBoxLayout();
m_layout->setSpacing(10);
m_findLabel = new QLabel(tr("Find"));
m_findLabel->setMinimumHeight(36);
m_editLine = new LineBar();
m_editLine->lineEdit()->setMinimumHeight(36);
m_findPrevButton = new QPushButton(tr("Previous"));
// m_findPrevButton->setFixedSize(80, 36);
m_findNextButton = new QPushButton(tr("Next"));
// m_findNextButton->setFixedSize(80, 36);
m_closeButton = new DIconButton(DStyle::SP_CloseButton);
m_closeButton->setIconSize(QSize(30, 30));
m_closeButton->setFixedSize(30, 30);
m_closeButton->setEnabledCircle(true);
m_closeButton->setFlat(true);
m_layout->setContentsMargins(16, 6, 10, 6);
m_layout->addWidget(m_findLabel);
m_layout->addWidget(m_editLine);
m_layout->addWidget(m_findPrevButton);
m_layout->addWidget(m_findNextButton);
m_layout->addWidget(m_closeButton);
this->setLayout(m_layout);
// Make button don't grab keyboard focus after click it.
// m_findNextButton->setFocusPolicy(Qt::NoFocus);
// m_findPrevButton->setFocusPolicy(Qt::NoFocus);
// m_closeButton->setFocusPolicy(Qt::NoFocus);
connect(this, &FindBar::pressEsc, this, &FindBar::findCancel,
Qt::QueuedConnection);
// connect(m_editLine, &LineBar::pressEnter, this, &FindBar::findNext,
// Qt::QueuedConnection); //Shielded by Hengbo ,for new demand.
// 20200220
// connect(m_editLine, &LineBar::pressCtrlEnter, this, &FindBar::findPrev,
// Qt::QueuedConnection);
connect(m_editLine, &LineBar::returnPressed, this,
&FindBar::handleContentChanged, Qt::QueuedConnection);
connect(m_editLine, &LineBar::signal_sentText, this, &FindBar::receiveText,
Qt::QueuedConnection);
// connect(m_editLine, &LineBar::contentChanged, this,
// &FindBar::slot_ifClearSearchWord, Qt::QueuedConnection);
connect(m_findNextButton, &QPushButton::clicked, this,
&FindBar::handleFindNext, Qt::QueuedConnection);
connect(m_findPrevButton, &QPushButton::clicked, this,
&FindBar::handleFindPrev, Qt::QueuedConnection);
// connect(m_findPrevButton, &QPushButton::clicked, this, &FindBar::findPrev,
// Qt::QueuedConnection);
connect(m_closeButton, &DIconButton::clicked, this, &FindBar::findCancel,
Qt::QueuedConnection);
}
bool FindBar::isFocus() { return m_editLine->lineEdit()->hasFocus(); }
void FindBar::focus() {
m_editLine->lineEdit()->setFocus();
m_editLine->lineEdit()->selectAll();
}
void FindBar::activeInput(QString text, QString file, int row, int column,
int scrollOffset) {
// Try fill keyword with select text.
m_editLine->lineEdit()->clear();
m_editLine->lineEdit()->insert(text);
m_editLine->lineEdit()->selectAll();
// Show.
QWidget::show();
// Save file info for back to position.
m_findFile = file;
m_findFileRow = row;
m_findFileColumn = column;
m_findFileSrollOffset = scrollOffset;
// Focus.
focus();
}
void FindBar::findCancel() {
QWidget::hide();
emit sigFindbarClose();
}
void FindBar::handleContentChanged() {
updateSearchKeyword(m_findFile, m_editLine->lineEdit()->text());
}
void FindBar::handleFindPrev() { findPrev(m_editLine->lineEdit()->text()); }
void FindBar::handleFindNext() { findNext(m_editLine->lineEdit()->text()); }
void FindBar::hideEvent(QHideEvent *) {
//保留查询标记
// removeSearchKeyword();
}
bool FindBar::focusNextPrevChild(bool next) {
Q_UNUSED(next);
return false;
}
// modiefied by wingsummer
void FindBar::keyPressEvent(QKeyEvent *e) {
bool unhandled = false;
if (e->modifiers() == Qt::KeyboardModifier::NoModifier) {
switch (e->key()) {
case Qt::Key_Escape: {
QWidget::hide();
emit sigFindbarClose();
} break;
case Qt::Key_Tab: {
if (m_closeButton->hasFocus())
m_editLine->lineEdit()->setFocus();
} break;
case Qt::Key_Enter: {
if (m_findPrevButton->hasFocus()) {
m_editLine->lineEdit()->setFocus();
}
if (m_findNextButton->hasFocus()) {
m_findNextButton->click();
}
} break;
default:
unhandled = true;
break;
}
}
if (unhandled)
DFloatingWidget::keyPressEvent(e);
}
void FindBar::setMismatchAlert(bool isAlert) { m_editLine->setAlert(isAlert); }
void FindBar::receiveText(QString t) {
searched = false;
if (t != "") {
m_receivedText = t;
}
}
void FindBar::setSearched(bool _) { searched = _; }
void FindBar::findPreClicked() {
if (!searched) {
updateSearchKeyword(m_findFile, m_editLine->lineEdit()->text());
emit findPrev(m_editLine->lineEdit()->text());
searched = true;
} else {
emit findPrev(m_editLine->lineEdit()->text());
}
}

103
findbar.h Normal file
View File

@ -0,0 +1,103 @@
/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*-
* -*- coding: utf-8 -*-
*
* Copyright (C) 2011 ~ 2018 Deepin, Inc.
*
* Author: Wang Yong <wangyong@deepin.com>
* Maintainer: Rekols <rekols@foxmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef FINDBAR_H
#define FINDBAR_H
#include "linebar.h"
#include "dimagebutton.h"
#include <DApplicationHelper>
#include <DFloatingWidget>
#include <DIconButton>
#include <QColor>
#include <QHBoxLayout>
#include <QLabel>
#include <QMouseEvent>
#include <QMouseEventTransition>
#include <QPainter>
#include <QPushButton>
#include <QWidget>
#include <qmouseeventtransition.h>
#include <DAbstractDialog>
#include <DPalette>
DWIDGET_USE_NAMESPACE
class FindBar : public DFloatingWidget {
Q_OBJECT
public:
explicit FindBar(QWidget *parent = nullptr);
bool isFocus();
void focus();
void activeInput(QString text, QString file, int row, int column,
int scrollOffset);
void setMismatchAlert(bool isAlert);
void receiveText(QString t);
void setSearched(bool _);
void findPreClicked();
signals:
void pressEsc();
void findNext(const QString &keyword);
void findPrev(const QString &keyword);
void removeSearchKeyword();
void updateSearchKeyword(QString file, QString keyword);
// add guoshao
void sigFindbarClose();
public slots:
void findCancel();
void handleContentChanged();
void handleFindNext();
void handleFindPrev();
protected:
void hideEvent(QHideEvent *event) override;
bool focusNextPrevChild(bool next) override;
void keyPressEvent(QKeyEvent *e) override;
private:
QPushButton *m_findNextButton;
QPushButton *m_findPrevButton;
DIconButton *m_closeButton;
LineBar *m_editLine;
QHBoxLayout *m_layout;
QLabel *m_findLabel;
QString m_findFile;
int m_findFileColumn;
int m_findFileRow;
int m_findFileSrollOffset;
QColor m_backgroundColor;
QString m_receivedText = " ";
bool searched = false;
QPoint last;
};
#endif

48
img/README.md Normal file
View File

@ -0,0 +1,48 @@
开源不易,给个 Star 或者 捐助 吧
## WingHexPy
&emsp;&emsp;`WingHexPy`是一个强大的羽云十六进制编辑器插件,它具有对 Python3 脚本的支持,拥有即时交互控制台,使用脚本分析二进制有了可能。本插件支持所有的原生`IWingPlugin`的所有接口,于此同时也拥有自己独特的接口以供与插件进行交互。
&emsp;&emsp;本插件基于 QCodeEditor 和 PythonQt 以及深度文本编辑器的部分代码(纯粹自己懒)进行开发。为了和深度主题适配所以有 DTK 依赖。
### 使用声明
1. 开发本软件目的是让羽云十六进制编辑器具有强大的脚本分析功能,使用 C++ 的 Python 拓展来弥补羽云十六进制编辑器相对于 010 Editor 的不足之处。
2. 本软件仅供学习交流使用,不得私自用于商业用途。如需将本软件某些部分用于商业用途,必须找我购买商业授权,价格私聊。
3. 本人学生,由于本软件是用我的业余时间编写,不能及时修复 Bug 或者提供技术支持,请见谅。
4. 本人非计算机专业,编写程序难免有 Bug ,欢迎提交 PR 。
### 参与贡献
1. 如果您有想参与本软件代码开发递交,请在 pull request 联系我。
2. 本项目支持捐助,如有意愿请到本仓库通过微信或者支付宝的方式进行,一瓶水的价钱足以提高我的维护该项目的热情,感谢大家的支持。
3. 如果您想提交修复或者增进程序的代码,请在 pull request 递交。
4. 任何成功参与代码 Bug 修复以及增进程序功能的同志和 Sponsor ,都会在本仓库 ReadMe 和附属说明文件中体现,您如果是其中之一,本人可以按照您合理的意愿来进行说明。
**加入我们并不意味着就是代码的维护,你可以选择下列一项或多项进行参与:**
1. 代码维护:实现新功能或修复 BUG ,对代码进行维护和升级。
2. 文档编辑:主要是接口文档和教程需要撰写编辑,这很重要。
3. 参与讨论:主要是讨论本项目未来发展和方向等。
4. 编写插件:一起增强该软件的功能。
### 协议
&emsp;&emsp;本插件仓库将采用`AGPL-3.0`协议,不得将该插件代码用于改协议之外的用途。
### issue 前必读
&emsp;&emsp;如果你有任何形式的建议,在提交 issue 之前,请一定要阅读下面的声明,以免浪费我们双方宝贵的时间:
1. 本人不考虑多语言支持,主要是没时间和资金。由于本人是中国人,本人不考虑其他语言使用者。但如果使用其他语言,如果你有语言包,只需要简单的替换文件即可。
2. 本人不会将此插件单独打包为 deb ,会捆绑在“羽云十六进制编辑器”的安装包内供大家使用。
3. 本人不考虑主题 UI 层面的问题,开发本插件与窗体相关一切采用 DTK 原生样式,觉得丑找官方,或者自己写个样式编译加载。
&emsp;&emsp;上面一切的一切,如果你是志同道合的开源贡献者,欢迎 fork 我的仓库进行相应的维护!
## 有关仓库
* GitLink https://www.gitlink.org.cn/wingsummer/WingHexPy
* Gitea https://code.gitlink.org.cn/wingsummer/WingHexPy
* Gitee https://gitee.com/wingsummer/wing-hex-py

BIN
img/find.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
img/replace.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
img/runf.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

83
linebar.cpp Normal file
View File

@ -0,0 +1,83 @@
/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*-
* -*- coding: utf-8 -*-
*
* Copyright (C) 2011 ~ 2018 Deepin, Inc.
*
* Author: Wang Yong <wangyong@deepin.com>
* Maintainer: Rekols <rekols@foxmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "linebar.h"
#include <QDebug>
#include <QKeyEvent>
LineBar::LineBar(DLineEdit *parent) : DLineEdit(parent) {
// Init.
setClearButtonEnabled(true);
m_autoSaveInternal = 50;
m_autoSaveTimer = new QTimer(this);
m_autoSaveTimer->setSingleShot(true);
connect(m_autoSaveTimer, &QTimer::timeout, this,
&LineBar::handleTextChangeTimer);
connect(this, &DLineEdit::textEdited, this, &LineBar::sendText,
Qt::QueuedConnection);
connect(this, &DLineEdit::textChanged, this, &LineBar::handleTextChanged,
Qt::QueuedConnection);
}
void LineBar::handleTextChangeTimer() {
// Emit contentChanged signal.
contentChanged();
}
void LineBar::handleTextChanged() {
// Stop timer if new character is typed, avoid unused timer run.
if (m_autoSaveTimer->isActive()) {
m_autoSaveTimer->stop();
}
// Start new timer.
m_autoSaveTimer->start(m_autoSaveInternal);
}
void LineBar::sendText(QString t) { emit signal_sentText(t); }
void LineBar::focusOutEvent(QFocusEvent *e) {
// Emit focus out signal.
focusOut();
// Throw event out avoid DLineEdit can't hide cursor after lost focus.
DLineEdit::focusOutEvent(e);
}
void LineBar::keyPressEvent(QKeyEvent *e) {
auto modifiers = e->modifiers();
if (modifiers == Qt::ControlModifier && e->text() == "\r") {
pressCtrlEnter();
} else if (modifiers == Qt::AltModifier && e->text() == "\r") {
pressAltEnter();
} else if (modifiers == Qt::MetaModifier && e->text() == "\r") {
pressMetaEnter();
} else if (modifiers == Qt::NoModifier && e->text() == "\r") {
pressEnter();
} else {
// Pass event to DLineEdit continue, otherwise you can't type anything after
// here. ;)
DLineEdit::keyPressEvent(e);
}
}

62
linebar.h Normal file
View File

@ -0,0 +1,62 @@
/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*-
* -*- coding: utf-8 -*-
*
* Copyright (C) 2011 ~ 2018 Deepin, Inc.
*
* Author: Wang Yong <wangyong@deepin.com>
* Maintainer: Rekols <rekols@foxmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef LINEBAR_H
#define LINEBAR_H
#include "dlineedit.h"
#include <QTimer>
DWIDGET_USE_NAMESPACE
class LineBar : public DLineEdit
{
Q_OBJECT
public:
explicit LineBar(DLineEdit *parent = 0);
public slots:
void handleTextChangeTimer();
void handleTextChanged();
void sendText(QString t);
signals:
void contentChanged();
void focusOut();
void pressAltEnter();
void pressCtrlEnter();
void pressEnter();
void pressMetaEnter();
void signal_sentText(QString t);
protected:
virtual void focusOutEvent(QFocusEvent *e);
virtual void keyPressEvent(QKeyEvent *e);
private:
QTimer *m_autoSaveTimer;
int m_autoSaveInternal;
};
#endif

246
replacebar.cpp Normal file
View File

@ -0,0 +1,246 @@
/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*-
* -*- coding: utf-8 -*-
*
* Copyright (C) 2011 ~ 2018 Deepin, Inc.
*
* Author: Wang Yong <wangyong@deepin.com>
* Maintainer: Rekols <rekols@foxmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "replacebar.h"
#include <QDebug>
#include <QKeyEvent>
ReplaceBar::ReplaceBar(QWidget *parent) : DFloatingWidget(parent) {
// Init.
hide();
setFixedHeight(60);
// Init layout and widgets.
m_layout = new QHBoxLayout();
m_layout->setSpacing(10);
m_layout->setContentsMargins(16, 6, 10, 6);
m_replaceLabel = new QLabel(tr("Find"));
// m_replaceLabel->setMinimumHeight(36);
m_replaceLine = new LineBar();
// m_replaceLine->lineEdit()->setMinimumHeight(36);
m_withLabel = new QLabel(tr("Replace With"));
// m_withLabel->setMinimumHeight(36);
m_withLine = new LineBar();
// m_withLine->lineEdit()->setMinimumHeight(36);
m_replaceButton = new QPushButton(tr("Replace"));
// m_replaceButton->setMinimumWidth(66);
// m_replaceButton->setMinimumHeight(36);
m_replaceSkipButton = new QPushButton(tr("Skip"));
// m_replaceSkipButton->setMinimumWidth(66);
// m_replaceSkipButton->setMinimumHeight(36);
m_replaceRestButton = new QPushButton(tr("Replace Rest"));
// m_replaceRestButton->setMinimumWidth(80);
// m_replaceRestButton->setMinimumHeight(36);
m_replaceAllButton = new QPushButton(tr("Replace All"));
// m_replaceAllButton->setMinimumWidth(80);
// m_replaceAllButton->setMinimumHeight(36);
m_closeButton = new DIconButton(DStyle::SP_CloseButton);
m_closeButton->setFlat(true);
m_closeButton->setFixedSize(30, 30);
m_closeButton->setEnabledCircle(true);
m_closeButton->setIconSize(QSize(30, 30));
m_layout->addWidget(m_replaceLabel);
m_layout->addWidget(m_replaceLine);
m_layout->addWidget(m_withLabel);
m_layout->addWidget(m_withLine);
m_layout->addWidget(m_replaceButton);
m_layout->addWidget(m_replaceSkipButton);
m_layout->addWidget(m_replaceRestButton);
m_layout->addWidget(m_replaceAllButton);
m_layout->addWidget(m_closeButton);
this->setLayout(m_layout);
// Make button don't grab keyboard focus after click it.
#if 0
m_replaceButton->setFocusPolicy(Qt::NoFocus);
m_replaceSkipButton->setFocusPolicy(Qt::NoFocus);
m_replaceRestButton->setFocusPolicy(Qt::NoFocus);
m_replaceAllButton->setFocusPolicy(Qt::NoFocus);
m_closeButton->setFocusPolicy(Qt::NoFocus);
#endif
connect(m_replaceLine, &LineBar::signal_sentText, this, &ReplaceBar::change,
Qt::QueuedConnection);
connect(this, &ReplaceBar::pressEsc, this, &ReplaceBar::replaceClose,
Qt::QueuedConnection);
// connect(m_replaceLine, &LineBar::pressEnter, this,
// &ReplaceBar::handleReplaceNext, Qt::QueuedConnection); //Shielded
// by Hengbo for new demand.
connect(m_withLine, &LineBar::returnPressed, this,
&ReplaceBar::handleReplaceNext, Qt::QueuedConnection);
connect(m_replaceLine, &LineBar::pressCtrlEnter, this, [=]() {
emit replaceSkip(m_replaceFile, m_replaceLine->lineEdit()->text());
});
connect(m_withLine, &LineBar::pressCtrlEnter, this, [=]() {
emit replaceSkip(m_replaceFile, m_replaceLine->lineEdit()->text());
});
connect(m_replaceLine, &LineBar::pressAltEnter, this,
&ReplaceBar::handleReplaceRest, Qt::QueuedConnection);
connect(m_withLine, &LineBar::pressAltEnter, this,
&ReplaceBar::handleReplaceRest, Qt::QueuedConnection);
connect(m_replaceLine, &LineBar::pressMetaEnter, this,
&ReplaceBar::handleReplaceAll, Qt::QueuedConnection);
connect(m_withLine, &LineBar::pressMetaEnter, this,
&ReplaceBar::handleReplaceAll, Qt::QueuedConnection);
connect(m_replaceLine, &LineBar::returnPressed, this,
&ReplaceBar::handleContentChanged, Qt::QueuedConnection);
connect(m_replaceButton, &QPushButton::clicked, this,
&ReplaceBar::handleReplaceNext, Qt::QueuedConnection);
connect(m_replaceSkipButton, &QPushButton::clicked, this, [=]() {
emit replaceSkip(m_replaceFile, m_replaceLine->lineEdit()->text());
});
connect(m_replaceRestButton, &QPushButton::clicked, this,
&ReplaceBar::handleReplaceRest, Qt::QueuedConnection);
connect(m_replaceAllButton, &QPushButton::clicked, this,
&ReplaceBar::handleReplaceAll, Qt::QueuedConnection);
connect(m_closeButton, &DIconButton::clicked, this, &ReplaceBar::replaceClose,
Qt::QueuedConnection);
}
bool ReplaceBar::isFocus() { return m_replaceLine->hasFocus(); }
void ReplaceBar::focus() { m_replaceLine->lineEdit()->setFocus(); }
void ReplaceBar::activeInput(QString text, QString file, int row, int column,
int scrollOffset) {
// Try fill keyword with select text.
m_withLine->lineEdit()->clear();
m_replaceLine->lineEdit()->clear();
m_replaceLine->lineEdit()->insert(text);
m_replaceLine->lineEdit()->selectAll();
// Show.
show();
// Save file info for back to position.
m_replaceFile = file;
m_replaceFileRow = row;
m_replaceFileColumn = column;
m_replaceFileSrollOffset = scrollOffset;
// Focus.
focus();
}
void ReplaceBar::replaceClose() {
searched = false;
hide();
emit sigReplacebarClose();
}
void ReplaceBar::handleContentChanged() {
updateSearchKeyword(m_replaceFile, m_replaceLine->lineEdit()->text());
}
void ReplaceBar::handleReplaceNext() {
if (!searched) {
emit removeSearchKeyword();
emit beforeReplace(m_replaceLine->lineEdit()->text());
}
replaceNext(m_replaceFile, m_replaceLine->lineEdit()->text(),
m_withLine->lineEdit()->text());
searched = true;
}
void ReplaceBar::handleReplaceRest() {
replaceRest(m_replaceLine->lineEdit()->text(),
m_withLine->lineEdit()->text());
}
void ReplaceBar::handleReplaceAll() {
replaceAll(m_replaceLine->lineEdit()->text(), m_withLine->lineEdit()->text());
}
void ReplaceBar::hideEvent(QHideEvent *) {
searched = false;
removeSearchKeyword();
}
bool ReplaceBar::focusNextPrevChild(bool) {
// Make keyword jump between two EditLine widgets.
auto *editWidget = qobject_cast<LineBar *>(focusWidget());
if (editWidget != nullptr) {
if (editWidget == m_replaceLine) {
m_withLine->lineEdit()->setFocus();
return true;
} else if (editWidget == m_withLine) {
m_replaceLine->lineEdit()->setFocus();
return true;
}
}
return false;
}
void ReplaceBar::keyPressEvent(QKeyEvent *e) {
bool unhandled = false;
if (e->modifiers() == Qt::KeyboardModifier::NoModifier) {
switch (e->key()) {
case Qt::Key_Escape: {
QWidget::hide();
emit sigReplacebarClose();
} break;
case Qt::Key_Tab: {
if (m_closeButton->hasFocus())
m_replaceLine->lineEdit()->setFocus();
} break;
case Qt::Key_Enter: {
if (m_replaceAllButton->hasFocus()) {
m_replaceAllButton->click();
}
if (m_replaceButton->hasFocus()) {
m_replaceButton->click();
}
if (m_replaceRestButton->hasFocus()) {
m_replaceRestButton->click();
}
if (m_replaceSkipButton->hasFocus()) {
m_replaceSkipButton->click();
}
} break;
default:
unhandled = true;
break;
}
}
if (unhandled)
DFloatingWidget::keyPressEvent(e);
}
void ReplaceBar::setMismatchAlert(bool isAlert) {
m_replaceLine->setAlert(isAlert);
}
void ReplaceBar::setsearched(bool _) { searched = _; }
void ReplaceBar::change() { searched = false; }

103
replacebar.h Normal file
View File

@ -0,0 +1,103 @@
/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*-
* -*- coding: utf-8 -*-
*
* Copyright (C) 2011 ~ 2018 Deepin, Inc.
*
* Author: Wang Yong <wangyong@deepin.com>
* Maintainer: Rekols <rekols@foxmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef REPLACEBAR_H
#define REPLACEBAR_H
#include "dimagebutton.h"
#include "linebar.h"
#include <DAbstractDialog>
#include <DApplicationHelper>
#include <DFloatingWidget>
#include <DIconButton>
#include <QHBoxLayout>
#include <QLabel>
#include <QPainter>
#include <QPushButton>
#include <QWidget>
DWIDGET_USE_NAMESPACE
class ReplaceBar : public DFloatingWidget {
Q_OBJECT
public:
explicit ReplaceBar(QWidget *parent = nullptr);
bool isFocus();
void focus();
void activeInput(QString text, QString file, int row, int column,
int scrollOffset);
void setMismatchAlert(bool isAlert);
void setsearched(bool _);
signals:
void pressEsc();
void replaceNext(QString file, QString replaceText, QString withText);
void replaceSkip(QString file, QString keyword);
void replaceRest(QString replaceText, QString withText);
void replaceAll(QString replaceText, QString withText);
void beforeReplace(QString _);
void backToPosition(QString file, int row, int column, int scrollOffset);
void removeSearchKeyword();
void updateSearchKeyword(QString file, QString keyword);
void sigReplacebarClose();
public slots:
void change();
void replaceClose();
void handleContentChanged();
void handleReplaceAll();
void handleReplaceNext();
void handleReplaceRest();
protected:
void hideEvent(QHideEvent *event);
bool focusNextPrevChild(bool next);
void keyPressEvent(QKeyEvent *e);
private:
QPushButton *m_replaceAllButton;
QPushButton *m_replaceButton;
QPushButton *m_replaceRestButton;
QPushButton *m_replaceSkipButton;
DIconButton *m_closeButton;
LineBar *m_replaceLine;
LineBar *m_withLine;
QHBoxLayout *m_layout;
QLabel *m_replaceLabel;
QLabel *m_withLabel;
QString m_replaceFile;
int m_replaceFileColumn;
int m_replaceFileRow;
int m_replaceFileSrollOffset;
QColor m_backgroundColor;
bool searched = false;
QPoint last;
};
#endif

View File

@ -25,5 +25,10 @@
<file>img/close.png</file>
<file>img/edit.png</file>
<file>img/run.png</file>
<file>img/runf.png</file>
<file>img/find.png</file>
<file>img/replace.png</file>
<file>sponsor.png</file>
<file>img/README.md</file>
</qresource>
</RCC>

View File

@ -1,11 +1,13 @@
#include "scriptwindow.h"
#include "../WingHexExplorer/wing-hex-explorer.sourcecode/WingHexExplorer/plugin/iwingplugin.h"
#include "QCodeEditor/QPythonHighlighter.hpp"
#include "aboutsoftwaredialog.h"
#include "plginterface.h"
#include "sponsordialog.h"
#include <DFileDialog>
#include <DTitlebar>
#include <DWidgetUtil>
#include <Python.h>
#include <QVBoxLayout>
#define ICONRES(name) QIcon(":/img/" name ".png")
@ -19,7 +21,7 @@ ScriptWindow *ScriptWindow::instance() {
}
ScriptWindow::ScriptWindow(DMainWindow *parent) : DMainWindow(parent) {
setMinimumSize(QSize(600, 500));
setMinimumSize(QSize(800, 600));
auto _title = titlebar();
auto picon = ICONRES("pys");
@ -28,7 +30,7 @@ ScriptWindow::ScriptWindow(DMainWindow *parent) : DMainWindow(parent) {
_title->setTitle(tr("WingHexPyScriptWindow"));
auto w = new QWidget(this);
setCentralWidget(w);
auto vlayout = new QVBoxLayout(w);
vlayout = new QVBoxLayout(w);
m_styles[0] = QSyntaxStyle::defaultStyle();
auto darkstyle = new QSyntaxStyle(this);
@ -94,6 +96,29 @@ ScriptWindow::ScriptWindow(DMainWindow *parent) : DMainWindow(parent) {
ScriptWindow::on_copy);
PluginMenuAddItemIconAction(m, tr("Paste"), ICONRES("paste"),
ScriptWindow::on_paste);
m->addSeparator();
PluginMenuAddItemIconAction(m, tr("Find"), ICONRES("find"),
ScriptWindow::on_find);
PluginMenuAddItemIconAction(m, tr("Replace"), ICONRES("replace"),
ScriptWindow::on_replace);
}
PluginMenuInitEnd();
menu->addMenu(m);
PluginMenuInitBegin(m, tr("Script")) {
m->setIcon(ICONRES("icon"));
PluginMenuAddItemIconAction(m, tr("Run"), ICONRES("run"),
ScriptWindow::on_run);
PluginMenuAddItemIconAction(m, tr("RunFile"), ICONRES("runf"),
ScriptWindow::on_runfile);
}
PluginMenuInitEnd();
menu->addMenu(m);
PluginMenuInitBegin(m, tr("About")) {
m->setIcon(ICONRES("author"));
PluginMenuAddItemIconAction(m, tr("AboutPlugin"), ICONRES("soft"),
ScriptWindow::on_about);
PluginMenuAddItemIconAction(m, tr("Sponsor"), ICONRES("sponsor"),
ScriptWindow::on_sponsor);
}
PluginMenuInitEnd();
menu->addMenu(m);
@ -127,11 +152,23 @@ ScriptWindow::ScriptWindow(DMainWindow *parent) : DMainWindow(parent) {
tr("Cut"));
PluginToolBarAddAction(toolbar, ICONRES("copy"), ScriptWindow::on_copy,
tr("Copy"));
PluginToolBarAddAction(toolbar, ICONRES("paste"), ScriptWindow::on_saveas,
PluginToolBarAddAction(toolbar, ICONRES("paste"), ScriptWindow::on_paste,
tr("Paste"));
toolbar->addSeparator();
PluginToolBarAddAction(toolbar, ICONRES("find"), ScriptWindow::on_find,
tr("Find"));
PluginToolBarAddAction(toolbar, ICONRES("replace"),
ScriptWindow::on_replace, tr("Replace"));
toolbar->addSeparator();
PluginToolBarAddAction(toolbar, ICONRES("run"), ScriptWindow::on_run,
tr("Run"));
PluginToolBarAddAction(toolbar, ICONRES("runf"), ScriptWindow::on_runfile,
tr("RunFile"));
toolbar->addSeparator();
PluginToolBarAddAction(toolbar, ICONRES("soft"), ScriptWindow::on_about,
tr("AboutPlugin"));
PluginToolBarAddAction(toolbar, ICONRES("sponsor"),
ScriptWindow::on_sponsor, tr("Sponsor"));
}
PluginToolBarInitEnd();
@ -149,6 +186,13 @@ ScriptWindow::ScriptWindow(DMainWindow *parent) : DMainWindow(parent) {
mredo->setEnabled(b);
});
findbar = new FindBar(this);
vlayout->addWidget(findbar);
replacebar = new ReplaceBar(this);
vlayout->addWidget(replacebar);
connect(editor, &QCodeEditor::textChanged, this, [=] { isSaved = false; });
Dtk::Widget::moveToCenter(this);
}
@ -160,7 +204,12 @@ void ScriptWindow::setTheme(DGuiApplicationHelper::ColorType theme) {
}
}
void ScriptWindow::on_new() {}
void ScriptWindow::on_new() {
if (!isSaved) {
return;
}
editor->clear();
}
void ScriptWindow::on_open() {}
@ -181,6 +230,35 @@ void ScriptWindow::on_cut() { editor->cut(); }
void ScriptWindow::on_paste() { editor->paste(); }
void ScriptWindow::on_run() {
auto inst = PlgInterface::instance();
inst->RunPyText(editor->toPlainText());
PlgInterface::instance()->RunPyText(editor->toPlainText());
}
void ScriptWindow::on_runfile() {
auto filename = DFileDialog::getOpenFileName(this, tr("ChoosePyScript"),
QString(), "Python (*.py)");
if (filename.isEmpty())
return;
PlgInterface::instance()->RunPyFile(filename);
}
void ScriptWindow::on_find() {
replacebar->close();
auto cur = editor->textCursor();
findbar->activeInput("", "", cur.blockNumber(), cur.positionInBlock(), 0);
}
void ScriptWindow::on_replace() {
findbar->close();
auto cur = editor->textCursor();
replacebar->activeInput("", "", cur.blockNumber(), cur.positionInBlock(), 0);
}
void ScriptWindow::on_about() {
AboutSoftwareDialog d;
d.exec();
}
void ScriptWindow::on_sponsor() {
SponsorDialog d;
d.exec();
}

View File

@ -3,11 +3,14 @@
#include "QCodeEditor/QCodeEditor.hpp"
#include "QCodeEditor/QSyntaxStyle.hpp"
#include "findbar.h"
#include "recentfilemanager.h"
#include "replacebar.h"
#include <DGuiApplicationHelper>
#include <DMainWindow>
#include <DStatusBar>
#include <DToolBar>
#include <QVBoxLayout>
DWIDGET_USE_NAMESPACE
@ -34,7 +37,12 @@ private:
void on_cut();
void on_paste();
void on_run();
void on_runfile();
void on_close();
void on_sponsor();
void on_about();
void on_find();
void on_replace();
private:
QCodeEditor *editor;
@ -46,6 +54,12 @@ private:
QAction *mundo, *mredo;
DMenu *menu;
RecentFileManager *recentmanager;
QVBoxLayout *vlayout;
FindBar *findbar;
ReplaceBar *replacebar;
private:
bool isSaved = true;
};
#endif // SCRIPTWINDOW_H

BIN
sponsor.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 776 KiB

17
sponsordialog.cpp Normal file
View File

@ -0,0 +1,17 @@
#include "sponsordialog.h"
#include <DLabel>
#include <QPixmap>
SponsorDialog::SponsorDialog(DMainWindow *parent) : DDialog(parent) {
setWindowTitle(tr("Sponsor"));
addSpacing(5);
addContent(new DLabel(tr("ThanksForSponsor"), this), Qt::AlignHCenter);
addSpacing(5);
QPixmap sponsor(":/sponsor.png");
auto l = new DLabel(this);
l->setPixmap(sponsor);
l->setScaledContents(true);
addContent(l);
}

19
sponsordialog.h Normal file
View File

@ -0,0 +1,19 @@
#ifndef SPONSORDIALOG_H
#define SPONSORDIALOG_H
#include <DDialog>
#include <DMainWindow>
#include <QObject>
DWIDGET_USE_NAMESPACE
class SponsorDialog : public DDialog {
Q_OBJECT
public:
explicit SponsorDialog(DMainWindow *parent = nullptr);
signals:
public slots:
};
#endif // SPONSORDIALOG_H