Warning, file /plasma/khotkeys/kcm_hotkeys/conditions/conditions_widget.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* SPDX-FileCopyrightText: 2009 Michael Jansen <kde@michael-jansen.biz> 0002 0003 SPDX-License-Identifier: LGPL-2.0-or-later 0004 */ 0005 0006 #include "conditions/conditions_widget.h" 0007 #include "conditions/active_window_condition.h" 0008 #include "conditions/condition.h" 0009 #include "conditions/conditions.h" 0010 #include "conditions/conditions_list.h" 0011 #include "conditions/conditions_list_base.h" 0012 #include "conditions/conditions_visitor.h" 0013 #include "conditions/existing_window_condition.h" 0014 0015 #include "windows_helper/window_selection_list.h" 0016 0017 #include "helper_widgets/window_definition_list_widget.h" 0018 0019 #include "condition_type_menu.h" 0020 0021 #include <QStack> 0022 0023 #include <QDebug> 0024 0025 class BuildTree : public KHotKeys::ConditionsVisitor 0026 { 0027 public: 0028 BuildTree(QTreeWidget *tree); 0029 0030 void build(); 0031 0032 void visitConditionsListBase(KHotKeys::Condition_list_base *list) override; 0033 void visitConditionsList(KHotKeys::Condition_list *list) override; 0034 void visitCondition(KHotKeys::Condition *condition) override; 0035 0036 QMap<QTreeWidgetItem *, KHotKeys::Condition *> _items; 0037 0038 private: 0039 QTreeWidget *_tree; 0040 QStack<QTreeWidgetItem *> _stack; 0041 }; 0042 0043 BuildTree::BuildTree(QTreeWidget *tree) 0044 : _tree(tree) 0045 { 0046 _stack.push(_tree->invisibleRootItem()); 0047 } 0048 0049 void BuildTree::visitCondition(KHotKeys::Condition *cond) 0050 { 0051 QTreeWidgetItem *item = new QTreeWidgetItem(_stack.top()); 0052 item->setText(0, cond->description()); 0053 _items.insert(item, cond); 0054 } 0055 0056 void BuildTree::visitConditionsList(KHotKeys::Condition_list *list) 0057 { 0058 Q_ASSERT(_stack.count() == 1); 0059 0060 QTreeWidgetItem *parent = _stack.top(); 0061 0062 QTreeWidgetItem *item = new QTreeWidgetItem(parent); 0063 item->setText(0, i18nc("Add a new condition", "And")); 0064 _items.insert(item, list); 0065 _stack.push(item); 0066 0067 for (KHotKeys::Condition_list_base::Iterator it = list->begin(); it != list->end(); ++it) { 0068 (*it)->visit(this); 0069 } 0070 0071 _tree->expandAll(); 0072 } 0073 0074 void BuildTree::visitConditionsListBase(KHotKeys::Condition_list_base *list) 0075 { 0076 QTreeWidgetItem *parent = _stack.top(); 0077 0078 QTreeWidgetItem *item = new QTreeWidgetItem(parent); 0079 item->setText(0, list->description()); 0080 _items.insert(item, list); 0081 _stack.push(item); 0082 0083 for (KHotKeys::Condition_list_base::Iterator it = list->begin(); it != list->end(); ++it) { 0084 // QTreeWidgetItem *child = new QTreeWidgetItem(item); 0085 // child->setText(0, (*it)->description()); 0086 // _items.insert(child, list); 0087 (*it)->visit(this); 0088 } 0089 0090 _stack.pop(); 0091 } 0092 0093 ConditionsWidget::ConditionsWidget(QWidget *parent) 0094 : QWidget(parent) 0095 , _working(nullptr) 0096 , _changed(false) 0097 { 0098 ui.setupUi(this); 0099 0100 connect(ui.edit_button, SIGNAL(clicked(bool)), SLOT(slotEdit())); 0101 0102 connect(ui.delete_button, SIGNAL(clicked(bool)), SLOT(slotDelete())); 0103 0104 ui.new_button->setMenu(new ConditionTypeMenu(this)); 0105 // clang-format off 0106 connect(ui.new_button->menu(), SIGNAL(triggered(QAction*)), SLOT(slotNew(QAction*))); 0107 // clang-format on 0108 } 0109 0110 ConditionsWidget::~ConditionsWidget() 0111 { 0112 delete _working; 0113 _working = nullptr; 0114 } 0115 0116 void ConditionsWidget::copyFromObject() 0117 { 0118 Q_ASSERT(_conditions_list); 0119 0120 // Clear the tree and delete our old working copy 0121 ui.tree->clear(); 0122 if (_working) 0123 delete _working; 0124 0125 // Create the working copy 0126 _working = _conditions_list->copy(); 0127 Q_ASSERT(_working->count() == _conditions_list->count()); 0128 0129 qDebug() << _working->count(); 0130 qDebug() << _conditions_list->count(); 0131 0132 // Build the tree 0133 BuildTree builder(ui.tree); 0134 _working->visit(&builder); 0135 _items = builder._items; 0136 0137 _changed = false; 0138 } 0139 0140 void ConditionsWidget::copyToObject() 0141 { 0142 qDebug(); 0143 0144 Q_ASSERT(_conditions_list); 0145 if (!_conditions_list) 0146 return; 0147 0148 // Just copy the content from our working copy to the original 0149 0150 // Remove the old content 0151 qDeleteAll(*_conditions_list); 0152 _conditions_list->clear(); 0153 0154 for (KHotKeys::Condition_list::Iterator it = _working->begin(); it != _working->end(); ++it) { 0155 qDebug(); 0156 _conditions_list->append((*it)->copy()); 0157 } 0158 0159 Q_ASSERT(_working->count() == _conditions_list->count()); 0160 _changed = false; 0161 } 0162 0163 void ConditionsWidget::emitChanged(bool chgd) 0164 { 0165 if (_changed == (chgd || _changed)) 0166 return; 0167 0168 // Once changed always changed 0169 _changed = chgd || _changed; 0170 0171 emit changed(_changed); 0172 } 0173 0174 bool ConditionsWidget::hasChanges() const 0175 { 0176 return _changed; 0177 } 0178 0179 void ConditionsWidget::setConditionsList(KHotKeys::Condition_list *list) 0180 { 0181 Q_ASSERT(list); 0182 _conditions_list = list; 0183 } 0184 0185 void ConditionsWidget::slotDelete() 0186 { 0187 QTreeWidgetItem *citem = ui.tree->currentItem(); 0188 0189 // If no item is selected just return 0190 if (!citem) 0191 return; 0192 0193 // TODO: Ask for confirmation before deleting 0194 0195 // Get the currently select condition 0196 KHotKeys::Condition *cond = _items.value(citem); 0197 0198 // Do not allow deleting the root item 0199 if (cond == _working) 0200 return; 0201 0202 delete cond; 0203 delete citem; 0204 emitChanged(true); 0205 } 0206 0207 void ConditionsWidget::slotEdit() 0208 { 0209 // Get the currently select condition 0210 QTreeWidgetItem *citem = ui.tree->currentItem(); 0211 0212 // If no item is selected just return 0213 if (!citem) 0214 return; 0215 0216 KHotKeys::Condition *cond = _items.value(citem); 0217 0218 // Currently we only allow editing existing and active window conditions. 0219 // TODO: Disable buttons according to active item 0220 0221 KHotKeys::Existing_window_condition *ewcond = dynamic_cast<KHotKeys::Existing_window_condition *>(cond); 0222 if (ewcond) { 0223 WindowDefinitionListDialog dialog(ewcond->window()); 0224 switch (dialog.exec()) { 0225 case QDialog::Accepted: { 0226 citem->setText(0, ewcond->description()); 0227 emitChanged(true); 0228 } break; 0229 0230 case QDialog::Rejected: 0231 // Nothing to do 0232 return; 0233 0234 default: 0235 Q_ASSERT(false); 0236 return; 0237 } 0238 } 0239 0240 KHotKeys::Active_window_condition *awcond = dynamic_cast<KHotKeys::Active_window_condition *>(cond); 0241 if (awcond) { 0242 WindowDefinitionListDialog dialog(awcond->window()); 0243 switch (dialog.exec()) { 0244 case QDialog::Accepted: { 0245 citem->setText(0, awcond->description()); 0246 emitChanged(true); 0247 } break; 0248 0249 case QDialog::Rejected: 0250 // Nothing to do 0251 return; 0252 0253 default: 0254 Q_ASSERT(false); 0255 return; 0256 } 0257 } 0258 0259 return; 0260 } 0261 0262 void ConditionsWidget::slotNew(QAction *action) 0263 { 0264 QTreeWidgetItem *citem = ui.tree->currentItem(); 0265 0266 KHotKeys::Condition *cond; 0267 if (!citem) { 0268 // If no item is selected create the new condition as a top level 0269 // condition 0270 cond = _working; 0271 citem = ui.tree->invisibleRootItem()->child(0); 0272 Q_ASSERT(citem); 0273 } else { 0274 // Get the currently select condition 0275 cond = _items.value(citem); 0276 } 0277 0278 // get the nearest list 0279 KHotKeys::Condition_list_base *parent = dynamic_cast<KHotKeys::Condition_list_base *>(cond); 0280 0281 if (!parent) { 0282 parent = cond->parent(); 0283 citem = citem->parent(); 0284 } 0285 0286 Q_ASSERT(parent); 0287 0288 switch (action->data().toInt()) { 0289 case ConditionTypeMenu::ACTIVE_WINDOW: { 0290 KHotKeys::Windowdef_list *list = new KHotKeys::Windowdef_list(); 0291 WindowDefinitionListDialog dialog(list); 0292 switch (dialog.exec()) { 0293 case QDialog::Accepted: { 0294 KHotKeys::Active_window_condition *cond = new KHotKeys::Active_window_condition(list, parent); 0295 QTreeWidgetItem *item = new QTreeWidgetItem(citem); 0296 item->setText(0, cond->description()); 0297 _items.insert(item, cond); 0298 } break; 0299 0300 case QDialog::Rejected: 0301 delete list; 0302 return; 0303 0304 default: 0305 Q_ASSERT(false); 0306 delete list; 0307 return; 0308 } 0309 } break; 0310 0311 case ConditionTypeMenu::EXISTING_WINDOW: { 0312 KHotKeys::Windowdef_list *list = new KHotKeys::Windowdef_list(); 0313 WindowDefinitionListDialog dialog(list); 0314 switch (dialog.exec()) { 0315 case QDialog::Accepted: { 0316 KHotKeys::Existing_window_condition *cond = new KHotKeys::Existing_window_condition(list, parent); 0317 QTreeWidgetItem *item = new QTreeWidgetItem(citem); 0318 item->setText(0, cond->description()); 0319 _items.insert(item, cond); 0320 } break; 0321 0322 case QDialog::Rejected: 0323 delete list; 0324 return; 0325 0326 default: 0327 Q_ASSERT(false); 0328 delete list; 0329 return; 0330 } 0331 } break; 0332 0333 case ConditionTypeMenu::AND: { 0334 KHotKeys::And_condition *cond = new KHotKeys::And_condition(parent); 0335 QTreeWidgetItem *item = new QTreeWidgetItem(citem); 0336 item->setText(0, cond->description()); 0337 _items.insert(item, cond); 0338 } break; 0339 0340 case ConditionTypeMenu::OR: { 0341 KHotKeys::Or_condition *cond = new KHotKeys::Or_condition(parent); 0342 QTreeWidgetItem *item = new QTreeWidgetItem(citem); 0343 item->setText(0, cond->description()); 0344 _items.insert(item, cond); 0345 } break; 0346 0347 case ConditionTypeMenu::NOT: { 0348 KHotKeys::Not_condition *cond = new KHotKeys::Not_condition(parent); 0349 QTreeWidgetItem *item = new QTreeWidgetItem(citem); 0350 item->setText(0, cond->description()); 0351 _items.insert(item, cond); 0352 } break; 0353 0354 default: 0355 Q_ASSERT(false); 0356 break; 0357 } 0358 0359 emitChanged(true); 0360 } 0361 0362 #include "moc_conditions_widget.cpp"