File indexing completed on 2024-04-14 15:49:41
0001 // SPDX-FileCopyrightText: 2006 Pino Toscano <toscano.pino@tiscali.it> 0002 // SPDX-FileCopyrightText: 2020 Simon Persson <simon.persson@mykolab.com> 0003 // 0004 // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 0006 #include "kbuttongroup.h" 0007 0008 #include <QChildEvent> 0009 #include <QHash> 0010 #include <QAbstractButton> 0011 #include <QSignalMapper> 0012 0013 class KButtonGroup::Private 0014 { 0015 public: 0016 explicit Private(KButtonGroup *q) : 0017 q(q), 0018 currentId(-1), 0019 nextId(0), 0020 wantToBeId(-1) 0021 { 0022 connect(&clickedMapper, SIGNAL(mapped(int)), q, SLOT(slotClicked(int))); 0023 connect(&pressedMapper, SIGNAL(mapped(int)), q, SIGNAL(pressed(int))); 0024 connect(&releasedMapper, SIGNAL(mapped(int)), q, SIGNAL(released(int))); 0025 } 0026 0027 void slotClicked(int id); 0028 0029 KButtonGroup *q; 0030 QSignalMapper clickedMapper; 0031 QSignalMapper pressedMapper; 0032 QSignalMapper releasedMapper; 0033 0034 QHash<QObject *, int> btnMap; 0035 int currentId; 0036 int nextId; 0037 int wantToBeId; 0038 }; 0039 0040 KButtonGroup::KButtonGroup(QWidget *parent) : QGroupBox(parent), d(new Private(this)) 0041 { 0042 } 0043 0044 KButtonGroup::~KButtonGroup() 0045 { 0046 delete d; 0047 } 0048 0049 void KButtonGroup::setSelected(int id) 0050 { 0051 if (!testAttribute(Qt::WA_WState_Polished)) { 0052 d->wantToBeId = id; 0053 ensurePolished(); 0054 return; 0055 } 0056 0057 QHash<QObject *, int>::Iterator it = d->btnMap.begin(); 0058 QHash<QObject *, int>::Iterator itEnd = d->btnMap.end(); 0059 QAbstractButton *button = nullptr; 0060 0061 for (; it != itEnd; ++it) { 0062 if ((it.value() == id) && (button = qobject_cast<QAbstractButton *>(it.key()))) { 0063 button->setChecked(true); 0064 d->currentId = id; 0065 emit changed(id); 0066 d->wantToBeId = -1; 0067 return; 0068 } 0069 } 0070 // button not found, it might still show up though, eg. because of premature polishing above 0071 d->wantToBeId = id; 0072 } 0073 0074 int KButtonGroup::selected() const 0075 { 0076 return d->currentId; 0077 } 0078 0079 void KButtonGroup::childEvent(QChildEvent *event) 0080 { 0081 if (event->polished()) { 0082 auto button = qobject_cast<QAbstractButton *>(event->child()); 0083 if (!d->btnMap.contains(event->child()) && button) { 0084 connect(button, SIGNAL(clicked()), &d->clickedMapper, SLOT(map())); 0085 d->clickedMapper.setMapping(button, d->nextId); 0086 0087 connect(button, SIGNAL(pressed()), &d->pressedMapper, SLOT(map())); 0088 d->pressedMapper.setMapping(button, d->nextId); 0089 0090 connect(button, SIGNAL(released()), &d->releasedMapper, SLOT(map())); 0091 d->releasedMapper.setMapping(button, d->nextId); 0092 0093 d->btnMap[button] = d->nextId; 0094 0095 if (d->nextId == d->wantToBeId) { 0096 d->currentId = d->wantToBeId; 0097 d->wantToBeId = -1; 0098 button->setChecked(true); 0099 emit changed(d->currentId); 0100 } 0101 0102 ++d->nextId; 0103 } 0104 } else if (event->removed()) { 0105 QObject *obj = event->child(); 0106 QHash<QObject *, int>::ConstIterator it = d->btnMap.constFind(obj); 0107 0108 if (it != d->btnMap.constEnd()) { 0109 d->clickedMapper.removeMappings(obj); 0110 d->pressedMapper.removeMappings(obj); 0111 d->releasedMapper.removeMappings(obj); 0112 0113 if (it.value() == d->currentId) { 0114 d->currentId = -1; 0115 } 0116 0117 d->btnMap.remove(obj); 0118 } 0119 } 0120 0121 // be transparent 0122 QGroupBox::childEvent(event); 0123 } 0124 0125 int KButtonGroup::id(QAbstractButton *button) const 0126 { 0127 QHash<QObject *, int>::ConstIterator it = d->btnMap.constFind(button); 0128 0129 if (it != d->btnMap.constEnd()) { 0130 return it.value(); 0131 } 0132 0133 return -1; 0134 } 0135 0136 void KButtonGroup::Private::slotClicked(int id) 0137 { 0138 currentId = id; 0139 emit q->clicked(id); 0140 emit q->changed(id); 0141 } 0142 0143 #include "moc_kbuttongroup.cpp" 0144 0145