From: nds Date: Mon, 6 Oct 2008 09:32:53 +0000 (+0000) Subject: Merging from the BR_V5_DEV branch. X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=fa18a6dedb9c6aa1bbf42f8976e54cfd9a16a683;p=modules%2Fgui.git Merging from the BR_V5_DEV branch. --- diff --git a/src/Qtx/QtxActionGroup.cxx b/src/Qtx/QtxActionGroup.cxx new file mode 100644 index 000000000..cc3da3471 --- /dev/null +++ b/src/Qtx/QtxActionGroup.cxx @@ -0,0 +1,361 @@ +// 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: QtxActionGroup.cxx +// Author: Sergey TELKOV + +#include "QtxActionGroup.h" + +#include "QtxComboBox.h" + +#include +#include +#include + +/*! + \class QtxActionGroup + \brief The QtxActionGroup class groups actions together. + + QtxActionGroup class operates with a list of actions in the similar way as it does QActionGroup class. + But in contrast to the Qt 4's class, QtxActrionGroup behaves rather like it was in Qt series 3x. + For example, it automatically shows exclusive combo box widget when action group is added to the toolbar + and if \a usesDropDown and \a exclusive flags are both set to \c true. + + The setExclusive() function is used to ensure that only one action is active at any moment: + it should be used with actions which have their \a checkable state set to \c true. + + Action group actions appear as individual menu options and toolbar buttons. For exclusive action + groups use setUsesDropDown() to display the actions in a subwidget of the toolbar or menu the action group + is added on. + + Actions can be added to the action group using add() function. Add the action group to the menu or + toolbar in the same way as for single action - using addAction() method of QMenu or QToolbar class. +*/ + +/*! + \brief Constructor + + The created action group is exclusive by default. + + \param parent owner object + \sa setExclusive() +*/ +QtxActionGroup::QtxActionGroup( QObject* parent ) +: QtxActionSet( parent ), + myDropDown( false ) +{ + setMenu( new QMenu( 0 ) ); + myActionGroup = new QActionGroup( this ); + + connect( myActionGroup, SIGNAL( triggered( QAction* ) ), this, SLOT( onTriggered( QAction* ) ) ); +} + +/*! + \brief Constructor + \param parent owner object + \param exclusive if \c true only one action in the group will ever be active + \sa setExclusive() +*/ +QtxActionGroup::QtxActionGroup( QObject* parent, const bool exclusive ) +: QtxActionSet( parent ), + myDropDown( false ) +{ + setMenu( new QMenu( 0 ) ); + myActionGroup = new QActionGroup( this ); + myActionGroup->setExclusive( exclusive ); + + connect( myActionGroup, SIGNAL( triggered( QAction* ) ), this, SIGNAL( selected( QAction* ) ) ); +} + +/*! + \brief Destructor. +*/ +QtxActionGroup::~QtxActionGroup() +{ +} + +/*! + \brief Check if the action group is exclusive + \return \c true if the action group is exclusive and \c false otherwise + \sa setExclusive(), setUsesDropDown() +*/ +bool QtxActionGroup::isExclusive() const +{ + return myActionGroup->isExclusive(); +} + +/*! + \brief Set/clear the action group exclusiveness + \param on if \c true the action group will be exclusive + \sa isExclusive(), setUsesDropDown() +*/ +void QtxActionGroup::setExclusive( const bool on ) +{ + if ( myActionGroup->isExclusive() == on ) + return; + + bool e = isEmptyAction(); + + myActionGroup->setExclusive( on ); + + if ( e != isEmptyAction() ) + updateType(); +} + +/*! + \brief Check if action group should appear in a subwidget of parent widget + + Note: for this option to take into effect, the \a exclusive flag should + be also set to \c true + + \return \c true if the action group is shown in subwidget + \sa setUsesDropDown(), setExclusive() +*/ +bool QtxActionGroup::usesDropDown() const +{ + return myDropDown; +} + +/*! + \brief Defines a way how the group's actions should be displayed in parent widget + action group is added to - as a group of actions or in a subwidget (e.g. in the + combo box). + \param on if \c true, action group will be shown in the subwidget + \sa usesDropDown(), setExclusive() +*/ +void QtxActionGroup::setUsesDropDown( const bool on ) +{ + if ( myDropDown == on ) + return; + + bool e = isEmptyAction(); + + myDropDown = on; + + if ( e != isEmptyAction() ) + updateType(); +} + +/*! + \brief Append the specified action into group. + \a action action to be added to the action group +*/ +void QtxActionGroup::add( QAction* a ) +{ + insertAction( a ); +} + +/*! + \brief Called when some subwidget item is activated by the user. + \param id item identifier +*/ +void QtxActionGroup::onActivated( int id ) +{ + const QObject* s = sender(); + + QAction* a = action( id ); + if ( !a ) + return; + + if ( a->isChecked() ) + return; + + a->setChecked( true ); + a->trigger(); + + QList lst = createdWidgets(); + for ( QList::iterator it = lst.begin(); it != lst.end(); ++it ) + { + QtxComboBox* cb = ::qobject_cast( *it ); + if ( cb && cb != s ) + cb->setCurrentId( id ); + } +} + +/*! + \brief Called when some action owned by this action group is activated by the user + \param a action being activated +*/ +void QtxActionGroup::onTriggered( QAction* a ) +{ + int id = actionId( a ); + if ( id != -1 ) { + QList lst = createdWidgets(); + for ( QList::iterator it = lst.begin(); it != lst.end(); ++it ) + { + QtxComboBox* cb = ::qobject_cast( *it ); + if ( cb ) + cb->setCurrentId( id ); + } + } + + emit selected( a ); +} + +/*! + \brief Update action group for the specified widget. + \param w a widget this action group is added to +*/ +void QtxActionGroup::updateAction( QWidget* w ) +{ + if ( !::qobject_cast( w ) && !::qobject_cast( w ) ) { + QtxComboBox* cb = createdWidget( w ); + if ( !cb ) + QtxActionSet::updateAction( w ); + else + { + updateAction( cb ); + + QList lst = actions(); + for ( QList::iterator it = lst.begin(); it != lst.end(); ++it ) + w->removeAction( *it ); + } + } + else + { + if ( !usesDropDown() ) { + QtxActionSet::updateAction( w ); + } + else { + QList lst = actions(); + for ( QList::iterator it = lst.begin(); it != lst.end(); ++it ) + w->removeAction( *it ); + } + } +} + +/*! + \brief Update action group for the specified combo box. + \param cb a combo box this action group is added to +*/ +void QtxActionGroup::updateAction( QtxComboBox* cb ) +{ + if ( !cb ) + return; + + cb->clear(); + cb->setCleared( false ); + + QAction* cur = 0; + QList lst = actions(); + for ( QList::iterator it = lst.begin(); it != lst.end(); ++it ) + { + QAction* a = *it; + cb->addItem( a->icon(), a->text() ); + cb->setId( cb->count() - 1, actionId( a ) ); + if ( a->isChecked() ) + cur = a; + } + + if ( cur ) + cb->setCurrentId( actionId( cur ) ); + else + cb->setCleared( true ); +} + +/*! + \brief Create widget representing action group in the widget + this action group is added to. + \param p widget this action group is being added to + \return new widget representing this action group +*/ +QWidget* QtxActionGroup::createWidget( QWidget* p ) +{ + if ( ::qobject_cast( p ) || ::qobject_cast( p ) ) + return 0; + + QtxComboBox* cb = !isEmptyAction() ? new QtxComboBox( p ) : 0; + if ( cb ) + connect( cb, SIGNAL( activatedId( int ) ), this, SLOT( onActivated( int ) ) ); + return cb; +} + +/*! + \brief Check if the action itself should be invisible + (only child action are shown) + \return \c true if the action itself should be visible +*/ +bool QtxActionGroup::isEmptyAction() const +{ + return !isExclusive() || !usesDropDown(); +} + +/*! + \brief Called when action is added to the action group + \param a action being added to the action group +*/ +void QtxActionGroup::actionAdded( QAction* a ) +{ + myActionGroup->addAction( a ); + if ( menu() ) + menu()->addAction( a ); +} + +/*! + \brief Called when action is removed from the action group + \param a action being removed from the action group +*/ +void QtxActionGroup::actionRemoved( QAction* a ) +{ + myActionGroup->removeAction( a ); + if ( menu() ) + menu()->removeAction( a ); +} + +/*! + \brief Internal update +*/ +void QtxActionGroup::updateType() +{ + QList lst = associatedWidgets(); + for ( QList::iterator it = lst.begin(); it != lst.end(); ++it ) + { + QWidget* w = *it; + QList lst = w->actions(); + + int i = lst.indexOf( this ); + w->removeAction( this ); + + lst = w->actions(); + w->insertAction( i < lst.count() ? lst.at( i ) : 0, this ); + } + setVisible( !isEmptyAction() ); +} + +/*! + \brief Get combo box created by this action group for the specified widget. + \param p widget this action group is added to + \return combo box if it was created for the specified widget or 0 otherwise +*/ +QtxComboBox* QtxActionGroup::createdWidget( QWidget* p ) +{ + QtxComboBox* cb = 0; + QList lst = createdWidgets(); + for ( QList::iterator it = lst.begin(); it != lst.end() && !cb; ++it ) + { + if ( (*it)->parent() == p ) + cb = ::qobject_cast( *it ); + } + return cb; +} + +/*! + \fn void QtxActionGroup::selected( QAction* a ); + \brief Emitted when some child action is toggled by the user. + \param a action being toggled +*/ diff --git a/src/Qtx/QtxActionGroup.h b/src/Qtx/QtxActionGroup.h new file mode 100644 index 000000000..108d40a53 --- /dev/null +++ b/src/Qtx/QtxActionGroup.h @@ -0,0 +1,82 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File: QtxActionGroup.h +// Author: Sergey TELKOV + +#ifndef QTXACTIONGROUP_H +#define QTXACTIONGROUP_H + +#include "QtxActionSet.h" + +#ifdef WIN32 +#pragma warning( disable:4251 ) +#endif + +class QtxComboBox; +class QActionGroup; + +class QTX_EXPORT QtxActionGroup : public QtxActionSet +{ + Q_OBJECT + +public: + QtxActionGroup( QObject* = 0 ); + QtxActionGroup( QObject*, const bool ); + virtual ~QtxActionGroup(); + + bool isExclusive() const; + bool usesDropDown() const; + + void add( QAction* ); + +public slots: + void setExclusive( const bool ); + void setUsesDropDown( const bool ); + +signals: + void selected( QAction* ); + +private slots: + void onActivated( int ); + void onTriggered( QAction* ); + +protected: + virtual void updateAction( QWidget* ); + virtual void updateAction( QtxComboBox* ); + + virtual QWidget* createWidget( QWidget* ); + + virtual bool isEmptyAction() const; + virtual void actionAdded( QAction* ); + virtual void actionRemoved( QAction* ); + +private: + void updateType(); + QtxComboBox* createdWidget( QWidget* ); + +private: + bool myDropDown; + QActionGroup* myActionGroup; +}; + +#ifdef WIN32 +#pragma warning( default:4251 ) +#endif + +#endif diff --git a/src/Qtx/QtxActionMenuMgr.cxx b/src/Qtx/QtxActionMenuMgr.cxx index 2540721e3..94368536e 100644 --- a/src/Qtx/QtxActionMenuMgr.cxx +++ b/src/Qtx/QtxActionMenuMgr.cxx @@ -46,6 +46,7 @@ public: int idx; //!< menu node index int group; //!< menu group ID bool visible; //!< visibility status + int emptyEnabled; //!< enable empty menu flag NodeList children; //!< children menu nodes list }; @@ -54,7 +55,7 @@ public: \internal */ QtxActionMenuMgr::MenuNode::MenuNode() -: parent( 0 ), id( -1 ), idx( -1 ), group( -1 ), visible( true ) + : parent( 0 ), id( -1 ), idx( -1 ), group( -1 ), visible( true ), emptyEnabled( 0 ) { } @@ -70,7 +71,7 @@ QtxActionMenuMgr::MenuNode::MenuNode( MenuNode* p, const int _id, const int _idx, const int _group ) -: parent( p ), id( _id ), idx( _idx ), group( _group ), visible( true ) +: parent( p ), id( _id ), idx( _idx ), group( _group ), visible( true ), emptyEnabled( 0 ) { if ( p ) p->children.append( this ); @@ -139,8 +140,9 @@ QtxActionMenuMgr::~QtxActionMenuMgr() { for ( MenuMap::Iterator itr = myMenus.begin(); itr != myMenus.end(); ++itr ) { - delete itr.value()->menu(); - delete itr.value(); + QPointer a = itr.value(); + delete a->menu(); + delete a; } delete myRoot; @@ -327,8 +329,9 @@ int QtxActionMenuMgr::insert( const QString& title, const int pId, const int gro int gid = (id == -1 || eNode ) ? generateId() : id; - QAction* ma = new QAction( title, this ); - ma->setMenu( new QMenu( 0 ) ); + QMenu* menu = new QMenu( 0 ); + QAction* ma = menu->menuAction(); + ma->setText( title ); connect( ma->menu(), SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) ); connect( ma->menu(), SIGNAL( aboutToHide() ), this, SLOT( onAboutToHide() ) ); @@ -853,17 +856,40 @@ void QtxActionMenuMgr::updateMenu( MenuNode* startNode, const bool rec, const bo bool filled = checkWidget( mw ); - for ( NodeList::iterator it1 = node->children.begin(); it1 != node->children.end(); ++it1 ) + // first remove all own actions and collect foreign ones + QMap< QAction*, QList > foreign; + QAction* a; + QAction* preva = 0; + QListIterator ait( mw->actions() ); ait.toBack(); + while ( ait.hasPrevious() ) { - QAction* a = itemAction( (*it1)->id ); - if ( !a ) - a = menuAction( (*it1)->id ); - - mw->removeAction( a ); -// if ( a ) -// a->removeFrom( mw ); + a = ait.previous(); + if ( ownAction( a, node ) ) + { + preva = a; + mw->removeAction( a ); // remove own actions + } + else + { + foreign[preva].prepend(a); // do not yet remove foreign actions + } } + // now only foreign actions should stay in the menu, thus remove them also + QMap< QAction*, QList >::Iterator formapit; + for( formapit = foreign.begin(); formapit != foreign.end(); ++formapit ) + { + QMutableListIterator foralit( formapit.value() ); + while ( foralit.hasNext() ) + { + a = foralit.next(); + if ( !mw->actions().contains( a ) ) + foralit.remove(); + } + } + QList alist = mw->actions(); + foreach( a, alist ) mw->removeAction( a ); + // collect all registered menus by group id QMap idMap; for ( NodeList::iterator it2 = node->children.begin(); it2 != node->children.end(); ++it2 ) { @@ -881,6 +907,7 @@ void QtxActionMenuMgr::updateMenu( MenuNode* startNode, const bool rec, const bo groups.removeAll( -1 ); groups.append( -1 ); + // rebuild menu: 1. add all registered actions for ( QIntList::const_iterator gIt = groups.begin(); gIt != groups.end(); ++gIt ) { if ( !idMap.contains( *gIt ) ) @@ -890,6 +917,7 @@ void QtxActionMenuMgr::updateMenu( MenuNode* startNode, const bool rec, const bo for ( NodeList::const_iterator iter = lst.begin(); iter != lst.end(); ++iter ) { MenuNode* node = *iter; + if ( !node ) continue; if ( rec ) updateMenu( node, rec, false ); @@ -905,14 +933,24 @@ void QtxActionMenuMgr::updateMenu( MenuNode* startNode, const bool rec, const bo isMenu = true; a = menuAction( node->id ); } + if ( !a ) continue; - if ( !isMenu || !a->menu()->isEmpty() ) + if ( !isMenu || !a->menu()->isEmpty() || node->emptyEnabled > 0 ) mw->addAction( a ); } } + // rebuild menu: 2. insert back all foreign actions + for( formapit = foreign.begin(); formapit != foreign.end(); ++formapit ) { + preva = formapit.key(); + foreach( a, formapit.value() ) + mw->insertAction( preva, a ); + } + + // remove extra separators simplifySeparators( mw ); + // update parent menu if necessary if ( updParent && node->parent && filled != checkWidget( mw ) ) updateMenu( node->parent, false ); } @@ -931,6 +969,24 @@ void QtxActionMenuMgr::internalUpdate() myUpdateIds.clear(); } +/*! + \brief Check if action belongs to the menu manager + \internal + \param a action being checked + \param node parent menu node + \return \c true if action belongs to the menu \a node +*/ +bool QtxActionMenuMgr::ownAction( QAction* a, MenuNode* node ) const +{ + for ( NodeList::const_iterator iter = node->children.begin(); iter != node->children.end(); ++iter ) + { + QAction* mya = itemAction( (*iter)->id ); + if ( !mya ) mya = menuAction( (*iter)->id ); + if ( mya && mya == a ) return true; + } + return false; +} + /*! \brief Check if menu widget has any actions. \param wid widget to be checked @@ -1057,6 +1113,56 @@ QMenu* QtxActionMenuMgr::findMenu( const int id ) const return m; } +/*! + \brief Get menu by the title. + \param title menu text + \param pid parent menu item ID (to start search) + \param rec if \c true, perform recursive update + \return menu pointer or 0 if menu is not found +*/ +QMenu* QtxActionMenuMgr::findMenu( const QString& title, const int pid, const bool rec ) const +{ + QMenu* m = 0; + MenuNode* node = find( title, pid, rec ); + if ( node ) + { + QAction* a = menuAction( node->id ); + if ( a ) + m = a->menu(); + } + return m; +} + +/*! + \brief Check if empty menu is enabled + \param id menu item ID + \return \c true if empty menu is enabled +*/ +bool QtxActionMenuMgr::isEmptyEnabled( const int id ) const +{ + MenuNode* node = find( id ); + if ( node && menuAction( id ) ) + return node->emptyEnabled > 0; + + return false; +} + +/*! + \brief Enable/disable empty menu + \param id menu item ID + \param enable if \c true, empty menu will be enabled, otherwise empty menu will be disabled +*/ +void QtxActionMenuMgr::setEmptyEnabled( const int id, const bool enable ) +{ + MenuNode* node = find( id ); + if ( node && menuAction( id ) ) { + int old = node->emptyEnabled; + node->emptyEnabled += enable ? 1 : -1; + if ( old <= 0 && enable || old > 0 && !enable ) // update menu only if enabled state has been changed + updateMenu( node, true, true ); + } +} + /*! \brief Perform delayed menu update. \param id menu item ID diff --git a/src/Qtx/QtxActionMenuMgr.h b/src/Qtx/QtxActionMenuMgr.h index 1f5079161..6ee27cf61 100644 --- a/src/Qtx/QtxActionMenuMgr.h +++ b/src/Qtx/QtxActionMenuMgr.h @@ -94,6 +94,10 @@ public: bool containsMenu( const int, const int, const bool = false ) const; QMenu* findMenu( const int ) const; + QMenu* findMenu( const QString&, const int, const bool = false ) const; + + bool isEmptyEnabled( const int ) const; + void setEmptyEnabled( const int, const bool ); private slots: void onAboutToShow(); @@ -126,6 +130,7 @@ protected: virtual void updateContent(); private: + bool ownAction( QAction*, MenuNode* ) const; bool checkWidget( QWidget* ) const; QWidget* menuWidget( MenuNode* ) const; void simplifySeparators( QWidget* ); diff --git a/src/Qtx/QtxActionToolMgr.cxx b/src/Qtx/QtxActionToolMgr.cxx index e2c4b2048..cf02d31d7 100644 --- a/src/Qtx/QtxActionToolMgr.cxx +++ b/src/Qtx/QtxActionToolMgr.cxx @@ -102,10 +102,9 @@ int QtxActionToolMgr::createToolBar( const QString& title, const int tid, QMainW int tbId = -1; for ( ToolBarMap::ConstIterator it = myToolBars.begin(); it != myToolBars.end() && tbId == -1; ++it ) { - // 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( it.value().toolBar->windowTitle().toLower() == title.toLower() && + ( !mw || it.value().toolBar->parent()==mw ) ) + tbId = it.key(); } if ( tbId != -1 ) @@ -122,10 +121,11 @@ int QtxActionToolMgr::createToolBar( const QString& title, const int tid, QMainW if ( !tb ) { tb = new QtxToolBar( true, tbw ); - mainWindow()->addToolBar( tb ); + //mainWindow()->addToolBar( tb ); tb->setWindowTitle( title ); tb->setObjectName( title ); - } + tb->setToolTip( title ); + } tInfo.toolBar = tb; connect( tInfo.toolBar, SIGNAL( destroyed() ), this, SLOT( onToolBarDestroyed() ) ); @@ -503,6 +503,11 @@ void QtxActionToolMgr::updateToolBar( const int tid ) } simplifySeparators( tb ); + + // fix of 19921 --> + if ( !tb->isVisible() ) + tb->adjustSize(); + // fix of 19921 <-- } /*! diff --git a/src/Qtx/QtxColorScale.cxx b/src/Qtx/QtxColorScale.cxx index b7dbf558a..44589c9c1 100755 --- a/src/Qtx/QtxColorScale.cxx +++ b/src/Qtx/QtxColorScale.cxx @@ -698,6 +698,17 @@ void QtxColorScale::hide() QFrame::hide(); } +/*! + \brief Paint widget + \param e paint event +*/ +void QtxColorScale::paintEvent( QPaintEvent* e ) +{ + QPainter p( this ); + drawFrame( &p ); + drawContents( &p ); +} + /*! \brief Draw color scale (reimplemented from QFrame). \param p painter diff --git a/src/Qtx/QtxColorScale.h b/src/Qtx/QtxColorScale.h index 453aeefe6..10014c8d9 100755 --- a/src/Qtx/QtxColorScale.h +++ b/src/Qtx/QtxColorScale.h @@ -123,6 +123,7 @@ public: virtual void hide(); protected: + virtual void paintEvent( QPaintEvent* ); virtual void drawContents( QPainter* ); private: diff --git a/src/Qtx/QtxComboBox.cxx b/src/Qtx/QtxComboBox.cxx index 817138c96..831cb18c5 100755 --- a/src/Qtx/QtxComboBox.cxx +++ b/src/Qtx/QtxComboBox.cxx @@ -21,7 +21,96 @@ #include "QtxComboBox.h" +#include #include +#include +#include + +/*! + \class QtxComboBox::Model + \brief Internal view model, used to process 'cleared' state of the combo box. + \internal +*/ +class QtxComboBox::Model : public QStandardItemModel +{ +public: + Model( QObject* parent = 0 ); + ~Model(); + void setCleared( const bool ); + + QVariant data( const QModelIndex&, int = Qt::DisplayRole ) const; + +private: + bool myCleared; +}; + +/*! + \brief Constructor + \internal + \param parent parent object +*/ +QtxComboBox::Model::Model( QObject* parent ) + : QStandardItemModel( 0, 1, parent ), + myCleared( false ) +{ +} + +/*! + \brief Destructor + \internal +*/ +QtxComboBox::Model::~Model() +{ +} + +/*! + \brief Set 'cleared' state + \param isClear new 'cleared' state + \internal +*/ +void QtxComboBox::Model::setCleared( const bool isClear ) +{ + if ( myCleared == isClear ) + return; + + myCleared = isClear; +} + +/*! + \brief Get model data. + \param index model index + \param role data role + \return data of role \a role for the \a index + \internal +*/ +QVariant QtxComboBox::Model::data( const QModelIndex& index, int role ) const +{ + return ( myCleared && ( role == Qt::DisplayRole || role == Qt::DecorationRole ) ) ? + QVariant() : QStandardItemModel::data( index, role ); +} + +/*! + \class QtxComboBox::ClearEvent + \brief Custom event, used to process 'cleared' state of the combo box + in the editable mode. + \internal +*/ + +#define CLEAR_EVENT QEvent::Type( QEvent::User + 123 ) + +class QtxComboBox::ClearEvent : public QEvent +{ +public: + ClearEvent(); +}; + +/*! + \brief Constructor + \internal +*/ +QtxComboBox::ClearEvent::ClearEvent() : QEvent( CLEAR_EVENT ) +{ +} /*! \class QtxComboBox @@ -41,8 +130,9 @@ QtxComboBox::QtxComboBox( QWidget* parent ) : QComboBox( parent ), myCleared( false ) { - connect( this, SIGNAL( activated( int ) ), this, SLOT( onActivated( int ) ) ); - connect( this, SIGNAL( activated( const QString& ) ), this, SLOT( onActivated( const QString& ) ) ); + connect( this, SIGNAL( activated( int ) ), this, SLOT( onActivated( int ) ) ); + connect( this, SIGNAL( currentIndexChanged( int ) ), this, SLOT( onCurrentChanged( int ) ) ); + setModel( new Model( this ) ); } /*! @@ -73,32 +163,11 @@ void QtxComboBox::setCleared( const bool isClear ) return; myCleared = isClear; - - if ( isEditable() ) - { - if ( myCleared ) - lineEdit()->setText( "" ); - else - lineEdit()->setText( itemText( currentIndex() ) ); - } - - update(); -} - -/*! - \brief Set current item. - Does nothing if the item index is out of range. + if ( lineEdit() ) + lineEdit()->setText( myCleared ? QString( "" ) : itemText( currentIndex() ) ); - \param idx item index -*/ -void QtxComboBox::setCurrentIndex( int idx ) -{ - if ( idx < 0 || idx >= count() ) - return; - - myCleared = false; - QComboBox::setCurrentIndex( idx ); + update(); } /*! @@ -135,10 +204,32 @@ void QtxComboBox::setId( const int index, const int id ) */ void QtxComboBox::paintEvent( QPaintEvent* e ) { - if ( !count() || !myCleared || isEditable() ) - QComboBox::paintEvent( e ); - else - paintClear( e ); + Model* m = dynamic_cast( model() ); + if ( m ) + m->setCleared( myCleared ); + QComboBox::paintEvent( e ); + if ( m ) + m->setCleared( false ); +} + +/*! + \brief Customize child addition/removal event + \param e child event +*/ +void QtxComboBox::childEvent( QChildEvent* e ) +{ + if ( ( e->added() || e->polished() ) && qobject_cast( e->child() ) ) + QApplication::postEvent( this, new ClearEvent() ); +} + +/*! + \brief Process custom events + \param e custom event +*/ +void QtxComboBox::customEvent( QEvent* e ) +{ + if ( e->type() == CLEAR_EVENT && lineEdit() && myCleared ) + lineEdit()->setText( "" ); } /*! @@ -148,17 +239,17 @@ void QtxComboBox::paintEvent( QPaintEvent* e ) void QtxComboBox::onActivated( int idx ) { resetClear(); - emit activatedId( id( idx ) ); } /*! - \brief Called when any item is activated by the user. - \param txt activated item text (not used) + \brief Called when current item is chaned (by the user or programmatically). + \param idx item being set current */ -void QtxComboBox::onActivated( const QString& /*txt*/ ) +void QtxComboBox::onCurrentChanged( int idx ) { - resetClear(); + if ( idx != -1 ) + resetClear(); } /*! @@ -173,30 +264,6 @@ void QtxComboBox::resetClear() update(); } -/*! - \brief Draw combobox in the "cleared" state. - \param e paint event -*/ -void QtxComboBox::paintClear( QPaintEvent* e ) -{ - int curIndex = currentIndex(); - QString curText = itemText( curIndex ); - QIcon curIcon = itemIcon( curIndex ); - - bool upd = updatesEnabled(); - setUpdatesEnabled( false ); - - setItemIcon( curIndex, QIcon() ); - setItemText( curIndex, QString() ); - - QComboBox::paintEvent( e ); - - setItemText( curIndex, curText ); - setItemIcon( curIndex, curIcon ); - - setUpdatesEnabled( upd ); -} - /*! \brief Get item ID by the index. \param idx item index @@ -242,9 +309,3 @@ bool QtxComboBox::hasId( const int idx ) const \brief Emitted when the item with identificator \a id is activated. \param id item ID */ - -/*! - \fn void QtxComboBox::highlightedId( int id ) - \brief Emitted when the item with identificator \a id is highlighted. - \param id item ID -*/ diff --git a/src/Qtx/QtxComboBox.h b/src/Qtx/QtxComboBox.h index c821ffaed..f1b4f91ec 100755 --- a/src/Qtx/QtxComboBox.h +++ b/src/Qtx/QtxComboBox.h @@ -35,6 +35,9 @@ class QTX_EXPORT QtxComboBox : public QComboBox { Q_OBJECT + class Model; + class ClearEvent; + public: QtxComboBox( QWidget* = 0 ); virtual ~QtxComboBox(); @@ -42,8 +45,6 @@ public: bool isCleared() const; void setCleared( const bool ); - virtual void setCurrentIndex( int ); - int currentId() const; void setCurrentId( int ); @@ -55,18 +56,18 @@ public: signals: void activatedId( int ); - void highlightedId( int ); private slots: void onActivated( int ); - void onActivated( const QString& ); + void onCurrentChanged( int ); protected: virtual void paintEvent( QPaintEvent* ); + virtual void childEvent( QChildEvent* ); + virtual void customEvent( QEvent* ); private: void resetClear(); - void paintClear( QPaintEvent* ); private: enum { IdRole = Qt::UserRole + 10 }; diff --git a/src/Qtx/QtxIntSpinBox.cxx b/src/Qtx/QtxIntSpinBox.cxx index 175a297ae..b4cff2238 100755 --- a/src/Qtx/QtxIntSpinBox.cxx +++ b/src/Qtx/QtxIntSpinBox.cxx @@ -57,6 +57,7 @@ QtxIntSpinBox::QtxIntSpinBox( QWidget* parent ) : QSpinBox( parent ), myCleared( false ) { + setCorrectionMode( QSpinBox::CorrectToNearestValue ); connect( lineEdit(), SIGNAL( textChanged( const QString& ) ), this, SLOT( onTextChanged( const QString& ) ) ); } @@ -79,6 +80,7 @@ QtxIntSpinBox::QtxIntSpinBox( int min, int max, int step, QWidget* parent ) setMinimum( min ); setMaximum( max ); setSingleStep( step ); + setCorrectionMode( QSpinBox::CorrectToNearestValue ); connect( lineEdit(), SIGNAL( textChanged( const QString& ) ), this, SLOT( onTextChanged( const QString& ) ) ); diff --git a/src/Qtx/QtxListAction.cxx b/src/Qtx/QtxListAction.cxx index fff34a603..44961ddb8 100755 --- a/src/Qtx/QtxListAction.cxx +++ b/src/Qtx/QtxListAction.cxx @@ -616,11 +616,6 @@ QtxListAction::QtxListAction( const QString& text, const QString& menuText, : QtxAction( text, menuText, accel, parent ), myFrame( 0 ) { - setText( menuText ); - setShortcut( accel ); - setToolTip( text ); - setStatusTip( text ); - initialize(); } @@ -637,12 +632,6 @@ QtxListAction::QtxListAction( const QString& text, const QIcon& icon, : QtxAction( text, icon, menuText, accel, parent ), myFrame( 0 ) { - setIcon( icon ); - setText( menuText ); - setShortcut( accel ); - setToolTip( text ); - setStatusTip( text ); - initialize(); } diff --git a/src/Qtx/QtxMRUAction.cxx b/src/Qtx/QtxMRUAction.cxx index c3767ca5f..5ee95779f 100755 --- a/src/Qtx/QtxMRUAction.cxx +++ b/src/Qtx/QtxMRUAction.cxx @@ -36,13 +36,19 @@ \param parent parent object */ QtxMRUAction::QtxMRUAction( QObject* parent ) -: QtxAction( "Most Recently Used", "Most Recently Used", 0, parent ), +: QtxAction( tr( "Most Recently Used" ), tr( "Most Recently Used" ), 0, parent ), myVisCount( 5 ), + myHistoryCount( -1 ), myLinkType( LinkAuto ), myInsertMode( MoveFirst ) { + myClear = new QAction( tr( "Clear" ), this ); + myClear->setVisible( false ); + setMenu( new QMenu( 0 ) ); + connect( menu(), SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) ); + connect( myClear, SIGNAL( triggered( bool ) ), this, SLOT( onCleared( bool ) ) ); } /*! @@ -54,11 +60,16 @@ QtxMRUAction::QtxMRUAction( QObject* parent ) QtxMRUAction::QtxMRUAction( const QString& text, const QString& menuText, QObject* parent ) : QtxAction( text, menuText, 0, parent ), myVisCount( 5 ), + myHistoryCount( -1 ), myLinkType( LinkAuto ), myInsertMode( MoveFirst ) { + myClear = new QAction( tr( "Clear" ), this ); + myClear->setVisible( false ); + setMenu( new QMenu( 0 ) ); connect( menu(), SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) ); + connect( myClear, SIGNAL( triggered( bool ) ), this, SLOT( onCleared( bool ) ) ); } /*! @@ -72,11 +83,16 @@ QtxMRUAction::QtxMRUAction( const QString& text, const QIcon& icon, const QString& menuText, QObject* parent ) : QtxAction( text, icon, menuText, 0, parent ), myVisCount( 5 ), + myHistoryCount( -1 ), myLinkType( LinkAuto ), myInsertMode( MoveFirst ) { + myClear = new QAction( tr( "Clear" ), this ); + myClear->setVisible( false ); + setMenu( new QMenu( 0 ) ); connect( menu(), SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) ); + connect( myClear, SIGNAL( triggered( bool ) ), this, SLOT( onCleared( bool ) ) ); } /*! @@ -169,6 +185,48 @@ void QtxMRUAction::setVisibleCount( int num ) myVisCount = num; } +/*! + \brief Return visible status of the menu item which clear all MRU items. +*/ +bool QtxMRUAction::isClearPossible() const +{ + return myClear->isVisible(); +} + +/*! + \brief Set visible the menu item which clear all MRU items. +*/ +void QtxMRUAction::setClearPossible( const bool on ) +{ + myClear->setVisible( on ); +} + +/*! + \brief Get number of totally stored MRU items. + \return number of MRU items stored in the preferences + \sa setHistoryCount(), saveLinks(), loadLinks() +*/ +int QtxMRUAction::historyCount() const +{ + return myHistoryCount; +} + +/*! + \brief Set number of totally stored MRU items. + + This option allows setting number of MRU items to be stored + in the preferences file. + + If \a num < 0, then number of stored MRU items is not limited. + + \return number of MRU items stored in the preferences + \sa historyCount(), saveLinks(), loadLinks() +*/ +void QtxMRUAction::setHistoryCount( const int num ) +{ + myHistoryCount = num; +} + /*! \brief Insert MRU item. @@ -223,6 +281,14 @@ void QtxMRUAction::remove( const QString& link ) myLinks.removeAll( link ); } +/*! + \brief Remove all MRU items. +*/ +void QtxMRUAction::clear() +{ + myLinks.clear(); +} + /*! \brief Get MRU item \param idx MRU item index @@ -302,8 +368,16 @@ void QtxMRUAction::saveLinks( QtxResourceMgr* resMgr, const QString& section, co if ( !resMgr || section.isEmpty() ) return; - if ( clear ) - resMgr->remove( section ); + QString itemPrefix( "item_" ); + + if ( clear ) { + QStringList items = resMgr->parameters( section ); + for ( QStringList::const_iterator it = items.begin(); it != items.end(); ++it ) + { + if ( (*it).startsWith( itemPrefix ) ) + resMgr->remove( section, *it ); + } + } QStringList lst; QMap map; @@ -313,7 +387,6 @@ void QtxMRUAction::saveLinks( QtxResourceMgr* resMgr, const QString& section, co map.insert( *itr, 0 ); } - QString itemPrefix( "item_" ); QStringList items = resMgr->parameters( section ); for ( QStringList::const_iterator it = items.begin(); it != items.end(); ++it ) { @@ -331,7 +404,9 @@ void QtxMRUAction::saveLinks( QtxResourceMgr* resMgr, const QString& section, co } int counter = 0; - for ( QStringList::const_iterator iter = lst.begin(); iter != lst.end(); ++iter, counter++ ) + for ( QStringList::const_iterator iter = lst.begin(); + iter != lst.end() && ( myHistoryCount < 0 || counter < myHistoryCount ); + ++iter, counter++ ) resMgr->setValue( section, itemPrefix + QString().sprintf( "%03d", counter ), *iter ); } @@ -362,6 +437,11 @@ void QtxMRUAction::onActivated() emit activated( link ); } +void QtxMRUAction::onCleared( bool ) +{ + clear(); +} + /*! \brief Update MRU items popup menu. */ @@ -376,12 +456,13 @@ void QtxMRUAction::updateMenu() 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-- ) + int i = insertMode() == AddLast || insertMode() == MoveLast ? qMax( 0, myLinks.count()-count ) : 0; + for ( ; i < myLinks.count() && count > 0; ++i, count-- ) { - links.append( *it ); + links.append( myLinks[i] ); if ( linkType() == LinkAuto ) { - QString shortName = Qtx::file( *it ); + QString shortName = Qtx::file( myLinks[i] ); if ( map.contains( shortName ) ) map[shortName]++; else @@ -389,7 +470,7 @@ void QtxMRUAction::updateMenu() } } - int i = 1; + i = 1; for ( QStringList::const_iterator it = links.begin(); it != links.end(); ++it, i++ ) { QString linkName; @@ -417,6 +498,13 @@ void QtxMRUAction::updateMenu() if ( pm->isEmpty() ) pm->addAction( tr( "" ) )->setEnabled( false ); + + if ( isClearPossible() ) + { + pm->addSeparator(); + pm->addAction( myClear ); + myClear->setEnabled( !pm->isEmpty() ); + } } /*! diff --git a/src/Qtx/QtxMRUAction.h b/src/Qtx/QtxMRUAction.h index 708383f43..f07f4fc46 100755 --- a/src/Qtx/QtxMRUAction.h +++ b/src/Qtx/QtxMRUAction.h @@ -67,6 +67,12 @@ public: int visibleCount() const; void setVisibleCount( const int ); + bool isClearPossible() const; + void setClearPossible( const bool ); + + int historyCount() const; + void setHistoryCount( const int ); + void remove( const int ); void remove( const QString& ); void insert( const QString& ); @@ -78,19 +84,25 @@ public: virtual void loadLinks( QtxResourceMgr*, const QString&, const bool = true ); virtual void saveLinks( QtxResourceMgr*, const QString&, const bool = true ) const; +public slots: + void clear(); + signals: void activated( const QString& ); private slots: void onActivated(); void onAboutToShow(); + void onCleared( bool ); private: void updateMenu(); private: QStringList myLinks; //!< most recent used items + QAction* myClear; //!< clear item int myVisCount; //!< number of visible MRU items + int myHistoryCount; //!< number of stored MRU items int myLinkType; //!< type of link names in menu int myInsertMode; //!< items insertion policy }; diff --git a/src/Qtx/QtxPopupMgr.cxx b/src/Qtx/QtxPopupMgr.cxx index 36ecc8011..970b2676f 100644 --- a/src/Qtx/QtxPopupMgr.cxx +++ b/src/Qtx/QtxPopupMgr.cxx @@ -39,13 +39,10 @@ bool operator<( const QVariant& v1, const QVariant& v2 ) { case QVariant::Int: return v1.toInt() < v2.toInt(); - break; case QVariant::Double: return v1.toDouble() < v2.toDouble(); - break; case QVariant::String: return v1.toString() < v2.toString(); - break; case QVariant::StringList: case QVariant::List: { @@ -58,15 +55,12 @@ bool operator<( const QVariant& v1, const QVariant& v2 ) return (*anIt1)<(*anIt2); } return anIt1 == aLast1 && anIt2 != aLast2; - break; } default: return v1.toString() < v2.toString(); - break; } } - else - return t1 < t2; + return t1 < t2; } /*! diff --git a/src/Qtx/QtxResourceMgr.cxx b/src/Qtx/QtxResourceMgr.cxx index 6a83b7b56..273c49159 100644 --- a/src/Qtx/QtxResourceMgr.cxx +++ b/src/Qtx/QtxResourceMgr.cxx @@ -20,12 +20,12 @@ // Author: Alexander SOLOVYOV, Sergey TELKOV #include "QtxResourceMgr.h" +#include "QtxTranslator.h" #include #include #include #include -#include #include #ifndef QT_NO_DOM #include @@ -387,47 +387,9 @@ QPixmap QtxResourceMgr::Resources::loadPixmap( const QString& sect, const QStrin */ QTranslator* QtxResourceMgr::Resources::loadTranslator( const QString& sect, const QString& prefix, const QString& name ) const { - QTranslator* trans = new QTranslator( 0 ); + QTranslator* trans = new QtxTranslator( 0 ); QString fname = fileName( sect, prefix, name ); -#ifdef EMULATE_GLOBAL_CONTEXT - char* buf = 0; - QFile file( fname ); - int len = file.size(); - if ( len ) - { - buf = new char[len]; - if ( !file.open( QIODevice::ReadOnly ) || len != (int)file.read( buf, len ) ) - { - delete buf; - buf = 0; - } - file.close(); - } - if ( buf ) - { - char* pattern = "@default"; - size_t pl = strlen( pattern ); - for ( size_t i = 0; i < len - pl; i++ ) - { - char* cur = buf + i; - if ( !strncmp( cur, pattern, pl ) ) - { - *cur = '\0'; - i += pl - 1; - } - } - - if ( !trans->load( (uchar*)buf, len ) ) - { - delete buf; - buf = 0; - } - } - - if ( !buf ) -#else if ( !trans->load( Qtx::file( fname, false ), Qtx::dir( fname ) ) ) -#endif { delete trans; trans = 0; diff --git a/src/Qtx/QtxRubberBand.cxx b/src/Qtx/QtxRubberBand.cxx new file mode 100755 index 000000000..1fb2fad37 --- /dev/null +++ b/src/Qtx/QtxRubberBand.cxx @@ -0,0 +1,313 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File: QtxRubberBand.cxx +// Author: Alexander A. BORODIN +// + +#include "QtxRubberBand.h" + +#include +#include +#include +#include +#include +#include +#include + +/*! + \class QtxAbstractRubberBand + \brief Analog of class QRubberBand with possibility of creation non-rectangular contour for selection. + + Currently this class does not support Style functionality in full. +*/ + +/*! + \brief Constructor + \param theParent parent widget + */ + +QtxAbstractRubberBand::QtxAbstractRubberBand( QWidget* theParent) + : QWidget( theParent/*,Qt::ToolTip*/ ), + myPoints(), + myIsClosed( false ) +{ + setAttribute(Qt::WA_TransparentForMouseEvents); +#ifndef WIN32 + setAttribute(Qt::WA_NoSystemBackground); +#endif //WIN32 + setAttribute(Qt::WA_WState_ExplicitShowHide); + setVisible(false); + theParent->installEventFilter(this); + setGeometry( QRect(QPoint(0,0), theParent->size() ) ); +} + +/*! + \brief Destructor + */ +QtxAbstractRubberBand::~QtxAbstractRubberBand() +{ +} + +void QtxAbstractRubberBand::clearGeometry() +{ + myPoints.clear(); +} + +bool QtxAbstractRubberBand::isClosed() +{ + return myIsClosed; +} + +void QtxAbstractRubberBand::paintEvent( QPaintEvent* theEvent ) +{ + if ( !myPoints.empty() ) + { + QPixmap tiledPixmap(16, 16); + + QPainter pixmapPainter(&tiledPixmap); + pixmapPainter.setPen(Qt::NoPen); + pixmapPainter.setBrush(QBrush( Qt::black, Qt::Dense4Pattern )); + pixmapPainter.setBackground(QBrush( Qt::white )); + pixmapPainter.setBackgroundMode(Qt::OpaqueMode); + pixmapPainter.drawRect(0, 0, tiledPixmap.width(), tiledPixmap.height()); + pixmapPainter.end(); + // ### workaround for borked XRENDER + tiledPixmap = QPixmap::fromImage(tiledPixmap.toImage()); + + + + QPainter aPainter( this ); + aPainter.setRenderHint( QPainter::Antialiasing ); + QRect r = myPoints.boundingRect(); + aPainter.setClipRegion( r.normalized().adjusted( -1, -1, 2, 2 ) ); + aPainter.drawTiledPixmap( 0, 0, width(), height(), tiledPixmap); + + aPainter.end(); + + /* + + + +#ifdef WIN32 + QPixmap anImage( size() ); +#else + QImage anImage( size(), QImage::Format_ARGB32_Premultiplied ); +#endif + + anImage.fill( Qt::transparent ); + QPainter aImgPainter( &anImage ); + aImgPainter.setRenderHint( QPainter::Antialiasing ); + aImgPainter.setCompositionMode(QPainter::CompositionMode_Source); + + QPen aPen( Qt::black ); + aPen.setWidth( 2 ); + aImgPainter.setPen( aPen ); + + aImgPainter.drawPolyline( myPoints ); + if ( myIsClosed && myPoints.last() != myPoints.first() ) + aImgPainter.drawLine( myPoints.last(), myPoints.first() ); + + //aImgPainter.setPen(Qt::NoPen); + //aImgPainter.setBrush(QBrush( Qt::white, Qt::Dense4Pattern)); + //aImgPainter.setCompositionMode(QPainter::CompositionMode_SourceAtop); + //aImgPainter.drawRect(0, 0, width(), height()); + aImgPainter.end(); + + QPainter aPainter( this ); + aPainter.drawPolyline( myPoints ); + if ( myIsClosed && myPoints.last() != myPoints.first() ) + aPainter.drawLine( myPoints.last(), myPoints.first() ); + +#ifdef WIN32 + aPainter.drawPixmap( 0, 0, anImage ); +#else + aPainter.drawImage( 0, 0, anImage ); + #endif + aPainter.end();*/ + + } +} + +void QtxAbstractRubberBand::showEvent( QShowEvent* theEvent ) +{ + raise(); + theEvent->ignore(); +} + +void QtxAbstractRubberBand::moveEvent( QMoveEvent* ) +{ +} + +void QtxAbstractRubberBand::resizeEvent( QResizeEvent* ) +{ +} + +bool QtxAbstractRubberBand::eventFilter( QObject* obj, QEvent* e ) +{ + if ( obj && obj == parent() && e->type() == QEvent::Resize ) + { + QWidget* p = (QWidget*)parent(); + setGeometry( QRect(QPoint(0,0), p->size() ) ); + } + return QWidget::eventFilter( obj, e ); +} + +QRegion createRegion( const QPointF& p1, const QPointF& p2 ) +{ + if ( p1 == p2 ) + return QRegion(); + + QLineF n = QLineF( p1, p2 ).normalVector();//.unitVector(); + n.setLength( 1 ); + n.translate( p1 * -1 ); + QPointF nPoint = n.p2(); + + QPolygonF p; + p << p1 + nPoint << p2 + nPoint << p2 - nPoint << p1 - nPoint << p1 + nPoint; + + return QRegion( p.toPolygon() ); +} + +void QtxAbstractRubberBand::updateMask() +{ + QRegion r; + + QVectorIterator it(myPoints); + while( it.hasNext() ) + { + QPoint p = it.next(); + if( !it.hasNext() ) + break; + + QPoint np = it.peekNext(); + + if ( p == np ) continue; + + r += createRegion( p, np ); + } + + if ( isClosed() ) + r += createRegion( myPoints.last(), myPoints.first() ); + + setMask( r ); + +} + + +QtxRectRubberBand::QtxRectRubberBand(QWidget* parent) + :QtxAbstractRubberBand( parent ) +{ + myPoints.resize( 4 ); + myIsClosed = true; +} + +QtxRectRubberBand::~QtxRectRubberBand() +{ +} + +void QtxRectRubberBand::initGeometry( const QRect& theRect ) +{ + myPoints.clear(); + myPoints << theRect.topLeft() << theRect.topRight() << theRect.bottomRight() << theRect.bottomLeft(); + //setMask( QRegion( myPoints ) ); + updateMask(); +} + +void QtxRectRubberBand::setStartPoint( const QPoint& thePoint ) +{ + myPoints[0] = thePoint; + myPoints[1].setY( thePoint.y() ); + myPoints[3].setX( thePoint.x() ); + updateMask(); +} + +void QtxRectRubberBand::setEndPoint( const QPoint& thePoint) +{ + myPoints[2] = thePoint; + myPoints[1].setX( thePoint.x() ); + myPoints[3].setY( thePoint.y() ); + updateMask(); +} + +void QtxRectRubberBand::clearGeometry() +{ + QMutableVectorIterator i(myPoints); + while (i.hasNext()) + { + i.next(); + i.setValue( QPoint( -1, -1 ) ); + } +} + + +QtxPolyRubberBand::QtxPolyRubberBand(QWidget* parent) + :QtxAbstractRubberBand( parent ) +{ +} + +QtxPolyRubberBand::~QtxPolyRubberBand() +{ +} + +void QtxPolyRubberBand::initGeometry( const QPolygon& thePoints ) +{ + myPoints = thePoints; + updateMask(); +} + +void QtxPolyRubberBand::initGeometry( const QPoint& thePoint ) +{ + myPoints.clear(); + myPoints << thePoint; + updateMask(); +} + +void QtxPolyRubberBand::addNode( const QPoint& thePoint ) +{ + myPoints << thePoint; + updateMask(); +} + +void QtxPolyRubberBand::replaceLastNode( const QPoint& thePoint ) +{ + if ( !myPoints.empty() ) + { + myPoints.pop_back(); + myPoints << thePoint; + updateMask(); + } +} + +void QtxPolyRubberBand::removeLastNode() +{ + if ( !myPoints.empty() ) + { + myPoints.pop_back(); + updateMask(); + } +} + +void QtxPolyRubberBand::setClosed( bool theFlag ) +{ + if (myIsClosed != theFlag ) + { + myIsClosed = theFlag; + updateMask(); + } +} diff --git a/src/Qtx/QtxRubberBand.h b/src/Qtx/QtxRubberBand.h new file mode 100755 index 000000000..e16426167 --- /dev/null +++ b/src/Qtx/QtxRubberBand.h @@ -0,0 +1,89 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File: QtxRubberBand.h +// Author: Alexander A. BORODIN +// + +#ifndef QTXRUBBERBAND_H +#define QTXRUBBERBAND_H + +#include "Qtx.h" + +#include + +class QTX_EXPORT QtxAbstractRubberBand: public QWidget +{ +protected: + QtxAbstractRubberBand( QWidget* ); + +public: + virtual ~QtxAbstractRubberBand(); + + virtual void clearGeometry(); + + bool isClosed(); + +protected: + virtual void paintEvent( QPaintEvent* ); + virtual void showEvent( QShowEvent* ); + virtual void moveEvent( QMoveEvent* ); + virtual void resizeEvent( QResizeEvent* ); + + virtual bool eventFilter( QObject*, QEvent* ); + + virtual void updateMask(); + +protected: + QPolygon myPoints; + + bool myIsClosed; +}; + +class QTX_EXPORT QtxRectRubberBand: public QtxAbstractRubberBand +{ +public: + + QtxRectRubberBand( QWidget* ); + virtual ~QtxRectRubberBand(); + + void initGeometry( const QRect& ); + void setStartPoint( const QPoint& ); + void setEndPoint( const QPoint& ); + + virtual void clearGeometry(); +}; + +class QTX_EXPORT QtxPolyRubberBand: public QtxAbstractRubberBand +{ +public: + + QtxPolyRubberBand( QWidget* ); + virtual ~QtxPolyRubberBand(); + + void initGeometry( const QPolygon& ); + void initGeometry( const QPoint& ); + + void addNode( const QPoint& ); + void replaceLastNode( const QPoint& ); + void removeLastNode(); + + void setClosed( bool ); +}; + +#endif //QTXRUBBERBAND_H diff --git a/src/Qtx/QtxTranslator.cxx b/src/Qtx/QtxTranslator.cxx new file mode 100644 index 000000000..f3f955be1 --- /dev/null +++ b/src/Qtx/QtxTranslator.cxx @@ -0,0 +1,78 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File: QtxTranslator.cxx +// Author: Alexander SOLOVYOV + +#include "QtxTranslator.h" + +/*! + \class QtxTranslator + \brief Extended version of QTranslator + + In addition to the functionality provided by QTranslator class, QtxTranslator + allows translating resources defined in the global context (i.e. common resources). + The QtxTranslator can be used to workaround QTranslator's limitation which + does not allow to process messages with global context. + + For the current moment global context should be specified in translation + (*.ts/*.qm) files as "@default" string. For example: + \verbatim + + + @default + + MY_MESSAGE + My translated message + + + + \endverbatim +*/ + +#define GLOBAL_CONTEXT "@default" + +/*! + \brief Constructor. +*/ +QtxTranslator::QtxTranslator( QObject* parent ) +: QTranslator( parent ) +{ +} + +/*! + \brief Destructor. +*/ +QtxTranslator::~QtxTranslator() +{ +} + +/*! + \brief Returns the translation for the key. + \param context message context + \param sourceText message source name + \param comment message comment (optional) + \return Translated text if found or \a sourceText otherwise +*/ +QString QtxTranslator::translate( const char* context, const char* sourceText, const char* comment ) const +{ + QString res = QTranslator::translate( context, sourceText, comment ); + if( res.isNull() ) + res = QTranslator::translate( GLOBAL_CONTEXT, sourceText, comment ); + return res; +} diff --git a/src/Qtx/QtxTranslator.h b/src/Qtx/QtxTranslator.h new file mode 100644 index 000000000..a2c9ae058 --- /dev/null +++ b/src/Qtx/QtxTranslator.h @@ -0,0 +1,35 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File: QtxTranslator.h +// Author: Alexander SOLOVYOV + +#ifndef QTXTRANSLATOR_H +#define QTXTRANSLATOR_H + +#include + +class QtxTranslator : public QTranslator +{ +public: + QtxTranslator( QObject* parent = 0 ); + ~QtxTranslator(); + virtual QString translate( const char*, const char*, const char* = 0 ) const; +}; + +#endif