00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "view.h"
00022 #include "model.h"
00023
00024 #include <kross/core/manager.h>
00025 #include <kross/core/action.h>
00026 #include <kross/core/actioncollection.h>
00027 #include <kross/core/interpreter.h>
00028
00029 #include <QtCore/QFileInfo>
00030 #include <QtCore/QDir>
00031 #include <QtGui/QBoxLayout>
00032 #include <QtGui/QHeaderView>
00033 #include <QtGui/QTreeView>
00034 #include <QtGui/QLabel>
00035 #include <QtGui/QLineEdit>
00036 #include <QtGui/QComboBox>
00037
00038 #include <kapplication.h>
00039
00040 #include <kconfig.h>
00041 #include <kstandarddirs.h>
00042 #include <kmessagebox.h>
00043 #include <kpushbutton.h>
00044 #include <kfiledialog.h>
00045 #include <kmenu.h>
00046 #include <kpagedialog.h>
00047 #include <kaction.h>
00048 #include <kactioncollection.h>
00049 #include <kurlrequester.h>
00050 #include <kicondialog.h>
00051
00052
00053
00054
00055 using namespace Kross;
00056
00057
00058
00059
00060
00061 namespace Kross {
00062
00064 class ActionCollectionEditor::Private
00065 {
00066 public:
00067 enum Type { ActionType, CollectionType };
00068 const Type type;
00069 union {
00070 Action* action;
00071 ActionCollection* collection;
00072 };
00073
00074 QString name() const {
00075 return type == ActionType ? action->name() : collection->name();
00076 }
00077 QString text() const {
00078 return type == ActionType ? action->text() : collection->text();
00079 }
00080 QString description() const {
00081 return type == ActionType ? action->description() : collection->description();
00082 }
00083 QString iconName() const {
00084 return type == ActionType ? action->iconName() : collection->iconName();
00085 }
00086 bool isEnabled() const {
00087 return type == ActionType ? action->isEnabled() : collection->isEnabled();
00088 }
00089
00090 QLineEdit* nameedit;
00091 QLineEdit* textedit;
00092 QLineEdit* commentedit;
00093 QLineEdit* iconedit;
00094 QComboBox* interpreteredit;
00095 KUrlRequester* fileedit;
00096
00097
00098 explicit Private(Action* a) : type(ActionType), action(a) { Q_ASSERT(a); }
00099 explicit Private(ActionCollection* c) : type(CollectionType), collection(c) { Q_ASSERT(c); }
00100 };
00101
00102 }
00103
00104 ActionCollectionEditor::ActionCollectionEditor(Action* action, QWidget* parent)
00105 : QWidget(parent), d(new Private(action))
00106 {
00107 initGui();
00108 }
00109
00110 ActionCollectionEditor::ActionCollectionEditor(ActionCollection* collection, QWidget* parent)
00111 : QWidget(parent), d(new Private(collection))
00112 {
00113 initGui();
00114 }
00115
00116 ActionCollectionEditor::~ActionCollectionEditor()
00117 {
00118 delete d;
00119 }
00120
00121 Action* ActionCollectionEditor::action() const
00122 {
00123 return d->type == Private::ActionType ? d->action : 0;
00124 }
00125
00126 ActionCollection* ActionCollectionEditor::collection() const
00127 {
00128 return d->type == Private::CollectionType ? d->collection : 0;
00129 }
00130
00131 QLineEdit* ActionCollectionEditor::nameEdit() const { return d->nameedit; }
00132 QLineEdit* ActionCollectionEditor::textEdit() const { return d->textedit; }
00133 QLineEdit* ActionCollectionEditor::commentEdit() const { return d->commentedit; }
00134 QLineEdit* ActionCollectionEditor::iconEdit() const { return d->iconedit; }
00135 QComboBox* ActionCollectionEditor::interpreterEdit() const { return d->interpreteredit; }
00136 KUrlRequester* ActionCollectionEditor::fileEdit() const { return d->fileedit; }
00137
00138 void ActionCollectionEditor::initGui()
00139 {
00140 QVBoxLayout* mainlayout = new QVBoxLayout();
00141 setLayout(mainlayout);
00142
00143 QWidget* w = new QWidget(this);
00144 mainlayout->addWidget(w);
00145 QGridLayout* gridlayout = new QGridLayout();
00146 gridlayout->setMargin(0);
00147
00148 w->setLayout(gridlayout);
00149
00150 QLabel* namelabel = new QLabel(i18n("Name:"), w);
00151 gridlayout->addWidget(namelabel, 0, 0);
00152 d->nameedit = new QLineEdit(w);
00153 namelabel->setBuddy(d->nameedit);
00154 d->nameedit->setText( d->name() );
00155 d->nameedit->setEnabled(false);
00156 gridlayout->addWidget(d->nameedit, 0, 1);
00157
00158 QLabel* textlabel = new QLabel(i18n("Text:"), w);
00159 gridlayout->addWidget(textlabel, 1, 0);
00160 d->textedit = new QLineEdit(w);
00161 textlabel->setBuddy(d->textedit);
00162 d->textedit->setText( d->text() );
00163 gridlayout->addWidget(d->textedit, 1, 1);
00164
00165 QLabel* commentlabel = new QLabel(i18n("Comment:"), w);
00166 gridlayout->addWidget(commentlabel, 2, 0);
00167 d->commentedit = new QLineEdit(w);
00168 commentlabel->setBuddy(d->commentedit);
00169 d->commentedit->setText( d->description() );
00170 gridlayout->addWidget(d->commentedit, 2, 1);
00171
00172 QLabel* iconlabel = new QLabel(i18n("Icon:"), w);
00173 gridlayout->addWidget(iconlabel, 3, 0);
00174 QWidget* iconbox = new QWidget(w);
00175 QHBoxLayout* iconlayout = new QHBoxLayout();
00176 iconlayout->setMargin(0);
00177 iconbox->setLayout(iconlayout);
00178 d->iconedit = new QLineEdit(iconbox);
00179 iconlabel->setBuddy(d->iconedit);
00180 d->iconedit->setText( d->iconName() );
00181 iconlayout->addWidget(d->iconedit, 1);
00182 KIconButton* iconbutton = new KIconButton(iconbox);
00183 iconbutton->setIcon( d->iconName() );
00184 connect(iconbutton, SIGNAL(iconChanged(QString)), d->iconedit, SLOT(setText(QString)));
00185 iconlayout->addWidget(iconbutton);
00186 gridlayout->addWidget(iconbox, 3, 1);
00187
00188
00189
00190
00191
00192 if( d->type == Private::ActionType ) {
00193 QLabel* interpreterlabel = new QLabel(i18n("Interpreter:"), w);
00194 gridlayout->addWidget(interpreterlabel, 4, 0);
00195 d->interpreteredit = new QComboBox(w);
00196 interpreterlabel->setBuddy(d->interpreteredit);
00197 d->interpreteredit->setMaxVisibleItems(10);
00198 d->interpreteredit->insertItems(0, Manager::self().interpreters());
00199 d->interpreteredit->setEditable(true);
00200
00201 int idx = Manager::self().interpreters().indexOf( d->action->interpreter() );
00202 if( idx >= 0 )
00203 d->interpreteredit->setCurrentIndex(idx);
00204 else
00205 d->interpreteredit->setEditText( d->action->interpreter() );
00206 gridlayout->addWidget(d->interpreteredit, 4, 1);
00207
00208 QLabel* filelabel = new QLabel(i18n("File:"), w);
00209 gridlayout->addWidget(filelabel, 5, 0);
00210 d->fileedit = new KUrlRequester(w);
00211 filelabel->setBuddy(d->fileedit);
00212 QStringList mimetypes;
00213 foreach(QString interpretername, Manager::self().interpreters()) {
00214 InterpreterInfo* info = Manager::self().interpreterInfo(interpretername);
00215 Q_ASSERT( info );
00216 mimetypes.append( info->mimeTypes().join(" ").trimmed() );
00217 }
00218
00219
00220 d->fileedit->fileDialog()->setMimeFilter(mimetypes );
00221 d->fileedit->setMode( KFile::File | KFile::ExistingOnly | KFile::LocalOnly );
00222
00223 d->fileedit->setPath( d->action->file() );
00224 gridlayout->addWidget(d->fileedit, 5, 1);
00225 }
00226 else {
00227 d->interpreteredit = 0;
00228 d->fileedit = 0;
00229 }
00230
00231
00232
00233
00234
00235
00236 mainlayout->addStretch(1);
00237 }
00238
00239 bool ActionCollectionEditor::isValid()
00240 {
00241
00242 return ! d->nameedit->text().isEmpty();
00243 }
00244
00245 void ActionCollectionEditor::commit()
00246 {
00247 switch( d->type ) {
00248 case Private::ActionType: {
00249 d->action->setText( d->textedit->text() );
00250 d->action->setDescription( d->commentedit->text() );
00251 d->action->setIconName( d->iconedit->text() );
00252 d->action->setInterpreter( d->interpreteredit->currentText() );
00253 d->action->setFile( d->fileedit->url().path() );
00254
00255 } break;
00256 case Private::CollectionType: {
00257 d->collection->setText( d->textedit->text() );
00258 d->collection->setDescription( d->commentedit->text() );
00259 d->collection->setIconName( d->iconedit->text() );
00260
00261 } break;
00262 default: break;
00263 }
00264 }
00265
00266
00267
00268
00269
00270 namespace Kross {
00271
00273 class ActionCollectionView::Private
00274 {
00275 public:
00276 bool modified;
00277 KActionCollection* collection;
00278 QMap< QString, KPushButton* > buttons;
00279 explicit Private() : modified(false) {}
00280 };
00281
00282 }
00283
00284 ActionCollectionView::ActionCollectionView(QWidget* parent)
00285 : QTreeView(parent)
00286 , d(new Private())
00287 {
00288 header()->hide();
00289 setSelectionMode(QAbstractItemView::SingleSelection);
00290 setAlternatingRowColors(true);
00291 setRootIsDecorated(true);
00292 setSortingEnabled(false);
00293 setItemsExpandable(true);
00294
00295
00296 setDropIndicatorShown(true);
00297 setDragDropMode(QAbstractItemView::InternalMove);
00298
00299 d->collection = new KActionCollection(this);
00300
00301 KAction* runaction = new KAction(KIcon("system-run"), i18n("Run"), this);
00302 runaction->setObjectName("run");
00303 runaction->setToolTip( i18n("Execute the selected script.") );
00304 runaction->setEnabled(false);
00305 d->collection->addAction("run", runaction);
00306 connect(runaction, SIGNAL(triggered()), this, SLOT(slotRun()));
00307
00308 KAction* stopaction = new KAction(KIcon("process-stop"), i18n("Stop"), this);
00309 stopaction->setObjectName("stop");
00310 stopaction->setToolTip( i18n("Stop execution of the selected script.") );
00311 stopaction->setEnabled(false);
00312 d->collection->addAction("stop", stopaction);
00313 connect(stopaction, SIGNAL(triggered()), this, SLOT(slotStop()));
00314
00315 KAction* editaction = new KAction(KIcon("document-properties"), i18n("Edit..."), this);
00316 editaction->setObjectName("edit");
00317 editaction->setToolTip( i18n("Edit selected script.") );
00318 editaction->setEnabled(false);
00319 d->collection->addAction("edit", editaction);
00320 connect(editaction, SIGNAL(triggered()), this, SLOT(slotEdit()));
00321
00322 KAction* addaction = new KAction(KIcon("list-add"), i18n("Add..."), this);
00323 addaction->setObjectName("add");
00324 addaction->setToolTip( i18n("Add a new script.") );
00325
00326 d->collection->addAction("add", addaction);
00327 connect(addaction, SIGNAL(triggered()), this, SLOT(slotAdd()) );
00328
00329 KAction* removeaction = new KAction(KIcon("list-remove"), i18n("Remove"), this);
00330 removeaction->setObjectName("remove");
00331 removeaction->setToolTip( i18n("Remove selected script.") );
00332 removeaction->setEnabled(false);
00333 d->collection->addAction("remove", removeaction);
00334 connect(removeaction, SIGNAL(triggered()), this, SLOT(slotRemove()) );
00335
00336 connect(this, SIGNAL(enabledChanged(const QString&)), this, SLOT(slotEnabledChanged(const QString&)));
00337
00338 }
00339
00340 ActionCollectionView::~ActionCollectionView()
00341 {
00342 delete d;
00343 }
00344
00345 void ActionCollectionView::setModel(QAbstractItemModel* m)
00346 {
00347 QTreeView::setModel(m);
00348 d->modified = false;
00349
00350 QItemSelectionModel* selectionmodel = new QItemSelectionModel(m, this);
00351 setSelectionModel(selectionmodel);
00352
00353 connect(selectionModel(), SIGNAL(selectionChanged(const QItemSelection&,const QItemSelection&)),
00354 this, SLOT(slotSelectionChanged()));
00355 connect(m, SIGNAL(dataChanged(const QModelIndex&,const QModelIndex&)),
00356 this, SLOT(slotDataChanged(const QModelIndex&,const QModelIndex&)));
00357 }
00358
00359 bool ActionCollectionView::isModified() const
00360 {
00361 return d->modified;
00362 }
00363
00364 void ActionCollectionView::setModified(bool modified)
00365 {
00366 d->modified = modified;
00367 }
00368
00369 KActionCollection* ActionCollectionView::actionCollection() const
00370 {
00371 return d->collection;
00372 }
00373
00374 KPushButton* ActionCollectionView::button(const QString& actionname) const
00375 {
00376 return d->buttons.contains(actionname) ? d->buttons[actionname] : 0;
00377 }
00378
00379 QItemSelection ActionCollectionView::itemSelection() const
00380 {
00381 QAbstractProxyModel* proxymodel = dynamic_cast< QAbstractProxyModel* >( model() );
00382 QItemSelection selection = selectionModel()->selection();
00383 return proxymodel ? proxymodel->mapSelectionToSource(selection) : selection;
00384 }
00385
00386 KPushButton* ActionCollectionView::createButton(QWidget* parentWidget, const QString& actionname)
00387 {
00388 QAction* action = d->collection->action(actionname);
00389 if( ! action ) return 0;
00390
00391 KPushButton* btn = new KPushButton(parentWidget);
00392 btn->setText( action->text() );
00393 btn->setToolTip( action->toolTip() );
00394 btn->setIcon( KIcon(action->icon()) );
00395 btn->setEnabled( action->isEnabled() );
00396 if( parentWidget && parentWidget->layout() )
00397 parentWidget->layout()->addWidget(btn);
00398 QObject::connect(btn, SIGNAL(clicked()), action, SLOT(trigger()));
00399 d->buttons.insert( actionname, btn );
00400 return btn;
00401 }
00402
00403 void ActionCollectionView::slotEnabledChanged(const QString& actionname)
00404 {
00405 if( d->buttons.contains( actionname ) ) {
00406 QAction* action = d->collection->action( actionname );
00407 d->buttons[ actionname ]->setEnabled( action ? action->isEnabled() : false );
00408 }
00409 }
00410
00411 void ActionCollectionView::slotSelectionChanged()
00412 {
00413 bool startenabled = selectionModel()->hasSelection();
00414 bool stopenabled = false;
00415 bool hasselection = selectionModel()->selectedIndexes().count() > 0;
00416 foreach(QModelIndex index, itemSelection().indexes()) {
00417 Action* action = ActionCollectionModel::action(index);
00418 if( startenabled && ! action )
00419 startenabled = false;
00420 if( ! stopenabled )
00421 stopenabled = (action && ! action->isFinalized());
00422 }
00423 QAction* runaction = d->collection->action("run");
00424 if( runaction ) {
00425 runaction->setEnabled(startenabled);
00426 emit enabledChanged("run");
00427 }
00428 QAction* stopaction = d->collection->action("stop");
00429 if( stopaction ) {
00430 stopaction->setEnabled(stopenabled);
00431 emit enabledChanged("stop");
00432 }
00433 QAction* editaction = d->collection->action("edit");
00434 if( editaction ) {
00435 editaction->setEnabled(hasselection);
00436 emit enabledChanged("edit");
00437 }
00438 QAction* removeaction = d->collection->action("remove");
00439 if( removeaction ) {
00440 removeaction->setEnabled(hasselection);
00441 emit enabledChanged("remove");
00442 }
00443 }
00444
00445 void ActionCollectionView::slotDataChanged(const QModelIndex&, const QModelIndex&)
00446 {
00447 d->modified = true;
00448 }
00449
00450 void ActionCollectionView::slotRun()
00451 {
00452 if( ! selectionModel() ) return;
00453 QAction* stopaction = d->collection->action("stop");
00454
00455 foreach(QModelIndex index, itemSelection().indexes()) {
00456 if( ! index.isValid() )
00457 continue;
00458 if( stopaction ) {
00459 stopaction->setEnabled(true);
00460 emit enabledChanged("stop");
00461 }
00462 Action* action = ActionCollectionModel::action(index);
00463 if( ! action )
00464 continue;
00465 connect(action, SIGNAL(finished(Kross::Action*)), SLOT(slotSelectionChanged()));
00466 action->trigger();
00467 }
00468 slotSelectionChanged();
00469 }
00470
00471 void ActionCollectionView::slotStop()
00472 {
00473 if( ! selectionModel() ) return;
00474 foreach(QModelIndex index, itemSelection().indexes()) {
00475 if( ! index.isValid() )
00476 continue;
00477 Action* action = ActionCollectionModel::action(index);
00478 if( ! action )
00479 continue;
00480
00481
00482 action->finalize();
00483 }
00484 slotSelectionChanged();
00485 }
00486
00487 void ActionCollectionView::slotEdit()
00488 {
00489 if( ! selectionModel() ) return;
00490 Action* action = 0;
00491 ActionCollection* collection = 0;
00492 foreach(QModelIndex index, itemSelection().indexes()) {
00493 if( ! index.isValid() ) continue;
00494 if( Action* a = ActionCollectionModel::action(index) )
00495 action = a;
00496 else if( ActionCollection* c = ActionCollectionModel::collection(index) )
00497 collection = c;
00498 else
00499 continue;
00500 break;
00501 }
00502 if( (! action) && (! collection) ) return;
00503 KPageDialog* dialog = new KPageDialog( this );
00504 dialog->setCaption( i18n("Edit") );
00505 dialog->setButtons( KDialog::Ok | KDialog::Cancel );
00506
00507 dialog->setFaceType( KPageDialog::Plain );
00508 ActionCollectionEditor* editor =
00509 action ? new ActionCollectionEditor(action, dialog->mainWidget())
00510 : new ActionCollectionEditor(collection, dialog->mainWidget());
00511 dialog->addPage(editor, i18n("General"));
00512
00513 dialog->resize( QSize(580, 200).expandedTo( dialog->minimumSizeHint() ) );
00514 int result = dialog->exec();
00515 if( result == QDialog::Accepted ) {
00516 editor->commit();
00517 }
00518 dialog->delayedDestruct();
00519 }
00520
00521 void ActionCollectionView::slotAdd()
00522 {
00523
00524
00525 KMessageBox::sorry(0, "TODO");
00526
00527
00528
00529
00530 #if 0
00531 if( ! selectionModel() ) return;
00532 ActionCollection* collection = 0;
00533 foreach(QModelIndex index, itemSelection().indexes()) {
00534 if( ! index.isValid() ) continue;
00535 if( ActionCollectionModel::action(index) ) {
00536
00537 QModelIndex parent = index;
00538 while( parent.isValid() && ! collection ) {
00539 parent = d->view->model()->parent(parent);
00540 collection = ActionCollectionModel::collection(parent);
00541 }
00542 if( collection ) break;
00543 }
00544 else if( ActionCollection* c = ActionCollectionModel::collection(index) ) {
00545 collection = c;
00546 break;
00547 }
00548 }
00549 ScriptManagerAddWizard wizard(this, collection);
00550 int result = wizard.exec();
00551 Q_UNUSED(result);
00552 #endif
00553 }
00554
00555 void ActionCollectionView::slotRemove()
00556 {
00557 if( ! selectionModel() ) return;
00558 KMessageBox::sorry(0, "TODO");
00559 }
00560
00561 #include "view.moc"