summaryrefslogtreecommitdiffstats
path: root/src/gui/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/widgets')
-rw-r--r--src/gui/widgets/qabstractscrollarea.cpp35
-rw-r--r--src/gui/widgets/qabstractscrollarea_p.h9
-rw-r--r--src/gui/widgets/qabstractspinbox.cpp15
-rw-r--r--src/gui/widgets/qabstractspinbox_p.h2
-rw-r--r--src/gui/widgets/qcheckbox.cpp129
-rw-r--r--src/gui/widgets/qcocoamenu_mac_p.h17
-rw-r--r--src/gui/widgets/qcombobox.cpp9
-rw-r--r--src/gui/widgets/qdockarealayout.cpp141
-rw-r--r--src/gui/widgets/qdockarealayout_p.h38
-rw-r--r--src/gui/widgets/qdockwidget.cpp6
-rw-r--r--src/gui/widgets/qeffects.cpp96
-rw-r--r--src/gui/widgets/qfontcombobox.cpp2
-rw-r--r--src/gui/widgets/qframe.cpp2
-rw-r--r--src/gui/widgets/qgroupbox.cpp11
-rw-r--r--src/gui/widgets/qlineedit.cpp14
-rw-r--r--src/gui/widgets/qlineedit.h1
-rw-r--r--src/gui/widgets/qlineedit_p.h1
-rw-r--r--src/gui/widgets/qmainwindow.cpp20
-rw-r--r--src/gui/widgets/qmainwindowlayout.cpp276
-rw-r--r--src/gui/widgets/qmainwindowlayout_mac.mm47
-rw-r--r--src/gui/widgets/qmainwindowlayout_p.h25
-rw-r--r--src/gui/widgets/qmdisubwindow.cpp35
-rw-r--r--src/gui/widgets/qmenu.cpp511
-rw-r--r--src/gui/widgets/qmenu_mac.mm2
-rw-r--r--src/gui/widgets/qmenu_p.h26
-rw-r--r--src/gui/widgets/qmenubar.cpp251
-rw-r--r--src/gui/widgets/qmenubar_p.h16
-rw-r--r--src/gui/widgets/qplaintextedit.cpp51
-rw-r--r--src/gui/widgets/qplaintextedit.h1
-rw-r--r--src/gui/widgets/qplaintextedit_p.h5
-rw-r--r--src/gui/widgets/qprogressbar.cpp2
-rw-r--r--src/gui/widgets/qpushbutton.cpp5
-rw-r--r--src/gui/widgets/qpushbutton_p.h3
-rw-r--r--src/gui/widgets/qsizegrip.cpp3
-rw-r--r--src/gui/widgets/qspinbox.cpp13
-rw-r--r--src/gui/widgets/qtabbar.cpp66
-rw-r--r--src/gui/widgets/qtabbar.h2
-rw-r--r--src/gui/widgets/qtabbar_p.h68
-rw-r--r--src/gui/widgets/qtextedit.cpp26
-rw-r--r--src/gui/widgets/qtextedit.h1
-rw-r--r--src/gui/widgets/qtextedit_p.h5
-rw-r--r--src/gui/widgets/qtoolbar.cpp69
-rw-r--r--src/gui/widgets/qtoolbar.h1
-rw-r--r--src/gui/widgets/qtoolbar_p.h8
-rw-r--r--src/gui/widgets/qtoolbararealayout.cpp54
-rw-r--r--src/gui/widgets/qtoolbararealayout_p.h20
-rw-r--r--src/gui/widgets/qwidgetanimator.cpp164
-rw-r--r--src/gui/widgets/qwidgetanimator_p.h34
-rw-r--r--src/gui/widgets/qworkspace.cpp26
-rw-r--r--src/gui/widgets/widgets.pri2
50 files changed, 1200 insertions, 1166 deletions
diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/gui/widgets/qabstractscrollarea.cpp
index 00be29b..e78f5a7 100644
--- a/src/gui/widgets/qabstractscrollarea.cpp
+++ b/src/gui/widgets/qabstractscrollarea.cpp
@@ -51,10 +51,13 @@
#include "qdebug.h"
#include "qboxlayout.h"
#include "qpainter.h"
+#include "qstandardgestures.h"
#include "qabstractscrollarea_p.h"
#include <qwidget.h>
+#include <private/qapplication_p.h>
+
#ifdef Q_WS_MAC
#include <private/qt_mac_p.h>
#include <private/qt_cocoa_helpers_mac_p.h>
@@ -157,6 +160,9 @@ QAbstractScrollAreaPrivate::QAbstractScrollAreaPrivate()
:hbar(0), vbar(0), vbarpolicy(Qt::ScrollBarAsNeeded), hbarpolicy(Qt::ScrollBarAsNeeded),
viewport(0), cornerWidget(0), left(0), top(0), right(0), bottom(0),
xoffset(0), yoffset(0), viewportFilter(0)
+#ifdef Q_WS_WIN
+ , singleFingerPanEnabled(false)
+#endif
{
}
@@ -290,6 +296,31 @@ void QAbstractScrollAreaPrivate::init()
layoutChildren();
}
+void QAbstractScrollAreaPrivate::setupGestures()
+{
+#ifdef Q_OS_WIN
+ if (!viewport)
+ return;
+ QApplicationPrivate *qAppPriv = getQApplicationPrivateInternal();
+ bool needh = (hbarpolicy == Qt::ScrollBarAlwaysOn
+ || (hbarpolicy == Qt::ScrollBarAsNeeded && hbar->minimum() < hbar->maximum()));
+
+ bool needv = (vbarpolicy == Qt::ScrollBarAlwaysOn
+ || (vbarpolicy == Qt::ScrollBarAsNeeded && vbar->minimum() < vbar->maximum()));
+ if (qAppPriv->SetGestureConfig && (needh || needv)) {
+ GESTURECONFIG gc[1];
+ gc[0].dwID = GID_PAN;
+ gc[0].dwWant = GC_PAN;
+ gc[0].dwBlock = 0;
+ if (needv && singleFingerPanEnabled)
+ gc[0].dwWant |= GC_PAN_WITH_SINGLE_FINGER_VERTICALLY;
+ if (needh && singleFingerPanEnabled)
+ gc[0].dwWant |= GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY;
+ qAppPriv->SetGestureConfig(viewport->winId(), 0, 1, gc, sizeof(gc));
+ }
+#endif // Q_OS_WIN
+}
+
void QAbstractScrollAreaPrivate::layoutChildren()
{
Q_Q(QAbstractScrollArea);
@@ -459,9 +490,6 @@ void QAbstractScrollAreaPrivate::layoutChildren()
viewport->setGeometry(QStyle::visualRect(opt.direction, opt.rect, viewportRect)); // resize the viewport last
}
-// ### Fix for 4.4, talk to Bjoern E or Girish.
-void QAbstractScrollAreaPrivate::scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy) {}
-
/*!
\internal
@@ -1238,6 +1266,7 @@ void QAbstractScrollAreaPrivate::_q_vslide(int y)
void QAbstractScrollAreaPrivate::_q_showOrHideScrollBars()
{
layoutChildren();
+ setupGestures();
}
QPoint QAbstractScrollAreaPrivate::contentsOffset() const
diff --git a/src/gui/widgets/qabstractscrollarea_p.h b/src/gui/widgets/qabstractscrollarea_p.h
index 71a83cc..aef8ac5 100644
--- a/src/gui/widgets/qabstractscrollarea_p.h
+++ b/src/gui/widgets/qabstractscrollarea_p.h
@@ -62,7 +62,7 @@ QT_BEGIN_NAMESPACE
class QScrollBar;
class QAbstractScrollAreaScrollBarContainer;
-class QAbstractScrollAreaPrivate: public QFramePrivate
+class Q_AUTOTEST_EXPORT QAbstractScrollAreaPrivate: public QFramePrivate
{
Q_DECLARE_PUBLIC(QAbstractScrollArea)
@@ -88,7 +88,7 @@ public:
void init();
void layoutChildren();
// ### Fix for 4.4, talk to Bjoern E or Girish.
- virtual void scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy);
+ virtual void scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy) {}
void _q_hslide(int);
void _q_vslide(int);
@@ -99,6 +99,11 @@ public:
inline bool viewportEvent(QEvent *event)
{ return q_func()->viewportEvent(event); }
QObject *viewportFilter;
+
+#ifdef Q_WS_WIN
+ bool singleFingerPanEnabled;
+#endif
+ void setupGestures();
};
class QAbstractScrollAreaFilter : public QObject
diff --git a/src/gui/widgets/qabstractspinbox.cpp b/src/gui/widgets/qabstractspinbox.cpp
index e7f7c78..433406c 100644
--- a/src/gui/widgets/qabstractspinbox.cpp
+++ b/src/gui/widgets/qabstractspinbox.cpp
@@ -57,6 +57,9 @@
#include <qpalette.h>
#include <qstylepainter.h>
#include <qdebug.h>
+#ifndef QT_NO_ACCESSIBILITY
+# include <qaccessible.h>
+#endif
#if defined(Q_WS_X11)
#include <limits.h>
@@ -951,6 +954,9 @@ void QAbstractSpinBox::keyPressEvent(QKeyEvent *event)
d->buttonState = (Keyboard | (up ? Up : Down));
}
stepBy(steps);
+#ifndef QT_NO_ACCESSIBILITY
+ QAccessible::updateAccessibility(this, 0, QAccessible::ValueChanged);
+#endif
return;
}
#ifdef QT_KEYPAD_NAVIGATION
@@ -1548,6 +1554,9 @@ void QAbstractSpinBoxPrivate::updateState(bool up)
spinClickThresholdTimerId = q->startTimer(spinClickThresholdTimerInterval);
buttonState = (up ? (Mouse | Up) : (Mouse | Down));
q->stepBy(up ? 1 : -1);
+#ifndef QT_NO_ACCESSIBILITY
+ QAccessible::updateAccessibility(q, 0, QAccessible::ValueChanged);
+#endif
}
}
@@ -1568,7 +1577,7 @@ void QAbstractSpinBox::initStyleOption(QStyleOptionSpinBox *option) const
option->initFrom(this);
option->activeSubControls = QStyle::SC_None;
option->buttonSymbols = d->buttonSymbols;
- option->subControls = QStyle::SC_SpinBoxFrame;
+ option->subControls = QStyle::SC_SpinBoxFrame | QStyle::SC_SpinBoxEditField;
if (d->buttonSymbols != QAbstractSpinBox::NoButtons) {
option->subControls |= QStyle::SC_SpinBoxUp | QStyle::SC_SpinBoxDown;
if (d->buttonState & Up) {
@@ -1696,6 +1705,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 +1718,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..097f3d0 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),
@@ -149,8 +148,10 @@ QStyleOptionMenuItem QComboMenuDelegate::getStyleOption(const QStyleOptionViewIt
menuOption.rect = option.rect;
// Make sure fonts set on the combo box also overrides the font for the popup menu.
- if (mCombo->testAttribute(Qt::WA_SetFont) || mCombo->testAttribute(Qt::WA_MacSmallSize)
- || mCombo->testAttribute(Qt::WA_MacMiniSize))
+ if (mCombo->testAttribute(Qt::WA_SetFont)
+ || mCombo->testAttribute(Qt::WA_MacSmallSize)
+ || mCombo->testAttribute(Qt::WA_MacMiniSize)
+ || mCombo->font() != qt_app_fonts_hash()->value("QComboBox", QFont()))
menuOption.font = mCombo->font();
else
menuOption.font = qt_app_fonts_hash()->value("QComboMenuItem", mCombo->font());
diff --git a/src/gui/widgets/qdockarealayout.cpp b/src/gui/widgets/qdockarealayout.cpp
index cbfa5bf..ee29b55 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
@@ -994,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();
@@ -1010,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];
@@ -1059,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);
@@ -1142,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;
@@ -1155,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
@@ -1194,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
@@ -1295,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
@@ -1335,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
@@ -1367,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
@@ -1488,7 +1488,7 @@ bool QDockAreaLayoutInfo::hasFixedSize() const
void QDockAreaLayoutInfo::apply(bool animate)
{
- QWidgetAnimator *widgetAnimator = mainWindowLayout()->widgetAnimator;
+ QWidgetAnimator &widgetAnimator = mainWindowLayout()->widgetAnimator;
#ifndef QT_NO_TABBAR
if (tabbed) {
@@ -1521,7 +1521,7 @@ void QDockAreaLayoutInfo::apply(bool animate)
}
}
- widgetAnimator->animate(tabBar, tab_rect, animate);
+ widgetAnimator.animate(tabBar, tab_rect, animate);
}
#endif // QT_NO_TABBAR
@@ -1544,7 +1544,7 @@ void QDockAreaLayoutInfo::apply(bool animate)
QWidget *w = item.widgetItem->widget();
QRect geo = w->geometry();
- widgetAnimator->animate(w, r, animate);
+ widgetAnimator.animate(w, r, animate);
if (!w->isHidden()) {
QDockWidget *dw = qobject_cast<QDockWidget*>(w);
if (!r.isValid() && geo.right() >= 0 && geo.bottom() >= 0) {
@@ -1702,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[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
@@ -2073,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);
@@ -2474,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
@@ -2528,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)); }
@@ -3063,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);
}
@@ -3111,14 +3112,12 @@ QRegion QDockAreaLayout::separatorRegion() const
return result;
}
-int QDockAreaLayout::separatorMove(QList<int> separator, const QPoint &origin,
+int QDockAreaLayout::separatorMove(const QList<int> &separator, const QPoint &origin,
const QPoint &dest)
{
int delta = 0;
int index = separator.last();
-
-
if (separator.count() > 1) {
QDockAreaLayoutInfo *info = this->info(separator);
delta = pick(info->o, dest - origin);
@@ -3255,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 771aa52..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;
@@ -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,7 +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);
+ int separatorMove(const QList<int> &separator, const QPoint &origin, const QPoint &dest);
void updateSeparatorWidgets() const;
QLayoutItem *itemAt(int *x, int index) const;
@@ -289,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..f3b1b76 100644
--- a/src/gui/widgets/qeffects.cpp
+++ b/src/gui/widgets/qeffects.cpp
@@ -126,9 +126,9 @@ QAlphaWidget::QAlphaWidget(QWidget* w, Qt::WindowFlags f)
QAlphaWidget::~QAlphaWidget()
{
-#ifdef Q_WS_WIN
+#if defined(Q_WS_WIN) && !defined(Q_WS_WINCE)
// Restore user-defined opacity value
- if (widget && QSysInfo::WindowsVersion >= QSysInfo::WV_2000 && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ if (widget)
widget->setWindowOpacity(windowOpacity);
#endif
}
@@ -160,43 +160,40 @@ void QAlphaWidget::run(int time)
checkTime.start();
showWidget = true;
-#if defined(Q_OS_WIN)
- if (QSysInfo::WindowsVersion >= QSysInfo::WV_2000 && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) {
- qApp->installEventFilter(this);
- widget->setWindowOpacity(0.0);
- widget->show();
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ qApp->installEventFilter(this);
+ widget->setWindowOpacity(0.0);
+ widget->show();
+ connect(&anim, SIGNAL(timeout()), this, SLOT(render()));
+ anim.start(1);
+#else
+ //This is roughly equivalent to calling setVisible(true) without actually showing the widget
+ widget->setAttribute(Qt::WA_WState_ExplicitShowHide, true);
+ widget->setAttribute(Qt::WA_WState_Hidden, false);
+
+ qApp->installEventFilter(this);
+
+ move(widget->geometry().x(),widget->geometry().y());
+ resize(widget->size().width(), widget->size().height());
+
+ frontImage = QPixmap::grabWidget(widget).toImage();
+ backImage = QPixmap::grabWindow(QApplication::desktop()->winId(),
+ widget->geometry().x(), widget->geometry().y(),
+ widget->geometry().width(), widget->geometry().height()).toImage();
+
+ if (!backImage.isNull() && checkTime.elapsed() < duration / 2) {
+ mixedImage = backImage.copy();
+ pm = QPixmap::fromImage(mixedImage);
+ show();
+ setEnabled(false);
+
connect(&anim, SIGNAL(timeout()), this, SLOT(render()));
anim.start(1);
- } else
-#endif
- {
- //This is roughly equivalent to calling setVisible(true) without actually showing the widget
- widget->setAttribute(Qt::WA_WState_ExplicitShowHide, true);
- widget->setAttribute(Qt::WA_WState_Hidden, false);
-
- qApp->installEventFilter(this);
-
- move(widget->geometry().x(),widget->geometry().y());
- resize(widget->size().width(), widget->size().height());
-
- frontImage = QPixmap::grabWidget(widget).toImage();
- backImage = QPixmap::grabWindow(QApplication::desktop()->winId(),
- widget->geometry().x(), widget->geometry().y(),
- widget->geometry().width(), widget->geometry().height()).toImage();
-
- if (!backImage.isNull() && checkTime.elapsed() < duration / 2) {
- mixedImage = backImage.copy();
- pm = QPixmap::fromImage(mixedImage);
- show();
- setEnabled(false);
-
- connect(&anim, SIGNAL(timeout()), this, SLOT(render()));
- anim.start(1);
- } else {
- duration = 0;
- render();
- }
+ } else {
+ duration = 0;
+ render();
}
+#endif
}
/*
@@ -270,19 +267,17 @@ void QAlphaWidget::render()
else
alpha = 1;
-#if defined(Q_OS_WIN)
- if (QSysInfo::WindowsVersion >= QSysInfo::WV_2000 && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) {
- if (alpha >= windowOpacity || !showWidget) {
- anim.stop();
- qApp->removeEventFilter(this);
- widget->setWindowOpacity(windowOpacity);
- q_blend = 0;
- deleteLater();
- } else {
- widget->setWindowOpacity(alpha);
- }
- } else
-#endif
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ if (alpha >= windowOpacity || !showWidget) {
+ anim.stop();
+ qApp->removeEventFilter(this);
+ widget->setWindowOpacity(windowOpacity);
+ q_blend = 0;
+ deleteLater();
+ } else {
+ widget->setWindowOpacity(alpha);
+ }
+#else
if (alpha >= 1 || !showWidget) {
anim.stop();
qApp->removeEventFilter(this);
@@ -292,7 +287,7 @@ void QAlphaWidget::render()
#ifdef Q_WS_WIN
setEnabled(true);
setFocus();
-#endif
+#endif // Q_WS_WIN
widget->hide();
} else {
//Since we are faking the visibility of the widget
@@ -309,6 +304,7 @@ void QAlphaWidget::render()
pm = QPixmap::fromImage(mixedImage);
repaint();
}
+#endif // defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
}
/*
diff --git a/src/gui/widgets/qfontcombobox.cpp b/src/gui/widgets/qfontcombobox.cpp
index 9660399..f87ccd3 100644
--- a/src/gui/widgets/qfontcombobox.cpp
+++ b/src/gui/widgets/qfontcombobox.cpp
@@ -263,7 +263,7 @@ void QFontComboBoxPrivate::_q_currentChanged(const QString &text)
{
Q_Q(QFontComboBox);
QFont newFont(text);
- if (currentFont != newFont) {
+ if (currentFont.family() != newFont.family()) {
currentFont = newFont;
emit q->currentFontChanged(currentFont);
}
diff --git a/src/gui/widgets/qframe.cpp b/src/gui/widgets/qframe.cpp
index b9e769d..a87ec85 100644
--- a/src/gui/widgets/qframe.cpp
+++ b/src/gui/widgets/qframe.cpp
@@ -135,7 +135,7 @@ inline void QFramePrivate::init()
\value VLine QFrame draws a vertical line that frames nothing
(useful as separator)
\value WinPanel draws a rectangular panel that can be raised or
- sunken like those in Windows 95. Specifying this shape sets
+ sunken like those in Windows 2000. Specifying this shape sets
the line width to 2 pixels. WinPanel is provided for compatibility.
For GUI style independence we recommend using StyledPanel instead.
diff --git a/src/gui/widgets/qgroupbox.cpp b/src/gui/widgets/qgroupbox.cpp
index 0bfa8c0..5758b6a 100644
--- a/src/gui/widgets/qgroupbox.cpp
+++ b/src/gui/widgets/qgroupbox.cpp
@@ -431,7 +431,7 @@ void QGroupBoxPrivate::_q_fixFocus(Qt::FocusReason reason)
{
Q_Q(QGroupBox);
QWidget *fw = q->focusWidget();
- if (!fw) {
+ if (!fw || fw == q) {
QWidget * best = 0;
QWidget * candidate = 0;
QWidget * w = q;
@@ -449,8 +449,7 @@ void QGroupBoxPrivate::_q_fixFocus(Qt::FocusReason reason)
}
if (best)
fw = best;
- else
- if (candidate)
+ else if (candidate)
fw = candidate;
}
if (fw)
@@ -479,11 +478,7 @@ void QGroupBox::focusInEvent(QFocusEvent *fe)
if (focusPolicy() == Qt::NoFocus) {
d->_q_fixFocus(fe->reason());
} else {
- QStyleOptionGroupBox box;
- initStyleOption(&box);
- QRect rect = style()->subControlRect(QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxCheckBox, this)
- | style()->subControlRect(QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxLabel, this);
- update(rect);
+ QWidget::focusInEvent(fe);
}
}
diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp
index ab2a7b7..d1067a8 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()));
}
}
@@ -2172,7 +2169,8 @@ void QLineEdit::keyPressEvent(QKeyEvent *event)
if (unknown && !d->readOnly) {
QString t = event->text();
- if (!t.isEmpty() && t.at(0).isPrint()) {
+ if (!t.isEmpty() && t.at(0).isPrint() &&
+ ((event->modifiers() & (Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier)) == Qt::NoModifier)) {
insert(t);
#ifndef QT_NO_COMPLETER
d->complete(event->key());
@@ -2689,11 +2687,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 +2747,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/qmainwindow.cpp b/src/gui/widgets/qmainwindow.cpp
index 0a0faa0..c51bed9 100644
--- a/src/gui/widgets/qmainwindow.cpp
+++ b/src/gui/widgets/qmainwindow.cpp
@@ -1369,20 +1369,25 @@ bool QMainWindow::event(QEvent *event)
#ifdef Q_WS_MAC
case QEvent::Show:
if (unifiedTitleAndToolBarOnMac())
- macWindowToolbarShow(this, true);
+ d->layout->syncUnifiedToolbarVisibility();
+ d->layout->blockVisiblityCheck = false;
break;
-# ifdef QT_MAC_USE_COCOA
case QEvent::WindowStateChange:
{
+ if (isHidden()) {
+ // We are coming out of a minimize, leave things as is.
+ d->layout->blockVisiblityCheck = true;
+ }
+# ifdef QT_MAC_USE_COCOA
// We need to update the HIToolbar status when we go out of or into fullscreen.
QWindowStateChangeEvent *wce = static_cast<QWindowStateChangeEvent *>(event);
if ((windowState() & Qt::WindowFullScreen) || (wce->oldState() & Qt::WindowFullScreen)) {
d->layout->updateHIToolBarStatus();
}
+# endif // Cocoa
}
break;
-# endif // Cocoa
-#endif
+#endif // Q_WS_MAC
#if !defined(QT_NO_DOCKWIDGET) && !defined(QT_NO_CURSOR)
case QEvent::CursorChange:
if (d->cursorAdjusted) {
@@ -1419,9 +1424,10 @@ bool QMainWindow::event(QEvent *event)
\i Toolbar breaks are not respected or preserved
\i Any custom widgets in the toolbar will not be shown if the toolbar
becomes too small (only actions will be shown)
- \i If you call showFullScreen() on the main window, the QToolbar will
- disappear since it is considered to be part of the title bar. You can
- work around this by turning off the unified toolbar before you call
+ \i Before Qt 4.5, if you called showFullScreen() on the main window, the QToolbar would
+ disappear since it is considered to be part of the title bar. Qt 4.5 and up will now work around this by pulling
+ the toolbars out and back into the regular toolbar and vice versa when you swap out.
+ However, a good practice would be that turning off the unified toolbar before you call
showFullScreen() and restoring it after you call showNormal().
\endlist
diff --git a/src/gui/widgets/qmainwindowlayout.cpp b/src/gui/widgets/qmainwindowlayout.cpp
index 526e7a5..3936a67 100644
--- a/src/gui/widgets/qmainwindowlayout.cpp
+++ b/src/gui/widgets/qmainwindowlayout.cpp
@@ -237,7 +237,7 @@ void QMainWindowLayoutState::apply(bool animated)
if (centralWidgetItem != 0) {
QMainWindowLayout *layout = qobject_cast<QMainWindowLayout*>(mainWindow->layout());
Q_ASSERT(layout != 0);
- layout->widgetAnimator->animate(centralWidgetItem->widget(), centralWidgetRect, animated);
+ layout->widgetAnimator.animate(centralWidgetItem->widget(), centralWidgetRect, animated);
}
#endif
}
@@ -426,42 +426,42 @@ QList<int> QMainWindowLayoutState::gapIndex(QWidget *widget,
return result;
}
-bool QMainWindowLayoutState::insertGap(QList<int> path, QLayoutItem *item)
+bool QMainWindowLayoutState::insertGap(const QList<int> &path, QLayoutItem *item)
{
if (path.isEmpty())
return false;
- int i = path.takeFirst();
+ int i = path.first();
#ifndef QT_NO_TOOLBAR
if (i == 0) {
Q_ASSERT(qobject_cast<QToolBar*>(item->widget()) != 0);
- return toolBarAreaLayout.insertGap(path, item);
+ return toolBarAreaLayout.insertGap(path.mid(1), item);
}
#endif
#ifndef QT_NO_DOCKWIDGET
if (i == 1) {
Q_ASSERT(qobject_cast<QDockWidget*>(item->widget()) != 0);
- return dockAreaLayout.insertGap(path, item);
+ return dockAreaLayout.insertGap(path.mid(1), item);
}
#endif //QT_NO_DOCKWIDGET
return false;
}
-void QMainWindowLayoutState::remove(QList<int> path)
+void QMainWindowLayoutState::remove(const QList<int> &path)
{
- int i = path.takeFirst();
+ int i = path.first();
#ifndef QT_NO_TOOLBAR
if (i == 0)
- toolBarAreaLayout.remove(path);
+ toolBarAreaLayout.remove(path.mid(1));
#endif
#ifndef QT_NO_DOCKWIDGET
if (i == 1)
- dockAreaLayout.remove(path);
+ dockAreaLayout.remove(path.mid(1));
#endif //QT_NO_DOCKWIDGET
}
@@ -501,88 +501,88 @@ bool QMainWindowLayoutState::isValid() const
return rect.isValid();
}
-QLayoutItem *QMainWindowLayoutState::item(QList<int> path)
+QLayoutItem *QMainWindowLayoutState::item(const QList<int> &path)
{
- int i = path.takeFirst();
+ int i = path.first();
#ifndef QT_NO_TOOLBAR
if (i == 0)
- return toolBarAreaLayout.item(path).widgetItem;
+ return toolBarAreaLayout.item(path.mid(1)).widgetItem;
#endif
#ifndef QT_NO_DOCKWIDGET
if (i == 1)
- return dockAreaLayout.item(path).widgetItem;
+ return dockAreaLayout.item(path.mid(1)).widgetItem;
#endif //QT_NO_DOCKWIDGET
return 0;
}
-QRect QMainWindowLayoutState::itemRect(QList<int> path) const
+QRect QMainWindowLayoutState::itemRect(const QList<int> &path) const
{
- int i = path.takeFirst();
+ int i = path.first();
#ifndef QT_NO_TOOLBAR
if (i == 0)
- return toolBarAreaLayout.itemRect(path);
+ return toolBarAreaLayout.itemRect(path.mid(1));
#endif
#ifndef QT_NO_DOCKWIDGET
if (i == 1)
- return dockAreaLayout.itemRect(path);
+ return dockAreaLayout.itemRect(path.mid(1));
#endif //QT_NO_DOCKWIDGET
return QRect();
}
-QRect QMainWindowLayoutState::gapRect(QList<int> path) const
+QRect QMainWindowLayoutState::gapRect(const QList<int> &path) const
{
- int i = path.takeFirst();
+ int i = path.first();
#ifndef QT_NO_TOOLBAR
if (i == 0)
- return toolBarAreaLayout.itemRect(path);
+ return toolBarAreaLayout.itemRect(path.mid(1));
#endif
#ifndef QT_NO_DOCKWIDGET
if (i == 1)
- return dockAreaLayout.gapRect(path);
+ return dockAreaLayout.gapRect(path.mid(1));
#endif //QT_NO_DOCKWIDGET
return QRect();
}
-QLayoutItem *QMainWindowLayoutState::plug(QList<int> path)
+QLayoutItem *QMainWindowLayoutState::plug(const QList<int> &path)
{
- int i = path.takeFirst();
+ int i = path.first();
#ifndef QT_NO_TOOLBAR
if (i == 0)
- return toolBarAreaLayout.plug(path);
+ return toolBarAreaLayout.plug(path.mid(1));
#endif
#ifndef QT_NO_DOCKWIDGET
if (i == 1)
- return dockAreaLayout.plug(path);
+ return dockAreaLayout.plug(path.mid(1));
#endif //QT_NO_DOCKWIDGET
return 0;
}
-QLayoutItem *QMainWindowLayoutState::unplug(QList<int> path, QMainWindowLayoutState *other)
+QLayoutItem *QMainWindowLayoutState::unplug(const QList<int> &path, QMainWindowLayoutState *other)
{
- int i = path.takeFirst();
+ int i = path.first();
#ifdef QT_NO_TOOLBAR
Q_UNUSED(other);
#else
if (i == 0)
- return toolBarAreaLayout.unplug(path, other ? &other->toolBarAreaLayout : 0);
+ return toolBarAreaLayout.unplug(path.mid(1), other ? &other->toolBarAreaLayout : 0);
#endif
#ifndef QT_NO_DOCKWIDGET
if (i == 1)
- return dockAreaLayout.unplug(path);
+ return dockAreaLayout.unplug(path.mid(1));
#endif //QT_NO_DOCKWIDGET
return 0;
@@ -939,16 +939,70 @@ void QMainWindowLayout::getStyleOptionInfo(QStyleOptionToolBar *option, QToolBar
void QMainWindowLayout::toggleToolBarsVisible()
{
- layoutState.toolBarAreaLayout.visible = !layoutState.toolBarAreaLayout.visible;
- if (!layoutState.mainWindow->isMaximized()){
- QPoint topLeft = parentWidget()->geometry().topLeft();
- QRect r = parentWidget()->geometry();
- r = layoutState.toolBarAreaLayout.rectHint(r);
- r.moveTo(topLeft);
- parentWidget()->setGeometry(r);
-// widgetAnimator->animate(parentWidget(), r, true);
- } else{
- update();
+ bool updateNonUnifiedParts = true;
+#ifdef Q_WS_MAC
+ if (layoutState.mainWindow->unifiedTitleAndToolBarOnMac()) {
+ // If we hit this case, someone has pressed the "toolbar button" which will
+ // toggle the unified toolbar visiblity, because that's what the user wants.
+ // We might be in a situation where someone has hidden all the toolbars
+ // beforehand (maybe in construction), but now they've hit this button and
+ // and are expecting the items to show. What do we do?
+ // 1) Check the visibility of all the toolbars, if one is visible, do nothing, this
+ // preserves what people would expect (these toolbars were visible when I clicked last time).
+ // 2) If NONE are visible, then show them all. Again, this preserves the user expectation
+ // of, "I want to see the toolbars." The user may get more toolbars than expected, but this
+ // is better seeing nothing.
+ // Don't worry about any of this if we are going invisible. This does mean we may get
+ // into issues when switching into and out of fullscreen mode, but this is probably minor.
+ // If we ever need to do hiding, that would have to be taken care of after the unified toolbar
+ // has finished hiding.
+ // People can of course handle the QEvent::ToolBarChange event themselves and do
+ // WHATEVER they want if they don't like what we are doing (though the unified toolbar
+ // will fire regardless).
+
+ // Check if we REALLY need to update the geometry below. If we only have items in the
+ // unified toolbar, all the docks will be empty, so there's very little point
+ // in doing the geometry as Apple will do it (we also avoid flicker in Cocoa as well).
+ // FWIW, layoutState.toolBarAreaLayout.visible and the state of the unified toolbar
+ // visibility can get out of sync. I really don't think it's a big issue. It is kept
+ // to a minimum because we only change the visibility if we absolutely must.
+ // update the "non unified parts."
+ updateNonUnifiedParts = !layoutState.toolBarAreaLayout.isEmpty();
+
+ // We get this function before the unified toolbar does its thing.
+ // So, the value will be opposite of what we expect.
+ bool goingVisible = !macWindowToolbarIsVisible(qt_mac_window_for(layoutState.mainWindow));
+ if (goingVisible) {
+ const int ToolBarCount = qtoolbarsInUnifiedToolbarList.size();
+ bool needAllVisible = true;
+ for (int i = 0; i < ToolBarCount; ++i) {
+ if (!qtoolbarsInUnifiedToolbarList.at(i)->isHidden()) {
+ needAllVisible = false;
+ break;
+ }
+ }
+ if (needAllVisible) {
+ QBoolBlocker blocker(blockVisiblityCheck); // Disable the visibilty check because
+ // the toggle has already happened.
+ for (int i = 0; i < ToolBarCount; ++i)
+ qtoolbarsInUnifiedToolbarList.at(i)->setVisible(true);
+ }
+ }
+ if (!updateNonUnifiedParts)
+ layoutState.toolBarAreaLayout.visible = goingVisible;
+ }
+#endif
+ if (updateNonUnifiedParts) {
+ layoutState.toolBarAreaLayout.visible = !layoutState.toolBarAreaLayout.visible;
+ if (!layoutState.mainWindow->isMaximized()) {
+ QPoint topLeft = parentWidget()->geometry().topLeft();
+ QRect r = parentWidget()->geometry();
+ r = layoutState.toolBarAreaLayout.rectHint(r);
+ r.moveTo(topLeft);
+ parentWidget()->setGeometry(r);
+ } else {
+ update();
+ }
}
}
@@ -1361,7 +1415,7 @@ QLayoutItem *QMainWindowLayout::takeAt(int index)
if (QLayoutItem *ret = layoutState.takeAt(index, &x)) {
// the widget might in fact have been destroyed by now
if (QWidget *w = ret->widget()) {
- widgetAnimator->abort(w);
+ widgetAnimator.abort(w);
if (w == pluggingWidget)
pluggingWidget = 0;
}
@@ -1528,75 +1582,28 @@ bool QMainWindowLayout::plug(QLayoutItem *widgetItem)
layoutState.remove(previousPath);
pluggingWidget = widget;
- if (dockOptions & QMainWindow::AnimatedDocks) {
- QRect globalRect = currentGapRect;
- globalRect.moveTopLeft(parentWidget()->mapToGlobal(globalRect.topLeft()));
+ QRect globalRect = currentGapRect;
+ globalRect.moveTopLeft(parentWidget()->mapToGlobal(globalRect.topLeft()));
#ifndef QT_NO_DOCKWIDGET
- if (qobject_cast<QDockWidget*>(widget) != 0) {
- QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(widget->layout());
- if (layout->nativeWindowDeco()) {
- globalRect.adjust(0, layout->titleHeight(), 0, 0);
- } else {
- int fw = widget->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, widget);
- globalRect.adjust(-fw, -fw, fw, fw);
- }
+ if (qobject_cast<QDockWidget*>(widget) != 0) {
+ QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(widget->layout());
+ if (layout->nativeWindowDeco()) {
+ globalRect.adjust(0, layout->titleHeight(), 0, 0);
+ } else {
+ int fw = widget->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, widget);
+ globalRect.adjust(-fw, -fw, fw, fw);
}
-#endif
- widgetAnimator->animate(widget, globalRect,
- dockOptions & QMainWindow::AnimatedDocks);
- } else {
-#ifndef QT_NO_DOCKWIDGET
- if (QDockWidget *dw = qobject_cast<QDockWidget*>(widget))
- dw->d_func()->plug(currentGapRect);
-#endif
-#ifndef QT_NO_TOOLBAR
- if (QToolBar *tb = qobject_cast<QToolBar*>(widget))
- tb->d_func()->plug(currentGapRect);
-#endif
- applyState(layoutState);
- savedState.clear();
-#ifndef QT_NO_DOCKWIDGET
- parentWidget()->update(layoutState.dockAreaLayout.separatorRegion());
-#endif
- currentGapPos.clear();
- updateGapIndicator();
- pluggingWidget = 0;
}
+#endif
+ widgetAnimator.animate(widget, globalRect, dockOptions & QMainWindow::AnimatedDocks);
return true;
}
-void QMainWindowLayout::allAnimationsFinished()
-{
-#ifndef QT_NO_DOCKWIDGET
- parentWidget()->update(layoutState.dockAreaLayout.separatorRegion());
-
-#ifndef QT_NO_TABBAR
- foreach (QTabBar *tab_bar, usedTabBars)
- tab_bar->show();
-#endif // QT_NO_TABBAR
-#endif // QT_NO_DOCKWIDGET
-
- updateGapIndicator();
-}
-
void QMainWindowLayout::animationFinished(QWidget *widget)
{
-
- /* This signal is delivered from QWidgetAnimator over a qeued connection. The problem is that
- the widget can be deleted. This is handled as follows:
-
- The animator only ever animates widgets that have been added to this layout. If a widget
- is deleted during animation, the widget's destructor removes the widget form this layout.
- This in turn aborts the animation (see takeAt()) and this signal will never be delivered.
-
- If the widget is deleted after the animation is finished but before this qeued signal
- is delivered, the widget is no longer in the layout and we catch it here. The key is that
- QMainWindowLayoutState::contains() never dereferences the pointer. */
-
- if (!layoutState.contains(widget))
- return;
-
+ //this function is called from within the Widget Animator whenever an animation is finished
+ //on a certain widget
#ifndef QT_NO_TOOLBAR
if (QToolBar *tb = qobject_cast<QToolBar*>(widget)) {
QToolBarLayout *tbl = qobject_cast<QToolBarLayout*>(tb->layout());
@@ -1609,32 +1616,44 @@ void QMainWindowLayout::animationFinished(QWidget *widget)
}
#endif
- if (widget != pluggingWidget)
- return;
+ if (widget == pluggingWidget) {
#ifndef QT_NO_DOCKWIDGET
- if (QDockWidget *dw = qobject_cast<QDockWidget*>(widget))
- dw->d_func()->plug(currentGapRect);
+ if (QDockWidget *dw = qobject_cast<QDockWidget*>(widget))
+ dw->d_func()->plug(currentGapRect);
#endif
#ifndef QT_NO_TOOLBAR
- if (QToolBar *tb = qobject_cast<QToolBar*>(widget))
- tb->d_func()->plug(currentGapRect);
+ if (QToolBar *tb = qobject_cast<QToolBar*>(widget))
+ tb->d_func()->plug(currentGapRect);
#endif
- applyState(layoutState, false);
#ifndef QT_NO_DOCKWIDGET
#ifndef QT_NO_TABBAR
- if (qobject_cast<QDockWidget*>(widget) != 0) {
- // info() might return null if the widget is destroyed while
- // animating but before the animationFinished signal is received.
- if (QDockAreaLayoutInfo *info = layoutState.dockAreaLayout.info(widget))
- info->setCurrentTab(widget);
- }
+ if (qobject_cast<QDockWidget*>(widget) != 0) {
+ // info() might return null if the widget is destroyed while
+ // animating but before the animationFinished signal is received.
+ if (QDockAreaLayoutInfo *info = layoutState.dockAreaLayout.info(widget))
+ info->setCurrentTab(widget);
+ }
#endif
#endif
- savedState.clear();
- currentGapPos.clear();
- pluggingWidget = 0;
+
+ savedState.clear();
+ currentGapPos.clear();
+ pluggingWidget = 0;
+ }
+
+ if (!widgetAnimator.animating()) {
+ //all animations are finished
+#ifndef QT_NO_DOCKWIDGET
+ parentWidget()->update(layoutState.dockAreaLayout.separatorRegion());
+#ifndef QT_NO_TABBAR
+ foreach (QTabBar *tab_bar, usedTabBars)
+ tab_bar->show();
+#endif // QT_NO_TABBAR
+#endif // QT_NO_DOCKWIDGET
+ }
+
updateGapIndicator();
}
@@ -1667,6 +1686,14 @@ QMainWindowLayout::QMainWindowLayout(QMainWindow *mainwindow)
#endif
#endif
#endif // QT_NO_DOCKWIDGET
+ , widgetAnimator(this)
+ , pluggingWidget(0)
+#ifndef QT_NO_RUBBERBAND
+ , gapIndicator(new QRubberBand(QRubberBand::Rectangle, mainwindow))
+#endif //QT_NO_RUBBERBAND
+#ifdef Q_WS_MAC
+ , blockVisiblityCheck(false)
+#endif
{
#ifndef QT_NO_DOCKWIDGET
#ifndef QT_NO_TABBAR
@@ -1680,20 +1707,13 @@ QMainWindowLayout::QMainWindowLayout(QMainWindow *mainwindow)
#endif // QT_NO_DOCKWIDGET
#ifndef QT_NO_RUBBERBAND
- gapIndicator = new QRubberBand(QRubberBand::Rectangle, mainwindow);
// For accessibility to identify this special widget.
gapIndicator->setObjectName(QLatin1String("qt_rubberband"));
-
gapIndicator->hide();
#endif
pluggingWidget = 0;
setObjectName(mainwindow->objectName() + QLatin1String("_layout"));
- widgetAnimator = new QWidgetAnimator(this);
- connect(widgetAnimator, SIGNAL(finished(QWidget*)),
- this, SLOT(animationFinished(QWidget*)), Qt::QueuedConnection);
- connect(widgetAnimator, SIGNAL(finishedAll()),
- this, SLOT(allAnimationsFinished()));
}
QMainWindowLayout::~QMainWindowLayout()
@@ -1795,14 +1815,8 @@ QLayoutItem *QMainWindowLayout::unplug(QWidget *widget)
void QMainWindowLayout::updateGapIndicator()
{
#ifndef QT_NO_RUBBERBAND
- if (widgetAnimator->animating() || currentGapPos.isEmpty()) {
- gapIndicator->hide();
- } else {
- if (gapIndicator->geometry() != currentGapRect)
- gapIndicator->setGeometry(currentGapRect);
- if (!gapIndicator->isVisible())
- gapIndicator->show();
- }
+ gapIndicator->setVisible(!widgetAnimator.animating() && !currentGapPos.isEmpty());
+ gapIndicator->setGeometry(currentGapRect);
#endif
}
diff --git a/src/gui/widgets/qmainwindowlayout_mac.mm b/src/gui/widgets/qmainwindowlayout_mac.mm
index 03bae2f..61719c2 100644
--- a/src/gui/widgets/qmainwindowlayout_mac.mm
+++ b/src/gui/widgets/qmainwindowlayout_mac.mm
@@ -329,29 +329,25 @@ 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
layoutState.mainWindow->setUpdatesEnabled(false); // reduces a little bit of flicker, not all though
if (!useMacToolbar) {
- OSWindowRef windowRef = qt_mac_window_for(parentWidget());
- macWindowToolbarShow(parentWidget(), false);
+ macWindowToolbarShow(layoutState.mainWindow, false);
// Move everything out of the HIToolbar into the main toolbar.
while (!qtoolbarsInUnifiedToolbarList.isEmpty()) {
// Should shrink the list by one every time.
layoutState.mainWindow->addToolBar(Qt::TopToolBarArea, qtoolbarsInUnifiedToolbarList.first());
}
- macWindowToolbarSet(windowRef, NULL);
+ macWindowToolbarSet(qt_mac_window_for(layoutState.mainWindow), 0);
} else {
QList<QToolBar *> toolbars = layoutState.mainWindow->findChildren<QToolBar *>();
for (int i = 0; i < toolbars.size(); ++i) {
@@ -361,6 +357,7 @@ void QMainWindowLayout::updateHIToolBarStatus()
layoutState.mainWindow->addToolBar(Qt::TopToolBarArea, toolbar);
}
}
+ syncUnifiedToolbarVisibility();
}
layoutState.mainWindow->setUpdatesEnabled(true);
}
@@ -441,7 +438,7 @@ void QMainWindowLayout::insertIntoMacToolbar(QToolBar *before, QToolBar *toolbar
#else
NSString *toolbarID = kQToolBarNSToolbarIdentifier;
toolbarID = [toolbarID stringByAppendingFormat:@"%p", toolbar];
- cocoaItemIDToToolbarHash.insert(QCFString::toQString(CFStringRef(toolbarID)), toolbar);
+ cocoaItemIDToToolbarHash.insert(qt_mac_NSStringToQString(toolbarID), toolbar);
[macToolbar insertItemWithItemIdentifier:toolbarID atIndex:beforeIndex];
#endif
}
@@ -489,6 +486,7 @@ void QMainWindowLayout::cleanUpMacToolbarItems()
void QMainWindowLayout::fixSizeInUnifiedToolbar(QToolBar *tb) const
{
+#ifdef QT_MAC_USE_COCOA
QHash<void *, QToolBar *>::const_iterator it = unifiedToolbarHash.constBegin();
NSToolbarItem *item = nil;
while (it != unifiedToolbarHash.constEnd()) {
@@ -509,5 +507,26 @@ void QMainWindowLayout::fixSizeInUnifiedToolbar(QToolBar *tb) const
nssize.height = size.height() - 2;
[item setMinSize:nssize];
}
+#else
+ Q_UNUSED(tb);
+#endif
}
+
+void QMainWindowLayout::syncUnifiedToolbarVisibility()
+{
+ if (blockVisiblityCheck)
+ return;
+
+ Q_ASSERT(layoutState.mainWindow->unifiedTitleAndToolBarOnMac());
+ bool show = false;
+ const int ToolBarCount = qtoolbarsInUnifiedToolbarList.count();
+ for (int i = 0; i < ToolBarCount; ++i) {
+ if (qtoolbarsInUnifiedToolbarList.at(i)->isVisible()) {
+ show = true;
+ break;
+ }
+ }
+ macWindowToolbarShow(layoutState.mainWindow, show);
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/widgets/qmainwindowlayout_p.h b/src/gui/widgets/qmainwindowlayout_p.h
index 26f8633..524fdbf 100644
--- a/src/gui/widgets/qmainwindowlayout_p.h
+++ b/src/gui/widgets/qmainwindowlayout_p.h
@@ -63,6 +63,7 @@
#include "QtCore/qset.h"
#include "QtCore/qbasictimer.h"
#include "private/qlayoutengine_p.h"
+#include "private/qwidgetanimator_p.h"
#include "qdockarealayout_p.h"
#include "qtoolbararealayout_p.h"
@@ -89,7 +90,6 @@ typedef const struct __CFString * CFStringRef;
QT_BEGIN_NAMESPACE
class QToolBar;
-class QWidgetAnimator;
class QRubberBand;
/* This data structure represents the state of all the tool-bars and dock-widgets. It's value based
@@ -128,9 +128,9 @@ public:
QLayoutItem *itemAt(int index, int *x) const;
QLayoutItem *takeAt(int index, int *x);
QList<int> indexOf(QWidget *widget) const;
- QLayoutItem *item(QList<int> path);
- QRect itemRect(QList<int> path) const;
- QRect gapRect(QList<int> path) const; // ### get rid of this, use itemRect() instead
+ QLayoutItem *item(const QList<int> &path);
+ QRect itemRect(const QList<int> &path) const;
+ QRect gapRect(const QList<int> &path) const; // ### get rid of this, use itemRect() instead
bool contains(QWidget *widget) const;
@@ -138,14 +138,14 @@ public:
QWidget *centralWidget() const;
QList<int> gapIndex(QWidget *widget, const QPoint &pos) const;
- bool insertGap(QList<int> path, QLayoutItem *item);
- void remove(QList<int> path);
+ bool insertGap(const QList<int> &path, QLayoutItem *item);
+ void remove(const QList<int> &path);
void remove(QLayoutItem *item);
void clear();
bool isValid() const;
- QLayoutItem *plug(QList<int> path);
- QLayoutItem *unplug(QList<int> path, QMainWindowLayoutState *savedState = 0);
+ QLayoutItem *plug(const QList<int> &path);
+ QLayoutItem *unplug(const QList<int> &path, QMainWindowLayoutState *savedState = 0);
void saveState(QDataStream &stream) const;
bool checkFormat(QDataStream &stream, bool pre43);
@@ -278,7 +278,7 @@ public:
// animations
- QWidgetAnimator *widgetAnimator;
+ QWidgetAnimator widgetAnimator;
QList<int> currentGapPos;
QRect currentGapRect;
QWidget *pluggingWidget;
@@ -295,10 +295,9 @@ public:
void applyState(QMainWindowLayoutState &newState, bool animate = true);
void restore(bool keepSavedState = false);
void updateHIToolBarStatus();
-
-private slots:
void animationFinished(QWidget *widget);
- void allAnimationsFinished();
+
+private Q_SLOTS:
#ifndef QT_NO_DOCKWIDGET
#ifndef QT_NO_TABBAR
void tabChanged();
@@ -336,6 +335,8 @@ public:
void cleanUpMacToolbarItems();
void fixSizeInUnifiedToolbar(QToolBar *tb) const;
bool useHIToolBar;
+ void syncUnifiedToolbarVisibility();
+ bool blockVisiblityCheck;
#endif
};
QT_END_NAMESPACE
diff --git a/src/gui/widgets/qmdisubwindow.cpp b/src/gui/widgets/qmdisubwindow.cpp
index 25bc724..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..35b68b4 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
@@ -164,6 +163,12 @@ void QMenuPrivate::init()
}
}
+int QMenuPrivate::scrollerHeight() const
+{
+ Q_Q(const QMenu);
+ return qMax(QApplication::globalStrut().height(), q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q));
+}
+
//Windows and KDE allows menus to cover the taskbar, while GNOME and Mac don't
QRect QMenuPrivate::popupGeometry(int screen) const
{
@@ -194,57 +199,75 @@ 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 +298,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 +306,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);
-
- // skip double/tripple/etc. separators
- while (i < actions.count()
- && (!actions.at(i)->isVisible() || actions.at(i)->isSeparator()))
- ++i;
- }
+ updateActionRects();
- 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 +488,17 @@ void QMenuPrivate::setSyncAction()
void QMenuPrivate::setFirstActionActive()
{
Q_Q(QMenu);
- 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];
+ updateActionRects();
+ 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();
- if (saccum > scroll->scrollOffset-scrollerHeight)
+ 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 +548,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 +595,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,27 +671,25 @@ void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation loc
Q_Q(QMenu);
if (!scroll || !scroll->scrollFlags)
return;
+ updateActionRects();
int newOffset = 0;
- const int scrollHeight = q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q);
- const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp) ? scrollHeight : 0;
- const int botScroll = (scroll->scrollFlags & QMenuScroller::ScrollDown) ? scrollHeight : 0;
+ const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp) ? scrollerHeight() : 0;
+ const int botScroll = (scroll->scrollFlags & QMenuScroller::ScrollDown) ? scrollerHeight() : 0;
const int vmargin = q->style()->pixelMetric(QStyle::PM_MenuVMargin, 0, q);
const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q);
if (location == QMenuScroller::ScrollTop) {
- for(int i = 0, saccum = 0; i < actionList.count(); i++) {
- QAction *act = actionList.at(i);
- if (act == action) {
+ for(int i = 0, saccum = 0; i < actions.count(); i++) {
+ if (actions.at(i) == 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();
- if (act == action) {
+ for(int i = 0, saccum = 0; i < actions.count(); i++) {
+ saccum += actionRects.at(i).height();
+ if (actions.at(i) == action) {
if (location == QMenuScroller::ScrollCenter)
newOffset = ((q->height() / 2) - botScroll) - (saccum - topScroll);
else
@@ -734,7 +698,7 @@ void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation loc
}
}
if(newOffset)
- newOffset -= fw*2;
+ newOffset -= fw * 2;
}
//figure out which scroll flags
@@ -742,8 +706,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;
@@ -794,9 +758,19 @@ void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation loc
}
//actually update flags
- scroll->scrollOffset = newOffset;
- if (scroll->scrollOffset > 0)
- scroll->scrollOffset = 0;
+ const int delta = qMin(0, newOffset) - scroll->scrollOffset; //make sure the new offset is always negative
+ if (!itemsDirty && delta) {
+ //we've scrolled so we need to update the action rects
+ for (int i = 0; i < actionRects.count(); ++i) {
+ QRect &current = actionRects[i];
+ current.moveTop(current.top() + delta);
+
+ //we need to update the widgets geometry
+ if (QWidget *w = widgetItems.at(i))
+ w->setGeometry(current);
+ }
+ }
+ scroll->scrollOffset += delta;
scroll->scrollFlags = newScrollFlags;
if (active)
setCurrentAction(action);
@@ -807,9 +781,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 +798,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,38 +821,33 @@ void QMenuPrivate::scrollMenu(QMenuScroller::ScrollDirection direction, bool pag
Q_Q(QMenu);
if (!scroll || !(scroll->scrollFlags & direction)) //not really possible...
return;
- const int scrollHeight = q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q);
- const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp) ? scrollHeight : 0;
- const int botScroll = (scroll->scrollFlags & QMenuScroller::ScrollDown) ? scrollHeight : 0;
+ updateActionRects();
+ const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp) ? scrollerHeight() : 0;
+ const int botScroll = (scroll->scrollFlags & QMenuScroller::ScrollDown) ? scrollerHeight() : 0;
const int vmargin = q->style()->pixelMetric(QStyle::PM_MenuVMargin, 0, q);
const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q);
const int offset = topScroll ? topScroll-vmargin : 0;
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;
}
}
@@ -896,13 +870,12 @@ bool QMenuPrivate::mouseEventTaken(QMouseEvent *e)
if (scroll && !activeMenu) { //let the scroller "steal" the event
bool isScroll = false;
if (pos.x() >= 0 && pos.x() < q->width()) {
- const int scrollerHeight = q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q);
for(int dir = QMenuScroller::ScrollUp; dir <= QMenuScroller::ScrollDown; dir = dir << 1) {
if (scroll->scrollFlags & dir) {
if (dir == QMenuScroller::ScrollUp)
- isScroll = (pos.y() <= scrollerHeight);
+ isScroll = (pos.y() <= scrollerHeight());
else if (dir == QMenuScroller::ScrollDown)
- isScroll = (pos.y() >= q->height()-scrollerHeight);
+ isScroll = (pos.y() >= q->height() - scrollerHeight());
if (isScroll) {
scroll->scrollDirection = dir;
break;
@@ -911,19 +884,17 @@ bool QMenuPrivate::mouseEventTaken(QMouseEvent *e)
}
}
if (isScroll) {
- if (!scroll->scrollTimer)
- scroll->scrollTimer = new QBasicTimer;
- scroll->scrollTimer->start(50, q);
+ scroll->scrollTimer.start(50, q);
return true;
- } else if (scroll->scrollTimer && scroll->scrollTimer->isActive()) {
- scroll->scrollTimer->stop();
+ } else {
+ scroll->scrollTimer.stop();
}
}
if (tearoff) { //let the tear off thingie "steal" the event..
QRect tearRect(0, 0, q->width(), q->style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, q));
if (scroll && scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)
- tearRect.translate(0, q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q));
+ tearRect.translate(0, scrollerHeight());
q->update(tearRect);
if (tearRect.contains(pos) && hasMouseMoved(e->globalPos())) {
setCurrentAction(0);
@@ -1178,7 +1149,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,19 +1345,17 @@ 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();
- if (d->tornPopup)
- d->tornPopup->close();
+ hideTearOffMenu();
}
/*!
@@ -1596,8 +1566,8 @@ void QMenu::setTearOffEnabled(bool b)
Q_D(QMenu);
if (d->tearoff == b)
return;
- if (!b && d->tornPopup)
- d->tornPopup->close();
+ if (!b)
+ hideTearOffMenu();
d->tearoff = b;
d->itemsDirty = true;
@@ -1632,8 +1602,8 @@ bool QMenu::isTearOffMenuVisible() const
*/
void QMenu::hideTearOffMenu()
{
- if (d_func()->tornPopup)
- d_func()->tornPopup->close();
+ if (QWidget *w = d_func()->tornPopup)
+ w->close();
}
@@ -1732,35 +1702,34 @@ 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());
- }
- 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;
+ 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());
}
// 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 +1771,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 +1780,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 +1795,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 +2008,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);
}
@@ -2090,6 +2058,8 @@ void QMenu::hideEvent(QHideEvent *)
d->hasHadMouse = false;
d->causedPopup.widget = 0;
d->causedPopup.action = 0;
+ if (d->scroll)
+ d->scroll->scrollTimer.stop(); //make sure the timer stops
}
/*!
@@ -2098,6 +2068,7 @@ void QMenu::hideEvent(QHideEvent *)
void QMenu::paintEvent(QPaintEvent *e)
{
Q_D(QMenu);
+ d->updateActionRects();
QPainter p(this);
QRegion emptyArea = QRegion(rect());
@@ -2110,11 +2081,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);
@@ -2130,18 +2101,17 @@ void QMenu::paintEvent(QPaintEvent *e)
const int fw = style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, this);
//draw the scroller regions..
if (d->scroll) {
- const int scrollerHeight = style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, this);
menuOpt.menuItemType = QStyleOptionMenuItem::Scroller;
menuOpt.state |= QStyle::State_Enabled;
if (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp) {
- menuOpt.rect.setRect(fw, fw, width() - (fw * 2), scrollerHeight);
+ menuOpt.rect.setRect(fw, fw, width() - (fw * 2), d->scrollerHeight());
emptyArea -= QRegion(menuOpt.rect);
p.setClipRect(menuOpt.rect);
style()->drawControl(QStyle::CE_MenuScroller, &menuOpt, &p, this);
}
if (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollDown) {
- menuOpt.rect.setRect(fw, height() - scrollerHeight - fw, width() - (fw * 2),
- scrollerHeight);
+ menuOpt.rect.setRect(fw, height() - d->scrollerHeight() - fw, width() - (fw * 2),
+ d->scrollerHeight());
emptyArea -= QRegion(menuOpt.rect);
menuOpt.state |= QStyle::State_DownArrow;
p.setClipRect(menuOpt.rect);
@@ -2154,7 +2124,7 @@ void QMenu::paintEvent(QPaintEvent *e)
menuOpt.rect.setRect(fw, fw, width() - (fw * 2),
style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this));
if (d->scroll && d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)
- menuOpt.rect.translate(0, style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, this));
+ menuOpt.rect.translate(0, d->scrollerHeight());
emptyArea -= QRegion(menuOpt.rect);
p.setClipRect(menuOpt.rect);
menuOpt.state = QStyle::State_None;
@@ -2263,7 +2233,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 +2314,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 +2354,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 +2406,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 +2418,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 +2431,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,21 +2441,23 @@ 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)))
continue;
nextAction = next;
if (d->scroll && (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)) {
- int topVisible = style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, this);
+ int topVisible = d->scrollerHeight();
if (d->tearoff)
topVisible += style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this);
- if (((y + d->scroll->scrollOffset) - topVisible) <= d->actionRects.value(nextAction).height())
+ if (((y + d->scroll->scrollOffset) - topVisible) <= d->actionRects.at(next_i).height())
scroll_loc = QMenuPrivate::QMenuScroller::ScrollTop;
}
break;
@@ -2488,31 +2465,32 @@ 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)))
continue;
nextAction = next;
if (d->scroll && (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollDown)) {
- const int scrollerHeight = style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, this);
- int bottomVisible = height()-scrollerHeight;
+ int bottomVisible = height() - d->scrollerHeight();
if (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)
- bottomVisible -= scrollerHeight;
+ bottomVisible -= d->scrollerHeight();
if (d->tearoff)
bottomVisible -= style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this);
- if ((y + d->scroll->scrollOffset + d->actionRects.value(nextAction).height()) > bottomVisible)
+ if ((y + d->scroll->scrollOffset + d->actionRects.at(next_i).height()) > bottomVisible)
scroll_loc = QMenuPrivate::QMenuScroller::ScrollBottom;
}
break;
@@ -2520,13 +2498,12 @@ void QMenu::keyPressEvent(QKeyEvent *e)
}
break;
}
- y += d->actionRects.value(act).height();
+ y += d->actionRects.at(i).height();
}
}
if (nextAction) {
if (d->scroll && scroll_loc != QMenuPrivate::QMenuScroller::ScrollStay) {
- if (d->scroll->scrollTimer)
- d->scroll->scrollTimer->stop();
+ d->scroll->scrollTimer.stop();
d->scrollMenu(nextAction, scroll_loc);
}
d->setCurrentAction(nextAction, /*popup*/-1, QMenuPrivate::SelectedFromKeyboard);
@@ -2648,9 +2625,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 +2646,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 +2720,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) {
@@ -2783,10 +2764,10 @@ void
QMenu::timerEvent(QTimerEvent *e)
{
Q_D(QMenu);
- if (d->scroll && d->scroll->scrollTimer && d->scroll->scrollTimer->timerId() == e->timerId()) {
+ if (d->scroll && d->scroll->scrollTimer.timerId() == e->timerId()) {
d->scrollMenu((QMenuPrivate::QMenuScroller::ScrollDirection)d->scroll->scrollDirection);
if (d->scroll->scrollFlags == QMenuPrivate::QMenuScroller::ScrollNone)
- d->scroll->scrollTimer->stop();
+ d->scroll->scrollTimer.stop();
} else if(QMenuPrivate::menuDelayTimer.timerId() == e->timerId()) {
QMenuPrivate::menuDelayTimer.stop();
internalDelayedPopup();
@@ -2813,31 +2794,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 +2838,7 @@ void QMenu::actionEvent(QActionEvent *e)
#endif
if (isVisible()) {
- d->updateActions();
+ d->updateActionRects();
resize(sizeHint());
update();
}
@@ -3044,7 +3019,7 @@ void QMenu::setSeparatorsCollapsible(bool collapse)
d->collapsibleSeparators = collapse;
d->itemsDirty = 1;
if (isVisible()) {
- d->updateActions();
+ d->updateActionRects();
update();
}
}
@@ -3103,9 +3078,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..4e428fe 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
@@ -151,18 +151,18 @@ public:
}
void init();
+ int scrollerHeight() const;
+
//item calculations
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;
@@ -191,10 +191,10 @@ public:
enum ScrollDirection { ScrollNone=0, ScrollUp=0x01, ScrollDown=0x02 };
uint scrollFlags : 2, scrollDirection : 2;
int scrollOffset;
- QBasicTimer *scrollTimer;
+ QBasicTimer scrollTimer;
- QMenuScroller() : scrollFlags(ScrollNone), scrollDirection(ScrollNone), scrollOffset(0), scrollTimer(0) { }
- ~QMenuScroller() { delete scrollTimer; }
+ QMenuScroller() : scrollFlags(ScrollNone), scrollDirection(ScrollNone), scrollOffset(0) { }
+ ~QMenuScroller() { }
} *scroll;
void scrollMenu(QMenuScroller::ScrollLocation location, bool active=false);
void scrollMenu(QMenuScroller::ScrollDirection direction, bool page=false, bool active=false);
@@ -234,7 +234,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..be6ed67 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 (rect.isValid() && !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 (rect.isValid() && !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.
*/
@@ -922,6 +956,13 @@ void QMenuBar::setActiveAction(QAction *act)
/*!
Removes all the actions from the menu bar.
+ \note On Mac OS X, menu items that have been merged to the system
+ menu bar are not removed by this function. One way to handle this
+ would be to remove the extra actions yourself. You can set the
+ \l{QAction::MenuRole}{menu role} on the different menus, so that
+ you know ahead of time which menu items get merged and which do
+ not. Then decide what to recreate or remove yourself.
+
\sa removeAction()
*/
void QMenuBar::clear()
@@ -975,8 +1016,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 +1133,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 +1168,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 +1193,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 +1298,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 +1608,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 +1670,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 +1725,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 +1755,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..82026d4 100644
--- a/src/gui/widgets/qplaintextedit.cpp
+++ b/src/gui/widgets/qplaintextedit.cpp
@@ -66,6 +66,8 @@
#include <qtexttable.h>
#include <qvariant.h>
+#include <qstandardgestures.h>
+
#include <qinputcontext.h>
#ifndef QT_NO_TEXTEDIT
@@ -250,7 +252,7 @@ QPlainTextDocumentLayoutPrivate *QPlainTextDocumentLayout::priv() const
*/
void QPlainTextDocumentLayout::requestUpdate()
{
- emit update(QRectF(0., -4., 1000000000., 1000000000.));
+ emit update(QRectF(0., -document()->documentMargin(), 1000000000., 1000000000.));
}
@@ -345,8 +347,7 @@ void QPlainTextDocumentLayout::documentChanged(int from, int /*charsRemoved*/, i
}
if (!d->blockUpdate)
- emit update(); // optimization potential
-
+ emit update(QRectF(0., -doc->documentMargin(), 1000000000., 1000000000.)); // optimization potential
}
@@ -726,6 +727,9 @@ QPlainTextEditPrivate::QPlainTextEditPrivate()
backgroundVisible = false;
centerOnScroll = false;
inDrag = false;
+#ifdef Q_WS_WIN
+ singleFingerPanEnabled = true;
+#endif
}
@@ -781,6 +785,9 @@ void QPlainTextEditPrivate::init(const QString &txt)
#ifndef QT_NO_CURSOR
viewport->setCursor(Qt::IBeamCursor);
#endif
+ originalOffsetY = 0;
+ panGesture = new QPanGesture(q);
+ QObject::connect(panGesture, SIGNAL(triggered()), q, SLOT(_q_gestureTriggered()));
}
void QPlainTextEditPrivate::_q_repaintContents(const QRectF &contentsRect)
@@ -1014,14 +1021,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 +1168,8 @@ void QPlainTextEditPrivate::ensureViewportLayouted()
\sa QTextDocument, QTextCursor, {Application Example},
- {Syntax Highlighter Example}, {Rich Text Processing}
+ {Code Editor Example}, {Syntax Highlighter Example},
+ {Rich Text Processing}
*/
@@ -2899,6 +2906,30 @@ QAbstractTextDocumentLayout::PaintContext QPlainTextEdit::getPaintContext() cons
(\a available is true) or unavailable (\a available is false).
*/
+void QPlainTextEditPrivate::_q_gestureTriggered()
+{
+ Q_Q(QPlainTextEdit);
+ QPanGesture *g = qobject_cast<QPanGesture*>(q->sender());
+ if (!g)
+ return;
+ QScrollBar *hBar = q->horizontalScrollBar();
+ QScrollBar *vBar = q->verticalScrollBar();
+ if (g->state() == Qt::GestureStarted)
+ originalOffsetY = vBar->value();
+ QSize totalOffset = g->totalOffset();
+ if (!totalOffset.isNull()) {
+ if (QApplication::isRightToLeft())
+ totalOffset.rwidth() *= -1;
+ // QPlainTextEdit scrolls by lines only in vertical direction
+ QFontMetrics fm(q->document()->defaultFont());
+ int lineHeight = fm.height();
+ int newX = hBar->value() - g->lastOffset().width();
+ int newY = originalOffsetY - totalOffset.height()/lineHeight;
+ hbar->setValue(newX);
+ vbar->setValue(newY);
+ }
+}
+
QT_END_NAMESPACE
#include "moc_qplaintextedit.cpp"
diff --git a/src/gui/widgets/qplaintextedit.h b/src/gui/widgets/qplaintextedit.h
index dc0851b..35bbc37 100644
--- a/src/gui/widgets/qplaintextedit.h
+++ b/src/gui/widgets/qplaintextedit.h
@@ -269,6 +269,7 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_adjustScrollbars())
Q_PRIVATE_SLOT(d_func(), void _q_verticalScrollbarActionTriggered(int))
Q_PRIVATE_SLOT(d_func(), void _q_cursorPositionChanged())
+ Q_PRIVATE_SLOT(d_func(), void _q_gestureTriggered())
friend class QPlainTextEditControl;
};
diff --git a/src/gui/widgets/qplaintextedit_p.h b/src/gui/widgets/qplaintextedit_p.h
index 5075fc4..ae584e0 100644
--- a/src/gui/widgets/qplaintextedit_p.h
+++ b/src/gui/widgets/qplaintextedit_p.h
@@ -72,6 +72,7 @@ class QMimeData;
class QPlainTextEdit;
class ExtraArea;
+class QPanGesture;
class QPlainTextEditControl : public QTextControl
{
@@ -173,6 +174,10 @@ public:
void _q_cursorPositionChanged();
void _q_modificationChanged(bool);
+
+ void _q_gestureTriggered();
+ int originalOffsetY;
+ QPanGesture *panGesture;
};
QT_END_NAMESPACE
diff --git a/src/gui/widgets/qprogressbar.cpp b/src/gui/widgets/qprogressbar.cpp
index ac3338b..d168028 100644
--- a/src/gui/widgets/qprogressbar.cpp
+++ b/src/gui/widgets/qprogressbar.cpp
@@ -204,7 +204,7 @@ bool QProgressBarPrivate::repaintRequired() const
\o A progress bar shown in the Plastique widget style.
\endtable
- \sa QTimeLine, QProgressDialog, {fowler}{GUI Design Handbook: Progress Indicator}
+ \sa QProgressDialog, {fowler}{GUI Design Handbook: Progress Indicator}
*/
/*!
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..3933272 100644
--- a/src/gui/widgets/qspinbox.cpp
+++ b/src/gui/widgets/qspinbox.cpp
@@ -50,6 +50,7 @@
#include <qdebug.h>
#include <math.h>
+#include <float.h>
QT_BEGIN_NAMESPACE
@@ -284,6 +285,9 @@ void QSpinBox::setPrefix(const QString &prefix)
d->prefix = prefix;
d->updateEdit();
+
+ d->cachedSizeHint = QSize();
+ updateGeometry();
}
/*!
@@ -318,6 +322,9 @@ void QSpinBox::setSuffix(const QString &suffix)
d->suffix = suffix;
d->updateEdit();
+
+ d->cachedSizeHint = QSize();
+ updateGeometry();
}
/*!
@@ -817,8 +824,8 @@ void QDoubleSpinBox::setRange(double minimum, double maximum)
Sets how many decimals the spinbox will use for displaying and
interpreting doubles.
- \warning The results might not be reliable with very high values
- for \a decimals.
+ \warning The maximum value for \a decimals is DBL_MAX_10_EXP +
+ DBL_DIG (ie. 323) because of the limitations of the double type.
Note: The maximum, minimum and value might change as a result of
changing this property.
@@ -834,7 +841,7 @@ int QDoubleSpinBox::decimals() const
void QDoubleSpinBox::setDecimals(int decimals)
{
Q_D(QDoubleSpinBox);
- d->decimals = qMax(0, decimals);
+ d->decimals = qBound(0, decimals, DBL_MAX_10_EXP + DBL_DIG);
setRange(minimum(), maximum()); // make sure values are rounded
setValue(value());
diff --git a/src/gui/widgets/qtabbar.cpp b/src/gui/widgets/qtabbar.cpp
index 11cb6a1..690e624 100644
--- a/src/gui/widgets/qtabbar.cpp
+++ b/src/gui/widgets/qtabbar.cpp
@@ -663,7 +663,7 @@ void QTabBarPrivate::refresh()
if (pressedIndex != -1
&& movable
&& QApplication::mouseButtons() == Qt::NoButton) {
- _q_moveTabFinished(pressedIndex);
+ moveTabFinished(pressedIndex);
if (!validIndex(pressedIndex))
pressedIndex = -1;
}
@@ -1662,26 +1662,17 @@ void QTabBarPrivate::slide(int from, int to)
q->setUpdatesEnabled(true);
int postLocation = vertical ? q->tabRect(to).y() : q->tabRect(to).x();
int length = postLocation - preLocation;
- tabList[to].makeTimeLine(q);
- tabList[to].dragOffset += -1 * length;
- tabList[to].timeLine->setFrameRange(tabList[to].dragOffset, 0);
- animations[tabList[to].timeLine] = to;
- tabList[to].timeLine->setDuration(ANIMATION_DURATION);
- if (tabList[to].timeLine->state() != QTimeLine::Running)
- tabList[to].timeLine->start();
+ tabList[to].dragOffset -= length;
+ tabList[to].startAnimation(this, ANIMATION_DURATION);
}
-void QTabBarPrivate::_q_moveTab(int offset)
+void QTabBarPrivate::moveTab(int index, int offset)
{
- Q_Q(QTabBar);
- if (QTimeLine *timeLine = qobject_cast<QTimeLine *>(q->sender())) {
- int index = animations[timeLine];
- if (!validIndex(index))
- return;
- tabList[index].dragOffset = offset;
- layoutTab(index); // Make buttons follow tab
- q->update();
- }
+ if (!validIndex(index))
+ return;
+ tabList[index].dragOffset = offset;
+ layoutTab(index); // Make buttons follow tab
+ q_func()->update();
}
/*!\reimp
@@ -1695,7 +1686,7 @@ void QTabBar::mousePressEvent(QMouseEvent *event)
}
// Be safe!
if (d->pressedIndex != -1 && d->movable)
- d->_q_moveTabFinished(d->pressedIndex);
+ d->moveTabFinished(d->pressedIndex);
d->pressedIndex = d->indexAtPos(event->pos());
if (d->validIndex(d->pressedIndex)) {
@@ -1721,7 +1712,7 @@ void QTabBar::mouseMoveEvent(QMouseEvent *event)
// Be safe!
if (d->pressedIndex != -1
&& event->buttons() == Qt::NoButton)
- d->_q_moveTabFinished(d->pressedIndex);
+ d->moveTabFinished(d->pressedIndex);
// Start drag
if (!d->dragInProgress && d->pressedIndex != -1) {
@@ -1789,16 +1780,6 @@ void QTabBar::mouseMoveEvent(QMouseEvent *event)
optTabBase.documentMode = d->documentMode;
}
-void QTabBarPrivate::_q_moveTabFinished()
-{
- Q_Q(QTabBar);
- if (QTimeLine *timeLine = qobject_cast<QTimeLine *>(q->sender())) {
- int index = animations[timeLine];
- animations.remove(timeLine);
- _q_moveTabFinished(index);
- }
-}
-
void QTabBarPrivate::setupMovableTab()
{
Q_Q(QTabBar);
@@ -1838,11 +1819,19 @@ void QTabBarPrivate::setupMovableTab()
movingTab->setVisible(true);
}
-void QTabBarPrivate::_q_moveTabFinished(int index)
+void QTabBarPrivate::moveTabFinished(int index)
{
Q_Q(QTabBar);
bool cleanup = (pressedIndex == index) || (pressedIndex == -1) || !validIndex(index);
- if (animations.isEmpty() && cleanup) {
+ bool allAnimationsFinished = true;
+#ifndef QT_NO_ANIMATION
+ for(int i = 0; allAnimationsFinished && i < tabList.count(); ++i) {
+ const Tab &t = tabList.at(i);
+ if (t.animation && t.animation->state() == QAbstractAnimation::Running)
+ allAnimationsFinished = false;
+ }
+#endif //QT_NO_ANIMATION
+ if (allAnimationsFinished && cleanup) {
movingTab->setVisible(false); // We might not get a mouse release
for (int i = 0; i < tabList.count(); ++i) {
tabList[i].dragOffset = 0;
@@ -1877,17 +1866,8 @@ void QTabBar::mouseReleaseEvent(QMouseEvent *event)
? tabRect(d->pressedIndex).height()
: tabRect(d->pressedIndex).width();
int duration = qMin(ANIMATION_DURATION,
- ((length < 0 ? (-1 * length) : length) * ANIMATION_DURATION) / width);
- if (duration > 0) {
- d->tabList[d->pressedIndex].makeTimeLine(this);
- d->tabList[d->pressedIndex].timeLine->setFrameRange(length, 0);
- d->animations[d->tabList[d->pressedIndex].timeLine] = d->pressedIndex;
- d->tabList[d->pressedIndex].timeLine->setDuration(duration);
- if (d->tabList[d->pressedIndex].timeLine->state() != QTimeLine::Running)
- d->tabList[d->pressedIndex].timeLine->start();
- } else {
- d->_q_moveTabFinished(d->pressedIndex);
- }
+ (qAbs(length) * ANIMATION_DURATION) / width);
+ d->tabList[d->pressedIndex].startAnimation(d, duration);
d->dragInProgress = false;
d->movingTab->setVisible(false);
d->dragStartPosition = QPoint();
diff --git a/src/gui/widgets/qtabbar.h b/src/gui/widgets/qtabbar.h
index 7514486..402f54b 100644
--- a/src/gui/widgets/qtabbar.h
+++ b/src/gui/widgets/qtabbar.h
@@ -215,8 +215,6 @@ private:
Q_DECLARE_PRIVATE(QTabBar)
Q_PRIVATE_SLOT(d_func(), void _q_scrollTabs())
Q_PRIVATE_SLOT(d_func(), void _q_closeTab())
- Q_PRIVATE_SLOT(d_func(), void _q_moveTab(int))
- Q_PRIVATE_SLOT(d_func(), void _q_moveTabFinished())
};
#endif // QT_NO_TABBAR
diff --git a/src/gui/widgets/qtabbar_p.h b/src/gui/widgets/qtabbar_p.h
index dbae055..b9b9fba 100644
--- a/src/gui/widgets/qtabbar_p.h
+++ b/src/gui/widgets/qtabbar_p.h
@@ -58,9 +58,8 @@
#include <qicon.h>
#include <qtoolbutton.h>
-#include <qtimeline.h>
-#include <qhash.h>
#include <qdebug.h>
+#include <qvariantanimation.h>
#ifndef QT_NO_TABBAR
@@ -75,9 +74,10 @@ class QTabBarPrivate : public QWidgetPrivate
Q_DECLARE_PUBLIC(QTabBar)
public:
QTabBarPrivate()
- :currentIndex(-1), pressedIndex(-1),
- shape(QTabBar::RoundedNorth),
- layoutDirty(false), drawBase(true), scrollOffset(0), expanding(true), closeButtonOnTabs(false), selectionBehaviorOnRemove(QTabBar::SelectRightTab), paintWithOffsets(true), movable(false), dragInProgress(false), documentMode(false), movingTab(0) {}
+ :currentIndex(-1), pressedIndex(-1), shape(QTabBar::RoundedNorth), layoutDirty(false),
+ drawBase(true), scrollOffset(0), expanding(true), closeButtonOnTabs(false),
+ selectionBehaviorOnRemove(QTabBar::SelectRightTab), paintWithOffsets(true), movable(false),
+ dragInProgress(false), documentMode(false), movingTab(0) {}
int currentIndex;
int pressedIndex;
@@ -88,16 +88,13 @@ public:
struct Tab {
inline Tab(const QIcon &ico, const QString &txt)
- : enabled(true)
- , shortcutId(0)
- , text(txt)
- , icon(ico)
- , leftWidget(0)
- , rightWidget(0)
- , lastTab(-1)
- , timeLine(0)
- , dragOffset(0)
+ : enabled(true) , shortcutId(0), text(txt), icon(ico),
+ leftWidget(0), rightWidget(0), lastTab(-1), dragOffset(0)
+#ifndef QT_NO_ANIMATION
+ , animation(0)
+#endif //QT_NO_ANIMATION
{}
+ bool operator==(const Tab &other) const { return &other == this; }
bool enabled;
int shortcutId;
QString text;
@@ -117,21 +114,39 @@ public:
QWidget *leftWidget;
QWidget *rightWidget;
int lastTab;
-
- QTimeLine *timeLine;
int dragOffset;
- void makeTimeLine(QWidget *q) {
- if (timeLine)
- return;
- timeLine = new QTimeLine(ANIMATION_DURATION, q);
- q->connect(timeLine, SIGNAL(frameChanged(int)), q, SLOT(_q_moveTab(int)));
- q->connect(timeLine, SIGNAL(finished()), q, SLOT(_q_moveTabFinished()));
+#ifndef QT_NO_ANIMATION
+ ~Tab() { delete animation; }
+ struct TabBarAnimation : public QVariantAnimation {
+ TabBarAnimation(Tab *t, QTabBarPrivate *_priv) : tab(t), priv(_priv)
+ { setEasingCurve(QEasingCurve::InOutQuad); }
+
+ void updateCurrentValue(const QVariant &current)
+ { priv->moveTab(priv->tabList.indexOf(*tab), current.toInt()); }
+
+ void updateState(State, State newState)
+ { if (newState == Stopped) priv->moveTabFinished(priv->tabList.indexOf(*tab)); }
+ private:
+ //these are needed for the callbacks
+ Tab *tab;
+ QTabBarPrivate *priv;
+ } *animation;
+
+ void startAnimation(QTabBarPrivate *priv, int duration) {
+ if (!animation)
+ animation = new TabBarAnimation(this, priv);
+ animation->setStartValue(dragOffset);
+ animation->setEndValue(0);
+ animation->setDuration(duration);
+ animation->start();
}
-
+#else
+ void startAnimation(QTabBarPrivate *priv, int duration)
+ { Q_UNUSED(duration); priv->moveTabFinished(priv->tabList.indexOf(*this)); }
+#endif //QT_NO_ANIMATION
};
QList<Tab> tabList;
- QHash<QTimeLine*, int> animations;
int calculateNewPosition(int from, int to, int index) const;
void slide(int from, int to);
@@ -152,9 +167,8 @@ public:
void _q_scrollTabs();
void _q_closeTab();
- void _q_moveTab(int);
- void _q_moveTabFinished();
- void _q_moveTabFinished(int offset);
+ void moveTab(int index, int offset);
+ void moveTabFinished(int index);
QRect hoverRect;
void refresh();
diff --git a/src/gui/widgets/qtextedit.cpp b/src/gui/widgets/qtextedit.cpp
index c8d8d04..e80df92 100644
--- a/src/gui/widgets/qtextedit.cpp
+++ b/src/gui/widgets/qtextedit.cpp
@@ -67,6 +67,8 @@
#include <qtexttable.h>
#include <qvariant.h>
+#include <qstandardgestures.h>
+
#include <qinputcontext.h>
#endif
@@ -111,6 +113,9 @@ QTextEditPrivate::QTextEditPrivate()
preferRichText = false;
showCursorOnInitialShow = true;
inDrag = false;
+#ifdef Q_WS_WIN
+ singleFingerPanEnabled = true;
+#endif
}
void QTextEditPrivate::createAutoBulletList()
@@ -178,6 +183,8 @@ void QTextEditPrivate::init(const QString &html)
#ifndef QT_NO_CURSOR
viewport->setCursor(Qt::IBeamCursor);
#endif
+ panGesture = new QPanGesture(q);
+ QObject::connect(panGesture, SIGNAL(triggered()), q, SLOT(_q_gestureTriggered()));
}
void QTextEditPrivate::_q_repaintContents(const QRectF &contentsRect)
@@ -2610,6 +2617,25 @@ void QTextEdit::ensureCursorVisible()
d->control->ensureCursorVisible();
}
+void QTextEditPrivate::_q_gestureTriggered()
+{
+ Q_Q(QTextEdit);
+ QPanGesture *g = qobject_cast<QPanGesture*>(q->sender());
+ if (!g)
+ return;
+ QScrollBar *hBar = q->horizontalScrollBar();
+ QScrollBar *vBar = q->verticalScrollBar();
+ QPoint delta = g->pos() - (g->lastPos().isNull() ? g->pos() : g->lastPos());
+ if (!delta.isNull()) {
+ if (QApplication::isRightToLeft())
+ delta.rx() *= -1;
+ int newX = hBar->value() - delta.x();
+ int newY = vBar->value() - delta.y();
+ hbar->setValue(newX);
+ vbar->setValue(newY);
+ }
+}
+
/*!
\enum QTextEdit::KeyboardAction
diff --git a/src/gui/widgets/qtextedit.h b/src/gui/widgets/qtextedit.h
index 617822a..9e10e07 100644
--- a/src/gui/widgets/qtextedit.h
+++ b/src/gui/widgets/qtextedit.h
@@ -414,6 +414,7 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_currentCharFormatChanged(const QTextCharFormat &))
Q_PRIVATE_SLOT(d_func(), void _q_adjustScrollbars())
Q_PRIVATE_SLOT(d_func(), void _q_ensureVisible(const QRectF &))
+ Q_PRIVATE_SLOT(d_func(), void _q_gestureTriggered())
friend class QTextEditControl;
friend class QTextDocument;
friend class QTextControl;
diff --git a/src/gui/widgets/qtextedit_p.h b/src/gui/widgets/qtextedit_p.h
index e7609d6..249331e 100644
--- a/src/gui/widgets/qtextedit_p.h
+++ b/src/gui/widgets/qtextedit_p.h
@@ -70,7 +70,7 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_TEXTEDIT
class QMimeData;
-
+class QPanGesture;
class QTextEditPrivate : public QAbstractScrollAreaPrivate
{
Q_DECLARE_PUBLIC(QTextEdit)
@@ -129,6 +129,9 @@ public:
QString anchorToScrollToWhenVisible;
+ void _q_gestureTriggered();
+ QPanGesture *panGesture;
+
#ifdef QT_KEYPAD_NAVIGATION
QBasicTimer deleteAllTimer;
#endif
diff --git a/src/gui/widgets/qtoolbar.cpp b/src/gui/widgets/qtoolbar.cpp
index b635628..b65f1ba 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);
@@ -1080,19 +1074,46 @@ static bool waitForPopup(QToolBar *tb, QWidget *popup)
return false;
}
+#if defined(Q_WS_MAC)
+static bool toolbarInUnifiedToolBar(QToolBar *toolbar)
+{
+ const QMainWindow *mainWindow = qobject_cast<const QMainWindow *>(toolbar->parentWidget());
+ return mainWindow && mainWindow->unifiedTitleAndToolBarOnMac()
+ && mainWindow->toolBarArea(toolbar) == Qt::TopToolBarArea;
+}
+#endif
+
/*! \reimp */
bool QToolBar::event(QEvent *event)
{
Q_D(QToolBar);
switch (event->type()) {
+ case QEvent::Timer:
+ if (d->waitForPopupTimer.timerId() == static_cast<QTimerEvent*>(event)->timerId()) {
+ QWidget *w = QApplication::activePopupWidget();
+ if (!waitForPopup(this, w)) {
+ d->waitForPopupTimer.stop();
+ if (!this->underMouse())
+ d->layout->setExpanded(false);
+ }
+ }
+ break;
case QEvent::Hide:
if (!isHidden())
break;
// fallthrough intended
case QEvent::Show:
d->toggleViewAction->setChecked(event->type() == QEvent::Show);
-#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)
+#if defined(Q_WS_MAC)
+ if (toolbarInUnifiedToolBar(this)) {
+ // I can static_cast because I did the qobject_cast in the if above, therefore
+ // we must have a QMainWindowLayout here.
+ QMainWindowLayout *mwLayout = static_cast<QMainWindowLayout *>(parentWidget()->layout());
+ mwLayout->fixSizeInUnifiedToolbar(this);
+ mwLayout->syncUnifiedToolbarVisibility();
+ }
+# if !defined(QT_MAC_USE_COCOA)
// Fall through
case QEvent::LayoutRequest: {
// There's currently no way to invalidate the size and let
@@ -1107,10 +1128,9 @@ bool QToolBar::event(QEvent *event)
}
if (needUpdate) {
- OSWindowRef windowRef = qt_mac_window_for(this);
- if (mainWindow->unifiedTitleAndToolBarOnMac()
- && mainWindow->toolBarArea(this) == Qt::TopToolBarArea
- && macWindowToolbarVisible(windowRef)) {
+ OSWindowRef windowRef = qt_mac_window_for(mainWindow);
+ if (toolbarInUnifiedToolBar(this)
+ && macWindowToolbarIsVisible(windowRef)) {
DisableScreenUpdates();
macWindowToolbarShow(this, false);
macWindowToolbarShow(this, true);
@@ -1122,7 +1142,8 @@ bool QToolBar::event(QEvent *event)
return earlyResult;
}
}
-#endif
+# endif // !QT_MAC_USE_COCOA
+#endif // Q_WS_MAC
break;
case QEvent::ParentChange:
d->layout->checkUsePopupMenu();
@@ -1141,6 +1162,10 @@ bool QToolBar::event(QEvent *event)
if (d->mouseReleaseEvent(static_cast<QMouseEvent*>(event)))
return true;
break;
+ case QEvent::HoverEnter:
+ case QEvent::HoverLeave:
+ // there's nothing special to do here and we don't want to update the whole widget
+ return true;
case QEvent::HoverMove: {
#ifndef QT_NO_CURSOR
QHoverEvent *e = static_cast<QHoverEvent*>(event);
@@ -1183,11 +1208,11 @@ bool QToolBar::event(QEvent *event)
QWidget *w = QApplication::activePopupWidget();
if (waitForPopup(this, w)) {
- d->waitForPopupTimer->start();
+ d->waitForPopupTimer.start(POPUP_TIMER_INTERVAL, this);
break;
}
- d->waitForPopupTimer->stop();
+ d->waitForPopupTimer.stop();
d->layout->setExpanded(false);
break;
}
@@ -1197,18 +1222,6 @@ bool QToolBar::event(QEvent *event)
return QWidget::event(event);
}
-void QToolBarPrivate::_q_waitForPopup()
-{
- Q_Q(QToolBar);
-
- QWidget *w = QApplication::activePopupWidget();
- if (!waitForPopup(q, w)) {
- waitForPopupTimer->stop();
- if (!q->underMouse())
- layout->setExpanded(false);
- }
-}
-
/*!
Returns a checkable action that can be used to show or hide this
toolbar.
diff --git a/src/gui/widgets/qtoolbar.h b/src/gui/widgets/qtoolbar.h
index 2ab4ffd..07502b3 100644
--- a/src/gui/widgets/qtoolbar.h
+++ b/src/gui/widgets/qtoolbar.h
@@ -167,7 +167,6 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_toggleView(bool))
Q_PRIVATE_SLOT(d_func(), void _q_updateIconSize(const QSize &))
Q_PRIVATE_SLOT(d_func(), void _q_updateToolButtonStyle(Qt::ToolButtonStyle))
- Q_PRIVATE_SLOT(d_func(), void _q_waitForPopup())
friend class QMainWindow;
friend class QMainWindowLayout;
diff --git a/src/gui/widgets/qtoolbar_p.h b/src/gui/widgets/qtoolbar_p.h
index b03c460..42ea97f 100644
--- a/src/gui/widgets/qtoolbar_p.h
+++ b/src/gui/widgets/qtoolbar_p.h
@@ -56,6 +56,7 @@
#include "qtoolbar.h"
#include "QtGui/qaction.h"
#include "private/qwidget_p.h"
+#include <QtCore/qbasictimer.h>
QT_BEGIN_NAMESPACE
@@ -70,7 +71,7 @@ class QToolBarPrivate : public QWidgetPrivate
public:
inline QToolBarPrivate()
- : explicitIconSize(false), explicitToolButtonStyle(false), movable(false),
+ : explicitIconSize(false), explicitToolButtonStyle(false), movable(true), floatable(true),
allowedAreas(Qt::AllToolBarAreas), orientation(Qt::Horizontal),
toolButtonStyle(Qt::ToolButtonIconOnly),
layout(0), state(0)
@@ -84,16 +85,15 @@ public:
void _q_toggleView(bool b);
void _q_updateIconSize(const QSize &sz);
void _q_updateToolButtonStyle(Qt::ToolButtonStyle style);
- void _q_waitForPopup();
bool explicitIconSize;
bool explicitToolButtonStyle;
bool movable;
+ bool floatable;
Qt::ToolBarAreas allowedAreas;
Qt::Orientation orientation;
Qt::ToolButtonStyle toolButtonStyle;
QSize iconSize;
- bool floatable;
QAction *toggleViewAction;
@@ -125,7 +125,7 @@ public:
void unplug(const QRect &r);
void plug(const QRect &r);
- QTimer *waitForPopupTimer;
+ QBasicTimer waitForPopupTimer;
};
#endif // QT_NO_TOOLBAR
diff --git a/src/gui/widgets/qtoolbararealayout.cpp b/src/gui/widgets/qtoolbararealayout.cpp
index 8a10355..b4a0ef0 100644
--- a/src/gui/widgets/qtoolbararealayout.cpp
+++ b/src/gui/widgets/qtoolbararealayout.cpp
@@ -156,21 +156,15 @@ void QToolBarAreaLayoutLine::fitLayout()
if (item.skip())
continue;
- QToolBarLayout *tblayout = qobject_cast<QToolBarLayout*>(item.widgetItem->widget()->layout());
- if (tblayout)
+ if (QToolBarLayout *tblayout = qobject_cast<QToolBarLayout*>(item.widgetItem->widget()->layout()))
tblayout->checkUsePopupMenu();
- int itemMin = pick(o, item.minimumSize());
- int itemHint = pick(o, item.sizeHint());
- //we ensure the extraspace is not too low
- item.size = qMax(item.size, itemHint);
- if (item.preferredSize > 0) {
- //preferredSize would be the default size
- item.size = item.preferredSize;
- }
+ const int itemMin = pick(o, item.minimumSize());
+ //preferredSize is the default if it is set, otherwise, we take the sizehint
+ item.size = item.preferredSize > 0 ? item.preferredSize : pick(o, item.sizeHint());
//the extraspace is the space above the item minimum sizehint
- int extraSpace = qMin(item.size - itemMin, extra);
+ const int extraSpace = qMin(item.size - itemMin, extra);
item.size = itemMin + extraSpace; //that is the real size
extra -= extraSpace;
@@ -526,9 +520,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 +565,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 +619,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 +926,7 @@ void QToolBarAreaLayout::apply(bool animate)
if (visible && dock.o == Qt::Horizontal)
geo = QStyle::visualRect(dir, line.rect, geo);
- layout->widgetAnimator->animate(widget, geo, animate);
+ layout->widgetAnimator.animate(widget, geo, animate);
}
}
}
@@ -1064,16 +1058,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 +1099,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 +1111,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 +1131,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..1a93b51 100644
--- a/src/gui/widgets/qwidgetanimator.cpp
+++ b/src/gui/widgets/qwidgetanimator.cpp
@@ -39,158 +39,80 @@
**
****************************************************************************/
-#include <QtCore/qtimer.h>
-#include <QtCore/qdatetime.h>
+#include <QtCore/qpropertyanimation.h>
#include <QtGui/qwidget.h>
-#include <QtGui/qtextedit.h>
-#include <QtGui/private/qwidget_p.h>
-#include <qdebug.h>
+#include <QtGui/private/qmainwindowlayout_p.h>
#include "qwidgetanimator_p.h"
QT_BEGIN_NAMESPACE
-static const int g_animation_steps = 12;
-static const int g_animation_interval = 16;
-
-// 1000 * (x/(1 + x*x) + 0.5) on interval [-1, 1]
-static const int g_animate_function[] =
-{
- 0, 1, 5, 12, 23, 38, 58, 84, 116, 155, 199, 251, 307, 368,
- 433, 500, 566, 631, 692, 748, 799, 844, 883, 915, 941, 961,
- 976, 987, 994, 998, 1000
-};
-static const int g_animate_function_points = sizeof(g_animate_function)/sizeof(int);
-
-static inline int animateHelper(int start, int stop, int step, int steps)
-{
- if (start == stop)
- return start;
- if (step == 0)
- return start;
- if (step == steps)
- return stop;
-
- int x = g_animate_function_points*step/(steps + 1);
- return start + g_animate_function[x]*(stop - start)/1000;
-}
-
-QWidgetAnimator::QWidgetAnimator(QObject *parent)
- : QObject(parent)
+QWidgetAnimator::QWidgetAnimator(QMainWindowLayout *layout) : m_mainWindowLayout(layout)
{
- m_time = new QTime();
- m_timer = new QTimer(this);
- m_timer->setInterval(g_animation_interval);
- connect(m_timer, SIGNAL(timeout()), this, SLOT(animationStep()));
}
-QWidgetAnimator::~QWidgetAnimator()
+void QWidgetAnimator::abort(QWidget *w)
{
- delete m_time;
+#ifndef QT_NO_ANIMATION
+ AnimationMap::iterator it = m_animation_map.find(w);
+ if (it == m_animation_map.end())
+ return;
+ QPropertyAnimation *anim = *it;
+ m_animation_map.erase(it);
+ anim->stop();
+ m_mainWindowLayout->animationFinished(w);
+#else
+ Q_UNUSED(w); //there is no animation to abort
+#endif //QT_NO_ANIMATION
}
-void QWidgetAnimator::abort(QWidget *w)
+#ifndef QT_NO_ANIMATION
+void QWidgetAnimator::animationFinished()
{
- if (m_animation_map.remove(w) == 0)
- return;
- if (m_animation_map.isEmpty()) {
- m_timer->stop();
- emit finishedAll();
- }
+ QPropertyAnimation *anim = qobject_cast<QPropertyAnimation*>(sender());
+ abort(static_cast<QWidget*>(anim->targetObject()));
}
+#endif //QT_NO_ANIMATION
void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, bool animate)
{
- QRect final_geometry = _final_geometry;
-
QRect r = widget->geometry();
if (r.right() < 0 || r.bottom() < 0)
r = QRect();
- if (r.isNull() || final_geometry.isNull())
- animate = false;
+ animate = animate && !r.isNull() && !_final_geometry.isNull();
- AnimationMap::const_iterator it = m_animation_map.constFind(widget);
- if (it == m_animation_map.constEnd()) {
- if (r == final_geometry) {
- emit finished(widget);
- return;
- }
- } else {
- if ((*it).r2 == final_geometry)
- return;
- }
-
- if (animate) {
- AnimationItem item(widget, r, final_geometry);
- m_animation_map[widget] = item;
- if (!m_timer->isActive()) {
- m_timer->start();
- m_time->start();
- }
- } else {
- m_animation_map.remove(widget);
- if (m_animation_map.isEmpty())
- m_timer->stop();
-
- if (!final_geometry.isValid() && !widget->isWindow()) {
- // Make the wigdet go away by sending it to negative space
- QSize s = widget->size();
- final_geometry = QRect(-500 - s.width(), -500 - s.height(), s.width(), s.height());
- }
- widget->setGeometry(final_geometry);
-
- emit finished(widget);
-
- if (m_animation_map.isEmpty())
- emit finishedAll();
+ // might make the wigdet go away by sending it to negative space
+ const QRect final_geometry = _final_geometry.isValid() || widget->isWindow() ? _final_geometry :
+ QRect(QPoint(-500 - widget->width(), -500 - widget->height()), widget->size());
+ if (r == final_geometry)
+ return; //the widget is already where it should be
+#ifndef QT_NO_ANIMATION
+ AnimationMap::const_iterator it = m_animation_map.constFind(widget);
+ if (it != m_animation_map.constEnd() && (*it)->endValue().toRect() == final_geometry)
return;
- }
-}
-
-void QWidgetAnimator::animationStep()
-{
- int steps = (1 + m_time->restart())/g_animation_interval;
- AnimationMap::iterator it = m_animation_map.begin();
- while (it != m_animation_map.end()) {
- AnimationItem &item = *it;
-
- item.step = qMin(item.step + steps, g_animation_steps);
-
- int x = animateHelper(item.r1.left(), item.r2.left(),
- item.step, g_animation_steps);
- int y = animateHelper(item.r1.top(), item.r2.top(),
- item.step, g_animation_steps);
- int w = animateHelper(item.r1.width(), item.r2.width(),
- item.step, g_animation_steps);
- int h = animateHelper(item.r1.height(), item.r2.height(),
- item.step, g_animation_steps);
-
- item.widget->setGeometry(x, y, w, h);
-
- if (item.step == g_animation_steps) {
- emit finished(item.widget);
- AnimationMap::iterator tmp = it;
- ++it;
- m_animation_map.erase(tmp);
- } else {
- ++it;
- }
- }
- if (m_animation_map.isEmpty()) {
- m_timer->stop();
- emit finishedAll();
- }
+ QPropertyAnimation *anim = new QPropertyAnimation(widget, "geometry");
+ anim->setDuration(animate ? 200 : 0);
+ anim->setEasingCurve(QEasingCurve::InOutQuad);
+ anim->setEndValue(final_geometry);
+ m_animation_map[widget] = anim;
+ connect(anim, SIGNAL(finished()), SLOT(animationFinished()));
+ anim->start(QPropertyAnimation::DeleteWhenStopped);
+#else
+ //we do it in one shot
+ widget->setGeometry(final_geometry);
+ m_mainWindowLayout->animationFinished(widget);
+#endif //QT_NO_ANIMATION
}
bool QWidgetAnimator::animating() const
{
- return m_timer->isActive();
+ return !m_animation_map.isEmpty();
}
-bool QWidgetAnimator::animating(QWidget *widget)
+bool QWidgetAnimator::animating(QWidget *widget) const
{
return m_animation_map.contains(widget);
}
diff --git a/src/gui/widgets/qwidgetanimator_p.h b/src/gui/widgets/qwidgetanimator_p.h
index 6ee150b..5a3e39d 100644
--- a/src/gui/widgets/qwidgetanimator_p.h
+++ b/src/gui/widgets/qwidgetanimator_p.h
@@ -54,47 +54,35 @@
//
#include <qobject.h>
-#include <qrect.h>
#include <qmap.h>
QT_BEGIN_NAMESPACE
class QWidget;
-class QTimer;
-class QTime;
+class QMainWindowLayout;
+class QPropertyAnimation;
+class QRect;
class QWidgetAnimator : public QObject
{
Q_OBJECT
public:
- QWidgetAnimator(QObject *parent = 0);
- ~QWidgetAnimator();
+ QWidgetAnimator(QMainWindowLayout *layout);
void animate(QWidget *widget, const QRect &final_geometry, bool animate);
bool animating() const;
- bool animating(QWidget *widget);
+ bool animating(QWidget *widget) const;
void abort(QWidget *widget);
-signals:
- void finished(QWidget *widget);
- void finishedAll();
-
-private slots:
- void animationStep();
+#ifndef QT_NO_ANIMATION
+private Q_SLOTS:
+ void animationFinished();
+#endif
private:
- struct AnimationItem {
- AnimationItem(QWidget *_widget = 0, const QRect &_r1 = QRect(),
- const QRect &_r2 = QRect())
- : widget(_widget), r1(_r1), r2(_r2), step(0) {}
- QWidget *widget;
- QRect r1, r2;
- int step;
- };
- typedef QMap<QWidget*, AnimationItem> AnimationMap;
+ typedef QMap<QWidget*, QPropertyAnimation*> AnimationMap;
AnimationMap m_animation_map;
- QTimer *m_timer;
- QTime *m_time;
+ QMainWindowLayout *m_mainWindowLayout;
};
QT_END_NAMESPACE
diff --git a/src/gui/widgets/qworkspace.cpp b/src/gui/widgets/qworkspace.cpp
index 58ef1e3..2833c08 100644
--- a/src/gui/widgets/qworkspace.cpp
+++ b/src/gui/widgets/qworkspace.cpp
@@ -397,21 +397,17 @@ void QWorkspaceTitleBarPrivate::readColors()
pal.setColor(QPalette::Inactive, QPalette::Highlight, colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTION)));
pal.setColor(QPalette::Active, QPalette::HighlightedText, colorref2qrgb(GetSysColor(COLOR_CAPTIONTEXT)));
pal.setColor(QPalette::Inactive, QPalette::HighlightedText, colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTIONTEXT)));
- if (QSysInfo::WindowsVersion != QSysInfo::WV_95 && QSysInfo::WindowsVersion != QSysInfo::WV_NT) {
- colorsInitialized = true;
- BOOL gradient;
- QT_WA({
- SystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, &gradient, 0);
- } , {
- SystemParametersInfoA(SPI_GETGRADIENTCAPTIONS, 0, &gradient, 0);
- });
- if (gradient) {
- pal.setColor(QPalette::Active, QPalette::Base, colorref2qrgb(GetSysColor(COLOR_GRADIENTACTIVECAPTION)));
- pal.setColor(QPalette::Inactive, QPalette::Base, colorref2qrgb(GetSysColor(COLOR_GRADIENTINACTIVECAPTION)));
- } else {
- pal.setColor(QPalette::Active, QPalette::Base, pal.color(QPalette::Active, QPalette::Highlight));
- pal.setColor(QPalette::Inactive, QPalette::Base, pal.color(QPalette::Inactive, QPalette::Highlight));
- }
+
+ colorsInitialized = true;
+ BOOL gradient = false;
+ SystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, &gradient, 0);
+
+ if (gradient) {
+ pal.setColor(QPalette::Active, QPalette::Base, colorref2qrgb(GetSysColor(COLOR_GRADIENTACTIVECAPTION)));
+ pal.setColor(QPalette::Inactive, QPalette::Base, colorref2qrgb(GetSysColor(COLOR_GRADIENTINACTIVECAPTION)));
+ } else {
+ pal.setColor(QPalette::Active, QPalette::Base, pal.color(QPalette::Active, QPalette::Highlight));
+ pal.setColor(QPalette::Inactive, QPalette::Base, pal.color(QPalette::Inactive, QPalette::Highlight));
}
}
#endif // Q_WS_WIN
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 \