|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the Qt3Support module of the Qt Toolkit. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 #include "q3groupbox.h" |
|
43 |
|
44 #include "qlayout.h" |
|
45 #include "qpainter.h" |
|
46 #include "qbitmap.h" |
|
47 #include "q3accel.h" |
|
48 #include "qradiobutton.h" |
|
49 #include "qdrawutil.h" |
|
50 #include "qapplication.h" |
|
51 #include "qstyle.h" |
|
52 #include "qcheckbox.h" |
|
53 #include "qaccessible.h" |
|
54 #include "qstyleoption.h" |
|
55 #include "qdebug.h" |
|
56 |
|
57 QT_BEGIN_NAMESPACE |
|
58 |
|
59 /*! |
|
60 \class Q3GroupBox |
|
61 \brief The Q3GroupBox widget provides a group box frame with a title. |
|
62 |
|
63 \compat |
|
64 |
|
65 A group box provides a frame, a title and a keyboard shortcut, and |
|
66 displays various other widgets inside itself. The title is on top, |
|
67 the keyboard shortcut moves keyboard focus to one of the group |
|
68 box's child widgets, and the child widgets are usually laid out |
|
69 horizontally (or vertically) inside the frame. |
|
70 |
|
71 The simplest way to use it is to create a group box with the |
|
72 desired number of columns (or rows) and orientation, and then just |
|
73 create widgets with the group box as parent. |
|
74 |
|
75 It is also possible to change the orientation() and number of |
|
76 columns() after construction, or to ignore all the automatic |
|
77 layout support and manage the layout yourself. You can add 'empty' |
|
78 spaces to the group box with addSpace(). |
|
79 |
|
80 Q3GroupBox also lets you set the title() (normally set in the |
|
81 constructor) and the title's alignment(). |
|
82 |
|
83 You can change the spacing used by the group box with |
|
84 setInsideMargin() and setInsideSpacing(). To minimize space |
|
85 consumption, you can remove the right, left and bottom edges of |
|
86 the frame with setFlat(). |
|
87 |
|
88 \sa QButtonGroup |
|
89 */ |
|
90 |
|
91 class QCheckBox; |
|
92 |
|
93 class Q3GroupBoxPrivate |
|
94 { |
|
95 public: |
|
96 Q3GroupBoxPrivate(Q3GroupBox *w): |
|
97 q(w), vbox(0), grid(0), row(0), col(0), nRows(0), nCols(0), dir(Qt::Horizontal), |
|
98 spac(5), marg(11), |
|
99 checkbox(0), |
|
100 frameStyle(Q3GroupBox::GroupBoxPanel | Q3GroupBox::Sunken), |
|
101 lineWidth(1), midLineWidth(0), frameWidth(0), |
|
102 leftFrameWidth(0), rightFrameWidth(0), |
|
103 topFrameWidth(0), bottomFrameWidth(0) {} |
|
104 |
|
105 void updateFrameWidth(); |
|
106 void updateStyledFrameWidths(); |
|
107 |
|
108 Q3GroupBox *q; |
|
109 QVBoxLayout *vbox; |
|
110 QGridLayout *grid; |
|
111 int row; |
|
112 int col; |
|
113 int nRows, nCols; |
|
114 Qt::Orientation dir; |
|
115 int spac, marg; |
|
116 |
|
117 QCheckBox *checkbox; |
|
118 |
|
119 int frameStyle; |
|
120 int oldFrameStyle; |
|
121 short lineWidth, //line width |
|
122 midLineWidth; //midline width |
|
123 int frameWidth; |
|
124 short leftFrameWidth, rightFrameWidth, |
|
125 topFrameWidth, bottomFrameWidth; |
|
126 }; |
|
127 |
|
128 /*! |
|
129 \internal |
|
130 Updates the frame widths from the style. |
|
131 */ |
|
132 void Q3GroupBoxPrivate::updateStyledFrameWidths() |
|
133 { |
|
134 QStyleOptionFrameV2 opt; |
|
135 opt.initFrom(q); |
|
136 QRect cr = q->style()->subElementRect(QStyle::SE_FrameContents, &opt, q); |
|
137 leftFrameWidth = cr.left() - opt.rect.left(); |
|
138 topFrameWidth = cr.top() - opt.rect.top(); |
|
139 rightFrameWidth = opt.rect.right() - cr.right(), |
|
140 bottomFrameWidth = opt.rect.bottom() - cr.bottom(); |
|
141 frameWidth = qMax(qMax(leftFrameWidth, rightFrameWidth), |
|
142 qMax(topFrameWidth, bottomFrameWidth)); |
|
143 } |
|
144 |
|
145 /*! |
|
146 \internal |
|
147 Updated the frameWidth parameter. |
|
148 */ |
|
149 |
|
150 void Q3GroupBoxPrivate::updateFrameWidth() |
|
151 { |
|
152 QRect fr = q->frameRect(); |
|
153 |
|
154 int frameShape = frameStyle & QFrame::Shape_Mask; |
|
155 int frameShadow = frameStyle & QFrame::Shadow_Mask; |
|
156 |
|
157 frameWidth = -1; |
|
158 |
|
159 switch (frameShape) { |
|
160 |
|
161 case QFrame::NoFrame: |
|
162 frameWidth = 0; |
|
163 break; |
|
164 |
|
165 case QFrame::Box: |
|
166 case QFrame::HLine: |
|
167 case QFrame::VLine: |
|
168 switch (frameShadow) { |
|
169 case QFrame::Plain: |
|
170 frameWidth = lineWidth; |
|
171 break; |
|
172 case QFrame::Raised: |
|
173 case QFrame::Sunken: |
|
174 frameWidth = (short)(lineWidth*2 + midLineWidth); |
|
175 break; |
|
176 } |
|
177 break; |
|
178 |
|
179 case QFrame::StyledPanel: |
|
180 updateStyledFrameWidths(); |
|
181 break; |
|
182 |
|
183 case QFrame::WinPanel: |
|
184 frameWidth = 2; |
|
185 break; |
|
186 |
|
187 |
|
188 case QFrame::Panel: |
|
189 switch (frameShadow) { |
|
190 case QFrame::Plain: |
|
191 case QFrame::Raised: |
|
192 case QFrame::Sunken: |
|
193 frameWidth = lineWidth; |
|
194 break; |
|
195 } |
|
196 break; |
|
197 } |
|
198 |
|
199 if (frameWidth == -1) // invalid style |
|
200 frameWidth = 0; |
|
201 |
|
202 q->setFrameRect(fr); |
|
203 } |
|
204 |
|
205 |
|
206 |
|
207 |
|
208 |
|
209 /*! |
|
210 Constructs a group box widget with no title. |
|
211 |
|
212 The \a parent and \a name arguments are passed to the QWidget |
|
213 constructor. |
|
214 |
|
215 This constructor does not do automatic layout. |
|
216 */ |
|
217 |
|
218 Q3GroupBox::Q3GroupBox(QWidget *parent, const char *name) |
|
219 : QGroupBox(parent, name) |
|
220 { |
|
221 init(); |
|
222 } |
|
223 |
|
224 /*! |
|
225 Constructs a group box with the title \a title. |
|
226 |
|
227 The \a parent and \a name arguments are passed to the QWidget |
|
228 constructor. |
|
229 |
|
230 This constructor does not do automatic layout. |
|
231 */ |
|
232 |
|
233 Q3GroupBox::Q3GroupBox(const QString &title, QWidget *parent, const char *name) |
|
234 : QGroupBox(parent, name) |
|
235 { |
|
236 init(); |
|
237 setTitle(title); |
|
238 } |
|
239 |
|
240 /*! |
|
241 Constructs a group box with no title. Child widgets will be |
|
242 arranged in \a strips rows or columns (depending on \a |
|
243 orientation). |
|
244 |
|
245 The \a parent and \a name arguments are passed to the QWidget |
|
246 constructor. |
|
247 */ |
|
248 |
|
249 Q3GroupBox::Q3GroupBox(int strips, Qt::Orientation orientation, |
|
250 QWidget *parent, const char *name) |
|
251 : QGroupBox(parent, name) |
|
252 { |
|
253 init(); |
|
254 setColumnLayout(strips, orientation); |
|
255 } |
|
256 |
|
257 /*! |
|
258 Constructs a group box titled \a title. Child widgets will be |
|
259 arranged in \a strips rows or columns (depending on \a |
|
260 orientation). |
|
261 |
|
262 The \a parent and \a name arguments are passed to the QWidget |
|
263 constructor. |
|
264 */ |
|
265 |
|
266 Q3GroupBox::Q3GroupBox(int strips, Qt::Orientation orientation, |
|
267 const QString &title, QWidget *parent, |
|
268 const char *name) |
|
269 : QGroupBox(parent, name) |
|
270 { |
|
271 init(); |
|
272 setTitle(title); |
|
273 setColumnLayout(strips, orientation); |
|
274 } |
|
275 |
|
276 /*! |
|
277 Destroys the group box. |
|
278 */ |
|
279 Q3GroupBox::~Q3GroupBox() |
|
280 { |
|
281 delete d; |
|
282 } |
|
283 |
|
284 void Q3GroupBox::init() |
|
285 { |
|
286 d = new Q3GroupBoxPrivate(this); |
|
287 } |
|
288 |
|
289 |
|
290 /*! \reimp |
|
291 */ |
|
292 void Q3GroupBox::resizeEvent(QResizeEvent *e) |
|
293 { |
|
294 QGroupBox::resizeEvent(e); |
|
295 } |
|
296 |
|
297 |
|
298 /*! |
|
299 Adds an empty cell at the next free position. If \a size is |
|
300 greater than 0, the empty cell takes \a size to be its fixed width |
|
301 (if orientation() is \c Horizontal) or height (if orientation() is |
|
302 \c Vertical). |
|
303 |
|
304 Use this method to separate the widgets in the group box or to |
|
305 skip the next free cell. For performance reasons, call this method |
|
306 after calling setColumnLayout() or by changing the \l |
|
307 Q3GroupBox::columns or \l Q3GroupBox::orientation properties. It is |
|
308 generally a good idea to call these methods first (if needed at |
|
309 all), and insert the widgets and spaces afterwards. |
|
310 */ |
|
311 void Q3GroupBox::addSpace(int size) |
|
312 { |
|
313 QApplication::sendPostedEvents(this, QEvent::ChildInserted); |
|
314 |
|
315 if (d->nCols <= 0 || d->nRows <= 0) |
|
316 return; |
|
317 |
|
318 if (d->row >= d->nRows || d->col >= d->nCols) |
|
319 d->grid->expand(d->row+1, d->col+1); |
|
320 |
|
321 if (size > 0) { |
|
322 QSpacerItem *spacer |
|
323 = new QSpacerItem((d->dir == Qt::Horizontal) ? 0 : size, |
|
324 (d->dir == Qt::Vertical) ? 0 : size, |
|
325 QSizePolicy::Fixed, QSizePolicy::Fixed); |
|
326 d->grid->addItem(spacer, d->row, d->col); |
|
327 } |
|
328 |
|
329 skip(); |
|
330 } |
|
331 |
|
332 /*! |
|
333 \property Q3GroupBox::columns |
|
334 \brief the number of columns or rows (depending on \l Q3GroupBox::orientation) in the group box |
|
335 |
|
336 Usually it is not a good idea to set this property because it is |
|
337 slow (it does a complete layout). It is best to set the number |
|
338 of columns directly in the constructor. |
|
339 */ |
|
340 int Q3GroupBox::columns() const |
|
341 { |
|
342 if (d->dir == Qt::Horizontal) |
|
343 return d->nCols; |
|
344 return d->nRows; |
|
345 } |
|
346 |
|
347 void Q3GroupBox::setColumns(int c) |
|
348 { |
|
349 setColumnLayout(c, d->dir); |
|
350 } |
|
351 |
|
352 /*! |
|
353 Returns the width of the empty space between the items in the |
|
354 group and the frame of the group. |
|
355 |
|
356 Only applies if the group box has a defined orientation. |
|
357 |
|
358 The default is usually 11, by may vary depending on the platform |
|
359 and style. |
|
360 |
|
361 \sa setInsideMargin(), orientation |
|
362 */ |
|
363 int Q3GroupBox::insideMargin() const |
|
364 { |
|
365 return d->marg; |
|
366 } |
|
367 |
|
368 /*! |
|
369 Returns the width of the empty space between each of the items |
|
370 in the group. |
|
371 |
|
372 Only applies if the group box has a defined orientation. |
|
373 |
|
374 The default is usually 5, by may vary depending on the platform |
|
375 and style. |
|
376 |
|
377 \sa setInsideSpacing(), orientation |
|
378 */ |
|
379 int Q3GroupBox::insideSpacing() const |
|
380 { |
|
381 return d->spac; |
|
382 } |
|
383 |
|
384 /*! |
|
385 Sets the width of the inside margin to \a m pixels. |
|
386 |
|
387 \sa insideMargin() |
|
388 */ |
|
389 void Q3GroupBox::setInsideMargin(int m) |
|
390 { |
|
391 d->marg = m; |
|
392 setColumnLayout(columns(), d->dir); |
|
393 } |
|
394 |
|
395 /*! |
|
396 Sets the width of the empty space between each of the items in |
|
397 the group to \a s pixels. |
|
398 |
|
399 \sa insideSpacing() |
|
400 */ |
|
401 void Q3GroupBox::setInsideSpacing(int s) |
|
402 { |
|
403 d->spac = s; |
|
404 setColumnLayout(columns(), d->dir); |
|
405 } |
|
406 |
|
407 /*! |
|
408 \property Q3GroupBox::orientation |
|
409 \brief the group box's orientation |
|
410 |
|
411 A horizontal group box arranges its children in columns, while a |
|
412 vertical group box arranges them in rows. |
|
413 |
|
414 Usually it is not a good idea to set this property because it is |
|
415 slow (it does a complete layout). It is better to set the |
|
416 orientation directly in the constructor. |
|
417 */ |
|
418 void Q3GroupBox::setOrientation(Qt::Orientation o) |
|
419 { |
|
420 setColumnLayout(columns(), o); |
|
421 } |
|
422 |
|
423 |
|
424 Qt::Orientation Q3GroupBox::orientation() const |
|
425 { |
|
426 return d->dir; |
|
427 } |
|
428 |
|
429 /*! |
|
430 Changes the layout of the group box. This function is only useful |
|
431 in combination with the default constructor that does not take any |
|
432 layout information. This function will put all existing children |
|
433 in the new layout. It is not good Qt programming style to call |
|
434 this function after children have been inserted. Sets the number |
|
435 of columns or rows to be \a strips, depending on \a direction. |
|
436 |
|
437 \sa orientation columns |
|
438 */ |
|
439 void Q3GroupBox::setColumnLayout(int strips, Qt::Orientation direction) |
|
440 { |
|
441 if (layout()) |
|
442 delete layout(); |
|
443 |
|
444 d->vbox = 0; |
|
445 d->grid = 0; |
|
446 |
|
447 if (strips < 0) // if 0, we create the d->vbox but not the d->grid. See below. |
|
448 return; |
|
449 |
|
450 d->vbox = new QVBoxLayout(this, d->marg, 0); |
|
451 |
|
452 d->nCols = 0; |
|
453 d->nRows = 0; |
|
454 d->dir = direction; |
|
455 |
|
456 // Send all child events and ignore them. Otherwise we will end up |
|
457 // with doubled insertion. This won't do anything because d->nCols == |
|
458 // d->nRows == 0. |
|
459 QApplication::sendPostedEvents(this, QEvent::ChildInserted); |
|
460 |
|
461 // if 0 or smaller , create a vbox-layout but no grid. This allows |
|
462 // the designer to handle its own grid layout in a group box. |
|
463 if (strips <= 0) |
|
464 return; |
|
465 |
|
466 d->dir = direction; |
|
467 if (d->dir == Qt::Horizontal) { |
|
468 d->nCols = strips; |
|
469 d->nRows = 1; |
|
470 } else { |
|
471 d->nCols = 1; |
|
472 d->nRows = strips; |
|
473 } |
|
474 d->grid = new QGridLayout(d->nRows, d->nCols, d->spac); |
|
475 d->row = d->col = 0; |
|
476 d->grid->setAlignment(Qt::AlignTop); |
|
477 d->vbox->addLayout(d->grid); |
|
478 |
|
479 // Add all children |
|
480 QObjectList childList = children(); |
|
481 if (!childList.isEmpty()) { |
|
482 for (int i = 0; i < childList.size(); ++i) { |
|
483 QObject *o = childList.at(i); |
|
484 if (o->isWidgetType() && o != d->checkbox) |
|
485 insertWid(static_cast<QWidget *>(o)); |
|
486 } |
|
487 } |
|
488 } |
|
489 |
|
490 /*!\reimp */ |
|
491 void Q3GroupBox::childEvent(QChildEvent *c) |
|
492 { |
|
493 QGroupBox::childEvent(c); |
|
494 if (!c->inserted() || !c->child()->isWidgetType()) |
|
495 return; |
|
496 if (d->grid) { |
|
497 insertWid((QWidget*)c->child()); |
|
498 } |
|
499 } |
|
500 |
|
501 void Q3GroupBox::insertWid(QWidget* w) |
|
502 { |
|
503 if (d->row >= d->nRows || d->col >= d->nCols) |
|
504 d->grid->expand(d->row+1, d->col+1); |
|
505 d->grid->addWidget(w, d->row, d->col); |
|
506 skip(); |
|
507 } |
|
508 |
|
509 |
|
510 void Q3GroupBox::skip() |
|
511 { |
|
512 // Same as QGrid::skip() |
|
513 if (d->dir == Qt::Horizontal) { |
|
514 if (d->col+1 < d->nCols) { |
|
515 d->col++; |
|
516 } else { |
|
517 d->col = 0; |
|
518 d->row++; |
|
519 } |
|
520 } else { //Vertical |
|
521 if (d->row+1 < d->nRows) { |
|
522 d->row++; |
|
523 } else { |
|
524 d->row = 0; |
|
525 d->col++; |
|
526 } |
|
527 } |
|
528 } |
|
529 |
|
530 |
|
531 /*! \reimp */ |
|
532 void Q3GroupBox::changeEvent(QEvent *ev) |
|
533 { |
|
534 QGroupBox::changeEvent(ev); |
|
535 } |
|
536 |
|
537 /*! \reimp */ |
|
538 bool Q3GroupBox::event(QEvent *e) |
|
539 { |
|
540 if (e->type()==QEvent::Paint) |
|
541 { |
|
542 QStyleOptionGroupBox opt; |
|
543 initStyleOption(&opt); |
|
544 opt.lineWidth=d->lineWidth; |
|
545 opt.midLineWidth=d->midLineWidth; |
|
546 QPainter p(this); |
|
547 if (frameShape()==GroupBoxPanel) |
|
548 { |
|
549 style()->drawComplexControl(QStyle::CC_GroupBox, &opt, &p, this); |
|
550 } |
|
551 else { |
|
552 //in case it is a Paint event with a frame shape different from the group box |
|
553 const QRect textRect = style()->subControlRect(QStyle::CC_GroupBox, &opt, QStyle::SC_GroupBoxLabel, this); |
|
554 const QRect checkBoxRect = style()->subControlRect(QStyle::CC_GroupBox, &opt, QStyle::SC_GroupBoxCheckBox, this); |
|
555 |
|
556 // Draw title |
|
557 if ((opt.subControls & QStyle::SC_GroupBoxLabel) && !opt.text.isEmpty()) { |
|
558 QColor textColor = opt.textColor; |
|
559 if (textColor.isValid()) |
|
560 p.setPen(textColor); |
|
561 int alignment = int(opt.textAlignment); |
|
562 if (!style()->styleHint(QStyle::SH_UnderlineShortcut, &opt, this)) |
|
563 alignment |= Qt::TextHideMnemonic; |
|
564 |
|
565 style()->drawItemText(&p, textRect, Qt::TextShowMnemonic | Qt::AlignHCenter | alignment, |
|
566 opt.palette, opt.state & QStyle::State_Enabled, opt.text, |
|
567 textColor.isValid() ? QPalette::NoRole : QPalette::WindowText); |
|
568 |
|
569 if (opt.state & QStyle::State_HasFocus) { |
|
570 QStyleOptionFocusRect fropt; |
|
571 fropt.QStyleOption::operator=(opt); |
|
572 fropt.rect = textRect; |
|
573 style()->drawPrimitive(QStyle::PE_FrameFocusRect, &fropt, &p, this); |
|
574 } |
|
575 } |
|
576 |
|
577 // Draw checkbox |
|
578 if (opt.subControls & QStyle::SC_GroupBoxCheckBox) { |
|
579 QStyleOptionButton box; |
|
580 box.QStyleOption::operator=(opt); |
|
581 box.rect = checkBoxRect; |
|
582 style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &box, &p, this); |
|
583 } |
|
584 |
|
585 //sets clipping |
|
586 QRegion region(rect()); |
|
587 if (!title().isEmpty()) { |
|
588 bool ltr = layoutDirection() == Qt::LeftToRight; |
|
589 QRect finalRect = checkBoxRect.united(textRect); |
|
590 if (isCheckable()) |
|
591 finalRect.adjust(ltr ? -4 : 0, 0, ltr ? 0 : 4, 0); |
|
592 region -= finalRect; |
|
593 } |
|
594 p.setClipRegion(region); |
|
595 |
|
596 drawFrame(&p); |
|
597 } |
|
598 return false; |
|
599 } |
|
600 return QGroupBox::event(e); |
|
601 } |
|
602 |
|
603 /*! |
|
604 \fn void Q3GroupBox::drawFrame(QPainter *p) |
|
605 \internal |
|
606 */ |
|
607 |
|
608 void Q3GroupBox::drawFrame(QPainter *p) |
|
609 { |
|
610 QPoint p1, p2; |
|
611 QStyleOptionFrame opt; |
|
612 opt.init(this); |
|
613 |
|
614 int frameShape = d->frameStyle & QFrame::Shape_Mask; |
|
615 int frameShadow = d->frameStyle & QFrame::Shadow_Mask; |
|
616 |
|
617 int lw = 0; |
|
618 int mlw = 0; |
|
619 opt.rect = frameRect(); |
|
620 |
|
621 switch (frameShape) { |
|
622 case QFrame::Box: |
|
623 case QFrame::HLine: |
|
624 case QFrame::VLine: |
|
625 case QFrame::StyledPanel: |
|
626 lw = d->lineWidth; |
|
627 mlw = d->midLineWidth; |
|
628 break; |
|
629 default: |
|
630 // most frame styles do not handle customized line and midline widths |
|
631 // (see updateFrameWidth()). |
|
632 lw = d->frameWidth; |
|
633 break; |
|
634 } |
|
635 opt.lineWidth = lw; |
|
636 opt.midLineWidth = mlw; |
|
637 if (frameShadow == Sunken) |
|
638 opt.state |= QStyle::State_Sunken; |
|
639 else if (frameShadow == Raised) |
|
640 opt.state |= QStyle::State_Raised; |
|
641 |
|
642 switch (frameShape) { |
|
643 case Box: |
|
644 if (frameShadow == Plain) |
|
645 qDrawPlainRect(p, opt.rect, opt.palette.foreground().color(), lw); |
|
646 else |
|
647 qDrawShadeRect(p, opt.rect, opt.palette, frameShadow == Sunken, lw, mlw); |
|
648 break; |
|
649 |
|
650 case StyledPanel: |
|
651 style()->drawPrimitive(QStyle::PE_Frame, &opt, p, this); |
|
652 break; |
|
653 |
|
654 case Panel: |
|
655 if (frameShadow == Plain) |
|
656 qDrawPlainRect(p, opt.rect, opt.palette.foreground().color(), lw); |
|
657 else |
|
658 qDrawShadePanel(p, opt.rect, opt.palette, frameShadow == Sunken, lw); |
|
659 break; |
|
660 |
|
661 case WinPanel: |
|
662 if (frameShadow == Plain) |
|
663 qDrawPlainRect(p, opt.rect, opt.palette.foreground().color(), lw); |
|
664 else |
|
665 qDrawWinPanel(p, opt.rect, opt.palette, frameShadow == Sunken); |
|
666 break; |
|
667 case HLine: |
|
668 case VLine: |
|
669 if (frameShape == HLine) { |
|
670 p1 = QPoint(opt.rect.x(), opt.rect.height() / 2); |
|
671 p2 = QPoint(opt.rect.x() + opt.rect.width(), p1.y()); |
|
672 } else { |
|
673 p1 = QPoint(opt.rect.x()+opt.rect.width() / 2, 0); |
|
674 p2 = QPoint(p1.x(), opt.rect.height()); |
|
675 } |
|
676 if (frameShadow == Plain) { |
|
677 QPen oldPen = p->pen(); |
|
678 p->setPen(QPen(opt.palette.foreground().color(), lw)); |
|
679 p->drawLine(p1, p2); |
|
680 p->setPen(oldPen); |
|
681 } else { |
|
682 qDrawShadeLine(p, p1, p2, opt.palette, frameShadow == Sunken, lw, mlw); |
|
683 } |
|
684 break; |
|
685 } |
|
686 |
|
687 #ifdef QT_KEYPAD_NAVIGATION |
|
688 if (QApplication::keypadNavigationEnabled() && hasFocus()) { |
|
689 QStyleOptionFocusRect fopt; |
|
690 fopt.init(this); |
|
691 fopt.state |= QStyle::State_KeyboardFocusChange; |
|
692 fopt.rect = frameRect(); |
|
693 style()->drawPrimitive(QStyle::PE_FrameFocusRect, &fopt, p, this); |
|
694 } |
|
695 #endif |
|
696 } |
|
697 |
|
698 /*! |
|
699 \property Q3GroupBox::frameShadow |
|
700 \brief the frame shadow value from the frame style |
|
701 |
|
702 \sa frameStyle() |
|
703 */ |
|
704 |
|
705 /* |
|
706 \enum Q3GroupBox::FrameShape |
|
707 |
|
708 This enum defines the available frame shapes a group box can |
|
709 have. All values have equivalents in QFrame. |
|
710 |
|
711 \value Box QFrame::Box |
|
712 \value Sunken QFrame::Sunken |
|
713 \value Plain QFrame::Plain |
|
714 \value Raised QFrame::Raised |
|
715 \value MShadow QFrame::Shadow_Mask |
|
716 \value NoFrame QFrame::NoFrame |
|
717 \value Panel QFrame::Panel |
|
718 \value StyledPanel QFrame::StyledPanel |
|
719 \value HLine QFrame::HLine |
|
720 \value VLine QFrame::VLine |
|
721 \value WinPanel QFrame::WinPanel |
|
722 \value ToolBarPanel QFrame::StyledPanel |
|
723 \value MenuBarPanel = QFrame::StyledPanel |
|
724 \value PopupPanel QFrame::StyledPanel |
|
725 \value LineEditPanel QFrame::StyledPanel |
|
726 \value TabWidgetPanel QFrame::StyledPanel |
|
727 \value GroupBoxPanel 0x0007 |
|
728 \value MShape QFrame::Shape_Mask |
|
729 */ |
|
730 |
|
731 |
|
732 void Q3GroupBox::setFrameShadow(DummyFrame s) |
|
733 { |
|
734 setFrameStyle((d->frameStyle & MShape) | s); |
|
735 } |
|
736 |
|
737 Q3GroupBox::DummyFrame Q3GroupBox::frameShadow() const |
|
738 { |
|
739 return (DummyFrame) (d->frameStyle & MShadow); |
|
740 } |
|
741 |
|
742 /*! |
|
743 \property Q3GroupBox::frameShape |
|
744 \brief the frame shape value from the frame style |
|
745 |
|
746 \sa frameStyle(), frameShadow() |
|
747 */ |
|
748 |
|
749 void Q3GroupBox::setFrameShape(DummyFrame s) |
|
750 { |
|
751 setFrameStyle((d->frameStyle & MShadow) | s); |
|
752 } |
|
753 |
|
754 Q3GroupBox::DummyFrame Q3GroupBox::frameShape() const |
|
755 { |
|
756 return (DummyFrame) (d->frameStyle & MShape); |
|
757 } |
|
758 |
|
759 /*! |
|
760 \fn void Q3GroupBox::setFrameStyle(int style) |
|
761 |
|
762 Sets the frame style to \a style. The style is the bitwise OR |
|
763 between a frame shape and a frame shadow style. |
|
764 */ |
|
765 |
|
766 void Q3GroupBox::setFrameStyle(int style) |
|
767 { |
|
768 if (!testAttribute(Qt::WA_WState_OwnSizePolicy)) { |
|
769 switch (style & MShape) { |
|
770 case HLine: |
|
771 setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); |
|
772 break; |
|
773 case VLine: |
|
774 setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum); |
|
775 break; |
|
776 default: |
|
777 if ((d->frameStyle & MShape) == HLine || (d->frameStyle & MShape) == VLine) |
|
778 setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); |
|
779 } |
|
780 setAttribute(Qt::WA_WState_OwnSizePolicy, false); |
|
781 } |
|
782 d->frameStyle = style; |
|
783 update(); |
|
784 d->updateFrameWidth(); |
|
785 d->oldFrameStyle = style; |
|
786 } |
|
787 |
|
788 /*! |
|
789 \fn int Q3GroupBox::frameStyle() const |
|
790 |
|
791 Returns the frame style. |
|
792 */ |
|
793 |
|
794 int Q3GroupBox::frameStyle() const |
|
795 { |
|
796 return d->frameStyle; |
|
797 } |
|
798 |
|
799 /*! |
|
800 \property Q3GroupBox::lineWidth |
|
801 \brief This property holds the width of the line. |
|
802 |
|
803 \sa frameStyle(), frameShadow() |
|
804 */ |
|
805 |
|
806 void Q3GroupBox::setLineWidth(int w) |
|
807 { |
|
808 if (short(w) == d->lineWidth) |
|
809 return; |
|
810 d->lineWidth = short(w); |
|
811 d->updateFrameWidth(); |
|
812 } |
|
813 |
|
814 int Q3GroupBox::lineWidth() const |
|
815 { |
|
816 return d->lineWidth; |
|
817 } |
|
818 |
|
819 /*! |
|
820 \property Q3GroupBox::midLineWidth |
|
821 \brief This property holds the width of the mid-line. |
|
822 |
|
823 \sa frameStyle(), frameShadow() |
|
824 */ |
|
825 |
|
826 void Q3GroupBox::setMidLineWidth(int w) |
|
827 { |
|
828 if (short(w) == d->midLineWidth) |
|
829 return; |
|
830 d->midLineWidth = short(w); |
|
831 d->updateFrameWidth(); |
|
832 } |
|
833 |
|
834 int Q3GroupBox::midLineWidth() const |
|
835 { |
|
836 return d->midLineWidth; |
|
837 } |
|
838 |
|
839 /*! |
|
840 \property Q3GroupBox::frameRect |
|
841 \brief the bounding rectangle of the frame of the group box. |
|
842 */ |
|
843 |
|
844 /*! |
|
845 \fn QRect Q3GroupBox::frameRect() const |
|
846 \internal |
|
847 */ |
|
848 |
|
849 QRect Q3GroupBox::frameRect() const |
|
850 { |
|
851 QStyleOptionGroupBox opt; |
|
852 initStyleOption(&opt); |
|
853 QRect fr = style()->subControlRect(QStyle::CC_GroupBox, &opt, QStyle::SC_GroupBoxFrame, this); |
|
854 return fr; |
|
855 } |
|
856 |
|
857 /*! |
|
858 \fn void Q3GroupBox::setFrameRect(QRect) |
|
859 \internal |
|
860 */ |
|
861 |
|
862 void Q3GroupBox::setFrameRect(QRect r) |
|
863 { |
|
864 QRect cr = r.isValid() ? r : rect(); |
|
865 if ((d->frameStyle & QFrame::Shape_Mask) == StyledPanel) { |
|
866 cr.adjust(d->leftFrameWidth, d->topFrameWidth, -d->rightFrameWidth, -d->bottomFrameWidth); |
|
867 } else |
|
868 cr.adjust(d->frameWidth, d->frameWidth, -d->frameWidth, -d->frameWidth); |
|
869 setContentsMargins(cr.left(), cr.top(), rect().right() - cr.right(), rect().bottom() - cr.bottom()); |
|
870 } |
|
871 |
|
872 /*! |
|
873 \fn int Q3GroupBox::frameWidth() const |
|
874 \internal |
|
875 */ |
|
876 |
|
877 int Q3GroupBox::frameWidth() const |
|
878 { |
|
879 return d->frameWidth; |
|
880 } |
|
881 |
|
882 #if defined(Q_MOC_RUN) |
|
883 /*! |
|
884 \enum Q3GroupBox::FrameShape |
|
885 \internal |
|
886 |
|
887 \value Box |
|
888 \value Sunken |
|
889 \value Plain |
|
890 \value Raised |
|
891 \value MShadow |
|
892 \value NoFrame |
|
893 \value Panel |
|
894 \value StyledPanel |
|
895 \value HLine |
|
896 \value VLine |
|
897 \value GroupBoxPanel |
|
898 \value WinPanel |
|
899 \value ToolBarPanel |
|
900 \value MenuBarPanel |
|
901 \value PopupPanel |
|
902 \value LineEditPanel |
|
903 \value TabWidgetPanel |
|
904 \value MShape |
|
905 */ |
|
906 #else |
|
907 /*! |
|
908 \enum Q3GroupBox::DummyFrame |
|
909 \internal |
|
910 |
|
911 \value Box |
|
912 \value Sunken |
|
913 \value Plain |
|
914 \value Raised |
|
915 \value MShadow |
|
916 \value NoFrame |
|
917 \value Panel |
|
918 \value StyledPanel |
|
919 \value HLine |
|
920 \value VLine |
|
921 \value GroupBoxPanel |
|
922 \value WinPanel |
|
923 \value ToolBarPanel |
|
924 \value MenuBarPanel |
|
925 \value PopupPanel |
|
926 \value LineEditPanel |
|
927 \value TabWidgetPanel |
|
928 \value MShape |
|
929 */ |
|
930 #endif |
|
931 |
|
932 /*! |
|
933 \typedef Q3GroupBox::FrameShape |
|
934 \internal |
|
935 */ |
|
936 |
|
937 /*! |
|
938 \property Q3GroupBox::margin |
|
939 \brief the width of the margin around the contents of the |
|
940 group box. |
|
941 */ |
|
942 |
|
943 /*! |
|
944 \fn void Q3GroupBox::setMargin(int margin) |
|
945 \since 4.2 |
|
946 |
|
947 Sets the width of the margin around the contents of the widget to \a margin. |
|
948 |
|
949 This function uses QWidget::setContentsMargins() to set the margin. |
|
950 \sa margin(), QWidget::setContentsMargins() |
|
951 */ |
|
952 |
|
953 /*! |
|
954 \fn int Q3GroupBox::margin() const |
|
955 \since 4.2 |
|
956 |
|
957 Returns the width of the margin around the contents of the widget. |
|
958 |
|
959 This function uses QWidget::getContentsMargins() to get the margin. |
|
960 |
|
961 \sa setMargin(), QWidget::getContentsMargins() |
|
962 */ |
|
963 |
|
964 QT_END_NAMESPACE |