Salome HOME
Copyright update 2022
[modules/gui.git] / src / GraphicsView / GraphicsView_ViewFrame.cxx
1 // Copyright (C) 2013-2022  CEA/DEN, EDF R&D, OPEN CASCADE
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, or (at your option) any later version.
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
20 #include "GraphicsView_ViewFrame.h"
21
22 #include "GraphicsView_Viewer.h"
23 #include "GraphicsView_ViewPort.h"
24
25 #include <QtxAction.h>
26 #include <QtxActionToolMgr.h>
27 #include <QtxMultiAction.h>
28 #include <QtxToolBar.h>
29
30 #include <SUIT_Desktop.h>
31 #include <SUIT_MessageBox.h>
32 #include <SUIT_Session.h>
33 #include <SUIT_ResourceMgr.h>
34
35 #include <QColor>
36 #include <QFrame>
37 #include <QFileDialog>
38 #include <QGraphicsSceneMouseEvent>
39 #include <QGraphicsSceneWheelEvent>
40 #include <QHBoxLayout>
41 #include <QImage>
42 #include <QMouseEvent>
43 #include <QString>
44 #include <QWheelEvent>
45
46 //=======================================================================
47 // Name    : GraphicsView_ViewFrame
48 // Purpose : Constructor
49 //=======================================================================
50 GraphicsView_ViewFrame::GraphicsView_ViewFrame( SUIT_Desktop* d, GraphicsView_Viewer* vw, QWidget* w )
51 : SUIT_ViewWindow( d ),
52   myViewer( vw ), myToolBarId( -1 )
53 {
54   QFrame* aFrame = new QFrame( this );
55   setCentralWidget( aFrame );
56
57   QBoxLayout* aLayout = new QHBoxLayout( aFrame );
58   aLayout->setMargin( 0 );
59   aLayout->setSpacing( 0 );
60
61   if( w )
62     myViewPort = dynamic_cast<GraphicsView_ViewPort*>(w);
63   else
64     myViewPort = new GraphicsView_ViewPort( aFrame );
65
66   aLayout->addWidget( myViewPort );
67
68   connect( myViewPort, SIGNAL( vpKeyEvent( QKeyEvent* ) ),
69            this, SLOT( keyEvent( QKeyEvent* ) ) );
70   connect( myViewPort, SIGNAL( vpMouseEvent( QGraphicsSceneMouseEvent* ) ),
71            this, SLOT( mouseEvent( QGraphicsSceneMouseEvent* ) ) );
72   connect( myViewPort, SIGNAL( vpWheelEvent( QGraphicsSceneWheelEvent* ) ),
73            this, SLOT( wheelEvent( QGraphicsSceneWheelEvent* ) ) );
74   connect( myViewPort, SIGNAL( vpContextMenuEvent( QGraphicsSceneContextMenuEvent* ) ),
75            this, SLOT( contextMenuEvent( QGraphicsSceneContextMenuEvent* ) ) );
76
77   connect( myViewPort, SIGNAL( vpSketchingFinished( QPainterPath ) ),
78            this, SIGNAL( sketchingFinished( QPainterPath ) ) );
79 }
80
81 //=======================================================================
82 // Name    : GraphicsView_ViewFrame
83 // Purpose : Destructor
84 //=======================================================================
85 GraphicsView_ViewFrame::~GraphicsView_ViewFrame()
86 {
87 }
88
89 //================================================================
90 // Function : createActions
91 // Purpose  : 
92 //================================================================
93 void GraphicsView_ViewFrame::createActions()
94 {
95   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
96   QtxAction* anAction;
97
98   // Dump view
99   anAction = new QtxAction( tr( "MNU_DUMP_VIEW" ),
100                            aResMgr->loadPixmap( "GraphicsView", tr( "ICON_GV_DUMP" ) ),
101                            tr( "MNU_DUMP_VIEW" ), 0, this );
102   anAction->setStatusTip( tr( "DSC_DUMP_VIEW" ) );
103   connect( anAction, SIGNAL( triggered( bool ) ), this, SLOT( onDumpView() ) );
104   toolMgr()->registerAction( anAction, DumpId );
105
106   // FitAll
107   anAction = new QtxAction( tr( "MNU_FITALL" ),
108                            aResMgr->loadPixmap( "GraphicsView", tr( "ICON_GV_FITALL" ) ),
109                            tr( "MNU_FITALL" ), 0, this );
110   anAction->setStatusTip( tr( "DSC_FITALL" ) );
111   connect( anAction, SIGNAL( triggered( bool ) ), this, SLOT( onViewFitAll() ) );
112   toolMgr()->registerAction( anAction, FitAllId );
113
114   // FitRect
115   anAction = new QtxAction( tr( "MNU_FITRECT" ),
116                            aResMgr->loadPixmap( "GraphicsView", tr( "ICON_GV_FITAREA" ) ),
117                            tr( "MNU_FITRECT" ), 0, this );
118   anAction->setStatusTip( tr( "DSC_FITRECT" ) );
119   connect( anAction, SIGNAL( triggered( bool ) ), this, SLOT( onViewFitArea() ) );
120   toolMgr()->registerAction( anAction, FitRectId );
121
122   // FitSelect
123   anAction = new QtxAction( tr( "MNU_FITSELECT" ),
124                            aResMgr->loadPixmap( "GraphicsView", tr( "ICON_GV_FITSELECT" ) ),
125                            tr( "MNU_FITSELECT" ), 0, this );
126   anAction->setStatusTip( tr( "DSC_FITSELECT" ) );
127   connect( anAction, SIGNAL( triggered( bool ) ), this, SLOT( onViewFitSelect() ) );
128   toolMgr()->registerAction( anAction, FitSelectId );
129
130   // Zoom
131   anAction = new QtxAction( tr( "MNU_ZOOM_VIEW" ),
132                            aResMgr->loadPixmap( "GraphicsView", tr( "ICON_GV_ZOOM" ) ),
133                            tr( "MNU_ZOOM_VIEW" ), 0, this );
134   anAction->setStatusTip( tr( "DSC_ZOOM_VIEW" ) );
135   connect( anAction, SIGNAL( triggered( bool ) ), this, SLOT( onViewZoom() ) );
136   toolMgr()->registerAction( anAction, ZoomId );
137
138   // Panning
139   anAction = new QtxAction( tr( "MNU_PAN_VIEW" ),
140                            aResMgr->loadPixmap( "GraphicsView", tr( "ICON_GV_PAN" ) ),
141                            tr( "MNU_PAN_VIEW" ), 0, this );
142   anAction->setStatusTip( tr( "DSC_PAN_VIEW" ) );
143   connect( anAction, SIGNAL( triggered( bool ) ), this, SLOT( onViewPan() ) );
144   toolMgr()->registerAction( anAction, PanId );
145
146   // Global Panning
147   anAction = new QtxAction( tr( "MNU_GLOBALPAN_VIEW" ),
148                            aResMgr->loadPixmap( "GraphicsView", tr( "ICON_GV_GLOBALPAN" ) ),
149                            tr( "MNU_GLOBALPAN_VIEW" ), 0, this );
150   anAction->setStatusTip( tr( "DSC_GLOBALPAN_VIEW" ) );
151   connect( anAction, SIGNAL( triggered( bool ) ), this, SLOT( onViewGlobalPan() ) );
152   toolMgr()->registerAction( anAction, GlobalPanId );
153
154   // Reset (obsolete)
155   /*
156   anAction = new QtxAction( tr( "MNU_RESET_VIEW" ),
157                            aResMgr->loadPixmap( "GraphicsView", tr( "ICON_GV_RESET" ) ),
158                            tr( "MNU_RESET_VIEW" ), 0, this );
159   anAction->setStatusTip( tr( "DSC_RESET_VIEW" ) );
160   connect( anAction, SIGNAL( triggered( bool ) ), this, SLOT( onViewReset() ) );
161   toolMgr()->registerAction( anAction, ResetId );
162   */
163 }
164
165 //================================================================
166 // Function : createToolBar
167 // Purpose  : 
168 //================================================================
169 int GraphicsView_ViewFrame::createToolBar()
170 {
171   int tid = toolMgr()->createToolBar( tr("LBL_TOOLBAR_LABEL"),                 // title (language-dependant)
172                                       QString( "GraphicsViewViewOperations" ), // name (language-independant)
173                                       false );                                 // disable floatable toolbar
174   toolMgr()->append( DumpId, tid );
175
176   QtxMultiAction* aScaleAction = new QtxMultiAction( this );
177   aScaleAction->insertAction( toolMgr()->action( FitAllId ) );
178   aScaleAction->insertAction( toolMgr()->action( FitRectId ) );
179   aScaleAction->insertAction( toolMgr()->action( FitSelectId ) );
180   aScaleAction->insertAction( toolMgr()->action( ZoomId ) );
181   toolMgr()->append( aScaleAction, tid );
182   myScaleAction = aScaleAction;
183
184   QtxMultiAction* aPanAction = new QtxMultiAction( this );
185   aPanAction->insertAction( toolMgr()->action( PanId ) );
186   aPanAction->insertAction( toolMgr()->action( GlobalPanId ) );
187   toolMgr()->append( aPanAction, tid );
188   myPanAction = aPanAction;
189
190   toolMgr()->append( toolMgr()->action( ResetId ), tid );
191
192   return tid;
193 }
194
195 //================================================================
196 // Function : getToolBarId
197 // Purpose  :
198 //================================================================
199 int GraphicsView_ViewFrame::getToolBarId()
200 {
201   return myToolBarId;
202 }
203
204 //================================================================
205 // Function : dumpView
206 // Purpose  : 
207 //================================================================
208 QImage GraphicsView_ViewFrame::dumpView()
209 {
210   return myViewPort->dumpView();
211 }
212
213 //================================================================
214 // Function : dumpViewToFormat
215 // Purpose  : 
216 //================================================================
217 bool GraphicsView_ViewFrame::dumpViewToFormat( const QImage& image, const QString& fileName, const QString& format )
218 {
219   bool isOK = myViewPort->dumpViewToFormat(fileName, format);
220   if( !isOK )
221     isOK = SUIT_ViewWindow::dumpViewToFormat( image, fileName, format );
222   return isOK;
223 }
224
225 //================================================================
226 // Function : getVisualParameters
227 // Purpose  : 
228 //================================================================
229 QString GraphicsView_ViewFrame::getVisualParameters()
230 {
231   QTransform aTransform = myViewPort->transform();
232
233   QString aString;
234   aString.sprintf( "%.3f*%.3f*%.3f*%.3f*%.3f*%.3f*%.3f*%.3f*%.3f",
235     aTransform.m11(), aTransform.m12(), aTransform.m13(),
236     aTransform.m21(), aTransform.m22(), aTransform.m23(),
237     aTransform.m31(), aTransform.m32(), aTransform.m33() );
238   return aString;
239 }
240
241 //================================================================
242 // Function : setVisualParameters
243 // Purpose  : 
244 //================================================================
245 void GraphicsView_ViewFrame::setVisualParameters( const QString& theParameters )
246 {
247   QStringList aList = theParameters.split( '*' );
248   if( aList.size() < 9 )
249     return;
250
251   bool anIsOk[9];
252   QTransform aTransform( aList[0].toDouble( &anIsOk[0] ),
253                          aList[1].toDouble( &anIsOk[1] ),
254                          aList[2].toDouble( &anIsOk[2] ),
255                          aList[3].toDouble( &anIsOk[3] ),
256                          aList[4].toDouble( &anIsOk[4] ),
257                          aList[5].toDouble( &anIsOk[5] ),
258                          aList[6].toDouble( &anIsOk[6] ),
259                          aList[7].toDouble( &anIsOk[7] ),
260                          aList[8].toDouble( &anIsOk[8] ) );
261   for( int i = 0; i < 9; i++ )
262     if( !anIsOk[ i ] )
263       return;
264
265   myViewPort->setTransform( aTransform );
266   myViewPort->applyTransform();
267 }
268
269 //================================================================
270 // Function : expandToolBarActions
271 // Purpose  : 
272 //================================================================
273 void GraphicsView_ViewFrame::expandToolBarActions()
274 {
275   QList<QAction*> anExpandableActions;
276   anExpandableActions.append( myScaleAction );
277   anExpandableActions.append( myPanAction );
278
279   QListIterator<QAction*> anIter( anExpandableActions );
280   while( anIter.hasNext() )
281   {
282     QtxMultiAction* aMultiAction = dynamic_cast<QtxMultiAction*>( anIter.next() );
283     if( aMultiAction )
284     {
285       QList<QAction*> aLocalActions = aMultiAction->actions();
286       QListIterator<QAction*> aLocalIter( aLocalActions );
287       while( aLocalIter.hasNext() )
288         if( QAction* anAction = aLocalIter.next() )
289           toolMgr()->append( anAction, myToolBarId );
290
291       int anId = toolMgr()->actionId( aMultiAction );
292       toolMgr()->remove( anId, myToolBarId );
293     }
294   }
295 }
296
297 //================================================================
298 // Function : onViewPan
299 // Purpose  : 
300 //================================================================
301 void GraphicsView_ViewFrame::onViewPan()
302 {
303   myViewer->activateTransform( GraphicsView_Viewer::Pan );
304 }
305
306 //================================================================
307 // Function : onViewZoom
308 // Purpose  : 
309 //================================================================
310 void GraphicsView_ViewFrame::onViewZoom()
311 {
312   myViewer->activateTransform( GraphicsView_Viewer::Zoom );
313 }
314
315 //================================================================
316 // Function : onViewFitAll
317 // Purpose  : 
318 //================================================================
319 void GraphicsView_ViewFrame::onViewFitAll()
320 {
321   myViewer->activateTransform( GraphicsView_Viewer::FitAll );
322 }
323
324 //================================================================
325 // Function : onViewFitArea
326 // Purpose  : 
327 //================================================================
328 void GraphicsView_ViewFrame::onViewFitArea()
329 {
330   myViewer->activateTransform( GraphicsView_Viewer::FitRect );
331 }
332
333 //================================================================
334 // Function : onViewFitSelect
335 // Purpose  : 
336 //================================================================
337 void GraphicsView_ViewFrame::onViewFitSelect()
338 {
339   myViewer->activateTransform( GraphicsView_Viewer::FitSelect );
340 }
341
342 //================================================================
343 // Function : onViewGlobalPan
344 // Purpose  : 
345 //================================================================
346 void GraphicsView_ViewFrame::onViewGlobalPan()
347 {
348   myViewer->activateTransform( GraphicsView_Viewer::PanGlobal );
349 }
350
351 //================================================================
352 // Function : onViewReset
353 // Purpose  : 
354 //================================================================
355 void GraphicsView_ViewFrame::onViewReset()
356 {
357   myViewer->activateTransform( GraphicsView_Viewer::Reset );
358 }
359
360 //================================================================
361 // Function : keyEvent
362 // Purpose  : 
363 //================================================================
364 void GraphicsView_ViewFrame::keyEvent( QKeyEvent* e )
365 {
366   switch ( e->type() )
367   {
368     case QEvent::KeyPress:
369       emit keyPressed( e );
370       break;
371     case QEvent::KeyRelease:
372       emit keyReleased( e );
373       break;
374     default:
375       break;
376   }
377 }
378
379 //================================================================
380 // Function : mouseEvent
381 // Purpose  : 
382 //================================================================
383 void GraphicsView_ViewFrame::mouseEvent( QGraphicsSceneMouseEvent* e )
384 {
385   switch ( e->type() )
386   {
387     case QEvent::GraphicsSceneMousePress:
388       emit mousePressed( e );
389       break;
390     case QEvent::GraphicsSceneMouseMove:
391       emit mouseMoving( e );
392       break;
393     case QEvent::GraphicsSceneMouseRelease:
394       emit mouseReleased( e );
395       break;
396     case QEvent::GraphicsSceneMouseDoubleClick:
397       emit mouseDoubleClicked( e );
398       break;
399     default:
400       break;
401   }
402 }
403
404 //================================================================
405 // Function : wheelEvent
406 // Purpose  : 
407 //================================================================
408 void GraphicsView_ViewFrame::wheelEvent( QGraphicsSceneWheelEvent* e )
409 {
410   switch ( e->type() )
411   {
412     case QEvent::GraphicsSceneWheel:
413       emit wheeling( e );
414       break;
415     default:
416       break;
417   }
418 }
419
420 //================================================================
421 // Function : contextMenuEvent
422 // Purpose  : 
423 //================================================================
424 void GraphicsView_ViewFrame::contextMenuEvent( QGraphicsSceneContextMenuEvent* e )
425 {
426   QPoint aPos = myViewPort->mapFromScene( e->scenePos() );
427   QContextMenuEvent* anEvent = new QContextMenuEvent( (QContextMenuEvent::Reason)e->reason(),
428                                                       aPos, e->screenPos(), e->modifiers() );
429   emit contextMenuRequested( anEvent );
430   delete anEvent;
431 }
432
433 /*!
434   \brief Handle show event.
435
436   Emits Show() signal.
437
438   \param theEvent show event
439 */
440 void GraphicsView_ViewFrame::showEvent( QShowEvent* theEvent )
441 {
442   if( myToolBarId < 0 )
443   {
444     createActions();
445     myToolBarId = createToolBar();
446   }
447
448   emit Show( theEvent );
449 }
450
451 /*!
452   \brief Handle hide event.
453
454   Emits Hide() signal.
455
456   \param theEvent hide event
457 */
458 void GraphicsView_ViewFrame::hideEvent( QHideEvent* theEvent )
459 {
460   emit Hide( theEvent );
461 }
462
463 /*!
464   \return filters for image files
465 */
466 QString GraphicsView_ViewFrame::filter() const
467 {
468   QStringList filters = SUIT_ViewWindow::filter().split( ";;", QString::SkipEmptyParts );
469   filters << tr( "POSTSCRIPT_FILES" );
470   return filters.join( ";;" );
471 }