1/***************************************************************************
2 * Copyright (C) 2009 by Ben Cooksley <ben@eclipse.endoftheinternet.org> *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA *
18 ***************************************************************************/
19
20#include "ActionEditor.h"
21
22#include <KMessageBox>
23
24#include <Solid/Predicate>
25
26ActionEditor::ActionEditor(QWidget *parent) : KDialog(parent)
27{
28 topItem = new PredicateItem( Solid::Predicate(), 0 );
29 rootItem = 0;
30 rootModel = new PredicateModel( topItem, this );
31 // Prepare the dialog
32 setInitialSize( QSize(600, 600) ); // Set a decent initial size
33 // setModal( true );
34 // Set up the interface
35 ui.setupUi( mainWidget() );
36 ui.TvPredicateTree->setHeaderHidden( true );
37 ui.TvPredicateTree->setModel( rootModel );
38 ui.IbActionIcon->setIconSize( KIconLoader::SizeLarge );
39
40 ui.CbDeviceType->addItems( actionData()->interfaceList() );
41
42 // Connect up with everything needed -> slot names explain
43 connect( ui.TvPredicateTree, SIGNAL(activated(QModelIndex)), this, SLOT(updateParameter()) );
44 connect( ui.PbParameterSave, SIGNAL(clicked()), this, SLOT(saveParameter()) );
45 connect( ui.PbParameterReset, SIGNAL(clicked()), this, SLOT(updateParameter()) );
46 connect( ui.CbDeviceType, SIGNAL(currentIndexChanged(int)), this, SLOT(updatePropertyList()) );
47 connect( ui.CbParameterType, SIGNAL(currentIndexChanged(int)), this, SLOT(manageControlStatus()) );
48
49 if( !KGlobalSettings::singleClick() ) {
50 connect( ui.TvPredicateTree, SIGNAL(clicked(QModelIndex)), this, SLOT(updateParameter()) );
51 }
52}
53
54ActionEditor::~ActionEditor()
55{
56 delete topItem;
57}
58
59void ActionEditor::setActionToEdit( ActionItem * item )
60{
61 activeItem = item;
62
63 // Set all the text appropriately
64 ui.IbActionIcon->setIcon( item->icon() );
65 ui.LeActionFriendlyName->setText( item->name() );
66 ui.LeActionCommand->setUrl( KUrl(item->exec()) );
67
68 setPredicate( item->predicate() );
69 setCaption( i18n("Editing Action %1", item->name()) ); // Set a friendly i18n caption
70}
71
72void ActionEditor::setPredicate( Solid::Predicate predicate )
73{
74 delete topItem;
75 topItem = new PredicateItem( Solid::Predicate(), 0 );
76 rootItem = new PredicateItem( predicate, topItem );
77 rootModel->setRootPredicate( rootItem->parent() );
78
79 // Select the top item, not the hidden root
80 QModelIndex topItem = rootModel->index( 0, 0, QModelIndex() );
81 ui.TvPredicateTree->setCurrentIndex( topItem );
82 ui.TvPredicateTree->expandToDepth( 2 );
83 updateParameter();
84}
85
86void ActionEditor::updateParameter()
87{
88 QModelIndex current = ui.TvPredicateTree->currentIndex();
89 PredicateItem * currentItem = static_cast<PredicateItem*>( current.internalPointer() );
90
91 ui.CbParameterType->setCurrentIndex( currentItem->itemType );
92 updatePropertyList();
93 ui.CbDeviceType->setCurrentIndex( actionData()->interfacePosition( currentItem->ifaceType ) );
94 int valuePos = actionData()->propertyPosition( currentItem->ifaceType, currentItem->property );
95 ui.CbValueName->setCurrentIndex( valuePos );
96 ui.LeValueMatch->setText( currentItem->value.toString() );
97 ui.CbValueMatch->setCurrentIndex( currentItem->compOperator );
98}
99
100void ActionEditor::saveParameter()
101{
102 QModelIndex current = ui.TvPredicateTree->currentIndex();
103 PredicateItem * currentItem = static_cast<PredicateItem*>( current.internalPointer() );
104
105 // Hold onto this so we can determine if the number of children has changed...
106 Solid::Predicate::Type oldType = currentItem->itemType;
107
108 currentItem->setTypeByInt( ui.CbParameterType->currentIndex() );
109 currentItem->ifaceType = actionData()->interfaceFromName( ui.CbDeviceType->currentText() );
110 currentItem->property = actionData()->propertyInternal( currentItem->ifaceType, ui.CbValueName->currentText() );
111 currentItem->value = QVariant( ui.LeValueMatch->text() );
112 currentItem->setComparisonByInt( ui.CbValueMatch->currentIndex() );
113
114 rootModel->itemUpdated( current );
115 rootModel->childrenChanging( current, oldType );
116}
117
118QString ActionEditor::predicateString()
119{
120 return rootItem->predicate().toString();
121}
122
123void ActionEditor::updatePropertyList()
124{
125 Solid::DeviceInterface::Type currentType;
126 currentType = actionData()->interfaceFromName( ui.CbDeviceType->currentText() );
127
128 ui.CbValueName->clear();
129 ui.CbValueName->addItems( actionData()->propertyList( currentType ) );
130}
131
132void ActionEditor::manageControlStatus()
133{
134 bool atomEnable = false;
135 bool isEnable = false;
136
137 switch( ui.CbParameterType->currentIndex() ) {
138 case Solid::Predicate::PropertyCheck:
139 atomEnable = true;
140 case Solid::Predicate::InterfaceCheck:
141 isEnable = true;
142 break;
143 default:
144 break;
145 }
146 ui.CbDeviceType->setEnabled( isEnable );
147 ui.CbValueName->setEnabled( atomEnable );
148 ui.CbValueMatch->setEnabled( atomEnable );
149 ui.LeValueMatch->setEnabled( atomEnable );
150}
151
152SolidActionData * ActionEditor::actionData()
153{
154 return SolidActionData::instance();
155}
156
157void ActionEditor::accept()
158{
159 // Save any open parameter changes first...
160 saveParameter();
161
162 // Read the data and prepare to save
163 QString iconName = ui.IbActionIcon->icon();
164 QString actionName = ui.LeActionFriendlyName->text();
165 QString command = ui.LeActionCommand->text();
166 QString predicate = predicateString();
167
168 // We need to ensure that they are all valid before applying
169 if (iconName.isEmpty() || actionName.isEmpty() || command.isEmpty() || !Solid::Predicate::fromString(predicate).isValid()) {
170 KMessageBox::error(this, i18n("It appears that the action name, command, icon or condition are not valid.\nTherefore, changes will not be applied."), i18n("Invalid action"));
171 return;
172 }
173 // apply the changes
174 if (iconName != activeItem->icon()) { // Has the icon changed?
175 activeItem->setIcon( ui.IbActionIcon->icon() ); // Write the change
176 }
177 if (actionName != activeItem->name()) { // Has the friendly name changed?
178 activeItem->setName( ui.LeActionFriendlyName->text() ); // Write the change
179 }
180 if (command != activeItem->exec()) { // Has the command changed?
181 activeItem->setExec( ui.LeActionCommand->text() ); // Write the change
182 }
183 if (predicate != activeItem->predicate().toString() ) { // Has it changed?
184 activeItem->setPredicate( predicate ); // Write the change
185 }
186
187 KDialog::accept();
188}
189
190#include "ActionEditor.moc"
191