Salome HOME
c3ff10c41508c1d40f3e3eea98d1c2362680dd71
[modules/gui.git] / src / SUIT / SUIT_ViewManager.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 #include "SUIT_ViewManager.h"
23
24 #include "SUIT_Desktop.h"
25 #include "SUIT_ViewModel.h"
26 #include "SUIT_ViewWindow.h"
27 #include "SUIT_Study.h"
28
29 #include <QMap>
30 #include <QRegExp>
31 #include <QIcon>
32
33 #ifdef WIN32
34 #include <windows.h>
35 #endif
36
37 QMap<QString, int> SUIT_ViewManager::_ViewMgrId;
38
39 /*!\class SUIT_ViewManager.
40  * Class provide manipulation with view windows.
41  */
42
43 /*!Constructor.*/
44 SUIT_ViewManager::SUIT_ViewManager( SUIT_Study* theStudy,
45                                     SUIT_Desktop* theDesktop,
46                                     SUIT_ViewModel* theViewModel )
47 : QObject( 0 ),
48 myDesktop( theDesktop ),
49 myTitle( "Default: %M - viewer %V" ),
50 myStudy( NULL )
51 {
52   myViewModel = 0;
53   myActiveView = 0;
54   setViewModel( theViewModel );
55
56   myId = useNewId( getType() );
57
58   connect( theDesktop, SIGNAL( windowActivated( SUIT_ViewWindow* ) ),
59            this,       SLOT( onWindowActivated( SUIT_ViewWindow* ) ) );
60
61   myStudy = theStudy;
62   if ( myStudy )
63     connect( myStudy, SIGNAL( destroyed() ), this, SLOT( onDeleteStudy() ) );
64 }
65
66 /*!Destructor.*/
67 SUIT_ViewManager::~SUIT_ViewManager()
68 {
69   if ( myViewModel )
70   {
71     myViewModel->setViewManager( 0 );
72     delete myViewModel;
73   }
74 }
75
76 int SUIT_ViewManager::useNewId( const QString& type )
77 {
78   if ( !_ViewMgrId.contains( type ) )
79     _ViewMgrId.insert( type, 0 );
80
81   int id = _ViewMgrId[type];
82   _ViewMgrId[type]++;
83   return id;
84 }
85
86 void SUIT_ViewManager::setTitle( const QString& theTitle )
87 {
88   if ( myTitle == theTitle )
89     return;
90
91   myTitle = theTitle;
92   for ( int i = 0; i < myViews.count(); i++ )
93     setViewName( myViews[i] );
94 }
95
96 void SUIT_ViewManager::setIcon( const QPixmap& theIcon )
97 {
98   myIcon = theIcon;
99   for ( int i = 0; i < myViews.count(); i++ )
100     myViews[i]->setWindowIcon( QIcon( myIcon ) );
101 }
102
103 /*!Sets view model \a theViewModel to view manager.*/
104 void SUIT_ViewManager::setViewModel(SUIT_ViewModel* theViewModel)
105 {
106   if (myViewModel && myViewModel != theViewModel) {
107     myViewModel->setViewManager(0);
108     delete myViewModel;
109   }
110   myViewModel = theViewModel;
111   if (myViewModel)
112     myViewModel->setViewManager(this);
113 }
114
115 /*!Sets view name for view window \a theView.*/
116 void SUIT_ViewManager::setViewName( SUIT_ViewWindow* theView )
117 {
118   QString title = prepareTitle( getTitle(), myId + 1, myViews.indexOf( theView ) + 1 );
119   theView->setWindowTitle( title );
120 }
121
122 QString SUIT_ViewManager::prepareTitle( const QString& title, const int mId, const int vId )
123 {
124   QString res = title;
125   QRegExp re( "%[%MV]" );
126   int i = 0;
127   while ( ( i = re.indexIn( res, i ) ) != -1 )
128   {
129     QString rplc;
130     QString str = res.mid( i, re.matchedLength() );
131     if ( str == QString( "%%" ) )
132       rplc = QString( "%" );
133     else if ( str == QString( "%M" ) )
134       rplc = QString::number( mId );
135     else if ( str == QString( "%V" ) )
136       rplc = QString::number( vId );
137     res.replace( i, re.matchedLength(), rplc );
138     i += rplc.length();
139   }
140   return res;
141 }
142
143 /*! Creates View, adds it into list of views and returns just created view window*/
144 SUIT_ViewWindow* SUIT_ViewManager::createViewWindow()
145 {
146   SUIT_ViewWindow* aView = myViewModel->createView(myDesktop);
147
148   if ( !insertView( aView ) ){
149     delete aView;
150     return 0;
151   }
152
153   setViewName( aView );
154   aView->setWindowIcon( QIcon( myIcon ) );
155
156   //myDesktop->addViewWindow( aView );
157   //it is done automatically during creation of view
158
159   aView->setViewManager( this );
160   emit viewCreated( aView );
161
162   // Special treatment for the case when <aView> is the first one in this view manager
163   // -> call onWindowActivated() directly, because somebody may always want
164   // to use getActiveView()
165   if ( !myActiveView )
166     onWindowActivated( aView );
167
168   return aView;
169 }
170
171 /*! Get identifier */
172 int SUIT_ViewManager::getId() const
173 {
174   return myId;
175 }
176
177 /*!Create view window.*/
178 void SUIT_ViewManager::createView()
179 {
180   createViewWindow();
181 }
182
183 QVector<SUIT_ViewWindow*> SUIT_ViewManager::getViews() const
184 {
185   QVector<SUIT_ViewWindow*> res;
186   for ( int i = 0; i < myViews.count(); i++ )
187   {
188     if ( myViews[i] )
189       res.append( myViews[i] );
190   }
191
192   return res;
193 }
194
195 /*!Insert view window to view manager.
196  *\retval false - if something wrong, else true.
197  */
198 bool SUIT_ViewManager::insertView(SUIT_ViewWindow* theView)
199 {
200   unsigned int aSize = myViews.size();
201   unsigned int aNbItems = myViews.count() + 1;
202   if ( aNbItems > aSize )
203   {
204     myViews.resize( aNbItems );
205     aSize = myViews.size();
206   }
207
208   connect(theView, SIGNAL(closing(SUIT_ViewWindow*)),
209           this,    SLOT(onClosingView(SUIT_ViewWindow*)));
210
211   connect(theView, SIGNAL(mousePressed(SUIT_ViewWindow*, QMouseEvent*)),
212           this,    SLOT(onMousePressed(SUIT_ViewWindow*, QMouseEvent*)));
213
214   connect(theView, SIGNAL(mouseReleased(SUIT_ViewWindow*, QMouseEvent*)),
215           this,    SIGNAL(mouseRelease(SUIT_ViewWindow*, QMouseEvent*)));
216
217   connect(theView, SIGNAL(mouseDoubleClicked(SUIT_ViewWindow*, QMouseEvent*)),
218           this,    SIGNAL(mouseDoubleClick(SUIT_ViewWindow*, QMouseEvent*)));
219
220   connect(theView, SIGNAL(mouseMoving(SUIT_ViewWindow*, QMouseEvent*)),
221           this,    SIGNAL(mouseMove(SUIT_ViewWindow*, QMouseEvent*)));
222
223   connect(theView, SIGNAL(wheeling(SUIT_ViewWindow*, QWheelEvent*)),
224           this,    SIGNAL(wheel(SUIT_ViewWindow*, QWheelEvent*)));
225
226   connect(theView, SIGNAL(keyPressed(SUIT_ViewWindow*, QKeyEvent*)),
227           this,    SIGNAL(keyPress(SUIT_ViewWindow*, QKeyEvent*)));
228
229   connect(theView, SIGNAL(keyReleased(SUIT_ViewWindow*, QKeyEvent*)),
230           this,    SIGNAL(keyRelease(SUIT_ViewWindow*, QKeyEvent*)));
231
232   connect(theView, SIGNAL(contextMenuRequested( QContextMenuEvent * )),
233           this,    SLOT  (onContextMenuRequested( QContextMenuEvent * )));
234
235   for ( uint i = 0; i < aSize; i++ )
236   {
237     if ( myViews[i] == 0 )
238     {
239       myViews[i] = theView;
240       return true;
241     }
242   }
243   return false;
244 }
245
246 /*!Emit delete view. Remove view window \a theView from view manager.
247 */
248 void SUIT_ViewManager::onClosingView( SUIT_ViewWindow* theView )
249 {
250   closeView( theView );
251 }
252
253 /*!
254   Remove the view window \a theView from view manager and destroy it.
255 */
256 void SUIT_ViewManager::closeView( SUIT_ViewWindow* theView )
257 {
258   if ( !theView )
259     return;
260
261   QPointer<SUIT_ViewWindow> view( theView );
262
263   view->hide();
264
265   if ( !view->testAttribute( Qt::WA_DeleteOnClose ) )
266     return;
267
268   emit deleteView( view );
269   removeView( view );
270
271   if ( view )
272     delete view;
273 }
274
275 /*!Remove view window \a theView from view manager.
276  *And close the last view, if it has \a theView.
277 */
278 void SUIT_ViewManager::removeView( SUIT_ViewWindow* theView )
279 {
280   theView->disconnect( this );
281   myViews.remove( myViews.indexOf( theView ) );
282   if ( myActiveView == theView )
283     myActiveView = 0;
284   if ( !myViews.count() )
285     emit lastViewClosed( this );
286 }
287
288 /*!
289   Set or clear flag Qt::WDestructiveClose for all views
290 */
291 void SUIT_ViewManager::setDestructiveClose( const bool on )
292 {
293   for ( int i = 0; i < myViews.count(); i++ )
294     myViews[i]->setDestructiveClose( on );
295 }
296
297 /*!
298   Returns 'true' if any of views (view windows) is visible.
299 */
300 bool SUIT_ViewManager::isVisible() const
301 {
302   bool res = false;
303   for ( int i = 0; i < myViews.count() && !res; i++ )
304     res = myViews[i]->isVisibleTo( myViews[i]->parentWidget() );
305   return res;
306 }
307
308 /*!
309   Show or hide all views (view windows)
310 */
311 void SUIT_ViewManager::setShown( const bool on )
312 {
313   for ( int i = 0; i < myViews.count(); i++ )
314     myViews.at( i )->setShown( on );
315 }
316
317 /*!Emit on \a theEvent mouse pressed in \a theView.*/
318 void SUIT_ViewManager::onMousePressed(SUIT_ViewWindow* theView, QMouseEvent* theEvent)
319 {
320   emit mousePress(theView, theEvent);
321 }
322
323 /*!Emit activated for view \a view.
324 */
325 void SUIT_ViewManager::onWindowActivated(SUIT_ViewWindow* view)
326 {
327   if (view) {
328     unsigned int aSize = myViews.size();
329     for (uint i = 0; i < aSize; i++) {
330       if (myViews[i] && myViews[i] == view) {
331         myActiveView = view;
332         emit activated( this );
333         return;
334       }
335     }
336   }
337 }
338
339 /*!Close all views.
340 */
341 void SUIT_ViewManager::closeAllViews()
342 {
343   for ( int i = 0; i < myViews.size(); i++ )
344     delete myViews[i];
345   myViews.clear();
346 }
347
348 /*!
349  *\retval QString - type of view model.
350  */
351 QString SUIT_ViewManager::getType() const
352 {
353   return (!myViewModel)? "": myViewModel->getType();
354 }
355
356 /*!
357  *\retval SUIT_Study* - current study.
358  */
359 SUIT_Study* SUIT_ViewManager::study() const
360 {
361     return myStudy;
362 }
363
364 /*!
365  * Sets stydy to NULL.
366  */
367 void SUIT_ViewManager::onDeleteStudy()
368 {
369     myStudy = NULL;
370 }
371
372 /*! invoke method of SUIT_PopupClient, which notifies about popup*/
373 void SUIT_ViewManager::onContextMenuRequested( QContextMenuEvent* e )
374 {
375   contextMenuRequest( e );
376 }
377
378 /*!Context menu popup for \a popup.*/
379 void SUIT_ViewManager::contextMenuPopup( QMenu* popup )
380 {
381   SUIT_ViewModel* vm = getViewModel();
382   if ( vm )
383     vm->contextMenuPopup( popup );
384 }