| 1 | /****************************************************************************
|
|---|
| 2 | ** $Id: qbuttongroup.cpp 2 2005-11-16 15:49:26Z dmik $
|
|---|
| 3 | **
|
|---|
| 4 | ** Implementation of QButtonGroup class
|
|---|
| 5 | **
|
|---|
| 6 | ** Created : 950130
|
|---|
| 7 | **
|
|---|
| 8 | ** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
|
|---|
| 9 | **
|
|---|
| 10 | ** This file is part of the widgets module of the Qt GUI Toolkit.
|
|---|
| 11 | **
|
|---|
| 12 | ** This file may be distributed under the terms of the Q Public License
|
|---|
| 13 | ** as defined by Trolltech AS of Norway and appearing in the file
|
|---|
| 14 | ** LICENSE.QPL included in the packaging of this file.
|
|---|
| 15 | **
|
|---|
| 16 | ** This file may be distributed and/or modified under the terms of the
|
|---|
| 17 | ** GNU General Public License version 2 as published by the Free Software
|
|---|
| 18 | ** Foundation and appearing in the file LICENSE.GPL included in the
|
|---|
| 19 | ** packaging of this file.
|
|---|
| 20 | **
|
|---|
| 21 | ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
|
|---|
| 22 | ** licenses may use this file in accordance with the Qt Commercial License
|
|---|
| 23 | ** Agreement provided with the Software.
|
|---|
| 24 | **
|
|---|
| 25 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|---|
| 26 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|---|
| 27 | **
|
|---|
| 28 | ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
|
|---|
| 29 | ** information about Qt Commercial License Agreements.
|
|---|
| 30 | ** See http://www.trolltech.com/qpl/ for QPL licensing information.
|
|---|
| 31 | ** See http://www.trolltech.com/gpl/ for GPL licensing information.
|
|---|
| 32 | **
|
|---|
| 33 | ** Contact info@trolltech.com if any conditions of this licensing are
|
|---|
| 34 | ** not clear to you.
|
|---|
| 35 | **
|
|---|
| 36 | **********************************************************************/
|
|---|
| 37 |
|
|---|
| 38 | #include "qbuttongroup.h"
|
|---|
| 39 | #ifndef QT_NO_BUTTONGROUP
|
|---|
| 40 | #include "qbutton.h"
|
|---|
| 41 | #include "qptrlist.h"
|
|---|
| 42 | #include "qapplication.h"
|
|---|
| 43 | #include "qradiobutton.h"
|
|---|
| 44 |
|
|---|
| 45 |
|
|---|
| 46 |
|
|---|
| 47 | /*!
|
|---|
| 48 | \class QButtonGroup qbuttongroup.h
|
|---|
| 49 | \brief The QButtonGroup widget organizes QButton widgets in a group.
|
|---|
| 50 |
|
|---|
| 51 | \ingroup organizers
|
|---|
| 52 | \ingroup geomanagement
|
|---|
| 53 | \ingroup appearance
|
|---|
| 54 | \mainclass
|
|---|
| 55 |
|
|---|
| 56 | A button group widget makes it easier to deal with groups of
|
|---|
| 57 | buttons. Each button in a button group has a unique identifier.
|
|---|
| 58 | The button group emits a clicked() signal with this identifier
|
|---|
| 59 | when a button in the group is clicked. This makes a button group
|
|---|
| 60 | particularly useful when you have several similar buttons and want
|
|---|
| 61 | to connect all their clicked() signals to a single slot.
|
|---|
| 62 |
|
|---|
| 63 | An \link setExclusive() exclusive\endlink button group switches
|
|---|
| 64 | off all toggle buttons except the one that was clicked. A button
|
|---|
| 65 | group is, by default, non-exclusive. Note that all radio buttons
|
|---|
| 66 | that are inserted into a button group are mutually exclusive even
|
|---|
| 67 | if the button group is non-exclusive. (See
|
|---|
| 68 | setRadioButtonExclusive().)
|
|---|
| 69 |
|
|---|
| 70 | There are two ways of using a button group:
|
|---|
| 71 | \list
|
|---|
| 72 | \i The button group is the parent widget of a number of buttons,
|
|---|
| 73 | i.e. the button group is the parent argument in the button
|
|---|
| 74 | constructor. The buttons are assigned identifiers 0, 1, 2, etc.,
|
|---|
| 75 | in the order they are created. A QButtonGroup can display a frame
|
|---|
| 76 | and a title because it inherits QGroupBox.
|
|---|
| 77 | \i The button group is an invisible widget and the contained
|
|---|
| 78 | buttons have some other parent widget. In this usage, each button
|
|---|
| 79 | must be manually inserted, using insert(), into the button group
|
|---|
| 80 | and given an identifier.
|
|---|
| 81 | \endlist
|
|---|
| 82 |
|
|---|
| 83 | A button can be removed from the group with remove(). A pointer to
|
|---|
| 84 | a button with a given id can be obtained using find(). The id of a
|
|---|
| 85 | button is available using id(). A button can be set \e on with
|
|---|
| 86 | setButton(). The number of buttons in the group is returned by
|
|---|
| 87 | count().
|
|---|
| 88 |
|
|---|
| 89 | <img src=qbttngrp-m.png> <img src=qbttngrp-w.png>
|
|---|
| 90 |
|
|---|
| 91 | \sa QPushButton, QCheckBox, QRadioButton
|
|---|
| 92 | */
|
|---|
| 93 |
|
|---|
| 94 | /*!
|
|---|
| 95 | \property QButtonGroup::exclusive
|
|---|
| 96 | \brief whether the button group is exclusive
|
|---|
| 97 |
|
|---|
| 98 | If this property is TRUE, then the buttons in the group are
|
|---|
| 99 | toggled, and to untoggle a button you must click on another button
|
|---|
| 100 | in the group. The default value is FALSE.
|
|---|
| 101 | */
|
|---|
| 102 |
|
|---|
| 103 | /*!
|
|---|
| 104 | \property QButtonGroup::radioButtonExclusive
|
|---|
| 105 | \brief whether the radio buttons in the group are exclusive
|
|---|
| 106 |
|
|---|
| 107 | If this property is TRUE (the default), the \link QRadioButton
|
|---|
| 108 | radiobuttons\endlink in the group are treated exclusively.
|
|---|
| 109 | */
|
|---|
| 110 |
|
|---|
| 111 | struct QButtonItem
|
|---|
| 112 | {
|
|---|
| 113 | QButton *button;
|
|---|
| 114 | int id;
|
|---|
| 115 | };
|
|---|
| 116 |
|
|---|
| 117 |
|
|---|
| 118 | class QButtonList: public QPtrList<QButtonItem>
|
|---|
| 119 | {
|
|---|
| 120 | public:
|
|---|
| 121 | QButtonList() {}
|
|---|
| 122 | ~QButtonList() {}
|
|---|
| 123 | };
|
|---|
| 124 |
|
|---|
| 125 |
|
|---|
| 126 | typedef QPtrListIterator<QButtonItem> QButtonListIt;
|
|---|
| 127 |
|
|---|
| 128 |
|
|---|
| 129 | /*!
|
|---|
| 130 | Constructs a button group with no title.
|
|---|
| 131 |
|
|---|
| 132 | The \a parent and \a name arguments are passed to the QWidget
|
|---|
| 133 | constructor.
|
|---|
| 134 | */
|
|---|
| 135 |
|
|---|
| 136 | QButtonGroup::QButtonGroup( QWidget *parent, const char *name )
|
|---|
| 137 | : QGroupBox( parent, name )
|
|---|
| 138 | {
|
|---|
| 139 | init();
|
|---|
| 140 | }
|
|---|
| 141 |
|
|---|
| 142 | /*!
|
|---|
| 143 | Constructs a button group with the title \a title.
|
|---|
| 144 |
|
|---|
| 145 | The \a parent and \a name arguments are passed to the QWidget
|
|---|
| 146 | constructor.
|
|---|
| 147 | */
|
|---|
| 148 |
|
|---|
| 149 | QButtonGroup::QButtonGroup( const QString &title, QWidget *parent,
|
|---|
| 150 | const char *name )
|
|---|
| 151 | : QGroupBox( title, parent, name )
|
|---|
| 152 | {
|
|---|
| 153 | init();
|
|---|
| 154 | }
|
|---|
| 155 |
|
|---|
| 156 | /*!
|
|---|
| 157 | Constructs a button group with no title. Child widgets will be
|
|---|
| 158 | arranged in \a strips rows or columns (depending on \a
|
|---|
| 159 | orientation).
|
|---|
| 160 |
|
|---|
| 161 | The \a parent and \a name arguments are passed to the QWidget
|
|---|
| 162 | constructor.
|
|---|
| 163 | */
|
|---|
| 164 |
|
|---|
| 165 | QButtonGroup::QButtonGroup( int strips, Orientation orientation,
|
|---|
| 166 | QWidget *parent, const char *name )
|
|---|
| 167 | : QGroupBox( strips, orientation, parent, name )
|
|---|
| 168 | {
|
|---|
| 169 | init();
|
|---|
| 170 | }
|
|---|
| 171 |
|
|---|
| 172 | /*!
|
|---|
| 173 | Constructs a button group with title \a title. Child widgets will
|
|---|
| 174 | be arranged in \a strips rows or columns (depending on \a
|
|---|
| 175 | orientation).
|
|---|
| 176 |
|
|---|
| 177 | The \a parent and \a name arguments are passed to the QWidget
|
|---|
| 178 | constructor.
|
|---|
| 179 | */
|
|---|
| 180 |
|
|---|
| 181 | QButtonGroup::QButtonGroup( int strips, Orientation orientation,
|
|---|
| 182 | const QString &title, QWidget *parent,
|
|---|
| 183 | const char *name )
|
|---|
| 184 | : QGroupBox( strips, orientation, title, parent, name )
|
|---|
| 185 | {
|
|---|
| 186 | init();
|
|---|
| 187 | }
|
|---|
| 188 |
|
|---|
| 189 | /*!
|
|---|
| 190 | Initializes the button group.
|
|---|
| 191 | */
|
|---|
| 192 |
|
|---|
| 193 | void QButtonGroup::init()
|
|---|
| 194 | {
|
|---|
| 195 | buttons = new QButtonList;
|
|---|
| 196 | Q_CHECK_PTR( buttons );
|
|---|
| 197 | buttons->setAutoDelete( TRUE );
|
|---|
| 198 | excl_grp = FALSE;
|
|---|
| 199 | radio_excl = TRUE;
|
|---|
| 200 | }
|
|---|
| 201 |
|
|---|
| 202 | /*! \reimp */
|
|---|
| 203 |
|
|---|
| 204 | QButtonGroup::~QButtonGroup()
|
|---|
| 205 | {
|
|---|
| 206 | QButtonList * tmp = buttons;
|
|---|
| 207 | QButtonItem *bi = tmp->first();
|
|---|
| 208 | buttons = 0;
|
|---|
| 209 | while( bi ) {
|
|---|
| 210 | bi->button->setGroup(0);
|
|---|
| 211 | bi = tmp->next();
|
|---|
| 212 | }
|
|---|
| 213 | delete tmp;
|
|---|
| 214 | }
|
|---|
| 215 |
|
|---|
| 216 | bool QButtonGroup::isExclusive() const
|
|---|
| 217 | {
|
|---|
| 218 | return excl_grp;
|
|---|
| 219 | }
|
|---|
| 220 |
|
|---|
| 221 | void QButtonGroup::setExclusive( bool enable )
|
|---|
| 222 | {
|
|---|
| 223 | excl_grp = enable;
|
|---|
| 224 | }
|
|---|
| 225 |
|
|---|
| 226 |
|
|---|
| 227 | /*!
|
|---|
| 228 | Inserts the \a button with the identifier \a id into the button
|
|---|
| 229 | group. Returns the button identifier.
|
|---|
| 230 |
|
|---|
| 231 | Buttons are normally inserted into a button group automatically by
|
|---|
| 232 | passing the button group as the parent when the button is
|
|---|
| 233 | constructed. So it is not necessary to manually insert buttons
|
|---|
| 234 | that have this button group as their parent widget. An exception
|
|---|
| 235 | is when you want custom identifiers instead of the default 0, 1,
|
|---|
| 236 | 2, etc., or if you want the buttons to have some other parent.
|
|---|
| 237 |
|
|---|
| 238 | The button is assigned the identifier \a id or an automatically
|
|---|
| 239 | generated identifier. It works as follows: If \a id >= 0, this
|
|---|
| 240 | identifier is assigned. If \a id == -1 (default), the identifier
|
|---|
| 241 | is equal to the number of buttons in the group. If \a id is any
|
|---|
| 242 | other negative integer, for instance -2, a unique identifier
|
|---|
| 243 | (negative integer \<= -2) is generated. No button has an id of -1.
|
|---|
| 244 |
|
|---|
| 245 | \sa find(), remove(), setExclusive()
|
|---|
| 246 | */
|
|---|
| 247 |
|
|---|
| 248 | int QButtonGroup::insert( QButton *button, int id )
|
|---|
| 249 | {
|
|---|
| 250 | if ( button->group() )
|
|---|
| 251 | button->group()->remove( button );
|
|---|
| 252 |
|
|---|
| 253 | static int seq_no = -2;
|
|---|
| 254 | QButtonItem *bi = new QButtonItem;
|
|---|
| 255 | Q_CHECK_PTR( bi );
|
|---|
| 256 |
|
|---|
| 257 | if ( id < -1 )
|
|---|
| 258 | bi->id = seq_no--;
|
|---|
| 259 | else if ( id == -1 )
|
|---|
| 260 | bi->id = buttons->count();
|
|---|
| 261 | else
|
|---|
| 262 | bi->id = id;
|
|---|
| 263 |
|
|---|
| 264 | bi->button = button;
|
|---|
| 265 | button->setGroup(this);
|
|---|
| 266 | buttons->append( bi );
|
|---|
| 267 |
|
|---|
| 268 | connect( button, SIGNAL(pressed()) , SLOT(buttonPressed()) );
|
|---|
| 269 | connect( button, SIGNAL(released()), SLOT(buttonReleased()) );
|
|---|
| 270 | connect( button, SIGNAL(clicked()) , SLOT(buttonClicked()) );
|
|---|
| 271 | connect( button, SIGNAL(toggled(bool)) , SLOT(buttonToggled(bool)) );
|
|---|
| 272 |
|
|---|
| 273 | if ( button->isToggleButton() && !button->isOn() &&
|
|---|
| 274 | selected() && (selected()->focusPolicy() & TabFocus) != 0 )
|
|---|
| 275 | button->setFocusPolicy( (FocusPolicy)(button->focusPolicy() &
|
|---|
| 276 | ~TabFocus) );
|
|---|
| 277 |
|
|---|
| 278 | return bi->id;
|
|---|
| 279 | }
|
|---|
| 280 |
|
|---|
| 281 | /*!
|
|---|
| 282 | Returns the number of buttons in the group.
|
|---|
| 283 | */
|
|---|
| 284 | int QButtonGroup::count() const
|
|---|
| 285 | {
|
|---|
| 286 | return buttons->count();
|
|---|
| 287 | }
|
|---|
| 288 |
|
|---|
| 289 | /*!
|
|---|
| 290 | Removes the \a button from the button group.
|
|---|
| 291 |
|
|---|
| 292 | \sa insert()
|
|---|
| 293 | */
|
|---|
| 294 |
|
|---|
| 295 | void QButtonGroup::remove( QButton *button )
|
|---|
| 296 | {
|
|---|
| 297 | if ( !buttons )
|
|---|
| 298 | return;
|
|---|
| 299 |
|
|---|
| 300 | QButtonListIt it( *buttons );
|
|---|
| 301 | QButtonItem *i;
|
|---|
| 302 | while ( (i=it.current()) != 0 ) {
|
|---|
| 303 | ++it;
|
|---|
| 304 | if ( i->button == button ) {
|
|---|
| 305 | buttons->remove( i );
|
|---|
| 306 | button->setGroup(0);
|
|---|
| 307 | button->disconnect( this );
|
|---|
| 308 | return;
|
|---|
| 309 | }
|
|---|
| 310 | }
|
|---|
| 311 | }
|
|---|
| 312 |
|
|---|
| 313 |
|
|---|
| 314 | /*!
|
|---|
| 315 | Returns the button with the specified identifier \a id, or 0 if
|
|---|
| 316 | the button was not found.
|
|---|
| 317 | */
|
|---|
| 318 |
|
|---|
| 319 | QButton *QButtonGroup::find( int id ) const
|
|---|
| 320 | {
|
|---|
| 321 | // introduce a QButtonListIt if calling anything
|
|---|
| 322 | for ( QButtonItem *i=buttons->first(); i; i=buttons->next() )
|
|---|
| 323 | if ( i->id == id )
|
|---|
| 324 | return i->button;
|
|---|
| 325 | return 0;
|
|---|
| 326 | }
|
|---|
| 327 |
|
|---|
| 328 |
|
|---|
| 329 | /*!
|
|---|
| 330 | \fn void QButtonGroup::pressed( int id )
|
|---|
| 331 |
|
|---|
| 332 | This signal is emitted when a button in the group is \link
|
|---|
| 333 | QButton::pressed() pressed\endlink. The \a id argument is the
|
|---|
| 334 | button's identifier.
|
|---|
| 335 |
|
|---|
| 336 | \sa insert()
|
|---|
| 337 | */
|
|---|
| 338 |
|
|---|
| 339 | /*!
|
|---|
| 340 | \fn void QButtonGroup::released( int id )
|
|---|
| 341 |
|
|---|
| 342 | This signal is emitted when a button in the group is \link
|
|---|
| 343 | QButton::released() released\endlink. The \a id argument is the
|
|---|
| 344 | button's identifier.
|
|---|
| 345 |
|
|---|
| 346 | \sa insert()
|
|---|
| 347 | */
|
|---|
| 348 |
|
|---|
| 349 | /*!
|
|---|
| 350 | \fn void QButtonGroup::clicked( int id )
|
|---|
| 351 |
|
|---|
| 352 | This signal is emitted when a button in the group is \link
|
|---|
| 353 | QButton::clicked() clicked\endlink. The \a id argument is the
|
|---|
| 354 | button's identifier.
|
|---|
| 355 |
|
|---|
| 356 | \sa insert()
|
|---|
| 357 | */
|
|---|
| 358 |
|
|---|
| 359 |
|
|---|
| 360 | /*!
|
|---|
| 361 | \internal
|
|---|
| 362 | This slot is activated when one of the buttons in the group emits the
|
|---|
| 363 | QButton::pressed() signal.
|
|---|
| 364 | */
|
|---|
| 365 |
|
|---|
| 366 | void QButtonGroup::buttonPressed()
|
|---|
| 367 | {
|
|---|
| 368 | // introduce a QButtonListIt if calling anything
|
|---|
| 369 | int id = -1;
|
|---|
| 370 | QButton *bt = (QButton *)sender(); // object that sent the signal
|
|---|
| 371 | for ( register QButtonItem *i=buttons->first(); i; i=buttons->next() )
|
|---|
| 372 | if ( bt == i->button ) { // button was clicked
|
|---|
| 373 | id = i->id;
|
|---|
| 374 | break;
|
|---|
| 375 | }
|
|---|
| 376 | if ( id != -1 )
|
|---|
| 377 | emit pressed( id );
|
|---|
| 378 | }
|
|---|
| 379 |
|
|---|
| 380 | /*!
|
|---|
| 381 | \internal
|
|---|
| 382 | This slot is activated when one of the buttons in the group emits the
|
|---|
| 383 | QButton::released() signal.
|
|---|
| 384 | */
|
|---|
| 385 |
|
|---|
| 386 | void QButtonGroup::buttonReleased()
|
|---|
| 387 | {
|
|---|
| 388 | // introduce a QButtonListIt if calling anything
|
|---|
| 389 | int id = -1;
|
|---|
| 390 | QButton *bt = (QButton *)sender(); // object that sent the signal
|
|---|
| 391 | for ( register QButtonItem *i=buttons->first(); i; i=buttons->next() )
|
|---|
| 392 | if ( bt == i->button ) { // button was clicked
|
|---|
| 393 | id = i->id;
|
|---|
| 394 | break;
|
|---|
| 395 | }
|
|---|
| 396 | if ( id != -1 )
|
|---|
| 397 | emit released( id );
|
|---|
| 398 | }
|
|---|
| 399 |
|
|---|
| 400 | /*!
|
|---|
| 401 | \internal
|
|---|
| 402 | This slot is activated when one of the buttons in the group emits the
|
|---|
| 403 | QButton::clicked() signal.
|
|---|
| 404 | */
|
|---|
| 405 |
|
|---|
| 406 | void QButtonGroup::buttonClicked()
|
|---|
| 407 | {
|
|---|
| 408 | // introduce a QButtonListIt if calling anything
|
|---|
| 409 | int id = -1;
|
|---|
| 410 | QButton *bt = ::qt_cast<QButton*>(sender()); // object that sent the signal
|
|---|
| 411 | #if defined(QT_CHECK_NULL)
|
|---|
| 412 | Q_ASSERT( bt );
|
|---|
| 413 | #endif
|
|---|
| 414 | for ( register QButtonItem *i=buttons->first(); i; i=buttons->next() ) {
|
|---|
| 415 | if ( bt == i->button ) { // button was clicked
|
|---|
| 416 | id = i->id;
|
|---|
| 417 | break;
|
|---|
| 418 | }
|
|---|
| 419 | }
|
|---|
| 420 | if ( id != -1 )
|
|---|
| 421 | emit clicked( id );
|
|---|
| 422 | }
|
|---|
| 423 |
|
|---|
| 424 |
|
|---|
| 425 | /*!
|
|---|
| 426 | \internal
|
|---|
| 427 | This slot is activated when one of the buttons in the group emits the
|
|---|
| 428 | QButton::toggled() signal.
|
|---|
| 429 | */
|
|---|
| 430 |
|
|---|
| 431 | void QButtonGroup::buttonToggled( bool on )
|
|---|
| 432 | {
|
|---|
| 433 | // introduce a QButtonListIt if calling anything
|
|---|
| 434 | if ( !on || !excl_grp && !radio_excl )
|
|---|
| 435 | return;
|
|---|
| 436 | QButton *bt = ::qt_cast<QButton*>(sender()); // object that sent the signal
|
|---|
| 437 | #if defined(QT_CHECK_NULL)
|
|---|
| 438 | Q_ASSERT( bt );
|
|---|
| 439 | Q_ASSERT( bt->isToggleButton() );
|
|---|
| 440 | #endif
|
|---|
| 441 |
|
|---|
| 442 | if ( !excl_grp && !::qt_cast<QRadioButton*>(bt) )
|
|---|
| 443 | return;
|
|---|
| 444 | QButtonItem * i = buttons->first();
|
|---|
| 445 | bool hasTabFocus = FALSE;
|
|---|
| 446 |
|
|---|
| 447 | while( i != 0 && hasTabFocus == FALSE ) {
|
|---|
| 448 | if ( ( excl_grp || ::qt_cast<QRadioButton*>(i->button) ) &&
|
|---|
| 449 | (i->button->focusPolicy() & TabFocus) )
|
|---|
| 450 | hasTabFocus = TRUE;
|
|---|
| 451 | i = buttons->next();
|
|---|
| 452 | }
|
|---|
| 453 |
|
|---|
| 454 | i = buttons->first();
|
|---|
| 455 | while( i ) {
|
|---|
| 456 | if ( bt != i->button &&
|
|---|
| 457 | i->button->isToggleButton() &&
|
|---|
| 458 | i->button->isOn() &&
|
|---|
| 459 | ( excl_grp || ::qt_cast<QRadioButton*>(i->button) ) )
|
|---|
| 460 | i->button->setOn( FALSE );
|
|---|
| 461 | if ( ( excl_grp || ::qt_cast<QRadioButton*>(i->button) ) &&
|
|---|
| 462 | i->button->isToggleButton() &&
|
|---|
| 463 | hasTabFocus )
|
|---|
| 464 | i->button->setFocusPolicy( (FocusPolicy)(i->button->focusPolicy() &
|
|---|
| 465 | ~TabFocus) );
|
|---|
| 466 | i = buttons->next();
|
|---|
| 467 | }
|
|---|
| 468 |
|
|---|
| 469 | if ( hasTabFocus )
|
|---|
| 470 | bt->setFocusPolicy( (FocusPolicy)(bt->focusPolicy() | TabFocus) );
|
|---|
| 471 | }
|
|---|
| 472 |
|
|---|
| 473 |
|
|---|
| 474 |
|
|---|
| 475 | void QButtonGroup::setButton( int id )
|
|---|
| 476 | {
|
|---|
| 477 | QButton * b = find( id );
|
|---|
| 478 | if ( b )
|
|---|
| 479 | b->setOn( TRUE );
|
|---|
| 480 | }
|
|---|
| 481 |
|
|---|
| 482 | void QButtonGroup::setRadioButtonExclusive( bool on)
|
|---|
| 483 | {
|
|---|
| 484 | radio_excl = on;
|
|---|
| 485 | }
|
|---|
| 486 |
|
|---|
| 487 |
|
|---|
| 488 | /*!
|
|---|
| 489 | Moves the keyboard focus according to \a key, and if appropriate
|
|---|
| 490 | checks the new focus item.
|
|---|
| 491 |
|
|---|
| 492 | This function does nothing unless the keyboard focus points to one
|
|---|
| 493 | of the button group members and \a key is one of \c Key_Up, \c
|
|---|
| 494 | Key_Down, \c Key_Left and \c Key_Right.
|
|---|
| 495 | */
|
|---|
| 496 |
|
|---|
| 497 | void QButtonGroup::moveFocus( int key )
|
|---|
| 498 | {
|
|---|
| 499 | QWidget * f = qApp->focusWidget();
|
|---|
| 500 |
|
|---|
| 501 | QButtonItem * i;
|
|---|
| 502 | i = buttons->first();
|
|---|
| 503 | while( i && i->button != f )
|
|---|
| 504 | i = buttons->next();
|
|---|
| 505 |
|
|---|
| 506 | if ( !i || !i->button )
|
|---|
| 507 | return;
|
|---|
| 508 |
|
|---|
| 509 | QWidget * candidate = 0;
|
|---|
| 510 | int bestScore = -1;
|
|---|
| 511 |
|
|---|
| 512 | QPoint goal( f->mapToGlobal( f->geometry().center() ) );
|
|---|
| 513 |
|
|---|
| 514 | i = buttons->first();
|
|---|
| 515 | while( i && i->button ) {
|
|---|
| 516 | if ( i->button != f &&
|
|---|
| 517 | i->button->isEnabled() ) {
|
|---|
| 518 | QPoint p(i->button->mapToGlobal(i->button->geometry().center()));
|
|---|
| 519 | int score = (p.y() - goal.y())*(p.y() - goal.y()) +
|
|---|
| 520 | (p.x() - goal.x())*(p.x() - goal.x());
|
|---|
| 521 | bool betterScore = score < bestScore || !candidate;
|
|---|
| 522 | switch( key ) {
|
|---|
| 523 | case Key_Up:
|
|---|
| 524 | if ( p.y() < goal.y() && betterScore ) {
|
|---|
| 525 | if ( QABS( p.x() - goal.x() ) < QABS( p.y() - goal.y() ) ) {
|
|---|
| 526 | candidate = i->button;
|
|---|
| 527 | bestScore = score;
|
|---|
| 528 | } else if ( i->button->x() == f->x() ) {
|
|---|
| 529 | candidate = i->button;
|
|---|
| 530 | bestScore = score/2;
|
|---|
| 531 | }
|
|---|
| 532 | }
|
|---|
| 533 | break;
|
|---|
| 534 | case Key_Down:
|
|---|
| 535 | if ( p.y() > goal.y() && betterScore ) {
|
|---|
| 536 | if ( QABS( p.x() - goal.x() ) < QABS( p.y() - goal.y() ) ) {
|
|---|
| 537 | candidate = i->button;
|
|---|
| 538 | bestScore = score;
|
|---|
| 539 | } else if ( i->button->x() == f->x() ) {
|
|---|
| 540 | candidate = i->button;
|
|---|
| 541 | bestScore = score/2;
|
|---|
| 542 | }
|
|---|
| 543 | }
|
|---|
| 544 | break;
|
|---|
| 545 | case Key_Left:
|
|---|
| 546 | if ( p.x() < goal.x() && betterScore ) {
|
|---|
| 547 | if ( QABS( p.y() - goal.y() ) < QABS( p.x() - goal.x() ) ) {
|
|---|
| 548 | candidate = i->button;
|
|---|
| 549 | bestScore = score;
|
|---|
| 550 | } else if ( i->button->y() == f->y() ) {
|
|---|
| 551 | candidate = i->button;
|
|---|
| 552 | bestScore = score/2;
|
|---|
| 553 | }
|
|---|
| 554 | }
|
|---|
| 555 | break;
|
|---|
| 556 | case Key_Right:
|
|---|
| 557 | if ( p.x() > goal.x() && betterScore ) {
|
|---|
| 558 | if ( QABS( p.y() - goal.y() ) < QABS( p.x() - goal.x() ) ) {
|
|---|
| 559 | candidate = i->button;
|
|---|
| 560 | bestScore = score;
|
|---|
| 561 | } else if ( i->button->y() == f->y() ) {
|
|---|
| 562 | candidate = i->button;
|
|---|
| 563 | bestScore = score/2;
|
|---|
| 564 | }
|
|---|
| 565 | }
|
|---|
| 566 | break;
|
|---|
| 567 | }
|
|---|
| 568 | }
|
|---|
| 569 | i = buttons->next();
|
|---|
| 570 | }
|
|---|
| 571 |
|
|---|
| 572 | QButton *buttoncand = ::qt_cast<QButton*>(candidate);
|
|---|
| 573 | if ( buttoncand && ::qt_cast<QButton*>(f) &&
|
|---|
| 574 | ((QButton*)f)->isOn() &&
|
|---|
| 575 | buttoncand->isToggleButton() &&
|
|---|
| 576 | ( isExclusive() || ( ::qt_cast<QRadioButton*>(f) &&
|
|---|
| 577 | ::qt_cast<QRadioButton*>(candidate)))) {
|
|---|
| 578 | if ( f->focusPolicy() & TabFocus ) {
|
|---|
| 579 | f->setFocusPolicy( (FocusPolicy)(f->focusPolicy() & ~TabFocus) );
|
|---|
| 580 | candidate->setFocusPolicy( (FocusPolicy)(candidate->focusPolicy()|
|
|---|
| 581 | TabFocus) );
|
|---|
| 582 | }
|
|---|
| 583 | buttoncand->setOn( TRUE );
|
|---|
| 584 | buttoncand->animateClick();
|
|---|
| 585 | buttoncand->animateTimeout(); // ### crude l&f hack
|
|---|
| 586 | }
|
|---|
| 587 |
|
|---|
| 588 | if ( candidate ) {
|
|---|
| 589 | if (key == Key_Up || key == Key_Left)
|
|---|
| 590 | QFocusEvent::setReason(QFocusEvent::Backtab);
|
|---|
| 591 | else
|
|---|
| 592 | QFocusEvent::setReason(QFocusEvent::Tab);
|
|---|
| 593 | candidate->setFocus();
|
|---|
| 594 | QFocusEvent::resetReason();
|
|---|
| 595 | }
|
|---|
| 596 | }
|
|---|
| 597 |
|
|---|
| 598 |
|
|---|
| 599 | /*!
|
|---|
| 600 | Returns the selected toggle button if exactly one is selected;
|
|---|
| 601 | otherwise returns 0.
|
|---|
| 602 |
|
|---|
| 603 | \sa selectedId()
|
|---|
| 604 | */
|
|---|
| 605 |
|
|---|
| 606 | QButton * QButtonGroup::selected() const
|
|---|
| 607 | {
|
|---|
| 608 | if ( !buttons )
|
|---|
| 609 | return 0;
|
|---|
| 610 | QButtonListIt it( *buttons );
|
|---|
| 611 | QButtonItem *i;
|
|---|
| 612 | QButton *candidate = 0;
|
|---|
| 613 |
|
|---|
| 614 | while ( (i = it.current()) != 0 ) {
|
|---|
| 615 | ++it;
|
|---|
| 616 | if ( i->button && i->button->isToggleButton() && i->button->isOn() ) {
|
|---|
| 617 | if ( candidate != 0 )
|
|---|
| 618 | return 0;
|
|---|
| 619 | candidate = i->button;
|
|---|
| 620 | }
|
|---|
| 621 | }
|
|---|
| 622 | return candidate;
|
|---|
| 623 | }
|
|---|
| 624 |
|
|---|
| 625 | /*!
|
|---|
| 626 | \property QButtonGroup::selectedId
|
|---|
| 627 | \brief The id of the selected toggle button.
|
|---|
| 628 |
|
|---|
| 629 | If no toggle button is selected, id() returns -1.
|
|---|
| 630 |
|
|---|
| 631 | If setButton() is called on an exclusive group, the button with
|
|---|
| 632 | the given id will be set to on and all the others will be set to
|
|---|
| 633 | off.
|
|---|
| 634 |
|
|---|
| 635 | \sa selected()
|
|---|
| 636 | */
|
|---|
| 637 |
|
|---|
| 638 | int QButtonGroup::selectedId() const
|
|---|
| 639 | {
|
|---|
| 640 | return id( selected() );
|
|---|
| 641 | }
|
|---|
| 642 |
|
|---|
| 643 |
|
|---|
| 644 | /*!
|
|---|
| 645 | Returns the id of \a button, or -1 if \a button is not a member of
|
|---|
| 646 | this group.
|
|---|
| 647 |
|
|---|
| 648 | \sa selectedId();
|
|---|
| 649 | */
|
|---|
| 650 |
|
|---|
| 651 | int QButtonGroup::id( QButton * button ) const
|
|---|
| 652 | {
|
|---|
| 653 | QButtonItem *i = buttons->first();
|
|---|
| 654 | while ( i && i->button != button )
|
|---|
| 655 | i = buttons->next();
|
|---|
| 656 | return i ? i->id : -1;
|
|---|
| 657 | }
|
|---|
| 658 |
|
|---|
| 659 |
|
|---|
| 660 | /*!
|
|---|
| 661 | \reimp
|
|---|
| 662 | */
|
|---|
| 663 | bool QButtonGroup::event( QEvent * e )
|
|---|
| 664 | {
|
|---|
| 665 | if ( e->type() == QEvent::ChildInserted ) {
|
|---|
| 666 | QChildEvent * ce = (QChildEvent *) e;
|
|---|
| 667 | if ( radio_excl && ::qt_cast<QRadioButton*>(ce->child()) ) {
|
|---|
| 668 | QButton * button = (QButton *) ce->child();
|
|---|
| 669 | if ( button->isToggleButton() && !button->isOn() &&
|
|---|
| 670 | selected() && (selected()->focusPolicy() & TabFocus) != 0 )
|
|---|
| 671 | button->setFocusPolicy( (FocusPolicy)(button->focusPolicy() &
|
|---|
| 672 | ~TabFocus) );
|
|---|
| 673 | }
|
|---|
| 674 | }
|
|---|
| 675 | return QGroupBox::event( e );
|
|---|
| 676 | }
|
|---|
| 677 | #endif
|
|---|