source: trunk/src/gui/widgets/qabstractscrollarea.cpp@ 187

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

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

File size: 43.1 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qabstractscrollarea.h"
43
44#ifndef QT_NO_SCROLLAREA
45
46#include "qscrollbar.h"
47#include "qapplication.h"
48#include "qstyle.h"
49#include "qstyleoption.h"
50#include "qevent.h"
51#include "qdebug.h"
52#include "qboxlayout.h"
53#include "qpainter.h"
54
55#include "qabstractscrollarea_p.h"
56#include <qwidget.h>
57
58#ifdef Q_WS_MAC
59#include <private/qt_mac_p.h>
60#include <private/qt_cocoa_helpers_mac_p.h>
61#endif
62
63QT_BEGIN_NAMESPACE
64
65/*!
66 \class QAbstractScrollArea
67 \brief The QAbstractScrollArea widget provides a scrolling area with
68 on-demand scroll bars.
69
70 \ingroup abstractwidgets
71
72 QAbstractScrollArea is a low-level abstraction of a scrolling
73 area. The area provides a central widget called the viewport, in
74 which the contents of the area is to be scrolled (i.e, the
75 visible parts of the contents are rendered in the viewport).
76
77 Next to the viewport is a vertical scroll bar, and below is a
78 horizontal scroll bar. When all of the area contents fits in the
79 viewport, each scroll bar can be either visible or hidden
80 depending on the scroll bar's Qt::ScrollBarPolicy. When a scroll
81 bar is hidden, the viewport expands in order to cover all
82 available space. When a scroll bar becomes visible again, the
83 viewport shrinks in order to make room for the scroll bar.
84
85 It is possible to reserve a margin area around the viewport, see
86 setViewportMargins(). The feature is mostly used to place a
87 QHeaderView widget above or beside the scrolling area. Subclasses
88 of QAbstractScrollArea should implement margins.
89
90 When inheriting QAbstractScrollArea, you need to do the
91 following:
92
93 \list
94 \o Control the scroll bars by setting their
95 range, value, page step, and tracking their
96 movements.
97 \o Draw the contents of the area in the viewport according
98 to the values of the scroll bars.
99 \o Handle events received by the viewport in
100 viewportEvent() - notably resize events.
101 \o Use \c{viewport->update()} to update the contents of the
102 viewport instead of \l{QWidget::update()}{update()}
103 as all painting operations take place on the viewport.
104 \endlist
105
106 With a scroll bar policy of Qt::ScrollBarAsNeeded (the default),
107 QAbstractScrollArea shows scroll bars when they provide a non-zero
108 scrolling range, and hides them otherwise.
109
110 The scroll bars and viewport should be updated whenever the viewport
111 receives a resize event or the size of the contents changes.
112 The viewport also needs to be updated when the scroll bars
113 values change. The initial values of the scroll bars are often
114 set when the area receives new contents.
115
116 We give a simple example, in which we have implemented a scroll area
117 that can scroll any QWidget. We make the widget a child of the
118 viewport; this way, we do not have to calculate which part of
119 the widget to draw but can simply move the widget with
120 QWidget::move(). When the area contents or the viewport size
121 changes, we do the following:
122
123 \snippet doc/src/snippets/myscrollarea.cpp 1
124
125 When the scroll bars change value, we need to update the widget
126 position, i.e., find the part of the widget that is to be drawn in
127 the viewport:
128
129 \snippet doc/src/snippets/myscrollarea.cpp 0
130
131 In order to track scroll bar movements, reimplement the virtual
132 function scrollContentsBy(). In order to fine-tune scrolling
133 behavior, connect to a scroll bar's
134 QAbstractSlider::actionTriggered() signal and adjust the \l
135 QAbstractSlider::sliderPosition as you wish.
136
137 For convenience, QAbstractScrollArea makes all viewport events
138 available in the virtual viewportEvent() handler. QWidget's
139 specialized handlers are remapped to viewport events in the cases
140 where this makes sense. The remapped specialized handlers are:
141 paintEvent(), mousePressEvent(), mouseReleaseEvent(),
142 mouseDoubleClickEvent(), mouseMoveEvent(), wheelEvent(),
143 dragEnterEvent(), dragMoveEvent(), dragLeaveEvent(), dropEvent(),
144 contextMenuEvent(), and resizeEvent().
145
146 QScrollArea, which inherits QAbstractScrollArea, provides smooth
147 scrolling for any QWidget (i.e., the widget is scrolled pixel by
148 pixel). You only need to subclass QAbstractScrollArea if you need
149 more specialized behavior. This is, for instance, true if the
150 entire contents of the area is not suitable for being drawn on a
151 QWidget or if you do not want smooth scrolling.
152
153 \sa QScrollArea
154*/
155
156QAbstractScrollAreaPrivate::QAbstractScrollAreaPrivate()
157 :hbar(0), vbar(0), vbarpolicy(Qt::ScrollBarAsNeeded), hbarpolicy(Qt::ScrollBarAsNeeded),
158 viewport(0), cornerWidget(0), left(0), top(0), right(0), bottom(0),
159 xoffset(0), yoffset(0), viewportFilter(0)
160{
161}
162
163QAbstractScrollAreaScrollBarContainer::QAbstractScrollAreaScrollBarContainer(Qt::Orientation orientation, QWidget *parent)
164 :QWidget(parent), scrollBar(new QScrollBar(orientation, this)),
165 layout(new QBoxLayout(orientation == Qt::Horizontal ? QBoxLayout::LeftToRight : QBoxLayout::TopToBottom)),
166 orientation(orientation)
167{
168 setLayout(layout);
169 layout->setMargin(0);
170 layout->setSpacing(0);
171 layout->addWidget(scrollBar);
172}
173
174/*! \internal
175 Adds a widget to the scroll bar container.
176*/
177void QAbstractScrollAreaScrollBarContainer::addWidget(QWidget *widget, LogicalPosition position)
178{
179 QSizePolicy policy = widget->sizePolicy();
180 if (orientation == Qt::Vertical)
181 policy.setHorizontalPolicy(QSizePolicy::Ignored);
182 else
183 policy.setVerticalPolicy(QSizePolicy::Ignored);
184 widget->setSizePolicy(policy);
185 widget->setParent(this);
186
187 const int insertIndex = (position & LogicalLeft) ? 0 : scrollBarLayoutIndex() + 1;
188 layout->insertWidget(insertIndex, widget);
189}
190
191/*! \internal
192 Retuns a list of scroll bar widgets for the given position. The scroll bar
193 itself is not returned.
194*/
195QWidgetList QAbstractScrollAreaScrollBarContainer::widgets(LogicalPosition position)
196{
197 QWidgetList list;
198 const int scrollBarIndex = scrollBarLayoutIndex();
199 if (position == LogicalLeft) {
200 for (int i = 0; i < scrollBarIndex; ++i)
201 list.append(layout->itemAt(i)->widget());
202 } else if (position == LogicalRight) {
203 const int layoutItemCount = layout->count();
204 for (int i = scrollBarIndex + 1; i < layoutItemCount; ++i)
205 list.append(layout->itemAt(i)->widget());
206 }
207 return list;
208}
209
210/*! \internal
211 Returns the layout index for the scroll bar. This needs to be
212 recalculated by a linear search for each use, since items in
213 the layout can be removed at any time (i.e. when a widget is
214 deleted or re-parented).
215*/
216int QAbstractScrollAreaScrollBarContainer::scrollBarLayoutIndex() const
217{
218 const int layoutItemCount = layout->count();
219 for (int i = 0; i < layoutItemCount; ++i) {
220 if (qobject_cast<QScrollBar *>(layout->itemAt(i)->widget()))
221 return i;
222 }
223 return -1;
224}
225
226/*! \internal
227*/
228void QAbstractScrollAreaPrivate::replaceScrollBar(QScrollBar *scrollBar,
229 Qt::Orientation orientation)
230{
231 Q_Q(QAbstractScrollArea);
232
233 QAbstractScrollAreaScrollBarContainer *container = scrollBarContainers[orientation];
234 bool horizontal = (orientation == Qt::Horizontal);
235 QScrollBar *oldBar = horizontal ? hbar : vbar;
236 if (horizontal)
237 hbar = scrollBar;
238 else
239 vbar = scrollBar;
240 scrollBar->setParent(container);
241 container->scrollBar = scrollBar;
242 container->layout->removeWidget(oldBar);
243 container->layout->insertWidget(0, scrollBar);
244 scrollBar->setVisible(oldBar->isVisibleTo(container));
245 scrollBar->setInvertedAppearance(oldBar->invertedAppearance());
246 scrollBar->setInvertedControls(oldBar->invertedControls());
247 scrollBar->setRange(oldBar->minimum(), oldBar->maximum());
248 scrollBar->setOrientation(oldBar->orientation());
249 scrollBar->setPageStep(oldBar->pageStep());
250 scrollBar->setSingleStep(oldBar->singleStep());
251 scrollBar->setSliderDown(oldBar->isSliderDown());
252 scrollBar->setSliderPosition(oldBar->sliderPosition());
253 scrollBar->setTracking(oldBar->hasTracking());
254 scrollBar->setValue(oldBar->value());
255 delete oldBar;
256
257 QObject::connect(scrollBar, SIGNAL(valueChanged(int)),
258 q, horizontal ? SLOT(_q_hslide(int)) : SLOT(_q_vslide(int)));
259 QObject::connect(scrollBar, SIGNAL(rangeChanged(int,int)),
260 q, SLOT(_q_showOrHideScrollBars()), Qt::QueuedConnection);
261}
262
263void QAbstractScrollAreaPrivate::init()
264{
265 Q_Q(QAbstractScrollArea);
266 viewport = new QWidget(q);
267 viewport->setObjectName(QLatin1String("qt_scrollarea_viewport"));
268 viewport->setBackgroundRole(QPalette::Base);
269 viewport->setAutoFillBackground(true);
270 scrollBarContainers[Qt::Horizontal] = new QAbstractScrollAreaScrollBarContainer(Qt::Horizontal, q);
271 scrollBarContainers[Qt::Horizontal]->setObjectName(QLatin1String("qt_scrollarea_hcontainer"));
272 hbar = scrollBarContainers[Qt::Horizontal]->scrollBar;
273 hbar->setRange(0,0);
274 scrollBarContainers[Qt::Horizontal]->setVisible(false);
275 QObject::connect(hbar, SIGNAL(valueChanged(int)), q, SLOT(_q_hslide(int)));
276 QObject::connect(hbar, SIGNAL(rangeChanged(int,int)), q, SLOT(_q_showOrHideScrollBars()), Qt::QueuedConnection);
277 scrollBarContainers[Qt::Vertical] = new QAbstractScrollAreaScrollBarContainer(Qt::Vertical, q);
278 scrollBarContainers[Qt::Vertical]->setObjectName(QLatin1String("qt_scrollarea_vcontainer"));
279 vbar = scrollBarContainers[Qt::Vertical]->scrollBar;
280 vbar->setRange(0,0);
281 scrollBarContainers[Qt::Vertical]->setVisible(false);
282 QObject::connect(vbar, SIGNAL(valueChanged(int)), q, SLOT(_q_vslide(int)));
283 QObject::connect(vbar, SIGNAL(rangeChanged(int,int)), q, SLOT(_q_showOrHideScrollBars()), Qt::QueuedConnection);
284 viewportFilter = new QAbstractScrollAreaFilter(this);
285 viewport->installEventFilter(viewportFilter);
286 viewport->setFocusProxy(q);
287 q->setFocusPolicy(Qt::WheelFocus);
288 q->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
289 q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
290 layoutChildren();
291}
292
293void QAbstractScrollAreaPrivate::layoutChildren()
294{
295 Q_Q(QAbstractScrollArea);
296 bool needh = (hbarpolicy == Qt::ScrollBarAlwaysOn
297 || (hbarpolicy == Qt::ScrollBarAsNeeded && hbar->minimum() < hbar->maximum()));
298
299 bool needv = (vbarpolicy == Qt::ScrollBarAlwaysOn
300 || (vbarpolicy == Qt::ScrollBarAsNeeded && vbar->minimum() < vbar->maximum()));
301
302#ifdef Q_WS_MAC
303 QWidget * const window = q->window();
304
305 // Use small scroll bars for tool windows, to match the native size grip.
306 bool hbarIsSmall = hbar->testAttribute(Qt::WA_MacSmallSize);
307 bool vbarIsSmall = vbar->testAttribute(Qt::WA_MacSmallSize);
308 const Qt::WindowType windowType = window->windowType();
309 if (windowType == Qt::Tool) {
310 if (!hbarIsSmall) {
311 hbar->setAttribute(Qt::WA_MacMiniSize, false);
312 hbar->setAttribute(Qt::WA_MacNormalSize, false);
313 hbar->setAttribute(Qt::WA_MacSmallSize, true);
314 }
315 if (!vbarIsSmall) {
316 vbar->setAttribute(Qt::WA_MacMiniSize, false);
317 vbar->setAttribute(Qt::WA_MacNormalSize, false);
318 vbar->setAttribute(Qt::WA_MacSmallSize, true);
319 }
320 } else {
321 if (hbarIsSmall) {
322 hbar->setAttribute(Qt::WA_MacMiniSize, false);
323 hbar->setAttribute(Qt::WA_MacNormalSize, false);
324 hbar->setAttribute(Qt::WA_MacSmallSize, false);
325 }
326 if (vbarIsSmall) {
327 vbar->setAttribute(Qt::WA_MacMiniSize, false);
328 vbar->setAttribute(Qt::WA_MacNormalSize, false);
329 vbar->setAttribute(Qt::WA_MacSmallSize, false);
330 }
331 }
332#endif
333
334 const int hsbExt = hbar->sizeHint().height();
335 const int vsbExt = vbar->sizeHint().width();
336 const QPoint extPoint(vsbExt, hsbExt);
337 const QSize extSize(vsbExt, hsbExt);
338
339 const QRect widgetRect = q->rect();
340 QStyleOption opt(0);
341 opt.init(q);
342
343 const bool hasCornerWidget = (cornerWidget != 0);
344
345// If the scroll bars are at the very right and bottom of the window we
346// move their positions to be aligned with the size grip.
347#ifdef Q_WS_MAC
348 // Check if a native sizegrip is present.
349 bool hasMacReverseSizeGrip = false;
350 bool hasMacSizeGrip = false;
351 bool nativeGripPresent = false;
352 if (q->testAttribute(Qt::WA_WState_Created))
353 nativeGripPresent = qt_mac_checkForNativeSizeGrip(q);
354
355 if (nativeGripPresent) {
356 // Look for a native size grip at the visual window bottom right and at the
357 // absolute window bottom right. In reverse mode, the native size grip does not
358 // swich side, so we need to check if it is on the "wrong side".
359 const QPoint scrollAreaBottomRight = q->mapTo(window, widgetRect.bottomRight() - QPoint(frameWidth, frameWidth));
360 const QPoint windowBottomRight = window->rect().bottomRight();
361 const QPoint visualWindowBottomRight = QStyle::visualPos(opt.direction, opt.rect, windowBottomRight);
362 const QPoint offset = windowBottomRight - scrollAreaBottomRight;
363 const QPoint visualOffset = visualWindowBottomRight - scrollAreaBottomRight;
364 hasMacSizeGrip = (visualOffset.manhattanLength() < vsbExt);
365 hasMacReverseSizeGrip = (hasMacSizeGrip == false && (offset.manhattanLength() < hsbExt));
366 }
367#endif
368
369 QPoint cornerOffset(needv ? vsbExt : 0, needh ? hsbExt : 0);
370 QRect controlsRect;
371 QRect viewportRect;
372
373 // In FrameOnlyAroundContents mode the frame is drawn between the controls and
374 // the viewport, else the frame rect is equal to the widget rect.
375 if ((frameStyle != QFrame::NoFrame) &&
376 q->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, &opt, q)) {
377 controlsRect = widgetRect;
378 const int extra = q->style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarSpacing);
379 const QPoint cornerExtra(needv ? extra : 0, needh ? extra : 0);
380 QRect frameRect = widgetRect;
381 frameRect.adjust(0, 0, -cornerOffset.x() - cornerExtra.x(), -cornerOffset.y() - cornerExtra.y());
382 q->setFrameRect(QStyle::visualRect(opt.direction, opt.rect, frameRect));
383 // The frame rect needs to be in logical coords, however we need to flip
384 // the contentsRect back before passing it on to the viewportRect
385 // since the viewportRect has its logical coords calculated later.
386 viewportRect = QStyle::visualRect(opt.direction, opt.rect, q->contentsRect());
387 } else {
388 q->setFrameRect(QStyle::visualRect(opt.direction, opt.rect, widgetRect));
389 controlsRect = q->contentsRect();
390 viewportRect = QRect(controlsRect.topLeft(), controlsRect.bottomRight() - cornerOffset);
391 }
392
393 // If we have a corner widget and are only showing one scroll bar, we need to move it
394 // to make room for the corner widget.
395 if (hasCornerWidget && (needv || needh))
396 cornerOffset = extPoint;
397
398#ifdef Q_WS_MAC
399 // Also move the scroll bars if they are covered by the native Mac size grip.
400 if (hasMacSizeGrip)
401 cornerOffset = extPoint;
402#endif
403
404 // The corner point is where the scroll bar rects, the corner widget rect and the
405 // viewport rect meets.
406 const QPoint cornerPoint(controlsRect.bottomRight() + QPoint(1, 1) - cornerOffset);
407
408 // Some styles paints the corner if both scorllbars are showing and there is
409 // no corner widget. Also, on the Mac we paint if there is a native
410 // (transparent) sizegrip in the area where a corner widget would be.
411 if ((needv && needh && hasCornerWidget == false)
412 || ((needv || needh)
413#ifdef Q_WS_MAC
414 && hasMacSizeGrip
415#endif
416 )
417 ) {
418 cornerPaintingRect = QStyle::visualRect(opt.direction, opt.rect, QRect(cornerPoint, extSize));
419 } else {
420 cornerPaintingRect = QRect();
421 }
422
423#ifdef Q_WS_MAC
424 if (hasMacReverseSizeGrip)
425 reverseCornerPaintingRect = QRect(controlsRect.bottomRight() + QPoint(1, 1) - extPoint, extSize);
426 else
427 reverseCornerPaintingRect = QRect();
428#endif
429
430 if (needh) {
431 QRect horizontalScrollBarRect(QPoint(controlsRect.left(), cornerPoint.y()), QPoint(cornerPoint.x() - 1, controlsRect.bottom()));
432#ifdef Q_WS_MAC
433 if (hasMacReverseSizeGrip)
434 horizontalScrollBarRect.adjust(vsbExt, 0, 0, 0);
435#endif
436 scrollBarContainers[Qt::Horizontal]->setGeometry(QStyle::visualRect(opt.direction, opt.rect, horizontalScrollBarRect));
437 scrollBarContainers[Qt::Horizontal]->raise();
438 }
439
440 if (needv) {
441 const QRect verticalScrollBarRect (QPoint(cornerPoint.x(), controlsRect.top()), QPoint(controlsRect.right(), cornerPoint.y() - 1));
442 scrollBarContainers[Qt::Vertical]->setGeometry(QStyle::visualRect(opt.direction, opt.rect, verticalScrollBarRect));
443 scrollBarContainers[Qt::Vertical]->raise();
444 }
445
446 if (cornerWidget) {
447 const QRect cornerWidgetRect(cornerPoint, controlsRect.bottomRight());
448 cornerWidget->setGeometry(QStyle::visualRect(opt.direction, opt.rect, cornerWidgetRect));
449 }
450
451 scrollBarContainers[Qt::Horizontal]->setVisible(needh);
452 scrollBarContainers[Qt::Vertical]->setVisible(needv);
453
454 if (q->isRightToLeft())
455 viewportRect.adjust(right, top, -left, -bottom);
456 else
457 viewportRect.adjust(left, top, -right, -bottom);
458
459 viewport->setGeometry(QStyle::visualRect(opt.direction, opt.rect, viewportRect)); // resize the viewport last
460}
461
462// ### Fix for 4.4, talk to Bjoern E or Girish.
463void QAbstractScrollAreaPrivate::scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy) {}
464
465/*!
466 \internal
467
468 Creates a new QAbstractScrollAreaPrivate, \a dd with the given \a parent.
469*/
470QAbstractScrollArea::QAbstractScrollArea(QAbstractScrollAreaPrivate &dd, QWidget *parent)
471 :QFrame(dd, parent)
472{
473 Q_D(QAbstractScrollArea);
474 d->init();
475}
476
477/*!
478 Constructs a viewport.
479
480 The \a parent arguments is sent to the QWidget constructor.
481*/
482QAbstractScrollArea::QAbstractScrollArea(QWidget *parent)
483 :QFrame(*new QAbstractScrollAreaPrivate, parent)
484{
485 Q_D(QAbstractScrollArea);
486 d->init();
487}
488
489
490/*!
491 Destroys the viewport.
492 */
493QAbstractScrollArea::~QAbstractScrollArea()
494{
495 Q_D(QAbstractScrollArea);
496 delete d->viewportFilter;
497}
498
499
500/*!
501 \since 4.2
502 Sets the viewport to be the given \a widget.
503 The QAbstractScrollArea will take ownership of the given \a widget.
504
505 If \a widget is 0, QAbstractScrollArea will assign a new QWidget instance
506 for the viewport.
507
508 \sa viewport()
509*/
510void QAbstractScrollArea::setViewport(QWidget *widget)
511{
512 Q_D(QAbstractScrollArea);
513 if (widget != d->viewport) {
514 QWidget *oldViewport = d->viewport;
515 if (!widget)
516 widget = new QWidget;
517 d->viewport = widget;
518 d->viewport->setParent(this);
519 d->viewport->setFocusProxy(this);
520 d->viewport->installEventFilter(d->viewportFilter);
521 d->layoutChildren();
522 if (isVisible())
523 d->viewport->show();
524 QMetaObject::invokeMethod(this, "setupViewport", Q_ARG(QWidget *, widget));
525 delete oldViewport;
526 }
527}
528
529/*!
530 Returns the viewport widget.
531
532 Use the QScrollArea::widget() function to retrieve the contents of
533 the viewport widget.
534
535 \sa QScrollArea::widget()
536*/
537QWidget *QAbstractScrollArea::viewport() const
538{
539 Q_D(const QAbstractScrollArea);
540 return d->viewport;
541}
542
543
544/*!
545Returns the size of the viewport as if the scroll bars had no valid
546scrolling range.
547*/
548// ### still thinking about the name
549QSize QAbstractScrollArea::maximumViewportSize() const
550{
551 Q_D(const QAbstractScrollArea);
552 int hsbExt = d->hbar->sizeHint().height();
553 int vsbExt = d->vbar->sizeHint().width();
554
555 int f = 2 * d->frameWidth;
556 QSize max = size() - QSize(f + d->left + d->right, f + d->top + d->bottom);
557 if (d->vbarpolicy == Qt::ScrollBarAlwaysOn)
558 max.rwidth() -= vsbExt;
559 if (d->hbarpolicy == Qt::ScrollBarAlwaysOn)
560 max.rheight() -= hsbExt;
561 return max;
562}
563
564/*!
565 \property QAbstractScrollArea::verticalScrollBarPolicy
566 \brief the policy for the vertical scroll bar
567
568 The default policy is Qt::ScrollBarAsNeeded.
569
570 \sa horizontalScrollBarPolicy
571*/
572
573Qt::ScrollBarPolicy QAbstractScrollArea::verticalScrollBarPolicy() const
574{
575 Q_D(const QAbstractScrollArea);
576 return d->vbarpolicy;
577}
578
579void QAbstractScrollArea::setVerticalScrollBarPolicy(Qt::ScrollBarPolicy policy)
580{
581 Q_D(QAbstractScrollArea);
582 const Qt::ScrollBarPolicy oldPolicy = d->vbarpolicy;
583 d->vbarpolicy = policy;
584 if (isVisible())
585 d->layoutChildren();
586 if (oldPolicy != d->vbarpolicy)
587 d->scrollBarPolicyChanged(Qt::Vertical, d->vbarpolicy);
588}
589
590
591/*!
592 Returns the vertical scroll bar.
593
594 \sa verticalScrollBarPolicy, horizontalScrollBar()
595 */
596QScrollBar *QAbstractScrollArea::verticalScrollBar() const
597{
598 Q_D(const QAbstractScrollArea);
599 return d->vbar;
600}
601
602/*!
603 \since 4.2
604 Replaces the existing vertical scroll bar with \a scrollBar, and sets all
605 the former scroll bar's slider properties on the new scroll bar. The former
606 scroll bar is then deleted.
607
608 QAbstractScrollArea already provides vertical and horizontal scroll bars by
609 default. You can call this function to replace the default vertical
610 scroll bar with your own custom scroll bar.
611
612 \sa verticalScrollBar(), setHorizontalScrollBar()
613*/
614void QAbstractScrollArea::setVerticalScrollBar(QScrollBar *scrollBar)
615{
616 Q_D(QAbstractScrollArea);
617 if (!scrollBar) {
618 qWarning("QAbstractScrollArea::setVerticalScrollBar: Cannot set a null scroll bar");
619 return;
620 }
621
622 d->replaceScrollBar(scrollBar, Qt::Vertical);
623}
624
625/*!
626 \property QAbstractScrollArea::horizontalScrollBarPolicy
627 \brief the policy for the horizontal scroll bar
628
629 The default policy is Qt::ScrollBarAsNeeded.
630
631 \sa verticalScrollBarPolicy
632*/
633
634Qt::ScrollBarPolicy QAbstractScrollArea::horizontalScrollBarPolicy() const
635{
636 Q_D(const QAbstractScrollArea);
637 return d->hbarpolicy;
638}
639
640void QAbstractScrollArea::setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy policy)
641{
642 Q_D(QAbstractScrollArea);
643 const Qt::ScrollBarPolicy oldPolicy = d->hbarpolicy;
644 d->hbarpolicy = policy;
645 if (isVisible())
646 d->layoutChildren();
647 if (oldPolicy != d->hbarpolicy)
648 d->scrollBarPolicyChanged(Qt::Horizontal, d->hbarpolicy);
649}
650
651/*!
652 Returns the horizontal scroll bar.
653
654 \sa horizontalScrollBarPolicy, verticalScrollBar()
655 */
656QScrollBar *QAbstractScrollArea::horizontalScrollBar() const
657{
658 Q_D(const QAbstractScrollArea);
659 return d->hbar;
660}
661
662/*!
663 \since 4.2
664
665 Replaces the existing horizontal scroll bar with \a scrollBar, and sets all
666 the former scroll bar's slider properties on the new scroll bar. The former
667 scroll bar is then deleted.
668
669 QAbstractScrollArea already provides horizontal and vertical scroll bars by
670 default. You can call this function to replace the default horizontal
671 scroll bar with your own custom scroll bar.
672
673 \sa horizontalScrollBar(), setVerticalScrollBar()
674*/
675void QAbstractScrollArea::setHorizontalScrollBar(QScrollBar *scrollBar)
676{
677 Q_D(QAbstractScrollArea);
678 if (!scrollBar) {
679 qWarning("QAbstractScrollArea::setHorizontalScrollBar: Cannot set a null scroll bar");
680 return;
681 }
682
683 d->replaceScrollBar(scrollBar, Qt::Horizontal);
684}
685
686/*!
687 \since 4.2
688
689 Returns the widget in the corner between the two scroll bars.
690
691 By default, no corner widget is present.
692*/
693QWidget *QAbstractScrollArea::cornerWidget() const
694{
695 Q_D(const QAbstractScrollArea);
696 return d->cornerWidget;
697}
698
699/*!
700 \since 4.2
701
702 Sets the widget in the corner between the two scroll bars to be
703 \a widget.
704
705 You will probably also want to set at least one of the scroll bar
706 modes to \c AlwaysOn.
707
708 Passing 0 shows no widget in the corner.
709
710 Any previous corner widget is hidden.
711
712 You may call setCornerWidget() with the same widget at different
713 times.
714
715 All widgets set here will be deleted by the scroll area when it is
716 destroyed unless you separately reparent the widget after setting
717 some other corner widget (or 0).
718
719 Any \e newly set widget should have no current parent.
720
721 By default, no corner widget is present.
722
723 \sa horizontalScrollBarPolicy, horizontalScrollBarPolicy
724*/
725void QAbstractScrollArea::setCornerWidget(QWidget *widget)
726{
727 Q_D(QAbstractScrollArea);
728 QWidget* oldWidget = d->cornerWidget;
729 if (oldWidget != widget) {
730 if (oldWidget)
731 oldWidget->hide();
732 d->cornerWidget = widget;
733
734 if (widget && widget->parentWidget() != this)
735 widget->setParent(this);
736
737 d->layoutChildren();
738 if (widget)
739 widget->show();
740 } else {
741 d->cornerWidget = widget;
742 d->layoutChildren();
743 }
744}
745
746/*!
747 \since 4.2
748 Adds \a widget as a scroll bar widget in the location specified
749 by \a alignment.
750
751 Scroll bar widgets are shown next to the horizontal or vertical
752 scroll bar, and can be placed on either side of it. If you want
753 the scroll bar widgets to be always visible, set the
754 scrollBarPolicy for the corresponding scroll bar to \c AlwaysOn.
755
756 \a alignment must be one of Qt::Alignleft and Qt::AlignRight,
757 which maps to the horizontal scroll bar, or Qt::AlignTop and
758 Qt::AlignBottom, which maps to the vertical scroll bar.
759
760 A scroll bar widget can be removed by either re-parenting the
761 widget or deleting it. It's also possible to hide a widget with
762 QWidget::hide()
763
764 The scroll bar widget will be resized to fit the scroll bar
765 geometry for the current style. The following describes the case
766 for scroll bar widgets on the horizontal scroll bar:
767
768 The height of the widget will be set to match the height of the
769 scroll bar. To control the width of the widget, use
770 QWidget::setMinimumWidth and QWidget::setMaximumWidth, or
771 implement QWidget::sizeHint() and set a horizontal size policy.
772 If you want a square widget, call
773 QStyle::pixelMetric(QStyle::PM_ScrollBarExtent) and set the
774 width to this value.
775
776 \sa scrollBarWidgets()
777*/
778void QAbstractScrollArea::addScrollBarWidget(QWidget *widget, Qt::Alignment alignment)
779{
780 Q_D(QAbstractScrollArea);
781
782 if (widget == 0)
783 return;
784
785 const Qt::Orientation scrollBarOrientation
786 = ((alignment & Qt::AlignLeft) || (alignment & Qt::AlignRight)) ? Qt::Horizontal : Qt::Vertical;
787 const QAbstractScrollAreaScrollBarContainer::LogicalPosition position
788 = ((alignment & Qt::AlignRight) || (alignment & Qt::AlignBottom))
789 ? QAbstractScrollAreaScrollBarContainer::LogicalRight : QAbstractScrollAreaScrollBarContainer::LogicalLeft;
790 d->scrollBarContainers[scrollBarOrientation]->addWidget(widget, position);
791 d->layoutChildren();
792 if (isHidden() == false)
793 widget->show();
794}
795
796/*!
797 \since 4.2
798 Returns a list of the currently set scroll bar widgets. \a alignment
799 can be any combination of the four location flags.
800
801 \sa addScrollBarWidget()
802*/
803QWidgetList QAbstractScrollArea::scrollBarWidgets(Qt::Alignment alignment)
804{
805 Q_D(QAbstractScrollArea);
806
807 QWidgetList list;
808
809 if (alignment & Qt::AlignLeft)
810 list += d->scrollBarContainers[Qt::Horizontal]->widgets(QAbstractScrollAreaScrollBarContainer::LogicalLeft);
811 if (alignment & Qt::AlignRight)
812 list += d->scrollBarContainers[Qt::Horizontal]->widgets(QAbstractScrollAreaScrollBarContainer::LogicalRight);
813 if (alignment & Qt::AlignTop)
814 list += d->scrollBarContainers[Qt::Vertical]->widgets(QAbstractScrollAreaScrollBarContainer::LogicalLeft);
815 if (alignment & Qt::AlignBottom)
816 list += d->scrollBarContainers[Qt::Vertical]->widgets(QAbstractScrollAreaScrollBarContainer::LogicalRight);
817
818 return list;
819}
820
821/*!
822 Sets the margins around the scrolling area to \a left, \a top, \a
823 right and \a bottom. This is useful for applications such as
824 spreadsheets with "locked" rows and columns. The marginal space is
825 is left blank; put widgets in the unused area.
826
827 Note that this function is frequently called by QTreeView and
828 QTableView, so margins must be implemented by QAbstractScrollArea
829 subclasses. Also, if the subclasses are to be used in item views,
830 they should not call this function.
831
832 By default all margins are zero.
833
834*/
835void QAbstractScrollArea::setViewportMargins(int left, int top, int right, int bottom)
836{
837 Q_D(QAbstractScrollArea);
838 d->left = left;
839 d->top = top;
840 d->right = right;
841 d->bottom = bottom;
842 d->layoutChildren();
843}
844
845/*!
846 \fn bool QAbstractScrollArea::event(QEvent *event)
847
848 \reimp
849
850 This is the main event handler for the QAbstractScrollArea widget (\e not
851 the scrolling area viewport()). The specified \a event is a general event
852 object that may need to be cast to the appropriate class depending on its
853 type.
854
855 \sa QEvent::type()
856*/
857bool QAbstractScrollArea::event(QEvent *e)
858{
859 Q_D(QAbstractScrollArea);
860 switch (e->type()) {
861 case QEvent::AcceptDropsChange:
862 // There was a chance that with accessibility client we get an
863 // event before the viewport was created.
864 // Also, in some cases we might get here from QWidget::event() virtual function which is (indirectly) called
865 // from the viewport constructor at the time when the d->viewport is not yet initialized even without any
866 // accessibility client. See qabstractscrollarea autotest for a test case.
867 if (d->viewport)
868 d->viewport->setAcceptDrops(acceptDrops());
869 break;
870 case QEvent::MouseTrackingChange:
871 d->viewport->setMouseTracking(hasMouseTracking());
872 break;
873 case QEvent::Resize:
874 d->layoutChildren();
875 break;
876 case QEvent::Paint:
877 if (d->cornerPaintingRect.isValid()) {
878 QStyleOption option;
879 option.rect = d->cornerPaintingRect;
880 QPainter p(this);
881 style()->drawPrimitive(QStyle::PE_PanelScrollAreaCorner, &option, &p, this);
882 }
883#ifdef Q_WS_MAC
884 if (d->reverseCornerPaintingRect.isValid()) {
885 QStyleOption option;
886 option.rect = d->reverseCornerPaintingRect;
887 QPainter p(this);
888 style()->drawPrimitive(QStyle::PE_PanelScrollAreaCorner, &option, &p, this);
889 }
890#endif
891 QFrame::paintEvent((QPaintEvent*)e);
892 break;
893#ifndef QT_NO_CONTEXTMENU
894 case QEvent::ContextMenu:
895 if (static_cast<QContextMenuEvent *>(e)->reason() == QContextMenuEvent::Keyboard)
896 return QFrame::event(e);
897 e->ignore();
898 break;
899#endif // QT_NO_CONTEXTMENU
900 case QEvent::MouseButtonPress:
901 case QEvent::MouseButtonRelease:
902 case QEvent::MouseButtonDblClick:
903 case QEvent::MouseMove:
904 case QEvent::Wheel:
905#ifndef QT_NO_DRAGANDDROP
906 case QEvent::Drop:
907 case QEvent::DragEnter:
908 case QEvent::DragMove:
909 case QEvent::DragLeave:
910#endif
911 return false;
912 case QEvent::StyleChange:
913 case QEvent::LayoutDirectionChange:
914 case QEvent::ApplicationLayoutDirectionChange:
915 d->layoutChildren();
916 // fall through
917 default:
918 return QFrame::event(e);
919 }
920 return true;
921}
922
923/*!
924 \fn bool QAbstractScrollArea::viewportEvent(QEvent *event)
925
926 The main event handler for the scrolling area (the viewport() widget).
927 It handles the \a event specified, and can be called by subclasses to
928 provide reasonable default behavior.
929
930 Returns true to indicate to the event system that the event has been
931 handled, and needs no further processing; otherwise returns false to
932 indicate that the event should be propagated further.
933
934 You can reimplement this function in a subclass, but we recommend
935 using one of the specialized event handlers instead.
936
937 Specialised handlers for viewport events are: paintEvent(),
938 mousePressEvent(), mouseReleaseEvent(), mouseDoubleClickEvent(),
939 mouseMoveEvent(), wheelEvent(), dragEnterEvent(), dragMoveEvent(),
940 dragLeaveEvent(), dropEvent(), contextMenuEvent(), and
941 resizeEvent().
942*/
943bool QAbstractScrollArea::viewportEvent(QEvent *e)
944{
945 switch (e->type()) {
946 case QEvent::Resize:
947 case QEvent::Paint:
948 case QEvent::MouseButtonPress:
949 case QEvent::MouseButtonRelease:
950 case QEvent::MouseButtonDblClick:
951 case QEvent::MouseMove:
952 case QEvent::ContextMenu:
953#ifndef QT_NO_WHEELEVENT
954 case QEvent::Wheel:
955#endif
956#ifndef QT_NO_DRAGANDDROP
957 case QEvent::Drop:
958 case QEvent::DragEnter:
959 case QEvent::DragMove:
960 case QEvent::DragLeave:
961#endif
962 return QFrame::event(e);
963 case QEvent::LayoutRequest:
964 return event(e);
965 default:
966 break;
967 }
968 return false; // let the viewport widget handle the event
969}
970
971/*!
972 \fn void QAbstractScrollArea::resizeEvent(QResizeEvent *event)
973
974 This event handler can be reimplemented in a subclass to receive
975 resize events (passed in \a event), for the viewport() widget.
976
977 When resizeEvent() is called, the viewport already has its new
978 geometry: Its new size is accessible through the
979 QResizeEvent::size() function, and the old size through
980 QResizeEvent::oldSize().
981
982 \sa QWidget::resizeEvent()
983 */
984void QAbstractScrollArea::resizeEvent(QResizeEvent *)
985{
986}
987
988/*!
989 \fn void QAbstractScrollArea::paintEvent(QPaintEvent *event)
990
991 This event handler can be reimplemented in a subclass to receive
992 paint events (passed in \a event), for the viewport() widget.
993
994 \note If you open a painter, make sure to open it on the viewport().
995
996 \sa QWidget::paintEvent()
997*/
998void QAbstractScrollArea::paintEvent(QPaintEvent*)
999{
1000}
1001
1002/*!
1003 This event handler can be reimplemented in a subclass to receive
1004 mouse press events for the viewport() widget. The event is passed
1005 in \a e.
1006
1007 \sa QWidget::mousePressEvent()
1008*/
1009void QAbstractScrollArea::mousePressEvent(QMouseEvent *e)
1010{
1011 e->ignore();
1012}
1013
1014/*!
1015 This event handler can be reimplemented in a subclass to receive
1016 mouse release events for the viewport() widget. The event is
1017 passed in \a e.
1018
1019 \sa QWidget::mouseReleaseEvent()
1020*/
1021void QAbstractScrollArea::mouseReleaseEvent(QMouseEvent *e)
1022{
1023 e->ignore();
1024}
1025
1026/*!
1027 This event handler can be reimplemented in a subclass to receive
1028 mouse double click events for the viewport() widget. The event is
1029 passed in \a e.
1030
1031 \sa QWidget::mouseDoubleClickEvent()
1032*/
1033void QAbstractScrollArea::mouseDoubleClickEvent(QMouseEvent *e)
1034{
1035 e->ignore();
1036}
1037
1038/*!
1039 This event handler can be reimplemented in a subclass to receive
1040 mouse move events for the viewport() widget. The event is passed
1041 in \a e.
1042
1043 \sa QWidget::mouseMoveEvent()
1044*/
1045void QAbstractScrollArea::mouseMoveEvent(QMouseEvent *e)
1046{
1047 e->ignore();
1048}
1049
1050/*!
1051 This event handler can be reimplemented in a subclass to receive
1052 wheel events for the viewport() widget. The event is passed in \a
1053 e.
1054
1055 \sa QWidget::wheelEvent()
1056*/
1057#ifndef QT_NO_WHEELEVENT
1058void QAbstractScrollArea::wheelEvent(QWheelEvent *e)
1059{
1060 Q_D(QAbstractScrollArea);
1061 if (static_cast<QWheelEvent*>(e)->orientation() == Qt::Horizontal)
1062 QApplication::sendEvent(d->hbar, e);
1063 else
1064 QApplication::sendEvent(d->vbar, e);
1065}
1066#endif
1067
1068#ifndef QT_NO_CONTEXTMENU
1069/*!
1070 This event handler can be reimplemented in a subclass to receive
1071 context menu events for the viewport() widget. The event is passed
1072 in \a e.
1073
1074 \sa QWidget::contextMenuEvent()
1075*/
1076void QAbstractScrollArea::contextMenuEvent(QContextMenuEvent *e)
1077{
1078 e->ignore();
1079}
1080#endif // QT_NO_CONTEXTMENU
1081
1082/*!
1083 This function is called with key event \a e when key presses
1084 occur. It handles PageUp, PageDown, Up, Down, Left, and Right, and
1085 ignores all other key presses.
1086*/
1087void QAbstractScrollArea::keyPressEvent(QKeyEvent * e)
1088{
1089 Q_D(QAbstractScrollArea);
1090 if (false){
1091#ifndef QT_NO_SHORTCUT
1092 } else if (e == QKeySequence::MoveToPreviousPage) {
1093 d->vbar->triggerAction(QScrollBar::SliderPageStepSub);
1094 } else if (e == QKeySequence::MoveToNextPage) {
1095 d->vbar->triggerAction(QScrollBar::SliderPageStepAdd);
1096#endif
1097 } else {
1098#ifdef QT_KEYPAD_NAVIGATION
1099 if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) {
1100 e->ignore();
1101 return;
1102 }
1103#endif
1104 switch (e->key()) {
1105 case Qt::Key_Up:
1106 d->vbar->triggerAction(QScrollBar::SliderSingleStepSub);
1107 break;
1108 case Qt::Key_Down:
1109 d->vbar->triggerAction(QScrollBar::SliderSingleStepAdd);
1110 break;
1111 case Qt::Key_Left:
1112#ifdef QT_KEYPAD_NAVIGATION
1113 if (QApplication::keypadNavigationEnabled() && hasEditFocus()
1114 && (!d->hbar->isVisible() || d->hbar->value() == d->hbar->minimum())) {
1115 //if we aren't using the hbar or we are already at the leftmost point ignore
1116 e->ignore();
1117 return;
1118 }
1119#endif
1120 d->hbar->triggerAction(
1121 layoutDirection() == Qt::LeftToRight
1122 ? QScrollBar::SliderSingleStepSub : QScrollBar::SliderSingleStepAdd);
1123 break;
1124 case Qt::Key_Right:
1125#ifdef QT_KEYPAD_NAVIGATION
1126 if (QApplication::keypadNavigationEnabled() && hasEditFocus()
1127 && (!d->hbar->isVisible() || d->hbar->value() == d->hbar->maximum())) {
1128 //if we aren't using the hbar or we are already at the rightmost point ignore
1129 e->ignore();
1130 return;
1131 }
1132#endif
1133 d->hbar->triggerAction(
1134 layoutDirection() == Qt::LeftToRight
1135 ? QScrollBar::SliderSingleStepAdd : QScrollBar::SliderSingleStepSub);
1136 break;
1137 default:
1138 e->ignore();
1139 return;
1140 }
1141 }
1142 e->accept();
1143}
1144
1145
1146#ifndef QT_NO_DRAGANDDROP
1147/*!
1148 \fn void QAbstractScrollArea::dragEnterEvent(QDragEnterEvent *event)
1149
1150 This event handler can be reimplemented in a subclass to receive
1151 drag enter events (passed in \a event), for the viewport() widget.
1152
1153 \sa QWidget::dragEnterEvent()
1154*/
1155void QAbstractScrollArea::dragEnterEvent(QDragEnterEvent *)
1156{
1157}
1158
1159/*!
1160 \fn void QAbstractScrollArea::dragMoveEvent(QDragMoveEvent *event)
1161
1162 This event handler can be reimplemented in a subclass to receive
1163 drag move events (passed in \a event), for the viewport() widget.
1164
1165 \sa QWidget::dragMoveEvent()
1166*/
1167void QAbstractScrollArea::dragMoveEvent(QDragMoveEvent *)
1168{
1169}
1170
1171/*!
1172 \fn void QAbstractScrollArea::dragLeaveEvent(QDragLeaveEvent *event)
1173
1174 This event handler can be reimplemented in a subclass to receive
1175 drag leave events (passed in \a event), for the viewport() widget.
1176
1177 \sa QWidget::dragLeaveEvent()
1178*/
1179void QAbstractScrollArea::dragLeaveEvent(QDragLeaveEvent *)
1180{
1181}
1182
1183/*!
1184 \fn void QAbstractScrollArea::dropEvent(QDropEvent *event)
1185
1186 This event handler can be reimplemented in a subclass to receive
1187 drop events (passed in \a event), for the viewport() widget.
1188
1189 \sa QWidget::dropEvent()
1190*/
1191void QAbstractScrollArea::dropEvent(QDropEvent *)
1192{
1193}
1194
1195
1196#endif
1197
1198/*!
1199 This virtual handler is called when the scroll bars are moved by
1200 \a dx, \a dy, and consequently the viewport's contents should be
1201 scrolled accordingly.
1202
1203 The default implementation simply calls update() on the entire
1204 viewport(), subclasses can reimplement this handler for
1205 optimization purposes, or - like QScrollArea - to move a contents
1206 widget. The parameters \a dx and \a dy are there for convenience,
1207 so that the class knows how much should be scrolled (useful
1208 e.g. when doing pixel-shifts). You may just as well ignore these
1209 values and scroll directly to the position the scroll bars
1210 indicate.
1211
1212 Calling this function in order to scroll programmatically is an
1213 error, use the scroll bars instead (e.g. by calling
1214 QScrollBar::setValue() directly).
1215*/
1216void QAbstractScrollArea::scrollContentsBy(int, int)
1217{
1218 viewport()->update();
1219}
1220
1221void QAbstractScrollAreaPrivate::_q_hslide(int x)
1222{
1223 Q_Q(QAbstractScrollArea);
1224 int dx = xoffset - x;
1225 xoffset = x;
1226 q->scrollContentsBy(dx, 0);
1227}
1228
1229void QAbstractScrollAreaPrivate::_q_vslide(int y)
1230{
1231 Q_Q(QAbstractScrollArea);
1232 int dy = yoffset - y;
1233 yoffset = y;
1234 q->scrollContentsBy(0, dy);
1235}
1236
1237void QAbstractScrollAreaPrivate::_q_showOrHideScrollBars()
1238{
1239 layoutChildren();
1240}
1241
1242QPoint QAbstractScrollAreaPrivate::contentsOffset() const
1243{
1244 Q_Q(const QAbstractScrollArea);
1245 QPoint offset;
1246 if (vbar->isVisible())
1247 offset.setY(vbar->value());
1248 if (hbar->isVisible()) {
1249 if (q->isRightToLeft())
1250 offset.setX(hbar->maximum() - hbar->value());
1251 else
1252 offset.setX(hbar->value());
1253 }
1254 return offset;
1255}
1256
1257/*!
1258 \reimp
1259
1260*/
1261QSize QAbstractScrollArea::minimumSizeHint() const
1262{
1263 Q_D(const QAbstractScrollArea);
1264 int hsbExt = d->hbar->sizeHint().height();
1265 int vsbExt = d->vbar->sizeHint().width();
1266 int extra = 2 * d->frameWidth;
1267 return QSize(d->scrollBarContainers[Qt::Horizontal]->sizeHint().width() + vsbExt + extra,
1268 d->scrollBarContainers[Qt::Vertical]->sizeHint().height() + hsbExt + extra);
1269}
1270
1271/*!
1272 \reimp
1273*/
1274QSize QAbstractScrollArea::sizeHint() const
1275{
1276 return QSize(256, 192);
1277#if 0
1278 Q_D(const QAbstractScrollArea);
1279 int h = qMax(10, fontMetrics().height());
1280 int f = 2 * d->frameWidth;
1281 return QSize((6 * h) + f, (4 * h) + f);
1282#endif
1283}
1284
1285/*!
1286 This slot is called by QAbstractScrollArea after setViewport(\a
1287 viewport) has been called. Reimplement this function in a
1288 subclass of QAbstractScrollArea to initialize the new \a viewport
1289 before it is used.
1290
1291 \sa setViewport()
1292*/
1293void QAbstractScrollArea::setupViewport(QWidget *viewport)
1294{
1295 Q_UNUSED(viewport);
1296}
1297
1298QT_END_NAMESPACE
1299
1300#include "moc_qabstractscrollarea.cpp"
1301#include "moc_qabstractscrollarea_p.cpp"
1302
1303#endif // QT_NO_SCROLLAREA
Note: See TracBrowser for help on using the repository browser.