File indexing completed on 2024-05-05 04:51:38

0001 /*
0002     SPDX-FileCopyrightText: 2010 Michal Malek <michalm@jabster.pl>
0003     SPDX-FileCopyrightText: 1998-2008 Sebastian Trueg <trueg@k3b.org>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "k3bexternalbinwidget.h"
0009 #include "k3bexternalbinmanager.h"
0010 #include "k3bexternalbinmodel.h"
0011 #include "k3bexternalbinparamsmodel.h"
0012 #include "k3bexternalbinpermissionmodel.h"
0013 #include "config-k3b.h"
0014 
0015 #include <KAuth/Action>
0016 #include <KAuth/ExecuteJob>
0017 #include <KLocalizedString>
0018 #include <KMessageBox>
0019 #include <KEditListWidget>
0020 
0021 #include <QDebug>
0022 #include <QItemSelectionModel>
0023 #include <QMap>
0024 #include <QStringList>
0025 #include <QCursor>
0026 #include <QPixmap>
0027 #include <QApplication>
0028 #include <QHeaderView>
0029 #include <QLabel>
0030 #include <QLayout>
0031 #include <QPushButton>
0032 #include <QTabWidget>
0033 #include <QToolTip>
0034 #include <QTreeView>
0035 #include <QVBoxLayout>
0036 
0037 #include <grp.h>
0038 
0039 
0040 
0041 // ///////////////////////////////////////////////////////////
0042 //
0043 // K3BEXTERNALBINWIDGET
0044 //
0045 // //////////////////////////////////////////////////////////
0046 
0047 
0048 K3b::ExternalBinWidget::ExternalBinWidget( K3b::ExternalBinManager* manager, QWidget* parent )
0049     : QWidget( parent ),
0050       m_manager( manager ),
0051       m_programModel( new ExternalBinModel( manager, this ) ),
0052       m_parameterModel( new ExternalBinParamsModel( manager, this ) )
0053 {
0054     QGridLayout* mainGrid = new QGridLayout( this );
0055     mainGrid->setContentsMargins( 0, 0, 0, 0 );
0056 
0057     m_mainTabWidget = new QTabWidget( this );
0058     m_rescanButton = new QPushButton( QIcon::fromTheme( "view-refresh" ), i18n( "Refresh" ), this );
0059     mainGrid->addWidget( m_mainTabWidget, 0, 0, 1, 3 );
0060     mainGrid->addWidget( m_rescanButton, 1, 2 );
0061     mainGrid->setColumnStretch( 0, 1 );
0062     mainGrid->setRowStretch( 0, 1 );
0063 
0064     // setup program tab
0065     // ------------------------------------------------------------
0066     QWidget* programTab = new QWidget( m_mainTabWidget );
0067     m_programView = new QTreeView( programTab );
0068     m_programView->setModel( m_programModel );
0069     m_programView->setAllColumnsShowFocus( true );
0070     m_programView->setRootIsDecorated( false );
0071     m_programView->setItemsExpandable( false );
0072     m_programView->header()->setSectionResizeMode( ExternalBinModel::PathColumn, QHeaderView::ResizeToContents );
0073     m_programView->header()->setSectionResizeMode( ExternalBinModel::VersionColumn, QHeaderView::ResizeToContents );
0074     m_programView->setWhatsThis( i18n("<p>If K3b finds more than one installed version of a program "
0075                                       "it will choose one as the <em>default</em>, which will be used "
0076                                       "to do the work. If you want to change the default, check "
0077                                       "desired version on the list.") );
0078 
0079     QVBoxLayout* programTabLayout = new QVBoxLayout( programTab );
0080     programTabLayout->addWidget( m_programView );
0081 
0082     m_mainTabWidget->addTab( programTab, i18n("Programs") );
0083 
0084 
0085     // setup parameters tab
0086     // ------------------------------------------------------------
0087     QWidget* parametersTab = new QWidget( m_mainTabWidget );
0088     QLabel* parametersLabel = new QLabel( i18n("User parameters have to be separated by space."), parametersTab );
0089     parametersLabel->setWordWrap( true );
0090     m_parameterView = new QTreeView( parametersTab );
0091     m_parameterView->setModel( m_parameterModel );
0092     m_parameterView->setAllColumnsShowFocus( true );
0093     m_parameterView->setRootIsDecorated( false );
0094     m_parameterView->setEditTriggers( QAbstractItemView::AllEditTriggers );
0095     m_parameterView->header()->setSectionResizeMode( QHeaderView::ResizeToContents );
0096 
0097     QVBoxLayout* parametersTabLayout = new QVBoxLayout( parametersTab );
0098     parametersTabLayout->addWidget( parametersLabel );
0099     parametersTabLayout->addWidget( m_parameterView, 1 );
0100 
0101     m_mainTabWidget->addTab( parametersTab, i18n("User Parameters") );
0102 
0103 
0104     // setup permissions tab
0105     // ------------------------------------------------------------
0106     QWidget* permissionsTab = new QWidget( m_mainTabWidget );
0107     QLabel* permissionsLabel = new QLabel( i18n("Check the programs whose permissions you want to be changed:"), permissionsTab );
0108     permissionsLabel->setWordWrap( true );
0109     m_permissionModel = new ExternalBinPermissionModel( *manager, permissionsTab );
0110     m_permissionView = new QTreeView( permissionsTab );
0111     m_permissionView->setModel( m_permissionModel );
0112     m_permissionView->setAllColumnsShowFocus( true );
0113     m_permissionView->setRootIsDecorated( false );
0114     m_permissionView->header()->setSectionResizeMode( ExternalBinPermissionModel::ProgramColumn, QHeaderView::ResizeToContents );
0115     m_changePermissionsButton = new QPushButton( QIcon::fromTheme("dialog-password"), i18n( "Change Permissions..." ), this );
0116     QVBoxLayout* permissionsTabLayout = new QVBoxLayout( permissionsTab );
0117     permissionsTabLayout->addWidget( permissionsLabel );
0118     permissionsTabLayout->addWidget( m_permissionView );
0119     permissionsTabLayout->addWidget( m_changePermissionsButton );
0120     m_mainTabWidget->addTab( permissionsTab, i18n("Permissions") );
0121 
0122 
0123     // setup search path tab
0124     // ------------------------------------------------------------
0125     QWidget* searchPathTab = new QWidget( m_mainTabWidget );
0126     m_searchPathBox = new KEditListWidget( searchPathTab );
0127     m_searchPathBox->setCheckAtEntering( true );
0128     QLabel* hintLabel = new QLabel( i18n("<qt><b>Hint:</b> to force K3b to use another than the "
0129                                          "default name for the executable specify it in the search path.</qt>"),
0130                                     searchPathTab );
0131     hintLabel->setWordWrap( true );
0132     QVBoxLayout* searchPathTabLayout = new QVBoxLayout( searchPathTab );
0133     searchPathTabLayout->addWidget( m_searchPathBox, 1 );
0134     searchPathTabLayout->addWidget( hintLabel );
0135 
0136     m_mainTabWidget->addTab( searchPathTab, i18n("Search Path") );
0137 
0138     connect( m_changePermissionsButton, SIGNAL(clicked()), SLOT(slotChangePermissions()) );
0139     connect( m_permissionModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), SLOT(slotPermissionModelChanged()) );
0140     connect( m_permissionModel, SIGNAL(modelReset()), SLOT(slotPermissionModelChanged()) );
0141     connect( m_rescanButton, SIGNAL(clicked(bool)), this, SLOT(rescan()) );
0142 
0143     qRegisterMetaType<HelperProgramItem>();
0144 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0145     qRegisterMetaTypeStreamOperators<HelperProgramItem>("K3b::HelperProgramItem");
0146 #endif
0147 
0148     while (::group *g = ::getgrent()) {
0149         const QString groupName = QString::fromLocal8Bit(g->gr_name);
0150         if (groupName == "cdrom" ||
0151             groupName == "optical" ||
0152             groupName == "operator" ) {
0153             m_permissionModel->setBurningGroup(groupName);
0154         }
0155     }
0156     ::endgrent();
0157 }
0158 
0159 
0160 K3b::ExternalBinWidget::~ExternalBinWidget()
0161 {
0162 }
0163 
0164 void K3b::ExternalBinWidget::rescan()
0165 {
0166     QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) );
0167     saveSearchPath();
0168     m_manager->search();
0169     load();
0170     QApplication::restoreOverrideCursor();
0171 }
0172 
0173 
0174 void K3b::ExternalBinWidget::load()
0175 {
0176     m_programModel->reload();
0177     m_programView->expandAll();
0178     m_parameterModel->reload();
0179 
0180     // load search path
0181     m_searchPathBox->clear();
0182     m_searchPathBox->insertStringList( m_manager->searchPath() );
0183 }
0184 
0185 
0186 void K3b::ExternalBinWidget::save()
0187 {
0188     saveSearchPath();
0189 
0190     m_programModel->save();
0191     m_parameterModel->save();
0192 }
0193 
0194 
0195 void K3b::ExternalBinWidget::saveSearchPath()
0196 {
0197     m_manager->setSearchPath( m_searchPathBox->items() );
0198 }
0199 
0200 
0201 void K3b::ExternalBinWidget::slotPermissionModelChanged()
0202 {
0203     m_changePermissionsButton->setEnabled(m_permissionModel->changesNeeded());
0204 }
0205 
0206 
0207 void K3b::ExternalBinWidget::slotChangePermissions()
0208 {
0209     KAuth::Action action("org.kde.k3b.updatepermissions");
0210     action.setHelperId("org.kde.k3b");
0211 
0212 #if QT_VERSION_MAJOR == 5
0213     action.setParentWidget(this);
0214 #else
0215     action.setParentWindow(window()->windowHandle());
0216 #endif
0217 
0218     QVariantMap args;
0219 
0220     // Set burning group name as first argument
0221     args["burningGroup"] = m_permissionModel->burningGroup();
0222 
0223     // Set devices list as second argument
0224     args["devices"] = QStringList();
0225 
0226     // Set programs list as third argument
0227     QVariantList programs;
0228     Q_FOREACH(const HelperProgramItem& item, m_permissionModel->selectedPrograms()) {
0229         programs << QVariant::fromValue(item);
0230     }
0231     args["programs"] = programs;
0232 
0233     action.setArguments(args);
0234 
0235     KAuth::ExecuteJob* job = action.execute();
0236     connect( job, &KAuth::ExecuteJob::result, [this, job]()
0237     {
0238         if( job->error() == KJob::NoError ) {
0239             // Success!!
0240             QStringList updated = job->data()["updated"].toStringList();
0241             QStringList failedToUpdate = job->data()["failedToUpdate"].toStringList();
0242             qDebug() << "Objects updated: " << updated;
0243             qDebug() << "Objects failed to update: " << failedToUpdate;
0244 
0245             if (!failedToUpdate.isEmpty()) {
0246                 KMessageBox::errorList(this, i18n("Following programs could not be updated:"), failedToUpdate);
0247             }
0248 
0249             m_permissionModel->update();
0250         } else {
0251             KMessageBox::error(this, i18n("Unable to execute the action: %1", job->errorString()));
0252         }
0253     } );
0254     job->start();
0255 }
0256 
0257 #include "moc_k3bexternalbinwidget.cpp"