begin work on qt gui - basic search & pdf preview
This commit is contained in:
parent
e006a95673
commit
68ab917756
6
gui/clicklabel.cpp
Normal file
6
gui/clicklabel.cpp
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#include "clicklabel.h"
|
||||||
|
|
||||||
|
void ClickLabel::mousePressEvent(QMouseEvent *event)
|
||||||
|
{
|
||||||
|
emit clicked();
|
||||||
|
}
|
17
gui/clicklabel.h
Normal file
17
gui/clicklabel.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#ifndef CLICKLABEL_H
|
||||||
|
#define CLICKLABEL_H
|
||||||
|
#include <QLabel>
|
||||||
|
|
||||||
|
class ClickLabel : public QLabel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
using QLabel::QLabel;
|
||||||
|
signals:
|
||||||
|
void clicked();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void mousePressEvent(QMouseEvent *event);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CLICKLABEL_H
|
19
gui/main.cpp
Normal file
19
gui/main.cpp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#include "mainwindow.h"
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QSettings>
|
||||||
|
#include "searchresult.h"
|
||||||
|
#include "pdfpreview.h"
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
QCoreApplication::setOrganizationName("quitesimple.org");
|
||||||
|
QCoreApplication::setOrganizationDomain("quitesimple.org");
|
||||||
|
QCoreApplication::setApplicationName("qss");
|
||||||
|
QApplication a(argc, argv);
|
||||||
|
qRegisterMetaType<QVector<SearchResult>>("QVector<SearchResult>");
|
||||||
|
qRegisterMetaType<QVector<PdfPreview>>("QVector<PdfPreview>");
|
||||||
|
qRegisterMetaType<PdfPreview>("PdfPreview");
|
||||||
|
MainWindow w;
|
||||||
|
w.showMaximized();
|
||||||
|
|
||||||
|
return a.exec();
|
||||||
|
}
|
160
gui/mainwindow.cpp
Normal file
160
gui/mainwindow.cpp
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
#include <poppler-qt5.h>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QtDebug>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QDesktopServices>
|
||||||
|
#include <QUrl>
|
||||||
|
#include <QClipboard>
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QDateTime>
|
||||||
|
#include "mainwindow.h"
|
||||||
|
#include "ui_mainwindow.h"
|
||||||
|
#include "clicklabel.h"
|
||||||
|
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
searchWorker = new SearchWorker(QSettings().value("dbpath").toString());
|
||||||
|
pdfWorker = new PdfWorker();
|
||||||
|
searchWorker->moveToThread(&searchThread);
|
||||||
|
pdfWorker->moveToThread(&pdfWorkerThread);
|
||||||
|
connectSignals();
|
||||||
|
searchThread.start();
|
||||||
|
ui->treeResultsList->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu);
|
||||||
|
|
||||||
|
ui->tabWidget->setCurrentIndex(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::connectSignals()
|
||||||
|
{
|
||||||
|
connect(ui->txtSearch, &QLineEdit::textChanged, this, &MainWindow::lineEditTextChanged);
|
||||||
|
connect(ui->txtSearch, &QLineEdit::returnPressed, this, &MainWindow::lineEditReturnPressed);
|
||||||
|
connect(this, &MainWindow::beginFileSearch, searchWorker, &SearchWorker::searchForFile);
|
||||||
|
connect(this, &MainWindow::beginContentSearch, searchWorker, &SearchWorker::searchForContent);
|
||||||
|
connect(searchWorker, &SearchWorker::searchResultsReady, this, &MainWindow::handleSearchResults);
|
||||||
|
connect(searchWorker, &SearchWorker::searchCancelled, this, &MainWindow::handleCancelledSearch);
|
||||||
|
connect(ui->treeResultsList, &QTreeWidget::itemActivated, this, &MainWindow::treeSearchItemActivated);
|
||||||
|
connect(ui->treeResultsList, &QTreeWidget::customContextMenuRequested, this,
|
||||||
|
&MainWindow::showSearchResultsContextMenu);
|
||||||
|
connect(ui->tabWidget, &QTabWidget::currentChanged, this, &MainWindow::tabChanged);
|
||||||
|
connect(this, &MainWindow::startPdfPreviewGeneration, pdfWorker, &PdfWorker::generatePreviews);
|
||||||
|
connect(pdfWorker, &PdfWorker::previewReady, this, &MainWindow::pdfPreviewReceived);
|
||||||
|
connect(pdfWorker, &PdfWorker::previewsFinished, [&] { this->pdfDirty = false; });
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::pdfTabActive()
|
||||||
|
{
|
||||||
|
return ui->tabWidget->currentIndex() == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::tabChanged()
|
||||||
|
{
|
||||||
|
if(pdfTabActive() && pdfDirty)
|
||||||
|
{
|
||||||
|
makePdfPreview();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::pdfPreviewReceived(PdfPreview preview)
|
||||||
|
{
|
||||||
|
ClickLabel *label = new ClickLabel();
|
||||||
|
label->setPixmap(QPixmap::fromImage(preview.previewImage));
|
||||||
|
ui->scrollAreaWidgetContents->layout()->addWidget(label);
|
||||||
|
connect(label, &ClickLabel::clicked,
|
||||||
|
[=]() { QDesktopServices::openUrl(QUrl::fromLocalFile(preview.documentPath)); });
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::lineEditReturnPressed()
|
||||||
|
{
|
||||||
|
if(pdfTabActive() && pdfDirty)
|
||||||
|
{
|
||||||
|
makePdfPreview();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::lineEditTextChanged()
|
||||||
|
{
|
||||||
|
QString q = ui->txtSearch->text();
|
||||||
|
if(q.startsWith("|"))
|
||||||
|
{
|
||||||
|
q = q.mid(1);
|
||||||
|
emit beginContentSearch(q);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
emit beginFileSearch(q);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::handleSearchResults(const QVector<SearchResult> &results)
|
||||||
|
{
|
||||||
|
this->pdfSearchResults.clear();
|
||||||
|
ui->treeResultsList->clear();
|
||||||
|
|
||||||
|
for(const SearchResult &result : results)
|
||||||
|
{
|
||||||
|
QFileInfo pathInfo(result.path);
|
||||||
|
QString fileName = pathInfo.fileName();
|
||||||
|
QTreeWidgetItem *item = new QTreeWidgetItem(ui->treeResultsList);
|
||||||
|
QDateTime dt = QDateTime::fromSecsSinceEpoch(result.mtime);
|
||||||
|
item->setIcon(0, iconProvider.icon(pathInfo));
|
||||||
|
item->setText(0, fileName);
|
||||||
|
item->setText(1, result.path);
|
||||||
|
item->setText(2, dt.toString(Qt::ISODate));
|
||||||
|
// TODO: this must be user definied or done more intelligently
|
||||||
|
if(this->pdfSearchResults.size() < 300)
|
||||||
|
{
|
||||||
|
if(result.path.endsWith(".pdf"))
|
||||||
|
{
|
||||||
|
this->pdfSearchResults.append(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ui->treeResultsList->resizeColumnToContents(0);
|
||||||
|
ui->treeResultsList->resizeColumnToContents(1);
|
||||||
|
pdfDirty = !this->pdfSearchResults.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::makePdfPreview()
|
||||||
|
{
|
||||||
|
if(!pdfWorkerThread.isRunning())
|
||||||
|
pdfWorkerThread.start();
|
||||||
|
qDeleteAll(ui->scrollAreaWidgetContents->children());
|
||||||
|
|
||||||
|
ui->scrollAreaWidgetContents->setLayout(new QHBoxLayout());
|
||||||
|
emit startPdfPreviewGeneration(this->pdfSearchResults, 0.75);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::handleCancelledSearch()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::treeSearchItemActivated(QTreeWidgetItem *item, int i)
|
||||||
|
{
|
||||||
|
QDesktopServices::openUrl(QUrl::fromLocalFile(item->text(1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::showSearchResultsContextMenu(const QPoint &point)
|
||||||
|
{
|
||||||
|
QTreeWidgetItem *item = ui->treeResultsList->itemAt(point);
|
||||||
|
if(item == nullptr)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QMenu menu("SearchResult", this);
|
||||||
|
menu.addAction("Copy filename to clipboard", [&] { QGuiApplication::clipboard()->setText(item->text(0)); });
|
||||||
|
menu.addAction("Copy full path to clipboard", [&] { QGuiApplication::clipboard()->setText(item->text(1)); });
|
||||||
|
menu.addAction("Open containing folder",
|
||||||
|
[&]
|
||||||
|
{
|
||||||
|
QFileInfo pathinfo(item->text(1));
|
||||||
|
QString dir = pathinfo.absolutePath();
|
||||||
|
QDesktopServices::openUrl(QUrl::fromLocalFile(dir));
|
||||||
|
});
|
||||||
|
menu.exec(QCursor::pos());
|
||||||
|
}
|
||||||
|
|
||||||
|
MainWindow::~MainWindow()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
53
gui/mainwindow.h
Normal file
53
gui/mainwindow.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#ifndef MAINWINDOW_H
|
||||||
|
#define MAINWINDOW_H
|
||||||
|
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include <QThread>
|
||||||
|
#include <QTreeWidgetItem>
|
||||||
|
#include <QFileIconProvider>
|
||||||
|
|
||||||
|
#include "searchworker.h"
|
||||||
|
#include "pdfworker.h"
|
||||||
|
namespace Ui
|
||||||
|
{
|
||||||
|
class MainWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
class MainWindow : public QMainWindow
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MainWindow(QWidget *parent = 0);
|
||||||
|
~MainWindow();
|
||||||
|
signals:
|
||||||
|
void beginFileSearch(const QString &query);
|
||||||
|
void beginContentSearch(const QString &query);
|
||||||
|
void startPdfPreviewGeneration(QVector<SearchResult> paths, double scalefactor);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::MainWindow *ui;
|
||||||
|
QFileIconProvider iconProvider;
|
||||||
|
bool pdfDirty;
|
||||||
|
SearchWorker *searchWorker;
|
||||||
|
PdfWorker *pdfWorker;
|
||||||
|
void add(QString path, unsigned int page);
|
||||||
|
QThread searchThread;
|
||||||
|
QThread pdfWorkerThread;
|
||||||
|
QVector<SearchResult> pdfSearchResults;
|
||||||
|
void connectSignals();
|
||||||
|
void makePdfPreview();
|
||||||
|
bool pdfTabActive();
|
||||||
|
private slots:
|
||||||
|
void lineEditReturnPressed();
|
||||||
|
void lineEditTextChanged();
|
||||||
|
void handleSearchResults(const QVector<SearchResult> &results);
|
||||||
|
void handleCancelledSearch();
|
||||||
|
void treeSearchItemActivated(QTreeWidgetItem *item, int i);
|
||||||
|
|
||||||
|
void showSearchResultsContextMenu(const QPoint &point);
|
||||||
|
void tabChanged();
|
||||||
|
void pdfPreviewReceived(PdfPreview preview);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MAINWINDOW_H
|
132
gui/mainwindow.ui
Normal file
132
gui/mainwindow.ui
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>MainWindow</class>
|
||||||
|
<widget class="QMainWindow" name="MainWindow">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>1221</width>
|
||||||
|
<height>614</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>MainWindow</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="centralWidget">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="txtSearch"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
|
<property name="tabPosition">
|
||||||
|
<enum>QTabWidget::South</enum>
|
||||||
|
</property>
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="resultsTab">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Search results</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QTreeWidget" name="treeResultsList">
|
||||||
|
<column>
|
||||||
|
<property name="text">
|
||||||
|
<string>Filename</string>
|
||||||
|
</property>
|
||||||
|
</column>
|
||||||
|
<column>
|
||||||
|
<property name="text">
|
||||||
|
<string>Path</string>
|
||||||
|
</property>
|
||||||
|
</column>
|
||||||
|
<column>
|
||||||
|
<property name="text">
|
||||||
|
<string>Last modified</string>
|
||||||
|
</property>
|
||||||
|
</column>
|
||||||
|
<column>
|
||||||
|
<property name="text">
|
||||||
|
<string>Size</string>
|
||||||
|
</property>
|
||||||
|
</column>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="pdfPreviewTab">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>PDF-Preview</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="1,0">
|
||||||
|
<item>
|
||||||
|
<widget class="QScrollArea" name="scrollArea">
|
||||||
|
<property name="layoutDirection">
|
||||||
|
<enum>Qt::LeftToRight</enum>
|
||||||
|
</property>
|
||||||
|
<property name="widgetResizable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>1179</width>
|
||||||
|
<height>428</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout"/>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="lblScale">
|
||||||
|
<property name="text">
|
||||||
|
<string>Scale</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="comboBox"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenuBar" name="menuBar">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>1221</width>
|
||||||
|
<height>20</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QToolBar" name="mainToolBar">
|
||||||
|
<attribute name="toolBarArea">
|
||||||
|
<enum>TopToolBarArea</enum>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="toolBarBreak">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
<widget class="QStatusBar" name="statusBar"/>
|
||||||
|
</widget>
|
||||||
|
<layoutdefault spacing="6" margin="11"/>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
5
gui/pdfpreview.cpp
Normal file
5
gui/pdfpreview.cpp
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#include "pdfpreview.h"
|
||||||
|
|
||||||
|
PdfPreview::PdfPreview()
|
||||||
|
{
|
||||||
|
}
|
13
gui/pdfpreview.h
Normal file
13
gui/pdfpreview.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#ifndef PDFPREVIEW_H
|
||||||
|
#define PDFPREVIEW_H
|
||||||
|
#include <QImage>
|
||||||
|
|
||||||
|
class PdfPreview
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PdfPreview();
|
||||||
|
QImage previewImage;
|
||||||
|
QString documentPath;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PDFPREVIEW_H
|
44
gui/pdfworker.cpp
Normal file
44
gui/pdfworker.cpp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QScreen>
|
||||||
|
#include <QDebug>
|
||||||
|
#include "pdfworker.h"
|
||||||
|
|
||||||
|
PdfWorker::PdfWorker()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Poppler::Document *PdfWorker::document(QString path)
|
||||||
|
{
|
||||||
|
if(this->documentcache.contains(path))
|
||||||
|
return this->documentcache.value(path);
|
||||||
|
|
||||||
|
Poppler::Document *result = Poppler::Document::load(path);
|
||||||
|
result->setRenderHint(Poppler::Document::TextAntialiasing);
|
||||||
|
this->documentcache.insert(path, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
void PdfWorker::generatePreviews(QVector<SearchResult> paths, double scalefactor)
|
||||||
|
{
|
||||||
|
for(SearchResult &sr : paths)
|
||||||
|
{
|
||||||
|
Poppler::Document *doc = document(sr.path);
|
||||||
|
qDebug() << sr.path;
|
||||||
|
if(doc->isLocked())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int p = (int)sr.page - 1;
|
||||||
|
if(p < 0)
|
||||||
|
p = 0;
|
||||||
|
Poppler::Page *pdfpage = doc->page(p);
|
||||||
|
QImage image = pdfpage->renderToImage(QGuiApplication::primaryScreen()->physicalDotsPerInchX() * scalefactor,
|
||||||
|
QGuiApplication::primaryScreen()->physicalDotsPerInchY() * scalefactor);
|
||||||
|
|
||||||
|
PdfPreview preview;
|
||||||
|
preview.previewImage = image;
|
||||||
|
preview.documentPath = sr.path;
|
||||||
|
emit previewReady(preview);
|
||||||
|
}
|
||||||
|
emit previewsFinished();
|
||||||
|
}
|
26
gui/pdfworker.h
Normal file
26
gui/pdfworker.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#ifndef PDFWORKER_H
|
||||||
|
#define PDFWORKER_H
|
||||||
|
#include <QObject>
|
||||||
|
#include <QImage>
|
||||||
|
#include <QHash>
|
||||||
|
#include <poppler-qt5.h>
|
||||||
|
#include "pdfpreview.h"
|
||||||
|
#include "searchresult.h"
|
||||||
|
class PdfWorker : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
QHash<QString, Poppler::Document *> documentcache;
|
||||||
|
Poppler::Document *document(QString path);
|
||||||
|
|
||||||
|
public:
|
||||||
|
PdfWorker();
|
||||||
|
public slots:
|
||||||
|
void generatePreviews(QVector<SearchResult> paths, double scalefactor);
|
||||||
|
signals:
|
||||||
|
void previewReady(PdfPreview p);
|
||||||
|
void previewsFinished();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PDFWORKER_H
|
49
gui/qss.pro
Normal file
49
gui/qss.pro
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#-------------------------------------------------
|
||||||
|
#
|
||||||
|
# Project created by QtCreator 2018-08-09T12:23:48
|
||||||
|
#
|
||||||
|
#-------------------------------------------------
|
||||||
|
|
||||||
|
QT += core gui
|
||||||
|
|
||||||
|
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||||
|
|
||||||
|
TARGET = qss
|
||||||
|
TEMPLATE = app
|
||||||
|
|
||||||
|
# The following define makes your compiler emit warnings if you use
|
||||||
|
# any feature of Qt which has been marked as deprecated (the exact warnings
|
||||||
|
# depend on your compiler). Please consult the documentation of the
|
||||||
|
# deprecated API in order to know how to port your code away from it.
|
||||||
|
DEFINES += QT_DEPRECATED_WARNINGS
|
||||||
|
|
||||||
|
# You can also make your code fail to compile if you use deprecated APIs.
|
||||||
|
# In order to do so, uncomment the following line.
|
||||||
|
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||||
|
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||||
|
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
main.cpp \
|
||||||
|
mainwindow.cpp \
|
||||||
|
searchresult.cpp \
|
||||||
|
searchworker.cpp \
|
||||||
|
pdfworker.cpp \
|
||||||
|
pdfpreview.cpp \
|
||||||
|
clicklabel.cpp
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
mainwindow.h \
|
||||||
|
searchresult.h \
|
||||||
|
searchworker.h \
|
||||||
|
pdfworker.h \
|
||||||
|
pdfpreview.h \
|
||||||
|
clicklabel.h
|
||||||
|
|
||||||
|
FORMS += \
|
||||||
|
mainwindow.ui
|
||||||
|
|
||||||
|
INCLUDEPATH += /usr/include/poppler/qt5/
|
||||||
|
LIBS += -lpoppler-qt5
|
||||||
|
QT += widgets sql
|
||||||
|
|
5
gui/searchresult.cpp
Normal file
5
gui/searchresult.cpp
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#include "searchresult.h"
|
||||||
|
|
||||||
|
SearchResult::SearchResult()
|
||||||
|
{
|
||||||
|
}
|
14
gui/searchresult.h
Normal file
14
gui/searchresult.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#ifndef SEARCHRESULT_H
|
||||||
|
#define SEARCHRESULT_H
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
class SearchResult
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
unsigned int page;
|
||||||
|
QString path;
|
||||||
|
uint64_t mtime;
|
||||||
|
SearchResult();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SEARCHRESULT_H
|
55
gui/searchworker.cpp
Normal file
55
gui/searchworker.cpp
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#include "searchworker.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
SearchWorker::SearchWorker()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
SearchWorker::SearchWorker(const QString &dbpath)
|
||||||
|
{
|
||||||
|
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
|
||||||
|
db.setDatabaseName(dbpath);
|
||||||
|
if(!db.open())
|
||||||
|
{
|
||||||
|
qDebug() << "failed to open database";
|
||||||
|
}
|
||||||
|
queryContent = new QSqlQuery(db);
|
||||||
|
queryFile = new QSqlQuery(db);
|
||||||
|
queryFile->prepare("SELECT path, mtime FROM file WHERE path LIKE ? ORDER BY mtime DESC");
|
||||||
|
|
||||||
|
queryContent->prepare("SELECT file.path, content.page, file.mtime FROM file INNER JOIN content ON file.id = "
|
||||||
|
"content.fileid INNER JOIN content_fts ON content.id = content_fts.ROWID WHERE "
|
||||||
|
"content_fts.content MATCH ? ORDER By file.mtime DESC, content.page ASC");
|
||||||
|
}
|
||||||
|
|
||||||
|
void SearchWorker::searchForFile(const QString &query)
|
||||||
|
{
|
||||||
|
QVector<SearchResult> results;
|
||||||
|
queryFile->addBindValue("%" + query + "%");
|
||||||
|
queryFile->exec();
|
||||||
|
while(queryFile->next())
|
||||||
|
{
|
||||||
|
SearchResult result;
|
||||||
|
result.page = 0;
|
||||||
|
result.path = queryFile->value(0).toString();
|
||||||
|
result.mtime = queryFile->value(1).toUInt();
|
||||||
|
|
||||||
|
results.append(result);
|
||||||
|
}
|
||||||
|
emit searchResultsReady(results);
|
||||||
|
}
|
||||||
|
void SearchWorker::searchForContent(const QString &query)
|
||||||
|
{
|
||||||
|
QVector<SearchResult> results;
|
||||||
|
queryContent->addBindValue(query);
|
||||||
|
queryContent->exec();
|
||||||
|
while(queryContent->next())
|
||||||
|
{
|
||||||
|
SearchResult result;
|
||||||
|
|
||||||
|
result.path = queryContent->value(0).toString();
|
||||||
|
result.page = queryContent->value(1).toUInt();
|
||||||
|
result.mtime = queryContent->value(2).toUInt();
|
||||||
|
results.append(result);
|
||||||
|
}
|
||||||
|
emit searchResultsReady(results);
|
||||||
|
}
|
28
gui/searchworker.h
Normal file
28
gui/searchworker.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#ifndef SEARCHWORKER_H
|
||||||
|
#define SEARCHWORKER_H
|
||||||
|
#include <QObject>
|
||||||
|
#include <QSqlDatabase>
|
||||||
|
#include <QSqlQuery>
|
||||||
|
#include <QString>
|
||||||
|
#include <QVector>
|
||||||
|
#include "searchresult.h"
|
||||||
|
|
||||||
|
class SearchWorker : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
private:
|
||||||
|
QSqlQuery *queryFile;
|
||||||
|
QSqlQuery *queryContent;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SearchWorker();
|
||||||
|
SearchWorker(const QString &dbpath);
|
||||||
|
public slots:
|
||||||
|
void searchForFile(const QString &query);
|
||||||
|
void searchForContent(const QString &query);
|
||||||
|
signals:
|
||||||
|
void searchResultsReady(const QVector<SearchResult> &results);
|
||||||
|
void searchCancelled();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SEARCHWORKER_H
|
Loading…
Reference in New Issue
Block a user