mirror of
				https://github.com/JakubMelka/PDF4QT.git
				synced 2025-06-05 21:59:17 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			561 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			561 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
//    Copyright (C) 2019-2020 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
 | 
						|
//    (at your option) 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 <execution>
 | 
						|
 | 
						|
namespace pdfviewer
 | 
						|
{
 | 
						|
 | 
						|
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));
 | 
						|
}
 | 
						|
 | 
						|
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.type() == QVariant::DateTime) ? 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::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") });
 | 
						|
                                        font->dumpFontToTreeItem(fontRootItem);
 | 
						|
                                        realizedFont->dumpFontToTreeItem(fontRootItem);
 | 
						|
 | 
						|
                                        // Separator item
 | 
						|
                                        new QTreeWidgetItem(fontRootItem, QStringList());
 | 
						|
 | 
						|
                                        // Finally add the tree item
 | 
						|
                                        QMutexLocker lock(&fontTreeItemMutex);
 | 
						|
                                        m_fontTreeWidgetItems.push_back(fontRootItemPtr.release());
 | 
						|
                                    }
 | 
						|
                                }
 | 
						|
                            }
 | 
						|
                            catch (pdf::PDFException)
 | 
						|
                            {
 | 
						|
                                // Do nothing, some error occured, continue with next font
 | 
						|
                                continue;
 | 
						|
                            }
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
            catch (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) < right->data(0, Qt::DisplayRole); });
 | 
						|
        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
 |