]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
New Viewer : QtViewer
authorCHEMIN Sebastien <sc236498@is242584.intra.cea.fr>
Tue, 19 Mar 2024 10:29:50 +0000 (11:29 +0100)
committerCHEMIN Sebastien <sc236498@is242584.intra.cea.fr>
Tue, 19 Mar 2024 10:29:50 +0000 (11:29 +0100)
40 files changed:
CMakeLists.txt
SalomeGUIConfig.cmake.in
src/CMakeLists.txt
src/LightApp/CMakeLists.txt
src/LightApp/LightApp_Application.cxx
src/LightApp/LightApp_Application.h
src/LightApp/LightApp_QTVSelector.cxx [new file with mode: 0644]
src/LightApp/LightApp_QTVSelector.h [new file with mode: 0644]
src/LightApp/resources/LightApp.xml
src/LightApp/resources/LightApp_msg_en.ts
src/QtViewer/CMakeLists.txt [new file with mode: 0644]
src/QtViewer/QtViewer.h [new file with mode: 0644]
src/QtViewer/QtViewer_Object.cxx [new file with mode: 0644]
src/QtViewer/QtViewer_Object.h [new file with mode: 0644]
src/QtViewer/QtViewer_Scene.cxx [new file with mode: 0644]
src/QtViewer/QtViewer_Scene.h [new file with mode: 0644]
src/QtViewer/QtViewer_Selector.cxx [new file with mode: 0644]
src/QtViewer/QtViewer_Selector.h [new file with mode: 0644]
src/QtViewer/QtViewer_ViewFrame.cxx [new file with mode: 0644]
src/QtViewer/QtViewer_ViewFrame.h [new file with mode: 0644]
src/QtViewer/QtViewer_ViewManager.cxx [new file with mode: 0644]
src/QtViewer/QtViewer_ViewManager.h [new file with mode: 0644]
src/QtViewer/QtViewer_ViewPort.cxx [new file with mode: 0644]
src/QtViewer/QtViewer_ViewPort.h [new file with mode: 0644]
src/QtViewer/QtViewer_Viewer.cxx [new file with mode: 0644]
src/QtViewer/QtViewer_Viewer.h [new file with mode: 0644]
src/QtViewer/resources/QtViewer_images.ts [new file with mode: 0644]
src/QtViewer/resources/QtViewer_msg_en.ts [new file with mode: 0644]
src/QtViewer/resources/QtViewer_msg_fr.ts [new file with mode: 0644]
src/QtViewer/resources/QtViewer_msg_ja.ts [new file with mode: 0644]
src/QtViewer/resources/qtviewer_cursor_zoom.png [new file with mode: 0644]
src/QtViewer/resources/qtviewer_dump.png [new file with mode: 0644]
src/QtViewer/resources/qtviewer_fitall.png [new file with mode: 0644]
src/QtViewer/resources/qtviewer_fitarea.png [new file with mode: 0644]
src/QtViewer/resources/qtviewer_fitselect.png [new file with mode: 0644]
src/QtViewer/resources/qtviewer_glpan.png [new file with mode: 0644]
src/QtViewer/resources/qtviewer_pan.png [new file with mode: 0644]
src/QtViewer/resources/qtviewer_reset.png [new file with mode: 0644]
src/QtViewer/resources/qtviewer_rotate.png [new file with mode: 0644]
src/QtViewer/resources/qtviewer_zoom.png [new file with mode: 0644]

index f787bf564832dd2a2697bd4bae25171352d1025a..59750e97fd611a2ecaba70caf3f83bb62c04e000 100644 (file)
@@ -75,6 +75,7 @@ OPTION(SALOME_USE_OCCVIEWER "Enable OCC visualization (Mandatory in classic conf
 OPTION(SALOME_USE_PV3DVIEWER "Enable ParaView3D visualization (Optionally in classic configurations)" ON)
 OPTION(SALOME_USE_GLVIEWER "Enable OpenGL visualization (Mandatory in classic configurations)" ON)
 OPTION(SALOME_USE_GRAPHICSVIEW "Enable GraphicsView visualization (Mandatory in classic configurations)" ON)
+OPTION(SALOME_USE_QTVIEWER "Enable Qt viewer visualization (Mandatory in classic configurations)" ON)
 OPTION(SALOME_USE_PYVIEWER "Enable Python viewer (Mandatory in classic configurations)" ON)
 OPTION(SALOME_USE_PLOT2DVIEWER "Enable Plot2D visualization (Mandatory in classic configurations)" ON)
 OPTION(SALOME_USE_PYCONSOLE "Enable Python GUI interface (Mandatory in classic configurations)" ON)
@@ -84,7 +85,7 @@ OPTION(SALOME_USE_PVVIEWER "Enable ParaView visualization (Mandatory in classic
 CMAKE_DEPENDENT_OPTION(SALOME_USE_SALOMEOBJECT "Enable Salome Object (Mandatory in classic configurations)" ON
                        "SALOME_LIGHT_ONLY" ON)
 
-MARK_AS_ADVANCED(SALOME_LIGHT_ONLY SALOME_USE_VTKVIEWER SALOME_USE_GRAPHICSVIEW SALOME_USE_PVVIEWER)
+MARK_AS_ADVANCED(SALOME_LIGHT_ONLY SALOME_USE_VTKVIEWER SALOME_USE_GRAPHICSVIEW SALOME_USE_QTVIEWER SALOME_USE_PVVIEWER)
 MARK_AS_ADVANCED(SALOME_USE_SALOMEOBJECT SALOME_USE_OCCVIEWER SALOME_USE_GLVIEWER SALOME_USE_PLOT2DVIEWER)
 MARK_AS_ADVANCED(SALOME_USE_PYCONSOLE SALOME_USE_QXGRAPHVIEWER SALOME_USE_PYVIEWER SALOME_USE_PV3DVIEWER)
 
@@ -226,6 +227,11 @@ IF (NOT SALOME_USE_GRAPHICSVIEW)
   ADD_DEFINITIONS("-DDISABLE_GRAPHICSVIEW")
 ENDIF()
 
+# - Qt viewer: no prereqs
+IF (NOT SALOME_USE_QTVIEWER)
+  ADD_DEFINITIONS("-DDISABLE_QTVIEWER")
+ENDIF()
+
 # - Python editor: no prereqs
 IF (NOT SALOME_USE_PYVIEWER)
   ADD_DEFINITIONS("-DDISABLE_PYVIEWER")
@@ -403,6 +409,12 @@ IF(SALOME_USE_GRAPHICSVIEW)
        GraphicsView)
 ENDIF(SALOME_USE_GRAPHICSVIEW)
 
+# QtViewer specific targets:
+IF(SALOME_USE_QTVIEWER)
+  LIST(APPEND _${PROJECT_NAME}_exposed_targets
+       QtViewer)
+ENDIF(SALOME_USE_QTVIEWER)
+
 # PyEditor/Viewer specific targets:
 IF(SALOME_USE_PYVIEWER)
   LIST(APPEND _${PROJECT_NAME}_exposed_targets
index dd43712f985bdfa2f01952ef7ae0b1132bcf2da4..3f320fa71ceab3ccfd07c61d369c69142c61707f 100644 (file)
@@ -58,6 +58,7 @@ SET(SALOME_USE_VTKVIEWER      @SALOME_USE_VTKVIEWER@)
 SET(SALOME_USE_PV3DVIEWER     @SALOME_USE_PV3DVIEWER@)
 SET(SALOME_USE_PLOT2DVIEWER   @SALOME_USE_PLOT2DVIEWER@)
 SET(SALOME_USE_GRAPHICSVIEW   @SALOME_USE_GRAPHICSVIEW@)
+SET(SALOME_USE_QTVIEWER       @SALOME_USE_QTVIEWER@)
 SET(SALOME_USE_QXGRAPHVIEWER  @SALOME_USE_QXGRAPHVIEWER@)
 SET(SALOME_USE_PVVIEWER       @SALOME_USE_PVVIEWER@)
 SET(SALOME_USE_PYVIEWER       @SALOME_USE_PYVIEWER@)
@@ -99,6 +100,9 @@ ENDIF()
 IF (NOT SALOME_USE_GRAPHICSVIEW)
   LIST(APPEND GUI_DEFINITIONS "-DDISABLE_GRAPHICSVIEW")
 ENDIF()
+IF (NOT SALOME_USE_QTVIEWER)
+  LIST(APPEND GUI_DEFINITIONS "-DDISABLE_QTVIEWER")
+ENDIF()
 IF (NOT SALOME_USE_PVVIEWER)
   LIST(APPEND GUI_DEFINITIONS "-DDISABLE_PVVIEWER")
 ENDIF()
index 6c5fb917de1b1cc0c5021c4425499efe2eff57d6..479760204e74efad4b44e4e4f72cb044087a3cea 100644 (file)
@@ -117,6 +117,12 @@ IF(SALOME_USE_GRAPHICSVIEW)
   ADD_SUBDIRECTORY(GraphicsView)
 ENDIF(SALOME_USE_GRAPHICSVIEW)
 
+# Qt viewer
+##
+IF(SALOME_USE_QTVIEWER)
+  ADD_SUBDIRECTORY(QtViewer)
+ENDIF(SALOME_USE_QTVIEWER)
+
 # ParaView Viewer
 IF(SALOME_USE_PVVIEWER)
   ADD_SUBDIRECTORY(PVViewer)
index ee2414121aff82aca60565c4b3a9225f10f9f4b6..d3b610cbf7149f5b1db2ebdbe67d95f02c07e854 100644 (file)
@@ -49,6 +49,9 @@ ENDIF()
 IF(SALOME_USE_GRAPHICSVIEW)
   INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/GraphicsView)
 ENDIF()
+IF(SALOME_USE_QTVIEWER)
+  INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/QtViewer)
+ENDIF()
 IF(SALOME_USE_PYVIEWER)
   INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/PyEditor)
   INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/PyViewer)
@@ -121,6 +124,9 @@ ENDIF()
 IF(SALOME_USE_GRAPHICSVIEW)
   LIST(APPEND _link_LIBRARIES GraphicsView)
 ENDIF()
+IF(SALOME_USE_QTVIEWER)
+  LIST(APPEND _link_LIBRARIES QtViewer)
+ENDIF()
 IF(SALOME_USE_PYVIEWER)
   LIST(APPEND _link_LIBRARIES PyEditor PyViewer)
 ENDIF()
@@ -187,6 +193,9 @@ ENDIF()
 IF(SALOME_USE_GRAPHICSVIEW)
   LIST(APPEND _moc_HEADERS LightApp_GVSelector.h)
 ENDIF()
+IF(SALOME_USE_QTVIEWER)
+  LIST(APPEND _moc_HEADERS LightApp_QTVSelector.h)
+ENDIF()
 IF(SALOME_USE_OCCVIEWER)
   LIST(APPEND _moc_HEADERS LightApp_OCCSelector.h)
 ENDIF()
@@ -299,6 +308,9 @@ ENDIF()
 IF(SALOME_USE_GRAPHICSVIEW)
   LIST(APPEND _other_SOURCES LightApp_GVSelector.cxx)
 ENDIF()
+IF(SALOME_USE_QTVIEWER)
+  LIST(APPEND _other_SOURCES LightApp_QTVSelector.cxx)
+ENDIF()
 IF(SALOME_USE_OCCVIEWER)
   LIST(APPEND _other_SOURCES LightApp_OCCSelector.cxx)
 ENDIF()
index 19639c2812cea9d2732149a0cecf41434ad2d981..e7c81099b648d203992de0430f84ada4c6009485 100644 (file)
   #include "LightApp_GVSelector.h"
 #endif
 
+#ifndef DISABLE_QTVIEWER
+  #include "QtViewer_Viewer.h"
+  #include "QtViewer_ViewManager.h"
+  #include "LightApp_QTVSelector.h"
+#endif
+
 #ifndef DISABLE_PVVIEWER
   #include "PVViewer_ViewManager.h"
   #include "PVViewer_ViewWindow.h"
@@ -810,6 +816,9 @@ void LightApp_Application::createActions()
 #ifndef DISABLE_PV3DVIEWER
   createActionForViewer( NewPV3DViewId, newWinMenu, QString::number( 8 ), Qt::ALT+Qt::Key_3 );
 #endif
+#ifndef DISABLE_QTVIEWER
+  createActionForViewer( NewQtViewId, newWinMenu, QString::number( 9 ), Qt::ALT+Qt::Key_Q );
+#endif
 
   createAction( RenameId, tr( "TOT_RENAME" ), QIcon(), tr( "MEN_DESK_RENAME" ), tr( "PRP_RENAME" ),
                 Qt::ALT+Qt::SHIFT+Qt::Key_R, desk, false, this, SLOT( onRenameWindow() ) );
@@ -1292,6 +1301,11 @@ void LightApp_Application::onNewWindow()
     type = GraphicsView_Viewer::Type();
     break;
 #endif
+#ifndef DISABLE_QTVIEWER
+  case NewQtViewId:
+    type = QtViewer_Viewer::Type();
+    break;
+#endif
 #ifndef DISABLE_PVVIEWER
   case NewPVViewId:
     type = PVViewer_Viewer::Type();
@@ -1469,6 +1483,12 @@ void LightApp_Application::updateCommandsStatus()
     a->setEnabled( activeStudy() );
 #endif
 
+#ifndef DISABLE_QTVIEWER
+  a = action( NewQtViewId );
+  if( a )
+    a->setEnabled( activeStudy() );
+#endif
+
 #ifndef DISABLE_PVVIEWER
   a = action( NewPVViewId );
   if( a )
@@ -1946,6 +1966,13 @@ SUIT_ViewManager* LightApp_Application::createViewManager( const QString& vmType
     new LightApp_GVSelector( (GraphicsView_Viewer*)viewMgr->getViewModel(), mySelMgr );
   }
 #endif
+#ifndef DISABLE_QTVIEWER
+  if( vmType == QtViewer_Viewer::Type() )
+  {
+    viewMgr = new QtViewer_ViewManager( activeStudy(), desktop() );
+    new LightApp_QTVSelector( (QtViewer_Viewer*)viewMgr->getViewModel(), mySelMgr );
+  }
+#endif
 #ifndef DISABLE_PVVIEWER
   if( vmType == PVViewer_Viewer::Type() )
   {
index cb2102e1977519d6a6cbee1ba89ae6dd65f777bb..7f2f6d76fd9dfc5a7d81b269409b8a960d4745e2 100644 (file)
@@ -92,7 +92,7 @@ public:
          CloseId, CloseAllId, GroupAllId,
          PreferencesId, MRUId, ModulesListId,
          NewGLViewId, NewPlot2dId, NewOCCViewId, NewVTKViewId,
-         NewQxSceneViewId, NewGraphicsViewId, NewPVViewId, NewPyViewerId, NewPV3DViewId, StyleId, FullScreenId,
+         NewQxSceneViewId, NewGraphicsViewId, NewQtViewId, NewPVViewId, NewPyViewerId, NewPV3DViewId, StyleId, FullScreenId,
          WebSiteId, ForumId, VideosId, TutorialsId,
          UserID };
 
diff --git a/src/LightApp/LightApp_QTVSelector.cxx b/src/LightApp/LightApp_QTVSelector.cxx
new file mode 100644 (file)
index 0000000..4c6554a
--- /dev/null
@@ -0,0 +1,96 @@
+// Copyright (C) 2013-2023  CEA, EDF, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "LightApp_QTVSelector.h"
+
+#include "LightApp_DataOwner.h"
+
+#include <QtViewer_Object.h>
+#include <QtViewer_ViewPort.h>
+#include <QtViewer_Viewer.h>
+
+LightApp_QTVSelector::LightApp_QTVSelector( QtViewer_Viewer* theViewer,
+                                          SUIT_SelectionMgr* theSelMgr )
+: SUIT_Selector( theSelMgr, theViewer ),
+  myViewer( theViewer )
+{
+  connect( theViewer, SIGNAL( selectionChanged() ),
+          this, SLOT( onSelectionChanged() ) );
+}
+
+LightApp_QTVSelector::~LightApp_QTVSelector()
+{
+}
+
+QString LightApp_QTVSelector::type() const
+{
+  return QtViewer_Viewer::Type();
+}
+
+void LightApp_QTVSelector::getSelection( SUIT_DataOwnerPtrList& theList ) const
+{
+  if ( !myViewer )
+    return;
+
+  if( QtViewer_ViewPort* aViewport = myViewer->getActiveViewPort() )
+    {
+      foreach (QGraphicsItem *item, aViewport->scene()->selectedItems()) 
+        {
+         if (QtViewer_Object* obj = dynamic_cast<QtViewer_Object*>(item))
+           {
+             LightApp_DataOwner* owner = dynamic_cast<LightApp_DataOwner*>( obj->owner() );
+             if ( owner )
+               theList.append( SUIT_DataOwnerPtr( new LightApp_DataOwner( owner->entry() ) ) );
+           }
+        }
+    } 
+}
+
+void LightApp_QTVSelector::setSelection( const SUIT_DataOwnerPtrList& theList)
+{ 
+ if ( !myViewer )
+    return;
+
+  QMap<QString, int> aSelected;
+  for ( SUIT_DataOwnerPtrList::const_iterator itr = theList.begin(); itr != theList.end(); ++itr )
+  {
+    const LightApp_DataOwner* owner = dynamic_cast<const LightApp_DataOwner*>( (*itr).operator->() );
+
+    if ( owner )
+      aSelected.insert( owner->entry(), 0 );
+  }
+  
+  if( QtViewer_ViewPort* aViewport = myViewer->getActiveViewPort() )
+    {
+    foreach (QGraphicsItem *item, aViewport->items())
+      { 
+        if (QtViewer_Object* obj = dynamic_cast<QtViewer_Object*>(item))
+          {
+            LightApp_DataOwner* owner = dynamic_cast<LightApp_DataOwner*>( obj->owner() );
+            bool sel = owner && aSelected.contains(owner->entry());
+            obj->setSelected(sel);
+          }
+      }
+   }
+}
+
+void LightApp_QTVSelector::onSelectionChanged()
+{
+  selectionChanged();
+}
diff --git a/src/LightApp/LightApp_QTVSelector.h b/src/LightApp/LightApp_QTVSelector.h
new file mode 100644 (file)
index 0000000..0d7e67c
--- /dev/null
@@ -0,0 +1,52 @@
+// Copyright (C) 2013-2023  CEA, EDF, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef LIGHTAPP_QTVSELECTOR_H
+#define LIGHTAPP_QTVSELECTOR_H
+
+#include "LightApp.h"
+
+#include <QObject>
+#include <SUIT_Selector.h>
+#include <SUIT_DataOwner.h>
+
+class QtViewer_Viewer;
+
+class LIGHTAPP_EXPORT LightApp_QTVSelector : public QObject, public SUIT_Selector
+{
+  Q_OBJECT
+
+public:
+  LightApp_QTVSelector( QtViewer_Viewer*, SUIT_SelectionMgr* );
+  virtual ~LightApp_QTVSelector();
+
+  virtual QString type() const;
+
+protected:
+  virtual void getSelection( SUIT_DataOwnerPtrList& ) const;
+  virtual void setSelection( const SUIT_DataOwnerPtrList& );
+
+protected slots:
+  void onSelectionChanged();
+
+protected:
+  QtViewer_Viewer* myViewer;
+};
+
+#endif
index 0e1c4249e764cebd02385eaca650232a47048102..1d72e5991e369d3738a4247066657b625c6ad578 100644 (file)
@@ -43,6 +43,7 @@
     <parameter name="SPlot2d"       value="${GUI_ROOT_DIR}/share/salome/resources/gui"/>
     <parameter name="GLViewer"      value="${GUI_ROOT_DIR}/share/salome/resources/gui"/>
     <parameter name="GraphicsView"  value="${GUI_ROOT_DIR}/share/salome/resources/gui"/>
+    <parameter name="QtViewer"      value="${GUI_ROOT_DIR}/share/salome/resources/gui"/>
     <parameter name="OCCViewer"     value="${GUI_ROOT_DIR}/share/salome/resources/gui"/>
     <parameter name="VTKViewer"     value="${GUI_ROOT_DIR}/share/salome/resources/gui"/>
     <parameter name="PVViewer"      value="${GUI_ROOT_DIR}/share/salome/resources/gui"/>
index 894c867f13f0278a5d5728c0540da3118d99deab..efdbdcc6a15193f099b550daa706835cd795d5a6 100644 (file)
@@ -568,6 +568,10 @@ The changes will be applied on the next application session.</translation>
         <source>NEW_WINDOW_8</source>
         <translation>ParaView&amp;3D view</translation>
     </message>
+    <message>
+        <source>NEW_WINDOW_9</source>
+        <translation>Q&amp;t view</translation>
+    </message>
     <message>
         <source>CREATING_NEW_WINDOW</source>
         <translation>Create new %1</translation>
diff --git a/src/QtViewer/CMakeLists.txt b/src/QtViewer/CMakeLists.txt
new file mode 100644 (file)
index 0000000..413bc41
--- /dev/null
@@ -0,0 +1,111 @@
+# Copyright (C) 2012-2023  CEA, EDF, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+INCLUDE(UseQtExt)
+
+# --- options ---
+
+# additional include directories
+INCLUDE_DIRECTORIES(
+  ${QT_INCLUDES}
+  ${PROJECT_SOURCE_DIR}/src/Qtx
+  ${PROJECT_SOURCE_DIR}/src/SUIT
+  ${PROJECT_SOURCE_DIR}/src/ImageComposer
+)
+
+# additional preprocessor / compiler flags
+ADD_DEFINITIONS(${QT_DEFINITIONS})
+
+# libraries to link to
+SET(_link_LIBRARIES ${QT_LIBRARIES} qtx suit ImageComposer)
+
+# --- headers ---
+
+# header files / to be processed by moc
+SET(_moc_HEADERS   
+  QtViewer_Scene.h
+  QtViewer_Selector.h
+  QtViewer_ViewFrame.h
+  QtViewer_ViewManager.h
+  QtViewer_ViewPort.h
+  QtViewer_Viewer.h
+)
+
+# header files / no moc processing
+SET(_other_HEADERS
+  QtViewer.h
+  QtViewer_Object.h
+)
+
+# header files / to install
+SET(QtViewer_HEADERS ${_moc_HEADERS} ${_other_HEADERS})
+
+# --- resources ---
+
+# resource files / to be processed by lrelease
+SET(_ts_RESOURCES
+  resources/QtViewer_images.ts
+  resources/QtViewer_msg_en.ts
+  resources/QtViewer_msg_fr.ts
+  resources/QtViewer_msg_ja.ts
+)
+
+# resource files / static
+SET(_other_RESOURCES
+  resources/qtviewer_cursor_zoom.png
+  resources/qtviewer_dump.png
+  resources/qtviewer_fitall.png
+  resources/qtviewer_fitarea.png
+  resources/qtviewer_fitselect.png
+  resources/qtviewer_glpan.png
+  resources/qtviewer_pan.png
+  resources/qtviewer_reset.png
+  resources/qtviewer_rotate.png
+  resources/qtviewer_zoom.png
+)
+
+# --- sources ---
+
+# sources / moc wrappings
+QT_WRAP_MOC(_moc_SOURCES ${_moc_HEADERS})
+
+# sources / static
+SET(_other_SOURCES
+  QtViewer_Object.cxx
+  QtViewer_Scene.cxx
+  QtViewer_Selector.cxx
+  QtViewer_ViewFrame.cxx
+  QtViewer_ViewManager.cxx
+  QtViewer_ViewPort.cxx
+  QtViewer_Viewer.cxx
+)
+
+# sources / to compile
+SET(QtViewer_SOURCES ${_other_SOURCES} ${_moc_SOURCES})
+
+# --- rules ---
+
+ADD_LIBRARY(QtViewer ${QtViewer_SOURCES})
+TARGET_LINK_LIBRARIES(QtViewer ${_link_LIBRARIES})
+INSTALL(TARGETS QtViewer EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_LIBS})
+
+INSTALL(FILES ${QtViewer_HEADERS} DESTINATION ${SALOME_INSTALL_HEADERS})
+QT_INSTALL_TS_RESOURCES("${_ts_RESOURCES}" "${SALOME_GUI_INSTALL_RES_DATA}")
+
+INSTALL(FILES ${_other_RESOURCES} DESTINATION ${SALOME_GUI_INSTALL_RES_DATA})
diff --git a/src/QtViewer/QtViewer.h b/src/QtViewer/QtViewer.h
new file mode 100644 (file)
index 0000000..b605fd4
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright (C) 2013-2023  CEA, EDF, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifdef WIN32
+
+#if defined QTVIEWER_EXPORTS || defined QtViewer_EXPORTS
+#define QTVIEWER_API __declspec(dllexport)
+#else
+#define QTVIEWER_API __declspec(dllimport)
+#endif
+
+#else
+#define QTVIEWER_API
+#endif // WIN32
+
diff --git a/src/QtViewer/QtViewer_Object.cxx b/src/QtViewer/QtViewer_Object.cxx
new file mode 100644 (file)
index 0000000..18fb3a3
--- /dev/null
@@ -0,0 +1,37 @@
+// Copyright (C) 2013-2023  CEA, EDF, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "QtViewer_Object.h"
+
+//=======================================================================
+// Name    : QtViewer_Object
+// Purpose : Constructor
+//=======================================================================
+QtViewer_Object::QtViewer_Object( QGraphicsItem* theParent ) 
+: QGraphicsItem( theParent )
+{
+}
+
+//=======================================================================
+// Name    : QtViewer_Object
+// Purpose : Destructor
+//=======================================================================
+QtViewer_Object::~QtViewer_Object()
+{
+}
diff --git a/src/QtViewer/QtViewer_Object.h b/src/QtViewer/QtViewer_Object.h
new file mode 100644 (file)
index 0000000..7e69f1a
--- /dev/null
@@ -0,0 +1,48 @@
+// Copyright (C) 2013-2023  CEA, EDF, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef QTVIEWER_OBJECT_H
+#define QTVIEWER_OBJECT_H
+
+#include "QtViewer.h"
+#include <QGraphicsItem>
+
+class SUIT_DataOwner;
+/*
+  Class       : QtViewer_Object
+  Description : Base class for all objects displayed at the scene
+*/
+class QTVIEWER_API QtViewer_Object : public QGraphicsItem
+{
+public:
+  QtViewer_Object( QGraphicsItem* theParent = nullptr );
+  ~QtViewer_Object();
+
+  const QString& getName() const { return myName; }
+  virtual void setName( const QString& theName ) { myName = theName; }
+
+  SUIT_DataOwner* owner() const { return myOwner; }
+  void setOwner( SUIT_DataOwner* owner ) { myOwner = owner; }
+
+protected:
+  SUIT_DataOwner* myOwner;
+  QString myName;
+};
+
+#endif
diff --git a/src/QtViewer/QtViewer_Scene.cxx b/src/QtViewer/QtViewer_Scene.cxx
new file mode 100644 (file)
index 0000000..29675ff
--- /dev/null
@@ -0,0 +1,38 @@
+// Copyright (C) 2013-2023  CEA, EDF, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "QtViewer_Scene.h"
+
+//=======================================================================
+// Name    : QtViewer_Scene
+// Purpose : Constructor
+//=======================================================================
+QtViewer_Scene::QtViewer_Scene( QObject* theParent )
+: QGraphicsScene( theParent )
+{
+}
+
+//=======================================================================
+// Name    : QtViewer_Scene
+// Purpose : Destructor
+//=======================================================================
+QtViewer_Scene::~QtViewer_Scene()
+{
+}
+
diff --git a/src/QtViewer/QtViewer_Scene.h b/src/QtViewer/QtViewer_Scene.h
new file mode 100644 (file)
index 0000000..47c1702
--- /dev/null
@@ -0,0 +1,40 @@
+// Copyright (C) 2013-2023  CEA, EDF, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef QTVIEWER_SCENE_H
+#define QTVIEWER_SCENE_H
+
+#include "QtViewer.h"
+#include <QGraphicsScene>
+
+class QGraphicsRectItem;
+
+/*
+  Class       : QtViewer_Scene
+  Description : Scene of the graphics view
+*/
+class QTVIEWER_API QtViewer_Scene : public QGraphicsScene
+{
+  Q_OBJECT
+
+public:
+  QtViewer_Scene( QObject* theParent = 0 );
+  ~QtViewer_Scene();
+};
+#endif
diff --git a/src/QtViewer/QtViewer_Selector.cxx b/src/QtViewer/QtViewer_Selector.cxx
new file mode 100644 (file)
index 0000000..79aa12c
--- /dev/null
@@ -0,0 +1,48 @@
+// Copyright (C) 2013-2023  CEA, EDF, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "QtViewer_Selector.h"
+#include "QtViewer_Viewer.h"
+
+//=======================================================================
+// Name    : QtViewer_Selector
+// Purpose : Constructor
+//=======================================================================
+QtViewer_Selector::QtViewer_Selector(QtViewer_Viewer* theViewer)
+: QObject( nullptr ),
+  myViewer(theViewer)
+{   
+}
+
+//=======================================================================
+// Name    : QtViewer_Selector
+// Purpose : Destructor
+//=======================================================================
+QtViewer_Selector::~QtViewer_Selector()
+{
+}
+
+//================================================================
+// Function : select
+// Purpose  : 
+//================================================================
+void QtViewer_Selector::select( const QRectF& selRect)
+{
+  emit selSelectionDone();
+}
diff --git a/src/QtViewer/QtViewer_Selector.h b/src/QtViewer/QtViewer_Selector.h
new file mode 100644 (file)
index 0000000..7720b86
--- /dev/null
@@ -0,0 +1,53 @@
+// Copyright (C) 2013-2023  CEA, EDF, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef QTVIEWER_SELECTOR_H
+#define QTVIEWER_SELECTOR_H
+
+#include "QtViewer.h"
+
+#include <QObject>
+#include <QRectF>
+
+class QtViewer_Viewer;
+
+/*
+  Class       : QtViewer_Selector
+  Description : Selector of the graphics view
+*/
+class QTVIEWER_API QtViewer_Selector : public QObject
+{
+  Q_OBJECT
+
+public:
+  QtViewer_Selector(QtViewer_Viewer*);
+  ~QtViewer_Selector();
+
+public:
+
+  virtual void  select(const QRectF&);    
+
+signals:
+  void selSelectionDone();
+
+protected:
+  QtViewer_Viewer* myViewer;
+};
+
+#endif
diff --git a/src/QtViewer/QtViewer_ViewFrame.cxx b/src/QtViewer/QtViewer_ViewFrame.cxx
new file mode 100644 (file)
index 0000000..e06bda3
--- /dev/null
@@ -0,0 +1,451 @@
+// Copyright (C) 2013-2023  CEA, EDF, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "QtViewer_ViewFrame.h"
+
+#include "QtViewer_Viewer.h"
+#include "QtViewer_ViewPort.h"
+
+#include <QtxAction.h>
+#include <QtxActionToolMgr.h>
+#include <QtxMultiAction.h>
+#include <QtxToolBar.h>
+
+#include <SUIT_Desktop.h>
+#include <SUIT_MessageBox.h>
+#include <SUIT_Session.h>
+#include <SUIT_ResourceMgr.h>
+
+#include <QColor>
+#include <QFrame>
+#include <QFileDialog>
+
+#include <QWheelEvent>
+#include <QHBoxLayout>
+#include <QImage>
+#include <QMouseEvent>
+#include <QString>
+#include <QWheelEvent>
+
+//=======================================================================
+// Name    : QtViewer_ViewFrame
+// Purpose : Constructor
+//=======================================================================
+QtViewer_ViewFrame::QtViewer_ViewFrame( SUIT_Desktop* d, QtViewer_Viewer* vw, QWidget* w )
+: SUIT_ViewWindow( d ),
+  myViewer( vw ), myToolBarId( -1 )
+{
+  QFrame* aFrame = new QFrame( this );
+  setCentralWidget( aFrame );
+
+  QBoxLayout* aLayout = new QHBoxLayout( aFrame );
+  aLayout->setMargin( 0 );
+  aLayout->setSpacing( 0 );
+
+  if( w )
+    myViewPort = dynamic_cast<QtViewer_ViewPort*>(w);
+  else
+    myViewPort = new QtViewer_ViewPort( aFrame );
+
+  aLayout->addWidget( myViewPort );
+
+  connect( myViewPort, SIGNAL( vpKeyEvent( QKeyEvent* ) ),
+           this, SLOT( keyEvent( QKeyEvent* ) ) );
+  connect( myViewPort, SIGNAL( vpMouseEvent( QMouseEvent* ) ),
+           this, SLOT( mouseEvent( QMouseEvent* ) ) );
+  connect( myViewPort, SIGNAL( vpWheelEvent( QWheelEvent* ) ),
+           this, SLOT( wheelEvent( QWheelEvent* ) ) );
+  connect( myViewPort, SIGNAL( vpContextMenuEvent( QContextMenuEvent* ) ),
+           this, SLOT( contextMenuEvent( QContextMenuEvent* ) ) );
+}
+
+//=======================================================================
+// Name    : QtViewer_ViewFrame
+// Purpose : Destructor
+//=======================================================================
+QtViewer_ViewFrame::~QtViewer_ViewFrame()
+{
+}
+
+//================================================================
+// Function : createActions
+// Purpose  : 
+//================================================================
+void QtViewer_ViewFrame::createActions()
+{
+  SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
+  QtxAction* anAction;
+
+  // Dump view
+  anAction = new QtxAction( tr( "MNU_DUMP_VIEW" ),
+                           aResMgr->loadPixmap( "QtViewer", tr( "ICON_QTV_DUMP" ) ),
+                           tr( "MNU_DUMP_VIEW" ), 0, this );
+  anAction->setStatusTip( tr( "DSC_DUMP_VIEW" ) );
+  connect( anAction, SIGNAL( triggered( bool ) ), this, SLOT( onDumpView() ) );
+  toolMgr()->registerAction( anAction, DumpId );
+
+  // FitAll
+  anAction = new QtxAction( tr( "MNU_FITALL" ),
+                           aResMgr->loadPixmap( "QtViewer", tr( "ICON_QTV_FITALL" ) ),
+                           tr( "MNU_FITALL" ), 0, this );
+  anAction->setStatusTip( tr( "DSC_FITALL" ) );
+  connect( anAction, SIGNAL( triggered( bool ) ), this, SLOT( onViewFitAll() ) );
+  toolMgr()->registerAction( anAction, FitAllId );
+
+  // FitRect
+  anAction = new QtxAction( tr( "MNU_FITRECT" ),
+                           aResMgr->loadPixmap( "QtViewer", tr( "ICON_QTV_FITAREA" ) ),
+                           tr( "MNU_FITRECT" ), 0, this );
+  anAction->setStatusTip( tr( "DSC_FITRECT" ) );
+  connect( anAction, SIGNAL( triggered( bool ) ), this, SLOT( onViewFitArea() ) );
+  toolMgr()->registerAction( anAction, FitRectId );
+
+  // FitSelect
+  anAction = new QtxAction( tr( "MNU_FITSELECT" ),
+                           aResMgr->loadPixmap( "QtViewer", tr( "ICON_QTV_FITSELECT" ) ),
+                           tr( "MNU_FITSELECT" ), 0, this );
+  anAction->setStatusTip( tr( "DSC_FITSELECT" ) );
+  connect( anAction, SIGNAL( triggered( bool ) ), this, SLOT( onViewFitSelect() ) );
+  toolMgr()->registerAction( anAction, FitSelectId );
+
+  // Zoom
+  anAction = new QtxAction( tr( "MNU_ZOOM_VIEW" ),
+                           aResMgr->loadPixmap( "QtViewer", tr( "ICON_QTV_ZOOM" ) ),
+                           tr( "MNU_ZOOM_VIEW" ), 0, this );
+  anAction->setStatusTip( tr( "DSC_ZOOM_VIEW" ) );
+  connect( anAction, SIGNAL( triggered( bool ) ), this, SLOT( onViewZoom() ) );
+  toolMgr()->registerAction( anAction, ZoomId );
+
+  // Panning
+  anAction = new QtxAction( tr( "MNU_PAN_VIEW" ),
+                           aResMgr->loadPixmap( "QtViewer", tr( "ICON_QTV_PAN" ) ),
+                           tr( "MNU_PAN_VIEW" ), 0, this );
+  anAction->setStatusTip( tr( "DSC_PAN_VIEW" ) );
+  connect( anAction, SIGNAL( triggered( bool ) ), this, SLOT( onViewPan() ) );
+  toolMgr()->registerAction( anAction, PanId );
+
+  // Global Panning
+  anAction = new QtxAction( tr( "MNU_GLOBALPAN_VIEW" ),
+                           aResMgr->loadPixmap( "QtViewer", tr( "ICON_QTV_GLOBALPAN" ) ),
+                           tr( "MNU_GLOBALPAN_VIEW" ), 0, this );
+  anAction->setStatusTip( tr( "DSC_GLOBALPAN_VIEW" ) );
+  connect( anAction, SIGNAL( triggered( bool ) ), this, SLOT( onViewGlobalPan() ) );
+  toolMgr()->registerAction( anAction, GlobalPanId );
+}
+
+//================================================================
+// Function : createToolBar
+// Purpose  : 
+//================================================================
+int QtViewer_ViewFrame::createToolBar()
+{
+  int tid = toolMgr()->createToolBar( tr("LBL_TOOLBAR_LABEL"),                 // title (language-dependant)
+                                     QString( "QtViewerViewOperations" ), // name (language-independant)
+                                     false );                                 // disable floatable toolbar
+  toolMgr()->append( DumpId, tid );
+
+  QtxMultiAction* aScaleAction = new QtxMultiAction( this );
+  aScaleAction->insertAction( toolMgr()->action( FitAllId ) );
+  aScaleAction->insertAction( toolMgr()->action( FitRectId ) );
+  aScaleAction->insertAction( toolMgr()->action( FitSelectId ) );
+  aScaleAction->insertAction( toolMgr()->action( ZoomId ) );
+  toolMgr()->append( aScaleAction, tid );
+  myScaleAction = aScaleAction;
+
+  QtxMultiAction* aPanAction = new QtxMultiAction( this );
+  aPanAction->insertAction( toolMgr()->action( PanId ) );
+  aPanAction->insertAction( toolMgr()->action( GlobalPanId ) );
+  toolMgr()->append( aPanAction, tid );
+  myPanAction = aPanAction;
+
+  toolMgr()->append( toolMgr()->action( ResetId ), tid );
+
+  return tid;
+}
+
+//================================================================
+// Function : getToolBarId
+// Purpose  :
+//================================================================
+int QtViewer_ViewFrame::getToolBarId()
+{
+  return myToolBarId;
+}
+
+//================================================================
+// Function : dumpView
+// Purpose  : 
+//================================================================
+QImage QtViewer_ViewFrame::dumpView()
+{
+  return myViewPort->dumpView();
+}
+
+//================================================================
+// Function : dumpViewToFormat
+// Purpose  : 
+//================================================================
+bool QtViewer_ViewFrame::dumpViewToFormat( const QImage& image, const QString& fileName, const QString& format )
+{
+  bool isOK = myViewPort->dumpViewToFormat(fileName, format);
+  if( !isOK )
+    isOK = SUIT_ViewWindow::dumpViewToFormat( image, fileName, format );
+  return isOK;
+}
+
+//================================================================
+// Function : getVisualParameters
+// Purpose  : 
+//================================================================
+QString QtViewer_ViewFrame::getVisualParameters()
+{
+  QTransform aTransform = myViewPort->transform();
+
+  QString aString;
+  aString.asprintf( "%.3f*%.3f*%.3f*%.3f*%.3f*%.3f*%.3f*%.3f*%.3f",
+    aTransform.m11(), aTransform.m12(), aTransform.m13(),
+    aTransform.m21(), aTransform.m22(), aTransform.m23(),
+    aTransform.m31(), aTransform.m32(), aTransform.m33() );
+  return aString;
+}
+
+//================================================================
+// Function : setVisualParameters
+// Purpose  : 
+//================================================================
+void QtViewer_ViewFrame::setVisualParameters( const QString& theParameters )
+{
+  QStringList aList = theParameters.split( '*' );
+  if( aList.size() < 9 )
+    return;
+
+  bool anIsOk[9];
+  QTransform aTransform( aList[0].toDouble( &anIsOk[0] ),
+                         aList[1].toDouble( &anIsOk[1] ),
+                         aList[2].toDouble( &anIsOk[2] ),
+                         aList[3].toDouble( &anIsOk[3] ),
+                         aList[4].toDouble( &anIsOk[4] ),
+                         aList[5].toDouble( &anIsOk[5] ),
+                         aList[6].toDouble( &anIsOk[6] ),
+                         aList[7].toDouble( &anIsOk[7] ),
+                         aList[8].toDouble( &anIsOk[8] ) );
+  for( int i = 0; i < 9; i++ )
+    if( !anIsOk[ i ] )
+      return;
+
+  myViewPort->setTransform(aTransform);
+}
+
+//================================================================
+// Function : expandToolBarActions
+// Purpose  : 
+//================================================================
+void QtViewer_ViewFrame::expandToolBarActions()
+{
+  QList<QAction*> anExpandableActions;
+  anExpandableActions.append( myScaleAction );
+  anExpandableActions.append( myPanAction );
+
+  QListIterator<QAction*> anIter( anExpandableActions );
+  while( anIter.hasNext() )
+  {
+    QtxMultiAction* aMultiAction = dynamic_cast<QtxMultiAction*>( anIter.next() );
+    if( aMultiAction )
+    {
+      QList<QAction*> aLocalActions = aMultiAction->actions();
+      QListIterator<QAction*> aLocalIter( aLocalActions );
+      while( aLocalIter.hasNext() )
+        if( QAction* anAction = aLocalIter.next() )
+          toolMgr()->append( anAction, myToolBarId );
+
+      int anId = toolMgr()->actionId( aMultiAction );
+      toolMgr()->remove( anId, myToolBarId );
+    }
+  }
+}
+
+//================================================================
+// Function : onViewPan
+// Purpose  : 
+//================================================================
+void QtViewer_ViewFrame::onViewPan()
+{
+  myViewer->pan();
+}
+
+//================================================================
+// Function : onViewZoom
+// Purpose  : 
+//================================================================
+void QtViewer_ViewFrame::onViewZoom()
+{
+  myViewer->zoom();
+}
+
+//================================================================
+// Function : onViewFitAll
+// Purpose  : 
+//================================================================
+void QtViewer_ViewFrame::onViewFitAll()
+{
+    myViewer->fitAll();
+}
+
+//================================================================
+// Function : onViewFitArea
+// Purpose  : 
+//================================================================
+void QtViewer_ViewFrame::onViewFitArea()
+{
+    myViewer->fitArea();
+}
+
+//================================================================
+// Function : onViewFitSelect
+// Purpose  : 
+//================================================================
+void QtViewer_ViewFrame::onViewFitSelect()
+{
+    myViewer->fitSelect();
+}
+
+//================================================================
+// Function : onViewGlobalPan
+// Purpose  : 
+//================================================================
+void QtViewer_ViewFrame::onViewGlobalPan()
+{
+  myViewer->globalPan();
+}
+
+//================================================================
+// Function : onViewReset
+// Purpose  : 
+//================================================================
+void QtViewer_ViewFrame::onViewReset()
+{
+}
+
+//================================================================
+// Function : keyEvent
+// Purpose  : 
+//================================================================
+void QtViewer_ViewFrame::keyEvent( QKeyEvent* e )
+{
+  switch ( e->type() )
+  {
+    case QEvent::KeyPress:
+      emit keyPressed( e );
+      break;
+    case QEvent::KeyRelease:
+      emit keyReleased( e );
+      break;
+    default:
+      break;
+  }
+}
+
+//================================================================
+// Function : mouseEvent
+// Purpose  : 
+//================================================================
+void QtViewer_ViewFrame::mouseEvent( QMouseEvent* e )
+{
+  switch ( e->type() )
+  {
+    case QEvent::MouseButtonPress:
+      emit mousePressed( e );
+      break;
+    case QEvent::MouseMove:
+      emit mouseMoving( e );
+      break;
+    case QEvent::MouseButtonRelease:
+      emit mouseReleased( e );
+      break;
+    case QEvent::MouseButtonDblClick:
+      emit mouseDoubleClicked( e );
+      break;
+    default:
+      break;
+  }
+}
+//================================================================
+// Function : wheelEvent
+// Purpose  : 
+//================================================================
+void QtViewer_ViewFrame::wheelEvent( QWheelEvent* e )
+{
+  switch ( e->type() )
+  {
+    case QEvent::Wheel:
+      emit wheeling( e );
+      break;
+    default:
+      break;
+  }
+}
+
+//================================================================
+// Function : contextMenuEvent
+// Purpose  : 
+//================================================================
+void QtViewer_ViewFrame::contextMenuEvent( QContextMenuEvent* e )
+{
+  emit contextMenuRequested(e);
+}
+
+/*!
+  \brief Handle show event.
+
+  Emits Show() signal.
+
+  \param theEvent show event
+*/
+void QtViewer_ViewFrame::showEvent( QShowEvent* theEvent )
+{
+  if( myToolBarId < 0 )
+  {
+    createActions();
+    myToolBarId = createToolBar();
+  }
+
+  emit Show( theEvent );
+}
+
+/*!
+  \brief Handle hide event.
+
+  Emits Hide() signal.
+
+  \param theEvent hide event
+*/
+void QtViewer_ViewFrame::hideEvent( QHideEvent* theEvent )
+{
+  emit Hide( theEvent );
+}
+
+/*!
+  \return filters for image files
+*/
+QString QtViewer_ViewFrame::filter() const
+{
+  QStringList filters = SUIT_ViewWindow::filter().split( ";;", Qt::SkipEmptyParts );
+  filters << tr("POSTSCRIPT_FILES");
+  return filters.join( ";;" );
+}
diff --git a/src/QtViewer/QtViewer_ViewFrame.h b/src/QtViewer/QtViewer_ViewFrame.h
new file mode 100644 (file)
index 0000000..a59694a
--- /dev/null
@@ -0,0 +1,111 @@
+// Copyright (C) 2013-2023  CEA, EDF, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef QTVIEWER_VIEWFRAME_H
+#define QTVIEWER_VIEWFRAME_H
+
+#include "QtViewer.h"
+
+#include <SUIT_ViewWindow.h>
+#include <QPainterPath>
+
+class QContextMenuEvent;
+
+class QAction;
+
+class SUIT_Desktop;
+
+class QtViewer_Viewer;
+class QtViewer_ViewPort;
+
+/*
+  Class       : QtViewer_ViewFrame
+  Description : View frame of the graphics view
+*/
+class QTVIEWER_API QtViewer_ViewFrame : public SUIT_ViewWindow
+{
+  Q_OBJECT
+
+public:
+  enum { DumpId, FitAllId, FitRectId, FitSelectId, ZoomId, PanId, GlobalPanId, ResetId };
+
+public:
+  QtViewer_ViewFrame( SUIT_Desktop*, QtViewer_Viewer*, QWidget* w = nullptr );
+  ~QtViewer_ViewFrame();
+
+  QtViewer_Viewer*    getViewer() const { return myViewer; }
+  QtViewer_ViewPort*  getViewPort() const  { return myViewPort; }
+
+  virtual QImage          dumpView();
+  
+  virtual QString         getVisualParameters();
+  virtual void            setVisualParameters( const QString& theParameters );
+
+  virtual void            expandToolBarActions();
+  int                     getToolBarId();
+
+public slots:
+  virtual void showEvent( QShowEvent* );
+  virtual void hideEvent( QHideEvent* );
+
+protected slots:
+  void                    onViewPan();
+  void                    onViewZoom();
+  void                    onViewFitAll();
+  void                    onViewFitArea();
+  void                    onViewFitSelect();
+  void                    onViewGlobalPan();
+  void                    onViewReset();
+
+private slots:
+  void                    keyEvent( QKeyEvent* );
+  void                    mouseEvent( QMouseEvent* );
+  void                    wheelEvent( QWheelEvent* );
+  void                    contextMenuEvent( QContextMenuEvent* );
+
+signals:
+  void                    keyPressed( QKeyEvent* );
+  void                    keyReleased( QKeyEvent* );
+  void                    mousePressed( QMouseEvent* );
+  void                    mouseMoving( QMouseEvent* );
+  void                    mouseReleased( QMouseEvent* );
+  void                    mouseDoubleClicked( QMouseEvent* );
+  void                    wheeling( QWheelEvent* );
+
+  void                    sketchingFinished( QPainterPath );
+
+  void Show( QShowEvent* );
+  void Hide( QHideEvent* );
+
+protected:
+  virtual void            createActions();
+  virtual int             createToolBar();
+  virtual QString         filter() const;
+  virtual bool            dumpViewToFormat( const QImage&, const QString& fileName, const QString& format );
+
+private:
+  QtViewer_Viewer*    myViewer;
+  QtViewer_ViewPort*  myViewPort;
+
+  int                     myToolBarId;
+  QAction*                myScaleAction;
+  QAction*                myPanAction;
+};
+
+#endif
diff --git a/src/QtViewer/QtViewer_ViewManager.cxx b/src/QtViewer/QtViewer_ViewManager.cxx
new file mode 100644 (file)
index 0000000..bd5c0dd
--- /dev/null
@@ -0,0 +1,51 @@
+// Copyright (C) 2013-2023  CEA, EDF, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "QtViewer_ViewManager.h"
+#include "QtViewer_Viewer.h"
+
+//=======================================================================
+// Name    : QtViewer_ViewManager
+// Purpose : Constructor
+//=======================================================================
+QtViewer_ViewManager::QtViewer_ViewManager( SUIT_Study* theStudy,
+                                                    SUIT_Desktop* theDesktop,
+                                                    SUIT_ViewModel* theModel )
+: SUIT_ViewManager( theStudy, theDesktop, 
+    theModel ? theModel : new QtViewer_Viewer("QtViewer") )
+{
+  setTitle( tr( "QTVIEWER_TITLE" ) );
+}
+
+//=======================================================================
+// Name    : QtViewer_ViewManager
+// Purpose : Destructor
+//=======================================================================
+QtViewer_ViewManager::~QtViewer_ViewManager()
+{
+}
+
+//================================================================
+// Function : getViewer
+// Purpose  : 
+//================================================================
+QtViewer_Viewer* QtViewer_ViewManager::getViewer()
+{
+  return dynamic_cast<QtViewer_Viewer*>( getViewModel() );
+}
diff --git a/src/QtViewer/QtViewer_ViewManager.h b/src/QtViewer/QtViewer_ViewManager.h
new file mode 100644 (file)
index 0000000..b7cd022
--- /dev/null
@@ -0,0 +1,44 @@
+// Copyright (C) 2013-2023  CEA, EDF, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef QTVIEWER_VIEWMANAGER_H
+#define QTVIEWER_VIEWMANAGER_H
+
+#include "QtViewer.h"
+#include <SUIT_ViewManager.h>
+
+class QtViewer_Viewer;
+
+/*
+  Class       : QtViewer_ViewManager
+  Description : View manager of the graphics view
+*/
+class QTVIEWER_API QtViewer_ViewManager : public SUIT_ViewManager
+{
+  Q_OBJECT
+
+public:
+  QtViewer_ViewManager( SUIT_Study* theStudy,
+                            SUIT_Desktop* theDesktop,
+                            SUIT_ViewModel* theModel = 0 );
+  virtual ~QtViewer_ViewManager();
+
+  QtViewer_Viewer* getViewer();
+};
+#endif
diff --git a/src/QtViewer/QtViewer_ViewPort.cxx b/src/QtViewer/QtViewer_ViewPort.cxx
new file mode 100644 (file)
index 0000000..56cac94
--- /dev/null
@@ -0,0 +1,372 @@
+// Copyright (C) 2013-2023  CEA, EDF, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "QtViewer_ViewPort.h"
+#include "QtViewer_Scene.h"
+#include <QGraphicsItem>
+#include <QRubberBand>
+#include <QMouseEvent>
+#include <QCursor>
+#include <QScrollBar>
+#include <QPainter>
+#include <QPrinter>
+
+#include "SUIT_ResourceMgr.h"
+#include "SUIT_Session.h"
+
+//=======================================================================
+// Name    : QtViewer_ViewPort
+// Purpose : Constructor
+//=======================================================================
+QtViewer_ViewPort::QtViewer_ViewPort( QWidget* theParent )
+: QGraphicsView( theParent )
+{
+  setScene(new QtViewer_Scene(this));
+
+  setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+  setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+
+  setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
+  
+  setMouseTracking( true );
+  setFocusPolicy( Qt::StrongFocus );
+
+  myFitAllGap = 40;
+
+  myRectBand = nullptr;
+  myRectBandStart = QPoint();
+  myRectBandEnd = QPoint();
+  fittingArea = false;
+
+  zooming = false;
+  previousPos = QPoint();
+
+  panning = false;
+  globalPanning = false;
+  
+  SUIT_ResourceMgr* rmgr = SUIT_Session::session()->resourceMgr();
+  zoomCursor = new QCursor( rmgr->loadPixmap( "QtViewer", tr( "ICON_QTV_CURSOR_ZOOM" ) ) );
+}
+
+//=======================================================================
+// Name    : QtViewer_ViewPort
+// Purpose : Destructor
+//=======================================================================
+QtViewer_ViewPort::~QtViewer_ViewPort()
+{
+  delete zoomCursor;
+  zoomCursor = nullptr;
+}
+
+void QtViewer_ViewPort::addItem( QGraphicsItem* theItem )
+{
+  scene()->addItem(theItem);
+}
+
+void QtViewer_ViewPort::fitAll()
+{
+  scene()->setSceneRect(scene()->itemsBoundingRect());
+  QRectF aRect = scene()->sceneRect();
+  fitInView( aRect.adjusted(-myFitAllGap, -myFitAllGap, myFitAllGap, myFitAllGap), Qt::KeepAspectRatio);
+}
+
+void QtViewer_ViewPort::fitSelect() 
+{
+  if (scene()->selectedItems().isEmpty())
+      return;
+
+  QRectF selectionRect;
+  foreach (QGraphicsItem *item, scene()->selectedItems()) 
+    selectionRect = selectionRect.united(item->sceneBoundingRect());
+
+  if(!selectionRect.isNull())
+    fitInView(selectionRect.adjusted(-myFitAllGap, -myFitAllGap, myFitAllGap, myFitAllGap), Qt::KeepAspectRatio); 
+}
+
+void QtViewer_ViewPort::fitRect(const QRectF& theRect)
+{
+  fitInView(theRect, Qt::KeepAspectRatio);
+}
+
+QRect QtViewer_ViewPort::selectionRect()
+{
+  if (myRectBand)
+    {
+      QRect aRect;
+      aRect.setLeft(qMin( myRectBandStart.x(), myRectBandEnd.x()));
+      aRect.setTop(qMin( myRectBandStart.y(), myRectBandEnd.y()));
+      aRect.setRight(qMax( myRectBandStart.x(), myRectBandEnd.x()));
+      aRect.setBottom(qMax( myRectBandStart.y(), myRectBandEnd.y()));
+      return aRect;
+    }
+  return QRect();
+}
+
+void QtViewer_ViewPort::startDrawingRect( int x, int y )
+{
+  myRectBandStart = QPoint(x,y);
+
+  if (!myRectBand) 
+    {
+      myRectBand = new QRubberBand(QRubberBand::Rectangle, this);
+      myRectBand->setGeometry(QRect(myRectBandStart, QSize()));
+      myRectBand->show();
+    }
+}
+
+void QtViewer_ViewPort::drawingRect( int x, int y )
+{
+  myRectBandEnd = QPoint(x,y);
+  myRectBand->setGeometry(QRect(myRectBandStart, myRectBandEnd).normalized());
+}
+
+void QtViewer_ViewPort::finishDrawingRect()
+{
+  myRectBand->hide();
+
+  QRectF selectionRect = mapToScene(myRectBand->geometry()).boundingRect();
+
+  if (fittingArea)
+    fitInView(selectionRect, Qt::KeepAspectRatio);
+  else
+    {
+      QList<QGraphicsItem *> selectedItems = scene()->items(selectionRect, Qt::IntersectsItemShape);
+      for (QGraphicsItem *item : selectedItems) 
+        item->setSelected(true);
+    }
+  
+  myRectBandStart = QPoint();
+  myRectBandEnd = QPoint();
+  delete myRectBand;
+  myRectBand = nullptr;
+}
+
+void QtViewer_ViewPort::updateSceneRect(const QRectF &rect)
+{
+}
+
+void QtViewer_ViewPort::mousePressEvent(QMouseEvent *event)
+{ 
+  if (!zooming && !panning && !globalPanning && items(event->pos()).count()==0 && (event->buttons() & Qt::LeftButton))
+    {
+      startDrawingRect(event->pos().x(), event->pos().y());
+    }
+
+  if (globalPanning)
+    {
+      QPoint p0 = viewport()->rect().center();
+      QPoint p1 = event->pos();
+      double deltaX = p0.x() - p1.x();
+      double deltaY = p0.y() - p1.y();
+
+      pan(deltaX, -deltaY);
+    }
+  QGraphicsView::mousePressEvent(event);
+  emit vpMouseEvent(event);
+}
+
+
+void QtViewer_ViewPort::mouseMoveEvent(QMouseEvent *event)
+{    
+  if ((event->modifiers() & Qt::ShiftModifier) && (event->buttons() & Qt::LeftButton))
+    activateZoomAction();
+
+  if (event->buttons() & Qt::MiddleButton)
+    activatePanAction();
+    
+  if (panning && event->buttons() & (Qt::LeftButton | Qt::MiddleButton))
+    {
+    QPoint currentPos = event->pos();
+
+    if (!previousPos.isNull())
+    {
+      double deltaX = currentPos.x() - previousPos.x();
+      double deltaY = currentPos.y() - previousPos.y();
+
+      pan(deltaX, -deltaY);
+
+    }
+    previousPos = currentPos;  
+
+    }
+  else if (zooming && (event->buttons() & Qt::LeftButton))
+  {
+    QPoint currentPos = event->pos();
+    if (!previousPos.isNull())
+    {
+      int deltaX = currentPos.x() - previousPos.x();
+      double scaleFactor = deltaX>0 ? 1.1 : 0.9;
+      scale(scaleFactor, scaleFactor);
+    }
+    previousPos = currentPos;
+  }
+  else if (myRectBand)
+    drawingRect(event->pos().x(), event->pos().y());
+
+  QGraphicsView::mouseMoveEvent(event);
+  emit vpMouseEvent(event);
+}
+
+void QtViewer_ViewPort::mouseReleaseEvent(QMouseEvent *event)
+{
+  if (myRectBand)
+    finishDrawingRect(); 
+
+  clearActions();
+  QGraphicsView::mouseReleaseEvent(event);
+  emit vpMouseEvent(event);
+}
+
+void QtViewer_ViewPort::resizeEvent(QResizeEvent *event)
+{
+  QSize oldSize = event->oldSize();
+  QSize newSize = event->size();
+
+  qreal w = static_cast<qreal>(newSize.width());
+  qreal h = static_cast<qreal>(newSize.height());
+
+  qreal w0 = static_cast<qreal>(oldSize.width());
+  qreal h0 = static_cast<qreal>(oldSize.height());
+
+  qreal widthRatio = w/w0;
+  qreal heightRatio = h/h0;
+   
+  if (widthRatio>0 && heightRatio>0)
+    {
+      qreal scaleFactor = w<h ? widthRatio : heightRatio;
+      scale(scaleFactor, scaleFactor);
+    }
+
+  QGraphicsView::resizeEvent(event);
+}
+
+void QtViewer_ViewPort::wheelEvent(QWheelEvent *event)
+{
+  int delta = event->angleDelta().y();
+  double scaleFactor = delta>0 ? 1.1 : 0.9;
+  scale(scaleFactor, scaleFactor);
+}
+
+void QtViewer_ViewPort::keyPressEvent(QKeyEvent *event)
+{
+  if (event->key() == Qt::Key_Escape)
+    clearActions();
+
+  QGraphicsView::keyPressEvent(event);
+}
+
+void QtViewer_ViewPort::clearActions()
+{
+  setCursor(Qt::ArrowCursor);
+  fittingArea = false;
+  zooming = false;
+  panning  = false;
+  globalPanning = false;
+  previousPos = QPoint();
+}
+  
+void QtViewer_ViewPort::activateZoomAction() 
+{ 
+  zooming = true;
+  fittingArea = false;
+  panning  = false;
+  globalPanning = false;
+  setCursor(*zoomCursor); 
+}
+
+void QtViewer_ViewPort::activateFitAreaAction() 
+{ 
+  fittingArea = true;
+  zooming = false;
+  panning  = false;
+  globalPanning = false;
+  setCursor(Qt::PointingHandCursor);
+}
+
+void QtViewer_ViewPort::activatePanAction() 
+{
+  panning = true; 
+  fittingArea = false;
+  zooming = false;
+  globalPanning = false;
+  setCursor(Qt::SizeAllCursor);
+}
+
+void QtViewer_ViewPort::activateGlobalPanAction() 
+{
+  globalPanning = true;
+  panning = false; 
+  fittingArea = false;
+  zooming = false;
+  setCursor(Qt::CrossCursor);
+}
+
+void QtViewer_ViewPort::pan( double theDX, double theDY )
+{
+  if( QScrollBar* aHBar = horizontalScrollBar() )
+  {
+      int aNewValue = aHBar->value() - theDX;
+      if( aNewValue < aHBar->minimum() )
+        aHBar->setMinimum( aNewValue );
+      if( aNewValue > aHBar->maximum() )
+        aHBar->setMaximum( aNewValue );
+    
+      aHBar->setValue( aHBar->value() - theDX );
+  }
+  if( QScrollBar* aVBar = verticalScrollBar() )
+  {
+      int aNewValue = aVBar->value() + theDY;
+      if( aNewValue < aVBar->minimum() )
+        aVBar->setMinimum( aNewValue );
+      if( aNewValue > aVBar->maximum() )
+        aVBar->setMaximum( aNewValue );
+    aVBar->setValue( aVBar->value() + theDY );
+  }
+}
+
+//================================================================
+// Function : dumpView
+// Purpose  : 
+//================================================================
+QImage QtViewer_ViewPort::dumpView( bool theWholeScene,
+                                        QSizeF theSize )
+{
+   QPixmap screenshot = viewport()->grab();
+   return screenshot.toImage();
+}
+
+bool QtViewer_ViewPort::dumpViewToFormat(const QString& fileName, const QString& format)
+{
+  if( format!="PS" && format!="EPS" )
+    return false;
+
+  QPrinter printer(QPrinter::ScreenResolution);
+  printer.setOutputFormat(QPrinter::NativeFormat); 
+  printer.setOutputFileName(fileName); 
+
+  QPainter painter;
+  if (!painter.begin(&printer))
+    return false;
+
+  render(&painter);
+  if (!painter.end())
+    return false;
+
+  return true;
+} 
diff --git a/src/QtViewer/QtViewer_ViewPort.h b/src/QtViewer/QtViewer_ViewPort.h
new file mode 100644 (file)
index 0000000..b7ddd15
--- /dev/null
@@ -0,0 +1,95 @@
+// Copyright (C) 2013-2023  CEA, EDF, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef QTVIEWER_VIEWPORT_H
+#define QTVIEWER_VIEWPORT_H
+
+#include "QtViewer.h"
+#include <QGraphicsView>
+
+class QRubberBand;
+
+/*
+  Class       : QtViewer_ViewPort
+  Description : View port of the graphics view
+*/
+class QTVIEWER_API QtViewer_ViewPort : public QGraphicsView
+{
+  Q_OBJECT
+
+public:
+  QtViewer_ViewPort(QWidget* theParent);
+  ~QtViewer_ViewPort();
+
+  void addItem(QGraphicsItem* theItem);
+
+  void fitAll();
+  void fitSelect();
+  void fitRect(const QRectF& theRect);
+  void pan(double theDX, double theDY);
+
+  // rectangle selection
+  void startDrawingRect(int x, int y);
+  void drawingRect(int x, int y);
+  void finishDrawingRect();
+  QRect selectionRect();
+
+  void activateZoomAction();
+  void activateFitAreaAction(); 
+  void activatePanAction(); 
+  void activateGlobalPanAction();
+
+  QImage dumpView(bool theWholeScene = false, QSizeF theSize = QSizeF());
+  bool dumpViewToFormat(const QString& fileName, const QString& format);
+
+
+signals:
+  void vpMouseEvent(QMouseEvent*);
+
+
+public slots:
+   virtual void updateSceneRect(const QRectF &rect);
+
+protected:
+
+  virtual void mousePressEvent(QMouseEvent *event);
+  virtual void mouseMoveEvent(QMouseEvent *event);
+  virtual void mouseReleaseEvent(QMouseEvent *event);
+  virtual void resizeEvent(QResizeEvent *event);
+  virtual void wheelEvent(QWheelEvent *event);
+  virtual void keyPressEvent(QKeyEvent *event);
+
+  void clearActions();
+private:
+
+  double myFitAllGap;
+  QRubberBand* myRectBand;
+  QPoint myRectBandStart;
+  QPoint myRectBandEnd;
+
+  bool fittingArea;
+  bool zooming;
+  bool panning;
+  bool globalPanning;
+  QPoint previousPos;
+  QCursor* zoomCursor;
+};
+
+#endif
diff --git a/src/QtViewer/QtViewer_Viewer.cxx b/src/QtViewer/QtViewer_Viewer.cxx
new file mode 100644 (file)
index 0000000..bf5db2e
--- /dev/null
@@ -0,0 +1,336 @@
+// Copyright (C) 2013-2023  CEA, EDF, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "QtViewer_Viewer.h"
+
+#include "QtViewer_Selector.h"
+#include "QtViewer_Scene.h"
+#include "QtViewer_ViewFrame.h"
+#include "QtViewer_ViewPort.h"
+
+#include <SUIT_ViewManager.h>
+
+#include <QColorDialog>
+#include <QWheelEvent>
+#include <QKeyEvent>
+#include <QMenu>
+
+
+//=======================================================================
+// Name    : QtViewer_Viewer
+// Purpose : Constructor
+//=======================================================================
+QtViewer_Viewer::QtViewer_Viewer( const QString& /*title*/, QWidget* widget )
+: SUIT_ViewModel(),
+  mySelector( 0 ),
+  myWidget( widget )
+{
+}
+
+//=======================================================================
+// Name    : QtViewer_Viewer
+// Purpose : Destructor
+//=======================================================================
+QtViewer_Viewer::~QtViewer_Viewer()
+{
+  delete mySelector;
+}
+
+QtViewer_ViewFrame* QtViewer_Viewer::createViewFrame( SUIT_Desktop* theDesktop, QWidget* theWidget )
+{
+  return new QtViewer_ViewFrame( theDesktop, this, theWidget );
+}
+
+//================================================================
+// Function : createView
+// Purpose  : 
+//================================================================
+SUIT_ViewWindow* QtViewer_Viewer::createView( SUIT_Desktop* theDesktop )
+{
+  QtViewer_ViewFrame* aViewFrame = createViewFrame( theDesktop, myWidget );
+
+  connect( aViewFrame, SIGNAL( keyPressed( QKeyEvent* ) ),
+           this, SLOT( onKeyEvent( QKeyEvent* ) ) );
+
+  connect( aViewFrame, SIGNAL( keyReleased( QKeyEvent* ) ),
+           this, SLOT( onKeyEvent( QKeyEvent* ) ) );
+
+  connect( aViewFrame, SIGNAL( mousePressed( QMouseEvent* ) ),
+           this, SLOT( onMouseEvent( QMouseEvent* ) ) );
+
+  connect( aViewFrame, SIGNAL( mouseMoving( QMouseEvent* ) ),
+           this, SLOT( onMouseEvent( QMouseEvent* ) ) );
+
+  connect( aViewFrame, SIGNAL( mouseReleased( QMouseEvent* ) ),
+           this, SLOT( onMouseEvent( QMouseEvent* ) ) );
+  return aViewFrame;
+}
+
+//================================================================
+// Function : contextMenuPopup
+// Purpose  : 
+//================================================================
+void QtViewer_Viewer::contextMenuPopup( QMenu* thePopup )
+{
+  if( thePopup->actions().count() > 0 )
+    thePopup->addSeparator();
+
+  thePopup->addAction(tr("CHANGE_BGCOLOR"), this, SLOT(onChangeBgColor()));
+}
+
+//================================================================
+// Function : getSelector
+// Purpose  : 
+//================================================================
+QtViewer_Selector* QtViewer_Viewer::getSelector()
+{
+  if( !mySelector )
+  {
+    mySelector = new QtViewer_Selector( this );
+    if( mySelector )
+      connect( mySelector, SIGNAL(selSelectionDone()), this, SLOT( onSelectionDone()));
+  }
+  return mySelector;
+}
+
+//================================================================
+// Function : getActiveView
+// Purpose  : 
+//================================================================
+QtViewer_ViewFrame* QtViewer_Viewer::getActiveView() const
+{
+  if( SUIT_ViewManager* aViewManager = getViewManager() )
+    return dynamic_cast<QtViewer_ViewFrame*>( aViewManager->getActiveView() );
+  return nullptr;
+}
+
+//================================================================
+// Function : getActiveViewPort
+// Purpose  : 
+//================================================================
+QtViewer_ViewPort* QtViewer_Viewer::getActiveViewPort() const
+{
+  if( QtViewer_ViewFrame* aViewFrame = getActiveView() )
+    return aViewFrame->getViewPort();
+  return nullptr;
+}
+
+//================================================================
+// Function : getActiveScene
+// Purpose  : 
+//================================================================
+QtViewer_Scene* QtViewer_Viewer::getActiveScene() const
+{
+  if( QtViewer_ViewPort* aViewPort = getActiveViewPort() )
+    return dynamic_cast<QtViewer_Scene*>( aViewPort->scene() );
+  return nullptr;
+}
+
+//================================================================
+// Function : onKeyEvent
+// Purpose  : 
+//================================================================
+void QtViewer_Viewer::onKeyEvent( QKeyEvent* e )
+{
+  switch( e->type() )
+  {
+    case QEvent::KeyPress:
+      handleKeyPress( e );
+      break;
+    case QEvent::KeyRelease:
+      handleKeyRelease( e );
+      break;
+    default: break;
+  }
+}
+
+//================================================================
+// Function : onMouseEvent
+// Purpose  : 
+//================================================================
+void QtViewer_Viewer::onMouseEvent(QMouseEvent* e)
+{
+  switch( e->type() )
+  {
+    case QEvent::MouseButtonPress:
+      handleMousePress(e);
+      break;
+    case QEvent::MouseMove:
+      handleMouseMove(e);
+      break;
+    case QEvent::MouseButtonRelease:
+      handleMouseRelease(e);
+      break;
+    default: break;
+  }
+}
+//================================================================
+// Function : onWheelEvent
+// Purpose  : 
+//================================================================
+void QtViewer_Viewer::onWheelEvent(QWheelEvent* e)
+{
+  switch(e->type())
+  {
+    case QEvent::Wheel:
+      handleWheel(e);
+      break;
+    default: break;
+  }
+}
+
+//================================================================
+// Function : handleKeyPress
+// Purpose  : 
+//================================================================
+void QtViewer_Viewer::handleKeyPress( QKeyEvent* e )
+{ 
+  Q_UNUSED(e);
+}
+
+//================================================================
+// Function : handleKeyRelease
+// Purpose  : 
+//================================================================
+void QtViewer_Viewer::handleKeyRelease(QKeyEvent* e)
+{
+  Q_UNUSED(e);
+}
+
+//================================================================
+// Function : handleMousePress
+// Purpose  : 
+//================================================================
+void QtViewer_Viewer::handleMousePress(QMouseEvent* e)
+{
+  Q_UNUSED(e);
+}
+
+void QtViewer_Viewer::handleWheel(QWheelEvent* e)
+{
+  Q_UNUSED(e);
+}
+
+//================================================================
+// Function : handleMouseMove
+// Purpose  : 
+//================================================================
+void QtViewer_Viewer::handleMouseMove(QMouseEvent* e)
+{
+  Q_UNUSED(e);
+}
+
+//================================================================
+// Function : handleMouseRelease
+// Purpose  : 
+//================================================================
+void QtViewer_Viewer::handleMouseRelease(QMouseEvent* e)
+{
+  QtViewer_ViewPort* aViewPort = getActiveViewPort();
+  if ( getSelector() )
+    getSelector()->select(aViewPort->selectionRect());
+}
+
+//================================================================
+// Function : onChangeBgColor
+// Purpose  : 
+//================================================================
+
+void QtViewer_Viewer::onChangeBgColor()
+{
+  if( QtViewer_ViewPort* aViewPort = getActiveViewPort() )
+  {
+    QColor aColor = QColorDialog::getColor( aColor, aViewPort );
+
+    if (aColor.isValid())
+      aViewPort->setBackgroundBrush(QBrush(aColor));
+ }
+}
+
+//================================================================
+// Function : onSelectionDone
+// Purpose  : 
+//================================================================
+void QtViewer_Viewer::onSelectionDone()
+{
+  emit selectionChanged();
+}
+
+//================================================================
+// Function : fitAll 
+// Purpose  : 
+//================================================================
+void QtViewer_Viewer::fitAll()
+{
+  if (QtViewer_ViewPort* aViewPort = getActiveViewPort())
+    aViewPort->fitAll();
+}
+
+//================================================================
+// Function : fitSelect
+// Purpose  : 
+//================================================================
+void QtViewer_Viewer::fitSelect()
+{
+  if (QtViewer_ViewPort* aViewPort = getActiveViewPort())
+    aViewPort->fitSelect();
+}
+
+//================================================================
+// Function : fitArea
+// Purpose  : 
+//================================================================
+void QtViewer_Viewer::fitArea()
+{
+  if (QtViewer_ViewPort* aViewPort = getActiveViewPort())
+    aViewPort->activateFitAreaAction();
+}
+
+//================================================================
+// Function : zoom
+// Purpose  : 
+//================================================================
+void QtViewer_Viewer::zoom()
+{
+  if (QtViewer_ViewPort* aViewPort = getActiveViewPort())
+    aViewPort->activateZoomAction();
+}
+
+//================================================================
+// Function : pan 
+// Purpose  : 
+//================================================================
+void QtViewer_Viewer::pan()
+{
+  if (QtViewer_ViewPort* aViewPort = getActiveViewPort())
+    aViewPort->activatePanAction();
+}
+
+//================================================================
+// Function : globalPan 
+// Purpose  : 
+//================================================================
+void QtViewer_Viewer::globalPan()
+{
+  if (QtViewer_ViewPort* aViewPort = getActiveViewPort())
+    {
+      aViewPort->fitAll();
+      aViewPort->activateGlobalPanAction();
+    }
+}
diff --git a/src/QtViewer/QtViewer_Viewer.h b/src/QtViewer/QtViewer_Viewer.h
new file mode 100644 (file)
index 0000000..71c41a4
--- /dev/null
@@ -0,0 +1,99 @@
+// Copyright (C) 2013-2023  CEA, EDF, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef QTVIEWER_VIEWER_H
+#define QTVIEWER_VIEWER_H
+
+#include "QtViewer.h"
+#include <SUIT_ViewModel.h>
+
+class QKeyEvent;
+class QMouseEvent;
+class QWheelEvent;
+
+class SUIT_ViewWindow;
+
+class QtViewer_Selector;
+class QtViewer_Scene;
+class QtViewer_ViewFrame;
+class QtViewer_ViewPort;
+
+/*
+  Class       : QtViewer_Viewer
+  Description : View model of the graphics view
+*/
+class QTVIEWER_API QtViewer_Viewer: public SUIT_ViewModel
+{
+  Q_OBJECT
+
+public:
+  QtViewer_Viewer(const QString& title, QWidget* widget = nullptr);
+  ~QtViewer_Viewer();
+
+public:
+  virtual SUIT_ViewWindow*      createView(SUIT_Desktop*);
+
+  virtual QString getType() const { return Type(); }
+  static QString Type() { return "QtViewer"; }
+
+  virtual void contextMenuPopup(QMenu*);
+
+public:
+  QtViewer_Selector* getSelector();
+
+  QtViewer_ViewFrame* getActiveView() const;
+  QtViewer_ViewPort* getActiveViewPort() const;
+  QtViewer_Scene* getActiveScene() const;
+
+  void fitAll();
+  void fitSelect();
+  void fitArea();
+  void zoom();
+  void pan();
+  void globalPan();
+
+signals:
+  void selectionChanged();
+
+protected:
+
+  virtual QtViewer_ViewFrame* createViewFrame(SUIT_Desktop* theDesktop, QWidget* theWidget);
+
+protected slots:
+  virtual void onKeyEvent(QKeyEvent*);
+  virtual void onMouseEvent(QMouseEvent*);
+  virtual void onWheelEvent(QWheelEvent*);
+
+  virtual void onSelectionDone();
+  virtual void onChangeBgColor();
+
+protected:
+  virtual void handleKeyPress(QKeyEvent*);
+  virtual void handleKeyRelease(QKeyEvent*);
+  virtual void handleMouseMove(QMouseEvent*);
+  virtual void handleMousePress(QMouseEvent*);
+  virtual void handleMouseRelease(QMouseEvent*);
+  virtual void handleWheel(QWheelEvent*);
+
+protected:
+  QtViewer_Selector*        mySelector;
+  QWidget*                      myWidget;
+};
+
+#endif
diff --git a/src/QtViewer/resources/QtViewer_images.ts b/src/QtViewer/resources/QtViewer_images.ts
new file mode 100644 (file)
index 0000000..b52e211
--- /dev/null
@@ -0,0 +1,48 @@
+<!DOCTYPE TS><TS>
+<context>
+    <name>QtViewer_ViewFrame</name>
+    <message>
+        <source>ICON_QTV_DUMP</source>
+        <translation>qtviewer_dump.png</translation>
+    </message>
+    <message>
+        <source>ICON_QTV_ZOOM</source>
+        <translation>qtviewer_zoom.png</translation>
+    </message>
+    <message>
+        <source>ICON_QTV_PAN</source>
+        <translation>qtviewer_pan.png</translation>
+    </message>
+    <message>
+        <source>ICON_QTV_GLOBALPAN</source>
+        <translation>qtviewer_glpan.png</translation>
+    </message>
+    <message>
+        <source>ICON_QTV_FITALL</source>
+        <translation>qtviewer_fitall.png</translation>
+    </message>
+    <message>
+        <source>ICON_QTV_FITSELECT</source>
+        <translation>qtviewer_fitselect.png</translation>
+    </message>
+    <message>
+        <source>ICON_QTV_RESET</source>
+        <translation>qtviewer_reset.png</translation>
+    </message>
+    <message>
+        <source>ICON_QTV_FITAREA</source>
+        <translation>qtviewer_fitarea.png</translation>
+    </message>
+    <message>
+        <source>ICON_QTV_ROTATE</source>
+        <translation>qtviewer_rotate.png</translation>
+    </message>
+</context>
+<context>
+    <name>QtViewer_ViewPort</name>
+    <message>
+        <source>ICON_QTV_CURSOR_ZOOM</source>
+        <translation>qtviewer_cursor_zoom.png</translation>
+    </message>
+</context>
+</TS>
diff --git a/src/QtViewer/resources/QtViewer_msg_en.ts b/src/QtViewer/resources/QtViewer_msg_en.ts
new file mode 100644 (file)
index 0000000..7898ce4
--- /dev/null
@@ -0,0 +1,128 @@
+<!DOCTYPE TS>
+<TS>
+  <context>
+    <name>QtViewer_ViewFrame</name>
+    <message>
+      <source>DSC_DUMP_VIEW</source>
+      <translation>Saves the active view in the image file</translation>
+    </message>
+    <message>
+      <source>DSC_FITALL</source>
+      <translation>Fit all objects inside the view frame</translation>
+    </message>
+    <message>
+      <source>DSC_FITRECT</source>
+      <translation>Fit area within the view frame</translation>
+    </message>
+    <message>
+      <source>DSC_FITSELECT</source>
+      <translation>Fit area of selection within the view frame</translation>
+    </message>
+    <message>
+      <source>DSC_GLOBALPAN_VIEW</source>
+      <translation>Selection of a new center of the view</translation>
+    </message>
+    <message>
+      <source>DSC_PAN_VIEW</source>
+      <translation>Pan the view</translation>
+    </message>
+    <message>
+      <source>DSC_RESET_VIEW</source>
+      <translation>Reset view point</translation>
+    </message>
+    <message>
+      <source>DSC_ZOOM_VIEW</source>
+      <translation>Zoom the view</translation>
+    </message>
+    <message>
+      <source>LBL_TOOLBAR_LABEL</source>
+      <translation>View Operations</translation>
+    </message>
+    <message>
+      <source>MNU_DUMP_VIEW</source>
+      <translation>Dump</translation>
+    </message>
+    <message>
+      <source>MNU_FITALL</source>
+      <translation>Fit All</translation>
+    </message>
+    <message>
+      <source>MNU_FITRECT</source>
+      <translation>Fit Area</translation>
+    </message>
+    <message>
+      <source>MNU_FITSELECT</source>
+      <translation>Fit Selection</translation>
+    </message>
+    <message>
+      <source>MNU_GLOBALPAN_VIEW</source>
+      <translation>Global Pan</translation>
+    </message>
+    <message>
+      <source>MNU_PAN_VIEW</source>
+      <translation>Pan</translation>
+    </message>
+    <message>
+      <source>MNU_RESET_VIEW</source>
+      <translation>Reset</translation>
+    </message>
+    <message>
+      <source>MNU_ZOOM_VIEW</source>
+      <translation>Zoom</translation>
+    </message>
+    <message>
+        <source>POSTSCRIPT_FILES</source>
+        <translation>PostScript files (*.ps *.eps)</translation>
+    </message>
+  </context>
+  <context>
+    <name>QtViewer_Viewer</name>
+    <message>
+      <source>CHANGE_BGCOLOR</source>
+      <translation>Change background...</translation>
+    </message>
+    <message>
+      <source>ADD_IMAGE</source>
+      <translation>Add image</translation>
+    </message>
+    <message>
+      <source>REMOVE_IMAGES</source>
+      <translation>Remove image(s)</translation>
+    </message>
+    <message>
+      <source>BRING_TO_FRONT</source>
+      <translation>Bring to front</translation>
+    </message>
+    <message>
+      <source>SEND_TO_BACK</source>
+      <translation>Send to back</translation>
+    </message>
+    <message>
+      <source>BRING_FORWARD</source>
+      <translation>Bring forward</translation>
+    </message>
+    <message>
+      <source>SEND_BACKWARD</source>
+      <translation>Send backward</translation>
+    </message>
+    <message>
+      <source>PROPERTIES</source>
+      <translation>Properties</translation>
+    </message>
+    <message>
+      <source>TEST_FUSE_OPERATOR</source>
+      <translation>Test Fuse operator</translation>
+    </message>
+    <message>
+      <source>TEST_CROP_OPERATOR</source>
+      <translation>Test Crop operator</translation>
+    </message>
+  </context>
+  <context>
+    <name>QtViewer_ViewManager</name>
+    <message>
+      <source>QTVIEWER_TITLE</source>
+      <translation>Qt scene:%M - viewer:%V</translation>
+    </message>
+  </context>
+</TS>
diff --git a/src/QtViewer/resources/QtViewer_msg_fr.ts b/src/QtViewer/resources/QtViewer_msg_fr.ts
new file mode 100644 (file)
index 0000000..7675789
--- /dev/null
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="fr" sourcelanguage="en">
+<context>
+    <name>QtViewer_ViewFrame</name>
+    <message>
+        <source>DSC_DUMP_VIEW</source>
+        <translation>Sauver la scène actuelle au fichier image</translation>
+    </message>
+    <message>
+        <source>DSC_FITALL</source>
+        <translation>Redimensionner la scène pour montrer tous les objets </translation>
+    </message>
+    <message>
+        <source>DSC_FITRECT</source>
+        <translation>Redimensionner la scène pour ne montrer que sa partie choisie par l&apos;encadré</translation>
+    </message>
+    <message>
+        <source>DSC_FITSELECT</source>
+        <translation>Redimensionner la scène pour montrer la sélection.</translation>
+    </message>
+    <message>
+        <source>DSC_GLOBALPAN_VIEW</source>
+        <translation>Sélection d&apos;un nouveau centre de la vue</translation>
+    </message>
+    <message>
+        <source>DSC_PAN_VIEW</source>
+        <translation>Redimensionner la vue</translation>
+    </message>
+    <message>
+        <source>DSC_RESET_VIEW</source>
+        <translation>Restaurer le point de vue</translation>
+    </message>
+    <message>
+        <source>DSC_ZOOM_VIEW</source>
+        <translation>Zoom</translation>
+    </message>
+    <message>
+        <source>LBL_TOOLBAR_LABEL</source>
+        <translation>Opérations de visualisation</translation>
+    </message>
+    <message>
+        <source>MNU_DUMP_VIEW</source>
+        <translation>Sauver la scène</translation>
+    </message>
+    <message>
+        <source>MNU_FITALL</source>
+        <translation>Montrer tout</translation>
+    </message>
+    <message>
+        <source>MNU_FITRECT</source>
+        <translation>Montrer l&apos;encadré</translation>
+    </message>
+    <message>
+        <source>MNU_FITSELECT</source>
+        <translation>Ajuster la sélection</translation>
+    </message>
+    <message>
+        <source>MNU_GLOBALPAN_VIEW</source>
+        <translation>Panoramique Globale</translation>
+    </message>
+    <message>
+        <source>MNU_PAN_VIEW</source>
+        <translation>Redimensionner la vue</translation>
+    </message>
+    <message>
+        <source>MNU_RESET_VIEW</source>
+        <translation>Restaurer</translation>
+    </message>
+    <message>
+        <source>MNU_ZOOM_VIEW</source>
+        <translation>Zoom</translation>
+    </message>
+    <message>
+        <source>POSTSCRIPT_FILES</source>
+        <translation>Fichiers PostScript (*.ps *.eps)</translation>
+    </message>
+</context>
+<context>
+    <name>QtViewer_Viewer</name>
+    <message>
+        <source>TEST_CROP_OPERATOR</source>
+        <translation>Test Crop operator</translation>
+    </message>
+    <message>
+        <source>TEST_FUSE_OPERATOR</source>
+        <translation>Test Fuse operator</translation>
+    </message>
+    <message>
+        <source>PROPERTIES</source>
+        <translation>Propriétés</translation>
+    </message>
+    <message>
+        <source>SEND_BACKWARD</source>
+        <translation>Afficher derrière</translation>
+    </message>
+    <message>
+        <source>BRING_FORWARD</source>
+        <translation>Afficher devant</translation>
+    </message>
+    <message>
+        <source>SEND_TO_BACK</source>
+        <translation>Afficher au fond</translation>
+    </message>
+    <message>
+        <source>BRING_TO_FRONT</source>
+        <translation>Afficher au premier plan</translation>
+    </message>
+    <message>
+        <source>REMOVE_IMAGES</source>
+        <translation>Supprimer image(s)</translation>
+    </message>
+    <message>
+        <source>ADD_IMAGE</source>
+        <translation>Ajouter une image</translation>
+    </message>
+    <message>
+        <source>CHANGE_BGCOLOR</source>
+        <translation>Changer l&apos;arrière-plan...</translation>
+    </message>
+</context>
+<context>
+    <name>QtViewer_ViewManager</name>
+    <message>
+        <source>QTVIEWER_TITLE</source>
+        <translation> Scène Qt:%M - visualisation:%V</translation>
+    </message>
+</context>
+</TS>
diff --git a/src/QtViewer/resources/QtViewer_msg_ja.ts b/src/QtViewer/resources/QtViewer_msg_ja.ts
new file mode 100644 (file)
index 0000000..262e904
--- /dev/null
@@ -0,0 +1,129 @@
+<?xml version="1.0"?>
+<!DOCTYPE TS>
+<TS language="ja" sourcelanguage="en">
+  <context>
+    <name>QtViewer_ViewFrame</name>
+    <message>
+      <source>DSC_DUMP_VIEW</source>
+      <translation>&#x30A2;&#x30AF;&#x30C6;&#x30A3;&#x30D6;&#x30D3;&#x30E5;&#x30FC;&#x306E;&#x753B;&#x50CF;&#x3092;&#x4FDD;&#x5B58;</translation>
+    </message>
+    <message>
+      <source>DSC_FITALL</source>
+      <translation>&#x30D3;&#x30E5;&#x30FC;&#x306E;&#x67A0;&#x5185;&#x306B;&#x3059;&#x3079;&#x3066;&#x306E;&#x30AA;&#x30D6;&#x30B8;&#x30A7;&#x30AF;&#x30C8;&#x3092;&#x30D5;&#x30A3;&#x30C3;&#x30C8;&#x3059;&#x308B;</translation>
+    </message>
+    <message>
+      <source>DSC_FITRECT</source>
+      <translation>&#x9818;&#x57DF;&#x3092;&#x30D3;&#x30E5;&#x30FC;&#x306E;&#x67A0;&#x5185;&#x306B;&#x30D5;&#x30A3;&#x30C3;&#x30C8;&#x3059;&#x308B;</translation>
+    </message>
+    <message>
+      <source>DSC_FITSELECT</source>
+      <translation>&#x9078;&#x629E;&#x9818;&#x57DF;&#x3092;&#x30D3;&#x30E5;&#x30FC;&#x306E;&#x67A0;&#x5185;&#x306B;&#x30D5;&#x30A3;&#x30C3;&#x30C8;&#x3059;&#x308B;</translation>
+    </message>
+    <message>
+      <source>DSC_GLOBALPAN_VIEW</source>
+      <translation>&#x30D3;&#x30E5;&#x30FC;&#x306E;&#x65B0;&#x3057;&#x3044;&#x4E2D;&#x5FC3;&#x306E;&#x9078;&#x629E;</translation>
+    </message>
+    <message>
+      <source>DSC_PAN_VIEW</source>
+      <translation>&#x30D3;&#x30E5;&#x30FC;&#x306E;&#x56DE;&#x8EE2;</translation>
+    </message>
+    <message>
+      <source>DSC_RESET_VIEW</source>
+      <translation>&#x30D3;&#x30E5;&#x30FC;&#x306E;&#x30EA;&#x30BB;&#x30C3;&#x30C8;</translation>
+    </message>
+    <message>
+      <source>DSC_ZOOM_VIEW</source>
+      <translation>&#x30D3;&#x30E5;&#x30FC;&#x306E;&#x62E1;&#x5927;</translation>
+    </message>
+    <message>
+      <source>LBL_TOOLBAR_LABEL</source>
+      <translation>&#x30D3;&#x30E5;&#x30FC;&#x306E;&#x64CD;&#x4F5C;</translation>
+    </message>
+    <message>
+      <source>MNU_DUMP_VIEW</source>
+      <translation>&#x8868;&#x793A;&#x72B6;&#x614B;&#x306E;&#x4FDD;&#x5B58;</translation>
+    </message>
+    <message>
+      <source>MNU_FITALL</source>
+      <translation>&#x5168;&#x8868;&#x793A;</translation>
+    </message>
+    <message>
+      <source>MNU_FITRECT</source>
+      <translation>&#x9818;&#x57DF;&#x306B;&#x30D5;&#x30A3;&#x30C3;&#x30C8;</translation>
+    </message>
+    <message>
+      <source>MNU_FITSELECT</source>
+      <translation>&#x9078;&#x629E;&#x7BC4;&#x56F2;&#x3092;&#x30BA;&#x30FC;&#x30E0;</translation>
+    </message>
+    <message>
+      <source>MNU_GLOBALPAN_VIEW</source>
+      <translation>&#x30B0;&#x30ED;&#x30FC;&#x30D0;&#x30EB;&#x56DE;&#x8EE2;</translation>
+    </message>
+    <message>
+      <source>MNU_PAN_VIEW</source>
+      <translation>&#x56DE;&#x8EE2;</translation>
+    </message>
+    <message>
+      <source>MNU_RESET_VIEW</source>
+      <translation>&#x30EA;&#x30BB;&#x30C3;&#x30C8;</translation>
+    </message>
+    <message>
+      <source>MNU_ZOOM_VIEW</source>
+      <translation>&#x30BA;&#x30FC;&#x30E0;</translation>
+    </message>
+    <message>
+        <source>POSTSCRIPT_FILES</source>
+        <translation>PostScript files (*.ps *.eps)</translation>
+    </message>
+  </context>
+  <context>
+    <name>QtViewer_Viewer</name>
+    <message>
+      <source>CHANGE_BGCOLOR</source>
+      <translation>&#x80CC;&#x666F;&#x306E;&#x5909;&#x66F4;.</translation>
+    </message>
+    <message>
+      <source>ADD_IMAGE</source>
+      <translation>&#x753B;&#x50CF;&#x306E;&#x8FFD;&#x52A0;</translation>
+    </message>
+    <message>
+      <source>REMOVE_IMAGES</source>
+      <translation>&#x753B;&#x50CF;&#x306E;&#x524A;&#x9664;</translation>
+    </message>
+    <message>
+      <source>BRING_TO_FRONT</source>
+      <translation>&#x6700;&#x524D;&#x9762;&#x3078;&#x79FB;&#x52D5;</translation>
+    </message>
+    <message>
+      <source>SEND_TO_BACK</source>
+      <translation>&#x6700;&#x80CC;&#x9762;&#x3078;&#x79FB;&#x52D5;</translation>
+    </message>
+    <message>
+      <source>BRING_FORWARD</source>
+      <translation>&#x524D;&#x9762;&#x3078;&#x79FB;&#x52D5;</translation>
+    </message>
+    <message>
+      <source>SEND_BACKWARD</source>
+      <translation>&#x80CC;&#x9762;&#x3078;&#x79FB;&#x52D5;</translation>
+    </message>
+    <message>
+      <source>PROPERTIES</source>
+      <translation>&#x30D7;&#x30ED;&#x30D1;&#x30C6;&#x30A3;</translation>
+    </message>
+    <message>
+      <source>TEST_FUSE_OPERATOR</source>
+      <translation>&#x7D50;&#x5408;&#x306E;&#x30C6;&#x30B9;&#x30C8;</translation>
+    </message>
+    <message>
+      <source>TEST_CROP_OPERATOR</source>
+      <translation>&#x30C8;&#x30EA;&#x30E0;&#x306E;&#x30C6;&#x30B9;&#x30C8;</translation>
+    </message>
+  </context>
+  <context>
+    <name>QtViewer_ViewManager</name>
+    <message>
+      <source>QTVIEWER_TITLE</source>
+      <translation>&#x30B0;&#x30E9;&#x30D5;&#x30A3;&#x30C3;&#x30AF;&#x30B7;&#x30FC;&#x30F3;:%M - &#x30D3;&#x30E5;&#x30FC;&#x30EF;:%V</translation>
+    </message>
+  </context>
+</TS>
diff --git a/src/QtViewer/resources/qtviewer_cursor_zoom.png b/src/QtViewer/resources/qtviewer_cursor_zoom.png
new file mode 100644 (file)
index 0000000..0020fea
Binary files /dev/null and b/src/QtViewer/resources/qtviewer_cursor_zoom.png differ
diff --git a/src/QtViewer/resources/qtviewer_dump.png b/src/QtViewer/resources/qtviewer_dump.png
new file mode 100644 (file)
index 0000000..b02616f
Binary files /dev/null and b/src/QtViewer/resources/qtviewer_dump.png differ
diff --git a/src/QtViewer/resources/qtviewer_fitall.png b/src/QtViewer/resources/qtviewer_fitall.png
new file mode 100644 (file)
index 0000000..87e001d
Binary files /dev/null and b/src/QtViewer/resources/qtviewer_fitall.png differ
diff --git a/src/QtViewer/resources/qtviewer_fitarea.png b/src/QtViewer/resources/qtviewer_fitarea.png
new file mode 100644 (file)
index 0000000..e83d023
Binary files /dev/null and b/src/QtViewer/resources/qtviewer_fitarea.png differ
diff --git a/src/QtViewer/resources/qtviewer_fitselect.png b/src/QtViewer/resources/qtviewer_fitselect.png
new file mode 100644 (file)
index 0000000..e52598d
Binary files /dev/null and b/src/QtViewer/resources/qtviewer_fitselect.png differ
diff --git a/src/QtViewer/resources/qtviewer_glpan.png b/src/QtViewer/resources/qtviewer_glpan.png
new file mode 100644 (file)
index 0000000..28ab547
Binary files /dev/null and b/src/QtViewer/resources/qtviewer_glpan.png differ
diff --git a/src/QtViewer/resources/qtviewer_pan.png b/src/QtViewer/resources/qtviewer_pan.png
new file mode 100644 (file)
index 0000000..ec56cac
Binary files /dev/null and b/src/QtViewer/resources/qtviewer_pan.png differ
diff --git a/src/QtViewer/resources/qtviewer_reset.png b/src/QtViewer/resources/qtviewer_reset.png
new file mode 100644 (file)
index 0000000..66f81e6
Binary files /dev/null and b/src/QtViewer/resources/qtviewer_reset.png differ
diff --git a/src/QtViewer/resources/qtviewer_rotate.png b/src/QtViewer/resources/qtviewer_rotate.png
new file mode 100644 (file)
index 0000000..3f180b4
Binary files /dev/null and b/src/QtViewer/resources/qtviewer_rotate.png differ
diff --git a/src/QtViewer/resources/qtviewer_zoom.png b/src/QtViewer/resources/qtviewer_zoom.png
new file mode 100644 (file)
index 0000000..386c966
Binary files /dev/null and b/src/QtViewer/resources/qtviewer_zoom.png differ