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
00036 #include <kapplication.h>
00037
00038 #include <kconfig.h>
00039 #include <kstandarddirs.h>
00040 #include <kmessagebox.h>
00041 #include <kpushbutton.h>
00042 #include <kfiledialog.h>
00043 #include <kmenu.h>
00044 #include <kpagedialog.h>
00045 #include <kaction.h>
00046 #include <kactioncollection.h>
00047 #include <kcombobox.h>
00048 #include <kicondialog.h>
00049 #include <klocale.h>
00050 #include <klineedit.h>
00051 #include <kurlrequester.h>
00052
00053
00054
00055
00056 using namespace Kross;
00057
00058
00059
00060
00061
00062 namespace Kross {
00063
00065 class ActionCollectionEditor::Private
00066 {
00067 public:
00068 enum Type { ActionType, CollectionType };
00069 const Type type;
00070 union {
00071 Action* action;
00072 ActionCollection* collection;
00073 };
00074
00075 QString name() const {
00076 return type == ActionType ? action->name() : collection->name();
00077 }
00078 QString text() const {
00079 return type == ActionType ? action->text() : collection->text();
00080 }
00081 QString description() const {
00082 return type == ActionType ? action->description() : collection->description();
00083 }
00084 QString iconName() const {
00085 return type == ActionType ? action->iconName() : collection->iconName();
00086 }
00087 bool isEnabled() const {
00088 return type == ActionType ? action->isEnabled() : collection->isEnabled();
00089 }
00090
00091 KLineEdit* nameedit;
00092 KLineEdit* textedit;
00093 KLineEdit* commentedit;
00094 KLineEdit* iconedit;
00095 KComboBox* interpreteredit;
00096 KUrlRequester* fileedit;
00097
00098
00099 explicit Private(Action* a) : type(ActionType), action(a) { Q_ASSERT(a); }
00100 explicit Private(ActionCollection* c) : type(CollectionType), collection(c) { Q_ASSERT(c); }
00101 };
00102
00103 }
00104
00105 ActionCollectionEditor::ActionCollectionEditor(Action* action, QWidget* parent)
00106 : QWidget(parent), d(new Private(action))
00107 {
00108 initGui();
00109 }
00110
00111 ActionCollectionEditor::ActionCollectionEditor(ActionCollection* collection, QWidget* parent)
00112 : QWidget(parent), d(new Private(collection))
00113 {
00114 initGui();
00115 }
00116
00117 ActionCollectionEditor::~ActionCollectionEditor()
00118 {
00119 delete d;
00120 }
00121
00122 Action* ActionCollectionEditor::action() const
00123 {
00124 return d->type == Private::ActionType ? d->action : 0;
00125 }
00126
00127 ActionCollection* ActionCollectionEditor::collection() const
00128 {
00129 return d->type == Private::CollectionType ? d->collection : 0;
00130 }
00131
00132 QLineEdit* ActionCollectionEditor::nameEdit() const { return d->nameedit; }
00133 QLineEdit* ActionCollectionEditor::textEdit() const { return d->textedit; }
00134 QLineEdit* ActionCollectionEditor::commentEdit() const { return d->commentedit; }
00135 QLineEdit* ActionCollectionEditor::iconEdit() const { return d->iconedit; }
00136 QComboBox* ActionCollectionEditor::interpreterEdit() const { return d->interpreteredit; }
00137 KUrlRequester* ActionCollectionEditor::fileEdit() const { return d->fileedit; }
00138
00139 void ActionCollectionEditor::initGui()
00140 {
00141 QVBoxLayout* mainlayout = new QVBoxLayout();
00142 setLayout(mainlayout);
00143
00144 QWidget* w = new QWidget(this);
00145 mainlayout->addWidget(w);
00146 QGridLayout* gridlayout = new QGridLayout();
00147 gridlayout->setMargin(0);
00148
00149 w->setLayout(gridlayout);
00150
00151 QLabel* namelabel = new QLabel(i18n("Name:"), w);
00152 gridlayout->addWidget(namelabel, 0, 0);
00153 d->nameedit = new KLineEdit(w);
00154 namelabel->setBuddy(d->nameedit);
00155 d->nameedit->setText( d->name() );
00156 d->nameedit->setEnabled(false);
00157 gridlayout->addWidget(d->nameedit, 0, 1);
00158
00159 QLabel* textlabel = new QLabel(i18n("Text:"), w);
00160 gridlayout->addWidget(textlabel, 1, 0);
00161 d->textedit = new KLineEdit(w);
00162 textlabel->setBuddy(d->textedit);
00163 d->textedit->setText( d->text() );
00164 gridlayout->addWidget(d->textedit, 1, 1);
00165
00166 QLabel* commentlabel = new QLabel(i18n("Comment:"), w);
00167 gridlayout->addWidget(commentlabel, 2, 0);
00168 d->commentedit = new KLineEdit(w);
00169 commentlabel->setBuddy(d->commentedit);
00170 d->commentedit->setText( d->description() );
00171 gridlayout->addWidget(d->commentedit, 2, 1);
00172
00173 QLabel* iconlabel = new QLabel(i18n("Icon:"), w);
00174 gridlayout->addWidget(iconlabel, 3, 0);
00175 QWidget* iconbox = new QWidget(w);
00176 QHBoxLayout* iconlayout = new QHBoxLayout();
00177 iconlayout->setMargin(0);
00178 iconbox->setLayout(iconlayout);
00179 d->iconedit = new KLineEdit(iconbox);
00180 iconlabel->setBuddy(d->iconedit);
00181 d->iconedit->setText( d->iconName() );
00182 iconlayout->addWidget(d->iconedit, 1);
00183 KIconButton* iconbutton = new KIconButton(iconbox);
00184 iconbutton->setIcon( d->iconName() );
00185 connect(iconbutton, SIGNAL(iconChanged(QString)), d->iconedit, SLOT(setText(QString)));
00186 iconlayout->addWidget(iconbutton);
00187 gridlayout->addWidget(iconbox, 3, 1);
00188
00189
00190
00191
00192
00193 if( d->type == Private::ActionType ) {
00194 QLabel* interpreterlabel = new QLabel(i18n("Interpreter:"), w);
00195 gridlayout->addWidget(interpreterlabel, 4, 0);
00196 d->interpreteredit = new KComboBox(w);
00197 interpreterlabel->setBuddy(d->interpreteredit);
00198 d->interpreteredit->setMaxVisibleItems(10);
00199 d->interpreteredit->insertItems(0, Manager::self().interpreters());
00200 d->interpreteredit->setEditable(true);
00201
00202 int idx = Manager::self().interpreters().indexOf( d->action->interpreter() );
00203 if( idx >= 0 )
00204 d->interpreteredit->setCurrentIndex(idx);
00205 else
00206 d->interpreteredit->setEditText( d->action->interpreter() );
00207 gridlayout->addWidget(d->interpreteredit, 4, 1);
00208
00209 QLabel* filelabel = new QLabel(i18n("File:"), w);
00210 gridlayout->addWidget(filelabel, 5, 0);
00211 d->fileedit = new KUrlRequester(w);
00212 filelabel->setBuddy(d->fileedit);
00213 QStringList mimetypes;
00214 foreach(const QString &interpretername, Manager::self().interpreters()) {
00215 InterpreterInfo* info = Manager::self().interpreterInfo(interpretername);
00216 Q_ASSERT( info );
00217 mimetypes.append( info->mimeTypes().join(" ").trimmed() );
00218 }
00219
00220
00221 d->fileedit->fileDialog()->setMimeFilter(mimetypes );
00222 d->fileedit->setMode( KFile::File | KFile::ExistingOnly | KFile::LocalOnly );
00223 d->fileedit->setUrl(KUrl(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(const 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(const 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(const 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(const 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, i18nc("@title:group Script properties", "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"