src/qt3support/widgets/q3groupbox.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     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