00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "controller.h"
00020
00021 #include <QMap>
00022 #include <QList>
00023 #include <QEvent>
00024 #include <QMouseEvent>
00025 #include <QApplication>
00026
00027 #include <kdebug.h>
00028
00029 #include "area.h"
00030 #include "view.h"
00031 #include "document.h"
00032 #include "mainwindow.h"
00033
00034 namespace Sublime {
00035
00036 struct WidgetFinder {
00037 WidgetFinder(QWidget *_w) :w(_w), view(0) {}
00038 Area::WalkerMode operator()(AreaIndex *index)
00039 {
00040 foreach (View *v, index->views())
00041 {
00042 if (v->hasWidget() && (v->widget() == w))
00043 {
00044 view = v;
00045 return Area::StopWalker;
00046 }
00047 }
00048 return Area::ContinueWalker;
00049 }
00050
00051 QWidget *w;
00052 View *view;
00053 };
00054
00055 struct ToolWidgetFinder {
00056 ToolWidgetFinder(QWidget *_w) :w(_w), view(0) {}
00057 Area::WalkerMode operator()(View *v, Sublime::Position )
00058 {
00059 if (v->hasWidget() && (v->widget() == w))
00060 {
00061 view = v;
00062 return Area::StopWalker;
00063 }
00064 return Area::ContinueWalker;
00065 }
00066
00067 QWidget *w;
00068 View *view;
00069 };
00070
00071
00072
00073
00074 struct ControllerPrivate {
00075 ControllerPrivate()
00076 {
00077 }
00078
00079 void removeArea(QObject *obj)
00080 {
00081 areas.removeAll(reinterpret_cast<Area*>(obj));
00082 }
00083
00084 void removeDocument(QObject *obj)
00085 {
00086 documents.removeAll(reinterpret_cast<Document*>(obj));
00087 }
00088
00089 QList<Document*> documents;
00090 QList<Area*> areas;
00091 QList<Area*> allAreas;
00092 QMap<QString, Area*> namedAreas;
00093
00094 QMap<Area*, MainWindow*> shownAreas;
00095 QList<MainWindow*> controlledWindows;
00096 QVector< QList<Area*> > mainWindowAreas;
00097 };
00098
00099
00100
00101
00102
00103 Controller::Controller(QObject *parent)
00104 :QObject(parent), MainWindowOperator(), d( new ControllerPrivate() )
00105 {
00106 init();
00107 }
00108
00109 void Controller::init()
00110 {
00111
00112 qApp->installEventFilter(this);
00113 }
00114
00115 Controller::~Controller()
00116 {
00117
00118
00119
00120 delete d;
00121 }
00122
00123 void Controller::showArea(Area *area, MainWindow *mainWindow)
00124 {
00125 Area *areaToShow = 0;
00126
00127 if (d->shownAreas.contains(area) && (mainWindow != d->shownAreas[area]))
00128 areaToShow = new Area(*area);
00129 else
00130 areaToShow = area;
00131 d->shownAreas[areaToShow] = mainWindow;
00132
00133 showAreaInternal(areaToShow, mainWindow);
00134 }
00135
00136 void Controller::showAreaInternal(Area* area, MainWindow *mainWindow)
00137 {
00138
00139
00140
00141
00142 if (mainWindow->area())
00143 disconnect(mainWindow->area(), 0, mainWindow, 0);
00144 MainWindowOperator::setArea(mainWindow, area);
00145 connect(area, SIGNAL(viewAdded(Sublime::AreaIndex*, Sublime::View*)),
00146 mainWindow, SLOT(viewAdded(Sublime::AreaIndex*, Sublime::View*)));
00147 connect(area, SIGNAL(requestToolViewRaise(Sublime::View*)),
00148 mainWindow, SLOT(raiseToolView(Sublime::View*)));
00149 connect(area, SIGNAL(aboutToRemoveView(Sublime::AreaIndex*, Sublime::View*)),
00150 mainWindow, SLOT(aboutToRemoveView(Sublime::AreaIndex*, Sublime::View*)));
00151 connect(area, SIGNAL(toolViewAdded(Sublime::View*, Sublime::Position)),
00152 mainWindow, SLOT(toolViewAdded(Sublime::View*, Sublime::Position)));
00153 connect(area, SIGNAL(aboutToRemoveToolView(Sublime::View*, Sublime::Position)),
00154 mainWindow, SLOT(aboutToRemoveToolView(Sublime::View*, Sublime::Position)));
00155 connect(area, SIGNAL(toolViewMoved(Sublime::View*, Sublime::Position)),
00156 mainWindow, SLOT(toolViewMoved(Sublime::View*, Sublime::Position)));
00157 }
00158
00159 void Controller::showArea(const QString& areaTypeId, MainWindow *mainWindow)
00160 {
00161 int index = d->controlledWindows.indexOf(mainWindow);
00162 Q_ASSERT(index != -1);
00163
00164 Area* area = NULL;
00165 foreach (Area* a, d->mainWindowAreas[index])
00166 {
00167 kDebug() << "Object name: " << a->objectName() << " id "
00168 << areaTypeId;
00169 if (a->objectName() == areaTypeId)
00170 {
00171 area = a;
00172 break;
00173 }
00174 }
00175 Q_ASSERT (area);
00176
00177 showAreaInternal(area, mainWindow);
00178 }
00179
00180 void Controller::resetCurrentArea(MainWindow *mainWindow)
00181 {
00182 QString id = mainWindow->area()->objectName();
00183
00184 int areaIndex = 0;
00185 Area* def = NULL;
00186 foreach (Area* a, d->areas) {
00187 if (a->objectName() == id)
00188 {
00189 def = a;
00190 break;
00191 }
00192 ++areaIndex;
00193 }
00194 Q_ASSERT(def);
00195
00196 int index = d->controlledWindows.indexOf(mainWindow);
00197 Q_ASSERT(index != -1);
00198
00199 Area* prev = d->mainWindowAreas[index][areaIndex];
00200 d->mainWindowAreas[index][areaIndex] = new Area(*def);
00201 showAreaInternal(d->mainWindowAreas[index][areaIndex], mainWindow);
00202 delete prev;
00203 }
00204
00205 const QList<Area*> &Controller::defaultAreas() const
00206 {
00207 return d->areas;
00208 }
00209
00210 const QList<Area*> &Controller::areas(int mainWindow) const
00211 {
00212 return d->mainWindowAreas[mainWindow];
00213 }
00214
00215 const QList<Area*> &Controller::allAreas() const
00216 {
00217 return d->allAreas;
00218 }
00219
00220 const QList<Document*> &Controller::documents() const
00221 {
00222 return d->documents;
00223 }
00224
00225 void Controller::addDefaultArea(Area *area)
00226 {
00227 d->areas.append(area);
00228 d->allAreas.append(area);
00229 d->namedAreas[area->objectName()] = area;
00230 }
00231
00232 void Controller::addMainWindow(MainWindow* mainWindow)
00233 {
00234 Q_ASSERT (!d->controlledWindows.contains(mainWindow));
00235 d->controlledWindows << mainWindow;
00236 d->mainWindowAreas.resize(d->controlledWindows.size());
00237 int index = d->controlledWindows.size()-1;
00238
00239 foreach (Area* area, defaultAreas())
00240 {
00241 Area *na = new Area(*area);
00242 d->allAreas.append(na);
00243 d->mainWindowAreas[index].push_back(na);
00244 }
00245 showAreaInternal(d->mainWindowAreas[index][0], mainWindow);
00246 }
00247
00248 void Controller::addDocument(Document *document)
00249 {
00250 d->documents.append(document);
00251 }
00252
00253 void Controller::areaReleased()
00254 {
00255 MainWindow *w = reinterpret_cast<Sublime::MainWindow*>(sender());
00256 kDebug() << "marking areas as mainwindow-free";
00257 foreach (Area *area, d->shownAreas.keys(w))
00258 {
00259 kDebug() << "" << area->objectName();
00260 areaReleased(area);
00261 disconnect(area, 0, w, 0);
00262 }
00263 }
00264
00265 void Controller::areaReleased(Sublime::Area *area)
00266 {
00267 d->controlledWindows.removeAll(d->shownAreas[area]);
00268 d->shownAreas.remove(area);
00269 d->namedAreas.remove(area->objectName());
00270 }
00271
00272 Area *Controller::defaultArea(const QString &id)
00273 {
00274 return d->namedAreas[id];
00275 }
00276
00277 Area *Controller::area(int mainWindow, const QString& id)
00278 {
00279 foreach (Area* area, areas(mainWindow))
00280 {
00281 if (area->objectName() == id)
00282 return area;
00283 }
00284 return 0;
00285 }
00286
00287
00288
00289
00290
00291
00292
00293 bool Controller::eventFilter(QObject *obj, QEvent *ev)
00294 {
00295
00296 if (ev->type() != QEvent::MouseButtonPress &&
00297 ev->type() != QEvent::MouseButtonDblClick &&
00298 ev->type() != QEvent::FocusIn)
00299 return false;
00300
00301
00302 if (!obj->isWidgetType())
00303 return false;
00304
00305
00306 QWidget *w = static_cast<QWidget*>(obj);
00307 if (((w->windowFlags().testFlag(Qt::Dialog)) && w->isModal()) ||
00308 (w->windowFlags().testFlag(Qt::Popup)) || (w->windowFlags().testFlag(Qt::Tool)))
00309 return false;
00310
00311
00312 QMouseEvent *mev = 0;
00313 if (ev->type() == QEvent::MouseButtonPress || ev->type() == QEvent::MouseButtonDblClick)
00314 {
00315 mev = static_cast<QMouseEvent*>(ev);
00316 int activationButtonMask = Qt::LeftButton | Qt::MidButton | Qt::RightButton;
00317 if ((mev->button() & activationButtonMask) == 0)
00318 return false;
00319 }
00320
00321 while (w)
00322 {
00323
00324 MainWindow *mw = qobject_cast<Sublime::MainWindow*>(w->topLevelWidget());
00325 if (!mw || !d->controlledWindows.contains(mw))
00326 return false;
00327
00328 Area *area = mw->area();
00329
00331
00332 WidgetFinder widgetFinder(w);
00333 area->walkViews(widgetFinder, area->rootIndex());
00334 if (widgetFinder.view && widgetFinder.view != mw->activeView())
00335 {
00336 setActiveView(mw, widgetFinder.view);
00338 return false;
00339 }
00340
00341
00342 ToolWidgetFinder toolFinder(w);
00343 area->walkToolViews(toolFinder, Sublime::AllPositions);
00344 if (toolFinder.view && toolFinder.view != mw->activeToolView())
00345 {
00346 setActiveToolView(mw, toolFinder.view);
00348 return false;
00349 }
00350
00351 w = w->parentWidget();
00352 }
00353
00354 return false;
00355 }
00356
00357 const QList< MainWindow * > & Controller::mainWindows() const
00358 {
00359 return d->controlledWindows;
00360 }
00361
00362
00363 void Controller::notifyToolViewRemoved(Sublime::View *view, Sublime::Position)
00364 {
00365 emit aboutToRemoveToolView(view);
00366 }
00367
00368 void Controller::notifyToolViewAdded(Sublime::View *view, Sublime::Position)
00369 {
00370 emit toolViewAdded(view);
00371 }
00372
00373 void Controller::notifyViewRemoved(Sublime::AreaIndex*, Sublime::View *view)
00374 {
00375 emit aboutToRemoveView(view);
00376 }
00377
00378 void Controller::notifyViewAdded(Sublime::AreaIndex*, Sublime::View *view)
00379 {
00380 emit viewAdded(view);
00381 }
00382
00383 void Controller::setStatusIcon(Document * document, const QIcon & icon)
00384 {
00385 foreach (MainWindow* mw, mainWindows())
00386 if (mw->area())
00387 foreach (View* view, mw->area()->views())
00388 if (view->document() == document)
00389 MainWindowOperator::setStatusIcon(mw, view, icon);
00390 }
00391
00392 }
00393
00394 #include "controller.moc"