src/gui/widgets/qabstractscrollarea.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.
00004 **
00005 ** This file is part of the QtGui module of the Qt Toolkit.
00006 **
00007 ** This file may be used under the terms of the GNU General Public
00008 ** License version 2.0 as published by the Free Software Foundation
00009 ** and appearing in the file LICENSE.GPL included in the packaging of
00010 ** this file.  Please review the following information to ensure GNU
00011 ** General Public Licensing requirements will be met:
00012 ** http://www.trolltech.com/products/qt/opensource.html
00013 **
00014 ** If you are unsure which license is appropriate for your use, please
00015 ** review the following information:
00016 ** http://www.trolltech.com/products/qt/licensing.html or contact the
00017 ** sales department at sales@trolltech.com.
00018 **
00019 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00020 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00021 **
00022 ****************************************************************************/
00023 
00024 #include "qabstractscrollarea.h"
00025 
00026 #ifndef QT_NO_SCROLLAREA
00027 
00028 #include "qscrollbar.h"
00029 #include "qapplication.h"
00030 #include "qstyle.h"
00031 #include "qstyleoption.h"
00032 #include "qevent.h"
00033 #include "qdebug.h"
00034 #include "qboxlayout.h"
00035 #include "qpainter.h"
00036 
00037 #include "qabstractscrollarea_p.h"
00038 #include <qwidget.h>
00039 
00040 #ifdef Q_WS_MAC
00041 #include <qmacstyle_mac.h>
00042 #include <private/qt_mac_p.h>
00043 #endif
00044 
00095 QAbstractScrollAreaPrivate::QAbstractScrollAreaPrivate()
00096     :hbar(0), vbar(0), vbarpolicy(Qt::ScrollBarAsNeeded), hbarpolicy(Qt::ScrollBarAsNeeded),
00097      viewport(0), cornerWidget(0), left(0), top(0), right(0), bottom(0),
00098      xoffset(0), yoffset(0), viewportFilter(0)
00099 {
00100 }
00101 
00102 QAbstractScrollAreaScrollBarContainer::QAbstractScrollAreaScrollBarContainer(Qt::Orientation orientation, QWidget *parent)
00103     :QWidget(parent), scrollBar(new QScrollBar(orientation, this)),
00104      layout(new QBoxLayout(orientation == Qt::Horizontal ? QBoxLayout::LeftToRight : QBoxLayout::TopToBottom)),
00105      orientation(orientation)
00106 {
00107     setLayout(layout);
00108     layout->setMargin(0);
00109     layout->setSpacing(0);
00110     layout->addWidget(scrollBar);
00111 }
00112 
00116 void QAbstractScrollAreaScrollBarContainer::addWidget(QWidget *widget, LogicalPosition position)
00117 {
00118     QSizePolicy policy = widget->sizePolicy();
00119     if (orientation == Qt::Vertical)
00120         policy.setHorizontalPolicy(QSizePolicy::Ignored);
00121     else
00122         policy.setVerticalPolicy(QSizePolicy::Ignored);
00123     widget->setSizePolicy(policy);
00124     widget->setParent(this);
00125 
00126     const int insertIndex = (position & LogicalLeft) ? 0 : scrollBarLayoutIndex() + 1;
00127     layout->insertWidget(insertIndex, widget);
00128 }
00129 
00134 QWidgetList QAbstractScrollAreaScrollBarContainer::widgets(LogicalPosition position)
00135 {
00136     QWidgetList list;
00137     const int scrollBarIndex = scrollBarLayoutIndex();
00138     if (position == LogicalLeft) {
00139         for (int i = 0; i < scrollBarIndex; ++i)
00140             list.append(layout->itemAt(i)->widget());
00141     } else if (position == LogicalRight) {
00142         const int layoutItemCount = layout->count();
00143         for (int i = scrollBarIndex + 1; i < layoutItemCount; ++i)
00144             list.append(layout->itemAt(i)->widget());
00145     }
00146     return list;
00147 }
00148 
00155 int QAbstractScrollAreaScrollBarContainer::scrollBarLayoutIndex() const
00156 {
00157     const int layoutItemCount = layout->count();
00158     for (int i = 0; i < layoutItemCount; ++i) {
00159         if (qobject_cast<QScrollBar *>(layout->itemAt(i)->widget()))
00160             return i;
00161     }
00162     return -1;
00163 }
00164 
00167 void QAbstractScrollAreaPrivate::replaceScrollBar(QScrollBar *scrollBar,
00168                                                   Qt::Orientation orientation)
00169 {
00170     Q_Q(QAbstractScrollArea);
00171 
00172     QAbstractScrollAreaScrollBarContainer *container = scrollBarContainers[orientation];
00173     bool horizontal = (orientation == Qt::Horizontal);
00174     QScrollBar *oldBar = horizontal ? hbar : vbar;
00175     if (horizontal)
00176         hbar = scrollBar;
00177     else
00178         vbar = scrollBar;
00179     scrollBar->setParent(container);
00180     container->scrollBar = scrollBar;
00181     container->layout->removeWidget(oldBar);
00182     container->layout->insertWidget(0, scrollBar);
00183     scrollBar->setVisible(oldBar->isVisible());
00184     scrollBar->setInvertedAppearance(oldBar->invertedAppearance());
00185     scrollBar->setInvertedControls(oldBar->invertedControls());
00186     scrollBar->setRange(oldBar->minimum(), oldBar->maximum());
00187     scrollBar->setOrientation(oldBar->orientation());
00188     scrollBar->setPageStep(oldBar->pageStep());
00189     scrollBar->setSingleStep(oldBar->singleStep());
00190     scrollBar->setSliderDown(oldBar->isSliderDown());
00191     scrollBar->setSliderPosition(oldBar->sliderPosition());
00192     scrollBar->setTracking(oldBar->hasTracking());
00193     scrollBar->setValue(oldBar->value());
00194     delete oldBar;
00195 
00196     QObject::connect(scrollBar, SIGNAL(valueChanged(int)),
00197                      q, horizontal ? SLOT(_q_hslide(int)) : SLOT(_q_vslide(int)));
00198     QObject::connect(scrollBar, SIGNAL(rangeChanged(int,int)),
00199                      q, SLOT(_q_showOrHideScrollBars()), Qt::QueuedConnection);
00200 }
00201 
00202 void QAbstractScrollAreaPrivate::init()
00203 {
00204     Q_Q(QAbstractScrollArea);
00205     scrollBarContainers[Qt::Horizontal] = new QAbstractScrollAreaScrollBarContainer(Qt::Horizontal, q);
00206     hbar = scrollBarContainers[Qt::Horizontal]->scrollBar;
00207     hbar->setRange(0,0);
00208     scrollBarContainers[Qt::Horizontal]->setVisible(false);
00209     QObject::connect(hbar, SIGNAL(valueChanged(int)), q, SLOT(_q_hslide(int)));
00210     QObject::connect(hbar, SIGNAL(rangeChanged(int,int)), q, SLOT(_q_showOrHideScrollBars()), Qt::QueuedConnection);
00211     scrollBarContainers[Qt::Vertical] = new QAbstractScrollAreaScrollBarContainer(Qt::Vertical, q);
00212     vbar = scrollBarContainers[Qt::Vertical]->scrollBar;
00213     vbar->setRange(0,0);
00214     scrollBarContainers[Qt::Vertical]->setVisible(false);
00215     QObject::connect(vbar, SIGNAL(valueChanged(int)), q, SLOT(_q_vslide(int)));
00216     QObject::connect(vbar, SIGNAL(rangeChanged(int,int)), q, SLOT(_q_showOrHideScrollBars()), Qt::QueuedConnection);
00217     viewportFilter = new QAbstractScrollAreaFilter(this);
00218     viewport = new QWidget(q);
00219     viewport->setObjectName(QLatin1String("qt_scrollarea_viewport"));
00220     viewport->setBackgroundRole(QPalette::Base);
00221     viewport->setAutoFillBackground(true);
00222     viewport->installEventFilter(viewportFilter);
00223     viewport->setFocusProxy(q);
00224     q->setFocusPolicy(Qt::WheelFocus);
00225     q->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
00226     q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
00227     layoutChildren();
00228 }
00229 
00230 void QAbstractScrollAreaPrivate::layoutChildren()
00231 {
00232     Q_Q(QAbstractScrollArea);
00233     bool needh = (hbarpolicy == Qt::ScrollBarAlwaysOn
00234                   || (hbarpolicy == Qt::ScrollBarAsNeeded && hbar->minimum() < hbar->maximum()));
00235 
00236     bool needv = (vbarpolicy == Qt::ScrollBarAlwaysOn
00237                   || (vbarpolicy == Qt::ScrollBarAsNeeded && vbar->minimum() < vbar->maximum()));
00238 
00239     const int hsbExt = hbar->sizeHint().height();
00240     const int vsbExt = vbar->sizeHint().width();
00241     const QPoint extPoint(vsbExt, hsbExt);
00242     const QSize extSize(vsbExt, hsbExt);
00243 
00244     const QRect widgetRect = q->rect();
00245     QStyleOption opt(0);
00246     opt.init(q);
00247 
00248     const bool hasCornerWidget = (cornerWidget != 0);
00249 
00250 // If the scroll bars are at the very right and bottom of the window we
00251 // move their positions to be aligned with the size grip.
00252 #ifdef Q_WS_MAC
00253     QWidget * const window = q->window();
00254     // Check if a native sizegrip is present.
00255     bool hasMacReverseSizeGrip = false;
00256     bool hasMacSizeGrip = false;
00257     HIViewRef nativeSizeGrip;
00258     HIViewFindByID(HIViewGetRoot(HIViewGetWindow(HIViewRef(q->winId()))), kHIViewWindowGrowBoxID, &nativeSizeGrip);
00259     if (nativeSizeGrip) {
00260         // Look for a native size grip at the visual window bottom right and at the
00261         // absolute window bottom right. In reverse mode, the native size grip does not
00262         // swich side, so we need to check if it is on the "wrong side".
00263         const QPoint scrollAreaBottomRight = q->mapTo(window, widgetRect.bottomRight() - QPoint(frameWidth, frameWidth));
00264         const QPoint windowBottomRight = window->rect().bottomRight();
00265         const QPoint visualWindowBottomRight = QStyle::visualPos(opt.direction, opt.rect, windowBottomRight);
00266         const QPoint offset = windowBottomRight - scrollAreaBottomRight;
00267         const QPoint visualOffset = visualWindowBottomRight - scrollAreaBottomRight;
00268         hasMacSizeGrip = (visualOffset.manhattanLength() < vsbExt);
00269         hasMacReverseSizeGrip = (hasMacSizeGrip == false && (offset.manhattanLength() < hsbExt));
00270     }
00271 
00272     // Use small scroll bars for tool windows, if the window has a native size grip.
00273     const QMacStyle::WidgetSizePolicy hpolicy = QMacStyle::widgetSizePolicy(hbar);
00274     const QMacStyle::WidgetSizePolicy vpolicy = QMacStyle::widgetSizePolicy(vbar);
00275     const Qt::WindowType windowType = window->windowType();
00276     if (windowType == Qt::Tool && (hasMacSizeGrip || hasMacReverseSizeGrip)) {
00277         if (hpolicy != QMacStyle::SizeSmall)
00278             QMacStyle::setWidgetSizePolicy(hbar, QMacStyle::SizeSmall);
00279         if (vpolicy != QMacStyle::SizeSmall)
00280             QMacStyle::setWidgetSizePolicy(vbar, QMacStyle::SizeSmall);
00281     } else {
00282         if (hpolicy != QMacStyle::SizeDefault)
00283             QMacStyle::setWidgetSizePolicy(hbar, QMacStyle::SizeDefault);
00284         if (vpolicy != QMacStyle::SizeDefault)
00285             QMacStyle::setWidgetSizePolicy(vbar, QMacStyle::SizeDefault);
00286     }
00287 #endif
00288     QPoint cornerOffset(needv ? vsbExt : 0, needh ? hsbExt : 0);
00289     QRect controlsRect;
00290     QRect viewportRect;
00291 
00292     // In FrameOnlyAroundContents mode the frame is drawn between the controls and
00293     // the viewport, else the frame rect is equal to the widget rect.
00294     if (q->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, &opt, q)) {
00295         controlsRect = widgetRect;
00296         const int extra = q->style()->pixelMetric(QStyle::PM_DefaultFrameWidth) * 2;
00297         const QPoint cornerExtra(needv ? extra : 0, needh ? extra : 0);
00298         QRect frameRect = widgetRect;
00299         frameRect.adjust(0, 0, -cornerOffset.x() - cornerExtra.x(), -cornerOffset.y() - cornerExtra.y());
00300         q->setFrameRect(frameRect);
00301         viewportRect = q->contentsRect();
00302     } else {
00303         q->setFrameRect(QStyle::visualRect(opt.direction, opt.rect, widgetRect));
00304         controlsRect = q->contentsRect();
00305         viewportRect = QRect(controlsRect.topLeft(), controlsRect.bottomRight() - cornerOffset);
00306     }
00307 
00308     // If we have a corner widget and are only showing one scroll bar, we need to move it
00309     // to make room for the corner widget.
00310     if (hasCornerWidget && (needv || needh))
00311         cornerOffset =  extPoint;
00312 
00313 #ifdef Q_WS_MAC
00314     // Also move the scroll bars if they are covered by the native Mac size grip.
00315     if (hasMacSizeGrip)
00316         cornerOffset =  extPoint;
00317 #endif
00318 
00319     // The corner point is where the scroll bar rects, the corner widget rect and the
00320     // viewport rect meets.
00321     const QPoint cornerPoint(controlsRect.bottomRight() + QPoint(1, 1) - cornerOffset);
00322 
00323     // Some styles paints the corner if both scorllbars are showing and there is
00324     // no corner widget. Also, on the Mac we paint if there is a native
00325     // (transparent) sizegrip in the area where a corner widget would be.
00326     if (needv && needh && hasCornerWidget == false
00327 #ifdef Q_WS_MAC
00328         || ((needv || needh) && hasMacSizeGrip)
00329 #endif
00330     ) {
00331         cornerPaintingRect = QStyle::visualRect(opt.direction, opt.rect, QRect(cornerPoint, extSize));
00332     } else {
00333         cornerPaintingRect = QRect();
00334     }
00335 
00336 #ifdef Q_WS_MAC
00337     if (hasMacReverseSizeGrip)
00338         reverseCornerPaintingRect = QRect(controlsRect.bottomRight() + QPoint(1, 1) - extPoint, extSize);
00339     else
00340         reverseCornerPaintingRect = QRect();
00341 #endif
00342 
00343     if (needh) {
00344         QRect horizontalScrollBarRect(QPoint(controlsRect.left(), cornerPoint.y()), QPoint(cornerPoint.x() - 1, controlsRect.bottom()));
00345 #ifdef Q_WS_MAC
00346         if (hasMacReverseSizeGrip)
00347             horizontalScrollBarRect.adjust(vsbExt, 0, 0, 0);
00348 #endif
00349         scrollBarContainers[Qt::Horizontal]->setGeometry(QStyle::visualRect(opt.direction, opt.rect, horizontalScrollBarRect));
00350         scrollBarContainers[Qt::Horizontal]->raise();
00351     }
00352 
00353     if (needv) {
00354         const QRect verticalScrollBarRect  (QPoint(cornerPoint.x(), controlsRect.top()),  QPoint(controlsRect.right(), cornerPoint.y() - 1));
00355         scrollBarContainers[Qt::Vertical]->setGeometry(QStyle::visualRect(opt.direction, opt.rect, verticalScrollBarRect));
00356         scrollBarContainers[Qt::Vertical]->raise();
00357     }
00358 
00359     if (cornerWidget) {
00360         const QRect cornerWidgetRect(cornerPoint, controlsRect.bottomRight());
00361         cornerWidget->setGeometry(QStyle::visualRect(opt.direction, opt.rect, cornerWidgetRect));
00362     }
00363 
00364     scrollBarContainers[Qt::Horizontal]->setVisible(needh);
00365     scrollBarContainers[Qt::Vertical]->setVisible(needv);
00366 
00367     // Existing code expect to have to account for reverse mode when calling
00368     // setViewportMargins(), so we undo that here to preserve the behavior.
00369     // ### Qt 5: Consider changing the behavior.
00370     if (QApplication::isRightToLeft())
00371         viewportRect.adjust(right, top, -left, -bottom);
00372     else
00373         viewportRect.adjust(left, top, -right, -bottom);
00374 
00375     viewport->setGeometry(QStyle::visualRect(opt.direction, opt.rect, viewportRect)); // resize the viewport last
00376 }
00377 
00383 QAbstractScrollArea::QAbstractScrollArea(QAbstractScrollAreaPrivate &dd, QWidget *parent)
00384     :QFrame(dd, parent)
00385 {
00386     Q_D(QAbstractScrollArea);
00387     d->init();
00388 }
00389 
00395 QAbstractScrollArea::QAbstractScrollArea(QWidget *parent)
00396     :QFrame(*new QAbstractScrollAreaPrivate, parent)
00397 {
00398     Q_D(QAbstractScrollArea);
00399     d->init();
00400 }
00401 
00402 
00406 QAbstractScrollArea::~QAbstractScrollArea()
00407 {
00408     Q_D(QAbstractScrollArea);
00409     delete d->viewportFilter;
00410 }
00411 
00412 
00423 void QAbstractScrollArea::setViewport(QWidget *widget)
00424 {
00425     Q_D(QAbstractScrollArea);
00426     if (widget != d->viewport) {
00427         QWidget *oldViewport = d->viewport;
00428         if (!widget)
00429             widget = new QWidget;
00430         d->viewport = widget;
00431         d->viewport->setParent(this);
00432         d->viewport->setFocusProxy(this);
00433         d->viewport->installEventFilter(d->viewportFilter);
00434         d->layoutChildren();
00435         if (isVisible())
00436             d->viewport->show();
00437         QMetaObject::invokeMethod(this, "setupViewport", Q_ARG(QWidget *, widget));
00438         delete oldViewport;
00439     }
00440 }
00441 
00450 QWidget *QAbstractScrollArea::viewport() const
00451 {
00452     Q_D(const QAbstractScrollArea);
00453     return d->viewport;
00454 }
00455 
00456 
00461 // ### still thinking about the name
00462 QSize QAbstractScrollArea::maximumViewportSize() const
00463 {
00464     Q_D(const QAbstractScrollArea);
00465     int hsbExt = d->hbar->sizeHint().height();
00466     int vsbExt = d->vbar->sizeHint().width();
00467 
00468     int f = 2 * d->frameWidth;
00469     QSize max = size() - QSize(f + d->left + d->right, f + d->top + d->bottom);
00470     if (d->vbarpolicy == Qt::ScrollBarAlwaysOn)
00471         max.rwidth() -= vsbExt;
00472     if (d->hbarpolicy == Qt::ScrollBarAlwaysOn)
00473         max.rheight() -= hsbExt;
00474     return max;
00475 }
00476 
00486 Qt::ScrollBarPolicy QAbstractScrollArea::verticalScrollBarPolicy() const
00487 {
00488     Q_D(const QAbstractScrollArea);
00489     return d->vbarpolicy;
00490 }
00491 
00492 void QAbstractScrollArea::setVerticalScrollBarPolicy(Qt::ScrollBarPolicy policy)
00493 {
00494     Q_D(QAbstractScrollArea);
00495     d->vbarpolicy = policy;
00496     if (isVisible())
00497         d->layoutChildren();
00498 }
00499 
00500 
00506 QScrollBar *QAbstractScrollArea::verticalScrollBar() const
00507 {
00508     Q_D(const QAbstractScrollArea);
00509     return d->vbar;
00510 }
00511 
00524 void QAbstractScrollArea::setVerticalScrollBar(QScrollBar *scrollBar)
00525 {
00526     Q_D(QAbstractScrollArea);
00527     if (!scrollBar) {
00528         qWarning("QAbstractScrollArea::setVerticalScrollBar: Cannot set a null scroll bar");
00529         return;
00530     }
00531 
00532     d->replaceScrollBar(scrollBar, Qt::Vertical);
00533 }
00534 
00544 Qt::ScrollBarPolicy QAbstractScrollArea::horizontalScrollBarPolicy() const
00545 {
00546     Q_D(const QAbstractScrollArea);
00547     return d->hbarpolicy;
00548 }
00549 
00550 void QAbstractScrollArea::setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy policy)
00551 {
00552     Q_D(QAbstractScrollArea);
00553     d->hbarpolicy = policy;
00554     if (isVisible())
00555         d->layoutChildren();
00556 }
00557 
00563 QScrollBar *QAbstractScrollArea::horizontalScrollBar() const
00564 {
00565     Q_D(const QAbstractScrollArea);
00566     return d->hbar;
00567 }
00568 
00582 void QAbstractScrollArea::setHorizontalScrollBar(QScrollBar *scrollBar)
00583 {
00584     Q_D(QAbstractScrollArea);
00585     if (!scrollBar) {
00586         qWarning("QAbstractScrollArea::setHorizontalScrollBar: Cannot set a null scroll bar");
00587         return;
00588     }
00589 
00590     d->replaceScrollBar(scrollBar, Qt::Horizontal);
00591 }
00592 
00600 QWidget *QAbstractScrollArea::cornerWidget() const
00601 {
00602     Q_D(const QAbstractScrollArea);
00603     return d->cornerWidget;
00604 }
00605 
00632 void QAbstractScrollArea::setCornerWidget(QWidget *widget)
00633 {
00634     Q_D(QAbstractScrollArea);
00635     QWidget* oldWidget = d->cornerWidget;
00636     if (oldWidget != widget) {
00637         if (oldWidget)
00638             oldWidget->hide();
00639         d->cornerWidget = widget;
00640 
00641         if (widget && widget->parentWidget() != this)
00642             widget->setParent(this);
00643 
00644         d->layoutChildren();
00645         if (widget)
00646             widget->show();
00647     } else {
00648         d->cornerWidget = widget;
00649         d->layoutChildren();
00650     }
00651 }
00652 
00685 void QAbstractScrollArea::addScrollBarWidget(QWidget *widget, Qt::Alignment alignment)
00686 {
00687     Q_D(QAbstractScrollArea);
00688 
00689     if (widget == 0)
00690         return;
00691 
00692     const Qt::Orientation scrollBarOrientation
00693         = ((alignment & Qt::AlignLeft) || (alignment & Qt::AlignRight)) ? Qt::Horizontal : Qt::Vertical;
00694     const QAbstractScrollAreaScrollBarContainer::LogicalPosition position
00695         = ((alignment & Qt::AlignRight) || (alignment & Qt::AlignBottom))
00696           ? QAbstractScrollAreaScrollBarContainer::LogicalRight : QAbstractScrollAreaScrollBarContainer::LogicalLeft;
00697     d->scrollBarContainers[scrollBarOrientation]->addWidget(widget, position);
00698     d->layoutChildren();
00699     if (isHidden() == false)
00700         widget->show();
00701 }
00702 
00710 QWidgetList QAbstractScrollArea::scrollBarWidgets(Qt::Alignment alignment)
00711 {
00712     Q_D(QAbstractScrollArea);
00713 
00714     QWidgetList list;
00715 
00716     if (alignment & Qt::AlignLeft)
00717         list += d->scrollBarContainers[Qt::Horizontal]->widgets(QAbstractScrollAreaScrollBarContainer::LogicalLeft);
00718     if (alignment & Qt::AlignRight)
00719         list += d->scrollBarContainers[Qt::Horizontal]->widgets(QAbstractScrollAreaScrollBarContainer::LogicalRight);
00720     if (alignment & Qt::AlignTop)
00721         list += d->scrollBarContainers[Qt::Vertical]->widgets(QAbstractScrollAreaScrollBarContainer::LogicalLeft);
00722     if (alignment & Qt::AlignBottom)
00723         list += d->scrollBarContainers[Qt::Vertical]->widgets(QAbstractScrollAreaScrollBarContainer::LogicalRight);
00724 
00725     return list;
00726 }
00727 
00737 void QAbstractScrollArea::setViewportMargins(int left, int top, int right, int bottom)
00738 {
00739     Q_D(QAbstractScrollArea);
00740     d->left = left;
00741     d->top = top;
00742     d->right = right;
00743     d->bottom = bottom;
00744     d->layoutChildren();
00745 }
00746 
00759 bool QAbstractScrollArea::event(QEvent *e)
00760 {
00761     Q_D(QAbstractScrollArea);
00762     switch (e->type()) {
00763     case QEvent::AcceptDropsChange:
00764         d->viewport->setAcceptDrops(acceptDrops());
00765         break;
00766     case QEvent::MouseTrackingChange:
00767         d->viewport->setMouseTracking(hasMouseTracking());
00768         break;
00769     case QEvent::Resize:
00770             d->layoutChildren();
00771             break;
00772     case QEvent::Paint:
00773         if (d->cornerPaintingRect.isValid()) {
00774             QStyleOption option;
00775             option.rect = d->cornerPaintingRect;
00776             QPainter p(this);
00777             style()->drawPrimitive(QStyle::PE_PanelScrollAreaCorner, &option, &p, this);
00778         }
00779 #ifdef Q_WS_MAC
00780         if (d->reverseCornerPaintingRect.isValid()) {
00781             QStyleOption option;
00782             option.rect = d->reverseCornerPaintingRect;
00783             QPainter p(this);
00784             style()->drawPrimitive(QStyle::PE_PanelScrollAreaCorner, &option, &p, this);
00785         }
00786 #endif
00787         QFrame::paintEvent((QPaintEvent*)e);
00788         break;
00789     case QEvent::ContextMenu:
00790         if (static_cast<QContextMenuEvent *>(e)->reason() == QContextMenuEvent::Keyboard)
00791            return QFrame::event(e);
00792         e->ignore();
00793         break;
00794     case QEvent::MouseButtonPress:
00795     case QEvent::MouseButtonRelease:
00796     case QEvent::MouseButtonDblClick:
00797     case QEvent::MouseMove:
00798     case QEvent::Wheel:
00799 #ifndef QT_NO_DRAGANDDROP
00800     case QEvent::Drop:
00801     case QEvent::DragEnter:
00802     case QEvent::DragMove:
00803     case QEvent::DragLeave:
00804 #endif
00805         return false;
00806     case QEvent::StyleChange:
00807         d->layoutChildren();
00808         // fall through
00809     default:
00810         return QFrame::event(e);
00811     }
00812     return true;
00813 }
00814 
00835 bool QAbstractScrollArea::viewportEvent(QEvent *e)
00836 {
00837     switch (e->type()) {
00838     case QEvent::Resize:
00839     case QEvent::Paint:
00840     case QEvent::MouseButtonPress:
00841     case QEvent::MouseButtonRelease:
00842     case QEvent::MouseButtonDblClick:
00843     case QEvent::MouseMove:
00844     case QEvent::ContextMenu:
00845 #ifndef QT_NO_WHEELEVENT
00846     case QEvent::Wheel:
00847 #endif
00848 #ifndef QT_NO_DRAGANDDROP
00849     case QEvent::Drop:
00850     case QEvent::DragEnter:
00851     case QEvent::DragMove:
00852     case QEvent::DragLeave:
00853 #endif
00854         return QFrame::event(e);
00855     case QEvent::LayoutRequest:
00856         return event(e);
00857     default:
00858         break;
00859     }
00860     return false; // let the viewport widget handle the event
00861 }
00862 
00876 void QAbstractScrollArea::resizeEvent(QResizeEvent *)
00877 {
00878 }
00879 
00891 void QAbstractScrollArea::paintEvent(QPaintEvent*)
00892 {
00893 }
00894 
00902 void QAbstractScrollArea::mousePressEvent(QMouseEvent *e)
00903 {
00904     e->ignore();
00905 }
00906 
00914 void QAbstractScrollArea::mouseReleaseEvent(QMouseEvent *e)
00915 {
00916     e->ignore();
00917 }
00918 
00926 void QAbstractScrollArea::mouseDoubleClickEvent(QMouseEvent *e)
00927 {
00928     e->ignore();
00929 }
00930 
00938 void QAbstractScrollArea::mouseMoveEvent(QMouseEvent *e)
00939 {
00940     e->ignore();
00941 }
00942 
00950 #ifndef QT_NO_WHEELEVENT
00951 void QAbstractScrollArea::wheelEvent(QWheelEvent *e)
00952 {
00953     Q_D(QAbstractScrollArea);
00954     if (static_cast<QWheelEvent*>(e)->orientation() == Qt::Horizontal)
00955         QApplication::sendEvent(d->hbar, e);
00956     else
00957         QApplication::sendEvent(d->vbar, e);
00958 }
00959 #endif
00960 
00968 void QAbstractScrollArea::contextMenuEvent(QContextMenuEvent *e)
00969 {
00970     e->ignore();
00971 }
00972 
00978 void QAbstractScrollArea::keyPressEvent(QKeyEvent * e)
00979 {
00980     Q_D(QAbstractScrollArea);
00981     if (false){
00982 #ifndef QT_NO_SHORTCUT
00983     } else if (e == QKeySequence::MoveToPreviousPage) {
00984         d->vbar->triggerAction(QScrollBar::SliderPageStepSub);
00985     } else if (e == QKeySequence::MoveToNextPage) {
00986         d->vbar->triggerAction(QScrollBar::SliderPageStepAdd);
00987 #endif
00988     } else {
00989         switch (e->key()) {
00990         case Qt::Key_Up:
00991             d->vbar->triggerAction(QScrollBar::SliderSingleStepSub);
00992             break;
00993         case Qt::Key_Down:
00994             d->vbar->triggerAction(QScrollBar::SliderSingleStepAdd);
00995             break;
00996         case Qt::Key_Left:
00997             d->hbar->triggerAction(QScrollBar::SliderSingleStepSub);
00998             break;
00999         case Qt::Key_Right:
01000             d->hbar->triggerAction(QScrollBar::SliderSingleStepAdd);
01001             break;
01002         default:
01003             e->ignore();
01004             return;
01005         }
01006     }
01007     e->accept();
01008 }
01009 
01010 
01011 #ifndef QT_NO_DRAGANDDROP
01012 
01020 void QAbstractScrollArea::dragEnterEvent(QDragEnterEvent *)
01021 {
01022 }
01023 
01032 void QAbstractScrollArea::dragMoveEvent(QDragMoveEvent *)
01033 {
01034 }
01035 
01044 void QAbstractScrollArea::dragLeaveEvent(QDragLeaveEvent *)
01045 {
01046 }
01047 
01056 void QAbstractScrollArea::dropEvent(QDropEvent *)
01057 {
01058 }
01059 
01060 
01061 #endif
01062 
01081 void QAbstractScrollArea::scrollContentsBy(int, int)
01082 {
01083     viewport()->update();
01084 }
01085 
01086 void QAbstractScrollAreaPrivate::_q_hslide(int x)
01087 {
01088     Q_Q(QAbstractScrollArea);
01089     int dx = xoffset - x;
01090     xoffset = x;
01091     q->scrollContentsBy(dx, 0);
01092 }
01093 
01094 void QAbstractScrollAreaPrivate::_q_vslide(int y)
01095 {
01096     Q_Q(QAbstractScrollArea);
01097     int dy = yoffset - y;
01098     yoffset = y;
01099     q->scrollContentsBy(0, dy);
01100 }
01101 
01102 void QAbstractScrollAreaPrivate::_q_showOrHideScrollBars()
01103 {
01104     layoutChildren();
01105 }
01106 
01107 QPoint QAbstractScrollAreaPrivate::contentsOffset() const
01108 {
01109     Q_Q(const QAbstractScrollArea);
01110     QPoint offset;
01111     if (vbar->isVisible())
01112         offset.setY(vbar->value());
01113     if (hbar->isVisible()) {
01114         if (q->isRightToLeft())
01115             offset.setX(hbar->maximum() - hbar->value());
01116         else
01117             offset.setX(hbar->value());
01118     }
01119     return offset;
01120 }
01121 
01126 QSize QAbstractScrollArea::minimumSizeHint() const
01127 {
01128     Q_D(const QAbstractScrollArea);
01129     int hsbExt = d->hbar->sizeHint().height();
01130     int vsbExt = d->vbar->sizeHint().width();
01131     int extra = 2 * d->frameWidth;
01132     return QSize(d->scrollBarContainers[Qt::Horizontal]->sizeHint().width() + vsbExt + extra,
01133                  d->scrollBarContainers[Qt::Vertical]->sizeHint().height() + hsbExt + extra);
01134 }
01135 
01139 QSize QAbstractScrollArea::sizeHint() const
01140 {
01141     return QSize(256, 192);
01142 #if 0
01143     Q_D(const QAbstractScrollArea);
01144     int h = qMax(10, fontMetrics().height());
01145     int f = 2 * d->frameWidth;
01146     return QSize((6 * h) + f, (4 * h) + f);
01147 #endif
01148 }
01149 
01158 void QAbstractScrollArea::setupViewport(QWidget *viewport)
01159 {
01160     Q_UNUSED(viewport);
01161 }
01162 
01163 #include "moc_qabstractscrollarea.cpp"
01164 #include "moc_qabstractscrollarea_p.cpp"
01165 #endif // QT_NO_SCROLLAREA

Generated on Thu Mar 15 11:56:42 2007 for Qt 4.2 User's Guide by  doxygen 1.5.1