File indexing completed on 2024-06-23 05:13:50
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 "newresultpage.h" 0013 0014 #include "resultitemwidget.h" 0015 #include "resultlistwidget.h" 0016 0017 #include <crypto/taskcollection.h> 0018 0019 #include <Libkleo/Stl_Util> 0020 0021 #include <KLocalizedString> 0022 0023 #include <QCheckBox> 0024 #include <QHash> 0025 #include <QLabel> 0026 #include <QProgressBar> 0027 #include <QTimer> 0028 #include <QVBoxLayout> 0029 0030 static const int ProgressBarHideDelay = 2000; // 2 secs 0031 0032 using namespace Kleo; 0033 using namespace Kleo::Crypto; 0034 using namespace Kleo::Crypto::Gui; 0035 0036 class NewResultPage::Private 0037 { 0038 NewResultPage *const q; 0039 0040 public: 0041 explicit Private(NewResultPage *qq); 0042 0043 void progress(int progress, int total); 0044 void result(const std::shared_ptr<const Task::Result> &result); 0045 void started(const std::shared_ptr<Task> &result); 0046 void allDone(); 0047 QLabel *labelForTag(const QString &tag); 0048 0049 std::vector<std::shared_ptr<TaskCollection>> m_collections; 0050 QTimer m_hideProgressTimer; 0051 QProgressBar *m_progressBar; 0052 QHash<QString, QLabel *> m_progressLabelByTag; 0053 QVBoxLayout *m_progressLabelLayout; 0054 int m_lastErrorItemIndex; 0055 ResultListWidget *m_resultList; 0056 }; 0057 0058 NewResultPage::Private::Private(NewResultPage *qq) 0059 : q(qq) 0060 , m_lastErrorItemIndex(0) 0061 { 0062 m_hideProgressTimer.setInterval(ProgressBarHideDelay); 0063 m_hideProgressTimer.setSingleShot(true); 0064 0065 QBoxLayout *const layout = new QVBoxLayout(q); 0066 auto const labels = new QWidget; 0067 m_progressLabelLayout = new QVBoxLayout(labels); 0068 layout->addWidget(labels); 0069 m_progressBar = new QProgressBar; 0070 layout->addWidget(m_progressBar); 0071 m_resultList = new ResultListWidget; 0072 connect(m_resultList, &ResultListWidget::linkActivated, q, &NewResultPage::linkActivated); 0073 layout->addWidget(m_resultList, 1); 0074 0075 connect(&m_hideProgressTimer, &QTimer::timeout, m_progressBar, &QProgressBar::hide); 0076 } 0077 0078 void NewResultPage::Private::progress(int progress, int total) 0079 { 0080 Q_ASSERT(progress >= 0); 0081 Q_ASSERT(total >= 0); 0082 m_progressBar->setRange(0, total); 0083 m_progressBar->setValue(progress); 0084 } 0085 0086 void NewResultPage::Private::allDone() 0087 { 0088 Q_ASSERT(!m_collections.empty()); 0089 if (!m_resultList->isComplete()) { 0090 return; 0091 } 0092 m_progressBar->setRange(0, 100); 0093 m_progressBar->setValue(100); 0094 m_collections.clear(); 0095 const auto progressLabelByTagKeys{m_progressLabelByTag.keys()}; 0096 for (const QString &i : progressLabelByTagKeys) { 0097 if (!i.isEmpty()) { 0098 m_progressLabelByTag.value(i)->setText(i18n("%1: All operations completed.", i)); 0099 } else { 0100 m_progressLabelByTag.value(i)->setText(i18n("All operations completed.")); 0101 } 0102 } 0103 if (QAbstractButton *cancel = q->wizard()->button(QWizard::CancelButton)) { 0104 cancel->setEnabled(false); 0105 } 0106 Q_EMIT q->completeChanged(); 0107 m_hideProgressTimer.start(); 0108 } 0109 0110 void NewResultPage::Private::result(const std::shared_ptr<const Task::Result> &) 0111 { 0112 } 0113 0114 void NewResultPage::Private::started(const std::shared_ptr<Task> &task) 0115 { 0116 Q_ASSERT(task); 0117 const QString tag = task->tag(); 0118 QLabel *const label = labelForTag(tag); 0119 Q_ASSERT(label); 0120 if (tag.isEmpty()) { 0121 label->setText(i18nc("number, operation description", "Operation %1: %2", m_resultList->numberOfCompletedTasks() + 1, task->label())); 0122 } else { 0123 label->setText(i18nc(R"(tag( "OpenPGP" or "CMS"), operation description)", "%1: %2", tag, task->label())); 0124 } 0125 } 0126 0127 NewResultPage::NewResultPage(QWidget *parent) 0128 : QWizardPage(parent) 0129 , d(new Private(this)) 0130 { 0131 setTitle(i18n("<b>Results</b>")); 0132 } 0133 0134 NewResultPage::~NewResultPage() 0135 { 0136 } 0137 0138 void NewResultPage::setTaskCollection(const std::shared_ptr<TaskCollection> &coll) 0139 { 0140 // clear(); ### PENDING(marc) implement 0141 addTaskCollection(coll); 0142 } 0143 0144 void NewResultPage::addTaskCollection(const std::shared_ptr<TaskCollection> &coll) 0145 { 0146 Q_ASSERT(coll); 0147 if (std::find(d->m_collections.cbegin(), d->m_collections.cend(), coll) != d->m_collections.cend()) { 0148 return; 0149 } 0150 d->m_hideProgressTimer.stop(); 0151 d->m_progressBar->show(); 0152 d->m_collections.push_back(coll); 0153 d->m_resultList->addTaskCollection(coll); 0154 connect(coll.get(), &TaskCollection::progress, this, [this](int current, int total) { 0155 d->progress(current, total); 0156 }); 0157 connect(coll.get(), SIGNAL(done()), this, SLOT(allDone())); 0158 connect(coll.get(), 0159 SIGNAL(result(std::shared_ptr<const Kleo::Crypto::Task::Result>)), 0160 this, 0161 SLOT(result(std::shared_ptr<const Kleo::Crypto::Task::Result>))); 0162 connect(coll.get(), SIGNAL(started(std::shared_ptr<Kleo::Crypto::Task>)), this, SLOT(started(std::shared_ptr<Kleo::Crypto::Task>))); 0163 0164 for (const std::shared_ptr<Task> &i : coll->tasks()) { // create labels for all tags in collection 0165 Q_ASSERT(i); 0166 QLabel *l = d->labelForTag(i->tag()); 0167 Q_ASSERT(l); 0168 (void)l; 0169 } 0170 Q_EMIT completeChanged(); 0171 } 0172 0173 QLabel *NewResultPage::Private::labelForTag(const QString &tag) 0174 { 0175 if (QLabel *const label = m_progressLabelByTag.value(tag)) { 0176 return label; 0177 } 0178 auto label = new QLabel; 0179 label->setTextFormat(Qt::RichText); 0180 label->setWordWrap(true); 0181 m_progressLabelLayout->addWidget(label); 0182 m_progressLabelByTag.insert(tag, label); 0183 return label; 0184 } 0185 0186 bool NewResultPage::isComplete() const 0187 { 0188 return d->m_resultList->isComplete(); 0189 } 0190 0191 #include "moc_newresultpage.cpp"