File indexing completed on 2024-04-21 05:45:05
0001 /* This file is part of Apper 0002 * 0003 * Copyright (C) 2012 Matthias Klumpp <matthias@tenstral.net> 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 <limba.h> 0022 #include <appstream.h> 0023 0024 #include "SetupWizard.h" 0025 #include "ui_SetupWizard.h" 0026 0027 #include <QLabel> 0028 #include <QApplication> 0029 #include <QAction> 0030 #include <QProgressBar> 0031 #include <QCheckBox> 0032 #include <QPushButton> 0033 #include <KDebug> 0034 #include <KMessageBox> 0035 #include <KGlobalSettings> 0036 #include <KLocalizedString> 0037 0038 #include "InfoWidget.h" 0039 #include "SimplePage.h" 0040 0041 class SetupWizardPrivate 0042 { 0043 public: 0044 SetupWizardPrivate() 0045 : setup(NULL), cpt(NULL) 0046 { 0047 preparationPageCount = -1; 0048 } 0049 0050 ~SetupWizardPrivate() 0051 { 0052 if (setup != NULL) 0053 g_object_unref (setup); 0054 if (cpt != NULL) 0055 g_object_unref (cpt); 0056 } 0057 0058 int preparationPageCount; 0059 0060 // Package information 0061 LiInstaller *setup; 0062 AsComponent *cpt; 0063 LiPkgInfo *pki; 0064 0065 // UI components 0066 InfoWidget *infoPage; 0067 SimplePage *execPage; 0068 QProgressBar *progressBar; 0069 }; 0070 0071 SetupWizard::SetupWizard(QWidget *parent) 0072 : KDialog (parent), 0073 d(new SetupWizardPrivate()), 0074 ui(new Ui::SetupWizard) 0075 { 0076 ui->setupUi(KDialog::mainWidget()); 0077 setAttribute(Qt::WA_DeleteOnClose); 0078 0079 connect(KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()), 0080 this, SLOT(updatePallete())); 0081 updatePallete(); 0082 0083 setWindowIcon(KIcon("system-software-install")); 0084 setButtons(KDialog::User1 | KDialog::Ok | KDialog::Cancel); 0085 setButtonText(KDialog::Ok, i18n("Continue")); 0086 setButtonIcon(KDialog::Ok, KIcon("go-next")); 0087 setButtonText(KDialog::User1, i18n("Back")); 0088 setButtonIcon(KDialog::User1, KIcon("go-previous")); 0089 0090 enableButtonOk(true); 0091 0092 connect(ui->stackedWidget, SIGNAL(currentChanged(int)), this, SLOT(currentPageChanged(int))); 0093 0094 setMinimumSize(QSize(430,280)); 0095 KConfig config("apper"); 0096 KConfigGroup configGroup(&config, "AppInstaller"); 0097 restoreDialogSize(configGroup); 0098 } 0099 0100 SetupWizard::~SetupWizard() 0101 { 0102 delete d; 0103 delete ui; 0104 } 0105 0106 void SetupWizard::showError(const QString& details) 0107 { 0108 d->infoPage->reset(); 0109 d->infoPage->setWindowTitle(i18n("Error")); 0110 d->infoPage->setDescription(i18n("An error occurred")); 0111 d->infoPage->setIcon(KIcon("dialog-error")); 0112 d->infoPage->setDetails(details); 0113 this->setButtons(KDialog::Close); 0114 this->button(KDialog::Close)->setFocus(); 0115 this->setCurrentPage(d->infoPage); 0116 } 0117 0118 bool SetupWizard::constructWizardLayout() 0119 { 0120 if (d->preparationPageCount > 1) 0121 return true; 0122 0123 if (d->preparationPageCount == 0) { 0124 ui->stackedWidget->addWidget(d->infoPage); 0125 } 0126 0127 0128 if (d->cpt == NULL) { 0129 kDebug() << "AppStream component was NULL!"; 0130 return false; 0131 } 0132 0133 QString appName = as_component_get_name(d->cpt); 0134 0135 // Welcome page 0136 SimplePage *introP = new SimplePage(this); 0137 introP->setTitle(i18n("Welcome!")); 0138 introP->setDescription(i18n("Welcome to the installation of %1!", appName)); 0139 introP->setDetails(i18n("Please be careful while installing a 3rd-party application.<br>" 0140 "It might eventually <b>damage</b> your system or " 0141 "have <b>malicious behaviour</b>, like spying out your passwords.<br>" 0142 "Please do only install this software if you <b>trust its " 0143 "publisher</b>.")); 0144 ui->stackedWidget->addWidget(introP); 0145 d->preparationPageCount = 1; 0146 0147 // Setup details page 0148 SimplePage *detailsP = new SimplePage(this); 0149 detailsP->setTitle(i18n("Details")); 0150 detailsP->setDescription(i18n("Details about this installation")); 0151 0152 QWidget *securityWidget = new QWidget(detailsP); 0153 QHBoxLayout *secWgLayout = new QHBoxLayout(); 0154 securityWidget->setLayout(secWgLayout); 0155 0156 QLabel *pix = new QLabel(detailsP); 0157 0158 LiTrustLevel trust = li_installer_get_package_trust_level(d->setup, NULL); 0159 if (trust == LI_TRUST_LEVEL_HIGH) 0160 pix->setPixmap(KIcon("security-high").pixmap (32, 32)); 0161 else if ((trust == LI_TRUST_LEVEL_LOW) || (trust == LI_TRUST_LEVEL_MEDIUM)) 0162 pix->setPixmap(KIcon("security-medium").pixmap (32, 32)); 0163 else if ((trust == LI_TRUST_LEVEL_NONE) || (trust == LI_TRUST_LEVEL_INVALID)) 0164 pix->setPixmap(KIcon("security-low").pixmap (32, 32)); 0165 else 0166 pix->setPixmap(KIcon("task-reject").pixmap (32, 32)); 0167 secWgLayout->addWidget(pix); 0168 0169 QLabel *secInfoL = new QLabel(detailsP); 0170 secInfoL->setText(QString::fromUtf8(li_trust_level_to_text(trust))); 0171 secWgLayout->addWidget(secInfoL); 0172 0173 // Install mode select checkbox 0174 secWgLayout->addStretch(); 0175 detailsP->addWidget(securityWidget); 0176 0177 ui->stackedWidget->addWidget(detailsP); 0178 d->preparationPageCount++; 0179 0180 // Application description page 0181 QString desc = as_component_get_description(d->cpt); 0182 if (desc.isEmpty()) 0183 desc = as_component_get_summary(d->cpt); 0184 SimplePage *descP = new SimplePage(this); 0185 descP->setTitle(i18n("Application description")); 0186 descP->setDescription(i18n("Description")); 0187 descP->setDetails(desc); 0188 ui->stackedWidget->addWidget(descP); 0189 d->preparationPageCount++; 0190 0191 // Setup exec page 0192 d->execPage = new SimplePage(this); 0193 d->execPage->setTitle(i18n("Running installation")); 0194 d->execPage->setDescription(i18n("Installing %1...", appName)); 0195 d->progressBar = new QProgressBar(d->execPage); 0196 d->progressBar->setMinimumHeight(40); 0197 d->execPage->addWidget(d->progressBar); 0198 ui->stackedWidget->addWidget(d->execPage); 0199 d->preparationPageCount++; 0200 0201 setCurrentPage(introP); 0202 0203 return true; 0204 } 0205 0206 void SetupWizard::currentPageChanged(int index) 0207 { 0208 // Set the page title 0209 ui->titleL->setText(ui->stackedWidget->currentWidget()->windowTitle()); 0210 0211 // Show "back" button if necessary 0212 if (index > 1) 0213 enableButton(KDialog::User1, true); 0214 else 0215 enableButton(KDialog::User1, false); 0216 } 0217 0218 void SetupWizard::setCurrentPage(QWidget* widget) 0219 { 0220 ui->stackedWidget->setCurrentWidget(widget); 0221 } 0222 0223 void SetupWizard::runInstallation() 0224 { 0225 GError *error = NULL; 0226 0227 // We now show the install dialog, so run the installation now! 0228 li_installer_install(d->setup, &error); 0229 0230 if (error == NULL) { 0231 /* we installed successfully */ 0232 QString appName = QString::fromUtf8(as_component_get_name (d->cpt)); 0233 d->infoPage->reset(); 0234 d->infoPage->setWindowTitle(i18n("Installation finished!")); 0235 d->infoPage->setDescription(i18n("%1 has been installed successfully!", appName)); 0236 d->infoPage->setIcon(KIcon("dialog-ok-apply")); 0237 setButtons(KDialog::Close); 0238 button(KDialog::Close)->setFocus(); 0239 setCurrentPage(d->infoPage); 0240 } else { 0241 /* there was an error */ 0242 showError(QString::fromUtf8(error->message)); 0243 g_error_free (error); 0244 } 0245 } 0246 0247 0248 void SetupWizard::slotButtonClicked(int button) 0249 { 0250 if (button == KDialog::Ok) { 0251 // We go forward 0252 0253 int index = ui->stackedWidget->currentIndex(); 0254 if (index < d->preparationPageCount) { 0255 index++; 0256 ui->stackedWidget->setCurrentIndex(index); 0257 } 0258 0259 if (index == d->preparationPageCount-1) { 0260 setButtonText(KDialog::Ok, i18n("Install")); 0261 setButtonIcon(KDialog::Ok, KIcon("dialog-ok-apply")); 0262 } 0263 0264 if (index == d->preparationPageCount) { 0265 // We can install the software now, so disable prev/fwd & abort buttons 0266 enableButton(KDialog::User1, false); 0267 enableButton(KDialog::Ok, false); 0268 enableButton(KDialog::Cancel, false); 0269 0270 ui->stackedWidget->update(); 0271 runInstallation(); 0272 } 0273 0274 } else if (button == KDialog::User1) { 0275 // We go back 0276 0277 int index = ui->stackedWidget->currentIndex(); 0278 if (index > 1) { 0279 index--; 0280 // Make sure go-forward button is enabled 0281 enableButton(KDialog::Ok, true); 0282 ui->stackedWidget->setCurrentIndex(index); 0283 if (index == 1) 0284 enableButton(KDialog::User1, false); 0285 } 0286 } else if (button == KDialog::Cancel) { 0287 close(); 0288 } else if (button == KDialog::Close) { 0289 close(); 0290 } 0291 } 0292 0293 bool SetupWizard::initialize(const QString& ipkFName) 0294 { 0295 GError *error = NULL; 0296 AsMetadata *mdata; 0297 gchar *data; 0298 0299 // Create a new installer instance 0300 d->setup = li_installer_new (); 0301 0302 // Create info page to notify about errors 0303 d->infoPage = new InfoWidget(this); 0304 d->infoPage->setWindowTitle("Information"); 0305 ui->stackedWidget->addWidget(d->infoPage); 0306 0307 // Load the package file, required to have metadata 0308 li_installer_open_file(d->setup, ipkFName.toUtf8().data(), &error); 0309 if (error != NULL) { 0310 this->showError(QString::fromUtf8(error->message)); 0311 g_error_free (error); 0312 return false; 0313 } 0314 0315 data = li_installer_get_appstream_data (d->setup); 0316 mdata = as_metadata_new (); 0317 as_metadata_parse (mdata, data, AS_FORMAT_KIND_XML, &error); 0318 g_free (data); 0319 if (error != NULL) { 0320 this->showError(QString::fromUtf8(error->message)); 0321 g_error_free (error); 0322 g_object_unref (mdata); 0323 return false; 0324 } 0325 0326 d->cpt = as_metadata_get_component (mdata); 0327 g_object_ref (d->cpt); 0328 d->pki = li_installer_get_package_info (d->setup); 0329 g_object_unref (mdata); 0330 0331 // Build layout of our setup wizard 0332 constructWizardLayout(); 0333 0334 return true; 0335 } 0336 0337 void SetupWizard::updatePallete() 0338 { 0339 QPalette pal; 0340 pal.setColor(QPalette::Window, KGlobalSettings::activeTitleColor()); 0341 pal.setColor(QPalette::WindowText, KGlobalSettings::activeTextColor()); 0342 ui->backgroundFrame->setPalette(pal); 0343 }