diff options
author | Michael Brasser <michael.brasser@nokia.com> | 2009-07-10 01:17:51 (GMT) |
---|---|---|
committer | Michael Brasser <michael.brasser@nokia.com> | 2009-07-10 01:17:51 (GMT) |
commit | 9c13caa3c99af01a9b4c3ff6e178e7dadb61741f (patch) | |
tree | b69df0a23c4628359fc3740e09958980eda7478e /src/gui/widgets | |
parent | bb1bdcab28e4c52dcea37dfaaa435045b1985eeb (diff) | |
parent | 883da42f7c75775502c818aa456c8576d8457ff8 (diff) | |
download | Qt-9c13caa3c99af01a9b4c3ff6e178e7dadb61741f.zip Qt-9c13caa3c99af01a9b4c3ff6e178e7dadb61741f.tar.gz Qt-9c13caa3c99af01a9b4c3ff6e178e7dadb61741f.tar.bz2 |
Merge branch 'kinetic-declarativeui' of git@scm.dev.nokia.troll.no:qt/kinetic into kinetic-declarativeui-gv
Conflicts:
examples/itemviews/frozencolumn/main.cpp
src/declarative/canvas/qsimplecanvas.cpp
src/declarative/canvas/qsimplecanvas_p.h
src/declarative/canvas/qsimplecanvasitem.h
src/declarative/extra/qfxparticles.cpp
src/declarative/fx/fx.pri
src/declarative/fx/qfxblurfilter.h
src/declarative/fx/qfxcontentwrapper.cpp
src/declarative/fx/qfxflickable.cpp
src/declarative/fx/qfxfocuspanel.h
src/declarative/fx/qfxfocusrealm.h
src/declarative/fx/qfxhighlightfilter.cpp
src/declarative/fx/qfxhighlightfilter.h
src/declarative/fx/qfximage.cpp
src/declarative/fx/qfxitem.cpp
src/declarative/fx/qfxitem.h
src/declarative/fx/qfxrect.cpp
src/declarative/fx/qfxreflectionfilter.h
src/declarative/fx/qfxshadowfilter.cpp
src/declarative/fx/qfxshadowfilter.h
src/declarative/fx/qfxtext.cpp
src/declarative/fx/qfxtext.h
src/declarative/fx/qfxtextedit.cpp
src/declarative/opengl/glbasicshaders.h
src/declarative/test/qfxtestengine.cpp
src/declarative/test/qfxtestengine.h
src/declarative/test/qfxtestobjects.cpp
src/declarative/test/qfxtestobjects.h
src/declarative/test/qfxtestview.h
src/declarative/util/qfxglobal.h
src/declarative/util/qfxview.cpp
src/gui/graphicsview/qgraphicsitem_p.h
tools/qmlviewer/qmlviewer.cpp
Diffstat (limited to 'src/gui/widgets')
38 files changed, 778 insertions, 869 deletions
diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/gui/widgets/qabstractscrollarea.cpp index 00be29b..e1beb98 100644 --- a/src/gui/widgets/qabstractscrollarea.cpp +++ b/src/gui/widgets/qabstractscrollarea.cpp @@ -909,6 +909,7 @@ bool QAbstractScrollArea::event(QEvent *e) case QEvent::DragMove: case QEvent::DragLeave: #endif + case QEvent::Gesture: return false; case QEvent::StyleChange: case QEvent::LayoutDirectionChange: diff --git a/src/gui/widgets/qabstractspinbox.cpp b/src/gui/widgets/qabstractspinbox.cpp index e7f7c78..25acd6e 100644 --- a/src/gui/widgets/qabstractspinbox.cpp +++ b/src/gui/widgets/qabstractspinbox.cpp @@ -1696,6 +1696,8 @@ void QAbstractSpinBoxPrivate::updateEdit() void QAbstractSpinBoxPrivate::setRange(const QVariant &min, const QVariant &max) { + Q_Q(QAbstractSpinBox); + clearCache(); minimum = min; maximum = (variantCompare(min, max) < 0 ? max : min); @@ -1707,6 +1709,8 @@ void QAbstractSpinBoxPrivate::setRange(const QVariant &min, const QVariant &max) } else if (value == minimum && !specialValueText.isEmpty()) { updateEdit(); } + + q->updateGeometry(); } /*! diff --git a/src/gui/widgets/qabstractspinbox_p.h b/src/gui/widgets/qabstractspinbox_p.h index 15f5d97..0d00e04 100644 --- a/src/gui/widgets/qabstractspinbox_p.h +++ b/src/gui/widgets/qabstractspinbox_p.h @@ -135,8 +135,6 @@ public: mutable QValidator::State cachedState; mutable QSize cachedSizeHint, cachedMinimumSizeHint; uint pendingEmit : 1; - uint spindownEnabled : 1; - uint spinupEnabled : 1; uint readOnly : 1; uint wrapping : 1; uint ignoreCursorPositionChanged : 1; diff --git a/src/gui/widgets/qcheckbox.cpp b/src/gui/widgets/qcheckbox.cpp index 0fbc323..3108c7c 100644 --- a/src/gui/widgets/qcheckbox.cpp +++ b/src/gui/widgets/qcheckbox.cpp @@ -75,52 +75,60 @@ public: \ingroup basicwidgets \mainclass - A QCheckBox is an option button that can be switched on (checked) - or off (unchecked). Checkboxes are typically used to represent - features in an application that can be enabled or disabled without - affecting others, but different types of behavior can be - implemented. - - A QButtonGroup can be used to group check buttons visually. + A QCheckBox is an option button that can be switched on (checked) or off + (unchecked). Checkboxes are typically used to represent features in an + application that can be enabled or disabled without affecting others, but + different types of behavior can be implemented. For example, a + QButtonGroup can be used to group check buttons logically, allowing + exclusive checkboxes. However, QButtonGroup does not provide any visual + representation. + + The image below further illustrates the differences between exclusive and + non-exclusive checkboxes. + + \table + \row \o \inlineimage checkboxes-exclusive.png + \o \inlineimage checkboxes-non-exclusive.png + \endtable Whenever a checkbox is checked or cleared it emits the signal - stateChanged(). Connect to this signal if you want to trigger an - action each time the checkbox changes state. You can use - isChecked() to query whether or not a checkbox is checked. - - In addition to the usual checked and unchecked states, QCheckBox - optionally provides a third state to indicate "no change". This - is useful whenever you need to give the user the option of neither - checking nor unchecking a checkbox. If you need this third state, - enable it with setTristate(), and use checkState() to query the current - toggle state. - - Just like QPushButton, a checkbox displays text, and optionally a - small icon. The icon is set with setIcon(). The text can be set in - the constructor or with setText(). A shortcut key can be specified - by preceding the preferred character with an ampersand. For - example: + stateChanged(). Connect to this signal if you want to trigger an action + each time the checkbox changes state. You can use isChecked() to query + whether or not a checkbox is checked. + + In addition to the usual checked and unchecked states, QCheckBox optionally + provides a third state to indicate "no change". This is useful whenever you + need to give the user the option of neither checking nor unchecking a + checkbox. If you need this third state, enable it with setTristate(), and + use checkState() to query the current toggle state. + + Just like QPushButton, a checkbox displays text, and optionally a small + icon. The icon is set with setIcon(). The text can be set in the + constructor or with setText(). A shortcut key can be specified by preceding + the preferred character with an ampersand. For example: \snippet doc/src/snippets/code/src_gui_widgets_qcheckbox.cpp 0 - In this example the shortcut is \e{Alt+A}. See the \l - {QShortcut#mnemonic}{QShortcut} documentation for details (to - display an actual ampersand, use '&&'). + In this example the shortcut is \e{Alt+A}. See the \l{QShortcut#mnemonic} + {QShortcut} documentation for details (to display an actual ampersand, + use '&&'). - Important inherited functions: text(), setText(), text(), - pixmap(), setPixmap(), accel(), setAccel(), isToggleButton(), - setDown(), isDown(), isOn(), checkState(), autoRepeat(), - isExclusiveToggle(), group(), setAutoRepeat(), toggle(), - pressed(), released(), clicked(), toggled(), checkState(), and - stateChanged(). + Important inherited functions: text(), setText(), text(), pixmap(), + setPixmap(), accel(), setAccel(), isToggleButton(), setDown(), isDown(), + isOn(), checkState(), autoRepeat(), isExclusiveToggle(), group(), + setAutoRepeat(), toggle(), pressed(), released(), clicked(), toggled(), + checkState(), and stateChanged(). \table 100% - \row \o \inlineimage macintosh-checkbox.png Screenshot of a Macintosh style checkbox - \o A checkbox shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}. - \row \o \inlineimage windows-checkbox.png Screenshot of a Windows XP style checkbox - \o A checkbox shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}. - \row \o \inlineimage plastique-checkbox.png Screenshot of a Plastique style checkbox - \o A checkbox shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}. + \row + \o \inlineimage macintosh-checkbox.png Screenshot of a Macintosh style checkbox + \o A checkbox shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}. + \row + \o \inlineimage windows-checkbox.png Screenshot of a Windows XP style checkbox + \o A checkbox shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}. + \row + \o \inlineimage plastique-checkbox.png Screenshot of a Plastique style checkbox + \o A checkbox shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}. \endtable \sa QAbstractButton, QRadioButton, {fowler}{GUI Design Handbook: Check Box} @@ -138,8 +146,8 @@ public: /*! \fn void QCheckBox::stateChanged(int state) - This signal is emitted whenever the check box's state changes, - i.e. whenever the user checks or unchecks it. + This signal is emitted whenever the check box's state changes, i.e. + whenever the user checks or unchecks it. \a state contains the check box's new Qt::CheckState. */ @@ -161,9 +169,9 @@ void QCheckBoxPrivate::init() } /*! - Initialize \a option with the values from this QCheckBox. This method is useful - for subclasses when they need a QStyleOptionButton, but don't want to fill - in all the information themselves. + Initializes \a option with the values from this QCheckBox. This method is + useful for subclasses that require a QStyleOptionButton, but do not want + to fill in all the information themselves. \sa QStyleOption::initFrom() */ @@ -193,7 +201,7 @@ void QCheckBox::initStyleOption(QStyleOptionButton *option) const /*! Constructs a checkbox with the given \a parent, but with no text. - The \a parent argument is passed on to the QAbstractButton constructor. + \a parent is passed on to the QAbstractButton constructor. */ QCheckBox::QCheckBox(QWidget *parent) @@ -206,7 +214,7 @@ QCheckBox::QCheckBox(QWidget *parent) /*! Constructs a checkbox with the given \a parent and \a text. - The \a parent argument is passed on to the QAbstractButton constructor. + \a parent is passed on to the QAbstractButton constructor. */ QCheckBox::QCheckBox(const QString &text, QWidget *parent) @@ -231,10 +239,8 @@ bool QCheckBox::isTristate() const /*! - Returns the check box's check state. - If you do not need tristate support, you can also - use \l QAbstractButton::isChecked() which returns - a boolean. + Returns the check box's check state. If you do not need tristate support, + you can also use \l QAbstractButton::isChecked() which returns a boolean. \sa setCheckState() Qt::CheckState */ @@ -247,10 +253,9 @@ Qt::CheckState QCheckBox::checkState() const } /*! - Sets the check box's check state to \a state. - If you do not need tristate support, you can also - use \l QAbstractButton::setChecked() which takes - a boolean. + Sets the check box's check state to \a state. If you do not need tristate + support, you can also use \l QAbstractButton::setChecked() which takes a + boolean. \sa checkState() Qt::CheckState */ @@ -274,7 +279,8 @@ void QCheckBox::setCheckState(Qt::CheckState state) } -/*!\reimp +/*! + \reimp */ QSize QCheckBox::sizeHint() const { @@ -294,7 +300,8 @@ QSize QCheckBox::sizeHint() const return d->sizeHint; } -/*!\reimp +/*! + \reimp */ void QCheckBox::paintEvent(QPaintEvent *) { @@ -325,7 +332,9 @@ void QCheckBox::mouseMoveEvent(QMouseEvent *e) } -/*!\reimp*/ +/*! + \reimp +*/ bool QCheckBox::hitButton(const QPoint &pos) const { QStyleOptionButton opt; @@ -333,7 +342,9 @@ bool QCheckBox::hitButton(const QPoint &pos) const return style()->subElementRect(QStyle::SE_CheckBoxClickRect, &opt, this).contains(pos); } -/*!\reimp*/ +/*! + \reimp +*/ void QCheckBox::checkStateSet() { Q_D(QCheckBox); @@ -345,7 +356,9 @@ void QCheckBox::checkStateSet() } } -/*!\reimp*/ +/*! + \reimp +*/ void QCheckBox::nextCheckState() { Q_D(QCheckBox); diff --git a/src/gui/widgets/qcocoamenu_mac_p.h b/src/gui/widgets/qcocoamenu_mac_p.h index cd53692..8eb6fba 100644 --- a/src/gui/widgets/qcocoamenu_mac_p.h +++ b/src/gui/widgets/qcocoamenu_mac_p.h @@ -56,16 +56,23 @@ QT_FORWARD_DECLARE_CLASS(QMenu) -@interface QT_MANGLE_NAMESPACE(QCocoaMenu) : NSMenu -{ - QMenu *qmenu; -} -- (id)initWithQMenu:(QMenu*)menu; +#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5 + +@protocol NSMenuDelegate <NSObject> - (void)menu:(NSMenu*)menu willHighlightItem:(NSMenuItem*)item; - (void)menuWillOpen:(NSMenu*)menu; - (void)menuWillClose:(NSMenu*)menu; - (BOOL)hasShortcut:(NSMenu *)menu forKey:(NSString *)key forModifiers:(NSUInteger)modifier whichItem:(NSMenuItem**)outItem; +@end + +#endif + +@interface QT_MANGLE_NAMESPACE(QCocoaMenu) : NSMenu <NSMenuDelegate> +{ + QMenu *qmenu; +} +- (id)initWithQMenu:(QMenu*)menu; - (BOOL)menuHasKeyEquivalent:(NSMenu *)menu forEvent:(NSEvent *)event target:(id *)target action:(SEL *)action; @end #endif diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp index ad6f3db..1ca878d 100644 --- a/src/gui/widgets/qcombobox.cpp +++ b/src/gui/widgets/qcombobox.cpp @@ -59,6 +59,7 @@ #ifndef QT_NO_IM #include "qinputcontext.h" #endif +#include <private/qapplication_p.h> #include <private/qcombobox_p.h> #include <private/qabstractitemmodel_p.h> #include <private/qabstractscrollarea_p.h> @@ -77,8 +78,6 @@ #endif QT_BEGIN_NAMESPACE -extern QHash<QByteArray, QFont> *qt_app_fonts_hash(); - QComboBoxPrivate::QComboBoxPrivate() : QWidgetPrivate(), model(0), diff --git a/src/gui/widgets/qdockarealayout.cpp b/src/gui/widgets/qdockarealayout.cpp index 3125304..b905ccd 100644 --- a/src/gui/widgets/qdockarealayout.cpp +++ b/src/gui/widgets/qdockarealayout.cpp @@ -223,7 +223,7 @@ static quintptr tabId(const QDockAreaLayoutItem &item) QDockAreaLayoutInfo::QDockAreaLayoutInfo() : sep(0), dockPos(QInternal::LeftDock), o(Qt::Horizontal), mainWindow(0) #ifndef QT_NO_TABBAR - , tabbed(false), tabBar(0), tabBarShape(QTabBar::RoundedSouth) + , tabbed(false), tabBar(0), tabBarShape(QTabBar::RoundedSouth), tabBarVisible(false) #endif { } @@ -233,7 +233,7 @@ QDockAreaLayoutInfo::QDockAreaLayoutInfo(int _sep, QInternal::DockPosition _dock QMainWindow *window) : sep(_sep), dockPos(_dockPos), o(_o), mainWindow(window) #ifndef QT_NO_TABBAR - , tabbed(false), tabBar(0), tabBarShape(static_cast<QTabBar::Shape>(tbshape)) + , tabbed(false), tabBar(0), tabBarShape(static_cast<QTabBar::Shape>(tbshape)), tabBarVisible(false) #endif { #ifdef QT_NO_TABBAR @@ -924,43 +924,41 @@ static int separatorMoveHelper(QVector<QLayoutStruct> &list, int index, int delt return delta; } -int QDockAreaLayoutInfo::separatorMove(int index, int delta, QVector<QLayoutStruct> *cache) +int QDockAreaLayoutInfo::separatorMove(int index, int delta) { #ifndef QT_NO_TABBAR Q_ASSERT(!tabbed); #endif - if (cache->isEmpty()) { - QVector<QLayoutStruct> &list = *cache; - list.resize(item_list.size()); - for (int i = 0; i < item_list.size(); ++i) { - const QDockAreaLayoutItem &item = item_list.at(i); - QLayoutStruct &ls = list[i]; - Q_ASSERT(!(item.flags & QDockAreaLayoutItem::GapItem)); - if (item.skip()) { - ls.empty = true; - } else { - ls.empty = false; - ls.pos = item.pos; - ls.size = item.size; - ls.minimumSize = pick(o, item.minimumSize()); - ls.maximumSize = pick(o, item.maximumSize()); - } + QVector<QLayoutStruct> list(item_list.size()); + for (int i = 0; i < list.size(); ++i) { + const QDockAreaLayoutItem &item = item_list.at(i); + QLayoutStruct &ls = list[i]; + Q_ASSERT(!(item.flags & QDockAreaLayoutItem::GapItem)); + if (item.skip()) { + ls.empty = true; + } else { + const int separatorSpace = item.hasFixedSize(o) ? 0 : sep; + ls.empty = false; + ls.pos = item.pos; + ls.size = item.size + separatorSpace; + ls.minimumSize = pick(o, item.minimumSize()) + separatorSpace; + ls.maximumSize = pick(o, item.maximumSize()) + separatorSpace; + } } - QVector<QLayoutStruct> list = *cache; + //the separator space has been added to the size, so we pass 0 as a parameter + delta = separatorMoveHelper(list, index, delta, 0 /*separator*/); - delta = separatorMoveHelper(list, index, delta, sep); - - for (int i = 0; i < item_list.size(); ++i) { + for (int i = 0; i < list.size(); ++i) { QDockAreaLayoutItem &item = item_list[i]; if (item.skip()) continue; QLayoutStruct &ls = list[i]; - item.size = ls.size; + const int separatorSpace = item.hasFixedSize(o) ? 0 : sep; + item.size = ls.size - separatorSpace; item.pos = ls.pos; - if (item.subinfo != 0) { item.subinfo->rect = itemRect(i); item.subinfo->fitItems(); @@ -996,15 +994,15 @@ void QDockAreaLayoutInfo::unnest(int index) } } -void QDockAreaLayoutInfo::remove(QList<int> path) +void QDockAreaLayoutInfo::remove(const QList<int> &path) { Q_ASSERT(!path.isEmpty()); if (path.count() > 1) { - int index = path.takeFirst(); + const int index = path.first(); QDockAreaLayoutItem &item = item_list[index]; Q_ASSERT(item.subinfo != 0); - item.subinfo->remove(path); + item.subinfo->remove(path.mid(1)); unnest(index); } else { int index = path.first(); @@ -1012,18 +1010,18 @@ void QDockAreaLayoutInfo::remove(QList<int> path) } } -QLayoutItem *QDockAreaLayoutInfo::plug(QList<int> path) +QLayoutItem *QDockAreaLayoutInfo::plug(const QList<int> &path) { Q_ASSERT(!path.isEmpty()); - int index = path.takeFirst(); + int index = path.first(); if (index < 0) index = -index - 1; - if (!path.isEmpty()) { + if (path.count() > 1) { const QDockAreaLayoutItem &item = item_list.at(index); Q_ASSERT(item.subinfo != 0); - return item.subinfo->plug(path); + return item.subinfo->plug(path.mid(1)); } QDockAreaLayoutItem &item = item_list[index]; @@ -1061,18 +1059,17 @@ QLayoutItem *QDockAreaLayoutInfo::plug(QList<int> path) return item.widgetItem; } -QLayoutItem *QDockAreaLayoutInfo::unplug(QList<int> path) +QLayoutItem *QDockAreaLayoutInfo::unplug(const QList<int> &path) { Q_ASSERT(!path.isEmpty()); + const int index = path.first(); if (path.count() > 1) { - int index = path.takeFirst(); const QDockAreaLayoutItem &item = item_list.at(index); Q_ASSERT(item.subinfo != 0); - return item.subinfo->unplug(path); + return item.subinfo->unplug(path.mid(1)); } - int index = path.first(); QDockAreaLayoutItem &item = item_list[index]; int prev = this->prev(index); int next = this->next(index); @@ -1144,12 +1141,12 @@ static QRect dockedGeometry(QWidget *widget) return result; } -bool QDockAreaLayoutInfo::insertGap(QList<int> path, QLayoutItem *dockWidgetItem) +bool QDockAreaLayoutInfo::insertGap(const QList<int> &path, QLayoutItem *dockWidgetItem) { Q_ASSERT(!path.isEmpty()); bool insert_tabbed = false; - int index = path.takeFirst(); + int index = path.first(); if (index < 0) { insert_tabbed = true; index = -index - 1; @@ -1157,7 +1154,7 @@ bool QDockAreaLayoutInfo::insertGap(QList<int> path, QLayoutItem *dockWidgetItem // dump(qDebug() << "insertGap() before:" << index << tabIndex, *this, QString()); - if (!path.isEmpty()) { + if (path.count() > 1) { QDockAreaLayoutItem &item = item_list[index]; if (item.subinfo == 0 @@ -1196,8 +1193,7 @@ bool QDockAreaLayoutInfo::insertGap(QList<int> path, QLayoutItem *dockWidgetItem #endif } - bool result = item.subinfo->insertGap(path, dockWidgetItem); - return result; + return item.subinfo->insertGap(path.mid(1), dockWidgetItem); } // create the gap item @@ -1297,16 +1293,16 @@ QDockAreaLayoutInfo *QDockAreaLayoutInfo::info(QWidget *widget) return 0; } -QDockAreaLayoutInfo *QDockAreaLayoutInfo::info(QList<int> path) +QDockAreaLayoutInfo *QDockAreaLayoutInfo::info(const QList<int> &path) { - int index = path.takeFirst(); + int index = path.first(); if (index < 0) index = -index - 1; if (index >= item_list.count()) return this; - if (path.isEmpty() || item_list.at(index).subinfo == 0) + if (path.count() == 1 || item_list.at(index).subinfo == 0) return this; - return item_list.at(index).subinfo->info(path); + return item_list.at(index).subinfo->info(path.mid(1)); } QRect QDockAreaLayoutInfo::itemRect(int index) const @@ -1337,17 +1333,18 @@ QRect QDockAreaLayoutInfo::itemRect(int index) const return result; } -QRect QDockAreaLayoutInfo::itemRect(QList<int> path) const +QRect QDockAreaLayoutInfo::itemRect(const QList<int> &path) const { Q_ASSERT(!path.isEmpty()); + const int index = path.first(); if (path.count() > 1) { - const QDockAreaLayoutItem &item = item_list.at(path.takeFirst()); + const QDockAreaLayoutItem &item = item_list.at(index); Q_ASSERT(item.subinfo != 0); - return item.subinfo->itemRect(path); + return item.subinfo->itemRect(path.mid(1)); } - return itemRect(path.first()); + return itemRect(index); } QRect QDockAreaLayoutInfo::separatorRect(int index) const @@ -1369,16 +1366,17 @@ QRect QDockAreaLayoutInfo::separatorRect(int index) const return QRect(pos, s); } -QRect QDockAreaLayoutInfo::separatorRect(QList<int> path) const +QRect QDockAreaLayoutInfo::separatorRect(const QList<int> &path) const { Q_ASSERT(!path.isEmpty()); + const int index = path.first(); if (path.count() > 1) { - const QDockAreaLayoutItem &item = item_list.at(path.takeFirst()); + const QDockAreaLayoutItem &item = item_list.at(index); Q_ASSERT(item.subinfo != 0); - return item.subinfo->separatorRect(path); + return item.subinfo->separatorRect(path.mid(1)); } - return separatorRect(path.first()); + return separatorRect(index); } QList<int> QDockAreaLayoutInfo::findSeparator(const QPoint &_pos) const @@ -1490,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) { @@ -1523,7 +1521,7 @@ void QDockAreaLayoutInfo::apply(bool animate) } } - widgetAnimator->animate(tabBar, tab_rect, animate); + widgetAnimator.animate(tabBar, tab_rect, animate); } #endif // QT_NO_TABBAR @@ -1546,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) { @@ -1704,15 +1702,16 @@ void QDockAreaLayoutInfo::split(int index, Qt::Orientation orientation, } } -QDockAreaLayoutItem &QDockAreaLayoutInfo::item(QList<int> path) +QDockAreaLayoutItem &QDockAreaLayoutInfo::item(const QList<int> &path) { Q_ASSERT(!path.isEmpty()); + const int index = path.first(); if (path.count() > 1) { - QDockAreaLayoutItem &item = item_list[path.takeFirst()]; + const QDockAreaLayoutItem &item = item_list.at(index); Q_ASSERT(item.subinfo != 0); - return item.subinfo->item(path); + return item.subinfo->item(path.mid(1)); } - return item_list[path.first()]; + return item_list[index]; } QLayoutItem *QDockAreaLayoutInfo::itemAt(int *x, int index) const @@ -1974,7 +1973,6 @@ bool QDockAreaLayoutInfo::restoreState(QDataStream &stream, QList<QDockWidget*> } else { int dummy; stream >> item.pos >> item.size >> dummy >> dummy; - // qDebug() << widget << item.pos << item.size; if (!testing) { widget->setFloating(false); widget->setVisible(flags & StateFlagVisible); @@ -2076,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); @@ -2477,37 +2475,37 @@ QDockAreaLayoutInfo *QDockAreaLayout::info(QWidget *widget) return 0; } -QDockAreaLayoutInfo *QDockAreaLayout::info(QList<int> path) +QDockAreaLayoutInfo *QDockAreaLayout::info(const QList<int> &path) { Q_ASSERT(!path.isEmpty()); - int index = path.takeFirst(); + const int index = path.first(); Q_ASSERT(index >= 0 && index < QInternal::DockCount); - if (path.isEmpty()) + if (path.count() == 1) return &docks[index]; - return docks[index].info(path); + return docks[index].info(path.mid(1)); } -const QDockAreaLayoutInfo *QDockAreaLayout::info(QList<int> path) const +const QDockAreaLayoutInfo *QDockAreaLayout::info(const QList<int> &path) const { return const_cast<QDockAreaLayout*>(this)->info(path); } -QDockAreaLayoutItem &QDockAreaLayout::item(QList<int> path) +QDockAreaLayoutItem &QDockAreaLayout::item(const QList<int> &path) { Q_ASSERT(!path.isEmpty()); - int index = path.takeFirst(); + const int index = path.first(); Q_ASSERT(index >= 0 && index < QInternal::DockCount); - return docks[index].item(path); + return docks[index].item(path.mid(1)); } -QRect QDockAreaLayout::itemRect(QList<int> path) const +QRect QDockAreaLayout::itemRect(const QList<int> &path) const { Q_ASSERT(!path.isEmpty()); - int index = path.takeFirst(); + const int index = path.first(); Q_ASSERT(index >= 0 && index < QInternal::DockCount); - return docks[index].itemRect(path); + return docks[index].itemRect(path.mid(1)); } QRect QDockAreaLayout::separatorRect(int index) const @@ -2531,49 +2529,49 @@ QRect QDockAreaLayout::separatorRect(int index) const return QRect(); } -QRect QDockAreaLayout::separatorRect(QList<int> path) const +QRect QDockAreaLayout::separatorRect(const QList<int> &path) const { Q_ASSERT(!path.isEmpty()); - int index = path.takeFirst(); + const int index = path.first(); Q_ASSERT(index >= 0 && index < QInternal::DockCount); - if (path.isEmpty()) + if (path.count() == 1) return separatorRect(index); else - return docks[index].separatorRect(path); + return docks[index].separatorRect(path.mid(1)); } -bool QDockAreaLayout::insertGap(QList<int> path, QLayoutItem *dockWidgetItem) +bool QDockAreaLayout::insertGap(const QList<int> &path, QLayoutItem *dockWidgetItem) { Q_ASSERT(!path.isEmpty()); - int index = path.takeFirst(); + const int index = path.first(); Q_ASSERT(index >= 0 && index < QInternal::DockCount); - return docks[index].insertGap(path, dockWidgetItem); + return docks[index].insertGap(path.mid(1), dockWidgetItem); } -QLayoutItem *QDockAreaLayout::plug(QList<int> path) +QLayoutItem *QDockAreaLayout::plug(const QList<int> &path) { Q_ASSERT(!path.isEmpty()); - int index = path.takeFirst(); + const int index = path.first(); Q_ASSERT(index >= 0 && index < QInternal::DockCount); - return docks[index].plug(path); + return docks[index].plug(path.mid(1)); } -QLayoutItem *QDockAreaLayout::unplug(QList<int> path) +QLayoutItem *QDockAreaLayout::unplug(const QList<int> &path) { Q_ASSERT(!path.isEmpty()); - int index = path.takeFirst(); + const int index = path.first(); Q_ASSERT(index >= 0 && index < QInternal::DockCount); - return docks[index].unplug(path); + return docks[index].unplug(path.mid(1)); } -void QDockAreaLayout::remove(QList<int> path) +void QDockAreaLayout::remove(const QList<int> &path) { Q_ASSERT(!path.isEmpty()); - int index = path.takeFirst(); + const int index = path.first(); Q_ASSERT(index >= 0 && index < QInternal::DockCount); - docks[index].remove(path); + docks[index].remove(path.mid(1)); } static inline int qMin(int i1, int i2, int i3) { return qMin(i1, qMin(i2, i3)); } @@ -3066,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); } @@ -3114,9 +3112,8 @@ QRegion QDockAreaLayout::separatorRegion() const return result; } -int QDockAreaLayout::separatorMove(QList<int> separator, const QPoint &origin, - const QPoint &dest, - QVector<QLayoutStruct> *cache) +int QDockAreaLayout::separatorMove(const QList<int> &separator, const QPoint &origin, + const QPoint &dest) { int delta = 0; int index = separator.last(); @@ -3125,21 +3122,18 @@ int QDockAreaLayout::separatorMove(QList<int> separator, const QPoint &origin, QDockAreaLayoutInfo *info = this->info(separator); delta = pick(info->o, dest - origin); if (delta != 0) - delta = info->separatorMove(index, delta, cache); + delta = info->separatorMove(index, delta); info->apply(false); return delta; } - if (cache->isEmpty()) { - QVector<QLayoutStruct> &list = *cache; + QVector<QLayoutStruct> list; - if (index == QInternal::LeftDock || index == QInternal::RightDock) - getGrid(0, &list); - else - getGrid(&list, 0); - } + if (index == QInternal::LeftDock || index == QInternal::RightDock) + getGrid(0, &list); + else + getGrid(&list, 0); - QVector<QLayoutStruct> list = *cache; int sep_index = index == QInternal::LeftDock || index == QInternal::TopDock ? 0 : 1; Qt::Orientation o = index == QInternal::LeftDock || index == QInternal::RightDock @@ -3260,7 +3254,7 @@ QSet<QWidget*> QDockAreaLayout::usedSeparatorWidgets() const return result; } -QRect QDockAreaLayout::gapRect(QList<int> path) const +QRect QDockAreaLayout::gapRect(const QList<int> &path) const { const QDockAreaLayoutInfo *info = this->info(path); if (info == 0) diff --git a/src/gui/widgets/qdockarealayout_p.h b/src/gui/widgets/qdockarealayout_p.h index 137aeba..543a201 100644 --- a/src/gui/widgets/qdockarealayout_p.h +++ b/src/gui/widgets/qdockarealayout_p.h @@ -136,18 +136,18 @@ public: QSize sizeHint() const; QSize size() const; - bool insertGap(QList<int> path, QLayoutItem *dockWidgetItem); - QLayoutItem *plug(QList<int> path); - QLayoutItem *unplug(QList<int> path); + bool insertGap(const QList<int> &path, QLayoutItem *dockWidgetItem); + QLayoutItem *plug(const QList<int> &path); + QLayoutItem *unplug(const QList<int> &path); enum TabMode { NoTabs, AllowTabs, ForceTabs }; QList<int> gapIndex(const QPoint &pos, bool nestingEnabled, TabMode tabMode) const; - void remove(QList<int> path); + void remove(const QList<int> &path); void unnest(int index); void split(int index, Qt::Orientation orientation, QLayoutItem *dockWidgetItem); void tab(int index, QLayoutItem *dockWidgetItem); - QDockAreaLayoutItem &item(QList<int> path); - QDockAreaLayoutInfo *info(QList<int> path); + QDockAreaLayoutItem &item(const QList<int> &path); + QDockAreaLayoutInfo *info(const QList<int> &path); QDockAreaLayoutInfo *info(QWidget *widget); enum { // sentinel values used to validate state data @@ -162,9 +162,9 @@ public: bool expansive(Qt::Orientation o) const; int changeSize(int index, int size, bool below); QRect itemRect(int index) const; - QRect itemRect(QList<int> path) const; + QRect itemRect(const QList<int> &path) const; QRect separatorRect(int index) const; - QRect separatorRect(QList<int> path) const; + QRect separatorRect(const QList<int> &path) const; void clear(); bool isEmpty() const; @@ -181,7 +181,7 @@ public: void paintSeparators(QPainter *p, QWidget *widget, const QRegion &clip, const QPoint &mouse) const; QRegion separatorRegion() const; - int separatorMove(int index, int delta, QVector<QLayoutStruct> *cache); + int separatorMove(int index, int delta); QLayoutItem *itemAt(int *x, int index) const; QLayoutItem *takeAt(int *x, int index); @@ -246,18 +246,18 @@ public: QList<int> gapIndex(const QPoint &pos) const; QList<int> findSeparator(const QPoint &pos) const; - QDockAreaLayoutItem &item(QList<int> path); - QDockAreaLayoutInfo *info(QList<int> path); - const QDockAreaLayoutInfo *info(QList<int> path) const; + QDockAreaLayoutItem &item(const QList<int> &path); + QDockAreaLayoutInfo *info(const QList<int> &path); + const QDockAreaLayoutInfo *info(const QList<int> &path) const; QDockAreaLayoutInfo *info(QWidget *widget); - QRect itemRect(QList<int> path) const; + QRect itemRect(const QList<int> &path) const; QRect separatorRect(int index) const; - QRect separatorRect(QList<int> path) const; + QRect separatorRect(const QList<int> &path) const; - bool insertGap(QList<int> path, QLayoutItem *dockWidgetItem); - QLayoutItem *plug(QList<int> path); - QLayoutItem *unplug(QList<int> path); - void remove(QList<int> path); + bool insertGap(const QList<int> &path, QLayoutItem *dockWidgetItem); + QLayoutItem *plug(const QList<int> &path); + QLayoutItem *unplug(const QList<int> &path); + void remove(const QList<int> &path); void fitLayout(); @@ -277,8 +277,7 @@ public: void paintSeparators(QPainter *p, QWidget *widget, const QRegion &clip, const QPoint &mouse) const; QRegion separatorRegion() const; - int separatorMove(QList<int> separator, const QPoint &origin, const QPoint &dest, - QVector<QLayoutStruct> *cache); + int separatorMove(const QList<int> &separator, const QPoint &origin, const QPoint &dest); void updateSeparatorWidgets() const; QLayoutItem *itemAt(int *x, int index) const; @@ -290,7 +289,7 @@ public: void setGrid(QVector<QLayoutStruct> *ver_struct_list, QVector<QLayoutStruct> *hor_struct_list); - QRect gapRect(QList<int> path) const; + QRect gapRect(const QList<int> &path) const; void keepSize(QDockWidget *w); diff --git a/src/gui/widgets/qdockwidget.cpp b/src/gui/widgets/qdockwidget.cpp index cf259fb..5810c81 100644 --- a/src/gui/widgets/qdockwidget.cpp +++ b/src/gui/widgets/qdockwidget.cpp @@ -59,6 +59,7 @@ #include "qdockwidget_p.h" #include "qmainwindowlayout_p.h" #ifdef Q_WS_MAC +#include <private/qapplication_p.h> #include <private/qt_mac_p.h> #include <qmacstyle_mac.h> #endif @@ -67,8 +68,6 @@ QT_BEGIN_NAMESPACE extern QString qt_setWindowTitle_helperHelper(const QString&, const QWidget*); // qwidget.cpp -extern QHash<QByteArray, QFont> *qt_app_fonts_hash(); // qapplication.cpp - static inline bool hasFeature(const QDockWidgetPrivate *priv, QDockWidget::DockWidgetFeature feature) { return (priv->features & feature) == feature; } @@ -1323,8 +1322,7 @@ void QDockWidget::changeEvent(QEvent *event) QMainWindow *win = qobject_cast<QMainWindow*>(parentWidget()); if (QMainWindowLayout *winLayout = (win ? qobject_cast<QMainWindowLayout*>(win->layout()) : 0)) - if (QDockAreaLayoutInfo *info = - (winLayout ? winLayout->layoutState.dockAreaLayout.info(this) : 0)) + if (QDockAreaLayoutInfo *info = winLayout->layoutState.dockAreaLayout.info(this)) info->updateTabBar(); } #endif // QT_NO_TABBAR diff --git a/src/gui/widgets/qeffects.cpp b/src/gui/widgets/qeffects.cpp index 065a2e0..d6d0a16 100644 --- a/src/gui/widgets/qeffects.cpp +++ b/src/gui/widgets/qeffects.cpp @@ -126,10 +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) - widget->setWindowOpacity(windowOpacity); + widget->setWindowOpacity(windowOpacity); #endif } @@ -160,43 +159,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 +266,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 +286,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 +303,7 @@ void QAlphaWidget::render() pm = QPixmap::fromImage(mixedImage); repaint(); } +#endif // defined(Q_OS_WIN) && !defined(Q_OS_WINCE) } /* 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..2380e78 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) diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp index ab2a7b7..c7f3e97 100644 --- a/src/gui/widgets/qlineedit.cpp +++ b/src/gui/widgets/qlineedit.cpp @@ -1550,10 +1550,7 @@ void QLineEditPrivate::copy(bool clipboard) const Q_Q(const QLineEdit); QString t = q->selectedText(); if (!t.isEmpty() && echoMode == QLineEdit::Normal) { - q->disconnect(QApplication::clipboard(), SIGNAL(selectionChanged()), q, 0); QApplication::clipboard()->setText(t, clipboard ? QClipboard::Clipboard : QClipboard::Selection); - q->connect(QApplication::clipboard(), SIGNAL(selectionChanged()), - q, SLOT(_q_clipboardChanged())); } } @@ -2689,11 +2686,11 @@ QMenu *QLineEdit::createStandardContextMenu() #ifndef QT_NO_CLIPBOARD action = popup->addAction(QLineEdit::tr("Cu&t") + ACCEL_KEY(QKeySequence::Cut)); - action->setEnabled(!d->readOnly && d->hasSelectedText()); + action->setEnabled(!d->readOnly && d->hasSelectedText() && d->echoMode == QLineEdit::Normal); connect(action, SIGNAL(triggered()), SLOT(cut())); action = popup->addAction(QLineEdit::tr("&Copy") + ACCEL_KEY(QKeySequence::Copy)); - action->setEnabled(d->hasSelectedText()); + action->setEnabled(d->hasSelectedText() && d->echoMode == QLineEdit::Normal); connect(action, SIGNAL(triggered()), SLOT(copy())); action = popup->addAction(QLineEdit::tr("&Paste") + ACCEL_KEY(QKeySequence::Paste)); @@ -2749,10 +2746,6 @@ void QLineEdit::changeEvent(QEvent *ev) QWidget::changeEvent(ev); } -void QLineEditPrivate::_q_clipboardChanged() -{ -} - void QLineEditPrivate::_q_handleWindowActivate() { Q_Q(QLineEdit); diff --git a/src/gui/widgets/qlineedit.h b/src/gui/widgets/qlineedit.h index bb75a19..a97dc9a 100644 --- a/src/gui/widgets/qlineedit.h +++ b/src/gui/widgets/qlineedit.h @@ -266,7 +266,6 @@ private: #endif Q_DISABLE_COPY(QLineEdit) Q_DECLARE_PRIVATE(QLineEdit) - Q_PRIVATE_SLOT(d_func(), void _q_clipboardChanged()) Q_PRIVATE_SLOT(d_func(), void _q_handleWindowActivate()) Q_PRIVATE_SLOT(d_func(), void _q_deleteSelected()) #ifndef QT_NO_COMPLETER diff --git a/src/gui/widgets/qlineedit_p.h b/src/gui/widgets/qlineedit_p.h index 3cb73d7..7a4ff26 100644 --- a/src/gui/widgets/qlineedit_p.h +++ b/src/gui/widgets/qlineedit_p.h @@ -216,7 +216,6 @@ public: void drag(); #endif - void _q_clipboardChanged(); void _q_handleWindowActivate(); void _q_deleteSelected(); bool userInput; diff --git a/src/gui/widgets/qmainwindowlayout.cpp b/src/gui/widgets/qmainwindowlayout.cpp index 10e07d3..0318f53 100644 --- a/src/gui/widgets/qmainwindowlayout.cpp +++ b/src/gui/widgets/qmainwindowlayout.cpp @@ -1304,30 +1304,15 @@ bool QMainWindowLayout::separatorMove(const QPoint &pos) if (movingSeparator.isEmpty()) return false; movingSeparatorPos = pos; - separatorMoveTimer->start(); + separatorMoveTimer.start(0, this); return true; } -void QMainWindowLayout::doSeparatorMove() -{ - if (movingSeparator.isEmpty()) - return; - if (movingSeparatorOrigin == movingSeparatorPos) - return; - - layoutState = savedState; - layoutState.dockAreaLayout.separatorMove(movingSeparator, movingSeparatorOrigin, - movingSeparatorPos, - &separatorMoveCache); - movingSeparatorPos = movingSeparatorOrigin; -} - bool QMainWindowLayout::endSeparatorMove(const QPoint&) { bool result = !movingSeparator.isEmpty(); movingSeparator.clear(); savedState.clear(); - separatorMoveCache.clear(); return result; } @@ -1376,7 +1361,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; } @@ -1557,25 +1542,9 @@ bool QMainWindowLayout::plug(QLayoutItem *widgetItem) } } #endif - widgetAnimator->animate(widget, globalRect, - dockOptions & QMainWindow::AnimatedDocks); + widgetAnimator.animate(widget, globalRect, true); } 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; + animationFinished(widget); } return true; @@ -1682,15 +1651,16 @@ QMainWindowLayout::QMainWindowLayout(QMainWindow *mainwindow) #endif #endif #endif // QT_NO_DOCKWIDGET + , widgetAnimator(this) + , pluggingWidget(0) +#ifndef QT_NO_RUBBERBAND + , gapIndicator(QRubberBand::Rectangle, mainwindow) +#endif //QT_NO_RUBBERBAND { #ifndef QT_NO_DOCKWIDGET #ifndef QT_NO_TABBAR sep = mainwindow->style()->pixelMetric(QStyle::PM_DockWidgetSeparatorExtent, 0, mainwindow); #endif - separatorMoveTimer = new QTimer(this); - separatorMoveTimer->setSingleShot(true); - separatorMoveTimer->setInterval(0); - connect(separatorMoveTimer, SIGNAL(timeout()), this, SLOT(doSeparatorMove())); #ifndef QT_NO_TABWIDGET for (int i = 0; i < QInternal::DockCount; ++i) @@ -1699,20 +1669,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(); + 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() @@ -1814,13 +1777,13 @@ QLayoutItem *QMainWindowLayout::unplug(QWidget *widget) void QMainWindowLayout::updateGapIndicator() { #ifndef QT_NO_RUBBERBAND - if (widgetAnimator->animating() || currentGapPos.isEmpty()) { - gapIndicator->hide(); + if (widgetAnimator.animating() || currentGapPos.isEmpty()) { + gapIndicator.hide(); } else { - if (gapIndicator->geometry() != currentGapRect) - gapIndicator->setGeometry(currentGapRect); - if (!gapIndicator->isVisible()) - gapIndicator->show(); + if (gapIndicator.geometry() != currentGapRect) + gapIndicator.setGeometry(currentGapRect); + if (!gapIndicator.isVisible()) + gapIndicator.show(); } #endif } @@ -1982,6 +1945,27 @@ bool QMainWindowLayout::usesHIToolBar(QToolBar *toolbar) const #endif } +void QMainWindowLayout::timerEvent(QTimerEvent *e) +{ +#ifndef QT_NO_DOCKWIDGET + if (e->timerId() == separatorMoveTimer.timerId()) { + //let's move the separators + separatorMoveTimer.stop(); + if (movingSeparator.isEmpty()) + return; + if (movingSeparatorOrigin == movingSeparatorPos) + return; + + layoutState = savedState; + layoutState.dockAreaLayout.separatorMove(movingSeparator, movingSeparatorOrigin, + movingSeparatorPos); + movingSeparatorPos = movingSeparatorOrigin; + } +#endif + QLayout::timerEvent(e); +} + + QT_END_NAMESPACE #endif // QT_NO_MAINWINDOW diff --git a/src/gui/widgets/qmainwindowlayout_mac.mm b/src/gui/widgets/qmainwindowlayout_mac.mm index 03bae2f..6632be7 100644 --- a/src/gui/widgets/qmainwindowlayout_mac.mm +++ b/src/gui/widgets/qmainwindowlayout_mac.mm @@ -329,18 +329,16 @@ OSStatus QMainWindowLayout::qtmacToolbarDelegate(EventHandlerCallRef, EventRef e void QMainWindowLayout::updateHIToolBarStatus() { bool useMacToolbar = layoutState.mainWindow->unifiedTitleAndToolBarOnMac(); - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) { #ifndef QT_MAC_USE_COCOA - if (useMacToolbar) { - ChangeWindowAttributes(qt_mac_window_for(layoutState.mainWindow), - kWindowUnifiedTitleAndToolbarAttribute, 0); - } else { - ChangeWindowAttributes(qt_mac_window_for(layoutState.mainWindow), - 0, kWindowUnifiedTitleAndToolbarAttribute); - } -#endif - macWindowToolbarShow(layoutState.mainWindow, useMacToolbar); + if (useMacToolbar) { + ChangeWindowAttributes(qt_mac_window_for(layoutState.mainWindow), + kWindowUnifiedTitleAndToolbarAttribute, 0); + } else { + ChangeWindowAttributes(qt_mac_window_for(layoutState.mainWindow), + 0, kWindowUnifiedTitleAndToolbarAttribute); } +#endif + macWindowToolbarShow(layoutState.mainWindow, useMacToolbar); layoutState.mainWindow->setUpdatesEnabled(false); // reduces a little bit of flicker, not all though if (!useMacToolbar) { diff --git a/src/gui/widgets/qmainwindowlayout_p.h b/src/gui/widgets/qmainwindowlayout_p.h index f5fcbda..5c5965a 100644 --- a/src/gui/widgets/qmainwindowlayout_p.h +++ b/src/gui/widgets/qmainwindowlayout_p.h @@ -59,9 +59,12 @@ #include "QtGui/qlayout.h" #include "QtGui/qtabbar.h" +#include "QtGui/qrubberband.h" #include "QtCore/qvector.h" #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" @@ -88,7 +91,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 @@ -165,6 +167,8 @@ public: void setDockOptions(QMainWindow::DockOptions opts); bool usesHIToolBar(QToolBar *toolbar) const; + void timerEvent(QTimerEvent *e); + // status bar QLayoutItem *statusbar; @@ -243,8 +247,7 @@ public: QList<int> movingSeparator; QPoint movingSeparatorOrigin, movingSeparatorPos; - QTimer *separatorMoveTimer; - QVector<QLayoutStruct> separatorMoveCache; + QBasicTimer separatorMoveTimer; bool startSeparatorMove(const QPoint &pos); bool separatorMove(const QPoint &pos); @@ -276,12 +279,12 @@ public: // animations - QWidgetAnimator *widgetAnimator; + QWidgetAnimator widgetAnimator; QList<int> currentGapPos; QRect currentGapRect; QWidget *pluggingWidget; #ifndef QT_NO_RUBBERBAND - QRubberBand *gapIndicator; + QRubberBand gapIndicator; #endif QList<int> hover(QLayoutItem *widgetItem, const QPoint &mousePos); @@ -293,12 +296,11 @@ public: void applyState(QMainWindowLayoutState &newState, bool animate = true); void restore(bool keepSavedState = false); void updateHIToolBarStatus(); - -private slots: void animationFinished(QWidget *widget); void allAnimationsFinished(); + +private slots: #ifndef QT_NO_DOCKWIDGET - void doSeparatorMove(); #ifndef QT_NO_TABBAR void tabChanged(); #endif diff --git a/src/gui/widgets/qmdisubwindow.cpp b/src/gui/widgets/qmdisubwindow.cpp index 25bc724..24dea37 100644 --- a/src/gui/widgets/qmdisubwindow.cpp +++ b/src/gui/widgets/qmdisubwindow.cpp @@ -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 fc55a2c..d3f5bc5 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -150,7 +150,6 @@ private: void QMenuPrivate::init() { Q_Q(QMenu); - activationRecursionGuard = false; #ifndef QT_NO_WHATSTHIS q->setAttribute(Qt::WA_CustomWhatsThis); #endif @@ -194,57 +193,76 @@ QList<QPointer<QWidget> > QMenuPrivate::calcCausedStack() const return ret; } -void QMenuPrivate::calcActionRects(QMap<QAction*, QRect> &actionRects, QList<QAction*> &actionList) const +void QMenuPrivate::updateActionRects() const { Q_Q(const QMenu); - if (!itemsDirty) { - actionRects = this->actionRects; - actionList = this->actionList; + if (!itemsDirty) return; + + //let's reinitialize the buffer + actionRects.resize(actions.count()); + actionRects.fill(QRect()); + + //let's try to get the last visible action + int lastVisibleAction = actions.count() - 1; + for(;lastVisibleAction >= 0; --lastVisibleAction) { + const QAction *action = actions.at(lastVisibleAction); + if (action->isVisible()) { + //removing trailing separators + if (action->isSeparator() && collapsibleSeparators) + continue; + break; + } } - actionRects.clear(); - actionList.clear(); int max_column_width = 0, dh = popupGeometry(QApplication::desktop()->screenNumber(q)).height(), - ncols = 1, y = 0; - const int hmargin = q->style()->pixelMetric(QStyle::PM_MenuHMargin, 0, q), - vmargin = q->style()->pixelMetric(QStyle::PM_MenuVMargin, 0, q), - icone = q->style()->pixelMetric(QStyle::PM_SmallIconSize, 0, q); + QStyle *style = q->style(); + const int hmargin = style->pixelMetric(QStyle::PM_MenuHMargin, 0, q), + vmargin = style->pixelMetric(QStyle::PM_MenuVMargin, 0, q), + icone = style->pixelMetric(QStyle::PM_SmallIconSize, 0, q); //for compatability now - will have to refactor this away.. tabWidth = 0; maxIconWidth = 0; hasCheckableItems = false; - QList<QAction*> items = filteredActions(); - for(int i = 0; i < items.count(); i++) { - QAction *action = items.at(i); - if (widgetItems.value(action)) + ncols = 1; + sloppyAction = 0; + + for (int i = 0; i < actions.count(); ++i) { + QAction *action = actions.at(i); + if (action->isSeparator() || !action->isVisible() || widgetItems.at(i)) continue; + //..and some members hasCheckableItems |= action->isCheckable(); QIcon is = action->icon(); if (!is.isNull()) { - uint miw = maxIconWidth; - maxIconWidth = qMax<uint>(miw, icone + 4); + maxIconWidth = qMax<uint>(maxIconWidth, icone + 4); } } //calculate size QFontMetrics qfm = q->fontMetrics(); - for(int i = 0; i < items.count(); i++) { - QAction *action = items.at(i); + bool previousWasSeparator = true; // this is true to allow removing the leading separators + for(int i = 0; i <= lastVisibleAction; i++) { + QAction *action = actions.at(i); - QFontMetrics fm(action->font().resolve(q->font())); - QSize sz; + if (!action->isVisible() || + (collapsibleSeparators && previousWasSeparator && action->isSeparator())) + continue; // we continue, this action will get an empty QRect + + previousWasSeparator = action->isSeparator(); //let the style modify the above size.. QStyleOptionMenuItem opt; q->initStyleOption(&opt, action); opt.rect = q->rect(); + const QFontMetrics &fm = opt.fontMetrics; - if (QWidget *w = widgetItems.value(action)) { - sz=w->sizeHint().expandedTo(w->minimumSize()).expandedTo(w->minimumSizeHint()).boundedTo(w->maximumSize()); + QSize sz; + if (QWidget *w = widgetItems.at(i)) { + sz = w->sizeHint().expandedTo(w->minimumSize()).expandedTo(w->minimumSizeHint()).boundedTo(w->maximumSize()); } else { //calc what I think the size is.. if (action->isSeparator()) { @@ -275,7 +293,7 @@ void QMenuPrivate::calcActionRects(QMap<QAction*, QRect> &actionRects, QList<QAc sz.setHeight(is_sz.height()); } } - sz = q->style()->sizeFromContents(QStyle::CT_MenuItem, &opt, sz, q); + sz = style->sizeFromContents(QStyle::CT_MenuItem, &opt, sz, q); } @@ -283,119 +301,59 @@ void QMenuPrivate::calcActionRects(QMap<QAction*, QRect> &actionRects, QList<QAc max_column_width = qMax(max_column_width, sz.width()); //wrapping if (!scroll && - y+sz.height()+vmargin > dh - (q->style()->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, 0, q) * 2)) { + y+sz.height()+vmargin > dh - (style->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, 0, q) * 2)) { ncols++; y = vmargin; } y += sz.height(); - //append item - actionRects.insert(action, QRect(0, 0, sz.width(), sz.height())); - actionList.append(action); + //update the item + actionRects[i] = QRect(0, 0, sz.width(), sz.height()); } } - if (tabWidth) - max_column_width += tabWidth; //finally add in the tab width + max_column_width += tabWidth; //finally add in the tab width //calculate position - int x = hmargin; - y = vmargin; - - for(int i = 0; i < actionList.count(); i++) { - QAction *action = actionList.at(i); - QRect &rect = actionRects[action]; + const int fw = style->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q); + const int base_y = vmargin + fw + topmargin + + (scroll ? scroll->scrollOffset : 0) + + (tearoff ? style->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, q) : 0); + int x = hmargin + fw + leftmargin; + y = base_y; + + for(int i = 0; i < actions.count(); i++) { + QRect &rect = actionRects[i]; if (rect.isNull()) continue; if (!scroll && - y+rect.height() > dh - (q->style()->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, 0, q) * 2)) { - ncols--; - if (ncols < 0) - qWarning("QMenu: Column calculation mismatch (%d)", ncols); + y+rect.height() > dh - (style->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, 0, q) * 2)) { x += max_column_width + hmargin; - y = vmargin; + y = base_y; } rect.translate(x, y); //move rect.setWidth(max_column_width); //uniform width - y += rect.height(); - } -} -void QMenuPrivate::updateActions() -{ - Q_Q(const QMenu); - if (!itemsDirty) - return; - sloppyAction = 0; - calcActionRects(actionRects, actionList); - for (QHash<QAction *, QWidget *>::ConstIterator item = widgetItems.constBegin(), - end = widgetItems.constEnd(); item != end; ++item) { - QAction *action = item.key(); - QWidget *widget = item.value(); - widget->setGeometry(actionRect(action)); - widget->setVisible(action->isVisible()); - } - ncols = 1; - int last_left = q->style()->pixelMetric(QStyle::PM_MenuVMargin, 0, q); - if (!scroll) { - for(int i = 0; i < actionList.count(); i++) { - int left = actionRects.value(actionList.at(i)).left(); - if (left > last_left) { - last_left = left; - ncols++; - } + //we need to update the widgets geometry + if (QWidget *widget = widgetItems.at(i)) { + widget->setGeometry(rect); + widget->setVisible(actions.at(i)->isVisible()); } + + y += rect.height(); } itemsDirty = 0; } -QList<QAction *> QMenuPrivate::filteredActions() const +QRect QMenuPrivate::actionRect(QAction *act) const { - QList<QAction *> visibleActions; - int i = 0; - while (i < actions.count()) { - QAction *action = actions.at(i); - if (!action->isVisible()) { - ++i; - continue; - } - if (!action->isSeparator() || !collapsibleSeparators) { - visibleActions.append(action); - ++i; - continue; - } + int index = actions.indexOf(act); + if (index == -1) + return QRect(); - // no leading separators - if (!visibleActions.isEmpty()) - visibleActions.append(action); + updateActionRects(); - // skip double/tripple/etc. separators - while (i < actions.count() - && (!actions.at(i)->isVisible() || actions.at(i)->isSeparator())) - ++i; - } - - if (collapsibleSeparators) { - // remove trailing separators - while (!visibleActions.isEmpty() && visibleActions.last()->isSeparator()) - visibleActions.removeLast(); - } - - return visibleActions; -} - -QRect QMenuPrivate::actionRect(QAction *act) const -{ - Q_Q(const QMenu); - QRect ret = actionRects.value(act); - if (ret.isNull()) - return ret; - if (scroll) - ret.translate(0, scroll->scrollOffset); - if (tearoff) - ret.translate(0, q->style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, q)); - const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q); - ret.translate(fw+leftmargin, fw+topmargin); - return ret; + //we found the action + return actionRects.at(index); } static const qreal MenuFadeTimeInSec = 0.150; @@ -525,14 +483,18 @@ void QMenuPrivate::setSyncAction() void QMenuPrivate::setFirstActionActive() { Q_Q(QMenu); + updateActionRects(); const int scrollerHeight = q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q); - for(int i = 0, saccum = 0; i < actionList.count(); i++) { - QAction *act = actionList[i]; + for(int i = 0, saccum = 0; i < actions.count(); i++) { + const QRect &rect = actionRects.at(i); + if (rect.isNull()) + continue; if (scroll && scroll->scrollFlags & QMenuScroller::ScrollUp) { - saccum -= actionRects.value(act).height(); + saccum -= rect.height(); 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())) { @@ -582,9 +544,10 @@ void QMenuPrivate::setCurrentAction(QAction *action, int popup, SelectionReason popupAction(currentAction, popup, activateFirst); } q->update(actionRect(action)); - QWidget *widget = widgetItems.value(action); if (reason == SelectedFromKeyboard) { + const int actionIndex = actions.indexOf(action); + QWidget *widget = widgetItems.at(actionIndex); if (widget) { if (widget->focusPolicy() != Qt::NoFocus) widget->setFocus(Qt::TabFocusReason); @@ -628,10 +591,9 @@ QAction *QMenuPrivate::actionAt(QPoint p) const if (!q_func()->rect().contains(p)) //sanity check return 0; - for(int i = 0; i < actionList.count(); i++) { - QAction *act = actionList[i]; - if (actionRect(act).contains(p)) - return act; + for(int i = 0; i < actionRects.count(); i++) { + if (actionRects.at(i).contains(p)) + return actions.at(i); } return 0; } @@ -705,6 +667,7 @@ 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; @@ -713,18 +676,18 @@ void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation loc const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q); if (location == QMenuScroller::ScrollTop) { - for(int i = 0, saccum = 0; i < actionList.count(); i++) { - QAction *act = actionList.at(i); + for(int i = 0, saccum = 0; i < actions.count(); i++) { + QAction *act = actions.at(i); if (act == action) { newOffset = topScroll - saccum; break; } - saccum += actionRects.value(act).height(); + saccum += actionRects.at(i).height(); } } else { - for(int i = 0, saccum = 0; i < actionList.count(); i++) { - QAction *act = actionList.at(i); - saccum += actionRects.value(act).height(); + for(int i = 0, saccum = 0; i < actions.count(); i++) { + QAction *act = actions.at(i); + saccum += actionRects.at(i).height(); if (act == action) { if (location == QMenuScroller::ScrollCenter) newOffset = ((q->height() / 2) - botScroll) - (saccum - topScroll); @@ -734,7 +697,7 @@ void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation loc } } if(newOffset) - newOffset -= fw*2; + newOffset -= fw * 2; } //figure out which scroll flags @@ -742,8 +705,8 @@ void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation loc if (newOffset < 0) //easy and cheap one newScrollFlags |= QMenuScroller::ScrollUp; int saccum = newOffset; - for(int i = 0; i < actionList.count(); i++) { - saccum += actionRects.value(actionList.at(i)).height(); + for(int i = 0; i < actionRects.count(); i++) { + saccum += actionRects.at(i).height(); if (saccum > q->height()) { newScrollFlags |= QMenuScroller::ScrollDown; break; @@ -807,9 +770,12 @@ 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 = actionList.size()-1; i >= 0; --i) { - QAction *act = actionList.at(i); + for(int i = actions.size()-1; i >= 0; --i) { + QAction *act = actions.at(i); + if (actionRects.at(i).isNull()) + continue; if (!act->isSeparator() && (q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, q) || act->isEnabled())) { @@ -821,8 +787,10 @@ void QMenuPrivate::scrollMenu(QMenuScroller::ScrollLocation location, bool activ } } } else if(location == QMenuScroller::ScrollTop) { - for(int i = 0; i < actionList.size(); ++i) { - QAction *act = actionList.at(i); + for(int i = 0; i < actions.size(); ++i) { + QAction *act = actions.at(i); + if (actionRects.at(i).isNull()) + continue; if (!act->isSeparator() && (q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, q) || act->isEnabled())) { @@ -842,6 +810,7 @@ void QMenuPrivate::scrollMenu(QMenuScroller::ScrollDirection direction, bool pag Q_Q(QMenu); if (!scroll || !(scroll->scrollFlags & direction)) //not really possible... return; + updateActionRects(); 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; @@ -849,31 +818,26 @@ void QMenuPrivate::scrollMenu(QMenuScroller::ScrollDirection direction, bool pag const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q); const int offset = topScroll ? topScroll-vmargin : 0; if (direction == QMenuScroller::ScrollUp) { - for(int i = 0, saccum = 0; i < actionList.count(); i++) { - QAction *act = actionList.at(i); - const int iHeight = actionRects.value(act).height(); - saccum -= iHeight; + for(int i = 0, saccum = 0; i < actions.count(); i++) { + saccum -= actionRects.at(i).height(); if (saccum <= scroll->scrollOffset-offset) { - scrollMenu(act, page ? QMenuScroller::ScrollBottom : QMenuScroller::ScrollTop, active); + scrollMenu(actions.at(i), page ? QMenuScroller::ScrollBottom : QMenuScroller::ScrollTop, active); break; } } } else if (direction == QMenuScroller::ScrollDown) { bool scrolled = false; - for(int i = 0, saccum = 0; i < actionList.count(); i++) { - QAction *act = actionList.at(i); - const int iHeight = actionRects.value(act).height(); + for(int i = 0, saccum = 0; i < actions.count(); i++) { + const int iHeight = actionRects.at(i).height(); saccum -= iHeight; if (saccum <= scroll->scrollOffset-offset) { const int scrollerArea = q->height() - botScroll - fw*2; int visible = (scroll->scrollOffset-offset) - saccum; - for(i++ ; i < actionList.count(); i++) { - act = actionList.at(i); - const int iHeight = actionRects.value(act).height(); - visible += iHeight; + for(i++ ; i < actions.count(); i++) { + visible += actionRects.at(i).height(); if (visible > scrollerArea - topScroll) { scrolled = true; - scrollMenu(act, page ? QMenuScroller::ScrollTop : QMenuScroller::ScrollBottom, active); + scrollMenu(actions.at(i), page ? QMenuScroller::ScrollTop : QMenuScroller::ScrollBottom, active); break; } } @@ -1178,7 +1142,8 @@ void QMenu::initStyleOption(QStyleOptionMenuItem *option, const QAction *action) else option->palette.setCurrentColorGroup(QPalette::Disabled); - option->font = action->font(); + option->font = action->font().resolve(font()); + option->fontMetrics = QFontMetrics(option->font); if (d->currentAction && d->currentAction == action && !d->currentAction->isSeparator()) { option->state |= QStyle::State_Selected @@ -1373,14 +1338,13 @@ QMenu::QMenu(QMenuPrivate &dd, QWidget *parent) QMenu::~QMenu() { Q_D(QMenu); - for (QHash<QAction *, QWidget *>::ConstIterator item = d->widgetItems.constBegin(), - end = d->widgetItems.constEnd(); item != end; ++item) { - QWidgetAction *action = static_cast<QWidgetAction *>(item.key()); - QWidget *widget = item.value(); - if (action && widget) + for (int i = 0; i < d->widgetItems.count(); ++i) { + if (QWidget *widget = d->widgetItems.at(i)) { + QWidgetAction *action = static_cast<QWidgetAction *>(d->actions.at(i)); action->releaseWidget(widget); + d->widgetItems[i] = 0; + } } - d->widgetItems.clear(); if (d->eventLoop) d->eventLoop->exit(); @@ -1732,35 +1696,36 @@ QSize QMenu::sizeHint() const { Q_D(const QMenu); ensurePolished(); - QMap<QAction*, QRect> actionRects; - QList<QAction*> actionList; - d->calcActionRects(actionRects, actionList); + d->updateActionRects(); QSize s; QStyleOption opt(0); opt.rect = rect(); opt.palette = palette(); opt.state = QStyle::State_None; - for (QMap<QAction*, QRect>::const_iterator i = actionRects.constBegin(); - i != actionRects.constEnd(); ++i) { - if (i.value().bottom() > s.height()) - s.setHeight(i.value().y()+i.value().height()); - if (i.value().right() > s.width()) - s.setWidth(i.value().right()); + for (int i = 0; i < d->actionRects.count(); ++i) { + const QRect &rect = d->actionRects.at(i); + if (rect.isNull()) + continue; + if (rect.bottom() >= s.height()) + s.setHeight(rect.y() + rect.height()); + if (rect.right() >= s.width()) + s.setWidth(rect.x() + rect.width()); } if (d->tearoff) s.rheight() += style()->pixelMetric(QStyle::PM_MenuTearoffHeight, &opt, this); - if (const int fw = style()->pixelMetric(QStyle::PM_MenuPanelWidth, &opt, this)) { - s.rwidth() += fw*2; - s.rheight() += fw*2; - } // 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. + if (const int fw = style()->pixelMetric(QStyle::PM_MenuPanelWidth, &opt, this)) { + s.rwidth() += fw; + s.rheight() += fw; + } + s.rwidth() += style()->pixelMetric(QStyle::PM_MenuHMargin, &opt, this); s.rheight() += style()->pixelMetric(QStyle::PM_MenuVMargin, &opt, this); - s += QSize(d->leftmargin + d->rightmargin, d->topmargin + d->bottommargin); + s += QSize(d->rightmargin, d->bottommargin); return style()->sizeFromContents(QStyle::CT_Menu, &opt, s.expandedTo(QApplication::globalStrut()), this); @@ -1802,7 +1767,7 @@ void QMenu::popup(const QPoint &p, QAction *atAction) ensurePolished(); // Get the right font emit aboutToShow(); - d->updateActions(); + d->updateActionRects(); QPoint pos = p; QSize size = sizeHint(); QRect screen = d->popupGeometry(QApplication::desktop()->screenNumber(p)); @@ -1811,10 +1776,10 @@ void QMenu::popup(const QPoint &p, QAction *atAction) if (d->ncols > 1) { pos.setY(screen.top()+desktopFrame); } else if (atAction) { - for(int i=0, above_height=0; i<(int)d->actionList.count(); i++) { - QAction *action = d->actionList.at(i); + for(int i = 0, above_height = 0; i < d->actions.count(); i++) { + QAction *action = d->actions.at(i); if (action == atAction) { - int newY = pos.y()-above_height; + int newY = pos.y() - above_height; if (d->scroll && newY < desktopFrame) { d->scroll->scrollFlags = d->scroll->scrollFlags | QMenuPrivate::QMenuScroller::ScrollUp; @@ -1826,13 +1791,13 @@ void QMenu::popup(const QPoint &p, QAction *atAction) if (d->scroll && d->scroll->scrollFlags != QMenuPrivate::QMenuScroller::ScrollNone && !style()->styleHint(QStyle::SH_Menu_FillScreenWithScroll, 0, this)) { int below_height = above_height + d->scroll->scrollOffset; - for(int i2 = i; i2 < d->actionList.count(); i2++) - below_height += d->actionRects.value(d->actionList.at(i2)).height(); + for(int i2 = i; i2 < d->actionRects.count(); i2++) + below_height += d->actionRects.at(i2).height(); size.setHeight(below_height); } break; } else { - above_height += d->actionRects.value(action).height(); + above_height += d->actionRects.at(i).height(); } } } @@ -2039,8 +2004,7 @@ QAction *QMenu::exec(const QPoint &p, QAction *action) QAction *QMenu::exec(QList<QAction*> actions, const QPoint &pos, QAction *at, QWidget *parent) { QMenu menu(parent); - for(QList<QAction*>::ConstIterator it = actions.constBegin(); it != actions.constEnd(); ++it) - menu.addAction((*it)); + menu.addActions(actions); return menu.exec(pos, at); } @@ -2098,6 +2062,7 @@ void QMenu::hideEvent(QHideEvent *) void QMenu::paintEvent(QPaintEvent *e) { Q_D(QMenu); + d->updateActionRects(); QPainter p(this); QRegion emptyArea = QRegion(rect()); @@ -2110,11 +2075,11 @@ void QMenu::paintEvent(QPaintEvent *e) style()->drawPrimitive(QStyle::PE_PanelMenu, &menuOpt, &p, this); //draw the items that need updating.. - for (int i = 0; i < d->actionList.count(); ++i) { - QAction *action = d->actionList.at(i); - QRect adjustedActionRect = d->actionRect(action); + for (int i = 0; i < d->actions.count(); ++i) { + QAction *action = d->actions.at(i); + QRect adjustedActionRect = d->actionRects.at(i); if (!e->rect().intersects(adjustedActionRect) - || d->widgetItems.value(action)) + || d->widgetItems.at(i)) continue; //set the clip region to be extra safe (and adjust for the scrollers) QRegion adjustedActionReg(adjustedActionRect); @@ -2263,7 +2228,7 @@ void QMenu::mouseReleaseEvent(QMouseEvent *e) break; } } - if (e->button() || isContextMenu) + if (e->button() == Qt::LeftButton || isContextMenu) #endif d->activateAction(action, QAction::Trigger); } @@ -2344,11 +2309,11 @@ QMenu::event(QEvent *e) setMask(menuMask.region); } d->itemsDirty = 1; - d->updateActions(); + d->updateActionRects(); break; } case QEvent::Show: d->mouseDown = 0; - d->updateActions(); + d->updateActionRects(); if (d->currentAction) d->popupAction(d->currentAction, 0, false); break; @@ -2384,6 +2349,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) @@ -2435,8 +2401,10 @@ void QMenu::keyPressEvent(QKeyEvent *e) QMenuPrivate::QMenuScroller::ScrollLocation scroll_loc = QMenuPrivate::QMenuScroller::ScrollStay; if (!d->currentAction) { if(key == Qt::Key_Down) { - for(int i = 0; i < d->actionList.size(); ++i) { - QAction *act = d->actionList.at(i); + for(int i = 0; i < d->actions.count(); ++i) { + QAction *act = d->actions.at(i); + if (d->actionRects.at(i).isNull()) + continue; if (!act->isSeparator() && (style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, this) || act->isEnabled())) { @@ -2445,8 +2413,10 @@ void QMenu::keyPressEvent(QKeyEvent *e) } } } else { - for(int i = d->actionList.size()-1; i >= 0; --i) { - QAction *act = d->actionList.at(i); + for(int i = d->actions.count()-1; i >= 0; --i) { + QAction *act = d->actions.at(i); + if (d->actionRects.at(i).isNull()) + continue; if (!act->isSeparator() && (style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, this) || act->isEnabled())) { @@ -2456,8 +2426,8 @@ void QMenu::keyPressEvent(QKeyEvent *e) } } } else { - for(int i=0, y=0; !nextAction && i < (int)d->actionList.count(); i++) { - QAction *act = d->actionList.at(i); + for(int i = 0, y = 0; !nextAction && i < d->actions.count(); i++) { + QAction *act = d->actions.at(i); if (act == d->currentAction) { if (key == Qt::Key_Up) { for(int next_i = i-1; true; next_i--) { @@ -2466,11 +2436,13 @@ void QMenu::keyPressEvent(QKeyEvent *e) break; if (d->scroll) scroll_loc = QMenuPrivate::QMenuScroller::ScrollBottom; - next_i = d->actionList.count()-1; + next_i = d->actionRects.count()-1; } - QAction *next = d->actionList.at(next_i); + QAction *next = d->actions.at(next_i); if (next == d->currentAction) break; + if (d->actionRects.at(next_i).isNull()) + continue; if (next->isSeparator() || (!next->isEnabled() && !style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, this))) @@ -2480,7 +2452,7 @@ void QMenu::keyPressEvent(QKeyEvent *e) int topVisible = style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, this); if (d->tearoff) topVisible += style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this); - if (((y + d->scroll->scrollOffset) - topVisible) <= d->actionRects.value(nextAction).height()) + if (((y + d->scroll->scrollOffset) - topVisible) <= d->actionRects.at(next_i).height()) scroll_loc = QMenuPrivate::QMenuScroller::ScrollTop; } break; @@ -2488,18 +2460,20 @@ void QMenu::keyPressEvent(QKeyEvent *e) if (!nextAction && d->tearoff) d->tearoffHighlighted = 1; } else { - y += d->actionRects.value(act).height(); + y += d->actionRects.at(i).height(); for(int next_i = i+1; true; next_i++) { - if (next_i == d->actionList.count()) { + if (next_i == d->actionRects.count()) { if(!style()->styleHint(QStyle::SH_Menu_SelectionWrap, 0, this)) break; if (d->scroll) scroll_loc = QMenuPrivate::QMenuScroller::ScrollTop; next_i = 0; } - QAction *next = d->actionList.at(next_i); + QAction *next = d->actions.at(next_i); if (next == d->currentAction) break; + if (d->actionRects.at(next_i).isNull()) + continue; if (next->isSeparator() || (!next->isEnabled() && !style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, this))) @@ -2512,7 +2486,7 @@ void QMenu::keyPressEvent(QKeyEvent *e) bottomVisible -= scrollerHeight; if (d->tearoff) bottomVisible -= style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this); - if ((y + d->scroll->scrollOffset + d->actionRects.value(nextAction).height()) > bottomVisible) + if ((y + d->scroll->scrollOffset + d->actionRects.at(next_i).height()) > bottomVisible) scroll_loc = QMenuPrivate::QMenuScroller::ScrollBottom; } break; @@ -2520,7 +2494,7 @@ void QMenu::keyPressEvent(QKeyEvent *e) } break; } - y += d->actionRects.value(act).height(); + y += d->actionRects.at(i).height(); } } if (nextAction) { @@ -2648,9 +2622,11 @@ void QMenu::keyPressEvent(QKeyEvent *e) int best_match_count = 0; d->searchBufferTimer.start(2000, this); d->searchBuffer += e->text(); - for(int i = 0; i < d->actionList.size(); ++i) { + for(int i = 0; i < d->actions.size(); ++i) { int match_count = 0; - register QAction *act = d->actionList.at(i); + if (d->actionRects.at(i).isNull()) + continue; + QAction *act = d->actions.at(i); const QString act_text = act->text(); for(int c = 0; c < d->searchBuffer.size(); ++c) { if(act_text.indexOf(d->searchBuffer.at(c), 0, Qt::CaseInsensitive) != -1) @@ -2667,8 +2643,10 @@ void QMenu::keyPressEvent(QKeyEvent *e) int clashCount = 0; QAction *first = 0, *currentSelected = 0, *firstAfterCurrent = 0; QChar c = e->text().at(0).toUpper(); - for(int i = 0; i < d->actionList.size(); ++i) { - register QAction *act = d->actionList.at(i); + for(int i = 0; i < d->actions.size(); ++i) { + if (d->actionRects.at(i).isNull()) + continue; + QAction *act = d->actions.at(i); QKeySequence sequence = QKeySequence::mnemonic(act->text()); int key = sequence[0] & 0xffff; if (key == c.unicode()) { @@ -2739,7 +2717,7 @@ void QMenu::mouseMoveEvent(QMouseEvent *e) d->motions++; if (d->motions == 0) // ignore first mouse move event (see enterEvent()) return; - d->hasHadMouse |= rect().contains(e->pos()); + d->hasHadMouse = d->hasHadMouse || rect().contains(e->pos()); QAction *action = d->actionAt(e->pos()); if (!action) { @@ -2813,31 +2791,25 @@ void QMenu::actionEvent(QActionEvent *e) connect(e->action(), SIGNAL(triggered()), this, SLOT(_q_actionTriggered())); connect(e->action(), SIGNAL(hovered()), this, SLOT(_q_actionHovered())); } + QWidget *widget = 0; + if (QWidgetAction *wa = qobject_cast<QWidgetAction *>(e->action())) + widget = wa->requestWidget(this); + + int index = d->actions.indexOf(e->action()); + Q_ASSERT(index != -1); + d->widgetItems.insert(index, widget); - if (QWidgetAction *wa = qobject_cast<QWidgetAction *>(e->action())) { - QWidget *widget = wa->requestWidget(this); - if (widget) - d->widgetItems.insert(wa, widget); - } } else if (e->type() == QEvent::ActionRemoved) { - d->actionRects.clear(); - d->actionList.clear(); e->action()->disconnect(this); if (e->action() == d->currentAction) d->currentAction = 0; + int index = d->actions.indexOf(e->before()) + 1; if (QWidgetAction *wa = qobject_cast<QWidgetAction *>(e->action())) { - QWidget *widget = d->widgetItems.take(wa); - if (widget) + if (QWidget *widget = d->widgetItems.at(index)) wa->releaseWidget(widget); - } else { - // If this is called from the QAction destructor, the - // previous call to qobject_cast will fail because the - // QWidgetAction has been destroyed already. We need to - // remove it from the hash anyway or it might crash later - // the widget itself has been already destroyed in - // ~QWidgetAction - d->widgetItems.remove(e->action()); } + Q_ASSERT(index != -1); + d->widgetItems.removeAt(index); } #ifdef Q_WS_MAC @@ -2863,7 +2835,7 @@ void QMenu::actionEvent(QActionEvent *e) #endif if (isVisible()) { - d->updateActions(); + d->updateActionRects(); resize(sizeHint()); update(); } @@ -3044,7 +3016,7 @@ void QMenu::setSeparatorsCollapsible(bool collapse) d->collapsibleSeparators = collapse; d->itemsDirty = 1; if (isVisible()) { - d->updateActions(); + d->updateActionRects(); update(); } } @@ -3103,9 +3075,9 @@ int QMenu::insertSeparator(int index) QAction *QMenu::findActionForId(int id) const { - QList<QAction *> list = actions(); - for (int i = 0; i < list.size(); ++i) { - QAction *act = list.at(i); + Q_D(const QMenu); + for (int i = 0; i < d->actions.size(); ++i) { + QAction *act = d->actions.at(i); if (findIdForAction(act)== id) return act; } diff --git a/src/gui/widgets/qmenu_mac.mm b/src/gui/widgets/qmenu_mac.mm index 6056119..77e98c4 100644 --- a/src/gui/widgets/qmenu_mac.mm +++ b/src/gui/widgets/qmenu_mac.mm @@ -1180,7 +1180,7 @@ QMenuPrivate::QMacMenuPrivate::addAction(QMacMenuAction *action, QMacMenuAction #endif } - QWidget *widget = qmenu ? qmenu->widgetItems.value(action->action) : 0; + QWidget *widget = qmenu ? qmenu->widgetItems.value(qmenu->actions.indexOf(action->action)) : 0; if (widget) { #ifndef QT_MAC_USE_COCOA ChangeMenuAttributes(action->menu, kMenuAttrDoNotCacheImage, 0); diff --git a/src/gui/widgets/qmenu_p.h b/src/gui/widgets/qmenu_p.h index 1ea8fe9..50a9f2f 100644 --- a/src/gui/widgets/qmenu_p.h +++ b/src/gui/widgets/qmenu_p.h @@ -126,9 +126,9 @@ class QMenuPrivate : public QWidgetPrivate Q_DECLARE_PUBLIC(QMenu) public: QMenuPrivate() : itemsDirty(0), maxIconWidth(0), tabWidth(0), ncols(0), - collapsibleSeparators(true), hasHadMouse(0), aboutToHide(0), motions(0), + collapsibleSeparators(true), activationRecursionGuard(false), hasHadMouse(0), aboutToHide(0), motions(0), currentAction(0), scroll(0), eventLoop(0), tearoff(0), tornoff(0), tearoffHighlighted(0), - hasCheckableItems(0), sloppyAction(0) + hasCheckableItems(0), sloppyAction(0), doChildEffects(false) #ifdef Q_WS_MAC ,mac_menu(0) #endif @@ -155,14 +155,12 @@ public: mutable uint itemsDirty : 1; mutable uint maxIconWidth, tabWidth; QRect actionRect(QAction *) const; - mutable QMap<QAction*, QRect> actionRects; - mutable QList<QAction*> actionList; - mutable QHash<QAction *, QWidget *> widgetItems; - void calcActionRects(QMap<QAction*, QRect> &actionRects, QList<QAction*> &actionList) const; - void updateActions(); + + mutable QVector<QRect> actionRects; + mutable QWidgetList widgetItems; + void updateActionRects() const; QRect popupGeometry(int screen=-1) const; - QList<QAction *> filteredActions() const; - uint ncols : 4; //4 bits is probably plenty + mutable uint ncols : 4; //4 bits is probably plenty uint collapsibleSeparators : 1; uint activationRecursionGuard : 1; @@ -234,7 +232,7 @@ public: //sloppy selection static QBasicTimer sloppyDelayTimer; - QAction *sloppyAction; + mutable QAction *sloppyAction; QRegion sloppyRegion; //default action diff --git a/src/gui/widgets/qmenubar.cpp b/src/gui/widgets/qmenubar.cpp index 34de252..e1d41de 100644 --- a/src/gui/widgets/qmenubar.cpp +++ b/src/gui/widgets/qmenubar.cpp @@ -197,17 +197,15 @@ void QMenuBarPrivate::updateGeometries() return; } #endif - calcActionRects(q_width, q_start, actionRects, actionList); - itemsWidth = q_width; - itemsStart = q_start; + calcActionRects(q_width, q_start); currentAction = 0; #ifndef QT_NO_SHORTCUT if(itemsDirty) { for(int j = 0; j < shortcutIndexMap.size(); ++j) q->releaseShortcut(shortcutIndexMap.value(j)); shortcutIndexMap.resize(0); // faster than clear - for(int i = 0; i < actionList.count(); i++) - shortcutIndexMap.append(q->grabShortcut(QKeySequence::mnemonic(actionList.at(i)->text()))); + for(int i = 0; i < actions.count(); i++) + shortcutIndexMap.append(q->grabShortcut(QKeySequence::mnemonic(actions.at(i)->text()))); } #endif itemsDirty = false; @@ -218,9 +216,9 @@ void QMenuBarPrivate::updateGeometries() //we try to see if the actions will fit there bool hasHiddenActions = false; - for (int i = 0; i < actionList.count(); ++i) { - QAction *action = actionList.at(i); - if (!menuRect.contains(actionRect(action))) { + for (int i = 0; i < actions.count(); ++i) { + const QRect &rect = actionRects.at(i); + if (!menuRect.contains(rect)) { hasHiddenActions = true; break; } @@ -229,10 +227,10 @@ void QMenuBarPrivate::updateGeometries() //...and if not, determine the ones that fit on the menu with the extension visible if (hasHiddenActions) { menuRect = this->menuRect(true); - for (int i = 0; i < actionList.count(); ++i) { - QAction *action = actionList.at(i); - if (!menuRect.contains(actionRect(action))) { - hiddenActions.append(action); + for (int i = 0; i < actions.count(); ++i) { + const QRect &rect = actionRects.at(i); + if (!menuRect.contains(rect)) { + hiddenActions.append(actions.at(i)); } } } @@ -267,12 +265,28 @@ void QMenuBarPrivate::updateGeometries() QRect QMenuBarPrivate::actionRect(QAction *act) const { Q_Q(const QMenuBar); - QRect ret = actionRects.value(act); - const int fw = q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q); - ret.translate(fw, fw); + const int index = actions.indexOf(act); + if (index == -1) + return QRect(); + + //makes sure the geometries are up-to-date + const_cast<QMenuBarPrivate*>(this)->updateGeometries(); + + QRect ret = actionRects.at(index); return QStyle::visualRect(q->layoutDirection(), q->rect(), ret); } +void QMenuBarPrivate::focusFirstAction() +{ + if(!currentAction) { + updateGeometries(); + int index = 0; + while (index < actions.count() && actionRects.at(index).isNull()) ++index; + if (index < actions.count()) + setCurrentAction(actions.at(index)); + } +} + void QMenuBarPrivate::setKeyboardMode(bool b) { Q_Q(QMenuBar); @@ -285,8 +299,7 @@ void QMenuBarPrivate::setKeyboardMode(bool b) QWidget *fw = QApplication::focusWidget(); if (fw != q) keyboardFocusWidget = fw; - if(!currentAction && !actionList.isEmpty()) - setCurrentAction(actionList.first()); + focusFirstAction(); q->setFocus(Qt::MenuBarFocusReason); } else { if(!popupState) @@ -398,25 +411,27 @@ void QMenuBarPrivate::setCurrentAction(QAction *action, bool popup, bool activat fw->setFocus(Qt::NoFocusReason); } -void QMenuBarPrivate::calcActionRects(int max_width, int start, QMap<QAction*, QRect> &actionRects, QList<QAction*> &actionList) const +void QMenuBarPrivate::calcActionRects(int max_width, int start) const { Q_Q(const QMenuBar); - if(!itemsDirty && itemsWidth == max_width && itemsStart == start) { - actionRects = actionRects; - actionList = actionList; + if(!itemsDirty) return; - } - actionRects.clear(); - actionList.clear(); - const int itemSpacing = q->style()->pixelMetric(QStyle::PM_MenuBarItemSpacing, 0, q); + + //let's reinitialize the buffer + actionRects.resize(actions.count()); + actionRects.fill(QRect()); + + const QStyle *style = q->style(); + + const int itemSpacing = style->pixelMetric(QStyle::PM_MenuBarItemSpacing, 0, q); int max_item_height = 0, separator = -1, separator_start = 0, separator_len = 0; //calculate size const QFontMetrics fm = q->fontMetrics(); - const int hmargin = q->style()->pixelMetric(QStyle::PM_MenuBarHMargin, 0, q), - vmargin = q->style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, q), - icone = q->style()->pixelMetric(QStyle::PM_SmallIconSize, 0, q); + const int hmargin = style->pixelMetric(QStyle::PM_MenuBarHMargin, 0, q), + vmargin = style->pixelMetric(QStyle::PM_MenuBarVMargin, 0, q), + icone = style->pixelMetric(QStyle::PM_SmallIconSize, 0, q); for(int i = 0; i < actions.count(); i++) { QAction *action = actions.at(i); if(!action->isVisible()) @@ -426,26 +441,21 @@ void QMenuBarPrivate::calcActionRects(int max_width, int start, QMap<QAction*, Q //calc what I think the size is.. if(action->isSeparator()) { - if (q->style()->styleHint(QStyle::SH_DrawMenuBarSeparator, 0, q)) - separator = actionRects.count(); + if (style->styleHint(QStyle::SH_DrawMenuBarSeparator, 0, q)) + separator = i; continue; //we don't really position these! } else { - QString s = action->text(); + const QString s = action->text(); if(!s.isEmpty()) { - int w = fm.width(s); - w -= s.count(QLatin1Char('&')) * fm.width(QLatin1Char('&')); - w += s.count(QLatin1String("&&")) * fm.width(QLatin1Char('&')); + const int w = fm.width(s) + - s.count(QLatin1Char('&')) * fm.width(QLatin1Char('&')) + + s.count(QLatin1String("&&")) * fm.width(QLatin1Char('&')); sz = QSize(w, fm.height()); } QIcon is = action->icon(); - if (!is.isNull()) { - QSize is_sz = QSize(icone, icone); - if (is_sz.height() > sz.height()) - sz.setHeight(is_sz.height()); - if (is_sz.width() > sz.width()) - sz.setWidth(is_sz.width()); - } + if (!is.isNull()) + sz = sz.expandedTo(QSize(icone, icone)); } //let the style modify the above size.. @@ -455,8 +465,7 @@ void QMenuBarPrivate::calcActionRects(int max_width, int start, QMap<QAction*, Q if(!sz.isEmpty()) { { //update the separator state - int iWidth = sz.width(); - iWidth += itemSpacing; + int iWidth = sz.width() + itemSpacing; if(separator == -1) separator_start += iWidth; else @@ -465,17 +474,19 @@ void QMenuBarPrivate::calcActionRects(int max_width, int start, QMap<QAction*, Q //maximum height max_item_height = qMax(max_item_height, sz.height()); //append - actionRects.insert(action, QRect(0, 0, sz.width(), sz.height())); - actionList.append(action); + actionRects[i] = QRect(0, 0, sz.width(), sz.height()); } } //calculate position - int x = ((start == -1) ? hmargin : start) + itemSpacing; - int y = vmargin; - for(int i = 0; i < actionList.count(); i++) { - QAction *action = actionList.at(i); - QRect &rect = actionRects[action]; + const int fw = q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q); + int x = fw + ((start == -1) ? hmargin : start) + itemSpacing; + int y = fw + vmargin; + for(int i = 0; i < actions.count(); i++) { + QRect &rect = actionRects[i]; + if (rect.isNull()) + continue; + //resize rect.setHeight(max_item_height); @@ -659,8 +670,9 @@ void QMenuBar::initStyleOption(QStyleOptionMenuItem *option, const QAction *acti \header \i String matches \i Placement \i Notes \row \i about.* \i Application Menu | About <application name> - \i If this entry is not found no About item will appear in - the Application Menu + \i The application name is fetched from the \c {Info.plist} file + (see note below). If this entry is not found no About item + will appear in the Application Menu. \row \i config, options, setup, settings or preferences \i Application Menu | Preferences \i If this entry is not found the Settings item will be disabled @@ -743,6 +755,28 @@ void QMenuBarPrivate::init() extension->hide(); } +//Gets the next action for keyboard navigation +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; + + for (int i = start; start != end;) { + i += increment; + QAction *current = actions.at(i); + if (!actionRects.at(i).isNull() && (allowActiveAndDisabled || current->isEnabled())) + return current; + } + + if (_start != -1) //let's try from the beginning or the end + return getNextAction(-1, increment); + + return 0; +} + /*! Constructs a menu bar with parent \a parent. */ @@ -975,8 +1009,8 @@ void QMenuBar::paintEvent(QPaintEvent *e) QRegion emptyArea(rect()); //draw the items - for (int i = 0; i < d->actionList.count(); ++i) { - QAction *action = d->actionList.at(i); + for (int i = 0; i < d->actions.count(); ++i) { + QAction *action = d->actions.at(i); QRect adjustedActionRect = d->actionRect(action); if (adjustedActionRect.isEmpty() || !d->isVisible(action)) continue; @@ -1092,6 +1126,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) @@ -1126,54 +1161,8 @@ void QMenuBar::keyPressEvent(QKeyEvent *e) case Qt::Key_Right: case Qt::Key_Left: { if(d->currentAction) { - QAction *nextAction = 0; - bool allowActiveAndDisabled = - style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, this); - - for(int i=0; i<(int)d->actionList.count(); i++) { - if(d->actionList.at(i) == (QAction*)d->currentAction) { - if (key == Qt::Key_Left) { - while (i > 0) { - i--; - if (allowActiveAndDisabled || d->actionList[i]->isEnabled()) { - nextAction = d->actionList.at(i); - break; - } - } - } else { - while (i < d->actionList.count()-1) { - i++; - if (allowActiveAndDisabled || d->actionList[i]->isEnabled()) { - nextAction = d->actionList.at(i); - break; - } - } - } - break; - - } - } - - if(!nextAction) { - if (key == Qt::Key_Left) { - for (int i = d->actionList.size() - 1 ; i >= 0 ; --i) { - if (allowActiveAndDisabled || d->actionList[i]->isEnabled()) { - nextAction = d->actionList.at(i); - i--; - break; - } - } - } else { - for (int i = 0 ; i < d->actionList.count() ; ++i) { - if (allowActiveAndDisabled || d->actionList[i]->isEnabled()) { - nextAction = d->actionList.at(i); - i++; - break; - } - } - } - } - if(nextAction) { + int index = d->actions.indexOf(d->currentAction); + if (QAction *nextAction = d->getNextAction(index, key == Qt::Key_Left ? -1 : +1)) { d->setCurrentAction(nextAction, d->popupState, true); key_consumed = true; } @@ -1197,8 +1186,10 @@ void QMenuBar::keyPressEvent(QKeyEvent *e) QAction *first = 0, *currentSelected = 0, *firstAfterCurrent = 0; { QChar c = e->text()[0].toUpper(); - for(int i = 0; i < d->actionList.size(); ++i) { - register QAction *act = d->actionList.at(i); + for(int i = 0; i < d->actions.size(); ++i) { + if (d->actionRects.at(i).isNull()) + continue; + QAction *act = d->actions.at(i); QString s = act->text(); if(!s.isEmpty()) { int ampersand = s.indexOf(QLatin1Char('&')); @@ -1300,8 +1291,8 @@ void QMenuBar::actionEvent(QActionEvent *e) void QMenuBar::focusInEvent(QFocusEvent *) { Q_D(QMenuBar); - if(d->keyboardState && !d->currentAction && !d->actionList.isEmpty()) - d->setCurrentAction(d->actionList.first()); + if(d->keyboardState) + d->focusFirstAction(); } /*! @@ -1610,20 +1601,18 @@ 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); int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, 0, this); if(as_gui_menubar) { - QMap<QAction*, QRect> actionRects; - QList<QAction*> actionList; int w = parentWidget() ? parentWidget()->width() : QApplication::desktop()->width(); - d->calcActionRects(w - (2 * fw), 0, actionRects, actionList); - if (d->actionList.count() > 0) { - ret = d->actionRect(d->actionList.at(0)).size(); - if (!d->extension->isHidden()) - ret += QSize(d->extension->sizeHint().width(), 0); - } + d->calcActionRects(w - (2 * fw), 0); + for (int i = 0; ret.isNull() && i < d->actions.count(); ++i) + ret = d->actionRects.at(i).size(); + if (!d->extension->isHidden()) + ret += QSize(d->extension->sizeHint().width(), 0); ret += QSize(2*fw + hmargin, 2*fw + vmargin); } int margin = 2*vmargin + 2*fw + spaceBelowMenuBar; @@ -1674,19 +1663,15 @@ QSize QMenuBar::sizeHint() const int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, this); int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, 0, this); if(as_gui_menubar) { - QMap<QAction*, QRect> actionRects; - QList<QAction*> actionList; const int w = parentWidget() ? parentWidget()->width() : QApplication::desktop()->width(); - d->calcActionRects(w - (2 * fw), 0, actionRects, actionList); - for (QMap<QAction*, QRect>::const_iterator i = actionRects.constBegin(); - i != actionRects.constEnd(); ++i) { - QRect actionRect(i.value()); - if(actionRect.x() + actionRect.width() > ret.width()) - ret.setWidth(actionRect.x() + actionRect.width()); - if(actionRect.y() + actionRect.height() > ret.height()) - ret.setHeight(actionRect.y() + actionRect.height()); + d->calcActionRects(w - (2 * fw), 0); + for (int i = 0; i < d->actionRects.count(); ++i) { + const QRect &actionRect = d->actionRects.at(i); + ret = ret.expandedTo(QSize(actionRect.x() + actionRect.width(), actionRect.y() + actionRect.height())); } - ret += QSize(2*fw + 2*hmargin, 2*fw + 2*vmargin); + //the action geometries already contain the top and left + //margins. So we only need to add those from right and bottom. + ret += QSize(fw + hmargin, fw + vmargin); } int margin = 2*vmargin + 2*fw + spaceBelowMenuBar; if(d->leftWidget) { @@ -1733,11 +1718,10 @@ int QMenuBar::heightForWidth(int) const int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, this); int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, 0, this); if(as_gui_menubar) { - if (d->actionList.count()) { - // assume all actionrects have the same height - height = d->actionRect(d->actionList.first()).height(); + for (int i = 0; i < d->actionRects.count(); ++i) + height = qMax(height, d->actionRects.at(i).height()); + if (height) //there is at least one non-null item height += spaceBelowMenuBar; - } height += 2*fw; height += 2*vmargin; } @@ -1764,7 +1748,7 @@ int QMenuBar::heightForWidth(int) const void QMenuBarPrivate::_q_internalShortcutActivated(int id) { Q_Q(QMenuBar); - QAction *act = actionList.at(id); + QAction *act = actions.at(id); setCurrentAction(act, true, true); if (act && !act->menu()) { activateAction(act, QAction::Trigger); diff --git a/src/gui/widgets/qmenubar_p.h b/src/gui/widgets/qmenubar_p.h index 0a4fbfe..b890b7b 100644 --- a/src/gui/widgets/qmenubar_p.h +++ b/src/gui/widgets/qmenubar_p.h @@ -69,9 +69,12 @@ class QMenuBarPrivate : public QWidgetPrivate { Q_DECLARE_PUBLIC(QMenuBar) public: - QMenuBarPrivate() : itemsDirty(0), itemsWidth(0), itemsStart(-1), currentAction(0), mouseDown(0), + QMenuBarPrivate() : itemsDirty(0), currentAction(0), mouseDown(0), closePopupMode(0), defaultPopDown(1), popupState(0), keyboardState(0), altPressed(0), - nativeMenuBar(-1) + nativeMenuBar(-1), doChildEffects(false) +#ifdef QT3_SUPPORT + , doAutoResize(false) +#endif #ifdef Q_WS_MAC , mac_menubar(0) #endif @@ -91,16 +94,14 @@ public: } void init(); - QStyleOptionMenuItem getStyleOption(const QAction *action) const; + QAction *getNextAction(const int start, const int increment) const; //item calculations uint itemsDirty : 1; - int itemsWidth, itemsStart; QVector<int> shortcutIndexMap; - mutable QMap<QAction*, QRect> actionRects; - mutable QList<QAction*> actionList; - void calcActionRects(int max_width, int start, QMap<QAction*, QRect> &actionRects, QList<QAction*> &actionList) const; + mutable QVector<QRect> actionRects; + void calcActionRects(int max_width, int start) const; QRect actionRect(QAction *) const; void updateGeometries(); @@ -116,6 +117,7 @@ public: QPointer<QMenu> activeMenu; //keyboard mode for keyboard navigation + void focusFirstAction(); void setKeyboardMode(bool); uint keyboardState : 1, altPressed : 1; QPointer<QWidget> keyboardFocusWidget; diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp index 4977b31..bab6b89 100644 --- a/src/gui/widgets/qplaintextedit.cpp +++ b/src/gui/widgets/qplaintextedit.cpp @@ -1014,14 +1014,13 @@ void QPlainTextEditPrivate::ensureViewportLayouted() QPlainText uses very much the same technology and concepts as QTextEdit, but is optimized for plain text handling. - QPlainTextEdit works on paragraphs and characters. A paragraph is a - formatted string which is word-wrapped to fit into the width of + QPlainTextEdit works on paragraphs and characters. A paragraph is + a formatted string which is word-wrapped to fit into the width of the widget. By default when reading plain text, one newline signifies a paragraph. A document consists of zero or more - paragraphs. The words in the paragraph are aligned in accordance - with the paragraph's alignment. Paragraphs are separated by hard - line breaks. Each character within a paragraph has its own - attributes, for example, font and color. + paragraphs. Paragraphs are separated by hard line breaks. Each + character within a paragraph has its own attributes, for example, + font and color. The shape of the mouse cursor on a QPlainTextEdit is Qt::IBeamCursor by default. It can be changed through the @@ -1162,7 +1161,8 @@ void QPlainTextEditPrivate::ensureViewportLayouted() \sa QTextDocument, QTextCursor, {Application Example}, - {Syntax Highlighter Example}, {Rich Text Processing} + {Code Editor Example}, {Syntax Highlighter Example}, + {Rich Text Processing} */ diff --git a/src/gui/widgets/qpushbutton.cpp b/src/gui/widgets/qpushbutton.cpp index 7da5930..a1c0d74 100644 --- a/src/gui/widgets/qpushbutton.cpp +++ b/src/gui/widgets/qpushbutton.cpp @@ -387,8 +387,9 @@ bool QPushButton::isDefault() const QSize QPushButton::sizeHint() const { Q_D(const QPushButton); - if (d->sizeHint.isValid()) + if (d->sizeHint.isValid() && d->lastAutoDefault == autoDefault()) return d->sizeHint; + d->lastAutoDefault = autoDefault(); ensurePolished(); int w = 0, h = 0; @@ -657,6 +658,8 @@ bool QPushButton::event(QEvent *e) ) { d->resetLayoutItemMargins(); updateGeometry(); + } else if (e->type() == QEvent::PolishRequest) { + updateGeometry(); } return QAbstractButton::event(e); } diff --git a/src/gui/widgets/qpushbutton_p.h b/src/gui/widgets/qpushbutton_p.h index 0c5ac79..9d682d8 100644 --- a/src/gui/widgets/qpushbutton_p.h +++ b/src/gui/widgets/qpushbutton_p.h @@ -65,7 +65,7 @@ public: QPushButtonPrivate() : QAbstractButtonPrivate(QSizePolicy::PushButton), autoDefault(Auto), - defaultButton(false), flat(false), menuOpen(false) {} + defaultButton(false), flat(false), menuOpen(false), lastAutoDefault(false) {} inline void init() { resetLayoutItemMargins(); } void resetLayoutItemMargins(); @@ -77,6 +77,7 @@ public: uint defaultButton : 1; uint flat : 1; uint menuOpen : 1; + mutable uint lastAutoDefault : 1; }; QT_END_NAMESPACE 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 1c2ae0d..e069a21 100644 --- a/src/gui/widgets/qspinbox.cpp +++ b/src/gui/widgets/qspinbox.cpp @@ -284,6 +284,9 @@ void QSpinBox::setPrefix(const QString &prefix) d->prefix = prefix; d->updateEdit(); + + d->cachedSizeHint = QSize(); + updateGeometry(); } /*! @@ -318,6 +321,9 @@ void QSpinBox::setSuffix(const QString &suffix) d->suffix = suffix; d->updateEdit(); + + d->cachedSizeHint = QSize(); + updateGeometry(); } /*! diff --git a/src/gui/widgets/qtoolbar.cpp b/src/gui/widgets/qtoolbar.cpp index b635628..3414b4f 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); @@ -1086,6 +1080,16 @@ 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; @@ -1183,11 +1187,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 +1201,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 8a10355..0c11700 100644 --- a/src/gui/widgets/qtoolbararealayout.cpp +++ b/src/gui/widgets/qtoolbararealayout.cpp @@ -526,9 +526,10 @@ QList<int> QToolBarAreaLayoutInfo::gapIndex(const QPoint &pos) const return QList<int>(); } -bool QToolBarAreaLayoutInfo::insertGap(QList<int> path, QLayoutItem *item) +bool QToolBarAreaLayoutInfo::insertGap(const QList<int> &path, QLayoutItem *item) { - int j = path.at(0); + Q_ASSERT(path.count() == 2); + int j = path.first(); if (j == lines.count()) lines.append(QToolBarAreaLayoutLine(o)); @@ -570,8 +571,9 @@ void QToolBarAreaLayoutInfo::clear() rect = QRect(); } -QRect QToolBarAreaLayoutInfo::itemRect(QList<int> path) const +QRect QToolBarAreaLayoutInfo::itemRect(const QList<int> &path) const { + Q_ASSERT(path.count() == 2); int j = path.at(0); int k = path.at(1); @@ -623,10 +625,8 @@ QRect QToolBarAreaLayoutInfo::appendLineDropRect() const ** QToolBarAreaLayout */ -QToolBarAreaLayout::QToolBarAreaLayout(QMainWindow *win) +QToolBarAreaLayout::QToolBarAreaLayout(const QMainWindow *win) : mainWindow(win), visible(true) { - visible = true; - mainWindow = win; for (int i = 0; i < QInternal::DockCount; ++i) { QInternal::DockPosition pos = static_cast<QInternal::DockPosition>(i); docks[i] = QToolBarAreaLayoutInfo(pos); @@ -932,7 +932,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); } } } @@ -1064,16 +1064,17 @@ QList<int> QToolBarAreaLayout::currentGapIndex() const return QList<int>(); } -bool QToolBarAreaLayout::insertGap(QList<int> path, QLayoutItem *item) +bool QToolBarAreaLayout::insertGap(const QList<int> &path, QLayoutItem *item) { - Q_ASSERT(!path.isEmpty()); - int i = path.takeFirst(); + Q_ASSERT(path.count() == 3); + const int i = path.first(); Q_ASSERT(i >= 0 && i < QInternal::DockCount); - return docks[i].insertGap(path, item); + return docks[i].insertGap(path.mid(1), item); } -void QToolBarAreaLayout::remove(QList<int> path) +void QToolBarAreaLayout::remove(const QList<int> &path) { + Q_ASSERT(path.count() == 3); docks[path.at(0)].lines[path.at(1)].toolBarItems.removeAt(path.at(2)); } @@ -1104,7 +1105,7 @@ void QToolBarAreaLayout::clear() rect = QRect(); } -QToolBarAreaLayoutItem &QToolBarAreaLayout::item(QList<int> path) +QToolBarAreaLayoutItem &QToolBarAreaLayout::item(const QList<int> &path) { Q_ASSERT(path.count() == 3); @@ -1116,18 +1117,18 @@ QToolBarAreaLayoutItem &QToolBarAreaLayout::item(QList<int> path) return line.toolBarItems[path.at(2)]; } -QRect QToolBarAreaLayout::itemRect(QList<int> path) const +QRect QToolBarAreaLayout::itemRect(const QList<int> &path) const { - int i = path.takeFirst(); + const int i = path.first(); - QRect r = docks[i].itemRect(path); + QRect r = docks[i].itemRect(path.mid(1)); if (docks[i].o == Qt::Horizontal) r = QStyle::visualRect(mainWindow->layoutDirection(), docks[i].rect, r); return r; } -QLayoutItem *QToolBarAreaLayout::plug(QList<int> path) +QLayoutItem *QToolBarAreaLayout::plug(const QList<int> &path) { QToolBarAreaLayoutItem &item = this->item(path); Q_ASSERT(item.gap); @@ -1136,9 +1137,10 @@ QLayoutItem *QToolBarAreaLayout::plug(QList<int> path) return item.widgetItem; } -QLayoutItem *QToolBarAreaLayout::unplug(QList<int> path, QToolBarAreaLayout *other) +QLayoutItem *QToolBarAreaLayout::unplug(const QList<int> &path, QToolBarAreaLayout *other) { //other needs to be update as well + Q_ASSERT(path.count() == 3); QToolBarAreaLayoutItem &item = this->item(path); //update the leading space here diff --git a/src/gui/widgets/qtoolbararealayout_p.h b/src/gui/widgets/qtoolbararealayout_p.h index a44fbc7..636c9ca 100644 --- a/src/gui/widgets/qtoolbararealayout_p.h +++ b/src/gui/widgets/qtoolbararealayout_p.h @@ -174,9 +174,9 @@ public: void moveToolBar(QToolBar *toolbar, int pos); QList<int> gapIndex(const QPoint &pos) const; - bool insertGap(QList<int> path, QLayoutItem *item); + bool insertGap(const QList<int> &path, QLayoutItem *item); void clear(); - QRect itemRect(QList<int> path) const; + QRect itemRect(const QList<int> &path) const; QRect appendLineDropRect() const; QRect rect; @@ -194,11 +194,11 @@ public: }; QRect rect; - QMainWindow *mainWindow; + const QMainWindow *mainWindow; QToolBarAreaLayoutInfo docks[4]; bool visible; - QToolBarAreaLayout(QMainWindow *win); + QToolBarAreaLayout(const QMainWindow *win); QRect fitLayout(); @@ -230,14 +230,14 @@ public: QList<int> indexOf(QWidget *toolBar) const; QList<int> gapIndex(const QPoint &pos) const; QList<int> currentGapIndex() 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(); - QToolBarAreaLayoutItem &item(QList<int> path); - QRect itemRect(QList<int> path) const; - QLayoutItem *plug(QList<int> path); - QLayoutItem *unplug(QList<int> path, QToolBarAreaLayout *other); + QToolBarAreaLayoutItem &item(const QList<int> &path); + QRect itemRect(const QList<int> &path) const; + QLayoutItem *plug(const QList<int> &path); + QLayoutItem *unplug(const QList<int> &path, QToolBarAreaLayout *other); void saveState(QDataStream &stream) const; bool restoreState(QDataStream &stream, const QList<QToolBar*> &toolBars, uchar tmarker, bool pre43, bool testing = false); diff --git a/src/gui/widgets/qwidgetanimator.cpp b/src/gui/widgets/qwidgetanimator.cpp index c67be4a..56b3f43 100644 --- a/src/gui/widgets/qwidgetanimator.cpp +++ b/src/gui/widgets/qwidgetanimator.cpp @@ -39,12 +39,8 @@ ** ****************************************************************************/ -#include <QtCore/qtimer.h> -#include <QtCore/qdatetime.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" @@ -75,18 +71,12 @@ static inline int animateHelper(int start, int stop, int step, int steps) 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() { - delete m_time; } void QWidgetAnimator::abort(QWidget *w) @@ -94,8 +84,8 @@ void QWidgetAnimator::abort(QWidget *w) if (m_animation_map.remove(w) == 0) return; if (m_animation_map.isEmpty()) { - m_timer->stop(); - emit finishedAll(); + m_timer.stop(); + m_mainWindowLayout->allAnimationsFinished(); } } @@ -107,32 +97,21 @@ void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, boo if (r.right() < 0 || r.bottom() < 0) r = QRect(); - if (r.isNull() || final_geometry.isNull()) + if (r.isNull() || final_geometry.isNull() || r == final_geometry) animate = false; 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 (it != m_animation_map.constEnd() && (*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(); + if (!m_timer.isActive()) { + m_timer.start(g_animation_interval, this); + 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(); @@ -140,18 +119,19 @@ void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, boo } widget->setGeometry(final_geometry); - emit finished(widget); - - if (m_animation_map.isEmpty()) - emit finishedAll(); - - return; + if (m_animation_map.remove(widget)) { + m_mainWindowLayout->animationFinished(widget); + if (m_animation_map.isEmpty()) { + m_timer.stop(); + m_mainWindowLayout->allAnimationsFinished(); + } + } } } -void QWidgetAnimator::animationStep() +void QWidgetAnimator::timerEvent(QTimerEvent *) { - int steps = (1 + m_time->restart())/g_animation_interval; + 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; @@ -159,35 +139,34 @@ void QWidgetAnimator::animationStep() item.step = qMin(item.step + steps, g_animation_steps); int x = animateHelper(item.r1.left(), item.r2.left(), - item.step, g_animation_steps); + item.step, g_animation_steps); int y = animateHelper(item.r1.top(), item.r2.top(), - item.step, g_animation_steps); + item.step, g_animation_steps); int w = animateHelper(item.r1.width(), item.r2.width(), - item.step, g_animation_steps); + item.step, g_animation_steps); int h = animateHelper(item.r1.height(), item.r2.height(), - item.step, g_animation_steps); + 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); + QWidget *widget = item.widget; + it = m_animation_map.erase(it); + m_mainWindowLayout->animationFinished(widget); } else { ++it; } } if (m_animation_map.isEmpty()) { - m_timer->stop(); - emit finishedAll(); + m_timer.stop(); + m_mainWindowLayout->allAnimationsFinished(); } } bool QWidgetAnimator::animating() const { - return m_timer->isActive(); + return m_timer.isActive(); } bool QWidgetAnimator::animating(QWidget *widget) diff --git a/src/gui/widgets/qwidgetanimator_p.h b/src/gui/widgets/qwidgetanimator_p.h index 6ee150b..0c68e00 100644 --- a/src/gui/widgets/qwidgetanimator_p.h +++ b/src/gui/widgets/qwidgetanimator_p.h @@ -56,18 +56,18 @@ #include <qobject.h> #include <qrect.h> #include <qmap.h> +#include <qbasictimer.h> +#include <qdatetime.h> QT_BEGIN_NAMESPACE class QWidget; -class QTimer; -class QTime; +class QMainWindowLayout; class QWidgetAnimator : public QObject { - Q_OBJECT public: - QWidgetAnimator(QObject *parent = 0); + QWidgetAnimator(QMainWindowLayout *layout); ~QWidgetAnimator(); void animate(QWidget *widget, const QRect &final_geometry, bool animate); bool animating() const; @@ -75,12 +75,8 @@ public: void abort(QWidget *widget); -signals: - void finished(QWidget *widget); - void finishedAll(); - -private slots: - void animationStep(); +protected: + void timerEvent(QTimerEvent *e); private: struct AnimationItem { @@ -93,8 +89,9 @@ private: }; typedef QMap<QWidget*, AnimationItem> AnimationMap; AnimationMap m_animation_map; - QTimer *m_timer; - QTime *m_time; + QBasicTimer 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 diff --git a/src/gui/widgets/widgets.pri b/src/gui/widgets/widgets.pri index 86dc453..2d809a1 100644 --- a/src/gui/widgets/widgets.pri +++ b/src/gui/widgets/widgets.pri @@ -37,7 +37,9 @@ HEADERS += \ widgets/qmdisubwindow.h \ widgets/qmdisubwindow_p.h \ widgets/qmenu.h \ + widgets/qmenu_p.h \ widgets/qmenubar.h \ + widgets/qmenubar_p.h \ widgets/qmenudata.h \ widgets/qprogressbar.h \ widgets/qpushbutton.h \ |