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
00224 d->fileedit->setPath( d->action->file() );
00225 gridlayout->addWidget(d->fileedit, 5, 1);
00226 }
00227 else {
00228 d->interpreteredit = 0;
00229 d->fileedit = 0;
00230 }
00231
00232
00233
00234
00235
00236
00237 mainlayout->addStretch(1);
00238 }
00239
00240 bool ActionCollectionEditor::isValid()
00241 {
00242
00243 return ! d->nameedit->text().isEmpty();
00244 }
00245
00246 void ActionCollectionEditor::commit()
00247 {
00248 switch( d->type ) {
00249 case Private::ActionType: {
00250 d->action->setText( d->textedit->text() );
00251 d->action->setDescription( d->commentedit->text() );
00252 d->action->setIconName( d->iconedit->text() );
00253 d->action->setInterpreter( d->interpreteredit->currentText() );
00254 d->action->setFile( d->fileedit->url().path() );
00255
00256 } break;
00257 case Private::CollectionType: {
00258 d->collection->setText( d->textedit->text() );
00259 d->collection->setDescription( d->commentedit->text() );
00260 d->collection->setIconName( d->iconedit->text() );
00261
00262 } break;
00263 default: break;
00264 }
00265 }
00266
00267
00268
00269
00270
00271 namespace Kross {
00272
00274 class ActionCollectionView::Private
00275 {
00276 public:
00277 bool modified;
00278 KActionCollection* collection;
00279 QMap< QString, KPushButton* > buttons;
00280 explicit Private() : modified(false) {}
00281 };
00282
00283 }
00284
00285 ActionCollectionView::ActionCollectionView(QWidget* parent)
00286 : QTreeView(parent)
00287 , d(new Private())
00288 {
00289 header()->hide();
00290 setSelectionMode(QAbstractItemView::SingleSelection);
00291 setAlternatingRowColors(true);
00292 setRootIsDecorated(true);
00293 setSortingEnabled(false);
00294 setItemsExpandable(true);
00295
00296
00297 setDropIndicatorShown(true);
00298 setDragDropMode(QAbstractItemView::InternalMove);
00299
00300 d->collection = new KActionCollection(this);
00301
00302 KAction* runaction = new KAction(KIcon("system-run"), i18n("Run"), this);
00303 runaction->setObjectName("run");
00304 runaction->setToolTip( i18n("Execute the selected script.") );
00305 runaction->setEnabled(false);
00306 d->collection->addAction("run", runaction);
00307 connect(runaction, SIGNAL(triggered()), this, SLOT(slotRun()));
00308
00309 KAction* stopaction = new KAction(KIcon("process-stop"), i18n("Stop"), this);
00310 stopaction->setObjectName("stop");
00311 stopaction->setToolTip( i18n("Stop execution of the selected script.") );
00312 stopaction->setEnabled(false);
00313 d->collection->addAction("stop", stopaction);
00314 connect(stopaction, SIGNAL(triggered()), this, SLOT(slotStop()));
00315
00316 KAction* editaction = new KAction(KIcon("document-properties"), i18n("Edit..."), this);
00317 editaction->setObjectName("edit");
00318 editaction->setToolTip( i18n("Edit selected script.") );
00319 editaction->setEnabled(false);
00320 d->collection->addAction("edit", editaction);
00321 connect(editaction, SIGNAL(triggered()), this, SLOT(slotEdit()));
00322
00323 KAction* addaction = new KAction(KIcon("list-add"), i18n("Add..."), this);
00324 addaction->setObjectName("add");
00325 addaction->setToolTip( i18n("Add a new script.") );
00326
00327 d->collection->addAction("add", addaction);
00328 connect(addaction, SIGNAL(triggered()), this, SLOT(slotAdd()) );
00329
00330 KAction* removeaction = new KAction(KIcon("list-remove"), i18n("Remove"), this);
00331 removeaction->setObjectName("remove");
00332 removeaction->setToolTip( i18n("Remove selected script.") );
00333 removeaction->setEnabled(false);
00334 d->collection->addAction("remove", removeaction);
00335 connect(removeaction, SIGNAL(triggered()), this, SLOT(slotRemove()) );
00336
00337 connect(this, SIGNAL(enabledChanged(const QString&)), this, SLOT(slotEnabledChanged(const QString&)));
00338
00339 }
00340
00341 ActionCollectionView::~ActionCollectionView()
00342 {
00343 delete d;
00344 }
00345
00346 void ActionCollectionView::setModel(QAbstractItemModel* m)
00347 {
00348 QTreeView::setModel(m);
00349 d->modified = false;
00350
00351 QItemSelectionModel* selectionmodel = new QItemSelectionModel(m, this);
00352 setSelectionModel(selectionmodel);
00353
00354 connect(selectionModel(), SIGNAL(selectionChanged(const QItemSelection&,const QItemSelection&)),
00355 this, SLOT(slotSelectionChanged()));
00356 connect(m, SIGNAL(dataChanged(const QModelIndex&,const QModelIndex&)),
00357 this, SLOT(slotDataChanged(const QModelIndex&,const QModelIndex&)));
00358 }
00359
00360 bool ActionCollectionView::isModified() const
00361 {
00362 return d->modified;
00363 }
00364
00365 void ActionCollectionView::setModified(bool modified)
00366 {
00367 d->modified = modified;
00368 }
00369
00370 KActionCollection* ActionCollectionView::actionCollection() const
00371 {
00372 return d->collection;
00373 }
00374
00375 KPushButton* ActionCollectionView::button(const QString& actionname) const
00376 {
00377 return d->buttons.contains(actionname) ? d->buttons[actionname] : 0;
00378 }
00379
00380 QItemSelection ActionCollectionView::itemSelection() const
00381 {
00382 QAbstractProxyModel* proxymodel = dynamic_cast< QAbstractProxyModel* >( model() );
00383 QItemSelection selection = selectionModel()->selection();
00384 return proxymodel ? proxymodel->mapSelectionToSource(selection) : selection;
00385 }
00386
00387 KPushButton* ActionCollectionView::createButton(QWidget* parentWidget, const QString& actionname)
00388 {
00389 QAction* action = d->collection->action(actionname);
00390 if( ! action ) return 0;
00391
00392 KPushButton* btn = new KPushButton(parentWidget);
00393 btn->setText( action->text() );
00394 btn->setToolTip( action->toolTip() );
00395 btn->setIcon( KIcon(action->icon()) );
00396 btn->setEnabled( action->isEnabled() );
00397 if( parentWidget && parentWidget->layout() )
00398 parentWidget->layout()->addWidget(btn);
00399 QObject::connect(btn, SIGNAL(clicked()), action, SLOT(trigger()));
00400 d->buttons.insert( actionname, btn );
00401 return btn;
00402 }
00403
00404 void ActionCollectionView::slotEnabledChanged(const QString& actionname)
00405 {
00406 if( d->buttons.contains( actionname ) ) {
00407 QAction* action = d->collection->action( actionname );
00408 d->buttons[ actionname ]->setEnabled( action ? action->isEnabled() : false );
00409 }
00410 }
00411
00412 void ActionCollectionView::slotSelectionChanged()
00413 {
00414 bool startenabled = selectionModel()->hasSelection();
00415 bool stopenabled = false;
00416 bool hasselection = selectionModel()->selectedIndexes().count() > 0;
00417 foreach(const QModelIndex &index, itemSelection().indexes()) {
00418 Action* action = ActionCollectionModel::action(index);
00419 if( startenabled && ! action )
00420 startenabled = false;
00421 if( ! stopenabled )
00422 stopenabled = (action && ! action->isFinalized());
00423 }
00424 QAction* runaction = d->collection->action("run");
00425 if( runaction ) {
00426 runaction->setEnabled(startenabled);
00427 emit enabledChanged("run");
00428 }
00429 QAction* stopaction = d->collection->action("stop");
00430 if( stopaction ) {
00431 stopaction->setEnabled(stopenabled);
00432 emit enabledChanged("stop");
00433 }
00434 QAction* editaction = d->collection->action("edit");
00435 if( editaction ) {
00436 editaction->setEnabled(hasselection);
00437 emit enabledChanged("edit");
00438 }
00439 QAction* removeaction = d->collection->action("remove");
00440 if( removeaction ) {
00441 removeaction->setEnabled(hasselection);
00442 emit enabledChanged("remove");
00443 }
00444 }
00445
00446 void ActionCollectionView::slotDataChanged(const QModelIndex&, const QModelIndex&)
00447 {
00448 d->modified = true;
00449 }
00450
00451 void ActionCollectionView::slotRun()
00452 {
00453 if( ! selectionModel() ) return;
00454 QAction* stopaction = d->collection->action("stop");
00455
00456 foreach(const QModelIndex &index, itemSelection().indexes()) {
00457 if( ! index.isValid() )
00458 continue;
00459 if( stopaction ) {
00460 stopaction->setEnabled(true);
00461 emit enabledChanged("stop");
00462 }
00463 Action* action = ActionCollectionModel::action(index);
00464 if( ! action )
00465 continue;
00466 connect(action, SIGNAL(finished(Kross::Action*)), SLOT(slotSelectionChanged()));
00467 action->trigger();
00468 }
00469 slotSelectionChanged();
00470 }
00471
00472 void ActionCollectionView::slotStop()
00473 {
00474 if( ! selectionModel() ) return;
00475 foreach(const QModelIndex &index, itemSelection().indexes()) {
00476 if( ! index.isValid() )
00477 continue;
00478 Action* action = ActionCollectionModel::action(index);
00479 if( ! action )
00480 continue;
00481
00482
00483 action->finalize();
00484 }
00485 slotSelectionChanged();
00486 }
00487
00488 void ActionCollectionView::slotEdit()
00489 {
00490 if( ! selectionModel() ) return;
00491 Action* action = 0;
00492 ActionCollection* collection = 0;
00493 foreach(const QModelIndex &index, itemSelection().indexes()) {
00494 if( ! index.isValid() ) continue;
00495 if( Action* a = ActionCollectionModel::action(index) )
00496 action = a;
00497 else if( ActionCollection* c = ActionCollectionModel::collection(index) )
00498 collection = c;
00499 else
00500 continue;
00501 break;
00502 }
00503 if( (! action) && (! collection) ) return;
00504 KPageDialog* dialog = new KPageDialog( this );
00505 dialog->setCaption( i18n("Edit") );
00506 dialog->setButtons( KDialog::Ok | KDialog::Cancel );
00507
00508 dialog->setFaceType( KPageDialog::Plain );
00509 ActionCollectionEditor* editor =
00510 action ? new ActionCollectionEditor(action, dialog->mainWidget())
00511 : new ActionCollectionEditor(collection, dialog->mainWidget());
00512 dialog->addPage(editor, i18nc("@title:group Script properties", "General"));
00513
00514 dialog->resize( QSize(580, 200).expandedTo( dialog->minimumSizeHint() ) );
00515 int result = dialog->exec();
00516 if( result == QDialog::Accepted ) {
00517 editor->commit();
00518 }
00519 dialog->delayedDestruct();
00520 }
00521
00522 void ActionCollectionView::slotAdd()
00523 {
00524
00525
00526 KMessageBox::sorry(0, "TODO");
00527
00528
00529
00530
00531 #if 0
00532 if( ! selectionModel() ) return;
00533 ActionCollection* collection = 0;
00534 foreach(QModelIndex index, itemSelection().indexes()) {
00535 if( ! index.isValid() ) continue;
00536 if( ActionCollectionModel::action(index) ) {
00537
00538 QModelIndex parent = index;
00539 while( parent.isValid() && ! collection ) {
00540 parent = d->view->model()->parent(parent);
00541 collection = ActionCollectionModel::collection(parent);
00542 }
00543 if( collection ) break;
00544 }
00545 else if( ActionCollection* c = ActionCollectionModel::collection(index) ) {
00546 collection = c;
00547 break;
00548 }
00549 }
00550 ScriptManagerAddWizard wizard(this, collection);
00551 int result = wizard.exec();
00552 Q_UNUSED(result);
00553 #endif
00554 }
00555
00556 void ActionCollectionView::slotRemove()
00557 {
00558 if( ! selectionModel() ) return;
00559 KMessageBox::sorry(0, "TODO");
00560 }
00561
00562 #include "view.moc"