diff --git a/ApperKCM/ApperKCM.cpp b/ApperKCM/ApperKCM.cpp index 295d7b8..f185615 100644 --- a/ApperKCM/ApperKCM.cpp +++ b/ApperKCM/ApperKCM.cpp @@ -1,948 +1,915 @@ /*************************************************************************** - * Copyright (C) 2008-2011 by Daniel Nicoletti * + * Copyright (C) 2008-2018 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "ApperKCM.h" #include "ui_ApperKCM.h" #include //#include #include #include #include #include #include #include #include //#include #include #include #include #include #include #include #include #include #include #ifdef HAVE_APPSTREAM #include #endif #include #include #include "FiltersMenu.h" #include "BrowseView.h" #include "CategoryModel.h" #include "TransactionHistory.h" #include "Settings/Settings.h" #include "Updater/Updater.h" Q_LOGGING_CATEGORY(APPER, "apper") #define BAR_SEARCH 0 #define BAR_UPDATE 1 #define BAR_SETTINGS 2 #define BAR_TITLE 3 //KCONFIGGROUP_DECLARE_ENUM_QOBJECT(Transaction, Filter) K_PLUGIN_FACTORY(ApperFactory, registerPlugin();) K_EXPORT_PLUGIN(ApperFactory("kcm_apper", "apper")) ApperKCM::ApperKCM(QWidget *parent, const QVariantList &args) : KCModule(parent, args), ui(new Ui::ApperKCM), m_currentAction(0), m_groupsProxyModel(0), m_settingsPage(0), m_updaterPage(0), m_searchTransaction(0), m_findIcon(QIcon::fromTheme("edit-find")), m_cancelIcon(QIcon::fromTheme("dialog-cancel")), m_forceRefreshCache(false), m_cacheAge(600), m_history(0), m_searchRole(Transaction::RoleUnknown) { - KAboutData *aboutData; - aboutData = new KAboutData("kcm_apper", - "apper", - APPER_VERSION, - i18n("KDE interface for managing software"), - KAboutLicense::LicenseKey::GPL); - aboutData->addAuthor(i18n("(C) 2008-2013 Daniel Nicoletti"), QString(), "dantti12@gmail.com", "http://dantti.wordpress.com"); + auto aboutData = new KAboutData("kcm_apper", + "apper", + APPER_VERSION, + i18n("KDE interface for managing software"), + KAboutLicense::LicenseKey::GPL); + aboutData->addAuthor(i18n("(C) 2008-2018 Daniel Nicoletti"), QString(), "dantti12@gmail.com", "http://dantti.wordpress.com"); aboutData->addAuthor(i18n("Matthias Klumpp"), QString(), QStringLiteral("matthias@tenstral.net")); setAboutData(aboutData); setButtons(Apply); // store the actions supported by the backend - connect(Daemon::global(), SIGNAL(changed()), this, SLOT(daemonChanged())); + connect(Daemon::global(), &Daemon::changed, this, &ApperKCM::daemonChanged); // Set the current locale //TODO FIXME // QString locale(KLocale::global()->language() % QLatin1Char('.') % KLocale::global()->encoding()); Daemon::global()->setHints(QLatin1String("locale=") + QLocale::system().name()); qCDebug(APPER) << Q_FUNC_INFO << QLocale::system().name(); ui->setupUi(this); // Browse TAB ui->backTB->setIcon(QIcon::fromTheme("go-previous")); // create our toolbar QToolBar *toolBar = new QToolBar(this); ui->gridLayout_2->addWidget(toolBar); toolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - connect(ui->browseView, SIGNAL(categoryActivated(QModelIndex)), - this, SLOT(on_homeView_activated(QModelIndex))); + connect(ui->browseView, &BrowseView::categoryActivated, this, &ApperKCM::on_homeView_activated); - QMenu *findMenu = new QMenu(this); + auto findMenu = new QMenu(this); // find is just a generic name in case we don't have any search method m_genericActionK = new KToolBarPopupAction(m_findIcon, i18n("Find"), this); toolBar->addAction(m_genericActionK); // Add actions that the backend supports findMenu->addAction(ui->actionFindName); setCurrentAction(ui->actionFindName); findMenu->addAction(ui->actionFindDescription); if (!m_currentAction) { setCurrentAction(ui->actionFindDescription); } findMenu->addAction(ui->actionFindFile); if (!m_currentAction) { setCurrentAction(ui->actionFindFile); } // If no action was set we can't use this search if (m_currentAction == 0) { m_genericActionK->setEnabled(false); ui->searchKLE->setEnabled(false); } else { // Check to see if we need the KToolBarPopupAction setCurrentActionCancel(false); if (findMenu->actions().size() > 1) { m_currentAction->setVisible(false); m_genericActionK->setMenu(findMenu); } else { m_currentAction->setVisible(true); toolBar->removeAction(m_genericActionK); toolBar->addAction(m_currentAction); } - connect(m_genericActionK, SIGNAL(triggered()), - this, SLOT(genericActionKTriggered())); + connect(m_genericActionK, &KToolBarPopupAction::triggered, this, &ApperKCM::genericActionKTriggered); } // Create the groups model m_groupsModel = new CategoryModel(this); ui->browseView->setCategoryModel(m_groupsModel); - connect(m_groupsModel, SIGNAL(finished()), - this, SLOT(setupHomeModel())); + connect(m_groupsModel, &CategoryModel::finished, this, &ApperKCM::setupHomeModel); // ui->homeView->setSpacing(QDialog::spacingHint()); ui->homeView->viewport()->setAttribute(Qt::WA_Hover); KFileItemDelegate *delegate = new KFileItemDelegate(this); delegate->setWrapMode(QTextOption::WordWrap); ui->homeView->setItemDelegate(delegate); // install the backend filters ui->filtersTB->setMenu(m_filtersMenu = new FiltersMenu(this)); - connect(m_filtersMenu, SIGNAL(filtersChanged()), this, SLOT(search())); + connect(m_filtersMenu, &FiltersMenu::filtersChanged, this, &ApperKCM::search); ui->filtersTB->setIcon(QIcon::fromTheme("view-filter")); ApplicationSortFilterModel *proxy = ui->browseView->proxy(); proxy->setApplicationFilter(m_filtersMenu->filterApplications()); - connect(m_filtersMenu, SIGNAL(filterApplications(bool)), - proxy, SLOT(setApplicationFilter(bool))); + connect(m_filtersMenu, QOverload::of(&FiltersMenu::filterApplications), proxy, &ApplicationSortFilterModel::setApplicationFilter); //initialize the model, delegate, client and connect it's signals m_browseModel = ui->browseView->model(); // CHANGES TAB ui->changesView->viewport()->setAttribute(Qt::WA_Hover); m_changesModel = new PackageModel(this); - KCategorizedSortFilterProxyModel *changedProxy = new KCategorizedSortFilterProxyModel(this); + auto changedProxy = new KCategorizedSortFilterProxyModel(this); changedProxy->setSourceModel(m_changesModel); changedProxy->setDynamicSortFilter(true); changedProxy->setCategorizedModel(true); changedProxy->setSortCaseSensitivity(Qt::CaseInsensitive); changedProxy->setSortRole(PackageModel::SortRole); changedProxy->sort(0); ui->changesView->setModel(changedProxy); - ChangesDelegate *changesDelegate = new ChangesDelegate(ui->changesView); + auto changesDelegate = new ChangesDelegate(ui->changesView); changesDelegate->setExtendPixmapWidth(0); ui->changesView->setItemDelegate(changesDelegate); // Connect this signal to keep track of changes - connect(m_browseModel, SIGNAL(changed(bool)), this, SLOT(checkChanged())); + connect(m_browseModel, &PackageModel::changed, this, &ApperKCM::checkChanged); // packageUnchecked from changes model - connect(m_changesModel, SIGNAL(packageUnchecked(QString)), - m_changesModel, SLOT(removePackage(QString))); - connect(m_changesModel, SIGNAL(packageUnchecked(QString)), - m_browseModel, SLOT(uncheckPackage(QString))); + connect(m_changesModel, &PackageModel::packageUnchecked, m_changesModel, &PackageModel::removePackage); + connect(m_changesModel, &PackageModel::packageUnchecked, m_browseModel, &PackageModel::uncheckPackageDefault); ui->changesPB->setIcon(QIcon::fromTheme("edit-redo")); auto menu = new QMenu(this); ui->settingsTB->setMenu(menu); ui->settingsTB->setIcon(QIcon::fromTheme("preferences-other")); + auto signalMapper = new QSignalMapper(this); + connect(signalMapper, QOverload::of(&QSignalMapper::mapped), this, &ApperKCM::setPage); + QAction *action; action = menu->addAction(QIcon::fromTheme("view-history"), i18n("History")); signalMapper->setMapping(action, "history"); - connect(action, SIGNAL(triggered()), - signalMapper, SLOT(map())); - connect(signalMapper, SIGNAL(mapped(QString)), - this, SLOT(setPage(QString))); + connect(action, &QAction::triggered, signalMapper, QOverload<>::of(&QSignalMapper::map)); + action = menu->addAction(QIcon::fromTheme("preferences-other"), i18n("Settings")); signalMapper->setMapping(action, "settings"); - connect(action, SIGNAL(triggered()), - signalMapper, SLOT(map())); - connect(signalMapper, SIGNAL(mapped(QString)), - this, SLOT(setPage(QString))); + connect(action, &QAction::triggered, signalMapper, QOverload<>::of(&QSignalMapper::map)); // Only show help menu if not on System Settings if (!args.isEmpty()) { // adds the help menu //! KHelpMenu *helpMenu = new KHelpMenu(this, KGlobal::mainComponent().aboutData()); //! menu->addMenu(helpMenu->menu()); } // Make sure the search bar is visible ui->stackedWidgetBar->setCurrentIndex(BAR_SEARCH); } void ApperKCM::setupHomeModel() { KCategorizedSortFilterProxyModel *oldProxy = m_groupsProxyModel; m_groupsProxyModel = new KCategorizedSortFilterProxyModel(this); m_groupsProxyModel->setSourceModel(m_groupsModel); m_groupsProxyModel->setCategorizedModel(true); m_groupsProxyModel->sort(0); ui->homeView->setModel(m_groupsProxyModel); if (oldProxy) { oldProxy->deleteLater(); } } void ApperKCM::genericActionKTriggered() { m_currentAction->trigger(); } void ApperKCM::setCurrentAction(QAction *action) { // just load the new action if it changes this // also ensures that our menu has more than one action if (m_currentAction != action) { // hides the item from the list action->setVisible(false); // ensures the current action was created if (m_currentAction) { // show the item back in the list m_currentAction->setVisible(true); } m_currentAction = action; // copy data from the curront action m_genericActionK->setText(m_currentAction->text()); m_genericActionK->setIcon(m_currentAction->icon()); } } void ApperKCM::setCurrentActionEnabled(bool state) { if (m_currentAction) { m_currentAction->setEnabled(state); } m_genericActionK->setEnabled(state); } void ApperKCM::setCurrentActionCancel(bool cancel) { if (cancel) { // every action should like cancel ui->actionFindName->setText(i18n("&Cancel")); ui->actionFindFile->setText(i18n("&Cancel")); ui->actionFindDescription->setText(i18n("&Cancel")); m_genericActionK->setText(i18n("&Cancel")); // set cancel icons ui->actionFindFile->setIcon(m_cancelIcon); ui->actionFindDescription->setIcon(m_cancelIcon); ui->actionFindName->setIcon(m_cancelIcon); m_genericActionK->setIcon(m_cancelIcon); } else { ui->actionFindName->setText(i18n("Find by &name")); ui->actionFindFile->setText(i18n("Find by f&ile name")); ui->actionFindDescription->setText(i18n("Find by &description")); // Define actions icon ui->actionFindFile->setIcon(QIcon::fromTheme("document-open")); ui->actionFindDescription->setIcon(QIcon::fromTheme("document-edit")); ui->actionFindName->setIcon(m_findIcon); m_genericActionK->setIcon(m_findIcon); if (m_currentAction) { m_genericActionK->setText(m_currentAction->text()); } else { // This might happen when the backend can // only search groups m_genericActionK->setText(i18n("Find")); } } } void ApperKCM::checkChanged() { bool hasChanges = false; if (ui->stackedWidget->currentWidget() == ui->pageHome || ui->stackedWidget->currentWidget() == ui->pageChanges || ui->stackedWidget->currentWidget() == ui->pageBrowse) { hasChanges = m_browseModel->hasChanges(); if (!hasChanges && ui->stackedWidget->currentWidget() == ui->pageChanges) { search(); } ui->changesPB->setEnabled(hasChanges); } else if (ui->stackedWidget->currentWidget() == m_updaterPage) { hasChanges = m_updaterPage->hasChanges(); } else if (ui->stackedWidget->currentWidget() == m_settingsPage) { hasChanges = m_settingsPage->hasChanges(); } emit changed(hasChanges); } void ApperKCM::errorCode(PackageKit::Transaction::Error error, const QString &details) { if (error != Transaction::ErrorTransactionCancelled) { KMessageBox::detailedSorry(this, PkStrings::errorMessage(error), details, PkStrings::error(error), KMessageBox::Notify); } } ApperKCM::~ApperKCM() { delete ui; } void ApperKCM::daemonChanged() { Transaction::Roles roles = Daemon::roles(); if (m_roles == roles) { return; } m_roles = roles; // Add actions that the backend supports ui->actionFindName->setEnabled(roles & Transaction::RoleSearchName); ui->actionFindDescription->setEnabled(roles & Transaction::RoleSearchDetails); ui->actionFindFile->setEnabled(roles & Transaction::RoleSearchFile); ui->browseView->init(roles); m_groupsModel->setRoles(roles); m_filtersMenu->setFilters(Daemon::filters()); } void ApperKCM::on_actionFindName_triggered() { setCurrentAction(ui->actionFindName); if (!ui->searchKLE->text().isEmpty()) { // cache the search - m_searchRole = Transaction::RoleSearchName; - m_searchString = ui->searchKLE->text(); + m_searchRole = Transaction::RoleSearchName; + m_searchString = ui->searchKLE->text(); // create the main transaction search(); } } void ApperKCM::on_actionFindDescription_triggered() { setCurrentAction(ui->actionFindDescription); if (!ui->searchKLE->text().isEmpty()) { // cache the search - m_searchRole = Transaction::RoleSearchDetails; - m_searchString = ui->searchKLE->text(); + m_searchRole = Transaction::RoleSearchDetails; + m_searchString = ui->searchKLE->text(); // create the main transaction search(); } } void ApperKCM::on_actionFindFile_triggered() { setCurrentAction(ui->actionFindFile); if (!ui->searchKLE->text().isEmpty()) { // cache the search m_searchRole = Transaction::RoleSearchFile; m_searchString = ui->searchKLE->text(); // create the main transaction search(); } } void ApperKCM::on_homeView_activated(const QModelIndex &index) { if (index.isValid()) { - const QSortFilterProxyModel *proxy; - proxy = qobject_cast(index.model()); + const auto proxy = qobject_cast(index.model()); // If the cast failed it's the index came from browseView if (proxy) { m_searchParentCategory = proxy->mapToSource(index); } else { m_searchParentCategory = index; } // cache the search m_searchRole = static_cast(index.data(CategoryModel::SearchRole).toUInt()); qCDebug(APPER) << m_searchRole << index.data(CategoryModel::CategoryRole).toString(); if (m_searchRole == Transaction::RoleResolve) { #ifdef HAVE_APPSTREAM CategoryMatcher parser = index.data(CategoryModel::CategoryRole).value(); m_searchCategory = AppStream::instance()->findPkgNames(parser); #endif // HAVE_APPSTREAM } else if (m_searchRole == Transaction::RoleSearchGroup) { if (index.data(CategoryModel::GroupRole).type() == QVariant::String) { QString category = index.data(CategoryModel::GroupRole).toString(); if (category.startsWith('@') || (category.startsWith(QLatin1String("repo:")) && category.size() > 5)) { m_searchGroupCategory = category; } else { m_groupsModel->setRootIndex(m_searchParentCategory); ui->backTB->setEnabled(true); return; } } else { m_searchGroupCategory.clear(); int groupRole = index.data(CategoryModel::GroupRole).toInt(); m_searchGroup = static_cast(groupRole); m_searchString = index.data().toString(); // Store the nice name to change the title } } else if (m_searchRole == Transaction::RoleGetUpdates) { setPage("updates"); return; } // create the main transaction search(); } } bool ApperKCM::canChangePage() { bool changed; // Check if we can change the current page if (ui->stackedWidget->currentWidget() == m_updaterPage) { changed = m_updaterPage->hasChanges(); } else if (ui->stackedWidget->currentWidget() == m_settingsPage) { changed = m_settingsPage->hasChanges(); } else { changed = m_browseModel->hasChanges(); } // if there are no changes don't ask the user if (!changed) { return true; } const int queryUser = KMessageBox::warningYesNoCancel( this, i18n("The settings of the current module have changed.\n" "Do you want to apply the changes or discard them?"), i18n("Apply Settings"), KStandardGuiItem::apply(), KStandardGuiItem::discard(), KStandardGuiItem::cancel()); switch (queryUser) { case KMessageBox::Yes: save(); return true; case KMessageBox::No: load(); return true; case KMessageBox::Cancel: return false; default: return false; } } QString ApperKCM::page() const { return QString(); } void ApperKCM::setPage(const QString &page) { - PkTransaction *transaction = qobject_cast(ui->stackedWidget->currentWidget()); + auto transaction = qobject_cast(ui->stackedWidget->currentWidget()); if (transaction) { return; } if (page == QLatin1String("settings")) { if (ui->stackedWidget->currentWidget() != m_settingsPage) { if (!canChangePage()) { return; } if (m_settingsPage == 0) { m_settingsPage = new Settings(m_roles, this); - connect(m_settingsPage, SIGNAL(changed(bool)), - this, SLOT(checkChanged())); - connect(m_settingsPage, SIGNAL(refreshCache()), - SLOT(refreshCache())); + connect(m_settingsPage, &Settings::changed, this, &ApperKCM::checkChanged); + connect(m_settingsPage, &Settings::refreshCache, this, &ApperKCM::refreshCache); ui->stackedWidget->addWidget(m_settingsPage); - connect(ui->generalSettingsPB, SIGNAL(toggled(bool)), - m_settingsPage, SLOT(showGeneralSettings())); - connect(ui->repoSettingsPB, SIGNAL(toggled(bool)), - m_settingsPage, SLOT(showRepoSettings())); + connect(ui->generalSettingsPB, &QPushButton::toggled, m_settingsPage, &Settings::showGeneralSettings); + connect(ui->repoSettingsPB, &QPushButton::toggled, m_settingsPage, &Settings::showRepoSettings); } checkChanged(); setButtons(KCModule::Default | KCModule::Apply); emit changed(true); // THIS IS DUMB setButtons only take effect after changed goes true emit changed(false); ui->generalSettingsPB->setChecked(true); ui->stackedWidgetBar->setCurrentIndex(BAR_SETTINGS); ui->stackedWidget->setCurrentWidget(m_settingsPage); m_settingsPage->load(); ui->titleL->clear(); ui->backTB->setEnabled(true); emit caption(i18n("Settings")); } } else if (page == QLatin1String("updates")) { if (ui->stackedWidget->currentWidget() != m_updaterPage) { if (!canChangePage()) { return; } if (m_updaterPage == 0) { m_updaterPage = new Updater(m_roles, this); - connect(m_updaterPage, SIGNAL(refreshCache()), - this, SLOT(refreshCache())); - connect(m_updaterPage, SIGNAL(downloadSize(QString)), - ui->downloadL, SLOT(setText(QString))); - connect(m_updaterPage, SIGNAL(changed(bool)), - this, SLOT(checkChanged())); + connect(m_updaterPage, &Updater::refreshCache, this, &ApperKCM::refreshCache); + connect(m_updaterPage, &Updater::downloadSize, ui->downloadL, &QLabel::setText); + connect(m_updaterPage, &Updater::changed, this, &ApperKCM::checkChanged); ui->stackedWidget->addWidget(m_updaterPage); ui->checkUpdatesPB->setIcon(QIcon::fromTheme("view-refresh")); - connect(ui->checkUpdatesPB, SIGNAL(clicked(bool)), - this, SLOT(refreshCache())); + connect(ui->checkUpdatesPB, &QPushButton::clicked, this, &ApperKCM::refreshCache); } checkChanged(); ui->stackedWidget->setCurrentWidget(m_updaterPage); m_updaterPage->load(); ui->stackedWidgetBar->setCurrentIndex(BAR_UPDATE); ui->backTB->setEnabled(true); emit caption(i18n("Updates")); } } else if (page == QLatin1String("home")) { if (ui->stackedWidget->currentWidget() == m_updaterPage || ui->stackedWidget->currentWidget() == m_settingsPage) { on_backTB_clicked(); } } else if (page == QLatin1String("history")) { m_history = new TransactionHistory(this); ui->searchKLE->clear(); - connect(ui->searchKLE, SIGNAL(textChanged(QString)), - m_history, SLOT(setFilterRegExp(QString))); + connect(ui->searchKLE, &QLineEdit::textChanged, m_history, &TransactionHistory::setFilterRegExp); ui->stackedWidget->addWidget(m_history); ui->stackedWidget->setCurrentWidget(m_history); ui->backTB->setEnabled(true); ui->filtersTB->setEnabled(false); ui->widget->setEnabled(false); emit caption(i18n("History")); } } void ApperKCM::on_backTB_clicked() { bool canGoBack = false; if (ui->stackedWidget->currentWidget() == ui->pageBrowse) { if (!ui->browseView->goBack()) { return; } else if (m_groupsModel->hasParent()) { canGoBack = true; } } else if (ui->stackedWidget->currentWidget() == m_history) { ui->filtersTB->setEnabled(true); ui->widget->setEnabled(true); m_history->deleteLater(); m_history = 0; } else if (ui->stackedWidget->currentWidget() == ui->pageHome) { if (m_groupsModel->setParentIndex()) { // if we are able to set a new parent item // do not disable back button return; } } else if (ui->stackedWidget->currentWidget() == m_updaterPage) { if (!canChangePage()) { return; } ui->stackedWidgetBar->setCurrentIndex(BAR_SEARCH); checkChanged(); } else if (ui->stackedWidget->currentWidget() == m_settingsPage) { if (!canChangePage()) { return; } setButtons(Apply); emit changed(true); // THIS IS DUMB setButtons only take effect after changed goes true ui->stackedWidgetBar->setCurrentIndex(BAR_SEARCH); checkChanged(); } ui->homeView->selectionModel()->clear(); ui->stackedWidget->setCurrentWidget(ui->pageHome); ui->backTB->setEnabled(canGoBack); // reset the search role m_searchRole = Transaction::RoleUnknown; emit caption(); } void ApperKCM::on_changesPB_clicked() { m_changesModel->clear(); m_changesModel->addSelectedPackagesFromModel(m_browseModel); ui->stackedWidget->setCurrentWidget(ui->pageChanges); ui->backTB->setEnabled(true); emit caption(i18n("Pending Changes")); } void ApperKCM::disconnectTransaction() { if (m_searchTransaction) { // Disconnect everything so that the model don't store // wrong data m_searchTransaction->cancel(); - disconnect(m_searchTransaction, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), - ui->browseView->busyCursor(), SLOT(stop())); - disconnect(m_searchTransaction, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), - this, SLOT(finished())); - disconnect(m_searchTransaction, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), - m_browseModel, SLOT(finished())); - disconnect(m_searchTransaction, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), - m_browseModel, SLOT(fetchSizes())); - disconnect(m_searchTransaction, SIGNAL(package(PackageKit::Transaction::Info,QString,QString)), - m_browseModel, SLOT(addPackage(PackageKit::Transaction::Info,QString,QString))); - disconnect(m_searchTransaction, SIGNAL(errorCode(PackageKit::Transaction::Error,QString)), - this, SLOT(errorCode(PackageKit::Transaction::Error,QString))); + disconnect(m_searchTransaction, &Transaction::finished, ui->browseView->busyCursor(), &KPixmapSequenceOverlayPainter::stop); + disconnect(m_searchTransaction, &Transaction::finished, this, &ApperKCM::finished); + disconnect(m_searchTransaction, &Transaction::finished, m_browseModel, &PackageModel::finished); + disconnect(m_searchTransaction, &Transaction::finished, m_browseModel, &PackageModel::fetchSizes); + disconnect(m_searchTransaction, &Transaction::package, m_browseModel, &PackageModel::addNotSelectedPackage); + disconnect(m_searchTransaction, &Transaction::errorCode, this, &ApperKCM::errorCode); } } void ApperKCM::search() { ui->browseView->cleanUi(); if (ui->stackedWidgetBar->currentIndex() != BAR_SEARCH) { ui->stackedWidgetBar->setCurrentIndex(BAR_SEARCH); } disconnectTransaction(); // search switch (m_searchRole) { case Transaction::RoleSearchName: m_searchTransaction = Daemon::searchNames(m_searchString, m_filtersMenu->filters()); emit caption(m_searchString); break; case Transaction::RoleSearchDetails: m_searchTransaction = Daemon::searchDetails(m_searchString, m_filtersMenu->filters()); emit caption(m_searchString); break; case Transaction::RoleSearchFile: m_searchTransaction = Daemon::searchFiles(m_searchString, m_filtersMenu->filters()); emit caption(m_searchString); break; case Transaction::RoleSearchGroup: if (m_searchGroupCategory.isEmpty()) { m_searchTransaction = Daemon::searchGroup(m_searchGroup, m_filtersMenu->filters()); // m_searchString has the group nice name emit caption(m_searchString); } else { ui->browseView->setParentCategory(m_searchParentCategory); emit caption(m_searchParentCategory.data().toString()); #ifndef HAVE_APPSTREAM - if (m_searchGroupCategory.startsWith('@') || + if (m_searchGroupCategory.startsWith(QLatin1Char('@')) || m_searchGroupCategory.startsWith(QLatin1String("repo:"))) { m_searchTransaction = Daemon::searchGroup(m_searchGroupCategory, m_filtersMenu->filters()); } #endif // else the transaction is useless } break; case Transaction::RoleGetPackages: // we want all the installed ones ui->browseView->disableExportInstalledPB(); m_searchTransaction = Daemon::getPackages(Transaction::FilterInstalled | m_filtersMenu->filters()); - connect(m_searchTransaction, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), - ui->browseView, SLOT(enableExportInstalledPB())); + connect(m_searchTransaction, &Transaction::finished, ui->browseView, &BrowseView::enableExportInstalledPB); emit caption(i18n("Installed Software")); break; case Transaction::RoleResolve: #ifdef HAVE_APPSTREAM if (!m_searchCategory.isEmpty()) { ui->browseView->setParentCategory(m_searchParentCategory); // WARNING the resolve might fail if the backend // has a low limit MaximumItemsToResolve m_searchTransaction = Daemon::resolve(m_searchCategory, m_filtersMenu->filters()); emit caption(m_searchParentCategory.data().toString()); } else { ui->browseView->setParentCategory(m_searchParentCategory); KMessageBox::sorry(this, i18n("Could not find an application that matched this category")); emit caption(); disconnectTransaction(); m_searchTransaction = 0; return; } break; #endif default: qCWarning(APPER) << "Search type not defined yet"; emit caption(); disconnectTransaction(); m_searchTransaction = 0; return; } - connect(m_searchTransaction, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), - ui->browseView->busyCursor(), SLOT(stop())); - connect(m_searchTransaction, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), - this, SLOT(finished())); - connect(m_searchTransaction, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), - m_browseModel, SLOT(finished())); + connect(m_searchTransaction, &Transaction::finished, ui->browseView->busyCursor(), &KPixmapSequenceOverlayPainter::stop); + connect(m_searchTransaction, &Transaction::finished, this, &ApperKCM::finished); + connect(m_searchTransaction, &Transaction::finished, m_browseModel, &PackageModel::finished); + if (ui->browseView->isShowingSizes()) { - connect(m_searchTransaction, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), - m_browseModel, SLOT(fetchSizes())); + connect(m_searchTransaction, &Transaction::finished, m_browseModel, &PackageModel::fetchSizes); } - connect(m_searchTransaction, SIGNAL(package(PackageKit::Transaction::Info,QString,QString)), - m_browseModel, SLOT(addPackage(PackageKit::Transaction::Info,QString,QString))); - connect(m_searchTransaction, SIGNAL(errorCode(PackageKit::Transaction::Error,QString)), - this, SLOT(errorCode(PackageKit::Transaction::Error,QString))); + connect(m_searchTransaction, &Transaction::package, m_browseModel, &PackageModel::addNotSelectedPackage); + connect(m_searchTransaction, &Transaction::errorCode, this, &ApperKCM::errorCode); // cleans the models m_browseModel->clear(); ui->browseView->showInstalledPanel(m_searchRole == Transaction::RoleGetPackages); ui->browseView->busyCursor()->start(); ui->backTB->setEnabled(true); setCurrentActionCancel(true); setCurrentActionEnabled(m_searchTransaction->allowCancel()); ui->stackedWidget->setCurrentWidget(ui->pageBrowse); } void ApperKCM::changed() { Transaction *trans = qobject_cast(sender()); setCurrentActionEnabled(trans->allowCancel()); } void ApperKCM::refreshCache() { emit changed(false); QWidget *currentWidget = ui->stackedWidget->currentWidget(); - PkTransactionWidget *transactionW = new PkTransactionWidget(this); - connect(transactionW, SIGNAL(titleChangedProgress(QString)), this, SIGNAL(caption(QString))); + auto transactionW = new PkTransactionWidget(this); + connect(transactionW, &PkTransactionWidget::titleChangedProgress, this, &ApperKCM::caption); QPointer transaction = new PkTransaction(transactionW); Daemon::setHints (QLatin1String("cache-age=")+QString::number(m_cacheAge)); transaction->refreshCache(m_forceRefreshCache); transactionW->setTransaction(transaction, Transaction::RoleRefreshCache); ui->stackedWidget->addWidget(transactionW); ui->stackedWidget->setCurrentWidget(transactionW); ui->stackedWidgetBar->setCurrentIndex(BAR_TITLE); ui->backTB->setEnabled(false); - connect(transactionW, SIGNAL(titleChanged(QString)), - ui->titleL, SLOT(setText(QString))); + connect(transactionW, &PkTransactionWidget::titleChanged, ui->titleL, &QLabel::setText); QEventLoop loop; - connect(transaction, SIGNAL(finished(PkTransaction::ExitStatus)), &loop, SLOT(quit())); + connect(transaction, &PkTransaction::finished, &loop, &QEventLoop::quit); // wait for the end of transaction if (!transaction->isFinished()) { loop.exec(); if (!transaction) { // Avoid crashing return; } // If the refresh failed force next refresh Cache call m_forceRefreshCache = transaction->exitStatus() == PkTransaction::Failed; } if (m_updaterPage) { m_updaterPage->getUpdates(); } if (currentWidget == m_settingsPage) { setPage("settings"); } else { setPage("updates"); } - QTimer::singleShot(0, this, SLOT(checkChanged())); + QTimer::singleShot(0, this, &ApperKCM::checkChanged); } void ApperKCM::save() { QWidget *currentWidget = ui->stackedWidget->currentWidget(); if (currentWidget == m_settingsPage) { m_settingsPage->save(); } else { - PkTransactionWidget *transactionW = new PkTransactionWidget(this); - connect(transactionW, SIGNAL(titleChangedProgress(QString)), this, SIGNAL(caption(QString))); + auto transactionW = new PkTransactionWidget(this); + connect(transactionW, &PkTransactionWidget::titleChangedProgress, this, &ApperKCM::caption); QPointer transaction = new PkTransaction(transactionW); ui->stackedWidget->addWidget(transactionW); ui->stackedWidget->setCurrentWidget(transactionW); ui->stackedWidgetBar->setCurrentIndex(BAR_TITLE); ui->backTB->setEnabled(false); - connect(transactionW, SIGNAL(titleChanged(QString)), - ui->titleL, SLOT(setText(QString))); + connect(transactionW, &PkTransactionWidget::titleChanged, ui->titleL, &QLabel::setText); emit changed(false); QEventLoop loop; - connect(transaction, SIGNAL(finished(PkTransaction::ExitStatus)), &loop, SLOT(quit())); + connect(transaction, &PkTransaction::finished, &loop, &QEventLoop::quit); if (currentWidget == m_updaterPage) { transaction->updatePackages(m_updaterPage->packagesToUpdate()); transactionW->setTransaction(transaction, Transaction::RoleUpdatePackages); // wait for the end of transaction if (!transaction->isFinished()) { loop.exec(); if (!transaction) { // Avoid crashing return; } } } else { // install then remove packages QStringList installPackages = m_browseModel->selectedPackagesToInstall(); if (!installPackages.isEmpty()) { transaction->installPackages(installPackages); transactionW->setTransaction(transaction, Transaction::RoleInstallPackages); // wait for the end of transaction if (!transaction->isFinished()) { loop.exec(); if (!transaction) { // Avoid crashing return; } } if (transaction->exitStatus() == PkTransaction::Success) { m_browseModel->uncheckAvailablePackages(); } } QStringList removePackages = m_browseModel->selectedPackagesToRemove(); if (!removePackages.isEmpty()) { transaction->removePackages(removePackages); transactionW->setTransaction(transaction, Transaction::RoleRemovePackages); // wait for the end of transaction if (!transaction->isFinished()) { loop.exec(); if (!transaction) { // Avoid crashing return; } } if (transaction->exitStatus() == PkTransaction::Success) { m_browseModel->uncheckInstalledPackages(); } } } transaction->deleteLater(); if (currentWidget == m_updaterPage) { m_updaterPage->getUpdates(); setPage("updates"); } else { // install then remove packages search(); } - QTimer::singleShot(0, this, SLOT(checkChanged())); + QTimer::singleShot(0, this, &ApperKCM::checkChanged); } } void ApperKCM::load() { if (ui->stackedWidget->currentWidget() == m_updaterPage) { m_updaterPage->load(); } else if (ui->stackedWidget->currentWidget() == m_settingsPage) { m_settingsPage->load(); } else { // set focus on the search lineEdit ui->searchKLE->setFocus(Qt::OtherFocusReason); m_browseModel->setAllChecked(false); } } void ApperKCM::defaults() { if (ui->stackedWidget->currentWidget() == m_settingsPage) { m_settingsPage->defaults(); } } void ApperKCM::finished() { // if m_currentAction is false means that our // find button should be disable as there aren't any // search methods setCurrentActionEnabled(m_currentAction); setCurrentActionCancel(false); m_searchTransaction = 0; } void ApperKCM::keyPressEvent(QKeyEvent *event) { if (ui->searchKLE->hasFocus() && ui->stackedWidget->currentWidget() != m_history && (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter)) { // special tab handling here m_currentAction->trigger(); return; } KCModule::keyPressEvent(event); } void ApperKCM::closeEvent(QCloseEvent *event) { // PkTransaction *transaction = qobject_cast(stackedWidget->currentWidget()); // if (transaction) { event->ignore(); // } else { // event->accept(); // } } #include "ApperKCM.moc" diff --git a/ApperKCM/BrowseView.cpp b/ApperKCM/BrowseView.cpp index 5cf1e6e..1c7c23c 100644 --- a/ApperKCM/BrowseView.cpp +++ b/ApperKCM/BrowseView.cpp @@ -1,338 +1,336 @@ /*************************************************************************** * Copyright (C) 2009-2010 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "BrowseView.h" #include "PackageDetails.h" #include "CategoryModel.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace PackageKit; BrowseView::BrowseView(QWidget *parent) : QWidget(parent) { setupUi(this); - connect(categoryView, SIGNAL(clicked(QModelIndex)), - this, SIGNAL(categoryActivated(QModelIndex))); + connect(categoryView, &QListView::clicked, this, &BrowseView::categoryActivated); m_busySeq = new KPixmapSequenceOverlayPainter(this); m_busySeq->setSequence(KPixmapSequence("process-working", KIconLoader::SizeSmallMedium)); m_busySeq->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); m_busySeq->setWidget(packageView->viewport()); m_model = new PackageModel(this); m_proxy = new ApplicationSortFilterModel(this); m_proxy->setSourceModel(m_model); packageView->setModel(m_proxy); packageView->sortByColumn(PackageModel::NameCol, Qt::AscendingOrder); packageView->header()->setDefaultAlignment(Qt::AlignCenter); packageView->header()->setStretchLastSection(false); packageView->header()->setSectionResizeMode(PackageModel::NameCol, QHeaderView::Stretch); packageView->header()->setSectionResizeMode(PackageModel::VersionCol, QHeaderView::ResizeToContents); packageView->header()->setSectionResizeMode(PackageModel::ArchCol, QHeaderView::ResizeToContents); packageView->header()->setSectionResizeMode(PackageModel::OriginCol, QHeaderView::ResizeToContents); packageView->header()->setSectionResizeMode(PackageModel::SizeCol, QHeaderView::ResizeToContents); packageView->header()->setSectionResizeMode(PackageModel::ActionCol, QHeaderView::ResizeToContents); // Hide current Version since it's useless for us packageView->header()->setSectionHidden(PackageModel::CurrentVersionCol, true); ApplicationsDelegate *delegate = new ApplicationsDelegate(packageView); packageView->setItemDelegate(delegate); exportInstalledPB->setIcon(QIcon::fromTheme("document-export")); importInstalledPB->setIcon(QIcon::fromTheme("document-import")); KConfig config("apper"); KConfigGroup viewGroup(&config, "BrowseView"); // Version packageView->header()->setSectionHidden(PackageModel::VersionCol, true); m_showPackageVersion = new QAction(i18n("Show Versions"), this); m_showPackageVersion->setCheckable(true); - connect(m_showPackageVersion, SIGNAL(toggled(bool)), this, SLOT(showVersions(bool))); + connect(m_showPackageVersion, &QAction::toggled, this, &BrowseView::showVersions); m_showPackageVersion->setChecked(viewGroup.readEntry("ShowApplicationVersions", true)); // Arch packageView->header()->setSectionHidden(PackageModel::ArchCol, true); m_showPackageArch = new QAction(i18n("Show Architectures"), this); m_showPackageArch->setCheckable(true); - connect(m_showPackageArch, SIGNAL(toggled(bool)), this, SLOT(showArchs(bool))); + connect(m_showPackageArch, &QAction::toggled, this, &BrowseView::showArchs); m_showPackageArch->setChecked(viewGroup.readEntry("ShowApplicationArchitectures", false)); // Origin packageView->header()->setSectionHidden(PackageModel::OriginCol, true); m_showPackageOrigin = new QAction(i18n("Show Origins"), this); m_showPackageOrigin->setCheckable(true); - connect(m_showPackageOrigin, SIGNAL(toggled(bool)), this, SLOT(showOrigins(bool))); + connect(m_showPackageOrigin, &QAction::toggled, this, &BrowseView::showOrigins); m_showPackageOrigin->setChecked(viewGroup.readEntry("ShowApplicationOrigins", false)); // Sizes packageView->header()->setSectionHidden(PackageModel::SizeCol, true); m_showPackageSizes = new QAction(i18n("Show Sizes"), this); m_showPackageSizes->setCheckable(true); - connect(m_showPackageSizes, SIGNAL(toggled(bool)), this, SLOT(showSizes(bool))); + connect(m_showPackageSizes, &QAction::toggled, this, &BrowseView::showSizes); m_showPackageSizes->setChecked(viewGroup.readEntry("ShowPackageSizes", false)); // Ensure the index is visible when the packageDetails appears - connect(packageDetails, SIGNAL(ensureVisible(QModelIndex)), - this, SLOT(ensureVisible(QModelIndex))); + connect(packageDetails, &PackageDetails::ensureVisible, this, &BrowseView::ensureVisible); } void BrowseView::init(Transaction::Roles roles) { packageDetails->init(roles); } BrowseView::~BrowseView() { } bool BrowseView::showPageHeader() const { return false; } PackageModel* BrowseView::model() const { return m_model; } void BrowseView::showVersions(bool enabled) { KConfig config("apper"); KConfigGroup viewGroup(&config, "BrowseView"); viewGroup.writeEntry("ShowApplicationVersions", enabled); packageView->header()->setSectionHidden(PackageModel::VersionCol, !enabled); packageDetails->hidePackageVersion(enabled); } void BrowseView::showArchs(bool enabled) { KConfig config("apper"); KConfigGroup viewGroup(&config, "BrowseView"); viewGroup.writeEntry("ShowApplicationArchitectures", enabled); packageView->header()->setSectionHidden(PackageModel::ArchCol, !enabled); packageDetails->hidePackageArch(enabled); } void BrowseView::showOrigins(bool enabled) { KConfig config("apper"); KConfigGroup viewGroup(&config, "BrowseView"); viewGroup.writeEntry("ShowApplicationOrigins", enabled); packageView->header()->setSectionHidden(PackageModel::OriginCol, !enabled); } void BrowseView::showSizes(bool enabled) { KConfig config("apper"); KConfigGroup viewGroup(&config, "BrowseView"); viewGroup.writeEntry("ShowPackageSizes", enabled); packageView->header()->setSectionHidden(PackageModel::SizeCol, !enabled); packageDetails->hidePackageArch(enabled); if (enabled) { m_model->fetchSizes(); } } void BrowseView::on_packageView_customContextMenuRequested(const QPoint &pos) { auto menu = new QMenu(this); menu->addAction(m_showPackageVersion); menu->addAction(m_showPackageArch); menu->addAction(m_showPackageOrigin); menu->addAction(m_showPackageSizes); menu->exec(packageView->viewport()->mapToGlobal(pos)); menu->deleteLater(); } void BrowseView::on_packageView_clicked(const QModelIndex &index) { if (index.column() == PackageModel::ActionCol) { return; } QModelIndex origIndex = m_proxy->mapToSource(index); packageDetails->setPackage(origIndex); } void BrowseView::ensureVisible(const QModelIndex &index) { QModelIndex proxIndex = m_proxy->mapFromSource(index); packageView->scrollTo(proxIndex); } void BrowseView::showInstalledPanel(bool visible) { installedF->setVisible(visible); } ApplicationSortFilterModel* BrowseView::proxy() const { return m_proxy; } KPixmapSequenceOverlayPainter* BrowseView::busyCursor() const { return m_busySeq; } void BrowseView::setCategoryModel(QAbstractItemModel *model) { categoryView->setModel(model); } void BrowseView::setParentCategory(const QModelIndex &index) { categoryView->setRootIndex(index); // Make sure the last item is not selected categoryView->selectionModel()->clearSelection(); categoryView->horizontalScrollBar()->setValue(0); // Display the category view if the index has child items categoryF->setVisible(categoryView->model()->rowCount(index)); } bool BrowseView::goBack() { packageDetails->hide(); QModelIndex index = categoryView->rootIndex(); if (index.parent().isValid()) { index = index.parent(); // if it's valid we need to know if it wasn't a PK root category if (index.data(CategoryModel::GroupRole).type() == QVariant::String) { QString category = index.data(CategoryModel::GroupRole).toString(); if (!category.startsWith('@')) { return true; } } setParentCategory(index); emit categoryActivated(index); return false; } return true; } void BrowseView::on_categoryMvLeft_clicked() { categoryView->horizontalScrollBar()->setValue(categoryView->horizontalScrollBar()->value() - 1); } void BrowseView::on_categoryMvRight_clicked() { categoryView->horizontalScrollBar()->setValue(categoryView->horizontalScrollBar()->value() + 1); } void BrowseView::cleanUi() { packageDetails->hide(); categoryF->setVisible(false); } bool BrowseView::isShowingSizes() const { return m_showPackageSizes->isChecked(); } void BrowseView::on_exportInstalledPB_clicked() { // We will assume the installed model // is populated since the user is seeing it. QString fileName; fileName = QFileDialog::getSaveFileName(this, i18n("Export installed packages"), QString(), QStringLiteral("*.catalog")); if (fileName.isEmpty()) { return; } QFile file(fileName); file.open(QIODevice::WriteOnly); QTextStream out(&file); out << "[PackageKit Catalog]\n\n"; out << "InstallPackages(" << Daemon::global()->distroID() << ")="; QStringList packages; for (int i = 0; i < m_model->rowCount(); i++) { packages << m_model->data(m_model->index(i, 0), PackageModel::PackageName).toString(); } - out << packages.join(";"); + out << packages.join(QLatin1Char(';')); } void BrowseView::on_importInstalledPB_clicked() { QString fileName; fileName = QFileDialog::getOpenFileName(this, i18n("Install packages from catalog"), QString(), QStringLiteral("*.catalog")); if (fileName.isEmpty()) { return; } // send a DBus message to install this catalog QDBusMessage message; message = QDBusMessage::createMethodCall("org.freedesktop.PackageKit", "/org/freedesktop/PackageKit", "org.freedesktop.PackageKit.Modify", "InstallCatalogs"); message << static_cast(effectiveWinId()); message << (QStringList() << fileName); message << QString(); // This call must block otherwise this application closes before // smarticon is activated QDBusMessage reply = QDBusConnection::sessionBus().call(message, QDBus::Block); } void BrowseView::disableExportInstalledPB() { exportInstalledPB->setEnabled(false); } void BrowseView::enableExportInstalledPB() { exportInstalledPB->setEnabled(true); } diff --git a/ApperKCM/CategoryModel.cpp b/ApperKCM/CategoryModel.cpp index 08e4e41..91080c3 100644 --- a/ApperKCM/CategoryModel.cpp +++ b/ApperKCM/CategoryModel.cpp @@ -1,421 +1,419 @@ /*************************************************************************** * Copyright (C) 2010-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "CategoryModel.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include Q_DECLARE_LOGGING_CATEGORY(APPER) using namespace PackageKit; CategoryModel::CategoryModel(QObject *parent) : QStandardItemModel(parent) { QStandardItem *item; item = new QStandardItem(i18n("Installed Software")); item->setDragEnabled(false); item->setData(Transaction::RoleGetPackages, SearchRole); item->setData(i18n("Lists"), KCategorizedSortFilterProxyModel::CategoryDisplayRole); item->setData(0, KCategorizedSortFilterProxyModel::CategorySortRole); item->setIcon(QIcon::fromTheme("dialog-ok-apply")); appendRow(item); item = new QStandardItem(i18n("Updates")); item->setDragEnabled(false); item->setData(Transaction::RoleGetUpdates, SearchRole); item->setData(i18n("Lists"), KCategorizedSortFilterProxyModel::CategoryDisplayRole); item->setData(0, KCategorizedSortFilterProxyModel::CategorySortRole); item->setIcon(QIcon::fromTheme("system-software-update")); appendRow(item); #ifdef HAVE_APPSTREAM // Get the groups #ifdef AS_CATEGORIES_PATH fillWithServiceGroups(); #else fillWithStandardGroups(); #endif // AS_CATEGORIES_PATH // category("", // "servers", // "Servers", // "const QString &summary", // "computer"); // category("servers", // "@coomputer", // "Lighttpd", // "const QString &summary", // "emblem-new"); // category("servers", // "@coomputer2", // "Apache", // "const QString &summary", // "dialog-cancel"); #else #endif //HAVE_APPSTREAM QTimer::singleShot(0, this, SIGNAL(finished())); } CategoryModel::~CategoryModel() { } void CategoryModel::setRoles(Transaction::Roles roles) { m_roles = roles; removeRows(2, rowCount() - 2); QDBusPendingReply > transactions = Daemon::getTransactionList(); transactions.waitForFinished(); if (m_roles & Transaction::RoleGetCategories && transactions.value().isEmpty()) { Transaction *trans = Daemon::getCategories(); - connect(trans, SIGNAL(category(QString,QString,QString,QString,QString)), - this, SLOT(category(QString,QString,QString,QString,QString))); - connect(trans, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), - this, SIGNAL(finished())); + connect(trans, &Transaction::category, this, &CategoryModel::category); + connect(trans, &Transaction::finished, this, &CategoryModel::finished); } else { fillWithStandardGroups(); } } QModelIndex CategoryModel::index(int row, int column, const QModelIndex &parent) const { if (parent.isValid()) { return QStandardItemModel::index(row, column, parent); } return QStandardItemModel::index(row, column, m_rootIndex); } int CategoryModel::rowCount(const QModelIndex &parent) const { if (parent.isValid()) { return QStandardItemModel::rowCount(parent); } return QStandardItemModel::rowCount(m_rootIndex); } void CategoryModel::setRootIndex(const QModelIndex &index) { beginResetModel(); m_rootIndex = index; endResetModel(); emit finished(); } bool CategoryModel::setParentIndex() { if (m_rootIndex.isValid()) { setRootIndex(m_rootIndex.parent()); // Return the future parent so that Back button can be disabled return m_rootIndex.parent().isValid(); } // if there is no higher level return false return false; } bool CategoryModel::hasParent() const { return m_rootIndex.isValid(); } void CategoryModel::category(const QString &parentId, const QString &categoryId, const QString &name, const QString &summary, const QString &icon) { qCDebug(APPER) << parentId << categoryId << name << summary << icon; - QStandardItem *item = new QStandardItem(name); + auto item = new QStandardItem(name); item->setDragEnabled(false); item->setData(Transaction::RoleSearchGroup, SearchRole); item->setData(categoryId, GroupRole); item->setData(i18n("Categories"), KCategorizedSortFilterProxyModel::CategoryDisplayRole); item->setData(2, KCategorizedSortFilterProxyModel::CategorySortRole); item->setToolTip(summary); item->setIcon(QIcon("/usr/share/pixmaps/comps/" + icon + ".png")); if (parentId.isEmpty()) { appendRow(item); } else { QStandardItem *parent = findCategory(parentId); if (parent) { item->setData(parent->text(), KCategorizedSortFilterProxyModel::CategoryDisplayRole); item->setData(2, KCategorizedSortFilterProxyModel::CategorySortRole); parent->appendRow(item); } else { appendRow(item); } } // This is a MUST since the spacing needs to be fixed emit finished(); } QStandardItem* CategoryModel::findCategory(const QString &categoryId, const QModelIndex &parent) const { - QStandardItem *ret = 0; + QStandardItem *ret = nullptr; for (int i = 0; i < rowCount(parent); i++) { QModelIndex group = index(i, 0, parent); if (group.data(SearchRole).toUInt() == Transaction::RoleSearchGroup && group.data(GroupRole).toString() == categoryId) { ret = itemFromIndex(group); } else if (hasChildren(group)) { ret = findCategory(categoryId, group); } if (ret) { break; } } return ret; } void CategoryModel::fillWithStandardGroups() { // Get the groups m_groups = Daemon::global()->groups(); qCDebug(APPER); QStandardItem *item; for (int i = 1; i < 64; ++i) { if (m_groups & i) { Transaction::Group group; group = static_cast(i); if (group != Transaction::GroupUnknown) { item = new QStandardItem(PkStrings::groups(group)); item->setDragEnabled(false); item->setData(Transaction::RoleSearchGroup, SearchRole); item->setData(group, GroupRole); item->setData(i18n("Groups"), KCategorizedSortFilterProxyModel::CategoryDisplayRole); item->setData(1, KCategorizedSortFilterProxyModel::CategorySortRole); item->setIcon(PkIcons::groupsIcon(group)); if (!(m_roles & Transaction::RoleSearchGroup)) { item->setSelectable(false); } appendRow(item); } } } emit finished(); } void CategoryModel::fillWithServiceGroups() { #ifdef AS_CATEGORIES_PATH KLocale::global()->insertCatalog("gnome-menus"); QFile file(QString(AS_CATEGORIES_PATH) + "/categories.xml"); if (!file.open(QIODevice::ReadOnly)) { qCDebug(APPER) << "Failed to open file"; fillWithStandardGroups(); return; } QXmlStreamReader xml(&file); while(xml.readNextStartElement() && !xml.hasError()) { // Read next element. if(xml.tokenType() == QXmlStreamReader::StartDocument) { // qCDebug(APPER) << "StartDocument"; continue; } if(xml.name() == "Menu") { parseMenu(xml, QString()); } } #endif //AS_CATEGORIES_PATH } void CategoryModel::parseMenu(QXmlStreamReader &xml, const QString &parentIcon, QStandardItem *parent) { QString icon = parentIcon; QStandardItem *item = 0; while(!xml.atEnd() && !(xml.tokenType() == QXmlStreamReader::EndElement && xml.name() == QLatin1String("Menu"))) { if(xml.tokenType() == QXmlStreamReader::StartElement) { if (xml.name() == QLatin1String("Menu")) { xml.readNext(); parseMenu(xml, icon, item); } else if (xml.name() == QLatin1String("Name")) { QString name = xml.readElementText(); if (!item) { item = new QStandardItem(i18n(name.toUtf8().data())); item->setDragEnabled(false); } else if (item->text().isEmpty()) { item->setText(i18n(name.toUtf8().data())); } } else if (xml.name() == QLatin1String("Icon")) { if (!item) { item = new QStandardItem; item->setDragEnabled(false); } // only sets the icon if it wasn't set, // the .directory might have a better one QString _icon; _icon = xml.readElementText(); if (item->icon().isNull()) { item->setIcon(PkIcons::getIcon(_icon, icon)); icon = _icon; } } else if (xml.name() == QLatin1String("Categories")) { QList categories; categories = parseCategories(xml); if (!categories.isEmpty()) { if (!item) { item = new QStandardItem; item->setDragEnabled(false); } // If we only have one category inside get the first item if (categories.size() == 1) { item->setData(qVariantFromValue(categories.first()), CategoryRole); } else { CategoryMatcher parser(CategoryMatcher::And); parser.setChild(categories); item->setData(qVariantFromValue(parser), CategoryRole); } item->setData(Transaction::RoleResolve, SearchRole); } } else if (xml.name() == QLatin1String("Directory")) { if (!item) { item = new QStandardItem; item->setDragEnabled(false); } QString directory = xml.readElementText(); const KDesktopFile desktopFile(directory); const KConfigGroup config = desktopFile.desktopGroup(); QString _icon = config.readEntry("Icon"); QString _name = config.readEntry("Name"); if (!_icon.isEmpty()) { item->setIcon(PkIcons::getIcon(_icon, icon)); icon = _icon; } if (!_name.isEmpty()) { item->setText(_name); } } else if (xml.name() == QLatin1String("PkGroups")) { if (!item) { item = new QStandardItem; item->setDragEnabled(false); } QString group = xml.readElementText(); Transaction::Group groupEnum; int groupInt = Daemon::enumFromString(group, "Group"); groupEnum = static_cast(groupInt); if (groupEnum != Transaction::GroupUnknown && m_groups & groupEnum) { item->setData(Transaction::RoleSearchGroup, SearchRole); item->setData(groupEnum, GroupRole); } } } // next... xml.readNext(); } if (item && (!item->data(GroupRole).isNull() || !item->data(CategoryRole).isNull())) { if (item->data(CategoryRole).isNull()) { // Set the group name to get it translated Transaction::Group group; group = item->data(GroupRole).value(); item->setText(PkStrings::groups(group)); } item->setData(i18n("Categories"), KCategorizedSortFilterProxyModel::CategoryDisplayRole); item->setData(1, KCategorizedSortFilterProxyModel::CategorySortRole); if (parent) { parent->appendRow(item); } else { appendRow(item); } } } QList CategoryModel::parseCategories(QXmlStreamReader &xml) { QString token = xml.name().toString(); QList ret; while(!xml.atEnd() && !(xml.readNext() == QXmlStreamReader::EndElement && xml.name() == token)) { if(xml.tokenType() == QXmlStreamReader::StartElement) { // Where the categories where AND if (xml.name() == QLatin1String("And")) { // We are going to read the next element to save the token name QList parsers; parsers = parseCategories(xml); if (!parsers.isEmpty()) { CategoryMatcher opAND(CategoryMatcher::And); opAND.setChild(parsers); ret << opAND; } } else if (xml.name() == QLatin1String("Or")) { // Where the categories where OR QList parsers; parsers = parseCategories(xml); if (!parsers.isEmpty()) { CategoryMatcher opOR(CategoryMatcher::Or); opOR.setChild(parsers); ret << opOR; } } else if (xml.name() == QLatin1String("Not")) { // USED to negate the categories inside it QList parsers; parsers = parseCategories(xml); if (!parsers.isEmpty()) { CategoryMatcher opNot(CategoryMatcher::Not); opNot.setChild(parsers); ret << opNot; } } else if (xml.name() == QLatin1String("Category")) { // Found the real category, if the join was not means // that applications in this category should NOT be displayed QString name = xml.readElementText(); if (!name.isEmpty()){ ret << CategoryMatcher(CategoryMatcher::Term, name); } } } } return ret; } diff --git a/ApperKCM/FiltersMenu.cpp b/ApperKCM/FiltersMenu.cpp index 58afea4..66381c3 100644 --- a/ApperKCM/FiltersMenu.cpp +++ b/ApperKCM/FiltersMenu.cpp @@ -1,357 +1,340 @@ /*************************************************************************** * Copyright (C) 2009-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include #include "FiltersMenu.h" #include #include #include FiltersMenu::FiltersMenu(QWidget *parent) : QMenu(parent) { // Loads the filter menu settings KConfig config("apper"); KConfigGroup filterMenuGroup(&config, "FilterMenu"); - QMenu *menuCollections = new QMenu(i18n("Collections"), this); - connect(menuCollections, SIGNAL(triggered(QAction*)), - this, SIGNAL(filtersChanged())); - connect(this, SIGNAL(enableCollections(bool)), - addMenu(menuCollections), SLOT(setVisible(bool))); - QActionGroup *collectionGroup = new QActionGroup(menuCollections); + auto menuCollections = new QMenu(i18n("Collections"), this); + connect(menuCollections, &QMenu::triggered, this, &FiltersMenu::filtersChanged); + + QAction *action = addMenu(menuCollections); + connect(this, &FiltersMenu::enableCollections, action, &QAction::setVisible); + + auto collectionGroup = new QActionGroup(menuCollections); collectionGroup->setExclusive(true); QAction *collectionTrue = new QAction(i18n("Only collections"), collectionGroup); collectionTrue->setCheckable(true); m_filtersAction[collectionTrue] = Transaction::FilterCollections; collectionGroup->addAction(collectionTrue); menuCollections->addAction(collectionTrue); m_actions << collectionTrue; - QAction *collectionFalse = new QAction(i18n("Exclude collections"), collectionGroup); + auto collectionFalse = new QAction(i18n("Exclude collections"), collectionGroup); collectionFalse->setCheckable(true); m_filtersAction[collectionFalse] = Transaction::FilterNotCollections; collectionGroup->addAction(collectionFalse); menuCollections->addAction(collectionFalse); m_actions << collectionFalse; // Installed - QMenu *menuInstalled = new QMenu(i18n("Installed"), this); - connect(menuInstalled, SIGNAL(triggered(QAction*)), - this, SIGNAL(filtersChanged())); - connect(this, SIGNAL(enableInstalled(bool)), - addMenu(menuInstalled), SLOT(setVisible(bool))); + auto menuInstalled = new QMenu(i18n("Installed"), this); + connect(menuInstalled, &QMenu::triggered, this, &FiltersMenu::filtersChanged); + connect(this, &FiltersMenu::enableInstalled, addMenu(menuInstalled), &QAction::setVisible); addMenu(menuInstalled); - QActionGroup *installedGroup = new QActionGroup(menuInstalled); + auto installedGroup = new QActionGroup(menuInstalled); installedGroup->setExclusive(true); - QAction *installedTrue = new QAction(i18n("Only installed"), installedGroup); + auto installedTrue = new QAction(i18n("Only installed"), installedGroup); installedTrue->setCheckable(true); m_filtersAction[installedTrue] = Transaction::FilterInstalled; installedGroup->addAction(installedTrue); menuInstalled->addAction(installedTrue); m_actions << installedTrue; - QAction *installedFalse = new QAction(i18n("Only available"), installedGroup); + auto installedFalse = new QAction(i18n("Only available"), installedGroup); installedFalse->setCheckable(true); m_filtersAction[installedFalse] = Transaction::FilterNotInstalled; installedGroup->addAction(installedFalse); menuInstalled->addAction(installedFalse); m_actions << installedFalse; - QAction *installedNone = new QAction(i18n("No filter"), installedGroup); + auto installedNone = new QAction(i18n("No filter"), installedGroup); installedNone->setCheckable(true); installedNone->setChecked(true); installedGroup->addAction(installedNone); menuInstalled->addAction(installedNone); m_actions << installedNone; // Development - QMenu *menuDevelopment = new QMenu(i18n("Development"), this); - connect(menuDevelopment, SIGNAL(triggered(QAction*)), - this, SIGNAL(filtersChanged())); - connect(this, SIGNAL(enableDevelopment(bool)), - addMenu(menuDevelopment), SLOT(setVisible(bool))); + auto menuDevelopment = new QMenu(i18n("Development"), this); + connect(menuDevelopment, &QMenu::triggered, this, &FiltersMenu::filtersChanged); + connect(this, &FiltersMenu::enableDevelopment, addMenu(menuDevelopment), &QAction::setVisible); addMenu(menuDevelopment); - QActionGroup *developmentGroup = new QActionGroup(menuDevelopment); + auto developmentGroup = new QActionGroup(menuDevelopment); developmentGroup->setExclusive(true); - QAction *developmentTrue = new QAction(i18n("Only development"), developmentGroup); + auto developmentTrue = new QAction(i18n("Only development"), developmentGroup); developmentTrue->setCheckable(true); m_filtersAction[developmentTrue] = Transaction::FilterDevel; developmentGroup->addAction(developmentTrue); menuDevelopment->addAction(developmentTrue); m_actions << developmentTrue; - QAction *developmentFalse = new QAction(i18n("Only end user files"), developmentGroup); + auto developmentFalse = new QAction(i18n("Only end user files"), developmentGroup); developmentFalse->setCheckable(true); m_filtersAction[developmentFalse] = Transaction::FilterNotDevel; developmentGroup->addAction(developmentFalse); menuDevelopment->addAction(developmentFalse); m_actions << developmentFalse; - QAction *developmentNone = new QAction(i18n("No filter"), developmentGroup); + auto developmentNone = new QAction(i18n("No filter"), developmentGroup); developmentNone->setCheckable(true); developmentNone->setChecked(true); developmentGroup->addAction(developmentNone); menuDevelopment->addAction(developmentNone); m_actions << developmentNone; // Graphical - QMenu *menuGui = new QMenu(i18n("Graphical"), this); - connect(menuGui, SIGNAL(triggered(QAction*)), - this, SIGNAL(filtersChanged())); - connect(this, SIGNAL(enableGraphical(bool)), - addMenu(menuGui), SLOT(setVisible(bool))); + auto menuGui = new QMenu(i18n("Graphical"), this); + connect(menuGui, &QMenu::triggered, this, &FiltersMenu::filtersChanged); + connect(this, &FiltersMenu::enableGraphical, addMenu(menuGui), &QAction::setVisible); addMenu(menuGui); - QActionGroup *guiGroup = new QActionGroup(menuGui); + auto guiGroup = new QActionGroup(menuGui); guiGroup->setExclusive(true); - QAction *guiTrue = new QAction(i18n("Only graphical"), guiGroup); + auto guiTrue = new QAction(i18n("Only graphical"), guiGroup); guiTrue->setCheckable(true); m_filtersAction[guiTrue] = Transaction::FilterGui; guiGroup->addAction(guiTrue); menuGui->addAction(guiTrue); m_actions << guiTrue; - QAction *guiFalse = new QAction(i18n("Only text"), guiGroup); + auto guiFalse = new QAction(i18n("Only text"), guiGroup); guiFalse->setCheckable(true); m_filtersAction[guiFalse] = Transaction::FilterNotGui; guiGroup->addAction(guiFalse); menuGui->addAction(guiFalse); m_actions << guiFalse; - QAction *guiNone = new QAction(i18n("No filter"), guiGroup); + auto guiNone = new QAction(i18n("No filter"), guiGroup); guiNone->setCheckable(true); guiNone->setChecked(true); guiGroup->addAction(guiNone); menuGui->addAction(guiNone); m_actions << guiNone; // Free - QMenu *menuFree = new QMenu(i18nc("Filter for free packages", "Free"), this); - connect(menuFree, SIGNAL(triggered(QAction*)), - this, SIGNAL(filtersChanged())); - connect(this, SIGNAL(enableFree(bool)), - addMenu(menuFree), SLOT(setVisible(bool))); + auto menuFree = new QMenu(i18nc("Filter for free packages", "Free"), this); + connect(menuFree, &QMenu::triggered, this, &FiltersMenu::filtersChanged); + connect(this, &FiltersMenu::enableFree, addMenu(menuFree), &QAction::setVisible); addMenu(menuFree); - QActionGroup *freeGroup = new QActionGroup(menuFree); + auto freeGroup = new QActionGroup(menuFree); freeGroup->setExclusive(true); - QAction *freeTrue = new QAction(i18n("Only free software"), freeGroup); + auto freeTrue = new QAction(i18n("Only free software"), freeGroup); freeTrue->setCheckable(true); m_filtersAction[freeTrue] = Transaction::FilterFree; freeGroup->addAction(freeTrue); menuFree->addAction(freeTrue); m_actions << freeTrue; - QAction *freeFalse = new QAction(i18n("Only non-free software"), freeGroup); + auto freeFalse = new QAction(i18n("Only non-free software"), freeGroup); freeFalse->setCheckable(true); m_filtersAction[freeFalse] = Transaction::FilterNotFree; freeGroup->addAction(freeFalse); menuFree->addAction(freeFalse); m_actions << freeFalse; - QAction *freeNone = new QAction(i18n("No filter"), freeGroup); + auto freeNone = new QAction(i18n("No filter"), freeGroup); freeNone->setCheckable(true); freeNone->setChecked(true); freeGroup->addAction(freeNone); menuFree->addAction(freeNone); m_actions << freeNone; // Supported - QMenu *menuSupported = new QMenu(i18nc("Filter for supported packages", "Supported"), this); - connect(menuSupported, SIGNAL(triggered(QAction*)), - this, SIGNAL(filtersChanged())); - connect(this, SIGNAL(enableSupported(bool)), - addMenu(menuSupported), SLOT(setVisible(bool))); + auto menuSupported = new QMenu(i18nc("Filter for supported packages", "Supported"), this); + connect(menuSupported, &QMenu::triggered, this, &FiltersMenu::filtersChanged); + connect(this, &FiltersMenu::enableSupported, addMenu(menuSupported), &QAction::setVisible); addMenu(menuSupported); - QActionGroup *supportedGroup = new QActionGroup(menuSupported); + auto supportedGroup = new QActionGroup(menuSupported); supportedGroup->setExclusive(true); - QAction *supportedTrue = new QAction(i18n("Only supported software"), supportedGroup); + auto supportedTrue = new QAction(i18n("Only supported software"), supportedGroup); supportedTrue->setCheckable(true); m_filtersAction[supportedTrue] = Transaction::FilterSupported; supportedGroup->addAction(supportedTrue); menuSupported->addAction(supportedTrue); m_actions << supportedTrue; - QAction *supportedFalse = new QAction(i18n("Only non-supported software"), supportedGroup); + auto supportedFalse = new QAction(i18n("Only non-supported software"), supportedGroup); supportedFalse->setCheckable(true); m_filtersAction[supportedFalse] = Transaction::FilterNotSupported; supportedGroup->addAction(supportedFalse); menuSupported->addAction(supportedFalse); m_actions << supportedFalse; - QAction *supportedNone = new QAction(i18n("No filter"), supportedGroup); + auto supportedNone = new QAction(i18n("No filter"), supportedGroup); supportedNone->setCheckable(true); supportedNone->setChecked(true); supportedGroup->addAction(supportedNone); menuSupported->addAction(supportedNone); m_actions << supportedNone; // Source - QMenu *menuSource = new QMenu(i18nc("Filter for source packages", "Source"), this); - connect(menuSource, SIGNAL(triggered(QAction*)), - this, SIGNAL(filtersChanged())); - connect(this, SIGNAL(enableSource(bool)), - addMenu(menuSource), SLOT(setVisible(bool))); + auto menuSource = new QMenu(i18nc("Filter for source packages", "Source"), this); + connect(menuSource, &QMenu::triggered, this, &FiltersMenu::filtersChanged); + connect(this, &FiltersMenu::enableSource, addMenu(menuSource), &QAction::setVisible); addMenu(menuSource); - QActionGroup *sourceGroup = new QActionGroup(menuSource); + auto sourceGroup = new QActionGroup(menuSource); sourceGroup->setExclusive(true); - QAction *sourceTrue = new QAction(i18n("Only sourcecode"), sourceGroup); + auto sourceTrue = new QAction(i18n("Only sourcecode"), sourceGroup); sourceTrue->setCheckable(true); m_filtersAction[sourceTrue] = Transaction::FilterSource; sourceGroup->addAction(sourceTrue); menuSource->addAction(sourceTrue); m_actions << sourceTrue; - QAction *sourceFalse = new QAction(i18n("Only non-sourcecode"), sourceGroup); + auto sourceFalse = new QAction(i18n("Only non-sourcecode"), sourceGroup); sourceFalse->setCheckable(true); m_filtersAction[sourceFalse] = Transaction::FilterNotSource; sourceGroup->addAction(sourceFalse); menuSource->addAction(sourceFalse); m_actions << sourceFalse; - QAction *sourceNone = new QAction(i18n("No filter"), sourceGroup); + auto sourceNone = new QAction(i18n("No filter"), sourceGroup); sourceNone->setCheckable(true); sourceNone->setChecked(true); sourceGroup->addAction(sourceNone); menuSource->addAction(sourceNone); m_actions << sourceNone; // Basename, Newest, Arch separator - connect(this, SIGNAL(enableBasenameNewestArchSeparator(bool)), - addSeparator(), SLOT(setVisible(bool))); - - QAction *basename = new QAction(i18n("Hide Subpackages"), this); - connect(basename, SIGNAL(triggered()), - this, SIGNAL(filtersChanged())); - connect(this, SIGNAL(enableBasename(bool)), - basename, SLOT(setVisible(bool))); + connect(this, &FiltersMenu::enableBasenameNewestArchSeparator, addSeparator(), &QAction::setVisible); + + auto basename = new QAction(i18n("Hide Subpackages"), this); + connect(basename, &QAction::triggered, this, &FiltersMenu::filtersChanged); + connect(this, &FiltersMenu::enableBasename, basename, &QAction::setVisible); basename->setCheckable(true); basename->setToolTip(i18n("Only show one package, not subpackages")); m_filtersAction[basename] = Transaction::FilterBasename; m_actions << basename; - QAction *newest = new QAction(i18n("Only Newest Packages"), this); - connect(newest, SIGNAL(triggered()), - this, SIGNAL(filtersChanged())); - connect(this, SIGNAL(enableNewest(bool)), - newest, SLOT(setVisible(bool))); + auto newest = new QAction(i18n("Only Newest Packages"), this); + connect(newest, &QAction::triggered, this, &FiltersMenu::filtersChanged); + connect(this, &FiltersMenu::enableNewest, newest, &QAction::setVisible); newest->setCheckable(true); newest->setChecked(filterMenuGroup.readEntry("FilterNewest", true)); newest->setToolTip(i18n("Only show the newest available package")); m_filtersAction[newest] = Transaction::FilterNewest; m_actions << newest; - QAction *native = new QAction(i18n("Only Native Packages"), this); - connect(native, SIGNAL(triggered()), - this, SIGNAL(filtersChanged())); - connect(this, SIGNAL(enableArch(bool)), - native, SLOT(setVisible(bool))); + auto native = new QAction(i18n("Only Native Packages"), this); + connect(native, &QAction::triggered, this, &FiltersMenu::filtersChanged); + connect(this, &FiltersMenu::enableArch, native, &QAction::setVisible); native->setCheckable(true); native->setChecked(filterMenuGroup.readEntry("FilterNative", true)); native->setToolTip(i18n("Only show packages matching the machine architecture")); m_filtersAction[native] = Transaction::FilterArch; m_actions << native; #ifdef HAVE_APPSTREAM addSeparator(); m_applications = new QAction(i18n("Only Show Applications"), this); m_applications->setCheckable(true); m_applications->setChecked(filterMenuGroup.readEntry("HidePackages", false)); m_applications->setToolTip(i18n("Hide packages that are not applications")); addAction(m_applications); connect(m_applications, SIGNAL(triggered(bool)), this, SIGNAL(filterApplications(bool))); #endif // HAVE_APPSTREAM } FiltersMenu::~FiltersMenu() { KConfig config("apper"); KConfigGroup filterMenuGroup(&config, "FilterMenu"); // For usability we will only save ViewInGroups settings and Newest filter, // - The user might get angry when he does not find any packages because he didn't // see that a filter is set by config // This entry does not depend on the backend it's ok to call this pointer // filterMenuGroup.writeEntry("ViewInGroups", m_filtersMenu->actionGrouped()); // This entry does not depend on the backend it's ok to call this pointer filterMenuGroup.writeEntry("FilterNewest", static_cast(filters() & Transaction::FilterNewest)); // This entry does not depend on the backend it's ok to call this pointer filterMenuGroup.writeEntry("FilterNative", static_cast(filters() & Transaction::FilterArch)); #ifdef HAVE_APPSTREAM filterMenuGroup.writeEntry("HidePackages", m_applications->isChecked()); #endif // HAVE_APPSTREAM } void FiltersMenu::setFilters(Transaction::Filters filters) { emit enableCollections(filters & Transaction::FilterCollections || filters & Transaction::FilterNotCollections); emit enableInstalled(filters & Transaction::FilterInstalled || filters & Transaction::FilterNotInstalled); emit enableDevelopment(filters & Transaction::FilterDevel || filters & Transaction::FilterNotDevel); emit enableGraphical(filters & Transaction::FilterGui || filters & Transaction::FilterNotGui); emit enableFree(filters & Transaction::FilterFree || filters & Transaction::FilterNotFree); emit enableSupported(filters & Transaction::FilterSupported || filters & Transaction::FilterNotSupported); emit enableSource(filters & Transaction::FilterSource || filters & Transaction::FilterNotSource); emit enableBasenameNewestArchSeparator(filters & Transaction::FilterBasename || filters & Transaction::FilterNewest || filters & Transaction::FilterArch); emit enableBasename(filters & Transaction::FilterBasename); emit enableNewest(filters & Transaction::FilterNewest); emit enableArch(filters & Transaction::FilterArch); } bool FiltersMenu::filterApplications() const { #ifdef HAVE_APPSTREAM return m_applications->isChecked(); #else return false; #endif // HAVE_APPSTREAM } Transaction::Filters FiltersMenu::filters() const { Transaction::Filters filters; bool filterSet = false; - foreach (QAction * const action, m_actions) { + const QVector actions = m_actions; + for (QAction * const action : actions) { if (action->isChecked()) { if (m_filtersAction.contains(action)) { filters |= m_filtersAction[action]; filterSet = true; } } } if (!filterSet) { filters = Transaction::FilterNone; } return filters; } diff --git a/ApperKCM/FiltersMenu.h b/ApperKCM/FiltersMenu.h index 1520a36..9bd1d7f 100644 --- a/ApperKCM/FiltersMenu.h +++ b/ApperKCM/FiltersMenu.h @@ -1,63 +1,63 @@ /*************************************************************************** * Copyright (C) 2009-2010 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef FILTERS_MENU_H #define FILTERS_MENU_H #include #include using namespace PackageKit; class FiltersMenu : public QMenu { Q_OBJECT public: explicit FiltersMenu(QWidget *parent = 0); ~FiltersMenu(); void setFilters(Transaction::Filters filters); Transaction::Filters filters() const; bool filterApplications() const; Q_SIGNALS: void filtersChanged(); void filterApplications(bool checked); void enableCollections(bool enable); void enableInstalled(bool enabled); void enableDevelopment(bool enabled); void enableGraphical(bool enabled); void enableFree(bool enabled); void enableSupported(bool enabled); void enableSource(bool enable); void enableBasenameNewestArchSeparator(bool enable); void enableBasename(bool enable); void enableNewest(bool enable); void enableArch(bool enable); private: QAction *m_applications; - QList m_actions; + QVector m_actions; QHash m_filtersAction; }; #endif diff --git a/ApperKCM/PackageDetails.cpp b/ApperKCM/PackageDetails.cpp index d1d4f06..753870f 100644 --- a/ApperKCM/PackageDetails.cpp +++ b/ApperKCM/PackageDetails.cpp @@ -1,802 +1,801 @@ /*************************************************************************** * Copyright (C) 2009-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "PackageDetails.h" #include "ui_PackageDetails.h" #include "ScreenShotViewer.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_APPSTREAM #include #endif #include "GraphicsOpacityDropShadowEffect.h" #define BLUR_RADIUS 15 #define FINAL_HEIGHT 210 using namespace PackageKit; Q_DECLARE_LOGGING_CATEGORY(APPER) Q_DECLARE_METATYPE(KPixmapSequenceOverlayPainter**) PackageDetails::PackageDetails(QWidget *parent) : QWidget(parent), ui(new Ui::PackageDetails), m_busySeq(0), m_display(false), m_hideVersion(false), m_hideArch(false), m_transaction(0), m_hasDetails(false), m_hasFileList(false) { ui->setupUi(this); ui->hideTB->setIcon(QIcon::fromTheme("window-close")); connect(ui->hideTB, SIGNAL(clicked()), this, SLOT(hide())); auto menu = new QMenu(i18n("Display"), this); m_actionGroup = new QActionGroup(this); // we check to see which roles are supported by the backend // if so we ask for information and create the containers descriptionAction = menu->addAction(i18n("Description")); descriptionAction->setCheckable(true); descriptionAction->setData(PackageKit::Transaction::RoleGetDetails); m_actionGroup->addAction(descriptionAction); ui->descriptionW->setWidgetResizable(true); dependsOnAction = menu->addAction(i18n("Depends On")); dependsOnAction->setCheckable(true); dependsOnAction->setData(PackageKit::Transaction::RoleDependsOn); m_actionGroup->addAction(dependsOnAction); // Sets a transparent background QWidget *dependsViewport = ui->dependsOnLV->viewport(); QPalette dependsPalette = dependsViewport->palette(); dependsPalette.setColor(dependsViewport->backgroundRole(), Qt::transparent); dependsPalette.setColor(dependsViewport->foregroundRole(), dependsPalette.color(QPalette::WindowText)); dependsViewport->setPalette(dependsPalette); m_dependsModel = new PackageModel(this); m_dependsProxy = new QSortFilterProxyModel(this); m_dependsProxy->setDynamicSortFilter(true); m_dependsProxy->setSortRole(PackageModel::SortRole); m_dependsProxy->setSourceModel(m_dependsModel); ui->dependsOnLV->setModel(m_dependsProxy); ui->dependsOnLV->sortByColumn(0, Qt::AscendingOrder); ui->dependsOnLV->header()->setDefaultAlignment(Qt::AlignCenter); ui->dependsOnLV->header()->setSectionResizeMode(PackageModel::NameCol, QHeaderView::ResizeToContents); ui->dependsOnLV->header()->setSectionResizeMode(PackageModel::VersionCol, QHeaderView::ResizeToContents); ui->dependsOnLV->header()->setSectionResizeMode(PackageModel::ArchCol, QHeaderView::Stretch); ui->dependsOnLV->header()->hideSection(PackageModel::ActionCol); ui->dependsOnLV->header()->hideSection(PackageModel::CurrentVersionCol); ui->dependsOnLV->header()->hideSection(PackageModel::OriginCol); ui->dependsOnLV->header()->hideSection(PackageModel::SizeCol); requiredByAction = menu->addAction(i18n("Required By")); requiredByAction->setCheckable(true); requiredByAction->setData(PackageKit::Transaction::RoleRequiredBy); m_actionGroup->addAction(requiredByAction); // Sets a transparent background QWidget *requiredViewport = ui->requiredByLV->viewport(); QPalette requiredPalette = requiredViewport->palette(); requiredPalette.setColor(requiredViewport->backgroundRole(), Qt::transparent); requiredPalette.setColor(requiredViewport->foregroundRole(), requiredPalette.color(QPalette::WindowText)); requiredViewport->setPalette(requiredPalette); m_requiresModel = new PackageModel(this); m_requiresProxy = new QSortFilterProxyModel(this); m_requiresProxy->setDynamicSortFilter(true); m_requiresProxy->setSortRole(PackageModel::SortRole); m_requiresProxy->setSourceModel(m_requiresModel); ui->requiredByLV->setModel(m_requiresProxy); ui->requiredByLV->sortByColumn(0, Qt::AscendingOrder); ui->requiredByLV->header()->setDefaultAlignment(Qt::AlignCenter); ui->requiredByLV->header()->setSectionResizeMode(PackageModel::NameCol, QHeaderView::ResizeToContents); ui->requiredByLV->header()->setSectionResizeMode(PackageModel::VersionCol, QHeaderView::ResizeToContents); ui->requiredByLV->header()->setSectionResizeMode(PackageModel::ArchCol, QHeaderView::Stretch); ui->requiredByLV->header()->hideSection(PackageModel::ActionCol); ui->requiredByLV->header()->hideSection(PackageModel::CurrentVersionCol); ui->requiredByLV->header()->hideSection(PackageModel::OriginCol); ui->requiredByLV->header()->hideSection(PackageModel::SizeCol); fileListAction = menu->addAction(i18n("File List")); fileListAction->setCheckable(true); fileListAction->setData(PackageKit::Transaction::RoleGetFiles); m_actionGroup->addAction(fileListAction); // Sets a transparent background QWidget *actionsViewport = ui->filesPTE->viewport(); QPalette palette = actionsViewport->palette(); palette.setColor(actionsViewport->backgroundRole(), Qt::transparent); palette.setColor(actionsViewport->foregroundRole(), palette.color(QPalette::WindowText)); actionsViewport->setPalette(palette); // Set the menu ui->menuTB->setMenu(menu); ui->menuTB->setIcon(QIcon::fromTheme("help-about")); connect(m_actionGroup, SIGNAL(triggered(QAction*)), this, SLOT(actionActivated(QAction*))); m_busySeq = new KPixmapSequenceOverlayPainter(this); m_busySeq->setSequence(KPixmapSequence("process-working", KIconLoader::SizeSmallMedium)); m_busySeq->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); m_busySeq->setWidget(ui->stackedWidget); // Setup the opacit effect that makes the descriptio transparent // after finished it checks in display() to see if it shouldn't show // up again. The property animation is always the same, the only different thing // is the Forward or Backward property QGraphicsOpacityEffect *effect = new QGraphicsOpacityEffect(ui->stackedWidget); effect->setOpacity(0); ui->stackedWidget->setGraphicsEffect(effect); m_fadeStacked = new QPropertyAnimation(effect, "opacity", this); m_fadeStacked->setDuration(500); m_fadeStacked->setStartValue(qreal(0)); m_fadeStacked->setEndValue(qreal(1)); connect(m_fadeStacked, SIGNAL(finished()), this, SLOT(display())); // It's is impossible due to some limitation in Qt to set two effects on the same // Widget m_fadeScreenshot = new QPropertyAnimation(effect, "opacity", this); GraphicsOpacityDropShadowEffect *shadow = new GraphicsOpacityDropShadowEffect(ui->screenshotL); shadow->setOpacity(0); shadow->setBlurRadius(BLUR_RADIUS); shadow->setOffset(2); shadow->setColor(QApplication::palette().dark().color()); ui->screenshotL->setGraphicsEffect(shadow); m_fadeScreenshot = new QPropertyAnimation(shadow, "opacity", this); m_fadeScreenshot->setDuration(500); m_fadeScreenshot->setStartValue(qreal(0)); m_fadeScreenshot->setEndValue(qreal(1)); connect(m_fadeScreenshot, SIGNAL(finished()), this, SLOT(display())); // This pannel expanding QPropertyAnimation *anim1 = new QPropertyAnimation(this, "maximumSize", this); anim1->setDuration(500); anim1->setEasingCurve(QEasingCurve::OutQuart); anim1->setStartValue(QSize(QWIDGETSIZE_MAX, 0)); anim1->setEndValue(QSize(QWIDGETSIZE_MAX, FINAL_HEIGHT)); QPropertyAnimation *anim2 = new QPropertyAnimation(this, "minimumSize", this); anim2->setDuration(500); anim2->setEasingCurve(QEasingCurve::OutQuart); anim2->setStartValue(QSize(QWIDGETSIZE_MAX, 0)); anim2->setEndValue(QSize(QWIDGETSIZE_MAX, FINAL_HEIGHT)); m_expandPanel = new QParallelAnimationGroup(this); m_expandPanel->addAnimation(anim1); m_expandPanel->addAnimation(anim2); connect(m_expandPanel, SIGNAL(finished()), this, SLOT(display())); } void PackageDetails::init(PackageKit::Transaction::Roles roles) { // qCDebug(); bool setChecked = true; if (roles & PackageKit::Transaction::RoleGetDetails) { descriptionAction->setEnabled(true); descriptionAction->setChecked(setChecked); setChecked = false; } else { descriptionAction->setEnabled(false); descriptionAction->setChecked(false); } if (roles & PackageKit::Transaction::RoleDependsOn) { dependsOnAction->setEnabled(true); dependsOnAction->setChecked(setChecked); setChecked = false; } else { dependsOnAction->setEnabled(false); dependsOnAction->setChecked(false); } if (roles & PackageKit::Transaction::RoleRequiredBy) { requiredByAction->setEnabled(true); requiredByAction->setChecked(setChecked); setChecked = false; } else { requiredByAction->setEnabled(false); requiredByAction->setChecked(false); } if (roles & PackageKit::Transaction::RoleGetFiles) { fileListAction->setEnabled(true); fileListAction->setChecked(setChecked); setChecked = false; } else { fileListAction->setEnabled(false); fileListAction->setChecked(false); } } PackageDetails::~PackageDetails() { } void PackageDetails::setPackage(const QModelIndex &index) { qCDebug(APPER) << index; QString appId = index.data(PackageModel::ApplicationId).toString(); QString packageID = index.data(PackageModel::IdRole).toString(); // if it's the same package and the same application, return if (packageID == m_packageID && appId == m_appId) { return; } else if (maximumSize().height() == 0) { // Expand the panel m_display = true; m_expandPanel->setDirection(QAbstractAnimation::Forward); m_expandPanel->start(); } else { // Hide the old description fadeOut(PackageDetails::FadeScreenshot | PackageDetails::FadeStacked); } m_index = index; m_appId = appId; m_packageID = packageID; m_hasDetails = false; m_hasFileList = false; m_hasRequires = false; m_hasDepends = false; qCDebug(APPER) << "appId" << appId << "m_package" << m_packageID; QString pkgIconPath = index.data(PackageModel::IconRole).toString(); m_currentIcon = PkIcons::getIcon(pkgIconPath, QString()).pixmap(64, 64); m_appName = index.data(PackageModel::NameRole).toString(); m_currentScreenshot = thumbnail(Transaction::packageName(m_packageID)); qCDebug(APPER) << "current screenshot" << m_currentScreenshot; if (!m_currentScreenshot.isNull()) { if (m_screenshotPath.contains(m_currentScreenshot)) { display(); } else { auto tempFile = new QTemporaryFile; tempFile->open(); KIO::FileCopyJob *job = KIO::file_copy(QUrl(m_currentScreenshot), QUrl(tempFile->fileName()), -1, KIO::Overwrite | KIO::HideProgressInfo); connect(job, &KIO::FileCopyJob::result, this, &PackageDetails::resultJob); } } if (m_actionGroup->checkedAction()) { actionActivated(m_actionGroup->checkedAction()); } } void PackageDetails::on_screenshotL_clicked() { QString url; url = screenshot(Transaction::packageName(m_packageID)); if (!url.isNull()) { ScreenShotViewer *view = new ScreenShotViewer(url); view->setWindowTitle(m_appName); view->show(); } } void PackageDetails::hidePackageVersion(bool hide) { m_hideVersion = hide; } void PackageDetails::hidePackageArch(bool hide) { m_hideArch = hide; } void PackageDetails::actionActivated(QAction *action) { // don't fade the screenshot // if the package changed setPackage() fades both fadeOut(FadeStacked); qCDebug(APPER); // disconnect the transaction // so that we don't get old data if (m_transaction) { disconnect(m_transaction, SIGNAL(details(PackageKit::Details)), this, SLOT(description(PackageKit::Details))); disconnect(m_transaction, SIGNAL(package(PackageKit::Transaction::Info,QString,QString)), m_dependsModel, SLOT(addPackage(PackageKit::Transaction::Info,QString,QString))); disconnect(m_transaction, SIGNAL(package(PackageKit::Transaction::Info,QString,QString)), m_requiresModel, SLOT(addPackage(PackageKit::Transaction::Info,QString,QString))); disconnect(m_transaction, SIGNAL(files(QString,QStringList)), this, SLOT(files(QString,QStringList))); disconnect(m_transaction, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), this, SLOT(finished())); m_transaction = 0; } // Check to see if we don't already have the required data uint role = action->data().toUInt(); switch (role) { case PackageKit::Transaction::RoleGetDetails: if (m_hasDetails) { description(m_details); display(); return; } break; case PackageKit::Transaction::RoleDependsOn: if (m_hasDepends) { display(); return; } break; case PackageKit::Transaction::RoleRequiredBy: if (m_hasRequires) { display(); return; } break; case PackageKit::Transaction::RoleGetFiles: if (m_hasFileList) { display(); return; } break; } // we don't have the data qCDebug(APPER) << "New transaction"; switch (role) { case PackageKit::Transaction::RoleGetDetails: m_transaction = Daemon::getDetails(m_packageID); connect(m_transaction, SIGNAL(details(PackageKit::Details)), SLOT(description(PackageKit::Details))); break; case PackageKit::Transaction::RoleDependsOn: m_dependsModel->clear(); m_transaction = Daemon::dependsOn(m_packageID, PackageKit::Transaction::FilterNone, false); connect(m_transaction, SIGNAL(package(PackageKit::Transaction::Info,QString,QString)), m_dependsModel, SLOT(addPackage(PackageKit::Transaction::Info,QString,QString))); connect(m_transaction, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), m_dependsModel, SLOT(finished())); break; case PackageKit::Transaction::RoleRequiredBy: m_requiresModel->clear(); m_transaction = Daemon::requiredBy(m_packageID, PackageKit::Transaction::FilterNone, false); connect(m_transaction, SIGNAL(package(PackageKit::Transaction::Info,QString,QString)), m_requiresModel, SLOT(addPackage(PackageKit::Transaction::Info,QString,QString))); connect(m_transaction, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), m_requiresModel, SLOT(finished())); break; case PackageKit::Transaction::RoleGetFiles: m_currentFileList.clear(); m_transaction = Daemon::getFiles(m_packageID); connect(m_transaction, SIGNAL(files(QString,QStringList)), this, SLOT(files(QString,QStringList))); break; default: qWarning() << Q_FUNC_INFO << "Oops, unhandled role, please report" << role; return; } connect(m_transaction, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), this, SLOT(finished())); qCDebug(APPER) <<"transaction running"; m_busySeq->start(); } void PackageDetails::resultJob(KJob *job) { KIO::FileCopyJob *fJob = qobject_cast(job); if (!fJob->error()) { m_screenshotPath[fJob->srcUrl().url()] = fJob->destUrl().toLocalFile(); display(); } } void PackageDetails::hide() { m_display = false; // Clean the old description otherwise if the user selects the same // package the pannel won't expand m_packageID.clear(); m_appId.clear(); if (maximumSize().height() == FINAL_HEIGHT) { if (m_fadeStacked->currentValue().toReal() == 0 && m_fadeScreenshot->currentValue().toReal() == 0) { // Screen shot and description faded let's shrink the pannel m_expandPanel->setDirection(QAbstractAnimation::Backward); m_expandPanel->start(); } else { // Hide current description fadeOut(PackageDetails::FadeScreenshot | PackageDetails::FadeStacked); } } } void PackageDetails::fadeOut(FadeWidgets widgets) { // Fade out only if needed if ((widgets & FadeStacked) && m_fadeStacked->currentValue().toReal() != 0) { m_fadeStacked->setDirection(QAbstractAnimation::Backward); m_fadeStacked->start(); } // Fade out the screenshot only if needed if ((widgets & FadeScreenshot) && m_fadeScreenshot->currentValue().toReal() != 0) { ui->screenshotL->unsetCursor(); m_fadeScreenshot->setDirection(QAbstractAnimation::Backward); m_fadeScreenshot->start(); } } void PackageDetails::display() { // If we shouldn't be showing hide the pannel if (!m_display) { hide(); } else if (maximumSize().height() == FINAL_HEIGHT) { emit ensureVisible(m_index); // Check to see if the stacked widget is transparent if (m_fadeStacked->currentValue().toReal() == 0 && m_actionGroup->checkedAction()) { bool fadeIn = false; switch (m_actionGroup->checkedAction()->data().toUInt()) { case PackageKit::Transaction::RoleGetDetails: if (m_hasDetails) { setupDescription(); fadeIn = true; } break; case PackageKit::Transaction::RoleDependsOn: if (m_hasDepends) { if (ui->stackedWidget->currentWidget() != ui->pageDepends) { ui->stackedWidget->setCurrentWidget(ui->pageDepends); } fadeIn = true; } break; case PackageKit::Transaction::RoleRequiredBy: if (m_hasRequires) { if (ui->stackedWidget->currentWidget() != ui->pageRequired) { ui->stackedWidget->setCurrentWidget(ui->pageRequired); } fadeIn = true; } break; case PackageKit::Transaction::RoleGetFiles: if (m_hasFileList) { ui->filesPTE->clear(); if (m_currentFileList.isEmpty()) { ui->filesPTE->insertPlainText(i18n("No files were found.")); } else { m_currentFileList.sort(); ui->filesPTE->insertPlainText(m_currentFileList.join("\n")); } if (ui->stackedWidget->currentWidget() != ui->pageFiles) { ui->stackedWidget->setCurrentWidget(ui->pageFiles); } ui->filesPTE->verticalScrollBar()->setValue(0); fadeIn = true; } break; } if (fadeIn) { // Fade In m_fadeStacked->setDirection(QAbstractAnimation::Forward); m_fadeStacked->start(); } } // Check to see if we have a screen shot and if we are // transparent, and make sure the details are going // to be shown if (m_fadeScreenshot->currentValue().toReal() == 0 && m_screenshotPath.contains(m_currentScreenshot) && m_fadeStacked->direction() == QAbstractAnimation::Forward) { QPixmap pixmap; pixmap = QPixmap(m_screenshotPath[m_currentScreenshot]) .scaled(160,120, Qt::KeepAspectRatio, Qt::SmoothTransformation); ui->screenshotL->setPixmap(pixmap); ui->screenshotL->setCursor(Qt::PointingHandCursor); // Fade In m_fadeScreenshot->setDirection(QAbstractAnimation::Forward); m_fadeScreenshot->start(); } } } void PackageDetails::setupDescription() { if (ui->stackedWidget->currentWidget() != ui->pageDescription) { ui->stackedWidget->setCurrentWidget(ui->pageDescription); } if (!m_hasDetails) { // Oops we don't have any details ui->descriptionL->setText(i18n("Could not fetch software details")); ui->descriptionL->show(); // Hide stuff so we don't display outdated data ui->homepageL->hide(); ui->pathL->hide(); ui->licenseL->hide(); ui->sizeL->hide(); ui->iconL->clear(); } if (!m_detailsDescription.isEmpty()) { ui->descriptionL->setText(m_detailsDescription.replace('\n', "
")); ui->descriptionL->show(); } else { ui->descriptionL->clear(); } if (!m_details.url().isEmpty()) { ui->homepageL->setText("" + m_details.url() + ""); ui->homepageL->show(); } else { ui->homepageL->hide(); } // Let's try to find the application's path in human user // readable easiest form :D KService::Ptr service = KService::serviceByDesktopName(m_appId); QVector > ret; if (service) { ret = locateApplication(QString(), service->menuId()); } if (ret.isEmpty()) { ui->pathL->hide(); } else { QString path; path.append(QString("") .arg(KIconLoader::global()->iconPath("kde", KIconLoader::Small))); path.append(QString(" %1  %3") .arg(QString::fromUtf8("âžœ")) .arg(KIconLoader::global()->iconPath("applications-other", KIconLoader::Small)) .arg(i18n("Applications"))); for (int i = 0; i < ret.size(); i++) { path.append(QString(" %1  %3") .arg(QString::fromUtf8("âžœ")) .arg(KIconLoader::global()->iconPath(ret.at(i).second, KIconLoader::Small)) .arg(ret.at(i).first)); } ui->pathL->setText(path); ui->pathL->show(); } // if (details->group() != Package::UnknownGroup) { // // description += "" + i18nc("Group of the package", "Group") + ":" // // + PkStrings::groups(details->group()) // // + ""; // } if (!m_details.license().isEmpty() && m_details.license() != "unknown") { // We have a license, check if we have and should show show package version if (!m_hideVersion && !Transaction::packageVersion(m_details.packageId()).isEmpty()) { ui->licenseL->setText(Transaction::packageVersion(m_details.packageId()) + " - " + m_details.license()); } else { ui->licenseL->setText(m_details.license()); } ui->licenseL->show(); } else if (!m_hideVersion) { ui->licenseL->setText(Transaction::packageVersion(m_details.packageId())); ui->licenseL->show(); } else { ui->licenseL->hide(); } if (m_details.size() > 0) { QString size = KFormat().formatByteSize(m_details.size()); if (!m_hideArch && !Transaction::packageArch(m_details.packageId()).isEmpty()) { ui->sizeL->setText(size % QLatin1String(" (") % Transaction::packageArch(m_details.packageId()) % QLatin1Char(')')); } else { ui->sizeL->setText(size); } ui->sizeL->show(); } else if (!m_hideArch && !Transaction::packageArch(m_details.packageId()).isEmpty()) { ui->sizeL->setText(Transaction::packageArch(m_details.packageId())); } else { ui->sizeL->hide(); } if (m_currentIcon.isNull()) { ui->iconL->clear(); } else { ui->iconL->setPixmap(m_currentIcon); } } QVector > PackageDetails::locateApplication(const QString &_relPath, const QString &menuId) const { QVector > ret; KServiceGroup::Ptr root = KServiceGroup::group(_relPath); if (!root || !root->isValid()) { return ret; } KServiceGroup::List list = root->entries(false /* sorted */, true /* exclude no display entries */, false /* allow separators */); //! TODO: Port to KF5 properly Q_UNUSED(menuId) #if 0 for (KServiceGroup::List::ConstIterator it = list.begin(); it != list.end(); it++) { KSycocaEntry::Ptr = (*it); if (p->isType(KST_KService)) { KService *service = static_cast(p.get()); if (service->noDisplay()) { continue; } // qCDebug(APPER) << menuId << service->menuId(); if (service->menuId() == menuId) { QPair pair; pair.first = service->name(); pair.second = service->icon(); ret << pair; // qCDebug(APPER) << "FOUND!"; return ret; } } else if (p->isType(KST_KServiceGroup)) { KServiceGroup *serviceGroup = static_cast(p.get()); if (serviceGroup->noDisplay() || serviceGroup->childCount() == 0) { continue; } QVector > found; found = locateApplication(serviceGroup->relPath(), menuId); if (!found.isEmpty()) { QPair pair; pair.first = serviceGroup->caption(); pair.second = serviceGroup->icon(); ret << pair; ret << found; return ret; } } else { kWarning(250) << "KServiceGroup: Unexpected object in list!"; continue; } } #endif return ret; } QString PackageDetails::thumbnail(const QString &pkgName) const { #ifndef HAVE_APPSTREAM Q_UNUSED(pkgName) return QString(); #else return AppStream::instance()->thumbnail(pkgName); #endif } QString PackageDetails::screenshot(const QString &pkgName) const { #ifndef HAVE_APPSTREAM Q_UNUSED(pkgName) return QString(); #else return AppStream::instance()->screenshot(pkgName); #endif } void PackageDetails::description(const PackageKit::Details &details) { qCDebug(APPER) << details; m_details = details; m_detailsDescription = details.description(); m_hasDetails = true; #ifdef HAVE_APPSTREAM // check if we have application details from Appstream data // FIXME: The whole AppStream handling sucks badly, since it was added later // and on to of the package-based model. So we can't respect the "multiple apps // in one package" case here. QList apps; apps = AppStream::instance()->applications(Transaction::packageName(m_packageID)); foreach (const AppStream::Application &app, apps) { if (!app.description.isEmpty()) { m_detailsDescription = app.description; break; } } #endif } void PackageDetails::finished() { if (m_busySeq) { m_busySeq->stop(); } m_transaction = 0; - PackageKit::Transaction *transaction; - transaction = qobject_cast(sender()); + auto transaction = qobject_cast(sender()); qCDebug(APPER); if (transaction) { qCDebug(APPER) << transaction->role() << PackageKit::Transaction::RoleGetDetails; if (transaction->role() == PackageKit::Transaction::RoleGetDetails) { m_hasDetails = true; } else if (transaction->role() == PackageKit::Transaction::RoleGetFiles) { m_hasFileList = true; } else if (transaction->role() == PackageKit::Transaction::RoleRequiredBy) { m_hasRequires = true; } else if (transaction->role() == PackageKit::Transaction::RoleDependsOn) { m_hasDepends = true; } else { return; } display(); } } void PackageDetails::files(const QString &packageID, const QStringList &files) { Q_UNUSED(packageID) m_currentFileList = files; } diff --git a/ApperKCM/ScreenShotViewer.cpp b/ApperKCM/ScreenShotViewer.cpp index 70c62f5..d30a803 100644 --- a/ApperKCM/ScreenShotViewer.cpp +++ b/ApperKCM/ScreenShotViewer.cpp @@ -1,107 +1,107 @@ /*************************************************************************** - * Copyright (C) 2009-2010 by Daniel Nicoletti * + * Copyright (C) 2009-2018 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "ScreenShotViewer.h" #include #include #include #include #include #include #include #include #include #include "ClickableLabel.h" ScreenShotViewer::ScreenShotViewer(const QString &url, QWidget *parent) : QScrollArea(parent) { m_screenshotL = new ClickableLabel(this); m_screenshotL->setCursor(Qt::PointingHandCursor); m_screenshotL->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); m_screenshotL->resize(250, 200); resize(250, 200); setFrameShape(NoFrame); setFrameShadow(Plain); setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); setWidget(m_screenshotL); setWindowIcon(QIcon::fromTheme("layer-visible-on")); auto tempFile = new QTemporaryFile; // tempFile->setPrefix("appgetfull"); // tempFile->setSuffix(".png"); tempFile->open(); KIO::FileCopyJob *job = KIO::file_copy(QUrl(url), - QUrl(tempFile->fileName()), - -1, - KIO::Overwrite | KIO::HideProgressInfo); + QUrl(tempFile->fileName()), + -1, + KIO::Overwrite | KIO::HideProgressInfo); connect(job, &KIO::FileCopyJob::result, this, &ScreenShotViewer::resultJob); m_busySeq = new KPixmapSequenceOverlayPainter(this); m_busySeq->setSequence(KPixmapSequence("process-working", KIconLoader::SizeSmallMedium)); m_busySeq->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); m_busySeq->setWidget(m_screenshotL); m_busySeq->start(); connect(m_screenshotL, SIGNAL(clicked()), this, SLOT(deleteLater())); } ScreenShotViewer::~ScreenShotViewer() { } void ScreenShotViewer::resultJob(KJob *job) { m_busySeq->stop(); auto fJob = qobject_cast(job); if (!fJob->error()) { m_screenshot = QPixmap(fJob->destUrl().toLocalFile()); QPropertyAnimation *anim1 = new QPropertyAnimation(this, "size"); anim1->setDuration(500); anim1->setStartValue(size()); anim1->setEndValue(m_screenshot.size()); anim1->setEasingCurve(QEasingCurve::OutCubic); - connect(anim1, SIGNAL(finished()), this, SLOT(fadeIn())); + connect(anim1, &QPropertyAnimation::finished, this, &ScreenShotViewer::fadeIn); anim1->start(); } else { m_screenshotL->setText(i18n("Could not find screen shot.")); } } void ScreenShotViewer::fadeIn() { - QGraphicsOpacityEffect *effect = new QGraphicsOpacityEffect(m_screenshotL); + auto effect = new QGraphicsOpacityEffect(m_screenshotL); effect->setOpacity(0); - QPropertyAnimation *anim = new QPropertyAnimation(effect, "opacity"); + auto anim = new QPropertyAnimation(effect, "opacity"); anim->setDuration(500); anim->setStartValue(qreal(0)); anim->setEndValue(qreal(1)); m_screenshotL->setGraphicsEffect(effect); m_screenshotL->setPixmap(m_screenshot); m_screenshotL->adjustSize(); anim->start(); } diff --git a/ApperKCM/Settings/OriginModel.cpp b/ApperKCM/Settings/OriginModel.cpp index 623ed1f..3e0d67c 100644 --- a/ApperKCM/Settings/OriginModel.cpp +++ b/ApperKCM/Settings/OriginModel.cpp @@ -1,105 +1,103 @@ /*************************************************************************** * Copyright (C) 2008-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "OriginModel.h" #include #include #include #include #include using namespace PackageKit; OriginModel::OriginModel(QObject *parent) : QStandardItemModel(parent), m_finished(true) { setHorizontalHeaderLabels(QStringList() << i18n("Origin of Packages")); } OriginModel::~OriginModel() { } bool OriginModel::setData(const QModelIndex &index, const QVariant &value, int role) { if (role == Qt::CheckStateRole && index.isValid()) { Transaction *transaction = Daemon::repoEnable(index.data(RepoId).toString(), value.toBool()); - connect(transaction, SIGNAL(errorCode(PackageKit::Transaction::Error,QString)), - SLOT(errorCode(PackageKit::Transaction::Error,QString))); - connect(transaction, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), - SLOT(setRepoFinished(PackageKit::Transaction::Exit))); + connect(transaction, &Transaction::errorCode, this, &OriginModel::errorCode); + connect(transaction, &Transaction::finished, this, &OriginModel::setRepoFinished); } return false; } QVariantHash OriginModel::changes() const { QVariantHash ret; for (int i = 0; i < rowCount(); ++i) { QStandardItem *repo = item(i); bool currentState = repo->checkState(); if (currentState != repo->data(RepoInitialState).toBool()) { ret[repo->data(RepoId).toString()] = currentState; } } return ret; } void OriginModel::addOriginItem(const QString &repo_id, const QString &details, bool enabled) { if (m_finished) { // if we received a finished signal this is a new query removeRows(0, rowCount()); m_finished = false; } - QStandardItem *item = new QStandardItem(details); + auto item = new QStandardItem(details); item->setCheckable(true); item->setCheckState(enabled ? Qt::Checked : Qt::Unchecked); item->setData(repo_id, RepoId); item->setData(enabled, RepoInitialState); appendRow(item); } void OriginModel::finished() { m_finished = true; } void OriginModel::errorCode(PackageKit::Transaction::Error error, const QString &details) { if (error != Transaction::ErrorTransactionCancelled) { KMessageBox::detailedSorry(0, PkStrings::errorMessage(error), details, PkStrings::error(error), KMessageBox::Notify); } } void OriginModel::setRepoFinished(Transaction::Exit exit) { if (exit == Transaction::ExitSuccess) { emit refreshRepoList(); } sender()->deleteLater(); } diff --git a/ApperKCM/Settings/Settings.cpp b/ApperKCM/Settings/Settings.cpp index 32cca18..8154aa9 100644 --- a/ApperKCM/Settings/Settings.cpp +++ b/ApperKCM/Settings/Settings.cpp @@ -1,341 +1,334 @@ /*************************************************************************** * Copyright (C) 2008-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "Settings.h" #include "ui_Settings.h" #include "OriginModel.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace PackageKit; Settings::Settings(Transaction::Roles roles, QWidget *parent) : QWidget(parent), ui(new Ui::Settings), m_roles(roles) { ui->setupUi(this); - QAction *action = new QAction(i18n("Refresh Cache"), this); - connect(action, SIGNAL(triggered()), SIGNAL(refreshCache())); - connect(action, SIGNAL(triggered()), ui->messageWidget, SLOT(animatedHide())); + auto action = new QAction(i18n("Refresh Cache"), this); + connect(action, &QAction::triggered, this, &Settings::refreshCache); + connect(action, &QAction::triggered, ui->messageWidget, &KMessageWidget::animatedHide); ui->messageWidget->addAction(action); ui->messageWidget->setText(i18n("A repository was changed, it's highly recommended to refresh the cache")); ui->messageWidget->hide(); if (!(m_roles & Transaction::RoleRefreshCache)) { ui->intervalL->setEnabled(false); ui->intervalCB->setEnabled(false); } if (!(m_roles & Transaction::RoleGetDistroUpgrades)) { ui->distroIntervalCB->setEnabled(false); } m_originModel = new OriginModel(this); - connect(m_originModel, SIGNAL(refreshRepoList()), - SLOT(refreshRepoModel())); - connect(m_originModel, SIGNAL(refreshRepoList()), - ui->messageWidget, SLOT(animatedShow())); - QSortFilterProxyModel *proxy = new QSortFilterProxyModel(this); + connect(m_originModel, &OriginModel::refreshRepoList, this, &Settings::refreshRepoModel); + connect(m_originModel, &OriginModel::refreshRepoList, ui->messageWidget, &KMessageWidget::animatedShow); + auto proxy = new QSortFilterProxyModel(this); proxy->setDynamicSortFilter(true); proxy->setSourceModel(m_originModel); ui->originTV->setModel(proxy); ui->originTV->header()->setDefaultAlignment(Qt::AlignCenter); // This is needed to keep the oring right ui->originTV->header()->setSortIndicator(0, Qt::AscendingOrder); proxy->sort(0); if (!(m_roles & Transaction::RoleGetRepoList)) { // Disables the group box ui->originTV->setEnabled(false); ui->showOriginsCB->setEnabled(false); } ui->distroIntervalCB->addItem(i18nc("Inform about distribution upgrades", "Never"), Enum::DistroNever); ui->distroIntervalCB->addItem(i18nc("Inform about distribution upgrades", "Only stable"), Enum::DistroStable); // Ignore unstable distros upgrades for now #ifndef false ui->distroIntervalCB->addItem(i18nc("Inform about distribution upgrades", "Stable and development"), Enum::DistroDevelopment); #endif ui->intervalCB->addItem(i18nc("Hourly refresh the package cache", "Hourly"), Enum::Hourly); ui->intervalCB->addItem(i18nc("Daily refresh the package cache", "Daily"), Enum::Daily); ui->intervalCB->addItem(i18nc("Weekly refresh the package cache", "Weekly"), Enum::Weekly); ui->intervalCB->addItem(i18nc("Monthly refresh the package cache", "Monthly"), Enum::Monthly); ui->intervalCB->addItem(i18nc("Never refresh package cache", "Never"), Enum::Never); ui->autoCB->addItem(i18nc("No updates will be automatically installed", "None"), Enum::None); ui->autoCB->addItem(i18n("Download only"), Enum::DownloadOnly); ui->autoCB->addItem(i18n("Security only"), Enum::Security); ui->autoCB->addItem(i18n("All updates"), Enum::All); - connect(ui->autoConfirmCB, SIGNAL(stateChanged(int)), this, SLOT(checkChanges())); - connect(ui->appLauncherCB, SIGNAL(stateChanged(int)), this, SLOT(checkChanges())); - connect(ui->distroIntervalCB, SIGNAL(currentIndexChanged(int)), this, SLOT(checkChanges())); - connect(ui->intervalCB, SIGNAL(currentIndexChanged(int)), this, SLOT(checkChanges())); - connect(ui->checkUpdatesBatteryCB, SIGNAL(stateChanged(int)), this, SLOT(checkChanges())); - connect(ui->checkUpdatesMobileCB, SIGNAL(stateChanged(int)), this, SLOT(checkChanges())); - connect(ui->autoCB, SIGNAL(currentIndexChanged(int)), this, SLOT(checkChanges())); - connect(ui->installUpdatesBatteryCB, SIGNAL(stateChanged(int)), this, SLOT(checkChanges())); - connect(ui->installUpdatesMobileCB, SIGNAL(stateChanged(int)), this, SLOT(checkChanges())); + connect(ui->autoConfirmCB, &QCheckBox::stateChanged, this, &Settings::checkChanges); + connect(ui->appLauncherCB, &QCheckBox::stateChanged, this, &Settings::checkChanges); + connect(ui->distroIntervalCB, QOverload::of(&KComboBox::currentIndexChanged), this, &Settings::checkChanges); + connect(ui->intervalCB, QOverload::of(&KComboBox::currentIndexChanged), this, &Settings::checkChanges); + connect(ui->checkUpdatesBatteryCB, &QCheckBox::stateChanged, this, &Settings::checkChanges); + connect(ui->checkUpdatesMobileCB, &QCheckBox::stateChanged, this, &Settings::checkChanges); + connect(ui->autoCB, QOverload::of(&KComboBox::currentIndexChanged), this, &Settings::checkChanges); + connect(ui->installUpdatesBatteryCB, &QCheckBox::stateChanged, this, &Settings::checkChanges); + connect(ui->installUpdatesMobileCB, &QCheckBox::stateChanged, this, &Settings::checkChanges); // Setup the busy cursor m_busySeq = new KPixmapSequenceOverlayPainter(this); m_busySeq->setSequence(KPixmapSequence("process-working", KIconLoader::SizeSmallMedium)); m_busySeq->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); m_busySeq->setWidget(ui->originTV->viewport()); #ifndef EDIT_ORIGNS_DESKTOP_NAME ui->editOriginsPB->hide(); #endif //EDIT_ORIGNS_DESKTOP_NAME } Settings::~Settings() { delete ui; } void Settings::on_editOriginsPB_clicked() { #ifdef EDIT_ORIGNS_DESKTOP_NAME KToolInvocation::startServiceByDesktopName(EDIT_ORIGNS_DESKTOP_NAME); #endif //EDIT_ORIGNS_DESKTOP_NAME } void Settings::refreshRepoModel() { on_showOriginsCB_stateChanged(ui->showOriginsCB->checkState()); } // TODO update the repo list connecting to repo changed signal void Settings::on_showOriginsCB_stateChanged(int state) { - Transaction *transaction; - transaction = Daemon::getRepoList(state == Qt::Checked ? - Transaction::FilterNone : Transaction::FilterNotDevel); - connect(transaction, SIGNAL(repoDetail(QString,QString,bool)), - m_originModel, SLOT(addOriginItem(QString,QString,bool))); - connect(transaction, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), - m_originModel, SLOT(finished())); - connect(transaction, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), - m_busySeq, SLOT(stop())); - connect(transaction, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), - this, SLOT(checkChanges())); + Transaction *transaction = Daemon::getRepoList(state == Qt::Checked ? + Transaction::FilterNone : Transaction::FilterNotDevel); + connect(transaction, &Transaction::repoDetail, m_originModel, &OriginModel::addOriginItem); + connect(transaction, &Transaction::finished, m_originModel, &OriginModel::finished); + connect(transaction, &Transaction::finished, m_busySeq, &KPixmapSequenceOverlayPainter::stop); + connect(transaction, &Transaction::finished, this, &Settings::checkChanges); m_busySeq->start(); KConfig config("apper"); KConfigGroup originsDialog(&config, "originsDialog"); bool showDevel = originsDialog.readEntry("showDevel", false); if (showDevel != ui->showOriginsCB->isChecked()) { originsDialog.writeEntry("showDevel", ui->showOriginsCB->isChecked()); } } bool Settings::hasChanges() const { KConfig config("apper"); KConfigGroup requirementsDialog(&config, "requirementsDialog"); KConfigGroup transaction(&config, "Transaction"); KConfigGroup checkUpdateGroup(&config, "CheckUpdate"); if (ui->distroIntervalCB->itemData(ui->distroIntervalCB->currentIndex()).toUInt() != static_cast(checkUpdateGroup.readEntry(CFG_DISTRO_UPGRADE, Enum::DistroUpgradeDefault)) || ui->intervalCB->itemData(ui->intervalCB->currentIndex()).toUInt() != static_cast(checkUpdateGroup.readEntry(CFG_INTERVAL, Enum::TimeIntervalDefault)) || ui->checkUpdatesBatteryCB->isChecked() != checkUpdateGroup.readEntry(CFG_CHECK_UP_BATTERY, DEFAULT_CHECK_UP_BATTERY) || ui->checkUpdatesMobileCB->isChecked() != checkUpdateGroup.readEntry(CFG_CHECK_UP_MOBILE, DEFAULT_CHECK_UP_MOBILE) || ui->autoCB->itemData(ui->autoCB->currentIndex()).toUInt() != static_cast(checkUpdateGroup.readEntry(CFG_AUTO_UP, Enum::AutoUpdateDefault)) || ui->installUpdatesBatteryCB->isChecked() != checkUpdateGroup.readEntry(CFG_INSTALL_UP_BATTERY, DEFAULT_INSTALL_UP_BATTERY) || ui->installUpdatesMobileCB->isChecked() != checkUpdateGroup.readEntry(CFG_INSTALL_UP_MOBILE, DEFAULT_INSTALL_UP_MOBILE) || ui->autoConfirmCB->isChecked() != !requirementsDialog.readEntry("autoConfirm", false) || ui->appLauncherCB->isChecked() != transaction.readEntry("ShowApplicationLauncher", true)) { return true; } return false; } void Settings::checkChanges() { emit changed(hasChanges()); // Check if interval update is never bool enabled = ui->intervalCB->itemData(ui->intervalCB->currentIndex()).toUInt() != Enum::Never; ui->checkUpdatesBatteryCB->setEnabled(enabled); ui->checkUpdatesMobileCB->setEnabled(enabled); ui->autoInsL->setEnabled(enabled); ui->autoCB->setEnabled(enabled); if (enabled) { enabled = ui->autoCB->itemData(ui->autoCB->currentIndex()).toUInt() != Enum::None; } ui->installUpdatesMobileCB->setEnabled(enabled); ui->installUpdatesBatteryCB->setEnabled(enabled); } void Settings::load() { KConfig config("apper"); KConfigGroup requirementsDialog(&config, "requirementsDialog"); ui->autoConfirmCB->setChecked(!requirementsDialog.readEntry("autoConfirm", false)); KConfigGroup transaction(&config, "Transaction"); ui->appLauncherCB->setChecked(transaction.readEntry("ShowApplicationLauncher", true)); KConfigGroup checkUpdateGroup(&config, "CheckUpdate"); uint distroUpgrade = checkUpdateGroup.readEntry(CFG_DISTRO_UPGRADE, Enum::DistroUpgradeDefault); int ret = ui->distroIntervalCB->findData(distroUpgrade); if (ret == -1) { ui->distroIntervalCB->setCurrentIndex(ui->distroIntervalCB->findData(Enum::DistroUpgradeDefault)); } else { ui->distroIntervalCB->setCurrentIndex(ret); } uint interval = checkUpdateGroup.readEntry(CFG_INTERVAL, Enum::TimeIntervalDefault); ret = ui->intervalCB->findData(interval); if (ret == -1) { // this is if someone change the file by hand... KFormat f; // ui->intervalCB->addItem(KLocale::global()->prettyFormatDuration(interval * 1000), interval); ui->intervalCB->addItem(f.formatDuration(interval * 1000), interval); ui->intervalCB->setCurrentIndex(ui->intervalCB->count() - 1); } else { ui->intervalCB->setCurrentIndex(ret); } ui->checkUpdatesBatteryCB->setChecked(checkUpdateGroup.readEntry(CFG_CHECK_UP_BATTERY, DEFAULT_CHECK_UP_BATTERY)); ui->checkUpdatesMobileCB->setChecked(checkUpdateGroup.readEntry(CFG_CHECK_UP_MOBILE, DEFAULT_CHECK_UP_MOBILE)); uint autoUpdate = checkUpdateGroup.readEntry(CFG_AUTO_UP, Enum::AutoUpdateDefault); ret = ui->autoCB->findData(autoUpdate); if (ret == -1) { // this is if someone change the file by hand... ui->autoCB->setCurrentIndex(ui->autoCB->findData(Enum::AutoUpdateDefault)); } else { ui->autoCB->setCurrentIndex(ret); } ui->installUpdatesBatteryCB->setChecked(checkUpdateGroup.readEntry(CFG_INSTALL_UP_BATTERY, DEFAULT_INSTALL_UP_BATTERY)); ui->installUpdatesMobileCB->setChecked(checkUpdateGroup.readEntry(CFG_INSTALL_UP_MOBILE, DEFAULT_INSTALL_UP_MOBILE)); // Load origns list if (m_roles & Transaction::RoleGetRepoList) { KConfigGroup originsDialog(&config, "originsDialog"); bool showDevel = originsDialog.readEntry("showDevel", false); ui->showOriginsCB->setChecked(showDevel); refreshRepoModel(); ui->originTV->setEnabled(true); } else { ui->originTV->setEnabled(false); } // hide battery options if we are on a desktop computer const QList listBattery = Solid::Device::listFromType(Solid::DeviceInterface::Battery, QString()); bool notFound = true; - foreach (const Solid::Device &device, listBattery) { + for (const Solid::Device &device : listBattery) { const Solid::Battery *battery = device.as(); if (battery && battery->type() == Solid::Battery::PrimaryBattery) { notFound = false; break; } } if (notFound) { ui->checkUpdatesBatteryCB->hide(); ui->installUpdatesBatteryCB->hide(); } } void Settings::save() { KConfig config("apper"); KConfigGroup requirementsDialog(&config, "requirementsDialog"); requirementsDialog.writeEntry("autoConfirm", !ui->autoConfirmCB->isChecked()); KConfigGroup transaction(&config, "Transaction"); transaction.writeEntry("ShowApplicationLauncher", ui->appLauncherCB->isChecked()); KConfigGroup checkUpdateGroup(&config, "CheckUpdate"); checkUpdateGroup.writeEntry("distroUpgrade", ui->distroIntervalCB->itemData(ui->distroIntervalCB->currentIndex()).toUInt()); checkUpdateGroup.writeEntry("interval", ui->intervalCB->itemData(ui->intervalCB->currentIndex()).toUInt()); checkUpdateGroup.writeEntry("checkUpdatesOnBattery", ui->checkUpdatesBatteryCB->isChecked()); checkUpdateGroup.writeEntry("checkUpdatesOnMobile", ui->checkUpdatesMobileCB->isChecked()); checkUpdateGroup.writeEntry("autoUpdate", ui->autoCB->itemData(ui->autoCB->currentIndex()).toUInt()); checkUpdateGroup.writeEntry("installUpdatesOnBattery", ui->installUpdatesBatteryCB->isChecked()); checkUpdateGroup.writeEntry("installUpdatesOnMobile", ui->installUpdatesMobileCB->isChecked()); } void Settings::defaults() { ui->autoConfirmCB->setChecked(true); ui->appLauncherCB->setChecked(true); ui->distroIntervalCB->setCurrentIndex(ui->distroIntervalCB->findData(Enum::DistroUpgradeDefault)); ui->intervalCB->setCurrentIndex(ui->intervalCB->findData(Enum::TimeIntervalDefault)); ui->autoCB->setCurrentIndex(ui->autoCB->findData(Enum::AutoUpdateDefault) ); checkChanges(); } void Settings::showGeneralSettings() { ui->stackedWidget->setCurrentIndex(0); } void Settings::showRepoSettings() { ui->stackedWidget->setCurrentIndex(1); } diff --git a/ApperKCM/TransactionFilterModel.cpp b/ApperKCM/TransactionFilterModel.cpp index 477ab6b..f0c2192 100644 --- a/ApperKCM/TransactionFilterModel.cpp +++ b/ApperKCM/TransactionFilterModel.cpp @@ -1,46 +1,46 @@ /*************************************************************************** * Copyright (C) 2009 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "TransactionFilterModel.h" #include #include TransactionFilterModel::TransactionFilterModel(QObject *parent) : QSortFilterProxyModel(parent) { } TransactionFilterModel::~TransactionFilterModel() { } bool TransactionFilterModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { - QVariant leftData = sourceModel()->data(left, Qt::UserRole); - QVariant rightData = sourceModel()->data(right, Qt::UserRole); + const QVariant leftData = sourceModel()->data(left, Qt::UserRole); + const QVariant rightData = sourceModel()->data(right, Qt::UserRole); if (leftData.type() == QVariant::DateTime) { return leftData.toDateTime() < rightData.toDateTime(); } else { return QSortFilterProxyModel::lessThan(left, right); } } diff --git a/ApperKCM/TransactionModel.cpp b/ApperKCM/TransactionModel.cpp index 68b771b..10fe54f 100644 --- a/ApperKCM/TransactionModel.cpp +++ b/ApperKCM/TransactionModel.cpp @@ -1,151 +1,155 @@ /*************************************************************************** * Copyright (C) 2009-2010 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "TransactionModel.h" #include #include #include #include #include #include using namespace PackageKit; TransactionModel::TransactionModel(QObject *parent) : QStandardItemModel(parent) { setSortRole(Qt::DisplayRole); clear(); } void TransactionModel::clear() { QStandardItemModel::clear(); setHorizontalHeaderItem(0, new QStandardItem(i18n("Date"))); setHorizontalHeaderItem(1, new QStandardItem(i18n("Action"))); setHorizontalHeaderItem(2, new QStandardItem(i18n("Details"))); setHorizontalHeaderItem(3, new QStandardItem(i18nc("Machine user who issued the transaction", "Username"))); setHorizontalHeaderItem(4, new QStandardItem(i18n("Application"))); } void TransactionModel::addTransaction(PackageKit::Transaction *trans) { - QStandardItem *dateI = new QStandardItem; - QStandardItem *roleI = new QStandardItem; - QStandardItem *detailsI = new QStandardItem; - QStandardItem *userI = new QStandardItem; - QStandardItem *appI = new QStandardItem; + auto dateI = new QStandardItem; + auto roleI = new QStandardItem; + auto detailsI = new QStandardItem; + auto userI = new QStandardItem; + auto appI = new QStandardItem; dateI->setText(QLocale::system().toString(trans->timespec().date())); // this is for the filterSort model dateI->setData(trans->timespec(), Qt::UserRole); dateI->setEditable(false); roleI->setText(PkStrings::actionPast(trans->role())); roleI->setIcon(PkIcons::actionIcon(trans->role())); roleI->setEditable(false); detailsI->setText(getDetailsLocalized(trans->data())); detailsI->setEditable(false); KUser user(trans->uid()); QString display; if (!user.property(KUser::FullName).toString().isEmpty()) { display = user.property(KUser::FullName).toString() + " (" + user.loginName() + ')'; } else { display = user.loginName(); } userI->setText(display); userI->setEditable(false); appI->setText(trans->cmdline()); appI->setEditable(false); - QList line; - line << dateI << roleI << detailsI << userI << appI; - appendRow(line); + appendRow({ + dateI, + roleI, + detailsI, + userI, + appI + }); delete trans; } QString TransactionModel::getDetailsLocalized(const QString &data) const { - QStringList lines = data.split('\n'); + QStringList lines = data.split(QLatin1Char('\n')); QStringList ret; QString text; text = getTypeLine(lines, Transaction::StatusInstall); if (!text.isNull()) { ret << text; } text = getTypeLine(lines, Transaction::StatusRemove); if (!text.isNull()) { ret << text; } text = getTypeLine(lines, Transaction::StatusUpdate); if (!text.isNull()) { ret << text; } - return ret.join("\n"); + return ret.join(QLatin1Char('\n')); } QString TransactionModel::getTypeLine(const QStringList &lines, Transaction::Status status) const { QStringList text; - foreach(const QString &line, lines) { - QStringList sections = line.split('\t'); + for (const QString &line : lines) { + const QStringList sections = line.split(QLatin1Char('\t')); if (sections.size() > 1) { switch (status) { case Transaction::StatusInstall: - if (sections.at(0) != "installing") { + if (sections.at(0) != QLatin1String("installing")) { continue; } break; case Transaction::StatusRemove: - if (sections.at(0) != "removing") { + if (sections.at(0) != QLatin1String("removing")) { continue; } break; case Transaction::StatusUpdate: - if (sections.at(0) != "updating") { + if (sections.at(0) != QLatin1String("updating")) { continue; } break; default: continue; } - QStringList packageData = sections.at(1).split(';'); + QStringList packageData = sections.at(1).split(QLatin1Char(';')); if (packageData.size()) { text << packageData.at(0); } } } if (text.size()) { // TODO make the status BOLD - return PkStrings::statusPast(status) + ": " + text.join(", "); + return PkStrings::statusPast(status) + QLatin1String(": ") + text.join(QLatin1String(", ")); } else { return QString(); } } diff --git a/ApperKCM/Updater/DistroUpgrade.cpp b/ApperKCM/Updater/DistroUpgrade.cpp index fecd75c..7152365 100644 --- a/ApperKCM/Updater/DistroUpgrade.cpp +++ b/ApperKCM/Updater/DistroUpgrade.cpp @@ -1,116 +1,115 @@ /*************************************************************************** * Copyright (C) 2009-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "DistroUpgrade.h" #include #include #include #include #include //#include #include #include DistroUpgrade::DistroUpgrade(QWidget *parent) : KMessageWidget(parent) { auto action = new QAction(i18n("Upgrade"), this); connect(action, &QAction::triggered, this, &DistroUpgrade::startDistroUpgrade); addAction(action); } DistroUpgrade::~DistroUpgrade() { } void DistroUpgrade::setName(const QString &name) { setText(i18n("Distribution upgrade available: %1", name)); } void DistroUpgrade::startDistroUpgrade() { //! QList powerPlugs = Solid::Device::listFromType(Solid::DeviceInterface::AcAdapter); bool pluggedIn = true; bool hasBattery = Solid::Device::listFromType(Solid::DeviceInterface::Battery).size()>0; //! foreach(const Solid::Device &dev, powerPlugs) { //! if (!dev.as()->isPlugged()) { //! pluggedIn = false; //! } //! } QString warning = i18n("You are about to upgrade your distribution to the latest version. " "This is usually a very lengthy process and takes a lot longer than " "simply upgrading your packages."); if (!pluggedIn) { warning += ' ' + i18n("It is recommended to plug in your computer before proceeding."); } else if (hasBattery) { warning += ' ' + i18n("It is recommended that you keep your computer plugged in while the upgrade is being performed."); } if (KMessageBox::warningContinueCancel(this,warning) == KMessageBox::Continue) { m_distroUpgradeProcess = new QProcess; - connect(m_distroUpgradeProcess, SIGNAL(error(QProcess::ProcessError)), - this, SLOT(distroUpgradeError(QProcess::ProcessError))); - connect(m_distroUpgradeProcess, SIGNAL(finished(int,QProcess::ExitStatus)), - this, SLOT(distroUpgradeFinished(int,QProcess::ExitStatus))); + connect(m_distroUpgradeProcess, &QProcess::errorOccurred, this, &DistroUpgrade::distroUpgradeError); + connect(m_distroUpgradeProcess, QOverload::of(&QProcess::finished), + this, &DistroUpgrade::distroUpgradeFinished); QStringList env = QProcess::systemEnvironment(); env << "DESKTOP=kde"; m_distroUpgradeProcess->setEnvironment(env); m_distroUpgradeProcess->start("/usr/share/PackageKit/pk-upgrade-distro.sh"); } } void DistroUpgrade::distroUpgradeFinished(int exitCode, QProcess::ExitStatus exitStatus) { if (exitStatus == QProcess::NormalExit && exitCode == 0) { KMessageBox::information(this, i18n("Distribution upgrade complete.")); } else if (exitStatus == QProcess::NormalExit) { KMessageBox::sorry(this, i18n("Distribution upgrade process exited with code %1.", exitCode)); } m_distroUpgradeProcess->deleteLater(); m_distroUpgradeProcess = 0; } void DistroUpgrade::distroUpgradeError(QProcess::ProcessError error) { QString text; switch(error) { case QProcess::FailedToStart: KMessageBox::sorry(this, i18n("The distribution upgrade process failed to start.")); break; case QProcess::Crashed: KMessageBox::sorry(this, i18n("The distribution upgrade process crashed some time after starting successfully.")); break; default: KMessageBox::sorry(this, i18n("The distribution upgrade process failed with an unknown error.")); break; } } diff --git a/ApperKCM/Updater/UpdateDetails.cpp b/ApperKCM/Updater/UpdateDetails.cpp index 27cc5a9..eff778f 100644 --- a/ApperKCM/Updater/UpdateDetails.cpp +++ b/ApperKCM/Updater/UpdateDetails.cpp @@ -1,344 +1,340 @@ /*************************************************************************** - * Copyright (C) 2009-2011 by Daniel Nicoletti * + * Copyright (C) 2009-2018 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "UpdateDetails.h" #include #include #include #include #include #include #include #include #include #include #include #include #define FINAL_HEIGHT 160 Q_DECLARE_LOGGING_CATEGORY(APPER) UpdateDetails::UpdateDetails(QWidget *parent) : QWidget(parent), m_show(false), m_transaction(0) { setupUi(this); hideTB->setIcon(QIcon::fromTheme("window-close")); - connect(hideTB, SIGNAL(clicked()), this, SLOT(hide())); + connect(hideTB, &QToolButton::clicked, this, &UpdateDetails::hide); m_busySeq = new KPixmapSequenceOverlayPainter(this); m_busySeq->setSequence(KPixmapSequence("process-working", KIconLoader::SizeSmallMedium)); m_busySeq->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); m_busySeq->setWidget(this); QWidget *actionsViewport = descriptionKTB->viewport(); QPalette palette = actionsViewport->palette(); palette.setColor(actionsViewport->backgroundRole(), Qt::transparent); palette.setColor(actionsViewport->foregroundRole(), palette.color(QPalette::WindowText)); actionsViewport->setPalette(palette); - QGraphicsOpacityEffect *effect = new QGraphicsOpacityEffect(descriptionKTB); + auto effect = new QGraphicsOpacityEffect(descriptionKTB); effect->setOpacity(0); descriptionKTB->setGraphicsEffect(effect); m_fadeDetails = new QPropertyAnimation(effect, "opacity", this); m_fadeDetails->setDuration(500); m_fadeDetails->setStartValue(qreal(0)); m_fadeDetails->setEndValue(qreal(1)); - connect(m_fadeDetails, SIGNAL(finished()), this, SLOT(display())); + connect(m_fadeDetails, &QPropertyAnimation::finished, this, &UpdateDetails::display); - QPropertyAnimation *anim1 = new QPropertyAnimation(this, "maximumSize", this); + auto anim1 = new QPropertyAnimation(this, "maximumSize", this); anim1->setDuration(500); anim1->setEasingCurve(QEasingCurve::OutQuart); anim1->setStartValue(QSize(QWIDGETSIZE_MAX, 0)); anim1->setEndValue(QSize(QWIDGETSIZE_MAX, FINAL_HEIGHT)); - QPropertyAnimation *anim2 = new QPropertyAnimation(this, "minimumSize", this); + auto anim2 = new QPropertyAnimation(this, "minimumSize", this); anim2->setDuration(500); anim2->setEasingCurve(QEasingCurve::OutQuart); anim2->setStartValue(QSize(QWIDGETSIZE_MAX, 0)); anim2->setEndValue(QSize(QWIDGETSIZE_MAX, FINAL_HEIGHT)); m_expandPanel = new QParallelAnimationGroup(this); m_expandPanel->addAnimation(anim1); m_expandPanel->addAnimation(anim2); - connect(m_expandPanel, SIGNAL(finished()), this, SLOT(display())); + connect(m_expandPanel, &QParallelAnimationGroup::finished, this, &UpdateDetails::display); } UpdateDetails::~UpdateDetails() { } void UpdateDetails::setPackage(const QString &packageId, Transaction::Info updateInfo) { if (m_packageId == packageId) { return; } m_show = true; m_packageId = packageId; m_updateInfo = updateInfo; m_currentDescription.clear(); if (m_transaction) { - disconnect(m_transaction, SIGNAL(updateDetail(QString,QStringList,QStringList,QStringList,QStringList,QStringList,PackageKit::Transaction::Restart,QString,QString,PackageKit::Transaction::UpdateState,QDateTime,QDateTime)), - this, SLOT(updateDetail(QString,QStringList,QStringList,QStringList,QStringList,QStringList,PackageKit::Transaction::Restart,QString,QString,PackageKit::Transaction::UpdateState,QDateTime,QDateTime))); - disconnect(m_transaction, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), - this, SLOT(display())); + disconnect(m_transaction, &Transaction::updateDetail, this, &UpdateDetails::updateDetail); + disconnect(m_transaction, &Transaction::finished, this, &UpdateDetails::display); } m_transaction = Daemon::getUpdateDetail(m_packageId); - connect(m_transaction, SIGNAL(updateDetail(QString,QStringList,QStringList,QStringList,QStringList,QStringList,PackageKit::Transaction::Restart,QString,QString,PackageKit::Transaction::UpdateState,QDateTime,QDateTime)), - this, SLOT(updateDetail(QString,QStringList,QStringList,QStringList,QStringList,QStringList,PackageKit::Transaction::Restart,QString,QString,PackageKit::Transaction::UpdateState,QDateTime,QDateTime))); - connect(m_transaction, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), - this, SLOT(display())); + connect(m_transaction, &Transaction::updateDetail, this, &UpdateDetails::updateDetail); + connect(m_transaction, &Transaction::finished, this, &UpdateDetails::display); if (maximumSize().height() == 0) { // Expand the panel m_expandPanel->setDirection(QAbstractAnimation::Forward); m_expandPanel->start(); } else if (m_fadeDetails->currentValue().toReal() != 0) { // Hide the old description m_fadeDetails->setDirection(QAbstractAnimation::Backward); m_fadeDetails->start(); } m_busySeq->start(); } void UpdateDetails::hide() { m_show = false; m_packageId.clear(); if (maximumSize().height() == FINAL_HEIGHT && m_fadeDetails->currentValue().toReal() == 1) { m_fadeDetails->setDirection(QAbstractAnimation::Backward); m_fadeDetails->start(); } else if (maximumSize().height() == FINAL_HEIGHT && m_fadeDetails->currentValue().toReal() == 0) { m_expandPanel->setDirection(QAbstractAnimation::Backward); m_expandPanel->start(); } } void UpdateDetails::display() { qCDebug(APPER) << sender(); // set transaction to 0 as if PK crashes // UpdateDetails won't be emmited m_transaction = 0; if (!m_show) { hide(); return; } if (maximumSize().height() == FINAL_HEIGHT && !m_currentDescription.isEmpty() && m_fadeDetails->currentValue().toReal() == 0) { descriptionKTB->setHtml(m_currentDescription); m_fadeDetails->setDirection(QAbstractAnimation::Forward); m_fadeDetails->start(); } else if (m_currentDescription.isEmpty()) { updateDetailFinished(); } } void UpdateDetails::updateDetail(const QString &packageID, const QStringList &updates, const QStringList &obsoletes, const QStringList &vendorUrls, const QStringList &bugzillaUrls, const QStringList &cveUrls, PackageKit::Transaction::Restart restart, const QString &updateText, const QString &changelog, PackageKit::Transaction::UpdateState state, const QDateTime &issued, const QDateTime &updated) { //format and show description QString description; // update type (ie Security Update) if (m_updateInfo == Transaction::InfoEnhancement) { description += "

" + i18n("This update will add new features and expand functionality.") + "

"; } else if (m_updateInfo == Transaction::InfoBugfix) { description += "

" + i18n("This update will fix bugs and other non-critical problems.") + "

"; } else if (m_updateInfo == Transaction::InfoImportant) { description += "

" + i18n("This update is important as it may solve critical problems.") + "

"; } else if (m_updateInfo == Transaction::InfoSecurity) { description += "

" + i18n("This update is needed to fix a security vulnerability with this package.") + "

"; } else if (m_updateInfo == Transaction::InfoBlocked) { description += "

" + i18n("This update is blocked.") + "

"; } // Issued and Updated if (!issued.isNull() && !updated.isNull()) { description += "

" + i18n("This notification was issued on %1 and last updated on %2.", QLocale::system().toString(issued, QLocale::ShortFormat), QLocale::system().toString(updated, QLocale::ShortFormat)) + "

"; } else if (!issued.isNull()) { description += "

" + i18n("This notification was issued on %1.", QLocale::system().toString(issued, QLocale::ShortFormat)) + "

"; } // Description if (!updateText.isEmpty()) { QString _updateText = updateText; _updateText.replace('\n', "
"); _updateText.replace(' ', " "); description += "

" + _updateText + "

"; } // links // Vendor if (!vendorUrls.isEmpty()) { description += "

" + i18np("For more information about this update please visit this website:", "For more information about this update please visit these websites:", vendorUrls.size()) + "
" + getLinkList(vendorUrls) + "

"; } // Bugzilla if (!bugzillaUrls.isEmpty()) { description += "

" + i18np("For more information about bugs fixed by this update please visit this website:", "For more information about bugs fixed by this update please visit these websites:", bugzillaUrls.size()) + "
" + getLinkList(bugzillaUrls) + "

"; } // CVE if (!cveUrls.isEmpty()) { description += "

" + i18np("For more information about this security update please visit this website:", "For more information about this security update please visit these websites:", cveUrls.size()) + "
" + getLinkList(cveUrls) + "

"; } // Notice (about the need for a reboot) if (restart == Transaction::RestartSystem) { description += "

" + i18n("The computer will have to be restarted after the update for the changes to take effect.") + "

"; } else if (restart == Transaction::RestartSession) { description += "

" + i18n("You will need to log out and back in after the update for the changes to take effect.") + "

"; } // State if (state == Transaction::UpdateStateUnstable) { description += "

" + i18n("The classification of this update is unstable which means it is not designed for production use.") + "

"; } else if (state == Transaction::UpdateStateTesting) { description += "

" + i18n("This is a test update, and is not designed for normal use. Please report any problems or regressions you encounter.") + "

"; } // only show changelog if we didn't have any update text if (updateText.isEmpty() && !changelog.isEmpty()) { QString _changelog = changelog; _changelog.replace('\n', "
"); _changelog.replace(' ', " "); description += "

" + i18n("The developer logs will be shown as no description is available for this update:") + "
" + _changelog + "

"; } // Updates (lists of packages that are updated) if (!updates.isEmpty()) { description += "

" + i18n("Updates:") + "
"; QStringList _updates; - foreach (const QString &pid, updates) { + for (const QString &pid : updates) { _updates += QString::fromUtf8("\xE2\x80\xA2 ") + Transaction::packageName(pid) + " - " + Transaction::packageVersion(pid); } description += _updates.join("
") + "

"; } // Obsoletes (lists of packages that are obsoleted) if (obsoletes.size()) { description += "

" + i18n("Obsoletes:") + "
"; QStringList _obsoletes; - foreach (const QString &pid, obsoletes) { + for (const QString &pid : obsoletes) { _obsoletes += QString::fromUtf8("\xE2\x80\xA2 ") + Transaction::packageName(pid) + " - " + Transaction::packageVersion(pid); } description += _obsoletes.join("
/") + "

"; } // Repository (this is the repository the package comes from) if (!Transaction::packageData(packageID).isEmpty()) { description += "

" + i18n("Repository: %1", Transaction::packageData(packageID)) + "

"; } m_currentDescription = description; m_busySeq->stop(); } QString UpdateDetails::getLinkList(const QStringList &urls) const { QString ret; - foreach (const QString &url, urls) { + for (const QString &url : urls) { if (!ret.isEmpty()) { ret += "
"; } ret += QString::fromUtf8(" \xE2\x80\xA2 ") % url % QLatin1String(""); } return ret; } void UpdateDetails::updateDetailFinished() { if (descriptionKTB->document()->toPlainText().isEmpty()) { descriptionKTB->setPlainText(i18n("No update description was found.")); } } diff --git a/ApperKCM/Updater/Updater.cpp b/ApperKCM/Updater/Updater.cpp index 1f15212..c695fe2 100644 --- a/ApperKCM/Updater/Updater.cpp +++ b/ApperKCM/Updater/Updater.cpp @@ -1,359 +1,349 @@ /*************************************************************************** * Copyright (C) 2008-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "Updater.h" #include "ui_Updater.h" #include "UpdateDetails.h" #include "DistroUpgrade.h" #include "CheckableHeader.h" #include //#include #include #include #include #include #include #include #include #include #include #include #include #include //#include #include #include #include Updater::Updater(Transaction::Roles roles, QWidget *parent) : QWidget(parent), ui(new Ui::Updater), m_roles(roles), m_selected(true), m_updatesT(0) { ui->setupUi(this); updatePallete(); // connect(KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()), // this, SLOT(updatePallete())); m_updatesModel = new PackageModel(this); m_updatesModel->setCheckable(true); - ApplicationSortFilterModel *proxyModel = new ApplicationSortFilterModel(this); + auto proxyModel = new ApplicationSortFilterModel(this); proxyModel->setSourceModel(m_updatesModel); ui->packageView->setModel(proxyModel); m_delegate = new ApplicationsDelegate(ui->packageView); m_delegate->setCheckable(true); ui->packageView->setItemDelegate(m_delegate); ui->packageView->sortByColumn(PackageModel::NameCol, Qt::AscendingOrder); - connect(m_updatesModel, SIGNAL(changed(bool)), - this, SLOT(checkEnableUpdateButton())); + connect(m_updatesModel, &PackageModel::changed, this, &Updater::checkEnableUpdateButton); //initialize the model, delegate, client and connect it's signals m_header = new CheckableHeader(Qt::Horizontal, this); - connect(m_header, SIGNAL(toggled(bool)), - m_updatesModel, SLOT(setAllChecked(bool))); + connect(m_header, &CheckableHeader::toggled, m_updatesModel, &PackageModel::setAllChecked); m_header->setCheckBoxVisible(false); m_header->setDefaultAlignment(Qt::AlignCenter); ui->packageView->setHeaderHidden(false); ui->packageView->setHeader(m_header); // This must be set AFTER the model is set, otherwise it doesn't work m_header->setSectionResizeMode(PackageModel::NameCol, QHeaderView::Stretch); m_header->setSectionResizeMode(PackageModel::VersionCol, QHeaderView::ResizeToContents); m_header->setSectionResizeMode(PackageModel::CurrentVersionCol, QHeaderView::ResizeToContents); m_header->setSectionResizeMode(PackageModel::ArchCol, QHeaderView::ResizeToContents); m_header->setSectionResizeMode(PackageModel::OriginCol, QHeaderView::ResizeToContents); m_header->setSectionResizeMode(PackageModel::SizeCol, QHeaderView::ResizeToContents); m_header->setStretchLastSection(false); // Setup the busy cursor m_busySeq = new KPixmapSequenceOverlayPainter(this); m_busySeq->setSequence(KPixmapSequence("process-working", KIconLoader::SizeSmallMedium)); m_busySeq->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); m_busySeq->setWidget(ui->packageView->viewport()); // hide distro Upgrade container and line ui->distroUpgrade->hide(); KConfig config("apper"); KConfigGroup viewGroup(&config, "UpdateView"); // versions ui->packageView->header()->setSectionHidden(PackageModel::VersionCol, true); m_showPackageVersion = new QAction(i18n("Show Versions"), this); m_showPackageVersion->setCheckable(true); - connect(m_showPackageVersion, SIGNAL(toggled(bool)), this, SLOT(showVersions(bool))); + connect(m_showPackageVersion, &QAction::toggled, this, &Updater::showVersions); m_showPackageVersion->setChecked(viewGroup.readEntry("ShowVersions", true)); // versions ui->packageView->header()->setSectionHidden(PackageModel::CurrentVersionCol, true); m_showPackageCurrentVersion = new QAction(i18n("Show Current Versions"), this); m_showPackageCurrentVersion->setCheckable(true); - connect(m_showPackageCurrentVersion, SIGNAL(toggled(bool)), this, SLOT(showCurrentVersions(bool))); + connect(m_showPackageCurrentVersion, &QAction::toggled, this, &Updater::showCurrentVersions); m_showPackageCurrentVersion->setChecked(viewGroup.readEntry("ShowCurrentVersions", false)); // Arch ui->packageView->header()->setSectionHidden(PackageModel::ArchCol, true); m_showPackageArch = new QAction(i18n("Show Architectures"), this); m_showPackageArch->setCheckable(true); - connect(m_showPackageArch, SIGNAL(toggled(bool)), this, SLOT(showArchs(bool))); + connect(m_showPackageArch, &QAction::toggled, this, &Updater::showArchs); m_showPackageArch->setChecked(viewGroup.readEntry("ShowArchs", false)); // Origin ui->packageView->header()->setSectionHidden(PackageModel::OriginCol, true); m_showPackageOrigin = new QAction(i18n("Show Origins"), this); m_showPackageOrigin->setCheckable(true); - connect(m_showPackageOrigin, SIGNAL(toggled(bool)), this, SLOT(showOrigins(bool))); + connect(m_showPackageOrigin, &QAction::toggled, this, &Updater::showOrigins); m_showPackageOrigin->setChecked(viewGroup.readEntry("ShowOrigins", false)); // Sizes ui->packageView->header()->setSectionHidden(PackageModel::SizeCol, true); m_showPackageSize = new QAction(i18n("Show Sizes"), this); m_showPackageSize->setCheckable(true); - connect(m_showPackageSize, SIGNAL(toggled(bool)), this, SLOT(showSizes(bool))); + connect(m_showPackageSize, &QAction::toggled, this, &Updater::showSizes); m_showPackageSize->setChecked(viewGroup.readEntry("ShowSizes", true)); } Updater::~Updater() { delete ui; } void Updater::showVersions(bool enabled) { KConfig config("apper"); KConfigGroup viewGroup(&config, "UpdateView"); viewGroup.writeEntry("ShowVersions", enabled); ui->packageView->header()->setSectionHidden(PackageModel::VersionCol, !enabled); } void Updater::showCurrentVersions(bool enabled) { KConfig config("apper"); KConfigGroup viewGroup(&config, "UpdateView"); viewGroup.writeEntry("ShowCurrentVersions", enabled); ui->packageView->header()->setSectionHidden(PackageModel::CurrentVersionCol, !enabled); if (enabled) { m_updatesModel->fetchCurrentVersions(); } } void Updater::showArchs(bool enabled) { KConfig config("apper"); KConfigGroup viewGroup(&config, "UpdateView"); viewGroup.writeEntry("ShowArchs", enabled); ui->packageView->header()->setSectionHidden(PackageModel::ArchCol, !enabled); } void Updater::showOrigins(bool enabled) { KConfig config("apper"); KConfigGroup viewGroup(&config, "UpdateView"); viewGroup.writeEntry("showOrigins", enabled); ui->packageView->header()->setSectionHidden(PackageModel::OriginCol, !enabled); } void Updater::showSizes(bool enabled) { KConfig config("apper"); KConfigGroup viewGroup(&config, "UpdateView"); viewGroup.writeEntry("ShowSizes", enabled); ui->packageView->header()->setSectionHidden(PackageModel::SizeCol, !enabled); if (enabled) { m_updatesModel->fetchSizes(); } } void Updater::updatePallete() { QPalette pal; pal.setColor(QPalette::Window, pal.base().color()); pal.setColor(QPalette::WindowText, pal.text().color()); ui->backgroundFrame->setPalette(pal); } void Updater::on_packageView_clicked(const QModelIndex &index) { QString pkgId = index.data(PackageModel::IdRole).toString(); - Transaction::Info pkgInfo = index.data(PackageModel::InfoRole).value(); + auto pkgInfo = index.data(PackageModel::InfoRole).value(); ui->updateDetails->setPackage(pkgId, pkgInfo); } //TODO: We should add some kind of configuration to let users show unstable distributions //That way, by default, users only see stable ones. void Updater::distroUpgrade(PackageKit::Transaction::DistroUpgrade type, const QString &name, const QString &description) { // TODO name should be used to do a upgrade to a different type Q_UNUSED(name) if (type != Transaction::DistroUpgradeStable) { // Ignore unstable distros upgrades for now return; } ui->distroUpgrade->setName(description); ui->distroUpgrade->animatedShow(); } bool Updater::hasChanges() const { return m_updatesModel->hasChanges(); } void Updater::checkEnableUpdateButton() { emit changed(hasChanges()); int selectedSize = m_updatesModel->selectedPackagesToInstall().size(); int updatesSize = m_updatesModel->rowCount(); if (selectedSize == 0) { m_header->setCheckState(Qt::Unchecked); } else if (selectedSize == updatesSize) { m_header->setCheckState(Qt::Checked); } else { m_header->setCheckState(Qt::PartiallyChecked); } unsigned long dwSize = m_updatesModel->downloadSize(); if (dwSize) { emit downloadSize(i18n("Estimated download size: %1", KFormat().formatByteSize(dwSize))); } else { emit downloadSize(QString()); } // if we don't have any upates let's disable the button m_header->setCheckBoxVisible(m_updatesModel->rowCount() != 0); ui->packageView->setHeaderHidden(m_updatesModel->rowCount() == 0); } void Updater::load() { // set focus on the updates view ui->packageView->setFocus(Qt::OtherFocusReason); emit downloadSize(QString()); // If the model already has some packages // let's just clear the selection if (m_updatesModel->rowCount()) { m_updatesModel->setAllChecked(false); } else { getUpdates(); } } void Updater::getUpdatesFinished() { m_updatesT = 0; m_updatesModel->clearSelectedNotPresent(); checkEnableUpdateButton(); if (m_updatesModel->rowCount() == 0) { // Set the info page ui->stackedWidget->setCurrentIndex(1); uint lastTime = Daemon::global()->getTimeSinceAction(Transaction::RoleRefreshCache); ui->titleL->setText(PkStrings::lastCacheRefreshTitle(lastTime)); ui->descriptionL->setText(PkStrings::lastCacheRefreshSubTitle(lastTime)); ui->iconL->setPixmap(QIcon::fromTheme(PkIcons::lastCacheRefreshIconName(lastTime)).pixmap(128, 128)); } } QStringList Updater::packagesToUpdate() const { return m_updatesModel->selectedPackagesToInstall(); } void Updater::getUpdates() { if (m_updatesT) { // There is a getUpdates running ignore this call return; } if (ui->stackedWidget->currentIndex() != 0) { ui->stackedWidget->setCurrentIndex(0); } // clears the model ui->packageView->setHeaderHidden(true); m_updatesModel->clear(); ui->updateDetails->hide(); m_updatesT = Daemon::getUpdates(); - connect(m_updatesT, SIGNAL(package(PackageKit::Transaction::Info,QString,QString)), - m_updatesModel, SLOT(addSelectedPackage(PackageKit::Transaction::Info,QString,QString))); - connect(m_updatesT, SIGNAL(errorCode(PackageKit::Transaction::Error,QString)), - this, SLOT(errorCode(PackageKit::Transaction::Error,QString))); - connect(m_updatesT, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), - m_busySeq, SLOT(stop())); - connect(m_updatesT, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), - m_updatesModel, SLOT(finished())); + connect(m_updatesT, &Transaction::package, m_updatesModel, &PackageModel::addSelectedPackage); + connect(m_updatesT, &Transaction::errorCode, this, &Updater::errorCode); + connect(m_updatesT, &Transaction::finished, m_busySeq, &KPixmapSequenceOverlayPainter::stop); + connect(m_updatesT, &Transaction::finished, m_updatesModel, &PackageModel::finished); + // This is required to estimate download size - connect(m_updatesT, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), - m_updatesModel, SLOT(fetchSizes())); + connect(m_updatesT, &Transaction::finished, m_updatesModel, &PackageModel::fetchSizes); + if (m_showPackageCurrentVersion->isChecked()) { - connect(m_updatesT, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), - m_updatesModel, SLOT(fetchCurrentVersions())); + connect(m_updatesT, &Transaction::finished, m_updatesModel, &PackageModel::fetchCurrentVersions); } - connect(m_updatesT, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), - this, SLOT(getUpdatesFinished())); + connect(m_updatesT, &Transaction::finished, this, &Updater::getUpdatesFinished); m_busySeq->start(); // Hide the distribution upgrade information ui->distroUpgrade->animatedHide(); if (m_roles & Transaction::RoleGetDistroUpgrades) { // Check for distribution Upgrades Transaction *t = Daemon::getDistroUpgrades(); - connect(t, SIGNAL(distroUpgrade(PackageKit::Transaction::DistroUpgrade,QString,QString)), - this, SLOT(distroUpgrade(PackageKit::Transaction::DistroUpgrade,QString,QString))); - connect(t, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), - t, SLOT(deleteLater())); + connect(m_updatesT, &Transaction::distroUpgrade, this, &Updater::distroUpgrade); + connect(m_updatesT, &Transaction::finished, t, &Transaction::deleteLater); } } void Updater::on_packageView_customContextMenuRequested(const QPoint &pos) { auto menu = new QMenu(this); menu->addAction(m_showPackageVersion); menu->addAction(m_showPackageCurrentVersion); menu->addAction(m_showPackageArch); menu->addAction(m_showPackageOrigin); menu->addAction(m_showPackageSize); QAction *action; action = menu->addAction(i18n("Check for new updates")); action->setIcon(QIcon::fromTheme("view-refresh")); - connect(action, SIGNAL(triggered(bool)), - this, SIGNAL(refreshCache())); + connect(action, &QAction::triggered, this, &Updater::refreshCache); menu->exec(ui->packageView->viewport()->mapToGlobal(pos)); delete menu; } void Updater::errorCode(PackageKit::Transaction::Error error, const QString &details) { KMessageBox::detailedSorry(this, PkStrings::errorMessage(error), details, PkStrings::error(error), KMessageBox::Notify); } diff --git a/CMakeLists.txt b/CMakeLists.txt index 2cd4ea0..349eef4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,148 +1,148 @@ project(Apper) cmake_minimum_required(VERSION 3.0) set(APPER_VERSION 1.0.0) find_package(ECM REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH}) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/) set(CMAKE_AUTOMOC ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) include(FindPkgConfig) include(KDEInstallDirs) include(KDECompilerSettings) include(KDECMakeSettings) include(FeatureSummary) include(ECMInstallIcons) -find_package(Qt5 5.2.0 CONFIG REQUIRED Core DBus Widgets Quick Sql XmlPatterns) +find_package(Qt5 5.7.0 CONFIG REQUIRED Core DBus Widgets Quick Sql XmlPatterns) # Load the frameworks we need find_package(KF5 REQUIRED COMPONENTS Config DocTools GuiAddons I18n KCMUtils DBusAddons KIO Notifications IconThemes ) find_package(LibKWorkspace REQUIRED) find_package(KDED REQUIRED) find_package(PackageKitQt5 1.0.0 REQUIRED) # # Options # # The various parts of Apper that can be built, or not. option(BUILD_APPER "Build the Apper application" ON) option(BUILD_APPERKCM "Build the Apper KDE Control Module" ON) option(BUILD_APPERD "Build the Apper daemon" ON) option(BUILD_DECLARATIVE "Build the Qt Quick plugins" ON) option(BUILD_PKSESSION "Build the PkSession helper application" ON) option(BUILD_PLASMOID "Build the update notifier plasmoid" ON) # Only for Debian based systems option(DEBCONF_SUPPORT "Build Apper with debconf support" OFF) # Yum does not support this option(AUTOREMOVE "Build Apper with auto remove enabled" OFF) set(HAVE_AUTOREMOVE ${AUTOREMOVE}) message(STATUS "Building Apper with auto remove: " ${AUTOREMOVE}) # AppStream application management support option(APPSTREAM "Build Apper with AppStream support" OFF) set(HAVE_APPSTREAM ${APPSTREAM}) message(STATUS "Building Apper with AppStream support: " ${APPSTREAM}) # Enable support for Limba packages option(LIMBA "Build Apper with Limba bundle support" OFF) set(HAVE_LIMBA ${LIMBA}) message(STATUS "Building Apper with Limba support: " ${LIMBA}) option(MAINTAINER "Enable maintainer mode" OFF) if(DEBCONF_SUPPORT) # Tries to find the package, when it finds it, set HAVE_DEBCONFKDE find_package(DebconfKDE REQUIRED) message(STATUS "Building with Debconf support") set(HAVE_DEBCONF ${DEBCONF_SUPPORT}) endif(DEBCONF_SUPPORT) # command to edit the packages origins set(EDIT_ORIGNS_DESKTOP_NAME "" CACHE STRING "Edit origins desktop name") if (EDIT_ORIGNS_DESKTOP_NAME) message(STATUS "Edit origins desktop name: " ${EDIT_ORIGNS_DESKTOP_NAME}) endif(EDIT_ORIGNS_DESKTOP_NAME) # Generate config.h configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h) # # Add definitions # set(MAINTAINER_CFLAGS "") if(MAINTAINER) set(MAINTAINER_CFLAGS "-Werror -Wall -Wcast-align -Wno-uninitialized -Wempty-body -Wformat-security -Winit-self -Wno-deprecated-declarations") if (CMAKE_COMPILER_IS_GNUCC) execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) if (GCC_VERSION VERSION_GREATER 4.9 OR GCC_VERSION VERSION_EQUAL 4.9) set(MAINTAINER_CFLAGS ${MAINTAINER_CFLAGS} "-fdiagnostics-color=auto") endif() endif() endif(MAINTAINER) add_definitions(${MAINTAINER_CFLAGS}) add_definitions( -DQT_USE_QSTRINGBUILDER -DQT_STRICT_ITERATORS -DQT_NO_URL_CAST_FROM_STRING -DQT_NO_CAST_FROM_BYTEARRAY -DQT_NO_SIGNALS_SLOTS_KEYWORDS -DQT_USE_FAST_OPERATOR_PLUS ) # # Global includes # include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${PackageKitQt5_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/libapper) # # Subcomponents # add_subdirectory(libapper) if(BUILD_APPERKCM) add_subdirectory(ApperKCM) endif(BUILD_APPERKCM) if(BUILD_APPER) add_subdirectory(Apper) endif(BUILD_APPER) if(BUILD_PKSESSION) add_subdirectory(PkSession) endif(BUILD_PKSESSION) if(BUILD_APPERD) add_subdirectory(apperd) endif(BUILD_APPERD) if(BUILD_DECLARATIVE) add_subdirectory(declarative-plugins) endif(BUILD_DECLARATIVE) if(BUILD_PLASMOID) add_subdirectory(plasmoid) endif(BUILD_PLASMOID) if(LIMBA) add_subdirectory(AppSetup) endif() add_subdirectory(doc) feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/PkSession/AbstractIsRunning.cpp b/PkSession/AbstractIsRunning.cpp index 195d652..be1f3cc 100644 --- a/PkSession/AbstractIsRunning.cpp +++ b/PkSession/AbstractIsRunning.cpp @@ -1,58 +1,57 @@ /*************************************************************************** * Copyright (C) 2009-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "AbstractIsRunning.h" #include #include using namespace PackageKit; AbstractIsRunning::AbstractIsRunning(QObject *parent) : - QObject(parent), - m_running(0) + QObject(parent) { } AbstractIsRunning::~AbstractIsRunning() { } void AbstractIsRunning::increaseRunning() { m_running++; // kDebug(); } void AbstractIsRunning::decreaseRunning() { m_running--; // kDebug(); if (!isRunning()) { // kDebug() << "Is not Running anymore"; emit close(); } } bool AbstractIsRunning::isRunning() const { return m_running > 0; } diff --git a/PkSession/AbstractIsRunning.h b/PkSession/AbstractIsRunning.h index 4856909..1eed695 100644 --- a/PkSession/AbstractIsRunning.h +++ b/PkSession/AbstractIsRunning.h @@ -1,48 +1,48 @@ /*************************************************************************** * Copyright (C) 2009-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef ABSTRACT_IS_RUNNING_H #define ABSTRACT_IS_RUNNING_H //#include #include class AbstractIsRunning : public QObject { Q_OBJECT public: explicit AbstractIsRunning(QObject *parent = 0); ~AbstractIsRunning(); bool isRunning() const; Q_SIGNALS: void close(); protected Q_SLOTS: void increaseRunning(); void decreaseRunning(); private: - int m_running; + int m_running = 0; }; #endif diff --git a/PkSession/FilesModel.cpp b/PkSession/FilesModel.cpp index e560e2c..b63e78a 100644 --- a/PkSession/FilesModel.cpp +++ b/PkSession/FilesModel.cpp @@ -1,179 +1,179 @@ /*************************************************************************** * Copyright (C) 2009-2010 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "FilesModel.h" #include #include #include #include #include #include #include #include #include #include Q_DECLARE_LOGGING_CATEGORY(APPER_SESSION) FilesModel::FilesModel(const QStringList &files, const QStringList &mimes, QObject *parent) : QStandardItemModel(parent), m_mimes(mimes) { if (!files.isEmpty()) { QList urls; - foreach (const QString &file, files) { + for (const QString &file : files) { urls << QUrl(file); } insertFiles(urls); } else if (!mimes.isEmpty()) { QMimeDatabase db; // we are searching for mimetypes - foreach (const QString &mimeName, mimes) { + for (const QString &mimeName : mimes) { QMimeType mime = db.mimeTypeForName(mimeName); if (mime.isValid()) { - QStandardItem *item = new QStandardItem(mimeName); + auto item = new QStandardItem(mimeName); item->setData(mimeName); item->setIcon(KIconLoader::global()->loadMimeTypeIcon(mime.iconName(), KIconLoader::Desktop)); appendRow(item); } } } } bool FilesModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) { Q_UNUSED(action) Q_UNUSED(row) Q_UNUSED(column) Q_UNUSED(parent) bool ret = false; if (data->hasUrls()) { ret = insertFiles(data->urls()); } return ret; } bool FilesModel::insertFiles(const QList &urls) { bool ret = false; - foreach (const QUrl &url, urls) { + for (const QUrl &url : urls) { QString path = QUrl::fromPercentEncoding(url.path().toUtf8()); if (files().contains(path)) { continue; } QFileInfo fileInfo(path); QStandardItem *item = 0; if (fileInfo.isFile()) { QMimeDatabase db; QMimeType mime = db.mimeTypeForFile(path, QMimeDatabase::MatchContent); qCDebug(APPER_SESSION) << url << mime.name(); - foreach (const QString &mimeType, m_mimes) { + for (const QString &mimeType : qAsConst(m_mimes)) { if (mime.name() == mimeType) { ret = true; /* kDebug() << "Found Supported Mime" << mimeType << mime->iconName();*/ item = new QStandardItem(fileInfo.fileName()); item->setData(path); item->setToolTip(path); item->setIcon(KIconLoader::global()->loadMimeTypeIcon(mime.iconName(), KIconLoader::Desktop)); break; } } if (ret == false && m_mimes.isEmpty()) { if (mime.name() == "application/x-desktop") { - KService *service = new KService(path); + auto service = new KService(path); item = new QStandardItem(service->name()); item->setData(true, Qt::UserRole); item->setIcon(KIconLoader::global()->loadMimeTypeIcon(service->icon(), KIconLoader::Desktop)); } else { item = new QStandardItem(fileInfo.fileName()); item->setIcon(KIconLoader::global()->loadMimeTypeIcon(mime.iconName(), KIconLoader::Desktop)); } item->setData(path); item->setToolTip(path); } else if (ret == false && !m_mimes.isEmpty()) { item = new QStandardItem(fileInfo.fileName()); item->setData(path); item->setToolTip(path); item->setEnabled(false); item->setIcon(KIconLoader::global()->loadIcon("dialog-cancel", KIconLoader::Desktop)); } } else if (m_mimes.isEmpty()) { // It's not a file but we don't have a mime so it's ok item = new QStandardItem(fileInfo.fileName()); item->setData(path); item->setToolTip(path); item->setIcon(KIconLoader::global()->loadIcon("unknown", KIconLoader::Desktop)); } if (item) { appendRow(item); } } return ret; } QStringList FilesModel::mimeTypes() const { - return QStringList() << "text/uri-list"; + return { QStringLiteral("text/uri-list") }; } Qt::DropActions FilesModel::supportedDropActions() const { return Qt::CopyAction | Qt::MoveAction | Qt::LinkAction; } Qt::ItemFlags FilesModel::flags(const QModelIndex &index) const { Q_UNUSED(index) return Qt::ItemIsEnabled | Qt::ItemIsDropEnabled; } QStringList FilesModel::files() const { QStringList ret; for (int i = 0; i < rowCount(); ++i) { if (item(i)->isEnabled()) { ret << item(i)->data().toString(); } } return ret; } bool FilesModel::onlyApplications() const { for (int i = 0; i < rowCount(); ++i) { // UserRole is true if it is an application if (item(i)->isEnabled() == true && item(i)->data(Qt::UserRole).toBool() == false) { return false; // there is something that is not an app } } return true; } #include "FilesModel.moc" diff --git a/PkSession/IntroDialog.cpp b/PkSession/IntroDialog.cpp index 8c9bca8..36dc9ce 100644 --- a/PkSession/IntroDialog.cpp +++ b/PkSession/IntroDialog.cpp @@ -1,81 +1,80 @@ /*************************************************************************** * Copyright (C) 2008-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "IntroDialog.h" #include "ui_IntroDialog.h" #include #include #include #include #include #include #include #include #include "FilesModel.h" IntroDialog::IntroDialog(QWidget *parent) : QWidget(parent), ui(new Ui::IntroDialog) { ui->setupUi(this); } IntroDialog::~IntroDialog() { delete ui; } void IntroDialog::setModel(QAbstractItemModel *model) { ui->listView->setModel(model); - connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), - this, SLOT(selectionChanged())); + connect(model, &QAbstractItemModel::dataChanged, this, &IntroDialog::selectionChanged); } void IntroDialog::acceptDrops(const QString &toolTip) { ui->listView->setDragDropMode(QListView::DropOnly); ui->listView->setToolTip(toolTip); } bool IntroDialog::canContinue() const { return ui->listView->model()->rowCount(); } void IntroDialog::selectionChanged() { // if the model has more than one item it can continue emit continueChanged(canContinue()); } void IntroDialog::setDescription(const QString &description) { ui->descriptionL->setText(description); } #include "IntroDialog.moc" diff --git a/PkSession/PkInstallCatalogs.cpp b/PkSession/PkInstallCatalogs.cpp index 721b7f6..4ceeef1 100644 --- a/PkSession/PkInstallCatalogs.cpp +++ b/PkSession/PkInstallCatalogs.cpp @@ -1,281 +1,273 @@ /*************************************************************************** * Copyright (C) 2009-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "PkInstallCatalogs.h" #include "IntroDialog.h" #include "FilesModel.h" #include #include #include #include #include #include Q_DECLARE_LOGGING_CATEGORY(APPER_SESSION) PkInstallCatalogs::PkInstallCatalogs(uint xid, const QStringList &files, const QString &interaction, const QDBusMessage &message, QWidget *parent) : SessionTask(xid, interaction, message, parent), m_interaction(interaction), - m_message(message), - m_maxResolve(100) + m_message(message) { setWindowTitle(i18n("Install Packages Catalogs")); // Find out how many packages PackageKit is able to resolve QFile file("/etc/PackageKit/PackageKit.conf"); QRegExp rx("\\s*MaximumItemsToResolve=(\\d+)", Qt::CaseSensitive); if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { QTextStream in(&file); while (!in.atEnd()) { if (rx.indexIn(in.readLine()) != -1) { m_maxResolve = rx.capturedTexts()[1].toInt(); break; } } } QStringList mimes; mimes << "application/x-catalog"; mimes << "text/plain"; m_introDialog = new IntroDialog(this); m_introDialog->acceptDrops(i18n("You can drop more catalogs in here")); m_model = new FilesModel(files, mimes, this); - connect(m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), - this, SLOT(modelChanged())); + connect(m_model, &FilesModel::rowsInserted, this, &PkInstallCatalogs::modelChanged); m_introDialog->setModel(m_model); setMainWidget(m_introDialog); modelChanged(); } PkInstallCatalogs::~PkInstallCatalogs() { } void PkInstallCatalogs::modelChanged() { QStringList files = m_model->files(); enableButtonOk(!files.isEmpty()); QString description; if (files.isEmpty()) { description = i18n("No supported catalog was found"); } else { description = i18np("Do you want to install this catalog?", "Do you want to install these catalogs?", files.size()); } m_introDialog->setDescription(description); QString title; // this will come from DBus interface if (parentTitle.isNull()) { title = i18np("An application wants to install a catalog", "An application wants to install catalogs", files.size()); } else { title = i18np("The application %2 wants to install a catalog", "The application %2 wants to install catalogs", files.size(), parentTitle); } setTitle(title); } void PkInstallCatalogs::search() { QString distroId = Daemon::global()->distroID(); QStringList parts = distroId.split(';'); if (parts.size() != 3) { sendErrorFinished(Failed, "invalid distribution id, please fill a bug against you distribution backend"); return; } QString distro = parts.at(0); QString version = parts.at(1); QString arch = parts.at(2); QStringList rxActions; Transaction::Roles roles = Daemon::global()->roles(); if (roles & Transaction::RoleResolve) { rxActions << "InstallPackages"; } if (roles & Transaction::RoleWhatProvides) { rxActions << "InstallProvides"; } if (roles & Transaction::RoleSearchFile) { rxActions << "InstallFiles"; } if (rxActions.isEmpty()) { if (showWarning()) { // TODO display a nicer message informing of already installed ones setInfo(i18n("Not supported"), i18n("Your backend does not support any of the needed " "methods to install a catalog")); } sendErrorFinished(Failed, "not supported by backend"); return; } // matches at the beginning of line installPackages or InstallProvides or installFiles and capture it // matches an optional set of parenthesis // matches *%1* and or *%2* and or *%3* // matches after '=' but ';' at the end QString pattern; pattern = QString( "^(%1)(?:\\((?:.*%2[^;]*(?:;(?:.*%3[^;]*(?:;(?:.*%4[^;]*)?)?)?)?)?\\))?=(.*[^;$])").arg(rxActions.join("|")).arg(distro).arg(version).arg(arch); QRegExp rx(pattern, Qt::CaseInsensitive); QStringList filesFailedToOpen; - QStringList files = m_model->files(); + const QStringList files = m_model->files(); if (!files.isEmpty()) { - foreach (const QString &file, files) { + for (const QString &file : files) { QFile catalog(file); if (catalog.open(QIODevice::ReadOnly | QIODevice::Text)) { QTextStream in(&catalog); while (!in.atEnd()) { if (rx.indexIn(in.readLine()) != -1) { - if (rx.cap(1).compare("InstallPackages", Qt::CaseInsensitive) == 0) { + if (rx.cap(1).compare(QLatin1String("InstallPackages"), Qt::CaseInsensitive) == 0) { m_installPackages.append(rx.cap(2).split(';')); - } else if (rx.cap(1).compare("InstallProvides", Qt::CaseInsensitive) == 0) { + } else if (rx.cap(1).compare(QLatin1String("InstallProvides"), Qt::CaseInsensitive) == 0) { m_installProvides.append(rx.cap(2).split(';')); - } else if (rx.cap(1).compare("InstallFiles", Qt::CaseInsensitive) == 0) { - m_installFiles.append(rx.cap(2).split(';')); + } else if (rx.cap(1).compare(QLatin1String("InstallFiles"), Qt::CaseInsensitive) == 0) { + m_installFiles.append(rx.cap(2).split(QLatin1Char(';'))); } } } } else { filesFailedToOpen << file; } } } else { setInfo(i18n("Catalog not found"), i18n("Could not find a catalog to install")); return; } if (showWarning() && filesFailedToOpen.size()) { // TODO display a nicer message informing of already installed ones KMessageBox::sorry(this, i18np("Catalog %2 failed to open", "Catalogs %2 failed to open", filesFailedToOpen.size(), filesFailedToOpen.join(",")), i18n("Failed to open")); } if (m_installPackages.isEmpty() && m_installProvides.isEmpty() && m_installFiles.isEmpty()) { setInfo(i18n("Catalog is Empty"), i18n("Could not find any package to install in this catalog")); } else { // Start resolving searchFinished(PkTransaction::Success); } } void PkInstallCatalogs::searchFinished(PkTransaction::ExitStatus status) { if (status == PkTransaction::Success) { if (!m_installPackages.isEmpty()) { // Continue resolving Install Packages QStringList resolve; int count = 0; while (!m_installPackages.isEmpty() && count < m_maxResolve) { // Remove the items from the list so next call we have less resolve.append(m_installPackages.takeFirst()); ++count; } qCDebug(APPER_SESSION) << "m_installPackages" << m_maxResolve << m_installPackages.size() << resolve.size(); - PkTransaction *transaction = new PkTransaction(this); + auto transaction = new PkTransaction(this); Transaction *t; t = Daemon::resolve(resolve, Transaction::FilterNotInstalled | Transaction::FilterArch | Transaction::FilterNewest); transaction->setupTransaction(t); setTransaction(Transaction::RoleResolve, transaction); - connect(transaction, SIGNAL(finished(PkTransaction::ExitStatus)), - this, SLOT(searchFinished(PkTransaction::ExitStatus)), Qt::UniqueConnection); - connect(transaction, SIGNAL(package(PackageKit::Transaction::Info,QString,QString)), - this, SLOT(addPackage(PackageKit::Transaction::Info,QString,QString))); + connect(transaction, &PkTransaction::finished, this, &PkInstallCatalogs::searchFinished, Qt::UniqueConnection); + connect(transaction, &PkTransaction::package, this, &PkInstallCatalogs::addPackage); } else if (!m_installProvides.isEmpty()) { // Continue resolving Install Provides QStringList provides; int count = 0; while (!m_installProvides.isEmpty() && count < m_maxResolve) { // Remove the items from the list so next call we have less provides.append(m_installProvides.takeFirst()); ++count; } qCDebug(APPER_SESSION) << "m_installProvides" << m_maxResolve << m_installProvides.size() << provides.size(); - PkTransaction *transaction = new PkTransaction(this); + auto transaction = new PkTransaction(this); Transaction *t; t = Daemon::whatProvides(provides, Transaction::FilterNotInstalled | Transaction::FilterArch | Transaction::FilterNewest); transaction->setupTransaction(t); setTransaction(Transaction::RoleWhatProvides, transaction); - connect(transaction, SIGNAL(finished(PkTransaction::ExitStatus)), - this, SLOT(searchFinished(PkTransaction::ExitStatus)), Qt::UniqueConnection); - connect(transaction, SIGNAL(package(PackageKit::Transaction::Info,QString,QString)), - this, SLOT(addPackage(PackageKit::Transaction::Info,QString,QString))); + connect(transaction, &PkTransaction::finished, this, &PkInstallCatalogs::searchFinished, Qt::UniqueConnection); + connect(transaction, &PkTransaction::package, this, &PkInstallCatalogs::addPackage); } else if (!m_installFiles.isEmpty()) { // Continue resolving Install Packages QStringList files; int count = 0; while (!m_installFiles.isEmpty() && count < m_maxResolve) { // Remove the items from the list so next call we have less files.append(m_installFiles.takeFirst()); ++count; } qCDebug(APPER_SESSION) << "m_installFiles" << m_maxResolve << m_installFiles.size() << files.size(); - PkTransaction *transaction = new PkTransaction(this); + auto transaction = new PkTransaction(this); Transaction *t; t = Daemon::searchFiles(files, Transaction::FilterNotInstalled | Transaction::FilterArch | Transaction::FilterNewest); transaction->setupTransaction(t); setTransaction(Transaction::RoleSearchFile, transaction); - connect(transaction, SIGNAL(finished(PkTransaction::ExitStatus)), - this, SLOT(searchFinished(PkTransaction::ExitStatus)), Qt::UniqueConnection); - connect(transaction, SIGNAL(package(PackageKit::Transaction::Info,QString,QString)), - this, SLOT(addPackage(PackageKit::Transaction::Info,QString,QString))); + connect(transaction, &PkTransaction::finished, this, &PkInstallCatalogs::searchFinished, Qt::UniqueConnection); + connect(transaction, &PkTransaction::package, this, &PkInstallCatalogs::addPackage); } else { // we are done resolving SessionTask::searchFinished(status); } } else { // we got an error... SessionTask::searchFinished(status); } } #include "PkInstallCatalogs.moc" diff --git a/PkSession/PkInstallCatalogs.h b/PkSession/PkInstallCatalogs.h index 805f793..e5cecae 100644 --- a/PkSession/PkInstallCatalogs.h +++ b/PkSession/PkInstallCatalogs.h @@ -1,60 +1,60 @@ /*************************************************************************** * Copyright (C) 2009-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef PK_INSTALL_CATALOGS_H #define PK_INSTALL_CATALOGS_H #include "SessionTask.h" class IntroDialog; class FilesModel; class PkInstallCatalogs : public SessionTask { Q_OBJECT public: PkInstallCatalogs(uint xid, const QStringList &files, const QString &interaction, const QDBusMessage &message, QWidget *parent = 0); ~PkInstallCatalogs(); protected: virtual void search(); protected Q_SLOTS: virtual void searchFinished(PkTransaction::ExitStatus status); private Q_SLOTS: void modelChanged(); private: QStringList m_installPackages; QStringList m_installProvides; QStringList m_installFiles; QString m_interaction; QDBusMessage m_message; QStringList m_alreadyInstalled; - int m_maxResolve; + int m_maxResolve = 100; IntroDialog *m_introDialog; FilesModel *m_model; }; #endif diff --git a/PkSession/PkInstallFontconfigResources.cpp b/PkSession/PkInstallFontconfigResources.cpp index 4848bdb..acd1cce 100644 --- a/PkSession/PkInstallFontconfigResources.cpp +++ b/PkSession/PkInstallFontconfigResources.cpp @@ -1,167 +1,164 @@ /*************************************************************************** * Copyright (C) 2009-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "PkInstallFontconfigResources.h" #include "IntroDialog.h" #include #include #include #include #include #include #include Q_DECLARE_LOGGING_CATEGORY(APPER_SESSION) PkInstallFontconfigResources::PkInstallFontconfigResources(uint xid, const QStringList &resources, const QString &interaction, const QDBusMessage &message, QWidget *parent) : SessionTask(xid, interaction, message, parent) { setWindowTitle(i18n("Installs new Fonts")); - IntroDialog *introDialog = new IntroDialog(this); - QStandardItemModel *model = new QStandardItemModel(this); + auto introDialog = new IntroDialog(this); + auto model = new QStandardItemModel(this); introDialog->setModel(model); - connect(introDialog, SIGNAL(continueChanged(bool)), - this, SLOT(enableButtonOk(bool))); + connect(introDialog, &IntroDialog::continueChanged, this, &PkInstallFontconfigResources::enableButtonOk); setMainWidget(introDialog); // This will only validate fields QStringList errors; QStringList iso639; - foreach (const QString &font, resources) { + for (const QString &font : resources) { // TODO never return in here // TODO add name field from /usr/share/xml/iso-codes/iso_639.xml into model if (!font.startsWith(QLatin1String(":lang="))) { errors << QString("not recognised prefix: '%1'").arg(font); qCWarning(APPER_SESSION) << QString("not recognised prefix: '%1'").arg(font); continue; } int size = font.size(); if (size < 7 || size > 20) { errors << QString("lang tag malformed: '%1'").arg(font); qCWarning(APPER_SESSION) << QString("lang tag malformed: '%1'").arg(font); continue; } m_resources << font; iso639 << font.mid(6); } if (m_resources.isEmpty()) { setError(i18n("Could interpret request"), i18n("Please verify if the request was valid")); sendErrorFinished(InternalError, errors.join("\n")); return; } enableButtonOk(true); // Search for the iso 639 names to present it nicely to the user QStringList niceNames; QFile file("/usr/share/xml/iso-codes/iso_639.xml"); file.open(QFile::ReadOnly); QXmlQuery query; query.bindVariable("path", &file); - foreach (const QString &font, iso639) { + for (const QString &font : iso639) { QString queryTxt; queryTxt = QString("declare variable $path external;" "doc($path)/iso_639_entries/" "iso_639_entry[@iso_639_2B_code=\"%1\" or " "@iso_639_2T_code=\"%1\" or " "@iso_639_1_code=\"%1\"]/string(@name)").arg(font); query.setQuery(queryTxt); QStringList result; query.evaluateTo(&result); niceNames.append(result); } // kDebug() << "result" << niceNames << iso639; - foreach (const QString &name, niceNames) { - QStandardItem *item = new QStandardItem(name); + for (const QString &name : niceNames) { + auto item = new QStandardItem(name); item->setIcon(QIcon::fromTheme("fonts-package").pixmap(32, 32)); item->setFlags(Qt::ItemIsEnabled); model->appendRow(item); } QString description; description = i18np("An additional font is required to view this document correctly.\n" "Do you want to search for a suitable package now?", "Additional fonts are required to view this document correctly.\n" "Do you want to search for suitable packages now?", m_resources.size()); introDialog->setDescription(description); QString title; // this will come from DBus interface if (parentTitle.isNull()) { title = i18np("A program wants to install a font", "A program wants to install fonts", m_resources.size()); } else { title = i18np("The application %2 wants to install a font", "The application %2 wants to install fonts", m_resources.size(), parentTitle); } setTitle(title); } PkInstallFontconfigResources::~PkInstallFontconfigResources() { } void PkInstallFontconfigResources::search() { - PkTransaction *transaction = new PkTransaction(this); + auto transaction = new PkTransaction(this); Transaction *t; t = Daemon::whatProvides(m_resources, Transaction::FilterNotInstalled | Transaction::FilterArch | Transaction::FilterNewest); transaction->setupTransaction(t); setTransaction(Transaction::RoleWhatProvides, transaction); - connect(transaction, SIGNAL(finished(PkTransaction::ExitStatus)), - this, SLOT(searchFinished(PkTransaction::ExitStatus)), Qt::UniqueConnection); - connect(transaction, SIGNAL(package(PackageKit::Transaction::Info,QString,QString)), - this, SLOT(addPackage(PackageKit::Transaction::Info,QString,QString))); + connect(transaction, &PkTransaction::finished, this, &PkInstallFontconfigResources::searchFinished, Qt::UniqueConnection); + connect(transaction, &PkTransaction::package, this, &PkInstallFontconfigResources::addPackage); } void PkInstallFontconfigResources::notFound() { QString msg = i18n("Failed to find font"); if (showWarning()) { setInfo(msg, i18n("No new fonts could be found for this document")); } sendErrorFinished(NoPackagesFound, msg); } void PkInstallFontconfigResources::searchFailed() { QString msg = i18n("Failed to find font"); if (showWarning()) { setError(msg, i18n("Failed to search for provides")); } sendErrorFinished(Failed, "failed to search for provides"); } #include "PkInstallFontconfigResources.moc" diff --git a/PkSession/PkInstallGStreamerResources.cpp b/PkSession/PkInstallGStreamerResources.cpp index 31678c7..5cabafc 100644 --- a/PkSession/PkInstallGStreamerResources.cpp +++ b/PkSession/PkInstallGStreamerResources.cpp @@ -1,150 +1,147 @@ /*************************************************************************** * Copyright (C) 2009-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "PkInstallGStreamerResources.h" #include "IntroDialog.h" #include #include #include #include #include PkInstallGStreamerResources::PkInstallGStreamerResources(uint xid, const QStringList &resources, const QString &interaction, const QDBusMessage &message, QWidget *parent) : SessionTask(xid, interaction, message, parent) { setWindowTitle(i18n("Install GStreamer Resources")); - IntroDialog *introDialog = new IntroDialog(this); - QStandardItemModel *model = new QStandardItemModel(this); + auto introDialog = new IntroDialog(this); + auto model = new QStandardItemModel(this); introDialog->setModel(model); - connect(introDialog, SIGNAL(continueChanged(bool)), - this, SLOT(enableButtonOk(bool))); + connect(introDialog, &IntroDialog::continueChanged, this, &PkInstallGStreamerResources::enableButtonOk); setMainWidget(introDialog); bool encoder = false; bool decoder = false; // Resources are strings like "ID3 tag|gstreamer0.10(decoder-application/x-id3)()(64bit)" - foreach (const QString &codec, resources) { + for (const QString &codec : resources) { if (codec.contains("|gstreamer0.10(decoder")) { decoder = true; } else if (codec.contains("|gstreamer0.10(encoder")) { encoder = true; } - QStandardItem *item = new QStandardItem(codec.section('|', 0, 0)); + auto item = new QStandardItem(codec.section('|', 0, 0)); item->setIcon(QIcon::fromTheme("x-kde-nsplugin-generated").pixmap(32, 32)); item->setFlags(Qt::ItemIsEnabled); model->appendRow(item); m_resources << codec.section('|', 1, -1); } QString description; description = i18np("The following plugin is required. " "Do you want to search for this now?", "The following plugins are required. " "Do you want to search for these now?", m_resources.size()); enableButtonOk(true); QString title; // this will come from DBus interface if (parentTitle.isNull()) { if (decoder && !encoder) { // TRANSLATORS: a random program which we can't get the name wants to decode something title = i18np("A program requires an additional plugin to decode this file", "A program requires additional plugins to decode this file", m_resources.size()); } else if (!decoder && encoder) { // TRANSLATORS: a random program which we can't get the name wants to encode something title = i18np("A program requires an additional plugin to encode this file", "A program requires additional plugins to encode this file", m_resources.size()); } else { // TRANSLATORS: a random program which we can't get the name wants to do something (unknown) title = i18np("A program requires an additional plugin for this operation", "A program requires additional plugins for this operation", m_resources.size()); } } else { if (decoder && !encoder) { // TRANSLATORS: a program wants to decode something (unknown) -- string is a program name, e.g. "Movie Player" title = i18np("%2 requires an additional plugin to decode this file", "%2 requires additional plugins to decode this file", m_resources.size(), parentTitle); } else if (!decoder && encoder) { // TRANSLATORS: a program wants to encode something (unknown) -- string is a program name, e.g. "Movie Player" title = i18np("%2 requires an additional plugin to encode this file", "%2 requires additional plugins to encode this file", m_resources.size(), parentTitle); } else { // TRANSLATORS: a program wants to do something (unknown) -- string is a program name, e.g. "Movie Player" title = i18np("%2 requires an additional plugin for this operation", "%2 requires additional plugins for this operation", m_resources.size(), parentTitle); } } introDialog->setDescription(description); setTitle(title); } PkInstallGStreamerResources::~PkInstallGStreamerResources() { } void PkInstallGStreamerResources::search() { - PkTransaction *transaction = new PkTransaction(this); + auto transaction = new PkTransaction(this); Transaction *t; t = Daemon::whatProvides(m_resources, Transaction::FilterNotInstalled | Transaction::FilterArch | Transaction::FilterNewest); transaction->setupTransaction(t); setTransaction(Transaction::RoleWhatProvides, transaction); - connect(transaction, SIGNAL(finished(PkTransaction::ExitStatus)), - this, SLOT(searchFinished(PkTransaction::ExitStatus)), Qt::UniqueConnection); - connect(transaction, SIGNAL(package(PackageKit::Transaction::Info,QString,QString)), - this, SLOT(addPackage(PackageKit::Transaction::Info,QString,QString))); + connect(transaction, &PkTransaction::finished, this, &PkInstallGStreamerResources::searchFinished, Qt::UniqueConnection); + connect(transaction, &PkTransaction::package, this, &PkInstallGStreamerResources::addPackage); } void PkInstallGStreamerResources::notFound() { if (showWarning()) { QString mgs = i18n("No results found"); setInfo(mgs, i18n("Could not find plugin " "in any configured software source")); } sendErrorFinished(NoPackagesFound, "failed to find codec"); } #include "PkInstallGStreamerResources.moc" diff --git a/PkSession/PkInstallMimeTypes.cpp b/PkSession/PkInstallMimeTypes.cpp index 2da13b1..b7787d2 100644 --- a/PkSession/PkInstallMimeTypes.cpp +++ b/PkSession/PkInstallMimeTypes.cpp @@ -1,109 +1,106 @@ /*************************************************************************** * Copyright (C) 2009-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "PkInstallMimeTypes.h" #include "IntroDialog.h" #include "FilesModel.h" #include #include #include #include PkInstallMimeTypes::PkInstallMimeTypes(uint xid, const QStringList &mime_types, const QString &interaction, const QDBusMessage &message, QWidget *parent) : SessionTask(xid, interaction, message, parent), m_mimeTypes(mime_types) { setWindowTitle(i18n("Install Support for File Types")); - IntroDialog *introDialog = new IntroDialog(this); + auto introDialog = new IntroDialog(this); m_model = new FilesModel(QStringList(), mime_types, this); introDialog->setModel(m_model); - connect(introDialog, SIGNAL(continueChanged(bool)), - this, SLOT(enableButtonOk(bool))); + connect(introDialog, &IntroDialog::continueChanged, this, &PkInstallMimeTypes::enableButtonOk); setMainWidget(introDialog); QString description; if (m_model->rowCount()) { description = i18np("Do you want to search for a program that can open this file type?", "Do you want to search for a program that can open these file types?", m_model->rowCount()); enableButtonOk(true); } else { description = i18n("No valid file types were provided"); } introDialog->setDescription(description); QString title; // this will come from DBus interface if (parentTitle.isNull()) { title = i18np("A program is requiring support to open this kind of files", "A program is requiring support to open these kinds of files", m_model->rowCount()); } else { title = i18np("The application %2 is requiring support to open this kind of files", "The application %2 is requiring support to open these kinds of files", m_model->rowCount(), parentTitle); } setTitle(title); } PkInstallMimeTypes::~PkInstallMimeTypes() { } void PkInstallMimeTypes::search() { QStringList mimeTypes = m_model->files(); - PkTransaction *transaction = new PkTransaction(this); + auto transaction = new PkTransaction(this); Transaction *t; t = Daemon::whatProvides(mimeTypes, Transaction::FilterNotInstalled | Transaction::FilterArch | Transaction::FilterNewest); transaction->setupTransaction(t); setTransaction(Transaction::RoleWhatProvides, transaction); - connect(transaction, SIGNAL(finished(PkTransaction::ExitStatus)), - this, SLOT(searchFinished(PkTransaction::ExitStatus)), Qt::UniqueConnection); - connect(transaction, SIGNAL(package(PackageKit::Transaction::Info,QString,QString)), - this, SLOT(addPackage(PackageKit::Transaction::Info,QString,QString))); + connect(transaction, &PkTransaction::finished, this, &PkInstallMimeTypes::searchFinished, Qt::UniqueConnection); + connect(transaction, &PkTransaction::package, this, &PkInstallMimeTypes::addPackage); } void PkInstallMimeTypes::notFound() { QString msg = i18n("Could not find software"); if (showWarning()) { setInfo(msg, i18n("No new applications can be found " "to handle this type of file")); } sendErrorFinished(NoPackagesFound, "nothing was found to handle mime type"); } //setTitle(i18np("Application that can open this type of file", // "Applications that can open this type of file", // m_foundPackages.size())); #include "PkInstallMimeTypes.moc" diff --git a/PkSession/PkInstallPackageFiles.cpp b/PkSession/PkInstallPackageFiles.cpp index 8bc5901..5022e9a 100644 --- a/PkSession/PkInstallPackageFiles.cpp +++ b/PkSession/PkInstallPackageFiles.cpp @@ -1,128 +1,126 @@ /*************************************************************************** * Copyright (C) 2008-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "PkInstallPackageFiles.h" #include "IntroDialog.h" #include "FilesModel.h" #include #include #include Q_DECLARE_LOGGING_CATEGORY(APPER_SESSION) PkInstallPackageFiles::PkInstallPackageFiles(uint xid, const QStringList &files, const QString &interaction, const QDBusMessage &message, QWidget *parent) : SessionTask(xid, interaction, message, parent) { setWindowTitle(i18n("Install Packages Files")); // if (Daemon::global()->roles() & Transaction::RoleInstallFiles) { m_introDialog = new IntroDialog(this); m_introDialog->acceptDrops(i18n("You can drop more files in here")); m_model = new FilesModel(files, Daemon::global()->mimeTypes(), this); m_introDialog->setModel(m_model); - connect(m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), - this, SLOT(modelChanged())); + connect(m_model, &FilesModel::rowsInserted, this, &PkInstallPackageFiles::modelChanged); setMainWidget(m_introDialog); modelChanged(); // } else { // setError(i18n("Not Supported"), // i18n("Your current backend does not support installing files")); // } } PkInstallPackageFiles::~PkInstallPackageFiles() { } void PkInstallPackageFiles::modelChanged() { QStringList files = m_model->files(); enableButtonOk(!files.isEmpty()); QString description; if (files.isEmpty()) { description = i18n("No supported files were provided"); } else { description = i18np("Press Continue if you want to install this file", "Press Continue if you want to install these files", files.size()); } m_introDialog->setDescription(description); QString title; // this will come from DBus interface if (parentTitle.isNull()) { title = i18np("An application wants to install a package", "An application wants to install packages", files.size()); } else { title = i18np("The application %2 wants to install a package", "The application %2 wants to install packages", files.size(), parentTitle); } setTitle(title); } void PkInstallPackageFiles::commit() { - PkTransaction *transaction = new PkTransaction(this); + auto transaction = new PkTransaction(this); setTransaction(Transaction::RoleInstallFiles, transaction); - connect(transaction, SIGNAL(finished(PkTransaction::ExitStatus)), - this, SLOT(transactionFinished(PkTransaction::ExitStatus)), Qt::UniqueConnection); + connect(transaction, &PkTransaction::finished, this, &PkInstallPackageFiles::transactionFinished, Qt::UniqueConnection); transaction->installFiles(m_model->files()); } void PkInstallPackageFiles::transactionFinished(PkTransaction::ExitStatus status) { qCDebug(APPER_SESSION) << "Finished."; switch (status) { case PkTransaction::Success : if (showFinished()) { setFinish(i18n("Installation Complete"), i18np("File was installed successfully", "Files were installed successfully", m_model->files().count())); } finishTaskOk(); break; case PkTransaction::Cancelled : sendErrorFinished(Cancelled, "Aborted"); break; case PkTransaction::Failed : if (showWarning()) { setError(i18n("Failed to install files"), i18n("Could not install files")); } sendErrorFinished(Failed, i18n("Could not install files")); break; } } #include "PkInstallPackageFiles.moc" diff --git a/PkSession/PkInstallPackageNames.cpp b/PkSession/PkInstallPackageNames.cpp index d39ac14..78b3c59 100644 --- a/PkSession/PkInstallPackageNames.cpp +++ b/PkSession/PkInstallPackageNames.cpp @@ -1,136 +1,133 @@ /*************************************************************************** * Copyright (C) 2009-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "PkInstallPackageNames.h" #include #include #include #include #include #include "IntroDialog.h" PkInstallPackageNames::PkInstallPackageNames(uint xid, const QStringList &packages, const QString &interaction, const QDBusMessage &message, QWidget *parent) : SessionTask(xid, interaction, message, parent), m_packages(packages), m_message(message) { setWindowTitle(i18n("Install Packages by Name")); - IntroDialog *introDialog = new IntroDialog(this); - QStandardItemModel *model = new QStandardItemModel(this); + auto introDialog = new IntroDialog(this); + auto model = new QStandardItemModel(this); introDialog->setModel(model); - connect(introDialog, SIGNAL(continueChanged(bool)), - this, SLOT(enableButtonOk(bool))); + connect(introDialog, &IntroDialog::continueChanged, this, &PkInstallPackageNames::enableButtonOk); setMainWidget(introDialog); - foreach (const QString &package, packages) { + for (const QString &package : packages) { QStandardItem *item = new QStandardItem(package); item->setIcon(QIcon::fromTheme("package-x-generic").pixmap(32, 32)); item->setFlags(Qt::ItemIsEnabled); model->appendRow(item); } if (m_packages.isEmpty()) { introDialog->setDescription(i18n("No package names were provided")); } else { QString description; description = i18np("Do you want to search for and install this package now?", "Do you want to search for and install these packages now?", m_packages.size()); introDialog->setDescription(description); enableButtonOk(true); } QString title; // this will come from DBus interface if (parentTitle.isNull()) { title = i18np("An application wants to install a package", "An application wants to install packages", m_packages.size()); } else { title = i18np("The application %2 wants to install a package", "The application %2 wants to install packages", m_packages.size(), parentTitle); } setTitle(title); } PkInstallPackageNames::~PkInstallPackageNames() { } void PkInstallPackageNames::search() { - PkTransaction *transaction = new PkTransaction(this); + auto transaction = new PkTransaction(this); transaction->setupTransaction(Daemon::resolve(m_packages, Transaction::FilterArch | Transaction::FilterNewest)); setTransaction(Transaction::RoleResolve, transaction); - connect(transaction, SIGNAL(finished(PkTransaction::ExitStatus)), - this, SLOT(searchFinished(PkTransaction::ExitStatus)), Qt::UniqueConnection); - connect(transaction, SIGNAL(package(PackageKit::Transaction::Info,QString,QString)), - this, SLOT(addPackage(PackageKit::Transaction::Info,QString,QString))); + connect(transaction, &PkTransaction::finished, this, &PkInstallPackageNames::searchFinished, Qt::UniqueConnection); + connect(transaction, &PkTransaction::package, this, &PkInstallPackageNames::addPackage); } void PkInstallPackageNames::notFound() { if (m_alreadyInstalled.size()) { if (showWarning()) { setInfo(i18n("Failed to install packages"), i18np("The package %2 is already installed", "The packages %2 are already installed", m_alreadyInstalled.size(), m_alreadyInstalled.join(","))); } sendErrorFinished(Failed, "package already found"); } else { if (showWarning()) { setInfo(i18n("Could not find %1", m_packages.join(", ")), i18np("The package could not be found in any software source", "The packages could not be found in any software source", m_packages.size())); } sendErrorFinished(NoPackagesFound, "no package found"); } } void PkInstallPackageNames::searchFailed() { sendErrorFinished(Failed, "failed to resolve package name"); } void PkInstallPackageNames::addPackage(Transaction::Info info, const QString &packageID, const QString &summary) { if (info != Transaction::InfoInstalled) { SessionTask::addPackage(info, packageID, summary); } else { m_alreadyInstalled << Transaction::packageName(packageID); } } #include "PkInstallPackageNames.moc" diff --git a/PkSession/PkInstallPlasmaResources.cpp b/PkSession/PkInstallPlasmaResources.cpp index 2cd1cc4..a5af7cb 100644 --- a/PkSession/PkInstallPlasmaResources.cpp +++ b/PkSession/PkInstallPlasmaResources.cpp @@ -1,115 +1,112 @@ /*************************************************************************** * Copyright (C) 2009-2011 by Daniel Nicoletti * * dantti12@gmail.com * * Copyright (C) 2011 Kevin Kofler * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "PkInstallPlasmaResources.h" #include "IntroDialog.h" #include #include #include #include #include PkInstallPlasmaResources::PkInstallPlasmaResources(uint xid, const QStringList &resources, const QString &interaction, const QDBusMessage &message, QWidget *parent) : SessionTask(xid, interaction, message, parent) { setWindowTitle(i18n("Install Plasma Resources")); - IntroDialog *introDialog = new IntroDialog(this); - QStandardItemModel *model = new QStandardItemModel(this); + auto introDialog = new IntroDialog(this); + auto model = new QStandardItemModel(this); introDialog->setModel(model); - connect(introDialog, SIGNAL(continueChanged(bool)), - this, SLOT(enableButtonOk(bool))); + connect(introDialog, &IntroDialog::continueChanged, this, &PkInstallPlasmaResources::enableButtonOk); setMainWidget(introDialog); // Resources are strings like "dataengine-weather" - foreach (const QString &service, resources) { + for (const QString &service : resources) { QString prettyService = service; if (service.startsWith(QLatin1String("dataengine-"))) { prettyService = i18n("%1 data engine", service.mid(11)); } else if (service.startsWith(QLatin1String("scriptengine-"))) { prettyService = i18n("%1 script engine", service.mid(13)); } - QStandardItem *item = new QStandardItem(prettyService); + auto item = new QStandardItem(prettyService); item->setIcon(QIcon::fromTheme("application-x-plasma").pixmap(32, 32)); item->setFlags(Qt::ItemIsEnabled); model->appendRow(item); m_resources << service; } if (m_resources.isEmpty()) { introDialog->setDescription(i18n("No supported resources were provided")); } else { QString description = i18np("The following service is required. " "Do you want to search for this now?", "The following services are required. " "Do you want to search for these now?", m_resources.size()); introDialog->setDescription(description); enableButtonOk(true); } QString title = i18np("Plasma requires an additional service for this operation", "Plasma requires additional services for this operation", m_resources.size()); setTitle(title); } PkInstallPlasmaResources::~PkInstallPlasmaResources() { } void PkInstallPlasmaResources::search() { - PkTransaction *transaction = new PkTransaction(this); + auto transaction = new PkTransaction(this); Transaction *t; t = Daemon::whatProvides(m_resources, Transaction::FilterNotInstalled | Transaction::FilterArch | Transaction::FilterNewest); transaction->setupTransaction(t); setTransaction(Transaction::RoleWhatProvides, transaction); - connect(transaction, SIGNAL(finished(PkTransaction::ExitStatus)), - this, SLOT(searchFinished(PkTransaction::ExitStatus)), Qt::UniqueConnection); - connect(transaction, SIGNAL(package(PackageKit::Transaction::Info,QString,QString)), - this, SLOT(addPackage(PackageKit::Transaction::Info,QString,QString))); + connect(transaction, &PkTransaction::finished, this, &PkInstallPlasmaResources::searchFinished, Qt::UniqueConnection); + connect(transaction, &PkTransaction::package, this, &PkInstallPlasmaResources::addPackage); } void PkInstallPlasmaResources::notFound() { QString msg = i18n("Failed to search for Plasma service"); if (showWarning()) { setInfo(msg, i18n("Could not find service " "in any configured software source")); } sendErrorFinished(NoPackagesFound, msg); } #include "PkInstallPlasmaResources.moc" diff --git a/PkSession/PkInstallPrinterDrivers.cpp b/PkSession/PkInstallPrinterDrivers.cpp index bd306c8..30f8542 100644 --- a/PkSession/PkInstallPrinterDrivers.cpp +++ b/PkSession/PkInstallPrinterDrivers.cpp @@ -1,91 +1,89 @@ /************************************************************************** * Copyright (C) 2009-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "PkInstallPrinterDrivers.h" #include #include #include #include #include PkInstallPrinterDrivers::PkInstallPrinterDrivers(uint xid, const QStringList &resources, const QString &interaction, const QDBusMessage &message, QWidget *parent) : SessionTask(xid, interaction, message, parent), m_resources(resources) { setWindowTitle(i18n("Install Printer Drivers")); // TODO confirm operation QStringList search; - foreach (const QString &deviceid, m_resources) { + for (const QString &deviceid : resources) { QString mfg, mdl; - QStringList fields = deviceid.split(';'); - foreach (const QString &field, fields) { - QString keyvalue = field.trimmed(); + const QStringList fields = deviceid.split(';'); + for (const QString &field : fields) { + const QString keyvalue = field.trimmed(); if (keyvalue.startsWith(QLatin1String("MFG:"))) { mfg = keyvalue.mid(4); } else if (keyvalue.startsWith(QLatin1String("MDL:"))) { mdl = keyvalue.mid(4); } } if (!mfg.isEmpty() && !mdl.isEmpty()) { QString prov; QTextStream out(&prov); out << mfg.toLower().replace(' ', '_') << ';' << mdl.toLower().replace(' ', '_') << ';'; search << prov; } } - PkTransaction *transaction = new PkTransaction(this); + auto transaction = new PkTransaction(this); Transaction *t; t = Daemon::whatProvides(search, Transaction::FilterNotInstalled | Transaction::FilterArch | Transaction::FilterNewest); transaction->setupTransaction(t); setTransaction(Transaction::RoleWhatProvides, transaction); - connect(transaction, SIGNAL(finished(PkTransaction::ExitStatus)), - this, SLOT(searchFinished(PkTransaction::ExitStatus)), Qt::UniqueConnection); - connect(transaction, SIGNAL(package(PackageKit::Transaction::Info,QString,QString)), - this, SLOT(addPackage(PackageKit::Transaction::Info,QString,QString))); + connect(transaction, &PkTransaction::finished, this, &PkInstallPrinterDrivers::searchFinished, Qt::UniqueConnection); + connect(transaction, &PkTransaction::package, this, &PkInstallPrinterDrivers::addPackage); } PkInstallPrinterDrivers::~PkInstallPrinterDrivers() { } void PkInstallPrinterDrivers::notFound() { if (showWarning()) { setInfo(i18n("Failed to search for printer driver"), i18n("Could not find printer driver " "in any configured software source")); } sendErrorFinished(NoPackagesFound, "failed to find printer driver"); } #include "PkInstallPrinterDrivers.moc" diff --git a/PkSession/PkInstallProvideFiles.cpp b/PkSession/PkInstallProvideFiles.cpp index a08ed4d..c91df0d 100644 --- a/PkSession/PkInstallProvideFiles.cpp +++ b/PkSession/PkInstallProvideFiles.cpp @@ -1,121 +1,118 @@ /*************************************************************************** * Copyright (C) 2009-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "PkInstallProvideFiles.h" #include "IntroDialog.h" #include "FilesModel.h" #include #include #include #include PkInstallProvideFiles::PkInstallProvideFiles(uint xid, const QStringList &files, const QString &interaction, const QDBusMessage &message, QWidget *parent) : SessionTask(xid, interaction, message, parent), m_args(files) { setWindowTitle(i18n("Install Packages that Provides Files")); - IntroDialog *introDialog = new IntroDialog(this); - FilesModel *model = new FilesModel(files, QStringList(), this); + auto introDialog = new IntroDialog(this); + auto model = new FilesModel(files, QStringList(), this); introDialog->setModel(model); - connect(introDialog, SIGNAL(continueChanged(bool)), - this, SLOT(enableButtonOk(bool))); + connect(introDialog, &IntroDialog::continueChanged, this, &PkInstallProvideFiles::enableButtonOk); setMainWidget(introDialog); if (m_args.isEmpty()) { introDialog->setDescription(i18n("No files were provided")); } else { QString description; description = i18np("Do you want to search for this now?", "Do you want to search for these now?", m_args.size()); introDialog->setDescription(description); enableButtonOk(true); } QString title; // this will come from DBus interface if (parentTitle.isNull()) { title = i18np("A program wants to install a file", "A program wants to install files", m_args.size()); } else { title = i18np("The application %2 is asking to install a file", "The application %2 is asking to install files", m_args.size(), parentTitle); } setTitle(title); } PkInstallProvideFiles::~PkInstallProvideFiles() { } void PkInstallProvideFiles::search() { - PkTransaction *transaction = new PkTransaction(this); + auto transaction = new PkTransaction(this); transaction->setupTransaction(Daemon::searchFiles(m_args, Transaction::FilterArch | Transaction::FilterNewest)); setTransaction(Transaction::RoleSearchFile, transaction); - connect(transaction, SIGNAL(finished(PkTransaction::ExitStatus)), - this, SLOT(searchFinished(PkTransaction::ExitStatus)), Qt::UniqueConnection); - connect(transaction, SIGNAL(package(PackageKit::Transaction::Info,QString,QString)), - this, SLOT(addPackage(PackageKit::Transaction::Info,QString,QString))); + connect(transaction, &PkTransaction::finished, this, &PkInstallProvideFiles::searchFinished, Qt::UniqueConnection); + connect(transaction, &PkTransaction::package, this, &PkInstallProvideFiles::addPackage); } void PkInstallProvideFiles::notFound() { if (m_alreadyInstalled.size()) { if (showWarning()) { setInfo(i18n("Failed to install file"), i18n("The %1 package already provides this file", m_alreadyInstalled)); } sendErrorFinished(Failed, "already provided"); } else { if (showWarning()) { setInfo(i18n("Failed to find package"), i18np("The file could not be found in any packages", "The files could not be found in any packages", m_args.size())); } sendErrorFinished(NoPackagesFound, "no files found"); } } void PkInstallProvideFiles::addPackage(Transaction::Info info, const QString &packageID, const QString &summary) { if (info != Transaction::InfoInstalled) { SessionTask::addPackage(info, packageID, summary); } else { m_alreadyInstalled = Transaction::packageName(packageID); } } #include "PkInstallProvideFiles.moc" diff --git a/PkSession/PkInterface.cpp b/PkSession/PkInterface.cpp index 44cdbbc..1e60143 100644 --- a/PkSession/PkInterface.cpp +++ b/PkSession/PkInterface.cpp @@ -1,243 +1,204 @@ /*************************************************************************** * Copyright (C) 2008-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "PkInterface.h" #include "packagekitadaptor.h" #include //#include #include "SessionTask.h" #include "PkInstallPackageNames.h" #include "PkInstallMimeTypes.h" #include "PkInstallGStreamerResources.h" #include "PkInstallFontconfigResources.h" #include "PkInstallPlasmaResources.h" #include "PkInstallPackageFiles.h" #include "PkInstallProvideFiles.h" #include "PkInstallCatalogs.h" #include "PkRemovePackageByFiles.h" #include "PkInstallPrinterDrivers.h" #include "PkIsInstalled.h" #include "PkSearchFile.h" #include #include Q_DECLARE_LOGGING_CATEGORY(APPER_SESSION) using namespace PackageKit; PkInterface::PkInterface(QObject *parent) : AbstractIsRunning(parent) { if (!Daemon::isRunning()) { QTimer timer; timer.setInterval(5000); QEventLoop loop; - connect(Daemon::global(), SIGNAL(isRunningChanged()), - &loop, SLOT(quit())); - connect(&timer, SIGNAL(timeout()), - &loop, SLOT(quit())); + connect(Daemon::global(), &Daemon::isRunningChanged, &loop, &QEventLoop::quit); + connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit); loop.exec(); if (!Daemon::isRunning()) { qCWarning(APPER_SESSION) << "Packagekit didn't start"; qApp->quit(); return; } } qCDebug(APPER_SESSION) << "Creating Helper"; (void) new ModifyAdaptor(this); (void) new QueryAdaptor(this); if (!QDBusConnection::sessionBus().registerService("org.freedesktop.PackageKit")) { qCDebug(APPER_SESSION) << "unable to register service to dbus"; return; } if (!QDBusConnection::sessionBus().registerObject("/org/freedesktop/PackageKit", this)) { qCDebug(APPER_SESSION) << "unable to register object to dbus"; return; } } PkInterface::~PkInterface() { } void PkInterface::InstallCatalogs(uint xid, const QStringList &files, const QString &interaction) { - increaseRunning(); qCDebug(APPER_SESSION) << xid << files << interaction; - setDelayedReply(true); - PkInstallCatalogs *task; - task = new PkInstallCatalogs(xid, files, interaction, message()); - connect(task, SIGNAL(finished()), this, SLOT(decreaseRunning())); + auto task = new PkInstallCatalogs(xid, files, interaction, message()); show(task); } void PkInterface::InstallFontconfigResources(uint xid, const QStringList &resources, const QString &interaction) { - increaseRunning(); qCDebug(APPER_SESSION) << xid << resources << interaction; - setDelayedReply(true); - PkInstallFontconfigResources *task; - task = new PkInstallFontconfigResources(xid, resources, interaction, message()); - connect(task, SIGNAL(finished()), this, SLOT(decreaseRunning())); + auto task = new PkInstallFontconfigResources(xid, resources, interaction, message()); show(task); } void PkInterface::InstallGStreamerResources(uint xid, const QStringList &resources, const QString &interaction) { - increaseRunning(); qCDebug(APPER_SESSION) << xid << resources << interaction; - setDelayedReply(true); - PkInstallGStreamerResources *task; - task = new PkInstallGStreamerResources(xid, resources, interaction, message()); - connect(task, SIGNAL(finished()), this, SLOT(decreaseRunning())); + auto task = new PkInstallGStreamerResources(xid, resources, interaction, message()); show(task); } void PkInterface::InstallMimeTypes(uint xid, const QStringList &mime_types, const QString &interaction) { - increaseRunning(); qCDebug(APPER_SESSION) << xid << mime_types << interaction; - setDelayedReply(true); - PkInstallMimeTypes *task = new PkInstallMimeTypes(xid, mime_types, interaction, message()); - connect(task, SIGNAL(finished()), this, SLOT(decreaseRunning())); + auto task = new PkInstallMimeTypes(xid, mime_types, interaction, message()); show(task); } void PkInterface::InstallPackageFiles(uint xid, const QStringList &files, const QString &interaction) { - increaseRunning(); qCDebug(APPER_SESSION) << xid << files << interaction; - setDelayedReply(true); - PkInstallPackageFiles *task = new PkInstallPackageFiles(xid, files, interaction, message()); - connect(task, SIGNAL(finished()), this, SLOT(decreaseRunning())); + auto task = new PkInstallPackageFiles(xid, files, interaction, message()); show(task); } void PkInterface::InstallPackageNames(uint xid, const QStringList &packages, const QString &interaction) { - increaseRunning(); qCDebug(APPER_SESSION) << xid << packages << interaction; - setDelayedReply(true); - PkInstallPackageNames *task = new PkInstallPackageNames(xid, packages, interaction, message()); - connect(task, SIGNAL(finished()), this, SLOT(decreaseRunning())); + auto task = new PkInstallPackageNames(xid, packages, interaction, message()); show(task); } void PkInterface::InstallProvideFiles(uint xid, const QStringList &files, const QString &interaction) { - increaseRunning(); qCDebug(APPER_SESSION) << xid << files << interaction; - setDelayedReply(true); - PkInstallProvideFiles *task = new PkInstallProvideFiles(xid, files, interaction, message()); - connect(task, SIGNAL(finished()), this, SLOT(decreaseRunning())); + auto task = new PkInstallProvideFiles(xid, files, interaction, message()); show(task); } void PkInterface::RemovePackageByFiles(uint xid, const QStringList &files, const QString &interaction) { - increaseRunning(); qCDebug(APPER_SESSION) << xid << files << interaction; - setDelayedReply(true); - PkRemovePackageByFiles *task = new PkRemovePackageByFiles(xid, files, interaction, message()); - connect(task, SIGNAL(finished()), this, SLOT(decreaseRunning())); + auto task = new PkRemovePackageByFiles(xid, files, interaction, message()); show(task); } void PkInterface::InstallPrinterDrivers(uint xid, const QStringList &resources, const QString &interaction) { - increaseRunning(); qCDebug(APPER_SESSION) << xid << resources << interaction; - setDelayedReply(true); - PkInstallPrinterDrivers *task; - task = new PkInstallPrinterDrivers(xid, resources, interaction, message()); - connect(task, SIGNAL(finished()), this, SLOT(decreaseRunning())); + auto task = new PkInstallPrinterDrivers(xid, resources, interaction, message()); show(task); } void PkInterface::InstallPlasmaResources(uint xid, const QStringList &resources, const QString &interaction) { - increaseRunning(); qCDebug(APPER_SESSION) << xid << resources << interaction; - setDelayedReply(true); - PkInstallPlasmaResources *task; - task = new PkInstallPlasmaResources(xid, resources, interaction, message()); - connect(task, SIGNAL(finished()), this, SLOT(decreaseRunning())); + auto task = new PkInstallPlasmaResources(xid, resources, interaction, message()); show(task); } void PkInterface::InstallResources(uint xid, const QString &type, const QStringList &resources, const QString &interaction) { if (type == "codec") InstallGStreamerResources(xid, resources, interaction); else if (type == "mimetype") InstallMimeTypes(xid, resources, interaction); else if (type == "font") InstallFontconfigResources(xid, resources, interaction); else if (type == "postscript-driver") InstallPrinterDrivers(xid, resources, interaction); else if (type == "plasma-service") InstallPlasmaResources(xid, resources, interaction); else sendErrorReply("org.freedesktop.PackageKit.Failed", "Unsupported resource type"); } //Query bool PkInterface::IsInstalled(const QString &package_name, const QString &interaction) { - increaseRunning(); - setDelayedReply(true); - PkIsInstalled *task = new PkIsInstalled(package_name, interaction, message()); - connect(task, SIGNAL(finished()), this, SLOT(decreaseRunning())); + auto task = new PkIsInstalled(package_name, interaction, message()); show(task); // This is discarted return false; } bool PkInterface::SearchFile(const QString &file_name, const QString &interaction, QString &package_name) { Q_UNUSED(package_name) - increaseRunning(); - setDelayedReply(true); - PkSearchFile *task = new PkSearchFile(file_name, interaction, message()); - connect(task, SIGNAL(finished()), this, SLOT(decreaseRunning())); + auto task = new PkSearchFile(file_name, interaction, message()); show(task); // This is discarted return false; } -void PkInterface::show(SessionTask *widget) const +void PkInterface::show(SessionTask *widget) { + increaseRunning(); + setDelayedReply(true); + + connect(widget, &SessionTask::finished, this, &PkInterface::decreaseRunning); if (widget->parentWId()) { // Check before showing if the widget has // a parent, otherwise it should not be modal // to not lock the application widget->setWindowModality(Qt::WindowModal); } widget->show(); // KWindowSystem::forceActiveWindow(widget->winId()); // KWindowSystem::setMainWindow(widget, widget->parentWId()); } diff --git a/PkSession/PkInterface.h b/PkSession/PkInterface.h index c8afd23..c496354 100644 --- a/PkSession/PkInterface.h +++ b/PkSession/PkInterface.h @@ -1,59 +1,59 @@ /*************************************************************************** * Copyright (C) 2008-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef PK_INTERFACE_H #define PK_INTERFACE_H #include #include "AbstractIsRunning.h" class SessionTask; class PkInterface : public AbstractIsRunning, protected QDBusContext { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.freedesktop.PackageKit") public: explicit PkInterface(QObject *parent = 0); ~PkInterface(); public Q_SLOTS: void InstallCatalogs(uint xid, const QStringList &files, const QString &interaction); void InstallFontconfigResources(uint xid, const QStringList &resources, const QString &interaction); void InstallGStreamerResources(uint xid, const QStringList &resources, const QString &interaction); void InstallMimeTypes(uint xid, const QStringList &mime_types, const QString &interaction); void InstallPackageFiles(uint xid, const QStringList &files, const QString &interaction); void InstallPackageNames(uint xid, const QStringList &packages, const QString &interaction); void InstallProvideFiles(uint xid, const QStringList &files, const QString &interaction); void RemovePackageByFiles(uint xid, const QStringList &files, const QString &interaction); void InstallPrinterDrivers(uint xid, const QStringList &resources, const QString &interaction); void InstallResources(uint xid, const QString &type, const QStringList &resources, const QString &interaction); //Query bool IsInstalled(const QString &package_name, const QString &interaction); bool SearchFile(const QString &file_name, const QString &interaction, QString &package_name); private: - void show(SessionTask *widget) const; + void show(SessionTask *widget); // QVariantHash parseInteraction(const QString &interaction); void InstallPlasmaResources(uint xid, const QStringList &resources, const QString &interaction); }; #endif diff --git a/PkSession/PkIsInstalled.cpp b/PkSession/PkIsInstalled.cpp index f52d798..11c698b 100644 --- a/PkSession/PkIsInstalled.cpp +++ b/PkSession/PkIsInstalled.cpp @@ -1,69 +1,67 @@ /*************************************************************************** * Copyright (C) 2009-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "PkIsInstalled.h" #include #include #include #include Q_DECLARE_LOGGING_CATEGORY(APPER_SESSION) PkIsInstalled::PkIsInstalled(const QString &package_name, const QString &interaction, const QDBusMessage &message, QWidget *parent) : SessionTask(0, interaction, message, parent), m_packageName(package_name), m_message(message) { setWindowTitle(i18n("Querying if a Package is Installed")); - PkTransaction *transaction = new PkTransaction(this); + auto transaction = new PkTransaction(this); transaction->setupTransaction(Daemon::resolve(m_packageName, Transaction::FilterInstalled)); setTransaction(Transaction::RoleResolve, transaction); - connect(transaction, SIGNAL(finished(PkTransaction::ExitStatus)), - this, SLOT(searchFinished(PkTransaction::ExitStatus)), Qt::UniqueConnection); - connect(transaction, SIGNAL(package(PackageKit::Transaction::Info,QString,QString)), - this, SLOT(addPackage(PackageKit::Transaction::Info,QString,QString))); + connect(transaction, &PkTransaction::finished, this, &PkIsInstalled::searchFinished, Qt::UniqueConnection); + connect(transaction, &PkTransaction::package, this, &PkIsInstalled::addPackage); } PkIsInstalled::~PkIsInstalled() { } void PkIsInstalled::searchFinished(PkTransaction::ExitStatus status) { qCDebug(APPER_SESSION); if (status == PkTransaction::Success) { QDBusMessage reply = m_message.createReply(); reply << (bool) foundPackagesSize(); sendMessageFinished(reply); } else if (status == PkTransaction::Cancelled) { sendErrorFinished(Cancelled, i18n("User canceled the transaction")); } else { sendErrorFinished(InternalError, i18n("An unknown error happened")); } } #include "PkIsInstalled.moc" diff --git a/PkSession/PkRemovePackageByFiles.cpp b/PkSession/PkRemovePackageByFiles.cpp index fd61de4..d4fc32e 100644 --- a/PkSession/PkRemovePackageByFiles.cpp +++ b/PkSession/PkRemovePackageByFiles.cpp @@ -1,151 +1,148 @@ /*************************************************************************** * Copyright (C) 2009-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "PkRemovePackageByFiles.h" #include "IntroDialog.h" #include "FilesModel.h" #include #include #include #include #include PkRemovePackageByFiles::PkRemovePackageByFiles(uint xid, const QStringList &files, const QString &interaction, const QDBusMessage &message, QWidget *parent) : SessionTask(xid, interaction, message, parent) { setWindowTitle(i18n("Remove Packages that Provides Files")); m_introDialog = new IntroDialog(this); m_introDialog->acceptDrops(i18n("You can drop more files in here")); m_model = new FilesModel(files, QStringList(), this); - connect(m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), - this, SLOT(modelChanged())); + connect(m_model, &FilesModel::rowsInserted, this, &PkRemovePackageByFiles::modelChanged); m_introDialog->setModel(m_model); setMainWidget(m_introDialog); modelChanged(); } PkRemovePackageByFiles::~PkRemovePackageByFiles() { } void PkRemovePackageByFiles::modelChanged() { QStringList files = m_model->files(); enableButtonOk(!files.isEmpty()); QString description; if (files.isEmpty()) { description = i18n("No supported files were provided"); } else { if (m_model->onlyApplications()) { description = i18np("Do you want to remove the following application?", "Do you want to remove the following applications?", files.size()); } else { description = i18np("Do you want to search for a package providing this file?", "Do you want to search for a package providing these files?", files.size()); } } m_introDialog->setDescription(description); QString title; // this will come from DBus interface if (!files.isEmpty() && parentTitle.isNull()) { if (m_model->onlyApplications()) { title = i18np("An application is asking to remove an application", "An application is asking to remove applications", files.size()); } else { title = i18np("An application is asking to remove a file", "An application is asking to remove files", files.size()); } } else if (!files.isEmpty()) { if (m_model->onlyApplications()) { title = i18np("The application %2 is asking to remove an application", "The application %2 is asking to remove applications", files.size(), parentTitle); } else { title = i18np("The application %2 is asking to remove a file", "The application %2 is asking to remove files", files.size(), parentTitle); } } else { title = i18n("No application was found"); } setTitle(title); } void PkRemovePackageByFiles::search() { m_files = m_model->files(); searchFinished(PkTransaction::Success); } void PkRemovePackageByFiles::searchFinished(PkTransaction::ExitStatus status) { if (status == PkTransaction::Success) { if (!m_files.isEmpty()) { QString file = m_files.takeFirst(); - PkTransaction *transaction = new PkTransaction(this); + auto transaction = new PkTransaction(this); transaction->setupTransaction(Daemon::searchFiles(file, Transaction::FilterInstalled)); setTransaction(Transaction::RoleSearchFile, transaction); - connect(transaction, SIGNAL(finished(PkTransaction::ExitStatus)), - this, SLOT(searchFinished(PkTransaction::ExitStatus)), Qt::UniqueConnection); - connect(transaction, SIGNAL(package(PackageKit::Transaction::Info,QString,QString)), - this, SLOT(addPackage(PackageKit::Transaction::Info,QString,QString))); + connect(transaction, &PkTransaction::finished, this, &PkRemovePackageByFiles::searchFinished, Qt::UniqueConnection); + connect(transaction, &PkTransaction::package, this, &PkRemovePackageByFiles::addPackage); } else { // we are done resolving SessionTask::searchFinished(status); } } else { // we got an error... SessionTask::searchFinished(status); } } void PkRemovePackageByFiles::notFound() { if (showWarning()) { QStringList files = m_model->files(); setInfo(i18n("Could not find %1", files.join(", ")), i18np("The file could not be found in any installed package", "The files could not be found in any installed package", files.size())); } sendErrorFinished(NoPackagesFound, "no package found"); } #include "PkRemovePackageByFiles.moc" diff --git a/PkSession/PkSearchFile.cpp b/PkSession/PkSearchFile.cpp index 29183bc..27a19e6 100644 --- a/PkSession/PkSearchFile.cpp +++ b/PkSession/PkSearchFile.cpp @@ -1,88 +1,86 @@ /*************************************************************************** * Copyright (C) 2009-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "PkSearchFile.h" #include #include #include #include #include Q_DECLARE_LOGGING_CATEGORY(APPER_SESSION) PkSearchFile::PkSearchFile(const QString &file_name, const QString &interaction, const QDBusMessage &message, QWidget *parent) : SessionTask(0, interaction, message, parent), m_fileName(file_name), m_message(message) { setWindowTitle(i18n("Search Packages that Provides Files")); // Check for a leading slash '/' return with an error if it's not there.. if (!m_fileName.startsWith('/')) { sendErrorFinished(Failed, "Only full file name path is supported"); return; } - PkTransaction *transaction = new PkTransaction(this); + auto transaction = new PkTransaction(this); transaction->setupTransaction(Daemon::searchFiles(m_fileName, Transaction::FilterNewest)); setTransaction(Transaction::RoleSearchFile, transaction); - connect(transaction, SIGNAL(finished(PkTransaction::ExitStatus)), - this, SLOT(searchFinished(PkTransaction::ExitStatus)), Qt::UniqueConnection); - connect(transaction, SIGNAL(package(PackageKit::Transaction::Info,QString,QString)), - this, SLOT(addPackage(PackageKit::Transaction::Info,QString,QString))); + connect(transaction, &PkTransaction::finished, this, &PkSearchFile::searchFinished, Qt::UniqueConnection); + connect(transaction, &PkTransaction::package, this, &PkSearchFile::addPackage); } PkSearchFile::~PkSearchFile() { } void PkSearchFile::searchSuccess() { QModelIndex index = model()->index(0, 0); bool installed = false; QString packageID; if (index.isValid()) { Transaction::Info info; info = index.data(PackageModel::InfoRole).value(); installed = info == Transaction::InfoInstalled; packageID = index.data(PackageModel::IdRole).toString(); } QDBusMessage reply = m_message.createReply(); reply << installed; reply << Transaction::packageName(packageID); qCDebug(APPER_SESSION) << reply; sendMessageFinished(reply); } void PkSearchFile::notFound() { QString msg(i18n("The file name could not be found in any software source")); setError(i18n("Could not find %1", m_fileName), msg); sendErrorFinished(NoPackagesFound, msg); } #include "PkSearchFile.moc" diff --git a/PkSession/PkSession.cpp b/PkSession/PkSession.cpp index 88e5b54..9c6e87c 100644 --- a/PkSession/PkSession.cpp +++ b/PkSession/PkSession.cpp @@ -1,102 +1,100 @@ /*************************************************************************** * Copyright (C) 2008-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "PkSession.h" #include "PkInterface.h" #include #include #include //#include //#include //#include #include #include #define MINUTE 60000 Q_DECLARE_LOGGING_CATEGORY(APPER_SESSION) using namespace PackageKit; PkSession::PkSession(QObject* parent) : QObject(parent) { m_pkInterface = new PkInterface(this); - connect(m_pkInterface, SIGNAL(close()), - this, SLOT(prepareToClose())); + connect(m_pkInterface, &PkInterface::close, this, &PkSession::prepareToClose); // QString locale(KLocale::global()->language() % QLatin1Char('.') % KLocale::global()->encoding()); // Daemon::global()->setHints(QLatin1String("locale=") % locale); // this enables not quitting when closing a transaction ui qApp->setQuitOnLastWindowClosed(false); // create the close timer and connect it's signal m_closeT = new QTimer(this); - connect(m_closeT, SIGNAL(timeout()), - this, SLOT(close())); + connect(m_closeT, &QTimer::timeout, this, &PkSession::close); prepareToClose(); } void PkSession::prepareToClose() { if (isRunning()) { qCDebug(APPER_SESSION) << "Stoping Timer"; m_closeT->stop(); } else { qCDebug(APPER_SESSION) << "Starting Timer: " << MINUTE; m_closeT->start(MINUTE); } } bool PkSession::isRunning() { if (m_pkInterface && m_pkInterface->isRunning()) { qCDebug(APPER_SESSION) << m_pkInterface; return true; } return false; } void PkSession::close() { // This will run when the timer times out, we will check // again just to be sure. if (!isRunning()) { qCDebug(APPER_SESSION) << "Closed by Timer"; qApp->quit(); } } int PkSession::newInstance() { return 0; } PkSession::~PkSession() { } diff --git a/PkSession/ReviewChanges.cpp b/PkSession/ReviewChanges.cpp index f73696c..bd70757 100644 --- a/PkSession/ReviewChanges.cpp +++ b/PkSession/ReviewChanges.cpp @@ -1,79 +1,78 @@ /*************************************************************************** * Copyright (C) 2008-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "ReviewChanges.h" #include "ui_ReviewChanges.h" #include #include #include #include #include ReviewChanges::ReviewChanges(PackageModel *model, QWidget *parent) : QWidget(parent), ui(new Ui::ReviewChanges), m_model(model) { ui->setupUi(this); //initialize the model, delegate, client and connect it's signals ui->packageView->viewport()->setAttribute(Qt::WA_Hover); - KCategorizedSortFilterProxyModel *changedProxy = new KCategorizedSortFilterProxyModel(this); + auto changedProxy = new KCategorizedSortFilterProxyModel(this); changedProxy->setSourceModel(m_model); changedProxy->setCategorizedModel(true); changedProxy->sort(0); changedProxy->setDynamicSortFilter(true); changedProxy->setSortCaseSensitivity(Qt::CaseInsensitive); changedProxy->setSortRole(PackageModel::SortRole); ui->packageView->setModel(changedProxy); setWindowTitle(i18np("The following package was found", "The following packages were found", m_model->rowCount())); - ChangesDelegate *delegate = new ChangesDelegate(ui->packageView); + auto delegate = new ChangesDelegate(ui->packageView); delegate->setExtendPixmapWidth(0); ui->packageView->setItemDelegate(delegate); - connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), - this, SLOT(selectionChanged())); + connect(m_model, &PackageModel::dataChanged, this, &ReviewChanges::selectionChanged); } ReviewChanges::~ReviewChanges() { delete ui; } PackageModel *ReviewChanges::model() const { return m_model; } void ReviewChanges::selectionChanged() { emit hasSelectedPackages(!m_model->selectedPackagesToInstall().isEmpty() || !m_model->selectedPackagesToRemove().isEmpty()); } #include "ReviewChanges.moc" diff --git a/PkSession/SessionTask.cpp b/PkSession/SessionTask.cpp index 3fa013e..6aabb8b 100644 --- a/PkSession/SessionTask.cpp +++ b/PkSession/SessionTask.cpp @@ -1,667 +1,661 @@ /*************************************************************************** * Copyright (C) 2009-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "SessionTask.h" #include "ui_SessionTask.h" #include "IntroDialog.h" #include "InfoWidget.h" #include "ReviewChanges.h" #include "ApplicationLauncher.h" #include #include #include #include #include #include #include #include #include #include #include //#include #include //#include #include //#include #include #include Q_DECLARE_LOGGING_CATEGORY(APPER_SESSION) using namespace PackageKit; SessionTask::SessionTask(uint xid, const QString &interaction, const QDBusMessage &message, QWidget *parent) : QDialog(parent), m_xid(xid), m_message(message), m_reviewChanges(0), m_pkTransaction(0), ui(new Ui::SessionTask) { ui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose); m_model = new PackageModel(this); // connect(KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()), // this, SLOT(updatePallete())); updatePallete(); setWindowIcon(QIcon::fromTheme("system-software-install")); // setButtons(KDialog::Ok | KDialog::Cancel); // setButtonText(KDialog::Ok, i18n("Continue")); // setButtonIcon(KDialog::Ok, QIcon::fromTheme("go-next")); enableButtonOk(false); //TODO FIXME // QString locale(KLocale::global()->language() % QLatin1Char('.') % KLocale::global()->encoding()); // Daemon::global()->setHints(QLatin1String("locale=") % locale); // Defaults to always m_interactions = ConfirmSearch | ConfirmDeps | ConfirmInstall | Progress | Finished | Warning; m_timeout = 0; parseInteraction(interaction); QString cmdline; uint pid; // TODO as we are running on the session it might // be useless to check the PID on the system if ((pid = getPidSession()) != UINT_MAX) { cmdline = getCmdLine(pid); } else if ((pid = getPidSystem()) != UINT_MAX) { cmdline = getCmdLine(pid); } if (!cmdline.isNull()) { setExec(cmdline); } setMinimumSize(QSize(430,280)); // KConfig config("apper"); // KConfigGroup configGroup(&config, "SessionInstaller"); // restoreDialogSize(configGroup); } SessionTask::~SessionTask() { // KConfig config("apper"); // KConfigGroup configGroup(&config, "SessionInstaller"); // saveDialogSize(configGroup); delete ui; } void SessionTask::addPackage(Transaction::Info info, const QString &packageID, const QString &summary) { m_model->addSelectedPackage(info, packageID, summary); } void SessionTask::searchFinished(PkTransaction::ExitStatus status) { if (m_pkTransaction) { // Disconnect so it can be connected to commitFinished latter - disconnect(m_pkTransaction->transaction(), SIGNAL(finished(PkTransaction::ExitStatus)), - this, SLOT(searchFinished(PkTransaction::ExitStatus))); + disconnect(m_pkTransaction->transaction(), &PkTransaction::finished, this, &SessionTask::searchFinished); } if (status == PkTransaction::Success) { m_model->finished(); if (m_model->rowCount() == 0) { notFound(); } else { searchSuccess(); } } else if (status == PkTransaction::Cancelled) { // TODO PORT // slotButtonClicked(KDialog::Cancel); } else { searchFailed(); } } void SessionTask::commitFinished(PkTransaction::ExitStatus status) { if (m_pkTransaction) { // Disconnect so it can be connected to something else latter - disconnect(m_pkTransaction->transaction(), SIGNAL(finished(PkTransaction::ExitStatus)), - this, SLOT(searchFinished(PkTransaction::ExitStatus))); + disconnect(m_pkTransaction->transaction(), &PkTransaction::finished, this, &SessionTask::searchFinished); } if (status == PkTransaction::Success) { if (!m_removePackages.isEmpty()) { removePackages(); } else { commitSuccess(); } } else if (status == PkTransaction::Cancelled) { // TODO PORT // slotButtonClicked(KDialog::Cancel); } else { commitFailed(); } } void SessionTask::updatePallete() { QPalette pal; // pal.setColor(QPalette::Window, KGlobalSettings::activeTitleColor()); // pal.setColor(QPalette::WindowText, KGlobalSettings::activeTextColor()); ui->backgroundFrame->setPalette(pal); } void SessionTask::setDialog(QDialog *dialog) { // Store the current values QWidget *widget = ui->stackedWidget->currentWidget(); if (qobject_cast(dialog)) { // TODO if there is a removal after instalation // this will break it, but we don't have // this case yet... commitSuccess(dialog); } else { // Set the new ones // setMainWidget(dialog->mainWidget()); // setTitle(dialog->windowTitle()); // must come after // connect(this, SIGNAL(okClicked()), // dialog, SLOT(accept())); // connect(this, SIGNAL(okClicked()), // dialog->mainWidget(), SLOT(deleteLater())); // connect(this, SIGNAL(okClicked()), // dialog, SLOT(deleteLater())); // Make sure we see the last widget and title - QSignalMapper *mapper = new QSignalMapper(this); + auto mapper = new QSignalMapper(this); mapper->setMapping(this, widget); connect(this, SIGNAL(okClicked()), mapper, SLOT(map())); connect(mapper, SIGNAL(mapped(QWidget*)), this, SLOT(setMainWidget(QWidget*))); enableButtonOk(true); } } void SessionTask::setMainWidget(QWidget *widget) { if (widget != mainWidget()) { ui->stackedWidget->addWidget(widget); ui->stackedWidget->setCurrentWidget(widget); setTitle(widget->windowTitle()); } } QWidget* SessionTask::mainWidget() { return ui->stackedWidget->currentWidget(); } void SessionTask::setInfo(const QString &title, const QString &text, const QString &details) { - InfoWidget *info = new InfoWidget(this); + auto info = new InfoWidget(this); info->setWindowTitle(title); info->setDescription(text); info->setDetails(details); setMainWidget(info); // setButtons(KDialog::Close); // button(KDialog::Close)->setFocus(); if (qobject_cast(sender())) { // if we have a sender this method was caller by PkTransaction // be carefull because QSignalMapper from KDialog also calls this method sender()->disconnect(); sendErrorFinished(Failed, text); } } void SessionTask::setError(const QString &title, const QString &text, const QString &details) { - InfoWidget *info = new InfoWidget(this); + auto info = new InfoWidget(this); info->setWindowTitle(title); info->setDescription(text); info->setIcon(QIcon::fromTheme("dialog-error")); info->setDetails(details); setMainWidget(info); // setButtons(KDialog::Close); // button(KDialog::Close)->setFocus(); if (qobject_cast(sender())) { // if we have a sender this method was caller by PkTransaction // be carefull because QSignalMapper from KDialog also calls this method sender()->disconnect(); sendErrorFinished(Failed, text); } } void SessionTask::setFinish(const QString &title, const QString &text, QWidget *widget) { auto info = new InfoWidget(this); info->setWindowTitle(title); info->setDescription(text); info->setIcon(QIcon::fromTheme("dialog-ok-apply")); info->addWidget(widget); setMainWidget(info); // setButtons(KDialog::Close); // button(KDialog::Close)->setFocus(); } void SessionTask::setTitle(const QString &title) { ui->titleL->setText(title); } void SessionTask::setExec(const QString &exec) { if (pathIsTrusted(exec)) { // Get from X11 the window title // KWindowInfo info = KWindowSystem::windowInfo(m_xid, NET::WMVisibleName); // parentTitle = info.visibleName(); } else { parentTitle = exec; } } bool SessionTask::pathIsTrusted(const QString &exec) { // special case the plugin helper -- it's trusted return exec == "/usr/libexec/gst-install-plugins-helper" || exec == "/usr/libexec/pk-gstreamer-install" || exec == "/usr/bin/gstreamer-codec-install" || exec == "/usr/lib/packagekit/pk-gstreamer-install" || exec == "/usr/bin/plasma-desktop" || exec == "/usr/bin/apper"; } QString SessionTask::getCmdLine(uint pid) { QFile file(QString("/proc/%1/cmdline").arg(pid)); QString line; if (file.open(QFile::ReadOnly)) { char buf[1024]; qint64 lineLength = file.readLine(buf, sizeof(buf)); if (lineLength != -1) { // the line is available in buf line = QString::fromLocal8Bit(buf); if (!line.contains("(deleted)")) { return line; } } } return QString(); } uint SessionTask::getPidSystem() { QDBusMessage msg; msg = QDBusMessage::createMethodCall("org.freedesktop.DBus", "/org/freedesktop/DBus/Bus", "org.freedesktop.DBus", QLatin1String("GetConnectionUnixProcessID")); msg << m_message.service(); QDBusMessage reply = QDBusConnection::systemBus().call(msg); if (reply.type() != QDBusMessage::ReplyMessage) { qCWarning(APPER_SESSION) << "Message did not receive a reply"; } if (reply.arguments().size() == 1) { return reply.arguments().at(0).toUInt(); } return UINT_MAX; } uint SessionTask::getPidSession() { QDBusMessage msg; msg = QDBusMessage::createMethodCall("org.freedesktop.DBus", "/org/freedesktop/DBus/Bus", "org.freedesktop.DBus", QLatin1String("GetConnectionUnixProcessID")); msg << m_message.service(); QDBusMessage reply = QDBusConnection::sessionBus().call(msg); if (reply.type() != QDBusMessage::ReplyMessage) { qCWarning(APPER_SESSION) << "Message did not receive a reply"; } if (reply.arguments().size() == 1) { return reply.arguments().at(0).toUInt(); } return UINT_MAX; } void SessionTask::search() { qCDebug(APPER_SESSION) << "virtual method called, falling back to commit()"; commit(); } void SessionTask::commit() { qCDebug(APPER_SESSION) << "virtual method called"; if (m_reviewChanges) { QStringList installPackages = m_reviewChanges->model()->selectedPackagesToInstall(); m_removePackages = m_reviewChanges->model()->selectedPackagesToRemove(); if (installPackages.isEmpty() && m_removePackages.isEmpty()) { setInfo(i18n("There are no packages to Install or Remove"), i18n("This action should not happen")); sendErrorFinished(Failed, "to install or remove due to empty lists"); } else if (!installPackages.isEmpty()) { // Install Packages - PkTransaction *transaction = new PkTransaction(this); + auto transaction = new PkTransaction(this); setTransaction(Transaction::RoleInstallPackages, transaction); - connect(transaction, SIGNAL(finished(PkTransaction::ExitStatus)), - this, SLOT(commitFinished(PkTransaction::ExitStatus)), Qt::UniqueConnection); + connect(transaction, &PkTransaction::finished, this, &SessionTask::commitFinished, Qt::UniqueConnection); transaction->installPackages(installPackages); } else { // Remove them removePackages(); } } } void SessionTask::removePackages() { // Remove Packages - PkTransaction *transaction = new PkTransaction(this); + auto transaction = new PkTransaction(this); setTransaction(Transaction::RoleRemovePackages, transaction); - connect(transaction, SIGNAL(finished(PkTransaction::ExitStatus)), - this, SLOT(commitFinished(PkTransaction::ExitStatus)), Qt::UniqueConnection); + connect(transaction, &PkTransaction::finished, this, &SessionTask::commitFinished, Qt::UniqueConnection); transaction->removePackages(m_removePackages); m_removePackages.clear(); } void SessionTask::notFound() { qCDebug(APPER_SESSION) << "virtual method called"; if (showWarning()) { setInfo(i18n("Could not find"), i18n("No packages were found that meet the request")); } sendErrorFinished(NoPackagesFound, "no package found"); } void SessionTask::searchFailed() { qCDebug(APPER_SESSION) << "virtual method called"; setInfo(i18n("Failed to find"), i18n("No packages were found that meet the request")); sendErrorFinished(Failed, "failed to search"); } void SessionTask::searchSuccess() { qCDebug(APPER_SESSION) << "virtual method called"; enableButtonOk(true); m_reviewChanges = new ReviewChanges(m_model, this); - connect(m_reviewChanges, SIGNAL(hasSelectedPackages(bool)), - this, SLOT(enableButtonOk(bool))); + connect(m_reviewChanges, &ReviewChanges::hasSelectedPackages, this, &SessionTask::enableButtonOk); setMainWidget(m_reviewChanges); } void SessionTask::commitFailed() { qCDebug(APPER_SESSION) << "virtual method called"; // This should not be used to display stuff as the transaction should // emit error() or info() // setInfo(i18n("Failed to commit transaction"), // PkStrings::errorMessage(m_pkTransaction->error())); sendErrorFinished(Failed, i18n("Transaction did not finish with success")); } void SessionTask::commitSuccess(QWidget *widget) { qCDebug(APPER_SESSION) << "virtual method called"; setFinish(i18n("Task completed"), i18n("All operations were committed successfully"), widget); finishTaskOk(); } void SessionTask::slotButtonClicked(int button) { if (button == QDialogButtonBox::Ok) { // qCDebug(APPER_SESSION) << mainWidget()->objectName(); if (qobject_cast(mainWidget())) { enableButtonOk(false); search(); } else if (qobject_cast(mainWidget())) { enableButtonOk(false); commit(); } else { // emit okClicked(); } } else { // KDialog::slotButtonClicked(button); sendErrorFinished(Cancelled, "Aborted by the user"); } } void SessionTask::sendErrorFinished(DBusError error, const QString &msg) { QString dbusError; switch (error) { case Failed: dbusError = "org.freedesktop.PackageKit.Failed"; break; case InternalError: dbusError = "org.freedesktop.PackageKit.InternalError"; break; case NoPackagesFound: dbusError = "org.freedesktop.PackageKit.NoPackagesFound"; break; case Forbidden: dbusError = "org.freedesktop.PackageKit.Forbidden"; break; case Cancelled: dbusError = "org.freedesktop.PackageKit.Cancelled"; break; } QDBusMessage reply; reply = m_message.createErrorReply(dbusError, msg); QDBusConnection::sessionBus().send(reply); } bool SessionTask::sendMessageFinished(const QDBusMessage &message) { // emit finished(); return QDBusConnection::sessionBus().send(message); } uint SessionTask::parentWId() const { return m_xid; } void SessionTask::enableButtonOk(bool state) { // KDialog::enableButtonOk(state); if (state) { // When enabling the Continue button put focus on it // button(KDialog::Ok)->setFocus(); } } void SessionTask::parseInteraction(const QString &interaction) { QStringList interactions = interaction.split(','); // Enable or disable all options if (interactions.contains("always")) { m_interactions = ConfirmSearch | ConfirmDeps | ConfirmInstall | Progress | Finished | Warning; } else if (interactions.contains("never")) { m_interactions = 0; } // show custom options if (interactions.contains("show-confirm-search")) { m_interactions |= ConfirmSearch; } if (interactions.contains("show-confirm-deps")) { m_interactions |= ConfirmDeps; } if (interactions.contains("show-confirm-install")) { m_interactions |= ConfirmInstall; } if (interactions.contains("show-progress")) { m_interactions |= Progress; } if (interactions.contains("show-finished")) { m_interactions |= Finished; } if (interactions.contains("show-warning")) { m_interactions |= Warning; } // hide custom options if (interactions.contains("hide-confirm-search")) { m_interactions &= ~ConfirmSearch; } if (interactions.contains("hide-confirm-deps")) { m_interactions &= ~ConfirmDeps; } if (interactions.contains("hide-confirm-install")) { m_interactions &= ~ConfirmInstall; } if (interactions.contains("hide-progress")) { m_interactions &= ~Progress; } if (interactions.contains("hide-finished")) { m_interactions &= ~Finished; } if (interactions.contains("hide-warning")) { m_interactions &= ~Warning; } int index; QRegExp rx("^timeout=(\\d+)$"); index = interactions.indexOf(rx); if (index != -1) { if (rx.indexIn(interactions.at(index)) != -1) { m_timeout = rx.cap(1).toUInt(); } } } bool SessionTask::foundPackages() const { return m_model->rowCount(); } int SessionTask::foundPackagesSize() const { return m_model->rowCount(); } PackageModel *SessionTask::model() const { return m_model; } void SessionTask::setTransaction(Transaction::Role role, PkTransaction *t) { if (m_pkTransaction == 0) { m_pkTransaction = new PkTransactionWidget(this); m_pkTransaction->hideCancelButton(); ui->stackedWidget->addWidget(m_pkTransaction); - connect(m_pkTransaction, SIGNAL(titleChanged(QString)), - this, SLOT(setTitle(QString))); + connect(m_pkTransaction, &PkTransactionWidget::titleChanged, this, &SessionTask::setTitle); connect(this, SIGNAL(cancelClicked()), m_pkTransaction, SLOT(cancel())); connect(m_pkTransaction, SIGNAL(dialog(KDialog*)), this, SLOT(setDialog(KDialog*))); connect(m_pkTransaction, SIGNAL(sorry(QString,QString,QString)), this, SLOT(setInfo(QString,QString,QString))); connect(m_pkTransaction, SIGNAL(error(QString,QString,QString)), this, SLOT(setError(QString,QString,QString))); } if (t) { m_pkTransaction->setTransaction(t, role); // setTitle(m_pkTransaction->title()); } // avoid changing the current widget if (mainWidget() != m_pkTransaction) { ui->stackedWidget->setCurrentWidget(m_pkTransaction); } } void SessionTask::finishTaskOk() { sendMessageFinished(m_message.createReply()); } SessionTask::Interactions SessionTask::interactions() const { return m_interactions; } uint SessionTask::timeout() const { return m_timeout; } bool SessionTask::showConfirmSearch() const { return m_interactions & ConfirmSearch; } bool SessionTask::showConfirmDeps() const { return m_interactions & ConfirmDeps; } bool SessionTask::showConfirmInstall() const { return m_interactions & ConfirmInstall; } bool SessionTask::showProgress() const { return m_interactions & Progress; } bool SessionTask::showFinished() const { return m_interactions & Finished; } bool SessionTask::showWarning() const { return m_interactions & Warning; } #include "SessionTask.moc" diff --git a/apperd/ApperdThread.cpp b/apperd/ApperdThread.cpp index 4103125..32ec90f 100644 --- a/apperd/ApperdThread.cpp +++ b/apperd/ApperdThread.cpp @@ -1,337 +1,333 @@ /*************************************************************************** * Copyright (C) 2012 by Daniel Nicoletti * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "ApperdThread.h" #include "RefreshCacheTask.h" #include "Updater.h" #include "DistroUpgrade.h" #include "TransactionWatcher.h" #include "DBusInterface.h" #include "RebootListener.h" #include #include //#include #include #include #include #include #include //#include #include #include #include #include #include #include #include Q_DECLARE_LOGGING_CATEGORY(APPER_DAEMON) #define FIVE_MIN 360000 #define ONE_MIN 72000 /* * What we need: * - Refresh the package cache periodicaly (implies listenning to PK's updates changed) * - Update or Display Package Updates * - Display Distro Upgrades * - Start Sentinel to keep an eye on running transactions */ using namespace PackageKit; //using namespace Solid; ApperdThread::ApperdThread(QObject *parent) : QObject(parent), m_proxyChanged(true), m_AptRebootListener(new AptRebootListener(this)) { } ApperdThread::~ApperdThread() { } void ApperdThread::init() { // connect(PowerManagement::notifier(), SIGNAL(appShouldConserveResourcesChanged(bool)), // this, SLOT(appShouldConserveResourcesChanged())); // This timer keeps polling to see if it has // to refresh the cache m_qtimer = new QTimer(this); m_qtimer->setInterval(FIVE_MIN); - connect(m_qtimer, SIGNAL(timeout()), this, SLOT(poll())); + connect(m_qtimer, &QTimer::timeout, this, &ApperdThread::poll); m_qtimer->start(); //check if any changes to the file occour //this also prevents from reading when a checkUpdate happens KDirWatch *confWatch = new KDirWatch(this); // confWatch->addFile(KStandardDirs::locateLocal("config", "apper")); connect(confWatch, SIGNAL(dirty(QString)), this, SLOT(configFileChanged())); connect(confWatch, SIGNAL(created(QString)), this, SLOT(configFileChanged())); connect(confWatch, SIGNAL(deleted(QString)), this, SLOT(configFileChanged())); confWatch->startScan(); // Watch for changes in the KDE proxy settings KDirWatch *proxyWatch = new KDirWatch(this); // proxyWatch->addFile(KStandardDirs::locateLocal("config", "kioslaverc")); connect(proxyWatch, SIGNAL(dirty(QString)), this, SLOT(proxyChanged())); connect(proxyWatch, SIGNAL(created(QString)), this, SLOT(proxyChanged())); connect(proxyWatch, SIGNAL(deleted(QString)), this, SLOT(proxyChanged())); proxyWatch->startScan(); // QString locale(KLocale::global()->language() % QLatin1Char('.') % KLocale::global()->encoding()); // Daemon::global()->setHints(QLatin1String("locale=") % locale); - connect(Daemon::global(), SIGNAL(updatesChanged()), - SLOT(updatesChanged())); + connect(Daemon::global(), &Daemon::updatesChanged, this, &ApperdThread::updatesChanged); m_interface = new DBusInterface(this); m_refreshCache = new RefreshCacheTask(this); - connect(m_interface, SIGNAL(refreshCache()), - m_refreshCache, SLOT(refreshCache())); + connect(m_interface, &DBusInterface::refreshCache, m_refreshCache, &RefreshCacheTask::refreshCache); m_updater = new Updater(this); m_distroUpgrade = new DistroUpgrade(this); // read the current settings configFileChanged(); // In case PackageKit is not running watch for it's registration to configure proxy - QDBusServiceWatcher *watcher; - watcher = new QDBusServiceWatcher(QLatin1String("org.freedesktop.PackageKit"), - QDBusConnection::systemBus(), - QDBusServiceWatcher::WatchForRegistration, - this); - connect(watcher, SIGNAL(serviceRegistered(QString)), SLOT(setProxy())); + auto watcher = new QDBusServiceWatcher(QLatin1String("org.freedesktop.PackageKit"), + QDBusConnection::systemBus(), + QDBusServiceWatcher::WatchForRegistration, + this); + connect(watcher, &QDBusServiceWatcher::serviceRegistered, this, &ApperdThread::setProxy); // if PackageKit is running check to see if there are running transactons already bool packagekitIsRunning = nameHasOwner(QLatin1String("org.freedesktop.PackageKit"), QDBusConnection::systemBus()); m_transactionWatcher = new TransactionWatcher(packagekitIsRunning, this); // connect the watch transaction coming from the updater icon to our watcher - connect(m_interface, SIGNAL(watchTransaction(QDBusObjectPath)), - m_transactionWatcher, SLOT(watchTransaction(QDBusObjectPath))); + connect(m_interface, &DBusInterface::watchTransaction, m_transactionWatcher, &TransactionWatcher::watchTransactionInteractive); // listen to Debian/Apt reboot signals from other sources (apt) - connect(m_AptRebootListener, SIGNAL(requestReboot()), m_transactionWatcher, SLOT(showRebootNotificationApt())); + connect(m_AptRebootListener, &AptRebootListener::requestReboot, m_transactionWatcher, &TransactionWatcher::showRebootNotificationApt); QTimer::singleShot(2 /*minutes*/ * 60 /*seconds*/ * 1000 /*msec*/, m_AptRebootListener, SLOT(checkForReboot())); if (packagekitIsRunning) { // PackageKit is running set the session Proxy setProxy(); // If packagekit is already running go check // for updates updatesChanged(); } else { // Initial check for updates QTimer::singleShot(ONE_MIN, this, SLOT(updatesChanged())); } } // This is called every 5 minutes void ApperdThread::poll() { if (m_lastRefreshCache.isNull()) { // This value wasn't set // convert this to QDateTime m_lastRefreshCache = getTimeSinceRefreshCache(); } // If check for updates is active if (m_configs[CFG_INTERVAL].value() != Enum::Never) { // Find out how many seconds passed since last refresh cache uint secsSinceLastRefresh; secsSinceLastRefresh = QDateTime::currentDateTime().toTime_t() - m_lastRefreshCache.toTime_t(); // If lastRefreshCache is null it means that the cache was never refreshed if (m_lastRefreshCache.isNull() || secsSinceLastRefresh > m_configs[CFG_INTERVAL].value()) { bool ignoreBattery = m_configs[CFG_CHECK_UP_BATTERY].value(); bool ignoreMobile = m_configs[CFG_CHECK_UP_MOBILE].value(); if (isSystemReady(ignoreBattery, ignoreMobile)) { m_refreshCache->refreshCache(); } // Invalidate the last time the cache was refreshed m_lastRefreshCache = QDateTime(); } } } void ApperdThread::configFileChanged() { KConfig config("apper"); KConfigGroup checkUpdateGroup(&config, "CheckUpdate"); m_configs[CFG_CHECK_UP_BATTERY] = checkUpdateGroup.readEntry(CFG_CHECK_UP_BATTERY, DEFAULT_CHECK_UP_BATTERY); m_configs[CFG_CHECK_UP_MOBILE] = checkUpdateGroup.readEntry(CFG_CHECK_UP_MOBILE, DEFAULT_CHECK_UP_MOBILE); m_configs[CFG_INSTALL_UP_BATTERY] = checkUpdateGroup.readEntry(CFG_INSTALL_UP_BATTERY, DEFAULT_INSTALL_UP_BATTERY); m_configs[CFG_INSTALL_UP_MOBILE] = checkUpdateGroup.readEntry(CFG_INSTALL_UP_MOBILE, DEFAULT_INSTALL_UP_MOBILE); m_configs[CFG_AUTO_UP] = checkUpdateGroup.readEntry(CFG_AUTO_UP, Enum::AutoUpdateDefault); m_configs[CFG_INTERVAL] = checkUpdateGroup.readEntry(CFG_INTERVAL, Enum::TimeIntervalDefault); m_configs[CFG_DISTRO_UPGRADE] = checkUpdateGroup.readEntry(CFG_DISTRO_UPGRADE, Enum::DistroUpgradeDefault); m_updater->setConfig(m_configs); m_distroUpgrade->setConfig(m_configs); KDirWatch *confWatch = qobject_cast(sender()); if (confWatch) { // Check for updates again since the config changed updatesChanged(); } } void ApperdThread::proxyChanged() { // We must reparse the configuration since the values are all cached KProtocolManager::reparseConfiguration(); QHash proxyConfig; if (KProtocolManager::proxyType() == KProtocolManager::ManualProxy) { proxyConfig["http"] = KProtocolManager::proxyFor("http"); proxyConfig["https"] = KProtocolManager::proxyFor("https"); proxyConfig["ftp"] = KProtocolManager::proxyFor("ftp"); proxyConfig["socks"] = KProtocolManager::proxyFor("socks"); } // Check if the proxy settings really changed to avoid setting them twice if (proxyConfig != m_proxyConfig) { m_proxyConfig = proxyConfig; m_proxyChanged = true; setProxy(); } } void ApperdThread::setProxy() { if (!m_proxyChanged) { return; } // If we were called by the watcher it is because PackageKit is running bool packagekitIsRunning = true; - QDBusServiceWatcher *watcher = qobject_cast(sender()); + auto watcher = qobject_cast(sender()); if (!watcher) { packagekitIsRunning = nameHasOwner(QLatin1String("org.freedesktop.PackageKit"), QDBusConnection::systemBus()); } if (packagekitIsRunning) { // Apply the proxy changes only if packagekit is running // use value() to not insert items on the hash Daemon::global()->setProxy(m_proxyConfig.value("http"), m_proxyConfig.value("https"), m_proxyConfig.value("ftp"), m_proxyConfig.value("socks"), QString(), QString()); m_proxyChanged = false; } } void ApperdThread::updatesChanged() { // update the last time the cache was refreshed QDateTime lastCacheRefresh; lastCacheRefresh = getTimeSinceRefreshCache(); if (lastCacheRefresh != m_lastRefreshCache) { m_lastRefreshCache = lastCacheRefresh; } bool ignoreBattery = m_configs[CFG_INSTALL_UP_BATTERY].value(); bool ignoreMobile = m_configs[CFG_INSTALL_UP_MOBILE].value(); // Make sure the user sees the updates m_updater->checkForUpdates(isSystemReady(ignoreBattery, ignoreMobile)); m_distroUpgrade->checkDistroUpgrades(); } void ApperdThread::appShouldConserveResourcesChanged() { bool ignoreBattery = m_configs[CFG_INSTALL_UP_BATTERY].value(); bool ignoreMobile = m_configs[CFG_INSTALL_UP_MOBILE].value(); if (isSystemReady(ignoreBattery, ignoreMobile)) { m_updater->setSystemReady(); } } QDateTime ApperdThread::getTimeSinceRefreshCache() const { uint value = Daemon::global()->getTimeSinceAction(Transaction::RoleRefreshCache); // When the refresh cache value was not yet defined UINT_MAX is returned if (value == UINT_MAX) { return QDateTime(); } else { // Calculate the last time the cache was refreshed by // subtracting the seconds from the current time return QDateTime::currentDateTime().addSecs(value * -1); } } bool ApperdThread::nameHasOwner(const QString &name, const QDBusConnection &connection) { QDBusMessage message; message = QDBusMessage::createMethodCall(QLatin1String("org.freedesktop.DBus"), QLatin1String("/"), QLatin1String("org.freedesktop.DBus"), QLatin1String("NameHasOwner")); message << qVariantFromValue(name); QDBusReply reply = connection.call(message); return reply.value(); } bool ApperdThread::isSystemReady(bool ignoreBattery, bool ignoreMobile) const { // First check if we should conserve resources // check how applications should behave (e.g. on battery power) // if (!ignoreBattery && Solid::PowerManagement::appShouldConserveResources()) { qCDebug(APPER_DAEMON) << "System is not ready, application should conserve resources"; // This was fixed for KDElibs 4.8.5 return false; // } // TODO it would be nice is Solid provided this // so we wouldn't be waking up PackageKit for this Solid task. Daemon::Network network = Daemon::global()->networkState(); // test whether network is connected if (network == Daemon::NetworkOffline || network == Daemon::NetworkUnknown) { qCDebug(APPER_DAEMON) << "System is not ready, network state" << network; return false; } // check how applications should behave (e.g. on battery power) if (!ignoreMobile && network == Daemon::NetworkMobile) { qCDebug(APPER_DAEMON) << "System is not ready, network state" << network; return false; } return true; } diff --git a/apperd/DBusInterface.cpp b/apperd/DBusInterface.cpp index d13a612..8409211 100644 --- a/apperd/DBusInterface.cpp +++ b/apperd/DBusInterface.cpp @@ -1,122 +1,121 @@ /*************************************************************************** * Copyright (C) 2008-2011 Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ #include "DBusInterface.h" #include "apperdadaptor.h" #include #ifdef HAVE_DEBCONFKDE #include #include #include using namespace PackageKit; #endif #include Q_DECLARE_LOGGING_CATEGORY(APPER_DAEMON) DBusInterface::DBusInterface(QObject *parent) : QObject(parent) { qCDebug(APPER_DAEMON) << "Creating Helper"; (void) new ApperdAdaptor(this); - if (!QDBusConnection::sessionBus().registerService("org.kde.apperd")) { + if (!QDBusConnection::sessionBus().registerService(QStringLiteral("org.kde.apperd"))) { qCDebug(APPER_DAEMON) << "another helper is already running"; return; } - if (!QDBusConnection::sessionBus().registerObject("/", this)) { + if (!QDBusConnection::sessionBus().registerObject(QStringLiteral("/"), this)) { qCDebug(APPER_DAEMON) << "unable to register service interface to dbus"; return; } } DBusInterface::~DBusInterface() { qCDebug(APPER_DAEMON) << "-------------DBusInterface-------------" << QThread::currentThreadId(); } void DBusInterface::RefreshCache() { emit refreshCache(); } void DBusInterface::SetupDebconfDialog(const QString &tid, const QString &socketPath, uint xidParent) { #ifdef HAVE_DEBCONFKDE qCDebug(APPER_DAEMON) << tid << socketPath << xidParent; DebconfGui *gui; if (m_debconfGuis.contains(socketPath)) { gui = m_debconfGuis[socketPath]; } else { // Create the Transaction object to delete // the DebconfGui class when the transaction finishes - Transaction *transaction = new Transaction(QDBusObjectPath(tid)); + auto transaction = new Transaction(QDBusObjectPath(tid)); transaction->setProperty("socketPath", socketPath); - connect(transaction, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), - this, SLOT(transactionFinished())); + connect(transaction, &Transaction::finished, this, &DBusInterface::transactionFinished); // Setup the Debconf dialog gui = new DebconfGui(socketPath); gui->setWindowModality(Qt::WindowModal); gui->setWindowFlags(Qt::Dialog); m_debconfGuis[socketPath] = gui; connect(gui, SIGNAL(activated()), this, SLOT(debconfActivate())); connect(gui, SIGNAL(deactivated()), gui, SLOT(hide())); } gui->setProperty("xidParent", xidParent); #else Q_UNUSED(tid) Q_UNUSED(socketPath) Q_UNUSED(xidParent) qCDebug(APPER_DAEMON) << "Not compiled with Debconf support - ignoring"; #endif //HAVE_DEBCONFKDE } void DBusInterface::WatchTransaction(const QDBusObjectPath &tid) { emit watchTransaction(tid); } void DBusInterface::debconfActivate() { #ifdef HAVE_DEBCONFKDE // Correct the parent qCDebug(APPER_DAEMON); DebconfGui *gui = qobject_cast(sender()); uint xidParent = gui->property("xidParent").toUInt(); KWindowSystem::setMainWindow(gui, xidParent); gui->show(); #endif } void DBusInterface::transactionFinished() { #ifdef HAVE_DEBCONFKDE QString socketPath = sender()->property("socketPath").toString(); if (m_debconfGuis.contains(socketPath)) { // remove the gui from the list and also delete it m_debconfGuis.take(socketPath)->deleteLater(); } #endif // HAVE_DEBCONFKDE } diff --git a/apperd/DistroUpgrade.cpp b/apperd/DistroUpgrade.cpp index 4fc2751..da74be7 100644 --- a/apperd/DistroUpgrade.cpp +++ b/apperd/DistroUpgrade.cpp @@ -1,181 +1,176 @@ /*************************************************************************** - * Copyright (C) 2009-2011 by Daniel Nicoletti * + * Copyright (C) 2009-2018 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "DistroUpgrade.h" #include #include #include #include #include #include Q_DECLARE_LOGGING_CATEGORY(APPER_DAEMON) DistroUpgrade::DistroUpgrade(QObject *parent) : QObject(parent), m_distroUpgradeProcess(0), m_transaction(0) { } DistroUpgrade::~DistroUpgrade() { } void DistroUpgrade::setConfig(const QVariantHash &configs) { m_configs = configs; } void DistroUpgrade::checkDistroUpgrades() { // Ignore check if the user disabled it if (m_configs[CFG_DISTRO_UPGRADE].toInt() == Enum::DistroNever) { return; } if (!m_transaction) { m_transaction = Daemon::getDistroUpgrades(); - connect(m_transaction, SIGNAL(distroUpgrade(PackageKit::Transaction::DistroUpgrade,QString,QString)), - this, SLOT(distroUpgrade(PackageKit::Transaction::DistroUpgrade,QString,QString))); - connect(m_transaction, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), - this, SLOT(checkDistroFinished(PackageKit::Transaction::Exit,uint))); - + connect(m_transaction, &Transaction::distroUpgrade, this, &DistroUpgrade::distroUpgrade); + connect(m_transaction, &Transaction::finished, this, &DistroUpgrade::checkDistroFinished); } } void DistroUpgrade::distroUpgrade(PackageKit::Transaction::DistroUpgrade type, const QString &name, const QString &description) { // TODO make use of the type switch (m_configs[CFG_DISTRO_UPGRADE].toInt()) { case Enum::DistroNever: return; case Enum::DistroStable: if (type != Transaction::DistroUpgradeStable) { // The user only wants to know about stable releases return; } default: break; } qCDebug(APPER_DAEMON) << "Distro upgrade found!" << name << description; if (m_shownDistroUpgrades.contains(name)) { // ignore distro upgrade if the user already saw it return; } - KNotification *notify = new KNotification("DistroUpgradeAvailable", 0, KNotification::Persistent); + auto notify = new KNotification("DistroUpgradeAvailable", 0, KNotification::Persistent); notify->setComponentName("apperd"); notify->setTitle(i18n("Distribution upgrade available")); notify->setText(description); QStringList actions; actions << i18n("Start upgrade now"); notify->setActions(actions); connect(notify, SIGNAL(activated(uint)), this, SLOT(handleDistroUpgradeAction(uint))); notify->sendEvent(); m_shownDistroUpgrades << name; } void DistroUpgrade::checkDistroFinished(Transaction::Exit status, uint enlapsed) { Q_UNUSED(status) Q_UNUSED(enlapsed) m_transaction = 0; } void DistroUpgrade::handleDistroUpgradeAction(uint action) { // get the sender cause there might be more than one auto notify = qobject_cast(sender()); switch(action) { case 1: // Check to see if there isn't another process running if (m_distroUpgradeProcess) { // if so we BREAK otherwise our running count gets // lost, and we leak as we don't close the caller. break; } m_distroUpgradeProcess = new QProcess; - connect (m_distroUpgradeProcess, SIGNAL(error(QProcess::ProcessError)), - this, SLOT(distroUpgradeError(QProcess::ProcessError))); - connect (m_distroUpgradeProcess, SIGNAL(finished(int,QProcess::ExitStatus)), - this, SLOT(distroUpgradeFinished(int,QProcess::ExitStatus))); + connect (m_distroUpgradeProcess, &QProcess::errorOccurred, this, &DistroUpgrade::distroUpgradeError); + connect (m_distroUpgradeProcess, QOverload::of(&QProcess::finished), this, &DistroUpgrade::distroUpgradeFinished); QStringList env = QProcess::systemEnvironment(); - env << "DESKTOP=kde"; + env.append(QStringLiteral("DESKTOP=kde")); m_distroUpgradeProcess->setEnvironment(env); - m_distroUpgradeProcess->start("/usr/share/PackageKit/pk-upgrade-distro.sh"); + m_distroUpgradeProcess->start(QStringLiteral("/usr/share/PackageKit/pk-upgrade-distro.sh")); // TODO // suppressSleep(true); break; // perhaps more actions needed in the future } // in persistent mode we need to manually close it notify->close(); } void DistroUpgrade::distroUpgradeFinished(int exitCode, QProcess::ExitStatus exitStatus) { auto notify = new KNotification("DistroUpgradeFinished"); notify->setComponentName("apperd"); if (exitStatus == QProcess::NormalExit && exitCode == 0) { notify->setPixmap(QIcon::fromTheme("security-high").pixmap(64, 64)); notify->setText(i18n("Distribution upgrade finished. ")); } else if (exitStatus == QProcess::NormalExit) { notify->setPixmap(QIcon::fromTheme("dialog-warning").pixmap(64, 64)); notify->setText(i18n("Distribution upgrade process exited with code %1.", exitCode)); }/* else { notify->setText(i18n("Distribution upgrade didn't exit normally, the process probably crashed. ")); }*/ notify->sendEvent(); m_distroUpgradeProcess->deleteLater(); m_distroUpgradeProcess = 0; // suppressSleep(false); } void DistroUpgrade::distroUpgradeError(QProcess::ProcessError error) { QString text; auto notify = new KNotification("DistroUpgradeError"); notify->setComponentName("apperd"); switch(error) { case QProcess::FailedToStart: text = i18n("The distribution upgrade process failed to start."); break; case QProcess::Crashed: text = i18n("The distribution upgrade process crashed some time after starting successfully.") ; break; default: text = i18n("The distribution upgrade process failed with an unknown error."); break; } notify->setPixmap(QIcon::fromTheme("dialog-error").pixmap(64,64)); notify->setText(text); notify->sendEvent(); } -#include "DistroUpgrade.moc" +#include "moc_DistroUpgrade.cpp" diff --git a/apperd/RebootListener.cpp b/apperd/RebootListener.cpp index 4a6f0b8..b7c50b5 100644 --- a/apperd/RebootListener.cpp +++ b/apperd/RebootListener.cpp @@ -1,56 +1,59 @@ /* Copyright (c) 2010 Sune Vuorela * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ #include "RebootListener.h" #include #include #include #include #include -static const char reboot_required_path[] = "/run/reboot-required"; +static const QString reboot_required_path = QStringLiteral("/run/reboot-required"); -AptRebootListener::AptRebootListener(QObject* parent): QObject(parent) { - m_watcher = new KDirWatch(this); - m_watcher->addFile(QString::fromLatin1(reboot_required_path)); - connect(m_watcher,SIGNAL(created(QString)),this,SLOT(slotDirectoryChanged(QString))); - m_timer = new QTimer(this); - m_timer->setSingleShot(true); - m_timer->setInterval(500); - connect(m_timer,SIGNAL(timeout()),SIGNAL(requestReboot())); +AptRebootListener::AptRebootListener(QObject *parent): QObject(parent) +{ + m_watcher = new KDirWatch(this); + m_watcher->addFile(reboot_required_path); + connect(m_watcher, &KDirWatch::created, this, &AptRebootListener::slotDirectoryChanged); + m_timer = new QTimer(this); + m_timer->setSingleShot(true); + m_timer->setInterval(500); + connect(m_timer, &QTimer::timeout, this, &AptRebootListener::requestReboot); } -void AptRebootListener::checkForReboot() { - if(QFile::exists(QString::fromLatin1(reboot_required_path))) { - m_timer->start(); - } +void AptRebootListener::checkForReboot() +{ + if (QFile::exists(reboot_required_path)) { + m_timer->start(); + } } -void AptRebootListener::slotDirectoryChanged(const QString& path) { - if(path==QLatin1String(reboot_required_path)) { - m_timer->start(); - } +void AptRebootListener::slotDirectoryChanged(const QString &path) +{ + if (path == reboot_required_path) { + m_timer->start(); + } } #include diff --git a/apperd/RebootListener.h b/apperd/RebootListener.h index 9dff245..4d2cafb 100644 --- a/apperd/RebootListener.h +++ b/apperd/RebootListener.h @@ -1,47 +1,51 @@ /* Copyright (c) 2010 Sune Vuorela * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ #ifndef REBOOT_LISTENER_H #define REBOOT_LISTENER_H #include class KDirWatch; class QTimer; class AptRebootListener : public QObject { - Q_OBJECT - public: - AptRebootListener(QObject* parent=0); - Q_SIGNALS: - void requestReboot(); - public Q_SLOTS: - void checkForReboot(); - private Q_SLOTS: - void slotDirectoryChanged(const QString& path); - private: - KDirWatch* m_watcher; - QTimer* m_timer; + Q_OBJECT +public: + AptRebootListener(QObject* parent = nullptr); + +Q_SIGNALS: + void requestReboot(); + +public Q_SLOTS: + void checkForReboot(); + +private Q_SLOTS: + void slotDirectoryChanged(const QString &path); + +private: + KDirWatch *m_watcher; + QTimer *m_timer; }; #endif // REBOOT_LISTENER_H diff --git a/apperd/RefreshCacheTask.cpp b/apperd/RefreshCacheTask.cpp index d843763..d0578b0 100644 --- a/apperd/RefreshCacheTask.cpp +++ b/apperd/RefreshCacheTask.cpp @@ -1,87 +1,85 @@ /*************************************************************************** * Copyright (C) 2012 by Daniel Nicoletti dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "RefreshCacheTask.h" #include #include #include #include #include RefreshCacheTask::RefreshCacheTask(QObject *parent) : QObject(parent), m_transaction(0), m_notification(0), m_lastError(Transaction::ErrorUnknown), m_cacheAge(3600) { } void RefreshCacheTask::refreshCache() { // kDebug(); if (!m_transaction) { // Refresh Cache is false otherwise it will rebuild // the whole cache on Fedora - Daemon::setHints (QLatin1String("cache-age=")+QString::number(m_cacheAge)); + Daemon::setHints (QLatin1String("cache-age=") + QString::number(m_cacheAge)); m_transaction = Daemon::refreshCache(false); - connect(m_transaction, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), - this, SLOT(refreshCacheFinished(PackageKit::Transaction::Exit,uint))); - connect(m_transaction, SIGNAL(errorCode(PackageKit::Transaction::Error,QString)), - this, SLOT(errorCode(PackageKit::Transaction::Error,QString))); + connect(m_transaction, &Transaction::finished, this, &RefreshCacheTask::refreshCacheFinished); + connect(m_transaction, &Transaction::errorCode, this, &RefreshCacheTask::errorCode); } } void RefreshCacheTask::refreshCacheFinished(PackageKit::Transaction::Exit status, uint runtime) { Q_UNUSED(runtime) m_transaction = 0; if (status == Transaction::ExitSuccess) { m_lastError = Transaction::ErrorUnknown; m_lastErrorString.clear(); } } void RefreshCacheTask::errorCode(Transaction::Error error, const QString &errorMessage) { if (m_notification || (m_lastError == error && m_lastErrorString == errorMessage)) { return; } m_notification = new KNotification("TransactionFailed", KNotification::Persistent, this); m_notification->setComponentName("apperd"); - connect(m_notification, SIGNAL(closed()), this, SLOT(notificationClosed())); + connect(m_notification, &KNotification::closed, this, &RefreshCacheTask::notificationClosed); QIcon icon = QIcon::fromTheme("dialog-cancel"); // use of QSize does the right thing m_notification->setPixmap(icon.pixmap(QSize(KPK_ICON_SIZE, KPK_ICON_SIZE))); m_notification->setTitle(PkStrings::error(error)); m_notification->setText(errorMessage); m_notification->sendEvent(); } void RefreshCacheTask::notificationClosed() { m_notification->deleteLater(); m_notification = 0; } diff --git a/apperd/TransactionJob.cpp b/apperd/TransactionJob.cpp index 2522d50..bfd429a 100644 --- a/apperd/TransactionJob.cpp +++ b/apperd/TransactionJob.cpp @@ -1,199 +1,188 @@ /*************************************************************************** * Copyright (C) 2008-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "TransactionJob.h" #include #include #include //#include #include #include Q_DECLARE_LOGGING_CATEGORY(APPER_DAEMON) TransactionJob::TransactionJob(Transaction *transaction, QObject *parent) : KJob(parent), m_transaction(transaction), m_status(transaction->status()), m_role(transaction->role()), m_flags(transaction->transactionFlags()), m_percentage(0), m_speed(0), m_downloadSizeRemainingTotal(0), m_finished(false) { setCapabilities(Killable); - connect(transaction, SIGNAL(roleChanged()), - SLOT(updateJob())); - connect(transaction, SIGNAL(statusChanged()), - SLOT(updateJob())); - connect(transaction, SIGNAL(downloadSizeRemainingChanged()), - SLOT(updateJob())); - connect(transaction, SIGNAL(transactionFlagsChanged()), - SLOT(updateJob())); - connect(transaction, SIGNAL(percentageChanged()), - SLOT(updateJob())); - connect(transaction, SIGNAL(roleChanged()), - SLOT(updateJob())); - connect(transaction, SIGNAL(speedChanged()), - SLOT(updateJob())); - connect(transaction, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), - this, SLOT(finished(PackageKit::Transaction::Exit))); - connect(transaction, SIGNAL(package(PackageKit::Transaction::Info,QString,QString)), - this, SLOT(package(PackageKit::Transaction::Info,QString,QString))); - connect(transaction, SIGNAL(repoDetail(QString,QString,bool)), - this, SLOT(repoDetail(QString,QString))); + connect(transaction, &Transaction::roleChanged, this, &TransactionJob::updateJob); + connect(transaction, &Transaction::statusChanged, this, &TransactionJob::updateJob); + connect(transaction, &Transaction::downloadSizeRemainingChanged, this, &TransactionJob::updateJob); + connect(transaction, &Transaction::transactionFlagsChanged, this, &TransactionJob::updateJob); + connect(transaction, &Transaction::percentageChanged, this, &TransactionJob::updateJob); + connect(transaction, &Transaction::speedChanged, this, &TransactionJob::updateJob); + connect(transaction, &Transaction::finished, this, &TransactionJob::finished); + connect(transaction, &Transaction::package, this, &TransactionJob::package); + connect(transaction, &Transaction::repoDetail, this, &TransactionJob::repoDetail); } TransactionJob::~TransactionJob() { } void TransactionJob::finished(PackageKit::Transaction::Exit exit) { if (m_finished) { return; } // emit the description so the Speed: xxx KiB/s // don't get confused to a destination URL emit description(this, PkStrings::action(m_role, m_flags)); if (exit == Transaction::ExitCancelled || exit == Transaction::ExitFailed) { setError(KilledJobError); } m_finished = true; emitResult(); } void TransactionJob::package(Transaction::Info info, const QString &packageID, const QString &summary) { Q_UNUSED(summary) if (!packageID.isEmpty()) { bool changed = false; if (info == Transaction::InfoFinished) { changed = m_packages.removeOne(Transaction::packageName(packageID)); } else if (!m_packages.contains(Transaction::packageName(packageID))) { m_packages << Transaction::packageName(packageID); changed = true; } if (changed) { m_details = m_packages.join(QLatin1String(", ")); emitDescription(); } } } void TransactionJob::repoDetail(const QString &repoId, const QString &repoDescription) { Q_UNUSED(repoId) QString first = PkStrings::status(m_status); emit description(this, PkStrings::action(m_role, m_flags), qMakePair(first, repoDescription)); } void TransactionJob::emitDescription() { QString details = m_details; if (details.isEmpty()) { details = QLatin1String("..."); } QString first = PkStrings::status(m_status); emit description(this, PkStrings::action(m_role, m_flags), qMakePair(first, details)); } void TransactionJob::updateJob() { Transaction::Role role = m_transaction->role(); Transaction::TransactionFlags flags = m_transaction->transactionFlags(); if (m_role != role || m_flags != flags) { m_role = role; m_flags = flags; emitDescription(); } // Status & Speed Transaction::Status status = m_transaction->status(); if (m_status != status) { m_status = status; emitDescription(); } uint percentage = m_transaction->percentage(); if (percentage <= 100) { emitPercent(percentage, 100); } else if (m_percentage != 0) { percentage = 0; emitPercent(0, 0); } m_percentage = percentage; uint speed = m_transaction->speed(); if (m_speed != speed) { m_speed = speed; emitSpeed(m_speed); } if (m_downloadSizeRemainingTotal == 0) { m_downloadSizeRemainingTotal = m_transaction->downloadSizeRemaining(); } if (m_downloadSizeRemainingTotal) { qulonglong processed; processed = m_downloadSizeRemainingTotal - m_transaction->downloadSizeRemaining(); emitPercent(processed, m_downloadSizeRemainingTotal); } } void TransactionJob::start() { m_role = Transaction::RoleUnknown; m_speed = 0; m_downloadSizeRemainingTotal = 0; m_details = Transaction::packageName(m_transaction->lastPackage()); updateJob(); } bool TransactionJob::isFinished() const { return m_finished; } Transaction *TransactionJob::transaction() const { return m_transaction; } bool TransactionJob::doKill() { // emit the description so the Speed: xxx KiB/s // don't get confused to a destination URL emit description(this, PkStrings::action(m_role, m_flags)); m_transaction->cancel(); emit canceled(); return m_transaction->role() == Transaction::RoleCancel; } #include "TransactionJob.moc" diff --git a/apperd/TransactionWatcher.cpp b/apperd/TransactionWatcher.cpp index 0fbaa5b..3167075 100644 --- a/apperd/TransactionWatcher.cpp +++ b/apperd/TransactionWatcher.cpp @@ -1,357 +1,343 @@ /*************************************************************************** * Copyright (C) 2008-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "TransactionWatcher.h" #include "TransactionJob.h" #include #include #include #include #include #include #include //#include //#include #include #include #include #include #include Q_DECLARE_LOGGING_CATEGORY(APPER_DAEMON) TransactionWatcher::TransactionWatcher(bool packagekitIsRunning, QObject *parent) : QObject(parent), m_inhibitCookie(-1) { m_tracker = new KUiServerJobTracker(this); // keep track of new transactions - connect(Daemon::global(), SIGNAL(transactionListChanged(QStringList)), - this, SLOT(transactionListChanged(QStringList))); + connect(Daemon::global(), &Daemon::transactionListChanged, this, &TransactionWatcher::transactionListChanged); // if PackageKit is running check to see if there are running transactons already if (packagekitIsRunning) { // here we check whether a transaction job should be created or not - QList paths = Daemon::global()->getTransactionList(); QStringList tids; - foreach (const QDBusObjectPath &path, paths) { + const QList paths = Daemon::global()->getTransactionList(); + for (const QDBusObjectPath &path : paths) { tids << path.path(); } transactionListChanged(tids); } } TransactionWatcher::~TransactionWatcher() { // release any cookie that we might have suppressSleep(false, m_inhibitCookie); } +void TransactionWatcher::watchTransactionInteractive(const QDBusObjectPath &tid) +{ + watchTransaction(tid); +} + void TransactionWatcher::transactionListChanged(const QStringList &tids) { if (tids.isEmpty()) { // release any cookie that we might have suppressSleep(false, m_inhibitCookie); } else { - foreach (const QString &tid, tids) { + for (const QString &tid : tids) { watchTransaction(QDBusObjectPath(tid), false); } } } void TransactionWatcher::watchTransaction(const QDBusObjectPath &tid, bool interactive) { Transaction *transaction; if (!m_transactions.contains(tid)) { // Check if the current transaction is still the same transaction = new Transaction(tid); - connect(transaction, SIGNAL(roleChanged()), this, SLOT(transactionReady())); - connect(transaction, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), - this, SLOT(finished(PackageKit::Transaction::Exit))); + connect(transaction, &Transaction::roleChanged, this, &TransactionWatcher::transactionReady); + connect(transaction, &Transaction::finished, this, &TransactionWatcher::finished); // Store the transaction id m_transactions[tid] = transaction; } else { transaction = m_transactions[tid]; if (transaction->role() != Transaction::RoleUnknown) { // force the first changed or create a TransactionJob transactionChanged(transaction, interactive); } } } void TransactionWatcher::transactionReady() { - Transaction *transaction = qobject_cast(sender()); + auto transaction = qobject_cast(sender()); Transaction::Role role = transaction->role(); Transaction::TransactionFlags flags = transaction->transactionFlags(); if (!(flags & Transaction::TransactionFlagOnlyDownload || flags & Transaction::TransactionFlagSimulate) && (role == Transaction::RoleInstallPackages || role == Transaction::RoleInstallFiles || role == Transaction::RoleRemovePackages || role == Transaction::RoleUpdatePackages)) { // AVOID showing messages and restart requires when // the user was just simulating an instalation - connect(transaction, SIGNAL(message(PackageKit::Transaction::Message,QString)), - this, SLOT(message(PackageKit::Transaction::Message,QString))); - connect(transaction, SIGNAL(requireRestart(PackageKit::Transaction::Restart,QString)), - this, SLOT(requireRestart(PackageKit::Transaction::Restart,QString))); + connect(transaction, &Transaction::requireRestart, this, &TransactionWatcher::requireRestart); // Don't let the system sleep while doing some sensible actions suppressSleep(true, m_inhibitCookie, PkStrings::action(role, flags)); } - connect(transaction, SIGNAL(isCallerActiveChanged()), - SLOT(transactionChanged())); + connect(transaction, &Transaction::isCallerActiveChanged, this, [this, transaction] () { + transactionChanged(transaction); + }); } void TransactionWatcher::showRebootNotificationApt() { // Create the notification about this transaction - KNotification *notify = new KNotification("RestartRequired", 0, KNotification::Persistent); - connect(notify, SIGNAL(activated(uint)), this, SLOT(logout())); + auto notify = new KNotification("RestartRequired", 0, KNotification::Persistent); + connect(notify, QOverload::of(&KNotification::activated), this, &TransactionWatcher::logout); notify->setComponentName("apperd"); QString text("" + i18n("The system update has completed") + ""); text.append("
" + PkStrings::restartType(Transaction::RestartSystem)); notify->setPixmap(PkIcons::restartIcon(Transaction::RestartSystem).pixmap(KPK_ICON_SIZE, KPK_ICON_SIZE)); notify->setText(text); // TODO RestartApplication should be handled differently QStringList actions; actions << i18n("Restart"); notify->setActions(actions); notify->sendEvent(); } void TransactionWatcher::finished(PackageKit::Transaction::Exit exit) { // check if the transaction emitted any require restart - Transaction *transaction = qobject_cast(sender()); + auto transaction = qobject_cast(sender()); QDBusObjectPath tid = transaction->tid(); transaction->disconnect(this); m_transactions.remove(tid); m_transactionJob.remove(tid); if (exit == Transaction::ExitSuccess && !transaction->property("restartType").isNull()) { Transaction::Restart type = transaction->property("restartType").value(); QStringList restartPackages = transaction->property("restartPackages").toStringList(); // Create the notification about this transaction - KNotification *notify = new KNotification("RestartRequired", 0, KNotification::Persistent); - connect(notify, SIGNAL(activated(uint)), this, SLOT(logout())); + auto notify = new KNotification("RestartRequired", 0, KNotification::Persistent); + connect(notify, QOverload::of(&KNotification::activated), this, &TransactionWatcher::logout); notify->setComponentName("apperd"); notify->setProperty("restartType", qVariantFromValue(type)); notify->setPixmap(PkIcons::restartIcon(type).pixmap(KPK_ICON_SIZE, KPK_ICON_SIZE)); notify->setTitle(PkStrings::restartType(type)); // Create a readable text with package names that required the restart if (!restartPackages.isEmpty()) { restartPackages.removeDuplicates(); restartPackages.sort(); QString text; text = i18np("Package: %2", "Packages: %2", restartPackages.size(), restartPackages.join(QLatin1String(", "))); notify->setText(text); } // TODO RestartApplication should be handled differently QStringList actions; actions << i18n("Restart"); notify->setActions(actions); notify->sendEvent(); } } void TransactionWatcher::transactionChanged(Transaction *transaction, bool interactive) { if (!transaction) { transaction = qobject_cast(sender()); } QDBusObjectPath tid = transaction->tid(); if (!interactive) { interactive = !transaction->isCallerActive(); } // If the if (!m_transactionJob.contains(tid) && interactive) { - TransactionJob *job = new TransactionJob(transaction, this); - connect(transaction, SIGNAL(errorCode(PackageKit::Transaction::Error,QString)), - this, SLOT(errorCode(PackageKit::Transaction::Error,QString))); - connect(job, SIGNAL(canceled()), this, SLOT(watchedCanceled())); + auto job = new TransactionJob(transaction, this); + connect(transaction, &Transaction::errorCode, this, &TransactionWatcher::errorCode); + connect(job, &TransactionJob::canceled, this, &TransactionWatcher::watchedCanceled); m_tracker->registerJob(job); m_transactionJob[tid] = job; job->start(); } } -//void TransactionWatcher::message(PackageKit::Transaction::Message type, const QString &message) -//{ -// KNotification *notify; -// notify = new KNotification("TransactionMessage", 0, KNotification::Persistent); -// notify->setComponentName("apperd"); -// notify->setTitle(PkStrings::message(type)); -// notify->setText(message); - -// notify->setPixmap(QIcon::fromTheme("dialog-warning").pixmap(KPK_ICON_SIZE, KPK_ICON_SIZE)); -// notify->sendEvent(); -//} - void TransactionWatcher::errorCode(PackageKit::Transaction::Error err, const QString &details) { - KNotification *notify; - notify = new KNotification("TransactionError", 0, KNotification::Persistent); + auto notify = new KNotification("TransactionError", 0, KNotification::Persistent); notify->setComponentName("apperd"); notify->setTitle(PkStrings::error(err)); notify->setText(PkStrings::errorMessage(err)); notify->setProperty("ErrorType", QVariant::fromValue(err)); notify->setProperty("Details", details); QStringList actions; actions << i18n("Details"); notify->setActions(actions); notify->setPixmap(QIcon::fromTheme("dialog-error").pixmap(KPK_ICON_SIZE, KPK_ICON_SIZE)); - connect(notify, SIGNAL(activated(uint)), - this, SLOT(errorActivated(uint))); + connect(notify, QOverload::of(&KNotification::activated), this, &TransactionWatcher::errorActivated); notify->sendEvent(); } void TransactionWatcher::errorActivated(uint action) { - KNotification *notify = qobject_cast(sender()); + auto notify = qobject_cast(sender()); // if the user clicked "Details" if (action == 1) { Transaction::Error error = notify->property("ErrorType").value(); QString details = notify->property("Details").toString(); KMessageBox::detailedSorry(0, PkStrings::errorMessage(error), details.replace('\n', "
"), PkStrings::error(error), KMessageBox::Notify); } notify->close(); } void TransactionWatcher::requireRestart(PackageKit::Transaction::Restart type, const QString &packageID) { - Transaction *transaction = qobject_cast(sender()); + auto transaction = qobject_cast(sender()); if (transaction->property("restartType").isNull()) { transaction->setProperty("restartType", qVariantFromValue(type)); } else { Transaction::Restart oldType; oldType = transaction->property("restartType").value(); int old = PackageImportance::restartImportance(oldType); int newer = PackageImportance::restartImportance(type); // Check to see which one is more important if (newer > old) { transaction->setProperty("restartType", qVariantFromValue(type)); } } if (!Transaction::packageName(packageID).isEmpty()) { QStringList restartPackages = transaction->property("restartPackages").toStringList(); restartPackages << Transaction::packageName(packageID); transaction->setProperty("restartPackages", restartPackages); } } void TransactionWatcher::logout() { - KNotification *notify = qobject_cast(sender()); + auto notify = qobject_cast(sender()); Transaction::Restart restartType; restartType = notify->property("restartType").value(); KWorkSpace::ShutdownType shutdownType; switch (restartType) { case Transaction::RestartSystem: case Transaction::RestartSecuritySystem: // The restart type was system shutdownType = KWorkSpace::ShutdownTypeReboot; break; case Transaction::RestartSession: case Transaction::RestartSecuritySession: // The restart type was session shutdownType = KWorkSpace::ShutdownTypeLogout; break; default: qCWarning(APPER_DAEMON) << "Unknown restart type:" << restartType; return; } // We call KSM server to restart or logout our system KWorkSpace::requestShutDown(KWorkSpace::ShutdownConfirmYes, shutdownType, KWorkSpace::ShutdownModeInteractive); } void TransactionWatcher::watchedCanceled() { - TransactionJob *job = qobject_cast(sender()); + auto job = qobject_cast(sender()); if (job->isFinished()) { job->deleteLater(); return; } Transaction::Role role = job->transaction()->role(); if (role != Transaction::RoleCancel && role != Transaction::RoleUnknown) { m_tracker->unregisterJob(job); m_tracker->registerJob(job); job->start(); } } void TransactionWatcher::suppressSleep(bool enable, int &inhibitCookie, const QString &reason) { if (inhibitCookie == -1) { return; } if (enable) { qCDebug(APPER_DAEMON) << "Begin Suppressing Sleep"; // inhibitCookie = Solid::PowerManagement::beginSuppressingSleep(reason); if (inhibitCookie == -1) { qCDebug(APPER_DAEMON) << "Sleep suppression denied!"; } } else { qCDebug(APPER_DAEMON) << "Stop Suppressing Sleep"; // if (!Solid::PowerManagement::stopSuppressingSleep(inhibitCookie)) { qCDebug(APPER_DAEMON) << "Stop failed: invalid cookie."; // } inhibitCookie = -1; } } diff --git a/apperd/TransactionWatcher.h b/apperd/TransactionWatcher.h index b46390c..c3359e5 100644 --- a/apperd/TransactionWatcher.h +++ b/apperd/TransactionWatcher.h @@ -1,72 +1,72 @@ /*************************************************************************** * Copyright (C) 2008-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef TRANSACTION_WATCHER_H #define TRANSACTION_WATCHER_H //#include "AbstractIsRunning.h" #include #include #include using namespace PackageKit; class TransactionJob; class TransactionWatcher : public QObject { Q_OBJECT public: explicit TransactionWatcher(bool packagekitIsRunning, QObject *parent = 0); ~TransactionWatcher(); public Q_SLOTS: + void watchTransactionInteractive(const QDBusObjectPath &tid); void watchTransaction(const QDBusObjectPath &tid, bool interactive = true); void transactionReady(); void showRebootNotificationApt(); private Q_SLOTS: void transactionListChanged(const QStringList &tids); -// void message(PackageKit::Transaction::Message type, const QString &message); void errorCode(PackageKit::Transaction::Error, const QString &); void errorActivated(uint action); void requireRestart(PackageKit::Transaction::Restart type, const QString &packageID); void finished(PackageKit::Transaction::Exit exit); void transactionChanged(Transaction *transaction = 0, bool interactive = false); void logout(); void watchedCanceled(); private: static void suppressSleep(bool enable, int &inhibitCookie, const QString &reason = QString()); // Hash of transactions we are watching QHash m_transactions; QHash m_transactionJob; // cookie to suppress sleep int m_inhibitCookie; KUiServerJobTracker *m_tracker; }; #endif diff --git a/apperd/Updater.cpp b/apperd/Updater.cpp index 81fff06..ee6ada7 100644 --- a/apperd/Updater.cpp +++ b/apperd/Updater.cpp @@ -1,324 +1,323 @@ /*************************************************************************** * Copyright (C) 2008 by Trever Fischer * * wm161@wm161.net * * Copyright (C) 2008-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "Updater.h" #include "ApperdThread.h" #include #include #include #include #include #include #include #include #include #include #include Q_DECLARE_LOGGING_CATEGORY(APPER_DAEMON) #define UPDATES_ICON "system-software-update" using namespace PackageKit; Updater::Updater(QObject* parent) : QObject(parent), m_getUpdatesT(0) { // in case registration fails due to another user or application running // keep an eye on it so we can register when available auto watcher = new QDBusServiceWatcher(QLatin1String("org.kde.ApperUpdaterIcon"), QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForOwnerChange, this); connect(watcher, &QDBusServiceWatcher::serviceOwnerChanged, this, &Updater::serviceOwnerChanged); m_hasAppletIconified = ApperdThread::nameHasOwner(QLatin1String("org.kde.ApperUpdaterIcon"), QDBusConnection::sessionBus()); } Updater::~Updater() { } void Updater::setConfig(const QVariantHash &configs) { m_configs = configs; } void Updater::setSystemReady() { // System ready changed, maybe we can auto // install some updates m_systemReady = true; getUpdateFinished(); } void Updater::checkForUpdates(bool systemReady) { m_systemReady = systemReady; // Skip the check if one is already running or // the plasmoid is in Icon form and the auto update type is None if (m_getUpdatesT) { return; } m_updateList.clear(); m_importantList.clear(); m_securityList.clear(); m_getUpdatesT = Daemon::getUpdates(); - connect(m_getUpdatesT, SIGNAL(package(PackageKit::Transaction::Info,QString,QString)), - this, SLOT(packageToUpdate(PackageKit::Transaction::Info,QString,QString))); - connect(m_getUpdatesT, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), - this, SLOT(getUpdateFinished())); + connect(m_getUpdatesT, &Transaction::package, this, &Updater::packageToUpdate); + connect(m_getUpdatesT, &Transaction::finished, this, &Updater::getUpdateFinished); } void Updater::packageToUpdate(Transaction::Info info, const QString &packageID, const QString &summary) { Q_UNUSED(summary) switch (info) { case Transaction::InfoBlocked: // Blocked updates are not instalable updates so there is no // reason to show/count them return; case Transaction::InfoImportant: m_importantList << packageID; break; case Transaction::InfoSecurity: m_securityList << packageID; break; default: break; } m_updateList << packageID; } void Updater::getUpdateFinished() { m_getUpdatesT = 0; if (!m_updateList.isEmpty()) { - Transaction *transaction = qobject_cast(sender()); + auto transaction = qobject_cast(sender()); bool different = false; if (m_oldUpdateList.size() != m_updateList.size()) { different = true; } else { // The lists have the same size let's make sure // all the packages are the same - foreach (const QString &packageId, m_updateList) { + const QStringList updates = m_updateList; + for (const QString &packageId : updates) { if (!m_oldUpdateList.contains(packageId)) { different = true; break; } } } // sender is not a transaction when we systemReady has changed // if the lists are the same don't show // a notification or try to upgrade again if (transaction && !different) { return; } uint updateType = m_configs[CFG_AUTO_UP].value(); if (m_systemReady && updateType == Enum::All) { // update all bool ret; ret = updatePackages(m_updateList, false, "plasmagik", i18n("Updates are being automatically installed.")); if (ret) { return; } } else if (m_systemReady && updateType == Enum::Security && !m_securityList.isEmpty()) { // Defaults to security bool ret; ret = updatePackages(m_securityList, false, UPDATES_ICON, i18n("Security updates are being automatically installed.")); if (ret) { return; } } else if (m_systemReady && updateType == Enum::DownloadOnly) { // Download all updates bool ret; ret = updatePackages(m_updateList, true, "download", i18n("Updates are being automatically downloaded.")); if (ret) { return; } } else if (!m_systemReady && (updateType == Enum::All || updateType == Enum::DownloadOnly || (updateType == Enum::Security && !m_securityList.isEmpty()))) { qCDebug(APPER_DAEMON) << "Not auto updating or downloading, as we might be on battery or mobile connection"; } // If an erro happened to create the auto update // transaction show the update list if (transaction) { // The transaction is not valid if the systemReady changed showUpdatesPopup(); } } else { m_oldUpdateList.clear(); } } void Updater::autoUpdatesFinished(PkTransaction::ExitStatus status) { - KNotification *notify = new KNotification("UpdatesComplete"); + auto notify = new KNotification("UpdatesComplete"); notify->setComponentName("apperd"); if (status == PkTransaction::Success) { if (sender()->property("DownloadOnly").toBool()) { // We finished downloading show the updates to the user showUpdatesPopup(); } else { QIcon icon = QIcon::fromTheme("task-complete"); // use of QSize does the right thing notify->setPixmap(icon.pixmap(KPK_ICON_SIZE, KPK_ICON_SIZE)); notify->setText(i18n("System update was successful.")); notify->sendEvent(); } } else { QIcon icon = QIcon::fromTheme("dialog-cancel"); // use of QSize does the right thing notify->setPixmap(icon.pixmap(KPK_ICON_SIZE, KPK_ICON_SIZE)); notify->setText(i18n("The software update failed.")); notify->sendEvent(); // show updates popup showUpdatesPopup(); } } void Updater::reviewUpdates() { if (m_hasAppletIconified) { QDBusMessage message; message = QDBusMessage::createMethodCall(QLatin1String("org.kde.ApperUpdaterIcon"), QLatin1String("/"), QLatin1String("org.kde.ApperUpdaterIcon"), QLatin1String("ReviewUpdates")); QDBusMessage reply = QDBusConnection::sessionBus().call(message); if (reply.type() == QDBusMessage::ReplyMessage) { return; } qCWarning(APPER_DAEMON) << "Message did not receive a reply"; } // This must be called from the main thread... KToolInvocation::startServiceByDesktopName("apper_updates"); } void Updater::installUpdates() { bool ret; ret = updatePackages(m_updateList, false); if (ret) { return; } reviewUpdates(); } void Updater::serviceOwnerChanged(const QString &service, const QString &oldOwner, const QString &newOwner) { Q_UNUSED(service) Q_UNUSED(oldOwner) m_hasAppletIconified = !newOwner.isEmpty(); } void Updater::showUpdatesPopup() { m_oldUpdateList = m_updateList; - KNotification *notify = new KNotification("ShowUpdates", 0, KNotification::Persistent); + auto notify = new KNotification("ShowUpdates", 0, KNotification::Persistent); notify->setComponentName("apperd"); - connect(notify, SIGNAL(action1Activated()), this, SLOT(reviewUpdates())); - connect(notify, SIGNAL(action2Activated()), this, SLOT(installUpdates())); + connect(notify, &KNotification::action1Activated, this, &Updater::reviewUpdates); + connect(notify, &KNotification::action2Activated, this, &Updater::installUpdates); notify->setTitle(i18np("There is one new update", "There are %1 new updates", m_updateList.size())); QString text; - foreach (const QString &packageId, m_updateList) { - QString packageName = Transaction::packageName(packageId); + const QStringList updates = m_updateList; + for (const QString &packageId : updates) { + const QString packageName = Transaction::packageName(packageId); if (text.length() + packageName.length() > 150) { text.append(QLatin1String(" ...")); break; } else if (!text.isNull()) { text.append(QLatin1String(", ")); } text.append(packageName); } notify->setText(text); QStringList actions; actions << i18n("Review"); if (m_hasAppletIconified) { actions << i18n("Install"); } notify->setActions(actions); // use of QSize does the right thing notify->setPixmap(QIcon::fromTheme("system-software-update").pixmap(KPK_ICON_SIZE, KPK_ICON_SIZE)); notify->sendEvent(); } bool Updater::updatePackages(const QStringList &packages, bool downloadOnly, const QString &icon, const QString &msg) { m_oldUpdateList = m_updateList; // Defaults to security - PkTransaction *transaction = new PkTransaction; + auto transaction = new PkTransaction; transaction->setProperty("DownloadOnly", downloadOnly); transaction->enableJobWatcher(true); transaction->updatePackages(packages, downloadOnly); - connect(transaction, SIGNAL(finished(PkTransaction::ExitStatus)), - this, SLOT(autoUpdatesFinished(PkTransaction::ExitStatus))); + connect(transaction, &PkTransaction::finished, this, &Updater::autoUpdatesFinished); if (!icon.isNull()) { KNotification *notify; if (downloadOnly) { notify = new KNotification("DownloadingUpdates"); } else { notify = new KNotification("AutoInstallingUpdates"); } notify->setComponentName("apperd"); notify->setText(msg); // use of QSize does the right thing notify->setPixmap(QIcon::fromTheme(icon).pixmap(QSize(KPK_ICON_SIZE, KPK_ICON_SIZE))); notify->sendEvent(); } return true; } diff --git a/declarative-plugins/DBusUpdaterInterface.cpp b/declarative-plugins/DBusUpdaterInterface.cpp index 9dad6b8..6fe6607 100644 --- a/declarative-plugins/DBusUpdaterInterface.cpp +++ b/declarative-plugins/DBusUpdaterInterface.cpp @@ -1,91 +1,91 @@ /*************************************************************************** * Copyright (C) 2008-2011 Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ #include "DBusUpdaterInterface.h" #include "apperupdatericonadaptor.h" #include #include DBusUpdaterInterface::DBusUpdaterInterface(QObject *parent) : QObject(parent), m_registered(false) { (void) new ApperUpdaterIconAdaptor(this); } DBusUpdaterInterface::~DBusUpdaterInterface() { if (m_registered) { unregisterService(); } } bool DBusUpdaterInterface::isRegistered() const { return m_registered; } void DBusUpdaterInterface::ReviewUpdates() { emit reviewUpdates(); } void DBusUpdaterInterface::registerService() { // kDebug(); - QDBusServiceWatcher *watcher = qobject_cast(sender()); + auto watcher = qobject_cast(sender()); if (!m_registered && !QDBusConnection::sessionBus().registerService(QLatin1String("org.kde.ApperUpdaterIcon"))) { // kDebug() << "unable to register service to dbus"; if (!watcher) { // in case registration fails due to another user or application running // keep an eye on it so we can register when available watcher = new QDBusServiceWatcher(QLatin1String("org.kde.ApperUpdaterIcon"), QDBusConnection::systemBus(), QDBusServiceWatcher::WatchForUnregistration, this); - connect(watcher, SIGNAL(serviceUnregistered(QString)), this, SLOT(registerService())); + connect(watcher, &QDBusServiceWatcher::serviceUnregistered, this, &DBusUpdaterInterface::registeredChanged); } m_registered = false; emit registeredChanged(); } else { if (!QDBusConnection::sessionBus().registerObject("/", this)) { // kDebug() << "unable to register service interface to dbus"; return; } m_registered = true; emit registeredChanged(); } } void DBusUpdaterInterface::unregisterService() { // We need to unregister the service since // plasma-desktop won't exit if (QDBusConnection::sessionBus().unregisterService(QLatin1String("org.kde.ApperUpdaterIcon"))) { m_registered = false; emit registeredChanged(); } else { // kDebug() << "unable to unregister service to dbus"; } } diff --git a/declarative-plugins/daemonhelper.cpp b/declarative-plugins/daemonhelper.cpp index df6740e..5db1a67 100644 --- a/declarative-plugins/daemonhelper.cpp +++ b/declarative-plugins/daemonhelper.cpp @@ -1,39 +1,39 @@ /*************************************************************************** * Copyright (C) 2012-2013 by Daniel Nicoletti * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ #include "daemonhelper.h" #include using namespace PackageKit; DaemonHelper::DaemonHelper(QObject *parent) : QObject(parent) { } uint DaemonHelper::getTimeSinceLastRefresh() { return Daemon::global()->getTimeSinceAction(Transaction::RoleRefreshCache); } void DaemonHelper::setCacheAge (int age) { - Daemon::setHints(QLatin1String("cache-age=")+QString::number(age)); + Daemon::setHints(QLatin1String("cache-age=") + QString::number(age)); } diff --git a/libapper/CategorizedView.cpp b/libapper/CategorizedView.cpp index 76fd8e6..97540cf 100644 --- a/libapper/CategorizedView.cpp +++ b/libapper/CategorizedView.cpp @@ -1,60 +1,60 @@ /*************************************************************************** * Copyright (C) 2009 by Rafael Fernández López * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * ***************************************************************************/ #include "CategorizedView.h" #include "CategoryDrawer.h" #include #include CategorizedView::CategorizedView(QWidget *parent) : KCategorizedView(parent) { setWordWrap(true); - CategoryDrawer *drawer = new CategoryDrawer(this); + auto drawer = new CategoryDrawer(this); setCategoryDrawer(drawer); } void CategorizedView::setModel(QAbstractItemModel *model) { KCategorizedView::setModel(model); // Don't set a fixed grid as this breaks the layout. Let Qt figure out the size itself #if 0 // KFileItemDelegate *delegate = qobject_cast(itemDelegate()); // kDebug() << delegate->maximumSize(); // if (delegate) { int maxWidth = -1; int maxHeight = -1; for (int i = 0; i < model->rowCount(); ++i) { const QModelIndex index = model->index(i, modelColumn(), rootIndex()); const QSize size = sizeHintForIndex(index); maxWidth = qMax(maxWidth, size.width()); maxHeight = qMax(maxHeight, size.height()); // kDebug() << size << index.data(Qt::DisplayRole); } // kDebug() << maxWidth << maxHeight; setGridSize(QSize(maxWidth, maxHeight )); // delegate->setMaximumSize(QSize(maxWidth, maxHeight)); // // } #endif } #include "moc_CategorizedView.cpp" diff --git a/libapper/CategoryMatcher.cpp b/libapper/CategoryMatcher.cpp index 4ce1e9e..0ca3ca7 100644 --- a/libapper/CategoryMatcher.cpp +++ b/libapper/CategoryMatcher.cpp @@ -1,103 +1,103 @@ /*************************************************************************** * Copyright (C) 2012 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "CategoryMatcher.h" CategoryMatcher::CategoryMatcher(Kind kind, const QString &term) : m_kind(kind), m_term(term) { } CategoryMatcher::CategoryMatcher(const CategoryMatcher &other) : m_kind(other.m_kind), m_term(other.m_term), m_child(other.m_child) { } CategoryMatcher::~CategoryMatcher() { } CategoryMatcher &CategoryMatcher::operator =(const CategoryMatcher &other) { m_kind = other.m_kind; m_term = other.m_term; m_child = other.m_child; return *this; } bool CategoryMatcher::match(const QStringList &categories) const { if (categories.isEmpty()) { return false; } bool ret = false; switch (m_kind) { case Term: ret = categories.contains(m_term); break; case And: - foreach (const CategoryMatcher &parser, m_child) { + for (const CategoryMatcher &parser : m_child) { if (!(ret = parser.match(categories))) { break; } } break; case Or: - foreach (const CategoryMatcher &parser, m_child) { + for (const CategoryMatcher &parser : m_child) { if ((ret = parser.match(categories))) { break; } } break; case Not: // We match like And but negating - foreach (const CategoryMatcher &parser, m_child) { + for (const CategoryMatcher &parser : m_child) { if (!(ret = !parser.match(categories))) { break; } } break; } return ret; } void CategoryMatcher::setChild(const QList &child) { m_child = child; } QList CategoryMatcher::child() const { return m_child; } QString CategoryMatcher::term() const { return m_term; } CategoryMatcher::Kind CategoryMatcher::kind() const { return m_kind; } diff --git a/libapper/PackageModel.cpp b/libapper/PackageModel.cpp index 4d4c8f7..30f5ea4 100644 --- a/libapper/PackageModel.cpp +++ b/libapper/PackageModel.cpp @@ -1,881 +1,879 @@ /*************************************************************************** - * Copyright (C) 2008-2011 by Daniel Nicoletti * + * Copyright (C) 2008-2018 by Daniel Nicoletti * * dantti12@gmail.com * * Copyright (C) 2008 by Trever Fischer * * wm161@wm161.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include #include "PackageModel.h" #include #include #include #include #include #include #include #include #include #ifdef HAVE_APPSTREAM #include #endif #define ICON_SIZE 22 #define OVERLAY_SIZE 16 using namespace PackageKit; PackageModel::PackageModel(QObject *parent) : QAbstractItemModel(parent), m_finished(false), m_checkable(false), m_fetchSizesTransaction(0), m_fetchInstalledVersionsTransaction(0) { m_installedEmblem = PkIcons::getIcon("dialog-ok-apply", QString()).pixmap(16, 16); m_roles[SortRole] = "rSort"; m_roles[NameRole] = "rName"; m_roles[SummaryRole] = "rSummary"; m_roles[VersionRole] = "rVersion"; m_roles[ArchRole] = "rArch"; m_roles[IconRole] = "rIcon"; m_roles[IdRole] = "rId"; m_roles[CheckStateRole] = "rChecked"; m_roles[InfoRole] = "rInfo"; m_roles[ApplicationId] = "rApplicationId"; m_roles[IsPackageRole] = "rIsPackageRole"; m_roles[PackageName] = "rPackageName"; m_roles[InfoIconRole] = "rInfoIcon"; } void PackageModel::addSelectedPackagesFromModel(PackageModel *model) { const QList packages = model->internalSelectedPackages(); for (const InternalPackage &package : packages) { addPackage(package.info, package.packageID, package.summary, true); } finished(); } void PackageModel::addNotSelectedPackage(Transaction::Info info, const QString &packageID, const QString &summary) { addPackage(info, packageID, summary); } void PackageModel::addPackage(Transaction::Info info, const QString &packageID, const QString &summary, bool selected) { if (m_finished) { qDebug() << Q_FUNC_INFO << "we are finished calling clear"; clear(); } switch(info) { case Transaction::InfoBlocked: case Transaction::InfoFinished: case Transaction::InfoCleanup: return; default: break; } #ifdef HAVE_APPSTREAM QList applications; if (!m_checkable) { applications = AppStream::instance()->applications(Transaction::packageName(packageID)); foreach (const AppStream::Application &app, applications) { InternalPackage iPackage; iPackage.info = info; iPackage.packageID = packageID; iPackage.version = Transaction::packageVersion(packageID); iPackage.arch = Transaction::packageArch(packageID); iPackage.repo = Transaction::packageData(packageID); iPackage.isPackage = false; if (app.name.isEmpty()) { iPackage.displayName = Transaction::packageName(packageID); } else { iPackage.displayName = app.name; } if (app.summary.isEmpty()) { iPackage.summary = summary; } else { iPackage.summary = app.summary; } iPackage.icon = app.icon_url; iPackage.appId = app.id; iPackage.size = 0; if (selected) { checkPackage(iPackage, false); } m_packages.append(iPackage); } } if (applications.isEmpty()) { #endif //HAVE_APPSTREAM InternalPackage iPackage; iPackage.info = info; iPackage.packageID = packageID; iPackage.displayName = Transaction::packageName(packageID); iPackage.version = Transaction::packageVersion(packageID); iPackage.arch = Transaction::packageArch(packageID); iPackage.repo = Transaction::packageData(packageID); iPackage.summary = summary; iPackage.size = 0; #ifdef HAVE_APPSTREAM iPackage.icon = AppStream::instance()->genericIcon(Transaction::packageName(packageID)); if (iPackage.icon.isEmpty()) iPackage.icon = Transaction::packageIcon(packageID); if (m_checkable) { // in case of updates model only check if it's an app applications = AppStream::instance()->applications(Transaction::packageName(packageID)); if (!applications.isEmpty() || !Transaction::packageIcon(packageID).isEmpty()) { iPackage.isPackage = false; } else { iPackage.isPackage = true; } } else { iPackage.isPackage = true; } #else iPackage.isPackage = true; #endif // HAVE_APPSTREAM if (selected) { checkPackage(iPackage, false); } m_packages.append(iPackage); #ifdef HAVE_APPSTREAM } #endif // HAVE_APPSTREAM } void PackageModel::addSelectedPackage(Transaction::Info info, const QString &packageID, const QString &summary) { addPackage(info, packageID, summary, true); } QVariant PackageModel::headerData(int section, Qt::Orientation orientation, int role) const { QVariant ret; if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { switch (section) { case NameCol: if (m_checkable) { ret = PkStrings::packageQuantity(true, m_packages.size(), m_checkedPackages.size()); } else { ret = i18n("Name"); } break; case VersionCol: ret = i18n("Version"); break; case CurrentVersionCol: ret = i18n("Installed Version"); break; case ArchCol: ret = i18n("Arch"); break; case OriginCol: ret = i18n("Origin"); break; case SizeCol: ret = i18n("Size"); break; case ActionCol: ret = i18n("Action"); break; } } return ret; } int PackageModel::rowCount(const QModelIndex &parent) const { if (parent.isValid() || !m_finished) { return 0; } return m_packages.size(); } QModelIndex PackageModel::index(int row, int column, const QModelIndex &parent) const { // kDebug() << parent.isValid() << m_packageCount << row << column; // Check to see if the index isn't out of list if (!parent.isValid() && m_packages.size() > row) { return createIndex(row, column); } return QModelIndex(); } QModelIndex PackageModel::parent(const QModelIndex &index) const { Q_UNUSED(index) return QModelIndex(); } QHash PackageModel::roleNames() const { return m_roles; } QVariant PackageModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) { return QVariant(); } const InternalPackage &package = m_packages[index.row()]; if (index.column() == NameCol) { switch (role) { case Qt::CheckStateRole: if (!m_checkable) { return QVariant(); } if (containsChecked(package.packageID)) { return Qt::Checked; } return Qt::Unchecked; case CheckStateRole: if (containsChecked(package.packageID)) { return Qt::Checked; } return Qt::Unchecked; case IsPackageRole: return package.isPackage; case Qt::DisplayRole: return package.displayName; case Qt::DecorationRole: { QPixmap icon = QPixmap(44, ICON_SIZE); icon.fill(Qt::transparent); if (!package.icon.isNull()) { QPixmap pixmap; if (package.icon.startsWith("/")) { pixmap = QPixmap(); pixmap.load(package.icon); pixmap = pixmap.scaledToHeight(ICON_SIZE); } else { pixmap = KIconLoader::global()->loadIcon(package.icon, KIconLoader::NoGroup, ICON_SIZE, KIconLoader::DefaultState, QStringList(), 0L, true); } if (!pixmap.isNull()) { QPainter painter(&icon); painter.drawPixmap(QPoint(2, 0), pixmap); } } if (package.info == Transaction::InfoInstalled || package.info == Transaction::InfoCollectionInstalled) { QPainter painter(&icon); QPoint startPoint; // bottom right corner startPoint = QPoint(44 - OVERLAY_SIZE, 4); painter.drawPixmap(startPoint, m_installedEmblem); } else if (m_checkable) { QIcon emblemIcon = PkIcons::packageIcon(package.info); QPainter painter(&icon); QPoint startPoint; // bottom right corner startPoint = QPoint(44 - OVERLAY_SIZE, 4); painter.drawPixmap(startPoint, emblemIcon.pixmap(OVERLAY_SIZE, OVERLAY_SIZE)); } return icon; } case PackageName: return Transaction::packageName(package.packageID); case Qt::ToolTipRole: if (m_checkable) { return PkStrings::info(package.info); } else { return i18n("Version: %1\nArchitecture: %2", package.version, package.arch); } } } else if (role == Qt::DisplayRole) { if (index.column() == VersionCol) { return package.version; } else if (index.column() == CurrentVersionCol) { return package.currentVersion; } else if (index.column() == ArchCol) { return package.arch; } else if (index.column() == OriginCol) { return package.repo; } else if (index.column() == SizeCol) { KFormat f; return package.size ? f.formatByteSize(package.size) : QString(); } } else if (index.column() == SizeCol && role == Qt::TextAlignmentRole) { return static_cast(Qt::AlignRight | Qt::AlignVCenter); } switch (role) { case IconRole: return package.icon; case SortRole: return QString(package.displayName % QLatin1Char(' ') % package.version % QLatin1Char(' ') % package.arch); case CheckStateRole: if (containsChecked(package.packageID)) { return Qt::Checked; } return Qt::Unchecked; case IdRole: return package.packageID; case NameRole: return package.displayName; case SummaryRole: return package.summary; case VersionRole: return package.version; case ArchRole: return package.arch; case OriginCol: return package.repo; case InfoRole: return qVariantFromValue(package.info); case KCategorizedSortFilterProxyModel::CategoryDisplayRole: if (package.info == Transaction::InfoInstalled || package.info == Transaction::InfoCollectionInstalled) { return i18n("To be Removed"); } else { return i18n("To be Installed"); } case KCategorizedSortFilterProxyModel::CategorySortRole: // USING 0 here seems to let things unsorted return package.isPackage ? 1 : 0; // Packages comes after applications case ApplicationId: return package.appId; case InfoIconRole: return PkIcons::packageIcon(package.info); default: return QVariant(); } return QVariant(); } bool PackageModel::setData(const QModelIndex &index, const QVariant &value, int role) { if (role == Qt::CheckStateRole && m_packages.size() > index.row()) { if (value.toBool()) { checkPackage(m_packages[index.row()]); } else { uncheckPackage(m_packages[index.row()].packageID); } emit changed(!m_checkedPackages.isEmpty()); return true; } return false; } Qt::ItemFlags PackageModel::flags(const QModelIndex &index) const { if (index.column() == NameCol) { return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | QAbstractItemModel::flags(index); } return QAbstractItemModel::flags(index); } int PackageModel::columnCount(const QModelIndex &parent) const { Q_UNUSED(parent); if (m_checkable) { // when the model is checkable the action column is not shown return ActionCol; } else { return ActionCol + 1; } } void PackageModel::removePackage(const QString &packageID) { int i = 0; while (i < m_packages.size()) { InternalPackage iPackage = m_packages[i]; if (iPackage.packageID == packageID && iPackage.info != Transaction::InfoUntrusted) { beginRemoveRows(QModelIndex(), i, i); m_packages.remove(i); endRemoveRows(); // since we removed one entry we don't // need to increase the counter continue; } ++i; } } void PackageModel::clear() { qDebug() << Q_FUNC_INFO; beginRemoveRows(QModelIndex(), 0, m_packages.size()); m_finished = false; m_packages.clear(); m_fetchSizesTransaction = 0; m_fetchInstalledVersionsTransaction = 0; if (m_getUpdatesTransaction) { m_getUpdatesTransaction->disconnect(this); m_getUpdatesTransaction->cancel(); } endRemoveRows(); } void PackageModel::clearSelectedNotPresent() { - foreach (const InternalPackage &package, m_checkedPackages) { + for (const InternalPackage &package : qAsConst(m_checkedPackages)) { bool notFound = true; - foreach (const InternalPackage &iPackage, m_packages) { + const QVector packages = m_packages; + for (const InternalPackage &iPackage : packages) { if (iPackage.packageID == package.packageID) { notFound = false; break; } } if (notFound) { // Uncheck the package If it's not in the model uncheckPackage(package.packageID); } } } bool PackageModel::checkable() const { return m_checkable; } void PackageModel::uncheckInstalledPackages() { - foreach (const InternalPackage &package, m_checkedPackages) { + for (const InternalPackage &package : qAsConst(m_checkedPackages)) { if (package.info == Transaction::InfoInstalled || package.info == Transaction::InfoCollectionInstalled) { uncheckPackage(package.packageID, true); } } } void PackageModel::uncheckAvailablePackages() { - foreach (const InternalPackage &package, m_checkedPackages) { + for (const InternalPackage &package : qAsConst(m_checkedPackages)) { if (package.info == Transaction::InfoAvailable || package.info == Transaction::InfoCollectionAvailable) { uncheckPackage(package.packageID, true); } } } void PackageModel::finished() { - Transaction *trans = qobject_cast(sender()); + auto trans = qobject_cast(sender()); qDebug() << Q_FUNC_INFO << trans << sender(); if (trans /*== m_getUpdatesTransaction*/) { // m_getUpdatesTransaction = 0; // When pkd dies this method is called twice // pk-qt2 bug.. - trans->disconnect(this, SLOT(finished())); + disconnect(trans, &Transaction::finished, this, &PackageModel::finished); } // The whole structure is about to change if (!m_packages.isEmpty()) { beginInsertRows(QModelIndex(), 0, m_packages.size() - 1); m_finished = true; endInsertRows(); } emit changed(!m_checkedPackages.isEmpty()); } void PackageModel::fetchSizes() { if (m_fetchSizesTransaction) { return; } // get package size QStringList pkgs; - foreach (const InternalPackage &p, m_packages) { + for (const InternalPackage &p : qAsConst(m_packages)) { pkgs << p.packageID; } if (!pkgs.isEmpty()) { m_fetchSizesTransaction = Daemon::getDetails(pkgs); - connect(m_fetchSizesTransaction, SIGNAL(details(PackageKit::Details)), - SLOT(updateSize(PackageKit::Details))); - connect(m_fetchSizesTransaction, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), - this, SLOT(fetchSizesFinished())); + connect(m_fetchSizesTransaction, &Transaction::details, this, &PackageModel::updateSize); + connect(m_fetchSizesTransaction, &Transaction::finished, this, &PackageModel::fetchSizesFinished); } } void PackageModel::fetchSizesFinished() { - Transaction *trans = qobject_cast(sender()); + auto trans = qobject_cast(sender()); if (trans) { // When pkd dies this method is called twice // pk-qt2 bug.. - trans->disconnect(this, SLOT(fetchSizesFinished())); + disconnect(trans, &Transaction::finished, this, &PackageModel::fetchSizesFinished); } // emit this after all is changed otherwise on large models it will // be hell slow... emit dataChanged(createIndex(0, SizeCol), createIndex(m_packages.size(), SizeCol)); emit changed(!m_checkedPackages.isEmpty()); } void PackageModel::updateSize(const PackageKit::Details &details) { // if size is 0 don't waste time looking for the package qulonglong size = details.size(); if (size == 0) { return; } for (int i = 0; i < m_packages.size(); ++i) { const QString &packageId = details.packageId(); if (packageId == m_packages[i].packageID) { m_packages[i].size = size; if (m_checkable) { // updates the checked packages as well if (m_checkedPackages.contains(packageId)) { // Avoid checking packages that aren't checked m_checkedPackages[packageId].size = size; } break; } #ifdef HAVE_APPSTREAM if (m_checkable) { // checkable models don't have duplicated package ids // so don't waste time scanning all list break; } #else // Without AppStream we don't have duplicated package ids break; #endif // HAVE_APPSTREAM } } } void PackageModel::fetchCurrentVersions() { if (m_fetchInstalledVersionsTransaction) { return; } // get package current version QStringList pkgs; - foreach (const InternalPackage &p, m_packages) { + for (const InternalPackage &p : qAsConst(m_packages)) { pkgs << Transaction::packageName(p.packageID); } if (!pkgs.isEmpty()) { m_fetchInstalledVersionsTransaction = Daemon::resolve(pkgs, Transaction::FilterInstalled);; - connect(m_fetchInstalledVersionsTransaction, SIGNAL(package(PackageKit::Transaction::Info,QString,QString)), - this, SLOT(updateCurrentVersion(PackageKit::Transaction::Info,QString,QString))); - connect(m_fetchInstalledVersionsTransaction, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), - this, SLOT(fetchCurrentVersionsFinished())); + connect(m_fetchInstalledVersionsTransaction, &Transaction::package, this, &PackageModel::updateCurrentVersion); + connect(m_fetchInstalledVersionsTransaction, &Transaction::finished, this, &PackageModel::fetchCurrentVersionsFinished); } } void PackageModel::fetchCurrentVersionsFinished() { - Transaction *trans = qobject_cast(sender()); + auto trans = qobject_cast(sender()); if (trans) { // When pkd dies this method is called twice // pk-qt2 bug.. - trans->disconnect(this, SLOT(fetchCurrentVersionsFinished())); + disconnect(trans, &Transaction::finished, this, &PackageModel::fetchCurrentVersionsFinished); } // emit this after all is changed otherwise on large models it will // be hell slow... emit dataChanged(createIndex(0, CurrentVersionCol), createIndex(m_packages.size(), CurrentVersionCol)); emit changed(!m_checkedPackages.isEmpty()); } void PackageModel::updateCurrentVersion(Transaction::Info info, const QString &packageID, const QString &summary) { Q_UNUSED(info) Q_UNUSED(summary) // if current version is empty don't waste time looking if (!Transaction::packageVersion(packageID).isEmpty()) { for (int i = 0; i < m_packages.size(); ++i) { if (Transaction::packageName(packageID) == Transaction::packageName(m_packages[i].packageID) && Transaction::packageArch(packageID) == m_packages[i].arch) { m_packages[i].currentVersion = Transaction::packageVersion(packageID); if (m_checkable) { // updates the checked packages as well if (m_checkedPackages.contains(m_packages[i].packageID)) { // Avoid checking packages that aren't checked m_checkedPackages[m_packages[i].packageID].currentVersion = Transaction::packageVersion(packageID); } break; } } } } } void PackageModel::getUpdates(bool fetchCurrentVersions, bool selected) { clear(); m_getUpdatesTransaction = Daemon::getUpdates(); if (selected) { - connect(m_getUpdatesTransaction, SIGNAL(package(PackageKit::Transaction::Info,QString,QString)), - this, SLOT(addSelectedPackage(PackageKit::Transaction::Info,QString,QString))); + connect(m_getUpdatesTransaction, &Transaction::package, this, &PackageModel::addSelectedPackage); } else { - connect(m_getUpdatesTransaction, SIGNAL(package(PackageKit::Transaction::Info,QString,QString)), - this, SLOT(addPackage(PackageKit::Transaction::Info,QString,QString))); + connect(m_getUpdatesTransaction, &Transaction::package, this, &PackageModel::addNotSelectedPackage); } - connect(m_getUpdatesTransaction, SIGNAL(errorCode(PackageKit::Transaction::Error,QString)), - this, SLOT(errorCode(PackageKit::Transaction::Error,QString))); // connect(m_getUpdatesTransaction, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), // m_busySeq, SLOT(stop())); // connect(m_getUpdatesTransaction, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), // this, SLOT(finished())); // This is required to estimate download size - connect(m_getUpdatesTransaction, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), - this, SLOT(fetchSizes())); + connect(m_getUpdatesTransaction, &Transaction::finished, this, &PackageModel::fetchSizes); + if (fetchCurrentVersions) { - connect(m_getUpdatesTransaction, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), - this, SLOT(fetchCurrentVersions())); + connect(m_getUpdatesTransaction, &Transaction::finished, this, &PackageModel::fetchCurrentVersions); } + connect(m_getUpdatesTransaction, SIGNAL(finished(PackageKit::Transaction::Exit,uint)), this, SLOT(getUpdatesFinished())); // get all updates } void PackageModel::toggleSelection(const QString &packageID) { if (containsChecked(packageID)) { uncheckPackage(packageID, true); } else { - foreach (const InternalPackage &package, m_packages) { + for (const InternalPackage &package : qAsConst(m_packages)) { if (package.packageID == packageID) { checkPackage(package); break; } } } } QString PackageModel::selectionStateText() const { return headerData(NameCol, Qt::Horizontal).toString(); } bool PackageModel::hasChanges() const { return !m_checkedPackages.isEmpty(); } int PackageModel::countInfo(PackageKit::Transaction::Info info) const { int ret = 0; - foreach (const InternalPackage &package, m_packages) { + for (const InternalPackage &package : qAsConst(m_packages)) { if (package.info == info) { ++ret; } } return ret; } void PackageModel::checkPackage(const InternalPackage &package, bool emitDataChanged) { QString pkgId = package.packageID; if (!containsChecked(pkgId)) { m_checkedPackages[pkgId] = package; // A checkable model does not have duplicated entries if (emitDataChanged || !m_checkable || !m_packages.isEmpty()) { // This is a slow operation so in case the user // is unchecking all of the packages there is // no need to emit data changed for every item for (int i = 0; i < m_packages.size(); ++i) { if (m_packages[i].packageID == pkgId) { QModelIndex index = createIndex(i, 0); emit dataChanged(index, index); } } // The model might not be displayed yet if (m_finished) { emit changed(!m_checkedPackages.isEmpty()); } } } } +void PackageModel::uncheckPackageDefault(const QString &packageID) +{ + uncheckPackage(packageID); +} + void PackageModel::uncheckPackage(const QString &packageID, bool forceEmitUnchecked, bool emitDataChanged) { if (containsChecked(packageID)) { m_checkedPackages.remove(packageID); if (forceEmitUnchecked || sender() == 0) { // The package might be removed by rmSelectedPackage // If we don't copy it the browse model won't uncheck there // right package emit packageUnchecked(packageID); } if (emitDataChanged || !m_checkable) { // This is a slow operation so in case the user // is unchecking all of the packages there is // no need to emit data changed for every item for (int i = 0; i < m_packages.size(); ++i) { if (m_packages[i].packageID == packageID) { QModelIndex index = createIndex(i, 0); emit dataChanged(index, index); } } // The model might not be displayed yet if (m_finished) { emit changed(!m_checkedPackages.isEmpty()); } } } } QList PackageModel::internalSelectedPackages() const { QList ret; QHash::const_iterator i = m_checkedPackages.constBegin(); while (i != m_checkedPackages.constEnd()) { ret << i.value(); ++i; } return ret; } bool PackageModel::containsChecked(const QString &pid) const { if (m_checkedPackages.isEmpty()) { return false; } return m_checkedPackages.contains(pid); } void PackageModel::setAllChecked(bool checked) { if (checked) { m_checkedPackages.clear(); - foreach (const InternalPackage &package, m_packages) { + for (const InternalPackage &package : qAsConst(m_packages)) { checkPackage(package, false); } emit dataChanged(createIndex(0, 0), createIndex(m_packages.size(), 0)); } else { // This is a very slow operation, which in here we try to optimize - foreach (const InternalPackage &package, m_checkedPackages) { + for (const InternalPackage &package : qAsConst(m_checkedPackages)) { uncheckPackage(package.packageID, true, false); } emit dataChanged(createIndex(0, 0), createIndex(m_packages.size(), 0)); } emit changed(!m_checkedPackages.isEmpty()); } QStringList PackageModel::selectedPackagesToInstall() const { QStringList list; - foreach (const InternalPackage &package, m_checkedPackages) { + for (const InternalPackage &package : qAsConst(m_checkedPackages)) { if (package.info != Transaction::InfoInstalled && package.info != Transaction::InfoCollectionInstalled) { // append the packages are not installed list << package.packageID; } } return list; } QStringList PackageModel::selectedPackagesToRemove() const { QStringList list; - foreach (const InternalPackage &package, m_checkedPackages) { + for (const InternalPackage &package : qAsConst(m_checkedPackages)) { if (package.info == Transaction::InfoInstalled || package.info == Transaction::InfoCollectionInstalled) { // check what packages are installed and marked to be removed list << package.packageID; } } return list; } QStringList PackageModel::packagesWithInfo(Transaction::Info info) const { QStringList list; - foreach (const InternalPackage &package, m_packages) { + for (const InternalPackage &package : qAsConst(m_packages)) { if (package.info == info) { // Append to the list if the package matches the info value list << package.packageID; } } return list; } QStringList PackageModel::packageIDs() const { QStringList list; - foreach (const InternalPackage &package, m_packages) { + for (const InternalPackage &package : qAsConst(m_packages)) { list << package.packageID; } return list; } unsigned long PackageModel::downloadSize() const { unsigned long size = 0; - foreach (const InternalPackage &package, m_checkedPackages) { + for (const InternalPackage &package : qAsConst(m_checkedPackages)) { size += package.size; } return size; } bool PackageModel::allSelected() const { - foreach (const InternalPackage &package, m_packages) { + for (const InternalPackage &package : qAsConst(m_packages)) { if (!containsChecked(package.packageID)) { return false; } } return true; } void PackageModel::setCheckable(bool checkable) { m_checkable = checkable; } diff --git a/libapper/PackageModel.h b/libapper/PackageModel.h index 0075cb1..e2a14ec 100644 --- a/libapper/PackageModel.h +++ b/libapper/PackageModel.h @@ -1,156 +1,157 @@ /*************************************************************************** * Copyright (C) 2008-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef PACKAGE_MODEL_H #define PACKAGE_MODEL_H #include #include #include #include
class Q_DECL_EXPORT PackageModel : public QAbstractItemModel { Q_OBJECT Q_PROPERTY(bool checkable READ checkable WRITE setCheckable NOTIFY changed) Q_PROPERTY(QString selectionStateText READ selectionStateText NOTIFY changed) public: enum { NameCol = 0, VersionCol, CurrentVersionCol, ArchCol, OriginCol, SizeCol, ActionCol }; enum { SortRole = Qt::UserRole, NameRole, SummaryRole, VersionRole, ArchRole, IconRole, IdRole, CheckStateRole, InfoRole, ApplicationId, IsPackageRole, PackageName, InfoIconRole }; typedef struct { QString displayName; QString version; QString arch; QString repo; QString packageID; QString summary; PackageKit::Transaction::Info info; QString icon; QString appId; QString currentVersion; bool isPackage; double size; } InternalPackage; explicit PackageModel(QObject *parent = 0); Q_INVOKABLE int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); Qt::ItemFlags flags(const QModelIndex &index) const; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; Q_INVOKABLE bool allSelected() const; Q_INVOKABLE QStringList selectedPackagesToInstall() const; Q_INVOKABLE QStringList selectedPackagesToRemove() const; Q_INVOKABLE QStringList packagesWithInfo(PackageKit::Transaction::Info info) const; Q_INVOKABLE QStringList packageIDs() const; unsigned long downloadSize() const; Q_INVOKABLE void clear(); /** * This removes all selected packages that are not in the model */ Q_INVOKABLE void clearSelectedNotPresent(); bool checkable() const; void setCheckable(bool checkable); QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; QModelIndex parent(const QModelIndex &index) const; virtual QHash roleNames() const override; public Q_SLOTS: void addSelectedPackagesFromModel(PackageModel *model); void addNotSelectedPackage(PackageKit::Transaction::Info info, const QString &packageID, const QString &summary); void addPackage(PackageKit::Transaction::Info info, const QString &packageID, const QString &summary, bool selected = false); void addSelectedPackage(PackageKit::Transaction::Info info, const QString &packageID, const QString &summary); void removePackage(const QString &packageID); void setAllChecked(bool checked); void checkPackage(const PackageModel::InternalPackage &package, bool emitDataChanged = true); + void uncheckPackageDefault(const QString &packageID); void uncheckPackage(const QString &packageID, bool forceEmitUnchecked = false, bool emitDataChanged = true); bool hasChanges() const; int countInfo(PackageKit::Transaction::Info info) const; void uncheckInstalledPackages(); void uncheckAvailablePackages(); void finished(); void fetchSizes(); void fetchSizesFinished(); void updateSize(const PackageKit::Details &details); void fetchCurrentVersions(); void fetchCurrentVersionsFinished(); void updateCurrentVersion(PackageKit::Transaction::Info info, const QString &packageID, const QString &summary); void getUpdates(bool fetchCurrentVersions, bool selected); void toggleSelection(const QString &packageID); QString selectionStateText() const; Q_SIGNALS: void changed(bool value); void packageUnchecked(const QString &packageID); private: QList internalSelectedPackages() const; bool containsChecked(const QString &pid) const; bool m_finished = true; bool m_checkable; QPixmap m_installedEmblem; QVector m_packages; QHash m_checkedPackages; PackageKit::Transaction *m_getUpdatesTransaction = 0; PackageKit::Transaction *m_fetchSizesTransaction; PackageKit::Transaction *m_fetchInstalledVersionsTransaction; QHash m_roles; }; #endif diff --git a/libapper/PkTransaction.cpp b/libapper/PkTransaction.cpp index 58a8c42..302e28a 100644 --- a/libapper/PkTransaction.cpp +++ b/libapper/PkTransaction.cpp @@ -1,778 +1,777 @@ /*************************************************************************** - * Copyright (C) 2008-2011 by Daniel Nicoletti * + * Copyright (C) 2008-2018 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include #include "PkTransaction.h" #include #include #include #include #include #include #include #include #include #include #include #include "Enum.h" #include "PkStrings.h" #include "RepoSig.h" #include "LicenseAgreement.h" #include "PkIcons.h" #include "ApplicationLauncher.h" #include "PackageModel.h" #include "Requirements.h" #include "PkTransactionProgressModel.h" #include "PkTransactionWidget.h" Q_DECLARE_LOGGING_CATEGORY(APPER_LIB) class PkTransactionPrivate { public: bool allowDeps; bool jobWatcher; bool handlingActionRequired; bool showingError; //This might replace the above qulonglong downloadSizeRemaining; PkTransaction::ExitStatus exitStatus; Transaction::Status status; Transaction::TransactionFlags flags; Transaction::Role originalRole; Transaction::Error error; Transaction::Role role; QStringList packages; ApplicationLauncher *launcher; QStringList files; QStringList newPackages; PackageModel *simulateModel; PkTransactionProgressModel *progressModel; QWidget *parentWindow; QDBusObjectPath tid; Transaction *transaction; }; PkTransaction::PkTransaction(QObject *parent) : QObject(parent), d(new PkTransactionPrivate) { // for sanity we are finished till some transaction is set d->allowDeps = false; d->jobWatcher = false; d->handlingActionRequired = false; d->showingError = false; d->downloadSizeRemaining = 0; d->exitStatus = Success; d->status = Transaction::StatusUnknown; // for sanity we are trusted till an error is given and the user accepts d->flags = Transaction::TransactionFlagOnlyTrusted; d->originalRole = Transaction::RoleUnknown; d->role = Transaction::RoleUnknown; d->error = Transaction::ErrorUnknown; d->launcher = 0; d->simulateModel = 0; d->progressModel = new PkTransactionProgressModel(this); d->parentWindow = qobject_cast(parent); d->transaction = 0; } PkTransaction::~PkTransaction() { // DO NOT disconnect the transaction here, // it might not exist when this happen delete d; } void PkTransaction::installFiles(const QStringList &files) { // if (Daemon::global()->roles() & Transaction::RoleInstallFiles) { d->originalRole = Transaction::RoleInstallFiles; d->files = files; d->flags = Transaction::TransactionFlagOnlyTrusted | Transaction::TransactionFlagSimulate; setupTransaction(Daemon::installFiles(files, d->flags)); // } else { // showError(i18n("Current backend does not support installing files."), i18n("Error")); // } } void PkTransaction::installPackages(const QStringList &packages) { // if (Daemon::global()->roles() & Transaction::RoleInstallPackages) { d->originalRole = Transaction::RoleInstallPackages; d->packages = packages; d->flags = Transaction::TransactionFlagOnlyTrusted | Transaction::TransactionFlagSimulate; setupTransaction(Daemon::installPackages(d->packages, d->flags)); // } else { // showError(i18n("Current backend does not support installing packages."), i18n("Error")); // } } void PkTransaction::removePackages(const QStringList &packages) { // if (Daemon::global()->roles() & Transaction::RoleRemovePackages) { d->originalRole = Transaction::RoleRemovePackages; d->allowDeps = true; // *was* false, Default to avoid dependencies removal unless simulate says so, except for https://bugs.kde.org/show_bug.cgi?id=315063 d->packages = packages; d->flags = Transaction::TransactionFlagOnlyTrusted | Transaction::TransactionFlagSimulate; setupTransaction(Daemon::removePackages(d->packages, d->allowDeps, AUTOREMOVE, d->flags)); // } else { // showError(i18n("The current backend does not support removing packages."), i18n("Error")); // } } void PkTransaction::updatePackages(const QStringList &packages, bool downloadOnly) { // if (Daemon::global()->roles() & Transaction::RoleUpdatePackages) { d->originalRole = Transaction::RoleUpdatePackages; d->packages = packages; if (downloadOnly) { // Don't simulate if we are just downloading d->flags = Transaction::TransactionFlagOnlyDownload; } else { d->flags = Transaction::TransactionFlagOnlyTrusted | Transaction::TransactionFlagSimulate; } setupTransaction(Daemon::updatePackages(d->packages, d->flags)); // } else { // showError(i18n("The current backend does not support updating packages."), i18n("Error")); // } } void PkTransaction::refreshCache(bool force) { setupTransaction(Daemon::refreshCache(force)); } void PkTransaction::installPackages() { setupTransaction(Daemon::installPackages(d->packages, d->flags)); } void PkTransaction::installFiles() { setupTransaction(Daemon::installFiles(d->files, d->flags)); } void PkTransaction::removePackages() { setupTransaction(Daemon::removePackages(d->packages, d->allowDeps, AUTOREMOVE, d->flags)); } void PkTransaction::updatePackages() { setupTransaction(Daemon::updatePackages(d->packages, d->flags)); } void PkTransaction::requeueTransaction() { - Requirements *requires = qobject_cast(sender()); + auto requires = qobject_cast(sender()); if (requires) { // As we have requires allow deps removal d->allowDeps = true; if (!requires->trusted()) { // Set only trusted to false, to do as the user asked setTrusted(false); } } // Delete the simulate model if (d->simulateModel) { d->simulateModel->deleteLater(); d->simulateModel = 0; } // We are not handling any required action yet for the requeued transaction. // Without this a second license agreement f.e. does not get shown, // see http://bugs.kde.org/show_bug.cgi?id=326619 d->handlingActionRequired = false; switch (d->originalRole) { case Transaction::RoleRemovePackages: removePackages(); break; case Transaction::RoleInstallPackages: installPackages(); break; case Transaction::RoleInstallFiles: installFiles(); break; case Transaction::RoleUpdatePackages: updatePackages(); break; default : setExitStatus(Failed); return; } } void PkTransaction::slotErrorCode(Transaction::Error error, const QString &details) { qCDebug(APPER_LIB) << "errorCode: " << error << details; d->error = error; if (d->handlingActionRequired) { // We are already handling required actions // like eulaRequired() and repoSignatureRequired() return; } switch (error) { case Transaction::ErrorTransactionCancelled: case Transaction::ErrorProcessKill: // these errors should be ignored break; case Transaction::ErrorGpgFailure: case Transaction::ErrorBadGpgSignature: case Transaction::ErrorMissingGpgSignature: case Transaction::ErrorCannotInstallRepoUnsigned: case Transaction::ErrorCannotUpdateRepoUnsigned: { d->handlingActionRequired = true; int ret = KMessageBox::warningYesNo(d->parentWindow, i18n("You are about to install unsigned packages that can compromise your system, " "as it is impossible to verify if the software came from a trusted " "source.\n\nAre you sure you want to proceed with the installation?"), i18n("Installing unsigned software")); if (ret == KMessageBox::Yes) { // Set only trusted to false, to do as the user asked setTrusted(false); requeueTransaction(); } else { setExitStatus(Cancelled); } d->handlingActionRequired = false; return; } default: d->showingError = true; showSorry(PkStrings::error(error), PkStrings::errorMessage(error), QString(details).replace('\n', "
")); // when we receive an error we are done setExitStatus(Failed); } } void PkTransaction::slotEulaRequired(const QString &eulaID, const QString &packageID, const QString &vendor, const QString &licenseAgreement) { if (d->handlingActionRequired) { // if its true means that we alread passed here d->handlingActionRequired = false; return; } else { d->handlingActionRequired = true; } auto eula = new LicenseAgreement(eulaID, packageID, vendor, licenseAgreement, d->parentWindow); - connect(eula, SIGNAL(yesClicked()), this, SLOT(acceptEula())); - connect(eula, SIGNAL(rejected()), this, SLOT(reject())); + connect(eula, &LicenseAgreement::accepted, this, &PkTransaction::acceptEula); + connect(eula, &LicenseAgreement::rejected, this, &PkTransaction::reject); showDialog(eula); } void PkTransaction::acceptEula() { - LicenseAgreement *eula = qobject_cast(sender()); + auto eula = qobject_cast(sender()); if (eula) { qCDebug(APPER_LIB) << "Accepting EULA" << eula->id(); setupTransaction(Daemon::acceptEula(eula->id())); } else { qCWarning(APPER_LIB) << "something is broken, slot is bound to LicenseAgreement but signalled from elsewhere."; } } void PkTransaction::slotChanged() { - Transaction *transaction = qobject_cast(sender()); + auto transaction = qobject_cast(sender()); d->downloadSizeRemaining = transaction->downloadSizeRemaining(); d->role = transaction->role(); if (!d->jobWatcher) { return; } QDBusObjectPath _tid = transaction->tid(); if (d->tid != _tid && !(d->flags & Transaction::TransactionFlagSimulate)) { d->tid = _tid; // if the transaction changed and // the user wants the watcher send the tid QDBusMessage message; message = QDBusMessage::createMethodCall(QLatin1String("org.kde.apperd"), QLatin1String("/"), QLatin1String("org.kde.apperd"), QLatin1String("WatchTransaction")); // Use our own cached tid to avoid crashes message << qVariantFromValue(_tid); if (!QDBusConnection::sessionBus().send(message)) { qCWarning(APPER_LIB) << "Failed to put WatchTransaction on the DBus queue"; } } } void PkTransaction::slotMediaChangeRequired(Transaction::MediaType type, const QString &id, const QString &text) { Q_UNUSED(id) d->handlingActionRequired = true; int ret = KMessageBox::questionYesNo(d->parentWindow, PkStrings::mediaMessage(type, text), i18n("A media change is required"), KStandardGuiItem::cont(), KStandardGuiItem::cancel()); d->handlingActionRequired = false; // if the user clicked continue we got yes if (ret == KMessageBox::Yes) { requeueTransaction(); } else { setExitStatus(Cancelled); } } void PkTransaction::slotRepoSignature(const QString &packageID, const QString &repoName, const QString &keyUrl, const QString &keyUserid, const QString &keyId, const QString &keyFingerprint, const QString &keyTimestamp, Transaction::SigType type) { if (d->handlingActionRequired) { // if its true means that we alread passed here d->handlingActionRequired = false; return; } else { d->handlingActionRequired = true; } auto repoSig = new RepoSig(packageID, repoName, keyUrl, keyUserid, keyId, keyFingerprint, keyTimestamp, type, d->parentWindow); - connect(repoSig, SIGNAL(yesClicked()), this, SLOT(installSignature())); - connect(repoSig, SIGNAL(rejected()), this, SLOT(reject())); + connect(repoSig, &RepoSig::accepted, this, &PkTransaction::installSignature); + connect(repoSig, &RepoSig::rejected, this, &PkTransaction::reject); showDialog(repoSig); } void PkTransaction::installSignature() { - RepoSig *repoSig = qobject_cast(sender()); + auto repoSig = qobject_cast(sender()); if (repoSig) { qCDebug(APPER_LIB) << "Installing Signature" << repoSig->keyID(); setupTransaction(Daemon::installSignature(repoSig->sigType(), repoSig->keyID(), repoSig->packageID())); } else { qCWarning(APPER_LIB) << "something is broken, slot is bound to RepoSig but signalled from elsewhere."; } } void PkTransaction::slotFinished(Transaction::Exit status) { // Clear the model to don't keep trash when reusing the transaction d->progressModel->clear(); Requirements *requires = 0; Transaction::Role _role = qobject_cast(sender())->role(); d->transaction = 0; // Will be deleted later qCDebug(APPER_LIB) << status << _role; switch (_role) { case Transaction::RoleInstallSignature: case Transaction::RoleAcceptEula: if (status == Transaction::ExitSuccess) { // if the required action was performed with success // requeue our main transaction requeueTransaction(); return; } break; default: break; } switch(status) { case Transaction::ExitSuccess: // Check if we are just simulating if (d->flags & Transaction::TransactionFlagSimulate) { // Disable the simulate flag d->flags ^= Transaction::TransactionFlagSimulate; d->simulateModel->finished(); // Remove the transaction packages - foreach (const QString &packageID, d->packages) { + for (const QString &packageID : qAsConst(d->packages)) { d->simulateModel->removePackage(packageID); } d->newPackages = d->simulateModel->packagesWithInfo(Transaction::InfoInstalling); if (_role == Transaction::RoleInstallPackages) { d->newPackages << d->packages; d->newPackages.removeDuplicates(); } requires = new Requirements(d->simulateModel, d->parentWindow); requires->setDownloadSizeRemaining(d->downloadSizeRemaining); connect(requires, &Requirements::accepted, this, &PkTransaction::requeueTransaction); connect(requires, &Requirements::rejected, this, &PkTransaction::reject); if (requires->shouldShow()) { showDialog(requires); } else { requires->deleteLater(); // Since we removed the Simulate Flag this will procced // with the actual action requeueTransaction(); } } else { KConfig config("apper"); KConfigGroup transactionGroup(&config, "Transaction"); bool showApp = transactionGroup.readEntry("ShowApplicationLauncher", true); if (showApp && !d->newPackages.isEmpty() && (_role == Transaction::RoleInstallPackages || _role == Transaction::RoleInstallFiles || _role == Transaction::RoleRemovePackages || _role == Transaction::RoleUpdatePackages)) { // When installing files or updates that involves new packages // try to resolve the available packages at simulation time // to maybe show the user the new applications that where installed if (d->launcher) { delete d->launcher; } d->launcher = new ApplicationLauncher(d->parentWindow); - connect(this, SIGNAL(files(QString,QStringList)), - d->launcher, SLOT(files(QString,QStringList))); + connect(d->transaction, &Transaction::files, d->launcher, &ApplicationLauncher::files); setupTransaction(Daemon::getFiles(d->newPackages)); d->newPackages.clear(); return; // avoid the exit code } else if (_role == Transaction::RoleGetFiles && d->launcher && d->launcher->hasApplications()) { // if we have a launcher and the laucher has applications // show them to the user showDialog(d->launcher); connect(d->launcher, &ApplicationLauncher::finished, this, &PkTransaction::setExitStatus); return; } setExitStatus(Success); } break; case Transaction::ExitNeedUntrusted: case Transaction::ExitKeyRequired: case Transaction::ExitEulaRequired: case Transaction::ExitMediaChangeRequired: qCDebug(APPER_LIB) << "finished KeyRequired or EulaRequired: " << status; if (!d->handlingActionRequired) { qCDebug(APPER_LIB) << "Not Handling Required Action"; setExitStatus(Failed); } break; case Transaction::ExitCancelled: // Avoid crash in case we are showing an error if (!d->showingError) { setExitStatus(Cancelled); } break; case Transaction::ExitFailed: if (!d->handlingActionRequired && !d->showingError) { qCDebug(APPER_LIB) << "Yep, we failed."; setExitStatus(Failed); } break; default : qCDebug(APPER_LIB) << "finished default" << status; setExitStatus(Failed); break; } } PkTransaction::ExitStatus PkTransaction::exitStatus() const { return d->exitStatus; } bool PkTransaction::isFinished() const { qCDebug(APPER_LIB) << d->transaction->status() << d->transaction->role(); return d->transaction->status() == Transaction::StatusFinished; } PackageModel *PkTransaction::simulateModel() const { return d->simulateModel; } uint PkTransaction::percentage() const { if (d->transaction) { return d->transaction->percentage(); } return 0; } uint PkTransaction::remainingTime() const { if (d->transaction) { return d->transaction->remainingTime(); } return 0; } uint PkTransaction::speed() const { if (d->transaction) { return d->transaction->speed(); } return 0; } qulonglong PkTransaction::downloadSizeRemaining() const { if (d->transaction) { return d->transaction->downloadSizeRemaining(); } return 0; } Transaction::Status PkTransaction::status() const { if (d->transaction) { return d->transaction->status(); } return Transaction::StatusUnknown; } Transaction::Role PkTransaction::role() const { if (d->transaction) { return d->transaction->role(); } return Transaction::RoleUnknown; } bool PkTransaction::allowCancel() const { if (d->transaction) { return d->transaction->allowCancel(); } return false; } Transaction::TransactionFlags PkTransaction::transactionFlags() const { if (d->transaction) { return d->transaction->transactionFlags(); } return Transaction::TransactionFlagNone; } void PkTransaction::getUpdateDetail(const QString &packageID) { setupTransaction(Daemon::getUpdateDetail(packageID)); } void PkTransaction::getUpdates() { setupTransaction(Daemon::getUpdates()); } void PkTransaction::cancel() { if (d->transaction) { d->transaction->cancel(); } } void PkTransaction::setTrusted(bool trusted) { if (trusted) { d->flags |= Transaction::TransactionFlagOnlyTrusted; } else { d->flags ^= Transaction::TransactionFlagOnlyTrusted; } } void PkTransaction::setExitStatus(int status) { qCDebug(APPER_LIB) << status; if (d->launcher) { d->launcher->deleteLater(); d->launcher = 0; } d->exitStatus = static_cast(status); if (!d->handlingActionRequired || !d->showingError) { emit finished(d->exitStatus); } } void PkTransaction::reject() { setExitStatus(Cancelled); } void PkTransaction::setupTransaction(Transaction *transaction) { // Clear the model to don't keep trash when reusing the transaction d->progressModel->clear(); d->transaction = transaction; if (!(transaction->transactionFlags() & Transaction::TransactionFlagSimulate) && transaction->role() != Transaction::RoleGetUpdates && transaction->role() != Transaction::RoleGetUpdateDetail) { connect(transaction, &Transaction::repoDetail, d->progressModel, &PkTransactionProgressModel::currentRepo); connect(transaction, &Transaction::package, d->progressModel, &PkTransactionProgressModel::currentPackage); connect(transaction, &Transaction::itemProgress, d->progressModel, &PkTransactionProgressModel::itemProgress); } connect(transaction, &Transaction::updateDetail, this, &PkTransaction::updateDetail); connect(transaction, &Transaction::package, this, &PkTransaction::package); connect(transaction, &Transaction::errorCode, this, &PkTransaction::errorCode); // Required actions connect(transaction, &Transaction::allowCancelChanged, this, &PkTransaction::allowCancelChanged); connect(transaction, &Transaction::downloadSizeRemainingChanged, this, &PkTransaction::downloadSizeRemainingChanged); connect(transaction, &Transaction::elapsedTimeChanged, this, &PkTransaction::elapsedTimeChanged); connect(transaction, &Transaction::isCallerActiveChanged, this, &PkTransaction::isCallerActiveChanged); connect(transaction, &Transaction::lastPackageChanged, this, &PkTransaction::lastPackageChanged); connect(transaction, &Transaction::percentageChanged, this, &PkTransaction::percentageChanged); connect(transaction, &Transaction::remainingTimeChanged, this, &PkTransaction::remainingTimeChanged); connect(transaction, &Transaction::roleChanged, this, &PkTransaction::roleChanged); connect(transaction, &Transaction::speedChanged, this, &PkTransaction::speedChanged); connect(transaction, &Transaction::statusChanged, this, &PkTransaction::statusChanged); connect(transaction, &Transaction::transactionFlagsChanged, this, &PkTransaction::transactionFlagsChanged); connect(transaction, &Transaction::uidChanged, this, &PkTransaction::uidChanged); connect(transaction, &Transaction::downloadSizeRemainingChanged, this, &PkTransaction::slotChanged); connect(transaction, &Transaction::errorCode, this, &PkTransaction::slotErrorCode); connect(transaction, &Transaction::eulaRequired, this, &PkTransaction::slotEulaRequired); connect(transaction, &Transaction::mediaChangeRequired, this, &PkTransaction::slotMediaChangeRequired); connect(transaction, &Transaction::repoSignatureRequired, this, &PkTransaction::slotRepoSignature); connect(transaction, &Transaction::finished, this, &PkTransaction::slotFinished); if (d->flags & Transaction::TransactionFlagSimulate) { d->simulateModel = new PackageModel(this); connect(d->transaction, &Transaction::package, d->simulateModel, &PackageModel::addNotSelectedPackage); } #ifdef HAVE_DEBCONFKDE QString _tid = transaction->tid().path(); QString socket; // Build a socket path like /tmp/1761_edeceabd_data_debconf socket = QLatin1String("/tmp") % _tid % QLatin1String("_debconf"); QDBusMessage message; message = QDBusMessage::createMethodCall(QLatin1String("org.kde.apperd"), QLatin1String("/"), QLatin1String("org.kde.apperd"), QLatin1String("SetupDebconfDialog")); // Use our own cached tid to avoid crashes message << qVariantFromValue(_tid); message << qVariantFromValue(socket); if (d->parentWindow) { message << qVariantFromValue(static_cast(d->parentWindow->effectiveWinId())); } else { message << qVariantFromValue(0u); } if (!QDBusConnection::sessionBus().send(message)) { qCWarning(APPER_LIB) << "Failed to put SetupDebconfDialog message in DBus queue"; } transaction->setHints(QLatin1String("frontend-socket=") % socket); #endif //HAVE_DEBCONFKDE } void PkTransaction::showDialog(QDialog *dlg) { auto widget = qobject_cast(d->parentWindow); if (!widget || widget->isCancelVisible()) { dlg->setModal(d->parentWindow); dlg->show(); } else { dlg->setProperty("embedded", true); emit dialog(dlg); } } void PkTransaction::showError(const QString &title, const QString &description, const QString &details) { - PkTransactionWidget *widget = qobject_cast(d->parentWindow); + auto widget = qobject_cast(d->parentWindow); if (!widget || widget->isCancelVisible()) { if (details.isEmpty()) { if (d->parentWindow) { KMessageBox::error(d->parentWindow, description, title); } else { KMessageBox::errorWId(0, description, title); } } else { KMessageBox::detailedError(d->parentWindow, description, details, title); } } else { emit errorMessage(title, description, details); } } void PkTransaction::showSorry(const QString &title, const QString &description, const QString &details) { - PkTransactionWidget *widget = qobject_cast(d->parentWindow); + auto widget = qobject_cast(d->parentWindow); if (!widget || widget->isCancelVisible()) { if (details.isEmpty()) { KMessageBox::sorry(d->parentWindow, description, title); } else { KMessageBox::detailedSorry(d->parentWindow, description, details, title); } } else { emit sorry(title, description, details); } } QString PkTransaction::title() const { return PkStrings::action(d->originalRole, d->flags); } Transaction::Role PkTransaction::cachedRole() const { return d->role; } Transaction::TransactionFlags PkTransaction::flags() const { return d->flags; } PkTransactionProgressModel *PkTransaction::progressModel() const { return d->progressModel; } void PkTransaction::enableJobWatcher(bool enable) { d->jobWatcher = enable; } #include "moc_PkTransaction.cpp" diff --git a/libapper/PkTransactionProgressModel.cpp b/libapper/PkTransactionProgressModel.cpp index cb46e50..55851e9 100644 --- a/libapper/PkTransactionProgressModel.cpp +++ b/libapper/PkTransactionProgressModel.cpp @@ -1,197 +1,197 @@ /*************************************************************************** * Copyright (C) 2010-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "PkTransactionProgressModel.h" #include #include #include "PkTransaction.h" Q_DECLARE_LOGGING_CATEGORY(APP_LIB) using namespace PackageKit; PkTransactionProgressModel::PkTransactionProgressModel(QObject *parent) : QStandardItemModel(parent) { } PkTransactionProgressModel::~PkTransactionProgressModel() { } void PkTransactionProgressModel::currentRepo(const QString &repoId, const QString &description, bool enabled) { Q_UNUSED(enabled) - PkTransaction *transaction = qobject_cast(sender()); + auto transaction = qobject_cast(sender()); if (transaction && transaction->flags() & Transaction::TransactionFlagSimulate) { return; } - QStandardItem *stdItem = new QStandardItem(description); + auto stdItem = new QStandardItem(description); stdItem->setData(repoId, RoleId); stdItem->setData(true, RoleRepo); appendRow(stdItem); } void PkTransactionProgressModel::itemProgress(const QString &id, Transaction::Status status, uint percentage) { Q_UNUSED(status) - PkTransaction *transaction = qobject_cast(sender()); + auto transaction = qobject_cast(sender()); if (transaction && transaction->flags() & Transaction::TransactionFlagSimulate) { return; } QStandardItem *stdItem = findLastItem(id); if (stdItem && !stdItem->data(RoleFinished).toBool()) { // if the progress is unknown (101), make it empty if (percentage == 101) { percentage = 0; } if (stdItem->data(RoleProgress).toUInt() != percentage) { stdItem->setData(percentage, RoleProgress); } } } void PkTransactionProgressModel::clear() { removeRows(0, rowCount()); } QHash PkTransactionProgressModel::roleNames() const { QHash roles; roles[RoleInfo] = "rInfo"; roles[RolePkgName] = "rPkgName"; roles[RolePkgSummary] = "rPkgSummary"; roles[RoleFinished] = "rFinished"; roles[RoleProgress] = "rProgress"; roles[RoleId] = "rId"; roles[RoleRepo] = "rRepo"; return roles; } void PkTransactionProgressModel::currentPackage(PackageKit::Transaction::Info info, const QString &packageID, const QString &summary) { - PkTransaction *transaction = qobject_cast(sender()); + auto transaction = qobject_cast(sender()); if (transaction && (transaction->flags() & Transaction::TransactionFlagSimulate || transaction->cachedRole() == Transaction::RoleResolve || transaction->cachedRole() == Transaction::RoleWhatProvides)) { return; } if (!packageID.isEmpty()) { QStandardItem *stdItem = findLastItem(packageID); // If there is alread some packages check to see if it has // finished, if the progress is 100 create a new item for the next task if (stdItem && !stdItem->data(RoleFinished).toBool()) { // if the item status (info) changed update it if (stdItem->data(RoleInfo).value() != info) { // If the package task has finished set progress to 100 if (info == Transaction::InfoFinished) { itemFinished(stdItem); } else { stdItem->setData(qVariantFromValue(info), RoleInfo); stdItem->setText(PkStrings::infoPresent(info)); } } } else if (info != Transaction::InfoFinished) { QList items; // It's a new package create it and append it stdItem = new QStandardItem; stdItem->setText(PkStrings::infoPresent(info)); stdItem->setData(Transaction::packageName(packageID), RolePkgName); stdItem->setData(summary, RolePkgSummary); stdItem->setData(qVariantFromValue(info), RoleInfo); stdItem->setData(0, RoleProgress); stdItem->setData(false, RoleFinished); stdItem->setData(packageID, RoleId); stdItem->setData(false, RoleRepo); items << stdItem; stdItem = new QStandardItem(Transaction::packageName(packageID)); stdItem->setToolTip(Transaction::packageVersion(packageID)); items << stdItem; stdItem = new QStandardItem(summary); stdItem->setToolTip(summary); items << stdItem; appendRow(items); } } } void PkTransactionProgressModel::itemFinished(QStandardItem *stdItem) { // Point to the item before it int count = stdItem->row() - 1; // Find the last finished item bool found = false; while (count >= 0) { // Put it after the finished item // so that running items can be kept // at the bottom if (item(count)->data(RoleFinished).toBool()) { // make sure it won't end in the same position if (count + 1 != stdItem->row()) { QList items; items = takeRow(stdItem->row()); insertRow(count + 1, items); } found = true; break; } --count; } // If it's not at the top of the list // and no FINISHED Item was found move it there if (!found && stdItem->row() != 0) { insertRow(0, takeRow(stdItem->row())); } Transaction::Info info = stdItem->data(RoleInfo).value(); stdItem->setText(PkStrings::infoPast(info)); stdItem->setData(100, RoleProgress); stdItem->setData(true, RoleFinished); } QStandardItem* PkTransactionProgressModel::findLastItem(const QString &packageID) { int rows = rowCount() - 1; for (int i = rows; i >= 0; --i) { QStandardItem *stdItem = item(i); if (stdItem->data(RoleId).toString() == packageID) { return stdItem; } } return 0; } #include "moc_PkTransactionProgressModel.cpp" diff --git a/libapper/PkTransactionWidget.cpp b/libapper/PkTransactionWidget.cpp index 65ff58f..f5c5751 100644 --- a/libapper/PkTransactionWidget.cpp +++ b/libapper/PkTransactionWidget.cpp @@ -1,331 +1,308 @@ /*************************************************************************** * Copyright (C) 2008-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include #include "PkTransactionWidget.h" #include "ui_PkTransactionWidget.h" #include #include #include #include #include #include #include #include #include #include #include "Enum.h" #include "PkStrings.h" #include "RepoSig.h" #include "LicenseAgreement.h" #include "PkIcons.h" #include "ApplicationLauncher.h" #include "Requirements.h" #include "PkTransaction.h" #include "TransactionDelegate.h" #include "PkTransactionProgressModel.h" #include "PackageModel.h" Q_DECLARE_LOGGING_CATEGORY(APPER_LIB) class PkTransactionWidgetPrivate { public: ApplicationLauncher *launcher; Transaction::Role role; KPixmapSequenceOverlayPainter *busySeq; }; PkTransactionWidget::PkTransactionWidget(QWidget *parent) : QWidget(parent), m_trans(0), m_keepScrollBarAtBottom(true), m_handlingActionRequired(false), m_showingError(false), m_status(Transaction::StatusUnknown), ui(new Ui::PkTransactionWidget), d(new PkTransactionWidgetPrivate) { ui->setupUi(this); // Setup the animation sequence d->busySeq = new KPixmapSequenceOverlayPainter(this); d->busySeq->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); d->busySeq->setWidget(ui->label); ui->label->clear(); // Connect stuff from the progressView QScrollBar *scrollBar = ui->progressView->verticalScrollBar(); - connect(scrollBar, SIGNAL(sliderMoved(int)), - this, SLOT(followBottom(int))); - connect(scrollBar, SIGNAL(valueChanged(int)), - this, SLOT(followBottom(int))); - connect(scrollBar, SIGNAL(rangeChanged(int,int)), - this, SLOT(rangeChanged(int,int))); + connect(scrollBar, &QScrollBar::sliderMoved, this, &PkTransactionWidget::followBottom); + connect(scrollBar, &QScrollBar::valueChanged, this, &PkTransactionWidget::followBottom); + connect(scrollBar, &QScrollBar::rangeChanged, this, &PkTransactionWidget::rangeChanged); ui->progressView->setItemDelegate(new TransactionDelegate(this)); - connect(ui->cancelButton, SIGNAL(rejected()), this, SLOT(cancel())); + connect(ui->cancelButton, &QDialogButtonBox::rejected, this, &PkTransactionWidget::cancel); } PkTransactionWidget::~PkTransactionWidget() { // DO NOT disconnect the transaction here, // it might not exist when this happen delete d; } void PkTransactionWidget::hideCancelButton() { // On the session installed we hide the // cancel button to use the KDialog main one ui->cancelButton->hide(); } void PkTransactionWidget::cancel() { if (m_trans) { m_trans->cancel(); } } void PkTransactionWidget::setTransaction(PkTransaction *trans, Transaction::Role role) { Q_ASSERT(trans); m_trans = trans; d->role = role; // This makes sure the Columns will properly resize to contents ui->progressView->header()->setStretchLastSection(false); if (role == Transaction::RoleRefreshCache) { trans->progressModel()->setColumnCount(1); ui->progressView->setModel(trans->progressModel()); ui->progressView->header()->setSectionResizeMode(0, QHeaderView::Stretch); } else { trans->progressModel()->setColumnCount(3); ui->progressView->setModel(trans->progressModel()); ui->progressView->header()->reset(); ui->progressView->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents); ui->progressView->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents); ui->progressView->header()->setSectionResizeMode(2, QHeaderView::Stretch); } - connect(m_trans, SIGNAL(percentageChanged()), - SLOT(updateUi())); - connect(m_trans, SIGNAL(speedChanged()), - SLOT(updateUi())); - connect(m_trans, SIGNAL(statusChanged()), - SLOT(updateUi())); - connect(m_trans, SIGNAL(downloadSizeRemainingChanged()), - SLOT(updateUi())); - connect(m_trans, SIGNAL(remainingTimeChanged()), - SLOT(updateUi())); - connect(m_trans, SIGNAL(roleChanged()), - SLOT(updateUi())); - connect(m_trans, SIGNAL(transactionFlagsChanged()), - SLOT(updateUi())); - connect(m_trans, SIGNAL(allowCancelChanged()), - SLOT(updateUi())); + connect(m_trans, &PkTransaction::percentageChanged, this, &PkTransactionWidget::updateUi); + connect(m_trans, &PkTransaction::speedChanged, this, &PkTransactionWidget::updateUi); + connect(m_trans, &PkTransaction::statusChanged, this, &PkTransactionWidget::updateUi); + connect(m_trans, &PkTransaction::downloadSizeRemainingChanged, this, &PkTransactionWidget::updateUi); + connect(m_trans, &PkTransaction::remainingTimeChanged, this, &PkTransactionWidget::updateUi); + connect(m_trans, &PkTransaction::roleChanged, this, &PkTransactionWidget::updateUi); + connect(m_trans, &PkTransaction::allowCancelChanged, this, &PkTransactionWidget::updateUi); + connect(m_trans, &PkTransaction::transactionFlagsChanged, this, &PkTransactionWidget::updateUi); // Forward Q_SIGNALS: - connect(m_trans, SIGNAL(sorry(QString,QString,QString)), - this, SIGNAL(sorry(QString,QString,QString))); - connect(m_trans, SIGNAL(errorMessage(QString,QString,QString)), - SIGNAL(error(QString,QString,QString))); - connect(m_trans, SIGNAL(dialog(KDialog*)), - this, SIGNAL(dialog(KDialog*))); - + connect(m_trans, &PkTransaction::sorry, this, &PkTransactionWidget::sorry); + connect(m_trans, &PkTransaction::errorMessage, this, &PkTransactionWidget::error); + connect(m_trans, &PkTransaction::dialog, this, &PkTransactionWidget::dialog); // sets ui updateUi(); } void PkTransactionWidget::unsetTransaction() { if (m_trans == 0) { return; } - connect(m_trans, SIGNAL(percentageChanged()), - SLOT(updateUi())); - connect(m_trans, SIGNAL(speedChanged()), - SLOT(updateUi())); - connect(m_trans, SIGNAL(statusChanged()), - SLOT(updateUi())); - connect(m_trans, SIGNAL(downloadSizeRemainingChanged()), - SLOT(updateUi())); - connect(m_trans, SIGNAL(remainingTimeChanged()), - SLOT(updateUi())); - connect(m_trans, SIGNAL(roleChanged()), - SLOT(updateUi())); - connect(m_trans, SIGNAL(transactionFlagsChanged()), - SLOT(updateUi())); - connect(m_trans, SIGNAL(allowCancelChanged()), - SLOT(updateUi())); + connect(m_trans, &PkTransaction::percentageChanged, this, &PkTransactionWidget::updateUi); + connect(m_trans, &PkTransaction::speedChanged, this, &PkTransactionWidget::updateUi); + connect(m_trans, &PkTransaction::statusChanged, this, &PkTransactionWidget::updateUi); + connect(m_trans, &PkTransaction::downloadSizeRemainingChanged, this, &PkTransactionWidget::updateUi); + connect(m_trans, &PkTransaction::remainingTimeChanged, this, &PkTransactionWidget::updateUi); + connect(m_trans, &PkTransaction::roleChanged, this, &PkTransactionWidget::updateUi); + connect(m_trans, &PkTransaction::allowCancelChanged, this, &PkTransactionWidget::updateUi); + connect(m_trans, &PkTransaction::transactionFlagsChanged, this, &PkTransactionWidget::updateUi); } void PkTransactionWidget::updateUi() { // sets the action icon to be the window icon - PkTransaction *transaction = qobject_cast(sender()); + auto transaction = qobject_cast(sender()); if (transaction == 0 && (transaction = m_trans) == 0) { qCWarning(APPER_LIB) << "no transaction object"; return; } uint percentage = transaction->percentage(); QString percentageString; if (percentage <= 100) { if (ui->progressBar->value() != static_cast(percentage)) { ui->progressBar->setMaximum(100); ui->progressBar->setValue(percentage); percentageString = QString::number(percentage); } } else if (ui->progressBar->maximum() != 0) { ui->progressBar->setMaximum(0); ui->progressBar->reset(); percentageString = QLatin1String(""); } ui->progressBar->setRemaining(transaction->remainingTime()); // Status & Speed Transaction::Status status = transaction->status(); uint speed = transaction->speed(); qulonglong downloadSizeRemaining = transaction->downloadSizeRemaining(); if (m_status != status) { m_status = status; ui->currentL->setText(PkStrings::status(status, speed, downloadSizeRemaining)); KPixmapSequence sequence = KPixmapSequence(PkIcons::statusAnimation(status), KIconLoader::SizeLarge); if (sequence.isValid()) { d->busySeq->setSequence(sequence); d->busySeq->start(); } } else if (status == Transaction::StatusDownload) { ui->currentL->setText(PkStrings::status(status, speed, downloadSizeRemaining)); } QString windowTitle; QString windowTitleProgress; QIcon windowIcon; Transaction::Role role = transaction->role(); if (role == Transaction::RoleUnknown) { windowTitle = PkStrings::status(Transaction::StatusSetup); if (percentageString.isEmpty()) { windowTitleProgress = PkStrings::status(status, speed, downloadSizeRemaining); } else { QString statusText = PkStrings::status(status, speed, downloadSizeRemaining); windowTitleProgress = i18n("%1 (%2%)", statusText, percentageString); } windowIcon = PkIcons::statusIcon(Transaction::StatusSetup); } else { windowTitle = PkStrings::action(role, transaction->transactionFlags()); if (percentageString.isEmpty()) { windowTitleProgress = PkStrings::status(status, speed, downloadSizeRemaining); } else { QString statusText = PkStrings::status(status, speed, downloadSizeRemaining); windowTitleProgress = i18n("%1 (%2%)", statusText, percentageString); } windowIcon = PkIcons::actionIcon(role); } if (d->role != role) { d->role = role; setWindowIcon(PkIcons::actionIcon(role)); setWindowTitle(windowTitle); emit titleChanged(windowTitle); emit titleChangedProgress(windowTitleProgress); } else if (!percentageString.isNull()) { emit titleChangedProgress(windowTitleProgress); } // check to see if we can cancel bool cancel = transaction->allowCancel(); emit allowCancel(cancel); ui->cancelButton->setEnabled(cancel); } bool PkTransactionWidget::isFinished() const { // return d->finished; return false; } bool PkTransactionWidget::isCancelVisible() const { return ui->cancelButton->isVisible(); } void PkTransactionWidget::reject() { // d->finished = true; // setExitStatus(Cancelled); } void PkTransactionWidget::followBottom(int value) { // If the user moves the slider to the bottom // keep it there as the list expands QScrollBar *scrollBar = qobject_cast(sender()); m_keepScrollBarAtBottom = value == scrollBar->maximum(); } void PkTransactionWidget::rangeChanged(int min, int max) { Q_UNUSED(min) QScrollBar *scrollBar = qobject_cast(sender()); if (m_keepScrollBarAtBottom && scrollBar->value() != max) { scrollBar->setValue(max); } } Transaction::Role PkTransactionWidget::role() const { return d->role; } PkTransaction *PkTransactionWidget::transaction() const { return m_trans; } #include "moc_PkTransactionWidget.cpp" diff --git a/libapper/Requirements.cpp b/libapper/Requirements.cpp index 4a2bc53..22db524 100644 --- a/libapper/Requirements.cpp +++ b/libapper/Requirements.cpp @@ -1,276 +1,273 @@ /*************************************************************************** * Copyright (C) 2008-2011 by Daniel Nicoletti * * dantti12@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; see the file COPYING. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "Requirements.h" #include "ui_Requirements.h" #include "PkIcons.h" #include "PackageModel.h" #include "ApplicationSortFilterModel.h" #include #include #include #include #include #include Requirements::Requirements(PackageModel *model, QWidget *parent) : QDialog(parent), m_embed(false), m_shouldShow(true), m_untrustedButton(0), ui(new Ui::Requirements) { setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(this); connect(ui->confirmCB, SIGNAL(toggled(bool)), this, SLOT(on_confirmCB_Toggled(bool))); ApplicationSortFilterModel *proxy = new ApplicationSortFilterModel(this); proxy->setSourceModel(model); ui->packageView->setModel(proxy); ui->packageView->header()->setSectionResizeMode(PackageModel::NameCol, QHeaderView::ResizeToContents); ui->packageView->header()->hideSection(PackageModel::ActionCol); ui->packageView->header()->hideSection(PackageModel::ArchCol); ui->packageView->header()->hideSection(PackageModel::CurrentVersionCol); ui->packageView->header()->hideSection(PackageModel::OriginCol); ui->packageView->header()->hideSection(PackageModel::SizeCol); m_hideAutoConfirm = false; setWindowTitle(i18n("Additional changes")); setWindowIcon(QIcon::fromTheme("dialog-warning")); // setButtons(KDialog::Ok | KDialog::Cancel | KDialog::Help); ui->buttonBox->button(QDialogButtonBox::Ok)->setText(i18n("Continue")); // setButtonText(KDialog::Ok, i18n("Continue")); // restore size setMinimumSize(QSize(600,480)); // setInitialSize(QSize(600,600)); KConfig config("apper"); KConfigGroup requirementsDialog(&config, "requirementsDialog"); // restoreGeometry(requirementsDialog.readEntry("geometry").toByteArray()); // restoreDialogSize(requirementsDialog); QPushButton *help = ui->buttonBox->button(QDialogButtonBox::Help); help->setFlat(true); help->setEnabled(false); help->setIcon(QIcon::fromTheme("download")); m_buttonGroup = new QButtonGroup(this); - connect(m_buttonGroup, SIGNAL(buttonClicked(int)), this, SLOT(actionClicked(int))); + connect(m_buttonGroup, QOverload::of(&QButtonGroup::buttonClicked), this, &Requirements::actionClicked); int count = 0; if (int c = model->countInfo(Transaction::InfoRemoving)) { - QToolButton *button = new QToolButton(this); + auto button = new QToolButton(this); button->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); button->setCheckable(true); button->setAutoRaise(true); button->setIconSize(QSize(32, 32)); button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); button->setText(i18np("1 package to remove", "%1 packages to remove", c)); button->setIcon(PkIcons::actionIcon(Transaction::RoleRemovePackages)); m_buttonGroup->addButton(button, Transaction::InfoRemoving); ui->verticalLayout->insertWidget(count++, button); m_hideAutoConfirm = true; } if (int c = model->countInfo(Transaction::InfoDowngrading)) { - QToolButton *button = new QToolButton(this); + auto button = new QToolButton(this); button->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); button->setCheckable(true); button->setAutoRaise(true); button->setIconSize(QSize(32, 32)); button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); button->setText(i18np("1 package to downgrade", "%1 packages to downgrade", c)); button->setIcon(PkIcons::actionIcon(Transaction::RoleRepairSystem)); m_buttonGroup->addButton(button, Transaction::InfoDowngrading); ui->verticalLayout->insertWidget(count++, button); m_hideAutoConfirm = true; } if (int c = model->countInfo(Transaction::InfoReinstalling)) { - QToolButton *button = new QToolButton(this); + auto button = new QToolButton(this); button->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); button->setCheckable(true); button->setAutoRaise(true); button->setIconSize(QSize(32, 32)); button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); button->setText(i18np("1 package to reinstall", "%1 packages to reinstall", c)); button->setIcon(PkIcons::actionIcon(Transaction::RoleRemovePackages)); m_buttonGroup->addButton(button, Transaction::InfoReinstalling); ui->verticalLayout->insertWidget(count++, button); } if (int c = model->countInfo(Transaction::InfoInstalling)) { - QToolButton *button = new QToolButton(this); + auto button = new QToolButton(this); button->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); button->setCheckable(true); button->setAutoRaise(true); button->setIconSize(QSize(32, 32)); button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); button->setText(i18np("1 package to install", "%1 packages to install", c)); button->setIcon(PkIcons::actionIcon(Transaction::RoleInstallPackages)); m_buttonGroup->addButton(button, Transaction::InfoInstalling); ui->verticalLayout->insertWidget(count++, button); } if (int c = model->countInfo(Transaction::InfoUpdating)) { - QToolButton *button = new QToolButton(this); + auto button = new QToolButton(this); button->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); button->setCheckable(true); button->setAutoRaise(true); button->setIconSize(QSize(32, 32)); button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); button->setText(i18np("1 package to update", "%1 packages to update", c)); button->setIcon(PkIcons::actionIcon(Transaction::RoleUpdatePackages)); m_buttonGroup->addButton(button, Transaction::InfoUpdating); ui->verticalLayout->insertWidget(count++, button); } if (int c = model->countInfo(Transaction::InfoUntrusted)) { m_untrustedButton = new QToolButton(this); m_untrustedButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); m_untrustedButton->setCheckable(true); m_untrustedButton->setAutoRaise(true); m_untrustedButton->setIconSize(QSize(32, 32)); m_untrustedButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); m_untrustedButton->setText(i18np("1 untrusted package", "%1 untrusted packages", c)); m_untrustedButton->setIcon(QIcon::fromTheme("security-low")); m_untrustedButton->setVisible(false); ui->verticalLayout->insertWidget(count++, m_untrustedButton); } if (!m_buttonGroup->buttons().isEmpty()) { m_buttonGroup->buttons().first()->click(); if (m_hideAutoConfirm) { ui->confirmCB->setVisible(false); } else { // if the confirmCB is visible means that we can skip this // dialog, but only if the user previusly set so ui->confirmCB->setChecked(requirementsDialog.readEntry("autoConfirm", false)); } } else if (m_untrustedButton) { showUntrustedButton(); } else { // set this as false so the dialog is not shown m_shouldShow = false; } } Requirements::~Requirements() { KConfig config("apper"); KConfigGroup requirementsDialog(&config, "requirementsDialog"); requirementsDialog.writeEntry("geometry", saveGeometry()); delete ui; } bool Requirements::embedded() const { return m_embed; } void Requirements::setEmbedded(bool embedded) { m_embed = embedded; ui->label->setVisible(!embedded); } void Requirements::setDownloadSizeRemaining(qulonglong size) { QPushButton *help = ui->buttonBox->button(QDialogButtonBox::Help); if (size) { KFormat f; QString text; text = i18nc("how many bytes are required for download", "Need to get %1 of archives", f.formatByteSize(size)); help->setText(text); help->setToolTip(text); help->show(); } else { help->hide(); } } bool Requirements::trusted() const { // There are untrusted packages if the button was created... return !m_untrustedButton; } bool Requirements::shouldShow() const { return (m_shouldShow && !ui->confirmCB->isChecked()); } void Requirements::slotButtonClicked(int) { // FIXME // if (button == KDialog::Ok && // m_untrustedButton && // !m_untrustedButton->isVisible()) { // showUntrustedButton(); // } else { // KDialog::slotButtonClicked(button); // } } void Requirements::on_confirmCB_Toggled(bool checked) { KConfig config("apper"); KConfigGroup requirementsDialog(&config, "requirementsDialog"); if (!m_hideAutoConfirm) { requirementsDialog.writeEntry("autoConfirm", checked); } config.sync(); } void Requirements::actionClicked(int type) { - ApplicationSortFilterModel *proxy; - proxy = qobject_cast(ui->packageView->model()); + auto proxy = qobject_cast(ui->packageView->model()); proxy->setInfoFilter(static_cast(type)); } void Requirements::showUntrustedButton() { // Clear the other buttons - foreach (QAbstractButton *button, m_buttonGroup->buttons()) { - delete button; - } + qDeleteAll(m_buttonGroup->buttons()); // Hide the auto confirm button since we will be showing this dialog anyway ui->confirmCB->setVisible(false); ui->label->setText(i18n("You are about to install unsigned packages that can compromise your system, " "as it is impossible to verify if the software came from a trusted source.")); m_untrustedButton->setVisible(true); m_buttonGroup->addButton(m_untrustedButton, Transaction::InfoUntrusted); m_untrustedButton->click(); } #include "moc_Requirements.cpp"