Сравнить коммиты
9 Коммитов
10d61acbd0
...
31f0568a87
Автор | SHA1 | Дата | |
---|---|---|---|
31f0568a87 | |||
238f9add49 | |||
7c63ee9178 | |||
1edfcc8f23 | |||
2df273dee3 | |||
5a47f5949f | |||
e6a0c0daee | |||
11b070ed42 | |||
47874b3706 |
@ -1,16 +1,50 @@
|
|||||||
#include <QtConcurrent>
|
#include <QtConcurrent>
|
||||||
#include "ipcpreviewworker.h"
|
#include "ipcpreviewworker.h"
|
||||||
#include "previewgeneratormapfunctor.h"
|
#include "previewgeneratormapfunctor.h"
|
||||||
IPCPreviewWorker::IPCPreviewWorker()
|
IPCPreviewWorker::IPCPreviewWorker(QLocalSocket *peer)
|
||||||
{
|
{
|
||||||
|
this->peer = peer;
|
||||||
this->connect(&previewWorkerWatcher, &QFutureWatcher<QByteArray>::resultReadyAt, this,
|
this->connect(&previewWorkerWatcher, &QFutureWatcher<QByteArray>::resultReadyAt, this,
|
||||||
[this](int index) { emit previewGenerated(previewWorkerWatcher.resultAt(index)); });
|
[this](int index)
|
||||||
connect(&previewWorkerWatcher, &QFutureWatcher<QByteArray>::finished, this, [this] { emit finished(); });
|
{
|
||||||
|
if(this->peer != nullptr)
|
||||||
|
{
|
||||||
|
QDataStream stream{this->peer};
|
||||||
|
stream << previewWorkerWatcher.resultAt(index);
|
||||||
|
this->peer->flush();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connect(&previewWorkerWatcher, &QFutureWatcher<QByteArray>::finished, this, &IPCPreviewWorker::shutdownSocket);
|
||||||
|
connect(this->peer, &QLocalSocket::disconnected, this, &IPCPreviewWorker::shutdownSocket);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IPCPreviewWorker::start(RenderConfig config, const QVector<RenderTarget> &targets, QLocalSocket *peer)
|
void IPCPreviewWorker::shutdownSocket()
|
||||||
|
{
|
||||||
|
if(cleaned)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cleaned = true;
|
||||||
|
if(this->peer != nullptr)
|
||||||
|
{
|
||||||
|
if(this->peer->state() == QLocalSocket::ConnectedState)
|
||||||
|
{
|
||||||
|
this->peer->flush();
|
||||||
|
this->peer->waitForBytesWritten();
|
||||||
|
this->peer->disconnectFromServer();
|
||||||
|
if(this->peer->state() != QLocalSocket::UnconnectedState)
|
||||||
|
{
|
||||||
|
this->peer->waitForDisconnected();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete this->peer;
|
||||||
|
this->peer = nullptr;
|
||||||
|
}
|
||||||
|
emit finished();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IPCPreviewWorker::start(RenderConfig config, const QVector<RenderTarget> &targets)
|
||||||
{
|
{
|
||||||
stop();
|
|
||||||
auto mapFunctor = PreviewGeneratorMapFunctor();
|
auto mapFunctor = PreviewGeneratorMapFunctor();
|
||||||
mapFunctor.setRenderConfig(config);
|
mapFunctor.setRenderConfig(config);
|
||||||
|
|
||||||
|
@ -11,13 +11,21 @@ class IPCPreviewWorker : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private:
|
private:
|
||||||
QFutureWatcher<QByteArray> previewWorkerWatcher;
|
QFutureWatcher<QByteArray> previewWorkerWatcher;
|
||||||
|
QLocalSocket *peer;
|
||||||
|
bool cleaned = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IPCPreviewWorker();
|
IPCPreviewWorker(QLocalSocket *peer);
|
||||||
void start(RenderConfig config, const QVector<RenderTarget> &targets, QLocalSocket *peer);
|
void start(RenderConfig config, const QVector<RenderTarget> &targets);
|
||||||
void stop();
|
void stop();
|
||||||
|
~IPCPreviewWorker()
|
||||||
|
{
|
||||||
|
delete this->peer;
|
||||||
|
}
|
||||||
|
private slots:
|
||||||
|
void shutdownSocket();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void previewGenerated(QByteArray);
|
|
||||||
void finished();
|
void finished();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18,8 +18,6 @@ IpcServer::IpcServer()
|
|||||||
/* Only 1, we are doing work for the GUI, not a service for general availability */
|
/* Only 1, we are doing work for the GUI, not a service for general availability */
|
||||||
this->spawningServer.setMaxPendingConnections(1);
|
this->spawningServer.setMaxPendingConnections(1);
|
||||||
connect(&this->spawningServer, &QLocalServer::newConnection, this, &IpcServer::spawnerNewConnection);
|
connect(&this->spawningServer, &QLocalServer::newConnection, this, &IpcServer::spawnerNewConnection);
|
||||||
connect(&this->previewWorker, &IPCPreviewWorker::previewGenerated, this, &IpcServer::handlePreviewGenerated);
|
|
||||||
connect(&this->previewWorker, &IPCPreviewWorker::finished, this, [this] { this->currentSocket->flush(); });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IpcServer::startSpawner(QString socketPath)
|
bool IpcServer::startSpawner(QString socketPath)
|
||||||
@ -31,8 +29,6 @@ bool IpcServer::startSpawner(QString socketPath)
|
|||||||
void IpcServer::spawnerNewConnection()
|
void IpcServer::spawnerNewConnection()
|
||||||
{
|
{
|
||||||
QLocalSocket *socket = this->spawningServer.nextPendingConnection();
|
QLocalSocket *socket = this->spawningServer.nextPendingConnection();
|
||||||
connect(socket, &QLocalSocket::disconnected, socket, &QLocalSocket::deleteLater);
|
|
||||||
this->currentSocket = socket;
|
|
||||||
if(socket != nullptr)
|
if(socket != nullptr)
|
||||||
{
|
{
|
||||||
if(!socket->waitForReadyRead())
|
if(!socket->waitForReadyRead())
|
||||||
@ -53,21 +49,22 @@ void IpcServer::spawnerNewConnection()
|
|||||||
stream.startTransaction();
|
stream.startTransaction();
|
||||||
stream >> renderConfig >> targets;
|
stream >> renderConfig >> targets;
|
||||||
} while(!stream.commitTransaction() && socket->state() == QLocalSocket::ConnectedState);
|
} while(!stream.commitTransaction() && socket->state() == QLocalSocket::ConnectedState);
|
||||||
|
if(socket->state() == QLocalSocket::ConnectedState)
|
||||||
|
{
|
||||||
stream << targets.count();
|
stream << targets.count();
|
||||||
socket->flush();
|
socket->flush();
|
||||||
previewWorker.start(renderConfig, targets, socket);
|
IPCPreviewWorker *previewWorker = new IPCPreviewWorker(socket);
|
||||||
|
connect(previewWorker, &IPCPreviewWorker::finished, this, [previewWorker] { delete previewWorker; });
|
||||||
|
previewWorker->start(renderConfig, targets);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete socket;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(command == StopGeneratePreviews)
|
if(command == StopGeneratePreviews)
|
||||||
{
|
{
|
||||||
previewWorker.stop();
|
/* TODO: implement */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IpcServer::handlePreviewGenerated(QByteArray ba)
|
|
||||||
{
|
|
||||||
QDataStream stream{this->currentSocket};
|
|
||||||
stream << ba;
|
|
||||||
this->currentSocket->flush();
|
|
||||||
}
|
|
||||||
|
@ -10,13 +10,10 @@ class IpcServer : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private:
|
private:
|
||||||
IPCPreviewWorker previewWorker;
|
|
||||||
QLocalServer spawningServer;
|
QLocalServer spawningServer;
|
||||||
QLocalSocket *currentSocket = nullptr;
|
|
||||||
SaveFileResult addFile(QString file);
|
SaveFileResult addFile(QString file);
|
||||||
private slots:
|
private slots:
|
||||||
void spawnerNewConnection();
|
void spawnerNewConnection();
|
||||||
void handlePreviewGenerated(QByteArray ba);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IpcServer();
|
IpcServer();
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QScreen>
|
#include <QScreen>
|
||||||
#include <QProgressDialog>
|
#include <QProgressDialog>
|
||||||
|
#include <QDesktopWidget>
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "ui_mainwindow.h"
|
#include "ui_mainwindow.h"
|
||||||
#include "clicklabel.h"
|
#include "clicklabel.h"
|
||||||
@ -647,6 +648,7 @@ void MainWindow::previewReceived(QSharedPointer<PreviewResult> preview, unsigned
|
|||||||
headerLabel->setText(QString("Path: ") + preview->getDocumentPath());
|
headerLabel->setText(QString("Path: ") + preview->getDocumentPath());
|
||||||
|
|
||||||
ClickLabel *label = dynamic_cast<ClickLabel *>(preview->createPreviewWidget());
|
ClickLabel *label = dynamic_cast<ClickLabel *>(preview->createPreviewWidget());
|
||||||
|
label->setMaximumWidth(QApplication::desktop()->availableGeometry().width() - 200);
|
||||||
|
|
||||||
QVBoxLayout *previewLayout = new QVBoxLayout();
|
QVBoxLayout *previewLayout = new QVBoxLayout();
|
||||||
|
|
||||||
@ -678,6 +680,7 @@ void MainWindow::previewReceived(QSharedPointer<PreviewResult> preview, unsigned
|
|||||||
previewLayout->setMargin(0);
|
previewLayout->setMargin(0);
|
||||||
previewLayout->insertStretch(0, 1);
|
previewLayout->insertStretch(0, 1);
|
||||||
previewLayout->insertStretch(-1, 1);
|
previewLayout->insertStretch(-1, 1);
|
||||||
|
previewLayout->setAlignment(Qt::AlignCenter);
|
||||||
QWidget *previewWidget = new QWidget();
|
QWidget *previewWidget = new QWidget();
|
||||||
|
|
||||||
previewWidget->setLayout(previewLayout);
|
previewWidget->setLayout(previewLayout);
|
||||||
@ -806,6 +809,7 @@ void MainWindow::handleSearchResults(const QVector<SearchResult> &results)
|
|||||||
ui->comboPreviewFiles->clear();
|
ui->comboPreviewFiles->clear();
|
||||||
ui->comboPreviewFiles->addItem("All previews");
|
ui->comboPreviewFiles->addItem("All previews");
|
||||||
ui->comboPreviewFiles->setVisible(true);
|
ui->comboPreviewFiles->setVisible(true);
|
||||||
|
ui->lblTotalPreviewPagesCount->setText("");
|
||||||
|
|
||||||
bool hasDeleted = false;
|
bool hasDeleted = false;
|
||||||
QHash<QString, bool> seenMap;
|
QHash<QString, bool> seenMap;
|
||||||
@ -816,7 +820,6 @@ void MainWindow::handleSearchResults(const QVector<SearchResult> &results)
|
|||||||
|
|
||||||
if(!seenMap.contains(absPath))
|
if(!seenMap.contains(absPath))
|
||||||
{
|
{
|
||||||
seenMap[absPath] = true;
|
|
||||||
QString fileName = pathInfo.fileName();
|
QString fileName = pathInfo.fileName();
|
||||||
QTreeWidgetItem *item = new QTreeWidgetItem(ui->treeResultsList);
|
QTreeWidgetItem *item = new QTreeWidgetItem(ui->treeResultsList);
|
||||||
|
|
||||||
@ -830,24 +833,26 @@ void MainWindow::handleSearchResults(const QVector<SearchResult> &results)
|
|||||||
bool exists = pathInfo.exists();
|
bool exists = pathInfo.exists();
|
||||||
if(exists)
|
if(exists)
|
||||||
{
|
{
|
||||||
if(!result.wasContentSearch)
|
if(result.wasContentSearch)
|
||||||
{
|
{
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!pathInfo.suffix().contains("htm")) // hack until we can preview them properly...
|
if(!pathInfo.suffix().contains("htm")) // hack until we can preview them properly...
|
||||||
{
|
{
|
||||||
if(PreviewGenerator::get(pathInfo) != nullptr)
|
if(PreviewGenerator::get(pathInfo) != nullptr)
|
||||||
{
|
{
|
||||||
this->previewableSearchResults.append(result);
|
this->previewableSearchResults.append(result);
|
||||||
|
if(!seenMap.contains(result.fileData.absPath))
|
||||||
|
{
|
||||||
ui->comboPreviewFiles->addItem(result.fileData.absPath);
|
ui->comboPreviewFiles->addItem(result.fileData.absPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hasDeleted = true;
|
hasDeleted = true;
|
||||||
}
|
}
|
||||||
|
seenMap[absPath] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->treeResultsList->resizeColumnToContents(0);
|
ui->treeResultsList->resizeColumnToContents(0);
|
||||||
@ -863,6 +868,7 @@ void MainWindow::handleSearchResults(const QVector<SearchResult> &results)
|
|||||||
}
|
}
|
||||||
|
|
||||||
QString statusText = "Results: " + QString::number(results.size()) + " files";
|
QString statusText = "Results: " + QString::number(results.size()) + " files";
|
||||||
|
statusText += ", previewable: " + QString::number(this->previewableSearchResults.count());
|
||||||
if(hasDeleted)
|
if(hasDeleted)
|
||||||
{
|
{
|
||||||
statusText += " WARNING: Some files are inaccessible. No preview available for those. Index may be out of sync";
|
statusText += " WARNING: Some files are inaccessible. No preview available for those. Index may be out of sync";
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include <QMutexLocker>
|
#include <QMutexLocker>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
#include <QRegularExpression>
|
||||||
#include "previewgeneratorpdf.h"
|
#include "previewgeneratorpdf.h"
|
||||||
|
|
||||||
static QMutex cacheMutex;
|
static QMutex cacheMutex;
|
||||||
@ -17,6 +18,7 @@ Poppler::Document *PreviewGeneratorPdf::document(QString path)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
result->setRenderHint(Poppler::Document::TextAntialiasing);
|
result->setRenderHint(Poppler::Document::TextAntialiasing);
|
||||||
|
|
||||||
QMutexLocker locker(&cacheMutex);
|
QMutexLocker locker(&cacheMutex);
|
||||||
documentcache.insert(path, result);
|
documentcache.insert(path, result);
|
||||||
locker.unlock();
|
locker.unlock();
|
||||||
@ -45,7 +47,12 @@ QSharedPointer<PreviewResult> PreviewGeneratorPdf::generate(RenderConfig config,
|
|||||||
QImage img = pdfPage->renderToImage(config.scaleX, config.scaleY);
|
QImage img = pdfPage->renderToImage(config.scaleX, config.scaleY);
|
||||||
for(QString &word : config.wordsToHighlight)
|
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)
|
for(QRectF &rect : rects)
|
||||||
{
|
{
|
||||||
QPainter painter(&img);
|
QPainter painter(&img);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
|
#include <QRegularExpression>
|
||||||
|
|
||||||
#include "previewgeneratorplaintext.h"
|
#include "previewgeneratorplaintext.h"
|
||||||
#include "previewresultplaintext.h"
|
#include "previewresultplaintext.h"
|
||||||
@ -57,6 +58,7 @@ QString PreviewGeneratorPlainText::generatePreviewText(QString content, RenderCo
|
|||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resulText = resulText.toHtmlEscaped();
|
||||||
QString header = "<b>" + fileName + "</b> ";
|
QString header = "<b>" + fileName + "</b> ";
|
||||||
for(QString &word : config.wordsToHighlight)
|
for(QString &word : config.wordsToHighlight)
|
||||||
{
|
{
|
||||||
@ -74,10 +76,19 @@ QString PreviewGeneratorPlainText::generatePreviewText(QString content, RenderCo
|
|||||||
return header + resulText.replace("\n", "<br>").mid(0, 1000);
|
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 PreviewGeneratorPlainText::generateLineBasedPreviewText(QTextStream &in, RenderConfig config, QString fileName)
|
||||||
{
|
{
|
||||||
QString resultText;
|
QVector<Snippet> snippets;
|
||||||
const unsigned int contextLinesCount = 2;
|
const int contextLinesCount = 2;
|
||||||
LimitQueue<QString> queue(contextLinesCount);
|
LimitQueue<QString> queue(contextLinesCount);
|
||||||
QString currentLine;
|
QString currentLine;
|
||||||
currentLine.reserve(512);
|
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 ) */
|
/* How many lines to read after a line with a match (like grep -A ) */
|
||||||
int justReadLinesCount = -1;
|
int justReadLinesCount = -1;
|
||||||
|
|
||||||
auto appendLine = [&resultText](int lineNumber, QString &line)
|
struct Snippet currentSnippet;
|
||||||
{ resultText.append(QString("<b>%1</b>%2<br>").arg(lineNumber).arg(line)); };
|
|
||||||
|
|
||||||
QHash<QString, int> countmap;
|
auto appendLine = [¤tSnippet, &config](int lineNumber, QString &line)
|
||||||
QString header = "<b>" + fileName + "</b> ";
|
|
||||||
|
|
||||||
unsigned int snippetsCount = 0;
|
|
||||||
unsigned int lineCount = 0;
|
|
||||||
while(in.readLineInto(¤tLine) && snippetsCount < MAX_SNIPPETS)
|
|
||||||
{
|
{
|
||||||
|
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;
|
++lineCount;
|
||||||
bool matched = false;
|
bool matched = false;
|
||||||
if(justReadLinesCount > 0)
|
if(justReadLinesCount > 0)
|
||||||
{
|
{
|
||||||
appendLine(lineCount, currentLine);
|
|
||||||
|
int result = appendLine(lineCount, currentLine);
|
||||||
|
if(justReadLinesCount == 1 && result > 0)
|
||||||
|
{
|
||||||
|
justReadLinesCount = contextLinesCount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
--justReadLinesCount;
|
--justReadLinesCount;
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(justReadLinesCount == 0)
|
if(justReadLinesCount == 0)
|
||||||
{
|
{
|
||||||
resultText += "---<br>";
|
currentSnippet.snippetText += "---<br>";
|
||||||
justReadLinesCount = -1;
|
justReadLinesCount = -1;
|
||||||
++snippetsCount;
|
snippets.append(currentSnippet);
|
||||||
|
currentSnippet = {};
|
||||||
}
|
}
|
||||||
for(QString &word : config.wordsToHighlight)
|
for(QString &word : config.wordsToHighlight)
|
||||||
{
|
{
|
||||||
if(currentLine.contains(word, Qt::CaseInsensitive))
|
if(currentLine.contains(word, Qt::CaseInsensitive))
|
||||||
{
|
{
|
||||||
countmap[word] = countmap.value(word, 0) + 1;
|
|
||||||
matched = true;
|
matched = true;
|
||||||
currentLine.replace(word, "<span style=\"background-color: yellow;\">" + word + "</span>",
|
break;
|
||||||
Qt::CaseInsensitive);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(matched)
|
if(matched)
|
||||||
@ -125,7 +171,6 @@ QString PreviewGeneratorPlainText::generateLineBasedPreviewText(QTextStream &in,
|
|||||||
{
|
{
|
||||||
int queuedLineCount = lineCount - queue.size();
|
int queuedLineCount = lineCount - queue.size();
|
||||||
QString queuedLine = queue.dequeue();
|
QString queuedLine = queue.dequeue();
|
||||||
|
|
||||||
appendLine(queuedLineCount, queuedLine);
|
appendLine(queuedLineCount, queuedLine);
|
||||||
}
|
}
|
||||||
appendLine(lineCount, currentLine);
|
appendLine(lineCount, currentLine);
|
||||||
@ -137,14 +182,78 @@ QString PreviewGeneratorPlainText::generateLineBasedPreviewText(QTextStream &in,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(QString &word : config.wordsToHighlight)
|
if(!currentSnippet.snippetText.isEmpty())
|
||||||
{
|
{
|
||||||
header += word + ": " + QString::number(countmap[word]) + " ";
|
currentSnippet.snippetText += "---<br>";
|
||||||
|
snippets.append(currentSnippet);
|
||||||
}
|
}
|
||||||
if(snippetsCount == MAX_SNIPPETS)
|
|
||||||
|
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) ";
|
header += "(truncated) ";
|
||||||
}
|
}
|
||||||
|
for(QString &word : config.wordsToHighlight)
|
||||||
|
{
|
||||||
|
header += word + ": " + QString::number(totalWordCountMap[word]) + " ";
|
||||||
|
}
|
||||||
header += "<hr>";
|
header += "<hr>";
|
||||||
|
|
||||||
return header + resultText;
|
return header + resultText;
|
||||||
|
@ -6,11 +6,11 @@ template <class T> class LimitQueue
|
|||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
QQueue<T> queue;
|
QQueue<T> queue;
|
||||||
unsigned int limit = 0;
|
int limit = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LimitQueue();
|
LimitQueue();
|
||||||
LimitQueue(unsigned int limit)
|
LimitQueue(int limit)
|
||||||
{
|
{
|
||||||
this->limit = limit;
|
this->limit = limit;
|
||||||
}
|
}
|
||||||
@ -34,7 +34,7 @@ template <class T> class LimitQueue
|
|||||||
return queue.dequeue();
|
return queue.dequeue();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLimit(unsigned int limit)
|
void setLimit(int limit)
|
||||||
{
|
{
|
||||||
this->limit = limit;
|
this->limit = limit;
|
||||||
}
|
}
|
||||||
|
Загрузка…
Ссылка в новой задаче
Block a user