mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
Progress bar for windows taskbar button
This commit is contained in:
@@ -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
|
||||
|
60
PdfForQtLib/sources/pdfprogress.cpp
Normal file
60
PdfForQtLib/sources/pdfprogress.cpp
Normal file
@@ -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
|
54
PdfForQtLib/sources/pdfprogress.h
Normal file
54
PdfForQtLib/sources/pdfprogress.h
Normal file
@@ -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
|
Reference in New Issue
Block a user