diff --git a/Pdf4QtViewer/CMakeLists.txt b/Pdf4QtViewer/CMakeLists.txt index cfcca12..a32dad6 100644 --- a/Pdf4QtViewer/CMakeLists.txt +++ b/Pdf4QtViewer/CMakeLists.txt @@ -47,6 +47,9 @@ add_library(Pdf4QtViewer SHARED pdfsanitizedocumentdialog.ui pdfsanitizedocumentdialog.cpp pdfsanitizedocumentdialog.h + pdfcreatebitonaldocumentdialog.ui + pdfcreatebitonaldocumentdialog.cpp + pdfcreatebitonaldocumentdialog.h pdf4qtviewer.qrc ) diff --git a/Pdf4QtViewer/pdf4qtviewer.qrc b/Pdf4QtViewer/pdf4qtviewer.qrc index 2132b85..2732c21 100644 --- a/Pdf4QtViewer/pdf4qtviewer.qrc +++ b/Pdf4QtViewer/pdf4qtviewer.qrc @@ -102,5 +102,7 @@ resources/book.svg resources/wallet.svg resources/web.svg + resources/create-bitonal-document.svg + resources/sanitize-document.svg diff --git a/Pdf4QtViewer/pdfcreatebitonaldocumentdialog.cpp b/Pdf4QtViewer/pdfcreatebitonaldocumentdialog.cpp new file mode 100644 index 0000000..62a8856 --- /dev/null +++ b/Pdf4QtViewer/pdfcreatebitonaldocumentdialog.cpp @@ -0,0 +1,85 @@ +// 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 . + +#include "pdfcreateBitonaldocumentdialog.h" +#include "ui_pdfcreateBitonaldocumentdialog.h" + +#include "pdfwidgetutils.h" +#include "pdfdocumentwriter.h" +#include "pdfdbgheap.h" + +#include +#include +#include +#include + +namespace pdfviewer +{ + +PDFCreateBitonalDocumentDialog::PDFCreateBitonalDocumentDialog(const pdf::PDFDocument* document, QWidget* parent) : + QDialog(parent), + ui(new Ui::PDFCreateBitonalDocumentDialog), + m_document(document), + m_createBitonalDocumentButton(nullptr), + m_conversionInProgress(false), + m_processed(false) +{ + ui->setupUi(this); + + m_createBitonalDocumentButton = ui->buttonBox->addButton(tr("Process"), 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); + + pdf::PDFWidgetUtils::scaleWidget(this, QSize(640, 380)); + updateUi(); + pdf::PDFWidgetUtils::style(this); +} + +PDFCreateBitonalDocumentDialog::~PDFCreateBitonalDocumentDialog() +{ + Q_ASSERT(!m_conversionInProgress); + Q_ASSERT(!m_future.isRunning()); + + delete ui; +} + +void PDFCreateBitonalDocumentDialog::createBitonalDocument() +{ + +} + +void PDFCreateBitonalDocumentDialog::onCreateBitonalDocumentButtonClicked() +{ + Q_ASSERT(!m_conversionInProgress); + Q_ASSERT(!m_future.isRunning()); + + m_conversionInProgress = true; + m_future = QtConcurrent::run([this]() { createBitonalDocument(); }); + updateUi(); +} + +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); +} + +} // namespace pdfviewer diff --git a/Pdf4QtViewer/pdfcreatebitonaldocumentdialog.h b/Pdf4QtViewer/pdfcreatebitonaldocumentdialog.h new file mode 100644 index 0000000..d45adee --- /dev/null +++ b/Pdf4QtViewer/pdfcreatebitonaldocumentdialog.h @@ -0,0 +1,61 @@ +// 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 . + +#ifndef PDFCREATEBITONALDOCUMENTDIALOG_H +#define PDFCREATEBITONALDOCUMENTDIALOG_H + +#include "pdfdocument.h" + +#include +#include + +namespace Ui +{ +class PDFCreateBitonalDocumentDialog; +} + +namespace pdfviewer +{ + +class PDFCreateBitonalDocumentDialog : public QDialog +{ + Q_OBJECT + +public: + explicit PDFCreateBitonalDocumentDialog(const pdf::PDFDocument* document, QWidget* parent); + virtual ~PDFCreateBitonalDocumentDialog() override; + + pdf::PDFDocument takeBitonaldDocument() { return qMove(m_bitonalDocument); } + +private: + void createBitonalDocument(); + void onCreateBitonalDocumentButtonClicked(); + + void updateUi(); + + Ui::PDFCreateBitonalDocumentDialog* ui; + const pdf::PDFDocument* m_document; + QPushButton* m_createBitonalDocumentButton; + bool m_conversionInProgress; + bool m_processed; + QFuture m_future; + pdf::PDFDocument m_bitonalDocument; +}; + +} // namespace pdfviewer + +#endif // PDFCREATEBITONALDOCUMENTDIALOG_H diff --git a/Pdf4QtViewer/pdfcreatebitonaldocumentdialog.ui b/Pdf4QtViewer/pdfcreatebitonaldocumentdialog.ui new file mode 100644 index 0000000..d877c0d --- /dev/null +++ b/Pdf4QtViewer/pdfcreatebitonaldocumentdialog.ui @@ -0,0 +1,158 @@ + + + PDFCreateBitonalDocumentDialog + + + + 0 + 0 + 741 + 530 + + + + Create Bitonal Document + + + + + + + 1 + + + + + + + + Color to Bitonal Conversion Options + + + + + + Automatic (Otsu's 1D method) + + + true + + + + + + + 255 + + + 128 + + + + + + + User-Defined Intensity Threshold (0-255): + + + + + + + + + + + + + + + 255 + 255 + 255 + + + + + + + + + 240 + 240 + 240 + + + + + + + + + 255 + 255 + 255 + + + + + + + + + + + + + + + + + 255 + 255 + 255 + + + + + + + + + 240 + 240 + 240 + + + + + + + + + 255 + 255 + 255 + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + diff --git a/Pdf4QtViewer/pdfprogramcontroller.cpp b/Pdf4QtViewer/pdfprogramcontroller.cpp index 7e66eb8..3feec4a 100644 --- a/Pdf4QtViewer/pdfprogramcontroller.cpp +++ b/Pdf4QtViewer/pdfprogramcontroller.cpp @@ -33,6 +33,7 @@ #include "pdfrendertoimagesdialog.h" #include "pdfoptimizedocumentdialog.h" #include "pdfsanitizedocumentdialog.h" +#include "pdfcreatebitonaldocumentdialog.h" #include "pdfviewersettingsdialog.h" #include "pdfaboutdialog.h" #include "pdfrenderingerrorswidget.h" @@ -458,6 +459,10 @@ void PDFProgramController::initialize(Features features, { connect(action, &QAction::triggered, this, &PDFProgramController::onActionSanitizeTriggered); } + if (QAction* action = m_actionManager->getAction(PDFActionManager::CreateBitonalDocument)) + { + connect(action, &QAction::triggered, this, &PDFProgramController::onActionCreateBitonalDocumentTriggered); + } if (QAction* action = m_actionManager->getAction(PDFActionManager::Encryption)) { connect(action, &QAction::triggered, this, &PDFProgramController::onActionEncryptionTriggered); @@ -1249,6 +1254,18 @@ void PDFProgramController::onActionSanitizeTriggered() } } +void PDFProgramController::onActionCreateBitonalDocumentTriggered() +{ + PDFCreateBitonalDocumentDialog dialog(m_pdfDocument.data(), m_mainWindow); + + if (dialog.exec() == QDialog::Accepted) + { + pdf::PDFDocumentPointer pointer(new pdf::PDFDocument(dialog.takeBitonaldDocument())); + pdf::PDFModifiedDocument document(qMove(pointer), m_optionalContentActivity, pdf::PDFModifiedDocument::ModificationFlags(pdf::PDFModifiedDocument::Reset | pdf::PDFModifiedDocument::PreserveUndoRedo)); + onDocumentModified(qMove(document)); + } +} + void PDFProgramController::onActionEncryptionTriggered() { auto queryPassword = [this](bool* ok) @@ -1569,6 +1586,7 @@ void PDFProgramController::updateActionsAvailability() m_actionManager->setEnabled(PDFActionManager::RenderToImages, hasValidDocument && canPrint); m_actionManager->setEnabled(PDFActionManager::Optimize, hasValidDocument); m_actionManager->setEnabled(PDFActionManager::Sanitize, hasValidDocument); + m_actionManager->setEnabled(PDFActionManager::CreateBitonalDocument, hasValidDocument); m_actionManager->setEnabled(PDFActionManager::Encryption, hasValidDocument); m_actionManager->setEnabled(PDFActionManager::Save, hasValidDocument); m_actionManager->setEnabled(PDFActionManager::SaveAs, hasValidDocument); diff --git a/Pdf4QtViewer/pdfprogramcontroller.h b/Pdf4QtViewer/pdfprogramcontroller.h index 4a3fbdf..d248224 100644 --- a/Pdf4QtViewer/pdfprogramcontroller.h +++ b/Pdf4QtViewer/pdfprogramcontroller.h @@ -109,6 +109,7 @@ public: RenderToImages, Optimize, Sanitize, + CreateBitonalDocument, Encryption, FitPage, FitWidth, @@ -337,6 +338,7 @@ private: void onActionRenderToImagesTriggered(); void onActionOptimizeTriggered(); void onActionSanitizeTriggered(); + void onActionCreateBitonalDocumentTriggered(); void onActionEncryptionTriggered(); void onActionFitPageTriggered(); void onActionFitWidthTriggered(); diff --git a/Pdf4QtViewer/pdfviewermainwindow.cpp b/Pdf4QtViewer/pdfviewermainwindow.cpp index 16b0fe4..037a194 100644 --- a/Pdf4QtViewer/pdfviewermainwindow.cpp +++ b/Pdf4QtViewer/pdfviewermainwindow.cpp @@ -164,6 +164,7 @@ PDFViewerMainWindow::PDFViewerMainWindow(QWidget* parent) : 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); diff --git a/Pdf4QtViewer/pdfviewermainwindow.ui b/Pdf4QtViewer/pdfviewermainwindow.ui index f1a0959..d7b3ffa 100644 --- a/Pdf4QtViewer/pdfviewermainwindow.ui +++ b/Pdf4QtViewer/pdfviewermainwindow.ui @@ -144,8 +144,9 @@ - + + @@ -952,6 +953,10 @@ + + + :/resources/sanitize-document.svg:/resources/sanitize-document.svg + Sanitize... @@ -979,6 +984,21 @@ Become a Sponsor + + + + :/resources/create-bitonal-document.svg:/resources/create-bitonal-document.svg + + + Create Bitonal Document... + + + Create Bitonal Document + + + Convert the colored images to monochromatic to create a bitonal document. + + diff --git a/Pdf4QtViewer/resources/create-bitonal-document.svg b/Pdf4QtViewer/resources/create-bitonal-document.svg new file mode 100644 index 0000000..6c113a7 --- /dev/null +++ b/Pdf4QtViewer/resources/create-bitonal-document.svg @@ -0,0 +1,58 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/Pdf4QtViewer/resources/sanitize-document.svg b/Pdf4QtViewer/resources/sanitize-document.svg new file mode 100644 index 0000000..74b5120 --- /dev/null +++ b/Pdf4QtViewer/resources/sanitize-document.svg @@ -0,0 +1,58 @@ + + + + + + + + image/svg+xml + + + + + + + + +