File indexing completed on 2024-05-12 17:07:25

0001 /*
0002     SPDX-FileCopyrightText: 2009 Ben Cooksley <ben@eclipse.endoftheinternet.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "ActionEditor.h"
0008 
0009 #include <KMessageBox>
0010 
0011 #include <Solid/Predicate>
0012 
0013 ActionEditor::ActionEditor(QWidget *parent)
0014     : QDialog(parent)
0015 {
0016     topItem = new PredicateItem(Solid::Predicate(), nullptr);
0017     rootItem = nullptr;
0018     rootModel = new PredicateModel(topItem, this);
0019     // Prepare the dialog
0020     resize(QSize(600, 600)); // Set a decent initial size
0021     // setModal( true );
0022     // Set up the interface
0023     ui.setupUi(this);
0024     ui.TvPredicateTree->setHeaderHidden(true);
0025     ui.TvPredicateTree->setModel(rootModel);
0026     ui.IbActionIcon->setIconSize(KIconLoader::SizeLarge);
0027 
0028     ui.CbDeviceType->addItems(actionData()->interfaceList());
0029 
0030     // Connect up with everything needed -> slot names explain
0031     connect(ui.TvPredicateTree, &QTreeView::activated, this, &ActionEditor::updateParameter);
0032     connect(ui.PbParameterSave, &QPushButton::clicked, this, &ActionEditor::saveParameter);
0033     connect(ui.PbParameterReset, &QPushButton::clicked, this, &ActionEditor::updateParameter);
0034     connect(ui.CbDeviceType, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &ActionEditor::updatePropertyList);
0035     connect(ui.CbParameterType, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &ActionEditor::manageControlStatus);
0036 
0037     connect(ui.buttonBox, &QDialogButtonBox::accepted, this, &ActionEditor::accept);
0038     connect(ui.buttonBox, &QDialogButtonBox::rejected, this, &ActionEditor::reject);
0039 
0040     if (ui.TvPredicateTree->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick)) {
0041         connect(ui.TvPredicateTree, &QTreeView::clicked, this, &ActionEditor::updateParameter);
0042     }
0043 }
0044 
0045 ActionEditor::~ActionEditor()
0046 {
0047     delete topItem;
0048 }
0049 
0050 void ActionEditor::setActionToEdit(ActionItem *item)
0051 {
0052     activeItem = item;
0053 
0054     // Set all the text appropriately
0055     ui.IbActionIcon->setIcon(item->icon());
0056     ui.LeActionFriendlyName->setText(item->name());
0057     ui.LeActionCommand->setText(item->exec());
0058 
0059     setPredicate(item->predicate());
0060     setWindowTitle(i18n("Editing Action '%1'", item->name())); // Set a friendly i18n caption
0061 }
0062 
0063 void ActionEditor::setPredicate(Solid::Predicate predicate)
0064 {
0065     delete topItem;
0066     topItem = new PredicateItem(Solid::Predicate(), nullptr);
0067     rootItem = new PredicateItem(predicate, topItem);
0068     rootModel->setRootPredicate(rootItem->parent());
0069 
0070     // Select the top item, not the hidden root
0071     QModelIndex topItem = rootModel->index(0, 0, QModelIndex());
0072     ui.TvPredicateTree->setCurrentIndex(topItem);
0073     ui.TvPredicateTree->expandToDepth(2);
0074     updateParameter();
0075 }
0076 
0077 void ActionEditor::updateParameter()
0078 {
0079     QModelIndex current = ui.TvPredicateTree->currentIndex();
0080     PredicateItem *currentItem = static_cast<PredicateItem *>(current.internalPointer());
0081 
0082     ui.CbParameterType->setCurrentIndex(currentItem->itemType);
0083     updatePropertyList();
0084     ui.CbDeviceType->setCurrentIndex(actionData()->interfacePosition(currentItem->ifaceType));
0085     int valuePos = actionData()->propertyPosition(currentItem->ifaceType, currentItem->property);
0086     ui.CbValueName->setCurrentIndex(valuePos);
0087     ui.LeValueMatch->setText(currentItem->value.toString());
0088     ui.CbValueMatch->setCurrentIndex(currentItem->compOperator);
0089 }
0090 
0091 void ActionEditor::saveParameter()
0092 {
0093     QModelIndex current = ui.TvPredicateTree->currentIndex();
0094     PredicateItem *currentItem = static_cast<PredicateItem *>(current.internalPointer());
0095 
0096     // Hold onto this so we can determine if the number of children has changed...
0097     Solid::Predicate::Type oldType = currentItem->itemType;
0098 
0099     currentItem->setTypeByInt(ui.CbParameterType->currentIndex());
0100     currentItem->ifaceType = actionData()->interfaceFromName(ui.CbDeviceType->currentText());
0101     currentItem->property = actionData()->propertyInternal(currentItem->ifaceType, ui.CbValueName->currentText());
0102     currentItem->value = QVariant(ui.LeValueMatch->text());
0103     currentItem->setComparisonByInt(ui.CbValueMatch->currentIndex());
0104 
0105     rootModel->itemUpdated(current);
0106     rootModel->childrenChanging(current, oldType);
0107 }
0108 
0109 QString ActionEditor::predicateString()
0110 {
0111     return rootItem->predicate().toString();
0112 }
0113 
0114 void ActionEditor::updatePropertyList()
0115 {
0116     Solid::DeviceInterface::Type currentType;
0117     currentType = actionData()->interfaceFromName(ui.CbDeviceType->currentText());
0118 
0119     ui.CbValueName->clear();
0120     ui.CbValueName->addItems(actionData()->propertyList(currentType));
0121 }
0122 
0123 void ActionEditor::manageControlStatus()
0124 {
0125     bool atomEnable = false;
0126     bool isEnable = false;
0127 
0128     switch (ui.CbParameterType->currentIndex()) {
0129     case Solid::Predicate::PropertyCheck:
0130         atomEnable = true;
0131     case Solid::Predicate::InterfaceCheck:
0132         isEnable = true;
0133         break;
0134     default:
0135         break;
0136     }
0137     ui.CbDeviceType->setEnabled(isEnable);
0138     ui.CbValueName->setEnabled(atomEnable);
0139     ui.CbValueMatch->setEnabled(atomEnable);
0140     ui.LeValueMatch->setEnabled(atomEnable);
0141 }
0142 
0143 SolidActionData *ActionEditor::actionData()
0144 {
0145     return SolidActionData::instance();
0146 }
0147 
0148 void ActionEditor::accept()
0149 {
0150     // Save any open parameter changes first...
0151     saveParameter();
0152 
0153     // Read the data and prepare to save
0154     QString iconName = ui.IbActionIcon->icon();
0155     QString actionName = ui.LeActionFriendlyName->text();
0156     QString command = ui.LeActionCommand->text();
0157     QString predicate = predicateString();
0158 
0159     // We need to ensure that they are all valid before applying
0160     if (iconName.isEmpty() || actionName.isEmpty() || command.isEmpty() || !Solid::Predicate::fromString(predicate).isValid()) {
0161         KMessageBox::error(this,
0162                            i18n("It appears that the action name, command, icon or condition are not valid.\nTherefore, changes will not be applied."),
0163                            i18n("Invalid action"));
0164         return;
0165     }
0166     // apply the changes
0167     if (iconName != activeItem->icon()) { // Has the icon changed?
0168         activeItem->setIcon(ui.IbActionIcon->icon()); // Write the change
0169     }
0170     if (actionName != activeItem->name()) { // Has the friendly name changed?
0171         activeItem->setName(ui.LeActionFriendlyName->text()); // Write the change
0172     }
0173     if (command != activeItem->exec()) { // Has the command changed?
0174         activeItem->setExec(ui.LeActionCommand->text()); // Write the change
0175     }
0176     if (predicate != activeItem->predicate().toString()) { // Has it changed?
0177         activeItem->setPredicate(predicate); // Write the change
0178     }
0179 
0180     QDialog::accept();
0181 }