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