比较提交

...

13 次代码提交

作者 SHA1 备注 提交日期
483ea04638 update README 2022-05-29 11:20:28 +02:00
aeafa9560e mainwindow: Disable page switcher while generation is running
This prevents 'spam'. User may have scrolled 10 pages forward, while
we are still generating old pages. Then the user wonders why
they arrive so late.

So disable switching pages while the generation is still running

It is unlikely that a user will have to quickly go through search
results like that.
2022-05-29 11:20:28 +02:00
a82818dc43 gui: init previewProcessBar with 0 on start 2022-05-29 11:20:28 +02:00
c867652b6f gui: IPCPreviewWorker(): Don't allocate mapfunctor on heap 2022-05-29 11:20:28 +02:00
f8fe21d50b gui: Add label showing total number of preview pages 2022-05-29 11:20:28 +02:00
1e97f8dd26 gui: mainwindow: Fix preview page number calculation
The paging now works on the actual pages to be rendered.
2022-05-29 11:20:28 +02:00
ad0fc74439 ipc: Place socket in /tmp/.looqs/, remove ipc path settings 2022-05-29 11:20:28 +02:00
e44fb1a942 gui: main: Enable exile.h for IPC preview generation 2022-05-29 11:20:28 +02:00
472661bff6 gui: Begin simple IPC error reporting 2022-05-29 11:20:28 +02:00
4aa6d43674 gui: Open files/previews directly without IPC again
Since the main GUI process is not sandboxed again
2022-05-29 11:20:28 +02:00
2591a4ccba gui: ipc: Support cancellation of preview generation 2022-05-29 11:20:28 +02:00
d66e395fda gui: main: Kill IPCServer process on exit 2022-05-29 11:20:28 +02:00
0d6fb1d482 gui: mainwindow: Use new IPCPreviewClient 2022-05-29 11:20:28 +02:00
共有 12 个文件被更改,包括 229 次插入86 次删除

查看文件

@ -4,6 +4,8 @@ search terms have been found, as shown in the screenshots below.
## Screenshots ## Screenshots
The screenshots in this section may occasionally be slightly outdated, but they are usually recent enough to get an overall impression of the current state.
### List ### List
![Screenshot looqs results](https://garage.quitesimple.org/assets/looqs/opearting_systems_looqs.png) ![Screenshot looqs results](https://garage.quitesimple.org/assets/looqs/opearting_systems_looqs.png)

查看文件

@ -61,7 +61,8 @@ void IPCPreviewClient::start(RenderConfig config, const QVector<RenderTarget> &t
if(!connect() || !socket->isOpen()) if(!connect() || !socket->isOpen())
{ {
// TODO: ERROR emit error("Could not connect to IPC worker");
return;
} }
if(socket->isOpen() && socket->isWritable()) if(socket->isOpen() && socket->isWritable())
@ -88,7 +89,8 @@ void IPCPreviewClient::start(RenderConfig config, const QVector<RenderTarget> &t
} }
else else
{ {
// TODO: ERROR emit error("Error while trying to process previews: " + socket->errorString());
return;
} }
int processed = 0; int processed = 0;
@ -107,7 +109,7 @@ void IPCPreviewClient::start(RenderConfig config, const QVector<RenderTarget> &t
} }
if(processed != targets.count()) if(processed != targets.count())
{ {
// TODO: ERROR emit error("IPC worker didn't send enough previews. This is a bug, please report");
} }
} }
socket->disconnectFromServer(); socket->disconnectFromServer();
@ -118,7 +120,8 @@ void IPCPreviewClient::stopGeneration()
{ {
if(!connect() || !socket->isOpen()) if(!connect() || !socket->isOpen())
{ {
// TODO: ERROR emit error("Could not connect to IPC worker");
return;
} }
QDataStream stream(socket); QDataStream stream(socket);
stream << StopGeneratePreviews; stream << StopGeneratePreviews;

查看文件

@ -31,6 +31,7 @@ class IPCPreviewClient : public QObject
signals: signals:
void previewReceived(QSharedPointer<PreviewResult> previewResult, unsigned int currentPreviewGeneration); void previewReceived(QSharedPointer<PreviewResult> previewResult, unsigned int currentPreviewGeneration);
void finished(); void finished();
void error(QString);
}; };
#endif // IPCPREVIEWCLIENT_H #endif // IPCPREVIEWCLIENT_H

查看文件

@ -3,29 +3,22 @@
#include "previewgeneratormapfunctor.h" #include "previewgeneratormapfunctor.h"
IPCPreviewWorker::IPCPreviewWorker() IPCPreviewWorker::IPCPreviewWorker()
{ {
this->connect(&previewWorkerWatcher, &QFutureWatcher<QByteArray>::resultReadyAt, this,
[this](int index) { emit previewGenerated(previewWorkerWatcher.resultAt(index)); });
connect(&previewWorkerWatcher, &QFutureWatcher<QByteArray>::finished, this, [this] { emit finished(); });
} }
void IPCPreviewWorker::start(RenderConfig config, const QVector<RenderTarget> &targets, QLocalSocket *peer) void IPCPreviewWorker::start(RenderConfig config, const QVector<RenderTarget> &targets, QLocalSocket *peer)
{ {
connect(&previewWorkerWatcher, &QFutureWatcher<QByteArray>::resultReadyAt, this, stop();
[peer, this](int index) auto mapFunctor = PreviewGeneratorMapFunctor();
{ mapFunctor.setRenderConfig(config);
QDataStream stream{peer};
stream << previewWorkerWatcher.resultAt(index);
peer->flush();
});
connect(&previewWorkerWatcher, &QFutureWatcher<QByteArray>::finished, this,
[peer]
{
/* TODO /
/*peer->waitForBytesWritten(); previewWorkerWatcher.setFuture(QtConcurrent::mapped(targets, mapFunctor));
peer->disconnectFromServer(); }
peer->deleteLater();*/
}); void IPCPreviewWorker::stop()
{
auto mapFunctor = new PreviewGeneratorMapFunctor(); previewWorkerWatcher.cancel();
mapFunctor->setRenderConfig(config); previewWorkerWatcher.waitForFinished();
previewWorkerWatcher.setFuture(QtConcurrent::mapped(targets, *mapFunctor));
} }

查看文件

@ -15,6 +15,10 @@ class IPCPreviewWorker : public QObject
public: public:
IPCPreviewWorker(); IPCPreviewWorker();
void start(RenderConfig config, const QVector<RenderTarget> &targets, QLocalSocket *peer); void start(RenderConfig config, const QVector<RenderTarget> &targets, QLocalSocket *peer);
void stop();
signals:
void previewGenerated(QByteArray);
void finished();
}; };
#endif // IPCPREVIEWWORKER_H #endif // IPCPREVIEWWORKER_H

查看文件

@ -15,7 +15,11 @@
IpcServer::IpcServer() IpcServer::IpcServer()
{ {
/* Only 1, we are doing work for the GUI, not a service for general availability */
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)
@ -28,6 +32,7 @@ void IpcServer::spawnerNewConnection()
{ {
QLocalSocket *socket = this->spawningServer.nextPendingConnection(); QLocalSocket *socket = this->spawningServer.nextPendingConnection();
connect(socket, &QLocalSocket::disconnected, socket, &QLocalSocket::deleteLater); connect(socket, &QLocalSocket::disconnected, socket, &QLocalSocket::deleteLater);
this->currentSocket = socket;
if(socket != nullptr) if(socket != nullptr)
{ {
if(!socket->waitForReadyRead()) if(!socket->waitForReadyRead())
@ -39,10 +44,8 @@ void IpcServer::spawnerNewConnection()
stream >> command; stream >> command;
if(command == GeneratePreviews) if(command == GeneratePreviews)
{ {
IPCPreviewWorker *worker = new IPCPreviewWorker();
RenderConfig renderConfig; RenderConfig renderConfig;
QVector<RenderTarget> targets; QVector<RenderTarget> targets;
do do
{ {
/* TODO: this is not entirely robust */ /* TODO: this is not entirely robust */
@ -53,7 +56,18 @@ void IpcServer::spawnerNewConnection()
stream << targets.count(); stream << targets.count();
socket->flush(); socket->flush();
worker->start(renderConfig, targets, socket); previewWorker.start(renderConfig, targets, socket);
}
if(command == StopGeneratePreviews)
{
previewWorker.stop();
} }
} }
} }
void IpcServer::handlePreviewGenerated(QByteArray ba)
{
QDataStream stream{this->currentSocket};
stream << ba;
this->currentSocket->flush();
}

查看文件

@ -4,14 +4,19 @@
#include <QLocalServer> #include <QLocalServer>
#include "ipc.h" #include "ipc.h"
#include "filesaver.h" #include "filesaver.h"
#include "ipcpreviewworker.h"
class IpcServer : public QObject 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();

查看文件

@ -5,6 +5,7 @@
#include <QProcess> #include <QProcess>
#include <QDir> #include <QDir>
#include <QCommandLineParser> #include <QCommandLineParser>
#include <QFileInfo>
#include "mainwindow.h" #include "mainwindow.h"
#include "searchresult.h" #include "searchresult.h"
@ -32,15 +33,46 @@ void enableSandbox()
} }
exile_free_policy(policy); exile_free_policy(policy);
} }
void enableIpcSandbox()
{
struct exile_policy *policy = exile_create_policy();
if(policy == NULL)
{
qCritical() << "Failed to init policy for sandbox";
exit(EXIT_FAILURE);
}
policy->namespace_options = EXILE_UNSHARE_NETWORK | EXILE_UNSHARE_USER;
policy->no_new_privs = 1;
policy->drop_caps = 1;
policy->vow_promises = exile_vows_from_str("thread cpath wpath rpath unix stdio prot_exec proc shm fsnotify ioctl");
QString ipcSocketPath = Common::ipcSocketPath();
QFileInfo info{ipcSocketPath};
QString ipcSocketPathDir = info.absolutePath();
std::string stdIpcSocketPath = ipcSocketPathDir.toStdString();
exile_append_path_policies(policy, EXILE_FS_ALLOW_ALL_READ, "/");
exile_append_path_policies(policy, EXILE_FS_ALLOW_ALL_READ | EXILE_FS_ALLOW_ALL_WRITE, stdIpcSocketPath.c_str());
int ret = exile_enable_policy(policy);
if(ret != 0)
{
qDebug() << "Failed to establish sandbox";
exit(EXIT_FAILURE);
}
exile_free_policy(policy);
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
QString socketPath = "/tmp/looqs-spawner"; QString socketPath = Common::ipcSocketPath();
if(argc > 1) if(argc > 1)
{ {
QString arg = argv[1]; QString arg = argv[1];
if(arg == "ipc") if(arg == "ipc")
{ {
Common::setupAppInfo(); Common::setupAppInfo();
enableIpcSandbox();
QApplication a(argc, argv); QApplication a(argc, argv);
IpcServer *ipcserver = new IpcServer(); IpcServer *ipcserver = new IpcServer();
@ -70,10 +102,24 @@ int main(int argc, char *argv[])
return processor.process(); return processor.process();
} }
} }
QString ipcSocketPath = Common::ipcSocketPath();
QFileInfo info{ipcSocketPath};
QString ipcSocketPathDir = info.absolutePath();
QDir dir;
if(!dir.mkpath(ipcSocketPathDir))
{
qCritical() << "Failed to create dir for ipc socket" << Qt::endl;
exit(EXIT_FAILURE);
}
QProcess process; QProcess process;
QStringList args; QStringList args;
args << "ipc"; args << "ipc";
if(!process.startDetached("/proc/self/exe", args)) process.setProcessChannelMode(QProcess::ForwardedChannels);
process.start("/proc/self/exe", args);
if(!process.waitForStarted(5000))
{ {
QString errorMsg = "Failed to start IPC server"; QString errorMsg = "Failed to start IPC server";
qDebug() << errorMsg; qDebug() << errorMsg;
@ -108,17 +154,18 @@ int main(int argc, char *argv[])
QMessageBox::critical(nullptr, "Error", e.message); QMessageBox::critical(nullptr, "Error", e.message);
return 1; return 1;
} }
// Keep this post sandbox, afterwards does not work (suspect due to threads, but unconfirmed)
QApplication a(argc, argv); QApplication a(argc, argv);
a.setWindowIcon(QIcon(":/icon.svg")); a.setWindowIcon(QIcon(":/icon.svg"));
QObject::connect(&a, &QApplication::aboutToQuit, &process, &QProcess::kill);
qRegisterMetaType<QVector<SearchResult>>("QVector<SearchResult>"); qRegisterMetaType<QVector<SearchResult>>("QVector<SearchResult>");
qRegisterMetaType<QVector<PreviewResultPdf>>("QVector<PreviewResultPdf>"); qRegisterMetaType<QVector<PreviewResultPdf>>("QVector<PreviewResultPdf>");
qRegisterMetaType<PreviewResultPdf>("PreviewResultPdf"); qRegisterMetaType<PreviewResultPdf>("PreviewResultPdf");
qRegisterMetaType<FileScanResult>("FileScanResult"); qRegisterMetaType<FileScanResult>("FileScanResult");
qRegisterMetaType<RenderConfig>("RenderConfig");
IPCClient client{socketPath}; qRegisterMetaType<QVector<RenderTarget>>("QVector<RenderTarget>");
MainWindow w{0, client}; qRegisterMetaType<QSharedPointer<PreviewResult>>("QSharedPointer<PreviewResult>");
MainWindow w{0, socketPath};
w.showMaximized(); w.showMaximized();
return a.exec(); return a.exec();
} }

查看文件

@ -13,18 +13,43 @@
#include <QtConcurrent/QtConcurrent> #include <QtConcurrent/QtConcurrent>
#include <QMessageBox> #include <QMessageBox>
#include <QFileDialog> #include <QFileDialog>
#include <QScreen>
#include "mainwindow.h" #include "mainwindow.h"
#include "ui_mainwindow.h" #include "ui_mainwindow.h"
#include "clicklabel.h" #include "clicklabel.h"
#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"
MainWindow::MainWindow(QWidget *parent, IPCClient &client) : QMainWindow(parent), ui(new Ui::MainWindow) MainWindow::MainWindow(QWidget *parent, QString socketPath) : QMainWindow(parent), ui(new Ui::MainWindow)
{ {
ui->setupUi(this); ui->setupUi(this);
setWindowTitle(QCoreApplication::applicationName()); setWindowTitle(QCoreApplication::applicationName());
this->ipcClient = &client; this->ipcPreviewClient.moveToThread(&this->ipcClientThread);
this->ipcPreviewClient.setSocketPath(socketPath);
connect(&ipcPreviewClient, &IPCPreviewClient::previewReceived, this, &MainWindow::previewReceived,
Qt::QueuedConnection);
connect(&ipcPreviewClient, &IPCPreviewClient::finished, this,
[&]
{
this->ui->previewProcessBar->setValue(this->ui->previewProcessBar->maximum());
this->ui->spinPreviewPage->setEnabled(true);
});
connect(&ipcPreviewClient, &IPCPreviewClient::error, this,
[this](QString msg)
{
qCritical() << msg << Qt::endl;
QMessageBox::critical(this, "IPC error", msg);
});
connect(this, &MainWindow::startIpcPreviews, &ipcPreviewClient, &IPCPreviewClient::startGeneration,
Qt::QueuedConnection);
connect(this, &MainWindow::stopIpcPreviews, &ipcPreviewClient, &IPCPreviewClient::stopGeneration,
Qt::QueuedConnection);
this->ipcClientThread.start();
QSettings settings; QSettings settings;
this->dbFactory = new DatabaseFactory(Common::databasePath()); this->dbFactory = new DatabaseFactory(Common::databasePath());
@ -46,6 +71,9 @@ MainWindow::MainWindow(QWidget *parent, IPCClient &client) : QMainWindow(parent)
QStringList indexPaths = settings.value("indexPaths").toStringList(); QStringList indexPaths = settings.value("indexPaths").toStringList();
ui->lstPaths->addItems(indexPaths); ui->lstPaths->addItems(indexPaths);
ui->spinPreviewPage->setValue(1);
ui->spinPreviewPage->setMinimum(1);
} }
void MainWindow::addPathToIndex() void MainWindow::addPathToIndex()
@ -82,16 +110,6 @@ void MainWindow::connectSignals()
handleSearchError(e.message); handleSearchError(e.message);
} }
}); });
connect(&previewWorkerWatcher, &QFutureWatcher<QSharedPointer<PreviewResult>>::resultReadyAt, this,
[&](int index) { previewReceived(previewWorkerWatcher.resultAt(index)); });
connect(&previewWorkerWatcher, &QFutureWatcher<QSharedPointer<PreviewResult>>::progressValueChanged,
ui->previewProcessBar, &QProgressBar::setValue);
connect(&previewWorkerWatcher, &QFutureWatcher<QSharedPointer<PreviewResult>>::started, this,
[&] { ui->indexerTab->setEnabled(false); });
connect(&previewWorkerWatcher, &QFutureWatcher<QSharedPointer<PreviewResult>>::finished, this,
[&] { ui->indexerTab->setEnabled(true); });
connect(ui->treeResultsList, &QTreeWidget::itemActivated, this, &MainWindow::treeSearchItemActivated); connect(ui->treeResultsList, &QTreeWidget::itemActivated, this, &MainWindow::treeSearchItemActivated);
connect(ui->treeResultsList, &QTreeWidget::customContextMenuRequested, this, connect(ui->treeResultsList, &QTreeWidget::customContextMenuRequested, this,
&MainWindow::showSearchResultsContextMenu); &MainWindow::showSearchResultsContextMenu);
@ -261,16 +279,21 @@ void MainWindow::tabChanged()
} }
} }
void MainWindow::previewReceived(QSharedPointer<PreviewResult> preview) void MainWindow::previewReceived(QSharedPointer<PreviewResult> preview, unsigned int previewGeneration)
{ {
if(preview->hasPreview()) if(previewGeneration < this->currentPreviewGeneration)
{
return;
}
this->ui->previewProcessBar->setValue(this->ui->previewProcessBar->value() + 1);
if(!preview.isNull() && preview->hasPreview())
{ {
QString docPath = preview->getDocumentPath(); QString docPath = preview->getDocumentPath();
auto previewPage = preview->getPage(); auto previewPage = preview->getPage();
ClickLabel *label = dynamic_cast<ClickLabel *>(preview->createPreviewWidget()); ClickLabel *label = dynamic_cast<ClickLabel *>(preview->createPreviewWidget());
ui->scrollAreaWidgetContents->layout()->addWidget(label); ui->scrollAreaWidgetContents->layout()->addWidget(label);
connect(label, &ClickLabel::leftClick, [this, docPath, previewPage]() { ipcDocOpen(docPath, previewPage); }); connect(label, &ClickLabel::leftClick, [this, docPath, previewPage]() { openDocument(docPath, previewPage); });
connect(label, &ClickLabel::rightClick, connect(label, &ClickLabel::rightClick,
[this, docPath, previewPage]() [this, docPath, previewPage]()
{ {
@ -357,10 +380,8 @@ void MainWindow::handleSearchResults(const QVector<SearchResult> &results)
ui->treeResultsList->resizeColumnToContents(1); ui->treeResultsList->resizeColumnToContents(1);
previewDirty = !this->previewableSearchResults.empty(); previewDirty = !this->previewableSearchResults.empty();
int numpages = ceil(static_cast<double>(this->previewableSearchResults.size()) / previewsPerPage);
ui->spinPreviewPage->setMinimum(1);
ui->spinPreviewPage->setMaximum(numpages);
ui->spinPreviewPage->setValue(1); ui->spinPreviewPage->setValue(1);
if(previewTabActive() && previewDirty) if(previewTabActive() && previewDirty)
{ {
makePreviews(1); makePreviews(1);
@ -376,12 +397,10 @@ void MainWindow::handleSearchResults(const QVector<SearchResult> &results)
void MainWindow::makePreviews(int page) void MainWindow::makePreviews(int page)
{ {
if(this->previewableSearchResults.empty())
this->previewWorkerWatcher.cancel(); {
this->previewWorkerWatcher.waitForFinished(); return;
}
QCoreApplication::processEvents(); // Maybe not necessary anymore, depends on whether it's possible that a slot is
// still to be fired.
qDeleteAll(ui->scrollAreaWidgetContents->children()); qDeleteAll(ui->scrollAreaWidgetContents->children());
ui->scrollAreaWidgetContents->setLayout(new QHBoxLayout()); ui->scrollAreaWidgetContents->setLayout(new QHBoxLayout());
@ -409,14 +428,43 @@ void MainWindow::makePreviews(int page)
} }
} }
} }
PreviewWorker worker;
int end = previewsPerPage; int end = previewsPerPage;
int begin = page * previewsPerPage - previewsPerPage; int begin = page * previewsPerPage - previewsPerPage;
this->previewWorkerWatcher.setFuture(worker.generatePreviews(this->previewableSearchResults.mid(begin, end), if(begin < 0)
wordsToHighlight, scaleText.toInt() / 100.)); {
ui->previewProcessBar->setMaximum(this->previewWorkerWatcher.progressMaximum()); // Should not happen actually
ui->previewProcessBar->setMinimum(this->previewWorkerWatcher.progressMinimum()); begin = 0;
}
RenderConfig renderConfig;
renderConfig.scaleX = QGuiApplication::primaryScreen()->physicalDotsPerInchX() * (scaleText.toInt() / 100.);
renderConfig.scaleY = QGuiApplication::primaryScreen()->physicalDotsPerInchY() * (scaleText.toInt() / 100.);
renderConfig.wordsToHighlight = wordsToHighlight;
QVector<RenderTarget> targets;
for(SearchResult &sr : this->previewableSearchResults)
{
RenderTarget renderTarget;
renderTarget.path = sr.fileData.absPath;
for(unsigned int pagenum : sr.pages)
{
renderTarget.page = (int)pagenum;
targets.append(renderTarget);
}
}
int numpages = ceil(static_cast<double>(targets.size()) / previewsPerPage);
ui->spinPreviewPage->setMaximum(numpages);
targets = targets.mid(begin, end);
ui->lblTotalPreviewPagesCount->setText(QString::number(numpages));
ui->previewProcessBar->setMaximum(targets.count());
ui->previewProcessBar->setMinimum(0);
ui->previewProcessBar->setValue(0);
ui->previewProcessBar->setVisible(this->previewableSearchResults.size() > 0); ui->previewProcessBar->setVisible(this->previewableSearchResults.size() > 0);
++this->currentPreviewGeneration;
this->ui->spinPreviewPage->setEnabled(false);
emit startIpcPreviews(renderConfig, targets);
} }
void MainWindow::handleSearchError(QString error) void MainWindow::handleSearchError(QString error)
@ -430,27 +478,39 @@ void MainWindow::createSearchResutlMenu(QMenu &menu, const QFileInfo &fileInfo)
[&fileInfo] { QGuiApplication::clipboard()->setText(fileInfo.fileName()); }); [&fileInfo] { QGuiApplication::clipboard()->setText(fileInfo.fileName()); });
menu.addAction("Copy full path to clipboard", menu.addAction("Copy full path to clipboard",
[&fileInfo] { QGuiApplication::clipboard()->setText(fileInfo.absoluteFilePath()); }); [&fileInfo] { QGuiApplication::clipboard()->setText(fileInfo.absoluteFilePath()); });
menu.addAction("Open containing folder", [this, &fileInfo] { this->ipcFileOpen(fileInfo.absolutePath()); }); menu.addAction("Open containing folder", [this, &fileInfo] { this->openFile(fileInfo.absolutePath()); });
} }
void MainWindow::ipcDocOpen(QString path, int num) void MainWindow::openDocument(QString path, int num)
{ {
QStringList args; QSettings settings;
args << path; QString command = settings.value("pdfviewer").toString();
args << QString::number(num); if(path.endsWith(".pdf") && command != "" && command.contains("%p") && command.contains("%f"))
this->ipcClient->sendCommand(DocOpen, args); {
QStringList splitted = command.split(" ");
if(splitted.size() > 1)
{
QString cmd = splitted[0];
QStringList args = splitted.mid(1);
args.replaceInStrings("%f", path);
args.replaceInStrings("%p", QString::number(num));
QProcess::startDetached(cmd, args);
}
}
else
{
QDesktopServices::openUrl(QUrl::fromLocalFile(path));
}
} }
void MainWindow::ipcFileOpen(QString path) void MainWindow::openFile(QString path)
{ {
QStringList args; QDesktopServices::openUrl(QUrl::fromLocalFile(path));
args << path;
this->ipcClient->sendCommand(FileOpen, args);
} }
void MainWindow::treeSearchItemActivated(QTreeWidgetItem *item, int i) void MainWindow::treeSearchItemActivated(QTreeWidgetItem *item, int i)
{ {
ipcFileOpen(item->text(1)); openFile(item->text(1));
} }
void MainWindow::showSearchResultsContextMenu(const QPoint &point) void MainWindow::showSearchResultsContextMenu(const QPoint &point)

查看文件

@ -9,9 +9,8 @@
#include <QFutureWatcher> #include <QFutureWatcher>
#include <QSqlDatabase> #include <QSqlDatabase>
#include <QLocalSocket> #include <QLocalSocket>
#include "previewworker.h"
#include "../shared/looqsquery.h" #include "../shared/looqsquery.h"
#include "ipcclient.h" #include "ipcpreviewclient.h"
#include "indexer.h" #include "indexer.h"
namespace Ui namespace Ui
{ {
@ -23,7 +22,7 @@ class MainWindow : public QMainWindow
Q_OBJECT Q_OBJECT
public: public:
explicit MainWindow(QWidget *parent, IPCClient &client); explicit MainWindow(QWidget *parent, QString socketPath);
~MainWindow(); ~MainWindow();
signals: signals:
void beginSearch(const QString &query); void beginSearch(const QString &query);
@ -33,13 +32,14 @@ class MainWindow : public QMainWindow
DatabaseFactory *dbFactory; DatabaseFactory *dbFactory;
SqliteDbService *dbService; SqliteDbService *dbService;
Ui::MainWindow *ui; Ui::MainWindow *ui;
IPCClient *ipcClient; IPCPreviewClient ipcPreviewClient;
QThread ipcClientThread;
Indexer *indexer; Indexer *indexer;
QFileIconProvider iconProvider; QFileIconProvider iconProvider;
bool previewDirty; bool previewDirty;
QSqlDatabase db; QSqlDatabase db;
QFutureWatcher<QVector<SearchResult>> searchWatcher; QFutureWatcher<QVector<SearchResult>> searchWatcher;
QFutureWatcher<QSharedPointer<PreviewResult>> previewWorkerWatcher;
void add(QString path, unsigned int page); void add(QString path, unsigned int page);
QVector<SearchResult> previewableSearchResults; QVector<SearchResult> previewableSearchResults;
void connectSignals(); void connectSignals();
@ -53,20 +53,24 @@ class MainWindow : public QMainWindow
LooqsQuery contentSearchQuery; LooqsQuery contentSearchQuery;
int previewsPerPage; int previewsPerPage;
void createSearchResutlMenu(QMenu &menu, const QFileInfo &fileInfo); void createSearchResutlMenu(QMenu &menu, const QFileInfo &fileInfo);
void ipcDocOpen(QString path, int num); void openDocument(QString path, int num);
void ipcFileOpen(QString path); void openFile(QString path);
unsigned int currentPreviewGeneration = 1;
private slots: private slots:
void lineEditReturnPressed(); void lineEditReturnPressed();
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); void previewReceived(QSharedPointer<PreviewResult> preview, unsigned int previewGeneration);
void comboScaleChanged(int i); void comboScaleChanged(int i);
void spinPreviewPageValueChanged(int val); void spinPreviewPageValueChanged(int val);
void startIndexing(); void startIndexing();
void finishIndexing(); void finishIndexing();
void addPathToIndex(); void addPathToIndex();
signals:
void startIpcPreviews(RenderConfig config, const QVector<RenderTarget> &targets);
void stopIpcPreviews();
}; };
#endif // MAINWINDOW_H #endif // MAINWINDOW_H

查看文件

@ -27,7 +27,7 @@
<enum>QTabWidget::South</enum> <enum>QTabWidget::South</enum>
</property> </property>
<property name="currentIndex"> <property name="currentIndex">
<number>2</number> <number>1</number>
</property> </property>
<widget class="QWidget" name="resultsTab"> <widget class="QWidget" name="resultsTab">
<attribute name="title"> <attribute name="title">
@ -155,6 +155,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QLabel" name="lblTotalPreviewPagesCount">
<property name="text">
<string/>
</property>
</widget>
</item>
<item> <item>
<spacer name="horizontalSpacer"> <spacer name="horizontalSpacer">
<property name="orientation"> <property name="orientation">
@ -349,7 +356,7 @@
<item> <item>
<widget class="QProgressBar" name="previewProcessBar"> <widget class="QProgressBar" name="previewProcessBar">
<property name="value"> <property name="value">
<number>24</number> <number>0</number>
</property> </property>
</widget> </widget>
</item> </item>

查看文件

@ -156,6 +156,9 @@ QString Common::databasePath()
QString Common::ipcSocketPath() QString Common::ipcSocketPath()
{ {
QSettings settings; return "/tmp/.looqs/looqs-ipc-socket";
return settings.value(SETTINGS_KEY_IPCSOCKETPATH, "/tmp/looqs-spawner").toString();
/* May not a good idea to set it in the settings and probably nobody would ever bother to change it anyway */
// QSettings settings;
// return settings.value(SETTINGS_KEY_IPCSOCKETPATH, "/tmp/.looqs/looqs-ipc-socket").toString();
} }