Changeset 561 for trunk/src/gui/widgets


Ignore:
Timestamp:
Feb 11, 2010, 11:19:06 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.6.1 sources.

Location:
trunk
Files:
152 edited
7 copied

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/gui/widgets/qabstractbutton.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    166166#endif
    167167    checkable(false), checked(false), autoRepeat(false), autoExclusive(false),
    168     down(false), blockRefresh(false),
     168    down(false), blockRefresh(false), pressed(false),
    169169#ifndef QT_NO_BUTTONGROUP
    170170    group(0),
     
    216216}
    217217
    218 /*!
    219     Adds the given \a button to the end of the group's internal list of buttons.
    220 
    221     \sa removeButton()
    222 */
     218
     219// TODO: Qt 5: Merge with addButton(QAbstractButton *button, int id)
    223220void QButtonGroup::addButton(QAbstractButton *button)
    224221{
     
    233230    button->d_func()->group = this;
    234231    d->buttonList.append(button);
    235     if (id != -1)
     232    if (id == -1) {
     233        QList<int> ids = d->mapping.values();
     234        if (ids.isEmpty())
     235           d->mapping[button] = -2;
     236        else {
     237            qSort(ids);
     238            d->mapping[button] = ids.first()-1;
     239        }
     240    } else {
    236241        d->mapping[button] = id;
     242    }
     243
    237244    if (d->exclusive && button->isChecked())
    238245        button->d_func()->notifyChecked();
     
    313320#endif
    314321
    315     Q_Q(const QAbstractButton);
    316     QList<QAbstractButton*>candidates;
    317     if (q->parentWidget()) {
    318         candidates =  qFindChildren<QAbstractButton *>(q->parentWidget());
    319         if (autoExclusive) {
    320             for (int i = candidates.count() - 1; i >= 0; --i) {
    321                 QAbstractButton *candidate = candidates.at(i);
    322                 if (!candidate->autoExclusive()
    323 #ifndef QT_NO_BUTTONGROUP
    324                     || candidate->group()
    325 #endif
    326                     )
    327                     candidates.removeAt(i);
    328             }
     322    QList<QAbstractButton*>candidates = qFindChildren<QAbstractButton *>(parent);
     323    if (autoExclusive) {
     324        for (int i = candidates.count() - 1; i >= 0; --i) {
     325            QAbstractButton *candidate = candidates.at(i);
     326            if (!candidate->autoExclusive()
     327#ifndef QT_NO_BUTTONGROUP
     328                || candidate->group()
     329#endif
     330                )
     331                candidates.removeAt(i);
    329332        }
    330333    }
     
    377380    bool exclusive = autoExclusive;
    378381#endif
    379     QWidget *f = qApp->focusWidget();
     382    QWidget *f = QApplication::focusWidget();
    380383    QAbstractButton *fb = qobject_cast<QAbstractButton *>(f);
    381384    if (!fb || !buttonList.contains(fb))
     
    10881091    if (hitButton(e->pos())) {
    10891092        setDown(true);
     1093        d->pressed = true;
    10901094        repaint(); //flush paint event before invoking potentially expensive operation
    10911095        QApplication::flush();
     
    11011105{
    11021106    Q_D(QAbstractButton);
     1107    d->pressed = false;
     1108
    11031109    if (e->button() != Qt::LeftButton) {
    11041110        e->ignore();
     
    11251131{
    11261132    Q_D(QAbstractButton);
    1127     if (!(e->buttons() & Qt::LeftButton)) {
     1133    if (!(e->buttons() & Qt::LeftButton) || !d->pressed) {
    11281134        e->ignore();
    11291135        return;
     
    11701176    case Qt::Key_Down:
    11711177#ifdef QT_KEYPAD_NAVIGATION
    1172         if (QApplication::keypadNavigationEnabled() && (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right)) {
     1178        if ((QApplication::keypadNavigationEnabled()
     1179                && (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right))
     1180                || (!QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional
     1181                || (e->key() == Qt::Key_Up || e->key() == Qt::Key_Down))) {
    11731182            e->ignore();
    11741183            return;
     
    12371246        if (d->down) {
    12381247            QPointer<QAbstractButton> guard(this);
    1239             d->emitReleased();
     1248            nextCheckState();
     1249            if (guard)
     1250                d->emitReleased();
    12401251            if (guard)
    12411252                d->emitClicked();
  • trunk/src/gui/widgets/qabstractbutton.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qabstractbutton_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    7878    uint down :1;
    7979    uint blockRefresh :1;
     80    uint pressed : 1;
    8081
    8182#ifndef QT_NO_BUTTONGROUP
  • trunk/src/gui/widgets/qabstractscrollarea.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5252#include "qboxlayout.h"
    5353#include "qpainter.h"
     54#include "qmargins.h"
    5455
    5556#include "qabstractscrollarea_p.h"
    5657#include <qwidget.h>
     58
     59#include <private/qapplication_p.h>
    5760
    5861#ifdef Q_WS_MAC
     
    158161     viewport(0), cornerWidget(0), left(0), top(0), right(0), bottom(0),
    159162     xoffset(0), yoffset(0), viewportFilter(0)
     163#ifdef Q_WS_WIN
     164     , singleFingerPanEnabled(false)
     165#endif
    160166{
    161167}
     
    282288    QObject::connect(vbar, SIGNAL(valueChanged(int)), q, SLOT(_q_vslide(int)));
    283289    QObject::connect(vbar, SIGNAL(rangeChanged(int,int)), q, SLOT(_q_showOrHideScrollBars()), Qt::QueuedConnection);
    284     viewportFilter = new QAbstractScrollAreaFilter(this);
    285     viewport->installEventFilter(viewportFilter);
     290    viewportFilter.reset(new QAbstractScrollAreaFilter(this));
     291    viewport->installEventFilter(viewportFilter.data());
    286292    viewport->setFocusProxy(q);
    287293    q->setFocusPolicy(Qt::WheelFocus);
     
    289295    q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    290296    layoutChildren();
    291 }
     297#ifndef Q_WS_MAC
     298    viewport->grabGesture(Qt::PanGesture);
     299#endif
     300}
     301
     302#ifdef Q_WS_WIN
     303void QAbstractScrollAreaPrivate::setSingleFingerPanEnabled(bool on)
     304{
     305    singleFingerPanEnabled = on;
     306    QWidgetPrivate *dd = static_cast<QWidgetPrivate *>(QObjectPrivate::get(viewport));
     307    if (dd)
     308        dd->winSetupGestures();
     309}
     310#endif // Q_WS_WIN
    292311
    293312void QAbstractScrollAreaPrivate::layoutChildren()
     
    460479}
    461480
    462 // ### Fix for 4.4, talk to Bjoern E or Girish.
    463 void QAbstractScrollAreaPrivate::scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy) {}
    464 
    465481/*!
    466482    \internal
     
    472488{
    473489    Q_D(QAbstractScrollArea);
    474     d->init();
     490    QT_TRY {
     491        d->init();
     492    } QT_CATCH(...) {
     493        d->viewportFilter.reset();
     494        QT_RETHROW;
     495    }
    475496}
    476497
     
    484505{
    485506    Q_D(QAbstractScrollArea);
    486     d->init();
     507    QT_TRY {
     508        d->init();
     509    } QT_CATCH(...) {
     510        d->viewportFilter.reset();
     511        QT_RETHROW;
     512    }
    487513}
    488514
     
    494520{
    495521    Q_D(QAbstractScrollArea);
    496     delete d->viewportFilter;
     522    // reset it here, otherwise we'll have a dangling pointer in ~QWidget
     523    d->viewportFilter.reset();
    497524}
    498525
     
    518545        d->viewport->setParent(this);
    519546        d->viewport->setFocusProxy(this);
    520         d->viewport->installEventFilter(d->viewportFilter);
     547        d->viewport->installEventFilter(d->viewportFilter.data());
     548#ifndef Q_WS_MAC
     549        d->viewport->grabGesture(Qt::PanGesture);
     550#endif
    521551        d->layoutChildren();
    522552        if (isVisible())
     
    841871    d->bottom = bottom;
    842872    d->layoutChildren();
     873}
     874
     875/*!
     876    \since 4.6
     877    Sets \a margins around the scrolling area. This is useful for
     878    applications such as spreadsheets with "locked" rows and columns.
     879    The marginal space is is left blank; put widgets in the unused
     880    area.
     881
     882    By default all margins are zero.
     883
     884*/
     885void QAbstractScrollArea::setViewportMargins(const QMargins &margins)
     886{
     887    setViewportMargins(margins.left(), margins.top(),
     888                       margins.right(), margins.bottom());
    843889}
    844890
     
    874920            d->layoutChildren();
    875921            break;
    876     case QEvent::Paint:
     922    case QEvent::Paint: {
     923        QStyleOption option;
     924        option.initFrom(this);
    877925        if (d->cornerPaintingRect.isValid()) {
    878             QStyleOption option;
    879926            option.rect = d->cornerPaintingRect;
    880927            QPainter p(this);
     
    883930#ifdef Q_WS_MAC
    884931        if (d->reverseCornerPaintingRect.isValid()) {
    885             QStyleOption option;
    886932            option.rect = d->reverseCornerPaintingRect;
    887933            QPainter p(this);
     
    889935        }
    890936#endif
     937        }
    891938        QFrame::paintEvent((QPaintEvent*)e);
    892939        break;
     
    909956    case QEvent::DragLeave:
    910957#endif
     958        // ignore touch events in case they have been propagated from the viewport
     959    case QEvent::TouchBegin:
     960    case QEvent::TouchUpdate:
     961    case QEvent::TouchEnd:
    911962        return false;
     963    case QEvent::Gesture:
     964    {
     965        QGestureEvent *ge = static_cast<QGestureEvent *>(e);
     966        QPanGesture *g = static_cast<QPanGesture *>(ge->gesture(Qt::PanGesture));
     967        if (g) {
     968            QScrollBar *hBar = horizontalScrollBar();
     969            QScrollBar *vBar = verticalScrollBar();
     970            QPointF delta = g->delta();
     971            if (!delta.isNull()) {
     972                if (QApplication::isRightToLeft())
     973                    delta.rx() *= -1;
     974                int newX = hBar->value() - delta.x();
     975                int newY = vBar->value() - delta.y();
     976                hBar->setValue(newX);
     977                vBar->setValue(newY);
     978            }
     979            return true;
     980        }
     981        return false;
     982    }
    912983    case QEvent::StyleChange:
    913984    case QEvent::LayoutDirectionChange:
     
    9491020    case QEvent::MouseButtonRelease:
    9501021    case QEvent::MouseButtonDblClick:
     1022    case QEvent::TouchBegin:
     1023    case QEvent::TouchUpdate:
     1024    case QEvent::TouchEnd:
    9511025    case QEvent::MouseMove:
    9521026    case QEvent::ContextMenu:
     
    9621036        return QFrame::event(e);
    9631037    case QEvent::LayoutRequest:
     1038    case QEvent::Gesture:
     1039    case QEvent::GestureOverride:
    9641040        return event(e);
    9651041    default:
     
    10591135{
    10601136    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);
     1137    QScrollBar *const bars[2] = { d->hbar, d->vbar };
     1138    int idx = (e->orientation() == Qt::Vertical) ? 1 : 0;
     1139    int other = (idx + 1) % 2;
     1140    if (!bars[idx]->isVisible() && bars[other]->isVisible())
     1141        idx = other;   // If the scrollbar of the event orientation is hidden, fallback to the other.
     1142
     1143    QApplication::sendEvent(bars[idx], e);
    10651144}
    10661145#endif
     
    12381317{
    12391318    layoutChildren();
     1319#ifdef Q_WS_WIN
     1320    // Need to re-subscribe to gestures as the content changes to make sure we
     1321    // enable/disable panning when needed.
     1322    QWidgetPrivate *dd = static_cast<QWidgetPrivate *>(QObjectPrivate::get(viewport));
     1323    if (dd)
     1324        dd->winSetupGestures();
     1325#endif // Q_WS_WIN
    12401326}
    12411327
     
    12651351    int vsbExt = d->vbar->sizeHint().width();
    12661352    int extra = 2 * d->frameWidth;
     1353    QStyleOption opt;
     1354    opt.initFrom(this);
     1355    if ((d->frameStyle != QFrame::NoFrame)
     1356        && style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, &opt, this)) {
     1357        extra += style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarSpacing, &opt, this);
     1358    }
    12671359    return QSize(d->scrollBarContainers[Qt::Horizontal]->sizeHint().width() + vsbExt + extra,
    12681360                 d->scrollBarContainers[Qt::Vertical]->sizeHint().height() + hsbExt + extra);
  • trunk/src/gui/widgets/qabstractscrollarea.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5353#ifndef QT_NO_SCROLLAREA
    5454
     55class QMargins;
    5556class QScrollBar;
    5657class QAbstractScrollAreaPrivate;
     
    9697    QAbstractScrollArea(QAbstractScrollAreaPrivate &dd, QWidget *parent = 0);
    9798    void setViewportMargins(int left, int top, int right, int bottom);
     99    void setViewportMargins(const QMargins &margins);
    98100
    99101    bool event(QEvent *);
     
    131133
    132134    friend class QStyleSheetStyle;
     135    friend class QWidgetPrivate;
    133136};
    134137
  • trunk/src/gui/widgets/qabstractscrollarea_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6363class QScrollBar;
    6464class QAbstractScrollAreaScrollBarContainer;
    65 class Q_GUI_EXPORT QAbstractScrollAreaPrivate: public QFramePrivate
     65class Q_AUTOTEST_EXPORT QAbstractScrollAreaPrivate: public QFramePrivate
    6666{
    6767    Q_DECLARE_PUBLIC(QAbstractScrollArea)
     
    8989    void layoutChildren();
    9090    // ### Fix for 4.4, talk to Bjoern E or Girish.
    91     virtual void scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy);
     91    virtual void scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy) {}
    9292
    9393    void _q_hslide(int);
     
    9999    inline bool viewportEvent(QEvent *event)
    100100    { return q_func()->viewportEvent(event); }
    101     QObject *viewportFilter;
     101    QScopedPointer<QObject> viewportFilter;
     102
     103#ifdef Q_WS_WIN
     104    bool singleFingerPanEnabled;
     105    void setSingleFingerPanEnabled(bool on = true);
     106#endif
    102107};
    103108
  • trunk/src/gui/widgets/qabstractslider.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4848#include "qaccessible.h"
    4949#endif
     50#ifdef QT_KEYPAD_NAVIGATION
     51#include "qtabwidget.h" // Needed in inTabWidget()
     52#endif // QT_KEYPAD_NAVIGATION
    5053#include <limits.h>
    5154
     
    213216QAbstractSliderPrivate::QAbstractSliderPrivate()
    214217    : minimum(0), maximum(99), singleStep(1), pageStep(10),
    215       value(0), position(0), pressValue(-1), tracking(true), blocktracking(false), pressed(false),
     218      value(0), position(0), pressValue(-1), offset_accumulated(0), tracking(true),
     219      blocktracking(false), pressed(false),
    216220      invertedAppearance(false), invertedControls(false),
    217221      orientation(Qt::Horizontal), repeatAction(QAbstractSlider::SliderNoAction)
     222#ifdef QT_KEYPAD_NAVIGATION
     223      , isAutoRepeating(false)
     224      , repeatMultiplier(1)
     225#endif
    218226{
    219227}
     
    367375    abstract sliders provides and typically corresponds to the user
    368376    pressing an arrow key.
     377
     378    If the property is modified during an auto repeating key event, behavior
     379    is undefined.
    369380
    370381    \sa pageStep
     
    595606    switch (action) {
    596607    case SliderSingleStepAdd:
    597         setSliderPosition(d->overflowSafeAdd(d->singleStep));
     608        setSliderPosition(d->overflowSafeAdd(d->effectiveSingleStep()));
    598609        break;
    599610    case SliderSingleStepSub:
    600         setSliderPosition(d->overflowSafeAdd(-d->singleStep));
     611        setSliderPosition(d->overflowSafeAdd(-d->effectiveSingleStep()));
    601612        break;
    602613    case SliderPageStepAdd:
     
    687698    Q_D(QAbstractSlider);
    688699    e->ignore();
    689     if (e->orientation() != d->orientation && !rect().contains(e->pos()))
    690         return;
    691 
    692     static qreal offset = 0;
    693     static QAbstractSlider *offset_owner = 0;
    694     if (offset_owner != this){
    695         offset_owner = this;
    696         offset = 0;
    697     }
    698 
    699     // On Mac/Cocoa, always scroll one step. The mouse wheel acceleration
    700     // is higher than on other systems, so this works well in practice.
    701 #ifdef QT_MAC_USE_COCOA
    702     int step = 1;
    703 #else
    704     int step = qMin(QApplication::wheelScrollLines() * d->singleStep, d->pageStep);
     700
     701    int stepsToScroll = 0;
     702    qreal offset = qreal(e->delta()) / 120;
     703
     704    if ((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::ShiftModifier)) {
     705        // Scroll one page regardless of delta:
     706        stepsToScroll = qBound(-d->pageStep, int(offset * d->pageStep), d->pageStep);
     707        d->offset_accumulated = 0;
     708    } else {
     709        // Calculate how many lines to scroll. Depending on what delta is (and
     710        // offset), we might end up with a fraction (e.g. scroll 1.3 lines). We can
     711        // only scroll whole lines, so we keep the reminder until next event.
     712        qreal stepsToScrollF = offset * QApplication::wheelScrollLines() * d->effectiveSingleStep();
     713        // Check if wheel changed direction since last event:
     714        if (d->offset_accumulated != 0 && (offset / d->offset_accumulated) < 0)
     715            d->offset_accumulated = 0;
     716
     717        d->offset_accumulated += stepsToScrollF;
     718        stepsToScroll = qBound(-d->pageStep, int(d->offset_accumulated), d->pageStep);
     719        d->offset_accumulated -= int(d->offset_accumulated);
     720        if (stepsToScroll == 0)
     721            return;
     722    }
     723
     724    if (d->invertedControls)
     725        stepsToScroll = -stepsToScroll;
     726
     727    int prevValue = d->value;
     728    d->position = d->overflowSafeAdd(stepsToScroll); // value will be updated by triggerAction()
     729    triggerAction(SliderMove);
     730
     731    if (prevValue == d->value)
     732        d->offset_accumulated = 0;
     733    else
     734        e->accept();
     735}
    705736#endif
    706     if ((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::ShiftModifier))
    707         step = d->pageStep;
    708     int currentOffset = qRound(qreal(e->delta()) * step / 120);
    709     if (currentOffset == 0)
    710         currentOffset = (e->delta() < 0 ? -1 : 1);
    711     offset += currentOffset;
    712 
    713     if (d->invertedControls)
    714         offset = -offset;
    715 
    716     int prevValue = d->value;
    717     d->position = d->overflowSafeAdd(int(offset)); // value will be updated by triggerAction()
    718 
    719     triggerAction(SliderMove);
    720     if (prevValue == d->value) {
    721         offset = 0;
    722     } else {
    723         offset -= int(offset);
    724         e->accept();
    725     }
    726 }
     737#ifdef QT_KEYPAD_NAVIGATION
     738/*!
     739    \internal
     740
     741    Tells us if it there is currently a reachable widget by keypad navigation in
     742    a certain \a orientation.
     743    If no navigation is possible, occuring key events in that \a orientation may
     744    be used to interact with the value in the focussed widget, even though it
     745    currently has not the editFocus.
     746
     747    \sa QWidgetPrivate::widgetInNavigationDirection(), QWidget::hasEditFocus()
     748*/
     749inline static bool canKeypadNavigate(Qt::Orientation orientation)
     750{
     751    return orientation == Qt::Horizontal?
     752            (QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionEast)
     753                    || QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionWest))
     754            :(QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionNorth)
     755                    || QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionSouth));
     756}
     757/*!
     758    \internal
     759
     760    Checks, if the \a widget is inside a QTabWidget. If is is inside
     761    one, left/right key events will be used to switch between tabs in keypad
     762    navigation. If there is no QTabWidget, the horizontal key events can be used to
     763    interact with the value in the focussed widget, even though it currently has
     764    not the editFocus.
     765
     766    \sa QWidget::hasEditFocus()
     767*/
     768inline static bool inTabWidget(QWidget *widget)
     769{
     770    for (QWidget *tabWidget = widget; tabWidget; tabWidget = tabWidget->parentWidget())
     771        if (qobject_cast<const QTabWidget*>(tabWidget))
     772            return true;
     773    return false;
     774}
     775#endif // QT_KEYPAD_NAVIGATION
     776/*!
     777    \reimp
     778*/
     779void QAbstractSlider::keyPressEvent(QKeyEvent *ev)
     780{
     781    Q_D(QAbstractSlider);
     782    SliderAction action = SliderNoAction;
     783#ifdef QT_KEYPAD_NAVIGATION
     784    if (ev->isAutoRepeat()) {
     785        if (d->firstRepeat.isNull())
     786            d->firstRepeat = QTime::currentTime();
     787        else if (1 == d->repeatMultiplier) {
     788            // This is the interval in milli seconds which one key repetition
     789            // takes.
     790            const int repeatMSecs = d->firstRepeat.msecsTo(QTime::currentTime());
     791
     792            /**
     793             * The time it takes to currently navigate the whole slider.
     794             */
     795            const qreal currentTimeElapse = (qreal(maximum()) / singleStep()) * repeatMSecs;
     796
     797            /**
     798             * This is an arbitrarily determined constant in msecs that
     799             * specifies how long time it should take to navigate from the
     800             * start to the end(excluding starting key auto repeat).
     801             */
     802            const int SliderRepeatElapse = 2500;
     803
     804            d->repeatMultiplier = currentTimeElapse / SliderRepeatElapse;
     805        }
     806
     807    }
     808    else if (!d->firstRepeat.isNull()) {
     809        d->firstRepeat = QTime();
     810        d->repeatMultiplier = 1;
     811    }
     812
    727813#endif
    728 /*!
    729     \reimp
    730 */
    731 void QAbstractSlider::keyPressEvent(QKeyEvent *ev)
    732 {
    733     Q_D(QAbstractSlider);
    734     SliderAction action = SliderNoAction;
     814
    735815    switch (ev->key()) {
    736816#ifdef QT_KEYPAD_NAVIGATION
     
    753833        case Qt::Key_Left:
    754834#ifdef QT_KEYPAD_NAVIGATION
    755             if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) {
     835            // In QApplication::KeypadNavigationDirectional, we want to change the slider
     836            // value if there is no left/right navigation possible and if this slider is not
     837            // inside a tab widget.
     838            if (QApplication::keypadNavigationEnabled()
     839                    && (!hasEditFocus() && QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
     840                    || d->orientation == Qt::Vertical
     841                    || !hasEditFocus() && (canKeypadNavigate(Qt::Horizontal) || inTabWidget(this)))) {
    756842                ev->ignore();
    757843                return;
     
    768854        case Qt::Key_Right:
    769855#ifdef QT_KEYPAD_NAVIGATION
    770             if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) {
     856            // Same logic as in Qt::Key_Left
     857            if (QApplication::keypadNavigationEnabled()
     858                    && (!hasEditFocus() && QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
     859                    || d->orientation == Qt::Vertical
     860                    || !hasEditFocus() && (canKeypadNavigate(Qt::Horizontal) || inTabWidget(this)))) {
    771861                ev->ignore();
    772862                return;
     
    783873        case Qt::Key_Up:
    784874#ifdef QT_KEYPAD_NAVIGATION
    785             if (QApplication::keypadNavigationEnabled()) {
     875            // In QApplication::KeypadNavigationDirectional, we want to change the slider
     876            // value if there is no up/down navigation possible.
     877            if (QApplication::keypadNavigationEnabled()
     878                    && (QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
     879                    || d->orientation == Qt::Horizontal
     880                    || !hasEditFocus() && canKeypadNavigate(Qt::Vertical))) {
    786881                ev->ignore();
    787882                break;
     
    792887        case Qt::Key_Down:
    793888#ifdef QT_KEYPAD_NAVIGATION
    794             if (QApplication::keypadNavigationEnabled()) {
     889            // Same logic as in Qt::Key_Up
     890            if (QApplication::keypadNavigationEnabled()
     891                    && (QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
     892                    || d->orientation == Qt::Horizontal
     893                    || !hasEditFocus() && canKeypadNavigate(Qt::Vertical))) {
    795894                ev->ignore();
    796895                break;
  • trunk/src/gui/widgets/qabstractslider.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qabstractslider_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6969    void setSteps(int single, int page);
    7070
    71     int minimum, maximum, singleStep, pageStep, value, position, pressValue;
     71    int minimum, maximum, pageStep, value, position, pressValue;
     72
     73    /**
     74     * Call effectiveSingleStep() when changing the slider value.
     75     */
     76    int singleStep;
     77
     78    float offset_accumulated;
    7279    uint tracking : 1;
    7380    uint blocktracking :1;
     
    8390#ifdef QT_KEYPAD_NAVIGATION
    8491    int origValue;
     92
     93    /**
     94     */
     95    bool isAutoRepeating;
     96
     97    /**
     98     * When we're auto repeating, we multiply singleStep with this value to
     99     * get our effective step.
     100     */
     101    qreal repeatMultiplier;
     102
     103    /**
     104     * The time of when the first auto repeating key press event occurs.
     105     */
     106    QTime firstRepeat;
     107
    85108#endif
     109
     110    inline int effectiveSingleStep() const
     111    {
     112        return singleStep
     113#ifdef QT_KEYPAD_NAVIGATION
     114        * repeatMultiplier
     115#endif
     116        ;
     117    }
    86118
    87119    inline int bound(int val) const { return qMax(minimum, qMin(maximum, val)); }
  • trunk/src/gui/widgets/qabstractspinbox.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5858#include <qstylepainter.h>
    5959#include <qdebug.h>
     60#ifndef QT_NO_ACCESSIBILITY
     61# include <qaccessible.h>
     62#endif
    6063
    6164#if defined(Q_WS_X11)
    6265#include <limits.h>
     66#endif
     67
     68#if defined(Q_OS_SYMBIAN)
     69#include <W32STD.H>
     70#include <private/qt_s60_p.h>
    6371#endif
    6472
     
    194202    if (d->buttonSymbols != buttonSymbols) {
    195203        d->buttonSymbols = buttonSymbols;
     204        d->updateEditFieldGeometry();
    196205        update();
    197206    }
     
    660669
    661670    d->edit->setFrame(false);
    662     d->edit->setAttribute(Qt::WA_InputMethodEnabled, false);
    663671    d->edit->setFocusProxy(this);
    664672    d->edit->setAcceptDrops(false);
     
    689697    Q_D(QAbstractSpinBox);
    690698    d->interpret(EmitIfChanged);
     699}
     700
     701/*
     702    Reimplemented in 4.6, so be careful.
     703 */
     704/*!
     705    \reimp
     706*/
     707QVariant QAbstractSpinBox::inputMethodQuery(Qt::InputMethodQuery query) const
     708{
     709    Q_D(const QAbstractSpinBox);
     710    return d->edit->inputMethodQuery(query);
    691711}
    692712
     
    925945
    926946    int steps = 1;
     947    bool isPgUpOrDown = false;
    927948    switch (event->key()) {
    928949    case Qt::Key_PageUp:
    929950    case Qt::Key_PageDown:
    930951        steps *= 10;
     952        isPgUpOrDown = true;
    931953    case Qt::Key_Up:
    932954    case Qt::Key_Down: {
     
    950972            d->buttonState = (Keyboard | (up ? Up : Down));
    951973        }
    952         stepBy(steps);
     974        if (d->spinClickTimerId == -1)
     975            stepBy(steps);
     976        if(event->isAutoRepeat() && !isPgUpOrDown) {
     977            if(d->spinClickThresholdTimerId == -1 && d->spinClickTimerId == -1) {
     978                d->updateState(up, true);
     979            }
     980        }
     981#ifndef QT_NO_ACCESSIBILITY
     982        QAccessible::updateAccessibility(this, 0, QAccessible::ValueChanged);
     983#endif
    953984        return;
    954985    }
     
    9701001    case Qt::Key_Enter:
    9711002    case Qt::Key_Return:
    972         d->edit->d_func()->modifiedState = d->edit->d_func()->undoState = 0;
     1003        d->edit->d_func()->control->clearUndo();
    9731004        d->interpret(d->keyboardTracking ? AlwaysEmit : EmitIfChanged);
    9741005        selectAll();
     
    10441075    Q_D(QAbstractSpinBox);
    10451076
    1046     if (d->buttonState & Keyboard && !event->isAutoRepeat()
    1047         && style()->styleHint(QStyle::SH_SpinBox_AnimateButton, 0, this)) {
     1077    if (d->buttonState & Keyboard && !event->isAutoRepeat())  {
    10481078        d->reset();
    10491079    } else {
     
    11311161}
    11321162
     1163
     1164/*!
     1165    \internal
     1166
     1167    Used when acceleration is turned on. We need to get the
     1168    keyboard auto repeat rate from OS. This value is used as
     1169    argument when starting acceleration related timers.
     1170
     1171    Every platform should, either, use native calls to obtain
     1172    the value or hard code some reasonable rate.
     1173
     1174    Remember that time value should be given in msecs.
     1175*/
     1176static int getKeyboardAutoRepeatRate() {
     1177    int ret = 30;
     1178#if defined(Q_OS_SYMBIAN)
     1179    TTimeIntervalMicroSeconds32 initialTime;
     1180    TTimeIntervalMicroSeconds32 time;
     1181    S60->wsSession().GetKeyboardRepeatRate(initialTime, time);
     1182    ret = time.Int() / 1000; // msecs
     1183#elif defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
     1184    DWORD time;
     1185    if (SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &time, 0) != FALSE)
     1186        ret = static_cast<int>(1000 / static_cast<int>(time)); // msecs
     1187#endif
     1188    return ret; // msecs
     1189}
     1190
    11331191/*!
    11341192    \reimp
     
    11431201        killTimer(d->spinClickThresholdTimerId);
    11441202        d->spinClickThresholdTimerId = -1;
    1145         d->spinClickTimerId = startTimer(d->spinClickTimerInterval);
     1203        d->effectiveSpinRepeatRate = d->buttonState & Keyboard
     1204                                     ? getKeyboardAutoRepeatRate()
     1205                                     : d->spinClickTimerInterval;
     1206        d->spinClickTimerId = startTimer(d->effectiveSpinRepeatRate);
    11461207        doStep = true;
    11471208    } else if (event->timerId() == d->spinClickTimerId) {
    11481209        if (d->accelerate) {
    1149             d->acceleration = d->acceleration + (int)(d->spinClickTimerInterval * 0.05);
    1150             if (d->spinClickTimerInterval - d->acceleration >= 10) {
     1210            d->acceleration = d->acceleration + (int)(d->effectiveSpinRepeatRate * 0.05);
     1211            if (d->effectiveSpinRepeatRate - d->acceleration >= 10) {
    11511212                killTimer(d->spinClickTimerId);
    1152                 d->spinClickTimerId = startTimer(d->spinClickTimerInterval - d->acceleration);
     1213                d->spinClickTimerId = startTimer(d->effectiveSpinRepeatRate - d->acceleration);
    11531214            }
    11541215        }
     
    12911352    : edit(0), type(QVariant::Invalid), spinClickTimerId(-1),
    12921353      spinClickTimerInterval(100), spinClickThresholdTimerId(-1), spinClickThresholdTimerInterval(-1),
    1293       buttonState(None), cachedText(QLatin1String("\x01")), cachedState(QValidator::Invalid),
    1294       pendingEmit(false), readOnly(false), wrapping(false),
     1354      effectiveSpinRepeatRate(1), buttonState(None), cachedText(QLatin1String("\x01")),
     1355      cachedState(QValidator::Invalid), pendingEmit(false), readOnly(false), wrapping(false),
    12951356      ignoreCursorPositionChanged(false), frame(true), accelerate(false), keyboardTracking(true),
    12961357      cleared(false), ignoreUpdateEdit(false), correctionMode(QAbstractSpinBox::CorrectToPreviousValue),
     
    15371598*/
    15381599
    1539 void QAbstractSpinBoxPrivate::updateState(bool up)
     1600void QAbstractSpinBoxPrivate::updateState(bool up, bool fromKeyboard /* = false */)
    15401601{
    15411602    Q_Q(QAbstractSpinBox);
     
    15461607                                  : QAbstractSpinBox::StepDownEnabled))) {
    15471608        spinClickThresholdTimerId = q->startTimer(spinClickThresholdTimerInterval);
    1548         buttonState = (up ? (Mouse | Up) : (Mouse | Down));
     1609        buttonState = (up ? Up : Down) | (fromKeyboard ? Keyboard : Mouse);
    15491610        q->stepBy(up ? 1 : -1);
     1611#ifndef QT_NO_ACCESSIBILITY
     1612        QAccessible::updateAccessibility(q, 0, QAccessible::ValueChanged);
     1613#endif
    15501614    }
    15511615}
     
    15681632    option->activeSubControls = QStyle::SC_None;
    15691633    option->buttonSymbols = d->buttonSymbols;
    1570     option->subControls = QStyle::SC_SpinBoxFrame;
     1634    option->subControls = QStyle::SC_SpinBoxFrame | QStyle::SC_SpinBoxEditField;
    15711635    if (d->buttonSymbols != QAbstractSpinBox::NoButtons) {
    15721636        option->subControls |= QStyle::SC_SpinBoxUp | QStyle::SC_SpinBoxDown;
     
    16961760void QAbstractSpinBoxPrivate::setRange(const QVariant &min, const QVariant &max)
    16971761{
     1762    Q_Q(QAbstractSpinBox);
     1763
    16981764    clearCache();
    16991765    minimum = min;
     
    17071773        updateEdit();
    17081774    }
     1775
     1776    q->updateGeometry();
    17091777}
    17101778
     
    17811849        QASBDEBUG() << "QAbstractSpinBoxPrivate::interpret() text '"
    17821850                    << edit->displayText()
    1783                     << "' >> '" << copy << "'"
    1784                     << "' >> '" << tmp << "'";
     1851                    << "' >> '" << copy << '\''
     1852                    << "' >> '" << tmp << '\'';
    17851853
    17861854        doInterpret = tmp != copy && (q->validate(tmp, pos) == QValidator::Acceptable);
     
    18321900        return QValidator::Acceptable;
    18331901
    1834     if (!dptr->prefix.isEmpty() && !input.startsWith(dptr->prefix))
     1902    if (!dptr->prefix.isEmpty() && !input.startsWith(dptr->prefix)) {
    18351903        input.prepend(dptr->prefix);
     1904        pos += dptr->prefix.length();
     1905    }
    18361906
    18371907    if (!dptr->suffix.isEmpty() && !input.endsWith(dptr->suffix))
  • trunk/src/gui/widgets/qabstractspinbox.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    123123    bool event(QEvent *event);
    124124
     125    QVariant inputMethodQuery(Qt::InputMethodQuery) const;
     126
    125127    virtual QValidator::State validate(QString &input, int &pos) const;
    126128    virtual void fixup(QString &input) const;
  • trunk/src/gui/widgets/qabstractspinbox_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    9999    void init();
    100100    void reset();
    101     void updateState(bool up);
     101    void updateState(bool up, bool fromKeyboard = false);
    102102    QString stripped(const QString &text, int *pos = 0) const;
    103103    bool specialValue() const;
     
    130130    QVariant::Type type;
    131131    int spinClickTimerId, spinClickTimerInterval, spinClickThresholdTimerId, spinClickThresholdTimerInterval;
     132    int effectiveSpinRepeatRate;
    132133    uint buttonState;
    133134    mutable QString cachedText;
     
    136137    mutable QSize cachedSizeHint, cachedMinimumSizeHint;
    137138    uint pendingEmit : 1;
    138     uint spindownEnabled : 1;
    139     uint spinupEnabled : 1;
    140139    uint readOnly : 1;
    141140    uint wrapping : 1;
  • trunk/src/gui/widgets/qbuttongroup.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4949    \ingroup organizers
    5050    \ingroup geomanagement
    51     \ingroup appearance
    52     \mainclass
    5351
    5452    QButtonGroup provides an abstract container into which button widgets can
     
    177175
    178176/*!
    179     \fn void QButtonGroup::addButton(QAbstractButton *button, int id = -1);
     177    \fn void QButtonGroup::addButton(QAbstractButton *button);
     178
     179    Adds the given \a button to the end of the group's internal list
     180    of buttons.  An id will be assigned to the button by this
     181    QButtonGroup. Automatically assigned ids are guaranteed to be
     182    negative, starting with -2. If you are also assigning your own
     183    ids, use positive values to avoid conflicts.
     184
     185    \sa removeButton() buttons()
     186*/
     187
     188/*!
     189    \fn void QButtonGroup::addButton(QAbstractButton *button, int id);
    180190
    181191    Adds the given \a button to the button group, with the given \a
    182     id. If \a id is -1 (the default), an id will be assigned to the
    183     button by this QButtonGroup.
     192    id. It is recommended to assign only positive ids.
    184193
    185194    \sa removeButton() buttons()
  • trunk/src/gui/widgets/qbuttongroup.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qcalendartextnavigator_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qcalendarwidget.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    199199    QString str;
    200200    if (m_day / 10 == 0)
    201         str += QLatin1String("0");
     201        str += QLatin1Char('0');
    202202    str += QString::number(m_day);
    203203    return highlightString(str, m_pos);
     
    211211        QString str;
    212212        if (date.day() / 10 == 0)
    213             str += QLatin1String("0");
     213            str += QLatin1Char('0');
    214214        return str + QString::number(date.day());
    215215    } else if (repeat == 3) {
     
    317317    QString str;
    318318    if (m_month / 10 == 0)
    319         str += QLatin1String("0");
     319        str += QLatin1Char('0');
    320320    str += QString::number(m_month);
    321321    return highlightString(str, m_pos);
     
    329329        QString str;
    330330        if (date.month() / 10 == 0)
    331             str += QLatin1String("0");
     331            str += QLatin1Char('0');
    332332        return str + QString::number(date.month());
    333333    } else if (repeat == 3) {
    334334        return m_locale.standaloneMonthName(date.month(), QLocale::ShortFormat);
    335     } else if (repeat >= 4) {
     335    } else /*if (repeat >= 4)*/ {
    336336        return m_locale.standaloneMonthName(date.month(), QLocale::LongFormat);
    337337    }
    338     return QString();
    339338}
    340339
     
    433432    for (int i = 0; i < 3; i++) {
    434433        if (m_year / pow == 0)
    435             str += QLatin1String("0");
     434            str += QLatin1Char('0');
    436435        pow *= 10;
    437436    }
     
    446445        int year = date.year() % 100;
    447446        if (year / 10 == 0)
    448             str = QLatin1String("0");
     447            str = QLatin1Char('0');
    449448        return str + QString::number(year);
    450449    }
     
    578577
    579578    int pos = 0;
    580     const QLatin1String quote("'");
     579    const QLatin1Char quote('\'');
    581580    bool quoting = false;
    582581    QString separator;
     
    19621961    calendar widget allowing the user to select a date.
    19631962    \since 4.2
    1964     \mainclass
     1963
    19651964    \ingroup advanced
    19661965
     
    19691968    The widget is initialized with the current month and year, but
    19701969    QCalendarWidget provides several public slots to change the year
    1971     and month that is shown.  The currently displayed month and year
    1972     can be retrieved using the currentPageMonth() and currentPageYear()
    1973     functions, respectively.
     1970    and month that is shown.
    19741971
    19751972    By default, today's date is selected, and the user can select a
     
    19831980    all. Note that a date also can be selected programmatically using
    19841981    the setSelectedDate() slot.
     1982
     1983    The currently displayed month and year can be retrieved using the
     1984    monthShown() and yearShown() functions, respectively.
    19851985
    19861986    A newly created calendar widget uses abbreviated day names, and
     
    21432143    int rows = 7;
    21442144    int cols = 8;
    2145     int startRow = 0;
    2146     int startCol = 0;
    21472145
    21482146    const int marginH = (style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1) * 2;
     
    21502148    if (horizontalHeaderFormat() == QCalendarWidget::NoHorizontalHeader) {
    21512149        rows = 6;
    2152         startRow = 1;
    21532150    } else {
    21542151        for (int i = 1; i <= 7; i++) {
     
    21612158    if (verticalHeaderFormat() == QCalendarWidget::NoVerticalHeader) {
    21622159        cols = 7;
    2163         startCol = 1;
    21642160    } else {
    21652161        for (int i = 1; i <= 6; i++) {
     
    22932289
    22942290    The currently displayed month and year can be retrieved using the
    2295     currentPageMonth() and currentPageYear() functions respectively.
     2291    monthShown() and yearShown() functions respectively.
    22962292
    22972293    \sa yearShown(), monthShown(), showPreviousMonth(), showNextMonth(),
     
    23022298{
    23032299    Q_D(QCalendarWidget);
     2300    QDate currentDate = d->getCurrentDate();
     2301    int day = currentDate.day();
     2302    int daysInMonths = QDate(year, month, 1).daysInMonth();
     2303    if (day > daysInMonths)
     2304        day = daysInMonths;
     2305
    23042306    d->showMonth(year, month);
     2307
     2308    QDate newDate(year, month, day);
     2309    int row = -1, col = -1;
     2310    d->m_model->cellForDate(newDate, &row, &col);
     2311    if (row != -1 && col != -1) {
     2312        d->m_view->selectionModel()->setCurrentIndex(d->m_model->index(row, col),
     2313                                                  QItemSelectionModel::NoUpdate);
     2314    }
    23052315}
    23062316
     
    25272537    if (!min.isValid() || !max.isValid())
    25282538        return;
    2529 
    2530     QDate minimum = min;
    2531     QDate maximum = max;
    2532     if (min > max) {
    2533         minimum = max;
    2534         maximum = min;
    2535     }
    25362539
    25372540    QDate oldDate = d->m_model->m_date;
     
    27922795{
    27932796    Q_D(QCalendarWidget);
    2794     if ( date.isNull() && !format.isValid() )
     2797    if (date.isNull())
    27952798        d->m_model->m_dateFormats.clear();
    27962799    else
     
    30343037{
    30353038    Q_D(QCalendarWidget);
    3036     if (event->type() == QEvent::MouseButtonPress && d->yearEdit->hasFocus() && !QRect(d->yearEdit->mapToGlobal(QPoint(0, 0)), d->yearEdit->size()).contains(static_cast<QMouseEvent *>(event)->globalPos())) {
    3037         event->accept();
    3038         d->_q_yearEditingFinished();
    3039         setFocus();
    3040         return true;
     3039    if (event->type() == QEvent::MouseButtonPress && d->yearEdit->hasFocus()) {
     3040        QWidget *tlw = window();
     3041        QWidget *widget = static_cast<QWidget*>(watched);
     3042        //as we have a event filter on the whole application we first make sure that the top level widget
     3043        //of both this and the watched widget are the same to decide if we should finish the year edition.
     3044        if (widget->window() == tlw) {
     3045            QPoint mousePos = widget->mapTo(tlw, static_cast<QMouseEvent *>(event)->pos());
     3046            QRect geom = QRect(d->yearEdit->mapTo(tlw, QPoint(0, 0)), d->yearEdit->size());
     3047            if (!geom.contains(mousePos)) {
     3048                event->accept();
     3049                d->_q_yearEditingFinished();
     3050                setFocus();
     3051                return true;
     3052            }
     3053        }
    30413054    }
    30423055    return QWidget::eventFilter(watched, event);
  • trunk/src/gui/widgets/qcalendarwidget.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qcheckbox.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    7474
    7575    \ingroup basicwidgets
    76     \mainclass
    77 
    78     A QCheckBox is an option button that can be switched on (checked)
    79     or off (unchecked). Checkboxes are typically used to represent
    80     features in an application that can be enabled or disabled without
    81     affecting others, but different types of behavior can be
    82     implemented.
    83 
    84     A QButtonGroup can be used to group check buttons visually.
     76
     77
     78    A QCheckBox is an option button that can be switched on (checked) or off
     79    (unchecked). Checkboxes are typically used to represent features in an
     80    application that can be enabled or disabled without affecting others, but
     81    different types of behavior can be implemented. For example, a
     82    QButtonGroup can be used to group check buttons logically, allowing
     83    exclusive checkboxes. However, QButtonGroup does not provide any visual
     84    representation.
     85
     86    The image below further illustrates the differences between exclusive and
     87    non-exclusive checkboxes.
     88
     89    \table
     90    \row \o \inlineimage checkboxes-exclusive.png
     91         \o \inlineimage checkboxes-non-exclusive.png
     92    \endtable
    8593
    8694    Whenever a checkbox is checked or cleared it emits the signal
    87     stateChanged(). Connect to this signal if you want to trigger an
    88     action each time the checkbox changes state. You can use
    89     isChecked() to query whether or not a checkbox is checked.
    90 
    91     In addition to the usual checked and unchecked states, QCheckBox
    92     optionally provides a third state to indicate "no change". This
    93     is useful whenever you need to give the user the option of neither
    94     checking nor unchecking a checkbox. If you need this third state,
    95     enable it with setTristate(), and use checkState() to query the current
    96     toggle state.
    97 
    98     Just like QPushButton, a checkbox displays text, and optionally a
    99     small icon. The icon is set with setIcon(). The text can be set in
    100     the constructor or with setText(). A shortcut key can be specified
    101     by preceding the preferred character with an ampersand. For
    102     example:
     95    stateChanged(). Connect to this signal if you want to trigger an action
     96    each time the checkbox changes state. You can use isChecked() to query
     97    whether or not a checkbox is checked.
     98
     99    In addition to the usual checked and unchecked states, QCheckBox optionally
     100    provides a third state to indicate "no change". This is useful whenever you
     101    need to give the user the option of neither checking nor unchecking a
     102    checkbox. If you need this third state, enable it with setTristate(), and
     103    use checkState() to query the current toggle state.
     104
     105    Just like QPushButton, a checkbox displays text, and optionally a small
     106    icon. The icon is set with setIcon(). The text can be set in the
     107    constructor or with setText(). A shortcut key can be specified by preceding
     108    the preferred character with an ampersand. For example:
    103109
    104110    \snippet doc/src/snippets/code/src_gui_widgets_qcheckbox.cpp 0
    105111
    106     In this example the shortcut is \e{Alt+A}. See the \l
    107     {QShortcut#mnemonic}{QShortcut} documentation for details (to
    108     display an actual ampersand, use '&&').
    109 
    110     Important inherited functions: text(), setText(), text(),
    111     pixmap(), setPixmap(), accel(), setAccel(), isToggleButton(),
    112     setDown(), isDown(), isOn(), checkState(), autoRepeat(),
    113     isExclusiveToggle(), group(), setAutoRepeat(), toggle(),
    114     pressed(), released(), clicked(), toggled(), checkState(), and
    115     stateChanged().
     112    In this example the shortcut is \e{Alt+A}. See the \l{QShortcut#mnemonic}
     113    {QShortcut} documentation for details (to display an actual ampersand,
     114    use '&&').
     115
     116    Important inherited functions: text(), setText(), text(), pixmap(),
     117    setPixmap(), accel(), setAccel(), isToggleButton(), setDown(), isDown(),
     118    isOn(), checkState(), autoRepeat(), isExclusiveToggle(), group(),
     119    setAutoRepeat(), toggle(), pressed(), released(), clicked(), toggled(),
     120    checkState(), and stateChanged().
    116121
    117122    \table 100%
    118     \row \o \inlineimage macintosh-checkbox.png Screenshot of a Macintosh style checkbox
    119          \o A checkbox shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
    120     \row \o \inlineimage windows-checkbox.png Screenshot of a Windows XP style checkbox
    121          \o A checkbox shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
    122     \row \o \inlineimage plastique-checkbox.png Screenshot of a Plastique style checkbox
    123          \o A checkbox shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
     123    \row
     124        \o \inlineimage macintosh-checkbox.png Screenshot of a Macintosh style checkbox
     125        \o A checkbox shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
     126    \row
     127        \o \inlineimage windows-checkbox.png Screenshot of a Windows XP style checkbox
     128        \o A checkbox shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
     129    \row
     130        \o \inlineimage plastique-checkbox.png Screenshot of a Plastique style checkbox
     131        \o A checkbox shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
    124132    \endtable
    125133
     
    139147    \fn void QCheckBox::stateChanged(int state)
    140148
    141     This signal is emitted whenever the check box's state changes,
    142     i.e. whenever the user checks or unchecks it.
     149    This signal is emitted whenever the check box's state changes, i.e.
     150    whenever the user checks or unchecks it.
    143151
    144152    \a state contains the check box's new Qt::CheckState.
     
    162170
    163171/*!
    164     Initialize \a option with the values from this QCheckBox. This method is useful
    165     for subclasses when they need a QStyleOptionButton, but don't want to fill
    166     in all the information themselves.
     172    Initializes \a option with the values from this QCheckBox. This method is
     173    useful for subclasses that require a QStyleOptionButton, but do not want
     174    to fill in all the information themselves.
    167175
    168176    \sa QStyleOption::initFrom()
     
    194202    Constructs a checkbox with the given \a parent, but with no text.
    195203
    196     The \a parent argument is passed on to the QAbstractButton constructor.
     204    \a parent is passed on to the QAbstractButton constructor.
    197205*/
    198206
     
    207215    Constructs a checkbox with the given \a parent and \a text.
    208216
    209     The \a parent argument is passed on to the QAbstractButton constructor.
     217    \a parent is passed on to the QAbstractButton constructor.
    210218*/
    211219
     
    232240
    233241/*!
    234     Returns the check box's check state.
    235     If you do not need tristate support, you can also
    236     use \l QAbstractButton::isChecked() which returns
    237     a boolean.
     242    Returns the check box's check state. If you do not need tristate support,
     243    you can also  use \l QAbstractButton::isChecked() which returns a boolean.
    238244
    239245    \sa setCheckState() Qt::CheckState
     
    248254
    249255/*!
    250     Sets the check box's check state to \a state.
    251     If you do not need tristate support, you can also
    252     use \l QAbstractButton::setChecked() which takes
    253     a boolean.
     256    Sets the check box's check state to \a state. If you do not need tristate
     257    support, you can also use \l QAbstractButton::setChecked() which takes a
     258    boolean.
    254259
    255260    \sa checkState() Qt::CheckState
     
    275280
    276281
    277 /*!\reimp
     282/*!
     283    \reimp
    278284*/
    279285QSize QCheckBox::sizeHint() const
     
    295301}
    296302
    297 /*!\reimp
     303/*!
     304    \reimp
    298305*/
    299306void QCheckBox::paintEvent(QPaintEvent *)
     
    326333
    327334
    328 /*!\reimp*/
     335/*!
     336    \reimp
     337*/
    329338bool QCheckBox::hitButton(const QPoint &pos) const
    330339{
     
    334343}
    335344
    336 /*!\reimp*/
     345/*!
     346    \reimp
     347*/
    337348void QCheckBox::checkStateSet()
    338349{
     
    346357}
    347358
    348 /*!\reimp*/
     359/*!
     360    \reimp
     361*/
    349362void QCheckBox::nextCheckState()
    350363{
  • trunk/src/gui/widgets/qcheckbox.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qcocoamenu_mac.mm

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    39 **
    40 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
    41 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
    4239**
    4340****************************************************************************/
     
    9996                = QApplication::activePopupWidget())
    10097        popup->close();
    101     qt_mac_emit_menuSignals(((QT_MANGLE_NAMESPACE(QCocoaMenu) *)menu)->qmenu, true);
     98    QMenu *qtmenu = static_cast<QT_MANGLE_NAMESPACE(QCocoaMenu) *>(menu)->qmenu;
     99    qt_mac_emit_menuSignals(qtmenu, true);
     100    qt_mac_menu_collapseSeparators(menu, qtmenu->separatorsCollapsible());
    102101}
    103102
  • trunk/src/gui/widgets/qcocoamenu_mac_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5757QT_FORWARD_DECLARE_CLASS(QMenu)
    5858
    59 @interface QT_MANGLE_NAMESPACE(QCocoaMenu) : NSMenu
    60 {
    61     QMenu *qmenu;
    62 }
    63 - (id)initWithQMenu:(QMenu*)menu;
     59#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5
     60
     61@protocol NSMenuDelegate <NSObject>
    6462- (void)menu:(NSMenu*)menu willHighlightItem:(NSMenuItem*)item;
    6563- (void)menuWillOpen:(NSMenu*)menu;
     
    6765- (BOOL)hasShortcut:(NSMenu *)menu forKey:(NSString *)key forModifiers:(NSUInteger)modifier
    6866  whichItem:(NSMenuItem**)outItem;
     67@end
     68
     69#endif
     70
     71@interface QT_MANGLE_NAMESPACE(QCocoaMenu) : NSMenu <NSMenuDelegate>
     72{
     73    QMenu *qmenu;
     74}
     75- (id)initWithQMenu:(QMenu*)menu;
    6976- (BOOL)menuHasKeyEquivalent:(NSMenu *)menu forEvent:(NSEvent *)event target:(id *)target action:(SEL *)action;
    7077@end
  • trunk/src/gui/widgets/qcocoatoolbardelegate_mac.mm

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4444#include <private/qmainwindowlayout_p.h>
    4545#include <private/qt_mac_p.h>
     46#include <private/qt_cocoa_helpers_mac_p.h>
    4647#include <private/qcocoaview_mac_p.h>
    4748#include <private/qwidget_p.h>
     
    100101    Q_UNUSED(flag);
    101102    Q_UNUSED(nstoolbar);
    102     QToolBar *tb = mainWindowLayout->cocoaItemIDToToolbarHash.value(QCFString::toQString(CFStringRef(itemIdentifier)));
     103    QToolBar *tb = mainWindowLayout->cocoaItemIDToToolbarHash.value(
     104            QT_PREPEND_NAMESPACE(qt_mac_NSStringToQString)(itemIdentifier));
    103105    NSToolbarItem *item = nil;
    104106    if (tb) {
     
    112114{
    113115    NSToolbarItem *item = [[notification userInfo] valueForKey:@"item"];
    114     QToolBar *tb = mainWindowLayout->cocoaItemIDToToolbarHash.value(QCFString::toQString(CFStringRef([item itemIdentifier])));
     116    QToolBar *tb = mainWindowLayout->cocoaItemIDToToolbarHash.value(
     117            QT_PREPEND_NAMESPACE(qt_mac_NSStringToQString)([item itemIdentifier]));
    115118    if (!tb)
    116119        return; // I can't really do anything about this.
     
    120123    NSArray *items = [[qt_mac_window_for(mainWindowLayout->layoutState.mainWindow->window()) toolbar] items];
    121124    int someIndex = 0;
    122     bool foundItem = false;
    123125    for (NSToolbarItem *i in items) {
    124         if (i == item) {
    125             foundItem = true;
     126        if (i == item)
    126127            break;
    127         }
    128128        ++someIndex;
    129129    }
  • trunk/src/gui/widgets/qcocoatoolbardelegate_mac_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qcombobox.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6060#include "qinputcontext.h"
    6161#endif
     62#include <private/qapplication_p.h>
    6263#include <private/qcombobox_p.h>
    6364#include <private/qabstractitemmodel_p.h>
    6465#include <private/qabstractscrollarea_p.h>
     66#include <private/qsoftkeymanager_p.h>
    6567#include <qdebug.h>
    66 
    6768#ifdef Q_WS_X11
    6869#include <private/qt_x11_p.h>
     
    7778#endif
    7879QT_BEGIN_NAMESPACE
    79 
    80 extern QHash<QByteArray, QFont> *qt_app_fonts_hash();
    8180
    8281QComboBoxPrivate::QComboBoxPrivate()
     
    150149
    151150    // Make sure fonts set on the combo box also overrides the font for the popup menu.
    152     if (mCombo->testAttribute(Qt::WA_SetFont) || mCombo->testAttribute(Qt::WA_MacSmallSize)
    153             || mCombo->testAttribute(Qt::WA_MacMiniSize))
     151    if (mCombo->testAttribute(Qt::WA_SetFont)
     152            || mCombo->testAttribute(Qt::WA_MacSmallSize)
     153            || mCombo->testAttribute(Qt::WA_MacMiniSize)
     154            || mCombo->font() != qt_app_fonts_hash()->value("QComboBox", QFont()))
    154155        menuOption.font = mCombo->font();
    155156    else
     
    192193        updateLineEditGeometry();
    193194    }
     195    if (currentIndex.row() != indexBeforeChange)
     196        _q_emitCurrentIndexChanged(currentIndex);
    194197    q->update();
    195198}
     
    314317
    315318        // height
    316         sh.setHeight(qMax(fm.lineSpacing(), 14) + 2);
     319        sh.setHeight(qMax(fm.height(), 14) + 2);
    317320        if (hasIcon) {
    318321            sh.setHeight(qMax(sh.height(), iconSize.height() + 2));
     
    487490
    488491/*
    489     Sets currentIndex on entered if the LeftButton is not pressed. This
    490     means that if mouseTracking(...) is on, we setCurrentIndex and select
    491     even when LeftButton is not pressed.
    492 */
    493 void QComboBoxPrivateContainer::setCurrentIndex(const QModelIndex &index)
    494 {
    495     if (QComboBoxDelegate::isSeparator(index))
    496         return;
    497     view->setCurrentIndex(index);
    498 }
    499 
    500 /*
    501492    Returns the item view used for the combobox popup.
    502493*/
     
    523514                   this, SLOT(updateScrollers()));
    524515#endif
    525         disconnect(view, SIGNAL(entered(QModelIndex)),
    526                    this, SLOT(setCurrentIndex(QModelIndex)));
    527516        disconnect(view, SIGNAL(destroyed()),
    528517                   this, SLOT(viewDestroyed()));
     518
    529519        delete view;
    530520        view = 0;
     
    560550            this, SLOT(updateScrollers()));
    561551#endif
    562     connect(view, SIGNAL(entered(QModelIndex)),
    563             this, SLOT(setCurrentIndex(QModelIndex)));
    564552    connect(view, SIGNAL(destroyed()),
    565553            this, SLOT(viewDestroyed()));
     554
     555#ifdef QT_SOFTKEYS_ENABLED
     556    selectAction = QSoftKeyManager::createKeyedAction(QSoftKeyManager::SelectSoftKey, Qt::Key_Select, itemView);
     557    cancelAction = QSoftKeyManager::createKeyedAction(QSoftKeyManager::CancelSoftKey, Qt::Key_Escape, itemView);
     558    addAction(selectAction);
     559    addAction(cancelAction);
     560#endif
    566561}
    567562
     
    639634        case Qt::Key_F4:
    640635        case Qt::Key_Escape:
    641 #ifdef QT_KEYPAD_NAVIGATION
    642         case Qt::Key_Back:
    643 #endif
    644636            combo->hidePopup();
    645637            return true;
     
    648640        }
    649641    break;
    650     case QEvent::MouseMove: {
     642    case QEvent::MouseMove:
    651643        if (isVisible()) {
    652644            QMouseEvent *m = static_cast<QMouseEvent *>(e);
     
    655647            if (vector.manhattanLength() > 9 && blockMouseReleaseTimer.isActive())
    656648                blockMouseReleaseTimer.stop();
     649            QModelIndex indexUnderMouse = view->indexAt(m->pos());
     650            if (indexUnderMouse.isValid() && indexUnderMouse != view->currentIndex()
     651                    && !QComboBoxDelegate::isSeparator(indexUnderMouse)) {
     652                view->setCurrentIndex(indexUnderMouse);
     653            }
    657654        }
    658655        break;
    659     }
    660656    case QEvent::MouseButtonRelease: {
    661657        QMouseEvent *m = static_cast<QMouseEvent *>(e);
     
    863859
    864860    \ingroup basicwidgets
    865     \mainclass
     861
    866862
    867863    A QComboBox provides a means of presenting a list of options to the user
     
    936932    setLayoutItemMargins(QStyle::SE_ComboBoxLayoutItem);
    937933    q->setModel(new QStandardItemModel(0, 1, q));
    938     q->setAttribute(Qt::WA_InputMethodEnabled);
     934    if (!q->isEditable())
     935        q->setAttribute(Qt::WA_InputMethodEnabled, false);
     936    else
     937        q->setAttribute(Qt::WA_InputMethodEnabled);
    939938}
    940939
     
    948947    container->itemView()->setModel(model);
    949948    container->itemView()->setTextElideMode(Qt::ElideMiddle);
    950     updateDelegate();
     949    updateDelegate(true);
    951950    updateLayoutDirection();
     951    updateViewContainerPaletteAndOpacity();
    952952    QObject::connect(container, SIGNAL(itemSelected(QModelIndex)),
    953953                     q, SLOT(_q_itemSelected(QModelIndex)));
     
    986986}
    987987
    988 void QComboBoxPrivate::_q_rowsAboutToBeInserted(const QModelIndex & parent,
    989                                              int /*start*/, int /*end*/)
    990 {
    991     if (parent != root)
    992         return;
    993     indexBeforeChange = currentIndex.row();
    994 }
    995 
    996988void QComboBoxPrivate::_q_rowsInserted(const QModelIndex &parent, int start, int end)
    997989{
     
    10161008}
    10171009
    1018 void QComboBoxPrivate::_q_rowsAboutToBeRemoved(const QModelIndex &parent, int /*start*/, int /*end*/)
    1019 {
    1020     if (parent != root)
    1021         return;
    1022 
     1010void QComboBoxPrivate::_q_updateIndexBeforeChange()
     1011{
    10231012    indexBeforeChange = currentIndex.row();
    10241013}
     
    10511040}
    10521041
     1042
     1043void QComboBoxPrivate::updateViewContainerPaletteAndOpacity()
     1044{
     1045    if (!container)
     1046        return;
     1047    Q_Q(QComboBox);
     1048    QStyleOptionComboBox opt;
     1049    q->initStyleOption(&opt);
     1050#ifndef QT_NO_MENU
     1051    if (q->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, q)) {
     1052        QMenu menu;
     1053        menu.ensurePolished();
     1054        container->setPalette(menu.palette());
     1055        container->setWindowOpacity(menu.windowOpacity());
     1056    } else
     1057#endif
     1058    {
     1059        container->setPalette(q->palette());
     1060        container->setWindowOpacity(1.0);
     1061    }
     1062}
    10531063
    10541064/*!
     
    11051115}
    11061116
     1117Qt::MatchFlags QComboBoxPrivate::matchFlags() const
     1118{
     1119    // Base how duplicates are determined on the autocompletion case sensitivity
     1120    Qt::MatchFlags flags = Qt::MatchFixedString;
     1121#ifndef QT_NO_COMPLETER
     1122    if (!lineEdit->completer() || lineEdit->completer()->caseSensitivity() == Qt::CaseSensitive)
     1123#endif
     1124        flags |= Qt::MatchCaseSensitive;
     1125    return flags;
     1126}
     1127
     1128
     1129void QComboBoxPrivate::_q_editingFinished()
     1130{
     1131    Q_Q(QComboBox);
     1132    if (lineEdit && !lineEdit->text().isEmpty()) {
     1133        //here we just check if the current item was entered
     1134        const int index = q_func()->findText(lineEdit->text(), matchFlags());
     1135        if (index != -1 && itemText(currentIndex) != lineEdit->text()) {
     1136            q->setCurrentIndex(index);
     1137            emitActivated(currentIndex);
     1138        }
     1139    }
     1140
     1141}
     1142
    11071143void QComboBoxPrivate::_q_returnPressed()
    11081144{
     
    11171153        int index = -1;
    11181154        if (!duplicatesEnabled) {
    1119             // Base how duplicates are determined on the autocompletion case sensitivity
    1120             Qt::MatchFlags flags = Qt::MatchFixedString;
    1121 #ifndef QT_NO_COMPLETER
    1122             if (!lineEdit->completer() || lineEdit->completer()->caseSensitivity() == Qt::CaseSensitive)
    1123 #endif
    1124                 flags |= Qt::MatchCaseSensitive;
    1125             index = q->findText(text, flags);
     1155            index = q->findText(text, matchFlags());
    11261156            if (index != -1) {
    11271157                q->setCurrentIndex(index);
     
    12251255    Q_D(QComboBox);
    12261256
    1227     disconnect(d->model, SIGNAL(destroyed()),
    1228                this, SLOT(_q_modelDestroyed()));
     1257    QT_TRY {
     1258        disconnect(d->model, SIGNAL(destroyed()),
     1259                this, SLOT(_q_modelDestroyed()));
     1260    } QT_CATCH(...) {
     1261        ; // objects can't throw in destructor
     1262    }
    12291263}
    12301264
     
    15681602}
    15691603
    1570 void QComboBoxPrivate::updateDelegate()
     1604/*! \internal
     1605    update the default delegate
     1606    depending on the style's SH_ComboBox_Popup hint, we use a different default delegate.
     1607
     1608    but we do not change the delegate is the combobox use a custom delegate,
     1609    unless \a force is set to true.
     1610 */
     1611void QComboBoxPrivate::updateDelegate(bool force)
    15711612{
    15721613    Q_Q(QComboBox);
    15731614    QStyleOptionComboBox opt;
    15741615    q->initStyleOption(&opt);
    1575     if (q->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, q))
    1576         q->setItemDelegate(new QComboMenuDelegate(q->view(), q));
    1577     else
    1578         q->setItemDelegate(new QComboBoxDelegate(q->view(), q));
     1616    if (q->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, q)) {
     1617        if (force || qobject_cast<QComboBoxDelegate *>(q->itemDelegate()))
     1618            q->setItemDelegate(new QComboMenuDelegate(q->view(), q));
     1619    } else {
     1620        if (force || qobject_cast<QComboMenuDelegate *>(q->itemDelegate()))
     1621            q->setItemDelegate(new QComboBoxDelegate(q->view(), q));
     1622    }
    15791623}
    15801624
     
    16441688        d->lineEdit->setParent(this);
    16451689    connect(d->lineEdit, SIGNAL(returnPressed()), this, SLOT(_q_returnPressed()));
     1690    connect(d->lineEdit, SIGNAL(editingFinished()), this, SLOT(_q_editingFinished()));
    16461691    connect(d->lineEdit, SIGNAL(textChanged(QString)), this, SIGNAL(editTextChanged(QString)));
    16471692#ifdef QT3_SUPPORT
     
    18271872                   this, SLOT(_q_dataChanged(QModelIndex,QModelIndex)));
    18281873        disconnect(d->model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)),
    1829                    this, SLOT(_q_rowsAboutToBeInserted(QModelIndex,int,int)));
     1874                   this, SLOT(_q_updateIndexBeforeChange()));
    18301875        disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
    18311876                   this, SLOT(_q_rowsInserted(QModelIndex,int,int)));
    18321877        disconnect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
    1833                    this, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int)));
     1878                   this, SLOT(_q_updateIndexBeforeChange()));
    18341879        disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
    18351880                   this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
    18361881        disconnect(d->model, SIGNAL(destroyed()),
    18371882                   this, SLOT(_q_modelDestroyed()));
     1883        disconnect(d->model, SIGNAL(modelAboutToBeReset()),
     1884                   this, SLOT(_q_updateIndexBeforeChange()));
    18381885        disconnect(d->model, SIGNAL(modelReset()),
    18391886                   this, SLOT(_q_modelReset()));
     
    18471894            this, SLOT(_q_dataChanged(QModelIndex,QModelIndex)));
    18481895    connect(model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)),
    1849             this, SLOT(_q_rowsAboutToBeInserted(QModelIndex,int,int)));
     1896            this, SLOT(_q_updateIndexBeforeChange()));
    18501897    connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)),
    18511898            this, SLOT(_q_rowsInserted(QModelIndex,int,int)));
    18521899    connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
    1853             this, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int)));
     1900            this, SLOT(_q_updateIndexBeforeChange()));
    18541901    connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
    18551902            this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
    18561903    connect(model, SIGNAL(destroyed()),
    18571904            this, SLOT(_q_modelDestroyed()));
     1905    connect(model, SIGNAL(modelAboutToBeReset()),
     1906            this, SLOT(_q_updateIndexBeforeChange()));
    18581907    connect(model, SIGNAL(modelReset()),
    18591908            this, SLOT(_q_modelReset()));
     
    19361985        QString newText = q->itemText(currentIndex.row());
    19371986        if (lineEdit->text() != newText)
    1938             lineEdit->setText(q->itemText(currentIndex.row()));
     1987            lineEdit->setText(newText);
    19391988        updateLineEditGeometry();
    19401989    }
     
    21332182    Removes the item at the given \a index from the combobox.
    21342183    This will update the current index if the index is removed.
     2184
     2185    This function does nothing if \a index is out of range.
    21352186*/
    21362187void QComboBox::removeItem(int index)
    21372188{
    2138     Q_ASSERT(index >= 0 && index < count());
    2139     Q_D(QComboBox);
     2189    Q_D(QComboBox);
     2190    if (index < 0 || index >= count())
     2191        return;
    21402192    d->model->removeRows(index, 1, d->root);
    21412193}
     
    24022454    container->setGeometry(listRect);
    24032455
    2404     bool updatesEnabled = container->updatesEnabled();
     2456#ifndef Q_WS_MAC
     2457    const bool updatesEnabled = container->updatesEnabled();
     2458#endif
     2459
    24052460#if defined(Q_WS_WIN) && !defined(QT_NO_EFFECTS)
    24062461    bool scrollDown = (listRect.topLeft() == below);
    2407     if (QApplication::isEffectEnabled(Qt::UI_AnimateCombo) 
     2462    if (QApplication::isEffectEnabled(Qt::UI_AnimateCombo)
    24082463        && !style->styleHint(QStyle::SH_ComboBox_Popup, &opt, this) && !window()->testAttribute(Qt::WA_DontShowOnScreen))
    24092464        qScrollEffect(container, scrollDown ? QEffects::DownScroll : QEffects::UpScroll, 150);
    24102465#endif
     2466
     2467// Don't disable updates on Mac OS X. Windows are displayed immediately on this platform,
     2468// which means that the window will be visible before the call to container->show() returns.
     2469// If updates are disabled at this point we'll miss our chance at painting the popup
     2470// menu before it's shown, causing flicker since the window then displays the standard gray
     2471// background.
     2472#ifndef Q_WS_MAC
    24112473    container->setUpdatesEnabled(false);
     2474#endif
     2475
    24122476    container->raise();
    24132477    container->show();
     
    24202484                             : QAbstractItemView::EnsureVisible);
    24212485
     2486#ifndef Q_WS_MAC
    24222487    container->setUpdatesEnabled(updatesEnabled);
     2488#endif
     2489
    24232490    container->update();
     2491#ifdef QT_KEYPAD_NAVIGATION
     2492    if (QApplication::keypadNavigationEnabled())
     2493        view()->setEditFocus(true);
     2494#endif
    24242495}
    24252496
     
    25732644        break;
    25742645    case QEvent::PaletteChange: {
    2575         QStyleOptionComboBox opt;
    2576         initStyleOption(&opt);
    2577 #ifndef QT_NO_MENU
    2578         if (style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, this)) {
    2579             QMenu menu;
    2580             menu.ensurePolished();
    2581             d->viewContainer()->setPalette(menu.palette());
    2582             d->viewContainer()->setWindowOpacity(menu.windowOpacity());
    2583         } else
    2584 #endif
    2585         {
    2586             d->viewContainer()->setPalette(palette());
    2587             d->viewContainer()->setWindowOpacity(1.0);
    2588         }
     2646        d->updateViewContainerPaletteAndOpacity();
    25892647        break;
    25902648    }
  • trunk/src/gui/widgets/qcombobox.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5353
    5454QT_MODULE(Gui)
    55 
    5655#ifndef QT_NO_COMBOBOX
    5756
     
    306305    Q_PRIVATE_SLOT(d_func(), void _q_emitHighlighted(const QModelIndex &))
    307306    Q_PRIVATE_SLOT(d_func(), void _q_emitCurrentIndexChanged(const QModelIndex &index))
     307    Q_PRIVATE_SLOT(d_func(), void _q_editingFinished())
    308308    Q_PRIVATE_SLOT(d_func(), void _q_returnPressed())
    309309    Q_PRIVATE_SLOT(d_func(), void _q_resetButton())
    310310    Q_PRIVATE_SLOT(d_func(), void _q_dataChanged(const QModelIndex &, const QModelIndex &))
    311     Q_PRIVATE_SLOT(d_func(), void _q_rowsAboutToBeInserted(const QModelIndex & parent, int start, int end))
     311    Q_PRIVATE_SLOT(d_func(), void _q_updateIndexBeforeChange())
    312312    Q_PRIVATE_SLOT(d_func(), void _q_rowsInserted(const QModelIndex & parent, int start, int end))
    313     Q_PRIVATE_SLOT(d_func(), void _q_rowsAboutToBeRemoved(const QModelIndex & parent, int start, int end))
    314313    Q_PRIVATE_SLOT(d_func(), void _q_rowsRemoved(const QModelIndex & parent, int start, int end))
    315314    Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed())
  • trunk/src/gui/widgets/qcombobox_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    7878
    7979QT_BEGIN_NAMESPACE
     80
     81class QAction;
    8082
    8183class QComboBoxListView : public QListView
     
    230232    void scrollItemView(int action);
    231233    void updateScrollers();
    232     void setCurrentIndex(const QModelIndex &index);
    233234    void viewDestroyed();
    234235
     
    254255    QComboBoxPrivateScroller *top;
    255256    QComboBoxPrivateScroller *bottom;
     257#ifdef QT_SOFTKEYS_ENABLED
     258    QAction *selectAction;
     259    QAction *cancelAction;
     260#endif
    256261};
    257262
    258263class QComboMenuDelegate : public QAbstractItemDelegate
    259 {
     264{ Q_OBJECT
    260265public:
    261266    QComboMenuDelegate(QObject *parent, QComboBox *cmb) : QAbstractItemDelegate(parent), mCombo(cmb) {}
     
    286291// be other side effects from using the new class
    287292class QComboBoxDelegate : public QItemDelegate
    288 {
     293{ Q_OBJECT
    289294public:
    290295    QComboBoxDelegate(QObject *parent, QComboBox *cmb) : QItemDelegate(parent), mCombo(cmb) {}
    291296
    292297    static bool isSeparator(const QModelIndex &index) {
    293         return index.data(Qt::AccessibleDescriptionRole).toString() == QString::fromLatin1("separator");
     298        return index.data(Qt::AccessibleDescriptionRole).toString() == QLatin1String("separator");
    294299    }
    295300    static void setSeparator(QAbstractItemModel *model, const QModelIndex &index) {
     
    338343    QComboBoxPrivateContainer* viewContainer();
    339344    void updateLineEditGeometry();
     345    Qt::MatchFlags matchFlags() const;
     346    void _q_editingFinished();
    340347    void _q_returnPressed();
    341348    void _q_complete();
     
    352359    void _q_resetButton();
    353360    void _q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
    354     void _q_rowsAboutToBeInserted(const QModelIndex & parent, int start, int end);
     361    void _q_updateIndexBeforeChange();
    355362    void _q_rowsInserted(const QModelIndex & parent, int start, int end);
    356     void _q_rowsAboutToBeRemoved(const QModelIndex & parent, int start, int end);
    357363    void _q_rowsRemoved(const QModelIndex & parent, int start, int end);
    358364    void updateArrow(QStyle::StateFlag state);
     
    368374    void updateLayoutDirection();
    369375    void setCurrentIndex(const QModelIndex &index);
    370     void updateDelegate();
     376    void updateDelegate(bool force = false);
    371377    void keyboardSearchString(const QString &text);
    372378    void modelChanged();
     379    void updateViewContainerPaletteAndOpacity();
    373380
    374381    QAbstractItemModel *model;
  • trunk/src/gui/widgets/qcommandlinkbutton.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5858
    5959    \ingroup basicwidgets
    60     \mainclass
     60
    6161
    6262    The command link is a new control that was introduced by Windows Vista. It's
     
    146146        font.setPointSizeF(9.0);
    147147    }
    148     return font;
     148
     149    // Note the font will be resolved against
     150    // QPainters font, so we need to restore the mask
     151    int resolve_mask = font.resolve_mask;
     152    QFont modifiedFont = q->font().resolve(font);
     153    modifiedFont.detach();
     154    modifiedFont.resolve_mask = resolve_mask;
     155    return modifiedFont;
    149156}
    150157
     
    154161    QFont font = q->font();
    155162    font.setPointSizeF(9.0);
    156     return font;
     163
     164    // Note the font will be resolved against
     165    // QPainters font, so we need to restore the mask
     166    int resolve_mask = font.resolve_mask;
     167    QFont modifiedFont = q->font().resolve(font);
     168    modifiedFont.detach();
     169    modifiedFont.resolve_mask = resolve_mask;
     170    return modifiedFont;
    157171}
    158172
     
    203217
    204218    q->setIconSize(QSize(20, 20));
    205     q->setIcon(q->style()->standardIcon(QStyle::SP_CommandLink));
     219    QStyleOptionButton opt;
     220    q->initStyleOption(&opt);
     221    q->setIcon(q->style()->standardIcon(QStyle::SP_CommandLink, &opt));
    206222}
    207223
     
    311327    int heightWithoutDescription = d->descriptionOffset() + d->bottomMargin();
    312328    // find the width available for the description area
    313     return heightWithoutDescription + d->descriptionHeight(width);
     329    return qMax(heightWithoutDescription + d->descriptionHeight(width),
     330                iconSize().height() + d->topMargin() + d->bottomMargin());
    314331}
    315332
  • trunk/src/gui/widgets/qcommandlinkbutton.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qdatetimeedit.cpp

    r2 r561  
    1 /****************************************************************************)
     1/****************************************************************************
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    7676
    7777  \ingroup basicwidgets
    78   \mainclass
     78
    7979
    8080  QDateTimeEdit allows the user to edit dates by using the keyboard or
     
    221221  \brief the QDateTime that is set in the QDateTimeEdit
    222222
     223  When setting this property the timespec of the QDateTimeEdit remains the same
     224  and the timespec of the new QDateTime is ignored.
     225
    223226  By default, this property contains a date that refers to January 1,
    224227  2000 and a time of 00:00:00 and 0 milliseconds.
     
    240243        if (!(d->sections & DateSections_Mask))
    241244            setDateRange(datetime.date(), datetime.date());
    242         d->setValue(QVariant(datetime), EmitIfChanged);
     245        d->setValue(QDateTime(datetime.date(), datetime.time(), d->spec), EmitIfChanged);
    243246    }
    244247}
     
    933936    \brief the current timespec used by the date time edit.
    934937    \since 4.4
    935 
    936     All dates/passed to the date time edit will be converted to this
    937     timespec.
    938938*/
    939939
     
    10871087                //hide cursor
    10881088                d->edit->d_func()->setCursorVisible(false);
    1089                 if (d->edit->d_func()->cursorTimer > 0)
    1090                     killTimer(d->edit->d_func()->cursorTimer);
    1091                 d->edit->d_func()->cursorTimer = 0;
    1092 
     1089                d->edit->d_func()->control->setCursorBlinkPeriod(0);
    10931090                d->setSelected(0);
    10941091            }
     
    11111108            //hide cursor
    11121109            d->edit->d_func()->setCursorVisible(false);
    1113             if (d->edit->d_func()->cursorTimer > 0)
    1114                 killTimer(d->edit->d_func()->cursorTimer);
    1115             d->edit->d_func()->cursorTimer = 0;
    1116 
     1110            d->edit->d_func()->control->setCursorBlinkPeriod(0);
    11171111            d->setSelected(0);
    11181112            oldCurrent = 0;
     
    11271121    case Qt::Key_Right:
    11281122        if (event->key() == Qt::Key_Left || event->key() == Qt::Key_Right) {
     1123            if (
    11291124#ifdef QT_KEYPAD_NAVIGATION
    1130             if (!QApplication::keypadNavigationEnabled() || !hasEditFocus()) {
    1131                 select = false;
    1132                 break;
    1133             }
    1134 #else
    1135             if (!(event->modifiers() & Qt::ControlModifier)) {
     1125                QApplication::keypadNavigationEnabled() && !hasEditFocus()
     1126                || !QApplication::keypadNavigationEnabled() &&
     1127#endif
     1128                !(event->modifiers() & Qt::ControlModifier)) {
    11361129                select = false;
    11371130                break;
    11381131            }
    11391132#ifdef Q_WS_MAC
    1140             else {
     1133            else
     1134#ifdef QT_KEYPAD_NAVIGATION
     1135                if (!QApplication::keypadNavigationEnabled())
     1136#endif
     1137            {
    11411138                select = (event->modifiers() & Qt::ShiftModifier);
    11421139                break;
    11431140            }
    11441141#endif
    1145 #endif // QT_KEYPAD_NAVIGATION
    11461142        }
    11471143        // else fall through
     
    15111507
    15121508  \ingroup basicwidgets
    1513   \mainclass
     1509
    15141510
    15151511  Many of the properties and functions provided by QTimeEdit are implemented in
     
    15731569
    15741570  \ingroup basicwidgets
    1575   \mainclass
     1571
    15761572
    15771573  Many of the properties and functions provided by QDateEdit are implemented in
     
    16481644    currentSectionIndex = FirstSectionIndex;
    16491645
    1650     layoutDirection = QApplication::layoutDirection();
    16511646    first.type = FirstSection;
    16521647    last.type = LastSection;
     
    19351930/*!
    19361931  \internal
    1937   \reimp
    19381932*/
    19391933
     
    19461940/*!
    19471941  \internal
    1948   \reimp
    19491942
    19501943  This function's name is slightly confusing; it is not to be confused
     
    21042097/*!
    21052098  \internal
    2106   \reimp
    21072099*/
    21082100
     
    21342126/*!
    21352127  \internal
    2136   \reimp
    21372128*/
    21382129
     
    22792270    optCombo.init(this);
    22802271    optCombo.editable = true;
     2272        optCombo.frame = opt.frame;
    22812273    optCombo.subControls = opt.subControls;
    22822274    optCombo.activeSubControls = opt.activeSubControls;
     
    23912383#endif
    23922384    updateTimeSpec();
     2385    q->setInputMethodHints(Qt::ImhPreferNumbers);
    23932386    setLayoutItemMargins(QStyle::SE_DateTimeEditLayoutItem);
    23942387}
  • trunk/src/gui/widgets/qdatetimeedit.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qdatetimeedit_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    9090                                   bool fixup = false) const;
    9191    void clearSection(int index);
    92     virtual QString displayText() const { return edit->displayText(); } // this is from QDateTimeParser
     92    virtual QString displayText() const { return edit->text(); } // this is from QDateTimeParser
    9393
    9494    int absoluteIndex(QDateTimeEdit::Section s, int index) const;
     
    133133
    134134    QString defaultDateFormat, defaultTimeFormat, defaultDateTimeFormat, unreversedFormat;
    135     Qt::LayoutDirection layoutDirection;
    136135    mutable QVariant conflictGuard;
    137136    bool hasHadFocus, formatExplicitlySet, calendarPopup;
  • trunk/src/gui/widgets/qdial.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6060#include "qaccessible.h"
    6161#endif
     62#include <qmath.h>
    6263
    6364QT_BEGIN_NAMESPACE
     
    136137    double yy = (double)q->height()/2.0 - p.y();
    137138    double xx = (double)p.x() - q->width()/2.0;
    138     double a = (xx || yy) ? atan2(yy, xx) : 0;
     139    double a = (xx || yy) ? qAtan2(yy, xx) : 0;
    139140
    140141    if (a < Q_PI / -2)
     
    169170
    170171    \ingroup basicwidgets
    171     \mainclass
     172
    172173
    173174    QDial is used when the user needs to control a value within a
  • trunk/src/gui/widgets/qdial.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qdialogbuttonbox.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4747#include <QtGui/qapplication.h>
    4848#include <QtGui/private/qwidget_p.h>
     49#include <QtGui/qaction.h>
    4950
    5051#include "qdialogbuttonbox.h"
     52
     53#ifdef QT_SOFTKEYS_ENABLED
     54#include <QtGui/qaction.h>
     55#endif
     56
    5157
    5258QT_BEGIN_NAMESPACE
     
    5864    layout that is appropriate to the current widget style.
    5965
    60     \ingroup application
    61     \mainclass
     66    \ingroup dialog-classes
     67
    6268
    6369    Dialogs and message boxes typically present buttons in a layout that
     
    255261};
    256262
     263class QDialogButtonEnabledProxy : public QObject
     264{
     265public:
     266    QDialogButtonEnabledProxy(QObject *parent, QWidget *src, QAction *trg) : QObject(parent), source(src), target(trg)
     267    {
     268        source->installEventFilter(this);
     269        target->setEnabled(source->isEnabled());
     270    }
     271    ~QDialogButtonEnabledProxy()
     272    {
     273        source->removeEventFilter(this);
     274    }
     275    bool eventFilter(QObject *object, QEvent *event)
     276    {
     277        if (object == source && event->type() == QEvent::EnabledChange) {
     278            target->setEnabled(source->isEnabled());
     279        }
     280        return false;
     281    };
     282private:
     283    QWidget *source;
     284    QAction *target;
     285};
     286
     287
    257288class QDialogButtonBoxPrivate : public QWidgetPrivate
    258289{
     
    264295    QList<QAbstractButton *> buttonLists[QDialogButtonBox::NRoles];
    265296    QHash<QPushButton *, QDialogButtonBox::StandardButton> standardButtonHash;
     297#ifdef QT_SOFTKEYS_ENABLED
     298    QHash<QAbstractButton *, QAction *> softKeyActions;
     299#endif
    266300
    267301    Qt::Orientation orientation;
     
    283317    void retranslateStrings();
    284318    const char *standardButtonText(QDialogButtonBox::StandardButton sbutton) const;
     319#ifdef QT_SOFTKEYS_ENABLED
     320    QAction *createSoftKey(QAbstractButton *button, QDialogButtonBox::ButtonRole role);
     321#endif
    285322};
    286323
     
    305342    }
    306343
    307         int left, top, right, bottom;
     344    int left, top, right, bottom;
    308345    setLayoutItemMargins(QStyle::SE_PushButtonLayoutItem);
    309         getLayoutItemMargins(&left, &top, &right, &bottom);
     346    getLayoutItemMargins(&left, &top, &right, &bottom);
    310347    buttonLayout->setContentsMargins(-left, -top, -right, -bottom);
    311348
     
    346383{
    347384    Q_Q(QDialogButtonBox);
    348     const int MacGap = 36 - 8;  // 8 is the default gap between a widget and a spacer item
     385    const int MacGap = 36 - 8;    // 8 is the default gap between a widget and a spacer item
    349386
    350387    for (int i = buttonLayout->count() - 1; i >= 0; --i) {
     
    537574    QObject::connect(button, SIGNAL(destroyed()), q, SLOT(_q_handleButtonDestroyed()));
    538575    buttonLists[role].append(button);
     576#ifdef QT_SOFTKEYS_ENABLED
     577    QAction *action = createSoftKey(button, role);
     578    softKeyActions.insert(button, action);
     579    new QDialogButtonEnabledProxy(action, button, action);
     580#endif
    539581    if (doLayout)
    540582        layoutButtons();
    541583}
     584
     585#ifdef QT_SOFTKEYS_ENABLED
     586QAction* QDialogButtonBoxPrivate::createSoftKey(QAbstractButton *button, QDialogButtonBox::ButtonRole role)
     587{
     588    Q_Q(QDialogButtonBox);
     589    QAction::SoftKeyRole softkeyRole;
     590
     591    QAction *action = new QAction(button->text(), button);
     592
     593    switch (role) {
     594    case ApplyRole:
     595    case AcceptRole:
     596    case YesRole:
     597    case ActionRole:
     598    case HelpRole:
     599        softkeyRole = QAction::PositiveSoftKey;
     600        break;
     601    case RejectRole:
     602    case DestructiveRole:
     603    case NoRole:
     604    case ResetRole:
     605        softkeyRole = QAction::NegativeSoftKey;
     606        break;
     607    default:
     608        break;
     609    }
     610    QObject::connect(action, SIGNAL(triggered()), button, SIGNAL(clicked()));
     611    action->setSoftKeyRole(softkeyRole);
     612
     613
     614    QWidget *dialog = 0;
     615    QWidget *p = q;
     616    while (p && !p->isWindow()) {
     617        p = p->parentWidget();
     618        if ((dialog = qobject_cast<QDialog *>(p)))
     619            break;
     620    }
     621
     622    if (dialog) {
     623        dialog->addAction(action);
     624    } else {
     625        q->addAction(action);
     626    }
     627
     628    return action;
     629}
     630#endif
    542631
    543632void QDialogButtonBoxPrivate::createStandardButtons(QDialogButtonBox::StandardButtons buttons)
     
    632721            QPushButton *button = it.key();
    633722            button->setText(QDialogButtonBox::tr(buttonText));
     723#ifdef QT_SOFTKEYS_ENABLED
     724            QAction *action = softKeyActions.value(button, 0);
     725            if (action)
     726                action->setText(button->text());
     727#endif
    634728        }
    635729        ++it;
     
    824918{
    825919    Q_D(QDialogButtonBox);
     920#ifdef QT_SOFTKEYS_ENABLED
     921    // Delete softkey actions as they have the buttons as parents
     922    qDeleteAll(d->softKeyActions.values());
     923    d->softKeyActions.clear();
     924#endif
    826925    // Remove the created standard buttons, they should be in the other lists, which will
    827926    // do the deletion
     
    9011000        }
    9021001    }
     1002#ifdef QT_SOFTKEYS_ENABLED
     1003    QAction *action = d->softKeyActions.value(button, 0);
     1004    if (action) {
     1005        d->softKeyActions.remove(button);
     1006        delete action;
     1007    }
     1008#endif
    9031009    if (!d->internalRemove)
    9041010        button->setParent(0);
     
    9691075{
    9701076    Q_D(QDialogButtonBox);
     1077#ifdef QT_SOFTKEYS_ENABLED
     1078    // Delete softkey actions since they have the buttons as parents
     1079    qDeleteAll(d->softKeyActions.values());
     1080    d->softKeyActions.clear();
     1081#endif
    9711082    // Clear out all the old standard buttons, then recreate them.
    9721083    qDeleteAll(d->standardButtonHash.keys());
     
    11261237        if (!hasDefault && firstAcceptButton)
    11271238            firstAcceptButton->setDefault(true);
     1239#ifdef QT_SOFTKEYS_ENABLED
     1240        if (dialog)
     1241            setFixedSize(0,0);
     1242#endif
    11281243    }else if (event->type() == QEvent::LanguageChange) {
    11291244        d->retranslateStrings();
    11301245    }
     1246#ifdef QT_SOFTKEYS_ENABLED
     1247    else if (event->type() == QEvent::ParentChange) {
     1248        QWidget *dialog = 0;
     1249        QWidget *p = this;
     1250        while (p && !p->isWindow()) {
     1251            p = p->parentWidget();
     1252            if ((dialog = qobject_cast<QDialog *>(p)))
     1253                break;
     1254        }
     1255
     1256        // If the parent changes, then move the softkeys
     1257        for (QHash<QAbstractButton *, QAction *>::const_iterator it = d->softKeyActions.constBegin();
     1258            it != d->softKeyActions.constEnd(); ++it) {
     1259            QAction *current = it.value();
     1260            QList<QWidget *> widgets = current->associatedWidgets();
     1261            foreach (QWidget *w, widgets)
     1262                w->removeAction(current);
     1263            if (dialog)
     1264                dialog->addAction(current);
     1265            else
     1266                addAction(current);
     1267        }
     1268    }
     1269#endif
    11311270
    11321271    return QWidget::event(event);
  • trunk/src/gui/widgets/qdialogbuttonbox.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qdockarealayout.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    156156}
    157157
     158bool QDockAreaLayoutItem::hasFixedSize(Qt::Orientation o) const
     159{
     160    return perp(o, minimumSize()) == perp(o, maximumSize());
     161}
     162
    158163bool QDockAreaLayoutItem::expansive(Qt::Orientation o) const
    159164{
     
    217222
    218223QDockAreaLayoutInfo::QDockAreaLayoutInfo()
    219     : sep(0), dockPos(QInternal::LeftDock), o(Qt::Horizontal), rect(0, 0, -1, -1), mainWindow(0)
    220 #ifndef QT_NO_TABBAR
    221     , tabbed(false), tabBar(0), tabBarShape(QTabBar::RoundedSouth)
     224    : sep(0), dockPos(QInternal::LeftDock), o(Qt::Horizontal), mainWindow(0)
     225#ifndef QT_NO_TABBAR
     226    , tabbed(false), tabBar(0), tabBarShape(QTabBar::RoundedSouth), tabBarVisible(false)
    222227#endif
    223228{
     
    227232                                            Qt::Orientation _o, int tbshape,
    228233                                            QMainWindow *window)
    229     : sep(_sep), dockPos(_dockPos), o(_o), rect(0, 0, -1, -1), mainWindow(window)
    230 #ifndef QT_NO_TABBAR
    231     , tabbed(false), tabBar(0), tabBarShape(static_cast<QTabBar::Shape>(tbshape))
     234    : sep(_sep), dockPos(_dockPos), o(_o), mainWindow(window)
     235#ifndef QT_NO_TABBAR
     236    , tabbed(false), tabBar(0), tabBarShape(static_cast<QTabBar::Shape>(tbshape)), tabBarVisible(false)
    232237#endif
    233238{
     
    245250{
    246251    item_list.clear();
    247     rect = QRect(0, 0, -1, -1);
     252    rect = QRect();
    248253#ifndef QT_NO_TABBAR
    249254    tabbed = false;
     
    389394
    390395    int a = 0, b = 0;
    391     bool prev_gap = false;
    392     bool first = true;
    393396    int min_perp = 0;
    394397    int max_perp = QWIDGETSIZE_MAX;
     398    const QDockAreaLayoutItem *previous = 0;
    395399    for (int i = 0; i < item_list.size(); ++i) {
    396400        const QDockAreaLayoutItem &item = item_list.at(i);
     
    410414#endif
    411415        {
    412             if (!first && !gap && !prev_gap)
     416            if (previous && !gap && !(previous->flags &  QDockAreaLayoutItem::GapItem)
     417                && !previous->hasFixedSize(o)) {
    413418                a += sep;
     419            }
    414420            a += gap ? item.size : pick(o, size_hint);
    415421        }
    416422        b = qMax(b, perp(o, size_hint));
    417423
    418         prev_gap = gap;
    419         first = false;
     424        previous = &item;
    420425    }
    421426
     
    540545    int last_index = -1;
    541546
    542     bool prev_gap = false;
    543     bool first = true;
     547    const QDockAreaLayoutItem *previous = 0;
    544548    for (int i = 0; i < item_list.size(); ++i) {
    545549        QDockAreaLayoutItem &item = item_list[i];
     
    548552
    549553        bool gap = item.flags & QDockAreaLayoutItem::GapItem;
    550         if (!first && !gap && !prev_gap) {
    551             QLayoutStruct &ls = layout_struct_list[j++];
    552             ls.init();
    553             ls.minimumSize = sep;
    554             ls.maximumSize = sep;
    555             ls.sizeHint = sep;
    556             ls.empty = false;
     554        if (previous && !gap) {
     555            if (!(previous->flags & QDockAreaLayoutItem::GapItem)) {
     556                QLayoutStruct &ls = layout_struct_list[j++];
     557                ls.init();
     558                ls.minimumSize = ls.maximumSize = ls.sizeHint = previous->hasFixedSize(o) ? 0 : sep;
     559                ls.empty = false;
     560            }
    557561        }
    558562
     
    593597
    594598        item.flags &= ~QDockAreaLayoutItem::KeepSize;
    595         prev_gap = gap;
    596         first = false;
     599        previous = &item;
    597600    }
    598601    layout_struct_list.resize(j);
     
    608611
    609612    j = 0;
    610     prev_gap = false;
    611     first = true;
     613    bool prev_gap = false;
     614    bool first = true;
    612615    for (int i = 0; i < item_list.size(); ++i) {
    613616        QDockAreaLayoutItem &item = item_list[i];
     
    922925}
    923926
    924 int QDockAreaLayoutInfo::separatorMove(int index, int delta, QVector<QLayoutStruct> *cache)
     927int QDockAreaLayoutInfo::separatorMove(int index, int delta)
    925928{
    926929#ifndef QT_NO_TABBAR
     
    928931#endif
    929932
    930     if (cache->isEmpty()) {
    931         QVector<QLayoutStruct> &list = *cache;
    932         list.resize(item_list.size());
    933         for (int i = 0; i < item_list.size(); ++i) {
    934             const QDockAreaLayoutItem &item = item_list.at(i);
    935             QLayoutStruct &ls = list[i];
    936             Q_ASSERT(!(item.flags & QDockAreaLayoutItem::GapItem));
    937             if (item.skip()) {
    938                 ls.empty = true;
    939             } else {
    940                 ls.empty = false;
    941                 ls.pos = item.pos;
    942                 ls.size = item.size;
    943                 ls.minimumSize = pick(o, item.minimumSize());
    944                 ls.maximumSize = pick(o, item.maximumSize());
    945             }
    946         }
    947     }
    948 
    949     QVector<QLayoutStruct> list = *cache;
    950 
    951     delta = separatorMoveHelper(list, index, delta, sep);
    952 
    953     for (int i = 0; i < item_list.size(); ++i) {
     933    QVector<QLayoutStruct> list(item_list.size());
     934    for (int i = 0; i < list.size(); ++i) {
     935        const QDockAreaLayoutItem &item = item_list.at(i);
     936        QLayoutStruct &ls = list[i];
     937        Q_ASSERT(!(item.flags & QDockAreaLayoutItem::GapItem));
     938        if (item.skip()) {
     939            ls.empty = true;
     940        } else {
     941            const int separatorSpace = item.hasFixedSize(o) ? 0 : sep;
     942            ls.empty = false;
     943            ls.pos = item.pos;
     944            ls.size = item.size + separatorSpace;
     945            ls.minimumSize = pick(o, item.minimumSize()) + separatorSpace;
     946            ls.maximumSize = pick(o, item.maximumSize()) + separatorSpace;
     947
     948        }
     949    }
     950
     951    //the separator space has been added to the size, so we pass 0 as a parameter
     952    delta = separatorMoveHelper(list, index, delta, 0 /*separator*/);
     953
     954    for (int i = 0; i < list.size(); ++i) {
    954955        QDockAreaLayoutItem &item = item_list[i];
    955956        if (item.skip())
    956957            continue;
    957958        QLayoutStruct &ls = list[i];
    958         item.size = ls.size;
     959        const int separatorSpace = item.hasFixedSize(o) ? 0 : sep;
     960        item.size = ls.size - separatorSpace;
    959961        item.pos = ls.pos;
    960 
    961962        if (item.subinfo != 0) {
    962963            item.subinfo->rect = itemRect(i);
     
    994995}
    995996
    996 void QDockAreaLayoutInfo::remove(QList<int> path)
     997void QDockAreaLayoutInfo::remove(const QList<int> &path)
    997998{
    998999    Q_ASSERT(!path.isEmpty());
    9991000
    10001001    if (path.count() > 1) {
    1001         int index = path.takeFirst();
     1002        const int index = path.first();
    10021003        QDockAreaLayoutItem &item = item_list[index];
    10031004        Q_ASSERT(item.subinfo != 0);
    1004         item.subinfo->remove(path);
     1005        item.subinfo->remove(path.mid(1));
    10051006        unnest(index);
    10061007    } else {
     
    10101011}
    10111012
    1012 QLayoutItem *QDockAreaLayoutInfo::plug(QList<int> path)
     1013QLayoutItem *QDockAreaLayoutInfo::plug(const QList<int> &path)
    10131014{
    10141015    Q_ASSERT(!path.isEmpty());
    10151016
    1016     int index = path.takeFirst();
     1017    int index = path.first();
    10171018    if (index < 0)
    10181019        index = -index - 1;
    10191020
    1020     if (!path.isEmpty()) {
     1021    if (path.count() > 1) {
    10211022        const QDockAreaLayoutItem &item = item_list.at(index);
    10221023        Q_ASSERT(item.subinfo != 0);
    1023         return item.subinfo->plug(path);
     1024        return item.subinfo->plug(path.mid(1));
    10241025    }
    10251026
     
    10591060}
    10601061
    1061 QLayoutItem *QDockAreaLayoutInfo::unplug(QList<int> path)
     1062QLayoutItem *QDockAreaLayoutInfo::unplug(const QList<int> &path)
    10621063{
    10631064    Q_ASSERT(!path.isEmpty());
    10641065
     1066    const int index = path.first();
    10651067    if (path.count() > 1) {
    1066         int index = path.takeFirst();
    10671068        const QDockAreaLayoutItem &item = item_list.at(index);
    10681069        Q_ASSERT(item.subinfo != 0);
    1069         return item.subinfo->unplug(path);
    1070     }
    1071 
    1072     int index = path.first();
     1070        return item.subinfo->unplug(path.mid(1));
     1071    }
     1072
    10731073    QDockAreaLayoutItem &item = item_list[index];
    10741074    int prev = this->prev(index);
     
    11421142}
    11431143
    1144 bool QDockAreaLayoutInfo::insertGap(QList<int> path, QLayoutItem *dockWidgetItem)
     1144bool QDockAreaLayoutInfo::insertGap(const QList<int> &path, QLayoutItem *dockWidgetItem)
    11451145{
    11461146    Q_ASSERT(!path.isEmpty());
    11471147
    11481148    bool insert_tabbed = false;
    1149     int index = path.takeFirst();
     1149    int index = path.first();
    11501150    if (index < 0) {
    11511151        insert_tabbed = true;
     
    11551155//    dump(qDebug() << "insertGap() before:" << index << tabIndex, *this, QString());
    11561156
    1157     if (!path.isEmpty()) {
     1157    if (path.count() > 1) {
    11581158        QDockAreaLayoutItem &item = item_list[index];
    11591159
     
    11681168            QDockAreaLayoutInfo *subinfo = item.subinfo;
    11691169            QLayoutItem *widgetItem = item.widgetItem;
    1170             QRect r = subinfo == 0 ? dockedGeometry(widgetItem->widget()) : subinfo->rect;
     1170            QPlaceHolderItem *placeHolderItem = item.placeHolderItem;
     1171            QRect r = subinfo == 0 ? widgetItem ? dockedGeometry(widgetItem->widget()) : placeHolderItem->topLevelRect : subinfo->rect;
    11711172
    11721173            Qt::Orientation opposite = o == Qt::Horizontal ? Qt::Vertical : Qt::Horizontal;
     
    11771178                = new QDockAreaLayoutInfo(sep, dockPos, opposite, tabBarShape, mainWindow);
    11781179
     1180            //item become a new top-level
    11791181            item.subinfo = new_info;
    11801182            item.widgetItem = 0;
     1183            item.placeHolderItem = 0;
    11811184
    11821185            QDockAreaLayoutItem new_item
    11831186                = widgetItem == 0
    11841187                    ? QDockAreaLayoutItem(subinfo)
    1185                     : QDockAreaLayoutItem(widgetItem);
     1188                    : widgetItem ? QDockAreaLayoutItem(widgetItem) : QDockAreaLayoutItem(placeHolderItem);
    11861189            new_item.size = pick(opposite, r.size());
    11871190            new_item.pos = pick(opposite, r.topLeft());
     
    11941197        }
    11951198
    1196         bool result = item.subinfo->insertGap(path, dockWidgetItem);
    1197         return result;
     1199        return item.subinfo->insertGap(path.mid(1), dockWidgetItem);
    11981200    }
    11991201
     
    12951297}
    12961298
    1297 QDockAreaLayoutInfo *QDockAreaLayoutInfo::info(QList<int> path)
    1298 {
    1299     int index = path.takeFirst();
     1299QDockAreaLayoutInfo *QDockAreaLayoutInfo::info(const QList<int> &path)
     1300{
     1301    int index = path.first();
    13001302    if (index < 0)
    13011303        index = -index - 1;
    13021304    if (index >= item_list.count())
    13031305        return this;
    1304     if (path.isEmpty() || item_list.at(index).subinfo == 0)
     1306    if (path.count() == 1 || item_list[index].subinfo == 0)
    13051307        return this;
    1306     return item_list.at(index).subinfo->info(path);
     1308    return item_list[index].subinfo->info(path.mid(1));
    13071309}
    13081310
     
    13351337}
    13361338
    1337 QRect QDockAreaLayoutInfo::itemRect(QList<int> path) const
     1339QRect QDockAreaLayoutInfo::itemRect(const QList<int> &path) const
    13381340{
    13391341    Q_ASSERT(!path.isEmpty());
    13401342
     1343    const int index = path.first();
    13411344    if (path.count() > 1) {
    1342         const QDockAreaLayoutItem &item = item_list.at(path.takeFirst());
     1345        const QDockAreaLayoutItem &item = item_list.at(index);
    13431346        Q_ASSERT(item.subinfo != 0);
    1344         return item.subinfo->itemRect(path);
    1345     }
    1346 
    1347     return itemRect(path.first());
     1347        return item.subinfo->itemRect(path.mid(1));
     1348    }
     1349
     1350    return itemRect(index);
    13481351}
    13491352
     
    13671370}
    13681371
    1369 QRect QDockAreaLayoutInfo::separatorRect(QList<int> path) const
     1372QRect QDockAreaLayoutInfo::separatorRect(const QList<int> &path) const
    13701373{
    13711374    Q_ASSERT(!path.isEmpty());
    13721375
     1376    const int index = path.first();
    13731377    if (path.count() > 1) {
    1374         const QDockAreaLayoutItem &item = item_list.at(path.takeFirst());
     1378        const QDockAreaLayoutItem &item = item_list.at(index);
    13751379        Q_ASSERT(item.subinfo != 0);
    1376         return item.subinfo->separatorRect(path);
    1377     }
    1378     return separatorRect(path.first());
     1380        return item.subinfo->separatorRect(path.mid(1));
     1381    }
     1382    return separatorRect(index);
    13791383}
    13801384
     
    14091413            continue;
    14101414
    1411         int margin = (sep == 1? 2 : 0);
    1412         if (pos >= item.pos + item.size - margin && item.pos + item.size + sep + margin > pos) {
    1413             QList<int> result;
    1414             result.append(i);
    1415             return result;
     1415        QRect sepRect = separatorRect(i);
     1416        if (!sepRect.isNull() && sep == 1)
     1417            sepRect.adjust(-2, -2, 2, 2);
     1418        //we also make sure we don't find a separator that's not there
     1419        if (sepRect.contains(_pos) && !item.hasFixedSize(o)) {
     1420            return QList<int>() << i;
    14161421        }
    14171422
     
    14791484}
    14801485
     1486bool QDockAreaLayoutInfo::hasFixedSize() const
     1487{
     1488    return perp(o, minimumSize()) == perp(o, maximumSize());
     1489}
     1490
     1491
    14811492void QDockAreaLayoutInfo::apply(bool animate)
    14821493{
    1483     QWidgetAnimator *widgetAnimator = mainWindowLayout()->widgetAnimator;
     1494    QWidgetAnimator &widgetAnimator = mainWindowLayout()->widgetAnimator;
    14841495
    14851496#ifndef QT_NO_TABBAR
     
    15141525        }
    15151526
    1516         widgetAnimator->animate(tabBar, tab_rect, animate);
     1527        widgetAnimator.animate(tabBar, tab_rect, animate);
    15171528    }
    15181529#endif // QT_NO_TABBAR
     
    15371548
    15381549        QRect geo = w->geometry();
    1539         widgetAnimator->animate(w, r, animate);
    1540         if (!w->isHidden()) {
     1550        widgetAnimator.animate(w, r, animate);
     1551        if (!w->isHidden() && w->window()->isVisible()) {
    15411552            QDockWidget *dw = qobject_cast<QDockWidget*>(w);
    15421553            if (!r.isValid() && geo.right() >= 0 && geo.bottom() >= 0) {
     
    15491560        }
    15501561    }
    1551 
     1562#ifndef QT_NO_TABBAR
    15521563    if (sep == 1)
    15531564        updateSeparatorWidgets();
     1565#endif //QT_NO_TABBAR
    15541566}
    15551567
     
    16301642            break;
    16311643        QRect r = separatorRect(i);
    1632         if (clip.contains(r))
     1644        if (clip.contains(r) && !item.hasFixedSize(o))
    16331645            paintSep(p, widget, r, o, r.contains(mouse));
    16341646    }
     
    16951707}
    16961708
    1697 QDockAreaLayoutItem &QDockAreaLayoutInfo::item(QList<int> path)
     1709QDockAreaLayoutItem &QDockAreaLayoutInfo::item(const QList<int> &path)
    16981710{
    16991711    Q_ASSERT(!path.isEmpty());
     1712    const int index = path.first();
    17001713    if (path.count() > 1) {
    1701         QDockAreaLayoutItem &item = item_list[path.takeFirst()];
     1714        const QDockAreaLayoutItem &item = item_list[index];
    17021715        Q_ASSERT(item.subinfo != 0);
    1703         return item.subinfo->item(path);
    1704     }
    1705     return item_list[path.first()];
     1716        return item.subinfo->item(path.mid(1));
     1717    }
     1718    return item_list[index];
    17061719}
    17071720
     
    18321845}
    18331846
    1834 #ifdef Q_WS_MAC
    18351847static Qt::DockWidgetArea toDockWidgetArea(QInternal::DockPosition pos)
    18361848{
     
    18441856    return Qt::NoDockWidgetArea;
    18451857}
    1846 #endif
    18471858
    18481859static QRect constrainedRect(QRect rect, const QRect &desktop)
     
    19611972                    if (!testing) {
    19621973                        widget->setVisible(flags & StateFlagVisible);
     1974                        item_list.append(item);
    19631975                    }
    19641976                } else {
    19651977                    int dummy;
    19661978                    stream >> item.pos >> item.size >> dummy >> dummy;
    1967     //                qDebug() << widget << item.pos << item.size;
    19681979                    if (!testing) {
     1980                        item_list.append(item);
    19691981                        widget->setFloating(false);
    19701982                        widget->setVisible(flags & StateFlagVisible);
     1983                        emit widget->dockLocationChanged(toDockWidgetArea(dockPos));
    19711984                    }
    19721985                }
    19731986
    1974                 if (!testing) {
    1975                     item_list.append(item);
    1976                 }
    19771987            }
    19781988        } else if (nextMarker == SequenceMarker) {
     
    20012011        setCurrentTabId(tabId(item_list.at(index)));
    20022012    }
    2003 #endif
    20042013    if (!testing && sep == 1)
    20052014        updateSeparatorWidgets();
     2015#endif
    20062016
    20072017    return true;
    20082018}
    20092019
     2020#ifndef QT_NO_TABBAR
    20102021void QDockAreaLayoutInfo::updateSeparatorWidgets() const
    20112022{
    2012     QDockAreaLayoutInfo *that = const_cast<QDockAreaLayoutInfo*>(this);
    2013 
    20142023    if (tabbed) {
    2015         that->separatorWidgets.clear();
     2024        separatorWidgets.clear();
    20162025        return;
    20172026    }
     
    20412050        } else {
    20422051            sepWidget = mainWindowLayout()->getSeparatorWidget();
    2043             that->separatorWidgets.append(sepWidget);
     2052            separatorWidgets.append(sepWidget);
    20442053        }
    20452054        j++;
     
    20542063    }
    20552064
    2056     for (int k = j; k < that->separatorWidgets.size(); ++k) {
    2057         that->separatorWidgets[k]->hide();
    2058     }
    2059     that->separatorWidgets.resize(j);
     2065    for (int k = j; k < separatorWidgets.size(); ++k) {
     2066        separatorWidgets[k]->hide();
     2067    }
     2068    separatorWidgets.resize(j);
    20602069    Q_ASSERT(separatorWidgets.size() == j);
    20612070}
     2071#endif //QT_NO_TABBAR
    20622072
    20632073#ifndef QT_NO_TABBAR
     
    20692079    QDockAreaLayoutInfo *that = const_cast<QDockAreaLayoutInfo*>(this);
    20702080
    2071     if (tabBar == 0) {
     2081    if (that->tabBar == 0) {
    20722082        that->tabBar = mainWindowLayout()->getTabBar();
    20732083        that->tabBar->setShape(static_cast<QTabBar::Shape>(tabBarShape));
     
    22032213    QSet<QWidget*> result;
    22042214
    2205     foreach (QWidget *sepWidget, separatorWidgets)
    2206         result << sepWidget;
     2215    for (int i = 0; i < separatorWidgets.count(); ++i)
     2216        result << separatorWidgets.at(i);
    22072217
    22082218    for (int i = 0; i < item_list.count(); ++i) {
     
    22542264*/
    22552265
    2256 QDockAreaLayout::QDockAreaLayout(QMainWindow *win)
     2266QDockAreaLayout::QDockAreaLayout(QMainWindow *win) : fallbackToSizeHints(true)
    22572267{
    22582268    mainWindow = win;
     
    22722282        = QDockAreaLayoutInfo(sep, QInternal::BottomDock, Qt::Horizontal, tabShape, win);
    22732283    centralWidgetItem = 0;
    2274     centralWidgetRect = QRect(0, 0, -1, -1);
     2284
    22752285
    22762286    corners[Qt::TopLeftCorner] = Qt::TopDockWidgetArea;
     
    23412351                corners[i] = static_cast<Qt::DockWidgetArea>(cornerData[i]);
    23422352        }
     2353
     2354        if (!testing)
     2355            fallbackToSizeHints = false;
    23432356    }
    23442357
     
    24432456            continue;
    24442457        QRect rect = separatorRect(i);
    2445         if (sep == 1)
     2458        if (!rect.isNull() && sep == 1)
    24462459            rect.adjust(-2, -2, 2, 2);
    2447         if (rect.contains(pos)) {
     2460        if (rect.contains(pos) && !info.hasFixedSize()) {
    24482461            result << i;
    24492462            break;
     
    24702483}
    24712484
    2472 QDockAreaLayoutInfo *QDockAreaLayout::info(QList<int> path)
     2485QDockAreaLayoutInfo *QDockAreaLayout::info(const QList<int> &path)
    24732486{
    24742487    Q_ASSERT(!path.isEmpty());
    2475     int index = path.takeFirst();
     2488    const int index = path.first();
    24762489    Q_ASSERT(index >= 0 && index < QInternal::DockCount);
    24772490
    2478     if (path.isEmpty())
     2491    if (path.count() == 1)
    24792492        return &docks[index];
    24802493
    2481     return docks[index].info(path);
    2482 }
    2483 
    2484 const QDockAreaLayoutInfo *QDockAreaLayout::info(QList<int> path) const
     2494    return docks[index].info(path.mid(1));
     2495}
     2496
     2497const QDockAreaLayoutInfo *QDockAreaLayout::info(const QList<int> &path) const
    24852498{
    24862499    return const_cast<QDockAreaLayout*>(this)->info(path);
    24872500}
    24882501
    2489 QDockAreaLayoutItem &QDockAreaLayout::item(QList<int> path)
     2502QDockAreaLayoutItem &QDockAreaLayout::item(const QList<int> &path)
    24902503{
    24912504    Q_ASSERT(!path.isEmpty());
    2492     int index = path.takeFirst();
     2505    const int index = path.first();
    24932506    Q_ASSERT(index >= 0 && index < QInternal::DockCount);
    2494     return docks[index].item(path);
    2495 }
    2496 
    2497 QRect QDockAreaLayout::itemRect(QList<int> path) const
     2507    return docks[index].item(path.mid(1));
     2508}
     2509
     2510QRect QDockAreaLayout::itemRect(const QList<int> &path) const
    24982511{
    24992512    Q_ASSERT(!path.isEmpty());
    2500     int index = path.takeFirst();
     2513    const int index = path.first();
    25012514    Q_ASSERT(index >= 0 && index < QInternal::DockCount);
    2502     return docks[index].itemRect(path);
     2515    return docks[index].itemRect(path.mid(1));
    25032516}
    25042517
    25052518QRect QDockAreaLayout::separatorRect(int index) const
    25062519{
    2507     if (docks[index].isEmpty())
     2520    const QDockAreaLayoutInfo &dock = docks[index];
     2521    if (dock.isEmpty())
    25082522        return QRect();
    2509     QRect r = docks[index].rect;
     2523    QRect r = dock.rect;
    25102524    switch (index) {
    25112525        case QInternal::LeftDock:
     
    25232537}
    25242538
    2525 QRect QDockAreaLayout::separatorRect(QList<int> path) const
     2539QRect QDockAreaLayout::separatorRect(const QList<int> &path) const
    25262540{
    25272541    Q_ASSERT(!path.isEmpty());
    25282542
    2529     int index = path.takeFirst();
     2543    const int index = path.first();
    25302544    Q_ASSERT(index >= 0 && index < QInternal::DockCount);
    25312545
    2532     if (path.isEmpty())
     2546    if (path.count() == 1)
    25332547        return separatorRect(index);
    25342548    else
    2535         return docks[index].separatorRect(path);
    2536 }
    2537 
    2538 bool QDockAreaLayout::insertGap(QList<int> path, QLayoutItem *dockWidgetItem)
     2549        return docks[index].separatorRect(path.mid(1));
     2550}
     2551
     2552bool QDockAreaLayout::insertGap(const QList<int> &path, QLayoutItem *dockWidgetItem)
    25392553{
    25402554    Q_ASSERT(!path.isEmpty());
    2541     int index = path.takeFirst();
     2555    const int index = path.first();
    25422556    Q_ASSERT(index >= 0 && index < QInternal::DockCount);
    2543     return docks[index].insertGap(path, dockWidgetItem);
    2544 }
    2545 
    2546 QLayoutItem *QDockAreaLayout::plug(QList<int> path)
     2557    return docks[index].insertGap(path.mid(1), dockWidgetItem);
     2558}
     2559
     2560QLayoutItem *QDockAreaLayout::plug(const QList<int> &path)
    25472561{
    25482562    Q_ASSERT(!path.isEmpty());
    2549     int index = path.takeFirst();
     2563    const int index = path.first();
    25502564    Q_ASSERT(index >= 0 && index < QInternal::DockCount);
    2551     return docks[index].plug(path);
    2552 }
    2553 
    2554 QLayoutItem *QDockAreaLayout::unplug(QList<int> path)
     2565    return docks[index].plug(path.mid(1));
     2566}
     2567
     2568QLayoutItem *QDockAreaLayout::unplug(const QList<int> &path)
    25552569{
    25562570    Q_ASSERT(!path.isEmpty());
    2557     int index = path.takeFirst();
     2571    const int index = path.first();
    25582572    Q_ASSERT(index >= 0 && index < QInternal::DockCount);
    2559     return docks[index].unplug(path);
    2560 }
    2561 
    2562 void QDockAreaLayout::remove(QList<int> path)
     2573    return docks[index].unplug(path.mid(1));
     2574}
     2575
     2576void QDockAreaLayout::remove(const QList<int> &path)
    25632577{
    25642578    Q_ASSERT(!path.isEmpty());
    2565     int index = path.takeFirst();
     2579    const int index = path.first();
    25662580    Q_ASSERT(index >= 0 && index < QInternal::DockCount);
    2567     docks[index].remove(path);
     2581    docks[index].remove(path.mid(1));
    25682582}
    25692583
     
    25762590    QSize center_hint(0, 0);
    25772591    QSize center_min(0, 0);
    2578     bool have_central = centralWidgetItem != 0 && !centralWidgetItem->isEmpty();
     2592    const bool have_central = centralWidgetItem != 0 && !centralWidgetItem->isEmpty();
    25792593    if (have_central) {
    25802594        center_hint = centralWidgetRect.size();
     
    25952609
    25962610    QSize left_hint = docks[QInternal::LeftDock].size();
    2597     if (!left_hint.isValid())
     2611    if (left_hint.isNull() || fallbackToSizeHints)
    25982612        left_hint = docks[QInternal::LeftDock].sizeHint();
    25992613    QSize left_min = docks[QInternal::LeftDock].minimumSize();
     
    26022616
    26032617    QSize right_hint = docks[QInternal::RightDock].size();
    2604     if (!right_hint.isValid())
     2618    if (right_hint.isNull() || fallbackToSizeHints)
    26052619        right_hint = docks[QInternal::RightDock].sizeHint();
    26062620    QSize right_min = docks[QInternal::RightDock].minimumSize();
     
    26092623
    26102624    QSize top_hint = docks[QInternal::TopDock].size();
    2611     if (!top_hint.isValid())
     2625    if (top_hint.isNull() || fallbackToSizeHints)
    26122626        top_hint = docks[QInternal::TopDock].sizeHint();
    26132627    QSize top_min = docks[QInternal::TopDock].minimumSize();
     
    26162630
    26172631    QSize bottom_hint = docks[QInternal::BottomDock].size();
    2618     if (!bottom_hint.isValid())
     2632    if (bottom_hint.isNull() || fallbackToSizeHints)
    26192633        bottom_hint = docks[QInternal::BottomDock].sizeHint();
    26202634    QSize bottom_min = docks[QInternal::BottomDock].minimumSize();
    26212635    QSize bottom_max = docks[QInternal::BottomDock].maximumSize();
    26222636    bottom_hint = bottom_hint.boundedTo(bottom_max).expandedTo(bottom_min);
     2637
     2638    fallbackToSizeHints = !have_central;
    26232639
    26242640    if (_ver_struct_list != 0) {
     
    28552871        docks[i].clear();
    28562872
    2857     rect = QRect(0, 0, -1, -1);
    2858     centralWidgetRect = QRect(0, 0, -1, -1);
     2873    rect = QRect();
     2874    centralWidgetRect = QRect();
    28592875}
    28602876
     
    30583074void QDockAreaLayout::apply(bool animate)
    30593075{
    3060     QWidgetAnimator *widgetAnimator
     3076    QWidgetAnimator &widgetAnimator
    30613077        = qobject_cast<QMainWindowLayout*>(mainWindow->layout())->widgetAnimator;
    30623078
     
    30643080        docks[i].apply(animate);
    30653081    if (centralWidgetItem != 0 && !centralWidgetItem->isEmpty()) {
    3066         widgetAnimator->animate(centralWidgetItem->widget(), centralWidgetRect,
     3082        widgetAnimator.animate(centralWidgetItem->widget(), centralWidgetRect,
    30673083                                animate);
    30683084    }
    3069 
     3085#ifndef QT_NO_TABBAR
    30703086    if (sep == 1)
    30713087        updateSeparatorWidgets();
     3088#endif //QT_NO_TABBAR
    30723089}
    30733090
     
    30813098            continue;
    30823099        QRect r = separatorRect(i);
    3083         if (clip.contains(r)) {
     3100        if (clip.contains(r) && !dock.hasFixedSize()) {
    30843101            Qt::Orientation opposite = dock.o == Qt::Horizontal
    30853102                                        ? Qt::Vertical : Qt::Horizontal;
     
    31063123}
    31073124
    3108 int QDockAreaLayout::separatorMove(QList<int> separator, const QPoint &origin,
    3109                                                 const QPoint &dest,
    3110                                                 QVector<QLayoutStruct> *cache)
     3125int QDockAreaLayout::separatorMove(const QList<int> &separator, const QPoint &origin,
     3126                                                const QPoint &dest)
    31113127{
    31123128    int delta = 0;
     
    31173133        delta = pick(info->o, dest - origin);
    31183134        if (delta != 0)
    3119             delta = info->separatorMove(index, delta, cache);
     3135            delta = info->separatorMove(index, delta);
    31203136        info->apply(false);
    31213137        return delta;
    31223138    }
    31233139
    3124     if (cache->isEmpty()) {
    3125         QVector<QLayoutStruct> &list = *cache;
    3126 
    3127         if (index == QInternal::LeftDock || index == QInternal::RightDock)
    3128             getGrid(0, &list);
    3129         else
    3130             getGrid(&list, 0);
    3131     }
    3132 
    3133     QVector<QLayoutStruct> list = *cache;
     3140    QVector<QLayoutStruct> list;
     3141
     3142    if (index == QInternal::LeftDock || index == QInternal::RightDock)
     3143        getGrid(0, &list);
     3144    else
     3145        getGrid(&list, 0);
     3146
    31343147    int sep_index = index == QInternal::LeftDock || index == QInternal::TopDock
    31353148                        ? 0 : 1;
     
    31513164}
    31523165
     3166#ifndef QT_NO_TABBAR
    31533167// Sets the correct positions for the seperator widgets
    31543168// Allocates new sepearator widgets with getSeparatorWidget
    31553169void QDockAreaLayout::updateSeparatorWidgets() const
    31563170{
    3157     QDockAreaLayout *that = const_cast<QDockAreaLayout*>(this);
    3158 
    31593171    int j = 0;
    31603172
     
    31693181        } else {
    31703182            sepWidget = qobject_cast<QMainWindowLayout*>(mainWindow->layout())->getSeparatorWidget();
    3171             that->separatorWidgets.append(sepWidget);
     3183            separatorWidgets.append(sepWidget);
    31723184        }
    31733185        j++;
     
    31843196        separatorWidgets.at(i)->hide();
    31853197
    3186     that->separatorWidgets.resize(j);
    3187 }
     3198    separatorWidgets.resize(j);
     3199}
     3200#endif //QT_NO_TABBAR
    31883201
    31893202QLayoutItem *QDockAreaLayout::itemAt(int *x, int index) const
     
    32383251    return result;
    32393252}
    3240 #endif
    32413253
    32423254// Returns the set of all used separator widgets
     
    32453257    QSet<QWidget*> result;
    32463258
    3247     foreach (QWidget *sepWidget, separatorWidgets)
    3248         result << sepWidget;
     3259    for (int i = 0; i < separatorWidgets.count(); ++i)
     3260        result << separatorWidgets.at(i);
    32493261    for (int i = 0; i < QInternal::DockCount; ++i) {
    32503262        const QDockAreaLayoutInfo &dock = docks[i];
     
    32533265    return result;
    32543266}
    3255 
    3256 QRect QDockAreaLayout::gapRect(QList<int> path) const
     3267#endif
     3268
     3269QRect QDockAreaLayout::gapRect(const QList<int> &path) const
    32573270{
    32583271    const QDockAreaLayoutInfo *info = this->info(path);
  • trunk/src/gui/widgets/qdockarealayout_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    104104    QSize sizeHint() const;
    105105    bool expansive(Qt::Orientation o) const;
     106    bool hasFixedSize(Qt::Orientation o) const;
    106107
    107108    QLayoutItem *widgetItem;
     
    136137    QSize size() const;
    137138
    138     bool insertGap(QList<int> path, QLayoutItem *dockWidgetItem);
    139     QLayoutItem *plug(QList<int> path);
    140     QLayoutItem *unplug(QList<int> path);
     139    bool insertGap(const QList<int> &path, QLayoutItem *dockWidgetItem);
     140    QLayoutItem *plug(const QList<int> &path);
     141    QLayoutItem *unplug(const QList<int> &path);
    141142    enum TabMode { NoTabs, AllowTabs, ForceTabs };
    142143    QList<int> gapIndex(const QPoint &pos, bool nestingEnabled,
    143144                            TabMode tabMode) const;
    144     void remove(QList<int> path);
     145    void remove(const QList<int> &path);
    145146    void unnest(int index);
    146147    void split(int index, Qt::Orientation orientation, QLayoutItem *dockWidgetItem);
    147148    void tab(int index, QLayoutItem *dockWidgetItem);
    148     QDockAreaLayoutItem &item(QList<int> path);
    149     QDockAreaLayoutInfo *info(QList<int> path);
     149    QDockAreaLayoutItem &item(const QList<int> &path);
     150    QDockAreaLayoutInfo *info(const QList<int> &path);
    150151    QDockAreaLayoutInfo *info(QWidget *widget);
    151152
     
    162163    int changeSize(int index, int size, bool below);
    163164    QRect itemRect(int index) const;
    164     QRect itemRect(QList<int> path) const;
     165    QRect itemRect(const QList<int> &path) const;
    165166    QRect separatorRect(int index) const;
    166     QRect separatorRect(QList<int> path) const;
     167    QRect separatorRect(const QList<int> &path) const;
    167168
    168169    void clear();
    169170    bool isEmpty() const;
     171    bool hasFixedSize() const;
    170172    QList<int> findSeparator(const QPoint &pos) const;
    171173    int next(int idx) const;
     
    180182                            const QPoint &mouse) const;
    181183    QRegion separatorRegion() const;
    182     int separatorMove(int index, int delta, QVector<QLayoutStruct> *cache);
     184    int separatorMove(int index, int delta);
    183185
    184186    QLayoutItem *itemAt(int *x, int index) const;
     
    189191
    190192    int sep;
    191     QVector<QWidget*> separatorWidgets;
     193    mutable QVector<QWidget*> separatorWidgets;
    192194    QInternal::DockPosition dockPos;
    193195    Qt::Orientation o;
     
    195197    QMainWindow *mainWindow;
    196198    QList<QDockAreaLayoutItem> item_list;
    197 
     199#ifndef QT_NO_TABBAR
    198200    void updateSeparatorWidgets() const;
    199201    QSet<QWidget*> usedSeparatorWidgets() const;
     202#endif //QT_NO_TABBAR
    200203
    201204#ifndef QT_NO_TABBAR
     
    232235    QDockAreaLayoutInfo docks[4];
    233236    int sep; // separator extent
    234     QVector<QWidget*> separatorWidgets;
     237    bool fallbackToSizeHints; //determines if we should use the sizehint for the dock areas (true until the layout is restored or the central widget is set)
     238    mutable QVector<QWidget*> separatorWidgets;
    235239
    236240    bool isValid() const;
     
    245249    QList<int> findSeparator(const QPoint &pos) const;
    246250
    247     QDockAreaLayoutItem &item(QList<int> path);
    248     QDockAreaLayoutInfo *info(QList<int> path);
    249     const QDockAreaLayoutInfo *info(QList<int> path) const;
     251    QDockAreaLayoutItem &item(const QList<int> &path);
     252    QDockAreaLayoutInfo *info(const QList<int> &path);
     253    const QDockAreaLayoutInfo *info(const QList<int> &path) const;
    250254    QDockAreaLayoutInfo *info(QWidget *widget);
    251     QRect itemRect(QList<int> path) const;
     255    QRect itemRect(const QList<int> &path) const;
    252256    QRect separatorRect(int index) const;
    253     QRect separatorRect(QList<int> path) const;
    254 
    255     bool insertGap(QList<int> path, QLayoutItem *dockWidgetItem);
    256     QLayoutItem *plug(QList<int> path);
    257     QLayoutItem *unplug(QList<int> path);
    258     void remove(QList<int> path);
     257    QRect separatorRect(const QList<int> &path) const;
     258
     259    bool insertGap(const QList<int> &path, QLayoutItem *dockWidgetItem);
     260    QLayoutItem *plug(const QList<int> &path);
     261    QLayoutItem *unplug(const QList<int> &path);
     262    void remove(const QList<int> &path);
    259263
    260264    void fitLayout();
     
    276280                            const QPoint &mouse) const;
    277281    QRegion separatorRegion() const;
    278     int separatorMove(QList<int> separator, const QPoint &origin, const QPoint &dest,
    279                         QVector<QLayoutStruct> *cache);
     282    int separatorMove(const QList<int> &separator, const QPoint &origin, const QPoint &dest);
     283#ifndef QT_NO_TABBAR
    280284    void updateSeparatorWidgets() const;
     285#endif //QT_NO_TABBAR
    281286
    282287    QLayoutItem *itemAt(int *x, int index) const;
     
    289294                    QVector<QLayoutStruct> *hor_struct_list);
    290295
    291     QRect gapRect(QList<int> path) const;
     296    QRect gapRect(const QList<int> &path) const;
    292297
    293298    void keepSize(QDockWidget *w);
    294 
     299#ifndef QT_NO_TABBAR
    295300    QSet<QTabBar*> usedTabBars() const;
    296301    QSet<QWidget*> usedSeparatorWidgets() const;
     302#endif //QT_NO_TABBAR
    297303};
    298304
  • trunk/src/gui/widgets/qdockwidget.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6060#include "qmainwindowlayout_p.h"
    6161#ifdef Q_WS_MAC
     62#include <private/qapplication_p.h>
    6263#include <private/qt_mac_p.h>
    6364#include <qmacstyle_mac.h>
     
    6869extern QString qt_setWindowTitle_helperHelper(const QString&, const QWidget*); // qwidget.cpp
    6970
    70 extern QHash<QByteArray, QFont> *qt_app_fonts_hash(); // qapplication.cpp
     71static inline bool hasFeature(const QDockWidgetPrivate *priv, QDockWidget::DockWidgetFeature feature)
     72{ return (priv->features & feature) == feature; }
    7173
    7274static inline bool hasFeature(const QDockWidget *dockwidget, QDockWidget::DockWidgetFeature feature)
     
    204206bool QDockWidgetLayout::nativeWindowDeco(bool floating) const
    205207{
    206 #if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_WINCE)
     208#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_WS_WINCE)
    207209    Q_UNUSED(floating);
    208210    return false;
     
    222224{
    223225    int cnt = 0;
    224     foreach (QLayoutItem *item, item_list) {
     226    for (int i = 0; i < item_list.count(); ++i) {
     227        QLayoutItem *item = item_list.at(i);
    225228        if (item == 0)
    226229            continue;
     
    251254{
    252255    int result = 0;
    253     foreach (QLayoutItem *item, item_list) {
    254         if (item != 0)
     256    for (int i = 0; i < item_list.count(); ++i) {
     257        if (item_list.at(i))
    255258            ++result;
    256259    }
     
    454457    int mw = q->style()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, 0, q);
    455458
    456     return qMax(buttonHeight + 2, titleFontMetrics.lineSpacing() + 2*mw);
     459    return qMax(buttonHeight + 2, titleFontMetrics.height() + 2*mw);
    457460}
    458461
     
    647650{
    648651    Q_Q(QDockWidget);
    649     QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(q->layout());
     652    QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout);
    650653
    651654    QStyleOptionDockWidget opt;
    652655    q->initStyleOption(&opt);
    653656
    654     bool customTitleBar = layout->widgetForRole(QDockWidgetLayout::TitleBar) != 0;
    655     bool nativeDeco = layout->nativeWindowDeco();
     657    bool customTitleBar = dwLayout->widgetForRole(QDockWidgetLayout::TitleBar) != 0;
     658    bool nativeDeco = dwLayout->nativeWindowDeco();
    656659    bool hideButtons = nativeDeco || customTitleBar;
    657660
    658     bool canClose = hasFeature(q, QDockWidget::DockWidgetClosable);
    659     bool canFloat = hasFeature(q, QDockWidget::DockWidgetFloatable);
     661    bool canClose = hasFeature(this, QDockWidget::DockWidgetClosable);
     662    bool canFloat = hasFeature(this, QDockWidget::DockWidgetFloatable);
    660663
    661664    QAbstractButton *button
    662         = qobject_cast<QAbstractButton*>(layout->widgetForRole(QDockWidgetLayout::FloatButton));
     665        = qobject_cast<QAbstractButton*>(dwLayout->widgetForRole(QDockWidgetLayout::FloatButton));
    663666    button->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarNormalButton, &opt, q));
    664667    button->setVisible(canFloat && !hideButtons);
    665668
    666669    button
    667         = qobject_cast <QAbstractButton*>(layout->widgetForRole(QDockWidgetLayout::CloseButton));
     670        = qobject_cast <QAbstractButton*>(dwLayout->widgetForRole(QDockWidgetLayout::CloseButton));
    668671    button->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarCloseButton, &opt, q));
    669672    button->setVisible(canClose && !hideButtons);
     
    683686void QDockWidgetPrivate::initDrag(const QPoint &pos, bool nca)
    684687{
    685     Q_Q(QDockWidget);
    686 
    687688    if (state != 0)
    688689        return;
    689690
    690     QMainWindow *win = qobject_cast<QMainWindow*>(q->parentWidget());
     691    QMainWindow *win = qobject_cast<QMainWindow*>(parent);
    691692    Q_ASSERT(win != 0);
    692693    QMainWindowLayout *layout = qobject_cast<QMainWindowLayout*>(win->layout());
    693694    Q_ASSERT(layout != 0);
    694     if (layout->layoutState.indexOf(q).isEmpty()) //The dock widget has not been added into the main window
    695         return;
    696695    if (layout->pluggingWidget != 0) // the main window is animating a docking operation
    697696        return;
     
    741740
    742741    if (state->dragging) {
    743         QMainWindowLayout *layout =
     742        QMainWindowLayout *mwLayout =
    744743            qobject_cast<QMainWindowLayout *>(q->parentWidget()->layout());
    745         Q_ASSERT(layout != 0);
    746 
    747         if (abort || !layout->plug(state->widgetItem)) {
    748             if (hasFeature(q, QDockWidget::DockWidgetFloatable)) {
     744        Q_ASSERT(mwLayout != 0);
     745
     746        if (abort || !mwLayout->plug(state->widgetItem)) {
     747            if (hasFeature(this, QDockWidget::DockWidgetFloatable)) {
    749748                if (state->ownWidgetItem)
    750749                    delete state->widgetItem;
    751                 layout->restore();
     750                mwLayout->restore();
    752751#ifdef Q_WS_X11
    753752                // get rid of the X11BypassWindowManager window flag and activate the resizer
     
    759758#else
    760759                QDockWidgetLayout *myLayout
    761                     = qobject_cast<QDockWidgetLayout*>(q->layout());
     760                    = qobject_cast<QDockWidgetLayout*>(layout);
    762761                resizer->setActive(QWidgetResizeHandler::Resize,
    763762                                    myLayout->widgetForRole(QDockWidgetLayout::TitleBar) != 0);
     
    766765                q->activateWindow();
    767766            } else {
    768                 layout->revert(state->widgetItem);
     767                mwLayout->revert(state->widgetItem);
    769768            }
    770769        }
     
    778777    Q_Q(const QDockWidget);
    779778
    780     QMainWindow *mainWin = qobject_cast<QMainWindow*>(q->parentWidget());
     779    QMainWindow *mainWin = qobject_cast<QMainWindow*>(parent);
    781780    if (mainWin == 0)
    782781        return false;
     
    795794    Q_Q(QDockWidget);
    796795
    797     QDockWidgetLayout *layout
    798         = qobject_cast<QDockWidgetLayout*>(q->layout());
    799 
    800     if (!layout->nativeWindowDeco()) {
    801         QRect titleArea = layout->titleArea();
     796    QDockWidgetLayout *dwLayout
     797        = qobject_cast<QDockWidgetLayout*>(layout);
     798
     799    if (!dwLayout->nativeWindowDeco()) {
     800        QRect titleArea = dwLayout->titleArea();
    802801
    803802        if (event->button() != Qt::LeftButton ||
     
    805804            // check if the tool window is movable... do nothing if it
    806805            // is not (but allow moving if the window is floating)
    807             (!hasFeature(q, QDockWidget::DockWidgetMovable) && !q->isFloating()) ||
    808             qobject_cast<QMainWindow*>(q->parentWidget()) == 0 ||
     806            (!hasFeature(this, QDockWidget::DockWidgetMovable) && !q->isFloating()) ||
     807            qobject_cast<QMainWindow*>(parent) == 0 ||
    809808            isAnimating() || state != 0) {
    810809            return false;
     
    814813
    815814        if (state)
    816             state->ctrlDrag = hasFeature(q, QDockWidget::DockWidgetFloatable) && event->modifiers() & Qt::ControlModifier;
     815            state->ctrlDrag = hasFeature(this, QDockWidget::DockWidgetFloatable) && event->modifiers() & Qt::ControlModifier;
    817816
    818817        return true;
     
    825824bool QDockWidgetPrivate::mouseDoubleClickEvent(QMouseEvent *event)
    826825{
    827     Q_Q(QDockWidget);
    828 
    829     QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(q->layout());
    830 
    831     if (!layout->nativeWindowDeco()) {
    832         QRect titleArea = layout->titleArea();
     826    QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout);
     827
     828    if (!dwLayout->nativeWindowDeco()) {
     829        QRect titleArea = dwLayout->titleArea();
    833830
    834831        if (event->button() == Qt::LeftButton && titleArea.contains(event->pos()) &&
    835             hasFeature(q, QDockWidget::DockWidgetFloatable)) {
     832            hasFeature(this, QDockWidget::DockWidgetFloatable)) {
    836833            _q_toggleTopLevel();
    837834            return true;
     
    851848
    852849    QDockWidgetLayout *dwlayout
    853         = qobject_cast<QDockWidgetLayout*>(q->layout());
     850        = qobject_cast<QDockWidgetLayout*>(layout);
    854851    QMainWindowLayout *mwlayout
    855852        = qobject_cast<QMainWindowLayout*>(q->parentWidget()->layout());
     
    924921            if (state != 0)
    925922                break;
    926             if (qobject_cast<QMainWindow*>(q->parentWidget()) == 0)
     923            if (qobject_cast<QMainWindow*>(parent) == 0)
    927924                break;
    928925            if (isAnimating())
     
    997994    QRect r = rect;
    998995    r.moveTopLeft(q->mapToGlobal(QPoint(0, 0)));
    999     QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(q->layout());
    1000     if (layout->nativeWindowDeco(true))
    1001         r.adjust(0, layout->titleHeight(), 0, 0);
     996    QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout);
     997    if (dwLayout->nativeWindowDeco(true))
     998        r.adjust(0, dwLayout->titleHeight(), 0, 0);
    1002999    setWindowState(true, true, r);
    10031000}
     
    10111008{
    10121009    Q_Q(QDockWidget);
     1010
     1011    if (!floating && parent) {
     1012        QMainWindowLayout *mwlayout = qobject_cast<QMainWindowLayout *>(q->parentWidget()->layout());
     1013        if (!mwlayout || mwlayout->dockWidgetArea(q) == Qt::NoDockWidgetArea)
     1014            return; // this dockwidget can't be redocked
     1015    }
    10131016
    10141017    bool wasFloating = q->isFloating();
     
    10201023    Qt::WindowFlags flags = floating ? Qt::Tool : Qt::Widget;
    10211024
    1022     QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(q->layout());
    1023     const bool nativeDeco = layout->nativeWindowDeco(floating);
     1025    QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout);
     1026    const bool nativeDeco = dwLayout->nativeWindowDeco(floating);
    10241027
    10251028    if (nativeDeco) {
    10261029        flags |= Qt::CustomizeWindowHint | Qt::WindowTitleHint;
    1027         if (hasFeature(q, QDockWidget::DockWidgetClosable))
     1030        if (hasFeature(this, QDockWidget::DockWidgetClosable))
    10281031            flags |= Qt::WindowCloseButtonHint;
    10291032    } else {
     
    10521055    if (floating != wasFloating) {
    10531056        emit q->topLevelChanged(floating);
    1054         if (!floating && q->parentWidget()) {
     1057        if (!floating && parent) {
    10551058            QMainWindowLayout *mwlayout = qobject_cast<QMainWindowLayout *>(q->parentWidget()->layout());
    10561059            if (mwlayout)
     
    10691072    desktop.
    10701073
    1071     \ingroup application
     1074    \ingroup mainwindow-classes
    10721075
    10731076    QDockWidget provides the concept of dock widgets, also know as
     
    11361139/*!
    11371140    \property QDockWidget::windowTitle
    1138     \internal
     1141    \brief the dock widget title (caption)
    11391142
    11401143    By default, this property contains an empty string.
     
    12231226    if (d->features == features)
    12241227        return;
     1228    const bool closableChanged = (d->features ^ features) & DockWidgetClosable;
    12251229    d->features = features;
    12261230    QDockWidgetLayout *layout
     
    12311235    emit featuresChanged(d->features);
    12321236    update();
     1237    if (closableChanged && layout->nativeWindowDeco()) {
     1238        //this ensures the native decoration is drawn
     1239        d->setWindowState(true /*floating*/, true /*unplug*/);
     1240    }
    12331241}
    12341242
     
    13221330            if (QMainWindowLayout *winLayout =
    13231331                (win ? qobject_cast<QMainWindowLayout*>(win->layout()) : 0))
    1324                 if (QDockAreaLayoutInfo *info =
    1325                     (winLayout ? winLayout->layoutState.dockAreaLayout.info(this) : 0))
     1332                if (QDockAreaLayoutInfo *info = winLayout->layoutState.dockAreaLayout.info(this))
    13261333                    info->updateTabBar();
    13271334        }
     
    13911398    case QEvent::Show:
    13921399        d->toggleViewAction->setChecked(true);
    1393         emit visibilityChanged(true);
     1400        emit visibilityChanged(geometry().right() >= 0 && geometry().bottom() >= 0);
    13941401        break;
    13951402#endif
  • trunk/src/gui/widgets/qdockwidget.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qdockwidget_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qeffects.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    127127QAlphaWidget::~QAlphaWidget()
    128128{
    129 #ifdef Q_WS_WIN
     129#if defined(Q_WS_WIN) && !defined(Q_WS_WINCE)
    130130    // Restore user-defined opacity value
    131     if (widget && QSysInfo::WindowsVersion >= QSysInfo::WV_2000 && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
     131    if (widget)
    132132        widget->setWindowOpacity(windowOpacity);
    133133#endif
     
    161161
    162162    showWidget = true;
    163 #if defined(Q_OS_WIN)
    164     if (QSysInfo::WindowsVersion >= QSysInfo::WV_2000 && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) {
    165         qApp->installEventFilter(this);
    166         widget->setWindowOpacity(0.0);
    167         widget->show();
     163#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
     164    qApp->installEventFilter(this);
     165    widget->setWindowOpacity(0.0);
     166    widget->show();
     167    connect(&anim, SIGNAL(timeout()), this, SLOT(render()));
     168    anim.start(1);
     169#else
     170    //This is roughly equivalent to calling setVisible(true) without actually showing the widget
     171    widget->setAttribute(Qt::WA_WState_ExplicitShowHide, true);
     172    widget->setAttribute(Qt::WA_WState_Hidden, false);
     173
     174    qApp->installEventFilter(this);
     175
     176    move(widget->geometry().x(),widget->geometry().y());
     177    resize(widget->size().width(), widget->size().height());
     178
     179    frontImage = QPixmap::grabWidget(widget).toImage();
     180    backImage = QPixmap::grabWindow(QApplication::desktop()->winId(),
     181                                widget->geometry().x(), widget->geometry().y(),
     182                                widget->geometry().width(), widget->geometry().height()).toImage();
     183
     184    if (!backImage.isNull() && checkTime.elapsed() < duration / 2) {
     185        mixedImage = backImage.copy();
     186        pm = QPixmap::fromImage(mixedImage);
     187        show();
     188        setEnabled(false);
     189
    168190        connect(&anim, SIGNAL(timeout()), this, SLOT(render()));
    169191        anim.start(1);
    170     } else
     192    } else {
     193       duration = 0;
     194       render();
     195    }
    171196#endif
    172     {
    173         //This is roughly equivalent to calling setVisible(true) without actually showing the widget
    174         widget->setAttribute(Qt::WA_WState_ExplicitShowHide, true);
    175         widget->setAttribute(Qt::WA_WState_Hidden, false);
    176 
    177         qApp->installEventFilter(this);
    178 
    179         move(widget->geometry().x(),widget->geometry().y());
    180         resize(widget->size().width(), widget->size().height());
    181 
    182         frontImage = QPixmap::grabWidget(widget).toImage();
    183         backImage = QPixmap::grabWindow(QApplication::desktop()->winId(),
    184                                     widget->geometry().x(), widget->geometry().y(),
    185                                     widget->geometry().width(), widget->geometry().height()).toImage();
    186 
    187         if (!backImage.isNull() && checkTime.elapsed() < duration / 2) {
    188             mixedImage = backImage.copy();
    189             pm = QPixmap::fromImage(mixedImage);
    190             show();
    191             setEnabled(false);
    192 
    193             connect(&anim, SIGNAL(timeout()), this, SLOT(render()));
    194             anim.start(1);
    195         } else {
    196            duration = 0;
    197            render();
    198         }
    199     }
    200197}
    201198
     
    271268        alpha = 1;
    272269
    273 #if defined(Q_OS_WIN)
    274     if (QSysInfo::WindowsVersion >= QSysInfo::WV_2000 && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) {
    275         if (alpha >= windowOpacity || !showWidget) {
    276             anim.stop();
    277             qApp->removeEventFilter(this);
    278             widget->setWindowOpacity(windowOpacity);
    279             q_blend = 0;
    280             deleteLater();
    281         } else {
    282             widget->setWindowOpacity(alpha);
    283         }
    284     } else
    285 #endif
     270#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
     271    if (alpha >= windowOpacity || !showWidget) {
     272        anim.stop();
     273        qApp->removeEventFilter(this);
     274        widget->setWindowOpacity(windowOpacity);
     275        q_blend = 0;
     276        deleteLater();
     277    } else {
     278        widget->setWindowOpacity(alpha);
     279    }
     280#else
    286281    if (alpha >= 1 || !showWidget) {
    287282        anim.stop();
     
    293288                setEnabled(true);
    294289                setFocus();
    295 #endif
     290#endif // Q_WS_WIN
    296291                widget->hide();
    297292            } else {
     
    310305        repaint();
    311306    }
     307#endif // defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
    312308}
    313309
     
    589585        return;
    590586
    591     qApp->sendPostedEvents(w, QEvent::Move);
    592     qApp->sendPostedEvents(w, QEvent::Resize);
     587    QApplication::sendPostedEvents(w, QEvent::Move);
     588    QApplication::sendPostedEvents(w, QEvent::Resize);
    593589    Qt::WindowFlags flags = Qt::ToolTip;
    594590
     
    611607        return;
    612608
    613     qApp->sendPostedEvents(w, QEvent::Move);
    614     qApp->sendPostedEvents(w, QEvent::Resize);
     609    QApplication::sendPostedEvents(w, QEvent::Move);
     610    QApplication::sendPostedEvents(w, QEvent::Resize);
    615611
    616612    Qt::WindowFlags flags = Qt::ToolTip;
  • trunk/src/gui/widgets/qeffects_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qfocusframe.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    119119
    120120    \ingroup basicwidgets
    121     \mainclass
     121
    122122
    123123    Normally an application will not need to create its own
  • trunk/src/gui/widgets/qfocusframe.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qfontcombobox.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    195195    font.setPointSize(QFontInfo(font).pointSize() * 3/2);
    196196    QFontMetrics fontMetrics(font);
    197     return QSize(fontMetrics.width(text), fontMetrics.lineSpacing());
     197    return QSize(fontMetrics.width(text), fontMetrics.height());
    198198}
    199199
     
    248248    list = result;
    249249
     250    //we need to block the signals so that the model doesn't emit reset
     251    //this prevents the current index from changing
     252    //it will be updated just after this
     253    ///TODO: we should finda way to avoid blocking signals and have a real update of the model
     254    const bool old = m->blockSignals(true);
    250255    m->setStringList(list);
     256    m->blockSignals(old);
     257
    251258    if (list.isEmpty()) {
    252259        if (currentFont != QFont()) {
     
    263270{
    264271    Q_Q(QFontComboBox);
    265     QFont newFont(text);
    266     if (currentFont != newFont) {
    267         currentFont = newFont;
     272    if (currentFont.family() != text) {
     273        currentFont.setFamily(text);
    268274        emit q->currentFontChanged(currentFont);
    269275    }
     
    277283    \since 4.2
    278284    \ingroup basicwidgets
    279     \ingroup text
    280285
    281286    The combobox is populated with an alphabetized list of font
     
    422427    if (font != d->currentFont) {
    423428        d->currentFont = font;
    424         emit currentFontChanged(d->currentFont);
    425429        d->_q_updateModel();
     430        if (d->currentFont == font) { //else the signal has already be emitted by _q_updateModel
     431            emit currentFontChanged(d->currentFont);
     432        }
    426433    }
    427434}
  • trunk/src/gui/widgets/qfontcombobox.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qframe.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6060      frameWidth(0),
    6161      leftFrameWidth(0), rightFrameWidth(0),
    62       topFrameWidth(0), bottomFrameWidth(0),
    63       oldFrameStyle(QFrame::NoFrame | QFrame::Plain)
     62      topFrameWidth(0), bottomFrameWidth(0)
    6463{
    6564}
     
    7574
    7675    \ingroup abstractwidgets
    77     \mainclass
     76
    7877
    7978    QMenu uses this to "raise" the menu above the surrounding
     
    137136    (useful as separator)
    138137    \value WinPanel draws a rectangular panel that can be raised or
    139     sunken like those in Windows 95. Specifying this shape sets
     138    sunken like those in Windows 2000. Specifying this shape sets
    140139    the line width to 2 pixels. WinPanel is provided for compatibility.
    141140    For GUI style independence we recommend using StyledPanel instead.
     
    334333    update();
    335334    d->updateFrameWidth();
    336     d->oldFrameStyle = (short)style;
    337335}
    338336
  • trunk/src/gui/widgets/qframe.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qframe_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5959QT_BEGIN_NAMESPACE
    6060
    61 class Q_GUI_EXPORT QFramePrivate : public QWidgetPrivate
     61class QFramePrivate : public QWidgetPrivate
    6262{
    6363    Q_DECLARE_PUBLIC(QFrame)
     
    7575    short       leftFrameWidth, rightFrameWidth;
    7676    short       topFrameWidth, bottomFrameWidth;
    77     short       oldFrameStyle;
    7877
    7978    inline void init();
  • trunk/src/gui/widgets/qgroupbox.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    148148    \ingroup organizers
    149149    \ingroup geomanagement
    150     \ingroup appearance
    151     \mainclass
    152150
    153151    A group box provides a frame, a title and a keyboard shortcut, and
     
    432430    Q_Q(QGroupBox);
    433431    QWidget *fw = q->focusWidget();
    434     if (!fw) {
     432    if (!fw || fw == q) {
    435433        QWidget * best = 0;
    436434        QWidget * candidate = 0;
     
    450448        if (best)
    451449            fw = best;
    452         else
    453             if (candidate)
     450        else if (candidate)
    454451                fw = candidate;
    455452    }
     
    480477        d->_q_fixFocus(fe->reason());
    481478    } else {
    482         QStyleOptionGroupBox box;
    483         initStyleOption(&box);
    484         QRect rect = style()->subControlRect(QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxCheckBox, this)
    485             | style()->subControlRect(QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxLabel, this);
    486         update(rect);
     479        QWidget::focusInEvent(fe);
    487480    }
    488481}
     
    645638{
    646639    Q_D(QGroupBox);
    647     if (d->checkable) {
    648         if (d->checked != b)
    649             update();
    650         bool wasToggled = (b != d->checked);
     640    if (d->checkable && b != d->checked) {
     641        update();
    651642        d->checked = b;
    652         if (wasToggled) {
    653             d->_q_setChildrenEnabled(b);
    654             emit toggled(b);
    655         }
     643        d->_q_setChildrenEnabled(b);
     644        emit toggled(b);
    656645    }
    657646}
  • trunk/src/gui/widgets/qgroupbox.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qlabel.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6262
    6363    \ingroup basicwidgets
    64     \ingroup text
    65     \mainclass
    6664
    6765    QLabel is used for displaying text or an image. No user
     
    889887{
    890888    Q_D(QLabel);
    891     d->sendControlEvent(ev);
     889    if (d->control) {
     890        d->sendControlEvent(ev);
     891        QTextCursor cursor = d->control->textCursor();
     892        Qt::FocusReason reason = ev->reason();
     893        if (reason != Qt::ActiveWindowFocusReason
     894            && reason != Qt::PopupFocusReason
     895            && cursor.hasSelection()) {
     896            cursor.clearSelection();
     897            d->control->setTextCursor(cursor);
     898        }
     899    }
     900
    892901    QFrame::focusOutEvent(ev);
    893902}
     
    972981    if (d->isTextLabel) {
    973982        QRectF lr = d->layoutRect();
     983        QStyleOption opt;
     984        opt.initFrom(this);
     985#ifndef QT_NO_STYLE_STYLESHEET
     986        if (QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(style)) {
     987            cssStyle->styleSheetPalette(this, &opt, &opt.palette);
     988        }
     989#endif
    974990        if (d->control) {
    975991#ifndef QT_NO_SHORTCUT
     
    9851001
    9861002            QAbstractTextDocumentLayout::PaintContext context;
    987             QStyleOption opt(0);
    988             opt.init(this);
    989 
    990             if (!isEnabled() && style->styleHint(QStyle::SH_EtchDisabledText, &opt, this)) {
    991                 context.palette = palette();
     1003            if (!isEnabled() && !d->control &&
     1004                // We cannot support etched for rich text controls because custom
     1005                // colors and links will override the light palette
     1006                style->styleHint(QStyle::SH_EtchDisabledText, &opt, this)) {
     1007                context.palette = opt.palette;
    9921008                context.palette.setColor(QPalette::Text, context.palette.light().color());
    9931009                painter.save();
     
    10001016
    10011017            // Adjust the palette
    1002             context.palette = palette();
    1003 #ifndef QT_NO_STYLE_STYLESHEET
    1004             if (QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(style)) {
    1005                 cssStyle->focusPalette(this, &opt, &context.palette);
    1006             }
    1007 #endif
     1018            context.palette = opt.palette;
    10081019
    10091020            if (foregroundRole() != QPalette::Text && isEnabled())
     
    10201031            if (d->hasShortcut) {
    10211032                flags |= Qt::TextShowMnemonic;
    1022                 QStyleOption opt;
    1023                 opt.initFrom(this);
    10241033                if (!style->styleHint(QStyle::SH_UnderlineShortcut, &opt, this))
    10251034                    flags |= Qt::TextHideMnemonic;
    10261035            }
    1027             style->drawItemText(&painter, lr.toRect(), flags, palette(), isEnabled(), d->text, foregroundRole());
     1036            style->drawItemText(&painter, lr.toRect(), flags, opt.palette, isEnabled(), d->text, foregroundRole());
    10281037        }
    10291038    } else
     
    11621171    hasShortcut = false;
    11631172
    1164     if (control) {
    1165         ensureTextPopulated();
    1166         // Underline the first character that follows an ampersand
    1167         shortcutCursor = control->document()->find(QLatin1String("&"));
    1168         if (shortcutCursor.isNull())
    1169             return;
    1170         hasShortcut = true;
    1171         shortcutId = q->grabShortcut(QKeySequence::mnemonic(text));
    1172         shortcutCursor.deleteChar(); // remove the ampersand
    1173         shortcutCursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
    1174     } else {
    1175         if (!text.contains(QLatin1String("&")))
    1176             return;
    1177         hasShortcut = true;
    1178         shortcutId = q->grabShortcut(QKeySequence::mnemonic(text));
    1179     }
     1173    if (!text.contains(QLatin1Char('&')))
     1174        return;
     1175    hasShortcut = true;
     1176    shortcutId = q->grabShortcut(QKeySequence::mnemonic(text));
    11801177}
    11811178
     
    14481445#endif
    14491446            doc->setUndoRedoEnabled(false);
     1447
     1448#ifndef QT_NO_SHORTCUT
     1449            if (hasShortcut) {
     1450                // Underline the first character that follows an ampersand (and remove the others ampersands)
     1451                int from = 0;
     1452                bool found = false;
     1453                QTextCursor cursor;
     1454                while (!(cursor = control->document()->find((QLatin1String("&")), from)).isNull()) {
     1455                    cursor.deleteChar(); // remove the ampersand
     1456                    cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
     1457                    from = cursor.position();
     1458                    if (!found && cursor.selectedText() != QLatin1String("&")) { //not a second &
     1459                        found = true;
     1460                        shortcutCursor = cursor;
     1461                    }
     1462                }
     1463            }
     1464#endif
    14501465        }
    14511466    }
  • trunk/src/gui/widgets/qlabel.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qlabel_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    114114    Qt::TextFormat textformat;
    115115    mutable QTextControl *control;
    116     QTextCursor shortcutCursor;
     116    mutable QTextCursor shortcutCursor;
    117117    Qt::TextInteractionFlags textInteractionFlags;
    118118
  • trunk/src/gui/widgets/qlcdnumber.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    7575
    7676    \ingroup basicwidgets
    77     \mainclass
     77
    7878
    7979    It can display a number in just about any size. It can display
     
    8686
    8787    QLCDNumber emits the overflow() signal when it is asked to display
    88     something beyond its range. The range is set by setNumDigits(),
     88    something beyond its range. The range is set by setDigitCount(),
    8989    but setSmallDecimalPoint() also influences it. If the display is
    9090    set to hexadecimal, octal or binary, the integer equivalent of the
     
    161161    a too-large number or a too-long string.
    162162
    163     It is never emitted by setNumDigits().
     163    It is never emitted by setDigitCount().
    164164*/
    165165
     
    346346    constructor.
    347347
    348     \sa setNumDigits(), setSmallDecimalPoint()
     348    \sa setDigitCount(), setSmallDecimalPoint()
    349349*/
    350350
     
    368368    constructor.
    369369
    370     \sa setNumDigits(), setSmallDecimalPoint()
     370    \sa setDigitCount(), setSmallDecimalPoint()
    371371*/
    372372
     
    388388    The \a parent argument is passed to the QFrame constructor.
    389389
    390     \sa setNumDigits(), setSmallDecimalPoint()
     390    \sa setDigitCount(), setSmallDecimalPoint()
    391391*/
    392392
     
    404404    numDigits, the base to decimal, the decimal point mode to 'small'
    405405    and the frame style to a raised box. The segmentStyle() is set to
    406     \c Outline.
     406    \c Filled.
    407407
    408408    The \a parent argument is passed to the QFrame constructor.
    409409
    410     \sa setNumDigits(), setSmallDecimalPoint()
     410    \sa setDigitCount(), setSmallDecimalPoint()
    411411*/
    412412
     
    427427    base       = QLCDNumber::Dec;
    428428    smallPoint = false;
    429     q->setNumDigits(ndigits);
    430     q->setSegmentStyle(QLCDNumber::Outline);
     429    q->setDigitCount(ndigits);
     430    q->setSegmentStyle(QLCDNumber::Filled);
    431431    q->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum));
    432432}
     
    442442
    443443/*!
     444    \deprecated
    444445    \property QLCDNumber::numDigits
     446    \brief the current number of digits displayed
     447    \sa digitCount
     448*/
     449
     450void QLCDNumber::setNumDigits(int numDigits)
     451{
     452    setDigitCount(numDigits);
     453}
     454
     455/*!
     456    \since 4.6
     457    \property QLCDNumber::digitCount
    445458    \brief the current number of digits displayed
    446459
     
    454467*/
    455468
    456 void QLCDNumber::setNumDigits(int numDigits)
     469/*!
     470  Sets the current number of digits to \a numDigits. Must
     471  be in the range 0..99.
     472 */
     473void QLCDNumber::setDigitCount(int numDigits)
    457474{
    458475    Q_D(QLCDNumber);
     
    471488        d->digitStr.fill(QLatin1Char(' '), d->ndigits);
    472489        d->points.fill(0, d->ndigits);
    473         d->digitStr[d->ndigits - 1] = QLatin1Char('0');            // "0" is the default number
     490        d->digitStr[d->ndigits - 1] = QLatin1Char('0'); // "0" is the default number
    474491    } else {
    475492        bool doDisplay = d->ndigits == 0;
     
    510527
    511528/*!
     529  Returns the current number of digits.
     530 */
     531int QLCDNumber::digitCount() const
     532{
     533    Q_D(const QLCDNumber);
     534    return d->ndigits;
     535}
     536
     537/*!
    512538    \overload
    513539
     
    515541    otherwise returns false.
    516542
    517     \sa display(), numDigits(), smallDecimalPoint()
     543    \sa display(), digitCount(), smallDecimalPoint()
    518544*/
    519545
     
    531557    otherwise returns false.
    532558
    533     \sa display(), numDigits(), smallDecimalPoint()
     559    \sa display(), digitCount(), smallDecimalPoint()
    534560*/
    535561
     
    757783    QPainter p(this);
    758784    drawFrame(&p);
     785    p.setRenderHint(QPainter::Antialiasing);
     786    if (d->shadow)
     787        p.translate(0.5, 0.5);
     788
    759789    if (d->smallPoint)
    760790        d->drawString(d->digitStr, p, &d->points, false);
     
    10711101        }
    10721102        // End exact copy
    1073         p.setPen(fgColor);
     1103        p.setPen(Qt::NoPen);
    10741104        p.setBrush(fgColor);
    10751105        p.drawPolygon(a);
     
    12191249    \row \i \c Outline
    12201250         \i Produces raised segments filled with the background color
     1251    \row \i \c Filled
    12211252            (this is the default).
    1222     \row \i \c Filled
    12231253         \i Produces raised segments filled with the foreground color.
    12241254    \row \i \c Flat
     
    12531283QSize QLCDNumber::sizeHint() const
    12541284{
    1255     return QSize(10 + 9 * (numDigits() + (smallDecimalPoint() ? 0 : 1)), 23);
     1285    return QSize(10 + 9 * (digitCount() + (smallDecimalPoint() ? 0 : 1)), 23);
    12561286}
    12571287
     
    12721302/*!
    12731303    \fn int QLCDNumber::margin() const
    1274     Returns the with of the the margin around the contents of the widget.
     1304    Returns the width of the margin around the contents of the widget.
    12751305   
    12761306    Use QWidget::getContentsMargins() instead.
  • trunk/src/gui/widgets/qlcdnumber.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6161    Q_PROPERTY(bool smallDecimalPoint READ smallDecimalPoint WRITE setSmallDecimalPoint)
    6262    Q_PROPERTY(int numDigits READ numDigits WRITE setNumDigits)
     63    Q_PROPERTY(int digitCount READ digitCount WRITE setDigitCount)
    6364    Q_PROPERTY(Mode mode READ mode WRITE setMode)
    6465    Q_PROPERTY(SegmentStyle segmentStyle READ segmentStyle WRITE setSegmentStyle)
     
    8283
    8384    bool smallDecimalPoint() const;
    84 
    85     int numDigits() const;
    86     void setNumDigits(int nDigits);
     85#ifdef QT_DEPRECATED
     86    QT_DEPRECATED int numDigits() const;
     87    QT_DEPRECATED void setNumDigits(int nDigits);
     88#endif
     89    int digitCount() const;
     90    void setDigitCount(int nDigits);
    8791
    8892    bool checkOverflow(double num) const;
  • trunk/src/gui/widgets/qlineedit.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    8080#include "private/qshortcutmap_p.h"
    8181#include "qkeysequence.h"
    82 #define ACCEL_KEY(k) (!qApp->d_func()->shortcutMap.hasShortcutForKeySequence(k) ? QLatin1String("\t") + QString(QKeySequence(k)) : QString())
     82#define ACCEL_KEY(k) (!qApp->d_func()->shortcutMap.hasShortcutForKeySequence(k) ? QLatin1Char('\t') + QString(QKeySequence(k)) : QString())
    8383#else
    8484#define ACCEL_KEY(k) QString()
     
    8787#include <limits.h>
    8888
    89 #define verticalMargin 1
    90 #define horizontalMargin 2
    91 
    9289QT_BEGIN_NAMESPACE
    9390
     
    9592extern void qt_mac_secure_keyboard(bool); //qapplication_mac.cpp
    9693#endif
    97 
    98 static inline bool shouldEnableInputMethod(QLineEdit *lineedit)
    99 {
    100     const QLineEdit::EchoMode mode = lineedit->echoMode();
    101     return !lineedit->isReadOnly() && (mode == QLineEdit::Normal || mode == QLineEdit::PasswordEchoOnEdit);
    102 }
    10394
    10495/*!
     
    123114    option->midLineWidth = 0;
    124115    option->state |= QStyle::State_Sunken;
    125     if (d->readOnly)
     116    if (d->control->isReadOnly())
    126117        option->state |= QStyle::State_ReadOnly;
    127118#ifdef QT_KEYPAD_NAVIGATION
     
    138129
    139130    \ingroup basicwidgets
    140     \mainclass
     131
    141132
    142133    A line edit allows the user to enter and edit a single line of
     
    351342    Q_D(QLineEdit);
    352343    setObjectName(QString::fromAscii(name));
    353     d->parseInputMask(inputMask);
    354     if (d->maskData) {
    355         QString ms = d->maskString(0, contents);
    356         d->init(ms + d->clearString(ms.length(), d->maxLength - ms.length()));
    357         d->cursor = d->nextMaskBlank(ms.length());
    358     } else {
    359         d->init(contents);
    360     }
     344    d->init(contents);
     345    d->control->setInputMask(inputMask);
     346    d->control->moveCursor(d->control->nextMaskBlank(contents.length()));
    361347}
    362348#endif
     
    389375{
    390376    Q_D(const QLineEdit);
    391     QString res = d->text;
    392     if (d->maskData)
    393         res = d->stripString(d->text);
    394     return (res.isNull() ? QString::fromLatin1("") : res);
     377    return d->control->text();
    395378}
    396379
     
    398381{
    399382    Q_D(QLineEdit);
    400     d->setText(text, -1, false);
    401 #ifdef QT_KEYPAD_NAVIGATION
    402     d->origText = d->text;
    403 #endif
    404 }
    405 
     383    d->control->setText(text);
     384}
     385
     386// ### Qt 4.7: remove this #if guard
     387#if (QT_VERSION >= 0x407000) || defined(Q_WS_MAEMO_5)
     388/*!
     389    \since 4.7
     390
     391    \property QLineEdit::placeholderText
     392    \brief the line edit's placeholder text
     393
     394    Setting this property makes the line edit display a grayed-out
     395    placeholder text as long as the text() is empty and the widget doesn't
     396    have focus.
     397
     398    By default, this property contains an empty string.
     399
     400    \sa text()
     401*/
     402QString QLineEdit::placeholderText() const
     403{
     404    Q_D(const QLineEdit);
     405    return d->placeholderText;
     406}
     407
     408void QLineEdit::setPlaceholderText(const QString& placeholderText)
     409{
     410    Q_D(QLineEdit);
     411    if (d->placeholderText != placeholderText) {
     412        d->placeholderText = placeholderText;
     413        if (!hasFocus())
     414            update();
     415    }
     416}
     417#endif
    406418
    407419/*!
     
    422434{
    423435    Q_D(const QLineEdit);
    424     if (d->echoMode == NoEcho)
    425         return QString::fromLatin1("");
    426     QString res = d->text;
    427 
    428     if (d->echoMode == Password || (d->echoMode == PasswordEchoOnEdit
    429                                     && !d->passwordEchoEditing)) {
    430         QStyleOptionFrameV2 opt;
    431         initStyleOption(&opt);
    432         res.fill(style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, &opt, this));
    433     }
    434     return (res.isNull() ? QString::fromLatin1("") : res);
     436    return d->control->displayText();
    435437}
    436438
     
    457459{
    458460    Q_D(const QLineEdit);
    459     return d->maxLength;
     461    return d->control->maxLength();
    460462}
    461463
     
    463465{
    464466    Q_D(QLineEdit);
    465     if (d->maskData)
    466         return;
    467     d->maxLength = maxLength;
    468     setText(d->text);
    469 }
    470 
    471 
     467    d->control->setMaxLength(maxLength);
     468}
    472469
    473470/*!
     
    537534{
    538535    Q_D(const QLineEdit);
    539     return (EchoMode) d->echoMode;
     536    return (EchoMode) d->control->echoMode();
    540537}
    541538
     
    543540{
    544541    Q_D(QLineEdit);
    545     if (mode == (EchoMode)d->echoMode)
     542    if (mode == (EchoMode)d->control->echoMode())
    546543        return;
    547     setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod(this));
    548     d->echoMode = mode;
    549     d->passwordEchoEditing = false;
    550     d->updateTextLayout();
     544    Qt::InputMethodHints imHints = inputMethodHints();
     545    if (mode == Password) {
     546        imHints |= Qt::ImhHiddenText;
     547    } else {
     548        imHints &= ~Qt::ImhHiddenText;
     549    }
     550    setInputMethodHints(imHints);
     551    d->control->setEchoMode(mode);
    551552    update();
    552553#ifdef Q_WS_MAC
    553554    if (hasFocus())
    554         qt_mac_secure_keyboard(d->echoMode == Password || d->echoMode == NoEcho);
     555        qt_mac_secure_keyboard(mode == Password || mode == NoEcho);
    555556#endif
    556557}
     
    568569{
    569570    Q_D(const QLineEdit);
    570     return d->validator;
     571    return d->control->validator();
    571572}
    572573
     
    586587{
    587588    Q_D(QLineEdit);
    588     d->validator = const_cast<QValidator*>(v);
     589    d->control->setValidator(v);
    589590}
    590591#endif // QT_NO_VALIDATOR
     
    610611{
    611612    Q_D(QLineEdit);
    612     if (c == d->completer)
     613    if (c == d->control->completer())
    613614        return;
    614     if (d->completer) {
    615         disconnect(d->completer, 0, this, 0);
    616         d->completer->setWidget(0);
    617         if (d->completer->parent() == this)
    618             delete d->completer;
    619     }
    620     d->completer = c;
     615    if (d->control->completer()) {
     616        disconnect(d->control->completer(), 0, this, 0);
     617        d->control->completer()->setWidget(0);
     618        if (d->control->completer()->parent() == this)
     619            delete d->control->completer();
     620    }
     621    d->control->setCompleter(c);
    621622    if (!c)
    622623        return;
     
    624625        c->setWidget(this);
    625626    if (hasFocus()) {
    626         QObject::connect(d->completer, SIGNAL(activated(QString)),
     627        QObject::connect(d->control->completer(), SIGNAL(activated(QString)),
    627628                         this, SLOT(setText(QString)));
    628         QObject::connect(d->completer, SIGNAL(highlighted(QString)),
     629        QObject::connect(d->control->completer(), SIGNAL(highlighted(QString)),
    629630                         this, SLOT(_q_completionHighlighted(QString)));
    630631    }
     
    639640{
    640641    Q_D(const QLineEdit);
    641     return d->completer;
    642 }
    643 
    644 // looks for an enabled item iterating forward(dir=1)/backward(dir=-1) from the
    645 // current row based. dir=0 indicates a new completion prefix was set.
    646 bool QLineEditPrivate::advanceToEnabledItem(int dir)
    647 {
    648     int start = completer->currentRow();
    649     if (start == -1)
    650         return false;
    651     int i = start + dir;
    652     if (dir == 0) dir = 1;
    653     do {
    654         if (!completer->setCurrentRow(i)) {
    655             if (!completer->wrapAround())
    656                 break;
    657             i = i > 0 ? 0 : completer->completionCount() - 1;
    658         } else {
    659             QModelIndex currentIndex = completer->currentIndex();
    660             if (completer->completionModel()->flags(currentIndex) & Qt::ItemIsEnabled)
    661                 return true;
    662             i += dir;
    663         }
    664     } while (i != start);
    665 
    666     completer->setCurrentRow(start); // restore
    667     return false;
    668 }
    669 
    670 void QLineEditPrivate::complete(int key)
    671 {
    672     if (!completer || readOnly || echoMode != QLineEdit::Normal)
    673         return;
    674 
    675     if (completer->completionMode() == QCompleter::InlineCompletion) {
    676         if (key == Qt::Key_Backspace)
    677             return;
    678         int n = 0;
    679         if (key == Qt::Key_Up || key == Qt::Key_Down) {
    680             if (selend != 0 && selend != text.length())
    681                 return;
    682             QString prefix = hasSelectedText() ? text.left(selstart) : text;
    683             if (text.compare(completer->currentCompletion(), completer->caseSensitivity()) != 0
    684                 || prefix.compare(completer->completionPrefix(), completer->caseSensitivity()) != 0) {
    685                 completer->setCompletionPrefix(prefix);
    686             } else {
    687                 n = (key == Qt::Key_Up) ? -1 : +1;
    688             }
    689         } else {
    690             completer->setCompletionPrefix(text);
    691         }
    692         if (!advanceToEnabledItem(n))
    693             return;
    694     } else {
    695 #ifndef QT_KEYPAD_NAVIGATION
    696         if (text.isEmpty()) {
    697             completer->popup()->hide();
    698             return;
    699         }
    700 #endif
    701         completer->setCompletionPrefix(text);
    702     }
    703 
    704     completer->complete();
    705 }
    706 
    707 void QLineEditPrivate::_q_completionHighlighted(QString newText)
    708 {
    709     Q_Q(QLineEdit);
    710     if (completer->completionMode() != QCompleter::InlineCompletion)
    711         q->setText(newText);
    712     else {
    713         int c = cursor;
    714         q->setText(text.left(c) + newText.mid(c));
    715         q->setSelection(text.length(), c - newText.length());
    716     }
    717 }
     642    return d->control->completer();
     643}
     644
    718645#endif // QT_NO_COMPLETER
    719646
     
    730657    ensurePolished();
    731658    QFontMetrics fm(font());
    732     int h = qMax(fm.lineSpacing(), 14) + 2*verticalMargin
     659    int h = qMax(fm.height(), 14) + 2*d->verticalMargin
    733660            + d->topTextMargin + d->bottomTextMargin
    734661            + d->topmargin + d->bottommargin;
    735     int w = fm.width(QLatin1Char('x')) * 17 + 2*horizontalMargin
     662    int w = fm.width(QLatin1Char('x')) * 17 + 2*d->horizontalMargin
    736663            + d->leftTextMargin + d->rightTextMargin
    737664            + d->leftmargin + d->rightmargin; // "some"
     
    754681    ensurePolished();
    755682    QFontMetrics fm = fontMetrics();
    756     int h = fm.height() + qMax(2*verticalMargin, fm.leading())
     683    int h = fm.height() + qMax(2*d->verticalMargin, fm.leading())
    757684            + d->topmargin + d->bottommargin;
    758685    int w = fm.maxWidth() + d->leftmargin + d->rightmargin;
     
    776703{
    777704    Q_D(const QLineEdit);
    778     return d->cursor;
     705    return d->control->cursorPosition();
    779706}
    780707
     
    782709{
    783710    Q_D(QLineEdit);
    784     if (pos < 0)
    785         pos = 0;
    786 
    787     if (pos <= d->text.length())
    788         d->moveCursor(pos);
     711    d->control->setCursorPosition(pos);
    789712}
    790713
     
    808731                                 int newMarkAnchor, int newMarkDrag)
    809732{
    810     Q_D(QLineEdit);
    811     int priorState = d->undoState;
    812     d->selstart = 0;
    813     d->selend = d->text.length();
    814     d->removeSelectedText();
    815     d->insert(newText);
    816     d->finishChange(priorState);
    817     if (d->undoState > priorState) {
    818         d->cursor = newPos;
    819         d->selstart = qMin(newMarkAnchor, newMarkDrag);
    820         d->selend = qMax(newMarkAnchor, newMarkDrag);
    821         update();
    822         d->emitCursorPositionChanged();
    823         return true;
    824     }
    825     return false;
     733    // The suggested functions above in the docs don't seem to validate,
     734    // below code tries to mimic previous behaviour.
     735    QString oldText = text();
     736    setText(newText);
     737    if(!hasAcceptableInput()){
     738        setText(oldText);
     739        return false;
     740    }
     741    setCursorPosition(newPos);
     742    setSelection(qMin(newMarkAnchor, newMarkDrag), qAbs(newMarkAnchor - newMarkDrag));
     743    return true;
    826744}
    827745#endif //QT3_SUPPORT
     
    864782{
    865783    Q_D(QLineEdit);
    866     int cursor = d->cursor;
    867     if (steps > 0) {
    868         while(steps--)
    869             cursor = d->textLayout.nextCursorPosition(cursor);
    870     } else if (steps < 0) {
    871         while (steps++)
    872             cursor = d->textLayout.previousCursorPosition(cursor);
    873     }
    874     d->moveCursor(cursor, mark);
     784    d->control->cursorForward(mark, steps);
    875785}
    876786
     
    897807{
    898808    Q_D(QLineEdit);
    899     d->moveCursor(d->textLayout.nextCursorPosition(d->cursor, QTextLayout::SkipWords), mark);
     809    d->control->cursorWordForward(mark);
    900810}
    901811
     
    910820{
    911821    Q_D(QLineEdit);
    912     d->moveCursor(d->textLayout.previousCursorPosition(d->cursor, QTextLayout::SkipWords), mark);
     822    d->control->cursorWordBackward(mark);
    913823}
    914824
     
    925835{
    926836    Q_D(QLineEdit);
    927     int priorState = d->undoState;
    928     if (d->hasSelectedText()) {
    929         d->removeSelectedText();
    930     } else if (d->cursor) {
    931             --d->cursor;
    932             if (d->maskData)
    933                 d->cursor = d->prevMaskBlank(d->cursor);
    934             QChar uc = d->text.at(d->cursor);
    935             if (d->cursor > 0 && uc.unicode() >= 0xdc00 && uc.unicode() < 0xe000) {
    936                 // second half of a surrogate, check if we have the first half as well,
    937                 // if yes delete both at once
    938                 uc = d->text.at(d->cursor - 1);
    939                 if (uc.unicode() >= 0xd800 && uc.unicode() < 0xdc00) {
    940                     d->del(true);
    941                     --d->cursor;
    942                 }
    943             }
    944             d->del(true);
    945     }
    946     d->finishChange(priorState);
     837    d->control->backspace();
    947838}
    948839
     
    958849{
    959850    Q_D(QLineEdit);
    960     int priorState = d->undoState;
    961     if (d->hasSelectedText()) {
    962         d->removeSelectedText();
    963     } else {
    964         int n = d->textLayout.nextCursorPosition(d->cursor) - d->cursor;
    965         while (n--)
    966             d->del();
    967     }
    968     d->finishChange(priorState);
     851    d->control->del();
    969852}
    970853
     
    981864{
    982865    Q_D(QLineEdit);
    983     d->moveCursor(0, mark);
     866    d->control->home(mark);
    984867}
    985868
     
    996879{
    997880    Q_D(QLineEdit);
    998     d->moveCursor(d->text.length(), mark);
     881    d->control->end(mark);
    999882}
    1000883
     
    1021904{
    1022905    Q_D(const QLineEdit);
    1023     return d->modifiedState != d->undoState;
     906    return d->control->isModified();
    1024907}
    1025908
     
    1027910{
    1028911    Q_D(QLineEdit);
    1029     if (modified)
    1030         d->modifiedState = -1;
    1031     else
    1032         d->modifiedState = d->undoState;
     912    d->control->setModified(modified);
    1033913}
    1034914
     
    1058938{
    1059939    Q_D(const QLineEdit);
    1060     return d->hasSelectedText();
     940    return d->control->hasSelectedText();
    1061941}
    1062942
     
    1076956{
    1077957    Q_D(const QLineEdit);
    1078     if (d->hasSelectedText())
    1079         return d->text.mid(d->selstart, d->selend - d->selstart);
    1080     return QString();
     958    return d->control->selectedText();
    1081959}
    1082960
     
    1091969{
    1092970    Q_D(const QLineEdit);
    1093     return d->hasSelectedText() ? d->selstart : -1;
     971    return d->control->selectionStart();
    1094972}
    1095973
     
    1121999{
    11221000    Q_D(const QLineEdit);
    1123     int pos = d->xToPos(xpos + contentsRect().x() - d->hscroll + horizontalMargin);
    1124     if (chr && pos < (int) d->text.length())
    1125         *chr = d->text.at(pos);
     1001    int pos = d->xToPos(xpos + contentsRect().x() - d->hscroll + d->horizontalMargin);
     1002    QString txt = d->control->text();
     1003    if (chr && pos < (int) txt.length())
     1004        *chr = txt.at(pos);
    11261005    return pos;
    11271006
     
    11341013{
    11351014    Q_D(QLineEdit);
    1136     if (d->hasSelectedText() && start && end) {
    1137         *start = d->selstart;
    1138         *end = d->selend;
     1015    if (d->control->hasSelectedText() && start && end) {
     1016        *start = selectionStart();
     1017        *end = *start + selectedText().length();
    11391018        return true;
    11401019    }
     
    11541033{
    11551034    Q_D(QLineEdit);
    1156     if (start < 0 || start > (int)d->text.length()) {
     1035    if (start < 0 || start > (int)d->control->text().length()) {
    11571036        qWarning("QLineEdit::setSelection: Invalid start position (%d)", start);
    11581037        return;
    1159     } else {
    1160         if (length > 0) {
    1161             d->selstart = start;
    1162             d->selend = qMin(start + length, (int)d->text.length());
    1163             d->cursor = d->selend;
    1164         } else {
    1165             d->selstart = qMax(start + length, 0);
    1166             d->selend = start;
    1167             d->cursor = d->selstart;
    1168         }
    1169     }
    1170 
    1171     if (d->hasSelectedText()){
     1038    }
     1039
     1040    d->control->setSelection(start, length);
     1041
     1042    if (d->control->hasSelectedText()){
    11721043        QStyleOptionFrameV2 opt;
    11731044        initStyleOption(&opt);
     
    11751046            d->setCursorVisible(false);
    11761047    }
    1177 
    1178     update();
    1179     d->emitCursorPositionChanged();
    11801048}
    11811049
     
    11931061{
    11941062    Q_D(const QLineEdit);
    1195     return d->isUndoAvailable();
     1063    return d->control->isUndoAvailable();
    11961064}
    11971065
     
    12091077{
    12101078    Q_D(const QLineEdit);
    1211     return d->isRedoAvailable();
     1079    return d->control->isRedoAvailable();
    12121080}
    12131081
     
    12451113{
    12461114    Q_D(const QLineEdit);
    1247     return d->hasAcceptableInput(d->text);
     1115    return d->control->hasAcceptableInput();
    12481116}
    12491117
     
    12641132    updateGeometry();
    12651133    update();
     1134}
     1135
     1136/*!
     1137    \since 4.6
     1138    Sets the \a margins around the text inside the frame.
     1139
     1140    See also textMargins().
     1141*/
     1142void QLineEdit::setTextMargins(const QMargins &margins)
     1143{
     1144    setTextMargins(margins.left(), margins.top(), margins.right(), margins.bottom());
    12661145}
    12671146
     
    12831162    if (bottom)
    12841163        *bottom = d->bottomTextMargin;
     1164}
     1165
     1166/*!
     1167    \since 4.6
     1168    Returns the widget's text margins.
     1169
     1170    \sa setTextMargins()
     1171*/
     1172QMargins QLineEdit::textMargins() const
     1173{
     1174    Q_D(const QLineEdit);
     1175    return QMargins(d->leftTextMargin, d->topTextMargin, d->rightTextMargin, d->bottomTextMargin);
    12851176}
    12861177
     
    13511242{
    13521243    Q_D(const QLineEdit);
    1353     return (d->maskData ? d->inputMask + QLatin1Char(';') + d->blank : QString());
     1244    return d->control->inputMask();
    13541245}
    13551246
     
    13571248{
    13581249    Q_D(QLineEdit);
    1359     d->parseInputMask(inputMask);
    1360     if (d->maskData)
    1361         d->moveCursor(d->nextMaskBlank(0));
     1250    d->control->setInputMask(inputMask);
    13621251}
    13631252
     
    13741263{
    13751264    Q_D(QLineEdit);
    1376     d->selstart = d->selend = d->cursor = 0;
    1377     d->moveCursor(d->text.length(), true);
     1265    d->control->selectAll();
    13781266}
    13791267
     
    13871275{
    13881276    Q_D(QLineEdit);
    1389     d->deselect();
    1390     d->finishChange();
     1277    d->control->deselect();
    13911278}
    13921279
     
    14031290//     q->resetInputContext(); //#### FIX ME IN QT
    14041291    Q_D(QLineEdit);
    1405     int priorState = d->undoState;
    1406     d->removeSelectedText();
    1407     d->insert(newText);
    1408     d->finishChange(priorState);
     1292    d->control->insert(newText);
    14091293}
    14101294
     
    14171301{
    14181302    Q_D(QLineEdit);
    1419     int priorState = d->undoState;
    14201303    resetInputContext();
    1421     d->selstart = 0;
    1422     d->selend = d->text.length();
    1423     d->removeSelectedText();
    1424     d->separate();
    1425     d->finishChange(priorState, /*update*/false, /*edited*/false);
     1304    d->control->clear();
    14261305}
    14271306
     
    14361315    Q_D(QLineEdit);
    14371316    resetInputContext();
    1438     d->undo();
    1439     d->finishChange(-1, true);
     1317    d->control->undo();
    14401318}
    14411319
     
    14481326    Q_D(QLineEdit);
    14491327    resetInputContext();
    1450     d->redo();
    1451     d->finishChange();
     1328    d->control->redo();
    14521329}
    14531330
     
    14711348{
    14721349    Q_D(const QLineEdit);
    1473     return d->readOnly;
     1350    return d->control->isReadOnly();
    14741351}
    14751352
     
    14771354{
    14781355    Q_D(QLineEdit);
    1479     if (d->readOnly != enable) {
    1480         d->readOnly = enable;
    1481         setAttribute(Qt::WA_MacShowFocusRect, !d->readOnly);
    1482         setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod(this));
     1356    if (d->control->isReadOnly() != enable) {
     1357        d->control->setReadOnly(enable);
     1358        setAttribute(Qt::WA_MacShowFocusRect, !enable);
     1359        setAttribute(Qt::WA_InputMethodEnabled, d->shouldEnableInputMethod());
    14831360#ifndef QT_NO_CURSOR
    14841361        setCursor(enable ? Qt::ArrowCursor : Qt::IBeamCursor);
     
    15191396{
    15201397    Q_D(const QLineEdit);
    1521     d->copy();
     1398    d->control->copy();
    15221399}
    15231400
     
    15361413{
    15371414    Q_D(QLineEdit);
    1538     if (echoMode() == PasswordEchoOnEdit && !d->passwordEchoEditing) {
    1539         // Clear the edit and reset to normal echo mode when pasting; the echo
    1540         // mode switches back when the edit loses focus.  ### changes a public
    1541         // property, resets current content
    1542         d->updatePasswordEchoEditing(true);
    1543         clear();
    1544     }
    1545     insert(QApplication::clipboard()->text(QClipboard::Clipboard));
    1546 }
    1547 
    1548 void QLineEditPrivate::copy(bool clipboard) const
    1549 {
    1550     Q_Q(const QLineEdit);
    1551     QString t = q->selectedText();
    1552     if (!t.isEmpty() && echoMode == QLineEdit::Normal) {
    1553         q->disconnect(QApplication::clipboard(), SIGNAL(selectionChanged()), q, 0);
    1554         QApplication::clipboard()->setText(t, clipboard ? QClipboard::Clipboard : QClipboard::Selection);
    1555         q->connect(QApplication::clipboard(), SIGNAL(selectionChanged()),
    1556                    q, SLOT(_q_clipboardChanged()));
    1557     }
     1415    d->control->paste();
    15581416}
    15591417
     
    15651423{
    15661424    Q_D(QLineEdit);
    1567 #ifndef QT_NO_SHORTCUT
    1568     if (e->type() == QEvent::ShortcutOverride && !d->readOnly) {
    1569         QKeyEvent* ke = (QKeyEvent*) e;
    1570         if (ke == QKeySequence::Copy
    1571             || ke == QKeySequence::Paste
    1572             || ke == QKeySequence::Cut
    1573             || ke == QKeySequence::Redo
    1574             || ke == QKeySequence::Undo
    1575             || ke == QKeySequence::MoveToNextWord
    1576             || ke == QKeySequence::MoveToPreviousWord
    1577             || ke == QKeySequence::MoveToStartOfDocument
    1578             || ke == QKeySequence::MoveToEndOfDocument
    1579             || ke == QKeySequence::SelectNextWord
    1580             || ke == QKeySequence::SelectPreviousWord
    1581             || ke == QKeySequence::SelectStartOfLine
    1582             || ke == QKeySequence::SelectEndOfLine
    1583             || ke == QKeySequence::SelectStartOfBlock
    1584             || ke == QKeySequence::SelectEndOfBlock
    1585             || ke == QKeySequence::SelectStartOfDocument
    1586             || ke == QKeySequence::SelectAll
    1587             || ke == QKeySequence::SelectEndOfDocument) {
    1588             ke->accept();
    1589         } else if (ke->modifiers() == Qt::NoModifier || ke->modifiers() == Qt::ShiftModifier
    1590                    || ke->modifiers() == Qt::KeypadModifier) {
    1591             if (ke->key() < Qt::Key_Escape) {
    1592                 ke->accept();
    1593             } else {
    1594                 switch (ke->key()) {
    1595                 case Qt::Key_Delete:
    1596                 case Qt::Key_Home:
    1597                 case Qt::Key_End:
    1598                 case Qt::Key_Backspace:
    1599                 case Qt::Key_Left:
    1600                 case Qt::Key_Right:
    1601                     ke->accept();
    1602                 default:
    1603                     break;
    1604                 }
    1605             }
    1606         }
    1607     } else
    1608 #endif
    1609         if (e->type() == QEvent::Timer) {
     1425    if (e->type() == QEvent::Timer) {
    16101426        // should be timerEvent, is here for binary compatibility
    16111427        int timerId = ((QTimerEvent*)e)->timerId();
    1612         if (timerId == d->cursorTimer) {
    1613             QStyleOptionFrameV2 opt;
    1614             initStyleOption(&opt);
    1615             if(!hasSelectedText()
    1616                || style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, this))
    1617                 d->setCursorVisible(!d->cursorVisible);
     1428        if (false) {
    16181429#ifndef QT_NO_DRAGANDDROP
    16191430        } else if (timerId == d->dndTimer.timerId()) {
     
    16231434        else if (timerId == d->tripleClickTimer.timerId())
    16241435            d->tripleClickTimer.stop();
    1625 #ifdef QT_KEYPAD_NAVIGATION
    1626         else if (timerId == d->deleteAllTimer.timerId()) {
    1627             d->deleteAllTimer.stop();
    1628             clear();
    1629         }
    1630 #endif
    16311436    } else if (e->type() == QEvent::ContextMenu) {
    16321437#ifndef QT_NO_IM
    1633         if (d->composeMode())
     1438        if (d->control->composeMode())
    16341439            return true;
    16351440#endif
    1636         d->separate();
     1441        //d->separate();
    16371442    } else if (e->type() == QEvent::WindowActivate) {
    16381443        QTimer::singleShot(0, this, SLOT(_q_handleWindowActivate()));
    1639     }
     1444    }else if(e->type() == QEvent::ShortcutOverride){
     1445        d->control->processEvent(e);
     1446    } else if (e->type() == QEvent::KeyRelease) {
     1447        d->control->setCursorBlinkPeriod(QApplication::cursorFlashTime());
     1448    } else if (e->type() == QEvent::Show) {
     1449        //In order to get the cursor blinking if QComboBox::setEditable is called when the combobox has focus
     1450        if (hasFocus()) {
     1451            d->control->setCursorBlinkPeriod(QApplication::cursorFlashTime());
     1452            QStyleOptionFrameV2 opt;
     1453            initStyleOption(&opt);
     1454            if ((!hasSelectedText() && d->control->preeditAreaText().isEmpty())
     1455                || style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, this))
     1456                d->setCursorVisible(true);
     1457        }
     1458    }
     1459
    16401460#ifdef QT_KEYPAD_NAVIGATION
    16411461    if (QApplication::keypadNavigationEnabled()) {
    1642         if ((e->type() == QEvent::KeyPress) || (e->type() == QEvent::KeyRelease)) {
    1643             QKeyEvent *ke = (QKeyEvent *)e;
    1644             if (ke->key() == Qt::Key_Back) {
    1645                 if (ke->isAutoRepeat()) {
    1646                     // Swallow it. We don't want back keys running amok.
    1647                     ke->accept();
    1648                     return true;
    1649                 }
    1650                 if ((e->type() == QEvent::KeyRelease)
    1651                     && !isReadOnly()
    1652                     && d->deleteAllTimer.isActive()) {
    1653                     d->deleteAllTimer.stop();
    1654                     backspace();
    1655                     ke->accept();
    1656                     return true;
    1657                 }
    1658             }
    1659         } else if (e->type() == QEvent::EnterEditFocus) {
     1462        if (e->type() == QEvent::EnterEditFocus) {
    16601463            end(false);
    1661             if (!d->cursorTimer) {
    1662                 int cft = QApplication::cursorFlashTime();
    1663                 d->cursorTimer = cft ? startTimer(cft/2) : -1;
    1664             }
     1464            d->setCursorVisible(true);
     1465            d->control->setCursorBlinkPeriod(QApplication::cursorFlashTime());
    16651466        } else if (e->type() == QEvent::LeaveEditFocus) {
    16661467            d->setCursorVisible(false);
    1667             if (d->cursorTimer > 0)
    1668                 killTimer(d->cursorTimer);
    1669             d->cursorTimer = 0;
    1670 
    1671             if (!d->emitingEditingFinished) {
    1672                 if (hasAcceptableInput() || d->fixup()) {
    1673                     d->emitingEditingFinished = true;
    1674                     emit editingFinished();
    1675                     d->emitingEditingFinished = false;
    1676                 }
    1677             }
     1468            d->control->setCursorBlinkPeriod(0);
     1469            if (d->control->hasAcceptableInput() || d->control->fixup())
     1470                emit editingFinished();
    16781471        }
    16791472    }
     
    16881481    Q_D(QLineEdit);
    16891482    if (d->sendMouseEventToInputContext(e))
    1690         return;
     1483        return;
    16911484    if (e->button() == Qt::RightButton)
    16921485        return;
     
    16951488        setEditFocus(true);
    16961489        // Get the completion list to pop up.
    1697         if (d->completer)
    1698             d->completer->complete();
     1490        if (d->control->completer())
     1491            d->control->completer()->complete();
    16991492    }
    17001493#endif
     
    17071500    int cursor = d->xToPos(e->pos().x());
    17081501#ifndef QT_NO_DRAGANDDROP
    1709     if (!mark && d->dragEnabled && d->echoMode == Normal &&
    1710          e->button() == Qt::LeftButton && d->inSelection(e->pos().x())) {
    1711         d->cursor = cursor;
    1712         update();
     1502    if (!mark && d->dragEnabled && d->control->echoMode() == Normal &&
     1503         e->button() == Qt::LeftButton && d->control->inSelection(e->pos().x())) {
    17131504        d->dndPos = e->pos();
    17141505        if (!d->dndTimer.isActive())
    17151506            d->dndTimer.start(QApplication::startDragTime(), this);
    1716         d->emitCursorPositionChanged();
    17171507    } else
    17181508#endif
    17191509    {
    1720         d->moveCursor(cursor, mark);
     1510        d->control->moveCursor(cursor, mark);
    17211511    }
    17221512}
     
    17281518    Q_D(QLineEdit);
    17291519    if (d->sendMouseEventToInputContext(e))
    1730         return;
     1520        return;
    17311521
    17321522    if (e->buttons() & Qt::LeftButton) {
     
    17381528#endif
    17391529        {
    1740             d->moveCursor(d->xToPos(e->pos().x()), true);
     1530            d->control->moveCursor(d->xToPos(e->pos().x()), true);
    17411531        }
    17421532    }
     
    17491539    Q_D(QLineEdit);
    17501540    if (d->sendMouseEventToInputContext(e))
    1751         return;
     1541        return;
    17521542#ifndef QT_NO_DRAGANDDROP
    17531543    if (e->button() == Qt::LeftButton) {
     
    17621552    if (QApplication::clipboard()->supportsSelection()) {
    17631553        if (e->button() == Qt::LeftButton) {
    1764             d->copy(false);
    1765         } else if (!d->readOnly && e->button() == Qt::MidButton) {
    1766             d->deselect();
     1554            d->control->copy(QClipboard::Selection);
     1555        } else if (!d->control->isReadOnly() && e->button() == Qt::MidButton) {
     1556            deselect();
    17671557            insert(QApplication::clipboard()->text(QClipboard::Selection));
    17681558        }
    17691559    }
    17701560#endif
     1561
     1562    if (!isReadOnly() && rect().contains(e->pos()))
     1563        d->handleSoftwareInputPanel(e->button(), d->clickCausedFocus);
     1564    d->clickCausedFocus = 0;
    17711565}
    17721566
     
    17771571    Q_D(QLineEdit);
    17781572    if (d->sendMouseEventToInputContext(e))
    1779         return;
     1573        return;
    17801574    if (e->button() == Qt::LeftButton) {
    1781         deselect();
    1782         d->cursor = d->xToPos(e->pos().x());
    1783         d->cursor = d->textLayout.previousCursorPosition(d->cursor, QTextLayout::SkipWords);
    1784         // ## text layout should support end of words.
    1785         int end = d->textLayout.nextCursorPosition(d->cursor, QTextLayout::SkipWords);
    1786         while (end > d->cursor && d->text[end-1].isSpace())
    1787             --end;
    1788         d->moveCursor(end, true);
     1575        d->control->selectWordAtPos(d->xToPos(e->pos().x()));
    17891576        d->tripleClickTimer.start(QApplication::doubleClickInterval(), this);
    17901577        d->tripleClick = e->pos();
     
    18261613{
    18271614    Q_D(QLineEdit);
    1828 
    1829     bool inlineCompletionAccepted = false;
    1830 
    1831 #ifndef QT_NO_COMPLETER
    1832     if (d->completer) {
    1833         QCompleter::CompletionMode completionMode = d->completer->completionMode();
    1834         if ((completionMode == QCompleter::PopupCompletion
    1835              || completionMode == QCompleter::UnfilteredPopupCompletion)
    1836             &&d->completer->popup()
    1837             && d->completer->popup()->isVisible()) {
    1838             // The following keys are forwarded by the completer to the widget
    1839             // Ignoring the events lets the completer provide suitable default behavior
    1840             switch (event->key()) {
    1841             case Qt::Key_Escape:
    1842                 event->ignore();
    1843                 return;
    1844             case Qt::Key_Enter:
    1845             case Qt::Key_Return:
    1846             case Qt::Key_F4:
    1847 #ifdef QT_KEYPAD_NAVIGATION
    1848             case Qt::Key_Select:
    1849                 if (!QApplication::keypadNavigationEnabled())
    1850                     break;
    1851 #endif
    1852                 d->completer->popup()->hide(); // just hide. will end up propagating to parent
    1853             default:
    1854                 break; // normal key processing
    1855             }
    1856         } else if (completionMode == QCompleter::InlineCompletion) {
    1857             switch (event->key()) {
    1858             case Qt::Key_Enter:
    1859             case Qt::Key_Return:
    1860             case Qt::Key_F4:
    1861 #ifdef QT_KEYPAD_NAVIGATION
    1862             case Qt::Key_Select:
    1863                 if (!QApplication::keypadNavigationEnabled())
    1864                     break;
    1865 #endif
    1866                 if (!d->completer->currentCompletion().isEmpty() && d->selend > d->selstart
    1867                     && d->selend == d->text.length()) {
    1868                     setText(d->completer->currentCompletion());
    1869                     inlineCompletionAccepted = true;
    1870                 }
    1871             default:
    1872                 break; // normal key processing
    1873             }
    1874         }
    1875     }
    1876 #endif // QT_NO_COMPLETER
    1877 
    1878 #ifdef QT_KEYPAD_NAVIGATION
     1615    #ifdef QT_KEYPAD_NAVIGATION
    18791616    bool select = false;
    18801617    switch (event->key()) {
     
    18831620                if (hasEditFocus()) {
    18841621                    setEditFocus(false);
    1885                     if (d->completer && d->completer->popup()->isVisible())
    1886                         d->completer->popup()->hide();
     1622                    if (d->control->completer() && d->control->completer()->popup()->isVisible())
     1623                        d->control->completer()->popup()->hide();
    18871624                    select = true;
    18881625                }
     
    19031640                    {
    19041641                        setEditFocus(true);
     1642#ifndef Q_OS_SYMBIAN
    19051643                        clear();
     1644#endif
    19061645                    } else {
    19071646                        event->ignore();
     
    19201659    }
    19211660#endif
    1922 
    1923     if (echoMode() == PasswordEchoOnEdit
    1924         && !d->passwordEchoEditing
    1925         && !isReadOnly()
    1926         && !event->text().isEmpty()
    1927 #ifdef QT_KEYPAD_NAVIGATION
    1928         && event->key() != Qt::Key_Select
    1929         && event->key() != Qt::Key_Up
    1930         && event->key() != Qt::Key_Down
    1931         && event->key() != Qt::Key_Back
    1932 #endif
    1933         && !(event->modifiers() & Qt::ControlModifier)) {
    1934         // Clear the edit and reset to normal echo mode while editing; the
    1935         // echo mode switches back when the edit loses focus.  ### changes a
    1936         // public property, resets current content.  dubious code; you can
    1937         // navigate with keys up, down, back, and select(?), but if you press
    1938         // "left" or "right" it clears?
    1939         d->updatePasswordEchoEditing(true);
    1940         clear();
    1941     }
    1942 
    1943     d->setCursorVisible(true);
    1944     if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) {
    1945         if (hasAcceptableInput() || d->fixup()) {
    1946             emit returnPressed();
    1947             d->emitingEditingFinished = true;
    1948             emit editingFinished();
    1949             d->emitingEditingFinished = false;
    1950         }
    1951         if (inlineCompletionAccepted)
    1952             event->accept();
    1953         else
    1954             event->ignore();
    1955         return;
    1956     }
    1957     bool unknown = false;
    1958 
    1959     if (false) {
    1960     }
    1961 #ifndef QT_NO_SHORTCUT
    1962     else if (event == QKeySequence::Undo) {
    1963         if (!d->readOnly)
    1964             undo();
    1965     }
    1966     else if (event == QKeySequence::Redo) {
    1967         if (!d->readOnly)
    1968             redo();
    1969     }
    1970     else if (event == QKeySequence::SelectAll) {
    1971         selectAll();
    1972     }
    1973 #ifndef QT_NO_CLIPBOARD
    1974     else if (event == QKeySequence::Copy) {
    1975         copy();
    1976     }
    1977     else if (event == QKeySequence::Paste) {
    1978         if (!d->readOnly)
    1979             paste();
    1980     }
    1981     else if (event == QKeySequence::Cut) {
    1982         if (!d->readOnly) {
    1983             cut();
    1984         }
    1985     }
    1986     else if (event == QKeySequence::DeleteEndOfLine) {
    1987         if (!d->readOnly) {
    1988             setSelection(d->cursor, d->text.size());
    1989             copy();
    1990             del();
    1991         }
    1992     }
    1993 #endif //QT_NO_CLIPBOARD
    1994     else if (event == QKeySequence::MoveToStartOfLine) {
    1995         home(0);
    1996     }
    1997     else if (event == QKeySequence::MoveToEndOfLine) {
    1998         end(0);
    1999     }
    2000     else if (event == QKeySequence::SelectStartOfLine) {
    2001         home(1);
    2002     }
    2003     else if (event == QKeySequence::SelectEndOfLine) {
    2004         end(1);
    2005     }
    2006     else if (event == QKeySequence::MoveToNextChar) {
    2007 #if !defined(Q_WS_WIN) || defined(QT_NO_COMPLETER)
    2008         if (d->hasSelectedText()) {
    2009 #else
    2010         if (d->hasSelectedText() && d->completer
    2011             && d->completer->completionMode() == QCompleter::InlineCompletion) {
    2012 #endif
    2013             d->moveCursor(d->selend, false);
    2014         } else {
    2015             cursorForward(0, layoutDirection() == Qt::LeftToRight ? 1 : -1);
    2016         }
    2017     }
    2018     else if (event == QKeySequence::SelectNextChar) {
    2019         cursorForward(1, layoutDirection() == Qt::LeftToRight ? 1 : -1);
    2020     }
    2021     else if (event == QKeySequence::MoveToPreviousChar) {
    2022 #if !defined(Q_WS_WIN) || defined(QT_NO_COMPLETER)
    2023         if (d->hasSelectedText()) {
    2024 #else
    2025         if (d->hasSelectedText() && d->completer
    2026             && d->completer->completionMode() == QCompleter::InlineCompletion) {
    2027 #endif
    2028             d->moveCursor(d->selstart, false);
    2029         } else {
    2030             cursorBackward(0, layoutDirection() == Qt::LeftToRight ? 1 : -1);
    2031         }
    2032     }
    2033     else if (event == QKeySequence::SelectPreviousChar) {
    2034         cursorBackward(1, layoutDirection() == Qt::LeftToRight ? 1 : -1);
    2035     }
    2036     else if (event == QKeySequence::MoveToNextWord) {
    2037         if (echoMode() == Normal)
    2038             layoutDirection() == Qt::LeftToRight ? cursorWordForward(0) : cursorWordBackward(0);
    2039         else
    2040             layoutDirection() == Qt::LeftToRight ? end(0) : home(0);
    2041     }
    2042     else if (event == QKeySequence::MoveToPreviousWord) {
    2043         if (echoMode() == Normal)
    2044             layoutDirection() == Qt::LeftToRight ? cursorWordBackward(0) : cursorWordForward(0);
    2045         else if (!d->readOnly) {
    2046             layoutDirection() == Qt::LeftToRight ? home(0) : end(0);
    2047         }
    2048     }
    2049     else if (event == QKeySequence::SelectNextWord) {
    2050         if (echoMode() == Normal)
    2051             layoutDirection() == Qt::LeftToRight ? cursorWordForward(1) : cursorWordBackward(1);
    2052         else
    2053             layoutDirection() == Qt::LeftToRight ? end(1) : home(1);
    2054     }
    2055     else if (event == QKeySequence::SelectPreviousWord) {
    2056         if (echoMode() == Normal)
    2057             layoutDirection() == Qt::LeftToRight ? cursorWordBackward(1) : cursorWordForward(1);
    2058         else
    2059             layoutDirection() == Qt::LeftToRight ? home(1) : end(1);
    2060     }
    2061     else if (event == QKeySequence::Delete) {
    2062         if (!d->readOnly)
    2063             del();
    2064     }
    2065     else if (event == QKeySequence::DeleteEndOfWord) {
    2066         if (!d->readOnly) {
    2067             cursorWordForward(true);
    2068             del();
    2069         }
    2070     }
    2071     else if (event == QKeySequence::DeleteStartOfWord) {
    2072         if (!d->readOnly) {
    2073             cursorWordBackward(true);
    2074             del();
    2075         }
    2076     }
    2077 #endif // QT_NO_SHORTCUT
    2078     else {
    2079 #ifdef Q_WS_MAC
    2080         if (event->key() == Qt::Key_Up || event->key() == Qt::Key_Down) {
    2081             Qt::KeyboardModifiers myModifiers = (event->modifiers() & ~Qt::KeypadModifier);
    2082             if (myModifiers & Qt::ShiftModifier) {
    2083                 if (myModifiers == (Qt::ControlModifier|Qt::ShiftModifier)
    2084                         || myModifiers == (Qt::AltModifier|Qt::ShiftModifier)
    2085                         || myModifiers == Qt::ShiftModifier) {
    2086 
    2087                     event->key() == Qt::Key_Up ? home(1) : end(1);
    2088                 }
    2089             } else {
    2090                 if ((myModifiers == Qt::ControlModifier
    2091                      || myModifiers == Qt::AltModifier
    2092                      || myModifiers == Qt::NoModifier)) {
    2093                     event->key() == Qt::Key_Up ? home(0) : end(0);
    2094                 }
    2095             }
    2096         }
    2097 #endif
    2098         if (event->modifiers() & Qt::ControlModifier) {
    2099             switch (event->key()) {
    2100             case Qt::Key_Backspace:
    2101                 if (!d->readOnly) {
    2102                     cursorWordBackward(true);
    2103                     del();
    2104                 }
    2105                 break;
    2106 #ifndef QT_NO_COMPLETER
    2107             case Qt::Key_Up:
    2108             case Qt::Key_Down:
    2109                 d->complete(event->key());
    2110                 break;
    2111 #endif
    2112 #if defined(Q_WS_X11)
    2113             case Qt::Key_E:
    2114                 end(0);
    2115                 break;
    2116 
    2117             case Qt::Key_U:
    2118                 if (!d->readOnly) {
    2119                     setSelection(0, d->text.size());
    2120 #ifndef QT_NO_CLIPBOARD
    2121                     copy();
    2122 #endif
    2123                     del();
    2124                 }
    2125             break;
    2126 #endif
    2127             default:
    2128                 unknown = true;
    2129             }
    2130         } else { // ### check for *no* modifier
    2131             switch (event->key()) {
    2132             case Qt::Key_Backspace:
    2133                 if (!d->readOnly) {
    2134                     backspace();
    2135 #ifndef QT_NO_COMPLETER
    2136                     d->complete(Qt::Key_Backspace);
    2137 #endif
    2138                 }
    2139                 break;
    2140 #ifdef QT_KEYPAD_NAVIGATION
    2141             case Qt::Key_Back:
    2142                 if (QApplication::keypadNavigationEnabled() && !event->isAutoRepeat()
    2143                     && !isReadOnly()) {
    2144                     if (text().length() == 0) {
    2145                         setText(d->origText);
    2146 
    2147                         if (d->passwordEchoEditing)
    2148                             d->updatePasswordEchoEditing(false);
    2149 
    2150                         setEditFocus(false);
    2151                     } else if (!d->deleteAllTimer.isActive()) {
    2152                         d->deleteAllTimer.start(750, this);
    2153                     }
    2154                 } else {
    2155                     unknown = true;
    2156                 }
    2157                 break;
    2158 #endif
    2159 
    2160             default:
    2161                 unknown = true;
    2162             }
    2163         }
    2164     }
    2165 
    2166     if (event->key() == Qt::Key_Direction_L || event->key() == Qt::Key_Direction_R) {
    2167         setLayoutDirection((event->key() == Qt::Key_Direction_L) ? Qt::LeftToRight : Qt::RightToLeft);
    2168         d->updateTextLayout();
    2169         update();
    2170         unknown = false;
    2171     }
    2172 
    2173     if (unknown && !d->readOnly) {
    2174         QString t = event->text();
    2175         if (!t.isEmpty() && t.at(0).isPrint()) {
    2176             insert(t);
    2177 #ifndef QT_NO_COMPLETER
    2178             d->complete(event->key());
    2179 #endif
    2180             event->accept();
    2181             return;
    2182         }
    2183     }
    2184 
    2185     if (unknown)
    2186         event->ignore();
    2187     else
    2188         event->accept();
     1661    d->control->processKeyEvent(event);
     1662    if (event->isAccepted())
     1663        d->control->setCursorBlinkPeriod(0);
    21891664}
    21901665
     
    21981673    Q_D(const QLineEdit);
    21991674    return d->cursorRect();
    2200 }
    2201 
    2202 /*!
    2203   This function is not intended as polymorphic usage. Just a shared code
    2204   fragment that calls QInputContext::mouseHandler for this
    2205   class.
    2206 */
    2207 bool QLineEditPrivate::sendMouseEventToInputContext( QMouseEvent *e )
    2208 {
    2209 #if !defined QT_NO_IM
    2210     Q_Q(QLineEdit);
    2211     if ( composeMode() ) {
    2212         int tmp_cursor = xToPos(e->pos().x());
    2213         int mousePos = tmp_cursor - cursor;
    2214         if ( mousePos < 0 || mousePos > textLayout.preeditAreaText().length() ) {
    2215             mousePos = -1;
    2216             // don't send move events outside the preedit area
    2217             if ( e->type() == QEvent::MouseMove )
    2218                 return true;
    2219         }
    2220 
    2221         QInputContext *qic = q->inputContext();
    2222         if ( qic )
    2223             // may be causing reset() in some input methods
    2224             qic->mouseHandler(mousePos, e);
    2225         if (!textLayout.preeditAreaText().isEmpty())
    2226             return true;
    2227     }
    2228 #else
    2229     Q_UNUSED(e);
    2230 #endif
    2231 
    2232     return false;
    22331675}
    22341676
     
    22381680{
    22391681    Q_D(QLineEdit);
    2240     if (d->readOnly) {
     1682    if (d->control->isReadOnly()) {
    22411683        e->ignore();
    22421684        return;
    22431685    }
    22441686
    2245     if (echoMode() == PasswordEchoOnEdit && !d->passwordEchoEditing) {
     1687    if (echoMode() == PasswordEchoOnEdit && !d->control->passwordEchoEditing()) {
    22461688        // Clear the edit and reset to normal echo mode while entering input
    22471689        // method data; the echo mode switches back when the edit loses focus.
     
    22591701        && !e->preeditString().isEmpty()) {
    22601702        setEditFocus(true);
     1703#ifndef Q_OS_SYMBIAN
    22611704        selectAll();        // so text is replaced rather than appended to
    2262     }
    2263 #endif
    2264 
    2265     int priorState = d->undoState;
    2266     d->removeSelectedText();
    2267 
    2268     int c = d->cursor; // cursor position after insertion of commit string
    2269     if (e->replacementStart() <= 0)
    2270         c += e->commitString().length() + qMin(-e->replacementStart(), e->replacementLength());
    2271 
    2272     d->cursor += e->replacementStart();
    2273 
    2274     // insert commit string
    2275     if (e->replacementLength()) {
    2276         d->selstart = d->cursor;
    2277         d->selend = d->selstart + e->replacementLength();
    2278         d->removeSelectedText();
    2279     }
    2280     if (!e->commitString().isEmpty())
    2281         d->insert(e->commitString());
    2282 
    2283     d->cursor = qMin(c, d->text.length());
    2284 
    2285     d->textLayout.setPreeditArea(d->cursor, e->preeditString());
    2286     d->preeditCursor = e->preeditString().length();
    2287     d->hideCursor = false;
    2288     QList<QTextLayout::FormatRange> formats;
    2289     for (int i = 0; i < e->attributes().size(); ++i) {
    2290         const QInputMethodEvent::Attribute &a = e->attributes().at(i);
    2291         if (a.type == QInputMethodEvent::Cursor) {
    2292             d->preeditCursor = a.start;
    2293             d->hideCursor = !a.length;
    2294         } else if (a.type == QInputMethodEvent::TextFormat) {
    2295             QTextCharFormat f = qvariant_cast<QTextFormat>(a.value).toCharFormat();
    2296             if (f.isValid()) {
    2297                 QTextLayout::FormatRange o;
    2298                 o.start = a.start + d->cursor;
    2299                 o.length = a.length;
    2300                 o.format = f;
    2301                 formats.append(o);
    2302             }
    2303         }
    2304     }
    2305     d->textLayout.setAdditionalFormats(formats);
    2306     d->updateTextLayout();
    2307     update();
    2308     if (!e->commitString().isEmpty())
    2309         d->emitCursorPositionChanged();
    2310     d->finishChange(priorState);
     1705#endif
     1706    }
     1707#endif
     1708
     1709    d->control->processInputMethodEvent(e);
     1710
    23111711#ifndef QT_NO_COMPLETER
    23121712    if (!e->commitString().isEmpty())
    2313         d->complete(Qt::Key_unknown);
     1713        d->control->complete(Qt::Key_unknown);
    23141714#endif
    23151715}
     
    23261726        return font();
    23271727    case Qt::ImCursorPosition:
    2328         return QVariant((d->selend - d->selstart == 0) ? d->cursor : d->selend);
     1728        return QVariant(d->control->cursor());
    23291729    case Qt::ImSurroundingText:
    2330         return QVariant(d->text);
     1730        return QVariant(text());
    23311731    case Qt::ImCurrentSelection:
    23321732        return QVariant(selectedText());
     1733    case Qt::ImMaximumTextLength:
     1734        return QVariant(maxLength());
     1735    case Qt::ImAnchorPosition:
     1736        if (d->control->selectionStart() == d->control->selectionEnd())
     1737            return QVariant(d->control->cursor());
     1738        else if (d->control->selectionStart() == d->control->cursor())
     1739            return QVariant(d->control->selectionEnd());
     1740        else
     1741            return QVariant(d->control->selectionStart());
    23331742    default:
    23341743        return QVariant();
     
    23451754         e->reason() == Qt::BacktabFocusReason  ||
    23461755         e->reason() == Qt::ShortcutFocusReason) {
    2347         if (d->maskData)
    2348             d->moveCursor(d->nextMaskBlank(0));
    2349         else if (!d->hasSelectedText())
     1756        if (!d->control->inputMask().isEmpty())
     1757            d->control->moveCursor(d->control->nextMaskBlank(0));
     1758        else if (!d->control->hasSelectedText())
    23501759            selectAll();
     1760    } else if (e->reason() == Qt::MouseFocusReason) {
     1761        d->clickCausedFocus = 1;
    23511762    }
    23521763#ifdef QT_KEYPAD_NAVIGATION
    2353     if (!QApplication::keypadNavigationEnabled() || (hasEditFocus() && e->reason() == Qt::PopupFocusReason))
    2354 #endif
    2355     if (!d->cursorTimer) {
    2356         int cft = QApplication::cursorFlashTime();
    2357         d->cursorTimer = cft ? startTimer(cft/2) : -1;
    2358     }
     1764    if (!QApplication::keypadNavigationEnabled() || (hasEditFocus() && ( e->reason() == Qt::PopupFocusReason
     1765#ifdef Q_OS_SYMBIAN
     1766            || e->reason() == Qt::ActiveWindowFocusReason
     1767#endif
     1768            ))) {
     1769#endif
     1770    d->control->setCursorBlinkPeriod(QApplication::cursorFlashTime());
    23591771    QStyleOptionFrameV2 opt;
    23601772    initStyleOption(&opt);
    2361     if((!hasSelectedText() && d->textLayout.preeditAreaText().isEmpty())
     1773    if((!hasSelectedText() && d->control->preeditAreaText().isEmpty())
    23621774       || style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, this))
    23631775        d->setCursorVisible(true);
    23641776#ifdef Q_WS_MAC
    2365     if (d->echoMode == Password || d->echoMode == NoEcho)
     1777    if (d->control->echoMode() == Password || d->control->echoMode() == NoEcho)
    23661778        qt_mac_secure_keyboard(true);
    23671779#endif
    23681780#ifdef QT_KEYPAD_NAVIGATION
    2369     d->origText = d->text;
     1781        d->control->setCancelText(d->control->text());
     1782    }
    23701783#endif
    23711784#ifndef QT_NO_COMPLETER
    2372     if (d->completer) {
    2373         d->completer->setWidget(this);
    2374         QObject::connect(d->completer, SIGNAL(activated(QString)),
     1785    if (d->control->completer()) {
     1786        d->control->completer()->setWidget(this);
     1787        QObject::connect(d->control->completer(), SIGNAL(activated(QString)),
    23751788                         this, SLOT(setText(QString)));
    2376         QObject::connect(d->completer, SIGNAL(highlighted(QString)),
     1789        QObject::connect(d->control->completer(), SIGNAL(highlighted(QString)),
    23771790                         this, SLOT(_q_completionHighlighted(QString)));
    23781791    }
     
    23871800{
    23881801    Q_D(QLineEdit);
    2389     if (d->passwordEchoEditing) {
     1802    if (d->control->passwordEchoEditing()) {
    23901803        // Reset the echomode back to PasswordEchoOnEdit when the widget loses
    23911804        // focus.
     
    23991812
    24001813    d->setCursorVisible(false);
    2401     if (d->cursorTimer > 0)
    2402         killTimer(d->cursorTimer);
    2403     d->cursorTimer = 0;
    2404 
     1814    d->control->setCursorBlinkPeriod(0);
    24051815#ifdef QT_KEYPAD_NAVIGATION
    24061816    // editingFinished() is already emitted on LeaveEditFocus
     
    24091819    if (reason != Qt::PopupFocusReason
    24101820        || !(QApplication::activePopupWidget() && QApplication::activePopupWidget()->parentWidget() == this)) {
    2411         if (!d->emitingEditingFinished) {
    2412             if (hasAcceptableInput() || d->fixup()) {
    2413                 d->emitingEditingFinished = true;
     1821            if (hasAcceptableInput() || d->control->fixup())
    24141822                emit editingFinished();
    2415                 d->emitingEditingFinished = false;
    2416             }
    2417         }
    24181823#ifdef QT3_SUPPORT
    24191824        emit lostFocus();
     
    24211826    }
    24221827#ifdef Q_WS_MAC
    2423     if (d->echoMode == Password || d->echoMode == NoEcho)
     1828    if (d->control->echoMode() == Password || d->control->echoMode() == NoEcho)
    24241829        qt_mac_secure_keyboard(false);
    24251830#endif
    24261831#ifdef QT_KEYPAD_NAVIGATION
    2427     d->origText = QString();
     1832    d->control->setCancelText(QString());
    24281833#endif
    24291834#ifndef QT_NO_COMPLETER
    2430     if (d->completer) {
    2431         QObject::disconnect(d->completer, 0, this, 0);
     1835    if (d->control->completer()) {
     1836        QObject::disconnect(d->control->completer(), 0, this, 0);
    24321837    }
    24331838#endif
     
    24591864    switch (va & Qt::AlignVertical_Mask) {
    24601865     case Qt::AlignBottom:
    2461          d->vscroll = r.y() + r.height() - fm.height() - verticalMargin;
     1866         d->vscroll = r.y() + r.height() - fm.height() - d->verticalMargin;
    24621867         break;
    24631868     case Qt::AlignTop:
    2464          d->vscroll = r.y() + verticalMargin;
     1869         d->vscroll = r.y() + d->verticalMargin;
    24651870         break;
    24661871     default:
     
    24691874         break;
    24701875    }
    2471     QRect lineRect(r.x() + horizontalMargin, d->vscroll, r.width() - 2*horizontalMargin, fm.height());
    2472     QTextLine line = d->textLayout.lineAt(0);
    2473 
    2474     int cursor = d->cursor;
    2475     if (d->preeditCursor != -1)
    2476         cursor += d->preeditCursor;
    2477     // locate cursor position
    2478     int cix = qRound(line.cursorToX(cursor));
     1876    QRect lineRect(r.x() + d->horizontalMargin, d->vscroll, r.width() - 2*d->horizontalMargin, fm.height());
     1877
     1878    if (d->control->text().isEmpty()) {
     1879        if (!hasFocus() && !d->placeholderText.isEmpty()) {
     1880            QColor col = pal.text().color();
     1881            col.setAlpha(128);
     1882            QPen oldpen = p.pen();
     1883            p.setPen(col);
     1884            p.drawText(lineRect, va, d->placeholderText);
     1885            p.setPen(oldpen);
     1886            return;
     1887        }
     1888    }
     1889
     1890    int cix = qRound(d->control->cursorToX());
    24791891
    24801892    // horizontal scrolling. d->hscroll is the left indent from the beginning
     
    24861898    int minLB = qMax(0, -fm.minLeftBearing());
    24871899    int minRB = qMax(0, -fm.minRightBearing());
    2488     int widthUsed = qRound(line.naturalTextWidth()) + 1 + minRB;
     1900    int widthUsed = qRound(d->control->naturalTextWidth()) + 1 + minRB;
    24891901    if ((minLB + widthUsed) <=  lineRect.width()) {
    24901902        // text fits in lineRect; use hscroll for alignment
     
    25141926    }
    25151927    // the y offset is there to keep the baseline constant in case we have script changes in the text.
    2516     QPoint topLeft = lineRect.topLeft() - QPoint(d->hscroll, d->ascent - fm.ascent());
     1928    QPoint topLeft = lineRect.topLeft() - QPoint(d->hscroll, d->control->ascent() - fm.ascent());
    25171929
    25181930    // draw text, selections and cursors
    25191931#ifndef QT_NO_STYLE_STYLESHEET
    25201932    if (QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(style())) {
    2521         cssStyle->focusPalette(this, &panel, &pal);
     1933        cssStyle->styleSheetPalette(this, &panel, &pal);
    25221934    }
    25231935#endif
    25241936    p.setPen(pal.text().color());
    25251937
    2526     QVector<QTextLayout::FormatRange> selections;
     1938    int flags = QLineControl::DrawText;
     1939
    25271940#ifdef QT_KEYPAD_NAVIGATION
    25281941    if (!QApplication::keypadNavigationEnabled() || hasEditFocus())
    25291942#endif
    2530     if (d->selstart < d->selend || (d->cursorVisible && d->maskData && !d->readOnly)) {
    2531         QTextLayout::FormatRange o;
    2532         if (d->selstart < d->selend) {
    2533             o.start = d->selstart;
    2534             o.length = d->selend - d->selstart;
    2535             o.format.setBackground(pal.brush(QPalette::Highlight));
    2536             o.format.setForeground(pal.brush(QPalette::HighlightedText));
    2537         } else {
    2538             // mask selection
    2539             o.start = d->cursor;
    2540             o.length = 1;
    2541             o.format.setBackground(pal.brush(QPalette::Text));
    2542             o.format.setForeground(pal.brush(QPalette::Window));
    2543         }
    2544         selections.append(o);
     1943    if (d->control->hasSelectedText() || (d->cursorVisible && !d->control->inputMask().isEmpty() && !d->control->isReadOnly())){
     1944        flags |= QLineControl::DrawSelections;
     1945        // Palette only used for selections/mask and may not be in sync
     1946        if(d->control->palette() != pal)
     1947            d->control->setPalette(pal);
    25451948    }
    25461949
     
    25481951    // selection phase of input method, so the ordinary cursor should be
    25491952    // invisible if we have a preedit string.
    2550     d->textLayout.draw(&p, topLeft, selections, r);
    2551     if (d->cursorVisible && !d->readOnly && !d->hideCursor)
    2552         d->textLayout.drawCursor(&p, topLeft, cursor, style()->pixelMetric(QStyle::PM_TextCursorWidth));
     1953    if (d->cursorVisible && !d->control->isReadOnly())
     1954        flags |= QLineControl::DrawCursor;
     1955
     1956    d->control->setCursorWidth(style()->pixelMetric(QStyle::PM_TextCursorWidth));
     1957    d->control->draw(&p, topLeft, r, flags);
     1958
    25531959}
    25541960
     
    25601966{
    25611967    Q_D(QLineEdit);
    2562     if (!d->readOnly && e->mimeData()->hasFormat(QLatin1String("text/plain"))) {
     1968    if (!d->control->isReadOnly() && e->mimeData()->hasFormat(QLatin1String("text/plain"))) {
    25631969        e->acceptProposedAction();
    2564         d->cursor = d->xToPos(e->pos().x());
     1970        d->control->moveCursor(d->xToPos(e->pos().x()), false);
    25651971        d->cursorVisible = true;
    25661972        update();
    2567         d->emitCursorPositionChanged();
    25681973    }
    25691974}
     
    25911996    QString str = e->mimeData()->text();
    25921997
    2593     if (!str.isNull() && !d->readOnly) {
     1998    if (!str.isNull() && !d->control->isReadOnly()) {
    25941999        if (e->source() == this && e->dropAction() == Qt::CopyAction)
    25952000            deselect();
    2596         d->cursor =d->xToPos(e->pos().x());
    2597         int selStart = d->cursor;
    2598         int oldSelStart = d->selstart;
    2599         int oldSelEnd = d->selend;
     2001        int cursorPos = d->xToPos(e->pos().x());
     2002        int selStart = cursorPos;
     2003        int oldSelStart = d->control->selectionStart();
     2004        int oldSelEnd = d->control->selectionEnd();
     2005        d->control->moveCursor(cursorPos, false);
    26002006        d->cursorVisible = false;
    26012007        e->acceptProposedAction();
     
    26192025}
    26202026
    2621 void QLineEditPrivate::drag()
    2622 {
    2623     Q_Q(QLineEdit);
    2624     dndTimer.stop();
    2625     QMimeData *data = new QMimeData;
    2626     data->setText(q->selectedText());
    2627     QDrag *drag = new QDrag(q);
    2628     drag->setMimeData(data);
    2629     Qt::DropAction action = drag->start();
    2630     if (action == Qt::MoveAction && !readOnly && drag->target() != q) {
    2631         int priorState = undoState;
    2632         removeSelectedText();
    2633         finishChange(priorState);
    2634     }
    2635 }
    2636 
    26372027#endif // QT_NO_DRAGANDDROP
    26382028
     
    26772067    QMenu *popup = new QMenu(this);
    26782068    popup->setObjectName(QLatin1String("qt_edit_menu"));
    2679 
    2680     QAction *action = popup->addAction(QLineEdit::tr("&Undo") + ACCEL_KEY(QKeySequence::Undo));
    2681     action->setEnabled(d->isUndoAvailable());
    2682     connect(action, SIGNAL(triggered()), SLOT(undo()));
    2683 
    2684     action = popup->addAction(QLineEdit::tr("&Redo") + ACCEL_KEY(QKeySequence::Redo));
    2685     action->setEnabled(d->isRedoAvailable());
    2686     connect(action, SIGNAL(triggered()), SLOT(redo()));
    2687 
    2688     popup->addSeparator();
     2069    QAction *action = 0;
     2070
     2071    if (!isReadOnly()) {
     2072        action = popup->addAction(QLineEdit::tr("&Undo") + ACCEL_KEY(QKeySequence::Undo));
     2073        action->setEnabled(d->control->isUndoAvailable());
     2074        connect(action, SIGNAL(triggered()), SLOT(undo()));
     2075
     2076        action = popup->addAction(QLineEdit::tr("&Redo") + ACCEL_KEY(QKeySequence::Redo));
     2077        action->setEnabled(d->control->isRedoAvailable());
     2078        connect(action, SIGNAL(triggered()), SLOT(redo()));
     2079
     2080        popup->addSeparator();
     2081    }
    26892082
    26902083#ifndef QT_NO_CLIPBOARD
    2691     action = popup->addAction(QLineEdit::tr("Cu&t") + ACCEL_KEY(QKeySequence::Cut));
    2692     action->setEnabled(!d->readOnly && d->hasSelectedText());
    2693     connect(action, SIGNAL(triggered()), SLOT(cut()));
     2084    if (!isReadOnly()) {
     2085        action = popup->addAction(QLineEdit::tr("Cu&t") + ACCEL_KEY(QKeySequence::Cut));
     2086        action->setEnabled(!d->control->isReadOnly() && d->control->hasSelectedText()
     2087                && d->control->echoMode() == QLineEdit::Normal);
     2088        connect(action, SIGNAL(triggered()), SLOT(cut()));
     2089    }
    26942090
    26952091    action = popup->addAction(QLineEdit::tr("&Copy") + ACCEL_KEY(QKeySequence::Copy));
    2696     action->setEnabled(d->hasSelectedText());
     2092    action->setEnabled(d->control->hasSelectedText()
     2093            && d->control->echoMode() == QLineEdit::Normal);
    26972094    connect(action, SIGNAL(triggered()), SLOT(copy()));
    26982095
    2699     action = popup->addAction(QLineEdit::tr("&Paste") + ACCEL_KEY(QKeySequence::Paste));
    2700     action->setEnabled(!d->readOnly && !QApplication::clipboard()->text().isEmpty());
    2701     connect(action, SIGNAL(triggered()), SLOT(paste()));
    2702 #endif
    2703 
    2704     action = popup->addAction(QLineEdit::tr("Delete"));
    2705     action->setEnabled(!d->readOnly && !d->text.isEmpty() && d->hasSelectedText());
    2706     connect(action, SIGNAL(triggered()), SLOT(_q_deleteSelected()));
    2707 
    2708     popup->addSeparator();
     2096    if (!isReadOnly()) {
     2097        action = popup->addAction(QLineEdit::tr("&Paste") + ACCEL_KEY(QKeySequence::Paste));
     2098        action->setEnabled(!d->control->isReadOnly() && !QApplication::clipboard()->text().isEmpty());
     2099        connect(action, SIGNAL(triggered()), SLOT(paste()));
     2100    }
     2101#endif
     2102
     2103    if (!isReadOnly()) {
     2104        action = popup->addAction(QLineEdit::tr("Delete"));
     2105        action->setEnabled(!d->control->isReadOnly() && !d->control->text().isEmpty() && d->control->hasSelectedText());
     2106        connect(action, SIGNAL(triggered()), d->control, SLOT(_q_deleteSelected()));
     2107    }
     2108
     2109    if (!popup->isEmpty())
     2110        popup->addSeparator();
    27092111
    27102112    action = popup->addAction(QLineEdit::tr("Select All") + ACCEL_KEY(QKeySequence::SelectAll));
    2711     action->setEnabled(!d->text.isEmpty() && !d->allSelected());
     2113    action->setEnabled(!d->control->text().isEmpty() && !d->control->allSelected());
    27122114    d->selectAllAction = action;
    27132115    connect(action, SIGNAL(triggered()), SLOT(selectAll()));
     
    27232125
    27242126#if defined(Q_WS_WIN)
    2725     if (!d->readOnly && qt_use_rtl_extensions) {
     2127    if (!d->control->isReadOnly() && qt_use_rtl_extensions) {
    27262128#else
    2727     if (!d->readOnly) {
     2129    if (!d->control->isReadOnly()) {
    27282130#endif
    27292131        popup->addSeparator();
     
    27392141{
    27402142    Q_D(QLineEdit);
    2741     if(ev->type() == QEvent::ActivationChange) {
     2143    switch(ev->type())
     2144    {
     2145    case QEvent::ActivationChange:
    27422146        if (!palette().isEqual(QPalette::Active, QPalette::Inactive))
    27432147            update();
    2744     } else if (ev->type() == QEvent::FontChange
    2745                || ev->type() == QEvent::StyleChange
    2746                || ev->type() == QEvent::LayoutDirectionChange) {
    2747         d->updateTextLayout();
    2748     }
    2749     QWidget::changeEvent(ev);
    2750 }
    2751 
    2752 void QLineEditPrivate::_q_clipboardChanged()
    2753 {
    2754 }
    2755 
    2756 void QLineEditPrivate::_q_handleWindowActivate()
    2757 {
    2758     Q_Q(QLineEdit);
    2759     if (!q->hasFocus() && q->hasSelectedText())
    2760         q->deselect();
    2761 }
    2762 
    2763 void QLineEditPrivate::_q_deleteSelected()
    2764 {
    2765     Q_Q(QLineEdit);
    2766     if (!hasSelectedText())
    2767         return;
    2768 
    2769     int priorState = undoState;
    2770     q->resetInputContext();
    2771     removeSelectedText();
    2772     separate();
    2773     finishChange(priorState);
    2774 }
    2775 
    2776 void QLineEditPrivate::init(const QString& txt)
    2777 {
    2778     Q_Q(QLineEdit);
    2779 #ifndef QT_NO_CURSOR
    2780     q->setCursor(Qt::IBeamCursor);
    2781 #endif
    2782     q->setFocusPolicy(Qt::StrongFocus);
    2783     q->setAttribute(Qt::WA_InputMethodEnabled);
    2784     //   Specifies that this widget can use more, but is able to survive on
    2785     //   less, horizontal space; and is fixed vertically.
    2786     q->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed, QSizePolicy::LineEdit));
    2787     q->setBackgroundRole(QPalette::Base);
    2788     q->setAttribute(Qt::WA_KeyCompression);
    2789     q->setMouseTracking(true);
    2790     q->setAcceptDrops(true);
    2791     text = txt;
    2792     updateTextLayout();
    2793     cursor = text.length();
    2794 
    2795     q->setAttribute(Qt::WA_MacShowFocusRect);
    2796 }
    2797 
    2798 void QLineEditPrivate::updatePasswordEchoEditing(bool editing)
    2799 {
    2800     Q_Q(QLineEdit);
    2801     passwordEchoEditing = editing;
    2802     q->setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod(q));
    2803     updateTextLayout();
    2804     q->update();
    2805 }
    2806 
    2807 void QLineEditPrivate::updateTextLayout()
    2808 {
    2809     // replace certain non-printable characters with spaces (to avoid
    2810     // drawing boxes when using fonts that don't have glyphs for such
    2811     // characters)
    2812     Q_Q(QLineEdit);
    2813     QString str = q->displayText();
    2814     QChar* uc = str.data();
    2815     for (int i = 0; i < (int)str.length(); ++i) {
    2816         if ((uc[i] < 0x20 && uc[i] != 0x09)
    2817             || uc[i] == QChar::LineSeparator
    2818             || uc[i] == QChar::ParagraphSeparator
    2819             || uc[i] == QChar::ObjectReplacementCharacter)
    2820             uc[i] = QChar(0x0020);
    2821     }
    2822     textLayout.setFont(q->font());
    2823     textLayout.setText(str);
    2824     QTextOption option;
    2825     option.setTextDirection(q->layoutDirection());
    2826     option.setFlags(QTextOption::IncludeTrailingSpaces);
    2827     textLayout.setTextOption(option);
    2828 
    2829     textLayout.beginLayout();
    2830     QTextLine l = textLayout.createLine();
    2831     textLayout.endLayout();
    2832     ascent = qRound(l.ascent());
    2833 }
    2834 
    2835 int QLineEditPrivate::xToPos(int x, QTextLine::CursorPosition betweenOrOn) const
    2836 {
    2837     QRect cr = adjustedContentsRect();
    2838     x-= cr.x() - hscroll + horizontalMargin;
    2839     QTextLine l = textLayout.lineAt(0);
    2840     return l.xToCursor(x, betweenOrOn);
    2841 }
    2842 
    2843 QRect QLineEditPrivate::cursorRect() const
    2844 {
    2845     Q_Q(const QLineEdit);
    2846     QRect cr = adjustedContentsRect();
    2847     int cix = cr.x() - hscroll + horizontalMargin;
    2848     QTextLine l = textLayout.lineAt(0);
    2849     int c = cursor;
    2850     if (preeditCursor != -1)
    2851         c += preeditCursor;
    2852     cix += qRound(l.cursorToX(c));
    2853     int ch = qMin(cr.height(), q->fontMetrics().height() + 1);
    2854     int w = q->style()->pixelMetric(QStyle::PM_TextCursorWidth);
    2855     return QRect(cix-5, vscroll, w + 9, ch);
    2856 }
    2857 
    2858 QRect QLineEditPrivate::adjustedContentsRect() const
    2859 {
    2860     Q_Q(const QLineEdit);
    2861     QStyleOptionFrameV2 opt;
    2862     q->initStyleOption(&opt);
    2863     QRect r = q->style()->subElementRect(QStyle::SE_LineEditContents, &opt, q);
    2864     r.setX(r.x() + leftTextMargin);
    2865     r.setY(r.y() + topTextMargin);
    2866     r.setRight(r.right() - rightTextMargin);
    2867     r.setBottom(r.bottom() - bottomTextMargin);
    2868     return r;
    2869 }
    2870 
    2871 bool QLineEditPrivate::fixup() // this function assumes that validate currently returns != Acceptable
    2872 {
    2873 #ifndef QT_NO_VALIDATOR
    2874     if (validator) {
    2875         QString textCopy = text;
    2876         int cursorCopy = cursor;
    2877         validator->fixup(textCopy);
    2878         if (validator->validate(textCopy, cursorCopy) == QValidator::Acceptable) {
    2879             if (textCopy != text || cursorCopy != cursor)
    2880                 setText(textCopy, cursorCopy);
    2881             return true;
     2148        break;
     2149    case QEvent::FontChange:
     2150        d->control->setFont(font());
     2151        break;
     2152    case QEvent::StyleChange:
     2153        {
     2154            QStyleOptionFrameV2 opt;
     2155            initStyleOption(&opt);
     2156            d->control->setPasswordCharacter(style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, &opt, this));
    28822157        }
    2883     }
    2884 #endif
    2885     return false;
    2886 }
    2887 
    2888 void QLineEditPrivate::moveCursor(int pos, bool mark)
    2889 {
    2890     Q_Q(QLineEdit);
    2891     if (pos != cursor) {
    2892         separate();
    2893         if (maskData)
    2894             pos = pos > cursor ? nextMaskBlank(pos) : prevMaskBlank(pos);
    2895     }
    2896     bool fullUpdate = mark || hasSelectedText();
    2897     if (mark) {
    2898         int anchor;
    2899         if (selend > selstart && cursor == selstart)
    2900             anchor = selend;
    2901         else if (selend > selstart && cursor == selend)
    2902             anchor = selstart;
    2903         else
    2904             anchor = cursor;
    2905         selstart = qMin(anchor, pos);
    2906         selend = qMax(anchor, pos);
    2907         updateTextLayout();
    2908     } else {
    2909         deselect();
    2910     }
    2911     if (fullUpdate) {
    2912         cursor = pos;
    2913         q->update();
    2914     } else {
    2915         setCursorVisible(false);
    2916         cursor = pos;
    2917         setCursorVisible(true);
    2918         if (!adjustedContentsRect().contains(cursorRect()))
    2919             q->update();
    2920     }
    2921     QStyleOptionFrameV2 opt;
    2922     q->initStyleOption(&opt);
    2923     if (mark && !q->style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, q))
    2924         setCursorVisible(false);
    2925     if (mark || selDirty) {
    2926         selDirty = false;
    2927         emit q->selectionChanged();
    2928     }
    2929     emitCursorPositionChanged();
    2930 }
    2931 
    2932 void QLineEditPrivate::finishChange(int validateFromState, bool update, bool edited)
    2933 {
    2934     Q_Q(QLineEdit);
    2935     bool lineDirty = selDirty;
    2936     if (textDirty) {
    2937         // do validation
    2938         bool wasValidInput = validInput;
    2939         validInput = true;
    2940 #ifndef QT_NO_VALIDATOR
    2941         if (validator) {
    2942             validInput = false;
    2943             QString textCopy = text;
    2944             int cursorCopy = cursor;
    2945             validInput = (validator->validate(textCopy, cursorCopy) != QValidator::Invalid);
    2946             if (validInput) {
    2947                 if (text != textCopy) {
    2948                     setText(textCopy, cursorCopy);
    2949                     return;
    2950                 }
    2951                 cursor = cursorCopy;
    2952             }
    2953         }
    2954 #endif
    2955         if (validateFromState >= 0 && wasValidInput && !validInput) {
    2956             undo(validateFromState);
    2957             history.resize(undoState);
    2958             if (modifiedState > undoState)
    2959                 modifiedState = -1;
    2960             validInput = true;
    2961             textDirty = false;
    2962         }
    2963         updateTextLayout();
    2964         lineDirty |= textDirty;
    2965         if (textDirty) {
    2966             textDirty = false;
    2967             QString actualText = maskData ? stripString(text) : text;
    2968             if (edited)
    2969                 emit q->textEdited(actualText);
    2970             q->updateMicroFocus();
    2971 #ifndef QT_NO_COMPLETER
    2972             if (edited && completer && completer->completionMode() != QCompleter::InlineCompletion)
    2973                 complete(-1); // update the popup on cut/paste/del
    2974 #endif
    2975             emit q->textChanged(actualText);
    2976         }
    2977 #ifndef QT_NO_ACCESSIBILITY
    2978         QAccessible::updateAccessibility(q, 0, QAccessible::ValueChanged);
    2979 #endif
    2980     }
    2981     if (selDirty) {
    2982         selDirty = false;
    2983         emit q->selectionChanged();
    2984     }
    2985     if (lineDirty || update)
    2986         q->update();
    2987     emitCursorPositionChanged();
    2988 }
    2989 
    2990 void QLineEditPrivate::emitCursorPositionChanged()
    2991 {
    2992     Q_Q(QLineEdit);
    2993     if (cursor != lastCursorPos) {
    2994         const int oldLast = lastCursorPos;
    2995         lastCursorPos = cursor;
    2996         emit q->cursorPositionChanged(oldLast, cursor);
    2997     }
    2998 }
    2999 
    3000 void QLineEditPrivate::setText(const QString& txt, int pos, bool edited)
    3001 {
    3002     Q_Q(QLineEdit);
    3003     q->resetInputContext();
    3004     deselect();
    3005     QString oldText = text;
    3006     if (maskData) {
    3007         text = maskString(0, txt, true);
    3008         text += clearString(text.length(), maxLength - text.length());
    3009     } else {
    3010         text = txt.isEmpty() ? txt : txt.left(maxLength);
    3011     }
    3012     history.clear();
    3013     modifiedState =  undoState = 0;
    3014     cursor = (pos < 0 || pos > text.length()) ? text.length() : pos;
    3015     textDirty = (oldText != text);
    3016     finishChange(-1, true, edited);
    3017 }
    3018 
    3019 
    3020 void QLineEditPrivate::setCursorVisible(bool visible)
    3021 {
    3022     Q_Q(QLineEdit);
    3023     if ((bool)cursorVisible == visible)
    3024         return;
    3025     if (cursorTimer)
    3026         cursorVisible = visible;
    3027     QRect r = cursorRect();
    3028     if (maskData)
    3029         q->update();
    3030     else
    3031         q->update(r);
    3032 }
    3033 
    3034 void QLineEditPrivate::addCommand(const Command& cmd)
    3035 {
    3036     if (separator && undoState && history[undoState-1].type != Separator) {
    3037         history.resize(undoState + 2);
    3038         history[undoState++] = Command(Separator, cursor, 0, selstart, selend);
    3039     } else {
    3040         history.resize(undoState + 1);
    3041     }
    3042     separator = false;
    3043     history[undoState++] = cmd;
    3044 }
    3045 
    3046 void QLineEditPrivate::insert(const QString& s)
    3047 {
    3048     if (hasSelectedText())
    3049         addCommand(Command(SetSelection, cursor, 0, selstart, selend));
    3050     if (maskData) {
    3051         QString ms = maskString(cursor, s);
    3052         for (int i = 0; i < (int) ms.length(); ++i) {
    3053             addCommand (Command(DeleteSelection, cursor+i, text.at(cursor+i), -1, -1));
    3054             addCommand(Command(Insert, cursor+i, ms.at(i), -1, -1));
    3055         }
    3056         text.replace(cursor, ms.length(), ms);
    3057         cursor += ms.length();
    3058         cursor = nextMaskBlank(cursor);
    3059         textDirty = true;
    3060     } else {
    3061         int remaining = maxLength - text.length();
    3062         if (remaining != 0) {
    3063             text.insert(cursor, s.left(remaining));
    3064             for (int i = 0; i < (int) s.left(remaining).length(); ++i)
    3065                addCommand(Command(Insert, cursor++, s.at(i), -1, -1));
    3066             textDirty = true;
    3067         }
    3068     }
    3069 }
    3070 
    3071 void QLineEditPrivate::del(bool wasBackspace)
    3072 {
    3073     if (cursor < (int) text.length()) {
    3074         if (hasSelectedText())
    3075             addCommand(Command(SetSelection, cursor, 0, selstart, selend));
    3076         addCommand (Command((CommandType)((maskData?2:0)+(wasBackspace?Remove:Delete)), cursor, text.at(cursor), -1, -1));
    3077         if (maskData) {
    3078             text.replace(cursor, 1, clearString(cursor, 1));
    3079             addCommand(Command(Insert, cursor, text.at(cursor), -1, -1));
    3080         } else {
    3081             text.remove(cursor, 1);
    3082         }
    3083         textDirty = true;
    3084     }
    3085 }
    3086 
    3087 void QLineEditPrivate::removeSelectedText()
    3088 {
    3089     if (selstart < selend && selend <= (int) text.length()) {
    3090         separate();
    3091         int i ;
    3092         addCommand(Command(SetSelection, cursor, 0, selstart, selend));
    3093         if (selstart <= cursor && cursor < selend) {
    3094             // cursor is within the selection. Split up the commands
    3095             // to be able to restore the correct cursor position
    3096             for (i = cursor; i >= selstart; --i)
    3097                 addCommand (Command(DeleteSelection, i, text.at(i), -1, 1));
    3098             for (i = selend - 1; i > cursor; --i)
    3099                 addCommand (Command(DeleteSelection, i - cursor + selstart - 1, text.at(i), -1, -1));
    3100         } else {
    3101             for (i = selend-1; i >= selstart; --i)
    3102                 addCommand (Command(RemoveSelection, i, text.at(i), -1, -1));
    3103         }
    3104         if (maskData) {
    3105             text.replace(selstart, selend - selstart,  clearString(selstart, selend - selstart));
    3106             for (int i = 0; i < selend - selstart; ++i)
    3107                 addCommand(Command(Insert, selstart + i, text.at(selstart + i), -1, -1));
    3108         } else {
    3109             text.remove(selstart, selend - selstart);
    3110         }
    3111         if (cursor > selstart)
    3112             cursor -= qMin(cursor, selend) - selstart;
    3113         deselect();
    3114         textDirty = true;
    3115 
    3116         // adjust hscroll to avoid gap
    3117         const int minRB = qMax(0, -q_func()->fontMetrics().minRightBearing());
    3118         updateTextLayout();
    3119         const QTextLine line = textLayout.lineAt(0);
    3120         const int widthUsed = qRound(line.naturalTextWidth()) + 1 + minRB;
    3121         hscroll = qMin(hscroll, widthUsed);
    3122     }
    3123 }
    3124 
    3125 void QLineEditPrivate::parseInputMask(const QString &maskFields)
    3126 {
    3127     int delimiter = maskFields.indexOf(QLatin1Char(';'));
    3128     if (maskFields.isEmpty() || delimiter == 0) {
    3129         if (maskData) {
    3130             delete [] maskData;
    3131             maskData = 0;
    3132             maxLength = 32767;
    3133             setText(QString());
    3134         }
    3135         return;
    3136     }
    3137 
    3138     if (delimiter == -1) {
    3139         blank = QLatin1Char(' ');
    3140         inputMask = maskFields;
    3141     } else {
    3142         inputMask = maskFields.left(delimiter);
    3143         blank = (delimiter + 1 < maskFields.length()) ? maskFields[delimiter + 1] : QLatin1Char(' ');
    3144     }
    3145 
    3146     // calculate maxLength / maskData length
    3147     maxLength = 0;
    3148     QChar c = 0;
    3149     for (int i=0; i<inputMask.length(); i++) {
    3150         c = inputMask.at(i);
    3151         if (i > 0 && inputMask.at(i-1) == QLatin1Char('\\')) {
    3152             maxLength++;
    3153             continue;
    3154         }
    3155         if (c != QLatin1Char('\\') && c != QLatin1Char('!') &&
    3156              c != QLatin1Char('<') && c != QLatin1Char('>') &&
    3157              c != QLatin1Char('{') && c != QLatin1Char('}') &&
    3158              c != QLatin1Char('[') && c != QLatin1Char(']'))
    3159             maxLength++;
    3160     }
    3161 
    3162     delete [] maskData;
    3163     maskData = new MaskInputData[maxLength];
    3164 
    3165     MaskInputData::Casemode m = MaskInputData::NoCaseMode;
    3166     c = 0;
    3167     bool s;
    3168     bool escape = false;
    3169     int index = 0;
    3170     for (int i = 0; i < inputMask.length(); i++) {
    3171         c = inputMask.at(i);
    3172         if (escape) {
    3173             s = true;
    3174             maskData[index].maskChar = c;
    3175             maskData[index].separator = s;
    3176             maskData[index].caseMode = m;
    3177             index++;
    3178             escape = false;
    3179         } else if (c == QLatin1Char('<')) {
    3180                 m = MaskInputData::Lower;
    3181         } else if (c == QLatin1Char('>')) {
    3182             m = MaskInputData::Upper;
    3183         } else if (c == QLatin1Char('!')) {
    3184             m = MaskInputData::NoCaseMode;
    3185         } else if (c != QLatin1Char('{') && c != QLatin1Char('}') && c != QLatin1Char('[') && c != QLatin1Char(']')) {
    3186             switch (c.unicode()) {
    3187             case 'A':
    3188             case 'a':
    3189             case 'N':
    3190             case 'n':
    3191             case 'X':
    3192             case 'x':
    3193             case '9':
    3194             case '0':
    3195             case 'D':
    3196             case 'd':
    3197             case '#':
    3198             case 'H':
    3199             case 'h':
    3200             case 'B':
    3201             case 'b':
    3202                 s = false;
    3203                 break;
    3204             case '\\':
    3205                 escape = true;
    3206             default:
    3207                 s = true;
    3208                 break;
    3209             }
    3210 
    3211             if (!escape) {
    3212                 maskData[index].maskChar = c;
    3213                 maskData[index].separator = s;
    3214                 maskData[index].caseMode = m;
    3215                 index++;
    3216             }
    3217         }
    3218     }
    3219     setText(text);
    3220 }
    3221 
    3222 
    3223 /* checks if the key is valid compared to the inputMask */
    3224 bool QLineEditPrivate::isValidInput(QChar key, QChar mask) const
    3225 {
    3226     switch (mask.unicode()) {
    3227     case 'A':
    3228         if (key.isLetter())
    3229             return true;
     2158        update();
    32302159        break;
    3231     case 'a':
    3232         if (key.isLetter() || key == blank)
    3233             return true;
    3234         break;
    3235     case 'N':
    3236         if (key.isLetterOrNumber())
    3237             return true;
    3238         break;
    3239     case 'n':
    3240         if (key.isLetterOrNumber() || key == blank)
    3241             return true;
    3242         break;
    3243     case 'X':
    3244         if (key.isPrint())
    3245             return true;
    3246         break;
    3247     case 'x':
    3248         if (key.isPrint() || key == blank)
    3249             return true;
    3250         break;
    3251     case '9':
    3252         if (key.isNumber())
    3253             return true;
    3254         break;
    3255     case '0':
    3256         if (key.isNumber() || key == blank)
    3257             return true;
    3258         break;
    3259     case 'D':
    3260         if (key.isNumber() && key.digitValue() > 0)
    3261             return true;
    3262         break;
    3263     case 'd':
    3264         if ((key.isNumber() && key.digitValue() > 0) || key == blank)
    3265             return true;
    3266         break;
    3267     case '#':
    3268         if (key.isNumber() || key == QLatin1Char('+') || key == QLatin1Char('-') || key == blank)
    3269             return true;
    3270         break;
    3271     case 'B':
    3272         if (key == QLatin1Char('0') || key == QLatin1Char('1'))
    3273             return true;
    3274         break;
    3275     case 'b':
    3276         if (key == QLatin1Char('0') || key == QLatin1Char('1') || key == blank)
    3277             return true;
    3278         break;
    3279     case 'H':
    3280         if (key.isNumber() || (key >= QLatin1Char('a') && key <= QLatin1Char('f')) || (key >= QLatin1Char('A') && key <= QLatin1Char('F')))
    3281             return true;
    3282         break;
    3283     case 'h':
    3284         if (key.isNumber() || (key >= QLatin1Char('a') && key <= QLatin1Char('f')) || (key >= QLatin1Char('A') && key <= QLatin1Char('F')) || key == blank)
    3285             return true;
     2160    case QEvent::LayoutDirectionChange:
     2161        d->control->setLayoutDirection(layoutDirection());
    32862162        break;
    32872163    default:
    32882164        break;
    32892165    }
    3290     return false;
    3291 }
    3292 
    3293 bool QLineEditPrivate::hasAcceptableInput(const QString &str) const
    3294 {
    3295 #ifndef QT_NO_VALIDATOR
    3296     QString textCopy = str;
    3297     int cursorCopy = cursor;
    3298     if (validator && validator->validate(textCopy, cursorCopy)
    3299         != QValidator::Acceptable)
    3300         return false;
    3301 #endif
    3302 
    3303     if (!maskData)
    3304         return true;
    3305 
    3306     if (str.length() != maxLength)
    3307         return false;
    3308 
    3309     for (int i=0; i < maxLength; ++i) {
    3310         if (maskData[i].separator) {
    3311             if (str.at(i) != maskData[i].maskChar)
    3312                 return false;
    3313         } else {
    3314             if (!isValidInput(str.at(i), maskData[i].maskChar))
    3315                 return false;
    3316         }
    3317     }
    3318     return true;
    3319 }
    3320 
    3321 /*
    3322   Applies the inputMask on \a str starting from position \a pos in the mask. \a clear
    3323   specifies from where characters should be gotten when a separator is met in \a str - true means
    3324   that blanks will be used, false that previous input is used.
    3325   Calling this when no inputMask is set is undefined.
    3326 */
    3327 QString QLineEditPrivate::maskString(uint pos, const QString &str, bool clear) const
    3328 {
    3329     if (pos >= (uint)maxLength)
    3330         return QString::fromLatin1("");
    3331 
    3332     QString fill;
    3333     fill = clear ? clearString(0, maxLength) : text;
    3334 
    3335     int strIndex = 0;
    3336     QString s = QString::fromLatin1("");
    3337     int i = pos;
    3338     while (i < maxLength) {
    3339         if (strIndex < str.length()) {
    3340             if (maskData[i].separator) {
    3341                 s += maskData[i].maskChar;
    3342                 if (str[(int)strIndex] == maskData[i].maskChar)
    3343                     strIndex++;
    3344                 ++i;
    3345             } else {
    3346                 if (isValidInput(str[(int)strIndex], maskData[i].maskChar)) {
    3347                     switch (maskData[i].caseMode) {
    3348                     case MaskInputData::Upper:
    3349                         s += str[(int)strIndex].toUpper();
    3350                         break;
    3351                     case MaskInputData::Lower:
    3352                         s += str[(int)strIndex].toLower();
    3353                         break;
    3354                     default:
    3355                         s += str[(int)strIndex];
    3356                     }
    3357                     ++i;
    3358                 } else {
    3359                     // search for separator first
    3360                     int n = findInMask(i, true, true, str[(int)strIndex]);
    3361                     if (n != -1) {
    3362                         if (str.length() != 1 || i == 0 || (i > 0 && (!maskData[i-1].separator || maskData[i-1].maskChar != str[(int)strIndex]))) {
    3363                             s += fill.mid(i, n-i+1);
    3364                             i = n + 1; // update i to find + 1
    3365                         }
    3366                     } else {
    3367                         // search for valid blank if not
    3368                         n = findInMask(i, true, false, str[(int)strIndex]);
    3369                         if (n != -1) {
    3370                             s += fill.mid(i, n-i);
    3371                             switch (maskData[n].caseMode) {
    3372                             case MaskInputData::Upper:
    3373                                 s += str[(int)strIndex].toUpper();
    3374                                 break;
    3375                             case MaskInputData::Lower:
    3376                                 s += str[(int)strIndex].toLower();
    3377                                 break;
    3378                             default:
    3379                                 s += str[(int)strIndex];
    3380                             }
    3381                             i = n + 1; // updates i to find + 1
    3382                         }
    3383                     }
    3384                 }
    3385                 strIndex++;
    3386             }
    3387         } else
    3388             break;
    3389     }
    3390 
    3391     return s;
    3392 }
    3393 
    3394 
    3395 
    3396 /*
    3397   Returns a "cleared" string with only separators and blank chars.
    3398   Calling this when no inputMask is set is undefined.
    3399 */
    3400 QString QLineEditPrivate::clearString(uint pos, uint len) const
    3401 {
    3402     if (pos >= (uint)maxLength)
    3403         return QString();
    3404 
    3405     QString s;
    3406     int end = qMin((uint)maxLength, pos + len);
    3407     for (int i=pos; i<end; i++)
    3408         if (maskData[i].separator)
    3409             s += maskData[i].maskChar;
    3410         else
    3411             s += blank;
    3412 
    3413     return s;
    3414 }
    3415 
    3416 /*
    3417   Strips blank parts of the input in a QLineEdit when an inputMask is set,
    3418   separators are still included. Typically "127.0__.0__.1__" becomes "127.0.0.1".
    3419 */
    3420 QString QLineEditPrivate::stripString(const QString &str) const
    3421 {
    3422     if (!maskData)
    3423         return str;
    3424 
    3425     QString s;
    3426     int end = qMin(maxLength, (int)str.length());
    3427     for (int i=0; i < end; i++)
    3428         if (maskData[i].separator)
    3429             s += maskData[i].maskChar;
    3430         else
    3431             if (str[i] != blank)
    3432                 s += str[i];
    3433 
    3434     return s;
    3435 }
    3436 
    3437 /* searches forward/backward in maskData for either a separator or a blank */
    3438 int QLineEditPrivate::findInMask(int pos, bool forward, bool findSeparator, QChar searchChar) const
    3439 {
    3440     if (pos >= maxLength || pos < 0)
    3441         return -1;
    3442 
    3443     int end = forward ? maxLength : -1;
    3444     int step = forward ? 1 : -1;
    3445     int i = pos;
    3446 
    3447     while (i != end) {
    3448         if (findSeparator) {
    3449             if (maskData[i].separator && maskData[i].maskChar == searchChar)
    3450                 return i;
    3451         } else {
    3452             if (!maskData[i].separator) {
    3453                 if (searchChar.isNull())
    3454                     return i;
    3455                 else if (isValidInput(searchChar, maskData[i].maskChar))
    3456                     return i;
    3457             }
    3458         }
    3459         i += step;
    3460     }
    3461     return -1;
    3462 }
    3463 
    3464 void QLineEditPrivate::undo(int until)
    3465 {
    3466     if (!isUndoAvailable())
    3467         return;
    3468     deselect();
    3469     while (undoState && undoState > until) {
    3470         Command& cmd = history[--undoState];
    3471         switch (cmd.type) {
    3472         case Insert:
    3473             text.remove(cmd.pos, 1);
    3474             cursor = cmd.pos;
    3475             break;
    3476         case SetSelection:
    3477             selstart = cmd.selStart;
    3478             selend = cmd.selEnd;
    3479             cursor = cmd.pos;
    3480             break;
    3481         case Remove:
    3482         case RemoveSelection:
    3483             text.insert(cmd.pos, cmd.uc);
    3484             cursor = cmd.pos + 1;
    3485             break;
    3486         case Delete:
    3487         case DeleteSelection:
    3488             text.insert(cmd.pos, cmd.uc);
    3489             cursor = cmd.pos;
    3490             break;
    3491         case Separator:
    3492             continue;
    3493         }
    3494         if (until < 0 && undoState) {
    3495             Command& next = history[undoState-1];
    3496             if (next.type != cmd.type && next.type < RemoveSelection
    3497                  && (cmd.type < RemoveSelection || next.type == Separator))
    3498                 break;
    3499         }
    3500     }
    3501     textDirty = true;
    3502     emitCursorPositionChanged();
    3503 }
    3504 
    3505 void QLineEditPrivate::redo() {
    3506     if (!isRedoAvailable())
    3507         return;
    3508     deselect();
    3509     while (undoState < (int)history.size()) {
    3510         Command& cmd = history[undoState++];
    3511         switch (cmd.type) {
    3512         case Insert:
    3513             text.insert(cmd.pos, cmd.uc);
    3514             cursor = cmd.pos + 1;
    3515             break;
    3516         case SetSelection:
    3517             selstart = cmd.selStart;
    3518             selend = cmd.selEnd;
    3519             cursor = cmd.pos;
    3520             break;
    3521         case Remove:
    3522         case Delete:
    3523         case RemoveSelection:
    3524         case DeleteSelection:
    3525             text.remove(cmd.pos, 1);
    3526             cursor = cmd.pos;
    3527             break;
    3528         case Separator:
    3529             selstart = cmd.selStart;
    3530             selend = cmd.selEnd;
    3531             cursor = cmd.pos;
    3532             break;
    3533         }
    3534         if (undoState < (int)history.size()) {
    3535             Command& next = history[undoState];
    3536             if (next.type != cmd.type && cmd.type < RemoveSelection && next.type != Separator
    3537                  && (next.type < RemoveSelection || cmd.type == Separator))
    3538                 break;
    3539         }
    3540     }
    3541     textDirty = true;
    3542     emitCursorPositionChanged();
     2166    QWidget::changeEvent(ev);
    35432167}
    35442168
     
    36742298/*!
    36752299    \fn int QLineEdit::margin() const
    3676     Returns the with of the the margin around the contents of the widget.
     2300    Returns the width of the margin around the contents of the widget.
    36772301
    36782302    Use QWidget::getContentsMargins() instead.
  • trunk/src/gui/widgets/qlineedit.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4545#include <QtGui/qframe.h>
    4646#include <QtCore/qstring.h>
     47#include <QtCore/qmargins.h>
    4748
    4849QT_BEGIN_HEADER
     
    8384    Q_PROPERTY(bool redoAvailable READ isRedoAvailable)
    8485    Q_PROPERTY(bool acceptableInput READ hasAcceptableInput)
     86// ### Qt 4.7: remove this #if guard
     87#if (QT_VERSION >= 0x407000) || defined(Q_WS_MAEMO_5)
     88    Q_PROPERTY(QString placeholderText READ placeholderText WRITE setPlaceholderText)
     89#endif
    8590
    8691public:
     
    97102
    98103    QString displayText() const;
     104
     105// ### Qt 4.7: remove this #if guard
     106#if (QT_VERSION >= 0x407000) || defined(Q_WS_MAEMO_5)
     107    QString placeholderText() const;
     108    void setPlaceholderText(const QString &);
     109#endif
    99110
    100111    int maxLength() const;
     
    159170
    160171    void setTextMargins(int left, int top, int right, int bottom);
     172    void setTextMargins(const QMargins &margins);
    161173    void getTextMargins(int *left, int *top, int *right, int *bottom) const;
     174    QMargins textMargins() const;
    162175
    163176public Q_SLOTS:
     
    267280    Q_DISABLE_COPY(QLineEdit)
    268281    Q_DECLARE_PRIVATE(QLineEdit)
    269     Q_PRIVATE_SLOT(d_func(), void _q_clipboardChanged())
    270282    Q_PRIVATE_SLOT(d_func(), void _q_handleWindowActivate())
    271     Q_PRIVATE_SLOT(d_func(), void _q_deleteSelected())
     283    Q_PRIVATE_SLOT(d_func(), void _q_textEdited(const QString &))
     284    Q_PRIVATE_SLOT(d_func(), void _q_cursorPositionChanged(int, int))
    272285#ifndef QT_NO_COMPLETER
    273286    Q_PRIVATE_SLOT(d_func(), void _q_completionHighlighted(QString))
    274287#endif
     288#ifdef QT_KEYPAD_NAVIGATION
     289    Q_PRIVATE_SLOT(d_func(), void _q_editFocusChange(bool))
     290#endif
     291    Q_PRIVATE_SLOT(d_func(), void _q_selectionChanged())
    275292};
    276293
  • trunk/src/gui/widgets/qlineedit_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6666#include "QtGui/qlineedit.h"
    6767
     68#include "private/qlinecontrol_p.h"
     69
    6870QT_BEGIN_NAMESPACE
    6971
     
    7476
    7577    QLineEditPrivate()
    76         : cursor(0), preeditCursor(0), cursorTimer(0), frame(1),
    77           cursorVisible(0), hideCursor(false), separator(0), readOnly(0),
    78           dragEnabled(0), contextMenuEnabled(1), echoMode(0), textDirty(0),
    79           selDirty(0), validInput(1), alignment(Qt::AlignLeading | Qt::AlignVCenter), ascent(0),
    80           maxLength(32767), hscroll(0), vscroll(0), lastCursorPos(-1), maskData(0),
    81           modifiedState(0), undoState(0), selstart(0), selend(0), userInput(false),
    82           emitingEditingFinished(false), passwordEchoEditing(false)
    83 #ifndef QT_NO_COMPLETER
    84         , completer(0)
    85 #endif
    86         , leftTextMargin(0), topTextMargin(0), rightTextMargin(0), bottomTextMargin(0)
    87         {
    88         }
     78        : control(0), frame(1), contextMenuEnabled(1), cursorVisible(0),
     79        dragEnabled(0), clickCausedFocus(0), hscroll(0), vscroll(0),
     80        alignment(Qt::AlignLeading | Qt::AlignVCenter),
     81        leftTextMargin(0), topTextMargin(0), rightTextMargin(0), bottomTextMargin(0)
     82    {
     83    }
    8984
    9085    ~QLineEditPrivate()
    9186    {
    92         delete [] maskData;
     87        delete control;
    9388    }
    94     void init(const QString&);
    9589
    96     QString text;
    97     int cursor;
    98     int preeditCursor;
    99     int cursorTimer; // -1 for non blinking cursor.
    100     QPoint tripleClick;
    101     QBasicTimer tripleClickTimer;
    102     uint frame : 1;
    103     uint cursorVisible : 1;
    104     uint hideCursor : 1; // used to hide the cursor inside preedit areas
    105     uint separator : 1;
    106     uint readOnly : 1;
    107     uint dragEnabled : 1;
    108     uint contextMenuEnabled : 1;
    109     uint echoMode : 2;
    110     uint textDirty : 1;
    111     uint selDirty : 1;
    112     uint validInput : 1;
    113     uint alignment;
    114     int ascent;
    115     int maxLength;
    116     int hscroll;
    117     int vscroll;
    118     int lastCursorPos;
     90    QLineControl *control;
    11991
    12092#ifndef QT_NO_CONTEXTMENU
    12193    QPointer<QAction> selectAllAction;
    12294#endif
     95    void init(const QString&);
    12396
    124     inline void emitCursorPositionChanged();
    125     bool sendMouseEventToInputContext(QMouseEvent *e);
     97    int xToPos(int x, QTextLine::CursorPosition = QTextLine::CursorBetweenCharacters) const;
     98    QRect cursorRect() const;
     99    void setCursorVisible(bool visible);
    126100
    127     void finishChange(int validateFromState = -1, bool update = false, bool edited = true);
     101    void updatePasswordEchoEditing(bool);
    128102
    129     QPointer<QValidator> validator;
    130     struct MaskInputData {
    131         enum Casemode { NoCaseMode, Upper, Lower };
    132         QChar maskChar; // either the separator char or the inputmask
    133         bool separator;
    134         Casemode caseMode;
    135     };
    136     QString inputMask;
    137     QChar blank;
    138     MaskInputData *maskData;
    139     inline int nextMaskBlank(int pos) {
    140         int c = findInMask(pos, true, false);
    141         separator |= (c != pos);
    142         return (c != -1 ?  c : maxLength);
    143     }
    144     inline int prevMaskBlank(int pos) {
    145         int c = findInMask(pos, false, false);
    146         separator |= (c != pos);
    147         return (c != -1 ? c : 0);
     103    inline bool shouldEnableInputMethod() const
     104    {
     105        return !control->isReadOnly();
    148106    }
    149107
    150     void setCursorVisible(bool visible);
     108    QPoint tripleClick;
     109    QBasicTimer tripleClickTimer;
     110    uint frame : 1;
     111    uint contextMenuEnabled : 1;
     112    uint cursorVisible : 1;
     113    uint dragEnabled : 1;
     114    uint clickCausedFocus : 1;
     115    int hscroll;
     116    int vscroll;
     117    uint alignment;
     118    static const int verticalMargin;
     119    static const int horizontalMargin;
    151120
    152 
    153     // undo/redo handling
    154     enum CommandType { Separator, Insert, Remove, Delete, RemoveSelection, DeleteSelection, SetSelection };
    155     struct Command {
    156         inline Command() {}
    157         inline Command(CommandType t, int p, QChar c, int ss, int se) : type(t),uc(c),pos(p),selStart(ss),selEnd(se) {}
    158         uint type : 4;
    159         QChar uc;
    160         int pos, selStart, selEnd;
    161     };
    162     int modifiedState;
    163     int undoState;
    164     QVector<Command> history;
    165     void addCommand(const Command& cmd);
    166     void insert(const QString& s);
    167     void del(bool wasBackspace = false);
    168     void remove(int pos);
    169 
    170     inline void separate() { separator = true; }
    171     void undo(int until = -1);
    172     void redo();
    173     inline bool isUndoAvailable() const { return !readOnly && undoState; }
    174     inline bool isRedoAvailable() const { return !readOnly && undoState < (int)history.size(); }
    175 
    176     // selection
    177     int selstart, selend;
    178     inline bool allSelected() const { return !text.isEmpty() && selstart == 0 && selend == (int)text.length(); }
    179     inline bool hasSelectedText() const { return !text.isEmpty() && selend > selstart; }
    180     inline void deselect() { selDirty |= (selend > selstart); selstart = selend = 0; }
    181     void removeSelectedText();
    182 #ifndef QT_NO_CLIPBOARD
    183     void copy(bool clipboard = true) const;
    184 #endif
    185     inline bool inSelection(int x) const
    186     { if (selstart >= selend) return false;
    187     int pos = xToPos(x, QTextLine::CursorOnCharacter);  return pos >= selstart && pos < selend; }
    188 
    189     // masking
    190     void parseInputMask(const QString &maskFields);
    191     bool isValidInput(QChar key, QChar mask) const;
    192     bool hasAcceptableInput(const QString &text) const;
    193     QString maskString(uint pos, const QString &str, bool clear = false) const;
    194     QString clearString(uint pos, uint len) const;
    195     QString stripString(const QString &str) const;
    196     int findInMask(int pos, bool forward, bool findSeparator, QChar searchChar = QChar()) const;
    197 
    198     // input methods
    199     bool composeMode() const { return !textLayout.preeditAreaText().isEmpty(); }
    200 
    201     // complex text layout
    202     QTextLayout textLayout;
    203     void updateTextLayout();
    204     void moveCursor(int pos, bool mark = false);
    205     void setText(const QString& txt, int pos = -1, bool edited = true);
    206     int xToPos(int x, QTextLine::CursorPosition = QTextLine::CursorBetweenCharacters) const;
    207     QRect cursorRect() const;
    208     bool fixup();
     121    bool sendMouseEventToInputContext(QMouseEvent *e);
    209122
    210123    QRect adjustedContentsRect() const;
    211124
     125    void _q_handleWindowActivate();
     126    void _q_textEdited(const QString &);
     127    void _q_cursorPositionChanged(int, int);
     128#ifdef QT_KEYPAD_NAVIGATION
     129    void _q_editFocusChange(bool);
     130#endif
     131    void _q_selectionChanged();
     132#ifndef QT_NO_COMPLETER
     133    void _q_completionHighlighted(QString);
     134#endif
    212135#ifndef QT_NO_DRAGANDDROP
    213     // drag and drop
    214136    QPoint dndPos;
    215137    QBasicTimer dndTimer;
    216138    void drag();
    217 #endif
    218 
    219     void _q_clipboardChanged();
    220     void _q_handleWindowActivate();
    221     void _q_deleteSelected();
    222     bool userInput;
    223     bool emitingEditingFinished;
    224 
    225 #ifdef QT_KEYPAD_NAVIGATION
    226     QBasicTimer deleteAllTimer; // keypad navigation
    227     QString origText;
    228 #endif
    229 
    230     bool passwordEchoEditing;
    231     void updatePasswordEchoEditing(bool editing);
    232 
    233 #ifndef QT_NO_COMPLETER
    234     QPointer<QCompleter> completer;
    235     void complete(int key = -1);
    236     void _q_completionHighlighted(QString);
    237     bool advanceToEnabledItem(int n);
    238139#endif
    239140
     
    242143    int rightTextMargin;
    243144    int bottomTextMargin;
     145
     146    QString placeholderText;
    244147};
    245148
  • trunk/src/gui/widgets/qmaccocoaviewcontainer_mac.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qmaccocoaviewcontainer_mac.mm

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    39 **
    40 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
    41 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
    4239**
    4340****************************************************************************/
  • trunk/src/gui/widgets/qmacnativewidget_mac.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6565
    6666private:
    67     Q_DECLARE_PRIVATE_D(QWidget::d_ptr, QMacNativeWidget)
     67    Q_DECLARE_PRIVATE(QMacNativeWidget)
    6868};
    6969
  • trunk/src/gui/widgets/qmacnativewidget_mac.mm

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    39 **
    40 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
    41 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
    4239**
    4340****************************************************************************/
  • trunk/src/gui/widgets/qmainwindow.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6666QT_END_NAMESPACE
    6767#endif
     68#ifdef QT_SOFTKEYS_ENABLED
     69#include <private/qsoftkeymanager_p.h>
     70#endif
    6871
    6972QT_BEGIN_NAMESPACE
     
    7477public:
    7578    inline QMainWindowPrivate()
    76         : layout(0), toolButtonStyle(Qt::ToolButtonIconOnly)
     79        : layout(0), explicitIconSize(false), toolButtonStyle(Qt::ToolButtonIconOnly)
    7780#ifdef Q_WS_MAC
    7881            , useHIToolBar(false)
     82#endif
     83#ifdef QT_SOFTKEYS_ENABLED
     84            , menuBarAction(0)
    7985#endif
    8086#if !defined(QT_NO_DOCKWIDGET) && !defined(QT_NO_CURSOR)
     
    8995    bool useHIToolBar;
    9096#endif
     97#ifdef QT_SOFTKEYS_ENABLED
     98    QAction *menuBarAction;
     99#endif
    91100    void init();
    92101    QList<int> hoverSeparator;
     
    108117    const int metric = q->style()->pixelMetric(QStyle::PM_ToolBarIconSize, 0, q);
    109118    iconSize = QSize(metric, metric);
    110     explicitIconSize = false;
    111 
    112119    q->setAttribute(Qt::WA_Hover);
     120#ifdef QT_SOFTKEYS_ENABLED
     121    menuBarAction = QSoftKeyManager::createAction(QSoftKeyManager::MenuSoftKey, q);
     122    menuBarAction->setObjectName(QLatin1String("_q_menuSoftKeyAction"));
     123    menuBarAction->setVisible(false);
     124#endif
    113125}
    114126
     
    149161    \brief The QMainWindow class provides a main application
    150162           window.
    151     \ingroup application
    152     \mainclass
     163    \ingroup mainwindow-classes
     164
    153165
    154166    \tableofcontents
     
    481493        oldMenuBar->deleteLater();
    482494    }
    483 #ifdef Q_OS_WINCE
    484     if (menuBar && menuBar->size().height() > 0)
    485 #endif
    486495    d->layout->setMenuBar(menuBar);
     496
     497#ifdef QT_SOFTKEYS_ENABLED
     498    if (menuBar)
     499        addAction(d->menuBarAction);
     500    else
     501        removeAction(d->menuBarAction);
     502#endif
    487503}
    488504
     
    919935
    920936#ifndef QT_NO_TABBAR
    921 /*! 
     937/*!
    922938    \property QMainWindow::documentMode
    923939    \brief whether the tab bar for tabbed dockwidgets is set to document mode.
     
    940956
    941957#ifndef QT_NO_TABWIDGET
    942 /*! 
     958/*!
    943959    \property QMainWindow::tabShape
    944960    \brief the tab shape used for tabbed dock widgets.
     
    10331049    to restoreState(). Returns true if the state was restored; otherwise
    10341050    returns false.
     1051
     1052    \sa restoreState(), saveState()
    10351053*/
    10361054
     
    11641182    number to restoreState().
    11651183
     1184    To save the geometry when the window closes, you can
     1185    implement a close event like this:
     1186
     1187    \snippet doc/src/snippets/code/src_gui_widgets_qmainwindow.cpp 0
     1188
    11661189    \sa restoreState(), QWidget::saveGeometry(), QWidget::restoreGeometry()
    11671190*/
     
    11831206    is restored, and this function returns \c true.
    11841207
    1185     \sa saveState(), QWidget::saveGeometry(), QWidget::restoreGeometry()
     1208    To restore geometry saved using QSettings, you can use code like
     1209    this:
     1210
     1211    \snippet doc/src/snippets/code/src_gui_widgets_qmainwindow.cpp 1
     1212
     1213    \sa saveState(), QWidget::saveGeometry(),
     1214    QWidget::restoreGeometry(), restoreDockWidget()
    11861215*/
    11871216bool QMainWindow::restoreState(const QByteArray &state, int version)
     
    13731402        case QEvent::Show:
    13741403            if (unifiedTitleAndToolBarOnMac())
    1375                 macWindowToolbarShow(this, true);
     1404                d->layout->syncUnifiedToolbarVisibility();
     1405            d->layout->blockVisiblityCheck = false;
    13761406            break;
    1377 #  ifdef QT_MAC_USE_COCOA
    13781407       case QEvent::WindowStateChange:
    13791408            {
     1409                if (isHidden()) {
     1410                    // We are coming out of a minimize, leave things as is.
     1411                    d->layout->blockVisiblityCheck = true;
     1412                }
     1413#  ifdef QT_MAC_USE_COCOA
    13801414                // We need to update the HIToolbar status when we go out of or into fullscreen.
    13811415                QWindowStateChangeEvent *wce = static_cast<QWindowStateChangeEvent *>(event);
     
    13831417                    d->layout->updateHIToolBarStatus();
    13841418                }
     1419#  endif // Cocoa
    13851420            }
    13861421            break;
    1387 #  endif // Cocoa
    1388 #endif
     1422#endif // Q_WS_MAC
    13891423#if !defined(QT_NO_DOCKWIDGET) && !defined(QT_NO_CURSOR)
    13901424       case QEvent::CursorChange:
     
    13951429           break;
    13961430#endif
    1397 
    13981431        default:
    13991432            break;
     
    14121445    This property is false by default and only has any effect on Mac OS X 10.4 or higher.
    14131446
    1414     If set to true, then the top toolbar area is replaced with a Carbon
    1415     HIToolbar and all toolbars in the top toolbar area are moved to that. Any
    1416     toolbars added afterwards will also be added to the Carbon HIToolbar. This
    1417     means a couple of things.
     1447    If set to true, then the top toolbar area is replaced with a Carbon HIToolbar
     1448    or a Cocoa NSToolbar (depending on whether Qt was built with Carbon or Cocoa).
     1449    All toolbars in the top toolbar area and any toolbars added afterwards are
     1450    moved to that. This means a couple of things.
    14181451
    14191452    \list
     
    14231456    \i Any custom widgets in the toolbar will not be shown if the toolbar
    14241457        becomes too small (only actions will be shown)
    1425     \i If you call showFullScreen() on the main window, the QToolbar will
    1426         disappear since it is considered to be part of the title bar. You can
    1427         work around this by turning off the unified toolbar before you call
     1458    \i Before Qt 4.5, if you called showFullScreen() on the main window, the QToolbar would
     1459        disappear since it is considered to be part of the title bar. Qt 4.5 and up will now work around this by pulling
     1460        the toolbars out and back into the regular toolbar and vice versa when you swap out.
     1461        However, a good practice would be that turning off the unified toolbar before you call
    14281462        showFullScreen() and restoring it after you call showNormal().
    14291463    \endlist
  • trunk/src/gui/widgets/qmainwindow.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qmainwindowlayout.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    238238        QMainWindowLayout *layout = qobject_cast<QMainWindowLayout*>(mainWindow->layout());
    239239        Q_ASSERT(layout != 0);
    240         layout->widgetAnimator->animate(centralWidgetItem->widget(), centralWidgetRect, animated);
     240        layout->widgetAnimator.animate(centralWidgetItem->widget(), centralWidgetRect, animated);
    241241    }
    242242#endif
     
    427427}
    428428
    429 bool QMainWindowLayoutState::insertGap(QList<int> path, QLayoutItem *item)
     429bool QMainWindowLayoutState::insertGap(const QList<int> &path, QLayoutItem *item)
    430430{
    431431    if (path.isEmpty())
    432432        return false;
    433433
    434     int i = path.takeFirst();
     434    int i = path.first();
    435435
    436436#ifndef QT_NO_TOOLBAR
    437437    if (i == 0) {
    438438        Q_ASSERT(qobject_cast<QToolBar*>(item->widget()) != 0);
    439         return toolBarAreaLayout.insertGap(path, item);
     439        return toolBarAreaLayout.insertGap(path.mid(1), item);
    440440    }
    441441#endif
     
    444444    if (i == 1) {
    445445        Q_ASSERT(qobject_cast<QDockWidget*>(item->widget()) != 0);
    446         return dockAreaLayout.insertGap(path, item);
     446        return dockAreaLayout.insertGap(path.mid(1), item);
    447447    }
    448448#endif //QT_NO_DOCKWIDGET
     
    451451}
    452452
    453 void QMainWindowLayoutState::remove(QList<int> path)
    454 {
    455     int i = path.takeFirst();
     453void QMainWindowLayoutState::remove(const QList<int> &path)
     454{
     455    int i = path.first();
    456456
    457457#ifndef QT_NO_TOOLBAR
    458458    if (i == 0)
    459         toolBarAreaLayout.remove(path);
     459        toolBarAreaLayout.remove(path.mid(1));
    460460#endif
    461461
    462462#ifndef QT_NO_DOCKWIDGET
    463463    if (i == 1)
    464         dockAreaLayout.remove(path);
     464        dockAreaLayout.remove(path.mid(1));
    465465#endif //QT_NO_DOCKWIDGET
    466466}
     
    491491    dockAreaLayout.clear();
    492492#else
    493     centralWidgetRect = QRect(0, 0, -1, -1);
    494 #endif
    495 
    496     rect = QRect(0, 0, -1, -1);
     493    centralWidgetRect = QRect();
     494#endif
     495
     496    rect = QRect();
    497497}
    498498
     
    502502}
    503503
    504 QLayoutItem *QMainWindowLayoutState::item(QList<int> path)
    505 {
    506     int i = path.takeFirst();
     504QLayoutItem *QMainWindowLayoutState::item(const QList<int> &path)
     505{
     506    int i = path.first();
    507507
    508508#ifndef QT_NO_TOOLBAR
    509509    if (i == 0)
    510         return toolBarAreaLayout.item(path).widgetItem;
     510        return toolBarAreaLayout.item(path.mid(1)).widgetItem;
    511511#endif
    512512
    513513#ifndef QT_NO_DOCKWIDGET
    514514    if (i == 1)
    515         return dockAreaLayout.item(path).widgetItem;
     515        return dockAreaLayout.item(path.mid(1)).widgetItem;
    516516#endif //QT_NO_DOCKWIDGET
    517517
     
    519519}
    520520
    521 QRect QMainWindowLayoutState::itemRect(QList<int> path) const
    522 {
    523     int i = path.takeFirst();
     521QRect QMainWindowLayoutState::itemRect(const QList<int> &path) const
     522{
     523    int i = path.first();
    524524
    525525#ifndef QT_NO_TOOLBAR
    526526    if (i == 0)
    527         return toolBarAreaLayout.itemRect(path);
     527        return toolBarAreaLayout.itemRect(path.mid(1));
    528528#endif
    529529
    530530#ifndef QT_NO_DOCKWIDGET
    531531    if (i == 1)
    532         return dockAreaLayout.itemRect(path);
     532        return dockAreaLayout.itemRect(path.mid(1));
    533533#endif //QT_NO_DOCKWIDGET
    534534
     
    536536}
    537537
    538 QRect QMainWindowLayoutState::gapRect(QList<int> path) const
    539 {
    540     int i = path.takeFirst();
     538QRect QMainWindowLayoutState::gapRect(const QList<int> &path) const
     539{
     540    int i = path.first();
    541541
    542542#ifndef QT_NO_TOOLBAR
    543543    if (i == 0)
    544         return toolBarAreaLayout.itemRect(path);
     544        return toolBarAreaLayout.itemRect(path.mid(1));
    545545#endif
    546546
    547547#ifndef QT_NO_DOCKWIDGET
    548548    if (i == 1)
    549         return dockAreaLayout.gapRect(path);
     549        return dockAreaLayout.gapRect(path.mid(1));
    550550#endif //QT_NO_DOCKWIDGET
    551551
     
    553553}
    554554
    555 QLayoutItem *QMainWindowLayoutState::plug(QList<int> path)
    556 {
    557     int i = path.takeFirst();
     555QLayoutItem *QMainWindowLayoutState::plug(const QList<int> &path)
     556{
     557    int i = path.first();
    558558
    559559#ifndef QT_NO_TOOLBAR
    560560    if (i == 0)
    561         return toolBarAreaLayout.plug(path);
     561        return toolBarAreaLayout.plug(path.mid(1));
    562562#endif
    563563
    564564#ifndef QT_NO_DOCKWIDGET
    565565    if (i == 1)
    566         return dockAreaLayout.plug(path);
     566        return dockAreaLayout.plug(path.mid(1));
    567567#endif //QT_NO_DOCKWIDGET
    568568
     
    570570}
    571571
    572 QLayoutItem *QMainWindowLayoutState::unplug(QList<int> path, QMainWindowLayoutState *other)
    573 {
    574     int i = path.takeFirst();
     572QLayoutItem *QMainWindowLayoutState::unplug(const QList<int> &path, QMainWindowLayoutState *other)
     573{
     574    int i = path.first();
    575575
    576576#ifdef QT_NO_TOOLBAR
     
    578578#else
    579579    if (i == 0)
    580         return toolBarAreaLayout.unplug(path, other ? &other->toolBarAreaLayout : 0);
     580        return toolBarAreaLayout.unplug(path.mid(1), other ? &other->toolBarAreaLayout : 0);
    581581#endif
    582582
    583583#ifndef QT_NO_DOCKWIDGET
    584584    if (i == 1)
    585         return dockAreaLayout.unplug(path);
     585        return dockAreaLayout.unplug(path.mid(1));
    586586#endif //QT_NO_DOCKWIDGET
    587587
     
    940940void QMainWindowLayout::toggleToolBarsVisible()
    941941{
    942     layoutState.toolBarAreaLayout.visible = !layoutState.toolBarAreaLayout.visible;
    943     if (!layoutState.mainWindow->isMaximized()){
    944         QPoint topLeft = parentWidget()->geometry().topLeft();
    945         QRect r = parentWidget()->geometry();
    946         r = layoutState.toolBarAreaLayout.rectHint(r);
    947         r.moveTo(topLeft);
    948         parentWidget()->setGeometry(r);
    949 //      widgetAnimator->animate(parentWidget(), r, true);
    950     } else{
    951         update();
     942    bool updateNonUnifiedParts = true;
     943#ifdef Q_WS_MAC
     944    if (layoutState.mainWindow->unifiedTitleAndToolBarOnMac()) {
     945        // If we hit this case, someone has pressed the "toolbar button" which will
     946        // toggle the unified toolbar visiblity, because that's what the user wants.
     947        // We might be in a situation where someone has hidden all the toolbars
     948        // beforehand (maybe in construction), but now they've hit this button and
     949        // and are expecting the items to show. What do we do?
     950        // 1) Check the visibility of all the toolbars, if one is visible, do nothing, this
     951        //    preserves what people would expect (these toolbars were visible when I clicked last time).
     952        // 2) If NONE are visible, then show them all. Again, this preserves the user expectation
     953        //    of, "I want to see the toolbars." The user may get more toolbars than expected, but this
     954        //    is better seeing nothing.
     955        // Don't worry about any of this if we are going invisible. This does mean we may get
     956        // into issues when switching into and out of fullscreen mode, but this is probably minor.
     957        // If we ever need to do hiding, that would have to be taken care of after the unified toolbar
     958        // has finished hiding.
     959        // People can of course handle the QEvent::ToolBarChange event themselves and do
     960        // WHATEVER they want if they don't like what we are doing (though the unified toolbar
     961        // will fire regardless).
     962
     963        // Check if we REALLY need to update the geometry below. If we only have items in the
     964        // unified toolbar, all the docks will be empty, so there's very little point
     965        // in doing the geometry as Apple will do it (we also avoid flicker in Cocoa as well).
     966        // FWIW, layoutState.toolBarAreaLayout.visible and the state of the unified toolbar
     967        // visibility can get out of sync. I really don't think it's a big issue. It is kept
     968        // to a minimum because we only change the visibility if we absolutely must.
     969        // update the "non unified parts."
     970        updateNonUnifiedParts = !layoutState.toolBarAreaLayout.isEmpty();
     971
     972        // We get this function before the unified toolbar does its thing.
     973        // So, the value will be opposite of what we expect.
     974        bool goingVisible = !macWindowToolbarIsVisible(qt_mac_window_for(layoutState.mainWindow));
     975        if (goingVisible) {
     976            const int ToolBarCount = qtoolbarsInUnifiedToolbarList.size();
     977            bool needAllVisible = true;
     978            for (int i = 0; i < ToolBarCount; ++i) {
     979                if (!qtoolbarsInUnifiedToolbarList.at(i)->isHidden()) {
     980                    needAllVisible = false;
     981                    break;
     982                }
     983            }
     984            if (needAllVisible) {
     985                QBoolBlocker blocker(blockVisiblityCheck);  // Disable the visibilty check because
     986                                                            // the toggle has already happened.
     987                for (int i = 0; i < ToolBarCount; ++i)
     988                    qtoolbarsInUnifiedToolbarList.at(i)->setVisible(true);
     989            }
     990        }
     991        if (!updateNonUnifiedParts)
     992            layoutState.toolBarAreaLayout.visible = goingVisible;
     993    }
     994#endif
     995    if (updateNonUnifiedParts) {
     996        layoutState.toolBarAreaLayout.visible = !layoutState.toolBarAreaLayout.visible;
     997        if (!layoutState.mainWindow->isMaximized()) {
     998            QPoint topLeft = parentWidget()->geometry().topLeft();
     999            QRect r = parentWidget()->geometry();
     1000            r = layoutState.toolBarAreaLayout.rectHint(r);
     1001            r.moveTo(topLeft);
     1002            parentWidget()->setGeometry(r);
     1003        } else {
     1004            update();
     1005        }
    9521006    }
    9531007}
     
    13051359        return false;
    13061360    movingSeparatorPos = pos;
    1307     separatorMoveTimer->start();
     1361    separatorMoveTimer.start(0, this);
    13081362    return true;
    1309 }
    1310 
    1311 void QMainWindowLayout::doSeparatorMove()
    1312 {
    1313     if (movingSeparator.isEmpty())
    1314         return;
    1315     if (movingSeparatorOrigin == movingSeparatorPos)
    1316         return;
    1317 
    1318     layoutState = savedState;
    1319     layoutState.dockAreaLayout.separatorMove(movingSeparator, movingSeparatorOrigin,
    1320                                                 movingSeparatorPos,
    1321                                                 &separatorMoveCache);
    1322     movingSeparatorPos = movingSeparatorOrigin;
    13231363}
    13241364
     
    13281368    movingSeparator.clear();
    13291369    savedState.clear();
    1330     separatorMoveCache.clear();
    13311370    return result;
    13321371}
     
    13771416        // the widget might in fact have been destroyed by now
    13781417        if (QWidget *w = ret->widget()) {
    1379             widgetAnimator->abort(w);
     1418            widgetAnimator.abort(w);
    13801419            if (w == pluggingWidget)
    13811420                pluggingWidget = 0;
     
    14251464                  .expandedTo(statusbar->minimumSize()));
    14261465        sbr.moveBottom(r.bottom());
    1427         QRect vr = QStyle::visualRect(QApplication::layoutDirection(), _r, sbr);
     1466        QRect vr = QStyle::visualRect(parentWidget()->layoutDirection(), _r, sbr);
    14281467        statusbar->setGeometry(vr);
    14291468        r.setBottom(sbr.top() - 1);
     
    15441583
    15451584    pluggingWidget = widget;
    1546     if (dockOptions & QMainWindow::AnimatedDocks) {
    1547         QRect globalRect = currentGapRect;
    1548         globalRect.moveTopLeft(parentWidget()->mapToGlobal(globalRect.topLeft()));
    1549 #ifndef QT_NO_DOCKWIDGET
    1550         if (qobject_cast<QDockWidget*>(widget) != 0) {
    1551             QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(widget->layout());
    1552             if (layout->nativeWindowDeco()) {
    1553                 globalRect.adjust(0, layout->titleHeight(), 0, 0);
    1554             } else {
    1555                 int fw = widget->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, widget);
    1556                 globalRect.adjust(-fw, -fw, fw, fw);
    1557             }
     1585    QRect globalRect = currentGapRect;
     1586    globalRect.moveTopLeft(parentWidget()->mapToGlobal(globalRect.topLeft()));
     1587#ifndef QT_NO_DOCKWIDGET
     1588    if (qobject_cast<QDockWidget*>(widget) != 0) {
     1589        QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(widget->layout());
     1590        if (layout->nativeWindowDeco()) {
     1591            globalRect.adjust(0, layout->titleHeight(), 0, 0);
     1592        } else {
     1593            int fw = widget->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, widget);
     1594            globalRect.adjust(-fw, -fw, fw, fw);
    15581595        }
    1559 #endif
    1560         widgetAnimator->animate(widget, globalRect,
    1561                                 dockOptions & QMainWindow::AnimatedDocks);
    1562     } else {
    1563 #ifndef QT_NO_DOCKWIDGET
    1564         if (QDockWidget *dw = qobject_cast<QDockWidget*>(widget))
    1565             dw->d_func()->plug(currentGapRect);
    1566 #endif
    1567 #ifndef QT_NO_TOOLBAR
    1568         if (QToolBar *tb = qobject_cast<QToolBar*>(widget))
    1569             tb->d_func()->plug(currentGapRect);
    1570 #endif
    1571         applyState(layoutState);
    1572         savedState.clear();
    1573 #ifndef QT_NO_DOCKWIDGET
    1574         parentWidget()->update(layoutState.dockAreaLayout.separatorRegion());
    1575 #endif
    1576         currentGapPos.clear();
    1577         updateGapIndicator();
    1578         pluggingWidget = 0;
    1579     }
     1596    }
     1597#endif
     1598    widgetAnimator.animate(widget, globalRect, dockOptions & QMainWindow::AnimatedDocks);
    15801599
    15811600    return true;
    15821601}
    15831602
    1584 void QMainWindowLayout::allAnimationsFinished()
    1585 {
    1586 #ifndef QT_NO_DOCKWIDGET
    1587     parentWidget()->update(layoutState.dockAreaLayout.separatorRegion());
    1588 
    1589 #ifndef QT_NO_TABBAR
    1590     foreach (QTabBar *tab_bar, usedTabBars)
    1591         tab_bar->show();
    1592 #endif // QT_NO_TABBAR
    1593 #endif // QT_NO_DOCKWIDGET
    1594 
    1595     updateGapIndicator();
    1596 }
    1597 
    15981603void QMainWindowLayout::animationFinished(QWidget *widget)
    15991604{
    1600 
    1601     /* This signal is delivered from QWidgetAnimator over a qeued connection. The problem is that
    1602        the widget can be deleted. This is handled as follows:
    1603 
    1604        The animator only ever animates widgets that have been added to this layout. If a widget
    1605        is deleted during animation, the widget's destructor removes the widget form this layout.
    1606        This in turn aborts the animation (see takeAt()) and this signal will never be delivered.
    1607 
    1608        If the widget is deleted after the animation is finished but before this qeued signal
    1609        is delivered, the widget is no longer in the layout and we catch it here. The key is that
    1610        QMainWindowLayoutState::contains() never dereferences the pointer. */
    1611 
    1612     if (!layoutState.contains(widget))
    1613         return;
    1614 
     1605    //this function is called from within the Widget Animator whenever an animation is finished
     1606    //on a certain widget
    16151607#ifndef QT_NO_TOOLBAR
    16161608    if (QToolBar *tb = qobject_cast<QToolBar*>(widget)) {
     
    16251617#endif
    16261618
    1627     if (widget != pluggingWidget)
    1628         return;
    1629 
    1630 #ifndef QT_NO_DOCKWIDGET
    1631     if (QDockWidget *dw = qobject_cast<QDockWidget*>(widget))
    1632         dw->d_func()->plug(currentGapRect);
    1633 #endif
    1634 #ifndef QT_NO_TOOLBAR
    1635     if (QToolBar *tb = qobject_cast<QToolBar*>(widget))
    1636         tb->d_func()->plug(currentGapRect);
    1637 #endif
    1638 
    1639     applyState(layoutState, false);
     1619    if (widget == pluggingWidget) {
     1620
     1621#ifndef QT_NO_DOCKWIDGET
     1622        if (QDockWidget *dw = qobject_cast<QDockWidget*>(widget))
     1623            dw->d_func()->plug(currentGapRect);
     1624#endif
     1625#ifndef QT_NO_TOOLBAR
     1626        if (QToolBar *tb = qobject_cast<QToolBar*>(widget))
     1627            tb->d_func()->plug(currentGapRect);
     1628#endif
     1629
    16401630#ifndef QT_NO_DOCKWIDGET
    16411631#ifndef QT_NO_TABBAR
    1642     if (qobject_cast<QDockWidget*>(widget) != 0) {
    1643         // info() might return null if the widget is destroyed while
    1644         // animating but before the animationFinished signal is received.
    1645         if (QDockAreaLayoutInfo *info = layoutState.dockAreaLayout.info(widget))
    1646             info->setCurrentTab(widget);
    1647     }
    1648 #endif
    1649 #endif
    1650     savedState.clear();
    1651     currentGapPos.clear();
    1652     pluggingWidget = 0;
     1632        if (qobject_cast<QDockWidget*>(widget) != 0) {
     1633            // info() might return null if the widget is destroyed while
     1634            // animating but before the animationFinished signal is received.
     1635            if (QDockAreaLayoutInfo *info = layoutState.dockAreaLayout.info(widget))
     1636                info->setCurrentTab(widget);
     1637        }
     1638#endif
     1639#endif
     1640
     1641        savedState.clear();
     1642        currentGapPos.clear();
     1643        pluggingWidget = 0;
     1644        //applying the state will make sure that the currentGap is updated correctly
     1645        //and all the geometries (especially the one from the central widget) is correct
     1646        layoutState.apply(false);
     1647    }
     1648
     1649    if (!widgetAnimator.animating()) {
     1650        //all animations are finished
     1651#ifndef QT_NO_DOCKWIDGET
     1652        parentWidget()->update(layoutState.dockAreaLayout.separatorRegion());
     1653#ifndef QT_NO_TABBAR
     1654        foreach (QTabBar *tab_bar, usedTabBars)
     1655            tab_bar->show();
     1656#endif // QT_NO_TABBAR
     1657#endif // QT_NO_DOCKWIDGET
     1658    }
     1659
    16531660    updateGapIndicator();
    16541661}
     
    16831690#endif
    16841691#endif // QT_NO_DOCKWIDGET
     1692    , widgetAnimator(this)
     1693    , pluggingWidget(0)
     1694#ifndef QT_NO_RUBBERBAND
     1695    , gapIndicator(new QRubberBand(QRubberBand::Rectangle, mainwindow))
     1696#endif //QT_NO_RUBBERBAND
     1697#ifdef Q_WS_MAC
     1698    , blockVisiblityCheck(false)
     1699#endif
    16851700{
    16861701#ifndef QT_NO_DOCKWIDGET
     
    16881703    sep = mainwindow->style()->pixelMetric(QStyle::PM_DockWidgetSeparatorExtent, 0, mainwindow);
    16891704#endif
    1690     separatorMoveTimer = new QTimer(this);
    1691     separatorMoveTimer->setSingleShot(true);
    1692     separatorMoveTimer->setInterval(0);
    1693     connect(separatorMoveTimer, SIGNAL(timeout()), this, SLOT(doSeparatorMove()));
    16941705
    16951706#ifndef QT_NO_TABWIDGET
     
    17001711
    17011712#ifndef QT_NO_RUBBERBAND
    1702     gapIndicator = new QRubberBand(QRubberBand::Rectangle, mainwindow);
    17031713    // For accessibility to identify this special widget.
    17041714    gapIndicator->setObjectName(QLatin1String("qt_rubberband"));
    1705 
    17061715    gapIndicator->hide();
    17071716#endif
     
    17091718
    17101719    setObjectName(mainwindow->objectName() + QLatin1String("_layout"));
    1711     widgetAnimator = new QWidgetAnimator(this);
    1712     connect(widgetAnimator, SIGNAL(finished(QWidget*)),
    1713             this, SLOT(animationFinished(QWidget*)), Qt::QueuedConnection);
    1714     connect(widgetAnimator, SIGNAL(finishedAll()),
    1715             this, SLOT(allAnimationsFinished()));
    17161720}
    17171721
     
    18151819{
    18161820#ifndef QT_NO_RUBBERBAND
    1817     if (widgetAnimator->animating() || currentGapPos.isEmpty()) {
    1818         gapIndicator->hide();
    1819     } else {
    1820         if (gapIndicator->geometry() != currentGapRect)
    1821             gapIndicator->setGeometry(currentGapRect);
    1822         if (!gapIndicator->isVisible())
    1823             gapIndicator->show();
    1824     }
     1821    gapIndicator->setVisible(!widgetAnimator.animating() && !currentGapPos.isEmpty());
     1822    gapIndicator->setGeometry(currentGapRect);
    18251823#endif
    18261824}
     
    19831981}
    19841982
     1983void QMainWindowLayout::timerEvent(QTimerEvent *e)
     1984{
     1985#ifndef QT_NO_DOCKWIDGET
     1986    if (e->timerId() == separatorMoveTimer.timerId()) {
     1987        //let's move the separators
     1988        separatorMoveTimer.stop();
     1989        if (movingSeparator.isEmpty())
     1990            return;
     1991        if (movingSeparatorOrigin == movingSeparatorPos)
     1992            return;
     1993
     1994        //when moving the separator, we need to update the previous position
     1995        parentWidget()->update(layoutState.dockAreaLayout.separatorRegion());
     1996
     1997        layoutState = savedState;
     1998        layoutState.dockAreaLayout.separatorMove(movingSeparator, movingSeparatorOrigin,
     1999                                                    movingSeparatorPos);
     2000        movingSeparatorPos = movingSeparatorOrigin;
     2001    }
     2002#endif
     2003    QLayout::timerEvent(e);
     2004}
     2005
     2006
    19852007QT_END_NAMESPACE
    19862008
  • trunk/src/gui/widgets/qmainwindowlayout_mac.mm

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
    78**
    89** $QT_BEGIN_LICENSE:LGPL$
    9 ** No Commercial Usage
    10 ** This file contains pre-release code and may not be distributed.
    11 ** You may use this file in accordance with the terms and conditions
    12 ** contained in the either Technology Preview License Agreement or the
    13 ** Beta Release License Agreement.
     10** Commercial Usage
     11** Licensees holding valid Qt Commercial licenses may use this file in
     12** accordance with the Qt Commercial License Agreement provided with the
     13** Software or, alternatively, in accordance with the terms contained in
     14** a written agreement between you and Nokia.
    1415**
    1516** GNU Lesser General Public License Usage
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    39 **
    40 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
    41 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
    4239**
    4340****************************************************************************/
     
    330327{
    331328    bool useMacToolbar = layoutState.mainWindow->unifiedTitleAndToolBarOnMac();
    332     if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) {
    333 #ifndef QT_MAC_USE_COCOA
    334         if (useMacToolbar) {
    335             ChangeWindowAttributes(qt_mac_window_for(layoutState.mainWindow),
    336                                    kWindowUnifiedTitleAndToolbarAttribute, 0);
    337         } else {
    338             ChangeWindowAttributes(qt_mac_window_for(layoutState.mainWindow),
    339                                    0, kWindowUnifiedTitleAndToolbarAttribute);
    340         }
    341 #endif
    342         macWindowToolbarShow(layoutState.mainWindow, useMacToolbar);
    343     }
     329#ifndef QT_MAC_USE_COCOA
     330    if (useMacToolbar) {
     331        ChangeWindowAttributes(qt_mac_window_for(layoutState.mainWindow),
     332                               kWindowUnifiedTitleAndToolbarAttribute, 0);
     333    } else {
     334        ChangeWindowAttributes(qt_mac_window_for(layoutState.mainWindow),
     335                               0, kWindowUnifiedTitleAndToolbarAttribute);
     336    }
     337#endif
    344338
    345339    layoutState.mainWindow->setUpdatesEnabled(false);  // reduces a little bit of flicker, not all though
    346340    if (!useMacToolbar) {
    347         OSWindowRef windowRef = qt_mac_window_for(parentWidget());
    348         macWindowToolbarShow(parentWidget(), false);
     341        macWindowToolbarShow(layoutState.mainWindow, false);
    349342        // Move everything out of the HIToolbar into the main toolbar.
    350343        while (!qtoolbarsInUnifiedToolbarList.isEmpty()) {
     
    352345            layoutState.mainWindow->addToolBar(Qt::TopToolBarArea, qtoolbarsInUnifiedToolbarList.first());
    353346        }
    354         macWindowToolbarSet(windowRef, NULL);
     347        macWindowToolbarSet(qt_mac_window_for(layoutState.mainWindow), 0);
    355348    } else {
    356349        QList<QToolBar *> toolbars = layoutState.mainWindow->findChildren<QToolBar *>();
     
    362355            }
    363356        }
     357        syncUnifiedToolbarVisibility();
    364358    }
    365359    layoutState.mainWindow->setUpdatesEnabled(true);
     
    442436    NSString *toolbarID = kQToolBarNSToolbarIdentifier;
    443437    toolbarID = [toolbarID stringByAppendingFormat:@"%p", toolbar];
    444     cocoaItemIDToToolbarHash.insert(QCFString::toQString(CFStringRef(toolbarID)), toolbar);
     438    cocoaItemIDToToolbarHash.insert(qt_mac_NSStringToQString(toolbarID), toolbar);
    445439    [macToolbar insertItemWithItemIdentifier:toolbarID atIndex:beforeIndex];
    446440#endif
     
    470464            [[qt_mac_window_for(layoutState.mainWindow->window()) toolbar]
    471465                removeItemAtIndex:toolbarItemsCopy.indexOf(item)];
    472             // In Carbon this hash and list gets emptied via events. In Cocoa, we have to do it ourselves here.
    473             it = unifiedToolbarHash.erase(it);
    474             qtoolbarsInUnifiedToolbarList.removeAll(toolbar);
    475466#endif
    476467            break;
     
    490481void QMainWindowLayout::fixSizeInUnifiedToolbar(QToolBar *tb) const
    491482{
     483#ifdef QT_MAC_USE_COCOA
    492484    QHash<void *, QToolBar *>::const_iterator it = unifiedToolbarHash.constBegin();
    493485    NSToolbarItem *item = nil;
     
    503495        QWidgetItem layoutItem(tb);
    504496        QSize size = layoutItem.maximumSize();
    505         NSSize nssize = NSMakeSize(size.width(), size.height());
     497        NSSize nssize = NSMakeSize(size.width(), size.height() - 2);
    506498        [item setMaxSize:nssize];
    507499        size = layoutItem.minimumSize();
    508500        nssize.width = size.width();
    509         nssize.height = size.height();
     501        nssize.height = size.height() - 2;
    510502        [item setMinSize:nssize];
    511503    }
    512 }
     504#else
     505    Q_UNUSED(tb);
     506#endif
     507}
     508
     509void QMainWindowLayout::syncUnifiedToolbarVisibility()
     510{
     511    if (blockVisiblityCheck)
     512        return;
     513
     514    Q_ASSERT(layoutState.mainWindow->unifiedTitleAndToolBarOnMac());
     515    bool show = false;
     516    const int ToolBarCount = qtoolbarsInUnifiedToolbarList.count();
     517    for (int i = 0; i < ToolBarCount; ++i) {
     518        if (qtoolbarsInUnifiedToolbarList.at(i)->isVisible()) {
     519            show = true;
     520            break;
     521        }
     522    }
     523    macWindowToolbarShow(layoutState.mainWindow, show);
     524}
     525
    513526QT_END_NAMESPACE
  • trunk/src/gui/widgets/qmainwindowlayout_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6262#include "QtCore/qvector.h"
    6363#include "QtCore/qset.h"
     64#include "QtCore/qbasictimer.h"
    6465#include "private/qlayoutengine_p.h"
     66#include "private/qwidgetanimator_p.h"
    6567
    6668#include "qdockarealayout_p.h"
     
    8991
    9092class QToolBar;
    91 class QWidgetAnimator;
    9293class QRubberBand;
    9394
     
    128129    QLayoutItem *takeAt(int index, int *x);
    129130    QList<int> indexOf(QWidget *widget) const;
    130     QLayoutItem *item(QList<int> path);
    131     QRect itemRect(QList<int> path) const;
    132     QRect gapRect(QList<int> path) const; // ### get rid of this, use itemRect() instead
     131    QLayoutItem *item(const QList<int> &path);
     132    QRect itemRect(const QList<int> &path) const;
     133    QRect gapRect(const QList<int> &path) const; // ### get rid of this, use itemRect() instead
    133134
    134135    bool contains(QWidget *widget) const;
     
    138139
    139140    QList<int> gapIndex(QWidget *widget, const QPoint &pos) const;
    140     bool insertGap(QList<int> path, QLayoutItem *item);
    141     void remove(QList<int> path);
     141    bool insertGap(const QList<int> &path, QLayoutItem *item);
     142    void remove(const QList<int> &path);
    142143    void remove(QLayoutItem *item);
    143144    void clear();
    144145    bool isValid() const;
    145146
    146     QLayoutItem *plug(QList<int> path);
    147     QLayoutItem *unplug(QList<int> path, QMainWindowLayoutState *savedState = 0);
     147    QLayoutItem *plug(const QList<int> &path);
     148    QLayoutItem *unplug(const QList<int> &path, QMainWindowLayoutState *savedState = 0);
    148149
    149150    void saveState(QDataStream &stream) const;
     
    165166    void setDockOptions(QMainWindow::DockOptions opts);
    166167    bool usesHIToolBar(QToolBar *toolbar) const;
     168
     169    void timerEvent(QTimerEvent *e);
    167170
    168171    // status bar
     
    244247    QList<int> movingSeparator;
    245248    QPoint movingSeparatorOrigin, movingSeparatorPos;
    246     QTimer *separatorMoveTimer;
    247     QVector<QLayoutStruct> separatorMoveCache;
     249    QBasicTimer separatorMoveTimer;
    248250
    249251    bool startSeparatorMove(const QPoint &pos);
     
    277279    // animations
    278280
    279     QWidgetAnimator *widgetAnimator;
     281    QWidgetAnimator widgetAnimator;
    280282    QList<int> currentGapPos;
    281283    QRect currentGapRect;
     
    294296    void restore(bool keepSavedState = false);
    295297    void updateHIToolBarStatus();
    296 
    297 private slots:
    298298    void animationFinished(QWidget *widget);
    299     void allAnimationsFinished();
     299
     300private Q_SLOTS:
    300301#ifndef QT_NO_DOCKWIDGET
    301     void doSeparatorMove();
    302302#ifndef QT_NO_TABBAR
    303303    void tabChanged();
     
    336336    void fixSizeInUnifiedToolbar(QToolBar *tb) const;
    337337    bool useHIToolBar;
     338    void syncUnifiedToolbarVisibility();
     339    bool blockVisiblityCheck;
    338340#endif
    339341};
     
    342344#endif // QT_NO_MAINWINDOW
    343345
    344 QT_BEGIN_NAMESPACE
    345 static inline int pick(Qt::Orientation o, const QPoint &pos)
    346 { return o == Qt::Horizontal ? pos.x() : pos.y(); }
    347 
    348 static inline int pick(Qt::Orientation o, const QSize &size)
    349 { return o == Qt::Horizontal ? size.width() : size.height(); }
    350 
    351 static inline int &rpick(Qt::Orientation o, QPoint &pos)
    352 { return o == Qt::Horizontal ? pos.rx() : pos.ry(); }
    353 
    354 static inline int &rpick(Qt::Orientation o, QSize &size)
    355 { return o == Qt::Horizontal ? size.rwidth() : size.rheight(); }
    356 
    357 static inline QSizePolicy::Policy pick(Qt::Orientation o, const QSizePolicy &policy)
    358 { return o == Qt::Horizontal ? policy.horizontalPolicy() : policy.verticalPolicy(); }
    359 
    360 static inline int perp(Qt::Orientation o, const QPoint &pos)
    361 { return o == Qt::Vertical ? pos.x() : pos.y(); }
    362 
    363 static inline int perp(Qt::Orientation o, const QSize &size)
    364 { return o == Qt::Vertical ? size.width() : size.height(); }
    365 
    366 static inline int &rperp(Qt::Orientation o, QPoint &pos)
    367 { return o == Qt::Vertical ? pos.rx() : pos.ry(); }
    368 
    369 static inline int &rperp(Qt::Orientation o, QSize &size)
    370 { return o == Qt::Vertical ? size.rwidth() : size.rheight(); }
    371 
    372 QT_END_NAMESPACE
    373 
    374346#endif // QDYNAMICMAINWINDOWLAYOUT_P_H
  • trunk/src/gui/widgets/qmdiarea.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4444    \brief The QMdiArea widget provides an area in which MDI windows are displayed.
    4545    \since 4.3
    46     \ingroup application
    47     \mainclass
     46    \ingroup mainwindow-classes
     47
    4848
    4949    QMdiArea functions, essentially, like a window manager for MDI
     
    8282    containing a list of windows, for example.
    8383
    84     The subwindows are sorted by the the current
     84    The subwindows are sorted by the current
    8585    \l{QMdiArea::}{WindowOrder}. This is used for the subWindowList()
    8686    and for activateNextSubWindow() and acivatePreviousSubWindow().
     
    801801    Q_ASSERT(child && childWindows.indexOf(child) == -1);
    802802
    803     if (child->parent() != q->viewport())
    804         child->setParent(q->viewport(), child->windowFlags());
     803    if (child->parent() != viewport)
     804        child->setParent(viewport, child->windowFlags());
    805805    childWindows.append(QPointer<QMdiSubWindow>(child));
    806806
    807807    if (!child->testAttribute(Qt::WA_Resized) && q->isVisible()) {
    808         QSize newSize(child->sizeHint().boundedTo(q->viewport()->size()));
     808        QSize newSize(child->sizeHint().boundedTo(viewport->size()));
    809809        child->resize(newSize.expandedTo(qSmartMinSize(child)));
    810810    }
     
    842842
    843843    QObject::connect(child, SIGNAL(aboutToActivate()), q, SLOT(_q_deactivateAllWindows()));
    844     QObject::connect(child, SIGNAL(windowStateChanged(Qt::WindowStates, Qt::WindowStates)),
    845                      q, SLOT(_q_processWindowStateChanged(Qt::WindowStates, Qt::WindowStates)));
     844    QObject::connect(child, SIGNAL(windowStateChanged(Qt::WindowStates,Qt::WindowStates)),
     845                     q, SLOT(_q_processWindowStateChanged(Qt::WindowStates,Qt::WindowStates)));
    846846}
    847847
     
    932932    }
    933933
    934     QRect domain = q->viewport()->rect();
     934    QRect domain = viewport->rect();
    935935    if (rearranger->type() == Rearranger::RegularTiler && !widgets.isEmpty())
    936936        domain = resizeToMinimumTileSize(minSubWindowSize, widgets.count());
     
    12131213    QMdiSubWindow *stackUnderChild = 0;
    12141214    if (!windowStaysOnTop(mdiChild)) {
    1215         foreach (QObject *object, q_func()->viewport()->children()) {
     1215        foreach (QObject *object, viewport->children()) {
    12161216            QMdiSubWindow *child = qobject_cast<QMdiSubWindow *>(object);
    12171217            if (!child || !childWindows.contains(child))
     
    12371237    Q_Q(QMdiArea);
    12381238    if (!minSubWindowSize.isValid() || subWindowCount <= 0)
    1239         return q->viewport()->rect();
     1239        return viewport->rect();
    12401240
    12411241    // Calculate minimum size.
     
    12561256        int minAreaWidth = minWidth + left + right + 2;
    12571257        int minAreaHeight = minHeight + top + bottom + 2;
    1258         if (q->horizontalScrollBar()->isVisible())
    1259             minAreaHeight += q->horizontalScrollBar()->height();
    1260         if (q->verticalScrollBar()->isVisible())
    1261             minAreaWidth += q->verticalScrollBar()->width();
     1258        if (hbar->isVisible())
     1259            minAreaHeight += hbar->height();
     1260        if (vbar->isVisible())
     1261            minAreaWidth += vbar->width();
    12621262        if (q->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, 0, q)) {
    12631263            const int frame = q->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, q);
     
    12691269    }
    12701270
    1271     QRect domain = q->viewport()->rect();
     1271    QRect domain = viewport->rect();
    12721272
    12731273    // Adjust domain width and provide horizontal scroll bar.
    12741274    if (domain.width() < minWidth) {
    12751275        domain.setWidth(minWidth);
    1276         if (q->horizontalScrollBarPolicy() == Qt::ScrollBarAlwaysOff)
     1276        if (hbarpolicy == Qt::ScrollBarAlwaysOff)
    12771277            q->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    1278         else if (q->horizontalScrollBar()->value() != 0)
    1279             q->horizontalScrollBar()->setValue(0);
     1278        else
     1279            hbar->setValue(0);
    12801280    }
    12811281    // Adjust domain height and provide vertical scroll bar.
    12821282    if (domain.height() < minHeight) {
    12831283        domain.setHeight(minHeight);
    1284         if (q->verticalScrollBarPolicy() == Qt::ScrollBarAlwaysOff)
     1284        if (vbarpolicy == Qt::ScrollBarAlwaysOff)
    12851285            q->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    1286         else if (q->verticalScrollBar()->value() != 0)
    1287             q->verticalScrollBar()->setValue(0);
     1286        else
     1287            vbar->setValue(0);
    12881288    }
    12891289    return domain;
     
    18541854
    18551855/*!
    1856     Gives the keyboard focus to the next window in the list of child
    1857     windows.  The windows are activated in the order in which they are
    1858     created (CreationOrder).
    1859 
    1860     \sa activatePreviousSubWindow()
     1856    Gives the keyboard focus to another window in the list of child
     1857    windows.  The window activated will be the next one determined
     1858    by the current \l{QMdiArea::WindowOrder} {activation order}.
     1859
     1860    \sa activatePreviousSubWindow(), QMdiArea::WindowOrder
    18611861*/
    18621862void QMdiArea::activateNextSubWindow()
     
    18721872
    18731873/*!
    1874     Gives the keyboard focus to the previous window in the list of
    1875     child windows. The windows are activated in the order in which
    1876     they are created (CreationOrder).
    1877 
    1878     \sa activateNextSubWindow()
     1874    Gives the keyboard focus to another window in the list of child
     1875    windows.  The window activated will be the previous one determined
     1876    by the current \l{QMdiArea::WindowOrder} {activation order}.
     1877
     1878    \sa activateNextSubWindow(), QMdiArea::WindowOrder
    18791879*/
    18801880void QMdiArea::activatePreviousSubWindow()
     
    19481948    Removes \a widget from the MDI area. The \a widget must be
    19491949    either a QMdiSubWindow or a widget that is the internal widget of
    1950     a subwindow. Note that the subwindow is not deleted by QMdiArea
    1951     and that its parent is set to 0.
     1950    a subwindow. Note \a widget is never actually deleted by QMdiArea.
     1951    If a QMdiSubWindow is passed in its parent is set to 0 and it is
     1952    removed, but if an internal widget is passed in the child widget
     1953    is set to 0 but the QMdiSubWindow is not removed.
    19521954
    19531955    \sa addSubWindow()
  • trunk/src/gui/widgets/qmdiarea.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qmdiarea_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qmdisubwindow.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4545    QMdiArea.
    4646    \since 4.3
    47     \ingroup application
    48     \mainclass
     47    \ingroup mainwindow-classes
     48
    4949
    5050    QMdiSubWindow represents a top-level window in a QMdiArea, and consists
     
    10071007    Q_Q(QMdiSubWindow);
    10081008    baseWidget->removeEventFilter(q);
    1009     if (QLayout *layout = q->layout())
     1009    if (layout)
    10101010        layout->removeWidget(baseWidget);
    10111011    if (baseWidget->windowTitle() == q->windowTitle()) {
     
    10671067    actions[CloseAction]->setIcon(style->standardIcon(QStyle::SP_TitleBarCloseButton, 0, q));
    10681068#if !defined(QT_NO_SHORTCUT)
    1069     actions[CloseAction]->setShortcut(QKeySequence::Close);
     1069    actions[CloseAction]->setShortcuts(QKeySequence::Close);
    10701070#endif
    10711071    updateActions();
     
    11031103{
    11041104    // No update necessary
    1105     if (!q_func()->parent())
     1105    if (!parent)
    11061106        return;
    11071107
     
    11161116{
    11171117    Q_Q(QMdiSubWindow);
    1118     if (!q->parent())
     1118    if (!parent)
    11191119        return;
    11201120
     
    11461146        q->clearMask();
    11471147
    1148     if (!q->parent())
     1148    if (!parent)
    11491149        return;
    11501150
     
    11691169    Q_Q(QMdiSubWindow);
    11701170    Q_ASSERT(currentOperation != None);
    1171     Q_ASSERT(q->parent());
     1171    Q_ASSERT(parent);
    11721172
    11731173    uint cflags = operationMap.find(currentOperation).value().changeFlags;
     
    12361236{
    12371237    Q_Q(QMdiSubWindow);
    1238     Q_ASSERT(q->parent());
     1238    Q_ASSERT(parent);
    12391239
    12401240    ensureWindowState(Qt::WindowMinimized);
     
    12641264{
    12651265    Q_Q(QMdiSubWindow);
    1266     Q_ASSERT(q->parent());
     1266    Q_ASSERT(parent);
    12671267
    12681268    isShadeMode = false;
     
    13351335{
    13361336    Q_Q(QMdiSubWindow);
    1337     Q_ASSERT(q->parent());
     1337    Q_ASSERT(parent);
    13381338
    13391339    ensureWindowState(Qt::WindowMaximized);
     
    14241424{
    14251425    Q_Q(QMdiSubWindow);
    1426     if (!q->parent() || !activationEnabled)
     1426    if (!parent || !activationEnabled)
    14271427        return;
    14281428
     
    17121712{
    17131713    Q_Q(const QMdiSubWindow);
    1714     if (!q->parent() || q->windowFlags() & Qt::FramelessWindowHint
     1714    if (!parent || q->windowFlags() & Qt::FramelessWindowHint
    17151715        || (q->isMaximized() && !drawTitleBarWhenMaximized())) {
    17161716        return 0;
     
    17351735    Q_Q(const QMdiSubWindow);
    17361736    Qt::WindowFlags flags = q->windowFlags();
    1737     if (!q->parent() || flags & Qt::FramelessWindowHint) {
     1737    if (!parent || flags & Qt::FramelessWindowHint) {
    17381738        *margin = 0;
    17391739        *minWidth = 0;
     
    17731773        return false;
    17741774
    1775 #if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC) || defined(Q_OS_WINCE_WM)
     1775#if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC) || defined(Q_WS_WINCE_WM)
    17761776    return true;
    17771777#else
     
    18941894        return;
    18951895    Q_ASSERT(oldGeometry.isValid());
    1896     Q_ASSERT(q->parent());
     1896    Q_ASSERT(parent);
    18971897    if (!rubberBand) {
    18981898        rubberBand = new QRubberBand(QRubberBand::Rectangle, q->parentWidget());
     
    19471947        newPalette.setColor(QPalette::Inactive, QPalette::HighlightedText,
    19481948                            colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTIONTEXT)));
    1949         if (QSysInfo::WindowsVersion != QSysInfo::WV_95
    1950                 && QSysInfo::WindowsVersion != QSysInfo::WV_NT) {
    1951             colorsInitialized = true;
    1952             BOOL hasGradient;
    1953             QT_WA({
    1954                 SystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, &hasGradient, 0);
    1955             } , {
    1956                 SystemParametersInfoA(SPI_GETGRADIENTCAPTIONS, 0, &hasGradient, 0);
    1957             });
    1958             if (hasGradient) {
    1959                 newPalette.setColor(QPalette::Active, QPalette::Base,
    1960                                     colorref2qrgb(GetSysColor(COLOR_GRADIENTACTIVECAPTION)));
    1961                 newPalette.setColor(QPalette::Inactive, QPalette::Base,
    1962                                     colorref2qrgb(GetSysColor(COLOR_GRADIENTINACTIVECAPTION)));
    1963             } else {
    1964                 newPalette.setColor(QPalette::Active, QPalette::Base,
    1965                                     newPalette.color(QPalette::Active, QPalette::Highlight));
    1966                 newPalette.setColor(QPalette::Inactive, QPalette::Base,
    1967                                     newPalette.color(QPalette::Inactive, QPalette::Highlight));
    1968             }
     1949
     1950        colorsInitialized = true;
     1951        BOOL hasGradient = false;
     1952        SystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, &hasGradient, 0);
     1953
     1954        if (hasGradient) {
     1955            newPalette.setColor(QPalette::Active, QPalette::Base,
     1956                                colorref2qrgb(GetSysColor(COLOR_GRADIENTACTIVECAPTION)));
     1957            newPalette.setColor(QPalette::Inactive, QPalette::Base,
     1958                                colorref2qrgb(GetSysColor(COLOR_GRADIENTINACTIVECAPTION)));
     1959        } else {
     1960            newPalette.setColor(QPalette::Active, QPalette::Base,
     1961                                newPalette.color(QPalette::Active, QPalette::Highlight));
     1962            newPalette.setColor(QPalette::Inactive, QPalette::Base,
     1963                                newPalette.color(QPalette::Inactive, QPalette::Highlight));
    19691964        }
    19701965    }
     
    20802075{
    20812076    Q_Q(QMdiSubWindow);
    2082     if (!q->parent()) {
     2077    if (!parent) {
    20832078        q->setWindowFlags(windowFlags);
    20842079        return;
     
    21652160{
    21662161    Q_Q(const QMdiSubWindow);
    2167     if (!q->parent() || q->windowFlags() & Qt::FramelessWindowHint)
     2162    if (!parent || q->windowFlags() & Qt::FramelessWindowHint)
    21682163        return QSize(-1, -1);
    21692164    return QSize(q->style()->pixelMetric(QStyle::PM_MdiSubWindowMinimizedWidth, 0, q), titleBarHeight());
     
    21812176        return;
    21822177
    2183     if (q->layout() && q->layout()->indexOf(newSizeGrip) != -1)
     2178    if (layout && layout->indexOf(newSizeGrip) != -1)
    21842179        return;
    21852180    newSizeGrip->setFixedSize(newSizeGrip->sizeHint());
    2186     bool putSizeGripInLayout = q->layout() ? true : false;
     2181    bool putSizeGripInLayout = layout ? true : false;
    21872182#if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC)
    21882183    if (qobject_cast<QMacStyle *>(q->style()))
     
    21902185#endif
    21912186    if (putSizeGripInLayout) {
    2192         q->layout()->addWidget(newSizeGrip);
    2193         q->layout()->setAlignment(newSizeGrip, Qt::AlignBottom | Qt::AlignRight);
     2187        layout->addWidget(newSizeGrip);
     2188        layout->setAlignment(newSizeGrip, Qt::AlignBottom | Qt::AlignRight);
    21942189    } else {
    21952190        newSizeGrip->setParent(q);
     
    22742269        d->menuIcon = windowIcon();
    22752270#endif
    2276     connect(qApp, SIGNAL(focusChanged(QWidget *, QWidget *)),
    2277             this, SLOT(_q_processFocusChanged(QWidget *, QWidget *)));
     2271    connect(qApp, SIGNAL(focusChanged(QWidget*,QWidget*)),
     2272            this, SLOT(_q_processFocusChanged(QWidget*,QWidget*)));
    22782273}
    22792274
  • trunk/src/gui/widgets/qmdisubwindow.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qmdisubwindow_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    288288    {
    289289        Q_Q(const QMdiSubWindow);
    290         if (!q->parent() || q->windowFlags() & Qt::FramelessWindowHint
     290        if (!parent || q->windowFlags() & Qt::FramelessWindowHint
    291291            || (q->isMaximized() && !drawTitleBarWhenMaximized())) {
    292292            return 0;
     
    309309    {
    310310        Q_Q(QMdiSubWindow);
    311         Q_ASSERT(q->parent());
     311        Q_ASSERT(parent);
    312312        geometry->setSize(geometry->size().expandedTo(internalMinimumSize));
    313313#ifndef QT_NO_RUBBERBAND
  • trunk/src/gui/widgets/qmenu.cpp

    r305 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6666#include "qwidgetaction.h"
    6767#include "qtoolbutton.h"
     68#include "qpushbutton.h"
     69#include <private/qpushbutton_p.h>
    6870#include <private/qaction_p.h>
     71#include <private/qsoftkeymanager_p.h>
    6972#ifdef QT3_SUPPORT
    7073#include <qmenudata.h>
     
    151154{
    152155    Q_Q(QMenu);
    153     activationRecursionGuard = false;
    154156#ifndef QT_NO_WHATSTHIS
    155157    q->setAttribute(Qt::WA_CustomWhatsThis);
     
    163165        scroll->scrollFlags = QMenuPrivate::QMenuScroller::ScrollNone;
    164166    }
     167
     168#ifdef QT_SOFTKEYS_ENABLED
     169    selectAction = QSoftKeyManager::createKeyedAction(QSoftKeyManager::SelectSoftKey, Qt::Key_Select, q);
     170    cancelAction = QSoftKeyManager::createKeyedAction(QSoftKeyManager::CancelSoftKey, Qt::Key_Back, q);
     171    selectAction->setVisible(false); // Don't show these in the menu
     172    cancelAction->setVisible(false);
     173    q->addAction(selectAction);
     174    q->addAction(cancelAction);
     175#endif
     176}
     177
     178int QMenuPrivate::scrollerHeight() const
     179{
     180    Q_Q(const QMenu);
     181    return qMax(QApplication::globalStrut().height(), q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q));
     182}
     183
     184// Windows, OS/2 and KDE allows menus to cover the taskbar, while GNOME and Mac don't
     185QRect QMenuPrivate::popupGeometry(const QWidget *widget) const
     186{
     187#if defined(Q_WS_WIN) || defined(Q_WS_PM)
     188    return QApplication::desktop()->screenGeometry(widget);
     189#elif defined Q_WS_X11
     190    if (X11->desktopEnvironment == DE_KDE)
     191        return QApplication::desktop()->screenGeometry(widget);
     192    else
     193        return QApplication::desktop()->availableGeometry(widget);
     194#else
     195        return QApplication::desktop()->availableGeometry(widget);
     196#endif
    165197}
    166198
     
    195227}
    196228
    197 void QMenuPrivate::calcActionRects(QMap<QAction*, QRect> &actionRects, QList<QAction*> &actionList) const
     229void QMenuPrivate::updateActionRects() const
    198230{
    199231    Q_Q(const QMenu);
    200     if (!itemsDirty) {
    201         actionRects = this->actionRects;
    202         actionList = this->actionList;
     232    if (!itemsDirty)
    203233        return;
    204     }
    205 
    206     actionRects.clear();
    207     actionList.clear();
    208     QList<QAction*> items = filterActions(q->actions());
     234
     235    q->ensurePolished();
     236
     237    //let's reinitialize the buffer
     238    actionRects.resize(actions.count());
     239    actionRects.fill(QRect());
     240
     241    //let's try to get the last visible action
     242    int lastVisibleAction = actions.count() - 1;
     243    for(;lastVisibleAction >= 0; --lastVisibleAction) {
     244        const QAction *action = actions.at(lastVisibleAction);
     245        if (action->isVisible()) {
     246            //removing trailing separators
     247            if (action->isSeparator() && collapsibleSeparators)
     248                continue;
     249            break;
     250        }
     251    }
     252
    209253    int max_column_width = 0,
    210         dh = popupGeometry(QApplication::desktop()->screenNumber(q)).height(),
    211         ncols = 1,
     254        dh = popupGeometry(q).height(),
    212255        y = 0;
    213     const int hmargin = q->style()->pixelMetric(QStyle::PM_MenuHMargin, 0, q),
    214               vmargin = q->style()->pixelMetric(QStyle::PM_MenuVMargin, 0, q),
    215               icone = q->style()->pixelMetric(QStyle::PM_SmallIconSize, 0, q);
     256    QStyle *style = q->style();
     257    QStyleOption opt;
     258    opt.init(q);
     259    const int hmargin = style->pixelMetric(QStyle::PM_MenuHMargin, &opt, q),
     260              vmargin = style->pixelMetric(QStyle::PM_MenuVMargin, &opt, q),
     261              icone = style->pixelMetric(QStyle::PM_SmallIconSize, &opt, q);
     262    const int fw = style->pixelMetric(QStyle::PM_MenuPanelWidth, &opt, q);
     263    const int deskFw = style->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, &opt, q);
     264
     265    const int sfcMargin = style->sizeFromContents(QStyle::CT_Menu, &opt, QApplication::globalStrut(), q).width() - QApplication::globalStrut().width();
     266    const int min_column_width = q->minimumWidth() - (sfcMargin + leftmargin + rightmargin + 2 * (fw + hmargin));
     267    const int tearoffHeight = tearoff ? style->pixelMetric(QStyle::PM_MenuTearoffHeight, &opt, q) : 0;
    216268
    217269    //for compatability now - will have to refactor this away..
     
    219271    maxIconWidth = 0;
    220272    hasCheckableItems = false;
    221     for(int i = 0; i < items.count(); i++) {
    222         QAction *action = items.at(i);
    223         if (widgetItems.value(action))
     273    ncols = 1;
     274    sloppyAction = 0;
     275
     276    for (int i = 0; i < actions.count(); ++i) {
     277        QAction *action = actions.at(i);
     278        if (action->isSeparator() || !action->isVisible() || widgetItems.contains(action))
    224279            continue;
     280        //..and some members
    225281        hasCheckableItems |= action->isCheckable();
    226282        QIcon is = action->icon();
    227283        if (!is.isNull()) {
    228             uint miw = maxIconWidth;
    229             maxIconWidth = qMax<uint>(miw, icone + 4);
     284            maxIconWidth = qMax<uint>(maxIconWidth, icone + 4);
    230285        }
    231286    }
     
    233288    //calculate size
    234289    QFontMetrics qfm = q->fontMetrics();
    235     for(int i = 0; i < items.count(); i++) {
    236         QAction *action = items.at(i);
    237 
    238         QFontMetrics fm(action->font().resolve(q->font()));
    239         QSize sz;
     290    bool previousWasSeparator = true; // this is true to allow removing the leading separators
     291    for(int i = 0; i <= lastVisibleAction; i++) {
     292        QAction *action = actions.at(i);
     293
     294        if (!action->isVisible() ||
     295            (collapsibleSeparators && previousWasSeparator && action->isSeparator()))
     296            continue; // we continue, this action will get an empty QRect
     297
     298        previousWasSeparator = action->isSeparator();
    240299
    241300        //let the style modify the above size..
    242301        QStyleOptionMenuItem opt;
    243302        q->initStyleOption(&opt, action);
    244         opt.rect = q->rect();
    245 
     303        const QFontMetrics &fm = opt.fontMetrics;
     304
     305        QSize sz;
    246306        if (QWidget *w = widgetItems.value(action)) {
    247           sz=w->sizeHint().expandedTo(w->minimumSize()).expandedTo(w->minimumSizeHint()).boundedTo(w->maximumSize());
     307          sz = w->sizeHint().expandedTo(w->minimumSize()).expandedTo(w->minimumSizeHint()).boundedTo(w->maximumSize());
    248308        } else {
    249309            //calc what I think the size is..
     
    263323    #endif
    264324                }
    265                 int w = fm.boundingRect(QRect(), Qt::TextSingleLine, s).width();
    266                 w -= s.count(QLatin1Char('&')) * fm.width(QLatin1Char('&'));
    267                 w += s.count(QLatin1String("&&")) * fm.width(QLatin1Char('&'));
    268                 sz.setWidth(w);
     325                sz.setWidth(fm.boundingRect(QRect(), Qt::TextSingleLine | Qt::TextShowMnemonic, s).width());
    269326                sz.setHeight(qMax(fm.height(), qfm.height()));
    270327
     
    276333                }
    277334            }
    278           sz = q->style()->sizeFromContents(QStyle::CT_MenuItem, &opt, sz, q);
     335            sz = style->sizeFromContents(QStyle::CT_MenuItem, &opt, sz, q);
    279336        }
    280337
    281338
    282339        if (!sz.isEmpty()) {
    283             max_column_width = qMax(max_column_width, sz.width());
     340            max_column_width = qMax(min_column_width, qMax(max_column_width, sz.width()));
    284341            //wrapping
    285342            if (!scroll &&
    286                y+sz.height()+vmargin > dh - (q->style()->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, 0, q) * 2)) {
     343               y+sz.height()+vmargin > dh - (deskFw * 2)) {
    287344                ncols++;
    288345                y = vmargin;
    289346            }
    290347            y += sz.height();
    291             //append item
    292             actionRects.insert(action, QRect(0, 0, sz.width(), sz.height()));
    293             actionList.append(action);
    294         }
    295     }
    296 
    297     if (tabWidth)
    298         max_column_width += tabWidth; //finally add in the tab width
     348            //update the item
     349            actionRects[i] = QRect(0, 0, sz.width(), sz.height());
     350        }
     351    }
     352
     353    max_column_width += tabWidth; //finally add in the tab width
    299354
    300355    //calculate position
    301     int x = hmargin;
    302     y = vmargin;
    303 
    304     for(int i = 0; i < actionList.count(); i++) {
    305         QAction *action = actionList.at(i);
    306         QRect &rect = actionRects[action];
     356    const int base_y = vmargin + fw + topmargin +
     357        (scroll ? scroll->scrollOffset : 0) +
     358        tearoffHeight;
     359    int x = hmargin + fw + leftmargin;
     360    y = base_y;
     361
     362    for(int i = 0; i < actions.count(); i++) {
     363        QRect &rect = actionRects[i];
    307364        if (rect.isNull())
    308365            continue;
    309366        if (!scroll &&
    310            y+rect.height() > dh - (q->style()->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, 0, q) * 2)) {
    311             ncols--;
    312             if (ncols < 0)
    313                 qWarning("QMenu: Column calculation mismatch (%d)", ncols);
     367           y+rect.height() > dh - deskFw * 2) {
    314368            x += max_column_width + hmargin;
    315             y = vmargin;
     369            y = base_y;
    316370        }
    317371        rect.translate(x, y);                        //move
    318372        rect.setWidth(max_column_width); //uniform width
     373
     374        //we need to update the widgets geometry
     375        if (QWidget *widget = widgetItems.value(actions.at(i))) {
     376            widget->setGeometry(rect);
     377            widget->setVisible(actions.at(i)->isVisible());
     378        }
     379
    319380        y += rect.height();
    320381    }
    321 }
    322 
    323 void QMenuPrivate::updateActions()
    324 {
    325     Q_Q(const QMenu);
    326     if (!itemsDirty)
    327         return;
    328     sloppyAction = 0;
    329     calcActionRects(actionRects, actionList);
    330     for (QHash<QAction *, QWidget *>::ConstIterator item = widgetItems.constBegin(),
    331          end = widgetItems.constEnd(); item != end; ++item) {
    332         QAction *action = item.key();
    333         QWidget *widget = item.value();
    334         widget->setGeometry(actionRect(action));
    335         widget->setVisible(action->isVisible());
    336     }
    337     ncols = 1;
    338     int last_left = q->style()->pixelMetric(QStyle::PM_MenuVMargin, 0, q);
    339     if (!scroll) {
    340         for(int i = 0; i < actionList.count(); i++) {
    341             int left = actionRects.value(actionList.at(i)).left();
    342             if (left > last_left) {
    343                 last_left = left;
    344                 ncols++;
    345             }
    346         }
    347     }
    348382    itemsDirty = 0;
    349383}
    350384
    351 QList<QAction *> QMenuPrivate::filterActions(const QList<QAction *> &actions) const
    352 {
    353     QList<QAction *> visibleActions;
    354     int i = 0;
    355     while (i < actions.count()) {
    356         QAction *action = actions.at(i);
    357         if (!action->isVisible()) {
    358             ++i;
    359             continue;
    360         }
    361         if (!action->isSeparator() || !collapsibleSeparators) {
    362             visibleActions.append(action);
    363             ++i;
    364             continue;
    365         }
    366 
    367         // no leading separators
    368         if (!visibleActions.isEmpty())
    369             visibleActions.append(action);
    370 
    371         // skip double/tripple/etc. separators
    372         while (i < actions.count()
    373                && (!actions.at(i)->isVisible() || actions.at(i)->isSeparator()))
    374             ++i;
    375     }
    376 
    377     if (collapsibleSeparators) {
    378         // remove trailing separators
    379         while (!visibleActions.isEmpty() && visibleActions.last()->isSeparator())
    380             visibleActions.removeLast();
    381     }
    382 
    383     return visibleActions;
    384 }
    385 
    386385QRect QMenuPrivate::actionRect(QAction *act) const
    387386{
    388     Q_Q(const QMenu);
    389     QRect ret = actionRects.value(act);
    390     if (ret.isNull())
    391         return ret;
    392     if (scroll)
    393         ret.translate(0, scroll->scrollOffset);
    394     if (tearoff)
    395         ret.translate(0, q->style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, q));
    396     const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q);
    397     ret.translate(fw+leftmargin, fw+topmargin);
    398     return ret;
    399 }
     387    int index = actions.indexOf(act);
     388    if (index == -1)
     389        return QRect();
     390
     391    updateActionRects();
     392
     393    //we found the action
     394    return actionRects.at(index);
     395}
     396
     397#if defined(Q_WS_MAC)
     398static const qreal MenuFadeTimeInSec = 0.150;
     399#endif
    400400
    401401void QMenuPrivate::hideUpToMenuBar()
    402402{
    403403    Q_Q(QMenu);
     404    bool fadeMenus = q->style()->styleHint(QStyle::SH_Menu_FadeOutOnHide);
    404405    if (!tornoff) {
    405406        QWidget *caused = causedPopup.widget;
     
    416417                caused = m->d_func()->causedPopup.widget;
    417418                if (!m->d_func()->tornoff)
    418                     hideMenu(m);
    419                 m->d_func()->setCurrentAction(0);
    420             } else {
    421 #ifndef QT_NO_TOOLBUTTON
    422                 if (qobject_cast<QToolButton*>(caused) == 0)
    423 #endif
    424                     qWarning("QMenu: Internal error");
    425                 caused = 0;
     419                    hideMenu(m, fadeMenus);
     420                if (!fadeMenus) // Mac doesn't clear the action until after hidden.
     421                    m->d_func()->setCurrentAction(0);
     422            } else {                caused = 0;
    426423            }
    427424        }
     425#if defined(Q_WS_MAC)
     426        if (fadeMenus) {
     427            QEventLoop eventLoop;
     428            QTimer::singleShot(int(MenuFadeTimeInSec * 1000), &eventLoop, SLOT(quit()));
     429            QMacWindowFader::currentFader()->performFade();
     430            eventLoop.exec();
     431        }
     432#endif
    428433    }
    429434    setCurrentAction(0);
    430435}
    431436
    432 void QMenuPrivate::hideMenu(QMenu *menu)
     437void QMenuPrivate::hideMenu(QMenu *menu, bool justRegister)
    433438{
    434439    if (!menu)
    435440        return;
    436 
    437441#if !defined(QT_NO_EFFECTS)
    438442    menu->blockSignals(true);
     
    440444    // Flash item which is about to trigger (if any).
    441445    if (menu->style()->styleHint(QStyle::SH_Menu_FlashTriggeredItem)
    442         && currentAction && currentAction == actionAboutToTrigger) {
    443 
     446        && currentAction && currentAction == actionAboutToTrigger
     447        && menu->actions().contains(currentAction)) {
    444448        QEventLoop eventLoop;
    445449        QAction *activeAction = currentAction;
    446450
    447         // Deselect and wait 60 ms.
    448451        menu->setActiveAction(0);
    449452        QTimer::singleShot(60, &eventLoop, SLOT(quit()));
     
    459462    if (menu->style()->styleHint(QStyle::SH_Menu_FadeOutOnHide)) {
    460463        // ### Qt 4.4:
    461         // Should be something like: q->transitionWindow(Qt::FadeOutTransition, 150);
     464        // Should be something like: q->transitionWindow(Qt::FadeOutTransition, MenuFadeTimeInSec);
    462465        // Hopefully we'll integrate qt/research/windowtransitions into main before 4.4.
    463466        // Talk to Richard, Trenton or Bjoern.
    464467#if defined(Q_WS_MAC)
    465                 macWindowFade(qt_mac_window_for(menu));         // FIXME - what is the default duration for view animations
    466 
    467         // Wait for the transition to complete.
    468                 QEventLoop eventLoop;
    469         QTimer::singleShot(150, &eventLoop, SLOT(quit()));
    470         eventLoop.exec();
     468        if (justRegister) {
     469            QMacWindowFader::currentFader()->setFadeDuration(MenuFadeTimeInSec);
     470            QMacWindowFader::currentFader()->registerWindowToFade(menu);
     471        } else {
     472            macWindowFade(qt_mac_window_for(menu), MenuFadeTimeInSec);
     473        }
     474
    471475#endif // Q_WS_MAC
    472476    }
     
    474478    menu->blockSignals(false);
    475479#endif // QT_NO_EFFECTS
    476     menu->hide();
     480    if (!justRegister)
     481        menu->hide();
    477482}
    478483
     
    514519{
    515520    Q_Q(QMenu);
    516     const int scrollerHeight = q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q);
    517     for(int i = 0, saccum = 0; i < actionList.count(); i++) {
    518         QAction *act = actionList[i];
     521    updateActionRects();
     522    for(int i = 0, saccum = 0; i < actions.count(); i++) {
     523        const QRect &rect = actionRects.at(i);
     524        if (rect.isNull())
     525            continue;
    519526        if (scroll && scroll->scrollFlags & QMenuScroller::ScrollUp) {
    520             saccum -= actionRects.value(act).height();
    521             if (saccum > scroll->scrollOffset-scrollerHeight)
     527            saccum -= rect.height();
     528            if (saccum > scroll->scrollOffset - scrollerHeight())
    522529                continue;
    523530        }
     531        QAction *act = actions.at(i);
    524532        if (!act->isSeparator() &&
    525533           (q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, q)
     
    536544    Q_Q(QMenu);
    537545    tearoffHighlighted = 0;
    538     if (action == currentAction && !(action && action->menu() && action->menu() != activeMenu)) {
    539         if(QMenu *menu = qobject_cast<QMenu*>(causedPopup.widget)) {
    540             if(causedPopup.action && menu->d_func()->activeMenu == q)
    541                 menu->d_func()->setCurrentAction(causedPopup.action, 0, reason, false);
     546    if (action == currentAction) {
     547        if (!action || !action->menu() || action->menu() == activeMenu) {
     548            if(QMenu *menu = qobject_cast<QMenu*>(causedPopup.widget)) {
     549                if(causedPopup.action && menu->d_func()->activeMenu == q)
     550                    menu->d_func()->setCurrentAction(causedPopup.action, 0, reason, false);
     551            }
    542552        }
    543553        return;
     
    554564#endif
    555565#ifdef QT3_SUPPORT
    556     emitHighlighted = (action && action != currentAction);
     566    emitHighlighted = action;
    557567#endif
    558568    currentAction = action;
     
    569579            }
    570580            q->update(actionRect(action));
    571             QWidget *widget = widgetItems.value(action);
    572581
    573582            if (reason == SelectedFromKeyboard) {
     583                QWidget *widget = widgetItems.value(action);
    574584                if (widget) {
    575585                    if (widget->focusPolicy() != Qt::NoFocus)
     
    579589                    // get the focus
    580590                    // Since the menu is a pop-up, it uses the popup reason.
    581                     if (!q->hasFocus())
     591                    if (!q->hasFocus()) {
    582592                        q->setFocus(Qt::PopupFocusReason);
     593                    }
    583594                }
    584595            }
     
    589600#ifndef QT_NO_STATUSTIP
    590601    }  else if (previousAction) {
    591         QWidget *w = causedPopup.widget;
    592         while (QMenu *m = qobject_cast<QMenu*>(w))
    593             w = m->d_func()->causedPopup.widget;
    594         if (w) {
    595             QString empty;
    596             QStatusTipEvent tip(empty);
    597             QApplication::sendEvent(w, &tip);
    598         }
     602        previousAction->d_func()->showStatusText(topCausedWidget(), QString());
    599603#endif
    600604    }
     
    610614}
    611615
     616//return the top causedPopup.widget that is not a QMenu
     617QWidget *QMenuPrivate::topCausedWidget() const
     618{
     619    QWidget* top = causedPopup.widget;
     620    while (QMenu* m = qobject_cast<QMenu *>(top))
     621        top = m->d_func()->causedPopup.widget;
     622    return top;
     623}
     624
    612625QAction *QMenuPrivate::actionAt(QPoint p) const
    613626{
     
    615628       return 0;
    616629
    617     for(int i = 0; i < actionList.count(); i++) {
    618         QAction *act = actionList[i];
    619         if (actionRect(act).contains(p))
    620             return act;
     630    for(int i = 0; i < actionRects.count(); i++) {
     631        if (actionRects.at(i).contains(p))
     632            return actions.at(i);
    621633    }
    622634    return 0;
     
    640652}
    641653
     654
     655void QMenuPrivate::updateLayoutDirection()
     656{
     657    Q_Q(QMenu);
     658    //we need to mimic the cause of the popup's layout direction
     659    //to allow setting it on a mainwindow for example
     660    //we call setLayoutDirection_helper to not overwrite a user-defined value
     661    if (!q->testAttribute(Qt::WA_SetLayoutDirection)) {
     662        if (QWidget *w = causedPopup.widget)
     663            setLayoutDirection_helper(w->layoutDirection());
     664        else if (QWidget *w = q->parentWidget())
     665            setLayoutDirection_helper(w->layoutDirection());
     666        else
     667            setLayoutDirection_helper(QApplication::layoutDirection());
     668    }
     669}
     670
     671
    642672/*!
    643673    Returns the action associated with this menu.
     
    692722    if (!scroll || !scroll->scrollFlags)
    693723        return;
     724    updateActionRects();
    694725    int newOffset = 0;
    695     const int scrollHeight = q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q);
    696     const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp)   ? scrollHeight : 0;
    697     const int botScroll = (scroll->scrollFlags & QMenuScroller::ScrollDown) ? scrollHeight : 0;
     726    const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp)   ? scrollerHeight() : 0;
     727    const int botScroll = (scroll->scrollFlags & QMenuScroller::ScrollDown) ? scrollerHeight() : 0;
    698728    const int vmargin = q->style()->pixelMetric(QStyle::PM_MenuVMargin, 0, q);
    699729    const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q);
    700730
    701731    if (location == QMenuScroller::ScrollTop) {
    702         for(int i = 0, saccum = 0; i < actionList.count(); i++) {
    703             QAction *act = actionList.at(i);
    704             if (act == action) {
     732        for(int i = 0, saccum = 0; i < actions.count(); i++) {
     733            if (actions.at(i) == action) {
    705734                newOffset = topScroll - saccum;
    706735                break;
    707736            }
    708             saccum += actionRects.value(act).height();
     737            saccum += actionRects.at(i).height();
    709738        }
    710739    } else {
    711         for(int i = 0, saccum = 0; i < actionList.count(); i++) {
    712             QAction *act = actionList.at(i);
    713             saccum += actionRects.value(act).height();
    714             if (act == action) {
     740        for(int i = 0, saccum = 0; i < actions.count(); i++) {
     741            saccum += actionRects.at(i).height();
     742            if (actions.at(i) == action) {
    715743                if (location == QMenuScroller::ScrollCenter)
    716744                    newOffset = ((q->height() / 2) - botScroll) - (saccum - topScroll);
     
    721749        }
    722750        if(newOffset)
    723             newOffset -= fw*2;
     751            newOffset -= fw * 2;
    724752    }
    725753
     
    729757        newScrollFlags |= QMenuScroller::ScrollUp;
    730758    int saccum = newOffset;
    731     for(int i = 0; i < actionList.count(); i++) {
    732         saccum += actionRects.value(actionList.at(i)).height();
     759    for(int i = 0; i < actionRects.count(); i++) {
     760        saccum += actionRects.at(i).height();
    733761        if (saccum > q->height()) {
    734762            newScrollFlags |= QMenuScroller::ScrollDown;
     
    748776        newOffset -= vmargin;
    749777
    750     QRect screen = popupGeometry(QApplication::desktop()->screenNumber(q));
     778    QRect screen = popupGeometry(q);
    751779    const int desktopFrame = q->style()->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, 0, q);
    752780    if (q->height() < screen.height()-(desktopFrame*2)-1) {
     
    781809
    782810    //actually update flags
    783     scroll->scrollOffset = newOffset;
    784     if (scroll->scrollOffset > 0)
    785         scroll->scrollOffset = 0;
     811    const int delta = qMin(0, newOffset) - scroll->scrollOffset; //make sure the new offset is always negative
     812    if (!itemsDirty && delta) {
     813        //we've scrolled so we need to update the action rects
     814        for (int i = 0; i < actionRects.count(); ++i) {
     815            QRect &current = actionRects[i];
     816            current.moveTop(current.top() + delta);
     817
     818            //we need to update the widgets geometry
     819            if (QWidget *w = widgetItems.value(actions.at(i)))
     820                w->setGeometry(current);
     821        }
     822    }
     823    scroll->scrollOffset += delta;
    786824    scroll->scrollFlags = newScrollFlags;
    787825    if (active)
     
    794832{
    795833    Q_Q(QMenu);
     834    updateActionRects();
    796835    if(location == QMenuScroller::ScrollBottom) {
    797         for(int i = actionList.size()-1; i >= 0; --i) {
    798             QAction *act = actionList.at(i);
     836        for(int i = actions.size()-1; i >= 0; --i) {
     837            QAction *act = actions.at(i);
     838            if (actionRects.at(i).isNull())
     839                continue;
    799840            if (!act->isSeparator() &&
    800841                (q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, q)
     
    808849        }
    809850    } else if(location == QMenuScroller::ScrollTop) {
    810         for(int i = 0; i < actionList.size(); ++i) {
    811             QAction *act = actionList.at(i);
     851        for(int i = 0; i < actions.size(); ++i) {
     852            QAction *act = actions.at(i);
     853            if (actionRects.at(i).isNull())
     854                continue;
    812855            if (!act->isSeparator() &&
    813856                (q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, q)
     
    829872    if (!scroll || !(scroll->scrollFlags & direction)) //not really possible...
    830873        return;
    831     const int scrollHeight = q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q);
    832     const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp)   ? scrollHeight : 0;
    833     const int botScroll = (scroll->scrollFlags & QMenuScroller::ScrollDown) ? scrollHeight : 0;
     874    updateActionRects();
     875    const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp)   ? scrollerHeight() : 0;
     876    const int botScroll = (scroll->scrollFlags & QMenuScroller::ScrollDown) ? scrollerHeight() : 0;
    834877    const int vmargin = q->style()->pixelMetric(QStyle::PM_MenuVMargin, 0, q);
    835878    const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q);
    836879    const int offset = topScroll ? topScroll-vmargin : 0;
    837880    if (direction == QMenuScroller::ScrollUp) {
    838         for(int i = 0, saccum = 0; i < actionList.count(); i++) {
    839             QAction *act = actionList.at(i);
    840             const int iHeight = actionRects.value(act).height();
    841             saccum -= iHeight;
     881        for(int i = 0, saccum = 0; i < actions.count(); i++) {
     882            saccum -= actionRects.at(i).height();
    842883            if (saccum <= scroll->scrollOffset-offset) {
    843                 scrollMenu(act, page ? QMenuScroller::ScrollBottom : QMenuScroller::ScrollTop, active);
     884                scrollMenu(actions.at(i), page ? QMenuScroller::ScrollBottom : QMenuScroller::ScrollTop, active);
    844885                break;
    845886            }
     
    847888    } else if (direction == QMenuScroller::ScrollDown) {
    848889        bool scrolled = false;
    849         for(int i = 0, saccum = 0; i < actionList.count(); i++) {
    850             QAction *act = actionList.at(i);
    851             const int iHeight = actionRects.value(act).height();
     890        for(int i = 0, saccum = 0; i < actions.count(); i++) {
     891            const int iHeight = actionRects.at(i).height();
    852892            saccum -= iHeight;
    853893            if (saccum <= scroll->scrollOffset-offset) {
    854894                const int scrollerArea = q->height() - botScroll - fw*2;
    855895                int visible = (scroll->scrollOffset-offset) - saccum;
    856                 for(i++ ; i < actionList.count(); i++) {
    857                     act = actionList.at(i);
    858                     const int iHeight = actionRects.value(act).height();
    859                     visible += iHeight;
     896                for(i++ ; i < actions.count(); i++) {
     897                    visible += actionRects.at(i).height();
    860898                    if (visible > scrollerArea - topScroll) {
    861899                        scrolled = true;
    862                         scrollMenu(act, page ? QMenuScroller::ScrollTop : QMenuScroller::ScrollBottom, active);
     900                        scrollMenu(actions.at(i), page ? QMenuScroller::ScrollTop : QMenuScroller::ScrollBottom, active);
    863901                        break;
    864902                    }
     
    883921        bool isScroll = false;
    884922        if (pos.x() >= 0 && pos.x() < q->width()) {
    885             const int scrollerHeight = q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q);
    886923            for(int dir = QMenuScroller::ScrollUp; dir <= QMenuScroller::ScrollDown; dir = dir << 1) {
    887924                if (scroll->scrollFlags & dir) {
    888925                    if (dir == QMenuScroller::ScrollUp)
    889                         isScroll = (pos.y() <= scrollerHeight);
     926                        isScroll = (pos.y() <= scrollerHeight());
    890927                    else if (dir == QMenuScroller::ScrollDown)
    891                         isScroll = (pos.y() >= q->height()-scrollerHeight);
     928                        isScroll = (pos.y() >= q->height() - scrollerHeight());
    892929                    if (isScroll) {
    893930                        scroll->scrollDirection = dir;
     
    898935        }
    899936        if (isScroll) {
    900             if (!scroll->scrollTimer)
    901                 scroll->scrollTimer = new QBasicTimer;
    902             scroll->scrollTimer->start(50, q);
     937            scroll->scrollTimer.start(50, q);
    903938            return true;
    904         } else if (scroll->scrollTimer && scroll->scrollTimer->isActive()) {
    905             scroll->scrollTimer->stop();
     939        } else {
     940            scroll->scrollTimer.stop();
    906941        }
    907942    }
     
    910945        QRect tearRect(0, 0, q->width(), q->style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, q));
    911946        if (scroll && scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)
    912             tearRect.translate(0, q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q));
     947            tearRect.translate(0, scrollerHeight());
    913948        q->update(tearRect);
    914949        if (tearRect.contains(pos) && hasMouseMoved(e->globalPos())) {
     
    957992}
    958993
     994class ExceptionGuard
     995{
     996public:
     997    inline ExceptionGuard(bool *w = 0) : watched(w) { Q_ASSERT(!(*watched)); *watched = true; }
     998    inline ~ExceptionGuard() { *watched = false; }
     999    inline operator bool() { return *watched; }
     1000private:
     1001    bool *watched;
     1002};
     1003
    9591004void QMenuPrivate::activateCausedStack(const QList<QPointer<QWidget> > &causedStack, QAction *action, QAction::ActionEvent action_e, bool self)
    9601005{
    961     Q_ASSERT(!activationRecursionGuard);
    962     activationRecursionGuard = true;
     1006    ExceptionGuard guard(&activationRecursionGuard);
    9631007#ifdef QT3_SUPPORT
    9641008    const int actionId = q_func()->findIdForAction(action);
     
    10051049        }
    10061050    }
    1007     activationRecursionGuard = false;
    10081051}
    10091052
     
    10351078            hideUpToMenuBar();
    10361079        } else {
    1037             for(QWidget *widget = qApp->activePopupWidget(); widget; ) {
     1080            for(QWidget *widget = QApplication::activePopupWidget(); widget; ) {
    10381081                if (QMenu *qmenu = qobject_cast<QMenu*>(widget)) {
    10391082                    if(qmenu == q)
     
    10691112        }
    10701113#endif
    1071         QWidget *w = causedPopup.widget;
    1072         while (QMenu *m = qobject_cast<QMenu*>(w))
    1073             w = m->d_func()->causedPopup.widget;
    1074         action->showStatusText(w);
     1114        action->showStatusText(topCausedWidget());
    10751115    } else {
    10761116        actionAboutToTrigger = 0;
     
    10821122    Q_Q(QMenu);
    10831123    if (QAction *action = qobject_cast<QAction *>(q->sender())) {
     1124        QWeakPointer<QAction> actionGuard = action;
    10841125#ifdef QT3_SUPPORT
    10851126        //we store it here because the action might be deleted/changed by connected slots
     
    10911132#endif
    10921133
    1093         if (!activationRecursionGuard) {
     1134        if (!activationRecursionGuard && actionGuard) {
    10941135            //in case the action has not been activated by the mouse
    10951136            //we check the parent hierarchy
     
    11651206        option->palette.setCurrentColorGroup(QPalette::Disabled);
    11661207
    1167     option->font = action->font();
     1208    option->font = action->font().resolve(font());
     1209    option->fontMetrics = QFontMetrics(option->font);
    11681210
    11691211    if (d->currentAction && d->currentAction == action && !d->currentAction->isSeparator()) {
     
    12091251    bars, context menus, and other popup menus.
    12101252
    1211     \ingroup application
     1253    \ingroup mainwindow-classes
    12121254    \ingroup basicwidgets
    1213     \mainclass
     1255
    12141256
    12151257    A menu widget is a selection menu. It can be either a pull-down
     
    13031345    It is not possible to display an icon in a native menu on Windows Mobile.
    13041346
     1347    \section1 QMenu on Mac OS X with Qt build against Cocoa
     1348
     1349    QMenu can be inserted only once in a menu/menubar. Subsequent insertions will
     1350    have no effect or will result in a disabled menu item.
     1351
    13051352    See the \l{mainwindows/menus}{Menus} example for an example of how
    13061353    to use QMenuBar and QMenu in your application.
     
    13601407{
    13611408    Q_D(QMenu);
    1362     for (QHash<QAction *, QWidget *>::ConstIterator item = d->widgetItems.constBegin(),
    1363          end = d->widgetItems.constEnd(); item != end; ++item) {
    1364         QWidgetAction *action = static_cast<QWidgetAction *>(item.key());
    1365         QWidget *widget = item.value();
    1366         if (action && widget)
     1409    QHash<QAction *, QWidget *>::iterator it = d->widgetItems.begin();
     1410    for (; it != d->widgetItems.end(); ++it) {
     1411        if (QWidget *widget = it.value()) {
     1412            QWidgetAction *action = static_cast<QWidgetAction *>(it.key());
    13671413            action->releaseWidget(widget);
    1368     }
    1369     d->widgetItems.clear();
     1414            *it = 0;
     1415        }
     1416    }
    13701417
    13711418    if (d->eventLoop)
    13721419        d->eventLoop->exit();
    1373     if (d->tornPopup)
    1374         d->tornPopup->close();
     1420    hideTearOffMenu();
    13751421}
    13761422
     
    15831629    if (d->tearoff == b)
    15841630        return;
    1585     if (!b && d->tornPopup)
    1586         d->tornPopup->close();
     1631    if (!b)
     1632        hideTearOffMenu();
    15871633    d->tearoff = b;
    15881634
     
    16191665void QMenu::hideTearOffMenu()
    16201666{
    1621     if (d_func()->tornPopup)
    1622         d_func()->tornPopup->close();
     1667    if (QWidget *w = d_func()->tornPopup)
     1668        w->close();
    16231669}
    16241670
     
    17181764{
    17191765    Q_D(const QMenu);
    1720     ensurePolished();
    1721     QMap<QAction*, QRect> actionRects;
    1722     QList<QAction*> actionList;
    1723     d->calcActionRects(actionRects, actionList);
     1766    d->updateActionRects();
    17241767
    17251768    QSize s;
    1726     QStyleOption opt(0);
    1727     opt.rect = rect();
    1728     opt.palette = palette();
    1729     opt.state = QStyle::State_None;
    1730     for (QMap<QAction*, QRect>::const_iterator i = actionRects.constBegin();
    1731          i != actionRects.constEnd(); ++i) {
    1732         if (i.value().bottom() > s.height())
    1733             s.setHeight(i.value().y()+i.value().height());
    1734         if (i.value().right() > s.width())
    1735             s.setWidth(i.value().right());
    1736     }
    1737     if (d->tearoff)
    1738         s.rheight() += style()->pixelMetric(QStyle::PM_MenuTearoffHeight, &opt, this);
    1739     if (const int fw = style()->pixelMetric(QStyle::PM_MenuPanelWidth, &opt, this)) {
    1740         s.rwidth() += fw*2;
    1741         s.rheight() += fw*2;
     1769    for (int i = 0; i < d->actionRects.count(); ++i) {
     1770        const QRect &rect = d->actionRects.at(i);
     1771        if (rect.isNull())
     1772            continue;
     1773        if (rect.bottom() >= s.height())
     1774            s.setHeight(rect.y() + rect.height());
     1775        if (rect.right() >= s.width())
     1776            s.setWidth(rect.x() + rect.width());
    17421777    }
    17431778    // Note that the action rects calculated above already include
    17441779    // the top and left margins, so we only need to add margins for
    17451780    // the bottom and right.
    1746     s.rwidth() += style()->pixelMetric(QStyle::PM_MenuHMargin, &opt, this);
    1747     s.rheight() += style()->pixelMetric(QStyle::PM_MenuVMargin, &opt, this);
    1748 
    1749     s += QSize(d->leftmargin + d->rightmargin, d->topmargin + d->bottommargin);
     1781    QStyleOption opt(0);
     1782    opt.init(this);
     1783    const int fw = style()->pixelMetric(QStyle::PM_MenuPanelWidth, &opt, this);
     1784    s.rwidth() += style()->pixelMetric(QStyle::PM_MenuHMargin, &opt, this) + fw + d->rightmargin;
     1785    s.rheight() += style()->pixelMetric(QStyle::PM_MenuVMargin, &opt, this) + fw + d->bottommargin;
    17501786
    17511787    return style()->sizeFromContents(QStyle::CT_Menu, &opt,
     
    17771813    d->motions = 0;
    17781814    d->doChildEffects = true;
     1815    d->updateLayoutDirection();
    17791816
    17801817#ifndef QT_NO_MENUBAR
    17811818    // if this menu is part of a chain attached to a QMenuBar, set the
    17821819    // _NET_WM_WINDOW_TYPE_DROPDOWN_MENU X11 window type
    1783     QWidget* top = this;
    1784     while (QMenu* m = qobject_cast<QMenu *>(top))
    1785         top = m->d_func()->causedPopup.widget;
    1786     setAttribute(Qt::WA_X11NetWmWindowTypeDropDownMenu, qobject_cast<QMenuBar *>(top) != 0);
     1820    setAttribute(Qt::WA_X11NetWmWindowTypeDropDownMenu, qobject_cast<QMenuBar *>(d->topCausedWidget()) != 0);
    17871821#endif
    17881822
    17891823    ensurePolished(); // Get the right font
    17901824    emit aboutToShow();
    1791     d->updateActions();
    1792     QPoint pos = p;
     1825    const bool actionListChanged = d->itemsDirty;
     1826    d->updateActionRects();
     1827    QPoint pos;
     1828    QPushButton *causedButton = qobject_cast<QPushButton*>(d->causedPopup.widget);
     1829    if (actionListChanged && causedButton)
     1830        pos = QPushButtonPrivate::get(causedButton)->adjustedMenuPosition();
     1831    else
     1832        pos = p;
     1833
    17931834    QSize size = sizeHint();
    1794     QRect screen = d->popupGeometry(QApplication::desktop()->screenNumber(p));
     1835    QRect screen;
     1836#ifndef QT_NO_GRAPHICSVIEW
     1837    bool isEmbedded = d->nearestGraphicsProxyWidget(this);
     1838    if (isEmbedded)
     1839        screen = d->popupGeometry(this);
     1840    else
     1841#endif
     1842    screen = d->popupGeometry(QApplication::desktop()->screenNumber(p));
     1843
    17951844    const int desktopFrame = style()->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, 0, this);
    17961845    bool adjustToDesktop = !window()->testAttribute(Qt::WA_DontShowOnScreen);
     1846#ifdef QT_KEYPAD_NAVIGATION
     1847    if (!atAction && QApplication::keypadNavigationEnabled()) {
     1848        // Try to have one item activated
     1849        if (d->defaultAction && d->defaultAction->isEnabled()) {
     1850            atAction = d->defaultAction;
     1851            // TODO: This works for first level menus, not yet sub menus
     1852        } else {
     1853            foreach (QAction *action, d->actions)
     1854                if (action->isEnabled()) {
     1855                    atAction = action;
     1856                    break;
     1857                }
     1858        }
     1859        d->currentAction = atAction;
     1860    }
     1861#endif
    17971862    if (d->ncols > 1) {
    17981863        pos.setY(screen.top()+desktopFrame);
    17991864    } else if (atAction) {
    1800         for(int i=0, above_height=0; i<(int)d->actionList.count(); i++) {
    1801             QAction *action = d->actionList.at(i);
     1865        for(int i = 0, above_height = 0; i < d->actions.count(); i++) {
     1866            QAction *action = d->actions.at(i);
    18021867            if (action == atAction) {
    1803                 int newY = pos.y()-above_height;
     1868                int newY = pos.y() - above_height;
    18041869                if (d->scroll && newY < desktopFrame) {
    18051870                    d->scroll->scrollFlags = d->scroll->scrollFlags
     
    18131878                    && !style()->styleHint(QStyle::SH_Menu_FillScreenWithScroll, 0, this)) {
    18141879                    int below_height = above_height + d->scroll->scrollOffset;
    1815                     for(int i2 = i; i2 < (int)d->actionList.count(); i2++)
    1816                         below_height += d->actionRects.value(d->actionList.at(i2)).height();
     1880                    for(int i2 = i; i2 < d->actionRects.count(); i2++)
     1881                        below_height += d->actionRects.at(i2).height();
    18171882                    size.setHeight(below_height);
    18181883                }
    18191884                break;
    18201885            } else {
    1821                 above_height += d->actionRects.value(action).height();
     1886                above_height += d->actionRects.at(i).height();
    18221887            }
    18231888        }
     
    18301895    if (adjustToDesktop) {
    18311896        //handle popup falling "off screen"
    1832         if (qApp->layoutDirection() == Qt::RightToLeft) {
     1897        if (isRightToLeft()) {
    18331898            if(snapToMouse) //position flowing left from the mouse
    18341899                pos.setX(mouse.x()-size.width());
     1900
     1901#ifndef QT_NO_MENUBAR
     1902            //if in a menubar, it should be right-aligned
     1903            if (qobject_cast<QMenuBar*>(d->causedPopup.widget))
     1904                pos.rx() -= size.width();
     1905#endif //QT_NO_MENUBAR
    18351906
    18361907            if (pos.x() < screen.left()+desktopFrame)
     
    18401911        } else {
    18411912            if (pos.x()+size.width()-1 > screen.right()-desktopFrame)
    1842                 pos.setX(qMin(p.x()+size.width(), screen.right()-desktopFrame-size.width()+1));
     1913                pos.setX(screen.right()-desktopFrame-size.width()+1);
    18431914            if (pos.x() < screen.left()+desktopFrame)
    1844                 pos.setX(qMax(p.x(), screen.left() + desktopFrame));
     1915                pos.setX(screen.left() + desktopFrame);
    18451916        }
    18461917        if (pos.y() + size.height() - 1 > screen.bottom() - desktopFrame) {
     
    18681939    setGeometry(QRect(pos, size));
    18691940#ifndef QT_NO_EFFECTS
    1870     int hGuess = qApp->layoutDirection() == Qt::RightToLeft ? QEffects::LeftScroll : QEffects::RightScroll;
     1941    int hGuess = isRightToLeft() ? QEffects::LeftScroll : QEffects::RightScroll;
    18711942    int vGuess = QEffects::DownScroll;
    1872     if (qApp->layoutDirection() == Qt::RightToLeft) {
     1943    if (isRightToLeft()) {
    18731944        if ((snapToMouse && (pos.x() + size.width()/2 > mouse.x())) ||
    18741945           (qobject_cast<QMenu*>(d->causedPopup.widget) && pos.x() + size.width()/2 > d->causedPopup.widget->x()))
     
    20262097{
    20272098    QMenu menu(parent);
    2028     for(QList<QAction*>::ConstIterator it = actions.constBegin(); it != actions.constEnd(); ++it)
    2029         menu.addAction((*it));
     2099    menu.addActions(actions);
    20302100    return menu.exec(pos, at);
    20312101}
     
    20772147    d->causedPopup.widget = 0;
    20782148    d->causedPopup.action = 0;
     2149    if (d->scroll)
     2150        d->scroll->scrollTimer.stop(); //make sure the timer stops
    20792151}
    20802152
     
    20852157{
    20862158    Q_D(QMenu);
     2159    d->updateActionRects();
    20872160    QPainter p(this);
    20882161    QRegion emptyArea = QRegion(rect());
     
    20972170
    20982171    //draw the items that need updating..
    2099     for (int i = 0; i < d->actionList.count(); ++i) {
    2100         QAction *action = d->actionList.at(i);
    2101         QRect adjustedActionRect = d->actionRect(action);
     2172    for (int i = 0; i < d->actions.count(); ++i) {
     2173        QAction *action = d->actions.at(i);
     2174        QRect adjustedActionRect = d->actionRects.at(i);
    21022175        if (!e->rect().intersects(adjustedActionRect)
    21032176            || d->widgetItems.value(action))
     
    21172190    //draw the scroller regions..
    21182191    if (d->scroll) {
    2119         const int scrollerHeight = style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, this);
    21202192        menuOpt.menuItemType = QStyleOptionMenuItem::Scroller;
    21212193        menuOpt.state |= QStyle::State_Enabled;
    21222194        if (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp) {
    2123             menuOpt.rect.setRect(fw, fw, width() - (fw * 2), scrollerHeight);
     2195            menuOpt.rect.setRect(fw, fw, width() - (fw * 2), d->scrollerHeight());
    21242196            emptyArea -= QRegion(menuOpt.rect);
    21252197            p.setClipRect(menuOpt.rect);
     
    21272199        }
    21282200        if (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollDown) {
    2129             menuOpt.rect.setRect(fw, height() - scrollerHeight - fw, width() - (fw * 2),
    2130                                      scrollerHeight);
     2201            menuOpt.rect.setRect(fw, height() - d->scrollerHeight() - fw, width() - (fw * 2),
     2202                                     d->scrollerHeight());
    21312203            emptyArea -= QRegion(menuOpt.rect);
    21322204            menuOpt.state |= QStyle::State_DownArrow;
     
    21412213                             style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this));
    21422214        if (d->scroll && d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)
    2143             menuOpt.rect.translate(0, style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, this));
     2215            menuOpt.rect.translate(0, d->scrollerHeight());
    21442216        emptyArea -= QRegion(menuOpt.rect);
    21452217        p.setClipRect(menuOpt.rect);
     
    22352307            action->menu()->d_func()->setFirstActionActive();
    22362308        else {
    2237 #if defined(Q_WS_WIN) && !defined(QT_NO_MENUBAR)
     2309#if defined(Q_WS_WIN)
    22382310            //On Windows only context menus can be activated with the right button
    2239             bool isContextMenu = true;
    2240             const QWidget *cause = d->causedPopup.widget;
    2241             while (cause) {
    2242                 //if the popup was caused by either QMenuBar or a QToolButton, it is not a context menu
    2243                 if (qobject_cast<const QMenuBar *>(cause) || qobject_cast<const QToolButton *>(cause)) {
    2244                     isContextMenu = false;
    2245                     break;
    2246                 } else if (const QMenu *menu = qobject_cast<const QMenu *>(cause)) {
    2247                     cause = menu->d_func()->causedPopup.widget;
    2248                 } else {
    2249                     break;
    2250                 }
    2251             }
    2252             if (e->button() == Qt::LeftButton || (e->button() == Qt::RightButton && isContextMenu))
     2311            if (e->button() == Qt::LeftButton || d->topCausedWidget() == 0)
    22532312#endif
    22542313                d->activateAction(action, QAction::Trigger);
     
    22992358    Q_D(QMenu);
    23002359    switch (e->type()) {
     2360    case QEvent::Polish:
     2361        d->updateLayoutDirection();
     2362        break;
    23012363    case QEvent::ShortcutOverride: {
    23022364            QKeyEvent *kev = static_cast<QKeyEvent*>(e);
     
    23312393        }
    23322394        d->itemsDirty = 1;
    2333         d->updateActions();
     2395        d->updateActionRects();
    23342396        break; }
    23352397    case QEvent::Show:
    23362398        d->mouseDown = 0;
    2337         d->updateActions();
     2399        d->updateActionRects();
    23382400        if (d->currentAction)
    23392401            d->popupAction(d->currentAction, 0, false);
     
    23712433{
    23722434    Q_D(QMenu);
     2435    d->updateActionRects();
    23732436    int key = e->key();
    23742437    if (isRightToLeft()) {  // in reverse mode open/close key for submenues are reversed
     
    24222485        if (!d->currentAction) {
    24232486            if(key == Qt::Key_Down) {
    2424                 for(int i = 0; i < d->actionList.size(); ++i) {
    2425                     QAction *act = d->actionList.at(i);
     2487                for(int i = 0; i < d->actions.count(); ++i) {
     2488                    QAction *act = d->actions.at(i);
     2489                    if (d->actionRects.at(i).isNull())
     2490                        continue;
    24262491                    if (!act->isSeparator() &&
    24272492                        (style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, this)
     
    24322497                }
    24332498            } else {
    2434                 for(int i = d->actionList.size()-1; i >= 0; --i) {
    2435                     QAction *act = d->actionList.at(i);
     2499                for(int i = d->actions.count()-1; i >= 0; --i) {
     2500                    QAction *act = d->actions.at(i);
     2501                    if (d->actionRects.at(i).isNull())
     2502                        continue;
    24362503                    if (!act->isSeparator() &&
    24372504                        (style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, this)
     
    24432510            }
    24442511        } else {
    2445             for(int i=0, y=0; !nextAction && i < (int)d->actionList.count(); i++) {
    2446                 QAction *act = d->actionList.at(i);
     2512            for(int i = 0, y = 0; !nextAction && i < d->actions.count(); i++) {
     2513                QAction *act = d->actions.at(i);
    24472514                if (act == d->currentAction) {
    24482515                    if (key == Qt::Key_Up) {
     
    24532520                                if (d->scroll)
    24542521                                    scroll_loc = QMenuPrivate::QMenuScroller::ScrollBottom;
    2455                                 next_i = d->actionList.count()-1;
     2522                                next_i = d->actionRects.count()-1;
    24562523                            }
    2457                             QAction *next = d->actionList.at(next_i);
     2524                            QAction *next = d->actions.at(next_i);
    24582525                            if (next == d->currentAction)
    24592526                                break;
     2527                            if (d->actionRects.at(next_i).isNull())
     2528                                continue;
    24602529                            if (next->isSeparator() ||
    24612530                               (!next->isEnabled() &&
     
    24642533                            nextAction = next;
    24652534                            if (d->scroll && (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)) {
    2466                                 int topVisible = style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, this);
     2535                                int topVisible = d->scrollerHeight();
    24672536                                if (d->tearoff)
    24682537                                    topVisible += style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this);
    2469                                 if (((y + d->scroll->scrollOffset) - topVisible) <= d->actionRects.value(nextAction).height())
     2538                                if (((y + d->scroll->scrollOffset) - topVisible) <= d->actionRects.at(next_i).height())
    24702539                                    scroll_loc = QMenuPrivate::QMenuScroller::ScrollTop;
    24712540                            }
     
    24752544                            d->tearoffHighlighted = 1;
    24762545                    } else {
    2477                         y += d->actionRects.value(act).height();
     2546                        y += d->actionRects.at(i).height();
    24782547                        for(int next_i = i+1; true; next_i++) {
    2479                             if (next_i == d->actionList.count()) {
     2548                            if (next_i == d->actionRects.count()) {
    24802549                                if(!style()->styleHint(QStyle::SH_Menu_SelectionWrap, 0, this))
    24812550                                    break;
     
    24842553                                next_i = 0;
    24852554                            }
    2486                             QAction *next = d->actionList.at(next_i);
     2555                            QAction *next = d->actions.at(next_i);
    24872556                            if (next == d->currentAction)
    24882557                                break;
     2558                            if (d->actionRects.at(next_i).isNull())
     2559                                continue;
    24892560                            if (next->isSeparator() ||
    24902561                               (!next->isEnabled() &&
     
    24932564                            nextAction = next;
    24942565                            if (d->scroll && (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollDown)) {
    2495                                 const int scrollerHeight = style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, this);
    2496                                 int bottomVisible = height()-scrollerHeight;
     2566                                int bottomVisible = height() - d->scrollerHeight();
    24972567                                if (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)
    2498                                     bottomVisible -= scrollerHeight;
     2568                                    bottomVisible -= d->scrollerHeight();
    24992569                                if (d->tearoff)
    25002570                                    bottomVisible -= style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this);
    2501                                 if ((y + d->scroll->scrollOffset + d->actionRects.value(nextAction).height()) > bottomVisible)
     2571                                if ((y + d->scroll->scrollOffset + d->actionRects.at(next_i).height()) > bottomVisible)
    25022572                                    scroll_loc = QMenuPrivate::QMenuScroller::ScrollBottom;
    25032573                            }
     
    25072577                    break;
    25082578                }
    2509                 y += d->actionRects.value(act).height();
     2579                y += d->actionRects.at(i).height();
    25102580            }
    25112581        }
    25122582        if (nextAction) {
    25132583            if (d->scroll && scroll_loc != QMenuPrivate::QMenuScroller::ScrollStay) {
    2514                 if (d->scroll->scrollTimer)
    2515                     d->scroll->scrollTimer->stop();
     2584                d->scroll->scrollTimer.stop();
    25162585                d->scrollMenu(nextAction, scroll_loc);
    25172586            }
     
    25622631            d->hideMenu(this);
    25632632#ifndef QT_NO_MENUBAR
    2564             if (QMenuBar *mb = qobject_cast<QMenuBar*>(qApp->focusWidget())) {
     2633            if (QMenuBar *mb = qobject_cast<QMenuBar*>(QApplication::focusWidget())) {
    25652634                mb->d_func()->setKeyboardMode(false);
    25662635            }
     
    26352704                d->searchBufferTimer.start(2000, this);
    26362705                d->searchBuffer += e->text();
    2637                 for(int i = 0; i < d->actionList.size(); ++i) {
     2706                for(int i = 0; i < d->actions.size(); ++i) {
    26382707                    int match_count = 0;
    2639                     register QAction *act = d->actionList.at(i);
     2708                    if (d->actionRects.at(i).isNull())
     2709                        continue;
     2710                    QAction *act = d->actions.at(i);
    26402711                    const QString act_text = act->text();
    26412712                    for(int c = 0; c < d->searchBuffer.size(); ++c) {
     
    26542725                QAction *first = 0, *currentSelected = 0, *firstAfterCurrent = 0;
    26552726                QChar c = e->text().at(0).toUpper();
    2656                 for(int i = 0; i < d->actionList.size(); ++i) {
    2657                     register QAction *act = d->actionList.at(i);
     2727                for(int i = 0; i < d->actions.size(); ++i) {
     2728                    if (d->actionRects.at(i).isNull())
     2729                        continue;
     2730                    QAction *act = d->actions.at(i);
    26582731                    QKeySequence sequence = QKeySequence::mnemonic(act->text());
    26592732                    int key = sequence[0] & 0xffff;
     
    26902763        }
    26912764        if (!key_consumed) {
    2692             if (QWidget *caused = d->causedPopup.widget) {
    2693                 while(QMenu *m = qobject_cast<QMenu*>(caused))
    2694                     caused = m->d_func()->causedPopup.widget;
    26952765#ifndef QT_NO_MENUBAR
    2696                 if (QMenuBar *mb = qobject_cast<QMenuBar*>(caused)) {
    2697                     QAction *oldAct = mb->d_func()->currentAction;
    2698                     QApplication::sendEvent(mb, e);
    2699                     if (mb->d_func()->currentAction != oldAct)
    2700                         key_consumed = true;
    2701                 }
    2702 #endif
     2766            if (QMenuBar *mb = qobject_cast<QMenuBar*>(d->topCausedWidget())) {
     2767                QAction *oldAct = mb->d_func()->currentAction;
     2768                QApplication::sendEvent(mb, e);
     2769                if (mb->d_func()->currentAction != oldAct)
     2770                    key_consumed = true;
    27032771            }
     2772#endif
    27042773        }
    27052774
    27062775#ifdef Q_OS_WIN32
    27072776        if (key_consumed && (e->key() == Qt::Key_Control || e->key() == Qt::Key_Shift || e->key() == Qt::Key_Meta))
    2708             qApp->beep();
     2777            QApplication::beep();
    27092778#endif // Q_OS_WIN32
    27102779    }
     
    27262795    if (d->motions == 0) // ignore first mouse move event (see enterEvent())
    27272796        return;
    2728     d->hasHadMouse |= rect().contains(e->pos());
     2797    d->hasHadMouse = d->hasHadMouse || rect().contains(e->pos());
    27292798
    27302799    QAction *action = d->actionAt(e->pos());
    27312800    if (!action) {
    2732         if (d->hasHadMouse && !rect().contains(e->pos()))
     2801        if (d->hasHadMouse)
    27332802            d->setCurrentAction(0);
    27342803        return;
    2735     } else if(e->buttons() & (Qt::LeftButton | Qt::RightButton)) {
     2804    } else if(e->buttons()) {
    27362805        d->mouseDown = this;
    27372806    }
     
    27612830    if (!d->sloppyRegion.isEmpty())
    27622831        d->sloppyRegion = QRegion();
     2832    if (!d->activeMenu && d->currentAction)
     2833        setActiveAction(0);
    27632834}
    27642835
     
    27702841{
    27712842    Q_D(QMenu);
    2772     if (d->scroll && d->scroll->scrollTimer && d->scroll->scrollTimer->timerId() == e->timerId()) {
     2843    if (d->scroll && d->scroll->scrollTimer.timerId() == e->timerId()) {
    27732844        d->scrollMenu((QMenuPrivate::QMenuScroller::ScrollDirection)d->scroll->scrollDirection);
    27742845        if (d->scroll->scrollFlags == QMenuPrivate::QMenuScroller::ScrollNone)
    2775             d->scroll->scrollTimer->stop();
     2846            d->scroll->scrollTimer.stop();
    27762847    } else if(QMenuPrivate::menuDelayTimer.timerId() == e->timerId()) {
    27772848        QMenuPrivate::menuDelayTimer.stop();
     
    28002871            connect(e->action(), SIGNAL(hovered()), this, SLOT(_q_actionHovered()));
    28012872        }
    2802 
    28032873        if (QWidgetAction *wa = qobject_cast<QWidgetAction *>(e->action())) {
    28042874            QWidget *widget = wa->requestWidget(this);
     
    28072877        }
    28082878    } else if (e->type() == QEvent::ActionRemoved) {
    2809         d->actionRects.clear();
    2810         d->actionList.clear();
    28112879        e->action()->disconnect(this);
    28122880        if (e->action() == d->currentAction)
    28132881            d->currentAction = 0;
    28142882        if (QWidgetAction *wa = qobject_cast<QWidgetAction *>(e->action())) {
    2815             QWidget *widget = d->widgetItems.take(wa);
    2816             if (widget)
     2883            if (QWidget *widget = d->widgetItems.value(wa))
    28172884                wa->releaseWidget(widget);
    2818         } else {
    2819             // If this is called from the QAction destructor, the
    2820             // previous call to qobject_cast will fail because the
    2821             // QWidgetAction has been destroyed already. We need to
    2822             // remove it from the hash anyway or it might crash later
    2823             // the widget itself has been already destroyed in
    2824             // ~QWidgetAction
    2825             d->widgetItems.remove(e->action());
    2826         }
     2885        }
     2886        d->widgetItems.remove(e->action());
    28272887    }
    28282888
     
    28382898#endif
    28392899
    2840 #if defined(Q_OS_WINCE) && !defined(QT_NO_MENUBAR)
     2900#if defined(Q_WS_WINCE) && !defined(QT_NO_MENUBAR)
    28412901    if (!d->wce_menu)
    28422902        d->wce_menu = new QMenuPrivate::QWceMenuPrivate;
     
    28492909#endif
    28502910
     2911#ifdef Q_WS_S60
     2912    if (!d->symbian_menu)
     2913        d->symbian_menu = new QMenuPrivate::QSymbianMenuPrivate;
     2914    if (e->type() == QEvent::ActionAdded)
     2915        d->symbian_menu->addAction(e->action(), d->symbian_menu->findAction(e->before()));
     2916    else if (e->type() == QEvent::ActionRemoved)
     2917        d->symbian_menu->removeAction(e->action());
     2918    else if (e->type() == QEvent::ActionChanged)
     2919        d->symbian_menu->syncAction(e->action());
     2920#endif
    28512921    if (isVisible()) {
    2852         d->updateActions();
     2922        d->updateActionRects();
    28532923        resize(sizeHint());
    28542924        update();
     
    28962966    QMenu *caused = qobject_cast<QMenu*>(d->activeMenu->d_func()->causedPopup.widget);
    28972967
    2898     const QRect availGeometry(d->popupGeometry(QApplication::desktop()->screenNumber(caused)));
     2968    const QRect availGeometry(d->popupGeometry(caused));
    28992969    if (isRightToLeft()) {
    29002970        pos = leftPos;
     
    30283098{
    30293099    Q_D(QMenu);
     3100    if (d->collapsibleSeparators == collapse)
     3101        return;
     3102
    30303103    d->collapsibleSeparators = collapse;
    30313104    d->itemsDirty = 1;
    30323105    if (isVisible()) {
    3033         d->updateActions();
     3106        d->updateActionRects();
    30343107        update();
    30353108    }
     3109#ifdef Q_WS_MAC
     3110    if (d->mac_menu)
     3111        d->syncSeparatorsCollapsible(collapse);
     3112#endif
    30363113}
    30373114
     
    30903167QAction *QMenu::findActionForId(int id) const
    30913168{
    3092     QList<QAction *> list = actions();
    3093     for (int i = 0; i < list.size(); ++i) {
    3094         QAction *act = list.at(i);
     3169    Q_D(const QMenu);
     3170    for (int i = 0; i < d->actions.size(); ++i) {
     3171        QAction *act = d->actions.at(i);
    30953172        if (findIdForAction(act)== id)
    30963173            return act;
  • trunk/src/gui/widgets/qmenu.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    142142#endif
    143143
    144 #ifdef Q_OS_WINCE
     144#ifdef Q_WS_WINCE
    145145    HMENU wceMenu(bool create = false);
    146146#endif
    147 
    148147
    149148    bool separatorsCollapsible() const;
     
    175174    void initStyleOption(QStyleOptionMenuItem *option, const QAction *action) const;
    176175
    177 #ifdef Q_OS_WINCE
     176#ifdef Q_WS_WINCE
    178177    QAction* wceCommands(uint command);
    179178#endif
  • trunk/src/gui/widgets/qmenu_mac.mm

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    7272  QMenu globals
    7373 *****************************************************************************/
    74 bool qt_mac_no_native_menubar = false;
    7574bool qt_mac_no_menubar_merge = false;
    7675bool qt_mac_quit_menu_item_enabled = true;
     
    144143}
    145144
     145static quint32 constructModifierMask(quint32 accel_key)
     146{
     147    quint32 ret = 0;
     148    const bool dontSwap = qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta);
     149#ifndef QT_MAC_USE_COCOA
     150    if ((accel_key & Qt::ALT) == Qt::ALT)
     151        ret |= kMenuOptionModifier;
     152    if ((accel_key & Qt::SHIFT) == Qt::SHIFT)
     153        ret |= kMenuShiftModifier;
     154    if (dontSwap) {
     155        if ((accel_key & Qt::META) != Qt::META)
     156            ret |= kMenuNoCommandModifier;
     157        if ((accel_key & Qt::CTRL) == Qt::CTRL)
     158            ret |= kMenuControlModifier;
     159    } else {
     160        if ((accel_key & Qt::CTRL) != Qt::CTRL)
     161            ret |= kMenuNoCommandModifier;
     162        if ((accel_key & Qt::META) == Qt::META)
     163            ret |= kMenuControlModifier;
     164    }
     165#else
     166    if ((accel_key & Qt::CTRL) == Qt::CTRL)
     167        ret |= (dontSwap ? NSControlKeyMask : NSCommandKeyMask);
     168    if ((accel_key & Qt::META) == Qt::META)
     169        ret |= (dontSwap ? NSCommandKeyMask : NSControlKeyMask);
     170    if ((accel_key & Qt::ALT) == Qt::ALT)
     171        ret |= NSAlternateKeyMask;
     172    if ((accel_key & Qt::SHIFT) == Qt::SHIFT)
     173        ret |= NSShiftKeyMask;
     174#endif
     175    return ret;
     176}
     177
    146178static bool actualMenuItemVisibility(const QMenuBarPrivate::QMacMenuBarPrivate *mbp,
    147179                                     const QMacMenuAction *action)
     
    167199        GetMenuItemProperty(menu, 0, kMenuCreatorQt, kMenuPropertyMergeList,
    168200                            sizeof(list), 0, &list);
    169         if (!list && qt_mac_current_menubar.qmenubar) {
     201        if (!list && qt_mac_current_menubar.qmenubar && qt_mac_current_menubar.qmenubar->isNativeMenuBar()) {
    170202            MenuRef apple_menu = qt_mac_current_menubar.qmenubar->d_func()->mac_menubar->apple_menu;
    171203            GetMenuItemProperty(apple_menu, 0, kMenuCreatorQt, kMenuPropertyMergeList, sizeof(list), 0, &list);
     
    427459                        int merged = 0;
    428460                        const QMenuPrivate::QMacMenuPrivate *mac_menu = qmenu->d_func()->mac_menu;
    429                         for(int i = 0; i < mac_menu->actionItems.size(); ++i) {
     461                        const int ActionItemsCount = mac_menu->actionItems.size();
     462                        for(int i = 0; i < ActionItemsCount; ++i) {
    430463                            QMacMenuAction *action = mac_menu->actionItems.at(i);
    431464                            if (action->action->isSeparator()) {
     
    527560static void qt_mac_get_accel(quint32 accel_key, quint32 *modif, quint32 *key) {
    528561    if (modif) {
    529         *modif = 0;
    530         if ((accel_key & Qt::CTRL) != Qt::CTRL)
    531             *modif |= kMenuNoCommandModifier;
    532         if ((accel_key & Qt::META) == Qt::META)
    533             *modif |= kMenuControlModifier;
    534         if ((accel_key & Qt::ALT) == Qt::ALT)
    535             *modif |= kMenuOptionModifier;
    536         if ((accel_key & Qt::SHIFT) == Qt::SHIFT)
    537             *modif |= kMenuShiftModifier;
     562        *modif = constructModifierMask(accel_key);
    538563    }
    539564
     
    583608}
    584609
     610static inline void syncNSMenuItemEnabled(NSMenuItem *menuItem, bool enabled)
     611{
     612    [menuItem setEnabled:NO];
     613    [menuItem setEnabled:YES];
     614    [menuItem setEnabled:enabled];
     615}
     616
    585617static inline void syncMenuBarItemsVisiblity(const QMenuBarPrivate::QMacMenuBarPrivate *mac_menubar)
    586618{
     
    600632{
    601633    NSMenuItem *item = [[NSMenuItem alloc]
    602                          initWithTitle:reinterpret_cast<const NSString *>(static_cast<CFStringRef>(QCFString(title)))
     634                         initWithTitle:qt_mac_QStringToNSString(title)
    603635                         action:@selector(qtDispatcherToQAction:) keyEquivalent:@""];
    604636    [item setTarget:getMenuLoader()];
     
    635667                if ([item tag]) {
    636668                    QAction *action = reinterpret_cast<QAction *>([item tag]);
    637                     [item setEnabled:action->isEnabled()];
     669                     syncNSMenuItemEnabled(item, action->isEnabled());
    638670                 } else {
    639                      [item setEnabled:YES];
     671                     syncNSMenuItemEnabled(item, YES);
    640672                 }
    641673            } else {
    642                 [item setEnabled:NO];
     674                syncNSMenuItemEnabled(item, NO);
    643675            }
    644676        }
     
    704736void qt_mac_clear_menubar()
    705737{
     738    if (QApplication::testAttribute(Qt::AA_MacPluginApplication))
     739        return;
     740
    706741#ifndef QT_MAC_USE_COCOA
    707742    MenuRef clear_menu = 0;
     
    729764#ifdef QT_MAC_USE_COCOA
    730765    [menu release];
    731     [menuItem setTag:nil];
     766    // Update the menu item if this action still owns it. For some items
     767    // (like 'Quit') ownership will be transferred between all menu bars...
     768    if (action && action.data() == reinterpret_cast<QAction *>([menuItem tag])) {
     769        QAction::MenuRole role = action->menuRole();
     770        // Check if the item is owned by Qt, and should be hidden to keep it from causing
     771        // problems. Do it for everything but the quit menu item since that should always
     772        // be visible.
     773        if (role > QAction::ApplicationSpecificRole && role < QAction::QuitRole) {
     774            [menuItem setHidden:YES];
     775        } else if (role == QAction::TextHeuristicRole
     776                   && menuItem != [getMenuLoader() quitMenuItem]) {
     777            [menuItem setHidden:YES];
     778        }
     779        [menuItem setTag:nil];
     780    }
    732781    [menuItem release];
    733782#endif
     
    872921    }
    873922
    874     if ([ret tag] != 0)
    875         ret = 0; // already taken
    876923#endif
    877924    return ret;
     
    918965#ifndef QT_MAC_USE_COCOA
    919966    else if (action->command == kHICommandPreferences)
    920         ret = QKeySequence(Qt::CTRL+Qt::Key_Comma);
     967        ret = QKeySequence(QKeySequence::Preferences);
    921968    else if (action->command == kHICommandQuit)
    922         ret = QKeySequence(Qt::CTRL+Qt::Key_Q);
     969        ret = QKeySequence(QKeySequence::Quit);
    923970#else
    924971    else if (action->menuItem == [loader preferencesMenuItem])
    925         ret = QKeySequence(Qt::CTRL+Qt::Key_Comma);
     972        ret = QKeySequence(QKeySequence::Preferences);
    926973    else if (action->menuItem == [loader quitMenuItem])
    927         ret = QKeySequence(Qt::CTRL+Qt::Key_Q);
     974        ret = QKeySequence(QKeySequence::Quit);
    928975#endif
    929976    return ret;
     
    932979void Q_GUI_EXPORT qt_mac_set_menubar_icons(bool b)
    933980{ QApplication::instance()->setAttribute(Qt::AA_DontShowIconsInMenus, !b); }
    934 void Q_GUI_EXPORT qt_mac_set_native_menubar(bool b) { qt_mac_no_native_menubar = !b; }
     981void Q_GUI_EXPORT qt_mac_set_native_menubar(bool b)
     982{  QApplication::instance()->setAttribute(Qt::AA_DontUseNativeMenuBar, !b); }
    935983void Q_GUI_EXPORT qt_mac_set_menubar_merge(bool b) { qt_mac_no_menubar_merge = !b; }
    936984
     
    11321180            if (mergedItems.contains(action->command)
    11331181                 && (testattr & kMenuItemAttrSeparator)) {
    1134                     InsertMenuItemTextWithCFString(action->menu, 0, qMax(itemCount - 1, 0), attr, action->command);
    1135                     index = itemCount;
    1136                  } else {
    1137                     MenuItemIndex tmpIndex;
    1138                     AppendMenuItemTextWithCFString(action->menu, 0, attr, action->command, &tmpIndex);
    1139                     index = tmpIndex;
    1140                     if (mergedItems.contains(action->command))
    1141                         AppendMenuItemTextWithCFString(action->menu, 0, kMenuItemAttrSeparator, 0, &tmpIndex);
    1142                  }
     1182                InsertMenuItemTextWithCFString(action->menu, 0, qMax(itemCount - 1, 0), attr, action->command);
     1183                index = itemCount;
     1184            } else {
     1185                MenuItemIndex tmpIndex;
     1186                AppendMenuItemTextWithCFString(action->menu, 0, attr, action->command, &tmpIndex);
     1187                index = tmpIndex;
     1188                if (mergedItems.contains(action->command))
     1189                    AppendMenuItemTextWithCFString(action->menu, 0, kMenuItemAttrSeparator, 0, &tmpIndex);
     1190            }
    11431191#else
    11441192            [menu addItem:newItem];
     
    12091257{
    12101258    quint32 accel_key = (accel[0] & ~(Qt::MODIFIER_MASK | Qt::UNICODE_ACCEL));
    1211     unichar keyEquiv[1] = { 0 };
    1212     if (accel_key == Qt::Key_Return)
    1213         keyEquiv[0] = kReturnCharCode;
    1214     else if (accel_key == Qt::Key_Enter)
    1215         keyEquiv[0] = kEnterCharCode;
    1216     else if (accel_key == Qt::Key_Tab)
    1217         keyEquiv[0] = kTabCharCode;
    1218     else if (accel_key == Qt::Key_Backspace)
    1219         keyEquiv[0] = kBackspaceCharCode;
    1220     else if (accel_key == Qt::Key_Delete)
    1221         keyEquiv[0] = NSDeleteFunctionKey;
    1222     else if (accel_key == Qt::Key_Escape)
    1223         keyEquiv[0] = kEscapeCharCode;
    1224     else if (accel_key == Qt::Key_PageUp)
    1225         keyEquiv[0] = NSPageUpFunctionKey;
    1226     else if (accel_key == Qt::Key_PageDown)
    1227         keyEquiv[0] = NSPageDownFunctionKey;
    1228     else if (accel_key == Qt::Key_Up)
    1229         keyEquiv[0] = NSUpArrowFunctionKey;
    1230     else if (accel_key == Qt::Key_Down)
    1231         keyEquiv[0] = NSDownArrowFunctionKey;
    1232     else if (accel_key == Qt::Key_Left)
    1233         keyEquiv[0] = NSLeftArrowFunctionKey;
    1234     else if (accel_key == Qt::Key_Right)
    1235         keyEquiv[0] = NSRightArrowFunctionKey;
    1236     else if (accel_key == Qt::Key_CapsLock)
    1237         keyEquiv[0] = kMenuCapsLockGlyph;  // ### Cocoa has no equivalent
    1238     else if (accel_key >= Qt::Key_F1 && accel_key <= Qt::Key_F15)
    1239         keyEquiv[0] = (accel_key - Qt::Key_F1) + NSF1FunctionKey;
    1240     else if (accel_key == Qt::Key_Home)
    1241         keyEquiv[0] = NSHomeFunctionKey;
    1242     else if (accel_key == Qt::Key_End)
    1243         keyEquiv[0] = NSEndFunctionKey;
    1244     else
    1245         keyEquiv[0] = unichar(QChar(accel_key).toLower().unicode());
    1246     return [NSString stringWithCharacters:keyEquiv length:1];
     1259    extern QChar qt_macSymbolForQtKey(int key); // qkeysequence.cpp
     1260    QChar keyEquiv = qt_macSymbolForQtKey(accel_key);
     1261    if (keyEquiv.isNull()) {
     1262        if (accel_key >= Qt::Key_F1 && accel_key <= Qt::Key_F15)
     1263            keyEquiv = (accel_key - Qt::Key_F1) + NSF1FunctionKey;
     1264        else
     1265            keyEquiv = unichar(QChar(accel_key).toLower().unicode());
     1266    }
     1267    return [NSString stringWithCharacters:&keyEquiv.unicode() length:1];
    12471268}
    12481269
     
    12501271NSUInteger keySequenceModifierMask(const QKeySequence &accel)
    12511272{
    1252     NSUInteger ret = 0;
    1253     quint32 accel_key = accel[0];
    1254     if ((accel_key & Qt::CTRL) == Qt::CTRL)
    1255         ret |= NSCommandKeyMask;
    1256     if ((accel_key & Qt::META) == Qt::META)
    1257         ret |= NSControlKeyMask;
    1258     if ((accel_key & Qt::ALT) == Qt::ALT)
    1259         ret |= NSAlternateKeyMask;
    1260     if ((accel_key & Qt::SHIFT) == Qt::SHIFT)
    1261         ret |= NSShiftKeyMask;
    1262     return ret;
     1273    return constructModifierMask(accel[0]);
    12631274}
    12641275
     
    13401351        }
    13411352    }
     1353    // Show multiple key sequences as part of the menu text.
    13421354    if (accel.count() > 1)
    1343         text += QLatin1String(" (****)"); //just to denote a multi stroke shortcut
     1355        text += QLatin1String(" (") + accel.toString(QKeySequence::NativeText) + QLatin1String(")");
    13441356
    13451357    QString finalString = qt_mac_removeMnemonics(text);
     
    13621374            && action->action->isIconVisibleInMenu()) {
    13631375        data.iconType = kMenuIconRefType;
    1364         data.iconHandle = (Handle)qt_mac_create_iconref(action->action->icon().pixmap(22, QIcon::Normal));
     1376        data.iconHandle = (Handle)qt_mac_create_iconref(action->action->icon().pixmap(16, QIcon::Normal));
    13651377    } else {
    13661378        data.iconType = kMenuNoIcon;
     
    13821394    if (action->action->font().resolve()) {
    13831395        const QFont &actionFont = action->action->font();
    1384         NSFont *customMenuFont = [NSFont fontWithName:reinterpret_cast<const NSString *>(static_cast<CFStringRef>(QCFString(actionFont.family())))
     1396        NSFont *customMenuFont = [NSFont fontWithName:qt_mac_QStringToNSString(actionFont.family())
    13851397                                  size:actionFont.pointSize()];
    13861398        NSArray *keys = [NSArray arrayWithObjects:NSFontAttributeName, nil];
    13871399        NSArray *objects = [NSArray arrayWithObjects:customMenuFont, nil];
    13881400        NSDictionary *attributes = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
    1389         NSAttributedString *str = [[[NSAttributedString alloc] initWithString:reinterpret_cast<const NSString *>(static_cast<CFStringRef>(QCFString(finalString)))
     1401        NSAttributedString *str = [[[NSAttributedString alloc] initWithString:qt_mac_QStringToNSString(finalString)
    13901402                                 attributes:attributes] autorelease];
    13911403       [item setAttributedTitle: str];
    13921404    } else {
    1393         [item setTitle: reinterpret_cast<const NSString *>(static_cast<CFStringRef>(QCFString(finalString)))];
    1394     }
    1395     [item setTitle:reinterpret_cast<const NSString *>(static_cast<CFStringRef>(QCFString(qt_mac_removeMnemonics(text))))];
     1405        [item setTitle: qt_mac_QStringToNSString(finalString)];
     1406    }
     1407    [item setTitle:qt_mac_QStringToNSString(qt_mac_removeMnemonics(text))];
    13961408
    13971409    // Cocoa Enabled
     
    14011413    NSImage *nsimage = 0;
    14021414    if (!action->action->icon().isNull() && action->action->isIconVisibleInMenu()) {
    1403         nsimage = static_cast<NSImage *>(qt_mac_create_nsimage(action->action->icon().pixmap(22, QIcon::Normal)));
     1415        nsimage = static_cast<NSImage *>(qt_mac_create_nsimage(action->action->icon().pixmap(16, QIcon::Normal)));
    14041416    }
    14051417    [item setImage:nsimage];
     
    14151427        SetMenuItemProperty(data.submenuHandle, 0, kMenuCreatorQt, kMenuPropertyCausedQWidget, sizeof(caused), &caused);
    14161428#else
    1417         [item setSubmenu:static_cast<NSMenu *>(action->action->menu()->macMenu())];
     1429        NSMenu *subMenu  = static_cast<NSMenu *>(action->action->menu()->macMenu());
     1430        if ([subMenu supermenu] && [subMenu supermenu] != [item menu]) {
     1431            // The menu is already a sub-menu of another one. Cocoa will throw an exception,
     1432            // in such cases. For the time being, a new QMenu with same set of actions is the
     1433            // only workaround.
     1434            action->action->setEnabled(false);
     1435        } else {
     1436            [item setSubmenu:subMenu];
     1437        }
    14181438#endif
    14191439    } else { //respect some other items
     
    14231443        data.whichData |= kMenuItemDataCmdKeyModifiers;
    14241444        data.whichData |= kMenuItemDataCmdKeyGlyph;
    1425         if (!accel.isEmpty()) {
     1445        if (accel.count() == 1) {
    14261446            qt_mac_get_accel(accel[0], (quint32*)&data.cmdKeyModifiers, (quint32*)&data.cmdKeyGlyph);
    14271447            if (data.cmdKeyGlyph == 0)
     
    14301450#else
    14311451        [item setSubmenu:0];
    1432         if (!accel.isEmpty()) {
     1452        // No key equivalent set for multiple key QKeySequence.
     1453        if (accel.count() == 1) {
    14331454            [item setKeyEquivalent:keySequenceToKeyEqivalent(accel)];
    14341455            [item setKeyEquivalentModifierMask:keySequenceModifierMask(accel)];
     
    14781499#else
    14791500    QMacCocoaAutoReleasePool pool;
    1480     QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
    1481     if (action->menuItem == [loader quitMenuItem] || action->menuItem == [loader preferencesMenuItem])
    1482         [action->menuItem setEnabled:false];
    1483     else
     1501    if (action->merged) {
     1502        if (reinterpret_cast<QAction *>([action->menuItem tag]) == action->action) {
     1503            QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
     1504            [action->menuItem setEnabled:false];
     1505            if (action->menuItem != [loader quitMenuItem]
     1506                && action->menuItem != [loader preferencesMenuItem]) {
     1507                [[action->menuItem menu] removeItem:action->menuItem];
     1508            }
     1509        }
     1510    } else {
    14841511        [[action->menuItem menu] removeItem:action->menuItem];
     1512    }
    14851513#endif
    14861514    actionItems.removeAll(action);
     
    15071535    for(int i = 0; i < items.count(); i++)
    15081536        mac_menu->addAction(items[i], 0, this);
     1537    syncSeparatorsCollapsible(collapsibleSeparators);
    15091538    return mac_menu->menu;
    15101539}
     1540
     1541/*!
     1542  \internal
     1543*/
     1544void
     1545QMenuPrivate::syncSeparatorsCollapsible(bool collapse)
     1546{
     1547#ifndef QT_MAC_USE_COCOA
     1548    if (collapse)
     1549        ChangeMenuAttributes(mac_menu->menu, kMenuAttrCondenseSeparators, 0);
     1550    else
     1551        ChangeMenuAttributes(mac_menu->menu, 0, kMenuAttrCondenseSeparators);
     1552#else
     1553    qt_mac_menu_collapseSeparators(mac_menu->menu, collapse);
     1554#endif
     1555}
     1556
     1557
    15111558
    15121559/*!
     
    16741721            SetMenuItemProperty(submenu, 0, kMenuCreatorQt, kMenuPropertyCausedQWidget, sizeof(caused), &caused);
    16751722#else
    1676             [item setSubmenu:submenu];
     1723            if ([submenu supermenu] && [submenu supermenu] != [item menu])
     1724                return;
     1725            else
     1726                [item setSubmenu:submenu];
    16771727#endif
    16781728        }
     
    16951745#else
    16961746        [item setSubmenu: submenu];
    1697         [submenu setTitle:reinterpret_cast<const NSString *>(static_cast<CFStringRef>(QCFString(qt_mac_removeMnemonics(action->action->text()))))];
     1747        [submenu setTitle:qt_mac_QStringToNSString(qt_mac_removeMnemonics(action->action->text()))];
    16981748        syncNSMenuItemVisiblity(item, visible);
    16991749#endif
     
    17241774}
    17251775
     1776bool QMenuBarPrivate::macWidgetHasNativeMenubar(QWidget *widget)
     1777{
     1778    // This function is different from q->isNativeMenuBar(), as
     1779    // it returns true only if a native menu bar is actually
     1780    // _created_.
     1781    if (!widget)
     1782        return false;
     1783    return menubars()->contains(widget->window());
     1784}
     1785
    17261786void
    17271787QMenuBarPrivate::macCreateMenuBar(QWidget *parent)
    17281788{
    17291789    Q_Q(QMenuBar);
    1730     static int checkEnv = -1;
    1731     if (qt_mac_no_native_menubar == false && checkEnv < 0) {
    1732         checkEnv = !qgetenv("QT_MAC_NO_NATIVE_MENUBAR").isEmpty();
    1733         qt_mac_no_native_menubar = checkEnv;
    1734     }
    1735     if (!qt_mac_no_native_menubar) {
     1790    static int dontUseNativeMenuBar = -1;
     1791    // We call the isNativeMenuBar function here
     1792    // because that will make sure that local overrides
     1793    // are dealt with correctly. q->isNativeMenuBar() will, if not
     1794    // overridden, depend on the attribute Qt::AA_DontUseNativeMenuBar:
     1795    bool qt_mac_no_native_menubar = !q->isNativeMenuBar();
     1796    if (qt_mac_no_native_menubar == false && dontUseNativeMenuBar < 0) {
     1797        // The menubar is set to be native. Let's check (one time only
     1798        // for all menubars) if this is OK with the rest of the environment.
     1799        // As a result, Qt::AA_DontUseNativeMenuBar is set. NB: the application
     1800        // might still choose to not respect, or change, this flag.
     1801        bool isPlugin = QApplication::testAttribute(Qt::AA_MacPluginApplication);
     1802        bool environmentSaysNo = !qgetenv("QT_MAC_NO_NATIVE_MENUBAR").isEmpty();
     1803        dontUseNativeMenuBar = isPlugin || environmentSaysNo;
     1804        QApplication::instance()->setAttribute(Qt::AA_DontUseNativeMenuBar, dontUseNativeMenuBar);
     1805        qt_mac_no_native_menubar = !q->isNativeMenuBar();
     1806    }
     1807    if (qt_mac_no_native_menubar == false) {
     1808        // INVARIANT: Use native menubar.
    17361809        extern void qt_event_request_menubarupdate(); //qapplication_mac.cpp
    17371810        qt_event_request_menubarupdate();
     
    17661839{
    17671840    Q_Q(QMenuBar);
    1768     if (!mac_menubar) {
     1841    if (!q->isNativeMenuBar() || !mac_menubar) {
    17691842        return 0;
    17701843    } else if (!mac_menubar->menu) {
     
    17821855                SetMenuItemProperty(mac_menubar->apple_menu, 0, kMenuCreatorQt, kMenuPropertyQWidget, sizeof(q), &q);
    17831856#else
    1784                 [mac_menubar->apple_menu setTitle:reinterpret_cast<const NSString *>(static_cast<CFStringRef>(QCFString(QString(QChar(0x14)))))];
     1857                [mac_menubar->apple_menu setTitle:qt_mac_QStringToNSString(QString(QChar(0x14)))];
    17851858                NSMenuItem *apple_menuItem = [[NSMenuItem alloc] init];
    17861859                [apple_menuItem setSubmenu:mac_menubar->menu];
     
    18251898static bool qt_mac_is_ancestor(QWidget* possibleAncestor, QWidget *child)
    18261899{
     1900    if (!possibleAncestor)
     1901        return false;
     1902
    18271903    QWidget * current = child->parentWidget();
    18281904    while (current != 0) {
     
    18431919    if (modalWidget == 0 || menuBar == 0)
    18441920        return false;
    1845     const Qt::WindowModality modality = modalWidget->windowModality();
    1846     if (modality == Qt::ApplicationModal) {
    1847         return true;
    1848     } else if (modality == Qt::WindowModal) {
    1849         QWidget * parent = menuBar->parentWidget();
    1850 
    1851         // Special case for the global menu bar: It's not associated
    1852         // with a window so don't disable it.
    1853         if (parent == 0)
    1854             return false;
    1855 
    1856         // Disable menu entries in menu bars that belong to ancestors of
    1857         // the modal widget, leave entries in unrelated menu bars enabled.
    1858         return qt_mac_is_ancestor(parent, modalWidget);
    1859     }
    1860     return false; // modality == NonModal
     1921
     1922    // If there is an application modal window on
     1923    // screen, the entries of the menubar should be disabled:
     1924    QWidget *w = modalWidget;
     1925    while (w) {
     1926        if (w->isVisible() && w->windowModality() == Qt::ApplicationModal)
     1927            return true;
     1928        w = w->parentWidget();
     1929    }
     1930
     1931    // INVARIANT: modalWidget is window modal. Disable menu entries
     1932    // if the menu bar belongs to an ancestor of modalWidget:
     1933    return qt_mac_is_ancestor(menuBar->parentWidget(), modalWidget);
    18611934}
    18621935
     
    18871960bool QMenuBar::macUpdateMenuBar()
    18881961{
    1889     if (qt_mac_no_native_menubar) //nothing to be done..
    1890         return true;
    1891 
    18921962    cancelAllMenuTracking();
    18931963    QMenuBar *mb = 0;
     
    19231993    //now set it
    19241994    bool ret = false;
    1925     if (mb) {
     1995    if (mb && mb->isNativeMenuBar()) {
    19261996#ifdef QT_MAC_USE_COCOA
    19271997        QMacCocoaAutoReleasePool pool;
     
    19352005            [NSApp setMainMenu:menu];
    19362006            syncMenuBarItemsVisiblity(mb->d_func()->mac_menubar);
     2007
     2008            if (OSMenuRef tmpMerge = QMenuPrivate::mergeMenuHash.value(menu)) {
     2009                if (QMenuMergeList *mergeList
     2010                        = QMenuPrivate::mergeMenuItemsHash.value(tmpMerge)) {
     2011                    const int mergeListSize = mergeList->size();
     2012
     2013                    for (int i = 0; i < mergeListSize; ++i) {
     2014                        const QMenuMergeItem &mergeItem = mergeList->at(i);
     2015                        // Ideally we would call QMenuPrivate::syncAction, but that requires finding
     2016                        // the original QMen and likely doing more work than we need.
     2017                        // For example, enabled is handled below.
     2018                        [mergeItem.menuItem setTag:reinterpret_cast<long>(
     2019                                                    static_cast<QAction *>(mergeItem.action->action))];
     2020                        [mergeItem.menuItem setHidden:!(mergeItem.action->action->isVisible())];
     2021                    }
     2022                }
     2023            }
    19372024#endif
    19382025            QWidget *modalWidget = qApp->activeModalWidget();
     
    19442031        qt_mac_current_menubar.modal = QApplicationPrivate::modalState();
    19452032        ret = true;
    1946     } else if (qt_mac_current_menubar.qmenubar) {
     2033    } else if (qt_mac_current_menubar.qmenubar && qt_mac_current_menubar.qmenubar->isNativeMenuBar()) {
    19472034        const bool modal = QApplicationPrivate::modalState();
    19482035        if (modal != qt_mac_current_menubar.modal) {
  • trunk/src/gui/widgets/qmenu_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6262#include "private/qwidget_p.h"
    6363
     64#ifdef Q_WS_S60
     65class CEikMenuPane;
     66#define QT_SYMBIAN_FIRST_MENU_ITEM 32000
     67#define QT_SYMBIAN_LAST_MENU_ITEM 41999 // 10000 items ought to be enough for anybody...
     68#endif
    6469QT_BEGIN_NAMESPACE
    6570
    6671#ifndef QT_NO_MENU
     72
     73#ifdef Q_WS_S60
     74void qt_symbian_show_toplevel(CEikMenuPane* menuPane);
     75void qt_symbian_show_submenu(CEikMenuPane* menuPane, int id);
     76#endif // Q_WS_S60
    6777
    6878class QTornOffMenu;
     
    113123#endif
    114124
    115 #ifdef Q_OS_WINCE
     125#ifdef Q_WS_WINCE
    116126struct QWceMenuAction {
    117127    uint command;   
     
    121131};
    122132#endif
     133#ifdef Q_WS_S60
     134struct QSymbianMenuAction {
     135    uint command;
     136    int parent;
     137    CEikMenuPane* menuPane;
     138    QPointer<QAction> action;
     139    QSymbianMenuAction() : command(0) {}
     140};
     141#endif
    123142
    124143class QMenuPrivate : public QWidgetPrivate
     
    127146public:
    128147    QMenuPrivate() : itemsDirty(0), maxIconWidth(0), tabWidth(0), ncols(0),
    129                       collapsibleSeparators(true), hasHadMouse(0), aboutToHide(0), motions(0),
    130                       currentAction(0), scroll(0), eventLoop(0), tearoff(0), tornoff(0), tearoffHighlighted(0),
    131                       hasCheckableItems(0), sloppyAction(0)
     148                      collapsibleSeparators(true), activationRecursionGuard(false), hasHadMouse(0), aboutToHide(0), motions(0),
     149                      currentAction(0),
     150#ifdef QT_KEYPAD_NAVIGATION
     151                      selectAction(0),
     152                      cancelAction(0),
     153#endif
     154                      scroll(0), eventLoop(0), tearoff(0), tornoff(0), tearoffHighlighted(0),
     155                      hasCheckableItems(0), sloppyAction(0), doChildEffects(false)
    132156#ifdef Q_WS_MAC
    133157                      ,mac_menu(0)
    134158#endif
    135 #if defined(Q_OS_WINCE) && !defined(QT_NO_MENUBAR)
     159#if defined(Q_WS_WINCE) && !defined(QT_NO_MENUBAR)
    136160                      ,wce_menu(0)
     161#endif
     162#ifdef Q_WS_S60
     163                      ,symbian_menu(0)
    137164#endif
    138165#ifdef QT3_SUPPORT
     
    146173        delete mac_menu;
    147174#endif
    148 #if defined(Q_OS_WINCE) && !defined(QT_NO_MENUBAR)
     175#if defined(Q_WS_WINCE) && !defined(QT_NO_MENUBAR)
    149176        delete wce_menu;
    150177#endif
     178#ifdef Q_WS_S60
     179        delete symbian_menu;
     180#endif
     181
    151182    }
    152183    void init();
     184
     185    static QMenuPrivate *get(QMenu *m) { return m->d_func(); }
     186    int scrollerHeight() const;
    153187
    154188    //item calculations
     
    156190    mutable uint maxIconWidth, tabWidth;
    157191    QRect actionRect(QAction *) const;
    158     mutable QMap<QAction*, QRect> actionRects;
    159     mutable QList<QAction*> actionList;
     192
     193    mutable QVector<QRect> actionRects;
    160194    mutable QHash<QAction *, QWidget *> widgetItems;
    161     void calcActionRects(QMap<QAction*, QRect> &actionRects, QList<QAction*> &actionList) const;
    162     void updateActions();
    163     QRect popupGeometry(int screen=-1) const;
    164     QList<QAction *> filterActions(const QList<QAction *> &actions) const;
    165     uint ncols : 4; //4 bits is probably plenty
     195    void updateActionRects() const;
     196    QRect popupGeometry(const QWidget *widget) const;
     197    QRect popupGeometry(int screen = -1) const;
     198    mutable uint ncols : 4; //4 bits is probably plenty
    166199    uint collapsibleSeparators : 1;
    167200
    168     uint activationRecursionGuard : 1;
     201    bool activationRecursionGuard;
    169202
    170203    //selection
     
    175208    int motions;
    176209    QAction *currentAction;
     210#ifdef QT_KEYPAD_NAVIGATION
     211    QAction *selectAction;
     212    QAction *cancelAction;
     213#endif
    177214    static QBasicTimer menuDelayTimer;
    178215    enum SelectionReason {
     
    180217        SelectedFromElsewhere
    181218    };
     219    QWidget *topCausedWidget() const;
    182220    QAction *actionAt(QPoint p) const;
    183221    void setFirstActionActive();
     
    192230        uint scrollFlags : 2, scrollDirection : 2;
    193231        int scrollOffset;
    194         QBasicTimer *scrollTimer;
    195 
    196         QMenuScroller() : scrollFlags(ScrollNone), scrollDirection(ScrollNone), scrollOffset(0), scrollTimer(0) { }
    197         ~QMenuScroller() { delete scrollTimer; }
     232        QBasicTimer scrollTimer;
     233
     234        QMenuScroller() : scrollFlags(ScrollNone), scrollDirection(ScrollNone), scrollOffset(0) { }
     235        ~QMenuScroller() { }
    198236    } *scroll;
    199237    void scrollMenu(QMenuScroller::ScrollLocation location, bool active=false);
     
    209247    QBasicTimer searchBufferTimer;
    210248
    211     //passing of mouse events up the parent heirarchy
     249    //passing of mouse events up the parent hierarchy
    212250    QPointer<QMenu> activeMenu;
    213251    bool mouseEventTaken(QMouseEvent *);
     
    221259    QMenuCaused causedPopup;
    222260    void hideUpToMenuBar();
    223     void hideMenu(QMenu *menu);
     261    void hideMenu(QMenu *menu, bool justRegister = false);
    224262
    225263    //index mappings
     
    235273    //sloppy selection
    236274    static QBasicTimer sloppyDelayTimer;
    237     QAction *sloppyAction;
     275    mutable QAction *sloppyAction;
    238276    QRegion sloppyRegion;
    239277
     
    255293
    256294    bool hasMouseMoved(const QPoint &globalPos);
     295
     296    void updateLayoutDirection();
     297
    257298
    258299    //menu fading/scrolling effects
     
    285326    OSMenuRef macMenu(OSMenuRef merge);
    286327    void setMacMenuEnabled(bool enable = true);
     328    void syncSeparatorsCollapsible(bool collapsible);
    287329    static QHash<OSMenuRef, OSMenuRef> mergeMenuHash;
    288330    static QHash<OSMenuRef, QMenuMergeList*> mergeMenuItemsHash;
     
    294336#endif
    295337
    296 #if defined(Q_OS_WINCE) && !defined(QT_NO_MENUBAR)
     338#if defined(Q_WS_WINCE) && !defined(QT_NO_MENUBAR)
    297339    struct QWceMenuPrivate {
    298340        QList<QWceMenuAction*> actionItems;
     
    319361    QAction* wceCommands(uint command);
    320362#endif
    321 
     363#if defined(Q_WS_S60)
     364    struct QSymbianMenuPrivate {
     365        QList<QSymbianMenuAction*> actionItems;
     366        QSymbianMenuPrivate();
     367        ~QSymbianMenuPrivate();
     368        void addAction(QAction *, QSymbianMenuAction* =0);
     369        void addAction(QSymbianMenuAction *, QSymbianMenuAction* =0);
     370        void syncAction(QSymbianMenuAction *);
     371        inline void syncAction(QAction *a) { syncAction(findAction(a)); }
     372        void removeAction(QSymbianMenuAction *);
     373        void rebuild(bool reCreate = false);
     374        inline void removeAction(QAction *a) { removeAction(findAction(a)); }
     375        inline QSymbianMenuAction *findAction(QAction *a) {
     376            for(int i = 0; i < actionItems.size(); i++) {
     377                QSymbianMenuAction *act = actionItems[i];
     378                if(a == act->action)
     379                    return act;
     380            }
     381            return 0;
     382        }
     383    } *symbian_menu;
     384#endif
    322385    QPointer<QWidget> noReplayFor;
    323386};
  • trunk/src/gui/widgets/qmenubar.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6868#include "qdebug.h"
    6969
    70 #ifdef Q_OS_WINCE
     70#ifdef Q_WS_WINCE
    7171extern bool qt_wince_is_mobile(); //defined in qguifunctions_wce.cpp
    7272#endif
     
    117117QAction *QMenuBarPrivate::actionAt(QPoint p) const
    118118{
    119     Q_Q(const QMenuBar);
    120     QList<QAction*> items = q->actions();
    121     for(int i = 0; i < items.size(); ++i) {
    122         if(actionRect(items.at(i)).contains(p))
    123             return items.at(i);
     119    for(int i = 0; i < actions.size(); ++i) {
     120        if(actionRect(actions.at(i)).contains(p))
     121            return actions.at(i);
    124122    }
    125123    return 0;
     
    135133
    136134    if (extVisible) {
    137         if (q->layoutDirection() == Qt::RightToLeft)
     135        if (q->isRightToLeft())
    138136            result.setLeft(result.left() + extension->sizeHint().width());
    139137        else
     
    143141    if (leftWidget && leftWidget->isVisible()) {
    144142        QSize sz = leftWidget->sizeHint();
    145         if (q->layoutDirection() == Qt::RightToLeft)
     143        if (q->isRightToLeft())
    146144            result.setRight(result.right() - sz.width());
    147145        else
     
    151149    if (rightWidget && rightWidget->isVisible()) {
    152150        QSize sz = rightWidget->sizeHint();
    153         if (q->layoutDirection() == Qt::RightToLeft)
     151        if (q->isRightToLeft())
    154152            result.setLeft(result.left() + sz.width());
    155153        else
     
    195193
    196194#ifdef Q_WS_MAC
    197     if(mac_menubar) {//nothing to see here folks, move along..
     195    if(q->isNativeMenuBar()) {//nothing to see here folks, move along..
    198196        itemsDirty = false;
    199197        return;
    200198    }
    201199#endif
    202     calcActionRects(q_width, q_start, actionRects, actionList);
    203     itemsWidth = q_width;
    204     itemsStart = q_start;
     200    calcActionRects(q_width, q_start);
    205201    currentAction = 0;
    206202#ifndef QT_NO_SHORTCUT
     
    209205            q->releaseShortcut(shortcutIndexMap.value(j));
    210206        shortcutIndexMap.resize(0); // faster than clear
    211         for(int i = 0; i < actionList.count(); i++)
    212             shortcutIndexMap.append(q->grabShortcut(QKeySequence::mnemonic(actionList.at(i)->text())));
     207        for(int i = 0; i < actions.count(); i++)
     208            shortcutIndexMap.append(q->grabShortcut(QKeySequence::mnemonic(actions.at(i)->text())));
    213209    }
    214210#endif
     
    221217    //we try to see if the actions will fit there
    222218    bool hasHiddenActions = false;
    223     foreach(QAction *action, actionList) {
    224         if (!menuRect.contains(actionRect(action))) {
     219    for (int i = 0; i < actions.count(); ++i) {
     220        const QRect &rect = actionRects.at(i);
     221        if (rect.isValid() && !menuRect.contains(rect)) {
    225222            hasHiddenActions = true;
    226223            break;
     
    231228    if (hasHiddenActions) {
    232229        menuRect = this->menuRect(true);
    233         foreach(QAction *action, actionList) {
    234             if (!menuRect.contains(actionRect(action))) {
    235                 hiddenActions.append(action);
     230        for (int i = 0; i < actions.count(); ++i) {
     231            const QRect &rect = actionRects.at(i);
     232            if (rect.isValid() && !menuRect.contains(rect)) {
     233                hiddenActions.append(actions.at(i));
    236234            }
    237235        }
     
    248246
    249247        int vmargin = q->style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, q);
    250         int x = q->layoutDirection() == Qt::RightToLeft
     248        int x = q->isRightToLeft()
    251249                ? menuRect.left() - extension->sizeHint().width() + 1
    252250                : menuRect.right();
     
    258256    q->updateGeometry();
    259257#ifdef QT3_SUPPORT
    260     if (q->parentWidget() != 0) {
     258    if (parent) {
    261259        QMenubarUpdatedEvent menubarUpdated(q);
    262         QApplication::sendEvent(q->parentWidget(), &menubarUpdated);
     260        QApplication::sendEvent(parent, &menubarUpdated);
    263261    }
    264262#endif
     
    268266{
    269267    Q_Q(const QMenuBar);
    270     QRect ret = actionRects.value(act);
    271     const int fw = q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q);
    272     ret.translate(fw, fw);
     268    const int index = actions.indexOf(act);
     269    if (index == -1)
     270        return QRect();
     271
     272    //makes sure the geometries are up-to-date
     273    const_cast<QMenuBarPrivate*>(this)->updateGeometries();
     274
     275    if (index >= actionRects.count())
     276        return QRect(); // that can happen in case of native menubar
     277
     278    QRect ret = actionRects.at(index);
    273279    return QStyle::visualRect(q->layoutDirection(), q->rect(), ret);
     280}
     281
     282void QMenuBarPrivate::focusFirstAction()
     283{
     284    if(!currentAction) {
     285        updateGeometries();
     286        int index = 0;
     287        while (index < actions.count() && actionRects.at(index).isNull()) ++index;
     288        if (index < actions.count())
     289            setCurrentAction(actions.at(index));
     290    }
    274291}
    275292
     
    283300    keyboardState = b;
    284301    if(b) {
    285         QWidget *fw = qApp->focusWidget();
     302        QWidget *fw = QApplication::focusWidget();
    286303        if (fw != q)
    287304            keyboardFocusWidget = fw;
    288         if(!currentAction && !actionList.isEmpty())
    289             setCurrentAction(actionList.first());
     305        focusFirstAction();
    290306        q->setFocus(Qt::MenuBarFocusReason);
    291307    } else {
     
    293309            setCurrentAction(0);
    294310        if(keyboardFocusWidget) {
    295             if (qApp->focusWidget() == q)
     311            if (QApplication::focusWidget() == q)
    296312                keyboardFocusWidget->setFocus(Qt::MenuBarFocusReason);
    297313            keyboardFocusWidget = 0;
     
    317333        QSize popup_size = activeMenu->sizeHint();
    318334
    319         QRect screenRect = QApplication::desktop()->screenGeometry(pos);
     335        //we put the popup menu on the screen containing the bottom-center of the action rect
     336        QRect screenRect = QApplication::desktop()->screenGeometry(pos + QPoint(adjustedActionRect.width() / 2, 0));
     337        pos = QPoint(qMax(pos.x(), screenRect.x()), qMax(pos.y(), screenRect.y()));
    320338
    321339        const bool fitUp = (q->mapToGlobal(adjustedActionRect.topLeft()).y() >= popup_size.height());
    322340        const bool fitDown = (pos.y() + popup_size.height() <= screenRect.bottom());
     341        const bool rtl = q->isRightToLeft();
    323342        const int actionWidth = adjustedActionRect.width();
    324343
    325344        if (!fitUp && !fitDown) { //we should shift the menu
    326             bool shouldShiftToRight = !q->isRightToLeft();
    327             if (q->isRightToLeft() && popup_size.width() > pos.x())
     345            bool shouldShiftToRight = !rtl;
     346            if (rtl && popup_size.width() > pos.x())
    328347                shouldShiftToRight = true;
    329348            else if (actionWidth + popup_size.width() + pos.x() > screenRect.right())
    330349                shouldShiftToRight = false;
    331350
    332             if (shouldShiftToRight)
    333                 pos.rx() += actionWidth;
    334             else
    335                 pos.rx() -= popup_size.width();
    336         } else if (q->isRightToLeft()) {
    337             pos.setX(pos.x()-(popup_size.width() - actionWidth));
    338         }
    339 
    340         if(pos.x() < screenRect.x()) {
    341             pos.setX(screenRect.x());
    342         } else {
    343             const int off = pos.x()+popup_size.width() - screenRect.right();
    344             if(off > 0)
    345                 pos.setX(qMax(screenRect.x(), pos.x()-off));
    346 
     351            if (shouldShiftToRight) {
     352                pos.rx() += actionWidth + (rtl ? popup_size.width() : 0);
     353            } else {
     354                //shift to left
     355                if (!rtl)
     356                    pos.rx() -= popup_size.width();
     357            }
     358        } else if (rtl) {
     359            pos.rx() += actionWidth;
    347360        }
    348361
     
    399412}
    400413
    401 void QMenuBarPrivate::calcActionRects(int max_width, int start, QMap<QAction*, QRect> &actionRects, QList<QAction*> &actionList) const
     414void QMenuBarPrivate::calcActionRects(int max_width, int start) const
    402415{
    403416    Q_Q(const QMenuBar);
    404417
    405     if(!itemsDirty && itemsWidth == max_width && itemsStart == start) {
    406         actionRects = actionRects;
    407         actionList = actionList;
     418    if(!itemsDirty)
    408419        return;
    409     }
    410     actionRects.clear();
    411     actionList.clear();
    412     const int itemSpacing = q->style()->pixelMetric(QStyle::PM_MenuBarItemSpacing, 0, q);
     420
     421    //let's reinitialize the buffer
     422    actionRects.resize(actions.count());
     423    actionRects.fill(QRect());
     424
     425    const QStyle *style = q->style();
     426
     427    const int itemSpacing = style->pixelMetric(QStyle::PM_MenuBarItemSpacing, 0, q);
    413428    int max_item_height = 0, separator = -1, separator_start = 0, separator_len = 0;
    414     QList<QAction*> items = q->actions();
    415429
    416430    //calculate size
    417431    const QFontMetrics fm = q->fontMetrics();
    418     const int hmargin = q->style()->pixelMetric(QStyle::PM_MenuBarHMargin, 0, q),
    419               vmargin = q->style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, q),
    420                 icone = q->style()->pixelMetric(QStyle::PM_SmallIconSize, 0, q);
    421     for(int i = 0; i < items.count(); i++) {
    422         QAction *action = items.at(i);
     432    const int hmargin = style->pixelMetric(QStyle::PM_MenuBarHMargin, 0, q),
     433              vmargin = style->pixelMetric(QStyle::PM_MenuBarVMargin, 0, q),
     434                icone = style->pixelMetric(QStyle::PM_SmallIconSize, 0, q);
     435    for(int i = 0; i < actions.count(); i++) {
     436        QAction *action = actions.at(i);
    423437        if(!action->isVisible())
    424438            continue;
     
    428442        //calc what I think the size is..
    429443        if(action->isSeparator()) {
    430             if (q->style()->styleHint(QStyle::SH_DrawMenuBarSeparator, 0, q))
    431                 separator = actionRects.count();
     444            if (style->styleHint(QStyle::SH_DrawMenuBarSeparator, 0, q))
     445                separator = i;
    432446            continue; //we don't really position these!
    433447        } else {
    434             QString s = action->text();
    435             if(!s.isEmpty()) {
    436                 int w = fm.width(s);
    437                 w -= s.count(QLatin1Char('&')) * fm.width(QLatin1Char('&'));
    438                 w += s.count(QLatin1String("&&")) * fm.width(QLatin1Char('&'));
    439                 sz = QSize(w, fm.height());
    440             }
    441 
     448            const QString s = action->text();
    442449            QIcon is = action->icon();
    443             if (!is.isNull()) {
    444                 QSize is_sz = QSize(icone, icone);
    445                 if (is_sz.height() > sz.height())
    446                     sz.setHeight(is_sz.height());
    447                 if (is_sz.width() > sz.width())
    448                     sz.setWidth(is_sz.width());
    449             }
     450            // If an icon is set, only the icon is visible
     451            if (!is.isNull())
     452                sz = sz.expandedTo(QSize(icone, icone));
     453            else if (!s.isEmpty())
     454                sz = fm.size(Qt::TextShowMnemonic, s);
    450455        }
    451456
     
    457462        if(!sz.isEmpty()) {
    458463            { //update the separator state
    459                 int iWidth = sz.width();
    460                 iWidth += itemSpacing;
     464                int iWidth = sz.width() + itemSpacing;
    461465                if(separator == -1)
    462466                    separator_start += iWidth;
     
    467471            max_item_height = qMax(max_item_height, sz.height());
    468472            //append
    469             actionRects.insert(action, QRect(0, 0, sz.width(), sz.height()));
    470             actionList.append(action);
     473            actionRects[i] = QRect(0, 0, sz.width(), sz.height());
    471474        }
    472475    }
    473476
    474477    //calculate position
    475     int x = ((start == -1) ? hmargin : start) + itemSpacing;
    476     int y = vmargin;
    477     for(int i = 0; i < actionList.count(); i++) {
    478         QAction *action = actionList.at(i);
    479         QRect &rect = actionRects[action];
     478    const int fw = q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q);
     479    int x = fw + ((start == -1) ? hmargin : start) + itemSpacing;
     480    int y = fw + vmargin;
     481    for(int i = 0; i < actions.count(); i++) {
     482        QRect &rect = actionRects[i];
     483        if (rect.isNull())
     484            continue;
     485
    480486        //resize
    481487        rect.setHeight(max_item_height);
     
    533539#ifndef QT_NO_ACCESSIBILITY
    534540        if (QAccessible::isActive()) {
    535             QList<QAction*> actions = q->actions();
    536541            int actionIndex = actions.indexOf(action);
    537542            ++actionIndex;
     
    583588    \brief The QMenuBar class provides a horizontal menu bar.
    584589
    585     \ingroup application
    586     \mainclass
     590    \ingroup mainwindow-classes
    587591
    588592    A menu bar consists of a list of pull-down menu items. You add
     
    662666    \row \i about.*
    663667         \i Application Menu | About <application name>
    664          \i If this entry is not found no About item will appear in
    665             the Application Menu
     668         \i The application name is fetched from the \c {Info.plist} file
     669            (see note below). If this entry is not found no About item
     670            will appear in the Application Menu.
    666671    \row \i config, options, setup, settings or preferences
    667672         \i Application Menu | Preferences
     
    707712
    708713    The \l{mainwindows/menus}{Menus} example shows how to use QMenuBar
    709     and QMenu.  The other \l{Qt Examples#Main Windows}{main window
     714    and QMenu.  The other \l{Main Window Examples}{main window
    710715    application examples} also provide menus using these classes.
    711716
    712717    \sa QMenu, QShortcut, QAction,
    713         {http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/index.html}{Introduction to Apple Human Interface Guidelines},
     718        {http://developer.apple.com/documentation/UserExperience/Conceptual/AppleHIGuidelines/XHIGIntro/XHIGIntro.html}{Introduction to Apple Human Interface Guidelines},
    714719        {fowler}{GUI Design Handbook: Menu Bar}, {Menus Example}
    715720*/
     
    726731        q->hide();
    727732#endif
    728 #ifdef Q_OS_WINCE
     733#ifdef Q_WS_WINCE
    729734    if (qt_wince_is_mobile()) {
    730735        wceCreateMenuBar(q->parentWidget());
     
    732737            q->hide();
    733738    }
    734 #endif
     739    else {
     740        QApplication::setAttribute(Qt::AA_DontUseNativeMenuBar, true);
     741    }
     742#endif
     743#ifdef Q_WS_S60
     744    symbianCreateMenuBar(q->parentWidget());
     745    if(symbian_menubar)
     746        q->hide();
     747#endif
     748
    735749    q->setBackgroundRole(QPalette::Button);
    736750    oldWindow = oldParent = 0;
     
    746760}
    747761
     762//Gets the next action for keyboard navigation
     763QAction *QMenuBarPrivate::getNextAction(const int _start, const int increment) const
     764{
     765    Q_Q(const QMenuBar);
     766    const_cast<QMenuBarPrivate*>(this)->updateGeometries();
     767    bool allowActiveAndDisabled = q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, q);
     768    const int start = (_start == -1 && increment == -1) ? actions.count() : _start;
     769    const int end =  increment == -1 ? 0 : actions.count() - 1;
     770
     771    for (int i = start; start != end;) {
     772        i += increment;
     773        QAction *current = actions.at(i);
     774        if (!actionRects.at(i).isNull() && (allowActiveAndDisabled || current->isEnabled()))
     775            return current;
     776    }
     777
     778    if (_start != -1) //let's try from the beginning or the end
     779        return getNextAction(-1, increment);
     780
     781    return 0;
     782}
     783
    748784/*!
    749785    Constructs a menu bar with parent \a parent.
     
    777813    d->macDestroyMenuBar();
    778814#endif
    779 #ifdef Q_OS_WINCE
     815#ifdef Q_WS_WINCE
    780816    Q_D(QMenuBar);
    781817    if (qt_wince_is_mobile())
    782818        d->wceDestroyMenuBar();
     819#endif
     820#ifdef Q_WS_S60
     821    Q_D(QMenuBar);
     822    d->symbianDestroyMenuBar();
    783823#endif
    784824}
     
    925965    Removes all the actions from the menu bar.
    926966
     967    \note On Mac OS X, menu items that have been merged to the system
     968    menu bar are not removed by this function. One way to handle this
     969    would be to remove the extra actions yourself. You can set the
     970    \l{QAction::MenuRole}{menu role} on the different menus, so that
     971    you know ahead of time which menu items get merged and which do
     972    not. Then decide what to recreate or remove yourself.
     973
    927974    \sa removeAction()
    928975*/
     
    9781025
    9791026    //draw the items
    980     for (int i = 0; i < d->actionList.count(); ++i) {
    981         QAction *action = d->actionList.at(i);
     1027    for (int i = 0; i < d->actions.count(); ++i) {
     1028        QAction *action = d->actions.at(i);
    9821029        QRect adjustedActionRect = d->actionRect(action);
    9831030        if (adjustedActionRect.isEmpty() || !d->isVisible(action))
     
    10261073void QMenuBar::setVisible(bool visible)
    10271074{
    1028 #ifdef Q_WS_MAC
    1029     Q_D(QMenuBar);
    1030     if(d->mac_menubar)
    1031         return;
    1032 #endif
    1033 #ifdef Q_OS_WINCE
    1034     Q_D(QMenuBar);
    1035     if(d->wce_menubar)
     1075#if defined(Q_WS_MAC) || defined(Q_OS_WINCE) || defined(Q_WS_S60)
     1076    if (isNativeMenuBar())
    10361077        return;
    10371078#endif
     
    10471088    if(e->button() != Qt::LeftButton)
    10481089        return;
     1090
     1091    d->mouseDown = true;
    10491092
    10501093    QAction *action = d->actionAt(e->pos());
     
    10571100        return;
    10581101    }
    1059 
    1060     d->mouseDown = true;
    10611102
    10621103    if(d->currentAction == action && d->popupState) {
     
    11011142{
    11021143    Q_D(QMenuBar);
     1144    d->updateGeometries();
    11031145    int key = e->key();
    11041146    if(isRightToLeft()) {  // in reverse mode open/close key for submenues are reversed
     
    11351177    case Qt::Key_Left: {
    11361178        if(d->currentAction) {
    1137             QAction *nextAction = 0;
    1138             bool allowActiveAndDisabled =
    1139                     style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, this);
    1140 
    1141             for(int i=0; i<(int)d->actionList.count(); i++) {
    1142                 if(d->actionList.at(i) == (QAction*)d->currentAction) {
    1143                     if (key == Qt::Key_Left) {
    1144                         while (i > 0) {
    1145                             i--;
    1146                             if (allowActiveAndDisabled || d->actionList[i]->isEnabled()) {
    1147                                 nextAction = d->actionList.at(i);
    1148                                 break;
    1149                             }
    1150                         }
    1151                     } else {
    1152                         while (i < d->actionList.count()-1) {
    1153                             i++;
    1154                             if (allowActiveAndDisabled || d->actionList[i]->isEnabled()) {
    1155                                 nextAction = d->actionList.at(i);
    1156                                 break;
    1157                             }
    1158                         }
    1159                     }
    1160                     break;
    1161 
    1162                 }
    1163             }
    1164 
    1165             if(!nextAction) {
    1166                 if (key == Qt::Key_Left) {
    1167                     for (int i = d->actionList.size() - 1 ; i >= 0 ; --i) {
    1168                         if (allowActiveAndDisabled || d->actionList[i]->isEnabled()) {
    1169                             nextAction = d->actionList.at(i);
    1170                             i--;
    1171                             break;
    1172                         }
    1173                     }
    1174                 } else {
    1175                     for (int i = 0 ; i < d->actionList.count() ; ++i) {
    1176                         if (allowActiveAndDisabled || d->actionList[i]->isEnabled()) {
    1177                             nextAction = d->actionList.at(i);
    1178                             i++;
    1179                             break;
    1180                         }
    1181                     }
    1182                 }
    1183             }
    1184             if(nextAction) {
     1179            int index = d->actions.indexOf(d->currentAction);
     1180            if (QAction *nextAction = d->getNextAction(index, key == Qt::Key_Left ? -1 : +1)) {
    11851181                d->setCurrentAction(nextAction, d->popupState, true);
    11861182                key_consumed = true;
     
    12061202        {
    12071203            QChar c = e->text()[0].toUpper();
    1208             for(int i = 0; i < d->actionList.size(); ++i) {
    1209                 register QAction *act = d->actionList.at(i);
     1204            for(int i = 0; i < d->actions.size(); ++i) {
     1205                if (d->actionRects.at(i).isNull())
     1206                    continue;
     1207                QAction *act = d->actions.at(i);
    12101208                QString s = act->text();
    12111209                if(!s.isEmpty()) {
     
    12491247{
    12501248    Q_D(QMenuBar);
    1251     d->mouseDown = e->buttons() & Qt::LeftButton;
     1249    if (!(e->buttons() & Qt::LeftButton))
     1250        d->mouseDown = false;
     1251    bool popupState = d->popupState || d->mouseDown;
    12521252    QAction *action = d->actionAt(e->pos());
    1253     bool popupState = d->popupState || d->mouseDown;
    12541253    if ((action && d->isVisible(action)) || !popupState)
    12551254        d->setCurrentAction(action, popupState);
     
    12621261{
    12631262    Q_D(QMenuBar);
    1264     if(!hasFocus() && !d->popupState)
     1263    if((!hasFocus() && !d->popupState) ||
     1264        (d->currentAction && d->currentAction->menu() == 0))
    12651265        d->setCurrentAction(0);
    12661266}
     
    12731273    Q_D(QMenuBar);
    12741274    d->itemsDirty = true;
     1275#if defined (Q_WS_MAC) || defined(Q_OS_WINCE) || defined(Q_WS_S60)
     1276    if (isNativeMenuBar()) {
    12751277#ifdef Q_WS_MAC
    1276     if(d->mac_menubar) {
     1278        QMenuBarPrivate::QMacMenuBarPrivate *nativeMenuBar = d->mac_menubar;
     1279#elif defined(Q_WS_S60)
     1280        QMenuBarPrivate::QSymbianMenuBarPrivate *nativeMenuBar = d->symbian_menubar;
     1281#else
     1282        QMenuBarPrivate::QWceMenuBarPrivate *nativeMenuBar = d->wce_menubar;
     1283#endif
     1284        if (!nativeMenuBar)
     1285            return;
    12771286        if(e->type() == QEvent::ActionAdded)
    1278             d->mac_menubar->addAction(e->action(), d->mac_menubar->findAction(e->before()));
     1287            nativeMenuBar->addAction(e->action(), nativeMenuBar->findAction(e->before()));
    12791288        else if(e->type() == QEvent::ActionRemoved)
    1280             d->mac_menubar->removeAction(e->action());
     1289            nativeMenuBar->removeAction(e->action());
    12811290        else if(e->type() == QEvent::ActionChanged)
    1282             d->mac_menubar->syncAction(e->action());
    1283     }
    1284 #endif
    1285 #ifdef Q_OS_WINCE
    1286     if(d->wce_menubar) {
    1287         if(e->type() == QEvent::ActionAdded)
    1288             d->wce_menubar->addAction(e->action(), d->wce_menubar->findAction(e->before()));
    1289         else if(e->type() == QEvent::ActionRemoved)
    1290             d->wce_menubar->removeAction(e->action());
    1291         else if(e->type() == QEvent::ActionChanged)
    1292             d->wce_menubar->syncAction(e->action());
    1293     }
    1294 #endif
     1291            nativeMenuBar->syncAction(e->action());
     1292    }
     1293#endif
     1294
    12951295    if(e->type() == QEvent::ActionAdded) {
    12961296        connect(e->action(), SIGNAL(triggered()), this, SLOT(_q_actionTriggered()));
     
    13111311{
    13121312    Q_D(QMenuBar);
    1313     if(d->keyboardState && !d->currentAction && !d->actionList.isEmpty())
    1314         d->setCurrentAction(d->actionList.first());
     1313    if(d->keyboardState)
     1314        d->focusFirstAction();
    13151315}
    13161316
     
    13711371
    13721372#ifdef Q_WS_MAC
    1373     macDestroyMenuBar();
    1374     macCreateMenuBar(newParent);
    1375 #endif
    1376 
    1377 #ifdef Q_OS_WINCE
     1373    if (q->isNativeMenuBar() && !macWidgetHasNativeMenubar(newParent)) {
     1374        // If the new parent got a native menubar from before, keep that
     1375        // menubar rather than replace it with this one (because a parents
     1376        // menubar has precedence over children menubars).
     1377        macDestroyMenuBar();
     1378        macCreateMenuBar(newParent);
     1379    }
     1380#endif
     1381
     1382#ifdef Q_WS_WINCE
    13781383    if (qt_wince_is_mobile() && wce_menubar)
    13791384        wce_menubar->rebuild();
    13801385#endif
     1386#ifdef Q_WS_S60
     1387    if (symbian_menubar)
     1388        symbian_menubar->rebuild();
     1389#endif
     1390
    13811391}
    13821392
     
    14801490    case QEvent::ShortcutOverride: {
    14811491        QKeyEvent *kev = static_cast<QKeyEvent*>(e);
    1482         if (kev->key() == Qt::Key_Escape) {
     1492        //we only filter out escape if there is a current action
     1493        if (kev->key() == Qt::Key_Escape && d->currentAction) {
    14831494            e->accept();
    14841495            return true;
     
    16131624{
    16141625    Q_D(const QMenuBar);
    1615 #ifdef Q_WS_MAC
    1616     const bool as_gui_menubar = !d->mac_menubar;
    1617 #elif defined (Q_OS_WINCE)
    1618     const bool as_gui_menubar = !d->wce_menubar;
     1626#if defined(Q_WS_MAC) || defined(Q_WS_WINCE) || defined(Q_WS_S60)
     1627    const bool as_gui_menubar = !isNativeMenuBar();
    16191628#else
    16201629    const bool as_gui_menubar = true;
     
    16231632    ensurePolished();
    16241633    QSize ret(0, 0);
     1634    const_cast<QMenuBarPrivate*>(d)->updateGeometries();
    16251635    const int hmargin = style()->pixelMetric(QStyle::PM_MenuBarHMargin, 0, this);
    16261636    const int vmargin = style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, this);
     
    16281638    int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, 0, this);
    16291639    if(as_gui_menubar) {
    1630         QMap<QAction*, QRect> actionRects;
    1631         QList<QAction*> actionList;
    16321640        int w = parentWidget() ? parentWidget()->width() : QApplication::desktop()->width();
    1633         d->calcActionRects(w - (2 * fw), 0, actionRects, actionList);
    1634         if (d->actionList.count() > 0) {
    1635             ret = d->actionRect(d->actionList.at(0)).size();
    1636             if (!d->extension->isHidden())
    1637                 ret += QSize(d->extension->sizeHint().width(), 0);
    1638         }
     1641        d->calcActionRects(w - (2 * fw), 0);
     1642        for (int i = 0; ret.isNull() && i < d->actions.count(); ++i)
     1643            ret = d->actionRects.at(i).size();
     1644        if (!d->extension->isHidden())
     1645            ret += QSize(d->extension->sizeHint().width(), 0);
    16391646        ret += QSize(2*fw + hmargin, 2*fw + vmargin);
    16401647    }
     
    16731680{
    16741681    Q_D(const QMenuBar);
    1675 #ifdef Q_WS_MAC
    1676     const bool as_gui_menubar = !d->mac_menubar;
    1677 #elif defined (Q_OS_WINCE)
    1678     const bool as_gui_menubar = !d->wce_menubar;
     1682#if defined(Q_WS_MAC) || defined(Q_WS_WINCE) || defined(Q_WS_S60)
     1683    const bool as_gui_menubar = !isNativeMenuBar();
    16791684#else
    16801685    const bool as_gui_menubar = true;
    16811686#endif
    16821687
     1688
    16831689    ensurePolished();
    16841690    QSize ret(0, 0);
     1691    const_cast<QMenuBarPrivate*>(d)->updateGeometries();
    16851692    const int hmargin = style()->pixelMetric(QStyle::PM_MenuBarHMargin, 0, this);
    16861693    const int vmargin = style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, this);
     
    16881695    int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, 0, this);
    16891696    if(as_gui_menubar) {
    1690         QMap<QAction*, QRect> actionRects;
    1691         QList<QAction*> actionList;
    16921697        const int w = parentWidget() ? parentWidget()->width() : QApplication::desktop()->width();
    1693         d->calcActionRects(w - (2 * fw), 0, actionRects, actionList);
    1694         for (QMap<QAction*, QRect>::const_iterator i = actionRects.constBegin();
    1695              i != actionRects.constEnd(); ++i) {
    1696             QRect actionRect(i.value());
    1697             if(actionRect.x() + actionRect.width() > ret.width())
    1698                 ret.setWidth(actionRect.x() + actionRect.width());
    1699             if(actionRect.y() + actionRect.height() > ret.height())
    1700                 ret.setHeight(actionRect.y() + actionRect.height());
    1701         }
    1702         ret += QSize(2*fw + 2*hmargin, 2*fw + 2*vmargin);
     1698        d->calcActionRects(w - (2 * fw), 0);
     1699        for (int i = 0; i < d->actionRects.count(); ++i) {
     1700            const QRect &actionRect = d->actionRects.at(i);
     1701            ret = ret.expandedTo(QSize(actionRect.x() + actionRect.width(), actionRect.y() + actionRect.height()));
     1702        }
     1703        //the action geometries already contain the top and left
     1704        //margins. So we only need to add those from right and bottom.
     1705        ret += QSize(fw + hmargin, fw + vmargin);
    17031706    }
    17041707    int margin = 2*vmargin + 2*fw + spaceBelowMenuBar;
     
    17361739{
    17371740    Q_D(const QMenuBar);
    1738 #ifdef Q_WS_MAC
    1739     const bool as_gui_menubar = !d->mac_menubar;
    1740 #elif defined (Q_OS_WINCE)
    1741     const bool as_gui_menubar = !d->wce_menubar;
     1741#if defined(Q_WS_MAC) || defined(Q_WS_WINCE) || defined(Q_WS_S60)
     1742    const bool as_gui_menubar = !isNativeMenuBar();
    17421743#else
    17431744    const bool as_gui_menubar = true;
    17441745#endif
     1746
     1747    const_cast<QMenuBarPrivate*>(d)->updateGeometries();
    17451748    int height = 0;
    17461749    const int vmargin = style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, this);
     
    17481751    int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, 0, this);
    17491752    if(as_gui_menubar) {
    1750         if (d->actionList.count()) {
    1751             // assume all actionrects have the same height
    1752             height = d->actionRect(d->actionList.first()).height();
     1753        for (int i = 0; i < d->actionRects.count(); ++i)
     1754            height = qMax(height, d->actionRects.at(i).height());
     1755        if (height) //there is at least one non-null item
    17531756            height += spaceBelowMenuBar;
    1754         }
    17551757        height += 2*fw;
    17561758        height += 2*vmargin;
     
    17791781{
    17801782    Q_Q(QMenuBar);
    1781     QAction *act = actionList.at(id);
     1783    QAction *act = actions.at(id);
    17821784    setCurrentAction(act, true, true);
    17831785    if (act && !act->menu()) {
     
    17851787        //100 is the same as the default value in QPushButton::animateClick
    17861788        autoReleaseTimer.start(100, q);
     1789    } else if (act && q->style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation, 0, q)) {
     1790        // When we open a menu using a shortcut, we should end up in keyboard state
     1791        setKeyboardMode(true);
    17871792    }
    17881793}
     
    18571862
    18581863/*!
     1864    \property QMenuBar::nativeMenuBar
     1865    \brief Whether or not a menubar will be used as a native menubar on platforms that support it
     1866    \since 4.6
     1867
     1868    This property specifies whether or not the menubar should be used as a native menubar on platforms
     1869    that support it. The currently supported platforms are Mac OS X and Windows CE. On these platforms
     1870    if this property is true, the menubar is used in the native menubar and is not in the window of
     1871    its parent, if false the menubar remains in the window. On other platforms the value of this
     1872    attribute has no effect.
     1873
     1874    The default is to follow whether the Qt::AA_DontUseNativeMenuBar attribute
     1875    is set for the application. Explicitly settings this property overrides
     1876    the presence (or abscence) of the attribute.
     1877*/
     1878
     1879void QMenuBar::setNativeMenuBar(bool nativeMenuBar)
     1880{
     1881    Q_D(QMenuBar);
     1882    if (d->nativeMenuBar == -1 || (nativeMenuBar != bool(d->nativeMenuBar))) {
     1883        d->nativeMenuBar = nativeMenuBar;
     1884#ifdef Q_WS_MAC
     1885        if (!d->nativeMenuBar) {
     1886            extern void qt_mac_clear_menubar();
     1887            qt_mac_clear_menubar();
     1888            d->macDestroyMenuBar();
     1889            const QList<QAction *> &menubarActions = actions();
     1890            for (int i = 0; i < menubarActions.size(); ++i) {
     1891                const QAction *action = menubarActions.at(i);
     1892                if (QMenu *menu = action->menu()) {
     1893                    delete menu->d_func()->mac_menu;
     1894                    menu->d_func()->mac_menu = 0;
     1895                }
     1896            }
     1897        } else {
     1898            d->macCreateMenuBar(parentWidget());
     1899        }
     1900        macUpdateMenuBar();
     1901        updateGeometry();
     1902        setVisible(false);
     1903        setVisible(true);
     1904#endif
     1905    }
     1906}
     1907
     1908bool QMenuBar::isNativeMenuBar() const
     1909{
     1910    Q_D(const QMenuBar);
     1911    if (d->nativeMenuBar == -1) {
     1912        return !QApplication::instance()->testAttribute(Qt::AA_DontUseNativeMenuBar);
     1913    }
     1914    return d->nativeMenuBar;
     1915}
     1916
     1917/*!
    18591918  \since 4.4
    18601919
     
    18701929*/
    18711930
    1872 #ifdef Q_OS_WINCE
     1931#ifdef Q_WS_WINCE
    18731932void QMenuBar::setDefaultAction(QAction *act)
    18741933{
     
    18761935    if (d->defaultAction == act)
    18771936        return;
    1878 #ifdef Q_OS_WINCE
     1937#ifdef Q_WS_WINCE
    18791938    if (qt_wince_is_mobile())
    18801939        if (d->defaultAction) {
    18811940            disconnect(d->defaultAction, SIGNAL(changed()), this, SLOT(_q_updateDefaultAction()));
    1882             disconnect(d->defaultAction, SIGNAL(destroyed ()), this, SLOT(_q_updateDefaultAction()));
     1941            disconnect(d->defaultAction, SIGNAL(destroyed()), this, SLOT(_q_updateDefaultAction()));
    18831942        }
    18841943#endif
    18851944    d->defaultAction = act;
    1886 #ifdef Q_OS_WINCE
     1945#ifdef Q_WS_WINCE
    18871946    if (qt_wince_is_mobile())
    18881947        if (d->defaultAction) {
     
    23802439/*!
    23812440    \fn int QMenuBar::margin() const
    2382     Returns the with of the the margin around the contents of the widget.
     2441    Returns the width of the margin around the contents of the widget.
    23832442
    23842443    Use QWidget::getContentsMargins() instead.
  • trunk/src/gui/widgets/qmenubar.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6565
    6666    Q_PROPERTY(bool defaultUp READ isDefaultUp WRITE setDefaultUp)
     67    Q_PROPERTY(bool nativeMenuBar READ isNativeMenuBar WRITE setNativeMenuBar)
    6768
    6869public:
     
    111112#endif
    112113
    113 #ifdef Q_OS_WINCE
     114#ifdef Q_WS_WINCE
    114115    void setDefaultAction(QAction *);
    115116    QAction *defaultAction() const;
     
    118119    static void wceRefresh();
    119120#endif
     121
     122    bool isNativeMenuBar() const;
     123    void setNativeMenuBar(bool nativeMenuBar);
    120124
    121125public Q_SLOTS:
     
    340344    Q_PRIVATE_SLOT(d_func(), void _q_updateLayout())
    341345
    342 #ifdef Q_OS_WINCE
     346#ifdef Q_WS_WINCE
    343347    Q_PRIVATE_SLOT(d_func(), void _q_updateDefaultAction())
    344348#endif
  • trunk/src/gui/widgets/qmenubar_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5858#include <private/qmenu_p.h> // Mac needs what in this file!
    5959
    60 #ifdef Q_OS_WINCE
     60#ifdef Q_WS_WINCE
    6161#include "qguifunctions_wince.h"
     62#endif
     63
     64#ifndef QT_NO_MENUBAR
     65#ifdef Q_WS_S60
     66class CCoeControl;
     67class CEikMenuBar;
     68#endif
    6269#endif
    6370
     
    7077    Q_DECLARE_PUBLIC(QMenuBar)
    7178public:
    72     QMenuBarPrivate() : itemsDirty(0), itemsWidth(0), itemsStart(-1), currentAction(0), mouseDown(0),
    73                          closePopupMode(0), defaultPopDown(1), popupState(0), keyboardState(0), altPressed(0)
     79    QMenuBarPrivate() : itemsDirty(0), currentAction(0), mouseDown(0),
     80                         closePopupMode(0), defaultPopDown(1), popupState(0), keyboardState(0), altPressed(0),
     81                         nativeMenuBar(-1), doChildEffects(false)
     82#ifdef QT3_SUPPORT
     83                         , doAutoResize(false)
     84#endif
    7485#ifdef Q_WS_MAC
    7586                         , mac_menubar(0)
    7687#endif
    7788
    78 #ifdef Q_OS_WINCE
     89#ifdef Q_WS_WINCE
    7990                         , wce_menubar(0), wceClassicMenu(false)
    8091#endif
    81     { }
     92#ifdef Q_WS_S60
     93                         , symbian_menubar(0)
     94#endif
     95
     96        { }
    8297    ~QMenuBarPrivate()
    8398        {
     
    85100            delete mac_menubar;
    86101#endif
    87 #ifdef Q_OS_WINCE
     102#ifdef Q_WS_WINCE
    88103            delete wce_menubar;
    89104#endif
     105#ifdef Q_WS_S60
     106            delete symbian_menubar;
     107#endif
    90108        }
    91109
    92110    void init();
    93     QStyleOptionMenuItem getStyleOption(const QAction *action) const;
     111    QAction *getNextAction(const int start, const int increment) const;
    94112
    95113    //item calculations
    96114    uint itemsDirty : 1;
    97     int itemsWidth, itemsStart;
    98115
    99116    QVector<int> shortcutIndexMap;
    100     mutable QMap<QAction*, QRect> actionRects;
    101     mutable QList<QAction*> actionList;
    102     void calcActionRects(int max_width, int start, QMap<QAction*, QRect> &actionRects, QList<QAction*> &actionList) const;
     117    mutable QVector<QRect> actionRects;
     118    void calcActionRects(int max_width, int start) const;
    103119    QRect actionRect(QAction *) const;
    104120    void updateGeometries();
     
    116132
    117133    //keyboard mode for keyboard navigation
     134    void focusFirstAction();
    118135    void setKeyboardMode(bool);
    119136    uint keyboardState : 1, altPressed : 1;
    120137    QPointer<QWidget> keyboardFocusWidget;
    121138
     139
     140    int nativeMenuBar : 3;  // Only has values -1, 0, and 1
    122141    //firing of events
    123142    void activateAction(QAction *, QAction::ActionEvent);
     
    128147    void _q_updateLayout();
    129148
    130 #ifdef Q_OS_WINCE
     149#ifdef Q_WS_WINCE
    131150    void _q_updateDefaultAction();
    132151#endif
     
    178197        }
    179198    } *mac_menubar;
     199    bool macWidgetHasNativeMenubar(QWidget *widget);
    180200    void macCreateMenuBar(QWidget *);
    181201    void macDestroyMenuBar();
    182202    OSMenuRef macMenu();
    183203#endif
    184 #ifdef Q_OS_WINCE
     204#ifdef Q_WS_WINCE
    185205    void wceCreateMenuBar(QWidget *);
    186206    void wceDestroyMenuBar();
     
    221241    bool wceEmitSignals(QList<QWceMenuAction*> actions, uint command);
    222242#endif
     243#ifdef Q_WS_S60
     244    void symbianCreateMenuBar(QWidget *);
     245    void symbianDestroyMenuBar();
     246    struct QSymbianMenuBarPrivate {
     247        QList<QSymbianMenuAction*> actionItems;
     248        QMenuBarPrivate *d;
     249        QSymbianMenuBarPrivate(QMenuBarPrivate *menubar);
     250        ~QSymbianMenuBarPrivate();
     251        void addAction(QAction *, QSymbianMenuAction* =0);
     252        void addAction(QSymbianMenuAction *, QSymbianMenuAction* =0);
     253        void syncAction(QSymbianMenuAction *);
     254        inline void syncAction(QAction *a) { syncAction(findAction(a)); }
     255        void removeAction(QSymbianMenuAction *);
     256        void rebuild();
     257        inline void removeAction(QAction *a) { removeAction(findAction(a)); }
     258        inline QSymbianMenuAction *findAction(QAction *a) {
     259            for(int i = 0; i < actionItems.size(); i++) {
     260                QSymbianMenuAction *act = actionItems[i];
     261                if(a == act->action)
     262                    return act;
     263            }
     264            return 0;
     265        }
     266        void insertNativeMenuItems(const QList<QAction*> &actions);
     267
     268    } *symbian_menubar;
     269    static int symbianCommands(int command);
     270
     271#endif
    223272};
    224273#endif
  • trunk/src/gui/widgets/qmenudata.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qmenudata.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6868    void setId(int);
    6969    void setSignalValue(int);
     70   
     71    Q_DISABLE_COPY(QMenuItem)
    7072};
    7173
  • trunk/src/gui/widgets/qplaintextedit.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6666#include <qtexttable.h>
    6767#include <qvariant.h>
    68 
    6968#include <qinputcontext.h>
    7069
     
    7271
    7372QT_BEGIN_NAMESPACE
     73
     74static inline bool shouldEnableInputMethod(QPlainTextEdit *plaintextedit)
     75{
     76    return !plaintextedit->isReadOnly();
     77}
    7478
    7579class QPlainTextDocumentLayoutPrivate : public QAbstractTextDocumentLayoutPrivate
     
    110114    \brief The QPlainTextDocumentLayout class implements a plain text layout for QTextDocument
    111115
    112     \ingroup text
    113 
     116    \ingroup richtext-processing
    114117
    115118   A QPlainTextDocumentLayout is required for text documents that can
     
    251254void QPlainTextDocumentLayout::requestUpdate()
    252255{
    253     emit update(QRectF(0., -4., 1000000000., 1000000000.));
     256    emit update(QRectF(0., -document()->documentMargin(), 1000000000., 1000000000.));
    254257}
    255258
     
    346349
    347350    if (!d->blockUpdate)
    348         emit update(); // optimization potential
    349 
     351        emit update(QRectF(0., -doc->documentMargin(), 1000000000., 1000000000.)); // optimization potential
    350352}
    351353
     
    356358    QTextDocument *doc = document();
    357359    qreal margin = doc->documentMargin();
    358     QFontMetrics fm(doc->defaultFont());
    359360    qreal blockMaximumWidth = 0;
    360361
    361     int leading = qMax(0, fm.leading());
    362362    qreal height = 0;
    363363    QTextLayout *tl = block.layout();
     
    371371    }
    372372    tl->beginLayout();
     373    qreal availableWidth = d->width;
     374    if (availableWidth <= 0) {
     375        availableWidth = qreal(INT_MAX); // similar to text edit with pageSize.width == 0
     376    }
     377    availableWidth -= 2*margin + extraMargin;
    373378    while (1) {
    374379        QTextLine line = tl->createLine();
    375380        if (!line.isValid())
    376381            break;
    377         line.setLineWidth(d->width - 2*margin - extraMargin);
    378 
    379         height += leading;
     382        line.setLeadingIncluded(true);
     383        line.setLineWidth(availableWidth);
    380384        line.setPosition(QPointF(margin, height));
    381385        height += line.height();
     
    440444{
    441445    pageUpDownLastCursorYIsValid = false;
    442 };
     446}
    443447
    444448void QPlainTextEditPrivate::_q_verticalScrollbarActionTriggered(int action) {
     
    508512    int currentBlockNumber = topBlock;
    509513    QTextBlock currentBlock = document()->findBlockByNumber(currentBlockNumber);
     514    if (!currentBlock.isValid())
     515        return -1;
     516
    510517    QPlainTextDocumentLayout *documentLayout = qobject_cast<QPlainTextDocumentLayout*>(document()->documentLayout());
    511518    Q_ASSERT(documentLayout);
     
    556563        return QRectF();
    557564    Q_ASSERT(currentBlock.blockNumber() == currentBlockNumber);
    558     QPlainTextDocumentLayout *documentLayout = qobject_cast<QPlainTextDocumentLayout*>(document()->documentLayout());
     565    QTextDocument *doc = document();
     566    QPlainTextDocumentLayout *documentLayout = qobject_cast<QPlainTextDocumentLayout*>(doc->documentLayout());
    559567    Q_ASSERT(documentLayout);
    560568
     
    563571        return QRectF();
    564572    QRectF r = documentLayout->blockBoundingRect(currentBlock);
    565     while (currentBlockNumber < blockNumber && offset.y() <= 2* textEdit->viewport()->height()) {
     573    int maxVerticalOffset = r.height();
     574    while (currentBlockNumber < blockNumber && offset.y() - maxVerticalOffset <= 2* textEdit->viewport()->height()) {
    566575        offset.ry() += r.height();
    567576        currentBlock = currentBlock.next();
    568577        ++currentBlockNumber;
     578        if (!currentBlock.isVisible()) {
     579            currentBlock = doc->findBlockByLineNumber(currentBlock.firstLineNumber());
     580            currentBlockNumber = currentBlock.blockNumber();
     581        }
    569582        r = documentLayout->blockBoundingRect(currentBlock);
    570583    }
    571     while (currentBlockNumber > blockNumber && offset.y() >= -textEdit->viewport()->height()) {
     584    while (currentBlockNumber > blockNumber && offset.y() + maxVerticalOffset >= -textEdit->viewport()->height()) {
    572585        currentBlock = currentBlock.previous();
     586        --currentBlockNumber;
     587        while (!currentBlock.isVisible()) {
     588            currentBlock = currentBlock.previous();
     589            --currentBlockNumber;
     590        }
    573591        if (!currentBlock.isValid())
    574592            break;
    575         --currentBlockNumber;
     593
    576594        r = documentLayout->blockBoundingRect(currentBlock);
    577595        offset.ry() -= r.height();
     
    625643    if (viewport->updatesEnabled() && viewport->isVisible()) {
    626644        int dy = 0;
    627         if (doc->findBlockByLineNumber(control->topBlock).isValid()) {
     645        if (doc->findBlockByNumber(control->topBlock).isValid()) {
    628646            dy = (int)(-q->blockBoundingGeometry(block).y())
    629647                 + verticalOffset() - verticalOffset(blockNumber, lineNumber);
     
    667685        qreal h = center ? line.naturalTextRect().center().y() : line.naturalTextRect().bottom();
    668686
     687        QTextBlock previousVisibleBlock = block;
    669688        while (h < height && block.previous().isValid()) {
    670             block = block.previous();
     689            previousVisibleBlock = block;
     690            do {
     691                block = block.previous();
     692            } while (!block.isVisible() && block.previous().isValid());
    671693            h += q->blockBoundingRect(block).height();
    672694        }
     
    682704        }
    683705
    684         if (block.next().isValid() && l >= lineCount) {
    685             block = block.next();
     706        if (l >= lineCount) {
     707            block = previousVisibleBlock;
    686708            l = 0;
    687709        }
     
    706728      lineWrap(QPlainTextEdit::WidgetWidth),
    707729      wordWrap(QTextOption::WrapAtWordBoundaryOrAnywhere),
    708       topLine(0), pageUpDownLastCursorYIsValid(false)
     730      clickCausedFocus(0),topLine(0),
     731      pageUpDownLastCursorYIsValid(false)
    709732{
    710733    showCursorOnInitialShow = true;
     
    743766    QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SIGNAL(cursorPositionChanged()));
    744767
     768    QObject::connect(control, SIGNAL(textChanged()), q, SLOT(updateMicroFocus()));
    745769
    746770    // set a null page size initially to avoid any relayouting until the textedit
    747771    // is shown. relayoutDocument() will take care of setting the page size to the
    748772    // viewport dimensions later.
    749     doc->setTextWidth(0);
     773    doc->setTextWidth(-1);
    750774    doc->documentLayout()->setPaintDevice(viewport);
    751775    doc->setDefaultFont(q->font());
     
    766790#ifndef QT_NO_CURSOR
    767791    viewport->setCursor(Qt::IBeamCursor);
     792#endif
     793    originalOffsetY = 0;
     794#ifdef Q_WS_WIN
     795    setSingleFingerPanEnabled(true);
    768796#endif
    769797}
     
    9861014    plain text.
    9871015
    988     \ingroup text
    989     \mainclass
     1016    \ingroup richtext-processing
     1017
    9901018
    9911019    \tableofcontents
     
    10001028    QTextEdit, but is optimized for plain text handling.
    10011029
    1002     QPlainTextEdit works on paragraphs and characters. A paragraph is a
    1003     formatted string which is word-wrapped to fit into the width of
     1030    QPlainTextEdit works on paragraphs and characters. A paragraph is
     1031    a formatted string which is word-wrapped to fit into the width of
    10041032    the widget. By default when reading plain text, one newline
    10051033    signifies a paragraph. A document consists of zero or more
    1006     paragraphs. The words in the paragraph are aligned in accordance
    1007     with the paragraph's alignment. Paragraphs are separated by hard
    1008     line breaks. Each character within a paragraph has its own
    1009     attributes, for example, font and color.
     1034    paragraphs. Paragraphs are separated by hard line breaks. Each
     1035    character within a paragraph has its own attributes, for example,
     1036    font and color.
    10101037
    10111038    The shape of the mouse cursor on a QPlainTextEdit is
     
    10151042    \section1 Using QPlainTextEdit as a Display Widget
    10161043
    1017     The text is set or replaced using setPlainText() which deletes any
    1018     existing text and replaces it with the text passed in the
    1019     setPlainText() call.
    1020 
    1021     Text itself can be inserted using the QTextCursor class or using
    1022     the convenience functins insertPlainText(), appendPlainText() or
     1044    The text is set or replaced using setPlainText() which deletes the
     1045    existing text and replaces it with the text passed to setPlainText().
     1046
     1047    Text can be inserted using the QTextCursor class or using the
     1048    convenience functions insertPlainText(), appendPlainText() or
    10231049    paste().
    10241050
    1025     By default the text edit wraps words at whitespace to fit within
     1051    By default, the text edit wraps words at whitespace to fit within
    10261052    the text edit widget. The setLineWrapMode() function is used to
    10271053    specify the kind of line wrap you want, \l WidgetWidth or \l
     
    11491175
    11501176    \sa QTextDocument, QTextCursor, {Application Example},
    1151         {Syntax Highlighter Example}, {Rich Text Processing}
     1177        {Code Editor Example}, {Syntax Highlighter Example},
     1178        {Rich Text Processing}
    11521179
    11531180*/
     
    14291456    }
    14301457#endif
     1458    else if (e->type() == QEvent::Gesture) {
     1459        QGestureEvent *ge = static_cast<QGestureEvent *>(e);
     1460        QPanGesture *g = static_cast<QPanGesture *>(ge->gesture(Qt::PanGesture));
     1461        if (g) {
     1462            QScrollBar *hBar = horizontalScrollBar();
     1463            QScrollBar *vBar = verticalScrollBar();
     1464            if (g->state() == Qt::GestureStarted)
     1465                d->originalOffsetY = vBar->value();
     1466            QPointF offset = g->offset();
     1467            if (!offset.isNull()) {
     1468                if (QApplication::isRightToLeft())
     1469                    offset.rx() *= -1;
     1470                // QPlainTextEdit scrolls by lines only in vertical direction
     1471                QFontMetrics fm(document()->defaultFont());
     1472                int lineHeight = fm.height();
     1473                int newX = hBar->value() - g->delta().x();
     1474                int newY = d->originalOffsetY - offset.y()/lineHeight;
     1475                hBar->setValue(newX);
     1476                vBar->setValue(newY);
     1477            }
     1478        }
     1479        return true;
     1480    }
    14311481    return QAbstractScrollArea::event(e);
    14321482}
     
    15521602#endif
    15531603
    1554     if (!(d->control->textInteractionFlags() & Qt::TextEditable)) {
     1604#ifndef QT_NO_SHORTCUT
     1605
     1606    Qt::TextInteractionFlags tif = d->control->textInteractionFlags();
     1607
     1608    if (tif & Qt::TextSelectableByKeyboard){
     1609        if (e == QKeySequence::SelectPreviousPage) {
     1610            e->accept();
     1611            d->pageUpDown(QTextCursor::Up, QTextCursor::KeepAnchor);
     1612            return;
     1613        } else if (e ==QKeySequence::SelectNextPage) {
     1614            e->accept();
     1615            d->pageUpDown(QTextCursor::Down, QTextCursor::KeepAnchor);
     1616            return;
     1617        }
     1618    }
     1619    if (tif & (Qt::TextSelectableByKeyboard | Qt::TextEditable)) {
     1620        if (e == QKeySequence::MoveToPreviousPage) {
     1621            e->accept();
     1622            d->pageUpDown(QTextCursor::Up, QTextCursor::MoveAnchor);
     1623            return;
     1624        } else if (e == QKeySequence::MoveToNextPage) {
     1625            e->accept();
     1626            d->pageUpDown(QTextCursor::Down, QTextCursor::MoveAnchor);
     1627            return;
     1628        }
     1629    }
     1630
     1631    if (!(tif & Qt::TextEditable)) {
    15551632        switch (e->key()) {
    15561633            case Qt::Key_Space:
     
    15781655        return;
    15791656    }
    1580 
    1581 #ifndef QT_NO_SHORTCUT
    1582     if (e == QKeySequence::MoveToPreviousPage) {
    1583             e->accept();
    1584             d->pageUpDown(QTextCursor::Up, QTextCursor::MoveAnchor);
    1585             return;
    1586     } else if (e == QKeySequence::MoveToNextPage) {
    1587             e->accept();
    1588             d->pageUpDown(QTextCursor::Down, QTextCursor::MoveAnchor);
    1589             return;
    1590     } else if (e == QKeySequence::SelectPreviousPage) {
    1591             e->accept();
    1592             d->pageUpDown(QTextCursor::Up, QTextCursor::KeepAnchor);
    1593             return;
    1594     } else if (e ==QKeySequence::SelectNextPage) {
    1595             e->accept();
    1596             d->pageUpDown(QTextCursor::Down, QTextCursor::KeepAnchor);
    1597             return;
    1598     }
    15991657#endif // QT_NO_SHORTCUT
    1600 
    16011658
    16021659    d->sendControlEvent(e);
     
    16091666                    // Cursor position didn't change, so we want to leave
    16101667                    // these keys to change focus.
     1668                    e->ignore();
     1669                    return;
     1670                }
     1671                break;
     1672            case Qt::Key_Left:
     1673            case Qt::Key_Right:
     1674                if (QApplication::keypadNavigationEnabled()
     1675                        && QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional) {
     1676                    // Same as for Key_Up and Key_Down.
    16111677                    e->ignore();
    16121678                    return;
     
    17111777    if (brush.style() >= Qt::LinearGradientPattern && brush.style() <= Qt::ConicalGradientPattern) {
    17121778        if (!gradientRect.isNull()) {
    1713             QTransform m;
    1714             m.translate(gradientRect.left(), gradientRect.top());
     1779            QTransform m = QTransform::fromTranslate(gradientRect.left(), gradientRect.top());
    17151780            m.scale(gradientRect.width(), gradientRect.height());
    17161781            brush.setTransform(m);
     
    17421807    QTextBlock block = firstVisibleBlock();
    17431808    qreal maximumWidth = document()->documentLayout()->documentSize().width();
    1744    
     1809
     1810    // Set a brush origin so that the WaveUnderline knows where the wave started
     1811    painter.setBrushOrigin(offset);
     1812
    17451813    // keep right margin clean from full-width selection
    17461814    int maxX = offset.x() + qMax((qreal)viewportRect.width(), maximumWidth)
     
    19061974        d->ensureCursorVisible();
    19071975    }
     1976
     1977    if (!isReadOnly() && rect().contains(e->pos()))
     1978        d->handleSoftwareInputPanel(e->button(), d->clickCausedFocus);
     1979    d->clickCausedFocus = 0;
    19081980}
    19091981
     
    20062078#endif
    20072079    d->sendControlEvent(e);
     2080    ensureCursorVisible();
    20082081}
    20092082
     
    20392112{
    20402113    Q_D(QPlainTextEdit);
     2114    if (e->reason() == Qt::MouseFocusReason) {
     2115        d->clickCausedFocus = 1;
     2116    }
    20412117    QAbstractScrollArea::focusInEvent(e);
    20422118    d->sendControlEvent(e);
     
    23052381        flags = Qt::TextEditorInteraction;
    23062382    }
    2307     setAttribute(Qt::WA_InputMethodEnabled, !ro);
     2383    setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod(this));
    23082384    d->control->setTextInteractionFlags(flags);
    23092385}
  • trunk/src/gui/widgets/qplaintextedit.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    270270    Q_PRIVATE_SLOT(d_func(), void _q_verticalScrollbarActionTriggered(int))
    271271    Q_PRIVATE_SLOT(d_func(), void _q_cursorPositionChanged())
     272
    272273    friend class QPlainTextEditControl;
    273274};
  • trunk/src/gui/widgets/qplaintextedit_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    9292    }
    9393    inline QRectF cursorRect() { return cursorRect(textCursor()); }
    94     void ensureCursorVisible() { textEdit->ensureCursorVisible(); }
     94    void ensureCursorVisible() {
     95        textEdit->ensureCursorVisible();
     96        emit microFocusChanged();
     97    }
    9598
    9699
     
    149152    uint centerOnScroll : 1;
    150153    uint inDrag : 1;
     154    uint clickCausedFocus : 1;
    151155
    152156    int topLine;
     
    172176
    173177    void _q_cursorPositionChanged();
     178    void _q_modificationChanged(bool);
    174179
    175     void _q_modificationChanged(bool);
     180    int originalOffsetY;
    176181};
    177182
  • trunk/src/gui/widgets/qprintpreviewwidget.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4141
    4242#include "qprintpreviewwidget.h"
     43#include "private/qwidget_p.h"
    4344#include <private/qprinter_p.h>
    4445
     
    99100    QRectF paperRect(0,0, paperSize.width(), paperSize.height());
    100101
    101     painter->setClipRect(paperRect & option->exposedRect);
    102     painter->fillRect(paperRect, Qt::white);
    103     if (!pagePicture)
    104         return;
    105     painter->drawPicture(pageRect.topLeft(), *pagePicture);
    106 
    107     // Effect: make anything drawn in the margins look washed out.
    108     QPainterPath path;
    109     path.addRect(paperRect);
    110     path.addRect(pageRect);
    111     painter->setPen(QPen(Qt::NoPen));
    112     painter->setBrush(QColor(255, 255, 255, 180));
    113     painter->drawPath(path);
    114 
     102    // Draw shadow
    115103    painter->setClipRect(option->exposedRect);
    116 #if 0
    117     // Draw frame around paper.
    118     painter->setPen(QPen(Qt::black, 0));
    119     painter->setBrush(Qt::NoBrush);
    120     painter->drawRect(paperRect);
    121 #endif
    122 
    123     // Draw shadow
    124104    qreal shWidth = paperRect.width()/100;
    125105    QRectF rshadow(paperRect.topRight() + QPointF(0, shWidth),
     
    142122    painter->fillRect(cshadow, QBrush(cgrad));
    143123
     124    painter->setClipRect(paperRect & option->exposedRect);
     125    painter->fillRect(paperRect, Qt::white);
     126    if (!pagePicture)
     127        return;
     128    painter->drawPicture(pageRect.topLeft(), *pagePicture);
     129
     130    // Effect: make anything drawn in the margins look washed out.
     131    QPainterPath path;
     132    path.addRect(paperRect);
     133    path.addRect(pageRect);
     134    painter->setPen(QPen(Qt::NoPen));
     135    painter->setBrush(QColor(255, 255, 255, 180));
     136    painter->drawPath(path);
     137
     138#if 0
     139    // Draw frame around paper.
     140    painter->setPen(QPen(Qt::black, 0));
     141    painter->setBrush(Qt::NoBrush);
     142    painter->drawRect(paperRect);
     143#endif
     144
    144145    // todo: drawtext "Page N" below paper
    145146}
     
    171172} // anonymous namespace
    172173
    173 class QPrintPreviewWidgetPrivate
     174class QPrintPreviewWidgetPrivate : public QWidgetPrivate
    174175{
    175176    Q_DECLARE_PUBLIC(QPrintPreviewWidget)
    176177public:
    177     QPrintPreviewWidgetPrivate(QPrintPreviewWidget *q)
    178         : q_ptr(q), scene(0), curPage(1),
     178    QPrintPreviewWidgetPrivate()
     179        : scene(0), curPage(1),
    179180          viewMode(QPrintPreviewWidget::SinglePageView),
    180181          zoomMode(QPrintPreviewWidget::FitInView),
     
    195196    int calcCurrentPage();
    196197
    197     QPrintPreviewWidget *q_ptr;
    198198    GraphicsView *graphicsView;
    199199    QGraphicsScene *scene;
     
    453453    previewing page layouts for printer output.
    454454
    455     \ingroup multimedia
     455    \ingroup printing
    456456
    457457    QPrintPreviewDialog uses a QPrintPreviewWidget internally, and the
     
    519519*/
    520520QPrintPreviewWidget::QPrintPreviewWidget(QPrinter *printer, QWidget *parent, Qt::WindowFlags flags)
    521     : QWidget(parent, flags), d_ptr(new QPrintPreviewWidgetPrivate(this))
     521    : QWidget(*new QPrintPreviewWidgetPrivate, parent, flags)
    522522{
    523523    Q_D(QPrintPreviewWidget);
     
    535535*/
    536536QPrintPreviewWidget::QPrintPreviewWidget(QWidget *parent, Qt::WindowFlags flags)
    537     : QWidget(parent, flags), d_ptr(new QPrintPreviewWidgetPrivate(this))
     537    : QWidget(*new QPrintPreviewWidgetPrivate, parent, flags)
    538538{
    539539    Q_D(QPrintPreviewWidget);
     
    552552    if (d->ownPrinter)
    553553        delete d->printer;
    554     delete d_ptr;
    555554}
    556555
     
    665664
    666665/*!
     666    \obsolete
    667667    Returns the number of pages in the preview.
     668    \sa pageCount()
    668669*/
    669670int QPrintPreviewWidget::numPages() const
     671{
     672    Q_D(const QPrintPreviewWidget);
     673    return d->pages.size();
     674}
     675
     676/*!
     677    \since 4.6
     678    Returns the number of pages in the preview.
     679*/
     680int QPrintPreviewWidget::pageCount() const
    670681{
    671682    Q_D(const QPrintPreviewWidget);
  • trunk/src/gui/widgets/qprintpreviewwidget.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    8383    ZoomMode zoomMode() const;
    8484    int currentPage() const;
    85     int numPages() const;
     85#ifdef QT_DEPRECATED
     86    QT_DEPRECATED int numPages() const;
     87#endif
     88    int pageCount() const;
    8689    void setVisible(bool visible);
    8790
     
    112115
    113116private:
    114     QPrintPreviewWidgetPrivate *d_ptr;
     117    void *dummy; // ### remove in Qt 5.0
    115118    Q_PRIVATE_SLOT(d_func(), void _q_fit())
    116119    Q_PRIVATE_SLOT(d_func(), void _q_updateCurrentPage())
  • trunk/src/gui/widgets/qprogressbar.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    173173
    174174    \ingroup basicwidgets
    175     \mainclass
     175
    176176
    177177    A progress bar is used to give the user an indication of the
     
    191191    beginning with reset().
    192192
    193     If minimum and maximum both are set to 0, the bar shows a busy indicator
    194     instead of a percentage of steps. This is useful, for example, when using
    195     QFtp or QHttp to download items when they are unable to determine the
    196     size of the item being downloaded.
     193    If minimum and maximum both are set to 0, the bar shows a busy
     194    indicator instead of a percentage of steps. This is useful, for
     195    example, when using QFtp or QNetworkAccessManager to download
     196    items when they are unable to determine the size of the item being
     197    downloaded.
    197198
    198199    \table
     
    205206    \endtable
    206207
    207     \sa QTimeLine, QProgressDialog, {fowler}{GUI Design Handbook: Progress Indicator}
     208    \sa QProgressDialog, {fowler}{GUI Design Handbook: Progress Indicator}
    208209*/
    209210
     
    350351    \brief whether the current completed percentage should be displayed
    351352
     353    This property may be ignored by the style (e.g., QMacStyle never draws the text).
     354
    352355    \sa textDirection
    353356*/
     
    442445{
    443446    Q_D(const QProgressBar);
    444     if (d->maximum == 0 || d->value < d->minimum
     447    if ((d->maximum == 0 && d->minimum == 0) || d->value < d->minimum
    445448            || (d->value == INT_MIN && d->minimum == INT_MIN))
    446449        return QString();
    447450
    448     qint64 totalSteps = qint64(d->maximum) - qint64(d->minimum);
     451    qint64 totalSteps = qint64(d->maximum) - d->minimum;
    449452
    450453    QString result = d->format;
    451     result.replace(QLatin1String("%m"), QString::fromLatin1("%1").arg(totalSteps));
    452     result.replace(QLatin1String("%v"), QString::fromLatin1("%1").arg(d->value));
     454    result.replace(QLatin1String("%m"), QString::number(totalSteps));
     455    result.replace(QLatin1String("%v"), QString::number(d->value));
    453456
    454457    // If max and min are equal and we get this far, it means that the
     
    456459    // 100% here in order to avoid division by zero further down.
    457460    if (totalSteps == 0) {
    458         result.replace(QLatin1String("%p"), QString::fromLatin1("%1").arg(100));
     461        result.replace(QLatin1String("%p"), QString::number(100));
    459462        return result;
    460463    }
    461464
    462     int progress = int(((qreal(d->value) - qreal(d->minimum)) * 100.0) / totalSteps);
    463     result.replace(QLatin1String("%p"), QString::fromLatin1("%1").arg(progress));
     465    int progress = (qreal(d->value) - d->minimum) * 100.0 / totalSteps;
     466    result.replace(QLatin1String("%p"), QString::number(progress));
    464467    return result;
    465468}
  • trunk/src/gui/widgets/qprogressbar.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qpushbutton.cpp

    r306 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6464#endif
    6565
     66#include "private/qmenu_p.h"
    6667#include "private/qpushbutton_p.h"
    6768
     
    7475
    7576    \ingroup basicwidgets
    76     \mainclass
     77
    7778
    7879    The push button, or command button, is perhaps the most commonly
     
    388389{
    389390    Q_D(const QPushButton);
    390     if (d->sizeHint.isValid())
     391    if (d->sizeHint.isValid() && d->lastAutoDefault == autoDefault())
    391392        return d->sizeHint;
     393    d->lastAutoDefault = autoDefault();
    392394    ensurePolished();
    393395
     
    528530
    529531    if (menu && !d->menu) {
    530         disconnect(this, SIGNAL(pressed()), this, SLOT(_q_popupPressed()));
    531         connect(this, SIGNAL(pressed()), this, SLOT(_q_popupPressed()));
     532        connect(this, SIGNAL(pressed()), this, SLOT(_q_popupPressed()), Qt::UniqueConnection);
    532533    }
    533534    if (d->menu)
     
    576577
    577578    menu->setNoReplayFor(q);
     579
     580    QPoint menuPos = adjustedMenuPosition();
     581
     582    QPointer<QPushButton> guard(q);
     583    QMenuPrivate::get(menu)->causedPopup.widget = guard;
     584
     585    //Because of a delay in menu effects, we must keep track of the
     586    //menu visibility to avoid flicker on button release
     587    menuOpen = true;
     588    menu->exec(menuPos);
     589    if (guard) {
     590        menuOpen = false;
     591        q->setDown(false);
     592    }
     593}
     594
     595QPoint QPushButtonPrivate::adjustedMenuPosition()
     596{
     597    Q_Q(QPushButton);
     598
    578599    bool horizontal = true;
    579600#if !defined(QT_NO_TOOLBAR)
    580     QToolBar *tb = qobject_cast<QToolBar*>(q->parentWidget());
     601    QToolBar *tb = qobject_cast<QToolBar*>(parent);
    581602    if (tb && tb->orientation() == Qt::Vertical)
    582603        horizontal = false;
    583604#endif
     605
    584606    QWidgetItem item(q);
    585607    QRect rect = item.geometry();
     
    591613    int y = globalPos.y();
    592614    if (horizontal) {
    593         if (globalPos.y() + rect.height() + menuSize.height() <= qApp->desktop()->height()) {
     615        if (globalPos.y() + rect.height() + menuSize.height() <= QApplication::desktop()->availableGeometry(q).height()) {
    594616            y += rect.height();
    595617        } else {
     
    599621            x += rect.width() - menuSize.width();
    600622    } else {
    601         if (globalPos.x() + rect.width() + menu->sizeHint().width() <= qApp->desktop()->width())
     623        if (globalPos.x() + rect.width() + menu->sizeHint().width() <= QApplication::desktop()->availableGeometry(q).width())
    602624            x += rect.width();
    603625        else
    604626            x -= menuSize.width();
    605627    }
    606     QPointer<QPushButton> guard(q);
    607 
    608     //Because of a delay in menu effects, we must keep track of the
    609     //menu visibility to avoid flicker on button release
    610     menuOpen = true;
    611     menu->exec(QPoint(x, y));
    612     if (guard) {
    613         menuOpen = false;
    614         // on some platforms (e.g. OS/2) QPushButton::focusOutEvent() may be called
    615         // before we return from exec() above (for example, as a result of window
    616         // deactivation). It will set down to false but since menuOpen won't be
    617         // false yet, the button will be redrawn as sunken still. Simple setDown(false)
    618         // won't do anything in this case so we need to call update() instead to make
    619         // sure the button is redrawn as unsunken.
    620         if (down)
    621             q->setDown(false);
    622         else
    623             q->update();
    624     }
    625 }
     628
     629    return QPoint(x,y);
     630}
     631
    626632#endif // QT_NO_MENU
    627633
     
    668674                d->resetLayoutItemMargins();
    669675                updateGeometry();
     676    } else if (e->type() == QEvent::PolishRequest) {
     677        updateGeometry();
    670678    }
    671679    return QAbstractButton::event(e);
  • trunk/src/gui/widgets/qpushbutton.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qpushbutton_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6666    QPushButtonPrivate()
    6767        : QAbstractButtonPrivate(QSizePolicy::PushButton), autoDefault(Auto),
    68           defaultButton(false), flat(false), menuOpen(false) {}
     68          defaultButton(false), flat(false), menuOpen(false), lastAutoDefault(false) {}
    6969
    7070    inline void init() { resetLayoutItemMargins(); }
     71    static QPushButtonPrivate* get(QPushButton *b) { return b->d_func(); }
     72#ifndef QT_NO_MENU
     73    QPoint adjustedMenuPosition();
     74#endif
    7175    void resetLayoutItemMargins();
    7276    void _q_popupPressed();
     
    7882    uint flat : 1;
    7983    uint menuOpen : 1;
     84    mutable uint lastAutoDefault : 1;
    8085};
    8186
  • trunk/src/gui/widgets/qradiobutton.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    8181
    8282    \ingroup basicwidgets
    83     \mainclass
     83
    8484
    8585    A QRadioButton is an option button that can be switched on (checked) or
  • trunk/src/gui/widgets/qradiobutton.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qrubberband.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    9898    \brief The QRubberBand class provides a rectangle or line that can
    9999    indicate a selection or a boundary.
    100 
    101     \ingroup misc
    102     \mainclass
    103100
    104101    A rubber band is often used to show a new bounding area (as in a
  • trunk/src/gui/widgets/qrubberband.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qscrollarea.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6262
    6363    \ingroup basicwidgets
    64     \mainclass
     64
    6565
    6666    A scroll area is used to display the contents of a child widget
     
    128128    property to one which provides constraints on the minimum and/or
    129129    maximum size of the layout (e.g., QLayout::SetMinAndMaxSize) will
    130     cause the size of the the scroll area to be updated whenever the
     130    cause the size of the scroll area to be updated whenever the
    131131    contents of the layout changes.
    132132
  • trunk/src/gui/widgets/qscrollarea.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qscrollarea_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qscrollbar.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    432432    q->setAttribute(Qt::WA_WState_OwnSizePolicy, false);
    433433    q->setAttribute(Qt::WA_OpaquePaintEvent);
     434
     435#if !defined(QT_NO_CONTEXTMENU) && defined(Q_WS_WINCE)
     436    if (!q->style()->styleHint(QStyle::SH_ScrollBar_ContextMenu, 0, q)) {
     437        q->setContextMenuPolicy(Qt::PreventContextMenu);
     438    }
     439#endif
    434440}
    435441
  • trunk/src/gui/widgets/qscrollbar.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qsizegrip.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    100100    Qt::Corner m_corner;
    101101    bool gotMousePress;
     102    QWidget *tlw;
    102103#ifdef Q_WS_MAC
    103104    void updateMacSizer(bool hide) const;
     
    112113    {
    113114        return m_corner == Qt::BottomLeftCorner || m_corner == Qt::TopLeftCorner;
     115    }
     116
     117    void updateTopLevelWidget()
     118    {
     119        Q_Q(QSizeGrip);
     120        QWidget *w = qt_sizegrip_topLevelWidget(q);
     121        if (tlw == w)
     122            return;
     123        if (tlw)
     124            tlw->removeEventFilter(q);
     125        tlw = w;
     126        if (tlw)
     127            tlw->installEventFilter(q);
    114128    }
    115129
     
    122136        Q_Q(QSizeGrip);
    123137        bool showSizeGrip = !(q->isHidden() && q->testAttribute(Qt::WA_WState_ExplicitShowHide));
    124         QWidget *tlw = qt_sizegrip_topLevelWidget(q);
     138        updateTopLevelWidget();
    125139        if (tlw && showSizeGrip) {
    126140            Qt::WindowStates sizeGripNotVisibleState = Qt::WindowFullScreen;
     
    140154{
    141155    Q_Q(const QSizeGrip);
    142     if (QApplication::closingDown() || !q->parentWidget())
     156    if (QApplication::closingDown() || !parent)
    143157        return;
    144158    QWidget *topLevelWindow = qt_sizegrip_topLevelWidget(const_cast<QSizeGrip *>(q));
     
    166180    \brief The QSizeGrip class provides a resize handle for resizing top-level windows.
    167181
    168     \ingroup application
     182    \ingroup mainwindow-classes
    169183    \ingroup basicwidgets
    170     \ingroup appearance
    171184
    172185    This widget works like the standard Windows resize handle. In the
     
    234247    dxMax = 0;
    235248    dyMax = 0;
     249    tlw = 0;
    236250    m_corner = q->isLeftToRight() ? Qt::BottomRightCorner : Qt::BottomLeftCorner;
    237251    gotMousePress = false;
     
    242256#endif
    243257    q->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed));
    244     QWidget *tlw = qt_sizegrip_topLevelWidget(q);
    245     tlw->installEventFilter(q);
     258    updateTopLevelWidget();
    246259}
    247260
     
    336349
    337350        ReleaseCapture();
    338         QT_WA_INLINE(PostMessageW(tlw->winId(), WM_SYSCOMMAND, orientation, 0),
    339                      PostMessageA(tlw->winId(), WM_SYSCOMMAND, orientation, 0));
     351        PostMessage(tlw->winId(), WM_SYSCOMMAND, orientation, 0);
    340352        return;
    341353    }
     
    527539bool QSizeGrip::eventFilter(QObject *o, QEvent *e)
    528540{
     541    Q_D(QSizeGrip);
    529542    if ((isHidden() && testAttribute(Qt::WA_WState_ExplicitShowHide))
    530         || e->type() != QEvent::WindowStateChange) {
     543        || e->type() != QEvent::WindowStateChange
     544                || o != d->tlw) {
    531545        return QWidget::eventFilter(o, e);
    532546    }
    533     QWidget *tlw = qt_sizegrip_topLevelWidget(this);
    534     if (o != tlw)
    535         return QWidget::eventFilter(o, e);
    536547    Qt::WindowStates sizeGripNotVisibleState = Qt::WindowFullScreen;
    537548#ifndef Q_WS_MAC
     
    539550#endif
    540551    // Don't show the size grip if the tlw is maximized or in full screen mode.
    541     setVisible(!(tlw->windowState() & sizeGripNotVisibleState));
     552    setVisible(!(d->tlw->windowState() & sizeGripNotVisibleState));
    542553    setAttribute(Qt::WA_WState_ExplicitShowHide, false);
    543554    return QWidget::eventFilter(o, e);
  • trunk/src/gui/widgets/qsizegrip.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qslider.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6363    QSlider::TickPosition tickPosition;
    6464    int clickOffset;
    65     int snapBackPosition;
    6665    void init();
    6766        void resetLayoutItemMargins();
     
    205204
    206205    \ingroup basicwidgets
    207     \mainclass
     206
    208207
    209208    The slider is the classic widget for controlling a bounded value.
     
    494493        QRect sr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this);
    495494        d->clickOffset = d->pick(ev->pos() - sr.topLeft());
    496         d->snapBackPosition = d->position;
    497495        update(sr);
    498496        setSliderDown(true);
     
    514512    QStyleOptionSlider opt;
    515513    initStyleOption(&opt);
    516     int m = style()->pixelMetric(QStyle::PM_MaximumDragDistance, &opt, this);
    517     if (m >= 0) {
    518         QRect r = rect();
    519         r.adjust(-m, -m, m, m);
    520         if (!r.contains(ev->pos())) {
    521             newPosition = d->snapBackPosition;
    522     }
    523     }
    524514    setSliderPosition(newPosition);
    525515}
  • trunk/src/gui/widgets/qslider.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    115115    inline QT3_SUPPORT TickPosition tickmarks() const { return tickPosition(); }
    116116public Q_SLOTS:
    117     inline QT_MOC_COMPAT void addStep() { triggerAction(SliderSingleStepAdd); };
    118     inline QT_MOC_COMPAT void subtractStep() { triggerAction(SliderSingleStepSub); };
     117    inline QT_MOC_COMPAT void addStep() { triggerAction(SliderSingleStepAdd); }
     118    inline QT_MOC_COMPAT void subtractStep() { triggerAction(SliderSingleStepSub); }
    119119#endif
    120120
  • trunk/src/gui/widgets/qspinbox.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5151
    5252#include <math.h>
     53#include <float.h>
    5354
    5455QT_BEGIN_NAMESPACE
     
    6162#endif
    6263
    63 static bool isIntermediateValueHelper(qint64 num, qint64 minimum, qint64 maximum, qint64 *match = 0);
    64 
    6564class QSpinBoxPrivate : public QAbstractSpinBoxPrivate
    6665{
    6766    Q_DECLARE_PUBLIC(QSpinBox)
    6867public:
    69     QSpinBoxPrivate(QWidget *parent = 0);
     68    QSpinBoxPrivate();
    7069    void emitSignals(EmitPolicy ep, const QVariant &);
    7170
     
    7473    QVariant validateAndInterpret(QString &input, int &pos,
    7574                                  QValidator::State &state) const;
    76     bool isIntermediateValue(const QString &str) const;
    77     QChar thousand;
    7875
    7976    inline void init() {
     77        Q_Q(QSpinBox);
     78        q->setInputMethodHints(Qt::ImhDigitsOnly);
    8079        setLayoutItemMargins(QStyle::SE_SpinBoxLayoutItem);
    8180    }
     
    8685    Q_DECLARE_PUBLIC(QDoubleSpinBox)
    8786public:
    88     QDoubleSpinBoxPrivate(QWidget *parent = 0);
     87    QDoubleSpinBoxPrivate();
    8988    void emitSignals(EmitPolicy ep, const QVariant &);
    90     bool isIntermediateValue(const QString &str) const;
    9189
    9290    virtual QVariant valueFromText(const QString &n) const;
     
    9795    // variables
    9896    int decimals;
    99     QChar delimiter, thousand;
     97
     98    inline void init() {
     99        Q_Q(QDoubleSpinBox);
     100        q->setInputMethodHints(Qt::ImhFormattedNumbersOnly);
     101    }
    100102};
    101103
     
    106108
    107109    \ingroup basicwidgets
    108     \mainclass
     110
    109111
    110112    QSpinBox is designed to handle integers and discrete sets of
     
    198200
    199201QSpinBox::QSpinBox(QWidget *parent)
    200     : QAbstractSpinBox(*new QSpinBoxPrivate(parent), parent)
     202    : QAbstractSpinBox(*new QSpinBoxPrivate, parent)
    201203{
    202204    Q_D(QSpinBox);
     
    210212*/
    211213QSpinBox::QSpinBox(QWidget *parent, const char *name)
    212     : QAbstractSpinBox(*new QSpinBoxPrivate(parent), parent)
     214    : QAbstractSpinBox(*new QSpinBoxPrivate, parent)
    213215{
    214216    Q_D(QSpinBox);
     
    222224*/
    223225QSpinBox::QSpinBox(int minimum, int maximum, int step, QWidget *parent, const char *name)
    224     : QAbstractSpinBox(*new QSpinBoxPrivate(parent), parent)
     226    : QAbstractSpinBox(*new QSpinBoxPrivate, parent)
    225227{
    226228    Q_D(QSpinBox);
     
    285287    d->prefix = prefix;
    286288    d->updateEdit();
     289
     290    d->cachedSizeHint = QSize();
     291    updateGeometry();
    287292}
    288293
     
    319324    d->suffix = suffix;
    320325    d->updateEdit();
     326
     327    d->cachedSizeHint = QSize();
     328    updateGeometry();
    321329}
    322330
     
    455463QString QSpinBox::textFromValue(int value) const
    456464{
    457     Q_D(const QSpinBox);
    458465    QString str = locale().toString(value);
    459466    if (qAbs(value) >= 1000 || value == INT_MIN) {
    460         str.remove(d->thousand);
     467        str.remove(locale().groupSeparator());
    461468    }
    462469
     
    507514void QSpinBox::fixup(QString &input) const
    508515{
    509     Q_D(const QSpinBox);
    510 
    511     input.remove(d->thousand);
     516    input.remove(locale().groupSeparator());
    512517}
    513518
     
    521526
    522527    \ingroup basicwidgets
    523     \mainclass
     528
    524529
    525530    QDoubleSpinBox allows the user to choose a value by clicking the
     
    591596*/
    592597QDoubleSpinBox::QDoubleSpinBox(QWidget *parent)
    593     : QAbstractSpinBox(*new QDoubleSpinBoxPrivate(parent), parent)
    594 {
     598    : QAbstractSpinBox(*new QDoubleSpinBoxPrivate, parent)
     599{
     600    Q_D(QDoubleSpinBox);
     601    d->init();
    595602}
    596603
     
    818825     interpreting doubles.
    819826
    820      \warning The results might not be reliable with very high values
    821      for \a decimals.
     827     \warning The maximum value for \a decimals is DBL_MAX_10_EXP +
     828     DBL_DIG (ie. 323) because of the limitations of the double type.
    822829
    823830     Note: The maximum, minimum and value might change as a result of
     
    835842{
    836843    Q_D(QDoubleSpinBox);
    837     d->decimals = qMax(0, decimals);
     844    d->decimals = qBound(0, decimals, DBL_MAX_10_EXP + DBL_DIG);
    838845
    839846    setRange(minimum(), maximum()); // make sure values are rounded
     
    864871    QString str = locale().toString(value, 'f', d->decimals);
    865872    if (qAbs(value) >= 1000.0) {
    866         str.remove(d->thousand);
     873        str.remove(locale().groupSeparator());
    867874    }
    868875    return str;
     
    909916void QDoubleSpinBox::fixup(QString &input) const
    910917{
    911     Q_D(const QDoubleSpinBox);
    912 
    913     input.remove(d->thousand);
     918    input.remove(locale().groupSeparator());
    914919}
    915920
     
    921926*/
    922927
    923 QSpinBoxPrivate::QSpinBoxPrivate(QWidget *parent)
     928QSpinBoxPrivate::QSpinBoxPrivate()
    924929{
    925930    minimum = QVariant((int)0);
     
    928933    singleStep = QVariant((int)1);
    929934    type = QVariant::Int;
    930     const QString str = (parent ? parent->locale() : QLocale()).toString(4567);
    931     if (str.size() == 5) {
    932         thousand = QChar(str.at(1));
    933     }
    934 
    935935}
    936936
     
    976976
    977977/*!
    978   \internal
    979 
    980   Return true if str can become a number which is between minimum and
    981   maximum or false if this is not possible.
    982 */
    983 
    984 bool QSpinBoxPrivate::isIntermediateValue(const QString &str) const
    985 {
    986     const int num = q_func()->locale().toInt(str, 0, 10);
    987     const int min = minimum.toInt();
    988     const int max = maximum.toInt();
    989 
    990     int numDigits = 0;
    991     int digits[10];
    992     int tmp = num;
    993     if (tmp == 0) {
    994         numDigits = 1;
    995         digits[0] = 0;
    996     } else {
    997         tmp = num;
    998         for (int i=0; tmp != 0; ++i) {
    999             digits[numDigits++] = qAbs(tmp % 10);
    1000             tmp /= 10;
    1001         }
    1002     }
    1003 
    1004     int failures = 0;
    1005     for (int number=min; /*number<=max*/; ++number) {
    1006         tmp = number;
    1007         for (int i=0; tmp != 0;) {
    1008             if (digits[i] == qAbs(tmp % 10)) {
    1009                 if (++i == numDigits)
    1010                     return true;
    1011             }
    1012             tmp /= 10;
    1013         }
    1014         if (failures++ == 500000) //upper bound
    1015             return true;
    1016         if (number == max) // needed for INT_MAX
    1017             break;
    1018     }
    1019     return false;
    1020 }
    1021 
    1022 /*!
    1023978    \internal Multi purpose function that parses input, sets state to
    1024979    the appropriate state and returns the value it will be interpreted
     
    1031986    if (cachedText == input && !input.isEmpty()) {
    1032987        state = cachedState;
    1033         QSBDEBUG() << "cachedText was" << "'" << cachedText << "'" << "state was "
     988        QSBDEBUG() << "cachedText was '" << cachedText << "' state was "
    1034989                   << state << " and value was " << cachedValue;
    1035990
     
    10491004        state = QValidator::Intermediate;
    10501005        QSBDEBUG() << __FILE__ << __LINE__<< "num is set to" << num;
    1051     } else if (copy.startsWith(QLatin1String("-")) && min >= 0) {
     1006    } else if (copy.startsWith(QLatin1Char('-')) && min >= 0) {
    10521007        state = QValidator::Invalid; // special-case -0 will be interpreted as 0 and thus not be invalid with a range from 0-100
    10531008    } else {
    10541009        bool ok = false;
    1055         bool removedThousand = false;
    1056         num = q_func()->locale().toInt(copy, &ok, 10);
    1057         if (!ok && copy.contains(thousand) && (max >= 1000 || min <= -1000)) {
    1058             const int s = copy.size();
    1059             copy.remove(thousand);
    1060             pos = qMax(0, pos - (s - copy.size()));
    1061             removedThousand = true;
    1062             num = q_func()->locale().toInt(copy, &ok, 10);
     1010        num = locale.toInt(copy, &ok, 10);
     1011        if (!ok && copy.contains(locale.groupSeparator()) && (max >= 1000 || min <= -1000)) {
     1012            QString copy2 = copy;
     1013            copy2.remove(locale.groupSeparator());
     1014            num = locale.toInt(copy2, &ok, 10);
    10631015        }
    10641016        QSBDEBUG() << __FILE__ << __LINE__<< "num is set to" << num;
     
    10661018            state = QValidator::Invalid;
    10671019        } else if (num >= min && num <= max) {
    1068             state = removedThousand ? QValidator::Intermediate : QValidator::Acceptable;
     1020            state = QValidator::Acceptable;
    10691021        } else if (max == min) {
    10701022            state = QValidator::Invalid;
     
    10741026                QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
    10751027            } else {
    1076                 state = isIntermediateValue(copy) ? QValidator::Intermediate : QValidator::Invalid;
    1077                 QSBDEBUG() << __FILE__ << __LINE__<< "state is set to "
    1078                            << (state == QValidator::Intermediate ? "Intermediate" : "Acceptable");
     1028                state = QValidator::Intermediate;
     1029                QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Intermediate";
    10791030            }
    10801031        }
     
    10991050*/
    11001051
    1101 QDoubleSpinBoxPrivate::QDoubleSpinBoxPrivate(QWidget *parent)
     1052QDoubleSpinBoxPrivate::QDoubleSpinBoxPrivate()
    11021053{
    11031054    minimum = QVariant(0.0);
     
    11071058    decimals = 2;
    11081059    type = QVariant::Double;
    1109     const QString str = (parent ? parent->locale() : QLocale()).toString(4567.1);
    1110     if (str.size() == 6) {
    1111         delimiter = str.at(4);
    1112         thousand = QChar((ushort)0);
    1113     } else if (str.size() == 7) {
    1114         thousand = str.at(1);
    1115         delimiter = str.at(5);
    1116     }
    1117     Q_ASSERT(!delimiter.isNull());
    11181060}
    11191061
     
    11361078
    11371079
    1138 bool QDoubleSpinBoxPrivate::isIntermediateValue(const QString &str) const
    1139 {
    1140     QSBDEBUG() << "input is" << str << minimum << maximum;
    1141     qint64 dec = 1;
    1142     for (int i=0; i<decimals; ++i)
    1143         dec *= 10;
    1144 
    1145     const QLatin1Char dot('.');
    1146 
    1147     // I know QString::number() uses CLocale so I use dot
    1148     const QString minstr = QString::number(minimum.toDouble(), 'f', decimals);
    1149     bool ok;
    1150     qint64 min_left = minstr.left(minstr.indexOf(dot)).toLongLong(&ok);
    1151     if (!ok)
    1152         return false;
    1153     qint64 min_right = minstr.mid(minstr.indexOf(dot) + 1).toLongLong();
    1154 
    1155     const QString maxstr = QString::number(maximum.toDouble(), 'f', decimals);
    1156     qint64 max_left = maxstr.left(maxstr.indexOf(dot)).toLongLong(&ok);
    1157     if (!ok)
    1158         return true;
    1159     qint64 max_right = maxstr.mid(maxstr.indexOf(dot) + 1).toLongLong();
    1160 
    1161     const int dotindex = str.indexOf(delimiter);
    1162     const bool negative = maximum.toDouble() < 0;
    1163     qint64 left = 0, right = 0;
    1164     bool doleft = true;
    1165     bool doright = true;
    1166     if (dotindex == -1) {
    1167         left = str.toLongLong();
    1168         doright = false;
    1169     } else if (dotindex == 0 || (dotindex == 1 && str.at(0) == QLatin1Char('+'))) {
    1170         if (negative) {
    1171             QSBDEBUG() << __FILE__ << __LINE__ << "returns false";
    1172             return false;
    1173         }
    1174         doleft = false;
    1175         right = str.mid(dotindex + 1).toLongLong();
    1176     } else if (dotindex == 1 && str.at(0) == QLatin1Char('-')) {
    1177         if (!negative) {
    1178             QSBDEBUG() << __FILE__ << __LINE__ << "returns false";
    1179             return false;
    1180         }
    1181         doleft = false;
    1182         right = str.mid(dotindex + 1).toLongLong();
    1183     } else {
    1184         left = str.left(dotindex).toLongLong();
    1185         if (dotindex == str.size() - 1) {
    1186             doright = false;
    1187         } else {
    1188             right = str.mid(dotindex + 1).toLongLong();
    1189         }
    1190     }
    1191     if ((left >= 0 && max_left < 0 && !str.startsWith(QLatin1Char('-'))) || (left < 0 && min_left >= 0)) {
    1192         QSBDEBUG("returns false 0");
    1193         return false;
    1194     }
    1195 
    1196     qint64 match = min_left;
    1197     if (doleft && !isIntermediateValueHelper(left, min_left, max_left, &match)) {
    1198         QSBDEBUG() << __FILE__ << __LINE__ << "returns false";
    1199         return false;
    1200     }
    1201     if (doright) {
    1202         QSBDEBUG("match %lld min_left %lld max_left %lld", match, min_left, max_left);
    1203         if (!doleft) {
    1204             if (min_left == max_left) {
    1205                 const bool ret = isIntermediateValueHelper(qAbs(left),
    1206                                                            negative ? max_right : min_right,
    1207                                                            negative ? min_right : max_right);
    1208                 QSBDEBUG() << __FILE__ << __LINE__ << "returns" << ret;
    1209                 return ret;
    1210             } else if (qAbs(max_left - min_left) == 1) {
    1211                 const bool ret = isIntermediateValueHelper(qAbs(left), min_right, negative ? 0 : dec)
    1212                                  || isIntermediateValueHelper(qAbs(left), negative ? dec : 0, max_right);
    1213                 QSBDEBUG() << __FILE__ << __LINE__ << "returns" << ret;
    1214                 return ret;
    1215             } else {
    1216                 const bool ret = isIntermediateValueHelper(qAbs(left), 0, dec);
    1217                 QSBDEBUG() << __FILE__ << __LINE__ << "returns" << ret;
    1218                 return ret;
    1219             }
    1220         }
    1221         if (match != min_left) {
    1222             min_right = negative ? dec : 0;
    1223         }
    1224         if (match != max_left) {
    1225             max_right = negative ? 0 : dec;
    1226         }
    1227         qint64 tmpl = negative ? max_right : min_right;
    1228         qint64 tmpr = negative ? min_right : max_right;
    1229         const bool ret = isIntermediateValueHelper(right, tmpl, tmpr);
    1230         QSBDEBUG() << __FILE__ << __LINE__ << "returns" << ret;
    1231         return ret;
    1232     }
    1233     QSBDEBUG() << __FILE__ << __LINE__ << "returns true";
    1234     return true;
    1235 }
    1236 
    12371080/*!
    12381081    \internal
     
    12551098double QDoubleSpinBoxPrivate::round(double value) const
    12561099{
    1257     Q_Q(const QDoubleSpinBox);
    1258     const QString strDbl = q->locale().toString(value, 'f', decimals);
    1259     return q->locale().toDouble(strDbl);
     1100    return QString::number(value, 'f', decimals).toDouble();
    12601101}
    12611102
     
    12721113    if (cachedText == input && !input.isEmpty()) {
    12731114        state = cachedState;
    1274         QSBDEBUG() << "cachedText was" << "'" << cachedText << "'" << "state was "
     1115        QSBDEBUG() << "cachedText was '" << cachedText << "' state was "
    12751116                   << state << " and value was " << cachedValue;
    12761117        return cachedValue;
     
    12911132        goto end;
    12921133    case 1:
    1293         if (copy.at(0) == delimiter
     1134        if (copy.at(0) == locale.decimalPoint()
    12941135            || (plus && copy.at(0) == QLatin1Char('+'))
    12951136            || (minus && copy.at(0) == QLatin1Char('-'))) {
     
    12991140        break;
    13001141    case 2:
    1301         if (copy.at(1) == delimiter
     1142        if (copy.at(1) == locale.decimalPoint()
    13021143            && ((plus && copy.at(0) == QLatin1Char('+')) || (minus && copy.at(0) == QLatin1Char('-')))) {
    13031144            state = QValidator::Intermediate;
     
    13081149    }
    13091150
    1310     if (copy.at(0) == thousand) {
     1151    if (copy.at(0) == locale.groupSeparator()) {
    13111152        QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
    13121153        state = QValidator::Invalid;
    13131154        goto end;
    13141155    } else if (len > 1) {
    1315         const int dec = copy.indexOf(delimiter);
     1156        const int dec = copy.indexOf(locale.decimalPoint());
    13161157        if (dec != -1) {
    1317             if (dec + 1 < copy.size() && copy.at(dec + 1) == delimiter && pos == dec + 1) {
     1158            if (dec + 1 < copy.size() && copy.at(dec + 1) == locale.decimalPoint() && pos == dec + 1) {
    13181159                copy.remove(dec + 1, 1); // typing a delimiter when you are on the delimiter
    13191160            } // should be treated as typing right arrow
     
    13251166            }
    13261167            for (int i=dec + 1; i<copy.size(); ++i) {
    1327                 if (copy.at(i).isSpace() || copy.at(i) == thousand) {
     1168                if (copy.at(i).isSpace() || copy.at(i) == locale.groupSeparator()) {
    13281169                    QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
    13291170                    state = QValidator::Invalid;
     
    13341175            const QChar &last = copy.at(len - 1);
    13351176            const QChar &secondLast = copy.at(len - 2);
    1336             if ((last == thousand || last.isSpace())
    1337                 && (secondLast == thousand || secondLast.isSpace())) {
     1177            if ((last == locale.groupSeparator() || last.isSpace())
     1178                && (secondLast == locale.groupSeparator() || secondLast.isSpace())) {
    13381179                state = QValidator::Invalid;
    13391180                QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
    13401181                goto end;
    1341             } else if (last.isSpace() && (!thousand.isSpace() || secondLast.isSpace())) {
     1182            } else if (last.isSpace() && (!locale.groupSeparator().isSpace() || secondLast.isSpace())) {
    13421183                state = QValidator::Invalid;
    13431184                QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
     
    13491190    {
    13501191        bool ok = false;
    1351         QLocale loc(q_func()->locale());
    1352         num = loc.toDouble(copy, &ok);
    1353         QSBDEBUG() << __FILE__ << __LINE__ << loc << copy << num << ok;
    1354         bool notAcceptable = false;
     1192        num = locale.toDouble(copy, &ok);
     1193        QSBDEBUG() << __FILE__ << __LINE__ << locale << copy << num << ok;
    13551194
    13561195        if (!ok) {
    1357             if (thousand.isPrint()) {
    1358                 if (max < 1000 && min > -1000 && copy.contains(thousand)) {
     1196            if (locale.groupSeparator().isPrint()) {
     1197                if (max < 1000 && min > -1000 && copy.contains(locale.groupSeparator())) {
    13591198                    state = QValidator::Invalid;
    13601199                    QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
     
    13641203                const int len = copy.size();
    13651204                for (int i=0; i<len- 1; ++i) {
    1366                     if (copy.at(i) == thousand && copy.at(i + 1) == thousand) {
     1205                    if (copy.at(i) == locale.groupSeparator() && copy.at(i + 1) == locale.groupSeparator()) {
    13671206                        QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
    13681207                        state = QValidator::Invalid;
     
    13711210                }
    13721211
    1373                 const int s = copy.size();
    1374                 copy.remove(thousand);
    1375                 pos = qMax(0, pos - (s - copy.size()));
    1376 
    1377 
    1378                 num = loc.toDouble(copy, &ok);
    1379                 QSBDEBUG() << thousand << num << copy << ok;
     1212                QString copy2 = copy;
     1213                copy2.remove(locale.groupSeparator());
     1214                num = locale.toDouble(copy2, &ok);
     1215                QSBDEBUG() << locale.groupSeparator() << num << copy2 << ok;
    13801216
    13811217                if (!ok) {
     
    13841220                    goto end;
    13851221                }
    1386                 notAcceptable = true;
    13871222            }
    13881223        }
     
    13921227            QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
    13931228        } else if (num >= min && num <= max) {
    1394             state = notAcceptable ? QValidator::Intermediate : QValidator::Acceptable;
    1395             QSBDEBUG() << __FILE__ << __LINE__<< "state is set to "
    1396                        << (state == QValidator::Intermediate ? "Intermediate" : "Acceptable");
     1229            state = QValidator::Acceptable;
     1230            QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Acceptable";
    13971231        } else if (max == min) { // when max and min is the same the only non-Invalid input is max (or min)
    13981232            state = QValidator::Invalid;
     
    14031237                QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid";
    14041238            } else {
    1405                 state = isIntermediateValue(copy) ? QValidator::Intermediate : QValidator::Invalid;
    1406                 QSBDEBUG() << __FILE__ << __LINE__<< "state is set to "
    1407                            << (state == QValidator::Intermediate ? "Intermediate" : "Acceptable");
     1239                state = QValidator::Intermediate;
     1240                QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Intermediate";
    14081241            }
    14091242        }
     
    14621295    Use minimum() instead.
    14631296*/
    1464 
    1465 /*!
    1466     \internal Returns whether \a str is a string which value cannot be
    1467     parsed but still might turn into something valid.
    1468 */
    1469 
    1470 static bool isIntermediateValueHelper(qint64 num, qint64 min, qint64 max, qint64 *match)
    1471 {
    1472     QSBDEBUG("%lld %lld %lld", num, min, max);
    1473 
    1474     if (num >= min && num <= max) {
    1475         if (match)
    1476             *match = num;
    1477         QSBDEBUG("returns true 0");
    1478         return true;
    1479     }
    1480     qint64 tmp = num;
    1481 
    1482     int numDigits = 0;
    1483     int digits[10];
    1484     if (tmp == 0) {
    1485         numDigits = 1;
    1486         digits[0] = 0;
    1487     } else {
    1488         tmp = qAbs(num);
    1489         for (int i=0; tmp > 0; ++i) {
    1490             digits[numDigits++] = tmp % 10;
    1491             tmp /= 10;
    1492         }
    1493     }
    1494 
    1495     int failures = 0;
    1496     qint64 number;
    1497     for (number=max; number>=min; --number) {
    1498         tmp = qAbs(number);
    1499         for (int i=0; tmp > 0;) {
    1500             if (digits[i] == (tmp % 10)) {
    1501                 if (++i == numDigits) {
    1502                     if (match)
    1503                         *match = number;
    1504                     QSBDEBUG("returns true 1");
    1505                     return true;
    1506                 }
    1507             }
    1508             tmp /= 10;
    1509         }
    1510         if (failures++ == 500000) { //upper bound
    1511             if (match)
    1512                 *match = num;
    1513             QSBDEBUG("returns true 2");
    1514             return true;
    1515         }
    1516     }
    1517     QSBDEBUG("returns false");
    1518     return false;
    1519 }
    15201297
    15211298/*! \reimp */
  • trunk/src/gui/widgets/qspinbox.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qsplashscreen.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    7272   \brief The QSplashScreen widget provides a splash screen that can
    7373   be shown during application startup.
    74 
    75    \ingroup misc
    76    \mainclass
    7774
    7875   A splash screen is a widget that is usually displayed when an
  • trunk/src/gui/widgets/qsplashscreen.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qsplitter.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    120120    Q_D(QSplitterHandle);
    121121    d->s = parent;
    122     d->hover = false;
    123122    setOrientation(orientation);
    124123}
     
    270269{
    271270    Q_D(QSplitterHandle);
    272     if (e->button() == Qt::LeftButton)
     271    if (e->button() == Qt::LeftButton) {
    273272        d->mouseOffset = d->pick(e->pos());
     273        d->pressed = true;
     274        update();
     275    }
    274276}
    275277
     
    285287        d->s->setRubberBand(-1);
    286288        moveSplitter(pos);
     289    }
     290    if (e->button() == Qt::LeftButton) {
     291        d->pressed = false;
     292        update();
    287293    }
    288294}
     
    304310    if (d->hover)
    305311        opt.state |= QStyle::State_MouseOver;
     312    if (d->pressed)
     313        opt.state |= QStyle::State_Sunken;
    306314    if (isEnabled())
    307315        opt.state |= QStyle::State_Enabled;
     
    353361    */
    354362    bool first = true;
     363    bool allInvisible = n != 0;
    355364    for (int i = 0; i < n ; ++i) {
    356365        QSplitterLayoutStruct *s = list.at(i);
    357         s->handle->setHidden(first || s->widget->isHidden());
    358         if (!s->widget->isHidden())
     366        bool widgetHidden = s->widget->isHidden();
     367        if (allInvisible && !widgetHidden && !s->collapsed)
     368            allInvisible = false;
     369        s->handle->setHidden(first || widgetHidden);
     370        if (!widgetHidden)
    359371            first = false;
    360372    }
     373
     374    if (allInvisible)
     375        for (int i = 0; i < n ; ++i) {
     376            QSplitterLayoutStruct *s = list.at(i);
     377            if (!s->widget->isHidden()) {
     378                s->collapsed = false;
     379                break;
     380            }
     381        }
    361382
    362383    int fi = 2 * q->frameWidth();
     
    390411
    391412    if (empty) {
    392         if (qobject_cast<QSplitter *>(q->parentWidget())) {
     413        if (qobject_cast<QSplitter *>(parent)) {
    393414            // nested splitters; be nice
    394415            maxl = maxt = 0;
     
    924945
    925946    \ingroup organizers
    926     \mainclass
     947
    927948
    928949    A splitter lets the user control the size of child widgets by dragging the
     
    15181539/*!
    15191540    \fn int QSplitter::margin() const
    1520     Returns the with of the the margin around the contents of the widget.
     1541    Returns the width of the margin around the contents of the widget.
    15211542
    15221543    Use QWidget::getContentsMargins() instead.
  • trunk/src/gui/widgets/qsplitter.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qsplitter_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    132132    Q_DECLARE_PUBLIC(QSplitterHandle)
    133133public:
    134     QSplitterHandlePrivate() : orient(Qt::Horizontal), opaq(false), s(0), mouseOffset(0) {}
     134    QSplitterHandlePrivate() : s(0), orient(Qt::Horizontal), mouseOffset(0), opaq(false), hover(false), pressed(false) {}
    135135
    136136    inline int pick(const QPoint &pos) const
    137137    { return orient == Qt::Horizontal ? pos.x() : pos.y(); }
    138138
     139    QSplitter *s;
    139140    Qt::Orientation orient;
    140     bool opaq;
    141     QSplitter *s;
    142     bool hover;
    143141    int mouseOffset;
     142    bool opaq    : 1;
     143    bool hover   : 1;
     144    bool pressed : 1;
    144145};
    145146
  • trunk/src/gui/widgets/qstackedwidget.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6666    \ingroup organizers
    6767    \ingroup geomanagement
    68     \ingroup appearance
    69     \mainclass
     68
    7069
    7170    QStackedWidget can be used to create a user interface similar to
  • trunk/src/gui/widgets/qstackedwidget.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qstatusbar.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    145145                        left = qMax(left, item->w->x() + item->w->width() + 2);
    146146                    else
    147                         right = qMin(right, item->w->x()-1);
     147                        right = qMin(right, item->w->x() - 2);
    148148                }
    149149                break;
     
    159159    presenting status information.
    160160
    161     \ingroup application
     161    \ingroup mainwindow-classes
    162162    \ingroup helpsystem
    163     \mainclass
     163
    164164
    165165    Each status indicator falls into one of three categories:
     
    729729        if (item && item->w->isVisible() && (!haveMessage || item->p)) {
    730730            QRect ir = item->w->geometry().adjusted(-2, -1, 2, 1);
    731             if (event->rect().contains(ir)) {
     731            if (event->rect().intersects(ir)) {
    732732                QStyleOption opt(0);
    733733                opt.rect = ir;
  • trunk/src/gui/widgets/qstatusbar.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qtabbar.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    8888        // TODO: test tab bar position
    8989
    90         // push the black line at the bottom of the menu bar down to the client are so we can paint over it
     90        OSWindowRef window = qt_mac_window_for(q);
     91
     92        // push base line separator down to the client are so we can paint over it (Carbon)
    9193        metrics.top = (documentMode && q->isVisible()) ? 1 : 0;
    9294        metrics.bottom = 0;
    9395        metrics.left = 0;
    9496        metrics.right = 0;
    95 
    96         qt_mac_updateContentBorderMetricts(qt_mac_window_for(q), metrics);
     97        qt_mac_updateContentBorderMetricts(window, metrics);
     98       
     99        // hide the base line separator if the tabs have docuemnt mode enabled (Cocoa)
     100        qt_mac_showBaseLineSeparator(window, !documentMode);
    97101    }
    98102#endif
     
    132136    if (isActiveWindow())
    133137        option->state |= QStyle::State_Active;
    134     if (option->rect == d->hoverRect)
     138    if (!d->dragInProgress && option->rect == d->hoverRect)
    135139        option->state |= QStyle::State_MouseOver;
    136140    option->shape = d->shape;
     
    177181            option->cornerWidgets |= QStyleOptionTab::RightCornerWidget;
    178182    }
     183#endif
    179184
    180185    QRect textRect = style()->subElementRect(QStyle::SE_TabBarTabText, option, this);
    181 
    182186    option->text = fontMetrics().elidedText(option->text, d->elideMode, textRect.width(),
    183187                        Qt::TextShowMnemonic);
    184 #endif
    185188}
    186189
     
    190193
    191194    \ingroup basicwidgets
    192     \mainclass
     195
    193196
    194197    QTabBar is straightforward to use; it draws the tabs using one of
     
    455458    }
    456459
    457     if (pressedIndex != -1 && movable)
    458         grabCache(0, tabList.count(), true);
    459 
    460460    Q_ASSERT(tabChainIndex == tabChain.count() - 1); // add an assert just to make sure.
    461461    // Mirror our front item.
     
    668668        && movable
    669669        && QApplication::mouseButtons() == Qt::NoButton) {
    670         _q_moveTabFinished(pressedIndex);
     670        moveTabFinished(pressedIndex);
    671671        if (!validIndex(pressedIndex))
    672672            pressedIndex = -1;
     
    10891089
    10901090/*!
    1091     Returns the datad of the tab at position \a index, or a null
     1091    Returns the data of the tab at position \a index, or a null
    10921092    variant if \a index is out of range.
    10931093*/
     
    11011101
    11021102/*!
    1103     Returns the visual rectangle of the of the tab at position \a
     1103    Returns the visual rectangle of the tab at position \a
    11041104    index, or a null rectangle if \a index is out of range.
    11051105*/
     
    11711171        update();
    11721172        d->makeVisible(index);
     1173        d->tabList[index].lastTab = oldIndex;
     1174        d->layoutWidgets(oldIndex);
     1175        d->layoutWidgets(index);
    11731176#ifdef QT3_SUPPORT
    11741177        emit selected(index);
    11751178#endif
    11761179        emit currentChanged(index);
    1177         d->tabList[index].lastTab = oldIndex;
    1178         d->layoutWidgets(oldIndex);
    1179         d->layoutWidgets(index);
    11801180    }
    11811181}
     
    12941294QSize QTabBar::tabSizeHint(int index) const
    12951295{
     1296    //Note: this must match with the computations in QCommonStylePrivate::tabLayout
    12961297    Q_D(const QTabBar);
    12971298    if (const QTabBarPrivate::Tab *tab = d->at(index)) {
     
    13101311        int widgetHeight = 0;
    13111312        int padding = 0;
    1312         if (opt.leftButtonSize.isValid()) {
    1313             padding += 6 + 2;
     1313        if (!opt.leftButtonSize.isEmpty()) {
     1314            padding += 4;
    13141315            widgetWidth += opt.leftButtonSize.width();
    13151316            widgetHeight += opt.leftButtonSize.height();
    13161317        }
    1317         if (opt.rightButtonSize.isValid()) {
    1318             padding += 6 + 2;
     1318        if (!opt.rightButtonSize.isEmpty()) {
     1319            padding += 4;
    13191320            widgetWidth += opt.rightButtonSize.width();
    13201321            widgetHeight += opt.rightButtonSize.height();
    13211322        }
    1322         if (opt.iconSize.isValid())
    1323             padding += 2;
     1323        if (!opt.icon.isNull())
     1324            padding += 4;
    13241325
    13251326        QSize csz;
     
    14851486    QStyleOptionTab cutTab;
    14861487    selected = d->currentIndex;
     1488    if (d->dragInProgress)
     1489        selected = d->pressedIndex;
    14871490
    14881491    for (int i = 0; i < d->tabList.count(); ++i)
     
    15231526            continue;
    15241527
    1525         if (!d->tabList[i].animatingCache.isNull() && d->paintWithOffsets) {
    1526             p.drawPixmap(tab.rect, d->tabList[i].animatingCache);
    1527         } else {
    1528             p.drawControl(QStyle::CE_TabBarTab, tab);
    1529         }
     1528        p.drawControl(QStyle::CE_TabBarTab, tab);
    15301529    }
    15311530
     
    15401539                tab.rect.moveLeft(tab.rect.x() + d->tabList[selected].dragOffset);
    15411540        }
    1542         p.drawControl(QStyle::CE_TabBarTab, tab);
     1541        if (!d->dragInProgress)
     1542            p.drawControl(QStyle::CE_TabBarTab, tab);
     1543        else {
     1544            int taboverlap = style()->pixelMetric(QStyle::PM_TabBarTabOverlap, 0, this);
     1545            d->movingTab->setGeometry(tab.rect.adjusted(-taboverlap, 0, taboverlap, 0));
     1546        }
    15431547    }
    15441548
     
    16641668    int postLocation = vertical ? q->tabRect(to).y() : q->tabRect(to).x();
    16651669    int length = postLocation - preLocation;
    1666     tabList[to].makeTimeLine(q);
    1667     tabList[to].dragOffset += -1 * length;
    1668     tabList[to].timeLine->setFrameRange(tabList[to].dragOffset, 0);
    1669     animations[tabList[to].timeLine] = to;
    1670     tabList[to].timeLine->setDuration(ANIMATION_DURATION);
    1671     if (tabList[to].timeLine->state() != QTimeLine::Running)
    1672         tabList[to].timeLine->start();
    1673 }
    1674 
    1675 void QTabBarPrivate::_q_moveTab(int offset)
    1676 {
    1677     Q_Q(QTabBar);
    1678     if (QTimeLine *timeLine = qobject_cast<QTimeLine *>(q->sender())) {
    1679         int index = animations[timeLine];
    1680         if (!validIndex(index))
    1681             return;
    1682         tabList[index].dragOffset = offset;
    1683         q->update();
    1684     }
     1670    tabList[to].dragOffset -= length;
     1671    tabList[to].startAnimation(this, ANIMATION_DURATION);
     1672}
     1673
     1674void QTabBarPrivate::moveTab(int index, int offset)
     1675{
     1676    if (!validIndex(index))
     1677        return;
     1678    tabList[index].dragOffset = offset;
     1679    layoutTab(index); // Make buttons follow tab
     1680    q_func()->update();
    16851681}
    16861682
     
    16961692    // Be safe!
    16971693    if (d->pressedIndex != -1 && d->movable)
    1698         d->_q_moveTabFinished(d->pressedIndex);
     1694        d->moveTabFinished(d->pressedIndex);
    16991695
    17001696    d->pressedIndex = d->indexAtPos(event->pos());
     1697#ifdef Q_WS_MAC
     1698    d->previousPressedIndex = d->pressedIndex;
     1699#endif
    17011700    if (d->validIndex(d->pressedIndex)) {
    17021701        QStyleOptionTabBarBaseV2 optTabBase;
     
    17221721        if (d->pressedIndex != -1
    17231722            && event->buttons() == Qt::NoButton)
    1724             d->_q_moveTabFinished(d->pressedIndex);
     1723            d->moveTabFinished(d->pressedIndex);
    17251724       
    17261725        // Start drag
     
    17281727            if ((event->pos() - d->dragStartPosition).manhattanLength() > QApplication::startDragDistance()) {
    17291728                d->dragInProgress = true;
    1730                 if (d->animations.isEmpty())
    1731                     d->grabCache(0, d->tabList.count(), false);
     1729                d->setupMovableTab();
    17321730            }
    17331731        }
     
    17741772                        d->slide(i + offset, d->pressedIndex);
    17751773                }
    1776 
    17771774            }
    17781775            // Buttons needs to follow the dragged tab
     
    17811778            update();
    17821779        }
     1780#ifdef Q_WS_MAC
     1781    } else if (!d->documentMode && event->buttons() == Qt::LeftButton && d->previousPressedIndex != -1) {
     1782        int newPressedIndex = d->indexAtPos(event->pos());
     1783        if (d->pressedIndex == -1 && d->previousPressedIndex == newPressedIndex) {
     1784            d->pressedIndex = d->previousPressedIndex;
     1785            update(tabRect(d->pressedIndex));
     1786        } else if(d->pressedIndex != newPressedIndex) {
     1787            d->pressedIndex = -1;
     1788            update(tabRect(d->previousPressedIndex));
     1789        }
     1790#endif
    17831791    }
    17841792
     
    17921800}
    17931801
    1794 void QTabBarPrivate::_q_moveTabFinished()
     1802void QTabBarPrivate::setupMovableTab()
    17951803{
    17961804    Q_Q(QTabBar);
    1797     if (QTimeLine *timeLine = qobject_cast<QTimeLine *>(q->sender())) {
    1798         int index = animations[timeLine];
    1799         animations.remove(timeLine);
    1800         _q_moveTabFinished(index);
    1801     }
    1802 }
    1803 
    1804 void QTabBarPrivate::grabCache(int start, int end, bool unhide)
    1805 {
    1806     Q_Q(QTabBar);
    1807     paintWithOffsets = false;
    1808     bool showButtonsAgain = rightB->isVisible();
    1809     rightB->hide();
    1810     leftB->hide();
    1811 
    1812     QWidget *topLevel = q->window();
    1813     QPoint topLevelOffset(q->mapTo(topLevel, QPoint()));
    1814     for (int i = start; i < end; ++i) {
    1815         QRect tabRect = q->tabRect(i);
    1816         tabRect.translate(topLevelOffset);
    1817         if (unhide) {
    1818             tabList[i].unHideWidgets();
    1819             layoutWidgets(i);
    1820         }
    1821         tabList[i].animatingCache = QPixmap::grabWidget(topLevel, tabRect);
    1822         if (i != pressedIndex)
    1823             tabList[i].hideWidgets();
    1824     }
    1825     if (showButtonsAgain) {
    1826         rightB->show();
    1827         leftB->show();
    1828     }
    1829     paintWithOffsets = true;
    1830 }
    1831 
    1832 void QTabBarPrivate::_q_moveTabFinished(int index)
     1805    if (!movingTab)
     1806        movingTab = new QWidget(q);
     1807
     1808    int taboverlap = q->style()->pixelMetric(QStyle::PM_TabBarTabOverlap, 0 ,q);
     1809    QRect grabRect = q->tabRect(pressedIndex);
     1810    grabRect.adjust(-taboverlap, 0, taboverlap, 0);
     1811
     1812    QPixmap grabImage(grabRect.size());
     1813    grabImage.fill(Qt::transparent);
     1814    QStylePainter p(&grabImage, q);
     1815    p.initFrom(q);
     1816
     1817    QStyleOptionTabV3 tab;
     1818    q->initStyleOption(&tab, pressedIndex);
     1819    tab.rect.moveTopLeft(QPoint(taboverlap, 0));
     1820    p.drawControl(QStyle::CE_TabBarTab, tab);
     1821    p.end();
     1822
     1823    QPalette pal;
     1824    pal.setBrush(QPalette::All, QPalette::Window, grabImage);
     1825    movingTab->setPalette(pal);
     1826    movingTab->setGeometry(grabRect);
     1827    movingTab->setAutoFillBackground(true);
     1828    movingTab->raise();
     1829
     1830    // Re-arrange widget order to avoid overlaps
     1831    if (tabList[pressedIndex].leftWidget)
     1832        tabList[pressedIndex].leftWidget->raise();
     1833    if (tabList[pressedIndex].rightWidget)
     1834        tabList[pressedIndex].rightWidget->raise();
     1835    if (leftB)
     1836        leftB->raise();
     1837    if (rightB)
     1838        rightB->raise();
     1839    movingTab->setVisible(true);
     1840}
     1841
     1842void QTabBarPrivate::moveTabFinished(int index)
    18331843{
    18341844    Q_Q(QTabBar);
    18351845    bool cleanup = (pressedIndex == index) || (pressedIndex == -1) || !validIndex(index);
    1836     if (animations.isEmpty() && cleanup) {
     1846    bool allAnimationsFinished = true;
     1847#ifndef QT_NO_ANIMATION
     1848    for(int i = 0; allAnimationsFinished && i < tabList.count(); ++i) {
     1849        const Tab &t = tabList.at(i);
     1850        if (t.animation && t.animation->state() == QAbstractAnimation::Running)
     1851            allAnimationsFinished = false;
     1852    }
     1853#endif //QT_NO_ANIMATION
     1854    if (allAnimationsFinished && cleanup) {
     1855        if(movingTab)
     1856            movingTab->setVisible(false); // We might not get a mouse release
    18371857        for (int i = 0; i < tabList.count(); ++i) {
    18381858            tabList[i].dragOffset = 0;
    1839             tabList[i].unHideWidgets();
    1840             tabList[i].animatingCache = QPixmap();
    18411859        }
    18421860        if (pressedIndex != -1 && movable) {
     
    18631881        return;
    18641882    }
    1865 
     1883#ifdef Q_WS_MAC
     1884    d->previousPressedIndex = -1;
     1885#endif
    18661886    if (d->movable && d->dragInProgress && d->validIndex(d->pressedIndex)) {
    18671887        int length = d->tabList[d->pressedIndex].dragOffset;
     
    18701890            : tabRect(d->pressedIndex).width();
    18711891        int duration = qMin(ANIMATION_DURATION,
    1872                 ((length < 0 ? (-1 * length) : length) * ANIMATION_DURATION) / width);
    1873         if (duration > 0) {
    1874             d->tabList[d->pressedIndex].makeTimeLine(this);
    1875             d->tabList[d->pressedIndex].timeLine->setFrameRange(length, 0);
    1876             d->animations[d->tabList[d->pressedIndex].timeLine] = d->pressedIndex;
    1877             d->tabList[d->pressedIndex].timeLine->setDuration(duration);
    1878             if (d->tabList[d->pressedIndex].timeLine->state() != QTimeLine::Running)
    1879                 d->tabList[d->pressedIndex].timeLine->start();
    1880         } else {
    1881             d->_q_moveTabFinished(d->pressedIndex);
    1882         }
     1892                (qAbs(length) * ANIMATION_DURATION) / width);
     1893        d->tabList[d->pressedIndex].startAnimation(d, duration);
    18831894        d->dragInProgress = false;
     1895        d->movingTab->setVisible(false);
    18841896        d->dragStartPosition = QPoint();
    18851897    }
     
    19031915        return;
    19041916    }
    1905     int dx = event->key() == (isRightToLeft() ? Qt::Key_Right : Qt::Key_Left) ? -1 : 1;
    1906     for (int index = d->currentIndex + dx; d->validIndex(index); index += dx) {
    1907         if (d->tabList.at(index).enabled) {
    1908             setCurrentIndex(index);
    1909             break;
    1910         }
    1911     }
     1917    int offset = event->key() == (isRightToLeft() ? Qt::Key_Right : Qt::Key_Left) ? -1 : 1;   
     1918    d->setCurrentNextEnabledIndex(offset);
    19121919}
    19131920
     
    19181925{
    19191926    Q_D(QTabBar);
    1920     int overIndex = d->indexAtPos(event->pos());
    1921     if (overIndex != -1) {
    1922         int offset = event->delta() > 0 ? -1 : 1;
    1923         setCurrentIndex(currentIndex() + offset);
    1924     }
     1927    int offset = event->delta() > 0 ? -1 : 1;
     1928    d->setCurrentNextEnabledIndex(offset);
    19251929    QWidget::wheelEvent(event);
    19261930}
    19271931#endif //QT_NO_WHEELEVENT
     1932
     1933void QTabBarPrivate::setCurrentNextEnabledIndex(int offset)
     1934{
     1935    Q_Q(QTabBar);
     1936    for (int index = currentIndex + offset; validIndex(index); index += offset) {
     1937        if (tabList.at(index).enabled) {
     1938            q->setCurrentIndex(index);
     1939            break;
     1940        }
     1941    }
     1942}
    19281943
    19291944/*!\reimp
     
    19341949    if (event->type() == QEvent::StyleChange) {
    19351950        d->elideMode = Qt::TextElideMode(style()->styleHint(QStyle::SH_TabBar_ElideMode, 0, this));
    1936         d->useScrollButtons = !style()->styleHint(QStyle::SH_TabBar_PreferNoArrows, 0, this);
    1937     }
    1938     d->refresh();
     1951        if (!d->useScrollButtonsSetByUser)
     1952            d->useScrollButtons = !style()->styleHint(QStyle::SH_TabBar_PreferNoArrows, 0, this);
     1953        d->refresh();
     1954    } else if (event->type() == QEvent::FontChange) {
     1955        d->refresh();
     1956    }
    19391957    QWidget::changeEvent(event);
    19401958}
     
    19872005{
    19882006    Q_D(QTabBar);
     2007    d->useScrollButtonsSetByUser = true;
    19892008    if (d->useScrollButtons == useButtons)
    19902009        return;
     
    22042223        // make sure our left and right widgets stay on top
    22052224        widget->lower();
     2225        widget->show();
    22062226    }
    22072227    if (position == LeftSide) {
     
    22092229            d->tabList[index].leftWidget->hide();
    22102230        d->tabList[index].leftWidget = widget;
    2211         if(!d->tabList[index].hidLeft && widget)
    2212             widget->show();
    22132231    } else {
    22142232        if (d->tabList[index].rightWidget)
    22152233            d->tabList[index].rightWidget->hide();
    22162234        d->tabList[index].rightWidget = widget;
    2217         if(!d->tabList[index].hidRight && widget)
    2218             widget->show();
    22192235    }
    22202236    d->layoutTabs();
     2237    d->refresh();
    22212238    update();
    22222239}
  • trunk/src/gui/widgets/qtabbar.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    216216    Q_PRIVATE_SLOT(d_func(), void _q_scrollTabs())
    217217    Q_PRIVATE_SLOT(d_func(), void _q_closeTab())
    218     Q_PRIVATE_SLOT(d_func(), void _q_moveTab(int))
    219     Q_PRIVATE_SLOT(d_func(), void _q_moveTabFinished())
    220218};
    221219
  • trunk/src/gui/widgets/qtabbar_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5959#include <qicon.h>
    6060#include <qtoolbutton.h>
    61 #include <qtimeline.h>
    62 #include <qhash.h>
    6361#include <qdebug.h>
     62#include <qvariantanimation.h>
    6463
    6564#ifndef QT_NO_TABBAR
     
    7069
    7170QT_BEGIN_NAMESPACE
    72 
    7371
    7472class QTabBarPrivate  : public QWidgetPrivate
     
    7775public:
    7876    QTabBarPrivate()
    79         :currentIndex(-1), pressedIndex(-1),
    80          shape(QTabBar::RoundedNorth),
    81          layoutDirty(false), drawBase(true), scrollOffset(0), expanding(true), closeButtonOnTabs(false), selectionBehaviorOnRemove(QTabBar::SelectRightTab), paintWithOffsets(true), movable(false), dragInProgress(false), documentMode(false) {}
     77        :currentIndex(-1), pressedIndex(-1), shape(QTabBar::RoundedNorth), layoutDirty(false),
     78        drawBase(true), scrollOffset(0), useScrollButtonsSetByUser(false) , expanding(true), closeButtonOnTabs(false),
     79        selectionBehaviorOnRemove(QTabBar::SelectRightTab), paintWithOffsets(true), movable(false),
     80        dragInProgress(false), documentMode(false), movingTab(0)
     81#ifdef Q_WS_MAC
     82        , previousPressedIndex(-1)
     83#endif
     84        {}
    8285
    8386    int currentIndex;
     
    9093    struct Tab {
    9194        inline Tab(const QIcon &ico, const QString &txt)
    92             : enabled(true)
    93             , shortcutId(0)
    94             , text(txt)
    95             , icon(ico)
    96             , leftWidget(0)
    97             , rightWidget(0)
    98             , lastTab(-1)
    99             , timeLine(0)
    100             , dragOffset(0)
    101             , hidLeft(false)
    102             , hidRight(false)
     95            : enabled(true) , shortcutId(0), text(txt), icon(ico),
     96            leftWidget(0), rightWidget(0), lastTab(-1), dragOffset(0)
     97#ifndef QT_NO_ANIMATION
     98            , animation(0)
     99#endif //QT_NO_ANIMATION
    103100        {}
     101        bool operator==(const Tab &other) const { return &other == this; }
    104102        bool enabled;
    105103        int shortcutId;
     
    121119        QWidget *rightWidget;
    122120        int lastTab;
    123 
    124         QTimeLine *timeLine;
    125121        int dragOffset;
    126         QPixmap animatingCache;
    127         bool hidLeft;
    128         bool hidRight;
    129 
    130         void makeTimeLine(QWidget *q) {
    131             if (timeLine)
    132                 return;
    133             timeLine = new QTimeLine(ANIMATION_DURATION, q);
    134             q->connect(timeLine, SIGNAL(frameChanged(int)), q, SLOT(_q_moveTab(int)));
    135             q->connect(timeLine, SIGNAL(finished()), q, SLOT(_q_moveTabFinished()));
     122
     123#ifndef QT_NO_ANIMATION
     124        ~Tab() { delete animation; }
     125        struct TabBarAnimation : public QVariantAnimation {
     126            TabBarAnimation(Tab *t, QTabBarPrivate *_priv) : tab(t), priv(_priv)
     127            { setEasingCurve(QEasingCurve::InOutQuad); }
     128
     129            void updateCurrentValue(const QVariant &current)
     130            { priv->moveTab(priv->tabList.indexOf(*tab), current.toInt()); }
     131
     132            void updateState(State, State newState)
     133            { if (newState == Stopped) priv->moveTabFinished(priv->tabList.indexOf(*tab)); }
     134        private:
     135            //these are needed for the callbacks
     136            Tab *tab;
     137            QTabBarPrivate *priv;
     138        } *animation;
     139
     140        void startAnimation(QTabBarPrivate *priv, int duration) {
     141            if (!animation)
     142                animation = new TabBarAnimation(this, priv);
     143            animation->setStartValue(dragOffset);
     144            animation->setEndValue(0);
     145            animation->setDuration(duration);
     146            animation->start();
    136147        }
    137 
    138         void hideWidgets() {
    139             if (!hidRight && rightWidget) {
    140                 hidRight = rightWidget->isVisible();
    141                 rightWidget->hide();
    142             }
    143 
    144             if (!hidLeft && leftWidget) {
    145                 hidLeft = leftWidget->isVisible();
    146                 leftWidget->hide();
    147             }
    148         }
    149 
    150         void unHideWidgets() {
    151             if (leftWidget && hidLeft)
    152                 leftWidget->show();
    153             hidLeft = false;
    154             if (rightWidget && hidRight)
    155                 rightWidget->show();
    156             hidRight = false;
    157         }
    158 
     148#else
     149        void startAnimation(QTabBarPrivate *priv, int duration)
     150        { Q_UNUSED(duration); priv->moveTabFinished(priv->tabList.indexOf(*this)); }
     151#endif //QT_NO_ANIMATION
    159152    };
    160153    QList<Tab> tabList;
    161     QHash<QTimeLine*, int> animations;
    162154
    163155    int calculateNewPosition(int from, int to, int index) const;
     
    172164
    173165    inline bool validIndex(int index) const { return index >= 0 && index < tabList.count(); }
     166    void setCurrentNextEnabledIndex(int offset);
    174167
    175168    QSize minimumTabSizeHint(int index);
     
    180173    void _q_scrollTabs();
    181174    void _q_closeTab();
    182     void _q_moveTab(int);
    183     void _q_moveTabFinished();
    184     void _q_moveTabFinished(int offset);
     175    void moveTab(int index, int offset);
     176    void moveTabFinished(int index);
    185177    QRect hoverRect;
    186178
    187     void grabCache(int start, int end, bool unhide);
    188179    void refresh();
    189180    void layoutTabs();
     
    191182    void layoutTab(int index);
    192183    void updateMacBorderMetrics();
     184    void setupMovableTab();
    193185
    194186    void makeVisible(int index);
     
    196188    Qt::TextElideMode elideMode;
    197189    bool useScrollButtons;
     190    bool useScrollButtonsSetByUser;
    198191
    199192    bool expanding;
     
    207200    bool documentMode;
    208201
     202    QWidget *movingTab;
     203#ifdef Q_WS_MAC
     204    int previousPressedIndex;
     205#endif
    209206    // shared by tabwidget and qtabbar
    210207    static void initStyleBaseOption(QStyleOptionTabBarBaseV2 *optTabBase, QTabBar *tabbar, QSize size)
  • trunk/src/gui/widgets/qtabwidget.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6565    \ingroup organizers
    6666    \ingroup basicwidgets
    67     \mainclass
     67
    6868
    6969    A tab widget provides a tab bar (see QTabBar) and a "page area"
     
    314314        break;
    315315    }
     316
    316317    option->tabBarSize = t;
     318
     319    if (QStyleOptionTabWidgetFrameV2 *tabframe = qstyleoption_cast<QStyleOptionTabWidgetFrameV2*>(option)) {
     320        QRect tbRect = tabBar()->geometry();
     321        QRect selectedTabRect = tabBar()->tabRect(tabBar()->currentIndex());
     322        tabframe->tabBarRect = tbRect;
     323        selectedTabRect.moveTopLeft(selectedTabRect.topLeft() + tbRect.topLeft());
     324        tabframe->selectedTabRect = selectedTabRect;
     325    }
    317326}
    318327
     
    505514
    506515/*!
    507     Returns true if the the page at position \a index is enabled; otherwise returns false.
     516    Returns true if the page at position \a index is enabled; otherwise returns false.
    508517
    509518    \sa setTabEnabled(), QWidget::isEnabled()
     
    691700    connect(d->tabs, SIGNAL(currentChanged(int)),
    692701            this, SLOT(_q_showTab(int)));
    693     connect(d->tabs, SIGNAL(tabMoved(int, int)),
    694             this, SLOT(_q_tabMoved(int, int)));
     702    connect(d->tabs, SIGNAL(tabMoved(int,int)),
     703            this, SLOT(_q_tabMoved(int,int)));
    695704    if (d->tabs->tabsClosable())
    696705        connect(d->tabs, SIGNAL(tabCloseRequested(int)),
     
    757766        return; // nothing to do
    758767
    759     QStyleOptionTabWidgetFrame option;
     768    QStyleOptionTabWidgetFrameV2 option;
    760769    initStyleOption(&option);
    761770
     
    10581067            }
    10591068        }
    1060         if (!qApp->focusWidget())
     1069        if (!QApplication::focusWidget())
    10611070            d->tabs->setFocus();
    10621071    } else {
     
    11681177{
    11691178    Q_D(QTabWidget);
    1170     QStylePainter p(this);
    11711179    if (documentMode()) {
     1180        QStylePainter p(this, tabBar());
    11721181        if (QWidget *w = cornerWidget(Qt::TopLeftCorner)) {
    11731182            QStyleOptionTabBarBaseV2 opt;
     
    11861195        return;
    11871196    }
    1188 
    1189     QStyleOptionTabWidgetFrame opt;
     1197    QStylePainter p(this);
     1198
     1199    QStyleOptionTabWidgetFrameV2 opt;
    11901200    initStyleOption(&opt);
    11911201    opt.rect = d->panelRect;
  • trunk/src/gui/widgets/qtabwidget.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qtextbrowser.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    264264#ifndef QT_NO_CURSOR
    265265    if (q->isVisible())
    266         qApp->setOverrideCursor(Qt::WaitCursor);
     266        QApplication::setOverrideCursor(Qt::WaitCursor);
    267267#endif
    268268    textOrSourceChanged = true;
     
    296296        if (q->isVisible()) {
    297297            QString firstTag = txt.left(txt.indexOf(QLatin1Char('>')) + 1);
    298             if (firstTag.left(3) == QLatin1String("<qt") && firstTag.contains(QLatin1String("type")) && firstTag.contains(QLatin1String("detail"))) {
     298            if (firstTag.startsWith(QLatin1String("<qt")) && firstTag.contains(QLatin1String("type")) && firstTag.contains(QLatin1String("detail"))) {
    299299#ifndef QT_NO_CURSOR
    300                 qApp->restoreOverrideCursor();
     300                QApplication::restoreOverrideCursor();
    301301#endif
    302302#ifndef QT_NO_WHATSTHIS
     
    343343#ifndef QT_NO_CURSOR
    344344    if (q->isVisible())
    345         qApp->restoreOverrideCursor();
     345        QApplication::restoreOverrideCursor();
    346346#endif
    347347    emit q->sourceChanged(url);
     
    581581    \brief The QTextBrowser class provides a rich text browser with hypertext navigation.
    582582
    583     \ingroup text
     583    \ingroup richtext-processing
    584584
    585585    This class extends QTextEdit (in read-only mode), adding some navigation
  • trunk/src/gui/widgets/qtextbrowser.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qtextedit.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    7575
    7676#ifndef QT_NO_TEXTEDIT
     77static inline bool shouldEnableInputMethod(QTextEdit *textedit)
     78{
     79    return !textedit->isReadOnly();
     80}
    7781
    7882class QTextEditControl : public QTextControl
     
    106110      autoFormatting(QTextEdit::AutoNone), tabChangesFocus(false),
    107111      lineWrap(QTextEdit::WidgetWidth), lineWrapColumnOrWidth(0),
    108       wordWrap(QTextOption::WrapAtWordBoundaryOrAnywhere), textFormat(Qt::AutoText)
     112      wordWrap(QTextOption::WrapAtWordBoundaryOrAnywhere), clickCausedFocus(0),
     113      textFormat(Qt::AutoText)
    109114{
    110115    ignoreAutomaticScrollbarAdjustment = false;
     
    153158    QObject::connect(control, SIGNAL(selectionChanged()), q, SIGNAL(selectionChanged()));
    154159    QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SIGNAL(cursorPositionChanged()));
     160
     161    QObject::connect(control, SIGNAL(textChanged()), q, SLOT(updateMicroFocus()));
    155162
    156163    QTextDocument *doc = control->document();
     
    178185#ifndef QT_NO_CURSOR
    179186    viewport->setCursor(Qt::IBeamCursor);
     187#endif
     188#ifdef Q_WS_WIN
     189    setSingleFingerPanEnabled(true);
    180190#endif
    181191}
     
    329339    both plain and rich text.
    330340
    331     \ingroup text
    332     \mainclass
     341    \ingroup richtext-processing
     342
    333343
    334344    \tableofcontents
     
    523533
    524534    If the text edit has another content type, it will not be replaced
    525     by plain text if you call toPlainText().
     535    by plain text if you call toPlainText(). The only exception to this
     536    is the non-break space, \e{nbsp;}, that will be converted into
     537    standard space.
    526538
    527539    By default, for an editor with no contents, this property contains
     
    12031215                    if (e->text()[0].isPrint()) {
    12041216                        setEditFocus(true);
     1217#ifndef Q_OS_SYMBIAN
    12051218                        clear();
     1219#endif
    12061220                    } else {
    12071221                        e->ignore();
     
    12131227    }
    12141228#endif
    1215 
    1216     if (!(d->control->textInteractionFlags() & Qt::TextEditable)) {
     1229#ifndef QT_NO_SHORTCUT
     1230
     1231    Qt::TextInteractionFlags tif = d->control->textInteractionFlags();
     1232
     1233    if (tif & Qt::TextSelectableByKeyboard){
     1234        if (e == QKeySequence::SelectPreviousPage) {
     1235            e->accept();
     1236            d->pageUpDown(QTextCursor::Up, QTextCursor::KeepAnchor);
     1237            return;
     1238        } else if (e ==QKeySequence::SelectNextPage) {
     1239            e->accept();
     1240            d->pageUpDown(QTextCursor::Down, QTextCursor::KeepAnchor);
     1241            return;
     1242        }
     1243    }
     1244    if (tif & (Qt::TextSelectableByKeyboard | Qt::TextEditable)) {
     1245        if (e == QKeySequence::MoveToPreviousPage) {
     1246            e->accept();
     1247            d->pageUpDown(QTextCursor::Up, QTextCursor::MoveAnchor);
     1248            return;
     1249        } else if (e == QKeySequence::MoveToNextPage) {
     1250            e->accept();
     1251            d->pageUpDown(QTextCursor::Down, QTextCursor::MoveAnchor);
     1252            return;
     1253        }
     1254    }
     1255
     1256    if (!(tif & Qt::TextEditable)) {
    12171257        switch (e->key()) {
    12181258            case Qt::Key_Space:
     
    12391279        }
    12401280        return;
    1241     }
    1242 
    1243 #ifndef QT_NO_SHORTCUT
    1244     if (e == QKeySequence::MoveToPreviousPage) {
    1245             e->accept();
    1246             d->pageUpDown(QTextCursor::Up, QTextCursor::MoveAnchor);
    1247             return;
    1248     } else if (e == QKeySequence::MoveToNextPage) {
    1249             e->accept();
    1250             d->pageUpDown(QTextCursor::Down, QTextCursor::MoveAnchor);
    1251             return;
    1252     } else if (e == QKeySequence::SelectPreviousPage) {
    1253             e->accept();
    1254             d->pageUpDown(QTextCursor::Up, QTextCursor::KeepAnchor);
    1255             return;
    1256     } else if (e ==QKeySequence::SelectNextPage) {
    1257             e->accept();
    1258             d->pageUpDown(QTextCursor::Down, QTextCursor::KeepAnchor);
    1259             return;
    12601281    }
    12611282#endif // QT_NO_SHORTCUT
     
    15601581        ensureCursorVisible();
    15611582    }
     1583    if (!isReadOnly() && rect().contains(e->pos()))
     1584        d->handleSoftwareInputPanel(e->button(), d->clickCausedFocus);
     1585    d->clickCausedFocus = 0;
    15621586}
    15631587
     
    16561680        && !hasEditFocus()) {
    16571681        setEditFocus(true);
     1682#ifndef Q_OS_SYMBIAN
    16581683        selectAll();    // so text is replaced rather than appended to
     1684#endif
    16591685    }
    16601686#endif
    16611687    d->sendControlEvent(e);
     1688    ensureCursorVisible();
    16621689}
    16631690
     
    16951722{
    16961723    Q_D(QTextEdit);
     1724    if (e->reason() == Qt::MouseFocusReason) {
     1725        d->clickCausedFocus = 1;
     1726    }
    16971727    QAbstractScrollArea::focusInEvent(e);
    16981728    d->sendControlEvent(e);
     
    18791909    \since 4.1
    18801910
    1881     By default, this property contains a value of 80.
     1911    By default, this property contains a value of 80 pixels.
    18821912*/
    18831913
     
    20592089        flags = Qt::TextEditorInteraction;
    20602090    }
    2061     setAttribute(Qt::WA_InputMethodEnabled, !ro);
    20622091    d->control->setTextInteractionFlags(flags);
     2092    setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod(this));
    20632093}
    20642094
     
    26102640}
    26112641
    2612 
    26132642/*!
    26142643    \enum QTextEdit::KeyboardAction
  • trunk/src/gui/widgets/qtextedit.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qtextedit_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    7171
    7272class QMimeData;
    73 
    7473class QTextEditPrivate : public QAbstractScrollAreaPrivate
    7574{
     
    124123    uint showCursorOnInitialShow : 1;
    125124    uint inDrag : 1;
     125    uint clickCausedFocus : 1;
    126126
    127127    // Qt3 COMPAT only, for setText
  • trunk/src/gui/widgets/qtoolbar.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    7171#include  "qdebug.h"
    7272
     73#define POPUP_TIMER_INTERVAL 500
     74
    7375QT_BEGIN_NAMESPACE
    7476
     
    8890{
    8991    Q_Q(QToolBar);
    90 
    91     waitForPopupTimer = new QTimer(q);
    92     waitForPopupTimer->setSingleShot(false);
    93     waitForPopupTimer->setInterval(500);
    94     QObject::connect(waitForPopupTimer, SIGNAL(timeout()), q, SLOT(_q_waitForPopup()));
    95 
    96     floatable = true;
    97     movable = true;
    9892    q->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed));
    9993    q->setBackgroundRole(QPalette::Button);
     
    190184    if (visible)
    191185        q->show();
     186
     187    if (floating != wasFloating)
     188        emit q->topLevelChanged(floating);
    192189}
    193190
     
    199196        return;
    200197
    201     QMainWindow *win = qobject_cast<QMainWindow*>(q->parentWidget());
     198    QMainWindow *win = qobject_cast<QMainWindow*>(parent);
    202199    Q_ASSERT(win != 0);
    203200    QMainWindowLayout *layout = qobject_cast<QMainWindowLayout*>(win->layout());
     
    212209    state->widgetItem = 0;
    213210
    214     if (q->layoutDirection() == Qt::RightToLeft)
     211    if (q->isRightToLeft())
    215212        state->pressPos = QPoint(q->width() - state->pressPos.x(), state->pressPos.y());
    216213}
     
    225222        return;
    226223
    227     QMainWindow *win = qobject_cast<QMainWindow*>(q->parentWidget());
     224    QMainWindow *win = qobject_cast<QMainWindow*>(parent);
    228225    Q_ASSERT(win != 0);
    229226    QMainWindowLayout *layout = qobject_cast<QMainWindowLayout*>(win->layout());
     
    275272bool QToolBarPrivate::mousePressEvent(QMouseEvent *event)
    276273{
    277     if (layout->handleRect().contains(event->pos()) == false) {
     274    Q_Q(QToolBar);
     275    QStyleOptionToolBar opt;
     276    q->initStyleOption(&opt);
     277    if (q->style()->subElementRect(QStyle::SE_ToolBarHandle, &opt, q).contains(event->pos()) == false) {
    278278#ifdef Q_WS_MAC
    279         Q_Q(QToolBar);
    280279        // When using the unified toolbar on Mac OS X the user can can click and
    281280        // drag between toolbar contents to move the window. Make this work by
    282281        // implementing the standard mouse-dragging code and then call
    283282        // window->move() in mouseMoveEvent below.
    284         if (QMainWindow *mainWindow = qobject_cast<QMainWindow *>(q->parentWidget())) {
     283        if (QMainWindow *mainWindow = qobject_cast<QMainWindow *>(parent)) {
    285284            if (mainWindow->toolBarArea(q) == Qt::TopToolBarArea
    286285                    && mainWindow->unifiedTitleAndToolBarOnMac()
     
    312311    } else {
    313312#ifdef Q_WS_MAC
     313        if (!macWindowDragging)
     314            return false;
    314315        macWindowDragging = false;
    315316        macWindowDragPressPosition = QPoint();
     
    336337    }
    337338
    338     QMainWindow *win = qobject_cast<QMainWindow*>(q->parentWidget());
     339    QMainWindow *win = qobject_cast<QMainWindow*>(parent);
    339340    if (win == 0)
    340341        return true;
     
    364365        // if we are right-to-left, we move so as to keep the right edge the same distance
    365366        // from the mouse
    366         if (q->layoutDirection() == Qt::LeftToRight)
     367        if (q->isLeftToRight())
    367368            pos -= state->pressPos;
    368369        else
     
    374375
    375376        const QPoint rtl(q->width() - state->pressPos.x(), state->pressPos.y()); //for RTL
    376         const QPoint globalPressPos = q->mapToGlobal(q->layoutDirection() == Qt::RightToLeft ? rtl : state->pressPos);
     377        const QPoint globalPressPos = q->mapToGlobal(q->isRightToLeft() ? rtl : state->pressPos);
    377378        int pos = 0;
    378379
     
    381382            pos = q->y() + delta.y();
    382383        } else {
    383             if (q->layoutDirection() == Qt::RightToLeft) {
     384            if (q->isRightToLeft()) {
    384385                pos = win->width() - q->width() - q->x()  - delta.x();
    385386            } else {
     
    396397{
    397398    Q_Q(QToolBar);
    398 
    399399    QRect r = _r;
    400400    r.moveTopLeft(q->mapToGlobal(QPoint(0, 0)));
    401401    setWindowState(true, true, r);
     402    layout->setExpanded(false);
    402403}
    403404
     
    417418    set of controls.
    418419
    419     \ingroup application
    420     \mainclass
     420    \ingroup mainwindow-classes
     421
    421422
    422423    Toolbar buttons are added by adding \e actions, using addAction()
     
    519520    \sa toolButtonStyle QMainWindow::toolButtonStyle
    520521*/
     522
     523/*!
     524    \since 4.6
     525
     526    \fn void QToolBar::topLevelChanged(bool topLevel)
     527
     528    This signal is emitted when the \l floating property changes.
     529    The \a topLevel parameter is true if the toolbar is now floating;
     530    otherwise it is false.
     531
     532    \sa isWindow()
     533*/
     534
    521535
    522536/*!
     
    879893    Qt::ToolButtonStyle will not be respected.
    880894
    881     Note: You should use QAction::setVisible() to change the
     895    \note You should use QAction::setVisible() to change the
    882896    visibility of the widget. Using QWidget::setVisible(),
    883897    QWidget::show() and QWidget::hide() does not work.
     
    10421056    }
    10431057
    1044     opt.rect = d->layout->handleRect();
     1058    opt.rect = style->subElementRect(QStyle::SE_ToolBarHandle, &opt, this);
    10451059    if (opt.rect.isValid())
    10461060        style->drawPrimitive(QStyle::PE_IndicatorToolBarHandle, &opt, &p, this);
     
    10791093}
    10801094
     1095#if defined(Q_WS_MAC)
     1096static bool toolbarInUnifiedToolBar(QToolBar *toolbar)
     1097{
     1098    const QMainWindow *mainWindow = qobject_cast<const QMainWindow *>(toolbar->parentWidget());
     1099    return mainWindow && mainWindow->unifiedTitleAndToolBarOnMac()
     1100            && mainWindow->toolBarArea(toolbar) == Qt::TopToolBarArea;
     1101}
     1102#endif
     1103
    10811104/*! \reimp */
    10821105bool QToolBar::event(QEvent *event)
     
    10851108
    10861109    switch (event->type()) {
     1110    case QEvent::Timer:
     1111        if (d->waitForPopupTimer.timerId() == static_cast<QTimerEvent*>(event)->timerId()) {
     1112            QWidget *w = QApplication::activePopupWidget();
     1113            if (!waitForPopup(this, w)) {
     1114                d->waitForPopupTimer.stop();
     1115                if (!this->underMouse())
     1116                    d->layout->setExpanded(false);
     1117            }
     1118        }
     1119        break;
    10871120    case QEvent::Hide:
    10881121        if (!isHidden())
     
    10911124    case QEvent::Show:
    10921125        d->toggleViewAction->setChecked(event->type() == QEvent::Show);
    1093 #if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)
     1126#if defined(Q_WS_MAC)
     1127        if (toolbarInUnifiedToolBar(this)) {
     1128             // I can static_cast because I did the qobject_cast in the if above, therefore
     1129            // we must have a QMainWindowLayout here.
     1130            QMainWindowLayout *mwLayout = static_cast<QMainWindowLayout *>(parentWidget()->layout());
     1131            mwLayout->fixSizeInUnifiedToolbar(this);
     1132            mwLayout->syncUnifiedToolbarVisibility();
     1133        }
     1134#  if !defined(QT_MAC_USE_COCOA)
    10941135        // Fall through
    10951136    case QEvent::LayoutRequest: {
     
    11061147
    11071148            if (needUpdate) {
    1108                 OSWindowRef windowRef = qt_mac_window_for(this);
    1109                 if (mainWindow->unifiedTitleAndToolBarOnMac()
    1110                         && mainWindow->toolBarArea(this) == Qt::TopToolBarArea
    1111                         && macWindowToolbarVisible(windowRef))   {
     1149                OSWindowRef windowRef = qt_mac_window_for(mainWindow);
     1150                if (toolbarInUnifiedToolBar(this)
     1151                        && macWindowToolbarIsVisible(windowRef))   {
    11121152                    DisableScreenUpdates();
    11131153                    macWindowToolbarShow(this, false);
     
    11211161        }
    11221162    }
    1123 #endif
     1163#  endif // !QT_MAC_USE_COCOA
     1164#endif // Q_WS_MAC
    11241165        break;
    11251166    case QEvent::ParentChange:
     
    11401181            return true;
    11411182        break;
     1183    case QEvent::HoverEnter:
     1184    case QEvent::HoverLeave:
     1185        // there's nothing special to do here and we don't want to update the whole widget
     1186        return true;
    11421187    case QEvent::HoverMove: {
    11431188#ifndef QT_NO_CURSOR
    11441189        QHoverEvent *e = static_cast<QHoverEvent*>(event);
    1145         if (d->layout->handleRect().contains(e->pos()))
     1190        QStyleOptionToolBar opt;
     1191        initStyleOption(&opt);
     1192        if (style()->subElementRect(QStyle::SE_ToolBarHandle, &opt, this).contains(e->pos()))
    11461193            setCursor(Qt::SizeAllCursor);
    11471194        else
     
    11541201            return true;
    11551202        break;
    1156 #ifdef Q_OS_WINCE
     1203#ifdef Q_WS_WINCE
    11571204    case QEvent::ContextMenu:
    11581205        {
     
    11781225                break;
    11791226
    1180             QWidget *w = qApp->activePopupWidget();
     1227            QWidget *w = QApplication::activePopupWidget();
    11811228            if (waitForPopup(this, w)) {
    1182                 d->waitForPopupTimer->start();
     1229                d->waitForPopupTimer.start(POPUP_TIMER_INTERVAL, this);
    11831230                break;
    11841231            }
    11851232
    1186             d->waitForPopupTimer->stop();
     1233            d->waitForPopupTimer.stop();
    11871234            d->layout->setExpanded(false);
    11881235            break;
     
    11921239    }
    11931240    return QWidget::event(event);
    1194 }
    1195 
    1196 void QToolBarPrivate::_q_waitForPopup()
    1197 {
    1198     Q_Q(QToolBar);
    1199 
    1200     QWidget *w = qApp->activePopupWidget();
    1201     if (!waitForPopup(q, w)) {
    1202         waitForPopupTimer->stop();
    1203         if (!q->underMouse())
    1204             layout->setExpanded(false);
    1205     }
    12061241}
    12071242
  • trunk/src/gui/widgets/qtoolbar.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    143143    void iconSizeChanged(const QSize &iconSize);
    144144    void toolButtonStyleChanged(Qt::ToolButtonStyle toolButtonStyle);
     145    void topLevelChanged(bool topLevel);
    145146
    146147protected:
     
    168169    Q_PRIVATE_SLOT(d_func(), void _q_updateIconSize(const QSize &))
    169170    Q_PRIVATE_SLOT(d_func(), void _q_updateToolButtonStyle(Qt::ToolButtonStyle))
    170     Q_PRIVATE_SLOT(d_func(), void _q_waitForPopup())
    171171
    172172    friend class QMainWindow;
  • trunk/src/gui/widgets/qtoolbar_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5757#include "QtGui/qaction.h"
    5858#include "private/qwidget_p.h"
     59#include <QtCore/qbasictimer.h>
    5960
    6061QT_BEGIN_NAMESPACE
     
    7172public:
    7273    inline QToolBarPrivate()
    73         : explicitIconSize(false), explicitToolButtonStyle(false), movable(false),
     74        : explicitIconSize(false), explicitToolButtonStyle(false), movable(true), floatable(true),
    7475          allowedAreas(Qt::AllToolBarAreas), orientation(Qt::Horizontal),
    7576          toolButtonStyle(Qt::ToolButtonIconOnly),
     
    8586    void _q_updateIconSize(const QSize &sz);
    8687    void _q_updateToolButtonStyle(Qt::ToolButtonStyle style);
    87     void _q_waitForPopup();
    8888
    8989    bool explicitIconSize;
    9090    bool explicitToolButtonStyle;
    9191    bool movable;
     92    bool floatable;
    9293    Qt::ToolBarAreas allowedAreas;
    9394    Qt::Orientation orientation;
    9495    Qt::ToolButtonStyle toolButtonStyle;
    9596    QSize iconSize;
    96     bool floatable;
    9797
    9898    QAction *toggleViewAction;
     
    126126    void plug(const QRect &r);
    127127
    128     QTimer *waitForPopupTimer;
     128    QBasicTimer waitForPopupTimer;
    129129};
    130130
  • trunk/src/gui/widgets/qtoolbararealayout.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    114114
    115115        QSize sh = item.sizeHint();
    116         a += pick(o, sh) + item.extraSpace;
     116        a += item.preferredSize > 0 ? item.preferredSize : pick(o, sh);
    117117        b = qMax(b, perp(o, sh));
    118118    }
     
    157157            continue;
    158158
    159         QToolBarLayout *tblayout = qobject_cast<QToolBarLayout*>(item.widgetItem->widget()->layout());
    160         if (tblayout)
     159        if (QToolBarLayout *tblayout = qobject_cast<QToolBarLayout*>(item.widgetItem->widget()->layout()))
    161160            tblayout->checkUsePopupMenu();
    162161
    163         int itemMin = pick(o, item.minimumSize());
    164         int itemHint = pick(o, item.sizeHint());
    165         //we ensure the extraspace is not too low
    166         item.extraSpace = qMax(itemMin - itemHint, item.extraSpace);
    167         itemHint  += item.extraSpace;
    168         int itemExtra = qMin(itemHint - itemMin, extra);
    169 
    170         item.size = itemMin + itemExtra;
    171         extra -= itemExtra;
     162        const int itemMin = pick(o, item.minimumSize());
     163        //preferredSize is the default if it is set, otherwise, we take the sizehint
     164        item.size = item.preferredSize > 0 ? item.preferredSize : pick(o, item.sizeHint());
     165
     166        //the extraspace is the space above the item minimum sizehint
     167        const int extraSpace = qMin(item.size - itemMin, extra);
     168        item.size = itemMin + extraSpace; //that is the real size
     169
     170        extra -= extraSpace;
    172171
    173172        last = i;
     
    396395void QToolBarAreaLayoutInfo::moveToolBar(QToolBar *toolbar, int pos)
    397396{
    398     if (dirty) {
     397    if (dirty)
    399398        fitLayout();
    400     }
    401399
    402400    dirty = true;
    403401
    404     if (o == Qt::Vertical) {
     402    if (o == Qt::Vertical)
    405403        pos -= rect.top();
    406     }
    407 
    408     //here we actually update the extraSpace for the line containing the toolbar so that we move it
     404
     405    //here we actually update the preferredSize for the line containing the toolbar so that we move it
    409406    for (int j = 0; j < lines.count(); ++j) {
    410407        QToolBarAreaLayoutLine &line = lines[j];
     
    433430                    }
    434431
    435                     //let's update the previous extra space
     432                    //extra is the number of pixels to add to the previous toolbar
    436433                    int extra = newPos - current.pos;
    437434
    438                     if (qAbs(previous.extraSpace + extra) < QApplication::startDragDistance()) {
    439                         //we stick to the default space
    440                         extra = 0;
     435                    //we check if the previous is near its size hint
     436                    //in which case we try to stick to it
     437                    const int diff = pick(o, previous.sizeHint()) - (previous.size + extra);
     438                    if (qAbs(diff) < QApplication::startDragDistance()) {
     439                        //we stick to the default place and size
     440                        extra += diff;
    441441                    }
    442442
    443443                    //update for the current item
    444                     current.extraSpace -= extra;
    445                     //this ensures the toolbars to be pushed to the right when necessary
    446                     current.extraSpace = qMax(pick(o,current.minimumSize())- pick(o,current.sizeHint()), current.extraSpace);
    447  
     444                    current.extendSize(line.o, -extra);
     445
    448446                    if (extra >= 0) {
    449                         previous.extraSpace += extra;
    450 
     447                        previous.extendSize(line.o, extra);
    451448                    } else {
    452449                        //we need to push the toolbars on the left starting with previous
     
    456453                            QToolBarAreaLayoutItem &item = line.toolBarItems[l];
    457454                            if (!item.skip()) {
    458                                 const int minExtraSpace = pick(o, item.minimumSize()) - pick(o, item.sizeHint());
    459                                 const int margin =  item.extraSpace - minExtraSpace;
     455                                const int minPreferredSize = pick(o, item.minimumSize());
     456                                const int margin =  item.size - minPreferredSize;
    460457                                if (margin < extra) {
    461                                     item.extraSpace = minExtraSpace;
     458                                    item.resize(line.o, minPreferredSize);
    462459                                    extra -= margin;
    463460                                } else {
    464                                     item.extraSpace -= extra;
     461                                    item.extendSize(line.o, -extra);
    465462                                    extra = 0;
    466463                                }
     
    484481
    485482
    486 QList<int> QToolBarAreaLayoutInfo::gapIndex(const QPoint &pos) const
     483QList<int> QToolBarAreaLayoutInfo::gapIndex(const QPoint &pos, int *minDistance) const
    487484{
    488485    int p = pick(o, pos);
     
    513510            QList<int> result;
    514511            result << j << k;
     512            *minDistance = 0; //we found a perfect match
    515513            return result;
    516514        }
    517     } else if (appendLineDropRect().contains(pos)) {
    518         QList<int> result;
    519         result << lines.count() << 0;
    520         return result;
     515    } else {
     516        const int dist = distance(pos);
     517        //it will only return a path if the minDistance is higher than the current distance
     518        if (dist >= 0 && *minDistance > dist) {
     519            *minDistance = dist;
     520
     521            QList<int> result;
     522            result << lines.count() << 0;
     523            return result;
     524        }
    521525    }
    522526
     
    524528}
    525529
    526 bool QToolBarAreaLayoutInfo::insertGap(QList<int> path, QLayoutItem *item)
    527 {
    528     int j = path.at(0);
     530bool QToolBarAreaLayoutInfo::insertGap(const QList<int> &path, QLayoutItem *item)
     531{
     532    Q_ASSERT(path.count() == 2);
     533    int j = path.first();
    529534    if (j == lines.count())
    530535        lines.append(QToolBarAreaLayoutLine(o));
     
    537542    gap_item.widgetItem = item;
    538543
    539     //update the previous item's extra space
     544    //update the previous item's preferred size
    540545    for(int p = k - 1 ; p >= 0; --p) {
    541546        QToolBarAreaLayoutItem &previous = line.toolBarItems[p];
    542547        if (!previous.skip()) {
    543548            //we found the previous one
    544             gap_item.extraSpace = qMax(0, previous.extraSpace - pick(o, gap_item.sizeHint()));
    545             previous.extraSpace = qMin(previous.extraSpace, 0);
     549            int previousSizeHint = pick(line.o, previous.sizeHint());
     550            int previousExtraSpace = previous.size - previousSizeHint;
     551
     552            if (previousExtraSpace > 0) {
     553                //in this case we reset the space
     554                previous.preferredSize = -1;
     555                previous.size = previousSizeHint;
     556
     557                gap_item.resize(o, previousExtraSpace);
     558            }
     559
    546560            break;
    547561        }
     
    556570{
    557571    lines.clear();
    558     rect = QRect(0, 0, -1, -1);
    559 }
    560 
    561 QRect QToolBarAreaLayoutInfo::itemRect(QList<int> path) const
    562 {
     572    rect = QRect();
     573}
     574
     575QRect QToolBarAreaLayoutInfo::itemRect(const QList<int> &path) const
     576{
     577    Q_ASSERT(path.count() == 2);
    563578    int j = path.at(0);
    564579    int k = path.at(1);
     
    580595}
    581596
    582 QRect QToolBarAreaLayoutInfo::appendLineDropRect() const
    583 {
    584     QRect result;
    585 
     597int QToolBarAreaLayoutInfo::distance(const QPoint &pos) const
     598{
    586599    switch (dockPos) {
    587600        case QInternal::LeftDock:
    588             result = QRect(rect.right(), rect.top(),
    589                             EmptyDockAreaSize, rect.height());
    590             break;
     601            if (pos.y() < rect.bottom())
     602                return pos.x() - rect.right();
    591603        case QInternal::RightDock:
    592             result = QRect(rect.left() - EmptyDockAreaSize, rect.top(),
    593                             EmptyDockAreaSize, rect.height());
    594             break;
     604            if (pos.y() < rect.bottom())
     605                return rect.left() - pos.x();
    595606        case QInternal::TopDock:
    596             result = QRect(rect.left(), rect.bottom() + 1,
    597                             rect.width(), EmptyDockAreaSize);
    598             break;
     607            if (pos.x() < rect.right())
     608                return pos.y() - rect.bottom();
    599609        case QInternal::BottomDock:
    600             result = QRect(rect.left(), rect.top() - EmptyDockAreaSize,
    601                             rect.width(), EmptyDockAreaSize);
    602             break;
     610            if (pos.x() < rect.right())
     611                return rect.top() - pos.y();
    603612        default:
    604613            break;
    605614    }
    606 
    607     return result;
     615    return -1;
    608616}
    609617
     
    612620*/
    613621
    614 QToolBarAreaLayout::QToolBarAreaLayout(QMainWindow *win)
    615 {
    616     visible = true;
    617     mainWindow = win;
     622QToolBarAreaLayout::QToolBarAreaLayout(const QMainWindow *win) : mainWindow(win), visible(true)
     623{
    618624    for (int i = 0; i < QInternal::DockCount; ++i) {
    619625        QInternal::DockPosition pos = static_cast<QInternal::DockPosition>(i);
     
    771777            for (int k = 0; k < line.toolBarItems.count(); ++k) {
    772778                QToolBarAreaLayoutItem &item = line.toolBarItems[k];
    773                 delete item.widgetItem;
     779                if (!item.gap)
     780                    delete item.widgetItem;
    774781                item.widgetItem = 0;
    775782            }
     
    921928                    geo = QStyle::visualRect(dir, line.rect, geo);
    922929
    923                 layout->widgetAnimator->animate(widget, geo, animate);
     930                layout->widgetAnimator.animate(widget, geo, animate);
    924931            }
    925932        }
     
    10161023}
    10171024
     1025//this functions returns the path to the possible gapindex for the position pos
    10181026QList<int> QToolBarAreaLayout::gapIndex(const QPoint &pos) const
    10191027{
    10201028    Qt::LayoutDirection dir = mainWindow->layoutDirection();
     1029    int minDistance = 80; // when a dock area is empty, how "wide" is it?
     1030    QList<int> ret; //return value
    10211031    for (int i = 0; i < QInternal::DockCount; ++i) {
    10221032        QPoint p = pos;
    10231033        if (docks[i].o == Qt::Horizontal)
    10241034            p = QStyle::visualPos(dir, docks[i].rect, p);
    1025         QList<int> result = docks[i].gapIndex(p);
     1035        QList<int> result = docks[i].gapIndex(p, &minDistance);
    10261036        if (!result.isEmpty()) {
    10271037            result.prepend(i);
    1028             return result;
    1029         }
    1030     }
    1031 
    1032     return QList<int>();
     1038            ret = result;
     1039        }
     1040    }
     1041
     1042    return ret;
    10331043}
    10341044
     
    10531063}
    10541064
    1055 bool QToolBarAreaLayout::insertGap(QList<int> path, QLayoutItem *item)
    1056 {
    1057     Q_ASSERT(!path.isEmpty());
    1058     int i = path.takeFirst();
     1065bool QToolBarAreaLayout::insertGap(const QList<int> &path, QLayoutItem *item)
     1066{
     1067    Q_ASSERT(path.count() == 3);
     1068    const int i = path.first();
    10591069    Q_ASSERT(i >= 0 && i < QInternal::DockCount);
    1060     return docks[i].insertGap(path, item);
    1061 }
    1062 
    1063 void QToolBarAreaLayout::remove(QList<int> path)
    1064 {
     1070    return docks[i].insertGap(path.mid(1), item);
     1071}
     1072
     1073void QToolBarAreaLayout::remove(const QList<int> &path)
     1074{
     1075    Q_ASSERT(path.count() == 3);
    10651076    docks[path.at(0)].lines[path.at(1)].toolBarItems.removeAt(path.at(2));
    10661077}
     
    10901101    for (int i = 0; i < QInternal::DockCount; ++i)
    10911102        docks[i].clear();
    1092     rect = QRect(0, 0, -1, -1);
    1093 }
    1094 
    1095 QToolBarAreaLayoutItem &QToolBarAreaLayout::item(QList<int> path)
     1103    rect = QRect();
     1104}
     1105
     1106QToolBarAreaLayoutItem &QToolBarAreaLayout::item(const QList<int> &path)
    10961107{
    10971108    Q_ASSERT(path.count() == 3);
     
    11051116}
    11061117
    1107 QRect QToolBarAreaLayout::itemRect(QList<int> path) const
    1108 {
    1109     int i = path.takeFirst();
    1110 
    1111     QRect r = docks[i].itemRect(path);
     1118QRect QToolBarAreaLayout::itemRect(const QList<int> &path) const
     1119{
     1120    const int i = path.first();
     1121
     1122    QRect r = docks[i].itemRect(path.mid(1));
    11121123    if (docks[i].o == Qt::Horizontal)
    11131124        r = QStyle::visualRect(mainWindow->layoutDirection(),
     
    11161127}
    11171128
    1118 QLayoutItem *QToolBarAreaLayout::plug(QList<int> path)
     1129QLayoutItem *QToolBarAreaLayout::plug(const QList<int> &path)
    11191130{
    11201131    QToolBarAreaLayoutItem &item = this->item(path);
     
    11251136}
    11261137
    1127 QLayoutItem *QToolBarAreaLayout::unplug(QList<int> path, QToolBarAreaLayout *other)
     1138QLayoutItem *QToolBarAreaLayout::unplug(const QList<int> &path, QToolBarAreaLayout *other)
    11281139{
    11291140    //other needs to be update as well
     1141    Q_ASSERT(path.count() == 3);
    11301142    QToolBarAreaLayoutItem &item = this->item(path);
    11311143
     
    11331145    QToolBarAreaLayoutInfo &info = docks[path.at(0)];
    11341146    QToolBarAreaLayoutLine &line = info.lines[path.at(1)];
    1135     if (item.extraSpace != 0) {
     1147    if (item.size != pick(line.o, item.realSizeHint())) {
     1148        //the item doesn't have its default size
     1149        //so we'll give this to the next item
    11361150        int newExtraSpace = 0;
     1151        //let's iterate over the siblings of the current item that pare placed before it
     1152        //we need to find just the one before
    11371153        for (int i = path.at(2) - 1; i >= 0; --i) {
    11381154            QToolBarAreaLayoutItem &previous = line.toolBarItems[i];
    11391155            if (!previous.skip()) {
     1156                //we need to check if it has a previous element and a next one
     1157                //the previous will get its size changed
    11401158                for (int j = path.at(2) + 1; j < line.toolBarItems.count(); ++j) {
    11411159                    const QToolBarAreaLayoutItem &next = line.toolBarItems.at(j);
    11421160                    if (!next.skip()) {
    1143                         newExtraSpace = previous.extraSpace = next.pos - previous.pos - pick(line.o, previous.sizeHint());
     1161                        newExtraSpace = next.pos - previous.pos - pick(line.o, previous.sizeHint());
     1162                        previous.resize(line.o, next.pos - previous.pos);
     1163                        break;
    11441164                    }
    1145                     break;
    11461165                }
    11471166                break;
     
    11551174                QToolBarAreaLayoutItem &previous = line.toolBarItems[i];
    11561175                if (!previous.skip()) {
    1157                     previous.extraSpace = newExtraSpace;
     1176                    previous.resize(line.o, pick(line.o, previous.sizeHint()) + newExtraSpace);
    11581177                    break;
    11591178                }
     
    11621181        }
    11631182    }
    1164 
    11651183
    11661184    Q_ASSERT(!item.gap);
     
    12541272                stream << shownOrientation;
    12551273                stream << item.pos;
    1256                 //if extraSpace is 0 the item has its "normal" size, so no need to store the size (we store -1)
    1257                 stream << (item.extraSpace == 0 ? -1 : (pick(line.o, item.realSizeHint()) + item.extraSpace));
     1274                //we store the preferred size. If the use rdidn't resize the toolbars it will be -1
     1275                stream << item.preferredSize;
    12581276
    12591277                uint geom0, geom1;
     
    12841302    int lines;
    12851303    stream >> lines;
     1304        if (!testing)
     1305        testing = mainWindow->unifiedTitleAndToolBarOnMac();
    12861306
    12871307    for (int j = 0; j < lines; ++j) {
     
    12941314
    12951315        QToolBarAreaLayoutInfo &dock = docks[pos];
     1316                const bool applyingLayout = !testing && !(pos == QInternal::TopDock && mainWindow->unifiedTitleAndToolBarOnMac());
    12961317        QToolBarAreaLayoutLine line(dock.o);
    12971318
     
    13341355            }
    13351356
    1336             if (!testing) {
     1357            if (applyingLayout) {
    13371358                item.widgetItem = new QWidgetItemV2(toolBar);
    13381359                toolBar->setOrientation(floating ? ((shown & 2) ? Qt::Vertical : Qt::Horizontal) : dock.o);
     
    13401361                toolBar->d_func()->setWindowState(floating, true, rect);
    13411362
    1342                 //if it is -1, it means we should use the default size
    1343                 item.extraSpace = (item.size == -1) ? 0 : item.size - pick(line.o, item.realSizeHint());
    1344 
    1345 
     1363                item.preferredSize = item.size;
    13461364                line.toolBarItems.append(item);
    13471365            }
    13481366        }
    13491367
    1350         if (!testing) {
     1368        if (applyingLayout) {
    13511369            dock.lines.append(line);
    13521370        }
  • trunk/src/gui/widgets/qtoolbararealayout_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5959
    6060QT_BEGIN_NAMESPACE
     61
     62static inline int pick(Qt::Orientation o, const QPoint &pos)
     63{ return o == Qt::Horizontal ? pos.x() : pos.y(); }
     64
     65static inline int pick(Qt::Orientation o, const QSize &size)
     66{ return o == Qt::Horizontal ? size.width() : size.height(); }
     67
     68static inline int &rpick(Qt::Orientation o, QPoint &pos)
     69{ return o == Qt::Horizontal ? pos.rx() : pos.ry(); }
     70
     71static inline int &rpick(Qt::Orientation o, QSize &size)
     72{ return o == Qt::Horizontal ? size.rwidth() : size.rheight(); }
     73
     74static inline QSizePolicy::Policy pick(Qt::Orientation o, const QSizePolicy &policy)
     75{ return o == Qt::Horizontal ? policy.horizontalPolicy() : policy.verticalPolicy(); }
     76
     77static inline int perp(Qt::Orientation o, const QPoint &pos)
     78{ return o == Qt::Vertical ? pos.x() : pos.y(); }
     79
     80static inline int perp(Qt::Orientation o, const QSize &size)
     81{ return o == Qt::Vertical ? size.width() : size.height(); }
     82
     83static inline int &rperp(Qt::Orientation o, QPoint &pos)
     84{ return o == Qt::Vertical ? pos.rx() : pos.ry(); }
     85
     86static inline int &rperp(Qt::Orientation o, QSize &size)
     87{ return o == Qt::Vertical ? size.rwidth() : size.rheight(); }
    6188
    6289#ifndef QT_NO_TOOLBAR
     
    7198public:
    7299    QToolBarAreaLayoutItem(QLayoutItem *item = 0)
    73         : widgetItem(item), pos(0), size(-1), extraSpace(0), gap(false) {}
     100        : widgetItem(item), pos(0), size(-1), preferredSize(-1), gap(false) {}
    74101
    75102    bool skip() const;
    76103    QSize minimumSize() const;
    77104    QSize sizeHint() const;
    78     QSize realSizeHint() const;
     105    QSize realSizeHint() const;
     106
     107    void resize(Qt::Orientation o, int newSize)
     108    {
     109        newSize = qMax(pick(o, minimumSize()), newSize);
     110        int sizeh = pick(o, sizeHint());
     111        if (newSize == sizeh) {
     112            preferredSize = -1;
     113            size = sizeh;
     114        } else {
     115            preferredSize = newSize;
     116        }
     117    }
     118
     119    void extendSize(Qt::Orientation o, int extent)
     120    {
     121        int newSize = qMax(pick(o, minimumSize()), (preferredSize > 0 ? preferredSize : pick(o, sizeHint())) + extent);
     122        int sizeh = pick(o, sizeHint());
     123        if (newSize == sizeh) {
     124            preferredSize = -1;
     125            size = sizeh;
     126        } else {
     127            preferredSize = newSize;
     128        }
     129    }
    79130
    80131    QLayoutItem *widgetItem;
    81132    int pos;
    82133    int size;
    83     int extraSpace;
     134    int preferredSize;
    84135    bool gap;
    85136};
     
    105156{
    106157public:
    107     enum { EmptyDockAreaSize = 80 }; // when a dock area is empty, how "wide" is it?
    108 
    109158    QToolBarAreaLayoutInfo(QInternal::DockPosition pos = QInternal::TopDock);
    110159
     
    123172    void moveToolBar(QToolBar *toolbar, int pos);
    124173
    125     QList<int> gapIndex(const QPoint &pos) const;
    126     bool insertGap(QList<int> path, QLayoutItem *item);
     174    QList<int> gapIndex(const QPoint &pos, int *maxDistance) const;
     175    bool insertGap(const QList<int> &path, QLayoutItem *item);
    127176    void clear();
    128     QRect itemRect(QList<int> path) const;
    129     QRect appendLineDropRect() const;
     177    QRect itemRect(const QList<int> &path) const;
     178    int distance(const QPoint &pos) const;
    130179
    131180    QRect rect;
     
    144193
    145194    QRect rect;
    146     QMainWindow *mainWindow;
     195    const QMainWindow *mainWindow;
    147196    QToolBarAreaLayoutInfo docks[4];
    148197    bool visible;
    149198
    150     QToolBarAreaLayout(QMainWindow *win);
     199    QToolBarAreaLayout(const QMainWindow *win);
    151200
    152201    QRect fitLayout();
     
    180229    QList<int> gapIndex(const QPoint &pos) const;
    181230    QList<int> currentGapIndex() const;
    182     bool insertGap(QList<int> path, QLayoutItem *item);
    183     void remove(QList<int> path);
     231    bool insertGap(const QList<int> &path, QLayoutItem *item);
     232    void remove(const QList<int> &path);
    184233    void remove(QLayoutItem *item);
    185234    void clear();
    186     QToolBarAreaLayoutItem &item(QList<int> path);
    187     QRect itemRect(QList<int> path) const;
    188     QLayoutItem *plug(QList<int> path);
    189     QLayoutItem *unplug(QList<int> path, QToolBarAreaLayout *other);
     235    QToolBarAreaLayoutItem &item(const QList<int> &path);
     236    QRect itemRect(const QList<int> &path) const;
     237    QLayoutItem *plug(const QList<int> &path);
     238    QLayoutItem *unplug(const QList<int> &path, QToolBarAreaLayout *other);
    190239
    191240    void saveState(QDataStream &stream) const;
  • trunk/src/gui/widgets/qtoolbarextension.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6262void QToolBarExtension::setOrientation(Qt::Orientation o)
    6363{
     64    QStyleOption opt;
     65    opt.init(this);
    6466    if (o == Qt::Horizontal) {
    65         setIcon(style()->standardIcon(QStyle::SP_ToolBarHorizontalExtensionButton));
     67        setIcon(style()->standardIcon(QStyle::SP_ToolBarHorizontalExtensionButton, &opt));
    6668    } else {
    67         setIcon(style()->standardIcon(QStyle::SP_ToolBarVerticalExtensionButton));
     69        setIcon(style()->standardIcon(QStyle::SP_ToolBarVerticalExtensionButton, &opt));
    6870   }
    6971}
  • trunk/src/gui/widgets/qtoolbarextension_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6060#ifndef QT_NO_TOOLBUTTON
    6161
    62 class QToolBarExtension : public QToolButton
     62class Q_AUTOTEST_EXPORT QToolBarExtension : public QToolButton
    6363{
    6464    Q_OBJECT
  • trunk/src/gui/widgets/qtoolbarlayout.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    129129    if (!set) {
    130130        QObject::connect(extension, SIGNAL(clicked(bool)),
    131                         this, SLOT(setExpanded(bool)));
     131                        this, SLOT(setExpanded(bool)), Qt::UniqueConnection);
    132132        extension->setPopupMode(QToolButton::DelayedPopup);
    133133        extension->setMenu(0);
     
    335335        if (mw->unifiedTitleAndToolBarOnMac()
    336336                && mw->toolBarArea(static_cast<QToolBar *>(parentWidget())) == Qt::TopToolBarArea) {
    337             if (that->expandFlag) {
     337            if (expandFlag) {
    338338                tb->setMaximumSize(0xFFFFFF, 0xFFFFFF);
    339339            } else {
     
    361361    QStyleOptionToolBar opt;
    362362    tb->initStyleOption(&opt);
    363     const int handleExtent = movable()
    364             ? style->pixelMetric(QStyle::PM_ToolBarHandleExtent, &opt, tb) : 0;
    365363    const int margin = this->margin();
    366364    const int extensionExtent = style->pixelMetric(QStyle::PM_ToolBarExtensionExtent, &opt, tb);
     
    368366
    369367    QLayout::setGeometry(rect);
    370     if (movable()) {
    371         if (o == Qt::Horizontal) {
    372             handRect = QRect(margin, margin, handleExtent, rect.height() - 2*margin);
    373             handRect = QStyle::visualRect(parentWidget()->layoutDirection(), rect, handRect);
    374         } else {
    375             handRect = QRect(margin, margin, rect.width() - 2*margin, handleExtent);
    376         }
    377     } else {
    378         handRect = QRect();
    379     }
    380368
    381369    bool ranOutOfSpace = false;
     
    667655        return;
    668656    if (QMainWindow *win = qobject_cast<QMainWindow*>(tb->parentWidget())) {
    669         animating = true;
     657        animating = !tb->isWindow() && win->isAnimated();
    670658        QMainWindowLayout *layout = qobject_cast<QMainWindowLayout*>(win->layout());
    671659        if (expanded) {
     
    678666            }
    679667        }
    680         layout->layoutState.toolBarAreaLayout.apply(true);
     668        layout->layoutState.toolBarAreaLayout.apply(animating);
    681669    }
    682670}
     
    743731}
    744732
    745 QRect QToolBarLayout::handleRect() const
    746 {
    747     return handRect;
    748 }
    749 
    750733QT_END_NAMESPACE
    751734
  • trunk/src/gui/widgets/qtoolbarlayout_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6666class QMenu;
    6767
    68 class Q_GUI_EXPORT QToolBarItem : public QWidgetItem
     68class QToolBarItem : public QWidgetItem
    6969{
    7070public:
     
    7676};
    7777
    78 class Q_GUI_EXPORT QToolBarLayout : public QLayout
     78class QToolBarLayout : public QLayout
    7979{
    8080    Q_OBJECT
     
    101101    int indexOf(QWidget *widget) const { return QLayout::indexOf(widget); }
    102102
    103     QRect handleRect() const;
    104 
    105103    bool layoutActions(const QSize &size);
    106104    QSize expandedSize(const QSize &size) const;
     
    114112    bool hasExpandFlag() const;
    115113
    116 public slots:
     114public Q_SLOTS:
    117115    void setExpanded(bool b);
    118116
  • trunk/src/gui/widgets/qtoolbarseparator.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qtoolbarseparator_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qtoolbox.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    253253    \brief The QToolBox class provides a column of tabbed widget items.
    254254
    255     \mainclass
     255
    256256    \ingroup basicwidgets
    257257
     
    803803/*!
    804804    \fn int QToolBox::margin() const
    805     Returns the with of the the margin around the contents of the widget.
     805    Returns the width of the margin around the contents of the widget.
    806806
    807807    Use QWidget::getContentsMargins() instead.
  • trunk/src/gui/widgets/qtoolbox.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qtoolbutton.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    105105bool QToolButtonPrivate::hasMenu() const
    106106{
    107     Q_Q(const QToolButton);
    108107    return ((defaultAction && defaultAction->menu())
    109108            || (menuAction && menuAction->menu())
    110             || q->actions().size() > (defaultAction ? 1 : 0));
     109            || actions.size() > (defaultAction ? 1 : 0));
    111110}
    112111#endif
     
    118117
    119118    \ingroup basicwidgets
    120     \mainclass
     119
    121120
    122121    A tool button is a special button that provides quick-access to
     
    279278    defaultAction = 0;
    280279#ifndef QT_NO_TOOLBAR
    281     if (qobject_cast<QToolBar*>(q->parentWidget()))
     280    if (qobject_cast<QToolBar*>(parent))
    282281        autoRaise = true;
    283282    else
     
    380379        option->features |= QStyleOptionToolButton::HasMenu;
    381380#endif
    382     option->toolButtonStyle = d->toolButtonStyle;
     381    if (d->toolButtonStyle == Qt::ToolButtonFollowStyle) {
     382        option->toolButtonStyle = Qt::ToolButtonStyle(style()->styleHint(QStyle::SH_ToolButtonStyle, option, this));
     383    } else
     384        option->toolButtonStyle = d->toolButtonStyle;
     385
     386    if (option->toolButtonStyle == Qt::ToolButtonTextBesideIcon) {
     387        // If the action is not prioritized, remove the text label to save space
     388        if (d->defaultAction && d->defaultAction->priority() < QAction::NormalPriority)
     389            option->toolButtonStyle = Qt::ToolButtonIconOnly;
     390    }
     391
    383392    if (d->icon.isNull() && d->arrowType == Qt::NoArrow && !forceNoText) {
    384393        if (!d->text.isEmpty())
     
    478487    The default is Qt::ToolButtonIconOnly.
    479488
     489    To have the style of toolbuttons follow the system settings (as available
     490    in GNOME and KDE desktop environments), set this property to Qt::ToolButtonFollowStyle.
     491
    480492    QToolButton automatically connects this slot to the relevant
    481493    signal in the QMainWindow in which is resides.
     
    860872    if (!hasMenu())
    861873        return; // no menu to show
    862 
    863     if (delay > 0 && popupMode == QToolButton::DelayedPopup)
     874    if (popupMode == QToolButton::MenuButtonPopup)
     875        return;
     876    else if (delay > 0 && !popupTimer.isActive() && popupMode == QToolButton::DelayedPopup)
    864877        popupTimer.start(delay, q);
    865878    else if (delay == 0 || popupMode == QToolButton::InstantPopup)
     
    884897        actualMenu = new QMenu(q);
    885898        mustDeleteActualMenu = true;
    886         QList<QAction*> actions = q->actions();
    887899        for(int i = 0; i < actions.size(); i++)
    888900            actualMenu->addAction(actions.at(i));
     
    892904    bool horizontal = true;
    893905#if !defined(QT_NO_TOOLBAR)
    894     QToolBar *tb = qobject_cast<QToolBar*>(q->parentWidget());
     906    QToolBar *tb = qobject_cast<QToolBar*>(parent);
    895907    if (tb && tb->orientation() == Qt::Vertical)
    896908        horizontal = false;
    897909#endif
    898910    QPoint p;
    899     QRect screen = qApp->desktop()->availableGeometry(q);
     911    QRect screen = QApplication::desktop()->availableGeometry(q);
    900912    QSize sh = ((QToolButton*)(QMenu*)actualMenu)->receivers(SIGNAL(aboutToShow()))? QSize() : actualMenu->sizeHint();
    901913    QRect rect = q->rect();
  • trunk/src/gui/widgets/qtoolbutton.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qvalidator.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5555    \class QValidator
    5656    \brief The QValidator class provides validation of input text.
    57 
    58     \ingroup misc
    59     \mainclass
    6057
    6158    The class itself is abstract. Two subclasses, \l QIntValidator and
     
    9188
    9289    \i For an editable combobox that accepts URLs, any well-formed URL
    93     is \l Acceptable, "http://qtsoftware.com/," is \l Intermediate
     90    is \l Acceptable, "http://example.com/," is \l Intermediate
    9491    (it might be a cut and paste action that accidentally took in a
    9592    comma at the end), the empty string is \l Intermediate (the user
     
    9996    \i For a spin box that accepts lengths, "11cm" and "1in" are \l
    10097    Acceptable, "11" and the empty string are \l Intermediate, and
    101     "http://qtsoftware.com" and "hour" are \l Invalid.
     98    "http://example.com" and "hour" are \l Invalid.
    10299
    103100    \endlist
     
    247244    a string contains a valid integer within a specified range.
    248245
    249     \ingroup misc
    250 
    251246    Example of use:
    252247
     
    371366        return 1;
    372367    return (int)log10(double(n)) + 1;
    373 };
     368}
    374369
    375370static qlonglong pow10(int exp)
     
    497492    \brief The QDoubleValidator class provides range checking of
    498493    floating-point numbers.
    499 
    500     \ingroup misc
    501494
    502495    QDoubleValidator provides an upper bound, a lower bound, and a
     
    644637            numMode = QLocalePrivate::DoubleScientificMode;
    645638            break;
    646     };
     639    }
    647640
    648641    QByteArray buff;
     
    767760    \brief The QRegExpValidator class is used to check a string
    768761    against a regular expression.
    769 
    770     \ingroup misc
    771762
    772763    QRegExpValidator uses a regular expression (regexp) to
  • trunk/src/gui/widgets/qvalidator.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6262    Q_OBJECT
    6363public:
    64     explicit QValidator(QObject * parent);
     64    explicit QValidator(QObject * parent = 0);
    6565    ~QValidator();
    6666
     
    101101
    102102public:
    103     explicit QIntValidator(QObject * parent);
     103    explicit QIntValidator(QObject * parent = 0);
    104104    QIntValidator(int bottom, int top, QObject * parent);
    105105    ~QIntValidator();
  • trunk/src/gui/widgets/qwidgetanimator.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
    4040****************************************************************************/
    4141
    42 #include <QtCore/qtimer.h>
    43 #include <QtCore/qdatetime.h>
     42#include <QtCore/qpropertyanimation.h>
    4443#include <QtGui/qwidget.h>
    45 #include <QtGui/qtextedit.h>
    46 #include <QtGui/private/qwidget_p.h>
    47 #include <qdebug.h>
     44#include <QtGui/private/qmainwindowlayout_p.h>
    4845
    4946#include "qwidgetanimator_p.h"
     
    5148QT_BEGIN_NAMESPACE
    5249
    53 static const int g_animation_steps = 12;
    54 static const int g_animation_interval = 16;
    55 
    56 // 1000 * (x/(1 + x*x) + 0.5) on interval [-1, 1]
    57 static const int g_animate_function[] =
     50QWidgetAnimator::QWidgetAnimator(QMainWindowLayout *layout) : m_mainWindowLayout(layout)
    5851{
    59     0, 1, 5, 12, 23, 38, 58, 84, 116, 155, 199, 251, 307, 368,
    60     433, 500, 566, 631, 692, 748, 799, 844, 883, 915, 941, 961,
    61     976, 987, 994, 998, 1000
    62 };
    63 static const int g_animate_function_points = sizeof(g_animate_function)/sizeof(int);
    64 
    65 static inline int animateHelper(int start, int stop, int step, int steps)
    66 {
    67     if (start == stop)
    68         return start;
    69     if (step == 0)
    70         return start;
    71     if (step == steps)
    72         return stop;
    73 
    74     int x = g_animate_function_points*step/(steps + 1);
    75     return start + g_animate_function[x]*(stop - start)/1000;
    76 }
    77 
    78 QWidgetAnimator::QWidgetAnimator(QObject *parent)
    79     : QObject(parent)
    80 {
    81     m_time = new QTime();
    82     m_timer = new QTimer(this);
    83     m_timer->setInterval(g_animation_interval);
    84     connect(m_timer, SIGNAL(timeout()), this, SLOT(animationStep()));
    85 }
    86 
    87 QWidgetAnimator::~QWidgetAnimator()
    88 {
    89     delete m_time;
    9052}
    9153
    9254void QWidgetAnimator::abort(QWidget *w)
    9355{
    94     if (m_animation_map.remove(w) == 0)
     56#ifndef QT_NO_ANIMATION
     57    AnimationMap::iterator it = m_animation_map.find(w);
     58    if (it == m_animation_map.end())
    9559        return;
    96     if (m_animation_map.isEmpty()) {
    97         m_timer->stop();
    98         emit finishedAll();
    99     }
     60    QPropertyAnimation *anim = *it;
     61    m_animation_map.erase(it);
     62    anim->stop();
     63#ifndef QT_NO_MAINWINDOW
     64    m_mainWindowLayout->animationFinished(w);
     65#endif
     66#else
     67    Q_UNUSED(w); //there is no animation to abort
     68#endif //QT_NO_ANIMATION
    10069}
     70
     71#ifndef QT_NO_ANIMATION
     72void QWidgetAnimator::animationFinished()
     73{
     74    QPropertyAnimation *anim = qobject_cast<QPropertyAnimation*>(sender());
     75    abort(static_cast<QWidget*>(anim->targetObject()));
     76}
     77#endif //QT_NO_ANIMATION
    10178
    10279void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, bool animate)
    10380{
    104     QRect final_geometry = _final_geometry;
    105 
    10681    QRect r = widget->geometry();
    10782    if (r.right() < 0 || r.bottom() < 0)
    10883        r = QRect();
    10984
    110     if (r.isNull() || final_geometry.isNull())
    111         animate = false;
     85    animate = animate && !r.isNull() && !_final_geometry.isNull();
    11286
     87    // might make the wigdet go away by sending it to negative space
     88    const QRect final_geometry = _final_geometry.isValid() || widget->isWindow() ? _final_geometry :
     89        QRect(QPoint(-500 - widget->width(), -500 - widget->height()), widget->size());
     90
     91#ifndef QT_NO_ANIMATION
    11392    AnimationMap::const_iterator it = m_animation_map.constFind(widget);
    114     if (it == m_animation_map.constEnd()) {
    115         if (r == final_geometry) {
    116             emit finished(widget);
    117             return;
    118         }
    119     } else {
    120         if ((*it).r2 == final_geometry)
    121             return;
    122     }
     93    if (it != m_animation_map.constEnd() && (*it)->endValue().toRect() == final_geometry)
     94        return;
    12395
    124     if (animate) {
    125         AnimationItem item(widget, r, final_geometry);
    126         m_animation_map[widget] = item;
    127         if (!m_timer->isActive()) {
    128             m_timer->start();
    129             m_time->start();
    130         }
    131     } else {
    132         m_animation_map.remove(widget);
    133         if (m_animation_map.isEmpty())
    134             m_timer->stop();
    135 
    136         if (!final_geometry.isValid() && !widget->isWindow()) {
    137             // Make the wigdet go away by sending it to negative space
    138             QSize s = widget->size();
    139             final_geometry = QRect(-500 - s.width(), -500 - s.height(), s.width(), s.height());
    140         }
    141         widget->setGeometry(final_geometry);
    142 
    143         emit finished(widget);
    144 
    145         if (m_animation_map.isEmpty())
    146             emit finishedAll();
    147 
    148         return;
    149     }
    150 }
    151 
    152 void QWidgetAnimator::animationStep()
    153 {
    154     int steps = (1 + m_time->restart())/g_animation_interval;
    155     AnimationMap::iterator it = m_animation_map.begin();
    156     while (it != m_animation_map.end()) {
    157         AnimationItem &item = *it;
    158 
    159         item.step = qMin(item.step + steps, g_animation_steps);
    160 
    161         int x = animateHelper(item.r1.left(), item.r2.left(),
    162                             item.step, g_animation_steps);
    163         int y = animateHelper(item.r1.top(), item.r2.top(),
    164                             item.step, g_animation_steps);
    165         int w = animateHelper(item.r1.width(), item.r2.width(),
    166                             item.step, g_animation_steps);
    167         int h = animateHelper(item.r1.height(), item.r2.height(),
    168                             item.step, g_animation_steps);
    169 
    170         item.widget->setGeometry(x, y, w, h);
    171 
    172         if (item.step == g_animation_steps) {
    173             emit finished(item.widget);
    174             AnimationMap::iterator tmp = it;
    175             ++it;
    176             m_animation_map.erase(tmp);
    177         } else {
    178             ++it;
    179         }
    180     }
    181 
    182     if (m_animation_map.isEmpty()) {
    183         m_timer->stop();
    184         emit finishedAll();
    185     }
     96    QPropertyAnimation *anim = new QPropertyAnimation(widget, "geometry", widget);
     97    anim->setDuration(animate ? 200 : 0);
     98    anim->setEasingCurve(QEasingCurve::InOutQuad);
     99    anim->setEndValue(final_geometry);
     100    m_animation_map[widget] = anim;
     101    connect(anim, SIGNAL(finished()), SLOT(animationFinished()));
     102    anim->start(QPropertyAnimation::DeleteWhenStopped);
     103#else
     104    //we do it in one shot
     105    widget->setGeometry(final_geometry);
     106#ifndef QT_NO_MAINWINDOW
     107    m_mainWindowLayout->animationFinished(widget);
     108#endif //QT_NO_MAINWINDOW
     109#endif //QT_NO_ANIMATION
    186110}
    187111
    188112bool QWidgetAnimator::animating() const
    189113{
    190     return m_timer->isActive();
    191 }
    192 
    193 bool QWidgetAnimator::animating(QWidget *widget)
    194 {
    195     return m_animation_map.contains(widget);
     114    return !m_animation_map.isEmpty();
    196115}
    197116
  • trunk/src/gui/widgets/qwidgetanimator_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5555
    5656#include <qobject.h>
    57 #include <qrect.h>
    5857#include <qmap.h>
    5958
     
    6160
    6261class QWidget;
    63 class QTimer;
    64 class QTime;
     62class QMainWindowLayout;
     63class QPropertyAnimation;
     64class QRect;
    6565
    6666class QWidgetAnimator : public QObject
     
    6868    Q_OBJECT
    6969public:
    70     QWidgetAnimator(QObject *parent = 0);
    71     ~QWidgetAnimator();
     70    QWidgetAnimator(QMainWindowLayout *layout);
    7271    void animate(QWidget *widget, const QRect &final_geometry, bool animate);
    7372    bool animating() const;
    74     bool animating(QWidget *widget);
    7573
    7674    void abort(QWidget *widget);
    7775
    78 signals:
    79     void finished(QWidget *widget);
    80     void finishedAll();
    81 
    82 private slots:
    83     void animationStep();
     76#ifndef QT_NO_ANIMATION
     77private Q_SLOTS:
     78    void animationFinished();
     79#endif
    8480
    8581private:
    86     struct AnimationItem {
    87         AnimationItem(QWidget *_widget = 0, const QRect &_r1 = QRect(),
    88                         const QRect &_r2 = QRect())
    89             : widget(_widget), r1(_r1), r2(_r2), step(0) {}
    90         QWidget *widget;
    91         QRect r1, r2;
    92         int step;
    93     };
    94     typedef QMap<QWidget*, AnimationItem> AnimationMap;
     82    typedef QMap<QWidget*, QPropertyAnimation*> AnimationMap;
    9583    AnimationMap m_animation_map;
    96     QTimer *m_timer;
    97     QTime *m_time;
     84    QMainWindowLayout *m_mainWindowLayout;
    9885};
    9986
  • trunk/src/gui/widgets/qwidgetresizehandler.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    259259#ifdef Q_WS_X11
    260260    // Workaround for window managers which refuse to move a tool window partially offscreen.
    261     QRect desktop = qApp->desktop()->availableGeometry(widget);
     261    QRect desktop = QApplication::desktop()->availableGeometry(widget);
    262262    pp.rx() = qMax(pp.x(), desktop.left());
    263263    pp.ry() = qMax(pp.y(), desktop.top());
  • trunk/src/gui/widgets/qwidgetresizehandler_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/qworkspace.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    111111                                                                 helpEvent->pos(), this);
    112112        if (ctrl == QStyle::SC_MdiCloseButton)
    113             QToolTip::showText(helpEvent->globalPos(), QWorkspace::tr("Close"));
     113            QToolTip::showText(helpEvent->globalPos(), QWorkspace::tr("Close"), this);
    114114        else if (ctrl == QStyle::SC_MdiMinButton)
    115             QToolTip::showText(helpEvent->globalPos(), QWorkspace::tr("Minimize"));
     115            QToolTip::showText(helpEvent->globalPos(), QWorkspace::tr("Minimize"), this);
    116116        else if (ctrl == QStyle::SC_MdiNormalButton)
    117             QToolTip::showText(helpEvent->globalPos(), QWorkspace::tr("Restore Down"));
     117            QToolTip::showText(helpEvent->globalPos(), QWorkspace::tr("Restore Down"), this);
    118118        else
    119119            QToolTip::hideText();
     
    398398        pal.setColor(QPalette::Active, QPalette::HighlightedText, colorref2qrgb(GetSysColor(COLOR_CAPTIONTEXT)));
    399399        pal.setColor(QPalette::Inactive, QPalette::HighlightedText, colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTIONTEXT)));
    400         if (QSysInfo::WindowsVersion != QSysInfo::WV_95 && QSysInfo::WindowsVersion != QSysInfo::WV_NT) {
    401             colorsInitialized = true;
    402             BOOL gradient;
    403             QT_WA({
    404                 SystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, &gradient, 0);
    405             } , {
    406                 SystemParametersInfoA(SPI_GETGRADIENTCAPTIONS, 0, &gradient, 0);
    407             });
    408             if (gradient) {
    409                 pal.setColor(QPalette::Active, QPalette::Base, colorref2qrgb(GetSysColor(COLOR_GRADIENTACTIVECAPTION)));
    410                 pal.setColor(QPalette::Inactive, QPalette::Base, colorref2qrgb(GetSysColor(COLOR_GRADIENTINACTIVECAPTION)));
    411             } else {
    412                 pal.setColor(QPalette::Active, QPalette::Base, pal.color(QPalette::Active, QPalette::Highlight));
    413                 pal.setColor(QPalette::Inactive, QPalette::Base, pal.color(QPalette::Inactive, QPalette::Highlight));
    414             }
     400
     401        colorsInitialized = true;
     402        BOOL gradient = false;
     403        SystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, &gradient, 0);
     404
     405        if (gradient) {
     406            pal.setColor(QPalette::Active, QPalette::Base, colorref2qrgb(GetSysColor(COLOR_GRADIENTACTIVECAPTION)));
     407            pal.setColor(QPalette::Inactive, QPalette::Base, colorref2qrgb(GetSysColor(COLOR_GRADIENTINACTIVECAPTION)));
     408        } else {
     409            pal.setColor(QPalette::Active, QPalette::Base, pal.color(QPalette::Active, QPalette::Highlight));
     410            pal.setColor(QPalette::Inactive, QPalette::Base, pal.color(QPalette::Inactive, QPalette::Highlight));
    415411        }
    416412    }
     
    839835    \brief The QWorkspace widget provides a workspace window that can be
    840836    used in an MDI application.
    841     \ingroup application
    842837
    843838    This class is deprecated. Use QMdiArea instead.
  • trunk/src/gui/widgets/qworkspace.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/widgets/widgets.pri

    r2 r561  
    3131        widgets/qlineedit.h \
    3232        widgets/qlineedit_p.h \
     33        widgets/qlinecontrol_p.h \
    3334        widgets/qmainwindow.h \
    3435        widgets/qmainwindowlayout_p.h \
     
    3839        widgets/qmdisubwindow_p.h \
    3940        widgets/qmenu.h \
     41        widgets/qmenu_p.h \
    4042        widgets/qmenubar.h \
     43        widgets/qmenubar_p.h \
    4144        widgets/qmenudata.h \
    4245        widgets/qprogressbar.h \
     
    8083        widgets/qplaintextedit_p.h \
    8184        widgets/qprintpreviewwidget.h
    82 
    8385SOURCES += \
    8486        widgets/qabstractbutton.cpp \
     
    100102        widgets/qlabel.cpp \
    101103        widgets/qlcdnumber.cpp \
     104        widgets/qlineedit_p.cpp \
    102105        widgets/qlineedit.cpp \
     106        widgets/qlinecontrol.cpp \
    103107        widgets/qmainwindow.cpp \
    104108        widgets/qmainwindowlayout.cpp \
     
    141145        widgets/qprintpreviewwidget.cpp
    142146
    143 
    144147!embedded:mac {
    145148    HEADERS += widgets/qmacnativewidget_mac.h \
     
    161164    !static: QMAKE_WRITE_DEFAULT_RC = 1
    162165}
     166
     167symbian*: {
     168    SOURCES += widgets/qmenu_symbian.cpp
     169}
Note: See TracChangeset for help on using the changeset viewer.