From d3ec674f2c2c15cd6a28ca6ab0bcbf417278e592 Mon Sep 17 00:00:00 2001 From: CHEMIN Sebastien Date: Tue, 19 Mar 2024 11:29:50 +0100 Subject: [PATCH] New Viewer : QtViewer --- CMakeLists.txt | 14 +- SalomeGUIConfig.cmake.in | 4 + src/CMakeLists.txt | 6 + src/LightApp/CMakeLists.txt | 12 + src/LightApp/LightApp_Application.cxx | 27 ++ src/LightApp/LightApp_Application.h | 2 +- src/LightApp/LightApp_QTVSelector.cxx | 96 ++++ src/LightApp/LightApp_QTVSelector.h | 52 ++ src/LightApp/resources/LightApp.xml | 1 + src/LightApp/resources/LightApp_msg_en.ts | 4 + src/QtViewer/CMakeLists.txt | 111 +++++ src/QtViewer/QtViewer.h | 31 ++ src/QtViewer/QtViewer_Object.cxx | 37 ++ src/QtViewer/QtViewer_Object.h | 48 ++ src/QtViewer/QtViewer_Scene.cxx | 38 ++ src/QtViewer/QtViewer_Scene.h | 40 ++ src/QtViewer/QtViewer_Selector.cxx | 48 ++ src/QtViewer/QtViewer_Selector.h | 53 ++ src/QtViewer/QtViewer_ViewFrame.cxx | 451 ++++++++++++++++++ src/QtViewer/QtViewer_ViewFrame.h | 111 +++++ src/QtViewer/QtViewer_ViewManager.cxx | 51 ++ src/QtViewer/QtViewer_ViewManager.h | 44 ++ src/QtViewer/QtViewer_ViewPort.cxx | 372 +++++++++++++++ src/QtViewer/QtViewer_ViewPort.h | 95 ++++ src/QtViewer/QtViewer_Viewer.cxx | 336 +++++++++++++ src/QtViewer/QtViewer_Viewer.h | 99 ++++ src/QtViewer/resources/QtViewer_images.ts | 48 ++ src/QtViewer/resources/QtViewer_msg_en.ts | 128 +++++ src/QtViewer/resources/QtViewer_msg_fr.ts | 129 +++++ src/QtViewer/resources/QtViewer_msg_ja.ts | 129 +++++ .../resources/qtviewer_cursor_zoom.png | Bin 0 -> 245 bytes src/QtViewer/resources/qtviewer_dump.png | Bin 0 -> 682 bytes src/QtViewer/resources/qtviewer_fitall.png | Bin 0 -> 816 bytes src/QtViewer/resources/qtviewer_fitarea.png | Bin 0 -> 815 bytes src/QtViewer/resources/qtviewer_fitselect.png | Bin 0 -> 857 bytes src/QtViewer/resources/qtviewer_glpan.png | Bin 0 -> 1086 bytes src/QtViewer/resources/qtviewer_pan.png | Bin 0 -> 982 bytes src/QtViewer/resources/qtviewer_reset.png | Bin 0 -> 918 bytes src/QtViewer/resources/qtviewer_rotate.png | Bin 0 -> 444 bytes src/QtViewer/resources/qtviewer_zoom.png | Bin 0 -> 797 bytes 40 files changed, 2615 insertions(+), 2 deletions(-) create mode 100644 src/LightApp/LightApp_QTVSelector.cxx create mode 100644 src/LightApp/LightApp_QTVSelector.h create mode 100644 src/QtViewer/CMakeLists.txt create mode 100644 src/QtViewer/QtViewer.h create mode 100644 src/QtViewer/QtViewer_Object.cxx create mode 100644 src/QtViewer/QtViewer_Object.h create mode 100644 src/QtViewer/QtViewer_Scene.cxx create mode 100644 src/QtViewer/QtViewer_Scene.h create mode 100644 src/QtViewer/QtViewer_Selector.cxx create mode 100644 src/QtViewer/QtViewer_Selector.h create mode 100644 src/QtViewer/QtViewer_ViewFrame.cxx create mode 100644 src/QtViewer/QtViewer_ViewFrame.h create mode 100644 src/QtViewer/QtViewer_ViewManager.cxx create mode 100644 src/QtViewer/QtViewer_ViewManager.h create mode 100644 src/QtViewer/QtViewer_ViewPort.cxx create mode 100644 src/QtViewer/QtViewer_ViewPort.h create mode 100644 src/QtViewer/QtViewer_Viewer.cxx create mode 100644 src/QtViewer/QtViewer_Viewer.h create mode 100644 src/QtViewer/resources/QtViewer_images.ts create mode 100644 src/QtViewer/resources/QtViewer_msg_en.ts create mode 100644 src/QtViewer/resources/QtViewer_msg_fr.ts create mode 100644 src/QtViewer/resources/QtViewer_msg_ja.ts create mode 100644 src/QtViewer/resources/qtviewer_cursor_zoom.png create mode 100644 src/QtViewer/resources/qtviewer_dump.png create mode 100644 src/QtViewer/resources/qtviewer_fitall.png create mode 100644 src/QtViewer/resources/qtviewer_fitarea.png create mode 100644 src/QtViewer/resources/qtviewer_fitselect.png create mode 100644 src/QtViewer/resources/qtviewer_glpan.png create mode 100644 src/QtViewer/resources/qtviewer_pan.png create mode 100644 src/QtViewer/resources/qtviewer_reset.png create mode 100644 src/QtViewer/resources/qtviewer_rotate.png create mode 100644 src/QtViewer/resources/qtviewer_zoom.png diff --git a/CMakeLists.txt b/CMakeLists.txt index f787bf564..59750e97f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/SalomeGUIConfig.cmake.in b/SalomeGUIConfig.cmake.in index dd43712f9..3f320fa71 100644 --- a/SalomeGUIConfig.cmake.in +++ b/SalomeGUIConfig.cmake.in @@ -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() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6c5fb917d..479760204 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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) diff --git a/src/LightApp/CMakeLists.txt b/src/LightApp/CMakeLists.txt index ee2414121..d3b610cbf 100644 --- a/src/LightApp/CMakeLists.txt +++ b/src/LightApp/CMakeLists.txt @@ -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() diff --git a/src/LightApp/LightApp_Application.cxx b/src/LightApp/LightApp_Application.cxx index 19639c281..e7c81099b 100644 --- a/src/LightApp/LightApp_Application.cxx +++ b/src/LightApp/LightApp_Application.cxx @@ -154,6 +154,12 @@ #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() ) { diff --git a/src/LightApp/LightApp_Application.h b/src/LightApp/LightApp_Application.h index cb2102e19..7f2f6d76f 100644 --- a/src/LightApp/LightApp_Application.h +++ b/src/LightApp/LightApp_Application.h @@ -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 index 000000000..4c6554a30 --- /dev/null +++ b/src/LightApp/LightApp_QTVSelector.cxx @@ -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 +#include +#include + +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(item)) + { + LightApp_DataOwner* owner = dynamic_cast( 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 aSelected; + for ( SUIT_DataOwnerPtrList::const_iterator itr = theList.begin(); itr != theList.end(); ++itr ) + { + const LightApp_DataOwner* owner = dynamic_cast( (*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(item)) + { + LightApp_DataOwner* owner = dynamic_cast( 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 index 000000000..0d7e67c28 --- /dev/null +++ b/src/LightApp/LightApp_QTVSelector.h @@ -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 +#include +#include + +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 diff --git a/src/LightApp/resources/LightApp.xml b/src/LightApp/resources/LightApp.xml index 0e1c4249e..1d72e5991 100644 --- a/src/LightApp/resources/LightApp.xml +++ b/src/LightApp/resources/LightApp.xml @@ -43,6 +43,7 @@ + diff --git a/src/LightApp/resources/LightApp_msg_en.ts b/src/LightApp/resources/LightApp_msg_en.ts index 894c867f1..efdbdcc6a 100644 --- a/src/LightApp/resources/LightApp_msg_en.ts +++ b/src/LightApp/resources/LightApp_msg_en.ts @@ -568,6 +568,10 @@ The changes will be applied on the next application session. NEW_WINDOW_8 ParaView&3D view + + NEW_WINDOW_9 + Q&t view + CREATING_NEW_WINDOW Create new %1 diff --git a/src/QtViewer/CMakeLists.txt b/src/QtViewer/CMakeLists.txt new file mode 100644 index 000000000..413bc41ec --- /dev/null +++ b/src/QtViewer/CMakeLists.txt @@ -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 index 000000000..b605fd4ef --- /dev/null +++ b/src/QtViewer/QtViewer.h @@ -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 index 000000000..18fb3a347 --- /dev/null +++ b/src/QtViewer/QtViewer_Object.cxx @@ -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 index 000000000..7e69f1a1d --- /dev/null +++ b/src/QtViewer/QtViewer_Object.h @@ -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 + +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 index 000000000..29675ffe9 --- /dev/null +++ b/src/QtViewer/QtViewer_Scene.cxx @@ -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 index 000000000..47c1702da --- /dev/null +++ b/src/QtViewer/QtViewer_Scene.h @@ -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 + +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 index 000000000..79aa12ccc --- /dev/null +++ b/src/QtViewer/QtViewer_Selector.cxx @@ -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 index 000000000..7720b8629 --- /dev/null +++ b/src/QtViewer/QtViewer_Selector.h @@ -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 +#include + +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 index 000000000..e06bda34e --- /dev/null +++ b/src/QtViewer/QtViewer_ViewFrame.cxx @@ -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 +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +//======================================================================= +// 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(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 anExpandableActions; + anExpandableActions.append( myScaleAction ); + anExpandableActions.append( myPanAction ); + + QListIterator anIter( anExpandableActions ); + while( anIter.hasNext() ) + { + QtxMultiAction* aMultiAction = dynamic_cast( anIter.next() ); + if( aMultiAction ) + { + QList aLocalActions = aMultiAction->actions(); + QListIterator 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 index 000000000..a59694a54 --- /dev/null +++ b/src/QtViewer/QtViewer_ViewFrame.h @@ -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 +#include + +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 index 000000000..bd5c0dde5 --- /dev/null +++ b/src/QtViewer/QtViewer_ViewManager.cxx @@ -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( getViewModel() ); +} diff --git a/src/QtViewer/QtViewer_ViewManager.h b/src/QtViewer/QtViewer_ViewManager.h new file mode 100644 index 000000000..b7cd0223c --- /dev/null +++ b/src/QtViewer/QtViewer_ViewManager.h @@ -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 + +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 index 000000000..56cac94ff --- /dev/null +++ b/src/QtViewer/QtViewer_ViewPort.cxx @@ -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 +#include +#include +#include +#include +#include +#include + +#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 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(newSize.width()); + qreal h = static_cast(newSize.height()); + + qreal w0 = static_cast(oldSize.width()); + qreal h0 = static_cast(oldSize.height()); + + qreal widthRatio = w/w0; + qreal heightRatio = h/h0; + + if (widthRatio>0 && heightRatio>0) + { + qreal scaleFactor = wangleDelta().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 index 000000000..b7ddd153d --- /dev/null +++ b/src/QtViewer/QtViewer_ViewPort.h @@ -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 + +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 index 000000000..bf5db2e41 --- /dev/null +++ b/src/QtViewer/QtViewer_Viewer.cxx @@ -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 + +#include +#include +#include +#include + + +//======================================================================= +// 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( 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( 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 index 000000000..71c41a401 --- /dev/null +++ b/src/QtViewer/QtViewer_Viewer.h @@ -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 + +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 index 000000000..b52e21179 --- /dev/null +++ b/src/QtViewer/resources/QtViewer_images.ts @@ -0,0 +1,48 @@ + + + QtViewer_ViewFrame + + ICON_QTV_DUMP + qtviewer_dump.png + + + ICON_QTV_ZOOM + qtviewer_zoom.png + + + ICON_QTV_PAN + qtviewer_pan.png + + + ICON_QTV_GLOBALPAN + qtviewer_glpan.png + + + ICON_QTV_FITALL + qtviewer_fitall.png + + + ICON_QTV_FITSELECT + qtviewer_fitselect.png + + + ICON_QTV_RESET + qtviewer_reset.png + + + ICON_QTV_FITAREA + qtviewer_fitarea.png + + + ICON_QTV_ROTATE + qtviewer_rotate.png + + + + QtViewer_ViewPort + + ICON_QTV_CURSOR_ZOOM + qtviewer_cursor_zoom.png + + + diff --git a/src/QtViewer/resources/QtViewer_msg_en.ts b/src/QtViewer/resources/QtViewer_msg_en.ts new file mode 100644 index 000000000..7898ce45e --- /dev/null +++ b/src/QtViewer/resources/QtViewer_msg_en.ts @@ -0,0 +1,128 @@ + + + + QtViewer_ViewFrame + + DSC_DUMP_VIEW + Saves the active view in the image file + + + DSC_FITALL + Fit all objects inside the view frame + + + DSC_FITRECT + Fit area within the view frame + + + DSC_FITSELECT + Fit area of selection within the view frame + + + DSC_GLOBALPAN_VIEW + Selection of a new center of the view + + + DSC_PAN_VIEW + Pan the view + + + DSC_RESET_VIEW + Reset view point + + + DSC_ZOOM_VIEW + Zoom the view + + + LBL_TOOLBAR_LABEL + View Operations + + + MNU_DUMP_VIEW + Dump + + + MNU_FITALL + Fit All + + + MNU_FITRECT + Fit Area + + + MNU_FITSELECT + Fit Selection + + + MNU_GLOBALPAN_VIEW + Global Pan + + + MNU_PAN_VIEW + Pan + + + MNU_RESET_VIEW + Reset + + + MNU_ZOOM_VIEW + Zoom + + + POSTSCRIPT_FILES + PostScript files (*.ps *.eps) + + + + QtViewer_Viewer + + CHANGE_BGCOLOR + Change background... + + + ADD_IMAGE + Add image + + + REMOVE_IMAGES + Remove image(s) + + + BRING_TO_FRONT + Bring to front + + + SEND_TO_BACK + Send to back + + + BRING_FORWARD + Bring forward + + + SEND_BACKWARD + Send backward + + + PROPERTIES + Properties + + + TEST_FUSE_OPERATOR + Test Fuse operator + + + TEST_CROP_OPERATOR + Test Crop operator + + + + QtViewer_ViewManager + + QTVIEWER_TITLE + Qt scene:%M - viewer:%V + + + diff --git a/src/QtViewer/resources/QtViewer_msg_fr.ts b/src/QtViewer/resources/QtViewer_msg_fr.ts new file mode 100644 index 000000000..767578933 --- /dev/null +++ b/src/QtViewer/resources/QtViewer_msg_fr.ts @@ -0,0 +1,129 @@ + + + + + QtViewer_ViewFrame + + DSC_DUMP_VIEW + Sauver la scène actuelle au fichier image + + + DSC_FITALL + Redimensionner la scène pour montrer tous les objets + + + DSC_FITRECT + Redimensionner la scène pour ne montrer que sa partie choisie par l'encadré + + + DSC_FITSELECT + Redimensionner la scène pour montrer la sélection. + + + DSC_GLOBALPAN_VIEW + Sélection d'un nouveau centre de la vue + + + DSC_PAN_VIEW + Redimensionner la vue + + + DSC_RESET_VIEW + Restaurer le point de vue + + + DSC_ZOOM_VIEW + Zoom + + + LBL_TOOLBAR_LABEL + Opérations de visualisation + + + MNU_DUMP_VIEW + Sauver la scène + + + MNU_FITALL + Montrer tout + + + MNU_FITRECT + Montrer l'encadré + + + MNU_FITSELECT + Ajuster la sélection + + + MNU_GLOBALPAN_VIEW + Panoramique Globale + + + MNU_PAN_VIEW + Redimensionner la vue + + + MNU_RESET_VIEW + Restaurer + + + MNU_ZOOM_VIEW + Zoom + + + POSTSCRIPT_FILES + Fichiers PostScript (*.ps *.eps) + + + + QtViewer_Viewer + + TEST_CROP_OPERATOR + Test Crop operator + + + TEST_FUSE_OPERATOR + Test Fuse operator + + + PROPERTIES + Propriétés + + + SEND_BACKWARD + Afficher derrière + + + BRING_FORWARD + Afficher devant + + + SEND_TO_BACK + Afficher au fond + + + BRING_TO_FRONT + Afficher au premier plan + + + REMOVE_IMAGES + Supprimer image(s) + + + ADD_IMAGE + Ajouter une image + + + CHANGE_BGCOLOR + Changer l'arrière-plan... + + + + QtViewer_ViewManager + + QTVIEWER_TITLE + Scène Qt:%M - visualisation:%V + + + diff --git a/src/QtViewer/resources/QtViewer_msg_ja.ts b/src/QtViewer/resources/QtViewer_msg_ja.ts new file mode 100644 index 000000000..262e90414 --- /dev/null +++ b/src/QtViewer/resources/QtViewer_msg_ja.ts @@ -0,0 +1,129 @@ + + + + + QtViewer_ViewFrame + + DSC_DUMP_VIEW + アクティブビューの画像を保存 + + + DSC_FITALL + ビューの枠内にすべてのオブジェクトをフィットする + + + DSC_FITRECT + 領域をビューの枠内にフィットする + + + DSC_FITSELECT + 選択領域をビューの枠内にフィットする + + + DSC_GLOBALPAN_VIEW + ビューの新しい中心の選択 + + + DSC_PAN_VIEW + ビューの回転 + + + DSC_RESET_VIEW + ビューのリセット + + + DSC_ZOOM_VIEW + ビューの拡大 + + + LBL_TOOLBAR_LABEL + ビューの操作 + + + MNU_DUMP_VIEW + 表示状態の保存 + + + MNU_FITALL + 全表示 + + + MNU_FITRECT + 領域にフィット + + + MNU_FITSELECT + 選択範囲をズーム + + + MNU_GLOBALPAN_VIEW + グローバル回転 + + + MNU_PAN_VIEW + 回転 + + + MNU_RESET_VIEW + リセット + + + MNU_ZOOM_VIEW + ズーム + + + POSTSCRIPT_FILES + PostScript files (*.ps *.eps) + + + + QtViewer_Viewer + + CHANGE_BGCOLOR + 背景の変更. + + + ADD_IMAGE + 画像の追加 + + + REMOVE_IMAGES + 画像の削除 + + + BRING_TO_FRONT + 最前面へ移動 + + + SEND_TO_BACK + 最背面へ移動 + + + BRING_FORWARD + 前面へ移動 + + + SEND_BACKWARD + 背面へ移動 + + + PROPERTIES + プロパティ + + + TEST_FUSE_OPERATOR + 結合のテスト + + + TEST_CROP_OPERATOR + トリムのテスト + + + + QtViewer_ViewManager + + QTVIEWER_TITLE + グラフィックシーン:%M - ビューワ:%V + + + diff --git a/src/QtViewer/resources/qtviewer_cursor_zoom.png b/src/QtViewer/resources/qtviewer_cursor_zoom.png new file mode 100644 index 0000000000000000000000000000000000000000..0020fea39f8531230eb0c25c662b76ee98f696bd GIT binary patch literal 245 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnH3?%tPCZz)@&H$ef*9{vs0Ga>)|F^Z8<^g0e zmIV0)GdMiEkp|?5mAFQf1m~xflqVLYGNfmw85QKED;Vh+=o#9^?aKhFU`h9MOJ`zW zkPLd4!Up7Lc)B=-RLn_EP!KOz+h7#dX4;UsjI)PRK$4w})1Y}W<0Lc-a$k!M*zN28VxpF`U#yCAY@F9!>Q{yu)SmYHks0PSS(boFyt=akR{08E}qwEzGB literal 0 HcmV?d00001 diff --git a/src/QtViewer/resources/qtviewer_dump.png b/src/QtViewer/resources/qtviewer_dump.png new file mode 100644 index 0000000000000000000000000000000000000000..b02616f2975e7a3865a236ee75380bdae5ce59f7 GIT binary patch literal 682 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE-VXMsm#F#`j)FbFd;%$g$s6l6(v z^mSxl*w|O|J8&|PuaN8!GAr-fh{`~)M&uq%*z+h+?Aj!ZYz}<83#0idNZ{NHLm{arOf}-0Di4NZr z4h;-Rj?WrQvR=Mwyy^F?%;4dFDJdx)KR>?&vt5iYrhzo>YRaCjpLk={x^?G1e0dpc zAf2Wt^rJsV!+{}D;>9cZGar846mH{Q?tkd0S>BzF%TD3t{4*BXIQ-IfVA%M8i#s*c zlr1kVj?FMpku6S6PGNSxV@Sx9M(Gn`0zzpIgandKboIMkOJX=8&cMX6ys@Kkl!Hi5Cs~Z*GuUfUrsH3ynxPybcSy{#2e*VG@J6ax= z#n~Osp1^ImwK3)gt3rdprHAi&vk!iGdwaWNpPVI=nU9lGQ{we?u{?kG+WrXQ(cn=9 z+IG10^fX=PhwiSfjl8q1O0@zxr4<@xOt_qoo~}Mam+y-f$9#+0wuLz-jo8f1&D+fL z?z+m40n#|u4mYG61ddHVaiyUq`r4~d9q8ZdYn zozP=;ncaEPUC6S9SjZ)j11xdTOVx|PwNDx OD+W(jKbLh*2~7Z6;rO)x literal 0 HcmV?d00001 diff --git a/src/QtViewer/resources/qtviewer_fitall.png b/src/QtViewer/resources/qtviewer_fitall.png new file mode 100644 index 0000000000000000000000000000000000000000..87e001dd80b2755858d4599857106a0c9c0b3500 GIT binary patch literal 816 zcmV-01JC@4P)z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ;rb$FWRCwBA{Qv(y12q9a0I`6G?+lD6rgAd;XCy{5 zHhlmA#Dc^@mIHB63}s|w3&>x^7VEp$V z!_S{T8NPo0%wTSB4^{^=10aA{2t*_sGYc!&H9+&gF8uxbH^cX@Ux5bxVEFUvH&_hp zNhkmaASMC^p1OMBJi~90i+=rL`10u!!-sco89u&$$ME^%M~1IozA)UpbP22urU4*; z81W@+U>Ndq^YVU}wt5|dps+B*k8j@@e*E~(@bkwHhQELQGJN^`k)bg^7i72+(46}q zJpciO*M(YIT7fc>k_-*mnGENS9|s!*!oPv8y?^^ALw|iO$gn1uVITkyKn&QD3J3!Y zt1#5l`yc4!^j}9?`#%#C(;-P2+5cJwhW{mHWkKFL1H{Sb`Tzn5YousvYge$bu(Yd+ zi!(g^@BtL?iGTn8T>uOM_2*9>%K?=<1!}&AO)o$IVT2*juu`C5U1~tXo&y8^?Uyf= zSFc{}AhvJ-2p}dj!}3{~naMT`1ONgE>_SkfVWO=i2{i0E$eXW$2^NUUfQEGwYY@l` zP;LPTAh-*gnwp;TadI-eff!amiebp56hHvMT?i_^fL=}k3i1H)bfAI1NHGa!20#G8 u4Wv>5%K#8S$g%vNP}zvfo5&o100RIgKz|e1YHVKs0000aa literal 0 HcmV?d00001 diff --git a/src/QtViewer/resources/qtviewer_fitarea.png b/src/QtViewer/resources/qtviewer_fitarea.png new file mode 100644 index 0000000000000000000000000000000000000000..e83d023a332df9a7d3ed0eb708e13260fb870af9 GIT binary patch literal 815 zcmV+~1JL}5P)Zvh0=!8? zK~xyios>&x6Hyd~zu0NDs70YTKG0afETV$oLIhFjgVtKmO2r4bsVfyxv7#GMx+ypn z*KVtBRD6IBT&PP0->u@KRa=@dHc8XYOs35woqJv6M*Fah_J_me-Z|&voOACSq?AZ0 zv1M@7I#mluDaos)rRC3N3TkX@3@|c7!!V>RgA@7J0XKk`z%5|^$d86$NB}K=P!{OM zFmme{tpN^IR&P64y|a#miNd5hI_;uymBe{-f4fYooV+1{{Y&t8O-ITI3J3Vb1`tf{4H=PrPg{|ek) zS+gBqN_-(179wZ9!1Fv@$6@WpjQ|Jo6&EVGv`8z)7Xl%3U}dUOJ7JPLs`K_}=lEOXtqw zSk`+Wu0n<;>|r<@J~Lg@nwOTB)6v^Y)A6G*ec_^cbIZ%=?@JKv=}7{ez$c(rg{8EK zU?rN?yj<5Y2L_16;}3-p@o1!{EE?&V4R}BjNCQ#ey$bcTzraqFXj*ef*NIvdT|a(2 ziN#`FfUSB}49rl__=qe4UW5tZ3HWj}%JL_k{xDGPLC%it*B3}6+oLABz! tx&&)7*jSAOYQQ{TnVN53)MfmaegTLEj1qkO@u>g+002ovPDHLkV1g{1YhM5W literal 0 HcmV?d00001 diff --git a/src/QtViewer/resources/qtviewer_fitselect.png b/src/QtViewer/resources/qtviewer_fitselect.png new file mode 100644 index 0000000000000000000000000000000000000000..e52598d7b5b26b8fb5c5097dc02fc59ec43606c1 GIT binary patch literal 857 zcmV-f1E&0mP)`6sbB}}ri!6#cjYNKxH+dMXhntu59dfWHkT)PgGfFRb+3KSzb$mip9 zUq{#Hd)l_|Km$r^GRs%6ZqsJgY}ja@JbVxphVq%f;_0&hOgb(bTDI=_@Z;?$t*3xW z6KX}MG|ero{Cw*cH?CYd5^EDPVP0>ah{HFt7n@tQ5^7DTG?PkAMX2z7AJ27Jy?#Bw zuGpZQFenM$i??L7qI*4*IzRDXFs0nP;?wT*Ja%ED2-1rnzQ)s@qxI#OW5=KzXc+n21`lVxy&#y3k9r^ksC^> z5vwq^JGXQZ;+-X=-pC*lf<$#SI-QQCzMKWto|3XNV;DTPZ3eU1o0eq_0#2f;l8VMv z;1v-XL}eOTGavt6Pb}B}16CxHpT@8O)BMpi%>f_}+(}l?Bh}Ohwu1;m5(p9kf@#$! zr#XA;tL|==83x0S!(T%~H?!I70AK-kfL{{nG{I+QKx+_Fe})hOAq2BMz1BCYs>r!6 zt=qN%ydT9&|A(pi`ud|m5Hy;mITShjEs8ua{-VH2U?uQg^u~XR3f2b7&+9NbtuKMe j$jL+CLF7!m$d>;B!^B5bH!%%h00000NkvXXu0mjfuh)e| literal 0 HcmV?d00001 diff --git a/src/QtViewer/resources/qtviewer_glpan.png b/src/QtViewer/resources/qtviewer_glpan.png new file mode 100644 index 0000000000000000000000000000000000000000..28ab547eab2e4614b8061252f5cbb4da079c7666 GIT binary patch literal 1086 zcmV-E1i|}>P)z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZc>jKeOv$OzL15I`)*h9FA-UC3*1Z~uwm?OTSQ4<0bQ ze(?e}13&j7BtjOg8oBY{u_wj195)S?b{&f6+rwNh(Uq* zK0ZGF9!TB4fBzVey$%pSph#d!NlE$3!NI}s_3KxL7r?*=#V#=XRDg2aKr9Qy%0Mg# zwcu`6R@RnZzkY$$K7Ra|;oiM_44*%L1}7(g00Oy$^}~k`3@Z!_7=WS-7i47_^npo& z_1d*NKskL-Yy$BYAm#zl;o;#2riOWv!1Q5tTw%b52J!EBN z_zMj9Ye2(a0MpVAL405VabQDXA%mWt-g{_beh*a#GW3?PurN#?D4ah51P}|7@?T7UooaWF76FUtY(e=N8Ih<%~* zEa-Xx0ti>}^$+SLM<6zX=4AnBQUWFN&ro@cDgYqB0GrW?VpB4t`v3p{07*qoM6N<$ Eg6tg6&Hw-a literal 0 HcmV?d00001 diff --git a/src/QtViewer/resources/qtviewer_pan.png b/src/QtViewer/resources/qtviewer_pan.png new file mode 100644 index 0000000000000000000000000000000000000000..ec56cacc779342a978f183ecf747860c8b6dafb4 GIT binary patch literal 982 zcmV;{11bE8P)z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZb!otG-18H_3W&!c>DFz52f`;Yh z=KlYG@Zf(vJw1@2;y}!e&rpB>!e<*(Vq)UoNnv3OZ?0TnIIE=v5_imOsnQ(>_Q@}D9Q|HpzmfY=u#@9*!A5&HlE#0WDiKR^HPSD@Ek zzkbaCa@oa;7a4y4{_O{p(+6UCAm#(&Px|`$DQaqJ3~X#{4Da5(V|e)RA;Yz6*FdiR z0t!=r00NsF6BF}yLQoI`!>?Zq4Bx&nFns>Zz!(z)vWNqS-$A_va>-9lVB{=URRycP zpsdWG&(6-kdhOZ^SVRE?5Q~nE&fmqMp$spM9AUWs@+E@^Q1mI#KqwFe;@8la1=_~I z2J*$jJ9ilVe*DOA?ZXF#7k~dU%-7RnNW63j9QyzP#B$}z6$wUv{}&HSOBrrFdBPyW z&(HAr=TDe{d{D#gLnA=o6)=Lf|NhPJ2I#_XKyN<>8oU@7aj@722p~`x$^o%15O2W} zQ4K(R5QwirT?%sXD=g|(05K?CodF0SP#A)o^9gFhL?B)Zjj^{zMn(Vgg6j zxpU_jK79D#4wN$jVr3vsfvN|&{yoSXfB<5F#?CWnLd}P!GmwE_`1tr3R)vHxJUVoU z;RMiI;U7Ty82F(McnHLu(3}E_l-nS400M{wntfhCo&E)yX#avZ-#{@A45MF<9x;Hz z4lSY{BV~fOP)EH02p|@y4KPE$Kyv_tjEu~^`}glN965WI;l_&>3~!m4VFpeGVn3)0 zVaeeeEFA&_5G?D#4E+fW52hzio+tt7dm^Ah;l~e#JMZ4X4D5u`pP`QU2lWw%{s$01 zxUwNTH0uR`vRkc+3M|{L0pd2OxFS>?3IGToW*i2Bk`pV``xg$qd*=yF8X#vr0J$9M zy07T20tg^xJOwPwRUpGpK{Y>y#^wX4;lH73-~b@N0A_|Q{Wj4Xb^rhX07*qoM6N<$ Ef)-GsSpWb4 literal 0 HcmV?d00001 diff --git a/src/QtViewer/resources/qtviewer_reset.png b/src/QtViewer/resources/qtviewer_reset.png new file mode 100644 index 0000000000000000000000000000000000000000..66f81e60471b7b587c37166a4e206b45f74e7fc2 GIT binary patch literal 918 zcmV;H18Mw;P)z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ<3`s;mRCwBA`2YVu0}KO!sHi9>h~bSaP6`GHAOZXQ009Iu ztVK?a_y6WCKL3CH$@>5IfA;^Iw`2aBnTdlW&7exTp@zi+u{AD30Ro7Lk&#hUNQk5Q z?D;STpjR1~nHj+nii&(-KGfwPzyqZXfLH~Ij{*P!hzW=@vvYJAfQEtvwrzdL@b~Y3 zhTx#>3=Q?CrT~SeL)CtP(l4O+3pN7*0*D2Ojg5^(!JOKflMHLu++jF%N|j;rru$QX z!I2B}0Zi>zGy}h4GY}wvKrZ|XauEp3n0^K5WhREsj&mSx69e%89{T_R1ajfcn>Rmz zIq%;60AXz)^A6B;zi?=K-}sfC-?tzTH62r z+1dZM`}+RpVPyp=a)o&VAb=Q=3jlDg;ox}n@#jy5zyJSR0p*SZ#Xz=e0L9NFXlO8m zC@V8qN=Sg!-~8}_;lk_J40EqvXW0Gtu^UimH$VWPmo_{g8)rH={0C|R3ET$aE+9^W z#_sAO0|T(@KsZfX8>D6hvI_wMh!MSr0=mcm=$i9OU0oSe`1u*u-@C_f=i^5PHYO$p zdueHgKqVyxW?=4l`t>V=_OfLRAAkK40Gja;rXL`H7_pRjAVWa`o#`Ya<56K`#Na9` ziz0vj(Tlf8<Y>>a4;Bfq33xx91b|2&+m7*TCKRy z_x-2Bw`W+Z)i9Y%aJ$`}ibb$;xeOsN3`6d2v)M>pk>l~m{`Go|MBsEfFK6hwt`u;&T(W<$SR?~U z)oK;(b~`op{eFk4s;E>d;w_UL$KltZC<@{@PK44$uh;ABvu*n|kYrgFN6|D5^Z6X7 z(+Q8q1DDGM6tmH2Fih9=KR*;k3W9()PT*WF$IJS8)2&tuolYmQ`_#eH9WzZ6-ENmP m91gMFZiVwr1^!nb2YvziR8V0}frc3X0000z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ;lSxEDRCwBA{Qv(y12q9a05LI882|(j3yAp6z=+{Y zPKN)C$b3dd#y}ty1;mO#{0NBG0DZR%T^~RIu^?$iH}pTm97baxo$2V|nd}h|$RH&v z$MF2=6XU&Gw*&&^{D5-Pfd(IhX#xl!22dE{!$2^nw!8QLxyR4`p9SL6kDmTN`QXX_ zWA`8bZ*#;G5q}bli};<&kW}F_F#1|4FCbe zLcl;aW)@bkYk=l~UHJR=Z-(z*zXA>X!SLtTZ?G6R8lV6mfC#zp)YS{;8GeIY^y?SH zmrtJL&@bUdShR+{AGJO5=h2iF{4FCbeh%aFS!;qhwm-oZ8)$14pg@qY@ zeEZJuHQCMa{8~Mt^J>giRqA}jO>3c z1H=E4va%p=odM!xbbSB;gf&vMwY4kQSXkOs#l;z(e)s?i_{6_||1JOqf%@|&kL7?$ zo&q&r!=@J?fH1-kXjm!Gur4*AVb6g9|Mtt5%Bxqec3{&C%ChKL6d-_@&RKiH#D= b009O7QZ{F9XF19?00000NkvXXu0mjfwM|pG literal 0 HcmV?d00001 -- 2.39.2