mirror of https://github.com/JakubMelka/PDF4QT.git
Progress bar for windows taskbar button
This commit is contained in:
parent
eab366b90d
commit
11bdba0580
|
@ -46,6 +46,7 @@ SOURCES += \
|
|||
sources/pdfdocument.cpp \
|
||||
sources/pdfdocumentreader.cpp \
|
||||
sources/pdfpattern.cpp \
|
||||
sources/pdfprogress.cpp \
|
||||
sources/pdfsecurityhandler.cpp \
|
||||
sources/pdfutils.cpp \
|
||||
sources/pdfxreftable.cpp \
|
||||
|
@ -80,6 +81,7 @@ HEADERS += \
|
|||
sources/pdfdocument.h \
|
||||
sources/pdfdocumentreader.h \
|
||||
sources/pdfpattern.h \
|
||||
sources/pdfprogress.h \
|
||||
sources/pdfsecurityhandler.h \
|
||||
sources/pdfxreftable.h \
|
||||
sources/pdfflatmap.h \
|
||||
|
|
|
@ -33,9 +33,10 @@
|
|||
namespace pdf
|
||||
{
|
||||
|
||||
PDFDocumentReader::PDFDocumentReader(const std::function<QString(bool*)>& getPasswordCallback) :
|
||||
PDFDocumentReader::PDFDocumentReader(PDFProgress* progress, const std::function<QString(bool*)>& getPasswordCallback) :
|
||||
m_result(Result::OK),
|
||||
m_getPasswordCallback(getPasswordCallback)
|
||||
m_getPasswordCallback(getPasswordCallback),
|
||||
m_progress(progress)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -253,6 +254,8 @@ PDFDocument PDFDocumentReader::readFromBuffer(const QByteArray& buffer)
|
|||
PDFParsingContext context(objectFetcher);
|
||||
PDFObject object = getObject(&context, entry.offset, entry.reference);
|
||||
|
||||
progressStep();
|
||||
|
||||
QMutexLocker lock(&m_mutex);
|
||||
objects[entry.reference.objectNumber] = PDFObjectStorage::Entry(entry.reference.generation, object);
|
||||
}
|
||||
|
@ -266,7 +269,9 @@ PDFDocument PDFDocumentReader::readFromBuffer(const QByteArray& buffer)
|
|||
};
|
||||
|
||||
// Now, we are ready to scan all objects
|
||||
progressStart(occupiedEntries.size());
|
||||
std::for_each(std::execution::parallel_policy(), occupiedEntries.cbegin(), occupiedEntries.cend(), processEntry);
|
||||
progressFinish();
|
||||
|
||||
if (m_result != Result::OK)
|
||||
{
|
||||
|
@ -351,8 +356,10 @@ PDFDocument PDFDocumentReader::readFromBuffer(const QByteArray& buffer)
|
|||
// decipher object streams here. 4) must be handled in the security handler.
|
||||
if (securityHandler->getMode() != EncryptionMode::None)
|
||||
{
|
||||
auto decryptEntry = [encryptObjectReference, &securityHandler, &objects](const PDFXRefTable::Entry& entry)
|
||||
auto decryptEntry = [this, encryptObjectReference, &securityHandler, &objects](const PDFXRefTable::Entry& entry)
|
||||
{
|
||||
progressStep();
|
||||
|
||||
if (encryptObjectReference.objectNumber != 0 && encryptObjectReference == entry.reference)
|
||||
{
|
||||
// 2) - Encrypt dictionary
|
||||
|
@ -362,7 +369,9 @@ PDFDocument PDFDocumentReader::readFromBuffer(const QByteArray& buffer)
|
|||
objects[entry.reference.objectNumber].object = securityHandler->decryptObject(objects[entry.reference.objectNumber].object, entry.reference);
|
||||
};
|
||||
|
||||
progressStart(occupiedEntries.size());
|
||||
std::for_each(std::execution::parallel_policy(), occupiedEntries.cbegin(), occupiedEntries.cend(), decryptEntry);
|
||||
progressFinish();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
|
@ -520,4 +529,28 @@ int PDFDocumentReader::findFromEnd(const char* what, const QByteArray& byteArray
|
|||
return FIND_NOT_FOUND_RESULT;
|
||||
}
|
||||
|
||||
void PDFDocumentReader::progressStart(size_t stepCount)
|
||||
{
|
||||
if (m_progress)
|
||||
{
|
||||
m_progress->start(stepCount);
|
||||
}
|
||||
}
|
||||
|
||||
void PDFDocumentReader::progressStep()
|
||||
{
|
||||
if (m_progress)
|
||||
{
|
||||
m_progress->step();
|
||||
}
|
||||
}
|
||||
|
||||
void PDFDocumentReader::progressFinish()
|
||||
{
|
||||
if (m_progress)
|
||||
{
|
||||
m_progress->finish();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace pdf
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "pdfglobal.h"
|
||||
#include "pdfdocument.h"
|
||||
#include "pdfprogress.h"
|
||||
|
||||
#include <QtCore>
|
||||
#include <QIODevice>
|
||||
|
@ -36,7 +37,7 @@ class PDFFORQTLIBSHARED_EXPORT PDFDocumentReader
|
|||
Q_DECLARE_TR_FUNCTIONS(pdf::PDFDocumentReader)
|
||||
|
||||
public:
|
||||
explicit PDFDocumentReader(const std::function<QString(bool*)>& getPasswordCallback);
|
||||
explicit PDFDocumentReader(PDFProgress* progress, const std::function<QString(bool*)>& getPasswordCallback);
|
||||
|
||||
constexpr inline PDFDocumentReader(const PDFDocumentReader&) = delete;
|
||||
constexpr inline PDFDocumentReader(PDFDocumentReader&&) = delete;
|
||||
|
@ -86,6 +87,10 @@ private:
|
|||
/// \returns Position of string, or FIND_NOT_FOUND_RESULT
|
||||
int findFromEnd(const char* what, const QByteArray& byteArray, int limit);
|
||||
|
||||
void progressStart(size_t stepCount);
|
||||
void progressStep();
|
||||
void progressFinish();
|
||||
|
||||
/// Mutex for access to variables of this reader from more threads
|
||||
/// (providing thread safety)
|
||||
QMutex m_mutex;
|
||||
|
@ -101,6 +106,9 @@ private:
|
|||
|
||||
/// Callback to obtain password from the user
|
||||
std::function<QString(bool*)> m_getPasswordCallback;
|
||||
|
||||
/// Progress indicator
|
||||
PDFProgress* m_progress;
|
||||
};
|
||||
|
||||
} // namespace pdf
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
// Copyright (C) 2019 Jakub Melka
|
||||
//
|
||||
// This file is part of PdfForQt.
|
||||
//
|
||||
// PdfForQt is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// PdfForQt is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with PDFForQt. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "pdfprogress.h"
|
||||
|
||||
namespace pdf
|
||||
{
|
||||
|
||||
void PDFProgress::start(size_t stepCount)
|
||||
{
|
||||
Q_ASSERT(stepCount > 0);
|
||||
|
||||
m_currentStep = 0;
|
||||
m_stepCount = stepCount;
|
||||
m_percentage = 0;
|
||||
|
||||
emit progressStarted();
|
||||
}
|
||||
|
||||
void PDFProgress::step()
|
||||
{
|
||||
// Atomically increment by one. We must add + 1 to the current step,
|
||||
// because fetch_add will return old value. Then we must test, if percentage
|
||||
// has been changed.
|
||||
size_t currentStep = m_currentStep.fetch_add(1) + 1;
|
||||
|
||||
int newPercentage = int((size_t(100) * currentStep) / m_stepCount);
|
||||
int oldPercentage = m_percentage.load(std::memory_order_acquire);
|
||||
bool emitSignal = oldPercentage < newPercentage;
|
||||
do
|
||||
{
|
||||
emitSignal = oldPercentage < newPercentage;
|
||||
} while (oldPercentage < newPercentage && !m_percentage.compare_exchange_weak(oldPercentage, newPercentage, std::memory_order_release, std::memory_order_relaxed));
|
||||
|
||||
if (emitSignal)
|
||||
{
|
||||
progressStep(newPercentage);
|
||||
}
|
||||
}
|
||||
|
||||
void PDFProgress::finish()
|
||||
{
|
||||
emit progressFinished();
|
||||
}
|
||||
|
||||
} // namespace pdf
|
|
@ -0,0 +1,54 @@
|
|||
// Copyright (C) 2019 Jakub Melka
|
||||
//
|
||||
// This file is part of PdfForQt.
|
||||
//
|
||||
// PdfForQt is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// PdfForQt is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with PDFForQt. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef PDFPROGRESS_H
|
||||
#define PDFPROGRESS_H
|
||||
|
||||
#include "pdfglobal.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include <atomic>
|
||||
|
||||
namespace pdf
|
||||
{
|
||||
|
||||
class PDFFORQTLIBSHARED_EXPORT PDFProgress : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PDFProgress(QObject* parent) : QObject(parent) { }
|
||||
|
||||
void start(size_t stepCount);
|
||||
void step();
|
||||
void finish();
|
||||
|
||||
signals:
|
||||
void progressStarted();
|
||||
void progressStep(int percentage);
|
||||
void progressFinished();
|
||||
|
||||
private:
|
||||
std::atomic<size_t> m_currentStep = 0;
|
||||
std::atomic<size_t> m_stepCount = 0;
|
||||
std::atomic<int> m_percentage = 0;
|
||||
};
|
||||
|
||||
} // namespace pdf
|
||||
|
||||
#endif // PDFPROGRESS_H
|
|
@ -4,7 +4,7 @@
|
|||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += core gui
|
||||
QT += core gui winextras
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
|
|
|
@ -61,10 +61,16 @@ PDFViewerMainWindow::PDFViewerMainWindow(QWidget *parent) :
|
|||
m_pageNumberSpinBox(nullptr),
|
||||
m_pageNumberLabel(nullptr),
|
||||
m_pageZoomSpinBox(nullptr),
|
||||
m_isLoadingUI(false)
|
||||
m_isLoadingUI(false),
|
||||
m_progress(new pdf::PDFProgress(this)),
|
||||
m_taskbarButton(new QWinTaskbarButton(this)),
|
||||
m_progressTaskbarIndicator(nullptr)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
// Initialize task bar progress
|
||||
m_progressTaskbarIndicator = m_taskbarButton->progress();
|
||||
|
||||
// Initialize shortcuts
|
||||
ui->actionOpen->setShortcut(QKeySequence::Open);
|
||||
ui->actionClose->setShortcut(QKeySequence::Close);
|
||||
|
@ -164,6 +170,9 @@ PDFViewerMainWindow::PDFViewerMainWindow(QWidget *parent) :
|
|||
connect(m_pdfWidget->getDrawWidgetProxy(), &pdf::PDFDrawWidgetProxy::pageLayoutChanged, this, &PDFViewerMainWindow::onPageLayoutChanged);
|
||||
connect(m_pdfWidget, &pdf::PDFWidget::pageRenderingErrorsChanged, this, &PDFViewerMainWindow::onPageRenderingErrorsChanged, Qt::QueuedConnection);
|
||||
connect(m_settings, &PDFViewerSettings::settingsChanged, this, &PDFViewerMainWindow::onViewerSettingsChanged);
|
||||
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);
|
||||
|
||||
updatePageLayoutActions();
|
||||
updateUI(true);
|
||||
|
@ -242,6 +251,23 @@ void PDFViewerMainWindow::onPageZoomSpinboxEditingFinished()
|
|||
m_pdfWidget->getDrawWidgetProxy()->zoom(m_pageZoomSpinBox->value() / 100.0);
|
||||
}
|
||||
|
||||
void PDFViewerMainWindow::onProgressStarted()
|
||||
{
|
||||
m_progressTaskbarIndicator->setRange(0, 100);
|
||||
m_progressTaskbarIndicator->reset();
|
||||
m_progressTaskbarIndicator->show();
|
||||
}
|
||||
|
||||
void PDFViewerMainWindow::onProgressStep(int percentage)
|
||||
{
|
||||
m_progressTaskbarIndicator->setValue(percentage);
|
||||
}
|
||||
|
||||
void PDFViewerMainWindow::onProgressFinished()
|
||||
{
|
||||
m_progressTaskbarIndicator->hide();
|
||||
}
|
||||
|
||||
void PDFViewerMainWindow::readSettings()
|
||||
{
|
||||
QSettings settings(QSettings::IniFormat, QSettings::UserScope, QCoreApplication::organizationName(), QCoreApplication::applicationName());
|
||||
|
@ -403,7 +429,7 @@ void PDFViewerMainWindow::openDocument(const QString& fileName)
|
|||
|
||||
// Try to open a new document
|
||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
pdf::PDFDocumentReader reader(qMove(getPasswordCallback));
|
||||
pdf::PDFDocumentReader reader(m_progress, qMove(getPasswordCallback));
|
||||
pdf::PDFDocument document = reader.readFromFile(fileName);
|
||||
QApplication::restoreOverrideCursor();
|
||||
|
||||
|
@ -497,6 +523,12 @@ void PDFViewerMainWindow::closeEvent(QCloseEvent* event)
|
|||
event->accept();
|
||||
}
|
||||
|
||||
void PDFViewerMainWindow::showEvent(QShowEvent* event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
m_taskbarButton->setWindow(windowHandle());
|
||||
}
|
||||
|
||||
void PDFViewerMainWindow::on_actionPageLayoutSinglePage_triggered()
|
||||
{
|
||||
setPageLayout(pdf::PageLayout::SinglePage);
|
||||
|
|
|
@ -20,12 +20,14 @@
|
|||
|
||||
#include "pdfcatalog.h"
|
||||
#include "pdfrenderer.h"
|
||||
|
||||
#include "pdfprogress.h"
|
||||
#include "pdfviewersettings.h"
|
||||
|
||||
#include <QTreeView>
|
||||
#include <QMainWindow>
|
||||
#include <QSharedPointer>
|
||||
#include <QWinTaskbarButton>
|
||||
#include <QWinTaskbarProgress>
|
||||
|
||||
class QLabel;
|
||||
class QSpinBox;
|
||||
|
@ -56,6 +58,7 @@ public:
|
|||
virtual ~PDFViewerMainWindow() override;
|
||||
|
||||
virtual void closeEvent(QCloseEvent* event) override;
|
||||
virtual void showEvent(QShowEvent* event) override;
|
||||
|
||||
private slots:
|
||||
void on_actionPageLayoutSinglePage_triggered();
|
||||
|
@ -77,6 +80,10 @@ private:
|
|||
void onPageNumberSpinboxEditingFinished();
|
||||
void onPageZoomSpinboxEditingFinished();
|
||||
|
||||
void onProgressStarted();
|
||||
void onProgressStep(int percentage);
|
||||
void onProgressFinished();
|
||||
|
||||
void readSettings();
|
||||
void writeSettings();
|
||||
|
||||
|
@ -111,6 +118,9 @@ private:
|
|||
QLabel* m_pageNumberLabel;
|
||||
QDoubleSpinBox* m_pageZoomSpinBox;
|
||||
bool m_isLoadingUI;
|
||||
pdf::PDFProgress* m_progress;
|
||||
QWinTaskbarButton* m_taskbarButton;
|
||||
QWinTaskbarProgress* m_progressTaskbarIndicator;
|
||||
};
|
||||
|
||||
} // namespace pdfviewer
|
||||
|
|
Loading…
Reference in New Issue