Merge branch 'master' into cmake-dev
* master: 更新2.0新插件说明,插件可发送消息给主程序执行功能 一次性整体提交v2.0的代码;基础版功能全部提交完毕。 update README.md. update README.md. update README_EN.md. 把英文版本描述信息的措辞修改了一下。 update README_EN.md. 修改到实时最新 update README.md. update README.md.
18
README.md
|
@ -18,11 +18,9 @@
|
|||
|
||||
您可以在这个项目提交bug或反馈问题。
|
||||
|
||||
最新版本下载地址:https://gitee.com/cxasm/notepad--/releases/tag/v1.22
|
||||
最新版本下载地址:https://gitee.com/cxasm/notepad--/releases/latest
|
||||
|
||||
最新内测版本下载地址:https://gitee.com/cxasm/notepad--/releases/tag/v1.23
|
||||
|
||||
NDD已初步推出插件编写功能,希望广大的CPP/QT开发者加入我们,插件功能均可以留上您的大名和捐赠渠道,希望
|
||||
NDD 具备插件编写功能,希望广大的CPP/QT开发者加入我们,插件功能均可以留上您的大名和捐赠渠道,希望
|
||||
开发者参与插件功能开发。
|
||||
|
||||
做国人自己的免费编辑器,离不开您的支持,请通过微信捐赠我们。
|
||||
|
@ -159,10 +157,18 @@ QQ群 616606091 开发群,建议懂CPP/QT、愿意参与NDD项目代码贡献
|
|||
|
||||
## 效果预览
|
||||
|
||||
![输入图片说明](png/20221107_160824.png)
|
||||
**windows效果图:**
|
||||
|
||||
![输入图片说明](png/11.png.png)
|
||||
|
||||
![输入图片说明](png/6.png)
|
||||
|
||||
**MacOS 效果图:**
|
||||
|
||||
![Mac系统运行图](png/%E6%88%AA%E5%B1%8F2023-02-26%2011.41.20.png)
|
||||
|
||||
![Mac系统文件对比图](png/%E6%88%AA%E5%B1%8F2023-02-26%2011.45.48.png)
|
||||
![Mac系统文件对比图](png/%E6%88%AA%E5%B1%8F2023-02-26%2011.45.48.png)
|
||||
|
||||
**Redhat7.x 效果图:**
|
||||
|
||||
![输入图片说明](png/10.png.png)
|
14
README_EN.md
|
@ -4,19 +4,17 @@
|
|||
|
||||
## Project Introduction
|
||||
|
||||
Introducing Notepad-- a text editor written in C++ that works seamlessly across Windows, Linux, and Mac platforms. Our aim is to eventually surpass Notepad++, with a particular focus on the Chinese UOS operating system. Unlike Notepad++, our advantage lies in our cross-platform compatibility and support for various OSes.
|
||||
Introducing Notepad-- a text editor written in C++ that works seamlessly across Windows, Linux, and Mac platforms. Our goal is to eventually surpass Notepad++, with a special focus on the Chinese UOS operating system. Unlike Notepad++, our advantage lies in our cross-platform compatibility and support for different operating system.
|
||||
|
||||
**The purpose of Notepad-- is to counteract some of the misguided remarks made by the author of Notepad++ and to promote a more humble and grounded perspective.**
|
||||
**The purpose of Notepad-- is to counteract some of the misleading statements made by the author of Notepad++ and to promote a more humble and grounded perspective.**
|
||||
|
||||
If you come across any bugs or have any feedback, feel free to share it with us.
|
||||
If you come across any bugs or have any feedback, feel free to let us know.
|
||||
|
||||
You can download the latest version at https://gitee.com/cxasm/notepad--/releases/tag/v1.21.
|
||||
You can download the latest version from https://gitee.com/cxasm/notepad--/releases/tag/v2.0.
|
||||
|
||||
The latest development version can be found at https://gitee.com/cxasm/notepad--/releases/tag/v1.22.
|
||||
We have recently added the ability to write plugins to Notepad-- and we hope that many CPP/QT developers will join us in this endeavour. If you develop a plugin, you can include your name and a donation channel.
|
||||
|
||||
We have recently added the plugin writing feature to Notepad-- and we hope that many CPP/QT developers will join us in this endeavor. If you develop a plugin, you can include your name and a donation channel.
|
||||
|
||||
Creating a free text editor requires support from users like you. If you'd like to contribute, please consider donating through WeChat.
|
||||
Creating a free text editor requires support from users like you. If you'd like to contribute, please consider donating via WeChat.
|
||||
|
||||
![Input description picture](6688.png)
|
||||
|
||||
|
|
After Width: | Height: | Size: 159 KiB |
After Width: | Height: | Size: 127 KiB |
After Width: | Height: | Size: 149 KiB |
|
@ -992,7 +992,9 @@ CODE_ID CmpareMode::readLineFromFile(uchar* m_fileFpr, const int fileLength, con
|
|||
|
||||
|
||||
//扫描文件的字符编码,不输出文件
|
||||
CODE_ID CmpareMode::scanFileRealCode(QString filePath)
|
||||
//扫描多少行scanLineNum 默认100
|
||||
//如果是-1 之前全部扫描
|
||||
CODE_ID CmpareMode::scanFileRealCode(QString filePath, int scanLineNum)
|
||||
{
|
||||
QFile file(filePath);
|
||||
file.open(QIODevice::ReadOnly);
|
||||
|
@ -1060,8 +1062,10 @@ CODE_ID CmpareMode::scanFileRealCode(QString filePath)
|
|||
|
||||
++lineNums;
|
||||
|
||||
//最多扫描200行,加块速度。速度与精确性的权衡
|
||||
if (lineNums >= 200)
|
||||
//默认最多扫描200行,加块速度。速度与精确性的权衡
|
||||
//对于打开文件,默认扫描前面的200行,加快速度。
|
||||
//对于编码转换,为了精确,默认全部都要处理
|
||||
if ((scanLineNum != -1) && (lineNums >= scanLineNum))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
@ -1103,3 +1107,56 @@ CODE_ID CmpareMode::scanFileOutPut(CODE_ID code, QString filePath, QList<LineFil
|
|||
|
||||
return code;
|
||||
}
|
||||
|
||||
//读取文件,并输出
|
||||
//bytes charsNums:文件字符个数,不是文件大小
|
||||
//20220908 自动判断是否是二进制文件。isHexFile 是输出
|
||||
//20230304 新增,一次性读取文件,不检测每行文本,加快速度。existGrbledCode 是否存在乱码
|
||||
CODE_ID CmpareMode::scanFileOutPut(QFile& pFile, CODE_ID code, QString filePath, QString& outText, bool & existGrbledCode)
|
||||
{
|
||||
QByteArray outTextBytes = pFile.readAll();
|
||||
|
||||
if (outTextBytes.size() == 0)
|
||||
{
|
||||
outText = "";
|
||||
existGrbledCode = false;
|
||||
return CODE_ID::UTF8_NOBOM;
|
||||
}
|
||||
|
||||
if (code == UNKOWN)
|
||||
{
|
||||
code = getTextFileEncodeType((uchar * )outTextBytes.data(), pFile.size(), filePath);
|
||||
|
||||
//编码还是检测失败,这里概率是比较小的。
|
||||
if (code == CODE_ID::UNKOWN)
|
||||
{
|
||||
//无条件按照ANSI/GBK编码打开
|
||||
code = CODE_ID::GBK;
|
||||
}
|
||||
}
|
||||
|
||||
int lineStartPos = 0; //uicode_le前面有2个特殊标识,故跳过2
|
||||
|
||||
if (code == CODE_ID::UNICODE_BE || code == CODE_ID::UNICODE_LE)
|
||||
{
|
||||
lineStartPos = 2;
|
||||
}
|
||||
else if (code == CODE_ID::UTF8_BOM)
|
||||
{
|
||||
lineStartPos = 3;
|
||||
}
|
||||
|
||||
bool codeSucess = Encode::tranStrToUNICODE(code, outTextBytes.data()+ lineStartPos, outTextBytes.size()- lineStartPos, outText);
|
||||
|
||||
//如果存在乱码,而且不是以gbk编码打开,再无条件尝试ASNI/GBK编码打开。如果是国际版,后续还得完善策略,得无条件以ASNI本地编码打开。
|
||||
if (!codeSucess && (code != CODE_ID::GBK))
|
||||
{
|
||||
code = CODE_ID::GBK;
|
||||
outText.clear();
|
||||
codeSucess = Encode::tranStrToUNICODE(code, outTextBytes.data() + lineStartPos, outTextBytes.size() - lineStartPos, outText);
|
||||
}
|
||||
existGrbledCode = !codeSucess;
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
|
|
@ -70,8 +70,9 @@ public:
|
|||
static CODE_ID judgeFinalTextCode(CODE_ID code, bool isExistUnKownCode, bool isExistGbk, bool isExistUtf8);
|
||||
static CODE_ID readLineFromFile(uchar * m_fileFpr, const int fileLength, const CODE_ID fileCode, QList<LineFileInfo>& lineInfoVec,int& maxLineSize, int& charsNums, bool &isMaybeHexFile);
|
||||
|
||||
static CODE_ID scanFileRealCode(QString filePath);
|
||||
static CODE_ID scanFileRealCode(QString filePath,int scanLineNum=200);
|
||||
static CODE_ID scanFileOutPut(CODE_ID code, QString filePath, QList<LineFileInfo>& outputLineInfoVec, int & maxLineSize, int & charsNums, bool &isHexFile);
|
||||
static CODE_ID scanFileOutPut(QFile& pFile, CODE_ID code, QString filePath, QString& outText, bool& existGrbledCode);
|
||||
|
||||
static CODE_ID getTextFileEncodeType(uchar* fileFpr, int fileLength, QString filePath="", bool isCheckHead = true);
|
||||
static bool tranUnicodeLeToUtf8Bytes(uchar* fileFpr, const int fileLength, QString& outUtf8Bytes, bool isSkipHead=false);
|
||||
|
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 652 B After Width: | Height: | Size: 848 B |
|
@ -194,7 +194,7 @@ int getFileNewIndexProperty(QWidget* pwidget)
|
|||
return pwidget->property(Edit_File_New).toInt();
|
||||
}
|
||||
|
||||
void setTextChangeProperty(QWidget* pwidget, bool status)
|
||||
inline void setTextChangeProperty(QWidget* pwidget, bool status)
|
||||
{
|
||||
QVariant v(status);
|
||||
pwidget->setProperty(Edit_Text_Change, v);
|
||||
|
@ -454,6 +454,8 @@ QString watchFilePath;
|
|||
|
||||
QStringList CCNotePad::s_findHistroy;
|
||||
|
||||
QStringList CCNotePad::s_replaceHistroy;
|
||||
|
||||
int CCNotePad::s_autoWarp = 0; //自动换行
|
||||
int CCNotePad::s_indent = 0; //自动缩进
|
||||
int CCNotePad::s_showblank = 0; //显示空白
|
||||
|
@ -1505,14 +1507,7 @@ void CCNotePad::setUserDefShortcutKey(int shortcutId)
|
|||
ui.actionGoline->setShortcut(keySeq);
|
||||
|
||||
break;
|
||||
|
||||
case File_Compare_ID:
|
||||
break;
|
||||
case Dir_Compare_ID:
|
||||
break;
|
||||
case Bin_Compare_ID:
|
||||
break;
|
||||
|
||||
|
||||
case Trans_code_ID:
|
||||
keySeq = ShortcutKeyMgr::getUserDefShortcutKey(Trans_code);
|
||||
m_transcode->setShortcut(keySeq);
|
||||
|
@ -1785,8 +1780,10 @@ void CCNotePad::onPlugWork(bool check)
|
|||
if (pMainCallBack != NULL)
|
||||
{
|
||||
std::function<QsciScintilla* ()> foundCallBack = std::bind(&CCNotePad::getCurEditView, this);
|
||||
std::function<bool(int, void*)> pluginCallBack = std::bind(&CCNotePad::pluginInvoke, this, std::placeholders::_1, std::placeholders::_2);
|
||||
|
||||
pMainCallBack(this, plugPath, foundCallBack, pluginCallBack, nullptr);
|
||||
|
||||
pMainCallBack(this, plugPath, foundCallBack, nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1809,8 +1806,9 @@ void CCNotePad::sendParaToPlugin(NDD_PROC_DATA& procData)
|
|||
if (pMainCallBack != NULL)
|
||||
{
|
||||
std::function<QsciScintilla* ()> foundCallBack = std::bind(&CCNotePad::getCurEditView, this);
|
||||
std::function<bool(int, void*)> pluginCallBack = std::bind(&CCNotePad::pluginInvoke, this, std::placeholders::_1, std::placeholders::_2);
|
||||
|
||||
pMainCallBack(this, plugPath, foundCallBack, &procData);
|
||||
pMainCallBack(this, plugPath, foundCallBack, pluginCallBack, &procData);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2158,7 +2156,7 @@ void CCNotePad::initNotePadSqlOptions()
|
|||
ScintillaEditView::s_noUseTab = (1 == NddSetting::getKeyValueFromNumSets(key1)) ? true : false;
|
||||
|
||||
ScintillaEditView::s_bigTextSize = NddSetting::getKeyValueFromNumSets(MAX_BIG_TEXT);
|
||||
if (ScintillaEditView::s_bigTextSize < 50 || ScintillaEditView::s_bigTextSize > 300)
|
||||
if (ScintillaEditView::s_bigTextSize < 50 || ScintillaEditView::s_bigTextSize > 600)
|
||||
{
|
||||
ScintillaEditView::s_bigTextSize = 100;
|
||||
}
|
||||
|
@ -3380,6 +3378,14 @@ void CCNotePad::slot_lexerActTrig(QAction *action)
|
|||
//保存最近打开文件到数据库。文件只有在关闭时,才写入最近列表。不关闭的下次自动恢复打开
|
||||
void CCNotePad::saveReceneOpenFile()
|
||||
{
|
||||
int clearOpenfilelist = NddSetting::getKeyValueFromDelayNumSets(CLEAR_OPENFILE_ON_CLOSE);
|
||||
//开启了关闭时清空打开历史列表
|
||||
if (clearOpenfilelist == 1)
|
||||
{
|
||||
NddSetting::updataKeyValueFromDelaySets(RECENT_OPEN_FILE, "");
|
||||
return;
|
||||
}
|
||||
|
||||
QString rFile(RECENT_OPEN_FILE);
|
||||
|
||||
const int maxRecord = 15;
|
||||
|
@ -3542,7 +3548,8 @@ void CCNotePad::setLangsDescLable(QString &langDesc)
|
|||
//重新加载文件。这里有个问题,文件的序号会跳动,要解决跳动问题。
|
||||
//这里不能销毁当前pedit,加载编码也要保持不变。而且加载的文件一定是普通文本模式
|
||||
//目前只在文本文件被修改后,外部自动加载的场景
|
||||
void CCNotePad::reloadEditFile(ScintillaEditView* pEdit, bool isTailfOn)
|
||||
//如果isTailfOn == true, 则从startReadSize开始读取文件,不从头读取。startReadSize=-1则还是从头,否则从startReadSize开始
|
||||
void CCNotePad::reloadEditFile(ScintillaEditView* pEdit, bool isTailfOn, qint64 startReadSize)
|
||||
{
|
||||
QString filePath = pEdit->property(Edit_View_FilePath).toString();
|
||||
|
||||
|
@ -3557,16 +3564,35 @@ void CCNotePad::reloadEditFile(ScintillaEditView* pEdit, bool isTailfOn)
|
|||
|
||||
//下面这个clear会触发文本修改,要避免不必要的消息循环。先屏蔽一些信号
|
||||
disEnableEditTextChangeSign(pEdit);
|
||||
if (isTailfOn && startReadSize != -1)
|
||||
{
|
||||
//如果是tail模式,则不要直接把文档清空
|
||||
}
|
||||
else
|
||||
{
|
||||
pEdit->clear();
|
||||
}
|
||||
pEdit->setProperty(Edit_Text_Change, QVariant(false));
|
||||
setSaveButtonStatus(false);
|
||||
|
||||
int errCode = FileManager::getInstance().loadFileDataInText(pEdit, filePath, code, lineEnd, nullptr, false, this);
|
||||
int errCode = 0;
|
||||
|
||||
if (isTailfOn && startReadSize != -1)
|
||||
{
|
||||
//使用tailf读取尾部一部分数据;而不是全部读取
|
||||
errCode = FileManager::getInstance().loadFileDataInTextFromOffset(pEdit, filePath, code, this, startReadSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
errCode = FileManager::getInstance().loadFileDataInText(pEdit, filePath, code, lineEnd, nullptr, false, this);
|
||||
}
|
||||
|
||||
enableEditTextChangeSign(pEdit);
|
||||
|
||||
if (errCode == 5)
|
||||
if (6 == errCode)
|
||||
{
|
||||
//可能存在乱码,给出警告。还是以编辑模式打开
|
||||
ui.statusBar->showMessage(tr("File %1 open success. But Exist Garbled code !"));
|
||||
}
|
||||
else if (errCode != 0)
|
||||
{
|
||||
|
@ -3579,17 +3605,44 @@ void CCNotePad::reloadEditFile(ScintillaEditView* pEdit, bool isTailfOn)
|
|||
lineNum = pEdit->lines();
|
||||
}
|
||||
pEdit->execute(SCI_GOTOLINE, lineNum - 1);
|
||||
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
void CCNotePad::on_roladFile(ScintillaEditView* pEdit)
|
||||
void CCNotePad::on_roladFile(ScintillaEditView* pEdit,quint64 lastSize, qint64 curSize)
|
||||
{
|
||||
pEdit->setProperty(Modify_Outside, QVariant(true));
|
||||
checkRoladFile(pEdit);
|
||||
checkRoladFile(pEdit, lastSize);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool CCNotePad::checkRoladFile(ScintillaEditView* pEdit)
|
||||
void CCNotePad::doReloadTxtFile(ScintillaEditView* pEdit, bool isOnTail, qint64 startReadSize)
|
||||
{
|
||||
//reloadEditFile 里面会关闭和新增tab,触发一系列的currentChanged
|
||||
disconnect(ui.editTabWidget, &QTabWidget::currentChanged, this, &CCNotePad::slot_tabCurrentChanged);
|
||||
reloadEditFile(pEdit, isOnTail, startReadSize);
|
||||
pEdit->setProperty(Modify_Outside, QVariant(false));
|
||||
connect(ui.editTabWidget, &QTabWidget::currentChanged, this, &CCNotePad::slot_tabCurrentChanged, Qt::UniqueConnection);
|
||||
};
|
||||
|
||||
//初次进入文件tailf模式。把文件清空,而且只留100行文件
|
||||
void CCNotePad::firstTimeIntoTail(ScintillaEditView* pEdit, int remainLineNums)
|
||||
{
|
||||
int lineCount = pEdit->lines();
|
||||
int startLineNum = 0;
|
||||
if (lineCount >= remainLineNums)
|
||||
{
|
||||
startLineNum = lineCount - remainLineNums;
|
||||
}
|
||||
int pos = pEdit->execute(SCI_POSITIONFROMLINE, startLineNum);
|
||||
disEnableEditTextChangeSign(pEdit);
|
||||
pEdit->clear();
|
||||
enableEditTextChangeSign(pEdit);
|
||||
doReloadTxtFile(pEdit, true, pos);
|
||||
}
|
||||
|
||||
//startReadSize == -1 则从头开始读取。否则从startReadSize开始
|
||||
bool CCNotePad::checkRoladFile(ScintillaEditView* pEdit, qint64 startReadSize)
|
||||
{
|
||||
if (pEdit != nullptr && pEdit->property(Modify_Outside).toBool())
|
||||
{
|
||||
|
@ -3601,8 +3654,6 @@ bool CCNotePad::checkRoladFile(ScintillaEditView* pEdit)
|
|||
|
||||
m_isInReloadFile = true;
|
||||
|
||||
QString filePath = pEdit->property(Edit_View_FilePath).toString();
|
||||
|
||||
int tailStatus = getFileTailProperty(pEdit);
|
||||
|
||||
if (tailStatus != 1)
|
||||
|
@ -3610,25 +3661,38 @@ bool CCNotePad::checkRoladFile(ScintillaEditView* pEdit)
|
|||
QApplication::beep();
|
||||
}
|
||||
|
||||
auto doReload = [this](ScintillaEditView* pEdit, bool isOnTail) {
|
||||
//reloadEditFile 里面会关闭和新增tab,触发一系列的currentChanged
|
||||
disconnect(ui.editTabWidget, &QTabWidget::currentChanged, this, &CCNotePad::slot_tabCurrentChanged);
|
||||
reloadEditFile(pEdit, isOnTail);
|
||||
pEdit->setProperty(Modify_Outside, QVariant(false));
|
||||
connect(ui.editTabWidget, &QTabWidget::currentChanged, this, &CCNotePad::slot_tabCurrentChanged, Qt::UniqueConnection);
|
||||
};
|
||||
|
||||
//如果是开启了taif,则不提示,直接重新加载文件
|
||||
if (tailStatus == 1)
|
||||
{
|
||||
doReload(pEdit,true);
|
||||
//如果是进入tailf模式,但是startReadSize == -1.则什么也不干。
|
||||
//等监控超时后,后续走tailf差异读取模式。
|
||||
if (startReadSize == -1)
|
||||
{
|
||||
//这里什么也不做。坐等超时后,走下面的逻辑
|
||||
}
|
||||
else
|
||||
{
|
||||
//如果文件大于3000行,则删除内容,只保留当前100行,继续tailf
|
||||
if (pEdit->lines() < 3000)
|
||||
{
|
||||
doReloadTxtFile(pEdit, true, startReadSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
firstTimeIntoTail(pEdit,100);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
QString filePath = pEdit->property(Edit_View_FilePath).toString();
|
||||
|
||||
int ret = QMessageBox::question(this, tr("Reload"), tr("\"%1\" This file has been modified by another program. Do you want to reload it?").arg(filePath), tr("Yes[Reload]"), tr("No[Drop]"), tr("On Tailf"));
|
||||
if(ret == 0)
|
||||
{
|
||||
doReload(pEdit, false);
|
||||
doReloadTxtFile(pEdit, false, startReadSize);
|
||||
}
|
||||
else if (ret == 1)
|
||||
{
|
||||
|
@ -3638,8 +3702,10 @@ bool CCNotePad::checkRoladFile(ScintillaEditView* pEdit)
|
|||
else if (ret == 2)
|
||||
{
|
||||
m_tailf->setChecked(true);
|
||||
doReload(pEdit, true);
|
||||
|
||||
//这里也是首次开启tailf
|
||||
//读取最后3000行的内容。进入tailf模式
|
||||
firstTimeIntoTail(pEdit,3000);
|
||||
//开启监控
|
||||
tailfile(true,pEdit);
|
||||
}
|
||||
|
@ -3702,7 +3768,8 @@ void CCNotePad::enableEditTextChangeSign(ScintillaEditView* pEdit)
|
|||
//直到保存后,再放开
|
||||
void CCNotePad::disEnableEditTextChangeSign(ScintillaEditView* pEdit)
|
||||
{
|
||||
pEdit->disconnect(SIGNAL(textChanged()));
|
||||
//pEdit->disconnect(SIGNAL(textChanged()));
|
||||
disconnect(pEdit, &ScintillaEditView::textChanged, this, &CCNotePad::slot_editViewMofidyChange);
|
||||
}
|
||||
|
||||
//编辑框文本变化后,设置对应的变化状态
|
||||
|
@ -3909,10 +3976,22 @@ void CCNotePad::tabClose(int index, bool isInQuit)
|
|||
{
|
||||
QApplication::beep();
|
||||
|
||||
int ret = QMessageBox::question(this, tr("Do you want to save changes to before closing?"), tr("If you don't save the changes you made in file %1, you'll lose them forever.").arg(filePath), tr("Yes"), tr("No"), tr("Cancel"));
|
||||
|
||||
QMessageBox askSave(QMessageBox::Question, tr("Do you want to save changes to before closing?"), \
|
||||
tr("If you don't save the changes you made in file %1, you'll lose them forever.").arg(filePath), \
|
||||
QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, this);
|
||||
QPushButton* okButton = (QPushButton *) askSave.button(QMessageBox::Yes);
|
||||
okButton->setText(tr("&Yes"));
|
||||
|
||||
okButton = (QPushButton*)askSave.button(QMessageBox::No);
|
||||
okButton->setText(tr("&No"));
|
||||
|
||||
okButton = (QPushButton*)askSave.button(QMessageBox::Cancel);
|
||||
okButton->setText(tr("&Cancel"));
|
||||
|
||||
int ret = askSave.exec();
|
||||
|
||||
//保存
|
||||
if (ret == 0)
|
||||
if (ret == QMessageBox::Yes)
|
||||
{
|
||||
saveTabEdit(index);
|
||||
|
||||
|
@ -3922,7 +4001,7 @@ void CCNotePad::tabClose(int index, bool isInQuit)
|
|||
return;
|
||||
}
|
||||
}
|
||||
else if (ret == 2)
|
||||
else if (ret == QMessageBox::Cancel)
|
||||
{
|
||||
m_isQuitCancel = true;
|
||||
return;
|
||||
|
@ -4012,7 +4091,12 @@ ScintillaEditView* CCNotePad::newTxtFile(QString name, int index, QString conten
|
|||
if (!contentPath.isEmpty())
|
||||
{
|
||||
int ret = FileManager::getInstance().loadFileDataInText(pEdit, contentPath, code, lineEnd, nullptr, false, this);
|
||||
if (ret != 0)
|
||||
if (6 == ret)
|
||||
{
|
||||
//可能存在乱码,给出警告。还是以编辑模式打开
|
||||
ui.statusBar->showMessage(tr("File %1 open success. But Exist Garbled code !"));
|
||||
}
|
||||
else if (ret != 0)
|
||||
{
|
||||
ui.statusBar->showMessage(tr("Restore Last Temp File %1 Failed").arg(contentPath));
|
||||
}
|
||||
|
@ -4165,9 +4249,9 @@ bool CCNotePad::reloadTextFileWithCode(CODE_ID code)
|
|||
if (docType == TXT_TYPE)
|
||||
{
|
||||
int errCode = FileManager::getInstance().loadFileDataInText(pEdit, filePath, code, lineEnd, this, false,this);
|
||||
if (errCode == 5)
|
||||
if (errCode == 6)
|
||||
{
|
||||
//只读模式。暂时什么也不做
|
||||
//有乱码
|
||||
}
|
||||
else if (errCode != 0)
|
||||
{
|
||||
|
@ -4531,11 +4615,11 @@ bool CCNotePad::openTextFile(QString filePath, bool isCheckHex, CODE_ID code)
|
|||
//用户同意以二进制格式打开文件
|
||||
return openHexFile(filePath);
|
||||
}
|
||||
else if (5 == ret)
|
||||
{
|
||||
isReadOnly = true;
|
||||
//只读模式
|
||||
}
|
||||
//else if (5 == ret)
|
||||
//{
|
||||
// isReadOnly = true;
|
||||
// //只读模式
|
||||
//}
|
||||
else if (6 == ret)
|
||||
{
|
||||
//可能存在乱码,给出警告。还是以编辑模式打开
|
||||
|
@ -5158,7 +5242,7 @@ bool CCNotePad::tryRestoreFile(QString filePath)
|
|||
bool CCNotePad::openFile(QString filePath, int lineNum)
|
||||
{
|
||||
s_padTimes++;
|
||||
|
||||
//如果是相对路径
|
||||
getRegularFilePath(filePath);
|
||||
|
||||
QFileInfo fi(filePath);
|
||||
|
@ -5231,6 +5315,11 @@ void CCNotePad::slot_slectionChanged()
|
|||
|
||||
void CCNotePad::slot_actionOpenFile_toggle(bool /*checked*/)
|
||||
{
|
||||
if (s_lastOpenDirPath.isEmpty())
|
||||
{
|
||||
s_lastOpenDirPath = NddSetting::getKeyValueFromDelaySets(LAST_OPEN_DIR);
|
||||
}
|
||||
|
||||
QFileDialog fd(this,QString(), s_lastOpenDirPath);
|
||||
fd.setFileMode(QFileDialog::ExistingFile);
|
||||
|
||||
|
@ -5248,6 +5337,7 @@ void CCNotePad::slot_actionOpenFile_toggle(bool /*checked*/)
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
#ifdef _WIN32
|
||||
void hide_file(const QString& szFile)
|
||||
{
|
||||
|
@ -5259,12 +5349,13 @@ void hide_file(const QString& szFile)
|
|||
#endif // !UNICODE
|
||||
}
|
||||
#endif // _WIN32
|
||||
#endif
|
||||
|
||||
//bool isBakWrite:是否进行保护写,即先写swap文件,再写源文件。这样可以避免突然断电导致源文件被清空
|
||||
//isBakWrite 是否写保护swp文件,默认true。只有新文件时不需要,因为新文件不存在覆盖写的问题
|
||||
//isStatic 是否静默:不弹出对话框,在外部批量查找替换文件夹时使用,避免弹窗中断。默认false
|
||||
//isClearSwpFile:是否回收swp交换文件,在外部批量查找替换文件夹时使用,替换后直接删除swp文件。默认false
|
||||
bool CCNotePad::saveFile(QString fileName, ScintillaEditView* pEdit, bool isBakWrite, bool isStatic,bool isClearSwpFile)
|
||||
bool CCNotePad::saveFile(QString fileName, ScintillaEditView* pEdit, bool isBakWrite, bool isStatic,bool /*isClearSwpFile*/)
|
||||
{
|
||||
QFile srcfile(fileName);
|
||||
|
||||
|
@ -5398,7 +5489,7 @@ bool CCNotePad::saveFile(QString fileName, ScintillaEditView* pEdit, bool isBak
|
|||
bool success = saveWork(swapfile, fileName, true);
|
||||
if (success)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
#if 0 //不要这个了,windows下无条件删除
|
||||
if (!isClearSwpFile)
|
||||
{
|
||||
hide_file(swapFilePath);
|
||||
|
@ -5410,10 +5501,18 @@ bool CCNotePad::saveFile(QString fileName, ScintillaEditView* pEdit, bool isBak
|
|||
return false;
|
||||
}
|
||||
}
|
||||
#ifdef _WIN32
|
||||
//windows下面如果保存成功,则无条件删除swap文件,许多用户反感这个.swap文件存在
|
||||
if (success)
|
||||
{
|
||||
QFile::remove(swapFilePath);
|
||||
}
|
||||
#else
|
||||
if (success && isClearSwpFile)
|
||||
{
|
||||
QFile::remove(swapFilePath);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
return true;
|
||||
|
@ -6117,6 +6216,8 @@ void CCNotePad::closeFileStatic(int index, QSettings& qs)
|
|||
removeWatchFilePath(filePath);
|
||||
pw->deleteLater();
|
||||
}
|
||||
|
||||
|
||||
void CCNotePad::closeAllFileStatic()
|
||||
{
|
||||
QString tempFileList = QString("notepad/temp/list");
|
||||
|
@ -6279,8 +6380,12 @@ void CCNotePad::closeEvent(QCloseEvent * event)
|
|||
}
|
||||
}
|
||||
|
||||
//保存上次打开目录
|
||||
if (!CCNotePad::s_lastOpenDirPath.isEmpty())
|
||||
{
|
||||
NddSetting::updataKeyValueFromDelaySets(LAST_OPEN_DIR, CCNotePad::s_lastOpenDirPath);
|
||||
}
|
||||
//保存大小
|
||||
|
||||
QByteArray curGeo = saveGeometry();
|
||||
NddSetting::updataKeyByteArrayValue(WIN_POS, curGeo);
|
||||
|
||||
|
@ -6652,7 +6757,11 @@ void CCNotePad::tailfile(bool isOn, ScintillaEditView* pEdit)
|
|||
//这里不能直接更新,而是要发生信号出去。否则跨线程访问,可能发生错误或告警
|
||||
//pEdit->setProperty(Modify_Outside, QVariant(true));
|
||||
//checkRoladFile(pEdit);
|
||||
emit this->tailFileChange(pEdit);
|
||||
quint64 lastSize = 0;
|
||||
quint64 curSize = 0;
|
||||
|
||||
fileChanges.getDiffFileSize(lastSize,curSize);
|
||||
emit this->tailFileChange(pEdit, lastSize, curSize);
|
||||
}
|
||||
//如果退出监控。这里要注意,一定要是volidate的,否则多线程获取不到该变化
|
||||
//使用了原子变量,效果是一样的,多个线程均可见
|
||||
|
@ -6811,15 +6920,21 @@ int CCNotePad::initFindWindow(FindTabIndex type)
|
|||
QVariant history = qs.value("keys", "");
|
||||
s_findHistroy = history.toStringList();
|
||||
}
|
||||
if (qs.contains("replace"))
|
||||
{
|
||||
QVariant replaceHistory = qs.value("replace", "");
|
||||
s_replaceHistroy = replaceHistory.toStringList();
|
||||
}
|
||||
}
|
||||
|
||||
pFind->setFindHistory(&s_findHistroy);
|
||||
|
||||
pFind->setReplaceHistory(&s_replaceHistroy);
|
||||
|
||||
pFind->setTabWidget(ui.editTabWidget);
|
||||
|
||||
if((TXT_TYPE == docType) || (BIG_TEXT_RO_TYPE == docType) || (SUPER_BIG_TEXT_RO_TYPE == docType))
|
||||
{
|
||||
connect(pFind, &FindWin::sign_findAllInCurDoc, this, &CCNotePad::slot_showFindAllInCurDocResult);
|
||||
//connect(pFind, &FindWin::sign_findAllInCurDoc, this, &CCNotePad::slot_showFindAllInCurDocResult);
|
||||
connect(pFind, &FindWin::sign_findAllInOpenDoc, this, &CCNotePad::slot_showfindAllInOpenDocResult);
|
||||
connect(pFind, &FindWin::sign_replaceSaveFile, this, &CCNotePad::slot_saveFile);
|
||||
connect(pFind, &FindWin::sign_clearResult, this, &CCNotePad::slot_clearFindResult);
|
||||
|
@ -6923,6 +7038,13 @@ void CCNotePad::slot_saveSearchHistory()
|
|||
s_findHistroy = s_findHistroy.mid(0, 15);
|
||||
}
|
||||
qs.setValue("keys", s_findHistroy);
|
||||
|
||||
if (s_replaceHistroy.count() > 15)
|
||||
{
|
||||
s_replaceHistroy = s_replaceHistroy.mid(0, 15);
|
||||
}
|
||||
qs.setValue("replace", s_replaceHistroy);
|
||||
|
||||
qs.sync();
|
||||
}
|
||||
|
||||
|
@ -7014,8 +7136,8 @@ void CCNotePad::clearHighlightWord(QString signWord, ScintillaEditView* pEdit)
|
|||
delete r;
|
||||
curMarkRecord.removeAt(i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CCNotePad::slot_clearWordHighlight()
|
||||
{
|
||||
QWidget* pw = ui.editTabWidget->currentWidget();
|
||||
|
@ -7155,7 +7277,9 @@ void CCNotePad::initFindResultDockWin()
|
|||
m_dockSelectTreeWin->setAllowedAreas(Qt::LeftDockWidgetArea| Qt::RightDockWidgetArea |Qt::BottomDockWidgetArea);
|
||||
|
||||
m_pResultWin = new FindResultWin(m_dockSelectTreeWin);
|
||||
connect(m_pResultWin, &FindResultWin::itemDoubleClicked, this, &CCNotePad::slot_findResultItemDoubleClick);
|
||||
//connect(m_pResultWin, &FindResultWin::itemDoubleClicked, this, &CCNotePad::slot_findResultItemDoubleClick);
|
||||
connect(m_pResultWin, &FindResultWin::lineDoubleClicked, this, &CCNotePad::on_findResultlineDoubleClick);
|
||||
|
||||
connect(m_pResultWin, &FindResultWin::showMsg, this, [this](QString& msg) {
|
||||
ui.statusBar->showMessage(msg,5000);
|
||||
});
|
||||
|
@ -7269,16 +7393,62 @@ void CCNotePad::slot_findResultItemDoubleClick(const QModelIndex &index)
|
|||
|
||||
}
|
||||
|
||||
//双击文件leve=2的节点后,显示文件并定位到文件位置中去高亮
|
||||
void CCNotePad::on_findResultlineDoubleClick(QString* pFilePath, int pos, int end)
|
||||
{
|
||||
auto locationCurrentEdit = [this](QString filePath)->ScintillaEditView* {
|
||||
|
||||
getRegularFilePath(filePath);
|
||||
|
||||
ScintillaEditView* pEdit = dynamic_cast<ScintillaEditView*>(ui.editTabWidget->currentWidget());
|
||||
if (pEdit != nullptr && (filePath == getFilePathProperty(pEdit)))
|
||||
{
|
||||
return pEdit;
|
||||
}
|
||||
|
||||
//不在则遍历插值定位到
|
||||
for (int i = 0; i < ui.editTabWidget->count(); ++i)
|
||||
{
|
||||
pEdit = dynamic_cast<ScintillaEditView*>(ui.editTabWidget->widget(i));
|
||||
if (pEdit != nullptr && (filePath == getFilePathProperty(pEdit)))
|
||||
{
|
||||
ui.editTabWidget->setCurrentIndex(i);
|
||||
return pEdit;
|
||||
}
|
||||
}
|
||||
|
||||
//走到这里,说明文档已经关闭,不在当前打开框中
|
||||
//还是没有找到,则新建打开文件
|
||||
if (openFile(filePath))
|
||||
{
|
||||
ScintillaEditView* pEdit = dynamic_cast<ScintillaEditView*>(ui.editTabWidget->currentWidget());
|
||||
return pEdit;
|
||||
}
|
||||
|
||||
ui.statusBar->showMessage(tr("file %1 was not exists !").arg(filePath), 5000);
|
||||
QApplication::beep();
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
ScintillaEditView* pCurEdit = locationCurrentEdit(*pFilePath);
|
||||
if (pCurEdit != nullptr)
|
||||
{
|
||||
pCurEdit->execute(SCI_SETSEL, pos, end);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
void CCNotePad::slot_showFindAllInCurDocResult(FindRecords* record)
|
||||
{
|
||||
initFindResultDockWin();
|
||||
|
||||
m_dockSelectTreeWin->setWindowTitle(tr("Find result - %1 hit").arg(record->records.size()));
|
||||
|
||||
m_pResultWin->appendResultsToShow(record);
|
||||
//m_pResultWin->appendResultsToShow(record);
|
||||
|
||||
m_dockSelectTreeWin->show();
|
||||
}
|
||||
#endif
|
||||
|
||||
void CCNotePad::slot_showfindAllInOpenDocResult(QVector<FindRecords*>* record, int hits, QString whatFind)
|
||||
{
|
||||
|
@ -7546,11 +7716,11 @@ void CCNotePad::transDocToEncord(CODE_ID destCode)
|
|||
//等到文件保存时才执行
|
||||
if (srcCode != newCode)
|
||||
{
|
||||
QVariant editTextCode((int)newCode);
|
||||
pEdit->setProperty(Edit_Text_Code, editTextCode);
|
||||
setCodeTypeProperty(pEdit, (int)newCode);
|
||||
|
||||
QVariant textChanged(true);
|
||||
pEdit->setProperty(Edit_Text_Change, textChanged);
|
||||
setTextChangeProperty(pEdit, true);
|
||||
|
||||
ui.editTabWidget->setTabIcon(ui.editTabWidget->currentIndex(), QIcon(TabNeedSave));
|
||||
|
||||
setSaveButtonStatus(true);
|
||||
setSaveAllButtonStatus(true);
|
||||
|
@ -7945,15 +8115,15 @@ void CCNotePad::slot_aboutNdd()
|
|||
QString title = tr("Notepad-- Version %1").arg(VersionStr);
|
||||
pWin->setWindowTitle(title);
|
||||
pWin->appendText(title);
|
||||
// int status = NddSetting::getKeyValueFromNumSets(SOFT_STATUS);
|
||||
// if (1 == status)
|
||||
// {
|
||||
// pWin->appendText(tr("Registered Version"));
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// pWin->appendText(tr("Free Trial"));
|
||||
// }
|
||||
int status = NddSetting::getKeyValueFromNumSets(SOFT_STATUS);
|
||||
if (1 == status)
|
||||
{
|
||||
pWin->appendText(tr("Registered Version"));
|
||||
}
|
||||
else
|
||||
{
|
||||
pWin->appendText(tr("Free Trial"));
|
||||
}
|
||||
pWin->show();
|
||||
registerEscKeyShort(pWin);
|
||||
#ifdef uos
|
||||
|
@ -8024,6 +8194,11 @@ void CCNotePad::dropEvent(QDropEvent* e)
|
|||
e->accept();
|
||||
}
|
||||
|
||||
void CCNotePad::dragLeaveEvent(QDragLeaveEvent* event)
|
||||
{
|
||||
qDebug() << "drag level";
|
||||
}
|
||||
|
||||
//目前只有一个Tabwidget的双击事件。
|
||||
bool CCNotePad::eventFilter(QObject * watched, QEvent * event)
|
||||
{
|
||||
|
@ -8519,7 +8694,7 @@ bool CCNotePad::restoreDirtyExistFile(QString& filePath, QString& tempFilePath)
|
|||
if (!tempFilePath.isEmpty())
|
||||
{
|
||||
int ret = FileManager::getInstance().loadFileDataInText(pEdit, tempFilePath, code, lineEnd, nullptr, false,this);
|
||||
if (ret != 0)
|
||||
if ((ret != 6) && (ret != 0))
|
||||
{
|
||||
isLoadOrgin = true;
|
||||
ui.statusBar->showMessage(tr("Restore Last Temp File %1 Failed").arg(tempFilePath), 5000);
|
||||
|
@ -8549,10 +8724,14 @@ bool CCNotePad::restoreDirtyExistFile(QString& filePath, QString& tempFilePath)
|
|||
//用户同意以二进制格式打开文件
|
||||
return openHexFile(filePath);
|
||||
}
|
||||
else if (5 == ret)
|
||||
//else if (5 == ret)
|
||||
//{
|
||||
// isReadOnly = true;
|
||||
// //只读模式
|
||||
//}
|
||||
else if (6 == ret)
|
||||
{
|
||||
isReadOnly = true;
|
||||
//只读模式
|
||||
//存在乱码,还是打开
|
||||
}
|
||||
else if (0 != ret)
|
||||
{
|
||||
|
@ -9646,6 +9825,46 @@ void CCNotePad::on_quitActiveWindow()
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
//修改主题颜色//暂时不开始,发现MAC下有不开启深色的配置
|
||||
void CCNotePad::changeAppFontColor(QColor color)
|
||||
{
|
||||
//把存在的界面都关闭。发现如果不关闭,颜色不会更新
|
||||
|
||||
if (!m_pFindWin.isNull())
|
||||
{
|
||||
QByteArray curGeo = m_pFindWin->saveGeometry();
|
||||
NddSetting::updataKeyByteArrayValue(FINDWINSIZE, curGeo);
|
||||
|
||||
m_pFindWin.data()->deleteLater();
|
||||
}
|
||||
|
||||
if (!m_pHexGotoWin.isNull())
|
||||
{
|
||||
m_pHexGotoWin.data()->close();
|
||||
}
|
||||
|
||||
if (!m_columnEditWin.isNull())
|
||||
{
|
||||
m_columnEditWin.data()->close();
|
||||
}
|
||||
|
||||
|
||||
//filelistwin还存在
|
||||
if (!m_dockFileListWin.isNull())
|
||||
{
|
||||
NddSetting::updataKeyValueFromNumSets(FILELISTSHOW, 1);
|
||||
m_dockFileListWin.data()->close();
|
||||
}
|
||||
|
||||
if (m_dockSelectTreeWin != nullptr)
|
||||
{
|
||||
m_dockSelectTreeWin->deleteLater();
|
||||
m_dockSelectTreeWin = nullptr;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void CCNotePad::on_md5hash()
|
||||
{
|
||||
Md5hash* pWin = new Md5hash(this);
|
||||
|
@ -9653,3 +9872,70 @@ void CCNotePad::on_md5hash()
|
|||
pWin->setAttribute(Qt::WA_DeleteOnClose);
|
||||
pWin->show();
|
||||
}
|
||||
|
||||
|
||||
#ifdef NO_PLUGIN
|
||||
//插件中调用主程序的功能。
|
||||
//cmdId 执行什么动作,一定固定后,主程序不能随便修改,否则会引发兼容性问题。
|
||||
bool CCNotePad::pluginInvoke(int cmdId, void* data)
|
||||
{
|
||||
bool ret = false;
|
||||
switch (cmdId)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
//新建一个文件。
|
||||
slot_actionNewFile_toggle(true);
|
||||
|
||||
//默认不需要。
|
||||
if (data != nullptr)
|
||||
{
|
||||
QVariant* pVar = (QVariant*)data;
|
||||
//回传回去新建文件的名称
|
||||
ScintillaEditView* pw = getCurEditView();
|
||||
if (pw != nullptr)
|
||||
{
|
||||
pVar->setValue(getFilePathProperty(pw));
|
||||
}
|
||||
|
||||
}
|
||||
ret = true;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
//设定当前编辑器的语言。0 js 1 json
|
||||
int lang = *((int*)data);
|
||||
|
||||
LangType langs = ((lang == 0) ? L_JAVASCRIPT : L_JSON);
|
||||
|
||||
ScintillaEditView* pEdit = getCurEditView();
|
||||
if (pEdit != nullptr)
|
||||
{
|
||||
QsciLexer* curLexer = pEdit->lexer();
|
||||
if (curLexer == nullptr)
|
||||
{
|
||||
//设定为目标语法
|
||||
QsciLexer* lexer = ScintillaEditView::createLexer(langs);
|
||||
pEdit->setLexer(lexer);
|
||||
}
|
||||
else if (curLexer->lexerId() != langs)
|
||||
{
|
||||
pEdit->setLexer(nullptr);
|
||||
delete curLexer;
|
||||
curLexer = nullptr;
|
||||
|
||||
QsciLexer* lexer = ScintillaEditView::createLexer(langs);
|
||||
pEdit->setLexer(lexer);
|
||||
}
|
||||
syncCurDocLexerToMenu(pEdit);
|
||||
}
|
||||
ret = true;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
|
@ -23,6 +23,7 @@
|
|||
#include "findwin.h"
|
||||
#include "pluginGl.h"
|
||||
|
||||
|
||||
//class ScintillaEditView;
|
||||
class ScintillaHexEditView;
|
||||
class FindRecords;
|
||||
|
@ -33,7 +34,6 @@ class CompareWin;
|
|||
struct HexFileMgr;
|
||||
struct TextFileMgr;
|
||||
struct BigTextEditFileMgr;
|
||||
class QtLangSet;
|
||||
|
||||
static const char* Tail_Thread = "tailthread";
|
||||
|
||||
|
@ -87,6 +87,7 @@ enum NddDocType {
|
|||
//打开模式。1 文本 2 二进制 3 大文本只读 4 文本只读
|
||||
//const char* Open_Attr = "openid";
|
||||
class FileListView;
|
||||
class QtLangSet;
|
||||
|
||||
class CCNotePad : public QMainWindow
|
||||
{
|
||||
|
@ -154,7 +155,7 @@ signals:
|
|||
void signRegisterReplay(int code);
|
||||
void signLinkNetServer();
|
||||
#ifdef Q_OS_WIN
|
||||
void tailFileChange(ScintillaEditView*);
|
||||
void tailFileChange(ScintillaEditView*,qint64 lastSize, qint64 curSize);
|
||||
#endif
|
||||
public slots:
|
||||
void slot_changeChinese();
|
||||
|
@ -197,6 +198,7 @@ protected:
|
|||
void closeEvent(QCloseEvent *event) override;
|
||||
void dragEnterEvent(QDragEnterEvent* event) override;
|
||||
void dropEvent(QDropEvent* e) override;
|
||||
void dragLeaveEvent(QDragLeaveEvent* event);
|
||||
bool eventFilter(QObject *watched, QEvent *event)override;
|
||||
#ifdef Q_OS_WIN
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
|
||||
|
@ -239,7 +241,9 @@ private slots:
|
|||
|
||||
void slot_findResultPosChangeed(Qt::DockWidgetArea area);
|
||||
void slot_findResultItemDoubleClick(const QModelIndex & index);
|
||||
#if 0
|
||||
void slot_showFindAllInCurDocResult(FindRecords * record);
|
||||
#endif
|
||||
void slot_showfindAllInOpenDocResult(QVector<FindRecords*>* record, int hits, QString whatFind);
|
||||
void slot_clearFindResult();
|
||||
void slot_convertWinLineEnd(bool);
|
||||
|
@ -351,6 +355,8 @@ private slots:
|
|||
#ifdef NO_PLUGIN
|
||||
void onPlugWork(bool check);
|
||||
void sendParaToPlugin(NDD_PROC_DATA& procData);
|
||||
//cmdId 执行什么动作,一定固定后,主程序不能随便修改,否则会引发兼容性问题。
|
||||
bool pluginInvoke(int cmdId, void* data);
|
||||
#endif
|
||||
void slot_showWebAddr(bool check);
|
||||
void slot_langFileSuffix();
|
||||
|
@ -358,7 +364,7 @@ private slots:
|
|||
void on_lineEndChange(int index);
|
||||
void on_tailfile(bool isOn);
|
||||
#ifdef Q_OS_WIN
|
||||
void on_roladFile(ScintillaEditView* pEdit);
|
||||
void on_roladFile(ScintillaEditView* pEdit,quint64 lastSize, qint64 curSize);
|
||||
#endif
|
||||
void on_md5hash();
|
||||
|
||||
|
@ -400,11 +406,15 @@ private:
|
|||
void addWatchFilePath(QString filePath);
|
||||
void removeWatchFilePath(QString filePath);
|
||||
|
||||
bool checkRoladFile(ScintillaEditView * pEdit);
|
||||
void reloadEditFile(ScintillaEditView * pEidt, bool isTailfOn = false);
|
||||
void doReloadTxtFile(ScintillaEditView* pEdit, bool isOnTail, qint64 startReadSize);
|
||||
void firstTimeIntoTail(ScintillaEditView* pEdit, int remainLineNums=100);
|
||||
bool checkRoladFile(ScintillaEditView * pEdit, qint64 startReadSize=-1);
|
||||
void reloadEditFile(ScintillaEditView * pEidt, bool isTailfOn = false, qint64 startReadSize=-1);
|
||||
int initFindWindow(FindTabIndex type= FIND_TAB);
|
||||
|
||||
void setToFileRightMenu();
|
||||
void initReceneCmp();
|
||||
void saveReceneCmp();
|
||||
|
||||
QString getShortName(const QString& name);
|
||||
|
||||
|
@ -475,6 +485,7 @@ private:
|
|||
void doFold(int type, bool mode);
|
||||
void doComment(int type);
|
||||
void tailfile(bool isOn, ScintillaEditView* pEdit);
|
||||
void on_findResultlineDoubleClick(QString* pFilePath, int pos, int end);
|
||||
private:
|
||||
Ui::CCNotePad ui;
|
||||
|
||||
|
@ -525,6 +536,10 @@ private:
|
|||
|
||||
QSharedMemory* m_shareMem;
|
||||
|
||||
|
||||
|
||||
QList<CompareDirs*> m_cmpDirMgr;
|
||||
QList<CompareWin*> m_cmpFileMgr;
|
||||
|
||||
//最近打开的对比文件和目录列表。做一个环形区
|
||||
//保存在数据库中
|
||||
|
@ -555,6 +570,7 @@ private:
|
|||
QPointer<QWidget> m_pHexGotoWin;
|
||||
|
||||
static QStringList s_findHistroy;
|
||||
static QStringList s_replaceHistroy;
|
||||
static int s_padTimes;
|
||||
|
||||
int m_curSoftLangs; //当前语言0:自动 1 中文 2 英语
|
||||
|
@ -619,6 +635,7 @@ private:
|
|||
QList<NDD_PROC_DATA> m_pluginList;
|
||||
|
||||
public:
|
||||
|
||||
static QString s_lastOpenDirPath;
|
||||
static int s_restoreLastFile; //自动恢复上次打开的文件
|
||||
static int s_curStyleId;
|
||||
|
|
|
@ -1627,6 +1627,9 @@
|
|||
<property name="text">
|
||||
<string>Column Block Editing</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Alt+X</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionWrap">
|
||||
<property name="checkable">
|
||||
|
|
|
@ -9,7 +9,9 @@
|
|||
#include <QFile>
|
||||
#include <QtGlobal>
|
||||
#include <qscilexer.h>
|
||||
#include <QFileInfo>
|
||||
|
||||
LangType detectLanguage(QString& headContent, QString& filepath);
|
||||
|
||||
FileManager::FileManager():m_lastErrorCode(NONE_ERROR)
|
||||
{
|
||||
|
@ -218,6 +220,68 @@ void FileManager::delNewFileNode(int fileIndex)
|
|||
}
|
||||
}
|
||||
|
||||
//和loadFileDataInText类似,但是不是从头开始读取文件,而是从startReadSize开始
|
||||
//不检查编码,直接按照fileTextCode进行读取
|
||||
int FileManager::loadFileDataInTextFromOffset(ScintillaEditView* editView, QString filePath, CODE_ID fileTextCode, QWidget* msgBoxParent, quint64 startReadSize)
|
||||
{
|
||||
QFile file(filePath);
|
||||
|
||||
//如果文件不存在,直接返回
|
||||
if (!file.exists())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
QFlags<QFileDevice::Permission> power = QFile::permissions(filePath);
|
||||
|
||||
//直接以只读的方式打开,至于能不能保存,是保存时需要考虑的问题。
|
||||
//只需要在保存的时候获取admin权限即可
|
||||
QIODevice::OpenMode mode;
|
||||
|
||||
mode = QIODevice::ExistingOnly | QIODevice::ReadOnly;
|
||||
|
||||
if (!file.open(mode))
|
||||
{
|
||||
QMessageBox::warning(msgBoxParent, tr("Error"), tr("Open File %1 failed").arg(filePath));
|
||||
return 2;
|
||||
}
|
||||
|
||||
quint64 fileSize = file.size();
|
||||
|
||||
//如果文件是空的。检查一下,有可能在临时文件损坏情况下出现,外面需要使用
|
||||
if (fileSize == 0)
|
||||
{
|
||||
file.close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//如果读取的内容,超过了当前文件大小,则直接返回。这里是返回0,视作成功,没有新内容要读
|
||||
if (startReadSize >= fileSize)
|
||||
{
|
||||
file.close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
QByteArray bytes;
|
||||
|
||||
if (file.seek(startReadSize))
|
||||
{
|
||||
//读取后面所有的内容
|
||||
bytes = file.readAll();
|
||||
}
|
||||
|
||||
file.close();
|
||||
|
||||
QString text;
|
||||
|
||||
Encode::tranStrToUNICODE(fileTextCode, bytes.data(), bytes.count(), text);
|
||||
|
||||
editView->append(text);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
//这里是以文本方式加载文件。但是可能遇到的是二进制文件,里面会做判断
|
||||
//二进制时hexAsk是否询问,当用户指定打开格式时,不需要询问
|
||||
|
@ -406,6 +470,172 @@ int FileManager::loadFileDataInText(ScintillaEditView* editView, QString filePat
|
|||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//20230304新增加:不再一行一行读取文件,而是一次性读取到内存,加快文本文件打开时的处理速度
|
||||
//这里是以文本方式加载文件。但是可能遇到的是二进制文件,里面会做判断
|
||||
//二进制时hexAsk是否询问,当用户指定打开格式时,不需要询问
|
||||
//MsgBoxParent::尽量把这个给一下,让MsgBox有图标,不那么难看。
|
||||
int FileManager::loadFileDataInText(ScintillaEditView* editView, QString filePath, CODE_ID& fileTextCode, RC_LINE_FORM& lineEnd, CCNotePad* callbackObj, bool hexAsk, QWidget* msgBoxParent)
|
||||
{
|
||||
QFile file(filePath);
|
||||
|
||||
//如果文件不存在,直接返回
|
||||
if (!file.exists())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
QFlags<QFileDevice::Permission> power = QFile::permissions(filePath);
|
||||
|
||||
//直接以只读的方式打开,至于能不能保存,是保存时需要考虑的问题。
|
||||
//只需要在保存的时候获取admin权限即可
|
||||
QIODevice::OpenMode mode;
|
||||
|
||||
mode = QIODevice::ExistingOnly | QIODevice::ReadOnly;
|
||||
|
||||
if (!file.open(mode))
|
||||
{
|
||||
qDebug() << file.error();
|
||||
#ifdef Q_OS_WIN
|
||||
//打开失败,这里一般是权限问题导致。如果是windows,在外面申请权限后继续处理
|
||||
if (QFileDevice::OpenError == file.error())
|
||||
{
|
||||
if (callbackObj != nullptr)
|
||||
{
|
||||
return callbackObj->runAsAdmin(filePath);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
#ifdef Q_OS_UNIX
|
||||
QMessageBox::warning(msgBoxParent, tr("Error"), tr("Open File %1 failed").arg(filePath));
|
||||
#endif
|
||||
return 2;
|
||||
}
|
||||
|
||||
qint64 fileSize = file.size();
|
||||
|
||||
//如果文件是空的。检查一下,有可能在临时文件损坏情况下出现,外面需要使用
|
||||
if (fileSize == 0)
|
||||
{
|
||||
m_lastErrorCode = ERROR_TYPE::OPEN_EMPTY_FILE;
|
||||
file.close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
qint64 bufferSizeRequested = fileSize + qMin((qint64)(1 << 20), (qint64)(fileSize / 6));
|
||||
|
||||
if (bufferSizeRequested > INT_MAX)
|
||||
{
|
||||
QMessageBox::warning(msgBoxParent, tr("Error"), tr("File is too big to be opened by Notepad--"));
|
||||
file.close();
|
||||
return 3;
|
||||
}
|
||||
|
||||
QString fileText;
|
||||
bool isErrorCode = false;
|
||||
|
||||
fileTextCode = CmpareMode::scanFileOutPut(file, fileTextCode, filePath, fileText, isErrorCode);
|
||||
|
||||
//如果文件是空的。检查一下,有可能在临时文件损坏情况下出现,外面需要使用
|
||||
if (fileText.size() == 0)
|
||||
{
|
||||
m_lastErrorCode = ERROR_TYPE::OPEN_EMPTY_FILE;
|
||||
file.close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (isErrorCode && hexAsk)
|
||||
{
|
||||
//检测到文件很可能是二进制文件,询问用户,是否以二进制加载
|
||||
int ret = QMessageBox::question(msgBoxParent, tr("Open with Text or Hex? [Exist Garbled Code]"), tr("The file %1 is likely to be binary. Do you want to open it in binary?").arg(filePath), tr("Hex Open"), tr("Text Open"), tr("Cancel"));
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
//16进制打开
|
||||
file.close();
|
||||
return 4;
|
||||
}
|
||||
else if (ret == 1)
|
||||
{
|
||||
//继续以文本打开
|
||||
}
|
||||
else
|
||||
{
|
||||
//取消,不打开
|
||||
file.close();
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
//以第一行的换行为文本的换行符。暂时只考虑win unix 。mac \r 已经淘汰,暂时不管
|
||||
lineEnd = RC_LINE_FORM::UNKNOWN_LINE;
|
||||
|
||||
int pos = fileText.indexOf("\n");
|
||||
if (pos >=1)
|
||||
{
|
||||
if (fileText[pos - 1] == QChar('\r'))
|
||||
{
|
||||
lineEnd = RC_LINE_FORM::DOS_LINE;
|
||||
}
|
||||
else
|
||||
{
|
||||
lineEnd = RC_LINE_FORM::UNIX_LINE;
|
||||
}
|
||||
}
|
||||
|
||||
if (lineEnd == UNKNOWN_LINE)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
lineEnd = DOS_LINE;
|
||||
#else
|
||||
lineEnd = UNIX_LINE;
|
||||
#endif
|
||||
}
|
||||
|
||||
file.close();
|
||||
|
||||
|
||||
//优先根据文件后缀来确定其语法风格
|
||||
LexerInfo lxdata = CCNotePad::getLangLexerIdByFileExt(filePath);
|
||||
|
||||
if (lxdata.lexerId != L_TXT)
|
||||
{
|
||||
QsciLexer* lexer = editView->createLexer(lxdata.lexerId, lxdata.tagName);
|
||||
editView->setLexer(lexer);
|
||||
}
|
||||
else
|
||||
{
|
||||
//利用前面100个字符,进行一个编程语言的判断
|
||||
QString headContens = fileText.mid(0, 100);
|
||||
|
||||
LangType _language = detectLanguage(headContens, filePath);
|
||||
|
||||
if (_language >= 0 && _language < L_EXTERNAL)
|
||||
{
|
||||
QsciLexer* lexer = editView->createLexer(_language);
|
||||
editView->setLexer(lexer);
|
||||
}
|
||||
}
|
||||
|
||||
//如果检测到时16进制文件,但是强行以二进制打开,则有限走setUtf8Text。
|
||||
if (!isErrorCode)
|
||||
{
|
||||
editView->setText(fileText);
|
||||
}
|
||||
else
|
||||
{
|
||||
//20230203有github用户反馈,说存在乱码的文件被截断,所以后续还是不走截断
|
||||
editView->setText(fileText);
|
||||
|
||||
return 6;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//加载文件,只为查找使用
|
||||
int FileManager::loadFileForSearch(ScintillaEditView* editView, QString filePath)
|
||||
{
|
||||
|
@ -413,15 +643,9 @@ int FileManager::loadFileForSearch(ScintillaEditView* editView, QString filePath
|
|||
|
||||
QFlags<QFileDevice::Permission> power = QFile::permissions(filePath);
|
||||
|
||||
if (!power.testFlag(QFile::ReadOwner))
|
||||
{
|
||||
//文件不能读
|
||||
return 1;
|
||||
}
|
||||
|
||||
QIODevice::OpenMode mode;
|
||||
|
||||
if (!power.testFlag(QFile::WriteOwner))
|
||||
if (!power.testFlag(QFile::WriteUser))
|
||||
{
|
||||
//文件不能写
|
||||
mode = QIODevice::ExistingOnly | QIODevice::ReadOnly;
|
||||
|
@ -433,7 +657,7 @@ int FileManager::loadFileForSearch(ScintillaEditView* editView, QString filePath
|
|||
|
||||
if (!file.open(mode))
|
||||
{
|
||||
qDebug() << file.error();
|
||||
//qDebug() << file.error();
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
@ -441,49 +665,30 @@ int FileManager::loadFileForSearch(ScintillaEditView* editView, QString filePath
|
|||
|
||||
qint64 bufferSizeRequested = fileSize + qMin((qint64)(1 << 20), (qint64)(fileSize / 6));
|
||||
|
||||
// As a 32bit application, we cannot allocate 2 buffer of more than INT_MAX size (it takes the whole address space)
|
||||
if (bufferSizeRequested > INT_MAX)
|
||||
{
|
||||
file.close();
|
||||
return 3;
|
||||
}
|
||||
|
||||
QList<LineFileInfo> outputLineInfoVec;
|
||||
|
||||
int maxLineSize = 0;
|
||||
int charsNums = 0;
|
||||
bool isHexFile = false;
|
||||
|
||||
bool existGrbledCode = false;
|
||||
QString outText;
|
||||
CODE_ID fileTextCode = CODE_ID::UNKOWN;
|
||||
|
||||
fileTextCode = CmpareMode::scanFileOutPut(fileTextCode, filePath, outputLineInfoVec, maxLineSize, charsNums, isHexFile);
|
||||
fileTextCode = CmpareMode::scanFileOutPut(file, fileTextCode, filePath, outText, existGrbledCode);
|
||||
|
||||
//20230218 这里必须指明一下编码,否则后续会导致编码被修改
|
||||
editView->setProperty(Edit_Text_Code, fileTextCode);
|
||||
|
||||
if (isHexFile)
|
||||
if (existGrbledCode)
|
||||
{
|
||||
qDebug() << filePath;
|
||||
//qDebug() << filePath;
|
||||
file.close();
|
||||
return 4;
|
||||
}
|
||||
|
||||
if (maxLineSize > 0)
|
||||
{
|
||||
editView->execute(SCI_SETSCROLLWIDTH, maxLineSize * 10);
|
||||
}
|
||||
|
||||
QString text;
|
||||
text.reserve(charsNums + 1);
|
||||
|
||||
for (QList<LineFileInfo>::iterator it = outputLineInfoVec.begin(); it != outputLineInfoVec.end(); ++it)
|
||||
{
|
||||
text.append(it->unicodeStr);
|
||||
}
|
||||
|
||||
file.close();
|
||||
|
||||
editView->setText(text);
|
||||
editView->setText(outText);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1223,95 +1428,52 @@ void FileManager::closeBigTextRoFileHand(QString filepath)
|
|||
}
|
||||
}
|
||||
|
||||
//检查文件的编程语言
|
||||
LangType FileManager::detectLanguageFromTextBegining(const unsigned char *data, size_t dataLen)
|
||||
//初步检查文件的编程语言。两个标准: 1 文件头部标签 2 文件特定名称
|
||||
LangType detectLanguage(QString& headContent, QString& filepath)
|
||||
{
|
||||
struct FirstLineLanguages
|
||||
{
|
||||
std::string pattern;
|
||||
QString pattern;
|
||||
LangType lang;
|
||||
};
|
||||
|
||||
// Is the buffer at least the size of a BOM?
|
||||
if (dataLen <= 3)
|
||||
return L_TXT;
|
||||
|
||||
// Eliminate BOM if present
|
||||
size_t i = 0;
|
||||
if ((data[0] == 0xEF && data[1] == 0xBB && data[2] == 0xBF) || // UTF8 BOM
|
||||
(data[0] == 0xFE && data[1] == 0xFF && data[2] == 0x00) || // UTF16 BE BOM
|
||||
(data[0] == 0xFF && data[1] == 0xFE && data[2] == 0x00)) // UTF16 LE BOM
|
||||
i += 3;
|
||||
|
||||
// Skip any space-like char
|
||||
for (; i < dataLen; ++i)
|
||||
{
|
||||
if (data[i] != ' ' && data[i] != '\t' && data[i] != '\n' && data[i] != '\r')
|
||||
break;
|
||||
}
|
||||
|
||||
// Create the buffer to need to test
|
||||
const size_t longestLength = 40; // shebangs can be large
|
||||
std::string buf2Test = std::string((const char *)data + i, longestLength);
|
||||
|
||||
// Is there a \r or \n in the buffer? If so, truncate it
|
||||
auto cr = buf2Test.find("\r");
|
||||
auto nl = buf2Test.find("\n");
|
||||
auto crnl = qMin(cr, nl);
|
||||
if (crnl != std::string::npos && crnl < longestLength)
|
||||
buf2Test = std::string((const char *)data + i, crnl);
|
||||
|
||||
// First test for a Unix-like Shebang
|
||||
// See https://en.wikipedia.org/wiki/Shebang_%28Unix%29 for more details about Shebang
|
||||
std::string shebang = "#!";
|
||||
|
||||
size_t foundPos = buf2Test.find(shebang);
|
||||
if (foundPos == 0)
|
||||
{
|
||||
// Make a list of the most commonly used languages
|
||||
const size_t NB_SHEBANG_LANGUAGES = 7;
|
||||
FirstLineLanguages ShebangLangs[NB_SHEBANG_LANGUAGES] = {
|
||||
{ "sh", L_BASH },
|
||||
{ "python", L_PYTHON },
|
||||
{ "perl", L_PERL },
|
||||
{ "php", L_PHP },
|
||||
{ "ruby", L_RUBY },
|
||||
{ "node", L_JAVASCRIPT },
|
||||
{ "Makefile", L_MAKEFILE}
|
||||
};
|
||||
|
||||
// Go through the list of languages
|
||||
for (i = 0; i < NB_SHEBANG_LANGUAGES; ++i)
|
||||
{
|
||||
if (buf2Test.find(ShebangLangs[i].pattern) != std::string::npos)
|
||||
{
|
||||
return ShebangLangs[i].lang;
|
||||
}
|
||||
}
|
||||
|
||||
// Unrecognized shebang (there is always room for improvement ;-)
|
||||
return L_TXT;
|
||||
}
|
||||
|
||||
// Are there any other patterns we know off?
|
||||
const size_t NB_FIRST_LINE_LANGUAGES = 5;
|
||||
FirstLineLanguages languages[NB_FIRST_LINE_LANGUAGES] = {
|
||||
const size_t FIRST_LINE_LANGUAGES = 5;
|
||||
FirstLineLanguages languages[FIRST_LINE_LANGUAGES] = {
|
||||
{ "<?xml", L_XML },
|
||||
{ "<?php", L_PHP },
|
||||
{ "<html", L_HTML },
|
||||
{ "<!DOCTYPE html", L_HTML },
|
||||
{ "<?", L_PHP } // MUST be after "<?php" and "<?xml" to get the result as accurate as possible
|
||||
{ "<?", L_PHP }
|
||||
};
|
||||
|
||||
for (i = 0; i < NB_FIRST_LINE_LANGUAGES; ++i)
|
||||
int foundPos = -1;
|
||||
for (int i = 0; i < FIRST_LINE_LANGUAGES; ++i)
|
||||
{
|
||||
foundPos = buf2Test.find(languages[i].pattern);
|
||||
foundPos = headContent.indexOf(languages[i].pattern);
|
||||
if (foundPos == 0)
|
||||
{
|
||||
return languages[i].lang;
|
||||
}
|
||||
}
|
||||
|
||||
const size_t NAME_CHECK_LANGUAGES = 3;
|
||||
FirstLineLanguages NAME_LEXER[NAME_CHECK_LANGUAGES] = {
|
||||
{ "make", L_MAKEFILE },
|
||||
{ "makefile", L_MAKEFILE },
|
||||
{ "CMakeLists", L_MAKEFILE },
|
||||
};
|
||||
|
||||
QFileInfo fi(filepath);
|
||||
QString baseName = fi.baseName();
|
||||
|
||||
for (int i = 0; i < NAME_CHECK_LANGUAGES; ++i)
|
||||
{
|
||||
if (0 == NAME_LEXER[i].pattern.compare(baseName, Qt::CaseInsensitive))
|
||||
{
|
||||
return NAME_LEXER[i].lang;
|
||||
}
|
||||
}
|
||||
|
||||
// Unrecognized first line, we assume it is a text file for now
|
||||
return L_UNKNOWN;
|
||||
}
|
||||
|
|
|
@ -154,8 +154,13 @@ public:
|
|||
|
||||
void delNewFileNode(int fileIndex);
|
||||
|
||||
int loadFileDataInText(ScintillaEditView * editView, QString filePath, CODE_ID & fileTextCode, RC_LINE_FORM &lineEnd, CCNotePad * callbackObj=nullptr, bool hexAsk = true, QWidget* MsgBoxParent=nullptr);
|
||||
int loadFileDataInTextFromOffset(ScintillaEditView* editView, QString filePath, CODE_ID fileTextCode, QWidget* msgBoxParent, quint64 startReadSize);
|
||||
|
||||
//下面这个是旧函数,之前对比时候用的。
|
||||
//int loadFileDataInText(ScintillaEditView * editView, QString filePath, CODE_ID & fileTextCode, RC_LINE_FORM &lineEnd, CCNotePad * callbackObj=nullptr, bool hexAsk = true, QWidget* MsgBoxParent=nullptr);
|
||||
|
||||
int loadFileDataInText(ScintillaEditView* editView, QString filePath, CODE_ID& fileTextCode, RC_LINE_FORM& lineEnd, CCNotePad* callbackObj = nullptr, bool hexAsk = true, QWidget* msgBoxParent = nullptr);
|
||||
|
||||
int loadFileForSearch(ScintillaEditView * editView, QString filePath);
|
||||
|
||||
//int loadFileData(ScintillaEditView * editView, QString filePath, CODE_ID & fileTextCode, RC_LINE_FORM & lineEnd);
|
||||
|
@ -188,8 +193,6 @@ public:
|
|||
|
||||
void closeBigTextRoFileHand(QString filepath);
|
||||
|
||||
LangType detectLanguageFromTextBegining(const unsigned char * data, size_t dataLen);
|
||||
|
||||
static FileManager& getInstance() {
|
||||
static FileManager instance;
|
||||
return instance;
|
||||
|
|
|
@ -153,7 +153,7 @@
|
|||
</size>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
<number>-100</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
@ -35,8 +35,9 @@ void CTipWin::slot_delayClose()
|
|||
}
|
||||
|
||||
|
||||
void CTipWin::showTips(QWidget* parent, QString text, int sec)
|
||||
void CTipWin::showTips(QWidget* parent, QString text, int sec, bool isMousePos)
|
||||
{
|
||||
|
||||
if (parent != nullptr)
|
||||
{
|
||||
CTipWin* pWin = new CTipWin();
|
||||
|
@ -44,10 +45,18 @@ void CTipWin::showTips(QWidget* parent, QString text, int sec)
|
|||
pWin->setAttribute(Qt::WA_DeleteOnClose);
|
||||
pWin->showMsg(sec);
|
||||
|
||||
if (!isMousePos)
|
||||
{
|
||||
QPoint pos = parent->pos();
|
||||
QSize size = parent->size();
|
||||
|
||||
QPoint newPos(pos.x() + 10, pos.y() + size.height() - 20);
|
||||
pWin->move(newPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
pWin->move(parent->cursor().pos());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ public:
|
|||
~CTipWin();
|
||||
void setTipText(QString text);
|
||||
void showMsg(int sec = 2000);
|
||||
static void showTips(QWidget* parent, QString text, int sec);
|
||||
static void showTips(QWidget* parent, QString text, int sec, bool isMousePos = false);
|
||||
|
||||
private slots:
|
||||
void slot_delayClose();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#ifdef WIN32
|
||||
|
||||
DectFileChanges::DectFileChanges()
|
||||
DectFileChanges::DectFileChanges():m_lastFileSize(0), m_curFileSize(0)
|
||||
{
|
||||
_szFile = NULL;
|
||||
_dwNotifyFilter = 0;
|
||||
|
@ -28,7 +28,16 @@ BOOL DectFileChanges::DetectChanges() {
|
|||
rValue = TRUE;
|
||||
}
|
||||
|
||||
if (rValue)
|
||||
{
|
||||
m_lastFileSize = getFileSize(_lastFileInfo);
|
||||
}
|
||||
_lastFileInfo = fInfo;
|
||||
|
||||
if (rValue)
|
||||
{
|
||||
m_curFileSize = getFileSize(_lastFileInfo);
|
||||
}
|
||||
return rValue;
|
||||
}
|
||||
|
||||
|
@ -45,4 +54,19 @@ void DectFileChanges::Terminate()
|
|||
_szFile = NULL;
|
||||
_dwNotifyFilter = 0;
|
||||
}
|
||||
#endif
|
||||
quint64 DectFileChanges::getFileSize(WIN32_FILE_ATTRIBUTE_DATA& data)
|
||||
{
|
||||
quint64 fileSize = data.nFileSizeHigh;
|
||||
fileSize = (fileSize << 32);
|
||||
fileSize += data.nFileSizeLow;
|
||||
|
||||
return fileSize;
|
||||
}
|
||||
|
||||
void DectFileChanges::getDiffFileSize(quint64& lastSize, quint64& curSize)
|
||||
{
|
||||
lastSize = m_lastFileSize;
|
||||
curSize = m_curFileSize;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#define NOMINMAX
|
||||
|
||||
#include <windows.h>
|
||||
#include <QtGlobal>
|
||||
|
||||
class DectFileChanges
|
||||
{
|
||||
|
@ -22,11 +23,19 @@ public:
|
|||
BOOL DetectChanges();
|
||||
void Terminate();
|
||||
|
||||
void getDiffFileSize(quint64& lastSize, quint64& curSize);
|
||||
|
||||
private:
|
||||
quint64 getFileSize(WIN32_FILE_ATTRIBUTE_DATA& data);
|
||||
|
||||
private:
|
||||
LPCTSTR _szFile = nullptr;
|
||||
DWORD _dwNotifyFilter = 0;
|
||||
WIN32_FILE_ATTRIBUTE_DATA _lastFileInfo = {};
|
||||
|
||||
quint64 m_lastFileSize;
|
||||
quint64 m_curFileSize;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -290,7 +290,7 @@ QFuture<EncodeThreadParameter*> EncodeConvert::commitTask(std::function<EncodeTh
|
|||
}
|
||||
|
||||
|
||||
//对比左右文件的大小,sha1值来判断文件是否相等
|
||||
//识别文件编码
|
||||
QFuture<EncodeThreadParameter_*> EncodeConvert::checkFileCode(QString filePath, QTreeWidgetItem* item)
|
||||
{
|
||||
EncodeThreadParameter_* p = new EncodeThreadParameter_(filePath);
|
||||
|
@ -299,7 +299,8 @@ QFuture<EncodeThreadParameter_*> EncodeConvert::checkFileCode(QString filePath,
|
|||
//int 0相等 1 不等
|
||||
return commitTask([](EncodeThreadParameter_* parameter)->EncodeThreadParameter_*
|
||||
{
|
||||
parameter->code = CmpareMode::scanFileRealCode(parameter->filepath);
|
||||
//整个文件都要扫描完毕。还是怕太慢,最多1000行吧
|
||||
parameter->code = CmpareMode::scanFileRealCode(parameter->filepath,1000);
|
||||
return parameter;
|
||||
}
|
||||
, p);
|
||||
|
@ -474,6 +475,7 @@ void EncodeConvert::scanFileCode()
|
|||
{
|
||||
iter->selfItem->setText(2, QString("--"));
|
||||
}
|
||||
//20230304 编码转换这里,不能仅仅只识别已知后缀文件,要失败所有文件
|
||||
else if ((iter->type == RC_FILE) && DocTypeListView::isSupportExt(fileSuffix(iter->relativePath)))
|
||||
{
|
||||
QFutureWatcher<EncodeThreadParameter_*>* futureWatcher = new QFutureWatcher<EncodeThreadParameter_*>();
|
||||
|
|
|
@ -0,0 +1,288 @@
|
|||
#include "findresultview.h"
|
||||
#include "styleset.h"
|
||||
#include "findresultwin.h"
|
||||
#include "ctipwin.h"
|
||||
#include "Scintilla.h"
|
||||
|
||||
#include <QClipboard>
|
||||
|
||||
|
||||
const int MARGE_FOLDER = 1;
|
||||
const int STYLE_COLOUR_TITLE = 1;
|
||||
const int STYLE_COLOUR_DEST_FILE = 2;
|
||||
const int STYLE_COLOUR_KEYWORD_HIGH = 3;
|
||||
const int STYLE_COLOUR_KEYWORD_BACK_HIGH = 4;
|
||||
const int STYLE_DEEP_COLOUR_KEYWORD_HIGH = 5; //深色模式下面的前景色
|
||||
const int STYLE_DEEP_COLOUR_DEST_FILE = 6;
|
||||
|
||||
static void getFoldColor(QColor& fgColor, QColor& bgColor, QColor& activeFgColor)
|
||||
{
|
||||
//这里看起来反了,但是实际代码就是如此
|
||||
fgColor = StyleSet::s_global_style->fold.bgColor;
|
||||
bgColor = StyleSet::s_global_style->fold.fgColor;
|
||||
|
||||
activeFgColor = StyleSet::s_global_style->fold_active.fgColor;
|
||||
|
||||
}
|
||||
|
||||
void FindResultView::setFoldColor(int margin, QColor fgClack, QColor bkColor, QColor foreActive)
|
||||
{
|
||||
SendScintilla(SCI_MARKERSETFORE, margin, fgClack);
|
||||
SendScintilla(SCI_MARKERSETBACK, margin, bkColor);
|
||||
SendScintilla(SCI_MARKERSETBACKSELECTED, margin, foreActive);
|
||||
}
|
||||
|
||||
FindResultView::FindResultView(QWidget *parent)
|
||||
: QsciScintilla(parent)
|
||||
{
|
||||
//通过fold发现,尽量使用qscint的功能,因为他做了大量封装和简化
|
||||
setFolding(BoxedTreeFoldStyle, MARGE_FOLDER);
|
||||
|
||||
SendScintilla(SCI_SETMARGINWIDTHN, MARGE_FOLDER, 14);
|
||||
|
||||
SendScintilla(SCI_MARKERSETFORE, SC_MARKNUM_FOLDERSUB, QColor(0xff,0,0));
|
||||
|
||||
setCaretLineVisible(true);
|
||||
SendScintilla(SCI_SETSCROLLWIDTHTRACKING, true);
|
||||
SendScintilla(SCI_SETCARETLINEBACK, StyleSet::s_global_style->current_line_background_color.bgColor);
|
||||
|
||||
QColor foldfgColor = Qt::white, foldbgColor = Qt::gray, activeFoldFgColor = Qt::red;
|
||||
getFoldColor(foldfgColor, foldbgColor, activeFoldFgColor);
|
||||
setFoldMarginColors(StyleSet::s_global_style->fold_margin.fgColor, StyleSet::s_global_style->fold_margin.bgColor);
|
||||
setFoldColor(SC_MARKNUM_FOLDEROPEN, foldfgColor, foldbgColor, activeFoldFgColor);
|
||||
setFoldColor(SC_MARKNUM_FOLDER, foldfgColor, foldbgColor, activeFoldFgColor);
|
||||
setFoldColor(SC_MARKNUM_FOLDERSUB, foldfgColor, foldbgColor, activeFoldFgColor);
|
||||
setFoldColor(SC_MARKNUM_FOLDERTAIL, foldfgColor, foldbgColor, activeFoldFgColor);
|
||||
setFoldColor(SC_MARKNUM_FOLDEREND, foldfgColor, foldbgColor, activeFoldFgColor);
|
||||
setFoldColor(SC_MARKNUM_FOLDEROPENMID, foldfgColor, foldbgColor, activeFoldFgColor);
|
||||
setFoldColor(SC_MARKNUM_FOLDERMIDTAIL, foldfgColor, foldbgColor, activeFoldFgColor);
|
||||
|
||||
SendScintilla(SCI_STYLESETSIZE, STYLE_DEFAULT, 12);
|
||||
|
||||
if (!StyleSet::isCurrentDeepStyle())
|
||||
{
|
||||
this->setPaper(StyleSet::s_global_style->default_style.bgColor);
|
||||
|
||||
SendScintilla(SCI_STYLESETBACK, STYLE_COLOUR_TITLE, 0xffbbbb);
|
||||
SendScintilla(SCI_STYLESETBACK, STYLE_COLOUR_DEST_FILE, 0xd5ffd5);
|
||||
SendScintilla(SCI_STYLESETEOLFILLED, STYLE_COLOUR_TITLE, true);
|
||||
SendScintilla(SCI_STYLESETEOLFILLED, STYLE_COLOUR_DEST_FILE, true);
|
||||
SendScintilla(SCI_STYLESETFORE, STYLE_COLOUR_KEYWORD_HIGH, 0x4080ff);
|
||||
SendScintilla(SCI_STYLESETBACK, STYLE_COLOUR_KEYWORD_BACK_HIGH, 0xbfffff);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
this->setColor(StyleSet::s_global_style->default_style.fgColor);
|
||||
this->setPaper(StyleSet::s_global_style->default_style.bgColor);
|
||||
|
||||
//QColor& col = StyleSet::s_global_style->default_style.fgColor;
|
||||
//sptr_t fgLParam = (col.blue() << 16) | (col.green() << 8) | col.red();
|
||||
|
||||
QColor& col2 = StyleSet::s_global_style->default_style.bgColor;
|
||||
sptr_t bklParam = (col2.blue() << 16) | (col2.green() << 8) | col2.red();
|
||||
|
||||
SendScintilla(SCI_STYLESETBACK, STYLE_COLOUR_TITLE, 0xffbbbb);
|
||||
SendScintilla(SCI_STYLESETEOLFILLED, STYLE_COLOUR_TITLE, true);
|
||||
//SendScintilla(SCI_STYLESETFORE, STYLE_COLOUR_TITLE, fgLParam);
|
||||
|
||||
SendScintilla(SCI_STYLESETBACK, STYLE_DEEP_COLOUR_DEST_FILE, bklParam);
|
||||
SendScintilla(SCI_STYLESETFORE, STYLE_DEEP_COLOUR_DEST_FILE, 0x99cc99);
|
||||
//SendScintilla(SCI_STYLESETFORE, STYLE_DEEP_COLOUR_DEST_FILE, fgLParam);
|
||||
//SendScintilla(SCI_STYLESETBOLD, STYLE_DEEP_COLOUR_DEST_FILE, 1);//这个无法生效。可能是qscint bug
|
||||
|
||||
//文字要大一号,然后颜色是绿色
|
||||
SendScintilla(SCI_STYLESETSIZE, STYLE_DEEP_COLOUR_DEST_FILE, 14);
|
||||
|
||||
SendScintilla(SCI_STYLESETFORE, STYLE_DEEP_COLOUR_KEYWORD_HIGH, 0x00aaff);
|
||||
SendScintilla(SCI_STYLESETBACK, STYLE_DEEP_COLOUR_KEYWORD_HIGH, bklParam);
|
||||
|
||||
|
||||
//给行号使用
|
||||
SendScintilla(SCI_STYLESETFORE, STYLE_COLOUR_KEYWORD_HIGH, 0x4080ff);
|
||||
SendScintilla(SCI_STYLESETBACK, STYLE_COLOUR_KEYWORD_HIGH, bklParam);
|
||||
}
|
||||
|
||||
|
||||
this->setReadOnly(true);
|
||||
|
||||
m_resultWin = dynamic_cast<FindResultWin*>(parent);
|
||||
}
|
||||
|
||||
FindResultView::~FindResultView()
|
||||
{}
|
||||
|
||||
//设置行背景色
|
||||
void FindResultView::setLineBackColorStyle(int line, int style)
|
||||
{
|
||||
int startPos = SendScintilla(SCI_POSITIONFROMLINE, line);
|
||||
int len = SendScintilla(SCI_LINELENGTH, line);
|
||||
|
||||
SendScintilla(SCI_STARTSTYLING, startPos);
|
||||
SendScintilla(SCI_SETSTYLING, len, style);
|
||||
}
|
||||
|
||||
//设置行前景色。line 行号,从相对行pos的位置开始
|
||||
void FindResultView::setLineColorStyle(int line, int offsetPos, int length, int style)
|
||||
{
|
||||
int startPos = SendScintilla(SCI_POSITIONFROMLINE, line);
|
||||
SendScintilla(SCI_STARTSTYLING, startPos + offsetPos);
|
||||
SendScintilla(SCI_SETSTYLING, length, style);
|
||||
}
|
||||
|
||||
|
||||
void FindResultView::mouseDoubleClickEvent(QMouseEvent* /*e*/)
|
||||
{
|
||||
//QsciScintilla::mouseDoubleClickEvent(e);
|
||||
|
||||
int line = 0;
|
||||
int index = 0;
|
||||
|
||||
this->getCursorPosition(&line,&index);
|
||||
|
||||
emit lineDoubleClick(line);
|
||||
}
|
||||
|
||||
void FindResultView::contextUserDefineMenuEvent(QMenu* menu)
|
||||
{
|
||||
if (menu != nullptr)
|
||||
{
|
||||
//移动一下位置
|
||||
|
||||
QAction* pCopy = menu->findChild<QAction*>("copy");
|
||||
if (pCopy != nullptr)
|
||||
{
|
||||
menu->removeAction(pCopy);
|
||||
}
|
||||
|
||||
menu->addAction(tr("Fold All"), this, &FindResultView::on_foldAll);
|
||||
menu->addAction(tr("Expand All"), this, &FindResultView::on_expandAll);
|
||||
|
||||
menu->addSeparator();
|
||||
|
||||
if (pCopy != nullptr)
|
||||
{
|
||||
menu->addAction(pCopy);
|
||||
}
|
||||
menu->addAction(tr("copy select line"), this, &FindResultView::on_copySelectLine);
|
||||
menu->addAction(tr("warp"), this, &FindResultView::on_warp);
|
||||
|
||||
menu->addSeparator();
|
||||
|
||||
menu->addAction(tr("clear"), this, &FindResultView::on_clear);
|
||||
menu->addAction(tr("close"), this, &FindResultView::on_close);
|
||||
|
||||
|
||||
}
|
||||
menu->move(cursor().pos()); //让菜单显示的位置在鼠标的坐标上
|
||||
menu->show();
|
||||
}
|
||||
|
||||
void FindResultView::on_foldAll()
|
||||
{
|
||||
for (int i = 0; i < m_resultWin->m_resultLineInfo.size(); ++i)
|
||||
{
|
||||
const ResultLineInfo& lineInfo = m_resultWin->m_resultLineInfo.at(i);
|
||||
|
||||
//如果是1级别的行,则进行一个收起操作
|
||||
if ((lineInfo.level == 1) || (lineInfo.level == 0))
|
||||
{
|
||||
SendScintilla(SCI_FOLDLINE, i, (long)SC_FOLDACTION_CONTRACT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FindResultView::on_expandAll()
|
||||
{
|
||||
for (int i = 0; i < m_resultWin->m_resultLineInfo.size(); ++i)
|
||||
{
|
||||
const ResultLineInfo& lineInfo = m_resultWin->m_resultLineInfo.at(i);
|
||||
|
||||
//如果是1级别的行,则进行一个收起操作
|
||||
if ((lineInfo.level == 1) || (lineInfo.level == 0))
|
||||
{
|
||||
SendScintilla(SCI_FOLDLINE, i, SC_FOLDACTION_EXPAND);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//复制选中的内容
|
||||
//void FindResultView::on_copySelect()
|
||||
//{
|
||||
// QString word = selectedText();
|
||||
// if (!word.isEmpty())
|
||||
// {
|
||||
// QClipboard* clipboard = QApplication::clipboard();
|
||||
// clipboard->setText(word);
|
||||
//
|
||||
// CTipWin::showTips(this, tr("Copy to clipboard Finished!"), 1200,true);
|
||||
// }
|
||||
//}
|
||||
|
||||
//复制选中行
|
||||
void FindResultView::on_copySelectLine()
|
||||
{
|
||||
int startPos = SendScintilla(SCI_GETSELECTIONSTART);
|
||||
int endPos = SendScintilla(SCI_GETSELECTIONEND);
|
||||
|
||||
int startLine = SendScintilla(SCI_LINEFROMPOSITION, startPos);
|
||||
int endLine = SendScintilla(SCI_LINEFROMPOSITION, endPos);
|
||||
|
||||
int start = SendScintilla(SCI_POSITIONFROMLINE, startLine);
|
||||
int end = SendScintilla(SCI_POSITIONFROMLINE, endLine+1);
|
||||
|
||||
char *dest = new char[end - start + 1];
|
||||
dest[end - start] = '\0';
|
||||
|
||||
Sci_TextRange tr;
|
||||
tr.chrg.cpMin = static_cast<Sci_PositionCR>(start);
|
||||
tr.chrg.cpMax = static_cast<Sci_PositionCR>(end);
|
||||
tr.lpstrText = dest;
|
||||
|
||||
this->SendScintilla(SCI_GETTEXTRANGE, 0, &tr);
|
||||
|
||||
QString text(dest);
|
||||
|
||||
QStringList lineText = text.split("\n");
|
||||
QString selectConnect;
|
||||
|
||||
for (int i = 0; i < lineText.size(); ++i)
|
||||
{
|
||||
const QString& t = lineText.at(i);
|
||||
int pos = t.indexOf(": ");
|
||||
if (pos != -1)
|
||||
{
|
||||
QString v = t.mid(pos + 2);
|
||||
selectConnect.append(v);
|
||||
selectConnect.append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
QClipboard* clipboard = QApplication::clipboard();
|
||||
clipboard->setText(selectConnect);
|
||||
|
||||
//CTipWin::showTips(this, tr("Copy to clipboard Finished!"), 1200, true);
|
||||
}
|
||||
|
||||
void FindResultView::on_clear()
|
||||
{
|
||||
this->clear();
|
||||
m_resultWin->clear();
|
||||
}
|
||||
|
||||
void FindResultView::on_close()
|
||||
{
|
||||
m_resultWin->m_parent->close();
|
||||
}
|
||||
|
||||
void FindResultView::on_warp()
|
||||
{
|
||||
if (SC_WRAP_CHAR != wrapMode())
|
||||
{
|
||||
this->setWrapMode(QsciScintilla::WrapCharacter);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->setWrapMode(QsciScintilla::WrapNone);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
#pragma once
|
||||
#include <QWidget>
|
||||
#include <qsciscintilla.h>
|
||||
#include <QMouseEvent>
|
||||
#include <QMenu>
|
||||
|
||||
extern const int MARGIN_VER_LINE;
|
||||
extern const int STYLE_COLOUR_TITLE;
|
||||
extern const int STYLE_COLOUR_DEST_FILE;
|
||||
extern const int STYLE_COLOUR_KEYWORD_HIGH;
|
||||
extern const int STYLE_COLOUR_KEYWORD_BACK_HIGH;
|
||||
extern const int STYLE_DEEP_COLOUR_KEYWORD_HIGH;
|
||||
extern const int STYLE_DEEP_COLOUR_DEST_FILE;
|
||||
|
||||
class FindResultWin;
|
||||
|
||||
class FindResultView : public QsciScintilla
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FindResultView(QWidget* parent);
|
||||
virtual ~FindResultView();
|
||||
|
||||
void setLineBackColorStyle(int line, int style);
|
||||
void setLineColorStyle(int line, int pos, int length, int style);
|
||||
|
||||
signals:
|
||||
void lineDoubleClick(int line);
|
||||
|
||||
public slots:
|
||||
void on_foldAll();
|
||||
private slots:
|
||||
|
||||
void on_expandAll();
|
||||
//void on_copySelect();
|
||||
void on_copySelectLine();
|
||||
void on_clear();
|
||||
void on_close();
|
||||
void on_warp();
|
||||
|
||||
protected:
|
||||
void mouseDoubleClickEvent(QMouseEvent* e) override;
|
||||
void contextUserDefineMenuEvent(QMenu* menu) override;
|
||||
void setFoldColor(int margin, QColor fgClack, QColor bkColor, QColor foreActive);
|
||||
|
||||
private:
|
||||
FindResultWin* m_resultWin;
|
||||
};
|
|
@ -3,19 +3,20 @@
|
|||
#include "common.h"
|
||||
#include "styleset.h"
|
||||
#include "nddsetting.h"
|
||||
#include "findresultview.h"
|
||||
|
||||
#include <QTreeWidgetItem>
|
||||
#include <QStyleFactory>
|
||||
#include <QToolButton>
|
||||
#include <qtreeview.h>
|
||||
#include <QStandardItem>
|
||||
#include <QStandardItemModel>
|
||||
#include <qsciscintilla.h>
|
||||
#include <Scintilla.h>
|
||||
|
||||
//#include <QTreeWidgetItem>
|
||||
//#include <QStyleFactory>
|
||||
//#include <QToolButton>
|
||||
//#include <qtreeview.h>
|
||||
//#include <QStandardItem>
|
||||
//#include <QStandardItemModel>
|
||||
#include <QClipboard>
|
||||
#include <QTextEdit>
|
||||
#include <qscrollbar.h>
|
||||
|
||||
#include "ndstyleditemdelegate.h"
|
||||
|
||||
//目前可以高亮,使用富文本进行了高亮设置。但是有个问题:富文本与html有一些冲突,在<>存在时,可能导致乱。这是一个问题。20220609
|
||||
//使用Html的转义解决了该问题
|
||||
|
||||
|
@ -23,51 +24,8 @@ FindResultWin::FindResultWin(QWidget *parent)
|
|||
: QWidget(parent), m_menu(nullptr), m_parent(parent),m_defaultFontSize(14), m_defFontSizeChange(false)
|
||||
{
|
||||
ui.setupUi(this);
|
||||
|
||||
//设置左边的缩起来按钮为加号,而不是箭头
|
||||
ui.resultTreeView->setStyle(QStyleFactory::create("windows"));
|
||||
ui.resultTreeView->header()->hide();
|
||||
connect(ui.displayView, &FindResultView::lineDoubleClick, this, &FindResultWin::on_lineDoubleClick);
|
||||
|
||||
m_model = new QStandardItemModel(ui.resultTreeView);
|
||||
m_delegate = new NdStyledItemDelegate(ui.resultTreeView);
|
||||
ui.resultTreeView->setModel(m_model);
|
||||
ui.resultTreeView->setItemDelegate(m_delegate);
|
||||
ui.resultTreeView->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
ui.resultTreeView->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
|
||||
//#if defined (Q_OS_MAC)
|
||||
// QString qss = "QTreeView::item:selected{ \
|
||||
// background:#e8e8ff; \
|
||||
// } \
|
||||
// QTreeView::item{ \
|
||||
// height:18px; \
|
||||
// }";
|
||||
//#else
|
||||
// QString qss = "QTreeView::item:selected{ \
|
||||
// background:#e8e8ff; \
|
||||
// }";
|
||||
//#endif
|
||||
// ui.resultTreeView->setStyleSheet(qss);
|
||||
|
||||
connect(ui.resultTreeView, &QTreeView::doubleClicked, this, &FindResultWin::itemDoubleClicked);
|
||||
|
||||
connect(ui.resultTreeView, SIGNAL(pressed(QModelIndex)), this, SLOT(slot_treeView_pressed(QModelIndex)));
|
||||
connect(ui.resultTreeView, SIGNAL(expanded(QModelIndex)), this, SLOT(slot_treeView_pressed(QModelIndex)));
|
||||
|
||||
ui.resultTreeView->verticalScrollBar()->setStyle(QStyleFactory::create("vis"));
|
||||
ui.resultTreeView->horizontalScrollBar()->setStyle(QStyleFactory::create("vis"));
|
||||
|
||||
int defFontSize = NddSetting::getKeyValueFromNumSets(FIND_RESULT_FONT_SIZE);
|
||||
if (defFontSize >= 8)
|
||||
{
|
||||
m_defaultFontSize = defFontSize;
|
||||
|
||||
QFont curFt = ui.resultTreeView->font();
|
||||
curFt.setPointSize(m_defaultFontSize);
|
||||
ui.resultTreeView->setFont(curFt);
|
||||
|
||||
m_delegate->setFontSize(m_defaultFontSize);
|
||||
}
|
||||
}
|
||||
|
||||
FindResultWin::~FindResultWin()
|
||||
|
@ -75,311 +33,32 @@ FindResultWin::~FindResultWin()
|
|||
if (m_defFontSizeChange)
|
||||
{
|
||||
NddSetting::updataKeyValueFromNumSets(FIND_RESULT_FONT_SIZE, m_defaultFontSize);
|
||||
}
|
||||
}
|
||||
|
||||
clear();
|
||||
}
|
||||
|
||||
void FindResultWin::slot_treeView_pressed(QModelIndex modeIndex)
|
||||
void FindResultWin::clear()
|
||||
{
|
||||
ui.resultTreeView->resizeColumnToContents(modeIndex.column());
|
||||
}
|
||||
|
||||
void FindResultWin::contextMenuEvent(QContextMenuEvent *)
|
||||
{
|
||||
if (m_menu == nullptr)
|
||||
for (int i = 0; i < m_resultLineFilePath.size(); ++i)
|
||||
{
|
||||
m_menu = new QMenu(this);
|
||||
m_menu->addAction(tr("clear this find result"), this, &FindResultWin::slot_clearContents);
|
||||
m_menu->addAction(tr("clear all find result"), this, &FindResultWin::slot_clearAllContents);
|
||||
|
||||
m_menu->addSeparator();
|
||||
m_pSelectSectonAct = m_menu->addAction(tr("select section"), this, &FindResultWin::slot_selectSection);
|
||||
m_menu->addAction(tr("select all item"), this, &FindResultWin::slot_selectAll);
|
||||
|
||||
m_menu->addSeparator();
|
||||
|
||||
m_menu->addAction(tr("copy select item (Ctrl Muli)"), this, &FindResultWin::slot_copyItemContents);
|
||||
m_menu->addAction(tr("copy select Line (Ctrl Muli)"), this, &FindResultWin::slot_copyContents);
|
||||
|
||||
m_menu->addSeparator();
|
||||
m_menu->addAction(tr("Zoom In"), this, &FindResultWin::slot_fontZoomIn);
|
||||
m_menu->addAction(tr("Zoom Out"), this, &FindResultWin::slot_fontZoomOut);
|
||||
m_menu->addAction(tr("close"), m_parent, &QWidget::close);
|
||||
|
||||
delete m_resultLineFilePath.at(i);
|
||||
}
|
||||
m_menu->move(cursor().pos()); //让菜单显示的位置在鼠标的坐标上
|
||||
m_menu->show();
|
||||
|
||||
QModelIndex curSelItem = ui.resultTreeView->currentIndex();
|
||||
|
||||
if (!curSelItem.data(ResultItemRoot).isNull())
|
||||
{
|
||||
//是根不能选择section
|
||||
m_pSelectSectonAct->setEnabled(false);
|
||||
}
|
||||
else if (!curSelItem.data(ResultItemEditor).isNull())
|
||||
{
|
||||
m_pSelectSectonAct->setEnabled(true);
|
||||
}
|
||||
else if (!curSelItem.data(ResultItemPos).isNull())
|
||||
{
|
||||
m_pSelectSectonAct->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void FindResultWin::slot_clearContents()
|
||||
{
|
||||
QModelIndex curSelItem = ui.resultTreeView->currentIndex();
|
||||
|
||||
if (!curSelItem.data(ResultItemRoot).isNull())
|
||||
{
|
||||
//是根可以直接删除
|
||||
m_model->removeRow(curSelItem.row());
|
||||
}
|
||||
else if (!curSelItem.data(ResultItemEditor).isNull())
|
||||
{
|
||||
//需要找到上一个父节点,即根
|
||||
QModelIndex rootItem = curSelItem.parent();
|
||||
|
||||
if (rootItem.isValid())
|
||||
{
|
||||
m_model->removeRow(curSelItem.row(), rootItem);
|
||||
|
||||
if (0 == m_model->rowCount(rootItem))
|
||||
{
|
||||
m_model->removeRow(rootItem.row());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!curSelItem.data(ResultItemPos).isNull())
|
||||
{
|
||||
//需要找到上两个父节点,即根
|
||||
QModelIndex itemEditor = curSelItem.parent();
|
||||
if (itemEditor.isValid())
|
||||
{
|
||||
QModelIndex rootItem = itemEditor.parent();
|
||||
if (rootItem.isValid())
|
||||
{
|
||||
m_model->removeRow(itemEditor.row(), rootItem);
|
||||
if (0 == m_model->rowCount(rootItem))
|
||||
{
|
||||
m_model->removeRow(rootItem.row());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//全选
|
||||
void FindResultWin::slot_selectAll()
|
||||
{
|
||||
|
||||
QModelIndex root = ui.resultTreeView->rootIndex();
|
||||
|
||||
QModelIndex curSelItem = ui.resultTreeView->currentIndex();
|
||||
QModelIndex firstRootItem;
|
||||
//先找到根节点
|
||||
while (curSelItem.isValid())
|
||||
{
|
||||
QModelIndex pMi = curSelItem.parent();
|
||||
if (pMi.isValid())
|
||||
{
|
||||
curSelItem = pMi;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//找到第一个兄弟根节点
|
||||
if (curSelItem.row() != 0)
|
||||
{
|
||||
firstRootItem = curSelItem.siblingAtRow(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
firstRootItem = curSelItem;
|
||||
}
|
||||
|
||||
auto selectSection = [this](QModelIndex& sectionItem)->int{
|
||||
//遍历其下面的所有子节点
|
||||
ui.resultTreeView->selectionModel()->select(sectionItem, QItemSelectionModel::Select);
|
||||
|
||||
//遍历下面的子节点
|
||||
int i = 0;
|
||||
QModelIndex childMi;
|
||||
childMi = sectionItem.model()->index(i, 0, sectionItem);
|
||||
while (childMi.isValid())
|
||||
{
|
||||
++i;
|
||||
ui.resultTreeView->selectionModel()->select(childMi, QItemSelectionModel::Select);
|
||||
childMi = sectionItem.model()->index(i, 0, sectionItem);
|
||||
}
|
||||
return i+1;
|
||||
};
|
||||
|
||||
QModelIndex rootItem = firstRootItem;
|
||||
int j = 0;
|
||||
int selectCount = 0;
|
||||
while (rootItem.isValid())
|
||||
{
|
||||
//遍历根节点下面每一个section
|
||||
{
|
||||
int i = 0;
|
||||
QModelIndex section = rootItem.model()->index(i, 0, rootItem);
|
||||
while (section.isValid() && !section.data(ResultItemEditor).isNull())
|
||||
{
|
||||
++i;
|
||||
selectCount += selectSection(section);
|
||||
section = firstRootItem.model()->index(i, 0, firstRootItem);
|
||||
}
|
||||
}
|
||||
|
||||
//切换到下一个查找的根节点
|
||||
j++;
|
||||
rootItem = firstRootItem.siblingAtRow(j);
|
||||
}
|
||||
|
||||
QString msg = tr("%1 rows selected !").arg(selectCount);
|
||||
emit showMsg(msg);
|
||||
}
|
||||
|
||||
void FindResultWin::slot_selectSection()
|
||||
{
|
||||
QModelIndex curSelItem = ui.resultTreeView->currentIndex();
|
||||
|
||||
auto selectSection = [this](QModelIndex& sectionItem)->int {
|
||||
//遍历其下面的所有子节点
|
||||
ui.resultTreeView->selectionModel()->select(sectionItem, QItemSelectionModel::Select);
|
||||
|
||||
//遍历下面的子节点
|
||||
int i = 0;
|
||||
QModelIndex childMi;
|
||||
childMi = sectionItem.model()->index(i, 0, sectionItem);
|
||||
while (childMi.isValid())
|
||||
{
|
||||
++i;
|
||||
ui.resultTreeView->selectionModel()->select(childMi, QItemSelectionModel::Select);
|
||||
childMi = sectionItem.model()->index(i, 0, sectionItem);
|
||||
}
|
||||
return i+1;
|
||||
};
|
||||
|
||||
int selectCount = 0;
|
||||
|
||||
if (!curSelItem.data(ResultItemRoot).isNull())
|
||||
{
|
||||
//啥也不做。不能选择多个section
|
||||
}
|
||||
else if (!curSelItem.data(ResultItemEditor).isNull())
|
||||
{
|
||||
selectCount = selectSection(curSelItem);
|
||||
|
||||
}
|
||||
else if (!curSelItem.data(ResultItemPos).isNull())
|
||||
{
|
||||
//其父节点
|
||||
QModelIndex sectionItem = curSelItem.parent();
|
||||
if (!sectionItem.data(ResultItemEditor).isNull())
|
||||
{
|
||||
selectCount = selectSection(sectionItem);
|
||||
}
|
||||
}
|
||||
|
||||
QString msg = tr("%1 rows selected !").arg(selectCount);
|
||||
emit showMsg(msg);
|
||||
}
|
||||
|
||||
//拷贝item的行,不进行过滤,全部拷贝
|
||||
void FindResultWin::slot_copyItemContents()
|
||||
{
|
||||
QModelIndexList selectList;
|
||||
|
||||
ui.resultTreeView->getSelectedIndexes(selectList);
|
||||
|
||||
QString selectConnect;
|
||||
|
||||
for (int i = 0, s = selectList.size(); i < s; ++i)
|
||||
{
|
||||
|
||||
QModelIndex curSelItem = selectList.at(i);
|
||||
|
||||
QString text = m_model->itemData(curSelItem).values()[0].toString();
|
||||
|
||||
QTextEdit t(this);
|
||||
t.setAcceptRichText(true);
|
||||
t.setText(text);
|
||||
text = t.toPlainText();
|
||||
|
||||
selectConnect.append(text);
|
||||
selectConnect.append("\n");
|
||||
}
|
||||
|
||||
QClipboard *clip = QApplication::clipboard();
|
||||
clip->setText(selectConnect);
|
||||
|
||||
QString msg = tr("%1 items have been copied to the clipboard !").arg(selectList.size());
|
||||
emit showMsg(msg);
|
||||
}
|
||||
|
||||
void FindResultWin::slot_copyContents()
|
||||
{
|
||||
QModelIndexList selectList;
|
||||
|
||||
//std::sort(selectList.begin(), selectList.end(), [](QModelIndex& a, QModelIndex& b) {
|
||||
// return a.row() < b.row();
|
||||
//});
|
||||
|
||||
ui.resultTreeView->getSelectedIndexes(selectList);
|
||||
|
||||
QString selectConnect;
|
||||
|
||||
int copyTimes = 0;
|
||||
|
||||
for (int i = 0, s = selectList.size(); i < s; ++i)
|
||||
{
|
||||
QModelIndex curSelItem = selectList.at(i);
|
||||
|
||||
//只拷贝真正的行内容
|
||||
if (curSelItem.data(ResultItemPos).isNull())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
copyTimes++;
|
||||
|
||||
QString text = m_model->itemData(curSelItem).values()[0].toString();
|
||||
|
||||
QTextEdit t(this);
|
||||
t.setAcceptRichText(true);
|
||||
t.setText(text);
|
||||
text = t.toPlainText();
|
||||
|
||||
int pos = text.indexOf(": ");
|
||||
if (pos != -1)
|
||||
{
|
||||
text = text.mid(pos + 2);
|
||||
}
|
||||
|
||||
selectConnect.append(text);
|
||||
selectConnect.append("\n");
|
||||
}
|
||||
|
||||
QClipboard *clip = QApplication::clipboard();
|
||||
clip->setText(selectConnect);
|
||||
|
||||
QString msg = tr("%1 lines have been copied to the clipboard !").arg(copyTimes);
|
||||
emit showMsg(msg);
|
||||
m_resultLineFilePath.clear();
|
||||
m_resultLineInfo.clear();
|
||||
}
|
||||
|
||||
void FindResultWin::slot_clearAllContents()
|
||||
{
|
||||
m_model->clear();
|
||||
clear();
|
||||
ui.displayView->clear();
|
||||
}
|
||||
|
||||
#if 0 //老的机制,暂时屏蔽,后续可删除
|
||||
//高亮查找的关键字文本。Index表示是第几次出现,前面的要跳过
|
||||
void FindResultWin::highlightFindText(int index, QString &srcText, QString &findText, Qt::CaseSensitivity cs)
|
||||
{
|
||||
#if 0
|
||||
int pos = 0;
|
||||
int findPos = 0;
|
||||
|
||||
|
@ -403,14 +82,18 @@ void FindResultWin::highlightFindText(int index, QString &srcText, QString &find
|
|||
index--;
|
||||
}
|
||||
srcText.replace(pos, lens, QString("<font style='font-size:14px;background-color:#ffffbf'>%1</font>").arg(srcText.mid(pos,lens)));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
const int MAX_HEAD_LENTGH = 20;
|
||||
const int MAX_TAIL_LENGTH = 80;
|
||||
|
||||
#if 0
|
||||
//更复杂的高亮:在全词语匹配,大小写敏感,甚至正则表达式情况下,上面的highlightFindText是不够的。需要精确定位
|
||||
QString FindResultWin::highlightFindText(FindRecord& record)
|
||||
{
|
||||
#if 0
|
||||
QByteArray utf8bytes = record.lineContents.toUtf8();
|
||||
|
||||
int lineLens = utf8bytes.length();
|
||||
|
@ -438,9 +121,9 @@ QString FindResultWin::highlightFindText(FindRecord& record)
|
|||
head = QString("<font style='font-size:14px;'>%1</font>").arg(QString(utf8bytes.mid(0, targetStart)).toHtmlEscaped());
|
||||
src = QString("<font style='font-size:14px;background-color:#ffffbf'>%1</font>").arg(QString(utf8bytes.mid(targetStart, targetLens)).toHtmlEscaped());
|
||||
tail = QString("<font style='font-size:14px;'>%1</font>").arg(QString(utf8bytes.mid(tailStart)).toHtmlEscaped());
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
head = QString(utf8bytes.mid(0, targetStart));
|
||||
if (head.size() > MAX_HEAD_LENTGH)
|
||||
{
|
||||
|
@ -475,7 +158,7 @@ QString FindResultWin::highlightFindText(FindRecord& record)
|
|||
head = QString("<font style='font-size:14px;color:#dcdcdc'>%1</font>").arg(QString(utf8bytes.mid(0, targetStart)).toHtmlEscaped());
|
||||
src = QString("<font style='font-size:14px;font-weight:bold;color:#ffaa00'>%1</font>").arg(QString(utf8bytes.mid(targetStart, targetLens)).toHtmlEscaped());
|
||||
tail = QString("<font style='font-size:14px;color:#dcdcdc'>%1</font>").arg(QString(utf8bytes.mid(tailStart)).toHtmlEscaped());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QString headContens = QString(utf8bytes.mid(0, targetStart));
|
||||
|
@ -509,36 +192,68 @@ QString FindResultWin::highlightFindText(FindRecord& record)
|
|||
}
|
||||
|
||||
return QString("%1%2%3").arg(head).arg(src).arg(tail);
|
||||
#endif
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
//在当前文件查找字段,结果是一个单一的FindRecords
|
||||
void FindResultWin::appendResultsToShow(FindRecords* record)
|
||||
{
|
||||
#if 0
|
||||
if (record == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
FindResultView* pDisplay = ui.displayView;
|
||||
|
||||
QString findTitle = tr("Search \"%1\" (%2 hits)\n").arg(record->findText).arg(record->records.size());
|
||||
|
||||
//pDisplay->append(findTitle);
|
||||
|
||||
pDisplay->insertAt(findTitle,0,0);
|
||||
|
||||
pDisplay->SendScintilla(SCI_SETFOLDLEVEL, 0, (long)(0|SC_FOLDLEVELHEADERFLAG));
|
||||
|
||||
QStringList contents;
|
||||
|
||||
for (int i = 0; i < record->records.size(); ++i)
|
||||
{
|
||||
FindRecord v = record->records.at(i);
|
||||
|
||||
const QString & richText = v.lineContents;
|
||||
|
||||
QString text;
|
||||
if (!StyleSet::isCurrentDeepStyle())
|
||||
{
|
||||
text = tr("Line %1 : %2\n").arg(v.lineNum + 1).arg(richText);
|
||||
}
|
||||
else
|
||||
{
|
||||
text = tr("Line %1 : %2\n").arg(v.lineNum + 1).arg(richText);
|
||||
}
|
||||
|
||||
contents.append(text);
|
||||
}
|
||||
|
||||
pDisplay->insertAt(contents.join(""), 1, 0);
|
||||
|
||||
for (int i = 0; i < record->records.size(); ++i)
|
||||
{
|
||||
pDisplay->SendScintilla(SCI_SETFOLDLEVEL, i+1, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
|
||||
|
||||
QString findTitle;
|
||||
//if (!StyleSet::isCurrentDeepStyle())
|
||||
//{
|
||||
findTitle = tr("<font style='font-size:14px;font-weight:bold;color:#343497'>Search \"%1\" (%2 hits)</font>").arg(record->findText.toHtmlEscaped()).arg(record->records.size());
|
||||
/*}
|
||||
else
|
||||
{
|
||||
findTitle = tr("<font style='font-size:14px;font-weight:bold;color:#ffffff'>Search \"%1\" (%2 hits)</font>").arg(record->findText.toHtmlEscaped()).arg(record->records.size());
|
||||
}*/
|
||||
|
||||
findTitle = tr("<font style='font-size:14px;font-weight:bold;color:#343497'>Search \"%1\" (%2 hits)</font>").arg(record->findText.toHtmlEscaped()).arg(record->records.size());
|
||||
|
||||
QStandardItem* titleItem = new QStandardItem(findTitle);
|
||||
|
||||
//if (!StyleSet::isCurrentDeepStyle())
|
||||
//{
|
||||
setItemBackground(titleItem, QColor(0xbbbbff));
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// setItemBackground(titleItem, QColor(0x423328));//0xd5ffd5
|
||||
//}
|
||||
setItemBackground(titleItem, QColor(0xbbbbff));
|
||||
|
||||
|
||||
m_model->insertRow(0, titleItem);
|
||||
titleItem->setData(QVariant(true), ResultItemRoot);
|
||||
|
@ -587,8 +302,6 @@ void FindResultWin::appendResultsToShow(FindRecords* record)
|
|||
//描述行双击不响应
|
||||
descItem->setData(QVariant(true), ResultItemDesc);
|
||||
|
||||
//int lastLineNum = -1;
|
||||
//int occurTimes = 0;
|
||||
|
||||
for (int i =0 ; i < record->records.size(); ++i)
|
||||
{
|
||||
|
@ -617,8 +330,9 @@ void FindResultWin::appendResultsToShow(FindRecords* record)
|
|||
{
|
||||
ui.resultTreeView->expand(m_model->index(0, 0, m_model->index(0, 0)));
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
void FindResultWin::appendResultsToShow(QVector<FindRecords*>* record, int hits, QString whatFind)
|
||||
{
|
||||
|
@ -627,149 +341,149 @@ void FindResultWin::appendResultsToShow(QVector<FindRecords*>* record, int hits,
|
|||
return;
|
||||
}
|
||||
|
||||
QString findTitle = tr("<font style='font-size:14px;font-weight:bold;color:#343497'>Search \"%1\" (%2 hits in %3 files)</font>").arg(whatFind.toHtmlEscaped()).arg(hits).arg(record->size());
|
||||
QStandardItem* titleItem = new QStandardItem(findTitle);
|
||||
setItemBackground(titleItem, QColor(0xbbbbff));
|
||||
titleItem->setData(QVariant(true), ResultItemRoot);
|
||||
|
||||
//总是把结果插在最上面一行
|
||||
m_model->insertRow(0, titleItem);
|
||||
|
||||
int rowNum = m_model->rowCount();
|
||||
|
||||
//把其余的行收起来
|
||||
for (int i = 1; i < rowNum; ++i)
|
||||
if (this->isHidden())
|
||||
{
|
||||
ui.resultTreeView->collapse(m_model->index(i, 0));
|
||||
this->setVisible(true);
|
||||
}
|
||||
ui.resultTreeView->expand(m_model->index(0, 0));
|
||||
|
||||
ResultLineInfo lineInfo;
|
||||
|
||||
QString findTitle = tr("Search \"%1\" (%2 hits in %3 files)\n").arg(whatFind).arg(hits).arg(record->size());
|
||||
|
||||
FindResultView* pDisplay = ui.displayView;
|
||||
pDisplay->on_foldAll();
|
||||
|
||||
pDisplay->insertAt(findTitle, 0, 0);
|
||||
|
||||
lineInfo.level = 0;
|
||||
m_resultLineInfo.insert(0,lineInfo);
|
||||
|
||||
pDisplay->SendScintilla(SCI_SETFOLDLEVEL, 0, (long)(0 | SC_FOLDLEVELHEADERFLAG));
|
||||
|
||||
if (record->size() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QStringList contents;
|
||||
|
||||
QList<int> keyworkOffsetPos;
|
||||
QString text;
|
||||
QString linePrefix;
|
||||
|
||||
|
||||
for (int i = 0,count= record->size(); i < count; ++i)
|
||||
int insertIndex = 1;
|
||||
for (int i = 0, count = record->size(); i < count; ++i)
|
||||
{
|
||||
FindRecords* pr = record->at(i);
|
||||
|
||||
QString* pFilePath = new QString(pr->findFilePath);
|
||||
QString desc;
|
||||
if (!StyleSet::isCurrentDeepStyle())
|
||||
{
|
||||
desc = tr("<font style='font-size:14px;font-weight:bold;color:#309730'>%1 (%2 hits)</font>").arg(pr->findFilePath.toHtmlEscaped()).arg(pr->records.size());
|
||||
desc = tr(" %1 (%2 hits)\n").arg(pr->findFilePath).arg(pr->records.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
desc = tr("<font style='font-size:14px;color:#99cc99'>%1 (%2 hits)</font>").arg(pr->findFilePath.toHtmlEscaped()).arg(pr->records.size());
|
||||
desc = tr(" %1 (%2 hits)\n").arg(pr->findFilePath).arg(pr->records.size());
|
||||
}
|
||||
contents.append(desc);
|
||||
m_resultLineFilePath.append(pFilePath);
|
||||
|
||||
QStandardItem* descItem = new QStandardItem(desc);
|
||||
lineInfo.level = 1;
|
||||
m_resultLineInfo.insert(insertIndex, lineInfo);
|
||||
++insertIndex;
|
||||
|
||||
if (!StyleSet::isCurrentDeepStyle())
|
||||
for (int j = 0; j < pr->records.size(); ++j)
|
||||
{
|
||||
setItemBackground(descItem, QColor(0xd5ffd5));
|
||||
}
|
||||
else
|
||||
{
|
||||
setItemBackground(descItem, QColor(0x484848));
|
||||
}
|
||||
FindRecord v = pr->records.at(j);
|
||||
QString richText = v.lineContents;
|
||||
|
||||
titleItem->insertRow(0,descItem);
|
||||
linePrefix = tr(" Line %1: ").arg(v.lineNum + 1);
|
||||
|
||||
//默认全部收起来
|
||||
if (count > 10)
|
||||
{
|
||||
ui.resultTreeView->collapse(m_model->index(0, 0, m_model->index(0, 0)));
|
||||
}
|
||||
|
||||
descItem->setData(QVariant((qlonglong)pr->pEdit), ResultItemEditor);
|
||||
descItem->setData(QVariant(pr->findFilePath), ResultItemEditorFilePath);
|
||||
descItem->setData(QVariant(pr->findText), ResultWhatFind);
|
||||
|
||||
//描述行双击不响应
|
||||
descItem->setData(QVariant(true), ResultItemDesc);
|
||||
|
||||
for (int i = 0; i < pr->records.size(); ++i)
|
||||
{
|
||||
FindRecord v = pr->records.at(i);
|
||||
QString richText = highlightFindText(v);
|
||||
|
||||
QString text;
|
||||
if (!StyleSet::isCurrentDeepStyle())
|
||||
{
|
||||
text = tr("<font style='font-size:14px;'>Line </font><font style='font-size:14px;color:#ff8040'>%1</font> : %2").arg(v.lineNum + 1).arg(richText);
|
||||
text = tr("%1%2\n").arg(linePrefix).arg(richText);
|
||||
}
|
||||
else
|
||||
{
|
||||
text = tr("<font style='font-size:14px;color:#ffffff'>Line </font><font style='font-size:14px;color:#ff8040'>%1</font> : %2").arg(v.lineNum + 1).arg(richText);
|
||||
text = tr("%1%2\n").arg(linePrefix).arg(richText);
|
||||
}
|
||||
QStandardItem* childItem = new QStandardItem(text);
|
||||
#if defined(Q_OS_MAC)
|
||||
childItem->setTextAlignment(Qt::AlignVCenter);
|
||||
#endif
|
||||
childItem->setData(QVariant(v.pos), ResultItemPos);
|
||||
childItem->setData(QVariant(v.end - v.pos), ResultItemLen);
|
||||
descItem->appendRow(childItem);
|
||||
contents.append(text);
|
||||
keyworkOffsetPos.append(linePrefix.toUtf8().size());
|
||||
lineInfo.level = 2;
|
||||
lineInfo.resultPos = v.pos;
|
||||
lineInfo.resultEnd = v.end;
|
||||
lineInfo.pFilePath = pFilePath;
|
||||
m_resultLineInfo.insert(insertIndex, lineInfo);
|
||||
++insertIndex;
|
||||
|
||||
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
|
||||
}
|
||||
if (count <= 10 && !pr->records.isEmpty())
|
||||
}
|
||||
|
||||
pDisplay->insertAt(contents.join(""), 1, 0);
|
||||
|
||||
int lineNum = 1;
|
||||
|
||||
QList<int> destFileLineNum;
|
||||
|
||||
for (int i = 0, count = record->size(); i < count; ++i)
|
||||
{
|
||||
FindRecords* pr = record->at(i);
|
||||
|
||||
pDisplay->SendScintilla(SCI_SETFOLDLEVEL, lineNum, (long)(1 | SC_FOLDLEVELHEADERFLAG));
|
||||
destFileLineNum.append(lineNum);
|
||||
++lineNum;
|
||||
|
||||
for (int j = 0; j < pr->records.size(); ++j)
|
||||
{
|
||||
ui.resultTreeView->expand(m_model->index(0, 0, m_model->index(0, 0)));
|
||||
pDisplay->SendScintilla(SCI_SETFOLDLEVEL, lineNum, (long)2| SC_FOLDLEVELBASE);
|
||||
|
||||
++lineNum;
|
||||
}
|
||||
}
|
||||
ui.resultTreeView->expand(m_model->index(0, 0, m_model->index(0, 0)));
|
||||
}
|
||||
|
||||
void FindResultWin::setItemBackground(QStandardItem* item, const QColor& color)
|
||||
{
|
||||
QBrush b(color);
|
||||
item->setBackground(b);
|
||||
}
|
||||
//着色
|
||||
pDisplay->setLineBackColorStyle(0, STYLE_COLOUR_TITLE);
|
||||
|
||||
void FindResultWin::setItemForeground(QStandardItem* item, const QColor& color)
|
||||
{
|
||||
QBrush b(color);
|
||||
item->setForeground(b);
|
||||
}
|
||||
|
||||
//查找结果框的字体变大
|
||||
void FindResultWin::slot_fontZoomIn()
|
||||
{
|
||||
QFont curFt = ui.resultTreeView->font();
|
||||
|
||||
int s = curFt.pointSize();
|
||||
s += 2;
|
||||
curFt.setPointSize(s);
|
||||
|
||||
m_defaultFontSize += 2;
|
||||
|
||||
ui.resultTreeView->setFont(curFt);
|
||||
|
||||
m_delegate->setFontSize(m_defaultFontSize);
|
||||
|
||||
m_defFontSizeChange = true;
|
||||
}
|
||||
|
||||
void FindResultWin::slot_fontZoomOut()
|
||||
{
|
||||
QFont curFt = ui.resultTreeView->font();
|
||||
|
||||
int s = curFt.pointSize();
|
||||
s -= 2;
|
||||
|
||||
if (s >= 8)
|
||||
for (int i = 0, count = destFileLineNum.size(); i < count; ++i)
|
||||
{
|
||||
m_defFontSizeChange = true;
|
||||
m_defaultFontSize -= 2;
|
||||
curFt.setPointSize(s);
|
||||
ui.resultTreeView->setFont(curFt);
|
||||
m_delegate->setFontSize(m_defaultFontSize);
|
||||
pDisplay->setLineBackColorStyle(destFileLineNum.at(i), (StyleSet::isCurrentDeepStyle()? STYLE_DEEP_COLOUR_DEST_FILE:STYLE_COLOUR_DEST_FILE));
|
||||
}
|
||||
|
||||
//关键字高亮
|
||||
//高亮的开始、结束位置
|
||||
int targetStart = 0;
|
||||
int targetLens = 0;
|
||||
lineNum = 1;
|
||||
|
||||
int lineOffsetPosIndex = 0;
|
||||
int lineOffsetPos = 0;
|
||||
|
||||
QString lineNumStr = tr(" Line ");
|
||||
int skipLineNumOffset = lineNumStr.toUtf8().size();
|
||||
|
||||
for (int i = 0, count = record->size(); i < count; ++i)
|
||||
{
|
||||
FindRecords* pr = record->at(i);
|
||||
++lineNum;
|
||||
for (int j = 0; j < pr->records.size(); ++j)
|
||||
{
|
||||
lineOffsetPos = keyworkOffsetPos.at(lineOffsetPosIndex);
|
||||
const FindRecord &v = pr->records.at(j);
|
||||
targetStart = v.pos - v.lineStartPos + lineOffsetPos;
|
||||
targetLens = v.end - v.pos;
|
||||
pDisplay->setLineColorStyle(lineNum, skipLineNumOffset, lineOffsetPos-skipLineNumOffset-2, STYLE_COLOUR_KEYWORD_HIGH);
|
||||
pDisplay->setLineColorStyle(lineNum, targetStart, targetLens, (StyleSet::isCurrentDeepStyle()? STYLE_DEEP_COLOUR_KEYWORD_HIGH:STYLE_COLOUR_KEYWORD_BACK_HIGH));
|
||||
++lineNum;
|
||||
++lineOffsetPosIndex;
|
||||
}
|
||||
}
|
||||
pDisplay->SendScintilla(SCI_GOTOLINE, 0);
|
||||
}
|
||||
|
||||
|
||||
int FindResultWin::getDefaultFontSize()
|
||||
{
|
||||
return m_defaultFontSize;
|
||||
|
@ -779,3 +493,21 @@ void FindResultWin::setDefaultFontSize(int defSize)
|
|||
{
|
||||
m_defaultFontSize = defSize;
|
||||
}
|
||||
|
||||
void FindResultWin::on_lineDoubleClick(int lineNum)
|
||||
{
|
||||
if (lineNum < m_resultLineInfo.size())
|
||||
{
|
||||
const ResultLineInfo& lineInfo = m_resultLineInfo.at(lineNum);
|
||||
|
||||
if (lineInfo.level == 2)
|
||||
{
|
||||
//文件定位到行
|
||||
emit lineDoubleClicked(lineInfo.pFilePath, lineInfo.resultPos, lineInfo.resultEnd);
|
||||
}
|
||||
else if ((lineInfo.level == 0) || (lineInfo.level == 1))
|
||||
{
|
||||
ui.displayView->SendScintilla(SCI_FOLDLINE, lineNum, SC_FOLDACTION_TOGGLE);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QContextMenuEvent>
|
||||
|
@ -6,57 +6,54 @@
|
|||
#include "ui_findresultwin.h"
|
||||
|
||||
class FindRecords;
|
||||
class QStandardItem;
|
||||
class NdStyledItemDelegate;
|
||||
class QStandardItemModel;
|
||||
struct FindRecord;
|
||||
|
||||
struct ResultLineInfo {
|
||||
int level;//缩进类型。0 1 2。0:title 1 filepath desc 2 result。
|
||||
int resultPos;//结果字段的开始offset。0和1是没有这个字段的。
|
||||
int resultEnd;//长度
|
||||
QString* pFilePath;
|
||||
};
|
||||
|
||||
class FindResultWin : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
friend class FindResultView;
|
||||
FindResultWin(QWidget *parent = Q_NULLPTR);
|
||||
~FindResultWin();
|
||||
|
||||
void appendResultsToShow(FindRecords * record);
|
||||
void appendResultsToShow(QVector<FindRecords*>* record, int hits, QString whatFind);
|
||||
int getDefaultFontSize();
|
||||
void setDefaultFontSize(int defSize);
|
||||
void clear();
|
||||
signals:
|
||||
void itemDoubleClicked(const QModelIndex &index);
|
||||
void showMsg(QString &msg);
|
||||
void lineDoubleClicked(QString* pFilePath, int pos, int end);
|
||||
|
||||
private slots:
|
||||
void slot_clearContents();
|
||||
void slot_selectAll();
|
||||
void slot_copyContents();
|
||||
void slot_copyItemContents();
|
||||
void slot_selectSection();
|
||||
void slot_treeView_pressed(QModelIndex modeIndex);
|
||||
void slot_fontZoomIn();
|
||||
void slot_fontZoomOut();
|
||||
void on_lineDoubleClick(int line);
|
||||
public slots:
|
||||
void slot_clearAllContents();
|
||||
|
||||
protected:
|
||||
void contextMenuEvent(QContextMenuEvent * event);
|
||||
|
||||
private:
|
||||
#if 0
|
||||
void setItemBackground(QStandardItem* item, const QColor& color);
|
||||
void setItemForeground(QStandardItem * item, const QColor & color);
|
||||
|
||||
void highlightFindText(int index, QString & srcText, QString & findText, Qt::CaseSensitivity cs);
|
||||
QString highlightFindText(FindRecord& record);
|
||||
#endif
|
||||
private:
|
||||
Ui::FindResultWin ui;
|
||||
QMenu *m_menu;
|
||||
QAction* m_pSelectSectonAct;
|
||||
|
||||
QStandardItemModel* m_model;
|
||||
NdStyledItemDelegate* m_delegate;
|
||||
|
||||
QWidget* m_parent;
|
||||
|
||||
QList<ResultLineInfo> m_resultLineInfo;
|
||||
QList<QString*> m_resultLineFilePath;
|
||||
|
||||
int m_defaultFontSize;
|
||||
bool m_defFontSizeChange;
|
||||
};
|
||||
|
|
|
@ -39,31 +39,13 @@
|
|||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="MyTreeView" name="resultTreeView">
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Microsoft YaHei</family>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<widget class="FindResultView" name="displayView">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Panel</enum>
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>1</number>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAsNeeded</enum>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::DoubleClicked</set>
|
||||
</property>
|
||||
<property name="animated">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="headerVisible">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
@ -71,9 +53,10 @@
|
|||
<layoutdefault spacing="6" margin="11"/>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>MyTreeView</class>
|
||||
<extends>QTreeView</extends>
|
||||
<header>mytreeview.h</header>
|
||||
<class>FindResultView</class>
|
||||
<extends>QFrame</extends>
|
||||
<header location="global">findresultview.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
|
|
288
src/findwin.cpp
|
@ -5,6 +5,7 @@
|
|||
#include "doctypelistview.h"
|
||||
#include "filemanager.h"
|
||||
#include "ccnotepad.h"
|
||||
#include "nddsetting.h"
|
||||
|
||||
#include <QMimeDatabase>
|
||||
#include <QRadioButton>
|
||||
|
@ -78,7 +79,7 @@ FindWin::~FindWin()
|
|||
{
|
||||
delete pEditTemp;
|
||||
pEditTemp = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FindWin::slot_tabIndexChange(int index)
|
||||
|
@ -277,6 +278,20 @@ void FindWin::setFindHistory(QList<QString>* findHistory)
|
|||
}
|
||||
}
|
||||
|
||||
void FindWin::setReplaceHistory(QList<QString>* replaceHistory)
|
||||
{
|
||||
m_replaceHistory = replaceHistory;
|
||||
|
||||
if ((m_replaceHistory != nullptr) && !m_replaceHistory->isEmpty())
|
||||
{
|
||||
ui.replaceWithBox->addItems(*m_replaceHistory);
|
||||
ui.replaceWithBox->clearEditText();
|
||||
ui.dirReplaceWhat->addItems(*m_replaceHistory);
|
||||
ui.dirReplaceWhat->clearEditText();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//标记高亮所有word单词
|
||||
int FindWin::markAllWord(QString & word)
|
||||
{
|
||||
|
@ -312,7 +327,7 @@ void FindWin::removeLineHeadEndBlank(int mode)
|
|||
{
|
||||
ui.replaceTextBox->setCurrentText("[ ]+$");
|
||||
}
|
||||
ui.replaceWithBox->setText("");
|
||||
ui.replaceWithBox->setEditText("");
|
||||
|
||||
ui.replaceModeRegularBt->setChecked(true);
|
||||
|
||||
|
@ -466,9 +481,9 @@ void FindWin::updateParameterFromUI()
|
|||
m_isFindFirst = true;
|
||||
}
|
||||
|
||||
if (m_replaceWithText != ui.replaceWithBox->text())
|
||||
if (m_replaceWithText != ui.replaceWithBox->currentText())
|
||||
{
|
||||
m_replaceWithText = ui.replaceWithBox->text();
|
||||
m_replaceWithText = ui.replaceWithBox->currentText();
|
||||
m_isFindFirst = true;
|
||||
}
|
||||
|
||||
|
@ -528,9 +543,9 @@ void FindWin::updateParameterFromUI()
|
|||
m_isFindFirst = true;
|
||||
}
|
||||
|
||||
if (m_replaceWithText != ui.dirReplaceWhat->text())
|
||||
if (m_replaceWithText != ui.dirReplaceWhat->currentText())
|
||||
{
|
||||
m_replaceWithText = ui.dirReplaceWhat->text();
|
||||
m_replaceWithText = ui.dirReplaceWhat->currentText();
|
||||
m_isFindFirst = true;
|
||||
}
|
||||
|
||||
|
@ -703,6 +718,55 @@ void FindWin::addFindHistory(QString &text)
|
|||
}
|
||||
}
|
||||
|
||||
void FindWin::addReplaceHistory(QString& text)
|
||||
{
|
||||
//太长会导致看起来很杂乱,也不记录
|
||||
if (text.isEmpty() || text.size() >= MAX_RECORD_KEY_LENGTH)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_replaceHistory != nullptr)
|
||||
{
|
||||
int index = m_replaceHistory->indexOf(text, 0);
|
||||
//已经是最上面一个了,直接返回
|
||||
if (0 == index)
|
||||
{
|
||||
return;
|
||||
}
|
||||
//没有直接添加到最前面。不做查找删除重复,一是慢,而是删除会引起信号逻辑时序有误
|
||||
if (-1 == index)
|
||||
{
|
||||
m_replaceHistory->push_front(text);
|
||||
ui.replaceWithBox->insertItem(0, text);
|
||||
ui.dirReplaceWhat->insertItem(0, text);
|
||||
}
|
||||
else
|
||||
{
|
||||
//有了怎么办,删除旧的,加新的
|
||||
m_replaceHistory->removeAt(index);
|
||||
m_replaceHistory->push_front(text);
|
||||
|
||||
//发现不能只删除旧的,有bug,一旦删除后,查找框乱了,被切换到下一个。
|
||||
ui.replaceWithBox->removeItem(index);
|
||||
ui.dirReplaceWhat->removeItem(index);
|
||||
ui.replaceWithBox->insertItem(0, text);
|
||||
ui.dirReplaceWhat->insertItem(0, text);
|
||||
//发现不能只删除旧的,有bug,一旦删除后,查找框乱了,被切换到下一个。
|
||||
//必须重新设置一下,否则查找框里面字段乱跳到下一个去了
|
||||
ui.replaceWithBox->setCurrentIndex(0);
|
||||
ui.dirReplaceWhat->setCurrentIndex(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (m_replaceHistory->size() >= 15)
|
||||
{
|
||||
m_replaceHistory->takeLast();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//检查是否是第一次查找,凡是参数变化了,则认定为是第一次查找。
|
||||
//因为查找分firstFirst和firstNext,则是qscint特性决定的。所以正确识别第一次查找是必要的
|
||||
bool FindWin::isFirstFind()
|
||||
|
@ -881,7 +945,7 @@ void FindWin::removeEmptyLine(bool isBlankContained)
|
|||
{
|
||||
ui.replaceTextBox->setCurrentText("^$(\\r\\n|\\r|\\n)");
|
||||
}
|
||||
ui.replaceWithBox->setText("");
|
||||
ui.replaceWithBox->setEditText("");
|
||||
|
||||
ui.replaceModeRegularBt->setChecked(true);
|
||||
|
||||
|
@ -974,8 +1038,6 @@ void FindWin::dofindNext()
|
|||
updateParameterFromUI();
|
||||
|
||||
QWidget* pw = autoAdjustCurrentEditWin();
|
||||
|
||||
|
||||
QsciScintilla* pEdit = dynamic_cast<QsciScintilla*>(pw);
|
||||
|
||||
//第一次查找
|
||||
|
@ -1100,7 +1162,7 @@ void FindWin::slot_findCount()
|
|||
//这里的forward一定要是true。回环一定是false
|
||||
if (!pEdit->findFirst(whatFind, m_re, m_cs, m_wo, false, true, FINDNEXTTYPE_FINDNEXT, 0, 0,false))
|
||||
{
|
||||
ui.statusbar->showMessage(tr("count %1 times with \'%2\'").arg(countNums).arg(m_expr), 8000);
|
||||
ui.statusbar->showMessage(tr("count %1 times with \'%2\'").arg(countNums).arg(m_expr));
|
||||
QApplication::beep();
|
||||
|
||||
m_isFindFirst = true;
|
||||
|
@ -1124,11 +1186,11 @@ void FindWin::slot_findCount()
|
|||
|
||||
pEdit->execute(SCI_GOTOPOS, srcPostion);
|
||||
pEdit->execute(SCI_SETFIRSTVISIBLELINE, firstDisLineNum);
|
||||
pEdit->execute(SCI_SETXOFFSET, 0);
|
||||
//pEdit->execute(SCI_SETXOFFSET, 0);
|
||||
|
||||
//全部替换后,下次查找,必须算第一次查找
|
||||
m_isFindFirst = true;
|
||||
ui.statusbar->showMessage(tr("count %1 times with \'%2\'").arg(countNums).arg(m_expr), 8000);
|
||||
ui.statusbar->showMessage(tr("count %1 times with \'%2\'").arg(countNums).arg(m_expr));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1170,11 +1232,16 @@ QString FindWin::addCurFindRecord(ScintillaEditView* pEdit, FindRecords& recordR
|
|||
FindState& state = pEdit->getLastFindState();
|
||||
aRecord.pos = state.targstart;
|
||||
aRecord.end = state.targend;
|
||||
aRecord.lineNum = state.linenum;
|
||||
|
||||
//mark模式不需要这么多信息,可直接返回
|
||||
if (!isMark)
|
||||
{
|
||||
aRecord.lineNum = pEdit->execute(SCI_LINEFROMPOSITION, aRecord.pos);
|
||||
//静默查找,在后台批量查找时,不会返回这个state.linenum。需要手动获取一下
|
||||
if (aRecord.lineNum == -1)
|
||||
{
|
||||
aRecord.lineNum = pEdit->execute(SCI_LINEFROMPOSITION, aRecord.pos);
|
||||
}
|
||||
aRecord.lineStartPos = pEdit->execute(SCI_POSITIONFROMLINE, aRecord.lineNum);
|
||||
int lineLens = pEdit->execute(SCI_LINELENGTH, aRecord.lineNum);
|
||||
|
||||
|
@ -1558,8 +1625,8 @@ int FindWin::findAllInCurDoc(QStringList* reResult)
|
|||
|
||||
if (!m_isStatic)
|
||||
{
|
||||
QApplication::beep();
|
||||
emit sign_findAllInCurDoc(&results);
|
||||
QApplication::beep();
|
||||
emit sign_findAllInCurDoc(&results);
|
||||
}
|
||||
|
||||
m_isFindFirst = true;
|
||||
|
@ -1609,7 +1676,7 @@ int FindWin::findAllInCurDoc(QStringList* reResult)
|
|||
|
||||
pEdit->execute(SCI_GOTOPOS, srcPostion);
|
||||
pEdit->execute(SCI_SETFIRSTVISIBLELINE, firstDisLineNum);
|
||||
pEdit->execute(SCI_SETXOFFSET, 0);
|
||||
//pEdit->execute(SCI_SETXOFFSET, 0);
|
||||
|
||||
//全部替换后,下次查找,必须算第一次查找
|
||||
m_isFindFirst = true;
|
||||
|
@ -1642,11 +1709,110 @@ int FindWin::findAllInCurDoc(QStringList* reResult)
|
|||
|
||||
void FindWin::slot_findAllInCurDoc()
|
||||
{
|
||||
findAllInCurDoc();
|
||||
//findAllInCurDoc();
|
||||
|
||||
int index = m_editTabWidget->currentIndex();
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
findAllInOpenDoc(index);
|
||||
}
|
||||
}
|
||||
|
||||
void FindWin::findAllInOpenDoc(int index)
|
||||
{
|
||||
if (ui.findComboBox->currentText().isEmpty())
|
||||
{
|
||||
ui.statusbar->showMessage(tr("what find is null !"), 8000);
|
||||
QApplication::beep();
|
||||
return;
|
||||
}
|
||||
|
||||
QString whatFind = ui.findComboBox->currentText();
|
||||
QString originWhatFine = whatFind;
|
||||
|
||||
if (m_extend)
|
||||
{
|
||||
QString extendFind;
|
||||
convertExtendedToString(whatFind, extendFind);
|
||||
whatFind = extendFind;
|
||||
}
|
||||
|
||||
int replaceNums = 0;
|
||||
QVector<FindRecords*>* allOpenFileRecord = new QVector<FindRecords*>();
|
||||
|
||||
for (int i = 0; i < m_editTabWidget->count(); ++i)
|
||||
{
|
||||
//是否只查找一个文档
|
||||
if ((index != -1) && (i != index))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
QWidget* pw = m_editTabWidget->widget(i);
|
||||
ScintillaEditView* pEdit = dynamic_cast<ScintillaEditView*>(pw);
|
||||
if (pEdit != nullptr)
|
||||
{
|
||||
if (pEdit->isReadOnly())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
FindRecords* results = new FindRecords();
|
||||
results->pEdit = pEdit;
|
||||
|
||||
results->findFilePath = pw->property("filePath").toString();
|
||||
|
||||
updateParameterFromUI();
|
||||
|
||||
//无条件进行第一次查找,从0行0列开始查找,而且不回环。如果没有找到,则替换完毕
|
||||
//results->findText要是有原来的值,因为扩展模式下\r\n不会转义,直接输出会换行显示
|
||||
results->findText = originWhatFine;
|
||||
if (!pEdit->findFirst(whatFind, m_re, m_cs, m_wo, false, true, FINDNEXTTYPE_FINDNEXT, 0, 0))
|
||||
{
|
||||
delete results;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
dealWithZeroFound(pEdit);
|
||||
}
|
||||
addCurFindRecord(pEdit, *results);
|
||||
|
||||
++replaceNums;
|
||||
|
||||
//找到了,把结果收集起来
|
||||
while (pEdit->findNext())
|
||||
{
|
||||
addCurFindRecord(pEdit, *results);
|
||||
++replaceNums;
|
||||
dealWithZeroFound(pEdit);
|
||||
}
|
||||
|
||||
allOpenFileRecord->append(results);
|
||||
}
|
||||
}
|
||||
|
||||
//全部替换后,下次查找,必须算第一次查找
|
||||
m_isFindFirst = true;
|
||||
ui.statusbar->showMessage(tr("find finished, total %1 found!").arg(replaceNums), 10000);
|
||||
|
||||
emit sign_findAllInOpenDoc(allOpenFileRecord, replaceNums, whatFind);
|
||||
|
||||
//释放元素
|
||||
for (int i = 0; i < allOpenFileRecord->size(); ++i)
|
||||
{
|
||||
delete allOpenFileRecord->at(i);
|
||||
}
|
||||
|
||||
delete allOpenFileRecord;
|
||||
|
||||
}
|
||||
|
||||
void FindWin::slot_findAllInOpenDoc()
|
||||
{
|
||||
findAllInOpenDoc(-1);
|
||||
|
||||
#if 0
|
||||
if (ui.findComboBox->currentText().isEmpty())
|
||||
{
|
||||
ui.statusbar->showMessage(tr("what find is null !"), 8000);
|
||||
|
@ -1726,7 +1892,7 @@ void FindWin::slot_findAllInOpenDoc()
|
|||
}
|
||||
|
||||
delete allOpenFileRecord;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
//返回是否查找得到内容
|
||||
|
@ -1744,6 +1910,9 @@ bool FindWin::replaceFindNext(QsciScintilla* pEdit, bool showZeroFindTip)
|
|||
|
||||
addFindHistory(whatFind);
|
||||
|
||||
QString replaceWith = ui.replaceWithBox->currentText();
|
||||
addReplaceHistory(replaceWith);
|
||||
|
||||
if (m_extend)
|
||||
{
|
||||
QString extendFind;
|
||||
|
@ -1820,7 +1989,7 @@ bool FindWin::replace(ScintillaEditView* pEdit)
|
|||
}
|
||||
|
||||
QString findText = ui.replaceTextBox->currentText();
|
||||
QString replaceText = ui.replaceWithBox->text();
|
||||
QString replaceText = ui.replaceWithBox->currentText();
|
||||
|
||||
if (m_extend)
|
||||
{
|
||||
|
@ -2083,7 +2252,7 @@ int FindWin::doReplaceAll(ScintillaEditView* pEdit, QString &whatFind, QString&
|
|||
|
||||
if (isCombineUndo)
|
||||
{
|
||||
pEdit->execute(SCI_BEGINUNDOACTION);
|
||||
pEdit->execute(SCI_BEGINUNDOACTION);
|
||||
}
|
||||
|
||||
int flags = buildSearchFlags(m_re, m_cs, m_wo, false, true, FINDNEXTTYPE_REPLACENEXT, 0, 0);
|
||||
|
@ -2147,14 +2316,12 @@ int FindWin::doReplaceAll(ScintillaEditView* pEdit, QString &whatFind, QString&
|
|||
|
||||
if (isCombineUndo)
|
||||
{
|
||||
pEdit->execute(SCI_ENDUNDOACTION);
|
||||
pEdit->execute(SCI_ENDUNDOACTION);
|
||||
}
|
||||
|
||||
pEdit->execute(SCI_GOTOPOS, srcPostion);
|
||||
pEdit->execute(SCI_SETFIRSTVISIBLELINE, firstDisLineNum);
|
||||
pEdit->execute(SCI_SETXOFFSET, 0);
|
||||
|
||||
|
||||
//pEdit->execute(SCI_SETXOFFSET, 0);
|
||||
|
||||
return replaceNums;
|
||||
}
|
||||
|
@ -2186,7 +2353,7 @@ int FindWin::replaceAll()
|
|||
updateParameterFromUI();
|
||||
|
||||
QString whatFind = ui.replaceTextBox->currentText();
|
||||
QString replaceText = ui.replaceWithBox->text();
|
||||
QString replaceText = ui.replaceWithBox->currentText();
|
||||
|
||||
if (m_extend)
|
||||
{
|
||||
|
@ -2290,7 +2457,7 @@ void FindWin::slot_replaceAllInOpenDoc()
|
|||
ui.statusbar->showMessage(tr("Replace in Opened Files: %1 occurrences were replaced.").arg(replaceNums), 10000);
|
||||
}
|
||||
|
||||
int FindWin::markAll()
|
||||
int FindWin::markAll(QSet<int>* outLineNum)
|
||||
{
|
||||
if (ui.markTextBox->currentText().isEmpty())
|
||||
{
|
||||
|
@ -2367,6 +2534,11 @@ int FindWin::markAll()
|
|||
pEdit->execute(SCI_SETINDICATORCURRENT, CCNotePad::s_curMarkColorId);
|
||||
pEdit->execute(SCI_INDICATORFILLRANGE, rs.pos, foundTextLen);
|
||||
}
|
||||
|
||||
if (outLineNum != nullptr)
|
||||
{
|
||||
outLineNum->insert(rs.lineNum);
|
||||
}
|
||||
}
|
||||
|
||||
if (!results->records.isEmpty())
|
||||
|
@ -2374,15 +2546,15 @@ int FindWin::markAll()
|
|||
pEdit->appendMarkRecord(results);
|
||||
}
|
||||
|
||||
|
||||
pEdit->execute(SCI_SETFIRSTVISIBLELINE, firstDisLineNum);
|
||||
pEdit->execute(SCI_GOTOPOS, srcPostion);
|
||||
pEdit->execute(SCI_SETXOFFSET, 0);
|
||||
pEdit->execute(SCI_SETFIRSTVISIBLELINE, firstDisLineNum);
|
||||
//pEdit->execute(SCI_SETXOFFSET, 0);
|
||||
|
||||
//全部替换后,下次查找,必须算第一次查找
|
||||
m_isFindFirst = true;
|
||||
ui.statusbar->showMessage(tr("mark finished, total %1 found!").arg(replaceNums), 10000);
|
||||
|
||||
|
||||
return replaceNums;
|
||||
}
|
||||
else
|
||||
|
@ -2431,6 +2603,10 @@ void FindWin::slot_dirSelectDest()
|
|||
QString curDirPath = ui.destFindDir->text();
|
||||
if (curDirPath.isEmpty())
|
||||
{
|
||||
if (CCNotePad::s_lastOpenDirPath.isEmpty())
|
||||
{
|
||||
CCNotePad::s_lastOpenDirPath = NddSetting::getKeyValueFromDelaySets(LAST_OPEN_DIR);
|
||||
}
|
||||
curDirPath = CCNotePad::s_lastOpenDirPath;
|
||||
}
|
||||
|
||||
|
@ -2517,31 +2693,15 @@ bool FindWin::replaceTextInFile(QString &filePath, int &replaceNums, QVector<Fin
|
|||
replace = extendReplace;
|
||||
}
|
||||
|
||||
replaceNums += doReplaceAll(pEditTemp, find, replace);
|
||||
int modifyTimes = doReplaceAll(pEditTemp, find, replace);
|
||||
|
||||
#if 0
|
||||
if (!pEditTemp->findFirst(find, m_re, m_cs, m_wo, false, m_forward, FINDNEXTTYPE_REPLACENEXT,0, 0,false))
|
||||
if (modifyTimes > 0)
|
||||
{
|
||||
return false;
|
||||
replaceNums += modifyTimes;
|
||||
//如果进行过替换,则必须要保存一下;否则不能保存,不然文件被修改。
|
||||
emit sign_replaceSaveFile(filePath, pEditTemp);
|
||||
}
|
||||
|
||||
pEditTemp->replace(replace);
|
||||
dealWithZeroFound(pEditTemp);
|
||||
|
||||
++replaceNums;
|
||||
|
||||
//找到了,则自动进行全部替换
|
||||
while (pEditTemp->findNext())
|
||||
{
|
||||
pEditTemp->replace(replace);
|
||||
++replaceNums;
|
||||
dealWithZeroFound(pEditTemp);
|
||||
}
|
||||
#endif
|
||||
|
||||
//必须要保存一下
|
||||
emit sign_replaceSaveFile(filePath, pEditTemp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2853,7 +3013,7 @@ void FindWin::slot_dirFindAll()
|
|||
|
||||
if (pEditTemp == nullptr)
|
||||
{
|
||||
pEditTemp = new ScintillaEditView(nullptr);
|
||||
pEditTemp = ScintillaEditView::createEditForSearch();
|
||||
}
|
||||
|
||||
int foundNums = 0;
|
||||
|
@ -2865,7 +3025,7 @@ void FindWin::slot_dirFindAll()
|
|||
|
||||
//全部替换后,下次查找,必须算第一次查找
|
||||
m_isFindFirst = true;
|
||||
ui.statusbar->showMessage(tr("find finished, total %1 found in %2 file!").arg(foundNums).arg(filesNum), 10000);
|
||||
ui.statusbar->showMessage(tr("find finished, walk %1 files, total %2 found in %3 file!").arg(filesNum).arg(foundNums).arg(allfileInDirRecord->size()));
|
||||
|
||||
//复用了这个信号函数,没有新做消息,要注意
|
||||
emit sign_findAllInOpenDoc(allfileInDirRecord, foundNums, whatFind);
|
||||
|
@ -2887,7 +3047,7 @@ void FindWin::slot_dirReplaceAll()
|
|||
{
|
||||
QString dirPath = ui.destFindDir->text();
|
||||
QString whatFind = ui.dirFindWhat->currentText();
|
||||
QString dirReplaceWhat = ui.dirReplaceWhat->text();
|
||||
QString dirReplaceWhat = ui.dirReplaceWhat->currentText();
|
||||
|
||||
if (dirPath.isEmpty())
|
||||
{
|
||||
|
@ -2969,12 +3129,15 @@ void FindWin::slot_dirReplaceAll()
|
|||
int skipMaxSize = (ui.skipFileMaxSize->isChecked()) ? ui.maxFileSizeSpinBox->value() * 1024 * 1024 : 0;
|
||||
bool isSkipChildDir = ui.skipChildDirs->isChecked();
|
||||
|
||||
addReplaceHistory(dirReplaceWhat);
|
||||
|
||||
updateParameterFromUI();
|
||||
|
||||
if (pEditTemp == nullptr)
|
||||
{
|
||||
pEditTemp = new ScintillaEditView(nullptr);
|
||||
pEditTemp = ScintillaEditView::createEditForSearch();
|
||||
}
|
||||
|
||||
int replaceNums = 0;
|
||||
|
||||
std::function<bool(QString &, int &, QVector<FindRecords*>* allfileInDirRecord)> foundCallBack = std::bind(&FindWin::replaceTextInFile, this, std::placeholders::_1, std::placeholders::_2, nullptr);
|
||||
|
@ -2983,7 +3146,7 @@ void FindWin::slot_dirReplaceAll()
|
|||
|
||||
//全部替换后,下次查找,必须算第一次查找
|
||||
m_isFindFirst = true;
|
||||
ui.statusbar->showMessage(tr("replace finished, total %1 replace in %2 file!").arg(replaceNums).arg(filesNum), 10000);
|
||||
ui.statusbar->showMessage(tr("replace finished, walk %1 files, total %2 replace !").arg(filesNum).arg(replaceNums));
|
||||
}
|
||||
|
||||
|
||||
|
@ -3004,4 +3167,19 @@ void FindWin::on_copyReFindResult()
|
|||
QClipboard* clipboard = QApplication::clipboard();
|
||||
clipboard->setText(reResult.join("\n"));
|
||||
}
|
||||
}
|
||||
|
||||
void FindWin::on_markAndBook()
|
||||
{
|
||||
QSet<int> outLineNum;
|
||||
markAll(&outLineNum);
|
||||
|
||||
QWidget* pw = autoAdjustCurrentEditWin();
|
||||
ScintillaEditView* pEdit = dynamic_cast<ScintillaEditView*>(pw);
|
||||
|
||||
if (pEdit != nullptr)
|
||||
{
|
||||
pEdit->bookmarkAdd(outLineNum);
|
||||
}
|
||||
|
||||
}
|
|
@ -69,6 +69,7 @@ public:
|
|||
void setMarkFindText(QString& text);
|
||||
void disableReplace();
|
||||
void setFindHistory(QList<QString>* findHistory);
|
||||
void setReplaceHistory(QList<QString>* replaceHistory);
|
||||
int markAllWord(QString& word);
|
||||
void removeLineHeadEndBlank(int mode);
|
||||
static void showCallTip(QsciScintilla * pEdit, int pos);
|
||||
|
@ -97,6 +98,7 @@ signals:
|
|||
private:
|
||||
void updateParameterFromUI();
|
||||
void addFindHistory(QString & text);
|
||||
void addReplaceHistory(QString& text);
|
||||
bool isFirstFind();
|
||||
|
||||
QString addCurFindRecord(ScintillaEditView * pEdit, FindRecords & recordRet, bool isMark=false, bool getResult=false);
|
||||
|
@ -125,10 +127,12 @@ private:
|
|||
|
||||
int replaceAll();
|
||||
|
||||
int markAll();
|
||||
int markAll(QSet<int>* outLineNum=nullptr);
|
||||
|
||||
int findAllInCurDoc(QStringList * reResult=nullptr);
|
||||
|
||||
void findAllInOpenDoc(int index = -1);
|
||||
|
||||
private slots:
|
||||
|
||||
void slot_findNext();
|
||||
|
@ -173,6 +177,8 @@ private slots:
|
|||
|
||||
void on_copyReFindResult();
|
||||
|
||||
void on_markAndBook();
|
||||
|
||||
private:
|
||||
Ui::FindWin ui;
|
||||
|
||||
|
@ -216,6 +222,8 @@ private:
|
|||
|
||||
QList<QString>* m_findHistory;
|
||||
|
||||
QList<QString>* m_replaceHistory;
|
||||
|
||||
ScintillaEditView* pEditTemp;
|
||||
|
||||
QWidget* m_curEditWin;
|
||||
|
|
169
src/findwin.ui
|
@ -403,13 +403,7 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="replaceWithBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<widget class="QComboBox" name="replaceWithBox">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>300</width>
|
||||
|
@ -422,6 +416,12 @@
|
|||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="maxCount">
|
||||
<number>512</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
@ -759,48 +759,7 @@
|
|||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="fileType">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>300</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>350</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>*.c:*.cpp:*.h</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="dealFileType">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>File Type :</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
|
@ -813,20 +772,7 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="skipDir">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Skip Dir Name :</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="skipDirNames">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
|
@ -854,8 +800,24 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="dirReplaceWhat">
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="skipDir">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Skip Dir Name :</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="fileType">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
|
@ -874,6 +836,35 @@
|
|||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>*.c:*.cpp:*.h</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="dealFileType">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>File Type :</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="dirReplaceWhat">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>300</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
@ -1312,6 +1303,25 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>28</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Mark & Bookmark</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="markClearBox">
|
||||
<property name="sizePolicy">
|
||||
|
@ -1410,7 +1420,6 @@
|
|||
<tabstop>findModeExtendBt</tabstop>
|
||||
<tabstop>findModeRegularBt</tabstop>
|
||||
<tabstop>replaceTextBox</tabstop>
|
||||
<tabstop>replaceWithBox</tabstop>
|
||||
<tabstop>replaceFindNextBox</tabstop>
|
||||
<tabstop>replaceBt</tabstop>
|
||||
<tabstop>replaceAllBt</tabstop>
|
||||
|
@ -1425,7 +1434,6 @@
|
|||
<tabstop>replaceModeRegularBt</tabstop>
|
||||
<tabstop>destFindDir</tabstop>
|
||||
<tabstop>dirFindWhat</tabstop>
|
||||
<tabstop>dirReplaceWhat</tabstop>
|
||||
<tabstop>selectDir</tabstop>
|
||||
<tabstop>dirFindAll</tabstop>
|
||||
<tabstop>dirReplaceAll</tabstop>
|
||||
|
@ -1627,8 +1635,8 @@
|
|||
<slot>slot_clearMark()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>489</x>
|
||||
<y>84</y>
|
||||
<x>672</x>
|
||||
<y>129</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>588</x>
|
||||
|
@ -1643,8 +1651,8 @@
|
|||
<slot>close()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>572</x>
|
||||
<y>162</y>
|
||||
<x>672</x>
|
||||
<y>197</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>404</x>
|
||||
|
@ -1755,8 +1763,8 @@
|
|||
<slot>slot_clearAllMark()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>538</x>
|
||||
<y>112</y>
|
||||
<x>672</x>
|
||||
<y>163</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>574</x>
|
||||
|
@ -1780,6 +1788,22 @@
|
|||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>pushButton</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>FindWin</receiver>
|
||||
<slot>on_markAndBook()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>565</x>
|
||||
<y>77</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>434</x>
|
||||
<y>386</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
<slots>
|
||||
<slot>slot_findNext()</slot>
|
||||
|
@ -1799,5 +1823,6 @@
|
|||
<slot>slot_findPrev()</slot>
|
||||
<slot>slot_clearAllMark()</slot>
|
||||
<slot>on_copyReFindResult()</slot>
|
||||
<slot>on_markAndBook()</slot>
|
||||
</slots>
|
||||
</ui>
|
||||
|
|
|
@ -121,8 +121,12 @@ class MyApplication : public QApplication
|
|||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
//可以防止某些屏幕下的字体拥挤重叠问题
|
||||
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
//可以防止某些屏幕下的字体拥挤重叠问题。暂时屏蔽,不使用qt方法,使用windows自带方案
|
||||
// 发现windows自带方案模糊。//发现下面打开后,在win10上反而效果不好,界面会变得很大,默认还是不开启的好。
|
||||
//QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
//QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
//QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::RoundPreferFloor);
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
MyApplication a(argc, argv);
|
||||
#else
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
#include "markdownview.h"
|
||||
|
||||
MarkdownView::MarkdownView(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
{
|
||||
ui.setupUi(this);
|
||||
}
|
||||
|
||||
MarkdownView::~MarkdownView()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void MarkdownView::viewMarkdown(QString& text)
|
||||
{
|
||||
ui.textEdit->setMarkdown(text);
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
#include <QMainWindow>
|
||||
#include "ui_markdownview.h"
|
||||
|
||||
class MarkdownView : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MarkdownView(QWidget *parent = nullptr);
|
||||
~MarkdownView();
|
||||
void viewMarkdown(QString& text);
|
||||
|
||||
private:
|
||||
Ui::MarkdownViewClass ui;
|
||||
};
|
|
@ -0,0 +1,65 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MarkdownViewClass</class>
|
||||
<widget class="QMainWindow" name="MarkdownViewClass">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1134</width>
|
||||
<height>712</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MarkdownView</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralWidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QTextEdit" name="textEdit">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menuBar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1134</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QToolBar" name="mainToolBar">
|
||||
<attribute name="toolBarArea">
|
||||
<enum>TopToolBarArea</enum>
|
||||
</attribute>
|
||||
<attribute name="toolBarBreak">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusBar"/>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,25 @@
|
|||
#include "nddpluginapi.h"
|
||||
#include "ccnotepad.h"
|
||||
|
||||
NddPluginApi::NddPluginApi(QObject *parent)
|
||||
: QObject(parent)
|
||||
{}
|
||||
|
||||
NddPluginApi::~NddPluginApi()
|
||||
{}
|
||||
|
||||
void NddPluginApi::setMainNotePad(QWidget * pWidget)
|
||||
{
|
||||
m_mainNotePad = pWidget;
|
||||
}
|
||||
|
||||
//注意这里实际返回的是ScintillaEditView
|
||||
QsciScintilla* NddPluginApi::getCurrentEidtHandle()
|
||||
{
|
||||
CCNotePad* pNotepad = dynamic_cast<CCNotePad*>(m_mainNotePad);
|
||||
if (pNotepad != nullptr)
|
||||
{
|
||||
return pNotepad->getCurEditView();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QMap>
|
||||
#include <QVariant>
|
||||
|
||||
//这个类供插件中调用,务必要保证该类的ABI兼容性。
|
||||
//这意味着,不能随意增加删除该类中的函数和成员变量;否则会导致插件无法兼容。
|
||||
//不使用除虚函数之外的任何虚函数
|
||||
//理论上最好一个插件,对应一个该对象。这样不会冲突。
|
||||
|
||||
class QsciScintilla;
|
||||
|
||||
class NddPluginApi : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
NddPluginApi(QObject *parent);
|
||||
~NddPluginApi();
|
||||
|
||||
//获取当前编辑框的对象这个一定要每次动态获取。这里也有问题,一旦QsciScintilla修改,还是不能起到ABI兼容。
|
||||
//尽量依赖不需要改动的部分。
|
||||
|
||||
void setMainNotePad(QWidget* pWidget);
|
||||
|
||||
//有了这个当前编辑框后,就可以动态做许多事情了。但是前提是QsciScintilla基类不能随意修改。
|
||||
QsciScintilla* getCurrentEidtHandle();
|
||||
|
||||
|
||||
|
||||
//这个里面的成员函数要特别小心,一旦给定,则顺序和参数不能随意修改。只能依次往后增加、不能删除。
|
||||
public:
|
||||
//使用动态参数进行参数的传递。使用public传递成员参数
|
||||
QMap<QString, QVariant> m_parameter;
|
||||
QWidget* m_mainNotePad;
|
||||
};
|
|
@ -90,10 +90,10 @@ void NddSetting::init()
|
|||
//开启自动缩进
|
||||
addKeyValueToNumSets(INDENT_KEY, 0);
|
||||
|
||||
//显示空白
|
||||
//显示空白。0都不显示 1 单显示空格 2 单显示行尾 3 都显示
|
||||
addKeyValueToNumSets(SHOWSPACE_KEY, 0);
|
||||
|
||||
//最大文本文件的门限。默认100M.(50-300)
|
||||
//最大文本文件的门限。默认100M.(50-600)
|
||||
addKeyValueToNumSets(MAX_BIG_TEXT, 100);
|
||||
|
||||
addKeyValueToSets(SOFT_KEY, "0");
|
||||
|
@ -368,3 +368,18 @@ bool NddSetting::updataKeyValueFromDelaySets(QString key, QString value)
|
|||
s_isContentChanged = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
//写一个总的获取配置的接口,避免以后每个字段都需要写一个读写接口
|
||||
int NddSetting::getKeyValueFromDelayNumSets(QString key)
|
||||
{
|
||||
nddDelaySetInit();
|
||||
return s_nddDelaySet->value(key, "").toInt();
|
||||
}
|
||||
|
||||
bool NddSetting::updataKeyValueFromDelayNumSets(QString key, int value)
|
||||
{
|
||||
nddDelaySetInit();
|
||||
s_nddDelaySet->setValue(key, value);
|
||||
s_isContentChanged = true;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@ static QString FIND_RESULT_FONT_SIZE = "frfs";//查找结果的默认字体大
|
|||
static QString LAST_ACTION_TAB_INDEX = "lati";//上次关闭时,当前激活的tab标签页序号
|
||||
|
||||
static QString RECENT_OPEN_FILE = "recentopenfile";
|
||||
static QString LAST_OPEN_DIR = "lastdir";
|
||||
static QString CLEAR_OPENFILE_ON_CLOSE = "clearopenfile"; //关闭时清空历史文件
|
||||
|
||||
|
||||
//下面这个是winpos.ini中的key,避免单个文件太大,拖慢启动速度
|
||||
|
@ -65,6 +67,10 @@ public:
|
|||
|
||||
static bool updataKeyValueFromDelaySets(QString key, QString value);
|
||||
|
||||
static int getKeyValueFromDelayNumSets(QString key);
|
||||
|
||||
static bool updataKeyValueFromDelayNumSets(QString key, int value);
|
||||
|
||||
static bool isDbExist()
|
||||
{
|
||||
return s_isExistDb;
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
#include "ndstyleditemdelegate.h"
|
||||
#include <QTextDocument>
|
||||
#include <QApplication>
|
||||
#include <QAbstractTextDocumentLayout>
|
||||
#include <QPainter>
|
||||
#include <QTextEdit>
|
||||
|
||||
NdStyledItemDelegate::NdStyledItemDelegate(QObject *parent)
|
||||
: QStyledItemDelegate(parent), m_defaultFontSize(14)
|
||||
{
|
||||
}
|
||||
|
||||
NdStyledItemDelegate::~NdStyledItemDelegate()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void NdStyledItemDelegate::setFontSize(int size)
|
||||
{
|
||||
m_defaultFontSize = size;
|
||||
|
||||
}
|
||||
|
||||
//重载使可以支持富文本格式的文字
|
||||
void NdStyledItemDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const
|
||||
{
|
||||
QStyleOptionViewItem viewOption(option);
|
||||
initStyleOption(&viewOption, index);
|
||||
if (option.state.testFlag(QStyle::State_HasFocus))
|
||||
viewOption.state = viewOption.state ^ QStyle::State_HasFocus;
|
||||
|
||||
// ... 省略
|
||||
// 设置显示文本为空,使用默认样式
|
||||
QStyle *pStyle = viewOption.widget ? viewOption.widget->style() : QApplication::style();
|
||||
|
||||
QTextDocument doc;
|
||||
|
||||
//外部修改了字体大小后,内部进行富文本的修改绘制。
|
||||
if (m_defaultFontSize != 14)
|
||||
{
|
||||
viewOption.text.replace("font-size:14px",QString("font-size:%1px").arg(m_defaultFontSize));
|
||||
}
|
||||
|
||||
doc.setHtml(viewOption.text);
|
||||
|
||||
viewOption.text.clear();
|
||||
|
||||
pStyle->drawControl(QStyle::CE_ItemViewItem, &viewOption, painter, viewOption.widget);
|
||||
|
||||
QAbstractTextDocumentLayout::PaintContext paintContext;
|
||||
|
||||
QRect textRect = pStyle->subElementRect(QStyle::SE_ItemViewItemText, &viewOption);
|
||||
painter->save();
|
||||
// 坐标变换,将左上角设置为原点
|
||||
painter->translate(textRect.topLeft());
|
||||
// 设置HTML绘制区域
|
||||
painter->setClipRect(textRect.translated(-textRect.topLeft()));
|
||||
|
||||
doc.documentLayout()->draw(painter, paintContext);
|
||||
|
||||
painter->restore();
|
||||
}
|
|
@ -5,6 +5,6 @@ class QMenu;
|
|||
class QsciScintilla;
|
||||
class QWidget;
|
||||
|
||||
typedef int (*NDD_PROC_MAIN_CALLBACK)(QWidget* parent, const QString& strFileName, std::function<QsciScintilla*()>getCurEdit, NDD_PROC_DATA* procData);
|
||||
typedef int (*NDD_PROC_MAIN_CALLBACK)(QWidget* parent, const QString& strFileName, std::function<QsciScintilla*()>getCurEdit, std::function<bool(int, void*)>, NDD_PROC_DATA* procData);
|
||||
|
||||
int loadProc(const QString& strDirOut, std::function<void(NDD_PROC_DATA&, QMenu*)> funcallback, QMenu* pUserData);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
TEMPLATE = lib
|
||||
LANGUAGE = C++
|
||||
|
||||
CONFIG += qt warn_on
|
||||
CONFIG += qt warn_on Release
|
||||
QT += core gui widgets
|
||||
|
||||
HEADERS += *.h
|
||||
|
|
|
@ -4,6 +4,9 @@
|
|||
#include <functional>
|
||||
#include <qsciscintilla.h>
|
||||
#include "qttestclass.h"
|
||||
#ifdef WIN32
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
#define NDD_EXPORTDLL
|
||||
|
||||
|
@ -22,7 +25,7 @@
|
|||
#endif
|
||||
|
||||
NDD_EXPORT bool NDD_PROC_IDENTIFY(NDD_PROC_DATA* pProcData);
|
||||
NDD_EXPORT int NDD_PROC_MAIN(QWidget* pNotepad, const QString& strFileName, std::function<QsciScintilla* ()>getCurEdit, NDD_PROC_DATA* procData);
|
||||
NDD_EXPORT int NDD_PROC_MAIN(QWidget* pNotepad, const QString& strFileName, std::function<QsciScintilla* ()>getCurEdit, std::function<bool(int, void*)> pluginCallBack, NDD_PROC_DATA* procData);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -32,6 +35,7 @@
|
|||
static NDD_PROC_DATA s_procData;
|
||||
static QWidget* s_pMainNotepad = nullptr;
|
||||
std::function<QsciScintilla* ()> s_getCurEdit;
|
||||
std::function<bool(int, void*)> s_invokeMainFun;
|
||||
|
||||
bool NDD_PROC_IDENTIFY(NDD_PROC_DATA* pProcData)
|
||||
{
|
||||
|
@ -40,7 +44,7 @@ bool NDD_PROC_IDENTIFY(NDD_PROC_DATA* pProcData)
|
|||
return false;
|
||||
}
|
||||
pProcData->m_strPlugName = QObject::tr("Hello World Plug");
|
||||
pProcData->m_strComment = QObject::tr("char to Upper.");
|
||||
pProcData->m_strComment = QObject::tr(u8"不需要创建二级菜单的插件例子");
|
||||
|
||||
pProcData->m_version = QString("v1.0");
|
||||
pProcData->m_auther = QString("zuowei.yin");
|
||||
|
@ -54,9 +58,10 @@ bool NDD_PROC_IDENTIFY(NDD_PROC_DATA* pProcData)
|
|||
//pNotepad:就是CCNotepad的主界面指针
|
||||
//strFileName:当前插件DLL的全路径,如果不关心,则可以不使用
|
||||
//getCurEdit:从NDD主程序传递过来的仿函数,通过该函数获取当前编辑框操作对象QsciScintilla
|
||||
//s_invokeMainFun: 可以回调NDD主程序中的功能函数,比如创建新文件功能等,根据需要可实时扩展。
|
||||
//pProcData:如果pProcData->m_menuType = 0 ,则该指针为空;如果pProcData->m_menuType = 1,则该指针有值。目前需要关心s_procData.m_rootMenu
|
||||
//开发者可以在该菜单下面,自行创建二级菜单
|
||||
int NDD_PROC_MAIN(QWidget* pNotepad, const QString &strFileName, std::function<QsciScintilla*()>getCurEdit, NDD_PROC_DATA* pProcData)
|
||||
int NDD_PROC_MAIN(QWidget* pNotepad, const QString &strFileName, std::function<QsciScintilla*()>getCurEdit, std::function<bool(int, void*)> pluginCallBack, NDD_PROC_DATA* pProcData)
|
||||
{
|
||||
QsciScintilla* pEdit = getCurEdit();
|
||||
if (pEdit == nullptr)
|
||||
|
@ -72,6 +77,7 @@ int NDD_PROC_MAIN(QWidget* pNotepad, const QString &strFileName, std::function<Q
|
|||
|
||||
s_pMainNotepad = pNotepad;
|
||||
s_getCurEdit = getCurEdit;
|
||||
s_invokeMainFun = pluginCallBack;
|
||||
|
||||
//如果pProcData->m_menuType = 1;是自己要创建二级菜单的场景。则通过s_procData.m_rootMenu 获取该插件的菜单根节点。
|
||||
//插件开发者自行在s_procData.m_rootMenu下添加新的二级菜单项目
|
||||
|
@ -85,3 +91,26 @@ int NDD_PROC_MAIN(QWidget* pNotepad, const QString &strFileName, std::function<Q
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
BOOL WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, LPVOID lpvReserved) {
|
||||
switch (fdwReason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
break;
|
||||
case DLL_THREAD_DETACH:
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
if (NULL == lpvReserved) {
|
||||
//做全局回收工作
|
||||
}
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#else
|
||||
void onDllUnload(void)
|
||||
{
|
||||
//做全局回收工作
|
||||
}
|
||||
#endif
|
|
@ -4,6 +4,9 @@
|
|||
#include <functional>
|
||||
#include <qsciscintilla.h>
|
||||
#include <QAction>
|
||||
#ifdef WIN32
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
#define NDD_EXPORTDLL
|
||||
|
||||
|
@ -22,7 +25,7 @@
|
|||
#endif
|
||||
|
||||
NDD_EXPORT bool NDD_PROC_IDENTIFY(NDD_PROC_DATA* pProcData);
|
||||
NDD_EXPORT int NDD_PROC_MAIN(QWidget* pNotepad, const QString& strFileName, std::function<QsciScintilla* ()>getCurEdit, NDD_PROC_DATA* procData);
|
||||
NDD_EXPORT int NDD_PROC_MAIN(QWidget* pNotepad, const QString& strFileName, std::function<QsciScintilla* ()>getCurEdit, std::function<bool(int, void*)> pluginCallBack, NDD_PROC_DATA* procData);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -31,6 +34,7 @@
|
|||
static NDD_PROC_DATA s_procData;
|
||||
static QWidget* s_pMainNotepad = nullptr;
|
||||
std::function<QsciScintilla* ()> s_getCurEdit;
|
||||
std::function<bool(int, void*)> s_invokeMainFun;
|
||||
|
||||
bool NDD_PROC_IDENTIFY(NDD_PROC_DATA* pProcData)
|
||||
{
|
||||
|
@ -38,8 +42,8 @@ bool NDD_PROC_IDENTIFY(NDD_PROC_DATA* pProcData)
|
|||
{
|
||||
return false;
|
||||
}
|
||||
pProcData->m_strPlugName = QObject::tr("Test Plug");
|
||||
pProcData->m_strComment = QObject::tr("char to lower.");
|
||||
pProcData->m_strPlugName = QObject::tr("Create Second Menu Plug");
|
||||
pProcData->m_strComment = QObject::tr(u8"创建二级菜单的插件例子");
|
||||
|
||||
pProcData->m_version = QString("v1.0");
|
||||
pProcData->m_auther = QString("zuowei.yin");
|
||||
|
@ -53,8 +57,9 @@ bool NDD_PROC_IDENTIFY(NDD_PROC_DATA* pProcData)
|
|||
//strFileName:当前插件DLL的全路径,如果不关心,则可以不使用
|
||||
//getCurEdit:从NDD主程序传递过来的仿函数,通过该函数获取当前编辑框操作对象QsciScintilla
|
||||
//pProcData:如果pProcData->m_menuType = 0 ,则该指针为空;如果pProcData->m_menuType = 1,则该指针有值。目前需要关心s_procData.m_rootMenu
|
||||
//开发者可以在该菜单下面,自行创建二级菜单
|
||||
int NDD_PROC_MAIN(QWidget* pNotepad, const QString& strFileName, std::function<QsciScintilla* ()>getCurEdit, NDD_PROC_DATA* pProcData)
|
||||
//s_invokeMainFun: 可以回调NDD主程序中的功能函数,比如创建新文件功能等,根据需要可实时扩展。
|
||||
//开发者可以在该菜单下面,自行创建二级菜单.更详细的例子,请见jstool min插件。
|
||||
int NDD_PROC_MAIN(QWidget* pNotepad, const QString& strFileName, std::function<QsciScintilla* ()>getCurEdit, std::function<bool(int, void*)> pluginCallBack, NDD_PROC_DATA* pProcData)
|
||||
{
|
||||
|
||||
//务必拷贝一份pProcData,在外面会释放。
|
||||
|
|
|
@ -833,7 +833,13 @@ static void DrawTextBlob(Surface *surface, const ViewStyle &vsDraw, PRectangle r
|
|||
PRectangle rcChar = rcCChar;
|
||||
rcChar.left++;
|
||||
rcChar.right--;
|
||||
surface->DrawTextClipped(rcChar, ctrlCharsFont,
|
||||
// In the original Scintilla code this was a call to DrawTextClipped().
|
||||
// This caused the clipping to be incorrect (triggered when EOLs are
|
||||
// visible) causing text to overwrite the margins when scrolling. The
|
||||
// change is consistent with the alternative code paths to where
|
||||
// DrawTextBlob() is called bu tthe root cause maybe in PlatQt.cpp or in Qt
|
||||
// itself.
|
||||
surface->DrawTextNoClip(rcChar, ctrlCharsFont,
|
||||
rcSegment.top + vsDraw.maxAscent, s, static_cast<int>(s ? strlen(s) : 0),
|
||||
textBack, textFore);
|
||||
}
|
||||
|
|
|
@ -5622,7 +5622,7 @@ void Editor::StyleSetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lParam
|
|||
vs.styles[wParam].back = ColourDesired(static_cast<int>(lParam));
|
||||
break;
|
||||
case SCI_STYLESETBOLD:
|
||||
vs.styles[wParam].weight = lParam != 0 ? SC_WEIGHT_BOLD : SC_WEIGHT_NORMAL;
|
||||
vs.styles[wParam].weight = ((lParam != 0) ? SC_WEIGHT_BOLD : SC_WEIGHT_NORMAL);
|
||||
break;
|
||||
case SCI_STYLESETWEIGHT:
|
||||
vs.styles[wParam].weight = static_cast<int>(lParam);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2021 Riverbank Computing Limited
|
||||
// Copyright (c) 2023 Riverbank Computing Limited
|
||||
// Copyright (c) 2011 Archaeopteryx Software, Inc.
|
||||
// Copyright (c) 1990-2011, Scientific Toolworks, Inc.
|
||||
//
|
||||
|
@ -137,44 +137,45 @@ void QsciScintillaBase::inputMethodEvent(QInputMethodEvent *event)
|
|||
return;
|
||||
}
|
||||
|
||||
bool initialCompose = false;
|
||||
if (sci->pdoc->TentativeActive()) {
|
||||
sci->pdoc->TentativeUndo();
|
||||
} else {
|
||||
// No tentative undo means start of this composition so
|
||||
// Fill in any virtual spaces.
|
||||
sci->ClearBeforeTentativeStart();
|
||||
initialCompose = true;
|
||||
}
|
||||
|
||||
sci->view.imeCaretBlockOverride = false;
|
||||
|
||||
if (!event->commitString().isEmpty()) {
|
||||
const QString commitStr = event->commitString();
|
||||
const unsigned int commitStrLen = commitStr.length();
|
||||
const int commitStrLen = commitStr.length();
|
||||
|
||||
for (unsigned int i = 0; i < commitStrLen;) {
|
||||
const unsigned int ucWidth = commitStr.at(i).isHighSurrogate() ? 2 : 1;
|
||||
for (int i = 0; i < commitStrLen;) {
|
||||
const int ucWidth = commitStr.at(i).isHighSurrogate() ? 2 : 1;
|
||||
const QString oneCharUTF16 = commitStr.mid(i, ucWidth);
|
||||
const QByteArray oneChar = textAsBytes(oneCharUTF16);
|
||||
const int oneCharLen = oneChar.length();
|
||||
|
||||
sci->AddCharUTF(oneChar.data(), oneCharLen);
|
||||
sci->AddCharUTF(oneChar.data(), oneChar.length());
|
||||
i += ucWidth;
|
||||
}
|
||||
|
||||
} else if (!event->preeditString().isEmpty()) {
|
||||
const QString preeditStr = event->preeditString();
|
||||
const unsigned int preeditStrLen = preeditStr.length();
|
||||
if ((preeditStrLen == 0) || (preeditStrLen > MAXLENINPUTIME)) {
|
||||
const int preeditStrLen = preeditStr.length();
|
||||
if (preeditStrLen == 0) {
|
||||
sci->ShowCaretAtCurrentPosition();
|
||||
return;
|
||||
}
|
||||
|
||||
if (initialCompose)
|
||||
sci->ClearBeforeTentativeStart();
|
||||
sci->pdoc->TentativeStart(); // TentativeActive() from now on.
|
||||
|
||||
std::vector<int> imeIndicator = MapImeIndicators(event);
|
||||
|
||||
const bool recording = sci->recordingMacro;
|
||||
sci->recordingMacro = false;
|
||||
for (unsigned int i = 0; i < preeditStrLen;) {
|
||||
const unsigned int ucWidth = preeditStr.at(i).isHighSurrogate() ? 2 : 1;
|
||||
const QString oneCharUTF16 = preeditStr.mid(i, ucWidth);
|
||||
|
@ -186,7 +187,6 @@ void QsciScintillaBase::inputMethodEvent(QInputMethodEvent *event)
|
|||
DrawImeIndicator(sci, imeIndicator[i], oneCharLen);
|
||||
i += ucWidth;
|
||||
}
|
||||
sci->recordingMacro = recording;
|
||||
|
||||
// Move IME carets.
|
||||
int imeCaretPos = GetImeCaretPos(event);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// This module implements the specialisation of QListBox that handles the
|
||||
// This module implements the specialisation of QListBox that handles the
|
||||
// Scintilla double-click callback.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// This defines the specialisation of QListBox that handles the Scintilla
|
||||
// This defines the specialisation of QListBox that handles the Scintilla
|
||||
// double-click callback.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// This module implements part of the support for rectangular selections on
|
||||
// This module implements part of the support for rectangular selections on
|
||||
// macOS. It is a separate file to avoid clashes between macOS and Scintilla
|
||||
// data types.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This module implements the portability layer for the Qt port of Scintilla.
|
||||
// This module implements the portability layer for the Qt port of Scintilla.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This module defines interface to the QsciAbstractAPIs class.
|
||||
// This module defines interface to the QsciAbstractAPIs class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This module defines interface to the QsciAPIs class.
|
||||
// This module defines interface to the QsciAPIs class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciCommand class.
|
||||
// This defines the interface to the QsciCommand class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciCommandSet class.
|
||||
// This defines the interface to the QsciCommandSet class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciDocument class.
|
||||
// This defines the interface to the QsciDocument class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This module defines various things common to all of the Scintilla Qt port.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexer class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
#pragma once
|
||||
// This defines the interface to the QsciLexerAsm class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerAVS class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerBash class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerBatch class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerCMake class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerCoffeeScript class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerCPP class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerCSharp class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerCSS class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerCustom class.
|
||||
// This defines the interface to the QsciLexerCustom class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerD class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerDiff class.
|
||||
// This defines the interface to the QsciLexerDiff class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerEDIFACT class.
|
||||
// This defines the interface to the QsciLexerEDIFACT class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerFortran class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerFortran77 class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerGO class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerHTML class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerIDL class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerJava class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerJavaScript class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerJSON class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerLua class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerMakefile class.
|
||||
// This defines the interface to the QsciLexerMakefile class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerMarkdown class.
|
||||
// This defines the interface to the QsciLexerMarkdown class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerMatlab class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerOctave class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerPascal class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerPerl class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerPO class.
|
||||
// This defines the interface to the QsciLexerPO class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerPostScript class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerPOV class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerProperties class.
|
||||
// This defines the interface to the QsciLexerProperties class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerPython class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#pragma once
|
||||
#pragma once
|
||||
#pragma once
|
||||
// This defines the interface to the QsciLexerR class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerRuby class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerSpice class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerSQL class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerTCL class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerTeX class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerVerilog class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerVHDL class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerXML class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciLexerYAML class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This defines the interface to the QsciMacro class.
|
||||
// This defines the interface to the QsciMacro class.
|
||||
//
|
||||
// Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
|
|