File indexing completed on 2024-04-14 14:20:16
0001 /* 0002 This file is part of the KDE Libraries 0003 0004 Copyright (C) 2006 Pino Toscano <toscano.pino@tiscali.it> 0005 0006 This library is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU Library General Public 0008 License as published by the Free Software Foundation; either 0009 version 2 of the License, or (at your option) any later version. 0010 0011 This library is distributed in the hope that it will be useful, 0012 but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0014 Library General Public License for more details. 0015 0016 You should have received a copy of the GNU Library General Public License 0017 along with this library; see the file COPYING.LIB. If not, write to 0018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0019 Boston, MA 02110-1301, USA. 0020 */ 0021 0022 #include "kbuttongroup.h" 0023 0024 #include <QChildEvent> 0025 #include <QHash> 0026 #include <QAbstractButton> 0027 #include <QSignalMapper> 0028 0029 class Q_DECL_HIDDEN KButtonGroup::Private 0030 { 0031 public: 0032 Private(KButtonGroup *q) : 0033 q(q), 0034 clickedMapper(), 0035 pressedMapper(), 0036 releasedMapper(), 0037 currentId(-1), 0038 nextId(0), 0039 wantToBeId(-1) 0040 { 0041 connect(&clickedMapper, SIGNAL(mapped(int)), q, SLOT(slotClicked(int))); 0042 connect(&pressedMapper, SIGNAL(mapped(int)), q, SIGNAL(pressed(int))); 0043 connect(&releasedMapper, SIGNAL(mapped(int)), q, SIGNAL(released(int))); 0044 } 0045 0046 void slotClicked(int id); 0047 0048 KButtonGroup *q; 0049 QSignalMapper clickedMapper; 0050 QSignalMapper pressedMapper; 0051 QSignalMapper releasedMapper; 0052 0053 QHash<QObject *, int> btnMap; 0054 int currentId; 0055 int nextId; 0056 int wantToBeId; 0057 }; 0058 0059 KButtonGroup::KButtonGroup(QWidget *parent) : QGroupBox(parent), d(new Private(this)) 0060 { 0061 } 0062 0063 KButtonGroup::~KButtonGroup() 0064 { 0065 delete d; 0066 } 0067 0068 void KButtonGroup::setSelected(int id) 0069 { 0070 if (!testAttribute(Qt::WA_WState_Polished)) { 0071 d->wantToBeId = id; 0072 ensurePolished(); 0073 return; 0074 } 0075 0076 QHash<QObject *, int>::Iterator it = d->btnMap.begin(); 0077 QHash<QObject *, int>::Iterator itEnd = d->btnMap.end(); 0078 QAbstractButton *button = nullptr; 0079 0080 for (; it != itEnd; ++it) { 0081 if ((it.value() == id) && (button = qobject_cast<QAbstractButton *>(it.key()))) { 0082 button->setChecked(true); 0083 d->currentId = id; 0084 emit changed(id); 0085 d->wantToBeId = -1; 0086 return; 0087 } 0088 } 0089 // button not found, it might still show up though, eg. because of premature polishing above 0090 d->wantToBeId = id; 0091 } 0092 0093 int KButtonGroup::selected() const 0094 { 0095 return d->currentId; 0096 } 0097 0098 void KButtonGroup::childEvent(QChildEvent *event) 0099 { 0100 if (event->polished()) { 0101 QAbstractButton *button = qobject_cast<QAbstractButton *>(event->child()); 0102 if (!d->btnMap.contains(event->child()) && button) { 0103 connect(button, SIGNAL(clicked()), &d->clickedMapper, SLOT(map())); 0104 d->clickedMapper.setMapping(button, d->nextId); 0105 0106 connect(button, SIGNAL(pressed()), &d->pressedMapper, SLOT(map())); 0107 d->pressedMapper.setMapping(button, d->nextId); 0108 0109 connect(button, SIGNAL(released()), &d->releasedMapper, SLOT(map())); 0110 d->releasedMapper.setMapping(button, d->nextId); 0111 0112 d->btnMap[button] = d->nextId; 0113 0114 if (d->nextId == d->wantToBeId) { 0115 d->currentId = d->wantToBeId; 0116 d->wantToBeId = -1; 0117 button->setChecked(true); 0118 emit changed(d->currentId); 0119 } 0120 0121 ++d->nextId; 0122 } 0123 } else if (event->removed()) { 0124 QObject *obj = event->child(); 0125 QHash<QObject *, int>::ConstIterator it = d->btnMap.constFind(obj); 0126 0127 if (it != d->btnMap.constEnd()) { 0128 d->clickedMapper.removeMappings(obj); 0129 d->pressedMapper.removeMappings(obj); 0130 d->releasedMapper.removeMappings(obj); 0131 0132 if (it.value() == d->currentId) { 0133 d->currentId = -1; 0134 } 0135 0136 d->btnMap.remove(obj); 0137 } 0138 } 0139 0140 // be transparent 0141 QGroupBox::childEvent(event); 0142 } 0143 0144 int KButtonGroup::id(QAbstractButton *button) const 0145 { 0146 QHash<QObject *, int>::ConstIterator it = d->btnMap.constFind(button); 0147 0148 if (it != d->btnMap.constEnd()) { 0149 return it.value(); 0150 } 0151 0152 return -1; 0153 } 0154 0155 void KButtonGroup::Private::slotClicked(int id) 0156 { 0157 currentId = id; 0158 emit q->clicked(id); 0159 emit q->changed(id); 0160 } 0161 0162 #include "moc_kbuttongroup.cpp" 0163