Comparar commits
22 Commits
b137dec434
...
80a4551f8b
Autor | SHA1 | Data | |
---|---|---|---|
80a4551f8b | |||
fa10cb606b | |||
b90ff840d9 | |||
86cc16d15d | |||
69c2956a1f | |||
82a4205c23 | |||
8d96f6e4ce | |||
d39157b58d | |||
a43ab169b5 | |||
ee19692a7a | |||
773325f2de | |||
065dcf8906 | |||
13f28c37c6 | |||
8f2e77b152 | |||
3bdcb76d8e | |||
ee18142e36 | |||
3e03fed1a2 | |||
6439adffc6 | |||
02642a147a | |||
fe29641d0a | |||
830226ae59 | |||
6a5cb69e27 |
@ -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)
|
||||||
|
|
||||||
|
13
gui/gui.pro
13
gui/gui.pro
@ -23,7 +23,8 @@ DEFINES += QT_DEPRECATED_WARNINGS
|
|||||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
ipcclient.cpp \
|
ipcpreviewclient.cpp \
|
||||||
|
ipcpreviewworker.cpp \
|
||||||
ipcserver.cpp \
|
ipcserver.cpp \
|
||||||
main.cpp \
|
main.cpp \
|
||||||
mainwindow.cpp \
|
mainwindow.cpp \
|
||||||
@ -35,11 +36,13 @@ SOURCES += \
|
|||||||
previewresult.cpp \
|
previewresult.cpp \
|
||||||
previewresultpdf.cpp \
|
previewresultpdf.cpp \
|
||||||
previewresultplaintext.cpp \
|
previewresultplaintext.cpp \
|
||||||
previewworker.cpp
|
renderconfig.cpp \
|
||||||
|
rendertarget.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
ipc.h \
|
ipc.h \
|
||||||
ipcclient.h \
|
ipcpreviewclient.h \
|
||||||
|
ipcpreviewworker.h \
|
||||||
ipcserver.h \
|
ipcserver.h \
|
||||||
mainwindow.h \
|
mainwindow.h \
|
||||||
clicklabel.h \
|
clicklabel.h \
|
||||||
@ -50,8 +53,8 @@ HEADERS += \
|
|||||||
previewresult.h \
|
previewresult.h \
|
||||||
previewresultpdf.h \
|
previewresultpdf.h \
|
||||||
previewresultplaintext.h \
|
previewresultplaintext.h \
|
||||||
previewworker.h \
|
renderconfig.h \
|
||||||
renderconfig.h
|
rendertarget.h
|
||||||
|
|
||||||
FORMS += \
|
FORMS += \
|
||||||
mainwindow.ui
|
mainwindow.ui
|
||||||
|
11
gui/ipc.h
11
gui/ipc.h
@ -3,8 +3,13 @@
|
|||||||
|
|
||||||
enum IPCCommand
|
enum IPCCommand
|
||||||
{
|
{
|
||||||
DocOpen,
|
GeneratePreviews = 23,
|
||||||
FileOpen,
|
StopGeneratePreviews,
|
||||||
AddFile,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum IPCReply
|
||||||
|
{
|
||||||
|
FinishedGeneratePreviews,
|
||||||
|
};
|
||||||
|
|
||||||
#endif // IPC_H
|
#endif // IPC_H
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
#include <QDataStream>
|
|
||||||
#include "ipcclient.h"
|
|
||||||
|
|
||||||
IPCClient::IPCClient(QString socketPath)
|
|
||||||
{
|
|
||||||
this->socketPath = socketPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IPCClient::sendCommand(IPCCommand command, QStringList args)
|
|
||||||
{
|
|
||||||
bool result = false;
|
|
||||||
QLocalSocket socket;
|
|
||||||
socket.connectToServer(socketPath);
|
|
||||||
if(socket.isOpen() && socket.isWritable())
|
|
||||||
{
|
|
||||||
QDataStream stream(&socket);
|
|
||||||
stream << command;
|
|
||||||
stream << args;
|
|
||||||
socket.flush();
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
qDebug() << "Not connected to IPC server";
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
#ifndef IPCCLIENT_H
|
|
||||||
#define IPCCLIENT_H
|
|
||||||
#include <QLocalSocket>
|
|
||||||
#include <QString>
|
|
||||||
#include <QStringList>
|
|
||||||
#include "ipc.h"
|
|
||||||
|
|
||||||
class IPCClient
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
QString socketPath;
|
|
||||||
|
|
||||||
public:
|
|
||||||
IPCClient(QString socketPath);
|
|
||||||
bool sendCommand(IPCCommand command, QStringList args);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // IPCCLIENT_H
|
|
129
gui/ipcpreviewclient.cpp
Arquivo normal
129
gui/ipcpreviewclient.cpp
Arquivo normal
@ -0,0 +1,129 @@
|
|||||||
|
#include <QLocalSocket>
|
||||||
|
#include <QApplication>
|
||||||
|
#include "ipc.h"
|
||||||
|
#include "ipcpreviewclient.h"
|
||||||
|
#include "previewresultpdf.h"
|
||||||
|
#include "previewresultplaintext.h"
|
||||||
|
|
||||||
|
bool IPCPreviewClient::connect()
|
||||||
|
{
|
||||||
|
if(socket->state() == QLocalSocket::ConnectedState)
|
||||||
|
{
|
||||||
|
socket->disconnectFromServer();
|
||||||
|
if(socket->state() == QLocalSocket::ConnectedState)
|
||||||
|
{
|
||||||
|
socket->waitForDisconnected(100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
socket->connectToServer(socketPath);
|
||||||
|
socket->waitForConnected(100);
|
||||||
|
return socket->state() == QLocalSocket::ConnectedState;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSharedPointer<PreviewResult> IPCPreviewClient::deserialize(QByteArray &array)
|
||||||
|
{
|
||||||
|
QDataStream stream{&array, QIODevice::ReadOnly};
|
||||||
|
|
||||||
|
PreviewResultType type;
|
||||||
|
stream >> type;
|
||||||
|
if(type == PreviewResultType::PDF)
|
||||||
|
{
|
||||||
|
return PreviewResultPdf::deserialize(array);
|
||||||
|
}
|
||||||
|
if(type == PreviewResultType::PlainText)
|
||||||
|
{
|
||||||
|
return PreviewResultPlainText::deserialize(array);
|
||||||
|
}
|
||||||
|
return QSharedPointer<PreviewResult>(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
IPCPreviewClient::IPCPreviewClient()
|
||||||
|
{
|
||||||
|
this->socket = new QLocalSocket(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IPCPreviewClient::setSocketPath(QString socketPath)
|
||||||
|
{
|
||||||
|
this->socketPath = socketPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IPCPreviewClient::startGeneration(RenderConfig config, const QVector<RenderTarget> &targets)
|
||||||
|
{
|
||||||
|
this->start(config, targets);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IPCPreviewClient::start(RenderConfig config, const QVector<RenderTarget> &targets)
|
||||||
|
{
|
||||||
|
if(targets.count() == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!connect() || !socket->isOpen())
|
||||||
|
{
|
||||||
|
emit error("Could not connect to IPC worker");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(socket->isOpen() && socket->isWritable())
|
||||||
|
{
|
||||||
|
QDataStream stream(socket);
|
||||||
|
stream << GeneratePreviews;
|
||||||
|
stream << config;
|
||||||
|
stream << targets;
|
||||||
|
socket->flush();
|
||||||
|
|
||||||
|
int numTarget = 0;
|
||||||
|
if(socket->isOpen() && socket->isReadable() && socket->state() == QLocalSocket::ConnectedState)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
socket->waitForReadyRead(100);
|
||||||
|
stream.startTransaction();
|
||||||
|
stream >> numTarget;
|
||||||
|
} while(!stream.commitTransaction() && socket->state() == QLocalSocket::ConnectedState);
|
||||||
|
if(numTarget != targets.count())
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Server reports less targets than it should");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
emit error("Error while trying to process previews: " + socket->errorString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int processed = 0;
|
||||||
|
++this->currentPreviewGeneration;
|
||||||
|
while(socket->isOpen() && socket->isReadable() && processed < targets.count())
|
||||||
|
{
|
||||||
|
QByteArray array;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
socket->waitForReadyRead(100);
|
||||||
|
stream.startTransaction();
|
||||||
|
stream >> array;
|
||||||
|
} while(!stream.commitTransaction() && socket->state() == QLocalSocket::ConnectedState);
|
||||||
|
emit previewReceived(deserialize(array), this->currentPreviewGeneration);
|
||||||
|
++processed;
|
||||||
|
}
|
||||||
|
if(processed != targets.count())
|
||||||
|
{
|
||||||
|
emit error("IPC worker didn't send enough previews. This is a bug, please report");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
socket->disconnectFromServer();
|
||||||
|
emit finished();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IPCPreviewClient::stopGeneration()
|
||||||
|
{
|
||||||
|
if(!connect() || !socket->isOpen())
|
||||||
|
{
|
||||||
|
emit error("Could not connect to IPC worker");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QDataStream stream(socket);
|
||||||
|
stream << StopGeneratePreviews;
|
||||||
|
socket->flush();
|
||||||
|
}
|
37
gui/ipcpreviewclient.h
Arquivo normal
37
gui/ipcpreviewclient.h
Arquivo normal
@ -0,0 +1,37 @@
|
|||||||
|
#ifndef IPCPREVIEWCLIENT_H
|
||||||
|
#define IPCPREVIEWCLIENT_H
|
||||||
|
#include <QObject>
|
||||||
|
#include <QLocalSocket>
|
||||||
|
#include "previewresult.h"
|
||||||
|
#include "renderconfig.h"
|
||||||
|
#include "rendertarget.h"
|
||||||
|
|
||||||
|
class IPCPreviewClient : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
private:
|
||||||
|
unsigned int currentPreviewGeneration = 1;
|
||||||
|
QLocalSocket *socket;
|
||||||
|
QString socketPath;
|
||||||
|
|
||||||
|
bool connect();
|
||||||
|
QSharedPointer<PreviewResult> deserialize(QByteArray &array);
|
||||||
|
|
||||||
|
public:
|
||||||
|
IPCPreviewClient();
|
||||||
|
~IPCPreviewClient()
|
||||||
|
{
|
||||||
|
delete socket;
|
||||||
|
}
|
||||||
|
void setSocketPath(QString socketPath);
|
||||||
|
public slots:
|
||||||
|
void start(RenderConfig config, const QVector<RenderTarget> &targets);
|
||||||
|
void startGeneration(RenderConfig config, const QVector<RenderTarget> &targets);
|
||||||
|
void stopGeneration();
|
||||||
|
signals:
|
||||||
|
void previewReceived(QSharedPointer<PreviewResult> previewResult, unsigned int currentPreviewGeneration);
|
||||||
|
void finished();
|
||||||
|
void error(QString);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // IPCPREVIEWCLIENT_H
|
24
gui/ipcpreviewworker.cpp
Arquivo normal
24
gui/ipcpreviewworker.cpp
Arquivo normal
@ -0,0 +1,24 @@
|
|||||||
|
#include <QtConcurrent>
|
||||||
|
#include "ipcpreviewworker.h"
|
||||||
|
#include "previewgeneratormapfunctor.h"
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
stop();
|
||||||
|
auto mapFunctor = PreviewGeneratorMapFunctor();
|
||||||
|
mapFunctor.setRenderConfig(config);
|
||||||
|
|
||||||
|
previewWorkerWatcher.setFuture(QtConcurrent::mapped(targets, mapFunctor));
|
||||||
|
}
|
||||||
|
|
||||||
|
void IPCPreviewWorker::stop()
|
||||||
|
{
|
||||||
|
previewWorkerWatcher.cancel();
|
||||||
|
previewWorkerWatcher.waitForFinished();
|
||||||
|
}
|
24
gui/ipcpreviewworker.h
Arquivo normal
24
gui/ipcpreviewworker.h
Arquivo normal
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef IPCPREVIEWWORKER_H
|
||||||
|
#define IPCPREVIEWWORKER_H
|
||||||
|
#include <QLocalSocket>
|
||||||
|
#include <QFutureWatcher>
|
||||||
|
#include "renderconfig.h"
|
||||||
|
#include "rendertarget.h"
|
||||||
|
#include "previewgenerator.h"
|
||||||
|
|
||||||
|
class IPCPreviewWorker : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
private:
|
||||||
|
QFutureWatcher<QByteArray> previewWorkerWatcher;
|
||||||
|
|
||||||
|
public:
|
||||||
|
IPCPreviewWorker();
|
||||||
|
void start(RenderConfig config, const QVector<RenderTarget> &targets, QLocalSocket *peer);
|
||||||
|
void stop();
|
||||||
|
signals:
|
||||||
|
void previewGenerated(QByteArray);
|
||||||
|
void finished();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // IPCPREVIEWWORKER_H
|
@ -9,13 +9,17 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "databasefactory.h"
|
#include "databasefactory.h"
|
||||||
#include "../shared/logger.h"
|
#include "../shared/logger.h"
|
||||||
|
#include "renderconfig.h"
|
||||||
|
#include "rendertarget.h"
|
||||||
|
#include "ipcpreviewworker.h"
|
||||||
|
|
||||||
IpcServer::IpcServer()
|
IpcServer::IpcServer()
|
||||||
{
|
{
|
||||||
this->dbFactory = QSharedPointer<DatabaseFactory>(new DatabaseFactory(Common::databasePath()));
|
/* Only 1, we are doing work for the GUI, not a service for general availability */
|
||||||
this->dbService = QSharedPointer<SqliteDbService>(new SqliteDbService(*this->dbFactory.get()));
|
this->spawningServer.setMaxPendingConnections(1);
|
||||||
this->fileSaver = QSharedPointer<FileSaver>(new FileSaver(*this->dbService.get()));
|
|
||||||
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)
|
||||||
@ -24,85 +28,46 @@ bool IpcServer::startSpawner(QString socketPath)
|
|||||||
return this->spawningServer.listen(socketPath);
|
return this->spawningServer.listen(socketPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IpcServer::docOpen(QString path, int pagenum)
|
|
||||||
{
|
|
||||||
|
|
||||||
QSettings settings;
|
|
||||||
QString command = settings.value("pdfviewer").toString();
|
|
||||||
if(path.endsWith(".pdf") && command != "" && command.contains("%p") && command.contains("%f"))
|
|
||||||
{
|
|
||||||
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(pagenum));
|
|
||||||
|
|
||||||
QProcess::startDetached(cmd, args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
QDesktopServices::openUrl(QUrl::fromLocalFile(path));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IpcServer::fileOpen(QString path)
|
|
||||||
{
|
|
||||||
return QDesktopServices::openUrl(QUrl::fromLocalFile(path));
|
|
||||||
}
|
|
||||||
|
|
||||||
SaveFileResult IpcServer::addFile(QString file)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return this->fileSaver->addFile(file);
|
|
||||||
}
|
|
||||||
catch(std::exception &e)
|
|
||||||
{
|
|
||||||
Logger::error() << e.what() << Qt::endl;
|
|
||||||
return PROCESSFAIL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void IpcServer::spawnerNewConnection()
|
void IpcServer::spawnerNewConnection()
|
||||||
{
|
{
|
||||||
QScopedPointer<QLocalSocket> socket{this->spawningServer.nextPendingConnection()};
|
QLocalSocket *socket = this->spawningServer.nextPendingConnection();
|
||||||
if(!socket.isNull())
|
connect(socket, &QLocalSocket::disconnected, socket, &QLocalSocket::deleteLater);
|
||||||
|
this->currentSocket = socket;
|
||||||
|
if(socket != nullptr)
|
||||||
{
|
{
|
||||||
if(!socket->waitForReadyRead())
|
if(!socket->waitForReadyRead())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QDataStream stream(socket.get());
|
QDataStream stream(socket);
|
||||||
IPCCommand command;
|
IPCCommand command;
|
||||||
QStringList args;
|
|
||||||
stream >> command;
|
stream >> command;
|
||||||
stream >> args;
|
if(command == GeneratePreviews)
|
||||||
if(args.size() < 1)
|
|
||||||
{
|
{
|
||||||
stream << "invalid";
|
RenderConfig renderConfig;
|
||||||
return;
|
QVector<RenderTarget> targets;
|
||||||
}
|
do
|
||||||
if(command == DocOpen)
|
|
||||||
{
|
|
||||||
if(args.size() < 2)
|
|
||||||
{
|
{
|
||||||
stream << "invalid";
|
/* TODO: this is not entirely robust */
|
||||||
return;
|
socket->waitForReadyRead(100);
|
||||||
}
|
stream.startTransaction();
|
||||||
docOpen(args[0], args[1].toInt());
|
stream >> renderConfig >> targets;
|
||||||
|
} while(!stream.commitTransaction() && socket->state() == QLocalSocket::ConnectedState);
|
||||||
|
|
||||||
|
stream << targets.count();
|
||||||
|
socket->flush();
|
||||||
|
previewWorker.start(renderConfig, targets, socket);
|
||||||
}
|
}
|
||||||
if(command == FileOpen)
|
if(command == StopGeneratePreviews)
|
||||||
{
|
{
|
||||||
if(args.size() < 1)
|
previewWorker.stop();
|
||||||
{
|
|
||||||
stream << "invalid";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fileOpen(args[0]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IpcServer::handlePreviewGenerated(QByteArray ba)
|
||||||
|
{
|
||||||
|
QDataStream stream{this->currentSocket};
|
||||||
|
stream << ba;
|
||||||
|
this->currentSocket->flush();
|
||||||
|
}
|
||||||
|
@ -4,19 +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:
|
||||||
QSharedPointer<DatabaseFactory> dbFactory;
|
IPCPreviewWorker previewWorker;
|
||||||
QSharedPointer<SqliteDbService> dbService;
|
|
||||||
QSharedPointer<FileSaver> fileSaver;
|
|
||||||
QLocalServer spawningServer;
|
QLocalServer spawningServer;
|
||||||
bool docOpen(QString path, int pagenum);
|
QLocalSocket *currentSocket = nullptr;
|
||||||
bool fileOpen(QString path);
|
|
||||||
SaveFileResult addFile(QString file);
|
SaveFileResult addFile(QString file);
|
||||||
private slots:
|
private slots:
|
||||||
void spawnerNewConnection();
|
void spawnerNewConnection();
|
||||||
|
void handlePreviewGenerated(QByteArray ba);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IpcServer();
|
IpcServer();
|
||||||
|
59
gui/main.cpp
59
gui/main.cpp
@ -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,18 @@ 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,
|
/* connect(&previewWorkerWatcher, &QFutureWatcher<QByteArray>::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); });
|
[&] { 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 +291,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 +392,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 +409,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 +440,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 +490,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>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
class PreviewGenerator
|
class PreviewGenerator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual PreviewResult *generate(RenderConfig config, QString documentPath, unsigned int page) = 0;
|
virtual QSharedPointer<PreviewResult> generate(RenderConfig config, QString documentPath, unsigned int page) = 0;
|
||||||
virtual ~PreviewGenerator()
|
virtual ~PreviewGenerator()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -10,16 +10,15 @@ void PreviewGeneratorMapFunctor::setRenderConfig(RenderConfig config)
|
|||||||
this->renderConfig = config;
|
this->renderConfig = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
QSharedPointer<PreviewResult> PreviewGeneratorMapFunctor::operator()(const QSharedPointer<PreviewResult> &renderResult)
|
QByteArray PreviewGeneratorMapFunctor::operator()(const RenderTarget &renderTarget)
|
||||||
{
|
{
|
||||||
QFileInfo info{renderResult->getDocumentPath()};
|
QFileInfo info{renderTarget.path};
|
||||||
PreviewGenerator *previewGenerator = PreviewGenerator::get(info);
|
PreviewGenerator *previewGenerator = PreviewGenerator::get(info);
|
||||||
if(previewGenerator == nullptr)
|
if(previewGenerator == nullptr)
|
||||||
{
|
{
|
||||||
return QSharedPointer<PreviewResult>();
|
return QByteArray{};
|
||||||
}
|
}
|
||||||
auto preview =
|
auto preview = previewGenerator->generate(this->renderConfig, renderTarget.path, renderTarget.page);
|
||||||
previewGenerator->generate(this->renderConfig, renderResult->getDocumentPath(), renderResult->getPage());
|
|
||||||
|
|
||||||
return QSharedPointer<PreviewResult>(preview);
|
return preview->serialize();
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,9 @@
|
|||||||
#define PREVIEWGENERATORMAPFUNCTOR_H
|
#define PREVIEWGENERATORMAPFUNCTOR_H
|
||||||
|
|
||||||
#include "renderconfig.h"
|
#include "renderconfig.h"
|
||||||
#include "previewgenerator.h"
|
#include "rendertarget.h"
|
||||||
|
|
||||||
|
#include "previewgenerator.h"
|
||||||
class PreviewGeneratorMapFunctor
|
class PreviewGeneratorMapFunctor
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -16,13 +17,13 @@ class PreviewGeneratorMapFunctor
|
|||||||
RenderConfig renderConfig;
|
RenderConfig renderConfig;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef QSharedPointer<PreviewResult> result_type;
|
typedef QByteArray result_type;
|
||||||
|
|
||||||
PreviewGeneratorMapFunctor();
|
PreviewGeneratorMapFunctor();
|
||||||
|
|
||||||
void setRenderConfig(RenderConfig config);
|
void setRenderConfig(RenderConfig config);
|
||||||
|
|
||||||
QSharedPointer<PreviewResult> operator()(const QSharedPointer<PreviewResult> &renderResult);
|
QByteArray operator()(const RenderTarget &renderTarget);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PREVIEWGENERATORMAPFUNCTOR_H
|
#endif // PREVIEWGENERATORMAPFUNCTOR_H
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#include <QMutexLocker>
|
#include <QMutexLocker>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
|
||||||
#include "previewgeneratorpdf.h"
|
#include "previewgeneratorpdf.h"
|
||||||
|
|
||||||
static QMutex cacheMutex;
|
static QMutex cacheMutex;
|
||||||
@ -24,18 +23,18 @@ Poppler::Document *PreviewGeneratorPdf::document(QString path)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
PreviewResult *PreviewGeneratorPdf::generate(RenderConfig config, QString documentPath, unsigned int page)
|
QSharedPointer<PreviewResult> PreviewGeneratorPdf::generate(RenderConfig config, QString documentPath,
|
||||||
|
unsigned int page)
|
||||||
{
|
{
|
||||||
PreviewResultPdf *result = new PreviewResultPdf(documentPath, page);
|
PreviewResultPdf *result = new PreviewResultPdf(documentPath, page);
|
||||||
|
|
||||||
Poppler::Document *doc = document(documentPath);
|
Poppler::Document *doc = document(documentPath);
|
||||||
if(doc == nullptr)
|
if(doc == nullptr)
|
||||||
{
|
{
|
||||||
return result;
|
return QSharedPointer<PreviewResult>(result);
|
||||||
}
|
}
|
||||||
if(doc->isLocked())
|
if(doc->isLocked())
|
||||||
{
|
{
|
||||||
return result;
|
return QSharedPointer<PreviewResult>(result);
|
||||||
}
|
}
|
||||||
int p = (int)page - 1;
|
int p = (int)page - 1;
|
||||||
if(p < 0)
|
if(p < 0)
|
||||||
@ -55,5 +54,5 @@ PreviewResult *PreviewGeneratorPdf::generate(RenderConfig config, QString docume
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
result->previewImage = img;
|
result->previewImage = img;
|
||||||
return result;
|
return QSharedPointer<PreviewResult>(result);
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ class PreviewGeneratorPdf : public PreviewGenerator
|
|||||||
public:
|
public:
|
||||||
using PreviewGenerator::PreviewGenerator;
|
using PreviewGenerator::PreviewGenerator;
|
||||||
|
|
||||||
PreviewResult *generate(RenderConfig config, QString documentPath, unsigned int page);
|
QSharedPointer<PreviewResult> generate(RenderConfig config, QString documentPath, unsigned int page);
|
||||||
|
|
||||||
~PreviewGeneratorPdf()
|
~PreviewGeneratorPdf()
|
||||||
{
|
{
|
||||||
|
@ -3,13 +3,14 @@
|
|||||||
#include "previewgeneratorplaintext.h"
|
#include "previewgeneratorplaintext.h"
|
||||||
#include "previewresultplaintext.h"
|
#include "previewresultplaintext.h"
|
||||||
|
|
||||||
PreviewResult *PreviewGeneratorPlainText::generate(RenderConfig config, QString documentPath, unsigned int page)
|
QSharedPointer<PreviewResult> PreviewGeneratorPlainText::generate(RenderConfig config, QString documentPath,
|
||||||
|
unsigned int page)
|
||||||
{
|
{
|
||||||
PreviewResultPlainText *result = new PreviewResultPlainText(documentPath, page);
|
PreviewResultPlainText *result = new PreviewResultPlainText(documentPath, page);
|
||||||
QFile file(documentPath);
|
QFile file(documentPath);
|
||||||
if(!file.open(QFile::ReadOnly | QFile::Text))
|
if(!file.open(QFile::ReadOnly | QFile::Text))
|
||||||
{
|
{
|
||||||
return result;
|
return QSharedPointer<PreviewResultPlainText>(result);
|
||||||
}
|
}
|
||||||
QTextStream in(&file);
|
QTextStream in(&file);
|
||||||
|
|
||||||
@ -77,5 +78,5 @@ PreviewResult *PreviewGeneratorPlainText::generate(RenderConfig config, QString
|
|||||||
header += "<hr>";
|
header += "<hr>";
|
||||||
|
|
||||||
result->setText(header + resulText.replace("\n", "<br>"));
|
result->setText(header + resulText.replace("\n", "<br>"));
|
||||||
return result;
|
return QSharedPointer<PreviewResultPlainText>(result);
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ class PreviewGeneratorPlainText : public PreviewGenerator
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using PreviewGenerator::PreviewGenerator;
|
using PreviewGenerator::PreviewGenerator;
|
||||||
PreviewResult *generate(RenderConfig config, QString documentPath, unsigned int page);
|
QSharedPointer<PreviewResult> generate(RenderConfig config, QString documentPath, unsigned int page);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PREVIEWGENERATORPLAINTEXT_H
|
#endif // PREVIEWGENERATORPLAINTEXT_H
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#include "previewresult.h"
|
#include "previewresult.h"
|
||||||
|
|
||||||
PreviewResult::PreviewResult()
|
PreviewResult::PreviewResult()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -33,3 +32,11 @@ unsigned int PreviewResult::getPage() const
|
|||||||
{
|
{
|
||||||
return this->page;
|
return this->page;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QByteArray PreviewResult::serialize() const
|
||||||
|
{
|
||||||
|
QByteArray result;
|
||||||
|
QDataStream stream{&result, QIODevice::WriteOnly};
|
||||||
|
stream << 0 << this->documentPath << this->page;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
@ -2,6 +2,12 @@
|
|||||||
#define PREVIEWRESULT_H
|
#define PREVIEWRESULT_H
|
||||||
#include "clicklabel.h"
|
#include "clicklabel.h"
|
||||||
|
|
||||||
|
enum PreviewResultType
|
||||||
|
{
|
||||||
|
PDF = 1,
|
||||||
|
PlainText
|
||||||
|
};
|
||||||
|
|
||||||
class PreviewResult
|
class PreviewResult
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
@ -17,6 +23,7 @@ class PreviewResult
|
|||||||
virtual bool hasPreview();
|
virtual bool hasPreview();
|
||||||
QString getDocumentPath() const;
|
QString getDocumentPath() const;
|
||||||
unsigned int getPage() const;
|
unsigned int getPage() const;
|
||||||
|
virtual QByteArray serialize() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PREVIEWRESULT_H
|
#endif // PREVIEWRESULT_H
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#include "previewresultpdf.h"
|
#include "previewresultpdf.h"
|
||||||
|
|
||||||
PreviewResultPdf::PreviewResultPdf(const PreviewResult &o)
|
PreviewResultPdf::PreviewResultPdf(const PreviewResult &o)
|
||||||
{
|
{
|
||||||
this->documentPath = o.getDocumentPath();
|
this->documentPath = o.getDocumentPath();
|
||||||
@ -19,3 +18,27 @@ bool PreviewResultPdf::hasPreview()
|
|||||||
bool result = !this->previewImage.isNull();
|
bool result = !this->previewImage.isNull();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QByteArray PreviewResultPdf::serialize() const
|
||||||
|
{
|
||||||
|
QByteArray result;
|
||||||
|
QDataStream stream{&result, QIODevice::WriteOnly};
|
||||||
|
PreviewResultType type = PreviewResultType::PDF;
|
||||||
|
stream << type << this->documentPath << this->page << this->previewImage;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSharedPointer<PreviewResultPdf> PreviewResultPdf::deserialize(QByteArray &ba)
|
||||||
|
{
|
||||||
|
PreviewResultPdf *result = new PreviewResultPdf();
|
||||||
|
PreviewResultType type;
|
||||||
|
|
||||||
|
QDataStream stream{&ba, QIODevice::ReadOnly};
|
||||||
|
stream >> type;
|
||||||
|
if(type != PreviewResultType::PDF)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Invalid byte array: Not a pdf preview");
|
||||||
|
}
|
||||||
|
stream >> result->documentPath >> result->page >> result->previewImage;
|
||||||
|
return QSharedPointer<PreviewResultPdf>(result);
|
||||||
|
}
|
||||||
|
@ -12,6 +12,10 @@ class PreviewResultPdf : public PreviewResult
|
|||||||
|
|
||||||
QWidget *createPreviewWidget() override;
|
QWidget *createPreviewWidget() override;
|
||||||
bool hasPreview() override;
|
bool hasPreview() override;
|
||||||
|
|
||||||
|
QByteArray serialize() const;
|
||||||
|
|
||||||
|
static QSharedPointer<PreviewResultPdf> deserialize(QByteArray &ba);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PREVIEWRESULTPDF_H
|
#endif // PREVIEWRESULTPDF_H
|
||||||
|
@ -28,3 +28,27 @@ void PreviewResultPlainText::setText(QString text)
|
|||||||
{
|
{
|
||||||
this->text = text;
|
this->text = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QByteArray PreviewResultPlainText::serialize() const
|
||||||
|
{
|
||||||
|
QByteArray result;
|
||||||
|
QDataStream stream{&result, QIODevice::WriteOnly};
|
||||||
|
PreviewResultType type = PreviewResultType::PlainText;
|
||||||
|
stream << type << this->documentPath << this->page << this->text;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSharedPointer<PreviewResultPlainText> PreviewResultPlainText::deserialize(QByteArray &ba)
|
||||||
|
{
|
||||||
|
PreviewResultPlainText *result = new PreviewResultPlainText();
|
||||||
|
PreviewResultType type;
|
||||||
|
|
||||||
|
QDataStream stream{&ba, QIODevice::ReadOnly};
|
||||||
|
stream >> type;
|
||||||
|
if(type != PreviewResultType::PlainText)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Invalid byte array: Not a pdf preview");
|
||||||
|
}
|
||||||
|
stream >> result->documentPath >> result->page >> result->text;
|
||||||
|
return QSharedPointer<PreviewResultPlainText>(result);
|
||||||
|
}
|
||||||
|
@ -15,6 +15,9 @@ class PreviewResultPlainText : public PreviewResult
|
|||||||
bool hasPreview() override;
|
bool hasPreview() override;
|
||||||
|
|
||||||
void setText(QString text);
|
void setText(QString text);
|
||||||
|
|
||||||
|
QByteArray serialize() const;
|
||||||
|
static QSharedPointer<PreviewResultPlainText> deserialize(QByteArray &ba);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PREVIEWRESULTPLAINTEXT_H
|
#endif // PREVIEWRESULTPLAINTEXT_H
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
#include <QApplication>
|
|
||||||
#include <QScreen>
|
|
||||||
#include <QScopedPointer>
|
|
||||||
#include <QMutexLocker>
|
|
||||||
#include <QtConcurrent/QtConcurrent>
|
|
||||||
#include <QtConcurrent/QtConcurrentMap>
|
|
||||||
#include <atomic>
|
|
||||||
#include "previewworker.h"
|
|
||||||
|
|
||||||
PreviewWorker::PreviewWorker()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
QFuture<QSharedPointer<PreviewResult>> PreviewWorker::generatePreviews(const QVector<SearchResult> paths,
|
|
||||||
QVector<QString> wordsToHighlight,
|
|
||||||
double scalefactor)
|
|
||||||
{
|
|
||||||
QVector<QSharedPointer<PreviewResult>> previews;
|
|
||||||
|
|
||||||
for(const SearchResult &sr : paths)
|
|
||||||
{
|
|
||||||
for(unsigned int page : sr.pages)
|
|
||||||
{
|
|
||||||
QSharedPointer<PreviewResult> ptr =
|
|
||||||
QSharedPointer<PreviewResult>(new PreviewResult{sr.fileData.absPath, page});
|
|
||||||
previews.append(ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RenderConfig renderConfig;
|
|
||||||
renderConfig.scaleX = QGuiApplication::primaryScreen()->physicalDotsPerInchX() * scalefactor;
|
|
||||||
renderConfig.scaleY = QGuiApplication::primaryScreen()->physicalDotsPerInchY() * scalefactor;
|
|
||||||
renderConfig.wordsToHighlight = wordsToHighlight;
|
|
||||||
|
|
||||||
auto mapFunctor = new PreviewGeneratorMapFunctor();
|
|
||||||
mapFunctor->setRenderConfig(renderConfig);
|
|
||||||
|
|
||||||
return QtConcurrent::mapped(previews, *mapFunctor);
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
#ifndef PREVIEWWORKER_H
|
|
||||||
#define PREVIEWWORKER_H
|
|
||||||
#include <QObject>
|
|
||||||
#include <QImage>
|
|
||||||
#include <QHash>
|
|
||||||
#include <QThread>
|
|
||||||
#include <QMutex>
|
|
||||||
#include <QWaitCondition>
|
|
||||||
#include <QMutex>
|
|
||||||
#include <QFuture>
|
|
||||||
#include "previewresultpdf.h"
|
|
||||||
#include "searchresult.h"
|
|
||||||
#include "previewgenerator.h"
|
|
||||||
#include "previewworker.h"
|
|
||||||
#include "previewgeneratorpdf.h"
|
|
||||||
#include "previewgeneratormapfunctor.h"
|
|
||||||
|
|
||||||
class PreviewWorker : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
PreviewWorker();
|
|
||||||
QSharedPointer<PreviewGenerator> createGenerator(QString path);
|
|
||||||
|
|
||||||
QFuture<QSharedPointer<PreviewResult>> generatePreviews(const QVector<SearchResult> paths,
|
|
||||||
QVector<QString> wordsToHighlight, double scalefactor);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // PREVIEWWORKER_H
|
|
17
gui/renderconfig.cpp
Arquivo normal
17
gui/renderconfig.cpp
Arquivo normal
@ -0,0 +1,17 @@
|
|||||||
|
#include "renderconfig.h"
|
||||||
|
|
||||||
|
QDataStream &operator<<(QDataStream &out, const RenderConfig &rc)
|
||||||
|
{
|
||||||
|
out << rc.scaleX;
|
||||||
|
out << rc.scaleY;
|
||||||
|
out << rc.wordsToHighlight;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDataStream &operator>>(QDataStream &in, RenderConfig &rc)
|
||||||
|
{
|
||||||
|
in >> rc.scaleX;
|
||||||
|
in >> rc.scaleY;
|
||||||
|
in >> rc.wordsToHighlight;
|
||||||
|
return in;
|
||||||
|
}
|
@ -1,12 +1,17 @@
|
|||||||
#ifndef RENDERCONFIG_H
|
#ifndef RENDERCONFIG_H
|
||||||
#define RENDERCONFIG_H
|
#define RENDERCONFIG_H
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
#include <QDataStream>
|
||||||
|
|
||||||
struct RenderConfig
|
struct RenderConfig
|
||||||
{
|
{
|
||||||
double scaleX = 50 / 100.;
|
double scaleX = 50 / 100.;
|
||||||
double scaleY = scaleX;
|
double scaleY = scaleX;
|
||||||
QVector<QString> wordsToHighlight;
|
QVector<QString> wordsToHighlight;
|
||||||
|
friend QDataStream &operator<<(QDataStream &out, const RenderConfig &rc);
|
||||||
|
friend QDataStream &operator>>(QDataStream &in, RenderConfig &rc);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
QDataStream &operator<<(QDataStream &out, const RenderConfig &rc);
|
||||||
|
QDataStream &operator>>(QDataStream &in, RenderConfig &rc);
|
||||||
#endif // RENDERCONFIG_H
|
#endif // RENDERCONFIG_H
|
||||||
|
14
gui/rendertarget.cpp
Arquivo normal
14
gui/rendertarget.cpp
Arquivo normal
@ -0,0 +1,14 @@
|
|||||||
|
#include <QDataStream>
|
||||||
|
|
||||||
|
#include "rendertarget.h"
|
||||||
|
QDataStream &operator<<(QDataStream &out, const RenderTarget &rc)
|
||||||
|
{
|
||||||
|
out << rc.path << rc.page;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDataStream &operator>>(QDataStream &in, RenderTarget &rc)
|
||||||
|
{
|
||||||
|
in >> rc.path >> rc.page;
|
||||||
|
return in;
|
||||||
|
}
|
15
gui/rendertarget.h
Arquivo normal
15
gui/rendertarget.h
Arquivo normal
@ -0,0 +1,15 @@
|
|||||||
|
#ifndef RENDERTARGET_H
|
||||||
|
#define RENDERTARGET_H
|
||||||
|
#include <QString>
|
||||||
|
struct RenderTarget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QString path;
|
||||||
|
int page;
|
||||||
|
friend QDataStream &operator<<(QDataStream &out, const RenderTarget &rc);
|
||||||
|
friend QDataStream &operator>>(QDataStream &in, RenderTarget &rc);
|
||||||
|
};
|
||||||
|
|
||||||
|
QDataStream &operator<<(QDataStream &out, const RenderTarget &rc);
|
||||||
|
QDataStream &operator>>(QDataStream &in, RenderTarget &rc);
|
||||||
|
#endif // RENDERTARGET_H
|
@ -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();
|
||||||
}
|
}
|
||||||
|
Carregando…
Referência em uma nova issue
Block a user