Salome HOME
Update copyrights 2014.
[modules/gui.git] / src / Qtx / QtxComboBox.cxx
1 // Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 // File:      QtxComboBox.cxx
24 // Author:    Sergey TELKOV
25 //
26 #include "QtxComboBox.h"
27
28 #include <QStandardItemModel>
29 #include <QLineEdit>
30 #include <QEvent>
31 #include <QApplication>
32
33 /*!
34   \class QtxComboBox::Model
35   \brief Internal view model, used to process 'cleared' state of the combo box.
36   \internal
37 */
38 class QtxComboBox::Model : public QStandardItemModel
39 {
40 public:
41   Model( QObject* parent = 0 );
42   ~Model();
43   void setCleared( const bool );
44
45   QVariant data( const QModelIndex&, int = Qt::DisplayRole ) const;
46
47 private:
48   bool   myCleared;
49 };
50
51 /*!
52   \brief Constructor
53   \internal
54   \param parent parent object
55 */
56 QtxComboBox::Model::Model( QObject* parent )
57   : QStandardItemModel( 0, 1, parent ),
58     myCleared( false )
59 {
60 }
61
62 /*!
63   \brief Destructor
64   \internal
65 */
66 QtxComboBox::Model::~Model()
67 {
68 }
69
70 /*!
71   \brief Set 'cleared' state
72   \param isClear new 'cleared' state
73   \internal
74 */
75 void QtxComboBox::Model::setCleared( const bool isClear )
76 {
77   if ( myCleared == isClear )
78     return;
79   
80   myCleared = isClear;
81 }
82
83 /*!
84   \brief Get model data.
85   \param index model index
86   \param role data role
87   \return data of role \a role for the \a index
88   \internal
89 */
90 QVariant QtxComboBox::Model::data( const QModelIndex& index, int role ) const
91 {
92   return ( myCleared && ( role == Qt::DisplayRole || role == Qt::DecorationRole ) ) ?
93     QVariant() : QStandardItemModel::data( index, role );
94 }
95
96 /*!
97   \class QtxComboBox::ClearEvent
98   \brief Custom event, used to process 'cleared' state of the combo box
99   in the editable mode.
100   \internal
101 */
102
103 #define CLEAR_EVENT QEvent::Type( QEvent::User + 123 )
104
105 class QtxComboBox::ClearEvent : public QEvent
106 {
107 public:
108   ClearEvent();
109 };
110
111 /*!
112   \brief Constructor
113   \internal
114 */
115 QtxComboBox::ClearEvent::ClearEvent() : QEvent( CLEAR_EVENT )
116 {
117 }
118
119 /*!
120   \class QtxComboBox
121   \brief Enhanced version of Qt combo box class.
122
123   In addition to the QComboBox class, QtxComboBox supports 
124   adding/removing the items with the associated unique identifiers.
125   It also provides a way to set "cleared" state to the combo box -
126   when no item is selected.
127 */
128
129 /*!
130   \brief Constructor.
131   \param parent parent widget
132 */
133 QtxComboBox::QtxComboBox( QWidget* parent )
134 : QComboBox( parent ),
135   myCleared( false )
136 {
137   connect( this, SIGNAL( currentIndexChanged( int ) ),  this, SLOT( onCurrentChanged( int ) ) );
138   setModel( new Model( this ) );
139 }
140
141 /*!
142   \brief Destructor.
143
144   Does nothing currently.
145 */
146 QtxComboBox::~QtxComboBox()
147 {
148 }
149
150 /*!
151   \brief Check if the combo box is in the "cleared" state.
152   \return \c true if combobox is in the "cleared" state
153 */
154 bool QtxComboBox::isCleared() const
155 {
156   return myCleared;
157 }
158
159 /*!
160   \brief Set "cleared" state.
161   \param isClear new "cleared" state
162 */
163 void QtxComboBox::setCleared( const bool isClear )
164 {
165   if ( myCleared == isClear )
166     return;
167     
168   myCleared = isClear;
169
170   if ( lineEdit() )
171     lineEdit()->setText( myCleared ? QString( "" ) : itemText( currentIndex() ) );
172
173   update();
174 }
175
176 /*!
177   \brief Get current item ID.
178   \return item id
179 */
180 int QtxComboBox::currentId() const
181 {
182   return id( currentIndex() );
183 }
184
185 /*!
186   \brief Set current item by ID.
187   \param num item ID
188 */
189 void QtxComboBox::setCurrentId( int num )
190 {
191   setCurrentIndex( index( num ) );
192 }
193
194 /*!
195   \brief Set the identifier to specified item.
196   \param index - index of the item
197   \param id - identifier of the item
198 */
199 void QtxComboBox::setId( const int index, const int id )
200 {
201   setItemData( index, QVariant( id ), (Qt::ItemDataRole)IdRole );
202 }
203
204 /*!
205   \brief Customize paint event.
206   \param e paint event
207 */
208 void QtxComboBox::paintEvent( QPaintEvent* e )
209 {
210   Model* m = dynamic_cast<Model*>( model() );
211   if ( m )
212     m->setCleared( myCleared );
213   QComboBox::paintEvent( e );
214   if ( m )
215     m->setCleared( false );
216 }
217
218 /*!
219   \brief Customize child addition/removal event
220   \param e child event
221 */
222 void QtxComboBox::childEvent( QChildEvent* e )
223 {
224   if ( ( e->added() || e->polished() ) && qobject_cast<QLineEdit*>( e->child() ) )
225     QApplication::postEvent( this, new ClearEvent() );
226 }
227
228 /*!
229   \brief Process custom events
230   \param e custom event
231 */
232 void QtxComboBox::customEvent( QEvent* e )
233 {
234   if ( e->type() == CLEAR_EVENT && lineEdit() && myCleared )
235     lineEdit()->setText( "" );
236 }
237
238 /*!
239   \brief Called when current item is chaned (by the user or programmatically).
240   \param idx item being set current
241 */
242 void QtxComboBox::onCurrentChanged( int idx )
243 {
244   if ( idx != -1 )
245   {
246     resetClear();
247     emit activatedId( id( idx ) );
248   }
249 }
250
251 /*!
252   \brief Reset "cleared" state and update the combo box.
253 */
254 void QtxComboBox::resetClear()
255 {
256   if ( !myCleared )
257     return;
258   
259   myCleared = false;
260   update();
261 }
262
263 /*!
264   \brief Get item ID by the index.
265   \param idx item index
266   \return item ID or -1 if index is invalid.
267 */
268 int QtxComboBox::id( const int idx ) const
269 {
270   int id = -1;
271   QVariant v = itemData( idx, (Qt::ItemDataRole)IdRole );
272   if ( v.canConvert( QVariant::Int ) )
273     id = v.toInt();
274   return id;
275 }
276
277 /*!
278   \brief Get item index by the ID.
279   \param id item ID
280   \return item index or -1 if ID is invalid.
281 */
282 int QtxComboBox::index( const int ident ) const
283 {
284   int idx = -1;
285   for ( int i = 0; i < (int)count() && idx == -1; i++ )
286   {
287     if ( id( i ) == ident )
288       idx = i;
289   }
290   return idx;
291 }
292
293 /*!
294   \brief Returns true if the item with index has ID.
295   \param idx item index
296 */
297 bool QtxComboBox::hasId( const int idx ) const
298 {
299   QVariant v = itemData( idx, (Qt::ItemDataRole)IdRole );
300   return v.canConvert( QVariant::Int );
301 }
302
303 /*!
304   \fn void QtxComboBox::activatedId( int id )
305   \brief Emitted when the item with identificator \a id is activated.
306   \param id item ID
307 */