]> SALOME platform Git repositories - modules/gui.git/blobdiff - src/Qtx/QtxComboBox.cxx
Salome HOME
Updated copyright comment
[modules/gui.git] / src / Qtx / QtxComboBox.cxx
old mode 100755 (executable)
new mode 100644 (file)
index a2c95f2..e31bd49
@@ -1,17 +1,20 @@
-// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
-// 
+// Copyright (C) 2007-2024  CEA, EDF, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either 
-// version 2.1 of the License.
-// 
-// This library is distributed in the hope that it will be useful 
-// but WITHOUT ANY WARRANTY; without even the implied warranty of 
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 // Lesser General Public License for more details.
 //
-// You should have received a copy of the GNU Lesser General Public  
-// License along with this library; if not, write to the Free Software 
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 
 #include "QtxComboBox.h"
 
-#include <qpixmap.h>
-#include <qlineedit.h>
-#include <qvaluelist.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 \a role for given \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 editable mode.
+  \internal
+*/
+
+#define CLEAR_EVENT QEvent::Type( QEvent::User + 123 )
+
+class QtxComboBox::ClearEvent : public QEvent
+{
+public:
+  ClearEvent();
+};
 
 /*!
-  Constructor
+  \brief Constructor.
+  \internal
 */
-QtxComboBox::QtxComboBox( QWidget* parent, const char* name )
-: QComboBox( parent, name ),
-myCleared( false )
+QtxComboBox::ClearEvent::ClearEvent() : QEvent( CLEAR_EVENT )
 {
-    connect( this, SIGNAL( activated( int ) ), this, SLOT( onActivated( int ) ) );
-    connect( this, SIGNAL( activated( const QString& ) ), this, SLOT( onActivated( const QString& ) ) );
 }
 
 /*!
-  Constructor
+  \class QtxComboBox
+  \brief Enhanced version of Qt combo box class.
+
+  In addition to the QComboBox class, QtxComboBox supports 
+  adding/removing the items with the associated unique identifiers.
+  It also provides a way to set "cleared" state to the combo box -
+  when no item is selected.
+*/
+
+/*!
+  \brief Constructor.
+  \param parent parent widget
 */
-QtxComboBox::QtxComboBox( bool rw, QWidget* parent, const char* name )
-: QComboBox( rw, parent, name ),
-myCleared( false )
+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( currentIndexChanged( int ) ),  this, SLOT( onCurrentChanged( int ) ) );
+  setModel( new Model( this ) );
 }
 
 /*!
-  Destructor
+  \brief Destructor.
 */
 QtxComboBox::~QtxComboBox()
 {
 }
 
 /*!
-  \return true if combobox is cleared
+  \brief Check if combo box is in "cleared" state.
+  \return \c true if combo box is in "cleared" state or \c false otherwise
 */
 bool QtxComboBox::isCleared() const
 {
-    return myCleared;
+  return myCleared;
 }
 
 /*!
-  Sets cleared status
-  \param isClear - new status
+  \brief Set "cleared" state.
+  \param isClear new "cleared" state
 */
 void QtxComboBox::setCleared( const bool isClear )
 {
-    if ( myCleared == isClear )
-        return;
-    
-    myCleared = isClear;
+  if ( myCleared == isClear )
+    return;
     
-    if ( editable() )
-    {
-        if ( myCleared )
-            lineEdit()->setText( "" );
-        else
-            lineEdit()->setText( text( currentItem() ) );
-    }
-    
-    update();
+  myCleared = isClear;
+
+  if ( lineEdit() )
+    lineEdit()->setText( myCleared ? QString( "" ) : itemText( currentIndex() ) );
+
+  update();
 }
 
 /*!
-  Sets currently selected item
-  \param idx - index of item
+  \brief Get current item's identifier.
+  \return current item's identifier
 */
-void QtxComboBox::setCurrentItem( int idx )
+QVariant QtxComboBox::currentId() const
 {
-    if ( idx < 0 || idx >= count() )
-        return;
-    
-    myCleared = false;
-    QComboBox::setCurrentItem( idx );
+  return id( currentIndex() );
 }
 
 /*!
-  Sets current text
-  \param txt - new current text
+  \brief Set current item by identifier.
+  \param ident item's identifier
 */
-void QtxComboBox::setCurrentText( const QString& txt )
+void QtxComboBox::setCurrentId( const QVariant& ident )
 {
-    myCleared = false;
-#if QT_VER < 3
-    int i = -1;
-    for ( int j = 0; j < count() && i == -1; j++ )
-        if ( text( j ) == txt )
-            i = j;
-    if ( i >= 0 && i < count() )
-        setCurrentItem( i );
-    else if ( editable() )
-        lineEdit()->setText( txt );
-    else
-        changeItem( txt, currentItem() );
-#else
-    QComboBox::setCurrentText( txt );
-#endif
+  setCurrentIndex( index( ident ) );
 }
 
 /*!
-  \return current selected id
+  \brief Assign identifier to specified item.
+  \param idx item's index
+  \param ident item's identifier
 */
-int QtxComboBox::currentId() const
+void QtxComboBox::setId( const int idx, const QVariant& ident )
 {
-    return id( currentItem() );
+  setItemData( idx, ident, (Qt::ItemDataRole)IdRole );
 }
 
 /*!
-  Sets current selected id
+  \brief Customize paint event.
+  \param e paint event
 */
-void QtxComboBox::setCurrentId( int num )
+void QtxComboBox::paintEvent( QPaintEvent* e )
 {
-    setCurrentItem( index( num ) );
+  Model* m = dynamic_cast<Model*>( model() );
+  if ( m )
+    m->setCleared( myCleared );
+  QComboBox::paintEvent( e );
+  if ( m )
+    m->setCleared( false );
 }
 
 /*!
-  Custom paint event handler
+  \brief Customize child addition/removal event.
+  \param e child event
 */
-void QtxComboBox::paintEvent( QPaintEvent* e )
+void QtxComboBox::childEvent( QChildEvent* e )
 {
-    if ( !count() || !myCleared || editable() )
-        QComboBox::paintEvent( e );
-    else
-        paintClear( e );
+  if ( ( e->added() || e->polished() ) && qobject_cast<QLineEdit*>( e->child() ) )
+    QApplication::postEvent( this, new ClearEvent() );
 }
 
 /*!
-  SLOT: called if some item is activated
-  \param idx - index of activated item
+  \brief Process custom events
+  \param e custom event
 */
-void QtxComboBox::onActivated( int idx )
+void QtxComboBox::customEvent( QEvent* e )
 {
-    resetClear();
-    
-    if ( myIndexId.contains( idx ) )
-        emit activatedId( myIndexId[idx] );
+  if ( e->type() == CLEAR_EVENT && lineEdit() && myCleared )
+    lineEdit()->setText( "" );
 }
 
 /*!
-  SLOT: called if some item is activated
-*/void QtxComboBox::onActivated( const QString& )
+  \brief Called when current item is changed (by user or programmatically).
+  \param idx index of item being set current
+*/
+void QtxComboBox::onCurrentChanged( int idx )
 {
+  if ( idx != -1 )
+  {
     resetClear();
+    QVariant ident = id( idx );
+    emit activatedId( id( idx ) );
+    if ( ident.type() == QVariant::Int )
+      emit activatedId( ident.toInt() );
+    else if ( ident.type() == QVariant::String )
+      emit activatedId( ident.toString() );
+  }
 }
 
 /*!
-  Strips "cleared" state and updates
+  \brief Reset "cleared" state and update combo box.
 */
 void QtxComboBox::resetClear()
 {
-    if ( !myCleared )
-        return;
-    
-    myCleared = false;
-    update();
+  if ( !myCleared )
+    return;
+  
+  myCleared = false;
+  update();
 }
 
 /*!
-  Draws combobox when it is cleared or isn't editable
+  \brief Get item's identifier by index.
+  \param idx item's index
+  \return item's identifier or invalid QVariant if index is out of range
+  or identifier is not assigned to item
 */
-void QtxComboBox::paintClear( QPaintEvent* e )
+QVariant QtxComboBox::id( const int idx ) const
 {
-    int curIndex = currentItem();
-    QString curText = text( curIndex );
-    
-    QPixmap curPix;
-    if ( pixmap( curIndex ) )
-        curPix = *pixmap( curIndex );
-    
-    bool upd = isUpdatesEnabled();
-    setUpdatesEnabled( false );
-    
-    changeItem( "", curIndex );
-    QComboBox::paintEvent( e );
-    
-    if ( curPix.isNull() )
-        changeItem( curText, curIndex );
-    else
-        changeItem( curPix, curText, curIndex );
-    
-    setUpdatesEnabled( upd );
+  return itemData( idx, (Qt::ItemDataRole)IdRole );
 }
 
 /*!
-  \return id by index
+  \brief Get item index by identifier.
+  \param ident item's identifier
+  \return item's index or -1 if \a ident is invalid of if item is not found
 */
-int QtxComboBox::id( const int idx ) const
+int QtxComboBox::index( const QVariant& ident ) const
 {
-    int id = -1;
-    if ( myIndexId.contains( idx ) )
-        id = myIndexId[idx];
-    return id;
+  if ( !ident.isValid() ) return -1;
+  return findData( ident, (Qt::ItemDataRole)IdRole );
 }
 
 /*!
-  \return index by id
+  \brief Check if item has assigned identifier.
+  \param idx item's index
+  \return \c true if item with given index has identifier of \c false otherwise
 */
-int QtxComboBox::index( const int id ) const
+bool QtxComboBox::hasId( const int idx ) const
 {
-    int idx = -1;
-    for ( IndexIdMap::ConstIterator it = myIndexId.begin();
-    it != myIndexId.end() && idx == -1; ++it )
-        if ( it.data() == id )
-            idx = it.key();
-        return idx;
+  QVariant v = itemData( idx, (Qt::ItemDataRole)IdRole );
+  return !v.isNull();
 }
+
+/*!
+  \fn void QtxComboBox::activatedId( QVariant ident )
+  \brief Emitted when item with identificator \a ident is activated.
+  \param ident item's identifier
+*/
+
+/*!
+  \fn void QtxComboBox::activatedId( int ident )
+  \brief Emitted when item with integer identificator \a ident is activated.
+  \param ident item's identifier
+*/
+
+/*!
+  \fn void QtxComboBox::activatedId( QString ident )
+  \brief Emitted when item with string identificator \a ident is activated.
+  \param ident item's identifier
+*/