don't access workingset controller in no-ui mode
[kdevelop:kdevplatform.git] / shell / uicontroller.cpp
1 /***************************************************************************
2  *   Copyright 2007 Alexander Dymo  <adymo@kdevelop.org>            *
3  *                                                                         *
4  *   This program is free software; you can redistribute it and/or modify  *
5  *   it under the terms of the GNU Library General Public License as       *
6  *   published by the Free Software Foundation; either version 2 of the    *
7  *   License, or (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 Library General Public     *
15  *   License 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 #include "uicontroller.h"
20
21 #include <QMap>
22 #include <QAction>
23 #include <QPointer>
24 #include <QApplication>
25 #include <QListWidget>
26 #include <QToolBar>
27
28 #include <kdebug.h>
29 #include <kdialog.h>
30 #include <klocale.h>
31 #include <ksettings/dialog.h>
32 #include <ksettings/dispatcher.h>
33 #include <kcmultidialog.h>
34 #include <kxmlguifactory.h>
35 #include <kxmlguiclient.h>
36
37 #include <sublime/area.h>
38 #include <sublime/view.h>
39 #include <sublime/tooldocument.h>
40
41 #include "core.h"
42 #include "shellextension.h"
43 #include "partcontroller.h"
44 #include "plugincontroller.h"
45 #include "mainwindow.h"
46 #include "partdocument.h"
47 #include "textdocument.h"
48 #include "documentcontroller.h"
49 #include "assistantpopup.h"
50 #include <kactioncollection.h>
51 #include <ktexteditor/view.h>
52 #include "workingsetcontroller.h"
53 #include "workingsets/workingset.h"
54
55 namespace KDevelop {
56
57 class UiControllerPrivate {
58 public:
59     UiControllerPrivate(UiController *controller)
60     : areasRestored(false), m_controller(controller)
61     {
62         if (Core::self()->workingSetControllerInternal())
63             Core::self()->workingSetControllerInternal()->initializeController(m_controller);
64
65         QMap<QString, Sublime::Position> desired;
66
67         desired["org.kdevelop.ClassBrowserView"] = Sublime::Left;
68         desired["org.kdevelop.DocumentsView"] = Sublime::Left;
69         desired["org.kdevelop.ProjectsView"] = Sublime::Left;
70         desired["org.kdevelop.FileManagerView"] = Sublime::Left;
71         desired["org.kdevelop.ProblemReporterView"] = Sublime::Bottom;
72         desired["org.kdevelop.OutputView"] = Sublime::Bottom;
73         desired["org.kdevelop.ContextBrowser"] = Sublime::Bottom;
74         desired["org.kdevelop.KonsoleView"] = Sublime::Bottom;
75         desired["org.kdevelop.SnippetView"] = Sublime::Right;
76         desired["org.kdevelop.ExternalScriptView"] = Sublime::Right;
77         Sublime::Area* a =
78             new Sublime::Area(m_controller, "code", i18n("Code"));
79         a->setDesiredToolViews(desired);
80         a->setIconName("document-edit");
81         m_controller->addDefaultArea(a);
82
83         desired.clear();
84         desired["org.kdevelop.debugger.VariablesView"] = Sublime::Left;
85         desired["org.kdevelop.debugger.BreakpointsView"] = Sublime::Bottom;
86         desired["org.kdevelop.debugger.StackView"] = Sublime::Bottom;
87         desired["org.kdevelop.debugger.ConsoleView"] = Sublime::Bottom;
88         desired["org.kdevelop.KonsoleView"] = Sublime::Bottom;
89         a = new Sublime::Area(m_controller, "debug", i18n("Debug"));
90         a->setDesiredToolViews(desired);
91         a->setIconName("tools-report-bug");
92         m_controller->addDefaultArea(a);
93
94         desired.clear();
95         desired["org.kdevelop.ProjectsView"] = Sublime::Left;
96         desired["org.kdevelop.PatchReview"] = Sublime::Bottom;
97         
98         a = new Sublime::Area(m_controller, "review", i18n("Review"));
99         a->setDesiredToolViews(desired);
100         a->setIconName("applications-engineering");
101         m_controller->addDefaultArea(a);
102
103         if(!(Core::self()->setupFlags() & Core::NoUi)) 
104         {
105             defaultMainWindow = new MainWindow(m_controller);
106             m_controller->addMainWindow(defaultMainWindow);
107             activeSublimeWindow = defaultMainWindow;
108         }
109         else
110         {
111             activeSublimeWindow = defaultMainWindow = 0;
112         }
113     }
114
115     void widgetChanged(QWidget*, QWidget* now)
116     {
117         if (now) {
118             Sublime::MainWindow* win = qobject_cast<Sublime::MainWindow*>(now->window());
119             if( win )
120             {
121                 activeSublimeWindow = win;
122             }
123         }
124     }
125
126     Core *core;
127     MainWindow* defaultMainWindow;
128
129     QMap<IToolViewFactory*, Sublime::ToolDocument*> factoryDocuments;
130
131     Sublime::MainWindow* activeSublimeWindow;
132     QList<Sublime::MainWindow*> sublimeWindows;
133     bool areasRestored;
134
135     //Currently shown assistant popup.
136     QPointer<AssistantPopup> currentShownAssistant;
137
138 private:
139     UiController *m_controller;
140 };
141
142
143 class UiToolViewFactory: public Sublime::ToolFactory {
144 public:
145     UiToolViewFactory(IToolViewFactory *factory): m_factory(factory) {}
146     ~UiToolViewFactory() { delete m_factory; }
147     virtual QWidget* create(Sublime::ToolDocument *doc, QWidget *parent = 0)
148     {
149         Q_UNUSED( doc );
150         return m_factory->create(parent);
151     }
152
153
154     QList<QAction*> toolBarActions( QWidget* viewWidget ) const
155     {
156         return m_factory->toolBarActions( viewWidget );
157     }
158
159     QString id() const { return m_factory->id(); }
160 private:
161     IToolViewFactory *m_factory;
162 };
163
164
165 class ViewSelectorItem: public QListWidgetItem {
166 public:
167     ViewSelectorItem(const QString &text, QListWidget *parent = 0, int type = Type)
168         :QListWidgetItem(text, parent, type) {}
169     IToolViewFactory *factory;
170 };
171
172 UiController::UiController(Core *core)
173     :Sublime::Controller(0), IUiController(), d(new UiControllerPrivate(this))
174 {
175     setObjectName("UiController");
176     d->core = core;
177
178     if (!defaultMainWindow() || (Core::self()->setupFlags() & Core::NoUi))
179         return;
180
181     connect( QApplication::instance(),
182              SIGNAL( focusChanged( QWidget*, QWidget* ) ),
183             this, SLOT( widgetChanged( QWidget*, QWidget* ) ) );
184
185     KActionCollection * actions = defaultMainWindow()->actionCollection();
186
187     KAction* assistantaction1 = actions->addAction("assistant_action_1");
188     assistantaction1->setText( i18n("&Assistant Action 1") );
189     assistantaction1->setShortcut( Qt::ALT | Qt::Key_1 );
190     connect(assistantaction1, SIGNAL(triggered(bool)), this, SLOT(assistantAction1()));
191
192     KAction* assistantaction2 = actions->addAction("assistant_action_2");
193     assistantaction2->setText( i18n("&Assistant Action 2") );
194     assistantaction2->setShortcut( Qt::ALT | Qt::Key_2 );
195     connect(assistantaction2, SIGNAL(triggered(bool)), this, SLOT(assistantAction2(bool)));
196
197     KAction* assistantaction3 = actions->addAction("assistant_action_3");
198     assistantaction3->setText( i18n("&Assistant Action 3") );
199     assistantaction3->setShortcut( Qt::ALT | Qt::Key_3 );
200     connect(assistantaction3, SIGNAL(triggered(bool)), this, SLOT(assistantAction3(bool)));
201
202     KAction* assistantaction4 = actions->addAction("assistant_action_4");
203     assistantaction4->setText( i18n("&Assistant Action 4") );
204     assistantaction4->setShortcut( Qt::ALT | Qt::Key_4 );
205     connect(assistantaction4, SIGNAL(triggered(bool)), this, SLOT(assistantAction4(bool)));
206
207     KAction* assistantactionhide = actions->addAction("assistant_action_hide");
208     assistantactionhide->setText( i18n("&Hide Assistant") );
209     assistantactionhide->setShortcut( Qt::ALT | Qt::Key_0 );
210     connect(assistantactionhide, SIGNAL(triggered(bool)), this, SLOT(assistantHide()));
211 }
212
213 UiController::~UiController()
214 {
215     delete d;
216 }
217
218 void UiController::mainWindowDeleted(MainWindow* mw)
219 {
220     if (d->defaultMainWindow == mw)
221         d->defaultMainWindow = 0L;
222
223     if (d->activeSublimeWindow == mw)
224         d->activeSublimeWindow = 0L;
225 }
226
227 // FIXME: currently, this always create new window. Probably,
228 // should just rename it.
229 void UiController::switchToArea(const QString &areaName, SwitchMode switchMode)
230 {
231     if (switchMode == ThisWindow) {
232         showArea(areaName, activeSublimeWindow());
233         return;
234     }
235
236     MainWindow *main = new MainWindow(this);
237     // FIXME: what this is supposed to do?
238     // Answer: Its notifying the mainwindow to reload its settings when one of
239     // the KCM's changes its settings and it works
240     KSettings::Dispatcher::registerComponent( KGlobal::mainComponent(),
241                                     main, "loadSettings" );
242     KSettings::Dispatcher::registerComponent( Core::self()->componentData(),
243                                     main, "loadSettings" );
244
245     addMainWindow(main);
246     showArea(areaName, main);
247     main->initialize();
248
249     // WTF? First, enabling this code causes crashes since we
250     // try to disconnect some already-deleted action, or something.
251     // Second, this code will disconnection the clients from guiFactory
252     // of the previous main window. Ick!
253 #if 0
254     //we need to add all existing guiclients to the new mainwindow
255     //@todo adymo: add only ones that belong to the area (when the area code is there)
256     foreach (KXMLGUIClient *client, oldMain->guiFactory()->clients())
257         main->guiFactory()->addClient(client);
258 #endif
259
260     main->show();
261 }
262
263
264 QWidget* UiController::findToolView(const QString& name, IToolViewFactory *factory, FindFlags flags)
265 {
266     if(!d->areasRestored)
267         return 0;
268
269     QList< Sublime::View* > views = activeArea()->toolViews();
270     foreach(Sublime::View* view, views) {
271         Sublime::ToolDocument *doc = dynamic_cast<Sublime::ToolDocument*>(view->document());
272         if(doc && doc->title() == name && view->widget()) {
273             if(flags & Raise)
274                 view->requestRaise();
275             return view->widget();
276         }
277     }
278     
279     QWidget* ret = 0;
280     
281     if(flags & Create)
282     {
283         if(!d->factoryDocuments.contains(factory))
284             d->factoryDocuments[factory] = new Sublime::ToolDocument(name, this, new UiToolViewFactory(factory));
285         
286         Sublime::ToolDocument *doc = d->factoryDocuments[factory];
287
288         Sublime::View* view = addToolViewToArea(factory, doc, activeArea());
289         if(view)
290             ret = view->widget();
291         
292         if(flags & Raise)
293             findToolView(name, factory, Raise);
294     }
295
296     return ret;
297 }
298
299 void UiController::raiseToolView(QWidget* toolViewWidget)
300 {
301     if(!d->areasRestored)
302         return;
303
304     QList< Sublime::View* > views = activeArea()->toolViews();
305     foreach(Sublime::View* view, views) {
306         if(view->widget() == toolViewWidget) {
307             view->requestRaise();
308             return;
309         }
310     }
311 }
312
313 void UiController::addToolView(const QString & name, IToolViewFactory *factory)
314 {
315     kDebug() ;
316     Sublime::ToolDocument *doc = new Sublime::ToolDocument(name, this, new UiToolViewFactory(factory));
317     d->factoryDocuments[factory] = doc;
318
319     /* Until areas are restored, we don't know which views should be really
320        added, and which not, so we just record view availability.  */
321     if (d->areasRestored) {
322          foreach (Sublime::Area* area, allAreas()) {
323              addToolViewToArea(factory, doc, area);
324          }
325     }
326 }
327
328 void KDevelop::UiController::raiseToolView(Sublime::View * view)
329 {
330     foreach( Sublime::Area* area, allAreas() ) {
331         if( area->toolViews().contains( view ) )
332             area->raiseToolView( view );
333     }
334 }
335
336 void KDevelop::UiController::removeToolView(IToolViewFactory *factory)
337 {
338     kDebug() ;
339     //delete the tooldocument
340     Sublime::ToolDocument *doc = d->factoryDocuments[factory];
341
342     ///@todo adymo: on document deletion all its views shall be also deleted
343     foreach (Sublime::View *view, doc->views()) {
344         foreach (Sublime::Area *area, allAreas())
345             if (area->removeToolView(view))
346                 view->deleteLater();
347     }
348
349     d->factoryDocuments.remove(factory);
350     delete doc;
351 }
352
353 Sublime::Area *UiController::activeArea()
354 {
355     Sublime::MainWindow *m = activeSublimeWindow();
356     if (m)
357         return activeSublimeWindow()->area();
358     return 0;
359 }
360
361 Sublime::MainWindow *UiController::activeSublimeWindow()
362 {
363     return d->activeSublimeWindow;
364 }
365
366 MainWindow *UiController::defaultMainWindow()
367 {
368     return d->defaultMainWindow;
369 }
370
371 void UiController::initialize()
372 {
373     defaultMainWindow()->initialize();
374 }
375
376 void UiController::cleanup()
377 {
378     foreach (Sublime::MainWindow* w, mainWindows())
379         w->saveSettings();
380     saveAllAreas(KGlobal::config());
381 }
382
383 void UiController::addNewToolView(MainWindow *mw)
384 {
385     if (!mw || !mw->area())
386         return;
387     KDialog *dia = new KDialog(mw);
388     dia->setCaption(i18n("Select Tool View to Add"));
389     dia->setButtons(KDialog::Ok | KDialog::Cancel);
390     QListWidget *list = new QListWidget(dia);
391
392     list->setSortingEnabled(true);
393     for (QMap<IToolViewFactory*, Sublime::ToolDocument*>::const_iterator it = d->factoryDocuments.constBegin();
394         it != d->factoryDocuments.constEnd(); ++it)
395     {
396         ViewSelectorItem *item = new ViewSelectorItem(it.value()->title(), list);
397         item->factory = it.key();
398         list->addItem(item);
399     }
400
401     list->setFocus();
402     dia->setMainWidget(list);
403     if (dia->exec() == QDialog::Accepted && list->currentItem())
404     {
405         ViewSelectorItem *current = static_cast<ViewSelectorItem*>(list->currentItem());
406         Sublime::ToolDocument *doc = d->factoryDocuments[current->factory];
407         Sublime::View *view = doc->createView();
408         mw->area()->addToolView(view,
409             Sublime::dockAreaToPosition(current->factory->defaultPosition()));
410         current->factory->viewCreated(view);
411     }
412     delete dia;
413 }
414
415 void UiController::showSettingsDialog()
416 {
417     QStringList blacklist = d->core->pluginControllerInternal()->projectPlugins();
418     kDebug() << "blacklist" << blacklist;
419     KSettings::Dialog cfgDlg( QStringList() << "kdevplatform",
420                                         activeMainWindow() );
421     cfgDlg.setComponentBlacklist( blacklist );
422     cfgDlg.exec();
423 }
424
425 Sublime::Controller* UiController::controller()
426 {
427     return this;
428 }
429
430 KParts::MainWindow *UiController::activeMainWindow()
431 {
432     return (KParts::MainWindow*)(activeSublimeWindow());
433 }
434
435 void UiController::saveArea(Sublime::Area * area, KConfigGroup & group)
436 {
437     area->save(group);
438     if (!area->workingSet().isEmpty()) {
439         WorkingSet* set = Core::self()->workingSetControllerInternal()->getWorkingSet(area->workingSet());
440         set->saveFromArea(area, area->rootIndex());
441     }
442 }
443
444 void UiController::loadArea(Sublime::Area * area, const KConfigGroup & group)
445 {
446     area->load(group);
447     if (!area->workingSet().isEmpty()) {
448         WorkingSet* set = Core::self()->workingSetControllerInternal()->getWorkingSet(area->workingSet());
449         Q_ASSERT(set->isConnected(area));
450     }
451 }
452
453 void UiController::saveAllAreas(KSharedConfig::Ptr config)
454 {
455     KConfigGroup uiConfig(config, "User Interface");
456     int wc = mainWindows().size();
457     uiConfig.writeEntry("Main Windows Count", wc);
458     for (int w = 0; w < wc; ++w)
459     {
460         Sublime::MainWindow *mw = mainWindows()[w];
461
462         KConfigGroup mainWindowConfig(&uiConfig,
463                                       QString("Main Window %1").arg(w));
464         mainWindowConfig.writeEntry("currentArea", mw->area()->objectName());
465
466         foreach (Sublime::Area* defaultArea, defaultAreas())
467         {
468             // FIXME: using object name seems ugly.
469             QString type = defaultArea->objectName();
470             Sublime::Area* area = this->area(w, type);
471             KConfigGroup areaConfig(&mainWindowConfig, "Area " + type);
472
473             areaConfig.deleteGroup();
474             areaConfig.writeEntry("id", type);
475             saveArea(area, areaConfig);
476             areaConfig.sync();
477         }
478     }
479     uiConfig.sync();
480 }
481
482 void UiController::loadAllAreas(KSharedConfig::Ptr config)
483 {
484     KConfigGroup uiConfig(config, "User Interface");
485     int wc = uiConfig.readEntry("Main Windows Count", 1);
486
487     /* It is expected the main windows are restored before
488        restoring areas.  */
489     if (wc > mainWindows().size())
490         wc = mainWindows().size();
491
492     QList<Sublime::Area*> changedAreas;
493
494     /* Offer all toolviews to the default areas.  */
495     foreach (Sublime::Area *area, defaultAreas())
496     {
497         QMap<IToolViewFactory*, Sublime::ToolDocument*>::const_iterator i, e;
498         for (i = d->factoryDocuments.constBegin(),
499                  e = d->factoryDocuments.constEnd(); i != e; ++i)
500         {
501             addToolViewIfWanted(i.key(), i.value(), area);
502         }
503     }
504
505     /* Restore per-windows areas.  */
506     for (int w = 0; w < wc; ++w)
507     {
508         KConfigGroup mainWindowConfig(&uiConfig,
509                                       QString("Main Window %1").arg(w));
510         QString currentArea = mainWindowConfig.readEntry("currentArea", "");
511         
512         if(currentArea == "test") ///@todo The area was renamed, and it will lead to a crash, so this is a dirty temporary workaround
513             currentArea = "review";
514         
515         Sublime::MainWindow *mw = mainWindows()[w];
516
517         /* We loop over default areas.  This means that if
518            the config file has an area of some type that is not
519            in default set, we'd just ignore it.  I think it's fine --
520            the model were a given mainwindow can has it's own
521            area types not represented in the default set is way
522            too complex.  */
523         foreach (Sublime::Area* defaultArea, defaultAreas())
524         {
525             QString type = defaultArea->objectName();
526             Sublime::Area* area = this->area(w, type);
527
528             KConfigGroup areaConfig(&mainWindowConfig, "Area " + type);
529
530             kDebug() << "Trying to restore area " << type;
531
532             /* This is just an easy check that a group exists, to
533                avoid "restoring" area from empty config group, wiping
534                away programmatically installed defaults.  */
535             if (areaConfig.readEntry("id", "") == type)
536             {
537                 kDebug() << "Restoring area " << type;
538                 loadArea(area, areaConfig);
539             }
540
541             // At this point we know which toolviews the area wants.
542             // Tender all tool views we have.
543             QMap<IToolViewFactory*, Sublime::ToolDocument*>::const_iterator i, e;
544             for (i = d->factoryDocuments.constBegin(),
545                      e = d->factoryDocuments.constEnd(); i != e; ++i)
546             {
547                 addToolViewIfWanted(i.key(), i.value(), area);
548             }
549         }
550
551         // FIXME: check that an area of this name exists.
552         if (!currentArea.isEmpty())
553             showArea(currentArea, mw);
554         else
555             // Force reload of the changes.
556             showAreaInternal(mw->area(), mw);
557
558         mw->enableAreaSettingsSave();
559     }
560
561     d->areasRestored = true;
562 }
563
564 void UiController::addToolViewToDockArea(const QString& name,
565                                          IToolViewFactory* factory,
566                                          Qt::DockWidgetArea area)
567 {
568     ///TODO: we should probably add a bool forcePosition member to
569     /// Area::addToolView(), to force adding at the given position.
570     Sublime::View* view = addToolViewToArea(factory, d->factoryDocuments[factory], activeArea());
571     activeArea()->moveToolView(view, Sublime::dockAreaToPosition(area));
572 }
573
574 void UiController::addToolViewIfWanted(IToolViewFactory* factory,
575                            Sublime::ToolDocument* doc,
576                            Sublime::Area* area)
577 {
578     if (area->wantToolView(factory->id()))
579     {
580         addToolViewToArea(factory, doc, area);
581     }
582 }
583
584 Sublime::View* UiController::addToolViewToArea(IToolViewFactory* factory,
585                                      Sublime::ToolDocument* doc,
586                                      Sublime::Area* area)
587 {
588     Sublime::View* view = doc->createView();
589     area->addToolView(
590         view,
591         Sublime::dockAreaToPosition(factory->defaultPosition()));
592
593     connect(view, SIGNAL(raise(Sublime::View*)),
594             SLOT(raiseToolView(Sublime::View*)));
595
596     factory->viewCreated(view);
597     return view;
598 }
599
600 void UiController::registerStatus(QObject* status)
601 {
602     Sublime::MainWindow* w = activeSublimeWindow();
603     if (!w) return;
604     MainWindow* mw = qobject_cast<KDevelop::MainWindow*>(w);
605     if (!mw) return;
606     mw->registerStatus(status);
607 }
608
609 void UiController::showErrorMessage(const QString& message, int timeout)
610 {
611     Sublime::MainWindow* w = activeSublimeWindow();
612     if (!w) return;
613     MainWindow* mw = qobject_cast<KDevelop::MainWindow*>(w);
614     if (!mw) return;
615     QMetaObject::invokeMethod(mw, "showErrorMessage", Q_ARG(QString, message), Q_ARG(int, timeout));
616 }
617
618 void UiController::hideAssistant(const KDevelop::IAssistant::Ptr& assistant)
619 {
620     if(d->currentShownAssistant && d->currentShownAssistant->assistant() == assistant) {
621         disconnect(d->currentShownAssistant->assistant().data(), SIGNAL(hide()), this, SLOT(assistantHide()));
622         disconnect(d->currentShownAssistant->assistant().data(), SIGNAL(actionsChanged()), this, SLOT(assistantActionsChanged()));
623         
624         AssistantPopup* oldPopup = d->currentShownAssistant;
625         d->currentShownAssistant = 0;
626         oldPopup->hide();
627         oldPopup->deleteLater(); //We have to do deleteLater, so we don't get problems when an assistant hides itself
628     }
629 }
630
631 void UiController::popUpAssistant(const KDevelop::IAssistant::Ptr& assistant)
632 {
633     assistantHide();
634     if(!assistant)
635         return;
636     
637     Sublime::View* view = d->activeSublimeWindow->activeView();
638     if( !view )
639     {
640         kDebug() << "no active view in mainwindow";
641         return;
642     }
643     TextEditorWidget* textWidget = dynamic_cast<TextEditorWidget*>(view->widget());
644     if(textWidget && textWidget->editorView()) {
645
646         d->currentShownAssistant = new AssistantPopup(textWidget->editorView(), assistant);
647         if(assistant->actions().count())
648             d->currentShownAssistant->show();
649
650         connect(assistant.data(), SIGNAL(hide()), SLOT(assistantHide()), Qt::DirectConnection);
651         connect(assistant.data(), SIGNAL(actionsChanged()), SLOT(assistantActionsChanged()), Qt::DirectConnection);
652     }
653 }
654
655 const QMap< IToolViewFactory*, Sublime::ToolDocument* >& UiController::factoryDocuments() const
656 {
657     return d->factoryDocuments;
658 }
659
660 void UiController::assistantAction1() {
661     if(d->currentShownAssistant)
662         d->currentShownAssistant->executeAction1();
663 }
664
665 void UiController::assistantAction2(bool) {
666     if(d->currentShownAssistant)
667         d->currentShownAssistant->executeAction2();
668 }
669
670 void UiController::assistantAction3(bool) {
671     if(d->currentShownAssistant)
672         d->currentShownAssistant->executeAction3();
673 }
674 void UiController::assistantAction4(bool) {
675     if(d->currentShownAssistant)
676         d->currentShownAssistant->executeAction4();
677 }
678
679 void UiController::assistantHide() {
680     if(d->currentShownAssistant)
681         hideAssistant(d->currentShownAssistant->assistant());
682 }
683
684 void UiController::assistantActionsChanged() {
685     if(d->currentShownAssistant)
686         popUpAssistant(d->currentShownAssistant->assistant());
687 }
688
689
690 }
691
692
693
694
695
696 #include "uicontroller.moc"