1 /*
2 SPDX-FileCopyrightText: 2010 Michal Malek <michalm@jabster.pl>
3 SPDX-FileCopyrightText: 1998-2008 Sebastian Trueg <trueg@k3b.org>
4
5 SPDX-License-Identifier: GPL-2.0-or-later
6 */
7
8 #include "k3bexternalbinwidget.h"
9 #include "k3bexternalbinmanager.h"
10 #include "k3bexternalbinmodel.h"
11 #include "k3bexternalbinparamsmodel.h"
12 #include "k3bexternalbinpermissionmodel.h"
13 #include "config-k3b.h"
14
15 #include <KAuth>
16 #include <KLocalizedString>
17 #include <KMessageBox>
18 #include <KEditListWidget>
19
20 #include <QDebug>
21 #include <QItemSelectionModel>
22 #include <QMap>
23 #include <QStringList>
24 #include <QCursor>
25 #include <QPixmap>
26 #include <QApplication>
27 #include <QHeaderView>
28 #include <QLabel>
29 #include <QLayout>
30 #include <QPushButton>
31 #include <QTabWidget>
32 #include <QToolTip>
33 #include <QTreeView>
34 #include <QVBoxLayout>
35
36 #include <grp.h>
37
38
39
40 // ///////////////////////////////////////////////////////////
41 //
42 // K3BEXTERNALBINWIDGET
43 //
44 // //////////////////////////////////////////////////////////
45
46
ExternalBinWidget(K3b::ExternalBinManager * manager,QWidget * parent)47 K3b::ExternalBinWidget::ExternalBinWidget( K3b::ExternalBinManager* manager, QWidget* parent )
48 : QWidget( parent ),
49 m_manager( manager ),
50 m_programModel( new ExternalBinModel( manager, this ) ),
51 m_parameterModel( new ExternalBinParamsModel( manager, this ) )
52 {
53 QGridLayout* mainGrid = new QGridLayout( this );
54 mainGrid->setContentsMargins( 0, 0, 0, 0 );
55
56 m_mainTabWidget = new QTabWidget( this );
57 m_rescanButton = new QPushButton( QIcon::fromTheme( "view-refresh" ), i18n( "Refresh" ), this );
58 mainGrid->addWidget( m_mainTabWidget, 0, 0, 1, 3 );
59 mainGrid->addWidget( m_rescanButton, 1, 2 );
60 mainGrid->setColumnStretch( 0, 1 );
61 mainGrid->setRowStretch( 0, 1 );
62
63 // setup program tab
64 // ------------------------------------------------------------
65 QWidget* programTab = new QWidget( m_mainTabWidget );
66 m_programView = new QTreeView( programTab );
67 m_programView->setModel( m_programModel );
68 m_programView->setAllColumnsShowFocus( true );
69 m_programView->setRootIsDecorated( false );
70 m_programView->setItemsExpandable( false );
71 m_programView->header()->setSectionResizeMode( ExternalBinModel::PathColumn, QHeaderView::ResizeToContents );
72 m_programView->header()->setSectionResizeMode( ExternalBinModel::VersionColumn, QHeaderView::ResizeToContents );
73 m_programView->setWhatsThis( i18n("<p>If K3b finds more than one installed version of a program "
74 "it will choose one as the <em>default</em>, which will be used "
75 "to do the work. If you want to change the default, check "
76 "desired version on the list.") );
77
78 QVBoxLayout* programTabLayout = new QVBoxLayout( programTab );
79 programTabLayout->addWidget( m_programView );
80
81 m_mainTabWidget->addTab( programTab, i18n("Programs") );
82
83
84 // setup parameters tab
85 // ------------------------------------------------------------
86 QWidget* parametersTab = new QWidget( m_mainTabWidget );
87 QLabel* parametersLabel = new QLabel( i18n("User parameters have to be separated by space."), parametersTab );
88 parametersLabel->setWordWrap( true );
89 m_parameterView = new QTreeView( parametersTab );
90 m_parameterView->setModel( m_parameterModel );
91 m_parameterView->setAllColumnsShowFocus( true );
92 m_parameterView->setRootIsDecorated( false );
93 m_parameterView->setEditTriggers( QAbstractItemView::AllEditTriggers );
94 m_parameterView->header()->setSectionResizeMode( QHeaderView::ResizeToContents );
95
96 QVBoxLayout* parametersTabLayout = new QVBoxLayout( parametersTab );
97 parametersTabLayout->addWidget( parametersLabel );
98 parametersTabLayout->addWidget( m_parameterView, 1 );
99
100 m_mainTabWidget->addTab( parametersTab, i18n("User Parameters") );
101
102
103 // setup permissions tab
104 // ------------------------------------------------------------
105 QWidget* permissionsTab = new QWidget( m_mainTabWidget );
106 QLabel* permissionsLabel = new QLabel( i18n("Check the programs whose permissions you want to be changed:"), permissionsTab );
107 permissionsLabel->setWordWrap( true );
108 m_permissionModel = new ExternalBinPermissionModel( *manager, permissionsTab );
109 m_permissionView = new QTreeView( permissionsTab );
110 m_permissionView->setModel( m_permissionModel );
111 m_permissionView->setAllColumnsShowFocus( true );
112 m_permissionView->setRootIsDecorated( false );
113 m_permissionView->header()->setSectionResizeMode( ExternalBinPermissionModel::ProgramColumn, QHeaderView::ResizeToContents );
114 m_changePermissionsButton = new QPushButton( QIcon::fromTheme("dialog-password"), i18n( "Change Permissions..." ), this );
115 QVBoxLayout* permissionsTabLayout = new QVBoxLayout( permissionsTab );
116 permissionsTabLayout->addWidget( permissionsLabel );
117 permissionsTabLayout->addWidget( m_permissionView );
118 permissionsTabLayout->addWidget( m_changePermissionsButton );
119 m_mainTabWidget->addTab( permissionsTab, i18n("Permissions") );
120
121
122 // setup search path tab
123 // ------------------------------------------------------------
124 QWidget* searchPathTab = new QWidget( m_mainTabWidget );
125 m_searchPathBox = new KEditListWidget( searchPathTab );
126 m_searchPathBox->setCheckAtEntering( true );
127 QLabel* hintLabel = new QLabel( i18n("<qt><b>Hint:</b> to force K3b to use another than the "
128 "default name for the executable specify it in the search path.</qt>"),
129 searchPathTab );
130 hintLabel->setWordWrap( true );
131 QVBoxLayout* searchPathTabLayout = new QVBoxLayout( searchPathTab );
132 searchPathTabLayout->addWidget( m_searchPathBox, 1 );
133 searchPathTabLayout->addWidget( hintLabel );
134
135 m_mainTabWidget->addTab( searchPathTab, i18n("Search Path") );
136
137 connect( m_changePermissionsButton, SIGNAL(clicked()), SLOT(slotChangePermissions()) );
138 connect( m_permissionModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), SLOT(slotPermissionModelChanged()) );
139 connect( m_permissionModel, SIGNAL(modelReset()), SLOT(slotPermissionModelChanged()) );
140 connect( m_rescanButton, SIGNAL(clicked(bool)), this, SLOT(rescan()) );
141
142 qRegisterMetaType<HelperProgramItem>();
143 qRegisterMetaTypeStreamOperators<HelperProgramItem>("K3b::HelperProgramItem");
144
145 while (::group *g = ::getgrent()) {
146 const QString groupName = QString::fromLocal8Bit(g->gr_name);
147 if (groupName == "cdrom" ||
148 groupName == "optical" ||
149 groupName == "operator" ) {
150 m_permissionModel->setBurningGroup(groupName);
151 }
152 }
153 ::endgrent();
154 }
155
156
~ExternalBinWidget()157 K3b::ExternalBinWidget::~ExternalBinWidget()
158 {
159 }
160
rescan()161 void K3b::ExternalBinWidget::rescan()
162 {
163 QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) );
164 saveSearchPath();
165 m_manager->search();
166 load();
167 QApplication::restoreOverrideCursor();
168 }
169
170
load()171 void K3b::ExternalBinWidget::load()
172 {
173 m_programModel->reload();
174 m_programView->expandAll();
175 m_parameterModel->reload();
176
177 // load search path
178 m_searchPathBox->clear();
179 m_searchPathBox->insertStringList( m_manager->searchPath() );
180 }
181
182
save()183 void K3b::ExternalBinWidget::save()
184 {
185 saveSearchPath();
186
187 m_programModel->save();
188 m_parameterModel->save();
189 }
190
191
saveSearchPath()192 void K3b::ExternalBinWidget::saveSearchPath()
193 {
194 m_manager->setSearchPath( m_searchPathBox->items() );
195 }
196
197
slotPermissionModelChanged()198 void K3b::ExternalBinWidget::slotPermissionModelChanged()
199 {
200 m_changePermissionsButton->setEnabled(m_permissionModel->changesNeeded());
201 }
202
203
slotChangePermissions()204 void K3b::ExternalBinWidget::slotChangePermissions()
205 {
206 KAuth::Action action("org.kde.k3b.updatepermissions");
207 action.setHelperId("org.kde.k3b");
208 action.setParentWidget(this);
209
210 QVariantMap args;
211
212 // Set burning group name as first argument
213 args["burningGroup"] = m_permissionModel->burningGroup();
214
215 // Set devices list as second argument
216 args["devices"] = QStringList();
217
218 // Set programs list as third argument
219 QVariantList programs;
220 Q_FOREACH(const HelperProgramItem& item, m_permissionModel->selectedPrograms()) {
221 programs << QVariant::fromValue(item);
222 }
223 args["programs"] = programs;
224
225 action.setArguments(args);
226
227 KAuth::ExecuteJob* job = action.execute();
228 connect( job, &KAuth::ExecuteJob::result, [this, job]()
229 {
230 if( job->error() == KJob::NoError ) {
231 // Success!!
232 QStringList updated = job->data()["updated"].toStringList();
233 QStringList failedToUpdate = job->data()["failedToUpdate"].toStringList();
234 qDebug() << "Objects updated: " << updated;
235 qDebug() << "Objects failed to update: " << failedToUpdate;
236
237 if (!failedToUpdate.isEmpty()) {
238 KMessageBox::errorList(this, i18n("Following programs could not be updated:"), failedToUpdate);
239 }
240
241 m_permissionModel->update();
242 } else {
243 KMessageBox::error(this, i18n("Unable to execute the action: %1", job->errorString()));
244 }
245 } );
246 job->start();
247 }
248
249
250