Salome HOME
Merge branch 'Dev_0.6' of newgeom:newgeom into Dev_0.6
[modules/shaper.git] / src / XGUI / XGUI_MainWindow.cpp
1 #include "XGUI_MainWindow.h"
2 #include "XGUI_Constants.h"
3 #include "XGUI_MainMenu.h"
4 #include "XGUI_ViewWindow.h"
5 #include "XGUI_Viewer.h"
6 #include "XGUI_ObjectsBrowser.h"
7
8 #include <PyConsole_Console.h>
9 #include <PyConsole_EnhInterp.h>
10
11 #include <QMdiArea>
12 #include <QMdiSubWindow>
13 #include <QAction>
14 #include <QDockWidget>
15 #include <QApplication>
16 #include <QTimer>
17 #include <QCloseEvent>
18
19
20 XGUI_MainWindow::XGUI_MainWindow(QWidget* parent)
21     : QMainWindow(parent),
22       myPythonConsole(0), myIsModified(false)
23 {
24   myTitle = tr("New Geom");
25   updateTitle();
26   createMainMenu();
27   QMdiArea* aMdiArea = new QMdiArea(this);
28   aMdiArea->setContextMenuPolicy(Qt::ActionsContextMenu);
29   setCentralWidget(aMdiArea);
30   connect(aMdiArea, SIGNAL(subWindowActivated(QMdiSubWindow*)), this,
31           SLOT(onViewActivated(QMdiSubWindow*)));
32
33   // Create actions of MDI area
34   QAction* aAction = new QAction(QIcon(":pictures/new_view.png"), tr("Create Window"), aMdiArea);
35   aMdiArea->addAction(aAction);
36   connect(aAction, SIGNAL(triggered(bool)), this, SLOT(createSubWindow()));
37
38   aAction = new QAction(QIcon(":pictures/tile_views.png"), tr("Tile"), aMdiArea);
39   aMdiArea->addAction(aAction);
40   connect(aAction, SIGNAL(triggered(bool)), aMdiArea, SLOT(tileSubWindows()));
41
42   aAction = new QAction(QIcon(":pictures/cascade_views.png"), tr("Cascade"), aMdiArea);
43   aMdiArea->addAction(aAction);
44   connect(aAction, SIGNAL(triggered(bool)), this, SLOT(cascadeWindows()));
45
46   aAction = new QAction(aMdiArea);
47   aAction->setSeparator(true);
48   aMdiArea->addAction(aAction);
49
50   myViewer = new XGUI_Viewer(this);
51   connect(myViewer, SIGNAL(viewCreated(XGUI_ViewWindow*)), this,
52           SLOT(onViewCreated(XGUI_ViewWindow*)));
53   connect(myViewer, SIGNAL(deleteView(XGUI_ViewWindow*)), this,
54           SLOT(onDeleteView(XGUI_ViewWindow*)));
55 }
56
57 XGUI_MainWindow::~XGUI_MainWindow(void)
58 {
59 }
60
61 //******************************************************
62 QMdiArea* XGUI_MainWindow::mdiArea() const
63 {
64   return static_cast<QMdiArea*>(centralWidget());
65 }
66
67 //******************************************************
68 void XGUI_MainWindow::showPythonConsole()
69 {
70   // TODO: Check why PyConsole can not be created
71   if (!myPythonConsole) {
72     myPythonConsole = new PyConsole_EnhConsole(this, new PyConsole_EnhInterp());
73     myPythonConsole->setObjectName("PythonConsole");
74     undockPythonConsole();
75   }
76   myPythonConsole->parentWidget()->show();
77 }
78
79 //******************************************************
80 void XGUI_MainWindow::hidePythonConsole()
81 {
82   if (myPythonConsole)
83     myPythonConsole->parentWidget()->hide();
84 }
85
86 //******************************************************
87 void XGUI_MainWindow::dockPythonConsole()
88 {
89   if (!myPythonConsole)
90     return;
91   myMenuBar->removeConsole();
92   QDockWidget* aDock = new QDockWidget(this);
93   aDock->setFeatures(QDockWidget::AllDockWidgetFeatures | QDockWidget::DockWidgetVerticalTitleBar);
94   aDock->setAllowedAreas(
95       Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea | Qt::BottomDockWidgetArea);
96   aDock->setMinimumHeight(0);
97   aDock->setWindowTitle("Console");
98   aDock->setWidget(myPythonConsole);
99   addDockWidget(Qt::BottomDockWidgetArea, aDock);
100   // Undock python console if widget is closed...
101   CloseEventWatcher* aWatcher = new CloseEventWatcher(aDock);
102   connect(aWatcher, SIGNAL(widgetClosed()), this, SLOT(undockPythonConsole()));
103   aDock->installEventFilter(aWatcher);
104 }
105
106 void XGUI_MainWindow::undockPythonConsole()
107 {
108   if (!myPythonConsole)
109     return;
110   QDockWidget* aDock = qobject_cast<QDockWidget*>(myPythonConsole->parentWidget());
111   //When the application starts console will be displayed as
112   //a wokbench tab, so there is no dock yet
113   if (aDock) {
114     aDock->hide();
115     aDock->setWidget(NULL);
116     aDock->deleteLater();
117   }
118   myMenuBar->insertConsole(myPythonConsole);
119 }
120
121 //******************************************************
122 void XGUI_MainWindow::createSubWindow()
123 {
124   viewer()->createView();
125 }
126
127 //******************************************************
128 void XGUI_MainWindow::cascadeWindows()
129 {
130   QMdiArea* aMdiArea = static_cast<QMdiArea*>(centralWidget());
131   QList<QMdiSubWindow*> aWindows = aMdiArea->subWindowList();
132
133   QSize aSize = aMdiArea->size();
134   QRect aRect = aMdiArea->geometry();
135   const int aOffset = 30;
136   int i = 0, j = 0;
137   int x, y;
138   int w = aSize.width() / 2;
139   int h = aSize.height() / 2;
140   QMdiSubWindow* aLastWnd;
141   foreach(QMdiSubWindow* aWnd, aWindows)
142   {
143     aWnd->showNormal();
144     aWnd->raise();
145     x = aOffset * i;
146     if ((x + w) > aSize.width()) {
147       x = 0;
148       i = 0;
149     }
150     y = aOffset * j;
151     if ((y + h) > aSize.height()) {
152       y = 0;
153       j = 0;
154     }
155     aWnd->setGeometry(QStyle::visualRect(aWnd->layoutDirection(), aRect, QRect(x, y, w, h)));
156     i++;
157     j++;
158     viewer()->onWindowActivated(aWnd);
159     aLastWnd = aWnd;
160     QApplication::processEvents();
161   }
162   aLastWnd->setFocus();
163 }
164
165 void XGUI_MainWindow::onViewCreated(XGUI_ViewWindow* theWindow)
166 {
167   QWidget* aSubWindow = theWindow->parentWidget();
168   QWidget* aMDIWidget = centralWidget();
169
170   QAction* aAction = new QAction(aSubWindow->windowTitle(), aMDIWidget);
171   aAction->setCheckable(true);
172   connect(aAction, SIGNAL(triggered(bool)), this, SLOT(activateView()));
173   aMDIWidget->addAction(aAction);
174
175   QList<QAction*> aActions = aMDIWidget->actions();
176   foreach(QAction* aAct, aActions)
177   {
178     if (aAct->isCheckable())
179       aAct->setChecked(false);
180   }
181   aAction->setChecked(true);
182 }
183
184 void XGUI_MainWindow::onDeleteView(XGUI_ViewWindow* theWindow)
185 {
186   QWidget* aSubWindow = theWindow->parentWidget();
187   QString aTitle = aSubWindow->windowTitle();
188   QWidget* aMDIWidget = centralWidget();
189   QList<QAction*> aActions = aMDIWidget->actions();
190
191   QAction* aDelAct = 0;
192   foreach(QAction* aAct, aActions)
193   {
194     if (aAct->text() == aTitle) {
195       aDelAct = aAct;
196       break;
197     }
198   }
199   aMDIWidget->removeAction(aDelAct);
200 }
201
202 void XGUI_MainWindow::activateView()
203 {
204   QAction* aAction = static_cast<QAction*>(sender());
205   QString aWndTitle = aAction->text();
206   QMdiArea* aMdiArea = static_cast<QMdiArea*>(centralWidget());
207
208   QList<QMdiSubWindow*> aWndList = aMdiArea->subWindowList();
209   QMdiSubWindow* aTargetView = 0;
210   foreach(QMdiSubWindow* aWnd, aWndList)
211   {
212     if (aWnd->windowTitle() == aWndTitle) {
213       aWnd->raise();
214       aWnd->activateWindow();
215       aTargetView = aWnd;
216       break;
217     }
218   }
219   QApplication::processEvents();
220   if (aTargetView)
221     QTimer::singleShot(20, aTargetView, SLOT(setFocus()));
222 }
223
224 void XGUI_MainWindow::onViewActivated(QMdiSubWindow* theSubWnd)
225 {
226   if (!theSubWnd)
227     return;
228   QMdiArea* aMdiArea = static_cast<QMdiArea*>(centralWidget());
229   QString aWndTitle = theSubWnd->windowTitle();
230   QList<QAction*> aActionList = aMdiArea->actions();
231   foreach(QAction* aAct, aActionList)
232   {
233     if (aAct->isCheckable())
234       aAct->setChecked(aAct->text() == aWndTitle);
235   }
236 }
237
238 void XGUI_MainWindow::closeEvent(QCloseEvent * event)
239 {
240   emit exitKeySequence();
241   event->ignore();
242 }
243
244 void XGUI_MainWindow::createMainMenu()
245 {
246   myMenuBar = new XGUI_MainMenu(this);
247   QDockWidget* aMenuDock = new QDockWidget(this);
248   aMenuDock->setWidget(myMenuBar);
249   aMenuDock->setAllowedAreas(Qt::TopDockWidgetArea);
250   aMenuDock->setFeatures(QDockWidget::DockWidgetVerticalTitleBar);
251   aMenuDock->setWindowTitle(tr("General"));
252   addDockWidget(Qt::TopDockWidgetArea, aMenuDock);
253 }
254
255
256 void XGUI_MainWindow::updateTitle()
257 {
258   QString aTitle = myTitle;
259   if (!myCurrentDir.isNull())
260     aTitle += " - " + myCurrentDir;
261   if (myIsModified)
262     aTitle += "*";
263   setWindowTitle(aTitle);
264 }
265
266 void XGUI_MainWindow::setCurrentDir(const QString& theDir, bool toUpdate)
267 {
268   myCurrentDir = theDir;
269   if (toUpdate)
270     updateTitle();
271 }
272
273 void XGUI_MainWindow::setModifiedState(bool isModified, bool toUpdate)
274 {
275   myIsModified = isModified;
276   if (toUpdate)
277     updateTitle();
278 }
279
280 CloseEventWatcher::CloseEventWatcher(QObject* theParent)
281     : QObject(theParent)
282 {
283 }
284
285 bool CloseEventWatcher::eventFilter(QObject *obj, QEvent *event)
286 {
287   if (event->type() == QEvent::Close) {
288     emit widgetClosed();
289     event->ignore();
290     return true;
291   } else {
292     // standard event processing
293     return QObject::eventFilter(obj, event);
294   }
295 }
296