paging for pdfpreviews
This commit is contained in:
		| @@ -17,260 +17,277 @@ | ||||
| #include "../shared/sqlitesearch.h" | ||||
| #include "../shared/qssgeneralexception.h" | ||||
| MainWindow::MainWindow(QWidget *parent) : | ||||
|     QMainWindow(parent), | ||||
|     ui(new Ui::MainWindow) | ||||
| 	QMainWindow(parent), | ||||
| 	ui(new Ui::MainWindow) | ||||
| { | ||||
|     ui->setupUi(this); | ||||
| 	ui->setupUi(this); | ||||
| 	QSettings settings; | ||||
|  | ||||
|     db = QSqlDatabase::addDatabase("QSQLITE"); | ||||
|     db.setDatabaseName(QSettings().value("dbpath").toString()); | ||||
|     if(!db.open()) | ||||
|     { | ||||
|         qDebug() << "failed to open database"; | ||||
|         throw std::runtime_error("Failed to open database"); | ||||
|     } | ||||
|     connectSignals(); | ||||
|     ui->treeResultsList->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu); | ||||
|     ui->tabWidget->setCurrentIndex(0); | ||||
|     ui->statusBar->addWidget(ui->lblSearchResults); | ||||
|     ui->statusBar->addWidget(ui->pdfProcessBar); | ||||
|     ui->pdfProcessBar->hide(); | ||||
|     QSettings settings; | ||||
|     ui->comboScale->setCurrentText(settings.value("currentScale").toString()); | ||||
| 	db = QSqlDatabase::addDatabase("QSQLITE"); | ||||
| 	db.setDatabaseName(settings.value("dbpath").toString()); | ||||
| 	if(!db.open()) | ||||
| 	{ | ||||
| 		qDebug() << "failed to open database"; | ||||
| 		throw std::runtime_error("Failed to open database"); | ||||
| 	} | ||||
| 	connectSignals(); | ||||
| 	ui->treeResultsList->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu); | ||||
| 	ui->tabWidget->setCurrentIndex(0); | ||||
| 	ui->statusBar->addWidget(ui->lblSearchResults); | ||||
| 	ui->statusBar->addWidget(ui->pdfProcessBar); | ||||
| 	ui->pdfProcessBar->hide(); | ||||
| 	ui->comboScale->setCurrentText(settings.value("currentScale").toString()); | ||||
| 	pdfPreviewsPerPage = settings.value("pdfPreviewsPerPage", 20).toInt(); | ||||
| 	ui->spinPdfPreviewPage->setMinimum(1); | ||||
| } | ||||
|  | ||||
| void MainWindow::connectSignals() | ||||
| { | ||||
|     connect(ui->txtSearch, &QLineEdit::returnPressed, this, &MainWindow::lineEditReturnPressed); | ||||
|     connect(&searchWatcher, &QFutureWatcher<SearchResult>::finished, this, [&]{ | ||||
|         try | ||||
|         { | ||||
|             auto results = searchWatcher.future().result(); | ||||
|             handleSearchResults(results); | ||||
|         } | ||||
|         catch(QSSGeneralException &e) | ||||
|         { | ||||
|             handleSearchError(e.message); | ||||
|         } | ||||
| 	connect(ui->txtSearch, &QLineEdit::returnPressed, this, &MainWindow::lineEditReturnPressed); | ||||
| 	connect(&searchWatcher, &QFutureWatcher<SearchResult>::finished, this, [&]{ | ||||
| 		try | ||||
| 		{ | ||||
| 			auto results = searchWatcher.future().result(); | ||||
| 			handleSearchResults(results); | ||||
| 		} | ||||
| 		catch(QSSGeneralException &e) | ||||
| 		{ | ||||
| 			handleSearchError(e.message); | ||||
| 		} | ||||
|  | ||||
|     }); | ||||
| 	}); | ||||
|  | ||||
|     connect(&pdfWorkerWatcher, &QFutureWatcher<PdfPreview>::resultReadyAt, this, [&](int index) { | ||||
|         pdfPreviewReceived(pdfWorkerWatcher.resultAt(index)); | ||||
|     }); | ||||
|     connect(&pdfWorkerWatcher, &QFutureWatcher<PdfPreview>::progressValueChanged, ui->pdfProcessBar, &QProgressBar::setValue); | ||||
|     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(ui->comboScale, qOverload<const QString &>(&QComboBox::currentIndexChanged), this, &MainWindow::comboScaleChanged); | ||||
| 	connect(&pdfWorkerWatcher, &QFutureWatcher<PdfPreview>::resultReadyAt, this, [&](int index) { | ||||
| 		pdfPreviewReceived(pdfWorkerWatcher.resultAt(index)); | ||||
| 	}); | ||||
| 	connect(&pdfWorkerWatcher, &QFutureWatcher<PdfPreview>::progressValueChanged, ui->pdfProcessBar, &QProgressBar::setValue); | ||||
| 	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(ui->comboScale, qOverload<const QString &>(&QComboBox::currentIndexChanged), this, &MainWindow::comboScaleChanged); | ||||
| 	connect(ui->spinPdfPreviewPage, qOverload<int>(&QSpinBox::valueChanged), this, &MainWindow::spinPdfPreviewPageValueChanged); | ||||
|  | ||||
| } | ||||
|  | ||||
| void MainWindow::spinPdfPreviewPageValueChanged(int val) | ||||
| { | ||||
| 	makePdfPreview(val); | ||||
| } | ||||
|  | ||||
| void MainWindow::comboScaleChanged(QString text) | ||||
| { | ||||
|     QSettings scaleSetting; | ||||
|     scaleSetting.setValue("currentScale", ui->comboScale->currentText()); | ||||
|     makePdfPreview(); | ||||
| 	QSettings scaleSetting; | ||||
| 	scaleSetting.setValue("currentScale", ui->comboScale->currentText()); | ||||
| 	makePdfPreview(ui->spinPdfPreviewPage->value()); | ||||
| } | ||||
| bool MainWindow::pdfTabActive() | ||||
| { | ||||
|     return ui->tabWidget->currentIndex() == 1; | ||||
| 	return ui->tabWidget->currentIndex() == 1; | ||||
| } | ||||
|  | ||||
| void MainWindow::keyPressEvent(QKeyEvent *event) | ||||
| { | ||||
|     bool quit = ((event->modifiers() & Qt::ControlModifier && event->key() == Qt::Key_Q) || event->key() == Qt::Key_Escape); | ||||
|     if(quit) | ||||
|     { | ||||
|         qApp->quit(); | ||||
|     } | ||||
| 	bool quit = ((event->modifiers() & Qt::ControlModifier && event->key() == Qt::Key_Q) || event->key() == Qt::Key_Escape); | ||||
| 	if(quit) | ||||
| 	{ | ||||
| 		qApp->quit(); | ||||
| 	} | ||||
|  | ||||
|     if(event->modifiers() & Qt::ControlModifier) | ||||
|     { | ||||
| 	if(event->modifiers() & Qt::ControlModifier) | ||||
| 	{ | ||||
|  | ||||
|         if(event->key() == Qt::Key_L) | ||||
|         { | ||||
|             ui->txtSearch->setFocus(); | ||||
|             ui->txtSearch->selectAll(); | ||||
|         } | ||||
|     } | ||||
|     QWidget::keyPressEvent(event); | ||||
| 		if(event->key() == Qt::Key_L) | ||||
| 		{ | ||||
| 			ui->txtSearch->setFocus(); | ||||
| 			ui->txtSearch->selectAll(); | ||||
| 		} | ||||
| 	} | ||||
| 	QWidget::keyPressEvent(event); | ||||
| } | ||||
|  | ||||
| void MainWindow::tabChanged() | ||||
| { | ||||
|     if(pdfTabActive()) | ||||
|     { | ||||
|         if(pdfDirty) | ||||
|         { | ||||
|             makePdfPreview(); | ||||
|         } | ||||
|         ui->pdfProcessBar->show(); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         ui->pdfProcessBar->hide(); | ||||
|     } | ||||
| 	if(pdfTabActive()) | ||||
| 	{ | ||||
| 		if(pdfDirty) | ||||
| 		{ | ||||
| 			makePdfPreview(ui->spinPdfPreviewPage->value()); | ||||
| 		} | ||||
| 		ui->pdfProcessBar->show(); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		ui->pdfProcessBar->hide(); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void MainWindow::pdfPreviewReceived(PdfPreview preview) | ||||
| { | ||||
|     if(preview.hasPreviewImage()) | ||||
|     { | ||||
|         ClickLabel *label = new ClickLabel(); | ||||
|         label->setPixmap(QPixmap::fromImage(preview.previewImage)); | ||||
|         label->setToolTip(preview.documentPath); | ||||
|         ui->scrollAreaWidgetContents->layout()->addWidget(label); | ||||
|         connect(label, &ClickLabel::leftClick, [=]() { | ||||
|             QSettings settings; | ||||
|             QString command = settings.value("pdfviewer").toString(); | ||||
|             if(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", preview.documentPath); | ||||
|                     args.replaceInStrings("%p", QString::number(preview.page)); | ||||
| 	if(preview.hasPreviewImage()) | ||||
| 	{ | ||||
| 		ClickLabel *label = new ClickLabel(); | ||||
| 		label->setPixmap(QPixmap::fromImage(preview.previewImage)); | ||||
| 		label->setToolTip(preview.documentPath); | ||||
| 		ui->scrollAreaWidgetContents->layout()->addWidget(label); | ||||
| 		connect(label, &ClickLabel::leftClick, [=]() { | ||||
| 			QSettings settings; | ||||
| 			QString command = settings.value("pdfviewer").toString(); | ||||
| 			if(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", preview.documentPath); | ||||
| 					args.replaceInStrings("%p", QString::number(preview.page)); | ||||
|  | ||||
|                     QProcess::startDetached(cmd, args); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 QDesktopServices::openUrl(QUrl::fromLocalFile(preview.documentPath)); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| 					QProcess::startDetached(cmd, args); | ||||
| 				} | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				QDesktopServices::openUrl(QUrl::fromLocalFile(preview.documentPath)); | ||||
| 			} | ||||
| 		}); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void MainWindow::lineEditReturnPressed() | ||||
| { | ||||
|     QString q = ui->txtSearch->text(); | ||||
|     if(!QSSQuery::checkParanthesis(q)) | ||||
|     { | ||||
|         ui->lblSearchResults->setText("Invalid paranthesis"); | ||||
|         return; | ||||
|     } | ||||
|     //TODO: validate q; | ||||
|     ui->lblSearchResults->setText("Searching..."); | ||||
|     searchWatcher.cancel(); | ||||
|     searchWatcher.waitForFinished(); | ||||
|     QFuture<QVector<SearchResult>> searchFuture = QtConcurrent::run([&, q]() { | ||||
|         SqliteSearch searcher(db); | ||||
|         this->currentQuery = QSSQuery::build(q); | ||||
|         return searcher.search(this->currentQuery); | ||||
|     }); | ||||
|     searchWatcher.setFuture(searchFuture); | ||||
| 	QString q = ui->txtSearch->text(); | ||||
| 	if(!QSSQuery::checkParanthesis(q)) | ||||
| 	{ | ||||
| 		ui->lblSearchResults->setText("Invalid paranthesis"); | ||||
| 		return; | ||||
| 	} | ||||
| 	//TODO: validate q; | ||||
| 	ui->lblSearchResults->setText("Searching..."); | ||||
| 	searchWatcher.cancel(); | ||||
| 	searchWatcher.waitForFinished(); | ||||
| 	QFuture<QVector<SearchResult>> searchFuture = QtConcurrent::run([&, q]() { | ||||
| 		SqliteSearch searcher(db); | ||||
| 		this->currentQuery = QSSQuery::build(q); | ||||
| 		return searcher.search(this->currentQuery); | ||||
| 	}); | ||||
| 	searchWatcher.setFuture(searchFuture); | ||||
|  | ||||
| } | ||||
|  | ||||
| void MainWindow::handleSearchResults(const QVector<SearchResult> &results) | ||||
| { | ||||
|    this->pdfSearchResults.clear(); | ||||
|    ui->treeResultsList->clear(); | ||||
|    ui->lblSearchResults->setText("Results: " + QString::number(results.size())); | ||||
|    for(const SearchResult &result : results) | ||||
|    { | ||||
|        QFileInfo pathInfo(result.fileData.absPath); | ||||
|        QString fileName =pathInfo.fileName(); | ||||
|        QTreeWidgetItem *item = new QTreeWidgetItem(ui->treeResultsList); | ||||
| 	this->pdfSearchResults.clear(); | ||||
| 	ui->treeResultsList->clear(); | ||||
| 	ui->lblSearchResults->setText("Results: " + QString::number(results.size())); | ||||
| 	for(const SearchResult &result : results) | ||||
| 	{ | ||||
| 		QFileInfo pathInfo(result.fileData.absPath); | ||||
| 		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)); | ||||
|        if(result.fileData.absPath.endsWith(".pdf")) | ||||
|        { | ||||
|            this->pdfSearchResults.append(result); | ||||
|        } | ||||
|    } | ||||
|    ui->treeResultsList->resizeColumnToContents(0); | ||||
|    ui->treeResultsList->resizeColumnToContents(1); | ||||
|    pdfDirty = ! this->pdfSearchResults.empty(); | ||||
|    if(pdfTabActive() && pdfDirty) | ||||
|    { | ||||
|        makePdfPreview(); | ||||
|    } | ||||
| 		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)); | ||||
| 		if(result.fileData.absPath.endsWith(".pdf")) | ||||
| 		{ | ||||
| 			this->pdfSearchResults.append(result); | ||||
| 		} | ||||
| 	} | ||||
| 	ui->treeResultsList->resizeColumnToContents(0); | ||||
| 	ui->treeResultsList->resizeColumnToContents(1); | ||||
| 	pdfDirty = ! this->pdfSearchResults.empty(); | ||||
|  | ||||
| 	int numpages = ceil(static_cast<double>(this->pdfSearchResults.size()) / pdfPreviewsPerPage); | ||||
| 	ui->spinPdfPreviewPage->setMinimum(1); | ||||
| 	ui->spinPdfPreviewPage->setMaximum(numpages); | ||||
| 	ui->spinPdfPreviewPage->setValue(1); | ||||
| 	if(pdfTabActive() && pdfDirty) | ||||
| 	{ | ||||
| 		makePdfPreview(1); | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| void MainWindow::makePdfPreview() | ||||
| void MainWindow::makePdfPreview(int page) | ||||
| { | ||||
|  | ||||
|    this->pdfWorkerWatcher.cancel(); | ||||
|    this->pdfWorkerWatcher.waitForFinished(); | ||||
| 	this->pdfWorkerWatcher.cancel(); | ||||
| 	this->pdfWorkerWatcher.waitForFinished(); | ||||
|  | ||||
|    QCoreApplication::processEvents(); //Maybe not necessary anymore, depends on whether it's possible that a slot is still to be fired. | ||||
|    qDeleteAll(ui->scrollAreaWidgetContents->children()); | ||||
| 	QCoreApplication::processEvents(); //Maybe not necessary anymore, depends on whether it's possible that a slot is still to be fired. | ||||
| 	qDeleteAll(ui->scrollAreaWidgetContents->children()); | ||||
|  | ||||
|    ui->scrollAreaWidgetContents->setLayout(new QHBoxLayout()); | ||||
|    ui->pdfProcessBar->setMaximum(this->pdfSearchResults.size()); | ||||
|    processedPdfPreviews = 0; | ||||
|    QString scaleText = ui->comboScale->currentText(); | ||||
|    scaleText.chop(1); | ||||
| 	ui->scrollAreaWidgetContents->setLayout(new QHBoxLayout()); | ||||
| 	ui->pdfProcessBar->setMaximum(this->pdfSearchResults.size()); | ||||
| 	processedPdfPreviews = 0; | ||||
| 	QString scaleText = ui->comboScale->currentText(); | ||||
| 	scaleText.chop(1); | ||||
|  | ||||
|    QVector<QString> wordsToHighlight; | ||||
|    QRegularExpression extractor(R"#("([^"]*)"|(\w+))#"); | ||||
|    for(const Token &token : this->currentQuery.getTokens()) | ||||
|    { | ||||
|        if(token.type == FILTER_CONTENT_CONTAINS) | ||||
|        { | ||||
|            QRegularExpressionMatchIterator i = extractor.globalMatch(token.value); | ||||
|            while(i.hasNext()) | ||||
|            { | ||||
|                QRegularExpressionMatch m = i.next(); | ||||
|                QString value = m.captured(1); | ||||
|                if(value.isEmpty()) | ||||
|                { | ||||
|                    value = m.captured(2); | ||||
|                } | ||||
|                wordsToHighlight.append(value); | ||||
| 	QVector<QString> wordsToHighlight; | ||||
| 	QRegularExpression extractor(R"#("([^"]*)"|(\w+))#"); | ||||
| 	for(const Token &token : this->currentQuery.getTokens()) | ||||
| 	{ | ||||
| 		if(token.type == FILTER_CONTENT_CONTAINS) | ||||
| 		{ | ||||
| 			QRegularExpressionMatchIterator i = extractor.globalMatch(token.value); | ||||
| 			while(i.hasNext()) | ||||
| 			{ | ||||
| 				QRegularExpressionMatch m = i.next(); | ||||
| 				QString value = m.captured(1); | ||||
| 				if(value.isEmpty()) | ||||
| 				{ | ||||
| 					value = m.captured(2); | ||||
| 				} | ||||
| 				wordsToHighlight.append(value); | ||||
|  | ||||
|            } | ||||
|        } | ||||
|    } | ||||
|    PdfWorker worker; | ||||
|    this->pdfWorkerWatcher.setFuture(worker.generatePreviews(this->pdfSearchResults, wordsToHighlight, scaleText.toInt() / 100.)); | ||||
|    ui->pdfProcessBar->setMaximum(this->pdfWorkerWatcher.progressMaximum()); | ||||
|    ui->pdfProcessBar->setMinimum(this->pdfWorkerWatcher.progressMinimum()); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	PdfWorker worker; | ||||
| 	int end = pdfPreviewsPerPage; | ||||
| 	int begin = page * pdfPreviewsPerPage - pdfPreviewsPerPage; | ||||
| 	this->pdfWorkerWatcher.setFuture(worker.generatePreviews(this->pdfSearchResults.mid(begin, end), wordsToHighlight, scaleText.toInt() / 100.)); | ||||
| 	ui->pdfProcessBar->setMaximum(this->pdfWorkerWatcher.progressMaximum()); | ||||
| 	ui->pdfProcessBar->setMinimum(this->pdfWorkerWatcher.progressMinimum()); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| void MainWindow::handleSearchError(QString error) | ||||
| { | ||||
|     ui->lblSearchResults->setText("Error:"  + error); | ||||
| 	ui->lblSearchResults->setText("Error:"  + error); | ||||
| } | ||||
|  | ||||
| void MainWindow::treeSearchItemActivated(QTreeWidgetItem *item, int i) | ||||
| { | ||||
|     QDesktopServices::openUrl(QUrl::fromLocalFile(item->text(1))); | ||||
| 	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)); | ||||
| 	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()); | ||||
| 	}); | ||||
| 	menu.exec(QCursor::pos()); | ||||
| } | ||||
|  | ||||
|  | ||||
| MainWindow::~MainWindow() | ||||
| { | ||||
|     delete ui; | ||||
| 	delete ui; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -34,13 +34,14 @@ private: | ||||
|     void add(QString path, unsigned int page); | ||||
|     QVector<SearchResult> pdfSearchResults; | ||||
|     void connectSignals(); | ||||
|     void makePdfPreview(); | ||||
| 	void makePdfPreview(int page); | ||||
|     bool pdfTabActive(); | ||||
|     void keyPressEvent(QKeyEvent *event) override; | ||||
|     unsigned int processedPdfPreviews; | ||||
|     void handleSearchResults(const QVector<SearchResult> &results); | ||||
|     void handleSearchError(QString error); | ||||
|     QSSQuery currentQuery; | ||||
| 	int pdfPreviewsPerPage; | ||||
| private slots: | ||||
|     void lineEditReturnPressed(); | ||||
|     void treeSearchItemActivated(QTreeWidgetItem *item, int i); | ||||
| @@ -48,7 +49,7 @@ private slots: | ||||
|     void tabChanged(); | ||||
|     void pdfPreviewReceived(PdfPreview preview); | ||||
|     void comboScaleChanged(QString text); | ||||
|  | ||||
| 	void spinPdfPreviewPageValueChanged(int val); | ||||
| }; | ||||
|  | ||||
| #endif // MAINWINDOW_H | ||||
|   | ||||
| @@ -148,6 +148,26 @@ | ||||
|             </property> | ||||
|            </spacer> | ||||
|           </item> | ||||
|           <item> | ||||
|            <widget class="QLabel" name="lblPdfPreviewPage"> | ||||
|             <property name="text"> | ||||
|              <string>Page:</string> | ||||
|             </property> | ||||
|            </widget> | ||||
|           </item> | ||||
|           <item> | ||||
|            <widget class="QSpinBox" name="spinPdfPreviewPage"> | ||||
|             <property name="buttonSymbols"> | ||||
|              <enum>QAbstractSpinBox::PlusMinus</enum> | ||||
|             </property> | ||||
|             <property name="accelerated"> | ||||
|              <bool>false</bool> | ||||
|             </property> | ||||
|             <property name="showGroupSeparator" stdset="0"> | ||||
|              <bool>false</bool> | ||||
|             </property> | ||||
|            </widget> | ||||
|           </item> | ||||
|          </layout> | ||||
|         </item> | ||||
|        </layout> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user