DocDiff application: basic functionality, opening documents

This commit is contained in:
Jakub Melka
2021-09-05 18:13:06 +02:00
parent ba13871a9c
commit e354a03564
13 changed files with 1088 additions and 16 deletions

View File

@ -16,23 +16,34 @@
// along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#include "pdfdiff.h"
#include "pdfdocumenttextflow.h"
#include <QtConcurrent/QtConcurrent>
namespace pdf
{
PDFDiff::PDFDiff(QObject* parent) :
BaseClass(parent),
m_progress(nullptr),
m_leftDocument(nullptr),
m_rightDocument(nullptr)
m_rightDocument(nullptr),
m_options(Asynchronous),
m_cancelled(false)
{
}
PDFDiff::~PDFDiff()
{
stop();
}
void PDFDiff::setLeftDocument(const PDFDocument* leftDocument)
{
if (m_leftDocument != leftDocument)
{
clear();
stop();
m_leftDocument = leftDocument;
}
}
@ -41,15 +52,147 @@ void PDFDiff::setRightDocument(const PDFDocument* rightDocument)
{
if (m_rightDocument != rightDocument)
{
clear();
stop();
m_rightDocument = rightDocument;
}
}
void PDFDiff::clear()
void PDFDiff::setPagesForLeftDocument(PDFClosedIntervalSet pagesForLeftDocument)
{
stopEngine();
stop();
m_pagesForLeftDocument = std::move(pagesForLeftDocument);
}
void PDFDiff::setPagesForRightDocument(PDFClosedIntervalSet pagesForRightDocument)
{
stop();
m_pagesForRightDocument = std::move(pagesForRightDocument);
}
void PDFDiff::start()
{
// Jakub Melka: First, we must ensure, that comparation
// process is finished, otherwise we must wait for end.
// Then, create a new future watcher.
stop();
m_cancelled = false;
if (m_options.testFlag(Asynchronous))
{
m_futureWatcher = std::nullopt;
m_futureWatcher.emplace();
m_future = QtConcurrent::run(std::bind(&PDFDiff::perform, this));
connect(&*m_futureWatcher, &QFutureWatcher<PDFDiffResult>::finished, this, &PDFDiff::onComparationPerformed);
m_futureWatcher->setFuture(m_future);
}
else
{
// Just do comparation immediately
m_result = perform();
emit comparationFinished();
}
}
void PDFDiff::stop()
{
if (m_futureWatcher && !m_futureWatcher->isFinished())
{
// Do stop only if process doesn't finished already.
// If we are finished, we do not want to set cancelled state.
m_cancelled = true;
m_futureWatcher->waitForFinished();
}
}
PDFDiffResult PDFDiff::perform()
{
PDFDiffResult result;
if (!m_leftDocument || !m_rightDocument)
{
result.setResult(tr("No document to be compared."));
return result;
}
if (m_pagesForLeftDocument.isEmpty() || m_pagesForRightDocument.isEmpty())
{
result.setResult(tr("No page to be compared."));
return result;
}
auto leftPages = m_pagesForLeftDocument.unfold();
auto rightPages = m_pagesForRightDocument.unfold();
const size_t leftDocumentPageCount = m_leftDocument->getCatalog()->getPageCount();
const size_t rightDocumentPageCount = m_rightDocument->getCatalog()->getPageCount();
if (leftPages.front() < 0 ||
leftPages.back() >= PDFInteger(leftDocumentPageCount) ||
rightPages.front() < 0 ||
rightPages.back() >= PDFInteger(rightDocumentPageCount))
{
result.setResult(tr("Invalid page range."));
return result;
}
if (m_progress)
{
ProgressStartupInfo info;
info.showDialog = false;
info.text = tr("");
m_progress->start(StepLast, std::move(info));
}
// StepExtractContentLeftDocument
stepProgress();
// StepExtractContentRightDocument
stepProgress();
// StepExtractTextLeftDocument
pdf::PDFDocumentTextFlowFactory factoryLeftDocumentTextFlow;
factoryLeftDocumentTextFlow.setCalculateBoundingBoxes(true);
PDFDocumentTextFlow leftTextFlow = factoryLeftDocumentTextFlow.create(m_leftDocument, leftPages, PDFDocumentTextFlowFactory::Algorithm::Auto);
stepProgress();
// StepExtractTextRightDocument
pdf::PDFDocumentTextFlowFactory factoryRightDocumentTextFlow;
factoryRightDocumentTextFlow.setCalculateBoundingBoxes(true);
PDFDocumentTextFlow rightTextFlow = factoryRightDocumentTextFlow.create(m_rightDocument, rightPages, PDFDocumentTextFlowFactory::Algorithm::Auto);
stepProgress();
// StepCompare
stepProgress();
if (m_progress)
{
m_progress->finish();
}
return result;
}
void PDFDiff::stepProgress()
{
if (m_progress)
{
m_progress->step();
}
}
void PDFDiff::onComparationPerformed()
{
m_cancelled = false;
m_result = m_future.result();
emit comparationFinished();
}
PDFDiffResult::PDFDiffResult() :
m_result(true)
{
}
} // namespace pdf