gui: mainwindow: Refactor to use new PreviewCoordinator

This commit is contained in:
Albert S. 2023-01-08 17:37:28 +01:00
parent 8485a25b21
commit 889725033a
2 changed files with 49 additions and 80 deletions

View File

@ -22,7 +22,6 @@
#include "../shared/sqlitesearch.h" #include "../shared/sqlitesearch.h"
#include "../shared/looqsgeneralexception.h" #include "../shared/looqsgeneralexception.h"
#include "../shared/common.h" #include "../shared/common.h"
#include "ipcpreviewclient.h"
#include "previewgenerator.h" #include "previewgenerator.h"
#include "aboutdialog.h" #include "aboutdialog.h"
@ -32,8 +31,7 @@ MainWindow::MainWindow(QWidget *parent, QString socketPath)
this->progressDialog.cancel(); // because constructing it shows it, quite weird this->progressDialog.cancel(); // because constructing it shows it, quite weird
ui->setupUi(this); ui->setupUi(this);
setWindowTitle(QCoreApplication::applicationName()); setWindowTitle(QCoreApplication::applicationName());
this->ipcPreviewClient.moveToThread(&this->ipcClientThread);
this->ipcPreviewClient.setSocketPath(socketPath);
QSettings settings; QSettings settings;
this->dbFactory = new DatabaseFactory(Common::databasePath()); this->dbFactory = new DatabaseFactory(Common::databasePath());
@ -78,7 +76,7 @@ MainWindow::MainWindow(QWidget *parent, QString socketPath)
ui->txtSearch->installEventFilter(this); ui->txtSearch->installEventFilter(this);
ui->scrollArea->viewport()->installEventFilter(this); ui->scrollArea->viewport()->installEventFilter(this);
this->ipcClientThread.start(); this->previewCoordinator.setSocketPath(socketPath);
} }
void MainWindow::addPathToIndex() void MainWindow::addPathToIndex()
@ -208,9 +206,9 @@ void MainWindow::connectSignals()
} }
}, },
Qt::QueuedConnection); Qt::QueuedConnection);
connect(&ipcPreviewClient, &IPCPreviewClient::previewReceived, this, &MainWindow::previewReceived, connect(&previewCoordinator, &PreviewCoordinator::previewReady, this, &MainWindow::previewReceived,
Qt::QueuedConnection); Qt::QueuedConnection);
connect(&ipcPreviewClient, &IPCPreviewClient::finished, this, connect(&previewCoordinator, &PreviewCoordinator::completedGeneration, this,
[&] [&]
{ {
this->ui->previewProcessBar->setValue(this->ui->previewProcessBar->maximum()); this->ui->previewProcessBar->setValue(this->ui->previewProcessBar->maximum());
@ -218,17 +216,17 @@ void MainWindow::connectSignals()
this->ui->comboPreviewFiles->setEnabled(true); this->ui->comboPreviewFiles->setEnabled(true);
ui->txtSearch->setEnabled(true); ui->txtSearch->setEnabled(true);
}); });
connect(&ipcPreviewClient, &IPCPreviewClient::error, this, connect(&previewCoordinator, &PreviewCoordinator::error, this,
[this](QString msg) [this](QString msg)
{ {
qCritical() << msg << Qt::endl; qCritical() << msg << Qt::endl;
QMessageBox::critical(this, "IPC error", msg); QMessageBox::critical(this, "IPC error", msg);
}); });
connect(this, &MainWindow::startIpcPreviews, &ipcPreviewClient, &IPCPreviewClient::startGeneration, /*connect(this, &MainWindow::startIpcPreviews, &previewCoordinator, &IPCPreviewClient::startGeneration,
Qt::QueuedConnection); Qt::QueuedConnection);
connect(this, &MainWindow::stopIpcPreviews, &ipcPreviewClient, &IPCPreviewClient::stopGeneration, connect(this, &MainWindow::stopIpcPreviews, &ipcPreviewClient, &IPCPreviewClient::stopGeneration,
Qt::QueuedConnection); Qt::QueuedConnection); */
} }
void MainWindow::exportFailedPaths() void MainWindow::exportFailedPaths()
@ -632,13 +630,17 @@ void MainWindow::saveSettings()
qApp->quit(); qApp->quit();
} }
void MainWindow::previewReceived(QSharedPointer<PreviewResult> preview, unsigned int previewGeneration) void MainWindow::previewReceived()
{ {
if(previewGeneration < this->currentPreviewGeneration)
{
return;
}
this->ui->previewProcessBar->setValue(this->ui->previewProcessBar->value() + 1); this->ui->previewProcessBar->setValue(this->ui->previewProcessBar->value() + 1);
QBoxLayout *layout = static_cast<QBoxLayout *>(ui->scrollAreaWidgetContents->layout());
int index = layout->count();
if(index > 0)
{
--index;
}
QSharedPointer<PreviewResult> preview = this->previewCoordinator.resultAt(index);
if(!preview.isNull() && preview->hasPreview()) if(!preview.isNull() && preview->hasPreview())
{ {
QString docPath = preview->getDocumentPath(); QString docPath = preview->getDocumentPath();
@ -684,24 +686,7 @@ void MainWindow::previewReceived(QSharedPointer<PreviewResult> preview, unsigned
previewWidget->setLayout(previewLayout); previewWidget->setLayout(previewLayout);
QBoxLayout *layout = static_cast<QBoxLayout *>(ui->scrollAreaWidgetContents->layout()); layout->insertWidget(index, previewWidget);
int pos = previewOrder[docPath + QString::number(previewPage)];
if(pos <= layout->count())
{
layout->insertWidget(pos, previewWidget);
for(auto it = previewWidgetOrderCache.constKeyValueBegin();
it != previewWidgetOrderCache.constKeyValueEnd(); it++)
{
if(it->first <= layout->count())
{
layout->insertWidget(it->first, it->second);
}
}
}
else
{
previewWidgetOrderCache[pos] = previewWidget;
}
} }
} }
@ -818,7 +803,6 @@ void MainWindow::lineEditReturnPressed()
void MainWindow::handleSearchResults(const QVector<SearchResult> &results) void MainWindow::handleSearchResults(const QVector<SearchResult> &results)
{ {
this->previewableSearchResults.clear();
qDeleteAll(ui->scrollAreaWidgetContents->children()); qDeleteAll(ui->scrollAreaWidgetContents->children());
ui->treeResultsList->clear(); ui->treeResultsList->clear();
@ -827,6 +811,8 @@ void MainWindow::handleSearchResults(const QVector<SearchResult> &results)
ui->comboPreviewFiles->setVisible(true); ui->comboPreviewFiles->setVisible(true);
ui->lblTotalPreviewPagesCount->setText(""); ui->lblTotalPreviewPagesCount->setText("");
this->previewCoordinator.init(results);
bool hasDeleted = false; bool hasDeleted = false;
QHash<QString, bool> seenMap; QHash<QString, bool> seenMap;
for(const SearchResult &result : results) for(const SearchResult &result : results)
@ -847,34 +833,29 @@ void MainWindow::handleSearchResults(const QVector<SearchResult> &results)
item->setText(3, this->locale().formattedDataSize(result.fileData.size)); item->setText(3, this->locale().formattedDataSize(result.fileData.size));
} }
bool exists = pathInfo.exists(); bool exists = pathInfo.exists();
if(exists) if(!exists)
{
if(result.wasContentSearch)
{
if(!pathInfo.suffix().contains("htm")) // hack until we can preview them properly...
{
if(PreviewGenerator::get(pathInfo) != nullptr)
{
this->previewableSearchResults.append(result);
if(!seenMap.contains(result.fileData.absPath))
{
ui->comboPreviewFiles->addItem(result.fileData.absPath);
}
}
}
}
}
else
{ {
hasDeleted = true; hasDeleted = true;
} }
seenMap[absPath] = true; seenMap[absPath] = true;
} }
seenMap.clear();
for(const SearchResult &result : this->previewCoordinator.getPreviewableSearchResults())
{
const QString &absPath = result.fileData.absPath;
if(!seenMap.contains(absPath))
{
ui->comboPreviewFiles->addItem(absPath);
}
seenMap[absPath] = true;
}
ui->treeResultsList->resizeColumnToContents(0); ui->treeResultsList->resizeColumnToContents(0);
ui->treeResultsList->resizeColumnToContents(1); ui->treeResultsList->resizeColumnToContents(1);
ui->treeResultsList->resizeColumnToContents(2); ui->treeResultsList->resizeColumnToContents(2);
previewDirty = !this->previewableSearchResults.empty();
previewDirty = this->previewCoordinator.previewableCount() > 0;
ui->spinPreviewPage->setValue(1); ui->spinPreviewPage->setValue(1);
@ -884,7 +865,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()); statusText += ", previewable: " + QString::number(this->previewCoordinator.previewableCount());
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";
@ -901,7 +882,7 @@ int MainWindow::currentSelectedScale()
void MainWindow::makePreviews(int page) void MainWindow::makePreviews(int page)
{ {
if(this->previewableSearchResults.empty()) if(this->previewCoordinator.previewableCount() == 0)
{ {
return; return;
} }
@ -918,8 +899,7 @@ void MainWindow::makePreviews(int page)
ui->scrollAreaWidgetContents->setLayout(new QVBoxLayout()); ui->scrollAreaWidgetContents->setLayout(new QVBoxLayout());
ui->scrollAreaWidgetContents->layout()->setAlignment(Qt::AlignCenter); ui->scrollAreaWidgetContents->layout()->setAlignment(Qt::AlignCenter);
} }
ui->previewProcessBar->setMaximum(this->previewableSearchResults.size()); ui->previewProcessBar->setMaximum(this->previewCoordinator.previewableCount());
processedPdfPreviews = 0;
QVector<QString> wordsToHighlight; QVector<QString> wordsToHighlight;
QRegularExpression extractor(R"#("([^"]*)"|([^\s]+))#"); QRegularExpression extractor(R"#("([^"]*)"|([^\s]+))#");
@ -954,12 +934,9 @@ void MainWindow::makePreviews(int page)
renderConfig.scaleY = QGuiApplication::primaryScreen()->physicalDotsPerInchY() * (currentScale / 100.); renderConfig.scaleY = QGuiApplication::primaryScreen()->physicalDotsPerInchY() * (currentScale / 100.);
renderConfig.wordsToHighlight = wordsToHighlight; renderConfig.wordsToHighlight = wordsToHighlight;
this->previewOrder.clear();
this->previewWidgetOrderCache.clear();
int previewPos = 0; int previewPos = 0;
QVector<RenderTarget> targets; QVector<RenderTarget> targets;
for(SearchResult &sr : this->previewableSearchResults) for(const SearchResult &sr : this->previewCoordinator.getPreviewableSearchResults())
{ {
if(ui->comboPreviewFiles->currentIndex() != 0) if(ui->comboPreviewFiles->currentIndex() != 0)
{ {
@ -971,11 +948,8 @@ void MainWindow::makePreviews(int page)
RenderTarget renderTarget; RenderTarget renderTarget;
renderTarget.path = sr.fileData.absPath; renderTarget.path = sr.fileData.absPath;
renderTarget.page = (int)sr.page; renderTarget.page = (int)sr.page;
targets.append(renderTarget);
int pos = previewPos - beginOffset; targets.append(renderTarget);
this->previewOrder[renderTarget.path + QString::number(renderTarget.page)] = pos;
++previewPos;
} }
int numpages = ceil(static_cast<double>(targets.size()) / previewsPerPage); int numpages = ceil(static_cast<double>(targets.size()) / previewsPerPage);
ui->spinPreviewPage->setMaximum(numpages); ui->spinPreviewPage->setMaximum(numpages);
@ -985,12 +959,12 @@ void MainWindow::makePreviews(int page)
ui->previewProcessBar->setMaximum(targets.count()); ui->previewProcessBar->setMaximum(targets.count());
ui->previewProcessBar->setMinimum(0); ui->previewProcessBar->setMinimum(0);
ui->previewProcessBar->setValue(0); ui->previewProcessBar->setValue(0);
ui->previewProcessBar->setVisible(this->previewableSearchResults.size() > 0); ui->previewProcessBar->setVisible(this->previewCoordinator.previewableCount() > 0);
++this->currentPreviewGeneration;
this->ui->spinPreviewPage->setEnabled(false); this->ui->spinPreviewPage->setEnabled(false);
this->ui->comboPreviewFiles->setEnabled(false); this->ui->comboPreviewFiles->setEnabled(false);
this->ui->txtSearch->setEnabled(false); this->ui->txtSearch->setEnabled(false);
emit startIpcPreviews(renderConfig, targets);
this->previewCoordinator.startGeneration(renderConfig, targets);
} }
void MainWindow::handleSearchError(QString error) void MainWindow::handleSearchError(QString error)
@ -1006,11 +980,12 @@ void MainWindow::createSearchResultMenu(QMenu &menu, const QFileInfo &fileInfo)
[&fileInfo] { QGuiApplication::clipboard()->setText(fileInfo.absoluteFilePath()); }); [&fileInfo] { QGuiApplication::clipboard()->setText(fileInfo.absoluteFilePath()); });
menu.addAction("Open containing folder", [this, &fileInfo] { this->openFile(fileInfo.absolutePath()); }); menu.addAction("Open containing folder", [this, &fileInfo] { this->openFile(fileInfo.absolutePath()); });
auto previewables = this->previewCoordinator.getPreviewableSearchResults();
auto result = auto result =
std::find_if(this->previewableSearchResults.begin(), this->previewableSearchResults.end(), std::find_if(previewables.begin(), previewables.end(),
[this, &fileInfo](SearchResult &a) { return fileInfo.absoluteFilePath() == a.fileData.absPath; }); [this, &fileInfo](SearchResult &a) { return fileInfo.absoluteFilePath() == a.fileData.absPath; });
if(result != this->previewableSearchResults.end()) if(result != previewables.end())
{ {
menu.addAction("Show previews for this file", menu.addAction("Show previews for this file",
[this, &fileInfo] [this, &fileInfo]
@ -1069,7 +1044,6 @@ void MainWindow::showSearchResultsContextMenu(const QPoint &point)
MainWindow::~MainWindow() MainWindow::~MainWindow()
{ {
syncerThread.terminate(); syncerThread.terminate();
ipcClientThread.terminate();
delete this->indexSyncer; delete this->indexSyncer;
delete this->dbService; delete this->dbService;
delete this->dbFactory; delete this->dbFactory;

View File

@ -12,7 +12,7 @@
#include <QProgressDialog> #include <QProgressDialog>
#include "../shared/looqsquery.h" #include "../shared/looqsquery.h"
#include "../shared/indexsyncer.h" #include "../shared/indexsyncer.h"
#include "ipcpreviewclient.h" #include "previewcoordinator.h"
#include "indexer.h" #include "indexer.h"
namespace Ui namespace Ui
{ {
@ -27,8 +27,9 @@ class MainWindow : public QMainWindow
DatabaseFactory *dbFactory; DatabaseFactory *dbFactory;
SqliteDbService *dbService; SqliteDbService *dbService;
Ui::MainWindow *ui; Ui::MainWindow *ui;
IPCPreviewClient ipcPreviewClient;
QThread ipcClientThread; PreviewCoordinator previewCoordinator;
QThread syncerThread; QThread syncerThread;
Indexer *indexer; Indexer *indexer;
IndexSyncer *indexSyncer; IndexSyncer *indexSyncer;
@ -36,18 +37,12 @@ class MainWindow : public QMainWindow
QFileIconProvider iconProvider; QFileIconProvider iconProvider;
QSqlDatabase db; QSqlDatabase db;
QFutureWatcher<QVector<SearchResult>> searchWatcher; QFutureWatcher<QVector<SearchResult>> searchWatcher;
QVector<SearchResult> previewableSearchResults;
LooqsQuery contentSearchQuery; LooqsQuery contentSearchQuery;
QVector<QString> searchHistory; QVector<QString> searchHistory;
int currentSearchHistoryIndex = 0; int currentSearchHistoryIndex = 0;
QString currentSavedSearchText; QString currentSavedSearchText;
QHash<QString, int> previewOrder; /* Quick lookup for the order a preview should have */
QMap<int, QWidget *>
previewWidgetOrderCache /* Saves those that arrived out of order to be inserted later at the correct pos */;
bool previewDirty = false; bool previewDirty = false;
int previewsPerPage = 20; int previewsPerPage = 20;
unsigned int processedPdfPreviews = 0;
unsigned int currentPreviewGeneration = 1;
void connectSignals(); void connectSignals();
void makePreviews(int page); void makePreviews(int page);
@ -69,7 +64,7 @@ class MainWindow : public QMainWindow
void treeSearchItemActivated(QTreeWidgetItem *item, int i); void treeSearchItemActivated(QTreeWidgetItem *item, int i);
void showSearchResultsContextMenu(const QPoint &point); void showSearchResultsContextMenu(const QPoint &point);
void tabChanged(); void tabChanged();
void previewReceived(QSharedPointer<PreviewResult> preview, unsigned int previewGeneration); void previewReceived();
void comboScaleChanged(int i); void comboScaleChanged(int i);
void spinPreviewPageValueChanged(int val); void spinPreviewPageValueChanged(int val);
void startIndexing(); void startIndexing();