From: admin Date: Mon, 5 Dec 2005 16:39:25 +0000 (+0000) Subject: This commit was generated by cvs2git to create branch 'BR-D5-38-2003'. X-Git-Tag: TG-D5-38-2003_D2005-29-12~18 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=7df5b5c0ef430e7e29f702ecbf788a64a2777aca;p=modules%2Fgui.git This commit was generated by cvs2git to create branch 'BR-D5-38-2003'. Cherrypick from master 2005-12-05 16:39:20 UTC smh 'Copyrights update': doc/salome/GUI_index_v3.1.0.html doc/salome/Makefile.in idl/SalomeApp_Engine.idl src/CAF/CAF.h src/CAF/CAF_Application.cxx src/CAF/CAF_Application.h src/CAF/CAF_Operation.cxx src/CAF/CAF_Operation.h src/CAF/CAF_Study.h src/CAF/CAF_Tools.cxx src/CAF/CAF_Tools.h src/CAM/CAM.h src/CAM/CAM_Application.cxx src/CAM/CAM_Application.h src/CAM/CAM_DataModel.cxx src/CAM/CAM_DataModel.h src/CAM/CAM_DataObject.cxx src/CAM/CAM_DataObject.h src/CAM/CAM_Module.cxx src/CAM/CAM_Module.h src/CAM/CAM_RootObject.cxx src/CAM/CAM_RootObject.h src/CAM/CAM_Study.cxx src/CAM/CAM_Study.h src/GLViewer/GLViewer_Drawer.cxx src/LightApp/LightApp_DataOwner.cxx src/LightApp/LightApp_DataOwner.h src/LightApp/LightApp_DataSubOwner.cxx src/LightApp/LightApp_DataSubOwner.h src/LightApp/LightApp_Dialog.cxx src/LightApp/LightApp_Dialog.h src/LightApp/LightApp_Displayer.cxx src/LightApp/LightApp_Displayer.h src/LightApp/LightApp_Driver.cxx src/LightApp/LightApp_Driver.h src/LightApp/LightApp_GLSelector.cxx src/LightApp/LightApp_GLSelector.h src/LightApp/LightApp_Module.cxx src/LightApp/LightApp_ModuleDlg.cxx src/LightApp/LightApp_NameDlg.cxx src/LightApp/LightApp_OBFilter.cxx src/LightApp/LightApp_OBFilter.h src/LightApp/LightApp_OCCSelector.cxx src/LightApp/LightApp_OCCSelector.h src/LightApp/LightApp_Preferences.cxx src/LightApp/LightApp_Preferences.h src/LightApp/LightApp_RootObject.h src/LightApp/LightApp_SelectionMgr.cxx src/LightApp/LightApp_SelectionMgr.h src/LightApp/LightApp_ShowHideOp.h src/LightApp/LightApp_Study.cxx src/LightApp/LightApp_Study.h src/LightApp/LightApp_SwitchOp.cxx src/LightApp/LightApp_SwitchOp.h src/LightApp/LightApp_WidgetContainer.cxx src/LightApp/LightApp_WidgetContainer.h src/OBJECT/SALOME_GLOwner.cxx src/OBJECT/SALOME_GLOwner.h src/OCCViewer/OCCViewer.h src/OCCViewer/OCCViewer_AISSelector.cxx src/OCCViewer/OCCViewer_AISSelector.h src/OCCViewer/OCCViewer_CreateRestoreViewDlg.cxx src/OCCViewer/OCCViewer_CreateRestoreViewDlg.h src/OCCViewer/OCCViewer_VService.cxx src/OCCViewer/OCCViewer_VService.h src/OCCViewer/OCCViewer_ViewManager.cxx src/OCCViewer/OCCViewer_ViewManager.h src/OCCViewer/OCCViewer_ViewModel.h src/OCCViewer/OCCViewer_ViewPort.cxx src/OCCViewer/OCCViewer_ViewPort.h src/OCCViewer/OCCViewer_ViewPort3d.cxx src/OCCViewer/OCCViewer_ViewPort3d.h src/ObjBrowser/OB.h src/ObjBrowser/OB_Filter.cxx src/ObjBrowser/OB_Filter.h src/Plot2d/Plot2d.h src/Plot2d/Plot2d_FitDataDlg.h src/Plot2d/Plot2d_Prs.h src/Plot2d/Plot2d_SetupViewDlg.h src/Plot2d/Plot2d_ViewManager.cxx src/Plot2d/Plot2d_ViewManager.h src/Plot2d/Plot2d_ViewModel.cxx src/Plot2d/Plot2d_ViewModel.h src/Prs/SALOME_Prs.cxx src/Prs/SALOME_Prs.h src/PyInterp/PyInterp.h src/PyInterp/PyInterp_Watcher.h src/PythonConsole/PythonConsole.h src/PythonConsole/PythonConsole_PyConsole.cxx src/PythonConsole/PythonConsole_PyConsole.h src/Qtx/Qtx.cxx src/Qtx/Qtx.h src/Qtx/QtxAction.cxx src/Qtx/QtxAction.h src/Qtx/QtxActionMenuMgr.cxx src/Qtx/QtxActionMenuMgr.h src/Qtx/QtxActionMgr.cxx src/Qtx/QtxActionMgr.h src/Qtx/QtxActionToolMgr.cxx src/Qtx/QtxActionToolMgr.h src/Qtx/QtxColorScale.h src/Qtx/QtxComboBox.cxx src/Qtx/QtxComboBox.h src/Qtx/QtxDblSpinBox.h src/Qtx/QtxDialog.cxx src/Qtx/QtxDialog.h src/Qtx/QtxDirListEditor.cxx src/Qtx/QtxDirListEditor.h src/Qtx/QtxDockAction.cxx src/Qtx/QtxDockAction.h src/Qtx/QtxDockWindow.cxx src/Qtx/QtxDockWindow.h src/Qtx/QtxGroupBox.cxx src/Qtx/QtxGroupBox.h src/Qtx/QtxIntSpinBox.cxx src/Qtx/QtxIntSpinBox.h src/Qtx/QtxListAction.cxx src/Qtx/QtxListAction.h src/Qtx/QtxListBox.cxx src/Qtx/QtxListBox.h src/Qtx/QtxListOfOperations.cxx src/Qtx/QtxListOfOperations.h src/Qtx/QtxListView.cxx src/Qtx/QtxListView.h src/Qtx/QtxLogoMgr.cxx src/Qtx/QtxLogoMgr.h src/Qtx/QtxMRUAction.cxx src/Qtx/QtxMRUAction.h src/Qtx/QtxMenuButton.cxx src/Qtx/QtxMenuButton.h src/Qtx/QtxOperations.cxx src/Qtx/QtxOperations.h src/Qtx/QtxParser.cxx src/Qtx/QtxParser.h src/Qtx/QtxPathDialog.cxx src/Qtx/QtxPathDialog.h src/Qtx/QtxPopupMenu.cxx src/Qtx/QtxPopupMenu.h src/Qtx/QtxResourceEdit.cxx src/Qtx/QtxResourceEdit.h src/Qtx/QtxResourceMgr.cxx src/Qtx/QtxResourceMgr.h src/Qtx/QtxStdOperations.cxx src/Qtx/QtxStdOperations.h src/Qtx/QtxTable.cxx src/Qtx/QtxTable.h src/Qtx/QtxToolBar.cxx src/Qtx/QtxToolBar.h src/Qtx/QtxToolTip.cxx src/Qtx/QtxToolTip.h src/Qtx/QtxWorkspaceAction.cxx src/Qtx/QtxWorkspaceAction.h src/Qtx/QtxWorkstackAction.cxx src/Qtx/QtxWorkstackAction.h src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_GUI.h src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_Module.h src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_PyInterp.h src/SALOME_PYQT/SalomePyQt/SalomePyQt.h src/SOCC/SOCC.h src/SOCC/SOCC_ViewModel.cxx src/SOCC/SOCC_ViewModel.h src/SOCC/SOCC_ViewWindow.cxx src/SOCC/SOCC_ViewWindow.h src/SPlot2d/SPlot2d.h src/SPlot2d/SPlot2d_Curve.cxx src/SPlot2d/SPlot2d_Curve.h src/SPlot2d/SPlot2d_Prs.cxx src/SPlot2d/SPlot2d_Prs.h src/SPlot2d/SPlot2d_ViewModel.cxx src/SPlot2d/SPlot2d_ViewModel.h src/SPlot2d/SPlot2d_msg_en.po src/STD/STD.h src/STD/STD_CloseDlg.cxx src/STD/STD_CloseDlg.h src/STD/STD_LoadStudiesDlg.cxx src/STD/STD_LoadStudiesDlg.h src/STD/STD_MDIDesktop.cxx src/STD/STD_MDIDesktop.h src/STD/STD_SDIDesktop.cxx src/STD/STD_SDIDesktop.h src/STD/STD_TabDesktop.h src/SUIT/SUIT.h src/SUIT/SUIT_Accel.cxx src/SUIT/SUIT_Accel.h src/SUIT/SUIT_ActionOperation.cxx src/SUIT/SUIT_ActionOperation.h src/SUIT/SUIT_Application.cxx src/SUIT/SUIT_Application.h src/SUIT/SUIT_Convertor.h src/SUIT/SUIT_DataObject.cxx src/SUIT/SUIT_DataObject.h src/SUIT/SUIT_DataObjectIterator.cxx src/SUIT/SUIT_DataObjectIterator.h src/SUIT/SUIT_DataObjectKey.cxx src/SUIT/SUIT_DataObjectKey.h src/SUIT/SUIT_Desktop.cxx src/SUIT/SUIT_Desktop.h src/SUIT/SUIT_ExceptionHandler.cxx src/SUIT/SUIT_ExceptionHandler.h src/SUIT/SUIT_FileDlg.cxx src/SUIT/SUIT_FileDlg.h src/SUIT/SUIT_Operation.cxx src/SUIT/SUIT_Operation.h src/SUIT/SUIT_OverrideCursor.cxx src/SUIT/SUIT_OverrideCursor.h src/SUIT/SUIT_PopupClient.cxx src/SUIT/SUIT_PopupClient.h src/SUIT/SUIT_ResourceMgr.cxx src/SUIT/SUIT_ResourceMgr.h src/SUIT/SUIT_SelectionFilter.cxx src/SUIT/SUIT_SelectionFilter.h src/SUIT/SUIT_Selector.cxx src/SUIT/SUIT_Selector.h src/SUIT/SUIT_Session.cxx src/SUIT/SUIT_Session.h src/SUIT/SUIT_SmartPtr.h src/SUIT/SUIT_Study.cxx src/SUIT/SUIT_Study.h src/SUIT/SUIT_ToolButton.cxx src/SUIT/SUIT_ToolButton.h src/SUIT/SUIT_Tools.cxx src/SUIT/SUIT_Tools.h src/SUIT/SUIT_ViewManager.cxx src/SUIT/SUIT_ViewManager.h src/SUIT/SUIT_ViewModel.cxx src/SUIT/SUIT_ViewModel.h src/SUITApp/SUITApp_Application.cxx src/SUITApp/SUITApp_Application.h src/SUPERVGraph/SUPERVGraph_ViewManager.cxx src/SUPERVGraph/SUPERVGraph_ViewManager.h src/SUPERVGraph/SUPERVGraph_ViewModel.cxx src/SUPERVGraph/SUPERVGraph_ViewModel.h src/SVTK/SVTK.h src/SVTK/SVTK_Trihedron.cxx src/SVTK/SVTK_Trihedron.h src/SalomeApp/SalomeApp_CheckFileDlg.cxx src/SalomeApp/SalomeApp_CheckFileDlg.h src/SalomeApp/SalomeApp_Displayer.cxx src/SalomeApp/SalomeApp_Displayer.h src/SalomeApp/SalomeApp_EventFilter.cxx src/SalomeApp/SalomeApp_EventFilter.h src/SalomeApp/SalomeApp_ExceptionHandler.cxx src/SalomeApp/SalomeApp_ExceptionHandler.h src/SalomeApp/SalomeApp_Filter.cxx src/SalomeApp/SalomeApp_Filter.h src/SalomeApp/SalomeApp_Study.cxx src/SalomeApp/SalomeApp_Study.h src/SalomeApp/SalomeApp_Tools.cxx src/SalomeApp/SalomeApp_Tools.h src/SalomeApp/SalomeApp_TypeFilter.cxx src/SalomeApp/SalomeApp_TypeFilter.h src/Style/SalomeStyle.cxx src/Style/SalomeStyle.h --- diff --git a/doc/salome/GUI_index_v3.1.0.html b/doc/salome/GUI_index_v3.1.0.html new file mode 100755 index 000000000..465e3ea9d --- /dev/null +++ b/doc/salome/GUI_index_v3.1.0.html @@ -0,0 +1,95 @@ + + + + + + + + Gui Module Documentation + + + +
  +
+
                   +   
+ + + + + + + + + +
+ + + +
+ +
+
+
+

GUI MODULE Documentation

+
+
+ + + + + +
+
+ +
+

Application-About.png +     

+
+ +
+ + + + +
+
+
+
+
+ +
+ +
GUI Documentation
+ +
+ +
+ +

+
+ +
+ +
TUI Documentation
+ +
+ +
+ +

+
+
+
+
+
+
+ + diff --git a/doc/salome/Makefile.in b/doc/salome/Makefile.in new file mode 100644 index 000000000..ca1d6f282 --- /dev/null +++ b/doc/salome/Makefile.in @@ -0,0 +1,44 @@ + +# -* Makefile *- +# +# Author : Patrick GOLDBRONN (CEA) +# Date : 30/11/2001 +# $Header$ +# +# source path +top_srcdir=@top_srcdir@ +top_builddir=../.. +srcdir=@srcdir@ +VPATH=.:@srcdir@ + +SUBDIRS= tui gui + +@COMMENCE@ + +docs: + @@SETX@; for d in $(SUBDIRS); do \ + (cd $$d && $(MAKE) $@) || exit 1; \ + done; \ + cp -f $(srcdir)/GUI_index_v3.1.0.html GUI_index_v3.1.0.html + +clean: + @@SETX@; for d in $(SUBDIRS); do \ + (cd $$d && $(MAKE) $@) || exit 1; \ + done + +distclean: clean + @@SETX@; for d in $(SUBDIRS); do \ + (cd $$d && $(MAKE) $@) || exit 1; \ + done + +install: + $(MAKE) docs + (cd tui && $(MAKE) install); + (cd gui && $(MAKE) install); + cp -f GUI_index_v3.1.0.html $(docdir) + +uninstall: + @@SETX@; for d in $(SUBDIRS); do \ + (cd $$d && $(MAKE) $@) || exit 1; \ + done; \ + rm -fr $(docdir)/GUI_index_v3.1.0.html diff --git a/idl/SalomeApp_Engine.idl b/idl/SalomeApp_Engine.idl new file mode 100644 index 000000000..d52b2eac2 --- /dev/null +++ b/idl/SalomeApp_Engine.idl @@ -0,0 +1,41 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File : SalomeApp_Engine.idl +// Author : Alexander SLADKOV + +#ifndef __SalomeApp_Engine__ +#define __SalomeApp_Engine__ + +#include "SALOME_Component.idl" +#include "SALOMEDS.idl" + +module SalomeApp +{ + + /*! + * SalomeApp::Engine: special CORBA pseudo-engine for persistance needs of components + * with no CORBA-based Engine. + */ + interface Engine : Engines::Component, + SALOMEDS::Driver + { + }; +}; + +#endif diff --git a/src/CAF/CAF.h b/src/CAF/CAF.h new file mode 100755 index 000000000..0eee94656 --- /dev/null +++ b/src/CAF/CAF.h @@ -0,0 +1,55 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef CAF_H +#define CAF_H + +#if defined CAF_EXPORTS +#if defined WNT +#define CAF_EXPORT __declspec( dllexport ) +#else +#define CAF_EXPORT +#endif +#else +#if defined WNT +#define CAF_EXPORT __declspec( dllimport ) +#else +#define CAF_EXPORT +#endif +#endif + +#if defined SOLARIS +#define bool int +#define false 0 +#define true 1 +#endif + +#if defined WNT +#pragma warning ( disable: 4251 ) +#endif + +#if defined ( _DEBUG ) || defined ( DEBUG ) +#include +#define CAF_VERIFY(x) assert(x); +#define CAF_ASSERT(x) assert(x); +#else +#define CAF_VERIFY(x) x +#define CAF_ASSERT(x) +#endif + +#endif diff --git a/src/CAF/CAF_Application.cxx b/src/CAF/CAF_Application.cxx new file mode 100755 index 000000000..823d09355 --- /dev/null +++ b/src/CAF/CAF_Application.cxx @@ -0,0 +1,271 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "CAF_Application.h" + +#include "CAF_Tools.h" +#include "CAF_Study.h" + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include + +#include + +extern "C" CAF_EXPORT SUIT_Application* createApplication() +{ + return new CAF_Application(); +} + +CAF_Application::CAF_Application() +: STD_Application() +{ +} + +CAF_Application::CAF_Application( const Handle(TDocStd_Application)& app ) +: STD_Application(), +myStdApp( app ) +{ +} + +CAF_Application::~CAF_Application() +{ +} + +QString CAF_Application::applicationName() const +{ + return QString( "CAFApplication" ); +} + +Handle(TDocStd_Application) CAF_Application::stdApp() const +{ + return myStdApp; +} + +QString CAF_Application::getFileFilter() const +{ + if ( stdApp().IsNull() ) + return QString::null; + + TColStd_SequenceOfExtendedString formats; + stdApp()->Formats( formats ); + + QStringList allWC; + QMap wildCards; + Handle(Resource_Manager) resMgr = new Resource_Manager( stdApp()->ResourcesName() ); + for ( int i = 1; i <= formats.Length(); i++ ) + { + QString extension; + QString extResStr = CAF_Tools::toQString( formats.Value( i ) ) + QString( ".FileExtension" ); + if ( resMgr->Find( (char*)extResStr.latin1() ) ) + extension = QString( resMgr->Value( (char*)extResStr.latin1() ) ); + + QString descr; + QString descrResStr = CAF_Tools::toQString( formats.Value( i ) ) + QString( ".Description" ); + if ( resMgr->Find( (char*)descrResStr.latin1() ) ) + descr = QString( resMgr->Value( (char*)descrResStr.latin1() ) ); + + if ( !descr.isEmpty() && !extension.isEmpty() ) + { + if ( !wildCards.contains( descr ) ) + wildCards.insert( descr, QStringList() ); + wildCards[descr].append( QString( "*.%1" ).arg( extension ) ); + allWC.append( QString( "*.%1" ).arg( extension ) ); + } + } + + if ( wildCards.isEmpty() ) + return QString::null; + + QStringList filters; + for ( QMap::ConstIterator it = wildCards.begin(); it != wildCards.end(); ++it ) + filters.append( QString( "%1 (%2)" ).arg( it.key() ).arg( it.data().join( "; " ) ) ); + + if ( wildCards.count() > 1 ) + filters.prepend( QString( "%1 (%2)" ).arg( tr( "INF_ALL_DOCUMENTS_FILTER" ) ).arg( allWC.join( "; " ) ) ); + + if ( !filters.isEmpty() ) + filters.append( tr( "INF_ALL_FILTER" ) ); + + return filters.join( ";;" ); +} + +void CAF_Application::createActions() +{ + STD_Application::createActions(); + + SUIT_Desktop* desk = desktop(); + SUIT_ResourceMgr* resMgr = resourceMgr(); + + QtxListAction* editUndo = + new QtxListAction( tr( "TOT_APP_EDIT_UNDO" ), resMgr->loadPixmap( "CAF", tr( "ICON_APP_EDIT_UNDO" ) ), + tr( "MEN_APP_EDIT_UNDO" ), CTRL+Key_Z, desk ); + registerAction( EditUndoId, editUndo ); + + QtxListAction* editRedo = + new QtxListAction( tr( "TOT_APP_EDIT_REDO" ), resMgr->loadPixmap( "CAF", tr( "ICON_APP_EDIT_REDO" ) ), + tr( "MEN_APP_EDIT_REDO" ), CTRL+Key_Y, desk ); + registerAction( EditRedoId, editRedo ); + + editUndo->setComment( tr( "INF_APP_UNDOACTIONS" ) ); + editRedo->setComment( tr( "INF_APP_REDOACTIONS" ) ); + + connect( editUndo, SIGNAL( activated( int ) ), this, SLOT( onUndo( int ) ) ); + connect( editRedo, SIGNAL( activated( int ) ), this, SLOT( onRedo( int ) ) ); + + + int editMenu = createMenu( tr( "MEN_DESK_EDIT" ), -1, -1, 10 ); + + createMenu( EditUndoId, editMenu, 0 ); + createMenu( EditRedoId, editMenu, 0 ); + createMenu( separator(), editMenu, -1, 0 ); + + int stdTBar = createTool( tr( "INF_DESK_TOOLBAR_STANDARD" ) ); + + createTool( separator(), stdTBar ); + createTool( EditUndoId, stdTBar ); + createTool( EditRedoId, stdTBar ); + createTool( separator(), stdTBar ); +} + +/*! + Undo operation on the given document. [ virtual protected ] +*/ +bool CAF_Application::undo( CAF_Study* doc ) +{ + bool success = false; + if ( doc ) + { + if ( success = doc->undo() ) + doc->update(); + } + return success; +} + +/*! + Redo operation on the given document. [ virtual protected ] +*/ +bool CAF_Application::redo(CAF_Study* doc) +{ + bool success = false; + if ( doc ) + { + if ( success = doc->redo() ) + doc->update(); + } + return success; +} + +/*! + Undo operation on the active document. [ virtual protected slot ] +*/ +bool CAF_Application::onUndo( int numActions ) +{ + bool ok = true; + while ( numActions > 0 ) + { + CAF_Study* cafStudy = dynamic_cast( activeStudy() ); + if ( cafStudy ) + { + if ( !undo( cafStudy ) ) + { + ok = false; + break; + } + numActions--; + } + } + updateCommandsStatus(); /* enable/disable undo/redo */ + return ok; +} + +/*! + Redo operation on the active document. [ virtual protected slot ] +*/ +bool CAF_Application::onRedo( int numActions ) +{ + bool ok = true; + while ( numActions > 0 ) + { + CAF_Study* cafStudy = dynamic_cast( activeStudy() ); + if ( cafStudy ) + { + if ( !redo( cafStudy ) ) + { + ok = false; + break; + } + numActions--; + } + } + updateCommandsStatus(); /* enable/disable undo/redo */ + return ok; +} + +/*! + Enables / disables the actions according to the application state. [ virtual protected ] +*/ +void CAF_Application::updateCommandsStatus() +{ + STD_Application::updateCommandsStatus(); + + CAF_Study* cafStudy = 0; + if ( activeStudy() && activeStudy()->inherits( "CAF_Study" ) ) + cafStudy = (CAF_Study*)activeStudy(); + + QAction* undo = action( EditUndoId ); + if ( cafStudy && undo ) + undo->setProperty( "names", cafStudy->undoNames() ); + + QAction* redo = action( EditRedoId ); + if ( cafStudy && redo ) + redo->setProperty( "names", cafStudy->redoNames() ); + + if ( undo ) + undo->setEnabled( cafStudy && cafStudy->canUndo() ); + if ( redo ) + redo->setEnabled( cafStudy && cafStudy->canRedo() ); +} + +void CAF_Application::onHelpAbout() +{ + SUIT_MessageBox::info1( desktop(), tr( "About" ), tr( "ABOUT_INFO" ), "&OK" ); +} + +SUIT_Study* CAF_Application::createNewStudy() +{ + return new CAF_Study( this ); +} + +void CAF_Application::setStdApp( const Handle(TDocStd_Application)& app ) +{ + myStdApp = app; +} diff --git a/src/CAF/CAF_Application.h b/src/CAF/CAF_Application.h new file mode 100755 index 000000000..1ec88331d --- /dev/null +++ b/src/CAF/CAF_Application.h @@ -0,0 +1,82 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef CAF_APPLICATION_H +#define CAF_APPLICATION_H + +#include "CAF.h" + +#include "STD_Application.h" + +#include +#include + +#include + +class QtxAction; +class CAF_Study; + +#if defined WIN32 +#pragma warning ( disable: 4251 ) +#endif + +class CAF_EXPORT CAF_Application : public STD_Application +{ + Q_OBJECT + +public: + CAF_Application(); + CAF_Application( const Handle(TDocStd_Application)& ); + virtual ~CAF_Application(); + + virtual QString applicationName() const; + + Handle(TDocStd_Application) stdApp() const; + + virtual QString getFileFilter() const; + +public slots: + virtual void onHelpAbout(); + +protected slots: + virtual bool onUndo( int ); + virtual bool onRedo( int ); + +protected: + enum { EditUndoId = STD_Application::UserID, EditRedoId, UserID }; + +protected: + virtual void createActions(); + virtual void updateCommandsStatus(); + + virtual SUIT_Study* createNewStudy(); + + bool undo( CAF_Study* doc ); + bool redo( CAF_Study* doc ); + + virtual void setStdApp( const Handle(TDocStd_Application)& ); + +private: + Handle(TDocStd_Application) myStdApp; +}; + +#if defined WIN32 +#pragma warning ( default: 4251 ) +#endif + +#endif diff --git a/src/CAF/CAF_Operation.cxx b/src/CAF/CAF_Operation.cxx new file mode 100755 index 000000000..24bc5ecd8 --- /dev/null +++ b/src/CAF/CAF_Operation.cxx @@ -0,0 +1,46 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "CAF_Operation.h" + +#include "CAF_Study.h" +#include "CAF_Application.h" + +#include + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +CAF_Operation::CAF_Operation(SUIT_Application* theApp) +:SUIT_Operation(theApp) +{ +} + +CAF_Operation::~CAF_Operation() +{ +} + +Handle(TDocStd_Document) CAF_Operation::stdDoc() const +{ + Handle(TDocStd_Document) doc; + CAF_Study* s = ::qt_cast( study() ); + if ( s ) + doc = s->stdDoc(); + return doc; +} diff --git a/src/CAF/CAF_Operation.h b/src/CAF/CAF_Operation.h new file mode 100755 index 000000000..f49e315d7 --- /dev/null +++ b/src/CAF/CAF_Operation.h @@ -0,0 +1,46 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef CAF_OPERATION_H +#define CAF_OPERATION_H + +#include "CAF.h" + +#include "SUIT_Operation.h" + +#include +#include + +#include + +class CAF_Study; +class Handle(TDocStd_Document); + +class CAF_EXPORT CAF_Operation : public SUIT_Operation +{ + Q_OBJECT + +public: + CAF_Operation( SUIT_Application* ); + virtual ~CAF_Operation(); + +protected: + Handle(TDocStd_Document) stdDoc() const; +}; + +#endif diff --git a/src/CAF/CAF_Study.h b/src/CAF/CAF_Study.h new file mode 100755 index 000000000..fe47c5b0b --- /dev/null +++ b/src/CAF/CAF_Study.h @@ -0,0 +1,89 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef CAF_STUDY_H +#define CAF_STUDY_H + +#include "CAF.h" + +#include "SUIT_Study.h" + +#include + +#include +#include + +class CAF_Application; + +#if defined WNT +#pragma warning ( disable: 4251 ) +#endif + +class CAF_EXPORT CAF_Study : public SUIT_Study +{ + Q_OBJECT + +public: + CAF_Study( SUIT_Application* theApp ); + CAF_Study( SUIT_Application* theApp, Handle(TDocStd_Document)& aStdDoc ); + virtual ~CAF_Study(); + + virtual void createDocument(); + virtual void closeDocument( bool = true ); + virtual bool openDocument( const QString& ); + + virtual bool saveDocumentAs( const QString& ); + + bool isSaved() const; + bool isModified() const; + void doModified( bool = true ); + void undoModified(); + void clearModified(); + + bool undo(); + bool redo(); + bool canUndo() const; + bool canRedo() const; + QStringList undoNames() const; + QStringList redoNames() const; + + Handle(TDocStd_Document) stdDoc() const; + +protected: + Handle(TDocStd_Application) stdApp() const; + CAF_Application* cafApplication() const; + + virtual bool openTransaction(); + virtual bool abortTransaction(); + virtual bool hasTransaction() const; + virtual bool commitTransaction( const QString& = QString::null ); + + virtual void setStdDoc( Handle(TDocStd_Document)& ); + +private: + Handle(TDocStd_Document) myStdDoc; + int myModifiedCnt; + + friend class CAF_Operation; +}; + +#if defined WNT +#pragma warning ( default: 4251 ) +#endif + +#endif diff --git a/src/CAF/CAF_Tools.cxx b/src/CAF/CAF_Tools.cxx new file mode 100755 index 000000000..41b56f6e1 --- /dev/null +++ b/src/CAF/CAF_Tools.cxx @@ -0,0 +1,44 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File : CAF_Tools.cxx +// Author : UI team + +#include "CAF_Tools.h" + +#include +#include + +/*! + Converts TCollection_ExtendedString 'src' to Qt string. [ static ] +*/ +QString CAF_Tools::toQString ( const TCollection_ExtendedString& src ) +{ + return QString( (const QChar*)src.ToExtString(), src.Length() ); +} + +/*! + Converts Qt string to TCollection_ExtendedString. [ static ] +*/ +TCollection_ExtendedString CAF_Tools::toExtString ( const QString& src ) +{ + TCollection_ExtendedString result; + for ( int i = 0; i < (int)src.length(); i++ ) + result.Insert( i + 1, src[ i ].unicode() ); + return result; +} diff --git a/src/CAF/CAF_Tools.h b/src/CAF/CAF_Tools.h new file mode 100755 index 000000000..8af84f9fe --- /dev/null +++ b/src/CAF/CAF_Tools.h @@ -0,0 +1,38 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File : CAF_Tools.h +// Author : UI team + +#ifndef CAF_TOOLS_H +#define CAF_TOOLS_H + +#include + +#include + +#include + +class CAF_EXPORT CAF_Tools : public SUIT_Tools +{ +public: + static QString toQString( const TCollection_ExtendedString& ); + static TCollection_ExtendedString toExtString( const QString& ); +}; + +#endif diff --git a/src/CAM/CAM.h b/src/CAM/CAM.h new file mode 100755 index 000000000..427fb53ce --- /dev/null +++ b/src/CAM/CAM.h @@ -0,0 +1,46 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef CAM_H +#define CAM_H + +#if defined CAM_EXPORTS +#if defined WNT +#define CAM_EXPORT __declspec( dllexport ) +#else +#define CAM_EXPORT +#endif +#else +#if defined WNT +#define CAM_EXPORT __declspec( dllimport ) +#else +#define CAM_EXPORT +#endif +#endif + +#if defined SOLARIS +#define bool int +#define false 0 +#define true 1 +#endif + +#if defined WNT +#pragma warning ( disable: 4251 ) +#endif + +#endif diff --git a/src/CAM/CAM_Application.cxx b/src/CAM/CAM_Application.cxx new file mode 100755 index 000000000..eb7060abd --- /dev/null +++ b/src/CAM/CAM_Application.cxx @@ -0,0 +1,516 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "CAM_Application.h" + +#include "CAM_Study.h" +#include "CAM_Module.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#ifdef WIN32 +#include +#else +#include +#endif + +/*!Create new instance of CAM_Application*/ +extern "C" CAM_EXPORT SUIT_Application* createApplication() +{ + return new CAM_Application(); +} + +/*!Constructor. read module list. + * \param autoLoad - auto load flag. + */ +CAM_Application::CAM_Application( const bool autoLoad ) +: STD_Application(), +myModule( 0 ), +myAutoLoad( autoLoad ) +{ + readModuleList(); +} + +/*!Destructor. Do nothing.*/ +CAM_Application::~CAM_Application() +{ +} + +/*! Load modules, if \a myAutoLoad flag is true.\n + * Start application - call start() method from parent class. + */ +void CAM_Application::start() +{ + if ( myAutoLoad ) + loadModules(); + + STD_Application::start(); +} + +/*!Get active module. + * \retval CAM_Module - active module. + */ +CAM_Module* CAM_Application::activeModule() const +{ + return myModule; +} + +/*!Get module with name \a modName from modules list. + * \retval CAM_Module pointer - module. + */ +CAM_Module* CAM_Application::module( const QString& modName ) const +{ + CAM_Module* mod = 0; + for ( ModuleListIterator it( myModules ); it.current() && !mod; ++it ) + if ( it.current()->moduleName() == modName ) + mod = it.current(); + return mod; +} + +/*!Gets modules iterator.*/ +CAM_Application::ModuleListIterator CAM_Application::modules() const +{ + return ModuleListIterator( myModules ); +} + +/*!Gets modules list. + * \param out - output list of modules. + */ +void CAM_Application::modules( CAM_Application::ModuleList& out ) const +{ + out.setAutoDelete( false ); + out.clear(); + + for ( ModuleListIterator it( myModules ); it.current(); ++it ) + out.append( it.current() ); +} + +/*!Gets list of names for modules.\n + * Get loaded modules names, if \a loaded is true, else \n + * get names from information list. + * \param lst - output list of names. + * \param loaded - boolean flag. + */ +void CAM_Application::modules( QStringList& lst, const bool loaded ) const +{ + lst.clear(); + + if ( loaded ) + for ( ModuleListIterator it( myModules ); it.current(); ++it ) + lst.append( it.current()->moduleName() ); + else + for ( ModuleInfoList::const_iterator it = myInfoList.begin(); it != myInfoList.end(); ++it ) + lst.append( (*it).title ); +} + +/*!Adding module \a mod to list. + *\param mod - module. + */ +void CAM_Application::addModule( CAM_Module* mod ) +{ + if ( !mod || myModules.contains( mod ) ) + return; + + mod->initialize( this ); + + QMap map; + + ModuleList newList; + for ( ModuleInfoList::const_iterator it = myInfoList.begin(); it != myInfoList.end(); ++it ) + { + if ( (*it).title == mod->moduleName() ) + newList.append( mod ); + else + { + CAM_Module* curMod = module( (*it).title ); + if ( curMod ) + newList.append( curMod ); + } + if ( !newList.isEmpty() ) + map.insert( newList.getLast(), 0 ); + } + + for ( ModuleListIterator itr( myModules ); itr.current(); ++itr ) + { + if ( !map.contains( itr.current() ) ) + newList.append( itr.current() ); + } + + if ( !map.contains( mod ) ) + newList.append( mod ); + + myModules = newList; + + moduleAdded( mod ); +} + +/*!Load modules from information list. + * \warning If some of modules not loaded, error message appear on desktop. + */ +void CAM_Application::loadModules() +{ + for ( ModuleInfoList::const_iterator it = myInfoList.begin(); it != myInfoList.end(); ++it ) + { + CAM_Module* mod = loadModule( (*it).title ); + if ( mod ) + addModule( mod ); + else + SUIT_MessageBox::error1( desktop(), tr( "Loading modules" ), + tr( "Can not load module %1" ).arg( (*it).title ), tr( "Ok" ) ); + } +} + +/*!Load module with name \a modName. + *\param modName - module name for loading. + *\warning If information list is empty. + *\warning If module library (for module with \a modName) is empty. + *\warning If module library is not loaded. + */ +CAM_Module* CAM_Application::loadModule( const QString& modName ) +{ + if ( myInfoList.isEmpty() ) + { + qWarning( tr( "Modules configuration is not defined." ) ); + return 0; + } + + QString libName = moduleLibrary( modName ); + if ( libName.isEmpty() ) + { + qWarning( tr( "Information about module \"%1\" doesn't exist." ).arg( modName ) ); + return 0; + } + + QString err; + GET_MODULE_FUNC crtInst = 0; + +#ifdef WIN32 + HINSTANCE modLib = ::LoadLibrary( libName ); + if ( !modLib ) + { + LPVOID lpMsgBuf; + ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, 0, ::GetLastError(), 0, (LPTSTR)&lpMsgBuf, 0, 0 ); + err = QString( "Failed to load %1. %2" ).arg( libName ).arg( (LPTSTR)lpMsgBuf ); + ::LocalFree( lpMsgBuf ); + } + else + { + crtInst = (GET_MODULE_FUNC)::GetProcAddress( modLib, GET_MODULE_NAME ); + if ( !crtInst ) + { + LPVOID lpMsgBuf; + ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, 0, ::GetLastError(), 0, (LPTSTR)&lpMsgBuf, 0, 0 ); + err = QString( "Failed to find %1 function. %2" ).arg( GET_MODULE_NAME ).arg( (LPTSTR)lpMsgBuf ); + ::LocalFree( lpMsgBuf ); + } + } +#else + void* modLib = dlopen( (char*)libName.latin1(), RTLD_LAZY ); + if ( !modLib ) + err = QString( "Can not load library %1. %2" ).arg( libName ).arg( dlerror() ); + else + { + crtInst = (GET_MODULE_FUNC)dlsym( modLib, GET_MODULE_NAME ); + if ( !crtInst ) + err = QString( "Failed to find function %1. %2" ).arg( GET_MODULE_NAME ).arg( dlerror() ); + } +#endif + + CAM_Module* module = crtInst ? crtInst() : 0; + if ( module ) + { + module->setModuleName( modName ); + module->setName( moduleName( modName ) ); + } + + if ( !err.isEmpty() ) + SUIT_MessageBox::warn1( desktop(), tr( "Error" ), err, tr( "Ok" ) ); + + return module; +} + +/**@name Activate module group.*/ +//@{ +/*!Activate module with name \a modName. + *\param modName - module name. + *\ratval true, if module loaded and activated successful, else false. + */ +bool CAM_Application::activateModule( const QString& modName ) +{ + if ( !modName.isEmpty() && !activeStudy() ) + return false; + + bool res = false; + if ( !modName.isEmpty() ) + { + CAM_Module* mod = module( modName ); + if ( !mod && !moduleLibrary( modName ).isEmpty() ) + { + mod = loadModule( modName ); + addModule( mod ); + } + + if ( mod ) + res = activateModule( mod ); + } + else + res = activateModule( 0 ); + + return res; +} + +/*!Activate module \a mod + *\param mod - module for activation. + *\retval true - if all sucessful. + *\warning Error message if module not activated in active study. + */ +bool CAM_Application::activateModule( CAM_Module* mod ) +{ + if ( mod && !activeStudy() ) + return false; + + if ( myModule == mod ) + return true; + + if ( myModule ) + { + if ( !myModule->deactivateModule( activeStudy() ) ) + { + // .... + } + } + myModule = mod; + + if ( myModule ){ + // Connect the module to the active study + myModule->connectToStudy( dynamic_cast( activeStudy() ) ); + if ( !myModule->activateModule( activeStudy() ) ) + { + myModule->setMenuShown( false ); + myModule->setToolShown( false ); + SUIT_MessageBox::error1( desktop(), tr( "ERROR_TLT" ), tr( "ERROR_ACTIVATE_MODULE_MSG" ).arg( myModule->moduleName() ), tr( "BUT_OK" ) ); + myModule = 0; + return false; + } + } + + updateCommandsStatus(); + + return true; +} +//@} + +/*!Create new study for current application. + *\retval study pointer. + */ +SUIT_Study* CAM_Application::createNewStudy() +{ + return new CAM_Study( this ); +} + +/*!Update commands status for parent class and for current class(if module is active)*/ +void CAM_Application::updateCommandsStatus() +{ + STD_Application::updateCommandsStatus(); + + if ( activeModule() ) + activeModule()->updateCommandsStatus(); +} + +/*!Close all modules in study \a theDoc. + *\param theDoc - study + */ +void CAM_Application::beforeCloseDoc( SUIT_Study* theDoc ) +{ + for ( ModuleListIterator it( myModules ); it.current(); ++it ) + it.current()->studyClosed( theDoc ); +} + +/*!Sets active study for parent class. + *\param study - study. + */ +void CAM_Application::setActiveStudy( SUIT_Study* study ) +{ + STD_Application::setActiveStudy( study ); +} + +/*!Do nothing.*/ +void CAM_Application::moduleAdded( CAM_Module* mod ) +{ +// CAM_Study* study = dynamic_cast( activeStudy() ); +// if ( !study ) +// return; + +// study->insertDataModel( mod->dataModel() ); +} + +/*!Gets module name by title \a title + *\param title - title name + *\retval QString module name. + */ +QString CAM_Application::moduleName( const QString& title ) const +{ + QString res; + for ( ModuleInfoList::const_iterator it = myInfoList.begin(); it != myInfoList.end() && res.isEmpty(); ++it ) + { + if ( (*it).title == title ) + res = (*it).name; + } + return res; +} + +/*!Gets module title by module name \a name + *\param name - module name + *\retval QString module title. + */ +QString CAM_Application::moduleTitle( const QString& name ) const +{ + QString res; + for ( ModuleInfoList::const_iterator it = myInfoList.begin(); it != myInfoList.end() && res.isEmpty(); ++it ) + { + if ( (*it).name == name ) + res = (*it).title; + } + return res; +} + +/*!Get library name for module with title \a title. + *\param title - module title name. + *\param full - boolean flag (if true - return full library name, else internal name) + *\retval QString - library name. + */ +QString CAM_Application::moduleLibrary( const QString& title, const bool full ) const +{ + QString res; + for ( ModuleInfoList::const_iterator it = myInfoList.begin(); it != myInfoList.end() && res.isEmpty(); ++it ) + { + if ( (*it).title == title ) + res = (*it).internal; + } + if ( !res.isEmpty() && full ) + res = SUIT_Tools::library( res ); + return res; +} + +/*!Read modules list*/ +void CAM_Application::readModuleList() +{ + if ( !myInfoList.isEmpty() ) + return; + + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + + QStringList modList; + + // parse command line arguments + int nbArgs = qApp->argc(); + char** CmdLine = qApp->argv(); + QString CmdStr; + for ( int i = 0; i < nbArgs; i++ ) + { + CmdStr.append(CmdLine[i]); + CmdStr.append(" "); + } + int startId = CmdStr.find("--modules ("); + if ( startId != -1 ) { // application launch with --modules option + startId = CmdStr.find("(", startId); + int stopId = CmdStr.find(" )", startId); + QString ModStr = CmdStr.mid( startId+1, stopId - (startId+1) ).stripWhiteSpace(); + int i = 0; + while ( i < ModStr.length() ) + { + int nextId = ModStr.find( ":", i ); + modList.append( ModStr.mid( i, nextId - i ).stripWhiteSpace() ); + i = nextId + 1; + } + } + else { + QString modStr = resMgr->stringValue( "launch", "modules", QString::null ); + modList = QStringList::split( ",", modStr ); + } + + for ( QStringList::const_iterator it = modList.begin(); it != modList.end(); ++it ) + { + QString modName = (*it).stripWhiteSpace(); + if ( modName.isEmpty() ) + continue; + + QString modTitle = resMgr->stringValue( *it, QString( "name" ), QString::null ); + if ( modTitle.isEmpty() ) + continue; + + QString modLibrary = resMgr->stringValue( *it, QString( "library" ), QString::null ).stripWhiteSpace(); + if ( !modLibrary.isEmpty() ) + { + QString libExt; + modLibrary = SUIT_Tools::file( modLibrary.stripWhiteSpace() ); + libExt = QString( "so" ); + if ( SUIT_Tools::extension( modLibrary ).lower() == libExt ) + modLibrary = modLibrary.mid( 0, modLibrary.length() - libExt.length() - 1 ); + libExt = QString( "dll" ); + if ( SUIT_Tools::extension( modLibrary ).lower() == libExt ) + modLibrary = modLibrary.mid( 0, modLibrary.length() - libExt.length() - 1 ); +#ifndef WIN32 + if ( modLibrary.startsWith( "lib" ) ) + modLibrary = modLibrary.mid( 3 ); +#endif + } + else + modLibrary = modName; + + ModuleInfo inf; + inf.name = modName; + inf.title = modTitle; + inf.internal = modLibrary; + myInfoList.append( inf ); + } + + if ( myInfoList.isEmpty() ) + SUIT_MessageBox::error1( 0, tr( "Error" ), tr( "Can not load modules configuration file " ), tr( "Ok" ) ); +} + +/*!Add common items for popup menu ( if they are exist ) + *\param type - type of popup menu + *\param thePopup - popup menu + *\param title - title of popup menu + */ +void CAM_Application::contextMenuPopup( const QString& type, QPopupMenu* thePopup, QString& title ) +{ + // to do : add common items for popup menu ( if they are exist ) + if ( activeModule() ) + activeModule()->contextMenuPopup( type, thePopup, title ); +} + +/*!Create empty study.*/ +void CAM_Application::createEmptyStudy() +{ + SUIT_Study* study = activeStudy(); + + STD_Application::createEmptyStudy(); +} diff --git a/src/CAM/CAM_Application.h b/src/CAM/CAM_Application.h new file mode 100755 index 000000000..d19bde645 --- /dev/null +++ b/src/CAM/CAM_Application.h @@ -0,0 +1,102 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef CAM_APPLICATION_H +#define CAM_APPLICATION_H + +#include "STD_Application.h" + +#include "CAM_Module.h" + +#include + +class QPopupMenu; + +#ifdef WIN32 +#pragma warning( disable:4251 ) +#endif + +class CAM_EXPORT CAM_Application : public STD_Application +{ + Q_OBJECT + +public: + typedef QPtrList ModuleList; + typedef QPtrListIterator ModuleListIterator; + +public: + CAM_Application( const bool = true ); + virtual ~CAM_Application(); + + virtual void start(); + + CAM_Module* activeModule() const; + CAM_Module* module( const QString& ) const; + + /** @name Modules lists.*/ + //@{ + ModuleListIterator modules() const; + void modules( ModuleList& ) const; + void modules( QStringList&, const bool loaded = true ) const; + //@} + + virtual void addModule( CAM_Module* ); + + virtual void loadModules(); + virtual CAM_Module* loadModule( const QString& ); + + virtual bool activateModule( const QString& ); + + virtual void contextMenuPopup( const QString&, QPopupMenu*, QString& ); + + QString moduleName( const QString& ) const; + QString moduleTitle( const QString& ) const; + + virtual void createEmptyStudy(); + +protected: + virtual SUIT_Study* createNewStudy(); + virtual void updateCommandsStatus(); + + virtual void moduleAdded( CAM_Module* ); + virtual void beforeCloseDoc( SUIT_Study* ); + virtual bool activateModule( CAM_Module* = 0 ); + + virtual void setActiveStudy( SUIT_Study* ); + + QString moduleLibrary( const QString&, const bool = true ) const; + +private: + void readModuleList(); + +private: + typedef struct { QString name, title, internal; } ModuleInfo; + typedef QValueList ModuleInfoList; + +private: + CAM_Module* myModule; + ModuleList myModules; + ModuleInfoList myInfoList; + bool myAutoLoad; +}; + +#ifdef WIN32 +#pragma warning( default:4251 ) +#endif + +#endif diff --git a/src/CAM/CAM_DataModel.cxx b/src/CAM/CAM_DataModel.cxx new file mode 100755 index 000000000..187ec6368 --- /dev/null +++ b/src/CAM/CAM_DataModel.cxx @@ -0,0 +1,83 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "CAM_DataModel.h" + +#include "CAM_Module.h" +#include "CAM_RootObject.h" + +/*!Constructor. Initialise module by \a module.*/ +CAM_DataModel::CAM_DataModel( CAM_Module* module ) +: myRoot( 0 ), +myModule( module ) +{ +} + +/*!Destructor. Do nothing.*/ +CAM_DataModel::~CAM_DataModel() +{ +} + +void CAM_DataModel::initialize() +{ + //! Default implementation, does nothing.\n + //! Can be used for creation of root object. +} + +/*!Get root object. + *\retval CAM_DataObject pointer - root object. + */ +CAM_DataObject* CAM_DataModel::root() const +{ + return myRoot; +} + +/*!Sets root object to \a newRoot.\n + *Emit root changed, if it was. + *\param newRoot - new root object + */ +void CAM_DataModel::setRoot( const CAM_DataObject* newRoot ) +{ + if ( myRoot == newRoot ) + return; + + if ( myRoot ) + myRoot->disconnect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) ); + + myRoot = (CAM_DataObject*)newRoot; + + if ( myRoot ) + myRoot->connect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) ); + + emit rootChanged( this ); +} + +/*!Gets module. + *\retval CAM_Module pointer - module. + */ +CAM_Module* CAM_DataModel::module() const +{ + return myModule; +} + +/*!Nullify root, if \a obj equal root.*/ +void CAM_DataModel::onDestroyed( SUIT_DataObject* obj ) +{ + if ( myRoot == obj ) + myRoot = 0; +} diff --git a/src/CAM/CAM_DataModel.h b/src/CAM/CAM_DataModel.h new file mode 100755 index 000000000..0724916cd --- /dev/null +++ b/src/CAM/CAM_DataModel.h @@ -0,0 +1,74 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef CAM_DATAMODEL_H +#define CAM_DATAMODEL_H + +#include "CAM.h" + +#include +#include + +class CAM_Module; +class CAM_DataObject; +class CAM_Study; +class SUIT_DataObject; + +class CAM_EXPORT CAM_DataModel : public QObject +{ + Q_OBJECT + +public: + CAM_DataModel( CAM_Module* ); + virtual ~CAM_DataModel(); + + virtual void initialize(); + + CAM_DataObject* root() const; + CAM_Module* module() const; + + /** @name These methods should be redefined in successors.*/ + //@{ + virtual bool open( const QString&, CAM_Study*, QStringList ) { return true; }//!< return true + virtual bool save( QStringList& ) { return true; }; + virtual bool saveAs( const QString&, CAM_Study*, QStringList& ) { return true; }; + virtual bool close() { return true; }; + virtual bool create( CAM_Study* ) { return true; } + //@} + +protected: + /*! setRoot() should be used to specify custom root object instance.\n + * Such an object can be created in several ways, depending on application or module needs:\n + * \li by initialize() + * \li while the model is being loaded + * \li when the model is updated and becomes non-empty + */ + virtual void setRoot( const CAM_DataObject* ); + +private slots: + void onDestroyed( SUIT_DataObject* ); + +signals: + void rootChanged( const CAM_DataModel* ); + +private: + CAM_DataObject* myRoot; + CAM_Module* myModule; +}; + +#endif diff --git a/src/CAM/CAM_DataObject.cxx b/src/CAM/CAM_DataObject.cxx new file mode 100755 index 000000000..2109bccac --- /dev/null +++ b/src/CAM/CAM_DataObject.cxx @@ -0,0 +1,61 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "CAM_DataObject.h" + +#include "CAM_Module.h" +#include "CAM_DataModel.h" + +/*!Constructor. Sets parent object.*/ +CAM_DataObject::CAM_DataObject( SUIT_DataObject* parent ) +: SUIT_DataObject( parent ) +{ +} + +/*!Destructor.Do nothing*/ +CAM_DataObject::~CAM_DataObject() +{ +} + +/*!Get module. + *\retval const CAM_Module pointer - module + */ +CAM_Module* CAM_DataObject::module() const +{ + CAM_Module* mod = 0; + + CAM_DataModel* data = dataModel(); + if ( data ) + mod = data->module(); + + return mod; +} + +/*!Get data model. + *Return 0 - if no parent obbject. + *\retval const CAM_DataModel pointer - data model + */ +CAM_DataModel* CAM_DataObject::dataModel() const +{ + CAM_DataObject* parentObj = dynamic_cast( parent() ); + + if ( !parentObj ) + return 0; + + return parentObj->dataModel(); +} diff --git a/src/CAM/CAM_DataObject.h b/src/CAM/CAM_DataObject.h new file mode 100755 index 000000000..1b89a8e60 --- /dev/null +++ b/src/CAM/CAM_DataObject.h @@ -0,0 +1,43 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef CAM_DATAOBJECT_H +#define CAM_DATAOBJECT_H + +#include "CAM.h" + +#include + +class CAM_Module; +class CAM_DataModel; + +class CAM_EXPORT CAM_DataObject : public SUIT_DataObject +{ +public: + CAM_DataObject( SUIT_DataObject* = 0 ); + virtual ~CAM_DataObject(); + + CAM_Module* module() const; + virtual CAM_DataModel* dataModel() const; +}; + +#endif + +#if _MSC_VER > 1000 +#pragma once +#endif diff --git a/src/CAM/CAM_Module.cxx b/src/CAM/CAM_Module.cxx new file mode 100755 index 000000000..885f6e05d --- /dev/null +++ b/src/CAM/CAM_Module.cxx @@ -0,0 +1,601 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "CAM_Module.h" + +#include "CAM_DataModel.h" +#include "CAM_Application.h" +#include "CAM_Study.h" + +#include +#include +#include + +/*!Icon.*/ +static const char* ModuleIcon[] = { +"20 20 2 1", +" c None", +". c #000000", +" ", +" ", +" ", +" .................. ", +" . . ", +" . . ", +" . . ", +" . . ", +" . . ", +" . . ", +" . . ", +" . . ", +" .................. ", +" . . . ", +" . . . ", +" ... ... ... ", +" .. .. .. .. .. .. ", +" . . . . . . ", +" .. .. .. .. .. .. ", +" ... ... ... "}; + +QPixmap MYPixmap( ModuleIcon ); + +/*!Constructor.*/ +CAM_Module::CAM_Module() +: QObject(), +myApp( 0 ), +myIcon( MYPixmap ), +myDataModel( 0 ) +{ +} + +/*!Constructor. initialize \a name.*/ +CAM_Module::CAM_Module( const QString& name ) +: QObject(), +myApp( 0 ), +myName( name ), +myIcon( MYPixmap ), +myDataModel( 0 ) +{ +} + +/*!Destructor. Remove data model.*/ +CAM_Module::~CAM_Module() +{ + delete myDataModel; + myDataModel = 0; +} + +/*!Initialize application.*/ +void CAM_Module::initialize( CAM_Application* app ) +{ + myApp = app; +} + +/*!\retval Module icon.*/ +QPixmap CAM_Module::moduleIcon() const +{ + return myIcon; +} + +/*!\retval Module icon name.*/ +QString CAM_Module::iconName() const +{ + return ""; +} + +/*!\retval Module name.*/ +QString CAM_Module::moduleName() const +{ + return myName; +} + +/*! \brief Return data model. + * Create data model, if it was't created before. + */ +CAM_DataModel* CAM_Module::dataModel() const +{ + if ( !myDataModel ) + { + CAM_Module* that = (CAM_Module*)this; + that->myDataModel = that->createDataModel(); + that->myDataModel->initialize(); + } + return myDataModel; +} + +/*!\retval CAM_Application pointer - application.*/ +CAM_Application* CAM_Module::application() const +{ + return myApp; +} + +/*!Public slot + * \retval true. + */ +bool CAM_Module::activateModule( SUIT_Study* study ) +{ + return true; +} + +/*!Public slot + * \retval true. + */ +bool CAM_Module::deactivateModule( SUIT_Study* ) +{ + return true; +} + +/*!Public slot, remove data model from \a study.*/ +void CAM_Module::studyClosed( SUIT_Study* study ) +{ + CAM_Study* camDoc = dynamic_cast( study ); + if ( !camDoc ) + return; + + CAM_DataModel* dm = dataModel(); + if ( dm && camDoc->containsDataModel( dm ) ) { + dm->close(); + camDoc->removeDataModel( dm ); + } +} + +/*!Public slot, do nothing.*/ +void CAM_Module::studyChanged( SUIT_Study* , SUIT_Study* ) +{ +} + +/*!Create and return new instance of CAM_DataModel.*/ +CAM_DataModel* CAM_Module::createDataModel() +{ + return new CAM_DataModel( this ); +} + +/*!Sets module name to \a name. + * \param name - new name for module. + */ +void CAM_Module::setModuleName( const QString& name ) +{ + myName = name; +} + +/*!Sets module icon to \a icon. + * \param icon - new icon for module. + */ +void CAM_Module::setModuleIcon( const QPixmap& icon ) +{ + myIcon = icon; +} + +/*! Return menu manager pointer. + * \retval QtxActionMenuMgr pointer - menu manager. + */ +QtxActionMenuMgr* CAM_Module::menuMgr() const +{ + QtxActionMenuMgr* mgr = 0; + if ( application() && application()->desktop() ) + mgr = application()->desktop()->menuMgr(); + return mgr; +} + +/*! Return tool manager pointer. + * \retval QtxActionToolMgr pointer - tool manager. + */ +QtxActionToolMgr* CAM_Module::toolMgr() const +{ + QtxActionToolMgr* mgr = 0; + if ( application() && application()->desktop() ) + mgr = application()->desktop()->toolMgr(); + return mgr; +} + +/*! Create tool bar with name \a name, if it was't created before. + * \retval -1 - if tool manager was't be created. + */ +int CAM_Module::createTool( const QString& name ) +{ + if ( !toolMgr() ) + return -1; + + return toolMgr()->createToolBar( name ); +} + +/*! Create tool. Register action \a a with id \a id. + * Insert QAction to tool manager. + *\param a - QAction + *\param tBar - integer + *\param id - integer + *\param idx - integer + *\retval integer id of new action in tool manager. + *\retval Return -1 if something wrong. + */ +int CAM_Module::createTool( QAction* a, const int tBar, const int id, const int idx ) +{ + if ( !toolMgr() ) + return -1; + + int regId = registerAction( id, a ); + int intId = toolMgr()->insert( a, tBar, idx ); + return intId != -1 ? regId : -1; +} + +/*! Create tool. Register action \a a with id \a id. + * Insert QAction to tool manager. + *\param a - QAction + *\param tBar - QString& + *\param id - integer + *\param idx - integer + *\retval integer id of new action in tool manager. + *\retval Return -1 if something wrong. + */ +int CAM_Module::createTool( QAction* a, const QString& tBar, const int id, const int idx ) +{ + if ( !toolMgr() ) + return -1; + + int regId = registerAction( id, a ); + int intId = toolMgr()->insert( a, tBar, idx ); + return intId != -1 ? regId : -1; +} + +/*! Create tool. + * Insert QAction with id \a id from action map(myActionMap) to tool manager. + *\param a - QAction + *\param tBar - integer + *\param id - integer + *\param idx - integer + *\retval integer id of new action in tool manager. + *\retval Return -1 if something wrong. + */ +int CAM_Module::createTool( const int id, const int tBar, const int idx ) +{ + if ( !toolMgr() ) + return -1; + + int intId = toolMgr()->insert( action( id ), tBar, idx ); + return intId != -1 ? id : -1; +} + +/*! Create tool. + * Insert QAction with id \a id from action map(myActionMap) to tool manager. + *\param a - QAction + *\param tBar - QString& + *\param id - integer + *\param idx - integer + *\retval integer id of new action in tool manager. + *\retval Return -1 if something wrong. + */ +int CAM_Module::createTool( const int id, const QString& tBar, const int idx ) +{ + if ( !toolMgr() ) + return -1; + + int intId = toolMgr()->insert( action( id ), tBar, idx ); + return intId != -1 ? id : -1; +} + +/*! Create menu. + * Insert submenu \a subMenu to menu manager. + *\param subMenu - QString& + *\param menu - integer + *\param id - integer + *\param group - integer + *\param index - integer + *\retval integer id of new menu in tool manager. + *\retval Return -1 if something wrong. + */ +int CAM_Module::createMenu( const QString& subMenu, const int menu, + const int id, const int group, const int index ) +{ + if ( !menuMgr() ) + return -1; + + return menuMgr()->insert( subMenu, menu, group, index ); +} + +/*! Create menu. + * Insert submenu \a subMenu to menu manager. + *\param subMenu - QString& + *\param menu - QString& + *\param id - integer + *\param group - integer + *\param index - integer + *\retval integer id of new menu in tool manager. + *\retval Return -1 if something wrong. + */ +int CAM_Module::createMenu( const QString& subMenu, const QString& menu, + const int id, const int group, const int index ) +{ + if ( !menuMgr() ) + return -1; + + return menuMgr()->insert( subMenu, menu, group, index ); +} + + +/*! Create menu. Register action \a a with id \a id. + * Insert QAction to menu manager. + *\param a - Qaction + *\param menu - integer + *\param id - integer + *\param group - integer + *\param index - integer + *\retval integer id of new menu in tool manager. + *\retval Return -1 if something wrong. + */ +int CAM_Module::createMenu( QAction* a, const int menu, const int id, const int group, const int index ) +{ + if ( !a || !menuMgr() ) + return -1; + + int regId = registerAction( id, a ); + int intId = menuMgr()->insert( a, menu, group, index ); + return intId != -1 ? regId : -1; +} + +/*! Create menu. Register action \a a with id \a id. + * Insert QAction to menu manager. + *\param a - Qaction + *\param menu - QString& + *\param id - integer + *\param group - integer + *\param index - integer + *\retval integer id of new menu in tool manager. + *\retval Return -1 if something wrong. + */ +int CAM_Module::createMenu( QAction* a, const QString& menu, const int id, const int group, const int index ) +{ + if ( !a || !menuMgr() ) + return -1; + + int regId = registerAction( id, a ); + int intId = menuMgr()->insert( a, menu, group, index ); + return intId != -1 ? regId : -1; +} + +/*! Create menu. + * Insert QAction with id \a id from action map(myActionMap) to menu manager. + *\param menu - integer + *\param id - integer + *\param group - integer + *\param index - integer + *\retval integer id of new menu in tool manager. + *\retval Return -1 if something wrong. + */ +int CAM_Module::createMenu( const int id, const int menu, const int group, const int index ) +{ + if ( !menuMgr() ) + return -1; + + int intId = menuMgr()->insert( action( id ), menu, group, index ); + return intId != -1 ? id : -1; +} + +/*! Create menu. + * Insert QAction with id \a id from action map(myActionMap) to menu manager. + *\param menu - QString& + *\param id - integer + *\param group - integer + *\param index - integer + *\retval integer id of new menu in tool manager. + *\retval Return -1 if something wrong. + */ +int CAM_Module::createMenu( const int id, const QString& menu, const int group, const int index ) +{ + if ( !menuMgr() ) + return -1; + + int intId = menuMgr()->insert( action( id ), menu, group, index ); + return intId != -1 ? id : -1; +} + +/*!Sets menus shown to \a on floag. + *\param on - flag. + */ +void CAM_Module::setMenuShown( const bool on ) +{ + QtxActionMenuMgr* mMgr = menuMgr(); + if ( !mMgr ) + return; + + bool upd = mMgr->isUpdatesEnabled(); + mMgr->setUpdatesEnabled( false ); + + QAction* sep = separator(); + for ( QMap::Iterator it = myActionMap.begin(); it != myActionMap.end(); ++it ) + { + if ( it.data() != sep ) + mMgr->setShown( mMgr->actionId( it.data() ), on ); + } + + mMgr->setUpdatesEnabled( upd ); + if ( upd ) + mMgr->update(); +} + +/*!Sets menu shown for QAction \a a to \a on flag. + * \param a - QAction + * \param on - flag + */ +void CAM_Module::setMenuShown( QAction* a, const bool on ) +{ + if ( menuMgr() ) + menuMgr()->setShown( menuMgr()->actionId( a ), on ); +} + +/*!Sets menu shown for action with id=\a id to \a on flag. + * \param id - id of action + * \param on - flag + */ +void CAM_Module::setMenuShown( const int id, const bool on ) +{ + setMenuShown( action( id ), on ); +} + +/*!Set tools shown to \a on flag. + *\param on - boolean flag. + */ +void CAM_Module::setToolShown( const bool on ) +{ + QtxActionToolMgr* tMgr = toolMgr(); + if ( !tMgr ) + return; + + bool upd = tMgr->isUpdatesEnabled(); + tMgr->setUpdatesEnabled( false ); + + QAction* sep = separator(); + for ( QMap::Iterator it = myActionMap.begin(); it != myActionMap.end(); ++it ) + { + if ( it.data() != sep ) + tMgr->setShown( tMgr->actionId( it.data() ), on ); + } + + tMgr->setUpdatesEnabled( upd ); + if ( upd ) + tMgr->update(); +} + +/*!Set tools shown for QAction \a a to \a on flag. + * \param a - QAction + * \param on - boolean flag + */ +void CAM_Module::setToolShown( QAction* a, const bool on ) +{ + if ( toolMgr() ) + toolMgr()->setShown( toolMgr()->actionId( a ), on ); +} + +/*!Set tools shown for action with id=\a id to \a on flag. + * \param id - integer action id + * \param on - boolean flag + */ +void CAM_Module::setToolShown( const int id, const bool on ) +{ + setToolShown( action( id ), on ); +} + +/*! Return action by id. + * \param id - id of action. + * \retval QAction. + */ +QAction* CAM_Module::action( const int id ) const +{ + QAction* a = 0; + if ( myActionMap.contains( id ) ) + a = myActionMap[id]; + return a; +} + +/*! Return id by action. + * \param a - QAction. + * \retval id of action. + */ +int CAM_Module::actionId( const QAction* a ) const +{ + int id = -1; + for ( QMap::ConstIterator it = myActionMap.begin(); it != myActionMap.end() && id == -1; ++it ) + { + if ( it.data() == a ) + id = it.key(); + } + return id; +} + +/*! Create new instance of QtxAction and register action with \a id. + * \param id - id for new action. + * \param text - parameter for creation QtxAction + * \param icon - parameter for creation QtxAction + * \param menu - parameter for creation QtxAction + * \param tip - tip status for QtxAction action. + * \param key - parameter for creation QtxAction + * \param parent - parent for action + * \param toggle - parameter for creation QtxAction + * \param reciever - + * \param member - + */ +QAction* CAM_Module::createAction( const int id, const QString& text, const QIconSet& icon, + const QString& menu, const QString& tip, const int key, + QObject* parent, const bool toggle, QObject* reciever, const char* member ) +{ + QtxAction* a = new QtxAction( text, icon, menu, key, parent, 0, toggle ); + a->setStatusTip( tip ); + + if ( reciever && member ) + connect( a, SIGNAL( activated() ), reciever, member ); + + registerAction( id, a ); + + return a; +} + +/*! Register action in action map. + * \param id - id for action. + * \param a - action + * \retval new id for action. + */ +int CAM_Module::registerAction( const int id, QAction* a ) +{ + int ident = -1; + for ( QMap::ConstIterator it = myActionMap.begin(); it != myActionMap.end() && ident == -1; ++it ) + if ( it.data() == a ) + ident = it.key(); + + if ( ident != -1 ) + return ident; + + static int generatedId = -1; + ident = id < 0 ? --generatedId : id; + + myActionMap.insert( ident, a ); + + if ( menuMgr() ) + menuMgr()->registerAction( a ); + + if ( toolMgr() ) + toolMgr()->registerAction( a ); + + return ident; +} + +/*! Return qt action manager separator.*/ +QAction* CAM_Module::separator() +{ + return QtxActionMgr::separator(); +} + +/*! Connect data model of module with active study */ +void CAM_Module::connectToStudy( CAM_Study* camStudy ) +{ + CAM_Application* app = camStudy ? dynamic_cast( camStudy->application() ) : 0; + if( !app ) + return; + + CAM_DataModel* prev = 0; + for( CAM_Application::ModuleListIterator it = app->modules(); it.current(); ++it ) + { + CAM_DataModel* dm = it.current()->dataModel(); + if( it.current() == this && !camStudy->containsDataModel( dm ) ) + { + if( prev ) + camStudy->insertDataModel( it.current()->dataModel(), prev ); + else + camStudy->insertDataModel( it.current()->dataModel(), 0 ); + } + prev = dm; + } +} diff --git a/src/CAM/CAM_Module.h b/src/CAM/CAM_Module.h new file mode 100755 index 000000000..7b525996c --- /dev/null +++ b/src/CAM/CAM_Module.h @@ -0,0 +1,150 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef CAM_MODULE_H +#define CAM_MODULE_H + +#include "CAM.h" + +#include +#include +#include +#include + +class QAction; +class SUIT_Study; +class CAM_Study; +class CAM_DataModel; +class CAM_Application; +class QtxActionMenuMgr; +class QtxActionToolMgr; + +#ifdef WIN32 +#pragma warning( disable: 4251 ) +#endif + +/*! + * Class provide support of tool and menu managers. + */ +class CAM_EXPORT CAM_Module : public QObject +{ + Q_OBJECT + +public: + CAM_Module(); + CAM_Module( const QString& ); + virtual ~CAM_Module(); + + virtual void initialize( CAM_Application* ); + + QString moduleName() const; + QPixmap moduleIcon() const; + + CAM_DataModel* dataModel() const; + CAM_Application* application() const; + + virtual QString iconName() const; + + virtual void contextMenuPopup( const QString&, QPopupMenu*, QString& title ) {}; + virtual void updateCommandsStatus() {}; + + /** @name Set Menu Shown*/ + //@{ + void setMenuShown( const bool ); + void setMenuShown( QAction*, const bool ); + void setMenuShown( const int, const bool ); + //@} + + /** @name Set Tool Shown*/ + //@{ + void setToolShown( const bool ); + void setToolShown( QAction*, const bool ); + void setToolShown( const int, const bool ); + //@} + +public slots: + virtual bool activateModule( SUIT_Study* ); + virtual bool deactivateModule( SUIT_Study* ); + + virtual void connectToStudy( CAM_Study* ); + + virtual void studyClosed( SUIT_Study* ); + virtual void studyChanged( SUIT_Study*, SUIT_Study* ); + +protected: + virtual CAM_DataModel* createDataModel(); + + virtual void setModuleName( const QString& ); + virtual void setModuleIcon( const QPixmap& ); + + QtxActionMenuMgr* menuMgr() const; + QtxActionToolMgr* toolMgr() const; + + /** @name Create tool methods.*/ + //@{ + int createTool( const QString& ); + int createTool( const int, const int, const int = -1 ); + int createTool( const int, const QString&, const int = -1 ); + int createTool( QAction*, const int, const int = -1, const int = -1 ); + int createTool( QAction*, const QString&, const int = -1, const int = -1 ); + //@} + + /** @name Create menu methods.*/ + //@{ + int createMenu( const QString&, const int, const int = -1, const int = -1, const int = -1 ); + int createMenu( const QString&, const QString&, const int = -1, const int = -1, const int = -1 ); + int createMenu( const int, const int, const int = -1, const int = -1 ); + int createMenu( const int, const QString&, const int = -1, const int = -1 ); + int createMenu( QAction*, const int, const int = -1, const int = -1, const int = -1 ); + int createMenu( QAction*, const QString&, const int = -1, const int = -1, const int = -1 ); + //@} + + static QAction* separator(); + + /**Action ids methods.*/ + //@{ + QAction* action( const int ) const; + int actionId( const QAction* ) const; + //@} + + int registerAction( const int, QAction* ); + QAction* createAction( const int, const QString&, const QIconSet&, const QString&, + const QString&, const int, QObject* = 0, + const bool = false, QObject* = 0, const char* = 0 ); + +private: + CAM_Application* myApp; + QString myName; + QPixmap myIcon; + CAM_DataModel* myDataModel; + QMap myActionMap; + + friend class CAM_Application; +}; + +#ifdef WIN32 +#pragma warning( default: 4251 ) +#endif + +extern "C" { + typedef CAM_Module* (*GET_MODULE_FUNC)(); +} + +#define GET_MODULE_NAME "createModule" + +#endif diff --git a/src/CAM/CAM_RootObject.cxx b/src/CAM/CAM_RootObject.cxx new file mode 100755 index 000000000..a45fcadeb --- /dev/null +++ b/src/CAM/CAM_RootObject.cxx @@ -0,0 +1,73 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "CAM_RootObject.h" + +#include "CAM_DataModel.h" +#include "CAM_Module.h" + +/*!Constructor. Initialize by \a parent. + * Set data model to 0. + */ +CAM_RootObject::CAM_RootObject( SUIT_DataObject* parent ) +: CAM_DataObject( parent ), +myDataModel( 0 ) +{ +} + +/*!Constructor. Initialize by \a parent and \a data - data object + *\param data - data object + *\param parent - parent data object + */ +CAM_RootObject::CAM_RootObject( CAM_DataModel* data, SUIT_DataObject* parent ) +: CAM_DataObject( parent ), +myDataModel( data ) +{ +} + +/*!Destructor. Do nothing.*/ +CAM_RootObject::~CAM_RootObject() +{ +} + +/*! + Returns module name +*/ +QString CAM_RootObject::name() const +{ + QString aName = ""; + if (myDataModel) + aName = myDataModel->module()->moduleName(); + return aName; +} + +/*!Get data model + *\retval const CAM_DataModel pointer to data model. + */ +CAM_DataModel* CAM_RootObject::dataModel() const +{ + return myDataModel; +} + +/*!Set data model. + *\param dm - data model to set. + */ +void CAM_RootObject::setDataModel( CAM_DataModel* dm ) +{ + myDataModel = dm; +} diff --git a/src/CAM/CAM_RootObject.h b/src/CAM/CAM_RootObject.h new file mode 100755 index 000000000..3ab434021 --- /dev/null +++ b/src/CAM/CAM_RootObject.h @@ -0,0 +1,52 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef CAM_ROOTOBJECT_H +#define CAM_ROOTOBJECT_H + +#include "CAM_DataObject.h" + +/*! + CAM_RootObject - class intended for optimized access to CAM_DataModel instance + from CAM_DataObject instances. + + To take advantage of this class in a specific application, + custom data model root object class should be derived from both CAM_RootObject + and application-specific DataObject implementation using virtual inheritance. + */ +class CAM_EXPORT CAM_RootObject : public virtual CAM_DataObject +{ +public: + CAM_RootObject( SUIT_DataObject* = 0 ); + CAM_RootObject( CAM_DataModel*, SUIT_DataObject* = 0 ); + virtual ~CAM_RootObject(); + + virtual QString name() const; + + virtual CAM_DataModel* dataModel() const; + virtual void setDataModel( CAM_DataModel* ); + +private: + CAM_DataModel* myDataModel; +}; + +#endif + +#if _MSC_VER > 1000 +#pragma once +#endif diff --git a/src/CAM/CAM_Study.cxx b/src/CAM/CAM_Study.cxx new file mode 100755 index 000000000..26f7504b3 --- /dev/null +++ b/src/CAM/CAM_Study.cxx @@ -0,0 +1,177 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "CAM_Study.h" + +#include "CAM_DataModel.h" +#include "CAM_DataObject.h" +#include "CAM_RootObject.h" +#include "CAM_Module.h" + +/*!Constructor.*/ +CAM_Study::CAM_Study( SUIT_Application* app ) +: SUIT_Study( app ) +{ +} + +/*!Destructor*/ +CAM_Study::~CAM_Study() +{ +} + +/*!Closing all data models and close document permanently(if \a permanently = true.) + * \param permanently - flag + */ +void CAM_Study::closeDocument(bool permanently) +{ + for ( ModelListIterator it( myDataModels ); it.current(); ++it ) + it.current()->close(); + + SUIT_Study::closeDocument(permanently); +} + +/*!Append data model to list. + * \param dm - data model for adding + */ +bool CAM_Study::appendDataModel( const CAM_DataModel* dm ) +{ + return insertDataModel( dm, myDataModels.count() ); +} + +/*!Insert data model \a dm after \a other + * \param dm - data model for adding + * \param other - previus data model for \a dm + */ +bool CAM_Study::insertDataModel( const CAM_DataModel* dm, const CAM_DataModel* other ) +{ + int idx = myDataModels.findRef( other ); + return insertDataModel( dm, idx < 0 ? idx : idx + 1 ); +} + +/*!Insert data model with index \a idx. \n + * \param dm - data model + * \param idx - index for inserting(must be no less zero) + * \retval true - if model added successful, else false. + */ +bool CAM_Study::insertDataModel( const CAM_DataModel* dm, const int idx ) +{ + if ( !dm || myDataModels.findRef( dm ) != -1 ) + return false; + + int pos = idx < 0 ? myDataModels.count() : idx; + myDataModels.insert( QMIN( pos, (int)myDataModels.count() ), dm ); + + connect( dm, SIGNAL( rootChanged( const CAM_DataModel* ) ), SLOT( updateModelRoot( const CAM_DataModel* ) ) ); + + dataModelInserted( dm ); + + return true; +} + +/*! Remove data model from list + * \param dm data model + * \retval true - if all ok, else false. + */ +bool CAM_Study::removeDataModel( const CAM_DataModel* dm ) +{ + if ( !dm ) + return true; + + CAM_RootObject* aModelRoot = dynamic_cast( dm->root() ); + if ( aModelRoot ) + aModelRoot->setDataModel( 0 ); + + return myDataModels.remove( dm ); +} + +/*!Check data model contains in list. + * \param dm - data model + * \retval true - if data model in list, else false. + */ +bool CAM_Study::containsDataModel( const CAM_DataModel* dm ) const +{ + return myDataModels.contains( dm ); +} + +/*!Gets list of all data models. + * \param lst - output data model list. + */ +void CAM_Study::dataModels( ModelList& lst ) const +{ + lst.clear(); + for ( ModelListIterator it( myDataModels ); it.current(); ++it ) + lst.append( it.current() ); +} + +/*! Open data model \a dModel, if it saved*/ +void CAM_Study::dataModelInserted( const CAM_DataModel* dModel ) +{ + CAM_DataModel* dm = (CAM_DataModel*)dModel; + + if ( isSaved() ) // need to load data model from an exisitng file? + openDataModel( studyName(), dm ); + else // no, just need to update data model's connection to study tree + //(some application may want to show model's root in a study tree even if a model is empty) + { + dm->create( this ); + updateModelRoot( dm ); + } +} + +/*! \retval false*/ +bool CAM_Study::openDataModel( const QString&, CAM_DataModel* ) +{ + return false; +} + +/*! \retval false*/ +bool CAM_Study::saveDataModel( const QString&, CAM_DataModel* ) +{ + return false; +} + +/*! Public slot. Update model root.*/ +void CAM_Study::updateModelRoot( const CAM_DataModel* dm ) +{ + if ( !root() ) + return; + + DataObjectList childList; + root()->children( childList ); + CAM_DataObject* curRoot = 0; + QString aName = dm->root() ? dm->root()->name() : dm->module()->moduleName(); + int i = 0; + for ( int n = childList.count(); i < n; i++ ) { + if ( childList.at( i )->name() == aName ) { + curRoot = dynamic_cast( childList.at( i ) ); + break; + } + } + + if ( curRoot == dm->root() ) + return; + + // replacing old data model root with a new one - old root deleted here ! + if ( curRoot ) + root()->replaceChild( curRoot, dm->root(), true ); + else { + int idx = myDataModels.findRef( dm ); + if ( idx != -1 ) + root()->insertChild( dm->root(), idx ); + } +} diff --git a/src/CAM/CAM_Study.h b/src/CAM/CAM_Study.h new file mode 100755 index 000000000..29106776b --- /dev/null +++ b/src/CAM/CAM_Study.h @@ -0,0 +1,78 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef CAM_STUDY_H +#define CAM_STUDY_H + +#include "CAM.h" + +#include "CAM_DataModel.h" + +#include + +#include + +#ifdef WIN32 +#pragma warning( disable:4251 ) +#endif + +class CAM_EXPORT CAM_Study : public SUIT_Study +{ + Q_OBJECT + +public: + typedef QPtrList ModelList; + typedef QPtrListIterator ModelListIterator; + +public: + CAM_Study( SUIT_Application* ); + virtual ~CAM_Study(); + + virtual void closeDocument(bool permanently = true); + + /** @name Insert data model methods.*/ + //@{ + bool appendDataModel( const CAM_DataModel* ); + virtual bool insertDataModel( const CAM_DataModel*, const int = -1 ); + bool insertDataModel( const CAM_DataModel*, const CAM_DataModel* ); + //@} + + virtual bool removeDataModel( const CAM_DataModel* ); + + bool containsDataModel( const CAM_DataModel* ) const; + + void dataModels( ModelList& ) const; + +protected: + virtual void dataModelInserted( const CAM_DataModel* ); + virtual bool openDataModel( const QString&, CAM_DataModel* ); + virtual bool saveDataModel( const QString&, CAM_DataModel* ); + +protected slots: + virtual void updateModelRoot( const CAM_DataModel* ); + +private: + //! Data model list + ModelList myDataModels; +}; + +#ifdef WIN32 +#pragma warning( default:4251 ) +#endif + +#endif diff --git a/src/GLViewer/GLViewer_Drawer.cxx b/src/GLViewer/GLViewer_Drawer.cxx new file mode 100644 index 000000000..841fb6b84 --- /dev/null +++ b/src/GLViewer/GLViewer_Drawer.cxx @@ -0,0 +1,848 @@ +// Copyright (C) 2005 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. +// +// 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_Drawer.cxx +// Created: November, 2004 + +//#include +#include "GLViewer_Drawer.h" +#include "GLViewer_Object.h" +#include "GLViewer_Text.h" +#include "GLViewer_ViewFrame.h" +#include "GLViewer_ViewPort2d.h" + +#ifndef WIN32 +#include +#endif + +#include +#include + +#define TEXT_GAP 5 + +GLboolean TFLoaded = GL_FALSE; + +GLdouble modelMatrix[16], projMatrix[16]; +GLint viewport[4]; +GLdouble winx, winy, winz; +GLint status; + +GLViewer_TexFont* staticGlFont; + +//================================================================ +// Class : GLViewer_TexFont +// Description : +//================================================================ +//! code of first font symbol +static int FirstSymbolNumber = 32; +//! code of last font symbol +static int LastSymbolNumber = 127; + +QMap GLViewer_TexFont::TexFontBase; +QMap GLViewer_TexFont::BitmapFontCache; + +//======================================================================= +// Function: clearTextBases +// Purpose : +//======================================================================= +void GLViewer_TexFont::clearTextBases() +{ + //cout << "Clear font map" << endl; + TexFontBase.clear(); + BitmapFontCache.clear(); +} + +//====================================================================== +// Function: GLViewer_TexFont +// Purpose : +//======================================================================= +GLViewer_TexFont::GLViewer_TexFont() +{ + myQFont = QFont::defaultFont(); + QFontMetrics aFM( myQFont ); + myWidths = new int[LastSymbolNumber - FirstSymbolNumber+1]; + myPositions = new int[LastSymbolNumber - FirstSymbolNumber+1]; + mySeparator = 2; + for( int k = FirstSymbolNumber, aWidth = 0; k <= LastSymbolNumber; k++ ) + { + myWidths[ k - FirstSymbolNumber ] = aFM.width( k ); + myPositions[ k - FirstSymbolNumber ] = aWidth; + aWidth += myWidths[ k - FirstSymbolNumber ] + 2;//mySeparator; + } + + myTexFontWidth = 0; + myTexFontHeight = 0; + myIsResizeable = false; + //myMinMagFilter = GL_NEAREST; + myMinMagFilter = GL_LINEAR_ATTENUATION ; +} + +//====================================================================== +// Function: GLViewer_TexFont +// Purpose : +//======================================================================= +GLViewer_TexFont::GLViewer_TexFont( QFont* theFont, int theSeparator, bool theIsResizeable, GLuint theMinMagFilter ) +{ + myQFont = *theFont; + QFontMetrics aFM( myQFont ); + myWidths = new int[LastSymbolNumber - FirstSymbolNumber+1]; + myPositions = new int[LastSymbolNumber - FirstSymbolNumber+1]; + mySeparator = theSeparator; + for( int k = FirstSymbolNumber, aWidth = 0; k <= LastSymbolNumber; k++ ) + { + myWidths[ k - FirstSymbolNumber ] = aFM.width( k ); + myPositions[ k - FirstSymbolNumber ] = aWidth; + aWidth += myWidths[ k - FirstSymbolNumber ] + 2;//mySeparator; + } + + myTexFontWidth = 0; + myTexFontHeight = 0; + myIsResizeable = theIsResizeable; + myMinMagFilter = theMinMagFilter; + +} + +//====================================================================== +// Function: ~GLViewer_TexFont +// Purpose : +//======================================================================= +GLViewer_TexFont::~GLViewer_TexFont() +{ + delete[] myWidths; + delete[] myPositions; +} + +//====================================================================== +// Function: generateTexture +// Purpose : +//======================================================================= +void GLViewer_TexFont::generateTexture() +{ + QFontMetrics aFM( myQFont ); + + GLViewer_TexFindId aFindFont; + aFindFont.myFontString = myQFont.toString(); + aFindFont.myViewPortId = (int)QGLContext::currentContext(); + + if( TexFontBase.contains( aFindFont ) ) + { + GLViewer_TexIdStored aTexture = TexFontBase[ aFindFont ]; + myTexFont = aTexture.myTexFontId; + myTexFontWidth = aTexture.myTexFontWidth; + myTexFontHeight = aTexture.myTexFontHeight; + } + else + { + QString aStr; + int pixelsWidth = 0; + int pixelsHight = aFM.height(); + myTexFontWidth = 64; + myTexFontHeight = 64; + + pixelsWidth = myWidths[LastSymbolNumber - FirstSymbolNumber] + + myPositions[LastSymbolNumber - FirstSymbolNumber]; + + while( myTexFontWidth < pixelsWidth ) + myTexFontWidth = myTexFontWidth * 2; + while( myTexFontHeight < pixelsHight ) + myTexFontHeight = myTexFontHeight * 2; + + QPixmap aPixmap( myTexFontWidth, myTexFontHeight ); + aPixmap.fill( QColor( 0, 0, 0) ); + QPainter aPainter( &aPixmap ); + aPainter.setFont( myQFont ); + for( int l = 0/*, gap = 0*/; l < LastSymbolNumber - FirstSymbolNumber; l++ ) + { + QString aLetter; + aLetter += (char)(FirstSymbolNumber + l); + aPainter.setPen( QColor( 255,255,255) ); + aPainter.drawText ( myPositions[l], pixelsHight, aLetter ); + } + + QImage aImage = aPixmap.convertToImage(); + char* pixels = new char[myTexFontWidth * myTexFontHeight * 2]; + + for( int i = 0; i < myTexFontHeight; i++ ) + { + for( int j = 0; j < myTexFontWidth; j++ ) + { + int aRed = qRed( aImage.pixel( j, myTexFontHeight - i - 1 ) ); + int aGreen = qGreen( aImage.pixel( j, myTexFontHeight - i - 1 ) ); + int aBlue = qBlue( aImage.pixel( j, myTexFontHeight - i - 1 ) ); + + if( aRed != 0 || aGreen != 0 || aBlue != 0 ) + { + pixels[i * myTexFontWidth * 2 + j * 2] = (GLubyte)( (aRed + aGreen + aBlue)/3 ); + pixels[i * myTexFontWidth * 2 + j * 2 + 1]= (GLubyte) 255; + } + else + { + pixels[i * myTexFontWidth * 2 + j * 2] = (GLubyte) 0; + pixels[i * myTexFontWidth * 2 + j * 2 + 1]= (GLubyte) 0; + } + } + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glGenTextures(1, &myTexFont); + glBindTexture(GL_TEXTURE_2D, myTexFont); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, myMinMagFilter); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, myMinMagFilter); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexImage2D(GL_TEXTURE_2D, + 0, + GL_INTENSITY, + myTexFontWidth, + myTexFontHeight, + 0, + GL_LUMINANCE_ALPHA, + GL_UNSIGNED_BYTE, + pixels); + + delete[] pixels; + + GLViewer_TexIdStored aTexture; + aTexture.myTexFontId = myTexFont; + aTexture.myTexFontWidth = myTexFontWidth; + aTexture.myTexFontHeight = myTexFontHeight; + + TexFontBase.insert( aFindFont, aTexture ); + } +} + +//====================================================================== +// Function: drawString +// Purpose : +//======================================================================= +void GLViewer_TexFont::drawString( QString theStr, GLdouble theX , GLdouble theY ) +{ + double aXScale = 1., aYScale = 1.; + // store attributes + glPushAttrib( GL_ENABLE_BIT | GL_TEXTURE_BIT ); + + if ( !myIsResizeable ) + { + glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix); + aXScale = modelMatrix[0]; + aYScale = modelMatrix[5]; + } + + glEnable(GL_TEXTURE_2D); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, myMinMagFilter); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, myMinMagFilter); + + glPixelTransferi(GL_MAP_COLOR, 0); + + glAlphaFunc(GL_GEQUAL, 0.05F); + glEnable(GL_ALPHA_TEST); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + + glBindTexture(GL_TEXTURE_2D, myTexFont); + glBegin(GL_QUADS); + + theY = theY - ( myTexFontHeight - QFontMetrics( myQFont ).height() ) / aYScale; + + double aLettBegin, aLettEnd, aDY = ( myTexFontHeight - 1 ) / aYScale, aDX; + char aLetter; + int aLettIndex; + for( int i = 0; i < theStr.length(); i++ ) + { + aLetter = theStr.data()[i]; + aLettIndex = (int)aLetter - FirstSymbolNumber; + + aLettBegin = (double)myPositions[aLettIndex] / ( (double)myTexFontWidth - 1. ); + aLettEnd = aLettBegin + ( (double)myWidths[aLettIndex] - 1. ) / ( (double)myTexFontWidth - 1. ); + + aDX = ( (double)myWidths[aLettIndex] - 1. ) / aXScale; + + glTexCoord2d( aLettBegin, 0.0 ); glVertex3d( theX, theY, 1.0 ); + glTexCoord2d( aLettBegin, 1.0 ); glVertex3d( theX, theY + aDY, 1.0 ); + glTexCoord2d( aLettEnd, 1.0 ); glVertex3d( theX + aDX, theY + aDY, 1.0 ); + glTexCoord2d( aLettEnd, 0.0 ); glVertex3d( theX + aDX, theY, 1.0 ); + + theX += aDX + mySeparator / aXScale; + } + + glEnd(); + // restore attributes + glPopAttrib(); +} + +//====================================================================== +// Function: getStringWidth +// Purpose : +//======================================================================= +int GLViewer_TexFont::getStringWidth( QString theStr ) +{ + int aWidth = 0; + for( int i = 0; i < theStr.length(); i ++ ) + { + char aLetter = theStr.data()[i]; + int aLettIndex = (int)aLetter - FirstSymbolNumber; + aWidth += myWidths[aLettIndex] + mySeparator; + } + + return aWidth; +} + +//====================================================================== +// Function: getStringHeight +// Purpose : +//======================================================================= +int GLViewer_TexFont::getStringHeight() +{ + QFontMetrics aFM( myQFont ); + return aFM.height(); +} + +//! function for generation list base for bitmap fonts +static GLuint displayListBase( QFont* theFont ) +{ + GLuint aList = 0; + //static QMap fontCache; + GLViewer_TexFindId aFindFont; + aFindFont.myFontString = theFont->toString(); + +#ifdef WIN32 + HGLRC ctx = ::wglGetCurrentContext(); + if ( !ctx ) + return aList; + + aFindFont.myViewPortId = (int)ctx; + + if ( GLViewer_TexFont::BitmapFontCache.contains( aFindFont ) ) + aList = GLViewer_TexFont::BitmapFontCache[aFindFont]; + else + { + GLuint listBase = 0; + QMap::iterator it = GLViewer_TexFont::BitmapFontCache.begin(); + for ( ; it != GLViewer_TexFont::BitmapFontCache.end(); ++it ) + { + if ( it.key().myViewPortId == (int)ctx && it.data() > listBase ) + listBase = it.data(); + } + listBase += 256; + + HDC glHdc = ::wglGetCurrentDC(); + ::SelectObject( glHdc, theFont->handle() ); + if ( !::wglUseFontBitmaps( glHdc, 0, 256, listBase ) ) + listBase = 0; + aList = listBase; + GLViewer_TexFont::BitmapFontCache[aFindFont] = aList; + } +#else //X Window + Display* aDisp = glXGetCurrentDisplay(); + if( !aDisp ) + { +#ifdef _DEBUG_ + printf( "Can't find current dislay\n" ); +#endif + return aList; + } + + GLXContext aCont = glXGetCurrentContext(); + if( !aCont ) + { +#ifdef _DEBUG_ + printf( "Can't find current context\n" ); +#endif + return aList; + } + + aFindFont.myViewPortId = (int)aCont; + + if ( GLViewer_TexFont::BitmapFontCache.contains( aFindFont ) ) + aList = GLViewer_TexFont::BitmapFontCache[aFindFont]; + else + { + GLuint listBase = 0; + QMap::iterator it = GLViewer_TexFont::BitmapFontCache.begin(); + for ( ; it != GLViewer_TexFont::BitmapFontCache.end(); ++it ) + { + if ( it.key().myViewPortId == (int)aCont && it.data() > listBase ) + listBase = it.data(); + } + listBase += 256; + + //glXUseXFont( (Font)(theFont->handle()), 0, 256, listBase ); + int aFontCont = 0; + char** xFontList = XListFonts( aDisp, aFindFont.myFontString.data(), 1, &aFontCont ); + if( !theFont->handle() ) + { +#ifdef _DEBUG_ + printf( "Can't load font %s. loading default font....\n", aFindFont.myFontString.data() ); +#endif + QString aFontMask ("-*-*-*-r-*-*-"); + aFontMask += aFindFont.myFontString.section( ',', 1, 1 ); +#ifdef _DEBUG_ + printf( "Height of Default font: %s\n", aFindFont.myFontString.section( ',', 1, 1 ).data() ); +#endif + aFontMask += "-*-*-*-m-*-*-*"; + xFontList = XListFonts( aDisp, aFontMask.data()/*"-*-*-*-r-*-*-12-*-*-*-m-*-*-*"*/, 1, &aFontCont ); + if( aFontCont == 0 ) + { +#ifdef _DEBUG_ + printf( "Can't load default font\n" ); +#endif + return 0; + } + glXUseXFont( (Font)(XLoadFont( aDisp,xFontList[0] )), 0, 256, listBase ); + } + else + glXUseXFont( (Font)(theFont->handle()), 0, 256, listBase ); + + aList = listBase; + GLViewer_TexFont::BitmapFontCache[aFindFont] = aList; + } + +#endif + + return aList; +} + +/*************************************************************************** +** Class: GLViewer_Drawer +** Descr: Drawer for GLViewer_Object +** Module: GLViewer +** Created: UI team, 01.10.01 +****************************************************************************/ +//====================================================================== +// Function: GLViewer_Drawer +// Purpose : +//======================================================================= +GLViewer_Drawer::GLViewer_Drawer() +: myFont( "Helvetica", 10, QFont::Bold ) +{ + myXScale = myYScale = 0.0; + myObjects.clear(); + myTextList = 0/*-1*/; + myObjectType = "GLViewer_Object"; + myPriority = 0; + myTextFormat = DTF_BITMAP; +} + +//====================================================================== +// Function: ~GLViewer_Drawer +// Purpose : +//======================================================================= +GLViewer_Drawer::~GLViewer_Drawer() +{ + myObjects.clear(); + glDeleteLists( myTextList, 1 ); +} + +//====================================================================== +// Function: destroyAllTextures +// Purpose : +//======================================================================= +void GLViewer_Drawer::destroyAllTextures() +{ + QMap::Iterator anIt= GLViewer_TexFont::TexFontBase.begin(); + QMap::Iterator anEndIt= GLViewer_TexFont::TexFontBase.end(); + + for( ; anIt != anEndIt; anIt++ ) + glDeleteTextures( 1, &(anIt.data().myTexFontId) ); +} + +//======================================================================= +// Function: setAntialiasing +// Purpose : The function enables and disables antialiasing in Open GL (for points, lines and polygons). +//======================================================================= +void GLViewer_Drawer::setAntialiasing(const bool on) +{ + if (on) + { + glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); + glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); + + glEnable(GL_POINT_SMOOTH); + glEnable(GL_LINE_SMOOTH); + glEnable(GL_POLYGON_SMOOTH); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable (GL_BLEND); + } + else + { + glDisable(GL_POINT_SMOOTH); + glDisable(GL_LINE_SMOOTH); + glDisable(GL_POLYGON_SMOOTH); + glBlendFunc (GL_ONE, GL_ZERO); + glDisable (GL_BLEND); + } +} + +//====================================================================== +// Function: loadTexture +// Purpose : +//======================================================================= +GLuint GLViewer_Drawer::loadTexture( const QString& fileName, + GLint* x_size, + GLint* y_size, + GLint* t_size ) +{ + QImage buf; + if ( fileName.isEmpty() || !buf.load( fileName ) ) + return 0; + + int w = buf.width(); + int h = buf.height(); + + int size = 16; + while( size < w || size < h ) + size = size * 2; + + GLuint texture; + GLubyte* pixels = new GLubyte[ size * size * 4 ]; + + for( int i = 0; i < size; i++ ) + { + for( int j = 0; j < size; j++ ) + { + GLubyte r, g, b, a; + if( j < w && i < h ) + { + QRgb pixel = buf.pixel( j, h - i - 1 ); + r = (GLubyte)qRed( pixel ); + g = (GLubyte)qGreen( pixel ); + b = (GLubyte)qBlue( pixel ); + a = (GLubyte)qAlpha( pixel ); + } + else + { + r = (GLubyte)255; + g = (GLubyte)255; + b = (GLubyte)255; + a = (GLubyte)255; + } + + int index = 4 * ( i * size + j ); + pixels[ index ] = r; + pixels[ index + 1 ] = g; + pixels[ index + 2 ] = b; + pixels[ index + 3 ] = a; + } + } + + //initialize texture + glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); + glGenTextures( 1, &texture ); + glBindTexture( GL_TEXTURE_2D, texture ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, size, size, 0, + GL_RGBA, GL_UNSIGNED_BYTE, pixels ); + + delete[] pixels; + + if ( x_size ) + *(x_size) = w; + + if ( y_size ) + *(y_size) = h; + + if ( t_size ) + *(t_size) = size; + + return texture; +} + +//====================================================================== +// Function: drawTexture +// Purpose : +//======================================================================= +void GLViewer_Drawer::drawTexture( GLuint texture, GLint size, GLfloat x, GLfloat y ) +{ + /*float xScale = myXScale; + float yScale = myYScale; + + glColor4f( 1.0, 1.0, 1.0, 1.0 ); + + glEnable( GL_TEXTURE_2D ); + glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); + glAlphaFunc( GL_GREATER, 0.95F ); + glEnable( GL_ALPHA_TEST ); + + glBindTexture( GL_TEXTURE_2D, texture ); + glBegin( GL_QUADS ); + + glTexCoord2f( 0.0, 0.0 ); + glVertex3f( x-size/2./xScale, y-size/2./yScale, 0.0 ); + + glTexCoord2f( 0.0, 1.0 ); + glVertex3f( x-size/2./xScale, y+size/2./yScale, 0.0 ); + + glTexCoord2f( 1.0, 1.0 ); + glVertex3f( x+size/2./xScale, y+size/2./yScale, 0.0 ); + + glTexCoord2f( 1.0, 0.0 ); + glVertex3f( x+size/2./xScale, y-size/2./yScale, 0.0 ); + + glEnd(); + glFlush(); + + glDisable( GL_ALPHA_TEST ); + glDisable( GL_TEXTURE_2D );*/ + + drawTexture( texture, size, size, x, y ); +} + +//====================================================================== +// Function: drawTexture +// Purpose : +//======================================================================= +void GLViewer_Drawer::drawTexture( GLuint texture, GLint x_size, GLint y_size, GLfloat x, GLfloat y ) +{ + /*float xScale = myXScale; + float yScale = myYScale; + + glColor4f( 1.0, 1.0, 1.0, 1.0 ); + + glEnable( GL_TEXTURE_2D ); + glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); + glAlphaFunc( GL_GREATER, 0.95F ); + glEnable( GL_ALPHA_TEST ); + + glBindTexture( GL_TEXTURE_2D, texture ); + glBegin( GL_QUADS ); + + glTexCoord2f( 0.0, 0.0 ); + glVertex3f( x-x_size/2./xScale, y-y_size/2./yScale, 0.0 ); + + glTexCoord2f( 0.0, 1.0 ); + glVertex3f( x-x_size/2./xScale, y+y_size/2./yScale, 0.0 ); + + glTexCoord2f( 1.0, 1.0 ); + glVertex3f( x+x_size/2./xScale, y+y_size/2./yScale, 0.0 ); + + glTexCoord2f( 1.0, 0.0 ); + glVertex3f( x+x_size/2./xScale, y-y_size/2./yScale, 0.0 ); + + glEnd(); + glFlush(); + + glDisable( GL_ALPHA_TEST ); + glDisable( GL_TEXTURE_2D );*/ + drawTexturePart( texture, 1.0, 1.0, x_size, y_size, x, y ); +} + +//====================================================================== +// Function: drawTexture +// Purpose : +//======================================================================= +void GLViewer_Drawer::drawTexturePart( GLuint texture, + GLfloat x_ratio, + GLfloat y_ratio, + GLfloat x_size, + GLfloat y_size, + GLfloat x, + GLfloat y, + GLfloat scale ) +{ + if( !texture ) + return; + + float xScale = scale > 0. ? 1./scale : myXScale; + float yScale = scale > 0. ? 1./scale : myYScale; + + glColor4f( 1.0, 1.0, 1.0, 1.0 ); + + + glEnable( GL_TEXTURE_2D ); + glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); + bool hasAlpha = glIsEnabled( GL_ALPHA_TEST ); + glDisable( GL_ALPHA_TEST ); + + glBindTexture( GL_TEXTURE_2D, texture ); + glBegin( GL_QUADS ); + + glTexCoord2f( 0.0, 0.0 ); + glVertex3f( x-x_size/2./xScale, y-y_size/2./yScale, 0.0 ); + + glTexCoord2f( 0.0, y_ratio ); + glVertex3f( x-x_size/2./xScale, y+y_size/2./yScale, 0.0 ); + + glTexCoord2f( x_ratio, y_ratio ); + glVertex3f( x+x_size/2./xScale, y+y_size/2./yScale, 0.0 ); + + glTexCoord2f( x_ratio, 0.0 ); + glVertex3f( x+x_size/2./xScale, y-y_size/2./yScale, 0.0 ); + + glEnd(); + glFlush(); + + if ( hasAlpha ) + glEnable( GL_ALPHA_TEST ); + + glDisable( GL_TEXTURE_2D ); +} + +//====================================================================== +// Function: drawText +// Purpose : +//======================================================================= +void GLViewer_Drawer::drawText( const QString& text, GLfloat xPos, GLfloat yPos, + const QColor& color, QFont* theFont, int theSeparator, DisplayTextFormat theFormat ) +{ + glColor3f( ( GLfloat )color.red() / 255, + ( GLfloat )color.green() / 255, + ( GLfloat )color.blue() / 255 ); + + if( theFormat != DTF_BITMAP ) + { + GLViewer_TexFont aTexFont( theFont, theSeparator, theFormat == DTF_TEXTURE_SCALABLE, GL_LINEAR ); + aTexFont.generateTexture(); + aTexFont.drawString( text, xPos, yPos ); + } + else + { + glRasterPos2f( xPos, yPos ); + glListBase( displayListBase( theFont ) ); + glCallLists( text.length(), GL_UNSIGNED_BYTE, text.local8Bit().data() ); + } +} + +//====================================================================== +// Function: drawText +// Purpose : +//======================================================================= +void GLViewer_Drawer::drawText( GLViewer_Object* theObject ) +{ + if( !theObject ) + return; + + GLViewer_Text* aText = theObject->getGLText(); + if( !aText ) + return; + + GLfloat aPosX, aPosY; + aText->getPosition( aPosX, aPosY ); + // get temporary copy of font + QFont aTmpVarFont = aText->getFont(); + drawText( aText->getText(), aPosX, aPosY, aText->getColor(), &aTmpVarFont, aText->getSeparator(), aText->getDisplayTextFormat() ); +} + +//====================================================================== +// Function: drawGLText +// Purpose : +//======================================================================= +void GLViewer_Drawer::drawGLText( QString text, float x, float y, + int hPosition, int vPosition, QColor color, bool smallFont ) +{ + QFont aFont( myFont ); + if( smallFont ) + aFont.setPointSize( aFont.pointSize() * 0.8 ); + + QFontMetrics aFontMetrics( aFont ); + float width = myTextFormat == DTF_TEXTURE_SCALABLE ? aFontMetrics.width( text ) : aFontMetrics.width( text ) / myXScale; + float height = myTextFormat == DTF_TEXTURE_SCALABLE ? aFontMetrics.height() : aFontMetrics.height() / myYScale; + float gap = 5 / myXScale; + + switch( hPosition ) + { + case GLText_Left : x -= ( gap + width ); break; + case GLText_Center : x -= width / 2; break; + case GLText_Right : x += gap; break; + default : break; + } + + switch( vPosition ) + { + case GLText_Top : y += height * 0.5; break; + case GLText_Center : y -= height * 0.5; break; + case GLText_Bottom : y -= height * 1.5; break; + default : break; + } + + drawText( text, x, y, color, &aFont, 2, myTextFormat ); +} + +//====================================================================== +// Function: drawRectangle +// Purpose : +//======================================================================= +void GLViewer_Drawer::drawRectangle( GLViewer_Rect* rect, QColor color ) +{ + if( !rect ) + return; + + float x1 = rect->left(); + float x2 = rect->right(); + float y1 = rect->bottom(); + float y2 = rect->top(); + + glColor3f( ( GLfloat )color.red() / 255, + ( GLfloat )color.green() / 255, + ( GLfloat )color.blue() / 255 ); + glLineWidth( 1.0 ); + + glBegin( GL_LINE_LOOP ); + glVertex2f( x1, y1 ); + glVertex2f( x1, y2 ); + glVertex2f( x2, y2 ); + glVertex2f( x2, y1 ); + glEnd(); +} + +//====================================================================== +// Function: translateToHPGL +// Purpose : +//======================================================================= +bool GLViewer_Drawer::translateToHPGL( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aHPGLCS ) +{ + bool result = true; + for( int i=0, n=myObjects.count(); itranslateToHPGL( hFile, aViewerCS, aHPGLCS ); + return result; +} + +//====================================================================== +// Function: translateToPS +// Purpose : +//======================================================================= +bool GLViewer_Drawer::translateToPS( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPSCS ) +{ + bool result = true; + for( int i=0, n=myObjects.count(); itranslateToPS( hFile, aViewerCS, aPSCS ); + return result; +} + +#ifdef WIN32 +//====================================================================== +// Function: translateToEMF +// Purpose : +//======================================================================= +bool GLViewer_Drawer::translateToEMF( HDC hDC, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aEMFCS ) +{ + bool result = true; + for( int i=0, n=myObjects.count(); itranslateToEMF( hDC, aViewerCS, aEMFCS ); + return result; +} +#endif diff --git a/src/LightApp/LightApp_DataOwner.cxx b/src/LightApp/LightApp_DataOwner.cxx new file mode 100644 index 000000000..add34d91f --- /dev/null +++ b/src/LightApp/LightApp_DataOwner.cxx @@ -0,0 +1,78 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "LightApp_DataOwner.h" + +#include "LightApp_DataObject.h" + +#ifndef WNT +#include +#define _typeinfo std::type_info +#else +#include +#define _typeinfo type_info +#endif + +#include + +/*!Constructor. Initialize by \a theEntry.*/ +LightApp_DataOwner +::LightApp_DataOwner( const QString& theEntry ): + myEntry( theEntry ) +{ +} + +/*!Constructor. Initialize by \a SALOME_InteractiveObject.*/ +LightApp_DataOwner +::LightApp_DataOwner( const Handle(SALOME_InteractiveObject)& theIO ): + myEntry(!theIO.IsNull()? theIO->getEntry(): ""), + myIO(theIO) +{ +} + +/*!Destructor. Do nothing.*/ +LightApp_DataOwner +::~LightApp_DataOwner() +{ +} + +/*!Checks: Is current data owner equal \a obj.*/ +bool +LightApp_DataOwner +::isEqual( const SUIT_DataOwner& obj ) const +{ + const LightApp_DataOwner* other = dynamic_cast( &obj ); + + return other && entry() == other->entry(); +} + +/*!Gets entry.*/ +QString +LightApp_DataOwner +::entry() const +{ + return myEntry; +} + +/*!Gets SALOME_InteractiveObject.*/ +const Handle(SALOME_InteractiveObject)& +LightApp_DataOwner +::IO() const +{ + return myIO; +} diff --git a/src/LightApp/LightApp_DataOwner.h b/src/LightApp/LightApp_DataOwner.h new file mode 100644 index 000000000..d76e6d411 --- /dev/null +++ b/src/LightApp/LightApp_DataOwner.h @@ -0,0 +1,48 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// + +#ifndef LIGHTAPP_DATAOWNER_H +#define LIGHTAPP_DATAOWNER_H + +#include "LightApp.h" +#include "SUIT_DataOwner.h" +#include "SALOME_InteractiveObject.hxx" + +/*! + This class provide data owner objects. +*/ +class LIGHTAPP_EXPORT LightApp_DataOwner : public SUIT_DataOwner +{ +public: + LightApp_DataOwner( const Handle(SALOME_InteractiveObject)& theIO ); + LightApp_DataOwner( const QString& ); + virtual ~LightApp_DataOwner(); + + virtual bool isEqual( const SUIT_DataOwner& ) const; + const Handle(SALOME_InteractiveObject)& IO() const; + QString entry() const; + +private: + QString myEntry; + Handle(SALOME_InteractiveObject) myIO; +}; + +typedef SMART(LightApp_DataOwner) LightApp_DataOwnerPtr; + +#endif diff --git a/src/LightApp/LightApp_DataSubOwner.cxx b/src/LightApp/LightApp_DataSubOwner.cxx new file mode 100644 index 000000000..c5a6703a4 --- /dev/null +++ b/src/LightApp/LightApp_DataSubOwner.cxx @@ -0,0 +1,53 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "LightApp_DataSubOwner.h" + +#include "LightApp_DataObject.h" + +#ifdef WNT +#include +#endif + +/*!Constructor.Initialize by \a entry and \a index*/ +LightApp_DataSubOwner::LightApp_DataSubOwner( const QString& entry, const int index ) +: LightApp_DataOwner( entry ), +myIndex( index ) +{ +} + +/*!Destructor. Do nothing.*/ +LightApp_DataSubOwner::~LightApp_DataSubOwner() +{ +} + +/*!Checks: Is current data sub owner equal \a obj.*/ +bool LightApp_DataSubOwner::isEqual( const SUIT_DataOwner& obj ) const +{ + if (LightApp_DataOwner::isEqual(obj)) { + const LightApp_DataSubOwner* other = dynamic_cast( &obj ); + return other && index() == other->index(); + } + return false; +} + +/*!Gets index.*/ +int LightApp_DataSubOwner::index() const +{ + return myIndex; +} diff --git a/src/LightApp/LightApp_DataSubOwner.h b/src/LightApp/LightApp_DataSubOwner.h new file mode 100644 index 000000000..507684d5f --- /dev/null +++ b/src/LightApp/LightApp_DataSubOwner.h @@ -0,0 +1,42 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// + +#ifndef LIGHTAPP_DATASUBOWNER_H +#define LIGHTAPP_DATASUBOWNER_H + +#include +#include + +/*! + Class provide sub owner. + */ +class LIGHTAPP_EXPORT LightApp_DataSubOwner : public LightApp_DataOwner +{ +public: + LightApp_DataSubOwner( const QString&, const int ); + virtual ~LightApp_DataSubOwner(); + + virtual bool isEqual( const SUIT_DataOwner& ) const; + int index() const; + +private: + int myIndex; +}; + +#endif diff --git a/src/LightApp/LightApp_Dialog.cxx b/src/LightApp/LightApp_Dialog.cxx new file mode 100644 index 000000000..b77f62f01 --- /dev/null +++ b/src/LightApp/LightApp_Dialog.cxx @@ -0,0 +1,878 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: LightApp_Dialog.cxx +// Author: Alexander SOLOVYOV + +#include +#include + +#include +#include +#include + +/* + Class : LightApp_Dialog + Description : Base class for all dialogs +*/ + +//======================================================================= +// name : LightApp_Dialog +// Purpose : Constructor +//======================================================================= +LightApp_Dialog::LightApp_Dialog( QWidget* parent, const char* name, bool modal, + bool allowResize, const int f, WFlags wf ) +: QtxDialog( parent, name, modal, allowResize, f, wf ), + myIsExclusive( true ), + myIsBusy( false ) +{ + setObjectPixmap( "LightApp", tr( "ICON_SELECT" ) ); +} + +//======================================================================= +// name : ~LightApp_Dialog +// Purpose : Destructor +//======================================================================= +LightApp_Dialog::~LightApp_Dialog() +{ +} + +//======================================================================= +// name : show +// Purpose : +//======================================================================= +void LightApp_Dialog::show() +{ + QtxDialog::show(); +} + +//======================================================================= +// name : isExclusive +// Purpose : +//======================================================================= +bool LightApp_Dialog::isExclusive() const +{ + return myIsExclusive; +} + +//======================================================================= +// name : updateButtons +// Purpose : +//======================================================================= +void LightApp_Dialog::updateButtons( const int _id ) +{ + if( !myIsExclusive ) + return; + + int id = _id; + + ObjectMap::const_iterator anIt = myObjects.begin(), + aLast = myObjects.end(); + for( ; anIt!=aLast; anIt++ ) + { + QToolButton* but = (QToolButton*)anIt.data().myBtn; + if( but && but->isOn() ) + { + if( id==-1 ) + id = anIt.key(); + + if( anIt.key()!=id ) + but->setOn( false ); + } + } +} + +//======================================================================= +// name : setExclusive +// Purpose : +//======================================================================= +void LightApp_Dialog::setExclusive( const bool ex ) +{ + myIsExclusive = ex; + updateButtons(); +} + +//======================================================================= +// name : showObject +// Purpose : +//======================================================================= +void LightApp_Dialog::showObject( const int id ) +{ + setObjectShown( id, true ); +} + +//======================================================================= +// name : hideObject +// Purpose : +//======================================================================= +void LightApp_Dialog::hideObject( const int id ) +{ + setObjectShown( id, false ); +} + +//======================================================================= +// name : setObjectShown +// Purpose : +//======================================================================= +void LightApp_Dialog::setObjectShown( const int id, const bool shown ) +{ + if( myObjects.contains( id ) && isObjectShown( id )!=shown ) + { + Object& obj = myObjects[ id ]; + obj.myEdit->setShown( shown ); + obj.myBtn->setShown( shown ); + obj.myLabel->setShown( shown ); + if( !shown ) + ( ( QToolButton* )obj.myBtn )->setOn( false ); + } +} + +//======================================================================= +// name : isObjectShown +// Purpose : +//======================================================================= +bool LightApp_Dialog::isObjectShown( const int id ) const +{ + return myObjects.contains( id ) && myObjects[ id ].myEdit->isShown(); +} + +//======================================================================= +// name : setObjectEnabled +// Purpose : +//======================================================================= +void LightApp_Dialog::setObjectEnabled( const int id, const bool en ) +{ + if( myObjects.contains( id ) && isObjectEnabled( id )!=en ) + { + Object& obj = myObjects[ id ]; + obj.myEdit->setEnabled( en ); + obj.myBtn->setEnabled( en ); +// obj.myLabel->setEnabled( en ); + if( !en ) + ( ( QToolButton* )obj.myBtn )->setOn( false ); + } +} + +//======================================================================= +// name : isObjectEnabled +// Purpose : +//======================================================================= +bool LightApp_Dialog::isObjectEnabled( const int id ) const +{ + return myObjects.contains( id ) && myObjects[ id ].myEdit->isEnabled(); +} + +//======================================================================= +// name : selectObject +// Purpose : +//======================================================================= +void LightApp_Dialog::selectObject( const QString& name, const int type, const QString& id, const bool update ) +{ + QStringList names; names.append( name ); + TypesList types; types.append( type ); + QStringList ids; ids.append( id ); + selectObject( names, types, ids, update ); +} + +//======================================================================= +// name : selectObject +// Purpose : +//======================================================================= +void LightApp_Dialog::selectObject( const QStringList& _names, + const TypesList& _types, + const QStringList& _ids, + const bool update ) +{ + ObjectMap::iterator anIt = myObjects.begin(), + aLast = myObjects.end(); + for( ; anIt!=aLast; anIt++ ) + if( anIt.data().myBtn->isOn() ) + selectObject( anIt.key(), _names, _types, _ids, update ); +} + +//======================================================================= +// name : hasSelection +// Purpose : +//======================================================================= +bool LightApp_Dialog::hasSelection( const int id ) const +{ + return myObjects.contains( id ) && !myObjects[ id ].myIds.isEmpty(); +} + +//======================================================================= +// name : clearSelection +// Purpose : +//======================================================================= +void LightApp_Dialog::clearSelection( const int id ) +{ + if( id==-1 ) + { + ObjectMap::const_iterator anIt = myObjects.begin(), + aLast = myObjects.end(); + for( ; anIt!=aLast; anIt++ ) + clearSelection( anIt.key() ); + } + + else if( myObjects.contains( id ) ) + { + myObjects[ id ].myIds.clear(); + myObjects[ id ].myTypes.clear(); + myObjects[ id ].myNames.clear(); + + myObjects[ id ].myEdit->setText( QString::null ); + emit selectionChanged( id ); + } +} + +//======================================================================= +// name : objectWg +// Purpose : +//======================================================================= +QWidget* LightApp_Dialog::objectWg( const int theId, const int theWgId ) const +{ + QWidget* aResWg = 0; + if( myObjects.contains( theId ) ) + { + if ( theWgId == Label ) + aResWg = myObjects[ theId ].myLabel; + else if ( theWgId == Btn ) + aResWg = myObjects[ theId ].myBtn; + else if ( theWgId == Control ) + aResWg = myObjects[ theId ].myEdit; + } + return aResWg; +} + +//======================================================================= +// name : objectText +// Purpose : +//======================================================================= +QString LightApp_Dialog::objectText( const int theId ) const +{ + return myObjects.contains( theId ) ? myObjects[ theId ].myEdit->text() : ""; +} + +//======================================================================= +// name : setObjectText +// Purpose : +//======================================================================= +void LightApp_Dialog::setObjectText( const int theId, const QString& theText ) +{ + if ( myObjects.contains( theId ) ) + myObjects[ theId ].myEdit->setText( theText ); +} + +//======================================================================= +// name : selectedObject +// Purpose : +//======================================================================= +void LightApp_Dialog::selectedObject( const int id, QStringList& list ) const +{ + if( myObjects.contains( id ) ) + list = myObjects[ id ].myIds; +} + +//======================================================================= +// name : selectedObject +// Purpose : +//======================================================================= +QString LightApp_Dialog::selectedObject( const int id ) const +{ + if ( myObjects.contains( id ) && myObjects[ id ].myIds.count() > 0 ) + return myObjects[ id ].myIds.first(); + else + return ""; +} + +//======================================================================= +// name : objectSelection +// Purpose : +//======================================================================= +void LightApp_Dialog::objectSelection( SelectedObjects& objs ) const +{ + //objs.clear(); + ObjectMap::const_iterator anIt = myObjects.begin(), + aLast = myObjects.end(); + for( ; anIt!=aLast; anIt++ ) + { + QStringList ids; + selectedObject( anIt.key(), ids ); + if( !ids.isEmpty() ) + objs.insert( anIt.key(), ids ); + } +} + +//======================================================================= +// name : createObject +// Purpose : +//======================================================================= +int LightApp_Dialog::createObject( const QString& label, QWidget* parent, const int id ) +{ + int nid = id; + if( nid<0 ) + for( nid=0; myObjects.contains( nid ); nid++ ); + + if( !myObjects.contains( nid ) ) + { + QLabel* lab = new QLabel( label, parent ); + myObjects[ nid ].myLabel = lab; + + QToolButton* but = new QToolButton( parent ); + but->setIconSet( QIconSet( myPixmap ) ); + but->setToggleButton( true ); + but->setMaximumWidth( but->height() ); + but->setMinimumWidth( but->height() ); + connect( but, SIGNAL( toggled( bool ) ), this, SLOT( onToggled( bool ) ) ); + myObjects[ nid ].myBtn = but; + + QLineEdit* ne = new QLineEdit( parent ); + ne->setReadOnly( true ); + ne->setMinimumWidth( 150 ); + connect( ne, SIGNAL( textChanged( const QString& ) ), this, SLOT( onTextChanged( const QString& ) ) ); + myObjects[ nid ].myEdit = ne; + + myObjects[ nid ].myNI = OneNameOrCount; + } + return nid; +} + +//======================================================================= +// name : renameObject +// Purpose : +//======================================================================= +void LightApp_Dialog::renameObject( const int id, const QString& label ) +{ + if( myObjects.contains( id ) ) + myObjects[ id ].myLabel->setText( label ); +} + +//======================================================================= +// name : setObjectType +// Purpose : +//======================================================================= +void LightApp_Dialog::setObjectType( const int id, const int type1, ... ) +{ + TypesList types; + + const int* tt = &type1; + while( *tt>=0 ) + { + types.append( *tt ); + tt++; + } + + setObjectType( id, types ); +} + +//======================================================================= +// name : setObjectType +// Purpose : +//======================================================================= +void LightApp_Dialog::setObjectType( const int id, const TypesList& list ) +{ + if( !myObjects.contains( id ) ) + return; + + TypesList& internal = myObjects[ id ].myPossibleTypes; + + QMap types; + TypesList::const_iterator anIt = list.begin(), + aLast = list.end(); + for( ; anIt!=aLast; anIt++ ) + types.insert( *anIt, 0 ); + + + internal.clear(); + QMap::const_iterator aMIt = types.begin(), + aMLast = types.end(); + for( ; aMIt!=aMLast; aMIt++ ) + internal.append( aMIt.key() ); + + updateObject( id ); +} + +//======================================================================= +// name : addObjectType +// Purpose : +//======================================================================= +void LightApp_Dialog::addObjectType( const int id, const int type1, const int, ... ) +{ + TypesList types; objectTypes( id, types ); + + const int* tt = &type1; + while( *tt>=0 ) + { + types.append( *tt ); + tt++; + } + + setObjectType( id, types ); +} + +//======================================================================= +// name : addObjectType +// Purpose : +//======================================================================= +void LightApp_Dialog::addObjectType( const int id, const TypesList& list ) +{ + TypesList types = list; objectTypes( id, types ); + setObjectType( id, types ); +} + +//======================================================================= +// name : addObjectType +// Purpose : +//======================================================================= +void LightApp_Dialog::addObjectType( const int id, const int type ) +{ + TypesList types; objectTypes( id, types ); + types.append( type ); + setObjectType( id, types ); +} + +//======================================================================= +// name : removeObjectType +// Purpose : +//======================================================================= +void LightApp_Dialog::removeObjectType( const int id ) +{ + TypesList types; + setObjectType( id, types ); +} + +//======================================================================= +// name : removeObjectType +// Purpose : +//======================================================================= +void LightApp_Dialog::removeObjectType( const int id, const TypesList& list ) +{ + if( !myObjects.contains( id ) ) + return; + + TypesList& internal = myObjects[ id ].myPossibleTypes; + + QMap types; + TypesList::const_iterator anIt = internal.begin(), + aLast = internal.end(); + for( ; anIt!=aLast; anIt++ ) + types.insert( *anIt, 0 ); + anIt = list.begin(); aLast = list.end(); + for( ; anIt!=aLast; anIt++ ) + types.remove( *anIt ); + + + internal.clear(); + QMap::const_iterator aMIt = types.begin(), + aMLast = types.end(); + for( ; aMIt!=aMLast; aMIt++ ) + internal.append( aMIt.key() ); + + updateObject( id ); +} + +//======================================================================= +// name : removeObjectType +// Purpose : +//======================================================================= +void LightApp_Dialog::removeObjectType( const int id, const int type ) +{ + TypesList list; list.append( type ); + removeObjectType( id, list ); +} + +//======================================================================= +// name : hasObjectType +// Purpose : +//======================================================================= +bool LightApp_Dialog::hasObjectType( const int id, const int type ) const +{ + if( myObjects.contains( id ) ) + return myObjects[ id ].myPossibleTypes.contains( type ); + else + return false; +} + +//======================================================================= +// name : objectTypes +// Purpose : +//======================================================================= +void LightApp_Dialog::objectTypes( const int id, TypesList& list ) const +{ + if( myObjects.contains( id ) ) + { + TypesList::const_iterator anIt = myObjects[ id ].myPossibleTypes.begin(), + aLast = myObjects[ id ].myPossibleTypes.end(); + for( ; anIt!=aLast; anIt++ ) + list.append( *anIt ); + } +} + +//======================================================================= +// name : onToggled +// Purpose : +//======================================================================= +void LightApp_Dialog::onToggled( bool on ) +{ + QButton* but = ( QButton* )sender(); + int id = -1; + + if( !but ) + return; + + ObjectMap::const_iterator anIt = myObjects.begin(), + aLast = myObjects.end(); + for( ; anIt!=aLast && id==-1; anIt++ ) + if( anIt.data().myBtn==but ) + id = anIt.key(); + + if( id!=-1 ) + if( on ) + { + updateButtons( id ); + emit objectActivated( id ); + } + else + emit objectDeactivated( id ); +} + +//======================================================================= +// name : updateObject +// Purpose : +//======================================================================= +void LightApp_Dialog::updateObject( const int id, bool emit_signal ) +{ + if( hasSelection( id ) ) + { + Object& obj = myObjects[ id ]; + filterTypes( id, obj.myNames, obj.myTypes, obj.myIds ); + obj.myEdit->setText( selectionDescription( obj.myNames, obj.myTypes, obj.myNI ) ); + if( emit_signal ) + emit selectionChanged( id ); + } +} + +//======================================================================= +// name : filterTypes +// Purpose : +//======================================================================= +void LightApp_Dialog::filterTypes( const int id, QStringList& names, TypesList& types, QStringList& ids ) const +{ + if( !myObjects.contains( id ) ) + return; + + const Object& obj = myObjects[ id ]; + if( obj.myPossibleTypes.isEmpty() ) + return; + + QStringList new_names, new_ids; + TypesList new_types; + + TypesList::const_iterator anIt1 = types.begin(), + aLast = types.end(); + QStringList::const_iterator anIt2 = names.begin(), + anIt3 = ids.begin(); + for( ; anIt1!=aLast; anIt1++, anIt2++, anIt3++ ) + if( obj.myPossibleTypes.contains( *anIt1 ) ) + { + if( new_types.count()==1 && !multipleSelection( id ) ) + break; + + new_names.append( *anIt2 ); + new_types.append( *anIt1 ); + new_ids.append( *anIt3 ); + } + names = new_names; + types = new_types; + ids = new_ids; +} + +//======================================================================= +// name : resMgr +// Purpose : +//======================================================================= +SUIT_ResourceMgr* LightApp_Dialog::resMgr() const +{ + return SUIT_Session::session()->resourceMgr(); +} + +//======================================================================= +// name : setObjectPixmap +// Purpose : +//======================================================================= +void LightApp_Dialog::setObjectPixmap( const QPixmap& p ) +{ + myPixmap = p; + ObjectMap::const_iterator anIt = myObjects.begin(), + aLast = myObjects.end(); + for( ; anIt!=aLast; anIt++ ) + ( ( QToolButton* )anIt.data().myBtn )->setIconSet( p ); +} + +//======================================================================= +// name : setObjectPixmap +// Purpose : +//======================================================================= +void LightApp_Dialog::setObjectPixmap( const QString& section, const QString& file ) +{ + SUIT_ResourceMgr* mgr = resMgr(); + if( mgr ) + setObjectPixmap( mgr->loadPixmap( section, file ) ); +} + +//======================================================================= +// name : multipleSelection +// Purpose : +//======================================================================= +bool LightApp_Dialog::multipleSelection( const int id ) const +{ + return nameIndication( id )!=OneName; +} + +//======================================================================= +// name : nameIndication +// Purpose : +//======================================================================= +LightApp_Dialog::NameIndication LightApp_Dialog::nameIndication( const int id ) const +{ + if( myObjects.contains( id ) ) + return myObjects[ id ].myNI; + else + return OneNameOrCount; +} + +//======================================================================= +// name : setNameIndication +// Purpose : +//======================================================================= +void LightApp_Dialog::setNameIndication( const int id, const NameIndication ni ) +{ + if( id==-1 ) + { + ObjectMap::iterator anIt = myObjects.begin(), + aNext, + aLast = myObjects.end(); + for( ; anIt!=aLast; anIt++ ) + { + anIt.data().myNI = ni; + setReadOnly( anIt.key(), isReadOnly( anIt.key() ) ); + aNext = anIt; aNext++; + updateObject( anIt.key(), aNext==aLast ); + } + } + else if( myObjects.contains( id ) ) + { + myObjects[ id ].myNI = ni; + setReadOnly( id, isReadOnly( id ) ); + updateObject( id, true ); + } +} + +//======================================================================= +// name : selectionDescription +// Purpose : +//======================================================================= +QString LightApp_Dialog::selectionDescription( const QStringList& names, const TypesList& types, const NameIndication ni ) const +{ + if( names.count()!=types.count() ) + return "LightApp_Dialog::selectionDescription(): Error!!!"; + + if( names.isEmpty() ) + return QString::null; + + switch( ni ) + { + case OneName: + return names.first(); + break; + + case OneNameOrCount: + if( names.count()==1 ) + return names.first(); + else + return countOfTypes( types ); + break; + + case ListOfNames: + return names.join( " " ); + break; + + case Count: + return countOfTypes( types ); + break; + }; + return QString::null; +} + +//======================================================================= +// name : countOfTypes +// Purpose : +//======================================================================= +QString LightApp_Dialog::countOfTypes( const TypesList& types ) const +{ + QMap typesCount; + QStringList typeCount; + + TypesList::const_iterator anIt = types.begin(), + aLast = types.end(); + for( ; anIt!=aLast; anIt++ ) + if( typesCount.contains( *anIt ) ) + typesCount[ *anIt ]++; + else + typesCount[ *anIt ] = 1; + + QMap::const_iterator aMIt = typesCount.begin(), + aMLast = typesCount.end(); + for( ; aMIt!=aMLast; aMIt++ ) + typeCount.append( QString( "%1 %2" ).arg( aMIt.data() ).arg( typeName( aMIt.key() ) ) ); + + return typeCount.join( ", " ); +} + +//======================================================================= +// name : typeName +// Purpose : +//======================================================================= +QString& LightApp_Dialog::typeName( const int type ) +{ + return myTypeNames[ type ]; +} + +//======================================================================= +// name : typeName +// Purpose : +//======================================================================= +const QString& LightApp_Dialog::typeName( const int type ) const +{ + return myTypeNames[ type ]; +} + + +//======================================================================= +// name : activateObject +// Purpose : +//======================================================================= +void LightApp_Dialog::activateObject( const int theId ) +{ + if ( myObjects.contains( theId ) && !myObjects[ theId ].myBtn->isOn() ) + myObjects[ theId ].myBtn->toggle(); +} + +//======================================================================= +// name : deactivateAll +// Purpose : +//======================================================================= +void LightApp_Dialog::deactivateAll() +{ + ObjectMap::iterator anIt = myObjects.begin(), + aLast = myObjects.end(); + for( ; anIt!=aLast; anIt++ ) + { + QToolButton* btn = ( QToolButton* )anIt.data().myBtn; + btn->setOn( false ); + } +} + +//======================================================================= +// name : selectObject +// Purpose : +//======================================================================= +void LightApp_Dialog::selectObject( const int id, const QString& name, const int type, const QString& selid, const bool update ) +{ + QStringList names; names.append( name ); + TypesList types; types.append( type ); + QStringList ids; ids.append( selid ); + selectObject( id, names, types, ids, update ); +} + +//======================================================================= +// name : selectObject +// Purpose : +//======================================================================= +void LightApp_Dialog::selectObject( const int id, const QStringList& _names, const TypesList& _types, + const QStringList& _ids, const bool update ) +{ + if( !myObjects.contains( id ) ) + return; + + QStringList names = _names, ids = _ids; + TypesList types = _types; + + filterTypes( id, names, types, ids ); + + Object& obj = myObjects[ id ]; + if( update ) + obj.myEdit->setText( selectionDescription( names, types, obj.myNI ) ); + obj.myTypes = types; + obj.myIds = ids; + obj.myNames = names; + + emit selectionChanged( id ); +} + +//======================================================================= +// name : setReadOnly +// Purpose : +//======================================================================= +void LightApp_Dialog::setReadOnly( const int id, const bool ro ) +{ + if( myObjects.contains( id ) ) + myObjects[ id ].myEdit->setReadOnly( nameIndication( id )==ListOfNames || nameIndication( id )==OneName ? ro : true ); +} + +//======================================================================= +// name : isReadOnly +// Purpose : +//======================================================================= +bool LightApp_Dialog::isReadOnly( const int id ) const +{ + if( myObjects.contains( id ) ) + return myObjects[ id ].myEdit->isReadOnly(); + else + return true; +} + +//======================================================================= +// name : onTextChanged +// Purpose : +//======================================================================= +void LightApp_Dialog::onTextChanged( const QString& text ) +{ + if( myIsBusy ) + return; + + myIsBusy = true; + + if( sender() && sender()->inherits( "QLineEdit" ) ) + { + QLineEdit* edit = ( QLineEdit* )sender(); + int id = -1; + ObjectMap::const_iterator anIt = myObjects.begin(), + aLast = myObjects.end(); + for( ; anIt!=aLast; anIt++ ) + if( anIt.data().myEdit == edit ) + id = anIt.key(); + + if( id>=0 && !isReadOnly( id ) ) + { + QStringList list = QStringList::split( " ", text ); + emit objectChanged( id, list ); + } + } + + myIsBusy = false; +} diff --git a/src/LightApp/LightApp_Dialog.h b/src/LightApp/LightApp_Dialog.h new file mode 100644 index 000000000..12fd50154 --- /dev/null +++ b/src/LightApp/LightApp_Dialog.h @@ -0,0 +1,285 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: LightApp_Dialog.h +// Author: Alexander SOLOVYOV + +#ifndef LIGHTAPP_DIALOG_H +#define LIGHTAPP_DIALOG_H + +#include "LightApp.h" +#include + +#include +#include +#include + +class QLineEdit; +class QButton; +class QLabel; + +class SUIT_ResourceMgr; + +/* + Class : LightApp_Dialog + Description : Base class for all LightApp dialogs +*/ +class LIGHTAPP_EXPORT LightApp_Dialog : public QtxDialog +{ + Q_OBJECT + +public: + typedef QValueList TypesList; + typedef QMap SelectedObjects; + + enum ObjectWg + { + Label = 0x00000001, + Btn = 0x00000002, + Control = 0x00000004 + }; + + typedef enum + { + OneName, // " is shown + ListOfNames, //! list of all names is shown + Count //! In every case " " is shown + + } NameIndication; + //! The enumeration describing how names of selected objects will be shown in line edit + //! For more details see above + +public: + LightApp_Dialog( QWidget* = 0, const char* = 0, bool = false, + bool = false, const int = Standard, WFlags = 0 ); + virtual ~LightApp_Dialog(); + + virtual void show(); + + //! Check if buttons is exclusive (as radiobuttons) + bool isExclusive() const; + + //! Set exclusive state + void setExclusive( const bool ); + + //! Check if operation according to dialog will be resumed automatically when mouse enter the dialog + bool isAutoResumed() const; + + //! Set auto resumed state + void setAutoResumed( const bool ); + + //! Show widgets corresponding to id + void showObject( const int ); + + //! Hide widgets corresponding to id + void hideObject( const int ); + + //! Change the shown state of widgets corresponding to id + void setObjectShown( const int, const bool ); + + //! Check the shown state + bool isObjectShown( const int ) const; + + //! Change the enabled state of widgets corresponding to id + void setObjectEnabled( const int, const bool ); + + //! Check the enabled state + bool isObjectEnabled( const int ) const; + + //! Get widget of object (see ObjectWg enumeration) + QWidget* objectWg( const int theId, const int theWgId ) const; + + //! Pass to all active widgets name, type and id of selected object + void selectObject( const QString&, const int, const QString&, const bool = true ); + + /*! + Pass to all active widgets list of names, types and ids of selected objects + Every active widget filters list and accept only objects with possible types + */ + void selectObject( const QStringList&, const TypesList&, const QStringList&, const bool = true ); + + //! Get text of object's control + QString objectText( const int ) const; + + //! Set text of object's control + void setObjectText( const int, const QString& ); + + //! Select in certain widget avoiding check if there is active widget + void selectObject( const int, const QString&, const int, const QString&, const bool = true ); + void selectObject( const int, const QStringList&, const TypesList&, const QStringList&, const bool = true ); + + //! Check if certain widget has selection + bool hasSelection( const int ) const; + + //! Clear selection in widgets. If parameter is -1, then selection in all widgets will be cleared + void clearSelection( const int = -1 ); + + //! Get ids list of object selected in certain widget + void selectedObject( const int, QStringList& ) const; + + //! Get ids list of object selected in certain widget + QString selectedObject( const int ) const; + + //! Get map "widget id -> ids list" + void objectSelection( SelectedObjects& ) const; + + //! Activate object selection button + void activateObject( const int ); + + //! Set all object selection buttons to inactive state + void deactivateAll(); + +signals: + //! selection in certain widget is changed + void selectionChanged ( int ); + + //! selection in certain widget is on + void objectActivated ( int ); + + //! selection in certain widget is off + void objectDeactivated( int ); + + /* + text representation of selection is changed + it is emitted only if "read only" state of line edit is false + */ + void objectChanged( int, const QStringList& ); + +protected: + //! Finds and returns resource manager + SUIT_ResourceMgr* resMgr() const; + + /*! Create label, button and line edit for object selection + * If passed id is negative, then id will be calculated automatically (first free id) + * Returns the same id (if id>=0) or calculated + */ + int createObject ( const QString&, QWidget*, const int = -1 ); + + //! Set pixmap as icon for all selection buttons + void setObjectPixmap ( const QPixmap& ); + + //! Load pixmap with section, name using resource manager and set as icon for all selection buttons + void setObjectPixmap ( const QString&, const QString& ); + + //! Change label + void renameObject ( const int, const QString& ); + + //! Set possible types for certain id. The list of arguments must be finished by negative integer + void setObjectType ( const int, const int, ... ); + + //! Set list as possible types for object selection + void setObjectType ( const int, const TypesList& ); + + /*! + Add types to list of possible types + The list of arguments must be finished by negative integer + */ + void addObjectType ( const int, const int, const int, ... ); + + //! Add types to list of possible types + void addObjectType ( const int, const TypesList& ); + + //! Add type to list of possible types + void addObjectType ( const int, const int ); + + //! Clear list of possible types (it means, that all types are welcome) + void removeObjectType( const int ); + + //! Remove types in list from list of possible types + void removeObjectType( const int, const TypesList& ); + + //! Remove a type from list of possible types + void removeObjectType( const int, const int ); + + //! Check if list of possible types contains this one + bool hasObjectType ( const int, const int ) const; + + //! Return list of possible types + void objectTypes ( const int, TypesList& ) const; + + //!Change and get type name for indicating in selection widget + QString& typeName( const int ); + const QString& typeName( const int ) const; + + //! Create string contains selection list by list of names, list of types and current name indication state + virtual QString selectionDescription( const QStringList&, const TypesList&, const NameIndication ) const; + + //! Create string by pattern " " for current list of types + virtual QString countOfTypes( const TypesList& ) const; + + //! Get and set name indication for certain widget + NameIndication nameIndication( const int ) const; + void setNameIndication( const int, const NameIndication ); + + //! Check using name indication if multiple selection in possible + bool multipleSelection( const int ) const; + + //! Set the "read only" state of object selection line edit + //! The "read only" will be false only if name indication is ListOfNames + void setReadOnly( const int, const bool ); + + //! Check the "read only" state of object selection line edit + bool isReadOnly( const int ) const; + +private slots: + //! emits if the object selection button changes state + void onToggled( bool ); + + //! text in some line edit is changed + void onTextChanged( const QString& ); + +private: + /*! + If buttons are exclusive, set to "off" all buttons except one with id + If id=-1, then all buttons, except first with "on" state, will be set to "off" + */ + void updateButtons( const int = -1 ); + + /*! + Filter types and update selection string in line edit + If bool is true, then signal is emitted + */ + void updateObject( const int, bool = true ); + + //! Remove from list not possible types and remove from names and ids lists the corresponding items + void filterTypes( const int, QStringList&, TypesList&, QStringList& ) const; + +private: + typedef struct + { + QLineEdit* myEdit; + QButton* myBtn; + QLabel* myLabel; + QStringList myNames, myIds; + TypesList myTypes, myPossibleTypes; + NameIndication myNI; + + } Object; + + typedef QMap ObjectMap; + +private: + ObjectMap myObjects; + QMap myTypeNames; + bool myIsExclusive, myIsBusy; + QPixmap myPixmap; +}; + +#endif diff --git a/src/LightApp/LightApp_Displayer.cxx b/src/LightApp/LightApp_Displayer.cxx new file mode 100644 index 000000000..65ce0fa3c --- /dev/null +++ b/src/LightApp/LightApp_Displayer.cxx @@ -0,0 +1,211 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// + +#include "LightApp_Displayer.h" +#include "LightApp_Application.h" +#include "LightApp_Module.h" + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +LightApp_Displayer::LightApp_Displayer() +{ +} + +LightApp_Displayer::~LightApp_Displayer() +{ +} + +void LightApp_Displayer::Display( const QString& entry, const bool updateViewer, SALOME_View* theViewFrame ) +{ + SALOME_View* vf = theViewFrame ? theViewFrame : GetActiveView(); + if ( vf ) + { + SALOME_Prs* prs = buildPresentation( entry, vf ); + + if ( prs ) + { + vf->BeforeDisplay( this ); + vf->Display( prs ); + vf->AfterDisplay( this ); + + if ( updateViewer ) + vf->Repaint(); + + delete prs; // delete presentation because displayer is its owner + } + } +} + +void LightApp_Displayer::Redisplay( const QString& entry, const bool updateViewer ) +{ + // Remove the object permanently ( == true) + SUIT_Session* ses = SUIT_Session::session(); + SUIT_Application* app = ses->activeApplication(); + if ( app ) + { + SUIT_Desktop* desk = app->desktop(); + QPtrList wnds = desk->windows(); + SUIT_ViewWindow* wnd; + for ( wnd = wnds.first(); wnd; wnd = wnds.next() ) + { + SUIT_ViewManager* vman = wnd->getViewManager(); + if( !vman ) + continue; + + SUIT_ViewModel* vmodel = vman->getViewModel(); + if( !vmodel ) + continue; + + SALOME_View* view = dynamic_cast(vmodel); + if( view && ( IsDisplayed( entry, view ) || view == GetActiveView() ) ) + { + Erase( entry, true, false, view ); + Display( entry, updateViewer, view ); + } + } + } +} + +void LightApp_Displayer::Erase( const QString& entry, const bool forced, + const bool updateViewer, SALOME_View* theViewFrame ) +{ + SALOME_View* vf = theViewFrame ? theViewFrame : GetActiveView(); + + if ( vf ) { + SALOME_Prs* prs = vf->CreatePrs( entry.latin1() ); + if ( prs ) { + vf->Erase( prs, forced ); + if ( updateViewer ) + vf->Repaint(); + delete prs; // delete presentation because displayer is its owner + } + } +} + +void LightApp_Displayer::EraseAll( const bool forced, const bool updateViewer, SALOME_View* theViewFrame ) const +{ + SALOME_View* vf = theViewFrame ? theViewFrame : GetActiveView(); + + if ( vf ) { + vf->EraseAll( forced ); + if ( updateViewer ) + vf->Repaint(); + } +} + +bool LightApp_Displayer::IsDisplayed( const QString& entry, SALOME_View* theViewFrame ) const +{ + SALOME_View* vf = theViewFrame ? theViewFrame : GetActiveView(); + if( vf ) + { + Handle( SALOME_InteractiveObject ) temp = new SALOME_InteractiveObject(); + temp->setEntry( entry.latin1() ); + return vf->isVisible( temp ); + } + else + return false; +} + +void LightApp_Displayer::UpdateViewer() const +{ + SALOME_View* vf = GetActiveView(); + if ( vf ) + vf->Repaint(); +} + +SALOME_Prs* LightApp_Displayer::buildPresentation( const QString& entry, SALOME_View* theViewFrame ) +{ + SALOME_Prs* prs = 0; + + SALOME_View* vf = theViewFrame ? theViewFrame : GetActiveView(); + + if ( vf ) + prs = vf->CreatePrs( entry.latin1() ); + + return prs; +} + +SALOME_View* LightApp_Displayer::GetActiveView() +{ + SUIT_Session* session = SUIT_Session::session(); + if ( SUIT_Application* app = session->activeApplication() ) { + if ( LightApp_Application* sApp = dynamic_cast( app ) ) { + if( SUIT_ViewManager* vman = sApp->activeViewManager() ) { + if ( SUIT_ViewModel* vmod = vman->getViewModel() ) + return dynamic_cast( vmod ); + } + } + } + return 0; +} + +bool LightApp_Displayer::canBeDisplayed( const QString&, const QString& ) const +{ + return true; +} + +bool LightApp_Displayer::canBeDisplayed( const QString& entry ) const +{ + QString viewerType; + SUIT_Session* session = SUIT_Session::session(); + if( SUIT_Application* app = session->activeApplication() ) + if( LightApp_Application* sApp = dynamic_cast( app ) ) + if( SUIT_ViewManager* vman = sApp->activeViewManager() ) + if( SUIT_ViewModel* vmod = vman->getViewModel() ) + viewerType = vmod->getType(); + return !viewerType.isNull() && canBeDisplayed( entry, viewerType ); +} + +LightApp_Displayer* LightApp_Displayer::FindDisplayer( const QString& mod_name, const bool load ) +{ + SUIT_Session* session = SUIT_Session::session(); + SUIT_Application* sapp = session ? session->activeApplication() : 0; + LightApp_Application* app = dynamic_cast( sapp ); + if( !app ) + return 0; + + LightApp_Module* m = dynamic_cast( app ? app->module( mod_name ) : 0 ); + if( !m && load ) + { + m = dynamic_cast( app->loadModule( mod_name ) ); + if( m ) + app->addModule( m ); + } + + if( m ) + { + m->connectToStudy( dynamic_cast( app->activeStudy() ) ); + if( m!=app->activeModule() && load ) + { + m->setMenuShown( false ); + m->setToolShown( false ); + } + } + return m ? m->displayer() : 0; +} diff --git a/src/LightApp/LightApp_Displayer.h b/src/LightApp/LightApp_Displayer.h new file mode 100644 index 000000000..f0896eb8f --- /dev/null +++ b/src/LightApp/LightApp_Displayer.h @@ -0,0 +1,50 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// + +#ifndef LIGHTAPP_DISPLAYER_HEADER +#define LIGHTAPP_DISPLAYER_HEADER + +#include + +class QString; + +class LightApp_Displayer : public SALOME_Displayer +{ +public: + LightApp_Displayer(); + virtual ~LightApp_Displayer(); + + void Display( const QString&, const bool = true, SALOME_View* = 0 ); + void Redisplay( const QString&, const bool = true ); + void Erase( const QString&, const bool forced = false, const bool updateViewer = true, SALOME_View* = 0 ); + void EraseAll( const bool forced = false, const bool updateViewer = true, SALOME_View* = 0 ) const; + bool IsDisplayed( const QString&, SALOME_View* = 0 ) const; + void UpdateViewer() const; + + static SALOME_View* GetActiveView(); + static LightApp_Displayer* FindDisplayer( const QString&, const bool ); + + virtual bool canBeDisplayed( const QString& /*entry*/, const QString& /*viewer_type*/ ) const; + bool canBeDisplayed( const QString& /*entry*/ ) const; + +protected: + virtual SALOME_Prs* buildPresentation( const QString&, SALOME_View* = 0 ); +}; + +#endif diff --git a/src/LightApp/LightApp_Driver.cxx b/src/LightApp/LightApp_Driver.cxx new file mode 100644 index 000000000..5b56e03b7 --- /dev/null +++ b/src/LightApp/LightApp_Driver.cxx @@ -0,0 +1,546 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "LightApp_Driver.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef WIN32 +#include +#endif + +/*! Constructor.*/ +LightApp_Driver::LightApp_Driver() +{ +} + +/*! Destructor.*/ +LightApp_Driver::~LightApp_Driver() +{ +} + +using namespace std; + +//================================================================ +// Function : SaveDatasInFile +/*! Purpose : save in file 'theFileName' datas from this driver*/ +//================================================================ +bool LightApp_Driver::SaveDatasInFile( const char* theFileName, bool isMultiFile ) +{ + int aNbModules = 0; + std::map::const_iterator it; + for (it = myMap.begin(); it != myMap.end(); ++it) + aNbModules++; + + unsigned char** aBuffer = new unsigned char*[aNbModules]; + long* aBufferSize = new long[aNbModules]; + char** aModuleName = new char*[aNbModules]; + + if(aBuffer == NULL || aBufferSize == NULL || aModuleName == NULL) + return false; + + int aFileBufferSize = 4; //4 bytes for a number of the modules that will be written to the stream; + int i = 0; + for (it = myMap.begin(); it != myMap.end(); ++it) { + aModuleName[i] = const_cast(it->first.c_str());//(it->first); + aFileBufferSize += 4; //Add 4 bytes: a length of the module name + aFileBufferSize += strlen(aModuleName[i])+1; + std::string aName(aModuleName[i]); + PutFilesToStream(aName, aBuffer[i], aBufferSize[i], isMultiFile); + aFileBufferSize += 8; //Add 8 bytes: a length of the buffer + aFileBufferSize += aBufferSize[i]; + i++; + } + int n = i; + + unsigned char* aFileBuffer = new unsigned char[aFileBufferSize]; + if(aFileBuffer == NULL) + return false; + + myTmpDir = QDir::convertSeparators( QFileInfo( theFileName ).dirPath( true ) + "/" ).latin1() ; + + int aCurrentPos = 0; + + //Initialize 4 bytes of the buffer by 0 + memset(aFileBuffer, 0, 4); + //Copy the number of modules that will be written to the stream + memcpy(aFileBuffer, &aNbModules, ((sizeof(int) > 4) ? 4 : sizeof(int))); + aCurrentPos += 4; + + int aBufferNameSize = 0; + for (i = 0; i < n; i++) { + aBufferNameSize = strlen(aModuleName[i])+1; + //Initialize 4 bytes of the buffer by 0 + memset((aFileBuffer + aCurrentPos), 0, 4); + //Copy the length of the module name to the buffer + memcpy((aFileBuffer + aCurrentPos), &aBufferNameSize, ((sizeof(int) > 4) ? 4 : sizeof(int))); + aCurrentPos += 4; + //Copy the module name to the buffer + memcpy((aFileBuffer + aCurrentPos), aModuleName[i], aBufferNameSize); + aCurrentPos += aBufferNameSize; + + //Initialize 8 bytes of the buffer by 0 + memset((aFileBuffer + aCurrentPos), 0, 8); + //Copy the length of the module buffer to the buffer + memcpy((aFileBuffer + aCurrentPos), (aBufferSize + i), ((sizeof(long) > 8) ? 8 : sizeof(long))); + aCurrentPos += 8; + //Copy the module buffer to the buffer + memcpy((aFileBuffer + aCurrentPos), aBuffer[i], aBufferSize[i]); + aCurrentPos += aBufferSize[i]; + } + +#ifdef WNT + ofstream aFile(theFileName, ios::out | ios::binary); +#else + ofstream aFile(theFileName); +#endif + aFile.write((char*)aFileBuffer, aFileBufferSize); + aFile.close(); + + delete[] aBuffer; + delete[] aBufferSize; + delete[] aModuleName; + delete[] aFileBuffer; + + return true; +} + +//======================================================================= +// name : ReaDatasFromFile +/*! Purpose : filling current driver from file 'theFileName'*/ +//======================================================================= +bool LightApp_Driver::ReadDatasFromFile( const char* theFileName, bool isMultiFile ) +{ +#ifdef WNT + ifstream aFile(theFileName, ios::binary); +#else + ifstream aFile(theFileName); +#endif + + myTmpDir = QDir::convertSeparators( QFileInfo( theFileName ).dirPath( true ) + "/" ).latin1() ; + + aFile.seekg(0, ios::end); + int aFileBufferSize = aFile.tellg(); + unsigned char* aFileBuffer = new unsigned char[aFileBufferSize]; + aFile.seekg(0, ios::beg); + aFile.read((char*)aFileBuffer, aFileBufferSize); + aFile.close(); + + int aNbModules = 0; + //Copy the number of files in the stream + memcpy(&aNbModules, aFileBuffer, sizeof(int)); + long aCurrentPos = 4; + int aModuleNameSize; + + for (int i = 0; i < aNbModules; i++) { + //Put a length of the module name to aModuleNameSize + memcpy(&aModuleNameSize, (aFileBuffer + aCurrentPos), ((sizeof(int) > 4) ? 4 : sizeof(int))); + aCurrentPos += 4; + + char *aModuleName = new char[aModuleNameSize]; + //Put a module name to aModuleName + memcpy(aModuleName, (aFileBuffer + aCurrentPos), aModuleNameSize); + aCurrentPos += aModuleNameSize; + + //Put a length of the file buffer to aBufferSize + long aBufferSize; + memcpy(&aBufferSize, (aFileBuffer + aCurrentPos), ((sizeof(long) > 8) ? 8 : sizeof(long))); + aCurrentPos += 8; + unsigned char *aBuffer = new unsigned char[aBufferSize]; + + //Put a buffer for current module to aBuffer + memcpy(aBuffer, (aFileBuffer + aCurrentPos), aBufferSize); + aCurrentPos += aBufferSize; + + // Put buffer to aListOfFiles and set to myMap + ListOfFiles aListOfFiles = PutStreamToFiles(aBuffer, aBufferSize, isMultiFile); + SetListOfFiles(aModuleName, aListOfFiles); + + delete[] aModuleName; + delete[] aBuffer; + } + + delete[] aFileBuffer; + + return true; +} + +//================================================================ +// Function : GetTmpDir +/*! Purpose : returns temp directory for path 'theURL'*/ +//================================================================ +std::string LightApp_Driver::GetTmpDir (const char* theURL, const bool isMultiFile) +{ + std::string anURLDir = GetDirFromPath(theURL); + std::string aTmpDir = isMultiFile ? anURLDir : GetTmpDir(); + + return aTmpDir; +} + +//================================================================ +// Function : GetListOfFiles +/*! Purpose : returns list of files for module with name 'theModuleName'*/ +//================================================================ +LightApp_Driver::ListOfFiles LightApp_Driver::GetListOfFiles( const char* theModuleName ) +{ + ListOfFiles aListOfFiles; + + std::string aName(theModuleName); + if (myMap.count(aName)) + aListOfFiles = myMap[aName]; + + return aListOfFiles; +} + +//================================================================ +// Function : SetListOfFiles +/*! Purpose : sets list of files for module with name 'theModuleName'*/ +//================================================================ +void LightApp_Driver::SetListOfFiles( const char* theModuleName, const ListOfFiles theListOfFiles ) +{ + std::string aName (theModuleName); + myMap[aName] = theListOfFiles; +} + +//============================================================================ +// function : PutFilesToStream +/*! Purpose : converts files which was created from module into a byte sequence unsigned char*/ +//============================================================================ +void LightApp_Driver::PutFilesToStream( const std::string& theModuleName, unsigned char*& theBuffer, + long& theBufferSize, bool theNamesOnly ) +{ + ListOfFiles aFiles = myMap[theModuleName]; + // aFiles must contain temporary directory name in its first item + // and names of files (relatively the temporary directory) in the others + + int i, aLength = aFiles.size() - 1; + if(aLength <= 0) { + theBufferSize = 0; + theBuffer = new unsigned char[theBufferSize]; + return; + } + //Get a temporary directory for saved a file + TCollection_AsciiString aTmpDir(const_cast(aFiles[0].c_str())); + + long aBufferSize = 0; + long aCurrentPos; + int aNbFiles = 0; + int* aFileNameSize= new int[aLength]; + long* aFileSize= new long[aLength]; + + //Determine the required size of the buffer + TCollection_AsciiString aFileName; + for (i = 0; i < aLength; i++) { + char* aFName = const_cast(aFiles[i+1].c_str()); + aFileName = aFName; + //Check if the file exists + if (!theNamesOnly) { // mpv 15.01.2003: if only file names must be stroed, then size of files is zero + TCollection_AsciiString aFullPath = aTmpDir + aFileName; + OSD_Path anOSDPath(aFullPath); + OSD_File anOSDFile(anOSDPath); + if(!anOSDFile.Exists()) continue; +#ifdef WNT + ifstream aFile(aFullPath.ToCString(), ios::binary); +#else + ifstream aFile(aFullPath.ToCString()); +#endif + aFile.seekg(0, ios::end); + aFileSize[i] = aFile.tellg(); + aBufferSize += aFileSize[i]; //Add a space to store the file + } + aFileNameSize[i] = strlen(aFName) + 1; + aBufferSize += aFileNameSize[i]; //Add a space to store the file name + aBufferSize += (theNamesOnly)?4:12; //Add 4 bytes: a length of the file name, + // 8 bytes: length of the file itself + aNbFiles++; + } + + aBufferSize += 4; //4 bytes for a number of the files that will be written to the stream; + theBuffer = new unsigned char[aBufferSize]; + if(theBuffer == NULL) { + theBufferSize = 0; + theBuffer = 0; + return; + } + //Initialize 4 bytes of the buffer by 0 + memset(theBuffer, 0, 4); + //Copy the number of files that will be written to the stream + memcpy(theBuffer, &aNbFiles, ((sizeof(int) > 4) ? 4 : sizeof(int))); + + aCurrentPos = 4; + + for(i = 0; i < aLength; i++) { + ifstream *aFile; + if (!theNamesOnly) { // mpv 15.01.2003: we don't open any file if theNamesOnly = true + TCollection_AsciiString aName(const_cast(aFiles[i+1].c_str())); + TCollection_AsciiString aFullPath = aTmpDir + aName; + OSD_Path anOSDPath(aFullPath); + OSD_File anOSDFile(anOSDPath); + if(!anOSDFile.Exists()) continue; +#ifdef WNT + aFile = new ifstream(aFullPath.ToCString(), ios::binary); +#else + aFile = new ifstream(aFullPath.ToCString()); +#endif + } + //Initialize 4 bytes of the buffer by 0 + memset((theBuffer + aCurrentPos), 0, 4); + //Copy the length of the file name to the buffer + memcpy((theBuffer + aCurrentPos), (aFileNameSize + i), ((sizeof(int) > 4) ? 4 : sizeof(int))); + aCurrentPos += 4; + + //Copy the file name to the buffer + char* aFName = const_cast(aFiles[i+1].c_str()); + memcpy((theBuffer + aCurrentPos), aFName, aFileNameSize[i]); + aCurrentPos += aFileNameSize[i]; + + if (!theNamesOnly) { // mpv 15.01.2003: we don't copy file content to the buffer if !theNamesOnly + //Initialize 8 bytes of the buffer by 0 + memset((theBuffer + aCurrentPos), 0, 8); + //Copy the length of the file to the buffer + memcpy((theBuffer + aCurrentPos), (aFileSize + i), ((sizeof(long) > 8) ? 8 : sizeof(long))); + aCurrentPos += 8; + + aFile->seekg(0, ios::beg); + aFile->read((char *)(theBuffer + aCurrentPos), aFileSize[i]); + aFile->close(); + delete(aFile); + aCurrentPos += aFileSize[i]; + } + } + delete[] aFileNameSize; + delete[] aFileSize; + + theBufferSize = aBufferSize; +} + +//============================================================================ +// function : PutStreamToFile +/*! Purpose : converts a byte sequence to files and return list of them*/ +//============================================================================ +LightApp_Driver::ListOfFiles LightApp_Driver::PutStreamToFiles( const unsigned char* theBuffer, + const long theBufferSize, bool theNamesOnly ) +{ + if(theBufferSize == 0 || theBuffer == 0) + return ListOfFiles(); + + // Create a temporary directory for the component's data files + std::string aDir = GetTmpDir(); + + //Get a temporary directory for saving a file + TCollection_AsciiString aTmpDir(const_cast(aDir.c_str())); + + long aFileSize, aCurrentPos = 4; + int i, aFileNameSize, aNbFiles = 0; + + //Copy the number of files in the stream + memcpy(&aNbFiles, theBuffer, sizeof(int)); + + const int n = aNbFiles + 1; + ListOfFiles aFiles(n); + aFiles[0] = aDir; + + for(i = 0; i < aNbFiles; i++) { + //Put a length of the file name to aFileNameSize + memcpy(&aFileNameSize, (theBuffer + aCurrentPos), ((sizeof(int) > 4) ? 4 : sizeof(int))); + aCurrentPos += 4; + + char *aFileName = new char[aFileNameSize]; + //Put a file name to aFileName + memcpy(aFileName, (theBuffer + aCurrentPos), aFileNameSize); + aCurrentPos += aFileNameSize; + + //Put a length of the file to aFileSize + if (!theNamesOnly) { + memcpy(&aFileSize, (theBuffer + aCurrentPos), ((sizeof(long) > 8) ? 8 : sizeof(long))); + aCurrentPos += 8; + + TCollection_AsciiString aFullPath = aTmpDir + aFileName; + +#ifdef WNT + ofstream aFile(aFullPath.ToCString(), ios::out | ios::binary); +#else + ofstream aFile(aFullPath.ToCString()); +#endif + + aFile.write((char *)(theBuffer+aCurrentPos), aFileSize); + aFile.close(); + aCurrentPos += aFileSize; + } + std::string aStrFileName(aFileName); + aFiles[i+1] = aStrFileName; + delete[] aFileName; + } + return aFiles; +} + +//============================================================================ +// function : RemoveFiles +/*! Purpose : Remove files. First item in is a directory with slash at the end. + Other items are names of files. If is true, + then the directory is also deleted. +*/ +//============================================================================ +void LightApp_Driver::RemoveFiles( const ListOfFiles& theFiles, const bool IsDirDeleted) +{ + int i, aLength = theFiles.size() - 1; + if(aLength <= 0) { + return; + } + //Get a temporary directory for saved a file + TCollection_AsciiString aDirName(const_cast(theFiles[0].c_str())); + + for(i = 0; i < aLength; i++) { + TCollection_AsciiString aFile(aDirName); + aFile += const_cast(theFiles[i+1].c_str()); + OSD_Path anOSDPath(aFile); + OSD_File anOSDFile(anOSDPath); + if(!anOSDFile.Exists()) continue; + + anOSDFile.Remove(); + } + + if(IsDirDeleted) { + OSD_Path aPath(aDirName); + OSD_Directory aDir(aPath); + OSD_FileIterator anIterator(aPath, '*'); + + if(aDir.Exists() && !anIterator.More()) aDir.Remove(); + } +} + +//============================================================================ +// function : RemoveTemporaryFiles +/*! Purpose : removes files which was created from module theModuleName if + is true tmp directory is also deleted if it is empty*/ +//============================================================================ +void LightApp_Driver::RemoveTemporaryFiles( const char* theModuleName, const bool IsDirDeleted ) +{ + std::string aModuleName(theModuleName); + ListOfFiles aFiles = myMap[aModuleName]; + // aFiles must contain temporary directory name in its first item + // and names of files (relatively the temporary directory) in the others + RemoveFiles( aFiles, IsDirDeleted ); + +} + +//============================================================================ +// function : ClearDriverContents +/*! Purpose : clear map of list files*/ +//============================================================================ +void LightApp_Driver::ClearDriverContents() +{ + std::map::iterator it; + for ( it = myMap.begin(); it != myMap.end(); ++it ) + { + const char* aModuleName = const_cast(it->first.c_str()); + RemoveTemporaryFiles( aModuleName, false ); + } + myMap.clear(); +} + +//============================================================================ +// function : GetTempDir +/*! Purpose : return a temp directory to store created files like "/tmp/sub_dir/" */ +//============================================================================ +std::string LightApp_Driver::GetTmpDir() +{ + if ( myTmpDir.length() != 0 ) + return myTmpDir; + + //Find a temporary directory to store a file + TCollection_AsciiString aTmpDir; + + char *Tmp_dir = getenv("SALOME_TMP_DIR"); + if ( !Tmp_dir ) + Tmp_dir = getenv ( "TEMP" ); + if ( !Tmp_dir ) + Tmp_dir = getenv ( "TMP" ); + if ( Tmp_dir ) + { + aTmpDir = TCollection_AsciiString(Tmp_dir); +#ifdef WIN32 + if(aTmpDir.Value(aTmpDir.Length()) != '\\') aTmpDir+='\\'; +#else + if(aTmpDir.Value(aTmpDir.Length()) != '/') aTmpDir+='/'; +#endif + } + else + { +#ifdef WIN32 + aTmpDir = TCollection_AsciiString("C:\\"); +#else + aTmpDir = TCollection_AsciiString("/tmp/"); +#endif + } + + srand((unsigned int)time(NULL)); + int aRND = 999 + (int)(100000.0*rand()/(RAND_MAX+1.0)); //Get a random number to present a name of a sub directory + TCollection_AsciiString aSubDir(aRND); + if(aSubDir.Length() <= 1) aSubDir = TCollection_AsciiString("123409876"); + + aTmpDir += aSubDir; //Get RND sub directory + +#ifdef WIN32 + if(aTmpDir.Value(aTmpDir.Length()) != '\\') aTmpDir+='\\'; +#else + if(aTmpDir.Value(aTmpDir.Length()) != '/') aTmpDir+='/'; +#endif + + OSD_Path aPath(aTmpDir); + OSD_Directory aDir(aPath); + + for(aRND = 0; aDir.Exists(); aRND++) { + aTmpDir.Insert((aTmpDir.Length() - 1), TCollection_AsciiString(aRND)); //Build a unique directory name + aPath = OSD_Path(aTmpDir); + aDir = OSD_Directory(aPath); + } + + OSD_Protection aProtection(OSD_RW, OSD_RWX, OSD_RX, OSD_RX); + aDir.Build(aProtection); + + myTmpDir = aTmpDir.ToCString(); + + return aTmpDir.ToCString(); +} + +//============================================================================ +// function : GetDirFromPath +/*! Purpose : returns the dir by the path*/ +//============================================================================ +std::string LightApp_Driver::GetDirFromPath( const std::string& thePath ) { + if(thePath == "") + return ""; + OSD_Path aPath = OSD_Path(TCollection_AsciiString(const_cast(thePath.c_str()))); + TCollection_AsciiString aDirString(aPath.Trek()); + aDirString.ChangeAll('|','/'); + return aDirString.ToCString(); +} + diff --git a/src/LightApp/LightApp_Driver.h b/src/LightApp/LightApp_Driver.h new file mode 100644 index 000000000..022ce16ec --- /dev/null +++ b/src/LightApp/LightApp_Driver.h @@ -0,0 +1,69 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef LIGHTAPP_DRIVER_H +#define LIGHTAPP_DRIVER_H + +#include + +#include "string" +#include "vector" +#include "map" + +#ifdef WIN32 +#pragma warning( disable:4251 ) +#endif + +/*!Description : Driver can save to file and read from file list of files for light modules*/ + +class LIGHTAPP_EXPORT LightApp_Driver +{ +public: + LightApp_Driver(); + virtual ~LightApp_Driver(); + + + typedef std::vector ListOfFiles; + + bool SaveDatasInFile (const char* theFileName, bool isMultiFile ); + bool ReadDatasFromFile (const char* theFileName, bool isMultiFile ); + virtual std::string GetTmpDir (const char* theURL, const bool isMultiFile); + + ListOfFiles GetListOfFiles (const char* theModuleName); + virtual void SetListOfFiles (const char* theModuleName, const ListOfFiles theListOfFiles); + virtual void RemoveTemporaryFiles(const char* theModuleName, const bool IsDirDeleted); + void RemoveFiles( const ListOfFiles& theFiles, const bool IsDirDeleted); + + virtual void ClearDriverContents(); + +private: + void PutFilesToStream(const std::string& theModuleName, unsigned char*& theBuffer, + long& theBufferSize, bool theNamesOnly = false); + ListOfFiles PutStreamToFiles(const unsigned char* theBuffer, + const long theBufferSize, bool theNamesOnly = false); + + std::string GetTmpDir(); + std::string GetDirFromPath(const std::string& thePath); + +private: + typedef std::map MapOfListOfFiles; + MapOfListOfFiles myMap; + std::string myTmpDir; +}; + +#endif diff --git a/src/LightApp/LightApp_GLSelector.cxx b/src/LightApp/LightApp_GLSelector.cxx new file mode 100644 index 000000000..7913b4edf --- /dev/null +++ b/src/LightApp/LightApp_GLSelector.cxx @@ -0,0 +1,117 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "LightApp_GLSelector.h" + +#include "LightApp_DataOwner.h" + +#include + +#include + +/*!Constructor. Initialize by GLViewer_Viewer2d and SUIT_SelectionMgr.*/ +LightApp_GLSelector::LightApp_GLSelector( GLViewer_Viewer2d* viewer, SUIT_SelectionMgr* mgr ) +: SUIT_Selector( mgr, viewer ), + myViewer( viewer ) +{ + if ( myViewer ) + connect( myViewer, SIGNAL( selectionChanged( SelectionChangeStatus ) ), + this, SLOT( onSelectionChanged() ) ); +} + +/*!Destructor. Do nothing.*/ +LightApp_GLSelector::~LightApp_GLSelector() +{ +} + +/*!Gets viewer*/ +GLViewer_Viewer2d* LightApp_GLSelector::viewer() const +{ + return myViewer; +} + +/*!On selection changed event.*/ +void LightApp_GLSelector::onSelectionChanged() +{ + selectionChanged(); +} + +/*!Gets list of selected Data Owner objects.*/ +void LightApp_GLSelector::getSelection( SUIT_DataOwnerPtrList& aList ) const +{ + if ( !myViewer ) + return; + + GLViewer_Context* cont = myViewer->getGLContext(); + if ( !cont ) + return; + + for ( cont->InitSelected(); cont->MoreSelected(); cont->NextSelected() ) + { + GLViewer_Object* obj = cont->SelectedObject(); + if ( obj ) + { + SALOME_GLOwner* owner = dynamic_cast< SALOME_GLOwner* >( obj->owner() ); + if( owner ) + aList.append( SUIT_DataOwnerPtr( new LightApp_DataOwner( owner->entry() ) ) ); + } + } +} + +/*!Sets to selected list of Data Owner objects.*/ +void LightApp_GLSelector::setSelection( const SUIT_DataOwnerPtrList& aList ) +{ + if ( !myViewer ) + return; + + GLViewer_Context* cont = myViewer->getGLContext(); + if ( !cont ) + return; + + QMap aDisplayed; + const ObjList& displayed = cont->getObjects(); + for ( ObjList::const_iterator it = displayed.begin(); it != displayed.end(); ++it ) + { + GLViewer_Object* obj = *it; + if ( obj && obj->getVisible() ) + { + SALOME_GLOwner* owner = dynamic_cast< SALOME_GLOwner* >( obj->owner() ); + if ( owner ) + aDisplayed.insert( owner->entry(), obj ); + } + } + + int Nb = 0; + cont->clearSelected( false ); + for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr ) + { + const LightApp_DataOwner* owner = dynamic_cast( (*itr).operator->() ); + + if ( !owner ) + continue; + + if ( aDisplayed.contains( owner->entry() ) ) + { + cont->setSelected( aDisplayed[owner->entry()], false ); + Nb++; + } + } + + if ( Nb > 0 ) + myViewer->updateAll(); +} diff --git a/src/LightApp/LightApp_GLSelector.h b/src/LightApp/LightApp_GLSelector.h new file mode 100644 index 000000000..069669a87 --- /dev/null +++ b/src/LightApp/LightApp_GLSelector.h @@ -0,0 +1,51 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef LIGHTAPP_GLSELECTOR_H +#define LIGHTAPP_GLSELECTOR_H + +#include "LightApp.h" + +#include + +#include + +class LIGHTAPP_EXPORT LightApp_GLSelector : public SUIT_Selector +{ + Q_OBJECT + +public: + LightApp_GLSelector( GLViewer_Viewer2d*, SUIT_SelectionMgr* ); + virtual ~LightApp_GLSelector(); + + GLViewer_Viewer2d* viewer() const; + + virtual QString type() const { return GLViewer_Viewer2d::Type(); } + +private slots: + void onSelectionChanged(); + +protected: + virtual void getSelection( SUIT_DataOwnerPtrList& ) const; + virtual void setSelection( const SUIT_DataOwnerPtrList& ); + +private: + GLViewer_Viewer2d* myViewer; +}; + +#endif diff --git a/src/LightApp/LightApp_Module.cxx b/src/LightApp/LightApp_Module.cxx new file mode 100644 index 000000000..46d3f82af --- /dev/null +++ b/src/LightApp/LightApp_Module.cxx @@ -0,0 +1,430 @@ +// File: LightApp_Module.cxx +// Created: 6/20/2005 16:30:56 AM +// Author: OCC team +// Copyright (C) CEA 2005 + +#include "LightApp_Module.h" + +#include "CAM_Application.h" + +#include "LightApp_Application.h" +#include "LightApp_DataModel.h" +#include "LightApp_Study.h" +#include "LightApp_Preferences.h" +#include "LightApp_Selection.h" +#include "LightApp_Operation.h" +#include "LightApp_SwitchOp.h" +#include "LightApp_UpdateFlags.h" +#include "LightApp_ShowHideOp.h" + +#include "SUIT_Operation.h" +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include + +/*!Constructor.*/ +LightApp_Module::LightApp_Module( const QString& name ) +: CAM_Module( name ), + myPopupMgr( 0 ), + mySwitchOp( 0 ), + myDisplay( -1 ), + myErase( -1 ), + myDisplayOnly( -1 ), + myEraseAll( -1 ) +{ +} + +/*!Destructor.*/ +LightApp_Module::~LightApp_Module() +{ + if ( mySwitchOp ) + delete mySwitchOp; +} + +/*!Initialize module.*/ +void LightApp_Module::initialize( CAM_Application* app ) +{ + CAM_Module::initialize( app ); + + SUIT_ResourceMgr* resMgr = app ? app->resourceMgr() : 0; + if ( resMgr ) + resMgr->raiseTranslators( name() ); +} + +/*!NOT IMPLEMENTED*/ +void LightApp_Module::windows( QMap& ) const +{ +} + +/*!NOT IMPLEMENTED*/ +void LightApp_Module::viewManagers( QStringList& ) const +{ +} + +/*!Context menu popup.*/ +void LightApp_Module::contextMenuPopup( const QString& client, QPopupMenu* menu, QString& /*title*/ ) +{ + LightApp_Selection* sel = createSelection(); + sel->init( client, getApp()->selectionMgr() ); + popupMgr()->updatePopup( menu, sel ); + delete sel; +} + +/*!Update object browser. + * For updating model or whole object browser use update() method can be used. +*/ +void LightApp_Module::updateObjBrowser( bool updateDataModel, SUIT_DataObject* root ) +{ + if( updateDataModel ) + if( CAM_DataModel* aDataModel = dataModel() ) + if( LightApp_DataModel* aModel = dynamic_cast( aDataModel ) ) + aModel->update( 0, dynamic_cast( getApp()->activeStudy() ) ); + getApp()->objectBrowser()->updateTree( root ); +} + +/*!NOT IMPLEMENTED*/ +void LightApp_Module::selectionChanged() +{ +} + +/*!Activate module.*/ +bool LightApp_Module::activateModule( SUIT_Study* study ) +{ + bool res = CAM_Module::activateModule( study ); + + if ( res && application() && application()->resourceMgr() ) + application()->resourceMgr()->raiseTranslators( name() ); + + if ( mySwitchOp == 0 ) + mySwitchOp = new LightApp_SwitchOp( this ); + + return res; +} + +/*!Deactivate module.*/ +bool LightApp_Module::deactivateModule( SUIT_Study* ) +{ + delete mySwitchOp; + mySwitchOp = 0; + + return true; +} + +/*!NOT IMPLEMENTED*/ +void LightApp_Module::MenuItem() +{ +} + +/*!NOT IMPLEMENTED*/ +void LightApp_Module::createPreferences() +{ +} + +/*!NOT IMPLEMENTED*/ +void LightApp_Module::preferencesChanged( const QString&, const QString& ) +{ +} + +/*!Gets application.*/ +LightApp_Application* LightApp_Module::getApp() const +{ + return (LightApp_Application*)application(); +} + +/*! + * \brief Update something in accordance with update flags + * \param theFlags - update flags +* +* Update viewer or/and object browser etc. in accordance with update flags ( see +* LightApp_UpdateFlags enumeration ). Derived modules can redefine this method for their +* own purposes +*/ +void LightApp_Module::update( const int theFlags ) +{ + if ( theFlags & UF_Model ) + { + if( CAM_DataModel* aDataModel = dataModel() ) + if( LightApp_DataModel* aModel = dynamic_cast( aDataModel ) ) + aModel->update( 0, dynamic_cast( getApp()->activeStudy() ) ); + } + if ( theFlags & UF_ObjBrowser ) + getApp()->objectBrowser()->updateTree( 0 ); + if ( theFlags & UF_Controls ) + updateControls(); + if ( theFlags & UF_Viewer ) + { + if ( SUIT_ViewManager* viewMgr = getApp()->activeViewManager() ) + if ( SUIT_ViewWindow* viewWnd = viewMgr->getActiveView() ) + { + if ( viewWnd->inherits( "SVTK_ViewWindow" ) ) + ( (SVTK_ViewWindow*)viewWnd )->Repaint(); + else if ( viewWnd->inherits( "OCCViewer_ViewWindow" ) ) + ( (OCCViewer_ViewWindow*)viewWnd )->getViewPort()->onUpdate(); + else if ( viewWnd->inherits( "Plot2d_ViewWindow" ) ) + ( (Plot2d_ViewWindow*)viewWnd )->getViewFrame()->Repaint(); + else if ( viewWnd->inherits( "GLViewer_ViewFrame" ) ) + ( (GLViewer_ViewFrame*)viewWnd )->getViewPort()->onUpdate(); + } + } +} +/*! + * \brief Updates controls +* +* Updates (i.e. disable/enable) controls states (menus, tool bars etc.). This method is +* called from update( UF_Controls ). You may redefine it in concrete module. +*/ +void LightApp_Module::updateControls() +{ +} + +/*!Create new instance of data model and return it.*/ +CAM_DataModel* LightApp_Module::createDataModel() +{ + return new LightApp_DataModel(this); +} + +/*!Create and return instance of LightApp_Selection.*/ +LightApp_Selection* LightApp_Module::createSelection() const +{ + return new LightApp_Selection(); +} + +/*!NOT IMPLEMENTED*/ +void LightApp_Module::onModelOpened() +{ +} + +/*!NOT IMPLEMENTED*/ +void LightApp_Module::onModelSaved() +{ +} + +/*!NOT IMPLEMENTED*/ +void LightApp_Module::onModelClosed() +{ +} + +/*!Gets popup manager.(create if not exist)*/ +QtxPopupMgr* LightApp_Module::popupMgr() +{ + if ( !myPopupMgr ) + { + myPopupMgr = new QtxPopupMgr( 0, this ); + + QPixmap p; + SUIT_Desktop* d = application()->desktop(); + + QAction + *disp = createAction( -1, tr( "TOP_DISPLAY" ), p, tr( "MEN_DISPLAY" ), tr( "STB_DISPLAY" ), + 0, d, false, this, SLOT( onShowHide() ) ), + *erase = createAction( -1, tr( "TOP_ERASE" ), p, tr( "MEN_ERASE" ), tr( "STB_ERASE" ), + 0, d, false, this, SLOT( onShowHide() ) ), + *dispOnly = createAction( -1, tr( "TOP_DISPLAY_ONLY" ), p, tr( "MEN_DISPLAY_ONLY" ), tr( "STB_DISPLAY_ONLY" ), + 0, d, false, this, SLOT( onShowHide() ) ), + *eraseAll = createAction( -1, tr( "TOP_ERASE_ALL" ), p, tr( "MEN_ERASE_ALL" ), tr( "STB_ERASE_ALL" ), + 0, d, false, this, SLOT( onShowHide() ) ); + myDisplay = actionId( disp ); + myErase = actionId( erase ); + myDisplayOnly = actionId( dispOnly ); + myEraseAll = actionId( eraseAll ); + + myPopupMgr->insert( disp, -1, 0 ); + myPopupMgr->insert( erase, -1, 0 ); + myPopupMgr->insert( dispOnly, -1, 0 ); + myPopupMgr->insert( eraseAll, -1, 0 ); + myPopupMgr->insert( separator(), -1, 0 ); + + QString oneAndNotActive = "( count( $component ) = 1 ) and ( component != activeModule )"; + QString uniform = "true in $canBeDisplayed and %1 and ( activeModule = '%2' )"; + uniform = uniform.arg( oneAndNotActive ).arg( name() ); + myPopupMgr->setRule( disp, /*QString( "( not isVisible ) and " ) + */ uniform, true ); + myPopupMgr->setRule( erase, /*QString( "( isVisible ) and " ) + */ uniform, true ); + myPopupMgr->setRule( dispOnly, uniform, true ); + QString viewers = "{ '%1' '%2' '%3' }"; + viewers = viewers.arg( SOCC_Viewer::Type() ).arg( SVTK_Viewer::Type() ).arg( SPlot2d_Viewer::Type() ); + myPopupMgr->setRule( eraseAll, QString( "client in %1" ).arg( viewers ), true ); + } + return myPopupMgr; +} + +/*!Gets preferences.*/ +LightApp_Preferences* LightApp_Module::preferences() const +{ + LightApp_Preferences* pref = 0; + if ( getApp() ) + pref = getApp()->preferences(); + return pref; +} + +/*!Add preference to preferences.*/ +int LightApp_Module::addPreference( const QString& label ) +{ + LightApp_Preferences* pref = preferences(); + if ( !pref ) + return -1; + + int catId = pref->addPreference( moduleName(), -1 ); + if ( catId == -1 ) + return -1; + + return pref->addPreference( label, catId ); +} + +/*!Add preference to preferences.*/ +int LightApp_Module::addPreference( const QString& label, const int pId, const int type, + const QString& section, const QString& param ) +{ + LightApp_Preferences* pref = preferences(); + if ( !pref ) + return -1; + + return pref->addPreference( moduleName(), label, pId, type, section, param ); +} + +/*!Gets property of preferences.*/ +QVariant LightApp_Module::preferenceProperty( const int id, const QString& prop ) const +{ + QVariant var; + LightApp_Preferences* pref = preferences(); + if ( pref ) + var = pref->itemProperty( id, prop ); + return var; +} + +/*!Set property of preferences.*/ +void LightApp_Module::setPreferenceProperty( const int id, const QString& prop, const QVariant& var ) +{ + LightApp_Preferences* pref = preferences(); + if ( pref ) + pref->setItemProperty( id, prop, var ); +} + +/*! + * \brief Starts operation with given identifier + * \param id - identifier of operation to be started +* +* Module stores operations in map. This method starts operation by id. +* If operation isn't in map, then it will be created by createOperation method +* and will be inserted to map +*/ +void LightApp_Module::startOperation( const int id ) +{ + LightApp_Operation* op = 0; + if( myOperations.contains( id ) ) + op = myOperations[ id ]; + else + { + op = createOperation( id ); + if( op ) + { + myOperations.insert( id, op ); + op->setModule( this ); + connect( op, SIGNAL( stopped( SUIT_Operation* ) ), this, SLOT( onOperationStopped( SUIT_Operation* ) ) ); + connect( op, SIGNAL( destroyed() ), this, SLOT( onOperationDestroyed() ) ); + } + } + + if( op ) + { + // be sure that operation has correct study pointer + op->setStudy( application() ? application()->activeStudy() : 0 ); + op->start(); + } +} + +/*! + * \brief Creates operation with given identifier + * \param id - identifier of operation to be started + * \return Pointer on created operation or NULL if operation is not created +* +* Creates operation with given id. You should not call this method, it will be called +* automatically from startOperation. You may redefine this method in concrete module to +* create operations. +*/ +LightApp_Operation* LightApp_Module::createOperation( const int id ) const +{ + if( id==-1 ) + return 0; + + if( id==myDisplay ) + return new LightApp_ShowHideOp( LightApp_ShowHideOp::DISPLAY ); + else if( id==myErase ) + return new LightApp_ShowHideOp( LightApp_ShowHideOp::ERASE ); + else if( id==myDisplayOnly ) + return new LightApp_ShowHideOp( LightApp_ShowHideOp::DISPLAY_ONLY ); + else if( id==myEraseAll ) + return new LightApp_ShowHideOp( LightApp_ShowHideOp::ERASE_ALL ); + else + return 0; +} + +/*! + * \brief Virtual protected slot called when operation stopped + * \param theOp - stopped operation +* +* Virtual protected slot called when operation stopped. Redefine this slot if you want to +* perform actions after stopping operation +*/ +void LightApp_Module::onOperationStopped( SUIT_Operation* /*theOp*/ ) +{ +} + +/*! + * \brief Virtual protected slot called when operation destroyed + * \param theOp - destroyed operation +* +* Virtual protected slot called when operation destroyed. Redefine this slot if you want to +* perform actions after destroying operation. Base implementation removes pointer on +* destroyed operation from the map of operations +*/ +void LightApp_Module::onOperationDestroyed() +{ + const QObject* s = sender(); + if( s && s->inherits( "LightApp_Operation" ) ) + { + const LightApp_Operation* op = ( LightApp_Operation* )s; + MapOfOperation::const_iterator anIt = myOperations.begin(), + aLast = myOperations.end(); + for( ; anIt!=aLast; anIt++ ) + if( anIt.data()==op ) + { + myOperations.remove( anIt.key() ); + break; + } + } +} + +LightApp_Displayer* LightApp_Module::displayer() +{ + return 0; +} + +void LightApp_Module::onShowHide() +{ + if( !sender()->inherits( "QAction" ) || !popupMgr() ) + return; + + QAction* act = ( QAction* )sender(); + int id = actionId( act ); + if( id!=-1 ) + startOperation( id ); +} diff --git a/src/LightApp/LightApp_ModuleDlg.cxx b/src/LightApp/LightApp_ModuleDlg.cxx new file mode 100644 index 000000000..28b37d92f --- /dev/null +++ b/src/LightApp/LightApp_ModuleDlg.cxx @@ -0,0 +1,216 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File : LightApp_ModuleDlg.cxx +// Author : Michael Zorin (mzn) +// Module : LightApp + +#include + +#include +#include +#include +#include +#include + +#ifndef WIN32 +using namespace std; +#endif + +/*!Default icon*/ +static const char* const default_icon[] = { +"48 48 17 1", +". c None", +"# c #161e4c", +"b c #1d3638", +"e c #2f585b", +"i c #345b5e", +"c c #386266", +"g c #3f7477", +"d c #4d8589", +"m c #519099", +"o c #6abbc1", +"a c #70c9d3", +"f c #79ddea", +"n c #7adff2", +"k c #7ce2f4", +"j c #993550", +"h c #d84b71", +"l c #ef537d", +"................................................", +"................................................", +"................................................", +"................................................", +"................................................", +"................########.########.########......", +"...............#aaaaaa###aaaaaa###aaaaaa##......", +"..............#aaaaaa#b#aaaaaa#b#aaaaaa#c#......", +".............########b########b########cc#......", +".............#dddddd#b#dddddd#b#dddddd#cc#......", +"...........########d########d########d#cc#......", +"..........#aaaaaa###aaaaaa###aaaaaa##d#cc#......", +".........#aaaaaa#b#aaaaaa#b#aaaaaa#c#d#cc#......", +"........########b########e########cc#d#c#.......", +"........#dddddd#b#dddddd#e#ffffff#cc#d####......", +"......########d########d########f#cc###g##......", +".....#aaaaaa###aaaaaa###hhhhhh##f#cc#gg#c#......", +"....#aaaaaa#b#aaaaaa#i#hhhhhh#j#f#cc###cc#......", +"...########b########i########jj#f#c#gg#cc#......", +"...#kkkkkk#b#kkkkkk#i#llllll#jj#f####g#cc#......", +"...#kkkkkk#b#kkkkkk#i#llllll#jj###m##g#cc#......", +"...#knnkkk#b#kkkkkk#i#llllll#jj#mm#c#g#cc#......", +"...#knnkkk#b#kkkkkk#i#llllll#jj###cc#g#c#.......", +"...#kkkkkk#b#kkkkkk#i#llllll#j#dd#cc#g####......", +"...#kkkkkk###kkkkkk###llllll####d#cc###g##......", +"...########g########g########o##d#cc#gg#c#......", +"....#gggggg#b#gggggg#b#oooooo#c#d#cc###cc#......", +"...########b########b########cc#d#c#gg#cc#......", +"...#kkkkkk#b#kkkkkk#b#kkkkkk#cc#d####g#cc#......", +"...#kkkkkk#b#kkkkkk#b#kkkkkk#cc###g##g#cc#......", +"...#kkkkkk#b#kkkkkk#b#kkkkkk#cc#gg#c#g#cc#......", +"...#kkkkkk#b#kkkkkk#b#kkkkkk#cc###cc#g#c#.......", +"...#kkkkkk#b#kkkkkk#b#kkkkkk#c#gg#cc#g##........", +"...#kkkkkk###kkkkkk###kkkkkk####g#cc###.........", +"...########g########g########g##g#cc#...........", +"....#gggggg#b#gggggg#b#gggggg#c#g#cc#...........", +"...########b########b########cc#g#c#............", +"...#kkkkkk#b#kkkkkk#b#kkkkkk#cc#g##.............", +"...#kkkkkk#b#kkkkkk#b#kkkkkk#cc###..............", +"...#kkkkkk#b#kkkkkk#b#kkkkkk#cc#................", +"...#kkkkkk#b#kkkkkk#b#kkkkkk#cc#................", +"...#kkkkkk#b#kkkkkk#b#kkkkkk#c#.................", +"...#kkkkkk###kkkkkk###kkkkkk##..................", +"...########.########.########...................", +"................................................", +"................................................", +"................................................", +"................................................"}; + +//============================================================================================================================== +/*! + * LightApp_ModuleDlg::LightApp_ModuleDlg \n + * + * Constructor. + */ +//============================================================================================================================== +LightApp_ModuleDlg::LightApp_ModuleDlg ( QWidget * parent, const QString& component, const QPixmap icon ) + : QDialog ( parent, "ActivateModuleDlg", true, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu ) +{ + QPixmap defaultIcon( ( const char** ) default_icon ); + setCaption( tr( "CAPTION" ) ); + setSizeGripEnabled( TRUE ); + + QGridLayout* ActivateModuleDlgLayout = new QGridLayout( this ); + ActivateModuleDlgLayout->setMargin( 11 ); ActivateModuleDlgLayout->setSpacing( 6 ); + + // Module's name and icon + myComponentFrame = new QFrame( this, "myComponentFrame" ); + myComponentFrame->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Expanding ) ); + myComponentFrame->setMinimumHeight( 100 ); + myComponentFrame->setFrameStyle( QFrame::Box | QFrame::Sunken ); + + QGridLayout* myComponentFrameLayout = new QGridLayout( myComponentFrame ); + myComponentFrameLayout->setMargin( 11 ); myComponentFrameLayout->setSpacing( 6 ); + + // --> icon + myComponentIcon = new QLabel( myComponentFrame, "myComponentIcon" ); + myComponentIcon->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) ); + myComponentIcon->setPixmap( !icon.isNull() ? icon : defaultIcon ); + myComponentIcon->setScaledContents( false ); + myComponentIcon->setAlignment( AlignCenter ); + // --> name + myComponentLab = new QLabel( component, myComponentFrame, "myComponentLab" ); + QFont fnt = myComponentLab->font(); fnt.setBold( TRUE ); myComponentLab->setFont( fnt ); + myComponentLab->setAlignment( AlignCenter ); + + myComponentFrameLayout->addWidget( myComponentIcon, 0, 0 ); + myComponentFrameLayout->addWidget( myComponentLab, 0, 1 ); + + // Info + QVBoxLayout* infoLayout = new QVBoxLayout(); + infoLayout->setMargin( 0 ); infoLayout->setSpacing( 6 ); + + // --> top line + QFrame* myLine1 = new QFrame( this, "myLine1" ); + myLine1->setFrameStyle( QFrame::HLine | QFrame::Plain ); + // --> info label + myInfoLabel = new QLabel( tr ("ActivateComponent_DESCRIPTION"), this, "myInfoLabel" ); + myInfoLabel->setAlignment( AlignCenter ); + // --> bottom line + QFrame* myLine2 = new QFrame( this, "myLine2" ); + myLine2->setFrameStyle( QFrame::HLine | QFrame::Plain ); + + infoLayout->addStretch(); + infoLayout->addWidget( myLine1 ); + infoLayout->addWidget( myInfoLabel ); + infoLayout->addWidget( myLine2 ); + infoLayout->addStretch(); + + // Buttons + QHBoxLayout* btnLayout = new QHBoxLayout(); + btnLayout->setMargin( 0 ); btnLayout->setSpacing( 6 ); + + // --> New + myNewBtn = new QPushButton( tr( "NEW" ), this, "myNewBtn" ); + myNewBtn->setDefault( true ); myNewBtn->setAutoDefault( true ); + // --> Open + myOpenBtn = new QPushButton( tr( "OPEN" ), this, "myOpenBtn" ); + myOpenBtn->setAutoDefault( true ); + // --> Load + myLoadBtn = new QPushButton( tr( "LOAD" ), this, "myLoadBtn" ); + myLoadBtn->setAutoDefault( true ); + // --> Cancel + myCancelBtn = new QPushButton( tr( "CANCEL" ), this, "myCancelBtn" ); + myCancelBtn->setAutoDefault( true ); + + btnLayout->addWidget( myNewBtn ); + btnLayout->addWidget( myOpenBtn ); + btnLayout->addWidget( myLoadBtn ); + btnLayout->addStretch(); + btnLayout->addSpacing( 70 ); + btnLayout->addStretch(); + btnLayout->addWidget( myCancelBtn ); + + ActivateModuleDlgLayout->addWidget( myComponentFrame, 0, 0 ); + ActivateModuleDlgLayout->addLayout( infoLayout, 0, 1 ); + ActivateModuleDlgLayout->addMultiCellLayout( btnLayout, 1, 1, 0, 1 ); + + // signals and slots connections + connect( myNewBtn, SIGNAL( clicked() ), this, SLOT( onButtonClicked() ) ); + connect( myOpenBtn, SIGNAL( clicked() ), this, SLOT( onButtonClicked() ) ); + connect( myLoadBtn, SIGNAL( clicked() ), this, SLOT( onButtonClicked() ) ); + connect( myCancelBtn, SIGNAL( clicked() ), this, SLOT( reject() ) ); +} + +//============================================================================================================================== +/*! + * LightApp_ModuleDlg::onButtonClicked + * + * Buttons slot + */ +//============================================================================================================================== +void LightApp_ModuleDlg::onButtonClicked() +{ + QPushButton* btn = ( QPushButton* )sender(); + if ( btn == myNewBtn ) + done( 1 ); + if ( btn == myOpenBtn ) + done( 2 ); + if ( btn == myLoadBtn ) + done( 3 ); +} diff --git a/src/LightApp/LightApp_NameDlg.cxx b/src/LightApp/LightApp_NameDlg.cxx new file mode 100644 index 000000000..3af8513c9 --- /dev/null +++ b/src/LightApp/LightApp_NameDlg.cxx @@ -0,0 +1,146 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File : LightApp_NameDlg.cxx +// Author : Vadim SANDLER +// $Header$ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#ifndef WIN32 +using namespace std; +#endif + +/*! + Constructor +*/ +LightApp_NameDlg::LightApp_NameDlg( QWidget* parent ) +: QDialog( parent ? parent : NULL,//application()->desktop(), +"LightApp_NameDlg", +true, +WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu ) +{ + setCaption( tr("TLT_RENAME") ); + setSizeGripEnabled( TRUE ); + + QVBoxLayout* topLayout = new QVBoxLayout( this ); + topLayout->setMargin( 11 ); topLayout->setSpacing( 6 ); + + /***************************************************************/ + QGroupBox* GroupC1 = new QGroupBox( this, "GroupC1" ); + GroupC1->setColumnLayout(0, Qt::Vertical ); + GroupC1->layout()->setMargin( 0 ); GroupC1->layout()->setSpacing( 0 ); + QHBoxLayout* GroupC1Layout = new QHBoxLayout( GroupC1->layout() ); + GroupC1Layout->setAlignment( Qt::AlignTop ); + GroupC1Layout->setMargin( 11 ); GroupC1Layout->setSpacing( 6 ); + + QLabel* TextLabel = new QLabel( GroupC1, "TextLabel1" ); + TextLabel->setText( tr( "NAME_LBL" ) ); + GroupC1Layout->addWidget( TextLabel ); + + myLineEdit = new QLineEdit( GroupC1, "LineEdit1" ); + myLineEdit->setMinimumSize( 250, 0 ); + GroupC1Layout->addWidget( myLineEdit ); + + /***************************************************************/ + QGroupBox* GroupButtons = new QGroupBox( this, "GroupButtons" ); + GroupButtons->setColumnLayout(0, Qt::Vertical ); + GroupButtons->layout()->setMargin( 0 ); GroupButtons->layout()->setSpacing( 0 ); + QHBoxLayout* GroupButtonsLayout = new QHBoxLayout( GroupButtons->layout() ); + GroupButtonsLayout->setAlignment( Qt::AlignTop ); + GroupButtonsLayout->setMargin( 11 ); GroupButtonsLayout->setSpacing( 6 ); + + myButtonOk = new QPushButton( GroupButtons, "buttonOk" ); + myButtonOk->setText( tr( "BUT_OK" ) ); + myButtonOk->setAutoDefault( TRUE ); myButtonOk->setDefault( TRUE ); + GroupButtonsLayout->addWidget( myButtonOk ); + + GroupButtonsLayout->addStretch(); + + myButtonCancel = new QPushButton( GroupButtons, "buttonCancel" ); + myButtonCancel->setText( tr( "BUT_CANCEL" ) ); + myButtonCancel->setAutoDefault( TRUE ); + GroupButtonsLayout->addWidget( myButtonCancel ); + /***************************************************************/ + + topLayout->addWidget( GroupC1 ); + topLayout->addWidget( GroupButtons ); + + // signals and slots connections + connect( myButtonOk, SIGNAL( clicked() ), this, SLOT( accept() ) ); + connect( myButtonCancel, SIGNAL( clicked() ), this, SLOT( reject() ) ); + + /* Move widget on the botton right corner of main widget */ + SUIT_Tools::centerWidget( this, parent ); +} + +/*! + Destructor +*/ +LightApp_NameDlg::~LightApp_NameDlg() +{ +} + +/*! + Sets name +*/ +void LightApp_NameDlg::setName( const QString& name ) +{ + myLineEdit->setText( name ); + myLineEdit->end(false); + myLineEdit->home(true); +} + +/*! + Returns name entered by user +*/ +QString LightApp_NameDlg::name() +{ + return myLineEdit->text(); +} + +void LightApp_NameDlg::accept() +{ + if ( name().stripWhiteSpace().isEmpty() ) + return; + QDialog::accept(); +} + +/*! + Creates modal dialog and returns name entered [ static ] +*/ +QString LightApp_NameDlg::getName( QWidget* parent, const QString& oldName ) +{ + QString n; + LightApp_NameDlg* dlg = new LightApp_NameDlg( parent ); + if ( !oldName.isNull() ) + dlg->setName( oldName ); + if ( dlg->exec() == QDialog::Accepted ) + n = dlg->name(); + delete dlg; + return n; +} diff --git a/src/LightApp/LightApp_OBFilter.cxx b/src/LightApp/LightApp_OBFilter.cxx new file mode 100644 index 000000000..90a3ce940 --- /dev/null +++ b/src/LightApp/LightApp_OBFilter.cxx @@ -0,0 +1,47 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "LightApp_OBFilter.h" + +#include "LightApp_SelectionMgr.h" +#include "LightApp_DataObject.h" +#include "LightApp_DataOwner.h" + +/*! + Constructor. +*/ +LightApp_OBFilter::LightApp_OBFilter( LightApp_SelectionMgr* theSelMgr ) +{ + mySelMgr = theSelMgr; +} + +/*!Destructor.*/ +LightApp_OBFilter::~LightApp_OBFilter() +{ +} + +/*!Checks: data object is ok?*/ +bool LightApp_OBFilter::isOk( const SUIT_DataObject* theDataObj ) const +{ + const LightApp_DataObject* obj = dynamic_cast( theDataObj ); + if ( obj ) + return mySelMgr->isOk( new LightApp_DataOwner( obj->entry() ) ); + + return true; +} + diff --git a/src/LightApp/LightApp_OBFilter.h b/src/LightApp/LightApp_OBFilter.h new file mode 100644 index 000000000..4ea292132 --- /dev/null +++ b/src/LightApp/LightApp_OBFilter.h @@ -0,0 +1,40 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef LIGHTAPP_OBFILTER_H +#define LIGHTAPP_OBFILTER_H + +#include "LightApp.h" +#include "OB_Filter.h" + +class LightApp_SelectionMgr; + +class LIGHTAPP_EXPORT LightApp_OBFilter: public OB_Filter +{ +public: + LightApp_OBFilter( LightApp_SelectionMgr* theSelMgr ); + ~LightApp_OBFilter(); + + virtual bool isOk( const SUIT_DataObject* ) const; + +private: + LightApp_SelectionMgr* mySelMgr; + +}; + +#endif diff --git a/src/LightApp/LightApp_OCCSelector.cxx b/src/LightApp/LightApp_OCCSelector.cxx new file mode 100644 index 000000000..d0b07bb7b --- /dev/null +++ b/src/LightApp/LightApp_OCCSelector.cxx @@ -0,0 +1,121 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// + +#include "LightApp_DataOwner.h" +#include "LightApp_OCCSelector.h" + +#include + +#include +#include + +/*! + Constructor +*/ +LightApp_OCCSelector::LightApp_OCCSelector( OCCViewer_Viewer* viewer, SUIT_SelectionMgr* mgr ) +: SUIT_Selector( mgr, viewer ), + myViewer( viewer ) +{ + if ( myViewer ) + connect( myViewer, SIGNAL( selectionChanged() ), this, SLOT( onSelectionChanged() ) ); +} + +/*! + Destructor. +*/ +LightApp_OCCSelector::~LightApp_OCCSelector() +{ +} + +/*! + Gets viewer. +*/ +OCCViewer_Viewer* LightApp_OCCSelector::viewer() const +{ + return myViewer; +} + +/*!On selection changed.*/ +void LightApp_OCCSelector::onSelectionChanged() +{ + selectionChanged(); +} + +/*!Gets selection list.*/ +void LightApp_OCCSelector::getSelection( SUIT_DataOwnerPtrList& aList ) const +{ + if ( !myViewer ) + return; + + AIS_ListOfInteractive aSelList; + myViewer->getSelectedObjects( aSelList ); + for ( AIS_ListIteratorOfListOfInteractive anIt( aSelList ); anIt.More(); anIt.Next() ) + if ( !anIt.Value().IsNull() ) + { + Handle(SALOME_InteractiveObject) anObj = Handle(SALOME_InteractiveObject)::DownCast(anIt.Value()->GetOwner()); + if( !anObj.IsNull() ) + aList.append( SUIT_DataOwnerPtr( new LightApp_DataOwner( anObj ) ) ); + } +} + +/*!Sets selection list.*/ +void LightApp_OCCSelector::setSelection( const SUIT_DataOwnerPtrList& aList ) +{ + if ( !myViewer ) + return; + + QMap aDisplayed; + Handle(AIS_InteractiveContext) aContext = myViewer->getAISContext(); + if ( aContext.IsNull() ) + return; + + AIS_ListOfInteractive aDispList, aSelList; + aContext->DisplayedObjects( aDispList ); + + for ( AIS_ListIteratorOfListOfInteractive it( aDispList ); it.More(); it.Next() ) + { + QString entryStr = entry( it.Value() ); + if ( !entryStr.isEmpty() ) + aDisplayed.insert( entryStr, it.Value() ); + } + + for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr ) + { + const LightApp_DataOwner* owner = dynamic_cast( (*itr).operator->() ); + if ( owner && aDisplayed.contains( owner->entry() ) ) + aSelList.Append( aDisplayed[owner->entry()] ); + } + + myViewer->unHighlightAll( false ); + myViewer->setObjectsSelected( aSelList ); +} + +/*!Gets entry ob object.*/ +QString LightApp_OCCSelector::entry( const Handle(AIS_InteractiveObject)& anAIS ) const +{ + if ( anAIS.IsNull() || !anAIS->HasOwner() ) + return QString::null; + + Handle(SALOME_InteractiveObject) anObj = Handle(SALOME_InteractiveObject)::DownCast(anAIS->GetOwner()); + + QString res; + if ( !anObj.IsNull() ) + res = QString( anObj->getEntry() ); + return res; +} diff --git a/src/LightApp/LightApp_OCCSelector.h b/src/LightApp/LightApp_OCCSelector.h new file mode 100644 index 000000000..5a53992e0 --- /dev/null +++ b/src/LightApp/LightApp_OCCSelector.h @@ -0,0 +1,55 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef LIGHTAPP_OCCSELECTOR_H +#define LIGHTAPP_OCCSELECTOR_H + +#include "LightApp.h" + +#include + +#include + +class Handle_AIS_InteractiveObject; + +class LIGHTAPP_EXPORT LightApp_OCCSelector : public SUIT_Selector +{ + Q_OBJECT + +public: + LightApp_OCCSelector( OCCViewer_Viewer*, SUIT_SelectionMgr* ); + virtual ~LightApp_OCCSelector(); + + OCCViewer_Viewer* viewer() const; + + virtual QString type() const { return OCCViewer_Viewer::Type(); } + +private slots: + virtual void onSelectionChanged(); + +protected: + virtual void getSelection( SUIT_DataOwnerPtrList& ) const; + virtual void setSelection( const SUIT_DataOwnerPtrList& ); + + QString entry( const Handle_AIS_InteractiveObject& ) const; + +private: + OCCViewer_Viewer* myViewer; +}; + +#endif diff --git a/src/LightApp/LightApp_Preferences.cxx b/src/LightApp/LightApp_Preferences.cxx new file mode 100644 index 000000000..96d6abcb2 --- /dev/null +++ b/src/LightApp/LightApp_Preferences.cxx @@ -0,0 +1,105 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: LightApp_Preferences.cxx +// Author: Sergey TELKOV + +#include "LightApp_Preferences.h" + +#include + +#include + +/*! + Constructor.Initialize by resource manager and parent QWidget. +*/ +LightApp_Preferences::LightApp_Preferences( QtxResourceMgr* resMgr, QWidget* parent ) +: QtxListResourceEdit( resMgr, parent ) +{ +} + +/*! + Destructor. +*/ +LightApp_Preferences::~LightApp_Preferences() +{ +} + +/*! + Adds preference. +*/ +int LightApp_Preferences::addPreference( const QString& label, const int pId, const int type, + const QString& section, const QString& param ) +{ + return addItem( label, pId, type, section, param ); +} + +/*! + Adds preference. +*/ +int LightApp_Preferences::addPreference( const QString& mod, const QString& label, const int pId, + const int type, const QString& section, const QString& param ) +{ + int id = addItem( label, pId, type, section, param ); + if ( id != -1 && !mod.isEmpty() ) + myPrefMod.insert( id, mod ); + return id; +} + +/* + Checks: is preferences has module with name \a mod. +*/ +bool LightApp_Preferences::hasModule( const QString& mod ) const +{ + bool res = false; + for ( PrefModuleMap::ConstIterator it = myPrefMod.begin(); it != myPrefMod.end() && !res; ++it ) + res = it.data() == mod; + return res; +} + +/*!Do nothing.*/ +void LightApp_Preferences::onHelp() +{ +} + +/*!Store preferences on apply.*/ +void LightApp_Preferences::onApply() +{ + store(); +} + +/*!Emit preference changed.*/ +void LightApp_Preferences::changedResources( const QMap& map ) +{ + for ( QMap::ConstIterator it = map.begin(); it != map.end(); ++it ) + { + QString sec, param; + it.key()->resource( sec, param ); + QString mod = module( it.key()->id() ); + emit preferenceChanged( mod, sec, param ); + } +} + +/*!Gets module name by \a id, if exist.*/ +QString LightApp_Preferences::module( const int id ) const +{ + QString mod; + if ( myPrefMod.contains( id ) ) + mod = myPrefMod[id]; + return mod; +} diff --git a/src/LightApp/LightApp_Preferences.h b/src/LightApp/LightApp_Preferences.h new file mode 100644 index 000000000..2aa97f143 --- /dev/null +++ b/src/LightApp/LightApp_Preferences.h @@ -0,0 +1,67 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: LightApp_Preferences.h +// Author: Sergey TELKOV + +#ifndef LIGHTAPP_PREFERENCES_H +#define LIGHTAPP_PREFERENCES_H + +#include + +#include +#include + +#include + +class QtxResourceMgr; + +class LIGHTAPP_EXPORT LightApp_Preferences : public QtxListResourceEdit +{ + Q_OBJECT + +public: + LightApp_Preferences( QtxResourceMgr*, QWidget* = 0 ); + virtual ~LightApp_Preferences(); + + int addPreference( const QString& label, const int pId = -1, const int = -1, + const QString& section = QString::null, const QString& param = QString::null ); + int addPreference( const QString& modName, const QString& label, const int pId = -1, const int = -1, + const QString& section = QString::null, const QString& param = QString::null ); + + bool hasModule( const QString& ) const; + +signals: + void preferenceChanged( QString&, QString&, QString& ); + +private slots: + void onHelp(); + void onApply(); + virtual void changedResources( const QMap& ); + +private: + QString module( const int ) const; + +private: + typedef QMap PrefModuleMap; + +private: + PrefModuleMap myPrefMod; +}; + +#endif diff --git a/src/LightApp/LightApp_RootObject.h b/src/LightApp/LightApp_RootObject.h new file mode 100644 index 000000000..f5daff71c --- /dev/null +++ b/src/LightApp/LightApp_RootObject.h @@ -0,0 +1,51 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef LIGHTAPP_ROOTOBJECT_H +#define LIGHTAPP_ROOTOBJECT_H + +#include "LightApp.h" +#include "SUIT_DataObject.h" + +class LightApp_Study; + +/*! + LightApp_RootObject - class to be instanciated by only one object - + root object of LightApp data object tree. This object is not shown + in object browser (invisible), so it has no re-definition of name(), icon(), + etc. methods. The goal of this class is to provide a unified access + to LightApp_Study object from LightApp_DataObject instances. +*/ +class LIGHTAPP_EXPORT LightApp_RootObject : public SUIT_DataObject +{ +public: + LightApp_RootObject( LightApp_Study* study ) + : myStudy( study ) + {} + + virtual ~LightApp_RootObject() {} + + void setStudy( LightApp_Study* study ) { myStudy = study; } + LightApp_Study* study() const { return myStudy; } + +private: + LightApp_Study* myStudy; + +}; + +#endif diff --git a/src/LightApp/LightApp_SelectionMgr.cxx b/src/LightApp/LightApp_SelectionMgr.cxx new file mode 100644 index 000000000..ab7a4f8b1 --- /dev/null +++ b/src/LightApp/LightApp_SelectionMgr.cxx @@ -0,0 +1,289 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "LightApp_SelectionMgr.h" + +#include "LightApp_Study.h" +#include "LightApp_DataOwner.h" +#include "LightApp_DataSubOwner.h" +#include "LightApp_Application.h" + +#include + +#include +#include + +// Open CASCADE Include +#include +#include +#include + +/*! + Constructor. +*/ +LightApp_SelectionMgr::LightApp_SelectionMgr( LightApp_Application* app, const bool fb ) +: SUIT_SelectionMgr( fb ), +myApp( app ) +{ +} + +/*! + Destructor. +*/ +LightApp_SelectionMgr::~LightApp_SelectionMgr() +{ +} + +/*! + Gets application. +*/ +LightApp_Application* LightApp_SelectionMgr::application() const +{ + return myApp; +} + +/*! + Get all selected objects from selection manager +*/ +void LightApp_SelectionMgr::selectedObjects( SALOME_ListIO& theList, const QString& theType, + const bool convertReferences ) const +{ + theList.Clear(); + + SUIT_DataOwnerPtrList aList; + selected( aList, theType ); + + QMap entryMap; + + QString entry; + for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr ) + { + const LightApp_DataOwner* owner = dynamic_cast( (*itr).operator->() ); + if( !owner ) + continue; + + LightApp_Study* study = dynamic_cast( application()->activeStudy() ); + if ( !study ) + return; + + entry = owner->entry(); + if ( convertReferences ) { + QString refEntry = study->referencedToEntry( entry ); + if( !entryMap.contains( entry ) ) { + if ( refEntry != entry ) { + QString component = study->componentDataType( refEntry ); + theList.Append( new SALOME_InteractiveObject( refEntry, component, ""/*refobj->Name().c_str()*/ ) ); + } + else + theList.Append( owner->IO() ); + } + } + else { + if( !entryMap.contains( entry ) ) + theList.Append( owner->IO() ); + } + + entryMap.insert(owner->entry(), 1); + } +} + +/*! + Append selected objects. +*/ +void LightApp_SelectionMgr::setSelectedObjects( const SALOME_ListIO& lst, const bool append ) +{ + SUIT_DataOwnerPtrList owners; + for ( SALOME_ListIteratorOfListIO it( lst ); it.More(); it.Next() ) + { + if ( it.Value()->hasEntry() ) + owners.append( new LightApp_DataOwner( it.Value() ) ); + } + + setSelected( owners, append ); +} + +/*! + Emit current selection changed. +*/ +void LightApp_SelectionMgr::selectionChanged( SUIT_Selector* theSel ) +{ + SUIT_SelectionMgr::selectionChanged( theSel ); + + emit currentSelectionChanged(); +} + +/*! + get map of indexes for the given SALOME_InteractiveObject +*/ +void LightApp_SelectionMgr::GetIndexes( const Handle(SALOME_InteractiveObject)& IObject, + TColStd_IndexedMapOfInteger& theIndex) +{ + theIndex.Clear(); + + SUIT_DataOwnerPtrList aList; + selected( aList ); + + for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr ) + { + const LightApp_DataSubOwner* subOwner = dynamic_cast( (*itr).operator->() ); + if ( subOwner ) + if ( subOwner->entry() == QString(IObject->getEntry()) ) + theIndex.Add( subOwner->index() ); + } + +} + +/*! + get map of indexes for the given entry of SALOME_InteractiveObject +*/ +void LightApp_SelectionMgr::GetIndexes( const QString& theEntry, TColStd_IndexedMapOfInteger& theIndex ) +{ + theIndex.Clear(); + + SUIT_DataOwnerPtrList aList; + selected( aList ); + + for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr ) + { + const LightApp_DataSubOwner* subOwner = dynamic_cast( (*itr).operator->() ); + if ( subOwner ) + if ( subOwner->entry() == theEntry ) + theIndex.Add( subOwner->index() ); + } + +} + +/*! + Add or remove interactive objects from selection manager. +*/ +bool LightApp_SelectionMgr::AddOrRemoveIndex( const Handle(SALOME_InteractiveObject)& IObject, + const TColStd_MapOfInteger& theIndexes, + bool modeShift) +{ + SUIT_DataOwnerPtrList remainsOwners; + + SUIT_DataOwnerPtrList aList; + selected( aList ); + + if ( !modeShift ) { + for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr ) + { + const LightApp_DataOwner* owner = dynamic_cast( (*itr).operator->() ); + if ( owner ) + { + if ( owner->entry() != QString(IObject->getEntry()) ) + { + const LightApp_DataSubOwner* subOwner = dynamic_cast( owner ); + if ( subOwner ) + remainsOwners.append( new LightApp_DataSubOwner( subOwner->entry(), subOwner->index() ) ); + else + remainsOwners.append( new LightApp_DataOwner( owner->entry() ) ); + } + } + } + } + else + remainsOwners = aList; + + TColStd_MapIteratorOfMapOfInteger It; + It.Initialize(theIndexes); + for(;It.More();It.Next()) + remainsOwners.append( new LightApp_DataSubOwner( QString(IObject->getEntry()), It.Key() ) ); + + bool append = false; + setSelected( remainsOwners, append ); + + emit currentSelectionChanged(); + + TColStd_IndexedMapOfInteger anIndexes; + GetIndexes( IObject, anIndexes ); + return !anIndexes.IsEmpty(); + +} + +/*! + select 'subobjects' with given indexes +*/ +void LightApp_SelectionMgr::selectObjects( const Handle(SALOME_InteractiveObject)& IObject, + TColStd_IndexedMapOfInteger theIndex, bool append ) +{ + SUIT_DataOwnerPtrList aList; + + if ( theIndex.IsEmpty() ) + aList.append( new LightApp_DataOwner( QString(IObject->getEntry()) ) ); + else + { + int i; + for ( i = 1; i <= theIndex.Extent(); i++ ) + aList.append( new LightApp_DataSubOwner( QString(IObject->getEntry()), theIndex( i ) ) ); + } + + setSelected( aList, append ); + +} + +/*! + select 'subobjects' with given indexes +*/ +void LightApp_SelectionMgr::selectObjects( MapIOOfMapOfInteger theMapIO, bool append ) +{ + SUIT_DataOwnerPtrList aList; + + MapIOOfMapOfInteger::Iterator it; + for ( it = theMapIO.begin(); it != theMapIO.end(); ++it ) + { + if ( it.data().IsEmpty() ) + aList.append( new LightApp_DataOwner( QString(it.key()->getEntry()) ) ); + else + { + int i; + for ( i = 1; i <= it.data().Extent(); i++ ) + aList.append( new LightApp_DataSubOwner( QString(it.key()->getEntry()), it.data()( i ) ) ); + } + } + + setSelected( aList, append ); + +} + +/*! + get map of selected subowners : object's entry <-> map of indexes +*/ +void LightApp_SelectionMgr::selectedSubOwners( MapEntryOfMapOfInteger& theMap ) +{ + theMap.clear(); + + TColStd_IndexedMapOfInteger anIndexes; + + SUIT_DataOwnerPtrList aList; + selected( aList ); + + for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr ) + { + const LightApp_DataSubOwner* subOwner = dynamic_cast( (*itr).operator->() ); + if ( subOwner ) + { + if ( !theMap.contains( subOwner->entry() ) ) + { + anIndexes.Clear(); + GetIndexes( subOwner->entry(), anIndexes ); + theMap.insert( subOwner->entry(), anIndexes ); + } + } + } +} diff --git a/src/LightApp/LightApp_SelectionMgr.h b/src/LightApp/LightApp_SelectionMgr.h new file mode 100644 index 000000000..c063b82be --- /dev/null +++ b/src/LightApp/LightApp_SelectionMgr.h @@ -0,0 +1,75 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef LIGHTAPP_SELECTIONMGR_H +#define LIGHTAPP_SELECTIONMGR_H + +#include "LightApp.h" + +#include +#include + +#include + +class SALOME_ListIO; +class LightApp_Application; +class TColStd_IndexedMapOfInteger; +class TColStd_MapOfInteger; + +class LIGHTAPP_EXPORT LightApp_SelectionMgr : public SUIT_SelectionMgr +{ + Q_OBJECT + +public: + LightApp_SelectionMgr( LightApp_Application*, const bool = true ); + virtual ~LightApp_SelectionMgr(); + + typedef QMap< Handle(SALOME_InteractiveObject), TColStd_IndexedMapOfInteger > MapIOOfMapOfInteger; + typedef QMap< QString, TColStd_IndexedMapOfInteger > MapEntryOfMapOfInteger; + + LightApp_Application* application() const; + + void selectedObjects( SALOME_ListIO&, const QString& = QString::null, const bool = true ) const; + void setSelectedObjects( const SALOME_ListIO&, const bool = false ); + + void GetIndexes( const Handle(SALOME_InteractiveObject)& IObject, + TColStd_IndexedMapOfInteger& theIndex ); + void GetIndexes( const QString& theEntry, + TColStd_IndexedMapOfInteger& theIndex ); + + bool AddOrRemoveIndex( const Handle(SALOME_InteractiveObject)& IObject, + const TColStd_MapOfInteger& theIndices, + bool modeShift ); + + void selectObjects( const Handle(SALOME_InteractiveObject)& IObject, + TColStd_IndexedMapOfInteger theIndex, bool append ); + void selectObjects( MapIOOfMapOfInteger theMapIO, bool append ); + + void selectedSubOwners( MapEntryOfMapOfInteger& theMap ); + +signals: + void currentSelectionChanged(); + +private: + virtual void selectionChanged( SUIT_Selector* ); + +private: + LightApp_Application* myApp; +}; + +#endif diff --git a/src/LightApp/LightApp_ShowHideOp.h b/src/LightApp/LightApp_ShowHideOp.h new file mode 100644 index 000000000..cac7b918d --- /dev/null +++ b/src/LightApp/LightApp_ShowHideOp.h @@ -0,0 +1,45 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// + +#ifndef LIGHTAPP_SHOW_HIDE_OPERATION_HEADER +#define LIGHTAPP_SHOW_HIDE_OPERATION_HEADER + +#include "LightApp_Operation.h" + +class LightApp_Displayer; +class LIGHTAPP_EXPORT LightApp_ShowHideOp : public LightApp_Operation +{ + Q_OBJECT + +public: + typedef enum { DISPLAY, ERASE, DISPLAY_ONLY, ERASE_ALL } ActionType; + +public: + LightApp_ShowHideOp( ActionType ); + ~LightApp_ShowHideOp(); + +protected: + virtual void startOperation(); + +private: + ActionType myActionType; +}; + +#endif + diff --git a/src/LightApp/LightApp_Study.cxx b/src/LightApp/LightApp_Study.cxx new file mode 100644 index 000000000..e6b6f04a2 --- /dev/null +++ b/src/LightApp/LightApp_Study.cxx @@ -0,0 +1,468 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "LightApp_Study.h" + +#include "CAM_DataModel.h" +#include "LightApp_Application.h" +#include "LightApp_DataModel.h" +#include "LightApp_DataObject.h" +#include "LightApp_RootObject.h" +#include "LightApp_Driver.h" + +#include "SUIT_ResourceMgr.h" +#include "SUIT_DataObjectIterator.h" + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/*! + Constructor. +*/ +LightApp_Study::LightApp_Study( SUIT_Application* app ) +: CAM_Study( app ) +{ + myDriver = new LightApp_Driver(); +} + +/*! + Destructor. +*/ +LightApp_Study::~LightApp_Study() +{ +} + +/*! + Create document. +*/ +void LightApp_Study::createDocument() +{ + // create myRoot + setRoot( new LightApp_RootObject( this ) ); + + CAM_Study::createDocument(); + + emit created( this ); +} + +//======================================================================= +// name : openDocument +/*! Purpose : Open document*/ +//======================================================================= +bool LightApp_Study::openDocument( const QString& theFileName ) +{ + myDriver->ClearDriverContents(); + // create files for models from theFileName + if( !openStudyData(theFileName)) + return false; + + setRoot( new LightApp_RootObject( this ) ); // create myRoot + + // update loaded data models: call open() and update() on them. + ModelList dm_s; + dataModels( dm_s ); + for ( ModelListIterator it( dm_s ); it.current(); ++it ) + openDataModel( studyName(), it.current() ); + // this will build a SUIT_DataObject-s tree under myRoot member field + // passing "false" in order NOT to rebuild existing data models' trees - it was done in previous step + // but tree that corresponds to not-loaded data models will be updated any way. + ((LightApp_Application*)application())->updateObjectBrowser( false ); + + bool res = CAM_Study::openDocument( theFileName ); + + emit opened( this ); + return res; +} + +//======================================================================= +// name : loadDocument +/*! Purpose : Load document */ +//======================================================================= +bool LightApp_Study::loadDocument( const QString& theStudyName ) +{ + myDriver->ClearDriverContents(); + if( !openStudyData(theStudyName)) + return false; + + setRoot( new LightApp_RootObject( this ) ); // create myRoot + + //SRN: BugID IPAL9021, put there the same code as in a method openDocument + + // update loaded data models: call open() and update() on them. + ModelList dm_s; + dataModels( dm_s ); + + for ( ModelListIterator it( dm_s ); it.current(); ++it ) + openDataModel( studyName(), it.current() ); + + // this will build a SUIT_DataObject-s tree under myRoot member field + // passing "false" in order NOT to rebuild existing data models' trees - it was done in previous step + // but tree that corresponds to not-loaded data models will be updated any way. + ((LightApp_Application*)application())->updateObjectBrowser( false ); + + bool res = CAM_Study::openDocument( theStudyName ); + emit opened( this ); + //SRN: BugID IPAL9021: End + return res; +} + +//======================================================================= +// name : saveDocumentAs +/*! Purpose : Save document */ +//======================================================================= +bool LightApp_Study::saveDocumentAs( const QString& theFileName ) +{ + SUIT_ResourceMgr* resMgr = application()->resourceMgr(); + if( !resMgr ) + return false; + + ModelList list; + dataModels( list ); + + LightApp_DataModel* aModel = (LightApp_DataModel*)list.first(); + + QStringList listOfFiles; + bool isMultiFile = resMgr->booleanValue( "Study", "multi_file", false ); + for ( ; aModel; aModel = (LightApp_DataModel*)list.next() ) + { + std::vector anOldList = myDriver->GetListOfFiles( aModel->module()->name() ); + listOfFiles.clear(); + aModel->saveAs( theFileName, this, listOfFiles ); + if ( !listOfFiles.isEmpty() ) + saveModuleData(aModel->module()->name(), listOfFiles); + + // Remove files if necessary. File is removed if it was in the list of files before + // saving and it is not contained in the list after saving. This provides correct + // removing previous temporary files. These files are not removed before saving + // because they may be required for it. + + std::vector aNewList = myDriver->GetListOfFiles( aModel->module()->name() ); + + std::set aNewNames; + std::set toRemove; + int i, n; + for( i = 0, n = aNewList.size(); i < n; i++ ) + aNewNames.insert( aNewList[ i ] ); + for( i = 0, n = anOldList.size(); i < n; i++ ) + { + if ( i == 0 ) // directory is always inserted in list + toRemove.insert( anOldList[ i ] ); + else if ( aNewNames.find( anOldList[ i ] ) == aNewNames.end() ) + toRemove.insert( anOldList[ i ] ); + } + + std::vector toRemoveList( toRemove.size() ); + std::set::iterator anIter; + for( anIter = toRemove.begin(), i = 0; anIter != toRemove.end(); ++anIter, ++i ) + toRemoveList[ i ] = *anIter; + + + myDriver->RemoveFiles( toRemoveList, isMultiFile ); + } + + bool res = saveStudyData(theFileName); + res = res && CAM_Study::saveDocumentAs( theFileName ); + //SRN: BugID IPAL9377, removed usage of uninitialized variable + if ( res ) + emit saved( this ); + + return res; +} + +//======================================================================= +// name : saveDocument +/*! Purpose : Save document */ +//======================================================================= +bool LightApp_Study::saveDocument() +{ + ModelList list; dataModels( list ); + + LightApp_DataModel* aModel = (LightApp_DataModel*)list.first(); + + myDriver->ClearDriverContents(); + QStringList listOfFiles; + for ( ; aModel; aModel = (LightApp_DataModel*)list.next() ) { + listOfFiles.clear(); + aModel->save( listOfFiles ); + saveModuleData(aModel->module()->name(), listOfFiles); + } + + bool res = saveStudyData(studyName()); + res = res && CAM_Study::saveDocument(); + if (res) + emit saved( this ); + + return res; +} + +//================================================================ +// Function : closeDocument +/*! Purpose : Close document */ +//================================================================ +void LightApp_Study::closeDocument(bool permanently) +{ + // Remove temporary files + ModelList aList; + dataModels( aList ); + myDriver->ClearDriverContents(); + + // Inform everybody that this study is going to close when it's most safe to, + // i.e. in the very beginning + emit closed( this ); + + CAM_Study::closeDocument(permanently); +} + +//================================================================ +// Function : referencedToEntry +/*! Purpose : Return current entry*/ +//================================================================ +QString LightApp_Study::referencedToEntry( const QString& entry ) const +{ + return entry; +} + +//================================================================ +// Function : children +/*! Purpose : Return entries of children of object*/ +//================================================================ +void LightApp_Study::children( const QString&, QStringList& ) const +{ +} + +//================================================================ +// Function : isComponent +/*! Purpose : Return true if entry corresponds to component*/ +//================================================================ +bool LightApp_Study::isComponent( const QString& entry ) const +{ + return false; +} + +//================================================================ +// Function : componentDataType +/*! Purpose : Return component data type from entry*/ +//================================================================ +QString LightApp_Study::componentDataType( const QString& entry ) const +{ + LightApp_DataObject* aCurObj; + for ( SUIT_DataObjectIterator it( root(), SUIT_DataObjectIterator::DepthLeft ); it.current(); ++it ) { + aCurObj = dynamic_cast( it.current() ); + if ( aCurObj && aCurObj->entry() == entry ) { + return aCurObj->componentDataType(); + } + } + return ""; +} + +//================================================================ +// Function : isModified +// Purpose : +//================================================================ +bool LightApp_Study::isModified() const +{ + bool isAnyChanged = CAM_Study::isModified(); + ModelList list; dataModels( list ); + + LightApp_DataModel* aModel = 0; + for ( QPtrListIterator it( list ); it.current() && !isAnyChanged; ++it ){ + aModel = dynamic_cast( it.current() ); + if ( aModel ) + isAnyChanged = aModel->isModified(); + } + return isAnyChanged; +} + +//================================================================ +// Function : isSaved +/*! Purpose : Check: data model is saved?*/ +//================================================================ +bool LightApp_Study::isSaved() const +{ + return CAM_Study::isSaved(); +} + +//======================================================================= +// name : saveModuleData +/*! Purpose : Create SComponent for module, necessary for SalomeApp study */ +//======================================================================= +void LightApp_Study::addComponent(const CAM_DataModel* dm) +{ +} + +//======================================================================= +// name : saveModuleData +/*! Purpose : save list file for module 'theModuleName' */ +//======================================================================= +void LightApp_Study::saveModuleData(QString theModuleName, QStringList theListOfFiles) +{ + int aNb = theListOfFiles.count(); + if ( aNb == 0 ) + return; + + std::vector aListOfFiles ( aNb ); + int anIndex = 0; + for ( QStringList::Iterator it = theListOfFiles.begin(); it != theListOfFiles.end(); ++it ) { + if ( (*it).isEmpty() ) + continue; + aListOfFiles[anIndex] = (*it).latin1(); + anIndex++; + } + myDriver->SetListOfFiles(theModuleName, aListOfFiles); +} + +//======================================================================= +// name : openModuleData +/*! Purpose : gets list of file for module 'theModuleNam' */ +//======================================================================= +void LightApp_Study::openModuleData(QString theModuleName, QStringList& theListOfFiles) +{ + std::vector aListOfFiles = myDriver->GetListOfFiles(theModuleName); + int i, aLength = aListOfFiles.size() - 1; + if (aLength < 0) + return; + + //Get a temporary directory for saved a file + theListOfFiles.append(aListOfFiles[0].c_str()); + for(i = 0; i < aLength; i++) + theListOfFiles.append(aListOfFiles[i+1].c_str()); +} + +//======================================================================= +// name : saveStudyData +/*! Purpose : save data from study */ +//======================================================================= +bool LightApp_Study::saveStudyData( const QString& theFileName ) +{ + ModelList list; dataModels( list ); + SUIT_ResourceMgr* resMgr = application()->resourceMgr(); + if( !resMgr ) + return false; + bool isMultiFile = resMgr->booleanValue( "Study", "multi_file", false ); + + bool aRes = myDriver->SaveDatasInFile(theFileName.latin1(), isMultiFile); + return aRes; +} + +//======================================================================= +// name : openStudyData +/*! Purpose : open data for study */ +//======================================================================= +bool LightApp_Study::openStudyData( const QString& theFileName ) +{ + SUIT_ResourceMgr* resMgr = application()->resourceMgr(); + if( !resMgr ) + return false; + bool isMultiFile = resMgr->booleanValue( "Study", "multi_file", false ); + + bool aRes = myDriver->ReadDatasFromFile(theFileName.latin1(), isMultiFile); + return aRes; +} + +//================================================================ +// Function : openDataModel +/*! Purpose : Open data model */ +//================================================================ +bool LightApp_Study::openDataModel( const QString& studyName, CAM_DataModel* dm ) +{ + if (!dm) + return false; + + QStringList listOfFiles; + openModuleData(dm->module()->name(), listOfFiles); + if (dm && dm->open(studyName, this, listOfFiles)) { + // Something has been read -> create data model tree + LightApp_DataModel* aDM = dynamic_cast( dm ); + if ( aDM ) + aDM->update(NULL, this); + return true; + } + return false; +} + +//================================================================ +// Function : GetTmpDir +/*! Purpose : to be used by modules*/ +//================================================================ +std::string LightApp_Study::GetTmpDir (const char* theURL, + const bool isMultiFile) +{ + return myDriver->GetTmpDir(theURL, isMultiFile); +} + +//================================================================ +// Function : GetListOfFiles +/*! Purpose : to be used by modules*/ +//================================================================ +std::vector LightApp_Study::GetListOfFiles(const char* theModuleName) const +{ + std::vector aListOfFiles; + aListOfFiles = myDriver->GetListOfFiles(theModuleName); + return aListOfFiles; +} + +//================================================================ +// Function : SetListOfFiles +/*! Purpose : to be used by modules*/ +//================================================================ +void LightApp_Study::SetListOfFiles (const char* theModuleName, const std::vector theListOfFiles) +{ + myDriver->SetListOfFiles(theModuleName, theListOfFiles); +} + +//================================================================ +// Function : RemoveTemporaryFiles +/*! Purpose : to be used by modules*/ +//================================================================ +void LightApp_Study::RemoveTemporaryFiles (const char* theModuleName, const bool isMultiFile) const +{ + if (isMultiFile) + return; + bool isDirDeleted = true; + myDriver->RemoveTemporaryFiles(theModuleName, isDirDeleted); +} + +//================================================================ +// Function : RemoveTemporaryFiles +/*! Purpose : to be used by modules*/ +//================================================================ +void LightApp_Study::components( QStringList& comp ) const +{ + DataObjectList children = root()->children(); + DataObjectList::const_iterator anIt = children.begin(), aLast = children.end(); + for( ; anIt!=aLast; anIt++ ) + { + LightApp_DataObject* obj = dynamic_cast( *anIt ); + if( obj && obj->entry()!="Interface Applicative" ) + comp.append( obj->entry() ); + } +} + diff --git a/src/LightApp/LightApp_Study.h b/src/LightApp/LightApp_Study.h new file mode 100644 index 000000000..1280fd99a --- /dev/null +++ b/src/LightApp/LightApp_Study.h @@ -0,0 +1,91 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef LIGHTAPP_STUDY_H +#define LIGHTAPP_STUDY_H + +#include +#include + +#include +#include +#include + +#include "string" +#include "vector" + +class SUIT_Application; +class CAM_DataModel; + +class LIGHTAPP_EXPORT LightApp_Study : public CAM_Study +{ + Q_OBJECT + +public: + LightApp_Study( SUIT_Application* ); + virtual ~LightApp_Study(); + + virtual void createDocument(); + virtual bool openDocument( const QString& ); + virtual bool loadDocument( const QString& ); + + virtual bool saveDocument(); + virtual bool saveDocumentAs( const QString& ); + + virtual void closeDocument(bool permanently = true); + + virtual bool isSaved() const; + virtual bool isModified() const; + + virtual void addComponent ( const CAM_DataModel* dm); + + virtual std::string GetTmpDir ( const char* theURL, const bool isMultiFile ); + + virtual QString componentDataType( const QString& ) const; + virtual QString referencedToEntry( const QString& ) const; + virtual bool isComponent( const QString& ) const; + virtual void children( const QString&, QStringList& ) const; + virtual void components( QStringList& ) const; + +protected: + virtual void saveModuleData ( QString theModuleName, QStringList theListOfFiles ); + virtual void openModuleData ( QString theModuleName, QStringList& theListOfFiles ); + virtual bool saveStudyData ( const QString& theFileName ); + virtual bool openStudyData ( const QString& theFileName ); + + virtual std::vector GetListOfFiles ( const char* theModuleName ) const; + virtual void SetListOfFiles ( const char* theModuleName, + const std::vector theListOfFiles ); + + virtual void RemoveTemporaryFiles ( const char* theModuleName, const bool isMultiFile ) const; + +protected: + virtual bool openDataModel ( const QString&, CAM_DataModel* ); + +signals: + void saved ( SUIT_Study* ); + void opened ( SUIT_Study* ); + void closed ( SUIT_Study* ); + void created( SUIT_Study* ); + + +private: + LightApp_Driver* myDriver; +}; + +#endif diff --git a/src/LightApp/LightApp_SwitchOp.cxx b/src/LightApp/LightApp_SwitchOp.cxx new file mode 100755 index 000000000..14feeaa6d --- /dev/null +++ b/src/LightApp/LightApp_SwitchOp.cxx @@ -0,0 +1,182 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +/** +* LIGHT LightApp +* +* Copyright (C) 2005 CEA/DEN, EDF R&D +* +* +* +* File : LightApp_SwitchOp.h +* Author : Sergey LITONIN +* Module : LIGHT +*/ + +#include "LightApp_SwitchOp.h" +#include "LightApp_Module.h" +#include "LightApp_Operation.h" +#include "LightApp_Dialog.h" +#include +#include +#include +#include +#include +#include +#include + +/*! + * \brief Constructor + * \param theParent - parent of object +* +* Creates instance of the object. Connects signals and slots. Install eveny filter +* on application +*/ +LightApp_SwitchOp::LightApp_SwitchOp( LightApp_Module* theModule ) +: QObject( 0 ), + myModule( theModule ) +{ + qApp->installEventFilter( this ); +} + +/*! + * \brief Destructor +*/ +LightApp_SwitchOp::~LightApp_SwitchOp() +{ + +} + +/*! + * \brief Get module +* +* Get module. Module is a parent of this class +*/ +LightApp_Module* LightApp_SwitchOp::module() const +{ + return myModule; +} + +/*! + * \brief Get study + * \return Active study of application (in current realisation) +* +* Get study +*/ +SUIT_Study* LightApp_SwitchOp::study() const +{ + return module()->application()->activeStudy(); +} + +/*! + * \brief Get operation by widget + * \param theWg - key widget to find operation + * \return Pointer to the operations if it is found or zero +* +* Find operation containing dialog with given widget +*/ +LightApp_Operation* LightApp_SwitchOp::operation( QWidget* theWg ) const +{ + // get dialog from widget + LightApp_Dialog* aDlg = 0; + QWidget* aParent = theWg; + while( aParent && !aParent->inherits( "LightApp_Dialog" ) ) + aParent = aParent->parentWidget(); + + if ( aParent && aParent->inherits( "LightApp_Dialog" ) ) + aDlg = (LightApp_Dialog*)aParent; + + // try to find operation corresponding to the dialog + if ( aDlg != 0 && study() != 0 ) + { + QPtrListIterator anIter( study()->operations() ); + while( SUIT_Operation* anOp = anIter.current() ) + { + if ( anOp->inherits( "LightApp_Operation" ) && + ((LightApp_Operation*)anOp)->dlg() == aDlg ) + return ((LightApp_Operation*)anOp); + ++anIter; + } + } + + return 0; +} + +/*! + * \brief Event filter + * \param theObj - object + * \param theEv - event +* +* Event filter. Catched signals off application. If event concerns to dialog then +* corresponding operation is found and activated. +*/ +bool LightApp_SwitchOp::eventFilter( QObject* theObj, QEvent* theEv ) +{ + if ( theObj->inherits( "QWidget" ) && ( theEv->type() == QEvent::Enter ) ) + { + QEvent::Type aType = theEv->type(); + LightApp_Operation* anOp = operation( (QWidget*)theObj ); + if ( anOp ) + { + switch ( aType ) + { + case QEvent::Enter: + { + if ( !anOp->isActive() && anOp->isAutoResumed() && + study() && !study()->blockingOperation( anOp ) ) + study()->resume( anOp ); + } + break; + + case QEvent::MouseButtonRelease: + case QEvent::MouseButtonPress: + case QEvent::MouseButtonDblClick: + case QEvent::MouseMove: + case QEvent::KeyPress: + case QEvent::KeyRelease: + { + if ( !anOp->isActive() ) + return true; + } + break; + + } + } + } + + return QObject::eventFilter( theObj, theEv ); +} + + + + + + + + + + + + + + + + + + + diff --git a/src/LightApp/LightApp_SwitchOp.h b/src/LightApp/LightApp_SwitchOp.h new file mode 100755 index 000000000..dad93261d --- /dev/null +++ b/src/LightApp/LightApp_SwitchOp.h @@ -0,0 +1,90 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +/** +* LIGHT LightApp +* +* Copyright (C) 2005 CEA/DEN, EDF R&D +* +* +* +* File : LightApp_SwitchOp.h +* Author : Sergey LITONIN +* Module : LIGHT +*/ + + + +#ifndef LightApp_SwitchOp_H +#define LightApp_SwitchOp_H + +#include "LightApp.h" +#include + +class LightApp_Module; +class LightApp_Operation; +class QEvent; +class SUIT_Study; + +/*! + * \brief This class is intended for controling switching between operation + * + * Several operation may be launched simultaneously. This class is intended for + * controlling switching between such operations. This class works with operations having + * dialogs (activation of other operations is performed by SUIT_Study). When several + * operations is launched simultaneously corresponding dialogs are shown on the screen. + * Only one operation from the launched ones can be active (active operation). Other + * operations are suspended. As result only one dialog from shown ones can be active too. + * Other dialogs are disabled. This class installs event filter on application. When mouse + * cursor is moved above disabled dialog corresponding event is catched by this class. + * It finds corresponding operation and verify whether operation can be resumed (see + * SUIT_Study::isDenied( SUIT_Operation* ) method). If yes then current active + * operation is suspended and new operation activated. Module contains this class as a + * field. Then module is created instance of this class created too. + */ +class LIGHTAPP_EXPORT LightApp_SwitchOp : public QObject +{ + Q_OBJECT + +public: + + LightApp_SwitchOp( LightApp_Module* ); + virtual ~LightApp_SwitchOp(); + + // Redefined from base class + bool eventFilter( QObject*, QEvent* ); + +private: + + LightApp_Module* module() const; + LightApp_Operation* operation( QWidget* ) const; + SUIT_Study* study() const; + +private: + + LightApp_Module* myModule; + +}; + +#endif + + + + + + diff --git a/src/LightApp/LightApp_WidgetContainer.cxx b/src/LightApp/LightApp_WidgetContainer.cxx new file mode 100644 index 000000000..df92c5313 --- /dev/null +++ b/src/LightApp/LightApp_WidgetContainer.cxx @@ -0,0 +1,151 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "LightApp_WidgetContainer.h" + +#include +#include + +/*! + Constructor. +*/ +LightApp_WidgetContainer::LightApp_WidgetContainer( const int type, QWidget* parent ) +: QDockWindow( QDockWindow::InDock, parent ), +myType( type ) +{ + setWidget( myStack = new QWidgetStack( this ) ); + myStack->show(); +} + +/*! + Destructor. +*/ +LightApp_WidgetContainer::~LightApp_WidgetContainer() +{ +} + +/*! + Checks: is widget container is empty? +*/ +bool LightApp_WidgetContainer::isEmpty() const +{ + const QObjectList* lst = myStack->children(); + if ( !lst ) + return true; + + bool res = true; + for ( QObjectListIt it( *lst ); it.current() && res; ++it ) + { + if ( it.current()->isWidgetType() && myStack->id( (QWidget*)it.current() ) != -1 ) + res = false; + } + return res; +} + +/*! + Gets type of widget container. +*/ +int LightApp_WidgetContainer::type() const +{ + return myType; +} + +/*! + Checks: is container contains widget with id \a id. +*/ +bool LightApp_WidgetContainer::contains( const int id ) const +{ + return myStack->widget( id ) != 0; +} + +/*! + * Insert widget(\a wid with id \a id) to container.And return id of widget in stack. + *\warning remove widget with id = \a id , if it was in container. + */ +int LightApp_WidgetContainer::insert( const int id, QWidget* wid ) +{ + if ( id == -1 || !wid ) + return -1; + + if ( contains( id ) ) + remove( id ); + + int stackId = myStack->addWidget( wid, id ); + if ( !myStack->visibleWidget() ) + myStack->raiseWidget( wid ); + + setCaption( myStack->visibleWidget() ? myStack->visibleWidget()->caption() : QString::null ); + + return stackId; +} + +/*! + Remove widget(\a wid) from stack. +*/ +void LightApp_WidgetContainer::remove( const int id ) +{ + remove( myStack->widget( id ) ); + + setCaption( myStack->visibleWidget() ? myStack->visibleWidget()->caption() : QString::null ); +} + +/*! + Remove widget(\a wid) from stack. +*/ +void LightApp_WidgetContainer::remove( QWidget* wid ) +{ + myStack->removeWidget( wid ); + + setCaption( myStack->visibleWidget() ? myStack->visibleWidget()->caption() : QString::null ); +} + +/*! + Raise widget with id = \a id. +*/ +void LightApp_WidgetContainer::activate( const int id ) +{ + myStack->raiseWidget( id ); + + setCaption( myStack->visibleWidget() ? myStack->visibleWidget()->caption() : QString::null ); +} + +/*! + Raise widget (\a wid). +*/ +void LightApp_WidgetContainer::activate( QWidget* wid ) +{ + myStack->raiseWidget( wid ); + + setCaption( myStack->visibleWidget() ? myStack->visibleWidget()->caption() : QString::null ); +} + +/*! + Gets widget from container list(stack) by id = \a id. +*/ +QWidget* LightApp_WidgetContainer::widget( const int id ) const +{ + return myStack->widget( id ); +} + +/*! + Gets visible widget. +*/ +QWidget* LightApp_WidgetContainer::active() const +{ + return myStack->visibleWidget(); +} diff --git a/src/LightApp/LightApp_WidgetContainer.h b/src/LightApp/LightApp_WidgetContainer.h new file mode 100644 index 000000000..df6dbc84d --- /dev/null +++ b/src/LightApp/LightApp_WidgetContainer.h @@ -0,0 +1,60 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef LIGHTAPP_WIDGETCONTAINER_H +#define LIGHTAPP_WIDGETCONTAINER_H + +#include "LightApp.h" + +#include + +class QWidget; +class QWidgetStack; + +/*! + Class which privade widget container. +*/ +class LIGHTAPP_EXPORT LightApp_WidgetContainer : public QDockWindow +{ + Q_OBJECT + +public: + LightApp_WidgetContainer( const int, QWidget* = 0 ); + virtual ~LightApp_WidgetContainer(); + + bool isEmpty() const; + + int type() const; + + int insert( const int, QWidget* ); + void remove( QWidget* ); + void remove( const int ); + bool contains( const int ) const; + + void activate( QWidget* ); + void activate( const int ); + + QWidget* active() const; + QWidget* widget( const int ) const; + +private: + int myType; + QWidgetStack* myStack; +}; + +#endif diff --git a/src/OBJECT/SALOME_GLOwner.cxx b/src/OBJECT/SALOME_GLOwner.cxx new file mode 100644 index 000000000..ed88afb38 --- /dev/null +++ b/src/OBJECT/SALOME_GLOwner.cxx @@ -0,0 +1,40 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// + +#include + +SALOME_GLOwner::SALOME_GLOwner( const char* entry ) +: GLViewer_Owner() +{ + setEntry( entry ); +} + +SALOME_GLOwner::~SALOME_GLOwner() +{ +} + +const char* SALOME_GLOwner::entry() const +{ + return myEntry.c_str(); +} + +void SALOME_GLOwner::setEntry( const char* entry ) +{ + myEntry = entry; +} diff --git a/src/OBJECT/SALOME_GLOwner.h b/src/OBJECT/SALOME_GLOwner.h new file mode 100644 index 000000000..770911392 --- /dev/null +++ b/src/OBJECT/SALOME_GLOwner.h @@ -0,0 +1,45 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SALOME_GLOWNER_H +#define SALOME_GLOWNER_H + +#include +//#include +#include + +#ifdef WNT +#define SALOME_OBJECT_EXPORT __declspec (dllexport) +#else +#define SALOME_OBJECT_EXPORT +#endif + +class SALOME_OBJECT_EXPORT SALOME_GLOwner : public GLViewer_Owner +{ +public: + SALOME_GLOwner( const char* ); + ~SALOME_GLOwner(); + + const char* entry() const; + void setEntry( const char* ); + +private: + std::string myEntry; +}; + +#endif diff --git a/src/OCCViewer/OCCViewer.h b/src/OCCViewer/OCCViewer.h new file mode 100755 index 000000000..ef0e91714 --- /dev/null +++ b/src/OCCViewer/OCCViewer.h @@ -0,0 +1,31 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifdef WNT +#ifdef OCCVIEWER_EXPORTS +#define OCCVIEWER_EXPORT __declspec(dllexport) +#else +#define OCCVIEWER_EXPORT __declspec(dllimport) +#endif +#else +#define OCCVIEWER_EXPORT +#endif + +#if defined WNT +#pragma warning ( disable: 4251 ) +#endif diff --git a/src/OCCViewer/OCCViewer_AISSelector.cxx b/src/OCCViewer/OCCViewer_AISSelector.cxx new file mode 100755 index 000000000..74cbca1bb --- /dev/null +++ b/src/OCCViewer/OCCViewer_AISSelector.cxx @@ -0,0 +1,223 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "OCCViewer_AISSelector.h" + +/*! + Constructor +*/ +OCCViewer_AISSelector::OCCViewer_AISSelector( QObject* parent, + const Handle (AIS_InteractiveContext)& aisContext) : + QObject( parent ), + myNumSelected( 0 ), + myEnableSelection( true ), + myEnableMultipleSelection( true ) +{ + myHilightColor = Quantity_NOC_CYAN1; + mySelectColor = Quantity_NOC_GRAY80; + + setAISContext( aisContext ); +} + +/*! + Destructor +*/ +OCCViewer_AISSelector::~OCCViewer_AISSelector() +{ +} + +/*! + Enables/disables selection +*/ +void OCCViewer_AISSelector::enableSelection( bool bEnable ) +{ + myEnableSelection = bEnable; +} + +/*! + Enables/disables multiple selection i.e + selection of several objects at the same time. +*/ +void OCCViewer_AISSelector::enableMultipleSelection( bool bEnable ) +{ + myEnableMultipleSelection = bEnable; + if ( bEnable ) myEnableSelection = bEnable; +} + +/*! + Sets the color to hilight the detected objects +*/ +void OCCViewer_AISSelector::setHilightColor ( Quantity_NameOfColor color ) +{ + myHilightColor = color; + if ( !myAISContext.IsNull() ) + myAISContext->SetHilightColor( myHilightColor ); +} + +/*! + Sets the color to display the selected objects +*/ +void OCCViewer_AISSelector::setSelectColor ( Quantity_NameOfColor color ) +{ + mySelectColor = color; + if ( !myAISContext.IsNull() ) + myAISContext->SelectionColor( mySelectColor ); +} + +/*! + Sets the interactive context for this selector +*/ +void OCCViewer_AISSelector::setAISContext ( const Handle (AIS_InteractiveContext)& aisContext ) +{ + myAISContext = aisContext; + if ( ! myAISContext.IsNull() ) { + myAISContext->SetHilightColor( myHilightColor ); + myAISContext->SelectionColor( mySelectColor ); + myAISContext->SetSubIntensityColor( Quantity_NOC_CYAN1 ); + } +} + +/*! + Checks the status of pick and emits 'selSelectionDone' or + 'selSelectionCancel'. + Returns 'true' if no error, 'false' otherwise. +*/ +bool OCCViewer_AISSelector::checkSelection ( AIS_StatusOfPick status, + bool hadSelection, + bool addTo ) +{ + if ( myAISContext.IsNull() ) + return false; + + myNumSelected = myAISContext->NbCurrents(); /* update after the last selection */ + + if ( status == AIS_SOP_NothingSelected && !hadSelection ) { + emit selSelectionCancel( addTo ); + } + else if ( status == AIS_SOP_NothingSelected && hadSelection ) { + emit selSelectionCancel( addTo ); /* unselected now */ + } + else if ( status == AIS_SOP_OneSelected || status == AIS_SOP_SeveralSelected ) + { + emit selSelectionDone( addTo ); /* selected ( the same object, may be ) */ + } + return ( status != AIS_SOP_Error && status != AIS_SOP_NothingSelected ); +} + +/*! + Detects the interactive objects at position (x,y). + Returns 'true' if no error, 'false' otherwise. +*/ +bool OCCViewer_AISSelector::moveTo ( int x, int y, const Handle (V3d_View)& view ) +{ + if ( myAISContext.IsNull() ) + return false; + + if ( !myEnableSelection ) + return false; + + AIS_StatusOfDetection status = AIS_SOD_Error; + status = myAISContext->MoveTo (x, y, view); + + return ( status != AIS_SOD_Error && status != AIS_SOD_AllBad ); +} + +/*! + Selects the detected interactive objects. + Calls checkSelection() for checking the status. +*/ +bool OCCViewer_AISSelector::select () +{ + if ( myAISContext.IsNull() ) + return false; + + if ( !myEnableSelection ) + return false; + + bool hadSelection = ( myNumSelected > 0 ); + + /* select and send notifications */ + return checkSelection ( myAISContext->Select(), hadSelection, false ); +} + +/*! + Selects the objects covered by the rectangle. + Multiple selection must be enabled to get use of this function. + Calls checkSelection() for checking the status. +*/ +bool OCCViewer_AISSelector::select ( int left, int top, int right, int bottom, + const Handle (V3d_View)& view ) +{ + if ( myAISContext.IsNull() ) + return false; + + if ( !myEnableSelection || !myEnableMultipleSelection ) + return false; /* selection with rectangle is considered as multiple selection */ + + bool hadSelection = ( myNumSelected > 0 ); + + /* select and send notifications */ + return checkSelection ( myAISContext->Select(left, top, right, bottom, view), + hadSelection, false ); +} + +/*! + Adds new selected objects to the objects previously selected. + Multiple selection must be enabled to get use of this function. + Calls checkSelection() for checking the status. +*/ +bool OCCViewer_AISSelector::shiftSelect () +{ + if ( myAISContext.IsNull() ) + return false; + + if ( !myEnableSelection ) + return false; + + bool hadSelection = ( myNumSelected > 0 ); /* something was selected */ + if ( hadSelection && !myEnableMultipleSelection) + return false; + + /* select and send notifications */ + return checkSelection ( myAISContext->ShiftSelect(), hadSelection, true ); +} + +/*! + Adds new selected objects covered by the rectangle to the objects + previously selected. + Multiple selection must be enabled to get use of this function. + Calls checkSelection() for checking the status. +*/ +bool OCCViewer_AISSelector::shiftSelect ( int left, int top, int right, int bottom, + const Handle (V3d_View)& view ) + +{ + if ( myAISContext.IsNull() ) + return false; + + if ( !myEnableSelection || !myEnableMultipleSelection ) + return false; /* selection with rectangle is considered as multiple selection */ + + bool hadSelection = ( myNumSelected > 0 ); /* something was selected */ + if ( hadSelection && !myEnableMultipleSelection) + return false; + + /* select and send notifications */ + return checkSelection ( myAISContext->ShiftSelect(left,top,right,bottom, view), + hadSelection, true ); +} diff --git a/src/OCCViewer/OCCViewer_AISSelector.h b/src/OCCViewer/OCCViewer_AISSelector.h new file mode 100755 index 000000000..526ab824a --- /dev/null +++ b/src/OCCViewer/OCCViewer_AISSelector.h @@ -0,0 +1,82 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#if !defined( OCCVIEWER_AISSELECTOR_H ) +#define OCCVIEWER_AISSELECTOR_H + +#include "OCCViewer.h" +#include + +#include +#include + +class OCCVIEWER_EXPORT OCCViewer_AISSelector : public QObject +{ + Q_OBJECT + +public: + // constructor + OCCViewer_AISSelector( QObject* parent, const Handle (AIS_InteractiveContext)& ); + // destructor + ~OCCViewer_AISSelector(); + + // enables/disables selection + void enableSelection( bool ); + // enables/disables multiple selection + void enableMultipleSelection( bool ); + + // detects the interactive objects at position (x,y). + bool moveTo ( int, int, const Handle (V3d_View)& ); + // selects the objects covered by the rectangle. + bool select ( int, int, int, int, const Handle (V3d_View)& ); + // adds new selected objects covered by the rectangle to the objects + // previously selected. + bool shiftSelect ( int, int, int, int, const Handle (V3d_View)& ); + // selects the detected interactive objects. + bool select (); + // adds new selected objects to the objects previously selected. + bool shiftSelect (); + + // sets the interactive context for this selector + void setAISContext ( const Handle (AIS_InteractiveContext)& ); + // sets the color to hilight the detected objects + void setHilightColor ( Quantity_NameOfColor color ); + // sets the color to display the selected objects + void setSelectColor ( Quantity_NameOfColor color ); + +protected: + // checks the status of pick and emits 'selSelectionDone' or 'selSelectionCancel'. + bool checkSelection ( AIS_StatusOfPick status, bool hadSelection, bool addTo ); + +signals: + // 'selection done' signal + void selSelectionDone( bool bAdded ); + // 'selection cancelled' signal + void selSelectionCancel( bool bAdded ); + +protected: + Handle (AIS_InteractiveContext) myAISContext; // graphic context + Quantity_NameOfColor myHilightColor; // color for hilight object + Quantity_NameOfColor mySelectColor; // color for selected object + + int myNumSelected; // nymber of selected objects + bool myEnableSelection; // enable selection flag + bool myEnableMultipleSelection; // enable multiple selection flag +}; + +#endif // OCCVIEWER_AISSELECTOR_H diff --git a/src/OCCViewer/OCCViewer_CreateRestoreViewDlg.cxx b/src/OCCViewer/OCCViewer_CreateRestoreViewDlg.cxx new file mode 100755 index 000000000..a79d5f2c7 --- /dev/null +++ b/src/OCCViewer/OCCViewer_CreateRestoreViewDlg.cxx @@ -0,0 +1,242 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "OCCViewer_CreateRestoreViewDlg.h" +#include "OCCViewer_ViewModel.h" +#include "OCCViewer_ViewPort3d.h" + +#include +#include +#include +#include + +OCCViewer_CreateRestoreViewDlg::OCCViewer_CreateRestoreViewDlg( QWidget* aWin, OCCViewer_Viewer* curModel ) +: QDialog( aWin ) +{ + setCaption( tr( "CAPTION" ) ); + + myParametersMap = curModel->getViewAspects(); + + myKeyFlag = 0; + + int aQuantityOfItems = myParametersMap.count(); + + setFixedSize( 400, 300 ); + + QGridLayout* aGrid = new QGridLayout( this, 2, 1, 5, 10 ); + + QWidget* aWidget1 = new QWidget( this ); + QWidget* aWidget2 = new QWidget( this ); + + QHBoxLayout* aLayout = new QHBoxLayout( aWidget1 ); + + myListBox = new QtxListBox( aWidget1 ); + myListBox->installEventFilter( this ); + + myCurViewPort = new OCCViewer_ViewPort3d( aWidget1, curModel->getViewer3d(), V3d_ORTHOGRAPHIC ); + myCurViewPort->getView()->SetBackgroundColor( Quantity_NOC_BLACK ); + + myListBox->setEditEnabled( 1 ); + + if ( aQuantityOfItems ) + { + myListBox->clear(); + for( int i = 0; i < aQuantityOfItems; i++ ) + myListBox->insertItem( myParametersMap[ i ].name ); + + changeImage( myListBox->item( 0 ) ); + } + else + { + myListBox->clear(); + myListBox->insertItem( "No Items", 0 ); + myListBox->setEditEnabled( 0 ); + } + + connect( myListBox, SIGNAL( clicked( QListBoxItem* ) ), this, SLOT( changeImage( QListBoxItem* ) ) ); + connect( myListBox, SIGNAL( itemEdited( QListBoxItem* ) ), this, SLOT( editItemText( QListBoxItem* ) ) ); + + aLayout->addWidget( myListBox ); + aLayout->addWidget( myCurViewPort, 30 ); + + QHBoxLayout* aButtonLayout = new QHBoxLayout( aWidget2, 0, 5 ); + + QPushButton* theOk = new QPushButton( tr( "Ok" ), aWidget2 ); theOk->setAutoDefault( false ); + QPushButton* theCancel = new QPushButton( tr( "Cancel" ), aWidget2 ); theCancel->setAutoDefault( false ); + QPushButton* theDelete = new QPushButton( tr( "Delete" ), aWidget2 ); theDelete->setAutoDefault( false ); + QPushButton* theClearAll = new QPushButton( tr( "Clear List" ), aWidget2 ); theClearAll->setAutoDefault( false ); + + aButtonLayout->addWidget( theOk ); + aButtonLayout->addWidget( theCancel ); + aButtonLayout->addWidget( theDelete ); + aButtonLayout->addWidget( theClearAll ); + + aGrid->addWidget( aWidget1, 0, 0 ); + aGrid->addWidget( aWidget2, 1, 0 ); + + connect( theOk, SIGNAL( clicked() ), this, SLOT( OKpressed() ) ); + connect( theCancel, SIGNAL( clicked() ), this, SLOT( reject() ) ); + connect( theDelete, SIGNAL( clicked() ), this, SLOT( deleteSelectedItems() ) ); + connect( theClearAll, SIGNAL( clicked() ), this, SLOT( clearList() ) ); +} + +OCCViewer_CreateRestoreViewDlg::~OCCViewer_CreateRestoreViewDlg() +{ +} + +void OCCViewer_CreateRestoreViewDlg::changeImage( QListBoxItem* curItem ) +{ + if( curItem && myListBox->isEditEnabled() ) + { + int lowLevel = -1; + int highLevel = -1; + int index = curItem->listBox()->index( curItem ); + if( myKeyFlag == 2 ) + { + for( int i = 0; i < myListBox->count(); i++ ) + { + if( myListBox->isSelected( i ) && i != index ) + { + myListBox->clearSelection(); + if( i > index ) + { + lowLevel = index; + highLevel = i; + } + else + { + lowLevel = i; + highLevel = index; + } + for( int j = lowLevel; j <= highLevel; j++ ) + myListBox->setSelected( j, TRUE ); + break; + } + if( myListBox->isSelected( i ) && i == index ) + myListBox->setSelected( i, TRUE ); + } + } + + Handle(V3d_View) aView3d = myCurViewPort->getView(); + myCurrentItem = myParametersMap[ index ]; + + Standard_Boolean prev = aView3d->SetImmediateUpdate( Standard_False ); + aView3d->SetScale( myCurrentItem.scale ); + aView3d->SetCenter( myCurrentItem.centerX, myCurrentItem.centerY ); + aView3d->SetProj( myCurrentItem.projX, myCurrentItem.projY, myCurrentItem.projZ ); + aView3d->SetTwist( myCurrentItem.twist ); + aView3d->SetAt( myCurrentItem.atX, myCurrentItem.atY, myCurrentItem.atZ ); + aView3d->SetImmediateUpdate( prev ); + aView3d->SetEye( myCurrentItem.eyeX, myCurrentItem.eyeY, myCurrentItem.eyeZ ); + } +} + +viewAspect OCCViewer_CreateRestoreViewDlg::currentItem() const +{ + return myCurrentItem; +} + +void OCCViewer_CreateRestoreViewDlg::deleteSelectedItems() +{ + if( myListBox->count() && myListBox->isEditEnabled() ) + { + int curIndex = -1; + for( int i = 0; i < myListBox->count(); i++ ) + if( myListBox->isSelected( i ) ) + { + myListBox->removeItem( i ); + for( int j = i; j < myParametersMap.count(); j++ ) + if( j != myParametersMap.count() - 1 ) + myParametersMap[ j ] = myParametersMap[ j + 1 ]; + else + myParametersMap.remove( myParametersMap.at(j) ); + if( i != myListBox->count() ) + curIndex = i; + else + curIndex = i - 1; + i--; + } + if( curIndex >= 0 ) + { + myListBox->setCurrentItem( curIndex ); + changeImage( myListBox->item( curIndex ) ); + } + } + if( !myListBox->count() ) + { + myListBox->clear(); + myListBox->insertItem( "No Items", 0 ); + myListBox->setEditEnabled( 0 ); + } +} + +void OCCViewer_CreateRestoreViewDlg::clearList() +{ + myListBox->clear(); + myListBox->insertItem( "No Items", 0 ); + myListBox->setEditEnabled( 0 ); + + myParametersMap.clear(); +} + +const viewAspectList& OCCViewer_CreateRestoreViewDlg::parameters() const +{ + return myParametersMap; +} + +void OCCViewer_CreateRestoreViewDlg::editItemText( QListBoxItem* anItem ) +{ + int index = anItem->listBox()->index( anItem ); + myParametersMap[ index ].name = anItem->text().latin1(); +} + +bool OCCViewer_CreateRestoreViewDlg::eventFilter( QObject* anObj, QEvent* anEv ) +{ + if( anEv->type() == QEvent::KeyPress ) + { + QKeyEvent* aKeyEv = ( QKeyEvent* )anEv; + if( aKeyEv->key() == Qt::Key_Control ) + { + myKeyFlag = 1; + myListBox->setSelectionMode( QListBox::Multi ); + } + else if( aKeyEv->key() == Qt::Key_Shift ) + { + myKeyFlag = 2; + myListBox->setSelectionMode( QListBox::Multi ); + } + else + myListBox->setSelectionMode( QListBox::Single ); + } + if( anEv->type() == QEvent::KeyRelease ) + myKeyFlag = 0; + + if( !myKeyFlag ) + { + if( anEv->type() == QEvent::KeyPress || anEv->type() == QEvent::MouseButtonPress ) + myListBox->setSelectionMode( QListBox::Single ); + } + return QWidget::eventFilter( anObj, anEv ); +} + +void OCCViewer_CreateRestoreViewDlg::OKpressed() +{ + emit dlgOk(); + accept(); +} + diff --git a/src/OCCViewer/OCCViewer_CreateRestoreViewDlg.h b/src/OCCViewer/OCCViewer_CreateRestoreViewDlg.h new file mode 100755 index 000000000..dc6dad1f7 --- /dev/null +++ b/src/OCCViewer/OCCViewer_CreateRestoreViewDlg.h @@ -0,0 +1,77 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef OCCVIEWER_CREATERESTOREVIEWDLG_H +#define OCCVIEWER_CREATERESTOREVIEWDLG_H + +#include "OCCViewer.h" + +#include "OCCViewer_ViewModel.h" +#include "OCCViewer_ViewWindow.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +class OCCViewer_ViewPort3d; + +#ifdef WIN32 +#pragma warning( disable:4251 ) +#endif + +class OCCVIEWER_EXPORT OCCViewer_CreateRestoreViewDlg : public QDialog +{ + Q_OBJECT + +public: + OCCViewer_CreateRestoreViewDlg( QWidget*, OCCViewer_Viewer* ); + virtual ~OCCViewer_CreateRestoreViewDlg(); + + const viewAspectList& parameters() const; + viewAspect currentItem() const; + virtual bool eventFilter( QObject*, QEvent* ); + +public slots: + void OKpressed(); + void clearList(); + void editItemText( QListBoxItem* ); + void changeImage( QListBoxItem* ); + void deleteSelectedItems(); + +signals: + void dlgOk(); + +private: + int myKeyFlag; + QtxListBox* myListBox; + OCCViewer_ViewPort3d* myCurViewPort; + viewAspect myCurrentItem; + viewAspectList myParametersMap; +}; + +#ifdef WIN32 +#pragma warning( default:4251 ) +#endif + +#endif diff --git a/src/OCCViewer/OCCViewer_VService.cxx b/src/OCCViewer/OCCViewer_VService.cxx new file mode 100755 index 000000000..662356c70 --- /dev/null +++ b/src/OCCViewer/OCCViewer_VService.cxx @@ -0,0 +1,323 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +/*********************************************************************** + + FONCTION : + ---------- + Classe OCCViewer_VService : + + HISTORIQUE DES MODIFICATIONS : + -------------------------------- + 00-09-92 : GG ; Creation. + 25-02-98 : FMN ; PERF.27: Optimisation de la création d'une vue à partir d'une vue existante + + REMARQUES : + ----------- + +************************************************************************/ + +/*----------------------------------------------------------------------*/ +/* + * Includes + */ +//just to load the OpenGl shared library +//#include + +#include "OCCViewer_VService.h" +#include +#include +#include + +#include +#include +#include + +#ifdef WNT +#include +#include +#include +#include +#include +#else +#include +#include +#include +#include +#include +#endif + +// For 2d +#define LOPTIM +#ifdef WNT +#ifndef LOPTIM +static Handle(WNT_GraphicDevice) XServiceDefault2dDevice; +static Handle(WNT_GraphicDevice) XServiceImageDevice; +#else +static Handle(WNT_GraphicDevice)& _XServiceDefault2dDevice() { +static Handle(WNT_GraphicDevice) XServiceDefault2dDevice; +return XServiceDefault2dDevice; +} +#define XServiceDefault2dDevice _XServiceDefault2dDevice() + +static Handle(WNT_GraphicDevice)& _XServiceImageDevice() { +static Handle(WNT_GraphicDevice) XServiceImageDevice; +return XServiceImageDevice; +} +#define XServiceImageDevice _XServiceImageDevice() +#endif // LOPTIM +#else +#ifndef LOPTIM +static Handle(Xw_GraphicDevice) XServiceDefault2dDevice; +static Handle(Xw_GraphicDevice) XServiceImageDevice; +#else +static Handle(Xw_GraphicDevice)& _XServiceDefault2dDevice() { +static Handle(Xw_GraphicDevice) XServiceDefault2dDevice; +return XServiceDefault2dDevice; +} +#define XServiceDefault2dDevice _XServiceImageDevice() + +static Handle(Xw_GraphicDevice)& _XServiceImageDevice() { +static Handle(Xw_GraphicDevice) XServiceImageDevice; +return XServiceImageDevice; +} +#define XServiceImageDevice _XServiceImageDevice() +#endif // LOPTIM +#endif // WNT + +/*! + Maps CasCade view to the window [ static ] +*/ +void OCCViewer_VService::SetWindow( const Handle(V3d_View)& view, + const Standard_Integer hiwin, + const Standard_Integer lowin, + const Xw_WindowQuality quality ) +{ +#ifdef WNT + Handle(WNT_Window) w = + new WNT_Window( Handle(Graphic3d_WNTGraphicDevice)::DownCast(view->Viewer()->Device()), hiwin, lowin ); +#else + Handle(Xw_Window) w = + new Xw_Window( Handle(Graphic3d_GraphicDevice)::DownCast(view->Viewer()->Device()), hiwin, lowin, quality ); +#endif + view->SetWindow( w ); +} + +/*! + Magnifies 'view' based on previous view [ static ] +*/ +void OCCViewer_VService::SetMagnify( const Handle(V3d_View)& view, + const Standard_Integer hiwin, + const Standard_Integer lowin, + const Handle(V3d_View)& prevView, + const Standard_Integer x1, + const Standard_Integer y1, + const Standard_Integer x2, + const Standard_Integer y2, + const Xw_WindowQuality aQuality ) +{ +#ifdef WNT + Handle(WNT_Window) w = + new WNT_Window( Handle(Graphic3d_WNTGraphicDevice)::DownCast(view->Viewer()->Device()), hiwin, lowin ); +#else + Handle(Xw_Window) w = + new Xw_Window( Handle(Graphic3d_GraphicDevice)::DownCast(view->Viewer()->Device()), hiwin, lowin, aQuality ); +#endif + view->SetMagnify( w, prevView, x1, y1, x2, y2 ); +} + +/*! + Creates viewer 3d [ static ] +*/ +Handle(V3d_Viewer) OCCViewer_VService::Viewer3d( const Standard_CString aDisplay, + const Standard_ExtString aName, + const Standard_CString aDomain, + const Standard_Real ViewSize , + const V3d_TypeOfOrientation ViewProj, + const Standard_Boolean ComputedMode, + const Standard_Boolean aDefaultComputedMode ) +{ +#ifndef WNT + static Handle(Graphic3d_GraphicDevice) defaultdevice; + if ( defaultdevice.IsNull() ) + defaultdevice = new Graphic3d_GraphicDevice( aDisplay ); + return new V3d_Viewer( defaultdevice, aName, aDomain, ViewSize, ViewProj, + Quantity_NOC_GRAY30, V3d_ZBUFFER, V3d_GOURAUD, V3d_WAIT, + ComputedMode, aDefaultComputedMode, V3d_TEX_NONE ); +#else + static Handle(Graphic3d_WNTGraphicDevice) defaultdevice; + if ( defaultdevice.IsNull() ) + defaultdevice = new Graphic3d_WNTGraphicDevice(); + return new V3d_Viewer( defaultdevice, aName, aDomain, ViewSize, ViewProj, + Quantity_NOC_GRAY30, V3d_ZBUFFER, V3d_GOURAUD, V3d_WAIT, + ComputedMode, aDefaultComputedMode, V3d_TEX_NONE); +#endif // WNT +} + +/*! + Creates view 2D and maps it to the window [ static ] +*/ +/*Handle(V2d_View) OCCViewer_VService::View2d( const Handle(V2d_Viewer)& aViewer, + const Standard_Integer hiwin, + const Standard_Integer lowin, + const Xw_WindowQuality aQuality, + const Standard_Boolean Update, + const Quantity_NameOfColor BackColor ) +{ +#ifdef WNT + Handle(WNT_GraphicDevice) GD = Handle(WNT_GraphicDevice)::DownCast(aViewer->Device()); + Handle(WNT_Window) W = new WNT_Window( GD, hiwin, lowin, BackColor ); + Handle(WNT_WDriver) D = new WNT_WDriver( W ); +#else + Handle(Xw_GraphicDevice) GD = Handle(Xw_GraphicDevice)::DownCast(aViewer->Device()); + Handle(Xw_Window) W = new Xw_Window( GD, hiwin, lowin, aQuality, BackColor ); + Handle(Xw_Driver) D = new Xw_Driver( W ); +#endif + Handle(V2d_View) V = new V2d_View( D, aViewer ); + if ( Update ) + V->Update(); + return V; +}*/ + +/*! + Creates view 2D and maps it to the window [ static ] +*/ +/*Handle(V2d_View) OCCViewer_VService::dpsView2d( const Handle(V2d_Viewer)& aViewer, + const Standard_Integer hiwin, + const Standard_Integer lowin, + const Xw_WindowQuality aQuality, + const Standard_Boolean Update, + const Quantity_NameOfColor BackColor ) +{ +#ifdef WNT + Handle(WNT_GraphicDevice) GD = Handle(WNT_GraphicDevice)::DownCast(aViewer->Device()); + Handle(WNT_Window) W = new WNT_Window( GD, hiwin, lowin, BackColor ); + W->SetBackground( BackColor ); + Handle(WNT_WDriver) D = new WNT_WDriver( W ); +#else + Handle(Xw_GraphicDevice) GD = Handle(Xw_GraphicDevice)::DownCast(aViewer->Device()); + Handle(Xw_Window) W = new Xw_Window( GD, hiwin, lowin, aQuality, BackColor ); + Handle(Xdps_Driver) D = new Xdps_Driver( W ); +#endif + Handle(V2d_View) V = new V2d_View( D, aViewer ); + if ( Update ) + V->Update(); + return V; +}*/ + +/*! + Creates viewer 2D [ static ] +*/ +/*Handle(V2d_Viewer) OCCViewer_VService::Viewer2d( const Standard_CString aDisplay, + const Standard_ExtString aName, + const Standard_CString aDomain ) +{ +#ifdef WNT + if ( XServiceDefault2dDevice.IsNull() ) + XServiceDefault2dDevice = new WNT_GraphicDevice(); +#else + if ( XServiceDefault2dDevice.IsNull() ) + XServiceDefault2dDevice = new Xw_GraphicDevice( aDisplay, Xw_TOM_READONLY ); +#endif + return new V2d_Viewer( XServiceDefault2dDevice, aName, aDomain ); +}*/ + +/*! + Creates viewer 2D [ static ] +*/ +/*Handle(V2d_Viewer) OCCViewer_VService::Viewer2d( const Standard_CString aDisplay, + const Handle(Graphic2d_View)& aView, + const Standard_ExtString aName, + const Standard_CString aDomain ) +{ +#ifdef WNT + if ( XServiceDefault2dDevice.IsNull() ) + XServiceDefault2dDevice = new WNT_GraphicDevice(); +#else + if ( XServiceDefault2dDevice.IsNull() ) + XServiceDefault2dDevice = new Xw_GraphicDevice( aDisplay, Xw_TOM_READONLY ); +#endif + return new V2d_Viewer( XServiceDefault2dDevice, aView, aName, aDomain ); +}*/ + +/*! + Creates window driver [ static ] +*/ +Handle(Aspect_WindowDriver) OCCViewer_VService::WindowDriver( const Standard_CString aDisplay, + const Standard_Integer ahiwin, + const Standard_Integer alowin, + const Quantity_NameOfColor aColor ) +{ +#ifdef WNT + if ( XServiceDefault2dDevice.IsNull() ) + XServiceDefault2dDevice = new WNT_GraphicDevice(); + Handle(WNT_Window) W = new WNT_Window( XServiceDefault2dDevice, ahiwin, alowin, aColor ); + return new WNT_WDriver( W ); +#else + if ( XServiceDefault2dDevice.IsNull() ) + XServiceDefault2dDevice = new Xw_GraphicDevice( aDisplay, Xw_TOM_READONLY ); + Handle(Xw_Window) W = new Xw_Window( XServiceDefault2dDevice, ahiwin, alowin, Xw_WQ_DRAWINGQUALITY , aColor ); + return new Xw_Driver( W ); +#endif +} + +/*! + Creates Xdps window driver [ static ] + On Win32 the same as OCCViewer_VService::WindowDriver() +*/ +Handle(Aspect_WindowDriver) OCCViewer_VService::XdpsDriver( const Standard_CString aDisplay, + const Standard_Integer ahiwin, + const Standard_Integer alowin, + const Quantity_NameOfColor aColor ) +{ +#ifdef WNT + if ( XServiceDefault2dDevice.IsNull() ) + XServiceDefault2dDevice = new WNT_GraphicDevice(); + Handle(WNT_Window) W = new WNT_Window( XServiceDefault2dDevice, ahiwin, alowin, aColor ); + return new WNT_WDriver( W ); +#else + if ( XServiceDefault2dDevice.IsNull() ) + XServiceDefault2dDevice = new Xw_GraphicDevice( aDisplay, Xw_TOM_READONLY ); + Handle(Xw_Window) W = new Xw_Window( XServiceDefault2dDevice, ahiwin, alowin, + Xw_WQ_DRAWINGQUALITY, aColor ); + return new Xdps_Driver( W ); +#endif +} + +/*! + Creates Xw window driver [ static ] + On Win32 the same as OCCViewer_VService::WindowDriver() +*/ +Handle(Aspect_WindowDriver) OCCViewer_VService::ImageDriver( const Standard_CString aDisplay, + const Standard_Integer ahiwin, + const Standard_Integer alowin, + const Quantity_NameOfColor aColor ) +{ +#ifdef WNT + if ( XServiceImageDevice.IsNull() ) + XServiceImageDevice = new WNT_GraphicDevice(); + Handle(WNT_Window) W = new WNT_Window( XServiceImageDevice, ahiwin, alowin, aColor ); + return new WNT_WDriver( W ); +#else + if ( XServiceImageDevice.IsNull() ) + XServiceImageDevice = new Xw_GraphicDevice( aDisplay, Xw_TOM_READONLY ); + Handle(Xw_Window) W = new Xw_Window( XServiceImageDevice, ahiwin, alowin, + Xw_WQ_PICTUREQUALITY, aColor ); + return new Xw_Driver( W ); +#endif +} diff --git a/src/OCCViewer/OCCViewer_VService.h b/src/OCCViewer/OCCViewer_VService.h new file mode 100755 index 000000000..5de36371d --- /dev/null +++ b/src/OCCViewer/OCCViewer_VService.h @@ -0,0 +1,131 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef OCCVIEWER_VSERVICE_H +#define OCCVIEWER_VSERVICE_H + +#ifndef _Handle_V3d_View_HeaderFile +#include +#endif +#ifndef _Standard_Integer_HeaderFile +#include +#endif +#ifndef _Xw_WindowQuality_HeaderFile +#include +#endif +#ifndef _Handle_V3d_Viewer_HeaderFile +#include +#endif +#ifndef _Standard_CString_HeaderFile +#include +#endif +#ifndef _Standard_ExtString_HeaderFile +#include +#endif +#ifndef _Quantity_Length_HeaderFile +#include +#endif +#ifndef _Quantity_NameOfColor_HeaderFile +#include +#endif +#ifndef _V3d_TypeOfOrientation_HeaderFile +#include +#endif +#ifndef _Standard_Boolean_HeaderFile +#include +#endif +#ifndef _Handle_Graphic2d_View_HeaderFile +#include +#endif +#ifndef _Handle_Aspect_WindowDriver_HeaderFile +#include +#endif + +class V3d_View; +class V2d_View; +class V3d_Viewer; +class V2d_Viewer; +class Graphic2d_View; +class Aspect_WindowDriver; + +#ifndef _Standard_HeaderFile +#include +#endif +#ifndef _Standard_Macro_HeaderFile +#include +#endif + +class Standard_EXPORT OCCViewer_VService +{ +public: + inline void* operator new(size_t,void* anAddress) + { + return anAddress; + } + inline void* operator new(size_t size) + { + return Standard::Allocate(size); + } + inline void operator delete(void *anAddress) + { + if ( anAddress ) Standard::Free((Standard_Address&)anAddress); + } + + // STATIC METHODS + static void SetWindow( const Handle( V3d_View )& view, + const Standard_Integer hiwin, + const Standard_Integer lowin, + const Xw_WindowQuality quality = Xw_WQ_3DQUALITY ); + + static void SetMagnify( const Handle( V3d_View)& view, + const Standard_Integer hiwin, + const Standard_Integer lowin, + const Handle( V3d_View)& aPreviousView, + const Standard_Integer x1, + const Standard_Integer y1, + const Standard_Integer x2, + const Standard_Integer y2, + const Xw_WindowQuality quality = Xw_WQ_3DQUALITY ); + static Handle_V3d_Viewer + Viewer3d( const Standard_CString display, + const Standard_ExtString name, + const Standard_CString domain = "", + const Quantity_Length ViewSize = 1000.0, + const V3d_TypeOfOrientation ViewProj = V3d_XposYnegZpos, + const Standard_Boolean ComputedMode = Standard_True, + const Standard_Boolean DefaultComputedMode = Standard_True ); + + static Handle_Aspect_WindowDriver + WindowDriver( const Standard_CString display, + const Standard_Integer hiwin, + const Standard_Integer lowin, + const Quantity_NameOfColor color = Quantity_NOC_GRAY69 ); + static Handle_Aspect_WindowDriver + XdpsDriver( const Standard_CString display, + const Standard_Integer hiwin, + const Standard_Integer lowin, + const Quantity_NameOfColor color = Quantity_NOC_GRAY69 ); + static Handle_Aspect_WindowDriver + ImageDriver( const Standard_CString display, + const Standard_Integer hiwin, + const Standard_Integer lowin, + const Quantity_NameOfColor color = Quantity_NOC_GRAY69 ); + +}; + +#endif diff --git a/src/OCCViewer/OCCViewer_ViewManager.cxx b/src/OCCViewer/OCCViewer_ViewManager.cxx new file mode 100755 index 000000000..dedfc4a0d --- /dev/null +++ b/src/OCCViewer/OCCViewer_ViewManager.cxx @@ -0,0 +1,51 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "OCCViewer_ViewManager.h" +#include "OCCViewer_ViewWindow.h" +#include "SUIT_Desktop.h" + +int OCCViewer_ViewManager::myMaxId = 0; + +//***************************************************************/ +OCCViewer_ViewManager::OCCViewer_ViewManager( SUIT_Study* study, SUIT_Desktop* theDesktop, bool DisplayTrihedron ) +: SUIT_ViewManager( study, theDesktop ) +{ + myId = ++myMaxId; + setViewModel( new OCCViewer_Viewer( DisplayTrihedron ) ); +} + +//***************************************************************/ +OCCViewer_ViewManager::~OCCViewer_ViewManager() +{ +} + +//***************************************************************/ +void OCCViewer_ViewManager::setViewName(SUIT_ViewWindow* theView) +{ + int aPos = myViews.find(theView); + theView->setCaption( tr( "OCC_VIEW_TITLE" ).arg( myId ).arg( aPos + 1 ) ); +} + +//***************************************************************/ +void OCCViewer_ViewManager::contextMenuPopup( QPopupMenu* popup ) +{ + SUIT_ViewManager::contextMenuPopup( popup ); + // if it is necessary invoke method CreatePopup of ViewPort + // be sure that existing QPopupMenu menu is used for that. +} diff --git a/src/OCCViewer/OCCViewer_ViewManager.h b/src/OCCViewer/OCCViewer_ViewManager.h new file mode 100755 index 000000000..71e9bf2db --- /dev/null +++ b/src/OCCViewer/OCCViewer_ViewManager.h @@ -0,0 +1,48 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef OCCVIEWER_VIEWMANAGER_H +#define OCCVIEWER_VIEWMANAGER_H + +#include "OCCViewer_ViewModel.h" + +#include "SUIT_ViewManager.h" + +class SUIT_Desktop; + +class OCCVIEWER_EXPORT OCCViewer_ViewManager : public SUIT_ViewManager +{ + Q_OBJECT + +public: + OCCViewer_ViewManager( SUIT_Study* study, SUIT_Desktop* theDesktop, bool DisplayTrihedron = true ); + ~OCCViewer_ViewManager(); + + OCCViewer_Viewer* getOCCViewer() { return (OCCViewer_Viewer*) myViewModel; } + + virtual void contextMenuPopup( QPopupMenu* ); + +protected: + void setViewName(SUIT_ViewWindow* theView); + +protected: + static int myMaxId; + int myId; +}; + +#endif diff --git a/src/OCCViewer/OCCViewer_ViewModel.h b/src/OCCViewer/OCCViewer_ViewModel.h new file mode 100755 index 000000000..0779d3aef --- /dev/null +++ b/src/OCCViewer/OCCViewer_ViewModel.h @@ -0,0 +1,175 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef OCCVIEWER_VIEWMODEL_H +#define OCCVIEWER_VIEWMODEL_H + +#include +#include + +#include "OCCViewer.h" + +#include "SUIT_ViewModel.h" + +#include +#include +#include +#include + +class SUIT_ViewWindow; +class SUIT_Desktop; +class OCCViewer_ViewWindow; + +struct viewAspect +{ +public: + double scale; + double centerX; + double centerY; + double projX; + double projY; + double projZ; + double twist; + double atX; + double atY; + double atZ; + double eyeX; + double eyeY; + double eyeZ; + QString name; +}; + +typedef QValueList viewAspectList; + +#ifdef WIN32 +#pragma warning( disable:4251 ) +#endif + +class OCCVIEWER_EXPORT OCCViewer_Viewer: public SUIT_ViewModel +{ + Q_OBJECT + +public: + static QString Type() { return "OCCViewer"; } + + OCCViewer_Viewer( bool DisplayTrihedron = true ); + virtual ~OCCViewer_Viewer(); + + void update(); + + virtual SUIT_ViewWindow* createView(SUIT_Desktop* theDesktop); + + virtual void setViewManager(SUIT_ViewManager* theViewManager); + virtual QString getType() const { return Type(); } + + virtual void contextMenuPopup(QPopupMenu*); + + void getSelectedObjects(AIS_ListOfInteractive& theList); + void setObjectsSelected(const AIS_ListOfInteractive& theList); + void setSelected(const Handle(AIS_InteractiveObject)& theIO) + { myAISContext->SetSelected(theIO);} + + void performSelectionChanged(); + // emit signal selectionChanged + + virtual const viewAspectList& getViewAspects(); + virtual void appendViewAspect( const viewAspect& ); + virtual void updateViewAspects( const viewAspectList& ); + virtual void clearViewAspects(); + + QColor backgroundColor() const; + void setBackgroundColor( const QColor& ); + + //! returns true if 3d Trihedron in viewer was created + bool trihedronActivated() const { return !myTrihedron.IsNull(); } + + void toggleTrihedron(); + bool isTrihedronVisible() const; + virtual void setTrihedronShown( const bool ); + + int trihedronSize() const; + virtual void setTrihedronSize( const int ); + +public slots: + void onClearViewAspects(); + +public: + Handle(V3d_Viewer) getViewer3d() const { return myV3dViewer;} + Handle(V3d_Viewer) getCollector3d() const { return myV3dCollector; } + Handle(AIS_InteractiveContext) getAISContext() const { return myAISContext; } + Handle(AIS_Trihedron) getTrihedron() const { return myTrihedron; } + + void enableSelection(bool isEnabled); + bool isSelectionEnabled() const + { return mySelectionEnabled; } + + void enableMultiselection(bool isEnable); + bool isMultiSelectionEnabled() const + { return myMultiSelectionEnabled; } + + int getSelectionCount() const + { return (!myAISContext.IsNull())? myAISContext->NbSelected():0; } + + /* Selection management */ + bool highlight( const Handle(AIS_InteractiveObject)&, bool, bool=true ); + bool unHighlightAll( bool=true ); + bool isInViewer( const Handle(AIS_InteractiveObject)&, bool=false ); + bool isVisible( const Handle(AIS_InteractiveObject)& ); + + void setColor( const Handle(AIS_InteractiveObject)&, const QColor&, bool=true ); + void switchRepresentation( const Handle(AIS_InteractiveObject)&, int, bool=true ); + void setTransparency( const Handle(AIS_InteractiveObject)&, float, bool=true ); + void setIsos( const int u, const int v ); // number of isolines + void isos( int& u, int& v ) const; + +signals: + void selectionChanged(); + +protected: + void initView( OCCViewer_ViewWindow* view ); + +protected slots: + void onMousePress(SUIT_ViewWindow*, QMouseEvent*); + void onMouseMove(SUIT_ViewWindow*, QMouseEvent*); + void onMouseRelease(SUIT_ViewWindow*, QMouseEvent*); + + void onDumpView(); + void onShowToolbar(); + void onChangeBgColor(); + +private: + Handle(V3d_Viewer) myV3dViewer; + Handle(V3d_Viewer) myV3dCollector; + + Handle(AIS_Trihedron) myTrihedron; + Handle(AIS_InteractiveContext) myAISContext; + + viewAspectList myViewAspects; + + bool mySelectionEnabled; + bool myMultiSelectionEnabled; + + QColor myBgColor; + QPoint myStartPnt, myEndPnt; +}; + +#ifdef WIN32 +#pragma warning( default:4251 ) +#endif + +#endif diff --git a/src/OCCViewer/OCCViewer_ViewPort.cxx b/src/OCCViewer/OCCViewer_ViewPort.cxx new file mode 100755 index 000000000..72f2fc5f3 --- /dev/null +++ b/src/OCCViewer/OCCViewer_ViewPort.cxx @@ -0,0 +1,480 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +/*************************************************************************** +** Class: OCCViewer_ViewPort +** Descr: Visualisation canvas of SUIT-based application +** Module: SUIT +** Created: UI team, 05.09.00 +****************************************************************************/ +#if !defined WNT +#define QT_CLEAN_NAMESPACE /* avoid definition of INT32 and INT8 */ +#endif + +#include "OCCViewer_ViewPort.h" + +#include "SUIT_Session.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +#if !defined WNT +#include +#include +#include +#include +#include +#undef QT_CLEAN_NAMESPACE +#include +#include + +struct CMapEntry +{ + CMapEntry(); + ~CMapEntry(); + Colormap cmap; + bool alloc; + XStandardColormap scmap; +}; + +CMapEntry::CMapEntry() +{ + cmap = 0; + alloc = false; + scmap.colormap = 0; +} + +CMapEntry::~CMapEntry() +{ + if ( alloc ) + XFreeColormap( QPaintDevice::x11AppDisplay(), cmap ); +} + +static QIntDict *cmap_dict = 0; +static bool mesa_gl = false; + +static void cleanup_cmaps() +{ + if ( !cmap_dict ) + return; + cmap_dict->setAutoDelete( true ); + delete cmap_dict; + cmap_dict = 0; +} + +static Colormap choose_cmap( Display *dpy, XVisualInfo *vi ) +{ + if ( !cmap_dict ) + { + cmap_dict = new QIntDict; + const char *v = glXQueryServerString( dpy, vi->screen, GLX_VERSION ); + mesa_gl = strstr( v,"Mesa" ) != 0; + qAddPostRoutine( cleanup_cmaps ); + } + + CMapEntry *x = cmap_dict->find( (long)vi->visualid ); + if ( x ) // found colormap for visual + return x->cmap; + + x = new CMapEntry(); + + XStandardColormap *c; + int n, i; + +#ifdef DEBUG + cout << "Choosing cmap for vID = " << vi->visualid << endl; +#endif + + if ( vi->visualid == XVisualIDFromVisual( (Visual*)QPaintDevice::x11AppVisual() ) ) + { +#ifdef DEBUG + cout << "Using x11AppColormap" << endl; +#endif + return QPaintDevice::x11AppColormap(); + } + + if ( mesa_gl ) + { + Atom hp_cmaps = XInternAtom( dpy, "_HP_RGB_SMOOTH_MAP_LIST", true ); + if ( hp_cmaps && vi->visual->c_class == TrueColor && vi->depth == 8 ) + { + if ( XGetRGBColormaps( dpy, RootWindow( dpy, vi->screen ), &c, &n, hp_cmaps ) ) + { + i = 0; + while ( i < n && x->cmap == 0 ) + { + if ( c[i].visualid == vi->visual->visualid ) + { + x->cmap = c[i].colormap; + x->scmap = c[i]; + } + i++; + } + XFree( (char*)c ); + } + } + } +#if !defined( _OS_SOLARIS_ ) + if ( !x->cmap ) + { + if ( XmuLookupStandardColormap( dpy, vi->screen, vi->visualid, vi->depth, XA_RGB_DEFAULT_MAP, false, true ) ) + { + if ( XGetRGBColormaps( dpy, RootWindow( dpy, vi->screen ), &c, &n, XA_RGB_DEFAULT_MAP ) ) + { + i = 0; + while ( i < n && x->cmap == 0 ) + { + if ( c[i].visualid == vi->visualid ) + { + x->cmap = c[i].colormap; + x->scmap = c[i]; + } + i++; + } + XFree( (char *)c ); + } + } + } +#endif + if ( !x->cmap ) + { + // no shared cmap found + x->cmap = XCreateColormap( dpy, RootWindow( dpy, vi->screen ), vi->visual, AllocNone ); + x->alloc = true; + } + + cmap_dict->insert( (long)vi->visualid, x ); // associate cmap with visualid + return x->cmap; +} +#endif + + +/*! + Constructor +*/ +OCCViewer_ViewPort::OCCViewer_ViewPort( QWidget* parent ) +: QWidget( parent, 0, WRepaintNoErase | WResizeNoErase ) +{ + initialize(); +} + +/*! + Destructor +*/ +OCCViewer_ViewPort::~OCCViewer_ViewPort() +{ + cleanup(); +} + +/*! + Initializes viewport. [ private ] +*/ +void OCCViewer_ViewPort::initialize() +{ + myPopupActions.setAutoDelete( true ); + myPaintersRedrawing = false; + myEnableSketching = false; + myEnableTransform = true; + + setMouseTracking( true ); + setBackgroundMode( NoBackground ); + // set focus policy to threat QContextMenuEvent from keyboard + setFocusPolicy( StrongFocus ); +} + +/*! + Cleans up the viewport. [ private ] +*/ +void OCCViewer_ViewPort::cleanup() +{ +} + +/*! + Selects visual ID for OpenGL window ( X11 specific ). [ protected ] +*/ +void OCCViewer_ViewPort::selectVisualId() +{ +#if !defined WNT + XVisualInfo* pVisualInfo; + if ( x11Display() ) + { + /* Initialization with the default VisualID */ + Visual *v = DefaultVisual( x11Display(), DefaultScreen( x11Display() ) ); + int visualID = XVisualIDFromVisual( v ); + + /* Here we use the settings from Optimizer_ViewInfo::TxglCreateWindow() */ + int visualAttr[] = { GLX_RGBA, GLX_DEPTH_SIZE, 1, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, None }; + + pVisualInfo = ::glXChooseVisual( x11Display(), DefaultScreen( x11Display() ), visualAttr ); + + if ( isVisible() ) + hide(); + + XSetWindowAttributes a; + + a.colormap = choose_cmap( x11Display(), pVisualInfo ); /* find best colormap */ + a.background_pixel = backgroundColor().pixel(); + a.border_pixel = black.pixel(); + Window p = RootWindow( x11Display(), DefaultScreen( x11Display() ) ); + if ( parentWidget() ) + p = parentWidget()->winId(); + + Window w; + /* if ( type == Type2D ) // creating simple X window for 2d + { + unsigned long xbackground = + BlackPixel( x11Display(), DefaultScreen( x11Display() ) ); + unsigned long xforeground = + WhitePixel( x11Display(), DefaultScreen( x11Display() ) ); + + w = XCreateSimpleWindow ( x11Display(), p, x(), y(), width(), + height(), 0, xforeground, xbackground ); + } + else if ( type == Type3D ) + { + w = XCreateWindow( x11Display(), p, x(), y(), width(), height(), + 0, pVisualInfo->depth, InputOutput, pVisualInfo->visual, + CWBackPixel | CWBorderPixel | CWColormap, &a ); + } + else + return;*/ + w = XCreateWindow( x11Display(), p, x(), y(), width(), height(), + 0, pVisualInfo->depth, InputOutput, pVisualInfo->visual, + CWBackPixel | CWBorderPixel | CWColormap, &a ); + + Window *cmw; + Window *cmwret; + int count; + if ( XGetWMColormapWindows( x11Display(), topLevelWidget()->winId(), &cmwret, &count ) ) + { + cmw = new Window[count+1]; + memcpy( (char*)cmw, (char*)cmwret, sizeof(Window) * count ); + XFree( (char*)cmwret ); + int i; + + for ( i = 0; i < count; i++ ) + { + if ( cmw[i] == winId() ) /* replace old window */ + { + cmw[i] = w; + break; + } + } + + if ( i >= count ) /* append new window */ + cmw[count++] = w; + } + else + { + count = 1; + cmw = new Window[count]; + cmw[0] = w; + } + + /* Creating new window (with good VisualID) for this widget */ + create(w); + XSetWMColormapWindows( x11Display(), topLevelWidget()->winId(), cmw, count ); + delete[] cmw; + + if ( isVisible() ) + show(); + + if ( pVisualInfo ) + { + XFree( (char *)pVisualInfo ); + } + XFlush( x11Display() ); + } +#endif +} + +/*! + Sets the background 'color'. [ virtual ] +*/ +void OCCViewer_ViewPort::setBackgroundColor( const QColor& color ) +{ + QPalette pal = palette(); + pal.setColor( QColorGroup::Background, color ); + setPalette( pal ); + repaint(); + emit vpChangeBGColor( color ); +} + +/*! + Returns the background color. [ virtual ] +*/ +QColor OCCViewer_ViewPort::backgroundColor() const +{ + return palette().active().background(); +} + +/*! + Returns 'true' if sketching is enabled in this viewport. [ public ] +*/ +bool OCCViewer_ViewPort::isSketchingEnabled() const +{ + return myEnableSketching; +} + +/*! + Enables / disables sketching [ public ] +*/ +void OCCViewer_ViewPort::setSketchingEnabled( bool enable ) +{ + myEnableSketching = enable; +} + +/*! + Returns 'true' if transformations ( rotation, zoom etc. ) + are enabled in this viewport. [ public ] +*/ +bool OCCViewer_ViewPort::isTransformEnabled() const +{ + return myEnableTransform; +} + +/*! + Enables / disables transformations. [ public ] +*/ +void OCCViewer_ViewPort::setTransformEnabled( bool enable ) +{ + myEnableTransform = enable; +} + +/*! + Emits 'mouseEvent' signal. [ virtual protected ] +*/ +void OCCViewer_ViewPort::mousePressEvent( QMouseEvent *e ) +{ + emit vpMouseEvent( e ); +} + +/*! + Emits 'mouseEvent' signal. [ virtual protected ] +*/ +void OCCViewer_ViewPort::mouseMoveEvent( QMouseEvent* e ) +{ + emit vpMouseEvent( e ); +} + +/*! + Emits 'mouseEvent' signal. [ virtual protected ] +*/ +void OCCViewer_ViewPort::mouseReleaseEvent( QMouseEvent *e ) +{ + emit vpMouseEvent( e ); +} + +/*! + Emits 'mouseEvent' signal. [ virtual protected ] +*/ +void OCCViewer_ViewPort::mouseDoubleClickEvent( QMouseEvent *e ) +{ + emit vpMouseEvent( e ); +} + +/*! + Emits 'keyEvent' signal. [ virtual protected ] +*/ +void OCCViewer_ViewPort::keyPressEvent( QKeyEvent *e ) +{ + emit vpKeyEvent( e ); +} + +/*! + Emits 'keyEvent' signal. [ virtual protected ] +*/ +void OCCViewer_ViewPort::keyReleaseEvent( QKeyEvent *e ) +{ + emit vpKeyEvent( e ); +} + +/*! + Repaints the viewport. [ virtual protected ] +*/ +void OCCViewer_ViewPort::paintEvent( QPaintEvent* ) +{ + if ( myPaintersRedrawing ) + { + QPainter p( this ); + emit vpDrawExternal( &p ); + myPaintersRedrawing = false; + } +} + +/*! + Forces to redraw the viewport by an external painter. [ public ] +*/ +void OCCViewer_ViewPort::redrawPainters() +{ + myPaintersRedrawing = true; + repaint(); +} + +/*! + Updates this view. Does nothing by default. [ virtual public ] +*/ +void OCCViewer_ViewPort::onUpdate() +{ +} + +/*! + Creates the popup. [ virtual protected ] +*/ +/*void OCCViewer_ViewPort::onCreatePopup( QPopupMenu* popup ) +{ + if ( popup ) + { + QtxAction* a = new QtxAction( "", tr( "MEN_VP_CHANGEBGR" ), 0, this ); + a->setStatusTip( tr( "PRP_VP_CHANGEBGR" ) ); + connect( a, SIGNAL( activated() ), SLOT( onChangeBgColor())); + myPopupActions.append( a ); + a->addTo( popup ); + } +}*/ + +/*! + Destroys the popup. [ virtual protected ] +*/ +/*void OCCViewer_ViewPort::onDestroyPopup( QPopupMenu* popup ) +{ + if ( popup ) + { + for ( QtxAction* a = myPopupActions.first(); a; a = myPopupActions.next() ) + a->removeFrom( popup ); + myPopupActions.clear(); + } +}*/ + +/*! + Sets the background color with color selection dialog. [ virtual protected slot ] +*/ +void OCCViewer_ViewPort::onChangeBgColor() +{ + QColor selColor = QColorDialog::getColor ( backgroundColor(), this ); + if ( selColor.isValid() ) + setBackgroundColor( selColor ); +} diff --git a/src/OCCViewer/OCCViewer_ViewPort.h b/src/OCCViewer/OCCViewer_ViewPort.h new file mode 100755 index 000000000..5c60ad502 --- /dev/null +++ b/src/OCCViewer/OCCViewer_ViewPort.h @@ -0,0 +1,110 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef OCCVIEWER_VIEWPORT_H +#define OCCVIEWER_VIEWPORT_H + +#include "OCCViewer.h" + +#include "QtxAction.h" + +#include +#include +#include + +#include + +class QRect; +class QCursor; +class QPainter; +class OCCViewer_ViewSketcher; +class OCCViewer_ViewTransformer; + +class OCCVIEWER_EXPORT OCCViewer_ViewPort : public QWidget +{ + Q_OBJECT + + friend class OCCViewer_ViewSketcher; + +public: + OCCViewer_ViewPort( QWidget* parent ); + virtual ~OCCViewer_ViewPort(); + +public: + void setSketchingEnabled( bool ); + bool isSketchingEnabled() const; + void setTransformEnabled( bool ); + bool isTransformEnabled() const; + + virtual QColor backgroundColor() const; + virtual void setBackgroundColor( const QColor& ); + + void redrawPainters(); + + virtual void onUpdate(); + +protected: +// enum ViewType { Type2D, Type3D }; + void selectVisualId(); + +// EVENTS + virtual void paintEvent( QPaintEvent *); + virtual void mouseMoveEvent( QMouseEvent *); + virtual void mouseReleaseEvent( QMouseEvent *); + virtual void mousePressEvent( QMouseEvent *); + virtual void mouseDoubleClickEvent( QMouseEvent *); + virtual void keyPressEvent( QKeyEvent *); + virtual void keyReleaseEvent( QKeyEvent *); + +// TO BE REDEFINED + virtual void reset() = 0; + virtual void pan( int, int ) = 0; + virtual void setCenter( int, int ) = 0; + virtual void fitRect( const QRect& ) = 0; + virtual void zoom( int, int, int, int ) = 0; + virtual void fitAll( bool keepScale = false, bool withZ = true, bool upd = true ) = 0; + +// POPUP +// void onCreatePopup( QPopupMenu* ); +// void onDestroyPopup( QPopupMenu* ); + +protected slots: + virtual void onChangeBgColor(); + +signals: + void vpKeyEvent( QKeyEvent* ); + void vpMouseEvent( QMouseEvent* ); + void vpDrawExternal( QPainter* ); + void vpChangeBGColor( QColor ); + +private: + void initialize(); + void cleanup(); + +protected: + Handle(Aspect_Window) myWindow; + bool myEnableSketching; + bool myEnableTransform; + bool myPaintersRedrawing; /* set to draw externally */ + QPtrList myPopupActions; + +private: + static int nCounter; /* objects counter */ +}; + +#endif diff --git a/src/OCCViewer/OCCViewer_ViewPort3d.cxx b/src/OCCViewer/OCCViewer_ViewPort3d.cxx new file mode 100755 index 000000000..badfe3cf3 --- /dev/null +++ b/src/OCCViewer/OCCViewer_ViewPort3d.cxx @@ -0,0 +1,461 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +/*************************************************************************** +** Class: OCCViewer_ViewPort3D +** Descr: Visualisation canvas with CasCade 3D view +** Module: OCCViewer +** Created: UI team, 05.09.00 +****************************************************************************/ + +#include "OCCViewer_ViewPort3d.h" + +#include "OCCViewer_VService.h" + +#include +#include +#include + +#include +#include +#include + +#if defined WNT +#include +#else +#include +#endif + +/*! + Constructor +*/ +OCCViewer_ViewPort3d::OCCViewer_ViewPort3d( QWidget* parent, const Handle( V3d_Viewer)& viewer, V3d_TypeOfView type ) +: OCCViewer_ViewPort( parent ), +myScale( 1.0 ), +myDegenerated( true ), +myAnimate( false ) +{ + selectVisualId(); + + if ( type == V3d_ORTHOGRAPHIC ) { + myOrthoView = new V3d_OrthographicView( viewer ); + myActiveView = myOrthoView; + myPerspView = 0; + } else { + myPerspView = new V3d_PerspectiveView( viewer ); + myActiveView = myPerspView; + } + if ( myDegenerated ) + activeView()->SetDegenerateModeOn(); +} + +/*! + Destructor +*/ +OCCViewer_ViewPort3d::~OCCViewer_ViewPort3d() +{ + Handle(V3d_View) aView = activeView(); + if (!aView.IsNull()) + aView->Remove(); +} + +/*! + Activates the desired 'type' of view in the viewer + ( view of 'type' is created if it doesn't exist ). [ public ] +*/ +/*void OCCViewer_ViewPort3d::setActive( V3d_TypeOfView type ) +{ + if ( activeView().IsNull() ) + return; + + if ( activeView()->Type() != type ) + { + if ( type == V3d_ORTHOGRAPHIC ) + setView( myOrthoView ); + if ( type == V3d_PERSPECTIVE ) + setView( myPerspView ); + } +}*/ + +/*! + Maps CasCade 'view' to this viewport. [ private ] +*/ +bool OCCViewer_ViewPort3d::mapView( const Handle(V3d_View)& view ) +{ + if ( !setWindow( view ) ) + return false; + + if ( !mapped( view ) ) + { + view->SetWindow( myWindow ); + if ( view != activeView() ) + view->View()->Deactivate(); + } + return true; +} + +/*! + Sets new CASCADE view on viewport. Returns the previous active view. [ public ] +*/ +Handle( V3d_View ) OCCViewer_ViewPort3d::setView( const Handle( V3d_View )& view ) +{ + /* map the new view */ + if ( view == activeView() || !mapView( view ) ) + return activeView(); + + /* activate the new view*/ + Handle( V3d_View ) oldView = activeView(); + if ( !oldView.IsNull() ) + { + oldView->View()->Deactivate(); + view->SetBackgroundColor( oldView->BackgroundColor() ); + } + if ( myDegenerated ) + view->SetDegenerateModeOn(); + else + view->SetDegenerateModeOff(); + + view->View()->Activate(); + activeView() = view; + return oldView; +} + +/*! + Returns CasCade 3D view. [ public ] +*/ +Handle(V3d_View) OCCViewer_ViewPort3d::getView() const +{ + return activeView(); +} + +/*! + Returns CasCade 3D viewer [ public ] +*/ +Handle(V3d_Viewer) OCCViewer_ViewPort3d::getViewer() const +{ + Handle(V3d_Viewer) viewer; + if ( !activeView().IsNull() ) + viewer = activeView()->Viewer(); + return viewer; +} + +/*! + Syncronizes visual state of this viewport with 'ref' + ( scale, projection, eye etc ) Returns 'true' if copied OK, + 'false' otherwise. [ virtual public ] +*/ +bool OCCViewer_ViewPort3d::syncronize( const OCCViewer_ViewPort3d* ref ) +{ + OCCViewer_ViewPort3d* ref3d = (OCCViewer_ViewPort3d*)ref; + Handle(V3d_View) refView = ref3d->getView(); + Handle(V3d_View) tgtView = getView(); + + /* Syncronize view types */ +/* if ( tgtView->Type() != refView->Type() ) + { + setActive( refView->Type() ); + tgtView = getView(); + }*/ + + /* The following params are copied: + - view type( ortho/persp ) + - position of view point + - orientation of high point + - position of the eye + - projection vector + - view center ( 2D ) + - view twist + - view scale + */ + + /* we'll update after setting all params */ + tgtView->SetImmediateUpdate( Standard_False ); + + /* perspective */ + if ( refView->Type() == V3d_PERSPECTIVE ) + tgtView->SetFocale( refView->Focale() ); + + /* copy params */ + Standard_Real x, y, z; + refView->At( x, y, z ); tgtView->SetAt( x, y, z ); + refView->Up( x, y, z ); tgtView->SetUp( x, y, z ); + refView->Eye( x, y, z ); tgtView->SetEye( x, y, z ); + refView->Proj( x, y, z ); tgtView->SetProj( x, y, z ); + refView->Center( x, y ); tgtView->SetCenter( x, y ); + tgtView->SetScale( refView->Scale() ); + tgtView->SetTwist( refView->Twist() ); + + /* update */ + tgtView->Update(); + tgtView->SetImmediateUpdate( Standard_True ); + return true; +} + +/*! + Returns Z-size of this view. [ public ] +*/ +double OCCViewer_ViewPort3d::getZSize() const +{ + if ( !activeView().IsNull() ) + return activeView()->ZSize(); + return 0; +} + +/*! + Sets Z-size of this view ( for both orthographic and perspective ). [ public ] +*/ +void OCCViewer_ViewPort3d::setZSize( double zsize ) +{ + myActiveView->SetZSize( zsize ); +/* if ( !myOrthoView.IsNull() ) + myOrthoView->SetZSize( zsize ); + if ( !myPerspView.IsNull() ) + myPerspView->SetZSize( zsize );*/ +} + +/*! + Returns the background color [ virtual public ] +*/ +QColor OCCViewer_ViewPort3d::backgroundColor() const +{ + if ( !activeView().IsNull() ) + { + Standard_Real aRed, aGreen, aBlue; + activeView()->BackgroundColor( Quantity_TOC_RGB, aRed, aGreen, aBlue ); + int red = (int) (aRed * 255); + int green = (int) (aGreen * 255); + int blue = (int) (aBlue * 255); + return QColor( red, green, blue ); + } + return OCCViewer_ViewPort::backgroundColor(); +} + +/*! + Sets the background color [ virtual public ] +*/ +void OCCViewer_ViewPort3d::setBackgroundColor( const QColor& color ) +{ + if ( !activeView().IsNull() ) + { + activeView()->SetBackgroundColor( Quantity_TOC_RGB, color.red()/255., + color.green()/255., color.blue()/255.); + activeView()->Update(); + emit vpChangeBGColor( color ); + } +} + +void OCCViewer_ViewPort3d::setAnimationMode(bool theDegenerated) +{ + if ( !activeView().IsNull() ) + { + myAnimate = theDegenerated; + activeView()->SetAnimationMode(true, theDegenerated); + } +} + +/*! + Updates the active viewport. [ virtual public ] +*/ +void OCCViewer_ViewPort3d::onUpdate() +{ + if ( !activeView().IsNull() ) + activeView()->Update(); +} + +/*! + Called at 'window fit' transformation. [ virtual protected ] +*/ +void OCCViewer_ViewPort3d::fitRect( const QRect& rect ) +{ + if ( !activeView().IsNull() ) + activeView()->WindowFit( rect.left(), rect.top(), rect.right(), rect.bottom() ); +} + +/*! + Called at 'zoom' transformation. [ virtual protected ] +*/ +void OCCViewer_ViewPort3d::zoom( int x0, int y0, int x, int y ) +{ + if ( !activeView().IsNull() ) + activeView()->Zoom( x0, y0, x, y ); +} + +/*! + Centers the viewport. [ virtual protected ] +*/ +void OCCViewer_ViewPort3d::setCenter( int x, int y ) +{ + if ( !activeView().IsNull() ) + activeView()->Place( x, y, myScale ); +} + +/*! + Called at 'pan' transformation. [ virtual protected ] +*/ +void OCCViewer_ViewPort3d::pan( int dx, int dy ) +{ + if ( !activeView().IsNull() ) + activeView()->Pan( dx, dy, 1.0 ); +} + +/*! + Inits 'rotation' transformation. [ protected ] +*/ +void OCCViewer_ViewPort3d::startRotation( int x, int y ) +{ + if ( !activeView().IsNull() ) + { + myDegenerated = activeView()->DegenerateModeIsOn(); + activeView()->SetDegenerateModeOn(); + if (myAnimate) activeView()->SetAnimationModeOn(); + activeView()->StartRotation( x, y, 0.45 ); + } +} + +/*! + Rotates the viewport. [ protected ] +*/ +void OCCViewer_ViewPort3d::rotate( int x, int y ) +{ + if ( !activeView().IsNull() ) + activeView()->Rotation( x, y ); +// setZSize( getZSize() ); +} + +/*! + Resets the viewport after 'rotation'. [ protected ] +*/ +void OCCViewer_ViewPort3d::endRotation() +{ + if ( !activeView().IsNull() ) + { + if (myAnimate) activeView()->SetAnimationModeOff(); + if ( !myDegenerated ) + activeView()->SetDegenerateModeOff(); + activeView()->ZFitAll(1.); + } +} + +/*! + Repaints the viewport. [ virtual protected ] +*/ +void OCCViewer_ViewPort3d::paintEvent( QPaintEvent* e ) +{ +#ifndef WNT + /* X11 : map before show doesn't work */ + if ( !mapped( activeView() ) ) + mapView( activeView() ); +#endif + if ( !myWindow.IsNull() ) + { + QApplication::syncX(); + QRect rc = e->rect(); + if ( !myPaintersRedrawing ) + activeView()->Redraw( rc.x(), rc.y(), rc.width(), rc.height() ); + } + OCCViewer_ViewPort::paintEvent( e ); +} + +/*! + Resizes the viewport. [ virtual protected ] +*/ +void OCCViewer_ViewPort3d::resizeEvent( QResizeEvent* e ) +{ +#ifdef WNT + /* Win32 : map before first show to avoid flicker */ + if ( !mapped( activeView() ) ) + mapView( activeView() ); +#endif + QApplication::syncX(); + if ( !activeView().IsNull() ) + activeView()->MustBeResized(); +} + +/*! + Fits all objects in view. [ virtual protected ] +*/ +void OCCViewer_ViewPort3d::fitAll( bool keepScale, bool withZ, bool upd ) +{ + if ( activeView().IsNull() ) + return; + + + if ( keepScale ) + myScale = activeView()->Scale(); + + Standard_Real margin = 0.01; + activeView()->FitAll( margin, withZ, upd ); +} + +/*! + Resets the view. [ virtual protected ] +*/ +void OCCViewer_ViewPort3d::reset() +{ +// double zsize = getZSize(); + if ( !activeView().IsNull() ) + activeView()->Reset(); +// setZSize( zsize ); +} + +/*! + Passed the handle of native window of the component to CASCADE view. [ private ] +*/ +bool OCCViewer_ViewPort3d::setWindow( const Handle(V3d_View)& view ) +{ + if ( !myWindow.IsNull() ) + return true; + + if ( view.IsNull() ) + return false; + + int hwnd = (int)winId(); + if ( !hwnd ) + return false; + + /* set this widget as the drawing window */ + short lo = (short)hwnd; + short hi = (short)( hwnd >> 16 ); + OCCViewer_VService::SetWindow( view, (int)hi, (int)lo, Xw_WQ_SAMEQUALITY ); + myWindow = view->Window(); + return !myWindow.IsNull(); +} + +/*! + Returns the current active view. [ private ] +*/ +Handle(V3d_View) OCCViewer_ViewPort3d::activeView() const +{ + return myActiveView; +} + +/*! + Returns the current inactive view [ private ] +*/ +/*Handle(V3d_View) OCCViewer_ViewPort3d::inactiveView() const +{ + return ( activeView() == myOrthoView ? myPerspView : myOrthoView ); +}*/ + +/*! + Returns 'true' if the given view is mapped to window. [ private ] +*/ +bool OCCViewer_ViewPort3d::mapped( const Handle(V3d_View)& view ) const +{ + return ( !view.IsNull() && view->View()->IsDefined() ); +} diff --git a/src/OCCViewer/OCCViewer_ViewPort3d.h b/src/OCCViewer/OCCViewer_ViewPort3d.h new file mode 100755 index 000000000..a16a609a9 --- /dev/null +++ b/src/OCCViewer/OCCViewer_ViewPort3d.h @@ -0,0 +1,92 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef OCCVIEWER_VIEWPORT3D_H +#define OCCVIEWER_VIEWPORT3D_H + +#include "OCCViewer_ViewPort.h" + +#include + +#include +#include + +class QRect; + +class OCCVIEWER_EXPORT OCCViewer_ViewPort3d: public OCCViewer_ViewPort +{ + Q_OBJECT + + friend class OCCViewer_ViewTransformer; + +public: + OCCViewer_ViewPort3d( QWidget*, const Handle(V3d_Viewer)&, V3d_TypeOfView = V3d_ORTHOGRAPHIC ); + virtual ~OCCViewer_ViewPort3d(); + +public: + Handle(V3d_View) getView() const; + Handle(V3d_View) setView( const Handle(V3d_View)& ); + Handle(V3d_Viewer) getViewer() const; + + void setAnimationMode(bool theDegenerated); + + virtual void setBackgroundColor( const QColor& color); + virtual QColor backgroundColor() const; + +// void setActive( V3d_TypeOfView ); + virtual bool syncronize( const OCCViewer_ViewPort3d* ); + + double getZSize() const; + void setZSize( double ); + + virtual void onUpdate(); + + // TRANSFORMATIONS + virtual void reset(); + virtual void pan( int , int ); + virtual void setCenter( int , int ); + virtual void fitRect( const QRect& ); + virtual void zoom( int, int, int, int ); + virtual void fitAll( bool keepScale = false, bool withZ = true, bool upd = true ); + + void startRotation( int, int ); + void rotate( int, int ); + void endRotation(); + +protected: + // EVENTS + virtual void paintEvent( QPaintEvent* ); + virtual void resizeEvent( QResizeEvent* ); + +private: + Handle(V3d_View) activeView() const; + Handle(V3d_View) inactiveView() const; + bool mapView( const Handle(V3d_View)& ); + bool setWindow( const Handle(V3d_View)& ); + bool mapped( const Handle(V3d_View)& ) const; + +private: + Handle(V3d_View) myOrthoView; + Handle(V3d_View) myPerspView; + Handle(V3d_View) myActiveView; + bool myDegenerated; + bool myAnimate; + double myScale; +}; + +#endif diff --git a/src/ObjBrowser/OB.h b/src/ObjBrowser/OB.h new file mode 100755 index 000000000..ed251feed --- /dev/null +++ b/src/ObjBrowser/OB.h @@ -0,0 +1,46 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef OB_H +#define OB_H + +#if defined OB_EXPORTS +#if defined WNT +#define OB_EXPORT __declspec( dllexport ) +#else +#define OB_EXPORT +#endif +#else +#if defined WNT +#define OB_EXPORT __declspec( dllimport ) +#else +#define OB_EXPORT +#endif +#endif + +#if defined SOLARIS +#define bool int +#define false 0 +#define true 1 +#endif + +#if defined WNT +#pragma warning ( disable: 4251 ) +#endif + +#endif diff --git a/src/ObjBrowser/OB_Filter.cxx b/src/ObjBrowser/OB_Filter.cxx new file mode 100644 index 000000000..1a9fda941 --- /dev/null +++ b/src/ObjBrowser/OB_Filter.cxx @@ -0,0 +1,27 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "OB_Filter.h" + +OB_Filter::OB_Filter() +{ +} + +OB_Filter::~OB_Filter() +{ +} diff --git a/src/ObjBrowser/OB_Filter.h b/src/ObjBrowser/OB_Filter.h new file mode 100644 index 000000000..3570eb06d --- /dev/null +++ b/src/ObjBrowser/OB_Filter.h @@ -0,0 +1,35 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef OB_FILTER_H +#define OB_FILTER_H + +#include "OB.h" + +class SUIT_DataObject; + +class OB_EXPORT OB_Filter +{ +public: + OB_Filter(); + virtual ~OB_Filter(); + + virtual bool isOk( const SUIT_DataObject* ) const = 0; +}; + +#endif diff --git a/src/Plot2d/Plot2d.h b/src/Plot2d/Plot2d.h new file mode 100755 index 000000000..5d1ffa369 --- /dev/null +++ b/src/Plot2d/Plot2d.h @@ -0,0 +1,31 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifdef WNT +#ifdef PLOT2D_EXPORTS +#define PLOT2D_EXPORT __declspec(dllexport) +#else +#define PLOT2D_EXPORT __declspec(dllimport) +#endif +#else +#define PLOT2D_EXPORT +#endif + +#if defined WNT +#pragma warning ( disable: 4251 ) +#endif diff --git a/src/Plot2d/Plot2d_FitDataDlg.h b/src/Plot2d/Plot2d_FitDataDlg.h new file mode 100755 index 000000000..2b4e501e8 --- /dev/null +++ b/src/Plot2d/Plot2d_FitDataDlg.h @@ -0,0 +1,75 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef PLOT2D_FITDATADLG_H +#define PLOT2D_FITDATADLG_H + +#include "Plot2d.h" +#include + +class QButtonGroup; +class QRadioButton; +class QLineEdit; +class QPushButton; + +class PLOT2D_EXPORT Plot2d_FitDataDlg : public QDialog +{ + Q_OBJECT + +public: +// constuctor + Plot2d_FitDataDlg( QWidget* parent, bool secondAxisY ); + +// sets range + void setRange(const double xMin, + const double xMax, + const double yMin, + const double yMax, + const double y2Min = 0, + const double y2Max = 0); +// gets range, returns mode (see getMode()) + int getRange(double& xMin, + double& xMax, + double& yMin, + double& yMax, + double& y2Min, + double& y2Max); +// gets mode : 0 - Fit all; 1 - Fit horizontal, 2 - Fit vertical + int getMode(); + +protected slots: +// called when range mode changed + void onModeChanged(int); + +private: + QButtonGroup* myRangeGrp; + QRadioButton* myModeAllRB; + QRadioButton* myModeHorRB; + QRadioButton* myModeVerRB; + QLineEdit* myXMinEdit; + QLineEdit* myYMinEdit; + QLineEdit* myY2MinEdit; + QLineEdit* myXMaxEdit; + QLineEdit* myYMaxEdit; + QLineEdit* myY2MaxEdit; + QPushButton* myOkBtn; + QPushButton* myCancelBtn; + bool mySecondAxisY; +}; + +#endif diff --git a/src/Plot2d/Plot2d_Prs.h b/src/Plot2d/Plot2d_Prs.h new file mode 100755 index 000000000..78f6a1951 --- /dev/null +++ b/src/Plot2d/Plot2d_Prs.h @@ -0,0 +1,46 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef PLOT2D_PRS_H +#define PLOT2D_PRS_H + +#include "Plot2d.h" +#include "Plot2d_Curve.h" + +class PLOT2D_EXPORT Plot2d_Prs +{ +public: + Plot2d_Prs( bool theDelete = false ); + Plot2d_Prs( const Plot2d_Curve* obj, bool theDelete = false ); + ~Plot2d_Prs(); + + curveList getCurves() const; + void AddObject( const Plot2d_Curve* obj ); + + bool IsNull() const; + + bool isSecondY() const; + + void setAutoDel(bool theDel); + +protected: + curveList myCurves; + bool mySecondY; +}; + +#endif diff --git a/src/Plot2d/Plot2d_SetupViewDlg.h b/src/Plot2d/Plot2d_SetupViewDlg.h new file mode 100755 index 000000000..383f97d40 --- /dev/null +++ b/src/Plot2d/Plot2d_SetupViewDlg.h @@ -0,0 +1,124 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef PLOT2D_SETUPVIEWDLG_H +#define PLOT2D_SETUPVIEWDLG_H + +#include "Plot2d.h" +#include + +class QSpinBox; +class QCheckBox; +class QLineEdit; +class QComboBox; +class QToolButton; +class QPushButton; + +class PLOT2D_EXPORT Plot2d_SetupViewDlg : public QDialog +{ + Q_OBJECT + +public: + Plot2d_SetupViewDlg( QWidget* parent = 0, bool showDefCheck = false, bool secondAxisY = false ); + ~Plot2d_SetupViewDlg(); + + void setMainTitle( bool enable, const QString& title = QString::null ); + bool isMainTitleEnabled(); + QString getMainTitle(); + void setXTitle( bool enable, const QString& title = QString::null ); + bool isXTitleEnabled(); + QString getXTitle(); + void setYTitle( bool enable, const QString& title = QString::null ); + void setY2Title( bool enable, const QString& title = QString::null ); + bool isYTitleEnabled(); + bool isY2TitleEnabled(); + QString getYTitle(); + QString getY2Title(); + void setCurveType( const int type ); + int getCurveType(); + void setLegend( bool enable, int pos ); + bool isLegendEnabled(); + int getLegendPos(); + void setMarkerSize( const int size ); + int getMarkerSize(); + void setBackgroundColor( const QColor& color ); + QColor getBackgroundColor(); + void setMajorGrid( bool enableX, const int xdiv, bool enableY, const int divY, + bool enableY2, const int divY2 ); + void getMajorGrid( bool& enableX, int& xdiv, bool& enableY, int& divY, + bool& enableY2, int& divY2); + void setMinorGrid( bool enableX, const int xdiv, bool enableY, const int divY, + bool enableY2, const int divY2); + void getMinorGrid( bool& enableX, int& xdiv, bool& enableY, int& divY, + bool& enableY2, int& divY2); + void setScaleMode( const int xMode, const int yMode ); + int getXScaleMode(); + int getYScaleMode(); + bool isSetAsDefault(); + +protected slots: + void onMainTitleChecked(); + void onXTitleChecked(); + void onYTitleChecked(); + void onY2TitleChecked(); + void onBackgroundClicked(); + void onLegendChecked(); + void onXGridMajorChecked(); + void onYGridMajorChecked(); + void onY2GridMajorChecked(); + void onXGridMinorChecked(); + void onYGridMinorChecked(); + void onY2GridMinorChecked(); + +private: + QCheckBox* myTitleCheck; + QLineEdit* myTitleEdit; + QCheckBox* myTitleXCheck; + QLineEdit* myTitleXEdit; + QCheckBox* myTitleYCheck; + QCheckBox* myTitleY2Check; + QLineEdit* myTitleYEdit; + QLineEdit* myTitleY2Edit; + QToolButton* myBackgroundBtn; + QCheckBox* myXGridCheck; + QSpinBox* myXGridSpin; + QCheckBox* myYGridCheck; + QCheckBox* myY2GridCheck; + QSpinBox* myYGridSpin; + QSpinBox* myY2GridSpin; + QCheckBox* myXMinGridCheck; + QSpinBox* myXMinGridSpin; + QCheckBox* myYMinGridCheck; + QCheckBox* myY2MinGridCheck; + QSpinBox* myYMinGridSpin; + QSpinBox* myY2MinGridSpin; + QComboBox* myCurveCombo; + QCheckBox* myLegendCheck; + QComboBox* myLegendCombo; + QSpinBox* myMarkerSpin; + QComboBox* myXModeCombo; + QComboBox* myYModeCombo; + QComboBox* myY2ModeCombo; + QCheckBox* myDefCheck; + + QPushButton* myOkBtn; + QPushButton* myCancelBtn; + bool mySecondAxisY; +}; + +#endif diff --git a/src/Plot2d/Plot2d_ViewManager.cxx b/src/Plot2d/Plot2d_ViewManager.cxx new file mode 100755 index 000000000..704e33095 --- /dev/null +++ b/src/Plot2d/Plot2d_ViewManager.cxx @@ -0,0 +1,76 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "Plot2d_ViewManager.h" +#include "Plot2d_ViewModel.h" +#include "Plot2d_ViewWindow.h" + +int Plot2d_ViewManager::myMaxId = 0; + +Plot2d_ViewManager::Plot2d_ViewManager( SUIT_Study* study, SUIT_Desktop* desk ) +: SUIT_ViewManager( study, desk ) +{ + myId = ++myMaxId; + Plot2d_Viewer* v = new Plot2d_Viewer(); + setViewModel( v ); +} + +Plot2d_ViewManager::~Plot2d_ViewManager() +{ +} + +Plot2d_Viewer* Plot2d_ViewManager::getPlot2dModel() const +{ + return (Plot2d_Viewer*)myViewModel; +} + +void Plot2d_ViewManager::setViewName( SUIT_ViewWindow* theView ) +{ + int aPos = myViews.find(theView); + theView->setCaption( QString( "Plot2d scene:%1 - viewer:%2" ).arg(myId).arg(aPos+1)); +} + +bool Plot2d_ViewManager::insertView( SUIT_ViewWindow* theView ) +{ + bool res = SUIT_ViewManager::insertView( theView ); + if ( res ) + { + Plot2d_ViewWindow* view = (Plot2d_ViewWindow*)theView; + connect( view, SIGNAL( cloneView() ), this, SLOT( onCloneView() ) ); + } + return res; +} + +void Plot2d_ViewManager::createView() +{ + createViewWindow(); +} + +void Plot2d_ViewManager::onCloneView() +{ + SUIT_ViewWindow* vw = createViewWindow(); + + Plot2d_ViewWindow *newWnd = 0, *clonedWnd = 0; + if( vw && vw->inherits( "Plot2d_ViewWindow" ) ) + newWnd = ( Plot2d_ViewWindow* )vw; + if( sender() && sender()->inherits( "Plot2d_ViewWindow" ) ) + clonedWnd = ( Plot2d_ViewWindow* )sender(); + + if( newWnd && clonedWnd ) + emit cloneView( clonedWnd->getViewFrame(), newWnd->getViewFrame() ); +} diff --git a/src/Plot2d/Plot2d_ViewManager.h b/src/Plot2d/Plot2d_ViewManager.h new file mode 100755 index 000000000..f8b841b41 --- /dev/null +++ b/src/Plot2d/Plot2d_ViewManager.h @@ -0,0 +1,57 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef PLOT2D_VIEWMANAGER_H +#define PLOT2D_VIEWMANAGER_H + +#include "Plot2d.h" +#include "SUIT_ViewManager.h" + +class SUIT_Desktop; +class Plot2d_Viewer; +class Plot2d_ViewFrame; + +class PLOT2D_EXPORT Plot2d_ViewManager : public SUIT_ViewManager +{ + Q_OBJECT + +public: + Plot2d_ViewManager( SUIT_Study*, SUIT_Desktop* ); + ~Plot2d_ViewManager(); + + Plot2d_Viewer* getPlot2dModel() const; + +protected: + void setViewName(SUIT_ViewWindow* theView); + bool insertView(SUIT_ViewWindow* theView); + +public slots: + void createView(); + +protected slots: + void onCloneView(); + +signals: + void cloneView( Plot2d_ViewFrame*, Plot2d_ViewFrame* ); + +protected: + static int myMaxId; + int myId; +}; + +#endif diff --git a/src/Plot2d/Plot2d_ViewModel.cxx b/src/Plot2d/Plot2d_ViewModel.cxx new file mode 100755 index 000000000..637351c91 --- /dev/null +++ b/src/Plot2d/Plot2d_ViewModel.cxx @@ -0,0 +1,159 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// Plot2d_ViewModel.cxx: implementation of the Plot2d_ViewModel class. +// +////////////////////////////////////////////////////////////////////// + +#include "Plot2d_ViewModel.h" +#include "Plot2d_ViewWindow.h" +#include "Plot2d_ViewManager.h" +#include "Plot2d_ViewFrame.h" +#include "Plot2d_Prs.h" + +#include + +Plot2d_Viewer::Plot2d_Viewer(bool theAutoDel) +:SUIT_ViewModel() +{ + myPrs = 0; + myAutoDel = theAutoDel; +} + +Plot2d_Viewer::~Plot2d_Viewer() +{ + if (myPrs) + clearPrs(); +} + +//********************************************************************* +SUIT_ViewWindow* Plot2d_Viewer::createView(SUIT_Desktop* theDesktop) +{ + Plot2d_ViewWindow* aPlot2dView = new Plot2d_ViewWindow(theDesktop, this); + if (myPrs) + aPlot2dView->getViewFrame()->Display(myPrs); + return aPlot2dView; +} + +//********************************************************************* +void Plot2d_Viewer::contextMenuPopup(QPopupMenu* thePopup) +{ + Plot2d_ViewWindow* aView = (Plot2d_ViewWindow*)(myViewManager->getActiveView()); + if ( aView ) + aView->contextMenuPopup(thePopup); + + if (thePopup->count() > 0) thePopup->insertSeparator(); + thePopup->insertItem( tr( "MNU_DUMP_VIEW" ), this, SLOT(onDumpView())); + thePopup->insertItem( tr( "MEN_PLOT2D_CHANGE_BACKGROUND" ), this, SLOT(onChangeBgColor())); + + if ( aView ) { + if ( !aView->getToolBar()->isVisible() ) { + if (thePopup->count() > 0) thePopup->insertSeparator(); + thePopup->insertItem("Show toolbar", this, SLOT(onShowToolbar())); + } + } +} + + +//********************************************************************* +void Plot2d_Viewer::setPrs(Plot2d_Prs* thePrs) +{ + if (myPrs) + clearPrs(); + myPrs = thePrs; + myPrs->setAutoDel(myAutoDel); +} + +//********************************************************************* +void Plot2d_Viewer::update() +{ + SUIT_ViewManager* aMgr = getViewManager(); + QPtrVector aViews = aMgr->getViews(); + unsigned int aSize = aViews.size(); + for (uint i = 0; i < aSize; i++) { + Plot2d_ViewWindow* aView = (Plot2d_ViewWindow*)aViews[i]; + if (myPrs && aView) + aView->getViewFrame()->Display(myPrs); + } +} + +//********************************************************************* +void Plot2d_Viewer::clearPrs() +{ + SUIT_ViewManager* aMgr = getViewManager(); + QPtrVector aViews = aMgr->getViews(); + unsigned int aSize = aViews.size(); + for (uint i = 0; i < aSize; i++) { + Plot2d_ViewWindow* aView = (Plot2d_ViewWindow*)aViews[i]; + if (myPrs && aView) + aView->getViewFrame()->Erase(myPrs); + } + if (myAutoDel && myPrs) { + delete myPrs; + } + myPrs = 0; +} + +//********************************************************************* +void Plot2d_Viewer::setAutoDel(bool theDel) +{ + myAutoDel = theDel; + if (myPrs) + myPrs->setAutoDel(theDel); +} + +//********************************************************************* +void Plot2d_Viewer::onChangeBgColor() +{ + Plot2d_ViewWindow* aView = (Plot2d_ViewWindow*)(myViewManager->getActiveView()); + if( !aView ) + return; + Plot2d_ViewFrame* aViewFrame = aView->getViewFrame(); + aViewFrame->onChangeBackground(); +} + +//********************************************************************* +void Plot2d_Viewer::onShowToolbar() { + Plot2d_ViewWindow* aView = (Plot2d_ViewWindow*)(myViewManager->getActiveView()); + if ( aView ) + aView->getToolBar()->show(); +} + +//********************************************************************* +void Plot2d_Viewer::onDumpView() +{ + Plot2d_ViewWindow* aView = (Plot2d_ViewWindow*)(myViewManager->getActiveView()); + if ( aView ) + aView->onDumpView(); +} + +//********************************************************************* +void Plot2d_Viewer::onCloneView( Plot2d_ViewFrame*, Plot2d_ViewFrame* ) +{ +} +//********************************************************************* +void Plot2d_Viewer::setViewManager( SUIT_ViewManager* mgr ) +{ + SUIT_ViewModel::setViewManager( mgr ); + if( mgr && mgr->inherits( "Plot2d_ViewManager" ) ) + { + Plot2d_ViewManager* pmgr = ( Plot2d_ViewManager* )mgr; + connect( pmgr, SIGNAL( cloneView( Plot2d_ViewFrame*, Plot2d_ViewFrame* ) ), + this, SLOT( onCloneView( Plot2d_ViewFrame*, Plot2d_ViewFrame* ) ) ); + } +} diff --git a/src/Plot2d/Plot2d_ViewModel.h b/src/Plot2d/Plot2d_ViewModel.h new file mode 100755 index 000000000..4ba4fd2b6 --- /dev/null +++ b/src/Plot2d/Plot2d_ViewModel.h @@ -0,0 +1,64 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#if !defined(_PLOT2D_VIEWMODEL_H) +#define _PLOT2D_VIEWMODEL_H + +#include "Plot2d.h" +#include "SUIT_ViewModel.h" + +class SUIT_ViewWindow; +class SUIT_Desktop; +class Plot2d_ViewFrame; +class Plot2d_Prs; +class QString; +class QPopupMenu; + +class PLOT2D_EXPORT Plot2d_Viewer: public SUIT_ViewModel +{ + Q_OBJECT + +public: + static QString Type() { return "Plot2d"; } + + Plot2d_Viewer(bool theAutoDel = false); + ~Plot2d_Viewer(); + + virtual void setViewManager( SUIT_ViewManager* ); + virtual SUIT_ViewWindow* createView(SUIT_Desktop* theDesktop); + virtual QString getType() const { return Type(); } + virtual void contextMenuPopup(QPopupMenu*); + Plot2d_Prs* getPrs() const { return myPrs; }; + void setPrs(Plot2d_Prs* thePrs); + void update(); + void clearPrs(); + void setAutoDel(bool theDel); + +protected slots: + void onChangeBgColor(); + void onDumpView(); + void onShowToolbar(); + virtual void onCloneView( Plot2d_ViewFrame*, Plot2d_ViewFrame* ); + +private: + Plot2d_Prs* myPrs; + bool myAutoDel; +}; + +#endif // !defined(_PLOT2D_VIEWMODEL_H) + diff --git a/src/Prs/SALOME_Prs.cxx b/src/Prs/SALOME_Prs.cxx new file mode 100755 index 000000000..cb35bb80b --- /dev/null +++ b/src/Prs/SALOME_Prs.cxx @@ -0,0 +1,394 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: SALOME_Prs.cxx +// Created: Wed Apr 28 15:03:43 2004 +// Author: Sergey ANIKIN +// + + +#include "SALOME_Prs.h" + +//#include "utilities.h" + +//using namespace std; + +//=========================================================== +/*! + * Function: SALOME_OCCPrs::DisplayIn \n + * Purpose: Dispatches display operation to proper Display() \n + * method of SALOME_View + */ +//=========================================================== +void SALOME_OCCPrs::DisplayIn( SALOME_View* v ) const +{ + if ( v ) v->Display( this ); +} + +//=========================================================== +/*! + * Function: SALOME_OCCPrs::EraseIn \n + * Purpose: Dispatches display operation to proper Erase() \n + * method of SALOME_View + */ +//=========================================================== +void SALOME_OCCPrs::EraseIn( SALOME_View* v, const bool forced ) const +{ + if ( v ) v->Erase( this, forced ); +} + +//=========================================================== +/*! + * Function: SALOME_OCCPrs::LocalSelectionIn \n + * Purpose: Dispatches operation to proper LocalSelectionIn() \n + * method of SALOME_View + */ +//=========================================================== +void SALOME_OCCPrs::LocalSelectionIn( SALOME_View* v, const int mode ) const +{ + if ( v ) v->LocalSelection( this, mode ); +} + +//=========================================================== +/*! + * Function: SALOME_OCCPrs::Update \n + * Purpose: Dispatches update operation to proper Update() \n + * method of SALOME_Displayer + */ +//=========================================================== +void SALOME_OCCPrs::Update( SALOME_Displayer* d ) +{ + if ( d ) d->Update( this ); +} + +//=========================================================== +/*! + * Function: SALOME_VTKPrs::DisplayIn \n + * Purpose: Dispatches display operation to proper Display() \n + * method of SALOME_View + */ +//=========================================================== +void SALOME_VTKPrs::DisplayIn( SALOME_View* v ) const +{ + if ( v ) v->Display( this ); +} + +//=========================================================== +/*! + * Function: SALOME_VTKPrs::EraseIn \n + * Purpose: Dispatches display operation to proper Erase() \n + * method of SALOME_View + */ +//=========================================================== +void SALOME_VTKPrs::EraseIn( SALOME_View* v, const bool forced ) const +{ + if ( v ) v->Erase( this, forced ); +} + +//=========================================================== +/*! + * Function: SALOME_VTKPrs::LocalSelectionIn \n + * Purpose: Dispatches operation to proper LocalSelectionIn() \n + * method of SALOME_View + */ +//=========================================================== +void SALOME_VTKPrs::LocalSelectionIn( SALOME_View* v, const int mode ) const +{ + if ( v ) v->LocalSelection( this, mode ); +} + +//=========================================================== +/*! + * Function: SALOME_VTKPrs::Update \n + * Purpose: Dispatches update operation to proper Update() \n + * method of SALOME_Displayer + */ +//=========================================================== +void SALOME_VTKPrs::Update( SALOME_Displayer* d ) +{ + if ( d ) d->Update( this ); +} + +//=========================================================== +/*! + * Function: SALOME_Prs2d::DisplayIn \n + * Purpose: Dispatches display operation to proper Display() \n + * method of SALOME_View + */ +//=========================================================== +void SALOME_Prs2d::DisplayIn( SALOME_View* v ) const +{ + if ( v ) v->Display( this ); +} + +//=========================================================== +/*! + * Function: SALOME_Prs2d::EraseIn \n + * Purpose: Dispatches display operation to proper Erase() \n + * method of SALOME_View + */ +//=========================================================== +void SALOME_Prs2d::EraseIn( SALOME_View* v, const bool forced ) const +{ + if ( v ) v->Erase( this, forced ); +} + +//=========================================================== +/*! + * Function: SALOME_Prs2d::LocalSelectionIn \n + * Purpose: Dispatches operation to proper LocalSelectionIn() \n + * method of SALOME_View + */ +//=========================================================== +void SALOME_Prs2d::LocalSelectionIn( SALOME_View* v, const int mode ) const +{ + if ( v ) v->LocalSelection( this, mode ); +} + +//=========================================================== +/*! + * Function: SALOME_Prs2d::Update \n + * Purpose: Dispatches update operation to proper Update() \n + * method of SALOME_Displayer + */ +//=========================================================== +void SALOME_Prs2d::Update( SALOME_Displayer* d ) +{ + if ( d ) d->Update( this ); +} + +//=========================================================== +/*! + * Function: SALOME_View::Display \n + * Purpose: Gives control to SALOME_Prs object, so that \n + * it could perform double dispatch + */ +//=========================================================== +void SALOME_View::Display( const SALOME_Prs* prs ) +{ + prs->DisplayIn( this ); +} + +//=========================================================== +/*! + * Function: SALOME_View::Erase \n + * Purpose: Gives control to SALOME_Prs object, so that \n + * it could perform double dispatch + */ +//=========================================================== +void SALOME_View::Erase( const SALOME_Prs* prs, const bool forced ) +{ + prs->EraseIn( this, forced ); +} + +//=========================================================== +/*! + * Function: SALOME_View::LocalSelection \n + * Purpose: Gives control to SALOME_Prs object, so that \n + * it could perform double dispatch + */ +//=========================================================== +void SALOME_View::LocalSelection( const SALOME_Prs* prs, const int mode ) +{ + prs->LocalSelectionIn( this, mode ); +} + +//=========================================================== +/*! + * Function: SALOME_View::Display \n + * Purpose: Virtual method, should be reimplemented in successors, \n + * by default issues a warning and does nothing. + */ +//=========================================================== +void SALOME_View::Display( const SALOME_OCCPrs* ) +{ +// MESSAGE( "SALOME_View::Display( const SALOME_OCCPrs& ) called! Probably, presentation is being displayed in uncompatible viewframe." ); +} + +//=========================================================== +/*! + * Function: SALOME_View::Display \n + * Purpose: Virtual method, should be reimplemented in successors, \n + * by default issues a warning and does nothing. + */ +//=========================================================== +void SALOME_View::Display( const SALOME_VTKPrs* ) +{ +// MESSAGE( "SALOME_View::Display( const SALOME_VTKPrs& ) called! Probably, presentation is being displayed in uncompatible viewframe." ); +} + +//=========================================================== +/*! + * Function: SALOME_View::Display \n + * Purpose: Virtual method, should be reimplemented in successors, \n + * by default issues a warning and does nothing. + */ +//=========================================================== +void SALOME_View::Display( const SALOME_Prs2d* ) +{ +// MESSAGE( "SALOME_View::Display( const SALOME_Prs2d& ) called! Probably, presentation is being displayed in uncompatible viewframe." ); +} + +//=========================================================== +/*! + * Function: SALOME_View::Erase \n + * Purpose: Virtual method, should be reimplemented in successors, \n + * by default issues a warning and does nothing. + */ +//=========================================================== +void SALOME_View::Erase( const SALOME_OCCPrs*, const bool ) +{ +// MESSAGE( "SALOME_View::Erase( const SALOME_OCCPrs& ) called! Probably, presentation is being erased in uncompatible viewframe." ); +} + +//=========================================================== +/*! + * Function: SALOME_View::Erase \n + * Purpose: Virtual method, should be reimplemented in successors, \n + * by default issues a warning and does nothing. + */ +//=========================================================== +void SALOME_View::Erase( const SALOME_VTKPrs*, const bool ) +{ +// MESSAGE( "SALOME_View::Erase( const SALOME_VTKPrs& ) called! Probably, presentation is being erased in uncompatible viewframe." ); +} + +//=========================================================== +/*! + * Function: SALOME_View::Erase \n + * Purpose: Virtual method, should be reimplemented in successors, \n + * by default issues a warning and does nothing. + */ +//=========================================================== +void SALOME_View::Erase( const SALOME_Prs2d*, const bool ) +{ +// MESSAGE( "SALOME_View::Erase( const SALOME_Prs2d& ) called! Probably, presentation is being erased in uncompatible viewframe." ); +} + +//=========================================================== +/*! + * Function: SALOME_View::EraseAll \n + * Purpose: Virtual method, should be reimplemented in successors, \n + * by default issues a warning and does nothing. + */ +//=========================================================== +void SALOME_View::EraseAll( const bool ) +{ +// MESSAGE( "SALOME_View::EraseAll() called!" ); +} + +//=========================================================== +/*! + * Function: SALOME_View::LocalSelection \n + * Purpose: Virtual method, should be reimplemented in successors, \n + * by default issues a warning and does nothing. + */ +//=========================================================== +void SALOME_View::LocalSelection( const SALOME_OCCPrs*, const int ) +{ +// MESSAGE( "SALOME_View::LocalSelection( const SALOME_OCCPrs* ) called! \ +// Probably, selection is being activated in uncompatible viewframe." ); +} + +//=========================================================== +/*! + * Function: SALOME_View::LocalSelection \n + * Purpose: Virtual method, should be reimplemented in successors, \n + * by default issues a warning and does nothing. + */ +//=========================================================== +void SALOME_View::LocalSelection( const SALOME_VTKPrs*, const int ) +{ +// MESSAGE( "SALOME_View::LocalSelection( const SALOME_VTKPrs* ) called! \ +// Probably, selection is being activated in uncompatible viewframe." ); +} + +//=========================================================== +/*! + * Function: SALOME_View::LocalSelection \n + * Purpose: Virtual method, should be reimplemented in successors, \n + * by default issues a warning and does nothing. + */ +//=========================================================== +void SALOME_View::LocalSelection( const SALOME_Prs2d*, const int ) +{ +// MESSAGE( "SALOME_View::LocalSelection( const SALOME_Prs2d* ) called! \ +// Probably, selection is being activated in uncompatible viewframe." ); +} + +//=========================================================== +/*! + * Function: SALOME_View::GlobalSelection \n + * Purpose: Virtual method, should be reimplemented in successors, \n + * by default issues a warning and does nothing. + */ +//=========================================================== +void SALOME_View::GlobalSelection( const bool ) const +{ +// MESSAGE( "SALOME_View::GlobalSelection() called! \ +// Probably, selection is being activated in uncompatible viewframe." ); +} + +//=========================================================== +/*! + * Function: SALOME_Displayer::UpdatePrs \n + * Purpose: Gives control to SALOME_Prs object, so that \n + * it could perform double dispatch + */ +//=========================================================== +void SALOME_Displayer::UpdatePrs( SALOME_Prs* prs ) +{ + prs->Update( this ); +} + +//=========================================================== +/*! + * Function: SALOME_Displayer::Update \n + * Purpose: Virtual method, should be reimplemented in successors, \n + * by default issues a warning and does nothing. + */ +//=========================================================== +void SALOME_Displayer::Update( SALOME_OCCPrs* ) +{ +// MESSAGE( "SALOME_Displayer::Update( SALOME_OCCPrs* ) called! Probably, presentation is being updated in uncompatible viewframe." ); +} + +//=========================================================== +/*! + * Function: SALOME_Displayer::Update \n + * Purpose: Virtual method, should be reimplemented in successors, \n + * by default issues a warning and does nothing. + */ +//=========================================================== +void SALOME_Displayer::Update( SALOME_VTKPrs* ) +{ +// MESSAGE( "SALOME_Displayer::Update( SALOME_VTKPrs* ) called! Probably, presentation is being updated in uncompatible viewframe." ); +} + +//=========================================================== +/*! + * Function: SALOME_Displayer::Update \n + * Purpose: Virtual method, should be reimplemented in successors, \n + * by default issues a warning and does nothing. + */ +//=========================================================== +void SALOME_Displayer::Update( SALOME_Prs2d* ) +{ +// MESSAGE( "SALOME_Displayer::Update( SALOME_Prs2d* ) called! Probably, presentation is being updated in uncompatible viewframe." ); +} + diff --git a/src/Prs/SALOME_Prs.h b/src/Prs/SALOME_Prs.h new file mode 100755 index 000000000..eec2a6055 --- /dev/null +++ b/src/Prs/SALOME_Prs.h @@ -0,0 +1,260 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SALOME_PRS_H +#define SALOME_PRS_H + +#ifdef WNT +#ifdef PRS_EXPORTS +#define PRS_EXPORT __declspec(dllexport) +#else +#define PRS_EXPORT __declspec(dllimport) +#endif +#else +#define PRS_EXPORT +#endif + +class SALOME_View; +class SALOME_Displayer; +class Handle_SALOME_InteractiveObject; + +//=========================================================== +/*! + * Class: SALOME_Prs \n + * Description: Base class for SALOME graphic object wrappers - presentations.\n + * Presentations are temporary objects, so they can be created on the stack. + */ +//=========================================================== + +class PRS_EXPORT SALOME_Prs +{ +public: + //! Destructor + virtual ~SALOME_Prs() {} + + //! Key method for double dispatch of display operation + virtual void DisplayIn( SALOME_View* ) const = 0; + + //! Key method for double dispatch of erase operation + virtual void EraseIn( SALOME_View*, const bool = false ) const = 0; + + //! Key method for double dispatch of update operation + virtual void Update( SALOME_Displayer* ) = 0; + + //! Should return true, if this presentation contains a graphic object + virtual bool IsNull() const = 0; + + //! Key method for double dispatch of activation of subshapes selection + virtual void LocalSelectionIn( SALOME_View*, const int ) const = 0; +}; + +//=========================================================== +/*! + * Class: SALOME_OCCPrs \n + * Description: Base class for OpenCASCADE graphic object (AIS_InteractiveObject) wrappers.\n + * This intermediate class is necessary to avoid dependencies from OCC libs. + */ +//=========================================================== + +class PRS_EXPORT SALOME_OCCPrs : public SALOME_Prs +{ +public: + //! It uses double dispatch in order to \n + //! invoke Display() method corresponding to the actual type of presentation. + virtual void DisplayIn( SALOME_View* ) const; + + //! It uses double dispatch in order to \n + //! invoke Erase() method corresponding to the actual type of presentation. + virtual void EraseIn( SALOME_View*, const bool = false ) const; + + //! It uses double dispatch in order to \n + //! invoke Update() method corresponding to the actual type of presentation. + virtual void Update( SALOME_Displayer* ); + + //! Key method for double dispatch of activation of subshapes selection + virtual void LocalSelectionIn( SALOME_View*, const int ) const; +}; + +//=========================================================== +/*! + * Class: SALOME_VTKPrs \n + * Description: Base class for VTK graphic object (vtkActor) wrappers \n + * This intermediate class is necessary to avoid dependencies from VTK libs. + */ +//=========================================================== +class PRS_EXPORT SALOME_VTKPrs : public SALOME_Prs +{ +public: + //! It uses double dispatch in order to \n + //! invoke Display() method corresponding to the actual type of presentation. + virtual void DisplayIn( SALOME_View* ) const; + + //! It uses double dispatch in order to \n + //! invoke Erase() method corresponding to the actual type of presentation. + virtual void EraseIn( SALOME_View*, const bool = false ) const; + + //! It uses double dispatch in order to \n + //! invoke Update() method corresponding to the actual type of presentation. + virtual void Update( SALOME_Displayer* ); + + //! Key method for double dispatch of activation of subshapes selection + virtual void LocalSelectionIn( SALOME_View*, const int ) const; +}; + +//=========================================================== +/*! + * Class: SALOME_Prs2d \n + * Description: Base class for Plot2d graphic object (Plot2d_Curve) wrappers. + */ +//=========================================================== + +class PRS_EXPORT SALOME_Prs2d : public SALOME_Prs +{ +public: + //! It uses double dispatch in order to + //! invoke Display() method corresponding to the actual type of presentation. + virtual void DisplayIn( SALOME_View* ) const; + + //! It uses double dispatch in order to + //! invoke Erase() method corresponding to the actual type of presentation. + virtual void EraseIn( SALOME_View*, const bool = false ) const; + + //! It uses double dispatch in order to + //! invoke Update() method corresponding to the actual type of presentation. + virtual void Update( SALOME_Displayer* ); + + //! Key method for double dispatch of activation of subshapes selection + virtual void LocalSelectionIn( SALOME_View*, const int ) const; +}; + +///////////////////////////////////////////////////////////////////////// +// Base classes for object wrappers for any other visualization libraries +// should be added here! +///////////////////////////////////////////////////////////////////////// + +//=========================================================== +/*! + * Class: SALOME_View \n + * Description: Base class for SALOME views (or view frames) + */ +//=========================================================== + +class PRS_EXPORT SALOME_View +{ +public: + //! Destructor + virtual ~SALOME_View() {} + + //! This Display() method should be called to display given presentation \n + //! created anywhere by anybody. It simply passes control to SALOME_Prs object \n + //! so that it could perform double dispatch. + void Display( const SALOME_Prs* ); + + //! This Erase() method should be called to erase given presentation \n + //! created anywhere by anybody. It simply passes control to SALOME_Prs object \n + //! so that it could perform double dispatch. + void Erase( const SALOME_Prs*, const bool = false ); + + //! This LocalSelection() method should be called to activate sub-shapes selection \n + //! created anywhere by anybody. It simply passes control to SALOME_Prs object \n + //! so that it could perform double dispatch. + void LocalSelection( const SALOME_Prs*, const int ); + + // Interface for derived views + + // Display() methods for ALL kinds of presentation should appear here + virtual void Display( const SALOME_OCCPrs* );//!< Display SALOME_OCCPrs presentation. + virtual void Display( const SALOME_VTKPrs* );//!< Display SALOME_VTKPrs presentation. + virtual void Display( const SALOME_Prs2d* );//!< Display SALOME_Prs2d presentation. + // Add new Display() methods here... + + // Erase() methods for ALL kinds of presentation should appear here + virtual void Erase( const SALOME_OCCPrs*, const bool = false );//!< Erase SALOME_OCCPrs + virtual void Erase( const SALOME_VTKPrs*, const bool = false );//!< Erase SALOME_VTKPrs + virtual void Erase( const SALOME_Prs2d*, const bool = false );//!< Erase SALOME_Prs2d + virtual void EraseAll( const bool = false ); + // Add new Erase() methods here... + + // LocalSelection() methods for ALL kinds of presentation should appear here + virtual void LocalSelection( const SALOME_OCCPrs*, const int );//!< Local selection SALOME_OCCPrs + virtual void LocalSelection( const SALOME_VTKPrs*, const int );//!< Local selection SALOME_VTKPrs + virtual void LocalSelection( const SALOME_Prs2d* , const int );//!< Local selection SALOME_Prs2d + + //! Deactivates selection of sub-shapes (must be redefined with OCC viewer) + virtual void GlobalSelection( const bool = false ) const; + + //! Creates empty presenation of corresponding type + virtual SALOME_Prs* CreatePrs( const char* entry = 0 ) { return 0; } + + // Axiluary methods called before and after displaying of objects + virtual void BeforeDisplay( SALOME_Displayer* d ) {} //!< Null body here + virtual void AfterDisplay ( SALOME_Displayer* d ) {} //!< Null body here + + // New methods (asv) + //! \retval Return false. + virtual bool isVisible( const Handle_SALOME_InteractiveObject& ){ return false; } + virtual void Repaint() {} //!< Null body here. +}; + +//=========================================================== +/* + * Classes: SALOME_Displayer + * Description: These classes are used to specify type of view + * VTK, OCC or Plot2d + */ +//=========================================================== +class PRS_EXPORT SALOME_OCCViewType {}; +class PRS_EXPORT SALOME_VTKViewType {}; +class PRS_EXPORT SALOME_Plot2dViewType {}; + +//=========================================================== +/*! + * Class: SALOME_Displayer \n + * Description: Base class for SALOME displayers + */ +//=========================================================== + +class PRS_EXPORT SALOME_Displayer +{ +public: + //! Destructor + virtual ~SALOME_Displayer() {/*! Null body here*/} + + //! This Update() method should be called to update given presentation \n + //! created anywhere by anybody. It simply passes control to SALOME_Prs object \n + //! so that it could perform double dispatch. + void UpdatePrs( SALOME_Prs* ); + + // Interface for derived displayers + + // Update() methods for ALL kinds of presentation should appear here + virtual void Update( SALOME_OCCPrs* );//!< Update SALOME_OCCPrs presentation. + virtual void Update( SALOME_VTKPrs* );//!< Update SALOME_VTKPrs presentation. + virtual void Update( SALOME_Prs2d* );//!< Update SALOME_Prs2d presentation. + // Add new Update() methods here... + + // Axiluary methods called before and after displaying of objects + virtual void BeforeDisplay( SALOME_View*, const SALOME_OCCViewType& ){/*! Null body here*/}; + virtual void AfterDisplay ( SALOME_View*, const SALOME_OCCViewType& ){/*! Null body here*/}; + virtual void BeforeDisplay( SALOME_View*, const SALOME_VTKViewType& ){/*! Null body here*/}; + virtual void AfterDisplay ( SALOME_View*, const SALOME_VTKViewType& ){/*! Null body here*/}; + virtual void BeforeDisplay( SALOME_View*, const SALOME_Plot2dViewType& ){/*! Null body here*/}; + virtual void AfterDisplay ( SALOME_View*, const SALOME_Plot2dViewType& ){/*! Null body here*/}; +}; + +#endif diff --git a/src/PyInterp/PyInterp.h b/src/PyInterp/PyInterp.h new file mode 100755 index 000000000..fe7ec6917 --- /dev/null +++ b/src/PyInterp/PyInterp.h @@ -0,0 +1,59 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#if !defined ( _PYINTERP_H ) +#define _PYINTERP_H + +// ======================================================== +// set dllexport type for Win platform +#ifdef WNT + +#ifdef PYINTERP_EXPORTS +#define PYINTERP_EXPORT __declspec(dllexport) +#else +#define PYINTERP_EXPORT __declspec(dllimport) +#endif + +#else // WNT + +#define PYINTERP_EXPORT + +#endif // WNT + +// ======================================================== +// little trick - we do not have debug python libraries +#ifdef _DEBUG + +#undef _DEBUG +#include +#define _DEBUG + +#else // _DEBUG + +#include + +#endif // _DEBUG + +// ======================================================== +// avoid warning messages +#ifdef WNT +#pragma warning (disable : 4786) +#pragma warning (disable : 4251) +#endif + +#endif // _PYINTERP_H diff --git a/src/PyInterp/PyInterp_Watcher.h b/src/PyInterp/PyInterp_Watcher.h new file mode 100755 index 000000000..e90877743 --- /dev/null +++ b/src/PyInterp/PyInterp_Watcher.h @@ -0,0 +1,41 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef _PYINTERP_WATCHER_H_ +#define _PYINTERP_WATCHER_H_ + +#include + +#include + +#include + +// Private class that keeps track of destructions of request listeners +class PYINTERP_EXPORT PyInterp_Watcher : public QObject +{ + Q_OBJECT + +public: + PyInterp_Watcher() : QObject( 0 ) {} + virtual ~PyInterp_Watcher() {} + +public slots: + void onDestroyed( QObject* o ) { PyInterp_Dispatcher::Get()->objectDestroyed( o ); } +}; + +#endif // _PYINTERP_WATCHER_H_ diff --git a/src/PythonConsole/PythonConsole.h b/src/PythonConsole/PythonConsole.h new file mode 100755 index 000000000..1e6f954ca --- /dev/null +++ b/src/PythonConsole/PythonConsole.h @@ -0,0 +1,59 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#if !defined ( _PYTHONCONSOLE_H ) +#define _PYTHONCONSOLE_H + +// ======================================================== +// set dllexport type for Win platform +#ifdef WNT + +#ifdef PYTHONCONSOLE_EXPORTS +#define PYCONSOLE_EXPORT __declspec(dllexport) +#else +#define PYCONSOLE_EXPORT __declspec(dllimport) +#endif + +#else // WNT + +#define PYCONSOLE_EXPORT + +#endif // WNT + +// ======================================================== +// little trick - we do not have debug python libraries +#ifdef _DEBUG + +#undef _DEBUG +#include +#define _DEBUG + +#else // _DEBUG + +#include + +#endif // _DEBUG + +// ======================================================== +// avoid warning messages +#ifdef WNT +#pragma warning (disable : 4786) +#pragma warning (disable : 4251) +#endif + +#endif // _PYTHONCONSOLE_H diff --git a/src/PythonConsole/PythonConsole_PyConsole.cxx b/src/PythonConsole/PythonConsole_PyConsole.cxx new file mode 100755 index 000000000..c7f8f1c7c --- /dev/null +++ b/src/PythonConsole/PythonConsole_PyConsole.cxx @@ -0,0 +1,73 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "PythonConsole_PyConsole.h" +#include "PythonConsole_PyEditor.h" +#include "PyInterp_base.h" + +#include "SUIT_Desktop.h" + +#include + +using namespace std; + +//**************************************************************** +PythonConsole::PythonConsole(QWidget* parent, PyInterp_base* interp) +: QWidget(parent), myEditor( 0 ) +{ + // create python interpreter + myInterp = interp; + if ( !myInterp ) + myInterp = new PythonConsole_PyInterp(); + + // initialize Python interpretator + myInterp->initialize(); + + // create editor console + QVBoxLayout* lay = new QVBoxLayout( this ); + myEditor = new PythonConsole_PyEditor(myInterp, this,"Python Interpreter"); + lay->addWidget( myEditor ); +} + +//**************************************************************** +PythonConsole::~PythonConsole() +{ +} + +//**************************************************************** +void PythonConsole::exec( const QString& command ) +{ + if ( myEditor ) + myEditor->exec( command ); +} + +//**************************************************************** +void PythonConsole::setFont( const QFont& f ) +{ + if( myEditor ) + myEditor->setFont( f ); +} + +//**************************************************************** +QFont PythonConsole::font() const +{ + QFont res; + if( myEditor ) + res = myEditor->font(); + return res; +} diff --git a/src/PythonConsole/PythonConsole_PyConsole.h b/src/PythonConsole/PythonConsole_PyConsole.h new file mode 100755 index 000000000..264e4ae0f --- /dev/null +++ b/src/PythonConsole/PythonConsole_PyConsole.h @@ -0,0 +1,49 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef PythonConsole_PyConsole_H +#define PythonConsole_PyConsole_H + +#include "PythonConsole.h" + +#include + +class PythonConsole_PyEditor; +class PyInterp_base; + +class PYCONSOLE_EXPORT PythonConsole: public QWidget +{ + Q_OBJECT; + +public: + PythonConsole(QWidget* parent, PyInterp_base* interp = 0 ); + virtual ~PythonConsole(); + + PyInterp_base* getInterp() { return myInterp; } + QFont font() const; + virtual void setFont( const QFont& ); + + void exec( const QString& command ); + +protected: + PyInterp_base* myInterp; + PythonConsole_PyEditor* myEditor; +}; + + +#endif diff --git a/src/Qtx/Qtx.cxx b/src/Qtx/Qtx.cxx new file mode 100755 index 000000000..41231fbe8 --- /dev/null +++ b/src/Qtx/Qtx.cxx @@ -0,0 +1,558 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: Qtx.cxx +// Author: Sergey TELKOV + +#include "Qtx.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/*! + Name: setTabOrder [static public] + Desc: Set tab order for specified list of widgets. Last parameter should be null pointer. +*/ + +void Qtx::setTabOrder( QWidget* first, ... ) +{ + va_list wids; + va_start( wids, first ); + + QWidgetList widList; + + QWidget* cur = first; + while ( cur ) + { + widList.append( cur ); + cur = va_arg( wids, QWidget* ); + } + + setTabOrder( widList ); +} + +/*! + Name: setTabOrder [static public] + Desc: Set tab order for specified list of widgets. +*/ + +void Qtx::setTabOrder( const QWidgetList& widgets ) +{ + if ( widgets.count() < 2 ) + return; + + QWidget* prev = 0; + for ( QWidgetListIt it( widgets ); it.current(); ++it ) + { + QWidget* next = it.current(); + if ( prev && next ) + QWidget::setTabOrder( prev, next ); + prev = next; + } +} + +/*! + Name: alignWidget [static public] + Desc: Align widget 'src' relative to widget 'ref' acording to alignment flags. + Alignment flags: + Qtx::AlignLeft - Align left side of 'src' to left side of 'ref'. + Qtx::AlignRight - Align right side of 'src' to right side of 'ref'. + Qtx::AlignTop - Align top side of 'src' to top side of 'ref'. + Qtx::AlignBottom - Align bottom side of 'src' to bottom side of 'ref'. + Qtx::AlignHCenter - Align 'src' to center of 'ref' in horizontal dimension. + Qtx::AlignVCenter - Align 'src' to center of 'ref' in vertical dimension. + Qtx::AlignCenter - Align 'src' to center of 'ref' in both dimensions. + Qtx::AlignOutLeft - Align right side of 'src' to left side of 'ref'. + Qtx::AlignOutRight - Align left side of 'src' to right side of 'ref'. + Qtx::AlignOutTop - Align bottom side of 'src' to top side of 'ref'. + Qtx::AlignOutBottom - Align top side of 'src' to bottom side of 'ref'. +*/ + +void Qtx::alignWidget( QWidget* src, const QWidget* ref, const int alignFlags ) +{ + if ( !src || !ref || !alignFlags ) + return; + + QPoint srcOri = src->pos(); + QPoint refOri = ref->pos(); + if ( src->parentWidget() && !src->isTopLevel() ) + srcOri = src->parentWidget()->mapToGlobal( srcOri ); + if ( ref->parentWidget() && !ref->isTopLevel() ) + refOri = ref->parentWidget()->mapToGlobal( refOri ); + + int x = srcOri.x(), y = srcOri.y(); + int refWidth = ref->frameGeometry().width(), refHei = ref->frameGeometry().height(); + int srcWidth = src->frameGeometry().width(), srcHei = src->frameGeometry().height(); + + if ( srcWidth <= 0 ) + srcWidth = src->sizeHint().width(); + if ( srcHei <= 0 ) + srcHei = src->sizeHint().height(); + + int border = 0; + if ( ref->isTopLevel() && ref->isMaximized() && + src->isTopLevel() && !src->isMaximized() ) + border = ( src->frameGeometry().width() - src->width() ) / 2; + + if ( alignFlags & Qtx::AlignLeft ) + x = refOri.x() + border; + if ( alignFlags & Qtx::AlignOutLeft ) + x = refOri.x() - srcWidth - border; + if ( alignFlags & Qtx::AlignRight ) + x = refOri.x() + refWidth - srcWidth - border; + if ( alignFlags & Qtx::AlignOutRight ) + x = refOri.x() + refWidth + border; + if ( alignFlags & Qtx::AlignTop ) + y = refOri.y() + border; + if ( alignFlags & Qtx::AlignOutTop ) + y = refOri.y() - srcHei - border; + if ( alignFlags & Qtx::AlignBottom ) + y = refOri.y() + refHei - srcHei - border; + if ( alignFlags & Qtx::AlignOutBottom ) + y = refOri.y() + refHei + border; + if ( alignFlags & Qtx::AlignHCenter ) + x = refOri.x() + ( refWidth - srcWidth ) / 2; + if ( alignFlags & Qtx::AlignVCenter ) + y = refOri.y() + ( refHei - srcHei ) / 2; + + if ( src->parentWidget() && !src->isTopLevel() ) + { + QPoint pos = src->parentWidget()->mapFromGlobal( QPoint( x, y ) ); + x = pos.x(); + y = pos.y(); + } + + QWidget* desk = QApplication::desktop(); + if ( desk && x + srcWidth + border > desk->width() ) + x = desk->width() - srcWidth - border; + if ( desk && y + srcHei + border > desk->height() ) + y = desk->height() - srcHei - border; + + x = QMAX( x, 0 ); + y = QMAX( y, 0 ); + + src->move( x, y ); +} + +/*! + Name: simplifySeparators [static public] + Desc: Checks toolbar for unnecessary separators and removes them +*/ +void Qtx::simplifySeparators( QToolBar* toolbar ) +{ + if ( !toolbar ) + return; + + const QObjectList* objList = toolbar->children(); + if ( !objList ) + return; + + QObjectList delList; + + bool isPrevSep = true; + for ( QObjectListIt it( *objList ); it.current(); ++it ) + { + bool isSep = it.current()->isA( "QToolBarSeparator" ); + if ( isPrevSep && isSep ) + delList.append( it.current() ); + isPrevSep = isSep; + } + + for ( QObjectListIt itr( delList ); itr.current(); ++itr ) + delete itr.current(); + + if ( toolbar->children() && !toolbar->children()->isEmpty() && + toolbar->children()->getFirst()->isA( "QToolBarSeparator" ) ) + delete toolbar->children()->getFirst(); + + if ( toolbar->children() && !toolbar->children()->isEmpty() && + toolbar->children()->getLast()->isA( "QToolBarSeparator" ) ) + delete toolbar->children()->getLast(); +} + +/*! + Name: simplifySeparators [static public] + Desc: Checks popup menu recursively for unnecessary separators and removes them +*/ +void Qtx::simplifySeparators( QPopupMenu* popup, const bool recursive ) +{ + if ( !popup || !popup->count() ) + return; + + QIntList idRemove; + for ( uint i = 1; i < popup->count(); i++ ) + { + if ( popup->findItem( popup->idAt( i ) )->isSeparator() && + popup->findItem( popup->idAt( i - 1 ) )->isSeparator() ) + idRemove.append( popup->idAt( i ) ); + + if ( recursive ) + simplifySeparators( popup->findItem( popup->idAt( i ) )->popup() ); + } + + for ( QIntList::const_iterator it = idRemove.begin(); it != idRemove.end(); ++it ) + popup->removeItem( *it ); + + if ( popup->count() > 0 && popup->findItem( popup->idAt( 0 ) )->isSeparator() ) + popup->removeItem( popup->idAt( 0 ) ); + + if ( popup->count() > 0 && popup->findItem( popup->idAt( popup->count() - 1 ) )->isSeparator() ) + popup->removeItem( popup->idAt( popup->count() - 1 ) ); +} + +/*! + Name: isParent [static public] + Desc: Returns 'true' if specified 'parent' is parent object of given 'child'. +*/ +bool Qtx::isParent( QObject* child, QObject* parent ) +{ + if ( !child || !parent ) + return false; + + bool res = false; + QObject* obj = child; + while ( !res && obj ) + { + res = obj == parent; + obj = obj->parent(); + } + return res; +} + +/*! + Name: dir [static public] + Desc: Returns dir name or null string. +*/ +QString Qtx::dir( const QString& path, const bool abs ) +{ + QString dirPath = QFileInfo( path ).dirPath( abs ); + if ( dirPath == QString( "." ) ) + dirPath = QString::null; + return dirPath; +} + +/*! + Name: file [static public] + Desc: Returns file with or without extension. +*/ +QString Qtx::file( const QString& path, bool withExt ) +{ + if ( withExt ) + return QFileInfo( path ).fileName(); + else + return QFileInfo( path ).baseName(); +} + +/*! + Name: extension [static public] + Desc: Returns the file extension only or null string. +*/ +QString Qtx::extension( const QString& path ) +{ + return QFileInfo( path ).extension(false); // after the last dot +} + +/*! + Name: library [static public] + Desc: Generate library file name. + Append required prefix (lib) and suffix (.dll/.so) to the library file name. +*/ +QString Qtx::library( const QString& str ) +{ + QString path = dir( str, false ); + QString name = file( str, false ); + QString ext = extension( str ); + +#ifndef WIN32 + if ( !name.startsWith( "lib" ) ) + name = QString( "lib" ) + name; +#endif + +#ifdef WIN32 + QString libExt( "dll" ); +#else + QString libExt( "so" ); +#endif + + if ( ext.lower() != QString( "so" ) && ext.lower() != QString( "dll" ) ) + { + if ( !name.isEmpty() && !ext.isEmpty() ) + name += QString( "." ); + name += ext; + } + + ext = libExt; + + QString fileName = addSlash( path ) + name + QString( "." ) + ext; + + return fileName; +} + +/*! + Name: tmpDir [static public] + Desc: Returns path to temporary directory. +*/ +QString Qtx::tmpDir() +{ + char* tmpdir = ::getenv( "TEMP" ); + if ( !tmpdir ) + tmpdir = ::getenv ( "TMP" ); + if ( !tmpdir ) + { +#ifdef WIN32 + tmpdir = "C:\\"; +#else + tmpdir = "/tmp"; +#endif + } + return QString( tmpdir ); +} + +/*! + Name: mkDir [static public] + Desc: Creates directory with intermediate perent directories. + Returns true in successfull case. +*/ +bool Qtx::mkDir( const QString& dirPath ) +{ + QString path = QDir::convertSeparators( dirPath ); + +#ifdef WIN32 + while ( !path.isEmpty() && path.at( path.length() - 1 ) == QDir::separator() ) + path.remove( path.length() - 1, 1 ); + + if ( path.at( path.length() - 1 ) == ':' ) + return QFileInfo( path ).exists(); +#endif + + QFileInfo fInfo( path ); + if ( fInfo.exists() ) + return fInfo.isDir(); + + if ( !mkDir( fInfo.dirPath() ) ) + return false; + + return QDir( fInfo.dirPath() ).mkdir( fInfo.fileName() ); +} + +/*! + Name: rmDir [static public] + Desc: Removes directory with its subdirectories and files. + Returns true in successfull case. +*/ +bool Qtx::rmDir( const QString& thePath ) +{ + QFileInfo fi( thePath ); + if ( !fi.exists() ) + return true; + + bool stat = true; + if ( fi.isFile() ) + stat = QFile::remove( thePath ); + else if ( fi.isDir() ) + { + QDir aDir( thePath ); + const QFileInfoList* anEntries = aDir.entryInfoList(); + if ( anEntries ) + { + for ( QPtrListIterator it( *anEntries ); it.current(); ++it ) + { + if ( it.current()->fileName() == "." || it.current()->fileName() == ".." ) + continue; + stat = stat && rmDir( it.current()->absFilePath() ); + } + } + stat = stat && aDir.rmdir( thePath ); + } + return stat; +} + +/*! + Name: addSlash [static public] + Desc: Adds a slash to the end of 'path' if it is not already there. +*/ +QString Qtx::addSlash( const QString& path ) +{ + QString res = path; + if ( !res.isEmpty() && res.at( res.length() - 1 ) != QChar( '/' ) && + res.at( res.length() - 1 ) != QChar( '\\' ) ) + res += QDir::separator(); + return res; +} + +/*! + Name: dos2unix [static public] + Desc: Convert text file. Replace symbols "LF/CR" by symbol "LF". +*/ +bool Qtx::dos2unix( const QString& absName ) +{ + FILE* src = ::fopen( absName, "rb" ); + if ( !src ) + return false; + + /* we'll use temporary file */ + char temp[512] = { '\0' }; + QString dir = Qtx::dir( absName ); + FILE* tgt = ::fopen( strcpy( temp, ::tempnam( dir, "__x" ) ), "wb" ); + if ( !tgt ) + return false; + + /* temp -> result of conversion */ + const char CR = 0x0d; + const char LF = 0x0a; + bool waitingLF = false; + + while( true ) + { + int outcnt = 0; + char inbuf[512], outbuf[512]; + + /* convert buffer */ + int nbread = ::fread( inbuf, 1, sizeof( inbuf ), src ); + for ( int incnt = 0; incnt < nbread; incnt++ ) + { + if ( waitingLF ) + { + waitingLF = false; + if ( inbuf[incnt] == LF ) + outbuf[outcnt++] = LF; + else + outbuf[outcnt++] = CR; + } + else if ( inbuf[incnt] == CR ) + waitingLF = true; + else + outbuf[outcnt++] = inbuf[incnt]; + } + + /* check last sym in buffer */ + waitingLF = ( inbuf[nbread - 1] == CR ); + + /* write converted buffer to temp file */ + int nbwri = ::fwrite( outbuf, 1, outcnt, tgt ); + if ( nbwri != outcnt ) + { + ::fclose( src ); + ::fclose( tgt ); + QFile::remove( QString( temp ) ); + return false; + } + if ( nbread != sizeof( inbuf ) ) + break; /* converted ok */ + } + ::fclose( src ); + ::fclose( tgt ); + + /* rename temp -> src */ + if ( !QFile::remove( absName ) ) + return false; + + return QDir().rename( QString( temp ), absName ); +} + +/*! + Name: rgbSet [static public] + Desc: Pack the specified color into one integer RGB set. +*/ +int Qtx::rgbSet( const QColor& c ) +{ + return rgbSet( c.red(), c.green(), c.blue() ); +} + +/*! + Name: rgbSet [static public] + Desc: Pack the specified color components into one integer RGB set. +*/ +int Qtx::rgbSet( const int r, const int g, const int b ) +{ + return ( ( ( 0xff & r ) << 16 ) + ( ( 0xff & g ) << 8 ) + ( 0xff & b ) ); +} + +/*! + Name: rgbSet [static public] + Desc: Unpack the specified integer RGB set into the color. +*/ +void Qtx::rgbSet( const int rgb, QColor& c ) +{ + int r, g, b; + rgbSet( rgb, r, g, b ); + c = QColor( r, g, b ); +} + +/*! + Name: rgbSet [static public] + Desc: Unpack the specified integer RGB set into the color components. +*/ +void Qtx::rgbSet( const int rgb, int& r, int& g, int& b ) +{ + r = ( rgb >> 16 ) & 0xff; + g = ( rgb >> 8 ) & 0xff; + b = rgb & 0xff; +} + +/*! + Name: scaleColor [static public] + Desc: Returns the color specified by the index between min (blue) and max (red). +*/ +QColor Qtx::scaleColor( const int index, const int min, const int max ) +{ + static const int HUE[10] = {230, 210, 195, 180, 160, 80, 60, 50, 30, 0}; + + int hue = HUE[0]; + + if ( min != max ) + { + double aPosition = 9.0 * ( index - min ) / ( max - min ); + if ( aPosition > 0.0 ) + { + if ( aPosition >= 9.0 ) + hue = HUE[9]; + else + { + int idx = (int)aPosition; + hue = HUE[idx] + int( ( aPosition - idx ) * ( HUE[idx + 1] - HUE[idx] ) ); + } + } + } + + return QColor( hue, 255, 255, QColor::Hsv ); +} + +/*! + Name: scaleColors [static public] + Desc: Returns the 'num' number of colors from blue to red. +*/ +void Qtx::scaleColors( const int num, QValueList& lst ) +{ + lst.clear(); + for ( int i = 0; i < num; i++ ) + lst.append( scaleColor( i, 0, num - 1 ) ); +} diff --git a/src/Qtx/Qtx.h b/src/Qtx/Qtx.h new file mode 100755 index 000000000..c16bd7b23 --- /dev/null +++ b/src/Qtx/Qtx.h @@ -0,0 +1,132 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: Qtx.h +// Author: Sergey TELKOV + +#ifndef QTX_H +#define QTX_H + +#if defined QTX_EXPORTS +#if defined WIN32 +#define QTX_EXPORT _declspec( dllexport ) +#else +#define QTX_EXPORT +#endif +#else +#if defined WIN32 +#define QTX_EXPORT _declspec( dllimport ) +#else +#define QTX_EXPORT +#endif +#endif + +#if defined SOLARIS +#define bool int +#define false 0 +#define true 1 +#endif + +#ifndef INCLUDE_MENUITEM_DEF +#define INCLUDE_MENUITEM_DEF +#endif + +#include + +#ifndef QT_VERSION +#define QT_VER 0 +#else +#if QT_VERSION >= 0x30000 +#define QT_VER 3 +#else +#if QT_VERSION >= 300 +#define QT_VER 3 +#else +#if QT_VERSION >= 200 +#define QT_VER 2 +#else +#if QT_VERSION >= 100 +#define QT_VER 1 +#endif +#endif +#endif +#endif +#endif + +class QObject; +class QString; +class QWidget; +class QToolBar; +class QGroupBox; +class QPopupMenu; +class QWidgetList; + +template class QValueList; + +#if QT_VER < 3 +#define QPtrList QList +#define QPtrListIterator QListIterator +#endif + +typedef QValueList QIntList; +typedef QValueList QShortList; +typedef QValueList QDoubleList; + +class QTX_EXPORT Qtx : public Qt +{ +public: + enum AlignmentFlags + { + AlignOutLeft = AlignVCenter << 2, + AlignOutRight = AlignOutLeft << 2, + AlignOutTop = AlignOutRight << 2, + AlignOutBottom = AlignOutTop << 2 + }; + + static void setTabOrder( QWidget*, ... ); + static void setTabOrder( const QWidgetList& ); + static void alignWidget( QWidget*, const QWidget*, const int ); + + static void simplifySeparators( QToolBar* ); + static void simplifySeparators( QPopupMenu*, const bool = true ); + + static bool isParent( QObject*, QObject* ); + + static QString extension( const QString& ); + static QString dir( const QString&, const bool = true ); + static QString file( const QString&, const bool = true ); + + static QString library( const QString& ); + + static QString tmpDir(); + static bool mkDir( const QString& ); + static bool rmDir( const QString& ); + static bool dos2unix( const QString& ); + static QString addSlash( const QString& ); + + static int rgbSet( const QColor& ); + static int rgbSet( const int, const int, const int ); + + static void rgbSet( const int, QColor& ); + static void rgbSet( const int, int&, int&, int& ); + + static QColor scaleColor( const int, const int, const int ); + static void scaleColors( const int, QValueList& ); +}; + +#endif diff --git a/src/Qtx/QtxAction.cxx b/src/Qtx/QtxAction.cxx new file mode 100755 index 000000000..9fafdb7ac --- /dev/null +++ b/src/Qtx/QtxAction.cxx @@ -0,0 +1,186 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxAction.cxx +// Author: Sergey TELKOV + +#include "QtxAction.h" + +#include + +/*! + Name: QtxAction [public] + Desc: Constructs an action with given parent and name. If toggle is true the + action will be a toggle action, otherwise it will be a command action. +*/ + +QtxAction::QtxAction( QObject* parent, const char* name, bool toggle ) +: QAction( parent, name, toggle ) +{ +} + +/*! + Name: QtxAction [public] + Desc: This constructor creates an action with the following properties: the + description text, the icon or iconset icon, the menu text and keyboard + accelerator. It is a child of given parent and named specified name. + If toggle is true the action will be a toggle action, otherwise it will + be a command action. +*/ + +QtxAction::QtxAction( const QString& text, const QIconSet& icon, + const QString& menuText, int accel, + QObject* parent, const char* name, bool toggle ) +: QAction( text, icon, menuText, accel, parent, name, toggle ) +{ +} + +/*! + Name: QtxAction [public] + Desc: This constructor creates an action with the following properties: the + description text, the menu text and keyboard accelerator. It is a child + of given parent and named specified name. If toggle is true the action + will be a toggle action, otherwise it will be a command action. +*/ + +QtxAction::QtxAction( const QString& text, const QString& menuText, int accel, + QObject* parent, const char* name, bool toggle ) +: QAction( text, menuText, accel, parent, name, toggle ) +{ +} + +/*! + Name: ~QtxAction [virtual public] + Desc: Destructor. +*/ + +QtxAction::~QtxAction() +{ +} + +/*! + Name: addTo [virtual public] + Desc: Adds this action to widget. Returns true if the action was added + successfully and false otherwise. +*/ + +bool QtxAction::addTo( QWidget* w ) +{ + return QAction::addTo( w ); +} + +/*! + Name: addTo [virtual public] + Desc: Adds this action to widget. If widget is QPopupMenu given index will + be used for menu item inserting. Returns true if the action was added + successfully and false otherwise. +*/ + +bool QtxAction::addTo( QWidget* w, int index ) +{ + if ( !addTo( w ) ) + return false; + + if ( w->inherits( "QPopupMenu" ) ) + { + QPopupMenu* popup = (QPopupMenu*)w; + if ( index < (int)popup->count() - 1 ) + { + int id = popup->idAt( popup->count() - 1 ); + if ( id != -1 ) + { + QMenuItem* item = popup->findItem( id ); + if ( item && item->isSeparator() ) + { + popup->removeItem( id ); + popup->insertSeparator( index ); + } + else + { + QPopupMenu* p = item ? item->popup() : 0; + int accel = popup->accel( id ); + bool isOn = popup->isItemEnabled( id ); + QString text = popup->text( id ); + QIconSet icon; + if ( popup->iconSet( id ) ) + icon = *popup->iconSet( id ); + popup->removeItem( id ); + int pos; + if ( icon.isNull() ) + if ( p ) + pos = popup->indexOf( popup->insertItem( text, p, id, index ) ); + else + pos = popup->indexOf( popup->insertItem( text, id, index ) ); + else + if ( p ) + pos = popup->indexOf( popup->insertItem( icon, text, p, id, index ) ); + else + pos = popup->indexOf( popup->insertItem( icon, text, p, id, index ) ); + popup->setId( pos, id ); + popup->setAccel( accel, id ); + popup->setItemEnabled( id, isOn ); + if ( !p ) + popup->connectItem( id, this, SLOT( internalActivation() ) ); + } + } + } + } + + return true; +} + +/*! + Name: setPopup [virtual public] + Desc: Set or unset the sub popup menu for item with specified id in the given popup. +*/ + +void QtxAction::setPopup( QPopupMenu* popup, const int id, QPopupMenu* subPopup ) const +{ + if ( !popup ) + return; + + QMenuData* md = 0; + const QMenuData* pmd = popup; + QMenuItem* item = popup->findItem( id, &md ); + if ( !item || md != pmd ) + return; + + QPopupMenu* oldPopup = item->popup(); + if ( oldPopup == subPopup ) + return; + + int accel = popup->accel( id ); + bool isOn = popup->isItemEnabled( id ); + QString text = popup->text( id ); + QIconSet icon; + if ( popup->iconSet( id ) ) + icon = *popup->iconSet( id ); + popup->removeItem( id ); + + int pos; + if ( icon.isNull() ) + pos = popup->indexOf( subPopup ? popup->insertItem( text, subPopup ) : popup->insertItem( text ) ); + else + pos = popup->indexOf( subPopup ? popup->insertItem( icon, text, subPopup ) : popup->insertItem( icon, text ) ); + + popup->setId( pos, id ); + popup->setAccel( accel, id ); + popup->setItemEnabled( id, isOn ); + + delete oldPopup; +} diff --git a/src/Qtx/QtxAction.h b/src/Qtx/QtxAction.h new file mode 100755 index 000000000..ffffcc4d8 --- /dev/null +++ b/src/Qtx/QtxAction.h @@ -0,0 +1,46 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxAction.hxx +// Author: Sergey TELKOV + +#ifndef QTXACTION_H +#define QTXACTION_H + +#include "Qtx.h" + +#include + +class QTX_EXPORT QtxAction : public QAction +{ + Q_OBJECT + +public: + QtxAction( QObject* = 0, const char* = 0, bool = false ); + QtxAction( const QString&, const QString&, int, QObject*, const char* = 0, bool = false ); + QtxAction( const QString&, const QIconSet&, const QString&, int, QObject*, const char* = 0, bool = false ); + virtual ~QtxAction(); + + virtual bool addTo( QWidget* ); + virtual bool addTo( QWidget*, int ); + +protected: + void setPopup( QPopupMenu*, const int, QPopupMenu* ) const; +}; + +#endif diff --git a/src/Qtx/QtxActionMenuMgr.cxx b/src/Qtx/QtxActionMenuMgr.cxx new file mode 100644 index 000000000..d49bbf482 --- /dev/null +++ b/src/Qtx/QtxActionMenuMgr.cxx @@ -0,0 +1,654 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxActionMenuMgr.cxx +// Author: Alexander SOLOVYEV, Sergey TELKOV + +#include "QtxActionMenuMgr.h" + +#include "QtxAction.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +/*! + Class: QtxActionMenuMgr::MenuAction + Level: Internal +*/ + +class QtxActionMenuMgr::MenuAction : public QtxAction +{ +public: + MenuAction( const QString&, const QString&, QObject* ); + virtual ~MenuAction(); + + virtual bool addTo( QWidget* ); + + virtual bool removeFrom( QWidget* ); + + QPopupMenu* popup() const; + +private: + int myId; + QPopupMenu* myPopup; +}; + +QtxActionMenuMgr::MenuAction::MenuAction( const QString& text, const QString& menuText, QObject* parent ) +: QtxAction( text, menuText, 0, parent ), +myId( -1 ), +myPopup( 0 ) +{ + myPopup = new QPopupMenu(); +} + +QtxActionMenuMgr::MenuAction::~MenuAction() +{ + delete myPopup; +} + +bool QtxActionMenuMgr::MenuAction::addTo( QWidget* w ) +{ + if ( myId != -1 || !w ) + return false; + + if ( !w->inherits( "QPopupMenu" ) && !w->inherits( "QMenuBar" ) ) + return false; + + if ( w->inherits( "QPopupMenu" ) && QAction::addTo( w ) ) + { + QPopupMenu* pm = (QPopupMenu*)w; + myId = pm->idAt( pm->count() - 1 ); + setPopup( pm, myId, myPopup ); + } + else if ( w->inherits( "QMenuBar" ) ) + { + QMenuBar* mb = (QMenuBar*)w; + myId = iconSet().isNull() ? mb->insertItem( menuText(), myPopup ) : + mb->insertItem( iconSet(), menuText(), myPopup ); + mb->setItemEnabled( myId, isEnabled() ); + } + else + return false; + + return true; +} + +bool QtxActionMenuMgr::MenuAction::removeFrom( QWidget* w ) +{ + if ( w->inherits( "QPopupMenu" ) && QAction::removeFrom( w ) ) + myId = -1; + else if ( w->inherits( "QMenuBar" ) ) + { + QMenuBar* mb = (QMenuBar*)w; + mb->removeItem( myId ); + myId = -1; + } + + return myId == -1; +} + +QPopupMenu* QtxActionMenuMgr::MenuAction::popup() const +{ + return myPopup; +} + +/*! + Class: QtxActionMenuMgr + Level: Public +*/ + + +QtxActionMenuMgr::QtxActionMenuMgr( QMainWindow* p ) +: QtxActionMgr( p ), +myMenu( p ? p->menuBar() : 0 ) +{ + myRoot.id = -1; + myRoot.group = -1; + + if ( myMenu ) + connect( myMenu, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) ); +} + +QtxActionMenuMgr::QtxActionMenuMgr( QWidget* mw, QObject* p ) +: QtxActionMgr( p ), +myMenu( mw ) +{ + myRoot.id = -1; + myRoot.group = -1; + + if ( myMenu ) + connect( myMenu, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) ); +} + +QtxActionMenuMgr::~QtxActionMenuMgr() +{ + for ( NodeListIterator it( myRoot.children ); it.current(); ++it ) + { + QAction* a = itemAction( it.current()->id ); + if ( !a ) + a = menuAction( it.current()->id ); + + if ( a ) + a->removeFrom( myMenu ); + } + + for ( MenuMap::Iterator itr = myMenus.begin(); itr != myMenus.end(); ++itr ) + delete itr.data(); +} + +bool QtxActionMenuMgr::isVisible( const int actId, const int place ) const +{ + MenuNode* node = find( actId, place ); + return node && node->visible; +} + +void QtxActionMenuMgr::setVisible( const int actId, const int place, const bool v ) +{ + MenuNode* node = find( actId, place ); + if ( node ) + node->visible = v; +} + +int QtxActionMenuMgr::insert( const int id, const QString& menus, const int group, const int idx ) +{ + return insert( id, QStringList::split( "|", menus ), group, idx ); +} + +int QtxActionMenuMgr::insert( QAction* a, const QString& menus, const int group, const int idx ) +{ + return insert( a, QStringList::split( "|", menus ), group, idx ); +} + +int QtxActionMenuMgr::insert( const int id, const QStringList& menus, const int group, const int idx ) +{ + int pId = createMenu( menus, -1 ); + if ( pId == -1 ) + return -1; + + return insert( id, pId, group, idx ); +} + +int QtxActionMenuMgr::insert( QAction* a, const QStringList& menus, const int group, const int idx ) +{ + int pId = createMenu( menus, -1 ); + if ( pId == -1 ) + return -1; + + return insert( a, pId, group, idx ); +} + +int QtxActionMenuMgr::insert( const int id, const int pId, const int group, const int idx ) +{ + if ( id == -1 ) + return -1; + + MenuNode* pNode = pId == -1 ? &myRoot : find( pId ); + if ( !pNode ) + return -1; + + MenuNode* node = new MenuNode( pNode ); + node->id = id; + node->group = group; + + if ( idx < 0 || idx >= (int)pNode->children.count() ) + pNode->children.append( node ); + else + pNode->children.insert( idx, node ); + + updateMenu( pNode, false ); + + return node->id; +} + +int QtxActionMenuMgr::insert( QAction* a, const int pId, const int group, const int idx ) +{ + return insert( registerAction( a ), pId, group, idx ); +} + +int QtxActionMenuMgr::insert( const QString& title, const int pId, const int group, const int idx ) +{ + MenuNode* pNode = pId == -1 ? &myRoot : find( pId ); + if ( !pNode ) + return -1; + + int id = -1; + for ( NodeListIterator it( pNode->children ); it.current() && id == -1; ++it ) + { + if ( myMenus.contains( it.current()->id ) && + clearTitle( myMenus[it.current()->id]->menuText() ) == clearTitle( title ) ) + id = it.current()->id; + } + + if ( id != -1 ) + return id; + + MenuAction* ma = new MenuAction( clearTitle( title ), title, this ); + + MenuNode* node = new MenuNode( pNode ); + node->group = group; + node->id = myMenus.insert( generateId(), ma ).key(); + + if ( idx < 0 || idx >= (int)pNode->children.count() ) + pNode->children.append( node ); + else + pNode->children.insert( idx, node ); + + updateMenu( pNode, false ); + + return node->id; +} + +int QtxActionMenuMgr::insert( const QString& title, const QString& menus, const int group, const int idx ) +{ + return insert( title, QStringList::split( "|", menus ), group, idx ); +} + +int QtxActionMenuMgr::insert( const QString& title, const QStringList& menus, const int group, const int idx ) +{ + int pId = createMenu( menus, -1 ); + return insert( title, pId, group, idx ); +} + +int QtxActionMenuMgr::append( const QString& title, const int pId, const int group ) +{ + return insert( title, pId, group ); +} + +int QtxActionMenuMgr::append( const int id, const int pId, const int group ) +{ + return insert( id, pId, group ); +} + +int QtxActionMenuMgr::append( QAction* a, const int pId, const int group ) +{ + return insert( a, pId, group ); +} + +int QtxActionMenuMgr::prepend( const QString& title, const int pId, const int group ) +{ + return insert( title, pId, group, 0 ); +} + +int QtxActionMenuMgr::prepend( const int id, const int pId, const int group ) +{ + return insert( id, pId, group, 0 ); +} + +int QtxActionMenuMgr::prepend( QAction* a, const int pId, const int group ) +{ + return insert( a, pId, group, 0 ); +} + +void QtxActionMenuMgr::remove( const int id ) +{ + removeMenu( id, 0 ); + update(); +} + +void QtxActionMenuMgr::remove( const int id, const int pId, const int group ) +{ + MenuNode* pNode = find( pId ); + if ( !pNode ) + return; + + NodeList delNodes; + for ( NodeListIterator it( pNode->children ); it.current(); ++it ) + { + if ( it.current()->id == id && ( it.current()->group == group || group == -1 ) ) + delNodes.append( it.current() ); + } + + for ( NodeListIterator itr( delNodes ); itr.current(); ++itr ) + pNode->children.remove( itr.current() ); + + updateMenu( pNode, false ); +} + +void QtxActionMenuMgr::show( const int id ) +{ + setShown( id, true ); +} + +void QtxActionMenuMgr::hide( const int id ) +{ + setShown( id, false ); +} + +bool QtxActionMenuMgr::isShown( const int id ) const +{ + bool res = false; + MenuNode* node = find( id ); + if ( node ) + res = node->visible; + return res; +} + +void QtxActionMenuMgr::setShown( const int id, const bool on ) +{ + NodeList aNodes; + find( id, aNodes ); + + QMap updMap; + for ( NodeListIterator it( aNodes ); it.current(); ++it ) + { + if ( it.current()->visible != on ) + { + it.current()->visible = on; + updMap.insert( it.current()->parent, 0 ); + } + } + + for ( QMap::ConstIterator itr = updMap.begin(); itr != updMap.end(); ++itr ) + updateMenu( itr.key(), false ); +} + +void QtxActionMenuMgr::onDestroyed( QObject* obj ) +{ + if ( myMenu == obj ) + myMenu = 0; +} + +void QtxActionMenuMgr::setWidget( QWidget* mw ) +{ + if ( myMenu == mw ) + return; + + if ( myMenu ) + disconnect( myMenu, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) ); + + myMenu = mw; + + if ( myMenu ) + connect( myMenu, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) ); +} + +QtxActionMenuMgr::MenuNode* QtxActionMenuMgr::find( const int actId, const int pId ) const +{ + return find( actId, find( pId ) ); +} + +QtxActionMenuMgr::MenuNode* QtxActionMenuMgr::find( const int id, MenuNode* startNode ) const +{ + MenuNode* node = 0; + MenuNode* start = startNode ? startNode : (MenuNode*)&myRoot; + for ( NodeListIterator it( start->children ); it.current() && !node; ++it ) + { + if ( it.current()->id == id ) + node = it.current(); + else + node = find( id, it.current() ); + } + return node; +} + +bool QtxActionMenuMgr::find( const int id, NodeList& lst, MenuNode* startNode ) const +{ + MenuNode* start = startNode ? startNode : (MenuNode*)&myRoot; + for ( NodeListIterator it( start->children ); it.current(); ++it ) + { + if ( it.current()->id == id ) + lst.prepend( it.current() ); + + find( id, lst, it.current() ); + } + return !lst.isEmpty(); +} + +void QtxActionMenuMgr::removeMenu( const int id, MenuNode* startNode ) +{ + MenuNode* start = startNode ? startNode : &myRoot; + for ( NodeListIterator it( start->children ); it.current(); ++it ) + { + if ( it.current()->id == id ) + start->children.remove( it.current() ); + else + removeMenu( id, it.current() ); + } +} + +QAction* QtxActionMenuMgr::itemAction( const int id ) const +{ + return action( id ); +} + +QtxActionMenuMgr::MenuAction* QtxActionMenuMgr::menuAction( const int id ) const +{ + MenuAction* a = 0; + + if ( myMenus.contains( id ) ) + a = myMenus[id]; + + return a; +} + +void QtxActionMenuMgr::updateMenu( MenuNode* startNode, const bool rec, const bool updParent ) +{ + if ( !isUpdatesEnabled() ) + return; + + MenuNode* node = startNode ? startNode : &myRoot; + + QWidget* mw = menuWidget( node ); + if ( !mw ) + return; + + bool filled = checkWidget( mw ); + + for ( NodeListIterator it1( node->children ); it1.current(); ++it1 ) + { + QAction* a = itemAction( it1.current()->id ); + if ( !a ) + a = menuAction( it1.current()->id ); + + if ( a ) + a->removeFrom( mw ); + } + + if ( node != &myRoot ) + { + if ( mw->inherits( "QMenuBar" ) ) + ((QMenuBar*)mw)->clear(); + else if ( mw->inherits( "QPopupMenu" ) ) + ((QPopupMenu*)mw)->clear(); + } + + QMap idMap; + for ( NodeListIterator it2( node->children ); it2.current(); ++it2 ) + { + MenuNode* par = it2.current()->parent; + if ( isVisible( it2.current()->id, par ? par->id : -1 ) ) + { + NodeList& lst = idMap[it2.current()->group]; + lst.append( it2.current() ); + } + } + + QIntList groups = idMap.keys(); + qHeapSort( groups ); + + groups.remove( -1 ); + groups.append( -1 ); + + for ( QIntList::const_iterator gIt = groups.begin(); gIt != groups.end(); ++gIt ) + { + if ( !idMap.contains( *gIt ) ) + continue; + + const NodeList& lst = idMap[*gIt]; + for ( NodeListIterator iter( lst ); iter.current(); ++iter ) + { + if ( rec ) + updateMenu( iter.current(), rec, false ); + + QAction* a = itemAction( iter.current()->id ); + if ( a ) + a->addTo( mw ); + else + { + MenuAction* ma = menuAction( iter.current()->id ); + if ( ma && ma->popup() && ma->popup()->count() ) + ma->addTo( mw ); + } + } + } + + simplifySeparators( mw ); + + if ( updParent && node->parent && filled != checkWidget( mw ) ) + updateMenu( node->parent, false ); +} + +void QtxActionMenuMgr::internalUpdate() +{ + if ( isUpdatesEnabled() ) + updateMenu(); +} + +bool QtxActionMenuMgr::checkWidget( QWidget* wid ) const +{ + if ( !wid ) + return false; + + QMenuData* md = 0; + if ( wid->inherits( "QPopupMenu" ) ) + md = (QPopupMenu*)wid; + else if ( wid->inherits( "QMenuBar" ) ) + md = (QMenuBar*)wid; + + return md->count(); +} + +QWidget* QtxActionMenuMgr::menuWidget( MenuNode* node) const +{ + if ( !node || node == &myRoot ) + return myMenu; + + if ( !myMenus.contains( node->id ) || !myMenus[node->id] ) + return 0; + + return myMenus[node->id]->popup(); +} + +void QtxActionMenuMgr::simplifySeparators( QWidget* wid ) +{ + if ( wid && wid->inherits( "QPopupMenu" ) ) + Qtx::simplifySeparators( (QPopupMenu*)wid, false ); +} + +QString QtxActionMenuMgr::clearTitle( const QString& txt ) const +{ + QString res = txt; + + for ( int i = 0; i < (int)res.length(); i++ ) + { + if ( res.at( i ) == '&' ) + res.remove( i--, 1 ); + } + + return res; +} + +int QtxActionMenuMgr::createMenu( const QStringList& lst, const int pId ) +{ + if ( lst.isEmpty() ) + return -1; + + QStringList sl( lst ); + + QString title = sl.last().stripWhiteSpace(); + sl.remove( sl.fromLast() ); + + int parentId = sl.isEmpty() ? pId : createMenu( sl, pId ); + + return insert( title, parentId, -1 ); +} + +bool QtxActionMenuMgr::load( const QString& fname, QtxActionMgr::Reader& r ) +{ + MenuCreator cr( &r, this ); + return r.read( fname, cr ); +} + + +/*! + Class: QtxActionMenuMgr::MenuCreator + Level: Public +*/ + +QtxActionMenuMgr::MenuCreator::MenuCreator( QtxActionMgr::Reader* r, + QtxActionMenuMgr* mgr ) +: QtxActionMgr::Creator( r ), + myMgr( mgr ) +{ +} + +QtxActionMenuMgr::MenuCreator::~MenuCreator() +{ +} + +int QtxActionMenuMgr::MenuCreator::append( const QString& tag, const bool subMenu, + const ItemAttributes& attr, const int pId ) +{ + if( !myMgr || !reader() ) + return -1; + + QString label = reader()->option( "label", "label" ), + id = reader()->option( "id", "id" ), + pos = reader()->option( "pos", "pos" ), + group = reader()->option( "group", "group" ), + tooltip = reader()->option( "tooltip", "tooltip" ), + sep = reader()->option( "separator", "separator" ), + accel = reader()->option( "accel", "accel" ), + icon = reader()->option( "icon", "icon" ), + toggle = reader()->option( "toggle", "toggle" ); + + int res = -1, actId = intValue( attr, id, -1 ); + + if( subMenu ) + res = myMgr->insert( strValue( attr, label ), pId, intValue( attr, group, 0 ), intValue( attr, pos, -1 ) ); + else if( tag==sep ) + res = myMgr->insert( separator(), pId, intValue( attr, group, 0 ), intValue( attr, pos, -1 ) ); + else + { + QPixmap pix; QIconSet set; + QString name = strValue( attr, icon ); + if( !name.isEmpty() && loadPixmap( name, pix ) ) + set = QIconSet( pix ); + + QtxAction* newAct = new QtxAction( strValue( attr, tooltip ), set, + strValue( attr, label ), + QKeySequence( strValue( attr, accel ) ), + myMgr ); + newAct->setToolTip( strValue( attr, tooltip ) ); + QString toggleact = strValue( attr, toggle ); + newAct->setToggleAction( !toggleact.isEmpty() ); + newAct->setOn( toggleact.lower()=="true" ); + + connect( newAct ); + int aid = myMgr->registerAction( newAct, actId ); + res = myMgr->insert( aid, pId, intValue( attr, group, 0 ), intValue( attr, pos, -1 ) ); + } + + return res; +} diff --git a/src/Qtx/QtxActionMenuMgr.h b/src/Qtx/QtxActionMenuMgr.h new file mode 100644 index 000000000..89b81aa89 --- /dev/null +++ b/src/Qtx/QtxActionMenuMgr.h @@ -0,0 +1,152 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxActionMenuMgr.h +// Author: Alexander SOLOVYEV, Sergey TELKOV + +#ifndef QTXACTIONMENUMGR_H +#define QTXACTIONMENUMGR_H + +#include "Qtx.h" +#include "QtxActionMgr.h" + +#include +#include + +class QPopupMenu; +class QMainWindow; + +#ifdef WIN32 +#pragma warning( disable:4251 ) +#endif + +class QTX_EXPORT QtxActionMenuMgr : public QtxActionMgr +{ + Q_OBJECT + + class MenuNode; + + typedef QPtrList NodeList; + typedef QPtrListIterator NodeListIterator; + + class MenuNode + { + public: + MenuNode() : parent( 0 ), visible( true ) { children.setAutoDelete( true ); }; + MenuNode( MenuNode* p ) : parent( p ), visible( true ) { children.setAutoDelete( true ); }; + + int id; + int group; + MenuNode* parent; + bool visible; + NodeList children; + }; + + class MenuAction; + +protected: + class MenuCreator; + +public: + QtxActionMenuMgr( QMainWindow* ); + QtxActionMenuMgr( QWidget*, QObject* ); + virtual ~QtxActionMenuMgr(); + + virtual bool isVisible( const int, const int ) const; + virtual void setVisible( const int, const int, const bool ); + + int insert( const int, const QString&, const int, const int = -1 ); + int insert( QAction*, const QString&, const int, const int = -1 ); + + int insert( const int, const QStringList&, const int, const int = -1 ); + int insert( QAction*, const QStringList&, const int, const int = -1 ); + + virtual int insert( const int, const int, const int, const int = -1 ); + int insert( QAction*, const int, const int, const int = -1 ); + + int insert( const QString&, const QString&, const int, const int = -1 ); + int insert( const QString&, const QStringList&, const int, const int = -1 ); + virtual int insert( const QString&, const int, const int, const int = -1 ); + + int append( const int, const int, const int ); + int append( QAction*, const int, const int ); + int append( const QString&, const int, const int ); + + int prepend( const int, const int, const int ); + int prepend( QAction*, const int, const int ); + int prepend( const QString&, const int, const int ); + + void remove( const int ); + void remove( const int, const int, const int = -1 ); + + void show( const int ); + void hide( const int ); + + bool isShown( const int ) const; + void setShown( const int, const bool ); + + virtual bool load( const QString&, QtxActionMgr::Reader& ); + +private slots: + void onDestroyed( QObject* ); + +protected: + void setWidget( QWidget* ); + MenuNode* find( const int, const int ) const; + MenuNode* find( const int, MenuNode* = 0 ) const; + bool find( const int, NodeList&, MenuNode* = 0 ) const; + + void removeMenu( const int, MenuNode* ); + + QAction* itemAction( const int ) const; + MenuAction* menuAction( const int ) const; + + void updateMenu( MenuNode* = 0, const bool = true, const bool = true ); + virtual void internalUpdate(); + +private: + bool checkWidget( QWidget* ) const; + QWidget* menuWidget( MenuNode* ) const; + void simplifySeparators( QWidget* ); + QString clearTitle( const QString& ) const; + int createMenu( const QStringList&, const int ); + +private: + typedef QMap MenuMap; + +private: + MenuNode myRoot; + QWidget* myMenu; + MenuMap myMenus; +}; + +class QtxActionMenuMgr::MenuCreator : public QtxActionMgr::Creator +{ +public: + MenuCreator( QtxActionMgr::Reader*, QtxActionMenuMgr* ); + virtual ~MenuCreator(); + + virtual int append( const QString&, const bool, + const ItemAttributes&, const int ); + +private: + QtxActionMenuMgr* myMgr; +}; + + +#endif diff --git a/src/Qtx/QtxActionMgr.cxx b/src/Qtx/QtxActionMgr.cxx new file mode 100644 index 000000000..16ec7b5b1 --- /dev/null +++ b/src/Qtx/QtxActionMgr.cxx @@ -0,0 +1,505 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxActionMgr.cxx +// Author: Alexander SOLOVYEV, Sergey TELKOV + +#include "Qtx.h" +#include "QtxActionMgr.h" +#include "QtxAction.h" + +#include +#include +#include +#include +#include +#include +#include + +static QAction* qtx_separator_action = 0; + +void qtxSeparatorActionCleanup() +{ + delete qtx_separator_action; + qtx_separator_action = 0; +} + +/*! + Class: QtxActionMenuMgr::SeparatorAction + Level: Internal +*/ + +class QtxActionMgr::SeparatorAction : public QtxAction +{ +public: + SeparatorAction( QObject* = 0 ); + virtual ~SeparatorAction(); + + virtual bool addTo( QWidget* ); + virtual bool removeFrom( QWidget* ); + +private: + QMap myMenus; + QMap myTools; +}; + +QtxActionMgr::SeparatorAction::SeparatorAction( QObject* parent ) +: QtxAction( parent ) +{ +} + +QtxActionMgr::SeparatorAction::~SeparatorAction() +{ +} + +bool QtxActionMgr::SeparatorAction::addTo( QWidget* wid ) +{ + if ( !wid ) + return false; + + bool res = true; + if ( wid->inherits( "QPopupMenu" ) ) + { + QPopupMenu* popup = (QPopupMenu*)wid; + myMenus[popup].append( popup->insertSeparator() ); + } + else if ( wid->inherits( "QToolBar" ) ) + { + QToolBar* tb = (QToolBar*)wid; + tb->addSeparator(); + myTools[tb].append( (QWidget*)tb->children()->getLast() ); + } + else + res = false; + + return res; +} + +bool QtxActionMgr::SeparatorAction::removeFrom( QWidget* wid ) +{ + if ( !wid ) + return false; + + bool res = true; + if ( wid->inherits( "QPopupMenu" ) ) + { + QPopupMenu* popup = (QPopupMenu*)wid; + if ( myMenus.contains( popup ) ) + { + const QIntList& list = myMenus[popup]; + for ( QIntList::const_iterator it = list.begin(); it != list.end(); ++it ) + popup->removeItem( *it ); + + myMenus.remove( popup ); + } + } + else if ( wid->inherits( "QToolBar" ) ) + { + QToolBar* tb = (QToolBar*)wid; + if ( myTools.contains( tb ) ) + { + QMap childMap; + if ( tb->children() ) + { + for ( QObjectListIt it( *tb->children() ); it.current(); ++it ) + childMap.insert( it.current(), 0 ); + } + const QWidgetList& list = myTools[tb]; + for ( QWidgetListIt it( list ); it.current(); ++it ) + { + if ( childMap.contains( it.current() ) ) + delete it.current(); + } + + myTools.remove( tb ); + } + } + else + res = false; + + return res; +} + +/*! + Class: QtxActionMgr + Level: Public +*/ + +QtxActionMgr::QtxActionMgr( QObject* parent ) +: QObject( parent ), +myUpdate( true ) +{ +} + +QtxActionMgr::~QtxActionMgr() +{ +} + +int QtxActionMgr::registerAction( QAction* a, const int userId ) +{ + if ( !a ) + return -1; + + int theId = userId < 0 ? generateId() : userId; + + if ( contains( theId ) ) + unRegisterAction( theId ); + + int cur = actionId( a ); + if ( cur != -1 ) + { + if ( userId == -1 ) + return cur; + else + unRegisterAction( cur ); + } + + myActions.insert( theId, a ); + + return theId; +} + +void QtxActionMgr::unRegisterAction( const int id ) +{ + if( contains( id ) ) + myActions.remove( id ); +} + +QAction* QtxActionMgr::action( const int id ) const +{ + if ( contains( id ) ) + return myActions[ id ]; + else + return 0; +} + +int QtxActionMgr::actionId( const QAction* a ) const +{ + if ( !a ) + return -1; + + int theId = -1; + for ( ActionMap::ConstIterator it = myActions.begin(); it != myActions.end() && theId == -1; ++it ) + { + if ( it.data() == a ) + theId = it.key(); + } + + return theId; +} + +bool QtxActionMgr::contains( const int id ) const +{ + return myActions.contains( id ); +} + +int QtxActionMgr::count() const +{ + return myActions.count(); +} + +bool QtxActionMgr::isEmpty() const +{ + return myActions.isEmpty(); +} + +void QtxActionMgr::idList( QIntList& lst ) const +{ + lst = myActions.keys(); +} + +bool QtxActionMgr::isUpdatesEnabled() const +{ + return myUpdate; +} + +void QtxActionMgr::setUpdatesEnabled( const bool upd ) +{ + myUpdate = upd; +} + +bool QtxActionMgr::isVisible( const int, const int ) const +{ + return true; +} + +void QtxActionMgr::setVisible( const int, const int, const bool ) +{ +} + +void QtxActionMgr::update() +{ + if ( isUpdatesEnabled() ) + internalUpdate(); +} + +void QtxActionMgr::internalUpdate() +{ +} + +int QtxActionMgr::generateId() const +{ + static int id = -1; + return --id; +} + +bool QtxActionMgr::isEnabled( const int id ) const +{ + QAction* a = action( id ); + if ( a ) + return a->isEnabled(); + else + return false; +} + +void QtxActionMgr::setEnabled( const int id, const bool en ) +{ + QAction* a = action( id ); + if ( a ) + a->setEnabled( en ); +} + +QAction* QtxActionMgr::separator( const bool individual ) +{ + if ( individual ) + return new SeparatorAction(); + + if ( !qtx_separator_action ) + { + qtx_separator_action = new SeparatorAction(); + qAddPostRoutine( qtxSeparatorActionCleanup ); + } + return qtx_separator_action; +} + +/*! + Class: QtxActionMgr::Reader + Level: Public +*/ + +QtxActionMgr::Reader::Reader() +{ +} + +QtxActionMgr::Reader::~Reader() +{ +} + +QStringList QtxActionMgr::Reader::options() const +{ + return myOptions.keys(); +} + +QString QtxActionMgr::Reader::option( const QString& name, const QString& def ) const +{ + if( myOptions.contains( name ) ) + return myOptions[ name ]; + else + return def; +} + +void QtxActionMgr::Reader::setOption( const QString& name, const QString& value ) +{ + myOptions[ name ] = value; +} + + +/*! + Class: QtxActionMgr::XMLReader + Level: Public +*/ +QtxActionMgr::XMLReader::XMLReader( const QString& root, + const QString& item, + const QString& dir ) +: Reader() +{ + setOption( QString( "root_tag" ), root ); + setOption( QString( "menu_item" ), item ); + setOption( QString( "icons_dir" ), dir ); + setOption( QString( "id" ), QString( "item-id" ) ); + setOption( QString( "pos" ), QString( "pos-id" ) ); + setOption( QString( "group" ), QString( "group-id" ) ); + setOption( QString( "label" ), QString( "label-id" ) ); + setOption( QString( "tooltip" ), QString( "tooltip-id" ) ); + setOption( QString( "accel" ), QString( "accel-id" ) ); + setOption( QString( "separator" ), QString( "separator" ) ); + setOption( QString( "icon" ), QString( "icon-id" ) ); + setOption( QString( "toggle" ), QString( "toggle-id" ) ); +} + +QtxActionMgr::XMLReader::~XMLReader() +{ +} + +bool QtxActionMgr::XMLReader::read( const QString& fname, Creator& cr ) const +{ + bool res = false; + +#ifndef QT_NO_DOM + + QFile file( fname ); + if ( !file.open( IO_ReadOnly ) ) + return res; + + QDomDocument doc; + + res = doc.setContent( &file ); + file.close(); + + if ( !res ) + return res; + + QString root = option( "root_tag" ); + for( QDomNode cur = doc.documentElement(); !cur.isNull(); ) + { + if( cur.isElement() && isNodeSimilar( cur, root ) ) + read( cur, -1, cr ); + else if( cur.hasChildNodes() ) + { + cur = cur.firstChild(); + continue; + } + + while( !cur.isNull() && cur.nextSibling().isNull() ) + cur = cur.parentNode(); + if( !cur.isNull() ) + cur = cur.nextSibling(); + } + +#endif + + return res; +} + +void QtxActionMgr::XMLReader::read( const QDomNode& parent_node, + const int parent_id, + Creator& cr ) const +{ + if( parent_node.isNull() ) + return; + + QStringList items = QStringList::split( "|", option( QString( "menu_item" ) ) ); + + const QDomNodeList& children = parent_node.childNodes(); + for( int i=0, n=children.count(); i0; + for( int i=0, n=temp_map.count(); ioption( "icons_dir", "." ) ); + QStringList::const_iterator anIt = dirlist.begin(), + aLast = dirlist.end(); + bool res = false; + for( ; anIt!=aLast && !res; anIt++ ) + res = pix.load( Qtx::addSlash( *anIt ) + fname ); + + return res; +} diff --git a/src/Qtx/QtxActionMgr.h b/src/Qtx/QtxActionMgr.h new file mode 100644 index 000000000..4cd9f2e38 --- /dev/null +++ b/src/Qtx/QtxActionMgr.h @@ -0,0 +1,146 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxActionMgr.h +// Author: Alexander SOLOVYEV, Sergey TELKOV + +#ifndef QTXACTIONMGR_H +#define QTXACTIONMGR_H + +#include "Qtx.h" + +#include +#include + +class QAction; +class QDomNode; + + +#ifdef WIN32 +#pragma warning( disable:4251 ) +#endif + +class QTX_EXPORT QtxActionMgr : public QObject +{ + Q_OBJECT + + class SeparatorAction; + +public: + class Reader; + class XMLReader; + +protected: + class Creator; + +public: + QtxActionMgr( QObject* parent ); + virtual ~QtxActionMgr(); + + virtual int registerAction( QAction*, const int = -1 ); + virtual void unRegisterAction( const int ); + + QAction* action( const int ) const; + int actionId( const QAction* ) const; + bool contains( const int ) const; + + int count() const; + bool isEmpty() const; + void idList( QIntList& ) const; + + bool isUpdatesEnabled() const; + virtual void setUpdatesEnabled( const bool ); + + virtual bool isVisible( const int, const int ) const; + virtual void setVisible( const int, const int, const bool ); + + void update(); + + virtual bool isEnabled( const int ) const; + virtual void setEnabled( const int, const bool ); + + static QAction* separator( const bool = false ); + +protected: + virtual void internalUpdate(); + int generateId() const; + +private: + typedef QMap ActionMap; + +private: + bool myUpdate; + ActionMap myActions; +}; + + +QTX_EXPORT typedef QMap ItemAttributes; + +class QtxActionMgr::Creator +{ +public: + Creator( QtxActionMgr::Reader* ); + virtual ~Creator(); + + Reader* reader() const; + + virtual int append( const QString&, const bool, + const ItemAttributes&, const int ) = 0; + virtual void connect( QAction* ) const; + + virtual bool loadPixmap( const QString&, QPixmap& ) const; + +protected: + static int intValue( const ItemAttributes&, const QString&, const int ); + static QString strValue( const ItemAttributes&, const QString&, + const QString& = QString::null ); +private: + QtxActionMgr::Reader* myReader; +}; + +class QtxActionMgr::Reader +{ +public: + QTX_EXPORT Reader(); + QTX_EXPORT virtual ~Reader(); + + QTX_EXPORT QStringList options() const; + QTX_EXPORT QString option( const QString&, const QString& = QString::null ) const; + QTX_EXPORT void setOption( const QString&, const QString& ); + + QTX_EXPORT virtual bool read( const QString&, Creator& ) const = 0; + +private: + QMap< QString, QString > myOptions; +}; + +class QtxActionMgr::XMLReader : public Reader +{ +public: + QTX_EXPORT XMLReader( const QString&, const QString&, const QString& ); + QTX_EXPORT virtual ~XMLReader(); + + QTX_EXPORT virtual bool read( const QString&, Creator& ) const; + +protected: + QTX_EXPORT virtual void read( const QDomNode&, const int, Creator& ) const; + QTX_EXPORT virtual bool isNodeSimilar( const QDomNode&, const QString& ) const; +}; + + +#endif diff --git a/src/Qtx/QtxActionToolMgr.cxx b/src/Qtx/QtxActionToolMgr.cxx new file mode 100644 index 000000000..f797306f0 --- /dev/null +++ b/src/Qtx/QtxActionToolMgr.cxx @@ -0,0 +1,445 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxActionToolMgr.cxx +// Author: Alexander SOLOVYEV, Sergey TELKOV + +#include "QtxActionToolMgr.h" + +#include "QtxAction.h" +#include "QtxToolBar.h" + +#include +#include + +QtxActionToolMgr::QtxActionToolMgr( QMainWindow* p ) +: QtxActionMgr( p ), +myMainWindow( p ) +{ +} + +QtxActionToolMgr::~QtxActionToolMgr() +{ +} + +QMainWindow* QtxActionToolMgr::mainWindow() const +{ + return myMainWindow; +} + +int QtxActionToolMgr::createToolBar( const QString& name, const int tid ) +{ + static int _toolBarId = -1; + + int tbId = -1; + for ( ToolBarMap::ConstIterator it = myToolBars.begin(); it != myToolBars.end() && tbId == -1; ++it ) + { + if ( it.data().toolBar->label().lower() == name.lower() ) + tbId = it.key(); + } + + if ( tbId != -1 ) + return tbId; + + QToolBar* tb = find( name, mainWindow() ); + + tbId = tid < 0 ? --_toolBarId : tid; + + myToolBars.insert( tbId, ToolBarInfo() ); + ToolBarInfo& tInfo = myToolBars[tbId]; + + if ( !tb ) + { + tb = new QtxToolBar( true, mainWindow() ); + tb->setLabel( name ); + } + + tInfo.toolBar = tb; + connect( tInfo.toolBar, SIGNAL( destroyed() ), this, SLOT( onToolBarDestroyed() ) ); + + return tbId; +} + +QToolBar* QtxActionToolMgr::find( const QString& label, QMainWindow* mw ) const +{ + if ( !mw ) + return 0; + + QString pattern = label.lower(); + + QToolBar* res = 0; + QPtrList lst = mw->dockWindows(); + for ( QPtrListIterator it( lst ); it.current() && !res; ++it ) + { + if ( !it.current()->inherits( "QToolBar" ) ) + continue; + + QToolBar* cur = (QToolBar*)it.current(); + if ( cur->label().lower() == pattern ) + res = cur; + } + return res; +} + +void QtxActionToolMgr::removeToolBar( const int tid ) +{ + if ( !myToolBars.contains( tid ) ) + return; + + delete myToolBars[tid].toolBar; + myToolBars.remove( tid ); +} + +void QtxActionToolMgr::removeToolBar( const QString& tname ) +{ + removeToolBar( find( tname ) ); +} + +int QtxActionToolMgr::insert( const int id, const int tid, const int idx ) +{ + if ( !contains( id ) || !hasToolBar( tid ) ) + return -1; + + ToolNode node; + node.id = id; + + NodeList& list = myToolBars[tid].nodes; + int index = idx < 0 ? list.count() : QMIN( idx, (int)list.count() ); + list.insert( list.at( index ), node ); + updateToolBar( tid ); + + return id; +} + +int QtxActionToolMgr::insert( QAction* act, const int tid, const int pos ) +{ + return insert( registerAction( act ), tid, pos ); +} + +int QtxActionToolMgr::insert( const int id, const QString& tname, const int pos ) +{ + return insert( id, createToolBar( tname ), pos ); +} + +int QtxActionToolMgr::insert( QAction* act, const QString& tname, const int pos ) +{ + return insert( registerAction( act ), createToolBar( tname ), pos ); +} + +int QtxActionToolMgr::append( const int id, const int tid ) +{ + return insert( id, tid ); +} + +int QtxActionToolMgr::append( QAction* act, const int tid ) +{ + return insert( act, tid ); +} + +int QtxActionToolMgr::append( const int id, const QString& tname ) +{ + return insert( id, tname ); +} + +int QtxActionToolMgr::append( QAction* act, const QString& tname ) +{ + return insert( act, tname ); +} + +int QtxActionToolMgr::prepend( const int id, const int tid ) +{ + return insert( id, tid, 0 ); +} + +int QtxActionToolMgr::prepend( QAction* act, const int tid ) +{ + return insert( act, tid, 0 ); +} + +int QtxActionToolMgr::prepend( const int id, const QString& tname ) +{ + return insert( id, tname, 0 ); +} + +int QtxActionToolMgr::prepend( QAction* act, const QString& tname ) +{ + return insert( act, tname, 0 ); +} + +void QtxActionToolMgr::remove( const int id, const int tid ) +{ + if ( !myToolBars.contains( tid ) ) + return; + + NodeList newList; + const NodeList& nodes = myToolBars[tid].nodes; + for ( NodeList::const_iterator it = nodes.begin(); it != nodes.end(); ++it ) + { + if ( (*it).id != id ) + newList.append( *it ); + } + + myToolBars[tid].nodes = newList; + + updateToolBar( tid ); +} + +void QtxActionToolMgr::remove( const int id, const QString& tname ) +{ + remove( id, find( tname ) ); +} + +QToolBar* QtxActionToolMgr::toolBar( const int tid ) const +{ + QToolBar* tb = 0; + if ( myToolBars.contains( tid ) ) + tb = myToolBars[tid].toolBar; + return tb; +} + +QToolBar* QtxActionToolMgr::toolBar( const QString& tname ) const +{ + return toolBar( find( tname ) ); +} + +bool QtxActionToolMgr::hasToolBar( const int tid ) const +{ + return myToolBars.contains( tid ); +} + +bool QtxActionToolMgr::hasToolBar( const QString& tname ) const +{ + return find( tname ) != -1; +} + +void QtxActionToolMgr::onToolBarDestroyed() +{ + myToolBars.remove( find( (QToolBar*)sender() ) ); +} + +int QtxActionToolMgr::find( const QString& tname ) const +{ + int id = -1; + for ( ToolBarMap::ConstIterator it = myToolBars.begin(); it != myToolBars.end() && id == -1; ++it ) + { + if ( it.data().toolBar->label() == tname ) + id = it.key(); + } + return id; +} + +int QtxActionToolMgr::find( QToolBar* t ) const +{ + int id = -1; + for ( ToolBarMap::ConstIterator it = myToolBars.begin(); it != myToolBars.end() && id == -1; ++it ) + { + if ( it.data().toolBar == t ) + id = it.key(); + } + return id; +} + +void QtxActionToolMgr::updateToolBar( const int tId ) +{ + if ( !isUpdatesEnabled() ) + return; + + if ( !myToolBars.contains( tId ) ) + return; + + QToolBar* tb = myToolBars[tId].toolBar; + const NodeList& list = myToolBars[tId].nodes; + + for ( NodeList::const_iterator it = list.begin(); it != list.end(); ++it ) + { + QAction* a = action( (*it).id ); + if ( a ) + a->removeFrom( tb ); + } + + tb->clear(); + + for ( NodeList::const_iterator itr = list.begin(); itr != list.end(); ++itr ) + { + if ( !isVisible( (*itr).id, tId ) ) + continue; + + QAction* a = action( (*itr).id ); + if ( a ) + a->addTo( tb ); + } + + simplifySeparators( tb ); +} + +void QtxActionToolMgr::internalUpdate() +{ + for ( ToolBarMap::ConstIterator it1 = myToolBars.begin(); it1 != myToolBars.end(); ++it1 ) + updateToolBar( it1.key() ); +} + +void QtxActionToolMgr::simplifySeparators( QToolBar* t ) +{ + if ( t ) + Qtx::simplifySeparators( t ); +} + +void QtxActionToolMgr::show( const int actId ) +{ + setShown( actId, true ); +} + +void QtxActionToolMgr::hide( const int actId ) +{ + setShown( actId, false ); +} + +void QtxActionToolMgr::setShown( const int id, const bool on ) +{ + for ( ToolBarMap::Iterator it = myToolBars.begin(); it != myToolBars.end(); ++it ) + setVisible( id, it.key(), on ); +} + +bool QtxActionToolMgr::isShown( const int id ) const +{ + QPtrList nodes; + for ( ToolBarMap::ConstIterator it = myToolBars.begin(); it != myToolBars.end(); ++it ) + { + const NodeList& nl = it.data().nodes; + for ( NodeList::const_iterator itr = nl.begin(); itr != nl.end(); ++itr ) + { + const ToolNode& node = *itr; + if ( node.id == id ) + nodes.append( &node ); + } + } + + if ( nodes.isEmpty() ) + return false; + + bool vis = true; + for ( QPtrListIterator itr( nodes ); itr.current() && vis; ++itr ) + vis = itr.current()->visible; + + return vis; +} + +bool QtxActionToolMgr::isVisible( const int id, const int tId ) const +{ + if ( !myToolBars.contains( tId ) ) + return false; + + bool vis = false; + const NodeList& lst = myToolBars[tId].nodes; + for ( NodeList::const_iterator it = lst.begin(); it != lst.end() && !vis; ++it ) + { + const ToolNode& node = *it; + if ( node.id == id ) + vis = node.visible; + } + return vis; +} + +void QtxActionToolMgr::setVisible( const int id, const int tId, const bool on ) +{ + if ( !myToolBars.contains( tId ) ) + return; + + bool changed = false; + NodeList& lst = myToolBars[tId].nodes; + for ( NodeList::iterator it = lst.begin(); it != lst.end(); ++it ) + { + ToolNode& node = *it; + if ( node.id == id ) + { + changed = changed || node.visible != on; + node.visible = on; + } + } + + if ( changed ) + updateToolBar( tId ); +} + +bool QtxActionToolMgr::load( const QString& fname, QtxActionMgr::Reader& r ) +{ + ToolCreator cr( &r, this ); + return r.read( fname, cr ); +} + + +/*! + Class: QtxActionToolMgr::ToolCreator + Level: Public +*/ +QtxActionToolMgr::ToolCreator::ToolCreator( QtxActionMgr::Reader* r, + QtxActionToolMgr* mgr ) +: QtxActionMgr::Creator( r ), + myMgr( mgr ) +{ +} + +QtxActionToolMgr::ToolCreator::~ToolCreator() +{ +} + +int QtxActionToolMgr::ToolCreator::append( const QString& tag, const bool subMenu, + const ItemAttributes& attr, const int tId ) +{ + if( !myMgr || !reader() ) + return -1; + + QString label = reader()->option( "label", "label" ), + id = reader()->option( "id", "id" ), + pos = reader()->option( "pos", "pos" ), + group = reader()->option( "group", "group" ), + tooltip = reader()->option( "tooltip", "tooltip" ), + sep = reader()->option( "separator", "separator" ), + accel = reader()->option( "accel", "accel" ), + icon = reader()->option( "icon", "icon" ), + toggle = reader()->option( "toggle", "toggle" ); + + int res = -1, actId = intValue( attr, id, -1 ); + if( tId==-1 ) + res = myMgr->createToolBar( strValue( attr, label ), intValue( attr, id, -1 ) ); + else if( tag==sep ) + res = myMgr->insert( separator(), tId, intValue( attr, pos, -1 ) ); + else + { + QPixmap pix; QIconSet set; + QString name = strValue( attr, icon ); + if( !name.isEmpty() && loadPixmap( name, pix ) ) + set = QIconSet( pix ); + + QtxAction* newAct = new QtxAction( strValue( attr, tooltip ), set, + strValue( attr, label ), + QKeySequence( strValue( attr, accel ) ), + myMgr ); + QString toggleact = strValue( attr, toggle ); + newAct->setToggleAction( !toggleact.isEmpty() ); + newAct->setOn( toggleact.lower()=="true" ); + + connect( newAct ); + int aid = myMgr->registerAction( newAct, actId ); + res = myMgr->insert( aid, tId, intValue( attr, pos, -1 ) ); + } + + return res; +} + + diff --git a/src/Qtx/QtxActionToolMgr.h b/src/Qtx/QtxActionToolMgr.h new file mode 100644 index 000000000..31c02209d --- /dev/null +++ b/src/Qtx/QtxActionToolMgr.h @@ -0,0 +1,136 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxActionToolMgr.h +// Author: Alexander SOLOVYEV, Sergey TELKOV + +#ifndef QTXACTIONTOOLMGR_H +#define QTXACTIONTOOLMGR_H + +#include "Qtx.h" + +#include + +#include "QtxActionMgr.h" + +class QToolBar; +class QMainWindow; + +#ifdef WIN32 +#pragma warning( disable:4251 ) +#endif + +class QTX_EXPORT QtxActionToolMgr : public QtxActionMgr +{ + Q_OBJECT + + class ToolNode + { + public: + ToolNode() : id( -1 ), visible( true ) {}; + + int id; + bool visible; + }; + + typedef QValueList NodeList; + +protected: + class ToolCreator; + +public: + QtxActionToolMgr( QMainWindow* ); + virtual ~QtxActionToolMgr(); + + QMainWindow* mainWindow() const; + + int createToolBar( const QString&, int = -1 ); + void removeToolBar( const QString& ); + void removeToolBar( const int ); + + int insert( const int, const int, const int = -1 ); + int insert( QAction*, const int, const int = -1 ); + int insert( const int, const QString&, const int = -1 ); + int insert( QAction*, const QString&, const int = -1 ); + + int append( const int, const int ); + int append( QAction*, const int ); + int append( const int, const QString& ); + int append( QAction*, const QString& ); + + int prepend( const int, const int ); + int prepend( QAction*, const int ); + int prepend( const int, const QString& ); + int prepend( QAction*, const QString& ); + + virtual bool isVisible( const int, const int ) const; + virtual void setVisible( const int, const int, const bool ); + + void show( const int ); + void hide( const int ); + bool isShown( const int ) const; + void setShown( const int, const bool ); + + void remove( const int, const int ); + void remove( const int, const QString& ); + + QToolBar* toolBar( const int ) const; + QToolBar* toolBar( const QString& ) const; + + bool hasToolBar( const int ) const; + bool hasToolBar( const QString& ) const; + + virtual bool load( const QString&, QtxActionMgr::Reader& ); + +protected slots: + void onToolBarDestroyed(); + +protected: + int find( QToolBar* ) const; + int find( const QString& ) const; + QToolBar* find( const QString&, QMainWindow* ) const; + + virtual void internalUpdate(); + void updateToolBar( const int ); + +private: + void simplifySeparators( QToolBar* ); + +private: + typedef struct { NodeList nodes; QToolBar* toolBar; } ToolBarInfo; + typedef QMap ToolBarMap; + +private: + ToolBarMap myToolBars; + QMainWindow* myMainWindow; +}; + +class QtxActionToolMgr::ToolCreator : public QtxActionMgr::Creator +{ +public: + ToolCreator( QtxActionMgr::Reader*, QtxActionToolMgr* ); + virtual ~ToolCreator(); + + virtual int append( const QString&, const bool, + const ItemAttributes&, const int ); + +private: + QtxActionToolMgr* myMgr; +}; + +#endif diff --git a/src/Qtx/QtxColorScale.h b/src/Qtx/QtxColorScale.h new file mode 100755 index 000000000..1037fd621 --- /dev/null +++ b/src/Qtx/QtxColorScale.h @@ -0,0 +1,182 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxColorScale.h +// Author: Sergey TELKOV + +#ifndef QTXCOLORSCALE_H +#define QTXCOLORSCALE_H + +#include "Qtx.h" + +#include +#include + +#if QT_VER == 3 +#include +#endif + +class QStyleSheet; +class QSimpleRichText; + +#ifdef WIN32 +#pragma warning( disable:4251 ) +#endif + +class QTX_EXPORT QtxColorScale : public QFrame +{ + Q_OBJECT + +public: + typedef enum { Auto, User } Mode; + typedef enum { None, Left, Right, Center } Position; + typedef enum { NoDump, TitleDump, ScaleDump, FullDump } DumpMode; + typedef enum { AtBorder = 0x001, Reverse = 0x002, Integer = 0x004, + WrapTitle = 0x008, PreciseFormat = 0x010, Transparent = 0x020 } Flags; + +#if QT_VER == 3 + class Dock : public QDockWindow + { + public: + Dock( Place = InDock, QWidget* = 0, const char* = 0, WFlags = 0 ); + virtual ~Dock(); + + QtxColorScale* colorScale() const; + + void activate(); + void deactivate(); + + bool isActive() const; + + virtual void show(); + virtual void hide(); + + virtual void resize( int, int ); + virtual void setOrientation( Orientation ); + + private: + QtxColorScale* myScale; + bool myBlockShow; + bool myBlockResize; + }; + +private: + QtxColorScale( Dock*, const char* = 0, WFlags = 0 ); +#endif + +public: + QtxColorScale( QWidget* = 0, const char* = 0, WFlags = 0 ); + QtxColorScale( const int, QWidget* = 0, const char* = 0, WFlags = 0 ); + virtual ~QtxColorScale(); + + double minimum() const; + double maximum() const; + void range( double&, double& ) const; + int dumpMode() const; + int labelMode() const; + int colorMode() const; + int intervalsNumber() const; + + QString title() const; + QString format() const; + QString label( const int ) const; + QColor color( const int ) const; + void labels( QStringList& ) const; + void colors( QValueList& ) const; + + int labelPosition() const; + int titlePosition() const; + + void setMinimum( const double ); + void setMaximum( const double ); + void setRange( const double, const double ); + void setDumpMode( const int ); + void setColorMode( const int ); + void setLabelMode( const int ); + void setIntervalsNumber( const int ); + + void setTitle( const QString& ); + void setFormat( const QString& ); + void setLabel( const QString&, const int = -1 ); + void setColor( const QColor&, const int = -1 ); + void setLabels( const QStringList& ); + void setColors( const QValueList& ); + + void setLabelPosition( const int ); + void setTitlePosition( const int ); + + void setFlags( const int ); + bool testFlags( const int ) const; + void clearFlags( const int ); + + QPixmap dump() const; + QPixmap dump( const int = -1, const int = -1 ) const; + QPixmap dump( const QColor&, const int = -1, const int = -1 ) const; + + virtual QSize minimumSizeHint() const; + virtual QSize sizeHint() const; + + virtual void show(); + virtual void hide(); + +protected: + virtual void drawContents( QPainter* ); + +private: + void updateScale(); + QString getFormat() const; + QString getLabel( const int ) const; + QColor getColor( const int ) const; + double getNumber( const int ) const; + QSimpleRichText* simpleRichText( const int ) const; + void drawScale( QPainter*, const bool, const int, const int, + const int, const int, const bool, const bool, const bool ) const; + void drawScale( QPainter*, const QColor&, const bool, + const int, const int, const int, const int, + const bool, const bool, const bool ) const; + QSize calculateSize( const bool, const int, + const bool, const bool, const bool ) const; + + friend class Dock; + +private: + double myMin; + double myMax; + QString myTitle; + QString myFormat; + QString myPrecise; + int myInterval; + int myDumpMode; + int myColorMode; + int myLabelMode; + + QValueList myColors; + QValueList myLabels; + + Dock* myDock; + int myFlags; + int myLabelPos; + int myTitlePos; + QStyleSheet* myStyleSheet; +}; + +#ifdef WIN32 +#pragma warning( default:4251 ) +#endif + +#endif diff --git a/src/Qtx/QtxComboBox.cxx b/src/Qtx/QtxComboBox.cxx new file mode 100755 index 000000000..4e7c3b5cb --- /dev/null +++ b/src/Qtx/QtxComboBox.cxx @@ -0,0 +1,178 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxComboBox.cxx +// Author: Sergey TELKOV + +#include "QtxComboBox.h" + +#include +#include +#include + +QtxComboBox::QtxComboBox( QWidget* parent, const char* name ) +: QComboBox( parent, name ), +myCleared( false ) +{ + connect( this, SIGNAL( activated( int ) ), this, SLOT( onActivated( int ) ) ); + connect( this, SIGNAL( activated( const QString& ) ), this, SLOT( onActivated( const QString& ) ) ); +} + +QtxComboBox::QtxComboBox( bool rw, QWidget* parent, const char* name ) +: QComboBox( rw, parent, name ), +myCleared( false ) +{ + connect( this, SIGNAL( activated( int ) ), this, SLOT( onActivated( int ) ) ); + connect( this, SIGNAL( activated( const QString& ) ), this, SLOT( onActivated( const QString& ) ) ); +} + +QtxComboBox::~QtxComboBox() +{ +} + +bool QtxComboBox::isCleared() const +{ + return myCleared; +} + +void QtxComboBox::setCleared( const bool isClear ) +{ + if ( myCleared == isClear ) + return; + + myCleared = isClear; + + if ( editable() ) + { + if ( myCleared ) + lineEdit()->setText( "" ); + else + lineEdit()->setText( text( currentItem() ) ); + } + + update(); +} + +void QtxComboBox::setCurrentItem( int idx ) +{ + if ( idx < 0 || idx >= count() ) + return; + + myCleared = false; + QComboBox::setCurrentItem( idx ); +} + +void QtxComboBox::setCurrentText( const QString& txt ) +{ + myCleared = false; +#if QT_VER < 3 + int i = -1; + for ( int j = 0; j < count() && i == -1; j++ ) + if ( text( j ) == txt ) + i = j; + if ( i >= 0 && i < count() ) + setCurrentItem( i ); + else if ( editable() ) + lineEdit()->setText( txt ); + else + changeItem( txt, currentItem() ); +#else + QComboBox::setCurrentText( txt ); +#endif +} + +int QtxComboBox::currentId() const +{ + return id( currentItem() ); +} + +void QtxComboBox::setCurrentId( int num ) +{ + setCurrentItem( index( num ) ); +} + +void QtxComboBox::paintEvent( QPaintEvent* e ) +{ + if ( !count() || !myCleared || editable() ) + QComboBox::paintEvent( e ); + else + paintClear( e ); +} + +void QtxComboBox::onActivated( int idx ) +{ + resetClear(); + + if ( myIndexId.contains( idx ) ) + emit activatedId( myIndexId[idx] ); +} + +void QtxComboBox::onActivated( const QString& ) +{ + resetClear(); +} + +void QtxComboBox::resetClear() +{ + if ( !myCleared ) + return; + + myCleared = false; + update(); +} + +void QtxComboBox::paintClear( QPaintEvent* e ) +{ + int curIndex = currentItem(); + QString curText = text( curIndex ); + + QPixmap curPix; + if ( pixmap( curIndex ) ) + curPix = *pixmap( curIndex ); + + bool upd = isUpdatesEnabled(); + setUpdatesEnabled( false ); + + changeItem( "", curIndex ); + QComboBox::paintEvent( e ); + + if ( curPix.isNull() ) + changeItem( curText, curIndex ); + else + changeItem( curPix, curText, curIndex ); + + setUpdatesEnabled( upd ); +} + +int QtxComboBox::id( const int idx ) const +{ + int id = -1; + if ( myIndexId.contains( idx ) ) + id = myIndexId[idx]; + return id; +} + +int QtxComboBox::index( const int id ) const +{ + int idx = -1; + for ( IndexIdMap::ConstIterator it = myIndexId.begin(); + it != myIndexId.end() && idx == -1; ++it ) + if ( it.data() == id ) + idx = it.key(); + return idx; +} diff --git a/src/Qtx/QtxComboBox.h b/src/Qtx/QtxComboBox.h new file mode 100755 index 000000000..9315c674e --- /dev/null +++ b/src/Qtx/QtxComboBox.h @@ -0,0 +1,81 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxComboBox.h +// Author: Sergey TELKOV + +#ifndef QTXCOMBOBOX_H +#define QTXCOMBOBOX_H + +#include "Qtx.h" + +#include +#include + +#ifdef WIN32 +#pragma warning( disable:4251 ) +#endif + +class QTX_EXPORT QtxComboBox : public QComboBox +{ + Q_OBJECT + + typedef QMap IndexIdMap; + +public: + QtxComboBox( QWidget* = 0, const char* = 0 ); + QtxComboBox( bool, QWidget* = 0, const char* = 0 ); + virtual ~QtxComboBox(); + + bool isCleared() const; + void setCleared( const bool ); + + virtual void setCurrentItem( int ); + virtual void setCurrentText( const QString& ); + + int currentId() const; + void setCurrentId( int ); + +signals: + void activatedId( int ); + void highlightedId( int ); + +private slots: + void onActivated( int ); + void onActivated( const QString& ); + +protected: + virtual void paintEvent( QPaintEvent* ); + +private: + int id( const int ) const; + int index( const int ) const; + + void resetClear(); + void paintClear( QPaintEvent* ); + +private: + bool myCleared; + IndexIdMap myIndexId; +}; + +#ifdef WIN32 +#pragma warning( default:4251 ) +#endif + +#endif diff --git a/src/Qtx/QtxDblSpinBox.h b/src/Qtx/QtxDblSpinBox.h new file mode 100755 index 000000000..e59fe4f3d --- /dev/null +++ b/src/Qtx/QtxDblSpinBox.h @@ -0,0 +1,109 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxDblSpinBox.h +// Author: Sergey TELKOV + +#ifndef QTXDBLSPINBOX_H +#define QTXDBLSPINBOX_H + +#include "Qtx.h" + +#include + +class QTX_EXPORT QtxDblSpinBox : public QSpinBox +{ + Q_OBJECT + + class Validator; + +public: + typedef enum QSpinBox::ButtonSymbols ButtonSymbols; + +public: + QtxDblSpinBox( QWidget* = 0, const char* = 0 ); + QtxDblSpinBox( double, double, double = 1, QWidget* = 0, const char* = 0 ); + virtual ~QtxDblSpinBox(); + + double minValue() const; + double maxValue() const; + void setMinValue( int ); + void setMaxValue( int ); + void setMinValue( double ); + void setMaxValue( double ); + void setRange( int, int ); + virtual void setRange( double, double ); + + double lineStep() const; + void setLineStep( int ); + virtual void setLineStep( double ); + + double value() const; + + int precision() const; + virtual void setPrecision( const int ); + + bool isCleared() const; + virtual void setCleared( const bool ); + + virtual bool eventFilter( QObject*, QEvent* ); + +signals: + void valueChanged( double ); + void valueChanged( const QString& ); + +public slots: + virtual void stepUp(); + virtual void stepDown(); + virtual void selectAll(); + virtual void setValue( int ); + virtual void setValue( double ); + +protected slots: + virtual void onTextChanged( const QString& ); + +protected: + virtual void updateDisplay(); + virtual void interpretText(); + + virtual void valueChange(); + virtual void rangeChange(); + + QString currentValueText(); + virtual QString mapValueToText( int ); + virtual QString mapValueToText( double ); + virtual double mapTextToDoubleValue( bool* ); + + virtual void leaveEvent( QEvent* ); + virtual void wheelEvent( QWheelEvent* ); + + double bound( double ); + + QString removeTrailingZeroes( const QString& ) const; + +private: + double myMin; + double myMax; + double myStep; + double myValue; + bool myCleared; + bool myBlocked; + int myPrecision; +}; + +#endif diff --git a/src/Qtx/QtxDialog.cxx b/src/Qtx/QtxDialog.cxx new file mode 100755 index 000000000..bf827df57 --- /dev/null +++ b/src/Qtx/QtxDialog.cxx @@ -0,0 +1,1383 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxDialog.cxx +// Author: Sergey TELKOV + +#include "QtxDialog.h" + +#include "QtxGroupBox.h" + +#include +#include +#include +#include +#include + +/*! + Class: QtxDialog::Area + Level: Internal +*/ + +class QtxDialog::Area : public QFrame +{ +public: + Area( Orientation, QtxDialog*, QWidget* = 0 ); + virtual ~Area(); + + bool isBorderEnabled() const; + void setBorderEnabled( const bool ); + + void setBorderWidget( QLabel* ); + + void insertButton( QButton* ); + void removeButton( QButton* ); + bool contains( QButton* ) const; + + int policy() const; + void setPolicy( const int ); + + void layoutButtons(); + + const QPtrList& buttons() const; + +private: + void updateBorder(); + +private: + QtxDialog* myDlg; + QLabel* myLine; + bool myBorder; + int myPolicy; + QPtrList myButtons; + Orientation myOrientation; +}; + +QtxDialog::Area::Area( Orientation o, QtxDialog* dlg, QWidget* parent ) +: QFrame( parent ), +myDlg( dlg ), +myLine( 0 ), +myBorder( false ), +myPolicy( Position ), +myOrientation( o ) +{ + if ( myOrientation == Qt::Horizontal ) + setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Maximum ) ); + else + setSizePolicy( QSizePolicy( QSizePolicy::Maximum, QSizePolicy::Preferred ) ); + + hide(); +} + +QtxDialog::Area::~Area() +{ +} + +void QtxDialog::Area::insertButton( QButton* b ) +{ + if ( !b || myButtons.findRef( b ) != -1 ) + return; + + QWidget* parent = b->parentWidget(); + if ( parent != this ) + b->reparent( this, 0, QPoint( 0, 0 ), b->isVisibleTo( parent ) ); + + myButtons.append( b ); + + if ( myDlg ) + myDlg->adjustButtons(); + layoutButtons(); + + show(); + + updateBorder(); +} + +void QtxDialog::Area::removeButton( QButton* b ) +{ + if ( !b ) + return; + + myButtons.removeRef( b ); + + if ( myButtons.isEmpty() ) + hide(); + + updateBorder(); + + if ( myDlg ) + myDlg->adjustButtons(); + + layoutButtons(); +} + +bool QtxDialog::Area::contains( QButton* b ) const +{ + return myButtons.containsRef( b ); +} + +int QtxDialog::Area::policy() const +{ + return myPolicy; +} + +void QtxDialog::Area::setPolicy( const int p ) +{ + if ( myPolicy == p ) + return; + + myPolicy = p; + layoutButtons(); +} + +bool QtxDialog::Area::isBorderEnabled() const +{ + return myLine && myBorder; +} + +void QtxDialog::Area::setBorderEnabled( const bool on ) +{ + if ( !myLine || myBorder == on ) + return; + + myBorder = on; + updateBorder(); +} + +void QtxDialog::Area::setBorderWidget( QLabel* line ) +{ + if ( myLine == line ) + return; + + delete myLine; + myLine = line; + updateBorder(); +} + +const QPtrList& QtxDialog::Area::buttons() const +{ + return myButtons; +} + +void QtxDialog::Area::updateBorder() +{ + if ( !myLine ) + return; + + bool isVis = isVisibleTo( parentWidget() ); +#if QT_VER >= 3 + if ( isVis ) +#else + if ( isVis && myBorder ) +#endif + myLine->show(); + else + myLine->hide(); + + myLine->setLineWidth( myBorder ? 1 : 0 ); +} + +void QtxDialog::Area::layoutButtons() +{ + int aPolicy = policy(); + + QMap buttonId; + for ( QPtrListIterator it1( myButtons ); it1.current(); ++it1 ) + buttonId.insert( it1.current(), 0 ); + + QPtrList src; + for ( ButtonMap::Iterator mit = myDlg->myButton.begin(); + mit != myDlg->myButton.end(); ++mit ) + { + if ( buttonId.contains( mit.data() ) ) + { + buttonId[mit.data()] = mit.key(); + if ( mit.key() >= 0 ) + src.append( mit.data() ); + } + } + + for ( QPtrListIterator it2( myButtons ); it2.current(); ++it2 ) + if ( buttonId[it2.current()] < 0 ) + src.append( it2.current() ); + + QPtrList left, right, center, other; + for ( QPtrListIterator it( src ); it.current(); ++it ) + { + if ( !it.current()->isVisibleTo( this ) ) + continue; + + int aPosition = myDlg->buttonPosition( it.current() ); + if ( aPosition == -1 ) + continue; + + if ( aPolicy != QtxDialog::Position ) + other.append( it.current() ); + else if ( aPosition == QtxDialog::Left ) + left.append( it.current() ); + else if ( aPosition == QtxDialog::Right ) + right.append( it.current() ); + else if ( aPosition == QtxDialog::Center ) + center.append( it.current() ); + } + + delete layout(); + + QBoxLayout* buttonLayout = 0; + if ( myOrientation == Qt::Vertical ) + buttonLayout = new QVBoxLayout( this, 0, 5 ); + else + buttonLayout = new QHBoxLayout( this, 0, 5 ); + + if ( !buttonLayout ) + return; + + if ( aPolicy == QtxDialog::Position ) + { + for ( QPtrListIterator lit( left ); lit.current(); ++lit ) + buttonLayout->addWidget( lit.current() ); + buttonLayout->addStretch( 1 ); + for ( QPtrListIterator cit( center ); cit.current(); ++cit ) + buttonLayout->addWidget( cit.current() ); + buttonLayout->addStretch( 1 ); + for ( QPtrListIterator rit( right ); rit.current(); ++rit ) + buttonLayout->addWidget( rit.current() ); + } + else + { + for ( QPtrListIterator oit( other ); oit.current(); ++oit ) + { + buttonLayout->addWidget( oit.current() ); + if ( aPolicy == QtxDialog::Uniform && !oit.atLast() ) + buttonLayout->addStretch( 1 ); + } + } +} + +/*! + Class: QtxDialog::Border + Level: Internal +*/ + +class QtxDialog::Border : public QLabel +{ +public: + Border( QWidget* = 0 ); + virtual ~Border(); + + virtual void setLineWidth( int ); + + virtual QSize sizeHint() const; + virtual QSize minimumSizeHint() const; +}; + +QtxDialog::Border::Border( QWidget* parent ) +: QLabel( parent ) +{ + setAlignment( Qt::AlignCenter ); +} + +QtxDialog::Border::~Border() +{ +} + +void QtxDialog::Border::setLineWidth( int lw ) +{ + bool isOn = lineWidth() > 0; + + QLabel::setLineWidth( lw ); + + if ( isOn != ( lineWidth() > 0 ) ) + updateGeometry(); +} + +QSize QtxDialog::Border::sizeHint() const +{ + QSize sz( 5, 5 ); + +#if QT_VER >= 3 + if ( lineWidth() > 0 ) + { + if ( frameShape() == VLine ) + sz += QSize( 5 + lineWidth(), 0 ); + else if ( frameShape() == HLine ) + sz += QSize( 0, 5 + lineWidth() ); + } +#endif + + return sz; +} + +QSize QtxDialog::Border::minimumSizeHint() const +{ + return sizeHint(); +} + +/*! + Class: QtxDialog + Level: Public +*/ + +/*! + Name: QtxDialog [public] + Desc: Construct a dialog with specified parent and name. + Parameter 'modal' define modal status of dialog (default non modal + dialog created). If parameter 'allowResize' is true then dialog + can be resize by user (default non resizable dialog created). + Button flags specified control buttons for dialog (default buttons + is OK, Cancel and Help). Widget flags used as in any widget. +*/ + +QtxDialog::QtxDialog( QWidget* parent, const char* name, + bool modal, bool allowResize, const int f, WFlags wf ) +: QDialog( parent, name, modal, +#ifdef WIN32 + wf | WStyle_Customize | WStyle_Title | WStyle_SysMenu | + ( allowResize ? WStyle_NormalBorder : WStyle_NoBorderEx ) ), +#else + wf | WStyle_NormalBorder | WStyle_Customize | WStyle_Title | WStyle_SysMenu ), +#endif +mySender( 0 ), +myAlignment( 0 ), +myInited( false ), +myDialogFlags( Accept | SetFocus ) +{ + QVBoxLayout* base = new QVBoxLayout( this, 5, 0 ); + QtxGroupBox* main = new QtxGroupBox( 1, Qt::Horizontal, "", this ); + main->setFrameStyle( QFrame::NoFrame ); + main->setInsideMargin( 0 ); + main->setInsideSpacing( 0 ); + base->addWidget( main ); + + Area* topArea = new Area( Qt::Horizontal, this, main ); + QLabel* topLine = new Border( main ); + QtxGroupBox* midGroup = new QtxGroupBox( 1, Qt::Vertical, "", main ); + QLabel* botLine = new Border( main ); + Area* botArea = new Area( Qt::Horizontal, this, main ); + + midGroup->setFrameStyle( QFrame::NoFrame ); + midGroup->setInsideMargin( 0 ); + midGroup->setInsideSpacing( 0 ); + + Area* leftArea = new Area( Qt::Vertical, this, midGroup ); + QLabel* leftLine = new Border( midGroup ); + myMainFrame = new QFrame( midGroup ); + QLabel* rightLine = new Border( midGroup ); + Area* rightArea = new Area( Qt::Vertical, this, midGroup ); + + myMainFrame->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, + QSizePolicy::Expanding ) ); + + topLine->setFrameStyle( QFrame::Sunken | QFrame::HLine ); + botLine->setFrameStyle( QFrame::Sunken | QFrame::HLine ); + leftLine->setFrameStyle( QFrame::Sunken | QFrame::VLine ); + rightLine->setFrameStyle( QFrame::Sunken | QFrame::VLine ); + topArea->setBorderWidget( topLine ); + botArea->setBorderWidget( botLine ); + leftArea->setBorderWidget( leftLine ); + rightArea->setBorderWidget( rightLine ); + + myArea.insert( TopArea, topArea ); + myArea.insert( BottomArea, botArea ); + myArea.insert( LeftArea, leftArea ); + myArea.insert( RightArea, rightArea ); + + for ( AreaMap::Iterator itr = myArea.begin(); itr != myArea.end(); ++ itr ) + itr.data()->setBorderEnabled( false ); + + myButton.insert( OK, new QPushButton( tr( "&OK" ), this ) ); + myButton.insert( Cancel, new QPushButton( tr( "&Cancel" ), this ) ); + myButton.insert( Close, new QPushButton( tr( "C&lose" ), this ) ); + myButton.insert( Help, new QPushButton( tr( "&Help" ), this ) ); + myButton.insert( Apply, new QPushButton( tr( "&Apply" ), this ) ); + myButton.insert( Yes, new QPushButton( tr( "&Yes" ), this ) ); + myButton.insert( No, new QPushButton( tr( "&No" ), this ) ); + + for ( ButtonMap::Iterator it = myButton.begin(); it != myButton.end(); ++it ) + { + ((QPushButton*)it.data())->setAutoDefault( false ); +#if QT_VER >= 3 + connect( it.data(), SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) ); +#endif + } + + setButtonPosition( Left, OK | Cancel | Apply ); + setButtonPosition( Center, Yes | No | Close ); + setButtonPosition( Right, Help ); + setButtonPlace( BottomArea, All ); + + connect( myButton[Apply], SIGNAL( clicked() ), this, SIGNAL( dlgApply() ) ); + connect( myButton[Help], SIGNAL( clicked() ), this, SIGNAL( dlgHelp() ) ); + + connect( myButton[OK], SIGNAL( clicked() ), this, SLOT( onAccept() ) ); + connect( myButton[Cancel], SIGNAL( clicked() ), this, SLOT( onReject() ) ); + connect( myButton[Yes], SIGNAL( clicked() ), this, SLOT( onAccept() ) ); + connect( myButton[No], SIGNAL( clicked() ), this, SLOT( onReject() ) ); + connect( myButton[Close], SIGNAL( clicked() ), this, SLOT( onReject() ) ); + + QPixmap icon; + if ( qApp && qApp->mainWidget() && qApp->mainWidget()->icon() ) + setIcon( *qApp->mainWidget()->icon() ); + + myButtonFlags = f; + +#ifndef WIN32 + if ( !allowResize ) + setMaximumSize( minimumSize() ); +#endif + + update(); +} + +/*! + Name: ~QtxDialog [public] + Desc: Destructor +*/ + +QtxDialog::~QtxDialog() +{ +} + +/*! + Name: setButtonFlags [public] + Desc: Allow to set specified control button(s) into dialog. +*/ + +void QtxDialog::setButtonFlags( const int f ) +{ + int old = myButtonFlags; + myButtonFlags = myButtonFlags | f; + if ( old != myButtonFlags ) + update(); +} + +/*! + Name: clearButtonFlags [public] + Desc: Allow to unset specified control button(s) from dialog. +*/ + +void QtxDialog::clearButtonFlags( const int f ) +{ + int old = myButtonFlags; + myButtonFlags = myButtonFlags & ~f; + if ( old != myButtonFlags ) + update(); +} + +/*! + Name: testButtonFlags [public] + Desc: Return true if specified control button is used in dialog. +*/ + +bool QtxDialog::testButtonFlags( const int f ) const +{ + return ( myButtonFlags & f ) == f; +} + +/*! + Name: setDialogFlags [public] + Desc: Allow to set the dialog flags. + + Following flags can be used: + Accept - Allow to control dialog accepting. See also acceptData(). + Reject - Allow to control dialog rejecting. See also rejectData(). + AlignOnce - Allow to align dialog only when it first time shown. + SetFocus - Allow to set focus on dialog when it shown. User can use + setFocusProxy() and specify own initial focus widget. +*/ + +void QtxDialog::setDialogFlags( const int f ) +{ + myDialogFlags = myDialogFlags | f; +} + +/*! + Name: clearDialogFlags [public] + Desc: Allow to clear the dialog flags. See also setDialogFlags(). +*/ + +void QtxDialog::clearDialogFlags( const int f ) +{ + myDialogFlags = myDialogFlags & ~f; +} + +/*! + Name: testDialogFlags [public] + Desc: Returns true if specified dialog flag is setted (see setDialogFlags()). +*/ + +bool QtxDialog::testDialogFlags( const int f ) const +{ + return ( myDialogFlags & f ) == f; +} + +/*! + Name: mainFrame [public] + Desc: Returns main frame of dialog. Main frame should contains all + elements of dialog except control buttons. +*/ + +QFrame* QtxDialog::mainFrame() const +{ + return myMainFrame; +} + +/*! + Name: buttonPosition [public] + Desc: Returns position of specified button. +*/ + +int QtxDialog::buttonPosition( const int id ) const +{ + int pos = -1; + if ( myPosition.contains( id ) ) + pos = myPosition[id]; + return pos; +} + +/*! + Name: setButtonPosition [public] + Desc: Sets the position for specified button(s). Following positions + may be used: Left, Right, Center, Top, Bottom. +*/ + +void QtxDialog::setButtonPosition( const int pos, const int id ) +{ + ButtonMap map = buttons( id ); + + QMap changed; + for ( ButtonMap::Iterator it = map.begin(); it != map.end(); ++it ) + { + if ( myPosition[it.key()] == pos ) + continue; + + myPosition[it.key()] = pos; + if ( button( it.key() ) ) + changed.insert( button( it.key() )->parent(), 0 ); + } + + for ( AreaMap::Iterator itr = myArea.begin(); itr != myArea.end(); ++itr ) + if ( changed.contains( itr.data() ) ) + itr.data()->layoutButtons(); +} + +/*! + Name: setPlacePosition [public] + Desc: Sets button position for all buttons in given place. +*/ + +void QtxDialog::setPlacePosition( const int pos, const int area ) +{ + if ( !myArea.contains( area ) ) + return; + + Area* anArea = myArea[area]; + + bool changed = false; + for ( ButtonMap::Iterator it = myButton.begin(); it != myButton.end(); ++it ) + { + if ( !anArea->contains( it.data() ) ) + continue; + + changed = changed && myPosition[it.key()] != pos; + + myPosition[it.key()] = pos; + } + + if ( changed ) + anArea->layoutButtons(); +} + +/*! + Name: placePolicy [public] + Desc: Returns policy of button layouting for specified place. + + Following place may be used: + TopArea - Horizontal area in the top side of dialog. + BottomArea - Horizontal area in the bottom side of dialog. + LeftArea - Vertical area in the left side of dialog. + RightArea - Vertical area in the right side of dialog. + + Following policy may be used: + Position - Buttons placed according their position. + Expand - Buttons fills all available space. + Uniform - Buttons uniformly placed in area. +*/ + +int QtxDialog::placePolicy( const int area ) const +{ + int res = -1; + if ( myArea.contains( area ) ) + res = myArea[area]->policy(); + return res; +} + +/*! + Name: setPlacePolicy [public] + Desc: Sets the policy of button layouting for specified place. + See also placePolicy(). +*/ + +void QtxDialog::setPlacePolicy( const int policy, const int area ) +{ + if ( area < 0 ) + for ( AreaMap::Iterator itr = myArea.begin(); itr != myArea.end(); ++itr ) + itr.data()->setPolicy( policy ); + else if ( myArea.contains( area ) ) + myArea[area]->setPolicy( policy ); +} + +/*! + Name: setButtonPlace [public] + Desc: Move given button(s) into specified place. +*/ + +void QtxDialog::setButtonPlace( const int area, const int ids ) +{ + if ( !myArea.contains( area ) ) + return; + + Area* anArea = myArea[area]; + + ButtonMap map = buttons( ids ); + + QMap areaMap; + for ( AreaMap::ConstIterator aIt = myArea.begin(); aIt != myArea.end(); ++aIt ) + areaMap.insert( aIt.data(), 0 ); + + for ( ButtonMap::Iterator it = map.begin(); it != map.end(); ++it ) + { + Area* old = (Area*)it.data()->parent(); + if ( old == anArea ) + continue; + + if ( areaMap.contains( old ) ) + old->removeButton( it.data() ); + anArea->insertButton( it.data() ); + } +} + +/*! + Name: isBorderEnabled [public] + Desc: Returns true if border is shown for specified button area. +*/ + +bool QtxDialog::isBorderEnabled( const int area ) const +{ + bool res = false; + if ( myArea.contains( area ) ) + res = myArea[area]->isBorderEnabled(); + return res; +} + +/*! + Name: setBorderEnabled [public] + Desc: Show/hide border for specified button area. Border are + line which separate main frame and control buttons. +*/ + +void QtxDialog::setBorderEnabled( const bool on, const int area ) +{ + if ( !myArea.contains( area ) ) + return; + + if ( myArea[area]->isBorderEnabled() == on ) + return; + + myArea[area]->setBorderEnabled( on ); + + if ( isVisible() ) + { + QApplication::sendPostedEvents(); + adjustSize(); + } +} + +/*! + Name: isButtonEnabled [public] + Desc: Returns true if all specified button(s) is enabled. +*/ + +bool QtxDialog::isButtonEnabled( const int f ) const +{ + ButtonMap map = buttons( f ); + bool result = !map.isEmpty(); + for ( ButtonMap::Iterator it = map.begin(); it != map.end(); ++it ) + result = result && it.data()->isEnabled(); + return result; +} + +/*! + Name: setButtonEnabled [public] + Desc: Enable/disable specified button(s). +*/ + +void QtxDialog::setButtonEnabled( const bool on, const int ids ) +{ + ButtonMap map = buttons( ids ); + for ( ButtonMap::Iterator it = map.begin(); it != map.end(); ++it ) + it.data()->setEnabled( on ); +} + +/*! + Name: hasButtonFocus [public] + Desc: Retruns true if specified button has keyboard focus. +*/ + +bool QtxDialog::hasButtonFocus( const int id ) const +{ + bool res = false; + QButton* pb = button( id ); + if ( pb ) + res = pb->hasFocus(); + return res; +} + +/*! + Name: setButtonFocus [public] + Desc: Sets the keyboard focus on specified button. +*/ + +void QtxDialog::setButtonFocus( const int id ) +{ + QButton* pb = button( id ); + if ( pb ) + pb->setFocus(); +} + +/*! + Name: buttonText [public] + Desc: Return text of specified button. +*/ + +QString QtxDialog::buttonText( const int id ) +{ + QString retval; + QButton* but = button( id ); + if ( but ) + retval = but->text(); + return retval; +} + +/*! + Name: setButtonText [public] + Desc: Sets text to specified button. +*/ + +void QtxDialog::setButtonText( const int id, const QString& text ) +{ + QButton* but = button( id ); + if ( but && but->text() != text ) + { + but->setText( text ); + adjustButtons(); + } +} + +/*! + Name: setAlignment [public] + Desc: Sets alignment policy. Returns the previous alignment. + Use the function before the first show of the dialog. + If dialog flag AlignOnce is setted then align will performed + only one time otherwise dialog will be aligned every time + when it shown. Dialog will be aligned relative to it parent. + + Following align flags may be used: + Qtx::AlignAuto - Align to center of desktop (default). + Qtx::AlignLeft - Align left side of dialog to left side of parent. + Qtx::AlignRight - Align right side of dialog to right side of parent. + Qtx::AlignTop - Align top side of dialog to top side of parent. + Qtx::AlignBottom - Align bottom side of dialog to bottom side of parent. + Qtx::AlignHCenter - Align dialog to center of parent in horizontal dimension. + Qtx::AlignVCenter - Align dialog to center of parent in vertical dimension. + Qtx::AlignCenter - Align dialog to center of parent in both dimensions. + Qtx::AlignOutLeft - Align right side of dialog to left side of parent. + Qtx::AlignOutRight - Align left side of dialog to right side of parent. + Qtx::AlignOutTop - Align bottom side of dialog to top side of parent. + Qtx::AlignOutBottom - Align top side of dialog to bottom side of parent. +*/ + +uint QtxDialog::setAlignment( uint align ) +{ + uint oldAlign = myAlignment; + myAlignment = align; + return oldAlign; +} + +/*! + Name: update [virtual public slot] + Desc: Updates dialog, show selected buttons and hide unselected. +*/ + +void QtxDialog::update() +{ + for ( ButtonMap::Iterator it = myButton.begin(); it != myButton.end(); ++it ) + if ( it.key() >= 0 ) + testButtonFlags( it.key() ) ? it.data()->show() : it.data()->hide(); + + for ( AreaMap::Iterator itr = myArea.begin(); itr != myArea.end(); ++itr ) + itr.data()->layoutButtons(); + + adjustButtons(); + + QDialog::update(); +} + +/*! + Name: show [virtual public] + Desc: Show dialog, set keyboard focus on dialog. +*/ + +void QtxDialog::show() +{ + QDialog::show(); + + if ( testDialogFlags( SetFocus ) ) + setFocus(); + + myInited = true; +} + +/*! + Name: hide [virtual public] + Desc: Hides dialog, processed all posted events. +*/ + +void QtxDialog::hide() +{ + QDialog::hide(); + qApp->processEvents(); +} + +/*! + Name: userButton [public] + Desc: Return user dialog button using specified identificator. +*/ + +QButton* QtxDialog::userButton( const int id ) const +{ + QButton* b = 0; + if ( id < -1 && myButton.contains( id ) ) + b = myButton[id]; + return b; +} + +/*! + Name: userButtonIds [public] + Desc: Return list of user dialog button identificators. +*/ + +QValueList QtxDialog::userButtonIds() const +{ + QValueList retlist; + for ( ButtonMap::ConstIterator it = myButton.begin(); it != myButton.end(); ++it ) + if ( it.key() < 0 ) + retlist.append( it.key() ); + return retlist; +} + +/*! + Name: insertButton [public] + Desc: Add new user dialog button. Function return identificator of + newly added button in successfull case otherwise -1 will be returned. +*/ + +int QtxDialog::insertButton( const QString& text, const int area ) +{ + if ( !myArea.contains( area ) ) + return -1; + + int id = -2; + while ( myButton.contains( id ) ) + id--; + + Area* anArea = myArea[area]; + QButton* b = createButton( this ); + if ( b ) + { + b->setText( text ); + myButton.insert( id, b ); + myPosition.insert( id, Left ); + + connect( b, SIGNAL( clicked() ), this, SLOT( onButton() ) ); +#if QT_VER >= 3 + connect( b, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) ); +#endif + + anArea->insertButton( b ); + update(); + } + else + id = -1; + + return id; +} + +/*! + Name: removeButton [public] + Desc: Remove user dialog button with specified identificator. If + identificator equal -1 then method will remove all user dialog buttons. +*/ + +void QtxDialog::removeButton( const int id ) +{ + if ( id >= 0 ) + return; + + ButtonMap map; + if ( id == -1 ) + { + for ( ButtonMap::Iterator it = myButton.begin(); it != myButton.end(); ++it ) + { + if ( it.key() < 0 ) + map.insert( it.key(), it.data() ); + } + } + else if ( myButton.contains( id ) ) + map.insert( id, myButton[id] ); + + for ( ButtonMap::Iterator itr = map.begin(); itr != map.end(); ++itr ) + { + for ( AreaMap::Iterator it = myArea.begin(); it != myArea.end(); ++it ) + it.data()->removeButton( itr.data() ); + + myButton.remove( itr.key() ); + myPosition.remove( itr.key() ); + + delete itr.data(); + } + update(); +} + +/*! + Name: setUnits [static public] + Desc: Sets specified measure units in given label. Measure units close + in braces. If measure units not exist then they will be added. + For example: + 1. Label contains text 'Radius'. + setUnits( aLabel, "mm" ) => aLabel contains 'Radius (mm)' + setUnits( aLabel, "cm" ) => aLabel contains 'Radius (cm)' + 2. Label "aLabel" contains text 'Radius ():'. + setUnits( aLabel, "mm" ) => aLabel contains 'Radius (mm):' + setUnits( aLabel, "cm" ) => aLabel contains 'Radius (cm):' +*/ + +void QtxDialog::setUnits( QLabel* aLabel, const QString& aUnits ) +{ + QString label = aLabel->text(); + int begin; + int end = label.findRev( ')' ); + + QString startLabel = label; + QString finalLabel; + + if ( end != -1 ) + { + begin = label.left( end ).findRev( '(' ); + if ( begin != -1 ) + { + startLabel = label.mid( 0, begin ); + finalLabel = label.mid( end + 1 ); + } + } + else + { + startLabel = startLabel.stripWhiteSpace(); + if ( startLabel.at( startLabel.length() - 1 ) == ':' ) + { + finalLabel = startLabel.mid( startLabel.length() - 1 ); + startLabel = startLabel.mid( 0, startLabel.length() - 1 ); + } + } + if ( aUnits.length() ) + label = startLabel.stripWhiteSpace() + + " (" + aUnits + ") " + finalLabel.stripWhiteSpace(); + else + label = startLabel.stripWhiteSpace() + + " " + finalLabel.stripWhiteSpace(); + aLabel->setText( label ); +} + +/*! + Name: acceptData [virtual protected] + Desc: If returns true dialog will be accepted and closed. This method + called if dialog flag Accept is setted. +*/ + +bool QtxDialog::acceptData() const +{ + return true; +} + +/*! + Name: rejectData [virtual protected] + Desc: If returns true dialog will be rejected and closed. This method + called if dialog flag Reject is setted. +*/ + +bool QtxDialog::rejectData() const +{ + return true; +} + +/*! + Name: createButton [virtual protected] + Desc: Create new user button. Invoked from method "insertButton". +*/ + +QButton* QtxDialog::createButton( QWidget* parent ) +{ + QPushButton* pb = new QPushButton( parent ); + pb->setAutoDefault( false ); + return pb; +} + +/*! + Name: button [protected] + Desc: Return pointer on control button specified by identifier. + If identifier is wrong then null pointer will returned. +*/ + +QButton* QtxDialog::button( const int f ) const +{ + QButton* retval = 0; + if ( myButton.contains( f ) ) + retval = myButton[f]; + return retval; +} + +/*! + Name: buttons [protected] + Desc: Return map with control dialog buttons accordance to given button flags. +*/ + +QtxDialog::ButtonMap QtxDialog::buttons( const int f ) const +{ + ButtonMap retmap; + if ( f < -1 ) + { + if ( myButton.contains( f ) ) + retmap.insert( f, myButton[f] ); + } + else + { + for ( ButtonMap::ConstIterator it = myButton.begin(); it != myButton.end(); ++it ) + if ( f == -1 || ( it.key() >= 0 && f & it.key() ) ) + retmap.insert( it.key(), it.data() ); + } + + return retmap; +} + +/*! + Name: buttonId [protected] + Desc: Return identifier of specified button. +*/ + +int QtxDialog::buttonId( const QButton* b ) const +{ + int id = -1; + for ( ButtonMap::ConstIterator it = myButton.begin(); it != myButton.end() && id == -1; ++it ) + if ( it.data() == b ) + id = it.key(); + return id; +} + +/*! + Name: buttonPosition + Desc: Returns position of specified button. [protected] +*/ + +int QtxDialog::buttonPosition( QButton* b ) const +{ + return buttonPosition( buttonId( b ) ); +} + +/*! + Name: showEvent [virtual protected] + Desc: Aligns this dialog according the parent widget and alignment + policy before the show. +*/ + +void QtxDialog::showEvent( QShowEvent* e ) +{ + if ( !testDialogFlags( AlignOnce ) || !myInited ) + Qtx::alignWidget( this, parentWidget(), myAlignment ); + QDialog::showEvent( e ); +} + +/*! + Name: hideEvent [virtual protected] + Desc: Process all existing events when dialog is closed. +*/ + +void QtxDialog::hideEvent( QHideEvent* e ) +{ + qApp->processEvents(); + QDialog::hideEvent( e ); +} + +/*! + Name: childEvent [virtual protected] + Desc: Setting up layout when size grip is added. +*/ + +void QtxDialog::childEvent( QChildEvent* e ) +{ + QDialog::childEvent( e ); + if ( layout() && e->inserted() && e->child()->inherits( "QSizeGrip" ) ) + { + layout()->setMargin( 12 ); +#if QT_VER >= 3 + connect( e->child(), SIGNAL( destroyed() ), this, SLOT( onSizeGripDestroyed() ) ); +#endif + } +} + +/*! + Name: keyPressEvent [virtual protected] + Desc: Calls reject() if key Escape is pressed. + Calls accept() if key "Ctrl+Enter" is pressed. + Process key "F1" and emit signal dlgHelp(). + Transfer key "Ctrl+(Shift+)Tab" press event to Tab Widget. +*/ + +void QtxDialog::keyPressEvent( QKeyEvent* e ) +{ + QDialog::keyPressEvent( e ); + if ( e->isAccepted() ) + return; + + if ( ( e->state() == 0 ) && ( e->key() == Key_Escape ) ) + reject(); + + if ( ( e->state() == ControlButton ) && ( e->key() == Key_Return ) ) + { + if ( testButtonFlags( OK ) || testButtonFlags( Yes ) ) + accept(); + else if ( testButtonFlags( Apply ) && isButtonEnabled( Apply ) ) + emit dlgApply(); + e->accept(); + } + + if ( e->key() == Key_F1 && testButtonFlags( Help ) && isButtonEnabled( Help ) ) + { + e->accept(); + emit dlgHelp(); + } + + if ( ( e->key() == Key_Tab ) && ( e->state() & ControlButton ) ) + { + QObject* tab = child( 0, "QTabWidget" ); + if ( tab ) + tab->event( e ); + } +} + +/*! + Name: closeEvent [virtual protected] + Desc: Reject the dialog. +*/ + +void QtxDialog::closeEvent( QCloseEvent* ) +{ + reject(); +} + +/*! + Name: accept [virtual protected slot] + Desc: Invoke function acceptData() if it needed and if acceptData() return + false does nothing. Otherwise hides the dialog and sets the result code + to Accepted. Emit signal according to the pressed control button. +*/ + +void QtxDialog::accept() +{ + if ( !mySender ) + { + if ( testButtonFlags( OK ) ) + mySender = button( OK ); + else if ( testButtonFlags( Yes ) ) + mySender = button( Yes ); + else + mySender = button( Close ); + } + + if ( !mySender || !mySender->isWidgetType() || + !((QWidget*)mySender)->isEnabled() ) + return; + + if ( testDialogFlags( Accept ) && !acceptData() ) + return; + + QDialog::accept(); + + emitSignal(); +} + +/*! + Name: reject [virtual protected slot] + Desc: Invoke function rejectData() if it needed and if rejectData() return + false does nothing. Otherwise hides the dialog and sets the result code + to Rejected. Emit signal according to the pressed control button. (If + dialog was closed by key Escape or by close event emit signal dlgCancel(), + or dlgClose(), or dlgNo(). +*/ + +void QtxDialog::reject() +{ + if ( testDialogFlags( Reject ) && !rejectData() ) + return; + + if ( !mySender ) + { + if ( testButtonFlags( Cancel ) ) + mySender = button( Cancel ); + else if ( testButtonFlags( No ) ) + mySender = button( No ); + else + mySender = button( Close ); + } + + if ( !mySender || !mySender->isWidgetType() || + !((QWidget*)mySender)->isEnabled() ) + return; + + QDialog::reject(); + + emitSignal(); +} + +/*! + Name: reject [private] + Desc: Emit signal appropriate to control button. +*/ + +void QtxDialog::emitSignal() +{ + qApp->processEvents(); + QApplication::syncX(); + + int id = buttonId( (QButton*)mySender ); + mySender = 0; + + switch ( id ) + { + case OK: + emit dlgOk(); + break; + case Cancel: + emit dlgCancel(); + break; + case Close: + emit dlgClose(); + break; + case Yes: + emit dlgYes(); + break; + case No: + emit dlgNo(); + break; + } +} + +/*! + Name: onAccept [private slot] + Desc: Process signals "clicked()" from control buttons "OK", "Yes". Invoke accept(). +*/ + +void QtxDialog::onAccept() +{ + const QObject* obj = sender(); + mySender = obj; + accept(); +} + +/*! + Name: onReject [private slot] + Desc: Process signals "clicked()" from control buttons "Cancel", "No", "Close". + Invoke reject(). +*/ + +void QtxDialog::onReject() +{ + const QObject* obj = sender(); + mySender = obj; + reject(); +} + +/*! + Name: onButton [private slot] + Desc: Receive signal "clicked()" from user buttons and emit signal + "dlgButton( int )" with identificator of clicked user button. +*/ + +void QtxDialog::onButton() +{ + int id = buttonId( (QButton*)sender() ); + if ( id != -1 ) + emit dlgButton( id ); +} + +/*! + Name: onDestroyed [private slot] + Desc: Remove user button if it was destroyed. +*/ + +void QtxDialog::onDestroyed( QObject* obj ) +{ + QButton* b = (QButton*)obj; + int id = buttonId( b ); + if ( id == -1 ) + return; + + myButton.remove( id ); + myPosition.remove( id ); + for ( AreaMap::Iterator it = myArea.begin(); it != myArea.end(); ++it ) + it.data()->removeButton( b ); +} + +/*! + Name: onSizeGripDestroyed [private slot] + Desc: Setting up layout when size grip is destroyed. +*/ + +void QtxDialog::onSizeGripDestroyed() +{ + if ( layout() ) + layout()->setMargin( 5 ); +} + +/*! + Name: adjustButtons [private] + Desc: Setting the equal with for all buttons. +*/ + +void QtxDialog::adjustButtons() +{ + int minWidth = 0; + for ( AreaMap::Iterator aIt = myArea.begin(); aIt != myArea.end(); ++aIt ) + for ( QPtrListIterator bIt( aIt.data()->buttons() ); bIt.current(); ++bIt ) + if ( bIt.current()->isVisibleTo( this ) ) + minWidth = QMAX( minWidth, bIt.current()->sizeHint().width() ); + + for ( AreaMap::Iterator aItr = myArea.begin(); aItr != myArea.end(); ++aItr ) + for ( QPtrListIterator bItr( aItr.data()->buttons() ); bItr.current(); ++bItr ) + if ( bItr.current()->isVisibleTo( this ) ) + bItr.current()->setMinimumWidth( minWidth ); +} diff --git a/src/Qtx/QtxDialog.h b/src/Qtx/QtxDialog.h new file mode 100755 index 000000000..321bc3e9b --- /dev/null +++ b/src/Qtx/QtxDialog.h @@ -0,0 +1,190 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxDialog.hxx +// Author: Sergey TELKOV + +#ifndef QTXDIALOG_H +#define QTXDIALOG_H + +#include "Qtx.h" + +#include +#include +#include + +class QFrame; +class QLabel; +class QButton; + +#ifdef WIN32 +#pragma warning( disable:4251 ) +#endif + +class QTX_EXPORT QtxDialog : public QDialog +{ + Q_OBJECT + + class Area; + class Border; + +public: + typedef enum { Position, Expand, Uniform } PlacePolicy; + typedef enum { TopArea, BottomArea, LeftArea, RightArea } ButtonArea; + typedef enum { Left, Right, Center, Top = Left, Bottom = Right } ButtonPosition; + + typedef enum { None = 0x00000000, + OK = 0x00000001, + Apply = 0x00000002, + Cancel = 0x00000004, + Yes = 0x00000008, + No = 0x00000010, + Close = 0x00000020, + Help = 0x00000040, + OKCancel = OK | Cancel, + YesNo = Yes | No, + Standard = OK | Cancel | Help, + All = Standard | YesNo | Apply | Close } ButtonFlags; + + typedef enum { Accept = 0x000001, + Reject = 0x000002, + AlignOnce = 0x000004, + SetFocus = 0x000008 } DialogFlags; + +public: + QtxDialog( QWidget* = 0, const char* = 0, bool = false, + bool = false, const int = Standard, WFlags = 0 ); + virtual ~QtxDialog(); + + void setDialogFlags( const int ); + void clearDialogFlags( const int ); + bool testDialogFlags( const int ) const; + + void setButtonFlags( const int ); + void clearButtonFlags( const int ); + bool testButtonFlags( const int ) const; + + int buttonPosition( const int ) const; + void setButtonPosition( const int, const int = -1 ); + void setPlacePosition( const int, const int ); + + int placePolicy( const int ) const; + void setPlacePolicy( const int, const int ); + void setButtonPlace( const int, const int ); + + QString buttonText( const int ); + void setButtonText( const int, const QString& text ); + + void setButtonFocus( const int ); + bool hasButtonFocus( const int ) const; + + bool isButtonEnabled( const int ) const; + void setButtonEnabled( const bool, const int ); + + bool isBorderEnabled( const int ) const; + void setBorderEnabled( const bool, const int ); + + void removeButton( const int ); + int insertButton( const QString&, const int = BottomArea ); + + QValueList userButtonIds() const; + QButton* userButton( const int ) const; + + virtual void show(); + virtual void hide(); + + uint setAlignment( uint align ); + static void setUnits( QLabel*, const QString& ); + +signals: + void dlgButton( int ); + void dlgParamChanged(); + + void dlgHelp(); + void dlgApply(); + + void dlgOk(); + void dlgNo(); + void dlgYes(); + void dlgClose(); + void dlgCancel(); + +public slots: + void update(); + +protected slots: + virtual void accept(); + virtual void reject(); + +private slots: + void onAccept(); + void onReject(); + void onButton(); + void onSizeGripDestroyed(); + void onDestroyed( QObject* ); + +protected: + typedef QMap ButtonMap; + +protected: + QFrame* mainFrame() const; + + virtual bool acceptData() const; + virtual bool rejectData() const; + + virtual QButton* createButton( QWidget* ); + + QButton* button( const int ) const; + ButtonMap buttons( const int = All ) const; + int buttonId( const QButton* ) const; + int buttonPosition( QButton* ) const; + + virtual void showEvent( QShowEvent* ); + virtual void hideEvent( QHideEvent* ); + virtual void closeEvent( QCloseEvent* ); + virtual void childEvent( QChildEvent* ); + virtual void keyPressEvent( QKeyEvent* ); + +private: + void adjustButtons(); + void emitSignal(); + +private: + typedef QMap AreaMap; + typedef QMap PositionMap; + + friend class Area; + +private: + AreaMap myArea; + ButtonMap myButton; + PositionMap myPosition; + + bool myInited; + const QObject* mySender; + uint myAlignment; + QFrame* myMainFrame; + int myButtonFlags; + int myDialogFlags; +}; + +#ifdef WIN32 +#pragma warning( default:4251 ) +#endif + +#endif diff --git a/src/Qtx/QtxDirListEditor.cxx b/src/Qtx/QtxDirListEditor.cxx new file mode 100644 index 000000000..0532cd77f --- /dev/null +++ b/src/Qtx/QtxDirListEditor.cxx @@ -0,0 +1,558 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "QtxDirListEditor.h" + +#include +#include +#include +#include +#include +#include + +#define MARGIN_SIZE 11 +#define SPACING_SIZE 6 +#define SPACER_SIZE 5 + +static const char* delete_icon[] = { +"16 16 3 1", +"` c #810000", +" c none", +"# c #ffffff", +" ", +" ", +" ``# ``# ", +" ````# ``# ", +" ````# ``# ", +" ```# `# ", +" `````# ", +" ```# ", +" `````# ", +" ```# ``# ", +" ```# ``# ", +" ```# `# ", +" ```# `# ", +" `# `# ", +" ", +" " +}; + +static const char* insert_icon[] = { +"16 16 5 1", +"` c #000000", +". c #ffff00", +"# c #9d9da1", +" c none", +"b c #ffffff", +" ", +" ", +" # #b #. ", +" # #.#.` ` ` ", +" .#.b#### ` ", +" ### .. ", +" . # .# ` ", +" #` #. ", +" # ` ", +" ` ", +" ` ", +" ` ", +" ` ", +" ` ` ` ` ` ` ", +" ", +" " +}; + +static const char* movedown_icon[] = { +"16 16 2 1", +"` c #000000", +" c none", +" ", +" ", +" ``` ", +" ``` ", +" ``` ", +" ``` ", +" ``` ", +" ``` ", +" ``````````` ", +" ````````` ", +" ``````` ", +" ````` ", +" ``` ", +" ` ", +" ", +" " +}; + +static const char* moveup_icon[] = { +"16 16 2 1", +"` c #000000", +" c none", +" ", +" ", +" ` ", +" ``` ", +" ````` ", +" ``````` ", +" ````````` ", +" ``````````` ", +" ``` ", +" ``` ", +" ``` ", +" ``` ", +" ``` ", +" ``` ", +" ", +" " +}; + +/*! + Constructor +*/ +QtxDirListEditor::QtxDirListEditor( QWidget* parent ) +: QWidget( parent ) +{ + myEdited = false; + myLastSelected = 0; + myEdit = 0; + myBtn = 0; + + QGridLayout* topLayout = new QGridLayout(this); + topLayout->setMargin(0); + topLayout->setSpacing(0); + + setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) ); + + myDirList = new QListBox(this); + myDirList->setSelectionMode(QListBox::Single); + myDirList->setHScrollBarMode(QListBox::AlwaysOff); + myDirList->horizontalScrollBar()->installEventFilter(this); + myDirList->verticalScrollBar()->installEventFilter(this); + myDirList->insertItem(tr("")); + myDirList->installEventFilter(this); + + QHBoxLayout* ctrlLayout = new QHBoxLayout; + ctrlLayout->setMargin(0); + ctrlLayout->setSpacing(0); + + // QLabel* lab = new QLabel(myDirList, tr("DIRECTORIES_LBL"), this); + + QToolButton* insertBtn = new QToolButton(this); + insertBtn->setIconSet(QPixmap( insert_icon )); + insertBtn->setAutoRaise(true); + + QToolButton* deleteBtn = new QToolButton(this); + deleteBtn->setIconSet(QPixmap( delete_icon )); + deleteBtn->setAutoRaise(true); + + QToolButton* upBtn = new QToolButton(this); + upBtn->setIconSet(QPixmap( moveup_icon )); + upBtn->setAutoRaise(true); + + QToolButton* downBtn = new QToolButton(this); + downBtn->setIconSet(QPixmap( movedown_icon )); + downBtn->setAutoRaise(true); + + // ctrlLayout->addWidget(lab); + ctrlLayout->addItem(new QSpacerItem(SPACER_SIZE, SPACER_SIZE, QSizePolicy::Expanding, QSizePolicy::Minimum)); + ctrlLayout->addWidget(insertBtn); + ctrlLayout->addWidget(deleteBtn); + ctrlLayout->addWidget(upBtn); + ctrlLayout->addWidget(downBtn); + + QHBoxLayout* btnLayout = new QHBoxLayout; + btnLayout->setMargin(0); + btnLayout->setSpacing(6); + + topLayout->addLayout(ctrlLayout, 0, 0); + topLayout->addWidget(myDirList, 1, 0); + topLayout->addLayout(btnLayout, 2, 0); + + connect(myDirList, SIGNAL(mouseButtonClicked(int, QListBoxItem*, const QPoint&)), + this, SLOT(onMouseButtonClicked(int, QListBoxItem*, const QPoint&))); + connect(myDirList, SIGNAL(doubleClicked(QListBoxItem*)), + this, SLOT(onDblClicked(QListBoxItem*))); + + connect(insertBtn, SIGNAL(clicked()), this, SLOT(onInsert())); + connect(deleteBtn, SIGNAL(clicked()), this, SLOT(onDelete())); + connect(upBtn, SIGNAL(clicked()), this, SLOT(onUp())); + connect(downBtn, SIGNAL(clicked()), this, SLOT(onDown())); +} + +/*! + Destructor +*/ +QtxDirListEditor::~QtxDirListEditor() +{ +} + +/*! + Gets list of paths +*/ +void QtxDirListEditor::getPathList(QStringList& list) +{ + list.clear(); + for (unsigned i = 0; i < myDirList->count()-1; i++) + list.append(myDirList->text(i)); +} + +/*! + Sets list of paths +*/ +void QtxDirListEditor::setPathList(const QStringList& list) { + myDirList->clear(); + myDirList->insertItem(tr("")); + for (unsigned i = 0; i < list.count(); i++) + myDirList->insertItem(list[i], myDirList->count()-1); +} + +/*! + Validates entered path, returns true if OK +*/ +bool QtxDirListEditor::validate() +{ + if ( myEdited ) + { + QString dirPath = QFileInfo( myEdit->text().stripWhiteSpace() ).absFilePath(); +/* +#ifndef WNT + if ( dirPath.startsWith( "~") ) { + dirPath = dirPath.remove(0,1); + QString user; + int slashPos = dirPath.find("/"); + if ( slashPos >= 0 ) { + user = dirPath.left(slashPos); + dirPath = dirPath.mid(slashPos); + } + else { + user = dirPath; + dirPath = ""; + } + if ( user.isEmpty() ) + user = getenv( "USER" ); + + struct passwd* user_data = getpwnam( user.latin1() ); + if ( user_data == NULL ) { + // unknown user or something another error + QMessageBox::critical(this, + tr("Error"), + tr("Unknown user %1").arg(user), + tr("Ok")); + myEdit->setFocus(); + return false; + } + dirPath = user_data->pw_dir + dirPath; + } +#endif +*/ + QDir dir(dirPath); + QListBoxItem* found = 0; + for (unsigned i = 0; i < myDirList->count()-1; i++) { + QDir aDir(myDirList->text(i)); + if ( aDir.canonicalPath().isNull() && myDirList->text(i) == dir.absPath() || + !aDir.canonicalPath().isNull() && aDir.exists() && aDir.canonicalPath() == dir.canonicalPath()) { + found = myDirList->item(i); + break; + } + } + if (dirPath.isEmpty()) { + if (found) { + // it should be last (empty) item in the list - nothing to do + return true; + } + else { + // delete directory from the list + removeDir(myLastSelected); + return true; + } + } + else { + if (found) { + if (found != myLastSelected) { + // it is forbidden to add directory more then once + QMessageBox::critical(this, + tr("Error"), + tr("Directory already specified."), + tr("Ok")); + myEdit->setFocus(); + return false; + } + } + else { + if (!dir.exists()) { + if ( QMessageBox::information(this, + tr("Warning"), + tr("%1\n\nThe directory doesn't exist.\nAdd directory anyway?").arg(dir.absPath()), + tr("Yes"), tr("No"), QString::null, 1, 1) == 1) { + myEdit->setFocus(); + return false; + } + } + // append + appendDir(myLastSelected, dir.absPath()); + } + } + } + return true; +} + +/*! + Appends/changes directory +*/ +void QtxDirListEditor::appendDir(QListBoxItem* item, const QString& dir) { + int index = myDirList->index(item); + if (index >= 0 && index < (int)myDirList->count()) { + if (index == (int)myDirList->count()-1) { + // it is the last item (new), well, insert it before the last (empty) + myDirList->insertItem(dir, myDirList->count()-1); + } + else { + // change item + myDirList->changeItem(dir, index); + } + } +} + +/*! + Removes directory from list +*/ +void QtxDirListEditor::removeDir(QListBoxItem* item) { + // do not remove last item (empty) + int index = myDirList->index(item); + if (index >= 0 && index < (int)myDirList->count()-1) { + delete item; + myLastSelected = myDirList->item(index); + myDirList->setSelected(myLastSelected, true); + } +} + +/*! + Resize event +*/ +void QtxDirListEditor::resizeEvent(QResizeEvent* event) { + QWidget::resizeEvent(event); + if ( myEdited ) { + myEdit->resize(myDirList->viewport()->width()-myBtn->sizeHint().width(), myEdit->height()); + myBtn->move(myEdit->width(), myEdit->y()); + } +} + +/*! + Called when user clicks inside directories list box +*/ +void QtxDirListEditor::onMouseButtonClicked(int button, + QListBoxItem* item, + const QPoint& point) { + if (myEdited) { + if (!validate()) { + myDirList->setCurrentItem(myLastSelected); + myDirList->setSelected(myLastSelected, true); + return; + } + delete myEdit; + delete myBtn; + myEdit = 0; + myBtn = 0; + myEdited = false; + myDirList->setFocus(); + } + if (item) { + myDirList->setCurrentItem(item); + myDirList->setSelected(item, true); + myDirList->ensureCurrentVisible(); + qApp->processEvents(); + if (button == LeftButton && myLastSelected == item) { + QRect ir = myDirList->itemRect(myLastSelected); + + myEdit = new QLineEdit(myDirList->viewport()); + myBtn = new QToolButton(myDirList->viewport()); + myBtn->setText(" ... "); + connect(myBtn, SIGNAL(clicked()), this, SLOT(onBtnClicked())); + myEdit->setGeometry(0, + ir.top()-(myEdit->sizeHint().height()-ir.height())/2, + myDirList->viewport()->width()-myBtn->sizeHint().width(), + myEdit->sizeHint().height()); + myBtn->setGeometry (myEdit->width(), + ir.top()-(myEdit->sizeHint().height()-ir.height())/2, + myBtn->sizeHint().width(), + myEdit->sizeHint().height()); + connect(myEdit, SIGNAL(returnPressed()), this, SLOT(onEditFinished())); + myEdited = true; + myEdit->show(); + myBtn->show(); + if (myDirList->index(myLastSelected) != (int)myDirList->count()-1) + myEdit->setText(myLastSelected->text()); + myEdit->selectAll(); + myEdit->setCursorPosition(myEdit->text().length()); + myEdit->installEventFilter(this); + myEdit->setFocus(); + } + } + else { + myDirList->clearSelection(); + } + myLastSelected = item; +} + +/*! + Called when user double-clicks on any item +*/ +void QtxDirListEditor::onDblClicked(QListBoxItem* item) { + onMouseButtonClicked(LeftButton, item, QPoint(0,0)); +} + +/*! + <...> (Browse dir) button slot +*/ +void QtxDirListEditor::onBtnClicked() { + QString dir = myEdit->text().stripWhiteSpace().isEmpty() ? + QString::null : + myEdit->text().stripWhiteSpace(); + + dir = QFileDialog::getExistingDirectory(dir, this, 0, tr("Select directory"), true); + + if (!dir.isEmpty()) { + myEdit->setText(dir); + myEdit->selectAll(); + myEdit->setCursorPosition(myEdit->text().length()); + } +} + +/*! + Called when user finises editing of path by pressing +*/ +void QtxDirListEditor::onEditFinished() { + if (myEdit) { + if (!validate()) { + myDirList->setCurrentItem(myLastSelected); + myDirList->setSelected(myLastSelected, true); + return; + } + myEdit->deleteLater(); + myBtn->deleteLater(); + myEdit = 0; + myBtn = 0; + myEdited = false; + myDirList->setFocus(); + } +} + +/*! + Event filter +*/ +bool QtxDirListEditor::eventFilter(QObject* object, QEvent* event) { + if ( myEdited ) { + if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick) { + if (object == myDirList->horizontalScrollBar() || object == myDirList->verticalScrollBar()) { + if (!validate()) { + myDirList->setCurrentItem(myLastSelected); + myDirList->setSelected(myLastSelected, true); + return true; + } + delete myEdit; + delete myBtn; + myEdit = 0; + myBtn = 0; + myEdited = false; + myDirList->setFocus(); + } + } + else if (event->type() == QEvent::KeyPress) { + QKeyEvent* ke = (QKeyEvent*)event; + if (ke->key() == Key_Tab) + return true; + if (object == myDirList) { + return true; + } + else if (object == myEdit) { + if ( ke->key() == Key_Up || ke->key() == Key_Down || ke->key() == Key_PageUp || ke->key() == Key_PageDown || + ( ke->key() == Key_Home || ke->key() == Key_End || ke->key() == Key_Prior || ke->key() == Key_Next ) && + (ke->state() & ControlButton) ) { + return true; + } + else if ( ke->key() == Key_Escape ) { + delete myEdit; + delete myBtn; + myEdit = 0; + myBtn = 0; + myEdited = false; + myDirList->setFocus(); + return true; + } + } + } + } + return QWidget::eventFilter(object, event); +} + +/*! + button slot +*/ +void QtxDirListEditor::onInsert() { + if (!myEdited) { + myLastSelected = 0; + onMouseButtonClicked(LeftButton, myDirList->item(myDirList->count()-1), QPoint(0,0)); + onMouseButtonClicked(LeftButton, myDirList->item(myDirList->count()-1), QPoint(0,0)); + } +} + +/*! + button slot +*/ +void QtxDirListEditor::onDelete() { + if (!myEdited && myDirList->currentItem() >=0) { + removeDir(myDirList->item(myDirList->currentItem())); + myDirList->setFocus(); + } +} + +/*! + button slot +*/ +void QtxDirListEditor::onUp() { + if (!myEdited && myLastSelected) { + int index = myDirList->currentItem(); + if (index > 0 && index < (int)myDirList->count()-1 && myDirList->isSelected(index)) { + QString t = myDirList->text(index-1); + myDirList->changeItem(myDirList->text(index), index-1); + myDirList->changeItem(t, index); + myDirList->setCurrentItem(index-1); + myLastSelected = myDirList->item(index-1); + myDirList->setSelected(myLastSelected, true); + myDirList->setFocus(); + } + } +} + +/*! + button slot +*/ +void QtxDirListEditor::onDown() { + if (!myEdited && myLastSelected) { + int index = myDirList->currentItem(); + if (index >= 0 && index < (int)myDirList->count()-2 && myDirList->isSelected(index)) { + QString t = myDirList->text(index+1); + myDirList->changeItem(myDirList->text(index), index+1); + myDirList->changeItem(t, index); + myDirList->setCurrentItem(index+1); + myLastSelected = myDirList->item(index+1); + myDirList->setSelected(myLastSelected, true); + myDirList->setFocus(); + } + } +} diff --git a/src/Qtx/QtxDirListEditor.h b/src/Qtx/QtxDirListEditor.h new file mode 100644 index 000000000..95e84228e --- /dev/null +++ b/src/Qtx/QtxDirListEditor.h @@ -0,0 +1,149 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef QTX_DIRLISTEDITOR_H +#define QTX_DIRLISTEDITOR_H + +#include "Qtx.h" + +#include +#include +#include +#include +#include + +#ifdef WIN32 +#pragma warning( disable:4251 ) +#endif + +/*! + * \brief The GUI implementation of the directory list + */ +class QTX_EXPORT QtxDirListEditor : public QWidget { + + Q_OBJECT + +public: + + /*! + * \brief Constructor + * \param parent - the parent of the widget + */ + QtxDirListEditor(QWidget* parent); + + /*! + * \brief Destructor + */ + ~QtxDirListEditor(); + + /*! + * \brief Gets list of paths + * \param list - the returned reference to the list of paths + */ + void getPathList(QStringList& list); + + /*! + * \brief Sets list of paths + * \param list - the list of paths to set + */ + void setPathList(const QStringList& list); + + /*! + * \brief Event filter, redefined from QObject class + */ + bool eventFilter(QObject* object, QEvent* event); + +protected: + + /*! + * \brief Validates entered path + * \retval bool - returns status (true if OK) + */ + bool validate(); + + /*! + * \brief Appends/changes path + * \param item - the item in QListBox + * \param dir - the path + */ + void appendDir(QListBoxItem* item, const QString& dir); + + /*! + * \brief Removes directory from list + * \param item - the item in QListBox + */ + void removeDir(QListBoxItem* item); + + /*! + * \brief Resize event handler, reimplemented from QWidget + * \param event - the resize event + */ + void resizeEvent(QResizeEvent* event); + +protected slots: + + /*! + * \brief Called when user clicks inside directories list box + */ + void onMouseButtonClicked(int, QListBoxItem*, const QPoint&); + + /*! + * \brief Called when user double-clicks on any item + */ + void onDblClicked(QListBoxItem*); + + /*! + * \brief <...> (Browse dir) button slot + */ + void onBtnClicked(); + + /*! + * \brief Ccalled when user finises editing of path by pressing + */ + void onEditFinished(); + + /*! + * \brief button slot + */ + void onInsert(); + + /*! + * \brief button slot + */ + void onDelete(); + + /*! + * \brief button slot + */ + void onUp(); + + /*! + * \brief button slot + */ + void onDown(); + +private: + QListBox* myDirList; //!< directory list + QLineEdit* myEdit; //!< path edit box + QToolButton* myBtn; //!< browse pah button + bool myEdited; //!< edit mode flag + QListBoxItem* myLastSelected; //!< last selected row + +}; + +#endif diff --git a/src/Qtx/QtxDockAction.cxx b/src/Qtx/QtxDockAction.cxx new file mode 100755 index 000000000..89e72344c --- /dev/null +++ b/src/Qtx/QtxDockAction.cxx @@ -0,0 +1,1250 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxDockAction.cxx +// Author: Sergey TELKOV + +#include "QtxDockAction.h" + +#include "QtxResourceMgr.h" + +#include +#include +#include +#include +#include +#include + +/*! + Name: QtxDockAction [public] + Desc: Constructs an Dock action with given main window and name. +*/ + +QtxDockAction::QtxDockAction( QMainWindow* mw, const char* name ) +: QtxAction( "Windows and Toolbars", "Windows and Toolbars", 0, mw, name ), +myMain( mw ), +myAutoAdd( true ), +mySeparate( true ), +myAutoPlace( false ) +{ + initialize( mw ); +} + +/*! + Name: QtxDockAction [public] + Desc: This constructor creates an action with the following properties: the + description text, the menu text and. It is a child of given main window + and named specified name. +*/ + +QtxDockAction::QtxDockAction( const QString& text, const QString& menuText, QMainWindow* mw, const char* name ) +: QtxAction( text, menuText, 0, mw, name ), +myMain( mw ), +myAutoAdd( true ), +mySeparate( true ), +myAutoPlace( false ) +{ + initialize( mw ); +} + +/*! + Name: QtxDockAction [public] + Desc: This constructor creates an action with the following properties: the + description text, the menu text, the icon or iconset icon and keyboard + accelerator. It is a child of given main window and named specified name. +*/ + +QtxDockAction::QtxDockAction( const QString& text, const QIconSet& icon, const QString& menuText, QMainWindow* mw, const char* name ) +: QtxAction( text, icon, menuText, 0, mw, name ), +myMain( mw ), +myAutoAdd( true ), +mySeparate( true ), +myAutoPlace( false ) +{ + initialize( mw ); +} + +/*! + Name: ~QtxDockAction [public] + Desc: Removes all added popup items. +*/ + +QtxDockAction::~QtxDockAction() +{ + for ( MenuMap::ConstIterator mIt = myMenu.begin(); mIt != myMenu.end(); ++mIt ) + removeFrom( mIt.key() ); + + for ( InfoMap::ConstIterator iIt = myInfo.begin(); iIt != myInfo.end(); ++iIt ) + delete iIt.data().a; +} + +/*! + Name: mainWindow [public] + Desc: Returns the main window which contains managed dock windows. +*/ + +QMainWindow* QtxDockAction::mainWindow() const +{ + return myMain; +} + +/*! + Name: isAutoAdd [public] + Desc: Returns the auto add property. If this property is setted then all newly + appeared dock windows will be automatically added. +*/ + +bool QtxDockAction::isAutoAdd() const +{ + return myAutoAdd; +} + +/*! + Name: setAutoAdd [public] + Desc: Sets the auto add property. If this property is setted then all newly + appeared dock windows will be automatically added. +*/ + +void QtxDockAction::setAutoAdd( const bool on ) +{ + myAutoAdd = on; +} + +/*! + Name: isAutoPlace [public] + Desc: Returns the auto place property. If this property is setted then all newly + added dock windows will be automatically placed according stored place information. +*/ + +bool QtxDockAction::isAutoPlace() const +{ + return myAutoPlace; +} + +/*! + Name: setAutoPlace [public] + Desc: Sets the auto place property. If this property is setted then all newly + added dock windows will be automatically placed according stored place + information. +*/ + +void QtxDockAction::setAutoPlace( const bool on ) +{ + myAutoPlace = on; +} + +/*! + Name: isSeparate [public] + Desc: Returns the 'separate' property. +*/ + +bool QtxDockAction::isSeparate() const +{ + return mySeparate; +} + +/*! + Name: setSeparate [public] + Desc: Sets the 'separate' property. If this property is 'true' then toolbars and + dock windows menu items will be placed in different popup menus otherwise + their will be placed in one common popup menu. This property will be + affected in next method 'addTo'. +*/ + +void QtxDockAction::setSeparate( const bool on ) +{ + if ( mySeparate == on ) + return; + + mySeparate = on; + updateMenus(); +} + +/*! + Name: addTo [public] + Desc: Add the dock windows sub menu item to the end of specified popup. +*/ + +bool QtxDockAction::addTo( QWidget* wid ) +{ + return addTo( wid, -1 ); +} + +/*! + Name: addTo [public] + Desc: Add the dock windows sub menu item to specified popup at the given index. +*/ + +bool QtxDockAction::addTo( QWidget* wid, const int idx ) +{ + if ( !wid || !wid->inherits( "QPopupMenu" ) ) + return false; + + QPopupMenu* pm = (QPopupMenu*)wid; + checkPopup( pm ); + + if ( myMenu.contains( pm ) ) + return false; + + MenuInfo mInfo; + mInfo.dock = new QPopupMenu( pm ); + mInfo.tool = isSeparate() ? new QPopupMenu( pm ) : 0; + + QString dock, tool; + splitMenuText( dock, tool ); + + myMenu.insert( pm, mInfo ); + + int index = idx; + + if ( mInfo.dock ) + iconSet().isNull() ? pm->insertItem ( dock, mInfo.dock, -1, index ) : + pm->insertItem ( iconSet(), dock, mInfo.dock, -1, index ); + + if ( index >= 0 ) + index++; + + if ( mInfo.tool ) + iconSet().isNull() ? pm->insertItem ( tool, mInfo.tool, -1, index ) : + pm->insertItem ( iconSet(), tool, mInfo.tool, -1, index ); + + connect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) ); + connect( pm, SIGNAL( destroyed( QObject* ) ), this, SLOT( onPopupDestroyed( QObject* ) ) ); + + return true; +} + +/*! + Name: removeFrom [public] + Desc: Removes dock window sub menu from specified popup. +*/ + +bool QtxDockAction::removeFrom( QWidget* wid ) +{ + QPopupMenu* pm = (QPopupMenu*)wid; + + if ( myMenu.contains( pm ) ) + { + pm->removeItem( findId( pm, myMenu[pm].dock ) ); + pm->removeItem( findId( pm, myMenu[pm].tool ) ); + + delete myMenu[pm].dock; + delete myMenu[pm].tool; + myMenu.remove( pm ); + + disconnect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) ); + disconnect( pm, SIGNAL( destroyed( QObject* ) ), this, SLOT( onPopupDestroyed( QObject* ) ) ); + } + + return QtxAction::removeFrom( wid ); +} + +void QtxDockAction::setMenuText( const QString& txt ) +{ + if ( menuText() == txt ) + return; + + QtxAction::setMenuText( txt ); + updateMenus(); +} + +/*! + Name: addDockWindow [public] + Desc: Add dock window to internal data structures. Action will be include all added + dock windows in to menu and manage their place configuration. +*/ + +bool QtxDockAction::addDockWindow( QDockWindow* dw ) +{ + if ( !dw || !mainWindow() ) + return false; + + if ( myInfo.contains( dw ) ) + return false; + + myInfo.insert( dw, DockInfo() ); + + DockInfo& inf = myInfo[dw]; + inf.name = windowName( dw ); + QAction* a = inf.a = new QAction( mainWindow(), 0, true ); + + autoLoadPlaceInfo( dw ); + + bool block = a->signalsBlocked(); + a->blockSignals( true ); + a->setOn( dw->isVisibleTo( mainWindow() ) ); + a->blockSignals( block ); + + updateInfo( dw ); + savePlaceInfo( dw ); + + dw->installEventFilter( this ); + + connect( a, SIGNAL( toggled( bool ) ), this, SLOT( onToggled( bool ) ) ); + connect( dw, SIGNAL( destroyed( QObject* ) ), this, SLOT( onWindowDestroyed( QObject* ) ) ); + connect( dw, SIGNAL( visibilityChanged( bool ) ), this, SLOT( onVisibilityChanged( bool ) ) ); + + return true; +} + +/*! + Name: removeDockWindow [public] + Desc: Remove dock window from internal data structures. Action will not manage this window. +*/ + +bool QtxDockAction::removeDockWindow( QDockWindow* dw ) +{ + if ( !myInfo.contains( dw ) ) + return false; + + myGeom.remove( myInfo[dw].name ); + + delete myInfo[dw].a; + myInfo.remove( dw ); + + dw->removeEventFilter( this ); + + disconnect( dw, SIGNAL( destroyed( QObject* ) ), this, SLOT( onWindowDestroyed( QObject* ) ) ); + disconnect( dw, SIGNAL( visibilityChanged( bool ) ), this, SLOT( onVisibilityChanged( bool ) ) ); + + return true; +} + +/*! + Name: eventFilter [public] + Desc: Event filter process caption and icon changing of managed dock windows + and try to add newly appeared dock windows. +*/ + +bool QtxDockAction::eventFilter( QObject* o, QEvent* e ) +{ + if ( o->inherits( "QDockWindow" ) && ( e->type() == QEvent::CaptionChange || + e->type() == QEvent::IconChange ) ) + updateInfo( (QDockWindow*)o ); + + if ( o->inherits( "QDockArea" ) && e->type() == QEvent::ChildRemoved ) + { + QChildEvent* ce = (QChildEvent*)e; + if ( ce->child() && ce->child()->inherits( "QDockWindow" ) ) + savePlaceInfo( (QDockWindow*)ce->child() ); + } + + if ( o->inherits( "QDockArea" ) && e->type() == QEvent::ChildInserted ) + { + QChildEvent* ce = (QChildEvent*)e; + if ( ce->child() && ce->child()->inherits( "QDockWindow" ) ) + QApplication::postEvent( this, new QCustomEvent( (QEvent::Type)AutoAdd, ce->child() ) ); + } + + return false; +} + +/*! + Name: restoreGeometry [public] + Desc: Retrieve the dock window geometry. If dock window specified as 0 + then all windows geometry will be restored. +*/ + +void QtxDockAction::restoreGeometry( QDockWindow* dw ) const +{ + if ( !dw ) + loadPlaceInfo(); + else + loadPlaceInfo( dw ); +} + +/*! + Name: storeGeometry [public] + Desc: Store the dock window geometry. If dock window specified as 0 + then all windows geometry will be stored. +*/ + +void QtxDockAction::storeGeometry( QDockWindow* dw ) +{ + QPtrList dwList; + + if ( dw ) + dwList.append( dw ); + else + dockWindows( dwList ); + + for ( QPtrListIterator it( dwList ); it.current(); ++it ) + savePlaceInfo( it.current() ); +} + +/*! + Name: loadGeometry [public] + Desc: Retrieve the dock windows geometry information from the specified resource manager section. +*/ + +void QtxDockAction::loadGeometry( QtxResourceMgr* resMgr, const QString& section, const bool clear ) +{ + QString sec = section.stripWhiteSpace(); + if ( !resMgr || sec.isEmpty() ) + return; + + myNames = QStringList::split( "|", resMgr->stringValue( sec, "windows_list", QString::null ) ); + + QMap map; + QStringList params = resMgr->parameters( sec ); + for ( QStringList::const_iterator it = params.begin(); it != params.end(); ++it ) + { + QString p = QStringList::split( ".", *it, true ).first().stripWhiteSpace(); + if ( !p.isEmpty() ) + map.insert( p, 0 ); + } + + for ( QMap::ConstIterator itr = map.begin(); itr != map.end(); ++itr ) + { + GeomInfo inf; + if ( !clear && myGeom.contains( itr.key() ) ) + inf = myGeom[itr.key()]; + else + { + inf.vis = true; inf.newLine = false; inf.place = DockTop; + inf.index = 0; inf.offset = 0; + inf.x = 0; inf.y = 0; inf.w = 0; inf.h = 0; + inf.fixW = -1; inf.fixH = -1; + } + if ( loadGeometry( resMgr, sec, itr.key(), inf ) ) + myGeom.insert( itr.key(), inf ); + } +} + +/*! + Name: saveGeometry [public] + Desc: Store the dock windows geometry information into the specified resource manager section. +*/ + +void QtxDockAction::saveGeometry( QtxResourceMgr* resMgr, const QString& section, const bool clear ) const +{ + QString sec = section.stripWhiteSpace(); + if ( !resMgr || sec.isEmpty() ) + return; + + QtxDockAction* that = (QtxDockAction*)this; + that->storeGeometry(); + + that->myNames.clear(); + collectNames( Minimized, that->myNames ); + for ( int i = DockTornOff; i < Minimized; i++ ) + collectNames( i, that->myNames ); + + if ( clear ) + resMgr->remove( sec ); + + resMgr->setValue( sec, "windows_list", myNames.join( "|" ) ); + + for ( GeomMap::ConstIterator it = myGeom.begin(); it != myGeom.end(); ++it ) + saveGeometry( resMgr, sec, it.key(), it.data() ); +} + +/*! + Name: onAboutToShow [private slots] + Desc: Prepare sub popup with dock windows list when parent popup is shown. +*/ + +void QtxDockAction::onAboutToShow() +{ + const QObject* obj = sender(); + if ( obj && obj->inherits( "QPopupMenu" ) ) + { + QPopupMenu* pm = (QPopupMenu*)obj; + fillPopup( pm ); + pm->setItemEnabled( findId( pm, myMenu[pm].dock ), isEnabled() && myMenu[pm].dock && myMenu[pm].dock->count() ); + pm->setItemEnabled( findId( pm, myMenu[pm].tool ), isEnabled() && myMenu[pm].tool && myMenu[pm].tool->count() ); + } +} + +/*! + Name: onToggled [private slots] + Desc: Show or hide dock window when user toggled window item in popup. +*/ + +void QtxDockAction::onToggled( bool on ) +{ + QDockWindow* dw = dockWindow( (QAction*)sender() ); + if ( dw ) + on ? dw->show() : dw->hide(); +} + +/*! + Name: onPopupDestroyed [private slots] + Desc: Remove destroyed popup from data structures. +*/ + +void QtxDockAction::onPopupDestroyed( QObject* obj ) +{ + myMenu.remove( (QPopupMenu*)obj ); +} + +/*! + Name: onWindowDestroyed [private slots] + Desc: Remove information about destroyed dock window. +*/ + +void QtxDockAction::onWindowDestroyed( QObject* obj ) +{ + QDockWindow* dw = (QDockWindow*)obj; + if ( !myInfo.contains( dw ) ) + return; + + delete myInfo[dw].a; + myInfo.remove( dw ); +} + +/*! + Name: onVisibilityChanged [private slots] + Desc: Toggle corresponded action when visibility state of dock window changed. +*/ + +void QtxDockAction::onVisibilityChanged( bool on ) +{ + const QObject* obj = sender(); + if ( !obj || !obj->inherits( "QDockWindow" ) ) + return; + + QDockWindow* dw = (QDockWindow*)obj; + + QAction* a = action( dw ); + if ( a && a->isOn() != on ) + { + bool block = a->signalsBlocked(); + a->blockSignals( true ); + a->setOn( on ); + a->blockSignals( block ); + } + + savePlaceInfo( dw ); +} + +/*! + Name: onDockWindowPositionChanged [private slots] + Desc: Update dock window place information +*/ + +void QtxDockAction::onDockWindowPositionChanged( QDockWindow* dw ) +{ + savePlaceInfo( dw ); +} + +/*! + Name: event [protected] + Desc: Check consistency the popup content and internal datas. + Synchronize internal data structures with popup content. +*/ + +bool QtxDockAction::event( QEvent* e ) +{ + if ( e->type() == (int)AutoAdd ) + { + QCustomEvent* ce = (QCustomEvent*)e; + QDockWindow* dw = (QDockWindow*)ce->data(); + if ( !myInfo.contains( dw ) ) + { + autoAddDockWindow( dw ); + autoLoadPlaceInfo( dw ); + } + } + + return QtxAction::event( e ); +} + +/*! + Name: checkPopup [private] + Desc: Check consistency the popup content and internal datas. + Synchronize internal data structures with popup content. +*/ + +void QtxDockAction::checkPopup( QPopupMenu* pm ) +{ + if ( !myMenu.contains( pm ) ) + return; + + int id = findId( pm, myMenu[pm].dock ); + if ( id == -1 ) + { + delete myMenu[pm].dock; + myMenu[pm].dock = 0; + } + id = findId( pm, myMenu[pm].tool ); + if ( id == -1 ) + { + delete myMenu[pm].tool; + myMenu[pm].tool = 0; + } + + if ( !myMenu[pm].dock ) + { + delete myMenu[pm].tool; + myMenu.remove( pm ); + disconnect( pm, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) ); + } +} + +/*! + Name: fillPopup [private] + Desc: Clear the popup and the add to it required actions. +*/ + +void QtxDockAction::fillPopup( QPopupMenu* pm ) const +{ + if ( !pm || !mainWindow() ) + return; + + if ( !myMenu.contains( pm ) ) + return; + + QPopupMenu* dockMenu = myMenu[pm].dock; + QPopupMenu* toolMenu = myMenu[pm].tool; + + for ( InfoMap::ConstIterator mit = myInfo.begin(); mit != myInfo.end(); ++mit ) + { + mit.data().a->removeFrom( dockMenu ); + mit.data().a->removeFrom( toolMenu ); + } + + if ( dockMenu ) + dockMenu->clear(); + + if ( toolMenu ) + toolMenu->clear(); + + QPtrList dockList; + dockWindows( dockList, mainWindow() ); + + if ( dockList.isEmpty() ) + return; + + QPtrList toolBars, windows; + for ( QPtrListIterator it( dockList ); it.current(); ++it ) + { + if ( !myInfo.contains( it.current() ) ) + { + QtxDockAction* that = (QtxDockAction*)this; + that->autoAddDockWindow( it.current() ); + } + + if ( !mainWindow()->appropriate( it.current() ) || + it.current()->caption().isEmpty() || !action( it.current() ) ) + continue; + + if ( isToolBar( it.current() ) ) + toolBars.append( action( it.current() ) ); + else + windows.append( action( it.current() ) ); + } + + for ( QPtrListIterator wit( windows ); wit.current(); ++wit ) + wit.current()->addTo( dockMenu ); + + dockMenu->insertSeparator(); + + for ( QPtrListIterator tit( toolBars ); tit.current(); ++tit ) + tit.current()->addTo( toolMenu ? toolMenu : dockMenu ); + + Qtx::simplifySeparators( dockMenu ); + Qtx::simplifySeparators( toolMenu ); +} + +/*! + Name: isToolBar [private] + Desc: Returns 'true' if dock window is a toolbar. +*/ + +bool QtxDockAction::isToolBar( QDockWindow* dw ) const +{ + return dw && dw->inherits( "QToolBar" ); +} + +/*! + Name: findId [private] + Desc: Returns identificator of popup item which contains sub popup 'pm' in the popup 'cont'. +*/ + +int QtxDockAction::findId( QPopupMenu* cont, QPopupMenu* pm ) const +{ + if ( !cont || !pm ) + return -1; + + int id = -1; + + for ( int i = 0; i < (int)cont->count() && id == -1; i++ ) + { + QMenuData* md = 0; + QMenuItem* item = cont->findItem( cont->idAt( i ), &md ); + if ( item && md == cont && item->popup() == pm ) + id = item->id(); + } + return id; +} + +/*! + Name: dockWindows [private] + Desc: Returns all dock windows of the main window. +*/ + +void QtxDockAction::dockWindows( QPtrList& lst, QMainWindow* main ) const +{ + lst.clear(); + + QMainWindow* mw = main ? main : mainWindow(); + if ( !mw ) + return; + + lst = mw->dockWindows(); +} + +/*! + Name: updateInfo [private] + Desc: Updates icon and caption info of dock window in the corresponded action. +*/ + +void QtxDockAction::updateInfo( QDockWindow* dw ) +{ + QAction* a = action( dw ); + if ( !a ) + return; + + a->setText( dw->caption() ); + a->setMenuText( dw->caption() ); + + if ( isToolBar( dw ) ) + a->setStatusTip( tr( "Toggles toolbar \"%1\" on/off" ).arg( dw->caption() ) ); + else + a->setStatusTip( tr( "Toggles window \"%1\" on/off" ).arg( dw->caption() ) ); + + const QPixmap* icon = dw->icon(); + if ( icon ) + a->setIconSet( *icon ); +} + +/*! + Name: savePlaceInfo [private] + Desc: Store the place and geometry information from specified dock window. +*/ + +void QtxDockAction::savePlaceInfo( QDockWindow* dw ) +{ + if ( !myInfo.contains( dw ) ) + return; + + if ( !myGeom.contains( myInfo[dw].name ) ) + myGeom.insert( myInfo[dw].name, GeomInfo() ); + + GeomInfo& inf = myGeom[myInfo[dw].name]; + + Dock dock; + inf.vis = dw->isVisibleTo( mainWindow() ); + mainWindow()->getLocation( dw, dock, inf.index, inf.newLine, inf.offset ); + + inf.place = dock; + inf.x = dw->x(); + inf.y = dw->y(); + inf.w = dw->width(); + inf.h = dw->height(); + inf.fixW = dw->fixedExtent().width(); + inf.fixH = dw->fixedExtent().height(); +} + +/*! + Name: loadPlaceInfo [private] + Desc: Retrieve the stored place and geometry information to specified dock window. +*/ + +void QtxDockAction::loadPlaceInfo( QDockWindow* dw ) const +{ + if ( !myInfo.contains( dw ) ) + return; + + QString winName = myInfo[dw].name; + if ( winName.isEmpty() || !myGeom.contains( winName ) ) + return; + + GeomInfo inf = myGeom[myInfo[dw].name]; + + mainWindow()->moveDockWindow( dw, (Qt::Dock)inf.place, inf.newLine, inf.index, inf.offset ); + dw->setGeometry( inf.x, inf.y, inf.w, inf.h ); + + dw->setFixedExtentWidth( inf.fixW ); + dw->setFixedExtentHeight( inf.fixH ); + + QtxDockAction* that = (QtxDockAction*)this; + that->myGeom.insert( myInfo[dw].name, inf ); +} + +/*! + Name: loadPlaceInfo [private] + Desc: Retrieve the stored place and geometry information to all dock windows. +*/ + +void QtxDockAction::loadPlaceInfo() const +{ + QMainWindow* mw = mainWindow(); + if ( !mw ) + return; + + typedef QPtrList DockWinList; + + DockWinList lst; + dockWindows( lst, mw ); + + QMap nameMap; + for ( QPtrListIterator itr( lst ); itr.current(); ++itr ) + { + QString name; + if ( myInfo.contains( itr.current() ) ) + name = myInfo[itr.current()].name; + + if ( !myGeom.contains( name ) ) + continue; + + nameMap.insert( name, itr.current() ); + } + + DockWinList winList; + for ( QStringList::const_iterator iter = myNames.begin(); iter != myNames.end(); ++iter ) + { + if ( nameMap.contains( *iter ) ) + winList.append( nameMap[*iter] ); + nameMap.remove( *iter ); + } + + for ( QMap::ConstIterator mIt = nameMap.begin(); mIt != nameMap.end(); ++mIt ) + winList.append( mIt.data() ); + + QMap winMap; + QMap geomMap; + + for ( QPtrListIterator it( winList ); it.current(); ++it ) + { + QString name; + if ( myInfo.contains( it.current() ) ) + name = myInfo[it.current()].name; + + if ( !myGeom.contains( name ) ) + continue; + + //! collect pointer of info to have fresh info data after processEvents(); + GeomInfo* inf = (GeomInfo*)&( myGeom[name] ); + geomMap.insert( it.current(), inf ); + if ( !winMap.contains( inf->place ) ) + winMap.insert( inf->place, DockWinList() ); + winMap[inf->place].append( it.current() ); + } + + loadPlaceArea( DockMinimized, mw, 0, + winMap.contains( DockMinimized ) ? winMap[DockMinimized] : DockWinList(), geomMap ); + for ( int i = DockTornOff; i < DockMinimized; i++ ) + { + loadPlaceArea( i, mw, dockArea( i ), winMap.contains( i ) ? winMap[i] : DockWinList(), geomMap ); + } +} + +/*! + Name: loadPlaceArea [private] + Desc: Set the place and geometry information to all dock windows in the area. +*/ + +void QtxDockAction::loadPlaceArea( const int place, QMainWindow* mw, QDockArea* area, + const QPtrList& dockList, + const QMap& geomMap ) const +{ + for ( QPtrListIterator it( dockList ); it.current(); ++it ) + { + if ( !geomMap.contains( it.current() ) ) + continue; + + GeomInfo* inf = geomMap[it.current()]; + mw->moveDockWindow( it.current(), (Qt::Dock)place, inf->newLine, inf->index, inf->offset ); + } + + if ( !area ) + return; + + qApp->processEvents(); + + for ( QPtrListIterator itr( dockList ); itr.current(); ++itr ) + { + QDockWindow* dw = itr.current(); + if ( !geomMap.contains( dw ) ) + continue; + + GeomInfo* inf = geomMap[dw]; + if ( place != DockTornOff ) + { + dw->setNewLine( inf->newLine ); + dw->setOffset( inf->offset ); + dw->setFixedExtentWidth( inf->fixW ); + dw->setFixedExtentHeight( inf->fixH ); + } + dw->setGeometry( inf->x, inf->y, inf->w, inf->h ); + + QAction* a = action( dw ); + if ( a ) + { + bool block = a->signalsBlocked(); + a->blockSignals( true ); + a->setOn( inf->vis ); + a->blockSignals( block ); + } + + if ( mainWindow() && mainWindow()->appropriate( dw ) ) + inf->vis ? dw->show() : dw->hide(); + } + + QWidget* wid = area; + if ( wid->layout() ) + { + wid->layout()->invalidate(); + wid->layout()->activate(); + } +} + +/*! + Name: action [private] + Desc: Returns action for the given dock window. +*/ + +QAction* QtxDockAction::action( QDockWindow* dw ) const +{ + QAction* a = 0; + if ( myInfo.contains( dw ) ) + a = myInfo[dw].a; + return a; +} + +/*! + Name: dockWindow [private] + Desc: Returns dock window for the given action. +*/ + +QDockWindow* QtxDockAction::dockWindow( const QAction* a ) const +{ + QDockWindow* dw = 0; + for ( InfoMap::ConstIterator it = myInfo.begin(); it != myInfo.end() && !dw; ++it ) + { + if ( it.data().a == a ) + dw = it.key(); + } + return dw; +} + +/*! + Name: initialize [private] + Desc: Initialisation of the object. Sets the event filters and add existing dock windows. +*/ + +void QtxDockAction::initialize( QMainWindow* mw ) +{ + if ( !mw ) + return; + + QPtrList lst; + dockWindows( lst, mw ); + + for ( QPtrListIterator it( lst ); it.current(); ++it ) + QApplication::postEvent( this, new QCustomEvent( (QEvent::Type)AutoAdd, it.current() ) ); + + if ( mw->topDock() ) + mw->topDock()->installEventFilter( this ); + if ( mw->leftDock() ) + mw->leftDock()->installEventFilter( this ); + if ( mw->rightDock() ) + mw->rightDock()->installEventFilter( this ); + if ( mw->bottomDock() ) + mw->bottomDock()->installEventFilter( this ); + + connect( mw, SIGNAL( dockWindowPositionChanged( QDockWindow* ) ), + this, SLOT( onDockWindowPositionChanged( QDockWindow* ) ) ); +} + +/*! + Name: windowName [private] + Desc: Generate the dock window name. +*/ + +QString QtxDockAction::windowName( QDockWindow* dw ) const +{ + QString name; + + if ( dw ) + { + name = dw->name( "" ); + if ( name.isEmpty() ) + name = dw->caption(); + } + + return name; +} + +/*! + Name: autoAddDockWindow [private] + Desc: Add the dock window if auto add property is setted. +*/ + +bool QtxDockAction::autoAddDockWindow( QDockWindow* dw ) +{ + if ( !isAutoAdd() ) + return false; + + return addDockWindow( dw ); +} + +/*! + Name: autoLoadPlaceInfo [private] + Desc: Retieve the dock window place geometry if auto place property is setted. +*/ + +void QtxDockAction::autoLoadPlaceInfo( QDockWindow* dw ) +{ + if ( isAutoPlace() ) + loadPlaceInfo( dw ); +} + +/*! + Name: splitMenuText [private] + Desc: +*/ + +void QtxDockAction::splitMenuText( QString& dock, QString& tool ) const +{ + dock = tool = menuText(); + if ( !isSeparate() ) + return; + + QStringList lst = splitText( menuText(), "|" ); + if ( lst.count() < 2 ) + lst = splitText( menuText(), "and" ); + + dock = lst.first(); + tool = lst.last(); +} + +/*! + Name: splitText [private] + Desc: +*/ + +QStringList QtxDockAction::splitText( const QString& str, const QString& sep ) const +{ + QStringList res; + + int idx = str.lower().find( sep.lower() ); + if ( idx != -1 ) + { + res.append( str.mid( 0, idx ).stripWhiteSpace() ); + res.append( str.mid( idx + sep.length() ).stripWhiteSpace() ); + } + + return res; +} + +/*! + Name: dockPlace [private] + Desc: +*/ + +int QtxDockAction::dockPlace( const QString& dockName ) const +{ + static QMap dockNameMap; + if ( dockNameMap.isEmpty() ) + { + dockNameMap["top"] = DockTop; + dockNameMap["bottom"] = DockBottom; + dockNameMap["left"] = DockLeft; + dockNameMap["right"] = DockRight; + dockNameMap["tornoff"] = DockTornOff; + dockNameMap["torn_off"] = DockTornOff; + dockNameMap["outside"] = DockTornOff; + dockNameMap["undock"] = DockTornOff; + dockNameMap["minimized"] = DockMinimized; + dockNameMap["unmanaged"] = DockUnmanaged; + } + + int res = -1; + if ( dockNameMap.contains( dockName.lower() ) ) + res = dockNameMap[dockName.lower()]; + return res; +} + +/*! + Name: dockArea [private] + Desc: +*/ + +QDockArea* QtxDockAction::dockArea( const int place ) const +{ + if ( !mainWindow() ) + return 0; + + QDockArea* area = 0; + switch ( place ) + { + case DockTop: + area = mainWindow()->topDock(); + break; + case DockBottom: + area = mainWindow()->bottomDock(); + break; + case DockLeft: + area = mainWindow()->leftDock(); + break; + case DockRight: + area = mainWindow()->rightDock(); + break; + } + return area; +} + +/*! + Name: loadGeometry [private] + Desc: +*/ + +bool QtxDockAction::loadGeometry( QtxResourceMgr* resMgr, const QString& sec, + const QString& name, GeomInfo& inf ) const +{ + if ( !resMgr || sec.isEmpty() || name.isEmpty() ) + return false; + + QString tmpl = QString( "%1.%2" ).arg( name ); + + inf.vis = resMgr->booleanValue( sec, tmpl.arg( "visible" ), inf.vis ); + inf.newLine = resMgr->booleanValue( sec, tmpl.arg( "new_line" ), inf.newLine ); + + inf.index = resMgr->integerValue( sec, tmpl.arg( "index" ), inf.index ); + inf.offset = resMgr->integerValue( sec, tmpl.arg( "offset" ), inf.offset ); + + inf.x = resMgr->integerValue( sec, tmpl.arg( "x" ), inf.x ); + inf.y = resMgr->integerValue( sec, tmpl.arg( "y" ), inf.y ); + inf.w = resMgr->integerValue( sec, tmpl.arg( "width" ), inf.w ); + inf.h = resMgr->integerValue( sec, tmpl.arg( "height" ), inf.h ); + + inf.fixW = resMgr->integerValue( sec, tmpl.arg( "fixed_width" ), inf.fixW ); + inf.fixH = resMgr->integerValue( sec, tmpl.arg( "fixed_height" ), inf.fixH ); + + int place = -1; + if ( !resMgr->value( sec, tmpl.arg( "place" ), place ) ) + { + QString placeStr; + if ( resMgr->value( sec, tmpl.arg( "place" ), placeStr ) ) + place = dockPlace( placeStr ); + } + + if ( place >= DockUnmanaged && place <= DockMinimized ) + inf.place = place; + + return true; +} + +/*! + Name: saveGeometry [private] + Desc: +*/ + +bool QtxDockAction::saveGeometry( QtxResourceMgr* resMgr, const QString& sec, + const QString& name, const GeomInfo& inf ) const +{ + if ( !resMgr || sec.isEmpty() || name.isEmpty() ) + return false; + + QString tmpl = QString( "%1.%2" ).arg( name ); + + resMgr->setValue( sec, tmpl.arg( "visible" ), inf.vis ); + resMgr->setValue( sec, tmpl.arg( "new_line" ), inf.newLine ); + resMgr->setValue( sec, tmpl.arg( "index" ), inf.index ); + resMgr->setValue( sec, tmpl.arg( "offset" ), inf.offset ); + resMgr->setValue( sec, tmpl.arg( "x" ), inf.x ); + resMgr->setValue( sec, tmpl.arg( "y" ), inf.y ); + resMgr->setValue( sec, tmpl.arg( "width" ), inf.w ); + resMgr->setValue( sec, tmpl.arg( "height" ), inf.h ); + resMgr->setValue( sec, tmpl.arg( "fixed_width" ), inf.fixW ); + resMgr->setValue( sec, tmpl.arg( "fixed_height" ), inf.fixH ); + resMgr->setValue( sec, tmpl.arg( "place" ), inf.place ); + + return true; +} + +/*! + Name: collectNames [private] + Desc: +*/ + +void QtxDockAction::collectNames( const int place, QStringList& lst ) const +{ + QPtrList winList; + QDockArea* area = dockArea( place ); + if ( area ) + winList = area->dockWindowList(); + else + winList = mainWindow()->dockWindows( (Qt::Dock)place ); + + for ( QPtrListIterator it( winList ); it.current(); ++it ) + { + QString name; + if ( myInfo.contains( it.current() ) ) + name = myInfo[it.current()].name; + if ( name.isEmpty() ) + name = windowName( it.current() ); + if ( name.isEmpty() ) + continue; + + lst.append( name ); + } +} + +void QtxDockAction::updateMenus() +{ + for ( MenuMap::Iterator it = myMenu.begin(); it != myMenu.end(); ++it ) + { + QPopupMenu* pm = it.key(); + MenuInfo& inf = it.data(); + + int toolId = findId( pm, inf.tool ); + int dockId = findId( pm, inf.dock ); + + int index = pm->indexOf( dockId ); + + if ( isSeparate() && !inf.tool ) + inf.tool = new QPopupMenu( pm ); + + pm->removeItem( dockId ); + pm->removeItem( toolId ); + + if ( !isSeparate() && inf.tool ) + { + delete inf.tool; + inf.tool = 0; + } + + QString dock, tool; + splitMenuText( dock, tool ); + + if ( inf.dock ) + iconSet().isNull() ? pm->insertItem ( dock, inf.dock, -1, index ) : + pm->insertItem ( iconSet(), dock, inf.dock, -1, index ); + + if ( index >= 0 ) + index++; + + if ( inf.tool ) + iconSet().isNull() ? pm->insertItem ( tool, inf.tool, -1, index ) : + pm->insertItem ( iconSet(), tool, inf.tool, -1, index ); + } +} diff --git a/src/Qtx/QtxDockAction.h b/src/Qtx/QtxDockAction.h new file mode 100755 index 000000000..4583bebda --- /dev/null +++ b/src/Qtx/QtxDockAction.h @@ -0,0 +1,162 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxDockAction.h +// Author: Sergey TELKOV + +#ifndef QTX_DOCKACTION_H +#define QTX_DOCKACTION_H + +#include "QtxAction.h" + +#include +#include +#include + +class QAction; +class QDockArea; +class QDockWindow; +class QMainWindow; +class QtxResourceMgr; + +#ifdef WIN32 +#pragma warning( disable:4251 ) +#endif + +class QTX_EXPORT QtxDockAction : public QtxAction +{ + Q_OBJECT + + Q_PROPERTY( bool autoAdd READ isAutoAdd WRITE setAutoAdd ) + Q_PROPERTY( bool autoPlace READ isAutoPlace WRITE setAutoPlace ) + Q_PROPERTY( bool separate READ isSeparate WRITE setSeparate ) + +public: + QtxDockAction( QMainWindow*, const char* = 0 ); + QtxDockAction( const QString&, const QString&, QMainWindow*, const char* = 0 ); + QtxDockAction( const QString&, const QIconSet&, const QString&, QMainWindow*, const char* = 0 ); + virtual ~QtxDockAction(); + + QMainWindow* mainWindow() const; + + bool isAutoAdd() const; + void setAutoAdd( const bool ); + + bool isAutoPlace() const; + void setAutoPlace( const bool ); + + bool isSeparate() const; + void setSeparate( const bool ); + + virtual bool addTo( QWidget* ); + virtual bool addTo( QWidget*, const int ); + virtual bool removeFrom( QWidget* ); + virtual void setMenuText( const QString& ); + + bool addDockWindow( QDockWindow* ); + bool removeDockWindow( QDockWindow* ); + + virtual bool eventFilter( QObject*, QEvent* ); + + virtual void storeGeometry( QDockWindow* = 0 ); + virtual void restoreGeometry( QDockWindow* = 0 ) const; + + virtual void loadGeometry( QtxResourceMgr*, const QString&, const bool = true ); + virtual void saveGeometry( QtxResourceMgr*, const QString&, const bool = true ) const; + +private slots: + void onAboutToShow(); + void onToggled( bool ); + void onVisibilityChanged( bool ); + void onPopupDestroyed( QObject* ); + void onWindowDestroyed( QObject* ); + void onDockWindowPositionChanged( QDockWindow* ); + +protected: + virtual bool event( QEvent* ); + +private: + QAction* action( QDockWindow* ) const; + QDockWindow* dockWindow( const QAction* ) const; + + void checkPopup( QPopupMenu* ); + void fillPopup( QPopupMenu* ) const; + int findId( QPopupMenu*, QPopupMenu* ) const; + + void initialize( QMainWindow* ); + void updateInfo( QDockWindow* ); + bool isToolBar( QDockWindow* ) const; + void dockWindows( QPtrList&, QMainWindow* = 0 ) const; + + QString windowName( QDockWindow* ) const; + void savePlaceInfo( QDockWindow* ); + void loadPlaceInfo( QDockWindow* ) const; + void loadPlaceInfo() const; + + bool autoAddDockWindow( QDockWindow* ); + void autoLoadPlaceInfo( QDockWindow* ); + + void splitMenuText( QString&, QString& ) const; + QStringList splitText( const QString&, const QString& ) const; + + QDockArea* dockArea( const int ) const; + int dockPlace( const QString& ) const; + + void collectNames( const int, QStringList& ) const; + + void updateMenus(); + +private: + enum { AutoAdd = QEvent::User, LoadArea }; + + typedef struct { bool vis, newLine; + int place, index, offset; + int x, y, w, h, fixW, fixH; } GeomInfo; + typedef struct { QString name; QAction* a; } DockInfo; + typedef struct { QPopupMenu *dock, *tool; } MenuInfo; + + typedef QMap InfoMap; + typedef QMap GeomMap; + typedef QMap MenuMap; + +private: + bool loadGeometry( QtxResourceMgr*, const QString&, + const QString&, GeomInfo& ) const; + bool saveGeometry( QtxResourceMgr*, const QString&, + const QString&, const GeomInfo& ) const; + void loadPlaceArea( const int, QMainWindow*, QDockArea*, + const QPtrList&, + const QMap& ) const; + +private: + InfoMap myInfo; + MenuMap myMenu; + GeomMap myGeom; + QMainWindow* myMain; + QStringList myNames; + + bool myAutoAdd; + bool mySeparate; + bool myAutoPlace; +}; + +#ifdef WIN32 +#pragma warning( default:4251 ) +#endif + +#endif diff --git a/src/Qtx/QtxDockWindow.cxx b/src/Qtx/QtxDockWindow.cxx new file mode 100644 index 000000000..9872d8505 --- /dev/null +++ b/src/Qtx/QtxDockWindow.cxx @@ -0,0 +1,338 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxDockWindow.cxx +// Author: Sergey TELKOV + +#include "QtxDockWindow.h" + +#include +#include +#include +#include +#include + +/*! + Class: QtxDockWindow::Watcher [Internal] + Descr: Internal object with event filter. +*/ + +class QtxDockWindow::Watcher : public QObject +{ +public: + Watcher( QtxDockWindow* ); + + void shown( QtxDockWindow* ); + void hided( QtxDockWindow* ); + + virtual bool eventFilter( QObject*, QEvent* ); + +protected: + virtual void customEvent( QCustomEvent* ); + +private: + void installFilters(); + + void showContainer(); + void hideContainer(); + + void updateIcon(); + void updateCaption(); + void updateVisibility(); + +private: + QtxDockWindow* myCont; + bool myState; + bool myEmpty; + bool myVisible; +}; + +QtxDockWindow::Watcher::Watcher( QtxDockWindow* cont ) +: QObject( cont ), myCont( cont ), +myState( true ), +myEmpty( true ) +{ + if ( myCont->mainWindow() ) + myState = myCont->mainWindow()->appropriate( myCont ); + + myCont->installEventFilter( this ); + myVisible = myCont->isVisibleTo( myCont->parentWidget() ); + + installFilters(); +} + +bool QtxDockWindow::Watcher::eventFilter( QObject* o, QEvent* e ) +{ + if ( o == myCont && + ( e->type() == QEvent::Show || e->type() == QEvent::ShowToParent || + e->type() == QEvent::Hide || e->type() == QEvent::HideToParent || + e->type() == QEvent::ChildInserted ) ) + QApplication::postEvent( this, new QCustomEvent( QEvent::User ) ); + + if ( o != myCont && e->type() == QEvent::IconChange ) + updateIcon(); + + if ( o != myCont && e->type() == QEvent::CaptionChange ) + updateCaption(); + + if ( ( o != myCont && ( e->type() == QEvent::Hide || e->type() == QEvent::HideToParent ) ) || + ( o == myCont && ( e->type() == QEvent::ChildRemoved ) ) || + ( e->type() == QEvent::Show || e->type() == QEvent::ShowToParent ) ) + updateVisibility(); + + return false; +} + +void QtxDockWindow::Watcher::shown( QtxDockWindow* dw ) +{ + if ( dw != myCont ) + return; + + myVisible = true; +} + +void QtxDockWindow::Watcher::hided( QtxDockWindow* dw ) +{ + if ( dw != myCont ) + return; + + myVisible = false; +} + +void QtxDockWindow::Watcher::showContainer() +{ + if ( !myCont ) + return; + + QtxDockWindow* cont = myCont; + myCont = 0; + cont->show(); + myCont = cont; +} + +void QtxDockWindow::Watcher::hideContainer() +{ + if ( !myCont ) + return; + + QtxDockWindow* cont = myCont; + myCont = 0; + cont->hide(); + myCont = cont; +} + +void QtxDockWindow::Watcher::customEvent( QCustomEvent* e ) +{ + installFilters(); + + updateIcon(); + updateCaption(); + updateVisibility(); +} + +void QtxDockWindow::Watcher::installFilters() +{ + if ( !myCont ) + return; + + QBoxLayout* bl = myCont->boxLayout(); + if ( !bl ) + return; + + for ( QLayoutIterator it = bl->iterator(); it.current(); ++it ) + { + if ( it.current()->widget() ) + it.current()->widget()->installEventFilter( this ); + } +} + +void QtxDockWindow::Watcher::updateVisibility() +{ + if ( !myCont ) + return; + + QBoxLayout* bl = myCont->boxLayout(); + if ( !bl ) + return; + + bool vis = false; + for ( QLayoutIterator it = bl->iterator(); it.current() && !vis; ++it ) + vis = it.current()->widget() && it.current()->widget()->isVisibleTo( myCont ); + + QMainWindow* mw = myCont->mainWindow(); + if ( mw && myEmpty == vis ) + { + myEmpty = !vis; + if ( !myEmpty ) + mw->setAppropriate( myCont, myState ); + else + { + myState = mw->appropriate( myCont ); + mw->setAppropriate( myCont, false ); + } + } + + vis = !myEmpty && myVisible; + if ( vis != myCont->isVisibleTo( myCont->parentWidget() ) ) + vis ? showContainer() : hideContainer(); +} + +void QtxDockWindow::Watcher::updateIcon() +{ + if ( !myCont || !myCont->widget() ) + return; + + const QPixmap* ico = myCont->widget()->icon(); + myCont->setIcon( ico ? *ico : QPixmap() ); +} + +void QtxDockWindow::Watcher::updateCaption() +{ + if ( myCont && myCont->widget() && !myCont->widget()->caption().isNull() ) + myCont->setCaption( myCont->widget()->caption() ); +} + +/*! + Class: QtxDockWindow [Public] + Descr: +*/ + +QtxDockWindow::QtxDockWindow( Place p, QWidget* parent, const char* name, WFlags f ) +: QDockWindow( p, parent, name, f ), +myWatcher( 0 ), +myStretch( false ) +{ +} + +QtxDockWindow::QtxDockWindow( const bool watch, QWidget* parent, const char* name, WFlags f ) +: QDockWindow( InDock, parent, name, f ), +myWatcher( 0 ), +myStretch( false ) +{ + if ( watch ) + myWatcher = new Watcher( this ); +} + +QtxDockWindow::QtxDockWindow( QWidget* parent, const char* name, WFlags f ) +: QDockWindow( InDock, parent, name, f ), +myWatcher( 0 ), +myStretch( false ) +{ +} + +QtxDockWindow::~QtxDockWindow() +{ +} + +void QtxDockWindow::setWidget( QWidget* wid ) +{ + if ( wid ) + wid->reparent( this, QPoint( 0, 0 ), wid->isVisibleTo( wid->parentWidget() ) ); + + QDockWindow::setWidget( wid ); +} + +bool QtxDockWindow::isStretchable() const +{ + return myStretch; +} + +void QtxDockWindow::setStretchable( const bool on ) +{ + if ( myStretch == on ) + return; + + myStretch = on; + + boxLayout()->setStretchFactor( widget(), myStretch ? 1 : 0 ); + + if ( myStretch != isHorizontalStretchable() || + myStretch != isVerticalStretchable() ) + { + if ( orientation() == Horizontal ) + setHorizontalStretchable( myStretch ); + else + setVerticalStretchable( myStretch ); + } +} + +QSize QtxDockWindow::sizeHint() const +{ + QSize sz = QDockWindow::sizeHint(); + + if ( place() == InDock && isStretchable() && area() ) + { + if ( orientation() == Horizontal ) + sz.setWidth( area()->width() ); + else + sz.setHeight( area()->height() ); + } + + return sz; +} + +QSize QtxDockWindow::minimumSizeHint() const +{ + QSize sz = QDockWindow::minimumSizeHint(); + + if ( orientation() == Horizontal ) + sz = QSize( 0, QDockWindow::minimumSizeHint().height() ); + else + sz = QSize( QDockWindow::minimumSizeHint().width(), 0 ); + + if ( place() == InDock && isStretchable() && area() ) + { + if ( orientation() == Horizontal ) + sz.setWidth( area()->width() ); + else + sz.setHeight( area()->height() ); + } + + return sz; +} + +QMainWindow* QtxDockWindow::mainWindow() const +{ + QMainWindow* mw = 0; + + QWidget* wid = parentWidget(); + while ( !mw && wid ) + { + if ( wid->inherits( "QMainWindow" ) ) + mw = (QMainWindow*)wid; + wid = wid->parentWidget(); + } + + return mw; +} + +void QtxDockWindow::show() +{ + if ( myWatcher ) + myWatcher->shown( this ); + + QDockWindow::show(); +} + +void QtxDockWindow::hide() +{ + if ( myWatcher ) + myWatcher->hided( this ); + + QDockWindow::hide(); +} diff --git a/src/Qtx/QtxDockWindow.h b/src/Qtx/QtxDockWindow.h new file mode 100644 index 000000000..ec9e88188 --- /dev/null +++ b/src/Qtx/QtxDockWindow.h @@ -0,0 +1,55 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxDockWindow.h +// Author: Sergey TELKOV + +#include "Qtx.h" + +#include + +class QTX_EXPORT QtxDockWindow : public QDockWindow +{ + Q_OBJECT + + class Watcher; + +public: + QtxDockWindow( Place = InDock, QWidget* = 0, const char* = 0, WFlags = 0 ); + QtxDockWindow( const bool, QWidget*, const char* = 0, WFlags = 0 ); + QtxDockWindow( QWidget*, const char* = 0, WFlags = 0 ); + virtual ~QtxDockWindow(); + + virtual void setWidget( QWidget* ); + + bool isStretchable() const; + virtual void setStretchable( const bool ); + + virtual QSize sizeHint() const; + virtual QSize minimumSizeHint() const; + + QMainWindow* mainWindow() const; + +public slots: + virtual void show(); + virtual void hide(); + +private: + Watcher* myWatcher; + bool myStretch; +}; diff --git a/src/Qtx/QtxGroupBox.cxx b/src/Qtx/QtxGroupBox.cxx new file mode 100644 index 000000000..51732dc75 --- /dev/null +++ b/src/Qtx/QtxGroupBox.cxx @@ -0,0 +1,322 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxGroupBox.cxx +// Author: Sergey TELKOV + +#include "QtxGroupBox.h" + +#include +#include +#include +#include +#include + +QtxGroupBox::QtxGroupBox( QWidget* parent, const char* name ) +: QGroupBox( parent, name ), +myContainer( 0 ) +{ +} + +QtxGroupBox::QtxGroupBox( const QString& title, QWidget* parent, const char* name ) +: QGroupBox( title, parent, name ), +myContainer( 0 ) +{ + initialize(); +} + +QtxGroupBox::QtxGroupBox( int strips, Orientation o, QWidget* parent, const char* name ) +: QGroupBox( strips, o, parent, name ), +myContainer( 0 ) +{ + initialize(); +} + +QtxGroupBox::QtxGroupBox( int strips, Orientation o, const QString& title, + QWidget* parent, const char* name ) +: QGroupBox( strips, o, title, parent, name ), +myContainer( 0 ) +{ + initialize(); +} + +QtxGroupBox::~QtxGroupBox() +{ + delete myContainer; +} + +void QtxGroupBox::initialize() +{ + myContainer = new QHBox( this, 0, WStyle_Customize | WStyle_NoBorderEx | WStyle_Tool ); + + updateTitle(); +} + +#if QT_VER < 3 + +int QtxGroupBox::insideMargin() const +{ + int m = 0; + if ( layout() ) + m = layout()->margin(); + return m; +} + +int QtxGroupBox::insideSpacing() const +{ + int s = 0; + if ( layout() ) + s = layout()->spacing(); + return s; +} + +void QtxGroupBox::setInsideMargin( int m ) +{ + if ( layout() ) + layout()->setMargin( m ); +} + +void QtxGroupBox::setInsideSpacing( int s ) +{ + if ( layout() ) + layout()->setSpacing( s ); +} + +#endif + +void QtxGroupBox::insertTitleWidget( QWidget* wid ) +{ + if ( !myContainer ) + return; + + wid->reparent( myContainer, QPoint( 0, 0 ), true ); + wid->installEventFilter( this ); + + updateTitle(); +} + +void QtxGroupBox::removeTitleWidget( QWidget* wid ) +{ + if ( !myContainer || wid->parentWidget() != myContainer ) + return; + + wid->reparent( 0, QPoint( 0, 0 ), false ); + wid->removeEventFilter( this ); + + updateTitle(); +} + +void QtxGroupBox::adjustInsideMargin() +{ + QApplication::sendPostedEvents( myContainer, QEvent::ChildInserted ); + + myContainer->resize( myContainer->minimumSizeHint() ); + + setInsideMargin( myContainer->height() ); +} + +void QtxGroupBox::setAlignment( int align ) +{ + QGroupBox::setAlignment( align ); + + updateTitle(); +} + +void QtxGroupBox::setTitle( const QString& title ) +{ + QGroupBox::setTitle( title ); + + updateTitle(); +} + +void QtxGroupBox::setColumnLayout( int strips, Orientation o ) +{ + if ( myContainer ) + myContainer->reparent( 0, QPoint( 0, 0 ), false ); + + QGroupBox::setColumnLayout( strips, o ); + + if ( myContainer ) + myContainer->reparent( this, QPoint( 0, 0 ), false ); + + updateTitle(); +} + +void QtxGroupBox::show() +{ + QGroupBox::show(); + + updateTitle(); +} + +void QtxGroupBox::update() +{ + QGroupBox::update(); + + updateTitle(); +} + +QSize QtxGroupBox::sizeHint() const +{ + QSize sz = QGroupBox::sizeHint(); + + int sw = titleSize().width(); + + if ( myContainer ) + { + if ( alignment() == AlignCenter ) + sw += 2 * ( myContainer->width() + 5 ); + else + sw += 1 * ( myContainer->width() + 5 ); + } + + sw += frameRect().left(); + + return QSize( QMAX( sz.width(), sw ), sz.height() ); +} + +QSize QtxGroupBox::minimumSizeHint() const +{ + QSize sz = QGroupBox::minimumSizeHint(); + + int sw = titleSize().width() + myContainer ? myContainer->width() + 5 : 0; + + if ( myContainer ) + { + if ( alignment() == AlignCenter ) + sw += 2 * ( myContainer->width() + 5 ); + else + sw += 1 * ( myContainer->width() + 5 ); + } + + sw += frameRect().left(); + + return QSize( QMAX( sz.width(), sw ), sz.height() ); +} + +bool QtxGroupBox::eventFilter( QObject* obj, QEvent* e ) +{ + QEvent::Type type = e->type(); + if ( myContainer && obj->parent() == myContainer && + ( type == QEvent::Show || type == QEvent::ShowToParent || + type == QEvent::Hide || type == QEvent::HideToParent ) ) + QApplication::postEvent( this, new QCustomEvent( QEvent::User ) ); + + return QGroupBox::eventFilter( obj, e ); +} + +void QtxGroupBox::resizeEvent( QResizeEvent* e ) +{ + QGroupBox::resizeEvent( e ); + + updateTitle(); +} + +void QtxGroupBox::childEvent( QChildEvent* e ) +{ + if ( e->type() == QEvent::ChildInserted && e->child() == myContainer ) + return; + + QGroupBox::childEvent( e ); +} + +void QtxGroupBox::customEvent( QCustomEvent* ) +{ + updateTitle(); +} + +void QtxGroupBox::frameChanged() +{ + updateTitle(); +} + +QSize QtxGroupBox::titleSize() const +{ + QSize sz( 0, 0 ); + + if ( layout() ) + { + QSpacerItem* si = 0; + for ( QLayoutIterator it = layout()->iterator(); it.current() && !si; ++it ) + si = it.current()->spacerItem(); + if ( si ) + sz = si->sizeHint(); + } + + int w = sz.width(); + int h = sz.height() + insideMargin(); + + return QSize( w, h ); +} + +void QtxGroupBox::updateTitle() +{ + if ( !myContainer ) + return; + + int align = alignment(); + if ( align == AlignAuto ) + align = QApplication::reverseLayout() ? AlignRight : AlignLeft; + + if ( title().isEmpty() ) + align = AlignRight; + + QSize ts = titleSize(); + + int m = 5; + + int w = frameRect().width() - ts.width(); + if ( align == AlignCenter ) + w = w / 2; + + w -= m; + + QApplication::sendPostedEvents( myContainer, QEvent::ChildInserted ); + myContainer->resize( myContainer->minimumSizeHint() ); + + bool vis = false; + const QObjectList* list = myContainer->children(); + if ( list ) + { + for ( QObjectListIt it( *list ); it.current() && !vis; ++it ) + vis = it.current()->isWidgetType() && + ((QWidget*)it.current())->isVisibleTo( myContainer ); + } + + if ( myContainer->height() > ts.height() || myContainer->width() > w || !vis ) + myContainer->hide(); + else + { + int x = 0; + if ( align == AlignRight ) + x = frameRect().left() + m; + else + x = frameRect().right() - myContainer->width() - m; + + int y = frameRect().top() - ( myContainer->height() - frameWidth() ) / 2; + + QPoint pos( x, QMAX( 0, y ) ); + pos = mapToGlobal( pos ); + if ( myContainer->parentWidget() ) + pos = myContainer->parentWidget()->mapFromGlobal( pos ); + myContainer->move( pos ); + myContainer->show(); + } + + updateGeometry(); +} diff --git a/src/Qtx/QtxGroupBox.h b/src/Qtx/QtxGroupBox.h new file mode 100644 index 000000000..99404c6cb --- /dev/null +++ b/src/Qtx/QtxGroupBox.h @@ -0,0 +1,80 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxGroupBox.h +// Author: Sergey TELKOV + +#ifndef QTXGROUPBOX_H +#define QTXGROUPBOX_H + +#include "Qtx.h" + +#include +#include + +class QTX_EXPORT QtxGroupBox : public QGroupBox +{ + Q_OBJECT + +public: + QtxGroupBox( QWidget* = 0, const char* = 0 ); + QtxGroupBox( const QString&, QWidget* = 0, const char* = 0 ); + QtxGroupBox( int, Orientation, QWidget* = 0, const char* = 0 ); + QtxGroupBox( int, Orientation, const QString&, QWidget* = 0, const char* = 0 ); + virtual ~QtxGroupBox(); + +#if QT_VER < 3 + int insideMargin() const; + int insideSpacing() const; + void setInsideMargin( int ); + void setInsideSpacing( int ); +#endif + + virtual void setAlignment( int ); + virtual void setTitle( const QString& ); + virtual void setColumnLayout( int, Orientation ); + + virtual void insertTitleWidget( QWidget* ); + virtual void removeTitleWidget( QWidget* ); + + virtual void show(); + virtual void update(); + + void adjustInsideMargin(); + + virtual QSize sizeHint() const; + virtual QSize minimumSizeHint() const; + + virtual bool eventFilter( QObject*, QEvent* ); + +protected: + virtual void frameChanged(); + virtual void childEvent( QChildEvent* ); + virtual void resizeEvent( QResizeEvent* ); + virtual void customEvent( QCustomEvent* ); + +private: + void initialize(); + void updateTitle(); + QSize titleSize() const; + +private: + QWidget* myContainer; +}; + +#endif diff --git a/src/Qtx/QtxIntSpinBox.cxx b/src/Qtx/QtxIntSpinBox.cxx new file mode 100755 index 000000000..35672e5ee --- /dev/null +++ b/src/Qtx/QtxIntSpinBox.cxx @@ -0,0 +1,135 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxIntSpinBox.cxx +// Author: Sergey TELKOV + +#include "QtxIntSpinBox.h" + +#include +#include + +QtxIntSpinBox::QtxIntSpinBox( QWidget* parent, const char* name ) +: QSpinBox( parent, name ), +myCleared( false ), +myBlocked( false ) +{ + connect( editor(), SIGNAL( textChanged( const QString& ) ), this, SLOT( onTextChanged( const QString& ) ) ); +} + +QtxIntSpinBox::QtxIntSpinBox( int min, int max, int step, QWidget* parent, const char* name ) +: QSpinBox( min, max, step, parent, name ), +myCleared( false ), +myBlocked( false ) +{ + connect( editor(), SIGNAL( textChanged( const QString& ) ), this, SLOT( onTextChanged( const QString& ) ) ); +} + +QtxIntSpinBox::~QtxIntSpinBox() +{ +} + +bool QtxIntSpinBox::isCleared() const +{ + return myCleared; +} + +void QtxIntSpinBox::setCleared( const bool on ) +{ + if ( myCleared == on ) + return; + + myCleared = on; + updateDisplay(); +} + +void QtxIntSpinBox::setValue( int value ) +{ + myCleared = false; + + QSpinBox::setValue( value ); +} + +bool QtxIntSpinBox::eventFilter( QObject* o, QEvent* e ) +{ + if ( !myCleared || o != editor() || !editor()->text().stripWhiteSpace().isEmpty() ) + return QSpinBox::eventFilter( o, e ); + + if ( e->type() == QEvent::FocusOut || e->type() == QEvent::Leave || e->type() == QEvent::Hide ) + return false; + + if ( e->type() == QEvent::KeyPress && + ( ((QKeyEvent*)e)->key() == Key_Tab || ((QKeyEvent*)e)->key() == Key_BackTab ) ) + { + QApplication::sendEvent( this, e ); + return true; + } + + return QSpinBox::eventFilter( o, e ); +} + +void QtxIntSpinBox::interpretText() +{ + myCleared = false; + + QSpinBox::interpretText(); +} + +void QtxIntSpinBox::updateDisplay() +{ + if ( myBlocked ) + return; + + bool block = myBlocked; + myBlocked = true; + + QSpinBox::updateDisplay(); + + if ( myCleared ) + editor()->clear(); + else if ( editor()->hasFocus() ) + { + if ( editor()->text() == specialValueText() ) + editor()->selectAll(); + else + editor()->setSelection( prefix().length(), editor()->text().length() - prefix().length() - suffix().length() ); + } + + myBlocked = block; +} + +void QtxIntSpinBox::leaveEvent( QEvent* e ) +{ + if ( !myCleared ) + QSpinBox::leaveEvent( e ); +} + +void QtxIntSpinBox::wheelEvent( QWheelEvent* e ) +{ + if ( !isEnabled() ) + return; + + QSpinBox::wheelEvent( e ); + updateDisplay(); +} + +void QtxIntSpinBox::onTextChanged( const QString& ) +{ + if ( !myBlocked ) + myCleared = false; +} diff --git a/src/Qtx/QtxIntSpinBox.h b/src/Qtx/QtxIntSpinBox.h new file mode 100755 index 000000000..5dffbe4ec --- /dev/null +++ b/src/Qtx/QtxIntSpinBox.h @@ -0,0 +1,60 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxIntSpinBox.h +// Author: Sergey TELKOV + +#ifndef QTXINTSPINBOX_H +#define QTXINTSPINBOX_H + +#include "Qtx.h" + +#include + +class QTX_EXPORT QtxIntSpinBox : public QSpinBox +{ + Q_OBJECT + +public: + QtxIntSpinBox( QWidget* = 0, const char* = 0 ); + QtxIntSpinBox( int, int, int = 1, QWidget* = 0, const char* = 0 ); + virtual ~QtxIntSpinBox(); + + bool isCleared() const; + virtual void setCleared( const bool ); + + virtual bool eventFilter( QObject*, QEvent* ); + +public slots: + virtual void setValue( int ); + +protected slots: + virtual void onTextChanged( const QString& ); + +protected: + virtual void interpretText(); + virtual void updateDisplay(); + virtual void leaveEvent( QEvent* ); + virtual void wheelEvent( QWheelEvent* ); + +private: + bool myCleared; + bool myBlocked; +}; + +#endif diff --git a/src/Qtx/QtxListAction.cxx b/src/Qtx/QtxListAction.cxx new file mode 100755 index 000000000..725120238 --- /dev/null +++ b/src/Qtx/QtxListAction.cxx @@ -0,0 +1,1098 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxListAction.cxx +// Author: Sergey TELKOV (Based on code by Eugene AKSENOV) + +#include "QtxListAction.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const char* list_arrow_icon[] = { +"10 6 2 1", +"# c #000000", +" c none", +" ", +" ####### ", +" ##### ", +" ### ", +" # ", +" " +}; + +/*! + Class: QtxListAction::ToolButton + Level: Internal +*/ + +class QtxListAction::ToolButton : public QToolButton +{ +public: + ToolButton( QtxListAction*, QWidget* = 0, const char* = 0 ); + virtual ~ToolButton(); + + virtual QSize sizeHint() const; + +private: + QtxListAction* myAction; +}; + +QtxListAction::ToolButton::ToolButton( QtxListAction* a, QWidget* parent, const char* name ) +: QToolButton( parent, name ), +myAction( a ) +{ + setIconSet( QPixmap( list_arrow_icon ) ); +} + +QtxListAction::ToolButton::~ToolButton() +{ + if ( myAction ) + myAction->controlDeleted( this ); +} + +QSize QtxListAction::ToolButton::sizeHint() const +{ + QSize sz = iconSet().pixmap().size(); + return QSize( sz.width() + 2, sz.height() + 2 ); +} + +/*! + Class: QtxListAction + Level: Public +*/ + +/*! + Name: QtxListAction [public] + Desc: Constructs an list action with given parent and name. If toggle is true the + action will be a toggle action, otherwise it will be a command action. +*/ + +QtxListAction::QtxListAction( QObject* parent, const char* name, bool toggle ) +: QtxAction( parent, name, toggle ), +myFrame( 0 ), +myMode( Item ), +myRaise( false ) +{ + initialize(); +} + +/*! + Name: QtxListAction [public] + Desc: This constructor creates an action with the following properties: the + description text, the icon or iconset icon, the menu text and keyboard + accelerator. It is a child of given parent and named specified name. + If toggle is true the action will be a toggle action, otherwise it will + be a command action. +*/ + +QtxListAction::QtxListAction( const QString& text, const QIconSet& icon, + const QString& menuText, int accel, + QObject* parent, const char* name, bool toggle ) +: QtxAction( text, icon, menuText, accel, parent, name, toggle ), +myFrame( 0 ), +myMode( Item ), +myRaise( false ) +{ + initialize(); +} + +/*! + Name: QtxListAction [public] + Desc: This constructor creates an action with the following properties: the + description text, the menu text and keyboard accelerator. It is a child + of given parent and named specified name. If toggle is true the action + will be a toggle action, otherwise it will be a command action. +*/ + +QtxListAction::QtxListAction( const QString& text, const QString& menuText, + int accel, QObject* parent, const char* name, bool toggle ) +: QtxAction( text, menuText, accel, parent, name, toggle ), +myFrame( 0 ), +myMode( Item ), +myRaise( false ) +{ + initialize(); +} + +/*! + Name: ~QtxListAction [virtual public] + Desc: Destructor. +*/ + +QtxListAction::~QtxListAction() +{ + if ( myFrame ) + myFrame->myAction = 0; +} + +/*! + Name: popupMode [public] + Desc: Returns popup mode. If popup mode "Item" (default) then action will + be added into popup menu as menu item. If popup mode "SubMenu" then + action will be added into popup menu as sub menu with list of items. +*/ + +int QtxListAction::popupMode() const +{ + return myMode; +} + +/*! + Name: setPopupMode [public] + Desc: Set the popup mode. Popup mode define way in this action will be + added into popup menu. This function should be used before addTo. +*/ + +void QtxListAction::setPopupMode( const int mode ) +{ + myMode = mode; +} + +QStringList QtxListAction::names() const +{ + QStringList lst; + if ( myFrame ) + lst = myFrame->names(); + return lst; +} + +/*! + Name: addNames [public] + Desc: Fills the list of actions. Removes the old contents from + the list if 'clear' is true. +*/ + +void QtxListAction::addNames( const QStringList& names, bool clear ) +{ + if ( !myFrame ) + return; + + if ( clear ) + myFrame->clear(); + + myFrame->addNames( names ); + + QStringList lst = myFrame->names(); + for ( PopupsMap::Iterator pit = myPopups.begin(); pit != myPopups.end(); ++pit ) + { + int i = 1; + QPopupMenu* pm = (QPopupMenu*)pit.key(); + for ( QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it ) + pit.data().popup->insertItem( *it, i++ ); + pm->setItemEnabled( pit.data().id, isEnabled() && pit.data().popup->count() ); + } + + for ( ButtonsMap::Iterator bit = myButtons.begin(); bit != myButtons.end(); ++bit ) + { + bit.data().drop->setEnabled( isEnabled() && !lst.isEmpty() ); + bit.data().main->setEnabled( isEnabled() && !lst.isEmpty() ); + } +} + +/*! + Name: addTo [virtual public] + Desc: Adds this control to 'popup' or 'toolbar'. +*/ + +bool QtxListAction::addTo( QWidget* w ) +{ + if ( myButtons.contains( w ) || myPopups.contains( w ) ) + return false; + + if ( !w->inherits( "QPopupMenu" ) || popupMode() != SubMenu ) + if ( !QtxAction::addTo( w ) ) + return false; + +#if QT_VER < 3 + if ( w->children() ) + addedTo( (QWidget*)w->children()->getLast(), w ); +#endif + + if ( w->inherits( "QToolBar" ) ) + { + Buttons& entry = myButtons[w]; + QHBox* dropWrap = new QHBox( w ); + entry.drop = new ToolButton( this, dropWrap, "qt_dockwidget_internal" ); + + entry.drop->setTextLabel( text() ); + entry.drop->setToggleButton( true ); + entry.drop->setAutoRaise( entry.main->autoRaise() ); + + entry.main->setEnabled( isEnabled() && !myFrame->names().isEmpty() ); + entry.drop->setEnabled( isEnabled() && !myFrame->names().isEmpty() ); + + entry.main->installEventFilter( this ); + entry.drop->installEventFilter( this ); + + QToolTip::add( entry.drop, toolTip(), myTipGroup, statusTip() ); + + connect( entry.drop, SIGNAL( toggled( bool ) ), this, SLOT( onExpand( bool ) ) ); + } + else if ( w->inherits( "QPopupMenu" ) && popupMode() == SubMenu ) + { + Popups entry; + QPopupMenu* pm = (QPopupMenu*)w; + + entry.popup = new QPopupMenu( pm ); + entry.id = pm->insertItem( text(), entry.popup ); + + int i = 1; + QStringList lst = myFrame->names(); + for ( QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it ) + { + int id = entry.popup->insertItem( *it ); + entry.popup->setItemParameter( id, i++ ); + } + pm->setItemEnabled( entry.id, isEnabled() && entry.popup->count() ); + myPopups.insert( w, entry ); + + connect( entry.popup, SIGNAL( activated( int ) ), this, SLOT( onActivated( int ) ) ); + } + +#if QT_VER >= 3 + connect( w, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) ); +#endif + + return true; +} + +/*! + Name: addTo [virtual public] + Desc: Adds this control to 'popup' or 'toolbar'. Allow to specify index + for adding into 'popup'. +*/ + +bool QtxListAction::addTo( QWidget* w, const int idx ) +{ + return QtxAction::addTo( w, idx ); +} + +/*! + Name: removeFrom [virtual public] + Desc: Removes this control from 'popup' or 'toolbar'. +*/ + +bool QtxListAction::removeFrom( QWidget* w ) +{ + if ( !QtxAction::removeFrom( w ) ) + return false; + + if ( w->inherits( "QToolBar" ) ) + { + if ( myFrame ) + myFrame->hide(); + + if ( myButtons.contains( w ) ) + { + Buttons& entry = myButtons[w]; + + if ( entry.drop->parent() && entry.drop->parent()->parent() == w ) + delete entry.drop->parent(); + else + delete entry.drop; + } + myButtons.remove( w ); + } + else if ( w->inherits( "QPopupMenu" ) ) + myPopups.remove( w ); + +#if QT_VER >= 3 + disconnect( w, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) ); +#endif + + return true; +} + +/*! + Name: setEnabled [virtual public slot] + Desc: Enables/disables this control. +*/ + +void QtxListAction::setEnabled( bool enable ) +{ + QtxAction::setEnabled( enable ); + + bool isOn = enable && !myFrame->names().isEmpty(); + + for ( ButtonsMap::Iterator bit = myButtons.begin(); bit != myButtons.end(); ++bit ) + { + bit.data().drop->setEnabled( isOn ); + bit.data().main->setEnabled( isOn ); + } + + for ( PopupsMap::Iterator pit = myPopups.begin(); pit != myPopups.end(); ++pit ) + { + QPopupMenu* cont = (QPopupMenu*)pit.key(); + cont->setItemEnabled( pit.data().id, isOn ); + } +} + +/*! + Name: setMaxLines [public] + Desc: Sets max number of lines that list frame shows + without vertical scroll bar. Default value is 5. +*/ + +void QtxListAction::setMaxLines( int nlines ) +{ + myFrame->setMaxLines( nlines ); +} + +/*! + Name: setMaxLineChars [public] + Desc: Sets max number of characters in a line which list frame shows + without truncation. Default value is 12 (the widest char size is used). +*/ + +void QtxListAction::setMaxLineChars( int nchars ) +{ + myFrame->setMaxLineChars( nchars ); +} + +/*! + Name: setComment [public] + Desc: Sets the format Qt string for comments displayed under the list + of actions for one action and for several actions. + Ex. "Undo %1 actions" format string will work as "Undo 3 actions" + when 3 actions are selected. The default format string is "%1". +*/ + +void QtxListAction::setComment( const QString& c, const QString& sc ) +{ + if ( !myFrame ) + return; + + myFrame->setSingleComment( sc.isEmpty() ? c : sc ); + myFrame->setMultipleComment( c ); +} + +/*! + Name: eventFilter [virtual public] + Desc: Reimplemented to paint the tool buttons in 2D/3D. +*/ + +bool QtxListAction::eventFilter( QObject* o, QEvent* e ) +{ + if ( !myRaise && ( e->type() == QEvent::Enter || e->type() == QEvent::Leave ) ) + { + QWidget* obj = 0; + QWidget* wid = widget( (QWidget*)o ); + if ( o == mainButton( wid ) ) + obj = dropButton( wid ); + else if ( o == dropButton( wid ) ) + obj = mainButton( wid ); + + if ( obj ) + { + myRaise = true; + QApplication::sendEvent( obj, e ); + obj->repaint(); + myRaise = false; + } + } + return QObject::eventFilter( o, e ); +} + +/*! + Name: addedTo [protected] + Desc: Reimplemented for internal reasons. +*/ + +void QtxListAction::addedTo( QWidget* actionWidget, QWidget* container ) +{ +#if QT_VER >= 3 + QtxAction::addedTo( actionWidget, container ); +#endif + + if ( !container->inherits( "QToolBar" ) ) + return; + + Buttons entry; + entry.main = (QToolButton*)actionWidget; + + myButtons.insert( container, entry ); +} + +/*! + Name: initialize [private] + Desc: Initialization of object QtxListAction. +*/ + +void QtxListAction::initialize() +{ + myTipGroup = new QToolTipGroup( this ); + + myFrame = new QtxListFrame( this, qApp->mainWidget() ); + myFrame->setMaxLines( 5 ); + myFrame->setMaxLineChars( 7 ); + + myFrame->hide(); + + connect( myFrame, SIGNAL( hided() ), this, SLOT( onHided() ) ); + connect( this, SIGNAL( activated() ), this, SLOT( onSingle() ) ); + connect( myFrame, SIGNAL( selected( int ) ), this, SLOT( onMultiple( int ) ) ); + + connect( myTipGroup, SIGNAL( removeTip() ), this, SLOT( clearStatusText() ) ); + connect( myTipGroup, SIGNAL( showTip( const QString& ) ), this, SLOT( showStatusText( const QString& ) ) ); +} + +/*! + Name: onSingle [private slot] + Desc: Called when a single action is selected. +*/ + +void QtxListAction::onSingle() +{ + emit activated( 1 ); +} + +/*! + Name: onMultiple [private slot] + Desc: Called when multiple actions are selected. +*/ + +void QtxListAction::onMultiple( int numActions ) +{ + if ( myFrame ) + myFrame->hide(); + + if ( numActions > 0 ) + emit activated( numActions ); +} + +/*! + Name: onExpand [private slot] + Desc: Activates the list of actions. +*/ + +void QtxListAction::onExpand( bool on ) +{ + const QObject* obj = sender(); + if ( on ) + { + QWidget* wid = widget( (QToolButton*)obj ); + QToolButton* main = mainButton( wid ); + myFrame->setOwner( main ); + if ( main ) + myFrame->show(); + } + else + myFrame->hide(); +} + +void QtxListAction::onHided() +{ + for ( ButtonsMap::Iterator bit = myButtons.begin(); bit != myButtons.end(); ++bit ) + { + bool block = bit.data().drop->signalsBlocked(); + bit.data().drop->blockSignals( true ); + bit.data().drop->setOn( false ); + bit.data().drop->blockSignals( block ); + } +} + +/*! + Name: onActivated [private slot] + Desc: Called when a sub menu item is activated. +*/ + +void QtxListAction::onActivated( int id ) +{ + QPopupMenu* pm = (QPopupMenu*)sender(); + int num = pm->itemParameter( id ); + if ( num > 0 ) + emit activated( num ); +} + +/*! + Name: onDestroyed [private slot] + Desc: Called when a container widget is destroyed. +*/ + +void QtxListAction::onDestroyed( QObject* obj ) +{ + if ( !obj->isWidgetType() ) + return; + + myPopups.remove( (QWidget*)obj ); + myButtons.remove( (QWidget*)obj ); +} + +/*! + Name: widget [private] + Desc: Returns container widget for specified control. +*/ + +QWidget* QtxListAction::widget( QWidget* obj ) const +{ + QWidget* wid = 0; + for ( PopupsMap::ConstIterator pit = myPopups.begin(); pit != myPopups.end() && !wid; ++pit ) + if ( pit.data().popup == obj ) + wid = pit.key(); + + for ( ButtonsMap::ConstIterator bit = myButtons.begin(); bit != myButtons.end() && !wid; ++bit ) + if ( bit.data().main == obj || bit.data().drop == obj ) + wid = bit.key(); + + return wid; +} + +/*! + Name: listPopup [private] + Desc: Returns sub popup menu widget for specified container. +*/ + +QPopupMenu* QtxListAction::listPopup( QWidget* wid ) const +{ + QPopupMenu* p = 0; + if ( myPopups.contains( wid ) ) + p = myPopups[wid].popup; + return p; +} + +/*! + Name: mainButton [private] + Desc: Returns main tool button for specified container. +*/ + +QToolButton* QtxListAction::mainButton( QWidget* wid ) const +{ + QToolButton* mb = 0; + if ( myButtons.contains( wid ) ) + mb = myButtons[wid].main; + return mb; +} + +/*! + Name: dropButton [private] + Desc: Returns drop tool button for specified container. +*/ + +QToolButton* QtxListAction::dropButton( QWidget* wid ) const +{ + QToolButton* db = 0; + if ( myButtons.contains( wid ) ) + db = myButtons[wid].drop; + return db; +} + +/*! + Name: controlDeleted [private] + Desc: Called when action child controls deleted. +*/ + +void QtxListAction::controlDeleted( QWidget* wid ) +{ + QWidget* w = 0; + for ( ButtonsMap::Iterator it = myButtons.begin(); it != myButtons.end() && !w; ++it ) + { + if ( it.data().main == wid || it.data().drop == wid ) + w = it.key(); + } + + if ( w ) + { + if ( myFrame ) + myFrame->hide(); + + myButtons.remove( w ); + } +} + +/********************************************************************** +** Class: QtxListFrame +** Descr: Frame for the list of actions +** Level: Internal +***********************************************************************/ + +class QtxListFrame::ScrollEvent : public QCustomEvent +{ +public: + enum { Scroll = User + 1 }; + + ScrollEvent( bool down ) : QCustomEvent( Scroll ), myDown( down ) {}; + virtual ~ScrollEvent() {}; + + bool isDown() const { return myDown; }; + +private: + bool myDown; +}; + +/*! + Class: QtxListAction + Level: Public +*/ + +/*! + Constructor +*/ +QtxListFrame::QtxListFrame( QtxListAction* a, QWidget* parent, WFlags f ) +: QFrame( parent, 0, WStyle_Customize | WStyle_NoBorderEx | WType_Popup | WStyle_Tool | WStyle_StaysOnTop ), +myList( 0 ), +myOwner( 0 ), +myAction( a ), +myComment( 0 ), +myMaxLines( 5 ), +myMaxLineChars( 10 ), +myScrollVal( 0 ), +myScrollBlock( false ) +{ + QVBoxLayout* theLayout = new QVBoxLayout( this, 3 ); + theLayout->setResizeMode( QLayout::FreeResize ); + + myList = new QListBox( this ); + myList->setSelectionMode( QListBox::Multi ); + myList->setHScrollBarMode( QScrollView::AlwaysOff ); + myList->setFocusPolicy( NoFocus ); + + QPalette p = myList->palette(); + p.setColor( QPalette::Inactive, QColorGroup::Highlight, + p.color( QPalette::Active, QColorGroup::Highlight ) ); + p.setColor( QPalette::Inactive, QColorGroup::HighlightedText, + p.color( QPalette::Active, QColorGroup::HighlightedText ) ); + myList->setPalette( p ); + + /* We'll have the vertical scroll bar only and + truncate the names which are too wide */ + connect( myList, SIGNAL( contentsMoving( int, int ) ), this, SLOT( onScroll( int, int ) ) ); + + myComment = new QLabel( this ); + myComment->setFrameStyle( Panel | Sunken ); + myComment->setAlignment( AlignCenter ); + myMultipleComment = "%1"; + + theLayout->addWidget( myList ); + theLayout->addWidget( myComment ); + + setFrameStyle( Panel | Raised ); +} + +QtxListFrame::~QtxListFrame() +{ + if ( myAction ) + myAction->myFrame = 0; +} + +/*! + Clears list of names [ public ] +*/ + +void QtxListFrame::clear() +{ + myNames.clear(); + setNames( myNames ); +} + +void QtxListFrame::addNames( const QStringList& names ) +{ + for ( QStringList::ConstIterator it = names.begin(); it != names.end(); ++it ) + myNames.append( *it ); + setNames( myNames ); +} + +/*! + Sets a names to the list. Truncates the name to fit to the frame width. + Use QtxListAction::setMaxLineChar( int ) to set the width in characters. [ public ] +*/ + +void QtxListFrame::setNames( const QStringList& names ) +{ + if ( !myList ) + return; + + myList->clear(); + + for ( QStringList::ConstIterator it = names.begin(); it != names.end(); ++it ) + { + QString s = *it; + QFontMetrics fm = myList->fontMetrics(); + int maxW = myMaxLineChars * fm.maxWidth(); + int w = fm.width( s ); + if ( w > maxW ) + { + QString extra( "..." ); + int len = s.length(); + int extraLen = fm.width( extra ) + 1; + while ( true ) + { + w = fm.width( s, --len ); + if ( w + extraLen < maxW ) + { + s = s.left( len ); + break; + } + } + s += extra; + } + myList->insertItem( s ); + } +} + +const QStringList QtxListFrame::names() const +{ + return myNames; +} + +/*! + Sets max number of lines shown without activation of vertical scroll bar. [ public ] +*/ + +void QtxListFrame::setMaxLines( int maxLines ) +{ + myMaxLines = maxLines; +} + +/*! + Sets max number of chars in line ( the rest will be truncated ). [ public ] +*/ + +void QtxListFrame::setMaxLineChars( int maxChars ) +{ + if ( myMaxLineChars == maxChars ) + return; + + myMaxLineChars = maxChars; + setNames( myNames ); +} + +/*! + Sets the format of single comment. [ public ] +*/ + +void QtxListFrame::setSingleComment( const QString& comment ) +{ + mySingleComment = comment; + setNames( myNames ); + updateComment(); +} + +/*! + Sets the format of multiple comment. [ public ] +*/ + +void QtxListFrame::setMultipleComment( const QString& comment ) +{ + myMultipleComment = comment; + setNames( myNames ); + updateComment(); +} + +/*! + Updates comment display. [ public ] +*/ + +void QtxListFrame::updateComment() +{ + QString com; + int selNum = selected(); + if ( selNum > 1 ) + com = myMultipleComment; + else if ( selNum > 0 && !mySingleComment.isEmpty() ) + com = mySingleComment; + + if ( !com.isEmpty() ) + com = com.arg( selNum ); + + myComment->setText( com ); +} + +void QtxListFrame::setOwner( QWidget* wo ) +{ + myOwner = wo; + if ( myOwner ) + { + QPoint lpos; + if ( myOwner->parentWidget() && myOwner->parentWidget()->inherits( "QToolBar" ) && + ((QToolBar*)myOwner->parentWidget())->orientation() == Qt::Vertical ) + lpos = QPoint( myOwner->x() + myOwner->width() + 2, myOwner->y() ); + else + lpos = QPoint( myOwner->x(), myOwner->y() + myOwner->height() + 2 ); + QPoint gpos = myOwner->parentWidget() ? myOwner->parentWidget()->mapToGlobal( lpos ) + : myOwner->mapToGlobal( lpos ); + if ( parentWidget() ) + move( parentWidget()->mapFromGlobal( gpos ) ); + else + move( gpos ); + } +} + +/*! + Validates the action. [ private slot ] +*/ + +void QtxListFrame::accept() +{ + emit selected( selected() ); +} + +/*! + Cancels the action. [ private slot ] +*/ + +void QtxListFrame::reject() +{ + emit selected( 0 ); +} + +/*! + Initializes / shows the frame. [ virtual public slot ] +*/ + +void QtxListFrame::show() +{ + int cnt = (int)myList->count(); + if ( cnt ) + { + myScrollVal = 0; + myList->setTopItem( 0 ); + myList->clearSelection(); + myList->setMinimumSize( 0, ( QMIN( cnt + 1, myMaxLines ) ) * myList->itemHeight() + 1 ); + setSelected( 1 ); + + int linstep = myList->itemHeight(); + myList->verticalScrollBar()->setLineStep( linstep ); + myList->verticalScrollBar()->setPageStep( myMaxLines * linstep ); + + QFontMetrics fm = myList->fontMetrics(); + layout()->invalidate(); + int maxHeight = layout()->minimumSize().height() + layout()->margin(); + int maxWidth = myMaxLineChars * fm.maxWidth(); + for ( uint i = 0; i <= myList->count(); i++ ) + maxWidth = QMAX( maxWidth, fm.width( myList->text( i ) ) ); + + resize( width(), maxHeight ); + + myList->updateGeometry(); + + QApplication::sendPostedEvents(); + + myList->resizeContents( myList->contentsWidth(), + myList->itemHeight() * cnt ); + if ( myList->contentsHeight() > myList->visibleHeight() ) + maxWidth += myList->verticalScrollBar()->width(); + + QString single = mySingleComment.arg( cnt ); + QString multi = myMultipleComment.arg( cnt ); + int comWidth = QMAX( myComment->fontMetrics().width( single ), myComment->fontMetrics().width( multi ) ); + if ( myComment->frameWidth() ) + comWidth += myComment->fontMetrics().width( "x" ); + + maxWidth = QMAX( maxWidth, comWidth ); + + resize( maxWidth, maxHeight ); + updateComment(); + + qApp->installEventFilter( this ); + + QFrame::show(); + } +} + +/*! + Cleanup. [ virtual public slot ] +*/ + +void QtxListFrame::hide() +{ + qApp->removeEventFilter( this ); + QFrame::hide(); + emit hided(); +} + +/*! + Processes KeyUp/KeyDown, PageUp/PageDown, CR and Esc keys. + Returns 'true' if event is eaten, 'false' otherwise. [ private ] +*/ + +bool QtxListFrame::handleKeyEvent( QObject* , QKeyEvent* e ) +{ + if ( e->type() == QEvent::KeyRelease ) + return true; + + int selNum = selected(); + switch( e->key() ) + { + case Key_Up: + setSelected( QMAX( 1, selNum - 1 ) ); + break; + case Key_Down: + setSelected( QMAX( 1, selNum + 1 ) ); + break; + case Key_PageUp: + setSelected( QMAX( 1, selNum - myMaxLines ) ); + break; + case Key_PageDown: + setSelected( selNum += myMaxLines ); + break; + case Key_Home: + setSelected( 1 ); + break; + case Key_End: + setSelected( myList->count() ); + break; + case Key_Return: + accept(); + break; + case Key_Escape: + reject(); + break; + } + return true; +} + +/*! + Selects items on move, validates on button release. If object 'o' is not our name list, + we close the frame. Returns 'true' if event is eaten, 'false' otherwise. [ private ] +*/ + +bool QtxListFrame::handleMouseEvent( QObject* o, QMouseEvent* e ) +{ + switch( e->type() ) + { + case QEvent::MouseButtonPress: + { + if ( o != myList->viewport() && !isPopup() ) + reject(); + return true; + } + case QEvent::MouseMove: + { + if ( o == myList->viewport() ) + { + QListBoxItem* lbi = myList->itemAt( e->pos() ); + if ( lbi ) + setSelected( myList->index( lbi ) + 1 ); + } + break; + } + case QEvent::MouseButtonRelease: + { + if ( o == myList->viewport() ) + accept(); + else + reject(); + break; + } + default: + break; + } + return true; +} + +bool QtxListFrame::event( QEvent* e ) +{ + if ( e->type() != (int)ScrollEvent::Scroll ) + return QFrame::event( e ); + + ScrollEvent* se = (ScrollEvent*)e; + if ( se->isDown() ) + setSelected( myList->topItem() + myList->numItemsVisible() ); + else + setSelected( myList->topItem() + 1 ); + + return true; +} + +/*! + Watches mouse events on the viewport of the list. [ virtual public ] +*/ + +bool QtxListFrame::eventFilter( QObject* o, QEvent* e ) +{ + bool isKeyEvent = ( e->type() == QEvent::KeyPress || + e->type() == QEvent::KeyRelease ); + bool isMouseEvent = ( e->type() == QEvent::MouseMove || + e->type() == QEvent::MouseButtonPress || + e->type() == QEvent::MouseButtonRelease || + e->type() == QEvent::MouseButtonDblClick ); + + if ( isKeyEvent ) + { + if ( handleKeyEvent( o, ( QKeyEvent* )e ) ) + return true; + } + else if ( isMouseEvent && o != myList->verticalScrollBar() ) + { + if ( handleMouseEvent( o, ( QMouseEvent*)e ) ) + return true; + } + + if ( o != this && ( e->type() == QEvent::Resize || e->type() == QEvent::Move ) ) + setOwner( myOwner ); + + return QFrame::eventFilter( o, e ); +} + +/*! + Selects operations while scrolling the list. [ private slot ] +*/ + +void QtxListFrame::onScroll( int x, int y ) +{ + int dx = y - myScrollVal; + if ( !myScrollBlock ) + QApplication::postEvent( this, new ScrollEvent( dx > 0 ) ); + myScrollVal = y; +} + +/*! + Selects the actions [ 0 - lastSel ]. [ public ] +*/ + +void QtxListFrame::setSelected( const int lastSel ) +{ + int last = QMIN( lastSel, (int)myList->count() ); + + for ( int i = 0; i < (int)myList->count(); i++ ) + myList->setSelected( i, i < last ); + + int item = last - 1; + + myScrollBlock = true; + + if ( item < myList->topItem() ) + myList->setTopItem( item ); + + if ( item >= myList->topItem() + myList->numItemsVisible() ) + myList->setTopItem( item - myList->numItemsVisible() + 1 ); + + myScrollBlock = false; + + myList->clearFocus(); + + updateComment(); +} + +int QtxListFrame::selected() const +{ + uint sel = 0; + while ( sel < myList->count() && myList->isSelected( sel ) ) + sel++; + return sel; +} diff --git a/src/Qtx/QtxListAction.h b/src/Qtx/QtxListAction.h new file mode 100755 index 000000000..30c85acc0 --- /dev/null +++ b/src/Qtx/QtxListAction.h @@ -0,0 +1,198 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxListAction.hxx +// Author: Sergey TELKOV (Based on code by Eugene AKSENOV) + +#ifndef QTXLISTACTION_H +#define QTXLISTACTION_H + +#include "QtxAction.h" + +#include +#include +#include + +class QLabel; +class QListBox; +class QPopupMenu; +class QToolButton; +class QToolTipGroup; + +class QtxListFrame; + +#ifdef WIN32 +#pragma warning( disable:4251 ) +#endif + +class QTX_EXPORT QtxListAction : public QtxAction +{ + Q_OBJECT + + Q_PROPERTY( QStringList names READ names WRITE addNames ) + + class ToolButton; + +public: + enum { Item, SubMenu } PopupMode; + +public: + QtxListAction( QObject* = 0, const char* = 0, bool = false ); + QtxListAction( const QString&, const QIconSet&, const QString&, int, QObject*, const char* = 0, bool = false ); + QtxListAction( const QString&, const QString&, int, QObject*, const char* = 0, bool = false ); + virtual ~QtxListAction(); + +public: + virtual bool addTo( QWidget* ); + virtual bool addTo( QWidget*, const int ); + + virtual bool removeFrom( QWidget* ); + virtual bool eventFilter( QObject*, QEvent* ); + + int popupMode() const; + void setPopupMode( const int ); + + QStringList names() const; + void addNames( const QStringList&, bool = true ); + void setComment( const QString&, const QString& = QString::null ); + + void setMaxLines( int ); + void setMaxLineChars( int ); + +signals: + void activated( int ); + +public slots: + virtual void setEnabled( bool ); + +private slots: + void onHided(); + void onSingle(); + void onExpand( bool ); + void onMultiple( int ); + void onActivated( int ); + void onDestroyed( QObject* ); + +protected: + virtual void addedTo( QWidget*, QWidget* ); + +private: + void initialize(); + QWidget* widget( QWidget* ) const; + QPopupMenu* listPopup( QWidget* ) const; + QToolButton* mainButton( QWidget* ) const; + QToolButton* dropButton( QWidget* ) const; + + void controlDeleted( QWidget* ); + +private: + typedef struct { int id; QPopupMenu* popup; } Popups; + typedef struct { QToolButton* main; QToolButton* drop; } Buttons; + typedef QMap PopupsMap; + typedef QMap ButtonsMap; + +private: + int myMode; + QtxListFrame* myFrame; + bool myRaise; + PopupsMap myPopups; + ButtonsMap myButtons; + QToolTipGroup* myTipGroup; + + friend class ToolButton; + friend class QtxListFrame; +}; + +/************************************* +** Class: QtxListFrame +** Level: Internal +*************************************/ + +class QtxListFrame : public QFrame +{ + Q_OBJECT + + class ScrollEvent; + +public: + QtxListFrame( QtxListAction*, QWidget* parent, WFlags f = 0 ); + virtual ~QtxListFrame(); + + void clear(); + const QStringList names() const; + void addNames( const QStringList& ); + + void setSingleComment( const QString& ); + void setMultipleComment( const QString& ); + + int selected() const; + void setSelected( const int ); + + void setMaxLines( int ); + void setMaxLineChars( int ); + + virtual bool event( QEvent* ); + virtual bool eventFilter( QObject*, QEvent* ); + + void setOwner( QWidget* ); + + void updateComment(); + +signals: + void hided(); + void selected( int ); + +public slots: + virtual void show(); + virtual void hide(); + +private slots: + void reject(); + void accept(); + + void onScroll( int, int ); + +private: + void setNames( const QStringList& ); + bool handleKeyEvent( QObject*, QKeyEvent* ); + bool handleMouseEvent( QObject*, QMouseEvent* ); + + friend class QtxListAction; + +private: + QListBox* myList; + QStringList myNames; + QWidget* myOwner; + QtxListAction* myAction; + QLabel* myComment; + + QString mySingleComment; + QString myMultipleComment; + + int myMaxLines; + int myMaxLineChars; + + int myScrollVal; + bool myScrollBlock; +}; + +#ifdef WIN32 +#pragma warning( default:4251 ) +#endif + +#endif diff --git a/src/Qtx/QtxListBox.cxx b/src/Qtx/QtxListBox.cxx new file mode 100755 index 000000000..6d2ce0cd9 --- /dev/null +++ b/src/Qtx/QtxListBox.cxx @@ -0,0 +1,352 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxListBox.cxx +// Author: Sergey TELKOV + +#include "QtxListBox.h" + +#include +#include + +QtxListBox::QtxListBox( QWidget* parent, const char* name, WFlags f ) +: QListBox( parent, name, f ), +myEditor( 0 ), +myEditIndex( -1 ), +myEditState( false ), +myEditDefault( true ), +myModifEnabled( true ) +{ + connect( this, SIGNAL( contentsMoving( int, int ) ), + this, SLOT( onContentsMoving( int, int ) ) ); +} + +QtxListBox::~QtxListBox() +{ +} + +bool QtxListBox::isEditEnabled() const +{ + return myEditState; +} + +void QtxListBox::setEditEnabled( bool on ) +{ + if ( isEditEnabled() == on ) + return; + + myEditState = on; + + if ( !isEditEnabled() ) + endEdition( defaultEditAction() ); +} + +bool QtxListBox::defaultEditAction() const +{ + return myEditDefault; +} + +void QtxListBox::setDefaultEditAction( bool def ) +{ + myEditDefault = def; +} + +bool QtxListBox::isModificationEnabled() const +{ + return myModifEnabled; +} + +void QtxListBox::setModificationEnabled( bool on ) +{ + myModifEnabled = on; +} + +QListBoxItem* QtxListBox::editedItem() const +{ + return item( editedIndex() ); +} + +int QtxListBox::editedIndex() const +{ + return myEditIndex; +} + +void QtxListBox::startEdition( const int idx ) +{ + if ( idx < 0 || editedIndex() == idx || !isEditEnabled() ) + return; + + QLineEdit* ed = editor(); + if ( !ed ) + return; + + endEdition( defaultEditAction() ); + + myEditIndex = idx; + + ensureItemVisible( myEditIndex ); + + ed->setText( text( myEditIndex ) ); + updateEditor(); + ed->show(); + + ed->setFocus(); +} + +void QtxListBox::startEdition( const QListBoxItem* item ) +{ + startEdition( index( item ) ); +} + +void QtxListBox::endEdition( const bool action ) +{ + int idx = editedIndex(); + QLineEdit* ed = editor(); + + if ( idx < 0 || !ed ) + return; + + myEditIndex = -1; + + ed->hide(); + + if ( action ) + { + int cur = currentItem(); + + if ( pixmap( idx ) ) + changeItem( *pixmap( idx ), ed->text(), idx ); + else + changeItem( ed->text(), idx ); + + setCurrentItem( cur ); + + emit itemEdited( idx ); + emit itemEdited( item( idx ) ); + } +} + +void QtxListBox::ensureItemVisible( const int idx ) +{ + if ( idx < 0 ) + return; + + if ( itemVisible( idx ) ) + return; + + setTopItem( idx ); +} + +void QtxListBox::ensureItemVisible( const QListBoxItem* item ) +{ + ensureItemVisible( index( item ) ); +} + +const QValidator* QtxListBox::validator() const +{ + const QValidator* v = 0; + if ( editor() ) + v = editor()->validator(); + return v; +} + +void QtxListBox::clearValidator() +{ + if ( editor() ) + editor()->clearValidator(); +} + +void QtxListBox::setValidator( const QValidator* v ) +{ + if ( editor() ) + editor()->setValidator( v ); +} + +void QtxListBox::moveItemToTop( const int idx ) +{ + moveItem( idx, -idx ); +} + +void QtxListBox::moveItemToBottom( const int idx ) +{ + moveItem( idx, count() - idx ); +} + +void QtxListBox::moveItem( const int idx, const int step ) +{ + QListBoxItem* i = item( idx ); + if ( !i || step == 0 ) + return; + + QListBoxItem* cur = item( currentItem() ); + + takeItem( i ); + insertItem( i, QMAX( 0, idx + step ) ); + + setCurrentItem( index( cur ) ); + + int pos = index( i ); + if ( myEditIndex == idx ) + myEditIndex = pos; + + updateEditor(); + + if ( idx != pos ) + emit itemMoved( idx, pos ); +} + +void QtxListBox::createItem( const int i ) +{ + if ( !isEditEnabled() ) + return; + + int idx = i < 0 ? currentItem() : i; + idx = idx < 0 ? count() : idx; + idx = QMIN( (int)count(), idx ); + + insertItem( "", idx ); + setCurrentItem( idx ); + startEdition( idx ); +} + +void QtxListBox::deleteItem( const int i ) +{ + if ( !isEditEnabled() ) + return; + + int idx = i < 0 ? currentItem() : i; + if ( idx < 0 ) + return; + + if ( editedIndex() == idx ) + endEdition( defaultEditAction() ); + + removeItem( idx ); + updateEditor(); +} + +void QtxListBox::setContentsPos( int x, int y ) +{ + QListBox::setContentsPos( x, y ); + + updateEditor(); +} + +bool QtxListBox::eventFilter( QObject* o, QEvent* e ) +{ + if ( editor() == o ) + { + if ( e->type() == QEvent::FocusOut ) + endEdition( defaultEditAction() ); + + if ( e->type() == QEvent::KeyPress ) + { + QKeyEvent* ke = (QKeyEvent*)e; + if ( ke->key() == Key_Escape ) + endEdition( false ); + else if ( ke->key() == Key_Enter || ke->key() == Key_Return ) + endEdition( true ); + } + } + + return QListBox::eventFilter( o, e ); +} + +void QtxListBox::keyPressEvent( QKeyEvent* e ) +{ + if ( e->key() == Key_Up && e->state() & ControlButton && isModificationEnabled() ) + moveItem( currentItem(), -1 ); + else if ( e->key() == Key_Down && e->state() & ControlButton && isModificationEnabled() ) + moveItem( currentItem(), 1 ); + else if ( e->key() == Key_Home && e->state() & ControlButton && isModificationEnabled() ) + moveItemToTop( currentItem() ); + else if ( e->key() == Key_End && e->state() & ControlButton && isModificationEnabled() ) + moveItemToBottom( currentItem() ); + else if ( e->key() == Key_Insert && e->state() & ControlButton ) + createItem( currentItem() ); + else if ( e->key() == Key_Delete && e->state() & ControlButton ) + deleteItem( currentItem() ); + else + QListBox::keyPressEvent( e ); +} + +void QtxListBox::viewportResizeEvent( QResizeEvent* e ) +{ + QListBox::viewportResizeEvent( e ); + + updateEditor(); +} + +void QtxListBox::mouseDoubleClickEvent( QMouseEvent* e ) +{ + if ( isEditEnabled() ) + startEdition( itemAt( e->pos() ) ); + else + QListBox::mouseDoubleClickEvent( e ); +} + +void QtxListBox::onContentsMoving( int, int ) +{ + updateEditor(); +} + +QLineEdit* QtxListBox::editor() const +{ + if ( !myEditor ) + { + QtxListBox* that = (QtxListBox*)this; + that->createEditor(); + } + return myEditor; +} + +void QtxListBox::createEditor() +{ + if ( myEditor ) + return; + + myEditor = new QLineEdit( viewport() ); + + myEditor->setLineWidth( 1 ); + myEditor->setMidLineWidth( 0 ); + myEditor->setFrameStyle( QFrame::Box | QFrame::Plain ); + myEditor->installEventFilter( this ); + + myEditor->hide(); + + addChild( myEditor ); +} + +void QtxListBox::updateEditor() +{ + if ( !editedItem() || !editor() ) + return; + + QRect r = itemRect( editedItem() ); + if ( !r.isValid() ) + return; + + int m = editor()->lineWidth(); + r.addCoords( m, 0, 0, 0 ); + + const QPixmap* pix = pixmap( editedIndex() ); + if ( pix ) + r.addCoords( pix->width() + 2, 0, 0, 0 ); + + editor()->setGeometry( r ); +} diff --git a/src/Qtx/QtxListBox.h b/src/Qtx/QtxListBox.h new file mode 100755 index 000000000..166831734 --- /dev/null +++ b/src/Qtx/QtxListBox.h @@ -0,0 +1,108 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxListBox.h +// Author: Sergey TELKOV + +#ifndef QTXLISTBOX_H +#define QTXLISTBOX_H + +#include "Qtx.h" + +#include + +#ifdef WIN32 +#pragma warning( disable:4251 ) +#endif + +class QLineEdit; +class QValidator; + +class QTX_EXPORT QtxListBox : public QListBox +{ + Q_OBJECT + +public: + QtxListBox( QWidget* = 0, const char* = 0, WFlags = 0 ); + virtual ~QtxListBox(); + + bool isEditEnabled() const; + bool defaultEditAction() const; + bool isModificationEnabled() const; + + QListBoxItem* editedItem() const; + int editedIndex() const; + + void startEdition( const int ); + void startEdition( const QListBoxItem* ); + void endEdition( const bool ); + + void ensureItemVisible( const int ); + void ensureItemVisible( const QListBoxItem* ); + + virtual bool eventFilter( QObject*, QEvent* ); + + const QValidator* validator() const; + + void moveItemToTop( const int ); + void moveItemToBottom( const int ); + void moveItem( const int, const int ); + + void createItem( const int = -1 ); + void deleteItem( const int = -1 ); + +signals: + void itemEdited( int ); + void itemEdited( QListBoxItem* ); + void itemMoved( int, int ); + +public slots: + virtual void setEditEnabled( bool ); + virtual void setDefaultEditAction( bool ); + virtual void setModificationEnabled( bool ); + + virtual void clearValidator(); + virtual void setValidator( const QValidator* ); + virtual void setContentsPos( int, int ); + +private slots: + void onContentsMoving( int, int ); + +protected: + virtual void keyPressEvent( QKeyEvent* ); + virtual void viewportResizeEvent( QResizeEvent* ); + virtual void mouseDoubleClickEvent( QMouseEvent* ); + +private: + QLineEdit* editor() const; + void createEditor(); + void updateEditor(); + +private: + QLineEdit* myEditor; + int myEditIndex; + bool myEditState; + bool myEditDefault; + bool myModifEnabled; +}; + +#ifdef WIN32 +#pragma warning( default:4251 ) +#endif + +#endif diff --git a/src/Qtx/QtxListOfOperations.cxx b/src/Qtx/QtxListOfOperations.cxx new file mode 100644 index 000000000..1be04a75d --- /dev/null +++ b/src/Qtx/QtxListOfOperations.cxx @@ -0,0 +1,272 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// + +#include "QtxListOfOperations.h" +#include + +//================================================================ +// Function : +// Purpose : +//================================================================ +QtxListOfOperations::QtxListOfOperations() +{ +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +QtxListOfOperations::~QtxListOfOperations() +{ +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +void QtxListOfOperations::bracketsList( QStringList& list, bool open ) const +{ + OperationSetsIterator anIt = mySets.begin(), + aLast = mySets.end(); + QStringList custom; + for( ; anIt!=aLast; anIt++ ) + { + custom.clear(); + (*anIt).myOperations->bracketsList( custom, open ); + QStringList::const_iterator aSIt = custom.begin(), + aSLast = custom.end(); + for( ; aSIt!=aSLast; aSIt++ ) + if( list.contains( *aSIt )==0 ) + list.append( *aSIt ); + } +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +void QtxListOfOperations::opersList( QStringList& list ) const +{ + OperationSetsIterator anIt = mySets.begin(), + aLast = mySets.end(); + QStringList custom; + for( ; anIt!=aLast; anIt++ ) + { + custom.clear(); + (*anIt).myOperations->opersList( custom ); + QStringList::const_iterator aSIt = custom.begin(), + aSLast = custom.end(); + for( ; aSIt!=aSLast; aSIt++ ) + if( list.contains( *aSIt )==0 ) + list.append( *aSIt ); + } +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +bool QtxListOfOperations::createValue( const QString& str, QtxValue& val ) const +{ + bool ok; + OperationSetsIterator anIt = mySets.begin(), + aLast = mySets.end(); + for( ; anIt!=aLast; anIt++ ) + { + ok = (*anIt).myOperations->createValue( str, val ); + if( ok ) + break; + } + return ok; +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +int QtxListOfOperations::prior( const QString& op, bool isBin ) const +{ + OperationSetsIterator anIt = mySets.begin(), + aLast = mySets.end(); + int prior = 0; + for( ; anIt!=aLast; anIt++ ) + { + prior = (*anIt).myOperations->prior( op, isBin ); + if( prior>0 ) + { + prior+=(*anIt).myAddPrior; + break; + } + } + return prior>0 ? prior : 0; +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +QtxParser::Error QtxListOfOperations::isValid( const QString& op, + const QVariant::Type t1, + const QVariant::Type t2 ) const +{ + OperationSetsIterator anIt = mySets.begin(), + aLast = mySets.end(); + QtxParser::Error err = QtxParser::OK; + for( ; anIt!=aLast; anIt++ ) + { + err = (*anIt).myOperations->isValid( op, t1, t2 ); + if( err==QtxParser::OK ) + break; + } + return err; +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +QtxParser::Error QtxListOfOperations::calculate( const QString& op, + QtxValue& v1, + QtxValue& v2 ) const +{ + const char* deb = op.latin1(); + + OperationSetsIterator anIt = mySets.begin(), + aLast = mySets.end(); + QtxValue nv1, nv2; + for( ; anIt!=aLast; anIt++ ) + { + nv1 = v1; + nv2 = v2; + if( (*anIt).myOperations->isValid( op, v1.type(), v2.type() ) == QtxParser::OK ) + { + QtxParser::Error err = (*anIt).myOperations->calculate( op, nv1, nv2 ); + if( err==QtxParser::OK || err==QtxParser::InvalidResult ) + { + QString oop = (*anIt).myName; + const char* ooo = oop.latin1(); + v1 = nv1; v2 = nv2; + return err; + } + } + } + return QtxParser::InvalidOperation; +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +void QtxListOfOperations::clear() +{ + mySets.clear(); +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +bool QtxListOfOperations::has( const QString& name ) const +{ + OperationSetsIterator anIt = mySets.begin(), + aLast = mySets.end(); + for( ; anIt!=aLast; anIt++ ) + if( (*anIt).myName == name ) + return true; + return false; +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +void QtxListOfOperations::append( const QString& name, QtxOperations* oper, + int prior ) +{ + insert( name, oper, prior ); +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +void QtxListOfOperations::prepend( const QString& name, QtxOperations* oper, + int prior ) +{ + insert( name, oper, prior, 0 ); +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +void QtxListOfOperations::insert( const QString& name, QtxOperations* oper, + int prior, int pos ) +{ + if( has( name ) || oper==NULL || prior<0 ) + return; + + OperationSet op; + op.myName = name; + op.myOperations = oper; + op.myAddPrior = prior; + if( pos<0 ) + mySets.append( op ); + else + mySets.insert( mySets.at( pos ), op ); +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +void QtxListOfOperations::remove( const QString& name ) +{ + OperationSets::iterator anIt = mySets.begin(), + aLast = mySets.end(); + for( ; anIt!=aLast; anIt++ ) + if( (*anIt).myName == name ) + { + mySets.erase( anIt ); + break; + } +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +int QtxListOfOperations::count() const +{ + return mySets.count(); +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +QtxOperations* QtxListOfOperations::operations( const QString& name ) const +{ + OperationSetsIterator anIt = mySets.begin(), + aLast = mySets.end(); + for( ; anIt!=aLast; anIt++ ) + if( (*anIt).myName == name ) + return (*anIt).myOperations; + return NULL; +} diff --git a/src/Qtx/QtxListOfOperations.h b/src/Qtx/QtxListOfOperations.h new file mode 100644 index 000000000..3e1a711f1 --- /dev/null +++ b/src/Qtx/QtxListOfOperations.h @@ -0,0 +1,77 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxListOfOperations.h +// Author: Alexander SOLOVYOV + +#ifndef __QTX_LIST_OF_OPERATIONS_HEADER__ +#define __QTX_LIST_OF_OPERATIONS_HEADER__ + +#include "Qtx.h" +#include "QtxOperations.h" + +#ifdef WIN32 +#pragma warning( disable:4251 ) +#endif + + +//================================================================ +// Class : +// Purpose : +//================================================================ +class QTX_EXPORT QtxListOfOperations : public QtxOperations +{ +public: + QtxListOfOperations(); + virtual ~QtxListOfOperations(); + + virtual void opersList( QStringList& ) const; + virtual void bracketsList( QStringList&, bool open ) const; + + virtual bool createValue( const QString&, QtxValue& ) const; + virtual int prior ( const QString&, bool isBin ) const; + virtual QtxParser::Error isValid( const QString&, + const QVariant::Type, + const QVariant::Type ) const; + virtual QtxParser::Error calculate( const QString&, QtxValue&, QtxValue& ) const; + + void clear (); + bool has ( const QString& ) const; + void append ( const QString&, QtxOperations*, int prior ); + void prepend( const QString&, QtxOperations*, int prior ); + void insert ( const QString&, QtxOperations*, int prior, int pos = -1 ); + void remove ( const QString& ); + int count () const; + QtxOperations* operations( const QString& ) const; + +private: + typedef struct + { + QString myName; + QtxOperations* myOperations; + int myAddPrior; + + } OperationSet; + + typedef QValueList< OperationSet > OperationSets; + typedef OperationSets::const_iterator OperationSetsIterator; + + OperationSets mySets; +}; + +#endif diff --git a/src/Qtx/QtxListView.cxx b/src/Qtx/QtxListView.cxx new file mode 100755 index 000000000..e0ccd4991 --- /dev/null +++ b/src/Qtx/QtxListView.cxx @@ -0,0 +1,330 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// + +#include "QtxListView.h" + +#include +#include +#include + +static const char* list_xpm[] = { +"16 16 6 1", +". c None", +"a c #E3E9EB", +"b c #798391", +"c c #EBEBEB", +"d c #ABB4BE", +"e c #030E1F", +"................", +"................", +"................", +"...aaaaaaaaaa...", +"..abbbbbbbbbbe..", +"..abecbecbecbe..", +"..abbbbbbbbbbe..", +"..abecbecbecbe..", +"..abecaaaaaaaa..", +"..abeccdbbbbbb..", +"..abecccdbbbbe..", +"..abbbbe.dbbe...", +"...eeeee..de....", +"................", +"................", +"................" }; + +QtxListView::QtxListView( const int state, QWidget* parent, const char* name, WFlags f ) +: QListView( parent, name, f ), +myButton( 0 ), +myHeaderState( state ) +{ + initialize(); +} + +QtxListView::QtxListView( QWidget* parent, const char* name, WFlags f ) +: QListView( parent, name, f ), +myButton( 0 ), +myHeaderState( HeaderAuto ) +{ + initialize(); +} + +void QtxListView::initialize() +{ + if ( myHeaderState == HeaderButton ) + { + QPixmap p( list_xpm ); + + QPushButton* but = new QPushButton( this ); + but->setDefault( false ); + but->setFlat( true ); + but->setIconSet( p ); + but->setBackgroundPixmap( p ); + if ( p.mask() ) + but->setMask( *p.mask() ); + myButton = but; + + connect( myButton, SIGNAL( clicked() ), this, SLOT( onButtonClicked() ) ); + } + else + { + header()->installEventFilter( this ); + } + + myPopup = new QPopupMenu( this ); + connect( myPopup, SIGNAL( activated( int ) ), this, SLOT( onShowHide( int ) ) ); + connect( header(), SIGNAL( sizeChange( int, int, int ) ), this, SLOT( onHeaderResized() ) ); +} + +QtxListView::~QtxListView() +{ +} + +int QtxListView::addColumn( const QString& label, int width ) +{ + int res = QListView::addColumn( label, width ); + for ( int i = myAppropriate.count(); i <= res; i++ ) + myAppropriate.append( 1 ); + onHeaderResized(); + return res; +} + +int QtxListView::addColumn( const QIconSet& iconset, const QString& label, int width ) +{ + int res = QListView::addColumn( iconset, label, width ); + for ( int i = myAppropriate.count(); i <= res; i++ ) + myAppropriate.append( 1 ); + onHeaderResized(); + return res; +} + +void QtxListView::removeColumn( int index ) +{ + QListView::removeColumn( index ); + if ( index >= 0 && index < (int)myAppropriate.count() ) + myAppropriate.remove( myAppropriate.at( index ) ); + onHeaderResized(); +} + +bool QtxListView::appropriate( const int index ) const +{ + return index >= 0 && index < (int)myAppropriate.count() && myAppropriate[index]; +} + +void QtxListView::setAppropriate( const int index, const bool on ) +{ + if ( index < 0 || index >= (int)myAppropriate.count() ) + return; + + myAppropriate[index] = on ? 1 : 0; +} + +void QtxListView::resize( int w, int h ) +{ + QListView::resize( w, h ); + onHeaderResized(); +} + +void QtxListView::show() +{ + QListView::show(); + onHeaderResized(); +} + +void QtxListView::resizeContents( int w, int h ) +{ +/* + if ( myButton && myButton->isVisibleTo( myButton->parentWidget() ) ) + { + if ( header()->orientation() == Qt::Horizontal ) + w += myButton->width(); + else + h += myButton->width(); + } +*/ + QListView::resizeContents( w, h ); + + onHeaderResized(); +} + +void QtxListView::show( int ind ) +{ + setShown( ind, true ); +} + +void QtxListView::hide( int ind ) +{ + setShown( ind, false ); +} + +bool QtxListView::isShown( int ind ) const +{ + if ( ind>=0 && indcount() ) + return columnWidth( ind ) > 0 || header()->isResizeEnabled( ind ); + else + return false; +} + +void QtxListView::setShown( int ind, bool sh ) +{ + if( ind<0 || ind>=header()->count() || isShown( ind )==sh ) + return; + + ColumnData& data = myColumns[ind]; + if ( sh ) + { + int w = data.width; + bool resizeable = data.resizeable; + myColumns.remove( ind ); + + setColumnWidth( ind, w ); + header()->setResizeEnabled( resizeable, ind ); + } + else + { + int w = columnWidth( ind ); + bool r = header()->isResizeEnabled( ind ); + setColumnWidth( ind, 0 ); + header()->setResizeEnabled( false, ind ); + data.width = w; + data.resizeable = r; + } + updateContents(); +} + +void QtxListView::setColumnWidth( int c, int w ) +{ + if ( myColumns.contains( c ) ) + myColumns[c].width = w; + + QListView::setColumnWidth( c, !myColumns.contains( c ) ? w : 0 ); +} + +QSize QtxListView::sizeHint() const +{ + QSize sz = QListView::sizeHint(); + + if ( myButton && myButton->isVisibleTo( myButton->parentWidget() ) ) + sz.setWidth( sz.width() + 2 + myButton->width() ); + + return sz; +} + +QSize QtxListView::minimumSizeHint() const +{ + QSize sz = QListView::minimumSizeHint(); + + if ( myButton && myButton->isVisibleTo( myButton->parentWidget() ) ) + sz.setWidth( sz.width() + 2 + myButton->width() ); + + return sz; +} + +void QtxListView::onHeaderResized() +{ + if ( myHeaderState == HeaderAuto ) + { + int c = 0; + for ( int i = 0; i < columns(); i++ ) + { + if ( !header()->label( i ).isEmpty() || + ( header()->iconSet( i ) && !header()->iconSet( i )->isNull() ) ) + c++; + } + + if ( c > 1 ) + header()->show(); + else + header()->hide(); + } + + if ( !myButton || !header()->isVisibleTo( this ) ) + return; + + int lw = lineWidth(); + int h = header()->size().height() - 1; + myButton->setFixedSize( h, h ); + + int x = header()->headerWidth() - header()->offset() + 2; + if ( x < header()->width() - h ) + x = header()->width() - h; + + if ( myHeaderState == HeaderButton ) + { + if ( header()->orientation() == Qt::Horizontal ) + myButton->move( lw+x, lw ); + else + myButton->move( lw, lw+x ); + } +} + +void QtxListView::showPopup( const int x, const int y ) +{ + myPopup->clear(); + for ( int i = 0; i < columns(); i++ ) + { + if ( appropriate( i ) ) + { + int id = myPopup->insertItem( header()->label( i ), i ); + myPopup->setItemChecked( id, isShown( i ) ); + } + } + + if( myPopup->count() ) + myPopup->exec( mapToGlobal( QPoint( x, y ) ) ); +} + +void QtxListView::onButtonClicked() +{ + if ( myHeaderState != HeaderButton ) + return; + + int x = myButton->x(), + y = myButton->y() + myButton->height(); + + showPopup( x, y ); +} + +void QtxListView::onShowHide( int id ) +{ + //if ( myHeaderState != HeaderButton ) + // return; + + setShown( id, !isShown( id ) ); +} + +void QtxListView::viewportResizeEvent( QResizeEvent* e ) +{ + QListView::viewportResizeEvent( e ); + onHeaderResized(); +} + +bool QtxListView::eventFilter( QObject* o, QEvent* e ) +{ + if( o==header() && e->type()==QEvent::MouseButtonPress ) + { + QMouseEvent* me = ( QMouseEvent* )e; + if( me->button()==Qt::RightButton ) + { + showPopup( me->x()+2, me->y()+2 ); + return true; + } + } + + return QListView::eventFilter( o, e ); +} diff --git a/src/Qtx/QtxListView.h b/src/Qtx/QtxListView.h new file mode 100755 index 000000000..bf38736c7 --- /dev/null +++ b/src/Qtx/QtxListView.h @@ -0,0 +1,101 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// + +#ifndef QTXLISTVIEW_H +#define QTXLISTVIEW_H + +#include "Qtx.h" + +#ifdef WIN32 +#pragma warning( disable:4251 ) +#endif + +#include +#include + +class QButton; +class QPopupMenu; + +class QTX_EXPORT QtxListView : public QListView +{ + Q_OBJECT + +public: + enum { HeaderAuto, HeaderButton, NoHeaderButton }; + +public: + QtxListView( QWidget* = 0, const char* = 0, WFlags = 0 ); + QtxListView( const int, QWidget* = 0, const char* = 0, WFlags = 0 ); + virtual ~QtxListView(); + + virtual int addColumn( const QString&, int = -1 ); + virtual int addColumn( const QIconSet&, const QString&, int width = -1 ); + + virtual void removeColumn( int ); + + virtual void resize( int, int ); + + void show( int ); + void hide( int ); + + bool isShown( int ) const; + void setShown( int, bool ); + + bool appropriate( const int ) const; + virtual void setAppropriate( const int, const bool ); + + virtual void setColumnWidth( int, int ); + + virtual QSize sizeHint() const; + virtual QSize minimumSizeHint() const; + +public slots: + virtual void show(); + virtual void resizeContents( int, int ); + +protected slots: + void onHeaderResized(); + void onButtonClicked(); + void onShowHide( int ); + +protected: + virtual void viewportResizeEvent( QResizeEvent* ); + virtual bool eventFilter( QObject*, QEvent* ); + virtual void showPopup( const int x, const int y ); + +private: + typedef struct { int width; bool resizeable; } ColumnData; + typedef QMap ColumnsMap; + +private: + void initialize(); + +private: + QPopupMenu* myPopup; + QButton* myButton; + ColumnsMap myColumns; + QIntList myAppropriate; + int myHeaderState; +}; + +#ifdef WIN32 +#pragma warning( default:4251 ) +#endif + +#endif diff --git a/src/Qtx/QtxLogoMgr.cxx b/src/Qtx/QtxLogoMgr.cxx new file mode 100644 index 000000000..68811c5f3 --- /dev/null +++ b/src/Qtx/QtxLogoMgr.cxx @@ -0,0 +1,187 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "QtxLogoMgr.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +QtxLogoMgr::QtxLogoMgr( QMenuBar* mb ) +: QObject( mb ), +myMenus( mb ), +myId( 0 ) +{ +} + +QtxLogoMgr::~QtxLogoMgr() +{ +} + +/*! + Returns the menubar. +*/ +QMenuBar* QtxLogoMgr::menuBar() const +{ + return myMenus; +} + +/*! + Returns the count of the existed logos. +*/ +int QtxLogoMgr::count() const +{ + return myLogos.count(); +} + +/*! + Insert new logo to the menu bar area +*/ +void QtxLogoMgr::insert( const QString& id, const QPixmap& pix, const int index ) +{ + if ( pix.isNull() ) + return; + + LogoInfo* inf = 0; + + int idx = find( id ); + if ( idx < 0 ) + { + idx = index < (int)myLogos.count() ? index : -1; + if ( idx < 0 ) + inf = &( *myLogos.append( LogoInfo() ) ); + else + inf = &( *myLogos.insert( myLogos.at( idx ), LogoInfo() ) ); + } + else + inf = &( *myLogos.at( idx ) ); + + + inf->id = id; + inf->pix = pix; + + generate(); +} + +/*! + Removes a logo +*/ +void QtxLogoMgr::remove( const QString& id ) +{ + int idx = find( id ); + if ( idx < 0 ) + return; + + myLogos.remove( myLogos.at( idx ) ); + + generate(); +} + +/*! + Removes all logos +*/ +void QtxLogoMgr::clear() +{ + myLogos.clear(); + generate(); +} + +void QtxLogoMgr::generate() +{ + if ( !menuBar() ) + return; + + if ( myId ) + menuBar()->removeItem( myId ); + + myId = 0; + + if ( myLogos.isEmpty() ) + return; + + class LogoBox : public QHBox + { + public: + LogoBox( QWidget* parent = 0, const char* name = 0, WFlags f = 0 ) : QHBox( parent, name, f ) {}; + + void addSpacing( int spacing ) + { + QApplication::sendPostedEvents( this, QEvent::ChildInserted ); + ((QHBoxLayout*)layout())->addSpacing( spacing ); + } + + protected: + void drawContents( QPainter* p ) + { + if ( parentWidget()->inherits( "QMenuBar" ) ) + style().drawControl( QStyle::CE_MenuBarEmptyArea, p, this, contentsRect(), colorGroup() ); + else + QHBox::drawContents( p ); + } + }; + + LogoBox* cnt = new LogoBox( menuBar() ); + cnt->setSpacing( 3 ); + + for ( LogoList::const_iterator it = myLogos.begin(); it != myLogos.end(); ++it ) + { + QPixmap pix = (*it).pix; + if ( !pix.mask() ) + { + QImage img = pix.convertToImage(); + QBitmap bm; + if ( img.hasAlphaBuffer() ) + bm = img.createAlphaMask(); + else + bm = img.createHeuristicMask(); + pix.setMask( bm ); + } + + QLabel* logoLab = new QLabel( cnt ); + logoLab->setPixmap( (*it).pix ); + logoLab->setScaledContents( false ); + logoLab->setAlignment( QLabel::AlignCenter ); + + if ( pix.mask() ) + logoLab->setMask( *pix.mask() ); + } + + QApplication::sendPostedEvents( cnt, QEvent::ChildInserted ); + cnt->addSpacing( 2 ); + + myId = menuBar()->insertItem( cnt ); + + QApplication::sendPostedEvents( menuBar()->parentWidget(), QEvent::LayoutHint ); + QApplication::postEvent( menuBar()->parentWidget(), new QEvent( QEvent::LayoutHint ) ); +} + +int QtxLogoMgr::find( const QString& id ) const +{ + int idx = -1; + for ( uint i = 0; i < myLogos.count() && idx < 0; i++ ) + { + if ( (*myLogos.at( i ) ).id == id ) + idx = i; + } + return idx; +} diff --git a/src/Qtx/QtxLogoMgr.h b/src/Qtx/QtxLogoMgr.h new file mode 100644 index 000000000..6eee42847 --- /dev/null +++ b/src/Qtx/QtxLogoMgr.h @@ -0,0 +1,67 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef QTX_LOGOMGR_H +#define QTX_LOGOMGR_H + +#include "Qtx.h" + +class QMenuBar; + +#include +#include + +#ifdef WIN32 +#pragma warning( disable : 4251 ) +#endif + +class QTX_EXPORT QtxLogoMgr : public QObject +{ + Q_OBJECT + +public: + QtxLogoMgr( QMenuBar* ); + virtual ~QtxLogoMgr(); + + int count() const; + + void insert( const QString&, const QPixmap&, const int = -1 ); + void remove( const QString& ); + void clear(); + + QMenuBar* menuBar() const; + +private: + void generate(); + int find( const QString& ) const; + +private: + typedef struct { QString id; QPixmap pix; } LogoInfo; + typedef QValueList LogoList; + +private: + int myId; + QMenuBar* myMenus; + LogoList myLogos; +}; + +#ifdef WIN32 +#pragma warning( default : 4251 ) +#endif + +#endif diff --git a/src/Qtx/QtxMRUAction.cxx b/src/Qtx/QtxMRUAction.cxx new file mode 100755 index 000000000..ee7c4f3ac --- /dev/null +++ b/src/Qtx/QtxMRUAction.cxx @@ -0,0 +1,662 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxMRUAction.cxx +// Author: Sergey TELKOV + +#include "QtxMRUAction.h" + +#include "QtxResourceMgr.h" + +#include + +/*! + Name: QtxMRUAction [public] + Desc: Constructs an MRU action with given parent and name. +*/ + +QtxMRUAction::QtxMRUAction( QObject* parent, const char* name ) +: QtxAction( "Most Recently Used", "Most Recently Used", 0, parent, name ), +myVisCount( 5 ), +myPopupMode( SubMenu ), +myInsertMode( MoveFirst ) +{ +} + +/*! + Name: QtxMRUAction [public] + Desc: This constructor creates an action with the following properties: the + description text, the menu text and. It is a child of given parent and + named specified name. +*/ + +QtxMRUAction::QtxMRUAction( const QString& text, const QString& menuText, QObject* parent, const char* name ) +: QtxAction( text, menuText, 0, parent, name ), +myVisCount( 5 ), +myPopupMode( SubMenu ), +myInsertMode( MoveFirst ) +{ +} + +/*! + Name: QtxMRUAction [public] + Desc: This constructor creates an action with the following properties: the + description text, the menu text, the icon or iconset icon and keyboard + accelerator. It is a child of given parent and named specified name. +*/ + +QtxMRUAction::QtxMRUAction( const QString& text, const QIconSet& icon, const QString& menuText, QObject* parent, const char* name ) +: QtxAction( text, icon, menuText, 0, parent, name ), +myVisCount( 5 ), +myPopupMode( SubMenu ), +myInsertMode( MoveFirst ) +{ +} + +/*! + Name: ~QtxMRUAction [public] + Desc: This destructor removes all added popup items. +*/ + +QtxMRUAction::~QtxMRUAction() +{ + for ( ItemsMap::ConstIterator iIt = myItems.begin(); iIt != myItems.end(); ++iIt ) + removeFrom( iIt.key() ); + + for ( MenusMap::ConstIterator mIt = myMenus.begin(); mIt != myMenus.end(); ++mIt ) + removeFrom( mIt.key() ); +} + +/*! + Name: insertMode [public] + Desc: Returns the insert mode. +*/ + +int QtxMRUAction::insertMode() const +{ + return myInsertMode; +} + +/*! + Name: setInsertMode [public] + Desc: Returns the insert mode. Can be following values: + MoveFirst - place the specified link to the first position in any case + MoveLast - place the specified link to the last position in any case + AddFirst - if inserted link doesn't exist then add to the first position + AddLast - if inserted link doesn't exist then add to the lase position +*/ + +void QtxMRUAction::setInsertMode( const int mode ) +{ + myInsertMode = mode; +} + +/*! + Name: popupMode [public] + Desc: Returns the popup mode. +*/ + +int QtxMRUAction::popupMode() const +{ + return myPopupMode; +} + +/*! + Name: setPopupMode [public] + Desc: Set the popup mode. If this mode is 'Items' then method "addTo" creates the + items in the specified popup menu. If mode is 'SubMenu' then items will be + create in sub popup menu which will be placed in specified popup. +*/ + +void QtxMRUAction::setPopupMode( const int mode ) +{ + myPopupMode = mode; +} + +/*! + Name: count [public] + Desc: Returns the number of links. +*/ + +int QtxMRUAction::count() const +{ + return myLinks.count(); +} + +/*! + Name: isEmpty [public] + Desc: Returns 'true' if there is no links. +*/ + +bool QtxMRUAction::isEmpty() const +{ + return myLinks.isEmpty(); +} + +/*! + Name: visibleCount [public] + Desc: Returns the number of first links which will be added to popup menu. + If 'visibleCount' less than 1 then all links will be used. +*/ + +int QtxMRUAction::visibleCount() const +{ + return myVisCount; +} + +/*! + Name: setVisibleCount [public] + Desc: Sets the number of links which will be used in popup menu. +*/ + +void QtxMRUAction::setVisibleCount( int num ) +{ + if ( myVisCount == num ) + return; + + myVisCount = num; + + updateState(); +} + +/*! + Name: insert [public] + Desc: Insert the link according to the insert mode. +*/ + +void QtxMRUAction::insert( const QString& link ) +{ + if ( myLinks.contains( link ) && ( insertMode() == AddFirst || insertMode() == AddLast ) ) + return; + + myLinks.remove( link ); + + switch ( insertMode() ) + { + case AddFirst: + case MoveFirst: + myLinks.prepend( link ); + break; + case AddLast: + case MoveLast: + myLinks.append( link ); + break; + } + + updateState(); +} + +/*! + Name: remove [public] + Desc: Removes link with specified index. +*/ + +void QtxMRUAction::remove( const int idx ) +{ + if ( idx < 0 || idx >= (int)myLinks.count() ) + return; + + myLinks.remove( myLinks.at( idx ) ); + + updateState(); +} + +/*! + Name: remove [public] + Desc: Removes specified link. +*/ + +void QtxMRUAction::remove( const QString& link ) +{ + if ( myLinks.remove( link ) ) + updateState(); +} + +/*! + Name: item [public] + Desc: Returns the link with specified index. +*/ + +QString QtxMRUAction::item( const int idx ) const +{ + QString res; + if ( idx >= 0 && idx < (int)myLinks.count() ) + res = myLinks[idx]; + return res; +} + +/*! + Name: find [public] + Desc: Find specified link. If link exists then returns index otherwise -1 returned. +*/ + +int QtxMRUAction::find( const QString& link ) const +{ + return myLinks.findIndex( link ); +} + +/*! + Name: contains [public] + Desc: Returns 'true' if given link exist. +*/ + +bool QtxMRUAction::contains( const QString& link ) const +{ + return myLinks.contains( link ); +} + +/*! + Name: addTo [public] + Desc: Add the MRU links to the end of specified popup according to the popup mode. +*/ + +bool QtxMRUAction::addTo( QWidget* wid ) +{ + if ( !wid || !wid->inherits( "QPopupMenu" ) ) + return false; + + QPopupMenu* pm = (QPopupMenu*)wid; + checkPopup( pm ); + + int mode = popupMode(); + + if ( ( mode == Items && myItems.contains( pm ) ) || + ( mode == SubMenu && myMenus.contains( pm ) ) ) + return false; + + bool exist = myItems.contains( pm ) || myMenus.contains( pm ); + + if ( mode == SubMenu && !QtxAction::addTo( wid ) ) + return false; + + if ( mode == Items ) + { + myItems.insert( pm, Item() ); + myItems[pm].pId = myItems[pm].nId -1; + connect( pm, SIGNAL( activated( int ) ), this, SLOT( onActivated( int ) ) ); + } + else if ( mode == SubMenu ) + { + myMenus.insert( pm, new QPopupMenu( pm ) ); + setPopup( pm, pm->idAt( pm->count() - 1 ), myMenus[pm] ); + connect( myMenus[pm], SIGNAL( activated( int ) ), this, SLOT( onActivated( int ) ) ); + } + + if ( !exist ) + { + connect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) ); + connect( pm, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) ); + } + + return insertLinks( pm, mode ); +} + +/*! + Name: addTo [public] + Desc: Add the MRU links to the specified popup at given index according to the popup mode. +*/ + +bool QtxMRUAction::addTo( QWidget* wid, const int idx ) +{ + if ( !QtxAction::addTo( wid, idx ) ) + return false; + + QPopupMenu* pm = (QPopupMenu*)wid; + + removeLinks( pm, popupMode() ); + insertLinks( pm, popupMode(), idx ); + + return true; +} + +/*! + Name: removeFrom [public] + Desc: Removes all MRU links from specified popup. +*/ + +bool QtxMRUAction::removeFrom( QWidget* wid ) +{ + QtxAction::removeFrom( wid ); + + QPopupMenu* pm = (QPopupMenu*)wid; + if ( !wid || !wid->inherits( "QPopupMenu" ) ) + return false; + + if ( myItems.contains( pm ) ) + { + removeLinks( pm, Items ); + myItems.remove( pm ); + disconnect( pm, SIGNAL( activated( int ) ), this, SLOT( onActivated( int ) ) ); + } + if ( myMenus.contains( pm ) ) + { + removeLinks( pm, SubMenu ); + delete myMenus[pm]; + myMenus.remove( pm ); + } + + disconnect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) ); + disconnect( pm, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) ); + + return true; +} + +/*! + Name: loadLinks [public] + Desc: Load the MRU links from specified resource manager section. + If parameter 'clear' is 'true' then link list will be cleared first. +*/ + +void QtxMRUAction::loadLinks( QtxResourceMgr* resMgr, const QString& section, const bool clear ) +{ + if ( !resMgr || section.isEmpty() ) + return; + + if ( clear ) + myLinks.clear(); + + QString itemPrefix( "item_" ); + + QMap map; + for ( QStringList::const_iterator itr = myLinks.begin(); itr != myLinks.end(); ++ itr ) + map.insert( *itr, 0 ); + + QStringList items = resMgr->parameters( section ); + for ( QStringList::const_iterator it = items.begin(); it != items.end(); ++it ) + { + if ( !(*it).startsWith( itemPrefix ) ) + continue; + + QString link = resMgr->stringValue( section, *it, QString::null ); + if ( link.isEmpty() || map.contains( link ) ) + continue; + + myLinks.append( link ); + map.insert( link, 0 ); + } + + updateState(); +} + +/*! + Name: saveLinks [public] + Desc: Save the MRU links into specified resource manager section. + If parameter 'clear' is 'true' then section will be cleared first. +*/ + +void QtxMRUAction::saveLinks( QtxResourceMgr* resMgr, const QString& section, const bool clear ) const +{ + if ( !resMgr || section.isEmpty() ) + return; + + if ( clear ) + resMgr->remove( section ); + + QStringList lst; + QMap map; + for ( QStringList::const_iterator itr = myLinks.begin(); itr != myLinks.end(); ++itr ) + map.insert( *lst.append( *itr ), 0 ); + + QString itemPrefix( "item_" ); + QStringList items = resMgr->parameters( section ); + for ( QStringList::const_iterator it = items.begin(); it != items.end(); ++it ) + { + if ( !(*it).startsWith( itemPrefix ) ) + continue; + + QString link = resMgr->stringValue( section, *it, QString::null ); + if ( !link.isEmpty() && !map.contains( link ) ) + map.insert( *lst.append( link ), 0 ); + + resMgr->remove( section, *it ); + } + + int counter = 0; + for ( QStringList::const_iterator iter = lst.begin(); iter != lst.end(); ++iter, counter++ ) + resMgr->setValue( section, itemPrefix + QString().sprintf( "%03d", counter ), *iter ); +} + +/*! + Name: setEnabled [public slot] + Desc: Enable or disable all popup items with MRU links. +*/ + +void QtxMRUAction::setEnabled( bool on ) +{ + QtxAction::setEnabled( on ); + + for ( ItemsMap::ConstIterator iter = myItems.begin(); iter != myItems.end(); ++iter ) + for ( QIntList::const_iterator it = iter.data().idList.begin(); it != iter.data().idList.end(); ++it ) + iter.key()->setItemEnabled( *it, on ); +} + +/*! + Name: onAboutToShow [private slots] + Desc: Enable or disable sub menu item according to number of MRU links + in sub popup when parent popup is shown. +*/ + +void QtxMRUAction::onAboutToShow() +{ + const QObject* obj = sender(); + if ( obj && obj->inherits( "QPopupMenu" ) ) + { + QPopupMenu* pm = (QPopupMenu*)obj; + if ( myMenus.contains( pm ) ) + pm->setItemEnabled( findId( pm, myMenus[pm]), isEnabled() && myMenus[pm] && myMenus[pm]->count() ); + } +} + +/*! + Name: onActivated [private slot] + Desc: Process popup item activation and emit signal activated with selected MRU link. +*/ + +void QtxMRUAction::onActivated( int id ) +{ + const QObject* obj = sender(); + if ( !obj->inherits( "QPopupMenu" ) ) + return; + + QPopupMenu* pm = (QPopupMenu*)obj; + + QString link; + if ( ( myItems.contains( pm ) && myItems[pm].idList.contains( id ) ) || + ( myMenus.contains( (QPopupMenu*)pm->parent() ) && myMenus[(QPopupMenu*)pm->parent()] == pm ) ) + link = pm->text( id ); + + if ( !link.isEmpty() ) + emit activated( link ); +} + +/*! + Name: onDestroyed [private slot] + Desc: Removes deleted popup menu from internal data structures. +*/ + +void QtxMRUAction::onDestroyed( QObject* obj ) +{ + if ( !obj ) + return; + + myItems.remove( (QPopupMenu*)obj ); + myMenus.remove( (QPopupMenu*)obj ); +} + +/*! + Name: updateState [private] + Desc: Updates the state of all popup menus which contains MRU link items. +*/ + +void QtxMRUAction::updateState() +{ + for ( ItemsMap::ConstIterator iIt = myItems.begin(); iIt != myItems.end(); ++iIt ) + updatePopup( iIt.key(), Items ); + + for ( MenusMap::ConstIterator mIt = myMenus.begin(); mIt != myMenus.end(); ++mIt ) + updatePopup( mIt.key(), SubMenu ); +} + +/*! + Name: checkPopup [private] + Desc: Check consistency the popup content and internal datas. + Synchronize internal data structures with popup content. +*/ + +void QtxMRUAction::checkPopup( QPopupMenu* pm ) +{ + if ( myItems.contains( pm ) ) + { + bool found = true; + for ( QIntList::const_iterator it = myItems[pm].idList.begin(); it != myItems[pm].idList.end() && found; ++it ) + found = pm->indexOf( *it ) != -1; + if ( !found ) + { + removeLinks( pm, Items ); + myItems.remove( pm ); + disconnect( pm, SIGNAL( activated( int ) ), this, SLOT( onActivated( int ) ) ); + } + } + if ( myMenus.contains( pm ) ) + { + int id = findId( pm, myMenus[pm] ); + if ( id == -1 ) + { + delete myMenus[pm]; + myMenus.remove( pm ); + } + } + + if ( !myItems.contains( pm ) && !myMenus.contains( pm ) ) + disconnect( pm, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) ); +} + +/*! + Name: updatePopup [private] + Desc: Updates the MRU link items state in the specified popup menu. +*/ + +void QtxMRUAction::updatePopup( QPopupMenu* pm, const int mode ) +{ + if ( !pm ) + return; + + int idx = -1; + if ( mode == Items && myItems.contains( pm ) ) + { + if ( !myItems[pm].idList.isEmpty() ) + idx = pm->indexOf( myItems[pm].idList.first() ); + else + { + int pIdx = pm->indexOf( myItems[pm].pId ); + int nIdx = pm->indexOf( myItems[pm].nId ); + if ( pIdx != -1 ) + idx = pIdx + 1; + else if ( nIdx != -1 ) + idx = nIdx - 1; + } + } + + removeLinks( pm, mode ); + insertLinks( pm, mode, idx ); +} + +/*! + Name: removeLinks [private] + Desc: Removes MRU link items from specified popup. +*/ + +bool QtxMRUAction::removeLinks( QPopupMenu* pm, const int mode ) +{ + if ( !pm ) + return false; + + if ( mode == SubMenu && myMenus.contains( pm ) ) + myMenus[pm]->clear(); + else if ( mode == Items && myItems.contains( pm ) ) + { + for ( QIntList::const_iterator it = myItems[pm].idList.begin(); it != myItems[pm].idList.end(); ++it ) + pm->removeItem( *it ); + myItems[pm].idList.clear(); + } + + return true; +} + +/*! + Name: insertLinks [private] + Desc: Inserts MRU link items to the specified popup. +*/ + +bool QtxMRUAction::insertLinks( QPopupMenu* pm, const int mode, const int idx ) +{ + if ( !pm ) + return false; + + int count = visibleCount() < 0 ? myLinks.count() : visibleCount(); + bool isOn = isEnabled(); + if ( mode == SubMenu && myMenus.contains( pm ) ) + { + for ( QStringList::const_iterator it = myLinks.begin(); it != myLinks.end() && count > 0; ++it, count-- ) + { + int id = myMenus[pm]->insertItem( *it, -1 ); + myMenus[pm]->setItemEnabled( id, isOn ); + } + } + else if ( mode == Items ) + { + QIntList ids; + int index = idx; + for ( QStringList::const_iterator it = myLinks.begin(); it != myLinks.end() && count > 0; ++it, count-- ) + { + ids.append( pm->insertItem( *it, -1, index ) ); + pm->setItemEnabled( ids.last(), isOn ); + if ( index >= 0 ) + index++; + } + myItems[pm].idList = ids; + if ( !myItems[pm].idList.isEmpty() ) + { + myItems[pm].pId = pm->idAt( pm->indexOf( myItems[pm].idList.first() ) - 1 ); + myItems[pm].nId = pm->idAt( pm->indexOf( myItems[pm].idList.first() ) + 1 ); + } + } + return true; +} + +/*! + Name: findId [private] + Desc: Returns identificator of popup item which contains sub popup 'pm' in the popup 'cont'. +*/ + +int QtxMRUAction::findId( QPopupMenu* cont, QPopupMenu* pm ) const +{ + if ( !cont || !pm ) + return -1; + + int id = -1; + + for ( int i = 0; i < (int)cont->count() && id == -1; i++ ) + { + QMenuData* md = 0; + QMenuItem* item = cont->findItem( cont->idAt( i ), &md ); + if ( item && md == cont && item->popup() == pm ) + id = item->id(); + } + return id; +} diff --git a/src/Qtx/QtxMRUAction.h b/src/Qtx/QtxMRUAction.h new file mode 100755 index 000000000..12a87e024 --- /dev/null +++ b/src/Qtx/QtxMRUAction.h @@ -0,0 +1,113 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxMRUAction.h +// Author: Sergey TELKOV + +#ifndef QTXMRUACTION_H +#define QTXMRUACTION_H + +#include "QtxAction.h" + +#include +#include + +class QPopupMenu; +class QtxResourceMgr; + +#ifdef WIN32 +#pragma warning( disable:4251 ) +#endif + +class QTX_EXPORT QtxMRUAction : public QtxAction +{ + Q_OBJECT + +public: + typedef enum { Items, SubMenu } PopupMode; + typedef enum { MoveFirst, MoveLast, AddFirst, AddLast } InsertMode; + +public: + QtxMRUAction( QObject* = 0, const char* = 0 ); + QtxMRUAction( const QString&, const QString&, QObject*, const char* = 0 ); + QtxMRUAction( const QString&, const QIconSet&, const QString&, QObject*, const char* = 0 ); + virtual ~QtxMRUAction(); + + int insertMode() const; + void setInsertMode( const int ); + + int popupMode() const; + void setPopupMode( const int ); + + int count() const; + bool isEmpty() const; + + int visibleCount() const; + void setVisibleCount( const int ); + + void remove( const int ); + void remove( const QString& ); + void insert( const QString& ); + + QString item( const int ) const; + int find( const QString& ) const; + bool contains( const QString& ) const; + + virtual bool addTo( QWidget* ); + virtual bool addTo( QWidget*, const int ); + + virtual bool removeFrom( QWidget* ); + + virtual void loadLinks( QtxResourceMgr*, const QString&, const bool = true ); + virtual void saveLinks( QtxResourceMgr*, const QString&, const bool = true ) const; + +signals: + void activated( QString ); + +public slots: + virtual void setEnabled( bool ); + +private slots: + void onAboutToShow(); + void onActivated( int ); + void onDestroyed( QObject* ); + +private: + void updateState(); + void checkPopup( QPopupMenu* ); + void updatePopup( QPopupMenu*, const int ); + bool removeLinks( QPopupMenu*, const int ); + bool insertLinks( QPopupMenu*, const int, const int = -1 ); + + int findId( QPopupMenu*, QPopupMenu* ) const; + +private: + typedef struct { int pId, nId; QIntList idList; } Item; + typedef QMap ItemsMap; + typedef QMap MenusMap; + +private: + QStringList myLinks; + ItemsMap myItems; + MenusMap myMenus; + int myVisCount; + int myPopupMode; + int myInsertMode; +}; + +#endif diff --git a/src/Qtx/QtxMenuButton.cxx b/src/Qtx/QtxMenuButton.cxx new file mode 100755 index 000000000..88bfc1061 --- /dev/null +++ b/src/Qtx/QtxMenuButton.cxx @@ -0,0 +1,328 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxMenuButton.cxx +// Author: Sergey TELKOV + +#include "QtxMenuButton.h" + +#include +#include +#include +#include +#include + +class QtxMenuButton::PopupMenu : public QPopupMenu +{ +public: + PopupMenu( QtxMenuButton* mb ) : QPopupMenu( mb ), myMenuButton( mb ) {}; + virtual ~PopupMenu() {}; + + virtual void setMinimumSize( int, int ); + +private: + QtxMenuButton* myMenuButton; +}; + +void QtxMenuButton::PopupMenu::setMinimumSize( int w, int h ) +{ + if ( myMenuButton->isAlignWidth() && + ( myMenuButton->position() == Top || myMenuButton->position() == Bottom ) ) + w = QMAX( w, myMenuButton->width() ); + + QPopupMenu::setMinimumSize( w, h ); +} + + +QtxMenuButton::QtxMenuButton( int pos, QWidget* parent, const char* name ) +: QPushButton( parent, name ), +myPos( pos ) +{ + initialize(); +} + +QtxMenuButton::QtxMenuButton( const QString& text, QWidget* parent, const char* name ) +: QPushButton( parent, name ), +myPos( Bottom ) +{ + setText( text ); + initialize(); +} + +QtxMenuButton::QtxMenuButton( int pos, const QString& text, QWidget* parent, const char* name ) +: QPushButton( parent, name ), +myPos( pos ) +{ + setText( text ); + initialize(); +} + +QtxMenuButton::QtxMenuButton( QWidget* parent, const char* name ) +: QPushButton( parent, name ), +myPos( Bottom ) +{ + initialize(); +} + +QtxMenuButton::~QtxMenuButton() +{ +} + +void QtxMenuButton::initialize() +{ + myArrow = true; + myAlign = true; + + setAutoDefault( false ); + myPopup = new PopupMenu( this ); + myPopup->hide(); + + connect( myPopup, SIGNAL( activated( int ) ), this, SIGNAL( activated( int ) ) ); + connect( this, SIGNAL( clicked() ), this, SLOT( onShowPopup() ) ); +} + +int QtxMenuButton::position() const +{ + return myPos; +} + +bool QtxMenuButton::isAlignWidth() const +{ + return myAlign; +} + +bool QtxMenuButton::isArrowEnabled() const +{ + return myArrow; +} + +void QtxMenuButton::setPosition( const int pos ) +{ + if ( myPos == pos ) + return; + + myPos = pos; + if ( myPopup->isVisible() ) + onShowPopup(); +} + +void QtxMenuButton::setAlignWidth( const bool on ) +{ + if ( myAlign == on ) + return; + + myAlign = on; + updateGeometry(); +} + +void QtxMenuButton::setArrowEnabled( const bool on ) +{ + if ( myArrow == on ) + return; + + myArrow = on; + repaint(); +} + +void QtxMenuButton::clear() +{ + if ( myPopup ) + myPopup->clear(); + onShowPopup(); + updateGeometry(); +} + +void QtxMenuButton::removeItem( int id ) +{ + if ( myPopup ) + removeItem( id ); + updateGeometry(); +} + +int QtxMenuButton::insertSeparator( int id ) +{ + int res = -1; + if ( myPopup ) + res = myPopup->insertSeparator( id ); + return res; +} + +int QtxMenuButton::insertItem( const QString& t, int id, int index ) +{ + int resId = -1; + if ( myPopup ) + resId = myPopup->insertItem( t, id, index ); + + if ( resId != -1 ) + updateGeometry(); + + return resId; +} + +int QtxMenuButton::insertItem( const QIconSet& is, const QString& t, int id, int index ) +{ + int resId = -1; + if ( myPopup ) + resId = myPopup->insertItem( is, t, id, index ); + + if ( resId != -1 ) + updateGeometry(); + + return resId; +} + +void QtxMenuButton::onShowPopup() +{ + if ( !myPopup || !myPopup->count() ) + { + myPopup->hide(); + return; + } + + QPoint p = mapToGlobal( QPoint( 0, 0 ) ); + int x = p.x(); + int y = p.y() + 1; + int margin = 0; + int xoffset = 0; + int yoffset = 0; + switch ( position() ) + { + case Left: + xoffset = -1 * ( myPopup->sizeHint().width() + margin ); + break; + case Right: + xoffset = width() + margin; + break; + case Top: + yoffset = -1 * ( myPopup->sizeHint().height() + margin ); + break; + case Bottom: + default: + yoffset = height() + margin; + break; + } + int dw = QApplication::desktop()->width(); + int dh = QApplication::desktop()->height(); + x = QMIN( QMAX( x + xoffset, 0 ), dw ); + y = QMIN( QMAX( y + yoffset, 0 ), dh ); + + myPopup->exec( QPoint( x, y ) ); +} + +bool QtxMenuButton::event( QEvent* e ) +{ + if ( e->type() == QEvent::MouseButtonPress || + e->type() == QEvent::MouseButtonDblClick || + e->type() == QEvent::MouseButtonRelease ) + { + onShowPopup(); + return false; + } + + return QPushButton::event( e ); +} + +QSize QtxMenuButton::sizeHint() const +{ + QSize sz = QPushButton::sizeHint(); + if ( ( position() == Top || position() == Bottom ) && myPopup && myAlign ) + sz = QSize( QMAX( sz.width(), myPopup->sizeHint().width() ), sz.height() ); + + return sz; +} + +QSize QtxMenuButton::minimumSizeHint() const +{ + QSize sz = QPushButton::minimumSizeHint(); + if ( ( position() == Top || position() == Bottom ) && myPopup && myAlign ) + sz = QSize( QMAX( sz.width(), myPopup->sizeHint().width() ), sz.height() ); + + return sz; +} + +void QtxMenuButton::resizeEvent( QResizeEvent* re ) +{ + if ( re ) + QPushButton::resizeEvent( re ); + + if ( ( position() == Top || position() == Bottom ) && myPopup && myAlign ) + myPopup->setMinimumWidth( re ? re->size().width() : width() ); +} + +QPopupMenu* QtxMenuButton::popup() const +{ + return myPopup; +} + +void QtxMenuButton::drawButtonLabel( QPainter* p ) +{ + QPushButton::drawButtonLabel( p ); +/* + QStyle::SFlags flags = QStyle::Style_Default; + if ( isEnabled() ) + flags |= QStyle::Style_Enabled; + if ( hasFocus() ) + flags |= QStyle::Style_HasFocus; +*/ +#if QT_VER < 3 + QRect r = rect(); +#else + QRect r = style().subRect( QStyle::SR_PushButtonContents, this ); +#endif + + if ( myArrow && myPopup && myPopup->count() ) + { + int w = 7; + int h = 7; + int margin = 5; + + QRect ar( 0, 0, w, h ); + if ( position() == Left || position() == Top ) + r.moveBy( ar.width() + 2 * margin, 0 ); + else + ar.moveBy( r.width() - ar.width() - 2 * margin, 0 ); + + r.setWidth( r.width() - ar.width() - 2 * margin ); + + ar.moveBy( margin, ( height() - h ) / 2 ); + + QPointArray arrow( 3 ); + switch ( position() ) + { + case Left: + arrow.putPoints( 0, 3, ar.left(), ar.top() + ar.height() / 2, ar.right(), ar.top(), ar.right(), ar.bottom() ); + break; + case Right: + arrow.putPoints( 0, 3, ar.left(), ar.top(), ar.left(), ar.bottom(), ar.right(), ar.top() + ar.height() / 2 ); + break; + case Top: + arrow.putPoints( 0, 3, ar.left(), ar.bottom(), ar.right(), ar.bottom(), ar.left() + ar.width() / 2, ar.top() ); + break; + case Bottom: + default: + arrow.putPoints( 0, 3, ar.left(), ar.top(), ar.right(), ar.top(), ar.left() + ar.width() / 2, ar.bottom() ); + break; + } + + p->setPen( colorGroup().text() ); + p->setBrush( colorGroup().text() ); + p->drawPolygon( arrow, true ); + } + +// style().drawControl( QStyle::CE_PushButtonLabel, p, this, r, colorGroup(), flags ); +} diff --git a/src/Qtx/QtxMenuButton.h b/src/Qtx/QtxMenuButton.h new file mode 100755 index 000000000..62effa2da --- /dev/null +++ b/src/Qtx/QtxMenuButton.h @@ -0,0 +1,88 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxMenuButton.h +// Author: Sergey TELKOV + +#ifndef QTXMENUBUTTON_H +#define QTXMENUBUTTON_H + +#include "Qtx.h" + +#include + +class QIconSet; +class QPopupMenu; + +class QTX_EXPORT QtxMenuButton : public QPushButton +{ + Q_OBJECT + + class PopupMenu; + +public: + enum { Left, Right, Top, Bottom }; + +public: + QtxMenuButton( int, QWidget* = 0, const char* = 0 ); + QtxMenuButton( const QString&, QWidget* = 0, const char* = 0 ); + QtxMenuButton( int, const QString&, QWidget* = 0, const char* = 0 ); + QtxMenuButton( QWidget* = 0, const char* = 0 ); + virtual ~QtxMenuButton(); + + int position() const; + void setPosition( const int ); + + bool isAlignWidth() const; + void setAlignWidth( const bool ); + + bool isArrowEnabled() const; + void setArrowEnabled( const bool ); + + void clear(); + void removeItem( int ); + int insertSeparator( int = -1 ); + int insertItem( const QString&, int = -1, int = -1 ); + int insertItem( const QIconSet&, const QString&, int = -1, int = -1 ); + + virtual QSize sizeHint() const; + virtual QSize minimumSizeHint() const; + +signals: + void activated( int ); + +private slots: + void onShowPopup(); + +protected: + QPopupMenu* popup() const; + virtual bool event( QEvent* ); + virtual void resizeEvent( QResizeEvent* ); + virtual void drawButtonLabel( QPainter* ); + +private: + void initialize(); + +private: + int myPos; + bool myArrow; + bool myAlign; + QPopupMenu* myPopup; +}; + +#endif diff --git a/src/Qtx/QtxOperations.cxx b/src/Qtx/QtxOperations.cxx new file mode 100644 index 000000000..0034d41e4 --- /dev/null +++ b/src/Qtx/QtxOperations.cxx @@ -0,0 +1,46 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// + +#include "QtxOperations.h" + +//================================================================ +// Function : +// Purpose : +//================================================================ +QtxOperations::QtxOperations() +{ +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +QtxOperations::~QtxOperations() +{ +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +bool QtxOperations::createValue( const QString& str, QtxValue& v ) const +{ + v = str; + return false; +} diff --git a/src/Qtx/QtxOperations.h b/src/Qtx/QtxOperations.h new file mode 100644 index 000000000..9dae0b336 --- /dev/null +++ b/src/Qtx/QtxOperations.h @@ -0,0 +1,65 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxOperations.h +// Author: Alexander SOLOVYOV + +#ifndef __QTX_OPERATIONS_HEADER__ +#define __QTX_OPERATIONS_HEADER__ + +#include "Qtx.h" +#include "QtxParser.h" + +//================================================================ +// Class : +// Purpose : +//================================================================ +class QTX_EXPORT QtxOperations +{ +public: + QtxOperations(); + virtual ~QtxOperations(); + + virtual void opersList( QStringList& ) const = 0; + //list of possible operations + + virtual void bracketsList( QStringList&, bool open ) const = 0; + //list of open/close brackets + + virtual bool createValue( const QString&, QtxValue& ) const; + //by default, the String value will be set, it corresponds to parameter + //base method returns false (always parameter) + //successor's method returns true if it has created custom value + //or call base if it hasn't + + virtual int prior( const QString&, bool isBin ) const = 0; + //returns prioritet of operation; + //if operation is impossible, it must return 0 or less + + virtual QtxParser::Error isValid( const QString&, + const QVariant::Type, + const QVariant::Type ) const = 0; + //return OK if this parameter types is valid for operation + //return OperandsNotMatch or InvalidOperation otherwise + + virtual QtxParser::Error calculate( const QString&, QtxValue&, QtxValue& ) const = 0; + //process binary operation with values + //for unary operation the second QtxValue will be passed as invalid +}; + +#endif diff --git a/src/Qtx/QtxParser.cxx b/src/Qtx/QtxParser.cxx new file mode 100644 index 000000000..105ddb7a5 --- /dev/null +++ b/src/Qtx/QtxParser.cxx @@ -0,0 +1,840 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// + +#include "QtxParser.h" +#include "QtxOperations.h" + +//================================================================ +// Function : +// Purpose : +//================================================================ +QtxParser::QtxParser( QtxOperations* operations, + const QString& expr ) +: myOperations( operations ) +{ + if( myOperations ) + { + setLastError( OK ); + setExpr( expr ); + } + else + setLastError( OperationsNull ); +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +QtxParser::~QtxParser() +{ +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +int QtxParser::search( const QStringList& list, const QString& str, int offset, + int& matchLen, int& listind ) +{ + QStringList::const_iterator anIt = list.begin(), aLast = list.end(); + int min = -1; + for( int ind = 0; anIt!=aLast; anIt++, ind++ ) + { + //const char* where = str.latin1(), *what = (*anIt).latin1(); + int pos = str.find( *anIt, offset ); + if( pos>=0 && ( min < 0 || min > pos || + ( min==pos && matchLen< (int)(*anIt).length() ) ) ) + { + min = pos; + listind = ind; + matchLen = (*anIt).length(); + } + } + if( min<0 ) + matchLen = 0; + return min; +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +QString QtxParser::note( const QString& str, int pos, int len ) +{ + return str.mid( pos, len ).stripWhiteSpace(); +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +bool QtxParser::prepare( const QString& expr, Postfix& post ) +{ + int pos = 0, len = expr.length(); + QValueStack< int > aBracketStack; + QStringList anOpers, anOpenBr, aCloseBr; + if( myOperations ) + { + myOperations->bracketsList( anOpenBr, true ); + myOperations->bracketsList( aCloseBr, false ); + myOperations->opersList( anOpers ); + } + else + { + setLastError( OperationsNull ); + return false; + } + + while( pos < len && lastError()==OK ) + { + PostfixItem item; + while( expr[ pos ].isSpace() && pos=len ) + break; + + int mBrLen = 0, mLen = 0, br_ind = -1, op_ind = -1; + int oPos = search( anOpenBr, expr, pos, mBrLen, br_ind ), + cPos = oPos==pos ? -1 : search( aCloseBr, expr, pos, mBrLen, br_ind ), + opPos = search( anOpers, expr, pos, mLen, op_ind ); + + if( expr[ pos ]=="'" ) + { + int vpos = pos+1; + while ( vpos< (int)expr.length() && expr[ vpos ]!="'" ) + vpos++; + + mLen = vpos-pos+1; + + int res = myOperations->createValue( note( expr, pos, mLen ), item.myValue ); + item.myType = res ? Value : Param; + post.append( item ); + pos = vpos+1; + continue; + } + + if( oPos==pos ) + { + aBracketStack.push( br_ind ); + item.myValue = note( expr, pos, mBrLen ); + item.myType = Open; + post.append( item ); + } + + else if( cPos==pos ) + { + if( aBracketStack.count()==0 ) + { + setLastError( ExcessClose ); + break; + } + if( br_ind!=aBracketStack.top() ) + { + setLastError( BracketsNotMatch ); + break; + } + else + { + aBracketStack.pop(); + item.myValue = note( expr, pos, mBrLen ); + item.myType = Close; + post.append( item ); + } + } + else + mBrLen = 0; + + if( opPos==pos ) + { + mBrLen = 0; + item.myValue = note( expr, pos, mLen ); + item.myType = Binary; + //the type is set by default; + //the method setOperationTypes will set correct types + + if( oPos==pos ) + post.insert( post.at( post.count()-1 ), item ); + else + post.append( item ); + } + else + { + mLen = 0; + if( oPos!=pos && cPos!=pos ) + { + int i; + for( i=pos+1; i<(int)expr.length(); i++ ) + if( expr[ i ].isSpace() ) + break; + + int vpos = i; + if( oPos>=0 && oPos=0 && cPos=0 && opPoscreateValue( note( expr, pos, mLen ), item.myValue ); + item.myType = res ? Value : Param; + post.append( item ); + } + } + + pos+=mBrLen+mLen; + } + + //Bracket checking + PostfixIterator anIt = post.begin(), + aLast = post.end(); + int brValue = 0; + for( ; anIt!=aLast; anIt++ ) + if( (*anIt).myType==Open ) + brValue++; + else if( (*anIt).myType==Close ) + if( brValue>0 ) + brValue--; + else + { + setLastError( ExcessClose ); + break; + } + if( brValue>0 ) + setLastError( CloseExpected ); + + return lastError()==OK; +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +bool QtxParser::setOperationTypes( Postfix& post ) +{ + Postfix::iterator aStart = post.begin(), + aLast = post.end(), + anIt = aStart, aPrev, aNext; + QStringList anOpen, aClose; + if( myOperations ) + { + myOperations->bracketsList( anOpen, true ); + myOperations->bracketsList( aClose, false ); + } + else + return false; + + for( ; anIt!=aLast; anIt++ ) + { + aPrev = anIt; aPrev--; + aNext = anIt; aNext++; + if( (*anIt).myType != Binary ) + continue; + + if( ( anIt==aStart || (*aPrev).myType == Open || + (*aPrev).myType == Pre || + (*aPrev).myType == Binary ) + && + aNext!=aLast && ( (*aNext).myType == Value || + (*aNext).myType == Param || + (*aNext).myType == Open || + (*aNext).myType == Binary ) ) + (*anIt).myType = Pre; + + else if( anIt!=aStart && ( (*aPrev).myType == Close || + (*aPrev).myType == Param || + (*aPrev).myType == Value || + (*aPrev).myType == Pre || + (*aPrev).myType == Post || + (*aPrev).myType == Binary ) + && + ( aNext==aLast || (*aNext).myType == Close ) ) + (*anIt).myType = Post; + + if( anOpen.contains( ( *anIt ).myValue.toString() )>0 ) + (*anIt).myType = Pre; + else if( aClose.contains( ( *anIt ).myValue.toString() )>0 ) + (*anIt).myType = Post; + } + + return lastError()==OK; +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +int QtxParser::globalBrackets( const QtxParser::Postfix& post, int f, int l ) +{ + int i, + start_br = 0, + fin_br = 0, + br = 0, + br_num = 0, + min_br_num = (l-f+1)*5; + + for( i=f; i<=l; i++ ) + if( post[ i ].myType==QtxParser::Open ) + start_br++; + else + break; + for( i=l; i>=f; i-- ) + if( post[ i ].myType==QtxParser::Close ) + fin_br++; + else + break; + + br = start_br=0 ) + res.append( post[ f ] ); + if( l<=f ) + return true; + + if( myOperations ) + { + int min = -1; + QIntList argmin; + QValueList< PostfixItemType > min_types; + + //Find operation with minimal priority + //PostfixIterator anIt = post.at( f ), + // aLast = post.at( l+1 ); + for( int i=0, j=f; j<=l; i++, j++ ) + { + const PostfixItem& item = post[ j ]; + PostfixItemType tt = item.myType; + if( tt==Binary || tt==Pre || tt==Post ) + { + int cur_pr = myOperations->prior( item.myValue.toString(), tt==Binary ); + if( cur_pr>0 ) + { + if( min<0 || min>=cur_pr ) + { + if( min==cur_pr ) + { + argmin.append( f+i ); + min_types.append( tt ); + } + else + { + min = cur_pr; + argmin.clear(); argmin.append( f+i ); + min_types.clear(); min_types.append( tt ); + } + } + } + else + { + setLastError( InvalidOperation ); + break; + } + } + else if( tt==Open ) + { + QString opBr = item.myValue.toString(); + int ind = anOpen.findIndex( opBr ), brValue = 0; + while( j<=l ) + { + const PostfixItem& anItem = post[ j ]; + if( anItem.myType==Open ) + brValue++; + + if( anItem.myType==Close ) + { + brValue--; + QString clBr = anItem.myValue.toString(); + if( aClose.findIndex( clBr )==ind && brValue==0 ) + break; + } + i++; j++; + } + if( brValue>0 ) + { + setLastError( CloseExpected ); + break; + } + } + } + + if( lastError()==OK ) + if( min>=0 ) + { + QValueList< Postfix > parts; + QIntList::const_iterator anIt = argmin.begin(), + aLast = argmin.end(); + Postfix one; + bool ok = sort( post, one, anOpen, aClose, f, *anIt - 1 ); + parts.append( one ); + one.clear(); + for( ; anIt!=aLast && ok; anIt++ ) + { + QIntList::const_iterator aNext = anIt; aNext++; + ok = sort( post, one, anOpen, aClose, *anIt + 1, aNext==aLast ? l : *aNext - 1 ); + parts.append( one ); + one.clear(); + } + if( !ok ) + return false; + + QValueList< Postfix >::const_iterator aPIt = parts.begin(); + QValueList< PostfixItemType >::const_iterator aTIt = min_types.begin(); + QValueStack< PostfixItem > aStack; + res += (*aPIt); aPIt++; + anIt = argmin.begin(); + for( ; anIt!=aLast; anIt++, aPIt++, aTIt++ ) + { + if( *aTIt==Pre ) + if( anOpen.contains( post[ *anIt ].myValue.toString() )==0 ) + { + res+=(*aPIt); + aStack.push( post[ *anIt ] ); + } + else + { + res.append( post[ *anIt ] ); + res+=(*aPIt); + } + else + { + res+=(*aPIt); + while( !aStack.isEmpty() ) + { + res.append( aStack.top() ); + aStack.pop(); + } + res.append( post[ *anIt ] ); + } + } + while( !aStack.isEmpty() ) + { + res.append( aStack.top() ); + aStack.pop(); + } + } + else + { //there are no operations + PostfixIterator anIt = post.at( f ), + aLast = post.at( l+1 ); + for( ; anIt!=aLast; anIt++ ) + if( (*anIt).myType==Value || (*anIt).myType==Param ) + res.append( *anIt ); + } + } + else + setLastError( OperationsNull ); + + return lastError()==OK; +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +bool QtxParser::parse( const QString& expr ) +{ + myPost.clear(); + + Postfix p; + QStringList opens, closes; + + if( myOperations ) + { + setLastError( OK ); + myOperations->bracketsList( opens, true ); + myOperations->bracketsList( closes, false ); + } + else + { + setLastError( OperationsNull ); + return false; + } + + //return prepare( expr, myPost ) && setOperationTypes( myPost ); + return prepare( expr, p ) && setOperationTypes( p ) && + sort( p, myPost, opens, closes ); +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +bool QtxParser::calculate( const QString& op, QtxValue& v1, QtxValue& v2 ) +{ + Error err = myOperations->isValid( op, v1.type(), v2.type() ); + if( err==OK ) + setLastError( myOperations->calculate( op, v1, v2 ) ); + else + setLastError( err ); + + return lastError()==OK; +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +QtxValue QtxParser::calculate() +{ + setLastError( OK ); + + QStringList anOpen, aClose; + if( myOperations ) + { + myOperations->bracketsList( anOpen, true ); + myOperations->bracketsList( aClose, false ); + } + else + { + setLastError( OperationsNull ); + return QtxValue(); + } + + QtxValueStack aStack; + PostfixIterator anIt = myPost.begin(), + aLast = myPost.end(); + for( ; anIt!=aLast && lastError()==OK; anIt++ ) + { + QString nn = (*anIt).myValue.toString(); + if( (*anIt).myType==Param ) + { + if( has( nn ) ) + { + QVariant& v = myParameters[ nn ]; + if( v.isValid() ) + aStack.push( v ); + else + setLastError( InvalidToken ); + } + else + setLastError( InvalidToken ); + } + + else if( (*anIt).myType==Value ) + aStack.push( (*anIt).myValue ); + + else if( (*anIt).myType==Pre || (*anIt).myType==Post ) + { + if( anOpen.contains( nn )>0 ) + { + QtxValue inv; + if( calculate( nn, inv, inv ) ) + aStack.push( QtxValue() ); + } + else if( aClose.contains( nn )>0 ) + { + QValueList< QtxValue > set; + while( true ) + { + if( aStack.count()==0 ) + { + setLastError( StackUnderflow ); + break; + } + if( aStack.top().isValid() ) + { + set.append( aStack.top() ); + aStack.pop(); + } + else + { + aStack.pop(); + break; + } + } + + QtxValue qSet = set, inv; + if( calculate( nn, qSet, inv ) ) + aStack.push( set ); + } + else if( aStack.count()>=1 ) + { + QtxValue inv; + QtxValue* v1 = &aStack.top(), *v2 = &inv; //"post-" case + if( (*anIt).myType==Pre ) + { + v2 = &aStack.top(); v1 = &inv; + } + + calculate( nn, *v1, *v2 ); + } + else + setLastError( StackUnderflow ); + } + + else if( (*anIt).myType==Binary ) + { + if( aStack.count()>=2 ) + { + QVariant v2 = aStack.top(); aStack.pop(); + calculate( nn, aStack.top(), v2 ); + } + else + setLastError( StackUnderflow ); + } + } + + QtxValue res; + if( lastError()==OK ) + { + int count = aStack.count(); + if( count==0 ) + setLastError( StackUnderflow ); + else if( count==1 ) + res = aStack.top(); + else + setLastError( ExcessData ); + } + return res; +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +QtxValue QtxParser::calculate( const QString& expr ) +{ + setExpr( expr ); + return calculate(); +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +bool QtxParser::setExpr( const QString& expr ) +{ + return parse( expr ); +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +bool QtxParser::has( const QString& name ) const +{ + return myParameters.contains( name.stripWhiteSpace() ); +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +void QtxParser::set( const QString& name, const QtxValue& value ) +{ + myParameters[ name.stripWhiteSpace() ] = value; +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +bool QtxParser::remove( const QString& name ) +{ + QString sname = name.stripWhiteSpace(); + bool res = has( sname ); + if( res ) + myParameters.remove( sname ); + return res; +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +QtxValue QtxParser::value( const QString& name ) const +{ + QString sname = name.stripWhiteSpace(); + if( has( sname ) ) + return myParameters[ sname ].toString(); + else + return QtxValue(); +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +bool QtxParser::firstInvalid( QString& name ) const +{ + QMap< QString, QtxValue >::const_iterator anIt = myParameters.begin(), + aLast = myParameters.end(); + for( ; anIt!=aLast; anIt++ ) + if( !anIt.data().isValid() ) + { + name = anIt.key(); + return true; + } + return false; +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +void QtxParser::removeInvalids() +{ + QStringList toDelete; + QMap< QString, QtxValue >::const_iterator anIt = myParameters.begin(), + aLast = myParameters.end(); + for( ; anIt!=aLast; anIt++ ) + if( !anIt.data().isValid() ) + toDelete.append( anIt.key() ); + + QStringList::const_iterator aLIt = toDelete.begin(), + aLLast = toDelete.end(); + for( ; aLIt!=aLLast; aLIt++ ) + myParameters.remove( *aLIt ); +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +QtxParser::Error QtxParser::lastError() const +{ + return myLastError; +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +void QtxParser::setLastError( QtxParser::Error err ) +{ + myLastError = err; +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +QString QtxParser::dump() const +{ + return dump( myPost ); +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +QString QtxParser::dump( const Postfix& post ) const +{ + QString res; + + if( myOperations ) + { + PostfixIterator anIt = post.begin(), + aLast = post.end(); + for( ; anIt!=aLast; anIt++ ) + { + if( (*anIt).myType == Value && + ( ( *anIt ).myValue.type()==QVariant::String || + ( *anIt ).myValue.type()==QVariant::CString ) ) + res += "'" + ( *anIt ).myValue.toString() + "'"; + else + res += ( *anIt ).myValue.toString(); + if( (*anIt).myType == Pre ) + res += "(pre)"; + else if( (*anIt).myType == Post ) + res += "(post)"; + else if( (*anIt).myType == Binary ) + res += "(bin)"; + + res += "_"; + } + } + return res; +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +void QtxParser::paramsList( QStringList& list ) +{ + PostfixIterator anIt = myPost.begin(), + aLast = myPost.end(); + for( ; anIt!=aLast; anIt++ ) + if( (*anIt).myType==Param ) + { + QString name = (*anIt).myValue.toString(); + if( list.contains( name )==0 ) + list.append( name ); + } +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +void QtxParser::clear() +{ + myParameters.clear(); +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +QString QtxParser::toString( const QValueList< QtxValue >& list ) +{ + QValueList< QtxValue >::const_iterator anIt = list.begin(), + aLast = list.end(); + QString res = "set : [ "; + for( ; anIt!=aLast; anIt++ ) + res+=(*anIt).toString()+" "; + res+="]"; + return res; +} diff --git a/src/Qtx/QtxParser.h b/src/Qtx/QtxParser.h new file mode 100644 index 000000000..737fc96ce --- /dev/null +++ b/src/Qtx/QtxParser.h @@ -0,0 +1,117 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxParser.h +// Author: Alexander SOLOVYOV + +#ifndef __QTX_PARSER_HEADER__ +#define __QTX_PARSER_HEADER__ + +#include "Qtx.h" +#include +#include + +#ifdef WIN32 +#pragma warning( disable:4251 ) +#endif + + +class QtxOperations; + +typedef QVariant QtxValue; + + +//================================================================ +// Class : +// Purpose : +//================================================================ +class QTX_EXPORT QtxParser +{ +public: + typedef enum + { + OK, OperandsNotMatch, InvalidResult, InvalidOperation, + OperationsNull, InvalidToken, CloseExpected, ExcessClose, + BracketsNotMatch, StackUnderflow, ExcessData + + } Error; + +public: + QtxParser( QtxOperations*, const QString& = QString::null ); + virtual ~QtxParser(); + + QtxValue calculate(); + QtxValue calculate( const QString& ); + bool setExpr( const QString& ); + + virtual void clear(); + virtual bool has ( const QString& name ) const; + virtual void set ( const QString& name, const QtxValue& value ); + virtual bool remove( const QString& name ); + virtual QtxValue value ( const QString& name ) const; + + bool firstInvalid( QString& ) const; + void removeInvalids(); + QString dump() const; + Error lastError() const; + void paramsList( QStringList& ); + + static QString toString( const QValueList< QtxValue >& ); + +protected: + typedef enum { Value, Param, Open, Close, Pre, Post, Binary } PostfixItemType; + + typedef struct + { + QtxValue myValue; + PostfixItemType myType; + + } PostfixItem; + + typedef QValueList< PostfixItem > Postfix; + typedef Postfix::const_iterator PostfixIterator; + +protected: + QString dump( const Postfix& ) const; + virtual bool prepare( const QString&, Postfix& ); + virtual bool setOperationTypes( Postfix& ); + virtual bool sort( const Postfix&, Postfix&, + const QStringList&, const QStringList&, + int f=-1, int l=-1 ); + + virtual bool parse( const QString& ); + virtual void setLastError( const Error ); + + bool calculate( const QString&, QtxValue&, QtxValue& ); + + static int search ( const QStringList&, const QString&, int offset, + int& matchLen, int& listind ); + static QString note ( const QString& str, int pos, int len ); + static int globalBrackets( const Postfix&, int, int ); + +private: + typedef QValueStack < QtxValue > QtxValueStack; + +private: + QtxOperations* myOperations; + QMap< QString, QtxValue > myParameters; + Error myLastError; + Postfix myPost; +}; + +#endif diff --git a/src/Qtx/QtxPathDialog.cxx b/src/Qtx/QtxPathDialog.cxx new file mode 100755 index 000000000..55df5d781 --- /dev/null +++ b/src/Qtx/QtxPathDialog.cxx @@ -0,0 +1,644 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxPathDialog.cxx +// Author: Sergey TELKOV + +#include "QtxPathDialog.h" + +#include "QtxGroupBox.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const char* open_icon[] = { +"16 16 5 1", +" c none", +". c #ffff00", +"# c #848200", +"a c #ffffff", +"b c #000000", +" ", +" bbb ", +" b b b", +" bb", +" bbb bbb", +" ba.abbbbbbb ", +" b.a.a.a.a.b ", +" ba.a.a.a.ab ", +" b.a.abbbbbbbbbb", +" ba.ab#########b", +" b.ab#########b ", +" bab#########b ", +" bb#########b ", +" bbbbbbbbbbb ", +" ", +" " +}; + +//================================================================ +// Function : QtxPathDialog +// Purpose : Constructor. +//================================================================ + +QtxPathDialog::QtxPathDialog( const bool import, QWidget* parent, const bool modal, const bool resize, const int buttons, WFlags f ) +: QtxDialog( parent, 0, modal, resize, buttons, f ), +myDefault( -1 ), +myEntriesFrame( 0 ), +myOptionsFrame( 0 ) +{ + initialize(); + + setCaption( tr( import ? "Open file" : "Save file" ) ); + + setDefaultEntry( createFileEntry( tr( "File name" ), import ? OpenFile : SaveFile ) ); + QLineEdit* le = fileEntry( defaultEntry() ); + if ( le ) + le->setMinimumWidth( 200 ); + + validate(); + + setFocusProxy( le ); +} + +//================================================================ +// Function : QtxPathDialog +// Purpose : Constructor. +//================================================================ + +QtxPathDialog::QtxPathDialog( QWidget* parent, const bool modal, const bool resize, const int buttons, WFlags f ) +: QtxDialog( parent, 0, modal, resize, buttons, f ), +myDefault( -1 ), +myEntriesFrame( 0 ), +myOptionsFrame( 0 ) +{ + initialize(); +} + +//================================================================ +// Function : ~QtxPathDialog +// Purpose : Destructor. +//================================================================ + +QtxPathDialog::~QtxPathDialog() +{ +} + +//================================================================ +// Function : fileName +// Purpose : +//================================================================ + +QString QtxPathDialog::fileName() const +{ + return fileName( defaultEntry() ); +} + +//================================================================ +// Function : setFileName +// Purpose : +//================================================================ + +void QtxPathDialog::setFileName( const QString& txt, const bool autoExtension ) +{ + setFileName( defaultEntry(), txt, autoExtension ); +} + +//================================================================ +// Function : filter +// Purpose : +//================================================================ + +QString QtxPathDialog::filter() const +{ + return myFilter; +} + +//================================================================ +// Function : setFilter +// Purpose : +//================================================================ + +void QtxPathDialog::setFilter( const QString& fltr ) +{ + myFilter = fltr; +} + +//================================================================ +// Function : show +// Purpose : +//================================================================ + +void QtxPathDialog::show() +{ + if ( hasVisibleChildren( myEntriesFrame ) ) + myEntriesFrame->show(); + else + myEntriesFrame->hide(); + + if ( hasVisibleChildren( myOptionsFrame ) ) + myOptionsFrame->show(); + else + myOptionsFrame->hide(); + + QtxDialog::show(); +} + +//================================================================ +// Function : onBrowse +// Purpose : +//================================================================ + +void QtxPathDialog::onBrowse() +{ + const QObject* obj = sender(); + + int id = -1; + + for ( FileEntryMap::Iterator it = myEntries.begin(); it != myEntries.end() && id == -1; ++it ) + if ( it.data().btn == obj ) + id = it.key(); + + if ( id == -1 ) + return; + + FileEntry& entry = myEntries[id]; + + bool isDir = entry.mode != OpenFile && entry.mode != SaveFile; + + if ( !entry.dlg ) + { + entry.dlg = new QFileDialog( QDir::current().path(), QString::null, this, 0, true ); + entry.dlg->setCaption( caption() ); + switch ( entry.mode ) + { + case NewDir: + case OpenDir: + case SaveDir: + isDir = true; + entry.dlg->setMode( QFileDialog::DirectoryOnly ); + break; + case SaveFile: + entry.dlg->setMode( QFileDialog::AnyFile ); + break; + case OpenFile: + default: + entry.dlg->setMode( QFileDialog::ExistingFile ); + break; + } + } + + if ( !isDir ) + entry.dlg->setFilters( prepareFilters() ); + entry.dlg->setSelection( fileName( id ) ); + + if ( entry.dlg->exec() != Accepted ) + return; + + QString fName = entry.dlg->selectedFile(); + + if ( fName.isEmpty() ) + return; + + if ( QFileInfo( fName ).extension().isEmpty() && !isDir ) + fName = autoExtension( fName, entry.dlg->selectedFilter() ); + + fName = QDir::convertSeparators( fName ); + QString prev = QDir::convertSeparators( fileName( id ) ); + if ( isDir ) + { + while ( prev.length() && prev.at( prev.length() - 1 ) == QDir::separator() ) + prev.remove( prev.length() - 1, 1 ); + while ( fName.length() && fName.at( fName.length() - 1 ) == QDir::separator() ) + fName.remove( fName.length() - 1, 1 ); + } + + if ( prev == fName ) + return; + + setFileName( id, fName ); + fileNameChanged( id, fName ); + + if ( id == defaultEntry() ) + emit fileNameChanged( fName ); +} + +//================================================================ +// Function : onReturnPressed +// Purpose : +//================================================================ + +void QtxPathDialog::onReturnPressed() +{ + const QObject* obj = sender(); + + int id = -1; + for ( FileEntryMap::Iterator it = myEntries.begin(); it != myEntries.end() && id == -1; ++it ) + if ( it.data().edit == obj ) + id = it.key(); + + if ( id == -1 ) + return; + + fileNameChanged( id, fileName( id ) ); + + if ( id == defaultEntry() ) + emit fileNameChanged( fileName() ); +} + +//================================================================ +// Function : onTextChanged +// Purpose : +//================================================================ + +void QtxPathDialog::onTextChanged( const QString& ) +{ + validate(); +} + +//================================================================ +// Function : validate +// Purpose : +//================================================================ + +void QtxPathDialog::validate() +{ + setButtonEnabled( isValid(), OK | Yes ); +} + +//================================================================ +// Function : isValid +// Purpose : +//================================================================ + +bool QtxPathDialog::isValid() +{ + bool ok = true; + for ( FileEntryMap::Iterator it = myEntries.begin(); it != myEntries.end() && ok; ++it ) + if ( it.data().edit->isEnabled() ) + ok = !it.data().edit->text().stripWhiteSpace().isEmpty(); + + return ok; +} + +//================================================================ +// Function : acceptData +// Purpose : +//================================================================ + +bool QtxPathDialog::acceptData() const +{ + bool ok = true; + + QWidget* parent = (QWidget*)this; + + FileEntryMap::ConstIterator it; + for ( it = myEntries.begin(); it != myEntries.end() && ok; ++it ) + { + const FileEntry& entry = it.data(); + QFileInfo fileInfo( entry.edit->text() ); + if ( entry.edit->text().isEmpty() ) + { + QMessageBox::critical( parent, caption(), tr( "File name not specified" ), + QMessageBox::Ok, QMessageBox::NoButton ); + ok = false; + } + else switch ( entry.mode ) + { + case OpenFile: + if ( !fileInfo.exists() ) + { + QMessageBox::critical( parent, caption(), tr( "File \"%1\" does not exist" ).arg( fileInfo.filePath() ), + QMessageBox::Ok, QMessageBox::NoButton ); + ok = false; + } + break; + case SaveFile: + if ( fileInfo.exists() ) + ok = QMessageBox::warning( parent, caption(), tr( "File \"%1\" already exist. Do you want to overwrite it?" ).arg( fileInfo.filePath() ), + QMessageBox::Yes, QMessageBox::No ) == QMessageBox::Yes; + break; + case OpenDir: + if ( !fileInfo.exists() || !fileInfo.isDir() ) + { + QMessageBox::critical( parent, caption(), tr( "Directory \"%1\" does not exist" ).arg( fileInfo.filePath() ), + QMessageBox::Ok, QMessageBox::NoButton ); + ok = false; + } + break; + case SaveDir: + if ( fileInfo.exists() && !fileInfo.isDir() ) + { + QMessageBox::critical( parent, caption(), tr( "Directory \"%1\" can't be created because file with the same name exist" ).arg( fileInfo.filePath() ), + QMessageBox::Ok, QMessageBox::NoButton ); + ok = false; + } + break; + case NewDir: + if ( fileInfo.exists() ) + { + if ( !fileInfo.isDir() ) + { + QMessageBox::critical( parent, caption(), tr( "Directory \"%1\" can't be created because file with the same name exist" ).arg( fileInfo.filePath() ), + QMessageBox::Ok, QMessageBox::NoButton ); + ok = false; + } + else if ( QDir( fileInfo.filePath() ).count() > 2 ) + ok = QMessageBox::warning( parent, caption(), tr( "Directory \"%1\" not empty. Do you want to remove all files in this directory?" ).arg( fileInfo.filePath() ), + QMessageBox::Yes, QMessageBox::No ) == QMessageBox::Yes; + } + break; + default: + break; + } + + if ( !ok ) + entry.edit->setFocus(); + } + + return ok; +} + +//================================================================ +// Function : fileNameChanged +// Purpose : +//================================================================ + +void QtxPathDialog::fileNameChanged( int, QString ) +{ +} + +//================================================================ +// Function : optionsFrame +// Purpose : +//================================================================ + +QFrame* QtxPathDialog::optionsFrame() +{ + return myOptionsFrame; +} + +//================================================================ +// Function : getFileName +// Purpose : +//================================================================ + +QString QtxPathDialog::fileName( const int id ) const +{ + QString res; + if ( myEntries.contains( id ) ) + res = myEntries[id].edit->text(); + + return res; +} + +//================================================================ +// Function : setFileName +// Purpose : +//================================================================ + +void QtxPathDialog::setFileName( const int id, const QString& txt, const bool autoExt ) +{ + int mode; + QLineEdit* le = fileEntry( id, mode ); + + if ( le ) + { + if ( autoExt && ( mode == OpenFile || mode == SaveFile ) ) + le->setText( autoExtension( txt ) ); + else + le->setText( txt ); + } +} + +//================================================================ +// Function : fileEntry +// Purpose : +//================================================================ + +QLineEdit* QtxPathDialog::fileEntry( const int id ) const +{ + QLineEdit* le = 0; + if ( myEntries.contains( id ) ) + le = myEntries[id].edit; + + return le; +} + +//================================================================ +// Function : fileEntry +// Purpose : +//================================================================ + +QLineEdit* QtxPathDialog::fileEntry( const int theId, int& theMode ) const +{ + QLineEdit* le = 0; + if ( myEntries.contains( theId ) ) + { + le = myEntries[theId].edit; + theMode = myEntries[theId].mode; + } + + return le; +} + +//================================================================ +// Function : createFileEntry +// Purpose : +//================================================================ + +int QtxPathDialog::createFileEntry( const QString& lab, const int mode, const int id ) +{ + int num = id; + if ( num == -1 ) + { + num--; + while ( myEntries.contains( num ) ) + num--; + } + + FileEntry entry; + entry.dlg = 0; + entry.mode = mode; + + new QLabel( lab, myEntriesFrame ); + entry.edit = new QLineEdit( myEntriesFrame ); + entry.btn = new QPushButton( myEntriesFrame ); + entry.btn->setAutoDefault( false ); + entry.btn->setPixmap( QPixmap( open_icon ) ); + + connect( entry.btn, SIGNAL( clicked() ), this, SLOT( onBrowse() ) ); + connect( entry.edit, SIGNAL( returnPressed() ), this, SLOT( onReturnPressed() ) ); + connect( entry.edit, SIGNAL( textChanged( const QString& ) ), this, SLOT( onTextChanged( const QString& ) ) ); + + myEntries.insert( num, entry ); + + return num; +} + +//================================================================ +// Function : defaultEntry +// Purpose : +//================================================================ + +int QtxPathDialog::defaultEntry() const +{ + return myDefault; +} + +//================================================================ +// Function : setDefaultEntry +// Purpose : +//================================================================ + +void QtxPathDialog::setDefaultEntry( const int id ) +{ + myDefault = id; +} + +//================================================================ +// Function : initialize +// Purpose : +//================================================================ + +void QtxPathDialog::initialize() +{ + setCaption( tr( "File dialog" ) ); + + QVBoxLayout* main = new QVBoxLayout( mainFrame() ); + QtxGroupBox* mainGroup = new QtxGroupBox( 1, Qt::Horizontal, "", mainFrame() ); + mainGroup->setFrameStyle( QFrame::NoFrame ); + mainGroup->setInsideMargin( 0 ); + main->addWidget( mainGroup ); + + myEntriesFrame = new QGroupBox( 3, Qt::Horizontal, "", mainGroup ); + myOptionsFrame = new QFrame( mainGroup ); +} + +//================================================================ +// Function : prepareFilters +// Purpose : +//================================================================ + +QStringList QtxPathDialog::prepareFilters() const +{ + QStringList res; + if ( !myFilter.isEmpty() ) + { + res = QStringList::split( ";;", myFilter ); + bool allFilter = false; + for ( QStringList::ConstIterator it = res.begin(); it != res.end() && !allFilter; ++it ) + { + QStringList wildCards = filterWildCards( *it ); + allFilter = wildCards.findIndex( "*.*" ) != -1; + } + + if ( !allFilter ) + res.append( tr( "All files (*.*)" ) ); + } + + return res; +} + +//================================================================ +// Function : filterWildCards +// Purpose : +//================================================================ + +QStringList QtxPathDialog::filterWildCards( const QString& theFilter ) const +{ + QStringList res; + + int b = theFilter.findRev( "(" ); + int e = theFilter.findRev( ")" ); + if ( b != -1 && e != -1 ) + { + QString content = theFilter.mid( b + 1, e - b - 1 ).stripWhiteSpace(); + QStringList lst = QStringList::split( " ", content ); + for ( QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it ) + if ( (*it).find( "." ) != -1 ) + res.append( (*it).stripWhiteSpace() ); + } + return res; +} + +//================================================================ +// Function : autoExtension +// Purpose : +//================================================================ + +QString QtxPathDialog::autoExtension( const QString& theFileName, const QString& theFilter ) const +{ + QString fName = theFileName; + + if ( fName.isEmpty() ) + return fName; + + QString filter = theFilter; + if ( filter.isEmpty() ) + { + QStringList filters = prepareFilters(); + if ( !filters.isEmpty() ) + filter = filters.first(); + } + + QStringList wildCards = filterWildCards( filter ); + if ( !wildCards.isEmpty() ) + { + QString ext = wildCards.first(); + if ( ext.find( "." ) != -1 ) + ext = ext.mid( ext.find( "." ) + 1 ); + + if ( !ext.isEmpty() && !ext.contains( "*" ) ) + fName = QDir::convertSeparators( fName ) + QString( "." ) + ext; + } + + return fName; +} + +//================================================================ +// Function : hasVisibleChildren +// Purpose : +//================================================================ + +bool QtxPathDialog::hasVisibleChildren( QWidget* wid ) const +{ + bool res = false; + if ( wid ) + { + const QObjectList* aChildren = wid->children(); + if ( aChildren ) + { + for ( QObjectListIt it( *aChildren ); it.current() && !res; ++it ) + { + if ( it.current()->isWidgetType() ) + res = ((QWidget*)it.current())->isVisibleTo( wid ); + } + } + } + return res; +} diff --git a/src/Qtx/QtxPathDialog.h b/src/Qtx/QtxPathDialog.h new file mode 100755 index 000000000..9bd743862 --- /dev/null +++ b/src/Qtx/QtxPathDialog.h @@ -0,0 +1,111 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxPathDialog.h +// Author: Sergey TELKOV + +#ifndef QTXPATHDIALOG_H +#define QTXPATHDIALOG_H + +#include "QtxDialog.h" + +#include + +class QFrame; +class QLineEdit; +class QPushButton; +class QFileDialog; + +#ifdef WIN32 +#pragma warning( disable:4251 ) +#endif + +class QTX_EXPORT QtxPathDialog : public QtxDialog +{ + Q_OBJECT + +protected: + QtxPathDialog( QWidget* = 0, const bool = true, const bool = false, const int = Standard, WFlags = 0 ); + +public: + QtxPathDialog( const bool, QWidget* = 0, const bool = true, const bool = false, const int = Standard, WFlags = 0 ); + virtual ~QtxPathDialog(); + + QString fileName() const; + void setFileName( const QString&, const bool = false ); + + QString filter() const; + void setFilter( const QString& ); + + virtual void show(); + +signals: + void fileNameChanged( QString ); + +protected slots: + void validate(); + +private slots: + void onBrowse(); + void onReturnPressed(); + void onTextChanged( const QString& ); + +protected: + virtual bool isValid(); + virtual bool acceptData() const; + virtual void fileNameChanged( int, QString ); + + QFrame* optionsFrame(); + QString fileName( const int ) const; + void setFileName( const int, const QString&, const bool = false ); + + QLineEdit* fileEntry( const int ) const; + QLineEdit* fileEntry( const int, int& ) const; + int createFileEntry( const QString&, const int, const int = -1 ); + + int defaultEntry() const; + void setDefaultEntry( const int ); + +private: + void initialize(); + QStringList prepareFilters() const; + bool hasVisibleChildren( QWidget* ) const; + QStringList filterWildCards( const QString& ) const; + QString autoExtension( const QString&, const QString& = QString::null ) const; + +protected: + enum { OpenFile, SaveFile, OpenDir, SaveDir, NewDir }; + +private: + typedef struct { int mode; QLineEdit* edit; + QPushButton* btn; QFileDialog* dlg; } FileEntry; + typedef QMap FileEntryMap; + +private: + QString myFilter; + FileEntryMap myEntries; + int myDefault; + QFrame* myEntriesFrame; + QFrame* myOptionsFrame; +}; + +#ifdef WIN32 +#pragma warning( default:4251 ) +#endif + +#endif diff --git a/src/Qtx/QtxPopupMenu.cxx b/src/Qtx/QtxPopupMenu.cxx new file mode 100644 index 000000000..5da53d034 --- /dev/null +++ b/src/Qtx/QtxPopupMenu.cxx @@ -0,0 +1,256 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "QtxPopupMenu.h" + +#include + +/*! + Class: QtxPopupMenu::TitleMenuItem [Internal] + Descr: Custom menu item for popup title. +*/ + +class QtxPopupMenu::TitleMenuItem : public QCustomMenuItem +{ +public: + TitleMenuItem( const QString&, const QIconSet&, const int ); + virtual ~TitleMenuItem(); + + virtual bool fullSpan() const; + virtual bool isSeparator() const; + virtual void setFont( const QFont& ); + + virtual void paint( QPainter*, const QColorGroup&, bool, bool, int, int, int, int ); + virtual QSize sizeHint(); + +private: + QString myText; + QIconSet myIcon; + QFont myFont; + int myAlign; +}; + +QtxPopupMenu::TitleMenuItem::TitleMenuItem( const QString& txt, const QIconSet& ico, const int align ) +: QCustomMenuItem(), +myText( txt ), +myIcon( ico ), +myAlign( align ) +{ +} + +QtxPopupMenu::TitleMenuItem::~TitleMenuItem() +{ +} + +bool QtxPopupMenu::TitleMenuItem::fullSpan() const +{ + return true; +} + +bool QtxPopupMenu::TitleMenuItem::isSeparator() const +{ + return false; +} + +void QtxPopupMenu::TitleMenuItem::setFont( const QFont& font ) +{ + myFont = font; + myFont.setBold( true ); +} + +void QtxPopupMenu::TitleMenuItem::paint( QPainter* p, const QColorGroup& cg, + bool act, bool enabled, int x, int y, int w, int h ) +{ + QFont f = p->font(); + p->setFont( myFont ); + + p->fillRect( x, y, w, h, cg.brush( QColorGroup::Dark ) ); + + p->setPen( cg.shadow() ); + p->drawRect( x, y, w, h ); + + int m = 3; + int s = 3; + int iw = p->fontMetrics().width( myText ) + ( myIcon.isNull() ? 0 : myIcon.pixmap().width() + s ); + int ih = QMAX( ( myIcon.isNull() ? 0 : myIcon.pixmap().height() ), p->fontMetrics().height() ); + + int ix = x; + int iy = y + m; + + if ( myAlign & AlignLeft ) + ix = x; + else if ( myAlign & AlignRight ) + ix = x + ( w - iw ); + else if ( myAlign & AlignHCenter ) + ix = x + ( w - iw ) / 2; + + if ( myAlign & AlignTop ) + iy = y; + else if ( myAlign & AlignBottom ) + iy = y + ( h - ih - m ); + else if ( myAlign & AlignVCenter ) + iy = y + ( h - ih ) / 2; + + if ( !myIcon.isNull() ) + { + p->drawPixmap( ix, iy + ( ih - myIcon.pixmap().height() ) / 2, myIcon.pixmap() ); + ix += myIcon.pixmap().width() + s; + } + + p->setPen( cg.brightText() ); + p->drawText( ix, iy + ( ih - p->fontMetrics().height() ) / 2 + + p->fontMetrics().ascent(), myText, 0, -1 ); + + p->setFont( f ); +} + +QSize QtxPopupMenu::TitleMenuItem::sizeHint() +{ + QFontMetrics fM( myFont ); + + int m = 3; + int s = 3; + int w = fM.width( myText ) + ( myIcon.isNull() ? 0 : myIcon.pixmap().width() + s ); + int h = QMAX( ( myIcon.isNull() ? 0 : myIcon.pixmap().height() ), fM.height() ) + 2 * m; + + return QSize( w, h ); +} + +/*! + Class: QtxPopupMenu [Public] + Descr: Popup menu item with title. +*/ + +QtxPopupMenu::QtxPopupMenu( QWidget* parent, const char* name ) +: QPopupMenu( parent, name ), +myId( -1 ), +myPolicy( TitleAuto ), +myAlign( AlignCenter ) +{ +} + +QtxPopupMenu::~QtxPopupMenu() +{ +} + +QString QtxPopupMenu::titleText() const +{ + return myText; +} + +QIconSet QtxPopupMenu::titleIcon() const +{ + return myIcon; +} + +int QtxPopupMenu::titlePolicy() const +{ + return myPolicy; +} + +int QtxPopupMenu::titleAlignment() const +{ + return myAlign; +} + +void QtxPopupMenu::setTitleText( const QString& txt ) +{ + if ( myText == txt ) + return; + + myText = txt; + + updateTitle(); +} + +void QtxPopupMenu::setTitleIcon( const QIconSet& ico ) +{ + myIcon = ico; + + updateTitle(); +} + +void QtxPopupMenu::setTitlePolicy( const int p ) +{ + if ( myPolicy == p ) + return; + + myPolicy = p; + + updateTitle(); +} + +void QtxPopupMenu::setTitleAlignment( const int a ) +{ + if ( myAlign == a ) + return; + + myAlign = a; + + updateTitle(); +} + +void QtxPopupMenu::show() +{ + insertTitle(); + + QPopupMenu::show(); +} + +void QtxPopupMenu::hide() +{ + QPopupMenu::hide(); + + removeTitle(); +} + +QtxPopupMenu::TitleMenuItem* QtxPopupMenu::createTitleItem( const QString& txt, const QIconSet& ico, + const int align ) const +{ + return new TitleMenuItem( txt, ico, align ); +} + +void QtxPopupMenu::insertTitle() +{ + if ( myId != -1 || titlePolicy() == TitleOff || + ( titlePolicy() == TitleAuto && titleText().stripWhiteSpace().isEmpty() ) ) + return; + + TitleMenuItem* item = createTitleItem( titleText(), titleIcon(), titleAlignment() ); + + myId = insertItem( item, -1, 0 ); + setItemEnabled( myId, false ); +} + +void QtxPopupMenu::removeTitle() +{ + if ( myId == -1 ) + return; + + removeItem( myId ); + myId = -1; +} + +void QtxPopupMenu::updateTitle() +{ + if ( myId != -1 ) + { + removeTitle(); + insertTitle(); + } +} diff --git a/src/Qtx/QtxPopupMenu.h b/src/Qtx/QtxPopupMenu.h new file mode 100644 index 000000000..4774ef062 --- /dev/null +++ b/src/Qtx/QtxPopupMenu.h @@ -0,0 +1,74 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef QTXPOPUPMENU_H +#define QTXPOPUPMENU_H + +#include "Qtx.h" + +#include +#include +#include + +class QTX_EXPORT QtxPopupMenu : public QPopupMenu +{ + Q_OBJECT + +protected: + class TitleMenuItem; + +public: + enum { TitleAuto, TitleOn, TitleOff }; + +public: + QtxPopupMenu( QWidget* = 0, const char* = 0 ); + virtual ~QtxPopupMenu(); + + QString titleText() const; + QIconSet titleIcon() const; + + int titlePolicy() const; + int titleAlignment() const; + + virtual void setTitleText( const QString& ); + virtual void setTitleIcon( const QIconSet& ); + + virtual void setTitlePolicy( const int ); + virtual void setTitleAlignment( const int ); + +public slots: + virtual void show(); + virtual void hide(); + +protected: + virtual TitleMenuItem* createTitleItem( const QString&, const QIconSet&, const int ) const; + +private: + void updateTitle(); + void insertTitle(); + void removeTitle(); + +private: + int myId; + QString myText; + QIconSet myIcon; + int myAlign; + int myPolicy; +}; + +#endif diff --git a/src/Qtx/QtxResourceEdit.cxx b/src/Qtx/QtxResourceEdit.cxx new file mode 100644 index 000000000..e1c9e7538 --- /dev/null +++ b/src/Qtx/QtxResourceEdit.cxx @@ -0,0 +1,506 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxResourceEdit.cxx +// Author: Sergey TELKOV + +#include "QtxResourceEdit.h" + +#include "QtxResourceMgr.h" + +/* + Class: QtxResourceEdit + Descr: Class for managing preferences items +*/ + +QtxResourceEdit::QtxResourceEdit( QtxResourceMgr* mgr ) +: myResMgr( mgr ) +{ +} + +QtxResourceEdit::~QtxResourceEdit() +{ + for ( ItemMap::ConstIterator it = myItems.begin(); it != myItems.end(); ++it ) + delete it.data(); +} + +QtxResourceMgr* QtxResourceEdit::resourceMgr() const +{ + return myResMgr; +} + +int QtxResourceEdit::addItem( const QString& label, const int pId, const int type, + const QString& section, const QString& param ) +{ + Item* i = createItem( label, type, pId ); + if ( !i ) + return -1; + + if ( !myItems.contains( i->id() ) ) + { + myItems.insert( i->id(), i ); + + i->setTitle( label ); + i->setResource( section, param ); + + if ( !i->parentItem() && !myChildren.contains( i ) ) + myChildren.append( i ); + + itemAdded( i ); + } + + return i->id(); +} + +QVariant QtxResourceEdit::itemProperty( const int id, const QString& propName ) const +{ + QVariant propValue; + Item* i = item( id ); + if ( i ) + propValue = i->property( propName ); + return propValue; +} + +void QtxResourceEdit::setItemProperty( const int id, const QString& propName, const QVariant& propValue ) +{ + Item* i = item( id ); + if ( i ) + i->setProperty( propName, propValue ); +} + +void QtxResourceEdit::resource( const int id, QString& sec, QString& param ) const +{ + Item* i = item( id ); + if ( i ) + i->resource( sec, param ); +} + +void QtxResourceEdit::store() +{ + QMap before; + resourceValues( before ); + + for ( ItemMap::ConstIterator it = myItems.begin(); it != myItems.end(); ++it ) + it.data()->store(); + + QMap after; + resourceValues( after ); + + QMap changed; + differentValues( before, after, changed ); + + changedResources( changed ); +} + +void QtxResourceEdit::retrieve() +{ + for ( ItemMap::ConstIterator it = myItems.begin(); it != myItems.end(); ++it ) + it.data()->retrieve(); +} + +void QtxResourceEdit::toBackup() +{ + myBackup.clear(); + resourceValues( myBackup ); +} + +void QtxResourceEdit::fromBackup() +{ + QMap before; + resourceValues( before ); + + setResourceValues( myBackup ); + + QMap after; + resourceValues( after ); + + QMap changed; + differentValues( before, after, changed ); + + changedResources( changed ); +} + +void QtxResourceEdit::update() +{ +} + +QtxResourceEdit::Item* QtxResourceEdit::item( const int id ) const +{ + Item* i = 0; + if ( myItems.contains( id ) ) + i = myItems[id]; + return i; +} + +QtxResourceEdit::Item* QtxResourceEdit::item( const QString& title ) const +{ + Item* i = 0; + for ( ItemMap::ConstIterator it = myItems.begin(); it != myItems.end() && !i; ++it ) + { + if ( it.data()->title() == title ) + i = it.data(); + } + return i; +} + +QtxResourceEdit::Item* QtxResourceEdit::item( const QString& title, const int pId ) const +{ + Item* i = 0; + Item* pItem = item( pId ); + for ( ItemMap::ConstIterator it = myItems.begin(); it != myItems.end() && !i; ++it ) + { + if ( it.data()->parentItem() == pItem && it.data()->title() == title ) + i = it.data(); + } + return i; +} + +QtxResourceEdit::Item* QtxResourceEdit::createItem( const QString& label, const int type, const int pId ) +{ + Item* i = 0; + if ( pId < 0 ) + i = createItem( label, type ); + else + { + Item* pItem = item( pId ); + if ( pItem ) + { + i = pItem->createItem( label, type ); + pItem->insertChild( i ); + } + } + + return i; +} + +void QtxResourceEdit::removeItem( Item* item ) +{ + if ( !item ) + return; + + myChildren.remove( item ); + myItems.remove( item->id() ); + + itemRemoved( item ); +} + +void QtxResourceEdit::childItems( QPtrList& lst ) const +{ + lst.clear(); + for ( QPtrListIterator it( myChildren ); it.current(); ++it ) + lst.append( it.current() ); +} + +void QtxResourceEdit::resourceValues( QMap& map ) const +{ + QString sect, name; + for ( ItemMap::ConstIterator it = myItems.begin(); it != myItems.end(); ++it ) + { + it.data()->resource( sect, name ); + if( myResMgr->hasValue( sect, name ) ) + map.insert( it.key(), it.data()->resourceValue() ); + } +} + +void QtxResourceEdit::resourceValues( QMap& map ) const +{ + QString sect, name; + for ( ItemMap::ConstIterator it = myItems.begin(); it != myItems.end(); ++it ) + { + it.data()->resource( sect, name ); + if( myResMgr->hasValue( sect, name ) ) + map.insert( it.data(), it.data()->resourceValue() ); + } +} + +void QtxResourceEdit::setResourceValues( QMap& map ) const +{ + for ( QMap::ConstIterator it = map.begin(); it != map.end(); ++it ) + { + Item* i = item( it.key() ); + if ( i ) + i->setResourceValue( it.data() ); + } +} + +void QtxResourceEdit::setResourceValues( QMap& map ) const +{ + for ( QMap::ConstIterator it = map.begin(); it != map.end(); ++it ) + it.key()->setResourceValue( it.data() ); +} + + +void QtxResourceEdit::differentValues( const QMap& map1, const QMap& map2, + QMap& resMap, const bool fromFirst ) const +{ + resMap.clear(); + const QMap& later = fromFirst ? map1 : map2; + const QMap& early = fromFirst ? map2 : map1; + + for ( QMap::ConstIterator it = later.begin(); it != later.end(); ++it ) + { + if ( !early.contains( it.key() ) || early[it.key()] != it.data() ) + resMap.insert( it.key(), it.data() ); + } +} + +void QtxResourceEdit::differentValues( const QMap& map1, const QMap& map2, + QMap& resMap, const bool fromFirst ) const +{ + resMap.clear(); + const QMap& later = fromFirst ? map1 : map2; + const QMap& early = fromFirst ? map2 : map1; + + for ( QMap::ConstIterator it = later.begin(); it != later.end(); ++it ) + { + if ( !early.contains( it.key() ) || early[it.key()] != it.data() ) + resMap.insert( it.key(), it.data() ); + } +} + +void QtxResourceEdit::changedResources( const QMap& ) +{ +} + +void QtxResourceEdit::itemAdded( Item* ) +{ +} + +void QtxResourceEdit::itemRemoved( Item* ) +{ +} + +/* + Class: QtxResourceEdit::Item + Descr: Class for incapsulation of one preference item +*/ + +QtxResourceEdit::Item::Item( QtxResourceEdit* edit, Item* parent ) +: myEdit( edit ), +myParent( 0 ) +{ + myId = generateId(); + + if ( parent ) + parent->insertChild( this ); +} + +QtxResourceEdit::Item::~Item() +{ + if ( resourceEdit() ) + resourceEdit()->removeItem( this ); +} + +int QtxResourceEdit::Item::id() const +{ + return myId; +} + +QtxResourceEdit::Item* QtxResourceEdit::Item::parentItem() const +{ + return myParent; +} + +void QtxResourceEdit::Item::insertChild( Item* item ) +{ + if ( !item || myChildren.contains( item ) ) + return; + + if ( item->parentItem() && item->parentItem() != this ) + item->parentItem()->removeChild( item ); + + item->myParent = this; + myChildren.append( item ); +} + +void QtxResourceEdit::Item::removeChild( Item* item ) +{ + if ( !item || !myChildren.contains( item ) ) + return; + + myChildren.remove( item ); + item->myParent = 0; +} + +void QtxResourceEdit::Item::childItems( QPtrList& lst ) const +{ + for ( ItemListIterator it( myChildren ); it.current(); ++it ) + lst.append( it.current() ); +} + +bool QtxResourceEdit::Item::isEmpty() const +{ + return myChildren.isEmpty(); +} + +QString QtxResourceEdit::Item::title() const +{ + return myTitle; +} + +void QtxResourceEdit::Item::resource( QString& sec, QString& param ) const +{ + sec = myResSection; + param = myResParameter; +} + +void QtxResourceEdit::Item::setTitle( const QString& title ) +{ + myTitle = title; +} + +void QtxResourceEdit::Item::setResource( const QString& sec, const QString& param ) +{ + myResSection = sec; + myResParameter = param; +} + +void QtxResourceEdit::Item::update() +{ +} + +QVariant QtxResourceEdit::Item::property( const QString& ) const +{ + return QVariant(); +} + +void QtxResourceEdit::Item::setProperty( const QString&, const QVariant& ) +{ +} + +QString QtxResourceEdit::Item::resourceValue() const +{ + return getString(); +} + +void QtxResourceEdit::Item::setResourceValue( const QString& val ) +{ + setString( val ); +} + +QtxResourceMgr* QtxResourceEdit::Item::resourceMgr() const +{ + QtxResourceMgr* resMgr = 0; + if ( resourceEdit() ) + resMgr = resourceEdit()->resourceMgr(); + return resMgr; +} + +QtxResourceEdit* QtxResourceEdit::Item::resourceEdit() const +{ + return myEdit; +} + +int QtxResourceEdit::Item::getInteger( const int val ) const +{ + QtxResourceMgr* resMgr = resourceMgr(); + return resMgr ? resMgr->integerValue( myResSection, myResParameter, val ) : val; +} + +double QtxResourceEdit::Item::getDouble( const double val ) const +{ + QtxResourceMgr* resMgr = resourceMgr(); + return resMgr ? resMgr->doubleValue( myResSection, myResParameter, val ) : val; +} + +bool QtxResourceEdit::Item::getBoolean( const bool val ) const +{ + QtxResourceMgr* resMgr = resourceMgr(); + return resMgr ? resMgr->booleanValue( myResSection, myResParameter, val ) : val; +} + +QString QtxResourceEdit::Item::getString( const QString& val ) const +{ + QtxResourceMgr* resMgr = resourceMgr(); + return resMgr ? resMgr->stringValue( myResSection, myResParameter, val ) : val; +} + +QColor QtxResourceEdit::Item::getColor( const QColor& val ) const +{ + QtxResourceMgr* resMgr = resourceMgr(); + return resMgr ? resMgr->colorValue( myResSection, myResParameter, val ) : val; +} + +QFont QtxResourceEdit::Item::getFont( const QFont& val ) const +{ + QtxResourceMgr* resMgr = resourceMgr(); + return resMgr ? resMgr->fontValue( myResSection, myResParameter, val ) : val; +} + +void QtxResourceEdit::Item::setInteger( const int val ) +{ + QtxResourceMgr* resMgr = resourceMgr(); + if ( resMgr ) + resMgr->setValue( myResSection, myResParameter, val ); +} + +void QtxResourceEdit::Item::setDouble( const double val ) +{ + QtxResourceMgr* resMgr = resourceMgr(); + if ( resMgr ) + resMgr->setValue( myResSection, myResParameter, val ); +} + +void QtxResourceEdit::Item::setBoolean( const bool val ) +{ + QtxResourceMgr* resMgr = resourceMgr(); + if ( resMgr ) + resMgr->setValue( myResSection, myResParameter, val ); +} + +void QtxResourceEdit::Item::setString( const QString& val ) +{ + QtxResourceMgr* resMgr = resourceMgr(); + if ( resMgr ) + resMgr->setValue( myResSection, myResParameter, val ); +} + +void QtxResourceEdit::Item::setColor( const QColor& val ) +{ + QtxResourceMgr* resMgr = resourceMgr(); + if ( resMgr ) + resMgr->setValue( myResSection, myResParameter, val ); +} + +void QtxResourceEdit::Item::setFont( const QFont& val ) +{ + QtxResourceMgr* resMgr = resourceMgr(); + if ( resMgr ) + resMgr->setValue( myResSection, myResParameter, val ); +} + +QtxResourceEdit::Item* QtxResourceEdit::Item::item( const int id ) const +{ + return resourceEdit() ? resourceEdit()->item( id ) : 0; +} + +QtxResourceEdit::Item* QtxResourceEdit::Item::item( const QString& title ) const +{ + return resourceEdit() ? resourceEdit()->item( title ) : 0; +} + +QtxResourceEdit::Item* QtxResourceEdit::Item::item( const QString& title, const int id ) const +{ + return resourceEdit() ? resourceEdit()->item( title, id ) : 0; +} + +int QtxResourceEdit::Item::generateId() +{ + static int _id = 0; + return _id++; +} diff --git a/src/Qtx/QtxResourceEdit.h b/src/Qtx/QtxResourceEdit.h new file mode 100644 index 000000000..7c55abc7b --- /dev/null +++ b/src/Qtx/QtxResourceEdit.h @@ -0,0 +1,193 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxResourceEdit.h +// Author: Sergey TELKOV + +#ifndef QTXRESOURCEEDIT_H +#define QTXRESOURCEEDIT_H + +#ifdef WIN32 +#pragma warning( disable:4251 ) +#endif + +#include "Qtx.h" + +class QString; +class QtxResourceMgr; + +#include +#include +#include + +class QTX_EXPORT QtxResourceEdit +{ +public: + class Item; + +public: + QtxResourceEdit( QtxResourceMgr* ); + virtual ~QtxResourceEdit(); + + QtxResourceMgr* resourceMgr() const; + + virtual int addItem( const QString& label, const int pId = -1, const int = -1, + const QString& section = QString::null, + const QString& param = QString::null ); + + QVariant itemProperty( const int, const QString& ) const; + virtual void setItemProperty( const int, const QString&, const QVariant& ); + + void resource( const int, QString&, QString& ) const; + + virtual void store(); + virtual void retrieve(); + + virtual void update(); + + virtual void toBackup(); + virtual void fromBackup(); + +protected: + Item* item( const int ) const; + Item* item( const QString& ) const; + Item* item( const QString&, const int ) const; + + virtual Item* createItem( const QString&, const int ) = 0; + + void resourceValues( QMap& ) const; + void resourceValues( QMap& ) const; + + void setResourceValues( QMap& ) const; + void setResourceValues( QMap& ) const; + + void differentValues( const QMap&, const QMap&, + QMap&, const bool fromFirst = false ) const; + void differentValues( const QMap&, const QMap&, + QMap&, const bool fromFirst = false ) const; + + virtual void changedResources( const QMap& ); + + virtual void itemAdded( Item* ); + virtual void itemRemoved( Item* ); + + void childItems( QPtrList& ) const; + +private: + void removeItem( Item* ); + Item* createItem( const QString&, const int, const int ); + +private: + typedef QMap ItemMap; + +private: + ItemMap myItems; + QtxResourceMgr* myResMgr; + QMap myBackup; + QPtrList myChildren; + + friend class QtxResourceEdit::Item; +}; + +/* + Class: QtxResourceEditor::Item + Descr: Class for incapsulation of one preference item +*/ + +class QTX_EXPORT QtxResourceEdit::Item +{ +public: + Item( QtxResourceEdit*, Item* = 0 ); + virtual ~Item(); + + int id() const; + virtual int type() const = 0; + + Item* parentItem() const; + void childItems( QPtrList& ) const; + + virtual bool isEmpty() const; + + QString title() const; + void resource( QString&, QString& ) const; + + virtual void setTitle( const QString& ); + virtual void setResource( const QString&, const QString& ); + + virtual void update(); + + QVariant property( const QString& ) const; + virtual void setProperty( const QString&, const QVariant& ); + + virtual void store() = 0; + virtual void retrieve() = 0; + + virtual Item* createItem( const QString&, const int ) = 0; + + QString resourceValue() const; + void setResourceValue( const QString& ); + + virtual void insertChild( Item* ); + virtual void removeChild( Item* ); + +protected: + QtxResourceMgr* resourceMgr() const; + QtxResourceEdit* resourceEdit() const; + + int getInteger( const int = 0 ) const; + double getDouble( const double = 0.0 ) const; + bool getBoolean( const bool = false ) const; + QColor getColor( const QColor& = QColor() ) const; + QFont getFont( const QFont& = QFont() ) const; + QString getString( const QString& = QString::null ) const; + + void setInteger( const int ); + void setDouble( const double ); + void setBoolean( const bool ); + void setColor( const QColor& ); + void setFont( const QFont& ); + void setString( const QString& ); + + Item* item( const int ) const; + Item* item( const QString& ) const; + Item* item( const QString&, const int ) const; + +protected: + typedef QPtrList ItemList; + typedef QPtrListIterator ItemListIterator; + +private: + static int generateId(); + +private: + int myId; + Item* myParent; + ItemList myChildren; + + QString myTitle; + QString myResSection; + QString myResParameter; + + QtxResourceEdit* myEdit; +}; + +#ifdef WIN32 +#pragma warning( default:4251 ) +#endif + +#endif diff --git a/src/Qtx/QtxResourceMgr.cxx b/src/Qtx/QtxResourceMgr.cxx new file mode 100644 index 000000000..29e178a19 --- /dev/null +++ b/src/Qtx/QtxResourceMgr.cxx @@ -0,0 +1,1609 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "QtxResourceMgr.h" + +#include +#include +#include +#include +#include +#include + +#ifndef QT_NO_DOM +#include +#endif + +#include + +/*! + Class: QtxResourceMgr::Resources + Level: Internal +*/ + +QtxResourceMgr::Resources::Resources( const QString& fileName ) +: myFileName( fileName ) +{ +} + +QtxResourceMgr::Resources::~Resources() +{ +} + +QString QtxResourceMgr::Resources::file() const +{ + return myFileName; +} + +void QtxResourceMgr::Resources::setFile( const QString& fn ) +{ + myFileName = fn; +} + +QString QtxResourceMgr::Resources::value( const QString& sect, const QString& name, const bool subst ) const +{ + QString val; + + if ( hasValue( sect, name ) ) + { + val = section( sect )[name]; + if ( subst ) + val = makeSubstitution( val, sect, name ); + } + return val; +} + +void QtxResourceMgr::Resources::setValue( const QString& sect, const QString& name, const QString& val ) +{ + Section& s = section( sect ); + s.insert( name, val ); +} + +bool QtxResourceMgr::Resources::hasSection( const QString& sect ) const +{ + return mySections.contains( sect ); +} + +bool QtxResourceMgr::Resources::hasValue( const QString& sect, const QString& name ) const +{ + return hasSection( sect ) && section( sect ).contains( name ); +} + +void QtxResourceMgr::Resources::removeSection( const QString& sect ) +{ + mySections.remove( sect ); +} + +void QtxResourceMgr::Resources::removeValue( const QString& sect, const QString& name ) +{ + if ( !hasSection( sect ) ) + return; + + Section& s = section( sect ); + s.remove( name ); + + if ( s.isEmpty() ) + mySections.remove( sect ); +} + +void QtxResourceMgr::Resources::clear() +{ + mySections.clear(); +} + +QStringList QtxResourceMgr::Resources::sections() const +{ + return mySections.keys(); +} + +QStringList QtxResourceMgr::Resources::parameters( const QString& sec ) const +{ + if ( !hasSection( sec ) ) + return QStringList(); + + return section( sec ).keys(); +} + +QString QtxResourceMgr::Resources::path( const QString& sec, const QString& prefix, const QString& name ) const +{ + QString filePath = fileName( sec, prefix, name ); + if ( !filePath.isEmpty() ) + { + if ( !QFileInfo( filePath ).exists() ) + filePath = QString::null; + } + return filePath; +} + +QtxResourceMgr::Section& QtxResourceMgr::Resources::section( const QString& sn ) +{ + if ( !mySections.contains( sn ) ) + mySections.insert( sn, Section() ); + + return mySections[sn]; +} + +const QtxResourceMgr::Section& QtxResourceMgr::Resources::section( const QString& sn ) const +{ + return mySections[sn]; +} + +QString QtxResourceMgr::Resources::fileName( const QString& sect, const QString& prefix, const QString& name ) const +{ + QString path; + if ( hasValue( sect, prefix ) ) + { + path = value( sect, prefix, true ); + if ( !path.isEmpty() ) + { + if ( QFileInfo( path ).isRelative() ) + path = Qtx::addSlash( QFileInfo( myFileName ).dirPath( true ) ) + path; + + path = Qtx::addSlash( path ) + name; + } + } + return QDir::convertSeparators( path ); +} + +QPixmap QtxResourceMgr::Resources::loadPixmap( const QString& sect, const QString& prefix, const QString& name ) const +{ + return QPixmap( fileName( sect, prefix, name ) ); +} + +QTranslator* QtxResourceMgr::Resources::loadTranslator( const QString& sect, const QString& prefix, const QString& name ) const +{ + QTranslator* trans = new QTranslator( 0 ); + if ( !trans->load( fileName( sect, prefix, name ) ) ) + { + delete trans; + trans = 0; + } + return trans; +} + +QString QtxResourceMgr::Resources::environmentVariable( const QString& str, int& start, int& len ) const +{ + QString varName = QString::null; + len = 0; + + QRegExp rx( "\\$\\{([a-zA-Z]+[a-zA-Z0-9_]*)\\}|\\$\\(([a-zA-Z]+[a-zA-Z0-9_]*)\\)|\\$([a-zA-Z]+[a-zA-Z0-9_]*)|\\%([a-zA-Z]+[a-zA-Z0-9_]*)\\%" ); + + int pos = rx.search( str, start ); + if ( pos != -1 ) + { + start = pos; + len = rx.matchedLength(); + QStringList caps = rx.capturedTexts(); + for ( uint i = 1; i <= caps.count() && varName.isEmpty(); i++ ) + varName = *caps.at( i ); + } + return varName; +} + +QString QtxResourceMgr::Resources::makeSubstitution( const QString& str, const QString& sect, const QString& name ) const +{ + QString res = str; + + QMap ignoreMap; + ignoreMap.insert( name, 0 ); + + int start( 0 ), len( 0 ); + while ( true ) + { + QString envName = environmentVariable( res, start, len ); + if ( envName.isNull() ) + break; + + QString newStr = QString::null; + if ( ::getenv( envName ) ) + newStr = QString( ::getenv( envName ) ); + + if ( newStr.isNull() ) + { + if ( ignoreMap.contains( envName ) ) + { + start += len; + continue; + } + + if ( hasValue( sect, envName ) ) + newStr = value( sect, envName, false ); + ignoreMap.insert( envName, 0 ); + } + res.replace( start, len, newStr ); + } + + return res; +} + +/*! + Class: QtxResourceMgr::IniFormat + Level: Internal +*/ + +class QtxResourceMgr::IniFormat : public Format +{ +public: + IniFormat(); + ~IniFormat(); + +protected: + virtual bool load( const QString&, QMap& ); + virtual bool save( const QString&, const QMap& ); +}; + +QtxResourceMgr::IniFormat::IniFormat() +: Format( "ini" ) +{ +} + +QtxResourceMgr::IniFormat::~IniFormat() +{ +} + +bool QtxResourceMgr::IniFormat::load( const QString& fname, QMap& secMap ) +{ + QFile file( fname ); + if ( !file.open( IO_ReadOnly ) ) + return false; + + QTextStream ts( &file ); + + QString data; + int line = 0; + bool res = true; + QString section; + + QString separator = option( "separator" ); + if ( separator.isNull() ) + separator = QString( "=" ); + + QString comment = option( "comment" ); + if ( comment.isNull() ) + comment = QString( "#" ); + + while ( true ) + { + data = ts.readLine(); + line++; + + if ( data.isNull() ) + break; + + data = data.stripWhiteSpace(); + if ( data.isEmpty() ) + continue; + + if ( data.startsWith( comment ) ) + continue; + + QRegExp rx( "^\\[([\\w\\s\\._]*)\\]$" ); + if ( rx.search( data ) != -1 ) + { + section = rx.cap( 1 ); + if ( section.isEmpty() ) + { + res = false; + qWarning( QString( "Empty section in line %1" ).arg( line ) ); + } + } + else if ( data.contains( "=" ) && !section.isEmpty() ) + { + int pos = data.find( separator ); + QString key = data.left( pos ).stripWhiteSpace(); + QString val = data.mid( pos + 1 ).stripWhiteSpace(); + secMap[section].insert( key, val ); + } + else + { + res = false; + section.isEmpty() ? qWarning( "Current section is empty" ) : + qWarning( QString( "Error in line: %1" ).arg( line ) ); + } + } + + file.close(); + + return res; +} + +bool QtxResourceMgr::IniFormat::save( const QString& fname, const QMap& secMap ) +{ + QFile file( fname ); + if ( !file.open( IO_WriteOnly ) ) + return false; + + bool res = true; + for ( QMap::ConstIterator it = secMap.begin(); it != secMap.end() && res; ++it ) + { + QString data = QString( "[%1]\n" ).arg( it.key() ); + for ( Section::ConstIterator iter = it.data().begin(); iter != it.data().end(); ++iter ) + data += iter.key() + " = " + iter.data() + "\n"; + data += "\n"; + + res = file.writeBlock( data.latin1(), data.length() ) == (int)data.length(); + } + + file.close(); + + return res; +} + +/*! + Class: QtxResourceMgr::XmlFormat + Level: Internal +*/ + +class QtxResourceMgr::XmlFormat : public Format +{ +public: + XmlFormat(); + ~XmlFormat(); + +protected: + virtual bool load( const QString&, QMap& ); + virtual bool save( const QString&, const QMap& ); + +private: + QString docTag() const; + QString sectionTag() const; + QString parameterTag() const; + QString nameAttribute() const; + QString valueAttribute() const; +}; + +QtxResourceMgr::XmlFormat::XmlFormat() +: Format( "xml" ) +{ +} + +QtxResourceMgr::XmlFormat::~XmlFormat() +{ +} + +bool QtxResourceMgr::XmlFormat::load( const QString& fname, QMap& secMap ) +{ + bool res = false; + +#ifndef QT_NO_DOM + + QFile file( fname ); + if ( !file.open( IO_ReadOnly ) ) + return false; + + QDomDocument doc; + + res = doc.setContent( &file ); + file.close(); + + if ( !res ) + return false; + + QDomElement root = doc.documentElement(); + if ( root.isNull() || root.tagName() != docTag() ) + return false; + + QDomNode sectNode = root.firstChild(); + while ( res && !sectNode.isNull() ) + { + res = sectNode.isElement(); + if ( res ) + { + QDomElement sectElem = sectNode.toElement(); + if ( sectElem.tagName() == sectionTag() && sectElem.hasAttribute( nameAttribute() ) ) + { + QString section = sectElem.attribute( nameAttribute() ); + QDomNode paramNode = sectNode.firstChild(); + while ( res && !paramNode.isNull() ) + { + res = paramNode.isElement(); + if ( res ) + { + QDomElement paramElem = paramNode.toElement(); + if ( paramElem.tagName() == parameterTag() && + paramElem.hasAttribute( nameAttribute() ) && paramElem.hasAttribute( valueAttribute() ) ) + { + QString paramName = paramElem.attribute( nameAttribute() ); + QString paramValue = paramElem.attribute( valueAttribute() ); + + secMap[section].insert( paramName, paramValue ); + } + else + res = false; + } + else + res = paramNode.isComment(); + + paramNode = paramNode.nextSibling(); + } + } + else + res = false; + } + else + res = sectNode.isComment(); // if it's a comment -- let it be, pass it.. + + sectNode = sectNode.nextSibling(); + } + +#endif + + return res; +} + +bool QtxResourceMgr::XmlFormat::save( const QString& fname, const QMap& secMap ) +{ + bool res = false; + +#ifndef QT_NO_DOM + + QFile file( fname ); + if ( !file.open( IO_WriteOnly ) ) + return false; + + QDomDocument doc( docTag() ); + QDomElement root = doc.createElement( docTag() ); + doc.appendChild( root ); + + for ( QMap::ConstIterator it = secMap.begin(); it != secMap.end(); ++it ) + { + QDomElement sect = doc.createElement( sectionTag() ); + sect.setAttribute( nameAttribute(), it.key() ); + root.appendChild( sect ); + for ( Section::ConstIterator iter = it.data().begin(); iter != it.data().end(); ++iter ) + { + QDomElement val = doc.createElement( parameterTag() ); + val.setAttribute( nameAttribute(), iter.key() ); + val.setAttribute( valueAttribute(), iter.data() ); + sect.appendChild( val ); + } + } + + QString docStr = doc.toString(); + res = file.writeBlock( docStr.latin1(), docStr.length() ) == (int)docStr.length(); + file.close(); + +#endif + + return res; +} + +QString QtxResourceMgr::XmlFormat::docTag() const +{ + QString tag = option( "doc_tag" ); + if ( tag.isEmpty() ) + tag = QString( "document" ); + return tag; +} + +QString QtxResourceMgr::XmlFormat::sectionTag() const +{ + QString tag = option( "section_tag" ); + if ( tag.isEmpty() ) + tag = QString( "section" ); + return tag; +} + +QString QtxResourceMgr::XmlFormat::parameterTag() const +{ + QString tag = option( "parameter_tag" ); + if ( tag.isEmpty() ) + tag = QString( "parameter" ); + return tag; +} + +QString QtxResourceMgr::XmlFormat::nameAttribute() const +{ + QString str = option( "name_attribute" ); + if ( str.isEmpty() ) + str = QString( "name" ); + return str; +} + +QString QtxResourceMgr::XmlFormat::valueAttribute() const +{ + QString str = option( "value_attribute" ); + if ( str.isEmpty() ) + str = QString( "value" ); + return str; +} + +/*! + Class: QtxResourceMgr::Format + Level: Public +*/ + +/*! + \brief Constructs the format object with specified name. + \param fmt - name of the format +*/ +QtxResourceMgr::Format::Format( const QString& fmt ) +: myFmt( fmt ) +{ +} + +/*! + \brief Destructs the format object. +*/ +QtxResourceMgr::Format::~Format() +{ +} + +/*! + \brief Returns the format name. +*/ +QString QtxResourceMgr::Format::format() const +{ + return myFmt; +} + +/*! + \brief Returns the string list of the format options. +*/ +QStringList QtxResourceMgr::Format::options() const +{ + return myOpt.keys(); +} + +/*! + \brief Returns the value of the option with specified name. + If option doesn't exist then empty string returned. + \param opt - name of the option +*/ +QString QtxResourceMgr::Format::option( const QString& opt ) const +{ + QString val; + if ( myOpt.contains( opt ) ) + val = myOpt[opt]; + return val; +} + +/*! + \brief Sets the value of the option with specified name. + \param opt - name of the option + \param opt - value of the option +*/ +void QtxResourceMgr::Format::setOption( const QString& opt, const QString& val ) +{ + myOpt.insert( opt, val ); +} + +/*! + \brief Perform the loading of the resources from resource file. + \param res - resources object which will be loaded +*/ +bool QtxResourceMgr::Format::load( Resources* res ) +{ + if ( !res ) + return false; + + QMap sections; + bool status = load( res->myFileName, sections ); + if ( status ) + res->mySections = sections; + else + qDebug( "QtxResourceMgr: Could not load resource file \"%s\"", res->myFileName.latin1() ); + + return status; +} + +/*! + \brief Perform the saving of the resources into resource file. + \param res - resources object which will be saved +*/ +bool QtxResourceMgr::Format::save( Resources* res ) +{ + if ( !res ) + return false; + + Qtx::mkDir( Qtx::dir( res->myFileName ) ); + + return save( res->myFileName, res->mySections ); +} + +/*! + Class: QtxResourceMgr + Level: Public +*/ + +/*! + \brief Constructs the resource manager object for application. + \param appName - name of the application which resources will be used. + \param resVarTemplate - template for the resource environment variable name which + should point to the resource directory list. + Default value is "%1Resources". Its mean that for application + with name "MyApp" environment variable "MyAppResources" will + be used. Template may not have the parameter '%1' substituted + by application name. In this case this string will be used as + is without substitution. + Resource environment variable should contains one or several resource directories + separated by symbol ';'. Resource directories list transfered into the setDirList(). + These directories and the user home directory used for the loading application resources. + Each of the resource directories can contains resource file. The name of this file defined + by the function globalFileName(). Resource file name in the user home defined by the + function userFileName(). Any resource looking firstly in the user home resources then + resource directories used in the specified order. All setted resources always stored into + the resource file at the user home. Only user home resource file is saved. +*/ +QtxResourceMgr::QtxResourceMgr( const QString& appName, const QString& resVarTemplate ) +: myAppName( appName ), +myCheckExist( true ) +{ + QString envVar = !resVarTemplate.isEmpty() ? resVarTemplate : QString( "%1Resources" ); + if ( envVar.contains( "%1" ) ) + envVar = envVar.arg( appName ); + + QString dirs; + if ( ::getenv( envVar ) ) + dirs = ::getenv( envVar ); +#ifdef WNT + QString dirsep = ";"; // for Windows: ";" is used as directories separator +#else + QString dirsep = "[:|;]"; // for Linux: both ":" and ";" can be used +#endif + setDirList( QStringList::split( QRegExp(dirsep), dirs ) ); + + installFormat( new XmlFormat() ); + installFormat( new IniFormat() ); + + setOption( "translators", QString( "%P_msg_%L.qm|%P_images.qm" ) ); +} + +/*! + \brief Destructs the resource manager object and free allocated memory. +*/ +QtxResourceMgr::~QtxResourceMgr() +{ + QStringList prefList = myTranslator.keys(); + for ( QStringList::const_iterator it = prefList.begin(); it != prefList.end(); ++it ) + removeTranslators( *it ); +} + +/*! + \brief Returns the application name. +*/ +QString QtxResourceMgr::appName() const +{ + return myAppName; +} + +/*! + \brief Returns the checking of the existance flag. If its 'true' then resource + will be setted into the manager only if it doesn't exist or has different + value that existing value. +*/ +bool QtxResourceMgr::checkExisting() const +{ + return myCheckExist; +} + +/*! + \brief Sets the checking of the existance flag. + \param on - boolean value of the flag. +*/ +void QtxResourceMgr::setCheckExisting( const bool on ) +{ + myCheckExist = on; +} + +/*! + \brief Returns the resource directories list except user home directory. +*/ +QStringList QtxResourceMgr::dirList() const +{ + return myDirList; +} + +/*! + \brief Initialise the manager. Prepare the resource containers and load resources. + \param autoLoad - if 'true' then all resources will be loaded. +*/ +void QtxResourceMgr::initialize( const bool autoLoad ) const +{ + if ( !myResources.isEmpty() ) + return; + + QtxResourceMgr* that = (QtxResourceMgr*)this; + + if ( !userFileName( appName() ).isEmpty() ) + that->myResources.append( new Resources( userFileName( appName() ) ) ); + + for ( QStringList::const_iterator it = myDirList.begin(); it != myDirList.end(); ++it ) + { + QString path = Qtx::addSlash( *it ) + globalFileName( appName() ); + that->myResources.append( new Resources( path ) ); + } + + if ( autoLoad ) + that->load(); +} + +/*! + \brief Removes all resources from the manager. +*/ +void QtxResourceMgr::clear() +{ + for ( ResListIterator it( myResources ); it.current(); ++it ) + it.current()->clear(); +} + +/*! + \brief Get the resource value as integer. Returns 'true' if it successfull otherwise + returns 'false'. + \param sect - Resource section name which contains resource. + \param name - Name of the resource. + \param iVal - Reference on the variable which should contains the resource output. +*/ +bool QtxResourceMgr::value( const QString& sect, const QString& name, int& iVal ) const +{ + QString val; + if ( !value( sect, name, val, true ) ) + return false; + + bool ok; + iVal = val.toInt( &ok ); + + return ok; +} + +/*! + \brief Get the resource value as double. Returns 'true' if it successfull otherwise + returns 'false'. + \param sect - Resource section name which contains resource. + \param name - Name of the resource. + \param dVal - Reference on the variable which should contains the resource output. +*/ +bool QtxResourceMgr::value( const QString& sect, const QString& name, double& dVal ) const +{ + QString val; + if ( !value( sect, name, val, true ) ) + return false; + + bool ok; + dVal = val.toDouble( &ok ); + + return ok; +} + +/*! + \brief Get the resource value as boolean. Returns 'true' if it successfull otherwise + returns 'false'. + \param sect - Resource section name which contains resource. + \param name - Name of the resource. + \param bVal - Reference on the variable which should contains the resource output. +*/ +bool QtxResourceMgr::value( const QString& sect, const QString& name, bool& bVal ) const +{ + QString val; + if ( !value( sect, name, val, true ) ) + return false; + + static QMap boolMap; + if ( boolMap.isEmpty() ) + { + boolMap["true"] = boolMap["yes"] = boolMap["on"] = true; + boolMap["false"] = boolMap["no"] = boolMap["off"] = false; + } + + val = val.lower(); + bool res = boolMap.contains( val ); + if ( res ) + bVal = boolMap[val]; + else + { + double num = val.toDouble( &res ); + if ( res ) + bVal = num != 0; + } + + return res; +} + +/*! + \brief Get the resource value as color. Returns 'true' if it successfull otherwise + returns 'false'. + \param sect - Resource section name which contains resource. + \param name - Name of the resource. + \param cVal - Reference on the variable which should contains the resource output. +*/ +bool QtxResourceMgr::value( const QString& sect, const QString& name, QColor& cVal ) const +{ + QString val; + if ( !value( sect, name, val, true ) ) + return false; + + bool res = true; + QStringList vals = QStringList::split( ",", val, true ); + + QIntList nums; + for ( QStringList::const_iterator it = vals.begin(); it != vals.end() && res; ++it ) + nums.append( (*it).toInt( &res ) ); + + if ( res && nums.count() >= 3 ) + cVal.setRgb( nums[0], nums[1], nums[2] ); + else + { + int pack = val.toInt( &res ); + if ( res ) + Qtx::rgbSet( pack, cVal ); + } + + return res; +} + +/*! + \brief Get the resource value as font. Returns 'true' if it successfull otherwise + returns 'false'. + \param sect - Resource section name which contains resource. + \param name - Name of the resource. + \param fVal - Reference on the variable which should contains the resource output. +*/ +bool QtxResourceMgr::value( const QString& sect, const QString& name, QFont& fVal ) const +{ + QString val; + if ( !value( sect, name, val, true ) ) + return false; + + QStringList fontDescr = QStringList::split( ",", val ); + + if ( fontDescr.count() < 2 ) + return false; + + QString family = fontDescr[0]; + if ( family.isEmpty() ) + return false; + + fVal = QFont( family ); + + for ( int i = 1; i < (int)fontDescr.count(); i++ ) + { + QString curval = fontDescr[i].stripWhiteSpace().lower(); + if ( curval == QString( "bold" ) ) + fVal.setBold( true ); + else if ( curval == QString( "italic" ) ) + fVal.setItalic( true ); + else if ( curval == QString( "underline" ) ) + fVal.setUnderline( true ); + else + { + bool isOk = false; + int ps = curval.toInt( &isOk ); + if ( isOk ) + fVal.setPointSize( ps ); + } + } + + return true; +} + +/*! + \brief Get the resource value as string (native format). Returns 'true' if it + successfull otherwise returns 'false'. + \param sect - Resource section name which contains resource. + \param name - Name of the resource. + \param val - Reference on the variable which should contains the resource output. + \param subst - If 'true' then manager substitute reference on environment variables + and other resources by thier values. Default value of this parameter + is 'true' +*/ +bool QtxResourceMgr::value( const QString& sect, const QString& name, QString& val, const bool subst ) const +{ + initialize(); + + bool ok = false; + for ( ResListIterator it( myResources ); it.current() && !ok; ++it ) + { + ok = it.current()->hasValue( sect, name ); + if ( ok ) + val = it.current()->value( sect, name, subst ); + } + + return ok; +} + +/*! + \brief Returns the integer resource value. If resource can not be found or converted + then specified default value will be returned. + \param sect - Resource section name which contains resource. + \param name - Name of the resource. + \param def - Default resource value which will be used when resource not found. +*/ +int QtxResourceMgr::integerValue( const QString& sect, const QString& name, const int def ) const +{ + int val; + if ( !value( sect, name, val ) ) + val = def; + return val; +} + +/*! + \brief Returns the double resource value. If resource can not be found or converted + then specified default value will be returned. + \param sect - Resource section name which contains resource. + \param name - Name of the resource. + \param def - Default resource value which will be used when resource not found. +*/ +double QtxResourceMgr::doubleValue( const QString& sect, const QString& name, const double def ) const +{ + double val; + if ( !value( sect, name, val ) ) + val = def; + return val; +} + +/*! + \brief Returns the boolean resource value. If resource can not be found or converted + then specified default value will be returned. + \param sect - Resource section name which contains resource. + \param name - Name of the resource. + \param def - Default resource value which will be used when resource not found. +*/ +bool QtxResourceMgr::booleanValue( const QString& sect, const QString& name, const bool def ) const +{ + bool val; + if ( !value( sect, name, val ) ) + val = def; + return val; +} + +/*! + \brief Returns the font resource value. If resource can not be found or converted + then specified default value will be returned. + \param sect - Resource section name which contains resource. + \param name - Name of the resource. + \param def - Default resource value which will be used when resource not found. +*/ +QFont QtxResourceMgr::fontValue( const QString& sect, const QString& name, const QFont& def ) const +{ + QFont font; + if( !value( sect, name, font ) ) + font = def; + return font; +} + +/*! + \brief Returns the color resource value. If resource can not be found or converted + then specified default value will be returned. + \param sect - Resource section name which contains resource. + \param name - Name of the resource. + \param def - Default resource value which will be used when resource not found. +*/ +QColor QtxResourceMgr::colorValue( const QString& sect, const QString& name, const QColor& def ) const +{ + QColor val; + if ( !value( sect, name, val ) ) + val = def; + return val; +} + +/*! + \brief Returns the string resource value. If resource can not be found or converted + then specified default value will be returned. + \param sect - Resource section name which contains resource. + \param name - Name of the resource. + \param def - Default resource value which will be used when resource not found. +*/ +QString QtxResourceMgr::stringValue( const QString& sect, const QString& name, const QString& def ) const +{ + QString val; + if ( !value( sect, name, val ) ) + val = def; + return val; +} + +/*! + \brief Checks existance of the specified resource. + \param sect - Resource section name which contains resource. + \param name - Name of the resource. +*/ +bool QtxResourceMgr::hasValue( const QString& sect, const QString& name ) const +{ + initialize(); + + bool ok = false; + for ( ResListIterator it( myResources ); it.current() && !ok; ++it ) + ok = it.current()->hasValue( sect, name ); + + return ok; +} + +/*! + \brief Checks existance of the specified resource section. + \param sect - Resource section name which contains resource. +*/ +bool QtxResourceMgr::hasSection( const QString& sect ) const +{ + initialize(); + + bool ok = false; + for ( ResListIterator it( myResources ); it.current() && !ok; ++it ) + ok = it.current()->hasSection( sect ); + + return ok; +} + +/*! + \brief Sets the integer resource value. + \param sect - Resource section name. + \param name - Name of the resource. + \param val - Resource value. +*/ +void QtxResourceMgr::setValue( const QString& sect, const QString& name, int val ) +{ + int res; + if ( checkExisting() && value( sect, name, res ) && res == val ) + return; + + setResource( sect, name, QString::number( val ) ); +} + +/*! + \brief Sets the double resource value. + \param sect - Resource section name. + \param name - Name of the resource. + \param val - Resource value. +*/ +void QtxResourceMgr::setValue( const QString& sect, const QString& name, double val ) +{ + double res; + if ( checkExisting() && value( sect, name, res ) && res == val ) + return; + + setResource( sect, name, QString::number( val, 'g', 12 ) ); +} + +/*! + \brief Sets the boolean resource value. + \param sect - Resource section name. + \param name - Name of the resource. + \param val - Resource value. +*/ +void QtxResourceMgr::setValue( const QString& sect, const QString& name, bool val ) +{ + bool res; + if ( checkExisting() && value( sect, name, res ) && res == val ) + return; + + setResource( sect, name, QString( val ? "true" : "false" ) ); +} + +/*! + \brief Sets the color resource value. + \param sect - Resource section name. + \param name - Name of the resource. + \param val - Resource value. +*/ +void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QColor& val ) +{ + QColor res; + if ( checkExisting() && value( sect, name, res ) && res == val ) + return; + + setResource( sect, name, QString( "%1, %2, %3" ).arg( val.red() ).arg( val.green() ).arg( val.blue() ) ); +} + +/*! + \brief Sets the font resource value. + \param sect - Resource section name. + \param name - Name of the resource. + \param val - Resource value. +*/ +void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QFont& val ) +{ + QFont res; + if ( checkExisting() && value( sect, name, res ) && res == val ) + return; + + QStringList fontDescr; + fontDescr.append( val.family() ); + if ( val.bold() ) + fontDescr.append( "Bold" ); + if ( val.italic() ) + fontDescr.append( "Italic" ); + if ( val.underline() ) + fontDescr.append( "Underline" ); + fontDescr.append( QString( "%1" ).arg( val.pointSize() ) ); + + setResource( sect, name, fontDescr.join( "," ) ); +} + +/*! + \brief Sets the string resource value. + \param sect - Resource section name. + \param name - Name of the resource. + \param val - Resource value. +*/ +void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QString& val ) +{ + QString res; + if ( checkExisting() && value( sect, name, res ) && res == val ) + return; + + setResource( sect, name, val ); +} + +/*! + \brief Remove the all specified resource section. + \param sect - Resource section name. +*/ +void QtxResourceMgr::remove( const QString& sect ) +{ + initialize(); + + for ( ResListIterator it( myResources ); it.current(); ++it ) + it.current()->removeSection( sect ); +} + +/*! + \brief Remove the specified resource. + \param sect - Resource section name. + \param name - Name of the resource. +*/ +void QtxResourceMgr::remove( const QString& sect, const QString& name ) +{ + initialize(); + + for ( ResListIterator it( myResources ); it.current(); ++it ) + it.current()->removeValue( sect, name ); +} + +/*! + \brief Returns the current format which operates with resource files. +*/ +QString QtxResourceMgr::currentFormat() const +{ + QString fmt; + if ( !myFormats.isEmpty() ) + fmt = myFormats.getFirst()->format(); + return fmt; +} + +/*! + \brief Sets the current format which operates with resource files. + \param fmt - Resource format name. +*/ +void QtxResourceMgr::setCurrentFormat( const QString& fmt ) +{ + Format* form = format( fmt ); + if ( !form ) + return; + + myFormats.remove( form ); + myFormats.prepend( form ); + + if ( myResources.isEmpty() ) + return; + + ResListIterator resIt( myResources ); + if ( myResources.count() > myDirList.count() && resIt.current() ) { + resIt.current()->setFile( userFileName( appName() ) ); + ++resIt; + } + + for ( QStringList::const_iterator it = myDirList.begin(); it != myDirList.end() && resIt.current(); ++it, ++resIt ) + resIt.current()->setFile( Qtx::addSlash( *it ) + globalFileName( appName() ) ); +} + +/*! + \brief Returns the resource format object by it name. + \param fmt - Resource format name. +*/ +QtxResourceMgr::Format* QtxResourceMgr::format( const QString& fmt ) const +{ + Format* form = 0; + for ( FormatListIterator it( myFormats ); it.current() && !form; ++it ) + { + if ( it.current()->format() == fmt ) + form = it.current(); + } + + return form; +} + +/*! + \brief Add the resource format to the manager. Newly added become current. + \param form - Resource format object. +*/ +void QtxResourceMgr::installFormat( QtxResourceMgr::Format* form ) +{ + if ( !myFormats.contains( form ) ) + myFormats.prepend( form ); +} + +/*! + \brief Remove the resource format from the manager. + \param form - Resource format object. +*/ +void QtxResourceMgr::removeFormat( QtxResourceMgr::Format* form ) +{ + myFormats.remove( form ); +} + +/*! + \brief Returns the string list of the resource format options names. +*/ +QStringList QtxResourceMgr::options() const +{ + return myOptions.keys(); +} + +/*! + \brief Returns the string value for the specified option. If option doesn't exist + then empty string will be returned. + \param opt - Option name. +*/ +QString QtxResourceMgr::option( const QString& opt ) const +{ + QString val; + if ( myOptions.contains( opt ) ) + val = myOptions[opt]; + return val; +} + +/*! + \brief Sets the string value for the specified option. + \param opt - Option name. + \param val - Option value. +*/ +void QtxResourceMgr::setOption( const QString& opt, const QString& val ) +{ + myOptions.insert( opt, val ); +} + +/*! + \brief Load the all resources from the resource files. +*/ +bool QtxResourceMgr::load() +{ + initialize( false ); + + Format* fmt = format( currentFormat() ); + if ( !fmt ) + return false; + + bool res = true; + for ( ResListIterator it( myResources ); it.current(); ++it ) + res = fmt->load( it.current() ) && res; + + return res; +} + +/*! + \brief Save the changed resources in to the user resource file. +*/ +bool QtxResourceMgr::save() +{ + initialize( false ); + + Format* fmt = format( currentFormat() ); + if ( !fmt ) + return false; + + if ( myResources.isEmpty() ) + return true; + + return fmt->save( myResources.getFirst() ); +} + +/*! + \brief Returns the string list of the existing section names.. +*/ +QStringList QtxResourceMgr::sections() const +{ + initialize(); + + QMap map; + for ( ResListIterator it( myResources ); it.current(); ++it ) + { + QStringList lst = it.current()->sections(); + for ( QStringList::const_iterator itr = lst.begin(); itr != lst.end(); ++itr ) + map.insert( *itr, 0 ); + } + + QStringList res; + for ( QMap::ConstIterator iter = map.begin(); iter != map.end(); ++iter ) + res.append( iter.key() ); + + return res; +} + +/*! + \brief Returns the string list of the existing resource names in the specified section. + \param sec - Resource section name. +*/ +QStringList QtxResourceMgr::parameters( const QString& sec ) const +{ + initialize(); + +#if defined(QTX_NO_INDEXED_MAP) + typedef QMap PMap; +#else + typedef IMap PMap; +#endif + PMap pmap; + ResListIterator it( myResources ); + it.toLast(); + for ( ; it.current(); --it ) { + QStringList lst = it.current()->parameters( sec ); + for ( QStringList::const_iterator itr = lst.begin(); itr != lst.end(); ++itr ) + pmap.insert( *itr, 0, false ); + } + + QStringList res; + for ( PMap::ConstIterator iter = pmap.begin(); iter != pmap.end(); ++iter ) + res.append( iter.key() ); + + return res; +} + +QString QtxResourceMgr::path( const QString& sect, const QString& prefix, const QString& name ) const +{ + QString res; + for ( ResListIterator it( myResources ); it.current() && res.isEmpty(); ++it ) + res = it.current()->path( sect, prefix, name ); + return res; +} + +QString QtxResourceMgr::resSection() const +{ + QString res = option( "res_section_name" ); + if ( res.isEmpty() ) + res = QString( "resources" ); + return res; +} + +QString QtxResourceMgr::langSection() const +{ + QString res = option( "lang_section_name" ); + if ( res.isEmpty() ) + res = QString( "language" ); + return res; +} + +QPixmap QtxResourceMgr::defaultPixmap() const +{ + return myDefaultPix; +} + +void QtxResourceMgr::setDefaultPixmap( const QPixmap& pix ) +{ + myDefaultPix = pix; +} + +QPixmap QtxResourceMgr::loadPixmap( const QString& prefix, const QString& name ) const +{ + return loadPixmap( prefix, name, true ); +} + +QPixmap QtxResourceMgr::loadPixmap( const QString& prefix, const QString& name, const bool useDef ) const +{ + return loadPixmap( prefix, name, useDef ? defaultPixmap() : QPixmap() ); +} + +QPixmap QtxResourceMgr::loadPixmap( const QString& prefix, const QString& name, const QPixmap& defPix ) const +{ + initialize(); + + QPixmap pix; + for ( ResListIterator it( myResources ); it.current() && pix.isNull(); ++it ) + pix = it.current()->loadPixmap( resSection(), prefix, name ); + if ( pix.isNull() ) + pix = defPix; + return pix; +} + +void QtxResourceMgr::loadLanguage( const QString& pref, const QString& l ) +{ + initialize(); + + QMap substMap; + substMap.insert( 'A', appName() ); + + QString lang = l; + if ( lang.isEmpty() ) + value( langSection(), "language", lang ); + + if ( lang.isEmpty() ) + { + lang = QString( "en" ); + qWarning( QString( "Language not specified. Assumed: %1" ).arg( lang ) ); + } + + substMap.insert( 'L', lang ); + + QString trs; + if ( value( langSection(), "translators", trs, false ) && !trs.isEmpty() ) + { + QStringList translators = QStringList::split( "|", option( "translators" ) ); + QStringList newTranslators = QStringList::split( "|", trs ); + for ( uint i = 0; i < newTranslators.count(); i++ ) + if ( translators.find( newTranslators[i] ) == translators.end() ) + translators += newTranslators[i]; + setOption( "translators", translators.join( "|" ) ); + } + + QStringList trList = QStringList::split( "|", option( "translators" ) ); + if ( trList.isEmpty() ) + { + trList.append( "%P_msg_%L.qm" ); + qWarning( QString( "Translators not defined. Assumed: %1" ).arg( trList.first() ) ); + } + + QStringList prefixList; + if ( !pref.isEmpty() ) + prefixList.append( pref ); + else + prefixList = parameters( resSection() ); + + for ( QStringList::const_iterator iter = prefixList.begin(); iter != prefixList.end(); ++iter ) + { + QString prefix = *iter; + substMap.insert( 'P', prefix ); + + QStringList trs; + for ( QStringList::const_iterator it = trList.begin(); it != trList.end(); ++it ) + trs.append( substMacro( *it, substMap ).stripWhiteSpace() ); + + loadTranslators( prefix, trs ); + } +} + +void QtxResourceMgr::loadTranslators( const QString& prefix, const QStringList& translators ) +{ + initialize(); + + QTranslator* trans = 0; + ResListIterator it( myResources ); + it.toLast(); + for ( ; it.current(); --it ) + { + for ( QStringList::const_iterator itr = translators.begin(); itr != translators.end(); ++itr ) + { + trans = it.current()->loadTranslator( resSection(), prefix, *itr ); + if ( trans ) + { + if ( !myTranslator[prefix].contains( trans ) ) + myTranslator[prefix].append( trans ); + qApp->installTranslator( trans ); + } + } + } +} + +void QtxResourceMgr::loadTranslator( const QString& prefix, const QString& name ) +{ + initialize(); + + QTranslator* trans = 0; + ResListIterator it( myResources ); + it.toLast(); + for ( ; it.current(); --it ) + { + trans = it.current()->loadTranslator( resSection(), prefix, name ); + if ( trans ) + { + if ( !myTranslator[prefix].contains( trans ) ) + myTranslator[prefix].append( trans ); + qApp->installTranslator( trans ); + } + } +} + +void QtxResourceMgr::removeTranslators( const QString& prefix ) +{ + if ( !myTranslator.contains( prefix ) ) + return; + + for ( TransListIterator it( myTranslator[prefix] ); it.current(); ++it ) + { + qApp->removeTranslator( it.current() ); + delete it.current(); + } + + myTranslator.remove( prefix ); +} + +void QtxResourceMgr::raiseTranslators( const QString& prefix ) +{ + if ( !myTranslator.contains( prefix ) ) + return; + + for ( TransListIterator it( myTranslator[prefix] ); it.current(); ++it ) + { + qApp->removeTranslator( it.current() ); + qApp->installTranslator( it.current() ); + } +} + +void QtxResourceMgr::refresh() +{ + QStringList sl = sections(); + for ( QStringList::const_iterator it = sl.begin(); it != sl.end(); ++it ) + { + QStringList pl = parameters( *it ); + for ( QStringList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr ) + setResource( *it, *itr, stringValue( *it, *itr ) ); + } +} + +void QtxResourceMgr::setDirList( const QStringList& dl ) +{ + myDirList = dl; + for ( ResListIterator it( myResources ); it.current(); ++it ) + delete it.current(); + + myResources.clear(); +} + +void QtxResourceMgr::setResource( const QString& sect, const QString& name, const QString& val ) +{ + initialize(); + + if ( !myResources.isEmpty() ) + myResources.first()->setValue( sect, name, val ); +} + +QString QtxResourceMgr::userFileName( const QString& appName ) const +{ + QString fileName; + QString pathName = QDir::homeDirPath(); + +#ifdef WIN32 + fileName = QString( "%1.%2" ).arg( appName ).arg( currentFormat() ); +#else + fileName = QString( ".%1rc" ).arg( appName ); +#endif + + if ( !fileName.isEmpty() ) + pathName = Qtx::addSlash( pathName ) + fileName; + + return pathName; +} + +QString QtxResourceMgr::globalFileName( const QString& appName ) const +{ + return QString( "%1.%2" ).arg( appName ).arg( currentFormat() ); +} + +QString QtxResourceMgr::substMacro( const QString& src, const QMap& substMap ) const +{ + QString trg = src; + + QRegExp rx( "%[A-Za-z%]" ); + + int idx = 0; + while ( ( idx = rx.search( trg, idx ) ) >= 0 ) + { + QChar spec = trg.at( idx + 1 ); + QString subst; + if ( spec == '%' ) + subst = "%"; + else if ( substMap.contains( spec ) ) + subst = substMap[spec]; + + if ( !subst.isEmpty() ) + { + trg.replace( idx, rx.matchedLength(), subst ); + idx += subst.length(); + } + else + idx += rx.matchedLength(); + } + + return trg; +} diff --git a/src/Qtx/QtxResourceMgr.h b/src/Qtx/QtxResourceMgr.h new file mode 100644 index 000000000..868dc9fde --- /dev/null +++ b/src/Qtx/QtxResourceMgr.h @@ -0,0 +1,433 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef QTX_RESOURCEMGR_H +#define QTX_RESOURCEMGR_H + +#include "Qtx.h" + +#include +#include +#include +#include +#include +#include +#include + +class QPixmap; + +#ifdef WIN32 +#pragma warning( disable:4251 ) +#endif + +/*! + Class: QtxResourceMgr +*/ + +class QTX_EXPORT QtxResourceMgr +{ + class IniFormat; + class XmlFormat; + class Resources; + +public: + class Format; + + template class IMap; + template class IMapIterator; + template class IMapConstIterator; + +#ifdef QTX_NO_INDEXED_MAP + typedef QMap Section; +#else + typedef IMap Section; +#endif + +public: + QtxResourceMgr( const QString&, const QString& = QString::null ); + virtual ~QtxResourceMgr(); + + QString appName() const; + QStringList dirList() const; + + bool checkExisting() const; + virtual void setCheckExisting( const bool ); + + void clear(); + + bool value( const QString&, const QString&, int& ) const; + bool value( const QString&, const QString&, double& ) const; + bool value( const QString&, const QString&, bool& ) const; + bool value( const QString&, const QString&, QColor& ) const; + bool value( const QString&, const QString&, QFont& ) const; + bool value( const QString&, const QString&, QString&, const bool = true ) const; + + int integerValue( const QString&, const QString&, const int = 0 ) const; + double doubleValue( const QString&, const QString&, const double = 0 ) const; + bool booleanValue( const QString&, const QString&, const bool = false ) const; + QFont fontValue( const QString&, const QString&, const QFont& = QFont() ) const; + QColor colorValue( const QString&, const QString&, const QColor& = QColor() ) const; + QString stringValue( const QString&, const QString&, const QString& = QString::null ) const; + + bool hasSection( const QString& ) const; + bool hasValue( const QString&, const QString& ) const; + + void setValue( const QString&, const QString&, const int ); + void setValue( const QString&, const QString&, const double ); + void setValue( const QString&, const QString&, const bool ); + void setValue( const QString&, const QString&, const QFont& ); + void setValue( const QString&, const QString&, const QColor& ); + void setValue( const QString&, const QString&, const QString& ); + + void remove( const QString& ); + void remove( const QString&, const QString& ); + + QString currentFormat() const; + void setCurrentFormat( const QString& ); + + Format* format( const QString& ) const; + void installFormat( Format* ); + void removeFormat( Format* ); + + QStringList options() const; + QString option( const QString& ) const; + void setOption( const QString&, const QString& ); + + QPixmap defaultPixmap() const; + virtual void setDefaultPixmap( const QPixmap& ); + + QString resSection() const; + QString langSection() const; + + QPixmap loadPixmap( const QString&, const QString& ) const; + QPixmap loadPixmap( const QString&, const QString&, const bool ) const; + QPixmap loadPixmap( const QString&, const QString&, const QPixmap& ) const; + void loadLanguage( const QString& = QString::null, const QString& = QString::null ); + + void raiseTranslators( const QString& ); + void removeTranslators( const QString& ); + void loadTranslator( const QString&, const QString& ); + void loadTranslators( const QString&, const QStringList& ); + + QString path( const QString&, const QString&, const QString& ) const; + + bool load(); + bool save(); + + QStringList sections() const; + QStringList parameters( const QString& ) const; + + void refresh(); + +protected: + virtual void setDirList( const QStringList& ); + virtual void setResource( const QString&, const QString&, const QString& ); + + virtual QString userFileName( const QString& ) const; + virtual QString globalFileName( const QString& ) const; + +private: + void initialize( const bool = true ) const; + QString substMacro( const QString&, const QMap& ) const; + +private: + typedef QPtrList ResList; + typedef QPtrList FormatList; + typedef QMap OptionsMap; + typedef QPtrListIterator ResListIterator; + typedef QPtrListIterator FormatListIterator; + + typedef QPtrList TransList; + typedef QMap TransListMap; + typedef QPtrListIterator TransListIterator; + +private: + QString myAppName; + QStringList myDirList; + FormatList myFormats; + OptionsMap myOptions; + ResList myResources; + bool myCheckExist; + TransListMap myTranslator; + QPixmap myDefaultPix; +}; + +/*! + Class: QtxResourceMgr::Format +*/ + +class QTX_EXPORT QtxResourceMgr::Format +{ +public: + Format( const QString& ); + ~Format(); + + QString format() const; + + QStringList options() const; + QString option( const QString& ) const; + void setOption( const QString&, const QString& ); + + bool load( Resources* ); + bool save( Resources* ); + +protected: + virtual bool load( const QString&, QMap& ) = 0; + virtual bool save( const QString&, const QMap& ) = 0; + +private: + QString myFmt; + QMap myOpt; +}; + +/*! + Class: QtxResourceMgr::Resources +*/ + +class QtxResourceMgr::Resources +{ +public: + Resources( const QString& ); + virtual ~Resources(); + + QString file() const; + void setFile( const QString& ); + + QString value( const QString&, const QString&, const bool ) const; + void setValue( const QString&, const QString&, const QString& ); + + bool hasSection( const QString& ) const; + bool hasValue( const QString&, const QString& ) const; + + void removeSection( const QString& ); + void removeValue( const QString&, const QString& ); + + QPixmap loadPixmap( const QString&, const QString&, const QString& ) const; + QTranslator* loadTranslator( const QString&, const QString&, const QString& ) const; + + QString environmentVariable( const QString&, int&, int& ) const; + QString makeSubstitution( const QString&, const QString&, const QString& ) const; + + void clear(); + + QStringList sections() const; + QStringList parameters( const QString& ) const; + + QString path( const QString&, const QString&, const QString& ) const; + +private: + Section& section( const QString& ); + const Section& section( const QString& ) const; + + QString fileName( const QString&, const QString&, const QString& ) const; + +private: + typedef QMap SectionMap; + +private: + SectionMap mySections; + QString myFileName; + + friend class QtxResourceMgr::Format; +}; + +/*! + Class: QtxResourceMgr::IMapIterator +*/ + +template class QtxResourceMgr::IMapIterator +{ +public: + IMapIterator() : myMap( 0 ), myIndex( 0 ) { init(); } + IMapIterator( const IMap* m ) : myMap( const_cast< IMap* >( m ) ), myIndex( 0 ) { init(); } + IMapIterator( const IMapIterator& i ) : myMap( i.myMap ), myIndex( i.myIndex ) { init(); } + + bool operator==( const IMapIterator& i ) { return !operator!=( i ); } + bool operator!=( const IMapIterator& i ) { return !myMap || myMap != i.myMap || myIndex != i.myIndex; } + + operator bool() const { return myIndex >= 0; } + + const Key& key() const { return myMap->key( myIndex ); } + Value& data() { return myMap->value( myIndex ); } + const Value& data() const { return myMap->value( myIndex ); } + + Value& operator*() { return data(); } + + IMapIterator& operator++() { myIndex++; init(); return *this; } + IMapIterator operator++( int ) { IMapIterator i = *this; myIndex++; init(); return i; } + IMapIterator& operator--() { myIndex--; init(); return *this; } + IMapIterator operator--( int ) { IMapIterator i = *this; myIndex--; init(); return i; } + +private: + IMapIterator( const IMap* m, const int index ) : myMap( const_cast< IMap* >( m ) ), myIndex( index ) { init(); } + void init() { if ( !myMap || myIndex >= myMap->count() ) myIndex = -1; } + +private: + IMap* myMap; + int myIndex; + + friend class IMap; + friend class IMapConstIterator; +}; + +/*! + Class: QtxResourceMgr::IMapConstIterator +*/ + +template class QtxResourceMgr::IMapConstIterator +{ +public: + IMapConstIterator() : myMap( 0 ), myIndex( 0 ) { init(); } + IMapConstIterator( const IMap* m ) : myMap( const_cast< IMap* >( m ) ), myIndex( 0 ) { init(); } + IMapConstIterator( const IMapConstIterator& i ) : myMap( i.myMap ), myIndex( i.myIndex ) { init(); } + IMapConstIterator( const IMapIterator& i ) : myMap( i.myMap ), myIndex( i.myIndex ) { init(); } + + bool operator==( const IMapConstIterator& i ) { return !operator!=( i ); } + bool operator!=( const IMapConstIterator& i ) { return !myMap || myMap != i.myMap || myIndex != i.myIndex; } + + operator bool() const { return myIndex >= 0; } + + const Key& key() const { return myMap->key( myIndex ); } + const Value& data() const { return myMap->value( myIndex ); } + + const Value& operator*() const { return data(); } + + IMapConstIterator& operator++() { myIndex++; init(); return *this; } + IMapConstIterator operator++( int ) { IMapConstIterator i = *this; myIndex++; init(); return i; } + IMapConstIterator& operator--() { myIndex--; init(); return *this; } + IMapConstIterator operator--( int ) { IMapConstIterator i = *this; myIndex--; init(); return i; } + +private: + IMapConstIterator( const IMap* m, const int index ): myMap( const_cast< IMap* >( m ) ), myIndex( index ) { init(); } + void init() { if ( !myMap || myIndex >= myMap->count() ) myIndex = -1; } + +private: + IMap* myMap; + int myIndex; + + friend class IMap; +}; + +/*! + Class: QtxResourceMgr::IMap +*/ + +template class QtxResourceMgr::IMap +{ +public: + typedef IMapIterator Iterator; + typedef IMapConstIterator ConstIterator; + +public: + IMap() {} + IMap( const IMap& m ) : myKeys( m.myKeys ), myData( m.myData ) {} + IMap& operator=( const IMap& m ) { myKeys = m.myKeys; myData = m.myData; return *this; } + + int count() const { return myData.count(); } + int size() const { return myData.count(); } + bool empty() const { return myData.empty(); } + bool isEmpty() const { return myData.empty(); } + + void clear() { myKeys.clear(); myData.clear(); } + + QValueList keys() const { return myKeys; } + QValueList values() const { QValueList l; for ( int i = 0; i < count(); i++ ) l.append( value( i ) ); return l; } + bool contains ( const Key& key ) const { return myData.contains( key ); } + + Iterator begin() { return Iterator( this ); } + Iterator end() { return Iterator( this, count() ); } + ConstIterator begin() const { return ConstIterator( this ); } + ConstIterator end() const { return ConstIterator( this, count() ); } + + Iterator insert( const Key& key, const Value& value, bool overwrite = true ) + { + if ( myData.find( key ) == myData.end() || overwrite ) + { + if ( myData.find( key ) != myData.end() && overwrite ) + myKeys.remove( myKeys.find( key ) ); + myKeys.append( key ); + myData[key] = value; + } + return Iterator( this, index( key ) ); + } + + Iterator replace( const Key& key, const Value& value ) + { + if ( myData.find( key ) == myData.end() ) + myKeys.append( key ); + myData[ key ] = value; + return Iterator( this, index( key ) ); + } + + int index( const Key& key ) const { return myKeys.findIndex( key ); } + Iterator at( const int index ) { return Iterator( this, index ); } + ConstIterator at( const int index ) const { return ConstIterator( this, index ); } + + Key& key( const int index ) + { + if ( index < 0 || index >= (int)myKeys.count() ) + return dummyKey; + return myKeys[index]; + } + + Value& value( const int index ) + { + if ( index < 0 || index >= (int)myKeys.count() ) + return dummyValue; + return myData[ myKeys[index] ]; + } + + Value& operator[]( const Key& key ) + { + if ( myData.find( key ) == myData.end() ) + insert( key, Value() ); + return myData[ key ]; + } + + const Value& operator[]( const Key& key ) const + { + if ( myData.find( key ) == myData.end() ) + return dummyValue; + return myData[ key ]; + } + + void erase( Iterator it ) { remove( it ); } + void erase( const Key& key ) { remove( key ); } + void erase( const int index ) { remove( index ); } + void remove( Iterator it ) { if ( it.myMap != this ) return; remove( it.myIndex ); } + void remove( const Key& key ) { remove( index( key ) ); } + void remove( const int index ) + { + if ( index >= 0 && index < (int)myKeys.count() ) + { + myData.remove( myKeys[ index ] ); + myKeys.remove( myKeys.at( index ) ); + } + } + +private: + QValueList myKeys; + QMap myData; + Key dummyKey; + Value dummyValue; + + friend class IMapIterator; + friend class IMapConstIterator; +}; + +#endif diff --git a/src/Qtx/QtxStdOperations.cxx b/src/Qtx/QtxStdOperations.cxx new file mode 100644 index 000000000..6d612b299 --- /dev/null +++ b/src/Qtx/QtxStdOperations.cxx @@ -0,0 +1,840 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "QtxStdOperations.h" + +#include +#include + +//================================================================ +// Function : +// Purpose : +//================================================================ +QtxStdOperations::QtxStdOperations() +{ +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +QtxStdOperations::~QtxStdOperations() +{ +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +void QtxStdOperations::bracketsList( QStringList& list, bool open ) const +{ + if( open ) + list.append( "(" ); + else + list.append( ")" ); +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +void QtxStdOperations::opersList( QStringList& list ) const +{ + list += myOpers; +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +void QtxStdOperations::addOperations( const QStringList& list ) +{ + QStringList::const_iterator anIt = list.begin(), + aLast = list.end(); + for( ; anIt!=aLast; anIt++ ) + if( myOpers.contains( *anIt )==0 ) + myOpers.append( *anIt ); +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +void QtxStdOperations::addTypes( const ListOfTypes& list ) +{ + ListOfTypes::const_iterator anIt = list.begin(), + aLast = list.end(); + for( ; anIt!=aLast; anIt++ ) + if( myTypes.contains( *anIt )==0 ) + myTypes.append( *anIt ); +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +QtxParser::Error QtxStdOperations::isValid( const QString& op, + const QVariant::Type t1, + const QVariant::Type t2 ) const +{ + if( ( t1==QVariant::Invalid || myTypes.contains( t1 ) ) && + ( t2==QVariant::Invalid || myTypes.contains( t2 ) ) && + ( t1!=QVariant::Invalid || t2!=QVariant::Invalid ) ) + if( prior( op, t1!=QVariant::Invalid && t2!=QVariant::Invalid ) > 0 ) + return QtxParser::OK; + else + return QtxParser::InvalidOperation; + else + return QtxParser::OperandsNotMatch; +} + + + + + + + + +//================================================================ +// Function : +// Purpose : +//================================================================ +QtxArithmetics::QtxArithmetics() +: QtxStdOperations() +{ + QStringList aList; + aList.append( "+" ); + aList.append( "-" ); + aList.append( "*" ); + aList.append( "/" ); + aList.append( "=" ); + aList.append( "<" ); + aList.append( ">" ); + aList.append( "<=" ); + aList.append( ">=" ); + aList.append( "<>" ); + aList.append( "!=" ); // same as "<>" - for C++ addicts + addOperations( aList ); + + ListOfTypes aTypes; + aTypes.append( QVariant::Int ); + aTypes.append( QVariant::UInt ); + aTypes.append( QVariant::Double ); + addTypes( aTypes ); +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +QtxArithmetics::~QtxArithmetics() +{ +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +bool QtxArithmetics::createValue( const QString& str, QtxValue& v ) const +{ + bool ok = false; + v = str.toInt( &ok ); + + if( !ok ) + { + v = str.toDouble( &ok ); + if( !ok ) + ok = QtxStdOperations::createValue( str, v ); + } + return ok; +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +int QtxArithmetics::prior( const QString& op, bool isBin ) const +{ + if( isBin ) + if( op=="<" || op==">" || op=="=" || + op=="<=" || op==">=" || op=="<>" || op=="!=" ) + return 1; + else if( op=="+" || op=="-" ) + return 2; + else if( op=="*" || op=="/" ) + return 3; + else + return 0; + else if( op=="+" || op=="-" ) + return 5; + else + return 0; +} + +void set( QVariant& v1, bool v2 ) +{ + v1 = QVariant( v2, 0 ); +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +QtxParser::Error QtxArithmetics::calculate( const QString& op, + QtxValue& v1, QtxValue& v2 ) const +{ + QtxParser::Error err = QtxParser::OK; + + if( v1.isValid() && v2.isValid() ) + // binary operations + if( ( v1.type()==QVariant::Int || v1.type()==QVariant::UInt ) && + ( v2.type()==QVariant::Int || v2.type()==QVariant::UInt ) ) + { + int _v1 = v1.toInt(), + _v2 = v2.toInt(); + + if( op=="+" ) + v1 = _v1 + _v2; + else if( op=="-" ) + v1 = _v1 - _v2; + else if( op=="*" ) + v1 = _v1 * _v2; + else if( op=="/" ) + if( _v2!=0 ) + if( _v1%_v2==0 ) + v1 = _v1 / _v2; + else + v1 = double( _v1 ) / double( _v2 ); + else + err = QtxParser::InvalidResult; + else if( op=="<" ) + set( v1, _v1<_v2 ); + else if( op==">" ) + set( v1, _v1>_v2 ); + else if( op=="=" ) + set( v1, _v1==_v2 ); + else if( op=="<=" ) + set( v1, _v1<=_v2 ); + else if( op==">=" ) + set( v1, _v1>=_v2 ); + else if( op=="<>" || op=="!=" ) + set( v1, _v1!=_v2 ); + } + else if( ( v1.type()==QVariant::Int || v1.type()==QVariant::Double ) && + ( v2.type()==QVariant::Int || v2.type()==QVariant::Double ) ) + { + double _v1 = v1.toDouble(), + _v2 = v2.toDouble(); + + if( op=="+" ) + v1 = _v1 + _v2; + else if( op=="-" ) + v1 = _v1 - _v2; + else if( op=="*" ) + v1 = _v1 * _v2; + else if( op=="/" ) + if( _v2!=0 ) + v1 = _v1 / _v2; + else + err = QtxParser::InvalidResult; + else if( op=="<" ) + set( v1, _v1<_v2 ); + else if( op==">" ) + set( v1, _v1>_v2 ); + else if( op=="=" ) + set( v1, _v1==_v2 ); + else if( op=="<=" ) + set( v1, _v1<=_v2 ); + else if( op==">=" ) + set( v1, _v1>=_v2 ); + else if( op=="<>" || op=="!=" ) + set( v1, _v1!=_v2 ); + } + else + // prefix operations + if( op=="-" ) + if( v2.type()==QVariant::Int ) + v2 = -v2.toInt(); + else if( v2.type()==QVariant::Double ) + v2 = -v2.toDouble(); + + return err; +} + + + + + + + + + + + +//================================================================ +// Function : +// Purpose : +//================================================================ +QtxLogic::QtxLogic() +: QtxStdOperations() +{ + QStringList aList; + aList.append( "and" ); + aList.append( "&&" ); + aList.append( "or" ); + aList.append( "||" ); + aList.append( "xor" ); + aList.append( "not" ); + aList.append( "!" ); + aList.append( "imp" ); + aList.append( "=" ); + addOperations( aList ); + + ListOfTypes aTypes; + aTypes.append( QVariant::Bool ); + aTypes.append( QVariant::Int ); + aTypes.append( QVariant::UInt ); + addTypes( aTypes ); +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +QtxLogic::~QtxLogic() +{ +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +bool QtxLogic::createValue( const QString& str, QtxValue& v ) const +{ + bool ok = true; + if( str.lower()=="true" ) + v = QtxValue( true, 0 ); + else if( str.lower()=="false" ) + v = QtxValue( false, 0 ); + else + ok = QtxStdOperations::createValue( str, v ); + + return ok; +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +int QtxLogic::prior( const QString& op, bool isBin ) const +{ + if( isBin ) + if( op=="and" || op=="or" || op=="xor" || + op=="&&" || op=="||" || + op=="imp" ) + return 1; + else if( op=="=" ) + return 2; + else + return 0; + else if( op=="not" || op=="!" ) + return 5; + else + return 0; +} + +bool boolean_value( const QtxValue& v ) +{ + if( v.type()==QVariant::Bool ) + return v.toBool(); + else if( v.type()==QVariant::Int ) + return v.toInt()!=0; + else if( v.type()==QVariant::UInt ) + return v.toUInt()!=0; + else + return false; +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +QtxParser::Error QtxLogic::calculate( const QString& op, + QtxValue& v1, QtxValue& v2 ) const +{ + QtxParser::Error err = QtxParser::OK; + bool val1 = boolean_value( v1 ), + val2 = boolean_value( v2 ); + if( v1.isValid() && v2.isValid() ) + { + if( op=="and" || op=="&&" ) + set( v1, val1 && val2 ); + else if( op=="or" || op=="||" ) + set( v1, val1 || val2 ); + else if( op=="xor" ) + set( v1, ( !val1 && val2 ) || ( val1 && !val2 ) ); + else if( op=="imp" ) + set( v1, !val1 || val2 ); + else if( op=="=" ) + set( v1, val1==val2 ); + } + else + if( op=="not" || op=="!" ) + set( v2, !val2 ); + + return err; +} + + + + + + +//================================================================ +// Function : +// Purpose : +//================================================================ +QtxFunctions::QtxFunctions() +: QtxStdOperations() +{ + QStringList aList; + aList.append( "sqrt" ); + aList.append( "abs" ); + aList.append( "sin" ); + aList.append( "cos" ); + aList.append( "rad2grad" ); + aList.append( "grad2rad" ); + addOperations( aList ); + + ListOfTypes aTypes; + aTypes.append( QVariant::Int ); + aTypes.append( QVariant::Double ); + addTypes( aTypes ); +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +QtxFunctions::~QtxFunctions() +{ +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +bool QtxFunctions::createValue( const QString& str, QtxValue& v ) const +{ + bool ok = false; + v = str.toInt( &ok ); + + if( !ok ) + { + v = str.toDouble( &ok ); + if( !ok ) + ok = QtxStdOperations::createValue( str, v ); + } + return ok; +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +int QtxFunctions::prior( const QString& op, bool isBin ) const +{ + if( isBin ) + return 0; + else if( op=="sqrt" || op=="abs" || op=="sin" || op=="cos" || + op=="rad2grad" || op=="grad2rad" ) + return 1; + else + return 0; +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +QtxParser::Error QtxFunctions::calculate( const QString& op, + QtxValue& v1, QtxValue& v2 ) const +{ + QtxParser::Error err = QtxParser::OK; + double val = v2.toDouble(); + if( op=="sqrt" ) + if( val>=0 ) + v2 = sqrt( val ); + else + err = QtxParser::InvalidResult; + else if( op=="abs" ) + if( v2.type()==QVariant::Int ) + v2 = abs( v2.toInt() ); + else + v2 = fabs( v2.toDouble() ); + else if( op=="sin" ) + v2 = sin( val ); + else if( op=="cos" ) + v2 = cos( val ); + else if( op=="grad2rad" ) + v2 = val * 3.14159256 / 180.0; + else if( op=="rad2grad" ) + v2 = val * 180.0 / 3.14159256; + + return err; +} + + + + + + + + +//================================================================ +// Function : +// Purpose : +//================================================================ +QtxStrings::QtxStrings() +: QtxStdOperations() +{ + QStringList aList; + aList.append( "+" ); + aList.append( "=" ); + aList.append( "<" ); + aList.append( ">" ); + aList.append( "<=" ); + aList.append( ">=" ); + aList.append( "<>" ); + aList.append( "!=" ); // same as "<>" - for C++ addicts + aList.append( "length" ); + aList.append( "lower" ); + aList.append( "upper" ); + addOperations( aList ); + + ListOfTypes aTypes; + aTypes.append( QVariant::Int ); + aTypes.append( QVariant::Double ); + aTypes.append( QVariant::String ); + aTypes.append( QVariant::CString ); + addTypes( aTypes ); +} + + +//================================================================ +// Function : +// Purpose : +//================================================================ +QtxStrings::~QtxStrings() +{ +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +bool QtxStrings::createValue( const QString& str, QtxValue& v ) const +{ + QChar st = str[0], + fin = str[ ( int )( str.length()-1 ) ]; + if( st=="'" && fin=="'" ) + { + v = str.mid( 1, str.length()-2 ); + return true; + } + else + return QtxStdOperations::createValue( str, v ); +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +int QtxStrings::prior( const QString& op, bool isBin ) const +{ + if( isBin ) + if( op=="+" ) + return 2; + else if( op=="=" || op=="<" || op==">" || + op=="<=" || op==">=" || op=="<>" || op=="!=" ) + return 1; + else + return 0; + else + if( op=="length" || op=="lower" || op=="upper" ) + return 5; + else + return 0; +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +QtxParser::Error QtxStrings::calculate( const QString& op, + QtxValue& v1, QtxValue& v2 ) const +{ + QtxParser::Error err = QtxParser::OK; + if( v1.isValid() && v2.isValid() ) + { + QString _v1 = v1.toString(), + _v2 = v2.toString(); + if( op=="+" ) + v1 = _v1 + _v2; + else if( op=="=" ) + set( v1, _v1==_v2 ); + else if( op=="<" ) + set( v1, _v1<_v2 ); + else if( op==">" ) + set( v1, _v1>_v2 ); + else if( op=="<>" || op=="!=" ) + set( v1, _v1!=_v2 ); + else if( op=="<=" ) + set( v1, _v1<_v2 || _v1==_v2 ); + else if( op==">=" ) + set( v1, _v1>_v2 || _v1==_v2 ); + } + else if( !v1.isValid() && v2.isValid() ) + { + QString val = v2.toString(); + if( op=="length" ) + v2 = ( int )val.length(); + else if( op=="lower" ) + v2 = val.lower(); + else if( op=="upper" ) + v2 = val.upper(); + } + + return err; +} + + + + + + +//================================================================ +// Function : +// Purpose : +//================================================================ +QtxSets::QtxSets() +{ + QStringList aList; + aList.append( "{" ); + aList.append( "}" ); + aList.append( "=" ); + aList.append( "<>" ); + aList.append( "!=" ); // same as "<>" - for C++ addicts + aList.append( "+" ); + aList.append( "-" ); + aList.append( "*" ); + aList.append( "in" ); + aList.append( "count" ); + addOperations( aList ); + + ListOfTypes aTypes; + aTypes.append( QVariant::List ); + addTypes( aTypes ); +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +QtxSets::~QtxSets() +{ +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +void QtxSets::bracketsList( QStringList& list, bool open ) const +{ + if( open ) + list.append( "{" ); + else + list.append( "}" ); + QtxStdOperations::bracketsList( list, open ); +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +bool QtxSets::createValue( const QString& str, QtxValue& val ) const +{ + return QtxStdOperations::createValue( str, val ); +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +int QtxSets::prior( const QString& op, bool isBin ) const +{ + if( isBin ) + if( op=="=" || op=="<>" || op=="!=" ) + return 1; + else if( op=="+" || op=="-" || op=="*" ) + return 2; + else if( op=="in" ) + return 3; + else + return 0; + + else + if( op=="{" || op=="}" ) + return 5; + else if( op=="count" ) + return 4; + else + return 0; +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +QtxParser::Error QtxSets::isValid( const QString& op, + const QVariant::Type t1, + const QVariant::Type t2 ) const +{ + if( op=="{" ) + return QtxParser::OK; + else if( op=="in" ) + if( t1!=QVariant::Invalid && t2==QVariant::List ) + return QtxParser::OK; + else + return QtxParser::OperandsNotMatch; + else + return QtxStdOperations::isValid( op, t1, t2 ); +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +void QtxSets::add( ValueSet& set, const QtxValue& v ) +{ + if( v.isValid() && set.contains( v )==0 ) + set.append( v ); +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +void QtxSets::add( ValueSet& s1, const ValueSet& s2 ) +{ + ValueSet::const_iterator anIt = s2.begin(), + aLast = s2.end(); + for( ; anIt!=aLast; anIt++ ) + add( s1, *anIt ); +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +void QtxSets::remove( ValueSet& set, const QtxValue& v ) +{ + set.remove( v ); +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +void QtxSets::remove( ValueSet& s1, const ValueSet& s2 ) +{ + ValueSet::const_iterator anIt = s2.begin(), + aLast = s2.end(); + for( ; anIt!=aLast; anIt++ ) + s1.remove( *anIt ); +} + +//================================================================ +// Function : +// Purpose : +//================================================================ +QtxParser::Error QtxSets::calculate( const QString& op, QtxValue& v1, QtxValue& v2 ) const +{ + QtxParser::Error err = QtxParser::OK; + + if( op!="{" ) + if( op=="}" ) + { + ValueSet aNewList; + add( aNewList, v1.toList() ); + v1 = aNewList; + } + + else if( op=="=" || op=="<>" || op=="!=" || op=="+" || op=="-" || op=="*" ) + { + ValueSet aNewList; + add( aNewList, v1.toList() ); + + if( op=="=" || op=="<>" || op=="!=" || op=="-" ) + { + remove( aNewList, v2.toList() ); + + if( op=="=" ) + set( v1, aNewList.isEmpty() && v1.toList().count()==v2.toList().count() ); + else if( op=="<>" || op=="!=" ) + set( v1, !aNewList.isEmpty() || v1.toList().count()!=v2.toList().count() ); + else + v1 = aNewList; + } + else if( op=="+" ) + { + add( aNewList, v2.toList() ); + v1 = aNewList; + } + else if( op=="*" ) + { + ValueSet toDelete; + add( toDelete, aNewList ); + remove( toDelete, v2.toList() ); + remove( aNewList, toDelete ); + v1 = aNewList; + } + } + else if( op=="count" ) + v2 = ( int )v2.toList().count(); + else if( op=="in" ) + { + if( v1.type()==QVariant::List ) + { + bool res = true; + ValueSet::const_iterator anIt = v1.toList().begin(), + aLast = v1.toList().end(); + for( ; anIt!=aLast && res; anIt++ ) + res = v2.toList().contains( *anIt )>0; + + set( v1, res ); + } + else + { + const QValueList< QVariant >& list = v2.toList(); + v1 = ( bool )( list.find( v1 )!=list.end() ); + } + } + + return err; +} diff --git a/src/Qtx/QtxStdOperations.h b/src/Qtx/QtxStdOperations.h new file mode 100644 index 000000000..5a8cfd48e --- /dev/null +++ b/src/Qtx/QtxStdOperations.h @@ -0,0 +1,143 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxStdOperations.h +// Author: Alexander SOLOVYOV + +#ifndef __QTX_STD_OPERATIONS_HEADER__ +#define __QTX_STD_OPERATIONS_HEADER__ + +#include "Qtx.h" +#include "QtxOperations.h" + +//================================================================ +// Class : +// Purpose : +//================================================================ +class QTX_EXPORT QtxStdOperations : public QtxOperations +{ +public: + QtxStdOperations(); + virtual ~QtxStdOperations(); + + virtual void opersList( QStringList& ) const; + virtual void bracketsList( QStringList&, bool open ) const; + + virtual QtxParser::Error isValid( const QString&, + const QVariant::Type, + const QVariant::Type ) const; +protected: + typedef QValueList< QVariant::Type > ListOfTypes; + + void addOperations( const QStringList& ); + void addTypes( const ListOfTypes& ); + +private: + QStringList myOpers; + ListOfTypes myTypes; +}; + +//================================================================ +// Class : +// Purpose : +//================================================================ +class QTX_EXPORT QtxArithmetics : public QtxStdOperations +{ +public: + QtxArithmetics(); + virtual ~QtxArithmetics(); + + virtual bool createValue( const QString&, QtxValue& ) const; + virtual int prior( const QString&, bool isBin ) const; + virtual QtxParser::Error calculate( const QString&, QtxValue&, QtxValue& ) const; +}; + +//================================================================ +// Class : +// Purpose : +//================================================================ +class QTX_EXPORT QtxLogic : public QtxStdOperations +{ +public: + QtxLogic(); + virtual ~QtxLogic(); + + virtual bool createValue( const QString&, QtxValue& ) const; + virtual int prior( const QString&, bool isBin ) const; + virtual QtxParser::Error calculate( const QString&, QtxValue&, QtxValue& ) const; +}; + +//================================================================ +// Class : +// Purpose : +//================================================================ +class QTX_EXPORT QtxFunctions : public QtxStdOperations +{ +public: + QtxFunctions(); + virtual ~QtxFunctions(); + + virtual bool createValue( const QString&, QtxValue& ) const; + virtual int prior( const QString&, bool isBin ) const; + virtual QtxParser::Error calculate( const QString&, QtxValue&, QtxValue& ) const; +}; + +//================================================================ +// Class : +// Purpose : +//================================================================ +class QTX_EXPORT QtxStrings : public QtxStdOperations +{ +public: + QtxStrings(); + virtual ~QtxStrings(); + + virtual bool createValue( const QString&, QtxValue& ) const; + virtual int prior( const QString&, bool isBin ) const; + virtual QtxParser::Error calculate( const QString&, QtxValue&, QtxValue& ) const; +}; + +//================================================================ +// Class : +// Purpose : +//================================================================ +class QTX_EXPORT QtxSets : public QtxStdOperations +{ +public: + typedef QValueList< QtxValue > ValueSet; + +public: + QtxSets(); + virtual ~QtxSets(); + + virtual void bracketsList( QStringList&, bool open ) const; + virtual bool createValue( const QString&, QtxValue& ) const; + virtual int prior( const QString&, bool isBin ) const; + virtual QtxParser::Error isValid( const QString&, + const QVariant::Type, + const QVariant::Type ) const; + virtual QtxParser::Error calculate( const QString&, QtxValue&, QtxValue& ) const; + + static void add( ValueSet&, const QtxValue& ); + static void add( ValueSet&, const ValueSet& ); + static void remove( ValueSet&, const QtxValue& ); + static void remove( ValueSet&, const ValueSet& ); +}; + + +#endif diff --git a/src/Qtx/QtxTable.cxx b/src/Qtx/QtxTable.cxx new file mode 100644 index 000000000..eac69ea60 --- /dev/null +++ b/src/Qtx/QtxTable.cxx @@ -0,0 +1,313 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxTable.cxx +// Author: Sergey TELKOV + +#include "QtxTable.h" + +#ifndef QT_NO_TABLE + +#include + +QtxTable::QtxTable( QWidget* parent, const char* name ) +: QTable( parent, name ), +myHeaderEditor( 0 ), +myEditedHeader( 0 ), +myEditedSection( -1 ) +{ + connect( verticalHeader(), SIGNAL( sizeChange( int, int, int ) ), + this, SLOT( onHeaderSizeChange( int, int, int ) ) ); + connect( horizontalHeader(), SIGNAL( sizeChange( int, int, int ) ), + this, SLOT( onHeaderSizeChange( int, int, int ) ) ); + connect( verticalScrollBar(), SIGNAL( valueChanged( int ) ), this, SLOT( onScrollBarMoved( int ) ) ); + connect( horizontalScrollBar(), SIGNAL( valueChanged( int ) ), this, SLOT( onScrollBarMoved( int ) ) ); +} + +QtxTable::QtxTable( int numRows, int numCols, QWidget* parent, const char* name ) +: QTable( numRows, numCols, parent, name ), +myHeaderEditor( 0 ), +myEditedHeader( 0 ), +myEditedSection( -1 ) +{ + connect( verticalHeader(), SIGNAL( sizeChange( int, int, int ) ), + this, SLOT( onHeaderSizeChange( int, int, int ) ) ); + connect( horizontalHeader(), SIGNAL( sizeChange( int, int, int ) ), + this, SLOT( onHeaderSizeChange( int, int, int ) ) ); + connect( verticalScrollBar(), SIGNAL( valueChanged( int ) ), this, SLOT( onScrollBarMoved( int ) ) ); + connect( horizontalScrollBar(), SIGNAL( valueChanged( int ) ), this, SLOT( onScrollBarMoved( int ) ) ); +} + +QtxTable::~QtxTable() +{ +} + +bool QtxTable::headerEditable( Orientation o ) const +{ + return myHeaderEditable.contains( o ) ? myHeaderEditable[o] : false; +} + +void QtxTable::setHeaderEditable( Orientation o, const bool on ) +{ + if ( headerEditable( o ) == on ) + return; + + myHeaderEditable.insert( o, on ); + + QHeader* hdr = header( o ); + + if ( !on && myEditedHeader == hdr ) + endHeaderEdit( false ); + + if ( on ) + hdr->installEventFilter( this ); + else + hdr->removeEventFilter( this ); +} + +bool QtxTable::editHeader( Orientation o, const int sec ) +{ + return beginHeaderEdit( o, sec ); +} + +void QtxTable::endEditHeader( const bool accept ) +{ + endHeaderEdit( accept ); +} + +void QtxTable::hide() +{ + endHeaderEdit(); + + QTable::hide(); +} + +bool QtxTable::eventFilter( QObject* o, QEvent* e ) +{ + if ( e->type() == QEvent::MouseButtonDblClick ) + { + QMouseEvent* me = (QMouseEvent*)e; + if ( o == horizontalHeader() ) + { + beginHeaderEdit( Horizontal, me->pos() ); + return true; + } + else if ( o == verticalHeader() ) + { + beginHeaderEdit( Vertical, me->pos() ); + return true; + } + } + + if ( o == myHeaderEditor && e->type() == QEvent::KeyPress && isHeaderEditing() ) + { + QKeyEvent* ke = (QKeyEvent*)e; + if ( ke->key() == Key_Escape ) + { + endHeaderEdit( false ); + return true; + } + + if ( ke->key() == Key_Return || ke->key() == Key_Enter ) + { + endHeaderEdit( true ); + return true; + } + + return false; + } + + if ( o == myHeaderEditor && e->type() == QEvent::FocusOut && + isHeaderEditing() && ((QFocusEvent*)e)->reason() != QFocusEvent::Popup ) + { + endHeaderEdit(); + return true; + } + + if ( e->type() == QEvent::Wheel && isHeaderEditing() ) + return true; + + return QTable::eventFilter( o, e ); +} + +void QtxTable::onScrollBarMoved( int ) +{ + updateHeaderEditor(); +} + +void QtxTable::onHeaderSizeChange( int, int, int ) +{ + if ( sender() == myEditedHeader ) + updateHeaderEditor(); +} + +void QtxTable::resizeEvent( QResizeEvent* e ) +{ + QTable::resizeEvent( e ); + + updateHeaderEditor(); +} + +bool QtxTable::beginHeaderEdit( Orientation o, const int section ) +{ + if ( !headerEditable( o ) || !header( o ) || !header( o )->isVisibleTo( this ) ) + return false; + + endHeaderEdit(); + + QHeader* hdr = header( o ); + + QRect r = headerSectionRect( hdr, section ); + if ( !r.isValid() ) + return false; + + if ( o == Horizontal ) + r.setLeft( QMAX( r.left(), leftMargin() ) ); + else + r.setTop( QMAX( r.top(), topMargin() ) ); + + myHeaderEditor = createHeaderEditor( hdr, section ); + if ( !myHeaderEditor ) + return false; + + myEditedHeader = hdr; + myEditedSection = section; + + myHeaderEditor->reparent( this, QPoint( 0, 0 ), false ); + + updateHeaderEditor(); + + myHeaderEditor->show(); + + myHeaderEditor->setActiveWindow(); + myHeaderEditor->setFocus(); + + myHeaderEditor->installEventFilter( this ); + + return true; +} + +void QtxTable::endHeaderEdit( const bool accept ) +{ + if ( !isHeaderEditing() ) + return; + + QString oldTxt = myEditedHeader ? myEditedHeader->label( myEditedSection ) : QString::null; + + if ( accept && myEditedHeader ) + setHeaderContentFromEditor( myEditedHeader, myEditedSection, myHeaderEditor ); + + QString newTxt = myEditedHeader ? myEditedHeader->label( myEditedSection ) : QString::null; + + int sec = myEditedSection; + QHeader* hdr = myEditedHeader; + + myEditedHeader = 0; + myEditedSection = -1; + + myHeaderEditor->hide(); + myHeaderEditor->deleteLater(); + myHeaderEditor = 0; + + if ( oldTxt != newTxt ) + { + emit headerEdited( hdr, sec ); + emit headerEdited( hdr == horizontalHeader() ? Horizontal : Vertical, sec ); + } +} + +bool QtxTable::isHeaderEditing() const +{ + return myHeaderEditor && myEditedHeader && myEditedSection != -1; +} + +QWidget* QtxTable::createHeaderEditor( QHeader* hdr, const int sec, const bool init ) +{ + QLineEdit* ed = new QLineEdit( 0 ); + + if ( init && hdr ) + ed->setText( hdr->label( sec ) ); + + return ed; +} + +void QtxTable::setHeaderContentFromEditor( QHeader* hdr, const int sec, QWidget* editor ) +{ + if ( !hdr || !editor ) + return; + + if ( editor->inherits( "QLineEdit" ) ) + hdr->setLabel( sec, ((QLineEdit*)editor)->text() ); +} + +QHeader* QtxTable::header( Orientation o ) const +{ + return o == Horizontal ? horizontalHeader() : verticalHeader(); +} + +void QtxTable::beginHeaderEdit( Orientation o, const QPoint& p ) +{ + QHeader* hdr = header( o ); + if ( !hdr ) + return; + + int pos = o == Horizontal ? p.x() : p.y(); + int sec = hdr->sectionAt( hdr->offset() + pos ); + + beginHeaderEdit( o, sec ); +} + +QRect QtxTable::headerSectionRect( QHeader* hdr, const int sec ) const +{ + QRect r( -1, -1, -1, -1 ); + + if ( !hdr ) + return r; + + r = hdr->sectionRect( sec ); + if ( r.isValid() ) + r = QRect( mapFromGlobal( hdr->mapToGlobal( r.topLeft() ) ), r.size() ); + + return r; +} + +void QtxTable::updateHeaderEditor() +{ + if ( !myHeaderEditor || !myEditedHeader || myEditedSection < 0 ) + return; + + QRect r = headerSectionRect( myEditedHeader, myEditedSection ); + if ( !r.isValid() ) + return; + + if ( myEditedHeader == horizontalHeader() ) + { + r.setLeft( QMAX( r.left(), leftMargin() ) ); + r.setRight( QMIN( r.right(), width() - rightMargin() - 2 ) ); + } + else + { + r.setTop( QMAX( r.top(), topMargin() ) ); + r.setBottom( QMIN( r.bottom(), height() - bottomMargin() - 2 ) ); + } + + myHeaderEditor->resize( r.size() ); + myHeaderEditor->move( r.topLeft() ); +} + +#endif diff --git a/src/Qtx/QtxTable.h b/src/Qtx/QtxTable.h new file mode 100644 index 000000000..bb8f5c0ef --- /dev/null +++ b/src/Qtx/QtxTable.h @@ -0,0 +1,88 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxTable.h +// Author: Sergey TELKOV + +#ifndef QTX_TABLE_H +#define QTX_TABLE_H + +#include "Qtx.h" + +#include + +#ifndef QT_NO_TABLE + +class QHeader; + +class QTX_EXPORT QtxTable : public QTable +{ + Q_OBJECT + + class HeaderEditor; + +public: + QtxTable( QWidget* = 0, const char* = 0 ); + QtxTable( int, int, QWidget* = 0, const char* = 0 ); + virtual ~QtxTable(); + + bool headerEditable( Orientation ) const; + + bool editHeader( Orientation, const int ); + void endEditHeader( const bool = true ); + + virtual bool eventFilter( QObject*, QEvent* ); + +signals: + void headerEdited( QHeader*, int ); + void headerEdited( Orientation, int ); + +public slots: + virtual void hide(); + virtual void setHeaderEditable( Orientation, bool ); + +private slots: + void onScrollBarMoved( int ); + void onHeaderSizeChange( int, int, int ); + +protected: + virtual void resizeEvent( QResizeEvent* ); + + virtual bool beginHeaderEdit( Orientation, const int ); + virtual void endHeaderEdit( const bool = true ); + bool isHeaderEditing() const; + virtual QWidget* createHeaderEditor( QHeader*, const int, const bool = true ); + virtual void setHeaderContentFromEditor( QHeader*, const int, QWidget* ); + + QHeader* header( Orientation o ) const; + +private: + void updateHeaderEditor(); + void beginHeaderEdit( Orientation, const QPoint& ); + QRect headerSectionRect( QHeader*, const int ) const; + +private: + QWidget* myHeaderEditor; + QHeader* myEditedHeader; + int myEditedSection; + QMap myHeaderEditable; +}; + +#endif + +#endif diff --git a/src/Qtx/QtxToolBar.cxx b/src/Qtx/QtxToolBar.cxx new file mode 100644 index 000000000..b5f32845e --- /dev/null +++ b/src/Qtx/QtxToolBar.cxx @@ -0,0 +1,364 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxToolBar.cxx +// Author: Sergey TELKOV + +#include "QtxToolBar.h" + +#include +#include +#include +#include +#include +#include + +/*! + Class: QtxToolBar::Watcher [Internal] + Descr: Internal object with event filter. +*/ + +class QtxToolBar::Watcher : public QObject +{ +public: + Watcher( QtxToolBar* ); + + void shown( QtxToolBar* ); + void hided( QtxToolBar* ); + + virtual bool eventFilter( QObject*, QEvent* ); + +protected: + virtual void customEvent( QCustomEvent* ); + +private: + enum { Install = QEvent::User, Update }; + +private: + void installFilters(); + + void showContainer(); + void hideContainer(); + + void updateIcon(); + void updateCaption(); + void updateVisibility(); + +private: + QtxToolBar* myCont; + bool myState; + bool myEmpty; + bool myVisible; +}; + +QtxToolBar::Watcher::Watcher( QtxToolBar* cont ) +: QObject( cont ), +myCont( cont ), +myState( true ), +myEmpty( true ) +{ + if ( myCont->mainWindow() ) + myState = myCont->mainWindow()->appropriate( myCont ); + + myCont->installEventFilter( this ); + myVisible = myCont->isVisibleTo( myCont->parentWidget() ); + + installFilters(); +} + +bool QtxToolBar::Watcher::eventFilter( QObject* o, QEvent* e ) +{ + if ( o == myCont && e->type() == QEvent::ChildInserted ) + QApplication::postEvent( this, new QCustomEvent( Install ) ); + + if ( o != myCont && e->type() == QEvent::IconChange ) + updateIcon(); + + if ( o != myCont && e->type() == QEvent::CaptionChange ) + updateCaption(); + + bool updVis = ( o != myCont && ( e->type() == QEvent::Show || e->type() == QEvent::ShowToParent || + e->type() == QEvent::Hide || e->type() == QEvent::HideToParent ) ) || + ( o == myCont && ( e->type() == QEvent::ChildRemoved || e->type() == QEvent::Show || e->type() == QEvent::ShowToParent ) ); + + if ( updVis ) + { + QtxToolBar* cont = myCont; + myCont = 0; + QApplication::sendPostedEvents( this, Update ); + myCont = cont; + QApplication::postEvent( this, new QCustomEvent( Update ) ); + } + + return false; +} + +void QtxToolBar::Watcher::shown( QtxToolBar* tb ) +{ + if ( tb != myCont ) + return; + + myVisible = true; +} + +void QtxToolBar::Watcher::hided( QtxToolBar* tb ) +{ + if ( tb != myCont ) + return; + + myVisible = false; +} + +void QtxToolBar::Watcher::showContainer() +{ + if ( !myCont ) + return; + + QtxToolBar* cont = myCont; + myCont = 0; + cont->show(); + myCont = cont; +} + +void QtxToolBar::Watcher::hideContainer() +{ + if ( !myCont ) + return; + + QtxToolBar* cont = myCont; + myCont = 0; + cont->hide(); + myCont = cont; +} + +void QtxToolBar::Watcher::customEvent( QCustomEvent* e ) +{ + switch ( e->type() ) + { + case Install: + installFilters(); + updateIcon(); + updateCaption(); + case Update: + updateVisibility(); + } +} + +void QtxToolBar::Watcher::installFilters() +{ + if ( !myCont ) + return; + + const QObjectList* objList = myCont->children(); + if ( !objList ) + return; + + for ( QObjectListIt it( *objList ); it.current(); ++it ) + { + if ( it.current()->isWidgetType() && + qstrcmp( "qt_dockwidget_internal", it.current()->name() ) ) + it.current()->installEventFilter( this ); + } +} + +void QtxToolBar::Watcher::updateVisibility() +{ + if ( !myCont ) + return; + + bool vis = false; + + const QObjectList* objList = myCont->children(); + if ( objList ) + { + for ( QObjectListIt it( *objList ); it.current() && !vis; ++it ) + { + if ( !it.current()->isWidgetType() || + !qstrcmp( "qt_dockwidget_internal", it.current()->name() ) ) + continue; + + QWidget* wid = (QWidget*)it.current(); + vis = wid->isVisibleTo( wid->parentWidget() ); + } + } + + QMainWindow* mw = myCont->mainWindow(); + if ( mw && myEmpty == vis ) + { + myEmpty = !vis; + if ( !myEmpty ) + mw->setAppropriate( myCont, myState ); + else + { + myState = mw->appropriate( myCont ); + mw->setAppropriate( myCont, false ); + } + } + + vis = !myEmpty && myVisible; + if ( vis != myCont->isVisibleTo( myCont->parentWidget() ) ) + vis ? showContainer() : hideContainer(); +} + +void QtxToolBar::Watcher::updateIcon() +{ + if ( !myCont || !myCont->widget() ) + return; + + const QPixmap* ico = myCont->widget()->icon(); + myCont->setIcon( ico ? *ico : QPixmap() ); +} + +void QtxToolBar::Watcher::updateCaption() +{ + if ( myCont && myCont->widget() && !myCont->widget()->caption().isNull() ) + myCont->setCaption( myCont->widget()->caption() ); +} + +/*! + Class: QtxToolBar [Public] + Descr: +*/ + +QtxToolBar::QtxToolBar( const bool watch, const QString& label, QMainWindow* main, + QWidget* parent, bool newLine, const char* name, WFlags f ) +: QToolBar( label, main, parent, newLine, name, f ), +myWatcher( 0 ), +myStretch( false ) +{ + if ( watch ) + myWatcher = new Watcher( this ); +} + +QtxToolBar::QtxToolBar( const QString& label, QMainWindow* main, + QWidget* parent, bool newLine, const char* name, WFlags f ) +: QToolBar( label, main, parent, newLine, name, f ), +myWatcher( 0 ), +myStretch( false ) +{ +} + +QtxToolBar::QtxToolBar( const bool watch, QMainWindow* main, const char* name ) +: QToolBar( main, name ), +myWatcher( 0 ), +myStretch( false ) +{ + if ( watch ) + myWatcher = new Watcher( this ); +} + +QtxToolBar::QtxToolBar( QMainWindow* main, const char* name ) +: QToolBar( main, name ), +myWatcher( 0 ), +myStretch( false ) +{ +} + +QtxToolBar::~QtxToolBar() +{ +} + +void QtxToolBar::setWidget( QWidget* wid ) +{ + if ( wid ) + wid->reparent( this, QPoint( 0, 0 ), wid->isVisibleTo( wid->parentWidget() ) ); + + QToolBar::setWidget( wid ); + + if ( !boxLayout() ) + return; + + for ( QLayoutIterator it = boxLayout()->iterator(); it.current(); ++it ) + { + if ( it.current()->widget() == wid ) + { + it.deleteCurrent(); + break; + } + } +} + +bool QtxToolBar::isStretchable() const +{ + return myStretch; +} + +void QtxToolBar::setStretchable( const bool on ) +{ + if ( myStretch == on ) + return; + + myStretch = on; + + boxLayout()->setStretchFactor( widget(), myStretch ? 1 : 0 ); + + if ( myStretch != isHorizontalStretchable() || + myStretch != isVerticalStretchable() ) + { + if ( orientation() == Horizontal ) + setHorizontalStretchable( myStretch ); + else + setVerticalStretchable( myStretch ); + } +} + +QSize QtxToolBar::sizeHint() const +{ + QSize sz = QToolBar::sizeHint(); + + if ( place() == InDock && isStretchable() && area() ) + { + if ( orientation() == Horizontal ) + sz.setWidth( area()->width() ); + else + sz.setHeight( area()->height() ); + } + + return sz; +} + +QSize QtxToolBar::minimumSizeHint() const +{ + QSize sz = QToolBar::minimumSizeHint(); + + if ( place() == InDock && isStretchable() && area() ) + { + if ( orientation() == Horizontal ) + sz.setWidth( area()->width() ); + else + sz.setHeight( area()->height() ); + } + + return sz; +} + +void QtxToolBar::show() +{ + if ( myWatcher ) + myWatcher->shown( this ); + + QToolBar::show(); +} + +void QtxToolBar::hide() +{ + if ( myWatcher ) + myWatcher->hided( this ); + + QToolBar::hide(); +} diff --git a/src/Qtx/QtxToolBar.h b/src/Qtx/QtxToolBar.h new file mode 100644 index 000000000..851f4d9cb --- /dev/null +++ b/src/Qtx/QtxToolBar.h @@ -0,0 +1,54 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxToolBar.h +// Author: Sergey TELKOV + +#include "Qtx.h" + +#include + +class QTX_EXPORT QtxToolBar : public QToolBar +{ + Q_OBJECT + + class Watcher; + +public: + QtxToolBar( const bool, const QString&, QMainWindow*, QWidget*, bool = false, const char* = 0, WFlags = 0 ); + QtxToolBar( const QString&, QMainWindow*, QWidget*, bool = false, const char* = 0, WFlags = 0 ); + QtxToolBar( const bool, QMainWindow* = 0, const char* = 0 ); + QtxToolBar( QMainWindow* = 0, const char* = 0 ); + virtual ~QtxToolBar(); + + virtual void setWidget( QWidget* ); + + bool isStretchable() const; + virtual void setStretchable( const bool ); + + virtual QSize sizeHint() const; + virtual QSize minimumSizeHint() const; + +public slots: + virtual void show(); + virtual void hide(); + +private: + Watcher* myWatcher; + bool myStretch; +}; diff --git a/src/Qtx/QtxToolTip.cxx b/src/Qtx/QtxToolTip.cxx new file mode 100755 index 000000000..0365ba135 --- /dev/null +++ b/src/Qtx/QtxToolTip.cxx @@ -0,0 +1,210 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxToolTip.cxx +// Author: Sergey TELKOV + +#include "QtxToolTip.h" + +#include +#include +#include +#include +#include + +#define TOOLTIP_SHOW_DELAY 0500 +#define TOOLTIP_HIDE_DELAY 7000 + +QtxToolTip::QtxToolTip( QWidget* parent ) +: QLabel( parent, "", WStyle_Customize | WStyle_NoBorder | WStyle_Tool | WStyle_StaysOnTop | WType_TopLevel ) +{ + setIndent( 3 ); + setAlignment( Qt::AlignLeft | Qt::AlignVCenter ); + setBackgroundColor( QColor( 255, 255, 231 ) ); + + myWidgetRegion = QRect( -1, -1, -1, -1 ); + + setFrameShape( QFrame::Panel ); + setFrameShadow( QFrame::Plain ); + + parent->setMouseTracking( true ); + parent->installEventFilter( this ); + installEventFilter( this ); + + mySleepTimer = new QTimer( this ); + myWakeUpTimer = new QTimer( this ); + connect( mySleepTimer, SIGNAL( timeout() ), this, SLOT( onSleepTimeOut() ) ); + connect( myWakeUpTimer, SIGNAL( timeout() ), this, SLOT( onWakeUpTimeOut() ) ); + + myWakeUpDelayTime = 700; + myShowDelayTime = 5000; +} + +QtxToolTip::~QtxToolTip() +{ +} + +bool QtxToolTip::eventFilter( QObject* o, QEvent* e ) +{ + if ( ( e->type() == QEvent::Destroy ) || ( e->type() == QEvent::Close ) || ( e->type() == QEvent::Hide ) ) + { + hideTip(); + } + if ( e->type() == QEvent::Leave ) + { + if ( isVisible() && ( o == this ) ) + hideTip(); + myWakeUpTimer->stop(); + } + if ( e->type() == QEvent::MouseMove ) + { + QMouseEvent* me = (QMouseEvent*)e; + QPoint thePos = parentWidget()->mapFromGlobal( me->globalPos() ); + if ( myWakeUpTimer->isActive() ) + { + myWakeUpTimer->stop(); + myWakeUpTimer->start( myWakeUpDelayTime, true ); + } + if ( isVisible() ) + { + if ( !myWidgetRegion.contains( thePos ) ) + { + hideTip(); + myWidgetRegion = QRect( -1, -1, -1, -1 ); + } + } + else + { + if ( !myWidgetRegion.isValid() || myWidgetRegion.contains( thePos ) ) + myWakeUpTimer->start( myWakeUpDelayTime, true ); + } + } + if ( e->type() == QEvent::KeyPress ) + { + hideTip(); + } + if ( o == parent() && ( e->type() == QEvent::MouseButtonPress || + e->type() == QEvent::MouseButtonRelease ) ) + { + hideTip(); + } + return false; +} + +void QtxToolTip::showTip( const QPoint& aPos, const QString& text, const QRect& aWidgetRegion ) +{ + QFontMetrics theFM = fontMetrics(); + int theHeight = theFM.height(); + int theWidth = theFM.width( text ) + 2; + showTip( QRect( QPoint( aPos.x(), aPos.y() + 10 ), QSize( theWidth, theHeight ) ), text, aWidgetRegion ); +} + +void QtxToolTip::showTip( const QRect& aRegion, const QString& text, const QRect& aWidgetRegion ) +{ + setText( text ); + myWidgetRegion = aWidgetRegion; + setGeometry( aRegion ); + if ( myShowDelayTime != 0 ) + mySleepTimer->start( myShowDelayTime, true ); + show(); +} + +void QtxToolTip::hideTip() +{ + hide(); + myWidgetRegion = QRect( -1, -1, -1, -1 ); + mySleepTimer->stop(); +} + +void QtxToolTip::maybeTip( const QPoint& pos ) +{ + QString text; + QRect textRegion, theRegion( -1, -1, -1, -1 ); + QFont theFnt = font(); + + emit maybeTip( pos, text, theFnt, textRegion, theRegion ); + + if ( theRegion.isValid() ) + { + setFont( theFnt ); + int margin = lineWidth() + indent(); + QRect dspRegion( QPoint( textRegion.x() - margin, textRegion.y() ), + QSize( textRegion.width() + 2 * margin, textRegion.height() ) ); + QRect tipRegion( parentWidget()->mapToGlobal( dspRegion.topLeft() ), dspRegion.size() ); + if ( tipRegion.left() < 0 ) + tipRegion.moveBy( -1 * tipRegion.left(), 0 ); + showTip( tipRegion, text, theRegion ); + } +} + +void QtxToolTip::onSleepTimeOut() +{ + mySleepTimer->stop(); + hideTip(); +} + +void QtxToolTip::onWakeUpTimeOut() +{ + myWakeUpTimer->stop(); + QPoint pos = QCursor::pos(); + if ( parentWidget() ) + pos = parentWidget()->mapFromGlobal( pos ); + maybeTip( pos ); +} + +void QtxToolTip::mousePressEvent( QMouseEvent* e ) +{ + hideTip(); + QWidget* reciever = parentWidget(); + QMouseEvent* me = new QMouseEvent( QEvent::MouseButtonPress, + reciever->mapFromGlobal( e->globalPos() ), + e->button(), e->state() ); + QApplication::sendEvent( reciever, me ); +} + +void QtxToolTip::mouseDoubleClickEvent( QMouseEvent* e ) +{ + hideTip(); + QWidget* reciever = parentWidget(); + QMouseEvent* me = new QMouseEvent( QEvent::MouseButtonDblClick, + reciever->mapFromGlobal( e->globalPos() ), + e->button(), e->state() ); + QApplication::sendEvent( reciever, me ); +} + +void QtxToolTip::setWakeUpDelayTime( int theTime ) +{ + if( !(theTime < 0) ) + myWakeUpDelayTime = theTime; +} + +void QtxToolTip::setShowDelayTime( int theTime ) +{ + if( !(theTime < 0) ) + myShowDelayTime = theTime; +} + +QTimer* QtxToolTip::sleepTimer() const +{ + return mySleepTimer; +} + +QTimer* QtxToolTip::wakeUpTimer() const +{ + return myWakeUpTimer; +} diff --git a/src/Qtx/QtxToolTip.h b/src/Qtx/QtxToolTip.h new file mode 100755 index 000000000..0901137e9 --- /dev/null +++ b/src/Qtx/QtxToolTip.h @@ -0,0 +1,78 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxToolTip.h +// Author: Sergey TELKOV + +#ifndef QTXTOOLTIP_H +#define QTXTOOLTIP_H + +#include "Qtx.h" + +#include + +class QTimer; + +class QTX_EXPORT QtxToolTip : public QLabel +{ + Q_OBJECT + +public: + QtxToolTip( QWidget* = 0 ); + virtual ~QtxToolTip(); + + void hideTip(); + + virtual void showTip( const QPoint& aPos, + const QString& text, const QRect& aWidgetRegion ); + virtual void showTip( const QRect& aRegion, + const QString& text, const QRect& aWidgetRegion ); + + virtual bool eventFilter( QObject* o, QEvent* e ); + + void setWakeUpDelayTime( int ); + void setShowDelayTime( int ); + + int wakeUpDelayTime() const { return myWakeUpDelayTime; } + int showDelayTime() const { return myShowDelayTime; } + +signals: + void maybeTip( QPoint, QString&, QFont&, QRect&, QRect& ); + +protected slots: + void onSleepTimeOut(); + void onWakeUpTimeOut(); + +protected: + virtual void maybeTip( const QPoint& ); + virtual void mousePressEvent( QMouseEvent* ); + virtual void mouseDoubleClickEvent( QMouseEvent* ); + + QTimer* sleepTimer() const; + QTimer* wakeUpTimer() const; + +private: + QTimer* myWakeUpTimer; + QTimer* mySleepTimer; + QRect myWidgetRegion; + + int myShowDelayTime; + int myWakeUpDelayTime; +}; + +#endif diff --git a/src/Qtx/QtxWorkspaceAction.cxx b/src/Qtx/QtxWorkspaceAction.cxx new file mode 100644 index 000000000..c630ff47d --- /dev/null +++ b/src/Qtx/QtxWorkspaceAction.cxx @@ -0,0 +1,419 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxWorkspaceAction.cxx +// Author: Sergey TELKOV + +#include "QtxWorkspaceAction.h" + +#include +#include +#include + +QtxWorkspaceAction::QtxWorkspaceAction( QWorkspace* ws, QObject* parent, const char* name ) +: QtxAction( tr( "Controls windows into workspace" ), tr( "Workspace management" ), 0, parent, name ), +myFlags( Standard ), +myWorkspace( ws ) +{ + myItem.insert( Cascade, new QtxAction( tr( "Arranges the windows as overlapping tiles" ), + tr( "Cascade" ), 0, this, 0, false ) ); + myItem.insert( Tile, new QtxAction( tr( "Arranges the windows as nonoverlapping tiles" ), + tr( "Tile" ), 0, this, 0, false ) ); + myItem.insert( HTile, new QtxAction( tr( "Arranges the windows as nonoverlapping horizontal tiles" ), + tr( "Tile horizontally" ), 0, this, 0, false ) ); + myItem.insert( VTile, new QtxAction( tr( "Arranges the windows as nonoverlapping vertical tiles" ), + tr( "Tile vertically" ), 0, this, 0, false ) ); + + connect( myItem[Tile], SIGNAL( activated() ), this, SLOT( tile() ) ); + connect( myItem[Cascade], SIGNAL( activated() ), this, SLOT( cascade() ) ); + connect( myItem[HTile], SIGNAL( activated() ), this, SLOT( tileVertical() ) ); + connect( myItem[VTile], SIGNAL( activated() ), this, SLOT( tileHorizontal() ) ); +} + +QtxWorkspaceAction::~QtxWorkspaceAction() +{ +} + +QWorkspace* QtxWorkspaceAction::workspace() const +{ + return myWorkspace; +} + +int QtxWorkspaceAction::items() const +{ + return myFlags; +} + +void QtxWorkspaceAction::setItems( const int flags ) +{ + if ( !flags || flags == myFlags || !( flags & Operations ) ) + return; + + myFlags = flags; +} + +bool QtxWorkspaceAction::hasItems( const int flags ) const +{ + return ( myFlags & flags ) == flags; +} + +int QtxWorkspaceAction::accel( const int id ) const +{ + int a = 0; + if ( myItem.contains( id ) ) + a = myItem[id]->accel(); + return a; +} + +QIconSet QtxWorkspaceAction::iconSet( const int id ) const +{ + QIconSet ico; + if ( myItem.contains( id ) ) + ico = myItem[id]->iconSet(); + return ico; +} + +QString QtxWorkspaceAction::menuText( const int id ) const +{ + QString txt; + if ( myItem.contains( id ) ) + txt = myItem[id]->menuText(); + return txt; +} + +QString QtxWorkspaceAction::statusTip( const int id ) const +{ + QString txt; + if ( myItem.contains( id ) ) + txt = myItem[id]->statusTip(); + return txt; +} + +void QtxWorkspaceAction::setAccel( const int id, const int a ) +{ + if ( myItem.contains( id ) ) + myItem[id]->setAccel( a ); +} + +void QtxWorkspaceAction::setIconSet( const int id, const QIconSet& ico ) +{ + if ( myItem.contains( id ) ) + myItem[id]->setIconSet( ico ); +} + +void QtxWorkspaceAction::setMenuText( const int id, const QString& txt ) +{ + if ( myItem.contains( id ) ) + myItem[id]->setMenuText( txt ); +} + +void QtxWorkspaceAction::setStatusTip( const int id, const QString& txt ) +{ + if ( myItem.contains( id ) ) + myItem[id]->setStatusTip( txt ); +} + +bool QtxWorkspaceAction::addTo( QWidget* wid ) +{ + return addTo( wid, -1 ); +} + +bool QtxWorkspaceAction::addTo( QWidget* wid, const int idx ) +{ + if ( !wid || !wid->inherits( "QPopupMenu" ) ) + return false; + + QPopupMenu* pm = (QPopupMenu*)wid; + checkPopup( pm ); + + if ( myMenu.contains( pm ) ) + return false; + + myMenu.insert( pm, QIntList() ); + fillPopup( pm, idx ); + + connect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) ); + connect( pm, SIGNAL( destroyed( QObject* ) ), this, SLOT( onPopupDestroyed( QObject* ) ) ); + + return true; +} + +bool QtxWorkspaceAction::removeFrom( QWidget* wid ) +{ + if ( !wid || !wid->inherits( "QPopupMenu" ) ) + return false; + + QPopupMenu* pm = (QPopupMenu*)wid; + if ( !myMenu.contains( pm ) ) + return false; + + clearPopup( pm ); + + disconnect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) ); + disconnect( pm, SIGNAL( destroyed( QObject* ) ), this, SLOT( onPopupDestroyed( QObject* ) ) ); + + myMenu.remove( pm ); + + return true; +} + +void QtxWorkspaceAction::perform( const int type ) +{ + switch ( type ) + { + case Cascade: + cascade(); + break; + case Tile: + tile(); + break; + case VTile: + tileVertical(); + break; + case HTile: + tileHorizontal(); + break; + } +} + +void QtxWorkspaceAction::tile() +{ + QWorkspace* ws = workspace(); + if ( !ws ) + return; + + ws->tile(); +} + +void QtxWorkspaceAction::cascade() +{ + QWorkspace* ws = workspace(); + if ( !ws ) + return; + + ws->cascade(); + + int w = ws->width(); + int h = ws->height(); + + QWidgetList winList = ws->windowList(); + for ( QWidgetListIt it( winList ); it.current(); ++it ) + it.current()->resize( int( w * 0.8 ), int( h * 0.8 ) ); +} + +void QtxWorkspaceAction::tileVertical() +{ + QWorkspace* wrkSpace = workspace(); + if ( !wrkSpace ) + return; + + QWidgetList winList = wrkSpace->windowList(); + if ( winList.isEmpty() ) + return; + + int count = 0; + for ( QWidgetListIt itr( winList ); itr.current(); ++itr ) + if ( !itr.current()->testWState( WState_Minimized ) ) + count++; + + if ( !count ) + return; + + int y = 0; + + int heightForEach = wrkSpace->height() / count; + for ( QWidgetListIt it( winList ); it.current(); ++it ) + { + QWidget* win = it.current(); + if ( win->testWState( WState_Minimized ) ) + continue; + + if ( win->testWState( WState_Maximized ) ) + { + win->hide(); + win->showNormal(); + } + int prefH = win->minimumHeight() + win->parentWidget()->baseSize().height(); + int actualH = QMAX( heightForEach, prefH ); + + win->parentWidget()->setGeometry( 0, y, wrkSpace->width(), actualH ); + y += actualH; + } +} + +void QtxWorkspaceAction::tileHorizontal() +{ + QWorkspace* wrkSpace = workspace(); + if ( !wrkSpace ) + return; + + QWidgetList winList = wrkSpace->windowList(); + if ( winList.isEmpty() ) + return; + + int count = 0; + for ( QWidgetListIt itr( winList ); itr.current(); ++itr ) + if ( !itr.current()->testWState( WState_Minimized ) ) + count++; + + if ( !count ) + return; + + int x = 0; + int widthForEach = wrkSpace->width() / count; + for ( QWidgetListIt it( winList ); it.current(); ++it ) + { + QWidget* win = it.current(); + if ( win->testWState( WState_Minimized ) ) + continue; + + if ( win->testWState( WState_Maximized ) ) + { + win->hide(); + win->showNormal(); + } + int prefW = win->minimumWidth(); + int actualW = QMAX( widthForEach, prefW ); + + win->parentWidget()->setGeometry( x, 0, actualW, wrkSpace->height() ); + x += actualW; + } +} + +void QtxWorkspaceAction::onAboutToShow() +{ + const QObject* obj = sender(); + if ( !obj || !obj->inherits( "QPopupMenu" ) ) + return; + + updatePopup( (QPopupMenu*)obj ); +} + +void QtxWorkspaceAction::onPopupDestroyed( QObject* obj ) +{ + myMenu.remove( (QPopupMenu*)obj ); +} + +void QtxWorkspaceAction::checkPopup( QPopupMenu* pm ) +{ + if ( !myMenu.contains( pm ) ) + return; + + QIntList updList; + for ( QIntList::const_iterator it = myMenu[pm].begin(); it != myMenu[pm].end(); ++it ) + { + if ( pm->indexOf( *it ) != -1 ) + updList.append( *it ); + } + + myMenu.remove( pm ); + + if ( !updList.isEmpty() ) + myMenu.insert( pm, updList ); + else + { + disconnect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) ); + disconnect( pm, SIGNAL( destroyed( QObject* ) ), this, SLOT( onPopupDestroyed( QObject* ) ) ); + } +} + +void QtxWorkspaceAction::updatePopup( QPopupMenu* pm ) +{ + if ( !myMenu.contains( pm ) ) + return; + + fillPopup( pm, clearPopup( pm ) ); + + bool count = workspace() ? workspace()->windowList().count() : 0; + myItem[Cascade]->setEnabled( count ); + myItem[Tile]->setEnabled( count ); + myItem[HTile]->setEnabled( count ); + myItem[VTile]->setEnabled( count ); +} + +int QtxWorkspaceAction::clearPopup( QPopupMenu* pm ) +{ + if ( !myMenu.contains( pm ) ) + return -1; + + int idx = -1; + const QIntList& lst = myMenu[pm]; + for ( QIntList::const_iterator it = lst.begin(); it != lst.end() && idx == -1; ++it ) + idx = pm->indexOf( *it ); + + for ( ItemMap::ConstIterator mit = myItem.begin(); mit != myItem.end(); ++mit ) + mit.data()->removeFrom( pm ); + + for ( QIntList::const_iterator itr = lst.begin(); itr != lst.end(); ++itr ) + pm->removeItem( *itr ); + + return idx; +} + +void QtxWorkspaceAction::fillPopup( QPopupMenu* pm, const int idx ) +{ + if ( !pm ) + return; + + int index = idx < 0 ? pm->count() : QMIN( (int)pm->count(), idx ); + + myMenu.insert( pm, QIntList() ); + QIntList& lst = myMenu[pm]; + + for ( ItemMap::ConstIterator mit = myItem.begin(); mit != myItem.end(); ++mit ) + { + if ( !hasItems( mit.key() ) ) + continue; + + mit.data()->addTo( pm, index ); + lst.append( pm->idAt( index++ ) ); + } + + QWorkspace* ws = workspace(); + if ( !ws || !hasItems( Windows ) ) + return; + + QWidgetList wList = ws->windowList(); + if ( wList.isEmpty() ) + return; + + lst.append( pm->insertSeparator( index++ ) ); + + int param = 0; + pm->setCheckable( true ); + for ( QWidgetListIt it( wList ); it.current(); ++it ) + { + int id = pm->insertItem( it.current()->caption(), this, SLOT( onItemActivated( int ) ), 0, -1, index++ ); + pm->setItemParameter( id, param++ ); + pm->setItemChecked( id, it.current() == ws->activeWindow() ); + lst.append( id ); + } +} + +void QtxWorkspaceAction::onItemActivated( int idx ) +{ + QWorkspace* ws = workspace(); + if ( !ws ) + return; + + QWidgetList wList = ws->windowList(); + if ( idx < 0 || idx >= (int)wList.count() ) + return; + + wList.at( idx )->setFocus(); +} diff --git a/src/Qtx/QtxWorkspaceAction.h b/src/Qtx/QtxWorkspaceAction.h new file mode 100644 index 000000000..3df49c798 --- /dev/null +++ b/src/Qtx/QtxWorkspaceAction.h @@ -0,0 +1,106 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxWorkspaceAction.h +// Author: Sergey TELKOV + +#ifndef QTXWORKSPACEACTION_H +#define QTXWORKSPACEACTION_H + +#include "QtxAction.h" + +class QWorkspace; + +#ifdef WIN32 +#pragma warning( disable:4251 ) +#endif + +class QTX_EXPORT QtxWorkspaceAction : public QtxAction +{ + Q_OBJECT + +public: + enum { Cascade = 0x0001, + Tile = 0x0002, + VTile = 0x0004, + HTile = 0x0008, + Windows = 0x0010, + Standard = Cascade | Tile | Windows, + Operations = Cascade | Tile | VTile | HTile, + All = Standard | HTile | VTile }; + +public: + QtxWorkspaceAction( QWorkspace*, QObject* = 0, const char* = 0 ); + virtual ~QtxWorkspaceAction(); + + QWorkspace* workspace() const; + + int items() const; + void setItems( const int ); + bool hasItems( const int ) const; + + int accel( const int ) const; + QIconSet iconSet( const int ) const; + QString menuText( const int ) const; + QString statusTip( const int ) const; + + void setAccel( const int, const int ); + void setIconSet( const int, const QIconSet& ); + void setMenuText( const int, const QString& ); + void setStatusTip( const int, const QString& ); + + virtual bool addTo( QWidget* ); + virtual bool addTo( QWidget*, const int ); + virtual bool removeFrom( QWidget* ); + + void perform( const int ); + +public slots: + void tile(); + void cascade(); + void tileVertical(); + void tileHorizontal(); + +private slots: + void onAboutToShow(); + void onItemActivated( int ); + void onPopupDestroyed( QObject* ); + +private: + void checkPopup( QPopupMenu* ); + void updatePopup( QPopupMenu* ); + + int clearPopup( QPopupMenu* ); + void fillPopup( QPopupMenu*, const int ); + +private: + typedef QMap MenuMap; + typedef QMap ItemMap; + +private: + MenuMap myMenu; + ItemMap myItem; + int myFlags; + QWorkspace* myWorkspace; +}; + +#ifdef WIN32 +#pragma warning( default:4251 ) +#endif + +#endif diff --git a/src/Qtx/QtxWorkstackAction.cxx b/src/Qtx/QtxWorkstackAction.cxx new file mode 100644 index 000000000..c26a9b0aa --- /dev/null +++ b/src/Qtx/QtxWorkstackAction.cxx @@ -0,0 +1,308 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxWorkstackAction.cxx +// Author: Sergey TELKOV + +#include "QtxWorkstackAction.h" + +#include "QtxWorkstack.h" + +#include +#include + +QtxWorkstackAction::QtxWorkstackAction( QtxWorkstack* ws, QObject* parent, const char* name ) +: QtxAction( tr( "Controls windows into workstack" ), tr( "Workstack management" ), 0, parent, name ), +myFlags( Standard ), +myWorkstack( ws ) +{ + myItem.insert( VSplit, new QtxAction( tr( "Split the active window on two vertical parts" ), + tr( "Split vertically" ), 0, this, 0, false ) ); + myItem.insert( HSplit, new QtxAction( tr( "Split the active window on two horizontal parts" ), + tr( "Split horizontally" ), 0, this, 0, false ) ); + + connect( myItem[VSplit], SIGNAL( activated() ), ws, SLOT( splitVertical() ) ); + connect( myItem[HSplit], SIGNAL( activated() ), ws, SLOT( splitHorizontal() ) ); +} + +QtxWorkstackAction::~QtxWorkstackAction() +{ +} + +QtxWorkstack* QtxWorkstackAction::workstack() const +{ + return myWorkstack; +} + +int QtxWorkstackAction::items() const +{ + return myFlags; +} + +void QtxWorkstackAction::setItems( const int flags ) +{ + if ( !flags || flags == myFlags || !( flags & Split ) ) + return; + + myFlags = flags; +} + +bool QtxWorkstackAction::hasItems( const int flags ) const +{ + return ( myFlags & flags ) == flags; +} + +int QtxWorkstackAction::accel( const int id ) const +{ + int a = 0; + if ( myItem.contains( id ) ) + a = myItem[id]->accel(); + return a; +} + +QIconSet QtxWorkstackAction::iconSet( const int id ) const +{ + QIconSet ico; + if ( myItem.contains( id ) ) + ico = myItem[id]->iconSet(); + return ico; +} + +QString QtxWorkstackAction::menuText( const int id ) const +{ + QString txt; + if ( myItem.contains( id ) ) + txt = myItem[id]->menuText(); + return txt; +} + +QString QtxWorkstackAction::statusTip( const int id ) const +{ + QString txt; + if ( myItem.contains( id ) ) + txt = myItem[id]->statusTip(); + return txt; +} + +void QtxWorkstackAction::setAccel( const int id, const int a ) +{ + if ( myItem.contains( id ) ) + myItem[id]->setAccel( a ); +} + +void QtxWorkstackAction::setIconSet( const int id, const QIconSet& ico ) +{ + if ( myItem.contains( id ) ) + myItem[id]->setIconSet( ico ); +} + +void QtxWorkstackAction::setMenuText( const int id, const QString& txt ) +{ + if ( myItem.contains( id ) ) + myItem[id]->setMenuText( txt ); +} + +void QtxWorkstackAction::setStatusTip( const int id, const QString& txt ) +{ + if ( myItem.contains( id ) ) + myItem[id]->setStatusTip( txt ); +} + +bool QtxWorkstackAction::addTo( QWidget* wid ) +{ + return addTo( wid, -1 ); +} + +bool QtxWorkstackAction::addTo( QWidget* wid, const int idx ) +{ + if ( !wid || !wid->inherits( "QPopupMenu" ) ) + return false; + + QPopupMenu* pm = (QPopupMenu*)wid; + checkPopup( pm ); + + if ( myMenu.contains( pm ) ) + return false; + + myMenu.insert( pm, QIntList() ); + fillPopup( pm, idx ); + + connect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) ); + connect( pm, SIGNAL( destroyed( QObject* ) ), this, SLOT( onPopupDestroyed( QObject* ) ) ); + + return true; +} + +bool QtxWorkstackAction::removeFrom( QWidget* wid ) +{ + if ( !wid || !wid->inherits( "QPopupMenu" ) ) + return false; + + QPopupMenu* pm = (QPopupMenu*)wid; + if ( !myMenu.contains( pm ) ) + return false; + + clearPopup( pm ); + + disconnect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) ); + disconnect( pm, SIGNAL( destroyed( QObject* ) ), this, SLOT( onPopupDestroyed( QObject* ) ) ); + + myMenu.remove( pm ); + + return true; +} + +void QtxWorkstackAction::perform( const int type ) +{ + switch ( type ) + { + case VSplit: + workstack()->splitVertical(); + break; + case HSplit: + workstack()->splitHorizontal(); + break; + } +} + +void QtxWorkstackAction::onAboutToShow() +{ + const QObject* obj = sender(); + if ( !obj || !obj->inherits( "QPopupMenu" ) ) + return; + + QtxWorkstack* ws = workstack(); + if ( ws && myItem.contains( VSplit ) ) + myItem[VSplit]->setAccel( ws->accel( QtxWorkstack::SplitVertical ) ); + if ( ws && myItem.contains( HSplit ) ) + myItem[HSplit]->setAccel( ws->accel( QtxWorkstack::SplitHorizontal ) ); + + updatePopup( (QPopupMenu*)obj ); +} + +void QtxWorkstackAction::onPopupDestroyed( QObject* obj ) +{ + myMenu.remove( (QPopupMenu*)obj ); +} + +void QtxWorkstackAction::checkPopup( QPopupMenu* pm ) +{ + if ( !myMenu.contains( pm ) ) + return; + + QIntList updList; + for ( QIntList::const_iterator it = myMenu[pm].begin(); it != myMenu[pm].end(); ++it ) + { + if ( pm->indexOf( *it ) != -1 ) + updList.append( *it ); + } + + myMenu.remove( pm ); + + if ( !updList.isEmpty() ) + myMenu.insert( pm, updList ); + else + { + disconnect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) ); + disconnect( pm, SIGNAL( destroyed( QObject* ) ), this, SLOT( onPopupDestroyed( QObject* ) ) ); + } +} + +void QtxWorkstackAction::updatePopup( QPopupMenu* pm ) +{ + if ( !myMenu.contains( pm ) ) + return; + + fillPopup( pm, clearPopup( pm ) ); + + int count = workstack() ? workstack()->splitWindowList().count() : 0; + myItem[VSplit]->setEnabled( count > 1 ); + myItem[HSplit]->setEnabled( count > 1 ); +} + +int QtxWorkstackAction::clearPopup( QPopupMenu* pm ) +{ + if ( !myMenu.contains( pm ) ) + return -1; + + int idx = -1; + const QIntList& lst = myMenu[pm]; + for ( QIntList::const_iterator it = lst.begin(); it != lst.end() && idx == -1; ++it ) + idx = pm->indexOf( *it ); + + for ( ItemMap::ConstIterator mit = myItem.begin(); mit != myItem.end(); ++mit ) + mit.data()->removeFrom( pm ); + + for ( QIntList::const_iterator itr = lst.begin(); itr != lst.end(); ++itr ) + pm->removeItem( *itr ); + + return idx; +} + +void QtxWorkstackAction::fillPopup( QPopupMenu* pm, const int idx ) +{ + if ( !pm ) + return; + + int index = idx < 0 ? pm->count() : QMIN( (int)pm->count(), idx ); + + myMenu.insert( pm, QIntList() ); + QIntList& lst = myMenu[pm]; + + for ( ItemMap::ConstIterator mit = myItem.begin(); mit != myItem.end(); ++mit ) + { + if ( !hasItems( mit.key() ) ) + continue; + + mit.data()->addTo( pm, index ); + lst.append( pm->idAt( index++ ) ); + } + + QtxWorkstack* ws = workstack(); + if ( !ws || !hasItems( Windows ) ) + return; + + QWidgetList wList = ws->windowList(); + if ( wList.isEmpty() ) + return; + + lst.append( pm->insertSeparator( index++ ) ); + + int param = 0; + pm->setCheckable( true ); + for ( QWidgetListIt it( wList ); it.current(); ++it ) + { + int id = pm->insertItem( it.current()->caption(), this, SLOT( onItemActivated( int ) ), 0, -1, index++ ); + pm->setItemParameter( id, param++ ); + pm->setItemChecked( id, it.current() == ws->activeWindow() ); + lst.append( id ); + } +} + +void QtxWorkstackAction::onItemActivated( int idx ) +{ + QtxWorkstack* ws = workstack(); + if ( !ws ) + return; + + QWidgetList wList = ws->windowList(); + if ( idx < 0 || idx >= (int)wList.count() ) + return; + + wList.at( idx )->setFocus(); +} diff --git a/src/Qtx/QtxWorkstackAction.h b/src/Qtx/QtxWorkstackAction.h new file mode 100644 index 000000000..6e91ddda2 --- /dev/null +++ b/src/Qtx/QtxWorkstackAction.h @@ -0,0 +1,97 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File: QtxWorkstackAction.h +// Author: Sergey TELKOV + +#ifndef QTXWORKSTACKACTION_H +#define QTXWORKSTACKACTION_H + +#include "QtxAction.h" + +class QtxWorkstack; + +#ifdef WIN32 +#pragma warning( disable:4251 ) +#endif + +class QTX_EXPORT QtxWorkstackAction : public QtxAction +{ + Q_OBJECT + +public: + enum { VSplit = 0x0001, + HSplit = 0x0002, + Windows = 0x0010, + Split = VSplit | HSplit, + Standard = Split | Windows }; + +public: + QtxWorkstackAction( QtxWorkstack*, QObject* = 0, const char* = 0 ); + virtual ~QtxWorkstackAction(); + + QtxWorkstack* workstack() const; + + int items() const; + void setItems( const int ); + bool hasItems( const int ) const; + + int accel( const int ) const; + QIconSet iconSet( const int ) const; + QString menuText( const int ) const; + QString statusTip( const int ) const; + + void setAccel( const int, const int ); + void setIconSet( const int, const QIconSet& ); + void setMenuText( const int, const QString& ); + void setStatusTip( const int, const QString& ); + + virtual bool addTo( QWidget* ); + virtual bool addTo( QWidget*, const int ); + virtual bool removeFrom( QWidget* ); + + void perform( const int ); + +private slots: + void onAboutToShow(); + void onItemActivated( int ); + void onPopupDestroyed( QObject* ); + +private: + void checkPopup( QPopupMenu* ); + void updatePopup( QPopupMenu* ); + + int clearPopup( QPopupMenu* ); + void fillPopup( QPopupMenu*, const int ); + +private: + typedef QMap MenuMap; + typedef QMap ItemMap; + +private: + MenuMap myMenu; + ItemMap myItem; + int myFlags; + QtxWorkstack* myWorkstack; +}; + +#ifdef WIN32 +#pragma warning( default:4251 ) +#endif + +#endif diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_GUI.h b/src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_GUI.h new file mode 100644 index 000000000..e6276148d --- /dev/null +++ b/src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_GUI.h @@ -0,0 +1,45 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#if !defined ( SALOME_PYQT_GUI_H ) +#define SALOME_PYQT_GUI_H + +// ======================================================== +// set dllexport type for Win platform +#ifdef WNT + +#ifdef SALOME_PYQT_EXPORTS +#define SALOME_PYQT_EXPORT __declspec(dllexport) +#else +#define SALOME_PYQT_EXPORT __declspec(dllimport) +#endif + +#else // WNT + +#define SALOME_PYQT_EXPORT + +#endif // WNT + +// ======================================================== +// avoid warning messages +#ifdef WNT +#pragma warning (disable : 4786) +#pragma warning (disable : 4251) +#endif + +#endif // SALOME_PYQT_GUI_H diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_Module.h b/src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_Module.h new file mode 100644 index 000000000..2582ee59e --- /dev/null +++ b/src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_Module.h @@ -0,0 +1,190 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +//============================================================================= +// File : SALOME_PYQT_Module.h +// Created : 25/04/05 +// Author : Vadim SANDLER +// Project : SALOME +// Copyright : 2003-2005 CEA/DEN, EDF R&D +// $Header : $ +//============================================================================= + +#ifndef SALOME_PYQT_MODULE_H +#define SALOME_PYQT_MODULE_H + +#include "SALOME_PYQT_GUI.h" + +#include "SALOME_PYQT_PyInterp.h" // this include must be first (see PyInterp_base.h)! +#include "SalomeApp_Module.h" +#include +#include +#include +#include +#include + +#include +#include CORBA_CLIENT_HEADER(SALOME_Component) + +class SALOME_PYQT_XmlHandler; + +class SALOME_PYQT_EXPORT SALOME_PYQT_Module: public SalomeApp_Module +{ + Q_OBJECT; + + /****************************** + * Data + ******************************/ + +private: + typedef std::map InterpMap; + + /* study-to-subinterpreter map */ + static InterpMap myInterpMap; + /* current Python subinterpreter */ + SALOME_PYQT_PyInterp* myInterp; + /* Python GUI module loaded */ + PyObjWrapper myModule; + /* Pytho GUI being initialized (not zero only during the initialization)*/ + static SALOME_PYQT_Module* myInitModule; + + typedef QPtrList ActionList; + + /* own actions list */ + ActionList myMenuActionList; + ActionList myPopupActionList; + ActionList myToolbarActionList; + + enum PyQtGUIAction { PYQT_ACTION_MENU = 10000000, + PYQT_ACTION_TOOLBAL = 20000000, + PYQT_ACTION_POPUP = 30000000 }; + + /* XML resource file parser */ + SALOME_PYQT_XmlHandler* myXmlHandler; + /* windows map*/ + QMap myWindowsMap; + /* compatible view managers list */ + QStringList myViewMgrList; + + /****************************** + * Construction/destruction + ******************************/ + +public: + /* constructor */ + SALOME_PYQT_Module(); + /* destructor */ + ~SALOME_PYQT_Module(); + + /* get module engine */ + Engines::Component_var getEngine() const; + + /****************************** + * Inherited from SalomeApp_Module + ******************************/ + +public: + /* little trick : provide an access to being activated Python module from outside; + needed by the SalomePyQt library :( + */ + static SALOME_PYQT_Module* getInitModule(); + + /* initialization */ + void initialize ( CAM_Application* ); + + /* getting windows list */ + void windows ( QMap& ) const; + /* getting compatible viewer managers list */ + void viewManagers( QStringList& ) const; + + /* context popup menu request */ + void contextMenuPopup( const QString&, QPopupMenu*, QString& ); + + /* get module engine IOR */ + virtual QString engineIOR() const; + + /* called when study desktop is activated */ + virtual void studyActivated(); + + /* working with toolbars : open protected methods */ + int createTool( const QString& ); + int createTool( const int, const int, const int = -1 ); + int createTool( const int, const QString&, const int = -1 ); + int createTool( QAction*, const int, const int = -1, const int = -1 ); + int createTool( QAction*, const QString&, const int = -1, const int = -1 ); + + /* working with menus : open protected methods */ + int createMenu( const QString&, const int, const int = -1, const int = -1, const int = -1 ); + int createMenu( const QString&, const QString&, const int = -1, const int = -1, const int = -1 ); + int createMenu( const int, const int, const int = -1, const int = -1 ); + int createMenu( const int, const QString&, const int = -1, const int = -1 ); + int createMenu( QAction*, const int, const int = -1, const int = -1, const int = -1 ); + int createMenu( QAction*, const QString&, const int = -1, const int = -1, const int = -1 ); + + /* create separator : open protected method */ + QAction* createSeparator(); + + /* working with actions : open protected methods */ + QAction* action( const int ) const; + int actionId( const QAction* ) const; + QAction* createAction( const int, const QString&, const QString&, const QString&, + const QString&, const int, const bool = false ); + +public slots: + /* activation */ + virtual bool activateModule( SUIT_Study* ); + /* deactivation */ + virtual bool deactivateModule( SUIT_Study* ); + + /****************************** + * Internal methods + ******************************/ + +public slots: + /* GUI action processing slots */ + void onGUIEvent(); + void onGUIEvent( int ); + +private: + /* internal initizalition */ + void init ( CAM_Application* ); + /* internal activation */ + void activate ( SUIT_Study* ); + /* internal deactivation */ + void deactivate ( SUIT_Study* ); + /* study activation */ + void studyChanged( SUIT_Study* ); + /* context popup menu processing */ + void contextMenu( const QString&, QPopupMenu* ); + /* GUI event processing */ + void guiEvent( const int ); + + /* add action to the private action map */ + void addAction ( const PyQtGUIAction, QAction* ); + + /* initialize a Python subinterpreter */ + void initInterp ( int ); + /* import a Python GUI module */ + void importModule(); + /* set workspace to Python GUI module */ + void setWorkSpace(); + + friend class SALOME_PYQT_XmlHandler; +}; + +#endif // SALOME_PYQT_MODULE_H diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_PyInterp.h b/src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_PyInterp.h new file mode 100644 index 000000000..1e15494e8 --- /dev/null +++ b/src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_PyInterp.h @@ -0,0 +1,48 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +//============================================================================= +// File : SALOME_PYQT_PyInterp.h +// Created : 25/04/05 +// Author : Christian CAREMOLI, Paul RASCLE, EDF +// Project : SALOME +// Copyright : 2003-2005 CEA/DEN, EDF R&D +// $Header : $ +//============================================================================= + +#ifndef SALOME_PYQT_PYINTERP_H +#define SALOME_PYQT_PYINTERP_H + +#include "SALOME_PYQT_GUI.h" + +#include "PyInterp_base.h" // this include must be first (see PyInterp_base.h)! + +class SALOME_PYQT_EXPORT SALOME_PYQT_PyInterp : public PyInterp_base +{ + public: + SALOME_PYQT_PyInterp(); + ~SALOME_PYQT_PyInterp(); + + int run(const char *command); + + protected: + virtual bool initState(); + virtual bool initContext(); +}; + +#endif // SALOME_PYQT_PYINTERP_H diff --git a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.h b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.h new file mode 100644 index 000000000..51f245f23 --- /dev/null +++ b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.h @@ -0,0 +1,151 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +//============================================================================= +// File : SalomePyQt.h +// Created : 25/04/05 +// Author : Vadim SANDLER +// Project : SALOME +// Copyright : 2003-2005 CEA/DEN, EDF R&D +// $Header : $ +//============================================================================= + +#ifndef SALOME_PYQT_H +#define SALOME_PYQT_H + +#include +#include +#include + +#include + +class LightApp_SelectionMgr; +class SalomeApp_Application; +class QMenuBar; +class QPopupMenu; +class QWidget; +class QtxAction; + +class SALOME_Selection : public QObject +{ + Q_OBJECT + +public: + ~SALOME_Selection(); + static SALOME_Selection* GetSelection( SalomeApp_Application* ); + + void Clear(); + void ClearIObjects(); + void ClearFilters(); + +signals: + void currentSelectionChanged(); + +private slots: + void onSelMgrDestroyed(); + +private: + LightApp_SelectionMgr* mySelMgr; + SALOME_Selection( QObject* ); +}; + +enum MenuName { + File = 1, + View = 2, + Edit = 3, + Preferences = 4, + Tools = 5, + Window = 6, + Help = 7 +}; + +enum { + WT_ObjectBrowser = LightApp_Application::WT_ObjectBrowser, + WT_PyConsole = LightApp_Application::WT_PyConsole, + WT_LogWindow = LightApp_Application::WT_LogWindow, + WT_User = LightApp_Application::WT_User +}; + +class SalomePyQt +{ +public: + static QWidget* getDesktop(); + static QWidget* getMainFrame(); + static QMenuBar* getMainMenuBar(); + static QPopupMenu* getPopupMenu( const MenuName ); + static SALOME_Selection* getSelection(); + static int getStudyId(); + static void putInfo( const QString&, const int = 0 ); + static const QString getActiveComponent(); + static void updateObjBrowser( const int = 0, bool = true ); + + static QString getFileName ( QWidget*, const QString&, const QStringList&, const QString&, bool ); + static QStringList getOpenFileNames ( QWidget*, const QString&, const QStringList&, const QString& ); + static QString getExistingDirectory( QWidget*, const QString&, const QString& ); + + static void helpContext( const QString&, const QString& ); + + static bool dumpView( const QString& ); + + static int createTool( const QString& ); + static int createTool( const int, const int, const int = -1 ); + static int createTool( const int, const QString&, const int = -1 ); + static int createTool( QtxAction*, const int, const int = -1, const int = -1 ); + static int createTool( QtxAction*, const QString&, const int = -1, const int = -1 ); + + static int createMenu( const QString&, const int = -1, + const int = -1, const int = -1 ); + static int createMenu( const QString&, const QString& = QString::null, + const int = -1, const int = -1 ); + static int createMenu( const int, const int = -1, + const int = -1, const int = -1 ); + static int createMenu( const int, const QString& = QString::null, + const int = -1, const int = -1 ); + static int createMenu( QtxAction*, const int, const int = -1, + const int = -1, const int = -1 ); + static int createMenu( QtxAction*, const QString&, const int = -1, + const int = -1, const int = -1 ); + + static QtxAction* createSeparator(); + + static QtxAction* createAction( const int, const QString&, + const QString& = QString::null, const QString& = QString::null, + const QString& = QString::null, const int = 0, const bool = false ); + + static QtxAction* action( const int ); + static int actionId( const QtxAction* ); + + static void addSetting ( const QString&, const QString&, const double ); + static void addSetting ( const QString&, const QString&, const int ); + static void addSetting ( const QString&, const QString&, const QString& ); + static void addSetting ( const QString&, const QString&, const QColor& ); + static int integerSetting( const QString&, const QString&, const int = 0 ); + static double doubleSetting ( const QString&, const QString&, const int = 0 ); + static bool boolSetting ( const QString&, const QString&, const bool = 0 ); + static QString stringSetting ( const QString&, const QString&, const QString& = QString("") ); + static QColor colorSetting ( const QString&, const QString&, const QColor& = QColor() ); + static void removeSetting ( const QString&, const QString& ); + // obsolete + static void addStringSetting( const QString&, const QString&, bool = true ); + static void addIntSetting ( const QString&, const int, bool = true ); + static void addDoubleSetting( const QString&, const double, bool = true ); + static void removeSettings ( const QString& ); + static QString getSetting ( const QString& ); +}; + +#endif // SALOME_PYQT_H diff --git a/src/SOCC/SOCC.h b/src/SOCC/SOCC.h new file mode 100755 index 000000000..c5f632238 --- /dev/null +++ b/src/SOCC/SOCC.h @@ -0,0 +1,31 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifdef WNT +#ifdef SOCC_EXPORTS +#define SOCC_EXPORT __declspec(dllexport) +#else +#define SOCC_EXPORT __declspec(dllimport) +#endif +#else +#define SOCC_EXPORT +#endif + +#if defined WNT +#pragma warning ( disable: 4251 ) +#endif diff --git a/src/SOCC/SOCC_ViewModel.cxx b/src/SOCC/SOCC_ViewModel.cxx new file mode 100755 index 000000000..60c0a880e --- /dev/null +++ b/src/SOCC/SOCC_ViewModel.cxx @@ -0,0 +1,658 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "SOCC_ViewModel.h" + +#include "SOCC_Prs.h" +#include "SOCC_ViewWindow.h" + +#include "SUIT_Session.h" +#include "SUIT_Application.h" + +//#include "ToolsGUI.h" + +// Temporarily commented to avoid awful dependecy on SALOMEDS +// TODO: better mechanism of storing display/erse status in a study +// should be provided... +//#include +//#include CORBA_CLIENT_HEADER(SALOMEDS) + +#include +#include + +#include +#include + +// Temporarily commented to avoid awful dependecy on SALOMEDS +// TODO: better mechanism of storing display/erse status in a study +// should be provided... +//#include +//#include +//#include +//#include + +//#include "SALOMEDSClient.hxx" +//#include "SALOMEDS_StudyManager.hxx" + +#include + +// in order NOT TO link with SalomeApp, here the code returns SALOMEDS_Study. +// SalomeApp_Study::studyDS() does it as well, but -- here it is retrieved from +// SALOMEDS::StudyManager - no linkage with SalomeApp. + +// Temporarily commented to avoid awful dependecy on SALOMEDS +// TODO: better mechanism of storing display/erse status in a study +// should be provided... +//static _PTR(Study) getStudyDS() +//{ +// SALOMEDSClient_Study* aStudy = NULL; +// _PTR(StudyManager) aMgr( new SALOMEDS_StudyManager() ); + + // get id of SUIT_Study, if it's a SalomeApp_Study, it will return + // id of its underlying SALOMEDS::Study +// SUIT_Application* app = SUIT_Session::session()->activeApplication(); +// if ( !app ) return _PTR(Study)(aStudy); +// SUIT_Study* stud = app->activeStudy(); +// if ( !stud ) return _PTR(Study)(aStudy); +// const int id = stud->id(); // virtual method, must return SALOMEDS_Study id + // get SALOMEDS_Study with this id from StudyMgr +// return aMgr->GetStudyByID( id ); +//} + +SOCC_Viewer::SOCC_Viewer( bool DisplayTrihedron ) +: OCCViewer_Viewer( DisplayTrihedron ) +{ +} + +SOCC_Viewer::~SOCC_Viewer() +{ +} + +bool SOCC_Viewer::highlight( const Handle(SALOME_InteractiveObject)& obj, + bool hilight, bool upd ) +{ + bool isInLocal = getAISContext()->HasOpenedContext(); + //SUIT_Study* ActiveStudy = SUIT_Application::getDesktop()->getActiveStudy(); + //SALOME_Selection* Sel = SALOME_Selection::Selection( ActiveStudy->getSelection() ); + + AIS_ListOfInteractive List; + getAISContext()->DisplayedObjects(List); + + AIS_ListIteratorOfListOfInteractive ite(List); + for ( ; ite.More(); ite.Next() ) + { + Handle(SALOME_InteractiveObject) anObj = + Handle(SALOME_InteractiveObject)::DownCast( ite.Value()->GetOwner() ); + + if ( !anObj.IsNull() && anObj->hasEntry() && anObj->isSame( obj ) ) + { + if ( !isInLocal ) + OCCViewer_Viewer::highlight( ite.Value(), hilight, false ); + // highlight subshapes only when local selection is active + else + { + /*if ( ite.Value()->IsKind( STANDARD_TYPE( SALOME_AISShape ) ) ) + { + Handle(SALOME_AISShape) aSh = Handle(SALOME_AISShape)::DownCast( ite.Value() ); + TColStd_IndexedMapOfInteger MapIndex; + Sel->GetIndex( IObject, MapIndex ); + aSh->highlightSubShapes( MapIndex, highlight ); + }*/ + } + break; + } + } + + if( upd ) + update(); + + return false; +} + +bool SOCC_Viewer::isInViewer( const Handle(SALOME_InteractiveObject)& obj, + bool onlyInViewer ) +{ + AIS_ListOfInteractive List; + getAISContext()->DisplayedObjects(List); + + if( !onlyInViewer ) { + AIS_ListOfInteractive List1; + getAISContext()->ObjectsInCollector(List1); + List.Append(List1); + } + + AIS_ListIteratorOfListOfInteractive ite(List); + for ( ; ite.More(); ite.Next() ) + { + Handle(SALOME_InteractiveObject) anObj = + Handle(SALOME_InteractiveObject)::DownCast( ite.Value()->GetOwner() ); + + if ( !anObj.IsNull() && anObj->hasEntry() && anObj->isSame( obj ) ) + return true; + } + return false; +} + +bool SOCC_Viewer::isVisible( const Handle(SALOME_InteractiveObject)& obj ) +{ + AIS_ListOfInteractive List; + getAISContext()->DisplayedObjects( List ); + + AIS_ListIteratorOfListOfInteractive ite( List ); + for ( ; ite.More(); ite.Next() ) + { + Handle(SALOME_InteractiveObject) anObj = + Handle(SALOME_InteractiveObject)::DownCast( ite.Value()->GetOwner() ); + + if ( !anObj.IsNull() && anObj->hasEntry() && anObj->isSame( obj ) ) + return getAISContext()->IsDisplayed( ite.Value() ); + } + + return false; +} + +void SOCC_Viewer::setColor( const Handle(SALOME_InteractiveObject)& obj, + const QColor& color, bool update ) +{ + AIS_ListOfInteractive List; + getAISContext()->DisplayedObjects(List); + + AIS_ListIteratorOfListOfInteractive ite(List); + for ( ; ite.More(); ite.Next() ) + { + Handle(SALOME_InteractiveObject) anObj = + Handle(SALOME_InteractiveObject)::DownCast( ite.Value()->GetOwner() ); + + if ( !anObj.IsNull() && anObj->hasEntry() && anObj->isSame( obj ) ) + { + OCCViewer_Viewer::setColor( ite.Value(), color, update ); + return; + } + } +} + +void SOCC_Viewer::switchRepresentation( const Handle(SALOME_InteractiveObject)& obj, + int mode, bool update ) +{ + AIS_ListOfInteractive List; + getAISContext()->DisplayedObjects(List); + + AIS_ListIteratorOfListOfInteractive ite(List); + for ( ; ite.More(); ite.Next() ) + { + Handle(SALOME_InteractiveObject) anObj = + Handle(SALOME_InteractiveObject)::DownCast( ite.Value()->GetOwner() ); + + if ( !anObj.IsNull() && anObj->hasEntry() && anObj->isSame( obj ) ) + { + OCCViewer_Viewer::switchRepresentation( ite.Value(), mode, update ); + return; + } + } +} + +void SOCC_Viewer::setTransparency( const Handle(SALOME_InteractiveObject)& obj, + float trans, bool update ) +{ + AIS_ListOfInteractive List; + getAISContext()->DisplayedObjects( List ); + + AIS_ListIteratorOfListOfInteractive ite( List ); + for ( ; ite.More(); ite.Next() ) + { + Handle(SALOME_InteractiveObject) anObj = + Handle(SALOME_InteractiveObject)::DownCast( ite.Value()->GetOwner() ); + + if ( !anObj.IsNull() && anObj->hasEntry() && anObj->isSame( obj ) ) + { + OCCViewer_Viewer::setTransparency( ite.Value(), trans, update ); + return; + } + } +} + +void SOCC_Viewer::rename( const Handle(SALOME_InteractiveObject)& obj, + const QString& name ) +{ + AIS_ListOfInteractive List; + getAISContext()->DisplayedObjects(List); + + AIS_ListIteratorOfListOfInteractive ite(List); + while (ite.More()) + { + if (ite.Value()->IsKind(STANDARD_TYPE(SALOME_AISShape))) + { + Handle(SALOME_AISShape) aSh = Handle(SALOME_AISShape)::DownCast(ite.Value()); + + if ( aSh->hasIO() ) + { + Handle(SALOME_InteractiveObject) IO = aSh->getIO(); + if ( IO->isSame( obj ) ) + { + aSh->setName( (char*)name.latin1() ); + break; + } + } + } + else if ( ite.Value()->IsKind( STANDARD_TYPE( SALOME_AISObject ) ) ) + { + Handle(SALOME_AISObject) aSh = Handle(SALOME_AISObject)::DownCast( ite.Value() ); + + // Add code here, if someone create a MODULE_AISObject. + } + ite.Next(); + } +} + +//======================================================================= +// name : Display +// Purpose : Display presentation +//======================================================================= +void SOCC_Viewer::Display( const SALOME_OCCPrs* prs ) +{ + // try do downcast object + const SOCC_Prs* anOCCPrs = dynamic_cast( prs ); + if ( !anOCCPrs || anOCCPrs->IsNull() ) + return; + + // get SALOMEDS Study + // Temporarily commented to avoid awful dependecy on SALOMEDS + // TODO: better mechanism of storing display/erse status in a study + // should be provided... + // _PTR(Study) study(getStudyDS()); + + // get context + Handle (AIS_InteractiveContext) ic = getAISContext(); + + // get all displayed objects + AIS_ListOfInteractive List; + ic->DisplayedObjects( List ); + // get objects in the collector + AIS_ListOfInteractive ListCollector; + ic->ObjectsInCollector( ListCollector ); + + // get objects to be displayed + AIS_ListOfInteractive anAISObjects; + anOCCPrs->GetObjects( anAISObjects ); + + AIS_ListIteratorOfListOfInteractive aIter( anAISObjects ); + for ( ; aIter.More(); aIter.Next() ) + { + Handle(AIS_InteractiveObject) anAIS = aIter.Value(); + if ( !anAIS.IsNull() ) + { + // try to find presentation in the viewer + bool bDisplayed = false; + AIS_ListIteratorOfListOfInteractive ite( List ); + for ( ; ite.More(); ite.Next() ) + { + // compare presentations by handles + // if the object is already displayed - nothing to do more + if ( ite.Value() == anAIS ) + { + // Deactivate object if necessary + if ( !anOCCPrs->ToActivate() ) + ic->Deactivate( anAIS ); + bDisplayed = true; + break; + } + } + + if ( bDisplayed ) + continue; + + // then try to find presentation in the collector + bDisplayed = false; + ite.Initialize( ListCollector ); + for ( ; ite.More(); ite.Next() ) + { + // compare presentations by handles + // if the object is in collector - display it + if ( ite.Value() == anAIS ) + { + ic->DisplayFromCollector( anAIS, false ); + + // Deactivate object if necessary + if ( !anOCCPrs->ToActivate() ) + ic->Deactivate( anAIS ); + bDisplayed = true; + + // Set visibility flag + // Temporarily commented to avoid awful dependecy on SALOMEDS + // TODO: better mechanism of storing display/erse status in a study + // should be provided... + //Handle(SALOME_InteractiveObject) anObj = + // Handle(SALOME_InteractiveObject)::DownCast( anAIS->GetOwner() ); + //if ( !anObj.IsNull() && anObj->hasEntry() ) + //{ + // if ( study ) + // ToolsGUI::SetVisibility( study, anObj->getEntry(), true, this ); + //} + break; + } + } + if ( bDisplayed ) + continue; + + // if object is not displayed and not found in the collector - display it + if ( anAIS->IsKind( STANDARD_TYPE(AIS_Trihedron) ) ) + { + Handle(AIS_Trihedron) aTrh = Handle(AIS_Trihedron)::DownCast( anAIS ); + double aNewSize = 100, aSize = 100; + getTrihedronSize( aNewSize, aSize ); + aTrh->SetSize( aTrh == getTrihedron() ? aNewSize : 0.5 * aNewSize ); + } + + ic->Display( anAIS, false ); + + // Set visibility flag + // Temporarily commented to avoid awful dependecy on SALOMEDS + // TODO: better mechanism of storing display/erse status in a study + // should be provided... + //Handle(SALOME_InteractiveObject) anObj = + // Handle(SALOME_InteractiveObject)::DownCast( anAIS->GetOwner() ); + //if ( !anObj.IsNull() && anObj->hasEntry() ) + //{ + // if ( study ) + // ToolsGUI::SetVisibility( study, anObj->getEntry(), true, this ); + //} + + // Deactivate object if necessary + if ( !anOCCPrs->ToActivate() ) + ic->Deactivate( anAIS ); + } + } +} + +//======================================================================= +// name : Erase +// Purpose : Erase presentation +//======================================================================= +void SOCC_Viewer::Erase( const SALOME_OCCPrs* prs, const bool forced ) +{ + // try do downcast object + const SOCC_Prs* anOCCPrs = dynamic_cast( prs ); + if ( !anOCCPrs || anOCCPrs->IsNull() ) + return; + + // get SALOMEDS Study + // Temporarily commented to avoid awful dependecy on SALOMEDS + // TODO: better mechanism of storing display/erse status in a study + // should be provided... + // _PTR(Study) study(getStudyDS()); + + // get context + Handle(AIS_InteractiveContext) ic = getAISContext(); + + // get objects to be erased + AIS_ListOfInteractive anAISObjects; + anOCCPrs->GetObjects( anAISObjects ); + + AIS_ListIteratorOfListOfInteractive aIter( anAISObjects ); + for ( ; aIter.More(); aIter.Next() ) { + Handle(AIS_InteractiveObject) anAIS = aIter.Value(); + if ( !anAIS.IsNull() ) { + // erase the object from context : move it to collector + ic->Erase( anAIS, false, forced ? false : true ); + + // Set visibility flag if necessary + // Temporarily commented to avoid awful dependecy on SALOMEDS + // TODO: better mechanism of storing display/erse status in a study + // should be provided... + //if ( !forced ) + //{ + // Handle(SALOME_InteractiveObject) anObj = + // Handle(SALOME_InteractiveObject)::DownCast( anAIS->GetOwner() ); + // if ( !anObj.IsNull() && anObj->hasEntry() ) + // { + // if ( study ) + // ToolsGUI::SetVisibility( study, anObj->getEntry(), true, this ); + // } + //} + } + } +} + +//======================================================================= +// name : EraseAll +// Purpose : Erase all presentations +//======================================================================= +void SOCC_Viewer::EraseAll( const bool forced ) +{ + // get SALOMEDS Study + // Temporarily commented to avoid awful dependecy on SALOMEDS + // TODO: better mechanism of storing display/erse status in a study + // should be provided... + // _PTR(Study) study(getStudyDS()); + + // get context + Handle(AIS_InteractiveContext) ic = getAISContext(); + + // check if trihedron is displayed + Standard_Boolean isTrihedronDisplayed = ic->IsDisplayed( getTrihedron() ); + + // get objects to be erased (all currently displayed objects) + AIS_ListOfInteractive aList; + ic->DisplayedObjects( aList ); + AIS_ListIteratorOfListOfInteractive anIter( aList ); + for ( ; anIter.More(); anIter.Next() ) { + if ( isTrihedronDisplayed && anIter.Value()->DynamicType() == STANDARD_TYPE( AIS_Trihedron ) ) + continue; + + // erase an object + Handle(AIS_InteractiveObject) anIO = anIter.Value(); + ic->Erase( anIO, false, forced ? false : true ); + + // Set visibility flag if necessary + // Temporarily commented to avoid awful dependecy on SALOMEDS + // TODO: better mechanism of storing display/erse status in a study + // should be provided... + //if ( !forced ) { + // Handle(SALOME_InteractiveObject) anObj = + // Handle(SALOME_InteractiveObject)::DownCast( anIO->GetOwner() ); + + // if ( !anObj.IsNull() && anObj->hasEntry() ) { + // if ( study ) + // ToolsGUI::SetVisibility( study, anObj->getEntry(), true, this ); + // } + //} + } + + // display trihedron if necessary + if ( isTrihedronDisplayed ) + getAISContext()->Display( getTrihedron() ); + else + Repaint(); +} + +//======================================================================= +// name : CreatePrs +// Purpose : Create presentation corresponding to the entry +//======================================================================= +SALOME_Prs* SOCC_Viewer::CreatePrs( const char* entry ) +{ + SOCC_Prs* prs = new SOCC_Prs(); + if ( entry ) + { + // get context + Handle(AIS_InteractiveContext) ic = getAISContext(); + + // get displayed objects + AIS_ListOfInteractive List; + ic->DisplayedObjects( List ); + // get objects in the collector + AIS_ListOfInteractive ListCollector; + ic->ObjectsInCollector( ListCollector ); + List.Append( ListCollector ); + + AIS_ListIteratorOfListOfInteractive ite( List ); + for ( ; ite.More(); ite.Next() ) + { + Handle(SALOME_InteractiveObject) anObj = + Handle(SALOME_InteractiveObject)::DownCast( ite.Value()->GetOwner() ); + + if ( !anObj.IsNull() && anObj->hasEntry() && strcmp( anObj->getEntry(), entry ) == 0 ) + prs->AddObject( ite.Value() ); + } + } + return prs; +} + +//======================================================================= +// name : LocalSelection +// Purpose : Activates selection of sub shapes +//======================================================================= +void SOCC_Viewer::LocalSelection( const SALOME_OCCPrs* thePrs, const int theMode ) +{ + Handle(AIS_InteractiveContext) ic = getAISContext(); + + const SOCC_Prs* anOCCPrs = dynamic_cast( thePrs ); + if ( ic.IsNull() ) + return; + + // Open local context if there is no one + bool allObjects = thePrs == 0 || thePrs->IsNull(); + if ( !ic->HasOpenedContext() ) { + ic->ClearCurrents( false ); + ic->OpenLocalContext( allObjects, true, true ); + } + + AIS_ListOfInteractive anObjs; + // Get objects to be activated + if ( allObjects ) + ic->DisplayedObjects( anObjs ); + else + anOCCPrs->GetObjects( anObjs ); + + // Activate selection of objects from prs + AIS_ListIteratorOfListOfInteractive aIter( anObjs ); + for ( ; aIter.More(); aIter.Next() ) { + Handle(AIS_InteractiveObject) anAIS = aIter.Value(); + if ( !anAIS.IsNull() ) + { + if ( anAIS->IsKind( STANDARD_TYPE( AIS_Shape ) ) ) + { + ic->Load( anAIS, -1, false ); + ic->Activate( anAIS, AIS_Shape::SelectionMode( (TopAbs_ShapeEnum)theMode ) ); + } + else if ( anAIS->DynamicType() != STANDARD_TYPE(AIS_Trihedron) ) + { + ic->Load( anAIS, -1, false ); + ic->Activate( anAIS, theMode ); + } + } + } +} + +//======================================================================= +// name : GlobalSelection +// Purpose : Deactivates selection of sub shapes +//======================================================================= +void SOCC_Viewer::GlobalSelection( const bool update ) const +{ + Handle(AIS_InteractiveContext) ic = getAISContext(); + if ( !ic.IsNull() ) + { + ic->CloseAllContexts( false ); + if ( update ) + ic->CurrentViewer()->Redraw(); + } +} + +//======================================================================= +// name : BeforeDisplay +// Purpose : Axiluary method called before displaying of objects +//======================================================================= +void SOCC_Viewer::BeforeDisplay( SALOME_Displayer* d ) +{ + d->BeforeDisplay( this, SALOME_OCCViewType() ); +} + +//======================================================================= +// name : AfterDisplay +// Purpose : Axiluary method called after displaying of objects +//======================================================================= +void SOCC_Viewer::AfterDisplay( SALOME_Displayer* d ) +{ + d->AfterDisplay( this, SALOME_OCCViewType() ); +} + +//======================================================================= +// name : getTrihedronSize +// Purpose : Get new and current trihedron size corresponding to the +// current model size +//======================================================================= +bool SOCC_Viewer::getTrihedronSize( double& theNewSize, double& theSize ) +{ + theNewSize = 100; + theSize = 100; + + //SRN: BUG IPAL8996, a usage of method ActiveView without an initialization + Handle(V3d_Viewer) viewer = getViewer3d(); + viewer->InitActiveViews(); + if(!viewer->MoreActiveViews()) return false; + + Handle(V3d_View) view3d = viewer->ActiveView(); + //SRN: END of fix + + if ( view3d.IsNull() ) + return false; + + double Xmin = 0, Ymin = 0, Zmin = 0, Xmax = 0, Ymax = 0, Zmax = 0; + double aMaxSide; + + view3d->View()->MinMaxValues( Xmin, Ymin, Zmin, Xmax, Ymax, Zmax ); + + if ( Xmin == RealFirst() || Ymin == RealFirst() || Zmin == RealFirst() || + Xmax == RealLast() || Ymax == RealLast() || Zmax == RealLast() ) + return false; + + aMaxSide = Xmax - Xmin; + if ( aMaxSide < Ymax -Ymin ) aMaxSide = Ymax -Ymin; + if ( aMaxSide < Zmax -Zmin ) aMaxSide = Zmax -Zmin; + + float aSizeInPercents = SUIT_Session::session()->resourceMgr()->doubleValue("Viewer","TrihedronSize", 105.); + + static float EPS = 5.0E-3; + theSize = getTrihedron()->Size(); + theNewSize = aMaxSide*aSizeInPercents / 100.0; + + return fabs( theNewSize - theSize ) > theSize * EPS || + fabs( theNewSize - theSize) > theNewSize * EPS; +} + +//======================================================================= +// name : Repaint +// Purpose : +//======================================================================= +void SOCC_Viewer::Repaint() +{ +// onAdjustTrihedron(); + getViewer3d()->Update(); +} + +//======================================================================= +// name : createView +// Purpose : create SOCC_ViewWindow +//======================================================================= +SUIT_ViewWindow* SOCC_Viewer::createView( SUIT_Desktop* theDesktop ) +{ + SOCC_ViewWindow* view = new SOCC_ViewWindow(theDesktop, this); + initView( view ); + return view; +} diff --git a/src/SOCC/SOCC_ViewModel.h b/src/SOCC/SOCC_ViewModel.h new file mode 100755 index 000000000..bf57aa8d7 --- /dev/null +++ b/src/SOCC/SOCC_ViewModel.h @@ -0,0 +1,72 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SOCC_VIEWMODEL_H +#define SOCC_VIEWMODEL_H + +#ifdef WIN32 +#pragma warning( disable:4251 ) +#endif + +#include "SOCC.h" +#include "SALOME_Prs.h" +#include "OCCViewer_ViewModel.h" +#include "SALOME_InteractiveObject.hxx" + +class SOCC_EXPORT SOCC_Viewer: public OCCViewer_Viewer, public SALOME_View +{ + Q_OBJECT + +public: + SOCC_Viewer( bool DisplayTrihedron = true ); + virtual ~SOCC_Viewer(); + + /* Selection management */ + bool highlight( const Handle(SALOME_InteractiveObject)&, bool, bool=true ); + bool isInViewer( const Handle(SALOME_InteractiveObject)&, bool=false ); + + void setColor( const Handle(SALOME_InteractiveObject)&, const QColor&, bool=true ); + void switchRepresentation( const Handle(SALOME_InteractiveObject)&, int, bool=true ); + void setTransparency( const Handle(SALOME_InteractiveObject)&, float, bool=true ); + + void rename( const Handle(SALOME_InteractiveObject)&, const QString& ); + + virtual SUIT_ViewWindow* createView(SUIT_Desktop* theDesktop); + + /* Reimplemented from SALOME_View */ + virtual void Display( const SALOME_OCCPrs* ); + virtual void Erase( const SALOME_OCCPrs*, const bool = false ); + virtual void EraseAll( const bool = false ); + virtual SALOME_Prs* CreatePrs( const char* entry = 0 ); + virtual void BeforeDisplay( SALOME_Displayer* d ); + virtual void AfterDisplay ( SALOME_Displayer* d ); + virtual void LocalSelection( const SALOME_OCCPrs*, const int ); + virtual void GlobalSelection( const bool = false ) const; + virtual bool isVisible( const Handle(SALOME_InteractiveObject)& ); + virtual void Repaint(); + + // a utility function, used by SALOME_View_s methods + bool getTrihedronSize( double& theNewSize, double& theSize ); + +}; + +#ifdef WIN32 +#pragma warning( default:4251 ) +#endif + +#endif diff --git a/src/SOCC/SOCC_ViewWindow.cxx b/src/SOCC/SOCC_ViewWindow.cxx new file mode 100644 index 000000000..ce28624a0 --- /dev/null +++ b/src/SOCC/SOCC_ViewWindow.cxx @@ -0,0 +1,95 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "SOCC_ViewWindow.h" + +#include "OCCViewer_ViewPort3d.h" + +#include "SUIT_Accel.h" + +//---------------------------------------------------------------------------- +SOCC_ViewWindow +::SOCC_ViewWindow( SUIT_Desktop* theDesktop, + OCCViewer_Viewer* theModel) + : OCCViewer_ViewWindow( theDesktop, theModel ) +{ +} + +//---------------------------------------------------------------------------- +SOCC_ViewWindow +::~SOCC_ViewWindow() +{ +} + +//---------------------------------------------------------------------------- +void +SOCC_ViewWindow +::action( const int theAction ) +{ + const int inc = 10; + int cx, cy; + if ( theAction == SUIT_Accel::ZoomIn || theAction == SUIT_Accel::ZoomOut || + theAction == SUIT_Accel::RotateLeft || theAction == SUIT_Accel::RotateRight || + theAction == SUIT_Accel::RotateUp || theAction == SUIT_Accel::RotateDown ) { + cx = myViewPort->width() / 2; + cy = myViewPort->height() / 2; + } + switch ( theAction ) { + case SUIT_Accel::PanLeft : + myViewPort->pan( -inc, 0 ); + break; + case SUIT_Accel::PanRight : + myViewPort->pan( inc, 0 ); + break; + case SUIT_Accel::PanUp : + myViewPort->pan( 0, inc ); + break; + case SUIT_Accel::PanDown : + myViewPort->pan( 0, -inc ); + break; + case SUIT_Accel::ZoomIn : + myViewPort->zoom( cx, cy, cx + inc, cy + inc ); + break; + case SUIT_Accel::ZoomOut : + myViewPort->zoom( cx, cy, cx - inc, cy - inc ); + break; + case SUIT_Accel::ZoomFit : + myViewPort->fitAll(); + break; + case SUIT_Accel::RotateLeft : + myViewPort->startRotation( cx, cy ); + myViewPort->rotate( cx - inc, cy ); + myViewPort->endRotation(); + break; + case SUIT_Accel::RotateRight : + myViewPort->startRotation( cx, cy ); + myViewPort->rotate( cx + inc, cy ); + myViewPort->endRotation(); + break; + case SUIT_Accel::RotateUp : + myViewPort->startRotation( cx, cy ); + myViewPort->rotate( cx, cy - inc ); + myViewPort->endRotation(); + break; + case SUIT_Accel::RotateDown : + myViewPort->startRotation( cx, cy ); + myViewPort->rotate( cx, cy + inc ); + myViewPort->endRotation(); + break; + } +} diff --git a/src/SOCC/SOCC_ViewWindow.h b/src/SOCC/SOCC_ViewWindow.h new file mode 100644 index 000000000..7b4f22551 --- /dev/null +++ b/src/SOCC/SOCC_ViewWindow.h @@ -0,0 +1,46 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SOCC_VIEWWINDOW_H +#define SOCC_VIEWWINDOW_H + +#ifdef WIN32 +#pragma warning( disable:4251 ) +#endif + +#include "SOCC.h" +#include "OCCViewer_ViewWindow.h" + +class SOCC_EXPORT SOCC_ViewWindow : public OCCViewer_ViewWindow +{ + Q_OBJECT; + +public: + SOCC_ViewWindow( SUIT_Desktop*, OCCViewer_Viewer* ); + virtual ~SOCC_ViewWindow(); + +protected: + virtual void action( const int ); + +}; + +#ifdef WIN32 +#pragma warning( default:4251 ) +#endif + +#endif diff --git a/src/SPlot2d/SPlot2d.h b/src/SPlot2d/SPlot2d.h new file mode 100644 index 000000000..aa9d5fec2 --- /dev/null +++ b/src/SPlot2d/SPlot2d.h @@ -0,0 +1,31 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifdef WNT +#ifdef SPLOT2D_EXPORTS +#define SPLOT2D_EXPORT __declspec(dllexport) +#else +#define SPLOT2D_EXPORT __declspec(dllimport) +#endif +#else +#define SPLOT2D_EXPORT +#endif + +#if defined WNT +#pragma warning ( disable: 4251 ) +#endif diff --git a/src/SPlot2d/SPlot2d_Curve.cxx b/src/SPlot2d/SPlot2d_Curve.cxx new file mode 100644 index 000000000..e6b2c5b83 --- /dev/null +++ b/src/SPlot2d/SPlot2d_Curve.cxx @@ -0,0 +1,116 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File : SPlot2d_Curve.cxx +// Author : Sergey RUIN +// Module : SUIT + +#include "SPlot2d_Curve.h" +using namespace std; + +/*! + Constructor +*/ +SPlot2d_Curve::SPlot2d_Curve() +:Plot2d_Curve() +{ +} + +/*! + Destructor +*/ +SPlot2d_Curve::~SPlot2d_Curve() +{ +} + +/*! + Copy constructor. Makes deep copy of data. +*/ +SPlot2d_Curve::SPlot2d_Curve( const SPlot2d_Curve& curve ) +{ + myAutoAssign = curve.isAutoAssign(); + myHorTitle = curve.getHorTitle(); + myVerTitle = curve.getVerTitle(); + myHorUnits = curve.getHorUnits(); + myVerUnits = curve.getVerUnits(); + myColor = curve.getColor(); + myMarker = curve.getMarker(); + myLine = curve.getLine(); + myLineWidth = curve.getLineWidth(); + myPoints = curve.getPointList(); + myIO = curve.getIO(); + myTableIO = curve.getTableIO(); +} + +/*! + operator=. Makes deep copy of data. +*/ +SPlot2d_Curve& SPlot2d_Curve::operator=( const SPlot2d_Curve& curve ) +{ + myAutoAssign = curve.isAutoAssign(); + myHorTitle = curve.getHorTitle(); + myVerTitle = curve.getVerTitle(); + myHorUnits = curve.getHorUnits(); + myVerUnits = curve.getVerUnits(); + myColor = curve.getColor(); + myMarker = curve.getMarker(); + myLine = curve.getLine(); + myLineWidth = curve.getLineWidth(); + myPoints = curve.getPointList(); + myIO = curve.getIO(); + myTableIO = curve.getTableIO(); + return *this; +} + +Handle(SALOME_InteractiveObject) SPlot2d_Curve::getIO() const +{ + return myIO; +} + +void SPlot2d_Curve::setIO( const Handle(SALOME_InteractiveObject)& io ) +{ + myIO = io; +} + +bool SPlot2d_Curve::hasTableIO() const +{ + return !myTableIO.IsNull(); +} + +Handle(SALOME_InteractiveObject) SPlot2d_Curve::getTableIO() const +{ + return myTableIO; +} + +void SPlot2d_Curve::setTableIO( const Handle(SALOME_InteractiveObject)& io ) +{ + myTableIO = io; +} + +bool SPlot2d_Curve::hasIO() const +{ + return !myIO.IsNull(); +} + +QString SPlot2d_Curve::getTableTitle() const +{ + QString title; + if( hasTableIO() ) + title = getTableIO()->getName(); + return title; +} diff --git a/src/SPlot2d/SPlot2d_Curve.h b/src/SPlot2d/SPlot2d_Curve.h new file mode 100644 index 000000000..21ebc8a94 --- /dev/null +++ b/src/SPlot2d/SPlot2d_Curve.h @@ -0,0 +1,64 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File : SPlot2d_Curve.h +// Author : Sergey RUIN +// Module : SUIT + +#ifndef SPlot2d_Curve_h +#define SPlot2d_Curve_h + +#include "SPlot2d.h" + +#include "Plot2d_Curve.h" + +#include +#include +#include +#ifndef _Handle_SALOME_InteractiveObject_HeaderFile +#include +#endif +#include "SALOME_InteractiveObject.hxx" + +class SPLOT2D_EXPORT SPlot2d_Curve : public Plot2d_Curve +{ +public: + + SPlot2d_Curve(); + virtual ~SPlot2d_Curve(); + SPlot2d_Curve( const SPlot2d_Curve& curve ); + SPlot2d_Curve& operator= ( const SPlot2d_Curve& curve ); + + virtual QString getTableTitle() const; + + virtual bool hasIO() const; + virtual Handle(SALOME_InteractiveObject) getIO() const; + virtual void setIO( const Handle(SALOME_InteractiveObject)& ); + + virtual bool hasTableIO() const; + virtual Handle(SALOME_InteractiveObject) getTableIO() const; + virtual void setTableIO( const Handle(SALOME_InteractiveObject)& ); + +private: + Handle(SALOME_InteractiveObject) myIO; + Handle(SALOME_InteractiveObject) myTableIO; +}; + +#endif // SPlot2d_Curve_h + + diff --git a/src/SPlot2d/SPlot2d_Prs.cxx b/src/SPlot2d/SPlot2d_Prs.cxx new file mode 100644 index 000000000..38756328c --- /dev/null +++ b/src/SPlot2d/SPlot2d_Prs.cxx @@ -0,0 +1,66 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File : SPlot2d_Prs.cxx +// Author : Sergey RUIN +// Module : SUIT + +#include "SPlot2d_Prs.h" +#ifndef WNT +using namespace std; +#endif + +//========================================================== +/*! + * SPlot2d_Prs::SPlot2d_Prs + * Default constructor + */ +//========================================================== +SPlot2d_Prs::SPlot2d_Prs() +:Plot2d_Prs() +{ +} + +//========================================================== +/*! + * SPlot2d_Prs::SPlot2d_Prs + * Standard constructor + */ +//========================================================== +SPlot2d_Prs::SPlot2d_Prs( const Plot2d_Curve* obj ) +:Plot2d_Prs(obj) +{ +} + +SPlot2d_Prs::SPlot2d_Prs( const Plot2d_Prs* prs ) +{ + mySecondY = prs->isSecondY(); + myCurves = prs->getCurves(); +} + +//========================================================== +/*! + * SPlot2d_Prs::~SPlot2d_Prs + * Destructor + */ +//========================================================== +SPlot2d_Prs::~SPlot2d_Prs() +{ +} + + diff --git a/src/SPlot2d/SPlot2d_Prs.h b/src/SPlot2d/SPlot2d_Prs.h new file mode 100644 index 000000000..65f1743ee --- /dev/null +++ b/src/SPlot2d/SPlot2d_Prs.h @@ -0,0 +1,57 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File : SPlot2d_Prs.h +// Author : Sergey RUIN +// Module : SUIT + +#ifndef SPLOT2D_PRS_H +#define SPLOT2D_PRS_H + +#include "SPlot2d.h" +#include "SALOME_Prs.h" +#include "Plot2d_Prs.h" + +#include + +class Plot2d_Curve; + +class SPLOT2D_EXPORT SPlot2d_Prs : public SALOME_Prs2d, public Plot2d_Prs +{ +public: + + // Default constructor + SPlot2d_Prs(); + + // Standard constructor + SPlot2d_Prs( const Plot2d_Curve* obj ); + + SPlot2d_Prs( const Plot2d_Prs* prs ); + + // Destructor + ~SPlot2d_Prs(); + + virtual bool IsNull() const { return Plot2d_Prs::IsNull(); } + + // Get curves list + // Note: Depricated method, use method getCurves + curveList GetObjects() const { return getCurves(); } + +}; + +#endif diff --git a/src/SPlot2d/SPlot2d_ViewModel.cxx b/src/SPlot2d/SPlot2d_ViewModel.cxx new file mode 100644 index 000000000..554927ff5 --- /dev/null +++ b/src/SPlot2d/SPlot2d_ViewModel.cxx @@ -0,0 +1,390 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File : SPlot2d_Viewer.cxx +// Author : Sergey RUIN +// Module : SUIT + +#include "SPlot2d_ViewModel.h" + +#include "SPlot2d_Prs.h" +#include "SUIT_Session.h" +#include "SUIT_Application.h" + +//#include "utilities.h" +#include "qapplication.h" +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +//ASL: Temporary commented in order to avoir dependency on SALOMEDS + +//#include "SALOMEDSClient.hxx" +//#include "SALOMEDS_StudyManager.hxx" + +// in order NOT TO link with SalomeApp, here the code returns SALOMEDS_Study. +// SalomeApp_Study::studyDS() does it as well, but -- here it is retrieved from +// SALOMEDS::StudyManager - no linkage with SalomeApp. + +/*static _PTR(Study) getStudyDS() +{ + SALOMEDSClient_Study* aStudy = NULL; + _PTR(StudyManager) aMgr( new SALOMEDS_StudyManager() ); + + // get id of SUIT_Study, if it's a SalomeApp_Study, it will return + // id of its underlying SALOMEDS::Study + SUIT_Application* app = SUIT_Session::session()->activeApplication(); + if ( !app ) return _PTR(Study)(aStudy); + SUIT_Study* stud = app->activeStudy(); + if ( !stud ) return _PTR(Study)(aStudy); + const int id = stud->id(); // virtual method, must return SALOMEDS_Study id + // get SALOMEDS_Study with this id from StudyMgr + return aMgr->GetStudyByID( id ); +} */ + +//================================================================================= +// SPlot2d_Viewer implementation +//================================================================================= + +/*! + Constructor +*/ +SPlot2d_Viewer::SPlot2d_Viewer( bool theAutoDel ) +: Plot2d_Viewer( theAutoDel ) +{ +} + +/*! + Destructor +*/ +SPlot2d_Viewer::~SPlot2d_Viewer() +{ +} + +/*! + Renames curve if it is found +*/ +void SPlot2d_Viewer::rename( const Handle(SALOME_InteractiveObject)& IObject, + const QString& newName, Plot2d_ViewFrame* fr ) +{ + Plot2d_ViewFrame* aViewFrame = fr ? fr : getActiveViewFrame(); + if( !aViewFrame ) + return; + + QIntDictIterator it( aViewFrame->getCurves() ); + for( ; it.current(); ++it ) + { + SPlot2d_Curve* aCurve = dynamic_cast( it.current() ); + if( aCurve && aCurve->hasIO() && aCurve->getIO()->isSame( IObject ) ) + { + aCurve->setVerTitle( newName ); + int key = aViewFrame->hasCurve( aCurve ); + if( key ) + aViewFrame->setCurveTitle( key, newName ); + } + + if( aCurve && aCurve->hasTableIO() && aCurve->getTableIO()->isSame( IObject ) ) + aCurve->getTableIO()->setName( newName.latin1() ); + } + aViewFrame->updateTitles(); +} + +void SPlot2d_Viewer::renameAll( const Handle(SALOME_InteractiveObject)& IObj, const QString& name ) +{ + SUIT_ViewManager* vm = getViewManager(); + if( vm ) + { + const QPtrVector& wnds = vm->getViews(); + for( int i=0; i( wnds.at( i ) ); + rename( IObj, name, pwnd->getViewFrame() ); + } + } +} + +/*! + Returns true if interactive object is presented in the viewer +*/ +bool SPlot2d_Viewer::isInViewer( const Handle(SALOME_InteractiveObject)& IObject ) +{ + Plot2d_ViewFrame* aViewFrame = getActiveViewFrame(); + if(aViewFrame == NULL) return 0; + + if( getCurveByIO( IObject ) != NULL ) + return 1; + else{ + if(!IObject.IsNull()){ + QIntDictIterator it(aViewFrame->getCurves()); + for(; it.current();++it) { + SPlot2d_Curve* aCurve = dynamic_cast(it.current()); + if(aCurve->hasIO() && aCurve->getTableIO()->isSame(IObject)) + return 1; + } + } + } + return 0; +} + + +/*! + Actually this method just re-displays curves which refers to the +*/ +void SPlot2d_Viewer::Display( const Handle(SALOME_InteractiveObject)& IObject, bool update ) +{ + Plot2d_ViewFrame* aViewFrame = getActiveViewFrame(); + if(aViewFrame == NULL) return; + + SPlot2d_Curve* curve = getCurveByIO( IObject ); + if ( curve ) + aViewFrame->updateCurve( curve, update ); +} + +/*! + Actually this method just erases all curves which don't refer to + and re-displays curve which is of +*/ +void SPlot2d_Viewer::DisplayOnly( const Handle(SALOME_InteractiveObject)& IObject ) +{ + Plot2d_ViewFrame* aViewFrame = getActiveViewFrame(); + if(aViewFrame == NULL) return; + + Plot2d_Curve* curve = getCurveByIO( IObject ); + QIntDictIterator it( aViewFrame->getCurves() ); + for ( ; it.current(); ++it ) { + if(it.current() != curve) + aViewFrame->eraseCurve( curve ); + else + aViewFrame->updateCurve( curve, false ); + } + + aViewFrame->Repaint(); +} + +/*! + Removes from the viewer the curves which refer to +*/ +void SPlot2d_Viewer::Erase( const Handle(SALOME_InteractiveObject)& IObject, bool update ) +{ + Plot2d_ViewFrame* aViewFrame = getActiveViewFrame(); + if(aViewFrame == NULL) return; + + SPlot2d_Curve* curve = getCurveByIO( IObject ); + if ( curve ) + aViewFrame->eraseCurve( curve, update ); + + // it can be table or container object selected + //ASL: Temporary commented in order to avoid dependency on SALOMEDS +/* _PTR(Study) aStudy = getStudyDS(); + _PTR(SObject) aSO = aStudy->FindObjectID(IObject->getEntry()); + if ( aSO ) { + _PTR(ChildIterator) aIter = aStudy->NewChildIterator( aSO ); + for ( ; aIter->More(); aIter->Next() ) { + _PTR(SObject) aChildSO = aIter->Value(); + _PTR(SObject) refSO; + if ( aChildSO->ReferencedObject( refSO ) && refSO ) + aChildSO = refSO; + curve = getCurveByIO( new SALOME_InteractiveObject( aChildSO->GetID().c_str(), "") ); + if ( curve ) + aViewFrame->eraseCurve( curve, update ); + } + } +*/ + +} + +/*! + Removes all curves from the view +*/ +void SPlot2d_Viewer::EraseAll(const bool /*forced*/) +{ + Plot2d_ViewFrame* aViewFrame = getActiveViewFrame(); + if(aViewFrame) aViewFrame->EraseAll(); +} + +/*! + Redraws Viewer contents +*/ +void SPlot2d_Viewer::Repaint() +{ + Plot2d_ViewFrame* aViewFrame = getActiveViewFrame(); + if(aViewFrame) aViewFrame->Repaint(); +} + +//========================================================== +/*! + * SPlot2d_Viewer::Display + * Display presentation + */ +//========================================================== +void SPlot2d_Viewer::Display( const SALOME_Prs2d* prs ) +{ + Plot2d_ViewFrame* aViewFrame = getActiveViewFrame(); + Plot2d_Prs* aPrs = dynamic_cast(const_cast(prs)); + if(aViewFrame && aPrs) aViewFrame->Display(aPrs); +} + +//========================================================== +/*! + * SPlot2d_Viewer::Erase + * Erase presentation + */ +//========================================================== +void SPlot2d_Viewer::Erase( const SALOME_Prs2d* prs, const bool ) +{ + Plot2d_ViewFrame* aViewFrame = getActiveViewFrame(); + Plot2d_Prs* aPrs = dynamic_cast(const_cast(prs)); + if(aViewFrame && aPrs) aViewFrame->Erase(aPrs); +} + +//========================================================== +/*! + * SPlot2d_Viewer::CreatePrs + * Create presentation by entry + */ +//========================================================== +SALOME_Prs* SPlot2d_Viewer::CreatePrs( const char* entry ) +{ + Plot2d_ViewFrame* aViewFrame = getActiveViewFrame(); + if(aViewFrame) + { + Plot2d_Prs* prs = aViewFrame->CreatePrs(entry); + if( prs ) + return new SPlot2d_Prs( prs ); + } + + return NULL; +} + +//========================================================== +/*! + * SPlot2d_Viewer::BeforeDisplay + * Axiluary method called before displaying of objects + */ +//========================================================== +void SPlot2d_Viewer::BeforeDisplay( SALOME_Displayer* d ) +{ + d->BeforeDisplay( this, SALOME_Plot2dViewType() ); +} + +//========================================================== +/*! + * SPlot2d_Viewer::AfterDisplay + * Axiluary method called after displaying of objects + */ +//========================================================== +void SPlot2d_Viewer::AfterDisplay( SALOME_Displayer* d ) +{ + d->AfterDisplay( this, SALOME_Plot2dViewType() ); +} + +/*! + Returns true if interactive object is presented in the viewer and displayed +*/ +bool SPlot2d_Viewer::isVisible( const Handle(SALOME_InteractiveObject)& IObject ) +{ + Plot2d_ViewFrame* aViewFrame = getActiveViewFrame(); + if(aViewFrame == NULL) return false; + + SPlot2d_Curve* curve = getCurveByIO( IObject ); + return aViewFrame->isVisible( curve ); +} + +/*! + Return interactive obeject if is presented in the viewer +*/ +Handle(SALOME_InteractiveObject) SPlot2d_Viewer::FindIObject( const char* Entry ) +{ + Handle(SALOME_InteractiveObject) anIO; + Plot2d_ViewFrame* aViewFrame = getActiveViewFrame(); + if(aViewFrame == NULL) return anIO; + + QIntDictIterator it( aViewFrame->getCurves() ); + for ( ; it.current(); ++it ) { + SPlot2d_Curve* aCurve = dynamic_cast(it.current()); + if ( aCurve->hasIO() && !strcmp( aCurve->getIO()->getEntry(), Entry ) ) { + anIO = aCurve->getIO(); + break; + } + } + return anIO; +} + +//========================================================== +/*! + * SPlot2d_Viewer::getActiveViewFrame + * Returns an active Plot2d ViewFrame or NULL + */ +//========================================================== +Plot2d_ViewFrame* SPlot2d_Viewer::getActiveViewFrame() +{ + SUIT_ViewManager* aViewMgr = getViewManager(); + if(aViewMgr) { + Plot2d_ViewWindow* aViewWnd = dynamic_cast(aViewMgr->getActiveView()); + if(aViewWnd) + return aViewWnd->getViewFrame(); + } + + return NULL; +} + +SPlot2d_Curve* SPlot2d_Viewer::getCurveByIO( const Handle(SALOME_InteractiveObject)& theIObject, + Plot2d_ViewFrame* fr ) +{ + if ( !theIObject.IsNull() ) { + Plot2d_ViewFrame* aViewFrame = fr ? fr : getActiveViewFrame(); + if(aViewFrame) { + QIntDictIterator it( aViewFrame->getCurves() ); + for ( ; it.current(); ++it ) { + SPlot2d_Curve* aCurve = dynamic_cast(it.current()); + if(aCurve) { + if ( aCurve->hasIO() && aCurve->getIO()->isSame( theIObject ) ) + return aCurve; + } + } + } + } + return NULL; +} + +void SPlot2d_Viewer::onCloneView( Plot2d_ViewFrame* clonedVF, Plot2d_ViewFrame* newVF ) +{ + if( !clonedVF || !newVF ) + return; + + // 1) Copy all properties of view + + newVF->copyPreferences( clonedVF ); + + // 2) Display all curves displayed in cloned view + + QList aCurves; + clonedVF->getCurves( aCurves ); + QList::const_iterator anIt = aCurves.begin(), aLast = aCurves.end(); + + for( ; anIt!=aLast; anIt++ ) + if( clonedVF->isVisible( *anIt ) ) + newVF->displayCurve( *anIt, false ); + newVF->Repaint(); +} diff --git a/src/SPlot2d/SPlot2d_ViewModel.h b/src/SPlot2d/SPlot2d_ViewModel.h new file mode 100644 index 000000000..09005da78 --- /dev/null +++ b/src/SPlot2d/SPlot2d_ViewModel.h @@ -0,0 +1,86 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// File : SPlot2d_ViewModel.h +// Author : Sergey RUIN +// Module : SUIT + +#ifndef SPlot2d_ViewModel_H +#define SPlot2d_ViewModel_H + +#include "SPlot2d.h" + +#include "SALOME_Prs.h" +#include "Plot2d_ViewModel.h" +#include "SALOME_InteractiveObject.hxx" +#include "Plot2d_ViewFrame.h" +#include "Plot2d_ViewWindow.h" +#include "SPlot2d_Curve.h" + +class SPLOT2D_EXPORT SPlot2d_Viewer : public Plot2d_Viewer, public SALOME_View +{ + Q_OBJECT + +public: + static QString Type() { return "Plot2d"; } + + /* Construction/destruction */ + SPlot2d_Viewer( bool theAutoDel = false ); + virtual ~SPlot2d_Viewer(); + +public: + virtual QString getType() const { return Type(); } + + /* interactive object management */ + void highlight( const Handle(SALOME_InteractiveObject)& IObject, bool highlight, bool update = true ) {} + void unHighlightAll() {} + void rename( const Handle(SALOME_InteractiveObject)&, const QString&, Plot2d_ViewFrame* = 0 ); + void renameAll( const Handle(SALOME_InteractiveObject)&, const QString& ); + bool isInViewer( const Handle(SALOME_InteractiveObject)& IObject ); + + /* display */ + void Display( const Handle(SALOME_InteractiveObject)& IObject, bool update = true ); + void DisplayOnly( const Handle(SALOME_InteractiveObject)& IObject ); + void Erase( const Handle(SALOME_InteractiveObject)& IObject, bool update = true ); + + /* Reimplemented from SALOME_View */ + void Display( const SALOME_Prs2d* ); + void Erase( const SALOME_Prs2d*, const bool = false ); + virtual void EraseAll(const bool = false); + virtual void Repaint(); + virtual SALOME_Prs* CreatePrs( const char* entry = 0 ); + virtual void BeforeDisplay( SALOME_Displayer* d ); + virtual void AfterDisplay ( SALOME_Displayer* d ); + virtual bool isVisible( const Handle(SALOME_InteractiveObject)& IObject ); + + + /* operations */ + SPlot2d_Curve* getCurveByIO( const Handle(SALOME_InteractiveObject)&, Plot2d_ViewFrame* = 0 ); + Plot2d_ViewFrame* getActiveViewFrame(); + Handle(SALOME_InteractiveObject) FindIObject( const char* Entry ); + +protected slots: + virtual void onCloneView( Plot2d_ViewFrame*, Plot2d_ViewFrame* ); +}; + + +#endif // SPlot2d_ViewModel_H + + + + diff --git a/src/SPlot2d/SPlot2d_msg_en.po b/src/SPlot2d/SPlot2d_msg_en.po new file mode 100644 index 000000000..0653ee888 --- /dev/null +++ b/src/SPlot2d/SPlot2d_msg_en.po @@ -0,0 +1,12 @@ +# This is a Qt message file in .po format. Each msgid starts with +# a scope. This scope should *NOT* be translated - eg. translating +# from French to English, "Foo::Bar" would be translated to "Pub", +# not "Foo::Pub". +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2005-06-16 12:01:13 PM MSD\n" +"PO-Revision-Date: YYYY-MM-DD\n" +"Last-Translator: FULLNAME \n" +"Content-Type: text/plain; charset=iso-8859-1\n" + diff --git a/src/STD/STD.h b/src/STD/STD.h new file mode 100755 index 000000000..d74b12e09 --- /dev/null +++ b/src/STD/STD.h @@ -0,0 +1,56 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef STD_H +#define STD_H + +#if defined STD_EXPORTS +#if defined WNT +#define STD_EXPORT __declspec( dllexport ) +#else +#define STD_EXPORT +#endif +#else +#if defined WNT +#define STD_EXPORT __declspec( dllimport ) +#else +#define STD_EXPORT +#endif +#endif + +#if defined SOLARIS +#define bool int +#define false 0 +#define true 1 +#endif + +#if defined WNT +#pragma warning ( disable: 4251 ) +#endif + +#if defined ( _DEBUG ) || defined ( DEBUG ) +#include +#define STD_VERIFY(x) (assert(x)) +#define STD_ASSERT(x) (assert(x)) +#else +#define STD_VERIFY(x) (x) +#define STD_ASSERT(x) +#endif + + +#endif diff --git a/src/STD/STD_CloseDlg.cxx b/src/STD/STD_CloseDlg.cxx new file mode 100644 index 000000000..a06d8c6c5 --- /dev/null +++ b/src/STD/STD_CloseDlg.cxx @@ -0,0 +1,103 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "STD_CloseDlg.h" + +#include +#include +#include +#include +#include + +#ifndef WNT +using namespace std; +#endif + +/*! + * \brief creates a Close dialog box + * \param parent a parent widget + * \param modal bool argument, if true the dialog box is a modal dialog box + * \param f style flags + */ + +STD_CloseDlg::STD_CloseDlg( QWidget* parent, bool modal, WFlags f ) +: QDialog( parent, "", true, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu ) +{ + setSizeGripEnabled( true ); + setCaption( tr( "CLOSE_DLG_CAPTION" ) ); + + QVBoxLayout* m_vbL = new QVBoxLayout( this ); + m_vbL->setMargin( 11 ); + m_vbL->setSpacing( 6 ); + + QLabel* m_lIcon = new QLabel( this, "m_lDescr" ); + QPixmap pm = QMessageBox::standardIcon( QMessageBox::Warning ); + m_lIcon->setPixmap( pm ); + m_lIcon->setScaledContents( false ); + m_lIcon->setAlignment( Qt::AlignCenter ); + + QLabel* m_lDescr = new QLabel (this, "m_lDescr"); + m_lDescr->setText ( tr ("CLOSE_DLG_DESCRIPTION") ); + m_lDescr->setAlignment( Qt::AlignCenter ); + m_lDescr->setMinimumHeight( m_lDescr->sizeHint().height()*5 ); + m_lDescr->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) ); + + QHBoxLayout* m_hl1 = new QHBoxLayout(); + m_hl1->setMargin( 0 ); m_hl1->setSpacing( 6 ); + m_hl1->addWidget( m_lIcon ); + m_hl1->addWidget( m_lDescr ); + + m_pb1 = new QPushButton( tr ("CLOSE_DLG_SAVE_CLOSE"), this ); + m_pb2 = new QPushButton( tr ("CLOSE_DLG_CLOSE"), this ); + m_pb3 = new QPushButton( tr ("CLOSE_DLG_UNLOAD"), this ); + m_pb4 = new QPushButton( tr ("BUT_CANCEL"), this ); + + QGridLayout* m_hl2 = new QGridLayout(); + m_hl2->setMargin( 0 ); m_hl2->setSpacing( 6 ); + m_hl2->addWidget( m_pb1, 0, 0 ); + m_hl2->addWidget( m_pb2, 0, 1 ); + m_hl2->addWidget( m_pb3, 0, 2 ); + m_hl2->addColSpacing( 3, 10 ); + m_hl2->setColStretch( 3, 5 ); + m_hl2->addWidget( m_pb4, 0, 4 ); + + m_vbL->addLayout( m_hl1 ); + m_vbL->addLayout( m_hl2 ); + + connect( m_pb1, SIGNAL( clicked() ), this, SLOT( onButtonClicked() ) ); + connect( m_pb2, SIGNAL( clicked() ), this, SLOT( onButtonClicked() ) ); + connect( m_pb3, SIGNAL( clicked() ), this, SLOT( onButtonClicked() ) ); + connect( m_pb4, SIGNAL( clicked() ), this, SLOT( reject() ) ); +} + +//================================================================================ +/*! + * \brief reaction on clicked(pressed) button + */ +//================================================================================ + +void STD_CloseDlg::onButtonClicked() +{ + QPushButton* btn = ( QPushButton* )sender(); + if ( btn == m_pb1 ) + done( 1 ); + if ( btn == m_pb2 ) + done( 2 ); + if ( btn == m_pb3 ) + done( 3 ); +} diff --git a/src/STD/STD_CloseDlg.h b/src/STD/STD_CloseDlg.h new file mode 100644 index 000000000..a7ec4616d --- /dev/null +++ b/src/STD/STD_CloseDlg.h @@ -0,0 +1,62 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef STD_CloseDlg_H +#define STD_CloseDlg_H + +#include + +/*! \class QDialog + * \brief For more information see QT documentation. + */ +/*!\class STD_CloseDlg + * \brief Describes a dialog box shown on closing the active study + */ +class STD_CloseDlg: public QDialog +{ + Q_OBJECT + +public: + STD_CloseDlg ( QWidget * parent = 0, bool modal = FALSE, WFlags f = 0 ) ; + ~STD_CloseDlg ( ) { }; + +private slots: + void onButtonClicked(); + +private: + /*!\var m_pb1 + * \brief Private, stores a dialog button 1 + */ + QPushButton* m_pb1; + /*!\var m_pb2 + * \brief Private, stores a dialog button 2 + */ + QPushButton* m_pb2; + /*!\var m_pb3 + * \brief Private, stores a dialog button 3 + */ + QPushButton* m_pb3; + + /*!\var m_pb4 + * \brief Private, stores a dialog button 4 + */ + QPushButton* m_pb4; +}; + +#endif + diff --git a/src/STD/STD_LoadStudiesDlg.cxx b/src/STD/STD_LoadStudiesDlg.cxx new file mode 100644 index 000000000..b8a655249 --- /dev/null +++ b/src/STD/STD_LoadStudiesDlg.cxx @@ -0,0 +1,84 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "STD_LoadStudiesDlg.h" + +#include +#include +#include +#include + +#define SPACING_SIZE 6 +#define MARGIN_SIZE 11 +#define MIN_LISTBOX_WIDTH 150 +#define MIN_LISTBOX_HEIGHT 100 + +/*! +* \brief creates a Load study dialog box +* \param parent a parent widget +* \param modal bool argument, if true the dialog box is a modal dialog box +* \param f style flags +*/ + +STD_LoadStudiesDlg::STD_LoadStudiesDlg( QWidget* parent, bool modal, WFlags fl ) +: QDialog( parent, "STD_LoadStudiesDlg", modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu ) +{ + resize( 321, 181 ); + setCaption( tr("DLG_LOAD_STUDY_CAPTION") ); + setSizeGripEnabled( TRUE ); + + QGridLayout* aTopLayout = new QGridLayout(this); + aTopLayout->setMargin(MARGIN_SIZE); + aTopLayout->setSpacing(SPACING_SIZE); + + TextLabel1 = new QLabel( this, "TextLabel1" ); + TextLabel1->setGeometry( QRect( 11, 12, 297, 16 ) ); + TextLabel1->setText( tr( "MEN_STUDIES_CHOICE" ) ); + + QHBoxLayout* aBtnLayout = new QHBoxLayout; + aBtnLayout->setSpacing( SPACING_SIZE ); + aBtnLayout->setMargin( 0 ); + + buttonOk = new QPushButton( this, "buttonOk" ); + buttonOk->setText( tr( "BUT_OK" ) ); + buttonOk->setAutoDefault( true ); + buttonOk->setDefault( true ); + + buttonCancel = new QPushButton( this, "buttonCancel" ); + buttonCancel->setText( tr( "BUT_CANCEL" ) ); + buttonCancel->setAutoDefault( true ); + + aBtnLayout->addWidget( buttonOk ); + aBtnLayout->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ) ); + aBtnLayout->addWidget( buttonCancel ); + + ListComponent = new QListBox( this, "ListComponent" ); + ListComponent->setVScrollBarMode(QListBox::AlwaysOn); + ListComponent->setMinimumSize(MIN_LISTBOX_WIDTH, MIN_LISTBOX_HEIGHT); + ListComponent->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding)); + ListComponent->setSelectionMode(QListBox::Single); + + aTopLayout->addWidget(TextLabel1, 0, 0); + aTopLayout->addWidget(ListComponent, 1, 0); + aTopLayout->addLayout(aBtnLayout, 2, 0); + + // signals and slots connections + connect( buttonOk, SIGNAL( clicked() ), this, SLOT( accept() ) ); + connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( reject() ) ); +} + diff --git a/src/STD/STD_LoadStudiesDlg.h b/src/STD/STD_LoadStudiesDlg.h new file mode 100644 index 000000000..141d064da --- /dev/null +++ b/src/STD/STD_LoadStudiesDlg.h @@ -0,0 +1,69 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef STD_LOADSTUDIESDLG_H +#define STD_LOADSTUDIESDLG_H + +#include + +#include +#include + +class QLabel; +class QListBox; +class QPushButton; +class QVBoxLayout; +class QHBoxLayout; +class QGridLayout; +class QListBoxItem; + +/*!\class STD_LoadStudiesDlg + * \brief Describes a dialog box that gives a list of opened studies. + * + */ +class STD_EXPORT STD_LoadStudiesDlg : public QDialog +{ + Q_OBJECT + +public: + STD_LoadStudiesDlg( QWidget* parent = 0, bool modal = FALSE, WFlags fl = 0 ); + ~STD_LoadStudiesDlg() {} + + /*!\var TextLabel1 + * \brief stores a dialog text label + */ + QLabel* TextLabel1; + + /*!\var buttonOk + * \brief stores a dialog button OK + */ + QPushButton* buttonOk; + + /*!\var buttonCancel + * \brief stores a dialog button Cancel + */ + QPushButton* buttonCancel; + + /*!\var ListComponent + * \brief stores a dialog list compoent + */ + QListBox* ListComponent; + +}; + +#endif // STD_LOADSTUDIESDLG_H diff --git a/src/STD/STD_MDIDesktop.cxx b/src/STD/STD_MDIDesktop.cxx new file mode 100755 index 000000000..aec25bb59 --- /dev/null +++ b/src/STD/STD_MDIDesktop.cxx @@ -0,0 +1,211 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "STD_MDIDesktop.h" + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include + +/*!Constructor.*/ +STD_MDIDesktop::STD_MDIDesktop() +: SUIT_Desktop(), +myWorkspace( 0 ), +myWorkspaceAction( 0 ) +{ + QVBox* base = new QVBox( this ); + base->setFrameStyle( QFrame::Panel | QFrame::Sunken ); + + setCentralWidget( base ); + + myWorkspace = new QWorkspace( base ); + + connect( myWorkspace, SIGNAL( windowActivated( QWidget* ) ), + this, SLOT( onWindowActivated( QWidget* ) ) ); + + createActions(); +} + +/*!destructor.*/ +STD_MDIDesktop::~STD_MDIDesktop() +{ +} + +/*!\retval SUIT_ViewWindow - return const active window.*/ +SUIT_ViewWindow* STD_MDIDesktop::activeWindow() const +{ + SUIT_ViewWindow* wnd = 0; + + QWidget* wid = myWorkspace->activeWindow(); + if ( wid && wid->inherits( "SUIT_ViewWindow" ) ) + wnd = (SUIT_ViewWindow*)wid; + + return wnd; +} + +/*!\retval QPtrList - return const active window list.*/ +QPtrList STD_MDIDesktop::windows() const +{ + QPtrList winList; + + QWidgetList children = myWorkspace->windowList(); + for ( QWidgetListIt it( children ); it.current(); ++it ) + { + if ( it.current()->inherits( "SUIT_ViewWindow" ) ) + winList.append( (SUIT_ViewWindow*)it.current() ); + } + + return winList; +} + +/*!\retval QWidget - pointer to work space.*/ +QWidget* STD_MDIDesktop::parentArea() const +{ + return workspace(); +} + +/*!Call method perform for operation \a type.*/ +void STD_MDIDesktop::windowOperation( const int type ) +{ + myWorkspaceAction->perform( operationFlag( type ) ); +} + +/*!Sets window operations by \a first ... parameters.*/ +void STD_MDIDesktop::setWindowOperations( const int first, ... ) +{ + va_list ints; + va_start( ints, first ); + + QValueList typeList; + + int cur = first; + while ( cur ) + { + typeList.append( cur ); + cur = va_arg( ints, int ); + } + + setWindowOperations( typeList ); +} + +/*!Sets window operations by variable \a opList - operation list.*/ +void STD_MDIDesktop::setWindowOperations( const QValueList& opList ) +{ + int flags = 0; + + for ( QValueList::const_iterator it = opList.begin(); it != opList.end(); ++it ) + flags = flags | operationFlag( *it ); + + myWorkspaceAction->setItems( flags ); +} + +/*!\retval QWorkspace pointer - work space.*/ +QWorkspace* STD_MDIDesktop::workspace() const +{ + return myWorkspace; +} + +/*!Emit window activated.*/ +void STD_MDIDesktop::onWindowActivated( QWidget* w ) +{ + if ( w && w->inherits( "SUIT_ViewWindow" ) ) + emit windowActivated( (SUIT_ViewWindow*)w ); +} + +/*!Create actions: cascade, Tile, Tile Horizontal, Tile Vertical*/ +void STD_MDIDesktop::createActions() +{ + if ( myWorkspaceAction ) + return; + + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + if ( !resMgr ) + return; + + myWorkspaceAction = new QtxWorkspaceAction( workspace(), this ); + + myWorkspaceAction->setItems( QtxWorkspaceAction::Cascade | QtxWorkspaceAction::Tile | + QtxWorkspaceAction::HTile | QtxWorkspaceAction::VTile | + QtxWorkspaceAction::Windows ); + + // Cascade + myWorkspaceAction->setIconSet( QtxWorkspaceAction::Cascade, + resMgr->loadPixmap( "STD", tr( "ICON_DESK_WINDOW_CASCADE" ) ) ); + myWorkspaceAction->setMenuText( QtxWorkspaceAction::Cascade, tr( "MEN_DESK_WINDOW_CASCADE" ) ); + myWorkspaceAction->setStatusTip( QtxWorkspaceAction::Cascade, tr( "PRP_DESK_WINDOW_CASCADE" ) ); + + // Tile + myWorkspaceAction->setIconSet( QtxWorkspaceAction::Tile, + resMgr->loadPixmap( "STD", tr( "ICON_DESK_WINDOW_TILE" ) ) ); + myWorkspaceAction->setMenuText( QtxWorkspaceAction::Tile, tr( "MEN_DESK_WINDOW_TILE" ) ); + myWorkspaceAction->setStatusTip( QtxWorkspaceAction::Tile, tr( "PRP_DESK_WINDOW_TILE" ) ); + + // Tile Horizontal + myWorkspaceAction->setIconSet( QtxWorkspaceAction::HTile, + resMgr->loadPixmap( "STD", tr( "ICON_DESK_WINDOW_HTILE" ) ) ); + myWorkspaceAction->setMenuText( QtxWorkspaceAction::HTile, tr( "MEN_DESK_WINDOW_HTILE" ) ); + myWorkspaceAction->setStatusTip( QtxWorkspaceAction::HTile, tr( "PRP_DESK_WINDOW_HTILE" ) ); + + // Tile Vertical + myWorkspaceAction->setIconSet( QtxWorkspaceAction::VTile, + resMgr->loadPixmap( "STD", tr( "ICON_DESK_WINDOW_VTILE" ) ) ); + myWorkspaceAction->setMenuText( QtxWorkspaceAction::VTile, tr( "MEN_DESK_WINDOW_VTILE" ) ); + myWorkspaceAction->setStatusTip( QtxWorkspaceAction::VTile, tr( "PRP_DESK_WINDOW_VTILE" ) ); + + + QtxActionMenuMgr* mMgr = menuMgr(); + if ( !mMgr ) + return; + + int winMenuId = mMgr->insert( tr( "MEN_DESK_WINDOW" ), -1, 100 ); + mMgr->insert( myWorkspaceAction, winMenuId, -1 ); + mMgr->insert( QtxActionMenuMgr::separator(), winMenuId, -1 ); +} + +/*!Convert STD_MDIDesktop enumerations to QtxWorkspaceAction.*/ +int STD_MDIDesktop::operationFlag( const int type ) const +{ + int res = 0; + switch ( type ) + { + case Cascade: + res = QtxWorkspaceAction::Cascade; + break; + case Tile: + res = QtxWorkspaceAction::Tile; + break; + case HTile: + res = QtxWorkspaceAction::HTile; + break; + case VTile: + res = QtxWorkspaceAction::VTile; + break; + } + return res; +} diff --git a/src/STD/STD_MDIDesktop.h b/src/STD/STD_MDIDesktop.h new file mode 100755 index 000000000..25ec9cb08 --- /dev/null +++ b/src/STD/STD_MDIDesktop.h @@ -0,0 +1,75 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef STD_MDIDESKTOP_H +#define STD_MDIDESKTOP_H + +#include "STD.h" + +#include + +class QtxAction; +class QPopupMenu; +class QWorkspace; +class QtxWorkspaceAction; + +#if defined WNT +#pragma warning( disable: 4251 ) +#endif + +class STD_EXPORT STD_MDIDesktop: public SUIT_Desktop +{ + Q_OBJECT + +public: + enum { Cascade, Tile, HTile, VTile }; + +public: + STD_MDIDesktop(); + virtual ~STD_MDIDesktop(); + + virtual SUIT_ViewWindow* activeWindow() const; + virtual QPtrList windows() const; + + void windowOperation( const int ); + + void setWindowOperations( const int, ... ); + void setWindowOperations( const QValueList& ); + + QWorkspace* workspace() const; + +private slots: + void onWindowActivated( QWidget* ); + +protected: + void createActions(); + virtual QWidget* parentArea() const; + +private: + int operationFlag( const int ) const; + +private: + QWorkspace* myWorkspace; + QtxWorkspaceAction* myWorkspaceAction; +}; + +#if defined WNT +#pragma warning( default: 4251 ) +#endif + +#endif diff --git a/src/STD/STD_SDIDesktop.cxx b/src/STD/STD_SDIDesktop.cxx new file mode 100755 index 000000000..a3a04ca5e --- /dev/null +++ b/src/STD/STD_SDIDesktop.cxx @@ -0,0 +1,81 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "STD_SDIDesktop.h" + +#include + +#include +#include +#include + +/*!Constructor. Create instance of QVBox*/ +STD_SDIDesktop::STD_SDIDesktop() +: SUIT_Desktop() +{ + myMainWidget = new QVBox( this ); + myMainWidget->setFrameStyle( QFrame::Panel | QFrame::Sunken ); + + setCentralWidget( myMainWidget ); +} + +/*!Destructor.*/ +STD_SDIDesktop::~STD_SDIDesktop() +{ +} + +/*!\retval SUIT_ViewWindow - return const active window.*/ +SUIT_ViewWindow* STD_SDIDesktop::activeWindow() const +{ + const QObjectList* children = myMainWidget->children(); + if ( !children ) + return 0; + + QPtrList winList; + for ( QObjectListIt it( *children ); it.current(); ++it ) + { + if ( it.current()->inherits( "SUIT_ViewWindow" ) ) + winList.append( (SUIT_ViewWindow*)it.current() ); + } + + SUIT_ViewWindow* win = 0; + for ( QPtrListIterator itr( winList ); itr.current() && !win; ++itr ) + { + if ( itr.current()->isActiveWindow() ) + win = itr.current(); + } + + if ( !win && !winList.isEmpty() ) + win = winList.getFirst(); + + return win; +} + +/*!\retval QPtrList - return const active window list.*/ +QPtrList STD_SDIDesktop::windows() const +{ + QPtrList winList; + winList.append( activeWindow() ); + return winList; +} + +/*!\retval QWidget - pointer to main window.*/ +QWidget* STD_SDIDesktop::parentArea() const +{ + return myMainWidget; +} diff --git a/src/STD/STD_SDIDesktop.h b/src/STD/STD_SDIDesktop.h new file mode 100755 index 000000000..91184b8ce --- /dev/null +++ b/src/STD/STD_SDIDesktop.h @@ -0,0 +1,46 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef STD_SDIDESKTOP_H +#define STD_SDIDESKTOP_H + +#include "STD.h" + +#include + +class QVBox; + +class STD_EXPORT STD_SDIDesktop: public SUIT_Desktop +{ + Q_OBJECT + +public: + STD_SDIDesktop(); + virtual ~STD_SDIDesktop(); + + virtual SUIT_ViewWindow* activeWindow() const; + virtual QPtrList windows() const; + +protected: + virtual QWidget* parentArea() const; + +private: + QVBox* myMainWidget; +}; + +#endif diff --git a/src/STD/STD_TabDesktop.h b/src/STD/STD_TabDesktop.h new file mode 100644 index 000000000..f3b1d1282 --- /dev/null +++ b/src/STD/STD_TabDesktop.h @@ -0,0 +1,76 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef STD_TABDESKTOP_H +#define STD_TABDESKTOP_H + +#include "STD.h" + +#include + +class QtxAction; +class QPopupMenu; +class QWorkspace; +class QtxWorkstack; +class QtxWorkstackAction; + +#if defined WNT +#pragma warning( disable: 4251 ) +#endif + +class STD_EXPORT STD_TabDesktop: public SUIT_Desktop +{ + Q_OBJECT + +public: + enum { VSplit, HSplit }; + +public: + STD_TabDesktop(); + virtual ~STD_TabDesktop(); + + virtual SUIT_ViewWindow* activeWindow() const; + virtual QPtrList windows() const; + + void windowOperation( const int ); + + void setWindowOperations( const int, ... ); + void setWindowOperations( const QValueList& ); + + QtxWorkstack* workstack() const; + +private slots: + void onWindowActivated( QWidget* ); + +protected: + void createActions(); + virtual QWidget* parentArea() const; + +private: + int operationFlag( const int ) const; + +private: + QtxWorkstack* myWorkstack; + QtxWorkstackAction* myWorkstackAction; +}; + +#if defined WNT +#pragma warning( default: 4251 ) +#endif + +#endif diff --git a/src/SUIT/SUIT.h b/src/SUIT/SUIT.h new file mode 100755 index 000000000..b84cf06ef --- /dev/null +++ b/src/SUIT/SUIT.h @@ -0,0 +1,55 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SUIT_H +#define SUIT_H + +#if defined SUIT_EXPORTS +#if defined WNT +#define SUIT_EXPORT __declspec( dllexport ) +#else +#define SUIT_EXPORT +#endif +#else +#if defined WNT +#define SUIT_EXPORT __declspec( dllimport ) +#else +#define SUIT_EXPORT +#endif +#endif + +#if defined SOLARIS +#define bool int +#define false 0 +#define true 1 +#endif + +#if defined WNT +#pragma warning ( disable: 4251 ) +#endif + +#if defined ( _DEBUG ) || defined ( DEBUG ) +#include +#define SUIT_VERIFY(x) assert( x ); +#define SUIT_ASSERT(x) assert( x ); +#else +#define SUIT_VERIFY(x) x +#define SUIT_ASSERT(x) +#endif + +#endif diff --git a/src/SUIT/SUIT_Accel.cxx b/src/SUIT/SUIT_Accel.cxx new file mode 100644 index 000000000..a72a317e1 --- /dev/null +++ b/src/SUIT/SUIT_Accel.cxx @@ -0,0 +1,80 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// SUIT_Accel.cxx: implementation of the SUIT_Accel class. +// +////////////////////////////////////////////////////////////////////// + +#include "SUIT_Accel.h" +#include "SUIT_Desktop.h" +#include "SUIT_ViewManager.h" +#include "SUIT_ViewWindow.h" +#include "SUIT_ViewModel.h" + +#include + +/*!\class SUIT_Accel + * Class handles keyboard accelerator bindings. + */ + +/*! Constructor.*/ +SUIT_Accel::SUIT_Accel(SUIT_Desktop* theDesktop) + : QObject( theDesktop, "SUIT_Accel" ), + myDesktop( theDesktop ) +{ + myAccel = new QAccel( theDesktop, "SUIT_Accel_interal_qaccel" ); + connect( myAccel, SIGNAL( activated( int ) ), this, SLOT( onActivated( int ) ) ); +} + +/*! Destructor.*/ +SUIT_Accel::~SUIT_Accel() +{ +} + +/*! setActionKey assign a ceratain action for a key accelerator */ +void SUIT_Accel::setActionKey( const int action, const int key, const QString& type ) +{ + // 1. get or generate interal "id" of action + int id = myAccel->findKey( key ); + if ( id == -1 ) + id = myAccel->insertItem( key ); + + IdActionMap idActionMap; + if ( myMap.contains( type ) ) + idActionMap = myMap[type]; + + idActionMap[id] = action; + myMap[type] = idActionMap; +} + +/*! onActivated slot called when a registered key accelerator was activated */ +void SUIT_Accel::onActivated( int id ) +{ + if ( myDesktop ) { + if ( SUIT_ViewWindow* vw = myDesktop->activeWindow() ) { + QString type = vw->getViewManager()->getViewModel()->getType(); + if ( myMap.contains( type ) ) { + IdActionMap idActionMap = myMap[type]; + if ( idActionMap.contains( id ) ) { + vw->onAccelAction( idActionMap[id] ); + } + } + } + } +} + diff --git a/src/SUIT/SUIT_Accel.h b/src/SUIT/SUIT_Accel.h new file mode 100644 index 000000000..78c9bff30 --- /dev/null +++ b/src/SUIT/SUIT_Accel.h @@ -0,0 +1,73 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// SUIT_Accel.h: interface for the SUIT_Accel class. +// +////////////////////////////////////////////////////////////////////// + +#ifndef SUIT_Accel_h +#define SUIT_Accel_h + +#include "SUIT.h" + +#include +#include +#include + +class QAccel; +class SUIT_Desktop; + +class SUIT_EXPORT SUIT_Accel: public QObject +{ + Q_OBJECT + +public: + enum Actions { + PanLeft = 1, + PanRight, + PanUp, + PanDown, + ZoomIn, + ZoomOut, + ZoomFit, + RotateLeft, + RotateRight, + RotateUp, + RotateDown, + LastAction + }; + +public: + SUIT_Accel( SUIT_Desktop* theDesktop ); + virtual ~SUIT_Accel(); + + void setActionKey( const int action, const int key, const QString& type ); + +protected slots: + void onActivated( int ); + +private: + QAccel* myAccel; + SUIT_Desktop* myDesktop; + + typedef QMap IdActionMap; // internal_id - to - action map + typedef QMap ViewerTypeIdActionMap; // viewer_type - to - IdActionMap + ViewerTypeIdActionMap myMap; +}; + +#endif diff --git a/src/SUIT/SUIT_ActionOperation.cxx b/src/SUIT/SUIT_ActionOperation.cxx new file mode 100644 index 000000000..8c24cf59a --- /dev/null +++ b/src/SUIT/SUIT_ActionOperation.cxx @@ -0,0 +1,110 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "SUIT_ActionOperation.h" + +#include "SUIT_Application.h" + +#include + +/*! + Constructor. +*/ +SUIT_ActionOperation::SUIT_ActionOperation( SUIT_Application* app ) +: SUIT_Operation( app ), +myAction( 0 ) +{ +} + +/*! + Destructor. +*/ +SUIT_ActionOperation::~SUIT_ActionOperation() +{ +} + +/*! + Gets action. +*/ +QtxAction* SUIT_ActionOperation::action() const +{ + return myAction; +} + +/*!Set action. + * Create new instance of QtxAction and set. + */ +void SUIT_ActionOperation::setAction( const QString& text, const QIconSet& icon, + const QString& menuText, QKeySequence accel, + QObject* parent, const char* name, bool toggle ) +{ + setAction( new QtxAction( text, icon, menuText, accel, parent, name, toggle ) ); +} + +/*!Set action. + * Create new instance of QtxAction and set. + */ +void SUIT_ActionOperation::setAction( const QString& text, const QString& menuText, + QKeySequence accel, QObject* parent, const char* name, bool toggle ) +{ + setAction( new QtxAction(text, menuText, accel, parent, name, toggle ) ); +} + +/*!Set action. + */ +void SUIT_ActionOperation::setAction( QtxAction* a ) +{ + if ( myAction == a ) + return; + + delete myAction; + myAction = a; + + myAction->setEnabled( application()->activeStudy() ); + connect( myAction, SIGNAL( activated() ), SLOT( start() ) ); +} + +/*! Add action to widget \a wid. + *\retval TRUE - successful, FALSE - not successful. + */ +bool SUIT_ActionOperation::addTo( QWidget* wid ) +{ + if ( !action() ) + return false; + + return action()->addTo( wid ); +} + +/*! Add action to widget \a wid. + *\retval TRUE - successful, FALSE - not successful. + */ +bool SUIT_ActionOperation::addTo( QWidget* wid, int idx ) +{ + if ( !action() ) + return false; + + return action()->addTo( wid, idx ); +} + +/*! Set status tip for action. +*/ +void SUIT_ActionOperation::setStatusTip( const QString& tip ) +{ + if ( action() ) + action()->setStatusTip( tip ); +} diff --git a/src/SUIT/SUIT_ActionOperation.h b/src/SUIT/SUIT_ActionOperation.h new file mode 100644 index 000000000..c9e9d774d --- /dev/null +++ b/src/SUIT/SUIT_ActionOperation.h @@ -0,0 +1,62 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SUIT_ACTIONOPERATION_H +#define SUIT_ACTIONOPERATION_H + +#include "SUIT_Operation.h" + +class QtxAction; +class QString; +class QIconSet; +class QKeySequence; +class QWidget; + +/*!Provide support QtxAction*/ +class SUIT_EXPORT SUIT_ActionOperation : public SUIT_Operation +{ + Q_OBJECT + +public: + SUIT_ActionOperation( SUIT_Application* theApp ); + virtual ~SUIT_ActionOperation(); + + QtxAction* action() const; + + /** @name GUI management*/ + //@{ + virtual void setAction( const QString& text, const QIconSet& icon, const QString& menuText, + QKeySequence accel, QObject* parent, const char* name = 0, bool toggle = false ); + + virtual void setAction( const QString& text, const QString& menuText, QKeySequence accel, + QObject* parent, const char* name = 0, bool toggle = false ); + virtual void setAction( QtxAction* theAction ); + + bool addTo( QWidget* theWidget ); + bool addTo( QWidget* theWidget, int thePos ); + + void setStatusTip( const QString& theTip ); + //@} + +private: + QtxAction* myAction; + + friend class SUIT_Study; +}; + +#endif diff --git a/src/SUIT/SUIT_Application.cxx b/src/SUIT/SUIT_Application.cxx new file mode 100755 index 000000000..4ae8aec86 --- /dev/null +++ b/src/SUIT/SUIT_Application.cxx @@ -0,0 +1,362 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "SUIT_Application.h" + +#include "SUIT_Session.h" +#include "SUIT_Desktop.h" +#include "SUIT_ResourceMgr.h" + +#include +#include +#include + +#include +#include +#include + +SUIT_Application::SUIT_Application() +: QObject( 0 ), +myStudy( 0 ), +myDesktop( 0 ), +myStatusLabel( 0 ) +{ +} + +SUIT_Application::~SUIT_Application() +{ + delete myStudy; + myStudy = 0; + + setDesktop( 0 ); +} + +SUIT_Desktop* SUIT_Application::desktop() +{ + return myDesktop; +} + +bool SUIT_Application::isPossibleToClose() +{ + return true; +} + +void SUIT_Application::closeApplication() +{ + emit applicationClosed( this ); +} + +SUIT_Study* SUIT_Application::activeStudy() const +{ + return myStudy; +} + +QString SUIT_Application::applicationVersion() const +{ + return QString::null; +} + +void SUIT_Application::start() +{ + if ( desktop() ) + desktop()->show(); +} + +bool SUIT_Application::useFile( const QString& theFileName ) +{ + createEmptyStudy(); + SUIT_Study* study = activeStudy(); + + bool status = study ? study->openDocument( theFileName ) : false; + + if ( !status ) + { + setActiveStudy( 0 ); + delete study; + } + + return status; +} + +bool SUIT_Application::useStudy( const QString& theName ) +{ + return false; +} + +void SUIT_Application::createEmptyStudy() +{ + if ( !activeStudy() ) + setActiveStudy( createNewStudy() ); +} + +int SUIT_Application::getNbStudies() const +{ + return activeStudy() ? 1 : 0; +} + +SUIT_ResourceMgr* SUIT_Application::resourceMgr() const +{ + if ( !SUIT_Session::session() ) + return 0; + + return SUIT_Session::session()->resourceMgr(); +} + +#define DEFAULT_MESSAGE_DELAY 3000 +void SUIT_Application::putInfo ( const QString& msg, const int msec ) +{ + if ( desktop() ) { + //desktop()->statusBar()->message( msg, msec <= 0 ? DEFAULT_MESSAGE_DELAY : msec ); + if ( !myStatusLabel ) { + myStatusLabel = new QLabel (desktop()->statusBar()); + desktop()->statusBar()->addWidget(myStatusLabel, /*int stretch = */1); + } + myStatusLabel->setText(msg); + if( msec != -1 ) + QTimer::singleShot(msec <= 0 ? DEFAULT_MESSAGE_DELAY : msec, myStatusLabel, SLOT(clear())); + } +} + +SUIT_Application* SUIT_Application::startApplication( int argc, char** argv ) const +{ + return startApplication( name(), argc, argv ); +} + +SUIT_Application* SUIT_Application::startApplication( const QString& name, int argc, char** argv ) const +{ + SUIT_Session* session = SUIT_Session::session(); + if ( !session ) + return 0; + + return session->startApplication( name, argc, argv ); +} + +void SUIT_Application::setDesktop( SUIT_Desktop* desk ) +{ + if ( myDesktop == desk ) + return; + + delete myDesktop; + myDesktop = desk; + if ( myDesktop ) + connect( myDesktop, SIGNAL( activated() ), this, SLOT( onDesktopActivated() ) ); +} + +SUIT_Study* SUIT_Application::createNewStudy() +{ + return new SUIT_Study( this ); +} + +void SUIT_Application::setActiveStudy( SUIT_Study* study ) +{ + if ( myStudy == study ) + return; + + myStudy = study; +} + +int SUIT_Application::createTool( const QString& name ) +{ + if ( !desktop() || !desktop()->toolMgr() ) + return -1; + + return desktop()->toolMgr()->createToolBar( name ); +} + +int SUIT_Application::createTool( QAction* a, const int tBar, const int id, const int idx ) +{ + if ( !desktop() || !desktop()->toolMgr() ) + return -1; + + int regId = desktop()->toolMgr()->registerAction( a, id ); + return desktop()->toolMgr()->insert( regId, tBar, idx ); +} + +int SUIT_Application::createTool( QAction* a, const QString& tBar, const int id, const int idx ) +{ + if ( !desktop() || !desktop()->toolMgr() ) + return -1; + + return desktop()->toolMgr()->insert( a, tBar, idx ); +} + +int SUIT_Application::createTool( const int id, const int tBar, const int idx ) +{ + if ( !desktop() || !desktop()->toolMgr() ) + return -1; + + return desktop()->toolMgr()->insert( id, tBar, idx ); +} + +int SUIT_Application::createTool( const int id, const QString& tBar, const int idx ) +{ + if ( !desktop() || !desktop()->toolMgr() ) + return -1; + + return desktop()->toolMgr()->insert( id, tBar, idx ); +} + +int SUIT_Application::createMenu( const QString& subMenu, const int menu, + const int id, const int group, const int index ) +{ + if ( !desktop() || !desktop()->menuMgr() ) + return -1; + + return desktop()->menuMgr()->insert( subMenu, menu, group, index ); +} + +int SUIT_Application::createMenu( const QString& subMenu, const QString& menu, + const int id, const int group, const int index ) +{ + if ( !desktop() || !desktop()->menuMgr() ) + return -1; + + return desktop()->menuMgr()->insert( subMenu, menu, group, index ); +} + +int SUIT_Application::createMenu( QAction* a, const int menu, const int id, const int group, const int index ) +{ + if ( !a || !desktop() || !desktop()->menuMgr() ) + return -1; + + int regId = desktop()->menuMgr()->registerAction( a, id ); + return desktop()->menuMgr()->insert( regId, menu, group, index ); +} + +int SUIT_Application::createMenu( QAction* a, const QString& menu, const int id, const int group, const int index ) +{ + if ( !a || !desktop() || !desktop()->menuMgr() ) + return -1; + + int regId = desktop()->menuMgr()->registerAction( a, id ); + return desktop()->menuMgr()->insert( regId, menu, group, index ); +} + +int SUIT_Application::createMenu( const int id, const int menu, const int group, const int index ) +{ + if ( !desktop() || !desktop()->menuMgr() ) + return -1; + + return desktop()->menuMgr()->insert( id, menu, group, index ); +} + +int SUIT_Application::createMenu( const int id, const QString& menu, const int group, const int index ) +{ + if ( !desktop() || !desktop()->menuMgr() ) + return -1; + + return desktop()->menuMgr()->insert( id, menu, group, index ); +} + +void SUIT_Application::setMenuShown( QAction* a, const bool on ) +{ + setMenuShown( actionId( a ), on ); +} + +void SUIT_Application::setMenuShown( const int id, const bool on ) +{ + if ( desktop() && desktop()->menuMgr() ) + desktop()->menuMgr()->setShown( id, on ); +} + +void SUIT_Application::setToolShown( QAction* a, const bool on ) +{ + setToolShown( actionId( a ), on ); +} + +void SUIT_Application::setToolShown( const int id, const bool on ) +{ + if ( desktop() && desktop()->toolMgr() ) + desktop()->toolMgr()->setShown( id, on ); +} + +void SUIT_Application::setActionShown( QAction* a, const bool on ) +{ + setMenuShown( a, on ); + setToolShown( a, on ); +} + +void SUIT_Application::setActionShown( const int id, const bool on ) +{ + setMenuShown( id, on ); + setToolShown( id, on ); +} + +QAction* SUIT_Application::action( const int id ) const +{ + SUIT_Application* that = (SUIT_Application*)this; + SUIT_Desktop* desk = that->desktop(); + if ( !desk ) + return 0; + + QAction* a = 0; + if ( desk->menuMgr() ) + a = desk->menuMgr()->action( id ); + if ( !a && desk->toolMgr() ) + a = desk->toolMgr()->action( id ); + return a; +} + +int SUIT_Application::actionId( const QAction* a ) const +{ + SUIT_Application* that = (SUIT_Application*)this; + SUIT_Desktop* desk = that->desktop(); + if ( !desk ) + return 0; + + int id = -1; + if ( desk->menuMgr() ) + id = desk->menuMgr()->actionId( a ); + if ( id == -1 && desk->toolMgr() ) + id = desk->toolMgr()->actionId( a ); + return id; +} + +QAction* SUIT_Application::createAction( const int id, const QString& text, const QIconSet& icon, + const QString& menu, const QString& tip, const int key, + QObject* parent, const bool toggle, QObject* reciever, const char* member ) +{ + QtxAction* a = new QtxAction( text, icon, menu, key, parent, 0, toggle ); + a->setStatusTip( tip ); + + if ( reciever && member ) + connect( a, SIGNAL( activated() ), reciever, member ); + + registerAction( id, a ); + + return a; +} + +void SUIT_Application::registerAction( const int id, QAction* a ) +{ + if ( desktop() && desktop()->menuMgr() ) + desktop()->menuMgr()->registerAction( a, id ); + + if ( desktop() && desktop()->toolMgr() ) + desktop()->toolMgr()->registerAction( a, id ); +} + +QAction* SUIT_Application::separator() +{ + return QtxActionMgr::separator(); +} + +void SUIT_Application::onDesktopActivated() +{ + emit activated( this ); +} diff --git a/src/SUIT/SUIT_Application.h b/src/SUIT/SUIT_Application.h new file mode 100755 index 000000000..43f6f29ed --- /dev/null +++ b/src/SUIT/SUIT_Application.h @@ -0,0 +1,171 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SUIT_APPLICATION_H +#define SUIT_APPLICATION_H + +#include "SUIT.h" +#include "SUIT_Study.h" + +#include +#include + +class QAction; +class SUIT_Desktop; +class SUIT_Convertor; +class SUIT_ViewModel; +class SUIT_ResourceMgr; +class QString; +class QIconSet; +class QLabel; +/*! \class QObject + * \brief For more information see QT documentation. + */ +/*! + An Application is a class which defines application configuration and behaviour. + For example Application object defines what Viewers are used in this application, what auxilliary windows + are present, how user can dial with them. Also Application object defines an sertain type of data structure by + holding of pointer on an instance of SUIT_Study class (which represents Document data structure). In other words + Application defines type of sata structure, type of used Viewers, type of main GUI widget (Desktop), + and other auxilliary tools. +*/ + +class SUIT_EXPORT SUIT_Application : public QObject +{ + Q_OBJECT + +public: + SUIT_Application(); + virtual ~SUIT_Application(); + + //! Returns main widget (Desktop) of the application (if it exists) + virtual SUIT_Desktop* desktop(); + + /*! Returns FALSE if applic ation can not be closed (because of non saved data for example). + This method called by SUIT_Session whin closing of application was requested. */ + virtual bool isPossibleToClose(); + + virtual void closeApplication(); + + //! Returns active Study. If Application supports wirking with several studies this method should be redefined + virtual SUIT_Study* activeStudy() const; + + //! Returns Name of application. Using is not defined. + virtual QString applicationName() const = 0; + + virtual QString applicationVersion() const; + + //! Shows the application's main widget. For non GUI application must be redefined. + virtual void start(); + + //! Opens document into active Study. If Study is empty - creates it. + virtual bool useFile( const QString& theFileName); + + //! Loads document into active Study. If Study is empty - creates it. + virtual bool useStudy( const QString& theName); + + //! Creates new empty Study if active Study = 0 + virtual void createEmptyStudy(); + + /*! Returns number of Studies. + * Must be redefined in Applications which support several studies for one Application instance. */ + virtual int getNbStudies() const; + + SUIT_ResourceMgr* resourceMgr() const; + + /*! Returns instance of data object Convertor class according to given Viewer. + If convertation is not supported returns 0. */ + virtual SUIT_Convertor* getConvertor(const SUIT_ViewModel* theViewer) { return 0; } + + //! Puts the message to the status bar + void putInfo ( const QString&, const int = 0 ); + + //! Invokes application-specific "Open/Save File" dialog and returns the selected file name. + virtual QString getFileName( bool open, const QString& initial, const QString& filters, + const QString& caption, QWidget* parent ) = 0; + + //! Invokes application-specific "Select Directory" dialog and returns the selected directory name. + virtual QString getDirectory( const QString& initial, const QString& caption, QWidget* parent ) = 0; + +signals: + void applicationClosed( SUIT_Application* ); + void activated( SUIT_Application* ); + +protected: + SUIT_Application* startApplication( int, char** ) const; + SUIT_Application* startApplication( const QString&, int, char** ) const; + + virtual void setDesktop( SUIT_Desktop* ); + + //! Creates a new Study instance. Must be redefined in new application according to its Study type. + virtual SUIT_Study* createNewStudy(); + virtual void setActiveStudy( SUIT_Study* ); + + /** @name Create tool functions*/ //@{ + int createTool( const QString& ); + int createTool( const int, const int, const int = -1 ); + int createTool( const int, const QString&, const int = -1 ); + int createTool( QAction*, const int, const int = -1, const int = -1 ); + int createTool( QAction*, const QString&, const int = -1, const int = -1 );//@} + + /** @name Create menu functions*/ //@{ + int createMenu( const QString&, const int, const int = -1, const int = -1, const int = -1 ); + int createMenu( const QString&, const QString&, const int = -1, const int = -1, const int = -1 ); + int createMenu( const int, const int, const int = -1, const int = -1 ); + int createMenu( const int, const QString&, const int = -1, const int = -1 ); + int createMenu( QAction*, const int, const int = -1, const int = -1, const int = -1 ); + int createMenu( QAction*, const QString&, const int = -1, const int = -1, const int = -1 );//@} + + /** @name Set menu shown functions*/ //@{ + void setMenuShown( QAction*, const bool ); + void setMenuShown( const int, const bool );//@} + /** @name Set tool shown functions*/ //@{ + void setToolShown( QAction*, const bool ); + void setToolShown( const int, const bool );//@} + + void setActionShown( QAction*, const bool ); + void setActionShown( const int, const bool ); + + static QAction* separator(); + QAction* action( const int ) const; + int actionId( const QAction* ) const; + void registerAction( const int, QAction* ); + QAction* createAction( const int, const QString&, const QIconSet&, const QString&, + const QString&, const int, QObject* = 0, + const bool = false, QObject* = 0, const char* = 0 ); + +protected slots: + virtual void onDesktopActivated(); + +private: + SUIT_Study* myStudy; + SUIT_Desktop* myDesktop; + + QLabel* myStatusLabel; +}; + +//! This function must return a new application instance. +extern "C" +{ + //jfa 22.06.2005:typedef SUIT_Application* (*APP_CREATE_FUNC)( int, char** ); + typedef SUIT_Application* (*APP_CREATE_FUNC)(); +} + +#define APP_CREATE_NAME "createApplication" + +#endif diff --git a/src/SUIT/SUIT_Convertor.h b/src/SUIT/SUIT_Convertor.h new file mode 100755 index 000000000..36e1985da --- /dev/null +++ b/src/SUIT/SUIT_Convertor.h @@ -0,0 +1,44 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// SUIT_Convertor.h: interface for the SUIT_Convertor class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_SUIT_CONVERTOR_H__4C27F4C7_DC7C_4BEF_9DC1_EFB97B387EBF__INCLUDED_) +#define AFX_SUIT_CONVERTOR_H__4C27F4C7_DC7C_4BEF_9DC1_EFB97B387EBF__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "SUIT.h" +#include "SUIT_DataObject.h" +#include "SUIT_ViewModel.h" + +/*! Provides convertation of selected object of specified viewer into SUIT_DataObject. + * Instance of Convertor class is created by Application according to data type and viewers used. + */ +class SUIT_Convertor +{ +public: + virtual DataObjectList getSelectedObjects(const SUIT_ViewModel* theViewer) = 0; + virtual void highlight(const SUIT_ViewModel* theViewer, const DataObjectList& theObjList) = 0; +}; + +#endif // !defined(AFX_SUIT_CONVERTOR_H__4C27F4C7_DC7C_4BEF_9DC1_EFB97B387EBF__INCLUDED_) diff --git a/src/SUIT/SUIT_DataObject.cxx b/src/SUIT/SUIT_DataObject.cxx new file mode 100755 index 000000000..afc3446f3 --- /dev/null +++ b/src/SUIT/SUIT_DataObject.cxx @@ -0,0 +1,538 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "SUIT_DataObject.h" + +#include + +#include "SUIT_DataObjectKey.h" + +#include // for cout in dump() + +/*! + Constructor +*/ + +SUIT_DataObject::SUIT_DataObject( SUIT_DataObject* p ) +: myParent( 0 ), + mySignal( 0 ), + myOpen( false ), + myCheck( false ) +{ + myChildren.setAutoDelete( true ); + + setParent( p ); +} + +/*! + Destructor +*/ + +SUIT_DataObject::~SUIT_DataObject() +{ + SUIT_DataObject* p = myParent; + + myParent = 0; + + if ( p ) + p->removeChild( this ); + + if ( mySignal ) + { + mySignal->emitSignal(); + mySignal->setOwner( 0 ); + } + + for ( QPtrListIterator it( myChildren ); it.current(); ++it ) + it.current()->myParent = 0; + + delete mySignal; +} + +/*! + Returns the root object. +*/ + +SUIT_DataObject* SUIT_DataObject::root() const +{ + return parent() ? parent()->root() : (SUIT_DataObject*)this; +} + +/*! + Returns the first child object. +*/ + +SUIT_DataObject* SUIT_DataObject::firstChild() const +{ + SUIT_DataObject* child = 0; + if ( !myChildren.isEmpty() ) + child = myChildren.getFirst(); + return child; +} + +/*! + Returns the last child object. +*/ + +SUIT_DataObject* SUIT_DataObject::lastChild() const +{ + SUIT_DataObject* child = 0; + if ( !myChildren.isEmpty() ) + child = myChildren.getLast(); + return child; +} + +/*! + Returns the number of the child objects. +*/ + +int SUIT_DataObject::childCount() const +{ + return myChildren.count(); +} + +/*! + Returns the index of the specified object in the child list or -1. +*/ + +int SUIT_DataObject::childPos( const SUIT_DataObject* obj ) const +{ + int res = -1; + + int i = 0; + for ( DataObjectListIterator it( myChildren ); it.current() && res == -1; ++it, i++ ) + { + if ( it.current() == obj ) + res = i; + } + + return res; +} + +/*! + Returns the child object with specified index. +*/ + +SUIT_DataObject* SUIT_DataObject::childObject( const int idx ) const +{ + SUIT_DataObject* child = 0; + + if ( idx>= 0 && idx < (int)myChildren.count() ) + { + SUIT_DataObject* that = (SUIT_DataObject*)this; + child = that->myChildren.at( idx ); + } + + return child; +} + +/*! + Returns the level of the object in the data tree. + 0 means that object is top-level. +*/ + +int SUIT_DataObject::level() const +{ + int lev = 0; + SUIT_DataObject* p = parent(); + while ( p ) { + p = p->parent(); + lev++; + } + return lev; +} + +/*! + Returns the next data object in the child list of the parent. +*/ + +SUIT_DataObject* SUIT_DataObject::nextBrother() const +{ + return myParent ? myParent->childObject( myParent->childPos( this ) + 1 ) : 0; +} + +/*! + Returns the previous data object in the child list of the parent. +*/ + +SUIT_DataObject* SUIT_DataObject::prevBrother() const +{ + return myParent ? myParent->childObject( myParent->childPos( this ) - 1 ) : 0; +} + +/*! + Returns 'true' if the object will delete children during destroying +*/ + +bool SUIT_DataObject::autoDeleteChildren() const +{ + return myChildren.autoDelete(); +} + +/*! + Specify should the object delete children during destroying +*/ + +void SUIT_DataObject::setAutoDeleteChildren( const bool on ) +{ + myChildren.setAutoDelete( on ); +} + +/*! + Returns the list of the child objects. if 'rec' is 'true' then function get all sub children. +*/ + +void SUIT_DataObject::children( DataObjectList& lst, const bool rec ) const +{ + for ( DataObjectListIterator it( myChildren ); it.current(); ++it ) + { + lst.append( it.current() ); + if ( rec ) + it.current()->children( lst, rec ); + } +} + +/*! + Returns the list of the child objects. if 'rec' is 'true' then function get all sub children. +*/ + +DataObjectList SUIT_DataObject::children( const bool rec ) +{ + DataObjectList lst; + children( lst, rec ); + return lst; +} + +/*! + Append new child object to the end of the children list +*/ + +void SUIT_DataObject::appendChild( SUIT_DataObject* theObj ) +{ + insertChild( theObj, myChildren.count() ); +} + +/*! + Insert new child object to the children list at specified position +*/ + +void SUIT_DataObject::insertChild( SUIT_DataObject* theObj, int thePosition ) +{ + if ( !theObj || myChildren.find( theObj ) != -1 ) + return; + + int pos = thePosition < 0 ? myChildren.count() : thePosition; + myChildren.insert( QMIN( pos, (int)myChildren.count() ), theObj ); + theObj->setParent( this ); +} + +/*! + Removes the specified child object reference. +*/ + +void SUIT_DataObject::removeChild( SUIT_DataObject* theObj ) +{ + if ( !theObj ) + return; + + bool ad = myChildren.autoDelete(); + myChildren.setAutoDelete( false ); + + if ( myChildren.remove( theObj ) ) + theObj->setParent( 0 ); + + myChildren.setAutoDelete( ad ); +} + +/*! + Replaces the specified child object by another object. +*/ + +bool SUIT_DataObject::replaceChild( SUIT_DataObject* src, SUIT_DataObject* trg, const bool del ) +{ + if ( !src || !trg ) + return false; + + int idx = childPos( trg ); + removeChild( trg ); + + int pos = childPos( src ); + if ( pos < 0 ) + { + if ( idx >= 0 ) + insertChild( trg, idx ); + return false; + } + + insertChild( trg, pos ); + removeChild( src ); + + if ( del ) + src->deleteLater(); + + return true; +} + +/*! + Transfer the all children from specified object 'obj' to self. +*/ + +void SUIT_DataObject::reparentChildren( const SUIT_DataObject* obj ) +{ + if ( !obj ) + return; + + DataObjectList lst; + obj->children( lst ); + for ( DataObjectListIterator it( lst ); it.current(); ++it ) + it.current()->setParent( this ); +} + +/*! + Set the parent object. Remove itself from current parent children + and append itself to the new parent children list. +*/ + +void SUIT_DataObject::setParent( SUIT_DataObject* theParent ) +{ + if ( theParent == parent() ) + return; + + if ( parent() ) + parent()->removeChild( this ); + + myParent = theParent; + + if ( parent() ) + parent()->appendChild( this ); +} + +/*! + Returns the parent object. +*/ + +SUIT_DataObject* SUIT_DataObject::parent() const +{ + return myParent; +} + + +/*! + Connect to signal destroyed( SUIT_DataObject* ). +*/ + +bool SUIT_DataObject::connect( QObject* reciever, const char* slot ) +{ + if ( !reciever || !slot ) + return false; + + if ( !mySignal ) + mySignal = new Signal( this ); + + QObject::disconnect( mySignal, SIGNAL( destroyed( SUIT_DataObject* ) ), reciever, slot ); + return QObject::connect( mySignal, SIGNAL( destroyed( SUIT_DataObject* ) ), reciever, slot ); +} + +/*! + Disconnect from signal destroyed( SUIT_DataObject* ). +*/ + +bool SUIT_DataObject::disconnect( QObject* reciever, const char* slot ) +{ + if ( !reciever || !slot ) + return false; + + if ( !mySignal ) + return true; + + return QObject::disconnect( mySignal, SIGNAL( destroyed( SUIT_DataObject* ) ), reciever, slot ); +} + +/*! + Returns object name +*/ + +void SUIT_DataObject::deleteLater() +{ + if ( !mySignal ) + mySignal = new Signal( this ); + + mySignal->emitSignal(); + mySignal->deleteLater(); +} + +/*! + Returns object name +*/ + +QString SUIT_DataObject::name() const +{ + return QString::null; +} + +/*! + Returns object icon +*/ + +QPixmap SUIT_DataObject::icon() const +{ + return QPixmap(); +} + +/*! + Returns object text +*/ + +QString SUIT_DataObject::text( const int ) const +{ + return QString::null; +} + +/*! + Returns object color +*/ + +QColor SUIT_DataObject::color( const ColorRole ) const +{ + return QColor(); +} + +/*! + Returns object tool tip +*/ + +QString SUIT_DataObject::toolTip() const +{ + return QString::null; +} + +/*! + Returns 'true' if it is possible to drag this object +*/ + +bool SUIT_DataObject::isDragable() const +{ + return false; +} + +/*! + Returns 'true' if it is possible to drop an object "obj" to this object. +*/ + +bool SUIT_DataObject::isDropAccepted( SUIT_DataObject* ) +{ + return false; +} + +/*! + Returns type of check possibility. +*/ + +SUIT_DataObject::CheckType SUIT_DataObject::checkType() const +{ + return None; +} + +/*! + Returns the checked state of the object. +*/ + +bool SUIT_DataObject::isOn() const +{ + return myCheck; +} + +/*! + Sets the checked state of the object. +*/ + +void SUIT_DataObject::setOn( const bool on ) +{ + myCheck = on; +} + +bool SUIT_DataObject::isOpen() const +{ + return myOpen; +} + +void SUIT_DataObject::setOpen( const bool on ) +{ + myOpen = on; +} + +/*! + Returns object personal indentification key. +*/ + +SUIT_DataObjectKey* SUIT_DataObject::key() const +{ + return 0; +} + +/*! + Dump this data object and its children to cout +*/ +void SUIT_DataObject::dump( const int indent ) const +{ + QString strIndent = QString().fill( ' ', indent ); // indentation string + std::cout << strIndent << name() << std::endl; // dump to cout + for ( DataObjectListIterator it( myChildren ); it.current(); ++it ) // iterate all children + it.current()->dump( indent + 2 ); // dump every child with indent + 2 spaces +} + +/*! + Class: SUIT_DataObject::Signal [Internal] +*/ + +SUIT_DataObject::Signal::Signal( SUIT_DataObject* o ) +: QObject(), +myOwner( o ) +{ +} + +/*! + Destructor. +*/ +SUIT_DataObject::Signal::~Signal() +{ + SUIT_DataObject* o = myOwner; + myOwner = 0; + if ( o ) + { + o->mySignal = 0; + delete o; + } +} + +/*! + Set owner \a o. +*/ +void SUIT_DataObject::Signal::setOwner( SUIT_DataObject* o ) +{ + myOwner = o; +} + +/*! + emit signal destroed owner. +*/ +void SUIT_DataObject::Signal::emitSignal() +{ + if ( myOwner ) + emit destroyed( myOwner ); +} diff --git a/src/SUIT/SUIT_DataObject.h b/src/SUIT/SUIT_DataObject.h new file mode 100755 index 000000000..bb14608c3 --- /dev/null +++ b/src/SUIT/SUIT_DataObject.h @@ -0,0 +1,141 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SUIT_DATAOBJECT_H +#define SUIT_DATAOBJECT_H + +#include +#include +#include +#include + +#include "SUIT.h" + +class SUIT_DataObject; +class SUIT_DataObjectKey; + +typedef QPtrList DataObjectList; +typedef QPtrListIterator DataObjectListIterator; + +#ifdef WIN32 +#pragma warning( disable:4251 ) +#endif + +/*! + Class provide support data object. +*/ +class SUIT_EXPORT SUIT_DataObject +{ +public: + class Signal; + + typedef enum { None, RadioButton, CheckBox } CheckType; + typedef enum { Text, Base, Foreground, Background, Highlight, HighlightedText } ColorRole; + + SUIT_DataObject( SUIT_DataObject* = 0 ); + virtual ~SUIT_DataObject(); + + SUIT_DataObject* root() const; + SUIT_DataObject* lastChild() const; + SUIT_DataObject* firstChild() const; + + int childCount() const; + int childPos( const SUIT_DataObject* ) const; + SUIT_DataObject* childObject( const int ) const; + int level() const; + + SUIT_DataObject* nextBrother() const; + SUIT_DataObject* prevBrother() const; + + bool autoDeleteChildren() const; + virtual void setAutoDeleteChildren( const bool ); + + virtual void children( DataObjectList&, const bool = false ) const; + virtual DataObjectList children( const bool = false ); + + void appendChild( SUIT_DataObject* ); + virtual void removeChild( SUIT_DataObject* ); + virtual void insertChild( SUIT_DataObject*, int thePosition ); + bool replaceChild( SUIT_DataObject*, SUIT_DataObject*, const bool = false ); + + void reparentChildren( const SUIT_DataObject* ); + + virtual QString text( const int ) const; + virtual QColor color( const ColorRole ) const; + + virtual QString name() const; + virtual QPixmap icon() const; + virtual QString toolTip() const; + + virtual SUIT_DataObject* parent() const; + virtual void setParent( SUIT_DataObject* ); + + virtual bool isDragable() const; + virtual bool isDropAccepted( SUIT_DataObject* obj ); + + virtual CheckType checkType() const; + + virtual bool isOn() const; + virtual void setOn( const bool ); + + virtual bool isOpen() const; + virtual void setOpen( const bool ); + + virtual SUIT_DataObjectKey* key() const; + + bool connect( QObject*, const char* ); + bool disconnect( QObject*, const char* ); + + void deleteLater(); + + void dump( const int indent = 2 ) const; // dump to cout + +private: + bool myOpen; + bool myCheck; + Signal* mySignal; + SUIT_DataObject* myParent; + DataObjectList myChildren; + + friend class SUIT_DataObject::Signal; + friend class SUIT_DataObjectIterator; +}; + +class SUIT_DataObject::Signal : public QObject +{ + Q_OBJECT + +public: + Signal( SUIT_DataObject* ); + virtual ~Signal(); + + void emitSignal(); + void setOwner( SUIT_DataObject* o ); + +signals: + void destroyed( SUIT_DataObject* ); + +private: + SUIT_DataObject* myOwner; +}; + +#ifdef WIN32 +#pragma warning( default:4251 ) +#endif + +#endif diff --git a/src/SUIT/SUIT_DataObjectIterator.cxx b/src/SUIT/SUIT_DataObjectIterator.cxx new file mode 100644 index 000000000..09a2c8bc2 --- /dev/null +++ b/src/SUIT/SUIT_DataObjectIterator.cxx @@ -0,0 +1,206 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "SUIT_DataObjectIterator.h" + +/*! + Constructor. +*/ +SUIT_DataObjectIterator::SUIT_DataObjectIterator( SUIT_DataObject* root, const int det, const bool fromTrueRoot ) +: myRoot( root ), +myDetourType( det ), +myCurrentLevel( 0 ) +{ + if ( myRoot && fromTrueRoot ) + myRoot = myRoot->root(); + + myCurrent = myExtremeChild = myRoot; +} + +/*! + Gets parent for object \a obj. +*/ +SUIT_DataObject* SUIT_DataObjectIterator::parent( SUIT_DataObject* obj ) const +{ + SUIT_DataObject* result = 0; + if ( obj && obj != myRoot ) + result = obj->parent(); + return result; +} + +/*! + Increment operator. +*/ +void SUIT_DataObjectIterator::operator++() +{ + SUIT_DataObject* aNext = 0; + SUIT_DataObject* aParent = 0; + + bool exit; + + if ( myCurrent ) + { + if ( myDetourType == DepthLeft || myDetourType == DepthRight ) + { + //Depth detour algorithm + if ( myCurrent->myChildren.count() > 0 ) + { + myCurrent = extreme( myCurrent->myChildren, myDetourType == DepthLeft ); + myCurrentLevel++; + } + else do + { + exit = false; + aParent = parent( myCurrent ); + if ( !aParent ) + { + myCurrent = 0; //the tree is passed completely + exit = true; + } + else + { + aParent->myChildren.find( myCurrent ); + if ( myDetourType == DepthLeft ) + myCurrent = aParent->myChildren.next(); + else + myCurrent = aParent->myChildren.prev(); + if ( !myCurrent ) + { + myCurrent = aParent; + myCurrentLevel--; + } + else + exit = true; + } + } + while ( !exit ); + } + else if ( myDetourType == BreadthLeft || myDetourType == BreadthRight ) + { + //Breadth detour algorithm + aNext = globalSibling( myCurrent, myDetourType == BreadthLeft ); + if ( !aNext ) + { + myCurrent = 0; + for ( SUIT_DataObject* cur = myExtremeChild; cur && !myCurrent; cur = globalSibling( cur, myDetourType == BreadthLeft ) ) + { + if ( cur->myChildren.count() > 0 ) + { + myExtremeChild = extreme( cur->myChildren, myDetourType == BreadthLeft ); + myCurrent = myExtremeChild; + myCurrentLevel++; + } + } + } + else + myCurrent = aNext; + } + } +} + +/*! + Gets current data object. +*/ +SUIT_DataObject* SUIT_DataObjectIterator::current() const +{ + return myCurrent; +} + +/*! + Gets depth of current lavel. +*/ +int SUIT_DataObjectIterator::depth() const +{ + return myCurrentLevel; +} + +/*! + Gets detour type. +*/ +int SUIT_DataObjectIterator::detour() const +{ + return myDetourType; +} + +/*! + Gets global sibling for object \a obj +*/ +SUIT_DataObject* SUIT_DataObjectIterator::globalSibling( SUIT_DataObject* obj, bool next ) const +{ + SUIT_DataObject* par; + + if ( obj && ( par = parent( obj ) ) ) + { + par->myChildren.find( obj ); + if ( par->myChildren.next() ) + return par->myChildren.current(); + else + { + for ( ; par; par = globalSibling( par, next ) ) + { + if ( par->myChildren.count() > 0 ) + return extreme( par->myChildren, next ); + } + } + return 0; + } + else + return 0; +} + +/*! + * Gets first or last data object from list. + * Get firls, if \a FromLeft == true, else last. + */ +SUIT_DataObject* SUIT_DataObjectIterator::extreme( DataObjectList& aList, bool FromLeft ) const +{ + if ( FromLeft ) + return aList.getFirst(); + else + return aList.getLast(); +} + +/*! + Constructor. +*/ +SUIT_DataObjectLevelIterator::SUIT_DataObjectLevelIterator( SUIT_DataObject* root, + int start, int end, bool LeftToRight ) +: SUIT_DataObjectIterator( root, LeftToRight ? BreadthLeft : BreadthRight ) +{ + myStartLevel = start; + if ( end > start ) + myEndLevel = end; + else + myEndLevel = myStartLevel; + + while ( current() && depth() < myStartLevel ) + SUIT_DataObjectIterator::operator++(); +} + +/*! + Increment operator. +*/ +void SUIT_DataObjectLevelIterator::operator++() +{ + if ( myCurrent ) + { + SUIT_DataObjectIterator::operator++(); + if ( depth() > myEndLevel ) + myCurrent = 0; + } +} diff --git a/src/SUIT/SUIT_DataObjectIterator.h b/src/SUIT/SUIT_DataObjectIterator.h new file mode 100644 index 000000000..45b8f7082 --- /dev/null +++ b/src/SUIT/SUIT_DataObjectIterator.h @@ -0,0 +1,66 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SUIT_DATAOBJECT_ITERATOR_H +#define SUIT_DATAOBJECT_ITERATOR_H + +#include "SUIT_DataObject.h" + +/*! + Class provide data object iterator. +*/ +class SUIT_EXPORT SUIT_DataObjectIterator +{ +public: + typedef enum { DepthLeft, DepthRight, BreadthLeft, BreadthRight, User } DetourType; + + SUIT_DataObjectIterator( SUIT_DataObject* root, const int det, const bool fromTrueRoot = false ); + + virtual void operator++(); + SUIT_DataObject* current() const; + + int depth() const; + int detour() const; + +protected: + SUIT_DataObject* parent( SUIT_DataObject* ) const; + SUIT_DataObject* extreme( DataObjectList&, bool FromLeft ) const; + SUIT_DataObject* globalSibling( SUIT_DataObject*, bool next ) const; + +protected: + SUIT_DataObject* myRoot; + SUIT_DataObject* myCurrent; + +private: + SUIT_DataObject* myExtremeChild; + int myDetourType, myCurrentLevel; +}; + +class SUIT_DataObjectLevelIterator : public SUIT_DataObjectIterator +{ +public: + SUIT_DataObjectLevelIterator( SUIT_DataObject* root, const int start, const int end = 0, + const bool LeftToRight = true ); + virtual void operator++(); + +protected: + int myStartLevel; + int myEndLevel; +}; + +#endif diff --git a/src/SUIT/SUIT_DataObjectKey.cxx b/src/SUIT/SUIT_DataObjectKey.cxx new file mode 100755 index 000000000..477ebd2f9 --- /dev/null +++ b/src/SUIT/SUIT_DataObjectKey.cxx @@ -0,0 +1,189 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "SUIT_DataObjectKey.h" + +#include + +#ifndef WNT +#include +#define _typeinfo std::type_info +#else +#include +#define _typeinfo type_info +#endif + +/*!\class SUIT_DataObjectKey + * Key for personal idetfication of SUIT_DataObject. + */ + +/*! + Constructor. +*/ +SUIT_DataObjectKey::SUIT_DataObjectKey() +: refCounter( 0 ) +{ +} + +/*! + Destructor. +*/ +SUIT_DataObjectKey::~SUIT_DataObjectKey() +{ +} + +/*!\class SUIT_DataObjectKeyHandle + * Wrapper around the pointer of class SUIT_DataObjectKey. + */ + +/*! + Constructor. +*/ +SUIT_DataObjectKeyHandle::SUIT_DataObjectKeyHandle() +: myKey( 0 ) +{ +} + +/*! + Copy Constructor. +*/ +SUIT_DataObjectKeyHandle::SUIT_DataObjectKeyHandle( const SUIT_DataObjectKeyHandle& other ) +: myKey( other.myKey ) +{ + myKey = other.myKey; + + beginScope(); +} + +/*! + Constructor. Initialize by key \a key. +*/ +SUIT_DataObjectKeyHandle::SUIT_DataObjectKeyHandle( SUIT_DataObjectKey* key ) +: myKey( key ) +{ + beginScope(); +} + +/*! + Destructor. +*/ +SUIT_DataObjectKeyHandle::~SUIT_DataObjectKeyHandle() +{ + nullify(); +} + +/*! + * Checks: Is key null? + *\retval TRUE - if null, esle false. +*/ +bool SUIT_DataObjectKeyHandle::isNull() const +{ + return !myKey; +} + +/*! + Nullify key. +*/ +void SUIT_DataObjectKeyHandle::nullify() +{ + endScope(); +} + +/*! + * Operator less. + *\retval boolean. TRUE - If current key less than \a kw. + */ +bool SUIT_DataObjectKeyHandle::operator<( const SUIT_DataObjectKeyHandle& kw ) const +{ + if ( myKey == kw.myKey ) + return false; + + if ( !myKey || !kw.myKey ) + return myKey < kw.myKey; + + const _typeinfo& i1 = typeid( *myKey ); + const _typeinfo& i2 = typeid( *kw.myKey ); + + int cmp = strcmp( i1.name(), i2.name() ); + if ( cmp < 0 ) + return true; + else if ( cmp > 0 ) + return false; + else + return myKey->isLess( kw.myKey ); +} + +/*! + * Operator is equal. + *\retval boolean. TRUE - If current key equal \a kw. + */ +bool SUIT_DataObjectKeyHandle::operator==( const SUIT_DataObjectKeyHandle& kw ) const +{ + if ( myKey == kw.myKey ) + return true; + + if ( !myKey || !kw.myKey ) + return false; + + if ( typeid( *myKey ) != typeid( *kw.myKey ) ) + return false; + + return myKey->isEqual( kw.myKey ); +} + +/*! + * Copy value of key \a kw to current. + */ +SUIT_DataObjectKeyHandle& SUIT_DataObjectKeyHandle::operator=( const SUIT_DataObjectKeyHandle& kw ) +{ + if ( myKey != kw.myKey ) + { + endScope(); + + myKey = kw.myKey; + + beginScope(); + } + return *this; +} + +/*! + * Inctrement reference counter for current key. + */ +void SUIT_DataObjectKeyHandle::beginScope() +{ + if ( myKey ) + myKey->refCounter++; +} + +/*! + * Decrement reference counter for current key. + */ +void SUIT_DataObjectKeyHandle::endScope() +{ + if ( !myKey ) + return; + + myKey->refCounter--; + + if ( !myKey->refCounter ) + { + delete myKey; + myKey = 0; + } +} diff --git a/src/SUIT/SUIT_DataObjectKey.h b/src/SUIT/SUIT_DataObjectKey.h new file mode 100755 index 000000000..40aea1454 --- /dev/null +++ b/src/SUIT/SUIT_DataObjectKey.h @@ -0,0 +1,65 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SUIT_DATAOBJECTKEY_H +#define SUIT_DATAOBJECTKEY_H + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "SUIT.h" + +class SUIT_EXPORT SUIT_DataObjectKey +{ +public: + SUIT_DataObjectKey(); + ~SUIT_DataObjectKey(); + + virtual bool isLess( const SUIT_DataObjectKey* ) const = 0; + virtual bool isEqual( const SUIT_DataObjectKey* ) const = 0; + +private: + int refCounter; + + friend class SUIT_DataObjectKeyHandle; +}; + +class SUIT_EXPORT SUIT_DataObjectKeyHandle +{ +public: + SUIT_DataObjectKeyHandle(); + SUIT_DataObjectKeyHandle( SUIT_DataObjectKey* ); + SUIT_DataObjectKeyHandle( const SUIT_DataObjectKeyHandle& ); + ~SUIT_DataObjectKeyHandle(); + + void nullify(); + bool isNull() const; + bool operator <( const SUIT_DataObjectKeyHandle& ) const; + bool operator ==( const SUIT_DataObjectKeyHandle& ) const; + SUIT_DataObjectKeyHandle& operator =( const SUIT_DataObjectKeyHandle& ); + +private: + void beginScope(); + void endScope(); + +private: + SUIT_DataObjectKey* myKey; +}; + +#endif diff --git a/src/SUIT/SUIT_Desktop.cxx b/src/SUIT/SUIT_Desktop.cxx new file mode 100755 index 000000000..8e7faecf5 --- /dev/null +++ b/src/SUIT/SUIT_Desktop.cxx @@ -0,0 +1,174 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "SUIT_Desktop.h" + +#include "SUIT_Tools.h" +#include "SUIT_ViewWindow.h" + +#include +#include +#include + +/*!\class SUIT_Desktop + * Provide desktop management:\n + * \li menu manager + * \li tool manager + * \li windows + */ + +/*! + Constructor. +*/ +SUIT_Desktop::SUIT_Desktop() +: QtxMainWindow() +{ + myMenuMgr = new QtxActionMenuMgr( this ); + myToolMgr = new QtxActionToolMgr( this ); + myLogoMgr = new QtxLogoMgr( menuBar() ); +} + +/*! + Destructor. +*/ +SUIT_Desktop::~SUIT_Desktop() +{ +} + +/*! + Emit on event \a e. +*/ +bool SUIT_Desktop::event( QEvent* e ) +{ + if ( !e ) + return false; + + switch ( e->type() ) + { + case QEvent::WindowActivate: + emit activated(); + break; + case QEvent::WindowDeactivate: + emit deactivated(); + break; + } + + return QMainWindow::event( e ); +} + +/*! + Close event \a e. +*/ +void SUIT_Desktop::closeEvent( QCloseEvent* e ) +{ + emit closing( this, e ); + e->ignore(); +} + +/*! + Child event. +*/ +void SUIT_Desktop::childEvent( QChildEvent* e ) +{ + if ( e->type() == QEvent::ChildInserted && parentArea() && + e->child()->isWidgetType() && e->child()->inherits( "SUIT_ViewWindow" ) ) + { + QWidget* wid = (QWidget*)e->child(); + bool vis = wid->isVisibleTo( wid->parentWidget() ); + wid->reparent( parentArea(), QPoint( 0, 0 ), vis ); + wid->setShown( vis ); + } + else + QtxMainWindow::childEvent( e ); +} + +/*! + Gets menu manager. +*/ +QtxActionMenuMgr* SUIT_Desktop::menuMgr() const +{ + return myMenuMgr; +} + +/*! + Gets tool manager. +*/ +QtxActionToolMgr* SUIT_Desktop::toolMgr() const +{ + return myToolMgr; +} + +/*! + Returns the count of the existed logos. +*/ +int SUIT_Desktop::logoCount() const +{ + if ( !myLogoMgr ) + return 0; + else + return myLogoMgr->count(); +} + +/*! + Adds new logo to the menu bar area. + Obsolete. Not should be used. + Use SUIT_Desktop::logoInsert(); +*/ +void SUIT_Desktop::addLogo( const QString& id, const QPixmap& pix ) +{ + logoInsert( id, pix ); +} + +/*! + Removes a logo. + Obsolete. Not should be used. + Use SUIT_Desktop::logoRemove(); +*/ +void SUIT_Desktop::removeLogo( const QString& id ) +{ + logoRemove( id ); +} + +/*! + Adds new logo to the menu bar area +*/ +void SUIT_Desktop::logoInsert( const QString& logoID, const QPixmap& logo, const int idx ) +{ + if ( myLogoMgr ) + myLogoMgr->insert( logoID, logo, idx ); +} + +/*! + Removes a logo +*/ +void SUIT_Desktop::logoRemove( const QString& logoID ) +{ + if ( myLogoMgr ) + myLogoMgr->remove( logoID ); +} + +/*! + Removes all logos +*/ +void SUIT_Desktop::logoClear() +{ + if ( myLogoMgr ) + myLogoMgr->clear(); +} + + diff --git a/src/SUIT/SUIT_Desktop.h b/src/SUIT/SUIT_Desktop.h new file mode 100755 index 000000000..c437dbb1c --- /dev/null +++ b/src/SUIT/SUIT_Desktop.h @@ -0,0 +1,76 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SUIT_DESKTOP_H +#define SUIT_DESKTOP_H + +#include "SUIT.h" + +#include +#include +#include + +class QPopupMenu; +class QtxLogoMgr; +class SUIT_ViewWindow; +class QtxActionMenuMgr; +class QtxActionToolMgr; + +class SUIT_EXPORT SUIT_Desktop : public QtxMainWindow +{ + Q_OBJECT + +public: + SUIT_Desktop(); + virtual ~SUIT_Desktop(); + + QtxActionMenuMgr* menuMgr() const; + QtxActionToolMgr* toolMgr() const; + + virtual SUIT_ViewWindow* activeWindow() const = 0; + virtual QPtrList windows() const = 0; + + void addLogo( const QString&, const QPixmap& ); // Not should be used. Will be removed. + void removeLogo( const QString& ); // Not should be used. Will be removed. + + int logoCount() const; + + void logoClear(); + void logoRemove( const QString& ); + void logoInsert( const QString&, const QPixmap&, const int = -1 ); + +signals: + void activated(); + void deactivated(); + void windowActivated( SUIT_ViewWindow* ); + void closing( SUIT_Desktop*, QCloseEvent* ); + +protected: + virtual bool event( QEvent* ); + virtual void closeEvent( QCloseEvent* ); + virtual void childEvent( QChildEvent* ); + + virtual QWidget* parentArea() const = 0; + +private: + QtxActionMenuMgr* myMenuMgr; + QtxActionToolMgr* myToolMgr; + QtxLogoMgr* myLogoMgr; +}; + +#endif diff --git a/src/SUIT/SUIT_ExceptionHandler.cxx b/src/SUIT/SUIT_ExceptionHandler.cxx new file mode 100755 index 000000000..391093418 --- /dev/null +++ b/src/SUIT/SUIT_ExceptionHandler.cxx @@ -0,0 +1,54 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "SUIT_ExceptionHandler.h" + +#include "SUIT_MessageBox.h" + +#include + +/*!\class SUIT_ExceptionHandler + * Show exception message on error handler. + */ + +/*! + Checks: is internal handle on object \a o? +*/ +bool SUIT_ExceptionHandler::handle( QObject* o, QEvent* e ) +{ + return internalHandle( o, e ); +} + +/*! + Checks: is internal handle on object \a o? +*/ +bool SUIT_ExceptionHandler::internalHandle( QObject* o, QEvent* e ) +{ + return qApp ? qApp->QApplication::notify( o, e ) : false; +} + +/*! + Show error message \a mgs, if application is not null. +*/ +void SUIT_ExceptionHandler::showMessage( const QString& title, const QString& msg ) +{ + if ( !qApp ) + return; + + SUIT_MessageBox::error1( qApp->mainWidget(), title, msg, "OK" ); +} diff --git a/src/SUIT/SUIT_ExceptionHandler.h b/src/SUIT/SUIT_ExceptionHandler.h new file mode 100755 index 000000000..f050e2183 --- /dev/null +++ b/src/SUIT/SUIT_ExceptionHandler.h @@ -0,0 +1,45 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SUIT_EXCEPTIONHANDLER_H +#define SUIT_EXCEPTIONHANDLER_H + +#include "SUIT.h" + +class QEvent; +class QObject; +class QString; + +class SUIT_EXPORT SUIT_ExceptionHandler +{ +public: + virtual bool handle( QObject*, QEvent* ); + +protected: + bool internalHandle( QObject*, QEvent* ); + void showMessage( const QString&, const QString& ); +}; + +extern "C" +{ + typedef SUIT_ExceptionHandler* (*APP_GET_HANDLER_FUNC)(); +} + +#define APP_GET_HANDLER_NAME "getExceptionHandler" + +#endif diff --git a/src/SUIT/SUIT_FileDlg.cxx b/src/SUIT/SUIT_FileDlg.cxx new file mode 100755 index 000000000..80a6ad589 --- /dev/null +++ b/src/SUIT/SUIT_FileDlg.cxx @@ -0,0 +1,523 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +//********************************************************************************* +// SUIT_FileDlg class is the extension of the Qt's Open/Save file dialog box. +// To get the file/directory name(s) call static methods: +// +// to invoke "Open file" or "Save file" dialog box +// static QString getFileName(QWidget* parent, const QString& initial, const QStringList& filters, +// const QString& caption, const bool open, const bool showQuickDir = true, +// SUIT_FileValidator* validator = 0); +// +// to invoke "Open files" dialog box (to get the multiple file selection) +// static QStringList getOpenFileNames(QWidget* parent, const QString& initial, const QStringList& filters, +// const QString& caption, bool showQuickDir = true, +// SUIT_FileValidator* validator = 0); +// +// to invoke "Select directory" dialog box +// static QString getExistingDirectory(QWidget* parent, const QString& initial, +// const QString& caption, const bool showQuickDir = true); +// +// The parameters: +// - parent parent widget (if 0, the current desktop is used) +// - initial starting directory or file name (if null, last visited directory is used) +// - filters file filters list; patterns inside the filter can be separated by ';','|' or ' ' +// symbols +// - caption dialog box's caption: if null, the default one is used +// - open open flag - true for "Open File" and false for "Save File" dialog box +// - showQuickDir this flag enables/disables "Quick directory list" controls +// - validator you can provide custom file validator with this parameter +// +// Examples: +// ... +// QStringList flist; +// flist.append( "Image files (*.bmp *.gif *.jpg )" ); +// flist.append( "All files (*.*)" ); +// QMyFileValidator* v = new QMyFileValidator( 0 ); +// QString fileName = SUIT_FileDlg::getFileName( 0, QString::null, flist, "Dump view", false, true, v ); +// if ( !fileName.isEmpty() ) { +// ... writing image to the file +// } +// ... +// QStringList flist; +// flist.append( "*.cpp | *.cxx | *.c++" ); +// flist.append( "*.h | *.hpp | *.hxx" ); +// QString fileName = SUIT_FileDlg::getFileName( desktop(), QString::null, flist, QString::null, true, true ); +// +//********************************************************************************* + +#include "SUIT_FileDlg.h" + +#include "SUIT_Tools.h" +#include "SUIT_Session.h" +#include "SUIT_Desktop.h" +#include "SUIT_MessageBox.h" +#include "SUIT_ResourceMgr.h" +#include "SUIT_FileValidator.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MIN_COMBO_SIZE 100 + +/*! If the selected file name has extension which does not match the selected filter + * this extension is ignored (and new one will be added). See below for details. + */ +const bool IGNORE_NON_MATCHING_EXTENSION = true; + +QString SUIT_FileDlg::myLastVisitedPath; + +/*! Constructor */ +SUIT_FileDlg::SUIT_FileDlg( QWidget* parent, bool open, bool showQuickDir, bool modal ) : +QFileDialog( parent, 0, modal ), +myValidator( 0 ), +myQuickCombo( 0 ), myQuickButton( 0 ), myQuickLab( 0 ), +myOpen( open )//, +//myAccepted( false ) +{ + const QObjectList* child = children(); + QObjectList::const_iterator anIt = child->begin(), aLast = child->end(); + for( ; anIt!=aLast; anIt++ ) + if( (*anIt)->inherits( "QPushButton" ) ) + { + QPushButton* bt = ( QPushButton* )( *anIt ); + bt->setDefault( false ); + bt->setAutoDefault( false ); + } + + if ( parent->icon() ) + setIcon( *parent->icon() ); + setSizeGripEnabled( true ); + + if ( showQuickDir ) { + // inserting quick dir combo box + myQuickLab = new QLabel(tr("LAB_QUICK_PATH"), this); + myQuickCombo = new QComboBox(false, this); + myQuickCombo->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed)); + myQuickCombo->setMinimumSize(MIN_COMBO_SIZE, 0); + + myQuickButton = new QPushButton(tr("BUT_ADD_PATH"), this); + + connect(myQuickCombo, SIGNAL(activated(const QString&)), this, SLOT(quickDir(const QString&))); + connect(myQuickButton, SIGNAL(clicked()), this, SLOT(addQuickDir())); + addWidgets(myQuickLab, myQuickCombo, myQuickButton); + + // getting dir list from settings + QString dirs; + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + if ( resMgr ) + dirs = resMgr->stringValue( "FileDlg", QString( "QuickDirList" ) ); + + QStringList dirList = QStringList::split(';', dirs, false); + if (dirList.count() > 0) { + for (unsigned i = 0; i < dirList.count(); i++) + myQuickCombo->insertItem(dirList[i]); + } + else { + myQuickCombo->insertItem(QDir::homeDirPath()); + } + } + setMode( myOpen ? ExistingFile : AnyFile ); + setCaption( myOpen ? tr( "INF_DESK_DOC_OPEN" ) : tr( "INF_DESK_DOC_SAVE" ) ); + + // If last visited path doesn't exist -> switch to the first preferred path + if ( !myLastVisitedPath.isEmpty() ) { + if ( !processPath( myLastVisitedPath ) && showQuickDir ) + processPath( myQuickCombo->text( 0 ) ); + } + else { + if ( showQuickDir ) + processPath(myQuickCombo->text( 0 ) ); + } + + // set default file validator + myValidator = new SUIT_FileValidator(this); +} + +/*! Destructor*/ +SUIT_FileDlg::~SUIT_FileDlg() +{ + setValidator( 0 ); +} + +/*! Redefined from QFileDialog.*/ +void SUIT_FileDlg::polish() +{ + QFileDialog::polish(); + if ( myQuickButton && myQuickLab ) { + // the following is a workaround for proper layouting of custom widgets + QValueList buttonList; + QValueList labelList; + const QObjectList *list = children(); + QObjectListIt it(*list); + int maxButWidth = myQuickLab->sizeHint().width(); + int maxLabWidth = myQuickButton->sizeHint().width(); + + for (; it.current() ; ++it) { + if ( it.current()->isA( "QLabel" ) ) { + int tempW = ((QLabel*)it.current())->minimumWidth(); + if ( maxLabWidth < tempW ) maxLabWidth = tempW; + labelList.append( (QLabel*)it.current() ); + } + else if( it.current()->isA("QPushButton") ) { + int tempW = ((QPushButton*)it.current())->minimumWidth(); + if ( maxButWidth < tempW ) maxButWidth = tempW; + buttonList.append( (QPushButton*)it.current() ); + } + } + if (maxButWidth > 0) { + QValueList::Iterator bListIt; + for ( bListIt = buttonList.begin(); bListIt != buttonList.end(); ++bListIt ) + (*bListIt)->setFixedWidth( maxButWidth ); + } + if (maxLabWidth > 0) { + QValueList::Iterator lListIt; + for ( lListIt = labelList.begin(); lListIt != labelList.end(); ++lListIt ) + (*lListIt)->setFixedWidth( maxLabWidth ); + } + } +} + +/*! Sets validator for file names to open/save + * Deletes previous validator if the dialog owns it. + */ +void SUIT_FileDlg::setValidator( SUIT_FileValidator* v ) +{ + if ( myValidator && myValidator->parent() == this ) + delete myValidator; + myValidator = v; +} + +/*! Returns the selected file */ +QString SUIT_FileDlg::selectedFile() const +{ + return mySelectedFile; +} + +/*! Returns 'true' if this is 'Open File' dialog + * and 'false' if 'Save File' dialog + */ +bool SUIT_FileDlg::isOpenDlg() const +{ + return myOpen; +} + +/*! Closes this dialog and sets the return code to 'Accepted' + * if the selected name is valid ( see 'acceptData()' ) + */ +void SUIT_FileDlg::accept() +{ + /* myAccepted + * flag is used to warkaround the Qt 2.2.2 BUG: + * accept() method is called twice if user presses 'Enter' key + * in file name editor while file name is not acceptable by acceptData() + * (e.g. permission denied) + */ +// if ( !myAccepted ) { + if ( mode() != ExistingFiles ) { + mySelectedFile = QFileDialog::selectedFile(); + addExtension(); + } + + if ( acceptData() ) { + myLastVisitedPath = dirPath(); + QFileDialog::accept(); +// myAccepted = true; + } +// } +// myAccepted = !myAccepted; +} + +/*! Closes this dialog and sets the return code to 'Rejected' */ +void SUIT_FileDlg::reject() +{ + mySelectedFile = QString::null; + QFileDialog::reject(); +} + +/*! Returns 'true' if selected file is valid. + * The validity is checked by a file validator, + * if there is no validator the file is always + * considered as valid + */ +bool SUIT_FileDlg::acceptData() +{ + if ( myValidator ) + { + if ( isOpenDlg() ) + { + if ( mode() == ExistingFiles ) + { + QStringList fileNames = selectedFiles(); + for ( int i = 0; i < (int)fileNames.count(); i++ ) + { + if ( !myValidator->canOpen( fileNames[i] ) ) + return false; + } + return true; + } + else + { + return myValidator->canOpen( selectedFile() ); + } + } + else + return myValidator->canSave( selectedFile() ); + } + return true; +} + +/*! Adds an extension to the selected file name + * if the file has not it. + * The extension is extracted from the active filter. + */ +void SUIT_FileDlg::addExtension() +{ + // check if file name entered is empty + if ( mySelectedFile.stripWhiteSpace().isEmpty() ) + return; + + // current file extension + QString anExt = "." + SUIT_Tools::extension( mySelectedFile.stripWhiteSpace() ).stripWhiteSpace(); + + // If the file already has extension and it does not match the filter there are two choices: + // - to leave it 'as is' + // - to ignore it + // The behavior is defined by IGNORE_NON_MATCHING_EXTENSION constant + if ( anExt != "." && !IGNORE_NON_MATCHING_EXTENSION ) + return; + + // get selected file filter +#if QT_VERSION < 0x030000 + QRegExp r( QString::fromLatin1("(?[a-zA-Z0-9.*? +;#|]*)?$") ); + int len, index = r.match( selectedFilter().stripWhiteSpace(), 0, &len ); +#else + QRegExp r( QString::fromLatin1("\\(?[a-zA-Z0-9.*? +;#|]*\\)?$") ); + int index = r.search( selectedFilter().stripWhiteSpace() ); +#endif + + if ( index >= 0 ) { + // Create wildcard regular expression basing on selected filter + // in order to validate a file extension. + // Due to transformations from the filter list (*.txt *.*xx *.c++ SUIT*.* ) we + // will have the pattern (\.txt|\..*xx|\.c\+\+|\..*) (as we validate extension only, + // we remove everything except extension mask from the pattern +#if QT_VERSION < 0x030000 + QString wildcard = selectedFilter().mid( index, len ).stripWhiteSpace(); +#else + QString wildcard = selectedFilter().mid( index, r.matchedLength() ).stripWhiteSpace(); +#endif + // replace '|' and ';' separators by space symbol and also brackets if there are some + wildcard.replace( QRegExp( "[\\|;|(|)]" )," " ); + + QString aPattern = wildcard.replace( QRegExp( "(^| )(\\s*)[0-9a-zA-Z*_?]*\\."), " \\." ).stripWhiteSpace(). + replace( QRegExp( "\\s+" ), "|" ).replace( QRegExp( "[?]" ),".?" ). + replace( QRegExp( "[*]" ),".*" ).replace( QRegExp( "[+]" ),"\\+" ); + + // now we get the list of all extension masks and remove all which does not contain wildcard symbols + QStringList extList = QStringList::split( "|",aPattern ); + for( int i = extList.count() - 1; i >= 0; i-- ) { + if ( !extList[i].contains( "." ) ) + extList.remove( extList.at( i ) ); + } + aPattern = extList.join( "|" ); + + // finalize pattern + QRegExp anExtRExp( "^("+ aPattern + ")$" ); + + // Check if the current file extension matches the pattern + if ( anExtRExp.match( anExt ) < 0 ) + { + // find first appropriate extension in the selected filter + // (it should be without wildcard symbols) + for ( int i = 0; i < (int)extList.count(); i++ ) + { + QString newExt = extList[i].replace( QRegExp( "[\\\\][+]" ),"+" ); + int res = newExt.findRev( '.' ); + if ( res >= 0 ) + newExt = newExt.mid( res + 1 ); + if ( newExt.find( QRegExp("[*|?]" ) ) < 0 ) + { + mySelectedFile.stripWhiteSpace(); + mySelectedFile += mySelectedFile.endsWith(".") ? newExt : QString(".") + newExt; + break; + } + } + } + } +} + +/*! Processes selection : tries to set given path or filename as selection */ +bool SUIT_FileDlg::processPath( const QString& path ) +{ + if ( !path.isNull() ) { + QFileInfo fi( path ); + if ( fi.exists() ) { + if ( fi.isFile() ) + setSelection( path ); + else if ( fi.isDir() ) + setDir( path ); + return true; + } + else { + if ( QFileInfo( fi.dirPath() ).exists() ) { + setDir( fi.dirPath() ); + setSelection( path ); + return true; + } + } + } + return false; +} +/*! Called when user selects item from "Quick Dir" combo box */ +void SUIT_FileDlg::quickDir(const QString& dirPath) +{ + QString aPath = dirPath; + if ( !QDir(aPath).exists() ) { + aPath = QDir::homeDirPath(); + SUIT_MessageBox::error1(this, + tr("ERR_ERROR"), + tr("ERR_DIR_NOT_EXIST").arg(dirPath), + tr("BUT_OK")); + } + else + processPath(aPath); +} +/*! + Called when user presses "Add" button - adds current directory to quick directory + list and to the preferences +*/ +void SUIT_FileDlg::addQuickDir() +{ + QString dp = dirPath(); + if ( !dp.isEmpty() ) { + QDir dir( dp ); + // getting dir list from settings + QString dirs; + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + if ( resMgr ) + dirs = resMgr->stringValue( "FileDlg", QString( "QuickDirList" ) ); + QStringList dirList = QStringList::split(';', dirs, false); + bool found = false; + bool emptyAndHome = false; + if ( dirList.count() > 0 ) { + for ( unsigned i = 0; i < dirList.count(); i++ ) { + QDir aDir( dirList[i] ); + if ( aDir.canonicalPath().isNull() && dirList[i] == dir.absPath() || + !aDir.canonicalPath().isNull() && aDir.exists() && aDir.canonicalPath() == dir.canonicalPath() ) { + found = true; + break; + } + } + } + else { + emptyAndHome = dir.canonicalPath() == QDir(QDir::homeDirPath()).canonicalPath(); + } + if ( !found ) { + dirList.append( dp ); + resMgr->setValue( "FileDlg", QString( "QuickDirList" ), dirList.join(";") ); + if ( !emptyAndHome ) + myQuickCombo->insertItem( dp ); + } + } +} +/*! + Returns the file name for Open/Save [ static ] +*/ +QString SUIT_FileDlg::getFileName( QWidget* parent, + const QString& initial, + const QStringList& filters, + const QString& caption, + bool open, + bool showQuickDir, + SUIT_FileValidator* validator ) +{ + SUIT_FileDlg* fd = new SUIT_FileDlg( parent, open, showQuickDir, true ); + if ( !caption.isEmpty() ) + fd->setCaption( caption ); + if ( !initial.isEmpty() ) { + fd->processPath( initial ); // VSR 24/03/03 check for existing of directory has been added to avoid QFileDialog's bug + } + fd->setFilters( filters ); + if ( validator ) + fd->setValidator( validator ); + fd->exec(); + QString filename = fd->selectedFile(); + delete fd; + qApp->processEvents(); + return filename; +} + + +/*! + Returns the list of files to be opened [ static ] +*/ +QStringList SUIT_FileDlg::getOpenFileNames( QWidget* parent, + const QString& initial, + const QStringList& filters, + const QString& caption, + bool showQuickDir, + SUIT_FileValidator* validator ) +{ + SUIT_FileDlg* fd = new SUIT_FileDlg( parent, true, showQuickDir, true ); + fd->setMode( ExistingFiles ); + if ( !caption.isEmpty() ) + fd->setCaption( caption ); + if ( !initial.isEmpty() ) { + fd->processPath( initial ); // VSR 24/03/03 check for existing of directory has been added to avoid QFileDialog's bug + } + fd->setFilters( filters ); + if ( validator ) + fd->setValidator( validator ); + fd->exec(); + QStringList filenames = fd->selectedFiles(); + delete fd; + qApp->processEvents(); + return filenames; +} + +/*! + Existing directory selection dialog [ static ] +*/ +QString SUIT_FileDlg::getExistingDirectory( QWidget* parent, + const QString& initial, + const QString& caption, + bool showQuickDir ) +{ + SUIT_FileDlg* fd = new SUIT_FileDlg( parent, true, showQuickDir, true); + if ( !caption.isEmpty() ) + fd->setCaption( caption ); + if ( !initial.isEmpty() ) { + fd->processPath( initial ); // VSR 24/03/03 check for existing of directory has been added to avoid QFileDialog's bug + } + fd->setMode( DirectoryOnly ); + fd->setFilters(tr("INF_DIRECTORIES_FILTER")); + fd->exec(); + QString dirname = fd->selectedFile(); + delete fd; + qApp->processEvents(); + return dirname; + +} diff --git a/src/SUIT/SUIT_FileDlg.h b/src/SUIT/SUIT_FileDlg.h new file mode 100755 index 000000000..bb9ae4e3f --- /dev/null +++ b/src/SUIT/SUIT_FileDlg.h @@ -0,0 +1,93 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SUIT_FILEDIALOG_H +#define SUIT_FILEDIALOG_H + +#include "SUIT.h" + +#include + +class QLabel; +class QComboBox; +class QPushButton; +class SUIT_FileValidator; + +/*! \class QFileDialog + * For more information see QT documentation. +*/ +class SUIT_EXPORT SUIT_FileDlg : public QFileDialog +{ + Q_OBJECT + +public: + SUIT_FileDlg( QWidget*, bool open, bool showQuickDir = true, bool modal = true ); + virtual ~SUIT_FileDlg(); + +public: + bool isOpenDlg() const; + QString selectedFile() const; + + void setValidator( SUIT_FileValidator* ); + + static QString getFileName( QWidget* parent, const QString& initial, const QStringList& filters, + const QString& caption, const bool open, const bool showQuickDir = true, + SUIT_FileValidator* validator = 0 ); + static QStringList getOpenFileNames( QWidget* parent, const QString& initial, const QStringList& filters, + const QString& caption, bool showQuickDir = true, + SUIT_FileValidator* validator = 0 ); + static QString getExistingDirectory( QWidget* parent, const QString& initial, + const QString& caption, const bool showQuickDir = true ); + +public slots: + void polish(); + +private: + bool acceptData(); + void addExtension(); + bool processPath( const QString& path ); + +protected slots: + void accept(); + void reject(); + void quickDir( const QString& ); + void addQuickDir(); + +protected: + bool myOpen; //!< open/save selector + QString mySelectedFile; //!< selected filename + SUIT_FileValidator* myValidator; //!< file validator + QLabel* myQuickLab; //!< quick dir combo box + QComboBox* myQuickCombo; //!< quick dir combo box + QPushButton* myQuickButton; //!< quick dir add button + + /*! \var myAccepted + * \brief flag is used to warkaround the Qt 2.2.2 + * \bug accept() method is called twice if user presses 'Enter' key + * in file name editor while file name is not acceptable by acceptData() + * (e.g. permission denied) + */ +// bool myAccepted; + /*! ASL: this bug can be fixed with help of call setDefault( false ) + * and setAutoDefault( false ) methods for all QPushButtons of this dialog + */ + + static QString myLastVisitedPath; //!< last visited path +}; + +#endif diff --git a/src/SUIT/SUIT_Operation.cxx b/src/SUIT/SUIT_Operation.cxx new file mode 100755 index 000000000..11beaef40 --- /dev/null +++ b/src/SUIT/SUIT_Operation.cxx @@ -0,0 +1,491 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +/** +* SALOME SalomeApp +* +* Copyright (C) 2005 CEA/DEN, EDF R&D +* +* +* +* File : SUIT_Operation.h +* Author : Unknown +* Module : SALOME +*/ + +#include "SUIT_Operation.h" + +#include "SUIT_Study.h" +#include "SUIT_Desktop.h" +#include "SUIT_MessageBox.h" +#include "SUIT_Application.h" + +/*! + * \brief Constructor + * \param SUIT_Application - application for this operation +* +* Constructs an empty operation. Constructor should work very fast because many +* operators may be created after starting application but only several from them +* may be used. As result this constructor stores given application in myApp field +* and set Waiting status. +*/ +SUIT_Operation::SUIT_Operation( SUIT_Application* app ) +: QObject(), +myApp( app ), +myStudy( 0 ), +myState( Waiting ), +myFlags( Transaction ) +{ +} + +/*! + * \brief Destructor +*/ +SUIT_Operation::~SUIT_Operation() +{ +} + +/*! + * \brief Returns operation study + * \return Pointer to study +* +* Get study corresponding to this operation i.e. study which starts this operation. +*/ +SUIT_Study* SUIT_Operation::study() const +{ + return myStudy; +} + +/*! + * \brief Sets operation study + * \param theStudy - study corresponding to this operation +* +* Sets study corresponding to this operation i.e. study which starts this operation. +*/ +void SUIT_Operation::setStudy( SUIT_Study* theStudy ) +{ + myStudy = theStudy; +} + +/*! + * \brief Gets application + * \return Pointer to application +* +* Gets application for this operation +*/ +SUIT_Application* SUIT_Operation::application() const +{ + return myApp; +} + +/*! + * \brief Sets application + * \param theApp - application for this operation +* +* Gets application for this operation +*/ +void SUIT_Operation::setApplication( SUIT_Application* theApp ) +{ + myApp = theApp; +} + +/*! + * \brief Gets state of operation + * \return Value from OperationState enumeration +* +* Gets state of operation (see OperationState enumeration) +*/ +SUIT_Operation::OperationState SUIT_Operation::state() const +{ + return myState; +} + +/*! + * \brief Sets state of operation + * \param theState - state of operation to be set +* +* Sets state of operation (see OperationState enumeration) +*/ +void SUIT_Operation::setState( const SUIT_Operation::OperationState theState ) +{ + myState = theState; +} + +/*! + * \brief Sets the flags of operation + * \param f - flags of operation to be set +* +* Sets flags of operation (see Flags enumeration) +*/ +void SUIT_Operation::setFlags( const int f ) +{ + myFlags = myFlags | f; +} + +/*! + * \brief Clears the flags of operation + * \param f - flags of operation to be cleared +* +* Clears flags of operation (see Flags enumeration) +*/ +void SUIT_Operation::clearFlags( const int f ) +{ + myFlags = myFlags & ~f; +} + +/*! + * \brief Test the flags of operation + * \param f - flags of operation to be tested +* +* Returns TRUE if the specified flags setted in the operation (see Flags enumeration) +*/ +bool SUIT_Operation::testFlags( const int f ) const +{ + return ( myFlags & f ) == f; +} + +/*! + * \brief Name of the operation +* +* Returns string name of the operation. This name will be used for +* automatically commited transaction. +*/ +QString SUIT_Operation::operationName() const +{ + return QString::null; +} + +/*! + * \brief Starts operation +* +* Public slot. Verifies whether operation can be started and starts operation. +* This slot is not virtual and cannot be redefined. Redefine startOperation method +* to change behavior of operation. There is no point in using this method. It would +* be better to inherit own operator from base one and redefine startOperation method +* instead. +*/ +void SUIT_Operation::start() +{ + if ( study() ) + study()->start( this ); + else + { + startOperation(); + emit started( this ); + } +} + +/*! + * \brief Aborts operation +* +* Public slot. Aborts operation. This slot is not virtual and cannot be redefined. +* Redefine abortOperation method to change behavior of operation instead +*/ +void SUIT_Operation::abort() +{ + if ( study() ) + study()->abort( this ); + else + { + abortOperation(); + myState = Waiting; + emit aborted( this ); + + stopOperation(); + emit stopped( this ); + } +} + +/*! + * \brief Commits operation +* +* Public slot. Commits operation. This slot is not virtual and cannot be redefined. +* Redefine commitOperation method to change behavior of operation instead +*/ +void SUIT_Operation::commit() +{ + if ( study() ) + study()->commit( this ); + else + { + commitOperation(); + myState = Waiting; + emit committed( this ); + + stopOperation(); + emit stopped( this ); + } +} + +/*! + * \brief Resumes operation +* +* Public slot. Resumes operation. This slot is called when operation is resumed after +* previous suspending. This slot is not virtual and cannot be redefined. Redefine +* resumeOperation method to change behavior of operation instead +*/ +void SUIT_Operation::resume() +{ + if ( study() ) + study()->resume( this ); + else + { + resumeOperation(); + myState = Running; + emit resumed( this ); + } +} + +/*! + * \brief Suspend operation. +* +* Public slot. Suspend operation. This slot is called when operation is suspended +* (for starting other one, for example) This slot is not virtual and cannot be +* redefined. Redefine suspendOperation method to change behavior of operation instead +*/ +void SUIT_Operation::suspend() +{ + if ( study() ) + study()->suspend( this ); + else + { + suspendOperation(); + myState = Suspended; + emit suspended( this ); + } +} + +/*! + * \brief Verifies whether operator is ready to start. + * \return TRUE if operation is ready to start +* +* Default implementation returns TRUE. Redefine this method to add own verifications +*/ +bool SUIT_Operation::isReadyToStart() const +{ + return true; +} + +/*! + * \brief Virtual method called when operation is started +* +* Virtual method called when operation started (see start() method for more description) +*/ +void SUIT_Operation::startOperation() +{ + emit callSlot(); + commit(); +} + +/*! + * \brief Virtual method called when operation is started +* +* Virtual method called when operation stopped - comitted or aborted. +*/ +void SUIT_Operation::stopOperation() +{ +} + +/*! + * \brief Virtual method called when operation aborted +* +* Virtual method called when operation aborted (see abort() method for more description) +*/ +void SUIT_Operation::abortOperation() +{ +} + +/*! + * \brief Virtual method called when operation resumed +* +* Virtual method called when operation resumed (see resume() method for more description) +*/ +void SUIT_Operation::resumeOperation() +{ +} + +/*! + * \brief Virtual method called when operation suspended +* +* Virtual method called when operation suspended (see suspend() method for more description) +*/ +void SUIT_Operation::suspendOperation() +{ +} + +/*! + * \brief Virtual method called when operation committed +* +* Virtual method called when operation committed (see commit() method for more description) +*/ +void SUIT_Operation::commitOperation() +{ +} + +/*! + * \brief Sets slot which is called when operation is started + * \param theReceiver - object containing slot + * \param theSlot - slot of theReceiver object + * \return TR if slot was connected successfully, FALSE otherwise +* +* Sets slot which is called when operation is started. There is no point in +* using this method. It would be better to inherit own operator from base +* one and redefine startOperation method +*/ +bool SUIT_Operation::setSlot( const QObject* theReceiver, const char* theSlot ) +{ + return connect( this, SIGNAL( callSlot() ), theReceiver, theSlot ); +} + +/*! + * \brief Verifies whether given operator is valid for this one + * \param theOtherOp - other operation + * \return Returns TRUE if the given operator is valid for this one +* +* Verifies whether given operator is valid for this one (i.e. can be started "above" +* this operator) +*/ +bool SUIT_Operation::isValid( SUIT_Operation* ) const +{ + return false; +} + +/*! + * \brief Verifies whether this operator can be always started above any already runnig one + * \return Returns TRUE if current operation must not be checked for ActiveOperation->IsValid( this ) +* +* This method must be redefined in derived operation if operation of derived class +* must be always can start above any launched one. Default implementation returns FALSE, +* so it is being checked for IsValid, but some operations may overload IsGranted() +* In this case they will always start, no matter what operation is running. +*/ +bool SUIT_Operation::isGranted() const +{ + return false; +} + +/*! + * \brief Verifies whether operation is an runned one (state()==Running) + * \return TRUE if operation is active, FALSE otherwise +* +* Verifies whether operation is an running. Returns TRUE if state of operator +* is Running +*/ +bool SUIT_Operation::isRunning() const +{ + return state() == Running; +} + +/*! + * \brief Verifies whether operation is an active for study. + * \return TRUE if operation is active, FALSE otherwise +* +* Verifies whether operation is an active on. Returns TRUE if this operator +* is active for study +*/ +bool SUIT_Operation::isActive() const +{ + return study() ? study()->activeOperation() == this : false; +} + +/*! + * \brief Starts operator above this one + * \param theOp - operation to be started +* +* Start operator above this one. Use this method if you want to call other operator +* from this one +*/ +void SUIT_Operation::start( SUIT_Operation* op, const bool check ) +{ + if ( !op ) + return; + + if ( study() ) + study()->start( op, false ); + else + { + connect( this, SIGNAL( stopped( SUIT_Operation* ) ), op, SLOT( abort() ) ); + op->start(); + } +} + +/*! + * \brief Sets execution status + * \param theStatus - execution status +* +* Sets myExecStatus to the given value +*/ +void SUIT_Operation::setExecStatus( const int theVal ) +{ + myExecStatus = (ExecStatus)theVal; +} + +/*! + * \brief Gets execution status + * \return Execution status +* +* Gets execution status +*/ +int SUIT_Operation::execStatus() const +{ + return myExecStatus; +} + +/*! + * \brief Opens transaction for data modifications. +*/ +bool SUIT_Operation::openTransaction() +{ + if ( !study() ) + return false; + + return study()->openTransaction(); +} + +/*! + * \brief Aborts transaction and all performed data modifications. +*/ +bool SUIT_Operation::abortTransaction() +{ + if ( !study() ) + return false; + + return study()->abortTransaction(); +} + +/*! + * \brief Commits transaction and all performed data modifications. +*/ +bool SUIT_Operation::commitTransaction( const QString& name ) +{ + if ( !study() ) + return false; + + return study()->commitTransaction( name ); +} + +/*! + * \brief Returns TRUE if transaction is opened. +*/ +bool SUIT_Operation::hasTransaction() const +{ + if ( !study() ) + return false; + + return study()->hasTransaction(); +} diff --git a/src/SUIT/SUIT_Operation.h b/src/SUIT/SUIT_Operation.h new file mode 100755 index 000000000..6d44d9502 --- /dev/null +++ b/src/SUIT/SUIT_Operation.h @@ -0,0 +1,165 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +/** +* SALOME SalomeApp +* +* Copyright (C) 2005 CEA/DEN, EDF R&D +* +* +* +* File : SUIT_Operation.h +* Author : Unknown +* Module : SALOME +*/ + +#ifndef SUIT_OPERATION_H +#define SUIT_OPERATION_H + +#include + +#include "SUIT.h" + +class SUIT_Study; +class SUIT_Application; + +/*! + * \brief Base class for all operations + * + * Base class for all operations. If you perform an action it is reasonable to create + * operation intended for this. This is a base class for all operations which provides + * mechanism for correct starting operations, starting operations above already started + * ones, committing operations and so on. To create own operation it is reasonable to + * inherit it from this class and redefines virtual methods to provide own behavior + * Main virtual methods are + * - virtual bool isReadyToStart(); + * - virtual void startOperation(); + * - virtual void abortOperation(); + * - virtual void commitOperation(); + * - virtual void resumeOperation(); + * - virtual void suspendOperation(); +*/ +class SUIT_EXPORT SUIT_Operation : public QObject +{ + Q_OBJECT + +public: + /*! Enum describes state of operation */ + enum OperationState + { + Waiting, //!< Operation is not used (it is not run or suspended) + Running, //!< Operation is started + Suspended //!< Operation is started but suspended (other operation is performed above it) + }; + + /*! + * Enum describes execution status of operation. Execution status often used after + * ending work of operation which was started from this one. In this case this + * operation can ask previously started operation whether it finished successfully. + */ + enum ExecStatus + { + Rejected, //!< Operation has not performed any action (modification of data model for example) + Accepted //!< Operation has performed an actions and must be stopped + }; + + /*! + * Enum describes setting of the operation. + */ + enum Flags + { + None = 0x00, //!< None options + Transaction = 0x01 //!< Automatically open (commit/abort) transaction during start (commit/abort). + }; + +public: + SUIT_Operation( SUIT_Application* ); + virtual ~SUIT_Operation(); + + OperationState state() const; + bool isActive() const; + bool isRunning() const; + + SUIT_Study* study() const; + virtual void setStudy( SUIT_Study* theStudy ); + + SUIT_Application* application() const; + virtual void setApplication( SUIT_Application* theApp ); + + virtual bool isValid( SUIT_Operation* theOtherOp ) const; + virtual bool isGranted() const; + + bool setSlot( const QObject* theReceiver, const char* theSlot ); + + void setFlags( const int ); + void clearFlags( const int ); + bool testFlags( const int ) const; + + virtual QString operationName() const; + +signals: + void started( SUIT_Operation* ); + void aborted( SUIT_Operation* ); + void committed( SUIT_Operation* ); + + void stopped( SUIT_Operation* ); + void resumed( SUIT_Operation* ); + void suspended( SUIT_Operation* ); + + void callSlot(); + +public slots: + void start(); + void abort(); + void commit(); + void resume(); + void suspend(); + +protected: + virtual bool isReadyToStart() const; + + virtual void stopOperation(); + virtual void startOperation(); + virtual void abortOperation(); + virtual void commitOperation(); + virtual void resumeOperation(); + virtual void suspendOperation(); + + virtual bool openTransaction(); + virtual bool abortTransaction(); + virtual bool hasTransaction() const; + virtual bool commitTransaction( const QString& = QString::null ); + + int execStatus() const; + void setExecStatus( const int ); + + void setState( const OperationState ); + + void start( SUIT_Operation*, const bool = false ); + +private: + SUIT_Application* myApp; //!< application for this operation + int myFlags; //!< operation flags + SUIT_Study* myStudy; //!< study for this operation + OperationState myState; //!< Operation state + ExecStatus myExecStatus; //!< Execution status + + friend class SUIT_Study; +}; + +#endif diff --git a/src/SUIT/SUIT_OverrideCursor.cxx b/src/SUIT/SUIT_OverrideCursor.cxx new file mode 100755 index 000000000..3d276a989 --- /dev/null +++ b/src/SUIT/SUIT_OverrideCursor.cxx @@ -0,0 +1,68 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "SUIT_OverrideCursor.h" + +/*!Constructor. Initialize wait cursor.*/ +SUIT_OverrideCursor::SUIT_OverrideCursor() +{ + QApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) ); +} + +/*!Copy constructor.*/ +SUIT_OverrideCursor::SUIT_OverrideCursor( const QCursor& cursor ) +{ + QApplication::setOverrideCursor( cursor ); +} + +/*!Destructor. restoring override cursor.*/ +SUIT_OverrideCursor::~SUIT_OverrideCursor() +{ + QApplication::restoreOverrideCursor(); +} + +/*! Check cursors is empty */ +bool SUIT_OverrideCursor::isActive() const +{ + return myCursors.isEmpty(); +} + +/*!Suspend cursors.*/ +void SUIT_OverrideCursor::suspend() +{ + if ( !isActive() ) + return; + + while ( QApplication::overrideCursor() ) + { + myCursors.prepend( *QApplication::overrideCursor() ); + QApplication::restoreOverrideCursor(); + } +} + +/*!Resume cursors.*/ +void SUIT_OverrideCursor::resume() +{ + if ( isActive() ) + return; + + for ( QValueList::const_iterator it = myCursors.begin(); it != myCursors.end(); ++it ) + QApplication::setOverrideCursor( *it ); + + myCursors.clear(); +} diff --git a/src/SUIT/SUIT_OverrideCursor.h b/src/SUIT/SUIT_OverrideCursor.h new file mode 100755 index 000000000..0fd4428eb --- /dev/null +++ b/src/SUIT/SUIT_OverrideCursor.h @@ -0,0 +1,43 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SUIT_OVERRIDECURSOR_H +#define SUIT_OVERRIDECURSOR_H + +#include +#include + +#include "SUIT.h" + +/*! \brief Class used for management cursors.*/ +class SUIT_EXPORT SUIT_OverrideCursor +{ +public: + SUIT_OverrideCursor(); + SUIT_OverrideCursor( const QCursor& ); + virtual ~SUIT_OverrideCursor(); + + bool isActive() const; + void suspend(); + void resume(); + +private: + QValueList myCursors; +}; + +#endif diff --git a/src/SUIT/SUIT_PopupClient.cxx b/src/SUIT/SUIT_PopupClient.cxx new file mode 100644 index 000000000..2bb8cde76 --- /dev/null +++ b/src/SUIT/SUIT_PopupClient.cxx @@ -0,0 +1,88 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "SUIT_PopupClient.h" + +#include + +/*! constructor. initialize mySignal.*/ +SUIT_PopupClient::SUIT_PopupClient() +: mySignal( 0 ) +{ +} + +/*! destructor. delete mySignal*/ +SUIT_PopupClient::~SUIT_PopupClient() +{ + delete mySignal; +} + +/*! + Connect popup request. +*/ +bool SUIT_PopupClient::connectPopupRequest( QObject* reciever, const char* slot ) +{ + if ( !reciever || !slot ) + return false; + if ( !mySignal ) + mySignal = new Signal(); + return QObject::connect( mySignal, SIGNAL( contextMenuRequest( SUIT_PopupClient*, QContextMenuEvent* ) ), + reciever, slot ); +} + +/*! + Disconnect popup request. +*/ +bool SUIT_PopupClient::disconnectPopupRequest( QObject* reciever, const char* slot ) +{ + if ( !reciever || !slot || !mySignal ) + return false; + return QObject::disconnect( mySignal, SIGNAL( contextMenuRequest( SUIT_PopupClient*, QContextMenuEvent* ) ), + reciever, slot ); +} + +/*! + Send signal on context menu request. +*/ +void SUIT_PopupClient::contextMenuRequest( QContextMenuEvent* e ) +{ + if ( mySignal ) + mySignal->sendSignal( this, e ); +} + +/*! + * \class SUIT_PopupClient::Signal + * Descr: invoke signal which is connected to reciever in SUIT_PopupClient + */ + +/*! constructor*/ +SUIT_PopupClient::Signal::Signal() +: QObject( 0 ) +{ +} + +/*! destructor. do nothing*/ +SUIT_PopupClient::Signal::~Signal() +{} + +/*! Send signal to \a client on context menu request \a e. + */ +void SUIT_PopupClient::Signal::sendSignal( SUIT_PopupClient* client, QContextMenuEvent* e ) +{ + emit contextMenuRequest( client, e ); +} diff --git a/src/SUIT/SUIT_PopupClient.h b/src/SUIT/SUIT_PopupClient.h new file mode 100644 index 000000000..e5a007b79 --- /dev/null +++ b/src/SUIT/SUIT_PopupClient.h @@ -0,0 +1,71 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SUIT_POPUPCLIENT_H +#define SUIT_POPUPCLIENT_H + +#include "SUIT.h" + +#include + +class QPopupMenu; +class QContextMenuEvent; + +/*!\class SUIT_PopupClient + * Descr: Base class for instances which creates popup menu on QContextMenuEvent + */ +class SUIT_EXPORT SUIT_PopupClient +{ +public: + + class Signal; + + SUIT_PopupClient(); + ~SUIT_PopupClient(); + + bool connectPopupRequest( QObject* reciever, const char* slot ); + bool disconnectPopupRequest( QObject* reciever, const char* slot ); + + virtual QString popupClientType() const = 0; + virtual void contextMenuPopup( QPopupMenu* ) {} + +protected: + void contextMenuRequest( QContextMenuEvent* e ); + +private: + Signal* mySignal; +}; + +/*! Class: SUIT_PopupClient::Signal [internal] \n + * Descr: invoke signal which is connected to reciever in SUIT_PopupClient + */ +class SUIT_PopupClient::Signal : public QObject +{ + Q_OBJECT + +public: + Signal(); + virtual ~Signal(); + + void sendSignal( SUIT_PopupClient*, QContextMenuEvent* ); + +signals: + void contextMenuRequest( SUIT_PopupClient*, QContextMenuEvent* ); +}; + +#endif diff --git a/src/SUIT/SUIT_ResourceMgr.cxx b/src/SUIT/SUIT_ResourceMgr.cxx new file mode 100755 index 000000000..ed8f3a872 --- /dev/null +++ b/src/SUIT/SUIT_ResourceMgr.cxx @@ -0,0 +1,75 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "SUIT_ResourceMgr.h" + +/*! + Constructor +*/ +SUIT_ResourceMgr::SUIT_ResourceMgr( const QString& app, const QString& resVarTemplate ) +: QtxResourceMgr( app, resVarTemplate ) +{ +} + +/*! + Destructor +*/ +SUIT_ResourceMgr::~SUIT_ResourceMgr() +{ +} + +/*! + Returns the version of application +*/ +QString SUIT_ResourceMgr::version() const +{ + return myVersion; +} + +/*! + Sets the version of application +*/ +void SUIT_ResourceMgr::setVersion( const QString& ver ) +{ + myVersion = ver; +} + +/*! + Loads a doc page from 'prefix' resources and indetified by 'id' +*/ +QString SUIT_ResourceMgr::loadDoc( const QString& prefix, const QString& id ) const +{ + QString docSection = option( "doc_section_name" ); + if ( docSection.isEmpty() ) + docSection = QString( "docs" ); + + return path( docSection, prefix, id ); +} + +/*! + Returns the user file name for specified application +*/ +QString SUIT_ResourceMgr::userFileName( const QString& appName ) const +{ + QString pathName = QtxResourceMgr::userFileName( appName ); + + if ( !version().isEmpty() ) + pathName += QString( "." ) + version(); + + return pathName; +} diff --git a/src/SUIT/SUIT_ResourceMgr.h b/src/SUIT/SUIT_ResourceMgr.h new file mode 100755 index 000000000..2b1a18bec --- /dev/null +++ b/src/SUIT/SUIT_ResourceMgr.h @@ -0,0 +1,44 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SUIT_RESOURCEMGR_H +#define SUIT_RESOURCEMGR_H + +#include "SUIT.h" + +#include + +class SUIT_EXPORT SUIT_ResourceMgr : public QtxResourceMgr +{ +public: + SUIT_ResourceMgr( const QString&, const QString& = QString::null ); + virtual ~SUIT_ResourceMgr(); + + virtual QString version() const; + void setVersion( const QString& ); + + QString loadDoc( const QString&, const QString& ) const; + +protected: + virtual QString userFileName( const QString& ) const; + +private: + QString myVersion; +}; + +#endif diff --git a/src/SUIT/SUIT_SelectionFilter.cxx b/src/SUIT/SUIT_SelectionFilter.cxx new file mode 100644 index 000000000..abb30272c --- /dev/null +++ b/src/SUIT/SUIT_SelectionFilter.cxx @@ -0,0 +1,28 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "SUIT_SelectionFilter.h" + +/*! constructor. do nothing*/ +SUIT_SelectionFilter::SUIT_SelectionFilter() +{ +} +/*! destructor. do nothing*/ +SUIT_SelectionFilter::~SUIT_SelectionFilter() +{ +} diff --git a/src/SUIT/SUIT_SelectionFilter.h b/src/SUIT/SUIT_SelectionFilter.h new file mode 100644 index 000000000..2f64f7ec9 --- /dev/null +++ b/src/SUIT/SUIT_SelectionFilter.h @@ -0,0 +1,36 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SUIT_SELECTIONFILTER_H +#define SUIT_SELECTIONFILTER_H + +#include "SUIT.h" + +class SUIT_DataOwner; + +/*!Base class.*/ +class SUIT_EXPORT SUIT_SelectionFilter +{ +public: + SUIT_SelectionFilter(); + ~SUIT_SelectionFilter(); + + virtual bool isOk( const SUIT_DataOwner* ) const = 0; +}; + +#endif diff --git a/src/SUIT/SUIT_Selector.cxx b/src/SUIT/SUIT_Selector.cxx new file mode 100755 index 000000000..7b23bb9f9 --- /dev/null +++ b/src/SUIT/SUIT_Selector.cxx @@ -0,0 +1,142 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "SUIT_Selector.h" + +#include "SUIT_SelectionMgr.h" + +/*!\class SUIT_Selector + * Class provide selector for data owners. + */ + +/*! + Constructor. +*/ +SUIT_Selector::SUIT_Selector( SUIT_SelectionMgr* selMgr, QObject* parent ) : +QObject( parent ), +mySelMgr( selMgr ), +myBlock( false ), +myEnabled( true ), +myAutoBlock( true ) +{ + if ( selMgr ) + selMgr->installSelector( this ); +} + +/*! + Destructor. +*/ +SUIT_Selector::~SUIT_Selector() +{ + if ( selectionMgr() ) + selectionMgr()->removeSelector( this ); +} + +/*! + Gets selection manager. +*/ +SUIT_SelectionMgr* SUIT_Selector::selectionMgr() const +{ + return mySelMgr; +} + +/*! + Checks: Is selctor enabled? +*/ +bool SUIT_Selector::isEnabled() const +{ + return myEnabled; +} + +/*! + Sets selctor anbled to \a on. +*/ +void SUIT_Selector::setEnabled( const bool on ) +{ + myEnabled = on; +} + +/*! + Checks: Is selector auto block? +*/ +bool SUIT_Selector::autoBlock() const +{ + return myAutoBlock; +} + +/*! + Sets selctor autoblock to \a on. +*/ +void SUIT_Selector::setAutoBlock( const bool on ) +{ + myAutoBlock = on; +} + +/*! + Puts to \a lst selection list of data owners. +*/ +void SUIT_Selector::selected( SUIT_DataOwnerPtrList& lst ) const +{ + lst.clear(); + getSelection( lst ); +} + +/*! + Puts to selection list of data owners \a lst.. +*/ +void SUIT_Selector::setSelected( const SUIT_DataOwnerPtrList& lst ) +{ + if ( !isEnabled() ) + return; + + bool block = myBlock; + myBlock = true; + + setSelection( lst ); + + myBlock = block; +} + +/*! + On selection changed. +*/ +void SUIT_Selector::selectionChanged() +{ + if ( selectionMgr() && isEnabled() && ( !autoBlock() || !myBlock ) ) + selectionMgr()->selectionChanged( this ); +} + +/*! + Checks: Is selection manager has selection mode \a mode? +*/ +bool SUIT_Selector::hasSelectionMode( const int mode ) const +{ + if ( !selectionMgr() ) + return false; + + return selectionMgr()->hasSelectionMode( mode ); +} + +/*! + Puts to list \a lst selection modes from selection manager. +*/ +void SUIT_Selector::selectionModes( QValueList& lst ) const +{ + if ( selectionMgr() ) + selectionMgr()->selectionModes( lst ); +} diff --git a/src/SUIT/SUIT_Selector.h b/src/SUIT/SUIT_Selector.h new file mode 100755 index 000000000..5d1ae0e3a --- /dev/null +++ b/src/SUIT/SUIT_Selector.h @@ -0,0 +1,65 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SUIT_SELECTOR_H +#define SUIT_SELECTOR_H + +#include "SUIT.h" + +#include +#include + +class SUIT_SelectionMgr; +class SUIT_DataOwnerPtrList; + +class SUIT_EXPORT SUIT_Selector : public QObject +{ + Q_OBJECT +public: + SUIT_Selector( SUIT_SelectionMgr*, QObject* = 0 ); + virtual ~SUIT_Selector(); + + virtual QString type() const = 0; + + SUIT_SelectionMgr* selectionMgr() const; + + bool isEnabled() const; + virtual void setEnabled( const bool ); + + bool autoBlock() const; + virtual void setAutoBlock( const bool ); + + void selected( SUIT_DataOwnerPtrList& ) const; + void setSelected( const SUIT_DataOwnerPtrList& ); + + bool hasSelectionMode( const int ) const; + void selectionModes( QValueList& ) const; + +protected: + void selectionChanged(); + virtual void getSelection( SUIT_DataOwnerPtrList& ) const = 0; + virtual void setSelection( const SUIT_DataOwnerPtrList& ) = 0; + +private: + bool myBlock; + SUIT_SelectionMgr* mySelMgr; + bool myEnabled; + bool myAutoBlock; +}; + +#endif diff --git a/src/SUIT/SUIT_Session.cxx b/src/SUIT/SUIT_Session.cxx new file mode 100755 index 000000000..03f32ee74 --- /dev/null +++ b/src/SUIT/SUIT_Session.cxx @@ -0,0 +1,325 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "SUIT_Session.h" + +#include "SUIT_Tools.h" +#include "SUIT_Desktop.h" +#include "SUIT_MessageBox.h" +#include "SUIT_ViewWindow.h" +#include "SUIT_ViewManager.h" +#include "SUIT_ExceptionHandler.h" + +#include +#include +#include + +#ifdef WIN32 +#include +#else +#include +#endif + +SUIT_Session* SUIT_Session::mySession = 0; + +/*! Constructor.*/ + +SUIT_Session::SUIT_Session() +: QObject(), +myResMgr( 0 ), +myHandler( 0 ), +myActiveApp( 0 ), +myExitStatus( FROM_GUI ) +{ + SUIT_ASSERT( !mySession ) + + mySession = this; + + myAppList.setAutoDelete( true ); +} + +/*!destructor. Clear applications list and set mySession to zero.*/ +SUIT_Session::~SUIT_Session() +{ + myAppList.clear(); + + mySession = 0; +} + +/*! \retval return mySession */ +SUIT_Session* SUIT_Session::session() +{ + return mySession; +} + +/*! + Starts new application using "createApplication" function of loaded DLL. +*/ + +SUIT_Application* SUIT_Session::startApplication( const QString& name, int args, char** argv ) +{ + AppLib libHandle = 0; + + QString appName = applicationName( name ); + if ( myAppLibs.contains( appName ) ) + libHandle = myAppLibs[appName]; + + QString lib; + if ( !libHandle ) + libHandle = loadLibrary( name, lib ); + + if ( !libHandle ) + { + SUIT_MessageBox::warn1( 0, tr( "Error" ), + tr( "Can not load application library \"%1\": %2").arg( lib ).arg( lastError() ), tr( "Ok" ) ); + return 0; + } + + if ( !myAppLibs.contains( appName ) || !myAppLibs[appName] ) // jfa 22.06.2005 + myAppLibs.insert( appName, libHandle ); + + APP_CREATE_FUNC crtInst = 0; + +#ifdef WIN32 + crtInst = (APP_CREATE_FUNC)::GetProcAddress( libHandle, APP_CREATE_NAME ); +#else + crtInst = (APP_CREATE_FUNC)dlsym( libHandle, APP_CREATE_NAME ); +#endif + + if ( !crtInst ) + { + SUIT_MessageBox::warn1( 0, tr( "Error" ), + tr( "Can not find function \"%1\": %2" ).arg( APP_CREATE_NAME ).arg( lastError() ), tr( "Ok" ) ); + return 0; + } + + // Prepare Resource Manager for the new application if it doesn't exist yet + if ( !myResMgr ) + { + myResMgr = createResourceMgr( appName ); + myResMgr->loadLanguage(); + } + + //jfa 22.06.2005:SUIT_Application* anApp = crtInst( args, argv ); + SUIT_Application* anApp = crtInst(); + if ( !anApp ) + { + SUIT_MessageBox::warn1( 0, tr( "Error" ), tr( "Can not create application \"%1\": %2").arg( appName ).arg( lastError() ), tr( "Ok" ) ); + return 0; + } + + anApp->setName( appName ); + + connect( anApp, SIGNAL( applicationClosed( SUIT_Application* ) ), + this, SLOT( onApplicationClosed( SUIT_Application* ) ) ); + connect( anApp, SIGNAL( activated( SUIT_Application* ) ), + this, SLOT( onApplicationActivated( SUIT_Application* ) ) ); + + myAppList.append( anApp ); + + if ( !myHandler ) + { + APP_GET_HANDLER_FUNC crtHndlr = 0; +#ifdef WIN32 + crtHndlr = (APP_GET_HANDLER_FUNC)::GetProcAddress( libHandle, APP_GET_HANDLER_NAME ); +#else + crtHndlr = (APP_GET_HANDLER_FUNC)dlsym( libHandle, APP_GET_HANDLER_NAME ); +#endif + if ( crtHndlr ) + myHandler = crtHndlr(); + } + + anApp->start(); + + // Application can be closed during starting (not started). + if ( !myAppList.contains( anApp ) ) + anApp = 0; + + return anApp; +} + +/*! + Gets the list of all applications +*/ +QPtrList SUIT_Session::applications() const +{ + QPtrList apps; + apps.setAutoDelete( false ); + + for ( AppListIterator it( myAppList ); it.current(); ++it ) + apps.append( it.current() ); + + return apps; +} + +/*! + Returns the active application +*/ +SUIT_Application* SUIT_Session::activeApplication() const +{ + /* + if ( myAppList.count() == 1 ) + return myAppList.getFirst(); + + SUIT_Desktop* desktop = 0; + for ( AppListIterator it( myAppList ); it.current() && !desktop; ++it ) + { + SUIT_Desktop* desk = it.current()->desktop(); + if ( desk && desk->isActiveWindow() ) + desktop = desk; + } + + if ( !desktop ) + return 0; + + SUIT_ViewWindow* win = desktop->activeWindow(); + if ( !win || !win->getViewManager() ) + return 0; + + SUIT_Study* study = win->getViewManager()->study(); + if ( !study ) + return 0; + + return study->application(); + */ + return myActiveApp; +} + +/*! + Returns the resource manager for the specified application name. +*/ +SUIT_ResourceMgr* SUIT_Session::resourceMgr() const +{ + return myResMgr; +} + +/*! + Removes the application from the list of launched applications. + If it is a last application the session will be closed. +*/ +void SUIT_Session::onApplicationClosed( SUIT_Application* theApp ) +{ + emit applicationClosed( theApp ); + + myAppList.remove( theApp ); + if ( theApp == myActiveApp ) + myActiveApp = 0; + + if ( myAppList.isEmpty() ) + { + printf( "Calling QApplication::exit() with exit code = %d\n", myExitStatus ); + qApp->exit( myExitStatus ); + } +} + +/*! + Destroys session by closing all applications. +*/ +void SUIT_Session::closeSession( int mode ) +{ + while ( !myAppList.isEmpty() ) + { + SUIT_Application* app = myAppList.getFirst(); + if ( mode == ASK && !app->isPossibleToClose() ) + return; + else if ( mode == SAVE ) + { + SUIT_Study* study = app->activeStudy(); + if ( study->isModified() && study->isSaved() ) + study->saveDocument(); + } + else if ( mode == DONT_SAVE ) + { + myExitStatus = FROM_CORBA_SESSION; + //.... + } + + app->closeApplication(); + } +} + +/*! \retval return myHandler*/ +SUIT_ExceptionHandler* SUIT_Session::handler() const +{ + return myHandler; +} + +/*! \retval return last error string.*/ +QString SUIT_Session::lastError() const +{ + QString str; +#ifdef WNT + LPVOID lpMsgBuf; + ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, 0, ::GetLastError(), 0, (LPTSTR)&lpMsgBuf, 0, 0 ); + str = QString( (LPTSTR)lpMsgBuf ); + LocalFree( lpMsgBuf ); +#else + str = QString( dlerror() ); +#endif + return str; +} + +/*! Load library to session. + * \retval Loaded library. + */ +SUIT_Session::AppLib SUIT_Session::loadLibrary( const QString& name, QString& libName ) +{ + QString libFile = SUIT_Tools::library( name ); + + libName = libFile; + if ( libFile.isEmpty() ) + return 0; + + AppLib lib = 0; +#ifdef WIN32 + lib = ::LoadLibrary( (char*)libFile.latin1() ); +#else + lib = dlopen( (char*)libFile.latin1(), RTLD_LAZY ); +#endif + return lib; +} + +/*! \retval Return file name by application name.*/ +QString SUIT_Session::applicationName( const QString& str ) const +{ +#ifdef WIN32 + return SUIT_Tools::file( str, false ); +#else + QString fileName = SUIT_Tools::file( str, false ); + if ( fileName.startsWith( "lib" ) ) + fileName = fileName.right( fileName.length() - 3 ); + return fileName; +#endif +} + +/*! + Virtual method, creates an instance of ResourceManager +*/ +SUIT_ResourceMgr* SUIT_Session::createResourceMgr( const QString& appName ) const +{ + return new SUIT_ResourceMgr( appName ); +} + +/*! + Slot, called on activation of some application's desktop +*/ +void SUIT_Session::onApplicationActivated( SUIT_Application* app ) +{ + myActiveApp = app; +} diff --git a/src/SUIT/SUIT_Session.h b/src/SUIT/SUIT_Session.h new file mode 100755 index 000000000..505f00c1a --- /dev/null +++ b/src/SUIT/SUIT_Session.h @@ -0,0 +1,108 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SUIT_SESSION_H +#define SUIT_SESSION_H + +#include "SUIT.h" + +#include "SUIT_Application.h" +#include "SUIT_ResourceMgr.h" + +#include +#include +#include +#include + +#ifdef WIN32 +#define LIB_HANDLE HINSTANCE +#else +#define LIB_HANDLE void* +#endif + +class SUIT_ResourceMgr; +class SUIT_ExceptionHandler; + +#ifdef WNT +#pragma warning( disable:4251 ) +#endif +/*! + The class Sesssion manages launching of Applications. Application must be returned \n + by static function "createApplication" in external library. The Library must be loaded with \n + loadLibrary method and after that application can be started. +*/ +class SUIT_EXPORT SUIT_Session: public QObject +{ + Q_OBJECT + +public: + typedef LIB_HANDLE AppLib; + + enum { ASK = 0, SAVE, DONT_SAVE } CloseMode; + enum { FROM_GUI = 0, FROM_CORBA_SESSION } ExitStatus; + +public: + SUIT_Session(); + virtual ~SUIT_Session(); + + static SUIT_Session* session(); + + SUIT_Application* startApplication( const QString&, int = 0, char** = 0 ); + + QPtrList applications() const; + SUIT_Application* activeApplication() const; + + SUIT_ResourceMgr* resourceMgr() const; + + void closeSession( int mode = ASK ); + + SUIT_ExceptionHandler* handler() const; + +signals: + void applicationClosed( SUIT_Application* ); + +protected: + virtual SUIT_ResourceMgr* createResourceMgr( const QString& ) const; + +private slots: + void onApplicationClosed( SUIT_Application* ); + void onApplicationActivated( SUIT_Application* ); + +private: + typedef QPtrList AppList; + typedef QMap AppLibMap; + typedef QPtrListIterator AppListIterator; + +private: + QString lastError() const; + AppLib loadLibrary( const QString&, QString& ); + QString applicationName( const QString& ) const; + +private: + SUIT_ResourceMgr* myResMgr; + AppList myAppList; + AppLibMap myAppLibs; + SUIT_Application* myActiveApp; + + SUIT_ExceptionHandler* myHandler; + static SUIT_Session* mySession; + + int myExitStatus; +}; + +#endif diff --git a/src/SUIT/SUIT_SmartPtr.h b/src/SUIT/SUIT_SmartPtr.h new file mode 100755 index 000000000..4f0d7a4c9 --- /dev/null +++ b/src/SUIT/SUIT_SmartPtr.h @@ -0,0 +1,129 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#if !defined(__SUIT_SMARTPTR_H) +#define __SUIT_SMARTPTR_H + +#include "SUIT.h" + +/*! \brief Base counter class what children using in SmartPtr class how template */ +class SUIT_EXPORT RefCount { +public: + //! constructor + RefCount() : crefs( 0 ) {} + //! copy constructor + RefCount( const RefCount& ) : crefs( 0 ) {} + //! destructor + virtual ~RefCount() {} + //! operator= (does not change counter) + RefCount& operator=( const RefCount& ) { return *this; } + + //! increments reference counter + void upcount() { + ++crefs; + } + + //! decrements reference counter + void downcount() + { + if ( crefs > 0 && --crefs == 0 ) + delete this; + } + + //! get reference counter value + int refcount() const { return crefs; } + +private: + unsigned long crefs; //!< reference counter +}; + +/*! \brief Template class that provides automatic casting for hold RefCount based objects.*/ +template class SmartPtr { +public: + //! default constructor + SmartPtr() : p( 0 ) {} + //! constructor from any RefCount-based class + template SmartPtr( Y* y_ ) { p = dynamic_cast( y_ ); if ( p ) p->upcount(); } + //! copy constructor from any RefCount-based class + template SmartPtr( const SmartPtr& y_ ) { p = dynamic_cast( y_.get() ); if ( p ) p->upcount(); } + //! copy constructor + SmartPtr( const SmartPtr& t_ ) : p( t_.p ) { if ( p ) p->upcount(); } + //! destructor + virtual ~SmartPtr(void) + { + if ( p ) + p->downcount(); + } + + // getting access + T& operator*() const { return *p; }//!< return *pointer + T* operator->() const { return p; }//!< return pointer + operator T*() const { return p; }//!< return pointer + T* get() const { return p; }//!< return pointer + + //! assignment + template SmartPtr& operator=( const SmartPtr& y_ ) + { + if ( this == &y_) return *this; + return operator=( y_.get() ); + } + //! assignment + SmartPtr& operator=( const SmartPtr& t_ ) + { + if ( this == &t_) return *this; + return operator=( t_.get() ); + } + //!< assignment + SmartPtr& operator=( T* p_ ) + { + if ( p ) + p->downcount(); + p = p_; + if ( p ) + p->upcount(); + return *this; + } + + // comparing + int operator==( const SmartPtr& t_ ) { return p == t_.p; }//!< comparing + int operator==( const T* p_ ) { return p == p_; }//!< comparing + friend int operator==( const T* p_, const SmartPtr& t_ ) { return t_ == p_; }//!< comparing + int operator!=( SmartPtr& t_ ) { return p != t_.p; }//!< comparing + int operator!=( T* p_ ) { return p != p_; }//!< comparing + friend int operator!=( T* p_, SmartPtr& t_ ) { return p_ != t_.p; }//!< comparing + + //! nullify + void nullify() { if ( p ) p->downcount(); p = 0; } + //! check for null + bool isNull() const { return p == 0; } + +private: + T* p;//!< stored pointer +}; + +/*! \def SMART( C ) + * Define macros SMART( C ) - same as SmartPtr(C), where \a C - class object. + */ +#define SMART( C ) SmartPtr +//! casting class T2 to class T1 +template SMART(T1) downcast( SMART(T2)& t ) +{ + return SMART(T1)(t.get()); +} + +#endif // __SUIT_SMARTPTR_H diff --git a/src/SUIT/SUIT_Study.cxx b/src/SUIT/SUIT_Study.cxx new file mode 100755 index 000000000..2f83179c4 --- /dev/null +++ b/src/SUIT/SUIT_Study.cxx @@ -0,0 +1,512 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "SUIT_Study.h" + +#include "SUIT_Desktop.h" +#include "SUIT_Operation.h" +#include "SUIT_DataObject.h" +#include "SUIT_MessageBox.h" +#include "SUIT_Application.h" +#include + +/*!\class SUIT_Study + * Support study management. Object management. Operation management. + */ + +/*!Constructor.*/ +SUIT_Study::SUIT_Study( SUIT_Application* app ) +: QObject(), +myApp( app ), +myIsSaved( false ), +myIsModified( false ), +myName( "" ), +myBlockChangeState( false ) +{ + static int _id = 0; + + myId = ++_id; + + myRoot = new SUIT_DataObject(); + myOperations.setAutoDelete( false ); + myOperations.setAutoDelete( false ); +} + +/*!Destructor.*/ +SUIT_Study::~SUIT_Study() +{ + delete myRoot; + myRoot = 0; +} + +/*! + *\retval study id. + */ +int SUIT_Study::id() const +{ + return myId; +} + +/*! + *\retval root data object. + */ +SUIT_DataObject* SUIT_Study::root() const +{ + return myRoot; +} + +/*! + *\retval Application. + */ +SUIT_Application* SUIT_Study::application() const +{ + return myApp; +} + +/*! + *\retval study name + */ +QString SUIT_Study::studyName() const +{ + return myName; +} + +/*! + *\retval active operation. + */ +SUIT_Operation* SUIT_Study::activeOperation() const +{ + return myOperations.count() > 0 ? myOperations.getLast() : 0; +} + +/*! + *\retval TRUE - if study saved, else FALSE. + */ +bool SUIT_Study::isSaved() const +{ + return myIsSaved; +} + +/*! + *\retval TRUE - if study modified, else FALSE. + */ +bool SUIT_Study::isModified() const +{ + return myIsModified; +} + +/*! + *Close document. NOT IMPLEMENTED. + */ +void SUIT_Study::closeDocument(bool permanently) +{ +} + +void SUIT_Study::createDocument() +{ + /*! Custom document initialization to be performed \n + * within onNewDoc() handler can be put here + */ +} + +/*! + * Open document. Sets file name. return true. + */ +bool SUIT_Study::openDocument( const QString& fileName ) +{ + myName = fileName; + myIsSaved = true; + myIsModified = false; + + return true; +} + +/*! + * Save document as \a fileName. Set file name. + */ +bool SUIT_Study::saveDocumentAs( const QString& fileName ) +{ + myName = fileName; + myIsSaved = true; + myIsModified = false; + + return true; +} + +/*! + *\retval TRUE - if document saved successful, else FALSE. + */ +bool SUIT_Study::saveDocument() +{ + return saveDocumentAs( myName ); +} + +/*! + *Abort all operations. + */ +void SUIT_Study::abortAllOperations() +{ + myBlockChangeState = true; + for( SUIT_Operation* op = myOperations.first(); op; op = myOperations.next() ) + op->abort(); + myBlockChangeState = false; + myOperations.clear(); +} + +/*! + Update study. NOT IMPLEMENTED HERE. + */ +void SUIT_Study::update() +{ +} + +/*! + Emit study modified. + */ +void SUIT_Study::sendChangesNotification() +{ + emit studyModified( this ); +} + +/*! + Set study saved to \a on. + */ +void SUIT_Study::setIsSaved( const bool on ) +{ + myIsSaved = on; +} + +/*! + Set study modified to \a on. + */ +void SUIT_Study::setIsModified( const bool on ) +{ + myIsModified = on; +} + +/*! + Set root object. + */ +void SUIT_Study::setRoot( SUIT_DataObject* obj ) +{ + if ( myRoot == obj ) + return; + + // This is necessary in order not to destroy the complete tree of objects + if ( obj ) + obj->reparentChildren( myRoot ); + + delete myRoot; + myRoot = obj; +} + +/*! + Set study name. + */ +void SUIT_Study::setStudyName( const QString& name ) +{ + myName = name; +} + +/*! + * \brief Verifies whether operation can be activated above already started ones + * \param theOp - operation to be checked + * \return NULL if operation can be activated, pointer to operation which denies + * starting tested operation +* +* Verifies whether operation can be activated above already started ones. This method +* is called from SUIT_Study::start() and SUIT_Study::resume() methods. +*/ +SUIT_Operation* SUIT_Study::blockingOperation( SUIT_Operation* theOp ) const +{ + if( theOp->isGranted() ) + return 0; + + Operations tmpOps( myOperations ); + SUIT_Operation* anOp = 0; + for ( anOp = tmpOps.last(); anOp; anOp = tmpOps.prev() ) + { + if ( anOp != 0 && anOp!= theOp && !anOp->isValid( theOp ) ) + return anOp; + } + + return 0; +} + +/*! + * \brief Starts operation + * \param theOp - operation to be started + * \param toCheck - if parameters is equal TRUE then checking performed whether + * all already started operations allow to start this operation above them (default + * value is TRUE + * \return TRUE if operation is started, FALSE otherwise +* +* Verifies whether theOp operation can be started above already started ones (if toCheck +* parameter is equal TRUE) and starts it +*/ +bool SUIT_Study::start( SUIT_Operation* theOp, const bool toCheck ) +{ + if ( !theOp || myOperations.find( theOp ) >= 0 ) + return false; + + theOp->setExecStatus( SUIT_Operation::Rejected ); + theOp->setStudy( this ); + + if ( !theOp->isReadyToStart() ) + return false; + + if ( toCheck ) + { + while( SUIT_Operation* anOp = blockingOperation( theOp ) ) + { + int anAnsw = SUIT_MessageBox::warn2( application()->desktop(), + tr( "OPERATION_LAUNCH" ), tr( "PREVIOUS_NOT_FINISHED" ), + tr( "CONTINUE" ), tr( "CANCEL" ), 0, 1, 1 ); + + if ( anAnsw == 1 ) + return false; + else + anOp->abort(); + } + } + + SUIT_Operation* anOp = activeOperation(); + if ( anOp ) + { + activeOperation()->suspendOperation(); + anOp->setState( SUIT_Operation::Suspended ); + } + + theOp->setState( SUIT_Operation::Running ); + myOperations.append( theOp ); + + emit theOp->started( theOp ); + operationStarted( theOp ); + theOp->startOperation(); + + return true; +} + +/*! + * \brief Aborts operation + * \param theOp - operation to be aborted + * \return TRUE if operation is aborted successfully +* +* Verifies whether operation already started and aborts it in this case (sets execution +* status to Rejected and stops operation) +*/ +bool SUIT_Study::abort( SUIT_Operation* theOp ) +{ + if ( !theOp || myOperations.find( theOp ) == -1 ) + return false; + + theOp->setExecStatus( SUIT_Operation::Rejected ); + + theOp->abortOperation(); + operationAborted( theOp ); + emit theOp->aborted( theOp ); + + stop( theOp ); + + return true; +} + +/*! + * \brief Commits operation + * \param theOp - operation to be committed + * \return TRUE if operation is committed successfully +* +* Verifies whether operation already started and commits it in this case (sets execution +* status to Accepted and stops operation) +*/ +bool SUIT_Study::commit( SUIT_Operation* theOp ) +{ + if ( !theOp || myOperations.find( theOp ) == -1 ) + return false; + + theOp->setExecStatus( SUIT_Operation::Accepted ); + + theOp->commitOperation(); + operationCommited( theOp ); + emit theOp->committed( theOp ); + + stop( theOp ); + + emit studyModified( this ); + + return true; +} + +/*! + * \brief Commits operation + * \param theOp - operation to be committed + * \return TRUE if operation is suspended successfully +* +* Verifies whether operation already started and suspends it in this case. Operations +* ususlly are suspended to start other one above them. +*/ +bool SUIT_Study::suspend( SUIT_Operation* theOp ) +{ + if ( !theOp || myOperations.find( theOp ) == -1 || theOp->state() == SUIT_Operation::Suspended ) + return false; + + theOp->setState( SUIT_Operation::Suspended ); + theOp->suspendOperation(); + emit theOp->suspended( theOp ); + return true; +} + + +/*! + * \brief Resumes operation + * \param theOp - operation to be resumed + * \return TRUE if operation is aborted successfully +* +* Verifies whether operation already started but suspended and resumesit in this case. +*/ +bool SUIT_Study::resume( SUIT_Operation* theOp ) +{ + if ( !theOp || myOperations.find( theOp ) == -1 || + theOp->state() == SUIT_Operation::Running || + blockingOperation( theOp ) != 0 ) + return false; + + if ( myOperations.count() > 0 ) + suspend( myOperations.last() ); + + theOp->setState( SUIT_Operation::Running ); + theOp->resumeOperation(); + + // Move operation at the end of list in order to sort it in the order of activation. + // As result active operation is a last operation of list, operation which was active + // before currently active operation is located before it and so on + myOperations.remove( theOp ); + myOperations.append( theOp ); + + emit theOp->resumed( theOp ); + return true; +} + +/*! + * \brief Stops operation + * \param theOp - operation to be stopped +* +* Stops operation. This private method is called from abort() and commit() ones to perform +* common actions when operation is stopped +*/ +void SUIT_Study::stop( SUIT_Operation* theOp ) +{ + theOp->setState( SUIT_Operation::Waiting ); + myOperations.remove( theOp ); + + // get last operation which can be resumed + SUIT_Operation* anOp, *aResultOp = 0; + for ( anOp = myOperations.last(); anOp; anOp = myOperations.prev() ) + { + if ( anOp && anOp != theOp && blockingOperation( anOp ) == 0 ) + { + aResultOp = anOp; + break; + } + } + + theOp->stopOperation(); + operationStopped( theOp ); + emit theOp->stopped( theOp ); + + if ( aResultOp ) + resume( aResultOp ); +} + +/*! + * \brief Get all started operations + * \return List of all started operations +*/ +const QPtrList& SUIT_Study::operations() const +{ + return myOperations; +} + +/*! + * \brief Perform some actions when operation starting +*/ +void SUIT_Study::operationStarted( SUIT_Operation* op ) +{ + if ( !op ) + return; + + if ( op->testFlags( SUIT_Operation::Transaction ) ) + op->openTransaction(); +} + +/*! + * \brief Perform some actions when operation aborted +*/ +void SUIT_Study::operationAborted( SUIT_Operation* op ) +{ + if ( op->testFlags( SUIT_Operation::Transaction ) ) + op->abortTransaction(); +} + +/*! + * \brief Perform some actions when operation commited +*/ +void SUIT_Study::operationCommited( SUIT_Operation* op ) +{ + if ( op->testFlags( SUIT_Operation::Transaction ) ) + op->commitTransaction( op->operationName() ); +} + +/*! + * \brief Perform some actions when operation stopped +*/ +void SUIT_Study::operationStopped( SUIT_Operation* ) +{ +} + +/*! + * \brief Opens transaction for data modifications. +*/ +bool SUIT_Study::openTransaction() +{ + return true; +} + +/*! + * \brief Aborts transaction and all performed data modifications. +*/ +bool SUIT_Study::abortTransaction() +{ + return true; +} + +/*! + * \brief Commits transaction and all performed data modifications. +*/ +bool SUIT_Study::commitTransaction( const QString& ) +{ + return true; +} + +/*! + * \brief Returns TRUE if transaction is opened. +*/ +bool SUIT_Study::hasTransaction() const +{ + return false; +} diff --git a/src/SUIT/SUIT_Study.h b/src/SUIT/SUIT_Study.h new file mode 100755 index 000000000..c1163cc6c --- /dev/null +++ b/src/SUIT/SUIT_Study.h @@ -0,0 +1,118 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SUIT_STUDY_H +#define SUIT_STUDY_H + +#include "SUIT.h" + +#include "SUIT_Operation.h" + +#include +#include + +class SUIT_DataObject; +class SUIT_Application; +class QDialog; + +#ifdef WIN32 +#pragma warning( disable:4251 ) +#endif + +class SUIT_EXPORT SUIT_Study : public QObject +{ + Q_OBJECT + +public: + SUIT_Study( SUIT_Application* ); + virtual ~SUIT_Study(); + + virtual int id() const; + + SUIT_DataObject* root() const; + QString studyName() const; + SUIT_Application* application() const; + + virtual bool isSaved() const; + virtual bool isModified() const; + + virtual void createDocument(); + virtual void closeDocument( bool = true ); + virtual bool openDocument( const QString& ); + + bool saveDocument(); + virtual bool saveDocumentAs( const QString& ); + + virtual void update(); + + virtual void sendChangesNotification(); + + // Operation management + SUIT_Operation* activeOperation() const; + virtual void abortAllOperations(); + const QPtrList& operations() const; + + virtual SUIT_Operation* blockingOperation( SUIT_Operation* ) const; + + bool start( SUIT_Operation*, const bool check = true ); + bool abort( SUIT_Operation* ); + bool commit( SUIT_Operation* ); + bool suspend( SUIT_Operation* ); + bool resume( SUIT_Operation* ); + +signals: + void studyModified( SUIT_Study* ); + +protected: + virtual void setIsSaved( const bool ); + virtual void setIsModified( const bool ); + virtual void setRoot( SUIT_DataObject* ); + virtual void setStudyName( const QString& ); + + virtual void operationStarted( SUIT_Operation* ); + virtual void operationAborted( SUIT_Operation* ); + virtual void operationStopped( SUIT_Operation* ); + virtual void operationCommited( SUIT_Operation* ); + + virtual bool openTransaction(); + virtual bool abortTransaction(); + virtual bool hasTransaction() const; + virtual bool commitTransaction( const QString& = QString::null ); + +private: + typedef QPtrList Operations; + void stop( SUIT_Operation* ); + +private: + int myId; + SUIT_Application* myApp; + SUIT_DataObject* myRoot; + QString myName; + bool myIsSaved; + bool myIsModified; + Operations myOperations; + bool myBlockChangeState; + + friend class SUIT_Operation; +}; + +#ifdef WIN32 +#pragma warning( default:4251 ) +#endif + +#endif diff --git a/src/SUIT/SUIT_ToolButton.cxx b/src/SUIT/SUIT_ToolButton.cxx new file mode 100755 index 000000000..f0434db3c --- /dev/null +++ b/src/SUIT/SUIT_ToolButton.cxx @@ -0,0 +1,144 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// + +#include "SUIT_ToolButton.h" + +#include +#include + +/*!Constructor.*/ +SUIT_ToolButton::SUIT_ToolButton( QWidget *parent, + const char *name, + bool changeItemAfterClick) + : QToolButton( parent, name ), + myChangeItemAfterClick( changeItemAfterClick ) +{ + initialize(); +} + +/*!Constructor.*/ +SUIT_ToolButton::SUIT_ToolButton( const QPixmap & pm, + const QString &textLabel, + const QString& grouptext, + QObject * receiver, + const char* slot, + QToolBar * parent, + const char* name, + bool changeItemAfterClick) + :QToolButton(pm, textLabel, grouptext, receiver, slot, parent, name), + myChangeItemAfterClick( changeItemAfterClick ) +{ + initialize(); +} + + +/*!Initialize tool buttons.*/ +void SUIT_ToolButton::initialize() +{ + mySignal = NULL; + myPopup = new QPopupMenu( this ); + setPopup(myPopup); + connect( myPopup, SIGNAL(activated(int)), SLOT(OnSelectAction(int)) ); + setPopupDelay(250); +} + +/*!drawButton is redefined to draw DownArrow*/ +void SUIT_ToolButton::drawButton( QPainter * p ) +{ + QToolButton::drawButton(p); + +//draw DownArrow + int x, y, w, h; + QStyle::visualRect(QRect(0, 0, width(), height()), this).rect( &x, &y, &w, &h ); + style().drawPrimitive( QStyle::PE_ArrowDown, + p, QRect(x+w/2+3, y+h/2+3, w/2, h/2), //QRect(x+(w-x)/2, y+(h-y)/2, w, h) + colorGroup(), isEnabled() ); +} + + +/*! Add action into popup*/ +void SUIT_ToolButton::AddAction(QAction* theAction) +{ + bool aIsFirst = false; + if ( myPopup->count() == 0 ) + { + aIsFirst = true; + setPixmap(theAction->iconSet().pixmap()); + setTextLabel(theAction->text()); + theAction->addTo( myPopup ); + QMenuItem* aItem = myPopup->findItem(myPopup->idAt(0)); + if (aItem != NULL) + { + mySignal = aItem->signal(); + } + } + else + theAction->addTo( myPopup ); +} + +/*! Sets myPopup item with theIndex as current*/ +void SUIT_ToolButton::SetItem(int theIndex) +{ + int anId = myPopup->idAt(theIndex); + if (anId != -1) + { + // Protection against unexpected null pointers returned + if ( myPopup->iconSet(anId) ) + setPixmap(myPopup->iconSet(anId)->pixmap()); + setTextLabel(myPopup->text(anId)); + QMenuItem* aItem = myPopup->findItem(anId); + if (aItem != NULL) + { + mySignal = aItem->signal(); + } + } +} + +/*!Public SLOT. + * On select action (icon and text set with id = \a theItemID) + */ +void SUIT_ToolButton::OnSelectAction(int theItemID) +{ + if (myChangeItemAfterClick) + { + // Protection against unexpected null pointers returned + if ( myPopup->iconSet(theItemID) ) + setPixmap(myPopup->iconSet(theItemID)->pixmap()); + setTextLabel(myPopup->text(theItemID)); + QMenuItem* aItem = myPopup->findItem(theItemID); + if (aItem != NULL) + { + mySignal = aItem->signal(); + } + } +} + + + +/*!On mouse release event.*/ +void SUIT_ToolButton::mouseReleaseEvent ( QMouseEvent * theEvent) +{ + QToolButton::mouseReleaseEvent(theEvent); + if (mySignal != NULL) + { + mySignal->activate(); + } +} + + diff --git a/src/SUIT/SUIT_ToolButton.h b/src/SUIT/SUIT_ToolButton.h new file mode 100755 index 000000000..6b8f51601 --- /dev/null +++ b/src/SUIT/SUIT_ToolButton.h @@ -0,0 +1,67 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SUIT_TOOLBUTTON_H +#define SUIT_TOOLBUTTON_H + +#include +#include + +#include "SUIT.h" + +/*! To draw down arrow on toolbutton.*/ +class SUIT_EXPORT SUIT_ToolButton : public QToolButton +{ + Q_OBJECT + +public: + /*! @name constructors*/ + //@{ + SUIT_ToolButton( QWidget *parent = 0, + const char *name = 0, + bool changeItemAfterClick = true ); + SUIT_ToolButton( const QPixmap & pm, const QString &textLabel, + const QString& grouptext, + QObject * receiver, const char* slot, + QToolBar * parent, const char* name = 0, + bool changeItemAfterClick = true ); + //@} + + void drawButton( QPainter * pQPainter); + + void AddAction(QAction* theAction); + + void SetItem(int theIndex); + +public slots: + void OnSelectAction(int theItemID); + +protected: + void mouseReleaseEvent (QMouseEvent * theEvent); + +private: + void initialize(); + + QPopupMenu* myPopup; + QSignal* mySignal; + bool myChangeItemAfterClick; + +}; + +#endif + diff --git a/src/SUIT/SUIT_Tools.cxx b/src/SUIT/SUIT_Tools.cxx new file mode 100755 index 000000000..3e728fe51 --- /dev/null +++ b/src/SUIT/SUIT_Tools.cxx @@ -0,0 +1,86 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "SUIT_Tools.h" + +#include + +#include +#include + +/*! + Traces output to log-file. + If log is NULL, 'Salome_trace' file is created in temp directory. + Log file is written in 'append' mode. +*/ +void SUIT_Tools::trace( const char* lpszLog, const char* lpszFormat, ... ) +{ + QString tmpPath = tmpDir(); + if ( !tmpPath.isEmpty() ) + tmpPath += QDir::separator(); + + tmpPath += QString( "Salome_trace" ); + + FILE* pStream; + pStream = fopen( lpszLog ? lpszLog : tmpPath.latin1(), "a" ); + if ( pStream ) + { + va_list argptr; + va_start( argptr, lpszFormat ); + fprintf( pStream, "- Trace %s [%d] : %s", __FILE__, __LINE__, lpszFormat ); + va_end( argptr ); + + fclose( pStream ); + } +} + +/*! + Creates a rect with TopLeft = ( min(x1,x2), min(y1,y2) ) + and BottomRight = ( TopLeft + (x2-x1)(y2-y1) ) +*/ +QRect SUIT_Tools::makeRect( const int x1, const int y1, const int x2, const int y2 ) +{ + return QRect( QMIN( x1, x2 ), QMIN( y1, y2 ), QABS( x2 - x1 ), QABS( y2 - y1 ) ); +} + +/*! + Creates font from string description +*/ +QFont SUIT_Tools::stringToFont( const QString& fontDescription ) +{ + QFont font; + if ( fontDescription.stripWhiteSpace().isEmpty() || !font.fromString( fontDescription ) ) + font = QFont( "Courier", 11 ); + return font; +} + +/*! + Creates font's string description +*/ +QString SUIT_Tools::fontToString( const QFont& font ) +{ + return font.toString(); +} + +/*! + Center widget 'src' relative to widget 'ref'. +*/ +void SUIT_Tools::centerWidget( QWidget* src, const QWidget* ref ) +{ + SUIT_Tools::alignWidget( src, ref, Qt::AlignCenter ); +} diff --git a/src/SUIT/SUIT_Tools.h b/src/SUIT/SUIT_Tools.h new file mode 100755 index 000000000..07d8ff059 --- /dev/null +++ b/src/SUIT/SUIT_Tools.h @@ -0,0 +1,42 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SUIT_TOOLS_H +#define SUIT_TOOLS_H + +#include "SUIT.h" + +#include + +#include +#include +#include + +class SUIT_EXPORT SUIT_Tools : public Qtx +{ +public: + static void trace( const char* pLog, const char* szFormat, ... );//!< Traces output to log-file. + static QRect makeRect( const int x1, const int y1, const int x2, const int y2 ); + + static QString fontToString( const QFont& font ); + static QFont stringToFont( const QString& fontDescription ); + + static void centerWidget( QWidget* src, const QWidget* ref ); +}; + +#endif diff --git a/src/SUIT/SUIT_ViewManager.cxx b/src/SUIT/SUIT_ViewManager.cxx new file mode 100755 index 000000000..69288994b --- /dev/null +++ b/src/SUIT/SUIT_ViewManager.cxx @@ -0,0 +1,269 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "SUIT_ViewManager.h" + +#include "SUIT_Desktop.h" +#include "SUIT_ViewModel.h" +#include "SUIT_Study.h" + +#include +#include + +#ifdef WNT +#include +#endif + +/*!\class SUIT_ViewManager. + * Class provide manipulation with view windows. + */ + +/*!Constructor.*/ +SUIT_ViewManager::SUIT_ViewManager( SUIT_Study* theStudy, + SUIT_Desktop* theDesktop, + SUIT_ViewModel* theViewModel ) +: QObject( 0 ), +myDesktop( theDesktop ), +myTitle( "Default viewer" ), +myStudy( NULL ) +{ + myViewModel = 0; + myActiveView = 0; + setViewModel(theViewModel); + connect(theDesktop, SIGNAL(windowActivated(SUIT_ViewWindow*)), + this, SLOT(onWindowActivated(SUIT_ViewWindow*))); + + myStudy = theStudy; + if( myStudy ) + connect( myStudy, SIGNAL( destroyed() ), this, SLOT( onDeleteStudy() ) ); +} + +/*!Destructor.*/ +SUIT_ViewManager::~SUIT_ViewManager() +{ + if ( myViewModel ) + { + myViewModel->setViewManager( 0 ); + delete myViewModel; + } +} + +/*!Sets view model \a theViewModel to view manager.*/ +void SUIT_ViewManager::setViewModel(SUIT_ViewModel* theViewModel) +{ + if (myViewModel && myViewModel != theViewModel) { + myViewModel->setViewManager(0); + delete myViewModel; + } + myViewModel = theViewModel; + if (myViewModel) + myViewModel->setViewManager(this); +} + +/*!Sets view name for view window \a theView.*/ +void SUIT_ViewManager::setViewName(SUIT_ViewWindow* theView) +{ + int aPos = myViews.find(theView); + theView->setCaption(myTitle + QString(":%1").arg(aPos+1)); +} + +/*! Creates View, adds it into list of views and returns just created view window*/ +SUIT_ViewWindow* SUIT_ViewManager::createViewWindow() +{ + SUIT_ViewWindow* aView = myViewModel->createView(myDesktop); + + if ( !insertView( aView ) ){ + delete aView; + return 0; + } + + setViewName( aView ); + //myDesktop->addViewWindow( aView ); + //it is done automatically during creation of view + + aView->setViewManager(this); + + emit viewCreated(aView); + + // Special treatment for the case when is the first one in this view manager + // -> call onWindowActivated() directly, because somebody may always want + // to use getActiveView() + if ( !myActiveView ) + onWindowActivated( aView ); + + return aView; +} + +/*!Create view window.*/ +void SUIT_ViewManager::createView() +{ + createViewWindow(); +} + +/*!Insert view window to view manager. + *\retval false - if something wrong, else true. + */ +bool SUIT_ViewManager::insertView(SUIT_ViewWindow* theView) +{ + unsigned int aSize = myViews.size(); + unsigned int aNbItems = myViews.count()+1; + if (aNbItems > aSize) { + if (!myViews.resize(aNbItems)) { + QMessageBox::critical(myDesktop, tr("Critical error"), tr("There is no memory for the new view!!!")); + return false; + } + aSize = myViews.size(); + } + + connect(theView, SIGNAL(closing(SUIT_ViewWindow*)), + this, SLOT(onDeleteView(SUIT_ViewWindow*))); + + connect(theView, SIGNAL(mousePressed(SUIT_ViewWindow*, QMouseEvent*)), + this, SLOT(onMousePressed(SUIT_ViewWindow*, QMouseEvent*))); + + connect(theView, SIGNAL(mouseReleased(SUIT_ViewWindow*, QMouseEvent*)), + this, SIGNAL(mouseRelease(SUIT_ViewWindow*, QMouseEvent*))); + + connect(theView, SIGNAL(mouseDoubleClicked(SUIT_ViewWindow*, QMouseEvent*)), + this, SIGNAL(mouseDoubleClick(SUIT_ViewWindow*, QMouseEvent*))); + + connect(theView, SIGNAL(mouseMoving(SUIT_ViewWindow*, QMouseEvent*)), + this, SIGNAL(mouseMove(SUIT_ViewWindow*, QMouseEvent*))); + + connect(theView, SIGNAL(wheeling(SUIT_ViewWindow*, QWheelEvent*)), + this, SIGNAL(wheel(SUIT_ViewWindow*, QWheelEvent*))); + + connect(theView, SIGNAL(keyPressed(SUIT_ViewWindow*, QKeyEvent*)), + this, SIGNAL(keyPress(SUIT_ViewWindow*, QKeyEvent*))); + + connect(theView, SIGNAL(keyReleased(SUIT_ViewWindow*, QKeyEvent*)), + this, SIGNAL(keyRelease(SUIT_ViewWindow*, QKeyEvent*))); + + connect(theView, SIGNAL(contextMenuRequested( QContextMenuEvent * )), + this, SLOT (onContextMenuRequested( QContextMenuEvent * ))); + + for (uint i = 0; i < aSize; i++) { + if (myViews[i]==0) { + myViews.insert(i, theView); + return true; + } + } + return false; +} + +/*!Emit delete view. Remove view window \a theView from view manager. +*/ +void SUIT_ViewManager::onDeleteView(SUIT_ViewWindow* theView) +{ + emit deleteView(theView); + removeView(theView); +} + +/*!Remove view window \a theView from view manager. + *And close the last view, if it has \a theView. +*/ +void SUIT_ViewManager::removeView(SUIT_ViewWindow* theView) +{ + theView->disconnect(this); + myViews.remove(myViews.find(theView)); + if (myActiveView == theView) + myActiveView = 0; + int aNumItems = myViews.count(); + if (aNumItems == 0) + emit lastViewClosed(this); +} + +/*! + Show or hide all views (view windows) +*/ +void SUIT_ViewManager::setShown( const bool on ) +{ + for ( uint i = 0; i < myViews.count(); i++ ) + myViews.at( i )->setShown( on ); +} + +/*!Emit on \a theEvent mouse pressed in \a theView.*/ +void SUIT_ViewManager::onMousePressed(SUIT_ViewWindow* theView, QMouseEvent* theEvent) +{ + emit mousePress(theView, theEvent); +} + +/*!Emit activated for view \a view. +*/ +void SUIT_ViewManager::onWindowActivated(SUIT_ViewWindow* view) +{ + if (view) { + unsigned int aSize = myViews.size(); + for (uint i = 0; i < aSize; i++) { + if (myViews[i] && myViews[i] == view) { + myActiveView = view; + emit activated( this ); + return; + } + } + } +} + +/*!Close all views. +*/ +void SUIT_ViewManager::closeAllViews() +{ + unsigned int aSize = myViews.size(); + for (uint i = 0; i < aSize; i++) { + if (myViews[i]) + myViews[i]->close(); + } +} + +/*! + *\retval QString - type of view model. + */ +QString SUIT_ViewManager::getType() const +{ + return (!myViewModel)? "": myViewModel->getType(); +} + +/*! + *\retval SUIT_Study* - current study. + */ +SUIT_Study* SUIT_ViewManager::study() const +{ + return myStudy; +} + +/*! + * Sets stydy to NULL. + */ +void SUIT_ViewManager::onDeleteStudy() +{ + myStudy = NULL; +} + +void SUIT_ViewManager::onContextMenuRequested( QContextMenuEvent* e ) +{ + /*! invoke method of SUIT_PopupClient, which notifies about popup*/ + contextMenuRequest( e ); +} + +/*!Context menu popup for \a popup.*/ +void SUIT_ViewManager::contextMenuPopup( QPopupMenu* popup ) +{ + SUIT_ViewModel* vm = getViewModel(); + if ( vm ) + vm->contextMenuPopup( popup ); +} diff --git a/src/SUIT/SUIT_ViewManager.h b/src/SUIT/SUIT_ViewManager.h new file mode 100755 index 000000000..e0ca57fb2 --- /dev/null +++ b/src/SUIT/SUIT_ViewManager.h @@ -0,0 +1,121 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SUIT_VIEWMANAGER_H +#define SUIT_VIEWMANAGER_H + +#include "SUIT.h" +#include "SUIT_ViewWindow.h" +#include "SUIT_PopupClient.h" + +#include +#include + +class SUIT_Study; +class SUIT_Desktop; +class SUIT_ViewModel; + +class QPopupMenu; + +#ifdef WIN32 +#pragma warning( disable:4251 ) +#endif + +class SUIT_EXPORT SUIT_ViewManager : public QObject, public SUIT_PopupClient +{ + Q_OBJECT +public: + SUIT_ViewManager( SUIT_Study*, + SUIT_Desktop*, + SUIT_ViewModel* = 0 ); + virtual ~SUIT_ViewManager(); + + virtual QString popupClientType() const { return getType(); } + virtual void contextMenuPopup( QPopupMenu* ); + + void setViewModel(SUIT_ViewModel* theViewModel); + SUIT_ViewModel* getViewModel() { return myViewModel; } + + SUIT_Study* study() const; + + QString getType() const; + SUIT_ViewWindow* getActiveView() { return myActiveView; } + + int getViewsCount() { return myViews.count(); } + QPtrVector getViews() { return myViews; } + + QString getTitle() const { return myTitle;} + void setTitle(QString theTitle) { myTitle = theTitle; } + + SUIT_ViewWindow* createViewWindow(); + + virtual void setShown( const bool ); + +public slots: + void createView(); + void closeAllViews(); + +signals: + void lastViewClosed(SUIT_ViewManager*); + void deleteView(SUIT_ViewWindow*); + void viewCreated(SUIT_ViewWindow*); + void mousePress(SUIT_ViewWindow*, QMouseEvent*); + void mouseRelease(SUIT_ViewWindow*, QMouseEvent*); + void mouseDoubleClick(SUIT_ViewWindow*, QMouseEvent*); + void mouseMove(SUIT_ViewWindow*, QMouseEvent*); + void wheel(SUIT_ViewWindow*, QWheelEvent*); + void keyPress(SUIT_ViewWindow*, QKeyEvent*); + void keyRelease(SUIT_ViewWindow*, QKeyEvent*); + void activated(SUIT_ViewManager*); + +protected slots: + void onWindowActivated(SUIT_ViewWindow*); + void onDeleteView(SUIT_ViewWindow* theView); + void onMousePressed(SUIT_ViewWindow* theView, QMouseEvent* theEvent); + void onDeleteStudy(); + +private slots: + void onContextMenuRequested( QContextMenuEvent* e ); + +protected: + /*! Inserts the View into internal Views Vector.\n + * Returns true if view has been added successfully + */ + virtual bool insertView(SUIT_ViewWindow* theView); + + /*! Removes the View from internal Views Vector.*/ + virtual void removeView(SUIT_ViewWindow* theView); + + /*! Used to set unique name for the view.*/ + virtual void setViewName(SUIT_ViewWindow* theView); + +protected: + SUIT_Desktop* myDesktop; + SUIT_ViewModel* myViewModel; + QPtrVector myViews; + SUIT_ViewWindow* myActiveView; + + QString myTitle; + SUIT_Study* myStudy; +}; + +#ifdef WIN32 +#pragma warning( default:4251 ) +#endif + +#endif diff --git a/src/SUIT/SUIT_ViewModel.cxx b/src/SUIT/SUIT_ViewModel.cxx new file mode 100755 index 000000000..38a9aac1e --- /dev/null +++ b/src/SUIT/SUIT_ViewModel.cxx @@ -0,0 +1,86 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +// SUIT_ViewModel.cxx: implementation of the SUIT_ViewModel class. +// +////////////////////////////////////////////////////////////////////// + +#include "SUIT_ViewModel.h" + +SUIT_ViewModel::StatesMap SUIT_ViewModel::myStateMap; +SUIT_ViewModel::ButtonsMap SUIT_ViewModel::myButtonMap; + +static bool isInitialized = false; + +/*!Constructor.*/ +SUIT_ViewModel::SUIT_ViewModel() +{ + if (!isInitialized) { + isInitialized = true; + + SUIT_ViewModel::myStateMap[ZOOM] = Qt::ControlButton; + SUIT_ViewModel::myButtonMap[ZOOM] = Qt::LeftButton; + + SUIT_ViewModel::myStateMap[PAN] = Qt::ControlButton; + SUIT_ViewModel::myButtonMap[PAN] = Qt::MidButton; + + SUIT_ViewModel::myStateMap[ROTATE] = Qt::ControlButton; + SUIT_ViewModel::myButtonMap[ROTATE] = Qt::RightButton; + + SUIT_ViewModel::myStateMap[FIT_AREA] = Qt::ControlButton; + SUIT_ViewModel::myButtonMap[FIT_AREA] = Qt::RightButton; + } + myViewManager = 0; +} + +/*!Destructor..*/ +SUIT_ViewModel::~SUIT_ViewModel() +{ +} + +/*!Create new instance of view window on desktop \a theDesktop. + *\retval SUIT_ViewWindow* - created view window pointer. + */ +SUIT_ViewWindow* SUIT_ViewModel::createView(SUIT_Desktop* theDesktop) +{ + return new SUIT_ViewWindow(theDesktop); +} + +/*! Sets hot button + *\param theOper - hot operation + *\param theState - adding state to state map operations. + *\param theButton - adding state to button map operations. + */ +void SUIT_ViewModel::setHotButton(HotOperation theOper, Qt::ButtonState theState, + Qt::ButtonState theButton) +{ + myStateMap[theOper] = theState; + myButtonMap[theOper] = theButton; +} + +/*! Gets hot button for operation \a theOper. + *\param theOper - input hot operation + *\param theState - output state from state map operations. + *\param theButton - output state from button map operations. +*/ +void SUIT_ViewModel::getHotButton(HotOperation theOper, Qt::ButtonState& theState, + Qt::ButtonState& theButton) +{ + theState = myStateMap[theOper]; + theButton = myButtonMap[theOper]; +} diff --git a/src/SUIT/SUIT_ViewModel.h b/src/SUIT/SUIT_ViewModel.h new file mode 100755 index 000000000..b99c4025c --- /dev/null +++ b/src/SUIT/SUIT_ViewModel.h @@ -0,0 +1,84 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SUIT_VIEWMODEL_H +#define SUIT_VIEWMODEL_H + +#include "SUIT.h" +#include "SUIT_Desktop.h" +#include "SUIT_ViewWindow.h" +#include "SUIT_ViewManager.h" + +#include +#include + +#ifdef WIN32 +#pragma warning( disable:4251 ) +#endif +/*! + * This object manages the definition and behaviour of a View Window. \n + * In case of definition of this object in an external lib that lib must \n + * have an exported function "createViewModel" which returns newly created \n + * instance of SUIT_ViewModel. + */ +class SUIT_EXPORT SUIT_ViewModel : public QObject +{ + Q_OBJECT +public: + enum HotOperation { PAN, ZOOM, ROTATE, FIT_AREA }; + + typedef QMap StatesMap; + typedef QMap ButtonsMap; + + SUIT_ViewModel(); + virtual ~SUIT_ViewModel(); + + virtual SUIT_ViewWindow* createView(SUIT_Desktop* theDesktop); + + virtual void setViewManager(SUIT_ViewManager* theViewManager) { myViewManager = theViewManager; } + SUIT_ViewManager* getViewManager() const { return myViewManager; } + + virtual QString getType() const { return "SUIT_ViewModel"; } + + virtual void contextMenuPopup(QPopupMenu*) {} + + static void setHotButton(HotOperation theOper, Qt::ButtonState theState, + Qt::ButtonState theButton); + static void getHotButton(HotOperation theOper, Qt::ButtonState& theState, + Qt::ButtonState& theButton); + +protected: + SUIT_ViewManager* myViewManager; + +public: + static StatesMap myStateMap; + static ButtonsMap myButtonMap; +}; + +#ifdef WIN32 +#pragma warning( default:4251 ) +#endif + +extern "C" +{ + typedef SUIT_ViewModel* (*VIEWMODEL_CREATE_FUNC)(); +} + +#define VIEWMODEL_CREATE_NAME "createViewModel" + +#endif diff --git a/src/SUITApp/SUITApp_Application.cxx b/src/SUITApp/SUITApp_Application.cxx new file mode 100644 index 000000000..744d84acc --- /dev/null +++ b/src/SUITApp/SUITApp_Application.cxx @@ -0,0 +1,71 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "SUITApp_Application.h" + +#include "SUIT_MessageBox.h" +#include "SUIT_ExceptionHandler.h" + +#include +#include + +#ifdef WIN32 +#include +#include +#else +#include +#endif + +SUITApp_Application::SUITApp_Application( int& argc, char** argv, SUIT_ExceptionHandler* hand ) +: QApplication( argc, argv ), +myExceptHandler( hand ) +{ + QString path = QFileInfo( argv[0] ).dirPath() + QDir::separator() + "../../resources"; + path = QDir::convertSeparators( QDir( path ).canonicalPath() ); + + QTranslator* strTbl = new QTranslator( 0 ); + if ( strTbl->load( "SUITApp_msg_en.po", path ) ) + installTranslator( strTbl ); + else + delete strTbl; +} + +SUITApp_Application::SUITApp_Application( int& argc, char** argv, Type type, SUIT_ExceptionHandler* hand ) +: QApplication( argc, argv, type ), +myExceptHandler( hand ) +{ + QTranslator* strTbl = new QTranslator( 0 ); + strTbl->load( "resources\\SUITApp_msg_en.po" ); + installTranslator( strTbl ); +} + +bool SUITApp_Application::notify( QObject* receiver, QEvent* e ) +{ + return myExceptHandler ? myExceptHandler->handle( receiver, e ) : + QApplication::notify( receiver, e ); +} + +void SUITApp_Application::setHandler( SUIT_ExceptionHandler* hand ) +{ + myExceptHandler = hand; +} + +SUIT_ExceptionHandler* SUITApp_Application::handler() const +{ + return myExceptHandler; +} diff --git a/src/SUITApp/SUITApp_Application.h b/src/SUITApp/SUITApp_Application.h new file mode 100644 index 000000000..4fe9acebd --- /dev/null +++ b/src/SUITApp/SUITApp_Application.h @@ -0,0 +1,43 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SUITAPP_APPLICATION_H +#define SUITAPP_APPLICATION_H + +#include + +class SUIT_ExceptionHandler; + +class SUITApp_Application : public QApplication +{ + Q_OBJECT + +public: + SUITApp_Application( int& argc, char** argv, SUIT_ExceptionHandler* = 0 ); + SUITApp_Application( int& argc, char** argv, Type type, SUIT_ExceptionHandler* = 0 ); + + virtual bool notify( QObject* receiver, QEvent* e ); + + SUIT_ExceptionHandler* handler() const; + void setHandler( SUIT_ExceptionHandler* ); + +private: + SUIT_ExceptionHandler* myExceptHandler; +}; + +#endif diff --git a/src/SUPERVGraph/SUPERVGraph_ViewManager.cxx b/src/SUPERVGraph/SUPERVGraph_ViewManager.cxx new file mode 100644 index 000000000..9cf508b31 --- /dev/null +++ b/src/SUPERVGraph/SUPERVGraph_ViewManager.cxx @@ -0,0 +1,45 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "SUPERVGraph_ViewManager.h" + +int SUPERVGraph_ViewManager::myMaxId = 0; + +SUPERVGraph_ViewManager::SUPERVGraph_ViewManager( SUIT_Study* theStudy, + SUIT_Desktop* theDesktop, + SUIT_ViewModel* theViewModel ) + : SUIT_ViewManager( theStudy, theDesktop, theViewModel ) +{ + myId = ++myMaxId; +} + +SUPERVGraph_ViewManager::~SUPERVGraph_ViewManager() +{ +} + +void SUPERVGraph_ViewManager::setViewName(SUIT_ViewWindow* theView) +{ + int aPos = myViews.find(theView); + theView->setCaption( QString( "SUPERVISION scene:%1 - viewer:%2" ).arg( myId ).arg(aPos+1)); +} + +void SUPERVGraph_ViewManager::contextMenuPopup( QPopupMenu* thePopup) +{ + SUIT_ViewManager::contextMenuPopup( thePopup ); + // to be implemented +} diff --git a/src/SUPERVGraph/SUPERVGraph_ViewManager.h b/src/SUPERVGraph/SUPERVGraph_ViewManager.h new file mode 100644 index 000000000..f35557960 --- /dev/null +++ b/src/SUPERVGraph/SUPERVGraph_ViewManager.h @@ -0,0 +1,48 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SUPERVGRAPH_VIEWMANAGER_H +#define SUPERVGRAPH_VIEWMANAGER_H + +#include "SUPERVGraph.h" + +#include "SUPERVGraph_ViewModel.h" +#include "SUIT_ViewManager.h" + +class SUIT_Desktop; + +class SUPERVGRAPH_EXPORT SUPERVGraph_ViewManager : public SUIT_ViewManager +{ + Q_OBJECT + +public: + SUPERVGraph_ViewManager( SUIT_Study* theStudy, SUIT_Desktop* theDesktop, SUIT_ViewModel* theViewModel = 0 ); + ~SUPERVGraph_ViewManager(); + + virtual void contextMenuPopup( QPopupMenu* thePopup ); + +protected: + void setViewName(SUIT_ViewWindow* theView); + +private: + static int myMaxId; + int myId; + +}; + +#endif diff --git a/src/SUPERVGraph/SUPERVGraph_ViewModel.cxx b/src/SUPERVGraph/SUPERVGraph_ViewModel.cxx new file mode 100644 index 000000000..c6fe5f9ea --- /dev/null +++ b/src/SUPERVGraph/SUPERVGraph_ViewModel.cxx @@ -0,0 +1,37 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "SUPERVGraph_ViewModel.h" +#include "SUPERVGraph_ViewFrame.h" +#include "SUIT_Desktop.h" +#include "SUIT_ViewWindow.h" + +SUPERVGraph_Viewer::SUPERVGraph_Viewer() +:SUIT_ViewModel() +{ +} + +SUPERVGraph_Viewer::~SUPERVGraph_Viewer() +{ +} + +SUIT_ViewWindow* SUPERVGraph_Viewer::createView(SUIT_Desktop* theDesktop) +{ + SUPERVGraph_ViewFrame* aRes = new SUPERVGraph_ViewFrame( theDesktop ); + return aRes; +} diff --git a/src/SUPERVGraph/SUPERVGraph_ViewModel.h b/src/SUPERVGraph/SUPERVGraph_ViewModel.h new file mode 100644 index 000000000..695f1a8fc --- /dev/null +++ b/src/SUPERVGraph/SUPERVGraph_ViewModel.h @@ -0,0 +1,40 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SUPERVGRAPH_VIEWMODEL_H +#define SUPERVGRAPH_VIEWMODEL_H + +#include "SUPERVGraph.h" + +#include "SUIT_ViewModel.h" + +class SUPERVGRAPH_EXPORT SUPERVGraph_Viewer: public SUIT_ViewModel +{ + Q_OBJECT + +public: + static QString Type() { return "SUPERVGraphViewer"; } + + SUPERVGraph_Viewer(); + virtual ~SUPERVGraph_Viewer(); + + virtual SUIT_ViewWindow* createView(SUIT_Desktop* theDesktop); + +}; + +#endif diff --git a/src/SVTK/SVTK.h b/src/SVTK/SVTK.h new file mode 100755 index 000000000..d4d8cf530 --- /dev/null +++ b/src/SVTK/SVTK.h @@ -0,0 +1,32 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifdef WNT +#ifdef SVTK_EXPORTS +#define SVTK_EXPORT __declspec(dllexport) +#else +#define SVTK_EXPORT __declspec(dllimport) +#endif +#else +#define SVTK_EXPORT +#endif + +#if defined WNT +#pragma warning ( disable: 4251 ) +#pragma warning ( disable: 4786 ) +#endif diff --git a/src/SVTK/SVTK_Trihedron.cxx b/src/SVTK/SVTK_Trihedron.cxx new file mode 100644 index 000000000..ea8783a07 --- /dev/null +++ b/src/SVTK/SVTK_Trihedron.cxx @@ -0,0 +1,50 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "SVTK_Trihedron.h" +#include "SALOME_Actor.h" + +#include +#include +#include + +//**************************************************************** +vtkStandardNewMacro(SVTK_Trihedron); + +//**************************************************************** +SVTK_Trihedron +::SVTK_Trihedron() +{ +} + +//**************************************************************** +int +SVTK_Trihedron +::GetVisibleActorCount(vtkRenderer* theRenderer) +{ + vtkActorCollection* aCollection = theRenderer->GetActors(); + aCollection->InitTraversal(); + int aCount = 0; + while(vtkActor* aProp = aCollection->GetNextActor()) { + if(aProp->GetVisibility()) + if(SALOME_Actor* anActor = SALOME_Actor::SafeDownCast(aProp)) + if(!anActor->IsInfinitive()) + aCount++; + } + return aCount; +} diff --git a/src/SVTK/SVTK_Trihedron.h b/src/SVTK/SVTK_Trihedron.h new file mode 100644 index 000000000..69a80303e --- /dev/null +++ b/src/SVTK/SVTK_Trihedron.h @@ -0,0 +1,41 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SVTK_TRIHEDRON_H +#define SVTK_TRIHEDRON_H + +#include "SVTK.h" + +#include "VTKViewer_Trihedron.h" + +class SVTK_EXPORT SVTK_Trihedron : public VTKViewer_Trihedron +{ +protected: + SVTK_Trihedron(); + SVTK_Trihedron(const SVTK_Trihedron&); // Not implemented + void operator = (const SVTK_Trihedron&); // Not implemented + +public: + vtkTypeMacro(SVTK_Trihedron,VTKViewer_Trihedron); + static SVTK_Trihedron *New(); + + virtual int GetVisibleActorCount(vtkRenderer* theRenderer); +}; + + +#endif diff --git a/src/SalomeApp/SalomeApp_CheckFileDlg.cxx b/src/SalomeApp/SalomeApp_CheckFileDlg.cxx new file mode 100644 index 000000000..370526ff8 --- /dev/null +++ b/src/SalomeApp/SalomeApp_CheckFileDlg.cxx @@ -0,0 +1,58 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "SalomeApp_CheckFileDlg.h" + +#include +#include +#include + +/*! +Constructor +*/ +SalomeApp_CheckFileDlg::SalomeApp_CheckFileDlg( QWidget* parent, bool open, const QString& theCheckBoxName, bool showQuickDir, bool modal) : +SUIT_FileDlg( parent, open, showQuickDir, modal ) +{ + myCheckBox = new QCheckBox( theCheckBoxName, this ); + QLabel* label = new QLabel("", this); + QPushButton* pb = new QPushButton(this); + addWidgets( label, myCheckBox, pb ); + pb->hide(); +} + +/*! +Destructor +*/ +SalomeApp_CheckFileDlg::~SalomeApp_CheckFileDlg() +{ + +} + +/*!Sets checked.*/ +void SalomeApp_CheckFileDlg::SetChecked( bool check ) +{ + myCheckBox->setChecked(check); +} + +/*!Is checked? + *\retval boolean - true, check box is checked, else false. + */ +bool SalomeApp_CheckFileDlg::IsChecked() const +{ + return myCheckBox->isChecked(); +} diff --git a/src/SalomeApp/SalomeApp_CheckFileDlg.h b/src/SalomeApp/SalomeApp_CheckFileDlg.h new file mode 100644 index 000000000..98989a70d --- /dev/null +++ b/src/SalomeApp/SalomeApp_CheckFileDlg.h @@ -0,0 +1,44 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SALOMEAPP_CHECKFILEDIALOG_H +#define SALOMEAPP_CHECKFILEDIALOG_H + +#include + +#include + +class QCheckBox; + +class SALOMEAPP_EXPORT SalomeApp_CheckFileDlg : public SUIT_FileDlg +{ + Q_OBJECT + +public: + SalomeApp_CheckFileDlg( QWidget*, bool open, const QString& theCheckBoxName, bool showQuickDir = true, bool modal = true ); + virtual ~SalomeApp_CheckFileDlg(); + +public: + void SetChecked( bool check ); + bool IsChecked() const; + +protected: + QCheckBox* myCheckBox; +}; + +#endif diff --git a/src/SalomeApp/SalomeApp_Displayer.cxx b/src/SalomeApp/SalomeApp_Displayer.cxx new file mode 100644 index 000000000..6e2caeda2 --- /dev/null +++ b/src/SalomeApp/SalomeApp_Displayer.cxx @@ -0,0 +1,163 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// + +#include "SalomeApp_Displayer.h" +#include "SalomeApp_Application.h" + +#include + +#include +#include +#include +#include +#include + +#include + +SalomeApp_Displayer::SalomeApp_Displayer() +{ +} + +SalomeApp_Displayer::~SalomeApp_Displayer() +{ +} + +void SalomeApp_Displayer::Display( const QString& entry, const bool updateViewer, SALOME_View* theViewFrame ) +{ + SALOME_View* vf = theViewFrame ? theViewFrame : GetActiveView(); + if ( vf ) + { + SALOME_Prs* prs = buildPresentation( entry, vf ); + + if ( prs ) + { + vf->BeforeDisplay( this ); + vf->Display( prs ); + vf->AfterDisplay( this ); + + if ( updateViewer ) + vf->Repaint(); + + delete prs; // delete presentation because displayer is its owner + } + } +} + +void SalomeApp_Displayer::Redisplay( const QString& entry, const bool updateViewer ) +{ + // Remove the object permanently ( == true) + SUIT_Session* ses = SUIT_Session::session(); + SUIT_Application* app = ses->activeApplication(); + if ( app ) + { + SUIT_Desktop* desk = app->desktop(); + QPtrList wnds = desk->windows(); + SUIT_ViewWindow* wnd; + for ( wnd = wnds.first(); wnd; wnd = wnds.next() ) + { + SUIT_ViewManager* vman = wnd->getViewManager(); + if( !vman ) + continue; + + SUIT_ViewModel* vmodel = vman->getViewModel(); + if( !vmodel ) + continue; + + SALOME_View* view = dynamic_cast(vmodel); + if( view && ( IsDisplayed( entry, view ) || view == GetActiveView() ) ) + { + Erase( entry, true, false, view ); + Display( entry, updateViewer, view ); + } + } + } +} + +void SalomeApp_Displayer::Erase( const QString& entry, const bool forced, + const bool updateViewer, SALOME_View* theViewFrame ) +{ + SALOME_View* vf = theViewFrame ? theViewFrame : GetActiveView(); + + if ( vf ) { + SALOME_Prs* prs = vf->CreatePrs( entry.latin1() ); + if ( prs ) { + vf->Erase( prs, forced ); + if ( updateViewer ) + vf->Repaint(); + delete prs; // delete presentation because displayer is its owner + } + } +} + +void SalomeApp_Displayer::EraseAll( const bool forced, const bool updateViewer, SALOME_View* theViewFrame ) const +{ + SALOME_View* vf = theViewFrame ? theViewFrame : GetActiveView(); + + if ( vf ) { + vf->EraseAll( forced ); + if ( updateViewer ) + vf->Repaint(); + } +} + +bool SalomeApp_Displayer::IsDisplayed( const QString& entry, SALOME_View* theViewFrame ) const +{ + SALOME_View* vf = theViewFrame ? theViewFrame : GetActiveView(); + if( vf ) + { + Handle( SALOME_InteractiveObject ) temp = new SALOME_InteractiveObject(); + temp->setEntry( entry.latin1() ); + return vf->isVisible( temp ); + } + else + return false; +} + +void SalomeApp_Displayer::UpdateViewer() const +{ + SALOME_View* vf = GetActiveView(); + if ( vf ) + vf->Repaint(); +} + +SALOME_Prs* SalomeApp_Displayer::buildPresentation( const QString& entry, SALOME_View* theViewFrame ) +{ + SALOME_Prs* prs = 0; + + SALOME_View* vf = theViewFrame ? theViewFrame : GetActiveView(); + + if ( vf ) + prs = vf->CreatePrs( entry.latin1() ); + + return prs; +} + +SALOME_View* SalomeApp_Displayer::GetActiveView() +{ + SUIT_Session* session = SUIT_Session::session(); + if ( SUIT_Application* app = session->activeApplication() ) { + if ( SalomeApp_Application* sApp = dynamic_cast( app ) ) { + if( SUIT_ViewManager* vman = sApp->activeViewManager() ) { + if ( SUIT_ViewModel* vmod = vman->getViewModel() ) + return dynamic_cast( vmod ); + } + } + } + return 0; +} diff --git a/src/SalomeApp/SalomeApp_Displayer.h b/src/SalomeApp/SalomeApp_Displayer.h new file mode 100644 index 000000000..25ba911e2 --- /dev/null +++ b/src/SalomeApp/SalomeApp_Displayer.h @@ -0,0 +1,46 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// + +#ifndef SALOMEAPP_DISPLAYER_HEADER +#define SALOMEAPP_DISPLAYER_HEADER + +#include + +class QString; + +class SalomeApp_Displayer : public SALOME_Displayer +{ +public: + SalomeApp_Displayer(); + virtual ~SalomeApp_Displayer(); + + void Display( const QString&, const bool = true, SALOME_View* = 0 ); + void Redisplay( const QString&, const bool = true ); + void Erase( const QString&, const bool forced = false, const bool updateViewer = true, SALOME_View* = 0 ); + void EraseAll( const bool forced = false, const bool updateViewer = true, SALOME_View* = 0 ) const; + bool IsDisplayed( const QString&, SALOME_View* = 0 ) const; + void UpdateViewer() const; + + static SALOME_View* GetActiveView(); + +protected: + virtual SALOME_Prs* buildPresentation( const QString&, SALOME_View* = 0 ); +}; + +#endif diff --git a/src/SalomeApp/SalomeApp_EventFilter.cxx b/src/SalomeApp/SalomeApp_EventFilter.cxx new file mode 100755 index 000000000..0db6f5fe3 --- /dev/null +++ b/src/SalomeApp/SalomeApp_EventFilter.cxx @@ -0,0 +1,78 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// + +#include "SalomeApp_EventFilter.h" +#include + +#include + +SalomeApp_EventFilter* SalomeApp_EventFilter::myFilter = NULL; + +/*!Constructor.*/ +SalomeApp_EventFilter::SalomeApp_EventFilter() +: QObject() +{ + /* VSR 13/01/03 : installing global event filter for the application */ + qApp->installEventFilter( this ); +} + +/*!Destructor.*/ +SalomeApp_EventFilter::~SalomeApp_EventFilter() +{ + qApp->removeEventFilter( this ); +} + +bool SalomeApp_EventFilter::eventFilter( QObject* o, QEvent* e ) +{ + if ( e->type() == SALOME_EVENT ) + { + SALOME_Event* aSE = (SALOME_Event*)((QCustomEvent*)e)->data(); + processEvent(aSE); + ((QCustomEvent*)e)->setData( 0 ); + return true; + } + return QObject::eventFilter( o, e ); +} + +/*!Process event.*/ +void SalomeApp_EventFilter::processEvent( SALOME_Event* theEvent ) +{ + if(theEvent){ + theEvent->Execute(); + // Signal the calling thread that the event has been processed + theEvent->processed(); + } +} + +/*!Create new instance of SalomeApp_EventFilter*/ +void SalomeApp_EventFilter::Init() +{ + if( myFilter==NULL ) + myFilter = new SalomeApp_EventFilter(); +} + +/*!Destroy filter.*/ +void SalomeApp_EventFilter::Destroy() +{ + if( myFilter ) + { + delete myFilter; + myFilter = NULL; + } +} diff --git a/src/SalomeApp/SalomeApp_EventFilter.h b/src/SalomeApp/SalomeApp_EventFilter.h new file mode 100755 index 000000000..1411a3f5e --- /dev/null +++ b/src/SalomeApp/SalomeApp_EventFilter.h @@ -0,0 +1,57 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SALOMEAPP_EVENTFILTER_H +#define SALOMEAPP_EVENTFILTER_H + +#include "SalomeApp.h" +#include + +#if defined WNT +#pragma warning( disable: 4251 ) +#endif + +class SALOME_Event; + +/*! + Class provide event filter. +*/ +class SALOMEAPP_EXPORT SalomeApp_EventFilter: public QObject +{ +public: + static void Init(); + static void Destroy(); + +protected: + SalomeApp_EventFilter(); + virtual ~SalomeApp_EventFilter(); + +private: + /*! global event filter for qapplication */ + virtual bool eventFilter( QObject* o, QEvent* e ); + void processEvent( SALOME_Event* ); + +private: + static SalomeApp_EventFilter* myFilter; +}; + +#if defined WNT +#pragma warning( default: 4251 ) +#endif + +#endif diff --git a/src/SalomeApp/SalomeApp_ExceptionHandler.cxx b/src/SalomeApp/SalomeApp_ExceptionHandler.cxx new file mode 100644 index 000000000..3791d4d98 --- /dev/null +++ b/src/SalomeApp/SalomeApp_ExceptionHandler.cxx @@ -0,0 +1,103 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "SalomeApp_ExceptionHandler.h" + +#include + +#include +#include + +#include +#include + +#include + +#include +#include +#include + + +/*!Constructor. Initialize by \a floatSignal.*/ +SalomeApp_ExceptionHandler::SalomeApp_ExceptionHandler( const bool floatSignal ) +: SUIT_ExceptionHandler() +{ + OSD::SetSignal( floatSignal ); +} + +/*!Try to call SUIT_ExceptionHandler::internalHandle(o, e), catch if failure.*/ +bool SalomeApp_ExceptionHandler::handleSignals( QObject* o, QEvent* e ) +{ + + CASCatch_CatchSignals aCatchSignals; + aCatchSignals.Activate(); + + + CASCatch_TRY { + SUIT_ExceptionHandler::internalHandle( o, e ); + } + CASCatch_CATCH(CASCatch_Failure) { + aCatchSignals.Deactivate(); + Handle(CASCatch_Failure) aFail = CASCatch_Failure::Caught(); + throw std::runtime_error( aFail->GetError() ); + } + + aCatchSignals.Deactivate(); + return true; +} + +#ifdef try +#undef try +#endif + +#ifdef catch +#undef catch +#endif + +/*!Try to call handleSignals( o, e ), catch and show error message.*/ +bool SalomeApp_ExceptionHandler::handle( QObject* o, QEvent* e ) +{ + bool res = false; + QString title( "Fatal error" ); + + try { + res = handleSignals( o, e ); + } + catch( std::exception& ex ) + { + showMessage( title, QString( ex.what() ) ); + } + catch( Standard_Failure& e ) + { + showMessage( title, QString( e.GetMessageString() ) ); + } +#ifndef WNT + catch(...) + { + showMessage( title, "Unknown Exception" ); + } +#endif + + return res; +} + +/*!Create new SUIT_ExceptionHandler*/ +extern "C" SALOMEAPP_EXPORT SUIT_ExceptionHandler* getExceptionHandler() +{ + return new SalomeApp_ExceptionHandler( true ); +} diff --git a/src/SalomeApp/SalomeApp_ExceptionHandler.h b/src/SalomeApp/SalomeApp_ExceptionHandler.h new file mode 100644 index 000000000..823c3e530 --- /dev/null +++ b/src/SalomeApp/SalomeApp_ExceptionHandler.h @@ -0,0 +1,36 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SALOMEAPP_EXCEPTIONHANDLER_H +#define SALOMEAPP_EXCEPTIONHANDLER_H + +#include "SalomeApp.h" + +#include + +class SALOMEAPP_EXPORT SalomeApp_ExceptionHandler : public SUIT_ExceptionHandler +{ +public: + SalomeApp_ExceptionHandler( const bool ); + virtual bool handle( QObject*, QEvent* ); + +protected: + virtual bool handleSignals( QObject*, QEvent* ); +}; + +#endif diff --git a/src/SalomeApp/SalomeApp_Filter.cxx b/src/SalomeApp/SalomeApp_Filter.cxx new file mode 100644 index 000000000..98f9a1a74 --- /dev/null +++ b/src/SalomeApp/SalomeApp_Filter.cxx @@ -0,0 +1,36 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "SalomeApp_Filter.h" + +/*!Constructor.Initialize by study.*/ +SalomeApp_Filter::SalomeApp_Filter( SalomeApp_Study* study ) +{ + myStudy = study; +} + +/*!Destructor. Do nothing.*/ +SalomeApp_Filter::~SalomeApp_Filter() +{ +} + +/*!Gets study.*/ +SalomeApp_Study* SalomeApp_Filter::getStudy() const +{ + return myStudy; +} diff --git a/src/SalomeApp/SalomeApp_Filter.h b/src/SalomeApp/SalomeApp_Filter.h new file mode 100644 index 000000000..e8afc8014 --- /dev/null +++ b/src/SalomeApp/SalomeApp_Filter.h @@ -0,0 +1,40 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SALOMEAPP_FILTER_H +#define SALOMEAPP_FILTER_H + +#include "SalomeApp.h" +#include "SUIT_SelectionFilter.h" + +class SalomeApp_Study; + +class SALOMEAPP_EXPORT SalomeApp_Filter: public SUIT_SelectionFilter +{ +public: + SalomeApp_Filter(SalomeApp_Study* study); + ~SalomeApp_Filter(); + +protected: + SalomeApp_Study* getStudy() const; + +private: + SalomeApp_Study* myStudy; +}; + +#endif diff --git a/src/SalomeApp/SalomeApp_Study.cxx b/src/SalomeApp/SalomeApp_Study.cxx new file mode 100644 index 000000000..3073e544e --- /dev/null +++ b/src/SalomeApp/SalomeApp_Study.cxx @@ -0,0 +1,630 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "SalomeApp_Study.h" + +#include "SalomeApp_Module.h" +#include "SalomeApp_DataModel.h" +#include "SalomeApp_DataObject.h" +#include "SalomeApp_Application.h" +#include "SalomeApp_Engine_i.hxx" + +#include "LightApp_RootObject.h" + +#include + +#include + +#include + +#include "utilities.h" +#include "string.h" +#include "vector.h" + +#include "SALOMEDS_Tool.hxx" + +#include +#include CORBA_SERVER_HEADER(SALOME_Exception) + +/*! + Constructor. +*/ +SalomeApp_Study::SalomeApp_Study( SUIT_Application* app ) +: LightApp_Study( app ) +{ +} + +/*! + Destructor. +*/ +SalomeApp_Study::~SalomeApp_Study() +{ +} + +/*! + Gets study id. +*/ +int SalomeApp_Study::id() const +{ + int id = -1; + if ( myStudyDS ) + id = studyDS()->StudyId(); + return id; +} + +/*! + Gets studyDS pointer. +*/ +_PTR(Study) SalomeApp_Study::studyDS() const +{ + return myStudyDS; +} + +/*! + Create document. +*/ +void SalomeApp_Study::createDocument() +{ + MESSAGE( "openDocument" ); + + // initialize myStudyDS, read HDF file + QString aName = newStudyName(); + _PTR(Study) study ( SalomeApp_Application::studyMgr()->NewStudy( aName.latin1() ) ); + if ( !study ) + return; + + setStudyDS( study ); + setStudyName( aName ); + + // create myRoot + setRoot( new LightApp_RootObject( this ) ); + + CAM_Study::createDocument(); + emit created( this ); +} + +//======================================================================= +// name : openDocument +/*! Purpose : Open document*/ +//======================================================================= +bool SalomeApp_Study::openDocument( const QString& theFileName ) +{ + MESSAGE( "openDocument" ); + + // initialize myStudyDS, read HDF file + _PTR(Study) study ( SalomeApp_Application::studyMgr()->Open( (char*) theFileName.latin1() ) ); + if ( !study ) + return false; + + setStudyDS( study ); + + setRoot( new LightApp_RootObject( this ) ); // create myRoot + + // update loaded data models: call open() and update() on them. + ModelList dm_s; + dataModels( dm_s ); + for ( ModelListIterator it( dm_s ); it.current(); ++it ) + openDataModel( studyName(), it.current() ); + + // this will build a SUIT_DataObject-s tree under myRoot member field + // passing "false" in order NOT to rebuild existing data models' trees - it was done in previous step + // but tree that corresponds to not-loaded data models will be updated any way. + ((SalomeApp_Application*)application())->updateObjectBrowser( false ); + + bool res = CAM_Study::openDocument( theFileName ); + + emit opened( this ); + study->IsSaved(true); + return res; +} + +//======================================================================= +// name : loadDocument +/*! Purpose : Connects GUI study to SALOMEDS one already loaded into StudyManager*/ +//======================================================================= +bool SalomeApp_Study::loadDocument( const QString& theStudyName ) +{ + MESSAGE( "loadDocument" ); + + // obtain myStudyDS from StudyManager + _PTR(Study) study ( SalomeApp_Application::studyMgr()->GetStudyByName( (char*) theStudyName.latin1() ) ); + if ( !study ) + return false; + + setStudyDS( study ); + + setRoot( new LightApp_RootObject( this ) ); // create myRoot + + //SRN: BugID IPAL9021, put there the same code as in a method openDocument + + // update loaded data models: call open() and update() on them. + ModelList dm_s; + dataModels( dm_s ); + + for ( ModelListIterator it( dm_s ); it.current(); ++it ) + openDataModel( studyName(), it.current() ); + + // this will build a SUIT_DataObject-s tree under myRoot member field + // passing "false" in order NOT to rebuild existing data models' trees - it was done in previous step + // but tree that corresponds to not-loaded data models will be updated any way. + ((SalomeApp_Application*)application())->updateObjectBrowser( false ); + + bool res = CAM_Study::openDocument( theStudyName ); + emit opened( this ); + + //SRN: BugID IPAL9021: End + + return res; +} + +//======================================================================= +// name : saveDocumentAs +/*! Purpose : Save document*/ +//======================================================================= +bool SalomeApp_Study::saveDocumentAs( const QString& theFileName ) +{ + ModelList list; dataModels( list ); + + SalomeApp_DataModel* aModel = (SalomeApp_DataModel*)list.first(); + QStringList listOfFiles; + for ( ; aModel; aModel = (SalomeApp_DataModel*)list.next() ) { + listOfFiles.clear(); + aModel->saveAs( theFileName, this, listOfFiles ); + if ( !listOfFiles.isEmpty() ) + saveModuleData(aModel->module()->name(), listOfFiles); + } + + // save SALOMEDS document + SUIT_ResourceMgr* resMgr = application()->resourceMgr(); + if( !resMgr ) + return false; + + bool isMultiFile = resMgr->booleanValue( "Study", "multi_file", false ), + isAscii = resMgr->booleanValue( "Study", "ascii_file", false ); + isAscii ? SalomeApp_Application::studyMgr()->SaveAsASCII( theFileName.latin1(), studyDS(), isMultiFile ) : + SalomeApp_Application::studyMgr()->SaveAs ( theFileName.latin1(), studyDS(), isMultiFile ); + + bool res = CAM_Study::saveDocumentAs( theFileName ); //SRN: BugID IPAL9377, removed usage of uninitialized variable + res = res && saveStudyData(theFileName); + if ( res ) + emit saved( this ); + + return res; +} + +//======================================================================= +// name : saveDocument +/*! Purpose : Save document*/ +//======================================================================= +bool SalomeApp_Study::saveDocument() +{ + ModelList list; dataModels( list ); + + SalomeApp_DataModel* aModel = (SalomeApp_DataModel*)list.first(); + QStringList listOfFiles; + for ( ; aModel; aModel = (SalomeApp_DataModel*)list.next() ) { + listOfFiles.clear(); + aModel->save(listOfFiles); + if ( !listOfFiles.isEmpty() ) + saveModuleData(aModel->module()->name(), listOfFiles); + } + + // save SALOMEDS document + SUIT_ResourceMgr* resMgr = application()->resourceMgr(); + if( !resMgr ) + return false; + + bool isMultiFile = resMgr->booleanValue( "Study", "multi_file", false ), + isAscii = resMgr->booleanValue( "Study", "ascii_file", false ); + isAscii ? SalomeApp_Application::studyMgr()->SaveASCII( studyDS(), isMultiFile ) : + SalomeApp_Application::studyMgr()->Save ( studyDS(), isMultiFile ); + + bool res = CAM_Study::saveDocument(); + + res = res && saveStudyData(studyName()); + if ( res ) + emit saved( this ); + + return res; +} + +//================================================================ +// Function : closeDocument +/*! Purpose : Close document*/ +//================================================================ +void SalomeApp_Study::closeDocument(bool permanently) +{ + LightApp_Study::closeDocument(permanently); + + // close SALOMEDS document + _PTR(Study) studyPtr = studyDS(); + if ( studyPtr ) + { + if(permanently) SalomeApp_Application::studyMgr()->Close( studyPtr ); + SALOMEDSClient_Study* aStudy = 0; + setStudyDS( _PTR(Study)(aStudy) ); + } +} + +//================================================================ +// Function : isModified +// Purpose : +//================================================================ +bool SalomeApp_Study::isModified() const +{ + bool isAnyChanged = studyDS() && studyDS()->IsModified(); + if (!isAnyChanged) + isAnyChanged = LightApp_Study::isModified(); + + return isAnyChanged; +} + +//================================================================ +// Function : isSaved +/*! Purpose : Check: data model is saved?*/ +//================================================================ +bool SalomeApp_Study::isSaved() const +{ + bool isAllSaved = studyDS() && studyDS()->GetPersistentReference().size(); + if (!isAllSaved) + isAllSaved = LightApp_Study::isModified(); + + return isAllSaved; +} + +//======================================================================= +// name : saveModuleData +/*! Purpose : save list file for module 'theModuleName' */ +//======================================================================= +void SalomeApp_Study::saveModuleData( QString theModuleName, QStringList theListOfFiles ) +{ + int aNb = theListOfFiles.count(); + if ( aNb == 0 ) + return; + + std::vector aListOfFiles ( aNb ); + int anIndex = 0; + for ( QStringList::Iterator it = theListOfFiles.begin(); it != theListOfFiles.end(); ++it ) { + if ( (*it).isEmpty() ) + continue; + aListOfFiles[anIndex] = (*it).latin1(); + anIndex++; + } + SetListOfFiles(theModuleName, aListOfFiles); +} + +//======================================================================= +// name : openModuleData +/*! Purpose : gets list of file for module 'theModuleNam' */ +//======================================================================= +void SalomeApp_Study::openModuleData( QString theModuleName, QStringList& theListOfFiles ) +{ + std::vector aListOfFiles = GetListOfFiles( theModuleName ); + + int i, aLength = aListOfFiles.size() - 1; + if ( aLength < 0 ) + return; + + //Get a temporary directory for saved a file + theListOfFiles.append(aListOfFiles[0].c_str()); + + for(i = 0; i < aLength; i++) + theListOfFiles.append(aListOfFiles[i+1].c_str()); +} + +//======================================================================= +// name : saveStudyData +/*! Purpose : save data from study */ +//======================================================================= +bool SalomeApp_Study::saveStudyData( const QString& theFileName ) +{ + ModelList list; dataModels( list ); + SalomeApp_DataModel* aModel = (SalomeApp_DataModel*)list.first(); + std::vector listOfFiles(0); + for ( ; aModel; aModel = (SalomeApp_DataModel*)list.next() ) + SetListOfFiles(aModel->module()->name(), listOfFiles); + return true; +} + +//======================================================================= +// name : openStudyData +/*! Purpose : open data for study */ +//======================================================================= +bool SalomeApp_Study::openStudyData( const QString& theFileName ) +{ + return true; +} + +/*! + Set studyDS. +*/ +void SalomeApp_Study::setStudyDS( const _PTR(Study)& s ) +{ + myStudyDS = s; +} + +/*! + Insert data model. +*/ +void SalomeApp_Study::dataModelInserted (const CAM_DataModel* dm) +{ + MESSAGE("SalomeApp_Study::dataModelInserted() : module name() = " << dm->module()->name()); + + CAM_Study::dataModelInserted(dm); + + // addComponent(dm); +} + +/*! + Create SComponent for module, using default engine (CORBAless) +*/ +void SalomeApp_Study::addComponent(const CAM_DataModel* dm) +{ + SalomeApp_Module* aModule = dynamic_cast( dm->module() ); + // 1. aModule == 0 means that this is a light module (no CORBA enigine) + if (!aModule) { + // Check SComponent existance + _PTR(Study) aStudy = studyDS(); + if (!aStudy) + return; + _PTR(SComponent) aComp = aStudy->FindComponent(dm->module()->name()); + if (!aComp) { + // Create SComponent + _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder(); + aComp = aBuilder->NewComponent(dm->module()->name()); + aBuilder->SetName(aComp, dm->module()->moduleName().latin1()); + QString anIconName = dm->module()->iconName(); + if (!anIconName.isEmpty()) { + _PTR(AttributePixMap) anAttr = aBuilder->FindOrCreateAttribute(aComp, "AttributePixMap"); + if (anAttr) + anAttr->SetPixMap(anIconName.latin1()); + } + // Set default engine IOR + aBuilder->DefineComponentInstance(aComp, SalomeApp_Application::defaultEngineIOR().latin1()); + SalomeApp_DataModel::BuildTree( aComp, root(), this, /*skipExisitng=*/true ); + } + } +} + +/*! + Open data model +*/ +bool SalomeApp_Study::openDataModel( const QString& studyName, CAM_DataModel* dm ) +{ + if (!dm) + return false; + + // SalomeApp_DataModel* aDM = (SalomeApp_DataModel*)(dm); + SalomeApp_Module* aModule = dynamic_cast( dm->module() ); + _PTR(Study) aStudy = studyDS(); // shared_ptr cannot be used here + _PTR(SComponent) aSComp; + QString anEngine; + // 1. aModule == 0 means that this is a light module (no CORBA enigine) + if (!aModule) { + anEngine = SalomeApp_Application::defaultEngineIOR(); + aSComp = aStudy->FindComponent(dm->module()->name()); + } + else { + SalomeApp_DataModel* aDM = dynamic_cast( dm ); + if ( aDM ) { + QString anId = aDM->getRootEntry( this ); + if ( anId.isEmpty() ) + return true; // Probably nothing to load + anEngine = aDM->getModule()->engineIOR(); + if ( anEngine.isEmpty() ) + return false; + aSComp = aStudy->FindComponentID( std::string( anId.latin1() ) ); + } + } + if ( aSComp ) { + _PTR(StudyBuilder) aBuilder( aStudy->NewBuilder() ); + if ( aBuilder ) { + try { + aBuilder->LoadWith( aSComp, std::string( anEngine.latin1() ) ); + } + catch( const SALOME::SALOME_Exception& ) { + // Oops, something went wrong while loading -> return an error + return false; + } + // Something has been read -> create data model tree + //SalomeApp_DataModel* aDM = dynamic_cast( dm ); + // aDM->buildTree( aSComp, 0, this ); + } + } else { + // Don't return false here, for there might be no data + // for a given component in the study yet + } + QStringList listOfFiles; + openModuleData(dm->module()->name(), listOfFiles); + if (dm && dm->open(studyName, this, listOfFiles)) { + // Remove the files and temporary directory, created + // for this module by LightApp_Engine_i::Load() + bool isMultiFile = false; // TODO: decide, how to access this parameter + RemoveTemporaryFiles( dm->module()->name(), isMultiFile ); + + // Something has been read -> create data model tree + LightApp_DataModel* aDM = dynamic_cast( dm ); + if ( aDM ) + aDM->update(NULL, this); + return true; + } + return false; +} + +/*! + Create new study name. +*/ +QString SalomeApp_Study::newStudyName() const +{ + std::vector studies = SalomeApp_Application::studyMgr()->GetOpenStudies(); + QString prefix( "Study%1" ), newName, curName; + int i = 1, j, n = studies.size(); + while ( newName.isEmpty() ){ + curName = prefix.arg( i ); + for ( j = 0 ; j < n; j++ ){ + if ( !strcmp( studies[j].c_str(), curName.latin1() ) ) + break; + } + if ( j == n ) + newName = curName; + else + i++; + } + return newName; +} + +//================================================================ +// Function : GetListOfFiles +/*! Purpose : to be used by CORBAless modules*/ +//================================================================ +std::vector SalomeApp_Study::GetListOfFiles( const char* theModuleName ) const +{ + SalomeApp_Engine_i* aDefaultEngine = SalomeApp_Engine_i::GetInstance(); + if (aDefaultEngine) + return aDefaultEngine->GetListOfFiles(id(), theModuleName); + + std::vector aListOfFiles; + return aListOfFiles; +} + +//================================================================ +// Function : SetListOfFiles +/*! Purpose : to be used by CORBAless modules*/ +//================================================================ +void SalomeApp_Study::SetListOfFiles ( const char* theModuleName, + const std::vector theListOfFiles ) +{ + SalomeApp_Engine_i* aDefaultEngine = SalomeApp_Engine_i::GetInstance(); + if (aDefaultEngine) + aDefaultEngine->SetListOfFiles(theListOfFiles, id(), theModuleName); +} + +//================================================================ +// Function : GetTmpDir +/*! Purpose : to be used by CORBAless modules*/ +//================================================================ +std::string SalomeApp_Study::GetTmpDir ( const char* theURL, const bool isMultiFile ) +{ + std::string anURLDir = SALOMEDS_Tool::GetDirFromPath(theURL); + std::string aTmpDir = isMultiFile ? anURLDir : SALOMEDS_Tool::GetTmpDir(); + return aTmpDir; +} + +//================================================================ +// Function : RemoveTemporaryFiles +/*! Purpose : to be used by CORBAless modules*/ +//================================================================ +void SalomeApp_Study::RemoveTemporaryFiles ( const char* theModuleName, const bool isMultiFile ) const +{ + if (isMultiFile) + return; + + std::vector aListOfFiles = GetListOfFiles( theModuleName ); + if (aListOfFiles.size() > 0) { + std::string aTmpDir = aListOfFiles[0]; + + const int n = aListOfFiles.size() - 1; + SALOMEDS::ListOfFileNames_var aSeq = new SALOMEDS::ListOfFileNames; + aSeq->length(n); + for (int i = 0; i < n; i++) + aSeq[i] = CORBA::string_dup(aListOfFiles[i + 1].c_str()); + + SALOMEDS_Tool::RemoveTemporaryFiles(aTmpDir.c_str(), aSeq.in(), true); + } +} + +// END: methods to be used by CORBAless modules + +void SalomeApp_Study::deleteReferencesTo( _PTR( SObject ) obj ) +{ + _PTR(StudyBuilder) sb = studyDS()->NewBuilder(); + std::vector<_PTR(SObject)> aRefs = studyDS()->FindDependances( obj ); + for( int i=0, n=aRefs.size(); iGetFatherComponent()->ComponentDataType()==obj->GetFatherComponent()->ComponentDataType() ) + { + sb->RemoveReference( o ); + sb->RemoveObjectWithChildren( o ); + } + } +} + +//================================================================ +// Function : referencedToEntry +/*! Purpose : Return referenced entry from entry*/ +//================================================================ +QString SalomeApp_Study::referencedToEntry( const QString& entry ) const +{ + _PTR(SObject) obj = studyDS()->FindObjectID( entry.latin1() ); + _PTR(SObject) refobj; + + if( obj && obj->ReferencedObject( refobj ) ) + return refobj->GetID().c_str(); + return LightApp_Study::referencedToEntry( entry ); +} + +//================================================================ +// Function : componentDataType +/*! Purpose : Return component data type from entry*/ +//================================================================ +QString SalomeApp_Study::componentDataType( const QString& entry ) const +{ + _PTR(SObject) obj( studyDS()->FindObjectID( entry.latin1() ) ); + if ( !obj ) + return LightApp_Study::componentDataType( entry ); + return obj->GetFatherComponent()->ComponentDataType().c_str(); +} + +//================================================================ +// Function : componentDataType +/*! Purpose : Return component data type from entry*/ +//================================================================ +bool SalomeApp_Study::isComponent( const QString& entry ) const +{ + _PTR(SObject) obj( studyDS()->FindObjectID( entry.latin1() ) ); + return obj && QString( obj->GetID().c_str() ) == obj->GetFatherComponent()->GetID().c_str(); +} + +//================================================================ +// Function : children +/*! Purpose : Return entries of children of object*/ +//================================================================ +void SalomeApp_Study::children( const QString& entry, QStringList& child_entries ) const +{ + _PTR(SObject) SO = studyDS()->FindObjectID( entry.latin1() ); + _PTR(ChildIterator) anIter ( studyDS()->NewChildIterator( SO ) ); + anIter->InitEx( true ); + while( anIter->More() ) + { + _PTR(SObject) val( anIter->Value() ); + child_entries.append( val->GetID().c_str() ); + anIter->Next(); + } +} + +void SalomeApp_Study::components( QStringList& comps ) const +{ + for( _PTR(SComponentIterator) it ( studyDS()->NewComponentIterator() ); it->More(); it->Next() ) + { + _PTR(SComponent) aComponent ( it->Value() ); + if( aComponent && aComponent->ComponentDataType() == "Interface Applicative" ) + continue; // skip the magic "Interface Applicative" component + comps.append( aComponent->ComponentDataType().c_str() ); + } +} diff --git a/src/SalomeApp/SalomeApp_Study.h b/src/SalomeApp/SalomeApp_Study.h new file mode 100644 index 000000000..c07d20528 --- /dev/null +++ b/src/SalomeApp/SalomeApp_Study.h @@ -0,0 +1,96 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SALOMEAPP_STUDY_H +#define SALOMEAPP_STUDY_H + +#include "SalomeApp.h" + +#include + +#ifdef WIN32 +#pragma warning( disable:4251 ) +#endif + +#include "SALOMEDSClient.hxx" + +class SALOMEAPP_EXPORT SalomeApp_Study : public LightApp_Study +{ + Q_OBJECT + +public: + SalomeApp_Study( SUIT_Application* ); + virtual ~SalomeApp_Study(); + + virtual int id() const; + + virtual void createDocument(); + virtual bool openDocument( const QString& ); + virtual bool loadDocument( const QString& ); + + virtual bool saveDocument(); + virtual bool saveDocumentAs( const QString& ); + + virtual void closeDocument(bool permanently = true); + + virtual bool isSaved() const; + virtual bool isModified() const; + + virtual void addComponent ( const CAM_DataModel* dm); + + _PTR(Study) studyDS() const; + + virtual std::string GetTmpDir ( const char* theURL, const bool isMultiFile); + + // to delete all references to object, whose have the same component + void deleteReferencesTo( _PTR( SObject ) ); + + virtual QString componentDataType( const QString& ) const; + virtual QString referencedToEntry( const QString& ) const; + virtual bool isComponent( const QString& ) const; + virtual void children( const QString&, QStringList& ) const; + virtual void components( QStringList& ) const; + +protected: + virtual void saveModuleData ( QString theModuleName, QStringList theListOfFiles ); + virtual void openModuleData ( QString theModuleName, QStringList& theListOfFiles ); + virtual bool saveStudyData ( const QString& theFileName ); + virtual bool openStudyData ( const QString& theFileName ); + + virtual std::vector GetListOfFiles ( const char* theModuleName ) const; + virtual void SetListOfFiles ( const char* theModuleName, + const std::vector theListOfFiles); + virtual void RemoveTemporaryFiles ( const char* theModuleName, const bool isMultiFile) const; + +protected: + virtual void dataModelInserted( const CAM_DataModel* ); + virtual bool openDataModel( const QString&, CAM_DataModel* ); + void setStudyDS(const _PTR(Study)& s ); + +private: + QString newStudyName() const; + +private: + _PTR(Study) myStudyDS; +}; + +#ifdef WIN32 +#pragma warning( default:4251 ) +#endif + +#endif diff --git a/src/SalomeApp/SalomeApp_Tools.cxx b/src/SalomeApp/SalomeApp_Tools.cxx new file mode 100644 index 000000000..f6b93b4ca --- /dev/null +++ b/src/SalomeApp/SalomeApp_Tools.cxx @@ -0,0 +1,120 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "SalomeApp_Tools.h" + +#include +#include +#include + +#include + +/*! + Convert QColor to Quantity_Color, if QColor is valid. +*/ +Quantity_Color SalomeApp_Tools::color( const QColor& c ) +{ + Quantity_Color aColor; + if ( c.isValid() ) + aColor = Quantity_Color( c.red() / 255., c.green() / 255., c.blue() / 255., Quantity_TOC_RGB ); + return aColor; +} + +/*! + Convert Quantity_Color to QColor. +*/ +QColor SalomeApp_Tools::color( const Quantity_Color& c ) +{ + return QColor( (int)( c.Red() * 255 ), (int)( c.Green() * 255 ), (int)( c.Blue() * 255 ) ); +} + +/*! + Gets message on exception \a S_ex. +*/ +QString SalomeApp_Tools::ExceptionToString( const SALOME::SALOME_Exception& S_ex ) +{ + QString message; + + switch ( S_ex.details.type ) + { + case SALOME::COMM: + case SALOME::INTERNAL_ERROR: + { + message = QString( S_ex.details.text ); + QString source( S_ex.details.sourceFile ); + QString line; + line.setNum( S_ex.details.lineNumber ); + message = message + " \n" + source + " : " + line; + break; + } + case SALOME::BAD_PARAM: + { + message = QString( S_ex.details.text ); +#ifdef _DEBUG_ + QString source( S_ex.details.sourceFile ); + QString line; + line.setNum( S_ex.details.lineNumber ); + message = message + " \n" + source + " : " + line; +#endif + break; + } + default: + { + message = QString( "SALOME CORBA Exception Type invalid" ); + QString source( S_ex.details.sourceFile ); + QString line; + line.setNum( S_ex.details.lineNumber ); + message = message + " \n" + source + " : " + line; + break; + } + } + return message; +} + +/*! + Gets message box on exception \a S_ex. +*/ +void SalomeApp_Tools::QtCatchCorbaException( const SALOME::SALOME_Exception& S_ex ) +{ + QString message = ExceptionToString( S_ex ); + + QString title; + bool error = true; + switch ( S_ex.details.type ) + { + case SALOME::COMM: + case SALOME::INTERNAL_ERROR: + title = QObject::tr( "Engine Error" ); + break; + case SALOME::BAD_PARAM: + error = false; + title = QObject::tr( "Engine Warning" ); + break; + default: + title = QObject::tr( "Internal SALOME Error" ); + break; + } + + if ( error ) + SUIT_MessageBox::error1( SUIT_Session::session()->activeApplication()->desktop(), + title, message, QObject::tr( "OK" ) ); + else + SUIT_MessageBox::warn1( SUIT_Session::session()->activeApplication()->desktop(), + title, message, QObject::tr( "OK" ) ); + +} diff --git a/src/SalomeApp/SalomeApp_Tools.h b/src/SalomeApp/SalomeApp_Tools.h new file mode 100644 index 000000000..074367b32 --- /dev/null +++ b/src/SalomeApp/SalomeApp_Tools.h @@ -0,0 +1,47 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SALOMEAPP_TOOLS_H +#define SALOMEAPP_TOOLS_H + +#include "SalomeApp.h" + +#include + +#include +#include + +#include + +#include +#include CORBA_CLIENT_HEADER(SALOME_Exception) + +/*! + Class which provide color converter and exception message box. +*/ +class SALOMEAPP_EXPORT SalomeApp_Tools : public SUIT_Tools +{ +public: + static Quantity_Color color( const QColor& ); + static QColor color( const Quantity_Color& ); + + static QString ExceptionToString( const SALOME::SALOME_Exception& ); + static void QtCatchCorbaException( const SALOME::SALOME_Exception& ); +}; + +#endif diff --git a/src/SalomeApp/SalomeApp_TypeFilter.cxx b/src/SalomeApp/SalomeApp_TypeFilter.cxx new file mode 100644 index 000000000..58ab6bb57 --- /dev/null +++ b/src/SalomeApp/SalomeApp_TypeFilter.cxx @@ -0,0 +1,65 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "SalomeApp_TypeFilter.h" + +#include "LightApp_DataOwner.h" +#include "SalomeApp_Study.h" + +#include + +/*! + Constructor. +*/ +SalomeApp_TypeFilter::SalomeApp_TypeFilter( SalomeApp_Study* study, const QString& kind ) + : SalomeApp_Filter( study ) +{ + myKind = kind; +} + +/*! + Destructor. +*/ +SalomeApp_TypeFilter::~SalomeApp_TypeFilter() +{ +} + +/*! + Check: data owner is valid? +*/ +bool SalomeApp_TypeFilter::isOk( const SUIT_DataOwner* sOwner ) const +{ + const LightApp_DataOwner* owner = dynamic_cast ( sOwner ); + + SalomeApp_Study* aDoc = getStudy(); + if (owner && aDoc && aDoc->studyDS()) + { + _PTR(Study) aStudy = aDoc->studyDS(); + QString entry = owner->entry(); + + _PTR(SObject) aSObj( aStudy->FindObjectID( entry.latin1() ) ); + if (aSObj) + { + _PTR(SComponent) aComponent(aSObj->GetFatherComponent()); + if ( aComponent && (aComponent->ComponentDataType() == myKind.latin1()) ) + return true; + } + } + + return false; +} diff --git a/src/SalomeApp/SalomeApp_TypeFilter.h b/src/SalomeApp/SalomeApp_TypeFilter.h new file mode 100644 index 000000000..9c95d25ee --- /dev/null +++ b/src/SalomeApp/SalomeApp_TypeFilter.h @@ -0,0 +1,41 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SALOMEAPP_TYPEFILTER_H +#define SALOMEAPP_TYPEFILTER_H + +#include + +#include "SalomeApp_Filter.h" + +/*! + Class which provide data owner validation. +*/ +class SALOMEAPP_EXPORT SalomeApp_TypeFilter: public SalomeApp_Filter +{ +public: + SalomeApp_TypeFilter( SalomeApp_Study* study, const QString& kind ); + ~SalomeApp_TypeFilter(); + + virtual bool isOk( const SUIT_DataOwner* ) const; + +private: + QString myKind; +}; + +#endif diff --git a/src/Style/SalomeStyle.cxx b/src/Style/SalomeStyle.cxx new file mode 100644 index 000000000..bcdc6f1ac --- /dev/null +++ b/src/Style/SalomeStyle.cxx @@ -0,0 +1,1232 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#include "SalomeStyle.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const char* const hole_xpm[] = { +"3 3 3 1", +". c None", +"a c #999999", +"b c #FFFFFF", +"aa.", +"aab", +".bb" +}; + +static const char* const cross_xpm[] = { +"12 12 4 1", +". c None", +"a c #000000", +"b c #FFFFFF", +"c c #666666", +"............", +"............", +"............", +".aaaa..aaaa.", +"..abbaabba..", +"...abbbba...", +"....abba....", +"...abbbba...", +"..abbaabba..", +".aaaa..aaaa.", +"............", +"............" +}; + +static const char* const maximize_xpm[] = { +"12 12 4 1", +". c None", +"a c #000000", +"b c #FFFFFF", +"c c #666666", +"............", +".aaaaaaaaaa.", +".acccccccca.", +".acccccccca.", +".abbbbbbbba.", +".abbbbbbbba.", +".abbbbbbbba.", +".abbbbbbbba.", +".abbbbbbbba.", +".abbbbbbbba.", +".aaaaaaaaaa.", +"............" +}; + +static const char* const normal_xpm[] = { +"12 12 4 1", +". c None", +"a c #000000", +"b c #FFFFFF", +"c c #666666", +"............", +"...aaaaaaaa.", +"...acccccca.", +"...abbbbbba.", +"...aaaaaaba.", +".aaaaaaaaba.", +".accccccaba.", +".abbbbbbaaa.", +".abbbbbba...", +".abbbbbba...", +".aaaaaaaa...", +"............" +}; + +static const char* const minimize_xpm[] = { +"12 12 4 1", +". c None", +"a c #000000", +"b c #FFFFFF", +"c c #666666", +"............", +"............", +"............", +"............", +"............", +"............", +"............", +"............", +"aaaaaaaaaaaa", +"abbbbbbbbbba", +"aaaaaaaaaaaa", +"............" +}; + +/*! + Class: SalomeStyle [Public] + Descr: Style for SALOME platform +*/ + +SalomeStyle::SalomeStyle() +: myTitleParent( 0 ) +{ + qApp->installEventFilter( this ); +} + +SalomeStyle::~SalomeStyle() +{ +} + +void SalomeStyle::polish( QWidget* w ) +{ + if ( !w ) + return; +/* + if ( w->inherits( "QLineEdit" ) ) + { + QLineEdit* fr = (QLineEdit*)w; + if ( w->parentWidget() && w->parentWidget()->inherits( "QSpinWidget" ) ) + fr->setFrameStyle( QFrame::Plain ); + else + { + fr->setFrameStyle( QFrame::Plain | QFrame::Box ); + fr->setLineWidth( 1 ); + fr->setMidLineWidth( 0 ); + } + } + else +*/ + if ( w->inherits( "QToolBar" ) ) + { + QToolBar* tb = (QToolBar*)w; + tb->setFrameStyle( QFrame::ToolBarPanel | QFrame::Plain ); + tb->setLineWidth( 1 ); + tb->setMidLineWidth( 1 ); + } + else + if ( w->inherits( "QDockWindow" ) ) + { + QDockWindow* dw = (QDockWindow*)w; + dw->setFrameStyle( QFrame::ToolBarPanel | QFrame::Raised ); + } +/* + else if ( w->inherits( "QListView" ) ) + { + QListView* lv = (QListView*)w; + lv->setFrameStyle( QFrame::Box | QFrame::Plain ); + } +*/ + else + PARENT_STYLE::polish( w ); +} + +bool SalomeStyle::eventFilter( QObject* o, QEvent* e ) +{ + if ( e->type() == QEvent::FocusIn || e->type() == QEvent::FocusOut ) + { + QDockWindow* wnd = NULL; + while( o && !wnd ) + if( o->inherits( "QDockWindow" ) ) + wnd = ( QDockWindow* )o; + else + o = o->parent(); + + if ( wnd ) + { + const QObjectList* objList = o->children(); + for( QObjectListIterator anIt( *objList ); anIt.current(); ++anIt ) + if( anIt.current()->inherits( "QDockWindowHandle" ) ) + { + QWidget* ww = ( QWidget* )anIt.current(); + ww->repaint( ww->rect() ); + const QObjectList* wc = ww->children(); + for( QObjectListIterator anIt2( *wc ); anIt2.current(); ++anIt2 ) + if( anIt2.current()->inherits( "QToolButton" ) ) + { + QWidget* tb = ( QWidget* )anIt2.current(); + tb->repaint( tb->rect() ); + } + } + } + } + + if ( o && o->inherits( "QPushButton" ) && ( e->type() == QEvent::Enter || e->type() == QEvent::Leave ) ) + ((QWidget*)o)->update(); + + return false; +} + +double linear( double x ) +{ + return x; +} + +void SalomeStyle::mix( const double t, const QColor& c1, const QColor& c2, QColor& res ) +{ + if( t<0.0 || t>1.0 ) + return; + + int r = int( c1.red() * (1-t) + c2.red() * t ), + g = int( c1.green() * (1-t) + c2.green() * t ), + b = int( c1.blue() * (1-t) + c2.blue() * t ); + res.setRgb( r, g, b ); +} + +void SalomeStyle::mix( const double t, QRgb& rgb1, const QRgb& rgb2 ) +{ + if( t<0.0 || t>1.0 ) + return; + + int c[2][4] = { qRed( rgb1 ), qGreen( rgb1 ), qBlue( rgb1 ), qAlpha( rgb1 ), + qRed( rgb2 ), qGreen( rgb2 ), qBlue( rgb2 ), qAlpha( rgb2 ) }; + for( int i=0; i<4; i++ ) + c[0][i] = (int)( c[0][i] * (1-t) + c[1][i] * t ); + + rgb1 = qRgba( c[0][0], c[0][1], c[0][2], qAlpha( rgb1 ) ); +} + +void SalomeStyle::mix( const double t, QPixmap& pix, const QColor& col ) +{ + if( t<0.0 || t>1.0 ) + return; + + QImage anImage = pix.convertToImage(); + if( anImage.isNull() ) + return; + + if( anImage.depth()!=32 ) + anImage = anImage.convertDepth( 32 ); + + int w = anImage.width(), + h = anImage.height(); + + QRgb colrgb = col.rgb(), cur; + for( int y=0; y255 ) + gray = 255; + else if( gray<0 ) + gray = 0; + colorline[ x ] = qRgba( gray, gray, gray, qAlpha( colorline[x] ) ); + } + } + pix = anImage; +} + +void SalomeStyle::drawGradient( QPainter* p, const QRect& r, + const QColor& c1, const QColor& c2, + const Direction d, gradient_func f ) const +{ + p->save(); + p->translate( r.x(), r.y() ); + + QColor mid; + if( d==LeftToRight || d==RightToLeft ) + for( int xmax = r.width(), x = d==LeftToRight ? 0 : xmax; + d==LeftToRight ? x<=xmax : x>=0; + d==LeftToRight ? x++ : x-- ) + { + double t = double( x ) / double( xmax ); + mix( d==LeftToRight ? f(t) : 1-f(t), c1, c2, mid ); + p->setPen( mid ); + p->drawLine( x, 0, x, r.height() ); + } + else + for( int ymax = r.height(), y = d==UpToDown ? 0 : ymax; + d==UpToDown ? y<=ymax : y>=0; + d==UpToDown ? y++ : y-- ) + { + double t = double( y ) / double( ymax ); + mix( d==UpToDown ? f(t) : 1-f(t), c1, c2, mid ); + p->setPen( mid ); + p->drawLine( 0, y, r.width(), y ); + } + + p->restore(); +} + +void SalomeStyle::drawPrimitive( PrimitiveElement pe, QPainter* p, const QRect& r, + const QColorGroup& cg, SFlags flags, const QStyleOption& opt ) const +{ + switch ( pe ) + { + case PE_ButtonTool: + if ( !myTitleParent ) + PARENT_STYLE::drawPrimitive( pe, p, r, cg, flags, opt ); + break; + + case PE_DockWindowResizeHandle: + p->fillRect( r.x(), r.y(), r.width(), r.height(), cg.dark() ); + if ( flags & Style_Horizontal ) + p->fillRect( r.x(), r.y() + 1, r.width(), r.height() - 2, cg.midlight() ); + else + p->fillRect( r.x() + 1, r.y(), r.width() - 2, r.height(), cg.midlight() ); + break; + + case PE_DockWindowHandle: + { + QPaintDevice* pd = p->device(); + if ( !pd ) + break; + + QWidget* w = (QWidget*)pd; + + if ( !w || !w->inherits( "QDockWindowHandle" ) ) + break; + + QDockWindow* wnd = ( QDockWindow* ) w->parent(); + if ( !wnd ) + return; + + QObject* activeWidget = qApp->focusWidget(); + QDockWindow* activeWnd = 0; + while ( !activeWnd && activeWidget ) + { + if ( activeWidget->inherits( "QDockWindow" ) ) + activeWnd = (QDockWindow*)activeWidget; + else + activeWidget = activeWidget->parent(); + } + + bool act = wnd == activeWnd, horiz = flags & Style_Horizontal; + + QPixmap hole( (const char**)hole_xpm ); + + if ( wnd->inherits( "QToolBar" ) ) + { + drawGradient( p, r, cg.light(), cg.background(), horiz ? UpToDown : LeftToRight, linear ); + + int c = 4, i; double d = ( horiz ? r.height() : r.width() ) / ( c + 1 ); + QBrush fill = cg.brush( QColorGroup::Dark ); + p->setPen( Qt::red ); + for ( i = 0; i < c; i++ ) + { + if ( horiz ) + p->drawPixmap( r.x() + r.width() / 2 - 1, (int)( r.y() + ( i + 1 ) * d - 1 ), hole ); + else + p->drawPixmap( (int) ( r.x() + ( i + 1 ) * d - 1 ), r.y() + r.height() / 2 - 1, hole ); + } + + int dd = (int(d)/2) + (int(d)%2); + for ( i = 0; i < c - 1; i++ ) + { + if ( horiz ) + p->drawPixmap( r.x() + r.width() / 2 + 2, (int)( r.y() + dd + ( i + 1 ) * d - 1 ), hole ); + else + p->drawPixmap( (int)( r.x() + dd + ( i + 1 ) * d - 1 ), r.y() + r.height() / 2 + 2, hole ); + } + } + else + { + int d = 1; + QRect rr( r.x()+d, r.y()+d, r.width()-2*d, r.height()-2*d ); + + QColor col; + if ( act ) + mix( 0.5, cg.highlight(), Qt::white, col ); + else + col = cg.background(); + + drawGradient( p, rr, act ? cg.highlight() : cg.dark(), col, + horiz ? LeftToRight : UpToDown, linear ); + + QRect rt = rr; + if ( flags & Style_Horizontal ) + rt.addCoords( 0, 20, 0, 0 ); + else + rt.addCoords( 0, 0, -20, 0 ); + + int textW = flags & Style_Horizontal ? rt.height() : rt.width(); + int textH = flags & Style_Horizontal ? rt.width() : rt.height(); + + QString title = titleText( wnd->caption(), textW, p->fontMetrics() ); + + if ( wnd ) + { + QColorGroup cgroup = wnd->isActiveWindow() ? wnd->palette().active() : wnd->palette().inactive(); + p->setPen( cgroup.highlightedText() ); + + if ( flags & Style_Horizontal ) + { + p->rotate( 270.0 ); + p->translate( -(rt.height()+rt.y()), (rt.width()-rt.x()) ); + p->drawText( 0, 0, title ); + } + else + p->drawText( 2, 2, textW, textH, AlignLeft, title ); + } + } + break; + } + + case PE_DockWindowSeparator: + { + bool horiz = ( flags & Style_Horizontal ); + QWidget* w = ( QWidget* )p->device(); + if( w->inherits( "QToolBarSeparator" ) ) + { + drawGradient( p, r, cg.light(), cg.background(), horiz ? UpToDown : LeftToRight, linear ); + int w = r.width(), h = r.height(); + int part = 8; + + p->setPen( cg.dark() ); + if( horiz ) + p->drawLine( r.x() + w/2, r.y() + h/part, r.x() + w/2, r.y() + (part-1)*h/part ); + else + p->drawLine( r.x() + w/part, r.y() + h/2, r.x() + (part-1)*w/part, r.y() + h/2 ); + + p->setPen( cg.light() ); + if( horiz ) + p->drawLine( r.x() + w/2 + 1, r.y() + h/part + 1, r.x() + w/2 + 1, r.y() + (part-1)*h/part + 1 ); + else + p->drawLine( r.x() + w/part + 1, r.y() + h/2 + 1, r.x() + (part-1)*w/part + 1, r.y() + h/2 + 1 ); + } + else + PARENT_STYLE::drawPrimitive( pe, p, r, cg, flags, opt ); + break; + } + + case PE_PanelDockWindow: + { + QWidget* w = ( QWidget* )p->device(); + + int offset = pixelMetric( PM_DockWindowHandleExtent, w ); + if ( w->inherits( "QToolBar" ) ) + { + bool vert = ( ( QToolBar* )w )->orientation() == Qt::Vertical; + if ( vert ) + drawGradient( p, QRect( r.x(), r.y()+offset, r.x()+r.width(), r.y()+offset ), + cg.light(), cg.background(), LeftToRight, linear ); + else + drawGradient( p, QRect( r.x()+offset, r.y(), r.x()+offset, r.y()+r.height() ), + cg.light(), cg.background(), UpToDown, linear ); + + p->setPen( QPen( cg.light(), 1 ) ); + p->drawRect( r ); + } + else + { + p->setPen( QPen( cg.dark(), 1 ) ); + p->setBrush( cg.light() ); + p->drawRect( r ); + } + + break; + } + + case PE_PanelPopup: + p->setPen( QPen( cg.dark(), 1 ) ); + p->setBrush( cg.light() ); + p->drawRect( r ); + break; + + case PE_HeaderSection: + { + QColor col; mix( 0.2, cg.light(), Qt::black, col ); + drawGradient( p, r, cg.light(), col, DownToUp, linear ); + drawGradient( p, QRect( r.x(), r.y(), 1, r.height() ), cg.light(), cg.dark(), DownToUp, linear ); + p->setPen( cg.dark() ); + p->drawLine( r.x(), r.y()+r.height()-1, r.x()+r.width(), r.y()+r.height()-1 ); + break; + } + + case PE_Splitter: + p->fillRect( r.x() + 1, r.y() + 1, r.width() - 2, r.height() - 2, cg.dark() ); + p->fillRect( r.x() + 2, r.y() + 2, r.width() - 4, r.height() - 4, cg.midlight() ); + break; + + case PE_ButtonBevel: + PARENT_STYLE::drawPrimitive( PE_ButtonDropDown, p, r, cg, flags, opt ); + break; + + case PE_ButtonCommand: + { + QColorGroup cGrp( cg ); + if ( flags & Style_MouseOver ) + cGrp.setColor( QColorGroup::Button, cGrp.midlight() ); + + if ( flags & Style_MouseOver ) + PARENT_STYLE::drawPrimitive( PE_ButtonDropDown, p, r, cGrp, flags, opt ); + else + PARENT_STYLE::drawPrimitive( flags & Style_Raised ? PE_ButtonDropDown : pe, p, r, cGrp, flags, opt ); + } + break; + + default: + PARENT_STYLE::drawPrimitive( pe, p, r, cg, flags, opt ); + break; + } +} + +void SalomeStyle::drawControl( ControlElement element, QPainter* p, const QWidget* widget, const QRect& r, + const QColorGroup& cg, SFlags flags, const QStyleOption& opt ) const +{ + switch( element ) + { + case CE_PopupMenuItem: + { + if(! widget || opt.isDefault()) + break; + + const QPopupMenu *popupmenu = (const QPopupMenu *) widget; + QMenuItem *mi = opt.menuItem(); + if( !mi ) + break; + + int tab = opt.tabWidth(); + int maxpmw = opt.maxIconWidth(); + bool dis = !( flags & Style_Enabled ); + bool checkable = popupmenu->isCheckable(); + bool act = flags & Style_Active; + bool use2000style = true; + int x, y, w, h; + + int windowsItemFrame = 2, + windowsItemHMargin = 5, + windowsItemVMargin = 1, + windowsRightBorder = 2, + windowsArrowHMargin = 2; + + r.rect(&x, &y, &w, &h); + + if ( checkable ) + { + // space for the checkmarks + if (use2000style) + maxpmw = QMAX( maxpmw, 20 ); + else + maxpmw = QMAX( maxpmw, 12 ); + } + + int checkcol = maxpmw; + + if ( mi && mi->isSeparator() ) + { + p->setPen( cg.dark() ); + p->drawLine( x+3*checkcol/2, y, x+w, y ); + //p->setPen( cg.light() ); + //p->drawLine( x, y+1, x+w, y+1 ); + return; + } + + QBrush fill = ( act && !dis ? + cg.brush( QColorGroup::Highlight ) : + cg.brush( QColorGroup::Light ) ); + p->fillRect( x, y, w, h, fill ); + + if( !mi ) + return; + + int xpos = x; + QRect vrect = visualRect( QRect( xpos, y, checkcol, h ), r ); + int xvis = vrect.x(); + + if( mi->isChecked() ) + { + if( act && !dis ) + qDrawShadePanel( p, xvis, y, checkcol, h, + cg, TRUE, 1, &cg.brush( QColorGroup::Button ) ); + else + { + QBrush fill( cg.light(), Dense4Pattern ); + // set the brush origin for the hash pattern to the x/y coordinate + // of the menu item's checkmark... this way, the check marks have + // a consistent look + QPoint origin = p->brushOrigin(); + p->setBrushOrigin( xvis, y ); + qDrawShadePanel( p, xvis, y, checkcol, h, cg, TRUE, 1, &fill ); + // restore the previous brush origin + p->setBrushOrigin( origin ); + } + } + else if( !act ) + p->fillRect(x+checkcol, y, w-checkcol , h, cg.brush( QColorGroup::Light )); + + if( !( act && !dis ) && !mi->isChecked() ) + { + QColor col; mix( 0.5, cg.mid(), Qt::white, col ); + drawGradient( p, QRect( xvis, y, checkcol, h+1 ), cg.light(), col, LeftToRight, linear ); + } + + if( mi->iconSet() ) + { // draw iconset + QIconSet::Mode mode = dis ? QIconSet::Active : QIconSet::Normal; + if(act && !dis ) + mode = QIconSet::Active; + QPixmap pixmap; + if( checkable && mi->isChecked() ) + pixmap = mi->iconSet()->pixmap( QIconSet::Small, mode, QIconSet::On ); + else + pixmap = mi->iconSet()->pixmap( QIconSet::Small, mode ); + int pixw = pixmap.width(); + int pixh = pixmap.height(); + + if( dis ) + toGrayscale( pixmap, 1.1 ); + + //if( act && !dis && !mi->isChecked() ) + // qDrawShadePanel( p, xvis, y, checkcol, h, cg, FALSE, 1, &cg.brush( QColorGroup::Button ) ); + + QRect pmr( 0, 0, pixw, pixh ); + pmr.moveCenter( vrect.center() ); + p->setPen( cg.text() ); + p->drawPixmap( pmr.topLeft(), pixmap ); + + QBrush fill = ( act ? cg.brush( QColorGroup::Highlight ) : cg.brush( QColorGroup::Light )); + int xp = xpos + checkcol + 1; + if( !dis ) + p->fillRect( visualRect( QRect( xp, y, w - checkcol - 1, h ), r ), fill); + } + else if( checkable ) + { // just "checking"... + if( mi->isChecked() ) + { + int xp = xpos + windowsItemFrame; + + SFlags cflags = Style_Default; + if( !dis ) + cflags |= Style_Enabled; + if( act ) + cflags |= Style_On; + + drawPrimitive( PE_CheckMark, p, + visualRect( QRect( xp, y + windowsItemFrame, + checkcol - 2*windowsItemFrame, + h - 2*windowsItemFrame), r ), cg, cflags, opt ); + } + } + + p->setPen( act ? cg.highlightedText() : cg.buttonText() ); + + QColor discol; + if( dis ) + { + discol = cg.text(); + p->setPen( discol ); + } + + int xm = windowsItemFrame + checkcol + windowsItemHMargin; + xpos += xm; + + vrect = visualRect( QRect( xpos, y+windowsItemVMargin, w-xm-tab+1, h-2*windowsItemVMargin ), r ); + xvis = vrect.x(); + if( mi->custom() ) + { + p->save(); + if ( dis && !act ) + { + p->setPen( cg.light() ); + mi->custom()->paint( p, cg, act, !dis, + xvis+1, y+windowsItemVMargin+1, + w-xm-tab+1, h-2*windowsItemVMargin ); + p->setPen( discol ); + } + mi->custom()->paint( p, cg, act, !dis, xvis, y+windowsItemVMargin, + w-xm-tab+1, h-2*windowsItemVMargin ); + p->restore(); + } + QString s = mi->text(); + if( !s.isNull() ) + { // draw text + int t = s.find( '\t' ); + int text_flags = AlignVCenter | ShowPrefix | DontClip | SingleLine; + if( !styleHint( SH_UnderlineAccelerator, widget ) ) + text_flags |= NoAccel; + text_flags |= (QApplication::reverseLayout() ? AlignRight : AlignLeft ); + if( t >= 0 ) + { // draw tab text + int xp = x + w - tab - windowsItemHMargin - windowsItemFrame + 1; + if( use2000style ) + xp -= 20; + else + xp -= windowsRightBorder; + int xoff = visualRect( QRect( xp, y+windowsItemVMargin, tab, h-2*windowsItemVMargin ), r ).x(); + if( dis && !act ) + { + p->setPen( cg.light() ); + p->drawText( xoff+1, y+windowsItemVMargin+1, tab, h-2*windowsItemVMargin, text_flags, s.mid( t+1 )); + p->setPen( discol ); + } + p->drawText( xoff, y+windowsItemVMargin, tab, h-2*windowsItemVMargin, text_flags, s.mid( t+1 ) ); + s = s.left( t ); + } + if( dis && !act ) + { + p->setPen( cg.light() ); + p->drawText( xvis+1, y+windowsItemVMargin+1, w-xm-tab+1, h-2*windowsItemVMargin, text_flags, s, t ); + p->setPen( discol ); + } + p->drawText( xvis, y+windowsItemVMargin, w-xm-tab+1, h-2*windowsItemVMargin, text_flags, s, t ); + } + else if( mi->pixmap() ) + { // draw pixmap + QPixmap *pixmap = mi->pixmap(); + if( pixmap->depth() == 1 ) + p->setBackgroundMode( OpaqueMode ); + p->drawPixmap( xvis, y+windowsItemFrame, *pixmap ); + if( pixmap->depth() == 1 ) + p->setBackgroundMode( TransparentMode ); + } + if( mi->popup() ) + { // draw sub menu arrow + int dim = (h-2*windowsItemFrame) / 2; + PrimitiveElement arrow; + arrow = ( QApplication::reverseLayout() ? PE_ArrowLeft : PE_ArrowRight ); + xpos = x+w - windowsArrowHMargin - windowsItemFrame - dim; + vrect = visualRect( QRect(xpos, y + h / 2 - dim / 2, dim, dim), r ); + if( act ) + { + QColorGroup g2 = cg; + g2.setColor( QColorGroup::ButtonText, g2.highlightedText() ); + drawPrimitive( arrow, p, vrect, g2, dis ? Style_Default : Style_Enabled, opt ); + } + else + { + drawPrimitive( arrow, p, vrect, cg, dis ? Style_Default : Style_Enabled, opt ); + } + } + + if( act && !dis ) + { + p->setPen( cg.dark() ); + p->drawRect( r ); + } + break; + } + + case CE_MenuBarItem: + { + bool active = flags & Style_Active; + bool down = flags & Style_Down; + QRect pr = r; + + p->save(); + if( active && down ) + { + //QColor col; mix( 0.5, cg.mid(), Qt::white, col ); + //drawGradient( p, r, col, cg.light(), UpToDown, linear ); + p->setPen( cg.light() ); + p->setBrush( cg.light() ); + p->drawRect( r ); + + p->setPen( cg.dark() ); + int w = r.width()-1, h = r.height(); + p->drawLine( r.x(), r.y(), r.x()+w, r.y() ); + p->drawLine( r.x(), r.y(), r.x(), r.y()+h ); + p->drawLine( r.x()+w, r.y(), r.x()+w, r.y()+h ); + + p->translate( 1, 1 ); + } + else + drawGradient( p, r, cg.light(), cg.background(), active ? DownToUp : UpToDown, linear ); + + QCommonStyle::drawControl(element, p, widget, pr, cg, flags, opt); + p->restore(); + break; + } + + case CE_MenuBarEmptyArea: + { + drawGradient( p, r, cg.light(), cg.background(), UpToDown, linear ); + break; + } + + case CE_ToolButtonLabel: + { + const QToolButton *toolbutton = (const QToolButton *) widget; + QObject* parent = toolbutton->parent(); + + QToolBar* tb = NULL; + while( parent ) + if( parent->inherits( "QToolBar" ) ) + { + tb = ( QToolBar* )parent; + break; + } + else + parent = parent->parent(); + parent = toolbutton->parent(); + + int horiz = -1; + if( tb ) + { + if( tb->orientation()==Qt::Horizontal ) + horiz = 1; + else + horiz = 0; + drawGradient( p, r, cg.light(), cg.background(), horiz ? UpToDown : LeftToRight, linear ); + } + else if( parent->inherits( "QDockWindowHandle" ) ) + { + QWidget* w = ( QWidget* ) parent; + QDockWindow* wnd = ( QDockWindow* )w->parent(); + if( !wnd->orientation()==Qt::Horizontal ) + horiz=1; + else + horiz=0; + + QPoint pp( r.x(), r.y() ), + qq = toolbutton->mapToParent( pp ); + + bitBlt( p->device(), r.x(), r.y(), w, horiz ? qq.x()-r.width() : qq.x(), + horiz ? qq.y() : qq.y()+r.height(), + r.width(), r.height(), Qt::CopyROP, true ); + } + + bool highlight = ( flags & Style_MouseOver ), + down = ( flags & ( Style_Down | Style_On ) ), + en = toolbutton->isEnabled(); + + if( down ) + if( horiz>=0 ) + { + drawGradient( p, r, cg.light(), cg.background(), horiz==1 ? DownToUp : RightToLeft, linear ); + p->setPen( cg.background() ); + p->drawRect( r ); + } + else + { + p->setPen( cg.dark() ); + p->setBrush( cg.light() ); + p->drawRect( r ); + } + if( highlight ) + { + p->setPen( cg.dark() ); + QColor col; mix( 0.05, cg.background(), Qt::black, col ); + p->setBrush( col ); + p->drawRect( r ); + } + + + QRect rect = r; + Qt::ArrowType arrowType = opt.isDefault() ? Qt::DownArrow : opt.arrowType(); + + int shiftX = 0, shiftY = 0; + if( flags & ( Style_Down | Style_On ) ) + { + shiftX = pixelMetric(PM_ButtonShiftHorizontal, widget); + shiftY = pixelMetric(PM_ButtonShiftVertical, widget); + } + + if (!opt.isDefault()) + { + PrimitiveElement pe; + switch (arrowType) + { + case Qt::LeftArrow: pe = PE_ArrowLeft; break; + case Qt::RightArrow: pe = PE_ArrowRight; break; + case Qt::UpArrow: pe = PE_ArrowUp; break; + default: + case Qt::DownArrow: pe = PE_ArrowDown; break; + } + + rect.moveBy(shiftX, shiftY); + drawPrimitive(pe, p, rect, cg, flags, opt); + } + else + { + QColor btext = toolbutton->paletteForegroundColor(); + + if (toolbutton->iconSet().isNull() && + ! toolbutton->text().isNull() && + ! toolbutton->usesTextLabel()) + { + int alignment = AlignCenter | ShowPrefix; + if (!styleHint(SH_UnderlineAccelerator, widget, QStyleOption::Default, 0)) + alignment |= NoAccel; + + rect.moveBy(shiftX, shiftY); + drawItem( p, rect, alignment, cg, flags & Style_Enabled, 0, toolbutton->text(), + toolbutton->text().length(), &btext); + } + else + { + QPixmap pm; + QIconSet::Size size = + toolbutton->usesBigPixmap() ? QIconSet::Large : QIconSet::Small; + QIconSet::State state = toolbutton->isOn() ? QIconSet::On : QIconSet::Off; + QIconSet::Mode mode; + if( !toolbutton->isEnabled() ) + mode = QIconSet::Active; //QIconSet::Disabled; + else if( flags & (Style_Down | Style_On ) || ( flags & Style_Raised ) && (flags & Style_AutoRaise)) + mode = QIconSet::Active; + else + mode = QIconSet::Normal; + pm = toolbutton->iconSet().pixmap( size, mode, state ); + + if( toolbutton->usesTextLabel() ) + { + p->setFont( toolbutton->font() ); + QRect pr = rect, tr = rect; + int alignment = ShowPrefix; + if (!styleHint(SH_UnderlineAccelerator, widget, QStyleOption::Default, 0)) + alignment |= NoAccel; + + if( toolbutton->textPosition() == QToolButton::Under ) + { + int fh = p->fontMetrics().height(); + pr.addCoords( 0, 1, 0, -fh-3 ); + tr.addCoords( 0, pr.bottom(), 0, -3 ); + pr.moveBy(shiftX, shiftY); + drawItem( p, pr, AlignCenter, cg, TRUE, &pm, QString::null ); + alignment |= AlignCenter; + } + else + { + pr.setWidth( pm.width() + 8 ); + tr.addCoords( pr.right(), 0, 0, 0 ); + pr.moveBy(shiftX, shiftY); + + drawItem( p, pr, AlignCenter, cg, TRUE, &pm, QString::null ); + alignment |= AlignLeft | AlignVCenter; + } + + tr.moveBy(shiftX, shiftY); + drawItem( p, tr, alignment, cg, flags & Style_Enabled, 0, toolbutton->textLabel(), + toolbutton->textLabel().length(), &btext); + } + else + { + /*if( en && !highlight ) + mix( 0.6, pm, cg.background() ); + else*/ if( !en ) + { + toGrayscale( pm, 1.1 ); + mix( 0.8, pm, cg.background() ); + } + + rect.moveBy(shiftX, shiftY); + drawItem( p, rect, AlignCenter, cg, true, &pm, QString::null ); + } + } + } + } + break; + + case CE_TabBarTab: + { + QPen oldPen = p->pen(); + + QRect r2( r ); + bool selected = flags & Style_Selected; + + p->setPen( cg.midlight() ); + p->drawLine( r2.left(), r2.bottom(), r2.right(), r2.bottom() ); + + if ( !selected ) + r2.setRect( r2.left(), r2.top() + 1, r2.width(), r2.height() - 1 ); + else + r2.setRect( r2.left(), r2.top(), r2.width() - 2, r2.height() - 1 ); + + p->setPen( cg.foreground() ); + drawGradient( p, QRect( r2.left(), r2.top(), r2.width(), r2.height() - 1 ), + selected ? cg.highlight() : cg.dark(), cg.background(), UpToDown, linear ); + +// p->fillRect( r2.left(), r2.top(), r2.width(), r2.height() - 1, selected ? cg.highlight() : cg.background() ); + p->drawRect( r2.left(), r2.top(), r2.width(), r2.height() - 1 ); + + if ( selected ) + { + p->setPen( cg.shadow() ); + p->drawLine( r2.left() + 1, r2.bottom(), r2.right() + 1, r2.bottom() ); + p->drawLine( r2.right() + 1, r2.top() + 1, r2.right() + 1, r2.bottom() ); + } + + break; + } + + case CE_TabBarLabel: + { + QColorGroup tmp( cg ); + if ( flags & Style_Selected ) + tmp.setColor( QColorGroup::Foreground, tmp.highlightedText() ); + PARENT_STYLE::drawControl( element, p, widget, r, tmp, flags, opt ); + } + break; + + case CE_PushButton: + { + if ( flags & Style_Enabled && !( flags & Style_Down || flags & Style_On ) ) + { + const QPushButton* button = (const QPushButton*)widget; + QRect br = QRect( button->mapToGlobal( button->rect().topLeft() ), button->rect().size() ); + if ( br.contains( QCursor::pos() ) ) + flags |= Style_MouseOver; + } + + PARENT_STYLE::drawControl( element, p, widget, r, cg, flags, opt ); + break; + } + + default: + PARENT_STYLE::drawControl( element, p, widget, r, cg, flags, opt ); + break; + } +} + +QRect SalomeStyle::subRect( SubRect subrect, const QWidget* w ) const +{ + QRect r = PARENT_STYLE::subRect( subrect, w ); + if ( subrect==SR_DockWindowHandleRect && w->inherits( "QDockWindowHandle" ) ) + { + QDockWindow* wnd = ( QDockWindow* ) w->parent(); + if( wnd->orientation()==Qt::Vertical ) + r.setWidth( w->width() ); + else + { + r.setY( r.y()+r.height()-w->height() ); + r.setHeight( w->height() ); + } + } + + return r; +} + +void SalomeStyle::drawComplexControl( ComplexControl control, QPainter* p, const QWidget* widget, + const QRect& r, const QColorGroup& cg, SFlags flags, + SCFlags controls, SCFlags active, const QStyleOption& opt ) const +{ + + + + + ((SalomeStyle*)this)->myTitleParent = 0; + + switch ( control ) + { + case CC_ComboBox: + if ( controls & SC_ComboBoxArrow ) + { + SFlags flags = Style_Default; + + qDrawShadeRect( p, r, cg, true, pixelMetric( PM_DefaultFrameWidth, widget ), + 0, widget->isEnabled() ? &cg.brush( QColorGroup::Base ) : &cg.brush( QColorGroup::Background ) ); + + QRect ar = QStyle::visualRect( querySubControlMetrics( CC_ComboBox, widget, SC_ComboBoxArrow ), widget ); + if ( active == SC_ComboBoxArrow ) + { + p->setPen( cg.dark() ); + p->setBrush( cg.brush( QColorGroup::Button ) ); + p->drawRect( ar ); + } + else + qDrawWinPanel( p, ar, cg, FALSE, &cg.brush( QColorGroup::Button ) ); + + ar.addCoords( 2, 2, -2, -2 ); + if ( widget->isEnabled() ) + flags |= Style_Enabled; + + if ( active == SC_ComboBoxArrow ) + flags |= Style_Sunken; + drawPrimitive( PE_ArrowDown, p, ar, cg, flags ); + } + PARENT_STYLE::drawComplexControl( control, p, widget, r, cg, flags, controls & ~SC_ComboBoxArrow, active, opt ); + break; + + case CC_TitleBar: + if( widget->inherits( "QTitleBar" ) ) + ( ( SalomeStyle* )this )->myTitleParent = ( QWidget* )widget->parent(); + + default: + PARENT_STYLE::drawComplexControl( control, p, widget, r, cg, flags, controls, active, opt ); + break; + } +} + +QPixmap SalomeStyle::stylePixmap( StylePixmap st, const QWidget* w, const QStyleOption& opt ) const +{ + switch ( st ) + { + case SP_DockWindowCloseButton: + case SP_TitleBarCloseButton: + return QPixmap( cross_xpm ); + case SP_TitleBarMaxButton: + return QPixmap( maximize_xpm ); + case SP_TitleBarNormalButton: + return QPixmap( normal_xpm ); + case SP_TitleBarMinButton: + return QPixmap( minimize_xpm ); + default: + return PARENT_STYLE::stylePixmap( st, w, opt ); + } +} + +int SalomeStyle::pixelMetric( PixelMetric pm, const QWidget* widget ) const +{ + int ret = 0; + + switch ( pm ) + { + case PM_ButtonMargin: + ret = 5; + break; + case PM_DockWindowFrameWidth: + ret = 0; + break; + case PM_TabBarTabOverlap: + ret = 2; + break; + case PM_TabBarTabHSpace: + ret = 20; + break; + case PM_TabBarTabShiftHorizontal: + case PM_TabBarTabShiftVertical: + ret = 0; + break; + case PM_TabBarTabVSpace: + ret = 5; + break; + case PM_DefaultFrameWidth: + ret = 1; + break; + case PM_SpinBoxFrameWidth: + ret = 1; + break; + case PM_ProgressBarChunkWidth: + ret = 1; + break; + default: + ret = PARENT_STYLE::pixelMetric( pm, widget ); + break; + } + return ret; +} + +QString SalomeStyle::titleText( const QString& txt, const int W, const QFontMetrics& fm ) const +{ + QString res = txt.stripWhiteSpace(); + + if ( fm.width( res ) > W ) + { + QString end( "..." ); + while ( !res.isEmpty() && fm.width( res + end ) > W ) + res.remove( res.length() - 1, 1 ); + + if ( !res.isEmpty() ) + res += end; + } + + return res; +} + +/*! + Class: SalomeStylePlugin [Internal] + Descr: Plugin for Qt style mechanism +*/ + +SalomeStylePlugin::SalomeStylePlugin() +{ +} + +SalomeStylePlugin::~SalomeStylePlugin() +{ +} + +QStringList SalomeStylePlugin::keys() const +{ + return QStringList() << "salome"; +} + +QStyle* SalomeStylePlugin::create( const QString& str ) +{ + if ( str == "salome" ) + return new SalomeStyle(); + else + return 0; +} + +Q_EXPORT_PLUGIN( SalomeStylePlugin ) diff --git a/src/Style/SalomeStyle.h b/src/Style/SalomeStyle.h new file mode 100644 index 000000000..32eec36bf --- /dev/null +++ b/src/Style/SalomeStyle.h @@ -0,0 +1,111 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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. +// +// 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/ +// +#ifndef SALOMESTYLE_H +#define SALOMESTYLE_H + +#define parent_style qwindowsstyle +#define PARENT_STYLE QWindowsStyle + +#define QUOTE(x) #x +#define PARENT_INC(x) QUOTE(x.h) + +//#include PARENT_INC(parent_style) +#include + +#include +#include +#include + +#if defined SALOMESTYLE_EXPORTS +#if defined WIN32 +#define SALOMESTYLE_EXPORT _declspec( dllexport ) +#else +#define SALOMESTYLE_EXPORT +#endif +#else +#if defined WIN32 +#define SALOMESTYLE_EXPORT _declspec( dllimport ) +#else +#define SALOMESTYLE_EXPORT +#endif +#endif + +class QFontMetrics; + +class SALOMESTYLE_EXPORT SalomeStyle : public PARENT_STYLE +{ +public: + SalomeStyle(); + virtual ~SalomeStyle(); + + virtual void polish( QWidget* ); + + virtual bool eventFilter( QObject*, QEvent* ); + + static void mix( const double, QRgb&, const QRgb& ); + static void mix( const double, QPixmap&, const QColor& ); + static void mix( const double, const QColor&, const QColor&, QColor& ); + + static void toGrayscale( QPixmap&, double = 1.0 ); + + virtual void drawPrimitive( PrimitiveElement, QPainter*, const QRect&, + const QColorGroup&, SFlags = Style_Default, + const QStyleOption& = QStyleOption::Default ) const; + + virtual void drawControl( ControlElement, QPainter*, const QWidget*, + const QRect&, const QColorGroup&, SFlags = Style_Default, + const QStyleOption& = QStyleOption::Default ) const; + + virtual QRect subRect( SubRect, const QWidget* ) const; + + virtual void drawComplexControl( ComplexControl, QPainter*, const QWidget*, + const QRect&, const QColorGroup&, SFlags = Style_Default, + SCFlags = SC_All, SCFlags = SC_None, + const QStyleOption& = QStyleOption::Default ) const; + + virtual QPixmap stylePixmap( StylePixmap, const QWidget* = 0, + const QStyleOption& = QStyleOption::Default ) const; + + virtual int pixelMetric( PixelMetric, const QWidget* widget = 0 ) const; + +protected: + typedef enum { LeftToRight, RightToLeft, UpToDown, DownToUp } Direction; + + typedef double (*gradient_func)( double ); + + void drawGradient( QPainter*, const QRect&, const QColor&, + const QColor&, const Direction, gradient_func ) const; + + QString titleText( const QString&, const int, const QFontMetrics& ) const; + +private: + QWidget* myTitleParent; +}; + +class SalomeStylePlugin : public QStylePlugin +{ +public: + SalomeStylePlugin(); + virtual ~SalomeStylePlugin(); + + virtual QStringList keys() const; + virtual QStyle* create( const QString& ); +}; + +#endif