source: vendor/trolltech/current/src/widgets/qcheckbox.cpp

Last change on this file was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

  • Property svn:keywords set to Id
File size: 10.3 KB
Line 
1/****************************************************************************
2** $Id: qcheckbox.cpp 2 2005-11-16 15:49:26Z dmik $
3**
4** Implementation of QCheckBox class
5**
6** Created : 940222
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the widgets module of the Qt GUI Toolkit.
11**
12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file.
15**
16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qcheckbox.h"
39#ifndef QT_NO_CHECKBOX
40#include "qpainter.h"
41#include "qdrawutil.h"
42#include "qpixmap.h"
43#include "qpixmapcache.h"
44#include "qbitmap.h"
45#include "qtextstream.h"
46#include "qapplication.h"
47#include "qstyle.h"
48
49/*!
50 \class QCheckBox qcheckbox.h
51 \brief The QCheckBox widget provides a checkbox with a text label.
52
53 \ingroup basic
54 \mainclass
55
56 QCheckBox and QRadioButton are both option buttons. That is, they
57 can be switched on (checked) or off (unchecked). The classes
58 differ in how the choices for the user are restricted. Radio
59 buttons define a "one of many" choice, whereas checkboxes provide
60 "many of many" choices.
61
62 A QButtonGroup can be used to group check buttons visually.
63
64 Whenever a checkbox is checked or cleared it emits the signal
65 toggled(). Connect to this signal if you want to trigger an action
66 each time the checkbox changes state. You can use isChecked() to
67 query whether or not a checkbox is checked.
68
69 \warning The toggled() signal can not be trusted for tristate
70 checkboxes.
71
72 In addition to the usual checked and unchecked states, QCheckBox
73 optionally provides a third state to indicate "no change". This
74 is useful whenever you need to give the user the option of neither
75 checking nor unchecking a checkbox. If you need this third state,
76 enable it with setTristate() and use state() to query the current
77 toggle state. When a tristate checkbox changes state, it emits the
78 stateChanged() signal.
79
80 Just like QPushButton, a checkbox can display text or a pixmap.
81 The text can be set in the constructor or with setText(); the
82 pixmap is set with setPixmap().
83
84 \important text(), setText(), text(), pixmap(), setPixmap(),
85 accel(), setAccel(), isToggleButton(), setDown(), isDown(),
86 isOn(), state(), autoRepeat(), isExclusiveToggle(), group(),
87 setAutoRepeat(), toggle(), pressed(), released(), clicked(),
88 toggled(), state() stateChanged()
89
90 <img src=qchkbox-m.png> <img src=qchkbox-w.png>
91
92 \sa QButton QRadioButton
93 \link guibooks.html#fowler Fowler: Check Box \endlink
94*/
95
96/*!
97 \property QCheckBox::checked
98 \brief whether the checkbox is checked
99
100 The default is unchecked, i.e. FALSE.
101*/
102
103/*!
104 \property QCheckBox::autoMask
105 \brief whether the checkbox is automatically masked
106
107 \sa QWidget::setAutoMask()
108*/
109
110/*!
111 \property QCheckBox::tristate
112 \brief whether the checkbox is a tri-state checkbox
113
114 The default is two-state, i.e. tri-state is FALSE.
115*/
116
117/*!
118 Constructs a checkbox with no text.
119
120 The \a parent and \a name arguments are sent to the QWidget
121 constructor.
122*/
123
124QCheckBox::QCheckBox( QWidget *parent, const char *name )
125 : QButton( parent, name, WNoAutoErase | WMouseNoMask )
126{
127 setToggleButton( TRUE );
128 setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed ) );
129}
130
131/*!
132 Constructs a checkbox with text \a text.
133
134 The \a parent and \a name arguments are sent to the QWidget
135 constructor.
136*/
137
138QCheckBox::QCheckBox( const QString &text, QWidget *parent, const char *name )
139 : QButton( parent, name, WNoAutoErase | WMouseNoMask )
140{
141 setText( text );
142 setToggleButton( TRUE );
143 setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed ) );
144}
145
146/*!
147 Sets the checkbox to the "no change" state.
148
149 \sa setTristate()
150*/
151void QCheckBox::setNoChange()
152{
153 setTristate(TRUE);
154 setState( NoChange );
155}
156
157void QCheckBox::setTristate(bool y)
158{
159 setToggleType( y ? Tristate : Toggle );
160}
161
162bool QCheckBox::isTristate() const
163{
164 return toggleType() == Tristate;
165}
166
167
168/*!\reimp
169*/
170QSize QCheckBox::sizeHint() const
171{
172 // NB: QRadioButton::sizeHint() is similar
173 constPolish();
174
175 QPainter p(this);
176 QSize sz = style().itemRect(&p, QRect(0, 0, 1, 1), ShowPrefix, FALSE,
177 pixmap(), text()).size();
178
179 return (style().sizeFromContents(QStyle::CT_CheckBox, this, sz).
180 expandedTo(QApplication::globalStrut()));
181}
182
183
184/*!\reimp
185*/
186
187void QCheckBox::drawButton( QPainter *paint )
188{
189 QPainter *p = paint;
190 QRect irect = QStyle::visualRect( style().subRect(QStyle::SR_CheckBoxIndicator, this), this );
191 const QColorGroup &cg = colorGroup();
192
193#if !defined( QT_NO_TEXTSTREAM ) && !defined( Q_WS_MACX )
194# define SAVE_CHECKBOX_PIXMAPS
195#endif
196#if defined(SAVE_CHECKBOX_PIXMAPS)
197 QString pmkey; // pixmap key
198 int kf = 0;
199 if ( isDown() )
200 kf |= 1;
201 if ( isEnabled() )
202 kf |= 2;
203 if ( hasFocus() )
204 kf |= 4; // active vs. normal colorgroup
205 if( isActiveWindow() )
206 kf |= 8;
207 if ( hasMouse() )
208 kf |= 16;
209
210 kf |= state() << 5;
211 QTextOStream os(&pmkey);
212 os << "$qt_check_" << style().className() << "_"
213 << palette().serialNumber() << "_" << irect.width() << "x" << irect.height() << "_" << kf;
214 QPixmap *pm = QPixmapCache::find( pmkey );
215 if ( pm ) { // pixmap exists
216 p->drawPixmap( irect.topLeft(), *pm );
217 drawButtonLabel( p );
218 return;
219 }
220 bool use_pm = TRUE;
221 QPainter pmpaint;
222 int wx = 0, wy = 0;
223 if ( use_pm ) {
224 pm = new QPixmap( irect.size() ); // create new pixmap
225 Q_CHECK_PTR( pm );
226 pm->fill( cg.background() );
227 QPainter::redirect(this, pm);
228 pmpaint.begin(this);
229 p = &pmpaint; // draw in pixmap
230 wx = irect.x(); // save x,y coords
231 wy = irect.y();
232 irect.moveTopLeft(QPoint(0, 0));
233 p->setBackgroundColor( cg.background() );
234 }
235#endif
236
237 QStyle::SFlags flags = QStyle::Style_Default;
238 if ( isEnabled() )
239 flags |= QStyle::Style_Enabled;
240 if ( hasFocus() )
241 flags |= QStyle::Style_HasFocus;
242 if ( isDown() )
243 flags |= QStyle::Style_Down;
244 if ( hasMouse() )
245 flags |= QStyle::Style_MouseOver;
246 if ( state() == QButton::On )
247 flags |= QStyle::Style_On;
248 else if ( state() == QButton::Off )
249 flags |= QStyle::Style_Off;
250 else if ( state() == QButton::NoChange )
251 flags |= QStyle::Style_NoChange;
252
253 style().drawControl(QStyle::CE_CheckBox, p, this, irect, cg, flags);
254
255#if defined(SAVE_CHECKBOX_PIXMAPS)
256 if ( use_pm ) {
257 pmpaint.end();
258 QPainter::redirect( this, 0 );
259 if ( backgroundPixmap() || backgroundMode() == X11ParentRelative ) {
260 QBitmap bm( pm->size() );
261 bm.fill( color0 );
262 pmpaint.begin( &bm );
263 style().drawControlMask(QStyle::CE_CheckBox, &pmpaint, this, irect);
264 pmpaint.end();
265 pm->setMask( bm );
266 }
267 p = paint; // draw in default device
268 p->drawPixmap( wx, wy, *pm );
269 if (!QPixmapCache::insert(pmkey, pm) ) // save in cache
270 delete pm;
271 }
272#endif
273
274 drawButtonLabel( paint );
275}
276
277
278/*!\reimp
279*/
280void QCheckBox::drawButtonLabel( QPainter *p )
281{
282 QRect r =
283 QStyle::visualRect( style().subRect(QStyle::SR_CheckBoxContents, this), this );
284
285 QStyle::SFlags flags = QStyle::Style_Default;
286 if (isEnabled())
287 flags |= QStyle::Style_Enabled;
288 if (hasFocus())
289 flags |= QStyle::Style_HasFocus;
290 if (isDown())
291 flags |= QStyle::Style_Down;
292 if (state() == QButton::On)
293 flags |= QStyle::Style_On;
294 else if (state() == QButton::Off)
295 flags |= QStyle::Style_Off;
296 else if (state() == QButton::NoChange)
297 flags |= QStyle::Style_NoChange;
298
299 style().drawControl(QStyle::CE_CheckBoxLabel, p, this, r, colorGroup(), flags);
300}
301
302/*!
303 \reimp
304*/
305void QCheckBox::resizeEvent( QResizeEvent *e )
306{
307 QButton::resizeEvent(e);
308 if ( isVisible() ) {
309 QPainter p(this);
310 QSize isz = style().itemRect(&p, QRect(0, 0, 1, 1), ShowPrefix, FALSE,
311 pixmap(), text()).size();
312 QSize wsz = (style().sizeFromContents(QStyle::CT_CheckBox, this, isz).
313 expandedTo(QApplication::globalStrut()));
314
315 update(wsz.width(), isz.width(), 0, wsz.height());
316 }
317 if (autoMask())
318 updateMask();
319}
320
321/*!
322 \reimp
323*/
324void QCheckBox::updateMask()
325{
326 QRect irect =
327 QStyle::visualRect( style().subRect(QStyle::SR_CheckBoxIndicator, this), this );
328
329 QBitmap bm(width(), height());
330 bm.fill(color0);
331
332 QPainter p( &bm, this );
333 style().drawControlMask(QStyle::CE_CheckBox, &p, this, irect);
334 if ( ! text().isNull() || ( pixmap() && ! pixmap()->isNull() ) ) {
335 QRect crect =
336 QStyle::visualRect( style().subRect( QStyle::SR_CheckBoxContents,
337 this ), this );
338 QRect frect =
339 QStyle::visualRect( style().subRect( QStyle::SR_CheckBoxFocusRect,
340 this ), this );
341 QRect label(crect.unite(frect));
342 p.fillRect(label, color1);
343 }
344 p.end();
345
346 setMask(bm);
347}
348
349/*!\reimp*/
350bool QCheckBox::hitButton( const QPoint &pos ) const
351{
352 QRect r = QStyle::visualRect( style().subRect( QStyle::SR_CheckBoxFocusRect, this ), this );
353 if ( qApp->reverseLayout() ) {
354 r.setRight( width() );
355 } else {
356 r.setLeft( 0 );
357 }
358 return r.contains( pos );
359}
360
361#endif
Note: See TracBrowser for help on using the repository browser.