File indexing completed on 2024-04-28 09:41:06
0001 /* 0002 KT list view item tasks implementation. 0003 -------------------------------------------------------------------- 0004 SPDX-FileCopyrightText: 1999 Gary Meyer <gary@meyer.net> 0005 -------------------------------------------------------------------- 0006 SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #include "tasksWidget.h" 0010 0011 #include <QAction> 0012 #include <QList> 0013 #include <QProcess> 0014 0015 #include <KLocalizedString> 0016 #include <KStandardAction> 0017 0018 #include "ctcron.h" 0019 #include "cttask.h" 0020 #include "ctvariable.h" 0021 0022 #include "crontabWidget.h" 0023 #include "taskEditorDialog.h" 0024 #include "taskWidget.h" 0025 0026 #include "kcm_cron_debug.h" 0027 0028 /** 0029 * Construct tasks folder from branch. 0030 */ 0031 TasksWidget::TasksWidget(CrontabWidget *crontabWidget) 0032 : GenericListWidget(crontabWidget, i18n("<b>Scheduled Tasks</b>"), QIcon::fromTheme(QStringLiteral("system-run"))) 0033 { 0034 refreshHeaders(); 0035 0036 treeWidget()->sortItems(1, Qt::AscendingOrder); 0037 0038 setupActions(crontabWidget); 0039 prepareContextualMenu(); 0040 0041 connect(treeWidget(), &QTreeWidget::itemSelectionChanged, this, &TasksWidget::changeCurrentSelection); 0042 0043 qCDebug(KCM_CRON_LOG) << "Tasks list created"; 0044 } 0045 0046 TasksWidget::~TasksWidget() 0047 { 0048 } 0049 0050 QList<TaskWidget *> TasksWidget::selectedTasksWidget() const 0051 { 0052 QList<TaskWidget *> tasksWidget; 0053 0054 const QList<QTreeWidgetItem *> tasksItems = treeWidget()->selectedItems(); 0055 tasksWidget.reserve(tasksItems.count()); 0056 for (QTreeWidgetItem *item : tasksItems) { 0057 auto taskWidget = static_cast<TaskWidget *>(item); 0058 tasksWidget.append(taskWidget); 0059 } 0060 0061 return tasksWidget; 0062 } 0063 0064 TaskWidget *TasksWidget::firstSelectedTaskWidget() const 0065 { 0066 QTreeWidgetItem *item = firstSelected(); 0067 if (!item) { 0068 return nullptr; 0069 } 0070 0071 return static_cast<TaskWidget *>(item); 0072 } 0073 0074 int TasksWidget::statusColumnIndex() 0075 { 0076 if (needUserColumn()) { 0077 return 3; 0078 } 0079 0080 return 2; 0081 } 0082 0083 void TasksWidget::runTaskNow() const 0084 { 0085 TaskWidget *taskWidget = firstSelectedTaskWidget(); 0086 if (taskWidget == nullptr) { 0087 return; 0088 } 0089 0090 CTCron *ctCron = crontabWidget()->currentCron(); 0091 if (!ctCron) { 0092 qCDebug(KCM_CRON_LOG) << "Unable to find the related CtCron, please report this bug to the developers."; 0093 return; 0094 } 0095 0096 const QString taskCommand = taskWidget->getCTTask()->command; 0097 0098 const QString echoMessage = i18nc("Do not use any quote characters (') in this string", "End of script execution. Type Enter or Ctrl+C to exit."); 0099 QStringList commandList; 0100 0101 const auto variables = ctCron->variables(); 0102 commandList.reserve(variables.count() + 5); 0103 for (CTVariable *variable : variables) { 0104 commandList << QStringLiteral("export %1=\"%2\"").arg(variable->variable, variable->value); 0105 } 0106 0107 commandList << taskCommand; 0108 commandList << QStringLiteral("echo '-------------------------------------------------------------------------'"); 0109 commandList << QLatin1String("echo ") + echoMessage; 0110 commandList << QStringLiteral("echo '-------------------------------------------------------------------------'"); 0111 commandList << QStringLiteral("read"); 0112 0113 QStringList parameters; 0114 parameters << QStringLiteral("-e") << QStringLiteral("bash") << QStringLiteral("-c"); 0115 parameters << commandList.join(QLatin1Char(';')); 0116 0117 QProcess process; 0118 process.startDetached(QStringLiteral("konsole"), parameters); 0119 } 0120 0121 void TasksWidget::createTask() 0122 { 0123 // Gather necessary data to combine it into a CTTask, opening the taskEditor dialog. 0124 auto task = 0125 new CTTask(QLatin1String(""), QLatin1String(""), crontabWidget()->currentCron()->userLogin(), crontabWidget()->currentCron()->isMultiUserCron()); 0126 0127 TaskEditorDialog taskEditorDialog(task, i18n("New Task"), crontabWidget()); 0128 const int result = taskEditorDialog.exec(); 0129 0130 // Signal that changes were made if the task was created, or clean up if not. 0131 if (result == QDialog::Accepted) { 0132 addTask(task); 0133 Q_EMIT taskModified(true); 0134 0135 changeCurrentSelection(); 0136 } else { 0137 delete task; 0138 } 0139 } 0140 0141 void TasksWidget::addTask(CTTask *task) 0142 { 0143 CTCron *cron = crontabWidget()->currentCron(); 0144 0145 cron->addTask(task); 0146 new TaskWidget(this, task); 0147 } 0148 0149 void TasksWidget::modifySelection() 0150 { 0151 modifySelection(firstSelectedTaskWidget(), -1); 0152 } 0153 0154 void TasksWidget::modifySelection(QTreeWidgetItem *item, int position) 0155 { 0156 auto taskWidget = static_cast<TaskWidget *>(item); 0157 if (taskWidget) { 0158 if (position == statusColumnIndex()) { 0159 taskWidget->toggleEnable(); 0160 Q_EMIT taskModified(true); 0161 } else { 0162 CTTask *task = taskWidget->getCTTask(); 0163 TaskEditorDialog taskEditorDialog(task, i18n("Modify Task"), crontabWidget()); 0164 int result = taskEditorDialog.exec(); 0165 0166 if (result == QDialog::Accepted) { 0167 crontabWidget()->currentCron()->modifyTask(task); 0168 taskWidget->refresh(); 0169 Q_EMIT taskModified(true); 0170 } 0171 } 0172 } 0173 0174 qCDebug(KCM_CRON_LOG) << "End of modification"; 0175 } 0176 0177 void TasksWidget::deleteSelection() 0178 { 0179 qCDebug(KCM_CRON_LOG) << "Selection deleting..."; 0180 0181 const QList<QTreeWidgetItem *> tasksItems = treeWidget()->selectedItems(); 0182 0183 bool deleteSomething = !(tasksItems.isEmpty()); 0184 0185 for (QTreeWidgetItem *item : tasksItems) { 0186 auto taskWidget = static_cast<TaskWidget *>(item); 0187 0188 crontabWidget()->currentCron()->removeTask(taskWidget->getCTTask()); 0189 delete taskWidget->getCTTask(); 0190 treeWidget()->takeTopLevelItem(treeWidget()->indexOfTopLevelItem(taskWidget)); 0191 delete taskWidget; 0192 } 0193 0194 if (deleteSomething) { 0195 Q_EMIT taskModified(true); 0196 changeCurrentSelection(); 0197 } 0198 0199 qCDebug(KCM_CRON_LOG) << "End of deletion"; 0200 } 0201 0202 void TasksWidget::refreshTasks(CTCron *cron) 0203 { 0204 // Remove previous items 0205 removeAll(); 0206 0207 refreshHeaders(); 0208 0209 // Add new items 0210 const auto tasks = cron->tasks(); 0211 for (CTTask *ctTask : tasks) { 0212 new TaskWidget(this, ctTask); 0213 } 0214 0215 resizeColumnContents(); 0216 } 0217 0218 void TasksWidget::refreshHeaders() 0219 { 0220 QStringList headerLabels; 0221 0222 if (needUserColumn()) { 0223 headerLabels << i18n("User"); 0224 } 0225 0226 headerLabels << i18n("Scheduling"); 0227 0228 headerLabels << i18n("Command"); 0229 headerLabels << i18n("Status"); 0230 headerLabels << i18n("Description"); 0231 headerLabels << i18n("Scheduling Details"); 0232 0233 treeWidget()->setHeaderLabels(headerLabels); 0234 0235 if (needUserColumn()) { 0236 treeWidget()->setColumnCount(6); 0237 } else { 0238 treeWidget()->setColumnCount(5); 0239 } 0240 } 0241 0242 bool TasksWidget::needUserColumn() const 0243 { 0244 CTCron *ctCron = crontabWidget()->currentCron(); 0245 if (ctCron && ctCron->isMultiUserCron()) { 0246 return true; 0247 } 0248 0249 return false; 0250 } 0251 0252 void TasksWidget::setupActions(CrontabWidget *crontabWidget) 0253 { 0254 mNewTaskAction = new QAction(this); 0255 mNewTaskAction->setIcon(QIcon::fromTheme(QStringLiteral("document-new"))); 0256 mNewTaskAction->setText(i18nc("Adds a new task", "New &Task...")); 0257 mNewTaskAction->setToolTip(i18n("Create a new task.")); 0258 addRightAction(mNewTaskAction, this, SLOT(createTask())); 0259 0260 mModifyAction = new QAction(this); 0261 mModifyAction->setText(i18n("M&odify...")); 0262 mModifyAction->setIcon(QIcon::fromTheme(QStringLiteral("document-open"))); 0263 mModifyAction->setToolTip(i18n("Modify the selected task.")); 0264 addRightAction(mModifyAction, this, SLOT(modifySelection())); 0265 0266 mDeleteAction = new QAction(this); 0267 mDeleteAction->setText(i18n("&Delete")); 0268 mDeleteAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-delete"))); 0269 mDeleteAction->setToolTip(i18n("Delete the selected task.")); 0270 addRightAction(mDeleteAction, this, SLOT(deleteSelection())); 0271 0272 mRunNowAction = new QAction(this); 0273 mRunNowAction->setText(i18n("&Run Now")); 0274 mRunNowAction->setIcon(QIcon::fromTheme(QStringLiteral("system-run"))); 0275 mRunNowAction->setToolTip(i18n("Run the selected task now.")); 0276 addRightAction(mRunNowAction, this, SLOT(runTaskNow())); 0277 0278 mPrintAction = KStandardAction::print(crontabWidget, SLOT(print()), this); 0279 addRightAction(mPrintAction, crontabWidget, SLOT(print())); 0280 0281 addRightStretch(); 0282 } 0283 0284 void TasksWidget::prepareContextualMenu() 0285 { 0286 treeWidget()->addAction(mNewTaskAction); 0287 0288 treeWidget()->addAction(createSeparator()); 0289 0290 treeWidget()->addAction(mModifyAction); 0291 treeWidget()->addAction(mDeleteAction); 0292 0293 treeWidget()->addAction(createSeparator()); 0294 const auto cutCopyPasteActions = crontabWidget()->cutCopyPasteActions(); 0295 0296 for (QAction *action : cutCopyPasteActions) { 0297 treeWidget()->addAction(action); 0298 } 0299 0300 treeWidget()->addAction(createSeparator()); 0301 0302 treeWidget()->addAction(mRunNowAction); 0303 } 0304 0305 void TasksWidget::toggleRunNowAction(bool state) 0306 { 0307 setActionEnabled(mRunNowAction, state); 0308 } 0309 0310 void TasksWidget::togglePrintAction(bool state) 0311 { 0312 setActionEnabled(mPrintAction, state); 0313 } 0314 0315 void TasksWidget::toggleModificationActions(bool state) 0316 { 0317 setActionEnabled(mModifyAction, state); 0318 setActionEnabled(mDeleteAction, state); 0319 } 0320 0321 void TasksWidget::toggleNewEntryAction(bool state) 0322 { 0323 setActionEnabled(mNewTaskAction, state); 0324 } 0325 0326 void TasksWidget::changeCurrentSelection() 0327 { 0328 // qCDebug(KCM_CRON_LOG) << "Change selection..."; 0329 0330 if (treeWidget()->topLevelItemCount() == 0) { 0331 togglePrintAction(false); 0332 } else { 0333 togglePrintAction(true); 0334 } 0335 0336 bool enabled; 0337 if (treeWidget()->selectedItems().isEmpty()) { 0338 enabled = false; 0339 } else { 0340 enabled = true; 0341 } 0342 0343 toggleModificationActions(enabled); 0344 toggleRunNowAction(enabled); 0345 } 0346 0347 #include "moc_tasksWidget.cpp"