123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505 |
- #include "findresultwin.h"
- #include "findwin.h"
- #include "common.h"
- #include "styleset.h"
- #include "nddsetting.h"
- #include "findresultview.h"
- #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>
- //目前可以高亮,使用富文本进行了高亮设置。但是有个问题:富文本与html有一些冲突,在<>存在时,可能导致乱。这是一个问题。20220609
- //使用Html的转义解决了该问题
- FindResultWin::FindResultWin(QWidget *parent)
- : QWidget(parent), m_menu(nullptr), m_parent(parent),m_defaultFontSize(14), m_defFontSizeChange(false)
- {
- ui.setupUi(this);
- connect(ui.displayView, &FindResultView::lineDoubleClick, this, &FindResultWin::on_lineDoubleClick);
-
- }
- FindResultWin::~FindResultWin()
- {
- if (m_defFontSizeChange)
- {
- NddSetting::updataKeyValueFromNumSets(FIND_RESULT_FONT_SIZE, m_defaultFontSize);
- }
- clear();
- }
- void FindResultWin::clear()
- {
- for (int i = 0; i < m_resultLineFilePath.size(); ++i)
- {
- delete m_resultLineFilePath.at(i);
- }
- m_resultLineFilePath.clear();
- m_resultLineInfo.clear();
- }
- void FindResultWin::slot_clearAllContents()
- {
- 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;
- //先把< > 转义为因为会与原来的html标签冲突。这是一个很厉害的方法,如果不转义,会导致显示丢失
- srcText = srcText.toHtmlEscaped();
- findText = findText.toHtmlEscaped();
- int lens = findText.size();
- while (index > 0)
- {
- pos = srcText.indexOf(findText, findPos, cs);
- if (pos == -1)
- {
- //错误,不替换
- return;
- }
- else
- {
- findPos = pos + lens;
- }
- 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();
- bool isNeedCut = false;
- //行太长的进行缩短显示
- if (lineLens > 300)
- {
- isNeedCut = true;
- }
- //高亮的开始、结束位置
- int targetStart = record.pos - record.lineStartPos;
- int targetLens = record.end - record.pos;
- int tailStart = record.end - record.lineStartPos;
- QString head;
- QString src;
- QString tail;
- if (!StyleSet::isCurrentDeepStyle())
- {
- if (!isNeedCut)
- {
- 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
- {
- head = QString(utf8bytes.mid(0, targetStart));
- if (head.size() > MAX_HEAD_LENTGH)
- {
- head = (head.mid(0, MAX_HEAD_LENTGH) + "...").toHtmlEscaped();
- }
- else
- {
- head = head.toHtmlEscaped();
- }
- head = QString("<font style='font-size:14px;'>%1</font>").arg(head);
- src = QString("<font style='font-size:14px;background-color:#ffffbf'>%1</font>").arg(QString(utf8bytes.mid(targetStart, targetLens)).toHtmlEscaped());
- tail = QString(utf8bytes.mid(tailStart));
- if (tail > MAX_TAIL_LENGTH)
- {
- tail = (tail.mid(0, MAX_TAIL_LENGTH) + "...").toHtmlEscaped();
- }
- else
- {
- tail = tail.toHtmlEscaped();
- }
- tail = QString("<font style='font-size:14px;'>%1</font>").arg(tail);
- }
- }
- else
- {
- if (!isNeedCut)
- {
- 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));
- if (headContens.size() > MAX_HEAD_LENTGH)
- {
- headContens = (headContens.mid(0, MAX_HEAD_LENTGH) + "...").toHtmlEscaped();
- }
- else
- {
- headContens = headContens.toHtmlEscaped();
- }
- head = QString("<font style='font-size:14px;color:#dcdcdc'>%1</font>").arg(headContens);
- src = QString("<font style='font-size:14px;font-weight:bold;color:#ffaa00'>%1</font>").arg(QString(utf8bytes.mid(targetStart, targetLens)).toHtmlEscaped());
- QString tailContens = QString(utf8bytes.mid(tailStart));
- if (tailContens > MAX_TAIL_LENGTH)
- {
- tailContens = (tailContens.mid(0, MAX_TAIL_LENGTH) + "...").toHtmlEscaped();
- }
- else
- {
- tailContens = tailContens.toHtmlEscaped();
- }
- tail = QString("<font style='font-size:14px;color:#dcdcdc'>%1</font>").arg(tailContens);
- }
- }
- 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;
- 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);
- setItemBackground(titleItem, QColor(0xbbbbff));
-
- m_model->insertRow(0, titleItem);
- titleItem->setData(QVariant(true), ResultItemRoot);
- int rowNum = m_model->rowCount();
- //把其余的行收起来。把第一行张开
- for (int i = 1; i < rowNum; ++i)
- {
- ui.resultTreeView->collapse(m_model->index(i, 0));
- }
- ui.resultTreeView->expand(m_model->index(0, 0));
- if (record->records.size() == 0)
- {
- return;
- }
- QString desc;
- if (!StyleSet::isCurrentDeepStyle())
- {
- desc = tr("<font style='font-size:14px;font-weight:bold;color:#309730'>%1 (%2 hits)</font>").arg(record->findFilePath.toHtmlEscaped()).arg(record->records.size());
- }
- else
- {
- desc = tr("<font style='font-size:14px;color:#99cc99'>%1 (%2 hits)</font>").arg(record->findFilePath.toHtmlEscaped()).arg(record->records.size());
- }
- QStandardItem* descItem = new QStandardItem(desc);
- if (!StyleSet::isCurrentDeepStyle())
- {
- setItemBackground(descItem, QColor(0xd5ffd5));
- }
- else
- {
- setItemBackground(descItem, QColor(0x484848));
- }
- titleItem->appendRow(descItem);
-
- descItem->setData(QVariant((qlonglong)record->pEdit), ResultItemEditor);
- descItem->setData(QVariant(record->findFilePath), ResultItemEditorFilePath);
- descItem->setData(QVariant(record->findText), ResultWhatFind);
- //描述行双击不响应
- descItem->setData(QVariant(true), ResultItemDesc);
- for (int i =0 ; i < record->records.size(); ++i)
- {
- FindRecord v = record->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);
- }
- 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);
- }
- QStandardItem* childItem = new QStandardItem(text);
- childItem->setData(QVariant(v.pos), ResultItemPos);
- childItem->setData(QVariant(v.end - v.pos), ResultItemLen);
- #if defined(Q_OS_MAC)
- childItem->setTextAlignment(Qt::AlignVCenter);
- #endif
- descItem->appendRow(childItem);
- }
- if (!record->records.isEmpty())
- {
- 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)
- {
- if (record == nullptr)
- {
- return;
- }
- if (this->isHidden())
- {
- this->setVisible(true);
- }
- 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;
- 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(" %1 (%2 hits)\n").arg(pr->findFilePath).arg(pr->records.size());
- }
- else
- {
- desc = tr(" %1 (%2 hits)\n").arg(pr->findFilePath).arg(pr->records.size());
- }
- contents.append(desc);
- m_resultLineFilePath.append(pFilePath);
- lineInfo.level = 1;
- m_resultLineInfo.insert(insertIndex, lineInfo);
- ++insertIndex;
- for (int j = 0; j < pr->records.size(); ++j)
- {
- FindRecord v = pr->records.at(j);
- QString richText = v.lineContents;
- linePrefix = tr(" Line %1: ").arg(v.lineNum + 1);
- if (!StyleSet::isCurrentDeepStyle())
- {
- text = tr("%1%2\n").arg(linePrefix).arg(richText);
- }
- else
- {
- text = tr("%1%2\n").arg(linePrefix).arg(richText);
- }
- 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);
- }
- }
- 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)
- {
- pDisplay->SendScintilla(SCI_SETFOLDLEVEL, lineNum, (long)2| SC_FOLDLEVELBASE);
- ++lineNum;
- }
- }
- //着色
- pDisplay->setLineBackColorStyle(0, STYLE_COLOUR_TITLE);
- for (int i = 0, count = destFileLineNum.size(); i < count; ++i)
- {
- 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;
- }
- 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);
- }
- }
- }
|