File indexing completed on 2024-04-21 05:45:00

0001 /***************************************************************************
0002  *   Copyright (C) 2008-2011 by Daniel Nicoletti                           *
0003  *   dantti12@gmail.com                                                    *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  *                                                                         *
0010  *   This program is distributed in the hope that it will be useful,       *
0011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0013  *   GNU General Public License for more details.                          *
0014  *                                                                         *
0015  *   You should have received a copy of the GNU General Public License     *
0016  *   along with this program; see the file COPYING. If not, write to       *
0017  *   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,  *
0018  *   Boston, MA 02110-1301, USA.                                           *
0019  ***************************************************************************/
0020 
0021 #include "Settings.h"
0022 #include "ui_Settings.h"
0023 
0024 #include "OriginModel.h"
0025 #include <Daemon>
0026 
0027 #include <Enum.h>
0028 #include <PkStrings.h>
0029 
0030 #include <QAction>
0031 #include <QTimer>
0032 #include <QSortFilterProxyModel>
0033 
0034 #include <KMessageBox>
0035 #include <KPixmapSequence>
0036 #include <KToolInvocation>
0037 #include <KLocalizedString>
0038 #include <KIconLoader>
0039 #include <KConfig>
0040 #include <KConfigGroup>
0041 #include <KFormat>
0042 
0043 #include <Solid/Device>
0044 #include <Solid/Battery>
0045 
0046 #include <config.h>
0047 
0048 #include <QLoggingCategory>
0049 
0050 Q_DECLARE_LOGGING_CATEGORY(APPER)
0051 
0052 using namespace PackageKit;
0053 
0054 Settings::Settings(Transaction::Roles roles, QWidget *parent) :
0055     QWidget(parent),
0056     ui(new Ui::Settings),
0057     m_roles(roles)
0058 {
0059     ui->setupUi(this);
0060 
0061     auto action = new QAction(i18n("Refresh Cache"), this);
0062     connect(action, &QAction::triggered, this, &Settings::refreshCache);
0063     connect(action, &QAction::triggered, ui->messageWidget, &KMessageWidget::animatedHide);
0064     ui->messageWidget->addAction(action);
0065     ui->messageWidget->setText(i18n("A repository was changed, it's highly recommended to refresh the cache"));
0066     ui->messageWidget->hide();
0067 
0068     if (!(m_roles & Transaction::RoleRefreshCache)) {
0069         ui->intervalL->setEnabled(false);
0070         ui->intervalCB->setEnabled(false);
0071     }
0072 
0073     if (!(m_roles & Transaction::RoleGetDistroUpgrades)) {
0074         ui->distroIntervalCB->setEnabled(false);
0075     }
0076 
0077     m_originModel = new OriginModel(this);
0078     connect(m_originModel, &OriginModel::refreshRepoList, this, &Settings::refreshRepoModel);
0079     connect(m_originModel, &OriginModel::refreshRepoList, ui->messageWidget, &KMessageWidget::animatedShow);
0080     auto proxy = new QSortFilterProxyModel(this);
0081     proxy->setDynamicSortFilter(true);
0082     proxy->setSourceModel(m_originModel);
0083     ui->originTV->setModel(proxy);
0084     ui->originTV->header()->setDefaultAlignment(Qt::AlignCenter);
0085     // This is needed to keep the oring right
0086     ui->originTV->header()->setSortIndicator(0, Qt::AscendingOrder);
0087     proxy->sort(0);
0088     if (!(m_roles & Transaction::RoleGetRepoList)) {
0089         // Disables the group box
0090         ui->originTV->setEnabled(false);
0091         ui->showOriginsCB->setEnabled(false);
0092     }
0093 
0094     ui->distroIntervalCB->addItem(i18nc("Inform about distribution upgrades",
0095                                         "Never"),
0096                                   Enum::DistroNever);
0097     ui->distroIntervalCB->addItem(i18nc("Inform about distribution upgrades",
0098                                         "Only stable"),
0099                                   Enum::DistroStable);
0100     // Ignore unstable distros upgrades for now
0101 #ifndef false
0102     ui->distroIntervalCB->addItem(i18nc("Inform about distribution upgrades",
0103                                         "Stable and development"),
0104                                   Enum::DistroDevelopment);
0105 #endif
0106 
0107     ui->intervalCB->addItem(i18nc("Hourly refresh the package cache", "Hourly"), Enum::Hourly);
0108     ui->intervalCB->addItem(i18nc("Daily refresh the package cache", "Daily"), Enum::Daily);
0109     ui->intervalCB->addItem(i18nc("Weekly refresh the package cache", "Weekly"), Enum::Weekly);
0110     ui->intervalCB->addItem(i18nc("Monthly refresh the package cache", "Monthly"), Enum::Monthly);
0111     ui->intervalCB->addItem(i18nc("Never refresh package cache", "Never"), Enum::Never);
0112 
0113     ui->autoCB->addItem(i18nc("No updates will be automatically installed", "None"), Enum::None);
0114     ui->autoCB->addItem(i18n("Download only"), Enum::DownloadOnly);
0115     ui->autoCB->addItem(i18n("Security only"), Enum::Security);
0116     ui->autoCB->addItem(i18n("All updates"), Enum::All);
0117 
0118     connect(ui->autoConfirmCB, &QCheckBox::stateChanged, this, &Settings::checkChanges);
0119     connect(ui->appLauncherCB, &QCheckBox::stateChanged, this, &Settings::checkChanges);
0120     connect(ui->distroIntervalCB, QOverload<int>::of(&KComboBox::currentIndexChanged), this, &Settings::checkChanges);
0121     connect(ui->intervalCB, QOverload<int>::of(&KComboBox::currentIndexChanged), this, &Settings::checkChanges);
0122     connect(ui->checkUpdatesBatteryCB, &QCheckBox::stateChanged, this, &Settings::checkChanges);
0123     connect(ui->checkUpdatesMobileCB, &QCheckBox::stateChanged, this, &Settings::checkChanges);
0124     connect(ui->autoCB, QOverload<int>::of(&KComboBox::currentIndexChanged), this, &Settings::checkChanges);
0125     connect(ui->installUpdatesBatteryCB, &QCheckBox::stateChanged, this, &Settings::checkChanges);
0126     connect(ui->installUpdatesMobileCB, &QCheckBox::stateChanged, this, &Settings::checkChanges);
0127 
0128     // Setup buttons
0129     QPushButton *apply = ui->buttonBox->button(QDialogButtonBox::Apply);
0130     apply->setEnabled(false);
0131     connect(apply, &QPushButton::clicked, this, &Settings::save);
0132     connect(this, &Settings::changed, apply, &QPushButton::setEnabled);
0133 
0134     QPushButton *reset = ui->buttonBox->button(QDialogButtonBox::Reset);
0135 //    reset->setEnabled(false);
0136     connect(reset, &QPushButton::clicked, this, &Settings::defaults);
0137 //    connect(this, &Settings::changed, reset, &QPushButton::setDisabled);
0138 
0139     // Setup the busy cursor
0140     m_busySeq = new KPixmapSequenceOverlayPainter(this);
0141     m_busySeq->setSequence(KIconLoader::global()->loadPixmapSequence(QLatin1String("process-working"), KIconLoader::SizeSmallMedium));
0142     m_busySeq->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
0143     m_busySeq->setWidget(ui->originTV->viewport());
0144 
0145 #ifndef EDIT_ORIGNS_DESKTOP_NAME
0146     ui->editOriginsPB->hide();
0147 #endif //EDIT_ORIGNS_DESKTOP_NAME
0148 }
0149 
0150 Settings::~Settings()
0151 {
0152     delete ui;
0153 }
0154 
0155 void Settings::on_editOriginsPB_clicked()
0156 {
0157 #ifdef EDIT_ORIGNS_DESKTOP_NAME
0158     KToolInvocation::startServiceByDesktopName(QLatin1String(EDIT_ORIGNS_DESKTOP_NAME));
0159 #endif //EDIT_ORIGNS_DESKTOP_NAME
0160 }
0161 
0162 void Settings::refreshRepoModel()
0163 {
0164     on_showOriginsCB_stateChanged(ui->showOriginsCB->checkState());
0165 }
0166 
0167 // TODO update the repo list connecting to repo changed signal
0168 void Settings::on_showOriginsCB_stateChanged(int state)
0169 {
0170     Transaction *transaction = Daemon::getRepoList(state == Qt::Checked ?
0171                                                        Transaction::FilterNone : Transaction::FilterNotDevel);
0172     connect(transaction, &Transaction::repoDetail, m_originModel, &OriginModel::addOriginItem);
0173     connect(transaction, &Transaction::finished, m_originModel, &OriginModel::finished);
0174     connect(transaction, &Transaction::finished, m_busySeq, &KPixmapSequenceOverlayPainter::stop);
0175     connect(transaction, &Transaction::finished, this, &Settings::checkChanges);
0176 
0177     m_busySeq->start();
0178 
0179     KConfig config(QLatin1String("apper"));
0180     KConfigGroup originsDialog(&config, "originsDialog");
0181     bool showDevel = originsDialog.readEntry("showDevel", false);
0182     if (showDevel != ui->showOriginsCB->isChecked()) {
0183         originsDialog.writeEntry("showDevel", ui->showOriginsCB->isChecked());
0184     }
0185 }
0186 
0187 bool Settings::hasChanges() const
0188 {
0189     KConfig config(QLatin1String("apper"));
0190 
0191     KConfigGroup requirementsDialog(&config, "requirementsDialog");
0192     KConfigGroup transaction(&config, "Transaction");
0193     KConfigGroup checkUpdateGroup(&config, "CheckUpdate");
0194     if (ui->distroIntervalCB->itemData(ui->distroIntervalCB->currentIndex()).toUInt() !=
0195             static_cast<uint>(checkUpdateGroup.readEntry(CFG_DISTRO_UPGRADE, Enum::DistroUpgradeDefault))
0196         ||
0197             ui->intervalCB->itemData(ui->intervalCB->currentIndex()).toUInt() !=
0198             static_cast<uint>(checkUpdateGroup.readEntry(CFG_INTERVAL, Enum::TimeIntervalDefault))
0199         ||
0200         ui->checkUpdatesBatteryCB->isChecked() != checkUpdateGroup.readEntry(CFG_CHECK_UP_BATTERY, DEFAULT_CHECK_UP_BATTERY)
0201         ||
0202         ui->checkUpdatesMobileCB->isChecked() != checkUpdateGroup.readEntry(CFG_CHECK_UP_MOBILE, DEFAULT_CHECK_UP_MOBILE)
0203         ||
0204         ui->autoCB->itemData(ui->autoCB->currentIndex()).toUInt() !=
0205         static_cast<uint>(checkUpdateGroup.readEntry(CFG_AUTO_UP, Enum::AutoUpdateDefault))
0206         ||
0207         ui->installUpdatesBatteryCB->isChecked()  != checkUpdateGroup.readEntry(CFG_INSTALL_UP_BATTERY, DEFAULT_INSTALL_UP_BATTERY)
0208         ||
0209         ui->installUpdatesMobileCB->isChecked() != checkUpdateGroup.readEntry(CFG_INSTALL_UP_MOBILE, DEFAULT_INSTALL_UP_MOBILE)
0210         ||
0211         ui->autoConfirmCB->isChecked() != !requirementsDialog.readEntry("autoConfirm", false)
0212         ||
0213         ui->appLauncherCB->isChecked() != transaction.readEntry("ShowApplicationLauncher", true)) {
0214         return true;
0215     }
0216     return false;
0217 }
0218 
0219 void Settings::checkChanges()
0220 {
0221     emit changed(hasChanges());
0222 
0223     // Check if interval update is never
0224     bool enabled = ui->intervalCB->itemData(ui->intervalCB->currentIndex()).toUInt() != Enum::Never;
0225     ui->checkUpdatesBatteryCB->setEnabled(enabled);
0226     ui->checkUpdatesMobileCB->setEnabled(enabled);
0227 
0228     ui->autoInsL->setEnabled(enabled);
0229     ui->autoCB->setEnabled(enabled);
0230     if (enabled) {
0231         enabled = ui->autoCB->itemData(ui->autoCB->currentIndex()).toUInt() != Enum::None;
0232     }
0233     ui->installUpdatesMobileCB->setEnabled(enabled);
0234     ui->installUpdatesBatteryCB->setEnabled(enabled);
0235 }
0236 
0237 void Settings::load()
0238 {
0239     KConfig config(QLatin1String("apper"));
0240 
0241     KConfigGroup requirementsDialog(&config, "requirementsDialog");
0242     ui->autoConfirmCB->setChecked(!requirementsDialog.readEntry("autoConfirm", false));
0243 
0244     KConfigGroup transaction(&config, "Transaction");
0245     ui->appLauncherCB->setChecked(transaction.readEntry("ShowApplicationLauncher", true));
0246 
0247     KConfigGroup checkUpdateGroup(&config, "CheckUpdate");
0248     uint distroUpgrade = checkUpdateGroup.readEntry(CFG_DISTRO_UPGRADE, Enum::DistroUpgradeDefault);
0249     int ret = ui->distroIntervalCB->findData(distroUpgrade);
0250     if (ret == -1) {
0251         ui->distroIntervalCB->setCurrentIndex(ui->distroIntervalCB->findData(Enum::DistroUpgradeDefault));
0252     } else {
0253         ui->distroIntervalCB->setCurrentIndex(ret);
0254     }
0255 
0256     uint interval = checkUpdateGroup.readEntry(CFG_INTERVAL, Enum::TimeIntervalDefault);
0257     ret = ui->intervalCB->findData(interval);
0258     if (ret == -1) {
0259         // this is if someone change the file by hand...
0260         ui->intervalCB->addItem(KFormat().formatSpelloutDuration(interval * 1000), interval);
0261         ui->intervalCB->setCurrentIndex(ui->intervalCB->count() - 1);
0262     } else {
0263         ui->intervalCB->setCurrentIndex(ret);
0264     }
0265     ui->checkUpdatesBatteryCB->setChecked(checkUpdateGroup.readEntry(CFG_CHECK_UP_BATTERY, DEFAULT_CHECK_UP_BATTERY));
0266     ui->checkUpdatesMobileCB->setChecked(checkUpdateGroup.readEntry(CFG_CHECK_UP_MOBILE, DEFAULT_CHECK_UP_MOBILE));
0267 
0268     uint autoUpdate = checkUpdateGroup.readEntry(CFG_AUTO_UP, Enum::AutoUpdateDefault);
0269     ret = ui->autoCB->findData(autoUpdate);
0270     if (ret == -1) {
0271         // this is if someone change the file by hand...
0272         ui->autoCB->setCurrentIndex(ui->autoCB->findData(Enum::AutoUpdateDefault));
0273     } else {
0274         ui->autoCB->setCurrentIndex(ret);
0275     }
0276     ui->installUpdatesBatteryCB->setChecked(checkUpdateGroup.readEntry(CFG_INSTALL_UP_BATTERY, DEFAULT_INSTALL_UP_BATTERY));
0277     ui->installUpdatesMobileCB->setChecked(checkUpdateGroup.readEntry(CFG_INSTALL_UP_MOBILE, DEFAULT_INSTALL_UP_MOBILE));
0278 
0279     // Load origns list
0280     if (m_roles & Transaction::RoleGetRepoList) {
0281         KConfigGroup originsDialog(&config, "originsDialog");
0282         bool showDevel = originsDialog.readEntry("showDevel", false);
0283         ui->showOriginsCB->setChecked(showDevel);
0284         refreshRepoModel();
0285         ui->originTV->setEnabled(true);
0286     } else {
0287         ui->originTV->setEnabled(false);
0288     }
0289 
0290     // hide battery options if we are on a desktop computer
0291     const QList<Solid::Device> listBattery = Solid::Device::listFromType(Solid::DeviceInterface::Battery, QString());
0292     bool notFound = true;
0293     for (const Solid::Device &device : listBattery) {
0294         const Solid::Battery *battery = device.as<Solid::Battery>();
0295         if (battery && battery->type() == Solid::Battery::PrimaryBattery) {
0296             notFound = false;
0297             break;
0298         }
0299     }
0300 
0301     if (notFound) {
0302         ui->checkUpdatesBatteryCB->hide();
0303         ui->installUpdatesBatteryCB->hide();
0304     }
0305 }
0306 
0307 void Settings::save()
0308 {
0309     qCDebug(APPER) << "Saving settings";
0310 
0311     KConfig config(QLatin1String("apper"));
0312 
0313     KConfigGroup requirementsDialog(&config, "requirementsDialog");
0314     requirementsDialog.writeEntry("autoConfirm", !ui->autoConfirmCB->isChecked());
0315 
0316     KConfigGroup transaction(&config, "Transaction");
0317     transaction.writeEntry("ShowApplicationLauncher", ui->appLauncherCB->isChecked());
0318 
0319     KConfigGroup checkUpdateGroup(&config, "CheckUpdate");
0320     checkUpdateGroup.writeEntry("distroUpgrade", ui->distroIntervalCB->itemData(ui->distroIntervalCB->currentIndex()).toUInt());
0321     checkUpdateGroup.writeEntry("interval", ui->intervalCB->itemData(ui->intervalCB->currentIndex()).toUInt());
0322     checkUpdateGroup.writeEntry("checkUpdatesOnBattery", ui->checkUpdatesBatteryCB->isChecked());
0323     checkUpdateGroup.writeEntry("checkUpdatesOnMobile", ui->checkUpdatesMobileCB->isChecked());
0324 
0325     checkUpdateGroup.writeEntry("autoUpdate", ui->autoCB->itemData(ui->autoCB->currentIndex()).toUInt());
0326     checkUpdateGroup.writeEntry("installUpdatesOnBattery", ui->installUpdatesBatteryCB->isChecked());
0327     checkUpdateGroup.writeEntry("installUpdatesOnMobile", ui->installUpdatesMobileCB->isChecked());
0328 
0329     emit changed(false);
0330 }
0331 
0332 void Settings::defaults()
0333 {
0334     qCDebug(APPER) << "Restoring default settings";
0335 
0336     ui->autoConfirmCB->setChecked(true);
0337     ui->appLauncherCB->setChecked(true);
0338     ui->distroIntervalCB->setCurrentIndex(ui->distroIntervalCB->findData(Enum::DistroUpgradeDefault));
0339     ui->intervalCB->setCurrentIndex(ui->intervalCB->findData(Enum::TimeIntervalDefault));
0340     ui->autoCB->setCurrentIndex(ui->autoCB->findData(Enum::AutoUpdateDefault) );
0341     checkChanges();
0342 }
0343 
0344 void Settings::showGeneralSettings()
0345 {
0346     ui->stackedWidget->setCurrentIndex(0);
0347 }
0348 
0349 void Settings::showRepoSettings()
0350 {
0351     ui->stackedWidget->setCurrentIndex(1);
0352 }
0353 
0354 #include "moc_Settings.cpp"