File indexing completed on 2024-04-14 05:38:47

0001 /***************************************************************************
0002  *   Copyright (C) 2004 by Juanjo Álvarez Martinez <juanjo@juanjoalvarez.net> *
0003  *   Copyright (C) 2004 by Mario Bensi <nef@ipsquad.net>                   *
0004  *   Copyright (C) 2004 by Kevin Ottens <ervin@kde.org>                    *
0005  *   Copyright (C) 2004, 2008-2009 by Pino Toscano <pino@kde.org>          *
0006  *   Copyright (C) 2008 by Armin Berres <armin@space-based.de>             *
0007  *                                                                         *
0008  *   This program is free software; you can redistribute it and/or modify  *
0009  *   it under the terms of the GNU General Public License as published by  *
0010  *   the Free Software Foundation; either version 2 of the License, or     *
0011  *   (at your option) any later version.                                   *
0012  *                                                                         *
0013  *   This program is distributed in the hope that it will be useful,       *
0014  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0015  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0016  *   GNU General Public License for more details.                          *
0017  *                                                                         *
0018  *   You should have received a copy of the GNU General Public License     *
0019  *   along with this program; if not, write to the                         *
0020  *   Free Software Foundation, Inc.,                                       *
0021  *   51 Franklin Steet, Fifth Floor, Boston, MA  02111-1307, USA.          *
0022  ***************************************************************************/
0023 
0024 #include "kalternatives.h"
0025 #include "altparser.h"
0026 #include "addalternatives.h"
0027 #include "alternativemodels.h"
0028 #include "ui_propertieswindow.h"
0029 #include "aboutdata.h"
0030 #include "slavemodel.h"
0031 
0032 #include <qdialog.h>
0033 #include <qdialogbuttonbox.h>
0034 #include <qheaderview.h>
0035 #include <qitemselectionmodel.h>
0036 #include <qtimer.h>
0037 
0038 #include <kmessagebox.h>
0039 #include <kaboutdata.h>
0040 #include <klazylocalizedstring.h>
0041 #include <kpluginfactory.h>
0042 #include <kstandardguiitem.h>
0043 
0044 #include <unistd.h>
0045 #include <sys/types.h>
0046 
0047 K_PLUGIN_FACTORY(KalternativesFactory, registerPlugin<Kalternatives>();)
0048 
0049 static inline QString componentName()
0050 {
0051     return QStringLiteral("kalternatives");
0052 }
0053 
0054 Kalternatives::Kalternatives(QWidget *parent, const QVariantList& args)
0055     : KCModule(parent, args)
0056 {
0057     auto *aboutData = new KAboutData(::aboutData(componentName(), kli18n("Kalternatives").untranslatedText()));
0058     setAboutData(aboutData);
0059 
0060     setUseRootOnlyMessage(false);
0061 
0062     int user = getuid();
0063     
0064     if (user == 0)
0065     {
0066         m_bisRoot = true;
0067         setButtons(KCModule::Help|KCModule::Apply);
0068     }
0069     else 
0070     {
0071         m_bisRoot = false;
0072         setButtons(Help);
0073     }
0074     
0075     m_ui.setupUi(this);
0076     m_ui.m_mainSplitter->setStretchFactor(1, 5);
0077     
0078     connect(m_ui.m_altList, SIGNAL(clicked(QModelIndex)),
0079             this, SLOT(slotSelectAlternativesActivated(QModelIndex)));
0080     
0081     connect(m_ui.m_bAdd, SIGNAL(clicked()), this,
0082             SLOT(slotAddClicked()));
0083     connect(m_ui.m_bDelete, SIGNAL(clicked()), this,
0084             SLOT(slotDeleteClicked()));
0085     connect(m_ui.m_bProperties, SIGNAL(clicked()), this,
0086             SLOT(slotPropertiesClicked()));
0087     
0088     KStandardGuiItem::assign(m_ui.m_bDelete, KStandardGuiItem::Delete);
0089     m_ui.m_bDelete->setWhatsThis(i18n("Removes the selected alternative from the current group."));
0090     KGuiItem::assign(m_ui.m_bAdd, KGuiItem(i18n("&Add"), "list-add",
0091                                            i18n("Adds a new alternative for the selected group.")));
0092     KGuiItem::assign(m_ui.m_bProperties, KGuiItem(i18n("&Properties"), "configure",
0093                                                   i18n("Shows the properties (path, priority, and slaves) of the selected alternative.")));
0094     
0095     m_ui.m_statusCombo->addItem(i18nc("Automatic alternative choice", "Automatic"), Item::AutoMode);
0096     m_ui.m_statusCombo->addItem(i18nc("Manual alternative choice", "Manual"), Item::ManualMode);
0097     
0098     m_ui.m_bDelete->setEnabled(false);
0099     m_ui.m_bAdd->setEnabled(false);
0100     m_ui.m_bProperties->setEnabled(false);
0101     if(!m_bisRoot)
0102     {
0103         m_ui.m_statusCombo->setEnabled(false);
0104     }
0105 }
0106 
0107 Kalternatives::~Kalternatives()
0108 {
0109 }
0110 
0111 void Kalternatives::load()
0112 {
0113     m_itemProxyModel = new AlternativeItemProxyModel(m_ui.m_altList);
0114     slotHideAlternativesClicked();
0115     AlternativeItemsModel *itemModel = new AlternativeItemsModel(componentName(), m_itemProxyModel);
0116     m_itemProxyModel->setSourceModel(itemModel);
0117     m_ui.m_altList->setModel(m_itemProxyModel);
0118     connect(itemModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)),
0119             this, SLOT(slotUpdateStatusCombo()));
0120     
0121     QHeaderView *h = m_ui.m_altList->header();
0122     h->resizeSections(QHeaderView::Stretch);
0123     h->resizeSection(0, h->sectionSizeHint(0));
0124     connect(m_ui.m_hideAlt, SIGNAL(clicked()), this,
0125             SLOT(slotHideAlternativesClicked()));
0126     
0127     QSortFilterProxyModel *altListSorter = new QSortFilterProxyModel(m_ui.m_optionsList);
0128     altListSorter->setDynamicSortFilter(true);
0129     m_altModel = new AlternativeAltModel(itemModel, !m_bisRoot, altListSorter);
0130     altListSorter->setSourceModel(m_altModel);
0131     m_ui.m_optionsList->setModel(altListSorter);
0132     m_ui.m_optionsList->header()->setSortIndicator(0, Qt::AscendingOrder);
0133     connect(m_altModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)),
0134             this, SLOT(configChanged()));
0135     connect(m_altModel, SIGNAL(rowsInserted(QModelIndex, int, int)),
0136             this, SLOT(configChanged()));
0137     connect(m_ui.m_statusCombo, SIGNAL(activated(int)),
0138             m_altModel, SLOT(statusChanged(int)));
0139 
0140     connect(m_ui.m_altList->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
0141             this, SLOT(slotUpdateButtons()));
0142     connect(m_ui.m_optionsList->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
0143             this, SLOT(slotUpdateButtons()));
0144 }
0145 
0146 void Kalternatives::slotSelectAlternativesActivated(const QModelIndex &index)
0147 {
0148     Item *item = index.data(AltItemRole).value<Item *>();
0149     m_altModel->setItem(item);
0150     m_ui.m_altTilte->setText(item->getName());
0151     const int statusIndex = m_ui.m_statusCombo->findData(item->getMode());
0152     Q_ASSERT(statusIndex != -1);
0153     m_ui.m_statusCombo->setCurrentIndex(statusIndex);
0154     slotUpdateButtons();
0155 }
0156 
0157 void Kalternatives::slotHideAlternativesClicked()
0158 {
0159     m_itemProxyModel->setShowSingleAlternative(!m_ui.m_hideAlt->isChecked());
0160 }
0161 
0162 void Kalternatives::slotAddClicked()
0163 {
0164     Item *item = m_ui.m_altList->currentIndex().data(AltItemRole).value<Item *>();
0165     if (item)
0166     {
0167         AddAlternatives addAlternatives(item, this);
0168         addAlternatives.exec();
0169         if (Alternative *a = addAlternatives.alternative())
0170         {
0171             m_altModel->addAlternative(a);
0172         }
0173     }
0174 }
0175 
0176 void Kalternatives::slotDeleteClicked()
0177 {
0178     Alternative *alt = m_ui.m_optionsList->currentIndex().data(AltAlternativeRole).value<Alternative *>();
0179     if (alt)
0180     {
0181         const QString messageText = i18n("Are you really sure you want to delete the alternative '%1'?", alt->getPath());
0182         if (KMessageBox::warningYesNo(this, messageText, i18n("Delete Alternative")) == KMessageBox::Yes)
0183         {
0184             m_altModel->removeAlternative(alt);
0185         }
0186     }
0187 }
0188 
0189 void Kalternatives::slotPropertiesClicked()
0190 {
0191     Alternative *a = m_ui.m_optionsList->currentIndex().data(AltAlternativeRole).value<Alternative *>();
0192     if (a)
0193     {
0194         QString text;
0195         QDialog *prop = new QDialog(this);
0196         prop->setWindowTitle(i18n("Alternative Properties"));
0197         QVBoxLayout *lay = new QVBoxLayout(prop);
0198         QWidget *main = new QWidget(prop);
0199         Ui::PropertiesWindow propUi;
0200         propUi.setupUi(main);
0201         main->layout()->setContentsMargins(0, 0, 0, 0);
0202         lay->addWidget(main);
0203         QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Close, prop);
0204         lay->addWidget(buttons);
0205         connect(buttons, SIGNAL(rejected()), prop, SLOT(deleteLater()));
0206         
0207         propUi.labelPath->setText(a->getPath());
0208         propUi.labelDescription->setText(Alternative::prettyDescription(a));
0209         propUi.labelPriority->setText(QString::number(a->getPriority()));
0210         
0211         if (a->slavesCount() > 0)
0212         {
0213             SlaveModel *sm = new SlaveModel(propUi.slaveView);
0214             sm->setItem(a->getParent());
0215             sm->setAlternative(a);
0216             propUi.slaveView->setModel(sm);
0217         }
0218         else
0219         {
0220             propUi.slavesGroup->hide();
0221         }
0222         
0223         prop->show();
0224     }
0225 }
0226 
0227 void Kalternatives::slotUpdateStatusCombo()
0228 {
0229     Item *item = m_ui.m_altList->currentIndex().data(AltItemRole).value<Item *>();
0230     if (item)
0231     {
0232         const int statusIndex = m_ui.m_statusCombo->findData(item->getMode());
0233         Q_ASSERT(statusIndex != -1);
0234         m_ui.m_statusCombo->setCurrentIndex(statusIndex);
0235         emit changed(true);
0236     }
0237 }
0238 
0239 void Kalternatives::slotUpdateButtons()
0240 {
0241     if (m_bisRoot)
0242     {
0243         const bool altSelected = m_ui.m_altList->selectionModel()->hasSelection();
0244         m_ui.m_bAdd->setEnabled(altSelected);
0245     }
0246     const bool altChoiceSelected = m_ui.m_optionsList->selectionModel()->currentIndex().isValid();
0247     m_ui.m_bProperties->setEnabled(altChoiceSelected);
0248     if (m_bisRoot)
0249     {
0250         m_ui.m_bDelete->setEnabled(altChoiceSelected);
0251     }
0252 }
0253 
0254 void Kalternatives::save()
0255 {
0256     AlternativeItemsModel *model = qobject_cast<AlternativeItemsModel *>(m_itemProxyModel->sourceModel());
0257     model->save();
0258     emit changed( false );
0259 }
0260 
0261 void Kalternatives::configChanged()
0262 {
0263     emit changed(true);
0264 }
0265 
0266 QString Kalternatives::quickHelp() const
0267 {
0268     return i18n("<h1>Alternatives Configuration</h1>\n"
0269                 "This module allows you to configure the system alternatives in "
0270                 "Debian/Fedora/Mandriva/openSUSE/Ubuntu distributions.");
0271 
0272 }
0273 
0274 #include <kalternatives.moc>