source: trunk/src/gui/widgets/qcheckbox.cpp@ 100

Last change on this file since 100 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 11.9 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qcheckbox.h"
43#include "qapplication.h"
44#include "qbitmap.h"
45#include "qicon.h"
46#include "qstylepainter.h"
47#include "qstyle.h"
48#include "qstyleoption.h"
49#include "qevent.h"
50
51#include "private/qabstractbutton_p.h"
52
53QT_BEGIN_NAMESPACE
54
55class QCheckBoxPrivate : public QAbstractButtonPrivate
56{
57 Q_DECLARE_PUBLIC(QCheckBox)
58public:
59 QCheckBoxPrivate()
60 : QAbstractButtonPrivate(QSizePolicy::CheckBox), tristate(false), noChange(false),
61 hovering(true), publishedState(Qt::Unchecked) {}
62
63 uint tristate : 1;
64 uint noChange : 1;
65 uint hovering : 1;
66 uint publishedState : 2;
67
68 void init();
69};
70
71/*!
72 \class QCheckBox
73 \brief The QCheckBox widget provides a checkbox with a text label.
74
75 \ingroup basicwidgets
76 \mainclass
77
78 A QCheckBox is an option button that can be switched on (checked)
79 or off (unchecked). Checkboxes are typically used to represent
80 features in an application that can be enabled or disabled without
81 affecting others, but different types of behavior can be
82 implemented.
83
84 A QButtonGroup can be used to group check buttons visually.
85
86 Whenever a checkbox is checked or cleared it emits the signal
87 stateChanged(). Connect to this signal if you want to trigger an
88 action each time the checkbox changes state. You can use
89 isChecked() to query whether or not a checkbox is checked.
90
91 In addition to the usual checked and unchecked states, QCheckBox
92 optionally provides a third state to indicate "no change". This
93 is useful whenever you need to give the user the option of neither
94 checking nor unchecking a checkbox. If you need this third state,
95 enable it with setTristate(), and use checkState() to query the current
96 toggle state.
97
98 Just like QPushButton, a checkbox displays text, and optionally a
99 small icon. The icon is set with setIcon(). The text can be set in
100 the constructor or with setText(). A shortcut key can be specified
101 by preceding the preferred character with an ampersand. For
102 example:
103
104 \snippet doc/src/snippets/code/src_gui_widgets_qcheckbox.cpp 0
105
106 In this example the shortcut is \e{Alt+A}. See the \l
107 {QShortcut#mnemonic}{QShortcut} documentation for details (to
108 display an actual ampersand, use '&&').
109
110 Important inherited functions: text(), setText(), text(),
111 pixmap(), setPixmap(), accel(), setAccel(), isToggleButton(),
112 setDown(), isDown(), isOn(), checkState(), autoRepeat(),
113 isExclusiveToggle(), group(), setAutoRepeat(), toggle(),
114 pressed(), released(), clicked(), toggled(), checkState(), and
115 stateChanged().
116
117 \table 100%
118 \row \o \inlineimage macintosh-checkbox.png Screenshot of a Macintosh style checkbox
119 \o A checkbox shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
120 \row \o \inlineimage windows-checkbox.png Screenshot of a Windows XP style checkbox
121 \o A checkbox shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
122 \row \o \inlineimage plastique-checkbox.png Screenshot of a Plastique style checkbox
123 \o A checkbox shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
124 \endtable
125
126 \sa QAbstractButton, QRadioButton, {fowler}{GUI Design Handbook: Check Box}
127*/
128
129/*!
130 \enum QCheckBox::ToggleState
131 \compat
132
133 \value Off Use Qt::Unchecked instead.
134 \value NoChange Use Qt::PartiallyChecked instead.
135 \value On Use Qt::Checked instead.
136*/
137
138/*!
139 \fn void QCheckBox::stateChanged(int state)
140
141 This signal is emitted whenever the check box's state changes,
142 i.e. whenever the user checks or unchecks it.
143
144 \a state contains the check box's new Qt::CheckState.
145*/
146
147/*!
148 \property QCheckBox::tristate
149 \brief whether the checkbox is a tri-state checkbox
150
151 The default is false; i.e. the checkbox has only two states.
152*/
153
154void QCheckBoxPrivate::init()
155{
156 Q_Q(QCheckBox);
157 q->setCheckable(true);
158 q->setMouseTracking(true);
159 q->setForegroundRole(QPalette::WindowText);
160 setLayoutItemMargins(QStyle::SE_CheckBoxLayoutItem);
161}
162
163/*!
164 Initialize \a option with the values from this QCheckBox. This method is useful
165 for subclasses when they need a QStyleOptionButton, but don't want to fill
166 in all the information themselves.
167
168 \sa QStyleOption::initFrom()
169*/
170void QCheckBox::initStyleOption(QStyleOptionButton *option) const
171{
172 if (!option)
173 return;
174 Q_D(const QCheckBox);
175 option->initFrom(this);
176 if (d->down)
177 option->state |= QStyle::State_Sunken;
178 if (d->tristate && d->noChange)
179 option->state |= QStyle::State_NoChange;
180 else
181 option->state |= d->checked ? QStyle::State_On : QStyle::State_Off;
182 if (testAttribute(Qt::WA_Hover) && underMouse()) {
183 if (d->hovering)
184 option->state |= QStyle::State_MouseOver;
185 else
186 option->state &= ~QStyle::State_MouseOver;
187 }
188 option->text = d->text;
189 option->icon = d->icon;
190 option->iconSize = iconSize();
191}
192
193/*!
194 Constructs a checkbox with the given \a parent, but with no text.
195
196 The \a parent argument is passed on to the QAbstractButton constructor.
197*/
198
199QCheckBox::QCheckBox(QWidget *parent)
200 : QAbstractButton (*new QCheckBoxPrivate, parent)
201{
202 Q_D(QCheckBox);
203 d->init();
204}
205
206/*!
207 Constructs a checkbox with the given \a parent and \a text.
208
209 The \a parent argument is passed on to the QAbstractButton constructor.
210*/
211
212QCheckBox::QCheckBox(const QString &text, QWidget *parent)
213 : QAbstractButton (*new QCheckBoxPrivate, parent)
214{
215 Q_D(QCheckBox);
216 d->init();
217 setText(text);
218}
219
220void QCheckBox::setTristate(bool y)
221{
222 Q_D(QCheckBox);
223 d->tristate = y;
224}
225
226bool QCheckBox::isTristate() const
227{
228 Q_D(const QCheckBox);
229 return d->tristate;
230}
231
232
233/*!
234 Returns the check box's check state.
235 If you do not need tristate support, you can also
236 use \l QAbstractButton::isChecked() which returns
237 a boolean.
238
239 \sa setCheckState() Qt::CheckState
240*/
241Qt::CheckState QCheckBox::checkState() const
242{
243 Q_D(const QCheckBox);
244 if (d->tristate && d->noChange)
245 return Qt::PartiallyChecked;
246 return d->checked ? Qt::Checked : Qt::Unchecked;
247}
248
249/*!
250 Sets the check box's check state to \a state.
251 If you do not need tristate support, you can also
252 use \l QAbstractButton::setChecked() which takes
253 a boolean.
254
255 \sa checkState() Qt::CheckState
256*/
257void QCheckBox::setCheckState(Qt::CheckState state)
258{
259 Q_D(QCheckBox);
260 if (state == Qt::PartiallyChecked) {
261 d->tristate = true;
262 d->noChange = true;
263 } else {
264 d->noChange = false;
265 }
266 d->blockRefresh = true;
267 setChecked(state != Qt::Unchecked);
268 d->blockRefresh = false;
269 d->refresh();
270 if ((uint)state != d->publishedState) {
271 d->publishedState = state;
272 emit stateChanged(state);
273 }
274}
275
276
277/*!\reimp
278*/
279QSize QCheckBox::sizeHint() const
280{
281 Q_D(const QCheckBox);
282 if (d->sizeHint.isValid())
283 return d->sizeHint;
284 ensurePolished();
285 QFontMetrics fm = fontMetrics();
286 QStyleOptionButton opt;
287 initStyleOption(&opt);
288 QSize sz = style()->itemTextRect(fm, QRect(0, 0, 1, 1), Qt::TextShowMnemonic, false,
289 text()).size();
290 if (!opt.icon.isNull())
291 sz = QSize(sz.width() + opt.iconSize.width() + 4, qMax(sz.height(), opt.iconSize.height()));
292 d->sizeHint = (style()->sizeFromContents(QStyle::CT_CheckBox, &opt, sz, this)
293 .expandedTo(QApplication::globalStrut()));
294 return d->sizeHint;
295}
296
297/*!\reimp
298*/
299void QCheckBox::paintEvent(QPaintEvent *)
300{
301 QStylePainter p(this);
302 QStyleOptionButton opt;
303 initStyleOption(&opt);
304 p.drawControl(QStyle::CE_CheckBox, opt);
305}
306
307/*!
308 \reimp
309*/
310void QCheckBox::mouseMoveEvent(QMouseEvent *e)
311{
312 Q_D(QCheckBox);
313 if (testAttribute(Qt::WA_Hover)) {
314 bool hit = false;
315 if (underMouse())
316 hit = hitButton(e->pos());
317
318 if (hit != d->hovering) {
319 update(rect());
320 d->hovering = hit;
321 }
322 }
323
324 QAbstractButton::mouseMoveEvent(e);
325}
326
327
328/*!\reimp*/
329bool QCheckBox::hitButton(const QPoint &pos) const
330{
331 QStyleOptionButton opt;
332 initStyleOption(&opt);
333 return style()->subElementRect(QStyle::SE_CheckBoxClickRect, &opt, this).contains(pos);
334}
335
336/*!\reimp*/
337void QCheckBox::checkStateSet()
338{
339 Q_D(QCheckBox);
340 d->noChange = false;
341 Qt::CheckState state = checkState();
342 if ((uint)state != d->publishedState) {
343 d->publishedState = state;
344 emit stateChanged(state);
345 }
346}
347
348/*!\reimp*/
349void QCheckBox::nextCheckState()
350{
351 Q_D(QCheckBox);
352 if (d->tristate)
353 setCheckState((Qt::CheckState)((checkState() + 1) % 3));
354 else {
355 QAbstractButton::nextCheckState();
356 QCheckBox::checkStateSet();
357 }
358}
359
360/*!
361 \reimp
362*/
363bool QCheckBox::event(QEvent *e)
364{
365 Q_D(QCheckBox);
366 if (e->type() == QEvent::StyleChange
367#ifdef Q_WS_MAC
368 || e->type() == QEvent::MacSizeChange
369#endif
370 )
371 d->setLayoutItemMargins(QStyle::SE_CheckBoxLayoutItem);
372 return QAbstractButton::event(e);
373}
374
375#ifdef QT3_SUPPORT
376/*!
377 Use one of the constructors that doesn't take the \a name
378 argument and then use setObjectName() instead.
379*/
380QCheckBox::QCheckBox(QWidget *parent, const char* name)
381 : QAbstractButton (*new QCheckBoxPrivate, parent)
382{
383 Q_D(QCheckBox);
384 setObjectName(QString::fromAscii(name));
385 d->init();
386}
387
388/*!
389 Use one of the constructors that doesn't take the \a name
390 argument and then use setObjectName() instead.
391*/
392QCheckBox::QCheckBox(const QString &text, QWidget *parent, const char* name)
393 : QAbstractButton (*new QCheckBoxPrivate, parent)
394{
395 Q_D(QCheckBox);
396 setObjectName(QString::fromAscii(name));
397 d->init();
398 setText(text);
399}
400
401#endif
402
403
404/*!
405 \fn void QCheckBox::setNoChange()
406 \compat
407
408 Use setCheckState() instead.
409*/
410
411/*!
412 \fn void QCheckBox::setState(ToggleState state)
413 \compat
414
415 Use setCheckState() instead.
416*/
417
418/*!
419 \fn QCheckBox::ToggleState QCheckBox::state() const
420 \compat
421
422 Use checkState() instead.
423*/
424
425QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.