]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
Merging from the BR_V5_DEV branch.
authornds <nds@opencascade.com>
Mon, 6 Oct 2008 09:32:53 +0000 (09:32 +0000)
committernds <nds@opencascade.com>
Mon, 6 Oct 2008 09:32:53 +0000 (09:32 +0000)
19 files changed:
src/Qtx/QtxActionGroup.cxx [new file with mode: 0644]
src/Qtx/QtxActionGroup.h [new file with mode: 0644]
src/Qtx/QtxActionMenuMgr.cxx
src/Qtx/QtxActionMenuMgr.h
src/Qtx/QtxActionToolMgr.cxx
src/Qtx/QtxColorScale.cxx
src/Qtx/QtxColorScale.h
src/Qtx/QtxComboBox.cxx
src/Qtx/QtxComboBox.h
src/Qtx/QtxIntSpinBox.cxx
src/Qtx/QtxListAction.cxx
src/Qtx/QtxMRUAction.cxx
src/Qtx/QtxMRUAction.h
src/Qtx/QtxPopupMgr.cxx
src/Qtx/QtxResourceMgr.cxx
src/Qtx/QtxRubberBand.cxx [new file with mode: 0755]
src/Qtx/QtxRubberBand.h [new file with mode: 0755]
src/Qtx/QtxTranslator.cxx [new file with mode: 0644]
src/Qtx/QtxTranslator.h [new file with mode: 0644]

diff --git a/src/Qtx/QtxActionGroup.cxx b/src/Qtx/QtxActionGroup.cxx
new file mode 100644 (file)
index 0000000..cc3da34
--- /dev/null
@@ -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 <QMenu>
+#include <QMenuBar>
+#include <QActionGroup>
+
+/*!
+  \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<QWidget*> lst = createdWidgets();
+  for ( QList<QWidget*>::iterator it = lst.begin(); it != lst.end(); ++it )
+  {
+    QtxComboBox* cb = ::qobject_cast<QtxComboBox*>( *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<QWidget*> lst = createdWidgets();
+    for ( QList<QWidget*>::iterator it = lst.begin(); it != lst.end(); ++it )
+    {
+      QtxComboBox* cb = ::qobject_cast<QtxComboBox*>( *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<QMenu*>( w ) && !::qobject_cast<QMenuBar*>( w ) ) {
+    QtxComboBox* cb = createdWidget( w );
+    if ( !cb )
+      QtxActionSet::updateAction( w );
+    else
+    {
+      updateAction( cb );
+      
+      QList<QAction*> lst = actions();
+      for ( QList<QAction*>::iterator it = lst.begin(); it != lst.end(); ++it )
+       w->removeAction( *it );
+    }
+  }
+  else
+  {
+    if ( !usesDropDown() ) {
+      QtxActionSet::updateAction( w );
+    }
+    else {
+      QList<QAction*> lst = actions();
+      for ( QList<QAction*>::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<QAction*> lst = actions();
+  for ( QList<QAction*>::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<QMenu*>( p ) || ::qobject_cast<QMenuBar*>( 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<QWidget*> lst = associatedWidgets();
+  for ( QList<QWidget*>::iterator it = lst.begin(); it != lst.end(); ++it )
+  {
+    QWidget* w = *it;
+    QList<QAction*> 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<QWidget*> lst = createdWidgets();
+  for ( QList<QWidget*>::iterator it = lst.begin(); it != lst.end() && !cb; ++it )
+  {
+    if ( (*it)->parent() == p )
+      cb = ::qobject_cast<QtxComboBox*>( *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 (file)
index 0000000..108d40a
--- /dev/null
@@ -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
index 2540721e3102dfc6c1b8dad297de8851170a13bb..94368536e86a25f684f2e5d2ea2e0625490529ed 100644 (file)
@@ -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<QAction> 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<QAction*> > foreign;
+  QAction* a;
+  QAction* preva = 0;
+  QListIterator<QAction*> 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<QAction*> >::Iterator formapit;
+  for( formapit = foreign.begin(); formapit != foreign.end(); ++formapit )
+  {
+    QMutableListIterator<QAction*> foralit( formapit.value() );
+    while ( foralit.hasNext() )
+    {
+      a = foralit.next();
+      if ( !mw->actions().contains( a ) )
+       foralit.remove();
+    }
+  }
+  QList<QAction*> alist = mw->actions();
+  foreach( a, alist ) mw->removeAction( a );
 
+  // collect all registered menus by group id
   QMap<int, NodeList> 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
index 1f5079161267a45e48ce81e42099ec2cb4359d4f..6ee27cf6100cb579579537728edaa09517ed3f75 100644 (file)
@@ -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* );
index e2c4b2048820d0ebdb3ce1bbf810c39b2e014ab8..cf02d31d73ca3d1c90f0d93ef309db72ca3450d6 100644 (file)
@@ -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 <--
 }
 
 /*!
index b7dbf558a743ce56542765eb7cf9dda112c752c0..44589c9c1e75b35ecbdf4ec1ee046c39f901f7c2 100755 (executable)
@@ -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
index 453aeefe66b4e69c54b3af73022ea0422bd0f0f5..10014c8d9181861f722e9c304105f5b253391820 100755 (executable)
@@ -123,6 +123,7 @@ public:
   virtual void          hide();
 
 protected:
+  virtual void          paintEvent( QPaintEvent* );
   virtual void          drawContents( QPainter* );
 
 private:
index 817138c962739be4dc96e5db7d62a85c3ca3a860..831cb18c548eea3c89e8cdc2f3ccd249076151a2 100755 (executable)
 
 #include "QtxComboBox.h"
 
+#include <QStandardItemModel>
 #include <QLineEdit>
+#include <QEvent>
+#include <QApplication>
+
+/*!
+  \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*>( 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<QLineEdit*>( 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
-*/
index c821ffaed538bea3d041ace02a3d7303376391dc..f1b4f91ec31c4209af1b733d00c20fd19903446c 100755 (executable)
@@ -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 };
index 175a297ae73ccc829c7e96dd6e60aef03b918d90..b4cff2238432cb09041f9060a5e200e1b87eaac8 100755 (executable)
@@ -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& ) ) );
index fff34a60338cc0e72cfb604e6e2117ab9a9aade7..44961ddb88187862eee6e52f4865ae334809d9fe 100755 (executable)
@@ -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();
 }
 
index c3767ca5f5604fc7dabdc5c026919c8832cf9556..5ee95779f4bd58f5302d0ab792d585407780f390 100755 (executable)
   \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<QString, int> 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<QString, int> 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( "<Empty>" ) )->setEnabled( false );
+
+  if ( isClearPossible() )
+  {
+    pm->addSeparator();
+    pm->addAction( myClear );
+    myClear->setEnabled( !pm->isEmpty() );
+  }
 }
 
 /*!
index 708383f439e1a7bd31a05fd26793b4d2dc717665..f07f4fc4684a13c7358108013bc0adc45fbc9fcf 100755 (executable)
@@ -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
 };
index 36ecc8011e7697287fcc31a6c9edf565928c7c0a..970b2676f872c21049bac2ffd498a348d88aa5ac 100644 (file)
@@ -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;
 }
 
 /*!
index 6a83b7b561a0c2f2fa1b3e49e66dffe27921d7db..273c491597ceb211dbc2039e02be528569354e96 100644 (file)
 // Author:    Alexander SOLOVYOV, Sergey TELKOV
 
 #include "QtxResourceMgr.h"
+#include "QtxTranslator.h"
 
 #include <QDir>
 #include <QFile>
 #include <QRegExp>
 #include <QTextStream>
-#include <QTranslator>
 #include <QApplication>
 #ifndef QT_NO_DOM
 #include <QDomDocument>
@@ -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 (executable)
index 0000000..1fb2fad
--- /dev/null
@@ -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 <QBitmap>
+#include <QImage>
+#include <QPaintEvent>
+#include <QPainter>
+#include <QPalette>
+#include <QShowEvent>
+#include <QVectorIterator>
+
+/*!
+  \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<QPoint> 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<QPoint> 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 (executable)
index 0000000..e164261
--- /dev/null
@@ -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 <QWidget>
+
+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 (file)
index 0000000..f3f955b
--- /dev/null
@@ -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
+  <!DOCTYPE TS><TS>
+  <context>
+    <name>@default</name>
+    <message>
+        <source>MY_MESSAGE</source>
+        <translation>My translated message</translation>
+    </message>
+  </context>
+  </TS>
+  \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 (file)
index 0000000..a2c9ae0
--- /dev/null
@@ -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 <QTranslator>
+
+class QtxTranslator : public QTranslator
+{
+public:
+  QtxTranslator( QObject* parent = 0 );
+  ~QtxTranslator();
+  virtual QString translate( const char*, const char*, const char* = 0 ) const;
+};
+
+#endif