比较提交
	
		
			10 次代码提交
		
	
	
		
			WIP/refact
			...
			2ab6e40d44
		
	
	| 作者 | SHA1 | 提交日期 | |
|---|---|---|---|
| 2ab6e40d44 | |||
| 31f0568a87 | |||
| 238f9add49 | |||
| 7c63ee9178 | |||
| 1edfcc8f23 | |||
| 2df273dee3 | |||
| 5a47f5949f | |||
| e6a0c0daee | |||
| 11b070ed42 | |||
| 47874b3706 | 
| @@ -18,6 +18,10 @@ class IPCPreviewWorker : public QObject | ||||
| 	IPCPreviewWorker(QLocalSocket *peer); | ||||
| 	void start(RenderConfig config, const QVector<RenderTarget> &targets); | ||||
| 	void stop(); | ||||
| 	~IPCPreviewWorker() | ||||
| 	{ | ||||
| 		delete this->peer; | ||||
| 	} | ||||
|   private slots: | ||||
| 	void shutdownSocket(); | ||||
|  | ||||
|   | ||||
| @@ -15,6 +15,7 @@ | ||||
| #include <QFileDialog> | ||||
| #include <QScreen> | ||||
| #include <QProgressDialog> | ||||
| #include <QDesktopWidget> | ||||
| #include "mainwindow.h" | ||||
| #include "ui_mainwindow.h" | ||||
| #include "clicklabel.h" | ||||
| @@ -647,6 +648,7 @@ void MainWindow::previewReceived(QSharedPointer<PreviewResult> preview, unsigned | ||||
| 		headerLabel->setText(QString("Path: ") + preview->getDocumentPath()); | ||||
|  | ||||
| 		ClickLabel *label = dynamic_cast<ClickLabel *>(preview->createPreviewWidget()); | ||||
| 		label->setMaximumWidth(QApplication::desktop()->availableGeometry().width() - 200); | ||||
|  | ||||
| 		QVBoxLayout *previewLayout = new QVBoxLayout(); | ||||
|  | ||||
| @@ -678,6 +680,7 @@ void MainWindow::previewReceived(QSharedPointer<PreviewResult> preview, unsigned | ||||
| 		previewLayout->setMargin(0); | ||||
| 		previewLayout->insertStretch(0, 1); | ||||
| 		previewLayout->insertStretch(-1, 1); | ||||
| 		previewLayout->setAlignment(Qt::AlignCenter); | ||||
| 		QWidget *previewWidget = new QWidget(); | ||||
|  | ||||
| 		previewWidget->setLayout(previewLayout); | ||||
| @@ -806,6 +809,7 @@ void MainWindow::handleSearchResults(const QVector<SearchResult> &results) | ||||
| 	ui->comboPreviewFiles->clear(); | ||||
| 	ui->comboPreviewFiles->addItem("All previews"); | ||||
| 	ui->comboPreviewFiles->setVisible(true); | ||||
| 	ui->lblTotalPreviewPagesCount->setText(""); | ||||
|  | ||||
| 	bool hasDeleted = false; | ||||
| 	QHash<QString, bool> seenMap; | ||||
| @@ -816,7 +820,6 @@ void MainWindow::handleSearchResults(const QVector<SearchResult> &results) | ||||
|  | ||||
| 		if(!seenMap.contains(absPath)) | ||||
| 		{ | ||||
| 			seenMap[absPath] = true; | ||||
| 			QString fileName = pathInfo.fileName(); | ||||
| 			QTreeWidgetItem *item = new QTreeWidgetItem(ui->treeResultsList); | ||||
|  | ||||
| @@ -830,17 +833,18 @@ void MainWindow::handleSearchResults(const QVector<SearchResult> &results) | ||||
| 		bool exists = pathInfo.exists(); | ||||
| 		if(exists) | ||||
| 		{ | ||||
| 			if(!result.wasContentSearch) | ||||
| 			if(result.wasContentSearch) | ||||
| 			{ | ||||
| 				continue; | ||||
| 			} | ||||
|  | ||||
| 			if(!pathInfo.suffix().contains("htm")) // hack until we can preview them properly... | ||||
| 			{ | ||||
| 				if(PreviewGenerator::get(pathInfo) != nullptr) | ||||
| 				if(!pathInfo.suffix().contains("htm")) // hack until we can preview them properly... | ||||
| 				{ | ||||
| 					this->previewableSearchResults.append(result); | ||||
| 					ui->comboPreviewFiles->addItem(result.fileData.absPath); | ||||
| 					if(PreviewGenerator::get(pathInfo) != nullptr) | ||||
| 					{ | ||||
| 						this->previewableSearchResults.append(result); | ||||
| 						if(!seenMap.contains(result.fileData.absPath)) | ||||
| 						{ | ||||
| 							ui->comboPreviewFiles->addItem(result.fileData.absPath); | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| @@ -848,6 +852,7 @@ void MainWindow::handleSearchResults(const QVector<SearchResult> &results) | ||||
| 		{ | ||||
| 			hasDeleted = true; | ||||
| 		} | ||||
| 		seenMap[absPath] = true; | ||||
| 	} | ||||
|  | ||||
| 	ui->treeResultsList->resizeColumnToContents(0); | ||||
| @@ -863,6 +868,7 @@ void MainWindow::handleSearchResults(const QVector<SearchResult> &results) | ||||
| 	} | ||||
|  | ||||
| 	QString statusText = "Results: " + QString::number(results.size()) + " files"; | ||||
| 	statusText += ", previewable: " + QString::number(this->previewableSearchResults.count()); | ||||
| 	if(hasDeleted) | ||||
| 	{ | ||||
| 		statusText += " WARNING: Some files are inaccessible. No preview available for those. Index may be out of sync"; | ||||
|   | ||||
| @@ -7,7 +7,7 @@ | ||||
|     <x>0</x> | ||||
|     <y>0</y> | ||||
|     <width>1280</width> | ||||
|     <height>888</height> | ||||
|     <height>923</height> | ||||
|    </rect> | ||||
|   </property> | ||||
|   <property name="windowTitle"> | ||||
| @@ -27,7 +27,7 @@ | ||||
|        <enum>QTabWidget::South</enum> | ||||
|       </property> | ||||
|       <property name="currentIndex"> | ||||
|        <number>3</number> | ||||
|        <number>1</number> | ||||
|       </property> | ||||
|       <widget class="QWidget" name="resultsTab"> | ||||
|        <attribute name="title"> | ||||
| @@ -82,7 +82,7 @@ | ||||
|              <x>0</x> | ||||
|              <y>0</y> | ||||
|              <width>1244</width> | ||||
|              <height>598</height> | ||||
|              <height>633</height> | ||||
|             </rect> | ||||
|            </property> | ||||
|            <layout class="QHBoxLayout" name="horizontalLayout"/> | ||||
| @@ -165,7 +165,7 @@ | ||||
|           <item> | ||||
|            <widget class="QComboBox" name="comboPreviewFiles"> | ||||
|             <property name="sizePolicy"> | ||||
|              <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> | ||||
|              <sizepolicy hsizetype="Maximum" vsizetype="Fixed"> | ||||
|               <horstretch>0</horstretch> | ||||
|               <verstretch>0</verstretch> | ||||
|              </sizepolicy> | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| #include <QMutexLocker> | ||||
| #include <QPainter> | ||||
| #include <QRegularExpression> | ||||
| #include "previewgeneratorpdf.h" | ||||
|  | ||||
| static QMutex cacheMutex; | ||||
| @@ -17,6 +18,7 @@ Poppler::Document *PreviewGeneratorPdf::document(QString path) | ||||
| 		return nullptr; | ||||
| 	} | ||||
| 	result->setRenderHint(Poppler::Document::TextAntialiasing); | ||||
|  | ||||
| 	QMutexLocker locker(&cacheMutex); | ||||
| 	documentcache.insert(path, result); | ||||
| 	locker.unlock(); | ||||
| @@ -45,7 +47,12 @@ QSharedPointer<PreviewResult> PreviewGeneratorPdf::generate(RenderConfig config, | ||||
| 	QImage img = pdfPage->renderToImage(config.scaleX, config.scaleY); | ||||
| 	for(QString &word : config.wordsToHighlight) | ||||
| 	{ | ||||
| 		QList<QRectF> rects = pdfPage->search(word, Poppler::Page::SearchFlag::IgnoreCase); | ||||
| 		QList<QRectF> rects = | ||||
| 			pdfPage->search(word, Poppler::Page::SearchFlag::IgnoreCase | Poppler::Page::SearchFlag::WholeWords); | ||||
| 		if(rects.empty()) | ||||
| 		{ | ||||
| 			rects = pdfPage->search(word, Poppler::Page::SearchFlag::IgnoreCase); | ||||
| 		} | ||||
| 		for(QRectF &rect : rects) | ||||
| 		{ | ||||
| 			QPainter painter(&img); | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| #include <QTextStream> | ||||
| #include <QRegularExpression> | ||||
|  | ||||
| #include "previewgeneratorplaintext.h" | ||||
| #include "previewresultplaintext.h" | ||||
| @@ -57,6 +58,7 @@ QString PreviewGeneratorPlainText::generatePreviewText(QString content, RenderCo | ||||
| 		++i; | ||||
| 	} | ||||
|  | ||||
| 	resulText = resulText.toHtmlEscaped(); | ||||
| 	QString header = "<b>" + fileName + "</b> "; | ||||
| 	for(QString &word : config.wordsToHighlight) | ||||
| 	{ | ||||
| @@ -74,10 +76,19 @@ QString PreviewGeneratorPlainText::generatePreviewText(QString content, RenderCo | ||||
| 	return header + resulText.replace("\n", "<br>").mid(0, 1000); | ||||
| } | ||||
|  | ||||
| struct Snippet | ||||
| { | ||||
| 	/* Contains each line number and line of the snippet*/ | ||||
| 	QString snippetText; | ||||
|  | ||||
| 	/* How many times a word occurs in the snippetText */ | ||||
| 	QHash<QString, int> wordCountMap; | ||||
| }; | ||||
|  | ||||
| QString PreviewGeneratorPlainText::generateLineBasedPreviewText(QTextStream &in, RenderConfig config, QString fileName) | ||||
| { | ||||
| 	QString resultText; | ||||
| 	const unsigned int contextLinesCount = 2; | ||||
| 	QVector<Snippet> snippets; | ||||
| 	const int contextLinesCount = 2; | ||||
| 	LimitQueue<QString> queue(contextLinesCount); | ||||
| 	QString currentLine; | ||||
| 	currentLine.reserve(512); | ||||
| @@ -85,38 +96,73 @@ QString PreviewGeneratorPlainText::generateLineBasedPreviewText(QTextStream &in, | ||||
| 	/* How many lines to read after a line with a match (like grep -A ) */ | ||||
| 	int justReadLinesCount = -1; | ||||
|  | ||||
| 	auto appendLine = [&resultText](int lineNumber, QString &line) | ||||
| 	{ resultText.append(QString("<b>%1</b>%2<br>").arg(lineNumber).arg(line)); }; | ||||
| 	struct Snippet currentSnippet; | ||||
|  | ||||
| 	QHash<QString, int> countmap; | ||||
| 	QString header = "<b>" + fileName + "</b> "; | ||||
|  | ||||
| 	unsigned int snippetsCount = 0; | ||||
| 	unsigned int lineCount = 0; | ||||
| 	while(in.readLineInto(¤tLine) && snippetsCount < MAX_SNIPPETS) | ||||
| 	auto appendLine = [¤tSnippet, &config](int lineNumber, QString &line) | ||||
| 	{ | ||||
| 		int foundWordsCount = 0; | ||||
| 		for(QString &word : config.wordsToHighlight) | ||||
| 		{ | ||||
| 			QRegularExpression searchRegex("\\b" + word + "\\b"); | ||||
| 			bool containsRegex = line.contains(searchRegex); | ||||
| 			bool contains = false; | ||||
| 			if(!containsRegex) | ||||
| 			{ | ||||
| 				contains = line.contains(word, Qt::CaseInsensitive); | ||||
| 			} | ||||
| 			if(containsRegex || contains) | ||||
| 			{ | ||||
| 				currentSnippet.wordCountMap[word] = currentSnippet.wordCountMap.value(word, 0) + 1; | ||||
| 				QString replacementString = "<span style=\"background-color: yellow;\">" + word + "</span>"; | ||||
| 				if(containsRegex) | ||||
| 				{ | ||||
| 					line.replace(searchRegex, replacementString); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					line.replace(word, replacementString, Qt::CaseInsensitive); | ||||
| 				} | ||||
| 				++foundWordsCount; | ||||
| 			} | ||||
| 		} | ||||
| 		currentSnippet.snippetText.append(QString("<b>%1</b>%2<br>").arg(lineNumber).arg(line)); | ||||
| 		return foundWordsCount; | ||||
| 	}; | ||||
|  | ||||
| 	unsigned int lineCount = 0; | ||||
| 	while(in.readLineInto(¤tLine)) | ||||
| 	{ | ||||
| 		currentLine = currentLine.toHtmlEscaped(); | ||||
| 		++lineCount; | ||||
| 		bool matched = false; | ||||
| 		if(justReadLinesCount > 0) | ||||
| 		{ | ||||
| 			appendLine(lineCount, currentLine); | ||||
| 			--justReadLinesCount; | ||||
|  | ||||
| 			int result = appendLine(lineCount, currentLine); | ||||
| 			if(justReadLinesCount == 1 && result > 0) | ||||
| 			{ | ||||
| 				justReadLinesCount = contextLinesCount; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				--justReadLinesCount; | ||||
| 			} | ||||
|  | ||||
| 			continue; | ||||
| 		} | ||||
| 		if(justReadLinesCount == 0) | ||||
| 		{ | ||||
| 			resultText += "---<br>"; | ||||
| 			currentSnippet.snippetText += "---<br>"; | ||||
| 			justReadLinesCount = -1; | ||||
| 			++snippetsCount; | ||||
| 			snippets.append(currentSnippet); | ||||
| 			currentSnippet = {}; | ||||
| 		} | ||||
| 		for(QString &word : config.wordsToHighlight) | ||||
| 		{ | ||||
| 			if(currentLine.contains(word, Qt::CaseInsensitive)) | ||||
| 			{ | ||||
| 				countmap[word] = countmap.value(word, 0) + 1; | ||||
| 				matched = true; | ||||
| 				currentLine.replace(word, "<span style=\"background-color: yellow;\">" + word + "</span>", | ||||
| 									Qt::CaseInsensitive); | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 		if(matched) | ||||
| @@ -125,7 +171,6 @@ QString PreviewGeneratorPlainText::generateLineBasedPreviewText(QTextStream &in, | ||||
| 			{ | ||||
| 				int queuedLineCount = lineCount - queue.size(); | ||||
| 				QString queuedLine = queue.dequeue(); | ||||
|  | ||||
| 				appendLine(queuedLineCount, queuedLine); | ||||
| 			} | ||||
| 			appendLine(lineCount, currentLine); | ||||
| @@ -137,13 +182,77 @@ QString PreviewGeneratorPlainText::generateLineBasedPreviewText(QTextStream &in, | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if(!currentSnippet.snippetText.isEmpty()) | ||||
| 	{ | ||||
| 		currentSnippet.snippetText += "---<br>"; | ||||
| 		snippets.append(currentSnippet); | ||||
| 	} | ||||
|  | ||||
| 	std::sort(snippets.begin(), snippets.end(), | ||||
| 			  [](Snippet &a, Snippet &b) | ||||
| 			  { | ||||
| 				  int differentWordsA = 0; | ||||
| 				  int totalWordsA = 0; | ||||
| 				  int differentWordsB = 0; | ||||
| 				  int totalWordsB = 0; | ||||
| 				  for(int count : a.wordCountMap.values()) | ||||
| 				  { | ||||
| 					  if(count > 0) | ||||
| 					  { | ||||
| 						  ++differentWordsA; | ||||
| 					  } | ||||
| 					  totalWordsA += count; | ||||
| 				  } | ||||
| 				  for(int count : b.wordCountMap.values()) | ||||
| 				  { | ||||
| 					  if(count > 0) | ||||
| 					  { | ||||
| 						  ++differentWordsB; | ||||
| 					  } | ||||
| 					  totalWordsB += count; | ||||
| 				  } | ||||
|  | ||||
| 				  if(differentWordsA > differentWordsB) | ||||
| 				  { | ||||
| 					  return true; | ||||
| 				  } | ||||
| 				  if(differentWordsA == differentWordsB) | ||||
| 				  { | ||||
| 					  return totalWordsA > totalWordsB; | ||||
| 				  } | ||||
| 				  return false; | ||||
| 			  }); | ||||
|  | ||||
| 	QString resultText = ""; | ||||
|  | ||||
| 	unsigned int snippetsCount = 0; | ||||
|  | ||||
| 	QString header = "<b>" + fileName + "</b> "; | ||||
|  | ||||
| 	QHash<QString, int> totalWordCountMap; | ||||
| 	bool isTruncated = false; | ||||
| 	for(Snippet &snippet : snippets) | ||||
| 	{ | ||||
| 		if(snippetsCount++ < MAX_SNIPPETS) | ||||
| 		{ | ||||
| 			resultText += snippet.snippetText; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			isTruncated = true; | ||||
| 		} | ||||
| 		for(auto it = snippet.wordCountMap.keyValueBegin(); it != snippet.wordCountMap.keyValueEnd(); it++) | ||||
| 		{ | ||||
| 			totalWordCountMap[it->first] = totalWordCountMap.value(it->first, 0) + it->second; | ||||
| 		} | ||||
| 	} | ||||
| 	if(isTruncated) | ||||
| 	{ | ||||
| 		header += "(truncated) "; | ||||
| 	} | ||||
| 	for(QString &word : config.wordsToHighlight) | ||||
| 	{ | ||||
| 		header += word + ": " + QString::number(countmap[word]) + " "; | ||||
| 	} | ||||
| 	if(snippetsCount == MAX_SNIPPETS) | ||||
| 	{ | ||||
| 		header += "(truncated)"; | ||||
| 		header += word + ": " + QString::number(totalWordCountMap[word]) + " "; | ||||
| 	} | ||||
| 	header += "<hr>"; | ||||
|  | ||||
|   | ||||
| @@ -6,11 +6,11 @@ template <class T> class LimitQueue | ||||
| { | ||||
|   protected: | ||||
| 	QQueue<T> queue; | ||||
| 	unsigned int limit = 0; | ||||
| 	int limit = 0; | ||||
|  | ||||
|   public: | ||||
| 	LimitQueue(); | ||||
| 	LimitQueue(unsigned int limit) | ||||
| 	LimitQueue(int limit) | ||||
| 	{ | ||||
| 		this->limit = limit; | ||||
| 	} | ||||
| @@ -34,7 +34,7 @@ template <class T> class LimitQueue | ||||
| 		return queue.dequeue(); | ||||
| 	} | ||||
|  | ||||
| 	void setLimit(unsigned int limit) | ||||
| 	void setLimit(int limit) | ||||
| 	{ | ||||
| 		this->limit = limit; | ||||
| 	} | ||||
|   | ||||
		在新工单中引用
	
	屏蔽一个用户