-// 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
+*/