Issue #159: Renaming applications

This commit is contained in:
Jakub Melka
2024-03-16 17:02:44 +01:00
parent a70f45c8a9
commit 28807b4f12
450 changed files with 1440 additions and 1416 deletions

View File

@@ -1,4 +1,4 @@
# Copyright (C) 2022-2023 Jakub Melka
# Copyright (C) 2022-2024 Jakub Melka
#
# This file is part of PDF4QT.
#
@@ -15,85 +15,19 @@
# You should have received a copy of the GNU Lesser General Public License
# along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
add_library(Pdf4QtViewer SHARED
pdfaboutdialog.cpp
pdfaboutdialog.h
pdfadvancedfindwidget.cpp
pdfadvancedfindwidget.h
pdfdocumentpropertiesdialog.cpp
pdfdocumentpropertiesdialog.h
pdfencryptionsettingsdialog.cpp
pdfencryptionsettingsdialog.h
pdfencryptionstrengthhintwidget.cpp
pdfencryptionstrengthhintwidget.h
pdfoptimizedocumentdialog.cpp
pdfoptimizedocumentdialog.h
pdfprogramcontroller.cpp
pdfprogramcontroller.h
pdfrecentfilemanager.cpp
pdfrecentfilemanager.h
pdfrendertoimagesdialog.cpp
pdfrendertoimagesdialog.h
pdfsendmail.cpp
pdfsendmail.h
pdfsidebarwidget.cpp
pdfsidebarwidget.h
pdftexttospeech.cpp
pdftexttospeech.h
pdfundoredomanager.cpp
pdfundoredomanager.h
pdfviewermainwindow.cpp
pdfviewermainwindow.h
pdfviewermainwindowlite.cpp
pdfviewermainwindowlite.h
pdfviewersettings.cpp
pdfviewersettings.h
pdfviewersettingsdialog.cpp
pdfviewersettingsdialog.h
pdfwintaskbarprogress.cpp
pdfwintaskbarprogress.h
pdfaboutdialog.ui
pdfadvancedfindwidget.ui
pdfdocumentpropertiesdialog.ui
pdfencryptionsettingsdialog.ui
pdfoptimizedocumentdialog.ui
pdfrendertoimagesdialog.ui
pdfsidebarwidget.ui
pdfviewermainwindow.ui
pdfviewermainwindowlite.ui
pdfviewersettingsdialog.ui
pdfsanitizedocumentdialog.ui
pdfsanitizedocumentdialog.cpp
pdfsanitizedocumentdialog.h
pdfcreatebitonaldocumentdialog.ui
pdfcreatebitonaldocumentdialog.cpp
pdfcreatebitonaldocumentdialog.h
pdf4qtviewer.qrc
pdfbookmarkmanager.h
pdfbookmarkmanager.cpp
pdfbookmarkui.h
pdfbookmarkui.cpp
pdfactioncombobox.h
pdfactioncombobox.cpp
add_executable(Pdf4QtViewer
main.cpp
icon.rc
app.qrc
)
add_compile_definitions(QT_INSTALL_DIRECTORY="${QT6_INSTALL_PREFIX}")
include(GenerateExportHeader)
GENERATE_EXPORT_HEADER(Pdf4QtViewer
EXPORT_MACRO_NAME
PDF4QTVIEWERLIBSHARED_EXPORT
EXPORT_FILE_NAME "${CMAKE_BINARY_DIR}/${INSTALL_INCLUDEDIR}/pdf4qtviewer_export.h")
target_link_libraries(Pdf4QtViewer PRIVATE Pdf4QtLibCore Pdf4QtLibWidgets Qt6::Core Qt6::Gui Qt6::Widgets Qt6::PrintSupport Qt6::TextToSpeech Qt6::Xml Qt6::Svg)
target_include_directories(Pdf4QtViewer INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(Pdf4QtViewer PUBLIC ${CMAKE_BINARY_DIR}/${INSTALL_INCLUDEDIR})
target_link_libraries(Pdf4QtViewer PRIVATE Pdf4QtLibCore Pdf4QtLibWidgets Pdf4QtLibGui Qt6::Core Qt6::Gui Qt6::Widgets)
set_target_properties(Pdf4QtViewer PROPERTIES
VERSION ${PDF4QT_VERSION}
SOVERSION ${PDF4QT_VERSION}
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${PDF4QT_INSTALL_LIB_DIR}
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${PDF4QT_INSTALL_BIN_DIR})
WIN32_EXECUTABLE ON
MACOSX_BUNDLE ON
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${PDF4QT_INSTALL_LIB_DIR}
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${PDF4QT_INSTALL_BIN_DIR}
)
install(TARGETS Pdf4QtViewer RUNTIME DESTINATION ${PDF4QT_INSTALL_BIN_DIR} LIBRARY DESTINATION ${PDF4QT_INSTALL_LIB_DIR})

BIN
Pdf4QtViewer/app-icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

29
Pdf4QtViewer/app-icon.svg Normal file
View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="256px" height="256px" viewBox="0 0 256 256" enable-background="new 0 0 256 256" xml:space="preserve">
<g>
<g>
<polygon fill="#C53620" points="146.424,82.454 146.424,0.009 41.555,0.009 41.555,132.476 41.555,134.875 41.555,136.483
41.555,149.734 41.555,164.561 41.555,210.879 41.555,222.338 41.555,232.549 41.555,238.801 41.555,249.24 41.555,255.99
214.445,255.99 214.445,82.454 "/>
<polygon fill="#6CBD45" points="155.248,0.053 155.248,73.619 214.445,73.619 "/>
</g>
<g>
<path fill="#FFFFFF" d="M192.199,165.65c-0.854-1.037-1.693-2.096-2.588-3.148l-5.592,6.719l-1.477,1.682
c-10.063,11.535-21.186,21.324-35.246,27.479c-13.006,5.668-25.996,5.518-39.008-0.277c-11.053-4.9-20.348-12.098-28.746-20.637
c-2.506-2.588-4.963-5.318-7.471-8.037c0.834-0.967,1.535-1.893,2.307-2.73c8.604-9.725,18.113-18.189,29.643-24.201
c8.184-4.269,16.779-6.838,26.145-6.363c6.088,0.289,11.889,1.895,17.482,4.277c8.947,3.975,16.779,9.5,23.982,15.996l5.67-6.641
c-8.67-7.823-18.256-14.473-29.375-18.588c-7.477-2.868-15.303-4.278-23.346-3.726c-9.861,0.713-18.945,3.992-27.479,8.89
c-12.93,7.465-23.777,17.471-33.006,29.164c-0.771,0.896-1.258,2.021-1.887,2.992v1.529c0.555,0.99,1.049,2.041,1.748,2.873
c4.26,5.535,8.943,10.563,14.049,15.244c8.957,8.115,18.738,14.963,30.066,19.299c7.551,2.875,15.385,4.191,23.42,3.631
c9.857-0.629,18.957-3.906,27.484-8.865c12.863-7.357,23.563-17.275,32.785-28.805c0.844-0.982,1.402-2.248,2.029-3.365v-1.523
C193.318,167.615,192.818,166.576,192.199,165.65z"/>
<path fill="#FFFFFF" d="M154.039,169.348c-0.027,14.379-11.768,26.051-26.102,25.965c-14.373-0.1-25.922-11.721-25.898-26.041
c0.039-14.396,11.748-26.074,26.098-25.963C142.514,143.414,154.072,155.018,154.039,169.348z M145.383,169.348
c0.027-9.547-7.68-17.303-17.283-17.379c-9.529-0.105-17.438,7.814-17.391,17.379c0.053,9.566,7.805,17.314,17.338,17.314
C137.584,186.662,145.344,178.914,145.383,169.348z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

5
Pdf4QtViewer/app.qrc Normal file
View File

@@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/">
<file>app-icon.svg</file>
</qresource>
</RCC>

1
Pdf4QtViewer/icon.rc Normal file
View File

@@ -0,0 +1 @@
IDI_ICON1 ICON DISCARDABLE "app-icon.ico"

View File

@@ -1,37 +1,35 @@
// Copyright (C) 2019-2020 Jakub Melka
// Copyright (C) 2021-2024 Jakub Melka
//
// This file is part of Pdf4Qt.
// This file is part of PDF4QT.
//
// Pdf4Qt is free software: you can redistribute it and/or modify
// PDF4QT 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.
// with the written consent of the copyright owner, any later version.
//
// Pdf4Qt is distributed in the hope that it will be useful,
// PDF4QT 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 Pdf4Qt. If not, see <https://www.gnu.org/licenses/>.
// along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#include "pdfviewermainwindow.h"
#include "pdfconstants.h"
#include <QResource>
#include <QApplication>
#include <QCommandLineParser>
int main(int argc, char *argv[])
{
QApplication::setAttribute(Qt::AA_CompressHighFrequencyEvents, true);
QApplication::setAttribute(Qt::AA_DisableHighDpiScaling, true);
QApplication::setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity, true);
QApplication application(argc, argv);
QCoreApplication::setOrganizationName("MelkaJ");
QCoreApplication::setApplicationName("PDF4QT Viewer Profi");
QCoreApplication::setApplicationVersion("1.0.0");
QApplication::setApplicationDisplayName(QApplication::translate("Application", "PDF4QT Viewer Profi"));
QCoreApplication::setApplicationName("PDF4QT Viewer");
QCoreApplication::setApplicationVersion(pdf::PDF_LIBRARY_VERSION);
QApplication::setApplicationDisplayName(QApplication::translate("Application", "PDF4QT Viewer"));
QCommandLineParser parser;
parser.setApplicationDescription(QCoreApplication::applicationName());
parser.addHelpOption();
@@ -39,6 +37,9 @@ int main(int argc, char *argv[])
parser.addPositionalArgument("file", "The PDF file to open.");
parser.process(application);
QIcon appIcon(":/app-icon.svg");
QApplication::setWindowIcon(appIcon);
pdfviewer::PDFViewerMainWindow mainWindow;
mainWindow.show();

View File

@@ -1,115 +0,0 @@
<RCC>
<qresource prefix="/">
<file>resources/engine.svg</file>
<file>resources/rendering.svg</file>
<file>resources/shading.svg</file>
<file>resources/next.svg</file>
<file>resources/next-end.svg</file>
<file>resources/next-page.svg</file>
<file>resources/open.svg</file>
<file>resources/previous.svg</file>
<file>resources/previous-page.svg</file>
<file>resources/previous-start.svg</file>
<file>resources/quit.svg</file>
<file>resources/rendering-errors.svg</file>
<file>resources/settings.svg</file>
<file>resources/zoom-in.svg</file>
<file>resources/zoom-out.svg</file>
<file>resources/security.svg</file>
<file>resources/zoom-fit.svg</file>
<file>resources/zoom-fit-horizontal.svg</file>
<file>resources/zoom-fit-vertical.svg</file>
<file>resources/synchronize.svg</file>
<file>resources/cache.svg</file>
<file>resources/shortcuts.svg</file>
<file>resources/info.svg</file>
<file>resources/send-mail.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>
<file>resources/select-text.svg</file>
<file>resources/ui.svg</file>
<file>resources/rotate-left.svg</file>
<file>resources/rotate-right.svg</file>
<file>resources/print.svg</file>
<file>resources/speech.svg</file>
<file>resources/pause.svg</file>
<file>resources/play.svg</file>
<file>resources/stop.svg</file>
<file>resources/magnifier.svg</file>
<file>resources/screenshot-tool.svg</file>
<file>resources/extract-image.svg</file>
<file>resources/form-settings.svg</file>
<file>resources/undo.svg</file>
<file>resources/redo.svg</file>
<file>resources/result-error.svg</file>
<file>resources/result-information.svg</file>
<file>resources/result-ok.svg</file>
<file>resources/result-warning.svg</file>
<file>resources/signature.svg</file>
<file>resources/plugins.svg</file>
<file>resources/hyperlink.svg</file>
<file>resources/highlight.svg</file>
<file>resources/squiggly.svg</file>
<file>resources/strikeout.svg</file>
<file>resources/underline.svg</file>
<file>resources/annot-ellipse.svg</file>
<file>resources/annot-freehand-curve.svg</file>
<file>resources/annot-inline-text.svg</file>
<file>resources/annot-polygon.svg</file>
<file>resources/annot-polyline.svg</file>
<file>resources/annot-sticky-note.svg</file>
<file>resources/annot-straight-line.svg</file>
<file>resources/app-icon.svg</file>
<file>resources/close.svg</file>
<file>resources/copy-text.svg</file>
<file>resources/deselect-text.svg</file>
<file>resources/encryption.svg</file>
<file>resources/invert-colors.svg</file>
<file>resources/optimize.svg</file>
<file>resources/save.svg</file>
<file>resources/save-as.svg</file>
<file>resources/select-all-text.svg</file>
<file>resources/pce-align-bottom.svg</file>
<file>resources/pce-align-h-center.svg</file>
<file>resources/pce-align-left.svg</file>
<file>resources/pce-align-right.svg</file>
<file>resources/pce-align-top.svg</file>
<file>resources/pce-align-v-center.svg</file>
<file>resources/pce-center-h.svg</file>
<file>resources/pce-center-v.svg</file>
<file>resources/pce-center-vh.svg</file>
<file>resources/pce-layout-form.svg</file>
<file>resources/pce-layout-grid.svg</file>
<file>resources/pce-layout-h.svg</file>
<file>resources/pce-layout-v.svg</file>
<file>resources/pce-same-height.svg</file>
<file>resources/pce-same-size.svg</file>
<file>resources/pce-same-width.svg</file>
<file>resources/certificate-manager.svg</file>
<file>resources/select-table.svg</file>
<file>resources/annot-rectangle.svg</file>
<file>resources/book.svg</file>
<file>resources/wallet.svg</file>
<file>resources/web.svg</file>
<file>resources/user.svg</file>
<file>resources/create-bitonal-document.svg</file>
<file>resources/sanitize-document.svg</file>
<file>resources/sidebar-attachment.svg</file>
<file>resources/sidebar-outline.svg</file>
<file>resources/sidebar-signature.svg</file>
<file>resources/sidebar-speech.svg</file>
<file>resources/sidebar-thumbnails.svg</file>
<file>resources/sidebar-visibility.svg</file>
<file>resources/sidebar-annotations.svg</file>
<file>resources/outline.svg</file>
<file>resources/sidebar-favourites.svg</file>
<file>resources/bookmark.svg</file>
<file>resources/bookmark-next.svg</file>
<file>resources/bookmark-previous.svg</file>
<file>resources/page.svg</file>
<file>resources/bubble.svg</file>
</qresource>
</RCC>

View File

@@ -1,65 +0,0 @@
// Copyright (C) 2019-2022 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#include "pdfaboutdialog.h"
#include "ui_pdfaboutdialog.h"
#include "pdfutils.h"
#include "pdfwidgetutils.h"
#include "pdfdbgheap.h"
namespace pdfviewer
{
PDFAboutDialog::PDFAboutDialog(QWidget* parent) :
QDialog(parent),
ui(new Ui::PDFAboutDialog)
{
ui->setupUi(this);
QString html = ui->copyrightLabel->text();
html.replace("PdfForQtViewer", QString("%1 %2").arg(QApplication::applicationDisplayName(), QApplication::applicationVersion()));
ui->copyrightLabel->setText(html);
std::vector<pdf::PDFDependentLibraryInfo> infos = pdf::PDFDependentLibraryInfo::getLibraryInfo();
ui->tableWidget->setColumnCount(4);
ui->tableWidget->setRowCount(static_cast<int>(infos.size()));
ui->tableWidget->setHorizontalHeaderLabels(QStringList() << tr("Library") << tr("Version") << tr("License") << tr("URL"));
ui->tableWidget->setEditTriggers(QTableWidget::NoEditTriggers);
ui->tableWidget->setSelectionMode(QTableView::SingleSelection);
ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
for (int i = 0; i < int(infos.size()); ++i)
{
const pdf::PDFDependentLibraryInfo& info = infos[i];
ui->tableWidget->setItem(i, 0, new QTableWidgetItem(info.library));
ui->tableWidget->setItem(i, 1, new QTableWidgetItem(info.version));
ui->tableWidget->setItem(i, 2, new QTableWidgetItem(info.license));
ui->tableWidget->setItem(i, 3, new QTableWidgetItem(info.url));
}
pdf::PDFWidgetUtils::scaleWidget(this, QSize(750, 600));
pdf::PDFWidgetUtils::style(this);
}
PDFAboutDialog::~PDFAboutDialog()
{
delete ui;
}
} // namespace viewer

View File

@@ -1,45 +0,0 @@
// Copyright (C) 2019-2021 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#ifndef PDFABOUTDIALOG_H
#define PDFABOUTDIALOG_H
#include <QDialog>
namespace Ui
{
class PDFAboutDialog;
}
namespace pdfviewer
{
class PDFAboutDialog : public QDialog
{
Q_OBJECT
public:
explicit PDFAboutDialog(QWidget* parent = nullptr);
virtual ~PDFAboutDialog() override;
private:
Ui::PDFAboutDialog* ui;
};
} // namespace pdfviewer
#endif // PDFABOUTDIALOG_H

View File

@@ -1,269 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PDFAboutDialog</class>
<widget class="QDialog" name="PDFAboutDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>900</width>
<height>600</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>900</width>
<height>600</height>
</size>
</property>
<property name="windowTitle">
<string>About</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="copyrightLabel">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;PdfForQtViewer&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Copyright 2018-2023 Jakub Melka. All rights reserved.&lt;/p&gt;&lt;p&gt;THE SOFTWARE IS PROVIDED &amp;quot;AS IS&amp;quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QTextEdit" name="textEdit">
<property name="readOnly">
<bool>true</bool>
</property>
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:7.875pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; GNU LESSER GENERAL PUBLIC LICENSE&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Version 3, 29 June 2007&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Copyright (C) 2007 Free Software Foundation, Inc. &amp;lt;https://fsf.org/&amp;gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Everyone is permitted to copy and distribute verbatim copies&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; of this license document, but changing it is not allowed.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; This version of the GNU Lesser General Public License incorporates&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;the terms and conditions of version 3 of the GNU General Public&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;License, supplemented by the additional permissions listed below.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; 0. Additional Definitions.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; As used herein, &amp;quot;this License&amp;quot; refers to version 3 of the GNU Lesser&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;General Public License, and the &amp;quot;GNU GPL&amp;quot; refers to version 3 of the GNU&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;General Public License.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; &amp;quot;The Library&amp;quot; refers to a covered work governed by this License,&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;other than an Application or a Combined Work as defined below.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; An &amp;quot;Application&amp;quot; is any work that makes use of an interface provided&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;by the Library, but which is not otherwise based on the Library.&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Defining a subclass of a class defined by the Library is deemed a mode&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;of using an interface provided by the Library.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; A &amp;quot;Combined Work&amp;quot; is a work produced by combining or linking an&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Application with the Library. The particular version of the Library&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;with which the Combined Work was made is also called the &amp;quot;Linked&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Version&amp;quot;.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; The &amp;quot;Minimal Corresponding Source&amp;quot; for a Combined Work means the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Corresponding Source for the Combined Work, excluding any source code&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;for portions of the Combined Work that, considered in isolation, are&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;based on the Application, and not on the Linked Version.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; The &amp;quot;Corresponding Application Code&amp;quot; for a Combined Work means the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;object code and/or source code for the Application, including any data&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;and utility programs needed for reproducing the Combined Work from the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Application, but excluding the System Libraries of the Combined Work.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; 1. Exception to Section 3 of the GNU GPL.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; You may convey a covered work under sections 3 and 4 of this License&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;without being bound by section 3 of the GNU GPL.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; 2. Conveying Modified Versions.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; If you modify a copy of the Library, and, in your modifications, a&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;facility refers to a function or data to be supplied by an Application&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;that uses the facility (other than as an argument passed when the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;facility is invoked), then you may convey a copy of the modified&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;version:&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; a) under this License, provided that you make a good faith effort to&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; ensure that, in the event an Application does not supply the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; function or data, the facility still operates, and performs&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; whatever part of its purpose remains meaningful, or&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; b) under the GNU GPL, with none of the additional permissions of&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; this License applicable to that copy.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; 3. Object Code Incorporating Material from Library Header Files.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; The object code form of an Application may incorporate material from&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;a header file that is part of the Library. You may convey such object&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;code under terms of your choice, provided that, if the incorporated&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;material is not limited to numerical parameters, data structure&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;layouts and accessors, or small macros, inline functions and templates&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;(ten or fewer lines in length), you do both of the following:&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; a) Give prominent notice with each copy of the object code that the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Library is used in it and that the Library and its use are&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; covered by this License.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; b) Accompany the object code with a copy of the GNU GPL and this license&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; document.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; 4. Combined Works.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; You may convey a Combined Work under terms of your choice that,&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;taken together, effectively do not restrict modification of the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;portions of the Library contained in the Combined Work and reverse&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;engineering for debugging such modifications, if you also do each of&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;the following:&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; a) Give prominent notice with each copy of the Combined Work that&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; the Library is used in it and that the Library and its use are&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; covered by this License.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; b) Accompany the Combined Work with a copy of the GNU GPL and this license&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; document.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; c) For a Combined Work that displays copyright notices during&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; execution, include the copyright notice for the Library among&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; these notices, as well as a reference directing the user to the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; copies of the GNU GPL and this license document.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; d) Do one of the following:&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; 0) Convey the Minimal Corresponding Source under the terms of this&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; License, and the Corresponding Application Code in a form&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; suitable for, and under terms that permit, the user to&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; recombine or relink the Application with a modified version of&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; the Linked Version to produce a modified Combined Work, in the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; manner specified by section 6 of the GNU GPL for conveying&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Corresponding Source.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; 1) Use a suitable shared library mechanism for linking with the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Library. A suitable mechanism is one that (a) uses at run time&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; a copy of the Library already present on the user's computer&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; system, and (b) will operate properly with a modified version&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; of the Library that is interface-compatible with the Linked&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Version.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; e) Provide Installation Information, but only if you would otherwise&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; be required to provide such information under section 6 of the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; GNU GPL, and only to the extent that such information is&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; necessary to install and execute a modified version of the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Combined Work produced by recombining or relinking the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Application with a modified version of the Linked Version. (If&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; you use option 4d0, the Installation Information must accompany&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; the Minimal Corresponding Source and Corresponding Application&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Code. If you use option 4d1, you must provide the Installation&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Information in the manner specified by section 6 of the GNU GPL&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; for conveying Corresponding Source.)&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; 5. Combined Libraries.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; You may place library facilities that are a work based on the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Library side by side in a single library together with other library&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;facilities that are not Applications and are not covered by this&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;License, and convey such a combined library under terms of your&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;choice, if you do both of the following:&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; a) Accompany the combined library with a copy of the same work based&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; on the Library, uncombined with any other library facilities,&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; conveyed under the terms of this License.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; b) Give prominent notice with the combined library that part of it&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; is a work based on the Library, and explaining where to find the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; accompanying uncombined form of the same work.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; 6. Revised Versions of the GNU Lesser General Public License.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; The Free Software Foundation may publish revised and/or new versions&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;of the GNU Lesser General Public License from time to time. Such new&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;versions will be similar in spirit to the present version, but may&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;differ in detail to address new problems or concerns.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Each version is given a distinguishing version number. If the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Library as you received it specifies that a certain numbered version&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;of the GNU Lesser General Public License &amp;quot;or any later version&amp;quot;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;applies to it, you have the option of following the terms and&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;conditions either of that published version or of any later version&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;published by the Free Software Foundation. If the Library as you&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;received it does not specify a version number of the GNU Lesser&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;General Public License, you may choose any version of the GNU Lesser&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;General Public License ever published by the Free Software Foundation.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; If the Library as you received it specifies that a proxy can decide&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;whether future versions of the GNU Lesser General Public License shall&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;apply, that proxy's public statement of acceptance of any version is&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;permanent authorization for you to choose that version for the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Library.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="usedLibrariesLabel">
<property name="text">
<string>Used libraries</string>
</property>
</widget>
</item>
<item>
<widget class="QTableWidget" name="tableWidget"/>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>PDFAboutDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>PDFAboutDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -1,211 +0,0 @@
// Copyright (C) 2023 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#include "pdfactioncombobox.h"
#include "pdfwidgetutils.h"
#include <QLineEdit>
#include <QStandardItemModel>
#include <QSortFilterProxyModel>
#include <QCompleter>
#include <QAbstractItemView>
#include <QKeyEvent>
namespace pdfviewer
{
PDFActionComboBox::PDFActionComboBox(QWidget* parent) :
BaseClass(parent),
m_model(nullptr)
{
setPlaceholderText(tr("Find action..."));
setClearButtonEnabled(true);
setMinimumWidth(pdf::PDFWidgetUtils::scaleDPI_x(this, DEFAULT_WIDTH));
m_model = new QStandardItemModel(this);
QCompleter* completer = new QCompleter(m_model, this);
setFocusPolicy(Qt::StrongFocus);
setCompleter(completer);
completer->setCompletionMode(QCompleter::PopupCompletion);
completer->setCompletionColumn(0);
completer->setCompletionRole(Qt::DisplayRole);
completer->setFilterMode(Qt::MatchContains);
completer->setCaseSensitivity(Qt::CaseInsensitive);
completer->setModelSorting(QCompleter::CaseInsensitivelySortedModel);
completer->setWrapAround(false);
completer->setMaxVisibleItems(20);
connect(this, &QLineEdit::editingFinished, this, &PDFActionComboBox::performExecuteAction, Qt::QueuedConnection);
}
QSize PDFActionComboBox::sizeHint() const
{
QSize sizeHint = BaseClass::sizeHint();
sizeHint.setWidth(pdf::PDFWidgetUtils::scaleDPI_x(this, DEFAULT_WIDTH));
return sizeHint;
}
QSize PDFActionComboBox::minimumSizeHint() const
{
QSize sizeHint = BaseClass::minimumSizeHint();
sizeHint.setWidth(pdf::PDFWidgetUtils::scaleDPI_x(this, DEFAULT_WIDTH));
return sizeHint;
}
void PDFActionComboBox::addQuickFindAction(QAction* action)
{
if (std::find(m_actions.begin(), m_actions.end(), action) == m_actions.end())
{
m_actions.push_back(action);
connect(action, &QAction::changed, this, &PDFActionComboBox::onActionChanged);
updateAction(action);
}
}
bool PDFActionComboBox::event(QEvent* event)
{
if (event->type() == QEvent::ShortcutOverride)
{
QKeyEvent* keyEvent = dynamic_cast<QKeyEvent*>(event);
switch (keyEvent->key())
{
case Qt::Key_Down:
case Qt::Key_Up:
event->accept();
return true;
}
}
if (event->type() == QEvent::KeyPress)
{
QKeyEvent* keyEvent = dynamic_cast<QKeyEvent*>(event);
// Redirect up and down arrows to the completer
switch (keyEvent->key())
{
case Qt::Key_Down:
case Qt::Key_Up:
{
if (completer())
{
if (completer()->popup()->isVisible())
{
QCoreApplication::sendEvent(completer()->popup(), event);
}
else
{
completer()->complete();
}
}
return true;
}
case Qt::Key_Enter:
case Qt::Key_Return:
clearFocus();
return true;
default:
break;
}
}
return BaseClass::event(event);
}
void PDFActionComboBox::onActionChanged()
{
QAction* action = qobject_cast<QAction*>(sender());
updateAction(action);
}
void PDFActionComboBox::performExecuteAction()
{
QString text = this->text();
QAction* action = nullptr;
for (QAction* currentAction : m_actions)
{
if (currentAction->text() == text)
{
action = currentAction;
}
}
clear();
completer()->setCompletionPrefix(QString());
if (action)
{
action->trigger();
}
}
void PDFActionComboBox::updateAction(QAction* action)
{
if (!action)
{
return;
}
int actionIndex = findAction(action);
if (action->isEnabled())
{
if (actionIndex == -1)
{
QStandardItem* item = new QStandardItem(action->icon(), action->text());
item->setData(QVariant::fromValue(action), Qt::UserRole);
m_model->appendRow(item);
}
else
{
QStandardItem* item = m_model->item(actionIndex);
item->setIcon(action->icon());
item->setText(action->text());
}
}
else
{
// Remove action from the model
if (actionIndex != -1)
{
m_model->removeRow(actionIndex);
}
}
}
int PDFActionComboBox::findAction(QAction* action)
{
const int rowCount = m_model->rowCount();
for (int i = 0; i < rowCount; ++i)
{
QModelIndex index = m_model->index(i, 0);
QAction* currentAction = index.data(Qt::UserRole).value<QAction*>();
if (currentAction == action)
{
return i;
}
}
return -1;
}
} // namespace pdfviewer

View File

@@ -1,64 +0,0 @@
// Copyright (C) 2023 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#ifndef PDFACTIONCOMBOBOX_H
#define PDFACTIONCOMBOBOX_H
#include "pdfwidgetsglobal.h"
#include <QAction>
#include <QComboBox>
#include <QLineEdit>
class QStandardItemModel;
class QSortFilterProxyModel;
namespace pdfviewer
{
class PDFActionComboBox : public QLineEdit
{
Q_OBJECT
private:
using BaseClass = QLineEdit;
public:
PDFActionComboBox(QWidget* parent);
virtual QSize sizeHint() const override;
virtual QSize minimumSizeHint() const override;
virtual bool event(QEvent* event) override;
void addQuickFindAction(QAction* action);
private:
static constexpr int DEFAULT_WIDTH = 220;
void onActionChanged();
void performExecuteAction();
void updateAction(QAction* action);
int findAction(QAction* action);
std::vector<QAction*> m_actions;
QStandardItemModel* m_model;
};
} // namespace pdfviewer
#endif // PDFACTIONCOMBOBOX_H

View File

@@ -1,324 +0,0 @@
// Copyright (C) 2020-2022 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#include "pdfadvancedfindwidget.h"
#include "ui_pdfadvancedfindwidget.h"
#include "pdfcompiler.h"
#include "pdfdocument.h"
#include "pdfdrawspacecontroller.h"
#include <QMessageBox>
#include "pdfdbgheap.h"
namespace pdfviewer
{
PDFAdvancedFindWidget::PDFAdvancedFindWidget(pdf::PDFDrawWidgetProxy* proxy, QWidget* parent) :
QWidget(parent),
ui(new Ui::PDFAdvancedFindWidget),
m_proxy(proxy),
m_document(nullptr)
{
ui->setupUi(this);
ui->resultsTableWidget->setHorizontalHeaderLabels({ tr("Page No."), tr("Phrase"), tr("Context") });
connect(ui->regularExpressionsCheckbox, &QCheckBox::clicked, this, &PDFAdvancedFindWidget::updateUI);
connect(m_proxy, &pdf::PDFDrawWidgetProxy::textLayoutChanged, this, &PDFAdvancedFindWidget::performSearch);
connect(ui->resultsTableWidget, &QTableWidget::cellDoubleClicked, this, &PDFAdvancedFindWidget::onResultItemDoubleClicked);
connect(ui->resultsTableWidget, &QTableWidget::itemSelectionChanged, this, &PDFAdvancedFindWidget::onSelectionChanged);
updateUI();
}
PDFAdvancedFindWidget::~PDFAdvancedFindWidget()
{
delete ui;
}
void PDFAdvancedFindWidget::setDocument(const pdf::PDFModifiedDocument& document)
{
if (m_document != document)
{
m_document = document;
// If document is not being reset, then page text should remain the same,
// so, there is no need to clear the results.
if (document.hasReset() || document.hasPageContentsChanged())
{
m_findResults.clear();
updateUI();
updateResultsUI();
}
}
}
pdf::PDFTextSelection PDFAdvancedFindWidget::getSelectedText() const
{
pdf::PDFTextSelection result;
std::vector<size_t> selectedRowIndices;
QModelIndexList selectedRows = ui->resultsTableWidget->selectionModel()->selectedRows();
std::transform(selectedRows.cbegin(), selectedRows.cend(), std::back_inserter(selectedRowIndices), [] (const QModelIndex& index) { return index.row(); });
std::sort(selectedRowIndices.begin(), selectedRowIndices.end());
for (size_t i = 0; i < m_findResults.size(); ++i)
{
const pdf::PDFFindResult& findResult = m_findResults[i];
QColor color(Qt::yellow);
if (std::binary_search(selectedRowIndices.cbegin(), selectedRowIndices.cend(), i))
{
result.addItems(findResult.textSelectionItems, color);
}
}
result.build();
return result;
}
void PDFAdvancedFindWidget::on_searchButton_clicked()
{
m_parameters.phrase = ui->searchPhraseEdit->text();
m_parameters.isCaseSensitive = ui->caseSensitiveCheckBox->isChecked();
m_parameters.isWholeWordsOnly = ui->wholeWordsOnlyCheckBox->isChecked();
m_parameters.isRegularExpression = ui->regularExpressionsCheckbox->isChecked();
m_parameters.isDotMatchingEverything = ui->dotMatchesEverythingCheckBox->isChecked();
m_parameters.isMultiline = ui->multilineMatchingCheckBox->isChecked();
m_parameters.isSoftHyphenRemoved = ui->removeSoftHyphenCheckBox->isChecked();
m_parameters.isSearchFinished = m_parameters.phrase.isEmpty();
if (m_parameters.isSearchFinished)
{
// We have nothing to search for
return;
}
// Validate regular expression
if (m_parameters.isRegularExpression)
{
QRegularExpression expression(m_parameters.phrase);
if (!expression.isValid())
{
m_parameters.isSearchFinished = true;
const int patternErrorOffset = expression.patternErrorOffset();
QMessageBox::critical(this, tr("Search error"), tr("Search phrase regular expression has error '%1' near symbol %2.").arg(expression.errorString()).arg(patternErrorOffset));
ui->searchPhraseEdit->setFocus();
ui->searchPhraseEdit->setSelection(patternErrorOffset, 1);
return;
}
}
m_findResults.clear();
m_textSelection.dirty();
updateResultsUI();
pdf::PDFAsynchronousTextLayoutCompiler* compiler = m_proxy->getTextLayoutCompiler();
if (compiler->isTextLayoutReady())
{
performSearch();
}
else
{
compiler->makeTextLayout();
}
}
void PDFAdvancedFindWidget::on_clearButton_clicked()
{
m_parameters = SearchParameters();
m_findResults.clear();
updateResultsUI();
}
void PDFAdvancedFindWidget::onSelectionChanged()
{
m_textSelection.dirty();
m_proxy->repaintNeeded();
}
void PDFAdvancedFindWidget::onResultItemDoubleClicked(int row, int column)
{
Q_UNUSED(column);
if (row >= 0 && row < m_findResults.size())
{
const pdf::PDFFindResult& findResult = m_findResults[row];
const pdf::PDFInteger pageIndex = findResult.textSelectionItems.front().first.pageIndex;
m_proxy->goToPage(pageIndex);
}
}
void PDFAdvancedFindWidget::updateUI()
{
const bool enableUI = m_document && m_document->getCatalog()->getPageCount() > 0;
const bool enableRegularExpressionUI = enableUI && ui->regularExpressionsCheckbox->isChecked();
ui->searchForGroupBox->setEnabled(enableUI);
ui->regularExpressionSettingsGroupBox->setEnabled(enableRegularExpressionUI);
}
void PDFAdvancedFindWidget::updateResultsUI()
{
ui->tabWidget->setTabText(ui->tabWidget->indexOf(ui->resultsTab), !m_findResults.empty() ? tr("Results (%1)").arg(m_findResults.size()) : tr("Results"));
ui->resultsTableWidget->setRowCount(static_cast<int>(m_findResults.size()));
for (int i = 0, rowCount = int(m_findResults.size()); i < rowCount; ++i)
{
const pdf::PDFFindResult& findResult = m_findResults[i];
ui->resultsTableWidget->setItem(i, 0, new QTableWidgetItem(QString::number(findResult.textSelectionItems.front().first.pageIndex + 1)));
ui->resultsTableWidget->setItem(i, 1, new QTableWidgetItem(findResult.matched));
ui->resultsTableWidget->setItem(i, 2, new QTableWidgetItem(findResult.context));
}
if (!m_findResults.empty())
{
ui->tabWidget->setCurrentWidget(ui->resultsTab);
}
}
void PDFAdvancedFindWidget::drawPage(QPainter* painter,
pdf::PDFInteger pageIndex,
const pdf::PDFPrecompiledPage* compiledPage,
pdf::PDFTextLayoutGetter& layoutGetter,
const QTransform& pagePointToDevicePointMatrix,
QList<pdf::PDFRenderError>& errors) const
{
Q_UNUSED(compiledPage);
Q_UNUSED(errors);
const pdf::PDFTextSelection& textSelection = getTextSelection();
pdf::PDFTextSelectionPainter textSelectionPainter(&textSelection);
textSelectionPainter.draw(painter, pageIndex, layoutGetter, pagePointToDevicePointMatrix);
}
void PDFAdvancedFindWidget::performSearch()
{
if (m_parameters.isSearchFinished || m_parameters.phrase.isEmpty())
{
return;
}
m_parameters.isSearchFinished = true;
pdf::PDFAsynchronousTextLayoutCompiler* compiler = m_proxy->getTextLayoutCompiler();
if (!compiler->isTextLayoutReady())
{
// Text layout is not ready yet
return;
}
// Prepare string to search
bool useRegularExpression = m_parameters.isRegularExpression;
QString expression = m_parameters.phrase;
if (m_parameters.isWholeWordsOnly)
{
if (useRegularExpression)
{
expression = QString("\\b%1\\b").arg(expression);
}
else
{
expression = QString("\\b%1\\b").arg(QRegularExpression::escape(expression));
}
useRegularExpression = true;
}
pdf::PDFTextFlow::FlowFlags flowFlags = pdf::PDFTextFlow::SeparateBlocks;
if (m_parameters.isSoftHyphenRemoved)
{
flowFlags |= pdf::PDFTextFlow::RemoveSoftHyphen;
}
if (m_parameters.isRegularExpression)
{
flowFlags |= pdf::PDFTextFlow::AddLineBreaks;
}
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;
if (!m_parameters.isCaseSensitive)
{
patternOptions |= QRegularExpression::CaseInsensitiveOption;
}
if (m_parameters.isDotMatchingEverything)
{
patternOptions |= QRegularExpression::DotMatchesEverythingOption;
}
if (m_parameters.isMultiline)
{
patternOptions |= QRegularExpression::MultilineOption;
}
QRegularExpression regularExpression(expression, patternOptions);
m_findResults = textLayoutStorage->find(regularExpression, flowFlags);
}
m_textSelection.dirty();
m_proxy->repaintNeeded();
updateResultsUI();
}
pdf::PDFTextSelection PDFAdvancedFindWidget::getTextSelectionImpl() const
{
pdf::PDFTextSelection result;
std::vector<size_t> selectedRowIndices;
QModelIndexList selectedRows = ui->resultsTableWidget->selectionModel()->selectedRows();
std::transform(selectedRows.cbegin(), selectedRows.cend(), std::back_inserter(selectedRowIndices), [] (const QModelIndex& index) { return index.row(); });
std::sort(selectedRowIndices.begin(), selectedRowIndices.end());
for (size_t i = 0; i < m_findResults.size(); ++i)
{
const pdf::PDFFindResult& findResult = m_findResults[i];
QColor color(Qt::blue);
if (std::binary_search(selectedRowIndices.cbegin(), selectedRowIndices.cend(), i))
{
color = QColor(Qt::yellow);
}
result.addItems(findResult.textSelectionItems, color);
}
result.build();
return result;
}
void PDFAdvancedFindWidget::showEvent(QShowEvent* event)
{
BaseClass::showEvent(event);
m_proxy->registerDrawInterface(this);
}
void PDFAdvancedFindWidget::hideEvent(QHideEvent* event)
{
m_proxy->unregisterDrawInterface(this);
BaseClass::hideEvent(event);
}
} // namespace pdfviewer

View File

@@ -1,107 +0,0 @@
// Copyright (C) 2020-2021 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#ifndef PDFADVANCEDFINDWIDGET_H
#define PDFADVANCEDFINDWIDGET_H
#include "pdfglobal.h"
#include "pdfdrawspacecontroller.h"
#include "pdftextlayout.h"
#include <QWidget>
namespace Ui
{
class PDFAdvancedFindWidget;
}
namespace pdf
{
class PDFDocument;
class PDFDrawWidgetProxy;
}
namespace pdfviewer
{
class PDFAdvancedFindWidget : public QWidget, public pdf::IDocumentDrawInterface
{
Q_OBJECT
private:
using BaseClass = QWidget;
public:
explicit PDFAdvancedFindWidget(pdf::PDFDrawWidgetProxy* proxy, QWidget* parent = nullptr);
virtual ~PDFAdvancedFindWidget() override;
virtual void drawPage(QPainter* painter,
pdf::PDFInteger pageIndex,
const pdf::PDFPrecompiledPage* compiledPage,
pdf::PDFTextLayoutGetter& layoutGetter,
const QTransform& pagePointToDevicePointMatrix,
QList<pdf::PDFRenderError>& errors) const override;
void setDocument(const pdf::PDFModifiedDocument& document);
/// Returns selected text items in the table (selected means not all results,
/// but those, which are selected rows in the result table)
pdf::PDFTextSelection getSelectedText() const;
protected:
virtual void showEvent(QShowEvent* event) override;
virtual void hideEvent(QHideEvent* event) override;
private slots:
void on_searchButton_clicked();
void onSelectionChanged();
void onResultItemDoubleClicked(int row, int column);
void on_clearButton_clicked();
private:
void updateUI();
void updateResultsUI();
void performSearch();
pdf::PDFTextSelection getTextSelection() const { return m_textSelection.get(this, &PDFAdvancedFindWidget::getTextSelectionImpl); }
pdf::PDFTextSelection getTextSelectionImpl() const;
struct SearchParameters
{
QString phrase;
bool isCaseSensitive = false;
bool isWholeWordsOnly = false;
bool isRegularExpression = false;
bool isDotMatchingEverything = false;
bool isMultiline = false;
bool isSearchFinished = false;
bool isSoftHyphenRemoved = false;
};
Ui::PDFAdvancedFindWidget* ui;
pdf::PDFDrawWidgetProxy* m_proxy;
const pdf::PDFDocument* m_document;
SearchParameters m_parameters;
pdf::PDFFindResults m_findResults;
mutable pdf::PDFCachedItem<pdf::PDFTextSelection> m_textSelection;
};
} // namespace pdfviewer
#endif // PDFADVANCEDFINDWIDGET_H

View File

@@ -1,164 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PDFAdvancedFindWidget</class>
<widget class="QWidget" name="PDFAdvancedFindWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>881</width>
<height>457</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="searchTab">
<attribute name="title">
<string>Search for</string>
</attribute>
<layout class="QVBoxLayout" name="searchTabLayout">
<item>
<widget class="QGroupBox" name="searchForGroupBox">
<property name="title">
<string>Search Settings</string>
</property>
<layout class="QGridLayout" name="searchSettingsGroupBoxLayout" columnstretch="0,1,0,0">
<item row="5" column="3">
<widget class="QPushButton" name="searchButton">
<property name="text">
<string>Search</string>
</property>
</widget>
</item>
<item row="2" column="1" colspan="3">
<widget class="QCheckBox" name="wholeWordsOnlyCheckBox">
<property name="text">
<string>Whole words only</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="removeSoftHyphenCheckBox">
<property name="text">
<string>Remove soft hyphen at end of line</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="searchLabel">
<property name="text">
<string>Search for:</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="3">
<widget class="QCheckBox" name="caseSensitiveCheckBox">
<property name="text">
<string>Case sensitive</string>
</property>
</widget>
</item>
<item row="0" column="1" colspan="3">
<widget class="QLineEdit" name="searchPhraseEdit"/>
</item>
<item row="3" column="1" colspan="3">
<widget class="QCheckBox" name="regularExpressionsCheckbox">
<property name="text">
<string>Use regular expressions</string>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QPushButton" name="clearButton">
<property name="text">
<string>Clear</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="regularExpressionSettingsGroupBox">
<property name="title">
<string>Regular Expression Settings</string>
</property>
<layout class="QVBoxLayout" name="regularExpressionSettingsGroupBoxLayout">
<item>
<widget class="QCheckBox" name="dotMatchesEverythingCheckBox">
<property name="text">
<string>Dot matches everything (including newline characters)</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="multilineMatchingCheckBox">
<property name="text">
<string>Multiline matching (enables search using '^' and '$' to mark line beginnings/endings)</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="resultsTab">
<attribute name="title">
<string>Results</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QTableWidget" name="resultsTableWidget">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="columnCount">
<number>3</number>
</property>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<column/>
<column/>
<column/>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -1,354 +0,0 @@
// Copyright (C) 2023 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#include "pdfbookmarkmanager.h"
#include "pdfaction.h"
#include <QFile>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonDocument>
namespace pdfviewer
{
class PDFBookmarkManagerHelper
{
public:
constexpr PDFBookmarkManagerHelper() = delete;
static QJsonObject convertBookmarkToJson(const PDFBookmarkManager::Bookmark& bookmark)
{
QJsonObject json;
json["isAuto"] = bookmark.isAuto;
json["name"] = bookmark.name;
json["pageIndex"] = static_cast<qint64>(bookmark.pageIndex);
return json;
}
static PDFBookmarkManager::Bookmark convertJsonToBookmark(const QJsonObject& json)
{
PDFBookmarkManager::Bookmark bookmark;
bookmark.isAuto = json["isAuto"].toBool();
bookmark.name = json["name"].toString();
bookmark.pageIndex = json["pageIndex"].toInteger();
return bookmark;
}
static QJsonObject convertBookmarksToJson(const PDFBookmarkManager::Bookmarks& bookmarks)
{
QJsonArray jsonArray;
for (const auto& bookmark : bookmarks.bookmarks)
{
jsonArray.append(convertBookmarkToJson(bookmark));
}
QJsonObject jsonObject;
jsonObject["bookmarks"] = jsonArray;
return jsonObject;
}
static PDFBookmarkManager::Bookmarks convertBookmarksFromJson(const QJsonObject& object)
{
PDFBookmarkManager::Bookmarks bookmarks;
QJsonArray jsonArray = object["bookmarks"].toArray();
for (const auto& jsonValue : jsonArray)
{
bookmarks.bookmarks.push_back(convertJsonToBookmark(jsonValue.toObject()));
}
return bookmarks;
}
static QJsonDocument convertBookmarksMapToJsonDocument(const std::map<QString, PDFBookmarkManager::Bookmarks>& bookmarksMap)
{
QJsonObject mainObject;
for (const auto& pair : bookmarksMap)
{
mainObject[pair.first] = convertBookmarksToJson(pair.second);
}
return QJsonDocument(mainObject);
}
static std::map<QString, PDFBookmarkManager::Bookmarks> convertBookmarksMapFromJsonDocument(const QJsonDocument &doc)
{
std::map<QString, PDFBookmarkManager::Bookmarks> container;
QJsonObject mainObject = doc.object();
for (auto it = mainObject.begin(); it != mainObject.end(); ++it)
{
container[it.key()] = convertBookmarksFromJson(it.value().toObject());
}
return container;
}
};
PDFBookmarkManager::PDFBookmarkManager(QObject* parent) :
BaseClass(parent)
{
}
void PDFBookmarkManager::setDocument(const pdf::PDFModifiedDocument& document)
{
Q_EMIT bookmarksAboutToBeChanged();
m_document = document.getDocument();
if (document.hasReset())
{
if (!document.hasPreserveView())
{
m_bookmarks.bookmarks.clear();
regenerateAutoBookmarks();
}
}
Q_EMIT bookmarksChanged();
}
void PDFBookmarkManager::saveToFile(QString fileName)
{
QJsonDocument doc(PDFBookmarkManagerHelper::convertBookmarksToJson(m_bookmarks));
// Příklad zápisu do souboru
QFile file(fileName);
if (file.open(QIODevice::WriteOnly))
{
file.write(doc.toJson());
file.close();
}
}
bool PDFBookmarkManager::loadFromFile(QString fileName)
{
QFile file(fileName);
if (file.open(QIODevice::ReadOnly))
{
QJsonDocument loadedDoc = QJsonDocument::fromJson(file.readAll());
file.close();
Q_EMIT bookmarksAboutToBeChanged();
m_bookmarks = PDFBookmarkManagerHelper::convertBookmarksFromJson(loadedDoc.object());
Q_EMIT bookmarksChanged();
return true;
}
return false;
}
bool PDFBookmarkManager::isEmpty() const
{
return m_bookmarks.bookmarks.empty();
}
int PDFBookmarkManager::getBookmarkCount() const
{
return static_cast<int>(m_bookmarks.bookmarks.size());
}
PDFBookmarkManager::Bookmark PDFBookmarkManager::getBookmark(int index) const
{
return m_bookmarks.bookmarks.at(index);
}
void PDFBookmarkManager::toggleBookmark(pdf::PDFInteger pageIndex)
{
Q_EMIT bookmarksAboutToBeChanged();
auto it = std::find_if(m_bookmarks.bookmarks.begin(), m_bookmarks.bookmarks.end(), [pageIndex](const auto& bookmark) { return bookmark.pageIndex == pageIndex; });
if (it != m_bookmarks.bookmarks.cend())
{
Bookmark& bookmark = *it;
if (bookmark.isAuto)
{
bookmark.isAuto = false;
}
else
{
m_bookmarks.bookmarks.erase(it);
}
}
else
{
Bookmark bookmark;
bookmark.isAuto = false;
bookmark.name = tr("User bookmark for page %1").arg(pageIndex + 1);
bookmark.pageIndex = pageIndex;
m_bookmarks.bookmarks.push_back(bookmark);
sortBookmarks();
}
Q_EMIT bookmarksChanged();
}
void PDFBookmarkManager::setGenerateBookmarksAutomatically(bool generateBookmarksAutomatically)
{
if (m_generateBookmarksAutomatically != generateBookmarksAutomatically)
{
Q_EMIT bookmarksAboutToBeChanged();
m_generateBookmarksAutomatically = generateBookmarksAutomatically;
regenerateAutoBookmarks();
Q_EMIT bookmarksChanged();
}
}
void PDFBookmarkManager::goToNextBookmark()
{
if (isEmpty())
{
return;
}
m_currentBookmark = (m_currentBookmark + 1) % getBookmarkCount();
goToCurrentBookmark();
}
void PDFBookmarkManager::goToPreviousBookmark()
{
if (isEmpty())
{
return;
}
if (m_currentBookmark <= 0)
{
m_currentBookmark = getBookmarkCount() - 1;
}
else
{
--m_currentBookmark;
}
goToCurrentBookmark();
}
void PDFBookmarkManager::goToCurrentBookmark()
{
if (isEmpty())
{
return;
}
if (m_currentBookmark >= 0 && m_currentBookmark < getBookmarkCount())
{
Q_EMIT bookmarkActivated(m_currentBookmark, m_bookmarks.bookmarks.at(m_currentBookmark));
}
}
void PDFBookmarkManager::goToBookmark(int index, bool force)
{
if (m_currentBookmark != index || force)
{
m_currentBookmark = index;
goToCurrentBookmark();
}
}
void PDFBookmarkManager::sortBookmarks()
{
auto predicate = [](const auto& l, const auto& r)
{
return l.pageIndex < r.pageIndex;
};
std::sort(m_bookmarks.bookmarks.begin(), m_bookmarks.bookmarks.end(), predicate);
}
void PDFBookmarkManager::regenerateAutoBookmarks()
{
if (!m_document)
{
return;
}
// Create bookmarks for all main chapters
Bookmarks& bookmarks = m_bookmarks;
for (auto it = bookmarks.bookmarks.begin(); it != bookmarks.bookmarks.end();)
{
if (it->isAuto)
{
it = bookmarks.bookmarks.erase(it);
}
else
{
++it;
}
}
if (!m_generateBookmarksAutomatically)
{
return;
}
if (auto outlineRoot = m_document->getCatalog()->getOutlineRootPtr())
{
size_t childCount = outlineRoot->getChildCount();
for (size_t i = 0; i < childCount; ++i)
{
Bookmark bookmark;
bookmark.isAuto = true;
bookmark.pageIndex = pdf::PDFCatalog::INVALID_PAGE_INDEX;
const pdf::PDFOutlineItem* child = outlineRoot->getChild(i);
const pdf::PDFAction* action = child->getAction();
if (action)
{
for (const pdf::PDFAction* currentAction : action->getActionList())
{
if (currentAction->getType() != pdf::ActionType::GoTo)
{
continue;
}
const pdf::PDFActionGoTo* typedAction = dynamic_cast<const pdf::PDFActionGoTo*>(currentAction);
pdf::PDFDestination destination = typedAction->getDestination();
if (destination.getDestinationType() == pdf::DestinationType::Named)
{
if (const pdf::PDFDestination* targetDestination = m_document->getCatalog()->getNamedDestination(destination.getName()))
{
destination = *targetDestination;
}
}
if (destination.getDestinationType() != pdf::DestinationType::Invalid &&
destination.getPageReference() != pdf::PDFObjectReference())
{
const size_t pageIndex = m_document->getCatalog()->getPageIndexFromPageReference(destination.getPageReference());
if (pageIndex != pdf::PDFCatalog::INVALID_PAGE_INDEX)
{
bookmark.pageIndex = pageIndex;
bookmark.name = child->getTitle();
}
}
}
}
if (bookmark.pageIndex != pdf::PDFCatalog::INVALID_PAGE_INDEX)
{
bookmarks.bookmarks.emplace_back(std::move(bookmark));
}
}
}
}
} // namespace pdf

View File

@@ -1,85 +0,0 @@
// Copyright (C) 2023 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#ifndef PDFBOOKMARKMANAGER_H
#define PDFBOOKMARKMANAGER_H
#include "pdfdocument.h"
#include <QObject>
namespace pdfviewer
{
class PDFBookmarkManager : public QObject
{
Q_OBJECT
private:
using BaseClass = QObject;
public:
PDFBookmarkManager(QObject* parent);
void setDocument(const pdf::PDFModifiedDocument& document);
void saveToFile(QString fileName);
bool loadFromFile(QString fileName);
struct Bookmark
{
bool isAuto = false;
QString name;
pdf::PDFInteger pageIndex = -1;
};
bool isEmpty() const;
int getBookmarkCount() const;
Bookmark getBookmark(int index) const;
void toggleBookmark(pdf::PDFInteger pageIndex);
void setGenerateBookmarksAutomatically(bool generateBookmarksAutomatically);
void goToNextBookmark();
void goToPreviousBookmark();
void goToCurrentBookmark();
void goToBookmark(int index, bool force);
signals:
void bookmarksAboutToBeChanged();
void bookmarksChanged();
void bookmarkActivated(int index, Bookmark bookmark);
private:
friend class PDFBookmarkManagerHelper;
void sortBookmarks();
void regenerateAutoBookmarks();
struct Bookmarks
{
std::vector<Bookmark> bookmarks;
};
pdf::PDFDocument* m_document;
Bookmarks m_bookmarks;
int m_currentBookmark = -1;
bool m_generateBookmarksAutomatically = true;
};
} // namespace pdf
#endif // PDFBOOKMARKMANAGER_H

View File

@@ -1,198 +0,0 @@
// Copyright (C) 2023 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#include "pdfbookmarkui.h"
#include "pdfwidgetutils.h"
#include "pdfpainterutils.h"
#include <QPainter>
#include <QPainterPath>
namespace pdfviewer
{
PDFBookmarkItemModel::PDFBookmarkItemModel(PDFBookmarkManager* bookmarkManager, QObject* parent) :
BaseClass(parent),
m_bookmarkManager(bookmarkManager)
{
connect(m_bookmarkManager, &PDFBookmarkManager::bookmarksAboutToBeChanged, this, &PDFBookmarkItemModel::beginResetModel);
connect(m_bookmarkManager, &PDFBookmarkManager::bookmarksChanged, this, &PDFBookmarkItemModel::endResetModel);
}
QModelIndex PDFBookmarkItemModel::index(int row, int column, const QModelIndex& parent) const
{
if (parent.isValid())
{
return QModelIndex();
}
return createIndex(row, column, nullptr);
}
QModelIndex PDFBookmarkItemModel::parent(const QModelIndex& child) const
{
Q_UNUSED(child);
return QModelIndex();
}
int PDFBookmarkItemModel::rowCount(const QModelIndex& parent) const
{
if (parent.isValid())
{
return 0;
}
return m_bookmarkManager ? m_bookmarkManager->getBookmarkCount() : 0;
}
int PDFBookmarkItemModel::columnCount(const QModelIndex& parent) const
{
if (parent.isValid())
{
return 0;
}
return 1;
}
QVariant PDFBookmarkItemModel::data(const QModelIndex& index, int role) const
{
if (role == Qt::DisplayRole)
{
return m_bookmarkManager->getBookmark(index.row()).name;
}
return QVariant();
}
PDFBookmarkItemDelegate::PDFBookmarkItemDelegate(PDFBookmarkManager* bookmarkManager, QObject* parent) :
BaseClass(parent),
m_bookmarkManager(bookmarkManager)
{
}
void PDFBookmarkItemDelegate::paint(QPainter* painter,
const QStyleOptionViewItem& option,
const QModelIndex& index) const
{
QStyleOptionViewItem options = option;
initStyleOption(&options, index);
PDFBookmarkManager::Bookmark bookmark = m_bookmarkManager->getBookmark(index.row());
options.text = QString();
options.widget->style()->drawControl(QStyle::CE_ItemViewItem, &options, painter);
const int margin = pdf::PDFWidgetUtils::scaleDPI_x(option.widget, MARGIN);
const int iconSize = pdf::PDFWidgetUtils::scaleDPI_x(option.widget, ICON_SIZE);
QRect rect = options.rect;
rect.marginsRemoved(QMargins(margin, margin, margin, margin));
QColor color = bookmark.isAuto ? QColor(0, 123, 255) : QColor(255, 159, 0);
if (options.state.testFlag(QStyle::State_Selected))
{
color = Qt::yellow;
}
QRect iconRect = rect;
iconRect.setWidth(iconSize);
iconRect.setHeight(iconSize);
iconRect.moveCenter(QPoint(rect.left() + iconSize / 2, rect.center().y()));
drawStar(*painter, iconRect.center(), iconRect.width() * 0.5, color);
QRect textRect = rect;
textRect.setLeft(iconRect.right() + margin);
textRect.moveTop(rect.top() + (rect.height() - 2 * options.fontMetrics.lineSpacing()) / 2);
textRect.setHeight(options.fontMetrics.lineSpacing());
QFont font = options.font;
font.setBold(true);
painter->setFont(font);
painter->drawText(textRect, getPageText(bookmark));
textRect.translate(0, textRect.height());
painter->setFont(options.font);
painter->drawText(textRect, bookmark.name);
}
QSize PDFBookmarkItemDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
{
PDFBookmarkManager::Bookmark bookmark = m_bookmarkManager->getBookmark(index.row());
const int textWidthLine1 = option.fontMetrics.horizontalAdvance(getPageText(bookmark));
const int textWidthLine2 = option.fontMetrics.horizontalAdvance(option.text);
const int textWidth = qMax(textWidthLine1, textWidthLine2);
const int textHeight = option.fontMetrics.lineSpacing() * 2;
const int margin = pdf::PDFWidgetUtils::scaleDPI_x(option.widget, MARGIN);
const int iconSize = pdf::PDFWidgetUtils::scaleDPI_x(option.widget, ICON_SIZE);
const int requiredWidth = 3 * margin + iconSize + textWidth;
const int requiredHeight = 2 * margin + qMax(iconSize, textHeight);
return QSize(requiredWidth, requiredHeight);
}
void PDFBookmarkItemDelegate::drawStar(QPainter& painter, const QPointF& center, double size, const QColor& color) const
{
pdf::PDFPainterStateGuard guard(&painter);
painter.setPen(Qt::NoPen);
painter.setBrush(color);
QPainterPath path;
double angle = M_PI / 5;
double phase = -M_PI / 10;
for (int i = 0; i < 10; ++i)
{
double radius = (i % 2 == 0) ? size : size / 2.5;
QPointF point(radius * cos(i * angle + phase), radius * sin(i * angle + phase));
point += center;
if (i == 0)
{
path.moveTo(point);
}
else
{
path.lineTo(point);
}
}
path.closeSubpath();
painter.drawPath(path);
}
QString PDFBookmarkItemDelegate::getPageText(const PDFBookmarkManager::Bookmark& bookmark) const
{
if (bookmark.isAuto)
{
return tr("Page %1 | Generated").arg(bookmark.pageIndex + 1);
}
else
{
return tr("Page %1").arg(bookmark.pageIndex + 1);
}
}
} // namespace pdfviewer

View File

@@ -1,76 +0,0 @@
// Copyright (C) 2023 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#ifndef PDFBOOKMARKUI_H
#define PDFBOOKMARKUI_H
#include "pdfviewerglobal.h"
#include "pdfbookmarkmanager.h"
#include <QStyledItemDelegate>
#include <QAbstractItemModel>
namespace pdfviewer
{
class PDFBookmarkItemModel : public QAbstractItemModel
{
Q_OBJECT
private:
using BaseClass = QAbstractItemModel;
public:
PDFBookmarkItemModel(PDFBookmarkManager* bookmarkManager, QObject* parent);
virtual QModelIndex index(int row, int column, const QModelIndex& parent) const override;
virtual QModelIndex parent(const QModelIndex& child) const override;
virtual int rowCount(const QModelIndex& parent) const override;
virtual int columnCount(const QModelIndex& parent) const override;
virtual QVariant data(const QModelIndex& index, int role) const override;
private:
PDFBookmarkManager* m_bookmarkManager = nullptr;
};
class PDFBookmarkItemDelegate : public QStyledItemDelegate
{
Q_OBJECT
private:
using BaseClass = QStyledItemDelegate;
public:
PDFBookmarkItemDelegate(PDFBookmarkManager* bookmarkManager, QObject* parent);
virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override;
private:
static constexpr int MARGIN = 6;
static constexpr int ICON_SIZE = 32;
void drawStar(QPainter& painter, const QPointF& center, double size, const QColor& color) const;
QString getPageText(const PDFBookmarkManager::Bookmark& bookmark) const;
PDFBookmarkManager* m_bookmarkManager = nullptr;
};
} // namespace pdfviewer
#endif // PDFBOOKMARKUI_H

View File

@@ -1,511 +0,0 @@
// Copyright (C) 2023 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#include "pdfcreatebitonaldocumentdialog.h"
#include "ui_pdfcreatebitonaldocumentdialog.h"
#include "pdfwidgetutils.h"
#include "pdfdocumentwriter.h"
#include "pdfimage.h"
#include "pdfexception.h"
#include "pdfwidgetutils.h"
#include "pdfimageconversion.h"
#include "pdfstreamfilters.h"
#include "pdfutils.h"
#include <QCheckBox>
#include <QPushButton>
#include <QElapsedTimer>
#include <QtConcurrent/QtConcurrent>
#include <QListWidget>
#include <QStyledItemDelegate>
#include <QPainter>
#include <QtSvg/QSvgRenderer>
#include <QMouseEvent>
#include <QToolTip>
#include "pdfdbgheap.h"
namespace pdfviewer
{
PDFCreateBitonalDocumentPreviewWidget::PDFCreateBitonalDocumentPreviewWidget(QWidget* parent) :
QWidget(parent)
{
}
PDFCreateBitonalDocumentPreviewWidget::~PDFCreateBitonalDocumentPreviewWidget()
{
}
void PDFCreateBitonalDocumentPreviewWidget::paintEvent(QPaintEvent* event)
{
Q_UNUSED(event);
QPainter painter(this);
painter.fillRect(rect(), Qt::white);
// Caption rect
QRect captionRect = rect();
captionRect.setHeight(painter.fontMetrics().lineSpacing() * 2);
painter.fillRect(captionRect, QColor::fromRgb(0, 0, 128, 255));
if (!m_caption.isEmpty())
{
painter.setPen(Qt::white);
painter.drawText(captionRect, m_caption, QTextOption(Qt::AlignCenter));
}
QRect imageRect = rect();
imageRect.setTop(captionRect.bottom());
imageRect = imageRect.adjusted(16, 16, -32, -32);
if (imageRect.isValid() && !m_image.isNull())
{
QRect imageDrawRect = imageRect;
imageDrawRect.setSize(m_image.size().scaled(imageRect.size(), Qt::KeepAspectRatio));
imageDrawRect.moveCenter(imageRect.center());
painter.drawImage(imageDrawRect, m_image);
}
}
void PDFCreateBitonalDocumentPreviewWidget::setCaption(QString caption)
{
if (m_caption != caption)
{
m_caption = caption;
update();
}
}
void PDFCreateBitonalDocumentPreviewWidget::setImage(QImage image)
{
m_image = std::move(image);
update();
}
class ImagePreviewDelegate : public QStyledItemDelegate
{
public:
ImagePreviewDelegate(std::vector<PDFCreateBitonalDocumentDialog::ImageConversionInfo>* imageConversionInfos, QObject* parent) :
QStyledItemDelegate(parent),
m_imageConversionInfos(imageConversionInfos)
{
m_yesRenderer.load(QString(":/resources/result-ok.svg"));
m_noRenderer.load(QString(":/resources/result-error.svg"));
}
virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override
{
QStyledItemDelegate::paint(painter, option, index);
QRect markRect = getMarkRect(option);
if (index.isValid())
{
const PDFCreateBitonalDocumentDialog::ImageConversionInfo& info = m_imageConversionInfos->at(index.row());
if (info.conversionEnabled)
{
m_yesRenderer.render(painter, markRect);
}
else
{
m_noRenderer.render(painter, markRect);
}
}
}
virtual bool editorEvent(QEvent* event,
QAbstractItemModel* model,
const QStyleOptionViewItem& option,
const QModelIndex& index)
{
Q_UNUSED(model);
Q_UNUSED(index);
if (event->type() == QEvent::MouseButtonPress && index.isValid())
{
QMouseEvent* mouseEvent = dynamic_cast<QMouseEvent*>(event);
if (mouseEvent && mouseEvent->button() == Qt::LeftButton)
{
// Do we click on yes/no mark?
QRectF markRect = getMarkRect(option);
if (markRect.contains(mouseEvent->position()))
{
PDFCreateBitonalDocumentDialog::ImageConversionInfo& info = m_imageConversionInfos->at(index.row());
info.conversionEnabled = !info.conversionEnabled;
return true;
}
}
}
return false;
}
virtual bool helpEvent(QHelpEvent* event,
QAbstractItemView* view,
const QStyleOptionViewItem& option,
const QModelIndex& index) override
{
Q_UNUSED(index);
if (!event || !view)
{
return false;
}
if (event->type() == QEvent::ToolTip)
{
// Are we hovering over yes/no mark?
QRectF markRect = getMarkRect(option);
if (markRect.contains(event->pos()))
{
event->accept();
QToolTip::showText(event->globalPos(), tr("Toggle this icon to switch image conversion to bitonal format on or off."), view);
return true;
}
}
return false;
}
private:
static constexpr QSize s_iconSize = QSize(24, 24);
QRect getMarkRect(const QStyleOptionViewItem& option) const
{
QSize markSize = pdf::PDFWidgetUtils::scaleDPI(option.widget, s_iconSize);
QRect markRect(option.rect.left(), option.rect.top(), markSize.width(), markSize.height());
return markRect;
}
std::vector<PDFCreateBitonalDocumentDialog::ImageConversionInfo>* m_imageConversionInfos;
mutable QSvgRenderer m_yesRenderer;
mutable QSvgRenderer m_noRenderer;
};
PDFCreateBitonalDocumentDialog::PDFCreateBitonalDocumentDialog(const pdf::PDFDocument* document,
const pdf::PDFCMS* cms,
pdf::PDFProgress* progress,
QWidget* parent) :
QDialog(parent),
ui(new Ui::PDFCreateBitonalDocumentDialog),
m_document(document),
m_cms(cms),
m_createBitonalDocumentButton(nullptr),
m_conversionInProgress(false),
m_processed(false),
m_leftPreviewWidget(new PDFCreateBitonalDocumentPreviewWidget(this)),
m_rightPreviewWidget(new PDFCreateBitonalDocumentPreviewWidget(this)),
m_progress(progress)
{
ui->setupUi(this);
m_leftPreviewWidget->setCaption(tr("ORIGINAL"));
m_rightPreviewWidget->setCaption(tr("BITONAL"));
ui->mainGridLayout->addWidget(m_leftPreviewWidget, 1, 1);
ui->mainGridLayout->addWidget(m_rightPreviewWidget, 1, 2);
m_classifier.classify(document);
m_imageReferences = m_classifier.getObjectsByType(pdf::PDFObjectClassifier::Image);
m_createBitonalDocumentButton = ui->buttonBox->addButton(tr("Perform"), QDialogButtonBox::ActionRole);
connect(m_createBitonalDocumentButton, &QPushButton::clicked, this, &PDFCreateBitonalDocumentDialog::onCreateBitonalDocumentButtonClicked);
connect(ui->automaticThresholdRadioButton, &QRadioButton::clicked, this, &PDFCreateBitonalDocumentDialog::updateUi);
connect(ui->manualThresholdRadioButton, &QRadioButton::clicked, this, &PDFCreateBitonalDocumentDialog::updateUi);
connect(ui->automaticThresholdRadioButton, &QRadioButton::clicked, this, &PDFCreateBitonalDocumentDialog::updatePreview);
connect(ui->manualThresholdRadioButton, &QRadioButton::clicked, this, &PDFCreateBitonalDocumentDialog::updatePreview);
connect(ui->imageListWidget, &QListWidget::currentItemChanged, this, &PDFCreateBitonalDocumentDialog::updatePreview);
connect(ui->thresholdEditBox, &QSpinBox::editingFinished, this, &PDFCreateBitonalDocumentDialog::updatePreview);
pdf::PDFWidgetUtils::scaleWidget(this, QSize(1024, 768));
updateUi();
pdf::PDFWidgetUtils::style(this);
ui->imageListWidget->setItemDelegate( new ImagePreviewDelegate(&m_imagesToBeConverted, this));
setGeometry(parent->geometry());
loadImages();
updatePreview();
}
PDFCreateBitonalDocumentDialog::~PDFCreateBitonalDocumentDialog()
{
Q_ASSERT(!m_conversionInProgress);
Q_ASSERT(!m_future.isRunning());
delete ui;
}
void PDFCreateBitonalDocumentDialog::onPerformFinished()
{
m_future.waitForFinished();
m_conversionInProgress = false;
m_processed = true;
updateUi();
}
void PDFCreateBitonalDocumentDialog::createBitonalDocument()
{
std::vector<ImageConversionInfo> imagesToBeConverted;
std::copy_if(m_imagesToBeConverted.begin(), m_imagesToBeConverted.end(), std::back_inserter(imagesToBeConverted), [](const auto& item) { return item.conversionEnabled; });
// Do we have something to be converted?
if (imagesToBeConverted.empty())
{
return;
}
pdf::ProgressStartupInfo info;
info.showDialog = true;
info.text = tr("Converting images...");
m_progress->start(imagesToBeConverted.size(), std::move(info));
pdf::PDFObjectStorage storage = m_document->getStorage();
pdf::PDFCMSGeneric genericCms;
pdf::PDFRenderErrorReporterDummy errorReporter;
for (int i = 0; i < imagesToBeConverted.size(); ++i)
{
pdf::PDFObjectReference reference = imagesToBeConverted[i].imageReference;
std::optional<pdf::PDFImage> pdfImage = getImageFromReference(reference);
QImage image;
try
{
image = pdfImage->getImage(&genericCms, &errorReporter, nullptr);
}
catch (pdf::PDFException)
{
// Do nothing
}
// Just for code safety - this should never occur in here.
if (image.isNull())
{
continue;
}
pdf::PDFImageConversion imageConversion;
imageConversion.setConversionMethod(m_conversionMethod);
imageConversion.setThreshold(m_manualThreshold);
imageConversion.setImage(image);
if (imageConversion.convert())
{
QImage bitonalImage = imageConversion.getConvertedImage();
Q_ASSERT(bitonalImage.format() == QImage::Format_Mono);
pdf::PDFBitWriter bitWriter(1);
bitWriter.reserve(bitonalImage.sizeInBytes());
for (int row = 0; row < bitonalImage.height(); ++row)
{
for (int col = 0; col < bitonalImage.width(); ++col)
{
QRgb pixelValue = bitonalImage.pixel(col, row);
QRgb withoutAlphaValue = pixelValue & 0xFFFFFF;
int value = withoutAlphaValue > 0 ? 1 : 0;
bitWriter.write(value);
}
bitWriter.finishLine();
}
QByteArray imageData = bitWriter.takeByteArray();
QByteArray compressedData = pdf::PDFFlateDecodeFilter::compress(imageData);
pdf::PDFArray array;
array.appendItem(pdf::PDFObject::createName("FlateDecode"));
pdf::PDFDictionary dictionary;
dictionary.addEntry(pdf::PDFInplaceOrMemoryString("Type"), pdf::PDFObject::createName("XObject"));
dictionary.addEntry(pdf::PDFInplaceOrMemoryString("Subtype"), pdf::PDFObject::createName("Image"));
dictionary.addEntry(pdf::PDFInplaceOrMemoryString("Width"), pdf::PDFObject::createInteger(image.width()));
dictionary.addEntry(pdf::PDFInplaceOrMemoryString("Height"), pdf::PDFObject::createInteger(image.height()));
dictionary.addEntry(pdf::PDFInplaceOrMemoryString("ColorSpace"), pdf::PDFObject::createName("DeviceGray"));
dictionary.addEntry(pdf::PDFInplaceOrMemoryString("BitsPerComponent"), pdf::PDFObject::createInteger(1));
dictionary.addEntry(pdf::PDFInplaceOrMemoryString("Predictor"), pdf::PDFObject::createInteger(1));
dictionary.setEntry(pdf::PDFInplaceOrMemoryString("Length"), pdf::PDFObject::createInteger(compressedData.size()));
dictionary.setEntry(pdf::PDFInplaceOrMemoryString("Filter"), pdf::PDFObject::createArray(std::make_shared<pdf::PDFArray>(qMove(array))));
pdf::PDFObject imageObject = pdf::PDFObject::createStream(std::make_shared<pdf::PDFStream>(qMove(dictionary), qMove(compressedData)));
storage.setObject(reference, std::move(imageObject));
}
m_progress->step();
}
m_bitonalDocument = pdf::PDFDocument(std::move(storage), m_document->getInfo()->version, QByteArray());
m_progress->finish();
}
void PDFCreateBitonalDocumentDialog::onCreateBitonalDocumentButtonClicked()
{
Q_ASSERT(!m_conversionInProgress);
Q_ASSERT(!m_future.isRunning());
m_conversionMethod = ui->automaticThresholdRadioButton->isChecked() ? pdf::PDFImageConversion::ConversionMethod::Automatic : pdf::PDFImageConversion::ConversionMethod::Manual;
m_manualThreshold = ui->thresholdEditBox->value();
m_conversionInProgress = true;
m_future = QtConcurrent::run([this]() { createBitonalDocument(); });
m_futureWatcher.emplace();
connect(&m_futureWatcher.value(), &QFutureWatcher<void>::finished, this, &PDFCreateBitonalDocumentDialog::onPerformFinished);
m_futureWatcher->setFuture(m_future);
updateUi();
}
void PDFCreateBitonalDocumentDialog::loadImages()
{
QSize iconSize(QSize(256, 256));
ui->imageListWidget->setIconSize(iconSize);
QSize imageSize = iconSize * ui->imageListWidget->devicePixelRatioF();
for (pdf::PDFObjectReference reference : m_imageReferences)
{
std::optional<pdf::PDFImage> pdfImage = getImageFromReference(reference);
if (!pdfImage)
{
continue;
}
pdf::PDFCMSGeneric genericCms;
pdf::PDFRenderErrorReporterDummy errorReporter;
QImage image;
try
{
image = pdfImage->getImage(&genericCms, &errorReporter, nullptr);
}
catch (pdf::PDFException)
{
// Do nothing
}
if (image.isNull())
{
continue;
}
QListWidgetItem* item = new QListWidgetItem(ui->imageListWidget);
image = image.scaled(imageSize.width(), imageSize.height(), Qt::KeepAspectRatio, Qt::FastTransformation);
item->setIcon(QIcon(QPixmap::fromImage(image)));
Qt::ItemFlags flags = item->flags();
flags.setFlag(Qt::ItemIsEditable, true);
item->setFlags(flags);
ImageConversionInfo imageConversionInfo;
imageConversionInfo.imageReference = reference;
imageConversionInfo.conversionEnabled = true;
m_imagesToBeConverted.push_back(imageConversionInfo);
}
}
void PDFCreateBitonalDocumentDialog::updateUi()
{
ui->thresholdEditBox->setEnabled(ui->manualThresholdRadioButton->isChecked());
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(m_processed && !m_conversionInProgress);
ui->buttonBox->button(QDialogButtonBox::Cancel)->setEnabled(!m_conversionInProgress);
m_createBitonalDocumentButton->setEnabled(!m_conversionInProgress);
}
void PDFCreateBitonalDocumentDialog::updatePreview()
{
QModelIndex index = ui->imageListWidget->currentIndex();
m_previewImageLeft = QImage();
m_previewImageRight = QImage();
if (index.isValid())
{
const ImageConversionInfo& info = m_imagesToBeConverted.at(index.row());
std::optional<pdf::PDFImage> pdfImage = getImageFromReference(info.imageReference);
Q_ASSERT(pdfImage);
pdf::PDFCMSGeneric cmsGeneric;
pdf::PDFRenderErrorReporterDummy reporter;
QImage image = pdfImage->getImage(&cmsGeneric, &reporter, nullptr);
pdf::PDFImageConversion imageConversion;
imageConversion.setConversionMethod(ui->automaticThresholdRadioButton->isChecked() ? pdf::PDFImageConversion::ConversionMethod::Automatic : pdf::PDFImageConversion::ConversionMethod::Manual);
imageConversion.setThreshold(ui->thresholdEditBox->value());
imageConversion.setImage(image);
if (imageConversion.convert())
{
m_previewImageLeft = image;
m_previewImageRight = imageConversion.getConvertedImage();
}
}
m_leftPreviewWidget->setImage(m_previewImageLeft);
m_rightPreviewWidget->setImage(m_previewImageRight);
}
std::optional<pdf::PDFImage> PDFCreateBitonalDocumentDialog::getImageFromReference(pdf::PDFObjectReference reference) const
{
std::optional<pdf::PDFImage> pdfImage;
pdf::PDFObject imageObject = m_document->getObjectByReference(reference);
pdf::PDFRenderErrorReporterDummy errorReporter;
if (!imageObject.isStream())
{
// Image is not stream
return pdfImage;
}
const pdf::PDFStream* stream = imageObject.getStream();
try
{
pdf::PDFColorSpacePointer colorSpace;
const pdf::PDFDictionary* streamDictionary = stream->getDictionary();
if (streamDictionary->hasKey("ColorSpace"))
{
const pdf::PDFObject& colorSpaceObject = m_document->getObject(streamDictionary->get("ColorSpace"));
if (colorSpaceObject.isName() || colorSpaceObject.isArray())
{
pdf::PDFDictionary dummyDictionary;
colorSpace = pdf::PDFAbstractColorSpace::createColorSpace(&dummyDictionary, m_document, colorSpaceObject);
}
}
pdfImage.emplace(pdf::PDFImage::createImage(m_document,
stream,
colorSpace,
false,
pdf::RenderingIntent::Perceptual,
&errorReporter));
}
catch (pdf::PDFException)
{
// Do nothing
}
return pdfImage;
}
} // namespace pdfviewer

View File

@@ -1,115 +0,0 @@
// Copyright (C) 2023 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#ifndef PDFCREATEBITONALDOCUMENTDIALOG_H
#define PDFCREATEBITONALDOCUMENTDIALOG_H
#include "pdfcms.h"
#include "pdfdocument.h"
#include "pdfobjectutils.h"
#include "pdfimage.h"
#include "pdfimageconversion.h"
#include "pdfprogress.h"
#include <QDialog>
#include <QFuture>
#include <QFutureWatcher>
namespace Ui
{
class PDFCreateBitonalDocumentDialog;
}
namespace pdfviewer
{
class PDFCreateBitonalDocumentPreviewWidget : public QWidget
{
Q_OBJECT
public:
PDFCreateBitonalDocumentPreviewWidget(QWidget* parent);
virtual ~PDFCreateBitonalDocumentPreviewWidget() override;
virtual void paintEvent(QPaintEvent* event) override;
void setCaption(QString caption);
void setImage(QImage image);
private:
QString m_caption;
QImage m_image;
};
class PDFCreateBitonalDocumentDialog : public QDialog
{
Q_OBJECT
public:
explicit PDFCreateBitonalDocumentDialog(const pdf::PDFDocument* document,
const pdf::PDFCMS* cms,
pdf::PDFProgress* progress,
QWidget* parent);
virtual ~PDFCreateBitonalDocumentDialog() override;
pdf::PDFDocument takeBitonaldDocument() { return qMove(m_bitonalDocument); }
struct ImageConversionInfo
{
pdf::PDFObjectReference imageReference;
bool conversionEnabled = true;
};
private:
void createBitonalDocument();
void onCreateBitonalDocumentButtonClicked();
void onPerformFinished();
void loadImages();
void updateUi();
void updatePreview();
std::optional<pdf::PDFImage> getImageFromReference(pdf::PDFObjectReference reference) const;
Ui::PDFCreateBitonalDocumentDialog* ui;
const pdf::PDFDocument* m_document;
const pdf::PDFCMS* m_cms;
QPushButton* m_createBitonalDocumentButton;
bool m_conversionInProgress;
bool m_processed;
QFuture<void> m_future;
std::optional<QFutureWatcher<void>> m_futureWatcher;
pdf::PDFDocument m_bitonalDocument;
pdf::PDFObjectClassifier m_classifier;
std::vector<pdf::PDFObjectReference> m_imageReferences;
std::vector<ImageConversionInfo> m_imagesToBeConverted;
QImage m_previewImageLeft;
QImage m_previewImageRight;
PDFCreateBitonalDocumentPreviewWidget* m_leftPreviewWidget;
PDFCreateBitonalDocumentPreviewWidget* m_rightPreviewWidget;
pdf::PDFProgress* m_progress;
pdf::PDFImageConversion::ConversionMethod m_conversionMethod = pdf::PDFImageConversion::ConversionMethod::Automatic;
int m_manualThreshold = 128;
};
} // namespace pdfviewer
#endif // PDFCREATEBITONALDOCUMENTDIALOG_H

View File

@@ -1,110 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PDFCreateBitonalDocumentDialog</class>
<widget class="QDialog" name="PDFCreateBitonalDocumentDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>741</width>
<height>530</height>
</rect>
</property>
<property name="windowTitle">
<string>Create Bitonal Document</string>
</property>
<layout class="QGridLayout" name="mainGridLayout" rowstretch="0,1,0" columnstretch="2,1,1">
<item row="2" column="0" colspan="3">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QGroupBox" name="createBitonalSettingsGroupBox">
<property name="title">
<string>Color to Bitonal Conversion Options</string>
</property>
<layout class="QGridLayout" name="optionsGridLayout">
<item row="0" column="0">
<widget class="QRadioButton" name="automaticThresholdRadioButton">
<property name="text">
<string>Automatic (Otsu's 1D method)</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="thresholdEditBox">
<property name="maximum">
<number>255</number>
</property>
<property name="value">
<number>128</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QRadioButton" name="manualThresholdRadioButton">
<property name="text">
<string>User-Defined Intensity Threshold (0-255):</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="0" rowspan="2">
<widget class="QListWidget" name="imageListWidget">
<property name="resizeMode">
<enum>QListView::Adjust</enum>
</property>
<property name="viewMode">
<enum>QListView::IconMode</enum>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>PDFCreateBitonalDocumentDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>370</x>
<y>508</y>
</hint>
<hint type="destinationlabel">
<x>370</x>
<y>264</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>PDFCreateBitonalDocumentDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>370</x>
<y>508</y>
</hint>
<hint type="destinationlabel">
<x>370</x>
<y>264</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -1,608 +0,0 @@
// Copyright (C) 2019-2022 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#include "pdfdocumentpropertiesdialog.h"
#include "ui_pdfdocumentpropertiesdialog.h"
#include "pdfdocument.h"
#include "pdfwidgetutils.h"
#include "pdffont.h"
#include "pdfutils.h"
#include "pdfexception.h"
#include "pdfexecutionpolicy.h"
#include <QLocale>
#include <QPageSize>
#include <QtConcurrent/QtConcurrent>
#include "pdfdbgheap.h"
#include <stack>
#include <execution>
namespace pdfviewer
{
class PDFTreeFactory : public pdf::ITreeFactory
{
public:
PDFTreeFactory(QTreeWidgetItem* root)
{
m_roots.push(root);
}
// ITreeFactory interface
virtual void pushItem(QStringList texts) override;
virtual void addItem(QStringList texts) override;
virtual void popItem() override;
private:
std::stack<QTreeWidgetItem*> m_roots;
};
void PDFTreeFactory::pushItem(QStringList texts)
{
Q_ASSERT(!m_roots.empty());
m_roots.push(new QTreeWidgetItem(m_roots.top(), texts));
}
void PDFTreeFactory::addItem(QStringList texts)
{
Q_ASSERT(!m_roots.empty());
new QTreeWidgetItem(m_roots.top(), texts);
}
void PDFTreeFactory::popItem()
{
Q_ASSERT(!m_roots.empty());
m_roots.pop();
}
PDFDocumentPropertiesDialog::PDFDocumentPropertiesDialog(const pdf::PDFDocument* document,
const PDFFileInfo* fileInfo,
QWidget* parent) :
QDialog(parent),
ui(new Ui::PDFDocumentPropertiesDialog)
{
ui->setupUi(this);
initializeProperties(document);
initializeFileInfoProperties(fileInfo);
initializeSecurity(document);
initializeFonts(document);
initializeDisplayAndPrintSettings(document);
const int minimumSectionSize = pdf::PDFWidgetUtils::scaleDPI_x(this, 300);
for (QTreeWidget* widget : findChildren<QTreeWidget*>(QString(), Qt::FindChildrenRecursively))
{
widget->header()->setMinimumSectionSize(minimumSectionSize);
}
pdf::PDFWidgetUtils::scaleWidget(this, QSize(750, 600));
pdf::PDFWidgetUtils::style(this);
}
PDFDocumentPropertiesDialog::~PDFDocumentPropertiesDialog()
{
Q_ASSERT(m_fontTreeWidgetItems.empty());
delete ui;
}
void PDFDocumentPropertiesDialog::initializeProperties(const pdf::PDFDocument* document)
{
QLocale locale;
// Initialize document properties
QTreeWidgetItem* propertiesRoot = new QTreeWidgetItem({ tr("Properties") });
const pdf::PDFDocumentInfo* info = document->getInfo();
const pdf::PDFCatalog* catalog = document->getCatalog();
new QTreeWidgetItem(propertiesRoot, { tr("PDF version"), QString::fromLatin1(document->getVersion()) });
new QTreeWidgetItem(propertiesRoot, { tr("Title"), info->title });
new QTreeWidgetItem(propertiesRoot, { tr("Subject"), info->subject });
new QTreeWidgetItem(propertiesRoot, { tr("Author"), info->author });
new QTreeWidgetItem(propertiesRoot, { tr("Keywords"), info->keywords });
new QTreeWidgetItem(propertiesRoot, { tr("Creator"), info->creator });
new QTreeWidgetItem(propertiesRoot, { tr("Producer"), info->producer });
new QTreeWidgetItem(propertiesRoot, { tr("Creation date"), locale.toString(info->creationDate) });
new QTreeWidgetItem(propertiesRoot, { tr("Modified date"), locale.toString(info->modifiedDate) });
QString trapped;
switch (info->trapped)
{
case pdf::PDFDocumentInfo::Trapped::True:
trapped = tr("Yes");
break;
case pdf::PDFDocumentInfo::Trapped::False:
trapped = tr("No");
break;
case pdf::PDFDocumentInfo::Trapped::Unknown:
trapped = tr("Unknown");
break;
default:
Q_ASSERT(false);
break;
}
QTreeWidgetItem* contentRoot = new QTreeWidgetItem({ tr("Content") });
const pdf::PDFInteger pageCount = catalog->getPageCount();
new QTreeWidgetItem(contentRoot, { tr("Page count"), locale.toString(pageCount) });
if (pageCount > 0)
{
const pdf::PDFPage* firstPage = catalog->getPage(0);
QSizeF pageSizeMM = firstPage->getRectMM(firstPage->getRotatedMediaBox()).size();
QPageSize pageSize(pageSizeMM, QPageSize::Millimeter, QString(), QPageSize::FuzzyOrientationMatch);
QString paperSizeString = QString("%1 x %2 mm").arg(locale.toString(pageSizeMM.width()), locale.toString(pageSizeMM.height()));
new QTreeWidgetItem(contentRoot, { tr("Paper format"), pageSize.name() });
new QTreeWidgetItem(contentRoot, { tr("Paper size"), paperSizeString });
}
new QTreeWidgetItem(contentRoot, { tr("Trapped"), trapped });
ui->propertiesTreeWidget->addTopLevelItem(propertiesRoot);
ui->propertiesTreeWidget->addTopLevelItem(contentRoot);
if (!info->extra.empty())
{
QTreeWidgetItem* customRoot = new QTreeWidgetItem({ tr("Custom properties") });
for (const auto& item : info->extra)
{
QString key = QString::fromLatin1(item.first);
QVariant valueVariant = item.second;
QString value = (valueVariant.typeId() == QMetaType::QDateTime) ? locale.toString(valueVariant.toDateTime()) : valueVariant.toString();
new QTreeWidgetItem(customRoot, { key, value });
}
ui->propertiesTreeWidget->addTopLevelItem(customRoot);
}
ui->propertiesTreeWidget->expandAll();
ui->propertiesTreeWidget->resizeColumnToContents(0);
}
void PDFDocumentPropertiesDialog::initializeFileInfoProperties(const PDFFileInfo* fileInfo)
{
QLocale locale;
// Initialize document file info
QTreeWidgetItem* fileInfoRoot = new QTreeWidgetItem({ tr("File information") });
new QTreeWidgetItem(fileInfoRoot, { tr("Name"), fileInfo->fileName });
new QTreeWidgetItem(fileInfoRoot, { tr("Directory"), fileInfo->path });
new QTreeWidgetItem(fileInfoRoot, { tr("Writable"), fileInfo->writable ? tr("Yes") : tr("No") });
QString fileSize;
if (fileInfo->fileSize > 1024 * 1024)
{
fileSize = QString("%1 MB (%2 bytes)").arg(locale.toString(fileInfo->fileSize / (1024.0 * 1024.0)), locale.toString(fileInfo->fileSize));
}
else
{
fileSize = QString("%1 kB (%2 bytes)").arg(locale.toString(fileInfo->fileSize / 1024.0), locale.toString(fileInfo->fileSize));
}
new QTreeWidgetItem(fileInfoRoot, { tr("Size"), fileSize });
new QTreeWidgetItem(fileInfoRoot, { tr("Created date"), locale.toString(fileInfo->creationTime) });
new QTreeWidgetItem(fileInfoRoot, { tr("Modified date"), locale.toString(fileInfo->lastModifiedTime) });
new QTreeWidgetItem(fileInfoRoot, { tr("Last read date"), locale.toString(fileInfo->lastReadTime) });
ui->fileInfoTreeWidget->addTopLevelItem(fileInfoRoot);
ui->fileInfoTreeWidget->expandAll();
ui->fileInfoTreeWidget->resizeColumnToContents(0);
}
void PDFDocumentPropertiesDialog::initializeSecurity(const pdf::PDFDocument* document)
{
QLocale locale;
QTreeWidgetItem* securityRoot = new QTreeWidgetItem({ tr("Security") });
const pdf::PDFSecurityHandler* securityHandler = document->getStorage().getSecurityHandler();
const pdf::EncryptionMode mode = securityHandler->getMode();
QString modeString;
switch (mode)
{
case pdf::EncryptionMode::None:
modeString = tr("None");
break;
case pdf::EncryptionMode::Standard:
modeString = tr("Standard");
break;
case pdf::EncryptionMode::PublicKey:
modeString = tr("Public Key");
break;
case pdf::EncryptionMode::Custom:
modeString = tr("Custom");
break;
default:
Q_ASSERT(false);
break;
}
QString authorizationMode;
switch (securityHandler->getAuthorizationResult())
{
case pdf::PDFSecurityHandler::AuthorizationResult::NoAuthorizationRequired:
authorizationMode = tr("No authorization required");
break;
case pdf::PDFSecurityHandler::AuthorizationResult::OwnerAuthorized:
authorizationMode = tr("Authorized as owner");
break;
case pdf::PDFSecurityHandler::AuthorizationResult::UserAuthorized:
authorizationMode = tr("Authorized as user");
break;
default:
Q_ASSERT(false);
break;
}
new QTreeWidgetItem(securityRoot, { tr("Document encryption"), modeString });
new QTreeWidgetItem(securityRoot, { tr("Authorized as"), authorizationMode });
if (securityHandler->getAuthorizationResult() != pdf::PDFSecurityHandler::AuthorizationResult::NoAuthorizationRequired)
{
new QTreeWidgetItem(securityRoot, { tr("Metadata encrypted"), securityHandler->isMetadataEncrypted() ? tr("Yes") : tr("No") });
new QTreeWidgetItem(securityRoot, { tr("Version"), locale.toString(securityHandler->getVersion()) });
}
QTreeWidgetItem* permissionsRoot = new QTreeWidgetItem({ tr("Permissions") });
auto addPermissionInfo = [securityHandler, permissionsRoot](QString caption, pdf::PDFSecurityHandler::Permission permission)
{
new QTreeWidgetItem(permissionsRoot, { caption, securityHandler->isAllowed(permission) ? tr("Yes") : tr("No")});
};
addPermissionInfo(tr("Print (low resolution)"), pdf::PDFSecurityHandler::Permission::PrintLowResolution);
addPermissionInfo(tr("Print (high resolution)"), pdf::PDFSecurityHandler::Permission::PrintHighResolution);
addPermissionInfo(tr("Content extraction"), pdf::PDFSecurityHandler::Permission::CopyContent);
addPermissionInfo(tr("Content extraction (accessibility)"), pdf::PDFSecurityHandler::Permission::Accessibility);
addPermissionInfo(tr("Page assembling"), pdf::PDFSecurityHandler::Permission::Assemble);
addPermissionInfo(tr("Modify content"), pdf::PDFSecurityHandler::Permission::Modify);
addPermissionInfo(tr("Modify interactive items"), pdf::PDFSecurityHandler::Permission::ModifyInteractiveItems);
addPermissionInfo(tr("Fill form fields"), pdf::PDFSecurityHandler::Permission::ModifyFormFields);
ui->securityTreeWidget->addTopLevelItem(securityRoot);
ui->securityTreeWidget->addTopLevelItem(permissionsRoot);
ui->securityTreeWidget->expandAll();
ui->securityTreeWidget->resizeColumnToContents(0);
}
void PDFDocumentPropertiesDialog::initializeFonts(const pdf::PDFDocument* document)
{
auto createFontInfo = [this, document]()
{
pdf::PDFInteger pageCount = document->getCatalog()->getPageCount();
QMutex fontTreeItemMutex;
QMutex usedFontReferencesMutex;
std::set<pdf::PDFObjectReference> usedFontReferences;
auto processPage = [&](pdf::PDFInteger pageIndex)
{
try
{
const pdf::PDFPage* page = document->getCatalog()->getPage(pageIndex);
if (const pdf::PDFDictionary* resourcesDictionary = document->getDictionaryFromObject(page->getResources()))
{
if (const pdf::PDFDictionary* fontsDictionary = document->getDictionaryFromObject(resourcesDictionary->get("Font")))
{
// Iterate trough each font
const size_t fontsCount = fontsDictionary->getCount();
for (size_t i = 0; i < fontsCount; ++i)
{
pdf::PDFObject object = fontsDictionary->getValue(i);
if (object.isReference())
{
// Check, if we have not processed the object. If we have it processed,
// then do nothing, otherwise insert it into the processed objects.
// We must also use mutex, because we use multithreading.
QMutexLocker lock(&usedFontReferencesMutex);
if (usedFontReferences.count(object.getReference()))
{
continue;
}
else
{
usedFontReferences.insert(object.getReference());
}
}
try
{
if (pdf::PDFFontPointer font = pdf::PDFFont::createFont(object, document))
{
pdf::PDFRenderErrorReporterDummy dummyReporter;
pdf::PDFRealizedFontPointer realizedFont = pdf::PDFRealizedFont::createRealizedFont(font, 8.0, &dummyReporter);
if (realizedFont)
{
const pdf::FontType fontType = font->getFontType();
const pdf::FontDescriptor* fontDescriptor = font->getFontDescriptor();
QString fontName = fontDescriptor->fontName;
// Try to remove characters from +, if we have font name 'SDFDSF+ValidFontName'
int plusPos = fontName.lastIndexOf('+');
if (plusPos != -1 && plusPos < fontName.size() - 1)
{
fontName = fontName.mid(plusPos + 1);
}
if (fontName.isEmpty())
{
fontName = QString::fromLatin1(fontsDictionary->getKey(i).getString());
}
std::unique_ptr<QTreeWidgetItem> fontRootItemPtr = std::make_unique<QTreeWidgetItem>(QStringList({ fontName }));
QTreeWidgetItem* fontRootItem = fontRootItemPtr.get();
QString fontTypeString;
switch (fontType)
{
case pdf::FontType::TrueType:
fontTypeString = tr("TrueType");
break;
case pdf::FontType::Type0:
fontTypeString = tr("Type0 (CID keyed)");
break;
case pdf::FontType::Type1:
fontTypeString = tr("Type1 (8 bit keyed)");
break;
case pdf::FontType::MMType1:
fontTypeString = tr("MMType1 (8 bit keyed)");
break;
case pdf::FontType::Type3:
fontTypeString = tr("Type3 (content streams for font glyphs)");
break;
default:
Q_ASSERT(false);
break;
}
new QTreeWidgetItem(fontRootItem, { tr("Type"), fontTypeString });
if (!fontDescriptor->fontFamily.isEmpty())
{
new QTreeWidgetItem(fontRootItem, { tr("Font family"), fontDescriptor->fontFamily });
}
new QTreeWidgetItem(fontRootItem, { tr("Embedded subset"), fontDescriptor->getEmbeddedFontData() ? tr("Yes") : tr("No") });
PDFTreeFactory treeFactory1(fontRootItem);
font->dumpFontToTreeItem(&treeFactory1);
PDFTreeFactory treeFactory2(fontRootItem);
realizedFont->dumpFontToTreeItem(&treeFactory2);
// Separator item
new QTreeWidgetItem(fontRootItem, QStringList());
// Finally add the tree item
QMutexLocker lock(&fontTreeItemMutex);
m_fontTreeWidgetItems.push_back(fontRootItemPtr.release());
}
}
}
catch (const pdf::PDFException &)
{
// Do nothing, some error occured, continue with next font
continue;
}
}
}
}
}
catch (const pdf::PDFException &)
{
// Do nothing, some error occured
}
};
pdf::PDFIntegerRange<pdf::PDFInteger> indices(pdf::PDFInteger(0), pageCount);
pdf::PDFExecutionPolicy::execute(pdf::PDFExecutionPolicy::Scope::Page, indices.begin(), indices.end(), processPage);
};
m_future = QtConcurrent::run(createFontInfo);
connect(&m_futureWatcher, &QFutureWatcher<void>::finished, this, &PDFDocumentPropertiesDialog::onFontsFinished);
m_futureWatcher.setFuture(m_future);
}
void PDFDocumentPropertiesDialog::initializeDisplayAndPrintSettings(const pdf::PDFDocument* document)
{
const pdf::PDFCatalog* catalog = document->getCatalog();
pdf::PageLayout pageLayout = catalog->getPageLayout();
pdf::PageMode pageMode = catalog->getPageMode();
const pdf::PDFViewerPreferences* viewerPreferences = catalog->getViewerPreferences();
QTreeWidgetItem* viewerSettingsRoot = new QTreeWidgetItem({ tr("Viewer settings") });
QTreeWidgetItem* printerSettingsRoot = new QTreeWidgetItem({ tr("Default printer settings") });
QString pageLayoutString;
switch (pageLayout)
{
case pdf::PageLayout::SinglePage:
pageLayoutString = tr("Single page");
break;
case pdf::PageLayout::OneColumn:
pageLayoutString = tr("Continuous column");
break;
case pdf::PageLayout::TwoColumnLeft:
case pdf::PageLayout::TwoColumnRight:
pageLayoutString = tr("Two continuous columns");
break;
case pdf::PageLayout::TwoPagesLeft:
case pdf::PageLayout::TwoPagesRight:
pageLayoutString = tr("Two pages");
break;
default:
Q_ASSERT(false);
break;
}
QString pageModeString;
switch (pageMode)
{
case pdf::PageMode::UseNone:
pageModeString = tr("Default");
break;
case pdf::PageMode::UseOutlines:
pageModeString = tr("Show outlines");
break;
case pdf::PageMode::UseThumbnails:
pageModeString = tr("Show thumbnails");
break;
case pdf::PageMode::Fullscreen:
pageModeString = tr("Fullscreen");
break;
case pdf::PageMode::UseOptionalContent:
pageModeString = tr("Show optional content");
break;
case pdf::PageMode::UseAttachments:
pageModeString = tr("Show attachments");
break;
default:
Q_ASSERT(false);
break;
}
QString directionString;
switch (viewerPreferences->getDirection())
{
case pdf::PDFViewerPreferences::Direction::LeftToRight:
directionString = tr("Left to right");
break;
case pdf::PDFViewerPreferences::Direction::RightToLeft:
directionString = tr("Right to left");
break;
default:
Q_ASSERT(false);
break;
}
new QTreeWidgetItem(viewerSettingsRoot, { tr("Page layout"), pageLayoutString });
new QTreeWidgetItem(viewerSettingsRoot, { tr("View mode"), pageModeString });
new QTreeWidgetItem(viewerSettingsRoot, { tr("Writing direction"), directionString });
QString printScalingString;
switch (viewerPreferences->getPrintScaling())
{
case pdf::PDFViewerPreferences::PrintScaling::None:
printScalingString = tr("None");
break;
case pdf::PDFViewerPreferences::PrintScaling::AppDefault:
printScalingString = tr("Application default");
break;
default:
Q_ASSERT(false);
break;
}
new QTreeWidgetItem(printerSettingsRoot, { tr("Scale"), printScalingString });
QString duplexString;
switch (viewerPreferences->getDuplex())
{
case pdf::PDFViewerPreferences::Duplex::None:
duplexString = tr("None");
break;
case pdf::PDFViewerPreferences::Duplex::Simplex:
duplexString = tr("Simplex");
break;
case pdf::PDFViewerPreferences::Duplex::DuplexFlipLongEdge:
duplexString = tr("Duplex (flip long edge)");
break;
case pdf::PDFViewerPreferences::Duplex::DuplexFlipShortEdge:
duplexString = tr("Duplex (flip long edge)");
break;
default:
Q_ASSERT(false);
break;
}
new QTreeWidgetItem(printerSettingsRoot, { tr("Duplex mode"), duplexString });
new QTreeWidgetItem(printerSettingsRoot, { tr("Pick tray by page size"), viewerPreferences->getOptions().testFlag(pdf::PDFViewerPreferences::PickTrayByPDFSize) ? tr("Yes") : tr("No") });
QStringList pageRanges;
for (const std::pair<pdf::PDFInteger, pdf::PDFInteger>& pageRange : viewerPreferences->getPrintPageRanges())
{
pageRanges << QString("%1-%2").arg(pageRange.first).arg(pageRange.second);
}
QString pageRangesString = pageRanges.join(",");
new QTreeWidgetItem(printerSettingsRoot, { tr("Default print page ranges"), pageRangesString });
new QTreeWidgetItem(printerSettingsRoot, { tr("Number of copies"), QString::number(viewerPreferences->getNumberOfCopies()) });
ui->displayAndPrintTreeWidget->addTopLevelItem(viewerSettingsRoot);
ui->displayAndPrintTreeWidget->addTopLevelItem(printerSettingsRoot);
ui->displayAndPrintTreeWidget->expandAll();
ui->displayAndPrintTreeWidget->resizeColumnToContents(0);
}
void PDFDocumentPropertiesDialog::onFontsFinished()
{
if (!m_fontTreeWidgetItems.empty())
{
std::sort(m_fontTreeWidgetItems.begin(), m_fontTreeWidgetItems.end(), [](QTreeWidgetItem* left, QTreeWidgetItem* right) { return left->data(0, Qt::DisplayRole).toString() < right->data(0, Qt::DisplayRole).toString(); });
for (QTreeWidgetItem* item : m_fontTreeWidgetItems)
{
ui->fontsTreeWidget->addTopLevelItem(item);
}
m_fontTreeWidgetItems.clear();
ui->fontsTreeWidget->collapseAll();
ui->fontsTreeWidget->expandToDepth(0);
ui->fontsTreeWidget->resizeColumnToContents(0);
}
}
void PDFDocumentPropertiesDialog::closeEvent(QCloseEvent* event)
{
// We must wait for finishing of font loading;
m_futureWatcher.waitForFinished();
// We must delete all font tree items, because of asynchronous signal sent
qDeleteAll(m_fontTreeWidgetItems);
m_fontTreeWidgetItems.clear();
BaseClass::closeEvent(event);
}
} // namespace pdfviewer

View File

@@ -1,90 +0,0 @@
// Copyright (C) 2019-2021 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#ifndef PDFDOCUMENTPROPERTIESDIALOG_H
#define PDFDOCUMENTPROPERTIESDIALOG_H
#include "pdfglobal.h"
#include <QDialog>
#include <QFuture>
#include <QFutureWatcher>
#include <QDateTime>
class QTreeWidgetItem;
namespace Ui
{
class PDFDocumentPropertiesDialog;
}
namespace pdf
{
class PDFDocument;
}
namespace pdfviewer
{
struct PDFFileInfo
{
QString originalFileName;
QString absoluteFilePath;
QString fileName;
QString path;
pdf::PDFInteger fileSize = 0;
bool writable = false;
QDateTime creationTime;
QDateTime lastModifiedTime;
QDateTime lastReadTime;
};
class PDFDocumentPropertiesDialog : public QDialog
{
Q_OBJECT
private:
using BaseClass = QDialog;
public:
explicit PDFDocumentPropertiesDialog(const pdf::PDFDocument* document,
const PDFFileInfo* fileInfo,
QWidget* parent);
virtual ~PDFDocumentPropertiesDialog() override;
protected:
virtual void closeEvent(QCloseEvent* event) override;
private:
Ui::PDFDocumentPropertiesDialog* ui;
void initializeProperties(const pdf::PDFDocument* document);
void initializeFileInfoProperties(const PDFFileInfo* fileInfo);
void initializeSecurity(const pdf::PDFDocument* document);
void initializeFonts(const pdf::PDFDocument* document);
void initializeDisplayAndPrintSettings(const pdf::PDFDocument* document);
void onFontsFinished();
std::vector<QTreeWidgetItem*> m_fontTreeWidgetItems;
QFuture<void> m_future;
QFutureWatcher<void> m_futureWatcher;
};
} // namespace pdfviewer
#endif // PDFDOCUMENTPROPERTIESDIALOG_H

View File

@@ -1,244 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PDFDocumentPropertiesDialog</class>
<widget class="QDialog" name="PDFDocumentPropertiesDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>807</width>
<height>609</height>
</rect>
</property>
<property name="windowTitle">
<string>Document Properties</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="propertiesTab">
<attribute name="title">
<string>Properties</string>
</attribute>
<layout class="QVBoxLayout" name="propertiesLayout" stretch="3,2">
<item>
<widget class="QGroupBox" name="propertiesGroupBox">
<property name="title">
<string>Properties</string>
</property>
<layout class="QVBoxLayout" name="propertiesGroupBoxLayout">
<item>
<widget class="QTreeWidget" name="propertiesTreeWidget">
<property name="columnCount">
<number>2</number>
</property>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
<column>
<property name="text">
<string notr="true">2</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="fileInfoGroupBox">
<property name="title">
<string>File Information</string>
</property>
<layout class="QVBoxLayout" name="fileInfoGroupBoxLayout">
<item>
<widget class="QTreeWidget" name="fileInfoTreeWidget">
<property name="columnCount">
<number>2</number>
</property>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
<column>
<property name="text">
<string notr="true">2</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="securityTab">
<attribute name="title">
<string>Security</string>
</attribute>
<layout class="QVBoxLayout" name="securityTabLayout">
<item>
<widget class="QGroupBox" name="securityGroupBox">
<property name="title">
<string>Security</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QTreeWidget" name="securityTreeWidget">
<property name="columnCount">
<number>2</number>
</property>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
<column>
<property name="text">
<string notr="true">2</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="fontsTab">
<attribute name="title">
<string>Fonts</string>
</attribute>
<layout class="QVBoxLayout" name="fontsTabLayout">
<item>
<widget class="QGroupBox" name="fontsGroupBox">
<property name="title">
<string>Fonts</string>
</property>
<layout class="QVBoxLayout" name="fontsGroupBoxLayout">
<item>
<widget class="QTreeWidget" name="fontsTreeWidget">
<property name="columnCount">
<number>2</number>
</property>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
<column>
<property name="text">
<string notr="true">2</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="displayAndPrintTab">
<attribute name="title">
<string>Display &amp;&amp; Print</string>
</attribute>
<layout class="QVBoxLayout" name="displayAndPrintPageLayout">
<item>
<widget class="QGroupBox" name="displayAndPrintGroupBox">
<property name="title">
<string>Display &amp;&amp; Print Settings</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QTreeWidget" name="displayAndPrintTreeWidget">
<property name="columnCount">
<number>2</number>
</property>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
<column>
<property name="text">
<string notr="true">2</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>PDFDocumentPropertiesDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>PDFDocumentPropertiesDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -1,261 +0,0 @@
// Copyright (C) 2021-2022 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#include "pdfencryptionsettingsdialog.h"
#include "ui_pdfencryptionsettingsdialog.h"
#include "pdfencryptionstrengthhintwidget.h"
#include "pdfutils.h"
#include "pdfwidgetutils.h"
#include "pdfsecurityhandler.h"
#include "pdfcertificatemanager.h"
#include "pdfcertificatelisthelper.h"
#include <QMessageBox>
#include "pdfdbgheap.h"
namespace pdfviewer
{
PDFEncryptionSettingsDialog::PDFEncryptionSettingsDialog(QByteArray documentId, QWidget* parent) :
QDialog(parent),
ui(new Ui::PDFEncryptionSettingsDialog),
m_isUpdatingUi(false),
m_documentId(documentId),
m_userPasswordStrengthHintWidget(new PDFEncryptionStrengthHintWidget(this)),
m_ownerPasswordStrengthHintWidget(new PDFEncryptionStrengthHintWidget(this)),
m_algorithmHintWidget(new PDFEncryptionStrengthHintWidget(this))
{
ui->setupUi(this);
ui->algorithmComboBox->addItem(tr("None"), int(pdf::PDFSecurityHandlerFactory::None));
ui->algorithmComboBox->addItem(tr("RC4 128-bit | R4"), int(pdf::PDFSecurityHandlerFactory::RC4));
ui->algorithmComboBox->addItem(tr("AES 128-bit | R4"), int(pdf::PDFSecurityHandlerFactory::AES_128));
ui->algorithmComboBox->addItem(tr("AES 256-bit | R6"), int(pdf::PDFSecurityHandlerFactory::AES_256));
ui->algorithmComboBox->addItem(tr("Certificate Encryption"), int(pdf::PDFSecurityHandlerFactory::Certificate));
ui->algorithmComboBox->setCurrentIndex(0);
m_algorithmHintWidget->setFixedSize(m_algorithmHintWidget->minimumSizeHint());
m_userPasswordStrengthHintWidget->setFixedSize(m_userPasswordStrengthHintWidget->minimumSizeHint());
m_ownerPasswordStrengthHintWidget->setFixedSize(m_userPasswordStrengthHintWidget->minimumSizeHint());
ui->passwordsGroupBoxLayout->addWidget(m_userPasswordStrengthHintWidget, 0, 2);
ui->passwordsGroupBoxLayout->addWidget(m_ownerPasswordStrengthHintWidget, 1, 2);
ui->methodGroupBoxLayout->addWidget(m_algorithmHintWidget, 0, 2);
m_algorithmHintWidget->setMinValue(1);
m_algorithmHintWidget->setMaxValue(5);
const int passwordOptimalEntropy = pdf::PDFSecurityHandlerFactory::getPasswordOptimalEntropy();
m_userPasswordStrengthHintWidget->setMinValue(0);
m_userPasswordStrengthHintWidget->setMaxValue(passwordOptimalEntropy);
m_ownerPasswordStrengthHintWidget->setMinValue(0);
m_ownerPasswordStrengthHintWidget->setMaxValue(passwordOptimalEntropy);
connect(ui->algorithmComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &PDFEncryptionSettingsDialog::updateUi);
connect(ui->userPasswordEnableCheckBox, &QCheckBox::clicked, this, &PDFEncryptionSettingsDialog::updateUi);
connect(ui->ownerPasswordEnableCheckBox, &QCheckBox::clicked, this, &PDFEncryptionSettingsDialog::updateUi);
connect(ui->userPasswordEdit, &QLineEdit::textChanged, this, &PDFEncryptionSettingsDialog::updatePasswordScore);
connect(ui->ownerPasswordEdit, &QLineEdit::textChanged, this, &PDFEncryptionSettingsDialog::updatePasswordScore);
m_checkBoxToPermission[ui->permPrintLowResolutionCheckBox] = pdf::PDFSecurityHandler::Permission::PrintLowResolution;
m_checkBoxToPermission[ui->permModifyDocumentContentsCheckBox] = pdf::PDFSecurityHandler::Permission::Modify;
m_checkBoxToPermission[ui->permCopyContentCheckBox] = pdf::PDFSecurityHandler::Permission::CopyContent;
m_checkBoxToPermission[ui->permInteractiveItemsCheckBox] = pdf::PDFSecurityHandler::Permission::ModifyInteractiveItems;
m_checkBoxToPermission[ui->permFillInteractiveFormsCheckBox] = pdf::PDFSecurityHandler::Permission::ModifyFormFields;
m_checkBoxToPermission[ui->permAccessibilityCheckBox] = pdf::PDFSecurityHandler::Permission::Accessibility;
m_checkBoxToPermission[ui->permAssembleCheckBox] = pdf::PDFSecurityHandler::Permission::Assemble;
m_checkBoxToPermission[ui->permPrintHighResolutionCheckBox] = pdf::PDFSecurityHandler::Permission::PrintHighResolution;
pdf::PDFCertificateListHelper::initComboBox(ui->certificateComboBox);
updateCertificates();
updateUi();
updatePasswordScore();
pdf::PDFWidgetUtils::style(this);
}
PDFEncryptionSettingsDialog::~PDFEncryptionSettingsDialog()
{
delete ui;
}
void PDFEncryptionSettingsDialog::updateUi()
{
if (m_isUpdatingUi)
{
return;
}
pdf::PDFTemporaryValueChange guard(&m_isUpdatingUi, true);
const pdf::PDFSecurityHandlerFactory::Algorithm algorithm = static_cast<pdf::PDFSecurityHandlerFactory::Algorithm>(ui->algorithmComboBox->currentData().toInt());
const bool encrypted = algorithm != pdf::PDFSecurityHandlerFactory::None;
const bool isEncryptedUsingCertificate = algorithm == pdf::PDFSecurityHandlerFactory::Certificate;
switch (algorithm)
{
case pdf::PDFSecurityHandlerFactory::None:
m_algorithmHintWidget->setCurrentValue(1);
break;
case pdf::PDFSecurityHandlerFactory::RC4:
m_algorithmHintWidget->setCurrentValue(2);
break;
case pdf::PDFSecurityHandlerFactory::AES_128:
m_algorithmHintWidget->setCurrentValue(4);
break;
case pdf::PDFSecurityHandlerFactory::AES_256:
case pdf::PDFSecurityHandlerFactory::Certificate:
m_algorithmHintWidget->setCurrentValue(5);
break;
default:
Q_ASSERT(false);
break;
}
ui->certificateComboBox->setEnabled(isEncryptedUsingCertificate);
if (!isEncryptedUsingCertificate)
{
ui->userPasswordEnableCheckBox->setEnabled(encrypted);
ui->ownerPasswordEnableCheckBox->setEnabled(false);
if (!encrypted)
{
ui->userPasswordEnableCheckBox->setChecked(false);
ui->ownerPasswordEnableCheckBox->setChecked(false);
ui->userPasswordEdit->clear();
ui->ownerPasswordEdit->clear();
}
else
{
ui->ownerPasswordEnableCheckBox->setChecked(true);
}
ui->certificateComboBox->setCurrentIndex(-1);
}
else
{
ui->userPasswordEnableCheckBox->setEnabled(false);
ui->ownerPasswordEnableCheckBox->setEnabled(false);
ui->userPasswordEnableCheckBox->setChecked(true);
ui->ownerPasswordEnableCheckBox->setChecked(false);
if (ui->certificateComboBox->currentIndex() == -1 && ui->certificateComboBox->count() > 0)
{
ui->certificateComboBox->setCurrentIndex(0);
}
}
ui->userPasswordEdit->setEnabled(ui->userPasswordEnableCheckBox->isChecked());
ui->ownerPasswordEdit->setEnabled(ui->ownerPasswordEnableCheckBox->isChecked());
if (!ui->userPasswordEdit->isEnabled())
{
ui->userPasswordEdit->clear();
}
if (!ui->ownerPasswordEdit->isEnabled())
{
ui->ownerPasswordEdit->clear();
}
m_userPasswordStrengthHintWidget->setEnabled(ui->userPasswordEnableCheckBox->isChecked());
m_ownerPasswordStrengthHintWidget->setEnabled(ui->ownerPasswordEnableCheckBox->isChecked());
ui->encryptAllRadioButton->setEnabled(encrypted);
ui->encryptAllExceptMetadataRadioButton->setEnabled(encrypted);
ui->encryptFileAttachmentsOnlyRadioButton->setEnabled(encrypted);
for (const auto& permissionItem : m_checkBoxToPermission)
{
permissionItem.first->setEnabled(encrypted);
}
}
void PDFEncryptionSettingsDialog::updateCertificates()
{
m_certificates = pdf::PDFCertificateManager::getCertificates();
pdf::PDFCertificateListHelper::fillComboBox(ui->certificateComboBox, m_certificates);
}
void PDFEncryptionSettingsDialog::updatePasswordScore()
{
const pdf::PDFSecurityHandlerFactory::Algorithm algorithm = static_cast<pdf::PDFSecurityHandlerFactory::Algorithm>(ui->algorithmComboBox->currentData().toInt());
const int userPasswordScore = pdf::PDFSecurityHandlerFactory::getPasswordEntropy(ui->userPasswordEdit->text(), algorithm);
const int ownerPasswordScore = pdf::PDFSecurityHandlerFactory::getPasswordEntropy(ui->ownerPasswordEdit->text(), algorithm);
m_userPasswordStrengthHintWidget->setCurrentValue(userPasswordScore);
m_ownerPasswordStrengthHintWidget->setCurrentValue(ownerPasswordScore);
}
void PDFEncryptionSettingsDialog::accept()
{
pdf::PDFSecurityHandlerFactory::SecuritySettings settings;
pdf::PDFSecurityHandlerFactory::EncryptContents encryptContents = pdf::PDFSecurityHandlerFactory::All;
if (ui->encryptAllExceptMetadataRadioButton->isChecked())
{
encryptContents = pdf::PDFSecurityHandlerFactory::AllExceptMetadata;
}
else if (ui->encryptFileAttachmentsOnlyRadioButton->isChecked())
{
encryptContents = pdf::PDFSecurityHandlerFactory::EmbeddedFiles;
}
settings.id = m_documentId;
settings.algorithm = static_cast<pdf::PDFSecurityHandlerFactory::Algorithm>(ui->algorithmComboBox->currentData().toInt());
settings.encryptContents = encryptContents;
settings.userPassword = ui->userPasswordEdit->text();
settings.ownerPassword = ui->ownerPasswordEdit->text();
settings.permissions = 0;
const int currentCertificateIndex = ui->certificateComboBox->currentIndex();
if (currentCertificateIndex >= 0 && currentCertificateIndex < m_certificates.size())
{
settings.certificate = m_certificates.at(currentCertificateIndex);
}
for (auto item : m_checkBoxToPermission)
{
if (item.first->isChecked())
{
settings.permissions += uint32_t(item.second);
}
}
QString errorMessage;
if (!pdf::PDFSecurityHandlerFactory::validate(settings, &errorMessage))
{
QMessageBox::critical(this, tr("Error"), errorMessage);
return;
}
m_updatedSecurityHandler = pdf::PDFSecurityHandlerFactory::createSecurityHandler(settings);
QDialog::accept();
}
} // namespace pdfviewer

View File

@@ -1,71 +0,0 @@
// Copyright (C) 2021 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#ifndef PDFENCRYPTIONSETTINGSDIALOG_H
#define PDFENCRYPTIONSETTINGSDIALOG_H
#include "pdfviewerglobal.h"
#include "pdfsecurityhandler.h"
#include "pdfcertificatestore.h"
#include <QDialog>
namespace Ui
{
class PDFEncryptionSettingsDialog;
}
class QCheckBox;
namespace pdfviewer
{
class PDFEncryptionStrengthHintWidget;
class PDFEncryptionSettingsDialog : public QDialog
{
Q_OBJECT
public:
explicit PDFEncryptionSettingsDialog(QByteArray documentId, QWidget* parent);
virtual ~PDFEncryptionSettingsDialog() override;
pdf::PDFSecurityHandlerPointer getUpdatedSecurityHandler() const { return m_updatedSecurityHandler; }
public slots:
virtual void accept() override;
private:
Ui::PDFEncryptionSettingsDialog* ui;
void updateUi();
void updateCertificates();
void updatePasswordScore();
bool m_isUpdatingUi;
std::map<QCheckBox*, pdf::PDFSecurityHandler::Permission> m_checkBoxToPermission;
pdf::PDFSecurityHandlerPointer m_updatedSecurityHandler;
QByteArray m_documentId;
PDFEncryptionStrengthHintWidget* m_userPasswordStrengthHintWidget;
PDFEncryptionStrengthHintWidget* m_ownerPasswordStrengthHintWidget;
PDFEncryptionStrengthHintWidget* m_algorithmHintWidget;
pdf::PDFCertificateEntries m_certificates;
};
} // namespace pdfviewer
#endif // PDFENCRYPTIONSETTINGSDIALOG_H

View File

@@ -1,244 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PDFEncryptionSettingsDialog</class>
<widget class="QDialog" name="PDFEncryptionSettingsDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>843</width>
<height>620</height>
</rect>
</property>
<property name="windowTitle">
<string>Encryption Settings</string>
</property>
<layout class="QVBoxLayout" name="dialogLayout">
<item>
<widget class="QGroupBox" name="encryptionMethodGroupBox">
<property name="title">
<string>Encryption Method</string>
</property>
<layout class="QGridLayout" name="methodGroupBoxLayout">
<item row="0" column="0">
<widget class="QLabel" name="encryptionAlgorithm">
<property name="text">
<string>Encryption algorithm</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="algorithmComboBox"/>
</item>
<item row="2" column="0" colspan="3">
<widget class="QLabel" name="encryptionMethodHintLabel">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Select encryption algorithm. AES-256 is strongly recommended, because older encryption algorithm can be potentially broken. Select older algorithms (as AES-128 or RC4) only, if you need backward compatibility. Also, choose a strong password to ensure strong encryption.&lt;/p&gt;&lt;p&gt;Public key security using certificate is also supported. In that case, you must select a certificate with private key, and this certificate is then used to encrypt data. User, which wants to open document encrypted with certificate, must have a private key to the certificae.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="certificateLabel">
<property name="text">
<string>Certificate</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="certificateComboBox"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="passwordsGroupBox">
<property name="title">
<string>Passwords</string>
</property>
<layout class="QGridLayout" name="passwordsGroupBoxLayout">
<item row="0" column="0">
<widget class="QCheckBox" name="userPasswordEnableCheckBox">
<property name="text">
<string>Password (document open)</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="ownerPasswordEdit">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="userPasswordEdit">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="ownerPasswordEnableCheckBox">
<property name="text">
<string>Password (owner access)</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="encryptContentsGroupBox">
<property name="title">
<string>Encrypt Contents</string>
</property>
<layout class="QVBoxLayout" name="encryptGroupBoxLayout">
<item>
<widget class="QRadioButton" name="encryptAllRadioButton">
<property name="text">
<string>Encrypt all document contents, including document metadata</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="encryptAllExceptMetadataRadioButton">
<property name="text">
<string>Encrypt all document contets except metadata</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="encryptFileAttachmentsOnlyRadioButton">
<property name="text">
<string>Encrypt file attachments only</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="permissionsGroupBox">
<property name="title">
<string>Permissions</string>
</property>
<layout class="QGridLayout" name="permissionsGroupBoxLayout">
<item row="0" column="0">
<widget class="QCheckBox" name="permPrintLowResolutionCheckBox">
<property name="text">
<string>Print (low resolution)</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="permFillInteractiveFormsCheckBox">
<property name="text">
<string>Fill interactive forms</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="permPrintHighResolutionCheckBox">
<property name="text">
<string>Print (high resolution)</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="permAccessibilityCheckBox">
<property name="text">
<string>Accessibility</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="permModifyDocumentContentsCheckBox">
<property name="text">
<string>Modify document contents</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="permAssembleCheckBox">
<property name="text">
<string>Assemble document (insert, rotate, delete pages...)</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="permInteractiveItemsCheckBox">
<property name="text">
<string>Edit interactive items (annotations, forms, ...)</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="permCopyContentCheckBox">
<property name="text">
<string>Copy/extract document content</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>PDFEncryptionSettingsDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>PDFEncryptionSettingsDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -1,187 +0,0 @@
// Copyright (C) 2021-2022 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#include "pdfencryptionstrengthhintwidget.h"
#include "pdfwidgetutils.h"
#include "pdfutils.h"
#include <QPainter>
#include <QFontMetrics>
#include "pdfdbgheap.h"
namespace pdfviewer
{
PDFEncryptionStrengthHintWidget::PDFEncryptionStrengthHintWidget(QWidget* parent) :
BaseClass(parent),
m_minValue(0),
m_maxValue(100),
m_currentValue(50)
{
m_levels = {
Level{ Qt::red, tr("Very weak") },
Level{ QColor::fromRgbF(1.0, 0.5, 0.0, 1.0), tr("Weak") },
Level{ Qt::yellow, tr("Moderate") },
Level{ QColor::fromRgbF(0.0, 1.0, 0.5, 1.0), tr("Strong") },
Level{ Qt::green, tr("Very strong") }
};
}
QSize PDFEncryptionStrengthHintWidget::sizeHint() const
{
const QSize markSize = getMarkSize();
const QSize textSize = getTextSizeHint();
const int markSpacing = getMarkSpacing();
const int levels = int(m_levels.size());
const int width = levels * (markSize.width() + markSpacing) + textSize.width() + markSpacing;
const int height = qMax(markSize.height(), textSize.height());
return QSize(width, height);
}
QSize PDFEncryptionStrengthHintWidget::minimumSizeHint() const
{
return sizeHint();
}
void PDFEncryptionStrengthHintWidget::paintEvent(QPaintEvent* event)
{
QPainter painter(this);
Q_UNUSED(event);
const QSize markSize = getMarkSize();
const int markSpacing = getMarkSpacing();
const int xAdvance = markSize.width() + markSpacing;
const bool isEnabled = this->isEnabled();
QRect rect = this->rect();
painter.fillRect(rect, Qt::lightGray);
painter.translate(markSpacing, 0);
int currentLevel = qFloor(pdf::interpolate(m_currentValue, m_minValue, m_maxValue, 0, m_levels.size()));
if (currentLevel == m_levels.size())
{
--currentLevel;
}
if (!isEnabled)
{
currentLevel = -1;
}
Q_ASSERT(currentLevel >= -1);
Q_ASSERT(currentLevel == -1 || currentLevel < m_levels.size());
QColor fillColor = Qt::darkGray;
if (currentLevel >= 0)
{
fillColor = m_levels[currentLevel].color;
}
QColor invalidColor = Qt::darkGray;
QRect markRect(QPoint(0, (rect.height() - markSize.height()) / 2), markSize);
painter.save();
for (size_t i = 0; i < m_levels.size(); ++i)
{
QColor color = (i <= currentLevel) ? fillColor : invalidColor;
painter.fillRect(markRect, color);
painter.translate(xAdvance, 0);
rect.setLeft(rect.left() + xAdvance);
}
painter.restore();
if (isEnabled)
{
painter.drawText(rect, Qt::TextSingleLine | Qt::TextDontClip | Qt::AlignLeft | Qt::AlignVCenter, m_levels[currentLevel].text);
}
}
void PDFEncryptionStrengthHintWidget::correctValue()
{
setCurrentValue(qBound(m_minValue, m_currentValue, m_maxValue));
}
QSize PDFEncryptionStrengthHintWidget::getMarkSize() const
{
return pdf::PDFWidgetUtils::scaleDPI(this, QSize(15, 5));
}
int PDFEncryptionStrengthHintWidget::getMarkSpacing() const
{
return pdf::PDFWidgetUtils::scaleDPI_x(this, 5);
}
QSize PDFEncryptionStrengthHintWidget::getTextSizeHint() const
{
QFontMetrics fontMetrics(font(), this);
const int height = fontMetrics.lineSpacing() + pdf::PDFWidgetUtils::scaleDPI_y(this, 4);
int width = 0;
for (const auto& levelItem : m_levels)
{
width = qMax(width, fontMetrics.horizontalAdvance(levelItem.text));
}
return QSize(width, height);
}
int PDFEncryptionStrengthHintWidget::getMaxValue() const
{
return m_maxValue;
}
void PDFEncryptionStrengthHintWidget::setMaxValue(int maxValue)
{
m_maxValue = maxValue;
correctValue();
}
int PDFEncryptionStrengthHintWidget::getMinValue() const
{
return m_minValue;
}
void PDFEncryptionStrengthHintWidget::setMinValue(int minValue)
{
m_minValue = minValue;
correctValue();
}
int PDFEncryptionStrengthHintWidget::getCurrentValue() const
{
return m_currentValue;
}
void PDFEncryptionStrengthHintWidget::setCurrentValue(int currentValue)
{
const int adjustedValue = qBound(m_minValue, currentValue, m_maxValue);
if (m_currentValue != adjustedValue)
{
m_currentValue = adjustedValue;
update();
}
}
} // namespace pdfviewer

View File

@@ -1,76 +0,0 @@
// Copyright (C) 2021 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#ifndef PDFENCRYPTIONSTRENGTHHINTWIDGET_H
#define PDFENCRYPTIONSTRENGTHHINTWIDGET_H
#include "pdfviewerglobal.h"
#include <QWidget>
#include <array>
namespace pdfviewer
{
class PDFEncryptionStrengthHintWidget : public QWidget
{
Q_OBJECT
private:
using BaseClass = QWidget;
public:
explicit PDFEncryptionStrengthHintWidget(QWidget* parent);
virtual QSize sizeHint() const override;
virtual QSize minimumSizeHint() const override;
int getCurrentValue() const;
void setCurrentValue(int currentValue);
int getMinValue() const;
void setMinValue(int minValue);
int getMaxValue() const;
void setMaxValue(int maxValue);
protected:
virtual void paintEvent(QPaintEvent* event) override;
void correctValue();
QSize getMarkSize() const;
int getMarkSpacing() const;
QSize getTextSizeHint() const;
struct Level
{
QColor color;
QString text;
};
int m_minValue;
int m_maxValue;
int m_currentValue;
std::array<Level, 5> m_levels;
};
} // namespace pdfviewer
#endif // PDFENCRYPTIONSTRENGTHHINTWIDGET_H

View File

@@ -1,164 +0,0 @@
// Copyright (C) 2021-2022 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#include "pdfoptimizedocumentdialog.h"
#include "ui_pdfoptimizedocumentdialog.h"
#include "pdfwidgetutils.h"
#include "pdfdocumentwriter.h"
#include <QCheckBox>
#include <QPushButton>
#include <QElapsedTimer>
#include <QtConcurrent/QtConcurrent>
#include "pdfdbgheap.h"
namespace pdfviewer
{
PDFOptimizeDocumentDialog::PDFOptimizeDocumentDialog(const pdf::PDFDocument* document, QWidget* parent) :
QDialog(parent),
ui(new Ui::PDFOptimizeDocumentDialog),
m_document(document),
m_optimizer(pdf::PDFOptimizer::All, nullptr),
m_optimizeButton(nullptr),
m_optimizationInProgress(false),
m_wasOptimized(false)
{
ui->setupUi(this);
auto addCheckBox = [this](QString text, pdf::PDFOptimizer::OptimizationFlag flag)
{
QCheckBox* checkBox = new QCheckBox(text, this);
checkBox->setChecked(m_optimizer.getFlags().testFlag(flag));
connect(checkBox, &QCheckBox::clicked, this, [this, flag](bool checked) { m_optimizer.setFlags(m_optimizer.getFlags().setFlag(flag, checked)); });
ui->groupBoxLayout->addWidget(checkBox);
};
addCheckBox(tr("Embed (dereference) simple objects, such as int, bool, real"), pdf::PDFOptimizer::DereferenceSimpleObjects);
addCheckBox(tr("Remove null objects from dictionary entries"), pdf::PDFOptimizer::RemoveNullObjects);
addCheckBox(tr("Remove unused objects (objects unreachable from document root object)"), pdf::PDFOptimizer::RemoveUnusedObjects);
addCheckBox(tr("Merge identical objects"), pdf::PDFOptimizer::MergeIdenticalObjects);
addCheckBox(tr("Shrink object storage (squeeze free entries)"), pdf::PDFOptimizer::ShrinkObjectStorage);
addCheckBox(tr("Recompress flate streams by maximal compression"), pdf::PDFOptimizer::RecompressFlateStreams);
m_optimizeButton = ui->buttonBox->addButton(tr("Optimize"), QDialogButtonBox::ActionRole);
connect(m_optimizeButton, &QPushButton::clicked, this, &PDFOptimizeDocumentDialog::onOptimizeButtonClicked);
connect(&m_optimizer, &pdf::PDFOptimizer::optimizationStarted, this, &PDFOptimizeDocumentDialog::onOptimizationStarted);
connect(&m_optimizer, &pdf::PDFOptimizer::optimizationProgress, this, &PDFOptimizeDocumentDialog::onOptimizationProgress);
connect(&m_optimizer, &pdf::PDFOptimizer::optimizationFinished, this, &PDFOptimizeDocumentDialog::onOptimizationFinished);
connect(this, &PDFOptimizeDocumentDialog::displayOptimizationInfo, this, &PDFOptimizeDocumentDialog::onDisplayOptimizationInfo);
pdf::PDFWidgetUtils::scaleWidget(this, QSize(640, 380));
updateUi();
pdf::PDFWidgetUtils::style(this);
}
PDFOptimizeDocumentDialog::~PDFOptimizeDocumentDialog()
{
Q_ASSERT(!m_optimizationInProgress);
Q_ASSERT(!m_future.isRunning());
delete ui;
}
void PDFOptimizeDocumentDialog::optimize()
{
QElapsedTimer timer;
timer.start();
m_optimizer.setDocument(m_document);
m_optimizer.optimize();
m_optimizedDocument = m_optimizer.takeOptimizedDocument();
qreal msecsElapsed = timer.nsecsElapsed() / 1000000.0;
timer.invalidate();
m_optimizationInfo.msecsElapsed = msecsElapsed;
m_optimizationInfo.bytesBeforeOptimization = pdf::PDFDocumentWriter::getDocumentFileSize(m_document);
m_optimizationInfo.bytesAfterOptimization = pdf::PDFDocumentWriter::getDocumentFileSize(&m_optimizedDocument);
Q_EMIT displayOptimizationInfo();
}
void PDFOptimizeDocumentDialog::onOptimizeButtonClicked()
{
Q_ASSERT(!m_optimizationInProgress);
Q_ASSERT(!m_future.isRunning());
m_optimizationInProgress = true;
m_future = QtConcurrent::run([this]() { optimize(); });
updateUi();
}
void PDFOptimizeDocumentDialog::onOptimizationStarted()
{
Q_ASSERT(m_optimizationInProgress);
ui->logTextEdit->setPlainText(tr("Optimization started!"));
}
void PDFOptimizeDocumentDialog::onOptimizationProgress(QString progressText)
{
Q_ASSERT(m_optimizationInProgress);
ui->logTextEdit->setPlainText(QString("%1\n%2").arg(ui->logTextEdit->toPlainText(), progressText));
}
void PDFOptimizeDocumentDialog::onOptimizationFinished()
{
ui->logTextEdit->setPlainText(QString("%1\n%2").arg(ui->logTextEdit->toPlainText(), tr("Optimization finished!")));
m_future.waitForFinished();
m_optimizationInProgress = false;
m_wasOptimized = true;
updateUi();
}
void PDFOptimizeDocumentDialog::onDisplayOptimizationInfo()
{
QStringList texts;
texts << tr("Optimized in %1 msecs").arg(m_optimizationInfo.msecsElapsed);
if (m_optimizationInfo.bytesBeforeOptimization != -1 &&
m_optimizationInfo.bytesAfterOptimization != -1)
{
texts << tr("Bytes before optimization: %1").arg(m_optimizationInfo.bytesBeforeOptimization);
texts << tr("Bytes after optimization: %1").arg(m_optimizationInfo.bytesAfterOptimization);
texts << tr("Bytes saved by optimization: %1").arg(m_optimizationInfo.bytesBeforeOptimization - m_optimizationInfo.bytesAfterOptimization);
qreal ratio = 100.0;
if (m_optimizationInfo.bytesBeforeOptimization > 0)
{
ratio = 100.0 * qreal(m_optimizationInfo.bytesAfterOptimization) / qreal(m_optimizationInfo.bytesBeforeOptimization);
}
texts << tr("Compression ratio: %1 %").arg(ratio);
}
ui->logTextEdit->setPlainText(QString("%1\n%2").arg(ui->logTextEdit->toPlainText(), texts.join("\n")));
}
void PDFOptimizeDocumentDialog::updateUi()
{
for (QCheckBox* checkBox : findChildren<QCheckBox*>(QString(), Qt::FindChildrenRecursively))
{
checkBox->setEnabled(!m_optimizationInProgress);
}
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(m_wasOptimized && !m_optimizationInProgress);
ui->buttonBox->button(QDialogButtonBox::Cancel)->setEnabled(!m_optimizationInProgress);
m_optimizeButton->setEnabled(!m_optimizationInProgress);
}
} // namespace pdfviewer

View File

@@ -1,77 +0,0 @@
// Copyright (C) 2021 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#ifndef PDFOPTIMIZEDOCUMENTDIALOG_H
#define PDFOPTIMIZEDOCUMENTDIALOG_H
#include "pdfoptimizer.h"
#include <QDialog>
#include <QFuture>
namespace Ui
{
class PDFOptimizeDocumentDialog;
}
namespace pdfviewer
{
class PDFOptimizeDocumentDialog : public QDialog
{
Q_OBJECT
public:
explicit PDFOptimizeDocumentDialog(const pdf::PDFDocument* document, QWidget* parent);
virtual ~PDFOptimizeDocumentDialog() override;
pdf::PDFDocument takeOptimizedDocument() { return qMove(m_optimizedDocument); }
signals:
void displayOptimizationInfo();
private:
void optimize();
void onOptimizeButtonClicked();
void onOptimizationStarted();
void onOptimizationProgress(QString progressText);
void onOptimizationFinished();
void onDisplayOptimizationInfo();
void updateUi();
struct OptimizationInfo
{
qreal msecsElapsed = 0.0;
qint64 bytesBeforeOptimization = -1;
qint64 bytesAfterOptimization = -1;
};
Ui::PDFOptimizeDocumentDialog* ui;
const pdf::PDFDocument* m_document;
pdf::PDFOptimizer m_optimizer;
QPushButton* m_optimizeButton;
bool m_optimizationInProgress;
bool m_wasOptimized;
QFuture<void> m_future;
pdf::PDFDocument m_optimizedDocument;
OptimizationInfo m_optimizationInfo;
};
} // namespace pdfviewer
#endif // PDFOPTIMIZEDOCUMENTDIALOG_H

View File

@@ -1,82 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PDFOptimizeDocumentDialog</class>
<widget class="QDialog" name="PDFOptimizeDocumentDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>741</width>
<height>530</height>
</rect>
</property>
<property name="windowTitle">
<string>Document optimization</string>
</property>
<layout class="QVBoxLayout" name="dialogLayout">
<item>
<widget class="QGroupBox" name="optimizationSettingsGroupBox">
<property name="title">
<string>Optimization Settings</string>
</property>
<layout class="QVBoxLayout" name="groupBoxLayout"/>
</widget>
</item>
<item>
<widget class="QPlainTextEdit" name="logTextEdit">
<property name="undoRedoEnabled">
<bool>false</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>PDFOptimizeDocumentDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>PDFOptimizeDocumentDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

File diff suppressed because it is too large Load Diff

View File

@@ -1,461 +0,0 @@
// Copyright (C) 2020-2021 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#ifndef PDFPROGRAMCONTROLLER_H
#define PDFPROGRAMCONTROLLER_H
#include "pdfviewerglobal.h"
#include "pdfdocument.h"
#include "pdfsignaturehandler.h"
#include "pdfdocumentreader.h"
#include "pdfdocumentpropertiesdialog.h"
#include "pdfplugin.h"
#include "pdfbookmarkmanager.h"
#include <QObject>
#include <QAction>
#include <QToolButton>
#include <QActionGroup>
#include <QFileSystemWatcher>
#include <array>
class QMainWindow;
class QComboBox;
class QToolBar;
namespace pdf
{
class PDFAction;
class PDFWidget;
class PDFCMSManager;
class PDFToolManager;
class PDFWidgetFormManager;
class PDFWidgetAnnotationManager;
}
namespace pdfviewer
{
class PDFViewerSettings;
class PDFUndoRedoManager;
class PDFRecentFileManager;
class PDFTextToSpeech;
class PDFActionComboBox;
class IMainWindow
{
public:
explicit IMainWindow() = default;
virtual ~IMainWindow() = default;
virtual void updateUI(bool fullUpdate) = 0;
virtual QMenu* addToolMenu(QString name) = 0;
virtual void setStatusBarMessage(QString message, int time) = 0;
virtual void setDocument(const pdf::PDFModifiedDocument& document) = 0;
virtual void adjustToolbar(QToolBar* toolbar) = 0;
virtual pdf::PDFTextSelection getSelectedText() const = 0;
};
class PDF4QTVIEWERLIBSHARED_EXPORT PDFActionManager : public QObject
{
Q_OBJECT
private:
using BaseClass = QObject;
public:
explicit PDFActionManager(QObject* parent);
enum Action
{
Open,
Close,
Quit,
AutomaticDocumentRefresh,
ZoomIn,
ZoomOut,
Find,
FindPrevious,
FindNext,
SelectTextAll,
DeselectText,
CopyText,
RotateRight,
RotateLeft,
Print,
Undo,
Redo,
Save,
SaveAs,
Properties,
Options,
ResetToFactorySettings,
CertificateManager,
GetSource,
BecomeSponsor,
About,
SendByMail,
RenderToImages,
Optimize,
Sanitize,
CreateBitonalDocument,
Encryption,
FitPage,
FitWidth,
FitHeight,
ShowRenderingErrors,
GoToDocumentStart,
GoToDocumentEnd,
GoToNextPage,
GoToPreviousPage,
GoToNextLine,
GoToPreviousLine,
CreateStickyNoteComment,
CreateStickyNoteHelp,
CreateStickyNoteInsert,
CreateStickyNoteKey,
CreateStickyNoteNewParagraph,
CreateStickyNoteNote,
CreateStickyNoteParagraph,
CreateTextHighlight,
CreateTextUnderline,
CreateTextStrikeout,
CreateTextSquiggly,
CreateHyperlink,
CreateInlineText,
CreateStraightLine,
CreatePolyline,
CreateRectangle,
CreatePolygon,
CreateEllipse,
CreateFreehandCurve,
CreateStampApproved,
CreateStampAsIs,
CreateStampConfidential,
CreateStampDepartmental,
CreateStampDraft,
CreateStampExperimental,
CreateStampExpired,
CreateStampFinal,
CreateStampForComment,
CreateStampForPublicRelease,
CreateStampNotApproved,
CreateStampNotForPublicRelease,
CreateStampSold,
CreateStampTopSecret,
RenderOptionAntialiasing,
RenderOptionTextAntialiasing,
RenderOptionSmoothPictures,
RenderOptionIgnoreOptionalContentSettings,
RenderOptionDisplayRenderTimes,
RenderOptionDisplayAnnotations,
RenderOptionInvertColors,
RenderOptionGrayscale,
RenderOptionBitonal,
RenderOptionHighContrast,
RenderOptionCustomColors,
RenderOptionShowTextBlocks,
RenderOptionShowTextLines,
PageLayoutSinglePage,
PageLayoutContinuous,
PageLayoutTwoPages,
PageLayoutTwoColumns,
PageLayoutFirstPageOnRightSide,
ToolSelectText,
ToolSelectTable,
ToolMagnifier,
ToolScreenshot,
ToolExtractImage,
BookmarkPage,
BookmarkGoToNext,
BookmarkGoToPrevious,
BookmarkExport,
BookmarkImport,
BookmarkGenerateAutomatically,
LastAction
};
enum ActionGroup
{
CreateStickyNoteGroup,
CreateTextHighlightGroup,
CreateStampGroup,
LastActionGroup
};
inline void setAction(Action type, QAction* action) { m_actions[type] = action; }
inline QAction* getAction(Action type) const { return m_actions[type]; }
inline QActionGroup* getActionGroup(ActionGroup group) const { return m_actionGroups[group]; }
/// Creates a tool button with menu for action group. If action group
/// doesn't exist, then nullptr is returned.
/// \param group Action group
/// \param parent Tool button's parent
QToolButton* createToolButtonForActionGroup(ActionGroup group, QWidget* parent) const;
/// Sets shortcut for given action. If action is nullptr,
/// then nothing happens.
/// \param type Action type
/// \param sequence Key sequence
void setShortcut(Action type, QKeySequence sequence);
/// Sets action data. If action is nullptr, then nothing happens.
/// \param type Action type
/// \param userData User data
void setUserData(Action type, QVariant userData);
/// Sets enabled state of the action. If action is nullptr, the nothing happens.
/// \param type Action type
/// \param enabled Enabled
void setEnabled(Action type, bool enabled);
/// Sets check state of the action. If action is nullptr, the nothing happens.
/// \param type Action type
/// \param enabled Enabled
void setChecked(Action type, bool checked);
/// Returns a list of rendering option actions
std::vector<QAction*> getRenderingOptionActions() const;
/// Returns a list of all actions
std::vector<QAction*> getActions() const;
/// Adds additional action to action manager
void addAdditionalAction(QAction* action);
void initActions(QSize iconSize, bool initializeStampActions);
void styleActions();
private:
bool hasActions(const std::initializer_list<Action>& actionTypes) const;
std::vector<QAction*> getActionList(const std::initializer_list<Action>& actionTypes) const;
std::array<QAction*, LastAction> m_actions;
std::array<QActionGroup*, LastActionGroup> m_actionGroups;
std::vector<QAction*> m_additionalActions;
QSize m_iconSize;
};
class PDF4QTVIEWERLIBSHARED_EXPORT PDFProgramController : public QObject, public pdf::IPluginDataExchange
{
Q_OBJECT
private:
using BaseClass = QObject;
public:
explicit PDFProgramController(QObject* parent);
virtual ~PDFProgramController() override;
enum Feature
{
None = 0x0000, ///< No feature
Tools = 0x0001, ///< Tools
Forms = 0x0002, ///< Forms
UndoRedo = 0x0004, ///< Undo/redo
Plugins = 0x0008, ///< Plugins
TextToSpeech = 0x0010, ///< Text to speech
AllFeatures = 0xFFFF, ///< All features enabled
};
Q_DECLARE_FLAGS(Features, Feature)
void openDocument(const QString& fileName);
void setDocument(pdf::PDFModifiedDocument document, bool isCurrentSaved);
void closeDocument();
pdf::PDFWidget* getPdfWidget() const { return m_pdfWidget; }
pdf::PDFToolManager* getToolManager() const { return m_toolManager; }
PDFRecentFileManager* getRecentFileManager() const { return m_recentFileManager; }
PDFViewerSettings* getSettings() const { return m_settings; }
pdf::PDFDocument* getDocument() const { return m_pdfDocument.data(); }
pdf::PDFCertificateStore* getCertificateStore() const { return const_cast<pdf::PDFCertificateStore*>(&m_certificateStore); }
PDFBookmarkManager* getBookmarkManager() const { return m_bookmarkManager; }
PDFTextToSpeech* getTextToSpeech() const { return m_textToSpeech; }
const std::vector<pdf::PDFSignatureVerificationResult>* getSignatures() const { return &m_signatures; }
void initialize(Features features,
QMainWindow* mainWindow,
IMainWindow* mainWindowInterface,
PDFActionManager* actionManager,
pdf::PDFProgress* progress);
void initActionComboBox(PDFActionComboBox* comboBox);
void finishInitialization();
void writeSettings();
void resetSettings();
void performPrint();
void performSave();
void performSaveAs();
void onActionTriggered(const pdf::PDFAction* action);
void onDocumentModified(pdf::PDFModifiedDocument document);
void updateActionsAvailability();
bool getIsBusy() const;
void setIsBusy(bool isBusy);
bool canClose() const;
bool askForSaveDocumentBeforeClose();
virtual QString getOriginalFileName() const override;
virtual pdf::PDFTextSelection getSelectedText() const override;
virtual QMainWindow* getMainWindow() const override;
virtual VoiceSettings getVoiceSettings() const override;
bool isFactorySettingsBeingRestored() const;
signals:
void queryPasswordRequest(QString* password, bool* ok);
private:
struct AsyncReadingResult
{
pdf::PDFDocumentPointer document;
QString errorMessage;
pdf::PDFDocumentReader::Result result = pdf::PDFDocumentReader::Result::Cancelled;
std::vector<pdf::PDFSignatureVerificationResult> signatures;
};
void initializeToolManager();
void initializeAnnotationManager();
void initializeFormManager();
void initializeBookmarkManager();
void onActionGoToDocumentStartTriggered();
void onActionGoToDocumentEndTriggered();
void onActionGoToNextPageTriggered();
void onActionGoToPreviousPageTriggered();
void onActionGoToNextLineTriggered();
void onActionGoToPreviousLineTriggered();
void onActionZoomIn();
void onActionZoomOut();
void onActionRotateRightTriggered();
void onActionRotateLeftTriggered();
void onActionRenderingOptionTriggered(bool checked);
void onActionPropertiesTriggered();
void onActionAboutTriggered();
void onActionSendByEMailTriggered();
void onActionRenderToImagesTriggered();
void onActionOptimizeTriggered();
void onActionSanitizeTriggered();
void onActionCreateBitonalDocumentTriggered();
void onActionEncryptionTriggered();
void onActionFitPageTriggered();
void onActionFitWidthTriggered();
void onActionFitHeightTriggered();
void onActionRenderingErrorsTriggered();
void onActionPageLayoutSinglePageTriggered();
void onActionPageLayoutContinuousTriggered();
void onActionPageLayoutTwoPagesTriggered();
void onActionPageLayoutTwoColumnsTriggered();
void onActionFirstPageOnRightSideTriggered();
void onActionFindTriggered();
void onActionOptionsTriggered();
void onActionCertificateManagerTriggered();
void onActionOpenTriggered();
void onActionCloseTriggered();
void onActionGetSource();
void onActionBecomeSponsor();
void onActionAutomaticDocumentRefresh();
void onActionBookmarkPage();
void onActionBookmarkGoToNext();
void onActionBookmarkGoToPrevious();
void onActionBookmarkExport();
void onActionBookmarkImport();
void onActionBookmarkGenerateAutomatically(bool checked);
void onDrawSpaceChanged();
void onPageLayoutChanged();
void onDocumentReadingFinished();
void onDocumentUndoRedo(pdf::PDFModifiedDocument document);
void onQueryPasswordRequest(QString* password, bool* ok);
void onPageRenderingErrorsChanged(pdf::PDFInteger pageIndex, int errorsCount);
void onViewerSettingsChanged();
void onColorManagementSystemChanged();
void onFileChanged(const QString& fileName);
void onBookmarkActivated(int index, PDFBookmarkManager::Bookmark bookmark);
void updateMagnifierToolSettings();
void updateUndoRedoSettings();
void updateUndoRedoActions();
void updateTitle();
void updatePageLayoutActions();
void updateRenderingOptionActions();
void updateBookmarkSettings();
void setPageLayout(pdf::PageLayout pageLayout);
void updateFileInfo(const QString& fileName);
void updateFileWatcher(bool forceDisable = false);
enum SettingFlag
{
NoSettings = 0x0000, ///< No feature
WindowSettings = 0x0001, ///< Window settings
GeneralSettings = 0x0002, ///< General settings
PluginsSettings = 0x0004, ///< Enabled plugin settings
ActionSettings = 0x0008, ///< Action settings
RecentFileSettings = 0x0010, ///< Recent files settings
CertificateSettings = 0x0020, ///< Certificate settings
};
Q_DECLARE_FLAGS(Settings, SettingFlag)
void loadPlugins();
void readSettings(Settings settings);
void saveDocument(const QString& fileName);
PDFActionManager* m_actionManager;
QMainWindow* m_mainWindow;
IMainWindow* m_mainWindowInterface;
pdf::PDFWidget* m_pdfWidget;
PDFViewerSettings* m_settings;
PDFUndoRedoManager* m_undoRedoManager;
PDFRecentFileManager* m_recentFileManager;
pdf::PDFOptionalContentActivity* m_optionalContentActivity;
pdf::PDFDocumentPointer m_pdfDocument;
PDFTextToSpeech* m_textToSpeech;
bool m_isDocumentSetInProgress;
QFuture<AsyncReadingResult> m_future;
QFutureWatcher<AsyncReadingResult>* m_futureWatcher;
pdf::PDFCMSManager* m_CMSManager;
pdf::PDFToolManager* m_toolManager;
pdf::PDFWidgetAnnotationManager* m_annotationManager;
pdf::PDFWidgetFormManager* m_formManager;
PDFBookmarkManager* m_bookmarkManager;
PDFActionComboBox* m_actionComboBox;
PDFFileInfo m_fileInfo;
QFileSystemWatcher m_fileWatcher;
pdf::PDFCertificateStore m_certificateStore;
std::vector<pdf::PDFSignatureVerificationResult> m_signatures;
bool m_isBusy;
bool m_isFactorySettingsBeingRestored;
pdf::PDFProgress* m_progress;
QStringList m_enabledPlugins;
pdf::PDFPluginInfos m_plugins;
std::vector<std::pair<pdf::PDFPluginInfo, pdf::PDFPlugin*>> m_loadedPlugins;
};
} // namespace pdfviewer
#endif // PDFPROGRAMCONTROLLER_H

View File

@@ -1,106 +0,0 @@
// Copyright (C) 2020-2022 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#include "pdfrecentfilemanager.h"
#include "pdfdbgheap.h"
namespace pdfviewer
{
PDFRecentFileManager::PDFRecentFileManager(QObject* parent) :
BaseClass(parent),
m_recentFilesLimit(DEFAULT_RECENT_FILES),
m_actions()
{
// Initialize actions
int index = 0;
for (auto it = m_actions.begin(); it != m_actions.end(); ++it)
{
QAction* recentFileAction = new QAction(this);
recentFileAction->setObjectName(QString("actionRecentFile%1").arg(++index));
recentFileAction->setVisible(false);
connect(recentFileAction, &QAction::triggered, this, &PDFRecentFileManager::onRecentFileActionTriggered);
*it = recentFileAction;
}
}
void PDFRecentFileManager::addRecentFile(QString fileName)
{
m_recentFiles.removeAll(fileName);
m_recentFiles.push_front(fileName);
update();
}
void PDFRecentFileManager::setRecentFiles(QStringList recentFiles)
{
if (m_recentFiles != recentFiles)
{
m_recentFiles = qMove(recentFiles);
update();
}
}
void PDFRecentFileManager::setRecentFilesLimit(int recentFilesLimit)
{
recentFilesLimit = qBound(getMinimumRecentFiles(), recentFilesLimit, getMaximumRecentFiles());
if (m_recentFilesLimit != recentFilesLimit)
{
m_recentFilesLimit = recentFilesLimit;
update();
}
}
void PDFRecentFileManager::update()
{
while (m_recentFiles.size() > m_recentFilesLimit)
{
m_recentFiles.pop_back();
}
for (int i = 0; i < static_cast<int>(m_actions.size()); ++i)
{
QAction* recentFileAction = m_actions[i];
if (i < m_recentFiles.size())
{
recentFileAction->setData(m_recentFiles[i]);
recentFileAction->setText(m_recentFiles[i]);
recentFileAction->setVisible(true);
}
else
{
recentFileAction->setData(QVariant());
recentFileAction->setText(tr("Recent file dummy %1").arg(i + 1));
recentFileAction->setVisible(false);
}
}
}
void PDFRecentFileManager::onRecentFileActionTriggered()
{
QAction* action = qobject_cast<QAction*>(sender());
Q_ASSERT(action);
QVariant data = action->data();
if (data.typeId() == QMetaType::QString)
{
Q_EMIT fileOpenRequest(data.toString());
}
}
} // namespace pdfviewer

View File

@@ -1,84 +0,0 @@
// Copyright (C) 2020-2021 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#ifndef PDFRECENTFILEMANAGER_H
#define PDFRECENTFILEMANAGER_H
#include <QObject>
#include <QAction>
#include <array>
namespace pdfviewer
{
/// Recent file manager, manages list of recent files.
class PDFRecentFileManager : public QObject
{
Q_OBJECT
private:
using BaseClass = QObject;
static constexpr const int MAXIMUM_RECENT_FILES = 9;
static constexpr const int DEFAULT_RECENT_FILES = 5;
public:
explicit PDFRecentFileManager(QObject* parent);
/// Adds recent file to recent file list and updates the actions.
/// New recent file is added as first file.
/// \param fileName New recent file
void addRecentFile(QString fileName);
/// Returns a list of recent files
const QStringList& getRecentFiles() const { return m_recentFiles; }
/// Sets a list of recent files, and udpates manager
void setRecentFiles(QStringList recentFiles);
/// Returns a limit of recent files count
int getRecentFilesLimit() const { return m_recentFilesLimit; }
/// Sets a new limit of recent files count
void setRecentFilesLimit(int recentFilesLimit);
/// Returns list of recent files actions
const std::array<QAction*, MAXIMUM_RECENT_FILES>& getActions() const { return m_actions; }
static constexpr int getMinimumRecentFiles() { return 1; }
static constexpr int getDefaultRecentFiles() { return DEFAULT_RECENT_FILES; }
static constexpr int getMaximumRecentFiles() { return MAXIMUM_RECENT_FILES; }
signals:
void fileOpenRequest(QString fileName);
private:
/// Updates recent files actions / recent file list
void update();
/// Reaction on recent file action triggered
void onRecentFileActionTriggered();
int m_recentFilesLimit;
std::array<QAction*, MAXIMUM_RECENT_FILES> m_actions;
QStringList m_recentFiles;
};
} // namespace pdfviewer
#endif // PDFRECENTFILEMANAGER_H

View File

@@ -1,364 +0,0 @@
// Copyright (C) 2020-2022 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#include "pdfrendertoimagesdialog.h"
#include "ui_pdfrendertoimagesdialog.h"
#include "pdfutils.h"
#include "pdfwidgetutils.h"
#include "pdfoptionalcontent.h"
#include "pdfdrawspacecontroller.h"
#include <QFileDialog>
#include <QMessageBox>
#include <QPushButton>
#include <QtConcurrent/QtConcurrent>
#include <QImageWriter>
#include "pdfdbgheap.h"
namespace pdfviewer
{
PDFRenderToImagesDialog::PDFRenderToImagesDialog(const pdf::PDFDocument* document,
pdf::PDFDrawWidgetProxy* proxy,
pdf::PDFProgress* progress,
QWidget* parent) :
QDialog(parent),
ui(new Ui::PDFRenderToImagesDialog),
m_document(document),
m_proxy(proxy),
m_progress(progress),
m_imageExportSettings(document),
m_isLoadingData(false),
m_optionalContentActivity(nullptr),
m_rasterizerPool(nullptr)
{
ui->setupUi(this);
qRegisterMetaType<pdf::PDFRenderError>("PDFRenderError");
qRegisterMetaType<pdf::PDFInteger>("PDFInteger");
// Load image formats
for (const QByteArray& format : m_imageWriterSettings.getFormats())
{
ui->formatComboBox->addItem(QString::fromLatin1(format), format);
}
connect(ui->pagesAllButton, &QRadioButton::clicked, this, &PDFRenderToImagesDialog::onPagesButtonClicked);
connect(ui->pagesSelectButton, &QRadioButton::clicked, this, &PDFRenderToImagesDialog::onPagesButtonClicked);
connect(ui->selectedPagesEdit, &QLineEdit::textChanged, this, &PDFRenderToImagesDialog::onSelectedPagesChanged);
connect(ui->directoryEdit, &QLineEdit::textChanged, this, &PDFRenderToImagesDialog::onDirectoryChanged);
connect(ui->fileTemplateEdit, &QLineEdit::textChanged, this, &PDFRenderToImagesDialog::onFileTemplateChanged);
connect(ui->resolutionDPIButton, &QRadioButton::clicked, this, &PDFRenderToImagesDialog::onResolutionButtonClicked);
connect(ui->resolutionPixelsButton, &QRadioButton::clicked, this, &PDFRenderToImagesDialog::onResolutionButtonClicked);
connect(ui->resolutionDPIEdit, QOverload<int>::of(&QSpinBox::valueChanged), this, &PDFRenderToImagesDialog::onResolutionDPIChanged);
connect(ui->resolutionPixelsEdit, QOverload<int>::of(&QSpinBox::valueChanged), this, &PDFRenderToImagesDialog::onResolutionPixelsChanged);
connect(ui->formatComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &PDFRenderToImagesDialog::onFormatChanged);
connect(ui->subtypeComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &PDFRenderToImagesDialog::onSubtypeChanged);
connect(ui->compressionEdit, QOverload<int>::of(&QSpinBox::valueChanged), this, &PDFRenderToImagesDialog::onCompressionChanged);
connect(ui->qualityEdit, QOverload<int>::of(&QSpinBox::valueChanged), this, &PDFRenderToImagesDialog::onQualityChanged);
connect(ui->gammaEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &PDFRenderToImagesDialog::onGammaChanged);
connect(ui->optimizedWriteCheckBox, &QCheckBox::clicked, this, &PDFRenderToImagesDialog::onOptimizedWriteChanged);
connect(ui->progressiveScanWriteCheckBox, &QCheckBox::clicked, this, &PDFRenderToImagesDialog::onProgressiveScanWriteChanged);
connect(&m_watcher, &QFutureWatcher<void>::finished, this, &PDFRenderToImagesDialog::onRenderingFinished);
ui->resolutionDPIEdit->setRange(pdf::PDFPageImageExportSettings::getMinDPIResolution(), pdf::PDFPageImageExportSettings::getMaxDPIResolution());
ui->resolutionPixelsEdit->setRange(pdf::PDFPageImageExportSettings::getMinPixelResolution(), pdf::PDFPageImageExportSettings::getMaxPixelResolution());
loadImageWriterSettings();
loadImageExportSettings();
pdf::PDFWidgetUtils::scaleWidget(this, QSize(1000, 600));
pdf::PDFWidgetUtils::style(this);
}
PDFRenderToImagesDialog::~PDFRenderToImagesDialog()
{
delete ui;
Q_ASSERT(!m_optionalContentActivity);
Q_ASSERT(!m_rasterizerPool);
}
void PDFRenderToImagesDialog::loadImageWriterSettings()
{
if (m_isLoadingData)
{
return;
}
pdf::PDFTemporaryValueChange guard(&m_isLoadingData, true);
ui->formatComboBox->setCurrentIndex(ui->formatComboBox->findData(m_imageWriterSettings.getCurrentFormat()));
ui->subtypeComboBox->setUpdatesEnabled(false);
ui->subtypeComboBox->clear();
for (const QByteArray& subtype : m_imageWriterSettings.getSubtypes())
{
ui->subtypeComboBox->addItem(QString::fromLatin1(subtype), subtype);
}
ui->subtypeComboBox->setCurrentIndex(ui->subtypeComboBox->findData(m_imageWriterSettings.getCurrentSubtype()));
ui->subtypeComboBox->setUpdatesEnabled(true);
ui->compressionEdit->setValue(m_imageWriterSettings.getCompression());
ui->qualityEdit->setValue(m_imageWriterSettings.getQuality());
ui->gammaEdit->setValue(m_imageWriterSettings.getGamma());
ui->optimizedWriteCheckBox->setChecked(m_imageWriterSettings.hasOptimizedWrite());
ui->progressiveScanWriteCheckBox->setChecked(m_imageWriterSettings.hasProgressiveScanWrite());
ui->subtypeComboBox->setEnabled(m_imageWriterSettings.isOptionSupported(QImageIOHandler::SupportedSubTypes));
ui->compressionEdit->setEnabled(m_imageWriterSettings.isOptionSupported(QImageIOHandler::CompressionRatio));
ui->qualityEdit->setEnabled(m_imageWriterSettings.isOptionSupported(QImageIOHandler::Quality));
ui->gammaEdit->setEnabled(m_imageWriterSettings.isOptionSupported(QImageIOHandler::Gamma));
ui->optimizedWriteCheckBox->setEnabled(m_imageWriterSettings.isOptionSupported(QImageIOHandler::OptimizedWrite));
ui->progressiveScanWriteCheckBox->setEnabled(m_imageWriterSettings.isOptionSupported(QImageIOHandler::ProgressiveScanWrite));
}
void PDFRenderToImagesDialog::loadImageExportSettings()
{
if (m_isLoadingData)
{
return;
}
pdf::PDFTemporaryValueChange guard(&m_isLoadingData, true);
const pdf::PDFPageImageExportSettings::PageSelectionMode pageSelectionMode = m_imageExportSettings.getPageSelectionMode();
ui->pagesAllButton->setChecked(pageSelectionMode == pdf::PDFPageImageExportSettings::PageSelectionMode::All);
ui->pagesSelectButton->setChecked(pageSelectionMode == pdf::PDFPageImageExportSettings::PageSelectionMode::Selection);
if (pageSelectionMode == pdf::PDFPageImageExportSettings::PageSelectionMode::Selection)
{
ui->selectedPagesEdit->setEnabled(true);
ui->selectedPagesEdit->setText(m_imageExportSettings.getPageSelection());
}
else
{
ui->selectedPagesEdit->setEnabled(false);
ui->selectedPagesEdit->setText(QString());
}
ui->directoryEdit->setText(m_imageExportSettings.getDirectory());
ui->fileTemplateEdit->setText(m_imageExportSettings.getFileTemplate());
const pdf::PDFPageImageExportSettings::ResolutionMode resolutionMode = m_imageExportSettings.getResolutionMode();
ui->resolutionDPIButton->setChecked(resolutionMode == pdf::PDFPageImageExportSettings::ResolutionMode::DPI);
ui->resolutionPixelsButton->setChecked(resolutionMode == pdf::PDFPageImageExportSettings::ResolutionMode::Pixels);
ui->resolutionDPIEdit->setValue(m_imageExportSettings.getDpiResolution());
ui->resolutionPixelsEdit->setValue(m_imageExportSettings.getPixelResolution());
ui->resolutionDPIEdit->setEnabled(resolutionMode == pdf::PDFPageImageExportSettings::ResolutionMode::DPI);
ui->resolutionPixelsEdit->setEnabled(resolutionMode == pdf::PDFPageImageExportSettings::ResolutionMode::Pixels);
}
void PDFRenderToImagesDialog::onFormatChanged()
{
m_imageWriterSettings.selectFormat(ui->formatComboBox->currentData().toByteArray());
loadImageWriterSettings();
}
void PDFRenderToImagesDialog::onSubtypeChanged()
{
m_imageWriterSettings.setCurrentSubtype(ui->subtypeComboBox->currentData().toByteArray());
}
void PDFRenderToImagesDialog::onPagesButtonClicked(bool checked)
{
if (checked)
{
const pdf::PDFPageImageExportSettings::PageSelectionMode pageSelectionMode = (sender() == ui->pagesAllButton) ? pdf::PDFPageImageExportSettings::PageSelectionMode::All
: pdf::PDFPageImageExportSettings::PageSelectionMode::Selection;
m_imageExportSettings.setPageSelectionMode(pageSelectionMode);
loadImageExportSettings();
}
}
void PDFRenderToImagesDialog::onSelectedPagesChanged(const QString& text)
{
m_imageExportSettings.setPageSelection(text);
}
void PDFRenderToImagesDialog::onDirectoryChanged(const QString& text)
{
m_imageExportSettings.setDirectory(text);
}
void PDFRenderToImagesDialog::onFileTemplateChanged(const QString& text)
{
m_imageExportSettings.setFileTemplate(text);
}
void PDFRenderToImagesDialog::onResolutionButtonClicked(bool checked)
{
if (checked)
{
const pdf::PDFPageImageExportSettings::ResolutionMode resolutionMode = (sender() == ui->resolutionDPIButton) ? pdf::PDFPageImageExportSettings::ResolutionMode::DPI
: pdf::PDFPageImageExportSettings::ResolutionMode::Pixels;
m_imageExportSettings.setResolutionMode(resolutionMode);
loadImageExportSettings();
}
}
void PDFRenderToImagesDialog::onResolutionDPIChanged(int value)
{
m_imageExportSettings.setDpiResolution(value);
}
void PDFRenderToImagesDialog::onResolutionPixelsChanged(int value)
{
m_imageExportSettings.setPixelResolution(value);
}
void PDFRenderToImagesDialog::onCompressionChanged(int value)
{
m_imageWriterSettings.setCompression(value);
}
void PDFRenderToImagesDialog::onQualityChanged(int value)
{
m_imageWriterSettings.setQuality(value);
}
void PDFRenderToImagesDialog::onGammaChanged(double value)
{
m_imageWriterSettings.setGamma(value);
}
void PDFRenderToImagesDialog::onOptimizedWriteChanged(bool value)
{
m_imageWriterSettings.setOptimizedWrite(value);
}
void PDFRenderToImagesDialog::onProgressiveScanWriteChanged(bool value)
{
m_imageWriterSettings.setProgressiveScanWrite(value);
}
void PDFRenderToImagesDialog::onRenderError(pdf::PDFInteger pageIndex, pdf::PDFRenderError error)
{
QString text;
if (pageIndex != pdf::PDFCatalog::INVALID_PAGE_INDEX)
{
text = tr("%1\nPage %2: %3").arg(ui->progressMessagesEdit->toPlainText(), QString::number(pageIndex + 1), error.message);
}
else
{
text = QString("%1\n%2").arg(ui->progressMessagesEdit->toPlainText(), error.message);
}
ui->progressMessagesEdit->setPlainText(text);
}
void PDFRenderToImagesDialog::onRenderingFinished()
{
setEnabled(true);
delete m_rasterizerPool;
m_rasterizerPool = nullptr;
delete m_optionalContentActivity;
m_optionalContentActivity = nullptr;
m_cms.reset();
}
void PDFRenderToImagesDialog::on_selectDirectoryButton_clicked()
{
QString directory = QFileDialog::getExistingDirectory(this, tr("Select output directory"), ui->directoryEdit->text());
if (!directory.isEmpty())
{
ui->directoryEdit->setText(directory);
}
}
void PDFRenderToImagesDialog::on_buttonBox_clicked(QAbstractButton* button)
{
if (button == ui->buttonBox->button(QDialogButtonBox::Apply))
{
QString message;
if (m_imageExportSettings.validate(&message))
{
setEnabled(false);
// We are ready to render the document
m_pageIndices = m_imageExportSettings.getPages();
m_optionalContentActivity = new pdf::PDFOptionalContentActivity(m_document, pdf::OCUsage::Export, this);
m_cms = m_proxy->getCMSManager()->getCurrentCMS();
m_rasterizerPool = new pdf::PDFRasterizerPool(m_document, m_proxy->getFontCache(), m_proxy->getCMSManager(),
m_optionalContentActivity, m_proxy->getFeatures(), m_proxy->getMeshQualitySettings(),
pdf::PDFRasterizerPool::getDefaultRasterizerCount(), m_proxy->getRendererEngine(), this);
connect(m_rasterizerPool, &pdf::PDFRasterizerPool::renderError, this, &PDFRenderToImagesDialog::onRenderError);
auto process = [this]()
{
auto imageSizeGetter = [this](const pdf::PDFPage* page) -> QSize
{
Q_ASSERT(page);
switch (m_imageExportSettings.getResolutionMode())
{
case pdf::PDFPageImageExportSettings::ResolutionMode::DPI:
{
QSizeF size = page->getRotatedMediaBox().size() * pdf::PDF_POINT_TO_INCH * m_imageExportSettings.getDpiResolution();
return size.toSize();
}
case pdf::PDFPageImageExportSettings::ResolutionMode::Pixels:
{
int pixelResolution = m_imageExportSettings.getPixelResolution();
QSizeF size = page->getRotatedMediaBox().size().scaled(pixelResolution, pixelResolution, Qt::KeepAspectRatio);
return size.toSize();
}
default:
{
Q_ASSERT(false);
break;
}
}
return QSize();
};
auto processImage = [this](pdf::PDFRenderedPageImage& renderedPageImage)
{
QString fileName = m_imageExportSettings.getOutputFileName(renderedPageImage.pageIndex, m_imageWriterSettings.getCurrentFormat());
QImageWriter imageWriter(fileName, m_imageWriterSettings.getCurrentFormat());
imageWriter.setSubType(m_imageWriterSettings.getCurrentSubtype());
imageWriter.setCompression(m_imageWriterSettings.getCompression());
imageWriter.setQuality(m_imageWriterSettings.getQuality());
imageWriter.setOptimizedWrite(m_imageWriterSettings.hasOptimizedWrite());
imageWriter.setProgressiveScanWrite(m_imageWriterSettings.hasProgressiveScanWrite());
if (!imageWriter.write(renderedPageImage.pageImage))
{
Q_EMIT m_rasterizerPool->renderError(renderedPageImage.pageIndex, pdf::PDFRenderError(pdf::RenderErrorType::Error, tr("Cannot write page image to file '%1', because: %2.").arg(fileName).arg(imageWriter.errorString())));
}
};
m_rasterizerPool->render(m_pageIndices, imageSizeGetter, processImage, m_progress);
};
m_watcher.setFuture(QtConcurrent::run(process));
}
else
{
QMessageBox::critical(this, tr("Error"), message);
}
}
}
} // namespace pdfviewer

View File

@@ -1,101 +0,0 @@
// Copyright (C) 2020-2021 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#ifndef PDFRENDERTOIMAGESDIALOG_H
#define PDFRENDERTOIMAGESDIALOG_H
#include "pdfcms.h"
#include "pdfrenderer.h"
#include <QDialog>
#include <QFutureWatcher>
class QAbstractButton;
namespace Ui
{
class PDFRenderToImagesDialog;
}
namespace pdf
{
class PDFProgress;
class PDFDrawWidgetProxy;
}
namespace pdfviewer
{
class PDFRenderToImagesDialog : public QDialog
{
Q_OBJECT
public:
explicit PDFRenderToImagesDialog(const pdf::PDFDocument* document,
pdf::PDFDrawWidgetProxy* proxy,
pdf::PDFProgress* progress,
QWidget* parent);
virtual ~PDFRenderToImagesDialog() override;
private slots:
void on_selectDirectoryButton_clicked();
void on_buttonBox_clicked(QAbstractButton* button);
private:
/// Loads image writer settings to the ui
void loadImageWriterSettings();
/// Load image export settigns to the ui
void loadImageExportSettings();
void onFormatChanged();
void onSubtypeChanged();
void onPagesButtonClicked(bool checked);
void onSelectedPagesChanged(const QString& text);
void onDirectoryChanged(const QString& text);
void onFileTemplateChanged(const QString& text);
void onResolutionButtonClicked(bool checked);
void onResolutionDPIChanged(int value);
void onResolutionPixelsChanged(int value);
void onCompressionChanged(int value);
void onQualityChanged(int value);
void onGammaChanged(double value);
void onOptimizedWriteChanged(bool value);
void onProgressiveScanWriteChanged(bool value);
void onRenderError(pdf::PDFInteger pageIndex, pdf::PDFRenderError error);
void onRenderingFinished();
Ui::PDFRenderToImagesDialog* ui;
const pdf::PDFDocument* m_document;
pdf::PDFDrawWidgetProxy* m_proxy;
pdf::PDFProgress* m_progress;
pdf::PDFImageWriterSettings m_imageWriterSettings;
pdf::PDFPageImageExportSettings m_imageExportSettings;
bool m_isLoadingData;
QFutureWatcher<void> m_watcher;
std::vector<pdf::PDFInteger> m_pageIndices;
pdf::PDFOptionalContentActivity* m_optionalContentActivity;
pdf::PDFCMSPointer m_cms;
pdf::PDFRasterizerPool* m_rasterizerPool;
};
} // namespace pdfviewer
Q_DECLARE_METATYPE(pdf::PDFRenderError)
#endif // PDFRENDERTOIMAGESDIALOG_H

View File

@@ -1,293 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PDFRenderToImagesDialog</class>
<widget class="QDialog" name="PDFRenderToImagesDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>690</width>
<height>602</height>
</rect>
</property>
<property name="windowTitle">
<string>Render Document to Images</string>
</property>
<layout class="QVBoxLayout" name="dialogLayout">
<item>
<widget class="QGroupBox" name="filesGroupBox">
<property name="title">
<string>Output Files Settings</string>
</property>
<layout class="QGridLayout" name="filesGroupBoxLayout">
<item row="0" column="0">
<widget class="QLabel" name="pagesToRenderLabel">
<property name="text">
<string>Pages to render</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="fileTemplateLabel">
<property name="text">
<string>File template</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QRadioButton" name="pagesAllButton">
<property name="text">
<string>All</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="directoryLabel">
<property name="text">
<string>Generate into directory</string>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QToolButton" name="selectDirectoryButton">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="QLineEdit" name="directoryEdit"/>
</item>
<item row="3" column="1" colspan="2">
<widget class="QLineEdit" name="fileTemplateEdit"/>
</item>
<item row="1" column="1">
<widget class="QRadioButton" name="pagesSelectButton">
<property name="text">
<string>Pages:</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLineEdit" name="selectedPagesEdit"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="imageResolutionGroupBox">
<property name="title">
<string>Image Resolution</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="resolutionLabel">
<property name="text">
<string>Resolution</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QRadioButton" name="resolutionPixelsButton">
<property name="text">
<string>Pixels</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QRadioButton" name="resolutionDPIButton">
<property name="text">
<string>DPI</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QSpinBox" name="resolutionDPIEdit">
<property name="suffix">
<string> dots/inch</string>
</property>
<property name="minimum">
<number>72</number>
</property>
<property name="maximum">
<number>6000</number>
</property>
<property name="singleStep">
<number>36</number>
</property>
<property name="value">
<number>300</number>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QSpinBox" name="resolutionPixelsEdit">
<property name="suffix">
<string> px</string>
</property>
<property name="minimum">
<number>100</number>
</property>
<property name="maximum">
<number>16384</number>
</property>
<property name="singleStep">
<number>100</number>
</property>
<property name="value">
<number>1000</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="imageFormatSettings">
<property name="title">
<string>Image Format Settings</string>
</property>
<layout class="QGridLayout" name="imageFormatSettingsLayout">
<item row="0" column="0">
<widget class="QLabel" name="imageFormatLabel">
<property name="text">
<string>Format</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="imageSubtypeLabel">
<property name="text">
<string>Subtype</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="subtypeComboBox"/>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="qualityEdit">
<property name="maximum">
<number>100</number>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="formatComboBox"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="gammaLabel">
<property name="text">
<string>Gamma</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="optimizedWriteLabel">
<property name="text">
<string>Optimized write</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QDoubleSpinBox" name="gammaEdit"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="qualityLabel">
<property name="text">
<string>Quality</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="compressionLabel">
<property name="text">
<string>Compression</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="compressionEdit"/>
</item>
<item row="6" column="0">
<widget class="QLabel" name="progressiveScanWriteLabel">
<property name="text">
<string>Progressive scan write</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QCheckBox" name="optimizedWriteCheckBox">
<property name="text">
<string>Enable</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QCheckBox" name="progressiveScanWriteCheckBox">
<property name="text">
<string>Enable</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QPlainTextEdit" name="progressMessagesEdit">
<property name="undoRedoEnabled">
<bool>false</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Apply|QDialogButtonBox::Close</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>PDFRenderToImagesDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>PDFRenderToImagesDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -1,165 +0,0 @@
// Copyright (C) 2023 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#include "pdfsanitizedocumentdialog.h"
#include "ui_pdfsanitizedocumentdialog.h"
#include "pdfwidgetutils.h"
#include "pdfdocumentwriter.h"
#include <QCheckBox>
#include <QPushButton>
#include <QElapsedTimer>
#include <QtConcurrent/QtConcurrent>
#include "pdfdbgheap.h"
namespace pdfviewer
{
PDFSanitizeDocumentDialog::PDFSanitizeDocumentDialog(const pdf::PDFDocument* document, QWidget* parent) :
QDialog(parent),
ui(new Ui::PDFSanitizeDocumentDialog),
m_document(document),
m_sanitizer(pdf::PDFDocumentSanitizer::All, nullptr),
m_sanitizeButton(nullptr),
m_sanitizationInProgress(false),
m_wasSanitized(false)
{
ui->setupUi(this);
auto addCheckBox = [this](QString text, pdf::PDFDocumentSanitizer::SanitizationFlag flag)
{
QCheckBox* checkBox = new QCheckBox(text, this);
checkBox->setChecked(m_sanitizer.getFlags().testFlag(flag));
connect(checkBox, &QCheckBox::clicked, this, [this, flag](bool checked) { m_sanitizer.setFlags(m_sanitizer.getFlags().setFlag(flag, checked)); });
ui->groupBoxLayout->addWidget(checkBox);
};
addCheckBox(tr("Remove document info"), pdf::PDFDocumentSanitizer::DocumentInfo);
addCheckBox(tr("Remove all metadata"), pdf::PDFDocumentSanitizer::Metadata);
addCheckBox(tr("Remove outline"), pdf::PDFDocumentSanitizer::Outline);
addCheckBox(tr("Remove file attachments"), pdf::PDFDocumentSanitizer::FileAttachments);
addCheckBox(tr("Remove embedded search index"), pdf::PDFDocumentSanitizer::EmbeddedSearchIndex);
addCheckBox(tr("Remove comments and other markup annotations"), pdf::PDFDocumentSanitizer::MarkupAnnotations);
addCheckBox(tr("Remove page thumbnails"), pdf::PDFDocumentSanitizer::PageThumbnails);
m_sanitizeButton = ui->buttonBox->addButton(tr("Sanitize"), QDialogButtonBox::ActionRole);
connect(m_sanitizeButton, &QPushButton::clicked, this, &PDFSanitizeDocumentDialog::onSanitizeButtonClicked);
connect(&m_sanitizer, &pdf::PDFDocumentSanitizer::sanitizationStarted, this, &PDFSanitizeDocumentDialog::onSanitizationStarted);
connect(&m_sanitizer, &pdf::PDFDocumentSanitizer::sanitizationProgress, this, &PDFSanitizeDocumentDialog::onSanitizationProgress);
connect(&m_sanitizer, &pdf::PDFDocumentSanitizer::sanitizationFinished, this, &PDFSanitizeDocumentDialog::onSanitizationFinished);
connect(this, &PDFSanitizeDocumentDialog::displaySanitizationInfo, this, &PDFSanitizeDocumentDialog::onDisplaySanitizationInfo);
pdf::PDFWidgetUtils::scaleWidget(this, QSize(640, 380));
updateUi();
pdf::PDFWidgetUtils::style(this);
}
PDFSanitizeDocumentDialog::~PDFSanitizeDocumentDialog()
{
Q_ASSERT(!m_sanitizationInProgress);
Q_ASSERT(!m_future.isRunning());
delete ui;
}
void PDFSanitizeDocumentDialog::sanitize()
{
QElapsedTimer timer;
timer.start();
m_sanitizer.setDocument(m_document);
m_sanitizer.sanitize();
m_sanitizedDocument = m_sanitizer.takeSanitizedDocument();
qreal msecsElapsed = timer.nsecsElapsed() / 1000000.0;
timer.invalidate();
m_sanitizationInfo.msecsElapsed = msecsElapsed;
m_sanitizationInfo.bytesBeforeSanitization = pdf::PDFDocumentWriter::getDocumentFileSize(m_document);
m_sanitizationInfo.bytesAfterSanitization = pdf::PDFDocumentWriter::getDocumentFileSize(&m_sanitizedDocument);
Q_EMIT displaySanitizationInfo();
}
void PDFSanitizeDocumentDialog::onSanitizeButtonClicked()
{
Q_ASSERT(!m_sanitizationInProgress);
Q_ASSERT(!m_future.isRunning());
m_sanitizationInProgress = true;
m_future = QtConcurrent::run([this]() { sanitize(); });
updateUi();
}
void PDFSanitizeDocumentDialog::onSanitizationStarted()
{
Q_ASSERT(m_sanitizationInProgress);
ui->logTextEdit->setPlainText(tr("Sanitization started!"));
}
void PDFSanitizeDocumentDialog::onSanitizationProgress(QString progressText)
{
Q_ASSERT(m_sanitizationInProgress);
ui->logTextEdit->setPlainText(QString("%1\n%2").arg(ui->logTextEdit->toPlainText(), progressText));
}
void PDFSanitizeDocumentDialog::onSanitizationFinished()
{
ui->logTextEdit->setPlainText(QString("%1\n%2").arg(ui->logTextEdit->toPlainText(), tr("Sanitization finished!")));
m_future.waitForFinished();
m_sanitizationInProgress = false;
m_wasSanitized = true;
updateUi();
}
void PDFSanitizeDocumentDialog::onDisplaySanitizationInfo()
{
QStringList texts;
texts << tr("Sanitized in %1 msecs").arg(m_sanitizationInfo.msecsElapsed);
if (m_sanitizationInfo.bytesBeforeSanitization != -1 &&
m_sanitizationInfo.bytesAfterSanitization != -1)
{
texts << tr("Bytes before sanitization: %1").arg(m_sanitizationInfo.bytesBeforeSanitization);
texts << tr("Bytes after sanitization: %1").arg(m_sanitizationInfo.bytesAfterSanitization);
texts << tr("Bytes saved by sanitization: %1").arg(m_sanitizationInfo.bytesBeforeSanitization - m_sanitizationInfo.bytesAfterSanitization);
qreal ratio = 100.0;
if (m_sanitizationInfo.bytesBeforeSanitization > 0)
{
ratio = 100.0 * qreal(m_sanitizationInfo.bytesAfterSanitization) / qreal(m_sanitizationInfo.bytesBeforeSanitization);
}
texts << tr("Compression ratio: %1 %").arg(ratio);
}
ui->logTextEdit->setPlainText(QString("%1\n%2").arg(ui->logTextEdit->toPlainText(), texts.join("\n")));
}
void PDFSanitizeDocumentDialog::updateUi()
{
for (QCheckBox* checkBox : findChildren<QCheckBox*>(QString(), Qt::FindChildrenRecursively))
{
checkBox->setEnabled(!m_sanitizationInProgress);
}
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(m_wasSanitized && !m_sanitizationInProgress);
ui->buttonBox->button(QDialogButtonBox::Cancel)->setEnabled(!m_sanitizationInProgress);
m_sanitizeButton->setEnabled(!m_sanitizationInProgress);
}
} // namespace pdfviewer

View File

@@ -1,77 +0,0 @@
// Copyright (C) 2023 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#ifndef PDFSANITIZEDOCUMENTDIALOG_H
#define PDFSANITIZEDOCUMENTDIALOG_H
#include "pdfdocumentsanitizer.h"
#include <QDialog>
#include <QFuture>
namespace Ui
{
class PDFSanitizeDocumentDialog;
}
namespace pdfviewer
{
class PDFSanitizeDocumentDialog : public QDialog
{
Q_OBJECT
public:
explicit PDFSanitizeDocumentDialog(const pdf::PDFDocument* document, QWidget* parent);
virtual ~PDFSanitizeDocumentDialog() override;
pdf::PDFDocument takeSanitizedDocument() { return qMove(m_sanitizedDocument); }
signals:
void displaySanitizationInfo();
private:
void sanitize();
void onSanitizeButtonClicked();
void onSanitizationStarted();
void onSanitizationProgress(QString progressText);
void onSanitizationFinished();
void onDisplaySanitizationInfo();
void updateUi();
struct SanitizationInfo
{
qreal msecsElapsed = 0.0;
qint64 bytesBeforeSanitization = -1;
qint64 bytesAfterSanitization = -1;
};
Ui::PDFSanitizeDocumentDialog* ui;
const pdf::PDFDocument* m_document;
pdf::PDFDocumentSanitizer m_sanitizer;
QPushButton* m_sanitizeButton;
bool m_sanitizationInProgress;
bool m_wasSanitized;
QFuture<void> m_future;
pdf::PDFDocument m_sanitizedDocument;
SanitizationInfo m_sanitizationInfo;
};
} // namespace pdfviewer
#endif // PDFSANITIZEDOCUMENTDIALOG_H

View File

@@ -1,82 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PDFSanitizeDocumentDialog</class>
<widget class="QDialog" name="PDFSanitizeDocumentDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>741</width>
<height>530</height>
</rect>
</property>
<property name="windowTitle">
<string>Document sanitization</string>
</property>
<layout class="QVBoxLayout" name="dialogLayout">
<item>
<widget class="QGroupBox" name="sanitizationSettingsGroupBox">
<property name="title">
<string>Sanitization Settings</string>
</property>
<layout class="QVBoxLayout" name="groupBoxLayout"/>
</widget>
</item>
<item>
<widget class="QPlainTextEdit" name="logTextEdit">
<property name="undoRedoEnabled">
<bool>false</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>PDFSanitizeDocumentDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>PDFSanitizeDocumentDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -1,116 +0,0 @@
// Copyright (C) 2019-2022 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#include "pdfsendmail.h"
#include <QDir>
#include <QWidget>
#include <QFileInfo>
#include "pdfdbgheap.h"
#ifdef Q_OS_WIN
#include <Windows.h>
#include <MAPI.h>
#include <string>
#endif
namespace pdfviewer
{
bool PDFSendMail::sendMail(QWidget* parent, QString subject, QString fileName)
{
#ifdef Q_OS_WIN
#if !defined(PDF4QT_COMPILER_MINGW)
QFileInfo fileInfo(fileName);
std::wstring subjectString = subject.toStdWString();
std::wstring fileNameString = fileInfo.fileName().toStdWString();
std::wstring filePathString = QDir::toNativeSeparators(fileInfo.absoluteFilePath()).toStdWString();
std::array<wchar_t, MAX_PATH> systemDirectoryBuffer = { };
if (!::GetSystemDirectoryW(systemDirectoryBuffer.data(), uint(systemDirectoryBuffer.size())))
{
return false;
}
QString systemDirectory = QString::fromWCharArray(systemDirectoryBuffer.data());
QString mapiDllPath = QString("%1\\MAPI32.dll").arg(systemDirectory);
QFileInfo mapiDllPathInfo(mapiDllPath);
QString mapiDllPathCorrected = mapiDllPathInfo.absoluteFilePath();
std::vector<wchar_t> mapiDllPathWchar(mapiDllPathCorrected.size() + 1);
qsizetype length = mapiDllPathCorrected.toWCharArray(mapiDllPathWchar.data());
mapiDllPathWchar[length] = 0;
HMODULE mapiLib = ::LoadLibraryW(mapiDllPathWchar.data());
if (!mapiLib)
{
return false;
}
LPMAPISENDMAILW SendMail;
SendMail = (LPMAPISENDMAILW)GetProcAddress(mapiLib, "MAPISendMailW");
if (!SendMail)
{
::FreeLibrary(mapiLib);
return false;
}
// Jakub Melka: now, we have function for mail sending, we can use it!
// First, we must fill the info structures.
MapiFileDescW fileDesc;
::ZeroMemory(&fileDesc, sizeof(fileDesc));
fileDesc.nPosition = ULONG(-1);
fileDesc.lpszFileName = const_cast<PWSTR>(fileNameString.c_str());
fileDesc.lpszPathName = const_cast<PWSTR>(filePathString.c_str());
MapiMessageW message;
::ZeroMemory(&message, sizeof(message));
message.lpszSubject = const_cast<PWSTR>(subjectString.c_str());
message.nFileCount = 1;
message.lpFiles = &fileDesc;
const int returnCode = SendMail(0, parent->winId(), &message, MAPI_LOGON_UI | MAPI_DIALOG, 0);
::FreeLibrary(mapiLib);
switch (returnCode)
{
case SUCCESS_SUCCESS:
case MAPI_USER_ABORT:
case MAPI_E_LOGIN_FAILURE:
return true;
default:
return false;
}
#endif
return false;
#elif defined(Q_OS_UNIX)
// TODO
return false;
#else
static_assert(false, "Implement this for another OS!");
return false;
#endif
}
} // namespace pdfviewer

View File

@@ -1,38 +0,0 @@
// Copyright (C) 2019-2021 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#ifndef PDFSENDMAIL_H
#define PDFSENDMAIL_H
#include <QString>
class QWidget;
namespace pdfviewer
{
class PDFSendMail
{
public:
PDFSendMail() = delete;
static bool sendMail(QWidget* parent, QString subject, QString fileName);
};
} // namespace pdfviewer
#endif // PDFSENDMAIL_H

File diff suppressed because it is too large Load Diff

View File

@@ -1,163 +0,0 @@
// Copyright (C) 2019-2023 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#ifndef PDFSIDEBARWIDGET_H
#define PDFSIDEBARWIDGET_H
#include "pdfglobal.h"
#include "pdfbookmarkmanager.h"
#include <QWidget>
class QPushButton;
class QToolButton;
class QWidget;
class QStandardItemModel;
class QSortFilterProxyModel;
namespace Ui
{
class PDFSidebarWidget;
}
namespace pdf
{
class PDFAction;
class PDFDocument;
class PDFCertificateInfo;
class PDFDrawWidgetProxy;
class PDFCertificateStore;
class PDFModifiedDocument;
class PDFThumbnailsItemModel;
class PDFOutlineTreeItemModel;
class PDFOptionalContentActivity;
class PDFAttachmentsTreeItemModel;
class PDFSignatureVerificationResult;
class PDFOptionalContentTreeItemModel;
}
namespace pdfviewer
{
class PDFTextToSpeech;
class PDFViewerSettings;
class PDFBookmarkItemModel;
class PDFSidebarWidget : public QWidget
{
Q_OBJECT
public:
explicit PDFSidebarWidget(pdf::PDFDrawWidgetProxy* proxy,
PDFTextToSpeech* textToSpeech,
pdf::PDFCertificateStore* certificateStore,
PDFBookmarkManager* bookmarkManager,
PDFViewerSettings* settings,
bool editableOutline,
QWidget* parent);
virtual ~PDFSidebarWidget() override;
enum Page
{
Invalid,
_BEGIN,
Outline = _BEGIN,
Thumbnails,
OptionalContent,
Attachments,
Speech,
Signatures,
Bookmarks,
Notes,
_END
};
void setDocument(const pdf::PDFModifiedDocument& document, const std::vector<pdf::PDFSignatureVerificationResult>& signatures);
/// Returns true, if all items in sidebar are empty
bool isEmpty() const;
/// Returns true, if page is empty
bool isEmpty(Page page) const;
/// Selects current page
void selectPage(Page page);
/// Returns list of valid pages (nonempty pages)
std::vector<Page> getValidPages() const;
/// Sets current pages (for example, selects the correct thumbnail)
void setCurrentPages(const std::vector<pdf::PDFInteger>& currentPages);
signals:
void actionTriggered(const pdf::PDFAction* action);
void documentModified(pdf::PDFModifiedDocument document);
private:
void updateGUI(Page preferredPage);
void updateButtons();
void updateSignatures(const std::vector<pdf::PDFSignatureVerificationResult>& signatures);
void updateNotes();
void onOutlineSearchText();
void onNotesSearchText();
void onPageButtonClicked();
void onOutlineItemClicked(const QModelIndex& index);
void onThumbnailsSizeChanged(int size);
void onAttachmentCustomContextMenuRequested(const QPoint& pos);
void onThumbnailClicked(const QModelIndex& index);
void onSignatureCustomContextMenuRequested(const QPoint& pos);
void onOutlineTreeViewContextMenuRequested(const QPoint& pos);
void onNotesTreeViewContextMenuRequested(const QPoint& pos);
void onOutlineItemsChanged();
void onBookmarkActivated(int index, PDFBookmarkManager::Bookmark bookmark);
void onBookmarsCurrentIndexChanged(const QModelIndex& current, const QModelIndex& previous);
void onBookmarkClicked(const QModelIndex& index);
void onNotesItemClicked(const QModelIndex& index);
struct PageInfo
{
QToolButton* button = nullptr;
QWidget* page = nullptr;
};
Ui::PDFSidebarWidget* ui;
pdf::PDFDrawWidgetProxy* m_proxy;
PDFTextToSpeech* m_textToSpeech;
pdf::PDFCertificateStore* m_certificateStore;
PDFBookmarkManager* m_bookmarkManager;
PDFViewerSettings* m_settings;
pdf::PDFOutlineTreeItemModel* m_outlineTreeModel;
QSortFilterProxyModel* m_outlineSortProxyTreeModel;
pdf::PDFThumbnailsItemModel* m_thumbnailsModel;
pdf::PDFOptionalContentTreeItemModel* m_optionalContentTreeModel;
PDFBookmarkItemModel* m_bookmarkItemModel;
QStandardItemModel* m_notesTreeModel;
QSortFilterProxyModel* m_notesSortProxyTreeModel;
const pdf::PDFDocument* m_document;
pdf::PDFOptionalContentActivity* m_optionalContentActivity;
pdf::PDFAttachmentsTreeItemModel* m_attachmentsTreeModel;
std::map<Page, PageInfo> m_pageInfo;
std::vector<pdf::PDFSignatureVerificationResult> m_signatures;
std::vector<pdf::PDFCertificateInfo> m_certificateInfos;
std::vector<std::pair<pdf::PDFObjectReference, pdf::PDFInteger>> m_markupAnnotations;
bool m_bookmarkChangeInProgress = false;
};
} // namespace pdfviewer
#endif // PDFSIDEBARWIDGET_H

View File

@@ -1,733 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PDFSidebarWidget</class>
<widget class="QWidget" name="PDFSidebarWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>404</width>
<height>778</height>
</rect>
</property>
<layout class="QHBoxLayout" name="sidebarLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QToolButton" name="outlineButton">
<property name="minimumSize">
<size>
<width>96</width>
<height>0</height>
</size>
</property>
<property name="font">
<font>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Outline</string>
</property>
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/sidebar-outline.svg</normaloff>:/resources/sidebar-outline.svg</iconset>
</property>
<property name="iconSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextUnderIcon</enum>
</property>
<property name="flat" stdset="0">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="thumbnailsButton">
<property name="minimumSize">
<size>
<width>96</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Thumbnails</string>
</property>
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/sidebar-thumbnails.svg</normaloff>:/resources/sidebar-thumbnails.svg</iconset>
</property>
<property name="iconSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextUnderIcon</enum>
</property>
<property name="flat" stdset="0">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="optionalContentButton">
<property name="minimumSize">
<size>
<width>96</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Visibility</string>
</property>
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/sidebar-visibility.svg</normaloff>:/resources/sidebar-visibility.svg</iconset>
</property>
<property name="iconSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextUnderIcon</enum>
</property>
<property name="flat" stdset="0">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="attachmentsButton">
<property name="minimumSize">
<size>
<width>96</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Attachments</string>
</property>
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/sidebar-attachment.svg</normaloff>:/resources/sidebar-attachment.svg</iconset>
</property>
<property name="iconSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextUnderIcon</enum>
</property>
<property name="flat" stdset="0">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="speechButton">
<property name="minimumSize">
<size>
<width>96</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Speech</string>
</property>
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/sidebar-speech.svg</normaloff>:/resources/sidebar-speech.svg</iconset>
</property>
<property name="iconSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextUnderIcon</enum>
</property>
<property name="flat" stdset="0">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="signaturesButton">
<property name="minimumSize">
<size>
<width>96</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Signatures</string>
</property>
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/sidebar-signature.svg</normaloff>:/resources/sidebar-signature.svg</iconset>
</property>
<property name="iconSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextUnderIcon</enum>
</property>
<property name="flat" stdset="0">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="bookmarksButton">
<property name="minimumSize">
<size>
<width>96</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Bookmarks</string>
</property>
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/sidebar-favourites.svg</normaloff>:/resources/sidebar-favourites.svg</iconset>
</property>
<property name="iconSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextUnderIcon</enum>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="notesButton">
<property name="minimumSize">
<size>
<width>96</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Notes</string>
</property>
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/sidebar-annotations.svg</normaloff>:/resources/sidebar-annotations.svg</iconset>
</property>
<property name="iconSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="shortcut">
<string>Ctrl+S</string>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextUnderIcon</enum>
</property>
</widget>
</item>
<item>
<spacer name="buttonSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex">
<number>6</number>
</property>
<widget class="QWidget" name="emptyPage"/>
<widget class="QWidget" name="outlinePage">
<layout class="QVBoxLayout" name="outlinePageLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="outlineSearchLayout">
<property name="leftMargin">
<number>10</number>
</property>
<property name="topMargin">
<number>10</number>
</property>
<property name="rightMargin">
<number>10</number>
</property>
<property name="bottomMargin">
<number>10</number>
</property>
<item>
<widget class="QLineEdit" name="outlineSearchLineEdit">
<property name="placeholderText">
<string>Search text or wildcard...</string>
</property>
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QTreeView" name="outlineTreeView"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="thumbnailsPage">
<layout class="QVBoxLayout" name="thumbnailsLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QWidget" name="thumbnailsToolbarWidget" native="true">
<layout class="QHBoxLayout" name="thumbnailsToolbarLayout">
<item>
<widget class="QToolButton" name="synchronizeThumbnailsButton">
<property name="toolTip">
<string>Synchronize thumbnails with current page</string>
</property>
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/synchronize.svg</normaloff>:/resources/synchronize.svg</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="thumbnailsSizeSlider">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>6</number>
</property>
<property name="value">
<number>3</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QListView" name="thumbnailsListView">
<property name="movement">
<enum>QListView::Static</enum>
</property>
<property name="resizeMode">
<enum>QListView::Adjust</enum>
</property>
<property name="viewMode">
<enum>QListView::IconMode</enum>
</property>
<property name="itemAlignment">
<set>Qt::AlignBottom|Qt::AlignHCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="optionalContentPage">
<layout class="QVBoxLayout" name="optionalContentPageLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QTreeView" name="optionalContentTreeView"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="attachmentsPage">
<layout class="QVBoxLayout" name="attachmentsPageLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QTreeView" name="attachmentsTreeView"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="bookmarksPage">
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QListView" name="bookmarksView">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="notesPage">
<layout class="QVBoxLayout" name="notesPageLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QVBoxLayout" name="notesSearchLayout">
<property name="leftMargin">
<number>10</number>
</property>
<property name="topMargin">
<number>10</number>
</property>
<property name="rightMargin">
<number>10</number>
</property>
<property name="bottomMargin">
<number>10</number>
</property>
<item>
<widget class="QLineEdit" name="notesSearchLineEdit">
<property name="placeholderText">
<string>Search text or wildcard...</string>
</property>
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QTreeView" name="notesTreeView">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="speechPage">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QComboBox" name="speechLocaleComboBox"/>
</item>
<item>
<widget class="QComboBox" name="speechVoiceComboBox"/>
</item>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="1">
<widget class="QSlider" name="speechRateEdit">
<property name="minimum">
<number>-10</number>
</property>
<property name="maximum">
<number>10</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="speechVolumeLabel">
<property name="text">
<string>Volume</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSlider" name="speechPitchEdit">
<property name="minimum">
<number>-10</number>
</property>
<property name="maximum">
<number>10</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="speechPitchLabel">
<property name="text">
<string>Pitch</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSlider" name="speechVolumeEdit">
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="speechRateLabel">
<property name="text">
<string>Rate</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="speechRateValueLabel"/>
</item>
<item row="1" column="2">
<widget class="QLabel" name="speechPitchValueLabel"/>
</item>
<item row="2" column="2">
<widget class="QLabel" name="speechVolumeValueLabel"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QToolButton" name="speechPlayButton">
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/play.svg</normaloff>:/resources/play.svg</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="speechPauseButton">
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/pause.svg</normaloff>:/resources/pause.svg</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="speechStopButton">
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/stop.svg</normaloff>:/resources/stop.svg</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="speechSynchronizeButton">
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/synchronize.svg</normaloff>:/resources/synchronize.svg</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QTextBrowser" name="speechActualTextEdit"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="signaturesPage">
<layout class="QVBoxLayout" name="signaturesPageLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QTreeWidget" name="signatureTreeWidget">
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="headerHidden">
<bool>true</bool>
</property>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="pdf4qtviewer.qrc"/>
</resources>
<connections/>
</ui>

View File

@@ -1,551 +0,0 @@
// Copyright (C) 2020-2022 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#include "pdftexttospeech.h"
#include "pdfviewersettings.h"
#include "pdfdrawspacecontroller.h"
#include "pdfcompiler.h"
#include "pdfdrawwidget.h"
#include <QLabel>
#include <QAction>
#include <QSlider>
#include <QComboBox>
#include <QToolButton>
#include <QTextBrowser>
#include <QTextToSpeech>
#include "pdfdbgheap.h"
namespace pdfviewer
{
PDFTextToSpeech::PDFTextToSpeech(QObject* parent) :
BaseClass(parent),
m_textToSpeech(nullptr),
m_document(nullptr),
m_proxy(nullptr),
m_state(Invalid),
m_initialized(false),
m_speechLocaleComboBox(nullptr),
m_speechVoiceComboBox(nullptr),
m_speechRateEdit(nullptr),
m_speechVolumeEdit(nullptr),
m_speechPitchEdit(nullptr),
m_speechPlayButton(nullptr),
m_speechPauseButton(nullptr),
m_speechStopButton(nullptr),
m_speechSynchronizeButton(nullptr),
m_speechRateValueLabel(nullptr),
m_speechPitchValueLabel(nullptr),
m_speechVolumeValueLabel(nullptr),
m_speechActualTextBrowser(nullptr)
{
}
bool PDFTextToSpeech::isValid() const
{
return m_document != nullptr;
}
void PDFTextToSpeech::setDocument(const pdf::PDFModifiedDocument& document)
{
if (m_document != document)
{
stop();
m_document = document;
if (m_textToSpeech)
{
m_state = m_document ? Ready : NoDocument;
}
else
{
// Set state to invalid, speech engine is not set
m_state = Invalid;
}
updateUI();
}
}
void PDFTextToSpeech::updateVoices()
{
QVector<QVoice> voices = m_textToSpeech->availableVoices();
m_speechVoiceComboBox->setUpdatesEnabled(false);
m_speechVoiceComboBox->clear();
for (const QVoice& voice : voices)
{
m_speechVoiceComboBox->addItem(QString("%1 (%2, %3)").arg(voice.name(), QVoice::genderName(voice.gender()), QVoice::ageName(voice.age())), voice.name());
}
m_speechVoiceComboBox->setUpdatesEnabled(true);
}
void PDFTextToSpeech::setSettings(const PDFViewerSettings* viewerSettings)
{
Q_ASSERT(viewerSettings);
if (!m_initialized)
{
// This object is not initialized yet
return;
}
// First, stop the engine
stop();
delete m_textToSpeech;
m_textToSpeech = nullptr;
const PDFViewerSettings::Settings& settings = viewerSettings->getSettings();
if (!settings.m_speechEngine.isEmpty())
{
m_textToSpeech = new QTextToSpeech(settings.m_speechEngine, this);
m_textToSpeech->setLocale(QLocale(settings.m_speechLocale));
connect(m_textToSpeech, &QTextToSpeech::stateChanged, this, &PDFTextToSpeech::updatePlay);
m_state = m_document ? Ready : NoDocument;
QVector<QLocale> locales = m_textToSpeech->availableLocales();
m_speechLocaleComboBox->setUpdatesEnabled(false);
m_speechLocaleComboBox->clear();
for (const QLocale& locale : locales)
{
m_speechLocaleComboBox->addItem(QString("%1 (%2)").arg(locale.nativeLanguageName(), locale.nativeTerritoryName()), locale.name());
}
m_speechLocaleComboBox->setUpdatesEnabled(true);
updateVoices();
}
else
{
// Set state to invalid, speech engine is not set
m_state = Invalid;
m_speechLocaleComboBox->clear();
m_speechVoiceComboBox->clear();
}
if (m_textToSpeech)
{
setLocale(settings.m_speechLocale);
setVoice(settings.m_speechVoice);
setRate(settings.m_speechRate);
setPitch(settings.m_speechPitch);
setVolume(settings.m_speechVolume);
}
updateUI();
}
void PDFTextToSpeech::setProxy(pdf::PDFDrawWidgetProxy* proxy)
{
m_proxy = proxy;
pdf::PDFAsynchronousTextLayoutCompiler* compiler = m_proxy->getTextLayoutCompiler();
connect(compiler, &pdf::PDFAsynchronousTextLayoutCompiler::textLayoutChanged, this, &PDFTextToSpeech::updatePlay);
}
void PDFTextToSpeech::initializeUI(QComboBox* speechLocaleComboBox,
QComboBox* speechVoiceComboBox,
QSlider* speechRateEdit,
QSlider* speechPitchEdit,
QSlider* speechVolumeEdit,
QToolButton* speechPlayButton,
QToolButton* speechPauseButton,
QToolButton* speechStopButton,
QToolButton* speechSynchronizeButton,
QLabel* speechRateValueLabel,
QLabel* speechPitchValueLabel,
QLabel* speechVolumeValueLabel,
QTextBrowser* speechActualTextBrowser)
{
Q_ASSERT(speechLocaleComboBox);
Q_ASSERT(speechVoiceComboBox);
Q_ASSERT(speechRateEdit);
Q_ASSERT(speechVolumeEdit);
Q_ASSERT(speechPitchEdit);
Q_ASSERT(speechPlayButton);
Q_ASSERT(speechPauseButton);
Q_ASSERT(speechStopButton);
Q_ASSERT(speechSynchronizeButton);
m_speechLocaleComboBox = speechLocaleComboBox;
m_speechVoiceComboBox = speechVoiceComboBox;
m_speechRateEdit = speechRateEdit;
m_speechVolumeEdit = speechVolumeEdit;
m_speechPitchEdit = speechPitchEdit;
m_speechPlayButton = speechPlayButton;
m_speechPauseButton = speechPauseButton;
m_speechStopButton = speechStopButton;
m_speechSynchronizeButton = speechSynchronizeButton;
m_speechRateValueLabel = speechRateValueLabel;
m_speechPitchValueLabel = speechPitchValueLabel;
m_speechVolumeValueLabel = speechVolumeValueLabel;
m_speechActualTextBrowser = speechActualTextBrowser;
connect(m_speechLocaleComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &PDFTextToSpeech::onLocaleChanged);
connect(m_speechVoiceComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &PDFTextToSpeech::onVoiceChanged);
connect(m_speechRateEdit, &QSlider::valueChanged, this, &PDFTextToSpeech::onRateChanged);
connect(m_speechPitchEdit, &QSlider::valueChanged, this, &PDFTextToSpeech::onPitchChanged);
connect(m_speechVolumeEdit, &QSlider::valueChanged, this, &PDFTextToSpeech::onVolumeChanged);
connect(m_speechPlayButton, &QToolButton::clicked, this, &PDFTextToSpeech::onPlayClicked);
connect(m_speechPauseButton, &QToolButton::clicked, this, &PDFTextToSpeech::onPauseClicked);
connect(m_speechStopButton, &QToolButton::clicked, this, &PDFTextToSpeech::onStopClicked);
m_initialized = true;
}
void PDFTextToSpeech::updateUI()
{
bool enableControls = false;
bool enablePlay = false;
bool enablePause = false;
bool enableStop = false;
switch (m_state)
{
case pdfviewer::PDFTextToSpeech::Invalid:
{
enableControls = false;
enablePlay = false;
enablePause = false;
enableStop = false;
break;
}
case pdfviewer::PDFTextToSpeech::NoDocument:
{
enableControls = true;
enablePlay = false;
enablePause = false;
enableStop = false;
break;
}
case pdfviewer::PDFTextToSpeech::Ready:
{
enableControls = true;
enablePlay = true;
enablePause = false;
enableStop = false;
break;
}
case pdfviewer::PDFTextToSpeech::Playing:
{
enableControls = true;
enablePlay = false;
enablePause = true;
enableStop = true;
break;
}
case pdfviewer::PDFTextToSpeech::Paused:
{
enableControls = true;
enablePlay = true;
enablePause = false;
enableStop = true;
break;
}
case pdfviewer::PDFTextToSpeech::Error:
{
enableControls = false;
enablePlay = false;
enablePause = false;
enableStop = false;
break;
}
default:
Q_ASSERT(false);
break;
}
m_speechLocaleComboBox->setEnabled(enableControls && m_speechLocaleComboBox->count() > 0);
m_speechVoiceComboBox->setEnabled(enableControls && m_speechVoiceComboBox->count() > 0);
m_speechRateEdit->setEnabled(enableControls);
m_speechVolumeEdit->setEnabled(enableControls);
m_speechPitchEdit->setEnabled(enableControls);
m_speechPlayButton->setEnabled(enablePlay);
m_speechPauseButton->setEnabled(enablePause);
m_speechStopButton->setEnabled(enableStop);
m_speechSynchronizeButton->setEnabled(enableControls);
}
void PDFTextToSpeech::stop()
{
switch (m_state)
{
case Playing:
case Paused:
{
m_textToSpeech->stop();
m_currentTextFlowIndex = 0;
m_currentPage = 0;
m_currentTextLayout = pdf::PDFTextLayout();
m_textFlows = pdf::PDFTextFlows();
m_state = Ready;
break;
}
default:
break;
}
updateUI();
}
void PDFTextToSpeech::setLocale(const QString& locale)
{
m_speechLocaleComboBox->setCurrentIndex(m_speechLocaleComboBox->findData(locale));
}
void PDFTextToSpeech::setVoice(const QString& voice)
{
m_speechVoiceComboBox->setCurrentIndex(m_speechVoiceComboBox->findData(voice));
}
void PDFTextToSpeech::setRate(const double rate)
{
pdf::PDFLinearInterpolation<double> interpolation(-1.0, 1.0, m_speechRateEdit->minimum(), m_speechRateEdit->maximum());
m_speechRateEdit->setValue(qRound(interpolation(rate)));
onRateChanged(m_speechRateEdit->value());
}
void PDFTextToSpeech::setPitch(const double pitch)
{
pdf::PDFLinearInterpolation<double> interpolation(-1.0, 1.0, m_speechPitchEdit->minimum(), m_speechPitchEdit->maximum());
m_speechPitchEdit->setValue(qRound(interpolation(pitch)));
onPitchChanged(m_speechPitchEdit->value());
}
void PDFTextToSpeech::setVolume(const double volume)
{
pdf::PDFLinearInterpolation<double> interpolation(0.0, 1.0, m_speechVolumeEdit->minimum(), m_speechVolumeEdit->maximum());
m_speechVolumeEdit->setValue(qRound(interpolation(volume)));
onVolumeChanged(m_speechVolumeEdit->value());
}
void PDFTextToSpeech::onLocaleChanged()
{
if (m_textToSpeech)
{
m_textToSpeech->setLocale(QLocale(m_speechLocaleComboBox->currentData().toString()));
updateVoices();
if (m_speechVoiceComboBox->currentIndex() == -1)
{
m_speechVoiceComboBox->setCurrentIndex(0);
}
}
}
void PDFTextToSpeech::onVoiceChanged()
{
if (m_textToSpeech)
{
QString voice = m_speechVoiceComboBox->currentData().toString();
for (const QVoice& voiceObject : m_textToSpeech->availableVoices())
{
if (voiceObject.name() == voice)
{
m_textToSpeech->setVoice(voiceObject);
}
}
}
}
void PDFTextToSpeech::onRateChanged(int rate)
{
if (m_textToSpeech)
{
pdf::PDFLinearInterpolation<double> interpolation(m_speechRateEdit->minimum(), m_speechRateEdit->maximum(), -1.0, 1.0);
double value = interpolation(rate);
m_textToSpeech->setRate(value);
m_speechRateValueLabel->setText(QString::number(value, 'f', 2));
}
}
void PDFTextToSpeech::onPitchChanged(int pitch)
{
if (m_textToSpeech)
{
pdf::PDFLinearInterpolation<double> interpolation(m_speechPitchEdit->minimum(), m_speechPitchEdit->maximum(), -1.0, 1.0);
double value = interpolation(pitch);
m_textToSpeech->setPitch(pitch);
m_speechPitchValueLabel->setText(QString::number(value, 'f', 2));
}
}
void PDFTextToSpeech::onVolumeChanged(int volume)
{
if (m_textToSpeech)
{
pdf::PDFLinearInterpolation<double> interpolation(m_speechVolumeEdit->minimum(), m_speechVolumeEdit->maximum(), 0.0, 1.0);
double value = interpolation(volume);
m_textToSpeech->setVolume(value);
m_speechVolumeValueLabel->setText(QString::number(value, 'f', 2));
}
}
void PDFTextToSpeech::onPlayClicked()
{
switch (m_state)
{
case Paused:
{
m_textToSpeech->resume();
m_state = Playing;
if (m_textToSpeech->state() == QTextToSpeech::Ready)
{
updatePlay();
}
break;
}
case Ready:
{
m_state = Playing;
m_currentTextFlowIndex = std::numeric_limits<size_t>::max();
m_currentPage = -1;
updatePlay();
break;
}
default:
break;
}
updateUI();
}
void PDFTextToSpeech::onPauseClicked()
{
Q_ASSERT(m_state == Playing);
if (m_state == Playing)
{
m_textToSpeech->pause();
m_state = Paused;
updateUI();
}
}
void PDFTextToSpeech::onStopClicked()
{
stop();
}
void PDFTextToSpeech::updatePlay()
{
if (m_state != Playing)
{
return;
}
Q_ASSERT(m_proxy);
Q_ASSERT(m_document);
// Jakub Melka: Check, if we have text layout. If not, then create it and return immediately.
// Otherwise, check, if we have something to say.
pdf::PDFAsynchronousTextLayoutCompiler* compiler = m_proxy->getTextLayoutCompiler();
if (!compiler->isTextLayoutReady())
{
compiler->makeTextLayout();
return;
}
QTextToSpeech::State state = m_textToSpeech->state();
if (state == QTextToSpeech::Ready)
{
if (m_currentPage == -1)
{
// Handle starting of document reading
std::vector<pdf::PDFInteger> currentPages = m_proxy->getWidget()->getDrawWidget()->getCurrentPages();
if (!currentPages.empty())
{
updateToNextPage(currentPages.front());
}
}
else if (++m_currentTextFlowIndex >= m_textFlows.size())
{
// Handle transition to next page
updateToNextPage(m_currentPage + 1);
}
if (m_currentTextFlowIndex < m_textFlows.size())
{
// Say next thing
const pdf::PDFTextFlow& textFlow = m_textFlows[m_currentTextFlowIndex];
QString text = textFlow.getText();
m_textToSpeech->say(text);
m_speechActualTextBrowser->setText(text);
}
else
{
// We are finished the reading
m_state = Ready;
}
}
else if (state == QTextToSpeech::Error)
{
m_state = Error;
}
updateUI();
}
void PDFTextToSpeech::updateToNextPage(pdf::PDFInteger pageIndex)
{
Q_ASSERT(m_document);
Q_ASSERT(m_state = Playing);
m_currentPage = pageIndex;
const pdf::PDFInteger pageCount = m_document->getCatalog()->getPageCount();
pdf::PDFAsynchronousTextLayoutCompiler* compiler = m_proxy->getTextLayoutCompiler();
Q_ASSERT(compiler->isTextLayoutReady());
m_currentTextLayout = pdf::PDFTextLayout();
m_textFlows.clear();
m_speechActualTextBrowser->clear();
// Find first nonempty page
while (m_currentPage < pageCount)
{
m_currentTextLayout = compiler->getTextLayout(m_currentPage);
m_textFlows = pdf::PDFTextFlow::createTextFlows(m_currentTextLayout, pdf::PDFTextFlow::SeparateBlocks | pdf::PDFTextFlow::RemoveSoftHyphen, m_currentPage);
if (!m_textFlows.empty())
{
break;
}
++m_currentPage;
}
if (m_currentPage < pageCount && m_speechSynchronizeButton->isChecked())
{
m_proxy->goToPage(m_currentPage);
}
m_currentTextFlowIndex = 0;
}
} // namespace pdfviewer

View File

@@ -1,148 +0,0 @@
// Copyright (C) 2020-2021 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#ifndef PDFTEXTTOSPEECH_H
#define PDFTEXTTOSPEECH_H
#include "pdftextlayout.h"
#include <QObject>
class QLabel;
class QSlider;
class QComboBox;
class QToolButton;
class QTextBrowser;
class QTextToSpeech;
namespace pdf
{
class PDFDocument;
class PDFDrawWidgetProxy;
class PDFModifiedDocument;
}
namespace pdfviewer
{
class PDFViewerSettings;
/// Text to speech engine used to reading the document
class PDFTextToSpeech : public QObject
{
Q_OBJECT
private:
using BaseClass = QObject;
public:
explicit PDFTextToSpeech(QObject* parent);
enum State
{
Invalid, ///< Text to speech engine is invalid (maybe bad engine)
NoDocument, ///< No document to read
Ready, ///< Ready to read the document contents
Playing, ///< Document is being read
Paused, ///< User paused the reading
Error ///< Error occured in text to speech engine
};
/// Returns true, if text to speech engine is valid and can be used
/// to synthetise text.
bool isValid() const;
/// Sets active document to text to speech engine
void setDocument(const pdf::PDFModifiedDocument& document);
/// Apply settings to the reader
void setSettings(const PDFViewerSettings* viewerSettings);
/// Set draw proxy
void setProxy(pdf::PDFDrawWidgetProxy* proxy);
/// Initialize the ui, which is used
void initializeUI(QComboBox* speechLocaleComboBox,
QComboBox* speechVoiceComboBox,
QSlider* speechRateEdit,
QSlider* speechPitchEdit,
QSlider* speechVolumeEdit,
QToolButton* speechPlayButton,
QToolButton* speechPauseButton,
QToolButton* speechStopButton,
QToolButton* speechSynchronizeButton,
QLabel* speechRateValueLabel,
QLabel* speechPitchValueLabel,
QLabel* speechVolumeValueLabel,
QTextBrowser* speechActualTextBrowser);
private:
/// Updates UI controls depending on the state
void updateUI();
/// Stop the engine, if it is reading
void stop();
void setLocale(const QString& locale);
void setVoice(const QString& voice);
void setRate(const double rate);
void setPitch(const double pitch);
void setVolume(const double volume);
void onLocaleChanged();
void onVoiceChanged();
void onRateChanged(int rate);
void onPitchChanged(int pitch);
void onVolumeChanged(int volume);
void onPlayClicked();
void onPauseClicked();
void onStopClicked();
void updatePlay();
void updateVoices();
void updateToNextPage(pdf::PDFInteger pageIndex);
QTextToSpeech* m_textToSpeech;
const pdf::PDFDocument* m_document;
pdf::PDFDrawWidgetProxy* m_proxy;
State m_state;
bool m_initialized;
QComboBox* m_speechLocaleComboBox;
QComboBox* m_speechVoiceComboBox;
QSlider* m_speechRateEdit;
QSlider* m_speechVolumeEdit;
QSlider* m_speechPitchEdit;
QToolButton* m_speechPlayButton;
QToolButton* m_speechPauseButton;
QToolButton* m_speechStopButton;
QToolButton* m_speechSynchronizeButton;
QLabel* m_speechRateValueLabel;
QLabel* m_speechPitchValueLabel;
QLabel* m_speechVolumeValueLabel;
QTextBrowser* m_speechActualTextBrowser;
pdf::PDFTextLayout m_currentTextLayout; ///< Text layout for actual page
pdf::PDFTextFlows m_textFlows; ///< Text flows for actual page
size_t m_currentTextFlowIndex = 0; ///< Index of current text flow
pdf::PDFInteger m_currentPage = 0; ///< Current page
};
} // namespace pdfviewer
#endif // PDFTEXTTOSPEECH_H

View File

@@ -1,125 +0,0 @@
// Copyright (C) 2020-2023 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#include "pdfundoredomanager.h"
#include "pdfdbgheap.h"
namespace pdfviewer
{
PDFUndoRedoManager::PDFUndoRedoManager(QObject* parent) :
BaseClass(parent)
{
}
PDFUndoRedoManager::~PDFUndoRedoManager()
{
}
void PDFUndoRedoManager::doUndo()
{
if (!canUndo())
{
// Undo operation can't be performed
return;
}
UndoRedoItem item = m_undoSteps.back();
m_undoSteps.pop_back();
m_isCurrentSaved = false;
m_redoSteps.insert(m_redoSteps.begin(), item);
clampUndoRedoSteps();
Q_EMIT undoRedoStateChanged();
Q_EMIT documentChangeRequest(pdf::PDFModifiedDocument(item.oldDocument, nullptr, item.flags));
}
void PDFUndoRedoManager::doRedo()
{
if (!canRedo())
{
// Redo operation can't be performed
return;
}
UndoRedoItem item = m_redoSteps.front();
m_redoSteps.erase(m_redoSteps.begin());
m_isCurrentSaved = false;
m_undoSteps.push_back(item);
clampUndoRedoSteps();
Q_EMIT undoRedoStateChanged();
Q_EMIT documentChangeRequest(pdf::PDFModifiedDocument(item.newDocument, nullptr, item.flags));
}
void PDFUndoRedoManager::clear()
{
if (canUndo() || canRedo())
{
m_undoSteps.clear();
m_redoSteps.clear();
Q_EMIT undoRedoStateChanged();
}
}
void PDFUndoRedoManager::createUndo(pdf::PDFModifiedDocument document, pdf::PDFDocumentPointer oldDocument)
{
m_undoSteps.emplace_back(oldDocument, document, document.getFlags());
m_redoSteps.clear();
m_isCurrentSaved = false;
clampUndoRedoSteps();
Q_EMIT undoRedoStateChanged();
}
void PDFUndoRedoManager::setMaximumSteps(size_t undoLimit, size_t redoLimit)
{
if (m_undoLimit != undoLimit || m_redoLimit != redoLimit)
{
m_undoLimit = undoLimit;
m_redoLimit = redoLimit;
clampUndoRedoSteps();
Q_EMIT undoRedoStateChanged();
}
}
void PDFUndoRedoManager::clampUndoRedoSteps()
{
if (m_undoSteps.size() > m_undoLimit)
{
// We erase from oldest steps to newest
m_undoSteps.erase(m_undoSteps.begin(), std::next(m_undoSteps.begin(), m_undoSteps.size() - m_undoLimit));
}
if (m_redoSteps.size() > m_redoLimit)
{
// Newest steps are erased
m_redoSteps.resize(m_redoLimit);
}
}
bool PDFUndoRedoManager::isCurrentSaved() const
{
return m_isCurrentSaved;
}
void PDFUndoRedoManager::setIsCurrentSaved(bool newIsCurrentSaved)
{
m_isCurrentSaved = newIsCurrentSaved;
}
} // namespace pdfviewer

View File

@@ -1,111 +0,0 @@
// Copyright (C) 2020-2023 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#ifndef PDFUNDOREDOMANAGER_H
#define PDFUNDOREDOMANAGER_H
#include "pdfdocument.h"
#include <QObject>
namespace pdfviewer
{
/// Undo/Redo document manager, it is managing undo and redo steps,
/// when document is modified.
class PDFUndoRedoManager : public QObject
{
Q_OBJECT
private:
using BaseClass = QObject;
public:
explicit PDFUndoRedoManager(QObject* parent);
virtual ~PDFUndoRedoManager() override;
bool canUndo() const { return !m_undoSteps.empty(); }
bool canRedo() const { return !m_redoSteps.empty(); }
/// Performs single undo step. If Undo action can't be performed,
/// then nothing happens.
void doUndo();
/// Performs single redo step. If Redo action can't be performed,
/// then nothing happens.
void doRedo();
/// Clears all undo/redo steps
void clear();
/// Create undo action (after document modification)
/// \param document Document created by modification
/// \param oldDocument Old document
void createUndo(pdf::PDFModifiedDocument document, pdf::PDFDocumentPointer oldDocument);
/// Sets maximum steps for undo/redo
/// \param undoLimit Maximum undo steps
/// \param redoLimit Maximum redo steps
void setMaximumSteps(size_t undoLimit, size_t redoLimit);
/// Returns true, if document was saved
bool isCurrentSaved() const;
/// Sets flag, if document was saved
void setIsCurrentSaved(bool newIsCurrentSaved = true);
signals:
/// This signals are emitted, when undo/redo action availability has
/// been changed (for example, user pressed undo/redo action)
void undoRedoStateChanged();
/// This signal is being emitted, when user performs undo/redo action.
/// Before signal is emitted, this object is in corrected state, as action
/// is performed.
/// \param document Document
void documentChangeRequest(pdf::PDFModifiedDocument document);
private:
/// Clamps undo/redo steps so they fit the limits
void clampUndoRedoSteps();
struct UndoRedoItem
{
explicit inline UndoRedoItem() = default;
explicit inline UndoRedoItem(pdf::PDFDocumentPointer oldDocument, pdf::PDFDocumentPointer newDocument, pdf::PDFModifiedDocument::ModificationFlags flags) :
oldDocument(qMove(oldDocument)),
newDocument(qMove(newDocument)),
flags(flags)
{
}
pdf::PDFDocumentPointer oldDocument;
pdf::PDFDocumentPointer newDocument;
pdf::PDFModifiedDocument::ModificationFlags flags = pdf::PDFModifiedDocument::None;
};
size_t m_undoLimit = 0;
size_t m_redoLimit = 0;
std::vector<UndoRedoItem> m_undoSteps;
std::vector<UndoRedoItem> m_redoSteps;
bool m_isCurrentSaved = true;
};
} // namespace pdfviewer
#endif // PDFUNDOREDOMANAGER_H

View File

@@ -1,33 +0,0 @@
// Copyright (C) 2020-2021 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#ifndef PDFVIEWERGLOBAL_H
#define PDFVIEWERGLOBAL_H
#include <pdf4qtviewer_export.h>
#if !defined(PDF4QTVIEWERLIBSHARED_EXPORT)
#if defined(PDF4QTVIEWER_LIBRARY)
# define PDF4QTVIEWERLIBSHARED_EXPORT Q_DECL_EXPORT
#else
# define PDF4QTVIEWERLIBSHARED_EXPORT Q_DECL_IMPORT
#endif
#endif
#endif // PDFVIEWERGLOBAL_H

View File

@@ -1,580 +0,0 @@
// Copyright (C) 2019-2022 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#include "pdfviewermainwindow.h"
#include "ui_pdfviewermainwindow.h"
#include "pdfaboutdialog.h"
#include "pdfsidebarwidget.h"
#include "pdfadvancedfindwidget.h"
#include "pdfviewersettingsdialog.h"
#include "pdfdocumentpropertiesdialog.h"
#include "pdfrendertoimagesdialog.h"
#include "pdfdocumentreader.h"
#include "pdfvisitor.h"
#include "pdfstreamfilters.h"
#include "pdfdrawwidget.h"
#include "pdfdrawspacecontroller.h"
#include "pdfrenderingerrorswidget.h"
#include "pdffont.h"
#include "pdfitemmodels.h"
#include "pdfutils.h"
#include "pdfsendmail.h"
#include "pdfexecutionpolicy.h"
#include "pdfwidgetutils.h"
#include "pdfdocumentwriter.h"
#include "pdfsignaturehandler.h"
#include "pdfadvancedtools.h"
#include "pdfwidgetutils.h"
#include "pdfactioncombobox.h"
#include <QPainter>
#include <QFileDialog>
#include <QMessageBox>
#include <QCloseEvent>
#include <QApplication>
#include <QStandardPaths>
#include <QDockWidget>
#include <QTreeView>
#include <QLayout>
#include <QHeaderView>
#include <QInputDialog>
#include <QSpinBox>
#include <QLabel>
#include <QDoubleSpinBox>
#include <QDesktopServices>
#include <QFileDialog>
#include <QLockFile>
#include <QtPrintSupport/QPrinter>
#include <QtPrintSupport/QPrintDialog>
#include <QtConcurrent/QtConcurrent>
#include <QPluginLoader>
#include <QToolButton>
#include <QActionGroup>
#include "pdfdbgheap.h"
#ifdef Q_OS_WIN
#include "Windows.h"
#endif
namespace pdfviewer
{
PDFViewerMainWindow::PDFViewerMainWindow(QWidget* parent) :
QMainWindow(parent),
ui(new Ui::PDFViewerMainWindow),
m_actionManager(new PDFActionManager(this)),
m_programController(new PDFProgramController(this)),
m_sidebarWidget(nullptr),
m_sidebarDockWidget(nullptr),
m_advancedFindWidget(nullptr),
m_advancedFindDockWidget(nullptr),
m_pageNumberSpinBox(nullptr),
m_pageNumberLabel(nullptr),
m_pageZoomSpinBox(nullptr),
m_isLoadingUI(false),
m_progress(new pdf::PDFProgress(this)),
m_progressTaskbarIndicator(new PDFWinTaskBarProgress(this)),
m_progressBarOnStatusBar(nullptr),
m_progressBarLeftLabelOnStatusBar(nullptr),
m_isChangingProgressStep(false)
{
ui->setupUi(this);
setAcceptDrops(true);
// Initialize toolbar icon size
adjustToolbar(ui->mainToolBar);
ui->mainToolBar->setWindowTitle(tr("Standard"));
// Initialize status bar
m_progressBarOnStatusBar = new QProgressBar(this);
m_progressBarOnStatusBar->setHidden(true);
m_progressBarLeftLabelOnStatusBar = new QLabel(this);
m_progressBarLeftLabelOnStatusBar->setHidden(true);
statusBar()->addPermanentWidget(m_progressBarLeftLabelOnStatusBar);
statusBar()->addPermanentWidget(m_progressBarOnStatusBar);
// Initialize actions
m_actionManager->setAction(PDFActionManager::Open, ui->actionOpen);
m_actionManager->setAction(PDFActionManager::Close, ui->actionClose);
m_actionManager->setAction(PDFActionManager::AutomaticDocumentRefresh, ui->actionAutomaticDocumentRefresh);
m_actionManager->setAction(PDFActionManager::Quit, ui->actionQuit);
m_actionManager->setAction(PDFActionManager::ZoomIn, ui->actionZoom_In);
m_actionManager->setAction(PDFActionManager::ZoomOut, ui->actionZoom_Out);
m_actionManager->setAction(PDFActionManager::Find, ui->actionFind);
m_actionManager->setAction(PDFActionManager::FindPrevious, ui->actionFindPrevious);
m_actionManager->setAction(PDFActionManager::FindNext, ui->actionFindNext);
m_actionManager->setAction(PDFActionManager::SelectTextAll, ui->actionSelectTextAll);
m_actionManager->setAction(PDFActionManager::DeselectText, ui->actionDeselectText);
m_actionManager->setAction(PDFActionManager::CopyText, ui->actionCopyText);
m_actionManager->setAction(PDFActionManager::RotateRight, ui->actionRotateRight);
m_actionManager->setAction(PDFActionManager::RotateLeft, ui->actionRotateLeft);
m_actionManager->setAction(PDFActionManager::Print, ui->actionPrint);
m_actionManager->setAction(PDFActionManager::Undo, ui->actionUndo);
m_actionManager->setAction(PDFActionManager::Redo, ui->actionRedo);
m_actionManager->setAction(PDFActionManager::Save, ui->actionSave);
m_actionManager->setAction(PDFActionManager::SaveAs, ui->actionSave_As);
m_actionManager->setAction(PDFActionManager::GoToDocumentStart, ui->actionGoToDocumentStart);
m_actionManager->setAction(PDFActionManager::GoToDocumentEnd, ui->actionGoToDocumentEnd);
m_actionManager->setAction(PDFActionManager::GoToNextPage, ui->actionGoToNextPage);
m_actionManager->setAction(PDFActionManager::GoToPreviousPage, ui->actionGoToPreviousPage);
m_actionManager->setAction(PDFActionManager::GoToNextLine, ui->actionGoToNextLine);
m_actionManager->setAction(PDFActionManager::GoToPreviousLine, ui->actionGoToPreviousLine);
m_actionManager->setAction(PDFActionManager::CreateStickyNoteComment, ui->actionStickyNoteComment);
m_actionManager->setAction(PDFActionManager::CreateStickyNoteHelp, ui->actionStickyNoteHelp);
m_actionManager->setAction(PDFActionManager::CreateStickyNoteInsert, ui->actionStickyNoteInsert);
m_actionManager->setAction(PDFActionManager::CreateStickyNoteKey, ui->actionStickyNoteKey);
m_actionManager->setAction(PDFActionManager::CreateStickyNoteNewParagraph, ui->actionStickyNoteNewParagraph);
m_actionManager->setAction(PDFActionManager::CreateStickyNoteNote, ui->actionStickyNoteNote);
m_actionManager->setAction(PDFActionManager::CreateStickyNoteParagraph, ui->actionStickyNoteParagraph);
m_actionManager->setAction(PDFActionManager::CreateTextHighlight, ui->actionCreateTextHighlight);
m_actionManager->setAction(PDFActionManager::CreateTextUnderline, ui->actionCreateTextUnderline);
m_actionManager->setAction(PDFActionManager::CreateTextStrikeout, ui->actionCreateTextStrikeout);
m_actionManager->setAction(PDFActionManager::CreateTextSquiggly, ui->actionCreateTextSquiggly);
m_actionManager->setAction(PDFActionManager::CreateHyperlink, ui->actionCreateHyperlink);
m_actionManager->setAction(PDFActionManager::CreateInlineText, ui->actionInlineText);
m_actionManager->setAction(PDFActionManager::CreateStraightLine, ui->actionCreateStraightLine);
m_actionManager->setAction(PDFActionManager::CreatePolyline, ui->actionCreatePolyline);
m_actionManager->setAction(PDFActionManager::CreateRectangle, ui->actionCreateRectangle);
m_actionManager->setAction(PDFActionManager::CreatePolygon, ui->actionCreatePolygon);
m_actionManager->setAction(PDFActionManager::CreateEllipse, ui->actionCreateEllipse);
m_actionManager->setAction(PDFActionManager::CreateFreehandCurve, ui->actionCreateFreehandCurve);
m_actionManager->setAction(PDFActionManager::RenderOptionAntialiasing, ui->actionRenderOptionAntialiasing);
m_actionManager->setAction(PDFActionManager::RenderOptionTextAntialiasing, ui->actionRenderOptionTextAntialiasing);
m_actionManager->setAction(PDFActionManager::RenderOptionSmoothPictures, ui->actionRenderOptionSmoothPictures);
m_actionManager->setAction(PDFActionManager::RenderOptionIgnoreOptionalContentSettings, ui->actionRenderOptionIgnoreOptionalContentSettings);
m_actionManager->setAction(PDFActionManager::RenderOptionDisplayRenderTimes, ui->actionRenderOptionDisplayRenderTimes);
m_actionManager->setAction(PDFActionManager::RenderOptionDisplayAnnotations, ui->actionRenderOptionDisplayAnnotations);
m_actionManager->setAction(PDFActionManager::RenderOptionInvertColors, ui->actionColorInvert);
m_actionManager->setAction(PDFActionManager::RenderOptionGrayscale, ui->actionColorGrayscale);
m_actionManager->setAction(PDFActionManager::RenderOptionHighContrast, ui->actionColorHighContrast);
m_actionManager->setAction(PDFActionManager::RenderOptionBitonal, ui->actionColorBitonal);
m_actionManager->setAction(PDFActionManager::RenderOptionCustomColors, ui->actionColorCustom);
m_actionManager->setAction(PDFActionManager::RenderOptionShowTextBlocks, ui->actionShow_Text_Blocks);
m_actionManager->setAction(PDFActionManager::RenderOptionShowTextLines, ui->actionShow_Text_Lines);
m_actionManager->setAction(PDFActionManager::Properties, ui->actionProperties);
m_actionManager->setAction(PDFActionManager::Options, ui->actionOptions);
m_actionManager->setAction(PDFActionManager::ResetToFactorySettings, ui->actionResetToFactorySettings);
m_actionManager->setAction(PDFActionManager::CertificateManager, ui->actionCertificateManager);
m_actionManager->setAction(PDFActionManager::GetSource, ui->actionGetSource);
m_actionManager->setAction(PDFActionManager::BecomeSponsor, ui->actionBecomeASponsor);
m_actionManager->setAction(PDFActionManager::About, ui->actionAbout);
m_actionManager->setAction(PDFActionManager::SendByMail, ui->actionSend_by_E_Mail);
m_actionManager->setAction(PDFActionManager::RenderToImages, ui->actionRender_to_Images);
m_actionManager->setAction(PDFActionManager::Optimize, ui->actionOptimize);
m_actionManager->setAction(PDFActionManager::Sanitize, ui->actionSanitize);
m_actionManager->setAction(PDFActionManager::CreateBitonalDocument, ui->actionCreateBitonalDocument);
m_actionManager->setAction(PDFActionManager::Encryption, ui->actionEncryption);
m_actionManager->setAction(PDFActionManager::FitPage, ui->actionFitPage);
m_actionManager->setAction(PDFActionManager::FitWidth, ui->actionFitWidth);
m_actionManager->setAction(PDFActionManager::FitHeight, ui->actionFitHeight);
m_actionManager->setAction(PDFActionManager::ShowRenderingErrors, ui->actionRendering_Errors);
m_actionManager->setAction(PDFActionManager::PageLayoutSinglePage, ui->actionPageLayoutSinglePage);
m_actionManager->setAction(PDFActionManager::PageLayoutContinuous, ui->actionPageLayoutContinuous);
m_actionManager->setAction(PDFActionManager::PageLayoutTwoPages, ui->actionPageLayoutTwoPages);
m_actionManager->setAction(PDFActionManager::PageLayoutTwoColumns, ui->actionPageLayoutTwoColumns);
m_actionManager->setAction(PDFActionManager::PageLayoutFirstPageOnRightSide, ui->actionFirstPageOnRightSide);
m_actionManager->setAction(PDFActionManager::ToolSelectText, ui->actionSelectText);
m_actionManager->setAction(PDFActionManager::ToolSelectTable, ui->actionSelectTable);
m_actionManager->setAction(PDFActionManager::ToolMagnifier, ui->actionMagnifier);
m_actionManager->setAction(PDFActionManager::ToolScreenshot, ui->actionScreenshot);
m_actionManager->setAction(PDFActionManager::ToolExtractImage, ui->actionExtractImage);
m_actionManager->setAction(PDFActionManager::BookmarkPage, ui->actionBookmarkPage);
m_actionManager->setAction(PDFActionManager::BookmarkGoToNext, ui->actionGotoNextBookmark);
m_actionManager->setAction(PDFActionManager::BookmarkGoToPrevious, ui->actionGotoPreviousBookmark);
m_actionManager->setAction(PDFActionManager::BookmarkExport, ui->actionBookmarkExport);
m_actionManager->setAction(PDFActionManager::BookmarkImport, ui->actionBookmarkImport);
m_actionManager->setAction(PDFActionManager::BookmarkGenerateAutomatically, ui->actionBookmarkAutoGenerate);
m_actionManager->initActions(pdf::PDFWidgetUtils::scaleDPI(this, QSize(24, 24)), true);
for (QAction* action : m_programController->getRecentFileManager()->getActions())
{
ui->menuFile->insertAction(ui->actionQuit, action);
}
ui->menuFile->insertSeparator(ui->actionQuit);
connect(ui->actionQuit, &QAction::triggered, this, &PDFViewerMainWindow::onActionQuitTriggered);
m_pageNumberSpinBox = new QSpinBox(this);
m_pageNumberSpinBox->setObjectName("pageNumberSpinBox");
m_pageNumberLabel = new QLabel(this);
m_pageNumberLabel->setObjectName("pageNumberLabel");
m_pageNumberSpinBox->setFixedWidth(pdf::PDFWidgetUtils::scaleDPI_x(m_pageNumberSpinBox, 80));
m_pageNumberSpinBox->setAlignment(Qt::AlignCenter);
connect(m_pageNumberSpinBox, &QSpinBox::editingFinished, this, &PDFViewerMainWindow::onPageNumberSpinboxEditingFinished);
for (QAction* action : m_actionManager->getActionGroup(PDFActionManager::CreateStampGroup)->actions())
{
ui->menuStamp->addAction(action);
}
// Page control
ui->mainToolBar->addSeparator();
ui->mainToolBar->addAction(ui->actionGoToDocumentStart);
ui->mainToolBar->addAction(ui->actionGoToPreviousPage);
ui->mainToolBar->addWidget(m_pageNumberSpinBox);
ui->mainToolBar->addWidget(m_pageNumberLabel);
ui->mainToolBar->addAction(ui->actionGoToNextPage);
ui->mainToolBar->addAction(ui->actionGoToDocumentEnd);
// Zoom
ui->mainToolBar->addSeparator();
ui->mainToolBar->addAction(ui->actionZoom_In);
ui->mainToolBar->addAction(ui->actionZoom_Out);
m_pageZoomSpinBox = new QDoubleSpinBox(this);
m_pageZoomSpinBox->setObjectName("pageZoomSpinBox");
m_pageZoomSpinBox->setMinimum(pdf::PDFDrawWidgetProxy::getMinZoom() * 100);
m_pageZoomSpinBox->setMaximum(pdf::PDFDrawWidgetProxy::getMaxZoom() * 100);
m_pageZoomSpinBox->setDecimals(2);
m_pageZoomSpinBox->setSuffix(tr("%"));
m_pageZoomSpinBox->setFixedWidth(pdf::PDFWidgetUtils::scaleDPI_x(m_pageNumberSpinBox, 80));
m_pageZoomSpinBox->setAlignment(Qt::AlignVCenter | Qt::AlignRight);
connect(m_pageZoomSpinBox, &QDoubleSpinBox::editingFinished, this, &PDFViewerMainWindow::onPageZoomSpinboxEditingFinished);
ui->mainToolBar->addWidget(m_pageZoomSpinBox);
// Fit page, width, height
ui->mainToolBar->addAction(ui->actionFitPage);
ui->mainToolBar->addAction(ui->actionFitWidth);
ui->mainToolBar->addAction(ui->actionFitHeight);
ui->mainToolBar->addSeparator();
// Tools
ui->mainToolBar->addAction(ui->actionSelectText);
ui->mainToolBar->addAction(ui->actionSelectTable);
ui->mainToolBar->addAction(ui->actionCreateTextHighlight);
ui->mainToolBar->addAction(ui->actionCreateTextUnderline);
ui->mainToolBar->addAction(ui->actionCreateTextStrikeout);
ui->mainToolBar->addAction(ui->actionCreateTextSquiggly);
ui->mainToolBar->addAction(ui->actionMagnifier);
ui->mainToolBar->addAction(ui->actionScreenshot);
ui->mainToolBar->addAction(ui->actionExtractImage);
ui->mainToolBar->addSeparator();
// Special tools
QToolButton* insertStickyNoteButton = m_actionManager->createToolButtonForActionGroup(PDFActionManager::CreateStickyNoteGroup, ui->mainToolBar);
ui->mainToolBar->addWidget(insertStickyNoteButton);
ui->mainToolBar->addSeparator();
m_programController->initialize(PDFProgramController::AllFeatures, this, this, m_actionManager, m_progress);
setCentralWidget(m_programController->getPdfWidget());
setFocusProxy(m_programController->getPdfWidget());
m_sidebarWidget = new PDFSidebarWidget(m_programController->getPdfWidget()->getDrawWidgetProxy(), m_programController->getTextToSpeech(), m_programController->getCertificateStore(), m_programController->getBookmarkManager(), m_programController->getSettings(), true, this);
m_sidebarDockWidget = new QDockWidget(tr("Sidebar"), this);
m_sidebarDockWidget->setObjectName("SidebarDockWidget");
m_sidebarDockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
m_sidebarDockWidget->setWidget(m_sidebarWidget);
addDockWidget(Qt::LeftDockWidgetArea, m_sidebarDockWidget);
m_sidebarDockWidget->hide();
connect(m_sidebarWidget, &PDFSidebarWidget::actionTriggered, m_programController, &PDFProgramController::onActionTriggered);
connect(m_sidebarWidget, &PDFSidebarWidget::documentModified, m_programController, &PDFProgramController::onDocumentModified);
m_advancedFindWidget = new PDFAdvancedFindWidget(m_programController->getPdfWidget()->getDrawWidgetProxy(), this);
m_advancedFindDockWidget = new QDockWidget(tr("Advanced find"), this);
m_advancedFindDockWidget->setObjectName("AdvancedFind");
m_advancedFindDockWidget->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
m_advancedFindDockWidget->setWidget(m_advancedFindWidget);
addDockWidget(Qt::BottomDockWidgetArea, m_advancedFindDockWidget);
m_advancedFindDockWidget->hide();
QAction* toggleAdvancedFindAction = m_advancedFindDockWidget->toggleViewAction();
toggleAdvancedFindAction->setObjectName("actionAdvancedFind");
toggleAdvancedFindAction->setText(tr("Advanced Find..."));
toggleAdvancedFindAction->setShortcut(QKeySequence("Ctrl+Shift+F"));
toggleAdvancedFindAction->setIcon(QIcon(":/resources/find-advanced.svg"));
ui->menuEdit->insertAction(nullptr, toggleAdvancedFindAction);
m_actionManager->addAdditionalAction(m_advancedFindDockWidget->toggleViewAction());
ui->menuView->addSeparator();
ui->menuView->addAction(m_sidebarDockWidget->toggleViewAction());
m_sidebarDockWidget->toggleViewAction()->setObjectName("actionSidebar");
m_actionManager->addAdditionalAction(m_sidebarDockWidget->toggleViewAction());
connect(m_progress, &pdf::PDFProgress::progressStarted, this, &PDFViewerMainWindow::onProgressStarted);
connect(m_progress, &pdf::PDFProgress::progressStep, this, &PDFViewerMainWindow::onProgressStep);
connect(m_progress, &pdf::PDFProgress::progressFinished, this, &PDFViewerMainWindow::onProgressFinished);
PDFActionComboBox* actionComboBox = new PDFActionComboBox(this);
menuBar()->setCornerWidget(actionComboBox);
m_programController->finishInitialization();
updateDeveloperMenu();
if (pdf::PDFToolManager* toolManager = m_programController->getToolManager())
{
connect(toolManager, &pdf::PDFToolManager::messageDisplayRequest, statusBar(), &QStatusBar::showMessage);
}
m_actionManager->styleActions();
m_programController->initActionComboBox(actionComboBox);
}
PDFViewerMainWindow::~PDFViewerMainWindow()
{
delete m_programController;
m_programController = nullptr;
delete m_actionManager;
m_actionManager = nullptr;
delete ui;
}
void PDFViewerMainWindow::onActionQuitTriggered()
{
close();
}
void PDFViewerMainWindow::onPageNumberSpinboxEditingFinished()
{
if (m_isLoadingUI)
{
return;
}
if (m_pageNumberSpinBox->hasFocus())
{
m_programController->getPdfWidget()->setFocus();
}
m_programController->getPdfWidget()->getDrawWidgetProxy()->goToPage(m_pageNumberSpinBox->value() - 1);
}
void PDFViewerMainWindow::onPageZoomSpinboxEditingFinished()
{
if (m_isLoadingUI)
{
return;
}
if (m_pageZoomSpinBox->hasFocus())
{
m_programController->getPdfWidget()->setFocus();
}
m_programController->getPdfWidget()->getDrawWidgetProxy()->zoom(m_pageZoomSpinBox->value() / 100.0);
}
void PDFViewerMainWindow::onProgressStarted(pdf::ProgressStartupInfo info)
{
m_progressBarLeftLabelOnStatusBar->setText(info.text);
m_progressBarLeftLabelOnStatusBar->setVisible(!info.text.isEmpty());
m_progressBarOnStatusBar->setRange(0, 100);
m_progressBarOnStatusBar->reset();
m_progressBarOnStatusBar->show();
m_progressTaskbarIndicator->setRange(0, 100);
m_progressTaskbarIndicator->reset();
m_progressTaskbarIndicator->show();
m_programController->setIsBusy(true);
m_programController->updateActionsAvailability();
}
void PDFViewerMainWindow::onProgressStep(int percentage)
{
if (m_isChangingProgressStep)
{
return;
}
pdf::PDFTemporaryValueChange guard(&m_isChangingProgressStep, true);
m_progressBarOnStatusBar->setValue(percentage);
m_progressTaskbarIndicator->setValue(percentage);
}
void PDFViewerMainWindow::onProgressFinished()
{
m_progressBarLeftLabelOnStatusBar->hide();
m_progressBarOnStatusBar->hide();
m_progressTaskbarIndicator->hide();
m_programController->setIsBusy(false);
m_programController->updateActionsAvailability();
}
void PDFViewerMainWindow::updateDeveloperMenu()
{
bool isDeveloperMode = m_programController->getSettings()->getSettings().m_allowDeveloperMode;
ui->menuDeveloper->menuAction()->setVisible(isDeveloperMode);
}
void PDFViewerMainWindow::updateUI(bool fullUpdate)
{
pdf::PDFTemporaryValueChange guard(&m_isLoadingUI, true);
if (fullUpdate)
{
if (pdf::PDFDocument* document = m_programController->getDocument())
{
size_t pageCount = document->getCatalog()->getPageCount();
m_pageNumberSpinBox->setMinimum(1);
m_pageNumberSpinBox->setMaximum(static_cast<int>(pageCount));
m_pageNumberSpinBox->setEnabled(true);
m_pageNumberLabel->setText(tr(" / %1").arg(pageCount));
}
else
{
m_pageNumberSpinBox->setEnabled(false);
m_pageNumberLabel->setText(QString());
}
}
else
{
std::vector<pdf::PDFInteger> currentPages = m_programController->getPdfWidget()->getDrawWidget()->getCurrentPages();
if (!currentPages.empty())
{
m_pageNumberSpinBox->setValue(currentPages.front() + 1);
// Prefetch pages, if it is enabled
if (m_programController->getSettings()->isPagePrefetchingEnabled())
{
m_programController->getPdfWidget()->getDrawWidgetProxy()->prefetchPages(currentPages.back());
}
}
m_sidebarWidget->setCurrentPages(currentPages);
}
m_pageZoomSpinBox->setValue(m_programController->getPdfWidget()->getDrawWidgetProxy()->getZoom() * 100);
}
QMenu* PDFViewerMainWindow::addToolMenu(QString name)
{
return ui->menuTools->addMenu(name);
}
void PDFViewerMainWindow::setStatusBarMessage(QString message, int time)
{
statusBar()->showMessage(message, time);
}
void PDFViewerMainWindow::setDocument(const pdf::PDFModifiedDocument& document)
{
if (m_sidebarWidget)
{
m_sidebarWidget->setDocument(document, *m_programController->getSignatures());
}
if (m_advancedFindWidget)
{
m_advancedFindWidget->setDocument(document);
}
if (m_sidebarWidget)
{
if (m_sidebarWidget->isEmpty())
{
m_sidebarDockWidget->hide();
}
else if (document.hasReset() && !document.hasPreserveUndoRedo())
{
m_sidebarDockWidget->show();
}
}
if (!document && m_advancedFindDockWidget)
{
m_advancedFindDockWidget->hide();
}
}
void PDFViewerMainWindow::adjustToolbar(QToolBar* toolbar)
{
QSize iconSize = pdf::PDFWidgetUtils::scaleDPI(this, QSize(24, 24));
toolbar->setIconSize(iconSize);
}
pdf::PDFTextSelection PDFViewerMainWindow::getSelectedText() const
{
if (!m_advancedFindWidget)
{
return pdf::PDFTextSelection();
}
return m_advancedFindWidget->getSelectedText();
}
void PDFViewerMainWindow::closeEvent(QCloseEvent* event)
{
if (!m_programController->canClose())
{
// Jakub Melka: Do not allow to close the application, if document
// reading is running.
event->ignore();
}
else
{
if (!m_programController->askForSaveDocumentBeforeClose())
{
// User cancelled close operation
event->ignore();
return;
}
if (!m_programController->isFactorySettingsBeingRestored())
{
m_programController->writeSettings();
}
m_programController->closeDocument();
event->accept();
}
}
void PDFViewerMainWindow::showEvent(QShowEvent* event)
{
QMainWindow::showEvent(event);
m_progressTaskbarIndicator->setWindow(windowHandle());
}
void PDFViewerMainWindow::dragEnterEvent(QDragEnterEvent* event)
{
if (event->mimeData()->hasUrls())
{
event->setDropAction(Qt::LinkAction);
event->accept();
}
}
void PDFViewerMainWindow::dragMoveEvent(QDragMoveEvent* event)
{
if (event->mimeData()->hasUrls())
{
event->setDropAction(Qt::LinkAction);
event->accept();
}
}
void PDFViewerMainWindow::dropEvent(QDropEvent* event)
{
if (event->mimeData()->hasUrls())
{
QList<QUrl> urls = event->mimeData()->urls();
if (urls.size() == 1)
{
m_programController->openDocument(urls.front().toLocalFile());
event->acceptProposedAction();
}
}
}
} // namespace pdfviewer

View File

@@ -1,131 +0,0 @@
// Copyright (C) 2019-2022 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#ifndef PDFVIEWERMAINWINDOW_H
#define PDFVIEWERMAINWINDOW_H
#include "pdfglobal.h"
#include "pdfviewerglobal.h"
#include "pdfcatalog.h"
#include "pdfrenderer.h"
#include "pdfprogress.h"
#include "pdfdocument.h"
#include "pdfviewersettings.h"
#include "pdfdocumentreader.h"
#include "pdfdocumentpropertiesdialog.h"
#include "pdfwidgettool.h"
#include "pdfrecentfilemanager.h"
#include "pdftexttospeech.h"
#include "pdfannotation.h"
#include "pdfform.h"
#include "pdfundoredomanager.h"
#include "pdfplugin.h"
#include "pdfprogramcontroller.h"
#include "pdfwintaskbarprogress.h"
#include <QFuture>
#include <QTreeView>
#include <QMainWindow>
#include <QFutureWatcher>
#include <QLabel>
#include <QProgressBar>
class QLabel;
class QSpinBox;
class QSettings;
class QDoubleSpinBox;
namespace Ui
{
class PDFViewerMainWindow;
}
namespace pdf
{
class PDFAction;
class PDFWidget;
class PDFDocument;
class PDFOptionalContentTreeItemModel;
}
namespace pdfviewer
{
class PDFSidebarWidget;
class PDFAdvancedFindWidget;
class PDF4QTVIEWERLIBSHARED_EXPORT PDFViewerMainWindow : public QMainWindow, public IMainWindow
{
Q_OBJECT
public:
explicit PDFViewerMainWindow(QWidget *parent = nullptr);
virtual ~PDFViewerMainWindow() override;
virtual void closeEvent(QCloseEvent* event) override;
virtual void showEvent(QShowEvent* event) override;
PDFProgramController* getProgramController() const { return m_programController; }
virtual void updateUI(bool fullUpdate) override;
virtual QMenu* addToolMenu(QString name) override;
virtual void setStatusBarMessage(QString message, int time) override;
virtual void setDocument(const pdf::PDFModifiedDocument& document) override;
virtual void adjustToolbar(QToolBar* toolbar) override;
virtual pdf::PDFTextSelection getSelectedText() const override;
protected:
virtual void dragEnterEvent(QDragEnterEvent* event) override;
virtual void dragMoveEvent(QDragMoveEvent* event) override;
virtual void dropEvent(QDropEvent* event) override;
private:
void onActionQuitTriggered();
void onPageNumberSpinboxEditingFinished();
void onPageZoomSpinboxEditingFinished();
void onProgressStarted(pdf::ProgressStartupInfo info);
void onProgressStep(int percentage);
void onProgressFinished();
void updateDeveloperMenu();
QIcon createStickyNoteIcon(QString key) const;
Ui::PDFViewerMainWindow* ui;
PDFActionManager* m_actionManager;
PDFProgramController* m_programController;
PDFSidebarWidget* m_sidebarWidget;
QDockWidget* m_sidebarDockWidget;
PDFAdvancedFindWidget* m_advancedFindWidget;
QDockWidget* m_advancedFindDockWidget;
QSpinBox* m_pageNumberSpinBox;
QLabel* m_pageNumberLabel;
QDoubleSpinBox* m_pageZoomSpinBox;
bool m_isLoadingUI;
pdf::PDFProgress* m_progress;
PDFWinTaskBarProgress* m_progressTaskbarIndicator;
QProgressBar* m_progressBarOnStatusBar;
QLabel* m_progressBarLeftLabelOnStatusBar;
bool m_isChangingProgressStep;
};
} // namespace pdfviewer
#endif // PDFVIEWERMAINWINDOW_H

File diff suppressed because it is too large Load Diff

View File

@@ -1,469 +0,0 @@
// Copyright (C) 2020-2022 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#include "pdfviewermainwindowlite.h"
#include "ui_pdfviewermainwindowlite.h"
#include "pdfaboutdialog.h"
#include "pdfsidebarwidget.h"
#include "pdfadvancedfindwidget.h"
#include "pdfviewersettingsdialog.h"
#include "pdfdocumentpropertiesdialog.h"
#include "pdfrendertoimagesdialog.h"
#include "pdfdocumentreader.h"
#include "pdfvisitor.h"
#include "pdfstreamfilters.h"
#include "pdfdrawwidget.h"
#include "pdfdrawspacecontroller.h"
#include "pdfrenderingerrorswidget.h"
#include "pdffont.h"
#include "pdfitemmodels.h"
#include "pdfutils.h"
#include "pdfsendmail.h"
#include "pdfexecutionpolicy.h"
#include "pdfwidgetutils.h"
#include "pdfdocumentwriter.h"
#include "pdfsignaturehandler.h"
#include "pdfadvancedtools.h"
#include "pdfwidgetutils.h"
#include "pdfactioncombobox.h"
#include <QPainter>
#include <QSettings>
#include <QFileDialog>
#include <QMessageBox>
#include <QCloseEvent>
#include <QApplication>
#include <QStandardPaths>
#include <QDockWidget>
#include <QTreeView>
#include <QLayout>
#include <QHeaderView>
#include <QInputDialog>
#include <QSpinBox>
#include <QLabel>
#include <QDoubleSpinBox>
#include <QDesktopServices>
#include <QFileDialog>
#include <QLockFile>
#include <QtPrintSupport/QPrinter>
#include <QtPrintSupport/QPrintDialog>
#include <QtConcurrent/QtConcurrent>
#include <QPluginLoader>
#include <QToolButton>
#include <QActionGroup>
#include "pdfdbgheap.h"
#ifdef Q_OS_WIN
#include "Windows.h"
#endif
namespace pdfviewer
{
PDFViewerMainWindowLite::PDFViewerMainWindowLite(QWidget* parent) :
QMainWindow(parent),
ui(new Ui::PDFViewerMainWindowLite),
m_actionManager(new PDFActionManager(this)),
m_programController(new PDFProgramController(this)),
m_sidebarWidget(nullptr),
m_sidebarDockWidget(nullptr),
m_pageNumberSpinBox(nullptr),
m_pageNumberLabel(nullptr),
m_pageZoomSpinBox(nullptr),
m_isLoadingUI(false),
m_progress(new pdf::PDFProgress(this)),
m_progressTaskbarIndicator(new PDFWinTaskBarProgress(this)),
m_progressBarOnStatusBar(nullptr),
m_progressBarLeftLabelOnStatusBar(nullptr),
m_isChangingProgressStep(false)
{
ui->setupUi(this);
setAcceptDrops(true);
// Initialize toolbar icon size
adjustToolbar(ui->mainToolBar);
ui->mainToolBar->setWindowTitle(tr("Standard"));
// Initialize status bar
m_progressBarOnStatusBar = new QProgressBar(this);
m_progressBarOnStatusBar->setHidden(true);
m_progressBarLeftLabelOnStatusBar = new QLabel(this);
m_progressBarLeftLabelOnStatusBar->setHidden(true);
statusBar()->addPermanentWidget(m_progressBarLeftLabelOnStatusBar);
statusBar()->addPermanentWidget(m_progressBarOnStatusBar);
// Initialize actions
m_actionManager->setAction(PDFActionManager::Open, ui->actionOpen);
m_actionManager->setAction(PDFActionManager::Close, ui->actionClose);
m_actionManager->setAction(PDFActionManager::AutomaticDocumentRefresh, ui->actionAutomaticDocumentRefresh);
m_actionManager->setAction(PDFActionManager::Quit, ui->actionQuit);
m_actionManager->setAction(PDFActionManager::ZoomIn, ui->actionZoom_In);
m_actionManager->setAction(PDFActionManager::ZoomOut, ui->actionZoom_Out);
m_actionManager->setAction(PDFActionManager::RotateRight, ui->actionRotateRight);
m_actionManager->setAction(PDFActionManager::RotateLeft, ui->actionRotateLeft);
m_actionManager->setAction(PDFActionManager::Print, ui->actionPrint);
m_actionManager->setAction(PDFActionManager::GoToDocumentStart, ui->actionGoToDocumentStart);
m_actionManager->setAction(PDFActionManager::GoToDocumentEnd, ui->actionGoToDocumentEnd);
m_actionManager->setAction(PDFActionManager::GoToNextPage, ui->actionGoToNextPage);
m_actionManager->setAction(PDFActionManager::GoToPreviousPage, ui->actionGoToPreviousPage);
m_actionManager->setAction(PDFActionManager::GoToNextLine, ui->actionGoToNextLine);
m_actionManager->setAction(PDFActionManager::GoToPreviousLine, ui->actionGoToPreviousLine);
m_actionManager->setAction(PDFActionManager::RenderOptionAntialiasing, ui->actionRenderOptionAntialiasing);
m_actionManager->setAction(PDFActionManager::RenderOptionTextAntialiasing, ui->actionRenderOptionTextAntialiasing);
m_actionManager->setAction(PDFActionManager::RenderOptionSmoothPictures, ui->actionRenderOptionSmoothPictures);
m_actionManager->setAction(PDFActionManager::RenderOptionIgnoreOptionalContentSettings, ui->actionRenderOptionIgnoreOptionalContentSettings);
m_actionManager->setAction(PDFActionManager::RenderOptionDisplayRenderTimes, ui->actionRenderOptionDisplayRenderTimes);
m_actionManager->setAction(PDFActionManager::RenderOptionDisplayAnnotations, ui->actionRenderOptionDisplayAnnotations);
m_actionManager->setAction(PDFActionManager::RenderOptionInvertColors, ui->actionColorInvert);
m_actionManager->setAction(PDFActionManager::RenderOptionGrayscale, ui->actionColorGrayscale);
m_actionManager->setAction(PDFActionManager::RenderOptionHighContrast, ui->actionColorHighContrast);
m_actionManager->setAction(PDFActionManager::RenderOptionBitonal, ui->actionColorBitonal);
m_actionManager->setAction(PDFActionManager::RenderOptionCustomColors, ui->actionColorCustom);
m_actionManager->setAction(PDFActionManager::Properties, ui->actionProperties);
m_actionManager->setAction(PDFActionManager::Options, ui->actionOptions);
m_actionManager->setAction(PDFActionManager::ResetToFactorySettings, ui->actionResetToFactorySettings);
m_actionManager->setAction(PDFActionManager::CertificateManager, ui->actionCertificateManager);
m_actionManager->setAction(PDFActionManager::GetSource, ui->actionGetSource);
m_actionManager->setAction(PDFActionManager::BecomeSponsor, ui->actionBecomeASponsor);
m_actionManager->setAction(PDFActionManager::About, ui->actionAbout);
m_actionManager->setAction(PDFActionManager::SendByMail, ui->actionSend_by_E_Mail);
m_actionManager->setAction(PDFActionManager::FitPage, ui->actionFitPage);
m_actionManager->setAction(PDFActionManager::FitWidth, ui->actionFitWidth);
m_actionManager->setAction(PDFActionManager::FitHeight, ui->actionFitHeight);
m_actionManager->setAction(PDFActionManager::ShowRenderingErrors, ui->actionRendering_Errors);
m_actionManager->setAction(PDFActionManager::PageLayoutSinglePage, ui->actionPageLayoutSinglePage);
m_actionManager->setAction(PDFActionManager::PageLayoutContinuous, ui->actionPageLayoutContinuous);
m_actionManager->setAction(PDFActionManager::PageLayoutTwoPages, ui->actionPageLayoutTwoPages);
m_actionManager->setAction(PDFActionManager::PageLayoutTwoColumns, ui->actionPageLayoutTwoColumns);
m_actionManager->setAction(PDFActionManager::PageLayoutFirstPageOnRightSide, ui->actionFirstPageOnRightSide);
m_actionManager->setAction(PDFActionManager::BookmarkPage, ui->actionBookmarkPage);
m_actionManager->setAction(PDFActionManager::BookmarkGoToNext, ui->actionGotoNextBookmark);
m_actionManager->setAction(PDFActionManager::BookmarkGoToPrevious, ui->actionGotoPreviousBookmark);
m_actionManager->setAction(PDFActionManager::BookmarkExport, ui->actionBookmarkExport);
m_actionManager->setAction(PDFActionManager::BookmarkImport, ui->actionBookmarkImport);
m_actionManager->setAction(PDFActionManager::BookmarkGenerateAutomatically, ui->actionBookmarkAutoGenerate);
m_actionManager->initActions(pdf::PDFWidgetUtils::scaleDPI(this, QSize(24, 24)), true);
for (QAction* action : m_programController->getRecentFileManager()->getActions())
{
ui->menuFile->insertAction(ui->actionQuit, action);
}
ui->menuFile->insertSeparator(ui->actionQuit);
connect(ui->actionQuit, &QAction::triggered, this, &PDFViewerMainWindowLite::onActionQuitTriggered);
m_pageNumberSpinBox = new QSpinBox(this);
m_pageNumberLabel = new QLabel(this);
m_pageNumberSpinBox->setFixedWidth(pdf::PDFWidgetUtils::scaleDPI_x(m_pageNumberSpinBox, 80));
m_pageNumberSpinBox->setAlignment(Qt::AlignCenter);
connect(m_pageNumberSpinBox, &QSpinBox::editingFinished, this, &PDFViewerMainWindowLite::onPageNumberSpinboxEditingFinished);
// Page control
ui->mainToolBar->addSeparator();
ui->mainToolBar->addAction(ui->actionGoToDocumentStart);
ui->mainToolBar->addAction(ui->actionGoToPreviousPage);
ui->mainToolBar->addWidget(m_pageNumberSpinBox);
ui->mainToolBar->addWidget(m_pageNumberLabel);
ui->mainToolBar->addAction(ui->actionGoToNextPage);
ui->mainToolBar->addAction(ui->actionGoToDocumentEnd);
// Zoom
ui->mainToolBar->addSeparator();
ui->mainToolBar->addAction(ui->actionZoom_In);
ui->mainToolBar->addAction(ui->actionZoom_Out);
m_pageZoomSpinBox = new QDoubleSpinBox(this);
m_pageZoomSpinBox->setMinimum(pdf::PDFDrawWidgetProxy::getMinZoom() * 100);
m_pageZoomSpinBox->setMaximum(pdf::PDFDrawWidgetProxy::getMaxZoom() * 100);
m_pageZoomSpinBox->setDecimals(2);
m_pageZoomSpinBox->setSuffix(tr("%"));
m_pageZoomSpinBox->setFixedWidth(pdf::PDFWidgetUtils::scaleDPI_x(m_pageNumberSpinBox, 80));
m_pageZoomSpinBox->setAlignment(Qt::AlignVCenter | Qt::AlignRight);
connect(m_pageZoomSpinBox, &QDoubleSpinBox::editingFinished, this, &PDFViewerMainWindowLite::onPageZoomSpinboxEditingFinished);
ui->mainToolBar->addWidget(m_pageZoomSpinBox);
// Fit page, width, height
ui->mainToolBar->addAction(ui->actionFitPage);
ui->mainToolBar->addAction(ui->actionFitWidth);
ui->mainToolBar->addAction(ui->actionFitHeight);
ui->mainToolBar->addSeparator();
// Special tools
m_programController->initialize(PDFProgramController::TextToSpeech, this, this, m_actionManager, m_progress);
setCentralWidget(m_programController->getPdfWidget());
setFocusProxy(m_programController->getPdfWidget());
m_sidebarWidget = new PDFSidebarWidget(m_programController->getPdfWidget()->getDrawWidgetProxy(), m_programController->getTextToSpeech(), m_programController->getCertificateStore(), m_programController->getBookmarkManager(), m_programController->getSettings(), false, this);
m_sidebarDockWidget = new QDockWidget(tr("Sidebar"), this);
m_sidebarDockWidget->setObjectName("SidebarDockWidget");
m_sidebarDockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
m_sidebarDockWidget->setWidget(m_sidebarWidget);
addDockWidget(Qt::LeftDockWidgetArea, m_sidebarDockWidget);
m_sidebarDockWidget->hide();
connect(m_sidebarWidget, &PDFSidebarWidget::actionTriggered, m_programController, &PDFProgramController::onActionTriggered);
connect(m_sidebarWidget, &PDFSidebarWidget::documentModified, m_programController, &PDFProgramController::onDocumentModified);
ui->menuView->addSeparator();
ui->menuView->addAction(m_sidebarDockWidget->toggleViewAction());
m_sidebarDockWidget->toggleViewAction()->setObjectName("actionSidebar");
m_actionManager->addAdditionalAction(m_sidebarDockWidget->toggleViewAction());
connect(m_progress, &pdf::PDFProgress::progressStarted, this, &PDFViewerMainWindowLite::onProgressStarted);
connect(m_progress, &pdf::PDFProgress::progressStep, this, &PDFViewerMainWindowLite::onProgressStep);
connect(m_progress, &pdf::PDFProgress::progressFinished, this, &PDFViewerMainWindowLite::onProgressFinished);
PDFActionComboBox* actionComboBox = new PDFActionComboBox(this);
menuBar()->setCornerWidget(actionComboBox);
m_programController->finishInitialization();
if (pdf::PDFToolManager* toolManager = m_programController->getToolManager())
{
connect(toolManager, &pdf::PDFToolManager::messageDisplayRequest, statusBar(), &QStatusBar::showMessage);
}
m_actionManager->styleActions();
m_programController->initActionComboBox(actionComboBox);
}
PDFViewerMainWindowLite::~PDFViewerMainWindowLite()
{
delete m_programController;
m_programController = nullptr;
delete m_actionManager;
m_actionManager = nullptr;
delete ui;
}
void PDFViewerMainWindowLite::onActionQuitTriggered()
{
close();
}
void PDFViewerMainWindowLite::onPageNumberSpinboxEditingFinished()
{
if (m_isLoadingUI)
{
return;
}
if (m_pageNumberSpinBox->hasFocus())
{
m_programController->getPdfWidget()->setFocus();
}
m_programController->getPdfWidget()->getDrawWidgetProxy()->goToPage(m_pageNumberSpinBox->value() - 1);
}
void PDFViewerMainWindowLite::onPageZoomSpinboxEditingFinished()
{
if (m_isLoadingUI)
{
return;
}
if (m_pageZoomSpinBox->hasFocus())
{
m_programController->getPdfWidget()->setFocus();
}
m_programController->getPdfWidget()->getDrawWidgetProxy()->zoom(m_pageZoomSpinBox->value() / 100.0);
}
void PDFViewerMainWindowLite::onProgressStarted(pdf::ProgressStartupInfo info)
{
m_progressBarLeftLabelOnStatusBar->setText(info.text);
m_progressBarLeftLabelOnStatusBar->setVisible(!info.text.isEmpty());
m_progressBarOnStatusBar->setRange(0, 100);
m_progressBarOnStatusBar->reset();
m_progressBarOnStatusBar->show();
m_progressTaskbarIndicator->setRange(0, 100);
m_progressTaskbarIndicator->reset();
m_progressTaskbarIndicator->show();
m_programController->setIsBusy(true);
m_programController->updateActionsAvailability();
}
void PDFViewerMainWindowLite::onProgressStep(int percentage)
{
if (m_isChangingProgressStep)
{
return;
}
pdf::PDFTemporaryValueChange guard(&m_isChangingProgressStep, true);
m_progressBarOnStatusBar->setValue(percentage);
m_progressTaskbarIndicator->setValue(percentage);
}
void PDFViewerMainWindowLite::onProgressFinished()
{
m_progressBarLeftLabelOnStatusBar->hide();
m_progressBarOnStatusBar->hide();
m_progressTaskbarIndicator->hide();
m_programController->setIsBusy(false);
m_programController->updateActionsAvailability();
}
void PDFViewerMainWindowLite::updateUI(bool fullUpdate)
{
pdf::PDFTemporaryValueChange guard(&m_isLoadingUI, true);
if (fullUpdate)
{
if (pdf::PDFDocument* document = m_programController->getDocument())
{
size_t pageCount = document->getCatalog()->getPageCount();
m_pageNumberSpinBox->setMinimum(1);
m_pageNumberSpinBox->setMaximum(static_cast<int>(pageCount));
m_pageNumberSpinBox->setEnabled(true);
m_pageNumberLabel->setText(tr(" / %1").arg(pageCount));
}
else
{
m_pageNumberSpinBox->setEnabled(false);
m_pageNumberLabel->setText(QString());
}
}
else
{
std::vector<pdf::PDFInteger> currentPages = m_programController->getPdfWidget()->getDrawWidget()->getCurrentPages();
if (!currentPages.empty())
{
m_pageNumberSpinBox->setValue(currentPages.front() + 1);
// Prefetch pages, if it is enabled
if (m_programController->getSettings()->isPagePrefetchingEnabled())
{
m_programController->getPdfWidget()->getDrawWidgetProxy()->prefetchPages(currentPages.back());
}
}
m_sidebarWidget->setCurrentPages(currentPages);
}
m_pageZoomSpinBox->setValue(m_programController->getPdfWidget()->getDrawWidgetProxy()->getZoom() * 100);
}
QMenu* PDFViewerMainWindowLite::addToolMenu(QString name)
{
return ui->menuTools->addMenu(name);
}
void PDFViewerMainWindowLite::setStatusBarMessage(QString message, int time)
{
statusBar()->showMessage(message, time);
}
void PDFViewerMainWindowLite::setDocument(const pdf::PDFModifiedDocument& document)
{
if (m_sidebarWidget)
{
m_sidebarWidget->setDocument(document, *m_programController->getSignatures());
}
if (m_sidebarWidget)
{
if (m_sidebarWidget->isEmpty())
{
m_sidebarDockWidget->hide();
}
else
{
m_sidebarDockWidget->show();
}
}
}
void PDFViewerMainWindowLite::adjustToolbar(QToolBar* toolbar)
{
QSize iconSize = pdf::PDFWidgetUtils::scaleDPI(this, QSize(24, 24));
toolbar->setIconSize(iconSize);
}
pdf::PDFTextSelection PDFViewerMainWindowLite::getSelectedText() const
{
return pdf::PDFTextSelection();
}
void PDFViewerMainWindowLite::closeEvent(QCloseEvent* event)
{
if (!m_programController->canClose())
{
// Jakub Melka: Do not allow to close the application, if document
// reading is running.
event->ignore();
}
else
{
if (!m_programController->isFactorySettingsBeingRestored())
{
m_programController->writeSettings();
}
m_programController->closeDocument();
event->accept();
}
}
void PDFViewerMainWindowLite::showEvent(QShowEvent* event)
{
QMainWindow::showEvent(event);
m_progressTaskbarIndicator->setWindow(windowHandle());
}
void PDFViewerMainWindowLite::dragEnterEvent(QDragEnterEvent* event)
{
if (event->mimeData()->hasUrls())
{
event->setDropAction(Qt::LinkAction);
event->accept();
}
}
void PDFViewerMainWindowLite::dragMoveEvent(QDragMoveEvent* event)
{
if (event->mimeData()->hasUrls())
{
event->setDropAction(Qt::LinkAction);
event->accept();
}
}
void PDFViewerMainWindowLite::dropEvent(QDropEvent* event)
{
if (event->mimeData()->hasUrls())
{
QList<QUrl> urls = event->mimeData()->urls();
if (urls.size() == 1)
{
m_programController->openDocument(urls.front().toLocalFile());
event->acceptProposedAction();
}
}
}
} // namespace pdfviewer

View File

@@ -1,126 +0,0 @@
// Copyright (C) 2020-2021 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#ifndef PDFVIEWERMAINWINDOWLITE_H
#define PDFVIEWERMAINWINDOWLITE_H
#include "pdfviewerglobal.h"
#include "pdfcatalog.h"
#include "pdfrenderer.h"
#include "pdfprogress.h"
#include "pdfdocument.h"
#include "pdfviewersettings.h"
#include "pdfdocumentreader.h"
#include "pdfdocumentpropertiesdialog.h"
#include "pdfwidgettool.h"
#include "pdfrecentfilemanager.h"
#include "pdftexttospeech.h"
#include "pdfannotation.h"
#include "pdfform.h"
#include "pdfundoredomanager.h"
#include "pdfplugin.h"
#include "pdfprogramcontroller.h"
#include "pdfwintaskbarprogress.h"
#include <QFuture>
#include <QTreeView>
#include <QMainWindow>
#include <QFutureWatcher>
#include <QProgressBar>
#include <QLabel>
class QLabel;
class QSpinBox;
class QSettings;
class QDoubleSpinBox;
namespace Ui
{
class PDFViewerMainWindowLite;
}
namespace pdf
{
class PDFAction;
class PDFWidget;
class PDFDocument;
class PDFOptionalContentTreeItemModel;
}
namespace pdfviewer
{
class PDFSidebarWidget;
class PDFAdvancedFindWidget;
class PDF4QTVIEWERLIBSHARED_EXPORT PDFViewerMainWindowLite : public QMainWindow, public IMainWindow
{
Q_OBJECT
public:
explicit PDFViewerMainWindowLite(QWidget *parent = nullptr);
virtual ~PDFViewerMainWindowLite() override;
virtual void closeEvent(QCloseEvent* event) override;
virtual void showEvent(QShowEvent* event) override;
PDFProgramController* getProgramController() const { return m_programController; }
virtual void updateUI(bool fullUpdate) override;
virtual QMenu* addToolMenu(QString name) override;
virtual void setStatusBarMessage(QString message, int time) override;
virtual void setDocument(const pdf::PDFModifiedDocument& document) override;
virtual void adjustToolbar(QToolBar* toolbar) override;
virtual pdf::PDFTextSelection getSelectedText() const override;
protected:
virtual void dragEnterEvent(QDragEnterEvent* event) override;
virtual void dragMoveEvent(QDragMoveEvent* event) override;
virtual void dropEvent(QDropEvent* event) override;
private:
void onActionQuitTriggered();
void onPageNumberSpinboxEditingFinished();
void onPageZoomSpinboxEditingFinished();
void onProgressStarted(pdf::ProgressStartupInfo info);
void onProgressStep(int percentage);
void onProgressFinished();
QIcon createStickyNoteIcon(QString key) const;
Ui::PDFViewerMainWindowLite* ui;
PDFActionManager* m_actionManager;
PDFProgramController* m_programController;
PDFSidebarWidget* m_sidebarWidget;
QDockWidget* m_sidebarDockWidget;
QSpinBox* m_pageNumberSpinBox;
QLabel* m_pageNumberLabel;
QDoubleSpinBox* m_pageZoomSpinBox;
bool m_isLoadingUI;
pdf::PDFProgress* m_progress;
PDFWinTaskBarProgress* m_progressTaskbarIndicator;
QProgressBar* m_progressBarOnStatusBar;
QLabel* m_progressBarLeftLabelOnStatusBar;
bool m_isChangingProgressStep;
};
} // namespace pdfviewer
#endif // PDFVIEWERMAINWINDOWLITE_H

View File

@@ -1,670 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PDFViewerMainWindowLite</class>
<widget class="QMainWindow" name="PDFViewerMainWindowLite">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>770</width>
<height>572</height>
</rect>
</property>
<property name="windowTitle">
<string>PDF Viewer</string>
</property>
<widget class="QWidget" name="centralWidget"/>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>770</width>
<height>21</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
<property name="title">
<string>File</string>
</property>
<addaction name="actionOpen"/>
<addaction name="actionClose"/>
<addaction name="actionAutomaticDocumentRefresh"/>
<addaction name="separator"/>
<addaction name="actionSend_by_E_Mail"/>
<addaction name="actionPrint"/>
<addaction name="separator"/>
<addaction name="actionProperties"/>
<addaction name="separator"/>
<addaction name="actionQuit"/>
</widget>
<widget class="QMenu" name="menuGoTo">
<property name="title">
<string>Go To</string>
</property>
<widget class="QMenu" name="menuBookmarkSettings">
<property name="title">
<string>Bookmark Settings</string>
</property>
<addaction name="actionBookmarkExport"/>
<addaction name="actionBookmarkImport"/>
<addaction name="actionBookmarkAutoGenerate"/>
</widget>
<addaction name="actionGoToDocumentStart"/>
<addaction name="actionGoToDocumentEnd"/>
<addaction name="actionGoToPreviousPage"/>
<addaction name="actionGoToNextPage"/>
<addaction name="actionGoToPreviousLine"/>
<addaction name="actionGoToNextLine"/>
<addaction name="separator"/>
<addaction name="actionBookmarkPage"/>
<addaction name="actionGotoPreviousBookmark"/>
<addaction name="actionGotoNextBookmark"/>
<addaction name="menuBookmarkSettings"/>
</widget>
<widget class="QMenu" name="menuView">
<property name="title">
<string>View</string>
</property>
<widget class="QMenu" name="menuPage_Layout">
<property name="title">
<string>Page Layout</string>
</property>
<addaction name="actionPageLayoutSinglePage"/>
<addaction name="actionPageLayoutContinuous"/>
<addaction name="actionPageLayoutTwoPages"/>
<addaction name="actionPageLayoutTwoColumns"/>
<addaction name="separator"/>
<addaction name="actionFirstPageOnRightSide"/>
</widget>
<widget class="QMenu" name="menuRendering_Options">
<property name="title">
<string>Rendering Options</string>
</property>
<addaction name="actionRenderOptionAntialiasing"/>
<addaction name="actionRenderOptionTextAntialiasing"/>
<addaction name="actionRenderOptionSmoothPictures"/>
<addaction name="actionRenderOptionIgnoreOptionalContentSettings"/>
<addaction name="actionRenderOptionDisplayAnnotations"/>
<addaction name="actionRenderOptionDisplayRenderTimes"/>
</widget>
<addaction name="menuPage_Layout"/>
<addaction name="menuRendering_Options"/>
<addaction name="separator"/>
<addaction name="actionRotateRight"/>
<addaction name="actionRotateLeft"/>
<addaction name="separator"/>
<addaction name="actionZoom_In"/>
<addaction name="actionZoom_Out"/>
<addaction name="separator"/>
<addaction name="actionFitPage"/>
<addaction name="actionFitWidth"/>
<addaction name="actionFitHeight"/>
<addaction name="separator"/>
<addaction name="actionColorInvert"/>
<addaction name="actionColorGrayscale"/>
<addaction name="actionColorHighContrast"/>
<addaction name="actionColorBitonal"/>
<addaction name="actionColorCustom"/>
</widget>
<widget class="QMenu" name="menuTools">
<property name="title">
<string>Tools</string>
</property>
<addaction name="separator"/>
<addaction name="actionRendering_Errors"/>
<addaction name="separator"/>
<addaction name="actionOptions"/>
<addaction name="actionResetToFactorySettings"/>
<addaction name="separator"/>
<addaction name="actionCertificateManager"/>
</widget>
<widget class="QMenu" name="menuHelp">
<property name="title">
<string>Help</string>
</property>
<addaction name="actionGetSource"/>
<addaction name="actionBecomeASponsor"/>
<addaction name="actionAbout"/>
</widget>
<addaction name="menuFile"/>
<addaction name="menuView"/>
<addaction name="menuGoTo"/>
<addaction name="menuTools"/>
<addaction name="menuHelp"/>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="actionOpen"/>
</widget>
<widget class="QStatusBar" name="statusBar"/>
<action name="actionOpen">
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/open.svg</normaloff>:/resources/open.svg</iconset>
</property>
<property name="text">
<string>Open...</string>
</property>
</action>
<action name="actionClose">
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/close.svg</normaloff>:/resources/close.svg</iconset>
</property>
<property name="text">
<string>Close</string>
</property>
</action>
<action name="actionQuit">
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/quit.svg</normaloff>:/resources/quit.svg</iconset>
</property>
<property name="text">
<string>Quit</string>
</property>
</action>
<action name="actionPageLayoutSinglePage">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Single Page</string>
</property>
<property name="shortcut">
<string>Ctrl+1</string>
</property>
</action>
<action name="actionPageLayoutContinuous">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Continuous</string>
</property>
<property name="shortcut">
<string>Ctrl+2</string>
</property>
</action>
<action name="actionPageLayoutTwoPages">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Two Pages</string>
</property>
<property name="shortcut">
<string>Ctrl+3</string>
</property>
</action>
<action name="actionPageLayoutTwoColumns">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Two columns</string>
</property>
<property name="shortcut">
<string>Ctrl+4</string>
</property>
</action>
<action name="actionFirstPageOnRightSide">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>First page on right side</string>
</property>
<property name="toolTip">
<string>First page on right side</string>
</property>
<property name="shortcut">
<string>Ctrl+5</string>
</property>
</action>
<action name="actionRendering_Errors">
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/rendering-errors.svg</normaloff>:/resources/rendering-errors.svg</iconset>
</property>
<property name="text">
<string>Rendering Errors...</string>
</property>
<property name="shortcut">
<string>Ctrl+E</string>
</property>
</action>
<action name="actionRenderOptionAntialiasing">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Antialiasing</string>
</property>
</action>
<action name="actionRenderOptionTextAntialiasing">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Text Antialiasing</string>
</property>
</action>
<action name="actionRenderOptionSmoothPictures">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Smooth Pictures</string>
</property>
</action>
<action name="actionRenderOptionIgnoreOptionalContentSettings">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Ignore Optional Content Settings</string>
</property>
</action>
<action name="actionOptions">
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/settings.svg</normaloff>:/resources/settings.svg</iconset>
</property>
<property name="text">
<string>Options...</string>
</property>
<property name="shortcut">
<string>Ctrl+K</string>
</property>
</action>
<action name="actionResetToFactorySettings">
<property name="text">
<string>Reset to Factory Settings</string>
</property>
</action>
<action name="actionZoom_In">
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/zoom-in.svg</normaloff>:/resources/zoom-in.svg</iconset>
</property>
<property name="text">
<string>Zoom In</string>
</property>
</action>
<action name="actionZoom_Out">
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/zoom-out.svg</normaloff>:/resources/zoom-out.svg</iconset>
</property>
<property name="text">
<string>Zoom Out</string>
</property>
</action>
<action name="actionAbout">
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/book.svg</normaloff>:/resources/book.svg</iconset>
</property>
<property name="text">
<string>About...</string>
</property>
</action>
<action name="actionFitPage">
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/zoom-fit.svg</normaloff>:/resources/zoom-fit.svg</iconset>
</property>
<property name="text">
<string>Fit Page</string>
</property>
</action>
<action name="actionFitWidth">
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/zoom-fit-horizontal.svg</normaloff>:/resources/zoom-fit-horizontal.svg</iconset>
</property>
<property name="text">
<string>Fit Width</string>
</property>
<property name="shortcut">
<string>W</string>
</property>
</action>
<action name="actionFitHeight">
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/zoom-fit-vertical.svg</normaloff>:/resources/zoom-fit-vertical.svg</iconset>
</property>
<property name="text">
<string>Fit Height</string>
</property>
<property name="shortcut">
<string>H</string>
</property>
</action>
<action name="actionProperties">
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/info.svg</normaloff>:/resources/info.svg</iconset>
</property>
<property name="text">
<string>Properties...</string>
</property>
</action>
<action name="actionSend_by_E_Mail">
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/send-mail.svg</normaloff>:/resources/send-mail.svg</iconset>
</property>
<property name="text">
<string>Send by E-Mail...</string>
</property>
</action>
<action name="actionColorInvert">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/invert-colors.svg</normaloff>:/resources/invert-colors.svg</iconset>
</property>
<property name="text">
<string>Color | Inverted</string>
</property>
</action>
<action name="actionColorGrayscale">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/invert-colors.svg</normaloff>:/resources/invert-colors.svg</iconset>
</property>
<property name="text">
<string>Color | Grayscale</string>
</property>
</action>
<action name="actionColorHighContrast">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/invert-colors.svg</normaloff>:/resources/invert-colors.svg</iconset>
</property>
<property name="text">
<string>Color | High Contrast</string>
</property>
</action>
<action name="actionColorBitonal">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/invert-colors.svg</normaloff>:/resources/invert-colors.svg</iconset>
</property>
<property name="text">
<string>Color | Monochromatic</string>
</property>
</action>
<action name="actionColorCustom">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/invert-colors.svg</normaloff>:/resources/invert-colors.svg</iconset>
</property>
<property name="text">
<string>Color | Custom</string>
</property>
</action>
<action name="actionRotateRight">
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/rotate-right.svg</normaloff>:/resources/rotate-right.svg</iconset>
</property>
<property name="text">
<string>Rotate Right</string>
</property>
</action>
<action name="actionRotateLeft">
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/rotate-left.svg</normaloff>:/resources/rotate-left.svg</iconset>
</property>
<property name="text">
<string>Rotate Left</string>
</property>
</action>
<action name="actionPrint">
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/print.svg</normaloff>:/resources/print.svg</iconset>
</property>
<property name="text">
<string>Print...</string>
</property>
</action>
<action name="actionRenderOptionDisplayAnnotations">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Display Annotations</string>
</property>
</action>
<action name="actionGoToDocumentStart">
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/previous-start.svg</normaloff>:/resources/previous-start.svg</iconset>
</property>
<property name="text">
<string>Go to document start</string>
</property>
</action>
<action name="actionGoToDocumentEnd">
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/next-end.svg</normaloff>:/resources/next-end.svg</iconset>
</property>
<property name="text">
<string>Go to document end</string>
</property>
</action>
<action name="actionGoToNextPage">
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/next-page.svg</normaloff>:/resources/next-page.svg</iconset>
</property>
<property name="text">
<string>Go to next page</string>
</property>
</action>
<action name="actionGoToPreviousPage">
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/previous-page.svg</normaloff>:/resources/previous-page.svg</iconset>
</property>
<property name="text">
<string>Go to previous page</string>
</property>
</action>
<action name="actionGoToNextLine">
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/next.svg</normaloff>:/resources/next.svg</iconset>
</property>
<property name="text">
<string>Go to next line</string>
</property>
</action>
<action name="actionGoToPreviousLine">
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/previous.svg</normaloff>:/resources/previous.svg</iconset>
</property>
<property name="text">
<string>Go to previous line</string>
</property>
</action>
<action name="actionGetSource">
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/web.svg</normaloff>:/resources/web.svg</iconset>
</property>
<property name="text">
<string>Get Source</string>
</property>
</action>
<action name="actionCertificateManager">
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/certificate-manager.svg</normaloff>:/resources/certificate-manager.svg</iconset>
</property>
<property name="text">
<string>Certificates...</string>
</property>
</action>
<action name="actionAutomaticDocumentRefresh">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Automatic Document Refresh</string>
</property>
<property name="statusTip">
<string>Automatically reloads the document if a change made by an external program is detected.</string>
</property>
</action>
<action name="actionBecomeASponsor">
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/wallet.svg</normaloff>:/resources/wallet.svg</iconset>
</property>
<property name="text">
<string>Become a Sponsor</string>
</property>
<property name="toolTip">
<string>Become a Sponsor</string>
</property>
</action>
<action name="actionBookmarkPage">
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/bookmark.svg</normaloff>:/resources/bookmark.svg</iconset>
</property>
<property name="text">
<string>Bookmark Page</string>
</property>
<property name="toolTip">
<string>Bookmark Page</string>
</property>
<property name="statusTip">
<string>Bookmark page for fast navigation.</string>
</property>
</action>
<action name="actionGotoNextBookmark">
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/bookmark-next.svg</normaloff>:/resources/bookmark-next.svg</iconset>
</property>
<property name="text">
<string>Go to Next Bookmark</string>
</property>
<property name="toolTip">
<string>Go to Next Bookmark</string>
</property>
<property name="statusTip">
<string>Navigates to the next bookmarked page.</string>
</property>
</action>
<action name="actionGotoPreviousBookmark">
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/bookmark-previous.svg</normaloff>:/resources/bookmark-previous.svg</iconset>
</property>
<property name="text">
<string>Go to Previous Bookmark</string>
</property>
<property name="toolTip">
<string>Go to Previous Bookmark</string>
</property>
<property name="statusTip">
<string>Navigates to the previous bookmarked page.</string>
</property>
</action>
<action name="actionBookmarkExport">
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/bookmark.svg</normaloff>:/resources/bookmark.svg</iconset>
</property>
<property name="text">
<string>Export Bookmarks</string>
</property>
<property name="toolTip">
<string>Export Bookmarks</string>
</property>
<property name="statusTip">
<string>Export bookmarks to the file.</string>
</property>
</action>
<action name="actionBookmarkImport">
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/bookmark.svg</normaloff>:/resources/bookmark.svg</iconset>
</property>
<property name="text">
<string>Import Bookmarks</string>
</property>
<property name="toolTip">
<string>Import Bookmarks</string>
</property>
<property name="statusTip">
<string>Import bookmarks from the file.</string>
</property>
</action>
<action name="actionBookmarkAutoGenerate">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="pdf4qtviewer.qrc">
<normaloff>:/resources/bookmark.svg</normaloff>:/resources/bookmark.svg</iconset>
</property>
<property name="text">
<string>Generate Bookmarks Automatically</string>
</property>
<property name="toolTip">
<string>Generate Bookmarks Automatically</string>
</property>
<property name="statusTip">
<string>If checked, bookmarks for main document chapters are generated automatically.</string>
</property>
</action>
<action name="actionRenderOptionDisplayRenderTimes">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Display Render Times</string>
</property>
<property name="menuRole">
<enum>QAction::NoRole</enum>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>
<include location="pdf4qtviewer.qrc"/>
</resources>
<connections/>
</ui>

View File

@@ -1,286 +0,0 @@
// Copyright (C) 2019-2022 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#include "pdfviewersettings.h"
#include "pdfconstants.h"
#include <QSettings>
#include <QPixmapCache>
#include <QStandardPaths>
#include "pdfdbgheap.h"
namespace pdfviewer
{
void PDFViewerSettings::setSettings(const PDFViewerSettings::Settings& settings)
{
if (m_settings != settings)
{
m_settings = settings;
Q_EMIT settingsChanged();
}
}
void PDFViewerSettings::readSettings(QSettings& settings, const pdf::PDFCMSSettings& defaultCMSSettings)
{
Settings defaultSettings;
settings.beginGroup("ViewerSettings");
m_settings.m_directory = settings.value("defaultDirectory", QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)).toString();
m_settings.m_features = static_cast<pdf::PDFRenderer::Features>(settings.value("rendererFeaturesv2", static_cast<int>(pdf::PDFRenderer::getDefaultFeatures())).toInt());
m_settings.m_rendererEngine = static_cast<pdf::RendererEngine>(settings.value("renderingEngine", static_cast<int>(pdf::RendererEngine::Blend2D_MultiThread)).toInt());
m_settings.m_prefetchPages = settings.value("prefetchPages", defaultSettings.m_prefetchPages).toBool();
m_settings.m_preferredMeshResolutionRatio = settings.value("preferredMeshResolutionRatio", defaultSettings.m_preferredMeshResolutionRatio).toDouble();
m_settings.m_minimalMeshResolutionRatio = settings.value("minimalMeshResolutionRatio", defaultSettings.m_minimalMeshResolutionRatio).toDouble();
m_settings.m_colorTolerance = settings.value("colorTolerance", defaultSettings.m_colorTolerance).toDouble();
m_settings.m_compiledPageCacheLimit = settings.value("compiledPageCacheLimit", defaultSettings.m_compiledPageCacheLimit).toInt();
m_settings.m_thumbnailsCacheLimit = settings.value("thumbnailsCacheLimit", defaultSettings.m_thumbnailsCacheLimit).toInt();
m_settings.m_fontCacheLimit = settings.value("fontCacheLimit", defaultSettings.m_fontCacheLimit).toInt();
m_settings.m_instancedFontCacheLimit = settings.value("instancedFontCacheLimit", defaultSettings.m_instancedFontCacheLimit).toInt();
m_settings.m_allowLaunchApplications = settings.value("allowLaunchApplications", defaultSettings.m_allowLaunchApplications).toBool();
m_settings.m_allowLaunchURI = settings.value("allowLaunchURI", defaultSettings.m_allowLaunchURI).toBool();
m_settings.m_allowDeveloperMode = settings.value("allowDeveloperMode", defaultSettings.m_allowDeveloperMode).toBool();
m_settings.m_multithreadingStrategy = static_cast<pdf::PDFExecutionPolicy::Strategy>(settings.value("multithreadingStrategy", static_cast<int>(defaultSettings.m_multithreadingStrategy)).toInt());
m_settings.m_magnifierSize = settings.value("magnifierSize", defaultSettings.m_magnifierSize).toInt();
m_settings.m_magnifierZoom = settings.value("magnifierZoom", defaultSettings.m_magnifierZoom).toDouble();
m_settings.m_maximumUndoSteps = settings.value("maximumUndoSteps", defaultSettings.m_maximumUndoSteps).toInt();
m_settings.m_maximumRedoSteps = settings.value("maximumRedoSteps", defaultSettings.m_maximumRedoSteps).toInt();
settings.endGroup();
settings.beginGroup("ColorManagementSystemSettings");
m_colorManagementSystemSettings.system = static_cast<pdf::PDFCMSSettings::System>(settings.value("system", int(defaultCMSSettings.system)).toInt());
m_colorManagementSystemSettings.accuracy = static_cast<pdf::PDFCMSSettings::Accuracy>(settings.value("accuracy", int(defaultCMSSettings.accuracy)).toInt());
m_colorManagementSystemSettings.intent = static_cast<pdf::RenderingIntent>(settings.value("intent", int(defaultCMSSettings.intent)).toInt());
m_colorManagementSystemSettings.colorAdaptationXYZ = static_cast<pdf::PDFCMSSettings::ColorAdaptationXYZ>(settings.value("colorAdaptationXYZ"), int(defaultCMSSettings.colorAdaptationXYZ));
m_colorManagementSystemSettings.isBlackPointCompensationActive = settings.value("isBlackPointCompensationActive", defaultCMSSettings.isBlackPointCompensationActive).toBool();
m_colorManagementSystemSettings.isWhitePaperColorTransformed = settings.value("isWhitePaperColorTransformed", defaultCMSSettings.isWhitePaperColorTransformed).toBool();
m_colorManagementSystemSettings.isConsiderOutputIntent = settings.value("isConsiderOutputIntent", defaultCMSSettings.isConsiderOutputIntent).toBool();
m_colorManagementSystemSettings.outputCS = settings.value("outputCS", defaultCMSSettings.outputCS).toString();
m_colorManagementSystemSettings.deviceGray = settings.value("deviceGray", defaultCMSSettings.deviceGray).toString();
m_colorManagementSystemSettings.deviceRGB = settings.value("deviceRGB", defaultCMSSettings.deviceRGB).toString();
m_colorManagementSystemSettings.deviceCMYK = settings.value("deviceCMYK", defaultCMSSettings.deviceCMYK).toString();
m_colorManagementSystemSettings.softProofingProfile = settings.value("softProofingProfile", defaultCMSSettings.softProofingProfile).toString();
m_colorManagementSystemSettings.proofingIntent = static_cast<pdf::RenderingIntent>(settings.value("proofingIntent", int(defaultCMSSettings.proofingIntent)).toInt());
m_colorManagementSystemSettings.outOfGamutColor = settings.value("outOfGamutColor", defaultCMSSettings.outOfGamutColor).value<QColor>();
m_colorManagementSystemSettings.profileDirectory = settings.value("profileDirectory", defaultCMSSettings.profileDirectory).toString();
m_colorManagementSystemSettings.foregroundColor = settings.value("foregroundColor", defaultCMSSettings.foregroundColor).value<QColor>();
m_colorManagementSystemSettings.backgroundColor = settings.value("backgroundColor", defaultCMSSettings.backgroundColor).value<QColor>();
m_colorManagementSystemSettings.sigmoidSlopeFactor = settings.value("sigmoidSlopeFactor", defaultCMSSettings.sigmoidSlopeFactor).toDouble();
m_colorManagementSystemSettings.bitonalThreshold = settings.value("bitonalThreshold",defaultCMSSettings.bitonalThreshold).toInt();
settings.endGroup();
settings.beginGroup("SpeechSettings");
m_settings.m_speechEngine = settings.value("speechEngine", defaultSettings.m_speechEngine).toString();
m_settings.m_speechLocale = settings.value("speechLocale", defaultSettings.m_speechLocale).toString();
m_settings.m_speechVoice = settings.value("speechVoice", defaultSettings.m_speechVoice).toString();
m_settings.m_speechRate = settings.value("speechRate", defaultSettings.m_speechRate).toDouble();
m_settings.m_speechPitch = settings.value("speechPitch", defaultSettings.m_speechPitch).toDouble();
m_settings.m_speechVolume = settings.value("speechVolume", defaultSettings.m_speechVolume).toDouble();
settings.endGroup();
settings.beginGroup("Forms");
m_settings.m_formAppearanceFlags = static_cast<pdf::PDFFormManager::FormAppearanceFlags>(settings.value("formAppearance", int(pdf::PDFFormManager::getDefaultApperanceFlags())).toInt());
settings.endGroup();
settings.beginGroup("Signature");
m_settings.m_signatureVerificationEnabled = settings.value("signatureVerificationEnabled", defaultSettings.m_signatureVerificationEnabled).toBool();
m_settings.m_signatureTreatWarningsAsErrors = settings.value("signatureTreatWarningsAsErrors", defaultSettings.m_signatureTreatWarningsAsErrors).toBool();
m_settings.m_signatureIgnoreCertificateValidityTime = settings.value("signatureIgnoreCertificateValidityTime", defaultSettings.m_signatureIgnoreCertificateValidityTime).toBool();
m_settings.m_signatureUseSystemStore = settings.value("signatureUseSystemStore", defaultSettings.m_signatureUseSystemStore).toBool();
settings.endGroup();
settings.beginGroup("Bookmarks");
m_settings.m_autoGenerateBookmarks = settings.value("autoGenerateBookmarks", defaultSettings.m_autoGenerateBookmarks).toBool();
settings.endGroup();
Q_EMIT settingsChanged();
}
void PDFViewerSettings::writeSettings(QSettings& settings)
{
settings.beginGroup("ViewerSettings");
settings.setValue("defaultDirectory", m_settings.m_directory);
settings.setValue("rendererFeaturesv2", static_cast<int>(m_settings.m_features));
settings.setValue("renderingEngine", static_cast<int>(m_settings.m_rendererEngine));
settings.setValue("prefetchPages", m_settings.m_prefetchPages);
settings.setValue("preferredMeshResolutionRatio", m_settings.m_preferredMeshResolutionRatio);
settings.setValue("minimalMeshResolutionRatio", m_settings.m_minimalMeshResolutionRatio);
settings.setValue("colorTolerance", m_settings.m_colorTolerance);
settings.setValue("compiledPageCacheLimit", m_settings.m_compiledPageCacheLimit);
settings.setValue("thumbnailsCacheLimit", m_settings.m_thumbnailsCacheLimit);
settings.setValue("fontCacheLimit", m_settings.m_fontCacheLimit);
settings.setValue("instancedFontCacheLimit", m_settings.m_instancedFontCacheLimit);
settings.setValue("allowLaunchApplications", m_settings.m_allowLaunchApplications);
settings.setValue("allowLaunchURI", m_settings.m_allowLaunchURI);
settings.setValue("allowDeveloperMode", m_settings.m_allowDeveloperMode);
settings.setValue("multithreadingStrategy", static_cast<int>(m_settings.m_multithreadingStrategy));
settings.setValue("magnifierSize", m_settings.m_magnifierSize);
settings.setValue("magnifierZoom", m_settings.m_magnifierZoom);
settings.setValue("maximumUndoSteps", m_settings.m_maximumUndoSteps);
settings.setValue("maximumRedoSteps", m_settings.m_maximumRedoSteps);
settings.endGroup();
settings.beginGroup("ColorManagementSystemSettings");
settings.setValue("system", int(m_colorManagementSystemSettings.system));
settings.setValue("accuracy", int(m_colorManagementSystemSettings.accuracy));
settings.setValue("intent", int(m_colorManagementSystemSettings.intent));
settings.setValue("colorAdaptationXYZ", int(m_colorManagementSystemSettings.colorAdaptationXYZ));
settings.setValue("isBlackPointCompensationActive", m_colorManagementSystemSettings.isBlackPointCompensationActive);
settings.setValue("isWhitePaperColorTransformed", m_colorManagementSystemSettings.isWhitePaperColorTransformed);
settings.setValue("isConsiderOutputIntent", m_colorManagementSystemSettings.isConsiderOutputIntent);
settings.setValue("outputCS", m_colorManagementSystemSettings.outputCS);
settings.setValue("deviceGray", m_colorManagementSystemSettings.deviceGray);
settings.setValue("deviceRGB", m_colorManagementSystemSettings.deviceRGB);
settings.setValue("deviceCMYK", m_colorManagementSystemSettings.deviceCMYK);
settings.setValue("softProofingProfile", m_colorManagementSystemSettings.softProofingProfile);
settings.setValue("proofingIntent", int(m_colorManagementSystemSettings.proofingIntent));
settings.setValue("outOfGamutColor", m_colorManagementSystemSettings.outOfGamutColor);
settings.setValue("profileDirectory", m_colorManagementSystemSettings.profileDirectory);
settings.setValue("foregroundColor", m_colorManagementSystemSettings.foregroundColor);
settings.setValue("backgroundColor", m_colorManagementSystemSettings.backgroundColor);
settings.setValue("sigmoidSlopeFactor", m_colorManagementSystemSettings.sigmoidSlopeFactor);
settings.setValue("bitonalThreshold", m_colorManagementSystemSettings.bitonalThreshold);
settings.endGroup();
settings.beginGroup("SpeechSettings");
settings.setValue("speechEngine", m_settings.m_speechEngine);
settings.setValue("speechLocale", m_settings.m_speechLocale);
settings.setValue("speechVoice", m_settings.m_speechVoice);
settings.setValue("speechRate", m_settings.m_speechRate);
settings.setValue("speechPitch", m_settings.m_speechPitch);
settings.setValue("speechVolume", m_settings.m_speechVolume);
settings.endGroup();
settings.beginGroup("Forms");
settings.setValue("formAppearance", int(m_settings.m_formAppearanceFlags));
settings.endGroup();
settings.beginGroup("Signature");
settings.setValue("signatureVerificationEnabled", m_settings.m_signatureVerificationEnabled);
settings.setValue("signatureTreatWarningsAsErrors", m_settings.m_signatureTreatWarningsAsErrors);
settings.setValue("signatureIgnoreCertificateValidityTime", m_settings.m_signatureIgnoreCertificateValidityTime);
settings.setValue("signatureUseSystemStore", m_settings.m_signatureUseSystemStore);
settings.endGroup();
settings.beginGroup("Bookmarks");
settings.setValue("autoGenerateBookmarks", m_settings.m_autoGenerateBookmarks);
settings.endGroup();
}
QString PDFViewerSettings::getDirectory() const
{
return m_settings.m_directory;
}
void PDFViewerSettings::setDirectory(const QString& directory)
{
if (m_settings.m_directory != directory)
{
m_settings.m_directory = directory;
Q_EMIT settingsChanged();
}
}
pdf::PDFRenderer::Features PDFViewerSettings::getFeatures() const
{
return m_settings.m_features;
}
void PDFViewerSettings::setFeatures(const pdf::PDFRenderer::Features& features)
{
if (m_settings.m_features != features)
{
m_settings.m_features = features;
Q_EMIT settingsChanged();
}
}
pdf::RendererEngine PDFViewerSettings::getRendererEngine() const
{
return m_settings.m_rendererEngine;
}
void PDFViewerSettings::setRendererEngine(pdf::RendererEngine rendererEngine)
{
if (m_settings.m_rendererEngine != rendererEngine)
{
m_settings.m_rendererEngine = rendererEngine;
Q_EMIT settingsChanged();
}
}
void PDFViewerSettings::setPreferredMeshResolutionRatio(pdf::PDFReal preferredMeshResolutionRatio)
{
if (m_settings.m_preferredMeshResolutionRatio != preferredMeshResolutionRatio)
{
m_settings.m_preferredMeshResolutionRatio = preferredMeshResolutionRatio;
Q_EMIT settingsChanged();
}
}
void PDFViewerSettings::setMinimalMeshResolutionRatio(pdf::PDFReal minimalMeshResolutionRatio)
{
if (m_settings.m_minimalMeshResolutionRatio != minimalMeshResolutionRatio)
{
m_settings.m_minimalMeshResolutionRatio = minimalMeshResolutionRatio;
Q_EMIT settingsChanged();
}
}
void PDFViewerSettings::setColorTolerance(pdf::PDFReal colorTolerance)
{
if (m_settings.m_colorTolerance != colorTolerance)
{
m_settings.m_colorTolerance = colorTolerance;
Q_EMIT settingsChanged();
}
}
PDFViewerSettings::Settings::Settings() :
m_features(pdf::PDFRenderer::getDefaultFeatures()),
m_rendererEngine(pdf::RendererEngine::Blend2D_MultiThread),
m_prefetchPages(true),
m_preferredMeshResolutionRatio(0.02),
m_minimalMeshResolutionRatio(0.005),
m_colorTolerance(0.01),
m_allowLaunchApplications(true),
m_allowLaunchURI(true),
m_allowDeveloperMode(false),
m_multithreadingStrategy(pdf::PDFExecutionPolicy::Strategy::AlwaysMultithreaded),
m_compiledPageCacheLimit(512 * 1024),
m_thumbnailsCacheLimit(64 * 1024),
m_fontCacheLimit(pdf::DEFAULT_FONT_CACHE_LIMIT),
m_instancedFontCacheLimit(pdf::DEFAULT_REALIZED_FONT_CACHE_LIMIT),
m_speechRate(0.0),
m_speechPitch(0.0),
m_speechVolume(1.0),
m_magnifierSize(100),
m_magnifierZoom(2.0),
m_maximumUndoSteps(5),
m_maximumRedoSteps(5),
m_formAppearanceFlags(pdf::PDFFormManager::getDefaultApperanceFlags()),
m_signatureVerificationEnabled(true),
m_signatureTreatWarningsAsErrors(false),
m_signatureIgnoreCertificateValidityTime(false),
m_signatureUseSystemStore(true),
m_autoGenerateBookmarks(true)
{
}
} // namespace pdfviewer

View File

@@ -1,145 +0,0 @@
// Copyright (C) 2019-2021 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#ifndef PDFVIEWERSETTINGS_H
#define PDFVIEWERSETTINGS_H
#include "pdfglobal.h"
#include "pdfrenderer.h"
#include "pdfcms.h"
#include "pdfexecutionpolicy.h"
#include "pdfform.h"
#include <QObject>
class QSettings;
namespace pdfviewer
{
class PDFViewerSettings : public QObject
{
Q_OBJECT
public:
inline explicit PDFViewerSettings(QObject* parent) :
QObject(parent)
{
}
struct Settings
{
Settings();
bool operator==(const Settings&) const = default;
bool operator!=(const Settings&) const = default;
pdf::PDFRenderer::Features m_features;
QString m_directory;
pdf::RendererEngine m_rendererEngine;
bool m_prefetchPages;
pdf::PDFReal m_preferredMeshResolutionRatio;
pdf::PDFReal m_minimalMeshResolutionRatio;
pdf::PDFReal m_colorTolerance;
bool m_allowLaunchApplications;
bool m_allowLaunchURI;
bool m_allowDeveloperMode;
pdf::PDFExecutionPolicy::Strategy m_multithreadingStrategy;
// Cache settings
int m_compiledPageCacheLimit;
int m_thumbnailsCacheLimit;
int m_fontCacheLimit;
int m_instancedFontCacheLimit;
// Speech settings
QString m_speechEngine;
QString m_speechLocale;
QString m_speechVoice;
double m_speechRate;
double m_speechPitch;
double m_speechVolume;
// Magnifier tool settings
int m_magnifierSize;
double m_magnifierZoom;
// Undo/redo steps settings
int m_maximumUndoSteps;
int m_maximumRedoSteps;
// Form settings
pdf::PDFFormManager::FormAppearanceFlags m_formAppearanceFlags;
// Signature settings
bool m_signatureVerificationEnabled;
bool m_signatureTreatWarningsAsErrors;
bool m_signatureIgnoreCertificateValidityTime;
bool m_signatureUseSystemStore;
// Bookmarks settings
bool m_autoGenerateBookmarks;
};
const Settings& getSettings() const { return m_settings; }
void setSettings(const Settings& settings);
void readSettings(QSettings& settings, const pdf::PDFCMSSettings& defaultCMSSettings);
void writeSettings(QSettings& settings);
QString getDirectory() const;
void setDirectory(const QString& directory);
pdf::PDFRenderer::Features getFeatures() const;
void setFeatures(const pdf::PDFRenderer::Features& features);
pdf::RendererEngine getRendererEngine() const;
void setRendererEngine(pdf::RendererEngine rendererEngine);
bool isPagePrefetchingEnabled() const { return m_settings.m_prefetchPages; }
pdf::PDFReal getPreferredMeshResolutionRatio() const { return m_settings.m_preferredMeshResolutionRatio; }
void setPreferredMeshResolutionRatio(pdf::PDFReal preferredMeshResolutionRatio);
pdf::PDFReal getMinimalMeshResolutionRatio() const { return m_settings.m_minimalMeshResolutionRatio; }
void setMinimalMeshResolutionRatio(pdf::PDFReal minimalMeshResolutionRatio);
pdf::PDFReal getColorTolerance() const { return m_settings.m_colorTolerance; }
void setColorTolerance(pdf::PDFReal colorTolerance);
int getCompiledPageCacheLimit() const { return m_settings.m_compiledPageCacheLimit; }
int getThumbnailsCacheLimit() const { return m_settings.m_thumbnailsCacheLimit; }
int getFontCacheLimit() const { return m_settings.m_fontCacheLimit; }
int getInstancedFontCacheLimit() const { return m_settings.m_instancedFontCacheLimit; }
const pdf::PDFCMSSettings& getColorManagementSystemSettings() const { return m_colorManagementSystemSettings; }
void setColorManagementSystemSettings(const pdf::PDFCMSSettings& settings) { m_colorManagementSystemSettings = settings; }
pdf::PDFExecutionPolicy::Strategy getMultithreadingStrategy() const { return m_settings.m_multithreadingStrategy; }
signals:
void settingsChanged();
private:
Settings m_settings;
pdf::PDFCMSSettings m_colorManagementSystemSettings;
};
} // namespace pdfviewer
#endif // PDFVIEWERSETTINGS_H

View File

@@ -1,897 +0,0 @@
// Copyright (C) 2019-2022 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#include "pdfviewersettingsdialog.h"
#include "ui_pdfviewersettingsdialog.h"
#include "pdfglobal.h"
#include "pdfutils.h"
#include "pdfwidgetutils.h"
#include "pdfrecentfilemanager.h"
#include "pdfcolorconvertor.h"
#include <QAction>
#include <QLineEdit>
#include <QMessageBox>
#include <QFileDialog>
#include <QListWidgetItem>
#include <QTextToSpeech>
#include <QDomDocument>
#include <QStyledItemDelegate>
#include "pdfdbgheap.h"
namespace pdfviewer
{
class SettingsDelegate : public QStyledItemDelegate
{
public:
SettingsDelegate(QObject* parent) :
QStyledItemDelegate(parent)
{
}
virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override
{
QSize size = QStyledItemDelegate::sizeHint(option, index);
size.setHeight(qMax(size.height(), pdf::PDFWidgetUtils::scaleDPI_y(qobject_cast<QWidget*>(parent()), 48)));
return size;
}
};
PDFViewerSettingsDialog::PDFViewerSettingsDialog(const PDFViewerSettings::Settings& settings,
const pdf::PDFCMSSettings& cmsSettings,
const OtherSettings& otherSettings,
const pdf::PDFCertificateStore& certificateStore,
const std::vector<QAction*>& actions,
pdf::PDFCMSManager* cmsManager,
const QStringList& enabledPlugins,
const pdf::PDFPluginInfos& plugins,
QWidget* parent) :
QDialog(parent),
ui(new Ui::PDFViewerSettingsDialog),
m_settings(settings),
m_cmsSettings(cmsSettings),
m_otherSettings(otherSettings),
m_actions(),
m_isLoadingData(false),
m_certificateStore(certificateStore),
m_enabledPlugins(enabledPlugins),
m_plugins(plugins)
{
ui->setupUi(this);
m_textToSpeechEngines = QTextToSpeech::availableEngines();
new QListWidgetItem(QIcon(":/resources/engine.svg"), tr("Engine"), ui->optionsPagesWidget, EngineSettings);
new QListWidgetItem(QIcon(":/resources/rendering.svg"), tr("Rendering"), ui->optionsPagesWidget, RenderingSettings);
new QListWidgetItem(QIcon(":/resources/shading.svg"), tr("Shading"), ui->optionsPagesWidget, ShadingSettings);
new QListWidgetItem(QIcon(":/resources/cache.svg"), tr("Cache"), ui->optionsPagesWidget, CacheSettings);
new QListWidgetItem(QIcon(":/resources/shortcuts.svg"), tr("Shortcuts"), ui->optionsPagesWidget, ShortcutSettings);
new QListWidgetItem(QIcon(":/resources/cms.svg"), tr("Colors | CMS"), ui->optionsPagesWidget, ColorManagementSystemSettings);
new QListWidgetItem(QIcon(":/resources/cms.svg"), tr("Colors | Postprocessing"), ui->optionsPagesWidget, ColorPostprocessingSettings);
new QListWidgetItem(QIcon(":/resources/security.svg"), tr("Security"), ui->optionsPagesWidget, SecuritySettings);
new QListWidgetItem(QIcon(":/resources/ui.svg"), tr("UI"), ui->optionsPagesWidget, UISettings);
new QListWidgetItem(QIcon(":/resources/speech.svg"), tr("Speech"), ui->optionsPagesWidget, SpeechSettings);
new QListWidgetItem(QIcon(":/resources/form-settings.svg"), tr("Forms"), ui->optionsPagesWidget, FormSettings);
new QListWidgetItem(QIcon(":/resources/signature.svg"), tr("Signature"), ui->optionsPagesWidget, SignatureSettings);
new QListWidgetItem(QIcon(":/resources/plugins.svg"), tr("Plugins"), ui->optionsPagesWidget, PluginsSettings);
ui->optionsPagesWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
ui->optionsPagesWidget->setItemDelegate(new SettingsDelegate(ui->optionsPagesWidget));
ui->optionsPagesWidget->setIconSize(pdf::PDFWidgetUtils::scaleDPI(this, QSize(32, 32)));
// Scale font
QFont font = ui->optionsPagesWidget->font();
font.setPointSize(font.pointSize() * 1.5);
ui->optionsPagesWidget->setFont(font);
ui->renderingEngineComboBox->addItem(tr("Software | QPainter"), static_cast<int>(pdf::RendererEngine::QPainter));
ui->renderingEngineComboBox->addItem(tr("Software | Blend2D | Parallel"), static_cast<int>(pdf::RendererEngine::Blend2D_MultiThread));
ui->renderingEngineComboBox->addItem(tr("Software | Blend2D | Sequential"), static_cast<int>(pdf::RendererEngine::Blend2D_SingleThread));
ui->multithreadingComboBox->addItem(tr("Single thread"), static_cast<int>(pdf::PDFExecutionPolicy::Strategy::SingleThreaded));
ui->multithreadingComboBox->addItem(tr("Multithreading (load balanced)"), static_cast<int>(pdf::PDFExecutionPolicy::Strategy::PageMultithreaded));
ui->multithreadingComboBox->addItem(tr("Multithreading (maximum threads)"), static_cast<int>(pdf::PDFExecutionPolicy::Strategy::AlwaysMultithreaded));
ui->maximumRecentFileCountEdit->setMinimum(PDFRecentFileManager::getMinimumRecentFiles());
ui->maximumRecentFileCountEdit->setMaximum(PDFRecentFileManager::getMaximumRecentFiles());
// Load CMS data
ui->cmsTypeComboBox->addItem(pdf::PDFCMSManager::getSystemName(pdf::PDFCMSSettings::System::Generic), int(pdf::PDFCMSSettings::System::Generic));
ui->cmsTypeComboBox->addItem(pdf::PDFCMSManager::getSystemName(pdf::PDFCMSSettings::System::LittleCMS2), int(pdf::PDFCMSSettings::System::LittleCMS2));
ui->cmsRenderingIntentComboBox->addItem(tr("Auto"), int(pdf::RenderingIntent::Auto));
ui->cmsRenderingIntentComboBox->addItem(tr("Perceptual"), int(pdf::RenderingIntent::Perceptual));
ui->cmsRenderingIntentComboBox->addItem(tr("Relative colorimetric"), int(pdf::RenderingIntent::RelativeColorimetric));
ui->cmsRenderingIntentComboBox->addItem(tr("Absolute colorimetric"), int(pdf::RenderingIntent::AbsoluteColorimetric));
ui->cmsRenderingIntentComboBox->addItem(tr("Saturation"), int(pdf::RenderingIntent::Saturation));
ui->cmsAccuracyComboBox->addItem(tr("Low"), int(pdf::PDFCMSSettings::Accuracy::Low));
ui->cmsAccuracyComboBox->addItem(tr("Medium"), int(pdf::PDFCMSSettings::Accuracy::Medium));
ui->cmsAccuracyComboBox->addItem(tr("High"), int(pdf::PDFCMSSettings::Accuracy::High));
ui->cmsColorAdaptationXYZComboBox->addItem(tr("None"), int (pdf::PDFCMSSettings::ColorAdaptationXYZ::None));
ui->cmsColorAdaptationXYZComboBox->addItem(tr("XYZ scaling"), int (pdf::PDFCMSSettings::ColorAdaptationXYZ::XYZScaling));
ui->cmsColorAdaptationXYZComboBox->addItem(tr("CAT97 matrix"), int (pdf::PDFCMSSettings::ColorAdaptationXYZ::CAT97));
ui->cmsColorAdaptationXYZComboBox->addItem(tr("CAT02 matrix"), int (pdf::PDFCMSSettings::ColorAdaptationXYZ::CAT02));
ui->cmsColorAdaptationXYZComboBox->addItem(tr("Bradford method"), int (pdf::PDFCMSSettings::ColorAdaptationXYZ::Bradford));
auto fillColorProfileList = [](QComboBox* comboBox, const pdf::PDFColorProfileIdentifiers& identifiers)
{
for (const pdf::PDFColorProfileIdentifier& identifier : identifiers)
{
comboBox->addItem(identifier.name, identifier.id);
}
};
fillColorProfileList(ui->cmsOutputColorProfileComboBox, cmsManager->getOutputProfiles());
fillColorProfileList(ui->cmsDeviceGrayColorProfileComboBox, cmsManager->getGrayProfiles());
fillColorProfileList(ui->cmsDeviceRGBColorProfileComboBox, cmsManager->getRGBProfiles());
fillColorProfileList(ui->cmsDeviceCMYKColorProfileComboBox, cmsManager->getCMYKProfiles());
for (QWidget* widget : { ui->engineInfoLabel, ui->renderingInfoLabel, ui->securityInfoLabel, ui->cmsInfoLabel, ui->colorPostProcessingInfoLabel })
{
widget->setMinimumWidth(widget->sizeHint().width());
}
for (QCheckBox* checkBox : findChildren<QCheckBox*>())
{
connect(checkBox, &QCheckBox::clicked, this, &PDFViewerSettingsDialog::saveData);
}
for (QComboBox* comboBox : findChildren<QComboBox*>())
{
connect(comboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &PDFViewerSettingsDialog::saveData);
}
for (QDoubleSpinBox* spinBox : findChildren<QDoubleSpinBox*>())
{
connect(spinBox, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &PDFViewerSettingsDialog::saveData);
}
for (QSpinBox* spinBox : findChildren<QSpinBox*>())
{
connect(spinBox, QOverload<int>::of(&QSpinBox::valueChanged), this, &PDFViewerSettingsDialog::saveData);
}
for (QLineEdit* lineEdit : findChildren<QLineEdit*>())
{
connect(lineEdit, &QLineEdit::editingFinished, this, &PDFViewerSettingsDialog::saveData);
}
for (QAction* action : actions)
{
if (!action->objectName().isEmpty())
{
m_actions.append(action);
}
}
// Text to speech
for (const QString& engine : m_textToSpeechEngines)
{
ui->speechEnginesComboBox->addItem(engine, engine);
}
connect(ui->trustedCertificateStoreTableWidget, &QTableWidget::itemSelectionChanged, this, &PDFViewerSettingsDialog::updateTrustedCertificatesTableActions);
connect(ui->pluginsTableWidget, &QTableWidget::itemSelectionChanged, this, &PDFViewerSettingsDialog::updatePluginInformation);
setMinimumSize(pdf::PDFWidgetUtils::scaleDPI(this, QSize(1000, 800)));
pdf::PDFWidgetUtils::style(this);
ui->optionsPagesWidget->setCurrentRow(0);
loadData();
loadActionShortcutsTable();
loadPluginsTable();
updateTrustedCertificatesTable();
updateTrustedCertificatesTableActions();
resize(sizeHint());
}
PDFViewerSettingsDialog::~PDFViewerSettingsDialog()
{
delete ui;
}
void PDFViewerSettingsDialog::on_optionsPagesWidget_currentItemChanged(QListWidgetItem* current, QListWidgetItem* previous)
{
Q_UNUSED(previous);
switch (current->type())
{
case EngineSettings:
ui->stackedWidget->setCurrentWidget(ui->enginePage);
break;
case RenderingSettings:
ui->stackedWidget->setCurrentWidget(ui->renderingPage);
break;
case ShadingSettings:
ui->stackedWidget->setCurrentWidget(ui->shadingPage);
break;
case CacheSettings:
ui->stackedWidget->setCurrentWidget(ui->cachePage);
break;
case ShortcutSettings:
ui->stackedWidget->setCurrentWidget(ui->shortcutsPage);
break;
case ColorManagementSystemSettings:
ui->stackedWidget->setCurrentWidget(ui->cmsPage);
break;
case ColorPostprocessingSettings:
ui->stackedWidget->setCurrentWidget(ui->cmsPostprocessingPage);
break;
case SecuritySettings:
ui->stackedWidget->setCurrentWidget(ui->securityPage);
break;
case UISettings:
ui->stackedWidget->setCurrentWidget(ui->uiPage);
break;
case SpeechSettings:
ui->stackedWidget->setCurrentWidget(ui->speechPage);
break;
case FormSettings:
ui->stackedWidget->setCurrentWidget(ui->formPage);
break;
case SignatureSettings:
ui->stackedWidget->setCurrentWidget(ui->signaturePage);
break;
case PluginsSettings:
ui->stackedWidget->setCurrentWidget(ui->pluginsPage);
break;
default:
Q_ASSERT(false);
break;
}
}
void PDFViewerSettingsDialog::loadData()
{
pdf::PDFTemporaryValueChange guard(&m_isLoadingData, true);
ui->renderingEngineComboBox->setCurrentIndex(ui->renderingEngineComboBox->findData(static_cast<int>(m_settings.m_rendererEngine)));
// Engine
ui->prefetchPagesCheckBox->setChecked(m_settings.m_prefetchPages);
ui->multithreadingComboBox->setCurrentIndex(ui->multithreadingComboBox->findData(static_cast<int>(m_settings.m_multithreadingStrategy)));
// Rendering
ui->antialiasingCheckBox->setChecked(m_settings.m_features.testFlag(pdf::PDFRenderer::Antialiasing));
ui->textAntialiasingCheckBox->setChecked(m_settings.m_features.testFlag(pdf::PDFRenderer::TextAntialiasing));
ui->smoothPicturesCheckBox->setChecked(m_settings.m_features.testFlag(pdf::PDFRenderer::SmoothImages));
ui->ignoreOptionalContentCheckBox->setChecked(m_settings.m_features.testFlag(pdf::PDFRenderer::IgnoreOptionalContent));
ui->clipToCropBoxCheckBox->setChecked(m_settings.m_features.testFlag(pdf::PDFRenderer::ClipToCropBox));
ui->displayTimeCheckBox->setChecked(m_settings.m_features.testFlag(pdf::PDFRenderer::DisplayTimes));
ui->displayAnnotationsCheckBox->setChecked(m_settings.m_features.testFlag(pdf::PDFRenderer::DisplayAnnotations));
// Shading
ui->preferredMeshResolutionEdit->setValue(m_settings.m_preferredMeshResolutionRatio);
ui->minimalMeshResolutionEdit->setValue(m_settings.m_minimalMeshResolutionRatio);
ui->colorToleranceEdit->setValue(m_settings.m_colorTolerance);
// Cache
ui->compiledPageCacheSizeEdit->setValue(m_settings.m_compiledPageCacheLimit);
ui->thumbnailCacheSizeEdit->setValue(m_settings.m_thumbnailsCacheLimit);
ui->cachedFontLimitEdit->setValue(m_settings.m_fontCacheLimit);
ui->cachedInstancedFontLimitEdit->setValue(m_settings.m_instancedFontCacheLimit);
// Security
ui->allowLaunchCheckBox->setChecked(m_settings.m_allowLaunchApplications);
ui->allowRunURICheckBox->setChecked(m_settings.m_allowLaunchURI);
// UI
ui->maximumRecentFileCountEdit->setValue(m_otherSettings.maximumRecentFileCount);
ui->magnifierSizeEdit->setValue(m_settings.m_magnifierSize);
ui->magnifierZoomEdit->setValue(m_settings.m_magnifierZoom);
ui->maximumUndoStepsEdit->setValue(m_settings.m_maximumUndoSteps);
ui->maximumRedoStepsEdit->setValue(m_settings.m_maximumRedoSteps);
ui->developerModeCheckBox->setChecked(m_settings.m_allowDeveloperMode);
ui->logicalPixelZoomCheckBox->setChecked(m_settings.m_features.testFlag(pdf::PDFRenderer::LogicalSizeZooming));
// CMS
ui->cmsTypeComboBox->setCurrentIndex(ui->cmsTypeComboBox->findData(int(m_cmsSettings.system)));
if (m_cmsSettings.system != pdf::PDFCMSSettings::System::Generic)
{
ui->cmsRenderingIntentComboBox->setEnabled(true);
ui->cmsRenderingIntentComboBox->setCurrentIndex(ui->cmsRenderingIntentComboBox->findData(int(m_cmsSettings.intent)));
ui->cmsAccuracyComboBox->setEnabled(true);
ui->cmsAccuracyComboBox->setCurrentIndex(ui->cmsAccuracyComboBox->findData(int(m_cmsSettings.accuracy)));
ui->cmsColorAdaptationXYZComboBox->setEnabled(true);
ui->cmsColorAdaptationXYZComboBox->setCurrentIndex(ui->cmsColorAdaptationXYZComboBox->findData(int(m_cmsSettings.colorAdaptationXYZ)));
ui->cmsIsBlackPointCompensationCheckBox->setEnabled(true);
ui->cmsIsBlackPointCompensationCheckBox->setChecked(m_cmsSettings.isBlackPointCompensationActive);
ui->cmsConsiderOutputIntentCheckBox->setEnabled(true);
ui->cmsConsiderOutputIntentCheckBox->setChecked(m_cmsSettings.isConsiderOutputIntent);
ui->cmsWhitePaperColorTransformedCheckBox->setEnabled(true);
ui->cmsWhitePaperColorTransformedCheckBox->setChecked(m_cmsSettings.isWhitePaperColorTransformed);
ui->cmsOutputColorProfileComboBox->setEnabled(true);
ui->cmsOutputColorProfileComboBox->setCurrentIndex(ui->cmsOutputColorProfileComboBox->findData(m_cmsSettings.outputCS));
ui->cmsDeviceGrayColorProfileComboBox->setEnabled(true);
ui->cmsDeviceGrayColorProfileComboBox->setCurrentIndex(ui->cmsDeviceGrayColorProfileComboBox->findData(m_cmsSettings.deviceGray));
ui->cmsDeviceRGBColorProfileComboBox->setEnabled(true);
ui->cmsDeviceRGBColorProfileComboBox->setCurrentIndex(ui->cmsDeviceRGBColorProfileComboBox->findData(m_cmsSettings.deviceRGB));
ui->cmsDeviceCMYKColorProfileComboBox->setEnabled(true);
ui->cmsDeviceCMYKColorProfileComboBox->setCurrentIndex(ui->cmsDeviceCMYKColorProfileComboBox->findData(m_cmsSettings.deviceCMYK));
ui->cmsProfileDirectoryButton->setEnabled(true);
ui->cmsProfileDirectoryEdit->setEnabled(true);
ui->cmsProfileDirectoryEdit->setText(m_cmsSettings.profileDirectory);
}
else
{
ui->cmsRenderingIntentComboBox->setEnabled(false);
ui->cmsRenderingIntentComboBox->setCurrentIndex(-1);
ui->cmsAccuracyComboBox->setEnabled(false);
ui->cmsAccuracyComboBox->setCurrentIndex(-1);
ui->cmsColorAdaptationXYZComboBox->setEnabled(false);
ui->cmsColorAdaptationXYZComboBox->setCurrentIndex(-1);
ui->cmsIsBlackPointCompensationCheckBox->setEnabled(false);
ui->cmsIsBlackPointCompensationCheckBox->setChecked(false);
ui->cmsConsiderOutputIntentCheckBox->setEnabled(false);
ui->cmsConsiderOutputIntentCheckBox->setChecked(false);
ui->cmsWhitePaperColorTransformedCheckBox->setEnabled(false);
ui->cmsWhitePaperColorTransformedCheckBox->setChecked(false);
ui->cmsOutputColorProfileComboBox->setEnabled(false);
ui->cmsOutputColorProfileComboBox->setCurrentIndex(-1);
ui->cmsDeviceGrayColorProfileComboBox->setEnabled(false);
ui->cmsDeviceGrayColorProfileComboBox->setCurrentIndex(-1);
ui->cmsDeviceRGBColorProfileComboBox->setEnabled(false);
ui->cmsDeviceRGBColorProfileComboBox->setCurrentIndex(-1);
ui->cmsDeviceCMYKColorProfileComboBox->setEnabled(false);
ui->cmsDeviceCMYKColorProfileComboBox->setCurrentIndex(-1);
ui->cmsProfileDirectoryButton->setEnabled(false);
ui->cmsProfileDirectoryEdit->setEnabled(false);
ui->cmsProfileDirectoryEdit->setText(QString());
}
// Color postprocessing
ui->foregroundColorEdit->setText(m_cmsSettings.foregroundColor.name(QColor::HexRgb));
ui->backgroundColorEdit->setText(m_cmsSettings.backgroundColor.name(QColor::HexRgb));
ui->sigmoidFunctionSlopeEdit->setValue(m_cmsSettings.sigmoidSlopeFactor);
ui->bitonalThresholdEdit->setValue(m_cmsSettings.bitonalThreshold);
// Text-to-speech
ui->speechEnginesComboBox->setCurrentIndex(ui->speechEnginesComboBox->findData(m_settings.m_speechEngine));
setSpeechEngine(m_settings.m_speechEngine, m_settings.m_speechLocale);
ui->speechLocaleComboBox->setCurrentIndex(ui->speechLocaleComboBox->findData(m_settings.m_speechLocale));
ui->speechVoiceComboBox->setCurrentIndex(ui->speechVoiceComboBox->findData(m_settings.m_speechVoice));
ui->speechRateEdit->setValue(m_settings.m_speechRate);
ui->speechPitchEdit->setValue(m_settings.m_speechPitch);
ui->speechVolumeEdit->setValue(m_settings.m_speechVolume);
// Form Settings
ui->formHighlightFieldsCheckBox->setChecked(m_settings.m_formAppearanceFlags.testFlag(pdf::PDFFormManager::HighlightFields));
ui->formHighlightRequiredFieldsCheckBox->setChecked(m_settings.m_formAppearanceFlags.testFlag(pdf::PDFFormManager::HighlightRequiredFields));
// Signature Settings
ui->signatureVerificationEnableCheckBox->setChecked(m_settings.m_signatureVerificationEnabled);
ui->signatureStrictModeEnabledCheckBox->setChecked(m_settings.m_signatureTreatWarningsAsErrors);
ui->signatureIgnoreExpiredCheckBox->setChecked(m_settings.m_signatureIgnoreCertificateValidityTime);
ui->signatureUseSystemCertificateStoreCheckBox->setChecked(m_settings.m_signatureUseSystemStore);
}
void PDFViewerSettingsDialog::saveData()
{
if (m_isLoadingData)
{
return;
}
QObject* sender = this->sender();
if (sender == ui->renderingEngineComboBox)
{
m_settings.m_rendererEngine = static_cast<pdf::RendererEngine>(ui->renderingEngineComboBox->currentData().toInt());
}
else if (sender == ui->prefetchPagesCheckBox)
{
m_settings.m_prefetchPages = ui->prefetchPagesCheckBox->isChecked();
}
else if (sender == ui->antialiasingCheckBox)
{
m_settings.m_features.setFlag(pdf::PDFRenderer::Antialiasing, ui->antialiasingCheckBox->isChecked());
}
else if (sender == ui->textAntialiasingCheckBox)
{
m_settings.m_features.setFlag(pdf::PDFRenderer::TextAntialiasing, ui->textAntialiasingCheckBox->isChecked());
}
else if (sender == ui->smoothPicturesCheckBox)
{
m_settings.m_features.setFlag(pdf::PDFRenderer::SmoothImages, ui->smoothPicturesCheckBox->isChecked());
}
else if (sender == ui->ignoreOptionalContentCheckBox)
{
m_settings.m_features.setFlag(pdf::PDFRenderer::IgnoreOptionalContent, ui->ignoreOptionalContentCheckBox->isChecked());
}
else if (sender == ui->displayAnnotationsCheckBox)
{
m_settings.m_features.setFlag(pdf::PDFRenderer::DisplayAnnotations, ui->displayAnnotationsCheckBox->isChecked());
}
else if (sender == ui->clipToCropBoxCheckBox)
{
m_settings.m_features.setFlag(pdf::PDFRenderer::ClipToCropBox, ui->clipToCropBoxCheckBox->isChecked());
}
else if (sender == ui->displayTimeCheckBox)
{
m_settings.m_features.setFlag(pdf::PDFRenderer::DisplayTimes, ui->displayTimeCheckBox->isChecked());
}
else if (sender == ui->preferredMeshResolutionEdit)
{
m_settings.m_preferredMeshResolutionRatio = ui->preferredMeshResolutionEdit->value();
}
else if (sender == ui->minimalMeshResolutionEdit)
{
m_settings.m_minimalMeshResolutionRatio = ui->minimalMeshResolutionEdit->value();
}
else if (sender == ui->colorToleranceEdit)
{
m_settings.m_colorTolerance = ui->colorToleranceEdit->value();
}
else if (sender == ui->allowLaunchCheckBox)
{
m_settings.m_allowLaunchApplications = ui->allowLaunchCheckBox->isChecked();
}
else if (sender == ui->allowRunURICheckBox)
{
m_settings.m_allowLaunchURI = ui->allowRunURICheckBox->isChecked();
}
else if (sender == ui->developerModeCheckBox)
{
m_settings.m_allowDeveloperMode = ui->developerModeCheckBox->isChecked();
}
else if (sender == ui->compiledPageCacheSizeEdit)
{
m_settings.m_compiledPageCacheLimit = ui->compiledPageCacheSizeEdit->value();
}
else if (sender == ui->thumbnailCacheSizeEdit)
{
m_settings.m_thumbnailsCacheLimit = ui->thumbnailCacheSizeEdit->value();
}
else if (sender == ui->cachedFontLimitEdit)
{
m_settings.m_fontCacheLimit = ui->cachedFontLimitEdit->value();
}
else if (sender == ui->cachedInstancedFontLimitEdit)
{
m_settings.m_instancedFontCacheLimit = ui->cachedInstancedFontLimitEdit->value();
}
else if (sender == ui->cmsTypeComboBox)
{
m_cmsSettings.system = static_cast<pdf::PDFCMSSettings::System>(ui->cmsTypeComboBox->currentData().toInt());
}
else if (sender == ui->cmsRenderingIntentComboBox)
{
m_cmsSettings.intent = static_cast<pdf::RenderingIntent>(ui->cmsRenderingIntentComboBox->currentData().toInt());
}
else if (sender == ui->cmsAccuracyComboBox)
{
m_cmsSettings.accuracy = static_cast<pdf::PDFCMSSettings::Accuracy>(ui->cmsAccuracyComboBox->currentData().toInt());
}
else if (sender == ui->cmsColorAdaptationXYZComboBox)
{
m_cmsSettings.colorAdaptationXYZ = static_cast<pdf::PDFCMSSettings::ColorAdaptationXYZ>(ui->cmsColorAdaptationXYZComboBox->currentData().toInt());
}
else if (sender == ui->cmsIsBlackPointCompensationCheckBox)
{
m_cmsSettings.isBlackPointCompensationActive = ui->cmsIsBlackPointCompensationCheckBox->isChecked();
}
else if (sender == ui->cmsWhitePaperColorTransformedCheckBox)
{
m_cmsSettings.isWhitePaperColorTransformed = ui->cmsWhitePaperColorTransformedCheckBox->isChecked();
}
else if (sender == ui->cmsConsiderOutputIntentCheckBox)
{
m_cmsSettings.isConsiderOutputIntent = ui->cmsConsiderOutputIntentCheckBox->isChecked();
}
else if (sender == ui->cmsOutputColorProfileComboBox)
{
m_cmsSettings.outputCS = ui->cmsOutputColorProfileComboBox->currentData().toString();
}
else if (sender == ui->cmsDeviceGrayColorProfileComboBox)
{
m_cmsSettings.deviceGray = ui->cmsDeviceGrayColorProfileComboBox->currentData().toString();
}
else if (sender == ui->cmsDeviceRGBColorProfileComboBox)
{
m_cmsSettings.deviceRGB = ui->cmsDeviceRGBColorProfileComboBox->currentData().toString();
}
else if (sender == ui->cmsDeviceCMYKColorProfileComboBox)
{
m_cmsSettings.deviceCMYK = ui->cmsDeviceCMYKColorProfileComboBox->currentData().toString();
}
else if (sender == ui->cmsProfileDirectoryEdit)
{
m_cmsSettings.profileDirectory = ui->cmsProfileDirectoryEdit->text();
}
else if (sender == ui->multithreadingComboBox)
{
m_settings.m_multithreadingStrategy = static_cast<pdf::PDFExecutionPolicy::Strategy>(ui->multithreadingComboBox->currentData().toInt());
}
else if (sender == ui->maximumRecentFileCountEdit)
{
m_otherSettings.maximumRecentFileCount = ui->maximumRecentFileCountEdit->value();
}
else if (sender == ui->speechEnginesComboBox)
{
m_settings.m_speechEngine = ui->speechEnginesComboBox->currentData().toString();
}
else if (sender == ui->speechLocaleComboBox)
{
m_settings.m_speechLocale = ui->speechLocaleComboBox->currentData().toString();
}
else if (sender == ui->speechVoiceComboBox)
{
m_settings.m_speechVoice = ui->speechVoiceComboBox->currentData().toString();
}
else if (sender == ui->speechRateEdit)
{
m_settings.m_speechRate = ui->speechRateEdit->value();
}
else if (sender == ui->speechPitchEdit)
{
m_settings.m_speechPitch = ui->speechPitchEdit->value();
}
else if (sender == ui->speechVolumeEdit)
{
m_settings.m_speechVolume = ui->speechVolumeEdit->value();
}
else if (sender == ui->magnifierSizeEdit)
{
m_settings.m_magnifierSize = ui->magnifierSizeEdit->value();
}
else if (sender == ui->magnifierZoomEdit)
{
m_settings.m_magnifierZoom = ui->magnifierZoomEdit->value();
}
else if (sender == ui->foregroundColorEdit)
{
m_cmsSettings.foregroundColor.fromString(ui->foregroundColorEdit->text());
if (!m_cmsSettings.foregroundColor.isValid())
{
pdf::PDFColorConvertor colorConvertor;
m_cmsSettings.foregroundColor = colorConvertor.getForegroundColor();
}
}
else if (sender == ui->backgroundColorEdit)
{
m_cmsSettings.backgroundColor.fromString(ui->backgroundColorEdit->text());
if (!m_cmsSettings.backgroundColor.isValid())
{
pdf::PDFColorConvertor colorConvertor;
m_cmsSettings.backgroundColor = colorConvertor.getBackgroundColor();
}
}
else if (sender == ui->sigmoidFunctionSlopeEdit)
{
m_cmsSettings.sigmoidSlopeFactor = ui->sigmoidFunctionSlopeEdit->value();
}
else if (sender == ui->bitonalThresholdEdit)
{
m_cmsSettings.bitonalThreshold = ui->bitonalThresholdEdit->value();
}
else if (sender == ui->formHighlightFieldsCheckBox)
{
m_settings.m_formAppearanceFlags.setFlag(pdf::PDFFormManager::HighlightFields, ui->formHighlightFieldsCheckBox->isChecked());
}
else if (sender == ui->formHighlightRequiredFieldsCheckBox)
{
m_settings.m_formAppearanceFlags.setFlag(pdf::PDFFormManager::HighlightRequiredFields, ui->formHighlightRequiredFieldsCheckBox->isChecked());
}
else if (sender == ui->maximumUndoStepsEdit)
{
m_settings.m_maximumUndoSteps = ui->maximumUndoStepsEdit->value();
}
else if (sender == ui->maximumRedoStepsEdit)
{
m_settings.m_maximumRedoSteps = ui->maximumRedoStepsEdit->value();
}
else if (sender == ui->logicalPixelZoomCheckBox)
{
m_settings.m_features.setFlag(pdf::PDFRenderer::LogicalSizeZooming, ui->logicalPixelZoomCheckBox->isChecked());
}
else if (sender == ui->signatureVerificationEnableCheckBox)
{
m_settings.m_signatureVerificationEnabled = ui->signatureVerificationEnableCheckBox->isChecked();
}
else if (sender == ui->signatureStrictModeEnabledCheckBox)
{
m_settings.m_signatureTreatWarningsAsErrors = ui->signatureStrictModeEnabledCheckBox->isChecked();
}
else if (sender == ui->signatureIgnoreExpiredCheckBox)
{
m_settings.m_signatureIgnoreCertificateValidityTime = ui->signatureIgnoreExpiredCheckBox->isChecked();
}
else if (sender == ui->signatureUseSystemCertificateStoreCheckBox)
{
m_settings.m_signatureUseSystemStore = ui->signatureUseSystemCertificateStoreCheckBox->isChecked();
}
const bool loadData = !qobject_cast<const QDoubleSpinBox*>(sender) && !qobject_cast<const QSpinBox*>(sender);
if (loadData)
{
this->loadData();
}
}
void PDFViewerSettingsDialog::updateTrustedCertificatesTable()
{
ui->trustedCertificateStoreTableWidget->setUpdatesEnabled(false);
ui->trustedCertificateStoreTableWidget->clear();
const pdf::PDFCertificateEntries& certificates = m_certificateStore.getCertificates();
ui->trustedCertificateStoreTableWidget->setRowCount(int(certificates.size()));
ui->trustedCertificateStoreTableWidget->setColumnCount(5);
ui->trustedCertificateStoreTableWidget->verticalHeader()->setVisible(true);
ui->trustedCertificateStoreTableWidget->setShowGrid(true);
ui->trustedCertificateStoreTableWidget->setEditTriggers(QTableWidget::NoEditTriggers);
ui->trustedCertificateStoreTableWidget->setHorizontalHeaderLabels(QStringList() << tr("Type") << tr("Certificate") << tr("Organization") << tr("Valid from") << tr("Valid to"));
for (int i = 0; i < certificates.size(); ++i)
{
QString type;
switch (certificates[i].type)
{
case pdf::PDFCertificateEntry::EntryType::User:
type = tr("User");
break;
case pdf::PDFCertificateEntry::EntryType::System:
type = tr("System");
break;
default:
Q_ASSERT(false);
break;
}
const pdf::PDFCertificateInfo& info = certificates[i].info;
ui->trustedCertificateStoreTableWidget->setItem(i, 0, new QTableWidgetItem(type));
ui->trustedCertificateStoreTableWidget->setItem(i, 1, new QTableWidgetItem(info.getName(pdf::PDFCertificateInfo::CommonName)));
ui->trustedCertificateStoreTableWidget->setItem(i, 2, new QTableWidgetItem(info.getName(pdf::PDFCertificateInfo::OrganizationName)));
QDateTime notValidBefore = info.getNotValidBefore().toLocalTime();
QDateTime notValidAfter = info.getNotValidAfter().toLocalTime();
if (notValidBefore.isValid())
{
ui->trustedCertificateStoreTableWidget->setItem(i, 3, new QTableWidgetItem(QLocale::system().toString(notValidBefore, QLocale::ShortFormat)));
}
if (notValidAfter.isValid())
{
ui->trustedCertificateStoreTableWidget->setItem(i, 4, new QTableWidgetItem(QLocale::system().toString(notValidAfter, QLocale::ShortFormat)));
}
}
ui->trustedCertificateStoreTableWidget->resizeColumnsToContents();
ui->trustedCertificateStoreTableWidget->setUpdatesEnabled(true);
}
void PDFViewerSettingsDialog::updateTrustedCertificatesTableActions()
{
ui->removeCertificateButton->setEnabled(!ui->trustedCertificateStoreTableWidget->selectionModel()->selectedRows().isEmpty());
}
void PDFViewerSettingsDialog::loadActionShortcutsTable()
{
ui->shortcutsTableWidget->setRowCount(m_actions.size());
ui->shortcutsTableWidget->setColumnCount(2);
ui->shortcutsTableWidget->setHorizontalHeaderLabels({ tr("Action"), tr("Shortcut")});
ui->shortcutsTableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
for (int i = 0; i < m_actions.size(); ++i)
{
QAction* action = m_actions[i];
// Action name and icon
QTableWidgetItem* actionItem = new QTableWidgetItem(action->icon(), action->text());
actionItem->setFlags(Qt::ItemIsEnabled);
ui->shortcutsTableWidget->setItem(i, 0, actionItem);
// Action shortcut
QTableWidgetItem* shortcutItem = new QTableWidgetItem(action->shortcut().toString(QKeySequence::NativeText));
ui->shortcutsTableWidget->setItem(i, 1, shortcutItem);
}
}
bool PDFViewerSettingsDialog::saveActionShortcutsTable()
{
// Jakub Melka: we need validation here
for (int i = 0; i < m_actions.size(); ++i)
{
QString shortcut = ui->shortcutsTableWidget->item(i, 1)->data(Qt::DisplayRole).toString();
if (!shortcut.isEmpty())
{
QKeySequence sequence = QKeySequence::fromString(shortcut, QKeySequence::NativeText);
if (sequence.toString(QKeySequence::PortableText).isEmpty())
{
QMessageBox::critical(this, tr("Error"), tr("Shortcut '%1' is invalid for action %2.").arg(shortcut, m_actions[i]->text()));
return false;
}
}
}
for (int i = 0; i < m_actions.size(); ++i)
{
QAction* action = m_actions[i];
// Set shortcut to the action
QString shortcut = ui->shortcutsTableWidget->item(i, 1)->data(Qt::DisplayRole).toString();
QKeySequence sequence = QKeySequence::fromString(shortcut, QKeySequence::NativeText);
action->setShortcut(sequence);
}
return true;
}
void PDFViewerSettingsDialog::loadPluginsTable()
{
ui->pluginsTableWidget->setRowCount(int(m_plugins.size()));
ui->pluginsTableWidget->setColumnCount(5);
ui->pluginsTableWidget->setHorizontalHeaderLabels({ tr("Active"), tr("Name"), tr("Author"), tr("Version"), tr("License") });
ui->pluginsTableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
ui->pluginsTableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
for (int i = 0; i < m_plugins.size(); ++i)
{
const pdf::PDFPluginInfo& plugin = m_plugins[i];
QTableWidgetItem* activeItem = new QTableWidgetItem(QString());
activeItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
activeItem->setCheckState((m_enabledPlugins.contains(plugin.name)) ? Qt::Checked : Qt::Unchecked);
ui->pluginsTableWidget->setItem(i, 0, activeItem);
ui->pluginsTableWidget->setItem(i, 1, new QTableWidgetItem(plugin.name));
ui->pluginsTableWidget->setItem(i, 2, new QTableWidgetItem(plugin.author));
ui->pluginsTableWidget->setItem(i, 3, new QTableWidgetItem(plugin.version));
ui->pluginsTableWidget->setItem(i, 4, new QTableWidgetItem(plugin.license));
}
}
void PDFViewerSettingsDialog::savePluginsTable()
{
QStringList enabledPlugins;
for (int i = 0; i < m_plugins.size(); ++i)
{
bool enabled = ui->pluginsTableWidget->item(i, 0)->data(Qt::CheckStateRole).toInt() == Qt::Checked;
if (enabled)
{
enabledPlugins << m_plugins[i].name;
}
}
m_enabledPlugins = qMove(enabledPlugins);
}
void PDFViewerSettingsDialog::updatePluginInformation()
{
QModelIndexList rows = ui->pluginsTableWidget->selectionModel()->selectedRows();
if (rows.size() == 1)
{
ui->pluginDescriptionLabel->setText(m_plugins.at(rows.front().row()).description);
}
else
{
ui->pluginDescriptionLabel->setText(QString());
}
}
void PDFViewerSettingsDialog::setSpeechEngine(const QString& engine, const QString& locale)
{
if (m_currentSpeechEngine == engine && m_currentSpeechLocale == locale)
{
return;
}
QTextToSpeech textToSpeech(engine, nullptr);
textToSpeech.setLocale(QLocale(locale));
if (m_currentSpeechEngine != engine)
{
m_currentSpeechEngine = engine;
QVector<QLocale> locales = textToSpeech.availableLocales();
ui->speechLocaleComboBox->setUpdatesEnabled(false);
ui->speechLocaleComboBox->clear();
for (const QLocale& currentLocale : locales)
{
ui->speechLocaleComboBox->addItem(QString("%1 (%2)").arg(currentLocale.nativeLanguageName(), currentLocale.nativeTerritoryName()), currentLocale.name());
}
ui->speechLocaleComboBox->setUpdatesEnabled(true);
}
m_currentSpeechLocale = locale;
QVector<QVoice> voices = textToSpeech.availableVoices();
ui->speechVoiceComboBox->setUpdatesEnabled(false);
ui->speechVoiceComboBox->clear();
for (const QVoice& voice : voices)
{
ui->speechVoiceComboBox->addItem(QString("%1 (%2, %3)").arg(voice.name(), QVoice::genderName(voice.gender()), QVoice::ageName(voice.age())), voice.name());
}
ui->speechVoiceComboBox->setUpdatesEnabled(true);
}
bool PDFViewerSettingsDialog::canCloseDialog()
{
return true;
}
void PDFViewerSettingsDialog::accept()
{
if (!canCloseDialog())
{
return;
}
if (saveActionShortcutsTable())
{
savePluginsTable();
QDialog::accept();
}
}
void PDFViewerSettingsDialog::reject()
{
if (canCloseDialog())
{
QDialog::reject();
}
}
void PDFViewerSettingsDialog::on_cmsProfileDirectoryButton_clicked()
{
QString directory = QFileDialog::getExistingDirectory(this, tr("Select color profile directory"));
if (!directory.isEmpty())
{
m_cmsSettings.profileDirectory = directory;
loadData();
}
}
void PDFViewerSettingsDialog::on_removeCertificateButton_clicked()
{
std::set<int> rows;
QModelIndexList selectedIndices = ui->trustedCertificateStoreTableWidget->selectionModel()->selectedRows();
for (const QModelIndex& index : selectedIndices)
{
rows.insert(index.row());
}
pdf::PDFCertificateEntries newEntries;
const pdf::PDFCertificateEntries& certificates = m_certificateStore.getCertificates();
for (int i = 0; i < int(certificates.size()); ++i)
{
if (!rows.count(i))
{
newEntries.push_back(certificates[i]);
}
}
m_certificateStore.setCertificates(qMove(newEntries));
updateTrustedCertificatesTable();
}
} // namespace pdfviewer

View File

@@ -1,133 +0,0 @@
// Copyright (C) 2019-2021 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#ifndef PDFVIEWERSETTINGSDIALOG_H
#define PDFVIEWERSETTINGSDIALOG_H
#include "pdfviewersettings.h"
#include "pdfplugin.h"
#include <QDialog>
class QListWidgetItem;
namespace Ui
{
class PDFViewerSettingsDialog;
}
namespace pdfviewer
{
class PDFViewerSettingsDialog : public QDialog
{
Q_OBJECT
public:
struct OtherSettings
{
int maximumRecentFileCount = 0;
};
/// Constructor
/// \param settings Viewer settings
/// \param cmsSettings Color management system settings
/// \param otherSettings Other settings
/// \param certificateStore Certificate store
/// \param actions Actions
/// \param cmsManager CMS manager
/// \param parent Parent widget
explicit PDFViewerSettingsDialog(const PDFViewerSettings::Settings& settings,
const pdf::PDFCMSSettings& cmsSettings,
const OtherSettings& otherSettings,
const pdf::PDFCertificateStore& certificateStore,
const std::vector<QAction*>& actions,
pdf::PDFCMSManager* cmsManager,
const QStringList& enabledPlugins,
const pdf::PDFPluginInfos& plugins,
QWidget* parent);
virtual ~PDFViewerSettingsDialog() override;
virtual void accept() override;
virtual void reject() override;
enum Page : int
{
EngineSettings,
RenderingSettings,
ShadingSettings,
CacheSettings,
ShortcutSettings,
ColorManagementSystemSettings,
ColorPostprocessingSettings,
SecuritySettings,
UISettings,
SpeechSettings,
FormSettings,
SignatureSettings,
PluginsSettings
};
const PDFViewerSettings::Settings& getSettings() const { return m_settings; }
const pdf::PDFCMSSettings& getCMSSettings() const { return m_cmsSettings; }
const OtherSettings& getOtherSettings() const { return m_otherSettings; }
const pdf::PDFCertificateStore& getCertificateStore() const { return m_certificateStore; }
const QStringList& getEnabledPlugins() const { return m_enabledPlugins; }
private slots:
void on_optionsPagesWidget_currentItemChanged(QListWidgetItem* current, QListWidgetItem* previous);
void on_cmsProfileDirectoryButton_clicked();
void on_removeCertificateButton_clicked();
private:
void loadData();
void saveData();
void updateTrustedCertificatesTable();
void updateTrustedCertificatesTableActions();
void loadActionShortcutsTable();
bool saveActionShortcutsTable();
void loadPluginsTable();
void savePluginsTable();
void updatePluginInformation();
void setSpeechEngine(const QString& engine, const QString& locale);
/// Returns true, if dialog can be closed. If not, then message is displayed
/// and false is returned.
bool canCloseDialog();
Ui::PDFViewerSettingsDialog* ui;
PDFViewerSettings::Settings m_settings;
pdf::PDFCMSSettings m_cmsSettings;
OtherSettings m_otherSettings;
QList<QAction*> m_actions;
bool m_isLoadingData;
QStringList m_textToSpeechEngines;
QString m_currentSpeechEngine;
QString m_currentSpeechLocale;
pdf::PDFCertificateStore m_certificateStore;
QStringList m_enabledPlugins;
pdf::PDFPluginInfos m_plugins;
};
} // namespace pdfviewer
#endif // PDFVIEWERSETTINGSDIALOG_H

File diff suppressed because it is too large Load Diff

View File

@@ -1,228 +0,0 @@
// Copyright (C) 2022 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#include "pdfwintaskbarprogress.h"
#include <QWindow>
#if defined(Q_OS_WIN) && !defined(PDF4QT_NO_TASKBAR_PROGRESS)
#define PDF4QT_TASKBAR_PROGRESS
#endif
#ifdef PDF4QT_TASKBAR_PROGRESS
#include <ShObjIdl.h>
#endif
namespace pdfviewer
{
#ifdef PDF4QT_TASKBAR_PROGRESS
class PDFWinTaskBarProgressImpl
{
public:
PDFWinTaskBarProgressImpl()
{
HRESULT result = CoCreateInstance(CLSID_TaskbarList, nullptr, CLSCTX_INPROC_SERVER, __uuidof(ITaskbarList3), reinterpret_cast<void**>(&m_taskBarList));
if (FAILED(result))
{
qWarning("Failed to create task bar progress");
m_taskBarList = nullptr;
}
else
{
HRESULT taskBarInitResult = m_taskBarList->HrInit();
if (FAILED(taskBarInitResult))
{
qWarning("Failed to initialize task bar progress");
m_taskBarList->Release();
m_taskBarList = nullptr;
}
}
}
~PDFWinTaskBarProgressImpl()
{
if (m_taskBarList)
{
m_taskBarList->Release();
m_taskBarList = nullptr;
}
}
inline HWND getHandle() const
{
return m_window ? reinterpret_cast<HWND>(m_window->winId()) : HWND();
}
inline void updateProgress() const
{
if (m_window && m_taskBarList)
{
const pdf::PDFReal range = m_progressMax - m_progressMin;
const pdf::PDFReal offset = m_value - m_progressMin;
const ULONGLONG max = 1000;
if (!qFuzzyIsNull(range))
{
const ULONGLONG progress = max * offset / range;
m_taskBarList->SetProgressValue(getHandle(), progress, max);
}
else
{
m_taskBarList->SetProgressValue(getHandle(), 0, max);
}
TBPFLAG stateFlag = TBPF_NOPROGRESS;
if (m_progressBarVisible)
{
stateFlag = TBPF_NORMAL;
}
m_taskBarList->SetProgressState(getHandle(), stateFlag);
}
}
inline void setWindow(QWindow* window)
{
if (m_window = window)
{
m_window = window;
updateProgress();
}
}
inline void reset()
{
setValue(m_progressMin);
}
inline void show()
{
if (!m_progressBarVisible)
{
m_progressBarVisible = true;
updateProgress();
}
}
inline void hide()
{
if (m_progressBarVisible)
{
m_progressBarVisible = false;
updateProgress();
}
}
inline void setValue(pdf::PDFInteger value)
{
if (m_value != value)
{
m_value = qBound(m_progressMin, value, m_progressMax);
updateProgress();
}
}
inline void setRange(pdf::PDFInteger min, pdf::PDFInteger max)
{
Q_ASSERT(min < max);
if (m_progressMin != min || m_progressMax != max)
{
m_progressMin = min;
m_progressMax = max;
m_value = qBound(min, m_value, max);
updateProgress();
}
}
private:
QWindow* m_window = nullptr;
ITaskbarList3* m_taskBarList = nullptr;
// Progress bar
bool m_progressBarVisible = false;
pdf::PDFInteger m_progressMin = 0;
pdf::PDFInteger m_progressMax = 100;
pdf::PDFInteger m_value = 0;
};
#else
class PDFWinTaskBarProgressImpl
{
public:
constexpr PDFWinTaskBarProgressImpl() = default;
constexpr ~PDFWinTaskBarProgressImpl() = default;
constexpr void setWindow(QWindow* window) { Q_UNUSED(window); }
constexpr void reset() { }
constexpr void show() { }
constexpr void hide() { }
constexpr void setValue(pdf::PDFInteger value) { Q_UNUSED(value); }
constexpr void setRange(pdf::PDFInteger min, pdf::PDFInteger max) { Q_UNUSED(min); Q_UNUSED(max); }
};
#endif
PDFWinTaskBarProgress::PDFWinTaskBarProgress(QObject* parent) :
QObject(parent),
m_impl(new PDFWinTaskBarProgressImpl())
{
}
PDFWinTaskBarProgress::~PDFWinTaskBarProgress()
{
delete m_impl;
}
void PDFWinTaskBarProgress::setWindow(QWindow* window)
{
m_impl->setWindow(window);
}
void PDFWinTaskBarProgress::reset()
{
m_impl->reset();
}
void PDFWinTaskBarProgress::show()
{
m_impl->show();
}
void PDFWinTaskBarProgress::hide()
{
m_impl->hide();
}
void PDFWinTaskBarProgress::setValue(pdf::PDFInteger value)
{
m_impl->setValue(value);
}
void PDFWinTaskBarProgress::setRange(pdf::PDFInteger min, pdf::PDFInteger max)
{
m_impl->setRange(min, max);
}
} // namespace pdfviewer

View File

@@ -1,58 +0,0 @@
// Copyright (C) 2022 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT 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
// with the written consent of the copyright owner, any later version.
//
// PDF4QT 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 PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#ifndef PDFWINTASKBARPROGRESS_H
#define PDFWINTASKBARPROGRESS_H
#include "pdfviewerglobal.h"
#include "pdfglobal.h"
#include <QObject>
class QWindow;
namespace pdfviewer
{
class PDFWinTaskBarProgressImpl;
/// Windows task bar progress. Displays progress
/// in the task bar icon in window's bottom side.
class PDFWinTaskBarProgress : public QObject
{
Q_OBJECT
public:
PDFWinTaskBarProgress(QObject* parent);
virtual ~PDFWinTaskBarProgress() override;
void setWindow(QWindow* window);
void reset();
void show();
void hide();
void setValue(pdf::PDFInteger value);
void setRange(pdf::PDFInteger min, pdf::PDFInteger max);
private:
PDFWinTaskBarProgressImpl* m_impl;
};
} // namespace pdfviewer
#endif // PDFWINTASKBARPROGRESS_H

View File

@@ -1,39 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<g>
<path fill="none" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" d="M22,10v5c0,5-2,7-7,7H9
c-5,0-7-2-7-7V9c0-5,2-7,7-7h5"/>
<path fill="none" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" d="M22,10h-4c-3,0-4-1-4-4
V2L22,10z"/>
</g>
</g>
<g>
<g>
<path fill="#292D32" d="M12.263,10.617l-0.716,0.005l-0.053,0.012c-0.622,0.029-1.23,0.119-1.811,0.265
c-0.161,0.041-0.321,0.088-0.476,0.134L8.53,11.229l0.787,1.064l0.174-0.063c0.774-0.275,1.6-0.414,2.524-0.422l0.248-0.002
V10.617z"/>
<path fill="#292D32" d="M16.354,13.259l0.238,0.253c0.468,0.493,0.746,1.02,0.852,1.609l0.04,0.223l1.492-0.112l-0.047-0.272
c-0.138-0.8-0.511-1.511-1.141-2.175l-0.124-0.131l-1.247,0.577L16.354,13.259z"/>
<path fill="#292D32" d="M17.629,16.143L17.42,16.11l-0.067,0.2c-0.194,0.581-0.556,1.089-1.102,1.552l-0.271,0.229l0.308,0.177
c0.264,0.153,0.516,0.297,0.771,0.442l0.152,0.086l0.132-0.113c0.728-0.615,1.204-1.291,1.46-2.065l0.091-0.281l-0.291-0.044
C18.275,16.243,17.956,16.194,17.629,16.143z"/>
<path fill="#292D32" d="M13.401,11.936l0.024,0.005c0.291,0.065,0.565,0.127,0.828,0.208c0.268,0.083,0.521,0.186,0.793,0.296
c0.121,0.049,0.243,0.099,0.368,0.147l0.144,0.055l0.911-0.824l0.054-0.048l-0.317-0.167c-0.891-0.468-1.856-0.766-2.951-0.912
l-0.218-0.028l-0.282,1.065l-0.014,0.049l0.25,0.06C13.128,11.876,13.266,11.906,13.401,11.936z"/>
<path fill="#292D32" d="M7.196,17.352c-0.046-0.083-0.092-0.164-0.139-0.244l-0.025-0.043c-0.113-0.195-0.22-0.381-0.295-0.565
c-0.076-0.185-0.122-0.378-0.171-0.584c-0.023-0.095-0.046-0.19-0.072-0.283l-0.05-0.185h-1.42l0.017,0.266
c0.05,0.81,0.346,1.543,0.904,2.241l0.115,0.143l1.271-0.494L7.196,17.352z"/>
<path fill="#292D32" d="M6.676,14.662l0.083-0.185c0.25-0.559,0.667-1.054,1.241-1.474l0.266-0.195l-1.048-0.816l-0.03-0.023
l-0.153,0.112c-0.804,0.592-1.357,1.242-1.689,1.99l-0.125,0.282l1.415,0.3L6.676,14.662z"/>
<path fill="#292D32" d="M8.328,18.271l-0.146-0.089l-1.033,0.797l-0.057,0.045l0.31,0.189c0.854,0.52,1.786,0.867,2.85,1.063
l0.206,0.038l0.073-0.194c0.087-0.226,0.17-0.444,0.255-0.671l0.104-0.279l-0.292-0.054C9.741,18.955,9,18.679,8.328,18.271z"/>
</g>
<path fill="#292D32" d="M15.07,18.639l-0.023-0.027c-0.452,0.304-1.75,0.524-2.438,0.623c-0.025,0.004-0.048,0.008-0.074,0.012
c-0.225,0.032-0.37,0.049-0.37,0.049l0.121,1.127l0.435-0.016l0,0c0.847-0.06,1.674-0.231,2.459-0.509
c0.087-0.031,0.172-0.065,0.259-0.1l0.486-0.189L15.07,18.639z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -1,39 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<g>
<path fill="none" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" d="M22,10v5c0,5-2,7-7,7H9
c-5,0-7-2-7-7V9c0-5,2-7,7-7h5"/>
<path fill="none" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" d="M22,10h-4c-3,0-4-1-4-4
V2L22,10z"/>
</g>
</g>
<path fill-rule="evenodd" clip-rule="evenodd" fill="none" d="M18.222,10.122c0.04,0.369-0.322,0.697-0.678,0.69
c-0.387-0.007-0.678-0.299-0.688-0.686c-0.012-0.395,0.335-0.697,0.689-0.698C17.898,9.427,18.26,9.751,18.222,10.122z"/>
<path fill="#292D32" d="M5.188,13.729"/>
<g>
<path fill="#292D32" d="M9.045,14.663c-0.06,0-0.114,0.017-0.158,0.049l-0.194,0.143c-0.236,0.173-0.478,0.362-0.739,0.579
l-0.199,0.164c-0.041,0.033-0.09,0.096-0.099,0.201c-0.014,0.18,0.099,0.423,0.303,0.652c0.169,0.19,0.426,0.394,0.64,0.394
c0.067,0,0.127-0.021,0.173-0.059l0.186-0.152c0.238-0.195,0.457-0.368,0.668-0.523l0.208-0.153c0.042-0.03,0.096-0.09,0.11-0.195
c0.024-0.175-0.077-0.431-0.264-0.667C9.515,14.886,9.262,14.663,9.045,14.663z M8.599,16.687L8.599,16.687v0.008V16.687z"/>
<path fill="#292D32" d="M12.522,13.168l-0.291,0.053c-0.323,0.064-0.647,0.15-0.965,0.256l-0.244,0.081
c-0.049,0.017-0.117,0.057-0.162,0.15c-0.077,0.159-0.062,0.436,0.041,0.72c0.104,0.286,0.311,0.621,0.556,0.621l0.312-0.091
c0.249-0.084,0.508-0.153,0.77-0.205l0.25-0.049c0.05-0.011,0.122-0.041,0.18-0.128c0.097-0.147,0.118-0.423,0.055-0.718
C12.949,13.515,12.766,13.168,12.522,13.168z"/>
<path fill="#292D32" d="M6.296,16.947c-0.062,0-0.119,0.019-0.164,0.053l-0.19,0.146c-0.244,0.188-0.457,0.334-0.653,0.448
l-0.223,0.131c-0.045,0.026-0.104,0.079-0.13,0.182c-0.042,0.172,0.031,0.438,0.191,0.693c0.144,0.229,0.392,0.497,0.617,0.497
c0.048,0,0.092-0.012,0.131-0.034l0.208-0.122c0.252-0.146,0.52-0.33,0.82-0.56l0.206-0.158c0.042-0.031,0.094-0.092,0.106-0.197
c0.021-0.179-0.084-0.427-0.281-0.663C6.768,17.162,6.512,16.947,6.296,16.947z"/>
<path fill="#292D32" d="M16.365,13.353l-0.248-0.047c-0.314-0.06-0.631-0.108-0.941-0.146l-0.273-0.03
c-0.254,0-0.417,0.364-0.466,0.725c-0.041,0.299,0.001,0.571,0.108,0.711c0.063,0.082,0.138,0.106,0.188,0.112l0.252,0.031
c0.291,0.036,0.574,0.08,0.842,0.131l0.243,0.046l0.046,0.004c0.247,0,0.427-0.349,0.495-0.694
c0.059-0.297,0.033-0.572-0.066-0.719C16.485,13.391,16.414,13.361,16.365,13.353z"/>
<path fill="#292D32" d="M20.093,14.734c-0.037-0.1-0.101-0.146-0.147-0.166l-0.232-0.105c-0.297-0.135-0.58-0.253-0.862-0.364
l-0.227-0.09c-0.253-0.102-0.536,0.266-0.667,0.574c-0.118,0.277-0.147,0.552-0.079,0.715c0.041,0.098,0.107,0.141,0.155,0.159
l0.239,0.094c0.261,0.102,0.52,0.211,0.796,0.335l0.222,0.098c0.032,0.015,0.066,0.021,0.104,0.021
c0.235,0,0.463-0.304,0.586-0.563C20.11,15.171,20.153,14.899,20.093,14.734z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -1,31 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<g>
<path fill="none" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" d="M22,10v5c0,5-2,7-7,7H9
c-5,0-7-2-7-7V9c0-5,2-7,7-7h5"/>
<path fill="none" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" d="M22,10h-4c-3,0-4-1-4-4
V2L22,10z"/>
</g>
</g>
<path fill-rule="evenodd" clip-rule="evenodd" fill="none" d="M18.222,10.122c0.04,0.369-0.322,0.697-0.678,0.69
c-0.387-0.007-0.678-0.299-0.688-0.686c-0.012-0.395,0.335-0.697,0.689-0.698C17.898,9.427,18.26,9.751,18.222,10.122z"/>
<path fill="#292D32" d="M5.188,13.729"/>
<g>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#292D32" d="M12.001,12.068c1.252,0,2.504-0.003,3.754,0.001
c0.554,0.002,0.911,0.5,0.723,0.992c-0.112,0.289-0.333,0.447-0.643,0.474c-0.091,0.011-0.183,0.005-0.275,0.005
c-2.423,0-4.847,0.002-7.271,0c-0.497,0-0.835-0.322-0.813-0.77c0.021-0.41,0.333-0.7,0.77-0.701
c0.97-0.004,1.939-0.001,2.908-0.001C11.437,12.068,11.718,12.068,12.001,12.068z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#292D32" d="M11.999,16.487c-1.246,0-2.491,0-3.737-0.002
c-0.503,0-0.835-0.359-0.779-0.831c0.04-0.341,0.312-0.604,0.661-0.637c0.049-0.004,0.098-0.004,0.147-0.004
c2.472,0,4.944,0,7.417,0c0.493,0,0.823,0.308,0.815,0.749c-0.006,0.417-0.326,0.721-0.769,0.723
c-0.958,0.004-1.915,0.002-2.872,0.002C12.588,16.487,12.293,16.487,11.999,16.487z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#292D32" d="M10.503,19.433c-0.76,0-1.521,0.002-2.281-0.002
c-0.344-0.002-0.612-0.199-0.712-0.507c-0.096-0.296-0.008-0.631,0.25-0.803c0.131-0.086,0.303-0.154,0.457-0.154
c1.526-0.012,3.053-0.01,4.579-0.006c0.435,0.002,0.754,0.328,0.75,0.741c-0.004,0.414-0.326,0.727-0.764,0.729
C12.023,19.435,11.263,19.433,10.503,19.433z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -1,34 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<g>
<path fill="none" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" d="M22,10v5c0,5-2,7-7,7H9
c-5,0-7-2-7-7V9c0-5,2-7,7-7h5"/>
<path fill="none" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" d="M22,10h-4c-3,0-4-1-4-4
V2L22,10z"/>
</g>
</g>
<g>
<polygon fill="#292D32" points="8.852,16.93 7.811,17.543 8.56,18.893 9.602,18.279 "/>
<polygon fill="#292D32" points="8.181,15.78 8.188,15.776 7.985,15.428 8.188,15.078 7.136,14.463 6.608,15.428 6.859,15.888
6.859,15.888 6.882,15.929 7.136,16.396 7.14,16.394 7.607,17.237 8.649,16.624 "/>
<polygon fill="#292D32" points="9.132,13.404 8.092,12.791 7.342,14.141 8.384,14.754 "/>
<rect x="10.778" y="10.684" fill="#292D32" width="1.509" height="1.213"/>
<polygon fill="#292D32" points="13.976,11.896 14.145,12.203 15.188,11.715 14.74,10.684 14.131,10.684 13.542,10.684
12.621,10.684 12.621,11.896 13.542,11.896 "/>
<polygon fill="#292D32" points="15.136,13.925 16.176,13.314 15.426,11.963 14.386,12.578 "/>
<polygon fill="#292D32" points="17.128,14.969 17.129,14.969 17.076,14.875 16.852,14.463 16.849,14.465 16.379,13.619
15.338,14.232 15.806,15.074 15.798,15.079 16.002,15.428 15.799,15.775 16.852,16.396 17.379,15.428 "/>
<polygon fill="#292D32" points="14.853,17.453 15.896,18.063 16.645,16.716 15.604,16.103 "/>
<polygon fill="#292D32" points="14.144,18.65 13.975,18.96 13.542,18.96 13.542,20.173 14.74,20.173 14.936,19.724 15.708,18.387
14.667,17.773 "/>
<rect x="11.699" y="18.96" fill="#292D32" width="1.51" height="1.213"/>
<polygon fill="#292D32" points="10.012,18.96 9.843,18.65 8.799,19.143 9.246,20.173 9.857,20.173 10.445,20.173 11.366,20.173
11.366,18.96 10.445,18.96 "/>
<polygon fill="#292D32" points="9.815,12.191 10.011,11.896 10.445,11.896 10.445,10.684 9.246,10.684 9.029,11.12 8.279,12.47
9.321,13.083 "/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -1,29 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<g>
<path fill="none" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" d="M22,10v5c0,5-2,7-7,7H9
c-5,0-7-2-7-7V9c0-5,2-7,7-7h5"/>
<path fill="none" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" d="M22,10h-4c-3,0-4-1-4-4
V2L22,10z"/>
</g>
</g>
<path fill="none" d="M18.223,10.122c0.039,0.369-0.322,0.697-0.679,0.69c-0.387-0.007-0.678-0.299-0.688-0.686
c-0.012-0.395,0.336-0.697,0.689-0.698S18.26,9.751,18.223,10.122z"/>
<g>
<path fill="#292D32" d="M16.787,15.384c-0.12,0.175-0.271,0.321-0.491,0.338c-0.12,0.01-0.252-0.004-0.367-0.042
c-0.49-0.159-0.978-0.333-1.465-0.505c-0.433-0.153-0.606-0.548-0.422-0.949c0.113-0.255,0.437-0.436,0.701-0.353
c0.568,0.179,1.134,0.369,1.695,0.579c0.308,0.116,0.429,0.354,0.417,0.691c-0.001,0.014,0.002,0.026,0.002,0.04
C16.833,15.252,16.811,15.318,16.787,15.384z"/>
<path fill="#292D32" d="M9.161,15.545c-0.248,0.187-0.489,0.381-0.748,0.55c-0.277,0.182-0.654,0.094-0.856-0.173
c-0.203-0.271-0.174-0.649,0.068-0.872c0.051-0.048,0.104-0.093,0.162-0.135c0.439-0.322,0.873-0.654,1.322-0.963
c0.274-0.188,0.653-0.096,0.856,0.174c0.201,0.268,0.173,0.646-0.068,0.871c-0.022,0.021-0.043,0.046-0.069,0.065
C9.608,15.227,9.381,15.383,9.161,15.545C9.16,15.543,9.164,15.547,9.161,15.545z"/>
</g>
<circle fill="#292D32" cx="6.074" cy="17.117" r="1.523"/>
<circle fill="#292D32" cx="12.055" cy="14.072" r="1.523"/>
<circle fill="#292D32" cx="18.529" cy="16.004" r="1.523"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -1,73 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<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"
version="1.1"
id="Vrstva_1"
x="0px"
y="0px"
width="24px"
height="24px"
viewBox="0 0 24 24"
enable-background="new 0 0 24 24"
xml:space="preserve"
sodipodi:docname="annot-rectangle.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"><metadata
id="metadata17"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs15" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="3840"
inkscape:window-height="2035"
id="namedview13"
showgrid="false"
inkscape:zoom="9.8333333"
inkscape:cx="12"
inkscape:cy="12"
inkscape:window-x="-13"
inkscape:window-y="-13"
inkscape:window-maximized="1"
inkscape:current-layer="Vrstva_1" />
<g
id="g8">
<g
id="g6">
<path
d="m 22,10 v 5 c 0,5 -2,7 -7,7 H 9 C 4,22 2,20 2,15 V 9 C 2,4 4,2 9,2 h 5"
id="path2"
inkscape:connector-curvature="0"
style="fill:none;stroke:#292d32;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round" />
<path
d="M 22,10 H 18 C 15,10 14,9 14,6 V 2 Z"
id="path4"
inkscape:connector-curvature="0"
style="fill:none;stroke:#292d32;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round" />
</g>
</g>
<g
id="g10">
</g>
<rect
style="opacity:1;fill:none;fill-opacity:1;stroke:#292d32;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
id="rect824"
width="9.1525431"
height="7.9322033"
x="7.6271186"
y="11.694916"
ry="0" /></svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -1,141 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<g>
<path fill="none" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" d="M22,10v5c0,5-2,7-7,7H9
c-5,0-7-2-7-7V9c0-5,2-7,7-7h5"/>
<path fill="none" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" d="M22,10h-4c-3,0-4-1-4-4
V2L22,10z"/>
</g>
</g>
<path fill-rule="evenodd" clip-rule="evenodd" fill="none" d="M18.222,10.122c0.04,0.369-0.322,0.697-0.678,0.69
c-0.387-0.007-0.678-0.299-0.688-0.686c-0.012-0.395,0.335-0.697,0.689-0.698C17.898,9.427,18.26,9.751,18.222,10.122z"/>
<path fill="#292D32" d="M5.188,13.729"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M16.008,20.289c0,0.059-0.014,0.107,0.002,0.143
s0.063,0.086,0.092,0.084c0.439-0.02,0.844-0.186,0.941-0.719c0.063-0.342,0.061-0.281-0.252-0.293
c-0.104-0.002-0.145,0.025-0.16,0.129c-0.041,0.281-0.178,0.426-0.443,0.459C16.035,20.109,15.971,20.162,16.008,20.289z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M7.948,20.316c0-0.186,0-0.186-0.198-0.225
c-0.221-0.041-0.362-0.164-0.413-0.375c-0.052-0.209-0.05-0.211-0.282-0.209c-0.022,0-0.044,0-0.066-0.002
c-0.08-0.004-0.107,0.029-0.105,0.105c0.014,0.502,0.32,0.83,0.84,0.895C7.948,20.535,7.948,20.535,7.948,20.316z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M16.828,11.83c0.063,0,0.111,0.012,0.15-0.003
c0.037-0.015,0.09-0.059,0.088-0.088c-0.021-0.386-0.164-0.791-0.746-0.893c-0.383-0.067-0.303-0.055-0.316,0.239
c-0.004,0.099,0.025,0.137,0.135,0.151c0.293,0.039,0.447,0.17,0.482,0.423C16.641,11.805,16.695,11.863,16.828,11.83z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M7.947,11.022c0-0.042,0.012-0.088-0.003-0.125
c-0.014-0.033-0.058-0.078-0.087-0.077c-0.448,0.018-0.858,0.195-0.95,0.742c-0.053,0.316-0.044,0.257,0.24,0.271
c0.125,0.005,0.165-0.036,0.181-0.15c0.038-0.258,0.182-0.396,0.435-0.441C7.947,11.208,7.947,11.208,7.947,11.022z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M17.074,17.898c0-0.109,0-0.219,0-0.328
c0-0.295,0-0.291-0.307-0.291c-0.105,0-0.127,0.039-0.125,0.127c0.004,0.27,0.002,0.537,0.002,0.807c0,0.307,0,0.303,0.32,0.291
c0.088-0.002,0.111-0.037,0.111-0.115C17.072,18.225,17.074,18.061,17.074,17.898z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M7.309,17.898c0-0.109,0-0.219,0-0.328
c0-0.295,0-0.291-0.306-0.291c-0.104,0.002-0.126,0.039-0.125,0.127c0.004,0.27-0.002,0.537,0.002,0.807
c0.005,0.336-0.065,0.283,0.322,0.291c0.079,0.002,0.111-0.025,0.109-0.102C7.307,18.232,7.309,18.066,7.309,17.898z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M14.311,10.813c-0.115,0-0.23,0-0.346,0
c-0.299,0.001-0.295,0.001-0.297,0.288c0,0.092,0.025,0.125,0.127,0.123c0.285-0.005,0.572,0.002,0.859-0.002
c0.346-0.005,0.291,0.068,0.299-0.296c0.002-0.092-0.041-0.115-0.127-0.113C14.654,10.816,14.482,10.813,14.311,10.813z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M11.991,20.115c-0.12,0-0.238,0-0.357,0
c-0.301-0.002-0.298-0.002-0.296,0.287c0,0.096,0.034,0.125,0.13,0.123c0.278-0.004,0.556,0.002,0.835-0.002
c0.368-0.006,0.305,0.068,0.314-0.309c0.003-0.08-0.03-0.104-0.109-0.102C12.334,20.117,12.163,20.115,11.991,20.115z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M14.305,20.115c-0.113,0-0.229,0-0.342,0
c-0.299,0-0.295,0-0.295,0.289c0,0.096,0.035,0.123,0.131,0.121c0.283-0.004,0.564,0.004,0.846-0.002
c0.355-0.006,0.303,0.074,0.309-0.316c0-0.072-0.035-0.094-0.105-0.094C14.666,20.117,14.486,20.115,14.305,20.115z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M16.645,15.666c0,0.109,0,0.219,0,0.328
c0,0.289,0,0.285,0.299,0.285c0.111,0.002,0.133-0.041,0.133-0.135c-0.004-0.264-0.002-0.529-0.002-0.793
c0-0.299,0-0.295-0.309-0.291c-0.092,0-0.125,0.023-0.123,0.113C16.648,15.338,16.645,15.502,16.645,15.666z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M7.309,15.67C7.309,15.67,7.309,15.67,7.309,15.67
c0-0.111,0-0.219,0-0.328c0.001-0.287,0.001-0.281-0.304-0.281c-0.1,0-0.13,0.029-0.128,0.123c0.005,0.264-0.002,0.529,0.003,0.795
c0.006,0.354-0.071,0.291,0.324,0.299c0.083,0.002,0.107-0.029,0.105-0.104C7.307,16.006,7.309,15.838,7.309,15.67z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M16.645,13.432c0,0.115,0,0.229,0,0.342
c0,0.291,0,0.287,0.311,0.283c0.094,0,0.121-0.031,0.121-0.117c-0.004-0.273,0-0.545-0.002-0.82
c-0.004-0.326,0.063-0.277-0.313-0.287c-0.098,0-0.121,0.037-0.119,0.121C16.648,13.113,16.645,13.273,16.645,13.432z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M9.646,20.523c0.11,0,0.22,0.002,0.33,0
c0.364-0.008,0.299,0.063,0.309-0.301c0.002-0.082-0.026-0.111-0.113-0.109c-0.291,0.004-0.582-0.002-0.873,0.002
c-0.344,0.006-0.29-0.068-0.297,0.301c-0.001,0.08,0.03,0.111,0.116,0.109C9.293,20.521,9.469,20.525,9.646,20.523z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M6.879,13.447c0,0.107,0,0.217,0,0.326
c-0.001,0.285-0.001,0.281,0.301,0.285c0.111,0,0.132-0.039,0.13-0.133c-0.004-0.268,0.002-0.537-0.002-0.807
c-0.006-0.33,0.07-0.277-0.311-0.285c-0.096-0.002-0.121,0.037-0.119,0.121C6.882,13.117,6.88,13.281,6.879,13.447z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M11.973,11.222c0.115,0,0.229,0,0.344,0c0.308,0,0.304,0,0.3-0.296
c-0.001-0.092-0.036-0.115-0.125-0.114c-0.283,0.003-0.565-0.001-0.848,0.002c-0.36,0.005-0.296-0.066-0.306,0.304
c-0.003,0.086,0.035,0.107,0.118,0.105C11.628,11.22,11.8,11.222,11.973,11.222z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M9.637,11.222c0.114,0,0.229,0,0.343,0c0.311,0,0.307,0,0.306-0.29
c0-0.097-0.039-0.122-0.132-0.121c-0.286,0.004-0.573-0.001-0.859,0.002C8.958,10.818,9.009,10.757,9,11.107
c-0.002,0.085,0.026,0.121,0.121,0.117C9.292,11.218,9.465,11.222,9.637,11.222z"/>
<g>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#292D32" stroke="#292D32" stroke-width="0.2" stroke-miterlimit="10" d="
M16.823,19.573c-0.104-0.002-0.145,0.025-0.16,0.129c-0.041,0.281-0.178,0.426-0.443,0.459c-0.152,0.018-0.217,0.07-0.18,0.197
c0,0.059-0.014,0.107,0.002,0.143s0.063,0.086,0.092,0.084c0.439-0.02,0.844-0.186,0.941-0.719
C17.138,19.524,17.136,19.585,16.823,19.573z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#292D32" stroke="#292D32" stroke-width="0.2" stroke-miterlimit="10" d="
M7.781,20.161c-0.221-0.041-0.362-0.164-0.413-0.375c-0.052-0.209-0.05-0.211-0.282-0.209c-0.022,0-0.044,0-0.066-0.002
c-0.08-0.004-0.107,0.029-0.105,0.105c0.014,0.502,0.32,0.83,0.84,0.895c0.226,0.029,0.226,0.029,0.225-0.189
C7.979,20.2,7.979,20.2,7.781,20.161z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#292D32" stroke="#292D32" stroke-width="0.2" stroke-miterlimit="10" d="
M16.171,11.305c0.293,0.039,0.447,0.17,0.482,0.423c0.02,0.146,0.074,0.205,0.207,0.171c0.063,0,0.111,0.012,0.15-0.003
c0.037-0.015,0.09-0.059,0.088-0.088c-0.021-0.386-0.164-0.791-0.746-0.893c-0.383-0.067-0.303-0.055-0.316,0.239
C16.032,11.252,16.062,11.291,16.171,11.305z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#292D32" stroke="#292D32" stroke-width="0.2" stroke-miterlimit="10" d="
M7.177,11.903c0.125,0.005,0.165-0.036,0.181-0.15c0.038-0.258,0.182-0.396,0.435-0.441c0.186-0.034,0.186-0.034,0.185-0.22
c0-0.042,0.012-0.088-0.003-0.125c-0.014-0.033-0.058-0.078-0.087-0.077c-0.448,0.018-0.858,0.195-0.95,0.742
C6.885,11.949,6.893,11.89,7.177,11.903z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#292D32" stroke="#292D32" stroke-width="0.2" stroke-miterlimit="10" d="
M17.106,17.64c0-0.295,0-0.291-0.307-0.291c-0.105,0-0.127,0.039-0.125,0.127c0.004,0.27,0.002,0.537,0.002,0.807
c0,0.307,0,0.303,0.32,0.291c0.088-0.002,0.111-0.037,0.111-0.115c-0.004-0.164-0.002-0.328-0.002-0.49
C17.106,17.858,17.106,17.749,17.106,17.64z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#292D32" stroke="#292D32" stroke-width="0.2" stroke-miterlimit="10" d="
M7.233,18.573c0.079,0.002,0.111-0.025,0.109-0.102c-0.004-0.17-0.001-0.336-0.001-0.504c0-0.109,0-0.219,0-0.328
c0-0.295,0-0.291-0.306-0.291c-0.104,0.002-0.126,0.039-0.125,0.127c0.004,0.27-0.002,0.537,0.002,0.807
C6.917,18.618,6.847,18.565,7.233,18.573z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#292D32" stroke="#292D32" stroke-width="0.2" stroke-miterlimit="10" d="
M14.858,10.881c-0.172,0.004-0.344,0.001-0.516,0.001c-0.115,0-0.23,0-0.346,0c-0.299,0.001-0.295,0.001-0.297,0.288
c0,0.092,0.025,0.125,0.127,0.123c0.285-0.005,0.572,0.002,0.859-0.002c0.346-0.005,0.291,0.068,0.299-0.296
C14.987,10.902,14.944,10.88,14.858,10.881z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#292D32" stroke="#292D32" stroke-width="0.2" stroke-miterlimit="10" d="
M12.539,20.183c-0.173,0.004-0.344,0.002-0.517,0.002c-0.12,0-0.238,0-0.357,0c-0.301-0.002-0.298-0.002-0.296,0.287
c0,0.096,0.034,0.125,0.13,0.123c0.278-0.004,0.556,0.002,0.835-0.002c0.368-0.006,0.306,0.068,0.314-0.309
C12.651,20.204,12.618,20.181,12.539,20.183z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#292D32" stroke="#292D32" stroke-width="0.2" stroke-miterlimit="10" d="
M14.88,20.183c-0.182,0.004-0.361,0.002-0.543,0.002c-0.113,0-0.229,0-0.342,0c-0.299,0-0.295,0-0.295,0.289
c0,0.096,0.035,0.123,0.131,0.121c0.283-0.004,0.564,0.004,0.846-0.002c0.355-0.006,0.303,0.074,0.309-0.316
C14.985,20.204,14.95,20.183,14.88,20.183z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#292D32" stroke="#292D32" stroke-width="0.2" stroke-miterlimit="10" d="
M16.798,15.13c-0.092,0-0.125,0.023-0.123,0.113c0.006,0.164,0.002,0.328,0.002,0.492c0,0.109,0,0.219,0,0.328
c0,0.289,0,0.285,0.299,0.285c0.111,0.002,0.133-0.041,0.133-0.135c-0.004-0.264-0.002-0.529-0.002-0.793
C17.106,15.122,17.106,15.126,16.798,15.13z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#292D32" stroke="#292D32" stroke-width="0.2" stroke-miterlimit="10" d="
M7.236,16.347c0.083,0.002,0.107-0.029,0.105-0.104c-0.003-0.168-0.001-0.336-0.001-0.504c0,0,0,0,0,0c0-0.111,0-0.219,0-0.328
c0.001-0.287,0.001-0.281-0.304-0.281c-0.1,0-0.13,0.029-0.128,0.123c0.005,0.264-0.002,0.529,0.003,0.795
C6.918,16.401,6.841,16.339,7.236,16.347z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#292D32" stroke="#292D32" stroke-width="0.2" stroke-miterlimit="10" d="
M16.794,12.901c-0.098,0-0.121,0.037-0.119,0.121c0.006,0.16,0.002,0.32,0.002,0.479c0,0.115,0,0.229,0,0.342
c0,0.291,0,0.287,0.311,0.283c0.094,0,0.121-0.031,0.121-0.117c-0.004-0.273,0-0.545-0.002-0.82
C17.103,12.862,17.169,12.911,16.794,12.901z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#292D32" stroke="#292D32" stroke-width="0.2" stroke-miterlimit="10" d="
M10.203,20.183c-0.291,0.004-0.582-0.002-0.873,0.002c-0.344,0.006-0.29-0.068-0.297,0.301c-0.001,0.08,0.03,0.111,0.116,0.109
c0.176-0.004,0.352,0,0.529-0.002c0.11,0,0.22,0.002,0.33,0c0.364-0.008,0.299,0.063,0.309-0.301
C10.318,20.21,10.29,20.181,10.203,20.183z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#292D32" stroke="#292D32" stroke-width="0.2" stroke-miterlimit="10" d="
M6.911,13.843c-0.001,0.285-0.001,0.281,0.301,0.285c0.111,0,0.132-0.039,0.13-0.133c-0.004-0.268,0.002-0.537-0.002-0.807
c-0.006-0.33,0.07-0.277-0.311-0.285c-0.096-0.002-0.121,0.037-0.119,0.121c0.004,0.162,0.001,0.326,0.001,0.492
C6.911,13.624,6.911,13.733,6.911,13.843z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#292D32" stroke="#292D32" stroke-width="0.2" stroke-miterlimit="10" d="
M12.524,10.881c-0.283,0.003-0.565-0.001-0.848,0.002c-0.36,0.005-0.296-0.066-0.306,0.304c-0.003,0.086,0.035,0.107,0.118,0.105
c0.172-0.004,0.344-0.001,0.517-0.001c0.115,0,0.229,0,0.344,0c0.309,0,0.305,0,0.301-0.296
C12.648,10.904,12.613,10.88,12.524,10.881z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#292D32" stroke="#292D32" stroke-width="0.2" stroke-miterlimit="10" d="
M10.185,10.881c-0.286,0.004-0.573-0.001-0.859,0.002c-0.336,0.004-0.285-0.057-0.293,0.293c-0.002,0.085,0.026,0.121,0.121,0.117
c0.171-0.005,0.344-0.001,0.516-0.001c0.114,0,0.229,0,0.343,0c0.311,0,0.307,0,0.306-0.29
C10.317,10.904,10.279,10.88,10.185,10.881z"/>
</g>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#292D32" d="M11.44,18.417c0.163-0.045,0.294-0.12,0.412-0.238
c0.635-0.638,1.272-1.273,1.909-1.909l0.994-0.991c0.065-0.066,0.133-0.133,0.192-0.204c0.322-0.387,0.44-0.824,0.352-1.302
c-0.116-0.635-0.482-1.053-1.087-1.242c-0.605-0.197-1.16-0.057-1.626,0.404c-1.017,1.007-2.028,2.02-3.038,3.034
c-0.079,0.08-0.139,0.172-0.165,0.252c-0.229,0.729-0.454,1.468-0.669,2.197c-0.078,0.264,0.037,0.485,0.305,0.592
c0.017,0.008,0.029,0.015,0.04,0.022h0.181l0.698-0.196C10.438,18.695,10.938,18.555,11.44,18.417z M13.166,13.677
c0.199-0.244,0.434-0.341,0.704-0.28c0.266,0.058,0.445,0.232,0.506,0.493c0.063,0.28-0.032,0.529-0.278,0.721l-0.069,0.054
l-0.92-0.917L13.166,13.677z M9.899,17.718c0.025-0.086,0.052-0.169,0.077-0.25c0.055-0.175,0.107-0.341,0.147-0.508
c0.058-0.242,0.182-0.449,0.39-0.651c0.469-0.454,0.937-0.925,1.391-1.38l0.332-0.333c0.017-0.017,0.031-0.044,0.044-0.067
l0.084-0.143l0.983,0.985l-0.958,0.954c-0.361,0.361-0.722,0.723-1.086,1.08c-0.068,0.067-0.163,0.122-0.267,0.153
c-0.254,0.076-0.51,0.146-0.777,0.219l-0.411,0.113L9.899,17.718z"/>
</svg>

Before

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -1,30 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<g>
<path fill="none" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" d="M22,10v5c0,5-2,7-7,7H9
c-5,0-7-2-7-7V9c0-5,2-7,7-7h5"/>
<path fill="none" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" d="M22,10h-4c-3,0-4-1-4-4
V2L22,10z"/>
</g>
</g>
<path fill-rule="evenodd" clip-rule="evenodd" fill="none" d="M18.222,10.122c0.04,0.369-0.322,0.697-0.678,0.69
c-0.387-0.007-0.678-0.299-0.688-0.686c-0.012-0.395,0.335-0.697,0.689-0.698C17.898,9.427,18.26,9.751,18.222,10.122z"/>
<g>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#292D32" d="M4.771,16.07c0.08-0.275,0.207-0.523,0.481-0.641
c0.151-0.066,0.324-0.107,0.488-0.109c0.696-0.012,1.393-0.008,2.088-0.004c0.616,0.002,1.01,0.426,0.954,1.014
c-0.036,0.375-0.367,0.742-0.744,0.754c-0.803,0.023-1.608,0.031-2.411,0.012c-0.446-0.012-0.705-0.26-0.833-0.693
c-0.005-0.018-0.016-0.033-0.024-0.049C4.771,16.258,4.771,16.164,4.771,16.07z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#292D32" d="M19.229,16.354c-0.08,0.273-0.207,0.523-0.48,0.641
c-0.15,0.064-0.324,0.105-0.488,0.109c-0.695,0.012-1.393,0.008-2.088,0.004c-0.615-0.004-1.01-0.428-0.953-1.016
c0.035-0.373,0.367-0.742,0.742-0.752c0.803-0.025,1.607-0.031,2.412-0.012c0.445,0.012,0.703,0.26,0.832,0.691
c0.006,0.018,0.016,0.033,0.023,0.051C19.229,16.164,19.229,16.258,19.229,16.354z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#292D32" d="M12.011,17.092c-0.414,0-0.829,0.02-1.241-0.006
c-0.443-0.025-0.776-0.422-0.777-0.871c-0.001-0.451,0.333-0.834,0.771-0.883c0.093-0.01,0.188-0.018,0.281-0.016
c0.729,0.004,1.458-0.008,2.186,0.021c0.443,0.016,0.775,0.42,0.777,0.871c0.002,0.449-0.332,0.832-0.771,0.883
c-0.041,0.004-0.082,0.014-0.125,0.014C12.744,17.107,12.377,17.092,12.011,17.092C12.011,17.088,12.011,17.098,12.011,17.092z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -1,166 +0,0 @@
<?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="app-icon2.svg"
inkscape:export-filename="K:\Programming\PDF\PDF_For_Qt\PdfForQt\PdfForQtViewer\resources\app-icon.png"
inkscape:export-xdpi="108.37334"
inkscape:export-ydpi="108.37334">
<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="5.6568541"
inkscape:cx="192.57793"
inkscape:cy="53.941207"
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)">
<g
id="g879"
style="fill:#000000;fill-opacity:1;stroke:none">
<g
aria-label=" 🕮 "
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:25.39999962px;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"
id="text869">
<path
d="m 28.674223,287.71878 -10.889258,-0.81855 q -0.595313,0.32246 -1.16582,0.49609 -0.570508,0.16123 -1.103809,0.16123 -0.545703,0 -1.178223,-0.16123 -0.620117,-0.17363 -1.32705,-0.49609 l -10.9636721,0.81855 v -17.23926 l 2.3192382,-0.13642 0.8929688,-1.74873 q 1.4634765,-0.38448 2.7657226,-0.57051 1.3146484,-0.19844 2.4556645,-0.19844 1.984374,0 3.100585,0.5209 1.128614,0.5085 1.773536,1.72393 0.58291,-1.19063 1.761132,-1.71153 1.178223,-0.5333 3.237012,-0.5333 1.054199,0 2.306836,0.19844 1.265039,0.18603 2.740918,0.57051 l 0.843359,1.6123 2.43086,0.13643 z m -0.620118,-0.65732 V 270.8888 l -1.525488,-0.0868 0.607715,1.00459 v 14.23789 l -9.934277,-0.62011 q -0.719336,0.60771 -1.835547,0.60771 -1.103809,0 -1.810742,-0.60771 l -9.9838869,0.62011 v -14.23789 l 0.4588868,-0.88056 -1.3766602,0.0744 v 16.06104 L 13.2085,286.28011 q 0.620117,0.33486 1.190625,0.50849 0.570508,0.16124 1.103809,0.16124 0.496093,0 1.016992,-0.16124 0.520898,-0.17363 1.079004,-0.50849 z M 4.1919963,271.9306 v 12.93564 l 1.2154297,-2.36885 v -12.79921 z m 21.1087887,-2.18282 v 12.74961 l 1.227832,2.30684 v -12.73721 z m -20.6374996,15.67657 9.0661136,-0.71934 q 0.396875,0.5085 1.32705,0.71934 -0.173633,-1.5627 -1.215429,-2.23242 -1.029395,-0.68213 -3.249414,-0.68213 -1.0293949,0 -2.2200199,0.14882 -1.1782226,0.13643 -2.5176757,0.42168 z m 21.4932616,0 -1.190625,-2.30684 q -1.438672,-0.31006 -2.678906,-0.45889 -1.227832,-0.14882 -2.244825,-0.14882 -4.378027,0 -4.378027,2.91455 0.917774,-0.14883 1.401465,-0.73174 z M 6.0275432,282.41058 q 1.4386718,-0.26045 2.5424804,-0.38448 1.1162109,-0.12402 1.8975584,-0.12402 3.187402,0 4.588867,1.53789 v -11.54658 q 0,-1.73633 -1.079004,-2.59209 -1.079003,-0.86816 -3.249414,-0.86816 -1.1162105,0 -2.2944332,0.16123 -1.1658203,0.14882 -2.4060546,0.45888 z M 24.69307,269.02845 q -1.364258,-0.29766 -2.517676,-0.44649 -1.153417,-0.14882 -2.095996,-0.14882 -2.294433,0 -3.472656,0.94257 -0.942578,0.74414 -0.942578,2.54248 v 11.57139 q 0.855762,-0.90537 1.823145,-1.24023 0.967382,-0.34727 2.666503,-0.34727 1.128614,0 2.257227,0.13643 1.141016,0.12402 2.282031,0.39687 z"
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
id="path881"
inkscape:connector-curvature="0" />
</g>
</g>
<rect
style="fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:1;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
id="rect871"
width="20.207552"
height="6.4161458"
x="5.4239583"
y="289.4263"
rx="3"
ry="3" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.64444447px;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"
x="9.9549494"
y="294.58566"
id="text875"><tspan
sodipodi:role="line"
id="tspan873"
x="9.9549494"
y="294.58566"
style="stroke-width:0.26458332">PDF</tspan></text>
<path
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.66813242;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
d="M 56.035606,61.117383 C 50.91089,56.733484 43.254928,55.395935 31.463645,56.824492 c -2.056179,0.249114 -6.774539,0.972122 -8.087535,1.239275 l -0.574524,0.116899 V 32.992057 7.8034451 L 25.409043,7.242608 c 3.696941,-0.7951744 8.084305,-1.3978883 11.918094,-1.6372476 9.65059,-0.6025263 15.757263,1.613886 18.149934,6.5875026 1.334247,2.773485 1.279091,1.563328 1.22525,26.883248 l -0.048,22.570551 z"
id="path884"
inkscape:connector-curvature="0"
transform="matrix(0.26458333,0,0,0.26458333,0,267)" />
<path
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.66813242;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
d="m 59.264755,39.016347 c 0.06771,-25.638618 0.002,-24.247605 1.27408,-26.963048 1.507681,-3.2183137 4.763884,-5.1976409 10.169237,-6.1815105 2.269207,-0.4130355 7.948482,-0.4089749 11.578874,0.00828 2.659095,0.3056192 6.219363,0.8791726 9.192389,1.4808792 l 1.59099,0.3219984 0.0448,25.2267639 c 0.02615,14.725326 -0.02094,25.226763 -0.113123,25.226763 -0.08686,0 -0.914735,-0.155721 -1.839728,-0.346045 -6.002472,-1.235056 -13.413018,-1.814882 -18.32761,-1.434013 -5.780071,0.447941 -8.737326,1.535854 -12.210146,4.491855 l -1.420607,1.209197 z"
id="path886"
inkscape:connector-curvature="0"
transform="matrix(0.26458333,0,0,0.26458333,0,267)" />
<path
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.66813242;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
d="m 97.88685,62.625306 -2.254543,-4.261612 0.04483,-23.797741 0.04483,-23.797741 2.254541,4.249114 2.254542,4.249115 -0.0448,23.810238 -0.0448,23.81024 z"
id="path888"
inkscape:connector-curvature="0"
transform="matrix(0.26458333,0,0,0.26458333,0,267)" />
<path
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.66813242;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
d="M 10.073664,45.487643 V 15.232137 l 1.458408,-0.113531 c 0.802124,-0.06244 1.916615,-0.114007 2.476647,-0.114589 l 1.01824,-0.0011 -0.797269,1.587458 -0.797269,1.587458 v 26.966903 26.966902 l 1.104854,-0.101905 c 1.671828,-0.154198 35.112801,-2.204923 35.965197,-2.205519 0.542668,-3.53e-4 0.966994,0.151031 1.576986,0.56271 1.527676,1.031015 2.908364,1.42384 5.33338,1.517413 1.338085,0.05163 2.59438,0.0014 3.270369,-0.130944 1.020449,-0.199678 2.932623,-1.014794 4.052038,-1.727289 0.458527,-0.291846 1.26745,-0.256538 18.473166,0.806312 9.896504,0.611338 18.331729,1.156072 18.744939,1.210521 l 0.75131,0.099 v -26.98039 -26.98043 l -1.15599,-1.870168 -1.15599,-1.870168 2.17246,0.111581 c 1.19484,0.06137 2.43098,0.151689 2.74697,0.20071 l 0.57453,0.08913 v 30.397582 30.397583 h -0.65417 c -0.35979,0 -9.209677,-0.644636 -19.66641,-1.432525 L 66.55382,72.772317 65.669936,73.25911 c -2.749991,1.51454 -5.144838,2.116392 -7.849377,1.972637 -2.232484,-0.118665 -3.894293,-0.559839 -6.212813,-1.649367 l -1.687822,-0.79315 -13.338198,0.986753 c -7.336009,0.542715 -16.042882,1.183594 -19.348606,1.424178 -3.305724,0.240583 -6.268944,0.461176 -6.584932,0.490206 l -0.574524,0.05278 z"
id="path890"
inkscape:connector-curvature="0"
transform="matrix(0.26458333,0,0,0.26458333,0,267)" />
<path
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.66813242;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
d="m 59.336921,68.454611 c 0.12295,-1.300105 0.795473,-3.376604 1.407689,-4.346416 1.897407,-3.005688 5.748663,-4.724909 11.819618,-5.276342 4.731191,-0.429739 13.178874,0.353388 20.420929,1.893086 l 1.329045,0.282561 2.173883,4.221341 2.173881,4.22134 h -0.568057 c -0.312434,0 -8.001434,-0.600063 -17.086669,-1.333472 l -16.51861,-1.333473 -0.795265,0.733049 c -0.876147,0.807605 -2.642456,1.685923 -3.744942,1.862218 l -0.709604,0.11347 z"
id="path892"
inkscape:connector-curvature="0"
transform="matrix(0.26458333,0,0,0.26458333,0,267)" />
<path
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.66813242;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
d="m 20.003644,65.144177 2.150869,-4.306003 1.163226,-0.220184 c 7.376688,-1.39631 11.160101,-1.820365 16.366022,-1.834347 2.42412,-0.0065 4.672595,0.07924 5.568466,0.212362 5.948092,0.883867 9.192177,2.997409 10.683939,6.960655 0.463033,1.230168 0.911577,3.27064 0.753673,3.428544 -0.125213,0.125212 -1.745147,-0.3958 -2.660544,-0.855699 -0.374268,-0.188032 -1.010788,-0.646339 -1.41449,-1.018458 l -0.734003,-0.67658 -16.351569,1.303192 C 26.53587,68.854414 18.879564,69.44295 18.51522,69.445516 l -0.662445,0.0047 z"
id="path894"
inkscape:connector-curvature="0"
transform="matrix(0.26458333,0,0,0.26458333,0,267)" />
<path
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.66813242;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
d="m 15.907956,42.889326 -6.61e-4,-24.17437 2.165514,-3.986795 2.165515,-3.986795 0.04483,23.904042 0.04483,23.904043 -1.886401,3.726792 c -1.037521,2.049737 -2.03188,3.965441 -2.209686,4.257122 -0.314207,0.515439 -0.323304,-0.148501 -0.323946,-23.644039 z"
id="path896"
inkscape:connector-curvature="0"
transform="matrix(0.26458333,0,0,0.26458333,0,267)" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -1,58 +0,0 @@
<?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"
version="1.1"
id="svg815"
width="1365.3333"
height="1365.3333"
viewBox="0 0 1365.3333 1365.3333"
sodipodi:docname="book.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
<metadata
id="metadata821">
<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>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs819" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="3840"
inkscape:window-height="2035"
id="namedview817"
showgrid="false"
inkscape:zoom="0.45523454"
inkscape:cx="880.27588"
inkscape:cy="385.67768"
inkscape:window-x="-13"
inkscape:window-y="-13"
inkscape:window-maximized="1"
inkscape:current-layer="svg815" />
<path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:30;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 887.59475,1160.8501 c -26.72293,-4.0778 -27.50822,-4.2448 -77.05227,-16.3894 -48.09016,-11.7882 -196.39813,-46.9068 -301.20433,-71.3237 -106.07404,-24.7123 -137.27126,-32.3054 -139.65725,-33.9911 -3.21806,-2.2737 -3.21806,-809.20503 0,-811.59417 1.20394,-0.89381 38.04455,-4.92282 81.86804,-8.95333 43.82347,-4.03051 126.17309,-11.64043 182.99915,-16.91094 56.82604,-5.27053 111.98847,-10.34685 122.58316,-11.28073 10.59469,-0.93387 37.78187,-3.47985 60.41599,-5.65771 94.77189,-9.11896 119.49401,-6.7052 126.46206,12.34721 0.5538,1.51429 8.2568,1.35807 34.7535,-0.70479 47.1547,-3.67119 58.6644,-0.23726 64.6106,19.2766 3.9606,12.99754 2.3716,896.49356 -1.6252,903.63406 -9.6844,17.3014 -21.1351,18.8127 -64.0542,8.4541 -25.1514,-6.0702 -26.9312,-5.6226 -30.4856,7.6657 -6.709,25.0816 -21.24683,31.2827 -59.61365,25.4282 z m 36.22316,-3.2615 c 6.65343,-2.2976 12.46235,-7.4482 16.50639,-14.6356 3.2838,-5.8364 3.3546,-15.8167 3.3204,-468.0456 -0.035,-462.08203 -0.035,-462.08203 4.9744,-462.08203 9.6565,0 71.2038,6.58602 72.5069,7.75879 0.7241,0.65167 1.1181,200.09696 0.8756,443.21175 -0.441,442.02679 -0.441,442.02679 -10.0725,444.88809 -5.2973,1.5738 -18.2999,5.3116 -28.8946,8.3064 -10.5947,2.9946 -17.6454,5.4778 -15.6682,5.518 1.9772,0.041 11.0395,1.8552 20.1386,4.0333 29.7304,7.1168 42.0003,4.5955 50.2725,-10.3304 6.2539,-11.2841 5.3576,-892.01758 -0.9193,-903.38593 -8.5899,-15.55744 -25.121,-17.49667 -87.0962,-10.2171 -6.7471,0.79252 -7.1851,0.55907 -11.90982,-6.34756 -8.49596,-12.41953 -15.69162,-14.45015 -46.52305,-13.12887 -21.63231,0.92708 -142.48884,11.56393 -328.57966,28.91904 -23.11568,2.1558 -73.94391,6.81748 -112.95163,10.35926 -39.0077,3.5418 -72.69618,6.79807 -74.86327,7.23619 -3.94018,0.79655 -3.94018,0.79655 -3.94018,404.3953 0,403.59867 0,403.59867 13.57171,406.90217 7.46443,1.8169 65.58199,15.489 129.15011,30.3823 63.56813,14.8933 166.40665,39.0981 228.53004,53.7884 62.12339,14.6904 116.49778,27.3407 120.83197,28.1118 32.845,5.8441 52.38469,7.2475 60.73979,4.3623 z M 940.6552,314.97342 c 0,-4.82808 0.3283,-6.80321 0.7295,-4.38918 0.4012,2.41405 0.4012,6.36431 0,8.77836 -0.4012,2.41404 -0.7295,0.43891 -0.7295,-4.38918 z m -0.2863,-95.28622 c -0.7603,-11.19845 -4.35924,-19.82119 -11.2515,-26.95761 -4.51508,-4.67502 -5.86665,-6.84122 -3.56932,-5.72064 9.6955,4.72923 18.03712,21.64789 15.87632,32.20067 -0.7301,3.56537 -0.8424,3.61621 -1.0555,0.47758 z m 94.3257,-3.39909 c 0,-1.02161 -2.9552,-4.87549 -6.567,-8.56417 -5.0016,-5.10801 -5.4543,-5.96514 -1.899,-3.59574 5.2126,3.47396 11.125,11.59388 9.5122,13.06385 -0.5755,0.52445 -1.0462,0.11767 -1.0462,-0.90394 z m -99.61463,-3.73121 c -0.11177,-1.46442 -0.65666,-3.97822 -1.21097,-5.58623 -0.95523,-2.77111 -0.9034,-2.7753 0.99342,-0.0804 1.10068,1.5638 1.64559,4.0776 1.21095,5.58623 -0.71194,2.4711 -0.81039,2.47908 -0.9934,0.0804 z m 69.40663,894.1216 c 12.6961,-3.5607 12.6961,-3.5607 12.6961,-443.91874 0,-375.36082 -0.3601,-440.35801 -2.4398,-440.35801 -3.8276,0 -51.9783,-4.63118 -59.2896,-5.70254 -6.567,-0.96229 -6.567,-0.96229 -6.567,452.26057 0,453.22292 0,453.22292 21.4521,447.25122 11.7986,-3.2845 27.1653,-7.5741 34.1482,-9.5325 z"
id="path825"
inkscape:connector-curvature="0" />
</svg>

Before

Width:  |  Height:  |  Size: 4.8 KiB

View File

@@ -1,75 +0,0 @@
<?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"
version="1.1"
id="svg815"
width="512"
height="512"
viewBox="0 0 512 512"
sodipodi:docname="bookmark-next.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
<metadata
id="metadata821">
<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 />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs819" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="3840"
inkscape:window-height="2035"
id="namedview817"
showgrid="false"
inkscape:zoom="2.4279174"
inkscape:cx="137.55859"
inkscape:cy="137.21551"
inkscape:window-x="-13"
inkscape:window-y="-13"
inkscape:window-maximized="1"
inkscape:current-layer="svg815" />
<path
sodipodi:type="star"
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:26.45669291;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
id="path839"
sodipodi:sides="5"
sodipodi:cx="259.20364"
sodipodi:cy="269.65189"
sodipodi:r1="203.30641"
sodipodi:r2="101.65321"
sodipodi:arg1="-1.585122"
sodipodi:arg2="-0.95680346"
inkscape:flatsided="false"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 256.29124,66.366336 61.47844,120.198874 133.87003,17.49813 -95.31804,95.61296 24.7264,132.72518 L 260.65984,371.29467 142.07158,435.82522 162.9856,302.44616 64.967615,209.60305 198.28142,188.27708 Z"
inkscape:transform-center-x="0.89998123"
inkscape:transform-center-y="-18.55611" />
<path
inkscape:connector-curvature="0"
style="fill:none;stroke:#000000;stroke-width:31.68950462;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 220.58404,237.11509 v 70.93287 c 0,14.53213 13.81864,23.63982 24.86768,16.38716 l 26.95074,-17.71983 26.95662,-17.78679 c 11.03729,-7.24597 11.03729,-25.42788 0,-32.68725 l -26.95662,-17.7734 -26.95074,-17.72652 c -11.04904,-7.27945 -24.86768,1.76127 -24.86768,16.37376 z"
id="path1701" />
</svg>

Before

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -1,75 +0,0 @@
<?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"
version="1.1"
id="svg815"
width="512"
height="512"
viewBox="0 0 512 512"
sodipodi:docname="bookmark-previous.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
<metadata
id="metadata821">
<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 />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs819" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="3840"
inkscape:window-height="2035"
id="namedview817"
showgrid="false"
inkscape:zoom="0.21459961"
inkscape:cx="-2504.7782"
inkscape:cy="317.10796"
inkscape:window-x="-13"
inkscape:window-y="-13"
inkscape:window-maximized="1"
inkscape:current-layer="svg815" />
<path
sodipodi:type="star"
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:26.45669291;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
id="path839"
sodipodi:sides="5"
sodipodi:cx="259.20364"
sodipodi:cy="269.65189"
sodipodi:r1="203.30641"
sodipodi:r2="101.65321"
sodipodi:arg1="-1.585122"
sodipodi:arg2="-0.95680346"
inkscape:flatsided="false"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 256.29124,66.366336 61.47844,120.198874 133.87003,17.49813 -95.31804,95.61296 24.7264,132.72518 L 260.65984,371.29467 142.07158,435.82522 162.9856,302.44616 64.967615,209.60305 198.28142,188.27708 Z"
inkscape:transform-center-x="0.89998123"
inkscape:transform-center-y="-18.55611" />
<path
inkscape:connector-curvature="0"
style="fill:none;stroke:#000000;stroke-width:31.68950462;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 292.61298,235.87946 v 70.93287 c 0,14.53213 -13.81864,23.63982 -24.86768,16.38716 l -26.95074,-17.71983 -26.95662,-17.78679 c -11.03729,-7.24597 -11.03729,-25.42788 0,-32.68725 l 26.95662,-17.7734 26.95074,-17.72652 c 11.04904,-7.27945 24.86768,1.76127 24.86768,16.37376 z"
id="path1701" />
</svg>

Before

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -1,70 +0,0 @@
<?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"
version="1.1"
id="svg815"
width="512"
height="512"
viewBox="0 0 512 512"
sodipodi:docname="sidebar-favourites.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
<metadata
id="metadata821">
<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>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs819" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="3840"
inkscape:window-height="2035"
id="namedview817"
showgrid="false"
inkscape:zoom="1.2139587"
inkscape:cx="535.31725"
inkscape:cy="132.65123"
inkscape:window-x="-13"
inkscape:window-y="-13"
inkscape:window-maximized="1"
inkscape:current-layer="svg815" />
<path
sodipodi:type="star"
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:26.45669291;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
id="path839"
sodipodi:sides="5"
sodipodi:cx="259.20364"
sodipodi:cy="269.65189"
sodipodi:r1="203.30641"
sodipodi:r2="101.65321"
sodipodi:arg1="-1.585122"
sodipodi:arg2="-0.95680346"
inkscape:flatsided="false"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 256.29124,66.366336 61.47844,120.198874 133.87003,17.49813 -95.31804,95.61296 24.7264,132.72518 L 260.65984,371.29467 142.07158,435.82522 162.9856,302.44616 64.967615,209.60305 198.28142,188.27708 Z"
inkscape:transform-center-x="0.89998123"
inkscape:transform-center-y="-18.55611" />
</svg>

Before

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -1,58 +0,0 @@
<?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"
version="1.1"
id="svg815"
width="512"
height="512"
viewBox="0 0 512 512"
sodipodi:docname="bubble.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
<metadata
id="metadata821">
<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 />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs819" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="3840"
inkscape:window-height="2035"
id="namedview817"
showgrid="false"
inkscape:zoom="3.4335938"
inkscape:cx="150.86235"
inkscape:cy="256"
inkscape:window-x="-13"
inkscape:window-y="-13"
inkscape:window-maximized="1"
inkscape:current-layer="svg815" />
<path
style="fill:#000000;stroke-width:12;stroke:#000000;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
d="m 123.75,430.79874 c -1.89158,-0.83496 -2.99805,-2.07362 -4.0049,-4.48334 -0.72128,-1.72628 -0.72276,-2.33532 -0.0163,-6.7317 0.42719,-2.65853 1.20779,-7.7587 1.73467,-11.3337 0.52688,-3.575 1.98151,-13.1375 3.23251,-21.25 1.251,-8.1125 3.05693,-20.36244 4.01318,-27.22208 l 1.73864,-12.47208 -4.40969,-6.52792 C 115.27198,324.84023 107.54774,309.75923 103.10358,296 c -6.25381,-19.36193 -8.066965,-29.81667 -8.45466,-48.75 -0.336065,-16.41179 0.88088,-29.37875 3.91823,-41.75 5.98814,-24.38995 17.17364,-46.76015 32.84264,-65.68295 5.0251,-6.0686 15.79673,-17.0453 21.14297,-21.54549 5.07023,-4.26785 16.86135,-12.5361 23.11796,-16.21093 18.74709,-11.01114 41.75064,-18.834225 62.59842,-21.28858 8.46167,-0.99617 26.90797,-1.016235 35.23392,-0.03835 45.2291,5.312295 87.05443,30.28592 113.99148,68.06356 13.18538,18.49172 22.80239,40.31706 27.2316,61.80081 6.6758,32.38074 2.73273,68.87128 -10.71408,99.15193 -12.77959,28.77816 -33.52708,53.61451 -58.51206,70.04345 -22.11027,14.53867 -43.57104,22.67606 -70,26.54226 -8.71057,1.27424 -30.12062,1.27404 -38.75,-3.6e-4 -13.58803,-2.00671 -26.36472,-5.52709 -39.63815,-10.92159 -4.89192,-1.98813 -8.98733,-3.37666 -9.44328,-3.2017 -0.94968,0.36443 -33.47182,22.15481 -46.41857,31.10123 -4.95,3.42053 -9.83479,6.66185 -10.85508,7.20293 -2.13439,1.1319 -4.49345,1.2322 -6.64492,0.28252 z M 151.28045,399.625 c 8.40229,-5.70625 18.35773,-12.48195 22.12321,-15.0571 12.81859,-8.76643 13.61635,-8.98482 20.4656,-5.60258 12.20829,6.02859 29.60537,11.35241 43.44875,13.2961 7.01506,0.98495 29.69754,1.13786 36.93199,0.24897 10.2186,-1.25555 23.1936,-4.53936 33.52657,-8.48515 5.26643,-2.01106 17.91766,-8.22219 22.97343,-11.27882 6.52901,-3.94732 15.89889,-10.84538 15.26437,-11.23754 -0.38193,-0.23604 -0.18756,-0.60966 0.58079,-1.11639 0.63516,-0.41889 3.40484,-2.85437 6.15484,-5.41217 2.75,-2.55781 6.27445,-5.71147 7.83209,-7.00813 8.60011,-7.15914 20.6777,-23.84493 27.66617,-38.22219 3.23461,-6.65451 8.58328,-20.09247 8.99568,-22.6007 0.64481,-3.92172 1.26965,-6.76993 2.28141,-10.3993 3.03127,-10.87379 4.83812,-27.81403 4.27301,-40.0619 -1.19421,-25.8822 -9.98436,-53.09135 -24.1081,-74.62456 C 365.97447,141.1523 352.64378,127.34519 334.43043,115.18618 327.79221,110.75459 317.21366,105.03773 310.5,102.2537 297.9373,97.04419 283.66999,93.43631 270,92.01218 c -6.11697,-0.63726 -22.38304,-0.63726 -28.5,0 -26.9942,2.81224 -52.03234,12.96726 -74,30.01307 -6.39422,4.9616 -18.15774,16.53065 -23.36093,22.97475 -15.70185,19.44656 -27.74239,44.71965 -32.86574,68.98514 -4.21743,19.97477 -3.79255,46.85768 0.98014,62.01486 0.64943,2.0625 1.55336,5.55 2.00871,7.75 3.03898,14.68243 13.01727,34.76904 25.41296,51.15704 2.01474,2.66363 3.92454,5.33442 4.24401,5.93509 1.25775,2.36486 0.89087,5.80329 -4.9518,46.40787 -1.66195,11.55 -3.13716,21.39375 -3.27823,21.875 -0.14108,0.48125 -0.12804,0.875 0.029,0.875 0.15701,0 7.16007,-4.66875 15.56235,-10.375 z"
id="path825"
inkscape:connector-curvature="0" />
</svg>

Before

Width:  |  Height:  |  Size: 4.5 KiB

View File

@@ -1,39 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="56.689px" height="56.689px" viewBox="0 0 56.689 56.689" enable-background="new 0 0 56.689 56.689" xml:space="preserve">
<g>
<g>
<path fill="#FF9518" d="M2.398,41.912l9.121-30.292c0.273-0.911,1.268-1.648,2.22-1.648h29.556c0.951,0,1.938,0.739,2.203,1.653
l8.797,30.287"/>
<path fill="#231F20" d="M54.775,41.769l-0.96,0.279l-8.8-30.29c-0.2-0.699-0.99-1.29-1.721-1.29h-29.56
c-0.729,0-1.53,0.591-1.74,1.29l-7.88,26.17l-1.239,4.131l-0.96-0.29l9.13-30.29c0.33-1.13,1.521-2.011,2.689-2.011h29.561
c1.181,0,2.351,0.891,2.681,2.021L54.775,41.769z"/>
</g>
<g>
<path fill="#FFEACE" d="M53.796,41.909c0,2.381-1.931,4.312-4.311,4.312H7.205c-2.369,0-4.31-1.931-4.31-4.312
c0-2.369,1.939-4.31,4.31-4.31h42.28C51.865,37.599,53.796,39.54,53.796,41.909z"/>
<path fill="#231F20" d="M49.485,36.599H7.205c-1.1,0-2.119,0.34-2.96,0.908c-1.42,0.961-2.35,2.57-2.35,4.4
c0,2.93,2.38,5.311,5.31,5.311h42.28c2.931,0,5.311-2.381,5.311-5.311C54.796,38.989,52.416,36.599,49.485,36.599z M49.485,46.719
H7.205c-2.648,0-4.81-2.149-4.81-4.811c0-1.85,1.05-3.46,2.59-4.26c0.46-0.25,0.97-0.42,1.5-0.49c0.24-0.039,0.479-0.06,0.72-0.06
h42.28c1.33,0,2.53,0.54,3.399,1.408c0.87,0.871,1.41,2.07,1.41,3.4C54.296,44.569,52.145,46.719,49.485,46.719z"/>
</g>
<path fill="#D9EACE" stroke="#231F20" stroke-miterlimit="10" d="M47.773,41.912c0,0.813,0.658,1.471,1.471,1.471l0,0
c0.813,0,1.471-0.658,1.471-1.471l0,0c0-0.813-0.657-1.471-1.471-1.471l0,0C48.431,40.441,47.773,41.098,47.773,41.912
L47.773,41.912z"/>
<path fill="#D9EACE" stroke="#231F20" stroke-miterlimit="10" d="M33.873,41.984c0,1.517,0.982,2.745,2.193,2.745h6.756
c1.213,0,2.195-1.229,2.195-2.745l0,0c0-1.518-0.982-2.745-2.195-2.745h-6.756C34.855,39.239,33.873,40.468,33.873,41.984
L33.873,41.984z"/>
<g>
<path fill="#DE9518" d="M15.296,10.469L8.535,36.599h-1.33c-1.1,0-2.119,0.34-2.96,0.908l7.75-25.749
c0.21-0.699,1.011-1.29,1.74-1.29H15.296z"/>
</g>
<path fill="#231F20" d="M52.885,38.509c-0.869-0.868-2.069-1.408-3.399-1.408H7.205c-0.239,0-0.479,0.021-0.72,0.06
c-0.53,0.07-1.04,0.24-1.5,0.49c-1.54,0.8-2.59,2.41-2.59,4.26c0,2.66,2.16,4.812,4.81,4.812h42.28c2.66,0,4.811-2.15,4.811-4.812
C54.296,40.579,53.756,39.38,52.885,38.509z M49.485,46.219H7.205c-2.369,0-4.31-1.93-4.31-4.311c0-2.369,1.939-4.31,4.31-4.31
h42.28c2.38,0,4.311,1.939,4.311,4.31C53.796,44.29,51.865,46.219,49.485,46.219z"/>
<path fill="#D9EACE" d="M7.275,46.219h-0.07c-2.369,0-4.31-1.93-4.31-4.311c0-2.369,1.939-4.31,4.31-4.31h0.841
C7.065,38.249,2.995,41.419,7.275,46.219z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -1,80 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<path fill="#292D32" stroke="#292D32" stroke-width="0.2" stroke-miterlimit="10" d="M11.987,14.505
c-2.647,0.009-4.82-2.152-4.828-4.801c-0.01-2.663,2.153-4.833,4.818-4.837c2.656-0.003,4.824,2.144,4.828,4.8
C16.82,12.329,14.656,14.501,11.987,14.505z M11.958,13.266c1.961,0.02,3.586-1.575,3.61-3.538
c0.023-1.964-1.566-3.599-3.525-3.622C10.048,6.084,8.42,7.665,8.396,9.641C8.374,11.625,9.969,13.245,11.958,13.266z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#292D32" stroke="#292D32" stroke-width="0.3" stroke-miterlimit="10" d="
M11.287,10.553c0.721-0.681,1.413-1.333,2.104-1.987c0.166-0.156,0.33-0.314,0.498-0.468c0.189-0.174,0.41-0.183,0.561-0.027
c0.154,0.158,0.137,0.374-0.057,0.556c-0.932,0.881-1.865,1.761-2.798,2.638c-0.21,0.198-0.409,0.193-0.612-0.013
c-0.476-0.483-0.947-0.97-1.42-1.456c-0.114-0.118-0.2-0.259-0.12-0.413c0.052-0.1,0.161-0.193,0.266-0.234
c0.155-0.061,0.281,0.042,0.389,0.153c0.357,0.368,0.715,0.735,1.071,1.104C11.208,10.446,11.24,10.494,11.287,10.553z"/>
<g>
<path fill="#292D32" d="M19.605,9.754c-0.025-0.07-0.025-0.168,0-0.247c0.203-0.596,0.377-1.082,0.547-1.53
c0.059-0.156,0.033-0.271-0.094-0.396c-0.373-0.355-0.76-0.74-1.154-1.142c-0.055-0.055-0.098-0.137-0.105-0.201
c-0.061-0.479-0.125-1.045-0.172-1.618c-0.014-0.186-0.094-0.285-0.275-0.341c-0.48-0.159-0.99-0.329-1.498-0.511
c-0.084-0.031-0.174-0.104-0.223-0.179c-0.316-0.489-0.615-0.986-0.84-1.365C15.703,2.08,15.607,2.03,15.426,2.05
c-0.547,0.076-1.096,0.138-1.66,0.202c-0.047,0.006-0.107-0.002-0.107-0.002c-0.52-0.337-1.043-0.679-1.563-1.02L12.07,1.213
h-0.144L11.9,1.23c-0.095,0.063-0.192,0.125-0.289,0.187c-0.218,0.139-0.444,0.283-0.65,0.449
c-0.426,0.35-0.866,0.451-1.398,0.315c-0.216-0.054-0.44-0.074-0.657-0.093C8.787,2.077,8.668,2.066,8.551,2.05
c-0.189-0.027-0.276,0.073-0.33,0.161C7.979,2.619,7.688,3.1,7.379,3.575C7.321,3.662,7.218,3.743,7.123,3.778
C6.622,3.967,6.108,4.138,5.627,4.294C5.459,4.349,5.388,4.442,5.371,4.625c-0.047,0.58-0.112,1.143-0.169,1.616
C5.193,6.31,5.15,6.393,5.098,6.445c-0.34,0.347-0.719,0.722-1.158,1.148c-0.091,0.089-0.165,0.198-0.092,0.39
c0.201,0.532,0.384,1.046,0.545,1.528c0.025,0.075,0.026,0.177,0,0.247c-0.167,0.499-0.349,1.007-0.541,1.511
c-0.065,0.172-0.039,0.297,0.095,0.432c0.348,0.325,0.712,0.683,1.146,1.126c0.057,0.058,0.102,0.147,0.108,0.224
c0.067,0.547,0.126,1.098,0.174,1.636c0.015,0.151,0.08,0.234,0.229,0.289c0.175,0.056,0.349,0.114,0.527,0.175
c0.088,0.03,0.177,0.061,0.268,0.091l0.872,0.238l0.547,0.922l0.003,0.011c0.13,0.209,0.26,0.416,0.376,0.622
c0.078,0.132,0.174,0.191,0.313,0.191c0.021,0,0.043-0.002,0.069-0.005c0.497-0.066,0.995-0.128,1.493-0.188l0.045-0.007
c0.063-0.008,0.134-0.011,0.196-0.004l0.005-0.002l0.016,0.009c0.036,0.006,0.076,0.011,0.09,0.03c0.003,0.004-0.002-0.004,0,0
l1.556,0.89c0,0-0.005,0.023-0.012,0.052c0.083,0.009,0.164-0.012,0.241-0.052l1.364-0.884c0.002-0.002,0-0.008,0.002-0.01
c0.014-0.017,0.037-0.026,0.064-0.032v-0.001l0,0c0.027-0.006,0.057-0.007,0.076-0.007c0.025,0,0.053,0.001,0.082,0.005
c0.24,0.022,0.482,0.054,0.725,0.084c0.141,0.017,0.279,0.034,0.418,0.051c0.061,0.006,0.125,0.019,0.188,0.031
c0.178,0.034,0.367,0.054,0.494,0.003l1.182-2.006h0.961c0.188-0.069,0.363-0.135,0.547-0.182c0.254-0.065,0.305-0.23,0.32-0.402
c0.039-0.53,0.102-1.061,0.166-1.557c0.006-0.073,0.051-0.161,0.107-0.22c0.355-0.366,0.725-0.73,1.131-1.111
c0.146-0.138,0.178-0.273,0.104-0.468C19.967,10.791,19.793,10.304,19.605,9.754z M18.111,9.891
c0.086,0.221,0.166,0.447,0.248,0.672c0.059,0.162,0.115,0.324,0.176,0.484c0.031,0.078,0.025,0.107-0.033,0.16
c-0.281,0.266-0.58,0.56-0.914,0.9c-0.092,0.098-0.154,0.23-0.17,0.354c-0.059,0.406-0.105,0.836-0.139,1.277
c-0.006,0.084-0.027,0.106-0.117,0.138c-0.396,0.13-0.807,0.265-1.211,0.418c-0.117,0.043-0.229,0.132-0.293,0.231
c-0.258,0.392-0.475,0.743-0.664,1.073c-0.063,0.112-0.129,0.104-0.215,0.096c-0.443-0.064-0.846-0.114-1.232-0.152l-0.033-0.001
c-0.109,0-0.236,0.033-0.352,0.095c-0.316,0.191-0.658,0.409-1.049,0.668c-0.049,0.032-0.083,0.047-0.112,0.047
c-0.018,0-0.048-0.004-0.105-0.043c-0.328-0.222-0.682-0.446-1.076-0.685c-0.065-0.044-0.138-0.065-0.186-0.079
c-0.013-0.004-0.023-0.007-0.031-0.011l-0.023-0.009l-0.438,0.054c-0.315,0.038-0.613,0.074-0.915,0.116
c-0.097,0.016-0.161,0.021-0.231-0.098c-0.192-0.34-0.408-0.693-0.661-1.081c-0.059-0.091-0.159-0.17-0.278-0.22
c-0.426-0.157-0.822-0.292-1.208-0.414c-0.096-0.033-0.122-0.054-0.128-0.153c-0.035-0.444-0.08-0.854-0.136-1.251
c-0.017-0.132-0.088-0.272-0.195-0.386c-0.271-0.289-0.559-0.563-0.836-0.828l-0.061-0.058c-0.057-0.058-0.059-0.083-0.033-0.146
l0.029-0.077c0.135-0.362,0.274-0.736,0.393-1.112C5.929,9.734,5.928,9.549,5.88,9.4C5.751,8.992,5.597,8.581,5.464,8.235
C5.436,8.155,5.441,8.13,5.499,8.075C5.86,7.731,6.151,7.445,6.411,7.176c0.087-0.086,0.156-0.218,0.173-0.338
c0.053-0.401,0.1-0.831,0.143-1.314C6.733,5.455,6.748,5.438,6.82,5.415C7.19,5.293,7.619,5.15,8.033,4.998
c0.125-0.046,0.251-0.147,0.322-0.256c0.249-0.377,0.48-0.763,0.673-1.089c0.054-0.09,0.088-0.08,0.149-0.072
c0.479,0.066,0.916,0.118,1.334,0.158c0.095,0.008,0.21-0.021,0.309-0.079c0.356-0.22,0.724-0.447,1.079-0.691
c0.054-0.036,0.084-0.04,0.102-0.04c0.03,0,0.065,0.014,0.113,0.046c0.354,0.236,0.717,0.467,1.08,0.688
c0.074,0.048,0.184,0.076,0.291,0.076l0.041-0.001c0.486-0.051,0.916-0.102,1.309-0.156c0.055-0.007,0.086-0.021,0.133,0.061
c0.207,0.353,0.434,0.729,0.68,1.09c0.074,0.113,0.203,0.215,0.336,0.267c0.211,0.079,0.422,0.15,0.631,0.221
c0.191,0.065,0.383,0.13,0.572,0.2c0.031,0.011,0.078,0.069,0.08,0.099c0.033,0.233,0.057,0.466,0.082,0.698
c0.023,0.211,0.045,0.421,0.072,0.628c0.012,0.11,0.076,0.236,0.162,0.321c0.311,0.32,0.623,0.628,0.928,0.915
c0.055,0.053,0.059,0.073,0.031,0.141C18.475,8.4,18.41,8.58,18.346,8.759c-0.078,0.216-0.156,0.432-0.236,0.643
C18.045,9.564,18.047,9.719,18.111,9.891z"/>
</g>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#292D32" d="M14.105,22.69c0.283,0,0.5-0.146,0.641-0.435
c0.209-0.434,0.42-0.868,0.629-1.303l0.426-0.881c0.031-0.064,0.064-0.127,0.1-0.196l0.084-0.159l0.078,0.021
c0.701,0.196,1.398,0.388,2.094,0.579l0.17,0.047c0.051,0.015,0.104,0.029,0.156,0.045c0.074,0.022,0.15,0.045,0.225,0.063
c0.084,0.021,0.164,0.03,0.238,0.03c0.205,0,0.369-0.077,0.504-0.235c0.191-0.222,0.223-0.478,0.098-0.76
c-0.275-0.615-0.553-1.229-0.832-1.844c-0.133-0.296-0.285-0.62-0.441-0.955c-0.301-0.65-0.613-1.322-0.859-1.908l-1.152,0.738
l0.547,1.245c0.264,0.584,0.527,1.17,0.799,1.773l0.084,0.187l-0.199-0.049c-0.041-0.01-0.074-0.017-0.102-0.022
c-0.033-0.008-0.061-0.014-0.086-0.021l-1.369-0.376c-0.527-0.146-0.777-0.032-1.018,0.466l-0.49,1.01
c-0.063,0.13-0.125,0.26-0.213,0.438l-0.094,0.19l-1.525-3.376l-0.826,0.324l-0.825-0.324l-1.527,3.376l-0.093-0.19
c-0.087-0.178-0.15-0.308-0.213-0.438l-0.49-1.009c-0.24-0.498-0.492-0.61-1.017-0.466l-1.371,0.377
c-0.024,0.007-0.05,0.013-0.085,0.021c-0.027,0.006-0.06,0.013-0.101,0.022l-0.199,0.049l0.084-0.187
c0.271-0.604,0.535-1.189,0.8-1.774l0.655-1.438l-1.362-0.281c-0.224,0.534-0.477,1.064-0.722,1.578
c-0.162,0.34-0.324,0.68-0.479,1.021c-0.278,0.615-0.556,1.229-0.831,1.844c-0.126,0.282-0.094,0.538,0.096,0.759
c0.185,0.217,0.429,0.285,0.742,0.206c0.076-0.019,0.151-0.041,0.227-0.063c0.052-0.016,0.104-0.03,0.156-0.045l0.17-0.047
c0.695-0.191,1.392-0.383,2.093-0.579l0.078-0.021l0.083,0.159c0.036,0.069,0.069,0.133,0.1,0.197l0.425,0.88
c0.21,0.435,0.419,0.869,0.63,1.303c0.141,0.288,0.356,0.435,0.641,0.435c0.299-0.006,0.511-0.154,0.647-0.441
c0.023-0.048,0.044-0.094,0.065-0.14l1.623-3.59l1.623,3.59c0.021,0.046,0.043,0.092,0.064,0.139
c0.137,0.288,0.35,0.437,0.631,0.442l0.018,0.098l0,0V22.69z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 8.0 KiB

View File

@@ -1,29 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="23.693px" height="23.693px" viewBox="0 0 23.693 23.693" enable-background="new 0 0 23.693 23.693" xml:space="preserve">
<g>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#292D32" d="M13.472,11.669c-0.259,0-0.498,0-0.748,0
c-0.014,0.076-0.025,0.136-0.037,0.194c-0.098,0.54-0.514,0.781-1.03,0.602c-0.233-0.081-0.406-0.433-0.4-0.815
c0.005-0.395,0.18-0.725,0.423-0.8c0.029-0.009,0.061-0.014,0.092-0.014c0.562-0.001,1.123-0.001,1.701-0.001
C13.472,11.11,13.472,11.371,13.472,11.669z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#292D32" d="M19.456,21.147c0-6.753,0-13.484,0-20.231
c-0.121,0-0.217,0-0.312,0c-2.31,0-4.617,0.002-6.926-0.003c-0.149,0-0.303-0.025-0.445-0.067
c-0.534-0.159-1.064-0.328-1.628-0.504c0,0.207,0,0.387,0,0.581c-1.982,0-3.938,0-5.89,0C4.244,0.96,4.23,0.982,4.23,1.005
C4.229,1.726,4.229,2.448,4.228,3.17l0,0V18c-0.003,0.032-0.006,0.067-0.006,0.104c0.009,0.926,0.004,1.853,0.004,2.778
c0,0.086,0,0.169,0,0.279c-0.582,0-1.129,0-1.673,0c0,0.295,0,0.561,0,0.85c2.538,0,5.059,0,7.604,0c0,0.456,0,0.892,0,1.34
c1.852-0.346,3.683-0.675,5.505-1.032c1.045-0.204,2.087-0.368,3.157-0.319c0.686,0.031,1.373,0.005,2.063,0.005
c0.084,0,0.167,0,0.26,0c0-0.299,0-0.566,0-0.857C20.575,21.147,20.028,21.147,19.456,21.147z M10.135,21.141
c-1.128,0-2.235,0-3.379,0c0-0.848,0-1.691,0-2.533c0-1.087,0-2.169,0-3.252V6.721C6.758,6.72,6.76,6.719,6.762,6.718
c0-1.079,0-2.16,0-3.253c1.143,0,2.256,0,3.373,0C10.135,9.366,10.135,15.256,10.135,21.141z M10.137,2.611
c-1.409,0-2.803,0-4.211,0c0,0.576,0,1.145,0,1.71l0,0v13.737c-0.002,0.931,0,1.858,0,2.789c0,0.095,0,0.188,0,0.295
c-0.294,0-0.563,0-0.847,0c0-0.741,0-1.48,0-2.216c0-0.63,0-1.26,0-1.888V5.111c0.002,0.001,0.002,0.002,0.006,0.004
c0-1.167,0-2.25,0-3.341c1.694,0,3.367,0,5.052,0C10.137,2.053,10.137,2.319,10.137,2.611z M16.922,21.021c0,0.063,0,0.126,0,0.211
c-1.972,0.368-3.927,0.733-5.904,1.103c0-6.951,0-13.883,0-20.839c0.669,0.208,1.321,0.412,1.975,0.616
c1.242,0.386,2.482,0.774,3.727,1.155c0.158,0.048,0.207,0.116,0.207,0.281C16.922,9.372,16.923,15.196,16.922,21.021z
M18.607,21.144c-0.283,0-0.543,0-0.834,0c0-0.11,0-0.213,0-0.313c0-5.943-0.001-11.888,0.007-17.832
c0-0.227-0.069-0.31-0.28-0.372c-0.811-0.238-1.615-0.498-2.421-0.75c-0.06-0.019-0.116-0.04-0.172-0.093c1.227,0,2.454,0,3.7,0
C18.607,8.231,18.607,14.675,18.607,21.144z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -1,35 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="56.689px" height="56.689px" viewBox="0 0 56.689 56.689" enable-background="new 0 0 56.689 56.689" xml:space="preserve">
<g>
<g>
<g>
<path fill="#FFEACE" stroke="#231F20" stroke-miterlimit="10" d="M4.688,38.748c-0.666,0-1.205,0.539-1.205,1.204v7.564
c0,0.665,0.539,1.204,1.205,1.204H43.51c0.665,0,1.205-0.539,1.205-1.204v-7.564c0-0.665-0.54-1.204-1.205-1.204H4.688z"/>
</g>
<g>
<path fill="#9266FF" stroke="#231F20" stroke-miterlimit="10" d="M9.188,27.766c-0.639-0.19-1.31,0.173-1.497,0.81l-2.154,7.251
c-0.188,0.638,0.174,1.309,0.813,1.498l37.215,11.052c0.638,0.189,1.309-0.174,1.498-0.812l2.152-7.251
c0.188-0.639-0.174-1.31-0.813-1.499L9.188,27.766z"/>
</g>
<g>
<path fill="#9D724C" stroke="#231F20" stroke-miterlimit="10" d="M16.013,19.144c-0.565-0.352-1.308-0.178-1.659,0.388
l-3.987,6.428c-0.35,0.565-0.177,1.31,0.388,1.659l32.989,20.467c0.565,0.352,1.307,0.177,1.658-0.391l3.988-6.427
c0.35-0.565,0.177-1.309-0.389-1.658L16.013,19.144z"/>
</g>
<g>
<path fill="#FF9518" stroke="#231F20" stroke-miterlimit="10" d="M33.503,8.106l-6.709,3.496
c-0.59,0.309-0.819,1.036-0.512,1.625l17.944,34.426c0.308,0.59,1.032,0.82,1.624,0.513l6.709-3.497
c0.589-0.308,0.817-1.033,0.512-1.624L35.126,8.616C34.819,8.028,34.092,7.799,33.503,8.106z"/>
</g>
</g>
<path fill="#DE9518" stroke="#231F20" stroke-miterlimit="10" d="M45.556,42.779c0,0.943,0.765,1.709,1.709,1.709l0,0
c0.942,0,1.708-0.766,1.708-1.709l0,0c0-0.943-0.767-1.708-1.708-1.708l0,0C46.321,41.071,45.556,41.835,45.556,42.779
L45.556,42.779z"/>
<polygon fill="#697041" points="30.596,28.811 39.393,39.452 35.378,31.733 "/>
<polygon fill="#7D3BF5" points="11.065,28.874 41.018,46.936 34.831,43.139 12.487,29.264 "/>
<polygon fill="#D9EACE" points="6.284,39.264 41.253,48.16 11.065,39.264 "/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -1,125 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<g>
<path fill="#292D32" d="M4.31,4.444C3.611,4.437,2.912,4.438,2.215,4.445C1.799,4.449,1.47,4.758,1.464,5.148
c-0.011,0.737-0.01,1.475-0.001,2.214C1.47,7.736,1.785,8.046,2.181,8.066l0.04,0.001c0.363,0,0.673-0.26,0.739-0.62
C2.979,7.343,2.98,7.233,2.98,7.127V5.967h0.731h0l0.586-0.002c0.438-0.004,0.764-0.314,0.775-0.736
c0.004-0.214-0.069-0.411-0.208-0.555C4.725,4.529,4.529,4.446,4.31,4.444z"/>
<path fill="#292D32" d="M4.286,21.03H2.979l0.001-0.357c0.001-0.328,0.002-0.655-0.004-0.986c-0.008-0.437-0.322-0.76-0.755-0.76
c-0.423,0-0.756,0.321-0.76,0.735c-0.007,0.718-0.007,1.429,0,2.151c0.004,0.403,0.322,0.72,0.727,0.725
c0.339,0.004,0.678,0.006,1.017,0.006c0.384,0,0.769-0.002,1.154-0.006c0.4-0.008,0.706-0.323,0.713-0.733
c0.004-0.215-0.068-0.409-0.202-0.544C4.725,21.109,4.523,21.032,4.286,21.03z"/>
<path fill="#292D32" d="M7.712,4.445c-0.357-0.012-0.715-0.013-1.075,0C6.205,4.464,5.89,4.806,5.908,5.238
c0.016,0.409,0.334,0.714,0.756,0.725l0.213,0.003l0.305-0.001l0.292,0.001l0.201-0.002c0.435-0.009,0.762-0.317,0.778-0.73
c0.008-0.201-0.062-0.395-0.198-0.541C8.117,4.542,7.923,4.454,7.712,4.445z"/>
<path fill="#292D32" d="M2.978,12.992c-0.02-0.446-0.338-0.767-0.771-0.767c-0.429,0.008-0.743,0.338-0.749,0.789
c-0.003,0.323-0.003,0.642,0,0.964c0.004,0.456,0.31,0.783,0.741,0.794h0.018c0.433,0,0.746-0.323,0.761-0.779
c0.004-0.111,0.003-0.223,0.002-0.334v-0.146l0.001-0.157C2.981,13.234,2.981,13.114,2.978,12.992z"/>
<path fill="#292D32" d="M1.458,10.686c0.015,0.423,0.322,0.74,0.731,0.752h0.029c0.406,0,0.729-0.296,0.75-0.69
c0.02-0.384,0.02-0.774,0-1.159C2.961,9.491,2.938,9.4,2.897,9.316C2.782,9.08,2.535,8.919,2.232,8.905
c-0.018-0.001-0.034-0.007-0.05-0.007c0,0-0.001,0-0.002,0C1.781,8.918,1.476,9.229,1.458,9.635
c-0.004,0.121-0.002,0.24-0.001,0.362l0.001,0.153L1.457,10.31C1.456,10.436,1.455,10.562,1.458,10.686z"/>
<path fill="#292D32" d="M2.176,18.095l0.044,0.001c0.414,0,0.736-0.313,0.752-0.727c0.016-0.363,0.016-0.729,0-1.097
c-0.019-0.408-0.342-0.719-0.777-0.719c-0.413,0.012-0.722,0.328-0.737,0.748c-0.004,0.121-0.003,0.243-0.002,0.365l0.001,0.151
l-0.001,0.148c0,0.124-0.001,0.244,0.002,0.366C1.469,17.755,1.771,18.074,2.176,18.095z"/>
<path fill="#292D32" d="M11.039,21.032c-0.352-0.009-0.708-0.009-1.065,0c-0.419,0.01-0.737,0.33-0.741,0.748
c0,0.003,0,0.006,0,0.01c0,0.002,0,0.003,0,0.005c0,0.063,0.021,0.118,0.035,0.177c0.01,0.031,0.009,0.07,0.022,0.103
c0.108,0.271,0.367,0.456,0.684,0.473c0.071,0.002,0.141,0.004,0.212,0.004h0.009c0.002,0,0.004,0,0.005,0l0.311-0.002
l0.327,0.002c0.071,0,0.142-0.002,0.211-0.006c0.4-0.019,0.699-0.324,0.72-0.716c0.002-0.016,0.012-0.024,0.012-0.044
C11.778,21.376,11.457,21.043,11.039,21.032z"/>
<path fill="#292D32" d="M7.723,21.034c-0.363-0.013-0.725-0.013-1.089,0c-0.422,0.011-0.734,0.34-0.726,0.76
c0.003,0.41,0.308,0.722,0.72,0.746c0.066,0.002,0.135,0.004,0.203,0.004l0.902-0.004c0.409-0.025,0.71-0.338,0.721-0.735
c0.005-0.208-0.069-0.401-0.207-0.542C8.109,21.118,7.922,21.038,7.723,21.034z"/>
<path fill="#292D32" d="M14.375,21.032c-0.364-0.011-0.727-0.011-1.086,0.002c-0.307,0.006-0.563,0.198-0.673,0.469
c-0.026,0.064-0.033,0.136-0.043,0.207c-0.002,0.021-0.012,0.04-0.013,0.062c0,0.002,0.001,0.005,0.001,0.007
c0,0.013-0.006,0.022-0.006,0.033c0.012,0.399,0.312,0.71,0.72,0.737l0.906,0.002c0.064,0,0.136,0,0.201-0.004
c0.411-0.02,0.718-0.331,0.721-0.742v-0.002c0-0.002,0-0.002,0-0.002C15.114,21.379,14.792,21.043,14.375,21.032z"/>
<path fill="#292D32" d="M16.713,5.973l0.586,0.002h0.004h0.729v1.161c0,0.105,0.002,0.216,0.021,0.32
c0.065,0.36,0.374,0.62,0.739,0.62l0.039-0.001c0.394-0.02,0.71-0.331,0.715-0.706c0.012-0.739,0.012-1.475,0-2.213
c-0.005-0.39-0.335-0.699-0.752-0.702c-0.693-0.008-1.394-0.01-2.093,0c-0.219,0.002-0.413,0.084-0.555,0.228
c-0.138,0.144-0.213,0.341-0.209,0.555C15.947,5.66,16.274,5.968,16.713,5.973z"/>
<path fill="#292D32" d="M18.788,18.935c-0.433,0.006-0.747,0.326-0.754,0.764c-0.01,0.327-0.008,0.653-0.004,0.981v0.357h-1.307
c-0.235,0.002-0.438,0.08-0.584,0.232c-0.137,0.136-0.206,0.33-0.202,0.544c0.007,0.409,0.313,0.727,0.713,0.731
c0.386,0.004,0.769,0.006,1.154,0.006c0.336,0,0.678-0.002,1.018-0.004c0.404-0.005,0.721-0.327,0.722-0.727
c0.013-0.717,0.013-1.434,0-2.151C19.544,19.257,19.211,18.935,18.788,18.935z"/>
<path fill="#292D32" d="M10,5.973l0.218,0.002l0.298-0.001l0.298,0.001c0.074,0,0.146,0,0.218-0.003
c0.409-0.014,0.721-0.311,0.747-0.708c0-0.004-0.004-0.007-0.004-0.013c0,0,0,0,0-0.001c0.004-0.021-0.007-0.041-0.007-0.063
c-0.004-0.079-0.01-0.159-0.031-0.231c-0.031-0.096-0.084-0.185-0.15-0.26c-0.135-0.147-0.317-0.233-0.515-0.243
c-0.377-0.018-0.76-0.021-1.139,0c-0.198,0.012-0.38,0.096-0.508,0.241c-0.136,0.152-0.203,0.35-0.19,0.563
c0.006,0.1,0.031,0.193,0.07,0.277C9.422,5.79,9.682,5.964,10,5.973z"/>
<path fill="#292D32" d="M14.375,4.453c-0.36-0.012-0.718-0.012-1.072,0c-0.214,0.008-0.408,0.097-0.544,0.248
c-0.136,0.147-0.209,0.34-0.201,0.541c0.019,0.414,0.345,0.72,0.779,0.73l0.203,0.002l0.293-0.001l0.302,0.001l0.215-0.003
c0.42-0.011,0.739-0.318,0.756-0.726C15.12,4.812,14.808,4.471,14.375,4.453z"/>
<path fill="#292D32" d="M18.034,13.997c0.018,0.458,0.329,0.778,0.76,0.778h0.02c0.433-0.007,0.734-0.333,0.741-0.789
c0.003-0.323,0.003-0.643,0-0.964c-0.007-0.452-0.32-0.781-0.748-0.789c-0.436-0.002-0.753,0.32-0.772,0.766
c-0.005,0.121-0.005,0.241-0.002,0.363v0.155v0.145C18.029,13.774,18.027,13.887,18.034,13.997z"/>
<path fill="#292D32" d="M19.557,10.006c0-0.122,0.001-0.243-0.002-0.364c-0.02-0.406-0.324-0.717-0.721-0.738h-0.002
c-0.019,0-0.033,0.008-0.054,0.009c-0.299,0.015-0.549,0.175-0.666,0.41c-0.038,0.084-0.06,0.176-0.067,0.272
c-0.02,0.385-0.02,0.774,0,1.158c0.021,0.395,0.344,0.694,0.749,0.694h0.03c0.409-0.015,0.717-0.331,0.73-0.755
c0.003-0.123,0.002-0.25,0.002-0.375l-0.002-0.159L19.557,10.006z"/>
<path fill="#292D32" d="M19.555,16.312c-0.018-0.424-0.326-0.739-0.737-0.751c-0.435,0-0.76,0.309-0.777,0.72
c-0.018,0.367-0.018,0.731,0,1.1c0.019,0.411,0.34,0.726,0.754,0.726l0.044-0.002c0.408-0.02,0.708-0.34,0.72-0.76
c0.002-0.126,0.002-0.248,0.002-0.37l-0.002-0.146l0.002-0.149C19.557,16.55,19.558,16.43,19.555,16.312z"/>
</g>
<g>
<path fill="#292D32" d="M7.604,15.028H5.609l-0.289,0.7H4.247l1.826-4.476h1.075l1.827,4.476H7.891L7.604,15.028z M7.27,14.214
l-0.665-1.636l-0.664,1.636H7.27z"/>
<path fill="#292D32" d="M13.102,14.046c0,1.033-0.65,1.766-1.55,1.766c-0.473,0-0.86-0.203-1.128-0.556v0.473H9.471v-4.552h0.953
v1.655c0.269-0.346,0.656-0.546,1.128-0.546C12.451,12.286,13.102,13.015,13.102,14.046z M12.176,14.046
c0-0.561-0.37-0.958-0.899-0.958c-0.464,0-0.802,0.339-0.853,0.826v0.262c0.051,0.493,0.389,0.835,0.853,0.835
C11.806,15.01,12.176,14.612,12.176,14.046z"/>
<path fill="#292D32" d="M13.581,14.046c0-0.958,0.847-1.76,1.847-1.76c0.544,0,0.995,0.221,1.321,0.571l-0.633,0.542
c-0.17-0.189-0.437-0.312-0.697-0.312c-0.494,0-0.916,0.438-0.916,0.951c0,0.525,0.422,0.972,0.925,0.972
c0.262,0,0.531-0.129,0.71-0.327l0.63,0.532c-0.334,0.367-0.786,0.596-1.349,0.596C14.423,15.812,13.581,14.999,13.581,14.046z"/>
</g>
<circle fill="#292D32" cx="18.763" cy="5.209" r="3.751"/>
</g>
<g>
<g>
<path fill="#292D32" d="M18.616,3.558v0.666c0,0.555-0.223,0.777-0.777,0.777h-0.668c-0.555,0-0.775-0.223-0.775-0.777V3.558
c0-0.557,0.221-0.778,0.775-0.778h0.668C18.394,2.779,18.616,3.002,18.616,3.558z"/>
<path fill="#FFFFFF" d="M17.839,5.12h-0.668c-0.619,0-0.895-0.276-0.895-0.896V3.558c0-0.62,0.275-0.897,0.895-0.897h0.668
c0.619,0,0.896,0.277,0.896,0.897v0.666C18.735,4.844,18.458,5.12,17.839,5.12z M17.171,2.898c-0.49,0-0.656,0.167-0.656,0.659
v0.666c0,0.492,0.164,0.658,0.656,0.658h0.668c0.492,0,0.658-0.166,0.658-0.658V3.558c0-0.492-0.166-0.659-0.658-0.659H17.171
L17.171,2.898z"/>
</g>
<g>
<path fill="#292D32" d="M21.13,6.194V6.86c0,0.556-0.223,0.778-0.777,0.778h-0.668c-0.555,0-0.775-0.223-0.775-0.778V6.194
c0-0.555,0.221-0.777,0.775-0.777h0.668C20.907,5.417,21.13,5.64,21.13,6.194z"/>
<path fill="#FFFFFF" d="M20.353,7.758h-0.668c-0.619,0-0.895-0.277-0.895-0.897V6.194c0-0.62,0.275-0.896,0.895-0.896h0.668
c0.619,0,0.896,0.276,0.896,0.896V6.86C21.249,7.48,20.972,7.758,20.353,7.758z M19.685,5.536c-0.49,0-0.656,0.166-0.656,0.658
V6.86c0,0.492,0.164,0.66,0.656,0.66l0.668-0.001c0.492,0,0.658-0.166,0.658-0.659V6.194c0-0.492-0.166-0.659-0.658-0.659
L19.685,5.536z"/>
</g>
<g>
<g>
<path fill="#FFFFFF" d="M20.614,6.157h-1.189c-0.066,0-0.119-0.053-0.119-0.118s0.053-0.119,0.119-0.119h1.189
c0.066,0,0.119,0.054,0.119,0.119S20.681,6.157,20.614,6.157z"/>
</g>
<g>
<path fill="#FFFFFF" d="M20.614,6.646h-1.189c-0.066,0-0.119-0.053-0.119-0.119c0-0.064,0.053-0.118,0.119-0.118h1.189
c0.066,0,0.119,0.054,0.119,0.118C20.733,6.594,20.681,6.646,20.614,6.646z"/>
</g>
<g>
<path fill="#FFFFFF" d="M20.614,7.136h-1.189c-0.066,0-0.119-0.053-0.119-0.119c0-0.065,0.053-0.119,0.119-0.119h1.189
c0.066,0,0.119,0.054,0.119,0.119C20.733,7.083,20.681,7.136,20.614,7.136z"/>
</g>
</g>
<g>
<g>
<path fill="#FFFFFF" d="M20.007,5.083c-0.027-0.002-0.055-0.013-0.074-0.032l-0.387-0.379c-0.045-0.043-0.045-0.114-0.002-0.158
c0.045-0.044,0.115-0.045,0.16-0.002l0.305,0.301l0.301-0.307c0.043-0.044,0.113-0.045,0.158-0.001
c0.045,0.043,0.045,0.113,0.002,0.158L20.091,5.05c-0.021,0.021-0.049,0.032-0.08,0.033C20.011,5.083,20.009,5.083,20.007,5.083z
"/>
</g>
</g>
<g>
<path fill="#FFFFFF" d="M20.132,4.865l-0.25-0.056c0-0.003,0.068-0.329-0.115-0.556c-0.127-0.155-0.348-0.235-0.658-0.235V3.762
c0.393,0.001,0.682,0.113,0.859,0.333C20.228,4.418,20.136,4.847,20.132,4.865z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 9.9 KiB

View File

@@ -1,58 +0,0 @@
<?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"
version="1.1"
id="svg4518"
width="1024"
height="1024"
viewBox="0 0 1024 1024"
sodipodi:docname="create-bitonal-document.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
<metadata
id="metadata4524">
<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>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs4522" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="3840"
inkscape:window-height="2035"
id="namedview4520"
showgrid="false"
inkscape:zoom="0.60697936"
inkscape:cx="-446.16507"
inkscape:cy="382.76742"
inkscape:window-x="-13"
inkscape:window-y="-13"
inkscape:window-maximized="1"
inkscape:current-layer="svg4518" />
<path
style="fill:#000000"
d="M 275,840.34984 C 239.39425,836.75303 210.93791,812.8012 200.68906,777.80196 198.55083,770.5 198.55083,770.5 198.26782,555 197.98481,339.5 197.98481,339.5 244.79539,292.5 270.54121,266.65 294.58068,242.6875 298.21644,239.25 304.82689,233 304.82689,233 439.41345,233 574,233 574,233 574,221.46788 c 0,-16.44964 3.6815,-23.54063 14.00146,-26.96836 7.72363,-2.56538 166.06628,-1.78035 170.88594,0.84721 8.98764,4.89986 12.06104,11.45552 12.09064,25.78973 0.022,10.63645 0.022,10.63645 4.27196,11.27967 22.89593,3.46521 48.18401,25.82601 56.14594,49.64663 4.76595,14.25883 4.67352,8.89106 4.38132,254.43724 -0.27726,233 -0.27726,233 -2.52142,241 -8.4023,29.95265 -31.42147,52.75955 -61.25584,60.69096 -8.5,2.25971 -8.5,2.25971 -251,2.38607 -133.375,0.0695 -244.075,-0.0327 -246,-0.22719 z m 490,-33.00821 c 17.35762,-4.79398 29.59742,-17.00765 37.37332,-37.29353 2.45292,-6.39921 3.99366,-453.89194 1.61667,-469.5481 -2.19986,-14.48955 -11.11357,-27.00001 -23.80071,-33.40445 C 770.66408,262.28724 771,261.9069 771,277.5 c 0,13.5 0,13.5 2.50822,13.5 3.73544,0 3.51498,470.65192 -0.22373,477.64255 -2.80216,5.23949 -9.12708,10.69411 -14.14293,12.19689 -7.53442,2.25737 -482.68052,1.55749 -487.64156,-0.71828 -4.8754,-2.23649 -8.98945,-6.26636 -11.85053,-11.60805 C 257.5,764.5 257.5,764.5 257,611.82303 c -0.5,-152.67696 -0.5,-152.67696 -2.60453,-155.5 -6.68903,-8.97271 -19.53324,-8.87451 -23.83093,0.1822 -2.88554,6.08083 -1.86962,307.89446 1.06214,315.54287 9.47687,24.72341 24.94287,35.64473 52.37332,36.98343 31.24799,1.525 475.00462,-0.034 481,-1.6899 z M 549.50613,723.48462 C 608.29522,716.62845 656.6189,689.18053 711.59979,631.41516 732.35953,609.60405 733.33491,607.60888 726.75,600.42502 723.5,596.8794 723.5,596.8794 689,596.29093 644.2412,595.52747 647.84972,594.56637 628.66971,612.35947 609.134,630.48256 596.22209,639.42823 578.0973,647.39723 532.63362,667.38645 474.23364,660.41077 448.62945,631.93275 443.99057,626.7732 436,615.4135 436,613.97823 c 0,-0.43662 10.76768,-0.94784 23.92819,-1.13604 26.87027,-0.38426 27.63895,-0.58383 31.40218,-8.15256 3.58151,-7.20326 4.07279,-6.58299 -40.68105,-51.36331 -45.57366,-45.60064 -44.92894,-45.0974 -53.07665,-41.42973 -2.79718,1.25915 -17.00264,14.63777 -45.35847,42.71836 C 310.92841,595.5 310.92841,595.5 310.9642,599.79966 311.06369,611.7495 314.27432,613 344.85582,613 c 24.05355,0 24.05355,0 24.68861,3.75 11.84266,69.93128 91.32462,117.07174 179.9617,106.73462 z M 646,537.43405 c 1.375,-0.70689 20.56475,-19.43124 42.64389,-41.60966 43.1112,-43.30505 42.94206,-43.09292 39.99159,-50.15438 C 726.01639,439.40165 724.11249,439 697.01828,439 c -18.40336,0 -24.16717,-0.29472 -24.44633,-1.25 -9.26076,-31.69033 -18.68029,-48.38717 -36.78802,-65.2096 C 592.55321,332.3782 529.03396,319.07899 464.12597,336.59985 411.6213,350.77263 366.32483,384.72873 314.85436,448.5 300.0098,466.89222 299,468.53606 299,474.30906 c 0,11.09459 3.46247,11.98038 45,11.51218 36.66276,-0.41325 30.61063,2.50744 59.45867,-28.69406 C 432.87399,425.31213 454.76264,409.35438 481,400.59627 521.997,386.91134 567.04829,394.54425 592.5745,419.5 598.55894,425.3507 607,436.44042 607,438.45196 607,438.75338 596.17765,439 582.95034,439 c -27.05976,0 -28.96721,0.4028 -31.58582,6.67001 -3.18128,7.61388 -6.48857,3.63459 54.90397,66.05974 29.31079,29.80378 30.39419,30.50468 39.73151,25.7043 z M 315.53668,388.3328 c 7.07205,-2.40969 13.91868,-9.53856 15.27685,-15.90662 0.57488,-2.69541 0.9427,-5.00328 0.81738,-5.1286 -0.17754,-0.17754 -93.38778,-0.48534 -100.88091,-0.33313 -1.56316,0.0317 -1.75,1.26338 -1.75,11.53555 0,11.5 0,11.5 40.82186,11.5 35.48238,0 41.46186,-0.21807 45.71482,-1.6672 z M 722.42901,343.20507 C 740,324.91015 740,324.91015 740,274.95507 740,225 740,225 704.5,225 669,225 669,225 669,275.50741 c 0,50.50741 0,50.50741 16.75,68.49574 9.2125,9.89358 17.28055,17.87774 17.92901,17.74259 0.64845,-0.13516 9.08595,-8.47846 18.75,-18.54067 z M 303.08795,311.75 c 0.0484,-12.7875 0.28877,-25.3875 0.53421,-28 0.28494,-3.03296 0.0525,-4.75 -0.64315,-4.75 -0.59917,0 -13.77706,12.58712 -29.2842,27.97138 C 245.5,334.94277 245.5,334.94277 274.25,334.97138 303,335 303,335 303.08795,311.75 Z m 334.9119,-51.91821 c 8e-5,-17.41752 0.27329,-32.38002 0.60714,-33.25 C 639.14591,225.17739 637.29548,225 622.10699,225 605,225 605,225 605,232.95078 c 0,15.23051 -3.66246,23.69246 -12.2366,28.27206 C 588.5,263.5 588.5,263.5 461.89019,263.76495 c -126.60982,0.26496 -126.60982,0.26496 -127.31515,13.24008 -0.38794,7.13632 -0.39208,13.48198 -0.009,14.10148 0.5128,0.82972 40.55932,1.02984 152.065,0.75992 C 637.9997,291.5 637.9997,291.5 637.99985,259.83179 Z"
id="path4528"
inkscape:connector-curvature="0" />
</svg>

Before

Width:  |  Height:  |  Size: 6.1 KiB

View File

@@ -1,87 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<g>
<path fill="#292D32" d="M4.31,4.444C3.611,4.437,2.912,4.438,2.215,4.445C1.799,4.449,1.47,4.758,1.464,5.148
c-0.011,0.737-0.01,1.475-0.001,2.214C1.47,7.736,1.785,8.046,2.181,8.066l0.04,0.001c0.363,0,0.673-0.26,0.739-0.62
C2.979,7.343,2.98,7.233,2.98,7.127V5.967h0.731h0l0.586-0.002c0.438-0.004,0.764-0.314,0.775-0.736
c0.004-0.214-0.069-0.411-0.208-0.555C4.725,4.529,4.529,4.446,4.31,4.444z"/>
<path fill="#292D32" d="M4.286,21.03H2.979l0.001-0.357c0.001-0.328,0.002-0.655-0.004-0.986c-0.008-0.437-0.322-0.76-0.755-0.76
c-0.423,0-0.756,0.321-0.76,0.735c-0.007,0.718-0.007,1.429,0,2.151c0.004,0.403,0.322,0.72,0.727,0.725
c0.339,0.004,0.678,0.006,1.017,0.006c0.384,0,0.769-0.002,1.154-0.006c0.4-0.008,0.706-0.323,0.713-0.733
c0.004-0.215-0.068-0.409-0.202-0.544C4.725,21.109,4.523,21.032,4.286,21.03z"/>
<path fill="#292D32" d="M7.712,4.445c-0.357-0.012-0.715-0.013-1.075,0C6.205,4.464,5.89,4.806,5.908,5.238
c0.016,0.409,0.334,0.714,0.756,0.725l0.213,0.003l0.305-0.001l0.292,0.001l0.201-0.002c0.435-0.009,0.762-0.317,0.778-0.73
c0.008-0.201-0.062-0.395-0.198-0.541C8.117,4.542,7.923,4.454,7.712,4.445z"/>
<path fill="#292D32" d="M2.978,12.992c-0.02-0.446-0.338-0.767-0.771-0.767c-0.429,0.008-0.743,0.338-0.749,0.789
c-0.003,0.323-0.003,0.642,0,0.964c0.004,0.456,0.31,0.783,0.741,0.794h0.018c0.433,0,0.746-0.323,0.761-0.779
c0.004-0.111,0.003-0.223,0.002-0.334v-0.146l0.001-0.157C2.981,13.234,2.981,13.114,2.978,12.992z"/>
<path fill="#292D32" d="M1.458,10.686c0.015,0.423,0.322,0.74,0.731,0.752h0.029c0.406,0,0.729-0.296,0.75-0.69
c0.02-0.384,0.02-0.774,0-1.159C2.961,9.491,2.938,9.4,2.897,9.316C2.782,9.08,2.535,8.919,2.232,8.905
c-0.018-0.001-0.034-0.007-0.05-0.007c0,0-0.001,0-0.002,0C1.781,8.918,1.476,9.229,1.458,9.635
c-0.004,0.121-0.002,0.24-0.001,0.362l0.001,0.153L1.457,10.31C1.456,10.436,1.455,10.562,1.458,10.686z"/>
<path fill="#292D32" d="M2.176,18.095l0.044,0.001c0.414,0,0.736-0.313,0.752-0.727c0.016-0.363,0.016-0.729,0-1.097
c-0.019-0.408-0.342-0.719-0.777-0.719c-0.413,0.012-0.722,0.328-0.737,0.748c-0.004,0.121-0.003,0.243-0.002,0.365l0.001,0.151
l-0.001,0.148c0,0.124-0.001,0.244,0.002,0.366C1.469,17.755,1.771,18.074,2.176,18.095z"/>
<path fill="#292D32" d="M11.039,21.032c-0.352-0.009-0.708-0.009-1.065,0c-0.419,0.01-0.737,0.33-0.741,0.748
c0,0.003,0,0.006,0,0.01c0,0.002,0,0.003,0,0.005c0,0.063,0.021,0.118,0.035,0.177c0.01,0.031,0.009,0.07,0.022,0.103
c0.108,0.271,0.367,0.456,0.684,0.473c0.071,0.002,0.141,0.004,0.212,0.004h0.009c0.002,0,0.004,0,0.005,0l0.311-0.002
l0.327,0.002c0.071,0,0.142-0.002,0.211-0.006c0.4-0.019,0.699-0.324,0.72-0.716c0.002-0.016,0.012-0.024,0.012-0.044
C11.778,21.376,11.457,21.043,11.039,21.032z"/>
<path fill="#292D32" d="M7.723,21.034c-0.363-0.013-0.725-0.013-1.089,0c-0.422,0.011-0.734,0.34-0.726,0.76
c0.003,0.41,0.308,0.722,0.72,0.746c0.066,0.002,0.135,0.004,0.203,0.004l0.902-0.004c0.409-0.025,0.71-0.338,0.721-0.735
c0.005-0.208-0.069-0.401-0.207-0.542C8.109,21.118,7.922,21.038,7.723,21.034z"/>
<path fill="#292D32" d="M14.375,21.032c-0.364-0.011-0.727-0.011-1.086,0.002c-0.307,0.006-0.563,0.198-0.673,0.469
c-0.026,0.064-0.033,0.136-0.043,0.207c-0.002,0.021-0.012,0.04-0.013,0.062c0,0.002,0.001,0.005,0.001,0.007
c0,0.013-0.006,0.022-0.006,0.033c0.012,0.399,0.312,0.71,0.72,0.737l0.906,0.002c0.064,0,0.136,0,0.201-0.004
c0.411-0.02,0.718-0.331,0.721-0.742v-0.002c0-0.002,0-0.002,0-0.002C15.114,21.379,14.792,21.043,14.375,21.032z"/>
<path fill="#292D32" d="M16.713,5.973l0.586,0.002h0.004h0.729v1.161c0,0.105,0.002,0.216,0.021,0.32
c0.065,0.36,0.374,0.62,0.739,0.62l0.039-0.001c0.394-0.02,0.71-0.331,0.715-0.706c0.012-0.739,0.012-1.475,0-2.213
c-0.005-0.39-0.335-0.699-0.752-0.702c-0.693-0.008-1.394-0.01-2.093,0c-0.219,0.002-0.413,0.084-0.555,0.228
c-0.138,0.144-0.213,0.341-0.209,0.555C15.947,5.66,16.274,5.968,16.713,5.973z"/>
<path fill="#292D32" d="M18.788,18.935c-0.433,0.006-0.747,0.326-0.754,0.764c-0.01,0.327-0.008,0.653-0.004,0.981v0.357h-1.307
c-0.235,0.002-0.438,0.08-0.584,0.232c-0.137,0.136-0.206,0.33-0.202,0.544c0.007,0.409,0.313,0.727,0.713,0.731
c0.386,0.004,0.769,0.006,1.154,0.006c0.336,0,0.678-0.002,1.018-0.004c0.404-0.005,0.721-0.327,0.722-0.727
c0.013-0.717,0.013-1.434,0-2.151C19.544,19.257,19.211,18.935,18.788,18.935z"/>
<path fill="#292D32" d="M10,5.973l0.218,0.002l0.298-0.001l0.298,0.001c0.074,0,0.146,0,0.218-0.003
c0.409-0.014,0.721-0.311,0.747-0.708c0-0.004-0.004-0.007-0.004-0.013c0,0,0,0,0-0.001c0.004-0.021-0.007-0.041-0.007-0.063
c-0.004-0.079-0.01-0.159-0.031-0.231c-0.031-0.096-0.084-0.185-0.15-0.26c-0.135-0.147-0.317-0.233-0.515-0.243
c-0.377-0.018-0.76-0.021-1.139,0c-0.198,0.012-0.38,0.096-0.508,0.241c-0.136,0.152-0.203,0.35-0.19,0.563
c0.006,0.1,0.031,0.193,0.07,0.277C9.422,5.79,9.682,5.964,10,5.973z"/>
<path fill="#292D32" d="M14.375,4.453c-0.36-0.012-0.718-0.012-1.072,0c-0.214,0.008-0.408,0.097-0.544,0.248
c-0.136,0.147-0.209,0.34-0.201,0.541c0.019,0.414,0.345,0.72,0.779,0.73l0.203,0.002l0.293-0.001l0.302,0.001l0.215-0.003
c0.42-0.011,0.739-0.318,0.756-0.726C15.12,4.812,14.808,4.471,14.375,4.453z"/>
<path fill="#292D32" d="M18.034,13.997c0.018,0.458,0.329,0.778,0.76,0.778h0.02c0.433-0.007,0.734-0.333,0.741-0.789
c0.003-0.323,0.003-0.643,0-0.964c-0.007-0.452-0.32-0.781-0.748-0.789c-0.436-0.002-0.753,0.32-0.772,0.766
c-0.005,0.121-0.005,0.241-0.002,0.363v0.155v0.145C18.029,13.774,18.027,13.887,18.034,13.997z"/>
<path fill="#292D32" d="M19.557,10.006c0-0.122,0.001-0.243-0.002-0.364c-0.02-0.406-0.324-0.717-0.721-0.738h-0.002
c-0.019,0-0.033,0.008-0.054,0.009c-0.299,0.015-0.549,0.175-0.666,0.41c-0.038,0.084-0.06,0.176-0.067,0.272
c-0.02,0.385-0.02,0.774,0,1.158c0.021,0.395,0.344,0.694,0.749,0.694h0.03c0.409-0.015,0.717-0.331,0.73-0.755
c0.003-0.123,0.002-0.25,0.002-0.375l-0.002-0.159L19.557,10.006z"/>
<path fill="#292D32" d="M19.555,16.312c-0.018-0.424-0.326-0.739-0.737-0.751c-0.435,0-0.76,0.309-0.777,0.72
c-0.018,0.367-0.018,0.731,0,1.1c0.019,0.411,0.34,0.726,0.754,0.726l0.044-0.002c0.408-0.02,0.708-0.34,0.72-0.76
c0.002-0.126,0.002-0.248,0.002-0.37l-0.002-0.146l0.002-0.149C19.557,16.55,19.558,16.43,19.555,16.312z"/>
</g>
<g>
<path fill="#292D32" d="M7.604,15.028H5.609l-0.289,0.7H4.247l1.826-4.476h1.075l1.827,4.476H7.891L7.604,15.028z M7.27,14.214
l-0.665-1.636l-0.664,1.636H7.27z"/>
<path fill="#292D32" d="M13.102,14.046c0,1.033-0.65,1.766-1.55,1.766c-0.473,0-0.86-0.203-1.128-0.556v0.473H9.471v-4.552h0.953
v1.655c0.269-0.346,0.656-0.546,1.128-0.546C12.451,12.286,13.102,13.015,13.102,14.046z M12.176,14.046
c0-0.561-0.37-0.958-0.899-0.958c-0.464,0-0.802,0.339-0.853,0.826v0.262c0.051,0.493,0.389,0.835,0.853,0.835
C11.806,15.01,12.176,14.612,12.176,14.046z"/>
<path fill="#292D32" d="M13.581,14.046c0-0.958,0.847-1.76,1.847-1.76c0.544,0,0.995,0.221,1.321,0.571l-0.633,0.542
c-0.17-0.189-0.437-0.312-0.697-0.312c-0.494,0-0.916,0.438-0.916,0.951c0,0.525,0.422,0.972,0.925,0.972
c0.262,0,0.531-0.129,0.71-0.327l0.63,0.532c-0.334,0.367-0.786,0.596-1.349,0.596C14.423,15.812,13.581,14.999,13.581,14.046z"/>
</g>
<circle fill="#292D32" cx="18.794" cy="5.202" r="3.751"/>
<path fill="#FFFFFF" d="M19.258,5.201l1.409-1.409l0.051-0.055c0.066-0.085,0.088-0.197,0.057-0.299
c-0.032-0.104-0.113-0.185-0.218-0.217l-0.098-0.015c-0.092,0-0.175,0.038-0.247,0.111l-1.419,1.421l-1.41-1.411l-0.047-0.042
c-0.102-0.081-0.229-0.095-0.354-0.033c-0.128,0.067-0.195,0.198-0.171,0.33c0.014,0.078,0.053,0.154,0.105,0.204
c0.47,0.473,0.941,0.945,1.413,1.416l-1.419,1.42l0,0l-0.038,0.04c-0.07,0.087-0.093,0.202-0.059,0.308
c0.033,0.105,0.118,0.186,0.227,0.216l0.087,0.012c0.091,0,0.174-0.038,0.246-0.111l1.42-1.421l1.419,1.418l0.047,0.043
c0.103,0.08,0.251,0.091,0.364,0.027c0.129-0.073,0.193-0.219,0.154-0.36c-0.019-0.062-0.055-0.123-0.104-0.174L19.258,5.201z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 8.2 KiB

View File

@@ -1,29 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<g>
<path fill="#292D32" d="M18.662,12.893c-0.019-0.962-0.756-1.756-1.716-1.853c-0.056-0.006-0.11-0.014-0.181-0.022
c0-0.074,0-0.141,0-0.208c0-1.164,0.015-2.329-0.006-3.494c-0.031-2.067-0.98-3.57-2.852-4.447
c-0.254-0.118-0.533-0.188-0.813-0.25c-0.053-0.01-1.043-0.213-1.861-0.077c-0.063,0.013-0.124,0.026-0.187,0.04
C11,2.591,10.954,2.605,10.909,2.619c-0.146,0.048-0.219,0.061-0.242,0.051c-0.135,0.034-0.27,0.077-0.396,0.129
C8.627,3.47,7.632,4.695,7.314,6.447C7.257,6.769,7.245,7.1,7.244,7.427C7.235,8.548,7.241,9.67,7.241,10.792
c0,0.067,0,0.134,0,0.214c-0.052,0.011-0.097,0.025-0.144,0.029c-1.041,0.11-1.756,0.898-1.756,1.952
c-0.004,2.174,0.012,4.35-0.009,6.523C5.322,20.465,6,21.332,6.934,21.477c0.016,0.004,0.031,0.018,0.046,0.029
c3.348,0,6.697,0,10.045,0c0.36-0.096,0.705-0.221,0.99-0.477c0.401-0.371,0.646-0.816,0.646-1.369
c0.009-1.822,0.006-3.641,0.006-5.463C18.666,13.764,18.672,13.33,18.662,12.893z M9.143,7.274c0.01-1.46,1.017-2.664,2.404-2.876
c1.731-0.267,3.264,1.007,3.311,2.781c0.026,1.245,0.003,2.491,0.003,3.735c0,0.029-0.007,0.059-0.013,0.098
c-1.899,0-3.791,0-5.708,0c0-0.374,0-0.727,0-1.082C9.141,9.047,9.137,8.16,9.143,7.274z"/>
<g>
<path fill="#FFFFFF" d="M11.386,17.957c0-0.514-0.003-1.029,0.003-1.547c0-0.125-0.027-0.191-0.155-0.25
c-0.883-0.4-1.307-1.373-1.013-2.283c0.296-0.902,1.205-1.435,2.165-1.26c0.9,0.162,1.568,1.018,1.505,1.957
c-0.051,0.738-0.43,1.27-1.097,1.588c-0.123,0.059-0.157,0.117-0.155,0.246c0.004,1.025,0.004,2.049,0.001,3.074
c-0.001,0.486-0.445,0.805-0.869,0.617c-0.253-0.113-0.383-0.316-0.384-0.594C11.385,18.988,11.386,18.475,11.386,17.957z
M12.64,14.455c-0.003-0.34-0.288-0.623-0.627-0.623c-0.346,0-0.635,0.301-0.626,0.648c0.009,0.336,0.299,0.615,0.638,0.609
C12.364,15.082,12.643,14.793,12.64,14.455z"/>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -1,103 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="56.689px" height="56.689px" viewBox="0 0 56.689 56.689" enable-background="new 0 0 56.689 56.689" xml:space="preserve">
<g>
<path fill="#FF9518" stroke="#231F20" stroke-miterlimit="10" d="M11.905,17.656c0,1.256,0,2.426,0,3.649c-0.896,0-1.766,0-2.635,0
c-1.5,0-3.001,0.005-4.502-0.001C3.62,21.3,2.797,20.516,2.809,19.459c0.012-1.038,0.821-1.797,1.944-1.801
c2.242-0.007,4.483-0.002,6.726-0.002C11.608,17.656,11.737,17.656,11.905,17.656z"/>
<path fill="#FF9518" stroke="#231F20" stroke-miterlimit="10" d="M44.889,21.151c0-1.246,0-2.416,0-3.625
c0.188-0.009,0.353-0.024,0.517-0.024c2.186-0.001,4.371-0.003,6.556,0c1.203,0.001,2.033,0.756,2.028,1.833
c-0.005,1.075-0.834,1.814-2.046,1.815C49.608,21.153,47.275,21.151,44.889,21.151z"/>
<path fill="#FF9518" stroke="#231F20" stroke-miterlimit="10" d="M11.885,37.733c-2.46,0-4.874,0.014-7.287-0.006
c-0.997-0.007-1.771-0.812-1.791-1.778C2.79,34.995,3.51,34.12,4.464,34.105c2.466-0.039,4.933-0.013,7.421-0.013
C11.885,35.325,11.885,36.521,11.885,37.733z"/>
<path fill="#FF9518" stroke="#231F20" stroke-miterlimit="10" d="M44.892,39.406c0-1.229,0-2.4,0-3.625
c0.183-0.009,0.365-0.024,0.547-0.025c2.165-0.002,4.332-0.003,6.497,0c1.216,0.001,2.045,0.735,2.054,1.809
c0.01,1.077-0.821,1.838-2.021,1.84C49.631,39.408,47.294,39.406,44.892,39.406z"/>
<path fill="#FF9518" stroke="#231F20" stroke-miterlimit="10" d="M17.411,44.97c1.256,0,2.426,0,3.649,0c0,0.858,0,1.689,0,2.521
c0,1.538,0.006,3.076-0.001,4.616c-0.005,1.149-0.787,1.972-1.844,1.96c-1.033-0.011-1.799-0.827-1.803-1.944
c-0.006-2.242-0.002-4.483-0.002-6.727C17.411,45.265,17.411,45.137,17.411,44.97z"/>
<path fill="#FF9518" stroke="#231F20" stroke-miterlimit="10" d="M35.665,44.968c1.252,0,2.423,0,3.649,0c0,0.247,0,0.471,0,0.692
c0,2.146,0.004,4.294-0.002,6.44c-0.003,1.151-0.782,1.974-1.839,1.965c-1.032-0.009-1.805-0.824-1.808-1.938
C35.661,49.756,35.665,47.385,35.665,44.968z"/>
<path fill="#FF9518" stroke="#231F20" stroke-miterlimit="10" d="M21.063,10.283c-1.243,0-2.399,0-3.582,0
c-0.021-0.066-0.063-0.135-0.063-0.202c-0.004-1.768-0.019-3.534,0.002-5.3c0.012-0.978,0.777-1.738,1.726-1.784
c0.946-0.045,1.787,0.661,1.904,1.604c0.019,0.149,0.012,0.303,0.012,0.455C21.063,6.781,21.063,8.506,21.063,10.283z"/>
<path fill="#FF9518" stroke="#231F20" stroke-miterlimit="10" d="M39.316,10.269c-1.227,0-2.396,0-3.607,0
c-0.016-0.143-0.04-0.287-0.04-0.431c-0.003-1.615-0.005-3.23-0.001-4.845c0.004-1.17,0.747-1.987,1.806-1.998
c1.077-0.011,1.84,0.82,1.843,2.019c0.004,1.596,0.001,3.192,0.001,4.788C39.316,9.95,39.316,10.098,39.316,10.269z"/>
<path fill="#FF9518" stroke="#231F20" stroke-miterlimit="10" d="M11.91,26.627c0,1.235,0,2.407,0,3.612
c-0.138,0.015-0.264,0.037-0.391,0.037c-1.652,0.002-3.306,0.008-4.958-0.002c-1.11-0.004-1.925-0.784-1.928-1.819
c-0.002-1.041,0.805-1.821,1.917-1.826C8.316,26.62,10.082,26.627,11.91,26.627z"/>
<path fill="#FF9518" stroke="#231F20" stroke-miterlimit="10" d="M44.893,30.278c0-1.225,0-2.396,0-3.617
c0.159-0.012,0.322-0.031,0.485-0.032c1.595-0.002,3.189-0.005,4.787,0c1.164,0.003,1.987,0.751,1.998,1.805
c0.011,1.078-0.818,1.841-2.019,1.844c-1.596,0.006-3.19,0.001-4.786,0.001C45.212,30.278,45.065,30.278,44.893,30.278z"/>
<path fill="#FF9518" stroke="#231F20" stroke-miterlimit="10" d="M30.185,44.982c0,1.881,0.025,3.723-0.011,5.563
c-0.021,0.956-0.862,1.696-1.81,1.697c-0.944,0-1.794-0.743-1.812-1.695c-0.035-1.84-0.01-3.682-0.01-5.563
C27.75,44.982,28.935,44.982,30.185,44.982z"/>
<path fill="#FF9518" stroke="#231F20" stroke-miterlimit="10" d="M26.543,10.254c0-1.273-0.028-2.506,0.01-3.738
c0.029-0.959,0.856-1.695,1.809-1.695c0.947-0.001,1.783,0.738,1.813,1.693c0.04,1.232,0.01,2.466,0.01,3.74
C28.978,10.254,27.794,10.254,26.543,10.254z"/>
<path fill="#231F20" d="M41.598,43.901c-0.141,0.15-0.28,0.29-0.391,0.4v-0.24C41.337,44.021,41.467,43.962,41.598,43.901z"/>
<path fill="#231F20" d="M44.447,41.292l-0.02,0.85l-0.551,0.37C44.117,42.142,44.317,41.731,44.447,41.292z"/>
<rect x="45.354" y="17.996" fill="#DE9518" width="1.422" height="2.672"/>
<rect x="45.385" y="27.117" fill="#DE9518" width="1.422" height="2.672"/>
<rect x="45.385" y="36.244" fill="#DE9518" width="1.422" height="2.672"/>
<rect x="9.984" y="18.149" fill="#DE9518" width="1.422" height="2.672"/>
<rect x="10.015" y="27.116" fill="#DE9518" width="1.422" height="2.673"/>
<rect x="9.984" y="34.575" fill="#DE9518" width="1.422" height="2.672"/>
<rect x="17.927" y="8.359" fill="#DE9518" width="2.629" height="1.423"/>
<rect x="27.027" y="8.359" fill="#DE9518" width="2.675" height="1.423"/>
<rect x="36.155" y="8.359" fill="#DE9518" width="2.673" height="1.423"/>
<rect x="17.901" y="45.472" fill="#DE9518" width="2.688" height="1.422"/>
<rect x="27.026" y="45.472" fill="#DE9518" width="2.671" height="1.422"/>
<rect x="36.182" y="45.472" fill="#DE9518" width="2.619" height="1.422"/>
<g>
<g>
<path fill="#9D724C" d="M44.522,14.252l-1.306-1.571c0.689,0.88,1.07,2.03,1.07,3.37c0.01,7.72,0.01,15.43,0,23.151
c0,1.608-0.551,2.938-1.511,3.868v0.182l1.101-0.74c-0.979,1.53-2.699,2.45-4.851,2.45c-7.109,0.01-14.221,0.01-21.331,0
c-3.42,0-5.76-2.34-5.76-5.76V16.041c0-3.42,2.34-5.76,5.771-5.76h21.32C41.811,10.281,43.845,11.838,44.522,14.252z"/>
<path fill="#9D724C" d="M44.547,14.281v0.058c-0.008-0.029-0.018-0.058-0.024-0.087L44.547,14.281z"/>
<path fill="#9D724C" d="M44.787,16.051c0.01,7.72,0.01,15.43,0,23.151c0,0.75-0.109,1.448-0.341,2.09l0.101-3.63V14.339
C44.688,14.875,44.787,15.438,44.787,16.051z"/>
</g>
</g>
<g>
<g>
<path fill="#FFEACE" d="M41.21,18.002v18.81c0,1.36-0.5,2.472-1.351,3.211c-0.22,0.199-0.47,0.369-0.75,0.5l-0.021,0.011
l-0.061,0.04v-0.012c-0.579,0.28-1.25,0.432-2,0.432H19.7c-2.49,0-4.171-1.69-4.171-4.19l-0.01-6.51l0.01-2.892l-0.01-2.89
l0.01-6.51c0-2.5,1.681-4.181,4.181-4.181H37.03c0.75,0,1.421,0.15,2,0.431C40.38,14.902,41.21,16.252,41.21,18.002z"/>
</g>
<g>
<path fill="#231F20" d="M39.027,40.562v0.01l0.061-0.039C39.067,40.542,39.047,40.552,39.027,40.562z M39.027,40.562v0.01
l0.061-0.039C39.067,40.542,39.047,40.552,39.027,40.562z M41.207,15.751v-0.95c-0.899-1.24-2.38-1.98-4.181-1.98H19.707
c-3.05,0-5.181,2.131-5.181,5.181l-0.01,6.51l0.01,2.89l-0.01,2.892l0.01,6.51c0,3.05,2.131,5.19,5.17,5.19h17.331
c1.79,0,3.271-0.74,4.181-1.98v-0.95c-0.729,1.5-2.24,2.432-4.181,2.432H19.697c-2.779,0-4.67-1.9-4.67-4.69
c-0.01-3.13,0-6.26,0-9.4c0-3.13-0.01-6.27,0-9.399c0-2.78,1.9-4.68,4.681-4.68h17.32C38.967,13.321,40.478,14.251,41.207,15.751
z M39.087,40.531c-0.021,0.011-0.04,0.021-0.061,0.029v0.01L39.087,40.531z"/>
</g>
</g>
<path fill="#231F20" d="M42.207,18.001v18.81c0,1.25-0.359,2.352-1,3.2v-25.21C41.848,15.651,42.207,16.741,42.207,18.001z"/>
<path fill="#231F20" d="M39.027,9.781H17.707c-3.69,0-6.271,2.579-6.271,6.26v23.161c0,3.688,2.58,6.26,6.26,6.26l10.66,0.01
l10.67-0.01c3.689,0,6.261-2.57,6.261-6.26c0.01-7.722,0.01-15.432,0-23.151C45.287,12.361,42.717,9.781,39.027,9.781z
M41.344,44.012l-0.137,0.05c-0.649,0.26-1.38,0.4-2.181,0.4l-10.67,0.01l-10.66-0.01c-3.14,0-5.26-2.11-5.26-5.26V16.051
c0-3.15,2.12-5.27,5.271-5.27h21.32c0.801,0,1.53,0.14,2.181,0.399c0.29,0.11,0.561,0.24,0.819,0.41h0.011
c0.271,0.17,0.521,0.37,0.739,0.59c0.091,0.08,0.181,0.18,0.261,0.271l0.18,0.229l1.311,1.57c0,0.003,0.002,0.006,0.002,0.009
l-1.313-1.579c0.69,0.88,1.07,2.03,1.07,3.37c0.01,7.72,0.01,15.43,0,23.151c0,1.608-0.551,2.938-1.511,3.868
c-0.34,0.33-0.739,0.61-1.18,0.83C41.457,44.052,41.454,43.901,41.344,44.012z"/>
<path fill="#697041" d="M44.287,16.051c0.01,7.72,0.271,15.435,0,23.151c-0.125,3.544-1.97,4.259-2.689,4.698
c-0.131,0.062-0.261,0.12-0.391,0.16v-4.05c0.641-0.85,1-1.95,1-3.2v-18.81c0-1.26-0.359-2.351-1-3.2v-3.62
c0.29,0.11,0.561,0.24,0.819,0.41h0.011l1,0.86l0.18,0.229C43.907,13.561,44.287,14.711,44.287,16.051z"/>
<g>
<path fill="#231F20" d="M37.03,13.322h-17.32c-2.78,0-4.681,1.9-4.681,4.681c-0.01,3.13,0,6.27,0,9.399c0,3.142-0.01,6.271,0,9.4
c0,2.79,1.891,4.69,4.671,4.69h17.33c2.78,0,4.681-1.9,4.681-4.682v-18.81C41.71,15.223,39.811,13.322,37.03,13.322z
M39.11,40.523l-0.021,0.011l-0.061,0.04v-0.012c-0.579,0.28-1.25,0.432-2,0.432H19.7c-2.49,0-4.171-1.69-4.171-4.19l-0.01-6.51
l0.01-2.892l-0.01-2.89l0.01-6.51c0-2.5,1.681-4.181,4.181-4.181H37.03c0.75,0,1.421,0.15,2,0.431c1.351,0.649,2.181,2,2.181,3.75
v18.81c0,1.36-0.5,2.472-1.351,3.211C39.641,40.223,39.391,40.393,39.11,40.523z"/>
<path fill="#D9EACE" d="M41.21,18.002v18.81c0,1.36-0.5,2.472-1.351,3.211l-0.75,0.5l-0.021,0.011l-0.061,0.04V14.252
C40.38,14.902,41.21,16.252,41.21,18.002z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 8.8 KiB

View File

@@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<g>
<path fill="none" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" d="M22,10v5c0,5-2,7-7,7H9
c-5,0-7-2-7-7V9c0-5,2-7,7-7h5"/>
<path fill="none" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" d="M22,10h-4c-3,0-4-1-4-4
V2L22,10z"/>
</g>
</g>
<g>
<path fill="#292D32" d="M15.343,18.876c0.563-0.002,0.866-0.303,0.866-0.859c0.001-1.912,0.001-3.828,0-5.742
c0-0.56-0.297-0.856-0.865-0.856c-2.534-0.001-5.068-0.001-7.604,0c-0.56,0-0.859,0.301-0.86,0.866c0,1.906,0,3.814,0,5.723
c0,0.568,0.303,0.867,0.875,0.869c1.266,0,2.529,0,3.795,0C12.813,18.876,14.079,18.876,15.343,18.876z M7.755,18.267
c-0.237-0.002-0.277-0.041-0.277-0.285c0-1.891,0-3.781,0-5.672c0-0.248,0.043-0.291,0.289-0.291c2.518,0,5.035,0,7.553,0
c0.258,0,0.296,0.041,0.296,0.302c0,1.885,0,3.77,0,5.656c0,0.25-0.038,0.287-0.29,0.287c-1.265,0-2.529,0-3.793,0
C10.272,18.267,9.013,18.267,7.755,18.267z"/>
<path fill="#292D32" d="M14.85,15.337c-0.588-0.58-1.172-1.168-1.759-1.75c-0.043-0.043-0.089-0.086-0.151-0.146
c-0.829,0.836-1.646,1.662-2.485,2.508c-0.264-0.277-0.513-0.541-0.772-0.816c-0.517,0.521-1.006,1.014-1.493,1.508
c-0.026,0.029-0.055,0.068-0.055,0.104c-0.004,0.289-0.003,0.58-0.003,0.873c2.29,0,4.555,0,6.833,0c0-0.074,0-0.137,0-0.201
c0-0.598-0.003-1.195,0.003-1.793C14.967,15.505,14.936,15.423,14.85,15.337z"/>
<path fill="#292D32" d="M9.052,14.511c0.517-0.002,0.917-0.4,0.919-0.918c0.003-0.525-0.398-0.928-0.925-0.926
c-0.516,0-0.915,0.396-0.917,0.914C8.126,14.106,8.529,14.511,9.052,14.511z"/>
<path fill="#292D32" d="M17.111,13.304c0-0.084-0.001-0.172-0.011-0.258c-0.027-0.301-0.31-0.574-0.585-0.619v0.834
c0.003,0.014,0.004,0.023,0.004,0.037c0.006,1.844,0.004,3.689,0.004,5.533c0,0.289-0.023,0.314-0.315,0.314
c-1.554,0-3.106,0.012-4.659,0V19.14h-0.586c-0.131,0-0.261-0.002-0.391-0.004c-0.105-0.002-0.212,0-0.316,0.004H8.907H8.285H7.972
c0.005,0.029,0.01,0.055,0.019,0.082c0.105,0.328,0.392,0.518,0.787,0.518c2.478,0,4.954-0.008,7.431,0.008
c0.508,0.002,0.918-0.287,0.911-0.91C17.099,16.991,17.111,15.146,17.111,13.304z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<path fill="#292D32" d="M11.548,21.76c-5.652,0-10.25-4.6-10.25-10.252c0-5.651,4.598-10.25,10.25-10.25
c5.652,0,10.25,4.599,10.25,10.25C21.798,17.16,17.2,21.76,11.548,21.76z M11.548,2.758c-4.825,0-8.75,3.926-8.75,8.75
c0,4.826,3.925,8.752,8.75,8.752c4.824,0,8.75-3.926,8.75-8.752C20.298,6.684,16.372,2.758,11.548,2.758z"/>
</g>
<path fill="none" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" d="M22,22l-2-2"/>
<path fill="none" stroke="#292D32" stroke-width="0.8" stroke-linecap="round" stroke-linejoin="round" d="M13.591,7.617h3.336"/>
<path fill="none" stroke="#292D32" stroke-width="0.8" stroke-linecap="round" stroke-linejoin="round" d="M15.259,9.285V5.948"/>
<g>
<path fill="none" stroke="#292D32" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round" d="M7.64,11.509h7.816"/>
<path fill="none" stroke="#292D32" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round" d="M11.549,15.415V7.603"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<path fill="none" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" d="M11.596,21.03
c5.247,0,9.5-4.254,9.5-9.501c0-5.247-4.254-9.5-9.5-9.5c-5.247,0-9.5,4.253-9.5,9.5C2.096,16.776,6.349,21.03,11.596,21.03z"/>
<path fill="none" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" d="M22,22l-2-2"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#292D32" d="M11.444,11.558c0.055-0.017,0.114-0.029,0.169-0.043
c1.169-0.286,2.008-0.198,2.008-0.198l0.055,1.928c0.012,0.398,0.249,0.492,0.529,0.209c0.988-1,1.969-1.99,2.949-2.981
c0.28-0.284,0.277-0.74-0.008-1.021c-1.014-1-2.026-1.996-3.043-3c-0.285-0.28-0.514-0.182-0.512,0.216
c0.004,0.599,0.008,1.189,0.011,1.781c0,0-6.975-0.387-7.773,8.317C7.385,13.294,9.729,12.019,11.444,11.558z"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<path fill="none" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" d="M11.596,21.03
c5.247,0,9.5-4.254,9.5-9.501c0-5.247-4.254-9.5-9.5-9.5c-5.247,0-9.5,4.253-9.5,9.5C2.096,16.776,6.349,21.03,11.596,21.03z"/>
<path fill="none" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" d="M22,22l-2-2"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#292D32" d="M11.747,11.558c-0.055-0.017-0.114-0.029-0.169-0.043
c-1.169-0.286-2.007-0.198-2.007-0.198l-0.056,1.928c-0.011,0.398-0.249,0.492-0.529,0.209c-0.989-1-1.969-1.99-2.95-2.981
c-0.28-0.284-0.277-0.74,0.008-1.021c1.015-1,2.027-1.996,3.043-3C9.373,6.173,9.601,6.271,9.6,6.668
C9.596,7.267,9.592,7.857,9.589,8.45c0,0,6.975-0.387,7.773,8.317C15.807,13.294,13.462,12.019,11.747,11.558z"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<path fill="#292D32" d="M11.547,21.752c-5.652,0-10.25-4.599-10.25-10.252c0-5.651,4.598-10.25,10.25-10.25
c5.652,0,10.25,4.599,10.25,10.25C21.797,17.153,17.199,21.752,11.547,21.752z M11.547,2.75c-4.825,0-8.75,3.926-8.75,8.75
c0,4.826,3.925,8.752,8.75,8.752c4.824,0,8.75-3.926,8.75-8.752C20.297,6.676,16.371,2.75,11.547,2.75z"/>
</g>
<path fill="none" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" d="M22,22l-2-2"/>
</svg>

Before

Width:  |  Height:  |  Size: 932 B

View File

@@ -1,65 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="56.689px" height="56.689px" viewBox="0 0 56.689 56.689" enable-background="new 0 0 56.689 56.689" xml:space="preserve">
<g>
<g>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFEACE" d="M46.424,17.157c0-0.03-0.02-0.06-0.02-0.09
c-3.36,0-6.71,0-10.061-0.01c-0.359,0-0.71-0.04-1.069-0.06c-1.721-0.54-2.521-1.65-2.53-3.48c0-3.38,0-6.76-0.01-10.14H12.823
c-2.05,0.87-2.58,1.66-2.58,3.9c0,14.17,0.01,28.34,0,42.51c0,1,0.22,1.9,0.94,2.63c0.51,0.521,1.15,0.78,1.83,0.95h30.761
c0.27-0.1,0.55-0.17,0.81-0.3c1.101-0.56,1.73-1.44,1.84-2.68c0.011-0.2,0.011-0.391,0.011-0.59V26.617
c0-0.16-0.011-0.32-0.021-0.48C46.474,23.137,46.444,20.147,46.424,17.157z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#FF9518" d="M32.736,3.382c0.131,0.145,0.633,0.574,0.772,0.711
c4.255,4.258,8.231,8.234,12.487,12.493c0.146,0.147,0.332,0.264,0.403,0.478c-3.351,0-6.704,0.001-10.055-0.004
c-0.356-0.001-0.713-0.04-1.071-0.062c-1.719-0.545-2.522-1.649-2.526-3.479C32.743,10.139,32.739,6.761,32.736,3.382
C32.768,3.382,32.706,3.382,32.736,3.382z"/>
</g>
<g>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#D9EACE" d="M34.633,17.295c0.356,0.021,0.982,0,1.339,0
c3.353,0.006,6.782,0.099,10.133,0.1c0.011,0.031,0.531,0.542,0.008,0.734c0.018,2.992-0.05,5.65-0.109,8.641
c-2.298-1.857-4.738-3.828-7.036-5.686c-1.276-1.032-2.549-2.067-3.825-3.097C34.976,17.853,34.715,17.502,34.633,17.295z"/>
</g>
<g>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#DE9518" d="M39.876,25.814c0,1.018-0.619,1.842-1.385,1.842H18.199
c-0.765,0-1.386-0.824-1.386-1.842l0,0c0-1.017,0.621-1.841,1.386-1.841h20.292C39.257,23.973,39.876,24.798,39.876,25.814
L39.876,25.814z"/>
<path fill="#231F20" d="M38.491,28.156H18.199c-1.04,0-1.886-1.05-1.886-2.342c0-1.291,0.846-2.341,1.886-2.341h20.292
c1.039,0,1.885,1.05,1.885,2.341C40.376,27.106,39.53,28.156,38.491,28.156z M18.199,24.473c-0.48,0-0.886,0.614-0.886,1.341
c0,0.728,0.406,1.342,0.886,1.342h20.292c0.479,0,0.885-0.614,0.885-1.342c0-0.727-0.405-1.341-0.885-1.341H18.199z"/>
</g>
<g>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#DE9518" d="M39.876,32.564c0,1.018-0.619,1.842-1.385,1.842H18.199
c-0.765,0-1.386-0.824-1.386-1.842l0,0c0-1.017,0.621-1.841,1.386-1.841h20.292C39.257,30.723,39.876,31.548,39.876,32.564
L39.876,32.564z"/>
<path fill="#231F20" d="M38.491,34.906H18.199c-1.04,0-1.886-1.051-1.886-2.342s0.846-2.341,1.886-2.341h20.292
c1.039,0,1.885,1.05,1.885,2.341S39.53,34.906,38.491,34.906z M18.199,31.223c-0.48,0-0.886,0.614-0.886,1.341
c0,0.728,0.406,1.342,0.886,1.342h20.292c0.479,0,0.885-0.614,0.885-1.342c0-0.727-0.405-1.341-0.885-1.341H18.199z"/>
</g>
<g>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#DE9518" d="M39.876,39.211c0,1.018-0.62,1.842-1.386,1.842H18.198
c-0.765,0-1.386-0.824-1.386-1.842l0,0c0-1.017,0.621-1.841,1.386-1.841H38.49C39.256,37.37,39.876,38.194,39.876,39.211
L39.876,39.211z"/>
<path fill="#231F20" d="M38.49,41.552H18.198c-1.04,0-1.886-1.051-1.886-2.342s0.846-2.341,1.886-2.341H38.49
c1.04,0,1.886,1.05,1.886,2.341S39.53,41.552,38.49,41.552z M18.198,37.87c-0.48,0-0.886,0.614-0.886,1.341
c0,0.728,0.406,1.342,0.886,1.342H38.49c0.48,0,0.886-0.614,0.886-1.342c0-0.727-0.405-1.341-0.886-1.341H18.198z"/>
</g>
<path fill="#231F20" d="M46.93,17.075l-0.057-0.169c-0.096-0.287-0.29-0.46-0.432-0.587L33.858,3.736
C33.8,3.678,33.68,3.572,33.55,3.454c-0.173-0.154-0.37-0.328-0.442-0.408l-0.149-0.165h-0.722l0.011,10.637
c0.004,2.049,0.945,3.343,2.875,3.955l0.447,0.046c0.258,0.02,0.516,0.039,0.774,0.04c2.166,0.003,4.332,0.004,6.499,0.004h4.088
V17.075z M42.843,16.564c-2.166,0-4.332,0-6.496-0.004c-0.233-0.001-0.468-0.019-0.701-0.037l-0.276-0.02
c-1.464-0.482-2.119-1.405-2.122-2.991l-0.01-8.983l12.029,12.035H42.843z"/>
<path fill="#231F20" d="M46.914,26.147c0.05-2.67,0.03-5.38,0.021-8l-0.011-0.99l-0.31-0.68l-3.771,0.09c-2.17,0-4.329,0-6.5-0.01
c-0.229,0-0.47-0.02-0.699-0.03l-0.28-0.02c-1.46-0.49-2.11-1.41-2.12-3l-0.01-10.31l-0.32-0.32l-18.32,0.004
c-0.053,0.002-0.12,0.003-0.217,0c-1.156-0.029-2.314,0.361-2.314,0.361c-0.773,0.303-1.115,0.64-1.359,0.864
c-0.16,0.15-0.22,0.25-0.22,0.25c-0.55,0.69-0.74,1.59-0.74,2.92v8.76c0.01,11.25,0.01,22.5,0,33.75c0,1.28,0.34,2.221,1.08,2.98
c0.478,0.492,1.044,0.767,1.559,0.941c0,0,0.499,0.115,1.055,0.148l29.868,0.01c0.023-0.001,0.513-0.017,0.905-0.126
c0.205-0.068,0.409-0.137,0.594-0.233c1.29-0.65,2-1.681,2.12-3.08c0.011-0.19,0.011-0.38,0.011-0.63V26.617
c0-0.12-0.011-0.24-0.011-0.37L46.914,26.147z M45.924,26.307c0,0.1,0.011,0.21,0.011,0.31v23.24c0,0.16,0,0.33-0.011,0.479
c-0.09,1.051-0.6,1.79-1.569,2.28c-0.082,0.044-0.174,0.071-0.263,0.104c-0.357,0.1-0.979,0.146-0.979,0.146H14.476
c-0.046-0.013-0.137-0.016-0.302,0h-0.758c-0.419-0.037-0.736-0.128-0.899-0.185c-0.411-0.16-0.722-0.354-0.983-0.615
c-0.55-0.57-0.79-1.27-0.79-2.28c0.01-11.25,0.01-22.5,0-33.75v-8.76c0-1.362,0.193-2.08,0.871-2.646
c0.985-0.777,1.748-0.745,1.748-0.745l0,0l18.872-0.009l0.01,9.64c0.01,2.05,0.95,3.34,2.88,3.96l0.45,0.04
c0.25,0.02,0.51,0.04,0.77,0.04c2.171,0.01,4.33,0.01,6.5,0.01h3.08l0.011,0.59c0.01,2.61,0.029,5.31-0.021,8L45.924,26.307z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 5.4 KiB

View File

@@ -1,24 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<g>
<g>
<rect x="0.745" y="6.124" fill="#EAFF15" width="22.51" height="11.752"/>
</g>
</g>
<g>
<path fill="#292D32" d="M7.002,14.641H3.57l-0.494,1.212h-1.85l3.14-7.705h1.851l3.141,7.705H7.496L7.002,14.641z M6.431,13.239
l-1.145-2.815l-1.144,2.814L6.431,13.239L6.431,13.239z"/>
<path fill="#292D32" d="M16.464,12.947c0,1.783-1.122,3.04-2.669,3.04c-0.809,0-1.48-0.348-1.941-0.952v0.817h-1.637v-7.84h1.637
v2.849c0.461-0.594,1.133-0.941,1.941-0.941C15.342,9.919,16.464,11.176,16.464,12.947z M14.871,12.947
c0-0.964-0.641-1.648-1.548-1.648c-0.796,0-1.38,0.584-1.47,1.426v0.447c0.09,0.854,0.674,1.437,1.47,1.437
C14.23,14.607,14.871,13.922,14.871,12.947z"/>
<path fill="#292D32" d="M17.289,12.947c0-1.648,1.458-3.027,3.174-3.027c0.941,0,1.717,0.381,2.275,0.986l-1.088,0.932
c-0.291-0.325-0.75-0.539-1.198-0.539c-0.853,0-1.57,0.753-1.57,1.639c0,0.908,0.718,1.671,1.581,1.671
c0.448,0,0.92-0.225,1.223-0.562l1.088,0.92c-0.571,0.629-1.356,1.021-2.32,1.021C18.734,15.987,17.289,14.597,17.289,12.947z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -1,24 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#292D32" d="M4.264,15.622c0.019-1.215,0.42-2.193,1.216-3.006
c0.377-0.385,0.761-0.766,1.144-1.145c0.344-0.34,0.816-0.352,1.134-0.033s0.302,0.787-0.042,1.135
c-0.375,0.379-0.757,0.75-1.131,1.131c-0.737,0.756-0.978,1.654-0.662,2.658c0.317,1.004,1.032,1.611,2.071,1.787
c0.86,0.146,1.619-0.107,2.248-0.717c0.406-0.391,0.797-0.799,1.199-1.191c0.242-0.236,0.58-0.285,0.875-0.145
c0.287,0.137,0.48,0.434,0.43,0.752c-0.027,0.174-0.109,0.367-0.229,0.494c-0.414,0.443-0.834,0.883-1.287,1.283
c-1.23,1.088-2.659,1.387-4.196,0.838c-1.548-0.551-2.451-1.695-2.722-3.324C4.279,15.944,4.276,15.743,4.264,15.622z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#292D32" d="M15.813,4.268c1.506,0.08,2.838,0.872,3.543,2.507
c0.701,1.621,0.42,3.146-0.75,4.477c-0.4,0.455-0.848,0.867-1.281,1.291c-0.324,0.318-0.803,0.313-1.105,0
c-0.307-0.314-0.299-0.779,0.025-1.107c0.396-0.402,0.805-0.791,1.193-1.199c0.713-0.744,0.951-1.627,0.648-2.613
c-0.299-0.969-0.975-1.579-1.969-1.788c-0.885-0.188-1.672,0.051-2.33,0.671c-0.426,0.404-0.83,0.832-1.25,1.244
c-0.23,0.227-0.51,0.301-0.818,0.188c-0.299-0.109-0.471-0.332-0.508-0.65c-0.023-0.201,0.014-0.402,0.156-0.543
c0.604-0.587,1.182-1.204,1.834-1.731C13.872,4.473,14.69,4.272,15.813,4.268z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#292D32" d="M9.587,15.165c-0.311-0.01-0.545-0.152-0.684-0.43
s-0.111-0.551,0.068-0.805c0.039-0.055,0.086-0.102,0.134-0.148c1.564-1.564,3.128-3.125,4.691-4.691
c0.234-0.234,0.502-0.336,0.824-0.244c0.502,0.141,0.715,0.74,0.42,1.172c-0.047,0.07-0.105,0.133-0.166,0.191
c-1.553,1.557-3.109,3.109-4.662,4.666C10.038,15.05,9.845,15.171,9.587,15.165z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -1,60 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<g>
<g>
<g>
<rect x="4.682" y="8.381" fill="#CCCED0" width="12.405" height="1.816"/>
</g>
</g>
<g>
<g>
<rect x="4.682" y="12.084" fill="#292D32" width="12.405" height="1.816"/>
</g>
</g>
<g>
<g>
<rect x="4.682" y="15.789" fill="#CCCED0" width="12.405" height="1.814"/>
</g>
</g>
</g>
<g>
<path fill="#292D32" d="M20.374,17.873c0.12-0.584,0.182-1.268,0.19-2.088v-5.589c-0.011-0.837-0.071-1.499-0.192-2.081
c-0.236-1.312-0.714-2.317-1.459-3.08c-0.556-0.582-1.308-1.028-2.238-1.322c-0.852-0.265-1.902-0.401-3.117-0.401L8.209,3.314
c-4.846,0-7.005,2.16-7.005,7.004v5.357c0,4.84,2.161,6.998,7.005,6.998h5.35c1.216,0,2.263-0.137,3.118-0.398
c0.923-0.291,1.658-0.721,2.24-1.318C19.656,20.195,20.133,19.189,20.374,17.873z M16.741,20.652
c-0.604,0.268-1.358,0.42-2.308,0.465c-0.286,0.02-0.57,0.029-0.874,0.029H8.211c-4.1,0-5.481-1.379-5.481-5.471v-5.359
c0-4.071,1.277-5.452,5.303-5.471l0,0l5.527-0.02c0.313,0,0.608,0.01,0.885,0.028c0.956,0.058,1.712,0.214,2.31,0.479
c1.124,0.477,1.791,1.348,2.098,2.741c0.123,0.595,0.186,1.287,0.193,2.121v5.59c-0.008,0.838-0.07,1.529-0.193,2.123
C18.545,19.303,17.874,20.176,16.741,20.652z"/>
</g>
<g>
<g>
<path fill="#FFFFFF" d="M18.067,2.299c-1.782,0-3.233,1.455-3.233,3.243c0,1.783,1.451,3.233,3.233,3.233S21.3,7.325,21.3,5.542
C21.3,3.754,19.85,2.299,18.067,2.299z"/>
<path fill="#292D32" d="M18.067,1.327c-2.324,0-4.214,1.891-4.214,4.215c0,2.319,1.89,4.206,4.214,4.206s4.214-1.887,4.214-4.206
C22.281,3.218,20.392,1.327,18.067,1.327z M18.067,8.775c-1.782,0-3.233-1.45-3.233-3.233c0-1.788,1.451-3.243,3.233-3.243
S21.3,3.754,21.3,5.542C21.3,7.325,19.85,8.775,18.067,8.775z"/>
</g>
<path fill="#292D32" d="M22.666,9.488l-0.784-0.783c-0.161-0.162-0.468-0.16-0.623-0.002c-0.085,0.084-0.131,0.195-0.131,0.313
c-0.002,0.117,0.045,0.229,0.131,0.313l0.781,0.781c0.08,0.084,0.194,0.133,0.313,0.133c0.117,0,0.229-0.047,0.313-0.131
s0.13-0.193,0.13-0.311S22.75,9.572,22.666,9.488z"/>
</g>
<g>
<path fill="#292D32" d="M17.206,6.443c0-0.233,0.037-0.445,0.112-0.629c0.077-0.187,0.235-0.348,0.473-0.485
c0.072-0.043,0.161-0.092,0.265-0.147c0.105-0.054,0.208-0.12,0.309-0.195c0.1-0.077,0.184-0.167,0.254-0.269
c0.068-0.104,0.102-0.222,0.102-0.354c0-0.1-0.017-0.188-0.057-0.264c-0.037-0.077-0.088-0.141-0.148-0.193
c-0.062-0.053-0.135-0.092-0.22-0.119c-0.082-0.025-0.167-0.039-0.253-0.039c-0.105,0-0.2,0.019-0.286,0.054
c-0.086,0.036-0.163,0.081-0.232,0.136c-0.069,0.055-0.13,0.116-0.185,0.187c-0.057,0.067-0.103,0.133-0.14,0.196l-0.624-0.428
c0.063-0.148,0.146-0.28,0.248-0.395c0.101-0.114,0.219-0.21,0.351-0.289c0.131-0.079,0.272-0.138,0.425-0.179
C17.751,2.99,17.909,2.97,18.07,2.97c0.18,0,0.36,0.026,0.536,0.079c0.178,0.052,0.334,0.136,0.475,0.25
c0.141,0.115,0.256,0.261,0.346,0.44c0.087,0.177,0.13,0.392,0.13,0.639c0,0.153-0.017,0.287-0.054,0.403
c-0.036,0.118-0.086,0.225-0.153,0.319c-0.067,0.096-0.146,0.182-0.237,0.257c-0.09,0.076-0.193,0.15-0.306,0.22
c-0.095,0.058-0.19,0.112-0.287,0.166c-0.094,0.053-0.182,0.109-0.261,0.175c-0.077,0.063-0.143,0.137-0.193,0.221
c-0.049,0.083-0.074,0.185-0.074,0.304L17.206,6.443L17.206,6.443z M17.221,8.109V7.123h0.791v0.986H17.221L17.221,8.109z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.6 KiB

View File

@@ -1,44 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<g>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#292D32" d="M12.059,22.386c-0.041,0-0.082,0-0.123,0
c-0.031-0.003-0.063-0.008-0.094-0.008c-0.573-0.013-1.135-0.089-1.688-0.232c-1.191-0.312-2.238-0.887-3.144-1.721
c-0.789-0.728-1.392-1.587-1.806-2.576c-0.297-0.71-0.474-1.451-0.538-2.218c-0.042-0.505-0.03-1.008,0.048-1.508
c0.075-0.484,0.193-0.959,0.342-1.427c0.373-1.176,0.894-2.286,1.473-3.37C7.17,8.129,7.887,6.978,8.644,5.851
c0.781-1.162,1.604-2.295,2.47-3.396c0.187-0.237,0.375-0.474,0.568-0.705c0.097-0.115,0.229-0.147,0.376-0.132
c0.147,0.016,0.244,0.105,0.332,0.214c0.998,1.235,1.941,2.511,2.833,3.824c0.88,1.296,1.705,2.625,2.427,4.017
c0.511,0.985,0.968,1.994,1.301,3.056c0.186,0.591,0.328,1.193,0.384,1.812c0.055,0.636,0.01,1.266-0.111,1.892
c-0.159,0.818-0.45,1.589-0.875,2.31c-0.507,0.861-1.163,1.591-1.965,2.189c-0.7,0.521-1.469,0.905-2.306,1.151
c-0.508,0.149-1.027,0.245-1.557,0.278C12.367,22.369,12.212,22.378,12.059,22.386z M11.563,21.496c0-6.072,0-12.131,0-18.201
c-0.018,0.021-0.03,0.035-0.04,0.049c-0.146,0.192-0.292,0.383-0.436,0.575C10.378,4.863,9.698,5.827,9.05,6.813
c-0.732,1.115-1.422,2.256-2.03,3.444c-0.44,0.86-0.837,1.739-1.13,2.662c-0.179,0.561-0.317,1.13-0.364,1.719
c-0.05,0.619,0.003,1.23,0.143,1.834c0.249,1.076,0.744,2.029,1.479,2.855c0.516,0.581,1.119,1.054,1.804,1.42
c0.669,0.356,1.379,0.586,2.128,0.694C11.239,21.465,11.399,21.478,11.563,21.496z"/>
<path fill="#292D32" d="M12.074,22.985h-0.139l0,0l-0.11-0.008c-0.618-0.014-1.232-0.098-1.822-0.251
c-1.28-0.335-2.423-0.961-3.4-1.86c-0.85-0.784-1.507-1.721-1.953-2.786c-0.317-0.757-0.513-1.564-0.582-2.399
c-0.047-0.566-0.029-1.122,0.054-1.65c0.076-0.49,0.195-0.986,0.363-1.516C4.823,11.45,5.304,10.347,6,9.044
c0.591-1.105,1.293-2.26,2.145-3.527c0.788-1.173,1.628-2.328,2.496-3.434c0.19-0.242,0.383-0.482,0.579-0.718
c0.19-0.228,0.464-0.352,0.771-0.352l0.13,0.007c0.42,0.045,0.657,0.337,0.734,0.433c0.996,1.232,1.959,2.533,2.863,3.865
c0.993,1.462,1.799,2.795,2.463,4.077c0.608,1.172,1.034,2.174,1.341,3.152c0.222,0.704,0.355,1.338,0.409,1.938
c0.057,0.662,0.017,1.354-0.12,2.06c-0.172,0.885-0.49,1.726-0.947,2.5c-0.543,0.924-1.258,1.72-2.122,2.365
c-0.758,0.563-1.597,0.982-2.496,1.246c-0.561,0.165-1.128,0.267-1.688,0.302L12.074,22.985z M12.144,2.483l0.019,0.812v18.484
l0.32-0.019c0.471-0.029,0.95-0.115,1.426-0.255c0.763-0.225,1.475-0.58,2.116-1.058c0.735-0.549,1.344-1.227,1.806-2.013
c0.388-0.656,0.658-1.369,0.804-2.119c0.117-0.604,0.15-1.169,0.103-1.726c-0.046-0.511-0.163-1.063-0.358-1.684
c-0.286-0.91-0.687-1.851-1.261-2.96c-0.644-1.238-1.425-2.532-2.391-3.955C13.907,4.786,13.04,3.607,12.144,2.483z M10.962,5.099
C10.473,5.776,10,6.461,9.551,7.144c-0.805,1.226-1.458,2.334-1.997,3.388c-0.496,0.969-0.843,1.785-1.092,2.57
c-0.192,0.604-0.3,1.107-0.338,1.585c-0.043,0.536,0,1.091,0.129,1.651c0.225,0.971,0.677,1.843,1.343,2.592
c0.465,0.522,1.016,0.956,1.639,1.289c0.539,0.287,1.12,0.487,1.728,0.597V5.099z"/>
</g>
<g>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M11.563,21.496c-0.163-0.019-0.324-0.031-0.482-0.054
c-0.75-0.108-1.459-0.338-2.128-0.694c-0.686-0.366-1.288-0.839-1.804-1.42c-0.735-0.826-1.23-1.779-1.479-2.855
c-0.139-0.604-0.193-1.215-0.143-1.834C5.573,14.05,5.711,13.48,5.89,12.92c0.293-0.923,0.689-1.802,1.13-2.662
c0.608-1.188,1.298-2.329,2.03-3.444c0.648-0.986,1.328-1.95,2.037-2.895c0.145-0.192,0.291-0.383,0.436-0.575
c0.01-0.014,0.022-0.027,0.04-0.049C11.563,9.365,11.563,15.424,11.563,21.496z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<path fill="none" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" d="M11.5,21
c5.247,0,9.5-4.254,9.5-9.5C21,6.253,16.746,2,11.5,2C6.253,2,2,6.253,2,11.5C2,16.746,6.253,21,11.5,21z"/>
<path fill="none" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" d="M22,22l-2-2"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 822 B

Some files were not shown because too many files have changed in this diff Show More