比較提交
10 次程式碼提交
v0.6
...
WIP/refact
作者 | SHA1 | 日期 | |
---|---|---|---|
7afbc60195 | |||
10d61acbd0 | |||
eef0fae137 | |||
d8205a0da4 | |||
877224b6e1 | |||
14730ed208 | |||
fe610d3068 | |||
0c1b57d911 | |||
2885e40a3a | |||
c0f4087937 |
@ -33,11 +33,18 @@ int CommandSearch::handle(QStringList arguments)
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
QHash<QString, bool> seenMap;
|
||||
auto results = dbService->search(query);
|
||||
|
||||
for(SearchResult &result : results)
|
||||
for(const SearchResult &result : results)
|
||||
{
|
||||
Logger::info() << result.fileData.absPath << Qt::endl;
|
||||
const QString &absPath = result.fileData.absPath;
|
||||
if(!seenMap.contains(absPath))
|
||||
{
|
||||
seenMap[absPath] = true;
|
||||
Logger::info() << absPath << Qt::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(LooqsGeneralException &e)
|
||||
|
@ -1,16 +1,50 @@
|
||||
#include <QtConcurrent>
|
||||
#include "ipcpreviewworker.h"
|
||||
#include "previewgeneratormapfunctor.h"
|
||||
IPCPreviewWorker::IPCPreviewWorker()
|
||||
IPCPreviewWorker::IPCPreviewWorker(QLocalSocket *peer)
|
||||
{
|
||||
this->peer = peer;
|
||||
this->connect(&previewWorkerWatcher, &QFutureWatcher<QByteArray>::resultReadyAt, this,
|
||||
[this](int index) { emit previewGenerated(previewWorkerWatcher.resultAt(index)); });
|
||||
connect(&previewWorkerWatcher, &QFutureWatcher<QByteArray>::finished, this, [this] { emit finished(); });
|
||||
[this](int index)
|
||||
{
|
||||
if(this->peer != nullptr)
|
||||
{
|
||||
QDataStream stream{this->peer};
|
||||
stream << previewWorkerWatcher.resultAt(index);
|
||||
this->peer->flush();
|
||||
}
|
||||
});
|
||||
connect(&previewWorkerWatcher, &QFutureWatcher<QByteArray>::finished, this, &IPCPreviewWorker::shutdownSocket);
|
||||
connect(this->peer, &QLocalSocket::disconnected, this, &IPCPreviewWorker::shutdownSocket);
|
||||
}
|
||||
|
||||
void IPCPreviewWorker::start(RenderConfig config, const QVector<RenderTarget> &targets, QLocalSocket *peer)
|
||||
void IPCPreviewWorker::shutdownSocket()
|
||||
{
|
||||
if(cleaned)
|
||||
{
|
||||
return;
|
||||
}
|
||||
cleaned = true;
|
||||
if(this->peer != nullptr)
|
||||
{
|
||||
if(this->peer->state() == QLocalSocket::ConnectedState)
|
||||
{
|
||||
this->peer->flush();
|
||||
this->peer->waitForBytesWritten();
|
||||
this->peer->disconnectFromServer();
|
||||
if(this->peer->state() != QLocalSocket::UnconnectedState)
|
||||
{
|
||||
this->peer->waitForDisconnected();
|
||||
}
|
||||
}
|
||||
delete this->peer;
|
||||
this->peer = nullptr;
|
||||
}
|
||||
emit finished();
|
||||
}
|
||||
|
||||
void IPCPreviewWorker::start(RenderConfig config, const QVector<RenderTarget> &targets)
|
||||
{
|
||||
stop();
|
||||
auto mapFunctor = PreviewGeneratorMapFunctor();
|
||||
mapFunctor.setRenderConfig(config);
|
||||
|
||||
|
@ -11,13 +11,17 @@ class IPCPreviewWorker : public QObject
|
||||
Q_OBJECT
|
||||
private:
|
||||
QFutureWatcher<QByteArray> previewWorkerWatcher;
|
||||
QLocalSocket *peer;
|
||||
bool cleaned = false;
|
||||
|
||||
public:
|
||||
IPCPreviewWorker();
|
||||
void start(RenderConfig config, const QVector<RenderTarget> &targets, QLocalSocket *peer);
|
||||
IPCPreviewWorker(QLocalSocket *peer);
|
||||
void start(RenderConfig config, const QVector<RenderTarget> &targets);
|
||||
void stop();
|
||||
private slots:
|
||||
void shutdownSocket();
|
||||
|
||||
signals:
|
||||
void previewGenerated(QByteArray);
|
||||
void finished();
|
||||
};
|
||||
|
||||
|
@ -18,8 +18,6 @@ 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->previewWorker, &IPCPreviewWorker::previewGenerated, this, &IpcServer::handlePreviewGenerated);
|
||||
connect(&this->previewWorker, &IPCPreviewWorker::finished, this, [this] { this->currentSocket->flush(); });
|
||||
}
|
||||
|
||||
bool IpcServer::startSpawner(QString socketPath)
|
||||
@ -31,8 +29,6 @@ bool IpcServer::startSpawner(QString socketPath)
|
||||
void IpcServer::spawnerNewConnection()
|
||||
{
|
||||
QLocalSocket *socket = this->spawningServer.nextPendingConnection();
|
||||
connect(socket, &QLocalSocket::disconnected, socket, &QLocalSocket::deleteLater);
|
||||
this->currentSocket = socket;
|
||||
if(socket != nullptr)
|
||||
{
|
||||
if(!socket->waitForReadyRead())
|
||||
@ -53,21 +49,22 @@ void IpcServer::spawnerNewConnection()
|
||||
stream.startTransaction();
|
||||
stream >> renderConfig >> targets;
|
||||
} while(!stream.commitTransaction() && socket->state() == QLocalSocket::ConnectedState);
|
||||
|
||||
stream << targets.count();
|
||||
socket->flush();
|
||||
previewWorker.start(renderConfig, targets, socket);
|
||||
if(socket->state() == QLocalSocket::ConnectedState)
|
||||
{
|
||||
stream << targets.count();
|
||||
socket->flush();
|
||||
IPCPreviewWorker *previewWorker = new IPCPreviewWorker(socket);
|
||||
connect(previewWorker, &IPCPreviewWorker::finished, this, [previewWorker] { delete previewWorker; });
|
||||
previewWorker->start(renderConfig, targets);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete socket;
|
||||
}
|
||||
}
|
||||
if(command == StopGeneratePreviews)
|
||||
{
|
||||
previewWorker.stop();
|
||||
/* TODO: implement */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IpcServer::handlePreviewGenerated(QByteArray ba)
|
||||
{
|
||||
QDataStream stream{this->currentSocket};
|
||||
stream << ba;
|
||||
this->currentSocket->flush();
|
||||
}
|
||||
|
@ -10,13 +10,10 @@ class IpcServer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
IPCPreviewWorker previewWorker;
|
||||
QLocalServer spawningServer;
|
||||
QLocalSocket *currentSocket = nullptr;
|
||||
SaveFileResult addFile(QString file);
|
||||
private slots:
|
||||
void spawnerNewConnection();
|
||||
void handlePreviewGenerated(QByteArray ba);
|
||||
|
||||
public:
|
||||
IpcServer();
|
||||
|
@ -60,6 +60,10 @@ MainWindow::MainWindow(QWidget *parent, QString socketPath)
|
||||
QString ignorePatterns = settings.value("ignorePatterns").toString();
|
||||
ui->txtIgnorePatterns->setText(ignorePatterns);
|
||||
|
||||
QStringList searchHistoryList = settings.value(SETTINGS_KEY_SEARCHHISTORY).toStringList();
|
||||
this->searchHistory = searchHistoryList.toVector();
|
||||
this->currentSearchHistoryIndex = this->searchHistory.size();
|
||||
|
||||
ui->spinPreviewPage->setValue(1);
|
||||
ui->spinPreviewPage->setMinimum(1);
|
||||
|
||||
@ -70,6 +74,9 @@ MainWindow::MainWindow(QWidget *parent, QString socketPath)
|
||||
policy.setRetainSizeWhenHidden(true);
|
||||
ui->btnOpenFailed->setSizePolicy(policy);
|
||||
|
||||
ui->txtSearch->installEventFilter(this);
|
||||
ui->scrollArea->viewport()->installEventFilter(this);
|
||||
|
||||
this->ipcClientThread.start();
|
||||
}
|
||||
|
||||
@ -191,7 +198,14 @@ void MainWindow::connectSignals()
|
||||
connect(ui->btnSaveSettings, &QPushButton::clicked, this, &MainWindow::saveSettings);
|
||||
connect(ui->btnOpenFailed, &QPushButton::clicked, this, &MainWindow::exportFailedPaths);
|
||||
connect(
|
||||
ui->comboPreviewFiles, qOverload<int>(&QComboBox::currentIndexChanged), this, [&]() { makePreviews(1); },
|
||||
ui->comboPreviewFiles, qOverload<int>(&QComboBox::currentIndexChanged), this,
|
||||
[&]()
|
||||
{
|
||||
if(this->previewTabActive())
|
||||
{
|
||||
makePreviews(1);
|
||||
}
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
connect(&ipcPreviewClient, &IPCPreviewClient::previewReceived, this, &MainWindow::previewReceived,
|
||||
Qt::QueuedConnection);
|
||||
@ -201,6 +215,7 @@ void MainWindow::connectSignals()
|
||||
this->ui->previewProcessBar->setValue(this->ui->previewProcessBar->maximum());
|
||||
this->ui->spinPreviewPage->setEnabled(true);
|
||||
this->ui->comboPreviewFiles->setEnabled(true);
|
||||
ui->txtSearch->setEnabled(true);
|
||||
});
|
||||
connect(&ipcPreviewClient, &IPCPreviewClient::error, this,
|
||||
[this](QString msg)
|
||||
@ -437,6 +452,86 @@ void MainWindow::processShortcut(int key)
|
||||
}
|
||||
}
|
||||
|
||||
bool MainWindow::eventFilter(QObject *object, QEvent *event)
|
||||
{
|
||||
if(object == ui->txtSearch && !searchHistory.empty())
|
||||
{
|
||||
if(event->type() == QEvent::KeyPress)
|
||||
{
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
|
||||
if(keyEvent->key() == Qt::Key_Up)
|
||||
{
|
||||
if(this->currentSavedSearchText.isEmpty())
|
||||
{
|
||||
this->currentSavedSearchText = ui->txtSearch->text();
|
||||
}
|
||||
if(this->currentSearchHistoryIndex <= 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
--this->currentSearchHistoryIndex;
|
||||
QString text = this->searchHistory.at(this->currentSearchHistoryIndex);
|
||||
ui->txtSearch->setText(text);
|
||||
return true;
|
||||
}
|
||||
else if(keyEvent->key() == Qt::Key_Down)
|
||||
{
|
||||
if(this->currentSearchHistoryIndex == searchHistory.size() - 1)
|
||||
{
|
||||
if(!this->currentSavedSearchText.isEmpty())
|
||||
{
|
||||
ui->txtSearch->setText(this->currentSavedSearchText);
|
||||
this->currentSavedSearchText.clear();
|
||||
++this->currentSearchHistoryIndex;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if(this->currentSearchHistoryIndex < searchHistory.size() - 1)
|
||||
{
|
||||
++this->currentSearchHistoryIndex;
|
||||
QString text = this->searchHistory.at(this->currentSearchHistoryIndex);
|
||||
ui->txtSearch->setText(text);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->currentSavedSearchText.clear();
|
||||
/* Off by one on purpose so Key_Up decrements it again and lands at
|
||||
* the last entry */
|
||||
this->currentSearchHistoryIndex = this->searchHistory.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
if(object == ui->scrollArea->viewport())
|
||||
{
|
||||
if(event->type() == QEvent::Wheel)
|
||||
{
|
||||
QWheelEvent *wheelEvent = static_cast<QWheelEvent *>(event);
|
||||
if(wheelEvent->modifiers() & Qt::ControlModifier)
|
||||
{
|
||||
if(wheelEvent->angleDelta().y() > 0)
|
||||
{
|
||||
if(ui->comboScale->currentIndex() < ui->comboScale->count() - 1)
|
||||
{
|
||||
ui->comboScale->setCurrentIndex(ui->comboScale->currentIndex() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if(ui->comboScale->currentIndex() > 0)
|
||||
{
|
||||
ui->comboScale->setCurrentIndex(ui->comboScale->currentIndex() - 1);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return QMainWindow::eventFilter(object, event);
|
||||
}
|
||||
|
||||
void MainWindow::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
bool quit =
|
||||
@ -498,6 +593,9 @@ void MainWindow::initSettingsTabs()
|
||||
ui->txtSettingMountPaths->setText(mountPaths);
|
||||
ui->spinSettingNumerPerPages->setValue(numPagesPerPreview);
|
||||
ui->txtSettingDatabasePath->setText(databasePath);
|
||||
bool horizontalScroll = settings.value(SETTINGS_KEY_PREVIEWS_SCROLL_HORIZONTALLY).toBool();
|
||||
ui->radioScrollHorizontally->setChecked(horizontalScroll);
|
||||
ui->radioScrollVertically->setChecked(!horizontalScroll);
|
||||
}
|
||||
|
||||
void MainWindow::saveSettings()
|
||||
@ -525,6 +623,7 @@ void MainWindow::saveSettings()
|
||||
settings.setValue(SETTINGS_KEY_MOUNTPATHS, mountPaths);
|
||||
settings.setValue(SETTINGS_KEY_PREVIEWSPERPAGE, ui->spinSettingNumerPerPages->value());
|
||||
settings.setValue(SETTINGS_KEY_DBPATH, databasePath);
|
||||
settings.setValue(SETTINGS_KEY_PREVIEWS_SCROLL_HORIZONTALLY, ui->radioScrollHorizontally->isChecked());
|
||||
|
||||
settings.sync();
|
||||
|
||||
@ -600,6 +699,14 @@ void MainWindow::lineEditReturnPressed()
|
||||
ui->tabWidget->setCurrentIndex(0);
|
||||
}
|
||||
// TODO: validate q;
|
||||
while(this->searchHistory.size() > 30)
|
||||
{
|
||||
this->searchHistory.removeFirst();
|
||||
}
|
||||
this->searchHistory.append(q);
|
||||
this->currentSearchHistoryIndex = this->searchHistory.size();
|
||||
this->currentSavedSearchText.clear();
|
||||
|
||||
ui->treeResultsList->clear();
|
||||
ui->lblSearchResults->setText("Searching...");
|
||||
this->ui->txtSearch->setEnabled(false);
|
||||
@ -701,19 +808,25 @@ void MainWindow::handleSearchResults(const QVector<SearchResult> &results)
|
||||
ui->comboPreviewFiles->setVisible(true);
|
||||
|
||||
bool hasDeleted = false;
|
||||
QHash<QString, bool> seenMap;
|
||||
for(const SearchResult &result : results)
|
||||
{
|
||||
QFileInfo pathInfo(result.fileData.absPath);
|
||||
const QString &absPath = result.fileData.absPath;
|
||||
QFileInfo pathInfo(absPath);
|
||||
|
||||
QString fileName = pathInfo.fileName();
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem(ui->treeResultsList);
|
||||
if(!seenMap.contains(absPath))
|
||||
{
|
||||
seenMap[absPath] = true;
|
||||
QString fileName = pathInfo.fileName();
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem(ui->treeResultsList);
|
||||
|
||||
QDateTime dt = QDateTime::fromSecsSinceEpoch(result.fileData.mtime);
|
||||
item->setIcon(0, iconProvider.icon(pathInfo));
|
||||
item->setText(0, fileName);
|
||||
item->setText(1, result.fileData.absPath);
|
||||
item->setText(2, dt.toString(Qt::ISODate));
|
||||
item->setText(3, this->locale().formattedDataSize(result.fileData.size));
|
||||
QDateTime dt = QDateTime::fromSecsSinceEpoch(result.fileData.mtime);
|
||||
item->setIcon(0, iconProvider.icon(pathInfo));
|
||||
item->setText(0, fileName);
|
||||
item->setText(1, absPath);
|
||||
item->setText(2, dt.toString(Qt::ISODate));
|
||||
item->setText(3, this->locale().formattedDataSize(result.fileData.size));
|
||||
}
|
||||
bool exists = pathInfo.exists();
|
||||
if(exists)
|
||||
{
|
||||
@ -736,6 +849,7 @@ void MainWindow::handleSearchResults(const QVector<SearchResult> &results)
|
||||
hasDeleted = true;
|
||||
}
|
||||
}
|
||||
|
||||
ui->treeResultsList->resizeColumnToContents(0);
|
||||
ui->treeResultsList->resizeColumnToContents(1);
|
||||
ui->treeResultsList->resizeColumnToContents(2);
|
||||
@ -771,7 +885,17 @@ void MainWindow::makePreviews(int page)
|
||||
}
|
||||
qDeleteAll(ui->scrollAreaWidgetContents->children());
|
||||
|
||||
ui->scrollAreaWidgetContents->setLayout(new QHBoxLayout());
|
||||
QSettings settings;
|
||||
bool horizontalScroll = settings.value(SETTINGS_KEY_PREVIEWS_SCROLL_HORIZONTALLY, false).toBool();
|
||||
if(horizontalScroll)
|
||||
{
|
||||
ui->scrollAreaWidgetContents->setLayout(new QHBoxLayout());
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->scrollAreaWidgetContents->setLayout(new QVBoxLayout());
|
||||
ui->scrollAreaWidgetContents->layout()->setAlignment(Qt::AlignCenter);
|
||||
}
|
||||
ui->previewProcessBar->setMaximum(this->previewableSearchResults.size());
|
||||
processedPdfPreviews = 0;
|
||||
|
||||
@ -820,12 +944,8 @@ void MainWindow::makePreviews(int page)
|
||||
}
|
||||
RenderTarget renderTarget;
|
||||
renderTarget.path = sr.fileData.absPath;
|
||||
|
||||
for(unsigned int pagenum : sr.pages)
|
||||
{
|
||||
renderTarget.page = (int)pagenum;
|
||||
targets.append(renderTarget);
|
||||
}
|
||||
renderTarget.page = (int)sr.page;
|
||||
targets.append(renderTarget);
|
||||
}
|
||||
int numpages = ceil(static_cast<double>(targets.size()) / previewsPerPage);
|
||||
ui->spinPreviewPage->setMaximum(numpages);
|
||||
@ -839,6 +959,7 @@ void MainWindow::makePreviews(int page)
|
||||
++this->currentPreviewGeneration;
|
||||
this->ui->spinPreviewPage->setEnabled(false);
|
||||
this->ui->comboPreviewFiles->setEnabled(false);
|
||||
this->ui->txtSearch->setEnabled(false);
|
||||
emit startIpcPreviews(renderConfig, targets);
|
||||
}
|
||||
|
||||
@ -925,3 +1046,11 @@ MainWindow::~MainWindow()
|
||||
delete this->indexer;
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void MainWindow::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
QStringList list = this->searchHistory.toList();
|
||||
QSettings settings;
|
||||
settings.setValue(SETTINGS_KEY_SEARCHHISTORY, list);
|
||||
settings.sync();
|
||||
}
|
||||
|
@ -30,6 +30,9 @@ class MainWindow : public QMainWindow
|
||||
void beginSearch(const QString &query);
|
||||
void startPdfPreviewGeneration(QVector<SearchResult> paths, double scalefactor);
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
|
||||
private:
|
||||
DatabaseFactory *dbFactory;
|
||||
SqliteDbService *dbService;
|
||||
@ -64,7 +67,11 @@ class MainWindow : public QMainWindow
|
||||
void initSettingsTabs();
|
||||
int currentSelectedScale();
|
||||
void processShortcut(int key);
|
||||
private slots:
|
||||
bool eventFilter(QObject *object, QEvent *event);
|
||||
QVector<QString> searchHistory;
|
||||
int currentSearchHistoryIndex = 0;
|
||||
QString currentSavedSearchText;
|
||||
private slots:
|
||||
void lineEditReturnPressed();
|
||||
void treeSearchItemActivated(QTreeWidgetItem *item, int i);
|
||||
void showSearchResultsContextMenu(const QPoint &point);
|
||||
|
@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1280</width>
|
||||
<height>855</height>
|
||||
<height>888</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -27,7 +27,7 @@
|
||||
<enum>QTabWidget::South</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
<number>3</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="resultsTab">
|
||||
<attribute name="title">
|
||||
@ -82,7 +82,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1244</width>
|
||||
<height>565</height>
|
||||
<height>598</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout"/>
|
||||
@ -542,6 +542,19 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="Misc">
|
||||
<property name="title">
|
||||
@ -551,7 +564,7 @@
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<widget class="QLabel" name="lblMaxNumbersPreviewPages">
|
||||
<property name="text">
|
||||
<string>Max number of previews per 'page' in 'Previews' tab: </string>
|
||||
</property>
|
||||
@ -575,22 +588,47 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||
<item>
|
||||
<widget class="QLabel" name="lblScrollModeForPreviews">
|
||||
<property name="text">
|
||||
<string>Scroll mode for previews:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioScrollVertically">
|
||||
<property name="text">
|
||||
<string>Vertically</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioScrollHorizontally">
|
||||
<property name="text">
|
||||
<string>Horizontally</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnSaveSettings">
|
||||
<property name="text">
|
||||
|
@ -9,6 +9,8 @@
|
||||
#define SETTINGS_KEY_EXCLUDEDPATHS "excludedpaths"
|
||||
#define SETTINGS_KEY_MOUNTPATHS "mountpaths"
|
||||
#define SETTINGS_KEY_PREVIEWSPERPAGE "previewsPerPage"
|
||||
#define SETTINGS_KEY_SEARCHHISTORY "searchhistory"
|
||||
#define SETTINGS_KEY_PREVIEWS_SCROLL_HORIZONTALLY "horizontalscroll"
|
||||
|
||||
namespace Common
|
||||
{
|
||||
|
@ -6,7 +6,7 @@ class SearchResult
|
||||
{
|
||||
public:
|
||||
FileData fileData;
|
||||
QVector<unsigned int> pages;
|
||||
unsigned int page;
|
||||
bool wasContentSearch = false;
|
||||
};
|
||||
|
||||
|
@ -78,12 +78,17 @@ QString SqliteSearch::escapeFtsArgument(QString ftsArg)
|
||||
if(value.isEmpty())
|
||||
{
|
||||
value = m.captured(2);
|
||||
if(value.endsWith('*'))
|
||||
{
|
||||
value = value.mid(0, value.size() - 1);
|
||||
}
|
||||
result += "\"" + value + "\"*";
|
||||
}
|
||||
else
|
||||
{
|
||||
value = "\"\"" + value + "\"\"";
|
||||
result += "\"" + value + "\" ";
|
||||
}
|
||||
result += "\"" + value + "\" ";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -189,10 +194,9 @@ QSqlQuery SqliteSearch::makeSqlQuery(const LooqsQuery &query)
|
||||
sortSql = "ORDER BY rank";
|
||||
}
|
||||
}
|
||||
prepSql =
|
||||
"SELECT file.path AS path, group_concat(content.page) AS pages, file.mtime AS mtime, file.size AS size, "
|
||||
"file.filetype AS filetype FROM file INNER JOIN content ON file.id = content.fileid " +
|
||||
joinSql + " WHERE 1=1 AND " + whereSql + " GROUP BY file.path " + sortSql;
|
||||
prepSql = "SELECT file.path AS path, content.page AS page, file.mtime AS mtime, file.size AS size, "
|
||||
"file.filetype AS filetype FROM file INNER JOIN content ON file.id = content.fileid " +
|
||||
joinSql + " WHERE 1=1 AND " + whereSql + " " + sortSql;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -200,7 +204,7 @@ QSqlQuery SqliteSearch::makeSqlQuery(const LooqsQuery &query)
|
||||
{
|
||||
sortSql = "ORDER BY file.mtime DESC";
|
||||
}
|
||||
prepSql = "SELECT file.path AS path, '0' as pages, file.mtime AS mtime, file.size AS size, file.filetype AS "
|
||||
prepSql = "SELECT file.path AS path, '0' as page, file.mtime AS mtime, file.size AS size, file.filetype AS "
|
||||
"filetype FROM file WHERE 1=1 AND " +
|
||||
whereSql + " " + sortSql;
|
||||
}
|
||||
@ -243,15 +247,7 @@ QVector<SearchResult> SqliteSearch::search(const LooqsQuery &query)
|
||||
result.fileData.mtime = dbQuery.value("mtime").toUInt();
|
||||
result.fileData.size = dbQuery.value("size").toUInt();
|
||||
result.fileData.filetype = dbQuery.value("filetype").toChar();
|
||||
QString pages = dbQuery.value("pages").toString();
|
||||
QStringList pagesList = pages.split(",");
|
||||
for(QString &page : pagesList)
|
||||
{
|
||||
if(page != "")
|
||||
{
|
||||
result.pages.append(page.toUInt());
|
||||
}
|
||||
}
|
||||
result.page = dbQuery.value("page").toUInt();
|
||||
result.wasContentSearch = contentSearch;
|
||||
results.append(result);
|
||||
}
|
||||
|
新增問題並參考
封鎖使用者