mirror of
				https://github.com/JakubMelka/PDF4QT.git
				synced 2025-06-05 21:59:17 +02:00 
			
		
		
		
	Tool for simple text search
This commit is contained in:
		| @@ -57,6 +57,7 @@ SOURCES += \ | |||||||
|     sources/pdfsecurityhandler.cpp \ |     sources/pdfsecurityhandler.cpp \ | ||||||
|     sources/pdftextlayout.cpp \ |     sources/pdftextlayout.cpp \ | ||||||
|     sources/pdfutils.cpp \ |     sources/pdfutils.cpp \ | ||||||
|  |     sources/pdfwidgettool.cpp \ | ||||||
|     sources/pdfxreftable.cpp \ |     sources/pdfxreftable.cpp \ | ||||||
|     sources/pdfvisitor.cpp \ |     sources/pdfvisitor.cpp \ | ||||||
|     sources/pdfencoding.cpp \ |     sources/pdfencoding.cpp \ | ||||||
| @@ -100,6 +101,7 @@ HEADERS += \ | |||||||
|     sources/pdfprogress.h \ |     sources/pdfprogress.h \ | ||||||
|     sources/pdfsecurityhandler.h \ |     sources/pdfsecurityhandler.h \ | ||||||
|     sources/pdftextlayout.h \ |     sources/pdftextlayout.h \ | ||||||
|  |     sources/pdfwidgettool.h \ | ||||||
|     sources/pdfxreftable.h \ |     sources/pdfxreftable.h \ | ||||||
|     sources/pdfflatmap.h \ |     sources/pdfflatmap.h \ | ||||||
|     sources/pdfvisitor.h \ |     sources/pdfvisitor.h \ | ||||||
|   | |||||||
| @@ -35,6 +35,7 @@ namespace pdf | |||||||
| class PDFProgress; | class PDFProgress; | ||||||
| class PDFWidget; | class PDFWidget; | ||||||
| class IDrawWidget; | class IDrawWidget; | ||||||
|  | class PDFWidgetTool; | ||||||
| class PDFCMSManager; | class PDFCMSManager; | ||||||
| class PDFTextLayoutGetter; | class PDFTextLayoutGetter; | ||||||
| class PDFAsynchronousPageCompiler; | class PDFAsynchronousPageCompiler; | ||||||
| @@ -298,6 +299,7 @@ public: | |||||||
|     PDFProgress* getProgress() const { return m_progress; } |     PDFProgress* getProgress() const { return m_progress; } | ||||||
|     void setProgress(PDFProgress* progress) { m_progress = progress; } |     void setProgress(PDFProgress* progress) { m_progress = progress; } | ||||||
|     PDFAsynchronousTextLayoutCompiler* getTextLayoutCompiler() const { return m_textLayoutCompiler; } |     PDFAsynchronousTextLayoutCompiler* getTextLayoutCompiler() const { return m_textLayoutCompiler; } | ||||||
|  |     PDFWidget* getWidget() const { return m_widget; } | ||||||
|  |  | ||||||
|     void setFeatures(PDFRenderer::Features features); |     void setFeatures(PDFRenderer::Features features); | ||||||
|     void setPreferredMeshResolutionRatio(PDFReal ratio); |     void setPreferredMeshResolutionRatio(PDFReal ratio); | ||||||
|   | |||||||
							
								
								
									
										417
									
								
								PdfForQtLib/sources/pdfwidgettool.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										417
									
								
								PdfForQtLib/sources/pdfwidgettool.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,417 @@ | |||||||
|  | //    Copyright (C) 2020 Jakub Melka | ||||||
|  | // | ||||||
|  | //    This file is part of PdfForQt. | ||||||
|  | // | ||||||
|  | //    PdfForQt is free software: you can redistribute it and/or modify | ||||||
|  | //    it under the terms of the GNU Lesser General Public License as published by | ||||||
|  | //    the Free Software Foundation, either version 3 of the License, or | ||||||
|  | //    (at your option) any later version. | ||||||
|  | // | ||||||
|  | //    PdfForQt is distributed in the hope that it will be useful, | ||||||
|  | //    but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | //    GNU Lesser General Public License for more details. | ||||||
|  | // | ||||||
|  | //    You should have received a copy of the GNU Lesser General Public License | ||||||
|  | //    along with PDFForQt.  If not, see <https://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
|  | #include "pdfwidgettool.h" | ||||||
|  | #include "pdfdrawwidget.h" | ||||||
|  | #include "pdfcompiler.h" | ||||||
|  |  | ||||||
|  | #include <QLabel> | ||||||
|  | #include <QAction> | ||||||
|  | #include <QCheckBox> | ||||||
|  | #include <QLineEdit> | ||||||
|  | #include <QGridLayout> | ||||||
|  | #include <QPushButton> | ||||||
|  |  | ||||||
|  | namespace pdf | ||||||
|  | { | ||||||
|  |  | ||||||
|  | PDFWidgetTool::PDFWidgetTool(PDFDrawWidgetProxy* proxy, QObject* parent) : | ||||||
|  |     BaseClass(parent), | ||||||
|  |     m_active(false), | ||||||
|  |     m_document(nullptr), | ||||||
|  |     m_proxy(proxy) | ||||||
|  | { | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | PDFWidgetTool::~PDFWidgetTool() | ||||||
|  | { | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PDFWidgetTool::drawPage(QPainter* painter, | ||||||
|  |                              PDFInteger pageIndex, | ||||||
|  |                              const PDFPrecompiledPage* compiledPage, | ||||||
|  |                              PDFTextLayoutGetter& layoutGetter, | ||||||
|  |                              const QMatrix& pagePointToDevicePointMatrix) const | ||||||
|  | { | ||||||
|  |     for (PDFWidgetTool* tool : m_toolStack) | ||||||
|  |     { | ||||||
|  |         tool->drawPage(painter, pageIndex, compiledPage, layoutGetter, pagePointToDevicePointMatrix); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PDFWidgetTool::setDocument(const PDFDocument* document) | ||||||
|  | { | ||||||
|  |     if (m_document != document) | ||||||
|  |     { | ||||||
|  |         // We must turn off the tool, if we are changing the document | ||||||
|  |         setActive(false); | ||||||
|  |         m_document = document; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PDFWidgetTool::setActive(bool active) | ||||||
|  | { | ||||||
|  |     if (m_active != active) | ||||||
|  |     { | ||||||
|  |         m_active = active; | ||||||
|  |  | ||||||
|  |         if (active) | ||||||
|  |         { | ||||||
|  |             m_proxy->registerDrawInterface(this); | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             m_proxy->unregisterDrawInterface(this); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         setActiveImpl(active); | ||||||
|  |  | ||||||
|  |         m_proxy->repaintNeeded(); | ||||||
|  |         emit toolActivityChanged(active); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PDFWidgetTool::setActiveImpl(bool active) | ||||||
|  | { | ||||||
|  |     Q_UNUSED(active); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | PDFFindTextTool::PDFFindTextTool(PDFDrawWidgetProxy* proxy, QAction* prevAction, QAction* nextAction, QObject* parent, QWidget* parentDialog) : | ||||||
|  |     BaseClass(proxy, parent), | ||||||
|  |     m_prevAction(prevAction), | ||||||
|  |     m_nextAction(nextAction), | ||||||
|  |     m_dialog(nullptr), | ||||||
|  |     m_parentDialog(parentDialog), | ||||||
|  |     m_caseSensitiveCheckBox(nullptr), | ||||||
|  |     m_wholeWordsCheckBox(nullptr), | ||||||
|  |     m_findTextEdit(nullptr), | ||||||
|  |     m_previousButton(nullptr), | ||||||
|  |     m_nextButton(nullptr), | ||||||
|  |     m_selectedResultIndex(0) | ||||||
|  | { | ||||||
|  |     PDFAsynchronousTextLayoutCompiler* compiler = getProxy()->getTextLayoutCompiler(); | ||||||
|  |     connect(compiler, &PDFAsynchronousTextLayoutCompiler::textLayoutChanged, this, &PDFFindTextTool::performSearch); | ||||||
|  |     connect(m_prevAction, &QAction::triggered, this, &PDFFindTextTool::onActionPrevious); | ||||||
|  |     connect(m_nextAction, &QAction::triggered, this, &PDFFindTextTool::onActionNext); | ||||||
|  |  | ||||||
|  |     updateActions(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PDFFindTextTool::drawPage(QPainter* painter, | ||||||
|  |                                PDFInteger pageIndex, | ||||||
|  |                                const PDFPrecompiledPage* compiledPage, | ||||||
|  |                                PDFTextLayoutGetter& layoutGetter, | ||||||
|  |                                const QMatrix& pagePointToDevicePointMatrix) const | ||||||
|  | { | ||||||
|  |     Q_UNUSED(compiledPage); | ||||||
|  |  | ||||||
|  |     const pdf::PDFTextSelection& textSelection = getTextSelection(); | ||||||
|  |     pdf::PDFTextSelectionPainter textSelectionPainter(&textSelection); | ||||||
|  |     textSelectionPainter.draw(painter, pageIndex, layoutGetter, pagePointToDevicePointMatrix); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PDFFindTextTool::clearResults() | ||||||
|  | { | ||||||
|  |     m_findResults.clear(); | ||||||
|  |     m_selectedResultIndex = 0; | ||||||
|  |     m_textSelection.dirty(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PDFFindTextTool::setActiveImpl(bool active) | ||||||
|  | { | ||||||
|  |     if (active) | ||||||
|  |     { | ||||||
|  |         Q_ASSERT(!m_dialog); | ||||||
|  |  | ||||||
|  |         // For find, we will need text layout | ||||||
|  |         getProxy()->getTextLayoutCompiler()->makeTextLayout(); | ||||||
|  |  | ||||||
|  |         // Create dialog | ||||||
|  |         m_dialog = new QDialog(m_parentDialog, Qt::Tool); | ||||||
|  |         m_dialog->setWindowTitle(tr("Find")); | ||||||
|  |  | ||||||
|  |         QGridLayout* layout = new QGridLayout(m_dialog); | ||||||
|  |         m_dialog->setLayout(layout); | ||||||
|  |  | ||||||
|  |         // Jakub Melka: we will create following widgets: | ||||||
|  |         //  - text with label | ||||||
|  |         //  - line edit, where user can enter search text | ||||||
|  |         //  - 2 checkbox for settings | ||||||
|  |         //  - 2 push buttons (previous/next) | ||||||
|  |  | ||||||
|  |         m_findTextEdit = new QLineEdit(m_dialog); | ||||||
|  |         m_caseSensitiveCheckBox = new QCheckBox(tr("Case sensitive"), m_dialog); | ||||||
|  |         m_wholeWordsCheckBox = new QCheckBox(tr("Whole words only"), m_dialog); | ||||||
|  |         m_previousButton = new QPushButton(tr("Previous"), m_dialog); | ||||||
|  |         m_nextButton = new QPushButton(tr("Next"), m_dialog); | ||||||
|  |  | ||||||
|  |         connect(m_previousButton, &QPushButton::clicked, m_prevAction, &QAction::trigger); | ||||||
|  |         connect(m_nextButton, &QPushButton::clicked, m_nextAction, &QAction::trigger); | ||||||
|  |         connect(m_findTextEdit, &QLineEdit::editingFinished, this, &PDFFindTextTool::onSearchText); | ||||||
|  |         connect(m_caseSensitiveCheckBox, &QCheckBox::clicked, this, &PDFFindTextTool::onSearchText); | ||||||
|  |         connect(m_wholeWordsCheckBox, &QCheckBox::clicked, this, &PDFFindTextTool::onSearchText); | ||||||
|  |  | ||||||
|  |         layout->addWidget(new QLabel(tr("Search text"), m_dialog), 0, 0, 1, -1, Qt::AlignLeft); | ||||||
|  |         layout->addWidget(m_findTextEdit, 1, 0, 1, -1); | ||||||
|  |         layout->addWidget(m_caseSensitiveCheckBox, 2, 0, 1, -1, Qt::AlignLeft); | ||||||
|  |         layout->addWidget(m_wholeWordsCheckBox, 3, 0, 1, -1, Qt::AlignLeft); | ||||||
|  |         layout->addWidget(m_previousButton, 4, 0); | ||||||
|  |         layout->addWidget(m_nextButton, 4, 1); | ||||||
|  |         m_dialog->setFixedSize(m_dialog->sizeHint()); | ||||||
|  |  | ||||||
|  |         PDFWidget* widget = getProxy()->getWidget(); | ||||||
|  |         QPoint topRight = widget->mapToGlobal(widget->rect().topRight()); | ||||||
|  |         QPoint topRightParent = m_parentDialog->mapFromGlobal(topRight); | ||||||
|  |  | ||||||
|  |         m_dialog->show(); | ||||||
|  |         m_dialog->move(topRightParent - QPoint(m_dialog->width() * 1.1, 0)); | ||||||
|  |         connect(m_dialog, &QDialog::rejected, this, [this] { setActive(false); }); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         Q_ASSERT(m_dialog); | ||||||
|  |         m_dialog->deleteLater(); | ||||||
|  |         m_dialog = nullptr; | ||||||
|  |         m_caseSensitiveCheckBox = nullptr; | ||||||
|  |         m_wholeWordsCheckBox = nullptr; | ||||||
|  |         m_findTextEdit = nullptr; | ||||||
|  |         m_previousButton = nullptr; | ||||||
|  |         m_nextButton = nullptr; | ||||||
|  |  | ||||||
|  |         clearResults(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PDFFindTextTool::onSearchText() | ||||||
|  | { | ||||||
|  |     m_parameters.phrase = m_findTextEdit->text(); | ||||||
|  |     m_parameters.isCaseSensitive = m_caseSensitiveCheckBox->isChecked(); | ||||||
|  |     m_parameters.isWholeWordsOnly = m_wholeWordsCheckBox->isChecked(); | ||||||
|  |     m_parameters.isSearchFinished = m_parameters.phrase.isEmpty(); | ||||||
|  |  | ||||||
|  |     m_findResults.clear(); | ||||||
|  |     m_textSelection.dirty(); | ||||||
|  |     updateResultsUI(); | ||||||
|  |  | ||||||
|  |     if (m_parameters.isSearchFinished) | ||||||
|  |     { | ||||||
|  |         // We have nothing to search for | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     pdf::PDFAsynchronousTextLayoutCompiler* compiler = getProxy()->getTextLayoutCompiler(); | ||||||
|  |     if (compiler->isTextLayoutReady()) | ||||||
|  |     { | ||||||
|  |         performSearch(); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         compiler->makeTextLayout(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PDFFindTextTool::onActionPrevious() | ||||||
|  | { | ||||||
|  |     if (!m_findResults.empty()) | ||||||
|  |     { | ||||||
|  |         if (m_selectedResultIndex == 0) | ||||||
|  |         { | ||||||
|  |             m_selectedResultIndex = m_findResults.size() - 1; | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             --m_selectedResultIndex; | ||||||
|  |         } | ||||||
|  |         m_textSelection.dirty(); | ||||||
|  |         getProxy()->repaintNeeded(); | ||||||
|  |         getProxy()->goToPage(m_findResults[m_selectedResultIndex].textSelectionItems.front().first.pageIndex); | ||||||
|  |         updateTitle(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PDFFindTextTool::onActionNext() | ||||||
|  | { | ||||||
|  |     if (!m_findResults.empty()) | ||||||
|  |     { | ||||||
|  |         m_selectedResultIndex = (m_selectedResultIndex + 1) % m_findResults.size(); | ||||||
|  |         m_textSelection.dirty(); | ||||||
|  |         getProxy()->repaintNeeded(); | ||||||
|  |         getProxy()->goToPage(m_findResults[m_selectedResultIndex].textSelectionItems.front().first.pageIndex); | ||||||
|  |         updateTitle(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PDFFindTextTool::performSearch() | ||||||
|  | { | ||||||
|  |     if (m_parameters.isSearchFinished) | ||||||
|  |     { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     clearResults(); | ||||||
|  |     m_parameters.isSearchFinished = true; | ||||||
|  |  | ||||||
|  |     if (m_parameters.phrase.isEmpty()) | ||||||
|  |     { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     PDFAsynchronousTextLayoutCompiler* compiler = getProxy()->getTextLayoutCompiler(); | ||||||
|  |     if (!compiler->isTextLayoutReady()) | ||||||
|  |     { | ||||||
|  |         // Text layout is not ready yet | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Prepare string to search | ||||||
|  |     QString expression = m_parameters.phrase; | ||||||
|  |  | ||||||
|  |     bool useRegularExpression = false; | ||||||
|  |     if (m_parameters.isWholeWordsOnly) | ||||||
|  |     { | ||||||
|  |         expression = QString("\\b%1\\b").arg(QRegularExpression::escape(expression)); | ||||||
|  |         useRegularExpression = true; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     pdf::PDFTextFlow::FlowFlags flowFlags = pdf::PDFTextFlow::SeparateBlocks; | ||||||
|  |  | ||||||
|  |     const pdf::PDFTextLayoutStorage* textLayoutStorage = compiler->getTextLayoutStorage(); | ||||||
|  |     if (!useRegularExpression) | ||||||
|  |     { | ||||||
|  |         // Use simple text search | ||||||
|  |         Qt::CaseSensitivity caseSensitivity = m_parameters.isCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive; | ||||||
|  |         m_findResults = textLayoutStorage->find(expression, caseSensitivity, flowFlags); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         // Use regular expression search | ||||||
|  |         QRegularExpression::PatternOptions patternOptions = QRegularExpression::UseUnicodePropertiesOption | QRegularExpression::OptimizeOnFirstUsageOption; | ||||||
|  |         if (!m_parameters.isCaseSensitive) | ||||||
|  |         { | ||||||
|  |             patternOptions |= QRegularExpression::CaseInsensitiveOption; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         QRegularExpression regularExpression(expression, patternOptions); | ||||||
|  |         m_findResults = textLayoutStorage->find(regularExpression, flowFlags); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     std::sort(m_findResults.begin(), m_findResults.end()); | ||||||
|  |     m_selectedResultIndex = 0; | ||||||
|  |     m_textSelection.dirty(); | ||||||
|  |     getProxy()->repaintNeeded(); | ||||||
|  |  | ||||||
|  |     updateResultsUI(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PDFFindTextTool::updateActions() | ||||||
|  | { | ||||||
|  |     const bool isActive = this->isActive(); | ||||||
|  |     const bool hasResults = !m_findResults.empty(); | ||||||
|  |     const bool enablePrevious = isActive && hasResults; | ||||||
|  |     const bool enableNext = isActive && hasResults; | ||||||
|  |  | ||||||
|  |     m_prevAction->setEnabled(enablePrevious); | ||||||
|  |     m_nextAction->setEnabled(enableNext); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PDFFindTextTool::updateResultsUI() | ||||||
|  | { | ||||||
|  |     m_selectedResultIndex = qBound(size_t(0), m_selectedResultIndex, m_findResults.size()); | ||||||
|  |  | ||||||
|  |     updateActions(); | ||||||
|  |     updateTitle(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PDFFindTextTool::updateTitle() | ||||||
|  | { | ||||||
|  |     if (!m_dialog) | ||||||
|  |     { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (m_findResults.empty()) | ||||||
|  |     { | ||||||
|  |         m_dialog->setWindowTitle(tr("Find")); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         m_dialog->setWindowTitle(tr("Find (%1/%2)").arg(m_selectedResultIndex + 1).arg(m_findResults.size())); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | PDFTextSelection PDFFindTextTool::getTextSelectionImpl() const | ||||||
|  | { | ||||||
|  |     pdf::PDFTextSelection result; | ||||||
|  |  | ||||||
|  |     for (size_t i = 0; i < m_findResults.size(); ++i) | ||||||
|  |     { | ||||||
|  |         const pdf::PDFFindResult& findResult = m_findResults[i]; | ||||||
|  |  | ||||||
|  |         QColor color(Qt::blue); | ||||||
|  |         if (i == m_selectedResultIndex) | ||||||
|  |         { | ||||||
|  |             color = QColor(Qt::yellow); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         result.addItems(findResult.textSelectionItems, color); | ||||||
|  |     } | ||||||
|  |     result.build(); | ||||||
|  |  | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | PDFToolManager::PDFToolManager(PDFDrawWidgetProxy* proxy, QAction* findPreviousAction, QAction* findNextAction, QObject* parent, QWidget* parentDialog) : | ||||||
|  |     BaseClass(parent), | ||||||
|  |     m_predefinedTools() | ||||||
|  | { | ||||||
|  |     m_predefinedTools[FindTextTool] = new PDFFindTextTool(proxy, findPreviousAction, findNextAction, this, parentDialog); | ||||||
|  |  | ||||||
|  |     for (PDFWidgetTool* tool : m_predefinedTools) | ||||||
|  |     { | ||||||
|  |         m_tools.insert(tool); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PDFToolManager::setDocument(const PDFDocument* document) | ||||||
|  | { | ||||||
|  |     for (PDFWidgetTool* tool : m_tools) | ||||||
|  |     { | ||||||
|  |         tool->setDocument(document); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | PDFWidgetTool* PDFToolManager::getActiveTool() const | ||||||
|  | { | ||||||
|  |     for (PDFWidgetTool* tool : m_tools) | ||||||
|  |     { | ||||||
|  |         if (tool->isActive()) | ||||||
|  |         { | ||||||
|  |             return tool; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return nullptr; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | PDFFindTextTool* PDFToolManager::getFindTextTool() const | ||||||
|  | { | ||||||
|  |     return qobject_cast<PDFFindTextTool*>(m_predefinedTools[FindTextTool]); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | }   // namespace pdf | ||||||
							
								
								
									
										188
									
								
								PdfForQtLib/sources/pdfwidgettool.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								PdfForQtLib/sources/pdfwidgettool.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,188 @@ | |||||||
|  | //    Copyright (C) 2020 Jakub Melka | ||||||
|  | // | ||||||
|  | //    This file is part of PdfForQt. | ||||||
|  | // | ||||||
|  | //    PdfForQt is free software: you can redistribute it and/or modify | ||||||
|  | //    it under the terms of the GNU Lesser General Public License as published by | ||||||
|  | //    the Free Software Foundation, either version 3 of the License, or | ||||||
|  | //    (at your option) any later version. | ||||||
|  | // | ||||||
|  | //    PdfForQt is distributed in the hope that it will be useful, | ||||||
|  | //    but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | //    GNU Lesser General Public License for more details. | ||||||
|  | // | ||||||
|  | //    You should have received a copy of the GNU Lesser General Public License | ||||||
|  | //    along with PDFForQt.  If not, see <https://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
|  | #ifndef PDFWIDGETTOOL_H | ||||||
|  | #define PDFWIDGETTOOL_H | ||||||
|  |  | ||||||
|  | #include "pdfdrawspacecontroller.h" | ||||||
|  | #include "pdftextlayout.h" | ||||||
|  |  | ||||||
|  | #include <QDialog> | ||||||
|  |  | ||||||
|  | class QCheckBox; | ||||||
|  |  | ||||||
|  | namespace pdf | ||||||
|  | { | ||||||
|  |  | ||||||
|  | /// Base class for various widget tools (for example, searching, text selection, | ||||||
|  | /// screenshots, zoom tool etc.). Each tool can have subtools (for example, | ||||||
|  | /// screenshot tool is picking screenshot rectangle). | ||||||
|  | class PDFFORQTLIBSHARED_EXPORT PDFWidgetTool : public QObject, public IDocumentDrawInterface | ||||||
|  | { | ||||||
|  |     Q_OBJECT | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     using BaseClass = QObject; | ||||||
|  |  | ||||||
|  | public: | ||||||
|  |     explicit PDFWidgetTool(PDFDrawWidgetProxy* proxy, QObject* parent); | ||||||
|  |     virtual ~PDFWidgetTool(); | ||||||
|  |  | ||||||
|  |     virtual void drawPage(QPainter* painter, | ||||||
|  |                           PDFInteger pageIndex, | ||||||
|  |                           const PDFPrecompiledPage* compiledPage, | ||||||
|  |                           PDFTextLayoutGetter& layoutGetter, | ||||||
|  |                           const QMatrix& pagePointToDevicePointMatrix) const override; | ||||||
|  |  | ||||||
|  |     /// Sets document, shuts down the tool, if it is active, and document | ||||||
|  |     /// is changing. | ||||||
|  |     /// \param document Document | ||||||
|  |     void setDocument(const PDFDocument* document); | ||||||
|  |  | ||||||
|  |     /// Sets tool as active or inactive. If tool is active, then it is processed | ||||||
|  |     /// in draw widget proxy events (such as drawing etc.). | ||||||
|  |     /// \param active Is tool active? | ||||||
|  |     void setActive(bool active); | ||||||
|  |  | ||||||
|  |     /// Returns true, if tool is active | ||||||
|  |     bool isActive() const { return m_active; } | ||||||
|  |  | ||||||
|  | signals: | ||||||
|  |     void toolActivityChanged(bool active); | ||||||
|  |  | ||||||
|  | protected: | ||||||
|  |     virtual void setActiveImpl(bool active); | ||||||
|  |  | ||||||
|  |     PDFDrawWidgetProxy* getProxy() const { return m_proxy; } | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     bool m_active; | ||||||
|  |     const PDFDocument* m_document; | ||||||
|  |     PDFDrawWidgetProxy* m_proxy; | ||||||
|  |     std::vector<PDFWidgetTool*> m_toolStack; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /// Simple tool for find text in PDF document. It is much simpler than advanced | ||||||
|  | /// search and can't search using regular expressions. | ||||||
|  | class PDFFORQTLIBSHARED_EXPORT PDFFindTextTool : public PDFWidgetTool | ||||||
|  | { | ||||||
|  |     Q_OBJECT | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     using BaseClass = PDFWidgetTool; | ||||||
|  |  | ||||||
|  | public: | ||||||
|  |     /// Construct new text search tool | ||||||
|  |     /// \param proxy Draw widget proxy | ||||||
|  |     /// \param prevAction Action for navigating to previous result | ||||||
|  |     /// \param nextAction Action for navigating to next result | ||||||
|  |     /// \param parent Parent object | ||||||
|  |     /// \param parentDialog Paret dialog for tool dialog | ||||||
|  |     explicit PDFFindTextTool(PDFDrawWidgetProxy* proxy, QAction* prevAction, QAction* nextAction, QObject* parent, QWidget* parentDialog); | ||||||
|  |  | ||||||
|  |     virtual void drawPage(QPainter* painter, | ||||||
|  |                           PDFInteger pageIndex, | ||||||
|  |                           const PDFPrecompiledPage* compiledPage, | ||||||
|  |                           PDFTextLayoutGetter& layoutGetter, | ||||||
|  |                           const QMatrix& pagePointToDevicePointMatrix) const override; | ||||||
|  |  | ||||||
|  | protected: | ||||||
|  |     virtual void setActiveImpl(bool active) override; | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     void onSearchText(); | ||||||
|  |     void onActionPrevious(); | ||||||
|  |     void onActionNext(); | ||||||
|  |  | ||||||
|  |     void performSearch(); | ||||||
|  |     void updateActions(); | ||||||
|  |     void updateResultsUI(); | ||||||
|  |     void updateTitle(); | ||||||
|  |     void clearResults(); | ||||||
|  |  | ||||||
|  |     QAction* m_prevAction; | ||||||
|  |     QAction* m_nextAction; | ||||||
|  |     QWidget* m_parentDialog; | ||||||
|  |  | ||||||
|  |     QDialog* m_dialog; | ||||||
|  |     QCheckBox* m_caseSensitiveCheckBox; | ||||||
|  |     QCheckBox* m_wholeWordsCheckBox; | ||||||
|  |     QLineEdit* m_findTextEdit; | ||||||
|  |     QPushButton* m_previousButton; | ||||||
|  |     QPushButton* m_nextButton; | ||||||
|  |  | ||||||
|  |     pdf::PDFTextSelection getTextSelection() const { return m_textSelection.get(this, &PDFFindTextTool::getTextSelectionImpl); } | ||||||
|  |     pdf::PDFTextSelection getTextSelectionImpl() const; | ||||||
|  |  | ||||||
|  |     struct SearchParameters | ||||||
|  |     { | ||||||
|  |         QString phrase; | ||||||
|  |         bool isCaseSensitive = false; | ||||||
|  |         bool isWholeWordsOnly = false; | ||||||
|  |         bool isSearchFinished = false; | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     SearchParameters m_parameters; | ||||||
|  |     pdf::PDFFindResults m_findResults; | ||||||
|  |     size_t m_selectedResultIndex; | ||||||
|  |     mutable pdf::PDFCachedItem<pdf::PDFTextSelection> m_textSelection; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /// Manager used for managing tools, their activity, availability | ||||||
|  | /// and other settings. It also defines a predefined set of tools, | ||||||
|  | /// available for various purposes (text searching, magnifier tool etc.) | ||||||
|  | class PDFFORQTLIBSHARED_EXPORT PDFToolManager : public QObject | ||||||
|  | { | ||||||
|  |     Q_OBJECT | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     using BaseClass = QObject; | ||||||
|  |  | ||||||
|  | public: | ||||||
|  |     /// Construct new text search tool | ||||||
|  |     /// \param proxy Draw widget proxy | ||||||
|  |     /// \param prevAction Action for navigating to previous result | ||||||
|  |     /// \param nextAction Action for navigating to next result | ||||||
|  |     /// \param parent Parent object | ||||||
|  |     /// \param parentDialog Paret dialog for tool dialog | ||||||
|  |     explicit PDFToolManager(PDFDrawWidgetProxy* proxy, QAction* findPreviousAction, QAction* findNextAction, QObject* parent, QWidget* parentDialog); | ||||||
|  |  | ||||||
|  |     /// Sets document | ||||||
|  |     /// \param document Document | ||||||
|  |     void setDocument(const PDFDocument* document); | ||||||
|  |  | ||||||
|  |     enum PredefinedTools | ||||||
|  |     { | ||||||
|  |         FindTextTool, | ||||||
|  |         ToolEnd | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     /// Returns first active tool from tool set. If no tool is active, | ||||||
|  |     /// then nullptr is returned. | ||||||
|  |     PDFWidgetTool* getActiveTool() const; | ||||||
|  |  | ||||||
|  |     /// Returns find text tool | ||||||
|  |     PDFFindTextTool* getFindTextTool() const; | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     std::set<PDFWidgetTool*> m_tools; | ||||||
|  |     std::array<PDFWidgetTool*, ToolEnd> m_predefinedTools; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | }   // namespace pdf | ||||||
|  |  | ||||||
|  | #endif // PDFWIDGETTOOL_H | ||||||
| @@ -93,6 +93,7 @@ void PDFAdvancedFindWidget::on_searchButton_clicked() | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     m_findResults.clear(); |     m_findResults.clear(); | ||||||
|  |     m_textSelection.dirty(); | ||||||
|     updateResultsUI(); |     updateResultsUI(); | ||||||
|  |  | ||||||
|     pdf::PDFAsynchronousTextLayoutCompiler* compiler = m_proxy->getTextLayoutCompiler(); |     pdf::PDFAsynchronousTextLayoutCompiler* compiler = m_proxy->getTextLayoutCompiler(); | ||||||
| @@ -173,7 +174,7 @@ void PDFAdvancedFindWidget::drawPage(QPainter* painter, | |||||||
|  |  | ||||||
| void PDFAdvancedFindWidget::performSearch() | void PDFAdvancedFindWidget::performSearch() | ||||||
| { | { | ||||||
|     if (m_parameters.isSearchFinished) |     if (m_parameters.isSearchFinished || m_parameters.phrase.isEmpty()) | ||||||
|     { |     { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| @@ -269,6 +270,7 @@ pdf::PDFTextSelection PDFAdvancedFindWidget::getTextSelectionImpl() const | |||||||
|  |  | ||||||
|         result.addItems(findResult.textSelectionItems, color); |         result.addItems(findResult.textSelectionItems, color); | ||||||
|     } |     } | ||||||
|  |     result.build(); | ||||||
|  |  | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -27,5 +27,9 @@ | |||||||
|         <file>resources/info.svg</file> |         <file>resources/info.svg</file> | ||||||
|         <file>resources/send-mail.svg</file> |         <file>resources/send-mail.svg</file> | ||||||
|         <file>resources/cms.svg</file> |         <file>resources/cms.svg</file> | ||||||
|  |         <file>resources/find.svg</file> | ||||||
|  |         <file>resources/find-advanced.svg</file> | ||||||
|  |         <file>resources/find-next.svg</file> | ||||||
|  |         <file>resources/find-previous.svg</file> | ||||||
|     </qresource> |     </qresource> | ||||||
| </RCC> | </RCC> | ||||||
|   | |||||||
| @@ -79,7 +79,8 @@ PDFViewerMainWindow::PDFViewerMainWindow(QWidget* parent) : | |||||||
|     m_taskbarButton(new QWinTaskbarButton(this)), |     m_taskbarButton(new QWinTaskbarButton(this)), | ||||||
|     m_progressTaskbarIndicator(nullptr), |     m_progressTaskbarIndicator(nullptr), | ||||||
|     m_progressDialog(nullptr), |     m_progressDialog(nullptr), | ||||||
|     m_isBusy(false) |     m_isBusy(false), | ||||||
|  |     m_toolManager(nullptr) | ||||||
| { | { | ||||||
|     ui->setupUi(this); |     ui->setupUi(this); | ||||||
|  |  | ||||||
| @@ -93,6 +94,8 @@ PDFViewerMainWindow::PDFViewerMainWindow(QWidget* parent) : | |||||||
|     ui->actionZoom_In->setShortcut(QKeySequence::ZoomIn); |     ui->actionZoom_In->setShortcut(QKeySequence::ZoomIn); | ||||||
|     ui->actionZoom_Out->setShortcut(QKeySequence::ZoomOut); |     ui->actionZoom_Out->setShortcut(QKeySequence::ZoomOut); | ||||||
|     ui->actionFind->setShortcut(QKeySequence::Find); |     ui->actionFind->setShortcut(QKeySequence::Find); | ||||||
|  |     ui->actionFindPrevious->setShortcut(QKeySequence::FindPrevious); | ||||||
|  |     ui->actionFindNext->setShortcut(QKeySequence::FindNext); | ||||||
|  |  | ||||||
|     connect(ui->actionOpen, &QAction::triggered, this, &PDFViewerMainWindow::onActionOpenTriggered); |     connect(ui->actionOpen, &QAction::triggered, this, &PDFViewerMainWindow::onActionOpenTriggered); | ||||||
|     connect(ui->actionClose, &QAction::triggered, this, &PDFViewerMainWindow::onActionCloseTriggered); |     connect(ui->actionClose, &QAction::triggered, this, &PDFViewerMainWindow::onActionCloseTriggered); | ||||||
| @@ -188,6 +191,7 @@ PDFViewerMainWindow::PDFViewerMainWindow(QWidget* parent) : | |||||||
|     toggleAdvancedFindAction->setObjectName("actionAdvancedFind"); |     toggleAdvancedFindAction->setObjectName("actionAdvancedFind"); | ||||||
|     toggleAdvancedFindAction->setText(tr("Advanced Find")); |     toggleAdvancedFindAction->setText(tr("Advanced Find")); | ||||||
|     toggleAdvancedFindAction->setShortcut(QKeySequence("Ctrl+Shift+F")); |     toggleAdvancedFindAction->setShortcut(QKeySequence("Ctrl+Shift+F")); | ||||||
|  |     toggleAdvancedFindAction->setIcon(QIcon(":/resources/find-advanced.svg")); | ||||||
|     ui->menuEdit->insertAction(nullptr, toggleAdvancedFindAction); |     ui->menuEdit->insertAction(nullptr, toggleAdvancedFindAction); | ||||||
|  |  | ||||||
|     ui->actionRenderOptionAntialiasing->setData(pdf::PDFRenderer::Antialiasing); |     ui->actionRenderOptionAntialiasing->setData(pdf::PDFRenderer::Antialiasing); | ||||||
| @@ -206,6 +210,9 @@ PDFViewerMainWindow::PDFViewerMainWindow(QWidget* parent) : | |||||||
|     ui->menuView->addAction(m_sidebarDockWidget->toggleViewAction()); |     ui->menuView->addAction(m_sidebarDockWidget->toggleViewAction()); | ||||||
|     m_sidebarDockWidget->toggleViewAction()->setObjectName("actionSidebar"); |     m_sidebarDockWidget->toggleViewAction()->setObjectName("actionSidebar"); | ||||||
|  |  | ||||||
|  |     // Initialize tools | ||||||
|  |     m_toolManager = new pdf::PDFToolManager(m_pdfWidget->getDrawWidgetProxy(), ui->actionFindPrevious, ui->actionFindNext, this, this); | ||||||
|  |  | ||||||
|     connect(m_pdfWidget->getDrawWidgetProxy(), &pdf::PDFDrawWidgetProxy::drawSpaceChanged, this, &PDFViewerMainWindow::onDrawSpaceChanged); |     connect(m_pdfWidget->getDrawWidgetProxy(), &pdf::PDFDrawWidgetProxy::drawSpaceChanged, this, &PDFViewerMainWindow::onDrawSpaceChanged); | ||||||
|     connect(m_pdfWidget->getDrawWidgetProxy(), &pdf::PDFDrawWidgetProxy::pageLayoutChanged, this, &PDFViewerMainWindow::onPageLayoutChanged); |     connect(m_pdfWidget->getDrawWidgetProxy(), &pdf::PDFDrawWidgetProxy::pageLayoutChanged, this, &PDFViewerMainWindow::onPageLayoutChanged); | ||||||
|     connect(m_pdfWidget, &pdf::PDFWidget::pageRenderingErrorsChanged, this, &PDFViewerMainWindow::onPageRenderingErrorsChanged, Qt::QueuedConnection); |     connect(m_pdfWidget, &pdf::PDFWidget::pageRenderingErrorsChanged, this, &PDFViewerMainWindow::onPageRenderingErrorsChanged, Qt::QueuedConnection); | ||||||
| @@ -215,6 +222,7 @@ PDFViewerMainWindow::PDFViewerMainWindow(QWidget* parent) : | |||||||
|     connect(m_progress, &pdf::PDFProgress::progressFinished, this, &PDFViewerMainWindow::onProgressFinished); |     connect(m_progress, &pdf::PDFProgress::progressFinished, this, &PDFViewerMainWindow::onProgressFinished); | ||||||
|     connect(&m_futureWatcher, &QFutureWatcher<AsyncReadingResult>::finished, this, &PDFViewerMainWindow::onDocumentReadingFinished); |     connect(&m_futureWatcher, &QFutureWatcher<AsyncReadingResult>::finished, this, &PDFViewerMainWindow::onDocumentReadingFinished); | ||||||
|     connect(this, &PDFViewerMainWindow::queryPasswordRequest, this, &PDFViewerMainWindow::onQueryPasswordRequest, Qt::BlockingQueuedConnection); |     connect(this, &PDFViewerMainWindow::queryPasswordRequest, this, &PDFViewerMainWindow::onQueryPasswordRequest, Qt::BlockingQueuedConnection); | ||||||
|  |     connect(ui->actionFind, &QAction::triggered, this, [this] { m_toolManager->getFindTextTool()->setActive(true); }); | ||||||
|  |  | ||||||
|     readActionSettings(); |     readActionSettings(); | ||||||
|     updatePageLayoutActions(); |     updatePageLayoutActions(); | ||||||
| @@ -756,6 +764,7 @@ void PDFViewerMainWindow::updateActionsAvailability() | |||||||
|     ui->actionFitWidth->setEnabled(hasValidDocument); |     ui->actionFitWidth->setEnabled(hasValidDocument); | ||||||
|     ui->actionFitHeight->setEnabled(hasValidDocument); |     ui->actionFitHeight->setEnabled(hasValidDocument); | ||||||
|     ui->actionRendering_Errors->setEnabled(hasValidDocument); |     ui->actionRendering_Errors->setEnabled(hasValidDocument); | ||||||
|  |     ui->actionFind->setEnabled(hasValidDocument); | ||||||
|     setEnabled(!isBusy); |     setEnabled(!isBusy); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -857,6 +866,7 @@ void PDFViewerMainWindow::onDocumentReadingFinished() | |||||||
|         case pdf::PDFDocumentReader::Result::Cancelled: |         case pdf::PDFDocumentReader::Result::Cancelled: | ||||||
|             break; // Do nothing, user cancelled the document reading |             break; // Do nothing, user cancelled the document reading | ||||||
|     } |     } | ||||||
|  |     updateActionsAvailability(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void PDFViewerMainWindow::setDocument(const pdf::PDFDocument* document) | void PDFViewerMainWindow::setDocument(const pdf::PDFDocument* document) | ||||||
| @@ -874,6 +884,7 @@ void PDFViewerMainWindow::setDocument(const pdf::PDFDocument* document) | |||||||
|         m_optionalContentActivity = new pdf::PDFOptionalContentActivity(document, pdf::OCUsage::View, this); |         m_optionalContentActivity = new pdf::PDFOptionalContentActivity(document, pdf::OCUsage::View, this); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     m_toolManager->setDocument(document); | ||||||
|     m_pdfWidget->setDocument(document, m_optionalContentActivity); |     m_pdfWidget->setDocument(document, m_optionalContentActivity); | ||||||
|     m_sidebarWidget->setDocument(document, m_optionalContentActivity); |     m_sidebarWidget->setDocument(document, m_optionalContentActivity); | ||||||
|     m_advancedFindWidget->setDocument(document); |     m_advancedFindWidget->setDocument(document); | ||||||
|   | |||||||
| @@ -25,6 +25,7 @@ | |||||||
| #include "pdfviewersettings.h" | #include "pdfviewersettings.h" | ||||||
| #include "pdfdocumentreader.h" | #include "pdfdocumentreader.h" | ||||||
| #include "pdfdocumentpropertiesdialog.h" | #include "pdfdocumentpropertiesdialog.h" | ||||||
|  | #include "pdfwidgettool.h" | ||||||
|  |  | ||||||
| #include <QFuture> | #include <QFuture> | ||||||
| #include <QTreeView> | #include <QTreeView> | ||||||
| @@ -163,6 +164,8 @@ private: | |||||||
|  |  | ||||||
|     QProgressDialog* m_progressDialog; |     QProgressDialog* m_progressDialog; | ||||||
|     bool m_isBusy; |     bool m_isBusy; | ||||||
|  |  | ||||||
|  |     pdf::PDFToolManager* m_toolManager; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| }   // namespace pdfviewer | }   // namespace pdfviewer | ||||||
|   | |||||||
| @@ -101,6 +101,8 @@ | |||||||
|      <string>Edit</string> |      <string>Edit</string> | ||||||
|     </property> |     </property> | ||||||
|     <addaction name="actionFind"/> |     <addaction name="actionFind"/> | ||||||
|  |     <addaction name="actionFindPrevious"/> | ||||||
|  |     <addaction name="actionFindNext"/> | ||||||
|    </widget> |    </widget> | ||||||
|    <addaction name="menuFile"/> |    <addaction name="menuFile"/> | ||||||
|    <addaction name="menuEdit"/> |    <addaction name="menuEdit"/> | ||||||
| @@ -348,10 +350,32 @@ | |||||||
|    </property> |    </property> | ||||||
|   </action> |   </action> | ||||||
|   <action name="actionFind"> |   <action name="actionFind"> | ||||||
|  |    <property name="icon"> | ||||||
|  |     <iconset resource="pdfforqtviewer.qrc"> | ||||||
|  |      <normaloff>:/resources/find.svg</normaloff>:/resources/find.svg</iconset> | ||||||
|  |    </property> | ||||||
|    <property name="text"> |    <property name="text"> | ||||||
|     <string>Find</string> |     <string>Find</string> | ||||||
|    </property> |    </property> | ||||||
|   </action> |   </action> | ||||||
|  |   <action name="actionFindPrevious"> | ||||||
|  |    <property name="icon"> | ||||||
|  |     <iconset resource="pdfforqtviewer.qrc"> | ||||||
|  |      <normaloff>:/resources/find-previous.svg</normaloff>:/resources/find-previous.svg</iconset> | ||||||
|  |    </property> | ||||||
|  |    <property name="text"> | ||||||
|  |     <string>Find Previous</string> | ||||||
|  |    </property> | ||||||
|  |   </action> | ||||||
|  |   <action name="actionFindNext"> | ||||||
|  |    <property name="icon"> | ||||||
|  |     <iconset resource="pdfforqtviewer.qrc"> | ||||||
|  |      <normaloff>:/resources/find-next.svg</normaloff>:/resources/find-next.svg</iconset> | ||||||
|  |    </property> | ||||||
|  |    <property name="text"> | ||||||
|  |     <string>Find Next</string> | ||||||
|  |    </property> | ||||||
|  |   </action> | ||||||
|  </widget> |  </widget> | ||||||
|  <layoutdefault spacing="6" margin="11"/> |  <layoutdefault spacing="6" margin="11"/> | ||||||
|  <resources> |  <resources> | ||||||
|   | |||||||
							
								
								
									
										135
									
								
								PdfForQtViewer/resources/find-advanced.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								PdfForQtViewer/resources/find-advanced.svg
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,135 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||||
|  | <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||||
|  |  | ||||||
|  | <svg | ||||||
|  |    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||||
|  |    xmlns:cc="http://creativecommons.org/ns#" | ||||||
|  |    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||||
|  |    xmlns:svg="http://www.w3.org/2000/svg" | ||||||
|  |    xmlns="http://www.w3.org/2000/svg" | ||||||
|  |    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||||
|  |    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||||
|  |    width="30mm" | ||||||
|  |    height="30mm" | ||||||
|  |    viewBox="0 0 30 30" | ||||||
|  |    version="1.1" | ||||||
|  |    id="svg5291" | ||||||
|  |    inkscape:version="0.92.4 (5da689c313, 2019-01-14)" | ||||||
|  |    sodipodi:docname="find-advanced.svg"> | ||||||
|  |   <defs | ||||||
|  |      id="defs5285"> | ||||||
|  |     <inkscape:perspective | ||||||
|  |        sodipodi:type="inkscape:persp3d" | ||||||
|  |        inkscape:vp_x="0 : 15 : 1" | ||||||
|  |        inkscape:vp_y="0 : 1000 : 0" | ||||||
|  |        inkscape:vp_z="30 : 15 : 1" | ||||||
|  |        inkscape:persp3d-origin="15 : 10 : 1" | ||||||
|  |        id="perspective5921" /> | ||||||
|  |   </defs> | ||||||
|  |   <sodipodi:namedview | ||||||
|  |      id="base" | ||||||
|  |      pagecolor="#ffffff" | ||||||
|  |      bordercolor="#666666" | ||||||
|  |      borderopacity="1.0" | ||||||
|  |      inkscape:pageopacity="0.0" | ||||||
|  |      inkscape:pageshadow="2" | ||||||
|  |      inkscape:zoom="7.9999996" | ||||||
|  |      inkscape:cx="96.758243" | ||||||
|  |      inkscape:cy="75.073314" | ||||||
|  |      inkscape:document-units="mm" | ||||||
|  |      inkscape:current-layer="layer1" | ||||||
|  |      showgrid="false" | ||||||
|  |      inkscape:window-width="3840" | ||||||
|  |      inkscape:window-height="2035" | ||||||
|  |      inkscape:window-x="-13" | ||||||
|  |      inkscape:window-y="-13" | ||||||
|  |      inkscape:window-maximized="1" /> | ||||||
|  |   <metadata | ||||||
|  |      id="metadata5288"> | ||||||
|  |     <rdf:RDF> | ||||||
|  |       <cc:Work | ||||||
|  |          rdf:about=""> | ||||||
|  |         <dc:format>image/svg+xml</dc:format> | ||||||
|  |         <dc:type | ||||||
|  |            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||||
|  |         <dc:title></dc:title> | ||||||
|  |         <dc:creator> | ||||||
|  |           <cc:Agent> | ||||||
|  |             <dc:title>Jakub Melka</dc:title> | ||||||
|  |           </cc:Agent> | ||||||
|  |         </dc:creator> | ||||||
|  |         <cc:license | ||||||
|  |            rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" /> | ||||||
|  |       </cc:Work> | ||||||
|  |       <cc:License | ||||||
|  |          rdf:about="http://creativecommons.org/licenses/by-sa/4.0/"> | ||||||
|  |         <cc:permits | ||||||
|  |            rdf:resource="http://creativecommons.org/ns#Reproduction" /> | ||||||
|  |         <cc:permits | ||||||
|  |            rdf:resource="http://creativecommons.org/ns#Distribution" /> | ||||||
|  |         <cc:requires | ||||||
|  |            rdf:resource="http://creativecommons.org/ns#Notice" /> | ||||||
|  |         <cc:requires | ||||||
|  |            rdf:resource="http://creativecommons.org/ns#Attribution" /> | ||||||
|  |         <cc:permits | ||||||
|  |            rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /> | ||||||
|  |         <cc:requires | ||||||
|  |            rdf:resource="http://creativecommons.org/ns#ShareAlike" /> | ||||||
|  |       </cc:License> | ||||||
|  |     </rdf:RDF> | ||||||
|  |   </metadata> | ||||||
|  |   <g | ||||||
|  |      inkscape:label="Vrstva 1" | ||||||
|  |      inkscape:groupmode="layer" | ||||||
|  |      id="layer1" | ||||||
|  |      transform="translate(0,-267)"> | ||||||
|  |     <flowRoot | ||||||
|  |        xml:space="preserve" | ||||||
|  |        id="flowRoot5913" | ||||||
|  |        style="fill:black;fill-opacity:1;stroke:none;font-family:sans-serif;font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;letter-spacing:0px;word-spacing:0px"><flowRegion | ||||||
|  |          id="flowRegion5915"><rect | ||||||
|  |            id="rect5917" | ||||||
|  |            width="129.22377" | ||||||
|  |            height="91.747108" | ||||||
|  |            x="-13.788582" | ||||||
|  |            y="-33.515606" /></flowRegion><flowPara | ||||||
|  |          id="flowPara5919" /></flowRoot>    <g | ||||||
|  |        id="g849" | ||||||
|  |        transform="translate(-1.0583333,1.5875)"> | ||||||
|  |       <ellipse | ||||||
|  |          ry="4.8121095" | ||||||
|  |          rx="4.8741207" | ||||||
|  |          cy="275.09717" | ||||||
|  |          cx="12.618022" | ||||||
|  |          id="path5985" | ||||||
|  |          style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.75;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> | ||||||
|  |       <path | ||||||
|  |          inkscape:connector-curvature="0" | ||||||
|  |          id="path5987" | ||||||
|  |          d="m 16.10308,278.8923 4.861718,5.45703" | ||||||
|  |          style="fill:none;stroke:#000000;stroke-width:0.75;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> | ||||||
|  |     </g> | ||||||
|  |     <text | ||||||
|  |        xml:space="preserve" | ||||||
|  |        style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif Italic';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332" | ||||||
|  |        x="3.0603709" | ||||||
|  |        y="293.01346" | ||||||
|  |        id="text845"><tspan | ||||||
|  |          sodipodi:role="line" | ||||||
|  |          id="tspan843" | ||||||
|  |          x="3.0603709" | ||||||
|  |          y="293.01346" | ||||||
|  |          style="stroke-width:0.26458332">abc</tspan></text> | ||||||
|  |     <text | ||||||
|  |        xml:space="preserve" | ||||||
|  |        style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif Italic';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332" | ||||||
|  |        x="19.719973" | ||||||
|  |        y="276.62527" | ||||||
|  |        id="text853"><tspan | ||||||
|  |          sodipodi:role="line" | ||||||
|  |          id="tspan851" | ||||||
|  |          x="19.719973" | ||||||
|  |          y="276.62527" | ||||||
|  |          style="stroke-width:0.26458332">+</tspan></text> | ||||||
|  |   </g> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 5.0 KiB | 
							
								
								
									
										129
									
								
								PdfForQtViewer/resources/find-next.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								PdfForQtViewer/resources/find-next.svg
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,129 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||||
|  | <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||||
|  |  | ||||||
|  | <svg | ||||||
|  |    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||||
|  |    xmlns:cc="http://creativecommons.org/ns#" | ||||||
|  |    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||||
|  |    xmlns:svg="http://www.w3.org/2000/svg" | ||||||
|  |    xmlns="http://www.w3.org/2000/svg" | ||||||
|  |    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||||
|  |    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||||
|  |    width="30mm" | ||||||
|  |    height="30mm" | ||||||
|  |    viewBox="0 0 30 30" | ||||||
|  |    version="1.1" | ||||||
|  |    id="svg5291" | ||||||
|  |    inkscape:version="0.92.4 (5da689c313, 2019-01-14)" | ||||||
|  |    sodipodi:docname="find-next.svg"> | ||||||
|  |   <defs | ||||||
|  |      id="defs5285"> | ||||||
|  |     <inkscape:perspective | ||||||
|  |        sodipodi:type="inkscape:persp3d" | ||||||
|  |        inkscape:vp_x="0 : 15 : 1" | ||||||
|  |        inkscape:vp_y="0 : 1000 : 0" | ||||||
|  |        inkscape:vp_z="30 : 15 : 1" | ||||||
|  |        inkscape:persp3d-origin="15 : 10 : 1" | ||||||
|  |        id="perspective5921" /> | ||||||
|  |   </defs> | ||||||
|  |   <sodipodi:namedview | ||||||
|  |      id="base" | ||||||
|  |      pagecolor="#ffffff" | ||||||
|  |      bordercolor="#666666" | ||||||
|  |      borderopacity="1.0" | ||||||
|  |      inkscape:pageopacity="0.0" | ||||||
|  |      inkscape:pageshadow="2" | ||||||
|  |      inkscape:zoom="7.9999996" | ||||||
|  |      inkscape:cx="55.758238" | ||||||
|  |      inkscape:cy="75.073314" | ||||||
|  |      inkscape:document-units="mm" | ||||||
|  |      inkscape:current-layer="layer1" | ||||||
|  |      showgrid="false" | ||||||
|  |      inkscape:window-width="3840" | ||||||
|  |      inkscape:window-height="2035" | ||||||
|  |      inkscape:window-x="-13" | ||||||
|  |      inkscape:window-y="-13" | ||||||
|  |      inkscape:window-maximized="1" /> | ||||||
|  |   <metadata | ||||||
|  |      id="metadata5288"> | ||||||
|  |     <rdf:RDF> | ||||||
|  |       <cc:Work | ||||||
|  |          rdf:about=""> | ||||||
|  |         <dc:format>image/svg+xml</dc:format> | ||||||
|  |         <dc:type | ||||||
|  |            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||||
|  |         <dc:title /> | ||||||
|  |         <dc:creator> | ||||||
|  |           <cc:Agent> | ||||||
|  |             <dc:title>Jakub Melka</dc:title> | ||||||
|  |           </cc:Agent> | ||||||
|  |         </dc:creator> | ||||||
|  |         <cc:license | ||||||
|  |            rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" /> | ||||||
|  |       </cc:Work> | ||||||
|  |       <cc:License | ||||||
|  |          rdf:about="http://creativecommons.org/licenses/by-sa/4.0/"> | ||||||
|  |         <cc:permits | ||||||
|  |            rdf:resource="http://creativecommons.org/ns#Reproduction" /> | ||||||
|  |         <cc:permits | ||||||
|  |            rdf:resource="http://creativecommons.org/ns#Distribution" /> | ||||||
|  |         <cc:requires | ||||||
|  |            rdf:resource="http://creativecommons.org/ns#Notice" /> | ||||||
|  |         <cc:requires | ||||||
|  |            rdf:resource="http://creativecommons.org/ns#Attribution" /> | ||||||
|  |         <cc:permits | ||||||
|  |            rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /> | ||||||
|  |         <cc:requires | ||||||
|  |            rdf:resource="http://creativecommons.org/ns#ShareAlike" /> | ||||||
|  |       </cc:License> | ||||||
|  |     </rdf:RDF> | ||||||
|  |   </metadata> | ||||||
|  |   <g | ||||||
|  |      inkscape:label="Vrstva 1" | ||||||
|  |      inkscape:groupmode="layer" | ||||||
|  |      id="layer1" | ||||||
|  |      transform="translate(0,-267)"> | ||||||
|  |     <flowRoot | ||||||
|  |        xml:space="preserve" | ||||||
|  |        id="flowRoot5913" | ||||||
|  |        style="fill:black;fill-opacity:1;stroke:none;font-family:sans-serif;font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;letter-spacing:0px;word-spacing:0px"><flowRegion | ||||||
|  |          id="flowRegion5915"><rect | ||||||
|  |            id="rect5917" | ||||||
|  |            width="129.22377" | ||||||
|  |            height="91.747108" | ||||||
|  |            x="-13.788582" | ||||||
|  |            y="-33.515606" /></flowRegion><flowPara | ||||||
|  |          id="flowPara5919" /></flowRoot>    <g | ||||||
|  |        id="g849" | ||||||
|  |        transform="translate(-1.0583333,1.5875)"> | ||||||
|  |       <ellipse | ||||||
|  |          ry="4.8121095" | ||||||
|  |          rx="4.8741207" | ||||||
|  |          cy="275.09717" | ||||||
|  |          cx="12.618022" | ||||||
|  |          id="path5985" | ||||||
|  |          style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.75;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> | ||||||
|  |       <path | ||||||
|  |          inkscape:connector-curvature="0" | ||||||
|  |          id="path5987" | ||||||
|  |          d="m 16.10308,278.8923 4.861718,5.45703" | ||||||
|  |          style="fill:none;stroke:#000000;stroke-width:0.75;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> | ||||||
|  |     </g> | ||||||
|  |     <text | ||||||
|  |        xml:space="preserve" | ||||||
|  |        style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif Italic';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332" | ||||||
|  |        x="3.0603709" | ||||||
|  |        y="293.01346" | ||||||
|  |        id="text845"><tspan | ||||||
|  |          sodipodi:role="line" | ||||||
|  |          id="tspan843" | ||||||
|  |          x="3.0603709" | ||||||
|  |          y="293.01346" | ||||||
|  |          style="stroke-width:0.26458332">abc</tspan></text> | ||||||
|  |     <path | ||||||
|  |        inkscape:connector-curvature="0" | ||||||
|  |        id="path1452" | ||||||
|  |        style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.58333302px;line-height:1;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332" | ||||||
|  |        d="m 20.889681,277.28864 v -7.4104 l 7.410401,3.65352 v 0.10335 z m 5.648234,-3.7052 -4.80074,-2.36679 v 4.73357 z" /> | ||||||
|  |   </g> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 4.9 KiB | 
							
								
								
									
										129
									
								
								PdfForQtViewer/resources/find-previous.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								PdfForQtViewer/resources/find-previous.svg
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,129 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||||
|  | <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||||
|  |  | ||||||
|  | <svg | ||||||
|  |    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||||
|  |    xmlns:cc="http://creativecommons.org/ns#" | ||||||
|  |    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||||
|  |    xmlns:svg="http://www.w3.org/2000/svg" | ||||||
|  |    xmlns="http://www.w3.org/2000/svg" | ||||||
|  |    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||||
|  |    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||||
|  |    width="30mm" | ||||||
|  |    height="30mm" | ||||||
|  |    viewBox="0 0 30 30" | ||||||
|  |    version="1.1" | ||||||
|  |    id="svg5291" | ||||||
|  |    inkscape:version="0.92.4 (5da689c313, 2019-01-14)" | ||||||
|  |    sodipodi:docname="find-previous.svg"> | ||||||
|  |   <defs | ||||||
|  |      id="defs5285"> | ||||||
|  |     <inkscape:perspective | ||||||
|  |        sodipodi:type="inkscape:persp3d" | ||||||
|  |        inkscape:vp_x="0 : 15 : 1" | ||||||
|  |        inkscape:vp_y="0 : 1000 : 0" | ||||||
|  |        inkscape:vp_z="30 : 15 : 1" | ||||||
|  |        inkscape:persp3d-origin="15 : 10 : 1" | ||||||
|  |        id="perspective5921" /> | ||||||
|  |   </defs> | ||||||
|  |   <sodipodi:namedview | ||||||
|  |      id="base" | ||||||
|  |      pagecolor="#ffffff" | ||||||
|  |      bordercolor="#666666" | ||||||
|  |      borderopacity="1.0" | ||||||
|  |      inkscape:pageopacity="0.0" | ||||||
|  |      inkscape:pageshadow="2" | ||||||
|  |      inkscape:zoom="7.9999996" | ||||||
|  |      inkscape:cx="82.945743" | ||||||
|  |      inkscape:cy="75.073314" | ||||||
|  |      inkscape:document-units="mm" | ||||||
|  |      inkscape:current-layer="layer1" | ||||||
|  |      showgrid="false" | ||||||
|  |      inkscape:window-width="3840" | ||||||
|  |      inkscape:window-height="2035" | ||||||
|  |      inkscape:window-x="-13" | ||||||
|  |      inkscape:window-y="-13" | ||||||
|  |      inkscape:window-maximized="1" /> | ||||||
|  |   <metadata | ||||||
|  |      id="metadata5288"> | ||||||
|  |     <rdf:RDF> | ||||||
|  |       <cc:Work | ||||||
|  |          rdf:about=""> | ||||||
|  |         <dc:format>image/svg+xml</dc:format> | ||||||
|  |         <dc:type | ||||||
|  |            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||||
|  |         <dc:title></dc:title> | ||||||
|  |         <dc:creator> | ||||||
|  |           <cc:Agent> | ||||||
|  |             <dc:title>Jakub Melka</dc:title> | ||||||
|  |           </cc:Agent> | ||||||
|  |         </dc:creator> | ||||||
|  |         <cc:license | ||||||
|  |            rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" /> | ||||||
|  |       </cc:Work> | ||||||
|  |       <cc:License | ||||||
|  |          rdf:about="http://creativecommons.org/licenses/by-sa/4.0/"> | ||||||
|  |         <cc:permits | ||||||
|  |            rdf:resource="http://creativecommons.org/ns#Reproduction" /> | ||||||
|  |         <cc:permits | ||||||
|  |            rdf:resource="http://creativecommons.org/ns#Distribution" /> | ||||||
|  |         <cc:requires | ||||||
|  |            rdf:resource="http://creativecommons.org/ns#Notice" /> | ||||||
|  |         <cc:requires | ||||||
|  |            rdf:resource="http://creativecommons.org/ns#Attribution" /> | ||||||
|  |         <cc:permits | ||||||
|  |            rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /> | ||||||
|  |         <cc:requires | ||||||
|  |            rdf:resource="http://creativecommons.org/ns#ShareAlike" /> | ||||||
|  |       </cc:License> | ||||||
|  |     </rdf:RDF> | ||||||
|  |   </metadata> | ||||||
|  |   <g | ||||||
|  |      inkscape:label="Vrstva 1" | ||||||
|  |      inkscape:groupmode="layer" | ||||||
|  |      id="layer1" | ||||||
|  |      transform="translate(0,-267)"> | ||||||
|  |     <flowRoot | ||||||
|  |        xml:space="preserve" | ||||||
|  |        id="flowRoot5913" | ||||||
|  |        style="fill:black;fill-opacity:1;stroke:none;font-family:sans-serif;font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;letter-spacing:0px;word-spacing:0px"><flowRegion | ||||||
|  |          id="flowRegion5915"><rect | ||||||
|  |            id="rect5917" | ||||||
|  |            width="129.22377" | ||||||
|  |            height="91.747108" | ||||||
|  |            x="-13.788582" | ||||||
|  |            y="-33.515606" /></flowRegion><flowPara | ||||||
|  |          id="flowPara5919" /></flowRoot>    <g | ||||||
|  |        id="g849" | ||||||
|  |        transform="translate(-1.0583333,1.5875)"> | ||||||
|  |       <ellipse | ||||||
|  |          ry="4.8121095" | ||||||
|  |          rx="4.8741207" | ||||||
|  |          cy="275.09717" | ||||||
|  |          cx="12.618022" | ||||||
|  |          id="path5985" | ||||||
|  |          style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.75;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> | ||||||
|  |       <path | ||||||
|  |          inkscape:connector-curvature="0" | ||||||
|  |          id="path5987" | ||||||
|  |          d="m 16.10308,278.8923 4.861718,5.45703" | ||||||
|  |          style="fill:none;stroke:#000000;stroke-width:0.75;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> | ||||||
|  |     </g> | ||||||
|  |     <text | ||||||
|  |        xml:space="preserve" | ||||||
|  |        style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif Italic';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332" | ||||||
|  |        x="3.0603709" | ||||||
|  |        y="293.01346" | ||||||
|  |        id="text845"><tspan | ||||||
|  |          sodipodi:role="line" | ||||||
|  |          id="tspan843" | ||||||
|  |          x="3.0603709" | ||||||
|  |          y="293.01346" | ||||||
|  |          style="stroke-width:0.26458332">abc</tspan></text> | ||||||
|  |     <path | ||||||
|  |        inkscape:connector-curvature="0" | ||||||
|  |        id="path863" | ||||||
|  |        style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332" | ||||||
|  |        d="m 20.546549,273.40342 v -0.10335 l 7.410401,-3.65352 v 7.4104 z m 6.562907,2.31511 v -4.73356 l -4.80074,2.36678 z" /> | ||||||
|  |   </g> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 4.9 KiB | 
							
								
								
									
										124
									
								
								PdfForQtViewer/resources/find.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								PdfForQtViewer/resources/find.svg
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,124 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||||
|  | <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||||
|  |  | ||||||
|  | <svg | ||||||
|  |    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||||
|  |    xmlns:cc="http://creativecommons.org/ns#" | ||||||
|  |    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||||
|  |    xmlns:svg="http://www.w3.org/2000/svg" | ||||||
|  |    xmlns="http://www.w3.org/2000/svg" | ||||||
|  |    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||||
|  |    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||||
|  |    width="30mm" | ||||||
|  |    height="30mm" | ||||||
|  |    viewBox="0 0 30 30" | ||||||
|  |    version="1.1" | ||||||
|  |    id="svg5291" | ||||||
|  |    inkscape:version="0.92.4 (5da689c313, 2019-01-14)" | ||||||
|  |    sodipodi:docname="find.svg"> | ||||||
|  |   <defs | ||||||
|  |      id="defs5285"> | ||||||
|  |     <inkscape:perspective | ||||||
|  |        sodipodi:type="inkscape:persp3d" | ||||||
|  |        inkscape:vp_x="0 : 15 : 1" | ||||||
|  |        inkscape:vp_y="0 : 1000 : 0" | ||||||
|  |        inkscape:vp_z="30 : 15 : 1" | ||||||
|  |        inkscape:persp3d-origin="15 : 10 : 1" | ||||||
|  |        id="perspective5921" /> | ||||||
|  |   </defs> | ||||||
|  |   <sodipodi:namedview | ||||||
|  |      id="base" | ||||||
|  |      pagecolor="#ffffff" | ||||||
|  |      bordercolor="#666666" | ||||||
|  |      borderopacity="1.0" | ||||||
|  |      inkscape:pageopacity="0.0" | ||||||
|  |      inkscape:pageshadow="2" | ||||||
|  |      inkscape:zoom="11.313708" | ||||||
|  |      inkscape:cx="92.712655" | ||||||
|  |      inkscape:cy="75.073314" | ||||||
|  |      inkscape:document-units="mm" | ||||||
|  |      inkscape:current-layer="layer1" | ||||||
|  |      showgrid="false" | ||||||
|  |      inkscape:window-width="3840" | ||||||
|  |      inkscape:window-height="2035" | ||||||
|  |      inkscape:window-x="-13" | ||||||
|  |      inkscape:window-y="-13" | ||||||
|  |      inkscape:window-maximized="1" /> | ||||||
|  |   <metadata | ||||||
|  |      id="metadata5288"> | ||||||
|  |     <rdf:RDF> | ||||||
|  |       <cc:Work | ||||||
|  |          rdf:about=""> | ||||||
|  |         <dc:format>image/svg+xml</dc:format> | ||||||
|  |         <dc:type | ||||||
|  |            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||||
|  |         <dc:title></dc:title> | ||||||
|  |         <dc:creator> | ||||||
|  |           <cc:Agent> | ||||||
|  |             <dc:title>Jakub Melka</dc:title> | ||||||
|  |           </cc:Agent> | ||||||
|  |         </dc:creator> | ||||||
|  |         <cc:license | ||||||
|  |            rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" /> | ||||||
|  |       </cc:Work> | ||||||
|  |       <cc:License | ||||||
|  |          rdf:about="http://creativecommons.org/licenses/by-sa/4.0/"> | ||||||
|  |         <cc:permits | ||||||
|  |            rdf:resource="http://creativecommons.org/ns#Reproduction" /> | ||||||
|  |         <cc:permits | ||||||
|  |            rdf:resource="http://creativecommons.org/ns#Distribution" /> | ||||||
|  |         <cc:requires | ||||||
|  |            rdf:resource="http://creativecommons.org/ns#Notice" /> | ||||||
|  |         <cc:requires | ||||||
|  |            rdf:resource="http://creativecommons.org/ns#Attribution" /> | ||||||
|  |         <cc:permits | ||||||
|  |            rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /> | ||||||
|  |         <cc:requires | ||||||
|  |            rdf:resource="http://creativecommons.org/ns#ShareAlike" /> | ||||||
|  |       </cc:License> | ||||||
|  |     </rdf:RDF> | ||||||
|  |   </metadata> | ||||||
|  |   <g | ||||||
|  |      inkscape:label="Vrstva 1" | ||||||
|  |      inkscape:groupmode="layer" | ||||||
|  |      id="layer1" | ||||||
|  |      transform="translate(0,-267)"> | ||||||
|  |     <flowRoot | ||||||
|  |        xml:space="preserve" | ||||||
|  |        id="flowRoot5913" | ||||||
|  |        style="fill:black;fill-opacity:1;stroke:none;font-family:sans-serif;font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;letter-spacing:0px;word-spacing:0px"><flowRegion | ||||||
|  |          id="flowRegion5915"><rect | ||||||
|  |            id="rect5917" | ||||||
|  |            width="129.22377" | ||||||
|  |            height="91.747108" | ||||||
|  |            x="-13.788582" | ||||||
|  |            y="-33.515606" /></flowRegion><flowPara | ||||||
|  |          id="flowPara5919" /></flowRoot>    <g | ||||||
|  |        id="g849" | ||||||
|  |        transform="translate(-1.0583333,1.5875)"> | ||||||
|  |       <ellipse | ||||||
|  |          ry="4.8121095" | ||||||
|  |          rx="4.8741207" | ||||||
|  |          cy="275.09717" | ||||||
|  |          cx="12.618022" | ||||||
|  |          id="path5985" | ||||||
|  |          style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.75;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> | ||||||
|  |       <path | ||||||
|  |          inkscape:connector-curvature="0" | ||||||
|  |          id="path5987" | ||||||
|  |          d="m 16.10308,278.8923 4.861718,5.45703" | ||||||
|  |          style="fill:none;stroke:#000000;stroke-width:0.75;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> | ||||||
|  |     </g> | ||||||
|  |     <text | ||||||
|  |        xml:space="preserve" | ||||||
|  |        style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif Italic';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332" | ||||||
|  |        x="3.0603709" | ||||||
|  |        y="293.01346" | ||||||
|  |        id="text845"><tspan | ||||||
|  |          sodipodi:role="line" | ||||||
|  |          id="tspan843" | ||||||
|  |          x="3.0603709" | ||||||
|  |          y="293.01346" | ||||||
|  |          style="stroke-width:0.26458332">abc</tspan></text> | ||||||
|  |   </g> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 4.4 KiB | 
		Reference in New Issue
	
	Block a user