KDEUI
kbuttongroup.cpp
Go to the documentation of this file.
00001 /* 00002 This file is part of the KDE Libraries 00003 00004 Copyright (C) 2006 Pino Toscano <toscano.pino@tiscali.it> 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Library General Public 00008 License as published by the Free Software Foundation; either 00009 version 2 of the License, or (at your option) any later version. 00010 00011 This library is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 Library General Public License for more details. 00015 00016 You should have received a copy of the GNU Library General Public License 00017 along with this library; see the file COPYING.LIB. If not, write to 00018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00019 Boston, MA 02110-1301, USA. 00020 */ 00021 00022 #include "kbuttongroup.h" 00023 00024 #include <QChildEvent> 00025 #include <QHash> 00026 #include <QAbstractButton> 00027 #include <QSignalMapper> 00028 00029 class KButtonGroup::Private 00030 { 00031 public: 00032 Private( KButtonGroup* q ) 00033 : q(q), clickedMapper(), pressedMapper(), releasedMapper(), 00034 currentId( -1 ), nextId( 0 ), wantToBeId( -1 ) 00035 { 00036 connect( &clickedMapper, SIGNAL( mapped( int ) ), q, SLOT( slotClicked( int ) ) ); 00037 connect( &pressedMapper, SIGNAL( mapped( int ) ), q, SIGNAL( pressed( int ) ) ); 00038 connect( &releasedMapper, SIGNAL( mapped( int ) ), q, SIGNAL( released( int ) ) ); 00039 } 00040 00041 void slotClicked( int id ); 00042 00043 KButtonGroup *q; 00044 QSignalMapper clickedMapper; 00045 QSignalMapper pressedMapper; 00046 QSignalMapper releasedMapper; 00047 00048 QHash<QObject*, int> btnMap; 00049 int currentId; 00050 int nextId; 00051 int wantToBeId; 00052 }; 00053 00054 KButtonGroup::KButtonGroup( QWidget* parent ) 00055 : QGroupBox( parent ), d( new Private( this ) ) 00056 { 00057 } 00058 00059 KButtonGroup::~KButtonGroup() 00060 { 00061 delete d; 00062 } 00063 00064 void KButtonGroup::setSelected( int id ) 00065 { 00066 if ( !testAttribute( Qt::WA_WState_Polished ) ) 00067 { 00068 d->wantToBeId = id; 00069 ensurePolished(); 00070 return; 00071 } 00072 00073 QHash<QObject*, int>::Iterator it = d->btnMap.begin(); 00074 QHash<QObject*, int>::Iterator itEnd = d->btnMap.end(); 00075 QAbstractButton* button = 0; 00076 for ( ; it != itEnd; ++it ) 00077 { 00078 if ( ( it.value() == id ) && ( button = qobject_cast<QAbstractButton*>( it.key() ) ) ) 00079 { 00080 button->setChecked( true ); 00081 d->currentId = id; 00082 emit changed( id ); 00083 d->wantToBeId = -1; 00084 return; 00085 } 00086 } 00087 // button not found, it might still show up though, eg. because of premature polishing above 00088 d->wantToBeId = id; 00089 } 00090 00091 int KButtonGroup::selected() const 00092 { 00093 return d->currentId; 00094 } 00095 00096 void KButtonGroup::childEvent( QChildEvent* event ) 00097 { 00098 if ( event->polished() ) 00099 { 00100 QAbstractButton* button = qobject_cast<QAbstractButton*>( event->child() ); 00101 if ( !d->btnMap.contains( event->child() ) && button ) 00102 { 00103 connect( button, SIGNAL( clicked() ), &d->clickedMapper, SLOT( map() ) ); 00104 d->clickedMapper.setMapping( button, d->nextId ); 00105 00106 connect( button, SIGNAL( pressed() ), &d->pressedMapper, SLOT( map() ) ); 00107 d->pressedMapper.setMapping( button, d->nextId ); 00108 00109 connect( button, SIGNAL( released() ), &d->releasedMapper, SLOT( map() ) ); 00110 d->releasedMapper.setMapping( button, d->nextId ); 00111 00112 d->btnMap[ button ] = d->nextId; 00113 00114 if ( d->nextId == d->wantToBeId ) 00115 { 00116 d->currentId = d->wantToBeId; 00117 d->wantToBeId = -1; 00118 button->setChecked( true ); 00119 emit changed( d->currentId ); 00120 } 00121 00122 ++d->nextId; 00123 } 00124 } 00125 else if ( event->removed() ) 00126 { 00127 QObject* obj = event->child(); 00128 QHash<QObject*, int>::ConstIterator it = d->btnMap.constFind( obj ); 00129 if ( it != d->btnMap.constEnd() ) 00130 { 00131 d->clickedMapper.removeMappings( obj ); 00132 d->pressedMapper.removeMappings( obj ); 00133 d->releasedMapper.removeMappings( obj ); 00134 00135 if ( it.value() == d->currentId ) 00136 d->currentId = -1; 00137 00138 d->btnMap.remove( obj ); 00139 } 00140 } 00141 00142 // be transparent 00143 QGroupBox::childEvent( event ); 00144 } 00145 00146 int KButtonGroup::id( QAbstractButton* button ) const 00147 { 00148 QHash<QObject*, int>::ConstIterator it = d->btnMap.constFind( button ); 00149 if ( it != d->btnMap.constEnd() ) 00150 { 00151 return it.value(); 00152 } 00153 return -1; 00154 } 00155 00156 void KButtonGroup::Private::slotClicked( int id ) 00157 { 00158 currentId = id; 00159 emit q->clicked( id ); 00160 emit q->changed( id ); 00161 } 00162 00163 #include "kbuttongroup.moc" 00164
KDE 4.6 API Reference