Encryption settings dialog

This commit is contained in:
Jakub Melka 2021-05-21 19:00:25 +02:00
parent f070f0eb01
commit 759d5c7793
12 changed files with 646 additions and 2 deletions

View File

@ -41,6 +41,8 @@ SOURCES += \
pdfaboutdialog.cpp \
pdfadvancedfindwidget.cpp \
pdfdocumentpropertiesdialog.cpp \
pdfencryptionsettingsdialog.cpp \
pdfencryptionstrengthhintwidget.cpp \
pdfoptimizedocumentdialog.cpp \
pdfprogramcontroller.cpp \
pdfrecentfilemanager.cpp \
@ -58,6 +60,8 @@ HEADERS += \
pdfaboutdialog.h \
pdfadvancedfindwidget.h \
pdfdocumentpropertiesdialog.h \
pdfencryptionsettingsdialog.h \
pdfencryptionstrengthhintwidget.h \
pdfoptimizedocumentdialog.h \
pdfprogramcontroller.h \
pdfrecentfilemanager.h \
@ -76,6 +80,7 @@ FORMS += \
pdfaboutdialog.ui \
pdfadvancedfindwidget.ui \
pdfdocumentpropertiesdialog.ui \
pdfencryptionsettingsdialog.ui \
pdfoptimizedocumentdialog.ui \
pdfrendertoimagesdialog.ui \
pdfsidebarwidget.ui \

View File

@ -0,0 +1,40 @@
// 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/>.
#include "pdfencryptionsettingsdialog.h"
#include "ui_pdfencryptionsettingsdialog.h"
namespace pdfviewer
{
PDFEncryptionSettingsDialog::PDFEncryptionSettingsDialog(QWidget* parent) :
QDialog(parent),
ui(new Ui::PDFEncryptionSettingsDialog)
{
ui->setupUi(this);
ui->algorithmHintWidget->setFixedSize(ui->algorithmHintWidget->minimumSizeHint());
ui->userPasswordStrengthHintWidget->setFixedSize(ui->userPasswordStrengthHintWidget->minimumSizeHint());
ui->ownerPasswordStrengthHintWidget->setFixedSize(ui->ownerPasswordStrengthHintWidget->minimumSizeHint());
}
PDFEncryptionSettingsDialog::~PDFEncryptionSettingsDialog()
{
delete ui;
}
} // namespace pdfviewer

View File

@ -0,0 +1,48 @@
// 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 <QDialog>
namespace Ui
{
class PDFEncryptionSettingsDialog;
}
namespace pdfviewer
{
class PDFEncryptionSettingsDialog : public QDialog
{
Q_OBJECT
public:
explicit PDFEncryptionSettingsDialog(QWidget* parent);
virtual ~PDFEncryptionSettingsDialog() override;
private:
Ui::PDFEncryptionSettingsDialog* ui;
};
} // namespace pdfviewer
#endif // PDFENCRYPTIONSETTINGSDIALOG_H

View File

@ -0,0 +1,248 @@
<?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>705</width>
<height>609</height>
</rect>
</property>
<property name="windowTitle">
<string>Encryption Settings</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QGroupBox" name="encryptionMethodGroupBox">
<property name="title">
<string>Encryption Method</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="1">
<widget class="QComboBox" name="algotithmComboBox"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="encryptionAlgorithm">
<property name="text">
<string>Encryption algorithm</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="pdfviewer::PDFEncryptionStrengthHintWidget" name="algorithmHintWidget" native="true"/>
</item>
<item row="1" 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;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="passwordsGroupBox">
<property name="title">
<string>Passwords</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
<widget class="QCheckBox" name="ownerPasswordEnableCheckBox">
<property name="text">
<string>Password (owner access)</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="userPasswordEnableCheckBox">
<property name="text">
<string>Password (document open)</string>
</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="0" column="2">
<widget class="pdfviewer::PDFEncryptionStrengthHintWidget" name="userPasswordStrengthHintWidget" native="true"/>
</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="1" column="2">
<widget class="pdfviewer::PDFEncryptionStrengthHintWidget" name="ownerPasswordStrengthHintWidget" native="true"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="encryptContentsGroupBox">
<property name="title">
<string>Encrypt Contents</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QRadioButton" name="encryptAllRadioButton">
<property name="text">
<string>Encrypt all document contents, including document metadata</string>
</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="gridLayout_2">
<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="checkBox_3">
<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="checkBox_4">
<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="checkBox_5">
<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="checkBox_6">
<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>
<customwidgets>
<customwidget>
<class>pdfviewer::PDFEncryptionStrengthHintWidget</class>
<extends>QWidget</extends>
<header>pdfencryptionstrengthhintwidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<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

@ -0,0 +1,172 @@
// 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/>.
#include "pdfencryptionstrengthhintwidget.h"
#include "pdfwidgetutils.h"
#include "pdfutils.h"
#include <QPainter>
#include <QFontMetrics>
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;
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;
}
Q_ASSERT(currentLevel >= 0);
Q_ASSERT(currentLevel < m_levels.size());
QColor 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();
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.width(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

@ -0,0 +1,76 @@
// 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,3 +1,20 @@
// 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/>.
#include "pdfoptimizedocumentdialog.h"
#include "ui_pdfoptimizedocumentdialog.h"

View File

@ -1,3 +1,20 @@
// 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

View File

@ -35,6 +35,7 @@
#include "pdfsendmail.h"
#include "pdfrecentfilemanager.h"
#include "pdftexttospeech.h"
#include "pdfencryptionsettingsdialog.h"
#include <QMenu>
#include <QPrinter>
@ -443,6 +444,10 @@ void PDFProgramController::initialize(Features features,
{
connect(action, &QAction::triggered, this, &PDFProgramController::onActionOptimizeTriggered);
}
if (QAction* action = m_actionManager->getAction(PDFActionManager::Encryption))
{
connect(action, &QAction::triggered, this, &PDFProgramController::onActionEncryptionTriggered);
}
if (QAction* action = m_actionManager->getAction(PDFActionManager::FitPage))
{
connect(action, &QAction::triggered, this, &PDFProgramController::onActionFitPageTriggered);
@ -1126,6 +1131,12 @@ void PDFProgramController::onActionOptimizeTriggered()
}
}
void PDFProgramController::onActionEncryptionTriggered()
{
PDFEncryptionSettingsDialog dialog(m_mainWindow);
dialog.exec();
}
void PDFProgramController::onActionFitPageTriggered()
{
m_pdfWidget->getDrawWidgetProxy()->performOperation(pdf::PDFDrawWidgetProxy::ZoomFit);
@ -1354,6 +1365,7 @@ void PDFProgramController::updateActionsAvailability()
m_actionManager->setEnabled(PDFActionManager::Print, hasValidDocument && canPrint);
m_actionManager->setEnabled(PDFActionManager::RenderToImages, hasValidDocument && canPrint);
m_actionManager->setEnabled(PDFActionManager::Optimize, hasValidDocument);
m_actionManager->setEnabled(PDFActionManager::Encryption, hasValidDocument);
m_actionManager->setEnabled(PDFActionManager::Save, hasValidDocument);
m_actionManager->setEnabled(PDFActionManager::SaveAs, hasValidDocument);
m_actionManager->setEnabled(PDFActionManager::Properties, hasDocument);

View File

@ -103,6 +103,7 @@ public:
SendByMail,
RenderToImages,
Optimize,
Encryption,
FitPage,
FitWidth,
FitHeight,
@ -318,6 +319,7 @@ private:
void onActionSendByEMailTriggered();
void onActionRenderToImagesTriggered();
void onActionOptimizeTriggered();
void onActionEncryptionTriggered();
void onActionFitPageTriggered();
void onActionFitWidthTriggered();
void onActionFitHeightTriggered();

View File

@ -163,6 +163,7 @@ PDFViewerMainWindow::PDFViewerMainWindow(QWidget* parent) :
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::Encryption, ui->actionEncryption);
m_actionManager->setAction(PDFActionManager::FitPage, ui->actionFitPage);
m_actionManager->setAction(PDFActionManager::FitWidth, ui->actionFitWidth);
m_actionManager->setAction(PDFActionManager::FitHeight, ui->actionFitHeight);

View File

@ -135,6 +135,7 @@
<addaction name="actionSelectTextAll"/>
<addaction name="actionDeselectText"/>
<addaction name="separator"/>
<addaction name="actionEncryption"/>
<addaction name="actionOptimize"/>
<addaction name="separator"/>
</widget>
@ -397,7 +398,7 @@
<normaloff>:/resources/info.svg</normaloff>:/resources/info.svg</iconset>
</property>
<property name="text">
<string>Properties</string>
<string>Properties...</string>
</property>
</action>
<action name="actionSend_by_E_Mail">
@ -586,7 +587,7 @@
</action>
<action name="actionOptimize">
<property name="text">
<string>Optimize</string>
<string>Optimize...</string>
</property>
</action>
<action name="actionSave_As">
@ -827,6 +828,11 @@
<string>Get Source</string>
</property>
</action>
<action name="actionEncryption">
<property name="text">
<string>Encryption...</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>