]> SALOME platform Git repositories - modules/gui.git/blob - src/QDS/QDS_RadioBox.cxx
Salome HOME
c2ae107ce6206115f1b3e45782053f206a410661
[modules/gui.git] / src / QDS / QDS_RadioBox.cxx
1 //  Copyright (C) 2007-2008  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.
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 #include "QDS_RadioBox.h"
23
24 #include <TColStd_HArray1OfInteger.hxx>
25 #include <TColStd_HArray1OfExtendedString.hxx>
26
27 #include <QButtonGroup>
28 #include <QGroupBox>
29 #include <QVBoxLayout>
30 #include <QRadioButton>
31
32 /*
33   \class QDS_RadioBox
34   \brief Datum with control corresponding to button group with set of exclusive radio buttons.
35
36   This control used for datum with enumerable values. It can be used for datum which has
37   type of value 'List'. Each radio button of group box is defined by two properties:
38   integer identifier and string name. All operations on radio buttons are performed via identifier.
39
40   If datum label text is specified, then it is displayed in the group box title.
41 */
42
43 /*!
44   \brief Constructor. 
45
46   Create radio button box datum object with datum identifier \a id and parent widget \a parent.
47   
48   Parameter \a flags defines behaviour of datum and set of created
49   subwidgets. Default value of this parameter is QDS::All. 
50   
51   Parameter \a comp specifies the component name which will be used
52   when searching the dictionary item.
53
54   \param id datum identifier
55   \param parent parent widget
56   \param flags datum flags
57   \param comp component
58 */
59 QDS_RadioBox::QDS_RadioBox( const QString& id, QWidget* parent, const int flags, const QString& comp )
60 : QDS_Datum( id, parent, flags & ~( Label | Units ), comp ),
61   myButtonGroup( 0 )
62 {
63 }
64
65 /*!
66   \brief Destructor.
67 */
68 QDS_RadioBox::~QDS_RadioBox()
69 {
70 }
71
72 /*!
73   \brief Get number of buttons in radio box.
74
75   If \a total is \c false, only visible buttons are taken into account; 
76   otherwise total number of buttons is returned
77
78   \param total get number of visible buttons if \c true and total number of buttons if \c false
79   \return requested number of items
80 */
81 int QDS_RadioBox::count( bool total ) const
82 {
83   if ( total )
84     return myValue.count();
85   else
86   {
87     QList<QRadioButton*> bList;
88     buttons( bList );
89     return bList.count();
90   }
91 }
92
93 /*!
94   \brief Get buttons identifiers.
95   \param ids returned list of buttons IDs
96   \param total take into account only visible buttons if \c true and all buttons if \c false
97 */
98 void QDS_RadioBox::values( QList<int>& ids, bool total ) const
99 {
100   ids.clear();
101   for ( QIntList::const_iterator it = myDataIds.begin(); it != myDataIds.end(); ++it )
102     if ( total || ( myState.contains( *it ) && myState[*it] ) )
103       ids.append( *it );
104 }
105
106 /*!
107   \brief Get visibility state of the button specified by \a id.
108   \param id button ID
109   \return item visibility state
110 */
111 bool QDS_RadioBox::state( const int id ) const
112 {
113   bool state = false;
114   if ( myState.contains( id ) )
115     state = myState[id];
116   return state;
117 }
118
119 /*!
120   \brief Set the visibility state of the button specified by \a id.
121
122   If \a id is -1 then specified state will be set to all buttons.
123
124   If \a append is set to \c true, keep current status for other buttons,
125   otherwise status of other buttons is cleared.
126
127   \param on new visibility state
128   \param id button ID
129   \param append if \c true, keep original status for other buttons
130 */
131 void QDS_RadioBox::setState( const bool on, const int id, const bool append )
132 {
133   QList<int> lst;
134   if ( id < 0 )
135   {
136     for ( IdStateMap::Iterator it = myState.begin(); it != myState.end(); ++it )
137       lst.append( it.key() );
138   }
139   else
140     lst.append( id );
141
142   setState( on, lst, append );
143 }
144
145 /*!
146   \brief Set the visibility state of buttons specified by \a ids.
147
148   If \a append is set to \c true, keep the current status for other buttons,
149   otherwise status of other buttons is cleared.
150
151   \param on new visibility state
152   \param ids buttons IDs list
153   \param append if \c true, keep original status for other buttons
154 */
155 void QDS_RadioBox::setState( const bool on, const QList<int>& ids, const bool append )
156 {
157   if ( ids.isEmpty() && append )
158     return;
159
160   bool changed = false;
161
162   QMap<int, int> aMap;
163   for ( uint i = 0; i < ids.count(); i++ )
164     aMap.insert( ids.at( i ), 0 );
165
166   for ( IdStateMap::Iterator it = myState.begin(); it != myState.end(); ++it )
167   {
168     if ( aMap.contains( it.key() ) )
169     {
170       if ( it.value() != on )
171       {
172         it.value() = on;
173         changed = true;
174       }
175     }
176     else if ( !append && it.value() == on )
177     {
178       it.value() = !on;
179       changed = true;
180     }
181   }
182   if ( changed )
183     updateRadioBox();
184 }
185
186 /*!
187   \brief Set the custom user buttons into the radio box.
188
189   User items like standard dictionary buttons will be added
190   into the radio box. This function allows user to customize
191   buttons.
192
193   \param ids buttons IDs
194   \param names buttons names
195 */
196 void QDS_RadioBox::setValues( const QList<int>& ids, const QStringList& names )
197 {
198   if ( ids.count() != names.count() )
199     return;
200
201   myUserIds = ids;
202   myUserNames = names;
203 }
204
205 /*!
206   \brief Set the custom user buttons into the radio box.
207   \overload
208
209   User buttons like standard dictionary buttons will be added
210   into the radio box. This function allows user to customize
211   buttons.
212
213   Uses (0, 1, 2 ... ) as buttons IDs.
214
215   \param names buttons names
216 */
217 void QDS_RadioBox::setValues( const QStringList& names )
218 {
219   QList< int > ids;
220   for ( int i = 0, n = names.count(); i < n; i++ )
221     ids.append( i );
222   setValues( ids, names );
223 }
224
225 /*!
226   \brief Get string from the radio box.
227
228   String which contains identifier of the currently selected button is returned.
229   \return identifier of the current button converted to string
230 */
231 QString QDS_RadioBox::getString() const
232 {
233   QString res;
234   QButtonGroup* bg = buttonGroup();
235   if ( bg )
236   {
237     int id = bg->checkedId();
238     if ( id != -1 )
239       res = QString::number( id );
240   }
241   return res;
242 }
243
244 /*!
245   \brief Set the string value to the radio box widget.
246
247   Button with the identifier from specified string \a txt becomes selected in the radio box.
248
249   \param txt string value
250 */
251 void QDS_RadioBox::setString( const QString& txt )
252 {
253   QButtonGroup* bg = buttonGroup();
254   if ( !bg )
255     return;
256
257   int oldId = bg->checkedId();
258
259   if ( txt.isEmpty() )
260   {
261     QList<QRadioButton*> bList;
262     buttons( bList );
263     QListIterator<QRadioButton*> it( bList );
264     while ( it.hasNext() )
265       it.next()->setChecked( false );
266   }
267   else
268   {
269     bool ok;
270     int id = txt.toInt( &ok );
271     if ( !ok )
272       id = -1;
273
274     bool block = signalsBlocked();
275     blockSignals( true );
276     bg->button(id)->setChecked(true);
277     blockSignals( block );
278   }
279
280   int newId = bg->checkedId();
281
282   if ( oldId != newId )
283   {
284     onParamChanged();
285     QString str = getString();
286     emit activated( newId );
287     emit paramChanged();
288     emit paramChanged( str );
289   }
290 }
291
292 /*!
293   \brief Get internal button group.
294   \return pointer to the QButtonGroup object
295 */
296 QButtonGroup* QDS_RadioBox::buttonGroup() const
297 {
298   return myButtonGroup;
299 }
300
301 /*!
302   \brief Get internal group box widget.
303   \return pointer to the QGroupBox widget
304 */
305 QGroupBox* QDS_RadioBox::groupBox() const
306 {
307   return ::qobject_cast<QGroupBox*>( controlWidget() );
308 }
309
310 /*!
311   \brief Get radio button group box widget.
312   \return internal group box widget
313 */
314 QWidget* QDS_RadioBox::createControl( QWidget* parent )
315 {
316   myButtonGroup = new QButtonGroup( parent );
317   myButtonGroup->setExclusive( true );
318
319   QGroupBox *gb = new QGroupBox( "", parent );
320   QVBoxLayout *vbox = new QVBoxLayout;
321   vbox->addStretch(1);
322   gb->setLayout(vbox);
323   return gb;
324 }
325
326 /*!
327   \brief Process notification about active units system changing.
328
329   Update radio box contents.
330   
331   \param system new active units system
332 */
333 void QDS_RadioBox::unitSystemChanged( const QString& system )
334 {
335   QDS_Datum::unitSystemChanged( system );
336
337   Handle(TColStd_HArray1OfInteger) anIds;
338   Handle(TColStd_HArray1OfExtendedString) aValues, anIcons;
339
340   Handle(DDS_DicItem) aDicItem = dicItem();
341   if ( !aDicItem.IsNull() )
342     aDicItem->GetListOfValues( aValues, anIds, anIcons );
343
344   myValue.clear();
345   myDataIds.clear();
346
347   QMap<int, QString> userMap;
348   QIntList::iterator iIt = myUserIds.begin();
349   QStringList::iterator sIt = myUserNames.begin();
350   for ( ; iIt != myUserIds.end() && sIt != myUserNames.end(); ++iIt, ++sIt )
351     userMap.insert( *iIt, *sIt );
352
353   if ( !anIds.IsNull() && !aValues.IsNull() &&
354        anIds->Length() == aValues->Length() )
355   {
356     for ( int i = anIds->Lower(); i <= anIds->Upper(); i++ )
357     {
358       QString aValue;
359       int id = anIds->Value( i );
360       if ( userMap.contains( id  ) )
361         aValue = userMap[id];
362       else
363         aValue = toQString( aValues->Value( i ) );
364
365       myDataIds.append( id );
366       myValue.insert( id, aValue );
367       myState.insert( id, true );
368     }
369   }
370
371   for ( iIt = myUserIds.begin(); iIt != myUserIds.end(); ++iIt )
372   {
373     int id = *iIt;
374     if ( !myValue.contains( id  ) )
375     {
376       myDataIds.append( id );
377       myValue.insert( id, userMap[id] );
378     }
379   }
380
381   QIntList del, add;
382   for ( IdStateMap::Iterator it1 = myState.begin(); it1 != myState.end(); ++it1 )
383     if ( !myValue.contains( it1.key() ) )
384       del.append( it1.key() );
385
386   for ( IdValueMap::Iterator it2 = myValue.begin(); it2 != myValue.end(); ++it2 )
387     if ( !myState.contains( it2.key() ) )
388       add.append( it2.key() );
389
390   for ( QIntList::iterator iter1 = del.begin(); iter1 != del.end(); ++iter1 )
391     myState.remove( *iter1 );
392
393   for ( QIntList::iterator iter2 = add.begin(); iter2 != add.end(); ++iter2 )
394     myState.insert( *iter2, true );
395
396   QGroupBox* gb = groupBox();
397   if ( gb ) gb->setTitle( label() );
398
399   updateRadioBox();
400 }
401
402 /*!
403   \brief Called when user toggles any radio button.
404   \param on new radio button state
405 */
406 void QDS_RadioBox::onToggled( bool on )
407 {
408   if ( !on )
409     return;
410
411   onParamChanged();
412   emit paramChanged();
413   QString str = getString();
414   emit paramChanged( str );
415 }
416
417 /*!
418   \brief Update radio box.
419 */
420 void QDS_RadioBox::updateRadioBox()
421 {
422   QButtonGroup* bg = buttonGroup();
423   if ( !bg )
424     return;
425
426   QGroupBox* gb = groupBox();
427   if ( !gb )
428     return;
429
430   int curId = bg->checkedId();
431
432   QList<QRadioButton*> bList;
433   buttons( bList );
434   QListIterator<QRadioButton*> itr( bList );
435   while ( itr.hasNext() ) {
436     QRadioButton* aButton = itr.next();
437     if ( gb->layout() ) gb->layout()->removeWidget(aButton);
438     delete aButton;
439   }
440
441   for ( QIntList::const_iterator it = myDataIds.begin(); it != myDataIds.end(); ++it )
442   {
443     int id = *it;
444     if ( !myValue.contains( id ) || !myState.contains( id ) || !myState[id] )
445       continue;
446
447     QRadioButton* rb = new QRadioButton( myValue[id] );
448     ((QObject*)rb)->setParent( bg );
449     bg->addButton( rb, id );
450     if ( gb->layout() ) gb->layout()->addWidget(rb);
451
452     connect( rb, SIGNAL( toggled( bool ) ), this, SLOT( onToggled( bool ) ) );
453   }
454
455   if ( curId != -1 )
456   {
457     int id = curId;
458     if ( !bg->button( id ) )
459     {
460       QList<QRadioButton*> bList;
461       buttons( bList );
462       if ( !bList.isEmpty() )
463         id = bg->id( bList.empty() ? 0 : bList.first() );
464     }
465
466     bool block = signalsBlocked();
467     blockSignals( true );
468     bg->button(id)->setChecked(true);
469     blockSignals( block );
470   }
471
472   if ( curId != bg->checkedId() )
473   {
474     onParamChanged();
475     QString str = getString();
476     emit paramChanged();
477     emit paramChanged( str );
478   }
479 }
480
481 /*!
482   \brief Get all the radio buttons from the radio box.
483   \param lst returned list of radio buttons
484 */
485 void QDS_RadioBox::buttons( QList<QRadioButton*>& lst ) const
486 {
487   lst.clear();
488
489   QButtonGroup* bg = buttonGroup();
490   if ( !bg )
491     return;
492
493   QList<QRadioButton*> objs = bg->findChildren<QRadioButton*>();
494   QListIterator<QRadioButton*> it( objs );
495   while ( it.hasNext() )
496     lst.append( it.next() );
497 }
498
499 /*!
500   \fn void QDS_RadioBox::activated( int id );
501   \brief The signal is emitted when any radio button is toggled.
502   \param id button ID
503 */