kdelibs/kdeui/widgets/kbuttongroup.cpp

163 lines
4.5 KiB
C++

/*
This file is part of the KDE Libraries
Copyright (C) 2006 Pino Toscano <toscano.pino@tiscali.it>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "kbuttongroup.h"
#include <QtCore/qcoreevent.h>
#include <QHash>
#include <QAbstractButton>
#include <QSignalMapper>
class KButtonGroup::Private
{
public:
Private(KButtonGroup* q) :
q(q),
clickedMapper(),
pressedMapper(),
releasedMapper(),
currentId(-1),
nextId(0),
wantToBeId(-1)
{
connect(&clickedMapper, SIGNAL(mapped(int)), q, SLOT(slotClicked(int)));
connect(&pressedMapper, SIGNAL(mapped(int)), q, SIGNAL(pressed(int)));
connect(&releasedMapper, SIGNAL(mapped(int)), q, SIGNAL(released(int)));
}
void slotClicked(int id);
KButtonGroup *q;
QSignalMapper clickedMapper;
QSignalMapper pressedMapper;
QSignalMapper releasedMapper;
QHash<QObject*, int> btnMap;
int currentId;
int nextId;
int wantToBeId;
};
KButtonGroup::KButtonGroup(QWidget* parent) : QGroupBox(parent), d(new Private(this))
{
}
KButtonGroup::~KButtonGroup()
{
delete d;
}
void KButtonGroup::setSelected(int id)
{
if (!testAttribute(Qt::WA_WState_Polished)) {
d->wantToBeId = id;
ensurePolished();
return;
}
QHash<QObject*, int>::Iterator it = d->btnMap.begin();
QHash<QObject*, int>::Iterator itEnd = d->btnMap.end();
QAbstractButton* button = 0;
for (; it != itEnd; ++it) {
if ((it.value() == id) && (button = qobject_cast<QAbstractButton*>(it.key()))) {
button->setChecked(true);
d->currentId = id;
emit changed(id);
d->wantToBeId = -1;
return;
}
}
// button not found, it might still show up though, eg. because of premature polishing above
d->wantToBeId = id;
}
int KButtonGroup::selected() const
{
return d->currentId;
}
void KButtonGroup::childEvent(QChildEvent* event)
{
if (event->polished()) {
QAbstractButton* button = qobject_cast<QAbstractButton*>(event->child());
if (!d->btnMap.contains( event->child()) && button) {
connect(button, SIGNAL(clicked()), &d->clickedMapper, SLOT(map()));
d->clickedMapper.setMapping(button, d->nextId);
connect(button, SIGNAL(pressed()), &d->pressedMapper, SLOT(map()));
d->pressedMapper.setMapping(button, d->nextId);
connect(button, SIGNAL(released()), &d->releasedMapper, SLOT(map()));
d->releasedMapper.setMapping(button, d->nextId);
d->btnMap[button] = d->nextId;
if (d->nextId == d->wantToBeId) {
d->currentId = d->wantToBeId;
d->wantToBeId = -1;
button->setChecked(true);
emit changed( d->currentId );
}
++d->nextId;
}
} else if (event->removed()) {
QObject* obj = event->child();
QHash<QObject*, int>::ConstIterator it = d->btnMap.constFind(obj);
if (it != d->btnMap.constEnd()) {
d->clickedMapper.removeMappings(obj);
d->pressedMapper.removeMappings(obj);
d->releasedMapper.removeMappings(obj);
if (it.value() == d->currentId) {
d->currentId = -1;
}
d->btnMap.remove(obj);
}
}
// be transparent
QGroupBox::childEvent(event);
}
int KButtonGroup::id(QAbstractButton* button) const
{
QHash<QObject*, int>::ConstIterator it = d->btnMap.constFind(button);
if (it != d->btnMap.constEnd()) {
return it.value();
}
return -1;
}
void KButtonGroup::Private::slotClicked(int id)
{
currentId = id;
emit q->clicked(id);
emit q->changed(id);
}
#include "moc_kbuttongroup.cpp"