File indexing completed on 2024-06-23 05:13:51

0001 /* -*- mode: c++; c-basic-offset:4 -*-
0002     crypto/gui/resultpage.cpp
0003 
0004     This file is part of Kleopatra, the KDE keymanager
0005     SPDX-FileCopyrightText: 2008 Klarälvdalens Datakonsult AB
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #include <config-kleopatra.h>
0011 
0012 #include "resultitemwidget.h"
0013 #include "resultlistwidget.h"
0014 #include "resultpage.h"
0015 
0016 #include <crypto/taskcollection.h>
0017 
0018 #include <utils/scrollarea.h>
0019 
0020 #include <KLocalizedString>
0021 
0022 #include <QCheckBox>
0023 #include <QHash>
0024 #include <QLabel>
0025 #include <QProgressBar>
0026 #include <QVBoxLayout>
0027 
0028 using namespace Kleo;
0029 using namespace Kleo::Crypto;
0030 using namespace Kleo::Crypto::Gui;
0031 
0032 class ResultPage::Private
0033 {
0034     ResultPage *const q;
0035 
0036 public:
0037     explicit Private(ResultPage *qq);
0038 
0039     void progress(int progress, int total);
0040     void result(const std::shared_ptr<const Task::Result> &result);
0041     void started(const std::shared_ptr<Task> &result);
0042     void allDone();
0043     QLabel *labelForTag(const QString &tag);
0044 
0045     std::shared_ptr<TaskCollection> m_tasks;
0046     QProgressBar *m_progressBar;
0047     QHash<QString, QLabel *> m_progressLabelByTag;
0048     QVBoxLayout *m_progressLabelLayout;
0049     int m_lastErrorItemIndex = 0;
0050     ResultListWidget *m_resultList;
0051     QCheckBox *m_keepOpenCB;
0052 };
0053 
0054 ResultPage::Private::Private(ResultPage *qq)
0055     : q(qq)
0056 {
0057     QBoxLayout *const layout = new QVBoxLayout(q);
0058     auto const labels = new QWidget;
0059     m_progressLabelLayout = new QVBoxLayout(labels);
0060     layout->addWidget(labels);
0061     m_progressBar = new QProgressBar;
0062     layout->addWidget(m_progressBar);
0063     m_resultList = new ResultListWidget;
0064     layout->addWidget(m_resultList);
0065     m_keepOpenCB = new QCheckBox;
0066     m_keepOpenCB->setText(i18n("Keep open after operation completed"));
0067     m_keepOpenCB->setChecked(true);
0068     layout->addWidget(m_keepOpenCB);
0069 }
0070 
0071 void ResultPage::Private::progress(int progress, int total)
0072 {
0073     Q_ASSERT(progress >= 0);
0074     Q_ASSERT(total >= 0);
0075     m_progressBar->setRange(0, total);
0076     m_progressBar->setValue(progress);
0077 }
0078 
0079 void ResultPage::Private::allDone()
0080 {
0081     Q_ASSERT(m_tasks);
0082     q->setAutoAdvance(!m_keepOpenCB->isChecked() && !m_tasks->errorOccurred());
0083     m_progressBar->setRange(0, 100);
0084     m_progressBar->setValue(100);
0085     m_tasks.reset();
0086     const auto progressLabelByTagKeys{m_progressLabelByTag.keys()};
0087     for (const QString &i : progressLabelByTagKeys) {
0088         if (!i.isEmpty()) {
0089             m_progressLabelByTag.value(i)->setText(i18n("%1: All operations completed.", i));
0090         } else {
0091             m_progressLabelByTag.value(i)->setText(i18n("All operations completed."));
0092         }
0093     }
0094     Q_EMIT q->completeChanged();
0095 }
0096 
0097 void ResultPage::Private::result(const std::shared_ptr<const Task::Result> &)
0098 {
0099 }
0100 
0101 void ResultPage::Private::started(const std::shared_ptr<Task> &task)
0102 {
0103     Q_ASSERT(task);
0104     const QString tag = task->tag();
0105     QLabel *const label = labelForTag(tag);
0106     Q_ASSERT(label);
0107     if (tag.isEmpty()) {
0108         label->setText(i18nc("number, operation description", "Operation %1: %2", m_tasks->numberOfCompletedTasks() + 1, task->label()));
0109     } else {
0110         label->setText(i18nc(R"(tag( "OpenPGP" or "CMS"),  operation description)", "%1: %2", tag, task->label()));
0111     }
0112 }
0113 
0114 ResultPage::ResultPage(QWidget *parent, Qt::WindowFlags flags)
0115     : WizardPage(parent, flags)
0116     , d(new Private(this))
0117 {
0118     setTitle(i18n("<b>Results</b>"));
0119 }
0120 
0121 ResultPage::~ResultPage()
0122 {
0123 }
0124 
0125 bool ResultPage::keepOpenWhenDone() const
0126 {
0127     return d->m_keepOpenCB->isChecked();
0128 }
0129 
0130 void ResultPage::setKeepOpenWhenDone(bool keep)
0131 {
0132     d->m_keepOpenCB->setChecked(keep);
0133 }
0134 
0135 void ResultPage::setTaskCollection(const std::shared_ptr<TaskCollection> &coll)
0136 {
0137     Q_ASSERT(!d->m_tasks);
0138     if (d->m_tasks == coll) {
0139         return;
0140     }
0141     d->m_tasks = coll;
0142     Q_ASSERT(d->m_tasks);
0143     d->m_resultList->setTaskCollection(coll);
0144     connect(d->m_tasks.get(), &TaskCollection::progress, this, [this](int current, int total) {
0145         d->progress(current, total);
0146     });
0147     connect(d->m_tasks.get(), SIGNAL(done()), this, SLOT(allDone()));
0148     connect(d->m_tasks.get(),
0149             SIGNAL(result(std::shared_ptr<const Kleo::Crypto::Task::Result>)),
0150             this,
0151             SLOT(result(std::shared_ptr<const Kleo::Crypto::Task::Result>)));
0152     connect(d->m_tasks.get(), SIGNAL(started(std::shared_ptr<Kleo::Crypto::Task>)), this, SLOT(started(std::shared_ptr<Kleo::Crypto::Task>)));
0153 
0154     for (const std::shared_ptr<Task> &i : d->m_tasks->tasks()) { // create labels for all tags in collection
0155         Q_ASSERT(i && d->labelForTag(i->tag()));
0156         Q_UNUSED(i)
0157     }
0158     Q_EMIT completeChanged();
0159 }
0160 
0161 QLabel *ResultPage::Private::labelForTag(const QString &tag)
0162 {
0163     if (QLabel *const label = m_progressLabelByTag.value(tag)) {
0164         return label;
0165     }
0166     auto label = new QLabel;
0167     label->setTextFormat(Qt::RichText);
0168     label->setWordWrap(true);
0169     m_progressLabelLayout->addWidget(label);
0170     m_progressLabelByTag.insert(tag, label);
0171     return label;
0172 }
0173 
0174 bool ResultPage::isComplete() const
0175 {
0176     return d->m_tasks ? d->m_tasks->allTasksCompleted() : true;
0177 }
0178 
0179 #include "moc_resultpage.cpp"