From 16cddd2365e63f8891fb4554e005372602696457 Mon Sep 17 00:00:00 2001 From: nds Date: Tue, 10 Jun 2008 07:16:15 +0000 Subject: [PATCH] Merge with BR_QT4_Dev branch --- src/ObjBrowser/OB_Browser.cxx | 22 +- src/ObjBrowser/OB_Browser.h | 2 + src/Plot2d/Plot2d_ViewWindow.cxx | 4 +- src/PyConsole/PyConsole.h | 40 +- src/PyConsole/PyConsole_Console.cxx | 175 ++- src/PyConsole/PyConsole_Console.h | 60 +- src/PyConsole/PyConsole_Editor.cxx | 175 ++- src/PyConsole/PyConsole_Editor.h | 41 +- src/PyConsole/PyConsole_Interp.cxx | 48 +- src/PyConsole/PyConsole_Interp.h | 6 +- src/PyInterp/PyInterp.h | 44 +- src/PyInterp/PyInterp_Dispatcher.cxx | 35 +- src/PyInterp/PyInterp_Dispatcher.h | 37 +- src/PyInterp/PyInterp_Interp.cxx | 449 +++++++ src/PyInterp/PyInterp_Interp.h | 116 ++ src/PyInterp/PyInterp_Watcher.h | 14 +- src/Qtx/Qtx.cxx | 39 +- src/Qtx/Qtx.h | 1 + src/Qtx/QtxAction.cxx | 12 +- src/Qtx/QtxActionMenuMgr.cxx | 8 +- src/Qtx/QtxActionMenuMgr.h | 4 +- src/Qtx/QtxActionMgr.cxx | 4 +- src/Qtx/QtxActionMgr.h | 4 +- src/Qtx/QtxActionToolMgr.cxx | 14 +- src/Qtx/QtxActionToolMgr.h | 5 +- src/Qtx/QtxColorScale.cxx | 6 +- src/Qtx/QtxColorScale.h | 12 +- src/Qtx/QtxComboBox.cxx | 2 +- src/Qtx/QtxListAction.cxx | 21 +- src/Qtx/QtxListAction.h | 5 +- src/Qtx/QtxMRUAction.cxx | 94 +- src/Qtx/QtxMRUAction.h | 9 + src/Qtx/QtxMainWindow.cxx | 6 +- src/Qtx/QtxMenu.cxx | 409 +++++++ src/Qtx/QtxMenu.h | 76 ++ src/Qtx/QtxPathDialog.h | 2 +- src/Qtx/QtxResourceMgr.cxx | 119 +- src/Qtx/QtxResourceMgr.h | 3 +- src/Qtx/QtxSplash.cxx | 607 +++++++--- src/Qtx/QtxSplash.h | 40 +- src/Qtx/QtxToolBar.cxx | 63 +- src/Qtx/QtxTreeView.cxx | 14 + src/Qtx/QtxTreeView.h | 4 + src/Qtx/QtxWorkstack.cxx | 20 +- src/Qtx/QtxWorkstack.h | 1 + src/STD/STD.h | 16 +- src/STD/STD_Application.cxx | 131 +- src/STD/STD_Application.h | 36 +- src/STD/STD_MDIDesktop.cxx | 110 +- src/STD/STD_MDIDesktop.h | 15 +- src/STD/STD_SDIDesktop.cxx | 7 +- src/STD/STD_TabDesktop.cxx | 102 +- src/STD/STD_TabDesktop.h | 10 +- src/STD/resources/STD_msg_en.po | 22 +- src/STD/resources/cascade.png | Bin 0 -> 430 bytes src/STD/resources/close.png | Bin 212 -> 1260 bytes src/STD/resources/copy.png | Bin 245 -> 843 bytes src/STD/resources/cursor_rotate.png | Bin 291 -> 0 bytes src/STD/resources/cursor_zoom.png | Bin 245 -> 0 bytes src/STD/resources/cut.png | Bin 211 -> 1206 bytes src/STD/resources/delete.png | Bin 0 -> 1344 bytes src/STD/resources/help.png | Bin 910 -> 1103 bytes src/STD/resources/htile.png | Bin 0 -> 343 bytes src/STD/resources/new.png | Bin 177 -> 667 bytes src/STD/resources/open.png | Bin 231 -> 1194 bytes src/STD/resources/paste.png | Bin 280 -> 1094 bytes src/STD/resources/print.png | Bin 233 -> 967 bytes src/STD/resources/redo.png | Bin 211 -> 885 bytes src/STD/resources/reset.png | Bin 232 -> 1032 bytes src/STD/resources/save.png | Bin 215 -> 1135 bytes src/STD/resources/undo.png | Bin 210 -> 873 bytes src/STD/resources/undo_arrow.png | Bin 895 -> 0 bytes src/STD/resources/vtile.png | Bin 0 -> 373 bytes src/SUIT/SUIT.h | 22 +- src/SUIT/SUIT_Application.cxx | 65 +- src/SUIT/SUIT_Application.h | 11 +- src/SUIT/SUIT_FileDlg.cxx | 1051 ++++++++++++----- src/SUIT/SUIT_FileDlg.h | 107 +- src/SUIT/SUIT_FileValidator.cxx | 200 +++- src/SUIT/SUIT_FileValidator.h | 25 +- src/SUIT/SUIT_Operation.cxx | 2 +- src/SUIT/SUIT_Operation.h | 2 +- src/SUIT/SUIT_ResourceMgr.h | 2 +- src/SUIT/SUIT_SelectionMgr.cxx | 3 +- src/SUIT/SUIT_SelectionMgr.h | 4 +- src/SUIT/SUIT_Session.cxx | 30 +- src/SUIT/SUIT_Session.h | 6 +- src/SUIT/SUIT_Study.cxx | 24 +- src/SUIT/SUIT_Study.h | 12 +- src/SUIT/SUIT_ViewManager.cxx | 6 + src/SUIT/SUIT_ViewManager.h | 2 + src/SUIT/SUIT_ViewWindow.cxx | 202 ++-- src/SUIT/SUIT_ViewWindow.h | 8 +- src/SUIT/resources/cascade.png | Bin 225 -> 0 bytes src/SUIT/resources/htile.png | Bin 871 -> 0 bytes src/SUIT/resources/vtile.png | Bin 876 -> 0 bytes src/SUITApp/SUITApp.cxx | 13 +- src/SUITApp/resources/SUITApp_msg_en.ts | 17 + src/SVTK/SVTK_CubeAxesDlg.h | 3 +- src/SVTK/SVTK_InteractorStyle.cxx | 56 +- src/SVTK/SVTK_InteractorStyle.h | 3 - src/SVTK/SVTK_MainWindow.cxx | 133 ++- src/SVTK/SVTK_MainWindow.h | 18 +- src/SVTK/SVTK_RectPicker.cxx | 19 +- src/SVTK/SVTK_Renderer.cxx | 8 +- src/SVTK/SVTK_Renderer.h | 3 +- src/SVTK/SVTK_Selector.cxx | 59 +- src/SVTK/SVTK_Selector.h | 11 + src/SVTK/SVTK_SelectorDef.h | 14 + src/SVTK/SVTK_View.cxx | 5 +- src/SVTK/SVTK_View.h | 3 +- src/SVTK/SVTK_ViewModel.cxx | 10 +- src/SVTK/SVTK_ViewWindow.cxx | 25 +- src/SVTK/SVTK_ViewWindow.h | 3 +- .../resources/vtk_view_graduated_axes.png | Bin 0 -> 650 bytes .../resources/vtk_view_rotation_point.png | Bin 0 -> 858 bytes src/SVTK/resources/vtk_view_scaling.png | Bin 0 -> 1128 bytes src/SVTK/resources/vtk_view_update_rate.png | Bin 0 -> 972 bytes src/Style/Style.qrc | 8 + src/Style/Style_Salome.cxx | 80 +- src/Style/Style_Salome.h | 4 + src/Style/Style_Tools.cxx | 71 ++ src/Style/Style_Tools.h | 2 + src/Style/images/critical.png | Bin 0 -> 2328 bytes src/Style/images/information.png | Bin 0 -> 2087 bytes src/Style/images/question.png | Bin 0 -> 2188 bytes src/Style/images/warning.png | Bin 0 -> 2198 bytes src/VTKViewer/VTKViewer_ConvexTool.cxx | 339 +++--- src/VTKViewer/VTKViewer_ConvexTool.h | 104 +- src/VTKViewer/VTKViewer_GeometryFilter.cxx | 2 + src/VTKViewer/VTKViewer_ViewManager.cxx | 37 - src/VTKViewer/VTKViewer_ViewManager.h | 3 - src/VTKViewer/VTKViewer_ViewWindow.cxx | 4 +- src/VTKViewer/resources/vtk_view_back.png | Bin 0 -> 432 bytes src/VTKViewer/resources/vtk_view_bottom.png | Bin 0 -> 428 bytes .../resources/vtk_view_camera_dump.png | Bin 0 -> 682 bytes src/VTKViewer/resources/vtk_view_fitall.png | Bin 0 -> 816 bytes src/VTKViewer/resources/vtk_view_fitarea.png | Bin 0 -> 912 bytes src/VTKViewer/resources/vtk_view_front.png | Bin 0 -> 410 bytes src/VTKViewer/resources/vtk_view_glpan.png | Bin 0 -> 1086 bytes src/VTKViewer/resources/vtk_view_left.png | Bin 0 -> 427 bytes src/VTKViewer/resources/vtk_view_pan.png | Bin 0 -> 982 bytes src/VTKViewer/resources/vtk_view_reset.png | Bin 0 -> 918 bytes src/VTKViewer/resources/vtk_view_right.png | Bin 0 -> 418 bytes src/VTKViewer/resources/vtk_view_rotate.png | Bin 0 -> 886 bytes src/VTKViewer/resources/vtk_view_top.png | Bin 0 -> 419 bytes src/VTKViewer/resources/vtk_view_triedre.png | Bin 0 -> 698 bytes src/VTKViewer/resources/vtk_view_zoom.png | Bin 0 -> 797 bytes src/src.pro | 31 + 149 files changed, 4312 insertions(+), 1881 deletions(-) create mode 100644 src/PyInterp/PyInterp_Interp.cxx create mode 100644 src/PyInterp/PyInterp_Interp.h create mode 100644 src/Qtx/QtxMenu.cxx create mode 100644 src/Qtx/QtxMenu.h create mode 100644 src/STD/resources/cascade.png delete mode 100755 src/STD/resources/cursor_rotate.png delete mode 100755 src/STD/resources/cursor_zoom.png create mode 100644 src/STD/resources/delete.png create mode 100644 src/STD/resources/htile.png delete mode 100755 src/STD/resources/undo_arrow.png create mode 100644 src/STD/resources/vtile.png delete mode 100755 src/SUIT/resources/cascade.png delete mode 100755 src/SUIT/resources/htile.png delete mode 100755 src/SUIT/resources/vtile.png create mode 100644 src/SUITApp/resources/SUITApp_msg_en.ts create mode 100755 src/SVTK/resources/vtk_view_graduated_axes.png create mode 100755 src/SVTK/resources/vtk_view_rotation_point.png create mode 100644 src/SVTK/resources/vtk_view_scaling.png create mode 100755 src/SVTK/resources/vtk_view_update_rate.png create mode 100644 src/Style/Style.qrc create mode 100644 src/Style/images/critical.png create mode 100644 src/Style/images/information.png create mode 100644 src/Style/images/question.png create mode 100644 src/Style/images/warning.png create mode 100755 src/VTKViewer/resources/vtk_view_back.png create mode 100755 src/VTKViewer/resources/vtk_view_bottom.png create mode 100755 src/VTKViewer/resources/vtk_view_camera_dump.png create mode 100755 src/VTKViewer/resources/vtk_view_fitall.png create mode 100755 src/VTKViewer/resources/vtk_view_fitarea.png create mode 100755 src/VTKViewer/resources/vtk_view_front.png create mode 100644 src/VTKViewer/resources/vtk_view_glpan.png create mode 100755 src/VTKViewer/resources/vtk_view_left.png create mode 100755 src/VTKViewer/resources/vtk_view_pan.png create mode 100755 src/VTKViewer/resources/vtk_view_reset.png create mode 100755 src/VTKViewer/resources/vtk_view_right.png create mode 100755 src/VTKViewer/resources/vtk_view_rotate.png create mode 100755 src/VTKViewer/resources/vtk_view_top.png create mode 100755 src/VTKViewer/resources/vtk_view_triedre.png create mode 100755 src/VTKViewer/resources/vtk_view_zoom.png create mode 100644 src/src.pro diff --git a/src/ObjBrowser/OB_Browser.cxx b/src/ObjBrowser/OB_Browser.cxx index 57e90af4d..8bdb6ddd2 100755 --- a/src/ObjBrowser/OB_Browser.cxx +++ b/src/ObjBrowser/OB_Browser.cxx @@ -37,6 +37,7 @@ #include #include #include +#include #include @@ -459,6 +460,25 @@ void OB_Browser::adjustWidth() myView->resizeColumnToContents( 0 ); } +/*! + \brief Adjust first column width to its contents. +*/ +void OB_Browser::adjustFirstColumnWidth() +{ + myView->resizeColumnToContents( 0 ); +} + +/*! + \brief Adjust all columns width to its contents except the first column. +*/ +void OB_Browser::adjustColumnsWidth() +{ + for ( int aCol = 1; aCol < myView->header()->count(); aCol++ ) { + if ( myView->columnWidth( aCol ) > 0 ) + myView->resizeColumnToContents( aCol ); + } +} + /*! \return SUIT object correspondint to item at position 'pos' \param pos - position @@ -980,7 +1000,7 @@ void OB_Browser::createPopupMenu( QMenu* menu ) if ( isSearchToolEnabled() ) { menu->addSeparator(); - menu->addAction( tr( "MEN_FIND" ), searchTool(), SLOT( find() ) ); + menu->addAction( tr( "MEN_FIND" ), searchTool(), SLOT( find() ), QKeySequence(Qt::CTRL + Qt::Key_F) ); menu->addSeparator(); } } diff --git a/src/ObjBrowser/OB_Browser.h b/src/ObjBrowser/OB_Browser.h index 1979c8100..289b5ce6a 100755 --- a/src/ObjBrowser/OB_Browser.h +++ b/src/ObjBrowser/OB_Browser.h @@ -86,6 +86,8 @@ public: virtual void setOpen( const QModelIndex& theObject, const bool theOpen = true ); void adjustWidth(); + void adjustFirstColumnWidth(); + void adjustColumnsWidth(); // san - To be revised or removed // QTreeView::indexAt() should be used diff --git a/src/Plot2d/Plot2d_ViewWindow.cxx b/src/Plot2d/Plot2d_ViewWindow.cxx index 2d8f3d9df..aaaf1046d 100755 --- a/src/Plot2d/Plot2d_ViewWindow.cxx +++ b/src/Plot2d/Plot2d_ViewWindow.cxx @@ -391,7 +391,7 @@ void Plot2d_ViewWindow::createActions() tr( "MNU_PRINT_VIEW" ), 0, this); aAction->setStatusTip( tr( "DSC_PRINT_VIEW" ) ); - connect( aAction, SIGNAL( activated() ), this, SLOT( onPrintView() ) ); + connect( aAction, SIGNAL( triggered( bool ) ), this, SLOT( onPrintView() ) ); myActionsMap[ PrintId ] = aAction; // Set initial values @@ -637,7 +637,7 @@ void Plot2d_ViewWindow::onPrintView() if ( !myViewFrame ) return; -#ifndef WIN32 +#if !defined(WIN32) && !defined(QT_NO_CUPS) #if QT_VERSION < 0x040303 if ( !Qtx::hasAnyPrinters() ) { SUIT_MessageBox::warning( this, tr( "WRN_WARNING" ), diff --git a/src/PyConsole/PyConsole.h b/src/PyConsole/PyConsole.h index 10a7106f6..d27c40c0f 100644 --- a/src/PyConsole/PyConsole.h +++ b/src/PyConsole/PyConsole.h @@ -16,39 +16,25 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#if !defined ( _PYTHONCONSOLE_H ) -#define _PYTHONCONSOLE_H +// File : PyConsole.h +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) +// + +#if !defined ( PYCONSOLE_H ) +#define PYCONSOLE_H // ======================================================== // set dllexport type for Win platform #ifdef WIN32 - -#ifdef PYCONSOLE_EXPORTS -#define PYCONSOLE_EXPORT __declspec(dllexport) -#else -#define PYCONSOLE_EXPORT __declspec(dllimport) -#endif - +# ifdef PYCONSOLE_EXPORTS +# define PYCONSOLE_EXPORT __declspec(dllexport) +# else +# define PYCONSOLE_EXPORT __declspec(dllimport) +# endif #else // WIN32 - -#define PYCONSOLE_EXPORT - +# define PYCONSOLE_EXPORT #endif // WIN32 -// ======================================================== -// 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 WIN32 @@ -56,4 +42,4 @@ #pragma warning (disable : 4251) #endif -#endif // _PYTHONCONSOLE_H +#endif // PYCONSOLE_H diff --git a/src/PyConsole/PyConsole_Console.cxx b/src/PyConsole/PyConsole_Console.cxx index 85ba6c722..85df7307a 100644 --- a/src/PyConsole/PyConsole_Console.cxx +++ b/src/PyConsole/PyConsole_Console.cxx @@ -16,30 +16,27 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// File : PythonConsole_PyConcole.cxx -// Author : Vadim SANDLER -// Module : SALOME +// File : PyConsole_Console.cxx +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) +// /*! - \class PythonConsole + \class PyConsole_Console \brief Python console widget. */ -#include - +#include "PyConsole_Interp.h" /// !!! WARNING !!! THIS INCLUDE MUST BE VERY FIRST !!! #include "PyConsole_Console.h" #include "PyConsole_Editor.h" -#include - -#include -#include -#include -#include -#include -#include +#include -using namespace std; +#include +#include +#include +#include +#include +#include /*! \brief Constructor. @@ -48,9 +45,9 @@ using namespace std; \param parent parent widget \param interp python interpreter */ -PythonConsole::PythonConsole( QWidget* parent, PyInterp_base* interp ) -: QFrame( parent ), -myEditor( 0 ) +PyConsole_Console::PyConsole_Console( QWidget* parent, PyConsole_Interp* interp ) +: QWidget( parent ), + myEditor( 0 ) { // create python interpreter myInterp = interp; @@ -62,7 +59,7 @@ myEditor( 0 ) // create editor console QVBoxLayout* lay = new QVBoxLayout( this ); - lay->setMargin( 5 ); + lay->setMargin( 0 ); myEditor = new PyConsole_Editor( myInterp, this ); myEditor->viewport()->installEventFilter( this ); lay->addWidget( myEditor ); @@ -75,15 +72,15 @@ myEditor( 0 ) Does nothing for the moment. */ -PythonConsole::~PythonConsole() +PyConsole_Console::~PyConsole_Console() { } /*! \brief Execute python command in the interpreter. - \param command - string with command and arguments + \param command string with command and arguments */ -void PythonConsole::exec( const QString& command ) +void PyConsole_Console::exec( const QString& command ) { if ( myEditor ) myEditor->exec( command ); @@ -94,29 +91,45 @@ void PythonConsole::exec( const QString& command ) and wait until it is finished. Block execution of main application until the python command is executed. - \param command - string with command and arguments + \param command string with command and arguments */ -void PythonConsole::execAndWait( const QString& command ) +void PyConsole_Console::execAndWait( const QString& command ) { if ( myEditor ) myEditor->execAndWait( command ); } -bool PythonConsole::isSync() const +/*! + \brief Get synchronous mode flag value. + + \sa setIsSync() + \return True if python console works in synchronous mode +*/ +bool PyConsole_Console::isSync() const { return myEditor->isSync(); } -void PythonConsole::setIsSync( const bool s ) +/*! + \brief Set synchronous mode flag value. + + In synhronous mode the Python commands are executed in the GUI thread + and the GUI is blocked until the command is finished. In the asynchronous + mode each Python command is executed in the separate thread that does not + block the main GUI loop. + + \param on synhronous mode flag +*/ +void PyConsole_Console::setIsSync( const bool on ) { - myEditor->setIsSync( s ); + myEditor->setIsSync( on ); } /*! \brief Change the python console's font. - \param f - new font + \param f new font */ -void PythonConsole::setFont( const QFont& f ) +void PyConsole_Console::setFont( const QFont& f ) { if( myEditor ) myEditor->setFont( f ); @@ -126,7 +139,7 @@ void PythonConsole::setFont( const QFont& f ) \brief Get python console font. \return current python console's font */ -QFont PythonConsole::font() const +QFont PyConsole_Console::font() const { QFont res; if( myEditor ) @@ -135,60 +148,112 @@ QFont PythonConsole::font() const } /*! - Custom event handler + \brief Event handler. + + Handles context menu request event. + + \param o object + \param e event + \return True if the event is processed and further processing should be stopped */ -bool PythonConsole::eventFilter( QObject* o, QEvent* e ) +bool PyConsole_Console::eventFilter( QObject* o, QEvent* e ) { if ( o == myEditor->viewport() && e->type() == QEvent::ContextMenu ) { contextMenuRequest( (QContextMenuEvent*)e ); return true; } - return QFrame::eventFilter( o, e ); + return QWidget::eventFilter( o, e ); } /*! - \brief Process context popup menu event. + \brief Create the context popup menu. + + Fill in the popup menu with the commands. - Show popup menu which includes standard copy/paste operations. - \param event context menu event + \param menu context popup menu */ -void PythonConsole::contextMenuPopup( QMenu* menu ) +void PyConsole_Console::contextMenuPopup( QMenu* menu ) { if ( myEditor->isReadOnly() ) return; - updateActions(); - menu->addAction( myActions[CopyId] ); menu->addAction( myActions[PasteId] ); menu->addAction( myActions[ClearId] ); - menu->addSeparator(); - menu->addAction( myActions[SelectAllId] ); + + Qtx::simplifySeparators( menu ); + + updateActions(); } -void PythonConsole::createActions() +/*! + \brief Set actions to be visible in the context popup menu. + + Actions, which IDs are set in \a flags parameter, will be shown in the + context popup menu. Other actions will not be shown. + + \param flags ORed together actions flags +*/ +void PyConsole_Console::setMenuActions( const int flags ) { - QAction* copyAction = new QAction( tr( "EDIT_COPY_CMD" ), this ); - connect( copyAction, SIGNAL( triggered( bool ) ), myEditor, SLOT( copy() ) ); - myActions.insert( CopyId, copyAction ); + myActions[CopyId]->setVisible( flags & CopyId ); + myActions[PasteId]->setVisible( flags & PasteId ); + myActions[ClearId]->setVisible( flags & ClearId ); + myActions[SelectAllId]->setVisible( flags & SelectAllId ); +} - QAction* pasteAction = new QAction( tr( "EDIT_PASTE_CMD" ), this ); - connect( pasteAction, SIGNAL( triggered( bool ) ), myEditor, SLOT( paste() ) ); - myActions.insert( PasteId, pasteAction ); +/*! + \brief Get menu actions which are currently visible in the context popup menu. + \return ORed together actions flags + \sa setMenuActions() +*/ +int PyConsole_Console::menuActions() const +{ + int ret = 0; + ret = ret | ( myActions[CopyId]->isVisible() ? CopyId : 0 ); + ret = ret | ( myActions[PasteId]->isVisible() ? PasteId : 0 ); + ret = ret | ( myActions[ClearId]->isVisible() ? ClearId : 0 ); + ret = ret | ( myActions[SelectAllId]->isVisible() ? SelectAllId : 0 ); + return ret; +} - QAction* clearAction = new QAction( tr( "EDIT_CLEAR_CMD" ), this ); - connect( clearAction, SIGNAL( triggered( bool ) ), myEditor, SLOT( clear() ) ); - myActions.insert( ClearId, clearAction ); +/*! + \brief Create menu actions. + + Create context popup menu actions. +*/ +void PyConsole_Console::createActions() +{ + QAction* a = new QAction( tr( "EDIT_COPY_CMD" ), this ); + a->setStatusTip( tr( "EDIT_COPY_CMD" ) ); + connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( copy() ) ); + myActions.insert( CopyId, a ); + + a = new QAction( tr( "EDIT_PASTE_CMD" ), this ); + a->setStatusTip( tr( "EDIT_PASTE_CMD" ) ); + connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( paste() ) ); + myActions.insert( PasteId, a ); - QAction* selAllAction = new QAction( tr( "EDIT_SELECTALL_CMD" ), this ); - connect( selAllAction, SIGNAL( triggered( bool ) ), myEditor, SLOT( selectAll() ) ); - myActions.insert( SelectAllId, selAllAction ); + a = new QAction( tr( "EDIT_CLEAR_CMD" ), this ); + a->setStatusTip( tr( "EDIT_CLEAR_CMD" ) ); + connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( clear() ) ); + myActions.insert( ClearId, a ); + + a = new QAction( tr( "EDIT_SELECTALL_CMD" ), this ); + a->setStatusTip( tr( "EDIT_SELECTALL_CMD" ) ); + connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( selectAll() ) ); + myActions.insert( SelectAllId, a ); } -void PythonConsole::updateActions() +/*! + \brief Update menu actions. + + Update context popup menu action state. +*/ +void PyConsole_Console::updateActions() { myActions[CopyId]->setEnabled( myEditor->textCursor().hasSelection() ); myActions[PasteId]->setEnabled( !myEditor->isReadOnly() && !QApplication::clipboard()->text().isEmpty() ); diff --git a/src/PyConsole/PyConsole_Console.h b/src/PyConsole/PyConsole_Console.h index b25f4d191..ed1203b83 100644 --- a/src/PyConsole/PyConsole_Console.h +++ b/src/PyConsole/PyConsole_Console.h @@ -16,65 +16,69 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// File : PythonConsole_PyConsole.h -// Author : Vadim SANDLER -// Module : SALOME +// File : PyConsole_Console.h +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) +// #ifndef PYCONSOLE_CONSOLE_H #define PYCONSOLE_CONSOLE_H #include "PyConsole.h" -#include -#include - #include +#include +#include -class PyInterp_base; +class PyConsole_Interp; class PyConsole_Editor; -class PYCONSOLE_EXPORT PythonConsole : public QFrame, public SUIT_PopupClient +class PYCONSOLE_EXPORT PyConsole_Console : public QWidget, public SUIT_PopupClient { Q_OBJECT public: + //! Context popup menu actions flags enum { - CopyId = 0x01, - PasteId = 0x02, - ClearId = 0x04, - SelectAllId = 0x08, - All = CopyId | PasteId | ClearId | SelectAllId + CopyId = 0x01, //!< "Copy" menu action + PasteId = 0x02, //!< "Paste" menu action + ClearId = 0x04, //!< "Clear" menu action + SelectAllId = 0x08, //!< "Select All" menu action + All = CopyId | PasteId | ClearId | SelectAllId //!< all menu actions }; public: - PythonConsole( QWidget* parent, PyInterp_base* interp = 0 ); - virtual ~PythonConsole(); + PyConsole_Console( QWidget* parent, PyConsole_Interp* interp = 0 ); + virtual ~PyConsole_Console(); //! \brief Get python interperter - PyInterp_base* getInterp() { return myInterp; } - QFont font() const; - virtual void setFont( const QFont& ); + PyConsole_Interp* getInterp() { return myInterp; } + QFont font() const; + virtual void setFont( const QFont& ); + + bool isSync() const; + void setIsSync( const bool ); - bool isSync() const; - void setIsSync( const bool ); + void exec( const QString& ); + void execAndWait( const QString& ); - void exec( const QString& command ); - void execAndWait( const QString& command ); + virtual bool eventFilter( QObject*, QEvent* ); - virtual bool eventFilter( QObject* o, QEvent* e ); + //! \brief Get popup client symbolic name + virtual QString popupClientType() const { return QString( "PyConsole" ); } + virtual void contextMenuPopup( QMenu* ); - virtual QString popupClientType() const { return QString( "PyConsole" ); } - virtual void contextMenuPopup( QMenu* ); + void setMenuActions( const int ); + int menuActions() const; private: void createActions(); void updateActions(); private: - PyInterp_base* myInterp; //!< python interpreter + PyConsole_Interp* myInterp; //!< python interpreter PyConsole_Editor* myEditor; //!< python console editor widget - QMap myActions; + QMap myActions; //!< menu actions list }; -#endif +#endif // PYCONSOLE_CONSOLE_H diff --git a/src/PyConsole/PyConsole_Editor.cxx b/src/PyConsole/PyConsole_Editor.cxx index 23268097e..fea5d6804 100644 --- a/src/PyConsole/PyConsole_Editor.cxx +++ b/src/PyConsole/PyConsole_Editor.cxx @@ -19,9 +19,9 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// File : PyConsole_Editor.cxx -// Author : Vadim SANDLER -// Module : SALOME +// File : PyConsole_Editor.cxx +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) +// /*! \class PyConsole_Editor @@ -92,32 +92,35 @@ - the same for drag-n-drop of multiline text */ -#include "PyConsole_Editor.h" // this include must be first (see PyInterp_base.h)! - +#include "PyConsole_Interp.h" // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!! +#include "PyConsole_Editor.h" #include #include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include static QString READY_PROMPT = ">>> "; static QString DOTS_PROMPT = "... "; #define PROMPT_SIZE myPrompt.length() +#define PRINT_EVENT 65432 + /*! \class ExecCommand - \brief Python command execution request [internal]. - */ + \brief Python command execution request. + \internal +*/ + class ExecCommand : public PyInterp_LockRequest { public: @@ -130,7 +133,7 @@ public: \param theListener widget to get the notification messages \param sync if True the request is processed synchronously */ - ExecCommand( PyInterp_base* theInterp, + ExecCommand( PyInterp_Interp* theInterp, const QString& theCommand, PyConsole_Editor* theListener, bool sync = false ) @@ -147,21 +150,12 @@ protected: { if ( myCommand != "" ) { -// SUIT_Session::SetPythonExecuted( true ); // disable GUI user actions int ret = getInterp()->run( myCommand.toLatin1() ); -// SUIT_Session::SetPythonExecuted(false); // enable GUI user actions if ( ret < 0 ) - myState = PyInterp_Event::ERROR; + myState = PyInterp_Event::ERROR; else if ( ret > 0 ) - myState = PyInterp_Event::INCOMPLETE; - myError = getInterp()->getverr().c_str(); - myOutput = getInterp()->getvout().c_str(); + myState = PyInterp_Event::INCOMPLETE; } - else - { - myError = ""; - myOutput = ""; - } } /*! @@ -170,18 +164,45 @@ protected: */ virtual QEvent* createEvent() const { + if ( IsSync() ) + QCoreApplication::sendPostedEvents( listener(), PRINT_EVENT ); return new PyInterp_Event( myState, (PyInterp_Request*)this ); } -public: - QString myError; //!< Python command error message - QString myOutput; //!< Python command output log - private: QString myCommand; //!< Python command int myState; //!< Python command execution status }; +/*! + \class PrintEvent + \brief Python command output backend event. + \internal +*/ + +class PrintEvent : public QEvent +{ +public: + /*! + \brief Constructor + \param c message text (python trace) + */ + PrintEvent( const char* c ) : QEvent( (QEvent::Type)PRINT_EVENT ), myText( c ) {} + /*! + \brief Get message + \return message text (python trace) + */ + QString text() const { return myText; } + +private: + QString myText; //!< Event message (python trace) +}; + +void staticCallback( void* data, char* c ) +{ + QApplication::postEvent( (PyConsole_Editor*)data, new PrintEvent( c ) ); +} + /*! \brief Constructor. @@ -189,8 +210,8 @@ private: \param theInterp python interper \param theParent parent widget */ -PyConsole_Editor::PyConsole_Editor( PyInterp_base* theInterp, - QWidget* theParent ) +PyConsole_Editor::PyConsole_Editor( PyConsole_Interp* theInterp, + QWidget* theParent ) : QTextEdit( theParent ), myInterp( 0 ), myCmdInHistory( -1 ), @@ -203,10 +224,13 @@ PyConsole_Editor::PyConsole_Editor( PyInterp_base* theInterp, setUndoRedoEnabled( false ); myPrompt = READY_PROMPT; - setLineWrapMode( QTextEdit::NoWrap ); - setWordWrapMode( QTextOption::NoWrap ); + setLineWrapMode( QTextEdit::WidgetWidth ); + setWordWrapMode( QTextOption::WrapAnywhere ); setAcceptRichText( false ); + theInterp->setvoutcb( staticCallback, this ); + theInterp->setverrcb( staticCallback, this ); + // san - This is necessary for troubleless initialization onPyInterpChanged( theInterp ); } @@ -220,14 +244,30 @@ PyConsole_Editor::~PyConsole_Editor() { } +/*! + \brief Get synchronous mode flag value. + + \sa setIsSync() + \return True if python console works in synchronous mode +*/ bool PyConsole_Editor::isSync() const { return myIsSync; } -void PyConsole_Editor::setIsSync( const bool s ) +/*! + \brief Set synchronous mode flag value. + + In synhronous mode the Python commands are executed in the GUI thread + and the GUI is blocked until the command is finished. In the asynchronous + mode each Python command is executed in the separate thread that does not + block the main GUI loop. + + \param on synhronous mode flag +*/ +void PyConsole_Editor::setIsSync( const bool on ) { - myIsSync = s; + myIsSync = on; } /*! @@ -236,7 +276,7 @@ void PyConsole_Editor::setIsSync( const bool s ) \param newBlock if True, then the string is printed on a new line */ void PyConsole_Editor::addText( const QString& str, - const bool newBlock ) + const bool newBlock ) { moveCursor( QTextCursor::End ); if ( newBlock ) @@ -288,14 +328,20 @@ void PyConsole_Editor::exec( const QString& command ) PyInterp_Dispatcher::Get()->Exec( createRequest( cmd ) ); } -PyInterp_Request* PyConsole_Editor::createRequest( const QString& cmd ) +/*! + \brief Create request to the python dispatcher for the command execution. + + \param command python command to be executed + */ +PyInterp_Request* PyConsole_Editor::createRequest( const QString& command ) { - return new ExecCommand( myInterp, cmd, this, isSync() ); + return new ExecCommand( myInterp, command, this, isSync() ); } /*! \brief Execute command in the python interpreter and wait until it is finished. + \param command python command to be executed */ void PyConsole_Editor::execAndWait( const QString& command ) @@ -333,6 +379,9 @@ void PyConsole_Editor::handleReturn() // add command to the history if ( !cmd.trimmed().isEmpty() ) myHistory.push_back( cmd ); + + // IPAL19397 + addText( "", true ); // set read-only mode setReadOnly( true ); @@ -566,7 +615,7 @@ void PyConsole_Editor::keyPressEvent( QKeyEvent* event ) moveCursor( QTextCursor::End ); moveCursor( QTextCursor::StartOfBlock, QTextCursor::KeepAnchor ); textCursor().removeSelectedText(); - addText( myPrompt + ( nextCommand != TOP_HISTORY_PY ? nextCommand : myCurrentCommand ) ); + addText( myPrompt + nextCommand ); // move cursor to the end moveCursor( QTextCursor::End ); } @@ -851,25 +900,24 @@ void PyConsole_Editor::customEvent( QEvent* event ) { switch( event->type() ) { + case PRINT_EVENT: + { + PrintEvent* pe=(PrintEvent*)event; + addText( pe->text() ); + return; + } case PyInterp_Event::OK: case PyInterp_Event::ERROR: { - PyInterp_Event* pe = dynamic_cast( event ); - if ( pe ) - { - ExecCommand* ec = dynamic_cast( pe->GetRequest() ); - if ( ec ) - { - // The next line has appeared dangerous in case if - // Python command execution has produced very large output. - // A more clever approach is needed... - // print python output - addText( ec->myOutput, true ); - addText( ec->myError ); - } - } // clear command buffer myCommandBuffer.truncate( 0 ); + // add caret return line if necessary + QTextBlock par = document()->end().previous(); + QString txt = par.text(); + txt.truncate( txt.length() - 1 ); + // IPAL19397 : addText moved to handleReturn() method + //if ( !txt.isEmpty() ) + // addText( "", true ); // set "ready" prompt myPrompt = READY_PROMPT; addText( myPrompt ); @@ -884,9 +932,16 @@ void PyConsole_Editor::customEvent( QEvent* event ) { // extend command buffer (multi-line command) myCommandBuffer.append( "\n" ); + // add caret return line if necessary + QTextBlock par = document()->end().previous(); + QString txt = par.text(); + txt.truncate( txt.length() - 1 ); + // IPAL19397 : addText moved to handleReturn() method + //if ( !txt.isEmpty() ) + // addText( "", true ); // set "dot" prompt myPrompt = DOTS_PROMPT; - addText( myPrompt, true ); + addText( myPrompt/*, true*/ ); // IPAL19397 // unset busy cursor unsetCursor(); // stop event loop (if running) @@ -918,7 +973,7 @@ void PyConsole_Editor::customEvent( QEvent* event ) Perform initialization actions if the interpreter is changed. \param interp python interpreter is being set */ -void PyConsole_Editor::onPyInterpChanged( PyInterp_base* interp ) +void PyConsole_Editor::onPyInterpChanged( PyConsole_Interp* interp ) { if ( myInterp != interp // Force read-only state and wait cursor when myInterp is NULL diff --git a/src/PyConsole/PyConsole_Editor.h b/src/PyConsole/PyConsole_Editor.h index 12deee059..222708c6e 100644 --- a/src/PyConsole/PyConsole_Editor.h +++ b/src/PyConsole/PyConsole_Editor.h @@ -19,28 +19,27 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// File : PyConsole_Editor.h -// Author : Vadim SANDLER -// Module : SALOME +// File : PyConsole_Editor.h +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) +// #ifndef PYCONSOLE_EDITOR_H #define PYCONSOLE_EDITOR_H -#include "PyConsole_Interp.h" // this include must be first (see PyInterp_base.h)! +#include "PyConsole.h" -#include +#include -class QMenu; -class QEventLoop; class PyConsole_Interp; class PyInterp_Request; +class QEventLoop; class PYCONSOLE_EXPORT PyConsole_Editor : public QTextEdit { Q_OBJECT; public: - PyConsole_Editor( PyInterp_base* theInterp, QWidget *theParent = 0 ); + PyConsole_Editor( PyConsole_Interp* theInterp, QWidget *theParent = 0 ); ~PyConsole_Editor(); virtual void addText( const QString& str, const bool newBlock = false ); @@ -59,26 +58,26 @@ protected: virtual void customEvent( QEvent* event); virtual PyInterp_Request* createRequest( const QString& ); - + public slots: void cut(); void paste(); void clear(); void handleReturn(); - void onPyInterpChanged( PyInterp_base* ); + void onPyInterpChanged( PyConsole_Interp* ); private: - PyInterp_base* myInterp; //!< python interpreter + PyConsole_Interp* myInterp; //!< python interpreter - QString myCommandBuffer; //!< python comman buffer - QString myCurrentCommand; //!< currently being printed command - QString myPrompt; //!< current command line prompt - int myCmdInHistory; //!< current history command index - QStringList myHistory; //!< commands history buffer - QEventLoop* myEventLoop; //!< internal event loop - QString myBanner; //!< current banner - QStringList myQueue; //!< python commands queue - bool myIsSync; + QString myCommandBuffer; //!< python comman buffer + QString myCurrentCommand; //!< currently being printed command + QString myPrompt; //!< current command line prompt + int myCmdInHistory; //!< current history command index + QStringList myHistory; //!< commands history buffer + QEventLoop* myEventLoop; //!< internal event loop + QString myBanner; //!< current banner + QStringList myQueue; //!< python commands queue + bool myIsSync; //!< synchronous mode flag }; -#endif +#endif // PYCONSOLE_EDITOR_H diff --git a/src/PyConsole/PyConsole_Interp.cxx b/src/PyConsole/PyConsole_Interp.cxx index b71c02178..234e55973 100644 --- a/src/PyConsole/PyConsole_Interp.cxx +++ b/src/PyConsole/PyConsole_Interp.cxx @@ -30,21 +30,32 @@ \brief Python interpreter to be embedded to the SALOME study's GUI. Python interpreter is created one per SALOME study. - Calls initialize method defined in the base class, which calls redefined - virtual methods initState() & initContext(). + + Call initialize method defined in the base class PyInterp_Interp, + to intialize interpreter after instance creation. + + The method initialize() calls virtuals methods + - initPython() to initialize global Python interpreter + - initState() to initialize embedded interpreter state + - initContext() to initialize interpreter internal context + - initRun() to prepare interpreter for running commands /EDF-CCAR/ When SALOME uses multi Python interpreter feature, every study has its own interpreter and thread state (_tstate = Py_NewInterpreter()). - This is fine because every study has its own modules (sys.modules) stdout and stderr.
+ This is fine because every study has its own modules (sys.modules) stdout and stderr. + But some Python modules must be imported only once. In multi interpreter context Python modules (*.py) are imported several times. - For example, the pyqt module must be imported only once because + For example, the PyQt module must be imported only once because it registers classes in a C module. + It's quite the same with omniorb modules (internals and generated with omniidl). + This problem is handled with "shared modules" defined in salome_shared_modules.py. These "shared modules" are imported only once and only copied in all - the other interpreters.
+ the other interpreters. + But it's not the only problem. Every interpreter has its own __builtin__ module. That's fine but if we have copied some modules and imported others problems may arise with operations that are not allowed @@ -52,14 +63,12 @@ have identical __builtin__ module. */ -using namespace std; - /*! \brief Constructor. Creates new python interpreter. */ -PyConsole_Interp::PyConsole_Interp(): PyInterp_base() +PyConsole_Interp::PyConsole_Interp(): PyInterp_Interp() { } @@ -74,32 +83,15 @@ PyConsole_Interp::~PyConsole_Interp() /*! \brief Initialize internal Python interpreter state. + \return \c true on success */ bool PyConsole_Interp::initState() { // The GIL is acquired and will be held on initState output // It is the caller responsability to release the lock if needed - -/* LLS PyEval_AcquireLock(); _tstate = Py_NewInterpreter(); // create an interpreter and save current state - PySys_SetArgv(PyInterp_base::_argc,PyInterp_base::_argv); // initialize sys.argv -*/ - - PyEval_AcquireLock(); -#ifdef WIN32 - _tstate = PyGILState_GetThisThreadState(); - // if no thread state defined - if ( _tstate ) - PyThreadState_Swap(_tstate); - else -#endif - { - _tstate = Py_NewInterpreter(); // create an interpreter and save current state - PySys_SetArgv(PyInterp_base::_argc,PyInterp_base::_argv); // initialize sys.argv - //if(MYDEBUG) MESSAGE("PythonConsole_PyInterp::initState - this = "< // this include must be first (see PyInterp_base.h)! +#include /// !!! WARNING !!! THIS INCLUDE MUST BE VERY FIRST !!! -class PYCONSOLE_EXPORT PyConsole_Interp : public PyInterp_base +class PYCONSOLE_EXPORT PyConsole_Interp : public PyInterp_Interp { public: PyConsole_Interp(); @@ -41,4 +41,4 @@ protected: virtual bool initContext(); }; -#endif +#endif // PYCONSOLE_INTERP_H diff --git a/src/PyInterp/PyInterp.h b/src/PyInterp/PyInterp.h index 86772a124..eab58424e 100755 --- a/src/PyInterp/PyInterp.h +++ b/src/PyInterp/PyInterp.h @@ -16,38 +16,40 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#if !defined ( _PYINTERP_H ) -#define _PYINTERP_H +// File : PyInterp.h +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) +// + +#if !defined ( PYINTERP_H ) +#define PYINTERP_H // ======================================================== // set dllexport type for Win platform #ifdef WIN32 - -#ifdef PYINTERP_EXPORTS -#define PYINTERP_EXPORT __declspec(dllexport) -#else -#define PYINTERP_EXPORT __declspec(dllimport) -#endif - +# ifdef PYINTERP_EXPORTS +# define PYINTERP_EXPORT __declspec(dllexport) +# else +# define PYINTERP_EXPORT __declspec(dllimport) +# endif #else // WIN32 - -#define PYINTERP_EXPORT - +# define PYINTERP_EXPORT #endif // WIN32 // ======================================================== -// little trick - we do not have debug python libraries +// little trick - if we do not have debug python libraries #ifdef _DEBUG - -#undef _DEBUG -#include -#define _DEBUG - -#else // _DEBUG + #ifndef HAVE_DEBUG_PYTHON + #undef _DEBUG + #endif +#endif #include -#endif // _DEBUG +#ifdef _DEBUG + #ifndef HAVE_DEBUG_PYTHON + #define _DEBUG + #endif +#endif // ======================================================== // avoid warning messages @@ -56,4 +58,4 @@ #pragma warning (disable : 4251) #endif -#endif // _PYINTERP_H +#endif // PYINTERP_H diff --git a/src/PyInterp/PyInterp_Dispatcher.cxx b/src/PyInterp/PyInterp_Dispatcher.cxx index 917298417..e3adb001d 100755 --- a/src/PyInterp/PyInterp_Dispatcher.cxx +++ b/src/PyInterp/PyInterp_Dispatcher.cxx @@ -16,20 +16,16 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SALOME SALOMEGUI : implementation of desktop and GUI kernel -// // File : PyInterp_Dispatcher.cxx // Author : Sergey ANIKIN, OCC // Module : GUI -// $Header$ - -#include "PyInterp_base.h" +#include "PyInterp_Dispatcher.h" // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!! +#include "PyInterp_Interp.h" #include "PyInterp_Watcher.h" -#include "PyInterp_Dispatcher.h" -#include -#include +#include +#include using namespace std; @@ -126,8 +122,9 @@ PyInterp_Dispatcher::~PyInterp_Dispatcher() // Clear the request queue myQueueMutex.lock(); - for ( std::list::iterator it = myQueue.begin(); it != myQueue.end(); ++it ) - PyInterp_Request::Destroy( *it ); + QListIterator it( myQueue ); + while ( it.hasNext() ) + PyInterp_Request::Destroy( it.next() ); myQueue.clear(); myQueueMutex.unlock(); @@ -155,7 +152,7 @@ void PyInterp_Dispatcher::Exec( PyInterp_Request* theRequest ) else // asynchronous processing { myQueueMutex.lock(); - myQueue.push_back( theRequest ); + myQueue.enqueue( theRequest ); if ( theRequest->listener() ) QObject::connect( theRequest->listener(), SIGNAL( destroyed( QObject* ) ), myWatcher, SLOT( onDestroyed( QObject* ) ) ); myQueueMutex.unlock(); @@ -175,7 +172,7 @@ void PyInterp_Dispatcher::run() while( myQueue.size() ) { // MESSAGE("*** PyInterp_Dispatcher::run(): next request taken from the queue") - aRequest = myQueue.front(); + aRequest = myQueue.head(); // let other threads append their requests to the end of the queue myQueueMutex.unlock(); @@ -187,8 +184,8 @@ void PyInterp_Dispatcher::run() // prepare for removal of the first request in the queue myQueueMutex.lock(); // IMPORTANT: the first item could have been removed by objectDestroyed() --> we have to check it - if ( myQueue.front() == aRequest ) // It's still here --> remove it - myQueue.pop_front(); + if ( myQueue.head() == aRequest ) // It's still here --> remove it + myQueue.dequeue(); // MESSAGE("*** PyInterp_Dispatcher::run(): request processed") } @@ -207,12 +204,14 @@ void PyInterp_Dispatcher::objectDestroyed( const QObject* o ) // prepare for modification of the queue myQueueMutex.lock(); - for ( std::list::iterator it = myQueue.begin(); it != myQueue.end(); ++it ) + QMutableListIterator it( myQueue ); + while ( it.hasNext() ) { - if ( o == (*it)->listener() ) + RequestPtr r = it.next(); + if ( o == r->listener() ) { - (*it)->setListener( 0 ); // to prevent event posting - it = myQueue.erase( it ); + r->setListener( 0 ); // to prevent event posting + it.remove(); } } diff --git a/src/PyInterp/PyInterp_Dispatcher.h b/src/PyInterp/PyInterp_Dispatcher.h index 6f6240794..cf46694e4 100755 --- a/src/PyInterp/PyInterp_Dispatcher.h +++ b/src/PyInterp/PyInterp_Dispatcher.h @@ -16,27 +16,23 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SALOME SALOMEGUI : implementation of desktop and GUI kernel -// // File : PyInterp_Dispatcher.h // Author : Sergey Anikin, OCC // Module : SALOME -#ifndef _PYINTERP_DISPATCHER_H_ -#define _PYINTERP_DISPATCHER_H_ - -#include "PyInterp.h" - -#include -#include +#ifndef PYINTERP_DISPATCHER_H +#define PYINTERP_DISPATCHER_H -#include +#include "PyInterp.h" // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!! -#include +#include +#include +#include +#include class QObject; -class PyInterp_base; +class PyInterp_Interp; class PyInterp_Watcher; class PyInterp_Dispatcher; @@ -73,11 +69,12 @@ protected: virtual void processEvent( QObject* ); -private: - void process(); QObject* listener() const { return myListener; } void setListener( QObject* ); +private: + void process(); + private: QMutex myMutex; bool myIsSync; @@ -87,16 +84,16 @@ private: class PYINTERP_EXPORT PyInterp_LockRequest : public PyInterp_Request { public: - PyInterp_LockRequest( PyInterp_base* interp, QObject* listener = 0, bool sync = false ) + PyInterp_LockRequest( PyInterp_Interp* interp, QObject* listener = 0, bool sync = false ) : PyInterp_Request( listener, sync ), myInterp( interp ) {} protected: - PyInterp_base* getInterp() const { return myInterp; } + PyInterp_Interp* getInterp() const { return myInterp; } - virtual void safeExecute(); + virtual void safeExecute(); private: - PyInterp_base* myInterp; + PyInterp_Interp* myInterp; }; class PYINTERP_EXPORT PyInterp_Event : public QEvent @@ -139,7 +136,7 @@ private: private: typedef PyInterp_Request* RequestPtr; - std::list myQueue; + QQueue myQueue; QMutex myQueueMutex; PyInterp_Watcher* myWatcher; @@ -148,4 +145,4 @@ private: friend class PyInterp_Watcher; }; -#endif +#endif // PYINTERP_DISPATCHER_H diff --git a/src/PyInterp/PyInterp_Interp.cxx b/src/PyInterp/PyInterp_Interp.cxx new file mode 100644 index 000000000..891d02908 --- /dev/null +++ b/src/PyInterp/PyInterp_Interp.cxx @@ -0,0 +1,449 @@ +// 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/ or email : webmaster.salome@opencascade.com +// +// File : PyInterp_Interp.cxx +// Author : Christian CAREMOLI, Paul RASCLE, EDF +// Module : SALOME + +#include "PyInterp_Interp.h" // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!! + +#include +#include + +#include +#include +#include + +#define TOP_HISTORY_PY "--- top of history ---" +#define BEGIN_HISTORY_PY "--- begin of history ---" + +/*! + \class PyLockWrapper + \brief Python GIL wrapper. +*/ + +/*! + \brief Constructor. Automatically acquires GIL. + \param theThreadState python thread state +*/ +PyLockWrapper::PyLockWrapper(PyThreadState* theThreadState): + myThreadState(theThreadState), + mySaveThreadState(0) +{ + if (myThreadState->interp == PyInterp_Interp::_interp) + _savestate = PyGILState_Ensure(); + else + PyEval_AcquireThread(myThreadState); +} + +/*! + \brief Desstructor. Automatically releases GIL. +*/ +PyLockWrapper::~PyLockWrapper() +{ + if (myThreadState->interp == PyInterp_Interp::_interp) + PyGILState_Release(_savestate); + else + PyEval_ReleaseThread(myThreadState); +} + +/*! + \brief Get Python GIL wrapper. + \return GIL lock wrapper (GIL is automatically acquired here) +*/ +PyLockWrapper PyInterp_Interp::GetLockWrapper() +{ + return _tstate; +} + +/* + The following functions are used to hook the Python + interpreter output. +*/ + +static void +PyStdOut_dealloc(PyStdOut *self) +{ + PyObject_Del(self); +} + +static PyObject* +PyStdOut_write(PyStdOut *self, PyObject *args) +{ + char *c; + int l; + if (!PyArg_ParseTuple(args, "t#:write",&c, &l)) + return NULL; + if(self->_cb==NULL) { + if ( self->_iscerr ) + std::cerr << c ; + else + std::cout << c ; + } + else { + self->_cb(self->_data,c); + } + Py_INCREF(Py_None); + return Py_None; +} + +static PyMethodDef PyStdOut_methods[] = { + {"write", (PyCFunction)PyStdOut_write, METH_VARARGS, + PyDoc_STR("write(string) -> None")}, + {NULL, NULL} /* sentinel */ +}; + +static PyMemberDef PyStdOut_memberlist[] = { + {"softspace", T_INT, offsetof(PyStdOut, softspace), 0, + "flag indicating that a space needs to be printed; used by print"}, + {NULL} /* Sentinel */ +}; + +static PyTypeObject PyStdOut_Type = { + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "PyOut", /*tp_name*/ + sizeof(PyStdOut), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)PyStdOut_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + PyObject_GenericGetAttr, /*tp_getattro*/ + /* softspace is writable: we must supply tp_setattro */ + PyObject_GenericSetAttr, /* tp_setattro */ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + PyStdOut_methods, /*tp_methods*/ + PyStdOut_memberlist, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + 0, /*tp_init*/ + 0, /*tp_alloc*/ + 0, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ +}; + +#define PyStdOut_Check(v) ((v)->ob_type == &PyStdOut_Type) + +static PyStdOut* newPyStdOut( bool iscerr ) +{ + PyStdOut *self; + self = PyObject_New(PyStdOut, &PyStdOut_Type); + if (self == NULL) + return NULL; + self->softspace = 0; + self->_cb = NULL; + self->_iscerr = iscerr; + return self; +} + +/*! + \class PyInterp_Interp + \brief Generic embedded Python interpreter. +*/ + +int PyInterp_Interp::_argc = 1; +char* PyInterp_Interp::_argv[] = {""}; +PyObject* PyInterp_Interp::builtinmodule = NULL; +PyThreadState* PyInterp_Interp::_gtstate = NULL; +PyInterpreterState* PyInterp_Interp::_interp = NULL; + +/*! + \brief Basic constructor. + + After construction the interpreter instance successor classes + must call virtual method initalize(). +*/ +PyInterp_Interp::PyInterp_Interp(): + _tstate(0), _vout(0), _verr(0), _g(0) +{ +} + +/*! + \brief Destructor. +*/ +PyInterp_Interp::~PyInterp_Interp() +{ +} + +/*! + \brief Initialize embedded interpreter. + + This method shoud be called after construction of the interpreter. + The method initialize() calls virtuals methods + - initPython() to initialize global Python interpreter + - initState() to initialize embedded interpreter state + - initContext() to initialize interpreter internal context + - initRun() to prepare interpreter for running commands + which should be implemented in the successor classes, according to the + embedded Python interpreter policy (mono or multi interpreter, etc). +*/ +void PyInterp_Interp::initialize() +{ + _history.clear(); // start a new list of user's commands + _ith = _history.begin(); + + initPython(); + // Here the global lock is released + + initState(); + + PyLockWrapper aLock = GetLockWrapper(); + + initContext(); + + // used to interpret & compile commands + PyObjWrapper m(PyImport_ImportModule("codeop")); + if(!m) { + PyErr_Print(); + return; + } + + // Create python objects to capture stdout and stderr + _vout=(PyObject*)newPyStdOut( false ); // stdout + _verr=(PyObject*)newPyStdOut( true ); // stderr + + // All the initRun outputs are redirected to the standard output (console) + initRun(); +} + +/*! + \brief Initialize Python interpreter. + + Set program name, initialize interpreter, set program arguments, + initiaize threads. + */ +void PyInterp_Interp::initPython() +{ + if (Py_IsInitialized()) + return; + + // Python is not initialized + Py_SetProgramName(_argv[0]); + Py_Initialize(); // Initialize the interpreter + PySys_SetArgv(_argc, _argv); + PyEval_InitThreads(); // Create (and acquire) the interpreter lock + _interp = PyThreadState_Get()->interp; + if (PyType_Ready(&PyStdOut_Type) < 0) { + PyErr_Print(); + } + _gtstate = PyEval_SaveThread(); // Release global thread state +} + +/*! + \brief Get embedded Python interpreter banner. + \return banner string + */ +std::string PyInterp_Interp::getbanner() +{ + // Should we take the lock ? + // PyEval_RestoreThread(_tstate); + std::string aBanner("Python "); + aBanner = aBanner + Py_GetVersion() + " on " + Py_GetPlatform() ; + aBanner = aBanner + "\ntype help to get general information on environment\n"; + //PyEval_SaveThread(); + return aBanner; +} + +/*! + \brief Initialize run command. + + This method is used to prepare interpreter for running + Python commands. + + \return \c true on success and \c false on error +*/ +bool PyInterp_Interp::initRun() +{ + // + // probably all below code isn't required + // + /* + PySys_SetObject("stderr",_verr); + PySys_SetObject("stdout",_vout); + + //PyObject *m = PyImport_GetModuleDict(); + + PySys_SetObject("stdout",PySys_GetObject("__stdout__")); + PySys_SetObject("stderr",PySys_GetObject("__stderr__")); + */ + return true; +} + +/*! + \brief Compile Python command and evaluate it in the + python dictionary context if possible. + \internal + \param command Python command string + \param context Python context (dictionary) + \return -1 on fatal error, 1 if command is incomplete and 0 + if command is executed successfully + */ +static int compile_command(const char *command,PyObject *context) +{ + PyObject *m = PyImport_AddModule("codeop"); + if(!m) { // Fatal error. No way to go on. + PyErr_Print(); + return -1; + } + PyObjWrapper v(PyObject_CallMethod(m,"compile_command","s",command)); + if(!v) { + // Error encountered. It should be SyntaxError, + //so we don't write out traceback + PyObjWrapper exception, value, tb; + PyErr_Fetch(&exception, &value, &tb); + PyErr_NormalizeException(&exception, &value, &tb); + PyErr_Display(exception, value, NULL); + return -1; + } + else if (v == Py_None) { + // Incomplete text we return 1 : we need a complete text to execute + return 1; + } + else { + // Complete and correct text. We evaluate it. + //#if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0 + // PyObjWrapper r(PyEval_EvalCode(v,context,context)); + //#else + PyObjWrapper r(PyEval_EvalCode((PyCodeObject *)(void *)v,context,context)); + //#endif + if(!r) { + // Execution error. We return -1 + PyErr_Print(); + return -1; + } + // The command has been successfully executed. Return 0 + return 0; + } +} + +/*! + \brief Run Python command. + \param command Python command + \return command status +*/ +int PyInterp_Interp::run(const char *command) +{ + beforeRun(); + return simpleRun(command); +} + +/*! + \brief Run Python command (used internally). + \param command Python command + \param addToHistory if \c true (default), the command is added to the commands history + \return command status +*/ +int PyInterp_Interp::simpleRun(const char *command, const bool addToHistory) +{ + if( addToHistory && strcmp(command,"") != 0 ) { + _history.push_back(command); + _ith = _history.end(); + } + + // We come from C++ to enter Python world + // We need to acquire the Python global lock + //PyLockWrapper aLock(_tstate); // san - lock is centralized now + + // Reset redirected outputs before treatment + PySys_SetObject("stderr",_verr); + PySys_SetObject("stdout",_vout); + + int ier = compile_command(command,_g); + + // Outputs are redirected on standards outputs (console) + PySys_SetObject("stdout",PySys_GetObject("__stdout__")); + PySys_SetObject("stderr",PySys_GetObject("__stderr__")); + + return ier; +} + +/*! + \brief Get previous command in the commands history. + \return previous command +*/ +const char * PyInterp_Interp::getPrevious() +{ + if(_ith != _history.begin()){ + _ith--; + return (*_ith).c_str(); + } + else + return BEGIN_HISTORY_PY; +} + +/*! + \brief Get next command in the commands history. + \return next command +*/ +const char * PyInterp_Interp::getNext() +{ + if(_ith != _history.end()){ + _ith++; + } + if (_ith == _history.end()) + return TOP_HISTORY_PY; + else + return (*_ith).c_str(); +} + +/*! + \brief Set Python standard output device hook. + \param cb callback function + \param data callback function parameters +*/ +void PyInterp_Interp::setvoutcb(PyOutChanged* cb, void* data) +{ + ((PyStdOut*)_vout)->_cb=cb; + ((PyStdOut*)_vout)->_data=data; +} + +/*! + \brief Set Python standard error device hook. + \param cb callback function + \param data callback function parameters +*/ +void PyInterp_Interp::setverrcb(PyOutChanged* cb, void* data) +{ + ((PyStdOut*)_verr)->_cb=cb; + ((PyStdOut*)_verr)->_data=data; +} diff --git a/src/PyInterp/PyInterp_Interp.h b/src/PyInterp/PyInterp_Interp.h new file mode 100644 index 000000000..397a79167 --- /dev/null +++ b/src/PyInterp/PyInterp_Interp.h @@ -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/ or email : webmaster.salome@opencascade.com +// +// File : PyInterp_Interp.h +// Author : Christian CAREMOLI, Paul RASCLE, EDF +// Module : SALOME + +#ifndef PYINTERP_INTERP_H +#define PYINTERP_INTERP_H + +#include "PyInterp.h" // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!! + +#include +#include + +class PYINTERP_EXPORT PyLockWrapper +{ + PyThreadState* myThreadState; + PyThreadState* mySaveThreadState; + PyGILState_STATE _savestate; +public: + PyLockWrapper(PyThreadState* theThreadState); + ~PyLockWrapper(); +}; + +typedef void PyOutChanged(void* data,char * c); + +class PYINTERP_EXPORT PyInterp_Interp +{ +public: + static int _argc; + static char* _argv[]; + static PyObject *builtinmodule; + static PyThreadState *_gtstate; + static PyInterpreterState *_interp; + + PyInterp_Interp(); + virtual ~PyInterp_Interp(); + + void initialize(); + + virtual int run(const char *command); + + PyLockWrapper GetLockWrapper(); + + std::string getbanner(); + void setverrcb(PyOutChanged*,void*); + void setvoutcb(PyOutChanged*,void*); + + const char * getPrevious(); + const char * getNext(); + +protected: + PyThreadState * _tstate; + PyObject * _vout; + PyObject * _verr; + PyObject * _g; + PyObject * _codeop; + std::list _history; + std::list::iterator _ith; + + virtual int beforeRun() { return 0; } + int simpleRun(const char* command, const bool addToHistory = true); + + virtual bool initRun(); + virtual void initPython(); + virtual bool initState() = 0; + virtual bool initContext() = 0; +}; + +class PYINTERP_EXPORT PyObjWrapper +{ + PyObject* myObject; +public: + PyObjWrapper(PyObject* theObject) : myObject(theObject) {} + PyObjWrapper() : myObject(0) {} + virtual ~PyObjWrapper() { Py_XDECREF(myObject); } + + operator PyObject*() { return myObject; } + PyObject* operator->() { return myObject; } + PyObject* get() { return myObject; } + bool operator!() { return !myObject; } + bool operator==(PyObject* theObject) { return myObject == theObject; } + PyObject** operator&() { return &myObject; } + PyObjWrapper& operator=(PyObjWrapper* theObjWrapper) + { + Py_XDECREF(myObject); + myObject = theObjWrapper->myObject; + return *this; + } +}; + +typedef struct { + PyObject_HEAD + int softspace; + PyOutChanged* _cb; + void* _data; + bool _iscerr; +} PyStdOut; + +#endif // PYINTERP_INTERP_H diff --git a/src/PyInterp/PyInterp_Watcher.h b/src/PyInterp/PyInterp_Watcher.h index f5d776034..1d50f5bf8 100755 --- a/src/PyInterp/PyInterp_Watcher.h +++ b/src/PyInterp/PyInterp_Watcher.h @@ -16,14 +16,18 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#ifndef _PYINTERP_WATCHER_H_ -#define _PYINTERP_WATCHER_H_ +// File : PyInterp_Watcher.h +// Author : Sergey Anikin, OCC +// Module : SALOME -#include "PyInterp.h" +#ifndef PYINTERP_WATCHER_H +#define PYINTERP_WATCHER_H + +#include "PyInterp.h" // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!! #include "PyInterp_Dispatcher.h" -#include +#include // Private class that keeps track of destructions of request listeners class PYINTERP_EXPORT PyInterp_Watcher : public QObject @@ -38,4 +42,4 @@ public slots: void onDestroyed( QObject* o ) { PyInterp_Dispatcher::Get()->objectDestroyed( o ); } }; -#endif // _PYINTERP_WATCHER_H_ +#endif // PYINTERP_WATCHER_H diff --git a/src/Qtx/Qtx.cxx b/src/Qtx/Qtx.cxx index a5d77d034..73b3c7624 100755 --- a/src/Qtx/Qtx.cxx +++ b/src/Qtx/Qtx.cxx @@ -303,6 +303,33 @@ bool Qtx::isParent( QObject* child, QObject* parent ) return res; } +/*! + \brief Find the parent object of class specified by \a className (in terms of QObject). + + \param obj current object + \param className class name of the parent + \return parent object or null pointer if the parent not found +*/ +QObject* Qtx::findParent( QObject* obj, const char* className ) +{ + if ( !obj ) + return 0; + + if ( !className || !strlen( className ) ) + return obj->parent(); + + QObject* res = 0; + QObject* p = obj->parent(); + while ( p && !res ) + { + if ( p->inherits( className ) ) + res = p; + p = p->parent(); + } + + return res; +} + /*! \brief Return directory part of the file path. @@ -1036,9 +1063,9 @@ QString Qtx::gradientToString( const QRadialGradient& gradient ) data << "radial"; data << QString::number( gradient.center().x() ); data << QString::number( gradient.center().y() ); - data << QString::number( gradient.radius() ); data << QString::number( gradient.focalPoint().x() ); data << QString::number( gradient.focalPoint().y() ); + data << QString::number( gradient.radius() ); switch( gradient.spread() ) { case QGradient::PadSpread: @@ -1171,9 +1198,9 @@ bool Qtx::stringToRadialGradient( const QString& str, QRadialGradient& gradient bool bOk1, bOk2, bOk3, bOk4, bOk5; cx = vals[1].toDouble( &bOk1 ); cy = vals[2].toDouble( &bOk2 ); - r = vals[3].toDouble( &bOk3 ); - fx = vals[4].toDouble( &bOk4 ); - fy = vals[5].toDouble( &bOk5 ); + fx = vals[3].toDouble( &bOk4 ); + fy = vals[4].toDouble( &bOk5 ); + r = vals[5].toDouble( &bOk3 ); if ( bOk1 && bOk2 && bOk3 && bOk4 && bOk5 ) { gradient = QRadialGradient( cx, cy, r, fx, fy ); @@ -1263,7 +1290,7 @@ bool Qtx::stringToConicalGradient( const QString& str, QConicalGradient& gradien * Cheque for existing any system printers */ -#ifndef WIN32 +#if !defined(WIN32) && !defined(QT_NO_CUPS) #if QT_VERSION < 0x040303 #include #include @@ -1275,7 +1302,7 @@ static CupsGetDests _cupsGetDests = 0; bool Qtx::hasAnyPrinters() { bool aRes = true; -#ifndef WIN32 +#if !defined(WIN32) && !defined(QT_NO_CUPS) #if QT_VERSION < 0x040303 QLibrary aCupsLib( QString( "cups" ) ); if ( !aCupsLib.load() ) diff --git a/src/Qtx/Qtx.h b/src/Qtx/Qtx.h index c8c4f41d6..8e67524fc 100755 --- a/src/Qtx/Qtx.h +++ b/src/Qtx/Qtx.h @@ -108,6 +108,7 @@ public: static void simplifySeparators( QWidget*, const bool = true ); static bool isParent( QObject*, QObject* ); + static QObject* findParent( QObject*, const char* ); static QString dir( const QString&, const bool = true ); static QString file( const QString&, const bool = true ); diff --git a/src/Qtx/QtxAction.cxx b/src/Qtx/QtxAction.cxx index 1e46ce16d..e4da75af7 100755 --- a/src/Qtx/QtxAction.cxx +++ b/src/Qtx/QtxAction.cxx @@ -22,6 +22,7 @@ #include "QtxAction.h" #include +#include #include #include @@ -37,12 +38,12 @@ public: ActionNotify( bool add, QWidget* wid ) : QEvent( QEvent::User ), myAdd( add ), myWidget( wid ) {}; ~ActionNotify() {}; - bool isAdded() const { return myAdd; } - QWidget* widget() const { return myWidget; } + bool isAdded() const { return myAdd; } + QWidget* widget() const { return myWidget; } private: - bool myAdd; - QWidget* myWidget; + bool myAdd; + QPointer myWidget; }; /*! @@ -195,6 +196,9 @@ void QtxAction::removedFrom( QWidget* /*w*/ ) void QtxAction::customEvent( QEvent* e ) { ActionNotify* ae = (ActionNotify*)e; + if ( !ae->widget() ) + return; + if ( ae->isAdded() ) addedTo( ae->widget() ); else diff --git a/src/Qtx/QtxActionMenuMgr.cxx b/src/Qtx/QtxActionMenuMgr.cxx index f3b42a46d..2540721e3 100644 --- a/src/Qtx/QtxActionMenuMgr.cxx +++ b/src/Qtx/QtxActionMenuMgr.cxx @@ -1027,9 +1027,9 @@ bool QtxActionMenuMgr::load( const QString& fname, QtxActionMgr::Reader& r ) \param pid parent menu item ID \return \c true if parent menu item contains such child item */ -bool QtxActionMenuMgr::containsMenu( const QString& title, const int pid ) const +bool QtxActionMenuMgr::containsMenu( const QString& title, const int pid, const bool rec ) const { - return (bool)find( title, pid, false ); + return (bool)find( title, pid, rec ); } /*! @@ -1038,9 +1038,9 @@ bool QtxActionMenuMgr::containsMenu( const QString& title, const int pid ) const \param pid parent menu item ID \return \c true if parent menu item contains such child item */ -bool QtxActionMenuMgr::containsMenu( const int id, const int pid ) const +bool QtxActionMenuMgr::containsMenu( const int id, const int pid, const bool rec ) const { - return (bool)find( id, pid, false ); + return (bool)find( id, pid, rec ); } /*! diff --git a/src/Qtx/QtxActionMenuMgr.h b/src/Qtx/QtxActionMenuMgr.h index 96d15b51b..1f5079161 100644 --- a/src/Qtx/QtxActionMenuMgr.h +++ b/src/Qtx/QtxActionMenuMgr.h @@ -90,8 +90,8 @@ public: virtual bool load( const QString&, QtxActionMgr::Reader& ); - bool containsMenu( const QString&, const int ) const; - bool containsMenu( const int, const int ) const; + bool containsMenu( const QString&, const int, const bool = false ) const; + bool containsMenu( const int, const int, const bool = false ) const; QMenu* findMenu( const int ) const; diff --git a/src/Qtx/QtxActionMgr.cxx b/src/Qtx/QtxActionMgr.cxx index a1aa362b5..053d5ab75 100644 --- a/src/Qtx/QtxActionMgr.cxx +++ b/src/Qtx/QtxActionMgr.cxx @@ -52,7 +52,7 @@ void qtxSeparatorActionCleanup() \internal */ -class QtxActionMgr::SeparatorAction : public QtxAction +class QtxActionMgr::SeparatorAction : public QAction { public: SeparatorAction( QObject* = 0 ); @@ -65,7 +65,7 @@ public: \param parent parent object */ QtxActionMgr::SeparatorAction::SeparatorAction( QObject* parent ) -: QtxAction( parent ) +: QAction( parent ) { setSeparator( true ); } diff --git a/src/Qtx/QtxActionMgr.h b/src/Qtx/QtxActionMgr.h index 98d99e3c6..d7c4d6a6d 100644 --- a/src/Qtx/QtxActionMgr.h +++ b/src/Qtx/QtxActionMgr.h @@ -118,7 +118,7 @@ public: protected: static int intValue( const ItemAttributes&, const QString&, const int ); static QString strValue( const ItemAttributes&, const QString&, - const QString& = QString::null ); + const QString& = QString() ); private: QtxActionMgr::Reader* myReader; //!< actions reader }; @@ -130,7 +130,7 @@ public: virtual ~Reader(); QStringList options() const; - QString option( const QString&, const QString& = QString::null ) const; + QString option( const QString&, const QString& = QString() ) const; void setOption( const QString&, const QString& ); virtual bool read( const QString&, Creator& ) const = 0; diff --git a/src/Qtx/QtxActionToolMgr.cxx b/src/Qtx/QtxActionToolMgr.cxx index 47b339edd..e2c4b2048 100644 --- a/src/Qtx/QtxActionToolMgr.cxx +++ b/src/Qtx/QtxActionToolMgr.cxx @@ -92,23 +92,27 @@ QMainWindow* QtxActionToolMgr::mainWindow() const \param title toolbar title \param tid requested toolbar ID + \param mw parent main window; if it is null, the tool manager's main window is used \return id of created/found toolbar */ -int QtxActionToolMgr::createToolBar( const QString& title, const int tid ) +int QtxActionToolMgr::createToolBar( const QString& title, const int tid, QMainWindow* mw ) { static int _toolBarId = -1; int tbId = -1; for ( ToolBarMap::ConstIterator it = myToolBars.begin(); it != myToolBars.end() && tbId == -1; ++it ) { - if ( it.value().toolBar->windowTitle().toLower() == title.toLower() ) - tbId = it.key(); + // NKV - BUG IPAL19144 - search by toolbar title is done below via find() function + // if ( it.value().toolBar->windowTitle().toLower() == title.toLower() ) + // tbId = it.key(); + if (it.key() == tid) tbId = it.key(); } if ( tbId != -1 ) return tbId; - QToolBar* tb = find( title, mainWindow() ); + QMainWindow* tbw = mw ? mw : mainWindow(); + QToolBar* tb = find( title, tbw ); tbId = tid < 0 ? --_toolBarId : tid; @@ -117,7 +121,7 @@ int QtxActionToolMgr::createToolBar( const QString& title, const int tid ) if ( !tb ) { - tb = new QtxToolBar( true, mainWindow() ); + tb = new QtxToolBar( true, tbw ); mainWindow()->addToolBar( tb ); tb->setWindowTitle( title ); tb->setObjectName( title ); diff --git a/src/Qtx/QtxActionToolMgr.h b/src/Qtx/QtxActionToolMgr.h index be8bda268..b774dda33 100644 --- a/src/Qtx/QtxActionToolMgr.h +++ b/src/Qtx/QtxActionToolMgr.h @@ -61,7 +61,7 @@ public: QMainWindow* mainWindow() const; - int createToolBar( const QString&, int = -1 ); + int createToolBar( const QString&, int = -1, QMainWindow* = 0 ); void removeToolBar( const QString& ); void removeToolBar( const int ); @@ -101,11 +101,12 @@ public: virtual bool load( const QString&, QtxActionMgr::Reader& ); + int find( QToolBar* ) const; + protected slots: void onToolBarDestroyed(); protected: - int find( QToolBar* ) const; int find( const QString& ) const; QToolBar* find( const QString&, QMainWindow* ) const; diff --git a/src/Qtx/QtxColorScale.cxx b/src/Qtx/QtxColorScale.cxx index 97b61a2b3..b7dbf558a 100755 --- a/src/Qtx/QtxColorScale.cxx +++ b/src/Qtx/QtxColorScale.cxx @@ -269,7 +269,7 @@ void QtxColorScale::setRange( const double min, const double max ) myMin = min; myMax = max; - myPrecise = QString::null; + myPrecise = QString(); if ( colorMode() == Auto || labelMode() == Auto ) updateScale(); @@ -299,7 +299,7 @@ void QtxColorScale::setFormat( const QString& format ) return; myFormat = format; - myPrecise = QString::null; + myPrecise = QString(); if ( colorMode() == Auto ) updateScale(); } @@ -314,7 +314,7 @@ void QtxColorScale::setIntervalsNumber( const int num ) return; myInterval = num; - myPrecise = QString::null; + myPrecise = QString(); updateScale(); } diff --git a/src/Qtx/QtxColorScale.h b/src/Qtx/QtxColorScale.h index ae9e985f2..453aeefe6 100755 --- a/src/Qtx/QtxColorScale.h +++ b/src/Qtx/QtxColorScale.h @@ -59,12 +59,12 @@ public: } DumpMode; //! Color scale flags (bitwise). typedef enum { - AtBorder = 0x001, - Reverse = 0x002, - Integer = 0x004, - WrapTitle = 0x008, - PreciseFormat = 0x010, - Transparent = 0x020 + AtBorder = 0x001, //!< diplay values at colors boundaries + Reverse = 0x002, //!< display color scale in reverse order + Integer = 0x004, //!< round numbers to integer values + WrapTitle = 0x008, //!< wrap title to several lines + PreciseFormat = 0x010, //!< autodetect decimal point precision for color scale values + Transparent = 0x020 //!< transparent background (not implemented yet!) } Flags; public: diff --git a/src/Qtx/QtxComboBox.cxx b/src/Qtx/QtxComboBox.cxx index eaffefbdf..817138c96 100755 --- a/src/Qtx/QtxComboBox.cxx +++ b/src/Qtx/QtxComboBox.cxx @@ -187,7 +187,7 @@ void QtxComboBox::paintClear( QPaintEvent* e ) setUpdatesEnabled( false ); setItemIcon( curIndex, QIcon() ); - setItemText( curIndex, QString::null ); + setItemText( curIndex, QString() ); QComboBox::paintEvent( e ); diff --git a/src/Qtx/QtxListAction.cxx b/src/Qtx/QtxListAction.cxx index 813d052ee..fff34a603 100755 --- a/src/Qtx/QtxListAction.cxx +++ b/src/Qtx/QtxListAction.cxx @@ -570,7 +570,7 @@ void QtxListAction::ListFrame::removePostedEvens( QObject* o, int type ) \param parent parent object */ QtxListAction::QtxListAction( QObject* parent ) -: QWidgetAction( parent ), +: QtxAction( parent ), myFrame( 0 ) { initialize(); @@ -585,13 +585,9 @@ QtxListAction::QtxListAction( QObject* parent ) */ QtxListAction::QtxListAction( const QIcon& icon, const QString& menuText, int accel, QObject* parent ) -: QWidgetAction( parent ), +: QtxAction( menuText, icon, menuText, accel, parent ), myFrame( 0 ) { - setIcon( icon ); - setText( menuText ); - setShortcut( accel ); - initialize(); } @@ -602,12 +598,9 @@ QtxListAction::QtxListAction( const QIcon& icon, const QString& menuText, \param parent parent object */ QtxListAction::QtxListAction( const QString& menuText, int accel, QObject* parent ) -: QWidgetAction( parent ), +: QtxAction( menuText, menuText, accel, parent ), myFrame( 0 ) { - setText( menuText ); - setShortcut( accel ); - initialize(); } @@ -620,12 +613,13 @@ QtxListAction::QtxListAction( const QString& menuText, int accel, QObject* paren */ QtxListAction::QtxListAction( const QString& text, const QString& menuText, int accel, QObject* parent ) -: QWidgetAction( parent ), +: QtxAction( text, menuText, accel, parent ), myFrame( 0 ) { setText( menuText ); setShortcut( accel ); setToolTip( text ); + setStatusTip( text ); initialize(); } @@ -640,13 +634,14 @@ QtxListAction::QtxListAction( const QString& text, const QString& menuText, */ QtxListAction::QtxListAction( const QString& text, const QIcon& icon, const QString& menuText, int accel, QObject* parent ) -: QWidgetAction( parent ), +: QtxAction( text, icon, menuText, accel, parent ), myFrame( 0 ) { setIcon( icon ); setText( menuText ); setShortcut( accel ); setToolTip( text ); + setStatusTip( text ); initialize(); } @@ -814,6 +809,7 @@ QWidget* QtxListAction::createWidget( QWidget* parent ) tb->setMenu( myFrame ); tb->setEnabled( isEnabled() && !names().isEmpty() ); tb->setToolTip( toolTip() ); + tb->setStatusTip( statusTip() ); connect( tb, SIGNAL( clicked( bool ) ), this, SLOT( onSingle( bool ) ) ); return tb; @@ -877,6 +873,7 @@ void QtxListAction::onChanged() tb->setText( text() ); tb->setIcon( icon() ); tb->setToolTip( toolTip() ); + tb->setStatusTip( statusTip() ); } } } diff --git a/src/Qtx/QtxListAction.h b/src/Qtx/QtxListAction.h index 182698551..956f65c73 100755 --- a/src/Qtx/QtxListAction.h +++ b/src/Qtx/QtxListAction.h @@ -23,15 +23,14 @@ #define QTXLISTACTION_H #include "Qtx.h" - +#include "QtxAction.h" #include -#include #ifdef WIN32 #pragma warning( disable:4251 ) #endif -class QTX_EXPORT QtxListAction : public QWidgetAction +class QTX_EXPORT QtxListAction : public QtxAction { Q_OBJECT diff --git a/src/Qtx/QtxMRUAction.cxx b/src/Qtx/QtxMRUAction.cxx index 6f1b81844..c3767ca5f 100755 --- a/src/Qtx/QtxMRUAction.cxx +++ b/src/Qtx/QtxMRUAction.cxx @@ -1,17 +1,17 @@ // 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 +// 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 +// +// This library is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com @@ -38,6 +38,7 @@ QtxMRUAction::QtxMRUAction( QObject* parent ) : QtxAction( "Most Recently Used", "Most Recently Used", 0, parent ), myVisCount( 5 ), + myLinkType( LinkAuto ), myInsertMode( MoveFirst ) { setMenu( new QMenu( 0 ) ); @@ -53,6 +54,7 @@ QtxMRUAction::QtxMRUAction( QObject* parent ) QtxMRUAction::QtxMRUAction( const QString& text, const QString& menuText, QObject* parent ) : QtxAction( text, menuText, 0, parent ), myVisCount( 5 ), + myLinkType( LinkAuto ), myInsertMode( MoveFirst ) { setMenu( new QMenu( 0 ) ); @@ -69,8 +71,9 @@ QtxMRUAction::QtxMRUAction( const QString& text, const QString& menuText, QObjec QtxMRUAction::QtxMRUAction( const QString& text, const QIcon& icon, const QString& menuText, QObject* parent ) : QtxAction( text, icon, menuText, 0, parent ), -myVisCount( 5 ), -myInsertMode( MoveFirst ) + myVisCount( 5 ), + myLinkType( LinkAuto ), + myInsertMode( MoveFirst ) { setMenu( new QMenu( 0 ) ); connect( menu(), SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) ); @@ -102,6 +105,24 @@ void QtxMRUAction::setInsertMode( const int mode ) myInsertMode = mode; } +/*! + \brief Get the type of link menu name. + \return link type (QtxMRUAction::LinkType) +*/ +int QtxMRUAction::linkType() const +{ + return myLinkType; +} + +/*! + \brief Set the type of link menu name. + \param link type (QtxMRUAction::LinkType) +*/ +void QtxMRUAction::setLinkType( const int type ) +{ + myLinkType = type; +} + /*! \brief Get number of MRU items. \return number of MRU items @@ -132,7 +153,7 @@ int QtxMRUAction::visibleCount() const /*! \brief Set number of visible MRU items. - + This method sets the maximum number of MRU items to be displayed in the popup menu (5 by default). @@ -261,7 +282,7 @@ void QtxMRUAction::loadLinks( QtxResourceMgr* resMgr, const QString& section, co if ( !(*it).startsWith( itemPrefix ) ) continue; - QString link = resMgr->stringValue( section, *it, QString::null ); + QString link = resMgr->stringValue( section, *it, QString() ); if ( link.isEmpty() || map.contains( link ) ) continue; @@ -299,7 +320,7 @@ void QtxMRUAction::saveLinks( QtxResourceMgr* resMgr, const QString& section, co if ( !(*it).startsWith( itemPrefix ) ) continue; - QString link = resMgr->stringValue( section, *it, QString::null ); + QString link = resMgr->stringValue( section, *it, QString() ); if ( !link.isEmpty() && !map.contains( link ) ) { lst.append( link ); @@ -316,7 +337,7 @@ void QtxMRUAction::saveLinks( QtxResourceMgr* resMgr, const QString& section, co /*! \brief Prepare MRU items popup menu. - + This method is called when the parent menu is shown. Enables or disables sub menu item according to the number of MRU items. */ @@ -336,7 +357,7 @@ void QtxMRUAction::onActivated() if ( !a ) return; - QString link = a->text(); + QString link = a->data().toString(); if ( !link.isEmpty() && myLinks.contains( link ) ) emit activated( link ); } @@ -352,9 +373,50 @@ void QtxMRUAction::updateMenu() pm->clear(); + QStringList links; + QMap map; int count = visibleCount() < 0 ? myLinks.count() : visibleCount(); for ( QStringList::const_iterator it = myLinks.begin(); it != myLinks.end() && count > 0; ++it, count-- ) - pm->addAction( *it, this, SLOT( onActivated() ) ); + { + links.append( *it ); + if ( linkType() == LinkAuto ) + { + QString shortName = Qtx::file( *it ); + if ( map.contains( shortName ) ) + map[shortName]++; + else + map.insert( shortName, 0 ); + } + } + + int i = 1; + for ( QStringList::const_iterator it = links.begin(); it != links.end(); ++it, i++ ) + { + QString linkName; + switch( linkType() ) + { + case LinkAuto: + linkName = Qtx::file( *it ); + if ( map.contains( linkName ) && map[linkName] ) + linkName = *it; + break; + case LinkShort: + linkName = Qtx::file( *it ); + break; + case LinkFull: + default: + linkName = *it; + break; + } + + if ( links.count() < 10 ) + linkName = QString( "&%1 %2" ).arg( i ).arg( linkName ); + + pm->addAction( linkName, this, SLOT( onActivated() ) )->setData( *it ); + } + + if ( pm->isEmpty() ) + pm->addAction( tr( "" ) )->setEnabled( false ); } /*! diff --git a/src/Qtx/QtxMRUAction.h b/src/Qtx/QtxMRUAction.h index f8a5dd9b0..708383f43 100755 --- a/src/Qtx/QtxMRUAction.h +++ b/src/Qtx/QtxMRUAction.h @@ -44,6 +44,11 @@ public: AddLast //!< if specified item doesn't exist, add it to the end } InsertionMode; + typedef enum { LinkAuto, //!< put the full path of link into the menu if link file names of severals link are same + LinkShort, //!< put the only file name of link into the menu + LinkFull //!< put the full path of link into the menu + } LinkType; + public: QtxMRUAction( QObject* = 0 ); QtxMRUAction( const QString&, const QString&, QObject* = 0 ); @@ -53,6 +58,9 @@ public: int insertMode() const; void setInsertMode( const int ); + int linkType() const; + void setLinkType( const int ); + int count() const; bool isEmpty() const; @@ -83,6 +91,7 @@ private: private: QStringList myLinks; //!< most recent used items int myVisCount; //!< number of visible MRU items + int myLinkType; //!< type of link names in menu int myInsertMode; //!< items insertion policy }; diff --git a/src/Qtx/QtxMainWindow.cxx b/src/Qtx/QtxMainWindow.cxx index 7ca329ac2..8e77da2e1 100644 --- a/src/Qtx/QtxMainWindow.cxx +++ b/src/Qtx/QtxMainWindow.cxx @@ -238,7 +238,7 @@ QString QtxMainWindow::storeGeometry() const else y = QString( "+%1" ).arg( frame.top() ); - QString geom = QString( "%1x%2%3%4" ).arg( frame.width() ).arg( frame.height() ).arg( x ).arg( y ); + QString geom = QString( "%1x%2%3%4" ).arg( width() ).arg( height() ).arg( x ).arg( y ); QString state; switch ( windowState() ) @@ -339,7 +339,9 @@ void QtxMainWindow::retrieveGeometry( const QString& str ) state = Qt::WindowFullScreen; } - setGeometry( rect ); + resize( rect.size() ); + move( rect.topLeft() ); + if ( state != Qt::WindowNoState ) setWindowState( state ); } diff --git a/src/Qtx/QtxMenu.cxx b/src/Qtx/QtxMenu.cxx new file mode 100644 index 000000000..418e5e61c --- /dev/null +++ b/src/Qtx/QtxMenu.cxx @@ -0,0 +1,409 @@ +// 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/ or email : webmaster.salome@opencascade.com +// +// File: QtxMenu.cxx +// Author: Sergey TELKOV +// + +#include "QtxMenu.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +/*! + \class QtxMenu::Title + \brief Popup menu title item. + \internal +*/ + +class QtxMenu::Title : public QWidget +{ +public: + Title( QWidget* = 0 ); + virtual ~Title(); + + QIcon icon() const; + void setIcon( const QIcon& ); + + QString text() const; + void setText( const QString& ); + + Qt::Alignment alignment() const; + void setAlignment( const Qt::Alignment ); + + virtual QSize sizeHint() const; + virtual QSize minimumSizeHint() const; + +protected: + virtual void paintEvent( QPaintEvent* ); + +private: + QIcon myIcon; + QString myText; + Qt::Alignment myAlignment; +}; + +/*! + \brief Constructor. + \param parent parent widget + \internal +*/ +QtxMenu::Title::Title( QWidget* parent ) +: QWidget( parent ), + myAlignment( 0 ) +{ +} + +/*! + \brief Destructor. + \internal +*/ +QtxMenu::Title::~Title() +{ +} + +/*! + \brief Get title icon. + \return title item icon + \internal +*/ +QIcon QtxMenu::Title::icon() const +{ + return myIcon; +} + +/*! + \brief Set title icon. + \param ico title item icon + \internal +*/ +void QtxMenu::Title::setIcon( const QIcon& ico ) +{ + myIcon = ico; +} + +/*! + \brief Get title menu text. + \return menu text for the title item + \internal +*/ +QString QtxMenu::Title::text() const +{ + return myText; +} + +/*! + \brief Set title menu text. + \param txt menu text to be used for the title item + \internal +*/ +void QtxMenu::Title::setText( const QString& txt ) +{ + myText = txt; +} + +/*! + \brief Get title alignment flags. + \return title alignment flags + \internal +*/ +Qt::Alignment QtxMenu::Title::alignment() const +{ + return myAlignment; +} + +/*! + \brief Set title alignment flags. + \param a title alignment flags + \internal +*/ +void QtxMenu::Title::setAlignment( const Qt::Alignment a ) +{ + myAlignment = a; +} + +/*! + \brief Get recommended size for the title item widget. + \return title item widget size + \internal +*/ +QSize QtxMenu::Title::sizeHint() const +{ + int m = 5; + QTextDocument doc; + doc.setHtml( text() ); + + QSize sz = icon().isNull() ? QSize( 0, 0 ) : icon().actualSize( QSize( 16, 16 ) ); + sz.setWidth( 2 * m + sz.width() + (int)doc.size().width() ); + sz.setHeight( 2 * m + qMax( sz.height(), (int)doc.size().height() ) ); + return sz; +} + +/*! + \brief Get recommended minimum size for the title item widget. + \return title item widget minimum size + \internal +*/ +QSize QtxMenu::Title::minimumSizeHint() const +{ + return sizeHint(); +} + +/*! + \brief Paint the title item widget. + \param e paint event (not used) + \internal +*/ +void QtxMenu::Title::paintEvent( QPaintEvent* /*e*/ ) +{ + int m = 5; + QIcon ico = icon(); + QString txt = text(); + Qt::Alignment align = alignment(); + + QRect base = rect(); + base.setTop( base.top() + 1 ); + base.setLeft( base.left() + 1 ); + base.setRight( base.right() -1 ); + base.setBottom( base.bottom() - 1 ); + + QTextDocument doc; + doc.setHtml( txt ); + + QSize isz = ico.isNull() ? QSize( 0, 0 ) : ico.actualSize( QSize( 16, 16 ) ); + QSize sz( (int)doc.size().width(), (int)doc.size().height() ); + + QPainter p( this ); + QAbstractTextDocumentLayout::PaintContext ctx; + ctx.palette.setColor( QPalette::Text, palette().color( QPalette::Light ) ); + + QLinearGradient linearGrad( base.topLeft(), base.topRight() ); + linearGrad.setColorAt( 0, palette().color( QPalette::Highlight ) ); + linearGrad.setColorAt( 1, palette().color( QPalette::Window ) ); + + p.fillRect( base, linearGrad ); + + QPoint start = base.topLeft() + QPoint( m, m ); + if ( align & Qt::AlignLeft ) + start.setX( base.left() + m ); + else if ( align & Qt::AlignRight ) + start.setX( base.right() - m - isz.width() - sz.width() ); + else if ( align & Qt::AlignHCenter ) + start.setX( base.left() + ( base.width() - isz.width() - sz.width() ) / 2 ); + + if ( align & Qt::AlignTop ) + start.setY( base.top() + m ); + else if ( align & Qt::AlignBottom ) + start.setY( base.bottom() - m - qMax( isz.height(), - sz.height() ) ); + else if ( align & Qt::AlignVCenter ) + start.setY( base.top() + ( base.height() - qMax( isz.height(), sz.height() ) ) / 2 ); + + if ( !ico.isNull() ) + { + ico.paint( &p, QRect( start, isz ) ); + start.setX( start.x() + isz.width() ); + } + + p.save(); + p.translate( start ); + doc.documentLayout()->draw( &p, ctx ); + p.restore(); +} + +/*! + \class QtxMenu + \brief The class QtxMenu represents the popup menu with the title. + + The title for the popup menu can be set via setTitleText() method. + In addition, title item can contain the icon, which can be set using + setTitleIcon() method. Current title text and icon can be retrieved with + titleText() and titleIcon() methods. + + The title text alignment flags can be changed using setTitleAlignment() + method and retrieved with titleAlignment() method. + + By default, QtxMenu::TitleAuto mode is used. In this mode, the title item + is shown only if it is not empty. To show title always (even empty), pass + QtxMenu::TitleOn to the setTitleMode() method. To hide the title, use + setTitleMode() method with QtxMenu::TitleOff parameter. +*/ + +/*! + \brief Constructor. + \param parent parent widget +*/ +QtxMenu::QtxMenu( QWidget* parent ) +: QMenu( parent ), + myMode( TitleAuto ) +{ + myTitle = new Title( this ); + myAction = new QWidgetAction( this ); + myAction->setDefaultWidget( myTitle ); +} + +/*! + \brief Destructor. +*/ +QtxMenu::~QtxMenu() +{ +} + +/*! + \brief Get title menu text. + \return menu text for the title item +*/ +QString QtxMenu::titleText() const +{ + return myTitle->text(); +} + +/*! + \brief Get title icon. + \return title item icon +*/ +QIcon QtxMenu::titleIcon() const +{ + return myTitle->icon(); +} + +/*! + \brief Get title item display mode. + \return popup menu title display mode (QtxMenu::TitleMode) +*/ +QtxMenu::TitleMode QtxMenu::titleMode() const +{ + return myMode; +} + +/*! + \brief Get title alignment flags. + \return title alignment flags +*/ +Qt::Alignment QtxMenu::titleAlignment() const +{ + return myTitle->alignment(); +} + +/*! + \brief Set title menu text. + \param txt menu text to be used for the title item +*/ +void QtxMenu::setTitleText( const QString& txt ) +{ + if ( titleText() == txt ) + return; + + myTitle->setText( txt ); + + updateTitle(); +} + +/*! + \brief Set title icon. + \param ico title item icon +*/ +void QtxMenu::setTitleIcon( const QIcon& ico ) +{ + myTitle->setIcon( ico ); + + updateTitle(); +} + +/*! + \brief Set title item display mode. + \param m popup menu title display mode (QtxMenu::TitleMode) +*/ +void QtxMenu::setTitleMode( const QtxMenu::TitleMode m ) +{ + if ( myMode == m ) + return; + + myMode = m; + + updateTitle(); +} + +/*! + \brief Set title alignment flags. + \param a title alignment flags +*/ +void QtxMenu::setTitleAlignment( const Qt::Alignment a ) +{ + if ( titleAlignment() == a ) + return; + + myTitle->setAlignment( a ); + + updateTitle(); +} + +/*! + \brief Customize show/hide menu operation. + \param on new popup menu visibility state +*/ +void QtxMenu::setVisible( bool on ) +{ + if ( on ) + insertTitle(); + + QMenu::setVisible( on ); + + if ( !on ) + removeTitle(); +} + +/*! + \brief Insert title item to the popup menu. +*/ +void QtxMenu::insertTitle() +{ + if ( titleMode() == TitleOff || ( titleMode() == TitleAuto && titleText().trimmed().isEmpty() ) ) + return; + + if ( actions().isEmpty() ) + addAction( myAction ); + else + insertAction( actions().first(), myAction ); +} + +/*! + \brief Remove title item from the popup menu. +*/ +void QtxMenu::removeTitle() +{ + if ( actions().contains( myAction ) ) + removeAction( myAction ); +} + +/*! + \brief Update title item. +*/ +void QtxMenu::updateTitle() +{ + if ( !actions().contains( myAction ) ) + return; + + removeTitle(); + insertTitle(); +} diff --git a/src/Qtx/QtxMenu.h b/src/Qtx/QtxMenu.h new file mode 100644 index 000000000..9a50f23c7 --- /dev/null +++ b/src/Qtx/QtxMenu.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/ or email : webmaster.salome@opencascade.com +// +// File: QtxMenu.h +// Author: Sergey TELKOV +// + +#ifndef QTXMENU_H +#define QTXMENU_H + +#include "Qtx.h" + +#include + +class QWidgetAction; + +class QTX_EXPORT QtxMenu : public QMenu +{ + Q_OBJECT + + class Title; + +public: + //! Popup menu title mode + typedef enum { + TitleAuto, //!< auto mode + TitleOn, //!< always on (display title) + TitleOff //!< always off (do not display title) + } TitleMode; + +public: + QtxMenu( QWidget* = 0 ); + virtual ~QtxMenu(); + + QIcon titleIcon() const; + QString titleText() const; + + TitleMode titleMode() const; + Qt::Alignment titleAlignment() const; + + virtual void setTitleIcon( const QIcon& ); + virtual void setTitleText( const QString& ); + + virtual void setTitleMode( const TitleMode ); + virtual void setTitleAlignment( const Qt::Alignment ); + +public slots: + virtual void setVisible( bool ); + +private: + void updateTitle(); + void insertTitle(); + void removeTitle(); + +private: + TitleMode myMode; + Title* myTitle; + QWidgetAction* myAction; +}; + +#endif // QTXMENU_H diff --git a/src/Qtx/QtxPathDialog.h b/src/Qtx/QtxPathDialog.h index 57b887756..29dbac051 100755 --- a/src/Qtx/QtxPathDialog.h +++ b/src/Qtx/QtxPathDialog.h @@ -94,7 +94,7 @@ private: QStringList prepareFilters( const QString& ) const; bool hasVisibleChildren( QWidget* ) const; QStringList filterWildCards( const QString& ) const; - QString autoExtension( const QString&, const QString& = QString::null ) const; + QString autoExtension( const QString&, const QString& = QString() ) const; protected: enum { OpenFile, SaveFile, OpenDir, SaveDir, NewDir }; diff --git a/src/Qtx/QtxResourceMgr.cxx b/src/Qtx/QtxResourceMgr.cxx index 45f5a2609..6a83b7b56 100644 --- a/src/Qtx/QtxResourceMgr.cxx +++ b/src/Qtx/QtxResourceMgr.cxx @@ -658,7 +658,7 @@ bool QtxResourceMgr::IniFormat::save( const QString& fname, const QMapmyResources.append( new Resources( that, userFileName( appName() ) ) ); - for ( QStringList::const_iterator it = myDirList.begin(); it != myDirList.end(); ++it ) + for ( QStringList::ConstIterator it = myDirList.begin(); it != myDirList.end(); ++it ) { QString path = Qtx::addSlash( *it ) + globalFileName( appName() ); that->myResources.append( new Resources( that, path ) ); @@ -1266,7 +1265,7 @@ void QtxResourceMgr::setIsPixmapCached( const bool on ) */ void QtxResourceMgr::clear() { - for ( ResList::iterator it = myResources.begin(); it != myResources.end(); ++it ) + for ( ResList::Iterator it = myResources.begin(); it != myResources.end(); ++it ) (*it)->clear(); } @@ -1448,7 +1447,7 @@ bool QtxResourceMgr::value( const QString& sect, const QString& name, QByteArray baVal.clear(); QStringList lst = val.split( QRegExp( "[\\s|,]" ), QString::SkipEmptyParts ); - for ( QStringList::const_iterator it = lst.begin(); it != lst.end(); ++it ) + for ( QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it ) { int base = 10; QString str = *it; @@ -1533,7 +1532,7 @@ bool QtxResourceMgr::value( const QString& sect, const QString& name, QString& v bool ok = false; - ResList::const_iterator it = myResources.begin(); + ResList::ConstIterator it = myResources.begin(); if ( ignoreUserValues() ) ++it; @@ -1743,7 +1742,7 @@ bool QtxResourceMgr::hasValue( const QString& sect, const QString& name ) const initialize(); bool ok = false; - for ( ResList::const_iterator it = myResources.begin(); it != myResources.end() && !ok; ++it ) + for ( ResList::ConstIterator it = myResources.begin(); it != myResources.end() && !ok; ++it ) ok = (*it)->hasValue( sect, name ); return ok; @@ -1759,7 +1758,7 @@ bool QtxResourceMgr::hasSection( const QString& sect ) const initialize(); bool ok = false; - for ( ResList::const_iterator it = myResources.begin(); it != myResources.end() && !ok; ++it ) + for ( ResList::ConstIterator it = myResources.begin(); it != myResources.end() && !ok; ++it ) ok = (*it)->hasSection( sect ); return ok; @@ -1940,7 +1939,7 @@ void QtxResourceMgr::remove( const QString& sect ) { initialize(); - for ( ResList::iterator it = myResources.begin(); it != myResources.end(); ++it ) + for ( ResList::Iterator it = myResources.begin(); it != myResources.end(); ++it ) (*it)->removeSection( sect ); } @@ -1953,7 +1952,7 @@ void QtxResourceMgr::remove( const QString& sect, const QString& name ) { initialize(); - for ( ResList::iterator it = myResources.begin(); it != myResources.end(); ++it ) + for ( ResList::Iterator it = myResources.begin(); it != myResources.end(); ++it ) (*it)->removeValue( sect, name ); } @@ -1985,14 +1984,14 @@ void QtxResourceMgr::setCurrentFormat( const QString& fmt ) if ( myResources.isEmpty() ) return; - ResList::iterator resIt = myResources.begin(); + ResList::Iterator resIt = myResources.begin(); if ( myResources.count() > myDirList.count() && resIt != myResources.end() ) { (*resIt)->setFile( userFileName( appName() ) ); ++resIt; } - for ( QStringList::const_iterator it = myDirList.begin(); it != myDirList.end() && resIt != myResources.end(); ++it, ++resIt ) + for ( QStringList::ConstIterator it = myDirList.begin(); it != myDirList.end() && resIt != myResources.end(); ++it, ++resIt ) (*resIt)->setFile( Qtx::addSlash( *it ) + globalFileName( appName() ) ); } @@ -2004,7 +2003,7 @@ void QtxResourceMgr::setCurrentFormat( const QString& fmt ) QtxResourceMgr::Format* QtxResourceMgr::format( const QString& fmt ) const { Format* form = 0; - for ( FormatList::const_iterator it = myFormats.begin(); it != myFormats.end() && !form; ++it ) + for ( FormatList::ConstIterator it = myFormats.begin(); it != myFormats.end() && !form; ++it ) { if ( (*it)->format() == fmt ) form = *it; @@ -2086,7 +2085,7 @@ bool QtxResourceMgr::load() return false; bool res = true; - for ( ResList::iterator it = myResources.begin(); it != myResources.end(); ++it ) + for ( ResList::Iterator it = myResources.begin(); it != myResources.end(); ++it ) res = fmt->load( *it ) && res; return res; @@ -2141,10 +2140,10 @@ QStringList QtxResourceMgr::sections() const initialize(); QMap map; - for ( ResList::const_iterator it = myResources.begin(); it != myResources.end(); ++it ) + for ( ResList::ConstIterator it = myResources.begin(); it != myResources.end(); ++it ) { QStringList lst = (*it)->sections(); - for ( QStringList::const_iterator itr = lst.begin(); itr != lst.end(); ++itr ) + for ( QStringList::ConstIterator itr = lst.begin(); itr != lst.end(); ++itr ) map.insert( *itr, 0 ); } @@ -2170,14 +2169,13 @@ QStringList QtxResourceMgr::parameters( const QString& sec ) const typedef IMap PMap; #endif PMap pmap; - ResList lst; - for ( ResList::const_iterator itr = myResources.begin(); itr != myResources.end(); ++itr ) - lst.prepend( *itr ); - for ( ResList::const_iterator it = lst.begin(); it != lst.end(); ++it ) + ResList::ConstIterator it = myResources.end(); + while ( it != myResources.begin() ) { + --it; QStringList lst = (*it)->parameters( sec ); - for ( QStringList::const_iterator itr = lst.begin(); itr != lst.end(); ++itr ) + for ( QStringList::ConstIterator itr = lst.begin(); itr != lst.end(); ++itr ) pmap.insert( *itr, 0, false ); } @@ -2205,7 +2203,7 @@ QStringList QtxResourceMgr::parameters( const QString& sec ) const QString QtxResourceMgr::path( const QString& sect, const QString& prefix, const QString& name ) const { QString res; - for ( ResList::const_iterator it = myResources.begin(); it != myResources.end() && res.isEmpty(); ++it ) + for ( ResList::ConstIterator it = myResources.begin(); it != myResources.end() && res.isEmpty(); ++it ) res = (*it)->path( sect, prefix, name ); return res; } @@ -2318,7 +2316,7 @@ QPixmap QtxResourceMgr::loadPixmap( const QString& prefix, const QString& name, initialize(); QPixmap pix; - for ( ResList::const_iterator it = myResources.begin(); it != myResources.end() && pix.isNull(); ++it ) + for ( ResList::ConstIterator it = myResources.begin(); it != myResources.end() && pix.isNull(); ++it ) pix = (*it)->loadPixmap( resSection(), prefix, name ); if ( pix.isNull() ) pix = defPix; @@ -2348,7 +2346,36 @@ QPixmap QtxResourceMgr::loadPixmap( const QString& prefix, const QString& name, */ void QtxResourceMgr::loadLanguage( const QString& pref, const QString& l ) { - initialize(); + loadLanguage( true, pref, l ); +} + +/*! + \brief Load translation files according to the specified language. + + Names of the translation files are calculated according to the pattern specified + by the "translators" option (this option is read from the section "language" of resources files). + By default, "%P_msg_%L.qm" pattern is used. + Keywords \%A, \%P, \%L in the pattern are substituted by the application name, prefix and language name + correspondingly. + For example, for prefix "SUIT" and language "en", all translation files "SUIT_msg_en.qm" are searched and + loaded. + + If prefix is empty or null string, all translation files specified in the "resources" section of resources + files are loaded (actually, the section is retrieved from resSection() method). + If language is not specified, it is retrieved from the langSection() method, and if the latest is also empty, + by default "en" (English) language is used. + By default, settings from the user preferences file are also loaded (if user resource file is valid, + see userFileName()). To avoid loading user settings, pass \c false as first parameter. + + \param loadUser if \c true then user settings are also loaded + \param pref parameter which defines translation context (for example, package name) + \param l language name + + \sa resSection(), langSection(), loadTranslators() +*/ +void QtxResourceMgr::loadLanguage( const bool loadUser, const QString& pref, const QString& l ) +{ + initialize( true, loadUser ); QMap substMap; substMap.insert( 'A', appName() ); @@ -2391,13 +2418,13 @@ void QtxResourceMgr::loadLanguage( const QString& pref, const QString& l ) else prefixList = parameters( resSection() ); - for ( QStringList::const_iterator iter = prefixList.begin(); iter != prefixList.end(); ++iter ) + for ( QStringList::ConstIterator 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 ) + for ( QStringList::ConstIterator it = trList.begin(); it != trList.end(); ++it ) trs.append( substMacro( *it, substMap ).trimmed() ); loadTranslators( prefix, trs ); @@ -2415,14 +2442,14 @@ void QtxResourceMgr::loadTranslators( const QString& prefix, const QStringList& initialize(); ResList lst; - for ( ResList::iterator iter = myResources.begin(); iter != myResources.end(); ++iter ) + for ( ResList::Iterator iter = myResources.begin(); iter != myResources.end(); ++iter ) lst.prepend( *iter ); QTranslator* trans = 0; - for ( ResList::iterator it = lst.begin(); it != lst.end(); ++it ) + for ( ResList::Iterator it = lst.begin(); it != lst.end(); ++it ) { - for ( QStringList::const_iterator itr = translators.begin(); itr != translators.end(); ++itr ) + for ( QStringList::ConstIterator itr = translators.begin(); itr != translators.end(); ++itr ) { trans = (*it)->loadTranslator( resSection(), prefix, *itr ); if ( trans ) @@ -2446,9 +2473,11 @@ void QtxResourceMgr::loadTranslator( const QString& prefix, const QString& name initialize(); QTranslator* trans = 0; - ResList::iterator it = myResources.end(); - for ( ; it != myResources.begin(); --it ) + + ResList::ConstIterator it = myResources.end(); + while ( it != myResources.begin() ) { + --it; trans = (*it)->loadTranslator( resSection(), prefix, name ); if ( trans ) { @@ -2468,7 +2497,7 @@ void QtxResourceMgr::removeTranslators( const QString& prefix ) if ( !myTranslator.contains( prefix ) ) return; - for ( TransList::iterator it = myTranslator[prefix].begin(); it != myTranslator[prefix].end(); ++it ) + for ( TransList::Iterator it = myTranslator[prefix].begin(); it != myTranslator[prefix].end(); ++it ) { QApplication::instance()->removeTranslator( *it ); delete *it; @@ -2487,7 +2516,7 @@ void QtxResourceMgr::raiseTranslators( const QString& prefix ) if ( !myTranslator.contains( prefix ) ) return; - for ( TransList::iterator it = myTranslator[prefix].begin(); it != myTranslator[prefix].end(); ++it ) + for ( TransList::Iterator it = myTranslator[prefix].begin(); it != myTranslator[prefix].end(); ++it ) { QApplication::instance()->removeTranslator( *it ); QApplication::instance()->installTranslator( *it ); @@ -2501,10 +2530,10 @@ void QtxResourceMgr::raiseTranslators( const QString& prefix ) void QtxResourceMgr::refresh() { QStringList sl = sections(); - for ( QStringList::const_iterator it = sl.begin(); it != sl.end(); ++it ) + for ( QStringList::ConstIterator it = sl.begin(); it != sl.end(); ++it ) { QStringList pl = parameters( *it ); - for ( QStringList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr ) + for ( QStringList::ConstIterator itr = pl.begin(); itr != pl.end(); ++itr ) setResource( *it, *itr, stringValue( *it, *itr ) ); } } @@ -2519,7 +2548,7 @@ void QtxResourceMgr::refresh() void QtxResourceMgr::setDirList( const QStringList& dl ) { myDirList = dl; - for ( ResList::iterator it = myResources.begin(); it != myResources.end(); ++it ) + for ( ResList::Iterator it = myResources.begin(); it != myResources.end(); ++it ) delete *it; myResources.clear(); diff --git a/src/Qtx/QtxResourceMgr.h b/src/Qtx/QtxResourceMgr.h index 9e5ba1716..550c14e30 100644 --- a/src/Qtx/QtxResourceMgr.h +++ b/src/Qtx/QtxResourceMgr.h @@ -138,6 +138,7 @@ public: QPixmap loadPixmap( const QString&, const QString&, const bool ) const; QPixmap loadPixmap( const QString&, const QString&, const QPixmap& ) const; void loadLanguage( const QString& = QString(), const QString& = QString() ); + void loadLanguage( const bool, const QString& = QString(), const QString& = QString() ); void raiseTranslators( const QString& ); void removeTranslators( const QString& ); @@ -163,7 +164,7 @@ protected: virtual QString globalFileName( const QString& ) const; private: - void initialize( const bool = true ) const; + void initialize( const bool = true, const bool = true ) const; QString substMacro( const QString&, const QMap& ) const; private: diff --git a/src/Qtx/QtxSplash.cxx b/src/Qtx/QtxSplash.cxx index d57c843a1..044d8fe88 100644 --- a/src/Qtx/QtxSplash.cxx +++ b/src/Qtx/QtxSplash.cxx @@ -70,20 +70,25 @@ private: /*! \class QtxSplash - \brief The QtxSplash widget provides a splash screen that can be shown during application startup.. - - A splash screen is a widget that is usually displayed when an application is being started. - Splash screens are often used for applications that have long start up times to provide - the user with feedback that the application is loading. - - Only one instance of the QtxSplash widget can be created. To access to the splash screen widget, - use static method QtxSplash::splash(), which creates and instance of the QtxSplash widget if - necessary and returns pointer to it. You should not destroy yhis instance - it is done automatically - after application main window is shown. Just use methods finish() to make splash screen wait untill - main window is shown. - - The splash screen appears in the center of the screen. The most common usage is to show a splash - screen before the main widget is displayed on the screen. + \brief The QtxSplash widget provides a splash screen that can be shown + during application startup. + + A splash screen is a widget that is usually displayed when an application + is being started. + Splash screens are often used for applications that have long start up times + to provide the user with feedback that the application is loading. + + Only one instance of the QtxSplash widget can be created. To access the splash + screen widget, use static method QtxSplash::splash(), which creates an + instance of the QtxSplash widget (if it is not yet creaed) and returns a + pointer to it. + You should not destroy this instance - it is done automatically after + application main window is shown. Just use methods finish() to make splash + screen wait untill main window is shown. + + The splash screen appears in the center of the screen. + The most common usage is to show a splash screen before the main widget + is displayed on the screen. For example, \code int main(int argc, char *argv[]) @@ -101,54 +106,71 @@ private: } \endcode - The user can hide the splash screen by clicking on it with the mouse. Since the splash screen is - typically displayed before the event loop has started running, it is necessary to periodically call + The user can hide the splash screen by clicking on it with the mouse. + Since the splash screen is typically displayed before the event loop + has started running, it is necessary to periodically call QApplication::processEvents() to receive the mouse clicks. - This feature can be switched off by using method setHideOnClick() with \c false parameter. + To activate the possibility of hiding the splash screen on the mouse + click, use setHideOnClick() method passing \c true as parameter. + By default, this feature is switched off. - It is sometimes useful to update the splash screen with messages and/or progress information, - for example, announcing connections established or modules loaded as the application starts up. - QtxSplash class provides the functionality to show status messages and(or) progress bar. + It is sometimes useful to update the splash screen with any status messages + and/or progress information, for example, announcing connections established + or modules loaded as the application starts up. + QtxSplash class provides the functionality to show status messages + and(or) progress bar. \code QPixmap pixmap(":/splash.png"); QtxSplash* splash = QtxSplash::splash(pixmap); - splash->setProgress(0, 5); + splash->setProgress(0, 5); // progress from 0 to 5 splash->show(); app.processEvents(); // doing first step splash->setMessage("Step 1"); - splash->ress(1); + splash->setProgress(1); // progress is 20% qApp->processEvents(); // ... perform some actions // doing second step splash->setMessage("Step 2"); - splash->setProgress(2); + splash->setProgress(2); // progress is 40% qApp->processEvents(); // ... perform some actions ... et cetera \endcode - There is a static function QtxSplash::setStatus() which allows to put next status message - and progress with one call. It can substitue two calls: setMessage() and setProgress(). - - QtxSplash class provides alos a lot of functions to set-up its behavior. Set progress - bar width with setProgressWidth() method, its position and direction with setProgressFlags(). - It can be single-colored or gradient-colored. Use setProgressColors() method for this. - You can even set your own gradient scale with QLinearGradient and use it for the progress - bar coloring: setProgressGradient(). - - To change the progress bar and status message transparency, use setOpacity() function. - The methods setTextAlignment(), setTextColor() and setTextColors() can be used to change - the attributes of the status message. - - The displayed message text includes constant info and status message. The constant info - is set by setConstantInfo() method and status message is set by setMessage(). - - Sometimes it is useful to splay an error message above the splash screen window. - For example, it can be necessary if an error occurs when loading the application. - Method setError() can be used to show the error message and set the error code which - can be then retrieved with the error() function. + There is a static function QtxSplash::setStatus() which allows to put the + next status message and current progress with one call. + It can substitue two calls: setMessage() and setProgress(). + + QtxSplash class provides also a lot of functions to customize its behavior. + Set progress bar width with setProgressWidth() method, its position and + direction with setProgressFlags(). + It can be single-colored or gradient-colored. Use setProgressColors() methods + for this. You can even set your own gradient scale with QLinearGradient, + QRadialGradient or QConicalGradient and use it for the progress + bar coloring. In addition, it is possible to enable/disable displaying + of the progress percentage with setPercentageVisible() method. + + Displaying of the progress bar and status messages can be switched on/off with + setProgressVisible() and setMessageVisible() methods. + + To change the progress bar and status message transparency, use + setOpacity() function. The methods setTextAlignment() and setTextColors() + can be used to change the attributes of the status messages. + + The displayed message text can include constant info and status message. + The constant info is set by setConstantInfo() method and status message + is set by setMessage(). + + Sometimes it is useful to display an error message above the splash screen + window. For example, it can be necessary if an error occurs when loading + the application. Method setError() can be used to show the error message + and set the error code which can be then retrieved with the error() function. + + There is one more helpful feature. The QtxSplash class can read all the + settings from the resource file with help of resource manager + (QtxResourceMgr class). Refer to the method readSettings() for more details. */ //! The only one instance of splash screen @@ -156,8 +178,11 @@ QtxSplash* QtxSplash::mySplash = 0; /*! \brief Constructor. - \brief Construct a splash screen that will display the \a pixmap. + + Construct a splash screen that will display the \a pixmap. + \param pixmap splash screen pixmap + \sa setPixmap(), pixmap() */ QtxSplash::QtxSplash( const QPixmap& pixmap ) : QWidget( 0, Qt::SplashScreen | Qt::WindowStaysOnTopHint ), @@ -166,14 +191,14 @@ QtxSplash::QtxSplash( const QPixmap& pixmap ) myHideOnClick( false ), myProgress( 0 ), myTotal( 0 ), - myStartColor( Qt::red ), - myGradientType( Vertical ), myProgressWidth( 10 ), myProgressFlags( BottomSide | LeftToRight ), myMargin( 5 ), myOpacity( 1.0 ), myError( 0 ), - myGradientUsed( false ) + myShowPercent( true ), + myShowProgress( true ), + myShowMessage( true ) { setAttribute( Qt::WA_DeleteOnClose, true ); setPixmap( pixmap ); @@ -195,6 +220,7 @@ QtxSplash::~QtxSplash() \param px splash screen pixmap \return splash screen widget + \sa setPixmap(), pixmap() */ QtxSplash* QtxSplash::splash( const QPixmap& px ) { @@ -313,6 +339,69 @@ bool QtxSplash::hideOnClick() const return myHideOnClick; } +/*! + \brief Enable/disable displaying of the progress bar. + \param on if \c true, progress bar will be enabled + \sa progressVisible(), setMessageVisible() +*/ +void QtxSplash::setProgressVisible( const bool on ) +{ + myShowProgress = on; + repaint(); +} + +/*! + \brief Check if the progress bar is displayed. + \return \c true if progress bar is enabled + \sa setProgressVisible() +*/ +bool QtxSplash::progressVisible() const +{ + return myShowProgress; +} + +/*! + \brief Enable/disable displaying of the status message. + \param on if \c true, status message will be enabled + \sa messageVisible(), setProgressVisible() +*/ +void QtxSplash::setMessageVisible( const bool on ) +{ + myShowMessage = on; + repaint(); +} + +/*! + \brief Check if the status message is displayed. + \return \c true if status message is enabled + \sa setMessageVisible() +*/ +bool QtxSplash::messageVisible() const +{ + return myShowMessage; +} + +/*! + \brief Enable/disable displaying progress percentage. + \param enable if \c true, percentage will be displayed + \sa percentageVisible() +*/ +void QtxSplash::setPercentageVisible( const bool enable ) +{ + myShowPercent = enable; + repaint(); +} + +/*! + \brief Check if the progress percentage is displayed. + \return \c true if percentage displaying is enabled + \sa setPercentageVisible() +*/ +bool QtxSplash::percentageVisible() const +{ + return myShowPercent; +} + /*! \brief Set total progress steps to \a total. \param total total number of progress steps @@ -369,7 +458,11 @@ void QtxSplash::setProgress( const int progress, const int total ) } /*! - \brief Set margin (a border width). + \brief Set splash window margin (a border width). + + Note, that margin is used only for drawing the progress bar and status + messages. + \param margin new margin width \sa margin() */ @@ -380,7 +473,7 @@ void QtxSplash::setMargin( const int margin ) } /*! - \brief Get margin (a border width). + \brief Get splash window margin (a border width). \return current margin width \sa setMargin() */ @@ -414,7 +507,7 @@ int QtxSplash::progressWidth() const \brief Set progress bar position and direction. By default, progress bar is displayed at the bottom side and - shows progress from left to right. + shows progress from left to right but this behaviour can be changed. \param flags ORed progress bar flags (QtxSplash::ProgressBarFlags) \sa progressFlags() @@ -442,54 +535,57 @@ int QtxSplash::progressFlags() const /*! \brief Set progress bar colors. - If the colors differ the gradient color bar is drawn. + If the colors differ the two-colored gradient bar is drawn. If the \a endColor is not valid, \a startColor is used instead - (no gradient coloring). + (i.e. simple, one-colored progress bar is drawn). - The parameter \a gradientType defines the type of gradient + The parameter \a orientation defines the type of gradient to be drawn - horizontal or vertical. Default is vertical. - Note, that methods setProgressGradient() and setProgressColors() are - alternative. Only the latest used is taken into account. - \param startColor start gradient color (or mono-color) \param endColor end gradient color - \param gradientType gradient type (QtxSplash::GradientType) - \sa progressColors(), setProgressGradient() + \param orientation gradient type (Qt::Orientation) + \sa progressColors() */ -void QtxSplash::setProgressColors( const QColor& startColor, - const QColor& endColor, - const GradientType gradientType ) +void QtxSplash::setProgressColors( const QColor& startColor, + const QColor& endColor, + const Qt::Orientation orientation ) { - if ( startColor.isValid() ) - myStartColor = startColor; - myEndColor = endColor; - myGradientType = gradientType; - myGradientUsed = false; - repaint(); -} + if ( !startColor.isValid() ) + return; -/*! - \brief Get progress colors and gradient type. - \param startColor start gradient color (or mono-color) - \param endColor end gradient color - \return gradient type (QtxSplash::GradientType) - \sa setProgressColors() -*/ -QtxSplash::GradientType QtxSplash::progressColors( QColor& startColor, - QColor& endColor ) const -{ - startColor = myStartColor; - endColor = myEndColor; - return myGradientType; + QLinearGradient l; + if ( orientation == Qt::Vertical ) { + l.setStart( 0., 0. ); + l.setFinalStop( 0., 1. ); + } + else { + l.setStart( 0., 0. ); + l.setFinalStop( 1., 0. ); + } + l.setColorAt( 0., startColor ); + l.setColorAt( 1., endColor.isValid() ? endColor : startColor ); + + setProgressColors( l ); } /*! - \brief Set custom progress bar colors. + \brief Set progress bar colors. - The gradient start and final stops are scaled to the actual progress - bar size. For example: + Use this method to display multi-colored gradient progress bar. + You have to use QLinearGradient, QRadialGradient or QConicalGradient + classes to define the gradient. + + Note, that progress bar coordinates can be defined in absolute or + relative mode. + In absolute mode the actual coordinates of the gradient key points + (like start and final point for linear gradient, center and focal point + for radial gradient, etc) are calculated from the top-left progress bar's corner. + In relative mode you have to use values from 0 to 1 (including) to define + the key points positions. + + For example: \code QLinearGradient lg(0.5, 0, 1, 1); lg.setColorAt(0.2, Qt::blue); @@ -498,31 +594,26 @@ QtxSplash::GradientType QtxSplash::progressColors( QColor& startColor, splash->setProgressGradient(lg); \endcode The above code creates linear gradient, which sets start stop to the - center of the progress bar; the final stop is always in the end of - the progress bar. The color scale (blue to red) is changed by the - progress bar diagonal. - - Note, that methods setProgressGradient() and setProgressColors() are - alternative. Only the latest used is taken into account. + center of the progress bar; the final stop is assigned to its right-bottom corner. + The color scale (blue to red) is changed by the progress bar diagonal. \param gradient color gradient to be used for progress bar coloring - \sa progressGradient(), setProgressColors() + \sa progressColors() */ -void QtxSplash::setProgressGradient( const QLinearGradient& gradient ) +void QtxSplash::setProgressColors( const QGradient& gradient ) { myGradient = gradient; - myGradientUsed = true; repaint(); } /*! \brief Get custom progress bar colors. \return color gradient used for progress bar coloring - \sa setProgressGradient() + \sa setProgressColors() */ -QLinearGradient QtxSplash::progressGradient() const +const QGradient* QtxSplash::progressColors() const { - return myGradient; + return &myGradient; } /*! @@ -575,50 +666,32 @@ int QtxSplash::textAlignment() const } /*! - \brief Set message text color. + \brief Set message text colors. - Default message color is white. - - \param color message text color - \sa setTextColors() -*/ -void QtxSplash::setTextColor( const QColor& color ) -{ - if ( myColor.isValid() ) - myColor = color; - myShadowColor = QColor(); - repaint(); -} + If \a shadow parameter is invalid color, the simple one-colored + text is drawn. Otherwise, second parameter is used to draw the text + shadow. -/*! - \brief Get message text color. - \return color message text color - \sa setTextColor() -*/ -QColor QtxSplash::textColor() const -{ - return myColor; -} - -/*! - \brief Set message text color and text shadow color. \param color message text color \param shadow message text shadow color - \sa textColors(), textColor(), setTextColor() + \sa textColors() */ void QtxSplash::setTextColors( const QColor& color, const QColor& shadow ) { - if ( myColor.isValid() ) - myColor = color; + if ( !myColor.isValid() ) + return; + + myColor = color; myShadowColor = shadow; + repaint(); } /*! - \brief Get message text color and text shadow color. + \brief Get message text colors. \param color message text color \param shadow message text shadow color - \sa setTextColors(), textColor(), setTextColor() + \sa setTextColors() */ void QtxSplash::textColors( QColor& color, QColor& shadow ) const { @@ -634,7 +707,7 @@ void QtxSplash::textColors( QColor& color, QColor& shadow ) const message is set by setMessage(). \param info constant info text - \sa constantInfo(), message(), setMessage() + \sa constantInfo(), message(), setMessage(), option(), setOption() */ void QtxSplash::setConstantInfo( const QString& info ) { @@ -659,14 +732,22 @@ QString QtxSplash::constantInfo() const which is replaced at the time of the displaying. The following options are supported: - - %A - could be used as application name - - %V - could be used as application version - - %L - could be used as application license information - - %C - could be used as application copyright information + - \c \%A - could be used as application name + - \c \%V - could be used as application version + - \c \%L - could be used as application license information + - \c \%C - could be used as application copyright information + For example, + \code + splash->setContantInfo("%A [%V]\n%C"); + splash->setOption("%A", "MyApplication" ); + splash->setOption("%V", "Version 1.0" ); + splash->setOption("%C", "Copyright (C) MyCompany 2008" ); + \endcode + \param name option name \param option value - \sa option() + \sa option(), setConstantInfo(), constantInfo() */ void QtxSplash::setOption( const QString& name, const QString& value ) { @@ -678,7 +759,7 @@ void QtxSplash::setOption( const QString& name, const QString& value ) \brief Get constant information option value. \param name option name \return option value or empty string if option is not set - \sa setOption() + \sa setOption(), setConstantInfo(), constantInfo() */ QString QtxSplash::option( const QString& name ) const { @@ -701,8 +782,8 @@ QString QtxSplash::message() const /*! \brief Get error code. - This function returns error code, set previoiusly with - error(const QString&, const QString&, const int) method. + This function returns error code, set previously with + setError() method. If no error code has been set, 0 is returned. \return last error code @@ -744,12 +825,33 @@ void QtxSplash::repaint() /*! \brief Read splash settings from the resources manager. + + This method can be used to setup the splash screen look-n-feel. + By default, "splash" section of the resources file is used, but you can + use any other section. + All the splash screen parameters can be defined via resources file: + - \c "image" : splash screen image, see setPixmap() + - \c "margin" : splash window margin, see setMargin() + - \c "show_progress" : show progress bar flag, see setProgressVisible() + - \c "show_message" : show status messages flag, see setMessageVisible() + - \c "show_percents" : show progress percentage flag, see setPercentageVisible() + - \c "progress_width" : progress bar width(), see setProgressWidth() + - \c "progress_flags" : progress bar position and direction, see setProgressFlags() + - \c "constant_info" : status messages constant info, see setConstantInfo() + - \c "text_colors" : status messages color(s), see setTextColors() + - \c "progress_colors" : progress bar color(s), see setProgressColors() + - \c "opacity" : progress bar and status messages opacity, see setOpacity() + - \c "font" : status messages font + - \c "alignment" : status messages alignment flags, see setTextAlignment() + - \c "hide_on_click" : hide-on-click flag, see setHideOnClick() + \param resMgr resources manager - \param section resources file section name (if empty, the default name is used). + \param section resources file section name (if empty, the default "splash" + section is used). */ void QtxSplash::readSettings( QtxResourceMgr* resMgr, const QString& section ) { - QString resSection = section.isEmpty() ? "splash" : section; + QString resSection = section.isEmpty() ? QString( "splash" ) : section; // pixmap QString pxname; @@ -769,6 +871,18 @@ void QtxSplash::readSettings( QtxResourceMgr* resMgr, const QString& section ) } #endif + // enable progress bar + bool bShowProgress; + if ( resMgr->value( resSection, "show_progress", bShowProgress ) ) { + setProgressVisible( bShowProgress ); + } + + // enable status message + bool bShowMessage; + if ( resMgr->value( resSection, "show_message", bShowMessage ) ) { + setMessageVisible( bShowMessage ); + } + // margin int m; if ( resMgr->value( resSection, "margin", m ) ) { @@ -850,20 +964,32 @@ void QtxSplash::readSettings( QtxResourceMgr* resMgr, const QString& section ) } setTextAlignment( fl ); } - // progress color(s) QString pc; - QLinearGradient grad; - if ( resMgr->value( resSection, "progress_gradient", grad ) ) { - // gradient-colored progress bar - setProgressGradient( grad ); + QLinearGradient lgrad; + QRadialGradient rgrad; + QConicalGradient cgrad; + if ( resMgr->value( resSection, "progress_color", lgrad ) || + resMgr->value( resSection, "progress_colors", lgrad ) ) { + // linear gradient-colored progress bar + setProgressColors( lgrad ); + } + else if ( resMgr->value( resSection, "progress_color", rgrad ) || + resMgr->value( resSection, "progress_colors", rgrad ) ) { + // radial gradient-colored progress bar + setProgressColors( rgrad ); + } + else if ( resMgr->value( resSection, "progress_color", cgrad ) || + resMgr->value( resSection, "progress_colors", cgrad ) ) { + // conical gradient-colored progress bar + setProgressColors( cgrad ); } else if ( resMgr->value( resSection, "progress_color", pc ) || resMgr->value( resSection, "progress_colors", pc ) ) { // one/two-colored progress bar QStringList colors = pc.split( "|", QString::SkipEmptyParts ); QColor c1, c2; - QtxSplash::GradientType gradType = QtxSplash::Vertical; + Qt::Orientation o = Qt::Vertical; if ( colors.count() > 0 ) c1 = QColor( colors[0] ); if ( colors.count() > 1 ) c2 = QColor( colors[1] ); int gt; @@ -871,17 +997,20 @@ void QtxSplash::readSettings( QtxResourceMgr* resMgr, const QString& section ) bool bOk; gt = colors[2].toInt( &bOk ); if ( bOk ) { - if ( gt >= QtxSplash::Horizontal && gt <= QtxSplash::Vertical ) - gradType = (QtxSplash::GradientType)gt; + if ( gt == 0 ) + o = Qt::Horizontal; } else { - if ( colors[2].toLower() == "horizontal" ) - gradType = QtxSplash::Horizontal; - else if ( colors[2].toLower() == "vertical" ) - gradType = QtxSplash::Vertical; + if ( colors[2].toLower().startsWith( "h" ) ) + o = Qt::Horizontal; } } - setProgressColors( c1, c2, gradType ); + setProgressColors( c1, c2, o ); + } + // show percents + bool bPercent; + if ( resMgr->value( resSection, "show_percents", bPercent ) ) { + setPercentageVisible( bPercent ); } // text color(s) @@ -938,7 +1067,10 @@ void QtxSplash::setMessage( const QString& msg ) /*! \brief Remove the message being displayed on the splash screen. - \sa message() + + This is equivalent to setMessage(""); + + \sa message(), setMessage() */ void QtxSplash::clear() { @@ -948,19 +1080,19 @@ void QtxSplash::clear() /*! \brief Draw the contents of the splash screen. - \param painter painter + \param p painter */ void QtxSplash::drawContents( QPainter* p ) { // draw progress bar - if ( myTotal > 0 ) { + if ( myTotal > 0 && progressVisible() ) { p->save(); drawProgressBar( p ); p->restore(); } // draw status message - if ( !fullMessage().isEmpty() ) { + if ( !fullMessage().isEmpty() && messageVisible() ) { p->save(); drawMessage( p ); p->restore(); @@ -1013,9 +1145,40 @@ void QtxSplash::customEvent( QEvent* ce ) } } +/*! + \brief Check if the gradient is defined in the relative coordinates [static]. + \internal + \return \c true if gradient is defined in the relative coordinates +*/ +static bool checkGradient( const QGradient* g ) +{ +#define BOUNDED( a, min, max ) ( a >= min && a <= max ) + if ( g->type() == QGradient::LinearGradient ) { + const QLinearGradient* lg = static_cast( g ); + return BOUNDED( lg->start().x(), 0.0, 1.0 ) && + BOUNDED( lg->start().y(), 0.0, 1.0 ) && + BOUNDED( lg->finalStop().x(), 0.0, 1.0 ) && + BOUNDED( lg->finalStop().y(), 0.0, 1.0 ); + } + if ( g->type() == QGradient::RadialGradient ) { + const QRadialGradient* rg = static_cast( g ); + return BOUNDED( rg->center().x(), 0.0, 1.0 ) && + BOUNDED( rg->center().y(), 0.0, 1.0 ) && + BOUNDED( rg->focalPoint().x(), 0.0, 1.0 ) && + BOUNDED( rg->focalPoint().y(), 0.0, 1.0 ); // && BOUNDED( rg->radius(), 0.0, 1.0 ); + } + if ( g->type() == QGradient::ConicalGradient ) { + const QConicalGradient* cg = static_cast( g ); + return BOUNDED( cg->center().x(), 0.0, 1.0 ) && + BOUNDED( cg->center().y(), 0.0, 1.0 ); + } + return false; +} + /*! \brief Draw progress bar. \param p painter + \sa drawMessage() */ void QtxSplash::drawProgressBar( QPainter* p ) { @@ -1046,35 +1209,90 @@ void QtxSplash::drawProgressBar( QPainter* p ) if ( myProgressFlags & RightToLeft) cr.translate( 0, r.height() - cr.height() ); } - int x1, x2, y1, y2; - if ( myGradientType == Horizontal ) { - x1 = r.left(); x2 = r.right(); y1 = y2 = 0; - } - else { - x1 = x2 = 0; y1 = r.top(); y2 = r.bottom(); - } - QLinearGradient lg; - if ( myGradientUsed ) { - QPointF start = myGradient.start(); - QPointF final = myGradient.finalStop(); - qreal xd = final.x() - start.x(); - qreal yd = final.y() - start.y(); - lg.setStart( xd != 0 ? r.left() + r.width() * start.x() / xd : 0, - yd != 0 ? r.top() + r.height() * start.y() / yd : 0 ); - lg.setFinalStop( xd != 0 ? r.right() : 0, yd != 0 ? r.bottom() : 0 ); - lg.setStops( myGradient.stops() ); - lg.setSpread( myGradient.spread() ); - } - else { - lg.setStart( x1, y1 ); - lg.setFinalStop( x2, y2 ); - lg.setColorAt( 0, myStartColor ); - lg.setColorAt( 1, myEndColor.isValid() ? myEndColor : myStartColor ); + QBrush b; + switch ( progressColors()->type() ) { + case QGradient::LinearGradient: + { + QLinearGradient lg; + const QLinearGradient* other = static_cast( progressColors() ); + if ( checkGradient( other ) ) { + // gradient is defined in relative coordinates [0.0 - 1.0] + lg.setStart( r.left() + r.width() * other->start().x(), + r.top() + r.height() * other->start().y() ); + lg.setFinalStop( r.left() + r.width() * other->finalStop().x(), + r.top() + r.height() * other->finalStop().y() ); + } + else { + // gradient is defined in absolute coordinates + // according to its dimensions + lg.setStart( r.topLeft() + other->start() ); + lg.setFinalStop( r.topLeft() + other->finalStop() ); + } + + lg.setStops( other->stops() ); + lg.setSpread( other->spread() ); + + b = QBrush( lg ); + + break; + } // case QGradient::LinearGradient + case QGradient::RadialGradient: + { + QRadialGradient rg; + const QRadialGradient* other = static_cast( progressColors() ); + if ( checkGradient( other ) ) { + // gradient is defined in relative coordinates [0.0 - 1.0] + rg.setCenter( r.left() + r.width() * other->center().x(), + r.top() + r.height() * other->center().y() ); + rg.setFocalPoint( r.left() + r.width() * other->focalPoint().x(), + r.top() + r.height() * other->focalPoint().y() ); + } + else { + // gradient is defined in absolute coordinates + // according to its dimensions + rg.setCenter( r.topLeft() + other->center() ); + rg.setFocalPoint( r.topLeft() + other->focalPoint() ); + } + + // only width is taken into account for the radius in relative mode + rg.setRadius( other->radius() > 1.0 ? other->radius() : r.width() * other->radius() ); + + rg.setStops( other->stops() ); + rg.setSpread( other->spread() ); + + b = QBrush( rg ); + + break; + } // case QGradient::RadialGradient + case QGradient::ConicalGradient: + { + QConicalGradient cg; + const QConicalGradient* other = static_cast( progressColors() ); + if ( checkGradient( other ) ) { + // gradient is defined in relative coordinates [0.0 - 1.0] + cg.setCenter( r.left() + r.width() * other->center().x(), + r.top() + r.height() * other->center().y() ); + } + else { + // gradient is defined in absolute coordinates + // according to its dimensions + cg.setCenter( r.topLeft() + other->center() ); + } + + cg.setAngle( other->angle() ); + cg.setStops( other->stops() ); + cg.setSpread( other->spread() ); + + b = QBrush( cg ); + + break; + } // case QGradient::RadialGradient + default: + b = QBrush( Qt::red ); // default is simple red-colored progress bar + break; } + p->setOpacity( myOpacity ); - p->setClipRect( cr ); - p->fillRect( r, lg ); - p->setClipping( false ); // draw progress bar outline rectangle p->setPen( palette().color( QPalette::Dark ) ); @@ -1083,18 +1301,40 @@ void QtxSplash::drawProgressBar( QPainter* p ) p->setPen( palette().color( QPalette::Light ) ); p->drawLine( r.left(), r.bottom(), r.right(), r.bottom() ); p->drawLine( r.right(), r.top(), r.right(), r.bottom() ); + + r.setCoords( r.left()+1, r.top()+1, r.right()-1, r.bottom()-1 ); + p->setClipRect( cr ); + p->fillRect( r, b ); + p->setClipping( false ); + + if ( myShowPercent ) { + int percent = ( int )( ( myProgress > 0 ? myProgress : 0 ) * 100 / myTotal ); + QFont f = font(); + f.setPixelSize( r.height() - 4 ); + p->setFont( f ); + // draw shadow status text + if ( myShadowColor.isValid() ) { + QRect rs = r; + rs.moveTopLeft( rs.topLeft() + QPoint( 1,1 ) ); + p->setPen( myShadowColor ); + p->drawText( rs, Qt::AlignCenter, QString( "%1%" ).arg( percent ) ); + } + p->setPen( myColor ); + p->drawText( r, Qt::AlignCenter, QString( "%1%" ).arg( percent ) ); + } } /*! \brief Draw status message. \param p painter + \sa drawProgressBar() */ void QtxSplash::drawMessage( QPainter* p ) { // get rect, margin, progress bar width QRect r = rect(); int m = margin(); - int pw = progressWidth(); + int pw = progressVisible() ? progressWidth() : 0; // calculate drawing rect QFontMetrics f( font() ); @@ -1142,6 +1382,7 @@ void QtxSplash::drawMessage( QPainter* p ) /*! \brief Draw the splash screen window contents. + \internal */ void QtxSplash::drawContents() { @@ -1157,6 +1398,7 @@ void QtxSplash::drawContents() /*! \brief Sets error code. \param code error code + \internal */ void QtxSplash::setError( const int code ) { @@ -1167,6 +1409,7 @@ void QtxSplash::setError( const int code ) \brief Get full message which includes constant info and status message. \return get fill message text \sa constantInfo(), setConstantInfo(), message(), setMessage() + \internal */ QString QtxSplash::fullMessage() const { diff --git a/src/Qtx/QtxSplash.h b/src/Qtx/QtxSplash.h index 1d92e70fb..cfebac158 100644 --- a/src/Qtx/QtxSplash.h +++ b/src/Qtx/QtxSplash.h @@ -27,7 +27,7 @@ #include #include -#include +#include #include #ifdef WIN32 @@ -44,12 +44,6 @@ private: QtxSplash( const QPixmap& ); public: - //! Gradient type - typedef enum { - Horizontal, //!< horizontal - Vertical //!< vertical - } GradientType; - //! Progress bar position and direction typedef enum { LeftSide = 0x0001, //!< progress bar is displayed at the left side @@ -72,7 +66,16 @@ public: void setHideOnClick( const bool ); bool hideOnClick() const; - + + void setProgressVisible( const bool ); + bool progressVisible() const; + + void setMessageVisible( const bool ); + bool messageVisible() const; + + void setPercentageVisible( const bool ); + bool percentageVisible() const; + void setTotalSteps( const int ); int totalSteps() const; @@ -85,17 +88,15 @@ public: void setProgressWidth( const int ); int progressWidth() const; - + void setProgressFlags( const int ); int progressFlags() const; void setProgressColors( const QColor&, const QColor& = QColor(), - const GradientType = Vertical ); - GradientType progressColors( QColor&, QColor& ) const; - - void setProgressGradient( const QLinearGradient& ); - QLinearGradient progressGradient() const; + const Qt::Orientation = Qt::Vertical ); + void setProgressColors( const QGradient& ); + const QGradient* progressColors() const; void setOpacity( const double ); double opacity() const; @@ -103,8 +104,6 @@ public: void setTextAlignment( const int ); int textAlignment() const; - void setTextColor( const QColor& ); - QColor textColor() const; void setTextColors( const QColor&, const QColor& = QColor() ); void textColors( QColor&, QColor& ) const; @@ -160,17 +159,16 @@ private: bool myHideOnClick; //!< 'hide on click' flag int myProgress; //!< current progress int myTotal; //!< total progress steps - QColor myStartColor; //!< progress bar gradient starting color - QColor myEndColor; //!< progress bar gradient ending color - GradientType myGradientType; //!< progress bar gradient direction - QLinearGradient myGradient; //!< progress bar custom gradient + QGradient myGradient; //!< progress bar custom gradient int myProgressWidth; //!< progress bar width int myProgressFlags; //!< progress bar flags (QtxSplash::ProgressBarFlags) int myMargin; //!< margin (for progress bar and status message) double myOpacity; //!< progress bar / status message opacity int myError; //!< error code - bool myGradientUsed; //!< 'use custom gradient color scale' flag OptMap myOptions; //!< constant info options + bool myShowProgress; //!< 'show progress bar' flag + bool myShowMessage; //!< 'show status message' flag + bool myShowPercent; //!< 'show percentage' flag }; #endif diff --git a/src/Qtx/QtxToolBar.cxx b/src/Qtx/QtxToolBar.cxx index f450db201..ec881d05a 100644 --- a/src/Qtx/QtxToolBar.cxx +++ b/src/Qtx/QtxToolBar.cxx @@ -41,6 +41,9 @@ public: virtual bool eventFilter( QObject*, QEvent* ); + bool isEmpty() const; + bool isVisible() const; + protected: virtual void customEvent( QEvent* ); @@ -55,11 +58,13 @@ private: void updateVisibility(); + void setEmpty( const bool ); + void setVisible( const bool ); + private: QtxToolBar* myCont; bool myState; bool myEmpty; - bool myVisible; }; /*! @@ -72,8 +77,9 @@ QtxToolBar::Watcher::Watcher( QtxToolBar* cont ) myState( true ), myEmpty( false ) { + setVisible( myCont->isVisibleTo( myCont->parentWidget() ) ); + myCont->installEventFilter( this ); - myVisible = myCont->isVisibleTo( myCont->parentWidget() ); installFilters(); } @@ -116,7 +122,7 @@ void QtxToolBar::Watcher::shown( QtxToolBar* tb ) if ( tb != myCont ) return; - myVisible = true; + setVisible( true ); } /*! @@ -128,7 +134,36 @@ void QtxToolBar::Watcher::hidden( QtxToolBar* tb ) if ( tb != myCont ) return; - myVisible = false; + setVisible( false ); +} + +bool QtxToolBar::Watcher::isEmpty() const +{ + return myEmpty; +} + +bool QtxToolBar::Watcher::isVisible() const +{ + bool vis = false; + if ( myCont && myCont->toggleViewAction() ) + vis = myCont->toggleViewAction()->isChecked(); + return vis; +} + +void QtxToolBar::Watcher::setEmpty( const bool on ) +{ + myEmpty = on; +} + +void QtxToolBar::Watcher::setVisible( const bool on ) +{ + if ( !myCont || !myCont->toggleViewAction() ) + return; + + bool block = myCont->toggleViewAction()->signalsBlocked(); + myCont->toggleViewAction()->blockSignals( true ); + myCont->toggleViewAction()->setChecked( on ); + myCont->toggleViewAction()->blockSignals( block ); } /*! @@ -139,10 +174,14 @@ void QtxToolBar::Watcher::showContainer() if ( !myCont ) return; + bool vis = isVisible(); + QtxToolBar* cont = myCont; myCont = 0; cont->show(); myCont = cont; + + setVisible( vis ); } /*! @@ -153,10 +192,14 @@ void QtxToolBar::Watcher::hideContainer() if ( !myCont ) return; + bool vis = isVisible(); + QtxToolBar* cont = myCont; myCont = 0; cont->hide(); myCont = cont; + + setVisible( vis ); } /*! @@ -205,9 +248,7 @@ void QtxToolBar::Watcher::updateVisibility() return; bool vis = false; - QList actList = myCont->actions(); - for ( QList::const_iterator it = actList.begin(); it != actList.end() && !vis; ++it ) { if ( (*it)->isSeparator() ) @@ -217,10 +258,12 @@ void QtxToolBar::Watcher::updateVisibility() } QMainWindow* mw = myCont->mainWindow(); - if ( mw && myEmpty == vis ) + bool empty = isEmpty(); + if ( mw && empty == vis ) { - myEmpty = !vis; - if ( !myEmpty ) + empty = !vis; + setEmpty( empty ); + if ( !empty ) myCont->toggleViewAction()->setVisible( myState ); else { @@ -229,7 +272,7 @@ void QtxToolBar::Watcher::updateVisibility() } } - vis = !myEmpty && myVisible; + vis = !empty && isVisible(); if ( vis != myCont->isVisibleTo( myCont->parentWidget() ) ) vis ? showContainer() : hideContainer(); } diff --git a/src/Qtx/QtxTreeView.cxx b/src/Qtx/QtxTreeView.cxx index 001ebd6d3..bd07c1206 100644 --- a/src/Qtx/QtxTreeView.cxx +++ b/src/Qtx/QtxTreeView.cxx @@ -331,6 +331,20 @@ void QtxTreeView::selectionChanged( const QItemSelection& selected, emit( selectionChanged() ); } +void QtxTreeView::drawRow( QPainter* painter, const QStyleOptionViewItem& option, + const QModelIndex& index ) const +{ + QTreeView::drawRow( painter, option, index ); + + QtxTreeView* aThis = (QtxTreeView*)this; + aThis->drawRow( index ); +} + +void QtxTreeView::drawRow( const QModelIndex& index ) +{ + emit drawedRow( index ); +} + /*! \brief Expand/collapse the specified item (recursively). \param index model index diff --git a/src/Qtx/QtxTreeView.h b/src/Qtx/QtxTreeView.h index b11a31c40..8106afcb8 100644 --- a/src/Qtx/QtxTreeView.h +++ b/src/Qtx/QtxTreeView.h @@ -59,10 +59,14 @@ protected slots: protected: void setOpened( const QModelIndex&, const int, bool ); + virtual void drawRow( QPainter*, const QStyleOptionViewItem&, + const QModelIndex& ) const; + void drawRow( const QModelIndex& ); signals: void sortingEnabled( bool ); void selectionChanged(); + void drawedRow( const QModelIndex& ); private: void emitSortingEnabled( bool ); diff --git a/src/Qtx/QtxWorkstack.cxx b/src/Qtx/QtxWorkstack.cxx index db2e4ef52..27e8cdd0a 100644 --- a/src/Qtx/QtxWorkstack.cxx +++ b/src/Qtx/QtxWorkstack.cxx @@ -713,6 +713,7 @@ void QtxWorkstackArea::customEvent( QEvent* e ) switch ( we->type() ) { case ActivateWidget: + myBar->updateActiveState(); emit activated( activeWidget() ); break; case FocusWidget: @@ -725,10 +726,12 @@ void QtxWorkstackArea::customEvent( QEvent* e ) if ( activeWidget()->focusWidget()->hasFocus() ) { QFocusEvent in( QEvent::FocusIn ); - QApplication::sendEvent( this, &in ); - } - else + QApplication::sendEvent( this, &in ); + } + else { activeWidget()->focusWidget()->setFocus(); + myBar->updateActiveState(); + } } } break; @@ -748,6 +751,8 @@ void QtxWorkstackArea::focusInEvent( QFocusEvent* e ) { QFrame::focusInEvent( e ); + myBar->updateActiveState(); + emit activated( activeWidget() ); } @@ -1423,6 +1428,15 @@ void QtxWorkstackTabBar::contextMenuEvent( QContextMenuEvent* e ) emit contextMenuRequested( e->globalPos() ); } +/*! + \brief Process widget change state events (style, palette, enable state changing, etc). + \param e change event (not used) +*/ +void QtxWorkstackTabBar::changeEvent( QEvent* /*e*/ ) +{ + updateActiveState(); +} + /* void QtxWorkstackTabBar::paintLabel( QPainter* p, const QRect& br, QTab* t, bool has_focus ) const { diff --git a/src/Qtx/QtxWorkstack.h b/src/Qtx/QtxWorkstack.h index 367713bf9..22425c869 100644 --- a/src/Qtx/QtxWorkstack.h +++ b/src/Qtx/QtxWorkstack.h @@ -326,6 +326,7 @@ protected: virtual void mousePressEvent( QMouseEvent* ); virtual void mouseReleaseEvent( QMouseEvent* ); virtual void contextMenuEvent( QContextMenuEvent* ); + virtual void changeEvent( QEvent* ); // virtual void paintLabel( QPainter*, const QRect&, QTab*, bool ) const; diff --git a/src/STD/STD.h b/src/STD/STD.h index 404cf9adf..e974b5255 100755 --- a/src/STD/STD.h +++ b/src/STD/STD.h @@ -19,18 +19,14 @@ #ifndef STD_H #define STD_H -#if defined STD_EXPORTS #if defined WIN32 -#define STD_EXPORT __declspec( dllexport ) +# if defined STD_EXPORTS +# define STD_EXPORT __declspec( dllexport ) +# else +# define STD_EXPORT __declspec( dllimport ) +# endif #else -#define STD_EXPORT -#endif -#else -#if defined WIN32 -#define STD_EXPORT __declspec( dllimport ) -#else -#define STD_EXPORT -#endif +# define STD_EXPORT #endif #if defined SOLARIS diff --git a/src/STD/STD_Application.cxx b/src/STD/STD_Application.cxx index 35b80fc39..211966bcd 100755 --- a/src/STD/STD_Application.cxx +++ b/src/STD/STD_Application.cxx @@ -199,11 +199,11 @@ void STD_Application::createActions() Qt::SHIFT+Qt::Key_A, desk, false, this, SLOT( onHelpAbout() ) ); - QtxDockAction* dwa = new QtxDockAction( tr( "TOT_DOCKWINDOWS" ), tr( "MEN_DOCKWINDOWS" ), desk ); + QtxDockAction* dwa = new QtxDockAction( tr( "TOT_DOCKWINDOWS" ), tr( "MEN_DESK_VIEW_DOCKWINDOWS" ), desk ); dwa->setDockType( QtxDockAction::DockWidget ); registerAction( ViewWindowsId, dwa ); - QtxDockAction* tba = new QtxDockAction( tr( "TOT_TOOLBARS" ), tr( "MEN_TOOLBARS" ), desk ); + QtxDockAction* tba = new QtxDockAction( tr( "TOT_TOOLBARS" ), tr( "MEN_DESK_VIEW_TOOLBARS" ), desk ); tba->setDockType( QtxDockAction::ToolBar ); registerAction( ViewToolBarsId, tba ); @@ -302,7 +302,7 @@ bool STD_Application::onNewDoc( const QString& name ) void STD_Application::onOpenDoc() { // It is preferrable to use OS-specific file dialog box here !!! - QString aName = getFileName( true, QString::null, getFileFilter(), QString::null, 0 ); + QString aName = getFileName( true, QString(), getFileFilter(), QString(), 0 ); if ( aName.isNull() ) return; @@ -314,76 +314,13 @@ bool STD_Application::onOpenDoc( const QString& aName ) { QApplication::setOverrideCursor( Qt::WaitCursor ); - bool res = true; - if ( !activeStudy() ) - { - // if no study - open in current desktop - res = useFile( aName ); - } - else - { - // if study exists - open in new desktop. Check: is the same file is opened? - SUIT_Session* aSession = SUIT_Session::session(); - QList aAppList = aSession->applications(); - bool isAlreadyOpen = false; - SUIT_Application* aApp = 0; - for ( QList::iterator it = aAppList.begin(); it != aAppList.end() && !isAlreadyOpen; ++it ) - { - aApp = *it; - if ( aApp->activeStudy()->studyName() == aName ) - isAlreadyOpen = true; - } - if ( !isAlreadyOpen ) - { - aApp = startApplication( 0, 0 ); - if ( aApp ) - res = aApp->useFile( aName ); - if ( !res ) - aApp->closeApplication(); - } - else - aApp->desktop()->activateWindow(); - } - + bool res = openAction( openChoice( aName ), aName ); + QApplication::restoreOverrideCursor(); return res; } -/*! \retval true, if document was loaded successful, else false.*/ -bool STD_Application::onLoadDoc( const QString& aName ) -{ - bool res = true; - if ( !activeStudy() ) - { - // if no study - load in current desktop - res = useStudy( aName ); - } - else - { - // if study exists - load in new desktop. Check: is the same file is loaded? - SUIT_Session* aSession = SUIT_Session::session(); - QList aAppList = aSession->applications(); - bool isAlreadyOpen = false; - SUIT_Application* aApp = 0; - for ( QList::iterator it = aAppList.begin(); it != aAppList.end() && !isAlreadyOpen; ++it ) - { - aApp = *it; - if ( aApp->activeStudy()->studyName() == aName ) - isAlreadyOpen = true; - } - if ( !isAlreadyOpen ) - { - aApp = startApplication( 0, 0 ); - if ( aApp ) - res = aApp->useStudy( aName ); - } - else - aApp->desktop()->activateWindow(); - } - return res; -} - /*!Virtual function. Not implemented here.*/ void STD_Application::beforeCloseDoc( SUIT_Study* ) { @@ -489,6 +426,58 @@ bool STD_Application::closeAction( const int choice, bool& closePermanently ) return res; } +int STD_Application::openChoice( const QString& aName ) +{ + SUIT_Session* aSession = SUIT_Session::session(); + + bool isAlreadyOpen = false; + QList aAppList = aSession->applications(); + for ( QList::iterator it = aAppList.begin(); it != aAppList.end() && !isAlreadyOpen; ++it ) + isAlreadyOpen = (*it)->activeStudy() && (*it)->activeStudy()->studyName() == aName; + return isAlreadyOpen ? OpenExist : OpenNew; +} + +bool STD_Application::openAction( const int choice, const QString& aName ) +{ + bool res = true; + switch ( choice ) + { + case OpenExist: + { + SUIT_Application* aApp = 0; + SUIT_Session* aSession = SUIT_Session::session(); + QList aAppList = aSession->applications(); + for ( QList::iterator it = aAppList.begin(); it != aAppList.end() && !aApp; ++it ) + { + if ( (*it)->activeStudy() && (*it)->activeStudy()->studyName() == aName ) + aApp = *it; + } + if ( aApp ) + aApp->desktop()->activateWindow(); + else + res = false; + } + break; + case OpenNew: + if ( !activeStudy() ) + res = useFile( aName ); + else + { + SUIT_Application* aApp = startApplication( 0, 0 ); + if ( aApp ) + res = aApp->useFile( aName ); + if ( !res ) + aApp->closeApplication(); + } + break; + case OpenCancel: + default: + res = false; + } + + return res; +} + /*!Save document if all ok, else error message.*/ void STD_Application::onSaveDoc() { @@ -533,7 +522,7 @@ bool STD_Application::onSaveAsDoc() bool isOk = false; while ( !isOk ) { - QString aName = getFileName( false, study->studyName(), getFileFilter(), QString::null, 0 ); + QString aName = getFileName( false, study->studyName(), getFileFilter(), QString(), 0 ); if ( aName.isNull() ) return false; @@ -623,6 +612,8 @@ void STD_Application::updateDesktopTitle() /*!Update commands status.*/ void STD_Application::updateCommandsStatus() { + SUIT_Application::updateCommandsStatus(); + bool aHasStudy = activeStudy() != 0; bool aIsNeedToSave = false; if ( aHasStudy ) @@ -849,7 +840,7 @@ QString STD_Application::getFileName( bool open, const QString& initial, const Q SUIT_MessageBox::Yes | SUIT_MessageBox::No | SUIT_MessageBox::Cancel, SUIT_MessageBox::Yes ); if ( aAnswer == SUIT_MessageBox::Cancel ) { // cancelled - aName = QString::null; + aName = QString(); isOk = true; } else if ( aAnswer == SUIT_MessageBox::No ) // not save to this file diff --git a/src/STD/STD_Application.h b/src/STD/STD_Application.h index 3ff6d57bc..77f2ed646 100755 --- a/src/STD/STD_Application.h +++ b/src/STD/STD_Application.h @@ -1,17 +1,17 @@ // 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 +// 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 +// +// This library is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com @@ -50,12 +50,10 @@ class STD_EXPORT STD_Application : public SUIT_Application public: enum { FileNewId, FileOpenId, FileCloseId, FileSaveId, FileSaveAsId, FileExitId, - ViewWindowsId, ViewToolBarsId, ViewStatusBarId, NewWindowId, + ViewWindowsId, ViewToolBarsId, ViewStatusBarId, NewWindowId, EditCutId, EditCopyId, EditPasteId, HelpAboutId, UserID }; - enum { CloseSave, CloseDiscard, CloseCancel }; - -public: + public: STD_Application(); virtual ~STD_Application(); @@ -82,8 +80,8 @@ public: void viewManagers( ViewManagerList& ) const; void viewManagers( const QString&, ViewManagerList& ) const; - virtual QString getFileFilter() const { return QString::null; } - virtual QString getFileName( bool open, const QString& initial, const QString& filters, + virtual QString getFileFilter() const { return QString(); } + virtual QString getFileName( bool open, const QString& initial, const QString& filters, const QString& caption, QWidget* parent ); QString getDirectory( const QString& initial, const QString& caption, QWidget* parent ); @@ -115,8 +113,6 @@ public slots: virtual void onOpenDoc(); virtual bool onOpenDoc( const QString& ); - virtual bool onLoadDoc( const QString& ); - virtual void onExit(); virtual void onCopy(); @@ -139,6 +135,9 @@ protected: MenuHelpId = 7 }; + enum { OpenCancel, OpenNew, OpenExist }; + enum { CloseCancel, CloseSave, CloseDiscard }; + protected: virtual void createActions(); virtual void updateDesktopTitle(); @@ -158,8 +157,11 @@ protected: virtual void setActiveViewManager( SUIT_ViewManager* ); - virtual bool closeAction( const int, bool& ); + virtual int openChoice( const QString& ); + virtual bool openAction( const int, const QString& ); + virtual int closeChoice( const QString& ); + virtual bool closeAction( const int, bool& ); private: ViewManagerList myViewMgrs; diff --git a/src/STD/STD_MDIDesktop.cxx b/src/STD/STD_MDIDesktop.cxx index db06097f2..7fc268671 100755 --- a/src/STD/STD_MDIDesktop.cxx +++ b/src/STD/STD_MDIDesktop.cxx @@ -22,23 +22,22 @@ #include #include -#include +#include #include -//#include +#include -#include -#include -#include -#include -#include +#include +#include #include -/*!Constructor.*/ +/*! + Constructor. +*/ STD_MDIDesktop::STD_MDIDesktop() : SUIT_Desktop(), -myWorkspace( 0 )//, -//myWorkspaceAction( 0 ) +myWorkspace( 0 ), +myWorkspaceAction( 0 ) { QFrame* base = new QFrame( this ); QVBoxLayout* main = new QVBoxLayout( base ); @@ -47,7 +46,7 @@ myWorkspace( 0 )//, setCentralWidget( base ); - myWorkspace = new QWorkspace( base ); + myWorkspace = new QtxWorkspace( base ); main->addWidget( myWorkspace ); connect( myWorkspace, SIGNAL( windowActivated( QWidget* ) ), @@ -56,12 +55,16 @@ myWorkspace( 0 )//, createActions(); } -/*!destructor.*/ +/*! + Destructor. +*/ STD_MDIDesktop::~STD_MDIDesktop() { } -/*!\retval SUIT_ViewWindow - return const active window.*/ +/*! + \retval SUIT_ViewWindow - return const active window. +*/ SUIT_ViewWindow* STD_MDIDesktop::activeWindow() const { SUIT_ViewWindow* wnd = 0; @@ -73,7 +76,9 @@ SUIT_ViewWindow* STD_MDIDesktop::activeWindow() const return wnd; } -/*!\retval QPtrList - return const active window list.*/ +/*! + \retval QList - return const active window list. +*/ QList STD_MDIDesktop::windows() const { QList winList; @@ -89,7 +94,9 @@ QList STD_MDIDesktop::windows() const return winList; } -/*! add the new widget into desktop.*/ +/*! + Add the new widget into desktop. +*/ void STD_MDIDesktop::addWindow( QWidget* w ) { if ( !w || !workspace() ) @@ -101,25 +108,25 @@ void STD_MDIDesktop::addWindow( QWidget* w ) /*!Call method perform for operation \a type.*/ void STD_MDIDesktop::windowOperation( const int type ) { - //myWorkspaceAction->perform( operationFlag( 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 ); - - QList typeList; + va_start( ints, first ); - int cur = first; - while ( cur ) - { - typeList.append( cur ); - cur = va_arg( ints, int ); + QList typeList; + + int cur = first; + while ( cur ) + { + typeList.append( cur ); + cur = va_arg( ints, int ); } - setWindowOperations( typeList ); + setWindowOperations( typeList ); } /*!Sets window operations by variable \a opList - operation list.*/ @@ -130,26 +137,31 @@ void STD_MDIDesktop::setWindowOperations( const QList& opList ) for ( QList::const_iterator it = opList.begin(); it != opList.end(); ++it ) flags = flags | operationFlag( *it ); -// myWorkspaceAction->setItems( flags ); + myWorkspaceAction->setMenuActions( flags ); } -/*!\retval QWorkspace pointer - work space.*/ -QWorkspace* STD_MDIDesktop::workspace() const +/*! + \retval QtxWorkspace pointer - work space. +*/ +QtxWorkspace* STD_MDIDesktop::workspace() const { return myWorkspace; } -/*!Emit window activated.*/ +/*! + 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*/ +/*! + Create actions: cascade, Tile, Tile Horizontal, Tile Vertical +*/ void STD_MDIDesktop::createActions() { -/* if ( myWorkspaceAction ) return; @@ -159,50 +171,47 @@ void STD_MDIDesktop::createActions() myWorkspaceAction = new QtxWorkspaceAction( workspace(), this ); - myWorkspaceAction->setItems( QtxWorkspaceAction::Cascade | QtxWorkspaceAction::Tile | - QtxWorkspaceAction::HTile | QtxWorkspaceAction::VTile | - QtxWorkspaceAction::Windows ); + myWorkspaceAction->setMenuActions( 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->setIcon( QtxWorkspaceAction::Cascade, + resMgr->loadPixmap( "STD", tr( "ICON_DESK_WINDOW_CASCADE" ) ) ); + myWorkspaceAction->setText( 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->setIcon( QtxWorkspaceAction::Tile, + resMgr->loadPixmap( "STD", tr( "ICON_DESK_WINDOW_TILE" ) ) ); + myWorkspaceAction->setText( 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->setIcon( QtxWorkspaceAction::HTile, + resMgr->loadPixmap( "STD", tr( "ICON_DESK_WINDOW_HTILE" ) ) ); + myWorkspaceAction->setText( 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->setIcon( QtxWorkspaceAction::VTile, + resMgr->loadPixmap( "STD", tr( "ICON_DESK_WINDOW_VTILE" ) ) ); + myWorkspaceAction->setText( 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, MenuWindowId ); + 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: @@ -218,6 +227,5 @@ int STD_MDIDesktop::operationFlag( const int type ) const res = QtxWorkspaceAction::VTile; break; } -*/ return res; } diff --git a/src/STD/STD_MDIDesktop.h b/src/STD/STD_MDIDesktop.h index 3d338854a..a3506a468 100755 --- a/src/STD/STD_MDIDesktop.h +++ b/src/STD/STD_MDIDesktop.h @@ -23,10 +23,8 @@ #include -class QtxAction; -class QPopupMenu; -class QWorkspace; -//class QtxWorkspaceAction; +class QtxWorkspace; +class QtxWorkspaceAction; #if defined WIN32 #pragma warning( disable: 4251 ) @@ -36,10 +34,7 @@ class STD_EXPORT STD_MDIDesktop: public SUIT_Desktop { Q_OBJECT - class Workspace; - public: - enum { MenuWindowId = 6 }; enum { Cascade, Tile, HTile, VTile }; public: @@ -54,7 +49,7 @@ public: void setWindowOperations( const int, ... ); void setWindowOperations( const QList& ); - QWorkspace* workspace() const; + QtxWorkspace* workspace() const; private slots: void onWindowActivated( QWidget* ); @@ -67,8 +62,8 @@ private: int operationFlag( const int ) const; private: - QWorkspace* myWorkspace; -// QtxWorkspaceAction* myWorkspaceAction; + QtxWorkspace* myWorkspace; + QtxWorkspaceAction* myWorkspaceAction; }; #if defined WIN32 diff --git a/src/STD/STD_SDIDesktop.cxx b/src/STD/STD_SDIDesktop.cxx index d04923414..1c9a08fd6 100755 --- a/src/STD/STD_SDIDesktop.cxx +++ b/src/STD/STD_SDIDesktop.cxx @@ -20,11 +20,8 @@ #include -#include -#include -#include - -#include +#include +#include /*!Constructor. Create instance of QVBox*/ STD_SDIDesktop::STD_SDIDesktop() diff --git a/src/STD/STD_TabDesktop.cxx b/src/STD/STD_TabDesktop.cxx index 8b6c41b08..cf98dad7a 100644 --- a/src/STD/STD_TabDesktop.cxx +++ b/src/STD/STD_TabDesktop.cxx @@ -22,21 +22,20 @@ #include #include -#include #include #include -//#include +#include -#include -#include +#include +#include #include /*!Constructor.Create new instances of QVBox and QtxWorkstack.*/ STD_TabDesktop::STD_TabDesktop() : SUIT_Desktop(), -myWorkstack( 0 )//, -//myWorkstackAction( 0 ) +myWorkstack( 0 ), +myWorkstackAction( 0 ) { QFrame* base = new QFrame( this ); base->setFrameStyle( QFrame::Panel | QFrame::Sunken ); @@ -57,18 +56,32 @@ myWorkstack( 0 )//, myWorkstack->setAccel( QtxWorkstack::SplitHorizontal, Qt::SHIFT + Qt::Key_H ); myWorkstack->setAccel( QtxWorkstack::Close, Qt::SHIFT + Qt::Key_C ); + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + if ( resMgr ) { + myWorkstack->setIcon( QtxWorkstack::SplitVertical, + resMgr->loadPixmap( "STD", tr( "ICON_DESK_WINDOW_HSPLIT" ) ) ); + myWorkstack->setIcon( QtxWorkstack::SplitHorizontal, + resMgr->loadPixmap( "STD", tr( "ICON_DESK_WINDOW_VSPLIT" ) ) ); + myWorkstack->setIcon( QtxWorkstack::Close, + resMgr->loadPixmap( "STD", tr( "ICON_FILE_CLOSE" ) )); + } + connect( myWorkstack, SIGNAL( windowActivated( QWidget* ) ), this, SLOT( onWindowActivated( QWidget* ) ) ); createActions(); } -/*!Destructor.*/ +/*! + Destructor. +*/ STD_TabDesktop::~STD_TabDesktop() { } -/*!\retval SUIT_ViewWindow - return const active window.*/ +/*! + \retval SUIT_ViewWindow - return const active window. +*/ SUIT_ViewWindow* STD_TabDesktop::activeWindow() const { SUIT_ViewWindow* wnd = 0; @@ -80,7 +93,9 @@ SUIT_ViewWindow* STD_TabDesktop::activeWindow() const return wnd; } -/*!\retval QPtrList - return const active window list.*/ +/*! + \retval QPtrList - return const active window list. +*/ QList STD_TabDesktop::windows() const { QList winList; @@ -95,7 +110,9 @@ QList STD_TabDesktop::windows() const return winList; } -/*! insert new widget into desktop.*/ +/*! + Insert new widget into desktop. +*/ void STD_TabDesktop::addWindow( QWidget* w ) { if ( !w || !workstack() ) @@ -104,13 +121,17 @@ void STD_TabDesktop::addWindow( QWidget* w ) workstack()->addWindow( w ); } -/*!Call method perform for operation \a type.*/ +/*! + Call method perform for operation \a type. +*/ void STD_TabDesktop::windowOperation( const int type ) { -// myWorkstackAction->perform( operationFlag( type ) ); + myWorkstackAction->perform( operationFlag( type ) ); } -/*!Sets window operations by \a first ... parameters.*/ +/*! + Sets window operations by \a first ... parameters. +*/ void STD_TabDesktop::setWindowOperations( const int first, ... ) { va_list ints; @@ -128,7 +149,9 @@ void STD_TabDesktop::setWindowOperations( const int first, ... ) setWindowOperations( typeList ); } -/*!Sets window operations by variable \a opList - operation list.*/ +/*! + Sets window operations by variable \a opList - operation list. +*/ void STD_TabDesktop::setWindowOperations( const QList& opList ) { int flags = 0; @@ -139,23 +162,28 @@ void STD_TabDesktop::setWindowOperations( const QList& opList ) // myWorkstackAction->setItems( flags ); } -/*!\retval QtxWorkstack pointer - QT work stack.*/ +/*! + \retval QtxWorkstack pointer - Qt work stack. +*/ QtxWorkstack* STD_TabDesktop::workstack() const { return myWorkstack; } -/*!Emit window activated.*/ +/*! + Emit window activated. +*/ void STD_TabDesktop::onWindowActivated( QWidget* w ) { if ( w && w->inherits( "SUIT_ViewWindow" ) ) emit windowActivated( (SUIT_ViewWindow*)w ); } -/*!Create actions for window.*/ +/*! + Create actions for window. +*/ void STD_TabDesktop::createActions() { -/* if ( myWorkstackAction ) return; @@ -165,44 +193,46 @@ void STD_TabDesktop::createActions() myWorkstackAction = new QtxWorkstackAction( workstack(), this ); - myWorkstackAction->setItems( QtxWorkstackAction::Split | QtxWorkstackAction::Windows ); + myWorkstackAction->setMenuActions( QtxWorkstackAction::Split | QtxWorkstackAction::Windows ); // Split Horizontal - myWorkstackAction->setIconSet( QtxWorkstackAction::HSplit, - resMgr->loadPixmap( "STD", tr( "ICON_DESK_WINDOW_HSPLIT" ) ) ); - myWorkstackAction->setMenuText( QtxWorkstackAction::HSplit, tr( "MEN_DESK_WINDOW_HSPLIT" ) ); - myWorkstackAction->setStatusTip( QtxWorkstackAction::HSplit, tr( "PRP_DESK_WINDOW_HSPLIT" ) ); + myWorkstackAction->setIcon( QtxWorkstackAction::SplitHorizontal, + resMgr->loadPixmap( "STD", tr( "ICON_DESK_WINDOW_HSPLIT" ) ) ); + myWorkstackAction->setText( QtxWorkstackAction::SplitHorizontal, tr( "MEN_DESK_WINDOW_HSPLIT" ) ); + myWorkstackAction->setStatusTip( QtxWorkstackAction::SplitHorizontal, tr( "PRP_DESK_WINDOW_HSPLIT" ) ); + myWorkstackAction->setAccel( QtxWorkstackAction::SplitHorizontal, Qt::SHIFT + Qt::Key_H ); // Split Vertical - myWorkstackAction->setIconSet( QtxWorkstackAction::VSplit, - resMgr->loadPixmap( "STD", tr( "ICON_DESK_WINDOW_VSPLIT" ) ) ); - myWorkstackAction->setMenuText( QtxWorkstackAction::VSplit, tr( "MEN_DESK_WINDOW_VSPLIT" ) ); - myWorkstackAction->setStatusTip( QtxWorkstackAction::VSplit, tr( "PRP_DESK_WINDOW_VSPLIT" ) ); + myWorkstackAction->setIcon( QtxWorkstackAction::SplitVertical, + resMgr->loadPixmap( "STD", tr( "ICON_DESK_WINDOW_VSPLIT" ) ) ); + myWorkstackAction->setText( QtxWorkstackAction::SplitVertical, tr( "MEN_DESK_WINDOW_VSPLIT" ) ); + myWorkstackAction->setStatusTip( QtxWorkstackAction::SplitVertical, tr( "PRP_DESK_WINDOW_VSPLIT" ) ); + myWorkstackAction->setAccel( QtxWorkstackAction::SplitVertical, Qt::SHIFT + Qt::Key_V ); QtxActionMenuMgr* mMgr = menuMgr(); if ( !mMgr ) return; - int winMenuId = mMgr->insert( tr( "MEN_DESK_WINDOW" ), -1, 100, MenuWindowId ); + int winMenuId = mMgr->insert( tr( "MEN_DESK_WINDOW" ), -1, 100 ); mMgr->insert( myWorkstackAction, winMenuId, -1 ); mMgr->insert( QtxActionMenuMgr::separator(), winMenuId, -1 ); -*/ } -/*!Convert STD_TabDesktop enumerations to QtxWorkstackAction*/ +/*! + Convert STD_TabDesktop enumerations to QtxWorkstackAction +*/ int STD_TabDesktop::operationFlag( const int type ) const { int res = 0; -/* switch ( type ) { - case VSplit: - res = QtxWorkstackAction::VSplit; + case SplitVertical: + res = QtxWorkstackAction::SplitVertical; break; - case HSplit: - res = QtxWorkstackAction::HSplit; + case SplitHorizontal: + res = QtxWorkstackAction::SplitHorizontal; break; } -*/ + return res; } diff --git a/src/STD/STD_TabDesktop.h b/src/STD/STD_TabDesktop.h index 1d5c2ecb8..35d09cd29 100644 --- a/src/STD/STD_TabDesktop.h +++ b/src/STD/STD_TabDesktop.h @@ -23,11 +23,8 @@ #include -class QtxAction; -class QPopupMenu; -class QWorkspace; class QtxWorkstack; -//class QtxWorkstackAction; +class QtxWorkstackAction; #if defined WIN32 #pragma warning( disable: 4251 ) @@ -38,8 +35,7 @@ class STD_EXPORT STD_TabDesktop: public SUIT_Desktop Q_OBJECT public: - enum { MenuWindowId = 6 }; - enum { VSplit, HSplit }; + enum { SplitVertical, SplitHorizontal }; public: STD_TabDesktop(); @@ -67,7 +63,7 @@ private: private: QtxWorkstack* myWorkstack; -// QtxWorkstackAction* myWorkstackAction; + QtxWorkstackAction* myWorkstackAction; }; #if defined WIN32 diff --git a/src/STD/resources/STD_msg_en.po b/src/STD/resources/STD_msg_en.po index c70c031cc..4dceccd1f 100755 --- a/src/STD/resources/STD_msg_en.po +++ b/src/STD/resources/STD_msg_en.po @@ -23,7 +23,7 @@ msgid "" msgstr "" "Project-Id-Version: example-Qt-message-extraction\n" "POT-Creation-Date: 1999-02-23 15:38+0200\n" -"PO-Revision-Date: 2007-11-07 18:43+0300\n" +"PO-Revision-Date: 1999-02-23 15:38+0200\n" "Last-Translator: \n" "Content-Type: text/plain; charset=iso-8859-1\n" @@ -140,6 +140,9 @@ msgstr "&View" msgid "MEN_DESK_VIEW_TOOLBARS" msgstr "T&oolbars" +msgid "MEN_DESK_VIEW_DOCKWINDOWS" +msgstr "W&indows" + msgid "MEN_DESK_VIEW_STATUSBAR" msgstr "&Status Bar" @@ -192,7 +195,7 @@ msgid "PRP_DESK_VIEW_STDTOOLBAR" msgstr "Toggles standard toolbar on/off" msgid "QUE_DESK_EXIT" -msgstr "Are you sure you want to quit SALOME?" +msgstr "Do you really want to quit ?" msgid "TOT_DESK_FILE_NEW" msgstr "New document" @@ -344,15 +347,6 @@ msgstr "Saving study " msgid "STD_Application::INF_DOC_SAVING_FAILS" msgstr "Can't save file \"%1\".\nPossible reason is permission denied or disc full.\nTry to use another file name." -msgid "CLOSE_DLG_SAVE_CLOSE" -msgstr "&Save && Close" - -msgid "CLOSE_DLG_CLOSE" -msgstr "C&lose w/o saving" - -msgid "CLOSE_DLG_UNLOAD" -msgstr "&Unload" - msgid "TOT_DESK_FILE_LOAD" msgstr "Load document" @@ -362,12 +356,6 @@ msgstr "Load a document" msgid "MEN_DESK_FILE_LOAD" msgstr "Conn&ect..." -msgid "CLOSE_DLG_CAPTION" -msgstr "Close active study" - -msgid "CLOSE_DLG_DESCRIPTION" -msgstr "Study is modified. Do you want to save it?" - msgid "DLG_LOAD_STUDY_CAPTION" msgstr "Load Study" diff --git a/src/STD/resources/cascade.png b/src/STD/resources/cascade.png new file mode 100644 index 0000000000000000000000000000000000000000..3111e55c26aeeb9e865f77fed2c222009ccc6375 GIT binary patch literal 430 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE-VXMsm#F#`j)FbFd;%$g$s6l6(v z^mSxl*w|O|J8&|PuaN8!{|6#PfXZR%A%6OapZa94^|&u2Zl!8JE4pHHatRckt`NDQpps9-53)~`@SOmB?HD2NHZeVaSoFJ9RDd3=EAu>UB8c=b|Sply@ zLO^R8mT56b_8CNL@B)=FRsLizI<&+@hmncn$y5Fd5=tEN>P!_^uqiamm=NpX*Rp`Q zfg#CB%TlD#f^&WnV>MgbdNs9#9&QE}fucz@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ=Vo5|nRCwBA{Qv(y10y3N0}`kQVhJE#55y;d_$Ltm z0^)xRL;!#QVgMP41cc@J1+L8Z3I1;(EeA5F28gwRSP+Prv1kWb90K+FcjEC2z- zge(hmsiK~!grc2{JVURO2b;Q(NEuK#0Ekt9m!$FDolUrG*_Y4;xz&P)Z$$Wq_C+sIdJE-f$0Rjl!K!$(+|M$$jcoq}@3}1i$W{A_)XAt4!@`QS+HCR=% zB2CAT;m4of4DY}HVAy!?Hp8oLU+)6tJ_GR&fB<5`63|BvJ$|tIih@S%l5F?gk0|I7N(sH}n zY@PXk{rSW2``=%NtFK=(XbFojy#Mi?;o|F;K>UJX-;;+o|Ni^87O4Ie5Z?siD*yq+ zgd;VbI`;I@rXx>)t^`{4|KEQGJy9`+r=LGD?0s~P;n0(ZAj7T!4O^2bJ0I>lA zhy{m%s=%b6#m&OX@CO(N2=tAk6>)gl?dT zI5*GEW*a9}V4`LC4h%n#%RtHFH;|U%=4LP!mEZ=dQwHKMK>P%h)L@2z06+jC8)ziQ zC$O!}+DT4bP?+Jz??1p~@r_~k!}|;y?%ZHt0fyywU@~%-Rb&9hxD8M}ClGT$vm`uL z0RjkSpfC?B>x?=JJ5eP8L56R?ela}y^pRoHy;}_PuAYCr?f#v&PrrO-0OfiS4o(I; zX*p1?F$H2-C+jxR z02*)|=%Ve=z(2Y3(fwy1fBpc6sRS^wn~O?_1I3L&zC$iJ00M{!QYbJy=sSCyq5s@* zV3^(g56qiafLZVuG~nL?@%4|ter(>&dyFf4xnBg+C9<4lZ9IzTy5Xz>N|@;`t8 zf*8o~fAPz2Uk^U}^7+N<@89+Sg+Q744-mhGCJRt5ShD}=|!@m;b=-0s?>lLe9%vKr95re9)xu9qQ#D&~)}2stHt-r9yMb6)1fHnq$5K1Q-Bj WYPb*HL2?`b0000MpMk-+o$V%& z#aI&L7tG-B>_!@hljQC0!qCAg>jC75mAFQf1m~xflqVLYGNfmw85QKED;Vh+=o#9^ z?aKhF@bYwV45^rtoRAQZz`&@=rl@d};fZB~%MKBV8!Qqm2Z9)7c$k=Yboh9Bcz9&^ zc(@NN(ot|a%eZ2eW+U$rp9Y~h!WNPeDv}GT7{z>>C BH68!} diff --git a/src/STD/resources/copy.png b/src/STD/resources/copy.png index 1e43a09c2f80427d80e154e552661e4cf9596317..a26b641984355b66dcf8a638b34e4e3dcd8205d0 100755 GIT binary patch literal 843 zcmV-R1GM~!P)z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ;!AV3xRCwBA{Qv(y10y42Dgy(98v}Om2#9w9)$L>; z0ssUM1IR!iSo0qX`2FYa|Hn_BeV3A!-T}3c38Wq$1_&USf$RVN{r~^ZA5{GE&FBCB z{{8!Z{^FHy{QUfTfa)9x843_Uj8HFc{Q3L8UvcwX6xR!}ykod>@f29$ySH!u9yxOO z&ELO&uK}gr0r5j@K>-jzFc)t6`t$$)cV7_r!`J`+-MxbTlNuBN0mK3``1fB1hPtk~ z7-9VH9|Hr#P6T-O;Twarlmy4tZ9DB8?5tTne*E|w=*xpZ1OEX85Zu5&Km$v2lNtVj ztb>ZB#cyNy0~E-}Dnc+PpPz?8OfisE81#*exYusnYUb_k3<{qs009Iy@aG=}hU6rm z3;#njfk4HXZQ!6NE<|-XEf#Jz0hIIj52nvdZ zsv^9ZqqQ3pB>$O#1V2Ckp}27UN=z4mf+DZF4<#s2Qo(VzD9Pr)W=t1?f+D7%53hkBH821WKyU-ag%}vZ<59z~1?s{j z6Y#q*zaC*BKmfrEJfI}N2sDy`57`nRkZ$?Qz~`OThY}PRF8qsN0|XFE^FkoL48$5h z%!Q;j1{f4NTW8^SVOk}^g#ZBrGw>%6KZUZ{k<@+x1w~Q?Y8ZmjBT}$|g9`=#0tjZ{ zcWBA{5-I(Hz&2n|fM^~dW+qTp-v$u?0mS(K|9_k+fSFwwNEu-X3T)sT5Z?d@FaV&5 VkFu@xL23X1002ovPDHLkV1nhtV&MP) literal 245 zcmVSHfgws1h@S1R)~Jg>q(I^nm!Ehk*h?(CiQ_`x^^=3-E)5 zLbA%d2#-ENIrtM(k(d=QkqFSj9m*Y5AB`$p^8^rMsgFI#G%JJ2WNc4{;DD&PfC_$1 zssbv*GlPT4%~)z_mngd^2hj~MDeS{szWFq}&Z4QW9aLgxm)u<+PTDR*aPx9$AME%Y vI-=-M9W*`mTejkBpTT~xoc|z*gX-b}*D!os%$qEI00000NkvXXu0mjfFDYd; diff --git a/src/STD/resources/cursor_rotate.png b/src/STD/resources/cursor_rotate.png deleted file mode 100755 index a3cb0c1ecc31ed66595b4387c55dd2731809a5e1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 291 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnH%)r1{DZJ<-ki!|^6XJT{zyToh|NsBJ3q{m` zEXI-`zhDN3XE)M7oFs2|7lsa2Sq~sbti&~FS$q5M)5)u*~FeEXuNpvI#I2A}-X}F}rqr=I=%gfWlk;uj_@bD7j z6|DtF4jh=G!12UL&ENr>PlD1KMh`VE4Ti0yjJ+8Jj78ER4MKcUJUm)LTnfPsZpKOG zEV4cgmtt0nIY{(yPjhvQn8U-#ZQ{ry%Esx*uHnq2v$d(wm(@i-H9286!$zGf)iWM5 e)|F^Z8<^g0e zmIV0)GdMiEkp|?5mAFQf1m~xflqVLYGNfmw85QKED;Vh+=o#9^?aKhFU`h9MOJ`zW zkPLd4!Up7Lc)B=-RLn_EP!KOz+h7#dX4;UsjI)PRK$4w})1Y}W<0Lc-a$k!M*zN28VxpF`U#yCAY@F9!>Q{yu)SmYHks0PSS(boFyt=akR{08E}qwEzGB diff --git a/src/STD/resources/cut.png b/src/STD/resources/cut.png index b35200830ca593d5f55a151525f9f9125caa44f3..055c27ea6a73f494b87fbe64868df09e01024597 100755 GIT binary patch literal 1206 zcmV;n1WEgeP)z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ=EJ;K`RCwBA{Qv(y12q9a05Rea7h@0<$zu=}(_wh= zew&^-4)gPrF+pr|z-2fzV905M?|6%x~C zU}XBoP!@fFVf%_Z3|>)+4C2zUKp9?~dY}LxfUrqQ0KF^5@$WYSXV9|*MNAmXKmkEPYwy6I4F`{(`1u!@ z_EsK0^Iu9!X8}L};R*&JAU0*-Df;SYg>)1~&FtK=~Me0Kyfv%s|W!N-D0wA(#LE`Tc*_g{!~xZS3#$&z|?~ z$&)AlU%h+xf5w^(zoqqzjsn%y191TmCjtZzBY_ALWM^lu*}m^UHYYO^>zRue8I&X? z7=E&`|68$T`|CBcXYBs>^T&0dy6-^z28bU31P}`j!$7fVCZehl8|?4z@#XzH*4>8= zGH`IPGuYbMF=Q5(zB#^a^G2W=P`Coq6vJa6z7NFD0Rjl!Km%Y52QrvD`!HBI88N7+ zGYAR%XSjOp+W$Y?e1EmfOj-E3xfrH(wTtHe`DK4-*Up^BUPH~eRqwEjP1Vf$m=DeL}n0ka>wiq<)xn(2%ztXsX~lHMIWb^8DP$B+MK z6cpV6Mv@COWq<)d0D%HOguyFf2}4G$DTA~;2gCkN8yV)b&u6}MSzOx5Oa9HrkMI8M zT)lH{02p|Rqw~*Vqs}BF?HnqC~bp9?TE#sSN)7SmiTXW<;lcwQX zprRrmjsRjUXi^e_vVDNKOI%s)Lf?WV|1-*}-h+}EKmai^$SBoF7q>JD%g8Z3`uLea zfQyTP|L;$ROH1c$`oDAaE{6aAKSKi^R33hT1{DW1$H)V*Dl-RX2oJvi^T(IZdjSH7 znc>s>o1dRPdiV0>3l7Hb-~N4k@$~7lgS*x;>{@dM7-m192Hk-s4_NX32Z+Bx#XkT4 z^XKl*uU{Sj*}nh+2$Zn-fLH@u%0SpmQ2Z5|&OizGHPjGniJu*aMS)lnqy`|s0MoW| UhR8)+HUIzs07*qoM6N<$f+i;|U;qFB literal 211 zcmV;^04)EBP)5rp7y4|B6o z^XVaW77F0XR@IjsWXMYaUHf=tDjGZ{Px2s*MfvR#^$JrRAmGcN?F5>>hte6<$NK;P N002ovPDHLkV1hc}Rq6l$ diff --git a/src/STD/resources/delete.png b/src/STD/resources/delete.png new file mode 100644 index 0000000000000000000000000000000000000000..93d166354301efead4c3a08cc686b748b33dfc83 GIT binary patch literal 1344 zcmV-G1;6@z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ=wn;=mRCwBA{Qv(y10y3N13GX?F4SaX`rrTe@BhF5 z|NUhGs$c^u{Q2U}t(t3xcRm0r`3l6pfcQVMK7asXL^jYlxqy|Mi#tz5NXY%|`}d0f z|NoQVU}L}c>(@^fpgQJXfBz`|`}5}!Q1!bnAK&l0bLRNW7x!+y25S8d#D73$00a=+ zK(EYlLoqRtCUp%hA3k1Qh6fKGF#P)ci$O?Gh~fK>9}Iu~{9<_h>NVJ67FJeKwty?^J+qkO^oL%C@AoP4FCD_C(wXDK>Qns|AN_n z|NVi`VDW!&{_`hKKc6|Ud*bz@`&IxAd;$x-$2ViV!wX=<`s~X_6Hhs4TzZl0tjs2yZ0ZD zp1*h@5UdGk&_AH@cem-!x{{>ngEhWwH_VK;D&`ACZ5I|rT{%83AnTws{D<3Z(2gp_Y`~u*xV_{`s z;Njr`yNHjE7isql01$+s%gF4z``z{mWkf4(S*N02qP- zs1l93|4rMW3+-nzkVnv9zSyO^uf7~J6Y!o$L;yN5qG4Z|iaeUwqG?J4wfF1-qki!V zz#_G!01U#gj5?K0u%|L zFa@b$X9I;HD=4A=1GyNQr~d;45EIP6=g*$~Wd(*4D6E));R1?bkO82G0l5sw0P^$XN> zpmg{LAb{WozJLGmBPd_~0p?Eu0e*0z1sMnm9+0?zfB*w1o&NpH#=r)29VnteVg2dt zn~%^m2+A#g0RjkOpqw7##q$?;DJsc_3JD2{{QdKn5tN^SX^;_=E1rM<4tD8}AK$^b zgaOR{!SLzRm;aZ}o_)cz@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ<#Ysd#RCwBA{Qv(y0|+oOGBRKTii(OVKuQ#de*y93 z`}gnv!ln*p4nP1gVlxnE2pf>91L911c}XE*VSa{RzkV~^y!nvf_wPT8f#TDF1|P>} zAV2_t8E_87upBit)&KSNx&Pn4KmPyUzvKV^{yPYy5B&f6^YH(5>w5lsc-Z|1s_R8J z5QG5&2*rg!Mae=!d~=pBZ(&eT5n}lJ?(e;CN0=g(iv1G?hFt(!tcfB$j-4g1RQ_RVjG_wT=f zE&luWFDOND!VClmAh?0Rz+L?P`}c=HtPfPA0JNFo=g*%{1O){p1qJzw5)$=+!N3M| z*>8ro@0fu!BT&yvpxE!HK<#WWa{vMe*@ZwCy*LY`KnnPQm|0R%(nCo}I(O2f6b4=0 zUkoo^-UWv1f1u0Q81CKu#BkxleTFx0-W)(S10aA{&=UMNAbtdkEDjEisZ*yGFzD$? zF#P#@2N;$-3_pIbFkHI$nqlqQ<3MkJ*zoV)zc)aoKVb#{1Q5D`|6ySPOp~I(G-;}@ zuM7;&PYi#4GctVt#>udI_g#i%%MRW9^5x5^PoF+*0xEqBP8LuA5I`&pxB({z2OGnc zD|dhfeqng~_BAj_zA~ITbrkl;wv10uAB~}GLXf9 zk#-gs*4;qn86bWF^DfLBfB?eC%SeXFSzDU`r4Ic6@@3oqd-s<9KYe=oe}8|+{}K`s znb4$yk(U7ih>3v!`1b8PFeX2ObItefkdlj;nfVJWtkD5L0O1S6U!WrETZ~LGT@(sN_1PCBT z0wp#mNMwOn4~WH}V()?YDiA+FPJb|S00M}RfgnK+Am)S84A83JGt_ne&+kQc*Xu(=L&L+vqobo^ zV`Gbpi_K=U(P&IeOvJ+?TCE*<>3`yAXY1f#=fnFKDw0G@!~s`Pm84=St`hl9lcXe; z#FIpRswTUB;P=g}8mWe=x3Gl!`T3%9MZWcK#%s|ZE-6Cg)H@La> zu*gx8JxLQSSrQu|kqR;3TUI_{4mXIV44J6Q{28=F1*Yr)&$;J-5xFHqhC^7{2l3@* z(mmQj6G)wy$(1Z=9%+#fkx+wsdWl6mmGz~}vbE$6KZGCxNh!~{WJfUo|0iZvZ)Id@ zX=!_IkaOlau&+ys`17D2nor6B2o1X2m#v zx4yx7?f%^Cd_Lg**OMLXCW~OE*KQ`Kr{{g4UsYCz( diff --git a/src/STD/resources/htile.png b/src/STD/resources/htile.png new file mode 100644 index 0000000000000000000000000000000000000000..42af00c0a777869f4598f9583960c130875e42cb GIT binary patch literal 343 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE-VXMsm#F#`j)FbFd;%$g$s6l6(v z^mSxl*w|O|J8&|PuaN8!WKtyUfA{e-W{t$3<3@b;_p^nT;A2_aNLlAML^h)Ykr-n;;n!NhNPqgMhqMZi+Dsf zq$m8yN@6DL1H+=K rLu|w{lUR~i70OtWT(cxN1QHm8^o%510;XC5J;vba>gTe~DWM4f^#y4^ literal 0 HcmV?d00001 diff --git a/src/STD/resources/new.png b/src/STD/resources/new.png index 953757a62f594c7591c7cdcfe8e51cdde41bfa45..68555d2211d1f80a63dab34e873a943b4f128bc5 100755 GIT binary patch literal 667 zcmV;M0%ZM(P)z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ;5lKWrRCwBA{Qv(y12q9a0I?u*7#SH;fs`8oJ&%BR z7ZC46mjF2qAb`LG3|&mZjg z<(tp{|NZ;-|NO-(-}w3Y_W;#9A{z=a10aCV4cz$i_y7OjeqhHJu0Q?%11SIX$KU^l zj-33$$;r7JsK)|kD98+e0AfN52F5@C7#M#1!NkA*GBAAk_M71k(B5DFm>Bepjkwot z+-e34_aLA?E|6Z30RRESf*!EHff|4P!4ZRO91N4^?__xO`U8WyiVTCbu{Iyj9BZK4 zM1j)3Ko}r^FbwgvSCI) zKmcL&^51{thao@!p&Mu{3{0Y$a*S9FfaM$*0I3B6Ib<~e0fcT~pOOGLvjg)e12d6@ z^bO>M4G=)+1}*{On?S4r#Oy>G_!AVDFb+U~0RTb2Cp*ew4LAS*002ovPDHLkV1jKT B2W$WU literal 177 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9oB=)|t_Kbr05bpo|KGb%L=DJd zED7=pW^j0RBMrzAD{+k|3C>R|DNig)Wk}CVGb+eSS1{5u&@;4++m``U!IJLjmJXyP ze>`8)3#3&%T^vIy<|HRDFdn-gps+DZvm@deLlP@PXQ*(8l9MyD!~+I~_)t;*^HWte Q0M#>iy85}Sb4q9e0N}kbVE_OC diff --git a/src/STD/resources/open.png b/src/STD/resources/open.png index d9953b6a7d36d4983f2cd609ef10976ac221215f..8ed143ebddf46107de32a68f5b95d4c0c90f26d6 100755 GIT binary patch literal 1194 zcmW+$drVVz6#lihTwb@M$g~B9TO+qU%DDf)s9hf4l6DbH1FD^GLq$*_4zP@J|_B(2{~-_6njwrrtoxYf99^B_&NCSt6is zPKit9ZZgm8R_b{RsV7|h+c*6V&-TQWwMTynPI?GHA? zAHxLKH#LFV#*UywBuPS4*=6bztq%>E30RBA>5X!A-5c#2BX>4IXZMwkF!Bts?6Jpiv&{KBhO3?BTk=+d}NXfF!N?2p zke-IcEMFjcN-Qfc*YBfYYA1Q3MY(t9dFqNQF(+-^OO3_{8M&>+VzS=TEzQrv1H+C= z{fgD&>w`k@CW`RXvJ-l$ao=f|gJCep4sW_^D6+LKkjtZNcV;Zn$-BF1Ic?3!Wu-np z8-xtfCXA+%A0EONiRr(-4A$zRTGKU`Ou+jJMGw9nJdvXu%IDS@PObb1dAh1^ifFz#WV(N-p}Pw9Gf{PJFOQy`GF_ z*+9_d1e((Okx57i`M*Op!0WA-m7q6tOpBAws`U=X{on0n_M?vqQ=&U0aHXIBXo#js zZT?8CjaCpg;;L3pBxoa-1BvS|+HSC_W@iv%It@7Dd!eMRrY*`1hLyI29IR<<$==TG+D$>SHB zO|!y*v*i6S70;aRYZ-OYcMFF)(JBQe(HiBRyPsb;^W~@*36DzB!UfI6=BbMrmiVmW z0VwQg;HaxwGT64l<6vidljhv<;bSy}M(cNi!sq&5k!q>ULmL#UKOnniJTx??`uQTl zY~^2^?l$XUn?{LT5kei%K1K!F?$;|sPTt=y01pKjyE`gpF6`OF{S}a(Tafc(wp#Ze D`a>n! literal 231 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!7%)r1n>(-?sKn{O^Pl)S*0|);9XJ~0+_z$EQ z7#`Knt^-nxB|(0{3=Yq3q=7g|-tI0e{TVj{fgG_C*NBqf{Irtt#G+J&^vpD)g1mGE zBRvB>L)*B089)``o-U3d6?1&M4)PvQ;5l+fi(A2vp(}!6Dx*Nk|Cv%5s~;VoE6>K# zQGEW5oA9EG!rjU&^ViLso3`2fSZHEMajgTe~DWM4fqRCMQ diff --git a/src/STD/resources/paste.png b/src/STD/resources/paste.png index c7446259534a83a6e06232c80c732b459919cd15..b2b5c95ac6a45af84b1f6de1b259e5e4ca890134 100755 GIT binary patch literal 1094 zcmV-M1iAZ(P)z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ&YxPIk2!}-hS88|pN z80O5H12)vj)d{Zd{pFp%Kl*Z@P!kssHA8v+_1Ux<}&p5 z_cAP9wv<6pL6M=SuLme!0;H3{YJdEYU{F;30e3w>05L{IM*Vkklw`Pm{TNX42gB6q z=fSqV|L~q+-THM5pMLyfxN`9n*n$rqJ}_K3e~y8Ri;Lmu)29pu`eF>Svb+p`|Ndjx zw*5ZXl>h<60`exvWgx>~VCm|mKnt!jJb&?=;p+t@Ds!3tFIZJ zJh{XmDk8+-;_Akbl#A&PU}a@xNY5*0m^^iXH7}Ql{ z7_5y=K`GY~Ab>CoymtL9!)IN1Q3dW&z^l@xb#?(fnSD)VR?}ugPb%w!>>OA z4Cl5@XRydw#~`R=#xQegEyJaY=NUvrB~TpF+T91voB#oYVxW*PC&Q=bHyAX;pD?&4 zs55-~_J?8h)^`lD79k8@U)^P3X5(bw)$(Q7b6^|8@^$+d6qMA#`u>5!@-M^;fB-@< zkb|9>Aud85OoIR)9~*;_juyk2!}A!}xrG@1{r$!8{K94iS0^WiP0MGZxUjON4@?6D z5Jnin41)n)K7NLb++v0Wi#7IPm zz53pV{~=G`qKY$tVi$=oEzH26B*3@^Ab?mH2!mZfg$zW3T>t?F0N;pZ%{;R2V*mgE M07*qoM6N<$f`ORsv;Y7A literal 280 zcmV+z0q6dSP)p}?9Qv#DoiT`}aPY1G@i@=zb*uwtp zmkY)pBs?6AgR+}@z?hGG;nxQ>UM}dz@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZk9}if)dhL5oPR>rCQc)lVy9ywHSQzjC zpdPTIC3~KthzHq7Fns&|lOZG|NZ|g1wxr66lD|MO0VwqvAb{|?P(?*$$3LKgPv8Fk z{|v=nzW@LK>fO)(*Y3WAyEHQ^=M@_pTM1ALA3y-H;5JNk)74wI+?S%c4g_TQe=)px z{g&a@!&eMCs({ThKq)nV0K#b?(A`YG{xC4u8%i_4;*1d@&hYrz8;19v zUom|7{sS0WYz$0{OhTX_2jVXP0ff^)pjVlH0u4NP{wY>@USSz9EhxkZwB-LkXw3fy z2p~pm$wo<8bw;LHV~f#;+p^g1^^ahyg$;D4>AA%002ovPDHLkV1h4ep~nCK literal 233 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!7%)r1n>(-?sKn{O^Pl)S*0|#1~TK@lM_z%Pk z3>q;Poq!Z$NswPKgTu2MX&_FLx4R2Vf5y!~AV;jkHKHUqKdq!Zu_%=xJu}UyATM3P zNY6me&^B&g22e$$r;B4q#T;9|+nfxB9H(Pt7Z~4RVU=~r_%{EgRO>H6zopr06D=?0RR91 diff --git a/src/STD/resources/redo.png b/src/STD/resources/redo.png index ac72e5c27cb02fdb6aebd6fdf3a8f08b4a4bb2fb..3753bb923cd9e03192cfe0d8cb013ae6813ddd51 100755 GIT binary patch literal 885 zcmV-*1B(2KP)z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ;>q$gGRCwBA{Qv(y12q9a05LI882|(j1IUFWxY7oQ z7Xh&)F0%jv2%mw{KbGxam~!?k!>_-8vw*VGVFm&O5W0ch zoNR1cCL|^@q}kdsFns^c!0_V-1H;ds3=Dt%fa$+qzcM`e{F&j+w{Hwr-@IYS-@BLL z!;c?gK)tU)W&s2c3z|1GSLf$5c&n%|Fg$$7@an}2h7(VpGJO91o8c$WKqe+81|C*c zkO2(W-@Rj4ed7j*-2l}0733z6BLM;kISfNW%*_7(pEc|M|CW~j2|79;L7)>Ep24sp zKmY#{pc)+!5s=(-AYKK;?m#RGG7w}AKmZ}TFgDiAjDZ2@l?BI-Gc34rj;n*1Y)2nu&^-P0=l;K)G3BXpMZ{FVuGbyaC-a#jOCl}-hnJ!hMuqi z0th`F&h%GRO=|@vULH0!27aK|`G7PN3nXOz|NYDG5ttVDK6t|h20 z1Q2>U%-?wXw!n?IZ^ObhH5q^|W)SA&WMBeX22%VFlwpAMo%bN$GO#0sB^&?*5PDt) zIa36PtAY3$EOxQr`#{_W#FFS{0R#}Xyvz*5LeRhmVPR+?fE(-?sK#pjDPl)S*0|(O5(ij+KrlrjU z0tN;ko8e_7w;YgSED7=pW^j0R10=?n*?YcQZXkvfq^-UO^uOFVzQz_10&lEi3m{%2_6XphGc;j yHqF!^hL=hVK9Uk42TzGOSUK#9bu1CEvt^K0XP(n=mTxoAAO=rYKbLh*2~7a~`8MzX diff --git a/src/STD/resources/reset.png b/src/STD/resources/reset.png index ccda81cb117fd14d8ba2279f5de2aa03b55e1b90..761af7368d1abbee4f38dfbcbedca5bbe3efabb1 100755 GIT binary patch literal 1032 zcmV+j1o!)iP)z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZRH&~*%AVhjx8;tUMm zzA;?8eVf7l#S4Zv|Nn;q^{jyz2oOME0x6~wY*bbM|Cu}Y|NrXh|Nn)A{x9X`{@=yP z`F{cz*Z;LVJpUi@^Z);^sQCY{py2=cKrx`610eUn3>3Z@?h<38dwjnHjX1neBnX9xwv{0th)$q@{Uy%*bku8Ys03i2niv z5VC>l>fGE649}i1FaTZn4d?lMT>|3{Reb16>ekfDlkf9B3FX5Hql`F);A)F))CV5Xivq-x*#5EqxAjDG;y% zF%QT5MIikRqW3Kj zbAT8C0fcPe)2Dy`p4sx@gNY5$Ya&1wGV%Z|m63rM0&*QFO+v$XB`~2s1iJ1O#D(Wz zh5!T*dMwXq273D>(B_N4*ku4l4A=lpP6!4X!f^2-!(L$8ob~f3!$+W(-~Rvq3aIZm z5dQ=j01!av2^&N#c4T3Rc4TE`5C)3r0llsR#329N0=fp|vg1Gte*pEJ16m3+WgAec z50njoW_<<-AZ$5B668{GMn*psph0X{GWj#0!FPc8FC;I|1>(Ix`~YayUw{BY&nd9H zECs|1fL8nmroaC(OicfkfLIjB2D%ia_zn=S2I4$ulHr2o6o3H2=0aF95QP?7UO=n^ z#J~i|@CFolK>Qep?*j2fAO>bDhOZFw{xbjs5H15@5ylI|VxZ&*H4v04zCjIs4oxmU zkxLtZ0K#V=vcc@obOvIBa^!a){=)$AK1u-#5MTffc}_YNsa>-G0000(-?sK#ov=Pl)S*0|);9XV|-sVZod^ z|A8z9hKEa&*8wTUk|4ie28U-i(m6vLp z1$pTTMtTN%hPHA0GJq;VJzX3_D(0m27;-fj2(YkE`r?+P-=x1o-s8>r7k~e2yK#1; zbj{VB#%i;{@t7vRb)2A-owOg9tRi2*k)6{5EmN1aeX};$d_CN2vYGxb%MOo=+y2z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ<xKpzbs~Q?&{nc4kgK9(EQsR_6cz z|1;nOjEsy7zyJJY{P5|=pI?9f{yBBw=JIpv+uDDB|L_?gfLK5Z6lFxhoa~JipFMxW z5NsvSAR{5bKnOg0{gGk8&KnGTLV^sRzx~O0Agyue<((5p0Ro6c%C(u1nTe6%&ht+U zS8qILaMBfHXgR=6(7+O_Ukso2xHKR+t~g|7ev5X-aOwg3NX&1Ya? zW@KPzWoBRkdS^xiCqV=6J^sqT#=^wF%=n+--@kth|Ni~~xq=NKfLO38j+%6hpn)xc z;tc=){b%_5_b=#UX@-QJ^Gt@7a5XpMU=|urU3Bco`ba00G1T^DihZ@eA-X zJp1^W;o_l(kl6bN68{T!`9B~A)Bpc5F#i7w4jyh!c7~t7e*?YtkAVT|NPqxhLC&9F zzkX$S_T(9ZAm={@F=0*yCKhIfzkmKSeEb@&B1W;*fEB#_HKs$o_>ZG z&z}KZ`itSm_pc0pe|-aIH&#|wa1QzT>le_+f8j0!2p}eD_jZukjG&kT1vn^tzkUC~ z@Z;BScqDxN@|EG^r_T%@K73?&|KT&(`yc=c-`_xW|A1a*WMl@50R#}!)18(7nV8vG zfG!8;OOR_pVadV4&LAu-#2_Id%J38D)%Wk-Gkkdef#KuFj}UdhumjP*KnDJ2X8iU2 z6WG%L0R#@io0re*GdI?>6BguScm{Oc$Issw%q=Y$)V1}25%Qhk$B&;3?>>BG`1#`p z!QGnAZM5y#-1xpaK9CW`96QhnW)?S!@j7zJ34C%Erd@@59|&S5NQW`0wxEJpcg& zF_3{l6pCemSO|!j8Q}4T75qnI{{iB6KztP-zyNe(%ahxayUPFo002ovPDHLkV1n@z B3}XNQ literal 215 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!9%)r1XI!iqT$l(m|32{Ae;6O_gki&3TqMZXs zF_r}R1v5B2yO9RsBze2LFr{(VfRu}sxJHx&=ckpFCl;kLq-UlX738HW80i`48QR9} z%K)nI^>lFzshE?TkPwiNkTB!Gfg=l8m&}#eBr!>XWru@DmT2=etpyT?nG}*37e;y? zSkda3%^Hw(m5a@kjm^N2*=a>vo14Lkbx{V)P7MqUQul;6JeuR&3^bU*)78&qol`;+ E0M`~hx&QzG diff --git a/src/STD/resources/undo.png b/src/STD/resources/undo.png index 61b19777e4f9527d8961358b7dde84d4af2d16e6..9b60fbd5d01059c8cc35f2dfa10f27626a498577 100755 GIT binary patch literal 873 zcmV-v1D5=WP)z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ;-$_J4RCwBA{Qv(y12q9a05LI882|(j1IUFqTxki! zi-6dM6te&V2%CYNK-|SIEb%|NcF})jT^o>O8WQ#cVrg6k0t65Xnph??3)?jNz#InO zq(%ltRvw0D&t5PHN^8x8S^4Gt3x;QR&N6&{`*aqNI~|BGAR7P>K#VZgF)}iWa`B12 zifr7=AgZ9t@aHcB!}ni61Aa0v`~xas0fsgQD+DtG*%x-rVmPp%fZ@-t?><27TVXB) z2q0twK~$EYtie>h&|U^UaW#hTpI$J0e0+i7&(CiREbQD2Y&^mY!b+A5g2LhqEX)iH zch7ERI55#?J5Zk&%s_wuLJvcbsTn|gMNGr#zkW#1e{K;4kmL&>eg?%qllI=j81GOw06mE8zEB*&h{r2BD zW;#fI7Z5Xp%mD}>^hg0oeg)#2KwSLy_m71Pzki5B`5@Q*f?CS;=;AQmjK{|{>DLm+++#N0sq4TwJh@gJy~KWsdr48Oj-Vfgm`2?JCd)QtmFRtzcsn`$o83RB7;W9AOGkXq$tfmb(4T93- z&)*CTAAbP-{oyUc=T~@O``!h%%Kmg$?9HM~uBvQB`W01z%K)ecw zOMut~h(%zz4j_Qga|$v5B^Og5Rs&*ov{V4{-diBP3&rn%_%FyTfB?d0AO{c&LX!g% zT3Y>sl$5^1A_Qa>KmajPyTk?vAgY(x009O7#HKIZQl!~300000NkvXXu0mjfr72_5 literal 210 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!7%)r1n>(-?sK#ov=Pl)S*0|(O5(ij+Krlrkf zU;r{0c8fE|0x8ClAirP+hi5lHVvI@N?k=o9@?RbYa>PnpBT9nv(@M${i&7cVGt-O; z^3oNI^bGV2ZR7T309Dv~x;TbZ%t=mQU}j}wb7#{iVECBO(8;)tf!9FG&|rfFL+EA) z6N97`4y=4Uemp!~4sBgbS7OxF+1c3AYpNKu@|hn*9eH^jXcU8|tDnm{r-UW|1Q0o1 diff --git a/src/STD/resources/undo_arrow.png b/src/STD/resources/undo_arrow.png deleted file mode 100755 index 717e0e6df7803954bf4d7edc708970333b7a959f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 895 zcmeAS@N?(olHy`uVBq!ia0vp^oIotV!OXzG*fMeIa|Q-xh5(-sR|bZL|NsC0Vg3!2 z1u}r-C>RZakrM(jE@`Yl-!hj3`2_=$|MgS6jzF%qr;B4q#hm1Xq$CDKHa3N$EJsgt vaH?@9ANEvX;+c`qb%8_8MyJDVQ7HpMPzEDo0B_A-P?&kT`njxgN@xNAf4(T; diff --git a/src/STD/resources/vtile.png b/src/STD/resources/vtile.png new file mode 100644 index 0000000000000000000000000000000000000000..9ad8814d73058287a9895da34961551bcd1914cd GIT binary patch literal 373 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE-VXMsm#F#`j)FbFd;%$g$s6l6(v z^mSxl*w|O|J8&|PuaN8!adnG-!)jK>28JY- zodGUq+19Vk&y!`8{_+00c+)EerViF4H$oTphbvwPVoSQp$RZ%jJeARbA@Ht41H+9cVO~AEHC`5IjcpLn31HK%^0II! ytdiysaOk #include #include +#include #include #include @@ -36,9 +37,9 @@ */ SUIT_Application::SUIT_Application() : QObject( 0 ), -myStudy( 0 ), -myDesktop( 0 ), -myStatusLabel( 0 ) + myStudy( 0 ), + myDesktop( 0 ), + myStatusLabel( 0 ) { if ( SUIT_Session::session() ) SUIT_Session::session()->insertApplication( this ); @@ -49,8 +50,9 @@ myStatusLabel( 0 ) */ SUIT_Application::~SUIT_Application() { - delete myStudy; - myStudy = 0; + SUIT_Study* s = myStudy; + setActiveStudy( 0 ); + delete s; setDesktop( 0 ); } @@ -67,7 +69,7 @@ SUIT_Desktop* SUIT_Application::desktop() \return FALSE if application can not be closed (because of non saved data for example). This method called by SUIT_Session whin closing of application was requested. */ -bool SUIT_Application::isPossibleToClose( bool& closePermanently ) +bool SUIT_Application::isPossibleToClose( bool& ) { return true; } @@ -94,7 +96,7 @@ SUIT_Study* SUIT_Application::activeStudy() const */ QString SUIT_Application::applicationVersion() const { - return QString::null; + return QString(); } /*! @@ -126,15 +128,6 @@ bool SUIT_Application::useFile( const QString& theFileName ) return status; } -/*! - Opens other study into active Study. If Study is empty - creates it. - \param theName - name of study -*/ -bool SUIT_Application::useStudy( const QString& /*theName*/ ) -{ - return false; -} - /*! Creates new empty Study if active Study = 0 */ @@ -204,7 +197,14 @@ void SUIT_Application::onInfoClear() bool changed = !myStatusLabel->text().isEmpty(); myStatusLabel->clear(); if ( changed ) - emit infoChanged( QString::null ); + emit infoChanged( QString() ); +} + +/*! + Update status of the registerd actions +*/ +void SUIT_Application::updateCommandsStatus() +{ } /*! @@ -243,8 +243,11 @@ void SUIT_Application::setDesktop( SUIT_Desktop* desk ) delete myDesktop; myDesktop = desk; - if ( myDesktop ) + if ( myDesktop ) { connect( myDesktop, SIGNAL( activated() ), this, SLOT( onDesktopActivated() ) ); + // Force desktop activation (NPAL16628) + QApplication::postEvent(myDesktop, new QEvent(QEvent::WindowActivate)); + } } /*! @@ -266,6 +269,13 @@ void SUIT_Application::setActiveStudy( SUIT_Study* study ) if ( myStudy == study ) return; + if ( myStudy ) + disconnect( myStudy, SIGNAL( studyModified( SUIT_Study* ) ), + this, SLOT( updateCommandsStatus() ) ); + if ( study ) + connect( study, SIGNAL( studyModified( SUIT_Study* ) ), + this, SLOT( updateCommandsStatus() ) ); + myStudy = study; } @@ -557,6 +567,16 @@ int SUIT_Application::actionId( const QAction* a ) const return id; } +QList SUIT_Application::actions() const +{ + return myActionMap.values(); +} + +QList SUIT_Application::actionIds() const +{ + return myActionMap.keys(); +} + /*! Creates action and registers it both in menu manager and tool manager \return new instance of action @@ -630,3 +650,12 @@ void SUIT_Application::onDesktopActivated() { emit activated( this ); } + +/*! + SLOT: is used for Help browsing +*/ +void SUIT_Application::onHelpContextModule( const QString& /*theComponentName*/, + const QString& /*theFileName*/, + const QString& /*theContext*/ ) +{ +} diff --git a/src/SUIT/SUIT_Application.h b/src/SUIT/SUIT_Application.h index 710d3b2d5..f20dc5633 100755 --- a/src/SUIT/SUIT_Application.h +++ b/src/SUIT/SUIT_Application.h @@ -84,9 +84,6 @@ public: //! 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(); @@ -111,6 +108,10 @@ signals: void activated( SUIT_Application* ); void infoChanged( QString ); +public slots: + virtual void updateCommandsStatus(); + virtual void onHelpContextModule( const QString&, const QString&, const QString& = QString() ); + private slots: void onInfoClear(); @@ -152,6 +153,10 @@ protected: static QAction* separator(); QAction* action( const int ) const; int actionId( const QAction* ) const; + + QList actions() const; + QList actionIds() const; + int registerAction( const int, QAction* ); QAction* createAction( const int, const QString&, const QIcon&, const QString&, const QString&, const int, QObject* = 0, diff --git a/src/SUIT/SUIT_FileDlg.cxx b/src/SUIT/SUIT_FileDlg.cxx index 6bebf3c9c..1a026be1b 100755 --- a/src/SUIT/SUIT_FileDlg.cxx +++ b/src/SUIT/SUIT_FileDlg.cxx @@ -16,50 +16,58 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +// File : SUIT_FileDlg.cxx +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) +// /*! - 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 ); + \class SUIT_FileDlg + \brief An extension of the Qt Open/Save file dialog box. + + The class SUIT_FileDlg provides a set of static methods which canbe used + for file or directories selection: + - getFileName() for single file opening or saving + - getOpenFileNames() for mulktiple files opening + - getExistingDirectory() for existing directory selection + + Examples: + \code + // select file to dump contents of the view + QStringList filters; + filters << "Image files (*.bmp *.gif *.jpg )" << "All files (*)"; + QString fileName = SUIT_FileDlg::getFileName( desktop(), + QString(), + filters, + "Dump view", + false ); + if ( !fileName.isEmpty() ) { + ... writing image to the file + } + + // select list of files to open in the editor windows + QStringList filters; + filters << "*.cpp | *.cxx | *.c++" << "*.h | *.hpp | *.hxx"; + QStringList fileNames = SUIT_FileDlg::getOpenFileName( desktop(), + QString(), + filters, + QString() ); + if ( !fileNames.isEmpty() ) { + ... open files + } + \endcode + + The class SUIT_FileDlg can be subclassed to implement custom file + dialog boxes. The class provides a set of methods which can be used + in subclasses: + - setCheckPermissions() - to enable/disable check of files/directories + permissions + - setValidator() - to use custom file validator + - addWidgets() - to add custom widgets to the lower part of the + dialog box + - getLastVisitedDirectory() - to get last visited directory + - acceptData() - can be used ti customize user selection validation + + \sa SUIT_FileValidator class. */ #include "SUIT_FileDlg.h" @@ -78,155 +86,147 @@ #include #include #include +#include +#include -#define MIN_COMBO_SIZE 100 +/*! + \brief Defines extension behavior. -/*! 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. - */ + If the selected file name has extension which does not match the selected filter + and this variable is set to \c true, the file extension is ignored and new one + (from current file filter will be added. + \sa addExtension() +*/ const bool IGNORE_NON_MATCHING_EXTENSION = true; QString SUIT_FileDlg::myLastVisitedPath; -/*! Constructor */ +/*! + \brief Constructor. + \param parent parent widget + \param open if \c true dialog box is used for file opening, otherwise - for saving + \param showQuickDir if \c true the quick directory list widgets will be shown + \param modal if \c true the dialog box will be modal +*/ SUIT_FileDlg::SUIT_FileDlg( QWidget* parent, bool open, bool showQuickDir, bool modal ) : QFileDialog( parent ), -myOpen( open ), -myValidator( 0 ), -myQuickLab( 0 ), -myQuickCombo( 0 ), -myQuickButton( 0 )//, -//myAccepted( false ) + myValidator( 0 ), + myQuickLab( 0 ), + myQuickCombo( 0 ), + myQuickButton( 0 ), + myCheckPermissions( true ) { setModal( modal ); - - const QObjectList& child = children(); - for ( QObjectList::const_iterator anIt = child.begin(); anIt != child.end(); ++anIt ) - { - QPushButton* pb = ::qobject_cast( *anIt ); - if ( pb ) - { - pb->setDefault( false ); - pb->setAutoDefault( false ); - } - } - + setSizeGripEnabled( true ); if ( parent ) setWindowIcon( parent->windowIcon() ); - setSizeGripEnabled( true ); - - QGridLayout* grid = ::qobject_cast( layout() ); - if ( showQuickDir && grid ) - { - // inserting quick dir combo box - myQuickLab = new QLabel( tr( "LAB_QUICK_PATH" ), this ); - myQuickCombo = new QComboBox( 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() ) ); + // add quick directories widgets + if ( showQuickDir ) { + myQuickLab = new QLabel( tr( "LAB_QUICK_PATH" ), this ); + myQuickCombo = new QComboBox( this ); + myQuickButton = new QPushButton( tr( "BUT_ADD_PATH" ), this ); + + if ( addWidgets( myQuickLab, myQuickCombo, myQuickButton ) ) { + connect( myQuickCombo, SIGNAL( activated( const QString& ) ), this, SLOT( quickDir( const QString& ) ) ); + connect( myQuickButton, SIGNAL( clicked() ), this, SLOT( addQuickDir() ) ); - int row = grid->rowCount(); - grid->addWidget( myQuickLab, row, 0 ); - grid->addWidget( myQuickCombo, row, 1, 1, 3 ); - grid->addWidget( myQuickButton, row, 5 ); + // retrieve directories list from the resources + QStringList dirList; + + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + if ( resMgr ) + dirList = resMgr->stringValue( "FileDlg", QString( "QuickDirList" ) ).split( ';', QString::SkipEmptyParts ); - // getting dir list from settings - QString dirs; - SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); - if ( resMgr ) - dirs = resMgr->stringValue( "FileDlg", QString( "QuickDirList" ) ); + if ( dirList.isEmpty() ) + dirList << QDir::homePath(); - QStringList dirList = dirs.split( ';' ); - if ( dirList.count() > 0 ) - { for ( int i = 0; i < dirList.count(); i++ ) - myQuickCombo->addItem( dirList[i] ); + myQuickCombo->addItem( dirList[i] ); + } + else { + delete myQuickLab; myQuickLab = 0; + delete myQuickCombo; myQuickCombo = 0; + delete myQuickButton; myQuickButton = 0; } - else - myQuickCombo->addItem( QDir::homePath() ); } - setAcceptMode( myOpen ? AcceptOpen: AcceptSave ); - setWindowTitle( myOpen ? tr( "INF_DESK_DOC_OPEN" ) : tr( "INF_DESK_DOC_SAVE" ) ); + + setAcceptMode( open ? AcceptOpen: AcceptSave ); + setWindowTitle( open ? 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 ( !myLastVisitedPath.isEmpty() ) { if ( !processPath( myLastVisitedPath ) && showQuickDir ) processPath( myQuickCombo->itemText( 0 ) ); } - else - { - if ( showQuickDir ) - processPath( myQuickCombo->itemText( 0 ) ); + else if ( showQuickDir ) { + processPath( myQuickCombo->itemText( 0 ) ); } // set default file validator - myValidator = new SUIT_FileValidator(this); + myValidator = new SUIT_FileValidator( this ); } -/*! Destructor*/ +/*! + \brief Destructor. +*/ SUIT_FileDlg::~SUIT_FileDlg() { setValidator( 0 ); } -bool SUIT_FileDlg::event( QEvent* e ) -{ - bool res = QFileDialog::event( e ); - if ( e->type() == QEvent::Polish ) - polish(); +/*! + \brief Check if the dialog box is used for opening or saving the file. + \return \c true if dialog is used for file opening and \c false otherwise +*/ +bool SUIT_FileDlg::isOpenDlg() const +{ + return acceptMode() == AcceptOpen; +} - return res; +/*! + \brief Get 'check file permissions' flag. + \return flag value + \sa setCheckPermissions() +*/ +bool SUIT_FileDlg::checkPermissions() const +{ + return myCheckPermissions; } -/*! Redefined from QFileDialog.*/ -void SUIT_FileDlg::polish() +/*! + \brief Set 'check file permissions' flag. + + If this flag is set and file validator is not null, + the validator will check the file permissions also. + + \param checkPerm new flag value + \sa checkPermissions() +*/ +void SUIT_FileDlg::setCheckPermissions( const bool checkPerm ) { -/* - 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 ); - } - } + myCheckPermissions = checkPerm; +} + +/*! + \brief Get file validator. + \return current file validator + \sa setValidator() */ +SUIT_FileValidator* SUIT_FileDlg::validator() const +{ + return myValidator; } -/*! Sets validator for file names to open/save - * Deletes previous validator if the dialog owns it. - */ +/*! + \brief Set file validator. + + Destroys previous validator if the dialog owns it. + + \param v new file validator + \sa validator() +*/ void SUIT_FileDlg::setValidator( SUIT_FileValidator* v ) { if ( myValidator && myValidator->parent() == this ) @@ -234,117 +234,263 @@ void SUIT_FileDlg::setValidator( SUIT_FileValidator* v ) myValidator = v; } -/*! Returns the selected file */ +/*! + \brief Adds the specified widgets to the bottom of the file dialog. + + The first widget (usually label) \a l is placed underneath the "file name" + and the "file types" labels. + The widget \a w is placed underneath the file types combobox. + The last widget (usually button) \a b is placed underneath the Cancel push button. + + In general, the widgets can be arbitrary. This method is added to support + the functionality provided by the Qt series 3.x. + + If you don't want to have one of the widgets added, pass 0 in that widget's position. + Every time this function is called, a new row of widgets is added to the bottom of the + file dialog. + + \param l first widget (e.g. text label) + \param w second widget (e.g. combo box) + \param b third widget (e.g. push button) + \return \c true if widgets have been added successfully +*/ +bool SUIT_FileDlg::addWidgets( QWidget* l, QWidget* w, QWidget* b ) +{ + QGridLayout* grid = ::qobject_cast( layout() ); + if ( grid ) { + int row = grid->rowCount(); + int columns = grid->columnCount(); + if ( l ) + grid->addWidget( l, row, 0 ); + if ( w ) + grid->addWidget( w, row, 1, 1, columns-2 ); + if ( b ) + grid->addWidget( b, row, columns-1 ); + return true; + } + return false; +} + +/*! + \brief Get list of selected files. + \return selected file names +*/ +QStringList SUIT_FileDlg::selectedFiles() const +{ + QStringList files = QFileDialog::selectedFiles(); + if ( fileMode() != DirectoryOnly && fileMode() != Directory ) { + QMutableListIterator it( files ); + while ( it.hasNext() ) { + QString f = it.next(); + QFileInfo finfo( f ); + if ( !finfo.isDir() ) + it.setValue( addExtension( f ) ); + } + } + return files; +} + +/*! + \brief Get selected file. + \return selected file name or null string if file is not selected +*/ QString SUIT_FileDlg::selectedFile() const { - return mySelectedFile; + QStringList files = selectedFiles(); + return files.count() > 0 ? files[0] : QString(); } -/*! Returns 'true' if this is 'Open File' dialog - * and 'false' if 'Save File' dialog - */ -bool SUIT_FileDlg::isOpenDlg() const +/*! + \brief Get last visited directory. + + Note, that last visited path is memorized only if the + dialog box is accepted. + + \return last visited directory +*/ +QString SUIT_FileDlg::getLastVisitedDirectory() { - return myOpen; + return myLastVisitedPath; } -/*! Closes this dialog and sets the return code to 'Accepted' - * if the selected name is valid ( see 'acceptData()' ) - */ -void SUIT_FileDlg::accept() +/*! + \brief Customize events processing. + \param e event + \return \c true if the event e was recognized and processed +*/ +bool SUIT_FileDlg::event( QEvent* e ) { - /* 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 ( acceptMode() != AcceptOpen ) - { - QString fn; - QStringList lst = QFileDialog::selectedFiles(); - if ( !lst.isEmpty() ) - fn = lst.first(); - mySelectedFile = fn; - addExtension(); - } + bool res = QFileDialog::event( e ); - if ( acceptData() ) - { - // NDS: needs to fill string mySelected file - QString fn; - QStringList lst = QFileDialog::selectedFiles(); - if ( !lst.isEmpty() ) - fn = lst.first(); - mySelectedFile = fn; - // end NDS - myLastVisitedPath = directory().path(); - QFileDialog::accept(); -// myAccepted = true; - } -// } -// myAccepted = !myAccepted; + if ( e->type() == QEvent::Polish ) + polish(); + + return res; } -/*! Closes this dialog and sets the return code to 'Rejected' */ -void SUIT_FileDlg::reject() +/*! + \brief Get line edit which is used to enter file name. + \return line edit widget or0 if it could not be found +*/ +QLineEdit* SUIT_FileDlg::lineEdit() const { - mySelectedFile = QString::null; - QFileDialog::reject(); + QLineEdit* ebox = 0; + QList editBoxes = findChildren(); + QGridLayout* grid = ::qobject_cast( layout() ); + if ( grid ) { + int idx = 10000; + for ( int i = 0; i < editBoxes.count(); i++ ) { + int widx = grid->indexOf( editBoxes[ i ] ); + if ( widx >= 0 ) + idx = qMin( idx, widx ); + } + if ( grid->itemAt( idx ) ) + ebox = qobject_cast( grid->itemAt( idx )->widget() ); + } + return ebox; } -/*! 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 - */ +/*! + \brief Validate user selection. + + The validation is done by calling the corresponding methods + of the validator. If the validator is not set, this method + always returns \c true. + + This method can be re-implemented in the subclasses to customize + the file dialog behavior. + Another solution could be implementing own file validator class. + + \return \c true if user selection (file(s) or directory) is valid + \sa SUIT_FileValidator class, validator(), setValidator() +*/ bool SUIT_FileDlg::acceptData() { - if ( myValidator ) - { - if ( isOpenDlg() ) + QStringList files = selectedFiles(); + if ( files.isEmpty() ) + return false; + + // special case for ".." + if ( lineEdit() ) { + QString txt = lineEdit()->text(); + if ( txt == ".." ) { + QDir dir = directory(); + if ( dir.cdUp() ) { + setDirectory( dir ); + bool block = lineEdit()->blockSignals( true ); + lineEdit()->setText( ".." ); + lineEdit()->selectAll(); + lineEdit()->setFocus( Qt::OtherFocusReason ); + lineEdit()->blockSignals( block ); + return false; + } + } + else if ( fileMode() != DirectoryOnly ) { + QStringList fs = txt.split( " ", QString::SkipEmptyParts ); + for ( int i = 0; i < fs.count(); i++ ) { + QString wc = fs.at( i ); + if ( wc.startsWith( "\"" ) && wc.endsWith( "\"" ) ) + wc = wc.mid( 1, wc.length()-2 ); + if ( hasWildCards( wc ) ) { + addFilter( wc ); + lineEdit()->clear(); + return false; + } + } + } + } + + // special case for wildcards + for ( int i = 0; i < files.count(); ++i ) { + } + + bool bOk = true; + + switch ( fileMode() ) { + case DirectoryOnly: + case Directory: { - if ( acceptMode() == AcceptOpen ) - { - QStringList fileNames = selectedFiles(); - for ( int i = 0; i < (int)fileNames.count(); i++ ) - { - if ( !myValidator->canOpen( fileNames[i] ) ) - return false; - } - return true; + QString fn = files.first(); + if ( validator() ) { + bOk = isOpenDlg() ? validator()->canReadDir( fn, checkPermissions() ) : + validator()->canWriteDir( fn, checkPermissions() ); } - else - { - return myValidator->canOpen( selectedFile() ); + break; + } + case AnyFile: + { + QString fn = files.first(); + QFileInfo info( fn ); + if ( info.isDir() ) { + setDirectory( info.absoluteFilePath() ); + if ( lineEdit() ) { + lineEdit()->selectAll(); + lineEdit()->setFocus( Qt::OtherFocusReason ); + } + return false; } + // validation is not required + if ( validator() ) { + bOk = isOpenDlg() ? validator()->canOpen( fn, checkPermissions() ) : + validator()->canSave( fn, checkPermissions() ); + } + break; + } + case ExistingFile: + case ExistingFiles: + { + for ( int i = 0; i < files.count(); ++i ) { + QFileInfo info( files.at( i ) ); + if ( info.isDir() ) { + setDirectory( info.absoluteFilePath() ); + if ( lineEdit() ) { + lineEdit()->selectAll(); + lineEdit()->setFocus( Qt::OtherFocusReason ); + } + return false; + } + if ( validator() ) { + bOk = isOpenDlg() ? validator()->canOpen( files.at( i ), checkPermissions() ) : + validator()->canSave( files.at( i ), checkPermissions() ); + if ( !bOk ) + return false; + } + } + break; } - else - return myValidator->canSave( selectedFile() ); } - return true; + + if ( bOk ) + emit filesSelected( files ); + + return bOk; } -/*! 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() +/*! + \brief Add an extension to the specified file name. + + The extension is extracted from the active filter. + + \param fileName file name to be processed + \return fileName with the extension added +*/ +QString SUIT_FileDlg::addExtension( const QString& fileName ) const { + QString fname = fileName.trimmed(); + // check if file name entered is empty - if ( mySelectedFile.trimmed().isEmpty() ) - return; + if ( fname.isEmpty() ) + return fileName; // current file extension - QString anExt = "." + SUIT_Tools::extension( mySelectedFile.trimmed() ).trimmed(); + QString anExt = "." + SUIT_Tools::extension( fname ).trimmed(); // 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; + return fileName; QRegExp r( QString::fromLatin1("\\(?[a-zA-Z0-9.*? +;#|]*\\)?$") ); int index = r.indexIn( selectedFilter().trimmed() ); @@ -365,8 +511,7 @@ void SUIT_FileDlg::addExtension() // now we get the list of all extension masks and remove all which does not contain wildcard symbols QStringList extList = aPattern.split( "|", QString::SkipEmptyParts ); - for ( int i = extList.count() - 1; i >= 0; i-- ) - { + for ( int i = extList.count() - 1; i >= 0; i-- ) { if ( !extList[i].contains( "." ) ) extList.removeAt( i ); } @@ -376,129 +521,234 @@ void SUIT_FileDlg::addExtension() QRegExp anExtRExp( "^("+ aPattern + ")$" ); // Check if the current file extension matches the pattern - if ( !anExtRExp.exactMatch( anExt ) ) - { + if ( !anExtRExp.exactMatch( anExt ) ) { // find first appropriate extension in the selected filter // (it should be without wildcard symbols) - for ( int i = 0; i < (int)extList.count(); i++ ) - { + for ( int i = 0; i < extList.count(); i++ ) { QString newExt = extList[i].replace( QRegExp( "[\\\\][+]" ),"+" ); int res = newExt.lastIndexOf( '.' ); if ( res >= 0 ) newExt = newExt.mid( res + 1 ); - if ( newExt.indexOf( QRegExp("[*|?]" ) ) < 0 ) - { - mySelectedFile.trimmed(); - mySelectedFile += mySelectedFile.endsWith(".") ? newExt : QString(".") + newExt; - break; + if ( newExt.indexOf( QRegExp("[*|?]" ) ) < 0 ) { + fname += fname.endsWith( "." ) ? newExt : QString( "." ) + newExt; + return fname; } } } } + return fileName; } -/*! Processes selection : tries to set given path or filename as selection */ +/*! + \brief Processes selection : tries to set specified sirectory or filename + as current file dialog selection. + \param path file or directory path + \return \c true if \a path is processed correctly and \c false otherwise +*/ bool SUIT_FileDlg::processPath( const QString& path ) { - if ( !path.isNull() ) - { + if ( !path.isNull() ) { QFileInfo fi( path ); - if ( fi.exists() ) - { + if ( fi.exists() ) { if ( fi.isFile() ) - selectFile( path ); + selectFile( path ); else if ( fi.isDir() ) - setDirectory( path ); + setDirectory( path ); return true; } - else - { - if ( QFileInfo( SUIT_Tools::dir( path ) ).exists() ) - { - setDirectory( SUIT_Tools::dir( path ) ); - selectFile( path ); - return true; - } + else if ( QFileInfo( SUIT_Tools::dir( path ) ).exists() ) { + setDirectory( SUIT_Tools::dir( path ) ); + selectFile( path ); + return true; } } return false; } -/*! Called when user selects item from "Quick Dir" combo box */ -void SUIT_FileDlg::quickDir(const QString& dirPath) + +/*! + \brief Add file filter and activates it. + \param filter new file filter +*/ +void SUIT_FileDlg::addFilter( const QString& filter ) { - QString aPath = dirPath; - if ( !QDir(aPath).exists() ) - { - aPath = QDir::homePath(); - SUIT_MessageBox::critical( this, tr( "ERR_ERROR" ), tr( "ERR_DIR_NOT_EXIST" ).arg( dirPath ) ); + QStringList flist = filters(); + if ( !flist.contains( filter ) ) { + flist << filter; + setFilters( flist ); + } + selectFilter( filter ); +} + +/*! + \brief Check if the string contains wildcard symbols. + \param s string to be checked (for example, file name) + \return \c true if string contains "*" or "?" symbols +*/ +bool SUIT_FileDlg::hasWildCards( const QString& s ) +{ + return s.contains( QRegExp("[*|?]") ); +} + +/*! + \brief Called when the user presses "Open"or "Save" button. + + Verifies the user choice and closes dialog box, setting the return code to QDialog::Accepted + + \sa acceptData() +*/ +void SUIT_FileDlg::accept() +{ + if ( acceptData() ) { + myLastVisitedPath = directory().path(); + QDialog::accept(); } +} + +/*! + \brief Called when user selects directory from the "Quick Dir" combo box. + + Browses the file dialog to the specified directory (if it is valid). + + \param dirPath selected directory +*/ +void SUIT_FileDlg::quickDir( const QString& dirPath ) +{ + if ( !QDir( dirPath ).exists() ) + SUIT_MessageBox::critical( this, tr( "ERR_ERROR" ), tr( "ERR_DIR_NOT_EXIST" ).arg( dirPath ) ); else - processPath( aPath ); + processPath( dirPath ); } + /*! - Called when user presses "Add" button - adds current directory to quick directory - list and to the preferences + \brief Called when user presses "Quick Dir Add" button. + + Adds current directory to the quick directories list and to the preferences. */ void SUIT_FileDlg::addQuickDir() { QString dp = directory().path(); - if ( !dp.isEmpty() ) - { + if ( !dp.isEmpty() ) { QDir dir( dp ); - // getting dir list from settings - QString dirs; + + QStringList dirList; + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); if ( resMgr ) - dirs = resMgr->stringValue( "FileDlg", QString( "QuickDirList" ) ); - QStringList dirList = dirs.split( ';', QString::SkipEmptyParts ); + dirList = resMgr->stringValue( "FileDlg", QString( "QuickDirList" ) ).split( ';', QString::SkipEmptyParts ); + bool found = false; bool emptyAndHome = false; - if ( dirList.count() > 0 ) - { - for ( int i = 0; i < dirList.count(); i++ ) - { - QDir aDir( dirList[i] ); - if ( aDir.canonicalPath().isNull() && dirList[i] == dir.absolutePath() || - !aDir.canonicalPath().isNull() && aDir.exists() && aDir.canonicalPath() == dir.canonicalPath() ) - { - found = true; - break; - } + if ( dirList.count() > 0 ) { + for ( int i = 0; i < dirList.count() && !found; i++ ) { + QDir aDir( dirList[i] ); + if ( aDir.canonicalPath().isNull() && dirList[i] == dir.absolutePath() || + !aDir.canonicalPath().isNull() && aDir.exists() && + aDir.canonicalPath() == dir.canonicalPath() ) { + found = true; + } } } - else + else { emptyAndHome = dir.canonicalPath() == QDir( QDir::homePath() ).canonicalPath(); + } - if ( !found ) - { + if ( !found ) { dirList.append( dp ); resMgr->setValue( "FileDlg", QString( "QuickDirList" ), dirList.join( ";" ) ); if ( !emptyAndHome ) - myQuickCombo->addItem( dp ); + myQuickCombo->addItem( dp ); } } } + /*! - Returns the file name for Open/Save [ static ] + \brief Polish the dialog box. */ -QString SUIT_FileDlg::getFileName( QWidget* parent, const QString& initial, const QStringList& filters, - const QString& caption, bool open, bool showQuickDir, +void SUIT_FileDlg::polish() +{ + QList buttons = findChildren(); + + int maxBtnWidth = 0; + + for ( QList::const_iterator it = buttons.begin(); + it != buttons.end(); ++it ) + maxBtnWidth = qMax( maxBtnWidth, (*it)->sizeHint().width() ); + + for ( QList::const_iterator it = buttons.begin(); + it != buttons.end(); ++it ) { + (*it)->setDefault( false ); + (*it)->setAutoDefault( false ); + (*it)->setFixedWidth( maxBtnWidth ); + } + + QList views = findChildren(); + for ( QList::const_iterator it = views.begin(); + it != views.end(); ++it ) { + (*it)->setViewMode( QListView::ListMode ); + } +} + +/*! + \brief Show dialog box for the file opening/saving. + + This method can be used to select the file for opening + or saving. The behavior is defined by the \a open parameter. + Note, that selection validation depends on the dialog mode used. + + If \a initial parameter is not null string it is used as starting directory + or file at which dialog box is opened. + + The parameter \a filters defines file filters (wildcards) to be used. + If filters list is empty, "All files (*)" is used by default. + + The parameter \a caption is used as dialog box title. If it is + is empty, the default title is used. + + The parameter \a showQuickDir specifies if it is necessary to + show additional quick directories list controls in the bottom part + of the dialog box. + + The validation of the user selection is done with help of the file + validator (SUIT_FileValidator class). The last parameter \a validator + can be used to pass the custom file validator to the dialog box. + + \param parent parent widget + \param initial initial file (or directory) dialog box to be opened on + \param filters file filters list + \param caption dialog box title + \param open if \c true dialog box is used for file opening, otherwise - for saving + \param showQuickDir if \c true the quick directory list widgets will be shown + \param validator custom file validator + \return selected file name or null string if dialog box is cancelled + \sa getOpenFileNames(), getExistingDirectory() +*/ +QString SUIT_FileDlg::getFileName( QWidget* parent, const QString& initial, + const QStringList& filters, const QString& caption, + const bool open, const bool showQuickDir, SUIT_FileValidator* validator ) { - SUIT_FileDlg* fd = new SUIT_FileDlg( parent, open, showQuickDir, true ); + SUIT_FileDlg fd( parent, open, showQuickDir, true ); + + fd.setFileMode( open ? ExistingFile : AnyFile ); + + if ( filters.isEmpty() ) + fd.setFilter( tr( "ALL_FILES_FILTER" ) ); // All files (*) + else + fd.setFilters( filters ); + if ( !caption.isEmpty() ) - fd->setWindowTitle( caption ); + fd.setWindowTitle( 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.processPath( initial ); - fd->setFilters( filters ); if ( validator ) - fd->setValidator( validator ); + fd.setValidator( validator ); - fd->exec(); + QString filename; - QString filename = fd->selectedFile(); - delete fd; + if ( fd.exec() == QDialog::Accepted ) + filename = fd.selectedFile(); QApplication::processEvents(); @@ -506,50 +756,215 @@ QString SUIT_FileDlg::getFileName( QWidget* parent, const QString& initial, cons } /*! - Returns the list of files to be opened [ static ] + \brief Show dialog box for the file opening/saving. + \overload + + This method can be used to select the file for opening + or saving. The behavior is defined by the \a open parameter. + Note, that selection validation depends on the dialog mode used. + + If \a initial parameter is not null string it is used as starting directory + or file at which dialog box is opened. + + The parameter \a filters defines file filters (wildcards) to be used. + This is the list of wildcards, separated by the ";;" symbols. + If filters list is empty, "All files (*)" is used by default. + + The parameter \a caption is used as dialog box title. If it is + is empty, the default title is used. + + The parameter \a showQuickDir specifies if it is necessary to + show additional quick directories list controls in the bottom part + of the dialog box. + + The validation of the user selection is done with help of the file + validator (SUIT_FileValidator class). The last parameter \a validator + can be used to pass the custom file validator to the dialog box. + + \param parent parent widget + \param initial initial file (or directory) dialog box to be opened on + \param filters file filters separated by ";;" + \param caption dialog box title + \param open if \c true dialog box is used for file opening, otherwise - for saving + \param showQuickDir if \c true the quick directory list widgets will be shown + \param validator custom file validator + \return selected file name or null string if dialog box is cancelled + \sa getOpenFileNames(), getExistingDirectory() +*/ +QString SUIT_FileDlg::getFileName( QWidget* parent, const QString& initial, + const QString& filters, const QString& caption, + const bool open, const bool showQuickDir, + SUIT_FileValidator* validator ) +{ + return getFileName( parent, initial, filters.split( ";;", QString::SkipEmptyParts ), + caption, open, showQuickDir, validator ); +} + +/*! + \brief Show dialog box for the multiple files selection. + + If \a initial parameter is not null string it is used as starting directory + or file at which dialog box is opened. + + The parameter \a filters defines file filters (wildcards) to be used. + If filters list is empty, "All files (*)" is used by default. + + The parameter \a caption is used as dialog box title. If it is + is empty, the default title is used. + + The parameter \a showQuickDir specifies if it is necessary to + show additional quick directories list controls in the bottom part + of the dialog box. + + The validation of the user selection is done with help of the file + validator (SUIT_FileValidator class). The last parameter \a validator + can be used to pass the custom file validator to the dialog box. + + \param parent parent widget + \param initial initial file (or directory) dialog box to be opened on + \param filters file filters list + \param caption dialog box title + \param showQuickDir if \c true the quick directory list widgets will be shown + \param validator custom file validator + \return selected file names or empty list if dialog box is cancelled + \sa getFileName(), getExistingDirectory() */ -QStringList SUIT_FileDlg::getOpenFileNames( QWidget* parent, const QString& initial, const QStringList& filters, - const QString& caption, bool showQuickDir, SUIT_FileValidator* validator ) +QStringList SUIT_FileDlg::getOpenFileNames( QWidget* parent, const QString& initial, + const QStringList& filters, const QString& caption, + const bool showQuickDir, + SUIT_FileValidator* validator ) { - SUIT_FileDlg* fd = new SUIT_FileDlg( parent, true, showQuickDir, true ); - fd->setFileMode( ExistingFiles ); + SUIT_FileDlg fd( parent, true, showQuickDir, true ); + + fd.setFileMode( ExistingFiles ); + + if ( filters.isEmpty() ) + fd.setFilter( tr( "ALL_FILES_FILTER" ) ); // All files (*) + else + fd.setFilters( filters ); + if ( !caption.isEmpty() ) - fd->setWindowTitle( caption ); + fd.setWindowTitle( 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.processPath( initial ); - fd->setFilters( filters ); if ( validator ) - fd->setValidator( validator ); + fd.setValidator( validator ); + + QStringList filenames; - fd->exec(); - QStringList filenames = fd->selectedFiles(); - delete fd; + if ( fd.exec() == QDialog::Accepted ) + filenames = fd.selectedFiles(); QApplication::processEvents(); + return filenames; } /*! - Existing directory selection dialog [ static ] + \brief Show dialog box for the multiple file opening. + \overload + + If \a initial parameter is not null string it is used as starting directory + or file at which dialog box is opened. + + The parameter \a filters defines file filters (wildcards) to be used. + This is the list of wildcards, separated by the ";;" symbols. + If filters list is empty, "All files (*)" is used by default. + + The parameter \a caption is used as dialog box title. If it is + is empty, the default title is used. + + The parameter \a showQuickDir specifies if it is necessary to + show additional quick directories list controls in the bottom part + of the dialog box. + + The validation of the user selection is done with help of the file + validator (SUIT_FileValidator class). The last parameter \a validator + can be used to pass the custom file validator to the dialog box. + + \param parent parent widget + \param initial initial file (or directory) dialog box to be opened on + \param filters file filters separated by ";;" + \param caption dialog box title + \param showQuickDir if \c true the quick directory list widgets will be shown + \param validator custom file validator + \return selected file names or empty list if dialog box is cancelled + \sa getFileName(), getExistingDirectory() +*/ +QStringList SUIT_FileDlg::getOpenFileNames( QWidget* parent, const QString& initial, + const QString& filters, const QString& caption, + const bool showQuickDir, + SUIT_FileValidator* validator ) +{ + return getOpenFileNames( parent, initial, filters.split( ";;", QString::SkipEmptyParts ), + caption, showQuickDir, validator ); +} + +/*! + \brief Show dialog box for the existing directory selection. + + If \a initial parameter is not null string it is used as starting directory + at which dialog box is opened. + + The parameter \a caption is used as dialog box title. If it is + is empty, the default title is used. + + The parameter \a showQuickDir specifies if it is necessary to + show additional quick directories list controls in the bottom part + of the dialog box. + + The validation of the user selection is done with help of the file + validator (SUIT_FileValidator class). The last parameter \a validator + can be used to pass the custom file validator to the dialog box. + + \param parent parent widget + \param initial initial directory dialog box to be opened on + \param caption dialog box title + \param showQuickDir if \c true the quick directory list widgets will be shown + \param validator custom file validator + \return selected directory name or null string if dialog box is cancelled + \sa getFileName(), getOpenFileNames() */ QString SUIT_FileDlg::getExistingDirectory( QWidget* parent, const QString& initial, - const QString& caption, bool showQuickDir ) + const QString& caption, const bool showQuickDir, + SUIT_FileValidator* validator ) { - SUIT_FileDlg* fd = new SUIT_FileDlg( parent, true, showQuickDir, true ); + SUIT_FileDlg fd( parent, true, showQuickDir, true ); + + fd.setFileMode( DirectoryOnly ); + if ( !caption.isEmpty() ) - fd->setWindowTitle( 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.setWindowTitle( caption ); - fd->setFileMode( DirectoryOnly ); - fd->setFilters( QStringList( tr( "INF_DIRECTORIES_FILTER" ) ) ); + if ( !initial.isEmpty() ) + fd.processPath( initial ); + + if ( validator ) + fd.setValidator( validator ); - fd->exec(); + QString dirname; - QString dirname = fd->selectedFile(); - delete fd; + if ( fd.exec() == QDialog::Accepted ) + dirname = fd.selectedFile(); QApplication::processEvents(); + return dirname; } + +/*! + \brief Selects current file + + This version of selectFile() methods works similar to Qt version 3.x: + it selects the given file as current and it changes the current file dialog's directory + to the directory of the file + + \param f - new current file name +*/ +void SUIT_FileDlg::selectFile( const QString& f ) +{ + QFileDialog::selectFile( f ); + setDirectory( QFileInfo( f ).absoluteDir() ); +} diff --git a/src/SUIT/SUIT_FileDlg.h b/src/SUIT/SUIT_FileDlg.h index c2d7e4c44..5405baa6e 100755 --- a/src/SUIT/SUIT_FileDlg.h +++ b/src/SUIT/SUIT_FileDlg.h @@ -16,79 +16,106 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#ifndef SUIT_FILEDIALOG_H -#define SUIT_FILEDIALOG_H +// File : SUIT_FileDlg.h +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) +// + +#ifndef SUIT_FILEDLG_H +#define SUIT_FILEDLG_H #include "SUIT.h" #include class QLabel; +class QLineEdit; 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 ); + SUIT_FileDlg( QWidget*, bool, bool = true, bool = true ); virtual ~SUIT_FileDlg(); -public: bool isOpenDlg() const; - QString selectedFile() const; + + bool checkPermissions() const; + void setCheckPermissions( const bool ); + SUIT_FileValidator* validator() 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 ); + bool addWidgets( QWidget*, QWidget*, QWidget* ); -private: - void polish(); - bool acceptData(); - void addExtension(); - bool processPath( const QString& path ); + QStringList selectedFiles() const; + QString selectedFile() const; + + static QString getLastVisitedDirectory(); + + void selectFile( const QString& ); + + static QString getFileName( QWidget*, + const QString&, + const QStringList&, + const QString& = QString(), + const bool = true, + const bool = true, + SUIT_FileValidator* = 0 ); + static QString getFileName( QWidget*, + const QString&, + const QString&, + const QString& = QString(), + const bool = true, + const bool = true, + SUIT_FileValidator* = 0 ); + + static QStringList getOpenFileNames( QWidget*, + const QString&, + const QStringList&, + const QString& = QString(), + const bool = true, + SUIT_FileValidator* = 0 ); + static QStringList getOpenFileNames( QWidget*, + const QString&, + const QString&, + const QString& = QString(), + const bool = true, + SUIT_FileValidator* = 0 ); + + static QString getExistingDirectory( QWidget*, + const QString&, + const QString& = QString(), + const bool = true, + SUIT_FileValidator* = 0 ); + +protected: + virtual bool event( QEvent* ); + QLineEdit* lineEdit() const; + virtual bool acceptData(); + QString addExtension( const QString& ) const; + bool processPath( const QString& ); + void addFilter( const QString& ); + static bool hasWildCards( const QString& ); protected slots: void accept(); - void reject(); void quickDir( const QString& ); void addQuickDir(); -protected: - virtual bool event( QEvent* ); +private: + void polish(); -protected: - bool myOpen; //!< open/save selector - QString mySelectedFile; //!< selected filename +private: 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 - */ - + bool myCheckPermissions; //!< check permissions option static QString myLastVisitedPath; //!< last visited path }; -#endif +#endif // SUIT_FILEDLG_H diff --git a/src/SUIT/SUIT_FileValidator.cxx b/src/SUIT/SUIT_FileValidator.cxx index 0adb0b331..5885a7892 100755 --- a/src/SUIT/SUIT_FileValidator.cxx +++ b/src/SUIT/SUIT_FileValidator.cxx @@ -16,74 +16,178 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#include "SUIT_FileValidator.h" +// File : SUIT_FileValidator.cxx +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) +// +#include "SUIT_FileValidator.h" #include "SUIT_MessageBox.h" - -#include +#include "SUIT_Tools.h" #include -/*! constructor */ -SUIT_FileValidator::SUIT_FileValidator(QWidget* parent) : -myParent(parent) +/*! + \class SUIT_FileValidator + \brief Provides functionality to check the file or directory + existance and permissions. + \sa SUIT_FileDlg class +*/ + +/*! + \brief Constructor. + \param parent parent widget (used as parent when displaying + information message boxes) +*/ +SUIT_FileValidator::SUIT_FileValidator( QWidget* parent ) +: myParent( parent ) { } -/*! returns false if can't open file */ -bool SUIT_FileValidator::canOpen( const QString& file ) +/*! + \brief Check if the specified file exists and (optionally) can be read. + + If file does not exists or can not be read (if \a checkPermission is \c true) + and parent() is not null, shows error message box. + + \param fileName file path + \param checkPermission if \c true (default) check also file permissions + \return \c false if file does not exist or if it does not have + read permissions (if \a checkPermission is \c true) +*/ +bool SUIT_FileValidator::canOpen( const QString& fileName, bool checkPermission ) { - if ( !QFile::exists( file ) ) - { - SUIT_MessageBox::critical( myParent, QObject::tr( "ERR_ERROR" ), - QObject::tr( "ERR_FILE_NOT_EXIST" ).arg( file ) ); - return false; + if ( !QFile::exists( fileName ) ) { + if ( parent() ) + SUIT_MessageBox::critical( parent(), QObject::tr( "ERR_ERROR" ), + QObject::tr( "ERR_FILE_NOT_EXIST" ).arg( fileName ) ); + return false; } - if ( !QFileInfo( file ).isReadable() ) - { - SUIT_MessageBox::critical( myParent, QObject::tr( "ERR_ERROR" ), - QObject::tr( "ERR_PERMISSION_DENIED" ).arg( file ) ); + if ( checkPermission && !QFileInfo( fileName ).isReadable() ) { + if ( parent() ) + SUIT_MessageBox::critical( parent(), QObject::tr( "ERR_ERROR" ), + QObject::tr( "ERR_PERMISSION_DENIED" ).arg( fileName ) ); return false; } return true; } -/*! returns false if can't save file */ -bool SUIT_FileValidator::canSave( const QString& file ) +/*! + \brief Check if the specified file can be written. + + If file already exists and parent() is not null, prompts + question message box to the user to confirm file overwriting. + + If file can not be written (if \a checkPermission is \c true) + and parent() is not null, shows error message box. + + \param fileName file path + \param checkPermission if \c true (default) check also file permissions + \return \c false if file exists and user rejects file overwriting + or if file does not have write permissions (if \a checkPermission is \c true) +*/ +bool SUIT_FileValidator::canSave( const QString& fileName, bool checkPermission ) { - if ( QFile::exists( file ) ) - { - // if file exists - raise warning... - if ( SUIT_MessageBox::question( myParent, QObject::tr( "WRN_WARNING" ), - QObject::tr( "QUE_DOC_FILEEXISTS" ).arg( file ), - SUIT_MessageBox::Yes | SUIT_MessageBox::No, - SUIT_MessageBox::No ) != SUIT_MessageBox::Yes ) - { - return false; - } - // ... and if user wants to overwrite file, check it for writeability - if ( !QFileInfo( file ).isWritable() ) - { - SUIT_MessageBox::critical( myParent, QObject::tr( "ERR_ERROR" ), - QObject::tr( "ERR_PERMISSION_DENIED" ).arg( file ) ); + if ( QFile::exists( fileName ) ) { + if ( parent() ) + if ( SUIT_MessageBox::question( parent(), QObject::tr( "WRN_WARNING" ), + QObject::tr( "QUE_DOC_FILEEXISTS" ).arg( fileName ), + SUIT_MessageBox::Yes | SUIT_MessageBox::No, + SUIT_MessageBox::No ) != SUIT_MessageBox::Yes ) + return false; + + if ( checkPermission && !QFileInfo( fileName ).isWritable() ) { + if ( parent() ) + SUIT_MessageBox::critical( myParent, QObject::tr( "ERR_ERROR" ), + QObject::tr( "ERR_PERMISSION_DENIED" ).arg( fileName ) ); return false; } } - else - { - // if file doesn't exist - try to create it - QFile qf( file ); - if ( !qf.open( QFile::WriteOnly ) ) - { - SUIT_MessageBox::critical( myParent, QObject::tr( "ERR_ERROR" ), - QObject::tr( "ERR_PERMISSION_DENIED" ).arg( file ) ); + else { + QString dirName = SUIT_Tools::dir( fileName ); + if ( checkPermission && !QFileInfo( dirName ).isWritable() ) { + if ( parent() ) + SUIT_MessageBox::critical( parent(), QObject::tr( "ERR_ERROR" ), + QObject::tr( "ERR_PERMISSION_DENIED" ).arg( fileName ) ); return false; } - else - { - // remove just created file - qf.close(); - qf.remove(); - } } return true; } + +/*! + \brief Check if the specified directory exists and (optionally) can be read. + + If directory does not exists or can not be read (if \a checkPermission is \c true) + and parent() is not null, shows error message box. + + \param dirName directory path + \param checkPermission if \c true (default) check also directory permissions + \return \c false if directory does not exist or if it does not have + read permissions (if \a checkPermission is \c true) +*/ +bool SUIT_FileValidator::canReadDir( const QString& dirName, bool checkPermission ) +{ + QFileInfo info( dirName ); + if ( !info.exists() ) { + if ( parent() ) + SUIT_MessageBox::critical( parent(), QObject::tr( "ERR_ERROR" ), + QObject::tr( "ERR_DIR_NOT_EXIST" ).arg( dirName ) ); + return false; + } + if ( !info.isDir() ) { + if ( parent() ) + SUIT_MessageBox::critical( parent(), QObject::tr( "ERR_ERROR" ), + QObject::tr( "ERR_FILE_NOT_DIR" ).arg( dirName ) ); + return false; + } + if ( checkPermission && !info.isReadable() ) { + if ( parent() ) + SUIT_MessageBox::critical( parent(), QObject::tr( "ERR_ERROR" ), + QObject::tr( "ERR_PERMISSION_DENIED" ).arg( dirName ) ); + return false; + } + return true; +} + +/*! + \brief Check if the specified directory can be written. + + If directory does not exists or can not be modified (if \a checkPermission is \c true) + and parent() is not null, shows error message box. + + \param dirName directory path + \param checkPermission if \c true (default) check also directory permissions + \return \c false if directory does not exist or if it does not have + write permissions (if \a checkPermission is \c true) +*/ +bool SUIT_FileValidator::canWriteDir( const QString& dirName, bool checkPermission ) +{ + QFileInfo info( dirName ); + if ( !info.exists() ) { + if ( parent() ) + SUIT_MessageBox::critical( parent(), QObject::tr( "ERR_ERROR" ), + QObject::tr( "ERR_DIR_NOT_EXIST" ).arg( dirName ) ); + return false; + } + if ( !info.isDir() ) { + if ( parent() ) + SUIT_MessageBox::critical( parent(), QObject::tr( "ERR_ERROR" ), + QObject::tr( "ERR_FILE_NOT_DIR" ).arg( dirName ) ); + return false; + } + if ( checkPermission && !info.isWritable() ) { + if ( parent() ) + SUIT_MessageBox::critical( parent(), QObject::tr( "ERR_ERROR" ), + QObject::tr( "ERR_PERMISSION_DENIED" ).arg( dirName ) ); + return false; + } + return true; +} + +/*! + \brief Get parent widget. + \return parent widget +*/ +QWidget* SUIT_FileValidator::parent() const +{ + return myParent; +} diff --git a/src/SUIT/SUIT_FileValidator.h b/src/SUIT/SUIT_FileValidator.h index 9142c381d..edcd3398b 100755 --- a/src/SUIT/SUIT_FileValidator.h +++ b/src/SUIT/SUIT_FileValidator.h @@ -16,8 +16,10 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SALOME SALOMEGUI : implementation of desktop and GUI kernel +// File : SUIT_FileValidator.h +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) // + #ifndef SUIT_FILEVALIDATOR_H #define SUIT_FILEVALIDATOR_H @@ -26,24 +28,21 @@ class QWidget; class QString; -/*! - \class SUIT_FileValidator - Provides functionality to check file -*/ class SUIT_EXPORT SUIT_FileValidator { public: - SUIT_FileValidator(QWidget* parent = 0); + SUIT_FileValidator( QWidget* = 0 ); - virtual bool canOpen( const QString& file ); - virtual bool canSave( const QString& file ); + virtual bool canOpen( const QString&, bool = true ); + virtual bool canSave( const QString&, bool = true ); - //! Return parent widget - QWidget* parent() const { return myParent; } - - private: + virtual bool canReadDir( const QString&, bool = true ); + virtual bool canWriteDir( const QString&, bool = true ); + + QWidget* parent() const; +private: QWidget* myParent; }; -#endif +#endif // SUIT_FILEVALIDATOR_H diff --git a/src/SUIT/SUIT_Operation.cxx b/src/SUIT/SUIT_Operation.cxx index 31ff40f8f..73ab85cc2 100755 --- a/src/SUIT/SUIT_Operation.cxx +++ b/src/SUIT/SUIT_Operation.cxx @@ -154,7 +154,7 @@ bool SUIT_Operation::testFlags( const int f ) const */ QString SUIT_Operation::operationName() const { - return QString::null; + return QString(); } /*! diff --git a/src/SUIT/SUIT_Operation.h b/src/SUIT/SUIT_Operation.h index 6a1785e2a..cf29007d7 100755 --- a/src/SUIT/SUIT_Operation.h +++ b/src/SUIT/SUIT_Operation.h @@ -140,7 +140,7 @@ protected: virtual bool openTransaction(); virtual bool abortTransaction(); virtual bool hasTransaction() const; - virtual bool commitTransaction( const QString& = QString::null ); + virtual bool commitTransaction( const QString& = QString() ); void setExecStatus( const int ); diff --git a/src/SUIT/SUIT_ResourceMgr.h b/src/SUIT/SUIT_ResourceMgr.h index db0eda711..2717de2c4 100755 --- a/src/SUIT/SUIT_ResourceMgr.h +++ b/src/SUIT/SUIT_ResourceMgr.h @@ -26,7 +26,7 @@ class SUIT_EXPORT SUIT_ResourceMgr : public QtxResourceMgr { public: - SUIT_ResourceMgr( const QString&, const QString& = QString::null ); + SUIT_ResourceMgr( const QString&, const QString& = QString() ); virtual ~SUIT_ResourceMgr(); virtual QString version() const; diff --git a/src/SUIT/SUIT_SelectionMgr.cxx b/src/SUIT/SUIT_SelectionMgr.cxx index 21d02eadc..a3f8a8e81 100755 --- a/src/SUIT/SUIT_SelectionMgr.cxx +++ b/src/SUIT/SUIT_SelectionMgr.cxx @@ -148,7 +148,8 @@ void SUIT_SelectionMgr::selectionChanged( SUIT_Selector* sel ) { for ( SelectorList::iterator it = mySelectors.begin(); it != mySelectors.end(); ++it ) { - if ( *it != sel ) + // Temporary action(to avoid selection of the objects which don't pass the filters): + //if ( *it != sel ) (*it)->setSelected( newOwners ); } } diff --git a/src/SUIT/SUIT_SelectionMgr.h b/src/SUIT/SUIT_SelectionMgr.h index 7f3082737..ec2ecb9fa 100755 --- a/src/SUIT/SUIT_SelectionMgr.h +++ b/src/SUIT/SUIT_SelectionMgr.h @@ -40,14 +40,14 @@ public: virtual ~SUIT_SelectionMgr(); void clearSelected(); - virtual void selected( SUIT_DataOwnerPtrList&, const QString& = QString::null ) const; + virtual void selected( SUIT_DataOwnerPtrList&, const QString& = QString() ) const; virtual void setSelected( const SUIT_DataOwnerPtrList&, const bool = false ); void selectors( QList& ) const; void selectors( const QString&, QList& ) const; - void setEnabled( const bool, const QString& = QString::null ); + void setEnabled( const bool, const QString& = QString() ); bool hasSelectionMode( const int ) const; diff --git a/src/SUIT/SUIT_Session.cxx b/src/SUIT/SUIT_Session.cxx index 891c20b8f..6ca03d964 100755 --- a/src/SUIT/SUIT_Session.cxx +++ b/src/SUIT/SUIT_Session.cxx @@ -38,10 +38,11 @@ SUIT_Session* SUIT_Session::mySession = 0; SUIT_Session::SUIT_Session() : QObject(), -myResMgr( 0 ), -myActiveApp( 0 ), -myHandler( 0 ), -myExitStatus( FROM_GUI ) + myResMgr( 0 ), + myActiveApp( 0 ), + myHandler( 0 ), + myExitStatus( NORMAL ), + myExitFlags ( 0 ) { SUIT_ASSERT( !mySession ) @@ -237,7 +238,7 @@ void SUIT_Session::onApplicationClosed( SUIT_Application* theApp ) /*! Destroys session by closing all applications. */ -void SUIT_Session::closeSession( int mode ) +void SUIT_Session::closeSession( int mode, int flags ) { AppList apps = myAppList; for ( AppList::const_iterator it = apps.begin(); it != apps.end(); ++it ) @@ -254,12 +255,27 @@ void SUIT_Session::closeSession( int mode ) } else if ( mode == DONT_SAVE ) { - myExitStatus = FROM_CORBA_SESSION; - //.... + myExitStatus = FORCED; } app->closeApplication(); } + + myExitFlags = flags; +} + +/*! + Get session exit flags. + + By default, exit flags are set to 0. You can use pass any flags to the + closeSession() method if you need to process them later on application + quiting. + + \return exit flags +*/ +int SUIT_Session::exitFlags() const +{ + return myExitFlags; } /*! \retval return myHandler*/ diff --git a/src/SUIT/SUIT_Session.h b/src/SUIT/SUIT_Session.h index f62d697c1..e6ece73e3 100755 --- a/src/SUIT/SUIT_Session.h +++ b/src/SUIT/SUIT_Session.h @@ -56,7 +56,7 @@ public: typedef LIB_HANDLE AppLib; enum { ASK = 0, SAVE, DONT_SAVE } CloseMode; - enum { FROM_GUI = 0, FROM_CORBA_SESSION } ExitStatus; + enum { NORMAL = 0, FORCED } ExitStatus; public: SUIT_Session(); @@ -71,7 +71,8 @@ public: SUIT_ResourceMgr* resourceMgr() const; - void closeSession( int mode = ASK ); + void closeSession( int mode = ASK, int flags = 0 ); + int exitFlags() const; SUIT_ExceptionHandler* handler() const; @@ -106,6 +107,7 @@ private: static SUIT_Session* mySession; int myExitStatus; + int myExitFlags; }; #endif diff --git a/src/SUIT/SUIT_Study.cxx b/src/SUIT/SUIT_Study.cxx index 8fc4f71ce..fec0b6a4f 100755 --- a/src/SUIT/SUIT_Study.cxx +++ b/src/SUIT/SUIT_Study.cxx @@ -198,6 +198,15 @@ void SUIT_Study::setIsModified( const bool on ) myIsModified = on; } +/*! + Set study modified to \a on. + */ +void SUIT_Study::Modified() +{ + setIsModified( true ); + sendChangesNotification(); +} + /*! Set root object. */ @@ -237,8 +246,9 @@ SUIT_Operation* SUIT_Study::blockingOperation( SUIT_Operation* theOp ) const return 0; Operations tmpOps( myOperations ); - for ( Operations::const_iterator it = tmpOps.end(); it != tmpOps.begin(); --it ) + for ( Operations::const_iterator it = tmpOps.end(); it != tmpOps.begin(); ) { + it--; SUIT_Operation* anOp = *it; if ( anOp != 0 && anOp!= theOp && !anOp->isValid( theOp ) ) return anOp; @@ -512,16 +522,8 @@ bool SUIT_Study::hasTransaction() const } /*! - * \brief Stores the study state -*/ -int SUIT_Study::storeState() -{ - return -1; -} - -/*! - * \brief Restores the study state -*/ + * \brief Restores the study state. + */ void SUIT_Study::restoreState(int /*savePoint*/) { } diff --git a/src/SUIT/SUIT_Study.h b/src/SUIT/SUIT_Study.h index 6ebf2bcad..4128bd7fe 100755 --- a/src/SUIT/SUIT_Study.h +++ b/src/SUIT/SUIT_Study.h @@ -48,6 +48,7 @@ public: virtual bool isSaved() const; virtual bool isModified() const; + virtual void Modified(); virtual void closeDocument( bool = true ); virtual bool openDocument( const QString& ); @@ -73,7 +74,6 @@ public: bool suspend( SUIT_Operation* ); bool resume( SUIT_Operation* ); - virtual int storeState(); virtual void restoreState(int savePoint); signals: @@ -85,15 +85,15 @@ protected: 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 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 ); + virtual bool commitTransaction( const QString& = QString() ); private: typedef QList Operations; diff --git a/src/SUIT/SUIT_ViewManager.cxx b/src/SUIT/SUIT_ViewManager.cxx index 61db632b6..34ee0c10c 100755 --- a/src/SUIT/SUIT_ViewManager.cxx +++ b/src/SUIT/SUIT_ViewManager.cxx @@ -165,6 +165,12 @@ SUIT_ViewWindow* SUIT_ViewManager::createViewWindow() return aView; } +/*! Get identifier */ +int SUIT_ViewManager::getId() const +{ + return myId; +} + /*!Create view window.*/ void SUIT_ViewManager::createView() { diff --git a/src/SUIT/SUIT_ViewManager.h b/src/SUIT/SUIT_ViewManager.h index cc6735d07..220c824f5 100755 --- a/src/SUIT/SUIT_ViewManager.h +++ b/src/SUIT/SUIT_ViewManager.h @@ -77,6 +77,8 @@ public: virtual void setShown( const bool ); virtual void setDestructiveClose( const bool ); + int getId() const; + public slots: void createView(); void closeAllViews(); diff --git a/src/SUIT/SUIT_ViewWindow.cxx b/src/SUIT/SUIT_ViewWindow.cxx index 9cde13e92..74d64ae9f 100755 --- a/src/SUIT/SUIT_ViewWindow.cxx +++ b/src/SUIT/SUIT_ViewWindow.cxx @@ -27,17 +27,16 @@ #include "SUIT_MessageBox.h" #include "SUIT_Application.h" #include "SUIT_ViewManager.h" - +#include "QtxActionToolMgr.h" #include "Qtx.h" #include #include #include #include -#include -#include #include - +#include +#include /*!\class SUIT_ViewWindow * Class provide view window. @@ -48,13 +47,15 @@ const int DUMP_EVENT = QEvent::User + 123; /*! Constructor.*/ SUIT_ViewWindow::SUIT_ViewWindow( SUIT_Desktop* theDesktop ) -: QMainWindow( theDesktop ), myManager( 0 ) +: QMainWindow( theDesktop ) { myDesktop = theDesktop; setWindowIcon( myDesktop->windowIcon() ); setAttribute( Qt::WA_DeleteOnClose ); + + myToolMgr = new QtxActionToolMgr( this ); } /*! Destructor.*/ @@ -120,6 +121,97 @@ bool SUIT_ViewWindow::dumpViewToFormat( const QString& fileName, const QString& return dumpViewToFormat( dumpView(), fileName, format ); } +/*! + Prints given image + \param theImage - the image to print +*/ +void SUIT_ViewWindow::printImage( const QImage& theImage, QWidget* theWidget ) +{ + if ( theImage.isNull() ) + return; + +#if !defined(WIN32) && !defined(QT_NO_CUPS) +#if QT_VERSION < 0x040303 + if ( !Qtx::hasAnyPrinters() ) { + SUIT_MessageBox::warning( this, tr( "WRN_WARNING" ), + tr( "WRN_NO_PRINTERS" ) ); + return; + } +#endif +#endif + + // stored settings for further starts + static QString aPrinterName; + static int anOrientation = -1; + + QPrinter aPrinter; + + // restore settinds from previous launching + + // printer name + if ( !aPrinterName.isEmpty() ) + aPrinter.setPrinterName( aPrinterName ); + else + { + // Nothing to do for the first printing. aPrinter contains default printer name by default + } + + if ( anOrientation >= 0 ) + aPrinter.setOrientation( (QPrinter::Orientation)anOrientation ); + else + aPrinter.setOrientation( QPrinter::Landscape ); + + + QPrintDialog printDlg( &aPrinter, theWidget ); + printDlg.setPrintRange( QAbstractPrintDialog::AllPages ); + if ( printDlg.exec() != QDialog::Accepted ) + return; + + // store printer settings for further starts + aPrinterName = aPrinter.printerName(); + anOrientation = aPrinter.orientation(); + + int W, H; + QPainter aPainter; + + // work arround for printing on real printer + if ( aPrinter.outputFileName().isEmpty() && aPrinter.orientation() == QPrinter::Landscape ) + { + aPrinter.setFullPage( true ); + // set paper orientation and rotate painter + aPrinter.setOrientation( QPrinter::Portrait ); + + W = aPrinter.height(); + H = aPrinter.width(); + + int wBorder = aPrinter.paperRect().height() - W; + int hBorder = aPrinter.paperRect().width() - H; + + aPainter.begin( &aPrinter ); + aPainter.translate( QPoint( H + hBorder, wBorder ) ); + aPainter.rotate( 90 ); + } + else + { + aPrinter.setFullPage( false ); + aPainter.begin( &aPrinter ); + W = aPrinter.width(); + H = aPrinter.height(); + } + + QImage anImage = theImage; + if ( anImage.width() > W || anImage.height() > H ) + anImage = anImage.scaled( W, H, Qt::KeepAspectRatio, Qt::SmoothTransformation ); + + // place image in the center of page + int offsetW = ( W - anImage.width() ) / 2; + int offsetH = ( H - anImage.height() ) / 2; + + aPainter.drawImage( offsetW, offsetH, anImage ); + + aPainter.end(); +} + /*! Set or clear flag Qt::WDestructiveClose */ @@ -138,8 +230,15 @@ void SUIT_ViewWindow::closeEvent( QCloseEvent* e ) /*! Context menu requested for event \a e. */ -void SUIT_ViewWindow::contextMenuEvent ( QContextMenuEvent * e ) +void SUIT_ViewWindow::contextMenuEvent( QContextMenuEvent* e ) { + e->ignore(); + + QMainWindow::contextMenuEvent( e ); + + if ( e->isAccepted() ) + return; + if ( e->reason() != QContextMenuEvent::Mouse ) emit contextMenuRequested( e ); } @@ -173,7 +272,7 @@ bool SUIT_ViewWindow::event( QEvent* e ) // get file name SUIT_Application* app = myManager->study()->application(); - QString fileName = app->getFileName( false, QString::null, filter(), tr( "TLT_DUMP_VIEW" ), 0 ); + QString fileName = app->getFileName( false, QString(), filter(), tr( "TLT_DUMP_VIEW" ), 0 ); if ( !fileName.isEmpty() ) { QString fmt = SUIT_Tools::extension( fileName ).toUpper(); @@ -221,92 +320,9 @@ void SUIT_ViewWindow::setVisualParameters( const QString& /*parameters*/ ) } /*! - Prints given image - \param theImage - the image to print + \return associated tool bar manager */ -void SUIT_ViewWindow::printImage( const QImage& theImage, QWidget* theWidget ) +QtxActionToolMgr* SUIT_ViewWindow::toolMgr() const { - if ( theImage.isNull() ) - return; - -#ifndef WIN32 -#if QT_VERSION < 0x040303 - if ( !Qtx::hasAnyPrinters() ) { - SUIT_MessageBox::warning( this, tr( "WRN_WARNING" ), - tr( "WRN_NO_PRINTERS" ) ); - return; - } -#endif -#endif - - // stored settings for further starts - static QString aPrinterName; - static int anOrientation = -1; - - QPrinter aPrinter; - - // restore settinds from previous launching - - // printer name - if ( !aPrinterName.isEmpty() ) - aPrinter.setPrinterName( aPrinterName ); - else - { - // Nothing to do for the first printing. aPrinter contains default printer name by default - } - - if ( anOrientation >= 0 ) - aPrinter.setOrientation( (QPrinter::Orientation)anOrientation ); - else - aPrinter.setOrientation( QPrinter::Landscape ); - - - QPrintDialog printDlg( &aPrinter, theWidget ); - printDlg.setPrintRange( QAbstractPrintDialog::AllPages ); - if ( printDlg.exec() != QDialog::Accepted ) - return; - - // store printer settings for further starts - aPrinterName = aPrinter.printerName(); - anOrientation = aPrinter.orientation(); - - int W, H; - QPainter aPainter; - - // work arround for printing on real printer - if ( aPrinter.outputFileName().isEmpty() && aPrinter.orientation() == QPrinter::Landscape ) - { - aPrinter.setFullPage( true ); - // set paper orientation and rotate painter - aPrinter.setOrientation( QPrinter::Portrait ); - - W = aPrinter.height(); - H = aPrinter.width(); - - int wBorder = aPrinter.paperRect().height() - W; - int hBorder = aPrinter.paperRect().width() - H; - - aPainter.begin( &aPrinter ); - aPainter.translate( QPoint( H + hBorder, wBorder ) ); - aPainter.rotate( 90 ); - } - else - { - aPrinter.setFullPage( false ); - aPainter.begin( &aPrinter ); - W = aPrinter.width(); - H = aPrinter.height(); - } - - QImage anImage = theImage; - if ( anImage.width() > W || anImage.height() > H ) - anImage = anImage.scaled( W, H, Qt::KeepAspectRatio, Qt::SmoothTransformation ); - - // place image in the center of page - int offsetW = ( W - anImage.width() ) / 2; - int offsetH = ( H - anImage.height() ) / 2; - - aPainter.drawImage( offsetW, offsetH, anImage ); - - aPainter.end(); + return myToolMgr; } diff --git a/src/SUIT/SUIT_ViewWindow.h b/src/SUIT/SUIT_ViewWindow.h index 944c9d5fa..1f853454c 100755 --- a/src/SUIT/SUIT_ViewWindow.h +++ b/src/SUIT/SUIT_ViewWindow.h @@ -25,10 +25,11 @@ #include "SUIT.h" #include -#include class SUIT_Desktop; class SUIT_ViewManager; +class QtxActionToolMgr; +class QImage; class SUIT_EXPORT SUIT_ViewWindow: public QMainWindow { @@ -53,6 +54,8 @@ public: void setDestructiveClose( const bool ); + QtxActionToolMgr* toolMgr() const; + public slots: virtual void onDumpView(); @@ -76,6 +79,9 @@ protected: SUIT_Desktop* myDesktop; SUIT_ViewManager* myManager; + +private: + QtxActionToolMgr* myToolMgr; }; #endif // !defined(AFX_SUIT_VIEWWINDOW_H__82C3D51A_6F10_45B0_BCFE_3CB3EF596A4D__INCLUDED_) diff --git a/src/SUIT/resources/cascade.png b/src/SUIT/resources/cascade.png deleted file mode 100755 index 9cd171538d3bf91cd2f2d4a9c9bff8806cf0da07..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 225 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!9%)r1XI!iqT$l(d_32{Ae-~arKTriH9nmt<-R&!UUhjd$-o|AfbHSH@gbvuNE7UK3u)$`nbw{wZ9^U{E4d?lo_c QCD42ZPgg&ebxsLQ05eNRGXMYp diff --git a/src/SUIT/resources/htile.png b/src/SUIT/resources/htile.png deleted file mode 100755 index b838286fb446498c73441a44cd808ff804fbd891..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 871 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPL>W(e>JasB`QKLbMxQ1HNk13;1} zAc;fO1E9D9LnlK{dnXPRLt9uA==>RsoeW%)eeik&6h1LPoB+frK)e8mL4cEyfgz(L zGbdHg-O~*e;KTu7>=20{<^dH0W0fEPDx;fvRQKNmB})cIhHxuTC=Dz)F)Ma2&;?4K zE{-7;w~`IonAj{12MF-ANb*P~^6cPXmPkkqSjL@Z&5)hV^*mGL_ZN_RJzf1=);T3K F0RWU&)(8Lq diff --git a/src/SUIT/resources/vtile.png b/src/SUIT/resources/vtile.png deleted file mode 100755 index 1965d6405cedd52e95726e3968d6d978418855d4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 876 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPL>W(e>JasB`QKLbMxQ1HNk13;1} zAc;fO1E9D9LnlK{dnXPRLt9uA==>RsoeW%)eeik&6h1LPoB+frKwJaFAi&AUz))6_ znUkuQo|y&;aN+IEGZ*N;YU?Vsmyh5J)pf5fKq#Fn*xK!_&jW!?Pvfz?ue2W`^~%IHk5sn34-} Nw5O||%Q~loCIEJ_)DQpw diff --git a/src/SUITApp/SUITApp.cxx b/src/SUITApp/SUITApp.cxx index 81bab394b..3e0f483d6 100644 --- a/src/SUITApp/SUITApp.cxx +++ b/src/SUITApp/SUITApp.cxx @@ -186,12 +186,12 @@ int main( int args, char* argv[] ) { SUITApp_Session* aSession = new SUITApp_Session( iniFormat ); QtxSplash* splash = 0; + SUIT_ResourceMgr* resMgr = aSession->createResourceMgr( argList.first() ); if ( !noSplash ) { - SUIT_ResourceMgr* resMgr = aSession->createResourceMgr( argList.first() ); if ( resMgr ) { - resMgr->loadLanguage(); + resMgr->loadLanguage( false ); splash = QtxSplash::splash( QPixmap() ); splash->readSettings( resMgr ); @@ -222,9 +222,12 @@ int main( int args, char* argv[] ) SUIT_Application* theApp = aSession->startApplication( argList.first() ); if ( theApp ) { - Style_Salome* aStyle = new Style_Salome(); - aStyle->getModel()->initFromResource( theApp->resourceMgr() ); - app.setStyle( aStyle ); + if ( resMgr && resMgr->booleanValue( "Style", "use_salome_style", true ) ) + { + Style_Salome* aStyle = new Style_Salome(); + aStyle->getModel()->initFromResource( theApp->resourceMgr() ); + app.setStyle( aStyle ); + } if ( !noExceptHandling ) app.setHandler( aSession->handler() ); diff --git a/src/SUITApp/resources/SUITApp_msg_en.ts b/src/SUITApp/resources/SUITApp_msg_en.ts new file mode 100644 index 000000000..20b003ece --- /dev/null +++ b/src/SUITApp/resources/SUITApp_msg_en.ts @@ -0,0 +1,17 @@ + + + @default + + APP_OK + Ok + + + APP_ERROR + Error + + + APP_UNK_EXCEPTION + Unknown exception + + + diff --git a/src/SVTK/SVTK_CubeAxesDlg.h b/src/SVTK/SVTK_CubeAxesDlg.h index f573f94b1..dc47654fe 100644 --- a/src/SVTK/SVTK_CubeAxesDlg.h +++ b/src/SVTK/SVTK_CubeAxesDlg.h @@ -27,7 +27,6 @@ #ifndef SVTK_CubeAxesDlg_H #define SVTK_CubeAxesDlg_H -#include "SVTK.h" #include "SVTK_DialogBase.h" #include @@ -53,7 +52,7 @@ class SVTK_MainWindow; * Class : SVTK_CubeAxesDlg * Description : Dialog for specifynig cube axes properties */ -class SVTK_EXPORT SVTK_CubeAxesDlg : public SVTK_DialogBase +class SVTK_CubeAxesDlg : public SVTK_DialogBase { Q_OBJECT diff --git a/src/SVTK/SVTK_InteractorStyle.cxx b/src/SVTK/SVTK_InteractorStyle.cxx index e9032bdcd..6c8d32111 100644 --- a/src/SVTK/SVTK_InteractorStyle.cxx +++ b/src/SVTK/SVTK_InteractorStyle.cxx @@ -49,7 +49,6 @@ #include #include #include -#include #include #include #include @@ -79,38 +78,18 @@ namespace theInteractor->GetEventPosition(theX,theY); theY = theInteractor->GetSize()[1] - theY - 1; } - - //================================================================== - // function : GetFirstSALOMEActor - // purpose : - //================================================================== - struct THaveIO - { - bool - operator()(SALOME_Actor* theActor) - { - return theActor->hasIO(); - } - }; - - inline - SALOME_Actor* - GetFirstSALOMEActor(vtkPicker *thePicker) - { - return VTK::Find(thePicker->GetActors(),THaveIO()); - } } vtkStandardNewMacro(SVTK_InteractorStyle); + /*! Constructor */ SVTK_InteractorStyle ::SVTK_InteractorStyle(): mySelectionEvent(new SVTK_SelectionEvent()), - myPicker(vtkPicker::New()), myPointPicker(vtkPointPicker::New()), myLastHighlitedActor(NULL), myLastPreHighlitedActor(NULL), @@ -119,7 +98,6 @@ SVTK_InteractorStyle myHighlightRotationPointActor(SVTK_Actor::New()), myRectBand(0) { - myPicker->Delete(); myPointPicker->Delete(); myPointPicker->SetTolerance(0.025); @@ -514,11 +492,10 @@ SVTK_InteractorStyle else if ( myCurrRotationPointType == SVTK::StartPointSelection ) { SVTK_SelectionEvent* aSelectionEvent = GetSelectionEventFlipY(); - myPicker->Pick(aSelectionEvent->myX, - aSelectionEvent->myY, - 0.0, - GetCurrentRenderer()); - if ( SALOME_Actor* anActor = GetFirstSALOMEActor(myPicker.GetPointer()) ) + + SALOME_Actor* anActor = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer()); + + if ( anActor ) { myPointPicker->Pick( aSelectionEvent->myX, aSelectionEvent->myY, @@ -1090,12 +1067,8 @@ SVTK_InteractorStyle this->FindPokedRenderer(aSelectionEvent->myX, aSelectionEvent->myY); Interactor->StartPickCallback(); - myPicker->Pick(aSelectionEvent->myX, - aSelectionEvent->myY, - 0.0, - GetCurrentRenderer()); - // - SALOME_Actor* anActor = GetFirstSALOMEActor(myPicker.GetPointer()); + SALOME_Actor* anActor = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer()); + aSelectionEvent->myIsRectangle = false; if(!myShiftState) @@ -1228,24 +1201,13 @@ SVTK_InteractorStyle bool anIsChanged = false; - myPicker->Pick(aSelectionEvent->myX, - aSelectionEvent->myY, - 0.0, - GetCurrentRenderer()); - - SALOME_Actor *anActor = GetFirstSALOMEActor(myPicker.GetPointer()); + SALOME_Actor *anActor = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer()); if ( myCurrRotationPointType == SVTK::StartPointSelection ) { myHighlightRotationPointActor->SetVisibility( false ); - SALOME_Actor *anCurrActor; - if ( anActor ) anCurrActor = anActor; - else if ( myLastPreHighlitedActor.GetPointer() - && - myLastPreHighlitedActor.GetPointer() != anActor ) - anCurrActor = myLastPreHighlitedActor.GetPointer(); - if ( anCurrActor ) + if ( anActor ) { myPointPicker->Pick( aSelectionEvent->myX, aSelectionEvent->myY, 0.0, GetCurrentRenderer() ); int aVtkId = myPointPicker->GetPointId(); diff --git a/src/SVTK/SVTK_InteractorStyle.h b/src/SVTK/SVTK_InteractorStyle.h index 60dbf4fe6..b02941bfb 100644 --- a/src/SVTK/SVTK_InteractorStyle.h +++ b/src/SVTK/SVTK_InteractorStyle.h @@ -102,7 +102,6 @@ class SVTK_EXPORT SVTK_ControllerOnKeyDown : public vtkObject{ void operator=(const SVTK_ControllerOnKeyDown&); //Not implemented }; -class vtkPicker; class vtkPointPicker; class SALOME_Actor; @@ -334,8 +333,6 @@ class SVTK_EXPORT SVTK_InteractorStyle: public vtkInteractorStyle PSelectionEvent mySelectionEvent; - vtkSmartPointer myPicker; - unsigned long myCurrRotationPointType; unsigned long myPrevRotationPointType; diff --git a/src/SVTK/SVTK_MainWindow.cxx b/src/SVTK/SVTK_MainWindow.cxx index 9e981c928..2dfd255c5 100644 --- a/src/SVTK/SVTK_MainWindow.cxx +++ b/src/SVTK/SVTK_MainWindow.cxx @@ -29,12 +29,14 @@ #include "SALOME_Actor.h" #include -#include -#include + +#include +#include #include #include #include +#include #include #include @@ -45,9 +47,7 @@ #include "SVTK_UpdateRateDlg.h" #include "SVTK_CubeAxesDlg.h" #include "SVTK_SetRotationPointDlg.h" - #include "SVTK_TextRegionDlg.h" - #include "SVTK_MainWindow.h" #include "SVTK_Event.h" #include "SVTK_Renderer.h" @@ -72,7 +72,7 @@ SVTK_MainWindow setObjectName(theName); setWindowFlags( windowFlags() & ~Qt::Window ); - myToolBar = new QtxToolBar( true, tr("LBL_TOOLBAR_LABEL"), this ); + myToolBar = myViewWindow->toolMgr()->createToolBar( tr("LBL_TOOLBAR_LABEL"), -1, this ); createActions(theResourceMgr); createToolBar(); @@ -95,11 +95,12 @@ SVTK_MainWindow myInteractor->setFocus(); setFocusProxy(myInteractor); - myUpdateRateDlg = new SVTK_UpdateRateDlg(myActionsMap[UpdateRate], this, "SVTK_UpdateRateDlg"); - myNonIsometricDlg = new SVTK_NonIsometricDlg(myActionsMap[NonIsometric], this," SVTK_NonIsometricDlg"); - myCubeAxesDlg = new SVTK_CubeAxesDlg(myActionsMap[GraduatedAxes], this, "SVTK_CubeAxesDlg"); - mySetRotationPointDlg = new SVTK_SetRotationPointDlg(myActionsMap[ChangeRotationPointId], this, "SVTK_SetRotationPointDlg"); - myTextRegionDlg = new SVTK_TextRegionDlg(myActionsMap[TextRegion], this, "SVTK_TextRegionDlg"); + myUpdateRateDlg = new SVTK_UpdateRateDlg( action( UpdateRate ), this, "SVTK_UpdateRateDlg" ); + myNonIsometricDlg = new SVTK_NonIsometricDlg( action( NonIsometric ), this, "SVTK_NonIsometricDlg" ); + myCubeAxesDlg = new SVTK_CubeAxesDlg( action( GraduatedAxes ), this, "SVTK_CubeAxesDlg" ); + mySetRotationPointDlg = new SVTK_SetRotationPointDlg + ( action( ChangeRotationPointId ), this, "SVTK_SetRotationPointDlg" ); + myTextRegionDlg = new SVTK_TextRegionDlg( action( TextRegion ), this, "SVTK_TextRegionDlg"); } @@ -402,7 +403,7 @@ QToolBar* SVTK_MainWindow ::getToolBar() { - return myToolBar; + return myViewWindow->toolMgr()->toolBar( myToolBar ); } void @@ -423,10 +424,8 @@ void SVTK_MainWindow ::createActions(SUIT_ResourceMgr* theResourceMgr) { - if(!myActionsMap.isEmpty()) - return; - QtxAction* anAction; + QtxActionToolMgr* mgr = myViewWindow->toolMgr(); // Dump view anAction = new QtxAction(tr("MNU_DUMP_VIEW"), @@ -434,7 +433,7 @@ SVTK_MainWindow tr( "MNU_DUMP_VIEW" ), 0, this); anAction->setStatusTip(tr("DSC_DUMP_VIEW")); connect(anAction, SIGNAL(triggered(bool)), myViewWindow, SLOT(onDumpView())); - myActionsMap[ DumpId ] = anAction; + mgr->registerAction( anAction, DumpId ); // FitAll anAction = new QtxAction(tr("MNU_FITALL"), @@ -442,7 +441,7 @@ SVTK_MainWindow tr( "MNU_FITALL" ), 0, this); anAction->setStatusTip(tr("DSC_FITALL")); connect(anAction, SIGNAL(triggered(bool)), this, SLOT(onFitAll())); - myActionsMap[ FitAllId ] = anAction; + mgr->registerAction( anAction, FitAllId ); // FitRect anAction = new QtxAction(tr("MNU_FITRECT"), @@ -450,7 +449,7 @@ SVTK_MainWindow tr( "MNU_FITRECT" ), 0, this); anAction->setStatusTip(tr("DSC_FITRECT")); connect(anAction, SIGNAL(triggered(bool)), this, SLOT(activateWindowFit())); - myActionsMap[ FitRectId ] = anAction; + mgr->registerAction( anAction, FitRectId ); // Zoom anAction = new QtxAction(tr("MNU_ZOOM_VIEW"), @@ -458,7 +457,7 @@ SVTK_MainWindow tr( "MNU_ZOOM_VIEW" ), 0, this); anAction->setStatusTip(tr("DSC_ZOOM_VIEW")); connect(anAction, SIGNAL(triggered(bool)), this, SLOT(activateZoom())); - myActionsMap[ ZoomId ] = anAction; + mgr->registerAction( anAction, ZoomId ); // Panning anAction = new QtxAction(tr("MNU_PAN_VIEW"), @@ -466,7 +465,7 @@ SVTK_MainWindow tr( "MNU_PAN_VIEW" ), 0, this); anAction->setStatusTip(tr("DSC_PAN_VIEW")); connect(anAction, SIGNAL(triggered(bool)), this, SLOT(activatePanning())); - myActionsMap[ PanId ] = anAction; + mgr->registerAction( anAction, PanId ); // Global Panning anAction = new QtxAction(tr("MNU_GLOBALPAN_VIEW"), @@ -474,16 +473,16 @@ SVTK_MainWindow tr( "MNU_GLOBALPAN_VIEW" ), 0, this); anAction->setStatusTip(tr("DSC_GLOBALPAN_VIEW")); connect(anAction, SIGNAL(triggered(bool)), this, SLOT(activateGlobalPanning())); - myActionsMap[ GlobalPanId ] = anAction; + mgr->registerAction( anAction, GlobalPanId ); // Change rotation point anAction = new QtxAction(tr("MNU_CHANGINGROTATIONPOINT_VIEW"), - theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_ROTATION_POINT" ) ), + theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_SVTK_ROTATION_POINT" ) ), tr( "MNU_CHANGINGROTATIONPOINT_VIEW" ), 0, this); anAction->setStatusTip(tr("DSC_CHANGINGROTATIONPOINT_VIEW")); anAction->setCheckable(true); connect(anAction, SIGNAL(toggled(bool)), this, SLOT(onChangeRotationPoint(bool))); - myActionsMap[ ChangeRotationPointId ] = anAction; + mgr->registerAction( anAction, ChangeRotationPointId ); // Rotation anAction = new QtxAction(tr("MNU_ROTATE_VIEW"), @@ -491,7 +490,7 @@ SVTK_MainWindow tr( "MNU_ROTATE_VIEW" ), 0, this); anAction->setStatusTip(tr("DSC_ROTATE_VIEW")); connect(anAction, SIGNAL(triggered(bool)), this, SLOT(activateRotation())); - myActionsMap[ RotationId ] = anAction; + mgr->registerAction( anAction, RotationId ); // Projections anAction = new QtxAction(tr("MNU_FRONT_VIEW"), @@ -499,42 +498,42 @@ SVTK_MainWindow tr( "MNU_FRONT_VIEW" ), 0, this); anAction->setStatusTip(tr("DSC_FRONT_VIEW")); connect(anAction, SIGNAL(triggered(bool)), this, SLOT(onFrontView())); - myActionsMap[ FrontId ] = anAction; + mgr->registerAction( anAction, FrontId ); anAction = new QtxAction(tr("MNU_BACK_VIEW"), theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_BACK" ) ), tr( "MNU_BACK_VIEW" ), 0, this); anAction->setStatusTip(tr("DSC_BACK_VIEW")); connect(anAction, SIGNAL(triggered(bool)), this, SLOT(onBackView())); - myActionsMap[ BackId ] = anAction; + mgr->registerAction( anAction, BackId ); anAction = new QtxAction(tr("MNU_TOP_VIEW"), theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_TOP" ) ), tr( "MNU_TOP_VIEW" ), 0, this); anAction->setStatusTip(tr("DSC_TOP_VIEW")); connect(anAction, SIGNAL(triggered(bool)), this, SLOT(onTopView())); - myActionsMap[ TopId ] = anAction; + mgr->registerAction( anAction, TopId ); anAction = new QtxAction(tr("MNU_BOTTOM_VIEW"), theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_BOTTOM" ) ), tr( "MNU_BOTTOM_VIEW" ), 0, this); anAction->setStatusTip(tr("DSC_BOTTOM_VIEW")); connect(anAction, SIGNAL(triggered(bool)), this, SLOT(onBottomView())); - myActionsMap[ BottomId ] = anAction; + mgr->registerAction( anAction, BottomId ); anAction = new QtxAction(tr("MNU_LEFT_VIEW"), theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_LEFT" ) ), tr( "MNU_LEFT_VIEW" ), 0, this); anAction->setStatusTip(tr("DSC_LEFT_VIEW")); connect(anAction, SIGNAL(triggered(bool)), this, SLOT(onLeftView())); - myActionsMap[ LeftId ] = anAction; + mgr->registerAction( anAction, LeftId ); anAction = new QtxAction(tr("MNU_RIGHT_VIEW"), theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_RIGHT" ) ), tr( "MNU_RIGHT_VIEW" ), 0, this); anAction->setStatusTip(tr("DSC_RIGHT_VIEW")); connect(anAction, SIGNAL(triggered(bool)), this, SLOT(onRightView())); - myActionsMap[ RightId ] = anAction; + mgr->registerAction( anAction, RightId ); // Reset anAction = new QtxAction(tr("MNU_RESET_VIEW"), @@ -542,7 +541,7 @@ SVTK_MainWindow tr( "MNU_RESET_VIEW" ), 0, this); anAction->setStatusTip(tr("DSC_RESET_VIEW")); connect(anAction, SIGNAL(triggered(bool)), this, SLOT(onResetView())); - myActionsMap[ ResetId ] = anAction; + mgr->registerAction( anAction, ResetId ); // onViewTrihedron: Shows - Hides Trihedron anAction = new QtxAction(tr("MNU_SHOW_TRIHEDRON"), @@ -550,7 +549,7 @@ SVTK_MainWindow tr( "MNU_SHOW_TRIHEDRON" ), 0, this); anAction->setStatusTip(tr("DSC_SHOW_TRIHEDRON")); connect(anAction, SIGNAL(triggered(bool)), this, SLOT(onViewTrihedron())); - myActionsMap[ ViewTrihedronId ] = anAction; + mgr->registerAction( anAction, ViewTrihedronId ); // onNonIsometric: Manage non-isometric params anAction = new QtxAction(tr("MNU_SVTK_SCALING"), @@ -559,25 +558,25 @@ SVTK_MainWindow anAction->setStatusTip(tr("DSC_SVTK_SCALING")); anAction->setCheckable(true); connect(anAction, SIGNAL(toggled(bool)), this, SLOT(onNonIsometric(bool))); - myActionsMap[ NonIsometric ] = anAction; + mgr->registerAction( anAction, NonIsometric ); // onGraduatedAxes: Manage graduated axes params anAction = new QtxAction(tr("MNU_SVTK_GRADUATED_AXES"), - theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_GRADUATED_AXES" ) ), + theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_SVTK_GRADUATED_AXES" ) ), tr( "MNU_SVTK_GRADUATED_AXES" ), 0, this); anAction->setStatusTip(tr("DSC_SVTK_GRADUATED_AXES")); anAction->setCheckable(true); connect(anAction, SIGNAL(toggled(bool)), this, SLOT(onGraduatedAxes(bool))); - myActionsMap[ GraduatedAxes ] = anAction; + mgr->registerAction( anAction, GraduatedAxes ); // onGraduatedAxes: Manage graduated axes params anAction = new QtxAction(tr("MNU_SVTK_UPDATE_RATE"), - theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_UPDATE_RATE" ) ), + theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_SVTK_UPDATE_RATE" ) ), tr( "MNU_SVTK_UPDATE_RATE" ), 0, this); anAction->setStatusTip(tr("DSC_SVTK_UPDATE_RATE")); anAction->setCheckable(true); connect(anAction, SIGNAL(toggled(bool)), this, SLOT(onUpdateRate(bool))); - myActionsMap[ UpdateRate ] = anAction; + mgr->registerAction( anAction, UpdateRate ); // onTextRegion: Create Text Region anAction = new QtxAction(tr("MNU_SVTK_TEXT_REGION"), @@ -585,7 +584,7 @@ SVTK_MainWindow tr( "MNU_SVTK_TEXT_REGION" ), 0, this); anAction->setStatusTip(tr("DSC_SVTK_TEXT_REGION")); connect(anAction, SIGNAL(triggered(bool)), this, SLOT(onTextRegion())); - myActionsMap[ TextRegion ] = anAction; + mgr->registerAction( anAction, TextRegion ); // print view anAction = new QtxAction(tr("MNU_PRINT_VIEW"), @@ -593,7 +592,7 @@ SVTK_MainWindow tr( "MNU_PRINT_VIEW" ), 0, this); anAction->setStatusTip(tr("DSC_PRINT_VIEW")); connect(anAction, SIGNAL(triggered(bool)), this, SLOT(onPrintView())); - myActionsMap[ PrintId ] = anAction; + mgr->registerAction( anAction, PrintId ); } #if defined(WIN32) && !defined(_DEBUG) @@ -607,40 +606,42 @@ void SVTK_MainWindow ::createToolBar() { - myToolBar->addAction( myActionsMap[DumpId] ); - myToolBar->addAction( myActionsMap[ViewTrihedronId] ); + QtxActionToolMgr* mgr = myViewWindow->toolMgr(); + + mgr->append( DumpId, myToolBar ); + mgr->append( ViewTrihedronId, myToolBar ); QtxMultiAction* aScaleAction = new QtxMultiAction( this ); - aScaleAction->insertAction( myActionsMap[FitAllId] ); - aScaleAction->insertAction( myActionsMap[FitRectId] ); - aScaleAction->insertAction( myActionsMap[ZoomId] ); - myToolBar->addAction( aScaleAction ); + aScaleAction->insertAction( action( FitAllId ) ); + aScaleAction->insertAction( action( FitRectId ) ); + aScaleAction->insertAction( action( ZoomId ) ); + mgr->append( aScaleAction, myToolBar ); QtxMultiAction* aPanningAction = new QtxMultiAction( this ); - aPanningAction->insertAction( myActionsMap[PanId] ); - aPanningAction->insertAction( myActionsMap[GlobalPanId] ); - myToolBar->addAction( aPanningAction ); + aPanningAction->insertAction( action( PanId ) ); + aPanningAction->insertAction( action( GlobalPanId ) ); + mgr->append( aPanningAction, myToolBar ); - myToolBar->addAction( myActionsMap[ChangeRotationPointId] ); + mgr->append( ChangeRotationPointId, myToolBar ); - myToolBar->addAction( myActionsMap[RotationId] ); + mgr->append( RotationId, myToolBar ); QtxMultiAction* aViewsAction = new QtxMultiAction( this ); - aViewsAction->insertAction( myActionsMap[FrontId] ); - aViewsAction->insertAction( myActionsMap[BackId] ); - aViewsAction->insertAction( myActionsMap[TopId] ); - aViewsAction->insertAction( myActionsMap[BottomId] ); - aViewsAction->insertAction( myActionsMap[LeftId] ); - aViewsAction->insertAction( myActionsMap[RightId] ); - myToolBar->addAction( aViewsAction ); + aViewsAction->insertAction( action( FrontId ) ); + aViewsAction->insertAction( action( BackId ) ); + aViewsAction->insertAction( action( TopId ) ); + aViewsAction->insertAction( action( BottomId ) ); + aViewsAction->insertAction( action( LeftId ) ); + aViewsAction->insertAction( action( RightId ) ); + mgr->append( aViewsAction, myToolBar ); - myToolBar->addAction( myActionsMap[ResetId] ); + mgr->append( ResetId, myToolBar ); - myToolBar->addAction( myActionsMap[UpdateRate] ); - myToolBar->addAction( myActionsMap[NonIsometric] ); - myToolBar->addAction( myActionsMap[GraduatedAxes] ); - myToolBar->addAction( myActionsMap[TextRegion] ); - myToolBar->addAction( myActionsMap[PrintId] ); + mgr->append( UpdateRate, myToolBar ); + mgr->append( NonIsometric, myToolBar ); + mgr->append( GraduatedAxes, myToolBar ); + mgr->append( TextRegion, myToolBar ); + mgr->append( PrintId, myToolBar ); } /*! @@ -934,6 +935,14 @@ SVTK_MainWindow return px.toImage(); } +/*! + \return action by it's id +*/ +QtxAction* SVTK_MainWindow::action( int id ) const +{ + return dynamic_cast( myViewWindow->toolMgr()->action( id ) ); +} + /*! \brief Called when the "Print view" action is activated. */ diff --git a/src/SVTK/SVTK_MainWindow.h b/src/SVTK/SVTK_MainWindow.h index 95503a88e..b15383eb9 100644 --- a/src/SVTK/SVTK_MainWindow.h +++ b/src/SVTK/SVTK_MainWindow.h @@ -26,12 +26,10 @@ #include "SVTK.h" #include "SVTK_Selection.h" -#include - #include #include -class QtxAction; +#include class vtkObject; class vtkRenderer; @@ -39,6 +37,8 @@ class vtkRenderWindow; class vtkInteractorStyle; class vtkRenderWindowInteractor; +class QtxAction; + class SUIT_ResourceMgr; class SUIT_ViewWindow; @@ -49,13 +49,11 @@ class SVTK_CubeAxesActor2D; class SVTK_CubeAxesDlg; class SVTK_SetRotationPointDlg; class SVTK_TextRegionDlg; - -class VTKViewer_Trihedron; -class VTKViewer_Actor; - class SVTK_Renderer; class SVTK_Selector; +class VTKViewer_Trihedron; +class VTKViewer_Actor; //! The class is a container for #SVTK_RenderWindowInteractor. /*! @@ -252,12 +250,13 @@ public: void SetEventDispatcher(vtkObject* theDispatcher); + QtxAction* action( int ) const; + enum { DumpId, FitAllId, FitRectId, ZoomId, PanId, GlobalPanId, ChangeRotationPointId, RotationId, FrontId, BackId, TopId, BottomId, LeftId, RightId, ResetId, ViewTrihedronId, NonIsometric, GraduatedAxes, UpdateRate, TextRegion, PrintId }; - typedef QMap TActionsMap; SUIT_ViewWindow* myViewWindow; @@ -268,8 +267,7 @@ public: SVTK_TextRegionDlg* myTextRegionDlg; vtkSmartPointer myEventDispatcher; - TActionsMap myActionsMap; - QToolBar* myToolBar; + int myToolBar; SVTK_RenderWindowInteractor* myInteractor; }; diff --git a/src/SVTK/SVTK_RectPicker.cxx b/src/SVTK/SVTK_RectPicker.cxx index 9aaad409e..fb5ced7f2 100644 --- a/src/SVTK/SVTK_RectPicker.cxx +++ b/src/SVTK/SVTK_RectPicker.cxx @@ -115,22 +115,29 @@ namespace // WorldToView() is called. This is expensive, so we get the matrix once // and handle the transformation ourselves. vtkMatrix4x4 *aMatrix = vtkMatrix4x4::New(); - aMatrix->DeepCopy(theRenderer->GetActiveCamera()-> - GetCompositePerspectiveTransformMatrix(1,0,1)); + aMatrix->DeepCopy( theRenderer->GetActiveCamera()-> + GetCompositePerspectiveTransformMatrix( theRenderer->GetTiledAspectRatio(), 0, 1 ) ); // We grab the z-buffer for the selection region all at once and probe the resulting array. float *aZPtr = theRenderer->GetRenderWindow()-> GetZbufferData(theSelection[0], theSelection[1], theSelection[2], theSelection[3]); //cout<<"theSelection = {"<Delete(); myTransform->Delete(); - SetSelectionTolerance(); - myPointPicker->Delete(); myCellPicker->Delete(); @@ -225,6 +223,7 @@ SVTK_Renderer { myInteractor = theInteractor; mySelector = theSelector; + SetSelectionTolerance(); } /*! @@ -348,13 +347,16 @@ SVTK_Renderer void SVTK_Renderer ::SetSelectionTolerance(const double& theTolNodes, - const double& theTolCell) + const double& theTolCell, + const double& theTolObjects) { myPointPicker->SetTolerance( theTolNodes ); myCellPicker->SetTolerance( theTolCell ); myPointRectPicker->SetTolerance( theTolNodes ); myCellRectPicker->SetTolerance( theTolCell ); + + mySelector->SetTolerance( theTolObjects ); } diff --git a/src/SVTK/SVTK_Renderer.h b/src/SVTK/SVTK_Renderer.h index 3e44d5fe4..5c24cefa1 100644 --- a/src/SVTK/SVTK_Renderer.h +++ b/src/SVTK/SVTK_Renderer.h @@ -122,7 +122,8 @@ class SVTK_EXPORT SVTK_Renderer : public vtkObject //! Setup requested tolerance for the picking void SetSelectionTolerance(const double& theTolNodes = 0.025, - const double& theTolCell = 0.001); + const double& theTolCell = 0.001, + const double& theTolObjects = 0.025); //---------------------------------------------------------------------------- //! Adjust all intenal actors (trihedron and graduated rules) to the scene diff --git a/src/SVTK/SVTK_Selector.cxx b/src/SVTK/SVTK_Selector.cxx index 86e9bc335..0f54789d6 100644 --- a/src/SVTK/SVTK_Selector.cxx +++ b/src/SVTK/SVTK_Selector.cxx @@ -37,6 +37,27 @@ #include #include +#include +#include + + +/*! + Find first SALOME_Actor from the end of actors collection +*/ +inline +SALOME_Actor* +GetLastSALOMEActor(vtkActorCollection* theCollection) +{ + if (theCollection) { + for (int i = theCollection->GetNumberOfItems() - 1; i >= 0; i--) { + if (SALOME_Actor* anActor = dynamic_cast(theCollection->GetItemAsObject(i))) + if (anActor->hasIO()) + return anActor; + } + } + return NULL; +} + /*! \return new SVTK_Selector @@ -52,9 +73,14 @@ SVTK_Selector Default constructor */ SVTK_SelectorDef -::SVTK_SelectorDef() +::SVTK_SelectorDef(): + myPicker(vtkPicker::New()), + myCellPicker(vtkCellPicker::New()) { mySelectionMode = ActorSelection; + + myPicker->Delete(); + myCellPicker->Delete(); } /*! @@ -517,3 +543,34 @@ SVTK_SelectorDef return Handle(VTKViewer_Filter)(); } +SALOME_Actor* +SVTK_SelectorDef +::Pick(const SVTK_SelectionEvent* theEvent, vtkRenderer* theRenderer) const +{ + myCellPicker->Pick(theEvent->myX, + theEvent->myY, + 0.0, + theRenderer); + + vtkActorCollection* aListActors = myCellPicker->GetActors(); + SALOME_Actor* anActor = GetLastSALOMEActor(aListActors); + + if (! anActor) { + myPicker->Pick(theEvent->myX, + theEvent->myY, + 0.0, + theRenderer); + aListActors = myPicker->GetActors(); + anActor = GetLastSALOMEActor(aListActors); + } + + return anActor; +} + +void +SVTK_SelectorDef +::SetTolerance(const double& theTolerance) +{ + myPicker->SetTolerance(theTolerance); + myCellPicker->SetTolerance(theTolerance); +} diff --git a/src/SVTK/SVTK_Selector.h b/src/SVTK/SVTK_Selector.h index 17ab9be70..0d65de7e3 100644 --- a/src/SVTK/SVTK_Selector.h +++ b/src/SVTK/SVTK_Selector.h @@ -41,6 +41,8 @@ class Handle(VTKViewer_Filter); class SALOME_Actor; +class SVTK_SelectionEvent; +class vtkRenderer; class Handle(SALOME_InteractiveObject); //! Define an abstract interface for selection in SVTK package @@ -206,6 +208,15 @@ public: virtual void EndPickCallback() = 0; + + //---------------------------------------------------------------------------- + virtual + SALOME_Actor* + Pick(const SVTK_SelectionEvent* theEvent, vtkRenderer* theRenderer) const = 0; + + virtual + void + SetTolerance(const double& theTolerance) = 0; }; diff --git a/src/SVTK/SVTK_SelectorDef.h b/src/SVTK/SVTK_SelectorDef.h index 6515a187b..70b957756 100644 --- a/src/SVTK/SVTK_SelectorDef.h +++ b/src/SVTK/SVTK_SelectorDef.h @@ -44,6 +44,8 @@ class SALOME_Actor; class SVTK_Viewer; class SVTK_ViewWindow; +class vtkPicker; +class vtkCellPicker; class SVTK_SelectorDef: public SVTK_Selector { @@ -167,6 +169,15 @@ public: void EndPickCallback(); + //---------------------------------------------------------------------------- + virtual + SALOME_Actor* + Pick(const SVTK_SelectionEvent* theEvent, vtkRenderer* theRenderer) const; + + virtual + void + SetTolerance(const double& theTolerance); + private: int mySelectionMode; @@ -208,6 +219,9 @@ private: typedef std::map TFilters; TFilters myFilters; + + vtkSmartPointer myPicker; + vtkSmartPointer myCellPicker; }; #endif diff --git a/src/SVTK/SVTK_View.cxx b/src/SVTK/SVTK_View.cxx index e056d6d77..57e6e49eb 100644 --- a/src/SVTK/SVTK_View.cxx +++ b/src/SVTK/SVTK_View.cxx @@ -259,9 +259,10 @@ SVTK_View void SVTK_View ::SetSelectionTolerance(const double& theTolNodes, - const double& theTolCell) + const double& theTolCell, + const double& theTolObjects) { - GetRenderer()->SetSelectionTolerance(theTolNodes,theTolCell); + GetRenderer()->SetSelectionTolerance(theTolNodes, theTolCell, theTolObjects); } /*! diff --git a/src/SVTK/SVTK_View.h b/src/SVTK/SVTK_View.h index af25bf5ea..ff463ab5e 100644 --- a/src/SVTK/SVTK_View.h +++ b/src/SVTK/SVTK_View.h @@ -258,7 +258,8 @@ public: //! Redirect the request to #SVTK_Renderer::SetPreselectionProp void SetSelectionTolerance(const double& theTolNodes = 0.025, - const double& theTolCell = 0.001); + const double& theTolCell = 0.001, + const double& theTolObjects = 0.025); protected: int myDisplayMode; diff --git a/src/SVTK/SVTK_ViewModel.cxx b/src/SVTK/SVTK_ViewModel.cxx index 990a96ee9..8e5360537 100644 --- a/src/SVTK/SVTK_ViewModel.cxx +++ b/src/SVTK/SVTK_ViewModel.cxx @@ -285,11 +285,19 @@ SVTK_Viewer QVector aViews = myViewManager->getViews(); for(int i = 0, iEnd = aViews.size(); i < iEnd; i++){ if(TViewWindow* aView = dynamic_cast(aViews.at(i))){ - aView->getMainWindow()->getToolBar()->show(); + //aView->getMainWindow()->getToolBar()->show(); + const QObjectList& aChildren = aView->getMainWindow()->children(); + foreach (QObject* aObj, aChildren) { + if (aObj->inherits("QToolBar")) { + QToolBar* aToolBar = dynamic_cast(aObj); + if (aToolBar) aToolBar->show(); + } + } } } } + /*! Display presentation \param prs - presentation diff --git a/src/SVTK/SVTK_ViewWindow.cxx b/src/SVTK/SVTK_ViewWindow.cxx index 12d296388..be2e4468f 100755 --- a/src/SVTK/SVTK_ViewWindow.cxx +++ b/src/SVTK/SVTK_ViewWindow.cxx @@ -799,9 +799,10 @@ SVTK_ViewWindow void SVTK_ViewWindow ::SetSelectionTolerance(const double& theTolNodes, - const double& theTolItems) + const double& theTolItems, + const double& theTolObjects) { - myView->SetSelectionTolerance(theTolNodes,theTolItems); + myView->SetSelectionTolerance(theTolNodes, theTolItems, theTolObjects); } /*! @@ -827,9 +828,7 @@ SVTK_ViewWindow // 76 values for graduated axes, so both numbers are processed. const int nNormalParams = 13; // number of view windows parameters excluding graduated axes params const int nGradAxisParams = 25; // number of parameters of ONE graduated axis (X, Y, or Z) -const int nNormalGradAxisParams = nNormalParams + 3*nGradAxisParams + 1; // number of visual parameters with graduated axes -const int nBgColorParams = 4; // number of parameters of BgColor ("BgColor",Red,Gree,Blue) -const int nNormalBgColorParams = nNormalGradAxisParams + nBgColorParams; // number of visual parameters with background color +const int nAllParams = nNormalParams + 3*nGradAxisParams + 1; // number of all visual parameters /*! The method returns visual parameters of a graduated axis actor (x,y,z axis of graduated axes) */ @@ -989,13 +988,6 @@ SVTK_ViewWindow retStr += ::getGradAxisVisualParams( gradAxesActor->GetZAxisActor2D() ); } - QColor bgColor=backgroundColor(); - - retStr += QString("* BgColor "); - retStr += QString( "*%1" ).arg(bgColor.red()); - retStr += QString( "*%1" ).arg(bgColor.green()); - retStr += QString( "*%1" ).arg(bgColor.blue()); - return retStr; } @@ -1051,7 +1043,7 @@ SVTK_ViewWindow // apply graduated axes parameters SVTK_CubeAxesActor2D* gradAxesActor = GetCubeAxes(); - if ( gradAxesActor && paramsLst.size() >= nNormalGradAxisParams ) { + if ( gradAxesActor && paramsLst.size() == nAllParams ) { int i = nNormalParams+1, j = i + nGradAxisParams - 1; ::setGradAxisVisualParams( gradAxesActor->GetXAxisActor2D(), parameters.section( '*', i, j ) ); @@ -1065,13 +1057,6 @@ SVTK_ViewWindow else gradAxesActor->VisibilityOff(); } - if(paramsLst.size() >= nNormalBgColorParams) { - QColor bgColor(paramsLst[nNormalBgColorParams-3].toInt(), - paramsLst[nNormalBgColorParams-2].toInt(), - paramsLst[nNormalBgColorParams-1].toInt() - ); - setBackgroundColor(bgColor); - } } } diff --git a/src/SVTK/SVTK_ViewWindow.h b/src/SVTK/SVTK_ViewWindow.h index f0c756ae5..811752c97 100755 --- a/src/SVTK/SVTK_ViewWindow.h +++ b/src/SVTK/SVTK_ViewWindow.h @@ -248,7 +248,8 @@ class SVTK_EXPORT SVTK_ViewWindow : public SUIT_ViewWindow virtual void SetSelectionTolerance(const double& theTolNodes = 0.025, - const double& theTolCell = 0.001); + const double& theTolCell = 0.001, + const double& theTolObjects = 0.025); //! Methods to save/restore visual parameters of a view (pan, zoom, etc.) virtual diff --git a/src/SVTK/resources/vtk_view_graduated_axes.png b/src/SVTK/resources/vtk_view_graduated_axes.png new file mode 100755 index 0000000000000000000000000000000000000000..2b44c06fe8f81517d47267c43b62963b1a40ace5 GIT binary patch literal 650 zcmV;50(Jd~P)z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ;07*naRCwBA`2YVu13vJ;#00+rGyo7lOhl>^2V!nw z6aoYg6EUs>(l3CN1Th8z1P}uOFY`hTtpZ{%5TB5F00G1ZGLVsx5tqD-v9a-EdQCNfLQPa2gtCsK+A5ow_`|FR8+v2prCjU#9x5;7eD|p;W6xQM@I)% zNswVkaw;im)@h0~(eq!v4A!D0vqkfUqTOAz&=O z72}z~P*n2)XZiygwjW4+hNeGeXkLE?5I{H$B#=8+11XSg&w&`EmJON~p8y09x`9ld z_NV`DKWORzWII9=Edx~ZZzvm-#Xf;F1Mxj*8Uz`@1_t3dn`h<~8@7^L|d)KHL1 ze}W8xNdg2A*vnoHXZ{0SrUEUZ_(8!0HSimz@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ;&`Cr=RCwBA{Qv(y12q9a05LI882|(j3n2xJjEp=$ zUwlF0Gntv0{Y6)I>eMMdAoU9%fLI6^=ETFpv=>P8f((Tjrjxc7uI9?DU>H*th+hK) z5DOl|(wrQ)X5N4Bo8ilsf1*JCH<-(i3}FzmDPVYaWCDn(4a8Rg0*D2NVIDx2&Ft+I zVKA|J1QOx_Vpb4CIdl?S-QCrB$l7Fp_%T2LF<~(*lZ}mW`_lOm3@S>j4AtdA47xh( zmw-}Je*E|WR>O5;Ha2&F!jJgz1R9!?lPNH{t5t-7lamoeE-v{6!_gC>3?d>T$g#Tx zNIeANi$Hu5Ab=P^1|nl1UT15$7oh-U)v zN+4be3JM@D1Y#FZI06I^Mx+1@1;u1BDE-;na;A0kyk~gy_z%O(DPj!jYHT1S!capw zf%qp7zXjs^Q2ZVsfEaOQJ)nUG!0 zfcQDkyOG|W+zhtPk3nM72$fC%0R(d)HxO&VybMZ*Kn%(T(<@2@|NHrHgTyKbxekN@ z0tlRJfJp>opga&808C$X-6moRSbzY68ORPz1|V-rL*<@A k6RS8-%_(9_Y=8g*0FLr@0@O3lmjD0&07*qoM6N<$f_(BtfB*mh literal 0 HcmV?d00001 diff --git a/src/SVTK/resources/vtk_view_scaling.png b/src/SVTK/resources/vtk_view_scaling.png new file mode 100644 index 0000000000000000000000000000000000000000..fa8cbbc71e4c929f859c045ef73c53a8e431fcad GIT binary patch literal 1128 zcmV-u1eg1XP)z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ<-bqA3RCwBAWME+U&wvRS8OQ_x0R+T(>KN|dzmIO{e|!cB3JNm3fB&8lAb?mvoPYm+0}cDluw~ADhHu}# zG5q-P10*a9#BYH3JIJtY+qN;tm^=cjy$r;^{{3V)KS_(hL0F$5wapM@7}#Kd0Ad0W zfB*kt_zP6vnkd5HlO@6M{X57E1{WY!2O0Kq(sG7hzkUH-|CQm)-_H!+fcVS=4TcXN zzcZw?8ZdMu9)>wo9Uy?fF8l*D4CGyq!OJ>sgIx&(hCng7LB{F@=9M24Za_ZLW*3q(Awn8@%T`x(Ra?aB=A+%Gfy`1g(BOpOi0 z_aA>4_O4B3@RrbI`1tKD+=T!E!~zR%5M0^ykm2XgpD3>Q_vJg#t6#vb26^@8|L+W6 zz5;{jFGStfA0HULe*XYh4-h~si0Ecy2rrWdht=fCNCy7+2@H}S41fOoVfYP>yuS?p z|NUk7_xBH2{>QIx3_pK=gR2J!AQnWL_zzAO%i8aux$qmSM44 zr-1U$nf5XKV*UkJ4-h~oUS0(ZLuis=Ko-BSN{7K9>@vf?A3)cA{ljpf#f-s4+zKc= zn?d-O6~o+ZWgw+On`RgZ&3zzHiG8lwhV)*wDHLox+F@tGj!$1Ha zfKXh>$iM`4B{FDiYy=YMDR4W(X#{63lEgQF00QUbOK%r}vmPu9nu+DY6yAhlbtuLM zKv8`YAb?O@xPIaja3pYYax!pnaV3LjW@csvMn*`afszgggVh7YKx~kDaKr)g|NsC0 z4FLiO6c7#RWxn8?qGry;plQj?!1`5*p=)Ij1M?SohNcC+3{0P885-t!1Nm|ct&9B` zSidPSv@G&xVE>`W(7rr?f$f_jL+6Shh6NLLX8;7?n9NZC1cD&gPZ0f+h~E$dUv997 z^c=3o1`ZQcQc)$9g%(I*1S?!wIIfhpHy^Hq6@qo(gwI*_q|P z00M{M{=1zFpFVzL`1z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ#c!2mTx`6-zgkd1auxNgMhW|&8GCa6=kpU#5v||TIsvD}L6iL4_ z5Whq=7$AUHK!k>x8Xu6#1me{nKYnCj0O8xW8D9SQ!C((GSX@-}%C{ds96x{l{1B*S znwY4l%HO|#-8k6UC;j{Xf7kODFXqAw1qdJ(sKFg6si~PeckJl!{qu+6|D#6?=RSXC z2)cHS!NJas!QI0{=jzp~3b8WS7q#>WS81A{kE-22Gk!Ktwj+7#X2^%Aa$}bGUtKj1^@&QIHv$(YZ^3R z!@;j#zc&B-_m7K%gToo_dZS2&&u<C;*u^AbP+VPriiDXITr zVqy$3GBONXwrl}sEp2V>FDB)e7#`g`&G78}28MU{PB6T_aR8)zC&)ZdDgxs5Kzt7% zfUp$~+#p2)z5)#Vm-rdDxw#n>Q}!}^czB-S{lha1*EZC_)a``QcY$~V5FZ1jB!B?I zTH1ih10Z$<;u%;{%UWnj!+`EOkN`jc;W7~9N$D2U!bMTJ*dkr!3qa} u0K#P;vH{9a!^M&0UP2AIi(Y&I1Q-C)H>OJ$<6_?c0000@}v&{ literal 0 HcmV?d00001 diff --git a/src/Style/Style.qrc b/src/Style/Style.qrc new file mode 100644 index 000000000..7c529c541 --- /dev/null +++ b/src/Style/Style.qrc @@ -0,0 +1,8 @@ + + + images/critical.png + images/information.png + images/question.png + images/warning.png + + diff --git a/src/Style/Style_Salome.cxx b/src/Style/Style_Salome.cxx index fe568a7e7..576e1778b 100644 --- a/src/Style/Style_Salome.cxx +++ b/src/Style/Style_Salome.cxx @@ -163,6 +163,8 @@ static const char* const minimize_xpm[] = { Style_Salome::Style_Salome() : QWindowsStyle() { + //Q_INIT_RESOURCE(Style); + myModel = new Style_Model(); myModel->setDefaults( qApp ); @@ -278,7 +280,7 @@ void Style_Salome::drawComplexControl( ComplexControl cc, const QStyleOptionComp pe = (spin->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorSpinPlus : PE_IndicatorSpinUp); copy.rect = aBtnRect; - drawPrimitive(PE_IndicatorSpinUp, ©, p, w); + drawPrimitive(pe, ©, p, w); } if (spin->subControls & SC_SpinBoxDown) { copy.subControls = SC_SpinBoxDown; @@ -443,7 +445,9 @@ void Style_Salome::drawComplexControl( ComplexControl cc, const QStyleOptionComp button = subControlRect(cc, toolbutton, SC_ToolButton, w); menuArea = subControlRect(cc, toolbutton, SC_ToolButtonMenu, w); - if (w && qobject_cast(w->parentWidget())) { + if (w && ( qobject_cast(w->parentWidget() ) || + toolbutton->state & State_AutoRaise && !( toolbutton->state & State_MouseOver ) ) + ) { QWindowsStyle::drawComplexControl( cc, opt, p, w ); return; } @@ -1160,9 +1164,6 @@ void Style_Salome::drawControl( ControlElement ce, const QStyleOption* opt, } } break; - case CE_ToolBoxTab: - QCommonStyle::drawControl( ce, opt, p, w ); - break; case CE_HeaderSection: { bool aStateOn = opt->state & State_On; QColor aColor = getColor( Style_Model::header_clr ); @@ -1296,13 +1297,12 @@ void Style_Salome::drawControl( ControlElement ce, const QStyleOption* opt, break; } default: - QWindowsStyle::drawControl( ce, opt, p, w ); - break; + QWindowsStyle::drawControl( ce, opt, p, w ); } } void Style_Salome::drawPrimitive( PrimitiveElement pe, const QStyleOption* opt, - QPainter* p, const QWidget* w ) const + QPainter* p, const QWidget* w ) const { const QPalette& pal = opt->palette; bool doRestore = false; @@ -1366,7 +1366,9 @@ void Style_Salome::drawPrimitive( PrimitiveElement pe, const QStyleOption* opt, case PE_IndicatorArrowUp: case PE_IndicatorArrowDown: case PE_IndicatorSpinUp: - case PE_IndicatorSpinDown: { + case PE_IndicatorSpinDown: + case PE_IndicatorSpinPlus: + case PE_IndicatorSpinMinus: { QRect rect = opt->rect; QColor pen, brush; if ( opt->state & State_Enabled ) { @@ -1378,7 +1380,10 @@ void Style_Salome::drawPrimitive( PrimitiveElement pe, const QStyleOption* opt, pen = opt->palette.mid().color(); brush = pen; } - Style_Tools::drawArrow( pe, p, rect, pen, brush ); + if ( pe == PE_IndicatorSpinPlus || pe == PE_IndicatorSpinMinus ) + Style_Tools::drawSign( pe, p, rect, pen, brush ); + else + Style_Tools::drawArrow( pe, p, rect, pen, brush ); break; } case PE_IndicatorCheckBox: { @@ -1388,7 +1393,7 @@ void Style_Salome::drawPrimitive( PrimitiveElement pe, const QStyleOption* opt, QBrush fill; if (opt->state & State_NoChange) fill = QBrush( opt->palette.color( QPalette::Base ), Qt::Dense4Pattern); - else if (opt->state & ( State_Sunken | !State_Enabled ) ) + else if (opt->state & ( State_Sunken | ~State_Enabled ) ) fill = opt->palette.color( QPalette::Window ); else if (opt->state & State_Enabled) { if (!(opt->state & State_Off) ) @@ -1431,15 +1436,13 @@ void Style_Salome::drawPrimitive( PrimitiveElement pe, const QStyleOption* opt, p->save(); doRestore = true; } - if (pe == PE_Q3CheckListIndicator || pe == PE_IndicatorViewItemCheck) { - const QStyleOptionViewItem *itemViewOpt = qstyleoption_cast(opt); - p->setPen(itemViewOpt && itemViewOpt->showDecorationSelected - && opt->state & State_Selected ? opt->palette.highlightedText().color() - : opt->palette.text().color()); - if (opt->state & State_NoChange) - p->setBrush( opt->palette.color( QPalette::Button ) ); - p->drawRect(opt->rect.x() + 1, opt->rect.y() + 1, 11, 11); - } + const QStyleOptionViewItem *itemViewOpt = qstyleoption_cast(opt); + p->setPen(itemViewOpt && itemViewOpt->showDecorationSelected + && opt->state & State_Selected ? opt->palette.highlightedText().color() + : opt->palette.text().color()); + if (opt->state & State_NoChange) + p->setBrush( opt->palette.color( QPalette::Button ) ); + p->drawRect(opt->rect.x() + 1, opt->rect.y() + 1, 11, 11); if (!(opt->state & State_Off)) { QLineF lines[11]; int i, xx, yy; @@ -1459,7 +1462,7 @@ void Style_Salome::drawPrimitive( PrimitiveElement pe, const QStyleOption* opt, QColor aColor = getColor( Style_Model::pointer_clr ); if ( !(opt->state & State_Enabled ) ) aColor = opt->palette.mid().color(); - if ( opt->state & State_Selected ) + if ( opt->state & State_Selected && itemViewOpt && itemViewOpt->showDecorationSelected ) aColor = opt->palette.highlightedText().color(); p->setPen( QPen( aColor ) ); @@ -1562,16 +1565,12 @@ void Style_Salome::drawPrimitive( PrimitiveElement pe, const QStyleOption* opt, drawHoverRect(p, opt->rect, opt->palette.color( QPalette::Window ), aRad, Style_Tools::All, true); else { Style_Tools::shadowRect( p, opt->rect, aRad, LINE_GR_MARGIN, SHADOW, - Style_Tools::All, getColor( Style_Model::fld_light_clr ), + Style_Tools::All, opt->palette.color( QPalette::Base ), // getColor( Style_Model::fld_light_clr ), getColor( Style_Model::fld_dark_clr ), aBrdTopCol, aBrdBotCol, getBoolValue( Style_Model::all_antialized ), false ); } } else { - drawPrimitive( PE_FrameLineEdit, opt, p, w ); - /* - // fillRect()'s not correct working with basic color - // for ListWidget in edit QListWidgetItem mode if (const QStyleOptionFrame *panel = qstyleoption_cast(opt)) { QRect rect = panel->rect.adjusted( panel->lineWidth, panel->lineWidth, -panel->lineWidth, -panel->lineWidth); @@ -1580,7 +1579,6 @@ void Style_Salome::drawPrimitive( PrimitiveElement pe, const QStyleOption* opt, else // not QLineEdit p->fillRect(rect, panel->palette.brush(QPalette::Base)); } - */ } break; } @@ -1718,7 +1716,7 @@ void Style_Salome::drawPrimitive( PrimitiveElement pe, const QStyleOption* opt, if ( qobject_cast(aWdg) ) { QTreeView* trView = qobject_cast(aWdg); QHeaderView* aHeader = trView->header(); - if ( aHeader ) { + if ( aHeader && aHeader->isVisible() ) { int aHeight = aHeader->contentsRect().height(); r = QRect( r.x(), r.y()+aHeight, r.width(), r.height()-aHeight ); } @@ -1726,10 +1724,10 @@ void Style_Salome::drawPrimitive( PrimitiveElement pe, const QStyleOption* opt, QPalette aPal = aWdg->palette(); double aMarg = LINE_GR_MARGIN; QColor base = getColor( Style_Model::pal_base_clr ), - light = base, + light = base, light_alt = base.dark(110),//AlternateBase color dark = getColor( Style_Model::fld_dark_clr ); - light.setAlpha( 0 ); + //light.setAlpha( 0 ); // VSR commented: IPAL19262 QLinearGradient gr_h(r.x(), r.y(), r.right(), r.y()); gr_h.setColorAt( 0.0, dark ); gr_h.setColorAt( aMarg / r.width(), light ); @@ -1851,6 +1849,28 @@ QPixmap Style_Salome::standardPixmap(StandardPixmap stPixmap, const QStyleOption } } +QIcon Style_Salome::standardIconImplementation( StandardPixmap standardIcon, + const QStyleOption* opt, + const QWidget* widget ) const +{ + /* + switch ( standardIcon ) + { + case SP_MessageBoxInformation: + return QPixmap( ":/images/information.png" ); + case SP_MessageBoxWarning: + return QPixmap( ":/images/warning.png" ); + case SP_MessageBoxCritical: + return QPixmap( ":/images/critical.png" ); + case SP_MessageBoxQuestion: + return QPixmap( ":/images/question.png" ); + default: + break; + } + */ + return QWindowsStyle::standardIconImplementation( standardIcon, opt, widget ); +} + int Style_Salome::styleHint( StyleHint hint, const QStyleOption* opt, const QWidget* widget, QStyleHintReturn* returnData ) const { diff --git a/src/Style/Style_Salome.h b/src/Style/Style_Salome.h index 67e6472eb..edcfd1973 100644 --- a/src/Style/Style_Salome.h +++ b/src/Style/Style_Salome.h @@ -69,6 +69,10 @@ public: SubControl, const QWidget* = 0 ) const; virtual QRect subElementRect( SubElement, const QStyleOption*, const QWidget* = 0 ) const; +protected slots: + QIcon standardIconImplementation( StandardPixmap, const QStyleOption* = 0, + const QWidget* = 0 ) const; + private: void updatePaletteColors(); void updateAllWidgets( QApplication* ); diff --git a/src/Style/Style_Tools.cxx b/src/Style/Style_Tools.cxx index 08e0abe56..390fa1332 100644 --- a/src/Style/Style_Tools.cxx +++ b/src/Style/Style_Tools.cxx @@ -338,6 +338,77 @@ void Style_Tools::drawArrow( QStyle::PrimitiveElement type, QPainter* p, const Q p->restore(); } +void Style_Tools::drawSign( QStyle::PrimitiveElement type, QPainter* p, const QRect& r, + const QColor& pen, const QColor& brush ) +{ + p->save(); + QPainterPath sign; + int x = r.x(), y = r.y(), w = r.right()-x, h = r.bottom()-y; + int x11 = 0, x12 = 0, y11 = 0, y12 = 0; + int aDelta = qMin( (int)(w/3.5), (int)(h/3.5) ); + int deltaX = aDelta, deltaY = aDelta; + QLineF line( 0, 0, 1, 0 ); + int xc = r.center().x(), yc = r.center().y(); + p->translate( xc, yc ); + bool correct = false; + switch( type ) { + case QStyle::PE_IndicatorSpinMinus: + correct = true; + case QStyle::PE_IndicatorSpinPlus: { + aDelta = (int)(deltaY/2); + if ( correct ) { + aDelta = -aDelta; + deltaY = -deltaY; + } + if ( correct ) + sign.moveTo( deltaY/2, -aDelta/2-(deltaY/2-aDelta/3) ); + else { + sign.moveTo( aDelta/3, -aDelta/2 ); + sign.lineTo( aDelta/3, -aDelta/2-(deltaY/2-aDelta/3) ); + sign.lineTo( deltaY/2, -aDelta/2-(deltaY/2-aDelta/3) ); + } + + sign.lineTo( deltaY/2, -aDelta/2-(deltaY/2-aDelta/3)-2*aDelta/3 ); + + if ( !correct ) { + sign.lineTo( aDelta/3, -aDelta/2-(deltaY/2-aDelta/3)-2*aDelta/3 ); + sign.lineTo( aDelta/3, -aDelta/2-deltaY ); + sign.lineTo( -aDelta/3, -aDelta/2-deltaY ); + sign.lineTo( -aDelta/3, -aDelta/2-(deltaY/2-aDelta/3)-2*aDelta/3 ); + } + + sign.lineTo( -deltaY/2, -aDelta/2-(deltaY/2-aDelta/3)-2*aDelta/3 ); + sign.lineTo( -deltaY/2, -aDelta/2-(deltaY/2-aDelta/3) ); + + if ( correct ) + sign.lineTo( deltaY/2, -aDelta/2-(deltaY/2-aDelta/3) ); + else { + sign.lineTo( -aDelta/3, -aDelta/2-(deltaY/2-aDelta/3) ); + sign.lineTo( -aDelta/3, -aDelta/2 ); + sign.lineTo( aDelta/3, -aDelta/2); + } + + if ( correct ) + deltaX = -deltaX; + x11 = -deltaX, y11 = -deltaY, x12 = deltaX, y12 = 0; + break; + } + default: + p->restore(); + return; + } + p->setPen( pen ); + p->setBrush( brush ); + + QLinearGradient gr( x11, y11, x12, y12 ); + gr.setColorAt( 0.0, pen ); // grayer + gr.setColorAt( 1.0, brush); // lighter + p->fillPath( sign, gr ); + p->strokePath( sign, QPen( pen, Qt::SolidLine ) ); + + p->restore(); +} + QPainterPath Style_Tools::tabRect( QPainter* p, const QRect& r, const int position, const double rad, const double delta, const QColor& light, const QColor& dark, const QColor& border_top, const QColor& border_bot, diff --git a/src/Style/Style_Tools.h b/src/Style/Style_Tools.h index 381c5a3d2..06ddc54b3 100644 --- a/src/Style/Style_Tools.h +++ b/src/Style/Style_Tools.h @@ -68,6 +68,8 @@ public: const QColor&, const int = 255 ); static void drawArrow( QStyle::PrimitiveElement, QPainter*, const QRect&, const QColor&, const QColor& ); + static void drawSign( QStyle::PrimitiveElement, QPainter*, const QRect&, + const QColor&, const QColor& ); static QPainterPath tabRect( QPainter*, const QRect&, const int, const double, const double, const QColor&, const QColor&, const QColor&, const QColor&, diff --git a/src/Style/images/critical.png b/src/Style/images/critical.png new file mode 100644 index 0000000000000000000000000000000000000000..3cf8e5b53a44dce2bc77379b86efdca75b47f120 GIT binary patch literal 2328 zcmW+&dr%YC9zMI9WCP??gP5q`ss$+o2?Z>0N3sDCya)tpdDTjIg(y@}v|2BcjlmGb zVpJ}oWy*qu8JhwnzbsRtg3}03mzh{o{AOnKN_d{J#0V-{ZI} zKAP>k+!+AC-V(DZ$${9rU@{zM(c#0>4sa@rNh<=th5s%faG^%vxTNJtvwttft* zc=p|k?3koD01kTsKxhD%qa64WfCFLxUdaIns|H}%o--Len*m@}Y}q8;cIelv1&We% z<1hiTvIKI#!$sK9)2C095y{EPCD^EQ&nw)dX&9mN25Eo%hAq6cO|%VDMc+w7!&)QB6N%SR)<14x~3AKWX_LBa>g>F=< zqNtmY)e5;=I5EQ~^9a!O5|BM6yfL=)>@`D2udXv8?Yx?<6b?KZY!}+8x$X|og@yAp zE1@OGkPW{pIy_&Q>0}O&P*f8dR=-sFv!s9nF|o@WkiMH?IdHu}5pn#x4-hnFojFOH z(Jru43r-C}X|Z9Hl*xgoqB@e8T_x*xAtQY{F{5Q{$P$4ky zLz2B3rr1?gEUAwVFH%}nLOtl197Y9!@Z3p!ua^N4NUPQkQ8>Ct*BT|{+IHm02KZvm zR8vNgx}q0Kf3qSq2*5ge?Dd>v8r~NwMk0aJC!?(=ATrF>d&02pU|R0t(*afxbP^{W#ZC4j46fXqWIesM#z|0!v(}986 zFH=*)Umx6`BS(+9nD3hK+PY6GSR#=~P@K`0Gay=Dv6>Q&9ZE?_VGO1;30fuw(dZDd zFt8X2~-r0%vE;{OoWZ2 z!kgi{tdI8mo^y*keIPOMJq=%68XkGX&cEx{sfiuebO$9$Pr5-Z?^Vu2H#&^d*oL6fNm~ z{N2aGE8xjEy)ky;9xfsn# zPzQVTLfBp6Hq8`#P0^oqi?dC|GjJKKY?Pw@bqe-dWKYle z%gxA&C6kZ2mZiO2edqi&N4WPVV$ZG5m7(_&zTUvDVGjQEB@)jk3z+r!`T4@@Y704Q z2gX{G6GAK40{Katecc>2;YRORK26oMnoQnT;%E(u1akGv%nXZ56zF@f@(sKH%Zwj? zfd?$bHWt0uDu?FTuX((00`oYU4`tg|cvEi52mdf2_;jWY;dGs$y%PfzY*~D||M=;> z_jZx6%x#|a#1#oL(v_*Xxt`va1V1-rJS4gOyU5w#V_{hiTC9%7s!Z#vC#-#V+mgqY zn`Rz3-|93XmB%0(-*PTQsvKUu97X%*X?)t2&<=2e&7r3vQui~aIm#tR&8SkOLf>^cd1;tn+a?PXxrXNLk#C=<-N_WEFrg=ln|zX~HFSvylITzD zkSAw{Fs?5IuN|h#18%dG+}>ZB>e^ILoJWR3zT2OenB~qG!&+LZ=G+4f<@;s%o6#{| z6xPo+s>~5XtFD*+NH-oN+$4GOL$si`EVCt0meH=cvzYG~bwPGMMl@Sps>zp(5#|oe z4bIvt54;Z<9x!wV@L=IbdL9VwlzPEdN;`JM$&~erTCoFtWUEs{CvMwhv6-zFm!M|5 zL!k|*c#Y={j&c?6vCfsyI_n0=$)otv& S=W@pu1GYrPZ@Lm8Kl(rI8_ekd literal 0 HcmV?d00001 diff --git a/src/Style/images/information.png b/src/Style/images/information.png new file mode 100644 index 0000000000000000000000000000000000000000..3cd976403a5ff4ddf25581e098b7aa7dc448e8dd GIT binary patch literal 2087 zcmW+%dpOhkAOGxP8=ILn8F4m>)&*ZCx0KB-DYeG$lrD^A*2xpORdV?<&9z*Lh-$j( zlp49!31dPL(nWQurR0_rDt9~U_s9GFdOz>yc|XtV^}KIsoNb#lHS{$A0GgXUT)8Tw z|27;(VV06h7(A;7s}sw#;NW_z&#C_fcDx8wBh3cd%|3xF6C0ALXS zGfEW>0}urPFv0`Cp#T8g&|LqA?f_uVZ+2z-9DNfwuT(n8Sx6WJ22y!|#6pb$RgBQi z%*=FMB?t=ojNs<8ZsD3cSRtVKPU5sSDFOS@yCFeYzd0QRkf|qdTTEadBq=50@L|27 z;bBXUEnAq7rKP1%D1;s)C@=KQOb!y95*GK@hJV(Oi?CYn5iiCtACIwGVc~-`0v)EZ z(@1-8!0e?Ox3H3~h5Q^%vXiioJPVvP73$s7zv*sKjrrRjagUCKi zVu64t&^-|yAHSGBIvOI*&L&AibIjaYHf8-0w5vYWUVhfXpK5GuOm*C_!KfNMiJSgz zi?`m1C{5NpqYjWb10+jrUiM*8%5NoN{QUf+ zg6z)_md?+9b;rMfI?#2oOB(XpN_?>Qwxu-HgE_C9D>8c1D=Mk3UOLJz@Y_|I*u1#7 z(B9qK+uE&AI1P7QbTX6N!jo81k_YOZ!O}sfJ>WKWMn9Py!nt%h=X9`85qF`lYWqe} zfATxRe7Oz_J0IZT<)s$9iANHdiR{t)i5;2E&90bj+d3U38!oYq-&4^XfEgAR7H1^b z1J1-4(#EI}iiEkHQo7cGK)*v=9_G->tJ}>YD;v^t`i`Z;1=)YM zC9pEqEH&F*X=i43vhVA^H6NPM5om_3o&783{DU||@j|>)o&0;yV4%3ya1|lIp@JaO zAY9<{(sTtg`DS~lx5~=cU&UoC1r0Hyo0^aWu|VVM<)*?e_T| ztzFnhlwR%OPwrwprT`jMG|=AKKujiIT2q5P8%A$uJ*-vT9h6iP(Ydbc!Un$Zz=42W zHHY4LNrJb5@pZ!XVKPaiZyx%48i2cyoMGtWh%5))&Ui`KmD1AE;K)d8QC60gC@)XP z?rOrqtWNO=y9E6g3^%igXr0gWu%9FU6RRXLN8i`YnRWMgbNrP_v$OcpcgQH&9vC>^ zKE*DPX+)vhR>Wt!z~K`td0b)$lXrTno0pg7-n)q(ZB0!v`SCJA|Gj2 z85W3f9buSKJUhRPvC`QPtj2Csjd}%&R|3*Ch#VtCI*~Du;^0XVmTPe8R+BP{&YgP` z85PxtFRQM$5kD!i6@8pBc-}-)(Sdg_>gdnYN`C07=!E84mYhKAJ`ao}gd5m)_u%k& z{1Q#X3Y|TsK=mt6rY|;rTGkma4*xQ@#}ujtcS8M53QsqlddiMv-B;E zp~U)(S>$&0sa9&2$56|{rY|obXESz-Qwfph?%C0n&yRctkOc7QuKHcKDYR7e)WK%A LZLYVSc}f2Pin4Ij literal 0 HcmV?d00001 diff --git a/src/Style/images/question.png b/src/Style/images/question.png new file mode 100644 index 0000000000000000000000000000000000000000..b42fc1c7f6718eb37e75b6aef5d8e7e49a5fec0b GIT binary patch literal 2188 zcmWlbdpOkV7RTS;jJYsB($(2OTzrd)F9GS zwvfwI4xO^2+MVhgA)_RANtc}xW;AqB*j>yZbEZGm`o7QmJZnAAde{4W)+*p{+hl5D zZ2|x=4diVMHYoDL$V7ur$;|v>5aWHkohblN7X2^?R8%qymqvTITe$#SDbAYx`P7ey z-Mrwf0AxAt=_(S$L0kEaae3NTO<;(n#KBRmG1Kx>?59!y_u{rQA$Y*2BBx4i0XrA zCnjnxfDw$rEuifp1J~z-;PUqN_VS#Z9Qf0xPXfvbKln_`aXX(?OrM-e;rE%Z$c!6b zMC`TC=25x(X($k;f!@EaWIVPGn1#6%$7!65)h|1jl%+ zCtEvd@0XOcQaO10&<*^Nc%1E3!h67o2V}&Y1YAdrf^WOIxs{umn!;XQUi&Cq#v6H9 zV-&lm#-~O&U40A=xOWw9U&4gzw{M6QXjin;EG+KQ%*^h9?w82SP^%awQJDfqH@A50 zw~xD^Ub82XV7)@?gMzc3f{4V##N|A8&kZCXQHNZDjj!bOftv`xEU;sW^EmZVU%Vp<#dbb;#C^fc`Ku-?l0!x%d}BBFf* zky3CetTFezIb-2Vv3{PQsf-3thtb#dKCGM06%`f3rBatTp%Cg~H(j~HZiu{f(%w6; z>dw9DW2%YPJXk!x0jN7+vAz|k-BHRQdrtSc%HAWYNci}iKa5g_N85UUMp0A*%QHNB zBixX95*Z2SmRK^G@bQ$gMxk|ofBzjSxll!ln31bG8#lr9hp%JuO(ExIbWdtv^}~0PJWT# zl}~2>1E;M?xwCU>x`qx%4)nlDQTmt+-5g!{(Pqf1wzihxEuM!D02dEIF+VhvIK|bK z(h-cm+4s%OJfU2JScj0)($XZ^)0%F&th#!!>{R_}PDB4i<>cqiXvGn+m3NL-xljFK z4{=i-(xgGU(f1NA)!pU|SM(GMUc12X3w(!{H#{C&cz!+)#QmMvS_EcG*ADT!8&q_$+6`wg?x6H=`m7LbfLqV+&$ z7A*G4Kk-%IfUF`G_#FKEFqeDc4A=K0UeqO)O$_N*HAH`wN%Fc&?7h60=V6qnxUfF; zE$#lI16U;0z>Qp|>RXBZt7O}2yoKTUQAScG;^;_*)jn{L<-qRnbz=l&-Ss4^%TY5A zz~=h{0|S$(cnUZ6THTg%oD+$P7RFd&0Otu9TUKImnFr$H90n`QO646L9SrYg{hv*# zsuWq;r6|t$>+jX7C!MXs=F|sQnM~$BIOx8j*T`aHRaF%-WOt<8n1)Ugjak>%;tF3L zQFs9Jq_^DsNEe@+xiT)dKq}NMca{BgZHHBbrv)SA={l>uum4L(2ab;=zPRvgsV$WJ z<@TXzM)U34T#YhRG$##K+ZoF9y|_dVxn2gPF+qKOeT>1DY|3^oR?&FAfrsqoOkJVs z^{b&agz)d(pir6xCxiRRG~#;Eqv{Rtw{PDR>B?=2iQ|4BBsJ(99>D}@(4s%~+`Ks8?Y7i{OSL@>*&tv-F4K5oo^ zeRcoHJx}yeB~ERFer|=PRvOC#R;M z(=yg3>_KiJePwQ8B)^)za3OAXafzI({$Kh>+z#agR$7gpnPEKrOA-HS4?^^ZE@-|G z5lnt*H{Y=-_bTzikLe)y!;($V&J28iT^q84Xu%5z2pCqly1EiNSKenMZ~|rER>~Nu zx2F@$G8O68@L7J+S^*^{iQ>ZWVUOGe`MR^kD#GKoj8LPCBq4j(u3dR| z3+d8Du8zx`oSYbIlLnhfZ%4ZM6t32J;dcYD`Q$94BSb?I_inwPv(ASfCYCti2+y1y zbBLyWzoS8?ZN0O!h~qKr!6AOL^aYyttMAt(yS`bz%p{gi5#Jw@54dB%cY;2bcVjhw zA8O5r+svC8Yj`D=oF;@2?`Po`qJM`}q33@m#%OPPV4Y z(3d^em|gZgJgQLA*TAEWY<$o%k4D&tMyZ0;RTA0oCdcmbqfS_>OP%_aJh literal 0 HcmV?d00001 diff --git a/src/Style/images/warning.png b/src/Style/images/warning.png new file mode 100644 index 0000000000000000000000000000000000000000..471ec5888e56d90e8a2c951d974761f539e11c19 GIT binary patch literal 2198 zcmWkwX;f2L625r}*?1vfB0JZdT^vkFsy-%n ze0+9Z2zZ#VV}FC)z~Z1ziyp>PDB+Uj#qaDCr|0G@MlF1+YH3j#fawWq(%x8JTK_|7 z*(y>%pCzKuKHnuuYGPpY4Z0cqt2m2y>_}I@YCIesbhmn?hjo1T%Erl^Z0ur02A}0YoG*FP-V-^#%R- za}&C!r5Ux-Xy((`tzA^dhfgW)UYQVNTU4RW_V#G2di_#k&D!NgvG@=v`hu}i8%WKfQuWyC_ z@1F?UJyulk4NIs&AwWNxyj!MF#Db?G7(^&7(&aT27suANGDbsDfr!RXDFo(2irj;| zoVjw5rq@)WRXRH)2M`Ff(9B|-TW~mZw=RTWal&2uQnhj+@beAFA`pe4}dT2(0-~=wyF|09GrOll1e`oX~x1{OBPf z+nh>!kp>uvx&P|)0Su=6T~p#VS+Am7Z00s%sx#&i$%Z*?cb8y((O0!ihTQ}?0Pp$f zCkkbyzF*eTJvjchx0MWw(_9F0+4)+4Ipc-%K3j6j8i#wTtn*><2?67Ftb1&B;KD4$ z9z{iubdISrt_a_>ConJyR(FLqLAbLey*3?p>vu_|(%MVkizq>!#%s~c)TeLUIGY?E z_691OC;hp662E$?Q3(|mYbHk;d4yaLZZhy%Eu5id;Rpn#YNQcWvT;y#bsGG(zDb#1 zvc_V6NEVmo66kK6G%4Yyq(p;C$Dq&2Vk%}_<&Jvnoe2)M)!aul-I`$21$i3G?&yO? z!;fuB!AC!v(l(;w!+kwH14;pT^S& zB`3qLYPmxKp@VXGsUkS);!1lh^3bES6y^vweE#fHknK8P!F7^NA_NvYBg-2zO-C?HANzBMsFhk#@CfeHa=J`}D!Zzy6A$H(j|1lVxIE~0cjx<1 zY(MBL;Z$7b(t)O5Vu|}+N|@E1rE%i-4c#q_JU@7C>?HZ;q&~+ z!_}p2!|;O#@0BMot{pBDQwQeHP_lByXPcv0XdQ|HpKZo_0GzdW7q-zEp ztX(NdP#E&tt*_r%oTEzp10VodeuiTjhilU z;2{lruJYSa+@P5`cUYdXduMC&#SYx44plx7Ybce*ZT8`r7h)i6AjS_vrZ(p2(%p1e z(Sjb-lka@M$Xzz^048IE1t+&C)phM|zz` z>%hC9apVGaL9X@#GtQdEG&{b$QRel6mAjz-r{<5-vP%rqJ9m-n4c=@s$G0h<+j5qv z%8B>9bzU#l;1<&*CqI?KKb;61??ACFmDb8G$zDT+X6Us-nPu9@w3=rR9u>$Ocxf0g73&x;dj(qsk6!AA{+3G&nV)R+NG9j|XBrQTWu>_B|ZfIc&*zfmT68q!N3=F;E{6wrdwXZRXmD zc>=mXagRe9>SdAVEZ%{P;yJ6Bse;^vX)C#Y8T&&rv^_Z~Dc>bx_v(zqGjB1gc)NKd z-Naye^!4Ys@NSL}KvspyR4MUhM3z`29#klhUeqS~zon&8Pf}$d?(&b~0D8WYqn>J2 zc;=<5kfX)?`2kw}@gczAZrBEUQr952NIeiY5@TLA){_$KXVUCmcyPk@BPWIi{~QO` zVf&UH5K7u3RwtH-bYNwcqOEI!5leg`KQ$?zwk?}{wSshOW1sM`JzChjd5OBeuVB9~ z!>Blu?X;Vap8U-hYOE8jZq}Y@S(-K|@TgPi1 #include #include +#include +#include +#include #ifdef _DEBUG_ static int DEBUG_TRIA_EXECUTE = 0; @@ -81,31 +84,117 @@ namespace typedef std::vector TPolygons; } -/*! - Constructor -*/ + +//---------------------------------------------------------------------------- VTKViewer_Triangulator ::VTKViewer_Triangulator(): - myInput(NULL), - myCellId(-1), - myShowInside(-1), - myAllVisible(-1), - myCellsVisibility(NULL), - myCellIds(vtkIdList::New()) + myCellIds(vtkIdList::New()), + myFaceIds(vtkIdList::New()), + myPoints(vtkPoints::New()), + myPointIds(NULL) {} -/*! - Destructor -*/ +//---------------------------------------------------------------------------- VTKViewer_Triangulator ::~VTKViewer_Triangulator() { myCellIds->Delete(); + myFaceIds->Delete(); + myPoints->Delete(); +} + + +//---------------------------------------------------------------------------- +vtkPoints* +VTKViewer_Triangulator +::InitPoints(vtkUnstructuredGrid *theInput, + vtkIdType theCellId) +{ + myPoints->Reset(); + myPoints->Modified(); // the VTK bug + + vtkIdType aNumPts; + theInput->GetCellPoints(theCellId, aNumPts, myPointIds); + if ( aNumPts > 0 ) { + vtkFloatingPointType anAbsoluteCoord[3]; + myPoints->SetNumberOfPoints(aNumPts); + vtkPoints *anInputPoints = theInput->GetPoints(); + for (int aPntId = 0; aPntId < aNumPts; aPntId++) { + anInputPoints->GetPoint(myPointIds[aPntId], anAbsoluteCoord); + myPoints->SetPoint(aPntId, anAbsoluteCoord); + } + } + + return myPoints; +} + + +//---------------------------------------------------------------------------- +vtkIdType +VTKViewer_Triangulator +::GetNbOfPoints() +{ + return myPoints->GetNumberOfPoints(); } +//---------------------------------------------------------------------------- +vtkIdType +VTKViewer_Triangulator +::GetPointId(vtkIdType thePointId) +{ + return thePointId; +} + +//---------------------------------------------------------------------------- +vtkFloatingPointType +VTKViewer_Triangulator +::GetCellLength() +{ + vtkFloatingPointType aBounds[6]; + myPoints->GetBounds(aBounds); + + vtkFloatingPointType aCoordDiff[3]; + aCoordDiff[0] = (aBounds[1] - aBounds[0]); + aCoordDiff[1] = (aBounds[3] - aBounds[2]); + aCoordDiff[2] = (aBounds[5] - aBounds[4]); + + return sqrt(aCoordDiff[0]*aCoordDiff[0] + + aCoordDiff[1]*aCoordDiff[1] + + aCoordDiff[2]*aCoordDiff[2]); +} + + +//---------------------------------------------------------------------------- +void +VTKViewer_Triangulator +::GetCellNeighbors(vtkUnstructuredGrid *theInput, + vtkIdType theCellId, + vtkCell* theFace, + vtkIdList* theCellIds) +{ + myFaceIds->Reset(); + vtkIdList *anIdList = theFace->PointIds; + myFaceIds->InsertNextId(myPointIds[anIdList->GetId(0)]); + myFaceIds->InsertNextId(myPointIds[anIdList->GetId(1)]); + myFaceIds->InsertNextId(myPointIds[anIdList->GetId(2)]); + + theInput->GetCellNeighbors(theCellId, myFaceIds, theCellIds); +} + + +//---------------------------------------------------------------------------- +vtkIdType +VTKViewer_Triangulator +::GetConnectivity(vtkIdType thePntId) +{ + return myPointIds[thePntId]; +} + + +//---------------------------------------------------------------------------- bool VTKViewer_Triangulator ::Execute(vtkUnstructuredGrid *theInput, @@ -120,13 +209,7 @@ VTKViewer_Triangulator std::vector& theVTK2ObjIds, bool theIsCheckConvex) { - myInput = theInput; - myCellId = theCellId; - myShowInside = theShowInside; - myAllVisible = theAllVisible; - myCellsVisibility = theCellsVisibility; - - vtkPoints *aPoints = InitPoints(); + vtkPoints *aPoints = InitPoints(theInput, theCellId); vtkIdType aNumPts = GetNbOfPoints(); if(DEBUG_TRIA_EXECUTE) cout<<"Triangulator - aNumPts = "< TPointIds; @@ -172,9 +255,9 @@ VTKViewer_Triangulator for (int aFaceId = 0; aFaceId < aNumFaces; aFaceId++) { vtkCell* aFace = GetFace(aFaceId); - GetCellNeighbors(theCellId, aFace, myCellIds); - if((!myAllVisible && !myCellsVisibility[myCellIds->GetId(0)]) || - myCellIds->GetNumberOfIds() <= 0 || myShowInside) + GetCellNeighbors(theInput, theCellId, aFace, myCellIds); + if((!theAllVisible && !theCellsVisibility[myCellIds->GetId(0)]) || + myCellIds->GetNumberOfIds() <= 0 || theShowInside) { TPointIds aPointIds; vtkIdList *anIdList = aFace->PointIds; @@ -320,9 +403,9 @@ VTKViewer_Triangulator aCenter[0] += aPntCoord[0]; aCenter[1] += aPntCoord[1]; aCenter[2] += aPntCoord[2]; - if(DEBUG_TRIA_EXECUTE) cout << "Added = TRUE" << endl; + if(DEBUG_TRIA_EXECUTE) cout << "; Added = TRUE" << endl; } else { - if(DEBUG_TRIA_EXECUTE) cout << "Added = FALSE" << endl; + if(DEBUG_TRIA_EXECUTE) cout << "; Added = FALSE" << endl; } } int aNbPoints = aPointIds.size(); @@ -512,171 +595,144 @@ VTKViewer_Triangulator return true; } -/*! - Constructor -*/ + +//---------------------------------------------------------------------------- VTKViewer_OrderedTriangulator ::VTKViewer_OrderedTriangulator(): - myCell(vtkGenericCell::New()) -{} + myTriangulator(vtkOrderedTriangulator::New()), + myBoundaryTris(vtkCellArray::New()), + myTriangle(vtkTriangle::New()) +{ + myBoundaryTris->Allocate(VTK_CELL_SIZE); + myTriangulator->PreSortedOff(); +} -/*! - Destructor -*/ + +//---------------------------------------------------------------------------- VTKViewer_OrderedTriangulator ::~VTKViewer_OrderedTriangulator() { - myCell->Delete(); + myTriangle->Delete(); + myBoundaryTris->Delete(); + myTriangulator->Delete(); } + +//---------------------------------------------------------------------------- vtkPoints* VTKViewer_OrderedTriangulator -::InitPoints() +::InitPoints(vtkUnstructuredGrid *theInput, + vtkIdType theCellId) { - myInput->GetCell(myCellId,myCell); - return myInput->GetPoints(); -} + myBoundaryTris->Reset(); -vtkIdType -VTKViewer_OrderedTriangulator -::GetNbOfPoints() -{ - return myCell->GetNumberOfPoints(); -} + vtkPoints* aPoints = VTKViewer_Triangulator::InitPoints(theInput, theCellId); + vtkIdType aNumPts = myPoints->GetNumberOfPoints(); + if ( aNumPts > 0 ) { + myTriangulator->InitTriangulation(0.0, 1.0, 0.0, 1.0, 0.0, 1.0, aNumPts); -vtkIdType -VTKViewer_OrderedTriangulator -::GetPointId(vtkIdType thePointId) -{ - return myCell->GetPointId(thePointId); -} + vtkFloatingPointType aBounds[6]; + myPoints->GetBounds(aBounds); -vtkFloatingPointType -VTKViewer_OrderedTriangulator -::GetCellLength() -{ - return sqrt(myCell->GetLength2()); + vtkFloatingPointType anAbsoluteCoord[3]; + vtkFloatingPointType aParamentrucCoord[3]; + for (int aPntId = 0; aPntId < aNumPts; aPntId++) { + myPoints->GetPoint(aPntId, anAbsoluteCoord); + aParamentrucCoord[0] = (anAbsoluteCoord[0] - aBounds[0]) / (aBounds[1] - aBounds[0]); + aParamentrucCoord[1] = (anAbsoluteCoord[1] - aBounds[2]) / (aBounds[3] - aBounds[2]); + aParamentrucCoord[2] = (anAbsoluteCoord[2] - aBounds[4]) / (aBounds[5] - aBounds[4]); + myTriangulator->InsertPoint(aPntId, anAbsoluteCoord, aParamentrucCoord, 0); + } + + myTriangulator->Triangulate(); + myTriangulator->AddTriangles(myBoundaryTris); + } + + return aPoints; } + +//---------------------------------------------------------------------------- vtkIdType VTKViewer_OrderedTriangulator ::GetNumFaces() { - return myCell->GetNumberOfFaces(); + return myBoundaryTris->GetNumberOfCells(); } + +//---------------------------------------------------------------------------- vtkCell* VTKViewer_OrderedTriangulator ::GetFace(vtkIdType theFaceId) { - return myCell->GetFace(theFaceId); -} + vtkIdType aNumCells = myBoundaryTris->GetNumberOfCells(); + if ( theFaceId < 0 || theFaceId >= aNumCells ) + return NULL; -void -VTKViewer_OrderedTriangulator -::GetCellNeighbors(vtkIdType theCellId, - vtkCell* theFace, - vtkIdList* theCellIds) -{ - vtkIdList *anIdList = theFace->PointIds; - myInput->GetCellNeighbors(theCellId, anIdList, theCellIds); -} + vtkIdType *aCells = myBoundaryTris->GetPointer(); -vtkIdType -VTKViewer_OrderedTriangulator -::GetConnectivity(vtkIdType thePntId) -{ - return thePntId; + // Each triangle has three points plus number of points + vtkIdType *aCellPtr = aCells + 4*theFaceId; + + myTriangle->PointIds->SetId(0, aCellPtr[1]); + myTriangle->Points->SetPoint(0, myPoints->GetPoint(aCellPtr[1])); + + myTriangle->PointIds->SetId(1, aCellPtr[2]); + myTriangle->Points->SetPoint(1, myPoints->GetPoint(aCellPtr[2])); + + myTriangle->PointIds->SetId(2, aCellPtr[3]); + myTriangle->Points->SetPoint(2, myPoints->GetPoint(aCellPtr[3])); + + return myTriangle; } -/*! - Constructor -*/ + +//---------------------------------------------------------------------------- VTKViewer_DelaunayTriangulator ::VTKViewer_DelaunayTriangulator(): myUnstructuredGrid(vtkUnstructuredGrid::New()), myGeometryFilter(vtkGeometryFilter::New()), myDelaunay3D(vtkDelaunay3D::New()), - myFaceIds(vtkIdList::New()), - myPoints(vtkPoints::New()), - myPolyData(NULL), - myPointIds(NULL) + myPolyData(NULL) { + myUnstructuredGrid->Initialize(); + myUnstructuredGrid->Allocate(); + myUnstructuredGrid->SetPoints(myPoints); + myDelaunay3D->SetInput(myUnstructuredGrid); myGeometryFilter->SetInput(myDelaunay3D->GetOutput()); + myPolyData = myGeometryFilter->GetOutput(); } - -/*! - Destructor -*/ +//---------------------------------------------------------------------------- VTKViewer_DelaunayTriangulator ::~VTKViewer_DelaunayTriangulator() { myUnstructuredGrid->Delete(); myGeometryFilter->Delete(); myDelaunay3D->Delete(); - myFaceIds->Delete(); - myPoints->Delete(); } +//---------------------------------------------------------------------------- vtkPoints* VTKViewer_DelaunayTriangulator -::InitPoints() +::InitPoints(vtkUnstructuredGrid *theInput, + vtkIdType theCellId) { - myPoints->Reset(); - myUnstructuredGrid->Initialize(); - myUnstructuredGrid->Allocate(); - myUnstructuredGrid->SetPoints(myPoints); - - vtkIdType aNumPts; - myInput->GetCellPoints(myCellId,aNumPts,myPointIds); - - if ( aNumPts < myPoints->GetNumberOfPoints() ) - myPoints->Reset(); - - { - vtkFloatingPointType aPntCoord[3]; - myPoints->SetNumberOfPoints(aNumPts); - vtkPoints *anInputPoints = myInput->GetPoints(); - for (int aPntId = 0; aPntId < aNumPts; aPntId++) { - anInputPoints->GetPoint(myPointIds[aPntId],aPntCoord); - myPoints->SetPoint(aPntId,aPntCoord); - } - } + vtkPoints* aPoints = VTKViewer_Triangulator::InitPoints(theInput, theCellId); myPoints->Modified(); myUnstructuredGrid->Modified(); - myGeometryFilter->Update(); - myPolyData = myGeometryFilter->GetOutput(); - return myPoints; -} - -vtkIdType -VTKViewer_DelaunayTriangulator -::GetNbOfPoints() -{ - return myPoints->GetNumberOfPoints(); + return aPoints; } -vtkIdType -VTKViewer_DelaunayTriangulator -::GetPointId(vtkIdType thePointId) -{ - return thePointId; -} - -vtkFloatingPointType -VTKViewer_DelaunayTriangulator -::GetCellLength() -{ - return myPolyData->GetLength(); -} +//---------------------------------------------------------------------------- vtkIdType VTKViewer_DelaunayTriangulator ::GetNumFaces() @@ -684,32 +740,11 @@ VTKViewer_DelaunayTriangulator return myPolyData->GetNumberOfCells(); } + +//---------------------------------------------------------------------------- vtkCell* VTKViewer_DelaunayTriangulator ::GetFace(vtkIdType theFaceId) { return myPolyData->GetCell(theFaceId); } - -void -VTKViewer_DelaunayTriangulator -::GetCellNeighbors(vtkIdType theCellId, - vtkCell* theFace, - vtkIdList* theCellIds) -{ - myFaceIds->Reset(); - vtkIdList *anIdList = theFace->PointIds; - myFaceIds->InsertNextId(myPointIds[anIdList->GetId(0)]); - myFaceIds->InsertNextId(myPointIds[anIdList->GetId(1)]); - myFaceIds->InsertNextId(myPointIds[anIdList->GetId(2)]); - - myInput->GetCellNeighbors(theCellId, myFaceIds, theCellIds); -} - - -vtkIdType -VTKViewer_DelaunayTriangulator -::GetConnectivity(vtkIdType thePntId) -{ - return myPointIds[thePntId]; -} diff --git a/src/VTKViewer/VTKViewer_ConvexTool.h b/src/VTKViewer/VTKViewer_ConvexTool.h index 2bf024d5e..5e391d976 100644 --- a/src/VTKViewer/VTKViewer_ConvexTool.h +++ b/src/VTKViewer/VTKViewer_ConvexTool.h @@ -36,7 +36,12 @@ class vtkCellData; class vtkPoints; class vtkIdList; class vtkCell; +class vtkCellArray; +class vtkTriangle; +class vtkOrderedTriangulator; + +//---------------------------------------------------------------------------- class VTKVIEWER_EXPORT VTKViewer_Triangulator { public: @@ -57,51 +62,48 @@ class VTKVIEWER_EXPORT VTKViewer_Triangulator std::vector& theVTK2ObjIds, bool theIsCheckConvex); - protected: + private: vtkIdList* myCellIds; - vtkUnstructuredGrid *myInput; - vtkIdType myCellId; - int myShowInside; - int myAllVisible; - const char* myCellsVisibility; + protected: + vtkIdType *myPointIds; + vtkIdList* myFaceIds; + vtkPoints* myPoints; virtual vtkPoints* - InitPoints() = 0; + InitPoints(vtkUnstructuredGrid *theInput, + vtkIdType theCellId); virtual vtkIdType - GetNbOfPoints() = 0; + GetNumFaces() = 0; virtual - vtkIdType - GetPointId(vtkIdType thePointId) = 0; + vtkCell* + GetFace(vtkIdType theFaceId) = 0; - virtual - vtkFloatingPointType - GetCellLength() = 0; + vtkIdType + GetNbOfPoints(); - virtual vtkIdType - GetNumFaces() = 0; + GetPointId(vtkIdType thePointId); - virtual - vtkCell* - GetFace(vtkIdType theFaceId) = 0; + vtkFloatingPointType + GetCellLength(); - virtual void - GetCellNeighbors(vtkIdType theCellId, + GetCellNeighbors(vtkUnstructuredGrid *theInput, + vtkIdType theCellId, vtkCell* theFace, - vtkIdList* theCellIds) = 0; + vtkIdList* theCellIds); - virtual vtkIdType - GetConnectivity(vtkIdType thePntId) = 0; + GetConnectivity(vtkIdType thePntId); }; +//---------------------------------------------------------------------------- class VTKVIEWER_EXPORT VTKViewer_OrderedTriangulator : public VTKViewer_Triangulator { public: @@ -111,22 +113,14 @@ class VTKVIEWER_EXPORT VTKViewer_OrderedTriangulator : public VTKViewer_Triangul ~VTKViewer_OrderedTriangulator(); protected: - vtkGenericCell *myCell; + vtkOrderedTriangulator *myTriangulator; + vtkCellArray *myBoundaryTris; + vtkTriangle *myTriangle; virtual vtkPoints* - InitPoints(); - - virtual - vtkIdType - GetNbOfPoints(); - - vtkIdType - GetPointId(vtkIdType thePointId); - - virtual - vtkFloatingPointType - GetCellLength(); + InitPoints(vtkUnstructuredGrid *theInput, + vtkIdType theCellId); virtual vtkIdType @@ -135,19 +129,10 @@ class VTKVIEWER_EXPORT VTKViewer_OrderedTriangulator : public VTKViewer_Triangul virtual vtkCell* GetFace(vtkIdType theFaceId); - - virtual - void - GetCellNeighbors(vtkIdType theCellId, - vtkCell* theFace, - vtkIdList* theCellIds); - - virtual - vtkIdType - GetConnectivity(vtkIdType thePntId); }; +//---------------------------------------------------------------------------- class VTKVIEWER_EXPORT VTKViewer_DelaunayTriangulator : public VTKViewer_Triangulator { public: @@ -161,24 +146,11 @@ class VTKVIEWER_EXPORT VTKViewer_DelaunayTriangulator : public VTKViewer_Triangu vtkGeometryFilter* myGeometryFilter; vtkDelaunay3D* myDelaunay3D; vtkPolyData* myPolyData; - vtkIdType *myPointIds; - vtkIdList* myFaceIds; - vtkPoints* myPoints; virtual vtkPoints* - InitPoints(); - - virtual - vtkIdType - GetNbOfPoints(); - - vtkIdType - GetPointId(vtkIdType thePointId); - - virtual - vtkFloatingPointType - GetCellLength(); + InitPoints(vtkUnstructuredGrid *theInput, + vtkIdType theCellId); virtual vtkIdType @@ -187,16 +159,6 @@ class VTKVIEWER_EXPORT VTKViewer_DelaunayTriangulator : public VTKViewer_Triangu virtual vtkCell* GetFace(vtkIdType theFaceId); - - virtual - void - GetCellNeighbors(vtkIdType theCellId, - vtkCell* theFace, - vtkIdList* theCellIds); - - virtual - vtkIdType - GetConnectivity(vtkIdType thePntId); }; diff --git a/src/VTKViewer/VTKViewer_GeometryFilter.cxx b/src/VTKViewer/VTKViewer_GeometryFilter.cxx index 50cade3f1..5d2590de6 100755 --- a/src/VTKViewer/VTKViewer_GeometryFilter.cxx +++ b/src/VTKViewer/VTKViewer_GeometryFilter.cxx @@ -771,6 +771,8 @@ VTKViewer_GeometryFilter { delete [] cellVis; } + + return 0; } diff --git a/src/VTKViewer/VTKViewer_ViewManager.cxx b/src/VTKViewer/VTKViewer_ViewManager.cxx index 0e3f32bb7..a206be6ee 100755 --- a/src/VTKViewer/VTKViewer_ViewManager.cxx +++ b/src/VTKViewer/VTKViewer_ViewManager.cxx @@ -19,9 +19,6 @@ #include "VTKViewer_ViewManager.h" #include "VTKViewer_ViewModel.h" -#include -#include - /*!Constructor.Initialize SIUT_ViewManager by \a study and \a theDesktop. * Create new instance of VTKViewer_Viewer and set view model by it. */ @@ -36,37 +33,3 @@ VTKViewer_ViewManager::~VTKViewer_ViewManager() { /*!Do nothing.*/ } - -/*! - Fills preference manager for viewer -*/ -int VTKViewer_ViewManager::fillPreferences( SUIT_PreferenceMgr* thePrefMgr, const int theId ) -{ - int aGrpId = thePrefMgr->addItem( tr( "PREF_GROUP_VTKVIEWER" ), theId, - SUIT_PreferenceMgr::GroupBox ); - - int vtkTS = thePrefMgr->addItem( tr( "PREF_TRIHEDRON_SIZE" ), aGrpId, - SUIT_PreferenceMgr::DblSpin, "VTKViewer", "trihedron_size" ); - thePrefMgr->addItem( tr( "PREF_RELATIVE_SIZE" ), aGrpId, SUIT_PreferenceMgr::Bool, - "VTKViewer", "relative_size" ); - thePrefMgr->addItem( tr( "PREF_VIEWER_BACKGROUND" ), aGrpId, - SUIT_PreferenceMgr::Color, "VTKViewer", "background" ); - - thePrefMgr->setItemProperty( "min", 1.0E-06, vtkTS ); - thePrefMgr->setItemProperty( "max", 150, vtkTS ); - - return aGrpId; -} - -/** - * Fills values from resources - */ -void VTKViewer_ViewManager::fillFrom( SUIT_ResourceMgr* theMgr ) -{ - VTKViewer_Viewer* aModel = dynamic_cast( getViewModel() ); - if ( !aModel ) - return; - - aModel->setBackgroundColor( theMgr->colorValue( "VTKViewer", "background", - aModel->backgroundColor() ) ); -} diff --git a/src/VTKViewer/VTKViewer_ViewManager.h b/src/VTKViewer/VTKViewer_ViewManager.h index c8e200817..debd7987e 100755 --- a/src/VTKViewer/VTKViewer_ViewManager.h +++ b/src/VTKViewer/VTKViewer_ViewManager.h @@ -35,9 +35,6 @@ class VTKVIEWER_EXPORT VTKViewer_ViewManager : public SUIT_ViewManager public: VTKViewer_ViewManager( SUIT_Study* study, SUIT_Desktop* ); virtual ~VTKViewer_ViewManager(); - - static int fillPreferences( SUIT_PreferenceMgr*, const int ); - void fillFrom( SUIT_ResourceMgr* ); }; #endif diff --git a/src/VTKViewer/VTKViewer_ViewWindow.cxx b/src/VTKViewer/VTKViewer_ViewWindow.cxx index ead79fd57..6f462e3e2 100755 --- a/src/VTKViewer/VTKViewer_ViewWindow.cxx +++ b/src/VTKViewer/VTKViewer_ViewWindow.cxx @@ -456,8 +456,8 @@ void VTKViewer_ViewWindow::onAdjustTrihedron(){ (bnd[5]-bnd[4])*(bnd[5]-bnd[4])); }else{ aLength = bnd[1]-bnd[0]; - aLength = max((bnd[3]-bnd[2]),aLength); - aLength = max((bnd[5]-bnd[4]),aLength); + aLength = qMax((bnd[3]-bnd[2]),aLength); + aLength = qMax((bnd[5]-bnd[4]),aLength); } static vtkFloatingPointType aSizeInPercents = 105; diff --git a/src/VTKViewer/resources/vtk_view_back.png b/src/VTKViewer/resources/vtk_view_back.png new file mode 100755 index 0000000000000000000000000000000000000000..51beb0c73e5fa109819e0d38cacb60c467e540b5 GIT binary patch literal 432 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE-VXMsm#F#`j)FbFd;%$g$s6l6(v z^mSxl*w|O|J8&|PuaN8!Y85oZ=>2VsZ z*|B4WqSelM8i#wf{7CTOSGdP0;NbJ3?dMNl#apQghtI|SW_jEcbAlNt8e+u5$H3Gf zD54n^6{T{VXH(*w9)HIxEDCW90uCPxT*~IIdR4n8u|p(Jf$t^q z>bS!nR-h>-40+fb+8DXnCM1eC{NOkd(7=$iXi}o}f-m6>3`*9o6ODOP_yimhm>Zui zG}`hbQ1Rdy@qqk8yv&RZ3{8?JcvHL^y5xm;{xF$-(cYxsz+f1(n~QY85oZ=>2VsZ z*|B5B!*98+i+FBt(PTgNh2fDbP^Kks#{Byti(=V~&Kyry>ftU@4rc>h5?ccECN?~SvV9{NplD|gqRB`G_1%| z0J`JBB!;6Vb_>@1<5+D007H_2!PC{x JWt~$(699I+gjE0l literal 0 HcmV?d00001 diff --git a/src/VTKViewer/resources/vtk_view_camera_dump.png b/src/VTKViewer/resources/vtk_view_camera_dump.png new file mode 100755 index 0000000000000000000000000000000000000000..b02616f2975e7a3865a236ee75380bdae5ce59f7 GIT binary patch literal 682 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE-VXMsm#F#`j)FbFd;%$g$s6l6(v z^mSxl*w|O|J8&|PuaN8!GAr-fh{`~)M&uq%*z+h+?Aj!ZYz}<83#0idNZ{NHLm{arOf}-0Di4NZr z4h;-Rj?WrQvR=Mwyy^F?%;4dFDJdx)KR>?&vt5iYrhzo>YRaCjpLk={x^?G1e0dpc zAf2Wt^rJsV!+{}D;>9cZGar846mH{Q?tkd0S>BzF%TD3t{4*BXIQ-IfVA%M8i#s*c zlr1kVj?FMpku6S6PGNSxV@Sx9M(Gn`0zzpIgandKboIMkOJX=8&cMX6ys@Kkl!Hi5Cs~Z*GuUfUrsH3ynxPybcSy{#2e*VG@J6ax= z#n~Osp1^ImwK3)gt3rdprHAi&vk!iGdwaWNpPVI=nU9lGQ{we?u{?kG+WrXQ(cn=9 z+IG10^fX=PhwiSfjl8q1O0@zxr4<@xOt_qoo~}Mam+y-f$9#+0wuLz-jo8f1&D+fL z?z+m40n#|u4mYG61ddHVaiyUq`r4~d9q8ZdYn zozP=;ncaEPUC6S9SjZ)j11xdTOVx|PwNDx OD+W(jKbLh*2~7Z6;rO)x literal 0 HcmV?d00001 diff --git a/src/VTKViewer/resources/vtk_view_fitall.png b/src/VTKViewer/resources/vtk_view_fitall.png new file mode 100755 index 0000000000000000000000000000000000000000..87e001dd80b2755858d4599857106a0c9c0b3500 GIT binary patch literal 816 zcmV-01JC@4P)z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ;rb$FWRCwBA{Qv(y12q9a0I`6G?+lD6rgAd;XCy{5 zHhlmA#Dc^@mIHB63}s|w3&>x^7VEp$V z!_S{T8NPo0%wTSB4^{^=10aA{2t*_sGYc!&H9+&gF8uxbH^cX@Ux5bxVEFUvH&_hp zNhkmaASMC^p1OMBJi~90i+=rL`10u!!-sco89u&$$ME^%M~1IozA)UpbP22urU4*; z81W@+U>Ndq^YVU}wt5|dps+B*k8j@@e*E~(@bkwHhQELQGJN^`k)bg^7i72+(46}q zJpciO*M(YIT7fc>k_-*mnGENS9|s!*!oPv8y?^^ALw|iO$gn1uVITkyKn&QD3J3!Y zt1#5l`yc4!^j}9?`#%#C(;-P2+5cJwhW{mHWkKFL1H{Sb`Tzn5YousvYge$bu(Yd+ zi!(g^@BtL?iGTn8T>uOM_2*9>%K?=<1!}&AO)o$IVT2*juu`C5U1~tXo&y8^?Uyf= zSFc{}AhvJ-2p}dj!}3{~naMT`1ONgE>_SkfVWO=i2{i0E$eXW$2^NUUfQEGwYY@l` zP;LPTAh-*gnwp;TadI-eff!amiebp56hHvMT?i_^fL=}k3i1H)bfAI1NHGa!20#G8 u4Wv>5%K#8S$g%vNP}zvfo5&o100RIgKz|e1YHVKs0000aa literal 0 HcmV?d00001 diff --git a/src/VTKViewer/resources/vtk_view_fitarea.png b/src/VTKViewer/resources/vtk_view_fitarea.png new file mode 100755 index 0000000000000000000000000000000000000000..450dc56c6ce722c040b4e5b77459207e8256cd58 GIT binary patch literal 912 zcmV;B18@9^P)z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ<21!IgRCwBA`2YVu0|yT@j4)mLY4&S1Wi z-OcbHM57sG48)m^9-he_0f7usvT_X1pFT0(yLC(8&W#(k0Oh^{@n4u?fB<44!Y5g^ z-MvYH5s?faC;S8YMon9X!N%2{!P42~V^d*1!@s|O;pPAY5EB8zLY%$4ll;RYzy^Ww zzyAz>|Nmq7`|lrvqn8hZdq5CKT`^1pKmZXkFx1h@8)yK~5THSSfQEqa-+v50fBt0n z`uQ`1xxGC|T`bJU00BhE%bd(CtYFsw%>%pe_wU~f-@kqZ8u)|Z&#&KLF(43ts^eU0F)F)_Iu>vs%)X>*Rt^|Sq00D$yAS*L-7tFAGPoM68`t<2NpzvEDJ`2PkgPEZQ zf?W3=>e4ST{Qv>Pgyb@bC5sj@fV}w<7@K#WJlO{{>@HC171XfPKztRHl%RYNeIJNF z01K4gATvM(3qSzDi!W_$?G#}ip4rTdj11l(AtV=F=_OOZ1q?s{!3|_&WMorRR4o7X z>z4u0Wlx|ky9mWEfcQ5q!$2+r83v*O0tneaP`Ky0YCsD8wiRZ mF(6igmT$M9kwFpw2rvMsC6+#;$I7?>0000Y85oZ=>2VsZ z*|B5B!*98+i+FBt(PTgNh2fDbP^Kks#{Byti(=V~&Kyry>ftU@fIOolmwP)z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZc>jKeOv$OzL15I`)*h9FA-UC3*1Z~uwm?OTSQ4<0bQ ze(?e}13&j7BtjOg8oBY{u_wj195)S?b{&f6+rwNh(Uq* zK0ZGF9!TB4fBzVey$%pSph#d!NlE$3!NI}s_3KxL7r?*=#V#=XRDg2aKr9Qy%0Mg# zwcu`6R@RnZzkY$$K7Ra|;oiM_44*%L1}7(g00Oy$^}~k`3@Z!_7=WS-7i47_^npo& z_1d*NKskL-Yy$BYAm#zl;o;#2riOWv!1Q5tTw%b52J!EBN z_zMj9Ye2(a0MpVAL405VabQDXA%mWt-g{_beh*a#GW3?PurN#?D4ah51P}|7@?T7UooaWF76FUtY(e=N8Ih<%~* zEa-Xx0ti>}^$+SLM<6zX=4AnBQUWFN&ro@cDgYqB0GrW?VpB4t`v3p{07*qoM6N<$ Eg6tg6&Hw-a literal 0 HcmV?d00001 diff --git a/src/VTKViewer/resources/vtk_view_left.png b/src/VTKViewer/resources/vtk_view_left.png new file mode 100755 index 0000000000000000000000000000000000000000..1b787b0433413a7117083cefce238d0219b55484 GIT binary patch literal 427 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE-VXMsm#F#`j)FbFd;%$g$s6l6(v z^mSxl*w|O|J8&|PuaN8!cxAr-fh{`~)M&uq%*z_77_!_Cc2#L?H+cT&#Iy1!N(L5z>Y85oZ=>2VsZ z*|B5B!*98+i+FBt(PTgNh2fDbP^KmC#?I{d9c7Xy4CLo`8t9#9wE>E{s2+a6pwJL8 z;qV!cZhoyh-WMEl+8P-g7!Dp5xLNA`-0Tsr^OAzYKsOvY;*iQ9;1FUipwO@)Pr-p9 z@UBAx!=hb{AX~kiLciL@^}c%5zoCnnMWC&*WfBk1fh!J^FNg)$u|3iU+0>VK;-z4O zK?Bcjh9m9{ZA>fz!c%!}GcMf^WGSz(xpL`}($0V*X%ZeX3JnL?m`*#VW_(=i)HG9n z!Mzq~HYNr}7UK!hC#Ero+N((XV9k0Fp5oZRkhG*sltCbY;YM8g@#-Jb&H@9L!PC{x JWt~$(69BoFkt+ZI literal 0 HcmV?d00001 diff --git a/src/VTKViewer/resources/vtk_view_pan.png b/src/VTKViewer/resources/vtk_view_pan.png new file mode 100755 index 0000000000000000000000000000000000000000..ec56cacc779342a978f183ecf747860c8b6dafb4 GIT binary patch literal 982 zcmV;{11bE8P)z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZb!otG-18H_3W&!c>DFz52f`;Yh z=KlYG@Zf(vJw1@2;y}!e&rpB>!e<*(Vq)UoNnv3OZ?0TnIIE=v5_imOsnQ(>_Q@}D9Q|HpzmfY=u#@9*!A5&HlE#0WDiKR^HPSD@Ek zzkbaCa@oa;7a4y4{_O{p(+6UCAm#(&Px|`$DQaqJ3~X#{4Da5(V|e)RA;Yz6*FdiR z0t!=r00NsF6BF}yLQoI`!>?Zq4Bx&nFns>Zz!(z)vWNqS-$A_va>-9lVB{=URRycP zpsdWG&(6-kdhOZ^SVRE?5Q~nE&fmqMp$spM9AUWs@+E@^Q1mI#KqwFe;@8la1=_~I z2J*$jJ9ilVe*DOA?ZXF#7k~dU%-7RnNW63j9QyzP#B$}z6$wUv{}&HSOBrrFdBPyW z&(HAr=TDe{d{D#gLnA=o6)=Lf|NhPJ2I#_XKyN<>8oU@7aj@722p~`x$^o%15O2W} zQ4K(R5QwirT?%sXD=g|(05K?CodF0SP#A)o^9gFhL?B)Zjj^{zMn(Vgg6j zxpU_jK79D#4wN$jVr3vsfvN|&{yoSXfB<5F#?CWnLd}P!GmwE_`1tr3R)vHxJUVoU z;RMiI;U7Ty82F(McnHLu(3}E_l-nS400M{wntfhCo&E)yX#avZ-#{@A45MF<9x;Hz z4lSY{BV~fOP)EH02p|@y4KPE$Kyv_tjEu~^`}glN965WI;l_&>3~!m4VFpeGVn3)0 zVaeeeEFA&_5G?D#4E+fW52hzio+tt7dm^Ah;l~e#JMZ4X4D5u`pP`QU2lWw%{s$01 zxUwNTH0uR`vRkc+3M|{L0pd2OxFS>?3IGToW*i2Bk`pV``xg$qd*=yF8X#vr0J$9M zy07T20tg^xJOwPwRUpGpK{Y>y#^wX4;lH73-~b@N0A_|Q{Wj4Xb^rhX07*qoM6N<$ Ef)-GsSpWb4 literal 0 HcmV?d00001 diff --git a/src/VTKViewer/resources/vtk_view_reset.png b/src/VTKViewer/resources/vtk_view_reset.png new file mode 100755 index 0000000000000000000000000000000000000000..66f81e60471b7b587c37166a4e206b45f74e7fc2 GIT binary patch literal 918 zcmV;H18Mw;P)z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ<3`s;mRCwBA`2YVu0}KO!sHi9>h~bSaP6`GHAOZXQ009Iu ztVK?a_y6WCKL3CH$@>5IfA;^Iw`2aBnTdlW&7exTp@zi+u{AD30Ro7Lk&#hUNQk5Q z?D;STpjR1~nHj+nii&(-KGfwPzyqZXfLH~Ij{*P!hzW=@vvYJAfQEtvwrzdL@b~Y3 zhTx#>3=Q?CrT~SeL)CtP(l4O+3pN7*0*D2Ojg5^(!JOKflMHLu++jF%N|j;rru$QX z!I2B}0Zi>zGy}h4GY}wvKrZ|XauEp3n0^K5WhREsj&mSx69e%89{T_R1ajfcn>Rmz zIq%;60AXz)^A6B;zi?=K-}sfC-?tzTH62r z+1dZM`}+RpVPyp=a)o&VAb=Q=3jlDg;ox}n@#jy5zyJSR0p*SZ#Xz=e0L9NFXlO8m zC@V8qN=Sg!-~8}_;lk_J40EqvXW0Gtu^UimH$VWPmo_{g8)rH={0C|R3ET$aE+9^W z#_sAO0|T(@KsZfX8>D6hvI_wMh!MSr0=mcm=$i9OU0oSe`1u*u-@C_f=i^5PHYO$p zdueHgKqVyxW?=4l`t>V=_OfLRAAkK40Gja;rXL`H7_pRjAVWa`o#`Ya<56K`#Na9` ziz0vj(Y85oZ=>2VsZ z*|B5B!*98+i+FBt(PTgNh2fDbP^Kks#{Byti(=V~-rU*hZ=iRg)dnc)qI&oNgF=IZ z+e1T-)tEt-^Qz2HlD1A~(F>qKK76+Qun1m?!43yrq?2vj_HMm!+@5HB-h z14EPK3EmX%hAw#_o&BefBz>vE(*)?7Fuoo~q89ZJ6T-G@yGywqE CrHFz@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ;>`6pHRCwBA{Qv(y12R~;bm{-kpFcBXWMnWhkO2S! zh!NSqB}nm z_#K0zqZ|V(D=WjUUAu@f7$ATcKn6xcL;xu(AT|MFC6Lhn$B!BQ-@VK5ALvjZpYgx7 zwe^1|C#U~lNjw-JfZz;ORn`9w9x(jhw~yifBP`+xG}xButP{r|6^ zpz#0SKaeu^{~*hO@{?f(!3+aofB<4dk7WS?0kC9s^&AE_w@?O<^q)V#kOc;9VxlU; z?b~;NzENS&)YJs4-?V8HO4tGf5EFWs{`m1Dg_)Td7#X2pgMR&j81~}_14CcmZ3Z

_Vnz58}j`-1H-p(2n+(i@MQS?`!|ES zx;=;+j;t9VfLO2?s3j(*3Dyh@GoVI@D?x^T`SOK;2)s#xwr&D>UEJd0|XE@ z1Al$^@Qag!gA?p!NcjC^`1I*D!^e*=zzTrof(`uo^&N=&7g;kv0AVxm!p)nP>@QyI zX7KP>0Cd@Bpld$>4SWSQ@aolD3??S}49d!`4A-yk1*t!dtQjDHFbs5aa|0V@W77-F zdJn*cefjbZY~bh5AVYyp`ui6w_wwaUkd`&b`T+t6ZlIr^-+x##0LI+pFJF3c^!0s# zhP?qA1j4U@?6*KeAl|)m=P)pg|7HPG#V=$70RjjmmBTPF(TW1`G$keD|2{qy|2;iR z|J&Lo{r~WR;lH7w;eQ?;eo(@0$CmW~0tj!u1Z6QGzQNBg3e1Mm|F2(X_^+$03o^_G zmmYusVjz^+p$5wVu`v)3EF1s=2qWuJ3IGC#iGj)hAb_ZDAV7ct0CqnRZB|4ZssI20 M07*qoM6N<$f-H}K!2kdN literal 0 HcmV?d00001 diff --git a/src/VTKViewer/resources/vtk_view_top.png b/src/VTKViewer/resources/vtk_view_top.png new file mode 100755 index 0000000000000000000000000000000000000000..cef95040afe84ada0bd453b6e4057004c3d75c5f GIT binary patch literal 419 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE-VXMsm#F#`j)FbFd;%$g$s6l6(v z^mSxl*w|O|J8&|PuaN8!Y85oZ=>2Vsp zxwF;ZMLKQCQTF62hL3y=3`vWw7|74>G|)TIY6Dc`qI&oNgF-{Zgu^^1f3h%|9d-cn z9wfeaZqBN=VpY}rhu?Bt=d|VCn$jH1r_eA%Vg(NaQ^zYdCKiFKyeu3FtE4#u974O2ZYzRgvtQ98zfuwPaa_K;WgpRWqg{f@Q+Er!RLuY+Z?$@R^}5MxE*R( zQZyVG3mdKI;Vst0Grx_ AY5)KL literal 0 HcmV?d00001 diff --git a/src/VTKViewer/resources/vtk_view_triedre.png b/src/VTKViewer/resources/vtk_view_triedre.png new file mode 100755 index 0000000000000000000000000000000000000000..bc5894dc380f7595ee865b43f1a94779c5aee3fa GIT binary patch literal 698 zcmV;r0!96aP)z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ;FiAu~RCwBA{Qv(y12q9a05O0Jgkf}$kdQ#KZ2$qp zgirF{zkdv;PoMsO_Uv+^4F(7xoCZcjMEw8w@gqZEU?9-ozaSxbAm$=uAV2`&^D>u- ziOK&nXO{jydUWRhEnC|DLk-0X00Ib~m$_cQe$8;_4l~1#ADW1qB5eL_|aw*x6aZd?0=erEvm)0Aj%>DI_Gsz`?-* zbR`>z`;{020RjlGfvl{o3`|TQPp}c44gmrPZ#raTWP~VU!fvm(w>L)800b`7drzdCp!Z(GYbPq`|sbs7`}Y@&hY2YUj~2x zLUCbYV&Z?8VOzFr0kQ4&?CAl~%Yb+e5Vr$y4H9mTjEwx>-JJnalL1l>5I`s{w6nAO z|MKNah7~KC7>tY}O!n{ZJLBkB)B#O<-=Hy#4!EJ|6C`&XAb?N|1SXOHKY#vY0A@9Y z@83T&xVV%QBN_A%nrzSk$S^G^`x-z1p@*SnO-;=;V`Dak=g;3Vym|A9p{{PeC)BWq zIMN_22Z6wAfB-@_5R_Lz2ADvF9suzfD1JjsIs^zH^aKX-(rGALgix-)1^@yGTe3kf g1c=JRFaQu>05%EfVPBu~R{#J207*qoM6N<$g3D|Y2LJ#7 literal 0 HcmV?d00001 diff --git a/src/VTKViewer/resources/vtk_view_zoom.png b/src/VTKViewer/resources/vtk_view_zoom.png new file mode 100755 index 0000000000000000000000000000000000000000..386c966d156f0a6f53e780aed211b78aa473a11b GIT binary patch literal 797 zcmV+&1LFLNP)z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ;lSxEDRCwBA{Qv(y12q9a05LI882|(j3yAp6z=+{Y zPKN)C$b3dd#y}ty1;mO#{0NBG0DZR%T^~RIu^?$iH}pTm97baxo$2V|nd}h|$RH&v z$MF2=6XU&Gw*&&^{D5-Pfd(IhX#xl!22dE{!$2^nw!8QLxyR4`p9SL6kDmTN`QXX_ zWA`8bZ*#;G5q}bli};<&kW}F_F#1|4FCbe zLcl;aW)@bkYk=l~UHJR=Z-(z*zXA>X!SLtTZ?G6R8lV6mfC#zp)YS{;8GeIY^y?SH zmrtJL&@bUdShR+{AGJO5=h2iF{4FCbeh%aFS!;qhwm-oZ8)$14pg@qY@ zeEZJuHQCMa{8~Mt^J>giRqA}jO>3c z1H=E4va%p=odM!xbbSB;gf&vMwY4kQSXkOs#l;z(e)s?i_{6_||1JOqf%@|&kL7?$ zo&q&r!=@J?fH1-kXjm!Gur4*AVb6g9|Mtt5%Bxqec3{&C%ChKL6d-_@&RKiH#D= b009O7QZ{F9XF19?00000NkvXXu0mjfwM|pG literal 0 HcmV?d00001 diff --git a/src/src.pro b/src/src.pro new file mode 100644 index 000000000..238d8d4b5 --- /dev/null +++ b/src/src.pro @@ -0,0 +1,31 @@ +TEMPLATE = subdirs +CONFIG += ordered + +SUBDIRS = Qtx +SUBDIRS += DDS +SUBDIRS += QDS +SUBDIRS += SUIT +SUBDIRS += SUITApp +SUBDIRS += STD +SUBDIRS += CAF +SUBDIRS += CAM +SUBDIRS += LogWindow +SUBDIRS += PyInterp +SUBDIRS += PyConsole +SUBDIRS += Prs +SUBDIRS += OBJECT +SUBDIRS += GLViewer +SUBDIRS += VTKViewer +SUBDIRS += SVTK +SUBDIRS += OCCViewer +SUBDIRS += SOCC +SUBDIRS += Plot2d +SUBDIRS += SPlot2d +SUBDIRS += SUPERVGraph +SUBDIRS += QxGraph +SUBDIRS += Event +SUBDIRS += LightApp +SUBDIRS += ResExporter +SUBDIRS += TOOLSGUI +SUBDIRS += SalomeApp +SUBDIRS += Session -- 2.39.2