~gabriel1984sibiu/minitube/qt5.6

« back to all changes in this revision

Viewing changes to src/widgets/kernel/qlayoutitem.cpp

  • Committer: Grevutiu Gabriel
  • Date: 2017-06-13 08:43:17 UTC
  • Revision ID: gabriel1984sibiu@gmail.com-20170613084317-ek0zqe0u9g3ocvi8
OriginalĀ upstreamĀ code

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 2016 The Qt Company Ltd.
 
4
** Contact: https://www.qt.io/licensing/
 
5
**
 
6
** This file is part of the QtWidgets module of the Qt Toolkit.
 
7
**
 
8
** $QT_BEGIN_LICENSE:LGPL$
 
9
** Commercial License Usage
 
10
** Licensees holding valid commercial Qt licenses may use this file in
 
11
** accordance with the commercial license agreement provided with the
 
12
** Software or, alternatively, in accordance with the terms contained in
 
13
** a written agreement between you and The Qt Company. For licensing terms
 
14
** and conditions see https://www.qt.io/terms-conditions. For further
 
15
** information use the contact form at https://www.qt.io/contact-us.
 
16
**
 
17
** GNU Lesser General Public License Usage
 
18
** Alternatively, this file may be used under the terms of the GNU Lesser
 
19
** General Public License version 3 as published by the Free Software
 
20
** Foundation and appearing in the file LICENSE.LGPL3 included in the
 
21
** packaging of this file. Please review the following information to
 
22
** ensure the GNU Lesser General Public License version 3 requirements
 
23
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
 
24
**
 
25
** GNU General Public License Usage
 
26
** Alternatively, this file may be used under the terms of the GNU
 
27
** General Public License version 2.0 or (at your option) the GNU General
 
28
** Public license version 3 or any later version approved by the KDE Free
 
29
** Qt Foundation. The licenses are as published by the Free Software
 
30
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
 
31
** included in the packaging of this file. Please review the following
 
32
** information to ensure the GNU General Public License requirements will
 
33
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
 
34
** https://www.gnu.org/licenses/gpl-3.0.html.
 
35
**
 
36
** $QT_END_LICENSE$
 
37
**
 
38
****************************************************************************/
 
39
 
 
40
#include "qlayout.h"
 
41
 
 
42
#include "qapplication.h"
 
43
#include "qlayoutengine_p.h"
 
44
#include "qmenubar.h"
 
45
#include "qtoolbar.h"
 
46
#include "qevent.h"
 
47
#include "qstyle.h"
 
48
#include "qvariant.h"
 
49
#include "qwidget_p.h"
 
50
 
 
51
QT_BEGIN_NAMESPACE
 
52
 
 
53
inline static QRect fromLayoutItemRect(QWidgetPrivate *priv, const QRect &rect)
 
54
{
 
55
    return rect.adjusted(priv->leftLayoutItemMargin, priv->topLayoutItemMargin,
 
56
                         -priv->rightLayoutItemMargin, -priv->bottomLayoutItemMargin);
 
57
}
 
58
 
 
59
inline static QSize fromLayoutItemSize(QWidgetPrivate *priv, const QSize &size)
 
60
{
 
61
    return fromLayoutItemRect(priv, QRect(QPoint(0, 0), size)).size();
 
62
}
 
63
 
 
64
inline static QRect toLayoutItemRect(QWidgetPrivate *priv, const QRect &rect)
 
65
{
 
66
    return rect.adjusted(-priv->leftLayoutItemMargin, -priv->topLayoutItemMargin,
 
67
                         priv->rightLayoutItemMargin, priv->bottomLayoutItemMargin);
 
68
}
 
69
 
 
70
inline static QSize toLayoutItemSize(QWidgetPrivate *priv, const QSize &size)
 
71
{
 
72
    return toLayoutItemRect(priv, QRect(QPoint(0, 0), size)).size();
 
73
}
 
74
 
 
75
/*!
 
76
    \class QLayoutItem
 
77
    \brief The QLayoutItem class provides an abstract item that a
 
78
    QLayout manipulates.
 
79
 
 
80
    \ingroup geomanagement
 
81
    \inmodule QtWidgets
 
82
 
 
83
    This is used by custom layouts.
 
84
 
 
85
    Pure virtual functions are provided to return information about
 
86
    the layout, including, sizeHint(), minimumSize(), maximumSize()
 
87
    and expanding().
 
88
 
 
89
    The layout's geometry can be set and retrieved with setGeometry()
 
90
    and geometry(), and its alignment with setAlignment() and
 
91
    alignment().
 
92
 
 
93
    isEmpty() returns whether the layout item is empty. If the
 
94
    concrete item is a QWidget, it can be retrieved using widget().
 
95
    Similarly for layout() and spacerItem().
 
96
 
 
97
    Some layouts have width and height interdependencies. These can
 
98
    be expressed using hasHeightForWidth(), heightForWidth(), and
 
99
    minimumHeightForWidth(). For more explanation see the \e{Qt
 
100
    Quarterly} article
 
101
    \l{http://doc.qt.io/archives/qq/qq04-height-for-width.html}{Trading
 
102
    Height for Width}.
 
103
 
 
104
    \sa QLayout
 
105
*/
 
106
 
 
107
/*!
 
108
    \class QSpacerItem
 
109
    \ingroup geomanagement
 
110
    \brief The QSpacerItem class provides blank space in a layout.
 
111
 
 
112
    \inmodule QtWidgets
 
113
 
 
114
    Normally, you don't need to use this class directly. Qt's
 
115
    built-in layout managers provide the following functions for
 
116
    manipulating empty space in layouts:
 
117
 
 
118
    \table
 
119
    \header \li Class
 
120
            \li Functions
 
121
    \row    \li QHBoxLayout
 
122
            \li \l{QBoxLayout::addSpacing()}{addSpacing()},
 
123
               \l{QBoxLayout::addStretch()}{addStretch()},
 
124
               \l{QBoxLayout::insertSpacing()}{insertSpacing()},
 
125
               \l{QBoxLayout::insertStretch()}{insertStretch()}
 
126
    \row    \li QGridLayout
 
127
            \li \l{QGridLayout::setRowMinimumHeight()}{setRowMinimumHeight()},
 
128
               \l{QGridLayout::setRowStretch()}{setRowStretch()},
 
129
               \l{QGridLayout::setColumnMinimumWidth()}{setColumnMinimumWidth()},
 
130
               \l{QGridLayout::setColumnStretch()}{setColumnStretch()}
 
131
    \endtable
 
132
 
 
133
    \sa QLayout, QWidgetItem, QLayoutItem::spacerItem()
 
134
*/
 
135
 
 
136
/*!
 
137
    \class QWidgetItem
 
138
    \ingroup geomanagement
 
139
    \brief The QWidgetItem class is a layout item that represents a widget.
 
140
 
 
141
    \inmodule QtWidgets
 
142
 
 
143
    Normally, you don't need to use this class directly. Qt's
 
144
    built-in layout managers provide the following functions for
 
145
    manipulating widgets in layouts:
 
146
 
 
147
    \table
 
148
    \header \li Class
 
149
            \li Functions
 
150
    \row    \li QBoxLayout
 
151
            \li \l{QBoxLayout::addWidget()}{addWidget()},
 
152
               \l{QBoxLayout::insertWidget()}{insertWidget()},
 
153
               \l{QBoxLayout::setStretchFactor()}{setStretchFactor()}
 
154
    \row    \li QGridLayout
 
155
            \li \l{QGridLayout::addWidget()}{addWidget()}
 
156
    \row    \li QStackedLayout
 
157
            \li \l{QStackedLayout::addWidget()}{addWidget()},
 
158
               \l{QStackedLayout::insertWidget()}{insertWidget()},
 
159
               \l{QStackedLayout::currentWidget()}{currentWidget()},
 
160
               \l{QStackedLayout::setCurrentWidget()}{setCurrentWidget()},
 
161
               \l{QStackedLayout::widget()}{widget()}
 
162
    \endtable
 
163
 
 
164
    \sa QLayout, QSpacerItem, QLayoutItem::widget()
 
165
*/
 
166
 
 
167
/*!
 
168
    \fn QLayoutItem::QLayoutItem(Qt::Alignment alignment)
 
169
 
 
170
    Constructs a layout item with an \a alignment.
 
171
    Not all subclasses support alignment.
 
172
*/
 
173
 
 
174
/*!
 
175
    \fn Qt::Alignment QLayoutItem::alignment() const
 
176
 
 
177
    Returns the alignment of this item.
 
178
*/
 
179
 
 
180
/*!
 
181
    Sets the alignment of this item to \a alignment.
 
182
 
 
183
    \b{Note:} Item alignment is only supported by QLayoutItem subclasses
 
184
    where it would have a visual effect. Except for QSpacerItem, which provides
 
185
    blank space for layouts, all public Qt classes that inherit QLayoutItem
 
186
    support item alignment.
 
187
*/
 
188
void QLayoutItem::setAlignment(Qt::Alignment alignment)
 
189
{
 
190
    align = alignment;
 
191
}
 
192
 
 
193
/*!
 
194
    \fn QSize QLayoutItem::maximumSize() const
 
195
 
 
196
    Implemented in subclasses to return the maximum size of this item.
 
197
*/
 
198
 
 
199
/*!
 
200
    \fn QSize QLayoutItem::minimumSize() const
 
201
 
 
202
    Implemented in subclasses to return the minimum size of this item.
 
203
*/
 
204
 
 
205
/*!
 
206
    \fn QSize QLayoutItem::sizeHint() const
 
207
 
 
208
    Implemented in subclasses to return the preferred size of this item.
 
209
*/
 
210
 
 
211
/*!
 
212
    \fn Qt::Orientations QLayoutItem::expandingDirections() const
 
213
 
 
214
    Returns whether this layout item can make use of more space than
 
215
    sizeHint(). A value of Qt::Vertical or Qt::Horizontal means that
 
216
    it wants to grow in only one dimension, whereas Qt::Vertical |
 
217
    Qt::Horizontal means that it wants to grow in both dimensions.
 
218
*/
 
219
 
 
220
/*!
 
221
    \fn void QLayoutItem::setGeometry(const QRect &r)
 
222
 
 
223
    Implemented in subclasses to set this item's geometry to \a r.
 
224
 
 
225
    \sa geometry()
 
226
*/
 
227
 
 
228
/*!
 
229
    \fn QRect QLayoutItem::geometry() const
 
230
 
 
231
    Returns the rectangle covered by this layout item.
 
232
 
 
233
    \sa setGeometry()
 
234
*/
 
235
 
 
236
/*!
 
237
    \fn virtual bool QLayoutItem::isEmpty() const
 
238
 
 
239
    Implemented in subclasses to return whether this item is empty,
 
240
    i.e. whether it contains any widgets.
 
241
*/
 
242
 
 
243
/*!
 
244
    \fn QSpacerItem::QSpacerItem(int w, int h, QSizePolicy::Policy hPolicy, QSizePolicy::Policy vPolicy)
 
245
 
 
246
    Constructs a spacer item with preferred width \a w, preferred
 
247
    height \a h, horizontal size policy \a hPolicy and vertical size
 
248
    policy \a vPolicy.
 
249
 
 
250
    The default values provide a gap that is able to stretch if
 
251
    nothing else wants the space.
 
252
*/
 
253
 
 
254
/*!
 
255
    Destructor.
 
256
*/
 
257
QSpacerItem::~QSpacerItem() {}
 
258
 
 
259
/*!
 
260
    Changes this spacer item to have preferred width \a w, preferred
 
261
    height \a h, horizontal size policy \a hPolicy and vertical size
 
262
    policy \a vPolicy.
 
263
 
 
264
    The default values provide a gap that is able to stretch if
 
265
    nothing else wants the space.
 
266
 
 
267
    Note that if changeSize() is called after the spacer item has been added
 
268
    to a layout, it is necessary to invalidate the layout in order for the
 
269
    spacer item's new size to take effect.
 
270
 
 
271
    \sa QSpacerItem::invalidate()
 
272
*/
 
273
void QSpacerItem::changeSize(int w, int h, QSizePolicy::Policy hPolicy,
 
274
                             QSizePolicy::Policy vPolicy)
 
275
{
 
276
    width = w;
 
277
    height = h;
 
278
    sizeP = QSizePolicy(hPolicy, vPolicy);
 
279
}
 
280
 
 
281
/*!
 
282
    \fn QWidgetItem::QWidgetItem(QWidget *widget)
 
283
 
 
284
    Creates an item containing the given \a widget.
 
285
*/
 
286
 
 
287
/*!
 
288
    Destructor.
 
289
*/
 
290
QWidgetItem::~QWidgetItem() {}
 
291
 
 
292
/*!
 
293
    Destroys the QLayoutItem.
 
294
*/
 
295
QLayoutItem::~QLayoutItem()
 
296
{
 
297
}
 
298
 
 
299
/*!
 
300
    Invalidates any cached information in this layout item.
 
301
*/
 
302
void QLayoutItem::invalidate()
 
303
{
 
304
}
 
305
 
 
306
/*!
 
307
    If this item is a QLayout, it is returned as a QLayout; otherwise
 
308
    0 is returned. This function provides type-safe casting.
 
309
 
 
310
    \sa spacerItem(), widget()
 
311
*/
 
312
QLayout * QLayoutItem::layout()
 
313
{
 
314
    return 0;
 
315
}
 
316
 
 
317
/*!
 
318
    If this item is a QSpacerItem, it is returned as a QSpacerItem;
 
319
    otherwise 0 is returned. This function provides type-safe casting.
 
320
 
 
321
    \sa layout(), widget()
 
322
*/
 
323
QSpacerItem * QLayoutItem::spacerItem()
 
324
{
 
325
    return 0;
 
326
}
 
327
 
 
328
/*!
 
329
    \reimp
 
330
*/
 
331
QLayout * QLayout::layout()
 
332
{
 
333
    return this;
 
334
}
 
335
 
 
336
/*!
 
337
    Returns a pointer to this object.
 
338
*/
 
339
QSpacerItem * QSpacerItem::spacerItem()
 
340
{
 
341
    return this;
 
342
}
 
343
 
 
344
/*!
 
345
    \fn QSizePolicy QSpacerItem::sizePolicy() const
 
346
    \since 5.5
 
347
 
 
348
    Returns the size policy of this item.
 
349
*/
 
350
 
 
351
/*!
 
352
    If this item manages a QWidget, returns that widget. Otherwise,
 
353
    \c nullptr is returned.
 
354
 
 
355
    \note While the functions layout() and spacerItem() perform casts, this
 
356
    function returns another object: QLayout and QSpacerItem inherit QLayoutItem,
 
357
    while QWidget does not.
 
358
 
 
359
    \sa layout(), spacerItem()
 
360
*/
 
361
QWidget * QLayoutItem::widget()
 
362
{
 
363
    return 0;
 
364
}
 
365
 
 
366
/*!
 
367
    Returns the widget managed by this item.
 
368
*/
 
369
QWidget *QWidgetItem::widget()
 
370
{
 
371
    return wid;
 
372
}
 
373
 
 
374
/*!
 
375
    Returns \c true if this layout's preferred height depends on its
 
376
    width; otherwise returns \c false. The default implementation returns
 
377
    false.
 
378
 
 
379
    Reimplement this function in layout managers that support height
 
380
    for width.
 
381
 
 
382
    \sa heightForWidth(), QWidget::heightForWidth()
 
383
*/
 
384
bool QLayoutItem::hasHeightForWidth() const
 
385
{
 
386
    return false;
 
387
}
 
388
 
 
389
/*!
 
390
    Returns the minimum height this widget needs for the given width,
 
391
    \a w. The default implementation simply returns heightForWidth(\a
 
392
    w).
 
393
*/
 
394
int QLayoutItem::minimumHeightForWidth(int w) const
 
395
{
 
396
    return heightForWidth(w);
 
397
}
 
398
 
 
399
 
 
400
/*!
 
401
    Returns the preferred height for this layout item, given the width
 
402
    \a w.
 
403
 
 
404
    The default implementation returns -1, indicating that the
 
405
    preferred height is independent of the width of the item. Using
 
406
    the function hasHeightForWidth() will typically be much faster
 
407
    than calling this function and testing for -1.
 
408
 
 
409
    Reimplement this function in layout managers that support height
 
410
    for width. A typical implementation will look like this:
 
411
    \snippet code/src_gui_kernel_qlayoutitem.cpp 0
 
412
 
 
413
    Caching is strongly recommended; without it layout will take
 
414
    exponential time.
 
415
 
 
416
    \sa hasHeightForWidth()
 
417
*/
 
418
int QLayoutItem::heightForWidth(int /* w */) const
 
419
{
 
420
    return -1;
 
421
}
 
422
 
 
423
/*!
 
424
    Returns the control type(s) for the layout item. For a
 
425
    QWidgetItem, the control type comes from the widget's size
 
426
    policy; for a QLayoutItem, the control types is derived from the
 
427
    layout's contents.
 
428
 
 
429
    \sa QSizePolicy::controlType()
 
430
*/
 
431
QSizePolicy::ControlTypes QLayoutItem::controlTypes() const
 
432
{
 
433
    return QSizePolicy::DefaultType;
 
434
}
 
435
 
 
436
/*!
 
437
    \reimp
 
438
*/
 
439
void QSpacerItem::setGeometry(const QRect &r)
 
440
{
 
441
    rect = r;
 
442
}
 
443
 
 
444
/*!
 
445
    \reimp
 
446
*/
 
447
void QWidgetItem::setGeometry(const QRect &rect)
 
448
{
 
449
    if (isEmpty())
 
450
        return;
 
451
 
 
452
    QRect r = !wid->testAttribute(Qt::WA_LayoutUsesWidgetRect)
 
453
            ? fromLayoutItemRect(wid->d_func(), rect)
 
454
            : rect;
 
455
    const QSize widgetRectSurplus = r.size() - rect.size();
 
456
 
 
457
    /*
 
458
       For historical reasons, this code is done using widget rect
 
459
       coordinates, not layout item rect coordinates. However,
 
460
       QWidgetItem's sizeHint(), maximumSize(), and heightForWidth()
 
461
       all work in terms of layout item rect coordinates, so we have to
 
462
       add or subtract widgetRectSurplus here and there. The code could
 
463
       be much simpler if we did everything using layout item rect
 
464
       coordinates and did the conversion right before the call to
 
465
       QWidget::setGeometry().
 
466
     */
 
467
 
 
468
    QSize s = r.size().boundedTo(maximumSize() + widgetRectSurplus);
 
469
    int x = r.x();
 
470
    int y = r.y();
 
471
    if (align & (Qt::AlignHorizontal_Mask | Qt::AlignVertical_Mask)) {
 
472
        QSize pref(sizeHint());
 
473
        QSizePolicy sp = wid->sizePolicy();
 
474
        if (sp.horizontalPolicy() == QSizePolicy::Ignored)
 
475
            pref.setWidth(wid->sizeHint().expandedTo(wid->minimumSize()).width());
 
476
        if (sp.verticalPolicy() == QSizePolicy::Ignored)
 
477
            pref.setHeight(wid->sizeHint().expandedTo(wid->minimumSize()).height());
 
478
        pref += widgetRectSurplus;
 
479
        if (align & Qt::AlignHorizontal_Mask)
 
480
            s.setWidth(qMin(s.width(), pref.width()));
 
481
        if (align & Qt::AlignVertical_Mask) {
 
482
            if (hasHeightForWidth())
 
483
                s.setHeight(qMin(s.height(),
 
484
                                 heightForWidth(s.width() - widgetRectSurplus.width())
 
485
                                 + widgetRectSurplus.height()));
 
486
            else
 
487
                s.setHeight(qMin(s.height(), pref.height()));
 
488
        }
 
489
    }
 
490
    Qt::Alignment alignHoriz = QStyle::visualAlignment(wid->layoutDirection(), align);
 
491
    if (alignHoriz & Qt::AlignRight)
 
492
        x = x + (r.width() - s.width());
 
493
    else if (!(alignHoriz & Qt::AlignLeft))
 
494
        x = x + (r.width() - s.width()) / 2;
 
495
 
 
496
    if (align & Qt::AlignBottom)
 
497
        y = y + (r.height() - s.height());
 
498
    else if (!(align & Qt::AlignTop))
 
499
        y = y + (r.height() - s.height()) / 2;
 
500
 
 
501
    wid->setGeometry(x, y, s.width(), s.height());
 
502
}
 
503
 
 
504
/*!
 
505
    \reimp
 
506
*/
 
507
QRect QSpacerItem::geometry() const
 
508
{
 
509
    return rect;
 
510
}
 
511
 
 
512
/*!
 
513
    \reimp
 
514
*/
 
515
QRect QWidgetItem::geometry() const
 
516
{
 
517
    return !wid->testAttribute(Qt::WA_LayoutUsesWidgetRect)
 
518
           ? toLayoutItemRect(wid->d_func(), wid->geometry())
 
519
           : wid->geometry();
 
520
}
 
521
 
 
522
 
 
523
/*!
 
524
    \reimp
 
525
*/
 
526
bool QWidgetItem::hasHeightForWidth() const
 
527
{
 
528
    if (isEmpty())
 
529
        return false;
 
530
    return wid->hasHeightForWidth();
 
531
}
 
532
 
 
533
/*!
 
534
    \reimp
 
535
*/
 
536
int QWidgetItem::heightForWidth(int w) const
 
537
{
 
538
    if (isEmpty())
 
539
        return -1;
 
540
 
 
541
    w = !wid->testAttribute(Qt::WA_LayoutUsesWidgetRect)
 
542
      ? fromLayoutItemSize(wid->d_func(), QSize(w, 0)).width()
 
543
      : w;
 
544
 
 
545
    int hfw;
 
546
    if (wid->layout())
 
547
        hfw = wid->layout()->totalHeightForWidth(w);
 
548
    else
 
549
        hfw = wid->heightForWidth(w);
 
550
 
 
551
    if (hfw > wid->maximumHeight())
 
552
        hfw = wid->maximumHeight();
 
553
    if (hfw < wid->minimumHeight())
 
554
        hfw = wid->minimumHeight();
 
555
 
 
556
    hfw = !wid->testAttribute(Qt::WA_LayoutUsesWidgetRect)
 
557
        ? toLayoutItemSize(wid->d_func(), QSize(0, hfw)).height()
 
558
        : hfw;
 
559
 
 
560
    if (hfw < 0)
 
561
        hfw = 0;
 
562
    return hfw;
 
563
}
 
564
 
 
565
/*!
 
566
    \reimp
 
567
*/
 
568
Qt::Orientations QSpacerItem::expandingDirections() const
 
569
{
 
570
    return sizeP.expandingDirections();
 
571
}
 
572
 
 
573
/*!
 
574
    \reimp
 
575
*/
 
576
Qt::Orientations QWidgetItem::expandingDirections() const
 
577
{
 
578
    if (isEmpty())
 
579
        return Qt::Orientations(0);
 
580
 
 
581
    Qt::Orientations e = wid->sizePolicy().expandingDirections();
 
582
    /*
 
583
      If the layout is expanding, we make the widget expanding, even if
 
584
      its own size policy isn't expanding.
 
585
    */
 
586
    if (wid->layout()) {
 
587
        if (wid->sizePolicy().horizontalPolicy() & QSizePolicy::GrowFlag
 
588
                && (wid->layout()->expandingDirections() & Qt::Horizontal))
 
589
            e |= Qt::Horizontal;
 
590
        if (wid->sizePolicy().verticalPolicy() & QSizePolicy::GrowFlag
 
591
                && (wid->layout()->expandingDirections() & Qt::Vertical))
 
592
            e |= Qt::Vertical;
 
593
    }
 
594
 
 
595
    if (align & Qt::AlignHorizontal_Mask)
 
596
        e &= ~Qt::Horizontal;
 
597
    if (align & Qt::AlignVertical_Mask)
 
598
        e &= ~Qt::Vertical;
 
599
    return e;
 
600
}
 
601
 
 
602
/*!
 
603
    \reimp
 
604
*/
 
605
QSize QSpacerItem::minimumSize() const
 
606
{
 
607
    return QSize(sizeP.horizontalPolicy() & QSizePolicy::ShrinkFlag ? 0 : width,
 
608
                 sizeP.verticalPolicy() & QSizePolicy::ShrinkFlag ? 0 : height);
 
609
}
 
610
 
 
611
/*!
 
612
    \reimp
 
613
*/
 
614
QSize QWidgetItem::minimumSize() const
 
615
{
 
616
    if (isEmpty())
 
617
        return QSize(0, 0);
 
618
    return !wid->testAttribute(Qt::WA_LayoutUsesWidgetRect)
 
619
           ? toLayoutItemSize(wid->d_func(), qSmartMinSize(this))
 
620
           : qSmartMinSize(this);
 
621
}
 
622
 
 
623
/*!
 
624
    \reimp
 
625
*/
 
626
QSize QSpacerItem::maximumSize() const
 
627
{
 
628
    return QSize(sizeP.horizontalPolicy() & QSizePolicy::GrowFlag ? QLAYOUTSIZE_MAX : width,
 
629
                 sizeP.verticalPolicy() & QSizePolicy::GrowFlag ? QLAYOUTSIZE_MAX : height);
 
630
}
 
631
 
 
632
/*!
 
633
    \reimp
 
634
*/
 
635
QSize QWidgetItem::maximumSize() const
 
636
{
 
637
    if (isEmpty()) {
 
638
        return QSize(0, 0);
 
639
    } else {
 
640
        return !wid->testAttribute(Qt::WA_LayoutUsesWidgetRect)
 
641
               ? toLayoutItemSize(wid->d_func(), qSmartMaxSize(this, align))
 
642
               : qSmartMaxSize(this, align);
 
643
    }
 
644
}
 
645
 
 
646
/*!
 
647
    \reimp
 
648
*/
 
649
QSize QSpacerItem::sizeHint() const
 
650
{
 
651
    return QSize(width, height);
 
652
}
 
653
 
 
654
/*!
 
655
    \reimp
 
656
*/
 
657
QSize QWidgetItem::sizeHint() const
 
658
{
 
659
    QSize s(0, 0);
 
660
    if (!isEmpty()) {
 
661
        s = wid->sizeHint().expandedTo(wid->minimumSizeHint());
 
662
        s = s.boundedTo(wid->maximumSize())
 
663
             .expandedTo(wid->minimumSize());
 
664
        s = !wid->testAttribute(Qt::WA_LayoutUsesWidgetRect)
 
665
           ? toLayoutItemSize(wid->d_func(), s)
 
666
           : s;
 
667
 
 
668
        if (wid->sizePolicy().horizontalPolicy() == QSizePolicy::Ignored)
 
669
            s.setWidth(0);
 
670
        if (wid->sizePolicy().verticalPolicy() == QSizePolicy::Ignored)
 
671
            s.setHeight(0);
 
672
    }
 
673
    return s;
 
674
}
 
675
 
 
676
/*!
 
677
    Returns \c true.
 
678
*/
 
679
bool QSpacerItem::isEmpty() const
 
680
{
 
681
    return true;
 
682
}
 
683
 
 
684
/*!
 
685
    Returns \c true if the widget is hidden; otherwise returns \c false.
 
686
 
 
687
    \sa QWidget::isHidden()
 
688
*/
 
689
bool QWidgetItem::isEmpty() const
 
690
{
 
691
    return (wid->isHidden() && !wid->sizePolicy().retainSizeWhenHidden()) || wid->isWindow();
 
692
}
 
693
 
 
694
/*!
 
695
    Returns the control type associated with the widget for which
 
696
    this size policy applies.
 
697
 
 
698
    \sa QSizePolicy::controlType()
 
699
 */
 
700
QSizePolicy::ControlTypes QWidgetItem::controlTypes() const
 
701
{
 
702
    return wid->sizePolicy().controlType();
 
703
}
 
704
 
 
705
/*!
 
706
    \class QWidgetItemV2
 
707
    \internal
 
708
*/
 
709
 
 
710
inline bool QWidgetItemV2::useSizeCache() const
 
711
{
 
712
    return wid->d_func()->widgetItem == this;
 
713
}
 
714
 
 
715
void QWidgetItemV2::updateCacheIfNecessary() const
 
716
{
 
717
    if (q_cachedMinimumSize.width() != Dirty)
 
718
        return;
 
719
 
 
720
    const QSize sizeHint(wid->sizeHint());
 
721
    const QSize minimumSizeHint(wid->minimumSizeHint());
 
722
    const QSize minimumSize(wid->minimumSize());
 
723
    const QSize maximumSize(wid->maximumSize());
 
724
    const QSizePolicy sizePolicy(wid->sizePolicy());
 
725
    const QSize expandedSizeHint(sizeHint.expandedTo(minimumSizeHint));
 
726
 
 
727
    const QSize smartMinSize(qSmartMinSize(sizeHint, minimumSizeHint, minimumSize, maximumSize, sizePolicy));
 
728
    const QSize smartMaxSize(qSmartMaxSize(expandedSizeHint, minimumSize, maximumSize, sizePolicy, align));
 
729
 
 
730
    const bool useLayoutItemRect = !wid->testAttribute(Qt::WA_LayoutUsesWidgetRect);
 
731
 
 
732
    q_cachedMinimumSize = useLayoutItemRect
 
733
           ? toLayoutItemSize(wid->d_func(), smartMinSize)
 
734
           : smartMinSize;
 
735
 
 
736
    q_cachedSizeHint = expandedSizeHint;
 
737
    q_cachedSizeHint = q_cachedSizeHint.boundedTo(maximumSize)
 
738
                                       .expandedTo(minimumSize);
 
739
    q_cachedSizeHint = useLayoutItemRect
 
740
           ? toLayoutItemSize(wid->d_func(), q_cachedSizeHint)
 
741
           : q_cachedSizeHint;
 
742
 
 
743
    if (wid->sizePolicy().horizontalPolicy() == QSizePolicy::Ignored)
 
744
        q_cachedSizeHint.setWidth(0);
 
745
    if (wid->sizePolicy().verticalPolicy() == QSizePolicy::Ignored)
 
746
        q_cachedSizeHint.setHeight(0);
 
747
 
 
748
    q_cachedMaximumSize = useLayoutItemRect
 
749
               ? toLayoutItemSize(wid->d_func(), smartMaxSize)
 
750
               : smartMaxSize;
 
751
}
 
752
 
 
753
QWidgetItemV2::QWidgetItemV2(QWidget *widget)
 
754
    : QWidgetItem(widget),
 
755
      q_cachedMinimumSize(Dirty, Dirty),
 
756
      q_cachedSizeHint(Dirty, Dirty),
 
757
      q_cachedMaximumSize(Dirty, Dirty),
 
758
      q_firstCachedHfw(0),
 
759
      q_hfwCacheSize(0),
 
760
      d(0)
 
761
{
 
762
    QWidgetPrivate *wd = wid->d_func();
 
763
    if (!wd->widgetItem)
 
764
        wd->widgetItem = this;
 
765
}
 
766
 
 
767
QWidgetItemV2::~QWidgetItemV2()
 
768
{
 
769
    if (wid) {
 
770
        QWidgetPrivate *wd = wid->d_func();
 
771
        if (wd->widgetItem == this)
 
772
            wd->widgetItem = 0;
 
773
    }
 
774
}
 
775
 
 
776
QSize QWidgetItemV2::sizeHint() const
 
777
{
 
778
    if (isEmpty())
 
779
        return QSize(0, 0);
 
780
 
 
781
    if (useSizeCache()) {
 
782
        updateCacheIfNecessary();
 
783
        return q_cachedSizeHint;
 
784
    } else {
 
785
        return QWidgetItem::sizeHint();
 
786
    }
 
787
}
 
788
 
 
789
QSize QWidgetItemV2::minimumSize() const
 
790
{
 
791
    if (isEmpty())
 
792
        return QSize(0, 0);
 
793
 
 
794
    if (useSizeCache()) {
 
795
        updateCacheIfNecessary();
 
796
        return q_cachedMinimumSize;
 
797
    } else {
 
798
        return QWidgetItem::minimumSize();
 
799
    }
 
800
}
 
801
 
 
802
QSize QWidgetItemV2::maximumSize() const
 
803
{
 
804
    if (isEmpty())
 
805
        return QSize(0, 0);
 
806
 
 
807
    if (useSizeCache()) {
 
808
        updateCacheIfNecessary();
 
809
        return q_cachedMaximumSize;
 
810
    } else {
 
811
        return QWidgetItem::maximumSize();
 
812
    }
 
813
}
 
814
 
 
815
/*
 
816
    The height-for-width cache is organized as a circular buffer. The entries
 
817
 
 
818
        q_hfwCachedHfws[q_firstCachedHfw],
 
819
        ...,
 
820
        q_hfwCachedHfws[(q_firstCachedHfw + q_hfwCacheSize - 1) % HfwCacheMaxSize]
 
821
 
 
822
    contain the last cached values. When the cache is full, the first entry to
 
823
    be erased is the entry before q_hfwCachedHfws[q_firstCachedHfw]. When
 
824
    values are looked up, we try to move q_firstCachedHfw to point to that new
 
825
    entry (unless the cache is not full, in which case it would leave the cache
 
826
    in a broken state), so that the most recently used entry is also the last
 
827
    to be erased.
 
828
*/
 
829
 
 
830
int QWidgetItemV2::heightForWidth(int width) const
 
831
{
 
832
    if (isEmpty())
 
833
        return -1;
 
834
 
 
835
    for (int i = 0; i < q_hfwCacheSize; ++i) {
 
836
        int offset = q_firstCachedHfw + i;
 
837
        const QSize &size = q_cachedHfws[offset % HfwCacheMaxSize];
 
838
        if (size.width() == width) {
 
839
            if (q_hfwCacheSize == HfwCacheMaxSize)
 
840
                q_firstCachedHfw = offset;
 
841
            return size.height();
 
842
        }
 
843
    }
 
844
 
 
845
    if (q_hfwCacheSize < HfwCacheMaxSize)
 
846
        ++q_hfwCacheSize;
 
847
    q_firstCachedHfw = (q_firstCachedHfw + HfwCacheMaxSize - 1) % HfwCacheMaxSize;
 
848
 
 
849
    int height = QWidgetItem::heightForWidth(width);
 
850
    q_cachedHfws[q_firstCachedHfw] = QSize(width, height);
 
851
    return height;
 
852
}
 
853
 
 
854
QT_END_NAMESPACE