File indexing completed on 2024-04-21 05:45:08
0001 /*************************************************************************** 0002 * Copyright (C) 2008-2011 by Daniel Nicoletti * 0003 * dantti12@gmail.com * 0004 * * 0005 * This program is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, * 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0013 * GNU General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU General Public License * 0016 * along with this program; see the file COPYING. If not, write to * 0017 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * 0018 * Boston, MA 02110-1301, USA. * 0019 ***************************************************************************/ 0020 0021 #include <config.h> 0022 0023 #include "PkTransactionWidget.h" 0024 #include "ui_PkTransactionWidget.h" 0025 0026 #include <KLocalizedString> 0027 #include <QPushButton> 0028 #include <KPixmapSequence> 0029 #include <KPixmapSequenceOverlayPainter> 0030 #include <KIconLoader> 0031 0032 #include <QLoggingCategory> 0033 0034 #include <QtDBus/QDBusMessage> 0035 #include <QtDBus/QDBusConnection> 0036 #include <QScrollBar> 0037 0038 #include <Daemon> 0039 0040 #include "Enum.h" 0041 #include "PkStrings.h" 0042 #include "RepoSig.h" 0043 #include "LicenseAgreement.h" 0044 #include "PkIcons.h" 0045 #include "ApplicationLauncher.h" 0046 #include "Requirements.h" 0047 #include "PkTransaction.h" 0048 #include "TransactionDelegate.h" 0049 #include "PkTransactionProgressModel.h" 0050 #include "PackageModel.h" 0051 0052 Q_DECLARE_LOGGING_CATEGORY(APPER_LIB) 0053 0054 class PkTransactionWidgetPrivate 0055 { 0056 public: 0057 ApplicationLauncher *launcher; 0058 Transaction::Role role; 0059 KPixmapSequenceOverlayPainter *busySeq; 0060 }; 0061 0062 PkTransactionWidget::PkTransactionWidget(QWidget *parent) : 0063 QWidget(parent), 0064 m_trans(nullptr), 0065 m_keepScrollBarAtBottom(true), 0066 m_handlingActionRequired(false), 0067 m_showingError(false), 0068 m_status(Transaction::StatusUnknown), 0069 ui(new Ui::PkTransactionWidget), 0070 d(new PkTransactionWidgetPrivate) 0071 { 0072 ui->setupUi(this); 0073 0074 // Setup the animation sequence 0075 d->busySeq = new KPixmapSequenceOverlayPainter(this); 0076 d->busySeq->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); 0077 d->busySeq->setWidget(ui->label); 0078 ui->label->clear(); 0079 0080 // Connect stuff from the progressView 0081 QScrollBar *scrollBar = ui->progressView->verticalScrollBar(); 0082 connect(scrollBar, &QScrollBar::sliderMoved, this, &PkTransactionWidget::followBottom); 0083 connect(scrollBar, &QScrollBar::valueChanged, this, &PkTransactionWidget::followBottom); 0084 connect(scrollBar, &QScrollBar::rangeChanged, this, &PkTransactionWidget::rangeChanged); 0085 0086 ui->progressView->setItemDelegate(new TransactionDelegate(this)); 0087 0088 connect(ui->cancelButton, &QDialogButtonBox::rejected, this, &PkTransactionWidget::cancel); 0089 } 0090 0091 PkTransactionWidget::~PkTransactionWidget() 0092 { 0093 // DO NOT disconnect the transaction here, 0094 // it might not exist when this happen 0095 delete d; 0096 } 0097 0098 void PkTransactionWidget::hideCancelButton() 0099 { 0100 // On the session installed we hide the 0101 // cancel button to use the KDialog main one 0102 ui->cancelButton->hide(); 0103 } 0104 0105 void PkTransactionWidget::cancel() 0106 { 0107 if (m_trans) { 0108 m_trans->cancel(); 0109 } 0110 } 0111 0112 void PkTransactionWidget::setTransaction(PkTransaction *trans, Transaction::Role role) 0113 { 0114 Q_ASSERT(trans); 0115 0116 m_trans = trans; 0117 d->role = role; 0118 0119 // This makes sure the Columns will properly resize to contents 0120 ui->progressView->header()->setStretchLastSection(false); 0121 if (role == Transaction::RoleRefreshCache) { 0122 trans->progressModel()->setColumnCount(1); 0123 ui->progressView->setModel(trans->progressModel()); 0124 ui->progressView->header()->setSectionResizeMode(0, QHeaderView::Stretch); 0125 } else { 0126 trans->progressModel()->setColumnCount(3); 0127 ui->progressView->setModel(trans->progressModel()); 0128 ui->progressView->header()->reset(); 0129 ui->progressView->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents); 0130 ui->progressView->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents); 0131 ui->progressView->header()->setSectionResizeMode(2, QHeaderView::Stretch); 0132 } 0133 0134 connect(m_trans, &PkTransaction::percentageChanged, this, &PkTransactionWidget::updateUi); 0135 connect(m_trans, &PkTransaction::speedChanged, this, &PkTransactionWidget::updateUi); 0136 connect(m_trans, &PkTransaction::statusChanged, this, &PkTransactionWidget::updateUi); 0137 connect(m_trans, &PkTransaction::downloadSizeRemainingChanged, this, &PkTransactionWidget::updateUi); 0138 connect(m_trans, &PkTransaction::remainingTimeChanged, this, &PkTransactionWidget::updateUi); 0139 connect(m_trans, &PkTransaction::roleChanged, this, &PkTransactionWidget::updateUi); 0140 connect(m_trans, &PkTransaction::allowCancelChanged, this, &PkTransactionWidget::updateUi); 0141 connect(m_trans, &PkTransaction::transactionFlagsChanged, this, &PkTransactionWidget::updateUi); 0142 0143 // Forward Q_SIGNALS: 0144 connect(m_trans, &PkTransaction::sorry, this, &PkTransactionWidget::sorry); 0145 connect(m_trans, &PkTransaction::errorMessage, this, &PkTransactionWidget::error); 0146 connect(m_trans, &PkTransaction::dialog, this, &PkTransactionWidget::dialog); 0147 0148 // sets ui 0149 updateUi(); 0150 } 0151 0152 void PkTransactionWidget::unsetTransaction() 0153 { 0154 if (m_trans == nullptr) { 0155 return; 0156 } 0157 0158 connect(m_trans, &PkTransaction::percentageChanged, this, &PkTransactionWidget::updateUi); 0159 connect(m_trans, &PkTransaction::speedChanged, this, &PkTransactionWidget::updateUi); 0160 connect(m_trans, &PkTransaction::statusChanged, this, &PkTransactionWidget::updateUi); 0161 connect(m_trans, &PkTransaction::downloadSizeRemainingChanged, this, &PkTransactionWidget::updateUi); 0162 connect(m_trans, &PkTransaction::remainingTimeChanged, this, &PkTransactionWidget::updateUi); 0163 connect(m_trans, &PkTransaction::roleChanged, this, &PkTransactionWidget::updateUi); 0164 connect(m_trans, &PkTransaction::allowCancelChanged, this, &PkTransactionWidget::updateUi); 0165 connect(m_trans, &PkTransaction::transactionFlagsChanged, this, &PkTransactionWidget::updateUi); 0166 } 0167 0168 void PkTransactionWidget::updateUi() 0169 { 0170 // sets the action icon to be the window icon 0171 auto transaction = qobject_cast<PkTransaction*>(sender()); 0172 if (transaction == nullptr && (transaction = m_trans) == nullptr) { 0173 qCWarning(APPER_LIB) << "no transaction object"; 0174 return; 0175 } 0176 0177 uint percentage = transaction->percentage(); 0178 QString percentageString; 0179 if (percentage <= 100) { 0180 if (ui->progressBar->value() != static_cast<int>(percentage)) { 0181 ui->progressBar->setMaximum(100); 0182 ui->progressBar->setValue(percentage); 0183 percentageString = QString::number(percentage); 0184 } 0185 } else if (ui->progressBar->maximum() != 0) { 0186 ui->progressBar->setMaximum(0); 0187 ui->progressBar->reset(); 0188 percentageString = QLatin1String(""); 0189 } 0190 0191 ui->progressBar->setRemaining(transaction->remainingTime()); 0192 0193 // Status & Speed 0194 Transaction::Status status = transaction->status(); 0195 uint speed = transaction->speed(); 0196 qulonglong downloadSizeRemaining = transaction->downloadSizeRemaining(); 0197 if (m_status != status) { 0198 m_status = status; 0199 ui->currentL->setText(PkStrings::status(status, 0200 speed, 0201 downloadSizeRemaining)); 0202 0203 KPixmapSequence sequence = KPixmapSequence(PkIcons::statusAnimation(status), 0204 KIconLoader::SizeLarge); 0205 if (sequence.isValid()) { 0206 d->busySeq->setSequence(sequence); 0207 d->busySeq->start(); 0208 } 0209 } else if (status == Transaction::StatusDownload) { 0210 ui->currentL->setText(PkStrings::status(status, 0211 speed, 0212 downloadSizeRemaining)); 0213 } 0214 0215 QString windowTitle; 0216 QString windowTitleProgress; 0217 QIcon windowIcon; 0218 Transaction::Role role = transaction->role(); 0219 if (role == Transaction::RoleUnknown) { 0220 windowTitle = PkStrings::status(Transaction::StatusSetup); 0221 if (percentageString.isEmpty()) { 0222 windowTitleProgress = PkStrings::status(status, 0223 speed, 0224 downloadSizeRemaining); 0225 } else { 0226 QString statusText = PkStrings::status(status, 0227 speed, 0228 downloadSizeRemaining); 0229 windowTitleProgress = i18n("%1 (%2%)", statusText, percentageString); 0230 } 0231 windowIcon = PkIcons::statusIcon(Transaction::StatusSetup); 0232 } else { 0233 windowTitle = PkStrings::action(role, transaction->transactionFlags()); 0234 if (percentageString.isEmpty()) { 0235 windowTitleProgress = PkStrings::status(status, 0236 speed, 0237 downloadSizeRemaining); 0238 } else { 0239 QString statusText = PkStrings::status(status, 0240 speed, 0241 downloadSizeRemaining); 0242 windowTitleProgress = i18n("%1 (%2%)", statusText, percentageString); 0243 } 0244 windowIcon = PkIcons::actionIcon(role); 0245 } 0246 0247 if (d->role != role) { 0248 d->role = role; 0249 setWindowIcon(PkIcons::actionIcon(role)); 0250 setWindowTitle(windowTitle); 0251 0252 emit titleChanged(windowTitle); 0253 emit titleChangedProgress(windowTitleProgress); 0254 } else if (!percentageString.isNull()) { 0255 emit titleChangedProgress(windowTitleProgress); 0256 } 0257 0258 // check to see if we can cancel 0259 bool cancel = transaction->allowCancel(); 0260 emit allowCancel(cancel); 0261 ui->cancelButton->setEnabled(cancel); 0262 } 0263 0264 bool PkTransactionWidget::isFinished() const 0265 { 0266 // return d->finished; 0267 return false; 0268 } 0269 0270 bool PkTransactionWidget::isCancelVisible() const 0271 { 0272 return ui->cancelButton->isVisible(); 0273 } 0274 0275 void PkTransactionWidget::reject() 0276 { 0277 // d->finished = true; 0278 // setExitStatus(Cancelled); 0279 } 0280 0281 void PkTransactionWidget::followBottom(int value) 0282 { 0283 // If the user moves the slider to the bottom 0284 // keep it there as the list expands 0285 QScrollBar *scrollBar = qobject_cast<QScrollBar*>(sender()); 0286 m_keepScrollBarAtBottom = value == scrollBar->maximum(); 0287 } 0288 0289 void PkTransactionWidget::rangeChanged(int min, int max) 0290 { 0291 Q_UNUSED(min) 0292 QScrollBar *scrollBar = qobject_cast<QScrollBar*>(sender()); 0293 if (m_keepScrollBarAtBottom && scrollBar->value() != max) { 0294 scrollBar->setValue(max); 0295 } 0296 } 0297 0298 Transaction::Role PkTransactionWidget::role() const 0299 { 0300 return d->role; 0301 } 0302 0303 PkTransaction *PkTransactionWidget::transaction() const 0304 { 0305 return m_trans; 0306 } 0307 0308 #include "moc_PkTransactionWidget.cpp"