]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
Fix problem with 'cleared' state of the combo box (infinite loop)
authorvsr <vsr@opencascade.com>
Fri, 18 Jul 2008 12:22:24 +0000 (12:22 +0000)
committervsr <vsr@opencascade.com>
Fri, 18 Jul 2008 12:22:24 +0000 (12:22 +0000)
src/Qtx/QtxComboBox.cxx
src/Qtx/QtxComboBox.h

index 817138c962739be4dc96e5db7d62a85c3ca3a860..656579d8bda5dadcb6ebab057d1fd11471648d3a 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 ? 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 +129,10 @@ QtxComboBox::QtxComboBox( QWidget* parent )
 : QComboBox( parent ),
   myCleared( false )
 {
-  connect( this, SIGNAL( activated( int ) ), this, SLOT( onActivated( int ) ) );
+  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 ) );
 }
 
 /*!
@@ -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,30 @@ 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() );
+  m->setCleared( myCleared );
+  QComboBox::paintEvent( e );
+  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 +237,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 +262,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 +307,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 };