diff options
author | Jason Barron <jbarron@trolltech.com> | 2009-07-24 09:45:33 (GMT) |
---|---|---|
committer | Jason Barron <jbarron@trolltech.com> | 2009-07-27 13:04:30 (GMT) |
commit | 3643028959f0b38350e57e60ba4000435b75e592 (patch) | |
tree | c129e4dee11487abd437ab8ebd993ba261e06fa6 /src/gui/widgets | |
parent | cf66c667a97c0079141eb3f2d9e997b7378ae792 (diff) | |
parent | c36139c665e61866aff4bf8572890a735167a7d0 (diff) | |
download | Qt-3643028959f0b38350e57e60ba4000435b75e592.zip Qt-3643028959f0b38350e57e60ba4000435b75e592.tar.gz Qt-3643028959f0b38350e57e60ba4000435b75e592.tar.bz2 |
Merge commit 'qt/master-stable'
Conflicts:
configure.exe
qmake/Makefile.unix
qmake/generators/makefile.cpp
src/corelib/global/qglobal.h
src/corelib/kernel/kernel.pri
src/corelib/kernel/qcoreevent.cpp
src/corelib/kernel/qsharedmemory_unix.cpp
src/gui/graphicsview/qgraphicsscene.cpp
src/gui/kernel/qaction.cpp
src/gui/kernel/qaction.h
src/gui/kernel/qaction_p.h
src/gui/kernel/qapplication.cpp
src/gui/kernel/qapplication.h
src/gui/kernel/qwidget.cpp
src/gui/kernel/qwidget.h
src/gui/kernel/qwidget_mac.mm
src/gui/painting/qgraphicssystemfactory.cpp
src/gui/styles/qwindowsstyle.cpp
src/gui/text/qfontengine_qpf.cpp
src/gui/widgets/qabstractscrollarea_p.h
src/network/access/qnetworkaccessdebugpipebackend.cpp
src/network/socket/qlocalsocket_unix.cpp
src/network/socket/qnativesocketengine_p.h
src/network/socket/qnativesocketengine_unix.cpp
src/openvg/qpaintengine_vg.cpp
tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp
tests/auto/qcssparser/qcssparser.pro
tests/auto/qdir/tst_qdir.cpp
tests/auto/qfile/tst_qfile.cpp
tests/auto/qobject/tst_qobject.cpp
tests/auto/qpathclipper/qpathclipper.pro
tests/auto/qprocess/tst_qprocess.cpp
tests/auto/qsettings/tst_qsettings.cpp
tests/auto/qsharedpointer/qsharedpointer.pro
tests/auto/qsqlquerymodel/qsqlquerymodel.pro
tests/auto/qsqlrelationaltablemodel/qsqlrelationaltablemodel.pro
tests/auto/qsqltablemodel/qsqltablemodel.pro
tests/auto/qsqlthread/qsqlthread.pro
tests/auto/qwidget/tst_qwidget.cpp
Diffstat (limited to 'src/gui/widgets')
41 files changed, 685 insertions, 616 deletions
diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/gui/widgets/qabstractscrollarea.cpp index a00f77a..391e095 100644 --- a/src/gui/widgets/qabstractscrollarea.cpp +++ b/src/gui/widgets/qabstractscrollarea.cpp @@ -51,10 +51,13 @@ #include "qdebug.h" #include "qboxlayout.h" #include "qpainter.h" +#include "qstandardgestures.h" #include "qabstractscrollarea_p.h" #include <qwidget.h> +#include <private/qapplication_p.h> + #ifdef Q_WS_MAC #include <private/qt_mac_p.h> #include <private/qt_cocoa_helpers_mac_p.h> @@ -157,6 +160,9 @@ QAbstractScrollAreaPrivate::QAbstractScrollAreaPrivate() :hbar(0), vbar(0), vbarpolicy(Qt::ScrollBarAsNeeded), hbarpolicy(Qt::ScrollBarAsNeeded), viewport(0), cornerWidget(0), left(0), top(0), right(0), bottom(0), xoffset(0), yoffset(0), viewportFilter(0) +#ifdef Q_WS_WIN + , singleFingerPanEnabled(false) +#endif { } @@ -290,6 +296,32 @@ void QAbstractScrollAreaPrivate::init() layoutChildren(); } +void QAbstractScrollAreaPrivate::setupGestures() +{ +#ifdef Q_OS_WIN + if (!viewport) + return; + QApplicationPrivate* getQApplicationPrivateInternal(); + QApplicationPrivate *qAppPriv = getQApplicationPrivateInternal(); + bool needh = (hbarpolicy == Qt::ScrollBarAlwaysOn + || (hbarpolicy == Qt::ScrollBarAsNeeded && hbar->minimum() < hbar->maximum())); + + bool needv = (vbarpolicy == Qt::ScrollBarAlwaysOn + || (vbarpolicy == Qt::ScrollBarAsNeeded && vbar->minimum() < vbar->maximum())); + if (qAppPriv->SetGestureConfig && (needh || needv)) { + GESTURECONFIG gc[1]; + gc[0].dwID = GID_PAN; + gc[0].dwWant = GC_PAN; + gc[0].dwBlock = 0; + if (needv && singleFingerPanEnabled) + gc[0].dwWant |= GC_PAN_WITH_SINGLE_FINGER_VERTICALLY; + if (needh && singleFingerPanEnabled) + gc[0].dwWant |= GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY; + qAppPriv->SetGestureConfig(viewport->winId(), 0, 1, gc, sizeof(gc)); + } +#endif // Q_OS_WIN +} + void QAbstractScrollAreaPrivate::layoutChildren() { Q_Q(QAbstractScrollArea); @@ -459,9 +491,6 @@ void QAbstractScrollAreaPrivate::layoutChildren() viewport->setGeometry(QStyle::visualRect(opt.direction, opt.rect, viewportRect)); // resize the viewport last } -// ### Fix for 4.4, talk to Bjoern E or Girish. -void QAbstractScrollAreaPrivate::scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy) {} - /*! \internal @@ -920,7 +949,6 @@ bool QAbstractScrollArea::event(QEvent *e) case QEvent::DragMove: case QEvent::DragLeave: #endif - case QEvent::Gesture: return false; case QEvent::StyleChange: case QEvent::LayoutDirectionChange: @@ -1250,6 +1278,7 @@ void QAbstractScrollAreaPrivate::_q_vslide(int y) void QAbstractScrollAreaPrivate::_q_showOrHideScrollBars() { layoutChildren(); + setupGestures(); } QPoint QAbstractScrollAreaPrivate::contentsOffset() const diff --git a/src/gui/widgets/qabstractscrollarea_p.h b/src/gui/widgets/qabstractscrollarea_p.h index 3a5ee4e..f8ea843 100644 --- a/src/gui/widgets/qabstractscrollarea_p.h +++ b/src/gui/widgets/qabstractscrollarea_p.h @@ -62,7 +62,7 @@ QT_BEGIN_NAMESPACE class QScrollBar; class QAbstractScrollAreaScrollBarContainer; -class QAbstractScrollAreaPrivate: public QFramePrivate +class Q_AUTOTEST_EXPORT QAbstractScrollAreaPrivate: public QFramePrivate { Q_DECLARE_PUBLIC(QAbstractScrollArea) @@ -88,7 +88,7 @@ public: void init(); void layoutChildren(); // ### Fix for 4.4, talk to Bjoern E or Girish. - virtual void scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy); + virtual void scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy) {} void _q_hslide(int); void _q_vslide(int); @@ -99,6 +99,11 @@ public: inline bool viewportEvent(QEvent *event) { return q_func()->viewportEvent(event); } QScopedPointer<QObject> viewportFilter; + +#ifdef Q_WS_WIN + bool singleFingerPanEnabled; +#endif + void setupGestures(); }; class QAbstractScrollAreaFilter : public QObject diff --git a/src/gui/widgets/qabstractspinbox.cpp b/src/gui/widgets/qabstractspinbox.cpp index 155fe3e..8027f9e 100644 --- a/src/gui/widgets/qabstractspinbox.cpp +++ b/src/gui/widgets/qabstractspinbox.cpp @@ -57,6 +57,9 @@ #include <qpalette.h> #include <qstylepainter.h> #include <qdebug.h> +#ifndef QT_NO_ACCESSIBILITY +# include <qaccessible.h> +#endif #if defined(Q_WS_X11) #include <limits.h> @@ -962,6 +965,9 @@ void QAbstractSpinBox::keyPressEvent(QKeyEvent *event) d->buttonState = (Keyboard | (up ? Up : Down)); } stepBy(steps); +#ifndef QT_NO_ACCESSIBILITY + QAccessible::updateAccessibility(this, 0, QAccessible::ValueChanged); +#endif return; } #ifdef QT_KEYPAD_NAVIGATION @@ -1559,6 +1565,9 @@ void QAbstractSpinBoxPrivate::updateState(bool up) spinClickThresholdTimerId = q->startTimer(spinClickThresholdTimerInterval); buttonState = (up ? (Mouse | Up) : (Mouse | Down)); q->stepBy(up ? 1 : -1); +#ifndef QT_NO_ACCESSIBILITY + QAccessible::updateAccessibility(q, 0, QAccessible::ValueChanged); +#endif } } @@ -1579,7 +1588,7 @@ void QAbstractSpinBox::initStyleOption(QStyleOptionSpinBox *option) const option->initFrom(this); option->activeSubControls = QStyle::SC_None; option->buttonSymbols = d->buttonSymbols; - option->subControls = QStyle::SC_SpinBoxFrame; + option->subControls = QStyle::SC_SpinBoxFrame | QStyle::SC_SpinBoxEditField; if (d->buttonSymbols != QAbstractSpinBox::NoButtons) { option->subControls |= QStyle::SC_SpinBoxUp | QStyle::SC_SpinBoxDown; if (d->buttonState & Up) { diff --git a/src/gui/widgets/qcocoatoolbardelegate_mac.mm b/src/gui/widgets/qcocoatoolbardelegate_mac.mm index 894028e..10fe9b0 100644 --- a/src/gui/widgets/qcocoatoolbardelegate_mac.mm +++ b/src/gui/widgets/qcocoatoolbardelegate_mac.mm @@ -43,6 +43,7 @@ #ifdef QT_MAC_USE_COCOA #include <private/qmainwindowlayout_p.h> #include <private/qt_mac_p.h> +#include <private/qt_cocoa_helpers_mac_p.h> #include <private/qcocoaview_mac_p.h> #include <private/qwidget_p.h> #include <qtoolbar.h> @@ -99,7 +100,7 @@ QT_FORWARD_DECLARE_CLASS(QCFString); { Q_UNUSED(flag); Q_UNUSED(nstoolbar); - QToolBar *tb = mainWindowLayout->cocoaItemIDToToolbarHash.value(QCFString::toQString(CFStringRef(itemIdentifier))); + QToolBar *tb = mainWindowLayout->cocoaItemIDToToolbarHash.value(qt_mac_NSStringToQString(itemIdentifier)); NSToolbarItem *item = nil; if (tb) { item = [[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier]; @@ -111,7 +112,7 @@ QT_FORWARD_DECLARE_CLASS(QCFString); - (void)toolbarWillAddItem:(NSNotification *)notification { NSToolbarItem *item = [[notification userInfo] valueForKey:@"item"]; - QToolBar *tb = mainWindowLayout->cocoaItemIDToToolbarHash.value(QCFString::toQString(CFStringRef([item itemIdentifier]))); + QToolBar *tb = mainWindowLayout->cocoaItemIDToToolbarHash.value(qt_mac_NSStringToQString([item itemIdentifier])); if (!tb) return; // I can't really do anything about this. [item retain]; @@ -119,12 +120,9 @@ QT_FORWARD_DECLARE_CLASS(QCFString); NSArray *items = [[qt_mac_window_for(mainWindowLayout->layoutState.mainWindow->window()) toolbar] items]; int someIndex = 0; - bool foundItem = false; for (NSToolbarItem *i in items) { - if (i == item) { - foundItem = true; + if (i == item) break; - } ++someIndex; } mainWindowLayout->toolbarItemsCopy.insert(someIndex, item); diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp index 7b91731..b6fae10 100644 --- a/src/gui/widgets/qcombobox.cpp +++ b/src/gui/widgets/qcombobox.cpp @@ -148,8 +148,10 @@ QStyleOptionMenuItem QComboMenuDelegate::getStyleOption(const QStyleOptionViewIt menuOption.rect = option.rect; // Make sure fonts set on the combo box also overrides the font for the popup menu. - if (mCombo->testAttribute(Qt::WA_SetFont) || mCombo->testAttribute(Qt::WA_MacSmallSize) - || mCombo->testAttribute(Qt::WA_MacMiniSize)) + if (mCombo->testAttribute(Qt::WA_SetFont) + || mCombo->testAttribute(Qt::WA_MacSmallSize) + || mCombo->testAttribute(Qt::WA_MacMiniSize) + || mCombo->font() != qt_app_fonts_hash()->value("QComboBox", QFont())) menuOption.font = mCombo->font(); else menuOption.font = qt_app_fonts_hash()->value("QComboMenuItem", mCombo->font()); diff --git a/src/gui/widgets/qdatetimeedit.cpp b/src/gui/widgets/qdatetimeedit.cpp index 648847a..db57b43 100644 --- a/src/gui/widgets/qdatetimeedit.cpp +++ b/src/gui/widgets/qdatetimeedit.cpp @@ -1936,7 +1936,6 @@ QDateTime QDateTimeEditPrivate::validateAndInterpret(QString &input, int &positi /*! \internal - \reimp */ QString QDateTimeEditPrivate::textFromValue(const QVariant &f) const @@ -1947,7 +1946,6 @@ QString QDateTimeEditPrivate::textFromValue(const QVariant &f) const /*! \internal - \reimp This function's name is slightly confusing; it is not to be confused with QAbstractSpinBox::valueFromText(). @@ -2105,7 +2103,6 @@ QDateTime QDateTimeEditPrivate::stepBy(int sectionIndex, int steps, bool test) c /*! \internal - \reimp */ void QDateTimeEditPrivate::emitSignals(EmitPolicy ep, const QVariant &old) @@ -2135,7 +2132,6 @@ void QDateTimeEditPrivate::emitSignals(EmitPolicy ep, const QVariant &old) /*! \internal - \reimp */ void QDateTimeEditPrivate::_q_editorCursorPositionChanged(int oldpos, int newpos) diff --git a/src/gui/widgets/qdockarealayout.cpp b/src/gui/widgets/qdockarealayout.cpp index 9828413..ee29b55 100644 --- a/src/gui/widgets/qdockarealayout.cpp +++ b/src/gui/widgets/qdockarealayout.cpp @@ -1488,7 +1488,7 @@ bool QDockAreaLayoutInfo::hasFixedSize() const void QDockAreaLayoutInfo::apply(bool animate) { - QWidgetAnimator *widgetAnimator = mainWindowLayout()->widgetAnimator; + QWidgetAnimator &widgetAnimator = mainWindowLayout()->widgetAnimator; #ifndef QT_NO_TABBAR if (tabbed) { @@ -1521,7 +1521,7 @@ void QDockAreaLayoutInfo::apply(bool animate) } } - widgetAnimator->animate(tabBar, tab_rect, animate); + widgetAnimator.animate(tabBar, tab_rect, animate); } #endif // QT_NO_TABBAR @@ -1544,7 +1544,7 @@ void QDockAreaLayoutInfo::apply(bool animate) QWidget *w = item.widgetItem->widget(); QRect geo = w->geometry(); - widgetAnimator->animate(w, r, animate); + widgetAnimator.animate(w, r, animate); if (!w->isHidden()) { QDockWidget *dw = qobject_cast<QDockWidget*>(w); if (!r.isValid() && geo.right() >= 0 && geo.bottom() >= 0) { @@ -1707,7 +1707,7 @@ QDockAreaLayoutItem &QDockAreaLayoutInfo::item(const QList<int> &path) Q_ASSERT(!path.isEmpty()); const int index = path.first(); if (path.count() > 1) { - const QDockAreaLayoutItem &item = item_list.at(index); + const QDockAreaLayoutItem &item = item_list[index]; Q_ASSERT(item.subinfo != 0); return item.subinfo->item(path.mid(1)); } @@ -2074,7 +2074,7 @@ void QDockAreaLayoutInfo::updateTabBar() const QDockAreaLayoutInfo *that = const_cast<QDockAreaLayoutInfo*>(this); - if (tabBar == 0) { + if (that->tabBar == 0) { that->tabBar = mainWindowLayout()->getTabBar(); that->tabBar->setShape(static_cast<QTabBar::Shape>(tabBarShape)); that->tabBar->setDrawBase(true); @@ -3064,13 +3064,13 @@ void QDockAreaLayout::splitDockWidget(QDockWidget *after, void QDockAreaLayout::apply(bool animate) { - QWidgetAnimator *widgetAnimator + QWidgetAnimator &widgetAnimator = qobject_cast<QMainWindowLayout*>(mainWindow->layout())->widgetAnimator; for (int i = 0; i < QInternal::DockCount; ++i) docks[i].apply(animate); if (centralWidgetItem != 0 && !centralWidgetItem->isEmpty()) { - widgetAnimator->animate(centralWidgetItem->widget(), centralWidgetRect, + widgetAnimator.animate(centralWidgetItem->widget(), centralWidgetRect, animate); } diff --git a/src/gui/widgets/qeffects.cpp b/src/gui/widgets/qeffects.cpp index 065a2e0..f3b1b76 100644 --- a/src/gui/widgets/qeffects.cpp +++ b/src/gui/widgets/qeffects.cpp @@ -126,9 +126,9 @@ QAlphaWidget::QAlphaWidget(QWidget* w, Qt::WindowFlags f) QAlphaWidget::~QAlphaWidget() { -#ifdef Q_WS_WIN +#if defined(Q_WS_WIN) && !defined(Q_WS_WINCE) // Restore user-defined opacity value - if (widget && QSysInfo::WindowsVersion >= QSysInfo::WV_2000 && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) + if (widget) widget->setWindowOpacity(windowOpacity); #endif } @@ -160,43 +160,40 @@ void QAlphaWidget::run(int time) checkTime.start(); showWidget = true; -#if defined(Q_OS_WIN) - if (QSysInfo::WindowsVersion >= QSysInfo::WV_2000 && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) { - qApp->installEventFilter(this); - widget->setWindowOpacity(0.0); - widget->show(); +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) + qApp->installEventFilter(this); + widget->setWindowOpacity(0.0); + widget->show(); + connect(&anim, SIGNAL(timeout()), this, SLOT(render())); + anim.start(1); +#else + //This is roughly equivalent to calling setVisible(true) without actually showing the widget + widget->setAttribute(Qt::WA_WState_ExplicitShowHide, true); + widget->setAttribute(Qt::WA_WState_Hidden, false); + + qApp->installEventFilter(this); + + move(widget->geometry().x(),widget->geometry().y()); + resize(widget->size().width(), widget->size().height()); + + frontImage = QPixmap::grabWidget(widget).toImage(); + backImage = QPixmap::grabWindow(QApplication::desktop()->winId(), + widget->geometry().x(), widget->geometry().y(), + widget->geometry().width(), widget->geometry().height()).toImage(); + + if (!backImage.isNull() && checkTime.elapsed() < duration / 2) { + mixedImage = backImage.copy(); + pm = QPixmap::fromImage(mixedImage); + show(); + setEnabled(false); + connect(&anim, SIGNAL(timeout()), this, SLOT(render())); anim.start(1); - } else -#endif - { - //This is roughly equivalent to calling setVisible(true) without actually showing the widget - widget->setAttribute(Qt::WA_WState_ExplicitShowHide, true); - widget->setAttribute(Qt::WA_WState_Hidden, false); - - qApp->installEventFilter(this); - - move(widget->geometry().x(),widget->geometry().y()); - resize(widget->size().width(), widget->size().height()); - - frontImage = QPixmap::grabWidget(widget).toImage(); - backImage = QPixmap::grabWindow(QApplication::desktop()->winId(), - widget->geometry().x(), widget->geometry().y(), - widget->geometry().width(), widget->geometry().height()).toImage(); - - if (!backImage.isNull() && checkTime.elapsed() < duration / 2) { - mixedImage = backImage.copy(); - pm = QPixmap::fromImage(mixedImage); - show(); - setEnabled(false); - - connect(&anim, SIGNAL(timeout()), this, SLOT(render())); - anim.start(1); - } else { - duration = 0; - render(); - } + } else { + duration = 0; + render(); } +#endif } /* @@ -270,19 +267,17 @@ void QAlphaWidget::render() else alpha = 1; -#if defined(Q_OS_WIN) - if (QSysInfo::WindowsVersion >= QSysInfo::WV_2000 && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) { - if (alpha >= windowOpacity || !showWidget) { - anim.stop(); - qApp->removeEventFilter(this); - widget->setWindowOpacity(windowOpacity); - q_blend = 0; - deleteLater(); - } else { - widget->setWindowOpacity(alpha); - } - } else -#endif +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) + if (alpha >= windowOpacity || !showWidget) { + anim.stop(); + qApp->removeEventFilter(this); + widget->setWindowOpacity(windowOpacity); + q_blend = 0; + deleteLater(); + } else { + widget->setWindowOpacity(alpha); + } +#else if (alpha >= 1 || !showWidget) { anim.stop(); qApp->removeEventFilter(this); @@ -292,7 +287,7 @@ void QAlphaWidget::render() #ifdef Q_WS_WIN setEnabled(true); setFocus(); -#endif +#endif // Q_WS_WIN widget->hide(); } else { //Since we are faking the visibility of the widget @@ -309,6 +304,7 @@ void QAlphaWidget::render() pm = QPixmap::fromImage(mixedImage); repaint(); } +#endif // defined(Q_OS_WIN) && !defined(Q_OS_WINCE) } /* diff --git a/src/gui/widgets/qfontcombobox.cpp b/src/gui/widgets/qfontcombobox.cpp index 9660399..f87ccd3 100644 --- a/src/gui/widgets/qfontcombobox.cpp +++ b/src/gui/widgets/qfontcombobox.cpp @@ -263,7 +263,7 @@ void QFontComboBoxPrivate::_q_currentChanged(const QString &text) { Q_Q(QFontComboBox); QFont newFont(text); - if (currentFont != newFont) { + if (currentFont.family() != newFont.family()) { currentFont = newFont; emit q->currentFontChanged(currentFont); } diff --git a/src/gui/widgets/qframe.cpp b/src/gui/widgets/qframe.cpp index b9e769d..a87ec85 100644 --- a/src/gui/widgets/qframe.cpp +++ b/src/gui/widgets/qframe.cpp @@ -135,7 +135,7 @@ inline void QFramePrivate::init() \value VLine QFrame draws a vertical line that frames nothing (useful as separator) \value WinPanel draws a rectangular panel that can be raised or - sunken like those in Windows 95. Specifying this shape sets + sunken like those in Windows 2000. Specifying this shape sets the line width to 2 pixels. WinPanel is provided for compatibility. For GUI style independence we recommend using StyledPanel instead. diff --git a/src/gui/widgets/qgroupbox.cpp b/src/gui/widgets/qgroupbox.cpp index 0bfa8c0..5758b6a 100644 --- a/src/gui/widgets/qgroupbox.cpp +++ b/src/gui/widgets/qgroupbox.cpp @@ -431,7 +431,7 @@ void QGroupBoxPrivate::_q_fixFocus(Qt::FocusReason reason) { Q_Q(QGroupBox); QWidget *fw = q->focusWidget(); - if (!fw) { + if (!fw || fw == q) { QWidget * best = 0; QWidget * candidate = 0; QWidget * w = q; @@ -449,8 +449,7 @@ void QGroupBoxPrivate::_q_fixFocus(Qt::FocusReason reason) } if (best) fw = best; - else - if (candidate) + else if (candidate) fw = candidate; } if (fw) @@ -479,11 +478,7 @@ void QGroupBox::focusInEvent(QFocusEvent *fe) if (focusPolicy() == Qt::NoFocus) { d->_q_fixFocus(fe->reason()); } else { - QStyleOptionGroupBox box; - initStyleOption(&box); - QRect rect = style()->subControlRect(QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxCheckBox, this) - | style()->subControlRect(QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxLabel, this); - update(rect); + QWidget::focusInEvent(fe); } } diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp index 4d69a9f..01d5711 100644 --- a/src/gui/widgets/qlineedit.cpp +++ b/src/gui/widgets/qlineedit.cpp @@ -2181,7 +2181,8 @@ void QLineEdit::keyPressEvent(QKeyEvent *event) if (unknown && !d->readOnly) { QString t = event->text(); - if (!t.isEmpty() && t.at(0).isPrint()) { + if (!t.isEmpty() && t.at(0).isPrint() && + ((event->modifiers() & (Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier)) == Qt::NoModifier)) { insert(t); #ifndef QT_NO_COMPLETER d->complete(event->key()); diff --git a/src/gui/widgets/qmainwindow.cpp b/src/gui/widgets/qmainwindow.cpp index c9706cf..b75b5ea 100644 --- a/src/gui/widgets/qmainwindow.cpp +++ b/src/gui/widgets/qmainwindow.cpp @@ -1374,20 +1374,25 @@ bool QMainWindow::event(QEvent *event) #ifdef Q_WS_MAC case QEvent::Show: if (unifiedTitleAndToolBarOnMac()) - macWindowToolbarShow(this, true); + d->layout->syncUnifiedToolbarVisibility(); + d->layout->blockVisiblityCheck = false; break; -# ifdef QT_MAC_USE_COCOA case QEvent::WindowStateChange: { + if (isHidden()) { + // We are coming out of a minimize, leave things as is. + d->layout->blockVisiblityCheck = true; + } +# ifdef QT_MAC_USE_COCOA // We need to update the HIToolbar status when we go out of or into fullscreen. QWindowStateChangeEvent *wce = static_cast<QWindowStateChangeEvent *>(event); if ((windowState() & Qt::WindowFullScreen) || (wce->oldState() & Qt::WindowFullScreen)) { d->layout->updateHIToolBarStatus(); } +# endif // Cocoa } break; -# endif // Cocoa -#endif +#endif // Q_WS_MAC #if !defined(QT_NO_DOCKWIDGET) && !defined(QT_NO_CURSOR) case QEvent::CursorChange: if (d->cursorAdjusted) { diff --git a/src/gui/widgets/qmainwindowlayout.cpp b/src/gui/widgets/qmainwindowlayout.cpp index 526e7a5..3936a67 100644 --- a/src/gui/widgets/qmainwindowlayout.cpp +++ b/src/gui/widgets/qmainwindowlayout.cpp @@ -237,7 +237,7 @@ void QMainWindowLayoutState::apply(bool animated) if (centralWidgetItem != 0) { QMainWindowLayout *layout = qobject_cast<QMainWindowLayout*>(mainWindow->layout()); Q_ASSERT(layout != 0); - layout->widgetAnimator->animate(centralWidgetItem->widget(), centralWidgetRect, animated); + layout->widgetAnimator.animate(centralWidgetItem->widget(), centralWidgetRect, animated); } #endif } @@ -426,42 +426,42 @@ QList<int> QMainWindowLayoutState::gapIndex(QWidget *widget, return result; } -bool QMainWindowLayoutState::insertGap(QList<int> path, QLayoutItem *item) +bool QMainWindowLayoutState::insertGap(const QList<int> &path, QLayoutItem *item) { if (path.isEmpty()) return false; - int i = path.takeFirst(); + int i = path.first(); #ifndef QT_NO_TOOLBAR if (i == 0) { Q_ASSERT(qobject_cast<QToolBar*>(item->widget()) != 0); - return toolBarAreaLayout.insertGap(path, item); + return toolBarAreaLayout.insertGap(path.mid(1), item); } #endif #ifndef QT_NO_DOCKWIDGET if (i == 1) { Q_ASSERT(qobject_cast<QDockWidget*>(item->widget()) != 0); - return dockAreaLayout.insertGap(path, item); + return dockAreaLayout.insertGap(path.mid(1), item); } #endif //QT_NO_DOCKWIDGET return false; } -void QMainWindowLayoutState::remove(QList<int> path) +void QMainWindowLayoutState::remove(const QList<int> &path) { - int i = path.takeFirst(); + int i = path.first(); #ifndef QT_NO_TOOLBAR if (i == 0) - toolBarAreaLayout.remove(path); + toolBarAreaLayout.remove(path.mid(1)); #endif #ifndef QT_NO_DOCKWIDGET if (i == 1) - dockAreaLayout.remove(path); + dockAreaLayout.remove(path.mid(1)); #endif //QT_NO_DOCKWIDGET } @@ -501,88 +501,88 @@ bool QMainWindowLayoutState::isValid() const return rect.isValid(); } -QLayoutItem *QMainWindowLayoutState::item(QList<int> path) +QLayoutItem *QMainWindowLayoutState::item(const QList<int> &path) { - int i = path.takeFirst(); + int i = path.first(); #ifndef QT_NO_TOOLBAR if (i == 0) - return toolBarAreaLayout.item(path).widgetItem; + return toolBarAreaLayout.item(path.mid(1)).widgetItem; #endif #ifndef QT_NO_DOCKWIDGET if (i == 1) - return dockAreaLayout.item(path).widgetItem; + return dockAreaLayout.item(path.mid(1)).widgetItem; #endif //QT_NO_DOCKWIDGET return 0; } -QRect QMainWindowLayoutState::itemRect(QList<int> path) const +QRect QMainWindowLayoutState::itemRect(const QList<int> &path) const { - int i = path.takeFirst(); + int i = path.first(); #ifndef QT_NO_TOOLBAR if (i == 0) - return toolBarAreaLayout.itemRect(path); + return toolBarAreaLayout.itemRect(path.mid(1)); #endif #ifndef QT_NO_DOCKWIDGET if (i == 1) - return dockAreaLayout.itemRect(path); + return dockAreaLayout.itemRect(path.mid(1)); #endif //QT_NO_DOCKWIDGET return QRect(); } -QRect QMainWindowLayoutState::gapRect(QList<int> path) const +QRect QMainWindowLayoutState::gapRect(const QList<int> &path) const { - int i = path.takeFirst(); + int i = path.first(); #ifndef QT_NO_TOOLBAR if (i == 0) - return toolBarAreaLayout.itemRect(path); + return toolBarAreaLayout.itemRect(path.mid(1)); #endif #ifndef QT_NO_DOCKWIDGET if (i == 1) - return dockAreaLayout.gapRect(path); + return dockAreaLayout.gapRect(path.mid(1)); #endif //QT_NO_DOCKWIDGET return QRect(); } -QLayoutItem *QMainWindowLayoutState::plug(QList<int> path) +QLayoutItem *QMainWindowLayoutState::plug(const QList<int> &path) { - int i = path.takeFirst(); + int i = path.first(); #ifndef QT_NO_TOOLBAR if (i == 0) - return toolBarAreaLayout.plug(path); + return toolBarAreaLayout.plug(path.mid(1)); #endif #ifndef QT_NO_DOCKWIDGET if (i == 1) - return dockAreaLayout.plug(path); + return dockAreaLayout.plug(path.mid(1)); #endif //QT_NO_DOCKWIDGET return 0; } -QLayoutItem *QMainWindowLayoutState::unplug(QList<int> path, QMainWindowLayoutState *other) +QLayoutItem *QMainWindowLayoutState::unplug(const QList<int> &path, QMainWindowLayoutState *other) { - int i = path.takeFirst(); + int i = path.first(); #ifdef QT_NO_TOOLBAR Q_UNUSED(other); #else if (i == 0) - return toolBarAreaLayout.unplug(path, other ? &other->toolBarAreaLayout : 0); + return toolBarAreaLayout.unplug(path.mid(1), other ? &other->toolBarAreaLayout : 0); #endif #ifndef QT_NO_DOCKWIDGET if (i == 1) - return dockAreaLayout.unplug(path); + return dockAreaLayout.unplug(path.mid(1)); #endif //QT_NO_DOCKWIDGET return 0; @@ -939,16 +939,70 @@ void QMainWindowLayout::getStyleOptionInfo(QStyleOptionToolBar *option, QToolBar void QMainWindowLayout::toggleToolBarsVisible() { - layoutState.toolBarAreaLayout.visible = !layoutState.toolBarAreaLayout.visible; - if (!layoutState.mainWindow->isMaximized()){ - QPoint topLeft = parentWidget()->geometry().topLeft(); - QRect r = parentWidget()->geometry(); - r = layoutState.toolBarAreaLayout.rectHint(r); - r.moveTo(topLeft); - parentWidget()->setGeometry(r); -// widgetAnimator->animate(parentWidget(), r, true); - } else{ - update(); + bool updateNonUnifiedParts = true; +#ifdef Q_WS_MAC + if (layoutState.mainWindow->unifiedTitleAndToolBarOnMac()) { + // If we hit this case, someone has pressed the "toolbar button" which will + // toggle the unified toolbar visiblity, because that's what the user wants. + // We might be in a situation where someone has hidden all the toolbars + // beforehand (maybe in construction), but now they've hit this button and + // and are expecting the items to show. What do we do? + // 1) Check the visibility of all the toolbars, if one is visible, do nothing, this + // preserves what people would expect (these toolbars were visible when I clicked last time). + // 2) If NONE are visible, then show them all. Again, this preserves the user expectation + // of, "I want to see the toolbars." The user may get more toolbars than expected, but this + // is better seeing nothing. + // Don't worry about any of this if we are going invisible. This does mean we may get + // into issues when switching into and out of fullscreen mode, but this is probably minor. + // If we ever need to do hiding, that would have to be taken care of after the unified toolbar + // has finished hiding. + // People can of course handle the QEvent::ToolBarChange event themselves and do + // WHATEVER they want if they don't like what we are doing (though the unified toolbar + // will fire regardless). + + // Check if we REALLY need to update the geometry below. If we only have items in the + // unified toolbar, all the docks will be empty, so there's very little point + // in doing the geometry as Apple will do it (we also avoid flicker in Cocoa as well). + // FWIW, layoutState.toolBarAreaLayout.visible and the state of the unified toolbar + // visibility can get out of sync. I really don't think it's a big issue. It is kept + // to a minimum because we only change the visibility if we absolutely must. + // update the "non unified parts." + updateNonUnifiedParts = !layoutState.toolBarAreaLayout.isEmpty(); + + // We get this function before the unified toolbar does its thing. + // So, the value will be opposite of what we expect. + bool goingVisible = !macWindowToolbarIsVisible(qt_mac_window_for(layoutState.mainWindow)); + if (goingVisible) { + const int ToolBarCount = qtoolbarsInUnifiedToolbarList.size(); + bool needAllVisible = true; + for (int i = 0; i < ToolBarCount; ++i) { + if (!qtoolbarsInUnifiedToolbarList.at(i)->isHidden()) { + needAllVisible = false; + break; + } + } + if (needAllVisible) { + QBoolBlocker blocker(blockVisiblityCheck); // Disable the visibilty check because + // the toggle has already happened. + for (int i = 0; i < ToolBarCount; ++i) + qtoolbarsInUnifiedToolbarList.at(i)->setVisible(true); + } + } + if (!updateNonUnifiedParts) + layoutState.toolBarAreaLayout.visible = goingVisible; + } +#endif + if (updateNonUnifiedParts) { + layoutState.toolBarAreaLayout.visible = !layoutState.toolBarAreaLayout.visible; + if (!layoutState.mainWindow->isMaximized()) { + QPoint topLeft = parentWidget()->geometry().topLeft(); + QRect r = parentWidget()->geometry(); + r = layoutState.toolBarAreaLayout.rectHint(r); + r.moveTo(topLeft); + parentWidget()->setGeometry(r); + } else { + update(); + } } } @@ -1361,7 +1415,7 @@ QLayoutItem *QMainWindowLayout::takeAt(int index) if (QLayoutItem *ret = layoutState.takeAt(index, &x)) { // the widget might in fact have been destroyed by now if (QWidget *w = ret->widget()) { - widgetAnimator->abort(w); + widgetAnimator.abort(w); if (w == pluggingWidget) pluggingWidget = 0; } @@ -1528,75 +1582,28 @@ bool QMainWindowLayout::plug(QLayoutItem *widgetItem) layoutState.remove(previousPath); pluggingWidget = widget; - if (dockOptions & QMainWindow::AnimatedDocks) { - QRect globalRect = currentGapRect; - globalRect.moveTopLeft(parentWidget()->mapToGlobal(globalRect.topLeft())); + QRect globalRect = currentGapRect; + globalRect.moveTopLeft(parentWidget()->mapToGlobal(globalRect.topLeft())); #ifndef QT_NO_DOCKWIDGET - if (qobject_cast<QDockWidget*>(widget) != 0) { - QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(widget->layout()); - if (layout->nativeWindowDeco()) { - globalRect.adjust(0, layout->titleHeight(), 0, 0); - } else { - int fw = widget->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, widget); - globalRect.adjust(-fw, -fw, fw, fw); - } + if (qobject_cast<QDockWidget*>(widget) != 0) { + QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(widget->layout()); + if (layout->nativeWindowDeco()) { + globalRect.adjust(0, layout->titleHeight(), 0, 0); + } else { + int fw = widget->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, widget); + globalRect.adjust(-fw, -fw, fw, fw); } -#endif - widgetAnimator->animate(widget, globalRect, - dockOptions & QMainWindow::AnimatedDocks); - } else { -#ifndef QT_NO_DOCKWIDGET - if (QDockWidget *dw = qobject_cast<QDockWidget*>(widget)) - dw->d_func()->plug(currentGapRect); -#endif -#ifndef QT_NO_TOOLBAR - if (QToolBar *tb = qobject_cast<QToolBar*>(widget)) - tb->d_func()->plug(currentGapRect); -#endif - applyState(layoutState); - savedState.clear(); -#ifndef QT_NO_DOCKWIDGET - parentWidget()->update(layoutState.dockAreaLayout.separatorRegion()); -#endif - currentGapPos.clear(); - updateGapIndicator(); - pluggingWidget = 0; } +#endif + widgetAnimator.animate(widget, globalRect, dockOptions & QMainWindow::AnimatedDocks); return true; } -void QMainWindowLayout::allAnimationsFinished() -{ -#ifndef QT_NO_DOCKWIDGET - parentWidget()->update(layoutState.dockAreaLayout.separatorRegion()); - -#ifndef QT_NO_TABBAR - foreach (QTabBar *tab_bar, usedTabBars) - tab_bar->show(); -#endif // QT_NO_TABBAR -#endif // QT_NO_DOCKWIDGET - - updateGapIndicator(); -} - void QMainWindowLayout::animationFinished(QWidget *widget) { - - /* This signal is delivered from QWidgetAnimator over a qeued connection. The problem is that - the widget can be deleted. This is handled as follows: - - The animator only ever animates widgets that have been added to this layout. If a widget - is deleted during animation, the widget's destructor removes the widget form this layout. - This in turn aborts the animation (see takeAt()) and this signal will never be delivered. - - If the widget is deleted after the animation is finished but before this qeued signal - is delivered, the widget is no longer in the layout and we catch it here. The key is that - QMainWindowLayoutState::contains() never dereferences the pointer. */ - - if (!layoutState.contains(widget)) - return; - + //this function is called from within the Widget Animator whenever an animation is finished + //on a certain widget #ifndef QT_NO_TOOLBAR if (QToolBar *tb = qobject_cast<QToolBar*>(widget)) { QToolBarLayout *tbl = qobject_cast<QToolBarLayout*>(tb->layout()); @@ -1609,32 +1616,44 @@ void QMainWindowLayout::animationFinished(QWidget *widget) } #endif - if (widget != pluggingWidget) - return; + if (widget == pluggingWidget) { #ifndef QT_NO_DOCKWIDGET - if (QDockWidget *dw = qobject_cast<QDockWidget*>(widget)) - dw->d_func()->plug(currentGapRect); + if (QDockWidget *dw = qobject_cast<QDockWidget*>(widget)) + dw->d_func()->plug(currentGapRect); #endif #ifndef QT_NO_TOOLBAR - if (QToolBar *tb = qobject_cast<QToolBar*>(widget)) - tb->d_func()->plug(currentGapRect); + if (QToolBar *tb = qobject_cast<QToolBar*>(widget)) + tb->d_func()->plug(currentGapRect); #endif - applyState(layoutState, false); #ifndef QT_NO_DOCKWIDGET #ifndef QT_NO_TABBAR - if (qobject_cast<QDockWidget*>(widget) != 0) { - // info() might return null if the widget is destroyed while - // animating but before the animationFinished signal is received. - if (QDockAreaLayoutInfo *info = layoutState.dockAreaLayout.info(widget)) - info->setCurrentTab(widget); - } + if (qobject_cast<QDockWidget*>(widget) != 0) { + // info() might return null if the widget is destroyed while + // animating but before the animationFinished signal is received. + if (QDockAreaLayoutInfo *info = layoutState.dockAreaLayout.info(widget)) + info->setCurrentTab(widget); + } #endif #endif - savedState.clear(); - currentGapPos.clear(); - pluggingWidget = 0; + + savedState.clear(); + currentGapPos.clear(); + pluggingWidget = 0; + } + + if (!widgetAnimator.animating()) { + //all animations are finished +#ifndef QT_NO_DOCKWIDGET + parentWidget()->update(layoutState.dockAreaLayout.separatorRegion()); +#ifndef QT_NO_TABBAR + foreach (QTabBar *tab_bar, usedTabBars) + tab_bar->show(); +#endif // QT_NO_TABBAR +#endif // QT_NO_DOCKWIDGET + } + updateGapIndicator(); } @@ -1667,6 +1686,14 @@ QMainWindowLayout::QMainWindowLayout(QMainWindow *mainwindow) #endif #endif #endif // QT_NO_DOCKWIDGET + , widgetAnimator(this) + , pluggingWidget(0) +#ifndef QT_NO_RUBBERBAND + , gapIndicator(new QRubberBand(QRubberBand::Rectangle, mainwindow)) +#endif //QT_NO_RUBBERBAND +#ifdef Q_WS_MAC + , blockVisiblityCheck(false) +#endif { #ifndef QT_NO_DOCKWIDGET #ifndef QT_NO_TABBAR @@ -1680,20 +1707,13 @@ QMainWindowLayout::QMainWindowLayout(QMainWindow *mainwindow) #endif // QT_NO_DOCKWIDGET #ifndef QT_NO_RUBBERBAND - gapIndicator = new QRubberBand(QRubberBand::Rectangle, mainwindow); // For accessibility to identify this special widget. gapIndicator->setObjectName(QLatin1String("qt_rubberband")); - gapIndicator->hide(); #endif pluggingWidget = 0; setObjectName(mainwindow->objectName() + QLatin1String("_layout")); - widgetAnimator = new QWidgetAnimator(this); - connect(widgetAnimator, SIGNAL(finished(QWidget*)), - this, SLOT(animationFinished(QWidget*)), Qt::QueuedConnection); - connect(widgetAnimator, SIGNAL(finishedAll()), - this, SLOT(allAnimationsFinished())); } QMainWindowLayout::~QMainWindowLayout() @@ -1795,14 +1815,8 @@ QLayoutItem *QMainWindowLayout::unplug(QWidget *widget) void QMainWindowLayout::updateGapIndicator() { #ifndef QT_NO_RUBBERBAND - if (widgetAnimator->animating() || currentGapPos.isEmpty()) { - gapIndicator->hide(); - } else { - if (gapIndicator->geometry() != currentGapRect) - gapIndicator->setGeometry(currentGapRect); - if (!gapIndicator->isVisible()) - gapIndicator->show(); - } + gapIndicator->setVisible(!widgetAnimator.animating() && !currentGapPos.isEmpty()); + gapIndicator->setGeometry(currentGapRect); #endif } diff --git a/src/gui/widgets/qmainwindowlayout_mac.mm b/src/gui/widgets/qmainwindowlayout_mac.mm index 6632be7..61719c2 100644 --- a/src/gui/widgets/qmainwindowlayout_mac.mm +++ b/src/gui/widgets/qmainwindowlayout_mac.mm @@ -338,18 +338,16 @@ void QMainWindowLayout::updateHIToolBarStatus() 0, kWindowUnifiedTitleAndToolbarAttribute); } #endif - macWindowToolbarShow(layoutState.mainWindow, useMacToolbar); layoutState.mainWindow->setUpdatesEnabled(false); // reduces a little bit of flicker, not all though if (!useMacToolbar) { - OSWindowRef windowRef = qt_mac_window_for(parentWidget()); - macWindowToolbarShow(parentWidget(), false); + macWindowToolbarShow(layoutState.mainWindow, false); // Move everything out of the HIToolbar into the main toolbar. while (!qtoolbarsInUnifiedToolbarList.isEmpty()) { // Should shrink the list by one every time. layoutState.mainWindow->addToolBar(Qt::TopToolBarArea, qtoolbarsInUnifiedToolbarList.first()); } - macWindowToolbarSet(windowRef, NULL); + macWindowToolbarSet(qt_mac_window_for(layoutState.mainWindow), 0); } else { QList<QToolBar *> toolbars = layoutState.mainWindow->findChildren<QToolBar *>(); for (int i = 0; i < toolbars.size(); ++i) { @@ -359,6 +357,7 @@ void QMainWindowLayout::updateHIToolBarStatus() layoutState.mainWindow->addToolBar(Qt::TopToolBarArea, toolbar); } } + syncUnifiedToolbarVisibility(); } layoutState.mainWindow->setUpdatesEnabled(true); } @@ -439,7 +438,7 @@ void QMainWindowLayout::insertIntoMacToolbar(QToolBar *before, QToolBar *toolbar #else NSString *toolbarID = kQToolBarNSToolbarIdentifier; toolbarID = [toolbarID stringByAppendingFormat:@"%p", toolbar]; - cocoaItemIDToToolbarHash.insert(QCFString::toQString(CFStringRef(toolbarID)), toolbar); + cocoaItemIDToToolbarHash.insert(qt_mac_NSStringToQString(toolbarID), toolbar); [macToolbar insertItemWithItemIdentifier:toolbarID atIndex:beforeIndex]; #endif } @@ -487,6 +486,7 @@ void QMainWindowLayout::cleanUpMacToolbarItems() void QMainWindowLayout::fixSizeInUnifiedToolbar(QToolBar *tb) const { +#ifdef QT_MAC_USE_COCOA QHash<void *, QToolBar *>::const_iterator it = unifiedToolbarHash.constBegin(); NSToolbarItem *item = nil; while (it != unifiedToolbarHash.constEnd()) { @@ -507,5 +507,26 @@ void QMainWindowLayout::fixSizeInUnifiedToolbar(QToolBar *tb) const nssize.height = size.height() - 2; [item setMinSize:nssize]; } +#else + Q_UNUSED(tb); +#endif } + +void QMainWindowLayout::syncUnifiedToolbarVisibility() +{ + if (blockVisiblityCheck) + return; + + Q_ASSERT(layoutState.mainWindow->unifiedTitleAndToolBarOnMac()); + bool show = false; + const int ToolBarCount = qtoolbarsInUnifiedToolbarList.count(); + for (int i = 0; i < ToolBarCount; ++i) { + if (qtoolbarsInUnifiedToolbarList.at(i)->isVisible()) { + show = true; + break; + } + } + macWindowToolbarShow(layoutState.mainWindow, show); +} + QT_END_NAMESPACE diff --git a/src/gui/widgets/qmainwindowlayout_p.h b/src/gui/widgets/qmainwindowlayout_p.h index 26f8633..524fdbf 100644 --- a/src/gui/widgets/qmainwindowlayout_p.h +++ b/src/gui/widgets/qmainwindowlayout_p.h @@ -63,6 +63,7 @@ #include "QtCore/qset.h" #include "QtCore/qbasictimer.h" #include "private/qlayoutengine_p.h" +#include "private/qwidgetanimator_p.h" #include "qdockarealayout_p.h" #include "qtoolbararealayout_p.h" @@ -89,7 +90,6 @@ typedef const struct __CFString * CFStringRef; QT_BEGIN_NAMESPACE class QToolBar; -class QWidgetAnimator; class QRubberBand; /* This data structure represents the state of all the tool-bars and dock-widgets. It's value based @@ -128,9 +128,9 @@ public: QLayoutItem *itemAt(int index, int *x) const; QLayoutItem *takeAt(int index, int *x); QList<int> indexOf(QWidget *widget) const; - QLayoutItem *item(QList<int> path); - QRect itemRect(QList<int> path) const; - QRect gapRect(QList<int> path) const; // ### get rid of this, use itemRect() instead + QLayoutItem *item(const QList<int> &path); + QRect itemRect(const QList<int> &path) const; + QRect gapRect(const QList<int> &path) const; // ### get rid of this, use itemRect() instead bool contains(QWidget *widget) const; @@ -138,14 +138,14 @@ public: QWidget *centralWidget() const; QList<int> gapIndex(QWidget *widget, const QPoint &pos) const; - bool insertGap(QList<int> path, QLayoutItem *item); - void remove(QList<int> path); + bool insertGap(const QList<int> &path, QLayoutItem *item); + void remove(const QList<int> &path); void remove(QLayoutItem *item); void clear(); bool isValid() const; - QLayoutItem *plug(QList<int> path); - QLayoutItem *unplug(QList<int> path, QMainWindowLayoutState *savedState = 0); + QLayoutItem *plug(const QList<int> &path); + QLayoutItem *unplug(const QList<int> &path, QMainWindowLayoutState *savedState = 0); void saveState(QDataStream &stream) const; bool checkFormat(QDataStream &stream, bool pre43); @@ -278,7 +278,7 @@ public: // animations - QWidgetAnimator *widgetAnimator; + QWidgetAnimator widgetAnimator; QList<int> currentGapPos; QRect currentGapRect; QWidget *pluggingWidget; @@ -295,10 +295,9 @@ public: void applyState(QMainWindowLayoutState &newState, bool animate = true); void restore(bool keepSavedState = false); void updateHIToolBarStatus(); - -private slots: void animationFinished(QWidget *widget); - void allAnimationsFinished(); + +private Q_SLOTS: #ifndef QT_NO_DOCKWIDGET #ifndef QT_NO_TABBAR void tabChanged(); @@ -336,6 +335,8 @@ public: void cleanUpMacToolbarItems(); void fixSizeInUnifiedToolbar(QToolBar *tb) const; bool useHIToolBar; + void syncUnifiedToolbarVisibility(); + bool blockVisiblityCheck; #endif }; QT_END_NAMESPACE diff --git a/src/gui/widgets/qmdisubwindow.cpp b/src/gui/widgets/qmdisubwindow.cpp index 25bc724..e8de957 100644 --- a/src/gui/widgets/qmdisubwindow.cpp +++ b/src/gui/widgets/qmdisubwindow.cpp @@ -1066,7 +1066,7 @@ void QMdiSubWindowPrivate::createSystemMenu() addToSystemMenu(CloseAction, QMdiSubWindow::tr("&Close"), SLOT(close())); actions[CloseAction]->setIcon(style->standardIcon(QStyle::SP_TitleBarCloseButton, 0, q)); #if !defined(QT_NO_SHORTCUT) - actions[CloseAction]->setShortcut(QKeySequence::Close); + actions[CloseAction]->setShortcuts(QKeySequence::Close); #endif updateActions(); } @@ -1946,26 +1946,21 @@ QPalette QMdiSubWindowPrivate::desktopPalette() const colorref2qrgb(GetSysColor(COLOR_CAPTIONTEXT))); newPalette.setColor(QPalette::Inactive, QPalette::HighlightedText, colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTIONTEXT))); - if (QSysInfo::WindowsVersion != QSysInfo::WV_95 - && QSysInfo::WindowsVersion != QSysInfo::WV_NT) { - colorsInitialized = true; - BOOL hasGradient; - QT_WA({ - SystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, &hasGradient, 0); - } , { - SystemParametersInfoA(SPI_GETGRADIENTCAPTIONS, 0, &hasGradient, 0); - }); - if (hasGradient) { - newPalette.setColor(QPalette::Active, QPalette::Base, - colorref2qrgb(GetSysColor(COLOR_GRADIENTACTIVECAPTION))); - newPalette.setColor(QPalette::Inactive, QPalette::Base, - colorref2qrgb(GetSysColor(COLOR_GRADIENTINACTIVECAPTION))); - } else { - newPalette.setColor(QPalette::Active, QPalette::Base, - newPalette.color(QPalette::Active, QPalette::Highlight)); - newPalette.setColor(QPalette::Inactive, QPalette::Base, - newPalette.color(QPalette::Inactive, QPalette::Highlight)); - } + + colorsInitialized = true; + BOOL hasGradient = false; + SystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, &hasGradient, 0); + + if (hasGradient) { + newPalette.setColor(QPalette::Active, QPalette::Base, + colorref2qrgb(GetSysColor(COLOR_GRADIENTACTIVECAPTION))); + newPalette.setColor(QPalette::Inactive, QPalette::Base, + colorref2qrgb(GetSysColor(COLOR_GRADIENTINACTIVECAPTION))); + } else { + newPalette.setColor(QPalette::Active, QPalette::Base, + newPalette.color(QPalette::Active, QPalette::Highlight)); + newPalette.setColor(QPalette::Inactive, QPalette::Base, + newPalette.color(QPalette::Inactive, QPalette::Highlight)); } } #endif // Q_WS_WIN diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index 43dc33a..b69e8bb 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -164,6 +164,12 @@ void QMenuPrivate::init() } } +int QMenuPrivate::scrollerHeight() const +{ + Q_Q(const QMenu); + return qMax(QApplication::globalStrut().height(), q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q)); +} + //Windows and KDE allows menus to cover the taskbar, while GNOME and Mac don't QRect QMenuPrivate::popupGeometry(int screen) const { @@ -258,7 +264,6 @@ void QMenuPrivate::updateActionRects() const //let the style modify the above size.. QStyleOptionMenuItem opt; q->initStyleOption(&opt, action); - opt.rect = q->rect(); const QFontMetrics &fm = opt.fontMetrics; QSize sz; @@ -281,10 +286,7 @@ void QMenuPrivate::updateActionRects() const tabWidth = qMax(int(tabWidth), qfm.width(seq)); #endif } - int w = fm.boundingRect(QRect(), Qt::TextSingleLine, s).width(); - w -= s.count(QLatin1Char('&')) * fm.width(QLatin1Char('&')); - w += s.count(QLatin1String("&&")) * fm.width(QLatin1Char('&')); - sz.setWidth(w); + sz.setWidth(fm.boundingRect(QRect(), Qt::TextSingleLine | Qt::TextShowMnemonic, s).width()); sz.setHeight(qMax(fm.height(), qfm.height())); QIcon is = action->icon(); @@ -484,17 +486,17 @@ void QMenuPrivate::setSyncAction() void QMenuPrivate::setFirstActionActive() { Q_Q(QMenu); - const int scrollerHeight = q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q); + updateActionRects(); for(int i = 0, saccum = 0; i < actions.count(); i++) { - QAction *act = actions.at(i); const QRect &rect = actionRects.at(i); if (rect.isNull()) continue; if (scroll && scroll->scrollFlags & QMenuScroller::ScrollUp) { saccum -= rect.height(); - if (saccum > scroll->scrollOffset-scrollerHeight) + if (saccum > scroll->scrollOffset - scrollerHeight()) continue; } + QAction *act = actions.at(i); if (!act->isSeparator() && (q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, q) || act->isEnabled())) { @@ -673,17 +675,16 @@ void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation loc Q_Q(QMenu); if (!scroll || !scroll->scrollFlags) return; + updateActionRects(); int newOffset = 0; - const int scrollHeight = q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q); - const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp) ? scrollHeight : 0; - const int botScroll = (scroll->scrollFlags & QMenuScroller::ScrollDown) ? scrollHeight : 0; + const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp) ? scrollerHeight() : 0; + const int botScroll = (scroll->scrollFlags & QMenuScroller::ScrollDown) ? scrollerHeight() : 0; const int vmargin = q->style()->pixelMetric(QStyle::PM_MenuVMargin, 0, q); const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q); if (location == QMenuScroller::ScrollTop) { for(int i = 0, saccum = 0; i < actions.count(); i++) { - QAction *act = actions.at(i); - if (act == action) { + if (actions.at(i) == action) { newOffset = topScroll - saccum; break; } @@ -691,9 +692,8 @@ void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation loc } } else { for(int i = 0, saccum = 0; i < actions.count(); i++) { - QAction *act = actions.at(i); saccum += actionRects.at(i).height(); - if (act == action) { + if (actions.at(i) == action) { if (location == QMenuScroller::ScrollCenter) newOffset = ((q->height() / 2) - botScroll) - (saccum - topScroll); else @@ -762,9 +762,19 @@ void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation loc } //actually update flags - scroll->scrollOffset = newOffset; - if (scroll->scrollOffset > 0) - scroll->scrollOffset = 0; + const int delta = qMin(0, newOffset) - scroll->scrollOffset; //make sure the new offset is always negative + if (!itemsDirty && delta) { + //we've scrolled so we need to update the action rects + for (int i = 0; i < actionRects.count(); ++i) { + QRect ¤t = actionRects[i]; + current.moveTop(current.top() + delta); + + //we need to update the widgets geometry + if (QWidget *w = widgetItems.at(i)) + w->setGeometry(current); + } + } + scroll->scrollOffset += delta; scroll->scrollFlags = newScrollFlags; if (active) setCurrentAction(action); @@ -775,6 +785,7 @@ void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation loc void QMenuPrivate::scrollMenu(QMenuScroller::ScrollLocation location, bool active) { Q_Q(QMenu); + updateActionRects(); if(location == QMenuScroller::ScrollBottom) { for(int i = actions.size()-1; i >= 0; --i) { QAction *act = actions.at(i); @@ -814,9 +825,9 @@ void QMenuPrivate::scrollMenu(QMenuScroller::ScrollDirection direction, bool pag Q_Q(QMenu); if (!scroll || !(scroll->scrollFlags & direction)) //not really possible... return; - const int scrollHeight = q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q); - const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp) ? scrollHeight : 0; - const int botScroll = (scroll->scrollFlags & QMenuScroller::ScrollDown) ? scrollHeight : 0; + updateActionRects(); + const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp) ? scrollerHeight() : 0; + const int botScroll = (scroll->scrollFlags & QMenuScroller::ScrollDown) ? scrollerHeight() : 0; const int vmargin = q->style()->pixelMetric(QStyle::PM_MenuVMargin, 0, q); const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q); const int offset = topScroll ? topScroll-vmargin : 0; @@ -863,13 +874,12 @@ bool QMenuPrivate::mouseEventTaken(QMouseEvent *e) if (scroll && !activeMenu) { //let the scroller "steal" the event bool isScroll = false; if (pos.x() >= 0 && pos.x() < q->width()) { - const int scrollerHeight = q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q); for(int dir = QMenuScroller::ScrollUp; dir <= QMenuScroller::ScrollDown; dir = dir << 1) { if (scroll->scrollFlags & dir) { if (dir == QMenuScroller::ScrollUp) - isScroll = (pos.y() <= scrollerHeight); + isScroll = (pos.y() <= scrollerHeight()); else if (dir == QMenuScroller::ScrollDown) - isScroll = (pos.y() >= q->height()-scrollerHeight); + isScroll = (pos.y() >= q->height() - scrollerHeight()); if (isScroll) { scroll->scrollDirection = dir; break; @@ -878,19 +888,17 @@ bool QMenuPrivate::mouseEventTaken(QMouseEvent *e) } } if (isScroll) { - if (!scroll->scrollTimer) - scroll->scrollTimer = new QBasicTimer; - scroll->scrollTimer->start(50, q); + scroll->scrollTimer.start(50, q); return true; - } else if (scroll->scrollTimer && scroll->scrollTimer->isActive()) { - scroll->scrollTimer->stop(); + } else { + scroll->scrollTimer.stop(); } } if (tearoff) { //let the tear off thingie "steal" the event.. QRect tearRect(0, 0, q->width(), q->style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, q)); if (scroll && scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp) - tearRect.translate(0, q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q)); + tearRect.translate(0, scrollerHeight()); q->update(tearRect); if (tearRect.contains(pos) && hasMouseMoved(e->globalPos())) { setCurrentAction(0); @@ -1351,8 +1359,7 @@ QMenu::~QMenu() if (d->eventLoop) d->eventLoop->exit(); - if (d->tornPopup) - d->tornPopup->close(); + hideTearOffMenu(); } /*! @@ -1563,8 +1570,8 @@ void QMenu::setTearOffEnabled(bool b) Q_D(QMenu); if (d->tearoff == b) return; - if (!b && d->tornPopup) - d->tornPopup->close(); + if (!b) + hideTearOffMenu(); d->tearoff = b; d->itemsDirty = true; @@ -1599,8 +1606,8 @@ bool QMenu::isTearOffMenuVisible() const */ void QMenu::hideTearOffMenu() { - if (d_func()->tornPopup) - d_func()->tornPopup->close(); + if (QWidget *w = d_func()->tornPopup) + w->close(); } @@ -1715,8 +1722,6 @@ QSize QMenu::sizeHint() const if (rect.right() >= s.width()) s.setWidth(rect.x() + rect.width()); } - if (d->tearoff) - s.rheight() += style()->pixelMetric(QStyle::PM_MenuTearoffHeight, &opt, this); // Note that the action rects calculated above already include // the top and left margins, so we only need to add margins for // the bottom and right. @@ -2076,6 +2081,8 @@ void QMenu::hideEvent(QHideEvent *) d->hasHadMouse = false; d->causedPopup.widget = 0; d->causedPopup.action = 0; + if (d->scroll) + d->scroll->scrollTimer.stop(); //make sure the timer stops } /*! @@ -2084,6 +2091,7 @@ void QMenu::hideEvent(QHideEvent *) void QMenu::paintEvent(QPaintEvent *e) { Q_D(QMenu); + d->updateActionRects(); QPainter p(this); QRegion emptyArea = QRegion(rect()); @@ -2116,18 +2124,17 @@ void QMenu::paintEvent(QPaintEvent *e) const int fw = style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, this); //draw the scroller regions.. if (d->scroll) { - const int scrollerHeight = style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, this); menuOpt.menuItemType = QStyleOptionMenuItem::Scroller; menuOpt.state |= QStyle::State_Enabled; if (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp) { - menuOpt.rect.setRect(fw, fw, width() - (fw * 2), scrollerHeight); + menuOpt.rect.setRect(fw, fw, width() - (fw * 2), d->scrollerHeight()); emptyArea -= QRegion(menuOpt.rect); p.setClipRect(menuOpt.rect); style()->drawControl(QStyle::CE_MenuScroller, &menuOpt, &p, this); } if (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollDown) { - menuOpt.rect.setRect(fw, height() - scrollerHeight - fw, width() - (fw * 2), - scrollerHeight); + menuOpt.rect.setRect(fw, height() - d->scrollerHeight() - fw, width() - (fw * 2), + d->scrollerHeight()); emptyArea -= QRegion(menuOpt.rect); menuOpt.state |= QStyle::State_DownArrow; p.setClipRect(menuOpt.rect); @@ -2140,7 +2147,7 @@ void QMenu::paintEvent(QPaintEvent *e) menuOpt.rect.setRect(fw, fw, width() - (fw * 2), style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this)); if (d->scroll && d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp) - menuOpt.rect.translate(0, style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, this)); + menuOpt.rect.translate(0, d->scrollerHeight()); emptyArea -= QRegion(menuOpt.rect); p.setClipRect(menuOpt.rect); menuOpt.state = QStyle::State_None; @@ -2370,6 +2377,7 @@ bool QMenu::focusNextPrevChild(bool next) void QMenu::keyPressEvent(QKeyEvent *e) { Q_D(QMenu); + d->updateActionRects(); int key = e->key(); if (isRightToLeft()) { // in reverse mode open/close key for submenues are reversed if (key == Qt::Key_Left) @@ -2469,7 +2477,7 @@ void QMenu::keyPressEvent(QKeyEvent *e) continue; nextAction = next; if (d->scroll && (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)) { - int topVisible = style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, this); + int topVisible = d->scrollerHeight(); if (d->tearoff) topVisible += style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this); if (((y + d->scroll->scrollOffset) - topVisible) <= d->actionRects.at(next_i).height()) @@ -2500,10 +2508,9 @@ void QMenu::keyPressEvent(QKeyEvent *e) continue; nextAction = next; if (d->scroll && (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollDown)) { - const int scrollerHeight = style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, this); - int bottomVisible = height()-scrollerHeight; + int bottomVisible = height() - d->scrollerHeight(); if (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp) - bottomVisible -= scrollerHeight; + bottomVisible -= d->scrollerHeight(); if (d->tearoff) bottomVisible -= style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this); if ((y + d->scroll->scrollOffset + d->actionRects.at(next_i).height()) > bottomVisible) @@ -2519,8 +2526,7 @@ void QMenu::keyPressEvent(QKeyEvent *e) } if (nextAction) { if (d->scroll && scroll_loc != QMenuPrivate::QMenuScroller::ScrollStay) { - if (d->scroll->scrollTimer) - d->scroll->scrollTimer->stop(); + d->scroll->scrollTimer.stop(); d->scrollMenu(nextAction, scroll_loc); } d->setCurrentAction(nextAction, /*popup*/-1, QMenuPrivate::SelectedFromKeyboard); @@ -2782,10 +2788,10 @@ void QMenu::timerEvent(QTimerEvent *e) { Q_D(QMenu); - if (d->scroll && d->scroll->scrollTimer && d->scroll->scrollTimer->timerId() == e->timerId()) { + if (d->scroll && d->scroll->scrollTimer.timerId() == e->timerId()) { d->scrollMenu((QMenuPrivate::QMenuScroller::ScrollDirection)d->scroll->scrollDirection); if (d->scroll->scrollFlags == QMenuPrivate::QMenuScroller::ScrollNone) - d->scroll->scrollTimer->stop(); + d->scroll->scrollTimer.stop(); } else if(QMenuPrivate::menuDelayTimer.timerId() == e->timerId()) { QMenuPrivate::menuDelayTimer.stop(); internalDelayedPopup(); diff --git a/src/gui/widgets/qmenu_mac.mm b/src/gui/widgets/qmenu_mac.mm index 77e98c4..87f6f82 100644 --- a/src/gui/widgets/qmenu_mac.mm +++ b/src/gui/widgets/qmenu_mac.mm @@ -1376,8 +1376,9 @@ QMenuPrivate::QMacMenuPrivate::syncAction(QMacMenuAction *action) accel = qt_mac_menu_merge_accel(action); } } + // Show multiple key sequences as part of the menu text. if (accel.count() > 1) - text += QLatin1String(" (****)"); //just to denote a multi stroke shortcut + text += QLatin1String(" (") + accel.toString(QKeySequence::NativeText) + QLatin1String(")"); QString finalString = qt_mac_removeMnemonics(text); @@ -1459,14 +1460,15 @@ QMenuPrivate::QMacMenuPrivate::syncAction(QMacMenuAction *action) data.whichData |= kMenuItemDataCmdKey; data.whichData |= kMenuItemDataCmdKeyModifiers; data.whichData |= kMenuItemDataCmdKeyGlyph; - if (!accel.isEmpty()) { + if (accel.count() == 1) { qt_mac_get_accel(accel[0], (quint32*)&data.cmdKeyModifiers, (quint32*)&data.cmdKeyGlyph); if (data.cmdKeyGlyph == 0) data.cmdKey = (UniChar)accel[0]; } #else [item setSubmenu:0]; - if (!accel.isEmpty()) { + // No key equivalent set for multiple key QKeySequence. + if (accel.count() == 1) { [item setKeyEquivalent:keySequenceToKeyEqivalent(accel)]; [item setKeyEquivalentModifierMask:keySequenceModifierMask(accel)]; } else { diff --git a/src/gui/widgets/qmenu_p.h b/src/gui/widgets/qmenu_p.h index d9ad422..355ecb4 100644 --- a/src/gui/widgets/qmenu_p.h +++ b/src/gui/widgets/qmenu_p.h @@ -170,6 +170,8 @@ public: } void init(); + int scrollerHeight() const; + //item calculations mutable uint itemsDirty : 1; mutable uint maxIconWidth, tabWidth; @@ -208,10 +210,10 @@ public: enum ScrollDirection { ScrollNone=0, ScrollUp=0x01, ScrollDown=0x02 }; uint scrollFlags : 2, scrollDirection : 2; int scrollOffset; - QBasicTimer *scrollTimer; + QBasicTimer scrollTimer; - QMenuScroller() : scrollFlags(ScrollNone), scrollDirection(ScrollNone), scrollOffset(0), scrollTimer(0) { } - ~QMenuScroller() { delete scrollTimer; } + QMenuScroller() : scrollFlags(ScrollNone), scrollDirection(ScrollNone), scrollOffset(0) { } + ~QMenuScroller() { } } *scroll; void scrollMenu(QMenuScroller::ScrollLocation location, bool active=false); void scrollMenu(QMenuScroller::ScrollDirection direction, bool page=false, bool active=false); diff --git a/src/gui/widgets/qmenubar.cpp b/src/gui/widgets/qmenubar.cpp index 4607fc3..bb1dd29 100644 --- a/src/gui/widgets/qmenubar.cpp +++ b/src/gui/widgets/qmenubar.cpp @@ -218,7 +218,7 @@ void QMenuBarPrivate::updateGeometries() bool hasHiddenActions = false; for (int i = 0; i < actions.count(); ++i) { const QRect &rect = actionRects.at(i); - if (!menuRect.contains(rect)) { + if (rect.isValid() && !menuRect.contains(rect)) { hasHiddenActions = true; break; } @@ -229,7 +229,7 @@ void QMenuBarPrivate::updateGeometries() menuRect = this->menuRect(true); for (int i = 0; i < actions.count(); ++i) { const QRect &rect = actionRects.at(i); - if (!menuRect.contains(rect)) { + if (rect.isValid() && !menuRect.contains(rect)) { hiddenActions.append(actions.at(i)); } } @@ -279,6 +279,7 @@ QRect QMenuBarPrivate::actionRect(QAction *act) const void QMenuBarPrivate::focusFirstAction() { if(!currentAction) { + updateGeometries(); int index = 0; while (index < actions.count() && actionRects.at(index).isNull()) ++index; if (index < actions.count()) @@ -446,10 +447,7 @@ void QMenuBarPrivate::calcActionRects(int max_width, int start) const } else { const QString s = action->text(); if(!s.isEmpty()) { - const int w = fm.width(s) - - s.count(QLatin1Char('&')) * fm.width(QLatin1Char('&')) - + s.count(QLatin1String("&&")) * fm.width(QLatin1Char('&')); - sz = QSize(w, fm.height()); + sz = fm.size(Qt::TextShowMnemonic, s); } QIcon is = action->icon(); @@ -764,6 +762,7 @@ void QMenuBarPrivate::init() QAction *QMenuBarPrivate::getNextAction(const int _start, const int increment) const { Q_Q(const QMenuBar); + const_cast<QMenuBarPrivate*>(this)->updateGeometries(); bool allowActiveAndDisabled = q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, q); const int start = (_start == -1 && increment == -1) ? actions.count() : _start; const int end = increment == -1 ? 0 : actions.count() - 1; @@ -964,6 +963,13 @@ void QMenuBar::setActiveAction(QAction *act) /*! Removes all the actions from the menu bar. + \note On Mac OS X, menu items that have been merged to the system + menu bar are not removed by this function. One way to handle this + would be to remove the extra actions yourself. You can set the + \l{QAction::MenuRole}{menu role} on the different menus, so that + you know ahead of time which menu items get merged and which do + not. Then decide what to recreate or remove yourself. + \sa removeAction() */ void QMenuBar::clear() @@ -1140,6 +1146,7 @@ void QMenuBar::mouseReleaseEvent(QMouseEvent *e) void QMenuBar::keyPressEvent(QKeyEvent *e) { Q_D(QMenuBar); + d->updateGeometries(); int key = e->key(); if(isRightToLeft()) { // in reverse mode open/close key for submenues are reversed if(key == Qt::Key_Left) @@ -1630,6 +1637,7 @@ QSize QMenuBar::minimumSizeHint() const ensurePolished(); QSize ret(0, 0); + const_cast<QMenuBarPrivate*>(d)->updateGeometries(); const int hmargin = style()->pixelMetric(QStyle::PM_MenuBarHMargin, 0, this); const int vmargin = style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, this); int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, this); diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp index c2ef5e4..7d9d2b5 100644 --- a/src/gui/widgets/qplaintextedit.cpp +++ b/src/gui/widgets/qplaintextedit.cpp @@ -66,6 +66,8 @@ #include <qtexttable.h> #include <qvariant.h> +#include <qstandardgestures.h> + #include <qinputcontext.h> #ifndef QT_NO_TEXTEDIT @@ -255,7 +257,7 @@ QPlainTextDocumentLayoutPrivate *QPlainTextDocumentLayout::priv() const */ void QPlainTextDocumentLayout::requestUpdate() { - emit update(QRectF(0., -4., 1000000000., 1000000000.)); + emit update(QRectF(0., -document()->documentMargin(), 1000000000., 1000000000.)); } @@ -350,8 +352,7 @@ void QPlainTextDocumentLayout::documentChanged(int from, int /*charsRemoved*/, i } if (!d->blockUpdate) - emit update(); // optimization potential - + emit update(QRectF(0., -doc->documentMargin(), 1000000000., 1000000000.)); // optimization potential } @@ -732,6 +733,9 @@ QPlainTextEditPrivate::QPlainTextEditPrivate() backgroundVisible = false; centerOnScroll = false; inDrag = false; +#ifdef Q_WS_WIN + singleFingerPanEnabled = true; +#endif } @@ -787,6 +791,9 @@ void QPlainTextEditPrivate::init(const QString &txt) #ifndef QT_NO_CURSOR viewport->setCursor(Qt::IBeamCursor); #endif + originalOffsetY = 0; + panGesture = new QPanGesture(q); + QObject::connect(panGesture, SIGNAL(triggered()), q, SLOT(_q_gestureTriggered())); } void QPlainTextEditPrivate::_q_repaintContents(const QRectF &contentsRect) @@ -2915,6 +2922,30 @@ QAbstractTextDocumentLayout::PaintContext QPlainTextEdit::getPaintContext() cons (\a available is true) or unavailable (\a available is false). */ +void QPlainTextEditPrivate::_q_gestureTriggered() +{ + Q_Q(QPlainTextEdit); + QPanGesture *g = qobject_cast<QPanGesture*>(q->sender()); + if (!g) + return; + QScrollBar *hBar = q->horizontalScrollBar(); + QScrollBar *vBar = q->verticalScrollBar(); + if (g->state() == Qt::GestureStarted) + originalOffsetY = vBar->value(); + QSize totalOffset = g->totalOffset(); + if (!totalOffset.isNull()) { + if (QApplication::isRightToLeft()) + totalOffset.rwidth() *= -1; + // QPlainTextEdit scrolls by lines only in vertical direction + QFontMetrics fm(q->document()->defaultFont()); + int lineHeight = fm.height(); + int newX = hBar->value() - g->lastOffset().width(); + int newY = originalOffsetY - totalOffset.height()/lineHeight; + hbar->setValue(newX); + vbar->setValue(newY); + } +} + QT_END_NAMESPACE #include "moc_qplaintextedit.cpp" diff --git a/src/gui/widgets/qplaintextedit.h b/src/gui/widgets/qplaintextedit.h index dc0851b..35bbc37 100644 --- a/src/gui/widgets/qplaintextedit.h +++ b/src/gui/widgets/qplaintextedit.h @@ -269,6 +269,7 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_adjustScrollbars()) Q_PRIVATE_SLOT(d_func(), void _q_verticalScrollbarActionTriggered(int)) Q_PRIVATE_SLOT(d_func(), void _q_cursorPositionChanged()) + Q_PRIVATE_SLOT(d_func(), void _q_gestureTriggered()) friend class QPlainTextEditControl; }; diff --git a/src/gui/widgets/qplaintextedit_p.h b/src/gui/widgets/qplaintextedit_p.h index 851702d..739fd89 100644 --- a/src/gui/widgets/qplaintextedit_p.h +++ b/src/gui/widgets/qplaintextedit_p.h @@ -72,6 +72,7 @@ class QMimeData; class QPlainTextEdit; class ExtraArea; +class QPanGesture; class QPlainTextEditControl : public QTextControl { @@ -177,6 +178,10 @@ public: void _q_cursorPositionChanged(); void _q_modificationChanged(bool); + + void _q_gestureTriggered(); + int originalOffsetY; + QPanGesture *panGesture; }; QT_END_NAMESPACE diff --git a/src/gui/widgets/qprogressbar.cpp b/src/gui/widgets/qprogressbar.cpp index ac3338b..6593cd6 100644 --- a/src/gui/widgets/qprogressbar.cpp +++ b/src/gui/widgets/qprogressbar.cpp @@ -204,7 +204,7 @@ bool QProgressBarPrivate::repaintRequired() const \o A progress bar shown in the Plastique widget style. \endtable - \sa QTimeLine, QProgressDialog, {fowler}{GUI Design Handbook: Progress Indicator} + \sa QProgressDialog, {fowler}{GUI Design Handbook: Progress Indicator} */ /*! @@ -443,11 +443,11 @@ QSize QProgressBar::minimumSizeHint() const QString QProgressBar::text() const { Q_D(const QProgressBar); - if (d->maximum == 0 || d->value < d->minimum + if ((d->maximum == 0 && d->minimum == 0) || d->value < d->minimum || (d->value == INT_MIN && d->minimum == INT_MIN)) return QString(); - qint64 totalSteps = qint64(d->maximum) - qint64(d->minimum); + qint64 totalSteps = qint64(d->maximum) - d->minimum; QString result = d->format; result.replace(QLatin1String("%m"), QString::number(totalSteps)); @@ -461,7 +461,7 @@ QString QProgressBar::text() const return result; } - int progress = int(((qreal(d->value) - qreal(d->minimum)) * 100.0) / totalSteps); + int progress = (qreal(d->value) - d->minimum) * 100.0 / totalSteps; result.replace(QLatin1String("%p"), QString::number(progress)); return result; } diff --git a/src/gui/widgets/qsizegrip.cpp b/src/gui/widgets/qsizegrip.cpp index d263b9c..c6aae68 100644 --- a/src/gui/widgets/qsizegrip.cpp +++ b/src/gui/widgets/qsizegrip.cpp @@ -335,8 +335,7 @@ void QSizeGrip::mousePressEvent(QMouseEvent * e) orientation = d->atLeft() ? SZ_SIZETOPLEFT : SZ_SIZETOPRIGHT; ReleaseCapture(); - QT_WA_INLINE(PostMessageW(tlw->winId(), WM_SYSCOMMAND, orientation, 0), - PostMessageA(tlw->winId(), WM_SYSCOMMAND, orientation, 0)); + PostMessage(tlw->winId(), WM_SYSCOMMAND, orientation, 0); return; } #endif // Q_WS_WIN diff --git a/src/gui/widgets/qspinbox.cpp b/src/gui/widgets/qspinbox.cpp index 9ec21d6..193b15c 100644 --- a/src/gui/widgets/qspinbox.cpp +++ b/src/gui/widgets/qspinbox.cpp @@ -50,6 +50,7 @@ #include <qdebug.h> #include <math.h> +#include <float.h> QT_BEGIN_NAMESPACE @@ -832,8 +833,8 @@ void QDoubleSpinBox::setRange(double minimum, double maximum) Sets how many decimals the spinbox will use for displaying and interpreting doubles. - \warning The results might not be reliable with very high values - for \a decimals. + \warning The maximum value for \a decimals is DBL_MAX_10_EXP + + DBL_DIG (ie. 323) because of the limitations of the double type. Note: The maximum, minimum and value might change as a result of changing this property. @@ -849,7 +850,7 @@ int QDoubleSpinBox::decimals() const void QDoubleSpinBox::setDecimals(int decimals) { Q_D(QDoubleSpinBox); - d->decimals = qMax(0, decimals); + d->decimals = qBound(0, decimals, DBL_MAX_10_EXP + DBL_DIG); setRange(minimum(), maximum()); // make sure values are rounded setValue(value()); @@ -1214,7 +1215,7 @@ bool QDoubleSpinBoxPrivate::isIntermediateValue(const QString &str) const return false; } if (doright) { - QSBDEBUG("match %lld min_left %lld max_left %lld", match, min_left, max_left); + QSBDEBUG() << "match" << match << "min_left" << min_left << "max_left" << max_left; if (!doleft) { if (min_left == max_left) { const bool ret = isIntermediateValueHelper(qAbs(left), @@ -1481,7 +1482,7 @@ QString QDoubleSpinBoxPrivate::textFromValue(const QVariant &f) const static bool isIntermediateValueHelper(qint64 num, qint64 min, qint64 max, qint64 *match) { - QSBDEBUG("%lld %lld %lld", num, min, max); + QSBDEBUG() << num << min << max; if (num >= min && num <= max) { if (match) diff --git a/src/gui/widgets/qtabbar.cpp b/src/gui/widgets/qtabbar.cpp index 11cb6a1..690e624 100644 --- a/src/gui/widgets/qtabbar.cpp +++ b/src/gui/widgets/qtabbar.cpp @@ -663,7 +663,7 @@ void QTabBarPrivate::refresh() if (pressedIndex != -1 && movable && QApplication::mouseButtons() == Qt::NoButton) { - _q_moveTabFinished(pressedIndex); + moveTabFinished(pressedIndex); if (!validIndex(pressedIndex)) pressedIndex = -1; } @@ -1662,26 +1662,17 @@ void QTabBarPrivate::slide(int from, int to) q->setUpdatesEnabled(true); int postLocation = vertical ? q->tabRect(to).y() : q->tabRect(to).x(); int length = postLocation - preLocation; - tabList[to].makeTimeLine(q); - tabList[to].dragOffset += -1 * length; - tabList[to].timeLine->setFrameRange(tabList[to].dragOffset, 0); - animations[tabList[to].timeLine] = to; - tabList[to].timeLine->setDuration(ANIMATION_DURATION); - if (tabList[to].timeLine->state() != QTimeLine::Running) - tabList[to].timeLine->start(); + tabList[to].dragOffset -= length; + tabList[to].startAnimation(this, ANIMATION_DURATION); } -void QTabBarPrivate::_q_moveTab(int offset) +void QTabBarPrivate::moveTab(int index, int offset) { - Q_Q(QTabBar); - if (QTimeLine *timeLine = qobject_cast<QTimeLine *>(q->sender())) { - int index = animations[timeLine]; - if (!validIndex(index)) - return; - tabList[index].dragOffset = offset; - layoutTab(index); // Make buttons follow tab - q->update(); - } + if (!validIndex(index)) + return; + tabList[index].dragOffset = offset; + layoutTab(index); // Make buttons follow tab + q_func()->update(); } /*!\reimp @@ -1695,7 +1686,7 @@ void QTabBar::mousePressEvent(QMouseEvent *event) } // Be safe! if (d->pressedIndex != -1 && d->movable) - d->_q_moveTabFinished(d->pressedIndex); + d->moveTabFinished(d->pressedIndex); d->pressedIndex = d->indexAtPos(event->pos()); if (d->validIndex(d->pressedIndex)) { @@ -1721,7 +1712,7 @@ void QTabBar::mouseMoveEvent(QMouseEvent *event) // Be safe! if (d->pressedIndex != -1 && event->buttons() == Qt::NoButton) - d->_q_moveTabFinished(d->pressedIndex); + d->moveTabFinished(d->pressedIndex); // Start drag if (!d->dragInProgress && d->pressedIndex != -1) { @@ -1789,16 +1780,6 @@ void QTabBar::mouseMoveEvent(QMouseEvent *event) optTabBase.documentMode = d->documentMode; } -void QTabBarPrivate::_q_moveTabFinished() -{ - Q_Q(QTabBar); - if (QTimeLine *timeLine = qobject_cast<QTimeLine *>(q->sender())) { - int index = animations[timeLine]; - animations.remove(timeLine); - _q_moveTabFinished(index); - } -} - void QTabBarPrivate::setupMovableTab() { Q_Q(QTabBar); @@ -1838,11 +1819,19 @@ void QTabBarPrivate::setupMovableTab() movingTab->setVisible(true); } -void QTabBarPrivate::_q_moveTabFinished(int index) +void QTabBarPrivate::moveTabFinished(int index) { Q_Q(QTabBar); bool cleanup = (pressedIndex == index) || (pressedIndex == -1) || !validIndex(index); - if (animations.isEmpty() && cleanup) { + bool allAnimationsFinished = true; +#ifndef QT_NO_ANIMATION + for(int i = 0; allAnimationsFinished && i < tabList.count(); ++i) { + const Tab &t = tabList.at(i); + if (t.animation && t.animation->state() == QAbstractAnimation::Running) + allAnimationsFinished = false; + } +#endif //QT_NO_ANIMATION + if (allAnimationsFinished && cleanup) { movingTab->setVisible(false); // We might not get a mouse release for (int i = 0; i < tabList.count(); ++i) { tabList[i].dragOffset = 0; @@ -1877,17 +1866,8 @@ void QTabBar::mouseReleaseEvent(QMouseEvent *event) ? tabRect(d->pressedIndex).height() : tabRect(d->pressedIndex).width(); int duration = qMin(ANIMATION_DURATION, - ((length < 0 ? (-1 * length) : length) * ANIMATION_DURATION) / width); - if (duration > 0) { - d->tabList[d->pressedIndex].makeTimeLine(this); - d->tabList[d->pressedIndex].timeLine->setFrameRange(length, 0); - d->animations[d->tabList[d->pressedIndex].timeLine] = d->pressedIndex; - d->tabList[d->pressedIndex].timeLine->setDuration(duration); - if (d->tabList[d->pressedIndex].timeLine->state() != QTimeLine::Running) - d->tabList[d->pressedIndex].timeLine->start(); - } else { - d->_q_moveTabFinished(d->pressedIndex); - } + (qAbs(length) * ANIMATION_DURATION) / width); + d->tabList[d->pressedIndex].startAnimation(d, duration); d->dragInProgress = false; d->movingTab->setVisible(false); d->dragStartPosition = QPoint(); diff --git a/src/gui/widgets/qtabbar.h b/src/gui/widgets/qtabbar.h index 7514486..402f54b 100644 --- a/src/gui/widgets/qtabbar.h +++ b/src/gui/widgets/qtabbar.h @@ -215,8 +215,6 @@ private: Q_DECLARE_PRIVATE(QTabBar) Q_PRIVATE_SLOT(d_func(), void _q_scrollTabs()) Q_PRIVATE_SLOT(d_func(), void _q_closeTab()) - Q_PRIVATE_SLOT(d_func(), void _q_moveTab(int)) - Q_PRIVATE_SLOT(d_func(), void _q_moveTabFinished()) }; #endif // QT_NO_TABBAR diff --git a/src/gui/widgets/qtabbar_p.h b/src/gui/widgets/qtabbar_p.h index dbae055..b9b9fba 100644 --- a/src/gui/widgets/qtabbar_p.h +++ b/src/gui/widgets/qtabbar_p.h @@ -58,9 +58,8 @@ #include <qicon.h> #include <qtoolbutton.h> -#include <qtimeline.h> -#include <qhash.h> #include <qdebug.h> +#include <qvariantanimation.h> #ifndef QT_NO_TABBAR @@ -75,9 +74,10 @@ class QTabBarPrivate : public QWidgetPrivate Q_DECLARE_PUBLIC(QTabBar) public: QTabBarPrivate() - :currentIndex(-1), pressedIndex(-1), - shape(QTabBar::RoundedNorth), - layoutDirty(false), drawBase(true), scrollOffset(0), expanding(true), closeButtonOnTabs(false), selectionBehaviorOnRemove(QTabBar::SelectRightTab), paintWithOffsets(true), movable(false), dragInProgress(false), documentMode(false), movingTab(0) {} + :currentIndex(-1), pressedIndex(-1), shape(QTabBar::RoundedNorth), layoutDirty(false), + drawBase(true), scrollOffset(0), expanding(true), closeButtonOnTabs(false), + selectionBehaviorOnRemove(QTabBar::SelectRightTab), paintWithOffsets(true), movable(false), + dragInProgress(false), documentMode(false), movingTab(0) {} int currentIndex; int pressedIndex; @@ -88,16 +88,13 @@ public: struct Tab { inline Tab(const QIcon &ico, const QString &txt) - : enabled(true) - , shortcutId(0) - , text(txt) - , icon(ico) - , leftWidget(0) - , rightWidget(0) - , lastTab(-1) - , timeLine(0) - , dragOffset(0) + : enabled(true) , shortcutId(0), text(txt), icon(ico), + leftWidget(0), rightWidget(0), lastTab(-1), dragOffset(0) +#ifndef QT_NO_ANIMATION + , animation(0) +#endif //QT_NO_ANIMATION {} + bool operator==(const Tab &other) const { return &other == this; } bool enabled; int shortcutId; QString text; @@ -117,21 +114,39 @@ public: QWidget *leftWidget; QWidget *rightWidget; int lastTab; - - QTimeLine *timeLine; int dragOffset; - void makeTimeLine(QWidget *q) { - if (timeLine) - return; - timeLine = new QTimeLine(ANIMATION_DURATION, q); - q->connect(timeLine, SIGNAL(frameChanged(int)), q, SLOT(_q_moveTab(int))); - q->connect(timeLine, SIGNAL(finished()), q, SLOT(_q_moveTabFinished())); +#ifndef QT_NO_ANIMATION + ~Tab() { delete animation; } + struct TabBarAnimation : public QVariantAnimation { + TabBarAnimation(Tab *t, QTabBarPrivate *_priv) : tab(t), priv(_priv) + { setEasingCurve(QEasingCurve::InOutQuad); } + + void updateCurrentValue(const QVariant ¤t) + { priv->moveTab(priv->tabList.indexOf(*tab), current.toInt()); } + + void updateState(State, State newState) + { if (newState == Stopped) priv->moveTabFinished(priv->tabList.indexOf(*tab)); } + private: + //these are needed for the callbacks + Tab *tab; + QTabBarPrivate *priv; + } *animation; + + void startAnimation(QTabBarPrivate *priv, int duration) { + if (!animation) + animation = new TabBarAnimation(this, priv); + animation->setStartValue(dragOffset); + animation->setEndValue(0); + animation->setDuration(duration); + animation->start(); } - +#else + void startAnimation(QTabBarPrivate *priv, int duration) + { Q_UNUSED(duration); priv->moveTabFinished(priv->tabList.indexOf(*this)); } +#endif //QT_NO_ANIMATION }; QList<Tab> tabList; - QHash<QTimeLine*, int> animations; int calculateNewPosition(int from, int to, int index) const; void slide(int from, int to); @@ -152,9 +167,8 @@ public: void _q_scrollTabs(); void _q_closeTab(); - void _q_moveTab(int); - void _q_moveTabFinished(); - void _q_moveTabFinished(int offset); + void moveTab(int index, int offset); + void moveTabFinished(int index); QRect hoverRect; void refresh(); diff --git a/src/gui/widgets/qtextedit.cpp b/src/gui/widgets/qtextedit.cpp index 3bac94b..2de661a 100644 --- a/src/gui/widgets/qtextedit.cpp +++ b/src/gui/widgets/qtextedit.cpp @@ -67,6 +67,8 @@ #include <qtexttable.h> #include <qvariant.h> +#include <qstandardgestures.h> + #include <qinputcontext.h> #endif @@ -116,6 +118,9 @@ QTextEditPrivate::QTextEditPrivate() preferRichText = false; showCursorOnInitialShow = true; inDrag = false; +#ifdef Q_WS_WIN + singleFingerPanEnabled = true; +#endif } void QTextEditPrivate::createAutoBulletList() @@ -183,6 +188,8 @@ void QTextEditPrivate::init(const QString &html) #ifndef QT_NO_CURSOR viewport->setCursor(Qt::IBeamCursor); #endif + panGesture = new QPanGesture(q); + QObject::connect(panGesture, SIGNAL(triggered()), q, SLOT(_q_gestureTriggered())); } void QTextEditPrivate::_q_repaintContents(const QRectF &contentsRect) @@ -2624,6 +2631,25 @@ void QTextEdit::ensureCursorVisible() d->control->ensureCursorVisible(); } +void QTextEditPrivate::_q_gestureTriggered() +{ + Q_Q(QTextEdit); + QPanGesture *g = qobject_cast<QPanGesture*>(q->sender()); + if (!g) + return; + QScrollBar *hBar = q->horizontalScrollBar(); + QScrollBar *vBar = q->verticalScrollBar(); + QPoint delta = g->pos() - (g->lastPos().isNull() ? g->pos() : g->lastPos()); + if (!delta.isNull()) { + if (QApplication::isRightToLeft()) + delta.rx() *= -1; + int newX = hBar->value() - delta.x(); + int newY = vBar->value() - delta.y(); + hbar->setValue(newX); + vbar->setValue(newY); + } +} + /*! \enum QTextEdit::KeyboardAction diff --git a/src/gui/widgets/qtextedit.h b/src/gui/widgets/qtextedit.h index 617822a..9e10e07 100644 --- a/src/gui/widgets/qtextedit.h +++ b/src/gui/widgets/qtextedit.h @@ -414,6 +414,7 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_currentCharFormatChanged(const QTextCharFormat &)) Q_PRIVATE_SLOT(d_func(), void _q_adjustScrollbars()) Q_PRIVATE_SLOT(d_func(), void _q_ensureVisible(const QRectF &)) + Q_PRIVATE_SLOT(d_func(), void _q_gestureTriggered()) friend class QTextEditControl; friend class QTextDocument; friend class QTextControl; diff --git a/src/gui/widgets/qtextedit_p.h b/src/gui/widgets/qtextedit_p.h index 75e7a35..cf87a86 100644 --- a/src/gui/widgets/qtextedit_p.h +++ b/src/gui/widgets/qtextedit_p.h @@ -70,7 +70,7 @@ QT_BEGIN_NAMESPACE #ifndef QT_NO_TEXTEDIT class QMimeData; - +class QPanGesture; class QTextEditPrivate : public QAbstractScrollAreaPrivate { Q_DECLARE_PUBLIC(QTextEdit) @@ -130,6 +130,9 @@ public: QString anchorToScrollToWhenVisible; + void _q_gestureTriggered(); + QPanGesture *panGesture; + #ifdef QT_KEYPAD_NAVIGATION QBasicTimer deleteAllTimer; #endif diff --git a/src/gui/widgets/qtoolbar.cpp b/src/gui/widgets/qtoolbar.cpp index b635628..426c3e1 100644 --- a/src/gui/widgets/qtoolbar.cpp +++ b/src/gui/widgets/qtoolbar.cpp @@ -70,6 +70,8 @@ #include "qdebug.h" +#define POPUP_TIMER_INTERVAL 500 + QT_BEGIN_NAMESPACE #ifdef Q_WS_MAC @@ -87,14 +89,6 @@ static void qt_mac_updateToolBarButtonHint(QWidget *parentWidget) void QToolBarPrivate::init() { Q_Q(QToolBar); - - waitForPopupTimer = new QTimer(q); - waitForPopupTimer->setSingleShot(false); - waitForPopupTimer->setInterval(500); - QObject::connect(waitForPopupTimer, SIGNAL(timeout()), q, SLOT(_q_waitForPopup())); - - floatable = true; - movable = true; q->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed)); q->setBackgroundRole(QPalette::Button); q->setAttribute(Qt::WA_Hover); @@ -880,7 +874,7 @@ QAction *QToolBar::insertSeparator(QAction *before) If you add a QToolButton with this method, the tools bar's Qt::ToolButtonStyle will not be respected. - Note: You should use QAction::setVisible() to change the + \note You should use QAction::setVisible() to change the visibility of the widget. Using QWidget::setVisible(), QWidget::show() and QWidget::hide() does not work. @@ -1080,19 +1074,46 @@ static bool waitForPopup(QToolBar *tb, QWidget *popup) return false; } +#if defined(Q_WS_MAC) +static bool toolbarInUnifiedToolBar(QToolBar *toolbar) +{ + const QMainWindow *mainWindow = qobject_cast<const QMainWindow *>(toolbar->parentWidget()); + return mainWindow && mainWindow->unifiedTitleAndToolBarOnMac() + && mainWindow->toolBarArea(toolbar) == Qt::TopToolBarArea; +} +#endif + /*! \reimp */ bool QToolBar::event(QEvent *event) { Q_D(QToolBar); switch (event->type()) { + case QEvent::Timer: + if (d->waitForPopupTimer.timerId() == static_cast<QTimerEvent*>(event)->timerId()) { + QWidget *w = QApplication::activePopupWidget(); + if (!waitForPopup(this, w)) { + d->waitForPopupTimer.stop(); + if (!this->underMouse()) + d->layout->setExpanded(false); + } + } + break; case QEvent::Hide: if (!isHidden()) break; // fallthrough intended case QEvent::Show: d->toggleViewAction->setChecked(event->type() == QEvent::Show); -#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA) +#if defined(Q_WS_MAC) + if (toolbarInUnifiedToolBar(this)) { + // I can static_cast because I did the qobject_cast in the if above, therefore + // we must have a QMainWindowLayout here. + QMainWindowLayout *mwLayout = static_cast<QMainWindowLayout *>(parentWidget()->layout()); + mwLayout->fixSizeInUnifiedToolbar(this); + mwLayout->syncUnifiedToolbarVisibility(); + } +# if !defined(QT_MAC_USE_COCOA) // Fall through case QEvent::LayoutRequest: { // There's currently no way to invalidate the size and let @@ -1107,10 +1128,9 @@ bool QToolBar::event(QEvent *event) } if (needUpdate) { - OSWindowRef windowRef = qt_mac_window_for(this); - if (mainWindow->unifiedTitleAndToolBarOnMac() - && mainWindow->toolBarArea(this) == Qt::TopToolBarArea - && macWindowToolbarVisible(windowRef)) { + OSWindowRef windowRef = qt_mac_window_for(mainWindow); + if (toolbarInUnifiedToolBar(this) + && macWindowToolbarIsVisible(windowRef)) { DisableScreenUpdates(); macWindowToolbarShow(this, false); macWindowToolbarShow(this, true); @@ -1122,7 +1142,8 @@ bool QToolBar::event(QEvent *event) return earlyResult; } } -#endif +# endif // !QT_MAC_USE_COCOA +#endif // Q_WS_MAC break; case QEvent::ParentChange: d->layout->checkUsePopupMenu(); @@ -1141,6 +1162,10 @@ bool QToolBar::event(QEvent *event) if (d->mouseReleaseEvent(static_cast<QMouseEvent*>(event))) return true; break; + case QEvent::HoverEnter: + case QEvent::HoverLeave: + // there's nothing special to do here and we don't want to update the whole widget + return true; case QEvent::HoverMove: { #ifndef QT_NO_CURSOR QHoverEvent *e = static_cast<QHoverEvent*>(event); @@ -1183,11 +1208,11 @@ bool QToolBar::event(QEvent *event) QWidget *w = QApplication::activePopupWidget(); if (waitForPopup(this, w)) { - d->waitForPopupTimer->start(); + d->waitForPopupTimer.start(POPUP_TIMER_INTERVAL, this); break; } - d->waitForPopupTimer->stop(); + d->waitForPopupTimer.stop(); d->layout->setExpanded(false); break; } @@ -1197,18 +1222,6 @@ bool QToolBar::event(QEvent *event) return QWidget::event(event); } -void QToolBarPrivate::_q_waitForPopup() -{ - Q_Q(QToolBar); - - QWidget *w = QApplication::activePopupWidget(); - if (!waitForPopup(q, w)) { - waitForPopupTimer->stop(); - if (!q->underMouse()) - layout->setExpanded(false); - } -} - /*! Returns a checkable action that can be used to show or hide this toolbar. diff --git a/src/gui/widgets/qtoolbar.h b/src/gui/widgets/qtoolbar.h index 2ab4ffd..07502b3 100644 --- a/src/gui/widgets/qtoolbar.h +++ b/src/gui/widgets/qtoolbar.h @@ -167,7 +167,6 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_toggleView(bool)) Q_PRIVATE_SLOT(d_func(), void _q_updateIconSize(const QSize &)) Q_PRIVATE_SLOT(d_func(), void _q_updateToolButtonStyle(Qt::ToolButtonStyle)) - Q_PRIVATE_SLOT(d_func(), void _q_waitForPopup()) friend class QMainWindow; friend class QMainWindowLayout; diff --git a/src/gui/widgets/qtoolbar_p.h b/src/gui/widgets/qtoolbar_p.h index b03c460..42ea97f 100644 --- a/src/gui/widgets/qtoolbar_p.h +++ b/src/gui/widgets/qtoolbar_p.h @@ -56,6 +56,7 @@ #include "qtoolbar.h" #include "QtGui/qaction.h" #include "private/qwidget_p.h" +#include <QtCore/qbasictimer.h> QT_BEGIN_NAMESPACE @@ -70,7 +71,7 @@ class QToolBarPrivate : public QWidgetPrivate public: inline QToolBarPrivate() - : explicitIconSize(false), explicitToolButtonStyle(false), movable(false), + : explicitIconSize(false), explicitToolButtonStyle(false), movable(true), floatable(true), allowedAreas(Qt::AllToolBarAreas), orientation(Qt::Horizontal), toolButtonStyle(Qt::ToolButtonIconOnly), layout(0), state(0) @@ -84,16 +85,15 @@ public: void _q_toggleView(bool b); void _q_updateIconSize(const QSize &sz); void _q_updateToolButtonStyle(Qt::ToolButtonStyle style); - void _q_waitForPopup(); bool explicitIconSize; bool explicitToolButtonStyle; bool movable; + bool floatable; Qt::ToolBarAreas allowedAreas; Qt::Orientation orientation; Qt::ToolButtonStyle toolButtonStyle; QSize iconSize; - bool floatable; QAction *toggleViewAction; @@ -125,7 +125,7 @@ public: void unplug(const QRect &r); void plug(const QRect &r); - QTimer *waitForPopupTimer; + QBasicTimer waitForPopupTimer; }; #endif // QT_NO_TOOLBAR diff --git a/src/gui/widgets/qtoolbararealayout.cpp b/src/gui/widgets/qtoolbararealayout.cpp index db2afd6..b4a0ef0 100644 --- a/src/gui/widgets/qtoolbararealayout.cpp +++ b/src/gui/widgets/qtoolbararealayout.cpp @@ -156,21 +156,15 @@ void QToolBarAreaLayoutLine::fitLayout() if (item.skip()) continue; - QToolBarLayout *tblayout = qobject_cast<QToolBarLayout*>(item.widgetItem->widget()->layout()); - if (tblayout) + if (QToolBarLayout *tblayout = qobject_cast<QToolBarLayout*>(item.widgetItem->widget()->layout())) tblayout->checkUsePopupMenu(); - int itemMin = pick(o, item.minimumSize()); - int itemHint = pick(o, item.sizeHint()); - //we ensure the extraspace is not too low - item.size = qMax(item.size, itemHint); - if (item.preferredSize > 0) { - //preferredSize would be the default size - item.size = item.preferredSize; - } + const int itemMin = pick(o, item.minimumSize()); + //preferredSize is the default if it is set, otherwise, we take the sizehint + item.size = item.preferredSize > 0 ? item.preferredSize : pick(o, item.sizeHint()); //the extraspace is the space above the item minimum sizehint - int extraSpace = qMin(item.size - itemMin, extra); + const int extraSpace = qMin(item.size - itemMin, extra); item.size = itemMin + extraSpace; //that is the real size extra -= extraSpace; @@ -932,7 +926,7 @@ void QToolBarAreaLayout::apply(bool animate) if (visible && dock.o == Qt::Horizontal) geo = QStyle::visualRect(dir, line.rect, geo); - layout->widgetAnimator->animate(widget, geo, animate); + layout->widgetAnimator.animate(widget, geo, animate); } } } diff --git a/src/gui/widgets/qtoolbutton.cpp b/src/gui/widgets/qtoolbutton.cpp index 6dcbfec..2c85dc5 100644 --- a/src/gui/widgets/qtoolbutton.cpp +++ b/src/gui/widgets/qtoolbutton.cpp @@ -378,7 +378,17 @@ void QToolButton::initStyleOption(QStyleOptionToolButton *option) const if (d->hasMenu()) option->features |= QStyleOptionToolButton::HasMenu; #endif - option->toolButtonStyle = d->toolButtonStyle; + if (d->toolButtonStyle == Qt::ToolButtonFollowStyle) { + option->toolButtonStyle = Qt::ToolButtonStyle(style()->styleHint(QStyle::SH_ToolButtonStyle, option, this)); + } else + option->toolButtonStyle = d->toolButtonStyle; + + if (option->toolButtonStyle == Qt::ToolButtonTextBesideIcon) { + // If the action is not prioritized, remove the text label to save space + if (d->defaultAction && d->defaultAction->priority() < QAction::NormalPriority) + option->toolButtonStyle = Qt::ToolButtonIconOnly; + } + if (d->icon.isNull() && d->arrowType == Qt::NoArrow && !forceNoText) { if (!d->text.isEmpty()) option->toolButtonStyle = Qt::ToolButtonTextOnly; @@ -476,6 +486,9 @@ QSize QToolButton::minimumSizeHint() const The default is Qt::ToolButtonIconOnly. + To have the style of toolbuttons follow the system settings (as available + in GNOME and KDE desktop environments), set this property to Qt::ToolButtonFollowStyle. + QToolButton automatically connects this slot to the relevant signal in the QMainWindow in which is resides. */ diff --git a/src/gui/widgets/qwidgetanimator.cpp b/src/gui/widgets/qwidgetanimator.cpp index c67be4a..1a93b51 100644 --- a/src/gui/widgets/qwidgetanimator.cpp +++ b/src/gui/widgets/qwidgetanimator.cpp @@ -39,158 +39,80 @@ ** ****************************************************************************/ -#include <QtCore/qtimer.h> -#include <QtCore/qdatetime.h> +#include <QtCore/qpropertyanimation.h> #include <QtGui/qwidget.h> -#include <QtGui/qtextedit.h> -#include <QtGui/private/qwidget_p.h> -#include <qdebug.h> +#include <QtGui/private/qmainwindowlayout_p.h> #include "qwidgetanimator_p.h" QT_BEGIN_NAMESPACE -static const int g_animation_steps = 12; -static const int g_animation_interval = 16; - -// 1000 * (x/(1 + x*x) + 0.5) on interval [-1, 1] -static const int g_animate_function[] = -{ - 0, 1, 5, 12, 23, 38, 58, 84, 116, 155, 199, 251, 307, 368, - 433, 500, 566, 631, 692, 748, 799, 844, 883, 915, 941, 961, - 976, 987, 994, 998, 1000 -}; -static const int g_animate_function_points = sizeof(g_animate_function)/sizeof(int); - -static inline int animateHelper(int start, int stop, int step, int steps) -{ - if (start == stop) - return start; - if (step == 0) - return start; - if (step == steps) - return stop; - - int x = g_animate_function_points*step/(steps + 1); - return start + g_animate_function[x]*(stop - start)/1000; -} - -QWidgetAnimator::QWidgetAnimator(QObject *parent) - : QObject(parent) +QWidgetAnimator::QWidgetAnimator(QMainWindowLayout *layout) : m_mainWindowLayout(layout) { - m_time = new QTime(); - m_timer = new QTimer(this); - m_timer->setInterval(g_animation_interval); - connect(m_timer, SIGNAL(timeout()), this, SLOT(animationStep())); } -QWidgetAnimator::~QWidgetAnimator() +void QWidgetAnimator::abort(QWidget *w) { - delete m_time; +#ifndef QT_NO_ANIMATION + AnimationMap::iterator it = m_animation_map.find(w); + if (it == m_animation_map.end()) + return; + QPropertyAnimation *anim = *it; + m_animation_map.erase(it); + anim->stop(); + m_mainWindowLayout->animationFinished(w); +#else + Q_UNUSED(w); //there is no animation to abort +#endif //QT_NO_ANIMATION } -void QWidgetAnimator::abort(QWidget *w) +#ifndef QT_NO_ANIMATION +void QWidgetAnimator::animationFinished() { - if (m_animation_map.remove(w) == 0) - return; - if (m_animation_map.isEmpty()) { - m_timer->stop(); - emit finishedAll(); - } + QPropertyAnimation *anim = qobject_cast<QPropertyAnimation*>(sender()); + abort(static_cast<QWidget*>(anim->targetObject())); } +#endif //QT_NO_ANIMATION void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, bool animate) { - QRect final_geometry = _final_geometry; - QRect r = widget->geometry(); if (r.right() < 0 || r.bottom() < 0) r = QRect(); - if (r.isNull() || final_geometry.isNull()) - animate = false; + animate = animate && !r.isNull() && !_final_geometry.isNull(); - AnimationMap::const_iterator it = m_animation_map.constFind(widget); - if (it == m_animation_map.constEnd()) { - if (r == final_geometry) { - emit finished(widget); - return; - } - } else { - if ((*it).r2 == final_geometry) - return; - } - - if (animate) { - AnimationItem item(widget, r, final_geometry); - m_animation_map[widget] = item; - if (!m_timer->isActive()) { - m_timer->start(); - m_time->start(); - } - } else { - m_animation_map.remove(widget); - if (m_animation_map.isEmpty()) - m_timer->stop(); - - if (!final_geometry.isValid() && !widget->isWindow()) { - // Make the wigdet go away by sending it to negative space - QSize s = widget->size(); - final_geometry = QRect(-500 - s.width(), -500 - s.height(), s.width(), s.height()); - } - widget->setGeometry(final_geometry); - - emit finished(widget); - - if (m_animation_map.isEmpty()) - emit finishedAll(); + // might make the wigdet go away by sending it to negative space + const QRect final_geometry = _final_geometry.isValid() || widget->isWindow() ? _final_geometry : + QRect(QPoint(-500 - widget->width(), -500 - widget->height()), widget->size()); + if (r == final_geometry) + return; //the widget is already where it should be +#ifndef QT_NO_ANIMATION + AnimationMap::const_iterator it = m_animation_map.constFind(widget); + if (it != m_animation_map.constEnd() && (*it)->endValue().toRect() == final_geometry) return; - } -} - -void QWidgetAnimator::animationStep() -{ - int steps = (1 + m_time->restart())/g_animation_interval; - AnimationMap::iterator it = m_animation_map.begin(); - while (it != m_animation_map.end()) { - AnimationItem &item = *it; - - item.step = qMin(item.step + steps, g_animation_steps); - - int x = animateHelper(item.r1.left(), item.r2.left(), - item.step, g_animation_steps); - int y = animateHelper(item.r1.top(), item.r2.top(), - item.step, g_animation_steps); - int w = animateHelper(item.r1.width(), item.r2.width(), - item.step, g_animation_steps); - int h = animateHelper(item.r1.height(), item.r2.height(), - item.step, g_animation_steps); - - item.widget->setGeometry(x, y, w, h); - - if (item.step == g_animation_steps) { - emit finished(item.widget); - AnimationMap::iterator tmp = it; - ++it; - m_animation_map.erase(tmp); - } else { - ++it; - } - } - if (m_animation_map.isEmpty()) { - m_timer->stop(); - emit finishedAll(); - } + QPropertyAnimation *anim = new QPropertyAnimation(widget, "geometry"); + anim->setDuration(animate ? 200 : 0); + anim->setEasingCurve(QEasingCurve::InOutQuad); + anim->setEndValue(final_geometry); + m_animation_map[widget] = anim; + connect(anim, SIGNAL(finished()), SLOT(animationFinished())); + anim->start(QPropertyAnimation::DeleteWhenStopped); +#else + //we do it in one shot + widget->setGeometry(final_geometry); + m_mainWindowLayout->animationFinished(widget); +#endif //QT_NO_ANIMATION } bool QWidgetAnimator::animating() const { - return m_timer->isActive(); + return !m_animation_map.isEmpty(); } -bool QWidgetAnimator::animating(QWidget *widget) +bool QWidgetAnimator::animating(QWidget *widget) const { return m_animation_map.contains(widget); } diff --git a/src/gui/widgets/qwidgetanimator_p.h b/src/gui/widgets/qwidgetanimator_p.h index 6ee150b..5a3e39d 100644 --- a/src/gui/widgets/qwidgetanimator_p.h +++ b/src/gui/widgets/qwidgetanimator_p.h @@ -54,47 +54,35 @@ // #include <qobject.h> -#include <qrect.h> #include <qmap.h> QT_BEGIN_NAMESPACE class QWidget; -class QTimer; -class QTime; +class QMainWindowLayout; +class QPropertyAnimation; +class QRect; class QWidgetAnimator : public QObject { Q_OBJECT public: - QWidgetAnimator(QObject *parent = 0); - ~QWidgetAnimator(); + QWidgetAnimator(QMainWindowLayout *layout); void animate(QWidget *widget, const QRect &final_geometry, bool animate); bool animating() const; - bool animating(QWidget *widget); + bool animating(QWidget *widget) const; void abort(QWidget *widget); -signals: - void finished(QWidget *widget); - void finishedAll(); - -private slots: - void animationStep(); +#ifndef QT_NO_ANIMATION +private Q_SLOTS: + void animationFinished(); +#endif private: - struct AnimationItem { - AnimationItem(QWidget *_widget = 0, const QRect &_r1 = QRect(), - const QRect &_r2 = QRect()) - : widget(_widget), r1(_r1), r2(_r2), step(0) {} - QWidget *widget; - QRect r1, r2; - int step; - }; - typedef QMap<QWidget*, AnimationItem> AnimationMap; + typedef QMap<QWidget*, QPropertyAnimation*> AnimationMap; AnimationMap m_animation_map; - QTimer *m_timer; - QTime *m_time; + QMainWindowLayout *m_mainWindowLayout; }; QT_END_NAMESPACE diff --git a/src/gui/widgets/qworkspace.cpp b/src/gui/widgets/qworkspace.cpp index 58ef1e3..2833c08 100644 --- a/src/gui/widgets/qworkspace.cpp +++ b/src/gui/widgets/qworkspace.cpp @@ -397,21 +397,17 @@ void QWorkspaceTitleBarPrivate::readColors() pal.setColor(QPalette::Inactive, QPalette::Highlight, colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTION))); pal.setColor(QPalette::Active, QPalette::HighlightedText, colorref2qrgb(GetSysColor(COLOR_CAPTIONTEXT))); pal.setColor(QPalette::Inactive, QPalette::HighlightedText, colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTIONTEXT))); - if (QSysInfo::WindowsVersion != QSysInfo::WV_95 && QSysInfo::WindowsVersion != QSysInfo::WV_NT) { - colorsInitialized = true; - BOOL gradient; - QT_WA({ - SystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, &gradient, 0); - } , { - SystemParametersInfoA(SPI_GETGRADIENTCAPTIONS, 0, &gradient, 0); - }); - if (gradient) { - pal.setColor(QPalette::Active, QPalette::Base, colorref2qrgb(GetSysColor(COLOR_GRADIENTACTIVECAPTION))); - pal.setColor(QPalette::Inactive, QPalette::Base, colorref2qrgb(GetSysColor(COLOR_GRADIENTINACTIVECAPTION))); - } else { - pal.setColor(QPalette::Active, QPalette::Base, pal.color(QPalette::Active, QPalette::Highlight)); - pal.setColor(QPalette::Inactive, QPalette::Base, pal.color(QPalette::Inactive, QPalette::Highlight)); - } + + colorsInitialized = true; + BOOL gradient = false; + SystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, &gradient, 0); + + if (gradient) { + pal.setColor(QPalette::Active, QPalette::Base, colorref2qrgb(GetSysColor(COLOR_GRADIENTACTIVECAPTION))); + pal.setColor(QPalette::Inactive, QPalette::Base, colorref2qrgb(GetSysColor(COLOR_GRADIENTINACTIVECAPTION))); + } else { + pal.setColor(QPalette::Active, QPalette::Base, pal.color(QPalette::Active, QPalette::Highlight)); + pal.setColor(QPalette::Inactive, QPalette::Base, pal.color(QPalette::Inactive, QPalette::Highlight)); } } #endif // Q_WS_WIN |