Move QButtonGroup implementation from qabstractbutton.cpp to qbuttongroup.cpp

Because it's the right thing to do.

Needed to introduce qbuttongroup_p.h because QAbstractButton
likes to poke around in QButtonGroup's private parts.

Fixed includes of qabstractbutton_p.h so it compiles on it's
own.

Change-Id: Ic7725277d2419754de273b2abd4790476edd0eb4
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
This commit is contained in:
Marc Mutz 2016-03-17 16:24:26 +01:00
parent 0e6ad27549
commit 69335920f7
5 changed files with 198 additions and 148 deletions

View File

@ -31,7 +31,9 @@
** **
****************************************************************************/ ****************************************************************************/
#include "qabstractbutton.h" #include "private/qabstractbutton_p.h"
#include "private/qbuttongroup_p.h"
#include "qabstractitemview.h" #include "qabstractitemview.h"
#include "qbuttongroup.h" #include "qbuttongroup.h"
#include "qabstractbutton_p.h" #include "qabstractbutton_p.h"
@ -171,137 +173,6 @@ QAbstractButtonPrivate::QAbstractButtonPrivate(QSizePolicy::ControlType type)
controlType(type) controlType(type)
{} {}
#ifndef QT_NO_BUTTONGROUP
class QButtonGroupPrivate: public QObjectPrivate
{
Q_DECLARE_PUBLIC(QButtonGroup)
public:
QButtonGroupPrivate():exclusive(true){}
QList<QAbstractButton *> buttonList;
QPointer<QAbstractButton> checkedButton;
void detectCheckedButton();
void notifyChecked(QAbstractButton *button);
bool exclusive;
QHash<QAbstractButton*, int> mapping;
};
QButtonGroup::QButtonGroup(QObject *parent)
: QObject(*new QButtonGroupPrivate, parent)
{
}
QButtonGroup::~QButtonGroup()
{
Q_D(QButtonGroup);
for (int i = 0; i < d->buttonList.count(); ++i)
d->buttonList.at(i)->d_func()->group = 0;
}
bool QButtonGroup::exclusive() const
{
Q_D(const QButtonGroup);
return d->exclusive;
}
void QButtonGroup::setExclusive(bool exclusive)
{
Q_D(QButtonGroup);
d->exclusive = exclusive;
}
void QButtonGroup::addButton(QAbstractButton *button, int id)
{
Q_D(QButtonGroup);
if (QButtonGroup *previous = button->d_func()->group)
previous->removeButton(button);
button->d_func()->group = this;
d->buttonList.append(button);
if (id == -1) {
const QHash<QAbstractButton*, int>::const_iterator it
= std::min_element(d->mapping.cbegin(), d->mapping.cend());
if (it == d->mapping.cend())
d->mapping[button] = -2;
else
d->mapping[button] = *it - 1;
} else {
d->mapping[button] = id;
}
if (d->exclusive && button->isChecked())
button->d_func()->notifyChecked();
}
void QButtonGroup::removeButton(QAbstractButton *button)
{
Q_D(QButtonGroup);
if (d->checkedButton == button) {
d->detectCheckedButton();
}
if (button->d_func()->group == this) {
button->d_func()->group = 0;
d->buttonList.removeAll(button);
d->mapping.remove(button);
}
}
QList<QAbstractButton*> QButtonGroup::buttons() const
{
Q_D(const QButtonGroup);
return d->buttonList;
}
QAbstractButton *QButtonGroup::checkedButton() const
{
Q_D(const QButtonGroup);
return d->checkedButton;
}
QAbstractButton *QButtonGroup::button(int id) const
{
Q_D(const QButtonGroup);
return d->mapping.key(id);
}
void QButtonGroup::setId(QAbstractButton *button, int id)
{
Q_D(QButtonGroup);
if (button && id != -1)
d->mapping[button] = id;
}
int QButtonGroup::id(QAbstractButton *button) const
{
Q_D(const QButtonGroup);
return d->mapping.value(button, -1);
}
int QButtonGroup::checkedId() const
{
Q_D(const QButtonGroup);
return d->mapping.value(d->checkedButton, -1);
}
// detect a checked button other than the current one
void QButtonGroupPrivate::detectCheckedButton()
{
QAbstractButton *previous = checkedButton;
checkedButton = 0;
if (exclusive)
return;
for (int i = 0; i < buttonList.count(); i++) {
if (buttonList.at(i) != previous && buttonList.at(i)->isChecked()) {
checkedButton = buttonList.at(i);
return;
}
}
}
#endif // QT_NO_BUTTONGROUP
QList<QAbstractButton *>QAbstractButtonPrivate::queryButtonList() const QList<QAbstractButton *>QAbstractButtonPrivate::queryButtonList() const
{ {
#ifndef QT_NO_BUTTONGROUP #ifndef QT_NO_BUTTONGROUP

View File

@ -45,6 +45,8 @@
// We mean it. // We mean it.
// //
#include "qabstractbutton.h"
#include "QtCore/qbasictimer.h" #include "QtCore/qbasictimer.h"
#include "private/qwidget_p.h" #include "private/qwidget_p.h"

View File

@ -31,7 +31,28 @@
** **
****************************************************************************/ ****************************************************************************/
#include "private/qbuttongroup_p.h"
#ifndef QT_NO_BUTTONGROUP
#include "private/qabstractbutton_p.h"
QT_BEGIN_NAMESPACE
// detect a checked button other than the current one
void QButtonGroupPrivate::detectCheckedButton()
{
QAbstractButton *previous = checkedButton;
checkedButton = 0;
if (exclusive)
return;
for (int i = 0; i < buttonList.count(); i++) {
if (buttonList.at(i) != previous && buttonList.at(i)->isChecked()) {
checkedButton = buttonList.at(i);
return;
}
}
}
/*! /*!
\class QButtonGroup \class QButtonGroup
@ -78,18 +99,24 @@
*/ */
/*! /*!
\fn QButtonGroup::QButtonGroup(QObject *parent)
Constructs a new, empty button group with the given \a parent. Constructs a new, empty button group with the given \a parent.
\sa addButton(), setExclusive() \sa addButton(), setExclusive()
*/ */
QButtonGroup::QButtonGroup(QObject *parent)
: QObject(*new QButtonGroupPrivate, parent)
{
}
/*! /*!
\fn QButtonGroup::~QButtonGroup()
Destroys the button group. Destroys the button group.
*/ */
QButtonGroup::~QButtonGroup()
{
Q_D(QButtonGroup);
for (int i = 0; i < d->buttonList.count(); ++i)
d->buttonList.at(i)->d_func()->group = 0;
}
/*! /*!
\property QButtonGroup::exclusive \property QButtonGroup::exclusive
@ -105,6 +132,19 @@
By default, this property is \c true. By default, this property is \c true.
*/ */
bool QButtonGroup::exclusive() const
{
Q_D(const QButtonGroup);
return d->exclusive;
}
void QButtonGroup::setExclusive(bool exclusive)
{
Q_D(QButtonGroup);
d->exclusive = exclusive;
}
/*! /*!
\fn void QButtonGroup::buttonClicked(QAbstractButton *button) \fn void QButtonGroup::buttonClicked(QAbstractButton *button)
@ -187,8 +227,6 @@
/*! /*!
\fn void QButtonGroup::addButton(QAbstractButton *button, int id = -1);
Adds the given \a button to the button group. If \a id is -1, Adds the given \a button to the button group. If \a id is -1,
an id will be assigned to the button. an id will be assigned to the button.
Automatically assigned ids are guaranteed to be negative, Automatically assigned ids are guaranteed to be negative,
@ -197,42 +235,82 @@
\sa removeButton(), buttons() \sa removeButton(), buttons()
*/ */
void QButtonGroup::addButton(QAbstractButton *button, int id)
{
Q_D(QButtonGroup);
if (QButtonGroup *previous = button->d_func()->group)
previous->removeButton(button);
button->d_func()->group = this;
d->buttonList.append(button);
if (id == -1) {
const QHash<QAbstractButton*, int>::const_iterator it
= std::min_element(d->mapping.cbegin(), d->mapping.cend());
if (it == d->mapping.cend())
d->mapping[button] = -2;
else
d->mapping[button] = *it - 1;
} else {
d->mapping[button] = id;
}
if (d->exclusive && button->isChecked())
button->d_func()->notifyChecked();
}
/*! /*!
\fn void QButtonGroup::removeButton(QAbstractButton *button);
Removes the given \a button from the button group. Removes the given \a button from the button group.
\sa addButton(), buttons() \sa addButton(), buttons()
*/ */
void QButtonGroup::removeButton(QAbstractButton *button)
{
Q_D(QButtonGroup);
if (d->checkedButton == button) {
d->detectCheckedButton();
}
if (button->d_func()->group == this) {
button->d_func()->group = 0;
d->buttonList.removeAll(button);
d->mapping.remove(button);
}
}
/*! /*!
\fn QList<QAbstractButton*> QButtonGroup::buttons() const
Returns the button group's list of buttons. This may be empty. Returns the button group's list of buttons. This may be empty.
\sa addButton(), removeButton() \sa addButton(), removeButton()
*/ */
QList<QAbstractButton*> QButtonGroup::buttons() const
{
Q_D(const QButtonGroup);
return d->buttonList;
}
/*! /*!
\fn QAbstractButton *QButtonGroup::checkedButton() const;
Returns the button group's checked button, or 0 if no buttons are Returns the button group's checked button, or 0 if no buttons are
checked. checked.
\sa buttonClicked() \sa buttonClicked()
*/ */
QAbstractButton *QButtonGroup::checkedButton() const
{
Q_D(const QButtonGroup);
return d->checkedButton;
}
/*! /*!
\fn QAbstractButton *QButtonGroup::button(int id) const;
\since 4.1 \since 4.1
Returns the button with the specified \a id, or 0 if no such button Returns the button with the specified \a id, or 0 if no such button
exists. exists.
*/ */
QAbstractButton *QButtonGroup::button(int id) const
{
Q_D(const QButtonGroup);
return d->mapping.key(id);
}
/*! /*!
\fn void QButtonGroup::setId(QAbstractButton *button, int id)
\since 4.1 \since 4.1
Sets the \a id for the specified \a button. Note that \a id cannot Sets the \a id for the specified \a button. Note that \a id cannot
@ -240,9 +318,14 @@
\sa id() \sa id()
*/ */
void QButtonGroup::setId(QAbstractButton *button, int id)
{
Q_D(QButtonGroup);
if (button && id != -1)
d->mapping[button] = id;
}
/*! /*!
\fn int QButtonGroup::id(QAbstractButton *button) const;
\since 4.1 \since 4.1
Returns the id for the specified \a button, or -1 if no such button Returns the id for the specified \a button, or -1 if no such button
@ -251,14 +334,27 @@
\sa setId() \sa setId()
*/ */
int QButtonGroup::id(QAbstractButton *button) const
{
Q_D(const QButtonGroup);
return d->mapping.value(button, -1);
}
/*! /*!
\fn int QButtonGroup::checkedId() const;
\since 4.1 \since 4.1
Returns the id of the checkedButton(), or -1 if no button is checked. Returns the id of the checkedButton(), or -1 if no button is checked.
\sa setId() \sa setId()
*/ */
int QButtonGroup::checkedId() const
{
Q_D(const QButtonGroup);
return d->mapping.value(d->checkedButton, -1);
}
QT_END_NAMESPACE
#include "moc_qbuttongroup.cpp" #include "moc_qbuttongroup.cpp"
#endif // QT_NO_BUTTONGROUP

View File

@ -0,0 +1,80 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtWidgets module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QBUTTONGROUP_P_H
#define QBUTTONGROUP_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtWidgets/qbuttongroup.h>
#ifndef QT_NO_BUTTONGROUP
#include <QtCore/private/qobject_p.h>
#include <QtCore/qlist.h>
#include <QtCore/qpointer.h>
#include <QtCore/qhash.h>
QT_BEGIN_NAMESPACE
class QButtonGroupPrivate: public QObjectPrivate
{
Q_DECLARE_PUBLIC(QButtonGroup)
public:
QButtonGroupPrivate() : exclusive(true) {}
QList<QAbstractButton *> buttonList;
QPointer<QAbstractButton> checkedButton;
void detectCheckedButton();
void notifyChecked(QAbstractButton *button);
bool exclusive;
QHash<QAbstractButton*, int> mapping;
};
QT_END_NAMESPACE
#endif // QT_NO_BUTTONGROUP
#endif // QBUTTONGROUP_P_H

View File

@ -2,6 +2,7 @@
HEADERS += \ HEADERS += \
widgets/qbuttongroup.h \ widgets/qbuttongroup.h \
widgets/qbuttongroup_p.h \
widgets/qabstractbutton.h \ widgets/qabstractbutton.h \
widgets/qabstractbutton_p.h \ widgets/qabstractbutton_p.h \
widgets/qabstractslider.h \ widgets/qabstractslider.h \