summaryrefslogtreecommitdiffstats
path: root/src/gui/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/widgets')
-rw-r--r--src/gui/widgets/qabstractbutton.h2
-rw-r--r--src/gui/widgets/qabstractscrollarea.cpp37
-rw-r--r--src/gui/widgets/qabstractscrollarea.h2
-rw-r--r--src/gui/widgets/qabstractscrollarea_p.h9
-rw-r--r--src/gui/widgets/qabstractslider.h2
-rw-r--r--src/gui/widgets/qabstractspinbox.cpp13
-rw-r--r--src/gui/widgets/qabstractspinbox.h2
-rw-r--r--src/gui/widgets/qactiontokeyeventmapper.cpp4
-rw-r--r--src/gui/widgets/qactiontokeyeventmapper_p.h4
-rw-r--r--src/gui/widgets/qbuttongroup.h2
-rw-r--r--src/gui/widgets/qcalendarwidget.h2
-rw-r--r--src/gui/widgets/qcheckbox.h2
-rw-r--r--src/gui/widgets/qcocoamenu_mac.mm4
-rw-r--r--src/gui/widgets/qcocoatoolbardelegate_mac.mm10
-rw-r--r--src/gui/widgets/qcombobox.cpp6
-rw-r--r--src/gui/widgets/qcombobox.h2
-rw-r--r--src/gui/widgets/qcommandlinkbutton.h2
-rw-r--r--src/gui/widgets/qdatetimeedit.cpp14
-rw-r--r--src/gui/widgets/qdatetimeedit.h2
-rw-r--r--src/gui/widgets/qdial.h2
-rw-r--r--src/gui/widgets/qdialogbuttonbox.h2
-rw-r--r--src/gui/widgets/qdockarealayout.cpp14
-rw-r--r--src/gui/widgets/qdockwidget.h2
-rw-r--r--src/gui/widgets/qeffects.cpp96
-rw-r--r--src/gui/widgets/qfocusframe.h2
-rw-r--r--src/gui/widgets/qfontcombobox.cpp2
-rw-r--r--src/gui/widgets/qfontcombobox.h2
-rw-r--r--src/gui/widgets/qframe.cpp2
-rw-r--r--src/gui/widgets/qframe.h2
-rw-r--r--src/gui/widgets/qgroupbox.cpp11
-rw-r--r--src/gui/widgets/qgroupbox.h2
-rw-r--r--src/gui/widgets/qlabel.h2
-rw-r--r--src/gui/widgets/qlcdnumber.h2
-rw-r--r--src/gui/widgets/qlinecontrol.cpp1750
-rw-r--r--src/gui/widgets/qlinecontrol_p.h741
-rw-r--r--src/gui/widgets/qlineedit.cpp1905
-rw-r--r--src/gui/widgets/qlineedit.h4
-rw-r--r--src/gui/widgets/qlineedit_p.cpp253
-rw-r--r--src/gui/widgets/qlineedit_p.h176
-rw-r--r--src/gui/widgets/qmaccocoaviewcontainer_mac.h2
-rw-r--r--src/gui/widgets/qmacnativewidget_mac.h2
-rw-r--r--src/gui/widgets/qmainwindow.cpp13
-rw-r--r--src/gui/widgets/qmainwindow.h2
-rw-r--r--src/gui/widgets/qmainwindowlayout.cpp276
-rw-r--r--src/gui/widgets/qmainwindowlayout_mac.mm31
-rw-r--r--src/gui/widgets/qmainwindowlayout_p.h25
-rw-r--r--src/gui/widgets/qmdiarea.h2
-rw-r--r--src/gui/widgets/qmdisubwindow.cpp37
-rw-r--r--src/gui/widgets/qmdisubwindow.h2
-rw-r--r--src/gui/widgets/qmenu.cpp130
-rw-r--r--src/gui/widgets/qmenu.h2
-rw-r--r--src/gui/widgets/qmenu_mac.mm89
-rw-r--r--src/gui/widgets/qmenu_p.h14
-rw-r--r--src/gui/widgets/qmenu_symbian.cpp6
-rw-r--r--src/gui/widgets/qmenubar.cpp30
-rw-r--r--src/gui/widgets/qmenubar.h2
-rw-r--r--src/gui/widgets/qplaintextedit.cpp37
-rw-r--r--src/gui/widgets/qplaintextedit.h5
-rw-r--r--src/gui/widgets/qplaintextedit_p.h5
-rw-r--r--src/gui/widgets/qprintpreviewwidget.h2
-rw-r--r--src/gui/widgets/qprogressbar.cpp17
-rw-r--r--src/gui/widgets/qprogressbar.h2
-rw-r--r--src/gui/widgets/qpushbutton.h2
-rw-r--r--src/gui/widgets/qradiobutton.h2
-rw-r--r--src/gui/widgets/qrubberband.h2
-rw-r--r--src/gui/widgets/qscrollarea.h2
-rw-r--r--src/gui/widgets/qscrollbar.h2
-rw-r--r--src/gui/widgets/qsizegrip.cpp3
-rw-r--r--src/gui/widgets/qsizegrip.h2
-rw-r--r--src/gui/widgets/qslider.h2
-rw-r--r--src/gui/widgets/qspinbox.cpp11
-rw-r--r--src/gui/widgets/qspinbox.h4
-rw-r--r--src/gui/widgets/qsplashscreen.h2
-rw-r--r--src/gui/widgets/qsplitter.h4
-rw-r--r--src/gui/widgets/qstackedwidget.h2
-rw-r--r--src/gui/widgets/qstatusbar.h2
-rw-r--r--src/gui/widgets/qtabbar.cpp76
-rw-r--r--src/gui/widgets/qtabbar.h4
-rw-r--r--src/gui/widgets/qtabbar_p.h68
-rw-r--r--src/gui/widgets/qtabwidget.h2
-rw-r--r--src/gui/widgets/qtextbrowser.h2
-rw-r--r--src/gui/widgets/qtextedit.cpp26
-rw-r--r--src/gui/widgets/qtextedit.h3
-rw-r--r--src/gui/widgets/qtextedit_p.h5
-rw-r--r--src/gui/widgets/qtoolbar.cpp71
-rw-r--r--src/gui/widgets/qtoolbar.h3
-rw-r--r--src/gui/widgets/qtoolbar_p.h8
-rw-r--r--src/gui/widgets/qtoolbararealayout.cpp18
-rw-r--r--src/gui/widgets/qtoolbox.h2
-rw-r--r--src/gui/widgets/qtoolbutton.cpp15
-rw-r--r--src/gui/widgets/qtoolbutton.h2
-rw-r--r--src/gui/widgets/qvalidator.h8
-rw-r--r--src/gui/widgets/qwidgetanimator.cpp164
-rw-r--r--src/gui/widgets/qwidgetanimator_p.h34
-rw-r--r--src/gui/widgets/qworkspace.cpp34
-rw-r--r--src/gui/widgets/qworkspace.h2
-rw-r--r--src/gui/widgets/widgets.pri3
97 files changed, 3800 insertions, 2618 deletions
diff --git a/src/gui/widgets/qabstractbutton.h b/src/gui/widgets/qabstractbutton.h
index 9e33479..29e9bf9 100644
--- a/src/gui/widgets/qabstractbutton.h
+++ b/src/gui/widgets/qabstractbutton.h
@@ -168,7 +168,7 @@ protected:
QAbstractButton(QAbstractButtonPrivate &dd, QWidget* parent = 0);
private:
- Q_DECLARE_SCOPED_PRIVATE(QAbstractButton)
+ Q_DECLARE_PRIVATE(QAbstractButton)
Q_DISABLE_COPY(QAbstractButton)
friend class QButtonGroup;
};
diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/gui/widgets/qabstractscrollarea.cpp
index a00f77a..391e095 100644
--- a/src/gui/widgets/qabstractscrollarea.cpp
+++ b/src/gui/widgets/qabstractscrollarea.cpp
@@ -51,10 +51,13 @@
#include "qdebug.h"
#include "qboxlayout.h"
#include "qpainter.h"
+#include "qstandardgestures.h"
#include "qabstractscrollarea_p.h"
#include <qwidget.h>
+#include <private/qapplication_p.h>
+
#ifdef Q_WS_MAC
#include <private/qt_mac_p.h>
#include <private/qt_cocoa_helpers_mac_p.h>
@@ -157,6 +160,9 @@ QAbstractScrollAreaPrivate::QAbstractScrollAreaPrivate()
:hbar(0), vbar(0), vbarpolicy(Qt::ScrollBarAsNeeded), hbarpolicy(Qt::ScrollBarAsNeeded),
viewport(0), cornerWidget(0), left(0), top(0), right(0), bottom(0),
xoffset(0), yoffset(0), viewportFilter(0)
+#ifdef Q_WS_WIN
+ , singleFingerPanEnabled(false)
+#endif
{
}
@@ -290,6 +296,32 @@ void QAbstractScrollAreaPrivate::init()
layoutChildren();
}
+void QAbstractScrollAreaPrivate::setupGestures()
+{
+#ifdef Q_OS_WIN
+ if (!viewport)
+ return;
+ QApplicationPrivate* getQApplicationPrivateInternal();
+ QApplicationPrivate *qAppPriv = getQApplicationPrivateInternal();
+ bool needh = (hbarpolicy == Qt::ScrollBarAlwaysOn
+ || (hbarpolicy == Qt::ScrollBarAsNeeded && hbar->minimum() < hbar->maximum()));
+
+ bool needv = (vbarpolicy == Qt::ScrollBarAlwaysOn
+ || (vbarpolicy == Qt::ScrollBarAsNeeded && vbar->minimum() < vbar->maximum()));
+ if (qAppPriv->SetGestureConfig && (needh || needv)) {
+ GESTURECONFIG gc[1];
+ gc[0].dwID = GID_PAN;
+ gc[0].dwWant = GC_PAN;
+ gc[0].dwBlock = 0;
+ if (needv && singleFingerPanEnabled)
+ gc[0].dwWant |= GC_PAN_WITH_SINGLE_FINGER_VERTICALLY;
+ if (needh && singleFingerPanEnabled)
+ gc[0].dwWant |= GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY;
+ qAppPriv->SetGestureConfig(viewport->winId(), 0, 1, gc, sizeof(gc));
+ }
+#endif // Q_OS_WIN
+}
+
void QAbstractScrollAreaPrivate::layoutChildren()
{
Q_Q(QAbstractScrollArea);
@@ -459,9 +491,6 @@ void QAbstractScrollAreaPrivate::layoutChildren()
viewport->setGeometry(QStyle::visualRect(opt.direction, opt.rect, viewportRect)); // resize the viewport last
}
-// ### Fix for 4.4, talk to Bjoern E or Girish.
-void QAbstractScrollAreaPrivate::scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy) {}
-
/*!
\internal
@@ -920,7 +949,6 @@ bool QAbstractScrollArea::event(QEvent *e)
case QEvent::DragMove:
case QEvent::DragLeave:
#endif
- case QEvent::Gesture:
return false;
case QEvent::StyleChange:
case QEvent::LayoutDirectionChange:
@@ -1250,6 +1278,7 @@ void QAbstractScrollAreaPrivate::_q_vslide(int y)
void QAbstractScrollAreaPrivate::_q_showOrHideScrollBars()
{
layoutChildren();
+ setupGestures();
}
QPoint QAbstractScrollAreaPrivate::contentsOffset() const
diff --git a/src/gui/widgets/qabstractscrollarea.h b/src/gui/widgets/qabstractscrollarea.h
index 9a7e844..3ec41d1 100644
--- a/src/gui/widgets/qabstractscrollarea.h
+++ b/src/gui/widgets/qabstractscrollarea.h
@@ -123,7 +123,7 @@ protected:
virtual void scrollContentsBy(int dx, int dy);
private:
- Q_DECLARE_SCOPED_PRIVATE(QAbstractScrollArea)
+ Q_DECLARE_PRIVATE(QAbstractScrollArea)
Q_DISABLE_COPY(QAbstractScrollArea)
Q_PRIVATE_SLOT(d_func(), void _q_hslide(int))
Q_PRIVATE_SLOT(d_func(), void _q_vslide(int))
diff --git a/src/gui/widgets/qabstractscrollarea_p.h b/src/gui/widgets/qabstractscrollarea_p.h
index 3a5ee4e..f8ea843 100644
--- a/src/gui/widgets/qabstractscrollarea_p.h
+++ b/src/gui/widgets/qabstractscrollarea_p.h
@@ -62,7 +62,7 @@ QT_BEGIN_NAMESPACE
class QScrollBar;
class QAbstractScrollAreaScrollBarContainer;
-class QAbstractScrollAreaPrivate: public QFramePrivate
+class Q_AUTOTEST_EXPORT QAbstractScrollAreaPrivate: public QFramePrivate
{
Q_DECLARE_PUBLIC(QAbstractScrollArea)
@@ -88,7 +88,7 @@ public:
void init();
void layoutChildren();
// ### Fix for 4.4, talk to Bjoern E or Girish.
- virtual void scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy);
+ virtual void scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy) {}
void _q_hslide(int);
void _q_vslide(int);
@@ -99,6 +99,11 @@ public:
inline bool viewportEvent(QEvent *event)
{ return q_func()->viewportEvent(event); }
QScopedPointer<QObject> viewportFilter;
+
+#ifdef Q_WS_WIN
+ bool singleFingerPanEnabled;
+#endif
+ void setupGestures();
};
class QAbstractScrollAreaFilter : public QObject
diff --git a/src/gui/widgets/qabstractslider.h b/src/gui/widgets/qabstractslider.h
index 6517944..7e03b6e 100644
--- a/src/gui/widgets/qabstractslider.h
+++ b/src/gui/widgets/qabstractslider.h
@@ -174,7 +174,7 @@ protected:
private:
Q_DISABLE_COPY(QAbstractSlider)
- Q_DECLARE_SCOPED_PRIVATE(QAbstractSlider)
+ Q_DECLARE_PRIVATE(QAbstractSlider)
};
QT_END_NAMESPACE
diff --git a/src/gui/widgets/qabstractspinbox.cpp b/src/gui/widgets/qabstractspinbox.cpp
index 155fe3e..bcc5c92 100644
--- a/src/gui/widgets/qabstractspinbox.cpp
+++ b/src/gui/widgets/qabstractspinbox.cpp
@@ -57,6 +57,9 @@
#include <qpalette.h>
#include <qstylepainter.h>
#include <qdebug.h>
+#ifndef QT_NO_ACCESSIBILITY
+# include <qaccessible.h>
+#endif
#if defined(Q_WS_X11)
#include <limits.h>
@@ -962,6 +965,9 @@ void QAbstractSpinBox::keyPressEvent(QKeyEvent *event)
d->buttonState = (Keyboard | (up ? Up : Down));
}
stepBy(steps);
+#ifndef QT_NO_ACCESSIBILITY
+ QAccessible::updateAccessibility(this, 0, QAccessible::ValueChanged);
+#endif
return;
}
#ifdef QT_KEYPAD_NAVIGATION
@@ -981,7 +987,7 @@ void QAbstractSpinBox::keyPressEvent(QKeyEvent *event)
#endif
case Qt::Key_Enter:
case Qt::Key_Return:
- d->edit->d_func()->modifiedState = d->edit->d_func()->undoState = 0;
+ d->edit->d_func()->control->clearUndo();
d->interpret(d->keyboardTracking ? AlwaysEmit : EmitIfChanged);
selectAll();
event->ignore();
@@ -1559,6 +1565,9 @@ void QAbstractSpinBoxPrivate::updateState(bool up)
spinClickThresholdTimerId = q->startTimer(spinClickThresholdTimerInterval);
buttonState = (up ? (Mouse | Up) : (Mouse | Down));
q->stepBy(up ? 1 : -1);
+#ifndef QT_NO_ACCESSIBILITY
+ QAccessible::updateAccessibility(q, 0, QAccessible::ValueChanged);
+#endif
}
}
@@ -1579,7 +1588,7 @@ void QAbstractSpinBox::initStyleOption(QStyleOptionSpinBox *option) const
option->initFrom(this);
option->activeSubControls = QStyle::SC_None;
option->buttonSymbols = d->buttonSymbols;
- option->subControls = QStyle::SC_SpinBoxFrame;
+ option->subControls = QStyle::SC_SpinBoxFrame | QStyle::SC_SpinBoxEditField;
if (d->buttonSymbols != QAbstractSpinBox::NoButtons) {
option->subControls |= QStyle::SC_SpinBoxUp | QStyle::SC_SpinBoxDown;
if (d->buttonState & Up) {
diff --git a/src/gui/widgets/qabstractspinbox.h b/src/gui/widgets/qabstractspinbox.h
index 2e8f7f9..e65f27b 100644
--- a/src/gui/widgets/qabstractspinbox.h
+++ b/src/gui/widgets/qabstractspinbox.h
@@ -165,7 +165,7 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_editorTextChanged(const QString &))
Q_PRIVATE_SLOT(d_func(), void _q_editorCursorPositionChanged(int, int))
- Q_DECLARE_SCOPED_PRIVATE(QAbstractSpinBox)
+ Q_DECLARE_PRIVATE(QAbstractSpinBox)
Q_DISABLE_COPY(QAbstractSpinBox)
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QAbstractSpinBox::StepEnabled)
diff --git a/src/gui/widgets/qactiontokeyeventmapper.cpp b/src/gui/widgets/qactiontokeyeventmapper.cpp
index 280b1c6..0e1e1bb 100644
--- a/src/gui/widgets/qactiontokeyeventmapper.cpp
+++ b/src/gui/widgets/qactiontokeyeventmapper.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: Qt Software Information (qt-info@nokia.com)
+** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtGui module of the Qt Toolkit.
**
@@ -34,7 +34,7 @@
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you are unsure which license is appropriate for your use, please
-** contact the sales department at qt-sales@nokia.com.
+** contact the sales department at http://www.qtsoftware.com/contact.
** $QT_END_LICENSE$
**
****************************************************************************/
diff --git a/src/gui/widgets/qactiontokeyeventmapper_p.h b/src/gui/widgets/qactiontokeyeventmapper_p.h
index c54e612..57b81af 100644
--- a/src/gui/widgets/qactiontokeyeventmapper_p.h
+++ b/src/gui/widgets/qactiontokeyeventmapper_p.h
@@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: Qt Software Information (qt-info@nokia.com)
+** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtGui module of the Qt Toolkit.
**
@@ -34,7 +34,7 @@
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you are unsure which license is appropriate for your use, please
-** contact the sales department at qt-sales@nokia.com.
+** contact the sales department at http://www.qtsoftware.com/contact.
** $QT_END_LICENSE$
**
****************************************************************************/
diff --git a/src/gui/widgets/qbuttongroup.h b/src/gui/widgets/qbuttongroup.h
index fca1524..708c91c 100644
--- a/src/gui/widgets/qbuttongroup.h
+++ b/src/gui/widgets/qbuttongroup.h
@@ -98,7 +98,7 @@ public:
private:
Q_DISABLE_COPY(QButtonGroup)
- Q_DECLARE_SCOPED_PRIVATE(QButtonGroup)
+ Q_DECLARE_PRIVATE(QButtonGroup)
friend class QAbstractButton;
friend class QAbstractButtonPrivate;
};
diff --git a/src/gui/widgets/qcalendarwidget.h b/src/gui/widgets/qcalendarwidget.h
index edd1511..f567180 100644
--- a/src/gui/widgets/qcalendarwidget.h
+++ b/src/gui/widgets/qcalendarwidget.h
@@ -179,7 +179,7 @@ Q_SIGNALS:
void currentPageChanged(int year, int month);
private:
- Q_DECLARE_SCOPED_PRIVATE(QCalendarWidget)
+ Q_DECLARE_PRIVATE(QCalendarWidget)
Q_DISABLE_COPY(QCalendarWidget)
Q_PRIVATE_SLOT(d_func(), void _q_slotShowDate(const QDate &date))
diff --git a/src/gui/widgets/qcheckbox.h b/src/gui/widgets/qcheckbox.h
index cd41626..1d61783 100644
--- a/src/gui/widgets/qcheckbox.h
+++ b/src/gui/widgets/qcheckbox.h
@@ -102,7 +102,7 @@ public:
#endif
private:
- Q_DECLARE_SCOPED_PRIVATE(QCheckBox)
+ Q_DECLARE_PRIVATE(QCheckBox)
Q_DISABLE_COPY(QCheckBox)
};
diff --git a/src/gui/widgets/qcocoamenu_mac.mm b/src/gui/widgets/qcocoamenu_mac.mm
index 3338fd8..f3bb73e 100644
--- a/src/gui/widgets/qcocoamenu_mac.mm
+++ b/src/gui/widgets/qcocoamenu_mac.mm
@@ -98,7 +98,9 @@ QT_USE_NAMESPACE
while (QWidget *popup
= QApplication::activePopupWidget())
popup->close();
- qt_mac_emit_menuSignals(((QT_MANGLE_NAMESPACE(QCocoaMenu) *)menu)->qmenu, true);
+ QMenu *qtmenu = static_cast<QT_MANGLE_NAMESPACE(QCocoaMenu) *>(menu)->qmenu;
+ qt_mac_emit_menuSignals(qtmenu, true);
+ qt_mac_menu_collapseSeparators(menu, qtmenu->separatorsCollapsible());
}
- (void)menuWillClose:(NSMenu*)menu;
diff --git a/src/gui/widgets/qcocoatoolbardelegate_mac.mm b/src/gui/widgets/qcocoatoolbardelegate_mac.mm
index 894028e..10fe9b0 100644
--- a/src/gui/widgets/qcocoatoolbardelegate_mac.mm
+++ b/src/gui/widgets/qcocoatoolbardelegate_mac.mm
@@ -43,6 +43,7 @@
#ifdef QT_MAC_USE_COCOA
#include <private/qmainwindowlayout_p.h>
#include <private/qt_mac_p.h>
+#include <private/qt_cocoa_helpers_mac_p.h>
#include <private/qcocoaview_mac_p.h>
#include <private/qwidget_p.h>
#include <qtoolbar.h>
@@ -99,7 +100,7 @@ QT_FORWARD_DECLARE_CLASS(QCFString);
{
Q_UNUSED(flag);
Q_UNUSED(nstoolbar);
- QToolBar *tb = mainWindowLayout->cocoaItemIDToToolbarHash.value(QCFString::toQString(CFStringRef(itemIdentifier)));
+ QToolBar *tb = mainWindowLayout->cocoaItemIDToToolbarHash.value(qt_mac_NSStringToQString(itemIdentifier));
NSToolbarItem *item = nil;
if (tb) {
item = [[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier];
@@ -111,7 +112,7 @@ QT_FORWARD_DECLARE_CLASS(QCFString);
- (void)toolbarWillAddItem:(NSNotification *)notification
{
NSToolbarItem *item = [[notification userInfo] valueForKey:@"item"];
- QToolBar *tb = mainWindowLayout->cocoaItemIDToToolbarHash.value(QCFString::toQString(CFStringRef([item itemIdentifier])));
+ QToolBar *tb = mainWindowLayout->cocoaItemIDToToolbarHash.value(qt_mac_NSStringToQString([item itemIdentifier]));
if (!tb)
return; // I can't really do anything about this.
[item retain];
@@ -119,12 +120,9 @@ QT_FORWARD_DECLARE_CLASS(QCFString);
NSArray *items = [[qt_mac_window_for(mainWindowLayout->layoutState.mainWindow->window()) toolbar] items];
int someIndex = 0;
- bool foundItem = false;
for (NSToolbarItem *i in items) {
- if (i == item) {
- foundItem = true;
+ if (i == item)
break;
- }
++someIndex;
}
mainWindowLayout->toolbarItemsCopy.insert(someIndex, item);
diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp
index 65a4279..c4f81d4 100644
--- a/src/gui/widgets/qcombobox.cpp
+++ b/src/gui/widgets/qcombobox.cpp
@@ -148,8 +148,10 @@ QStyleOptionMenuItem QComboMenuDelegate::getStyleOption(const QStyleOptionViewIt
menuOption.rect = option.rect;
// Make sure fonts set on the combo box also overrides the font for the popup menu.
- if (mCombo->testAttribute(Qt::WA_SetFont) || mCombo->testAttribute(Qt::WA_MacSmallSize)
- || mCombo->testAttribute(Qt::WA_MacMiniSize))
+ if (mCombo->testAttribute(Qt::WA_SetFont)
+ || mCombo->testAttribute(Qt::WA_MacSmallSize)
+ || mCombo->testAttribute(Qt::WA_MacMiniSize)
+ || mCombo->font() != qt_app_fonts_hash()->value("QComboBox", QFont()))
menuOption.font = mCombo->font();
else
menuOption.font = qt_app_fonts_hash()->value("QComboMenuItem", mCombo->font());
diff --git a/src/gui/widgets/qcombobox.h b/src/gui/widgets/qcombobox.h
index 2807a4f..22f6928 100644
--- a/src/gui/widgets/qcombobox.h
+++ b/src/gui/widgets/qcombobox.h
@@ -300,7 +300,7 @@ protected:
QComboBox(QComboBoxPrivate &, QWidget *);
private:
- Q_DECLARE_SCOPED_PRIVATE(QComboBox)
+ Q_DECLARE_PRIVATE(QComboBox)
Q_DISABLE_COPY(QComboBox)
Q_PRIVATE_SLOT(d_func(), void _q_itemSelected(const QModelIndex &item))
Q_PRIVATE_SLOT(d_func(), void _q_emitHighlighted(const QModelIndex &))
diff --git a/src/gui/widgets/qcommandlinkbutton.h b/src/gui/widgets/qcommandlinkbutton.h
index 5191252..bf30242 100644
--- a/src/gui/widgets/qcommandlinkbutton.h
+++ b/src/gui/widgets/qcommandlinkbutton.h
@@ -75,7 +75,7 @@ protected:
private:
Q_DISABLE_COPY(QCommandLinkButton)
- Q_DECLARE_SCOPED_PRIVATE(QCommandLinkButton)
+ Q_DECLARE_PRIVATE(QCommandLinkButton)
};
QT_END_NAMESPACE
diff --git a/src/gui/widgets/qdatetimeedit.cpp b/src/gui/widgets/qdatetimeedit.cpp
index 648847a..1533edb 100644
--- a/src/gui/widgets/qdatetimeedit.cpp
+++ b/src/gui/widgets/qdatetimeedit.cpp
@@ -1086,10 +1086,7 @@ void QDateTimeEdit::keyPressEvent(QKeyEvent *event)
//hide cursor
d->edit->d_func()->setCursorVisible(false);
- if (d->edit->d_func()->cursorTimer > 0)
- killTimer(d->edit->d_func()->cursorTimer);
- d->edit->d_func()->cursorTimer = 0;
-
+ d->edit->d_func()->control->setCursorBlinkPeriod(0);
d->setSelected(0);
}
}
@@ -1110,10 +1107,7 @@ void QDateTimeEdit::keyPressEvent(QKeyEvent *event)
//hide cursor
d->edit->d_func()->setCursorVisible(false);
- if (d->edit->d_func()->cursorTimer > 0)
- killTimer(d->edit->d_func()->cursorTimer);
- d->edit->d_func()->cursorTimer = 0;
-
+ d->edit->d_func()->control->setCursorBlinkPeriod(0);
d->setSelected(0);
oldCurrent = 0;
}
@@ -1936,7 +1930,6 @@ QDateTime QDateTimeEditPrivate::validateAndInterpret(QString &input, int &positi
/*!
\internal
- \reimp
*/
QString QDateTimeEditPrivate::textFromValue(const QVariant &f) const
@@ -1947,7 +1940,6 @@ QString QDateTimeEditPrivate::textFromValue(const QVariant &f) const
/*!
\internal
- \reimp
This function's name is slightly confusing; it is not to be confused
with QAbstractSpinBox::valueFromText().
@@ -2105,7 +2097,6 @@ QDateTime QDateTimeEditPrivate::stepBy(int sectionIndex, int steps, bool test) c
/*!
\internal
- \reimp
*/
void QDateTimeEditPrivate::emitSignals(EmitPolicy ep, const QVariant &old)
@@ -2135,7 +2126,6 @@ void QDateTimeEditPrivate::emitSignals(EmitPolicy ep, const QVariant &old)
/*!
\internal
- \reimp
*/
void QDateTimeEditPrivate::_q_editorCursorPositionChanged(int oldpos, int newpos)
diff --git a/src/gui/widgets/qdatetimeedit.h b/src/gui/widgets/qdatetimeedit.h
index 1e4c621..e43a3fa 100644
--- a/src/gui/widgets/qdatetimeedit.h
+++ b/src/gui/widgets/qdatetimeedit.h
@@ -197,7 +197,7 @@ protected:
QDateTimeEdit(const QVariant &val, QVariant::Type parserType, QWidget *parent = 0);
private:
- Q_DECLARE_SCOPED_PRIVATE(QDateTimeEdit)
+ Q_DECLARE_PRIVATE(QDateTimeEdit)
Q_DISABLE_COPY(QDateTimeEdit)
Q_PRIVATE_SLOT(d_func(), void _q_resetButton())
diff --git a/src/gui/widgets/qdial.h b/src/gui/widgets/qdial.h
index f07999b..91b8c5e 100644
--- a/src/gui/widgets/qdial.h
+++ b/src/gui/widgets/qdial.h
@@ -109,7 +109,7 @@ Q_SIGNALS:
#endif
private:
- Q_DECLARE_SCOPED_PRIVATE(QDial)
+ Q_DECLARE_PRIVATE(QDial)
Q_DISABLE_COPY(QDial)
};
diff --git a/src/gui/widgets/qdialogbuttonbox.h b/src/gui/widgets/qdialogbuttonbox.h
index 97a6a59..df40a66 100644
--- a/src/gui/widgets/qdialogbuttonbox.h
+++ b/src/gui/widgets/qdialogbuttonbox.h
@@ -154,7 +154,7 @@ protected:
private:
Q_DISABLE_COPY(QDialogButtonBox)
- Q_DECLARE_SCOPED_PRIVATE(QDialogButtonBox)
+ Q_DECLARE_PRIVATE(QDialogButtonBox)
Q_PRIVATE_SLOT(d_func(), void _q_handleButtonClicked())
Q_PRIVATE_SLOT(d_func(), void _q_handleButtonDestroyed())
};
diff --git a/src/gui/widgets/qdockarealayout.cpp b/src/gui/widgets/qdockarealayout.cpp
index 9828413..ee29b55 100644
--- a/src/gui/widgets/qdockarealayout.cpp
+++ b/src/gui/widgets/qdockarealayout.cpp
@@ -1488,7 +1488,7 @@ bool QDockAreaLayoutInfo::hasFixedSize() const
void QDockAreaLayoutInfo::apply(bool animate)
{
- QWidgetAnimator *widgetAnimator = mainWindowLayout()->widgetAnimator;
+ QWidgetAnimator &widgetAnimator = mainWindowLayout()->widgetAnimator;
#ifndef QT_NO_TABBAR
if (tabbed) {
@@ -1521,7 +1521,7 @@ void QDockAreaLayoutInfo::apply(bool animate)
}
}
- widgetAnimator->animate(tabBar, tab_rect, animate);
+ widgetAnimator.animate(tabBar, tab_rect, animate);
}
#endif // QT_NO_TABBAR
@@ -1544,7 +1544,7 @@ void QDockAreaLayoutInfo::apply(bool animate)
QWidget *w = item.widgetItem->widget();
QRect geo = w->geometry();
- widgetAnimator->animate(w, r, animate);
+ widgetAnimator.animate(w, r, animate);
if (!w->isHidden()) {
QDockWidget *dw = qobject_cast<QDockWidget*>(w);
if (!r.isValid() && geo.right() >= 0 && geo.bottom() >= 0) {
@@ -1707,7 +1707,7 @@ QDockAreaLayoutItem &QDockAreaLayoutInfo::item(const QList<int> &path)
Q_ASSERT(!path.isEmpty());
const int index = path.first();
if (path.count() > 1) {
- const QDockAreaLayoutItem &item = item_list.at(index);
+ const QDockAreaLayoutItem &item = item_list[index];
Q_ASSERT(item.subinfo != 0);
return item.subinfo->item(path.mid(1));
}
@@ -2074,7 +2074,7 @@ void QDockAreaLayoutInfo::updateTabBar() const
QDockAreaLayoutInfo *that = const_cast<QDockAreaLayoutInfo*>(this);
- if (tabBar == 0) {
+ if (that->tabBar == 0) {
that->tabBar = mainWindowLayout()->getTabBar();
that->tabBar->setShape(static_cast<QTabBar::Shape>(tabBarShape));
that->tabBar->setDrawBase(true);
@@ -3064,13 +3064,13 @@ void QDockAreaLayout::splitDockWidget(QDockWidget *after,
void QDockAreaLayout::apply(bool animate)
{
- QWidgetAnimator *widgetAnimator
+ QWidgetAnimator &widgetAnimator
= qobject_cast<QMainWindowLayout*>(mainWindow->layout())->widgetAnimator;
for (int i = 0; i < QInternal::DockCount; ++i)
docks[i].apply(animate);
if (centralWidgetItem != 0 && !centralWidgetItem->isEmpty()) {
- widgetAnimator->animate(centralWidgetItem->widget(), centralWidgetRect,
+ widgetAnimator.animate(centralWidgetItem->widget(), centralWidgetRect,
animate);
}
diff --git a/src/gui/widgets/qdockwidget.h b/src/gui/widgets/qdockwidget.h
index b1abbdd..f0c0b46 100644
--- a/src/gui/widgets/qdockwidget.h
+++ b/src/gui/widgets/qdockwidget.h
@@ -124,7 +124,7 @@ protected:
void initStyleOption(QStyleOptionDockWidget *option) const;
private:
- Q_DECLARE_SCOPED_PRIVATE(QDockWidget)
+ Q_DECLARE_PRIVATE(QDockWidget)
Q_DISABLE_COPY(QDockWidget)
Q_PRIVATE_SLOT(d_func(), void _q_toggleView(bool))
Q_PRIVATE_SLOT(d_func(), void _q_toggleTopLevel())
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/qfocusframe.h b/src/gui/widgets/qfocusframe.h
index e496343..139374c 100644
--- a/src/gui/widgets/qfocusframe.h
+++ b/src/gui/widgets/qfocusframe.h
@@ -71,7 +71,7 @@ protected:
void initStyleOption(QStyleOption *option) const;
private:
- Q_DECLARE_SCOPED_PRIVATE(QFocusFrame)
+ Q_DECLARE_PRIVATE(QFocusFrame)
Q_DISABLE_COPY(QFocusFrame)
};
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/qfontcombobox.h b/src/gui/widgets/qfontcombobox.h
index 41f9d72..6034881 100644
--- a/src/gui/widgets/qfontcombobox.h
+++ b/src/gui/widgets/qfontcombobox.h
@@ -97,7 +97,7 @@ protected:
private:
Q_DISABLE_COPY(QFontComboBox)
- Q_DECLARE_SCOPED_PRIVATE(QFontComboBox)
+ Q_DECLARE_PRIVATE(QFontComboBox)
Q_PRIVATE_SLOT(d_func(), void _q_currentChanged(const QString &))
Q_PRIVATE_SLOT(d_func(), void _q_updateModel())
};
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/qframe.h b/src/gui/widgets/qframe.h
index f8776c6..7b6073b 100644
--- a/src/gui/widgets/qframe.h
+++ b/src/gui/widgets/qframe.h
@@ -138,7 +138,7 @@ protected:
private:
Q_DISABLE_COPY(QFrame)
- Q_DECLARE_SCOPED_PRIVATE(QFrame)
+ Q_DECLARE_PRIVATE(QFrame)
};
QT_END_NAMESPACE
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/qgroupbox.h b/src/gui/widgets/qgroupbox.h
index c4bef6e..d3f76e1 100644
--- a/src/gui/widgets/qgroupbox.h
+++ b/src/gui/widgets/qgroupbox.h
@@ -109,7 +109,7 @@ public:
private:
Q_DISABLE_COPY(QGroupBox)
- Q_DECLARE_SCOPED_PRIVATE(QGroupBox)
+ Q_DECLARE_PRIVATE(QGroupBox)
Q_PRIVATE_SLOT(d_func(), void _q_setChildrenEnabled(bool b))
};
diff --git a/src/gui/widgets/qlabel.h b/src/gui/widgets/qlabel.h
index 520d661..b7a7c11 100644
--- a/src/gui/widgets/qlabel.h
+++ b/src/gui/widgets/qlabel.h
@@ -156,7 +156,7 @@ public:
private:
Q_DISABLE_COPY(QLabel)
- Q_DECLARE_SCOPED_PRIVATE(QLabel)
+ Q_DECLARE_PRIVATE(QLabel)
#ifndef QT_NO_MOVIE
Q_PRIVATE_SLOT(d_func(), void _q_movieUpdated(const QRect&))
Q_PRIVATE_SLOT(d_func(), void _q_movieResized(const QSize&))
diff --git a/src/gui/widgets/qlcdnumber.h b/src/gui/widgets/qlcdnumber.h
index 3d7cf43..1437427 100644
--- a/src/gui/widgets/qlcdnumber.h
+++ b/src/gui/widgets/qlcdnumber.h
@@ -128,7 +128,7 @@ public:
private:
Q_DISABLE_COPY(QLCDNumber)
- Q_DECLARE_SCOPED_PRIVATE(QLCDNumber)
+ Q_DECLARE_PRIVATE(QLCDNumber)
};
#endif // QT_NO_LCDNUMBER
diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp
new file mode 100644
index 0000000..64832c8
--- /dev/null
+++ b/src/gui/widgets/qlinecontrol.cpp
@@ -0,0 +1,1750 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qlinecontrol_p.h"
+
+#ifndef QT_NO_LINEEDIT
+
+#include "qabstractitemview.h"
+#include "qclipboard.h"
+#ifndef QT_NO_ACCESSIBILITY
+#include "qaccessible.h"
+#endif
+#ifndef QT_NO_IM
+#include "qinputcontext.h"
+#include "qlist.h"
+#endif
+#include "qapplication.h"
+#ifndef QT_NO_GRAPHICSVIEW
+#include "qgraphicssceneevent.h"
+#endif
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \internal
+
+ Updates the display text based of the current edit text
+ If the text has changed will emit displayTextChanged()
+*/
+void QLineControl::updateDisplayText()
+{
+ QString orig = m_textLayout.text();
+ QString str;
+ if (m_echoMode == QLineEdit::NoEcho)
+ str = QString::fromLatin1("");
+ else
+ str = m_text;
+
+ if (m_echoMode == QLineEdit::Password || (m_echoMode == QLineEdit::PasswordEchoOnEdit
+ && !m_passwordEchoEditing))
+ str.fill(m_passwordCharacter);
+
+ // replace certain non-printable characters with spaces (to avoid
+ // drawing boxes when using fonts that don't have glyphs for such
+ // characters)
+ QChar* uc = str.data();
+ for (int i = 0; i < (int)str.length(); ++i) {
+ if ((uc[i] < 0x20 && uc[i] != 0x09)
+ || uc[i] == QChar::LineSeparator
+ || uc[i] == QChar::ParagraphSeparator
+ || uc[i] == QChar::ObjectReplacementCharacter)
+ uc[i] = QChar(0x0020);
+ }
+
+ m_textLayout.setText(str);
+
+ QTextOption option;
+ option.setTextDirection(m_layoutDirection);
+ option.setFlags(QTextOption::IncludeTrailingSpaces);
+ m_textLayout.setTextOption(option);
+
+ m_textLayout.beginLayout();
+ QTextLine l = m_textLayout.createLine();
+ m_textLayout.endLayout();
+ m_ascent = qRound(l.ascent());
+
+ if (str != orig)
+ emit displayTextChanged(str);
+}
+
+#ifndef QT_NO_CLIPBOARD
+/*!
+ \internal
+
+ Copies the currently selected text into the clipboard using the given
+ \a mode.
+
+ \note If the echo mode is set to a mode other than Normal then copy
+ will not work. This is to prevent using copy as a method of bypassing
+ password features of the line control.
+*/
+void QLineControl::copy(QClipboard::Mode mode) const
+{
+ QString t = selectedText();
+ if (!t.isEmpty() && m_echoMode == QLineEdit::Normal) {
+ disconnect(QApplication::clipboard(), SIGNAL(selectionChanged()), this, 0);
+ QApplication::clipboard()->setText(t, mode);
+ connect(QApplication::clipboard(), SIGNAL(selectionChanged()),
+ this, SLOT(_q_clipboardChanged()));
+ }
+}
+
+/*!
+ \internal
+
+ Inserts the text stored in the application clipboard into the line
+ control.
+
+ \sa insert()
+*/
+void QLineControl::paste()
+{
+ insert(QApplication::clipboard()->text(QClipboard::Clipboard));
+}
+
+#endif // !QT_NO_CLIPBOARD
+
+/*!
+ \internal
+
+ Handles the behavior for the backspace key or function.
+ Removes the current selection if there is a selection, otherwise
+ removes the character prior to the cursor position.
+
+ \sa del()
+*/
+void QLineControl::backspace()
+{
+ int priorState = m_undoState;
+ if (hasSelectedText()) {
+ removeSelectedText();
+ } else if (m_cursor) {
+ --m_cursor;
+ if (m_maskData)
+ m_cursor = prevMaskBlank(m_cursor);
+ QChar uc = m_text.at(m_cursor);
+ if (m_cursor > 0 && uc.unicode() >= 0xdc00 && uc.unicode() < 0xe000) {
+ // second half of a surrogate, check if we have the first half as well,
+ // if yes delete both at once
+ uc = m_text.at(m_cursor - 1);
+ if (uc.unicode() >= 0xd800 && uc.unicode() < 0xdc00) {
+ internalDelete(true);
+ --m_cursor;
+ }
+ }
+ internalDelete(true);
+ }
+ finishChange(priorState);
+}
+
+/*!
+ \internal
+
+ Handles the behavior for the delete key or function.
+ Removes the current selection if there is a selection, otherwise
+ removes the character after the cursor position.
+
+ \sa del()
+*/
+void QLineControl::del()
+{
+ int priorState = m_undoState;
+ if (hasSelectedText()) {
+ removeSelectedText();
+ } else {
+ int n = m_textLayout.nextCursorPosition(m_cursor) - m_cursor;
+ while (n--)
+ internalDelete();
+ }
+ finishChange(priorState);
+}
+
+/*!
+ \internal
+
+ Inserts the given \a newText at the current cursor position.
+ If there is any selected text it is removed prior to insertion of
+ the new text.
+*/
+void QLineControl::insert(const QString &newText)
+{
+ int priorState = m_undoState;
+ removeSelectedText();
+ internalInsert(newText);
+ finishChange(priorState);
+}
+
+/*!
+ \internal
+
+ Clears the line control text.
+*/
+void QLineControl::clear()
+{
+ int priorState = m_undoState;
+ m_selstart = 0;
+ m_selend = m_text.length();
+ removeSelectedText();
+ separate();
+ finishChange(priorState, /*update*/false, /*edited*/false);
+}
+
+/*!
+ \internal
+
+ Sets \a length characters from the given \a start position as selected.
+ The given \a start position must be within the current text for
+ the line control. If \a length characters cannot be selected, then
+ the selection will extend to the end of the current text.
+*/
+void QLineControl::setSelection(int start, int length)
+{
+ if(start < 0 || start > (int)m_text.length()){
+ qWarning("QLineControl::setSelection: Invalid start position");
+ return;
+ }
+
+ if (length > 0) {
+ if (start == m_selstart && start + length == m_selend)
+ return;
+ m_selstart = start;
+ m_selend = qMin(start + length, (int)m_text.length());
+ m_cursor = m_selend;
+ } else {
+ if (start == m_selend && start + length == m_selstart)
+ return;
+ m_selstart = qMax(start + length, 0);
+ m_selend = start;
+ m_cursor = m_selstart;
+ }
+ emit selectionChanged();
+}
+
+void QLineControl::_q_clipboardChanged()
+{
+}
+
+void QLineControl::_q_deleteSelected()
+{
+ if (!hasSelectedText())
+ return;
+
+ int priorState = m_undoState;
+ emit resetInputContext();
+ removeSelectedText();
+ separate();
+ finishChange(priorState);
+}
+
+/*!
+ \internal
+
+ Initializes the line control with a starting text value of \a txt.
+*/
+void QLineControl::init(const QString &txt)
+{
+ m_text = txt;
+ updateDisplayText();
+ m_cursor = m_text.length();
+}
+
+/*!
+ \internal
+
+ Sets the password echo editing to \a editing. If password echo editing
+ is true, then the text of the password is displayed even if the echo
+ mode is set to QLineEdit::PasswordEchoOnEdit. Password echoing editing
+ does not affect other echo modes.
+*/
+void QLineControl::updatePasswordEchoEditing(bool editing)
+{
+ m_passwordEchoEditing = editing;
+ updateDisplayText();
+}
+
+/*!
+ \internal
+
+ Returns the cursor position of the given \a x pixel value in relation
+ to the displayed text. The given \a betweenOrOn specified what kind
+ of cursor position is requested.
+*/
+int QLineControl::xToPos(int x, QTextLine::CursorPosition betweenOrOn) const
+{
+ return m_textLayout.lineAt(0).xToCursor(x, betweenOrOn);
+}
+
+/*!
+ \internal
+
+ Returns the bounds of the current cursor, as defined as a
+ between characters cursor.
+*/
+QRect QLineControl::cursorRect() const
+{
+ QTextLine l = m_textLayout.lineAt(0);
+ int c = m_cursor;
+ if (m_preeditCursor != -1)
+ c += m_preeditCursor;
+ int cix = qRound(l.cursorToX(c));
+ int w = m_cursorWidth;
+ int ch = l.height() + 1;
+
+ return QRect(cix-5, 0, w+9, ch);
+}
+
+/*!
+ \internal
+
+ Fixes the current text so that it is valid given any set validators.
+
+ Returns true if the text was changed. Otherwise returns false.
+*/
+bool QLineControl::fixup() // this function assumes that validate currently returns != Acceptable
+{
+#ifndef QT_NO_VALIDATOR
+ if (m_validator) {
+ QString textCopy = m_text;
+ int cursorCopy = m_cursor;
+ m_validator->fixup(textCopy);
+ if (m_validator->validate(textCopy, cursorCopy) == QValidator::Acceptable) {
+ if (textCopy != m_text || cursorCopy != m_cursor)
+ internalSetText(textCopy, cursorCopy);
+ return true;
+ }
+ }
+#endif
+ return false;
+}
+
+/*!
+ \internal
+
+ Moves the cursor to the given position \a pos. If \a mark is true will
+ adjust the currently selected text.
+*/
+void QLineControl::moveCursor(int pos, bool mark)
+{
+ if (pos != m_cursor) {
+ separate();
+ if (m_maskData)
+ pos = pos > m_cursor ? nextMaskBlank(pos) : prevMaskBlank(pos);
+ }
+ if (mark) {
+ int anchor;
+ if (m_selend > m_selstart && m_cursor == m_selstart)
+ anchor = m_selend;
+ else if (m_selend > m_selstart && m_cursor == m_selend)
+ anchor = m_selstart;
+ else
+ anchor = m_cursor;
+ m_selstart = qMin(anchor, pos);
+ m_selend = qMax(anchor, pos);
+ updateDisplayText();
+ } else {
+ internalDeselect();
+ }
+ m_cursor = pos;
+ if (mark || m_selDirty) {
+ m_selDirty = false;
+ emit selectionChanged();
+ }
+ emitCursorPositionChanged();
+}
+
+/*!
+ \internal
+
+ Applies the given input method event \a event to the text of the line
+ control
+*/
+void QLineControl::processInputMethodEvent(QInputMethodEvent *event)
+{
+ int priorState = m_undoState;
+ removeSelectedText();
+
+ int c = m_cursor; // cursor position after insertion of commit string
+ if (event->replacementStart() <= 0)
+ c += event->commitString().length() + qMin(-event->replacementStart(), event->replacementLength());
+
+ m_cursor += event->replacementStart();
+
+ // insert commit string
+ if (event->replacementLength()) {
+ m_selstart = m_cursor;
+ m_selend = m_selstart + event->replacementLength();
+ removeSelectedText();
+ }
+ if (!event->commitString().isEmpty())
+ insert(event->commitString());
+
+ m_cursor = qMin(c, m_text.length());
+
+ setPreeditArea(m_cursor, event->preeditString());
+ m_preeditCursor = event->preeditString().length();
+ m_hideCursor = false;
+ QList<QTextLayout::FormatRange> formats;
+ for (int i = 0; i < event->attributes().size(); ++i) {
+ const QInputMethodEvent::Attribute &a = event->attributes().at(i);
+ if (a.type == QInputMethodEvent::Cursor) {
+ m_preeditCursor = a.start;
+ m_hideCursor = !a.length;
+ } else if (a.type == QInputMethodEvent::TextFormat) {
+ QTextCharFormat f = qvariant_cast<QTextFormat>(a.value).toCharFormat();
+ if (f.isValid()) {
+ QTextLayout::FormatRange o;
+ o.start = a.start + m_cursor;
+ o.length = a.length;
+ o.format = f;
+ formats.append(o);
+ }
+ }
+ }
+ m_textLayout.setAdditionalFormats(formats);
+ updateDisplayText();
+ if (!event->commitString().isEmpty())
+ emitCursorPositionChanged();
+ finishChange(priorState);
+}
+
+/*!
+ \internal
+
+ Draws the display text for the line control using the given
+ \a painter, \a clip, and \a offset. Which aspects of the display text
+ are drawn is specified by the given \a flags.
+
+ If the flags contain DrawSelections, then the selection or input mask
+ backgrounds and foregrounds will be applied before drawing the text.
+
+ If the flags contain DrawCursor a cursor of the current cursorWidth()
+ will be drawn after drawing the text.
+
+ The display text will only be drawn if the flags contain DrawText
+*/
+void QLineControl::draw(QPainter *painter, const QPoint &offset, const QRect &clip, int flags)
+{
+ QVector<QTextLayout::FormatRange> selections;
+ if (flags & DrawSelections) {
+ QTextLayout::FormatRange o;
+ if (m_selstart < m_selend) {
+ o.start = m_selstart;
+ o.length = m_selend - m_selstart;
+ o.format.setBackground(m_palette.brush(QPalette::Highlight));
+ o.format.setForeground(m_palette.brush(QPalette::HighlightedText));
+ } else {
+ // mask selection
+ o.start = m_cursor;
+ o.length = 1;
+ o.format.setBackground(m_palette.brush(QPalette::Text));
+ o.format.setForeground(m_palette.brush(QPalette::Window));
+ }
+ selections.append(o);
+ }
+
+ if (flags & DrawText)
+ m_textLayout.draw(painter, offset, selections, clip);
+
+ if (flags & DrawCursor){
+ if(!m_blinkPeriod || m_blinkStatus)
+ m_textLayout.drawCursor(painter, offset, m_cursor, m_cursorWidth);
+ }
+}
+
+/*!
+ \internal
+
+ Sets the selection to cover the word at the given cursor position.
+ The word boundries is defined by the behavior of QTextLayout::SkipWords
+ cursor mode.
+*/
+void QLineControl::selectWordAtPos(int cursor)
+{
+ int c = m_textLayout.previousCursorPosition(cursor, QTextLayout::SkipWords);
+ moveCursor(c, false);
+ // ## text layout should support end of words.
+ int end = m_textLayout.nextCursorPosition(cursor, QTextLayout::SkipWords);
+ while (end > cursor && m_text[end-1].isSpace())
+ --end;
+ moveCursor(end, true);
+}
+
+/*!
+ \internal
+
+ Completes a change to the line control text. If the change is not valid
+ will undo the line control state back to the given \a validateFromState.
+
+ If \a edited is true and the change is valid, will emit textEdited() in
+ addition to textChanged(). Otherwise only emits textChanged() on a valid
+ change.
+
+ The \a update value is currently unused.
+*/
+bool QLineControl::finishChange(int validateFromState, bool update, bool edited)
+{
+ Q_UNUSED(update)
+ bool lineDirty = m_selDirty;
+ if (m_textDirty) {
+ // do validation
+ bool wasValidInput = m_validInput;
+ m_validInput = true;
+#ifndef QT_NO_VALIDATOR
+ if (m_validator) {
+ m_validInput = false;
+ QString textCopy = m_text;
+ int cursorCopy = m_cursor;
+ m_validInput = (m_validator->validate(textCopy, cursorCopy) != QValidator::Invalid);
+ if (m_validInput) {
+ if (m_text != textCopy) {
+ internalSetText(textCopy, cursorCopy);
+ return true;
+ }
+ m_cursor = cursorCopy;
+ }
+ }
+#endif
+ if (validateFromState >= 0 && wasValidInput && !m_validInput) {
+ if (m_transactions.count())
+ return false;
+ internalUndo(validateFromState);
+ m_history.resize(m_undoState);
+ if (m_modifiedState > m_undoState)
+ m_modifiedState = -1;
+ m_validInput = true;
+ m_textDirty = false;
+ }
+ updateDisplayText();
+ lineDirty |= m_textDirty;
+ if (m_textDirty) {
+ m_textDirty = false;
+ QString actualText = text();
+ if (edited)
+ emit textEdited(actualText);
+ emit textChanged(actualText);
+ }
+ }
+ if (m_selDirty) {
+ m_selDirty = false;
+ emit selectionChanged();
+ }
+ emitCursorPositionChanged();
+ return true;
+}
+
+/*!
+ \internal
+
+ An internal function for setting the text of the line control.
+*/
+void QLineControl::internalSetText(const QString &txt, int pos, bool edited)
+{
+ internalDeselect();
+ emit resetInputContext();
+ QString oldText = m_text;
+ if (m_maskData) {
+ m_text = maskString(0, txt, true);
+ m_text += clearString(m_text.length(), m_maxLength - m_text.length());
+ } else {
+ m_text = txt.isEmpty() ? txt : txt.left(m_maxLength);
+ }
+ m_history.clear();
+ m_modifiedState = m_undoState = 0;
+ m_cursor = (pos < 0 || pos > m_text.length()) ? m_text.length() : pos;
+ m_textDirty = (oldText != m_text);
+ finishChange(-1, true, edited);
+}
+
+
+/*!
+ \internal
+
+ Adds the given \a command to the undo history
+ of the line control. Does not apply the command.
+*/
+void QLineControl::addCommand(const Command &cmd)
+{
+ if (m_separator && m_undoState && m_history[m_undoState - 1].type != Separator) {
+ m_history.resize(m_undoState + 2);
+ m_history[m_undoState++] = Command(Separator, m_cursor, 0, m_selstart, m_selend);
+ } else {
+ m_history.resize(m_undoState + 1);
+ }
+ m_separator = false;
+ m_history[m_undoState++] = cmd;
+}
+
+/*!
+ \internal
+
+ Inserts the given string \a s into the line
+ control.
+
+ Also adds the appropriate commands into the undo history.
+ This function does not call finishChange(), and may leave the text
+ in an invalid state.
+*/
+void QLineControl::internalInsert(const QString &s)
+{
+ if (hasSelectedText())
+ addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend));
+ if (m_maskData) {
+ QString ms = maskString(m_cursor, s);
+ for (int i = 0; i < (int) ms.length(); ++i) {
+ addCommand (Command(DeleteSelection, m_cursor + i, m_text.at(m_cursor + i), -1, -1));
+ addCommand(Command(Insert, m_cursor + i, ms.at(i), -1, -1));
+ }
+ m_text.replace(m_cursor, ms.length(), ms);
+ m_cursor += ms.length();
+ m_cursor = nextMaskBlank(m_cursor);
+ m_textDirty = true;
+ } else {
+ int remaining = m_maxLength - m_text.length();
+ if (remaining != 0) {
+ m_text.insert(m_cursor, s.left(remaining));
+ for (int i = 0; i < (int) s.left(remaining).length(); ++i)
+ addCommand(Command(Insert, m_cursor++, s.at(i), -1, -1));
+ m_textDirty = true;
+ }
+ }
+}
+
+/*!
+ \internal
+
+ deletes a single character from the current text. If \a wasBackspace,
+ the character prior to the cursor is removed. Otherwise the character
+ after the cursor is removed.
+
+ Also adds the appropriate commands into the undo history.
+ This function does not call finishChange(), and may leave the text
+ in an invalid state.
+*/
+void QLineControl::internalDelete(bool wasBackspace)
+{
+ if (m_cursor < (int) m_text.length()) {
+ if (hasSelectedText())
+ addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend));
+ addCommand(Command((CommandType)((m_maskData ? 2 : 0) + (wasBackspace ? Remove : Delete)),
+ m_cursor, m_text.at(m_cursor), -1, -1));
+ if (m_maskData) {
+ m_text.replace(m_cursor, 1, clearString(m_cursor, 1));
+ addCommand(Command(Insert, m_cursor, m_text.at(m_cursor), -1, -1));
+ } else {
+ m_text.remove(m_cursor, 1);
+ }
+ m_textDirty = true;
+ }
+}
+
+/*!
+ \internal
+
+ removes the currently selected text from the line control.
+
+ Also adds the appropriate commands into the undo history.
+ This function does not call finishChange(), and may leave the text
+ in an invalid state.
+*/
+void QLineControl::removeSelectedText()
+{
+ if (m_selstart < m_selend && m_selend <= (int) m_text.length()) {
+ separate();
+ int i ;
+ addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend));
+ if (m_selstart <= m_cursor && m_cursor < m_selend) {
+ // cursor is within the selection. Split up the commands
+ // to be able to restore the correct cursor position
+ for (i = m_cursor; i >= m_selstart; --i)
+ addCommand (Command(DeleteSelection, i, m_text.at(i), -1, 1));
+ for (i = m_selend - 1; i > m_cursor; --i)
+ addCommand (Command(DeleteSelection, i - m_cursor + m_selstart - 1, m_text.at(i), -1, -1));
+ } else {
+ for (i = m_selend-1; i >= m_selstart; --i)
+ addCommand (Command(RemoveSelection, i, m_text.at(i), -1, -1));
+ }
+ if (m_maskData) {
+ m_text.replace(m_selstart, m_selend - m_selstart, clearString(m_selstart, m_selend - m_selstart));
+ for (int i = 0; i < m_selend - m_selstart; ++i)
+ addCommand(Command(Insert, m_selstart + i, m_text.at(m_selstart + i), -1, -1));
+ } else {
+ m_text.remove(m_selstart, m_selend - m_selstart);
+ }
+ if (m_cursor > m_selstart)
+ m_cursor -= qMin(m_cursor, m_selend) - m_selstart;
+ internalDeselect();
+ m_textDirty = true;
+ }
+}
+
+/*!
+ \internal
+
+ Parses the input mask specified by \a maskFields to generate
+ the mask data used to handle input masks.
+*/
+void QLineControl::parseInputMask(const QString &maskFields)
+{
+ int delimiter = maskFields.indexOf(QLatin1Char(';'));
+ if (maskFields.isEmpty() || delimiter == 0) {
+ if (m_maskData) {
+ delete [] m_maskData;
+ m_maskData = 0;
+ m_maxLength = 32767;
+ internalSetText(QString());
+ }
+ return;
+ }
+
+ if (delimiter == -1) {
+ m_blank = QLatin1Char(' ');
+ m_inputMask = maskFields;
+ } else {
+ m_inputMask = maskFields.left(delimiter);
+ m_blank = (delimiter + 1 < maskFields.length()) ? maskFields[delimiter + 1] : QLatin1Char(' ');
+ }
+
+ // calculate m_maxLength / m_maskData length
+ m_maxLength = 0;
+ QChar c = 0;
+ for (int i=0; i<m_inputMask.length(); i++) {
+ c = m_inputMask.at(i);
+ if (i > 0 && m_inputMask.at(i-1) == QLatin1Char('\\')) {
+ m_maxLength++;
+ continue;
+ }
+ if (c != QLatin1Char('\\') && c != QLatin1Char('!') &&
+ c != QLatin1Char('<') && c != QLatin1Char('>') &&
+ c != QLatin1Char('{') && c != QLatin1Char('}') &&
+ c != QLatin1Char('[') && c != QLatin1Char(']'))
+ m_maxLength++;
+ }
+
+ delete [] m_maskData;
+ m_maskData = new MaskInputData[m_maxLength];
+
+ MaskInputData::Casemode m = MaskInputData::NoCaseMode;
+ c = 0;
+ bool s;
+ bool escape = false;
+ int index = 0;
+ for (int i = 0; i < m_inputMask.length(); i++) {
+ c = m_inputMask.at(i);
+ if (escape) {
+ s = true;
+ m_maskData[index].maskChar = c;
+ m_maskData[index].separator = s;
+ m_maskData[index].caseMode = m;
+ index++;
+ escape = false;
+ } else if (c == QLatin1Char('<')) {
+ m = MaskInputData::Lower;
+ } else if (c == QLatin1Char('>')) {
+ m = MaskInputData::Upper;
+ } else if (c == QLatin1Char('!')) {
+ m = MaskInputData::NoCaseMode;
+ } else if (c != QLatin1Char('{') && c != QLatin1Char('}') && c != QLatin1Char('[') && c != QLatin1Char(']')) {
+ switch (c.unicode()) {
+ case 'A':
+ case 'a':
+ case 'N':
+ case 'n':
+ case 'X':
+ case 'x':
+ case '9':
+ case '0':
+ case 'D':
+ case 'd':
+ case '#':
+ case 'H':
+ case 'h':
+ case 'B':
+ case 'b':
+ s = false;
+ break;
+ case '\\':
+ escape = true;
+ default:
+ s = true;
+ break;
+ }
+
+ if (!escape) {
+ m_maskData[index].maskChar = c;
+ m_maskData[index].separator = s;
+ m_maskData[index].caseMode = m;
+ index++;
+ }
+ }
+ }
+ internalSetText(m_text);
+}
+
+
+/*!
+ \internal
+
+ checks if the key is valid compared to the inputMask
+*/
+bool QLineControl::isValidInput(QChar key, QChar mask) const
+{
+ switch (mask.unicode()) {
+ case 'A':
+ if (key.isLetter())
+ return true;
+ break;
+ case 'a':
+ if (key.isLetter() || key == m_blank)
+ return true;
+ break;
+ case 'N':
+ if (key.isLetterOrNumber())
+ return true;
+ break;
+ case 'n':
+ if (key.isLetterOrNumber() || key == m_blank)
+ return true;
+ break;
+ case 'X':
+ if (key.isPrint())
+ return true;
+ break;
+ case 'x':
+ if (key.isPrint() || key == m_blank)
+ return true;
+ break;
+ case '9':
+ if (key.isNumber())
+ return true;
+ break;
+ case '0':
+ if (key.isNumber() || key == m_blank)
+ return true;
+ break;
+ case 'D':
+ if (key.isNumber() && key.digitValue() > 0)
+ return true;
+ break;
+ case 'd':
+ if ((key.isNumber() && key.digitValue() > 0) || key == m_blank)
+ return true;
+ break;
+ case '#':
+ if (key.isNumber() || key == QLatin1Char('+') || key == QLatin1Char('-') || key == m_blank)
+ return true;
+ break;
+ case 'B':
+ if (key == QLatin1Char('0') || key == QLatin1Char('1'))
+ return true;
+ break;
+ case 'b':
+ if (key == QLatin1Char('0') || key == QLatin1Char('1') || key == m_blank)
+ return true;
+ break;
+ case 'H':
+ if (key.isNumber() || (key >= QLatin1Char('a') && key <= QLatin1Char('f')) || (key >= QLatin1Char('A') && key <= QLatin1Char('F')))
+ return true;
+ break;
+ case 'h':
+ if (key.isNumber() || (key >= QLatin1Char('a') && key <= QLatin1Char('f')) || (key >= QLatin1Char('A') && key <= QLatin1Char('F')) || key == m_blank)
+ return true;
+ break;
+ default:
+ break;
+ }
+ return false;
+}
+
+/*!
+ \internal
+
+ Returns true if the given text \a str is valid for any
+ validator or input mask set for the line control.
+
+ Otherwise returns false
+*/
+bool QLineControl::hasAcceptableInput(const QString &str) const
+{
+#ifndef QT_NO_VALIDATOR
+ QString textCopy = str;
+ int cursorCopy = m_cursor;
+ if (m_validator && m_validator->validate(textCopy, cursorCopy)
+ != QValidator::Acceptable)
+ return false;
+#endif
+
+ if (!m_maskData)
+ return true;
+
+ if (str.length() != m_maxLength)
+ return false;
+
+ for (int i=0; i < m_maxLength; ++i) {
+ if (m_maskData[i].separator) {
+ if (str.at(i) != m_maskData[i].maskChar)
+ return false;
+ } else {
+ if (!isValidInput(str.at(i), m_maskData[i].maskChar))
+ return false;
+ }
+ }
+ return true;
+}
+
+/*!
+ \internal
+
+ Applies the inputMask on \a str starting from position \a pos in the mask. \a clear
+ specifies from where characters should be gotten when a separator is met in \a str - true means
+ that blanks will be used, false that previous input is used.
+ Calling this when no inputMask is set is undefined.
+*/
+QString QLineControl::maskString(uint pos, const QString &str, bool clear) const
+{
+ if (pos >= (uint)m_maxLength)
+ return QString::fromLatin1("");
+
+ QString fill;
+ fill = clear ? clearString(0, m_maxLength) : m_text;
+
+ int strIndex = 0;
+ QString s = QString::fromLatin1("");
+ int i = pos;
+ while (i < m_maxLength) {
+ if (strIndex < str.length()) {
+ if (m_maskData[i].separator) {
+ s += m_maskData[i].maskChar;
+ if (str[(int)strIndex] == m_maskData[i].maskChar)
+ strIndex++;
+ ++i;
+ } else {
+ if (isValidInput(str[(int)strIndex], m_maskData[i].maskChar)) {
+ switch (m_maskData[i].caseMode) {
+ case MaskInputData::Upper:
+ s += str[(int)strIndex].toUpper();
+ break;
+ case MaskInputData::Lower:
+ s += str[(int)strIndex].toLower();
+ break;
+ default:
+ s += str[(int)strIndex];
+ }
+ ++i;
+ } else {
+ // search for separator first
+ int n = findInMask(i, true, true, str[(int)strIndex]);
+ if (n != -1) {
+ if (str.length() != 1 || i == 0 || (i > 0 && (!m_maskData[i-1].separator || m_maskData[i-1].maskChar != str[(int)strIndex]))) {
+ s += fill.mid(i, n-i+1);
+ i = n + 1; // update i to find + 1
+ }
+ } else {
+ // search for valid m_blank if not
+ n = findInMask(i, true, false, str[(int)strIndex]);
+ if (n != -1) {
+ s += fill.mid(i, n-i);
+ switch (m_maskData[n].caseMode) {
+ case MaskInputData::Upper:
+ s += str[(int)strIndex].toUpper();
+ break;
+ case MaskInputData::Lower:
+ s += str[(int)strIndex].toLower();
+ break;
+ default:
+ s += str[(int)strIndex];
+ }
+ i = n + 1; // updates i to find + 1
+ }
+ }
+ }
+ ++strIndex;
+ }
+ } else
+ break;
+ }
+
+ return s;
+}
+
+
+
+/*!
+ \internal
+
+ Returns a "cleared" string with only separators and blank chars.
+ Calling this when no inputMask is set is undefined.
+*/
+QString QLineControl::clearString(uint pos, uint len) const
+{
+ if (pos >= (uint)m_maxLength)
+ return QString();
+
+ QString s;
+ int end = qMin((uint)m_maxLength, pos + len);
+ for (int i = pos; i < end; ++i)
+ if (m_maskData[i].separator)
+ s += m_maskData[i].maskChar;
+ else
+ s += m_blank;
+
+ return s;
+}
+
+/*!
+ \internal
+
+ Strips blank parts of the input in a QLineControl when an inputMask is set,
+ separators are still included. Typically "127.0__.0__.1__" becomes "127.0.0.1".
+*/
+QString QLineControl::stripString(const QString &str) const
+{
+ if (!m_maskData)
+ return str;
+
+ QString s;
+ int end = qMin(m_maxLength, (int)str.length());
+ for (int i = 0; i < end; ++i)
+ if (m_maskData[i].separator)
+ s += m_maskData[i].maskChar;
+ else
+ if (str[i] != m_blank)
+ s += str[i];
+
+ return s;
+}
+
+/*!
+ \internal
+ searches forward/backward in m_maskData for either a separator or a m_blank
+*/
+int QLineControl::findInMask(int pos, bool forward, bool findSeparator, QChar searchChar) const
+{
+ if (pos >= m_maxLength || pos < 0)
+ return -1;
+
+ int end = forward ? m_maxLength : -1;
+ int step = forward ? 1 : -1;
+ int i = pos;
+
+ while (i != end) {
+ if (findSeparator) {
+ if (m_maskData[i].separator && m_maskData[i].maskChar == searchChar)
+ return i;
+ } else {
+ if (!m_maskData[i].separator) {
+ if (searchChar.isNull())
+ return i;
+ else if (isValidInput(searchChar, m_maskData[i].maskChar))
+ return i;
+ }
+ }
+ i += step;
+ }
+ return -1;
+}
+
+void QLineControl::internalUndo(int until)
+{
+ if (!isUndoAvailable())
+ return;
+ internalDeselect();
+ while (m_undoState && m_undoState > until) {
+ Command& cmd = m_history[--m_undoState];
+ switch (cmd.type) {
+ case Insert:
+ m_text.remove(cmd.pos, 1);
+ m_cursor = cmd.pos;
+ break;
+ case SetSelection:
+ m_selstart = cmd.selStart;
+ m_selend = cmd.selEnd;
+ m_cursor = cmd.pos;
+ break;
+ case Remove:
+ case RemoveSelection:
+ m_text.insert(cmd.pos, cmd.uc);
+ m_cursor = cmd.pos + 1;
+ break;
+ case Delete:
+ case DeleteSelection:
+ m_text.insert(cmd.pos, cmd.uc);
+ m_cursor = cmd.pos;
+ break;
+ case Separator:
+ continue;
+ }
+ if (until < 0 && m_undoState) {
+ Command& next = m_history[m_undoState-1];
+ if (next.type != cmd.type && next.type < RemoveSelection
+ && (cmd.type < RemoveSelection || next.type == Separator))
+ break;
+ }
+ }
+ m_textDirty = true;
+ emitCursorPositionChanged();
+}
+
+void QLineControl::internalRedo()
+{
+ if (!isRedoAvailable())
+ return;
+ internalDeselect();
+ while (m_undoState < (int)m_history.size()) {
+ Command& cmd = m_history[m_undoState++];
+ switch (cmd.type) {
+ case Insert:
+ m_text.insert(cmd.pos, cmd.uc);
+ m_cursor = cmd.pos + 1;
+ break;
+ case SetSelection:
+ m_selstart = cmd.selStart;
+ m_selend = cmd.selEnd;
+ m_cursor = cmd.pos;
+ break;
+ case Remove:
+ case Delete:
+ case RemoveSelection:
+ case DeleteSelection:
+ m_text.remove(cmd.pos, 1);
+ m_selstart = cmd.selStart;
+ m_selend = cmd.selEnd;
+ m_cursor = cmd.pos;
+ break;
+ case Separator:
+ m_selstart = cmd.selStart;
+ m_selend = cmd.selEnd;
+ m_cursor = cmd.pos;
+ break;
+ }
+ if (m_undoState < (int)m_history.size()) {
+ Command& next = m_history[m_undoState];
+ if (next.type != cmd.type && cmd.type < RemoveSelection && next.type != Separator
+ && (next.type < RemoveSelection || cmd.type == Separator))
+ break;
+ }
+ }
+ m_textDirty = true;
+ emitCursorPositionChanged();
+}
+
+/*!
+ \internal
+
+ If the current cursor position differs from the last emited cursor
+ position, emits cursorPositionChanged().
+*/
+void QLineControl::emitCursorPositionChanged()
+{
+ if (m_cursor != m_lastCursorPos) {
+ const int oldLast = m_lastCursorPos;
+ m_lastCursorPos = m_cursor;
+ cursorPositionChanged(oldLast, m_cursor);
+ }
+}
+
+#ifndef QT_NO_COMPLETER
+// iterating forward(dir=1)/backward(dir=-1) from the
+// current row based. dir=0 indicates a new completion prefix was set.
+bool QLineControl::advanceToEnabledItem(int dir)
+{
+ int start = m_completer->currentRow();
+ if (start == -1)
+ return false;
+ int i = start + dir;
+ if (dir == 0) dir = 1;
+ do {
+ if (!m_completer->setCurrentRow(i)) {
+ if (!m_completer->wrapAround())
+ break;
+ i = i > 0 ? 0 : m_completer->completionCount() - 1;
+ } else {
+ QModelIndex currentIndex = m_completer->currentIndex();
+ if (m_completer->completionModel()->flags(currentIndex) & Qt::ItemIsEnabled)
+ return true;
+ i += dir;
+ }
+ } while (i != start);
+
+ m_completer->setCurrentRow(start); // restore
+ return false;
+}
+
+void QLineControl::complete(int key)
+{
+ if (!m_completer || isReadOnly() || echoMode() != QLineEdit::Normal)
+ return;
+
+ QString text = this->text();
+ if (m_completer->completionMode() == QCompleter::InlineCompletion) {
+ if (key == Qt::Key_Backspace)
+ return;
+ int n = 0;
+ if (key == Qt::Key_Up || key == Qt::Key_Down) {
+ if (textAfterSelection().length())
+ return;
+ QString prefix = hasSelectedText() ? textBeforeSelection()
+ : text;
+ if (text.compare(m_completer->currentCompletion(), m_completer->caseSensitivity()) != 0
+ || prefix.compare(m_completer->completionPrefix(), m_completer->caseSensitivity()) != 0) {
+ m_completer->setCompletionPrefix(prefix);
+ } else {
+ n = (key == Qt::Key_Up) ? -1 : +1;
+ }
+ } else {
+ m_completer->setCompletionPrefix(text);
+ }
+ if (!advanceToEnabledItem(n))
+ return;
+ } else {
+#ifndef QT_KEYPAD_NAVIGATION
+ if (text.isEmpty()) {
+ m_completer->popup()->hide();
+ return;
+ }
+#endif
+ m_completer->setCompletionPrefix(text);
+ }
+
+ m_completer->complete();
+}
+#endif
+
+void QLineControl::setCursorBlinkPeriod(int msec)
+{
+ if (msec == m_blinkPeriod)
+ return;
+ if (m_blinkTimer) {
+ killTimer(m_blinkTimer);
+ }
+ if (msec) {
+ m_blinkTimer = startTimer(msec / 2);
+ m_blinkStatus = 1;
+ } else {
+ m_blinkTimer = 0;
+ if (m_blinkStatus == 0)
+ emit updateNeeded(inputMask().isEmpty() ? cursorRect() : QRect());
+ }
+ m_blinkPeriod = msec;
+}
+
+void QLineControl::timerEvent(QTimerEvent *event)
+{
+ if (event->timerId() == m_blinkTimer) {
+ m_blinkStatus = !m_blinkStatus;
+ emit updateNeeded(inputMask().isEmpty() ? cursorRect() : QRect());
+ } else if (event->timerId() == m_deleteAllTimer) {
+ killTimer(m_deleteAllTimer);
+ m_deleteAllTimer = 0;
+ clear();
+ } else if (event->timerId() == m_tripleClickTimer) {
+ killTimer(m_tripleClickTimer);
+ m_tripleClickTimer = 0;
+ }
+}
+
+bool QLineControl::processEvent(QEvent* ev)
+{
+#ifdef QT_KEYPAD_NAVIGATION
+ if (QApplication::keypadNavigationEnabled()) {
+ if ((ev->type() == QEvent::KeyPress) || (ev->type() == QEvent::KeyRelease)) {
+ QKeyEvent *ke = (QKeyEvent *)ev;
+ if (ke->key() == Qt::Key_Back) {
+ if (ke->isAutoRepeat()) {
+ // Swallow it. We don't want back keys running amok.
+ ke->accept();
+ return true;
+ }
+ if ((ev->type() == QEvent::KeyRelease)
+ && !isReadOnly()
+ && m_deleteAllTimer) {
+ killTimer(m_deleteAllTimer);
+ m_deleteAllTimer = 0;
+ backspace();
+ ke->accept();
+ return true;
+ }
+ }
+ }
+ }
+#endif
+ switch(ev->type()){
+#ifndef QT_NO_GRAPHICSVIEW
+ case QEvent::GraphicsSceneMouseMove:
+ case QEvent::GraphicsSceneMouseRelease:
+ case QEvent::GraphicsSceneMousePress:{
+ QGraphicsSceneMouseEvent *gvEv = static_cast<QGraphicsSceneMouseEvent*>(ev);
+ QMouseEvent* mouse = new QMouseEvent(ev->type(),
+ gvEv->pos().toPoint(), gvEv->button(), gvEv->buttons(), gvEv->modifiers());
+ processMouseEvent(mouse); break;
+ }
+#endif
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseMove:
+ processMouseEvent(static_cast<QMouseEvent*>(ev)); break;
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ processKeyEvent(static_cast<QKeyEvent*>(ev)); break;
+ case QEvent::InputMethod:
+ processInputMethodEvent(static_cast<QInputMethodEvent*>(ev)); break;
+#ifndef QT_NO_SHORTCUT
+ case QEvent::ShortcutOverride:{
+ QKeyEvent* ke = static_cast<QKeyEvent*>(ev);
+ if (ke == QKeySequence::Copy
+ || ke == QKeySequence::Paste
+ || ke == QKeySequence::Cut
+ || ke == QKeySequence::Redo
+ || ke == QKeySequence::Undo
+ || ke == QKeySequence::MoveToNextWord
+ || ke == QKeySequence::MoveToPreviousWord
+ || ke == QKeySequence::MoveToStartOfDocument
+ || ke == QKeySequence::MoveToEndOfDocument
+ || ke == QKeySequence::SelectNextWord
+ || ke == QKeySequence::SelectPreviousWord
+ || ke == QKeySequence::SelectStartOfLine
+ || ke == QKeySequence::SelectEndOfLine
+ || ke == QKeySequence::SelectStartOfBlock
+ || ke == QKeySequence::SelectEndOfBlock
+ || ke == QKeySequence::SelectStartOfDocument
+ || ke == QKeySequence::SelectAll
+ || ke == QKeySequence::SelectEndOfDocument) {
+ ke->accept();
+ } else if (ke->modifiers() == Qt::NoModifier || ke->modifiers() == Qt::ShiftModifier
+ || ke->modifiers() == Qt::KeypadModifier) {
+ if (ke->key() < Qt::Key_Escape) {
+ ke->accept();
+ } else {
+ switch (ke->key()) {
+ case Qt::Key_Delete:
+ case Qt::Key_Home:
+ case Qt::Key_End:
+ case Qt::Key_Backspace:
+ case Qt::Key_Left:
+ case Qt::Key_Right:
+ ke->accept();
+ default:
+ break;
+ }
+ }
+ }
+ }
+#endif
+ default:
+ return false;
+ }
+ return true;
+}
+
+void QLineControl::processMouseEvent(QMouseEvent* ev)
+{
+
+ switch (ev->type()) {
+ case QEvent::GraphicsSceneMousePress:
+ case QEvent::MouseButtonPress:{
+ if (m_tripleClickTimer
+ && (ev->pos() - m_tripleClick).manhattanLength()
+ < QApplication::startDragDistance()) {
+ selectAll();
+ return;
+ }
+ if (ev->button() == Qt::RightButton)
+ return;
+
+ bool mark = ev->modifiers() & Qt::ShiftModifier;
+ int cursor = xToPos(ev->pos().x());
+ moveCursor(cursor, mark);
+ break;
+ }
+ case QEvent::MouseButtonDblClick:
+ if (ev->button() == Qt::LeftButton) {
+ selectWordAtPos(xToPos(ev->pos().x()));
+ if (m_tripleClickTimer)
+ killTimer(m_tripleClickTimer);
+ m_tripleClickTimer = startTimer(QApplication::doubleClickInterval());
+ m_tripleClick = ev->pos();
+ }
+ break;
+ case QEvent::GraphicsSceneMouseRelease:
+ case QEvent::MouseButtonRelease:
+#ifndef QT_NO_CLIPBOARD
+ if (QApplication::clipboard()->supportsSelection()) {
+ if (ev->button() == Qt::LeftButton) {
+ copy(QClipboard::Selection);
+ } else if (!isReadOnly() && ev->button() == Qt::MidButton) {
+ deselect();
+ insert(QApplication::clipboard()->text(QClipboard::Selection));
+ }
+ }
+#endif
+ break;
+ case QEvent::GraphicsSceneMouseMove:
+ case QEvent::MouseMove:
+ if (ev->buttons() & Qt::LeftButton) {
+ moveCursor(xToPos(ev->pos().x()), true);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void QLineControl::processKeyEvent(QKeyEvent* event)
+{
+ bool inlineCompletionAccepted = false;
+
+#ifndef QT_NO_COMPLETER
+ if (m_completer) {
+ QCompleter::CompletionMode completionMode = m_completer->completionMode();
+ if ((completionMode == QCompleter::PopupCompletion
+ || completionMode == QCompleter::UnfilteredPopupCompletion)
+ && m_completer->popup()
+ && m_completer->popup()->isVisible()) {
+ // The following keys are forwarded by the completer to the widget
+ // Ignoring the events lets the completer provide suitable default behavior
+ switch (event->key()) {
+ case Qt::Key_Escape:
+ event->ignore();
+ return;
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ case Qt::Key_F4:
+#ifdef QT_KEYPAD_NAVIGATION
+ case Qt::Key_Select:
+ if (!QApplication::keypadNavigationEnabled())
+ break;
+#endif
+ m_completer->popup()->hide(); // just hide. will end up propagating to parent
+ default:
+ break; // normal key processing
+ }
+ } else if (completionMode == QCompleter::InlineCompletion) {
+ switch (event->key()) {
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ case Qt::Key_F4:
+#ifdef QT_KEYPAD_NAVIGATION
+ case Qt::Key_Select:
+ if (!QApplication::keypadNavigationEnabled())
+ break;
+#endif
+ if (!m_completer->currentCompletion().isEmpty() && hasSelectedText()
+ && textAfterSelection().isEmpty()) {
+ setText(m_completer->currentCompletion());
+ inlineCompletionAccepted = true;
+ }
+ default:
+ break; // normal key processing
+ }
+ }
+ }
+#endif // QT_NO_COMPLETER
+
+ if (echoMode() == QLineEdit::PasswordEchoOnEdit
+ && !passwordEchoEditing()
+ && !isReadOnly()
+ && !event->text().isEmpty()
+#ifdef QT_KEYPAD_NAVIGATION
+ && event->key() != Qt::Key_Select
+ && event->key() != Qt::Key_Up
+ && event->key() != Qt::Key_Down
+ && event->key() != Qt::Key_Back
+#endif
+ && !(event->modifiers() & Qt::ControlModifier)) {
+ // Clear the edit and reset to normal echo mode while editing; the
+ // echo mode switches back when the edit loses focus
+ // ### resets current content. dubious code; you can
+ // navigate with keys up, down, back, and select(?), but if you press
+ // "left" or "right" it clears?
+ updatePasswordEchoEditing(true);
+ clear();
+ }
+
+ if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) {
+ if (hasAcceptableInput() || fixup()) {
+ emit accepted();
+ emit editingFinished();
+ }
+ if (inlineCompletionAccepted)
+ event->accept();
+ else
+ event->ignore();
+ return;
+ }
+ bool unknown = false;
+
+ if (false) {
+ }
+#ifndef QT_NO_SHORTCUT
+ else if (event == QKeySequence::Undo) {
+ if (!isReadOnly())
+ undo();
+ }
+ else if (event == QKeySequence::Redo) {
+ if (!isReadOnly())
+ redo();
+ }
+ else if (event == QKeySequence::SelectAll) {
+ selectAll();
+ }
+#ifndef QT_NO_CLIPBOARD
+ else if (event == QKeySequence::Copy) {
+ copy();
+ }
+ else if (event == QKeySequence::Paste) {
+ if (!isReadOnly())
+ paste();
+ }
+ else if (event == QKeySequence::Cut) {
+ if (!isReadOnly()) {
+ copy();
+ del();
+ }
+ }
+ else if (event == QKeySequence::DeleteEndOfLine) {
+ if (!isReadOnly()) {
+ setSelection(cursor(), end());
+ copy();
+ del();
+ }
+ }
+#endif //QT_NO_CLIPBOARD
+ else if (event == QKeySequence::MoveToStartOfLine) {
+ home(0);
+ }
+ else if (event == QKeySequence::MoveToEndOfLine) {
+ end(0);
+ }
+ else if (event == QKeySequence::SelectStartOfLine) {
+ home(1);
+ }
+ else if (event == QKeySequence::SelectEndOfLine) {
+ end(1);
+ }
+ else if (event == QKeySequence::MoveToNextChar) {
+#if !defined(Q_WS_WIN) || defined(QT_NO_COMPLETER)
+ if (hasSelectedText()) {
+#else
+ if (hasSelectedText() && m_completer
+ && m_completer->completionMode() == QCompleter::InlineCompletion) {
+#endif
+ moveCursor(selectionEnd(), false);
+ } else {
+ cursorForward(0, layoutDirection() == Qt::LeftToRight ? 1 : -1);
+ }
+ }
+ else if (event == QKeySequence::SelectNextChar) {
+ cursorForward(1, layoutDirection() == Qt::LeftToRight ? 1 : -1);
+ }
+ else if (event == QKeySequence::MoveToPreviousChar) {
+#if !defined(Q_WS_WIN) || defined(QT_NO_COMPLETER)
+ if (hasSelectedText()) {
+#else
+ if (hasSelectedText() && m_completer
+ && m_completer->completionMode() == QCompleter::InlineCompletion) {
+#endif
+ moveCursor(selectionStart(), false);
+ } else {
+ cursorForward(0, layoutDirection() == Qt::LeftToRight ? -1 : 1);
+ }
+ }
+ else if (event == QKeySequence::SelectPreviousChar) {
+ cursorForward(1, layoutDirection() == Qt::LeftToRight ? -1 : 1);
+ }
+ else if (event == QKeySequence::MoveToNextWord) {
+ if (echoMode() == QLineEdit::Normal)
+ layoutDirection() == Qt::LeftToRight ? cursorWordForward(0) : cursorWordBackward(0);
+ else
+ layoutDirection() == Qt::LeftToRight ? end(0) : home(0);
+ }
+ else if (event == QKeySequence::MoveToPreviousWord) {
+ if (echoMode() == QLineEdit::Normal)
+ layoutDirection() == Qt::LeftToRight ? cursorWordBackward(0) : cursorWordForward(0);
+ else if (!isReadOnly()) {
+ layoutDirection() == Qt::LeftToRight ? home(0) : end(0);
+ }
+ }
+ else if (event == QKeySequence::SelectNextWord) {
+ if (echoMode() == QLineEdit::Normal)
+ layoutDirection() == Qt::LeftToRight ? cursorWordForward(1) : cursorWordBackward(1);
+ else
+ layoutDirection() == Qt::LeftToRight ? end(1) : home(1);
+ }
+ else if (event == QKeySequence::SelectPreviousWord) {
+ if (echoMode() == QLineEdit::Normal)
+ layoutDirection() == Qt::LeftToRight ? cursorWordBackward(1) : cursorWordForward(1);
+ else
+ layoutDirection() == Qt::LeftToRight ? home(1) : end(1);
+ }
+ else if (event == QKeySequence::Delete) {
+ if (!isReadOnly())
+ del();
+ }
+ else if (event == QKeySequence::DeleteEndOfWord) {
+ if (!isReadOnly()) {
+ cursorWordForward(true);
+ del();
+ }
+ }
+ else if (event == QKeySequence::DeleteStartOfWord) {
+ if (!isReadOnly()) {
+ cursorWordBackward(true);
+ del();
+ }
+ }
+#endif // QT_NO_SHORTCUT
+ else {
+#ifdef Q_WS_MAC
+ if (event->key() == Qt::Key_Up || event->key() == Qt::Key_Down) {
+ Qt::KeyboardModifiers myModifiers = (event->modifiers() & ~Qt::KeypadModifier);
+ if (myModifiers & Qt::ShiftModifier) {
+ if (myModifiers == (Qt::ControlModifier|Qt::ShiftModifier)
+ || myModifiers == (Qt::AltModifier|Qt::ShiftModifier)
+ || myModifiers == Qt::ShiftModifier) {
+
+ event->key() == Qt::Key_Up ? home(1) : end(1);
+ }
+ } else {
+ if ((myModifiers == Qt::ControlModifier
+ || myModifiers == Qt::AltModifier
+ || myModifiers == Qt::NoModifier)) {
+ event->key() == Qt::Key_Up ? home(0) : end(0);
+ }
+ }
+ }
+#endif
+ if (event->modifiers() & Qt::ControlModifier) {
+ switch (event->key()) {
+ case Qt::Key_Backspace:
+ if (!isReadOnly()) {
+ cursorWordBackward(true);
+ del();
+ }
+ break;
+#ifndef QT_NO_COMPLETER
+ case Qt::Key_Up:
+ case Qt::Key_Down:
+ complete(event->key());
+ break;
+#endif
+#if defined(Q_WS_X11)
+ case Qt::Key_E:
+ end(0);
+ break;
+
+ case Qt::Key_U:
+ if (!isReadOnly()) {
+ setSelection(0, text().size());
+#ifndef QT_NO_CLIPBOARD
+ copy();
+#endif
+ del();
+ }
+ break;
+#endif
+ default:
+ unknown = true;
+ }
+ } else { // ### check for *no* modifier
+ switch (event->key()) {
+ case Qt::Key_Backspace:
+ if (!isReadOnly()) {
+ backspace();
+#ifndef QT_NO_COMPLETER
+ complete(Qt::Key_Backspace);
+#endif
+ }
+ break;
+#ifdef QT_KEYPAD_NAVIGATION
+ case Qt::Key_Back:
+ if (QApplication::keypadNavigationEnabled() && !event->isAutoRepeat()
+ && !isReadOnly()) {
+ if (text().length() == 0) {
+ setText(m_cancelText);
+
+ if (passwordEchoEditing())
+ updatePasswordEchoEditing(false);
+
+ // ### TODO this needs to be fixed.
+ // setEditFocus(false);
+ } else if (!m_deleteAllTimer) {
+ m_deleteAllTimer = startTimer(750);
+ }
+ } else {
+ unknown = true;
+ }
+ break;
+#endif
+
+ default:
+ unknown = true;
+ }
+ }
+ }
+
+ if (event->key() == Qt::Key_Direction_L || event->key() == Qt::Key_Direction_R) {
+ setLayoutDirection((event->key() == Qt::Key_Direction_L) ? Qt::LeftToRight : Qt::RightToLeft);
+ unknown = false;
+ }
+
+ if (unknown && !isReadOnly()) {
+ QString t = event->text();
+ if (!t.isEmpty() && t.at(0).isPrint()) {
+ insert(t);
+#ifndef QT_NO_COMPLETER
+ complete(event->key());
+#endif
+ event->accept();
+ return;
+ }
+ }
+
+ if (unknown)
+ event->ignore();
+ else
+ event->accept();
+}
+
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/gui/widgets/qlinecontrol_p.h b/src/gui/widgets/qlinecontrol_p.h
new file mode 100644
index 0000000..9cad857
--- /dev/null
+++ b/src/gui/widgets/qlinecontrol_p.h
@@ -0,0 +1,741 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLINECONTROL_P_H
+#define QLINECONTROL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "QtCore/qglobal.h"
+
+#ifndef QT_NO_LINEEDIT
+#include "private/qwidget_p.h"
+#include "QtGui/qlineedit.h"
+#include "QtGui/qtextlayout.h"
+#include "QtGui/qstyleoption.h"
+#include "QtCore/qpointer.h"
+#include "QtGui/qlineedit.h"
+#include "QtGui/qclipboard.h"
+#include "QtCore/qpoint.h"
+#include "QtGui/qcompleter.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class Q_GUI_EXPORT QLineControl : public QObject
+{
+ Q_OBJECT
+
+public:
+ QLineControl(const QString &txt = QString())
+ : m_cursor(0), m_preeditCursor(0), m_layoutDirection(Qt::LeftToRight),
+ m_hideCursor(false), m_separator(0), m_readOnly(0),
+ m_dragEnabled(0), m_echoMode(0), m_textDirty(0), m_selDirty(0),
+ m_validInput(1), m_blinkPeriod(0), m_blinkTimer(0), m_deleteAllTimer(0),
+ m_ascent(0), m_maxLength(32767), m_lastCursorPos(-1),
+ m_tripleClickTimer(0), m_maskData(0), m_modifiedState(0), m_undoState(0),
+ m_selstart(0), m_selend(0), m_passwordEchoEditing(false)
+ {
+ init(txt);
+ }
+
+ ~QLineControl()
+ {
+ delete [] m_maskData;
+ }
+
+ int nextMaskBlank(int pos);
+ int prevMaskBlank(int pos);
+
+ bool isUndoAvailable() const;
+ bool isRedoAvailable() const;
+ void clearUndo();
+ bool isModified() const;
+ void setModified(bool modified);
+
+ bool allSelected() const;
+ bool hasSelectedText() const;
+
+ int width() const;
+ int height() const;
+ int ascent() const;
+
+ void setSelection(int start, int length);
+
+ QString selectedText() const;
+ QString textBeforeSelection() const;
+ QString textAfterSelection() const;
+
+ int selectionStart() const;
+ int selectionEnd() const;
+ bool inSelection(int x) const;
+
+ void removeSelection();
+
+ int start() const;
+ int end() const;
+
+#ifndef QT_NO_CLIPBOARD
+ void copy(QClipboard::Mode mode = QClipboard::Clipboard) const;
+ void paste();
+#endif
+
+ int cursor() const;
+ int preeditCursor() const;
+
+ int cursorWidth() const;
+ void setCursorWidth(int value);
+
+ void moveCursor(int pos, bool mark = false);
+ void cursorForward(bool mark, int steps);
+ void cursorWordForward(bool mark);
+ void cursorWordBackward(bool mark);
+ void home(bool mark);
+ void end(bool mark);
+
+ int xToPos(int x, QTextLine::CursorPosition = QTextLine::CursorBetweenCharacters) const;
+ QRect cursorRect() const;
+
+ qreal cursorToX(int cursor) const;
+ qreal cursorToX() const;
+
+ bool isReadOnly() const;
+ void setReadOnly(bool enable);
+
+ QString text() const;
+ void setText(const QString &txt);
+
+ QString displayText() const;
+
+ void backspace();
+ void del();
+ void deselect();
+ void selectAll();
+ void insert(const QString &);
+ void clear();
+ void undo();
+ void redo();
+ void selectWordAtPos(int);
+
+ uint echoMode() const;
+ void setEchoMode(uint mode);
+
+ void setMaxLength(int maxLength);
+ int maxLength() const;
+
+ const QValidator *validator() const;
+ void setValidator(const QValidator *);
+
+#ifndef QT_NO_COMPLETER
+ QCompleter *completer() const;
+ void setCompleter(const QCompleter*);
+ void complete(int key);
+#endif
+
+ void setCursorPosition(int pos);
+ int cursorPosition() const;
+
+ bool hasAcceptableInput() const;
+ bool fixup();
+
+ QString inputMask() const;
+ void setInputMask(const QString &mask);
+
+ // input methods
+#ifndef QT_NO_IM
+ bool composeMode() const;
+ void setPreeditArea(int cursor, const QString &text);
+#endif
+
+ QString preeditAreaText() const;
+
+ void updatePasswordEchoEditing(bool editing);
+ bool passwordEchoEditing() const;
+
+ QChar passwordCharacter() const;
+ void setPasswordCharacter(const QChar &character);
+
+ Qt::LayoutDirection layoutDirection() const;
+ void setLayoutDirection(Qt::LayoutDirection direction);
+ void setFont(const QFont &font);
+
+ void processInputMethodEvent(QInputMethodEvent *event);
+ void processMouseEvent(QMouseEvent* ev);
+ void processKeyEvent(QKeyEvent* ev);
+
+ int cursorBlinkPeriod() const;
+ void setCursorBlinkPeriod(int msec);
+
+ QString cancelText() const;
+ void setCancelText(const QString &text);
+
+ enum DrawFlags {
+ DrawText = 0x01,
+ DrawSelections = 0x02,
+ DrawCursor = 0x04,
+ DrawAll = DrawText | DrawSelections | DrawCursor
+ };
+ void draw(QPainter *, const QPoint &, const QRect &, int flags = DrawAll);
+
+ bool processEvent(QEvent *ev);
+
+private:
+ void init(const QString &txt);
+ void removeSelectedText();
+ void internalSetText(const QString &txt, int pos = -1, bool edited = true);
+ void updateDisplayText();
+
+ void internalInsert(const QString &s);
+ void internalDelete(bool wasBackspace = false);
+ void internalRemove(int pos);
+
+ inline void internalDeselect()
+ {
+ m_selDirty |= (m_selend > m_selstart);
+ m_selstart = m_selend = 0;
+ }
+
+ void internalUndo(int until = -1);
+ void internalRedo();
+
+ QString m_text;
+ QPalette m_palette;
+ int m_cursor;
+ int m_preeditCursor;
+ int m_cursorWidth;
+ Qt::LayoutDirection m_layoutDirection;
+ uint m_hideCursor : 1; // used to hide the m_cursor inside preedit areas
+ uint m_separator : 1;
+ uint m_readOnly : 1;
+ uint m_dragEnabled : 1;
+ uint m_echoMode : 2;
+ uint m_textDirty : 1;
+ uint m_selDirty : 1;
+ uint m_validInput : 1;
+ int m_blinkPeriod; // 0 for non-blinking cursor
+ int m_blinkTimer;
+ int m_deleteAllTimer;
+ int m_blinkStatus;
+ int m_ascent;
+ int m_maxLength;
+ int m_lastCursorPos;
+ QList<int> m_transactions;
+ QPoint m_tripleClick;
+ int m_tripleClickTimer;
+ QString m_cancelText;
+
+ void emitCursorPositionChanged();
+
+ bool finishChange(int validateFromState = -1, bool update = false, bool edited = true);
+
+ QPointer<QValidator> m_validator;
+ QPointer<QCompleter> m_completer;
+#ifndef QT_NO_COMPLETER
+ bool advanceToEnabledItem(int dir);
+#endif
+
+ struct MaskInputData {
+ enum Casemode { NoCaseMode, Upper, Lower };
+ QChar maskChar; // either the separator char or the inputmask
+ bool separator;
+ Casemode caseMode;
+ };
+ QString m_inputMask;
+ QChar m_blank;
+ MaskInputData *m_maskData;
+
+ // undo/redo handling
+ enum CommandType { Separator, Insert, Remove, Delete, RemoveSelection, DeleteSelection, SetSelection };
+ struct Command {
+ inline Command() {}
+ inline Command(CommandType t, int p, QChar c, int ss, int se) : type(t),uc(c),pos(p),selStart(ss),selEnd(se) {}
+ uint type : 4;
+ QChar uc;
+ int pos, selStart, selEnd;
+ };
+ int m_modifiedState;
+ int m_undoState;
+ QVector<Command> m_history;
+ void addCommand(const Command& cmd);
+
+ inline void separate() { m_separator = true; }
+
+ // selection
+ int m_selstart;
+ int m_selend;
+
+ // masking
+ void parseInputMask(const QString &maskFields);
+ bool isValidInput(QChar key, QChar mask) const;
+ bool hasAcceptableInput(const QString &text) const;
+ QString maskString(uint pos, const QString &str, bool clear = false) const;
+ QString clearString(uint pos, uint len) const;
+ QString stripString(const QString &str) const;
+ int findInMask(int pos, bool forward, bool findSeparator, QChar searchChar = QChar()) const;
+
+ // complex text layout
+ QTextLayout m_textLayout;
+
+ bool m_passwordEchoEditing;
+ QChar m_passwordCharacter;
+
+Q_SIGNALS:
+ void cursorPositionChanged(int, int);
+ void selectionChanged();
+
+ void displayTextChanged(const QString &);
+ void textChanged(const QString &);
+ void textEdited(const QString &);
+
+ void resetInputContext();
+
+ void accepted();
+ void editingFinished();
+ void updateNeeded(const QRect &);
+
+protected:
+ virtual void timerEvent(QTimerEvent *event);
+
+private slots:
+ void _q_clipboardChanged();
+ void _q_deleteSelected();
+
+};
+
+inline int QLineControl::nextMaskBlank(int pos)
+{
+ int c = findInMask(pos, true, false);
+ m_separator |= (c != pos);
+ return (c != -1 ? c : m_maxLength);
+}
+
+inline int QLineControl::prevMaskBlank(int pos)
+{
+ int c = findInMask(pos, false, false);
+ m_separator |= (c != pos);
+ return (c != -1 ? c : 0);
+}
+
+inline bool QLineControl::isUndoAvailable() const
+{
+ return !m_readOnly && m_undoState;
+}
+
+inline bool QLineControl::isRedoAvailable() const
+{
+ return !m_readOnly && m_undoState < (int)m_history.size();
+}
+
+inline void QLineControl::clearUndo()
+{
+ m_history.clear();
+ m_modifiedState = m_undoState = 0;
+}
+
+inline bool QLineControl::isModified() const
+{
+ return m_modifiedState != m_undoState;
+}
+
+inline void QLineControl::setModified(bool modified)
+{
+ m_modifiedState = modified ? -1 : m_undoState;
+}
+
+inline bool QLineControl::allSelected() const
+{
+ return !m_text.isEmpty() && m_selstart == 0 && m_selend == (int)m_text.length();
+}
+
+inline bool QLineControl::hasSelectedText() const
+{
+ return !m_text.isEmpty() && m_selend > m_selstart;
+}
+
+inline int QLineControl::width() const
+{
+ return qRound(m_textLayout.lineAt(0).width()) + 1;
+}
+
+inline int QLineControl::height() const
+{
+ return qRound(m_textLayout.lineAt(0).height()) + 1;
+}
+
+inline int QLineControl::ascent() const
+{
+ return m_ascent;
+}
+
+inline QString QLineControl::selectedText() const
+{
+ if (hasSelectedText())
+ return m_text.mid(m_selstart, m_selend - m_selstart);
+ return QString();
+}
+
+inline QString QLineControl::textBeforeSelection() const
+{
+ if (hasSelectedText())
+ return m_text.left(m_selstart);
+ return QString();
+}
+
+inline QString QLineControl::textAfterSelection() const
+{
+ if (hasSelectedText())
+ return m_text.mid(m_selend);
+ return QString();
+}
+
+inline int QLineControl::selectionStart() const
+{
+ return hasSelectedText() ? m_selstart : -1;
+}
+
+inline int QLineControl::selectionEnd() const
+{
+ return hasSelectedText() ? m_selend : -1;
+}
+
+inline int QLineControl::start() const
+{
+ return 0;
+}
+
+inline int QLineControl::end() const
+{
+ return m_text.length();
+}
+
+inline void QLineControl::removeSelection()
+{
+ int priorState = m_undoState;
+ removeSelectedText();
+ finishChange(priorState);
+}
+
+inline bool QLineControl::inSelection(int x) const
+{
+ if (m_selstart >= m_selend)
+ return false;
+ int pos = xToPos(x, QTextLine::CursorOnCharacter);
+ return pos >= m_selstart && pos < m_selend;
+}
+
+inline int QLineControl::cursor() const
+{
+ return m_cursor;
+}
+
+inline int QLineControl::preeditCursor() const
+{
+ return m_preeditCursor;
+}
+
+inline int QLineControl::cursorWidth() const
+{
+ return m_cursorWidth;
+}
+
+inline void QLineControl::setCursorWidth(int value)
+{
+ m_cursorWidth = value;
+}
+
+inline void QLineControl::cursorForward(bool mark, int steps)
+{
+ int c = m_cursor;
+ if (steps > 0) {
+ while (steps--)
+ c = m_textLayout.nextCursorPosition(c);
+ } else if (steps < 0) {
+ while (steps++)
+ c = m_textLayout.previousCursorPosition(c);
+ }
+ moveCursor(c, mark);
+}
+
+inline void QLineControl::cursorWordForward(bool mark)
+{
+ moveCursor(m_textLayout.nextCursorPosition(m_cursor, QTextLayout::SkipWords), mark);
+}
+
+inline void QLineControl::home(bool mark)
+{
+ moveCursor(0, mark);
+}
+
+inline void QLineControl::end(bool mark)
+{
+ moveCursor(text().length(), mark);
+}
+
+inline void QLineControl::cursorWordBackward(bool mark)
+{
+ moveCursor(m_textLayout.previousCursorPosition(m_cursor, QTextLayout::SkipWords), mark);
+}
+
+inline qreal QLineControl::cursorToX(int cursor) const
+{
+ return m_textLayout.lineAt(0).cursorToX(cursor);
+}
+
+inline qreal QLineControl::cursorToX() const
+{
+ return cursorToX(m_cursor);
+}
+
+inline bool QLineControl::isReadOnly() const
+{
+ return m_readOnly;
+}
+
+inline void QLineControl::setReadOnly(bool enable)
+{
+ m_readOnly = enable;
+}
+
+inline QString QLineControl::text() const
+{
+ QString res = m_maskData ? stripString(m_text) : m_text;
+ return (res.isNull() ? QString::fromLatin1("") : res);
+}
+
+inline void QLineControl::setText(const QString &txt)
+{
+ internalSetText(txt, -1, false);
+}
+
+inline QString QLineControl::displayText() const
+{
+ return m_textLayout.text();
+}
+
+inline void QLineControl::deselect()
+{
+ internalDeselect();
+ finishChange();
+}
+
+inline void QLineControl::selectAll()
+{
+ m_selstart = m_selend = m_cursor = 0;
+ moveCursor(m_text.length(), true);
+}
+
+inline void QLineControl::undo()
+{
+ internalUndo();
+ finishChange(-1, true);
+}
+
+inline void QLineControl::redo()
+{
+ internalRedo();
+ finishChange();
+}
+
+inline uint QLineControl::echoMode() const
+{
+ return m_echoMode;
+}
+
+inline void QLineControl::setEchoMode(uint mode)
+{
+ m_echoMode = mode;
+ m_passwordEchoEditing = false;
+ updateDisplayText();
+}
+
+inline void QLineControl::setMaxLength(int maxLength)
+{
+ if (m_maskData)
+ return;
+ m_maxLength = maxLength;
+ setText(m_text);
+}
+
+inline int QLineControl::maxLength() const
+{
+ return m_maxLength;
+}
+
+inline const QValidator *QLineControl::validator() const
+{
+ return m_validator;
+}
+
+inline void QLineControl::setValidator(const QValidator *v)
+{
+ m_validator = const_cast<QValidator*>(v);
+}
+
+#ifndef QT_NO_COMPLETER
+inline QCompleter *QLineControl::completer() const
+{
+ return m_completer;
+}
+
+/* Note that you must set the widget for the completer seperately */
+inline void QLineControl::setCompleter(const QCompleter* c)
+{
+ m_completer = const_cast<QCompleter*>(c);
+}
+#endif
+
+inline void QLineControl::setCursorPosition(int pos)
+{
+ if (pos < 0)
+ pos = 0;
+ if (pos < m_text.length())
+ moveCursor(pos);
+}
+
+inline int QLineControl::cursorPosition() const
+{
+ return m_cursor;
+}
+
+inline bool QLineControl::hasAcceptableInput() const
+{
+ return hasAcceptableInput(m_text);
+}
+
+inline QString QLineControl::inputMask() const
+{
+ return m_maskData ? m_inputMask + QLatin1Char(';') + m_blank : QString();
+}
+
+inline void QLineControl::setInputMask(const QString &mask)
+{
+ parseInputMask(mask);
+ if (m_maskData)
+ moveCursor(nextMaskBlank(0));
+}
+
+// input methods
+#ifndef QT_NO_IM
+inline bool QLineControl::composeMode() const
+{
+ return !m_textLayout.preeditAreaText().isEmpty();
+}
+
+inline void QLineControl::setPreeditArea(int cursor, const QString &text)
+{
+ m_textLayout.setPreeditArea(cursor, text);
+}
+#endif
+
+inline QString QLineControl::preeditAreaText() const
+{
+ return m_textLayout.preeditAreaText();
+}
+
+inline bool QLineControl::passwordEchoEditing() const
+{
+ return m_passwordEchoEditing;
+}
+
+inline QChar QLineControl::passwordCharacter() const
+{
+ return m_passwordCharacter;
+}
+
+inline void QLineControl::setPasswordCharacter(const QChar &character)
+{
+ m_passwordCharacter = character;
+ updateDisplayText();
+}
+
+inline Qt::LayoutDirection QLineControl::layoutDirection() const
+{
+ return m_layoutDirection;
+}
+
+inline void QLineControl::setLayoutDirection(Qt::LayoutDirection direction)
+{
+ if (direction != m_layoutDirection) {
+ m_layoutDirection = direction;
+ updateDisplayText();
+ }
+}
+
+inline void QLineControl::setFont(const QFont &font)
+{
+ m_textLayout.setFont(font);
+ updateDisplayText();
+}
+
+inline int QLineControl::cursorBlinkPeriod() const
+{
+ return m_blinkPeriod;
+}
+
+inline QString QLineControl::cancelText() const
+{
+ return m_cancelText;
+}
+
+inline void QLineControl::setCancelText(const QString &text)
+{
+ m_cancelText = text;
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QT_NO_LINEEDIT
+
+#endif // QLINECONTROL_P_H
diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp
index 4d69a9f..8ab30fa 100644
--- a/src/gui/widgets/qlineedit.cpp
+++ b/src/gui/widgets/qlineedit.cpp
@@ -86,20 +86,12 @@
#include <limits.h>
-#define verticalMargin 1
-#define horizontalMargin 2
-
QT_BEGIN_NAMESPACE
#ifdef Q_WS_MAC
extern void qt_mac_secure_keyboard(bool); //qapplication_mac.cpp
#endif
-static inline bool shouldEnableInputMethod(QLineEdit *lineedit)
-{
- return !lineedit->isReadOnly();
-}
-
/*!
Initialize \a option with the values from this QLineEdit. This method
is useful for subclasses when they need a QStyleOptionFrame or QStyleOptionFrameV2, but don't want
@@ -121,7 +113,7 @@ void QLineEdit::initStyleOption(QStyleOptionFrame *option) const
: 0;
option->midLineWidth = 0;
option->state |= QStyle::State_Sunken;
- if (d->readOnly)
+ if (d->control->isReadOnly())
option->state |= QStyle::State_ReadOnly;
#ifdef QT_KEYPAD_NAVIGATION
if (hasEditFocus())
@@ -349,14 +341,9 @@ QLineEdit::QLineEdit(const QString& contents, const QString &inputMask, QWidget*
{
Q_D(QLineEdit);
setObjectName(QString::fromAscii(name));
- d->parseInputMask(inputMask);
- if (d->maskData) {
- QString ms = d->maskString(0, contents);
- d->init(ms + d->clearString(ms.length(), d->maxLength - ms.length()));
- d->cursor = d->nextMaskBlank(ms.length());
- } else {
- d->init(contents);
- }
+ d->init(contents);
+ d->control->setInputMask(inputMask);
+ d->control->moveCursor(d->control->nextMaskBlank(contents.length()));
}
#endif
@@ -387,19 +374,13 @@ QLineEdit::~QLineEdit()
QString QLineEdit::text() const
{
Q_D(const QLineEdit);
- QString res = d->text;
- if (d->maskData)
- res = d->stripString(d->text);
- return (res.isNull() ? QString::fromLatin1("") : res);
+ return d->control->text();
}
void QLineEdit::setText(const QString& text)
{
Q_D(QLineEdit);
- d->setText(text, -1, false);
-#ifdef QT_KEYPAD_NAVIGATION
- d->origText = d->text;
-#endif
+ d->control->setText(text);
}
@@ -420,17 +401,7 @@ void QLineEdit::setText(const QString& text)
QString QLineEdit::displayText() const
{
Q_D(const QLineEdit);
- if (d->echoMode == NoEcho)
- return QString::fromLatin1("");
- QString res = d->text;
-
- if (d->echoMode == Password || (d->echoMode == PasswordEchoOnEdit
- && !d->passwordEchoEditing)) {
- QStyleOptionFrameV2 opt;
- initStyleOption(&opt);
- res.fill(style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, &opt, this));
- }
- return (res.isNull() ? QString::fromLatin1("") : res);
+ return d->control->displayText();
}
@@ -455,20 +426,15 @@ QString QLineEdit::displayText() const
int QLineEdit::maxLength() const
{
Q_D(const QLineEdit);
- return d->maxLength;
+ return d->control->maxLength();
}
void QLineEdit::setMaxLength(int maxLength)
{
Q_D(QLineEdit);
- if (d->maskData)
- return;
- d->maxLength = maxLength;
- setText(d->text);
+ d->control->setMaxLength(maxLength);
}
-
-
/*!
\property QLineEdit::frame
\brief whether the line edit draws itself with a frame
@@ -535,13 +501,13 @@ void QLineEdit::setFrame(bool enable)
QLineEdit::EchoMode QLineEdit::echoMode() const
{
Q_D(const QLineEdit);
- return (EchoMode) d->echoMode;
+ return (EchoMode) d->control->echoMode();
}
void QLineEdit::setEchoMode(EchoMode mode)
{
Q_D(QLineEdit);
- if (mode == (EchoMode)d->echoMode)
+ if (mode == (EchoMode)d->control->echoMode())
return;
Qt::InputMethodHints imHints = inputMethodHints();
if (mode == Password) {
@@ -550,13 +516,11 @@ void QLineEdit::setEchoMode(EchoMode mode)
imHints &= ~Qt::ImhHiddenText;
}
setInputMethodHints(imHints);
- d->echoMode = mode;
- d->passwordEchoEditing = false;
- d->updateTextLayout();
+ d->control->setEchoMode(mode);
update();
#ifdef Q_WS_MAC
if (hasFocus())
- qt_mac_secure_keyboard(d->echoMode == Password || d->echoMode == NoEcho);
+ qt_mac_secure_keyboard(mode == Password || mode == NoEcho);
#endif
}
@@ -572,7 +536,7 @@ void QLineEdit::setEchoMode(EchoMode mode)
const QValidator * QLineEdit::validator() const
{
Q_D(const QLineEdit);
- return d->validator;
+ return d->control->validator();
}
/*!
@@ -590,7 +554,7 @@ const QValidator * QLineEdit::validator() const
void QLineEdit::setValidator(const QValidator *v)
{
Q_D(QLineEdit);
- d->validator = const_cast<QValidator*>(v);
+ d->control->setValidator(v);
}
#endif // QT_NO_VALIDATOR
@@ -614,23 +578,23 @@ void QLineEdit::setValidator(const QValidator *v)
void QLineEdit::setCompleter(QCompleter *c)
{
Q_D(QLineEdit);
- if (c == d->completer)
+ if (c == d->control->completer())
return;
- if (d->completer) {
- disconnect(d->completer, 0, this, 0);
- d->completer->setWidget(0);
- if (d->completer->parent() == this)
- delete d->completer;
+ if (d->control->completer()) {
+ disconnect(d->control->completer(), 0, this, 0);
+ d->control->completer()->setWidget(0);
+ if (d->control->completer()->parent() == this)
+ delete d->control->completer();
}
- d->completer = c;
+ d->control->setCompleter(c);
if (!c)
return;
if (c->widget() == 0)
c->setWidget(this);
if (hasFocus()) {
- QObject::connect(d->completer, SIGNAL(activated(QString)),
+ QObject::connect(d->control->completer(), SIGNAL(activated(QString)),
this, SLOT(setText(QString)));
- QObject::connect(d->completer, SIGNAL(highlighted(QString)),
+ QObject::connect(d->control->completer(), SIGNAL(highlighted(QString)),
this, SLOT(_q_completionHighlighted(QString)));
}
}
@@ -643,83 +607,9 @@ void QLineEdit::setCompleter(QCompleter *c)
QCompleter *QLineEdit::completer() const
{
Q_D(const QLineEdit);
- return d->completer;
-}
-
-// looks for an enabled item iterating forward(dir=1)/backward(dir=-1) from the
-// current row based. dir=0 indicates a new completion prefix was set.
-bool QLineEditPrivate::advanceToEnabledItem(int dir)
-{
- int start = completer->currentRow();
- if (start == -1)
- return false;
- int i = start + dir;
- if (dir == 0) dir = 1;
- do {
- if (!completer->setCurrentRow(i)) {
- if (!completer->wrapAround())
- break;
- i = i > 0 ? 0 : completer->completionCount() - 1;
- } else {
- QModelIndex currentIndex = completer->currentIndex();
- if (completer->completionModel()->flags(currentIndex) & Qt::ItemIsEnabled)
- return true;
- i += dir;
- }
- } while (i != start);
-
- completer->setCurrentRow(start); // restore
- return false;
-}
-
-void QLineEditPrivate::complete(int key)
-{
- if (!completer || readOnly || echoMode != QLineEdit::Normal)
- return;
-
- if (completer->completionMode() == QCompleter::InlineCompletion) {
- if (key == Qt::Key_Backspace)
- return;
- int n = 0;
- if (key == Qt::Key_Up || key == Qt::Key_Down) {
- if (selend != 0 && selend != text.length())
- return;
- QString prefix = hasSelectedText() ? text.left(selstart) : text;
- if (text.compare(completer->currentCompletion(), completer->caseSensitivity()) != 0
- || prefix.compare(completer->completionPrefix(), completer->caseSensitivity()) != 0) {
- completer->setCompletionPrefix(prefix);
- } else {
- n = (key == Qt::Key_Up) ? -1 : +1;
- }
- } else {
- completer->setCompletionPrefix(text);
- }
- if (!advanceToEnabledItem(n))
- return;
- } else {
-#ifndef QT_KEYPAD_NAVIGATION
- if (text.isEmpty()) {
- completer->popup()->hide();
- return;
- }
-#endif
- completer->setCompletionPrefix(text);
- }
-
- completer->complete();
+ return d->control->completer();
}
-void QLineEditPrivate::_q_completionHighlighted(QString newText)
-{
- Q_Q(QLineEdit);
- if (completer->completionMode() != QCompleter::InlineCompletion)
- q->setText(newText);
- else {
- int c = cursor;
- q->setText(text.left(c) + newText.mid(c));
- q->setSelection(text.length(), c - newText.length());
- }
-}
#endif // QT_NO_COMPLETER
/*!
@@ -734,10 +624,10 @@ QSize QLineEdit::sizeHint() const
Q_D(const QLineEdit);
ensurePolished();
QFontMetrics fm(font());
- int h = qMax(fm.lineSpacing(), 14) + 2*verticalMargin
+ int h = qMax(fm.lineSpacing(), 14) + 2*d->verticalMargin
+ d->topTextMargin + d->bottomTextMargin
+ d->topmargin + d->bottommargin;
- int w = fm.width(QLatin1Char('x')) * 17 + 2*horizontalMargin
+ int w = fm.width(QLatin1Char('x')) * 17 + 2*d->horizontalMargin
+ d->leftTextMargin + d->rightTextMargin
+ d->leftmargin + d->rightmargin; // "some"
QStyleOptionFrameV2 opt;
@@ -758,7 +648,7 @@ QSize QLineEdit::minimumSizeHint() const
Q_D(const QLineEdit);
ensurePolished();
QFontMetrics fm = fontMetrics();
- int h = fm.height() + qMax(2*verticalMargin, fm.leading())
+ int h = fm.height() + qMax(2*d->verticalMargin, fm.leading())
+ d->topmargin + d->bottommargin;
int w = fm.maxWidth() + d->leftmargin + d->rightmargin;
QStyleOptionFrameV2 opt;
@@ -780,17 +670,13 @@ QSize QLineEdit::minimumSizeHint() const
int QLineEdit::cursorPosition() const
{
Q_D(const QLineEdit);
- return d->cursor;
+ return d->control->cursorPosition();
}
void QLineEdit::setCursorPosition(int pos)
{
Q_D(QLineEdit);
- if (pos < 0)
- pos = 0;
-
- if (pos <= d->text.length())
- d->moveCursor(pos);
+ d->control->setCursorPosition(pos);
}
/*!
@@ -812,22 +698,17 @@ int QLineEdit::cursorPositionAt(const QPoint &pos)
bool QLineEdit::validateAndSet(const QString &newText, int newPos,
int newMarkAnchor, int newMarkDrag)
{
- Q_D(QLineEdit);
- int priorState = d->undoState;
- d->selstart = 0;
- d->selend = d->text.length();
- d->removeSelectedText();
- d->insert(newText);
- d->finishChange(priorState);
- if (d->undoState > priorState) {
- d->cursor = newPos;
- d->selstart = qMin(newMarkAnchor, newMarkDrag);
- d->selend = qMax(newMarkAnchor, newMarkDrag);
- update();
- d->emitCursorPositionChanged();
- return true;
+ // The suggested functions above in the docs don't seem to validate,
+ // below code tries to mimic previous behaviour.
+ QString oldText = text();
+ setText(newText);
+ if(!hasAcceptableInput()){
+ setText(oldText);
+ return false;
}
- return false;
+ setCursorPosition(newPos);
+ setSelection(qMin(newMarkAnchor, newMarkDrag), qAbs(newMarkAnchor - newMarkDrag));
+ return true;
}
#endif //QT3_SUPPORT
@@ -868,15 +749,7 @@ void QLineEdit::setAlignment(Qt::Alignment alignment)
void QLineEdit::cursorForward(bool mark, int steps)
{
Q_D(QLineEdit);
- int cursor = d->cursor;
- if (steps > 0) {
- while(steps--)
- cursor = d->textLayout.nextCursorPosition(cursor);
- } else if (steps < 0) {
- while (steps++)
- cursor = d->textLayout.previousCursorPosition(cursor);
- }
- d->moveCursor(cursor, mark);
+ d->control->cursorForward(mark, steps);
}
@@ -901,7 +774,7 @@ void QLineEdit::cursorBackward(bool mark, int steps)
void QLineEdit::cursorWordForward(bool mark)
{
Q_D(QLineEdit);
- d->moveCursor(d->textLayout.nextCursorPosition(d->cursor, QTextLayout::SkipWords), mark);
+ d->control->cursorWordForward(mark);
}
/*!
@@ -914,7 +787,7 @@ void QLineEdit::cursorWordForward(bool mark)
void QLineEdit::cursorWordBackward(bool mark)
{
Q_D(QLineEdit);
- d->moveCursor(d->textLayout.previousCursorPosition(d->cursor, QTextLayout::SkipWords), mark);
+ d->control->cursorWordBackward(mark);
}
@@ -929,26 +802,7 @@ void QLineEdit::cursorWordBackward(bool mark)
void QLineEdit::backspace()
{
Q_D(QLineEdit);
- int priorState = d->undoState;
- if (d->hasSelectedText()) {
- d->removeSelectedText();
- } else if (d->cursor) {
- --d->cursor;
- if (d->maskData)
- d->cursor = d->prevMaskBlank(d->cursor);
- QChar uc = d->text.at(d->cursor);
- if (d->cursor > 0 && uc.unicode() >= 0xdc00 && uc.unicode() < 0xe000) {
- // second half of a surrogate, check if we have the first half as well,
- // if yes delete both at once
- uc = d->text.at(d->cursor - 1);
- if (uc.unicode() >= 0xd800 && uc.unicode() < 0xdc00) {
- d->del(true);
- --d->cursor;
- }
- }
- d->del(true);
- }
- d->finishChange(priorState);
+ d->control->backspace();
}
/*!
@@ -962,15 +816,7 @@ void QLineEdit::backspace()
void QLineEdit::del()
{
Q_D(QLineEdit);
- int priorState = d->undoState;
- if (d->hasSelectedText()) {
- d->removeSelectedText();
- } else {
- int n = d->textLayout.nextCursorPosition(d->cursor) - d->cursor;
- while (n--)
- d->del();
- }
- d->finishChange(priorState);
+ d->control->del();
}
/*!
@@ -985,7 +831,7 @@ void QLineEdit::del()
void QLineEdit::home(bool mark)
{
Q_D(QLineEdit);
- d->moveCursor(0, mark);
+ d->control->home(mark);
}
/*!
@@ -1000,7 +846,7 @@ void QLineEdit::home(bool mark)
void QLineEdit::end(bool mark)
{
Q_D(QLineEdit);
- d->moveCursor(d->text.length(), mark);
+ d->control->end(mark);
}
@@ -1025,16 +871,13 @@ void QLineEdit::end(bool mark)
bool QLineEdit::isModified() const
{
Q_D(const QLineEdit);
- return d->modifiedState != d->undoState;
+ return d->control->isModified();
}
void QLineEdit::setModified(bool modified)
{
Q_D(QLineEdit);
- if (modified)
- d->modifiedState = -1;
- else
- d->modifiedState = d->undoState;
+ d->control->setModified(modified);
}
@@ -1062,7 +905,7 @@ Use setModified(false) instead.
bool QLineEdit::hasSelectedText() const
{
Q_D(const QLineEdit);
- return d->hasSelectedText();
+ return d->control->hasSelectedText();
}
/*!
@@ -1080,9 +923,7 @@ bool QLineEdit::hasSelectedText() const
QString QLineEdit::selectedText() const
{
Q_D(const QLineEdit);
- if (d->hasSelectedText())
- return d->text.mid(d->selstart, d->selend - d->selstart);
- return QString();
+ return d->control->selectedText();
}
/*!
@@ -1095,7 +936,7 @@ QString QLineEdit::selectedText() const
int QLineEdit::selectionStart() const
{
Q_D(const QLineEdit);
- return d->hasSelectedText() ? d->selstart : -1;
+ return d->control->selectionStart();
}
@@ -1125,9 +966,10 @@ void QLineEdit::setEdited(bool on) { setModified(on); }
int QLineEdit::characterAt(int xpos, QChar *chr) const
{
Q_D(const QLineEdit);
- int pos = d->xToPos(xpos + contentsRect().x() - d->hscroll + horizontalMargin);
- if (chr && pos < (int) d->text.length())
- *chr = d->text.at(pos);
+ int pos = d->xToPos(xpos + contentsRect().x() - d->hscroll + d->horizontalMargin);
+ QString txt = d->control->text();
+ if (chr && pos < (int) txt.length())
+ *chr = txt.at(pos);
return pos;
}
@@ -1138,9 +980,9 @@ int QLineEdit::characterAt(int xpos, QChar *chr) const
bool QLineEdit::getSelection(int *start, int *end)
{
Q_D(QLineEdit);
- if (d->hasSelectedText() && start && end) {
- *start = d->selstart;
- *end = d->selend;
+ if (d->control->hasSelectedText() && start && end) {
+ *start = selectionStart();
+ *end = *start + selectedText().length();
return true;
}
return false;
@@ -1158,30 +1000,19 @@ bool QLineEdit::getSelection(int *start, int *end)
void QLineEdit::setSelection(int start, int length)
{
Q_D(QLineEdit);
- if (start < 0 || start > (int)d->text.length()) {
+ if (start < 0 || start > (int)d->control->text().length()) {
qWarning("QLineEdit::setSelection: Invalid start position (%d)", start);
return;
- } else {
- if (length > 0) {
- d->selstart = start;
- d->selend = qMin(start + length, (int)d->text.length());
- d->cursor = d->selend;
- } else {
- d->selstart = qMax(start + length, 0);
- d->selend = start;
- d->cursor = d->selstart;
- }
}
- if (d->hasSelectedText()){
+ d->control->setSelection(start, length);
+
+ if (d->control->hasSelectedText()){
QStyleOptionFrameV2 opt;
initStyleOption(&opt);
if (!style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, this))
d->setCursorVisible(false);
}
-
- update();
- d->emitCursorPositionChanged();
}
@@ -1197,7 +1028,7 @@ void QLineEdit::setSelection(int start, int length)
bool QLineEdit::isUndoAvailable() const
{
Q_D(const QLineEdit);
- return d->isUndoAvailable();
+ return d->control->isUndoAvailable();
}
/*!
@@ -1213,7 +1044,7 @@ bool QLineEdit::isUndoAvailable() const
bool QLineEdit::isRedoAvailable() const
{
Q_D(const QLineEdit);
- return d->isRedoAvailable();
+ return d->control->isRedoAvailable();
}
/*!
@@ -1249,7 +1080,7 @@ void QLineEdit::setDragEnabled(bool b)
bool QLineEdit::hasAcceptableInput() const
{
Q_D(const QLineEdit);
- return d->hasAcceptableInput(d->text);
+ return d->control->hasAcceptableInput();
}
/*!
@@ -1355,15 +1186,13 @@ void QLineEdit::getTextMargins(int *left, int *top, int *right, int *bottom) con
QString QLineEdit::inputMask() const
{
Q_D(const QLineEdit);
- return (d->maskData ? d->inputMask + QLatin1Char(';') + d->blank : QString());
+ return d->control->inputMask();
}
void QLineEdit::setInputMask(const QString &inputMask)
{
Q_D(QLineEdit);
- d->parseInputMask(inputMask);
- if (d->maskData)
- d->moveCursor(d->nextMaskBlank(0));
+ d->control->setInputMask(inputMask);
}
/*!
@@ -1378,8 +1207,7 @@ void QLineEdit::setInputMask(const QString &inputMask)
void QLineEdit::selectAll()
{
Q_D(QLineEdit);
- d->selstart = d->selend = d->cursor = 0;
- d->moveCursor(d->text.length(), true);
+ d->control->selectAll();
}
/*!
@@ -1391,8 +1219,7 @@ void QLineEdit::selectAll()
void QLineEdit::deselect()
{
Q_D(QLineEdit);
- d->deselect();
- d->finishChange();
+ d->control->deselect();
}
@@ -1407,10 +1234,7 @@ void QLineEdit::insert(const QString &newText)
{
// q->resetInputContext(); //#### FIX ME IN QT
Q_D(QLineEdit);
- int priorState = d->undoState;
- d->removeSelectedText();
- d->insert(newText);
- d->finishChange(priorState);
+ d->control->insert(newText);
}
/*!
@@ -1421,13 +1245,8 @@ void QLineEdit::insert(const QString &newText)
void QLineEdit::clear()
{
Q_D(QLineEdit);
- int priorState = d->undoState;
resetInputContext();
- d->selstart = 0;
- d->selend = d->text.length();
- d->removeSelectedText();
- d->separate();
- d->finishChange(priorState, /*update*/false, /*edited*/false);
+ d->control->clear();
}
/*!
@@ -1440,8 +1259,7 @@ void QLineEdit::undo()
{
Q_D(QLineEdit);
resetInputContext();
- d->undo();
- d->finishChange(-1, true);
+ d->control->undo();
}
/*!
@@ -1452,8 +1270,7 @@ void QLineEdit::redo()
{
Q_D(QLineEdit);
resetInputContext();
- d->redo();
- d->finishChange();
+ d->control->redo();
}
@@ -1475,16 +1292,16 @@ void QLineEdit::redo()
bool QLineEdit::isReadOnly() const
{
Q_D(const QLineEdit);
- return d->readOnly;
+ return d->control->isReadOnly();
}
void QLineEdit::setReadOnly(bool enable)
{
Q_D(QLineEdit);
- if (d->readOnly != enable) {
- d->readOnly = enable;
- setAttribute(Qt::WA_MacShowFocusRect, !d->readOnly);
- setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod(this));
+ if (d->control->isReadOnly() != enable) {
+ d->control->setReadOnly(enable);
+ setAttribute(Qt::WA_MacShowFocusRect, !enable);
+ setAttribute(Qt::WA_InputMethodEnabled, d->shouldEnableInputMethod());
#ifndef QT_NO_CURSOR
setCursor(enable ? Qt::ArrowCursor : Qt::IBeamCursor);
#endif
@@ -1523,7 +1340,7 @@ void QLineEdit::cut()
void QLineEdit::copy() const
{
Q_D(const QLineEdit);
- d->copy();
+ d->control->copy();
}
/*!
@@ -1540,23 +1357,7 @@ void QLineEdit::copy() const
void QLineEdit::paste()
{
Q_D(QLineEdit);
- if (echoMode() == PasswordEchoOnEdit && !d->passwordEchoEditing) {
- // Clear the edit and reset to normal echo mode when pasting; the echo
- // mode switches back when the edit loses focus. ### changes a public
- // property, resets current content
- d->updatePasswordEchoEditing(true);
- clear();
- }
- insert(QApplication::clipboard()->text(QClipboard::Clipboard));
-}
-
-void QLineEditPrivate::copy(bool clipboard) const
-{
- Q_Q(const QLineEdit);
- QString t = q->selectedText();
- if (!t.isEmpty() && echoMode == QLineEdit::Normal) {
- QApplication::clipboard()->setText(t, clipboard ? QClipboard::Clipboard : QClipboard::Selection);
- }
+ d->control->paste();
}
#endif // !QT_NO_CLIPBOARD
@@ -1566,57 +1367,10 @@ void QLineEditPrivate::copy(bool clipboard) const
bool QLineEdit::event(QEvent * e)
{
Q_D(QLineEdit);
-#ifndef QT_NO_SHORTCUT
- if (e->type() == QEvent::ShortcutOverride && !d->readOnly) {
- QKeyEvent* ke = (QKeyEvent*) e;
- if (ke == QKeySequence::Copy
- || ke == QKeySequence::Paste
- || ke == QKeySequence::Cut
- || ke == QKeySequence::Redo
- || ke == QKeySequence::Undo
- || ke == QKeySequence::MoveToNextWord
- || ke == QKeySequence::MoveToPreviousWord
- || ke == QKeySequence::MoveToStartOfDocument
- || ke == QKeySequence::MoveToEndOfDocument
- || ke == QKeySequence::SelectNextWord
- || ke == QKeySequence::SelectPreviousWord
- || ke == QKeySequence::SelectStartOfLine
- || ke == QKeySequence::SelectEndOfLine
- || ke == QKeySequence::SelectStartOfBlock
- || ke == QKeySequence::SelectEndOfBlock
- || ke == QKeySequence::SelectStartOfDocument
- || ke == QKeySequence::SelectAll
- || ke == QKeySequence::SelectEndOfDocument) {
- ke->accept();
- } else if (ke->modifiers() == Qt::NoModifier || ke->modifiers() == Qt::ShiftModifier
- || ke->modifiers() == Qt::KeypadModifier) {
- if (ke->key() < Qt::Key_Escape) {
- ke->accept();
- } else {
- switch (ke->key()) {
- case Qt::Key_Delete:
- case Qt::Key_Home:
- case Qt::Key_End:
- case Qt::Key_Backspace:
- case Qt::Key_Left:
- case Qt::Key_Right:
- ke->accept();
- default:
- break;
- }
- }
- }
- } else
-#endif
- if (e->type() == QEvent::Timer) {
+ if (e->type() == QEvent::Timer) {
// should be timerEvent, is here for binary compatibility
int timerId = ((QTimerEvent*)e)->timerId();
- if (timerId == d->cursorTimer) {
- QStyleOptionFrameV2 opt;
- initStyleOption(&opt);
- if(!hasSelectedText()
- || style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, this))
- d->setCursorVisible(!d->cursorVisible);
+ if (false) {
#ifndef QT_NO_DRAGANDDROP
} else if (timerId == d->dndTimer.timerId()) {
d->drag();
@@ -1624,60 +1378,31 @@ bool QLineEdit::event(QEvent * e)
}
else if (timerId == d->tripleClickTimer.timerId())
d->tripleClickTimer.stop();
-#ifdef QT_KEYPAD_NAVIGATION
- else if (timerId == d->deleteAllTimer.timerId()) {
- d->deleteAllTimer.stop();
- clear();
- }
-#endif
} else if (e->type() == QEvent::ContextMenu) {
#ifndef QT_NO_IM
- if (d->composeMode())
+ if (d->control->composeMode())
return true;
#endif
- d->separate();
+ //d->separate();
} else if (e->type() == QEvent::WindowActivate) {
QTimer::singleShot(0, this, SLOT(_q_handleWindowActivate()));
+ }else if(e->type() == QEvent::ShortcutOverride){
+ d->control->processEvent(e);
}
+
#ifdef QT_KEYPAD_NAVIGATION
if (QApplication::keypadNavigationEnabled()) {
- if ((e->type() == QEvent::KeyPress) || (e->type() == QEvent::KeyRelease)) {
- QKeyEvent *ke = (QKeyEvent *)e;
- if (ke->key() == Qt::Key_Back) {
- if (ke->isAutoRepeat()) {
- // Swallow it. We don't want back keys running amok.
- ke->accept();
- return true;
- }
- if ((e->type() == QEvent::KeyRelease)
- && !isReadOnly()
- && d->deleteAllTimer.isActive()) {
- d->deleteAllTimer.stop();
- backspace();
- ke->accept();
- return true;
- }
- }
- } else if (e->type() == QEvent::EnterEditFocus) {
+ if (e->type() == QEvent::EnterEditFocus) {
end(false);
- if (!d->cursorTimer) {
- int cft = QApplication::cursorFlashTime();
- d->cursorTimer = cft ? startTimer(cft/2) : -1;
- }
+ int cft = QApplication::cursorFlashTime();
+ d->control->setCursorBlinkPeriod(cft/2);
} else if (e->type() == QEvent::LeaveEditFocus) {
d->setCursorVisible(false);
- if (d->cursorTimer > 0)
- killTimer(d->cursorTimer);
- d->cursorTimer = 0;
-
- if (!d->emitingEditingFinished) {
- if (hasAcceptableInput() || d->fixup()) {
- d->emitingEditingFinished = true;
- emit editingFinished();
- d->emitingEditingFinished = false;
- }
- }
+ d->control->setCursorBlinkPeriod(0);
+ if (d->control->hasAcceptableInput() || d->control->fixup())
+ emit editingFinished();
}
+ return true;
}
#endif
return QWidget::event(e);
@@ -1689,15 +1414,15 @@ void QLineEdit::mousePressEvent(QMouseEvent* e)
{
Q_D(QLineEdit);
if (d->sendMouseEventToInputContext(e))
- return;
+ return;
if (e->button() == Qt::RightButton)
return;
#ifdef QT_KEYPAD_NAVIGATION
if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) {
setEditFocus(true);
// Get the completion list to pop up.
- if (d->completer)
- d->completer->complete();
+ if (d->control->completer())
+ d->control->completer()->complete();
}
#endif
if (d->tripleClickTimer.isActive() && (e->pos() - d->tripleClick).manhattanLength() <
@@ -1708,18 +1433,16 @@ void QLineEdit::mousePressEvent(QMouseEvent* e)
bool mark = e->modifiers() & Qt::ShiftModifier;
int cursor = d->xToPos(e->pos().x());
#ifndef QT_NO_DRAGANDDROP
- if (!mark && d->dragEnabled && d->echoMode == Normal &&
- e->button() == Qt::LeftButton && d->inSelection(e->pos().x())) {
- d->cursor = cursor;
- update();
+ if (!mark && d->dragEnabled && d->control->echoMode() == Normal &&
+ e->button() == Qt::LeftButton && d->control->inSelection(e->pos().x())) {
+ d->control->moveCursor(cursor);
d->dndPos = e->pos();
if (!d->dndTimer.isActive())
d->dndTimer.start(QApplication::startDragTime(), this);
- d->emitCursorPositionChanged();
} else
#endif
{
- d->moveCursor(cursor, mark);
+ d->control->moveCursor(cursor, mark);
}
}
@@ -1729,7 +1452,7 @@ void QLineEdit::mouseMoveEvent(QMouseEvent * e)
{
Q_D(QLineEdit);
if (d->sendMouseEventToInputContext(e))
- return;
+ return;
if (e->buttons() & Qt::LeftButton) {
#ifndef QT_NO_DRAGANDDROP
@@ -1739,7 +1462,7 @@ void QLineEdit::mouseMoveEvent(QMouseEvent * e)
} else
#endif
{
- d->moveCursor(d->xToPos(e->pos().x()), true);
+ d->control->moveCursor(d->xToPos(e->pos().x()), true);
}
}
}
@@ -1750,7 +1473,7 @@ void QLineEdit::mouseReleaseEvent(QMouseEvent* e)
{
Q_D(QLineEdit);
if (d->sendMouseEventToInputContext(e))
- return;
+ return;
#ifndef QT_NO_DRAGANDDROP
if (e->button() == Qt::LeftButton) {
if (d->dndTimer.isActive()) {
@@ -1763,9 +1486,9 @@ void QLineEdit::mouseReleaseEvent(QMouseEvent* e)
#ifndef QT_NO_CLIPBOARD
if (QApplication::clipboard()->supportsSelection()) {
if (e->button() == Qt::LeftButton) {
- d->copy(false);
- } else if (!d->readOnly && e->button() == Qt::MidButton) {
- d->deselect();
+ d->control->copy(QClipboard::Selection);
+ } else if (!d->control->isReadOnly() && e->button() == Qt::MidButton) {
+ deselect();
insert(QApplication::clipboard()->text(QClipboard::Selection));
}
}
@@ -1785,16 +1508,9 @@ void QLineEdit::mouseDoubleClickEvent(QMouseEvent* e)
{
Q_D(QLineEdit);
if (d->sendMouseEventToInputContext(e))
- return;
+ return;
if (e->button() == Qt::LeftButton) {
- deselect();
- d->cursor = d->xToPos(e->pos().x());
- d->cursor = d->textLayout.previousCursorPosition(d->cursor, QTextLayout::SkipWords);
- // ## text layout should support end of words.
- int end = d->textLayout.nextCursorPosition(d->cursor, QTextLayout::SkipWords);
- while (end > d->cursor && d->text[end-1].isSpace())
- --end;
- d->moveCursor(end, true);
+ d->control->selectWordAtPos(d->xToPos(e->pos().x()));
d->tripleClickTimer.start(QApplication::doubleClickInterval(), this);
d->tripleClick = e->pos();
}
@@ -1834,65 +1550,15 @@ void QLineEdit::mouseDoubleClickEvent(QMouseEvent* e)
void QLineEdit::keyPressEvent(QKeyEvent *event)
{
Q_D(QLineEdit);
-
- bool inlineCompletionAccepted = false;
-
-#ifndef QT_NO_COMPLETER
- if (d->completer) {
- QCompleter::CompletionMode completionMode = d->completer->completionMode();
- if ((completionMode == QCompleter::PopupCompletion
- || completionMode == QCompleter::UnfilteredPopupCompletion)
- &&d->completer->popup()
- && d->completer->popup()->isVisible()) {
- // The following keys are forwarded by the completer to the widget
- // Ignoring the events lets the completer provide suitable default behavior
- switch (event->key()) {
- case Qt::Key_Escape:
- event->ignore();
- return;
- case Qt::Key_Enter:
- case Qt::Key_Return:
- case Qt::Key_F4:
-#ifdef QT_KEYPAD_NAVIGATION
- case Qt::Key_Select:
- if (!QApplication::keypadNavigationEnabled())
- break;
-#endif
- d->completer->popup()->hide(); // just hide. will end up propagating to parent
- default:
- break; // normal key processing
- }
- } else if (completionMode == QCompleter::InlineCompletion) {
- switch (event->key()) {
- case Qt::Key_Enter:
- case Qt::Key_Return:
- case Qt::Key_F4:
-#ifdef QT_KEYPAD_NAVIGATION
- case Qt::Key_Select:
- if (!QApplication::keypadNavigationEnabled())
- break;
-#endif
- if (!d->completer->currentCompletion().isEmpty() && d->selend > d->selstart
- && d->selend == d->text.length()) {
- setText(d->completer->currentCompletion());
- inlineCompletionAccepted = true;
- }
- default:
- break; // normal key processing
- }
- }
- }
-#endif // QT_NO_COMPLETER
-
-#ifdef QT_KEYPAD_NAVIGATION
+ #ifdef QT_KEYPAD_NAVIGATION
bool select = false;
switch (event->key()) {
case Qt::Key_Select:
if (QApplication::keypadNavigationEnabled()) {
if (hasEditFocus()) {
setEditFocus(false);
- if (d->completer && d->completer->popup()->isVisible())
- d->completer->popup()->hide();
+ if (d->control->completer() && d->control->completer()->popup()->isVisible())
+ d->control->completer()->popup()->hide();
select = true;
}
}
@@ -1928,273 +1594,7 @@ void QLineEdit::keyPressEvent(QKeyEvent *event)
return; // Just start. No action.
}
#endif
-
- if (echoMode() == PasswordEchoOnEdit
- && !d->passwordEchoEditing
- && !isReadOnly()
- && !event->text().isEmpty()
-#ifdef QT_KEYPAD_NAVIGATION
- && event->key() != Qt::Key_Select
- && event->key() != Qt::Key_Up
- && event->key() != Qt::Key_Down
- && event->key() != Qt::Key_Back
-#endif
- && !(event->modifiers() & Qt::ControlModifier)) {
- // Clear the edit and reset to normal echo mode while editing; the
- // echo mode switches back when the edit loses focus. ### changes a
- // public property, resets current content. dubious code; you can
- // navigate with keys up, down, back, and select(?), but if you press
- // "left" or "right" it clears?
- d->updatePasswordEchoEditing(true);
- clear();
- }
-
- d->setCursorVisible(true);
- if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) {
- if (hasAcceptableInput() || d->fixup()) {
- emit returnPressed();
- d->emitingEditingFinished = true;
- emit editingFinished();
- d->emitingEditingFinished = false;
- }
- if (inlineCompletionAccepted)
- event->accept();
- else
- event->ignore();
- return;
- }
- bool unknown = false;
-
- if (false) {
- }
-#ifndef QT_NO_SHORTCUT
- else if (event == QKeySequence::Undo) {
- if (!d->readOnly)
- undo();
- }
- else if (event == QKeySequence::Redo) {
- if (!d->readOnly)
- redo();
- }
- else if (event == QKeySequence::SelectAll) {
- selectAll();
- }
-#ifndef QT_NO_CLIPBOARD
- else if (event == QKeySequence::Copy) {
- copy();
- }
- else if (event == QKeySequence::Paste) {
- if (!d->readOnly)
- paste();
- }
- else if (event == QKeySequence::Cut) {
- if (!d->readOnly) {
- cut();
- }
- }
- else if (event == QKeySequence::DeleteEndOfLine) {
- if (!d->readOnly) {
- setSelection(d->cursor, d->text.size());
- copy();
- del();
- }
- }
-#endif //QT_NO_CLIPBOARD
- else if (event == QKeySequence::MoveToStartOfLine) {
- home(0);
- }
- else if (event == QKeySequence::MoveToEndOfLine) {
- end(0);
- }
- else if (event == QKeySequence::SelectStartOfLine) {
- home(1);
- }
- else if (event == QKeySequence::SelectEndOfLine) {
- end(1);
- }
- else if (event == QKeySequence::MoveToNextChar) {
-#if !defined(Q_WS_WIN) || defined(QT_NO_COMPLETER)
- if (d->hasSelectedText()) {
-#else
- if (d->hasSelectedText() && d->completer
- && d->completer->completionMode() == QCompleter::InlineCompletion) {
-#endif
- d->moveCursor(d->selend, false);
- } else {
- cursorForward(0, layoutDirection() == Qt::LeftToRight ? 1 : -1);
- }
- }
- else if (event == QKeySequence::SelectNextChar) {
- cursorForward(1, layoutDirection() == Qt::LeftToRight ? 1 : -1);
- }
- else if (event == QKeySequence::MoveToPreviousChar) {
-#if !defined(Q_WS_WIN) || defined(QT_NO_COMPLETER)
- if (d->hasSelectedText()) {
-#else
- if (d->hasSelectedText() && d->completer
- && d->completer->completionMode() == QCompleter::InlineCompletion) {
-#endif
- d->moveCursor(d->selstart, false);
- } else {
- cursorBackward(0, layoutDirection() == Qt::LeftToRight ? 1 : -1);
- }
- }
- else if (event == QKeySequence::SelectPreviousChar) {
- cursorBackward(1, layoutDirection() == Qt::LeftToRight ? 1 : -1);
- }
- else if (event == QKeySequence::MoveToNextWord) {
- if (echoMode() == Normal)
- layoutDirection() == Qt::LeftToRight ? cursorWordForward(0) : cursorWordBackward(0);
- else
- layoutDirection() == Qt::LeftToRight ? end(0) : home(0);
- }
- else if (event == QKeySequence::MoveToPreviousWord) {
- if (echoMode() == Normal)
- layoutDirection() == Qt::LeftToRight ? cursorWordBackward(0) : cursorWordForward(0);
- else if (!d->readOnly) {
- layoutDirection() == Qt::LeftToRight ? home(0) : end(0);
- }
- }
- else if (event == QKeySequence::SelectNextWord) {
- if (echoMode() == Normal)
- layoutDirection() == Qt::LeftToRight ? cursorWordForward(1) : cursorWordBackward(1);
- else
- layoutDirection() == Qt::LeftToRight ? end(1) : home(1);
- }
- else if (event == QKeySequence::SelectPreviousWord) {
- if (echoMode() == Normal)
- layoutDirection() == Qt::LeftToRight ? cursorWordBackward(1) : cursorWordForward(1);
- else
- layoutDirection() == Qt::LeftToRight ? home(1) : end(1);
- }
- else if (event == QKeySequence::Delete) {
- if (!d->readOnly)
- del();
- }
- else if (event == QKeySequence::DeleteEndOfWord) {
- if (!d->readOnly) {
- cursorWordForward(true);
- del();
- }
- }
- else if (event == QKeySequence::DeleteStartOfWord) {
- if (!d->readOnly) {
- cursorWordBackward(true);
- del();
- }
- }
-#endif // QT_NO_SHORTCUT
- else {
-#ifdef Q_WS_MAC
- if (event->key() == Qt::Key_Up || event->key() == Qt::Key_Down) {
- Qt::KeyboardModifiers myModifiers = (event->modifiers() & ~Qt::KeypadModifier);
- if (myModifiers & Qt::ShiftModifier) {
- if (myModifiers == (Qt::ControlModifier|Qt::ShiftModifier)
- || myModifiers == (Qt::AltModifier|Qt::ShiftModifier)
- || myModifiers == Qt::ShiftModifier) {
-
- event->key() == Qt::Key_Up ? home(1) : end(1);
- }
- } else {
- if ((myModifiers == Qt::ControlModifier
- || myModifiers == Qt::AltModifier
- || myModifiers == Qt::NoModifier)) {
- event->key() == Qt::Key_Up ? home(0) : end(0);
- }
- }
- }
-#endif
- if (event->modifiers() & Qt::ControlModifier) {
- switch (event->key()) {
- case Qt::Key_Backspace:
- if (!d->readOnly) {
- cursorWordBackward(true);
- del();
- }
- break;
-#ifndef QT_NO_COMPLETER
- case Qt::Key_Up:
- case Qt::Key_Down:
- d->complete(event->key());
- break;
-#endif
-#if defined(Q_WS_X11)
- case Qt::Key_E:
- end(0);
- break;
-
- case Qt::Key_U:
- if (!d->readOnly) {
- setSelection(0, d->text.size());
-#ifndef QT_NO_CLIPBOARD
- copy();
-#endif
- del();
- }
- break;
-#endif
- default:
- unknown = true;
- }
- } else { // ### check for *no* modifier
- switch (event->key()) {
- case Qt::Key_Backspace:
- if (!d->readOnly) {
- backspace();
-#ifndef QT_NO_COMPLETER
- d->complete(Qt::Key_Backspace);
-#endif
- }
- break;
-#ifdef QT_KEYPAD_NAVIGATION
- case Qt::Key_Back:
- if (QApplication::keypadNavigationEnabled() && !event->isAutoRepeat()
- && !isReadOnly()) {
- if (text().length() == 0) {
- setText(d->origText);
-
- if (d->passwordEchoEditing)
- d->updatePasswordEchoEditing(false);
-
- setEditFocus(false);
- } else if (!d->deleteAllTimer.isActive()) {
- d->deleteAllTimer.start(750, this);
- }
- } else {
- unknown = true;
- }
- break;
-#endif
-
- default:
- unknown = true;
- }
- }
- }
-
- if (event->key() == Qt::Key_Direction_L || event->key() == Qt::Key_Direction_R) {
- setLayoutDirection((event->key() == Qt::Key_Direction_L) ? Qt::LeftToRight : Qt::RightToLeft);
- d->updateTextLayout();
- update();
- unknown = false;
- }
-
- if (unknown && !d->readOnly) {
- QString t = event->text();
- if (!t.isEmpty() && t.at(0).isPrint()) {
- insert(t);
-#ifndef QT_NO_COMPLETER
- d->complete(event->key());
-#endif
- event->accept();
- return;
- }
- }
-
- if (unknown)
- event->ignore();
- else
- event->accept();
+ d->control->processKeyEvent(event);
}
/*!
@@ -2208,50 +1608,17 @@ QRect QLineEdit::cursorRect() const
return d->cursorRect();
}
-/*!
- This function is not intended as polymorphic usage. Just a shared code
- fragment that calls QInputContext::mouseHandler for this
- class.
-*/
-bool QLineEditPrivate::sendMouseEventToInputContext( QMouseEvent *e )
-{
-#if !defined QT_NO_IM
- Q_Q(QLineEdit);
- if ( composeMode() ) {
- int tmp_cursor = xToPos(e->pos().x());
- int mousePos = tmp_cursor - cursor;
- if ( mousePos < 0 || mousePos > textLayout.preeditAreaText().length() ) {
- mousePos = -1;
- // don't send move events outside the preedit area
- if ( e->type() == QEvent::MouseMove )
- return true;
- }
-
- QInputContext *qic = q->inputContext();
- if ( qic )
- // may be causing reset() in some input methods
- qic->mouseHandler(mousePos, e);
- if (!textLayout.preeditAreaText().isEmpty())
- return true;
- }
-#else
- Q_UNUSED(e);
-#endif
-
- return false;
-}
-
/*! \reimp
*/
void QLineEdit::inputMethodEvent(QInputMethodEvent *e)
{
Q_D(QLineEdit);
- if (d->readOnly) {
+ if (d->control->isReadOnly()) {
e->ignore();
return;
}
- if (echoMode() == PasswordEchoOnEdit && !d->passwordEchoEditing) {
+ if (echoMode() == PasswordEchoOnEdit && !d->control->passwordEchoEditing()) {
// Clear the edit and reset to normal echo mode while entering input
// method data; the echo mode switches back when the edit loses focus.
// ### changes a public property, resets current content.
@@ -2271,85 +1638,11 @@ void QLineEdit::inputMethodEvent(QInputMethodEvent *e)
}
#endif
- int priorState = 0;
- bool isGettingInput = !e->commitString().isEmpty() || !e->preeditString().isEmpty()
- || e->replacementLength() > 0;
- bool cursorPositionChanged = false;
-
- if (isGettingInput) {
- // If any text is being input, remove selected text.
- priorState = d->undoState;
- d->removeSelectedText();
- }
-
- int c = d->cursor; // cursor position after insertion of commit string
- if (e->replacementStart() <= 0)
- c += e->commitString().length() + qMin(-e->replacementStart(), e->replacementLength());
-
- d->cursor += e->replacementStart();
-
- // insert commit string
- if (e->replacementLength()) {
- d->selstart = d->cursor;
- d->selend = d->selstart + e->replacementLength();
- d->removeSelectedText();
- }
- if (!e->commitString().isEmpty()) {
- d->insert(e->commitString());
- cursorPositionChanged = true;
- }
-
- d->cursor = qMin(c, d->text.length());
-
- for (int i = 0; i < e->attributes().size(); ++i) {
- const QInputMethodEvent::Attribute &a = e->attributes().at(i);
- if (a.type == QInputMethodEvent::Selection) {
- d->cursor = qBound(0, a.start + a.length, d->text.length());
- if (a.length) {
- d->selstart = qMax(0, qMin(a.start, d->text.length()));
- d->selend = d->cursor;
- if (d->selend < d->selstart) {
- qSwap(d->selstart, d->selend);
- }
- } else {
- d->selstart = d->selend = 0;
- }
- cursorPositionChanged = true;
- }
- }
-
- d->textLayout.setPreeditArea(d->cursor, e->preeditString());
- d->preeditCursor = e->preeditString().length();
- d->hideCursor = false;
- QList<QTextLayout::FormatRange> formats;
- for (int i = 0; i < e->attributes().size(); ++i) {
- const QInputMethodEvent::Attribute &a = e->attributes().at(i);
- if (a.type == QInputMethodEvent::Cursor) {
- d->preeditCursor = a.start;
- d->hideCursor = !a.length;
- } else if (a.type == QInputMethodEvent::TextFormat) {
- QTextCharFormat f = qvariant_cast<QTextFormat>(a.value).toCharFormat();
- if (f.isValid()) {
- QTextLayout::FormatRange o;
- o.start = a.start + d->cursor;
- o.length = a.length;
- o.format = f;
- formats.append(o);
- }
- }
- }
- d->textLayout.setAdditionalFormats(formats);
- d->updateTextLayout();
- update();
- if (cursorPositionChanged)
- d->emitCursorPositionChanged();
-
- if (isGettingInput)
- d->finishChange(priorState);
+ d->control->processInputMethodEvent(e);
#ifndef QT_NO_COMPLETER
if (!e->commitString().isEmpty())
- d->complete(Qt::Key_unknown);
+ d->control->complete(Qt::Key_unknown);
#endif
}
@@ -2364,20 +1657,20 @@ QVariant QLineEdit::inputMethodQuery(Qt::InputMethodQuery property) const
case Qt::ImFont:
return font();
case Qt::ImCursorPosition:
- return QVariant(d->cursor);
+ return QVariant(d->control->hasSelectedText() ? d->control->selectionEnd() : d->control->cursor());
case Qt::ImSurroundingText:
- return QVariant(d->text);
+ return QVariant(text());
case Qt::ImCurrentSelection:
return QVariant(selectedText());
case Qt::ImMaximumTextLength:
return QVariant(maxLength());
case Qt::ImAnchorPosition:
- if (d->selstart == d->selend)
- return QVariant(d->cursor);
- else if (d->selstart == d->cursor)
- return QVariant(d->selend);
+ if (d->control->selectionStart() == d->control->selectionEnd())
+ return QVariant(d->control->cursor());
+ else if (d->control->selectionStart() == d->control->cursor())
+ return QVariant(d->control->selectionEnd());
else
- return QVariant(d->selstart);
+ return QVariant(d->control->selectionStart());
default:
return QVariant();
}
@@ -2392,9 +1685,9 @@ void QLineEdit::focusInEvent(QFocusEvent *e)
if (e->reason() == Qt::TabFocusReason ||
e->reason() == Qt::BacktabFocusReason ||
e->reason() == Qt::ShortcutFocusReason) {
- if (d->maskData)
- d->moveCursor(d->nextMaskBlank(0));
- else if (!d->hasSelectedText())
+ if (!d->control->inputMask().isEmpty())
+ d->control->moveCursor(d->control->nextMaskBlank(0));
+ else if (!d->control->hasSelectedText())
selectAll();
} else if (e->reason() == Qt::MouseFocusReason) {
d->clickCausedFocus = 1;
@@ -2402,28 +1695,28 @@ void QLineEdit::focusInEvent(QFocusEvent *e)
#ifdef QT_KEYPAD_NAVIGATION
if (!QApplication::keypadNavigationEnabled() || (hasEditFocus() && e->reason() == Qt::PopupFocusReason))
#endif
- if (!d->cursorTimer) {
+ {
int cft = QApplication::cursorFlashTime();
- d->cursorTimer = cft ? startTimer(cft/2) : -1;
+ d->control->setCursorBlinkPeriod(cft/2);
}
QStyleOptionFrameV2 opt;
initStyleOption(&opt);
- if((!hasSelectedText() && d->textLayout.preeditAreaText().isEmpty())
+ if((!hasSelectedText() && d->control->preeditAreaText().isEmpty())
|| style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, this))
d->setCursorVisible(true);
#ifdef Q_WS_MAC
- if (d->echoMode == Password || d->echoMode == NoEcho)
+ if (d->control->echoMode() == Password || d->control->echoMode() == NoEcho)
qt_mac_secure_keyboard(true);
#endif
#ifdef QT_KEYPAD_NAVIGATION
- d->origText = d->text;
+ d->control->setCancelText(d->control->text());
#endif
#ifndef QT_NO_COMPLETER
- if (d->completer) {
- d->completer->setWidget(this);
- QObject::connect(d->completer, SIGNAL(activated(QString)),
+ if (d->control->completer()) {
+ d->control->completer()->setWidget(this);
+ QObject::connect(d->control->completer(), SIGNAL(activated(QString)),
this, SLOT(setText(QString)));
- QObject::connect(d->completer, SIGNAL(highlighted(QString)),
+ QObject::connect(d->control->completer(), SIGNAL(highlighted(QString)),
this, SLOT(_q_completionHighlighted(QString)));
}
#endif
@@ -2436,7 +1729,7 @@ void QLineEdit::focusInEvent(QFocusEvent *e)
void QLineEdit::focusOutEvent(QFocusEvent *e)
{
Q_D(QLineEdit);
- if (d->passwordEchoEditing) {
+ if (d->control->passwordEchoEditing()) {
// Reset the echomode back to PasswordEchoOnEdit when the widget loses
// focus.
d->updatePasswordEchoEditing(false);
@@ -2448,37 +1741,29 @@ void QLineEdit::focusOutEvent(QFocusEvent *e)
deselect();
d->setCursorVisible(false);
- if (d->cursorTimer > 0)
- killTimer(d->cursorTimer);
- d->cursorTimer = 0;
-
+ d->control->setCursorBlinkPeriod(0);
#ifdef QT_KEYPAD_NAVIGATION
// editingFinished() is already emitted on LeaveEditFocus
if (!QApplication::keypadNavigationEnabled())
#endif
if (reason != Qt::PopupFocusReason
|| !(QApplication::activePopupWidget() && QApplication::activePopupWidget()->parentWidget() == this)) {
- if (!d->emitingEditingFinished) {
- if (hasAcceptableInput() || d->fixup()) {
- d->emitingEditingFinished = true;
+ if (hasAcceptableInput() || d->control->fixup())
emit editingFinished();
- d->emitingEditingFinished = false;
- }
- }
#ifdef QT3_SUPPORT
emit lostFocus();
#endif
}
#ifdef Q_WS_MAC
- if (d->echoMode == Password || d->echoMode == NoEcho)
+ if (d->control->echoMode() == Password || d->control->echoMode() == NoEcho)
qt_mac_secure_keyboard(false);
#endif
#ifdef QT_KEYPAD_NAVIGATION
- d->origText = QString();
+ d->control->setCancelText(QString());
#endif
#ifndef QT_NO_COMPLETER
- if (d->completer) {
- QObject::disconnect(d->completer, 0, this, 0);
+ if (d->control->completer()) {
+ QObject::disconnect(d->control->completer(), 0, this, 0);
}
#endif
update();
@@ -2508,24 +1793,19 @@ void QLineEdit::paintEvent(QPaintEvent *)
Qt::Alignment va = QStyle::visualAlignment(layoutDirection(), QFlag(d->alignment));
switch (va & Qt::AlignVertical_Mask) {
case Qt::AlignBottom:
- d->vscroll = r.y() + r.height() - fm.height() - verticalMargin;
+ d->vscroll = r.y() + r.height() - fm.height() - d->verticalMargin;
break;
case Qt::AlignTop:
- d->vscroll = r.y() + verticalMargin;
+ d->vscroll = r.y() + d->verticalMargin;
break;
default:
//center
d->vscroll = r.y() + (r.height() - fm.height() + 1) / 2;
break;
}
- QRect lineRect(r.x() + horizontalMargin, d->vscroll, r.width() - 2*horizontalMargin, fm.height());
- QTextLine line = d->textLayout.lineAt(0);
+ QRect lineRect(r.x() + d->horizontalMargin, d->vscroll, r.width() - 2*d->horizontalMargin, fm.height());
- int cursor = d->cursor;
- if (d->preeditCursor != -1)
- cursor += d->preeditCursor;
- // locate cursor position
- int cix = qRound(line.cursorToX(cursor));
+ int cix = qRound(d->control->cursorToX());
// horizontal scrolling. d->hscroll is the left indent from the beginning
// of the text line to the left edge of lineRect. we update this value
@@ -2535,7 +1815,7 @@ void QLineEdit::paintEvent(QPaintEvent *)
// (cix).
int minLB = qMax(0, -fm.minLeftBearing());
int minRB = qMax(0, -fm.minRightBearing());
- int widthUsed = qRound(line.naturalTextWidth()) + 1 + minRB;
+ int widthUsed = d->control->width() + minRB;
if ((minLB + widthUsed) <= lineRect.width()) {
// text fits in lineRect; use hscroll for alignment
switch (va & ~(Qt::AlignAbsolute|Qt::AlignVertical_Mask)) {
@@ -2563,7 +1843,7 @@ void QLineEdit::paintEvent(QPaintEvent *)
d->hscroll = widthUsed - lineRect.width() + 1;
}
// the y offset is there to keep the baseline constant in case we have script changes in the text.
- QPoint topLeft = lineRect.topLeft() - QPoint(d->hscroll, d->ascent - fm.ascent());
+ QPoint topLeft = lineRect.topLeft() - QPoint(d->hscroll, d->control->ascent() - fm.ascent());
// draw text, selections and cursors
#ifndef QT_NO_STYLE_STYLESHEET
@@ -2573,33 +1853,23 @@ void QLineEdit::paintEvent(QPaintEvent *)
#endif
p.setPen(pal.text().color());
- QVector<QTextLayout::FormatRange> selections;
+ int flags = QLineControl::DrawText;
+
#ifdef QT_KEYPAD_NAVIGATION
if (!QApplication::keypadNavigationEnabled() || hasEditFocus())
#endif
- if (d->selstart < d->selend || (d->cursorVisible && d->maskData && !d->readOnly)) {
- QTextLayout::FormatRange o;
- if (d->selstart < d->selend) {
- o.start = d->selstart;
- o.length = d->selend - d->selstart;
- o.format.setBackground(pal.brush(QPalette::Highlight));
- o.format.setForeground(pal.brush(QPalette::HighlightedText));
- } else {
- // mask selection
- o.start = d->cursor;
- o.length = 1;
- o.format.setBackground(pal.brush(QPalette::Text));
- o.format.setForeground(pal.brush(QPalette::Window));
- }
- selections.append(o);
- }
+ if (d->control->hasSelectedText() || (d->cursorVisible && !d->control->inputMask().isEmpty() && !d->control->isReadOnly()))
+ flags |= QLineControl::DrawSelections;
// Asian users see an IM selection text as cursor on candidate
// selection phase of input method, so the ordinary cursor should be
// invisible if we have a preedit string.
- d->textLayout.draw(&p, topLeft, selections, r);
- if (d->cursorVisible && !d->readOnly && !d->hideCursor)
- d->textLayout.drawCursor(&p, topLeft, cursor, style()->pixelMetric(QStyle::PM_TextCursorWidth));
+ if (d->cursorVisible && !d->control->isReadOnly())
+ flags |= QLineControl::DrawCursor;
+
+ d->control->setCursorWidth(style()->pixelMetric(QStyle::PM_TextCursorWidth));
+ d->control->draw(&p, topLeft, r, flags);
+
}
@@ -2609,12 +1879,11 @@ void QLineEdit::paintEvent(QPaintEvent *)
void QLineEdit::dragMoveEvent(QDragMoveEvent *e)
{
Q_D(QLineEdit);
- if (!d->readOnly && e->mimeData()->hasFormat(QLatin1String("text/plain"))) {
+ if (!d->control->isReadOnly() && e->mimeData()->hasFormat(QLatin1String("text/plain"))) {
e->acceptProposedAction();
- d->cursor = d->xToPos(e->pos().x());
+ d->control->moveCursor(d->xToPos(e->pos().x()), false);
d->cursorVisible = true;
update();
- d->emitCursorPositionChanged();
}
}
@@ -2640,13 +1909,14 @@ void QLineEdit::dropEvent(QDropEvent* e)
Q_D(QLineEdit);
QString str = e->mimeData()->text();
- if (!str.isNull() && !d->readOnly) {
+ if (!str.isNull() && !d->control->isReadOnly()) {
if (e->source() == this && e->dropAction() == Qt::CopyAction)
deselect();
- d->cursor =d->xToPos(e->pos().x());
- int selStart = d->cursor;
- int oldSelStart = d->selstart;
- int oldSelEnd = d->selend;
+ int cursorPos = d->xToPos(e->pos().x());
+ int selStart = cursorPos;
+ int oldSelStart = d->control->selectionStart();
+ int oldSelEnd = d->control->selectionEnd();
+ d->control->moveCursor(cursorPos, false);
d->cursorVisible = false;
e->acceptProposedAction();
insert(str);
@@ -2668,22 +1938,6 @@ void QLineEdit::dropEvent(QDropEvent* e)
}
}
-void QLineEditPrivate::drag()
-{
- Q_Q(QLineEdit);
- dndTimer.stop();
- QMimeData *data = new QMimeData;
- data->setText(q->selectedText());
- QDrag *drag = new QDrag(q);
- drag->setMimeData(data);
- Qt::DropAction action = drag->start();
- if (action == Qt::MoveAction && !readOnly && drag->target() != q) {
- int priorState = undoState;
- removeSelectedText();
- finishChange(priorState);
- }
-}
-
#endif // QT_NO_DRAGANDDROP
#ifndef QT_NO_CONTEXTMENU
@@ -2728,37 +1982,39 @@ QMenu *QLineEdit::createStandardContextMenu()
popup->setObjectName(QLatin1String("qt_edit_menu"));
QAction *action = popup->addAction(QLineEdit::tr("&Undo") + ACCEL_KEY(QKeySequence::Undo));
- action->setEnabled(d->isUndoAvailable());
+ action->setEnabled(d->control->isUndoAvailable());
connect(action, SIGNAL(triggered()), SLOT(undo()));
action = popup->addAction(QLineEdit::tr("&Redo") + ACCEL_KEY(QKeySequence::Redo));
- action->setEnabled(d->isRedoAvailable());
+ action->setEnabled(d->control->isRedoAvailable());
connect(action, SIGNAL(triggered()), SLOT(redo()));
popup->addSeparator();
#ifndef QT_NO_CLIPBOARD
action = popup->addAction(QLineEdit::tr("Cu&t") + ACCEL_KEY(QKeySequence::Cut));
- action->setEnabled(!d->readOnly && d->hasSelectedText() && d->echoMode == QLineEdit::Normal);
+ action->setEnabled(!d->control->isReadOnly() && d->control->hasSelectedText()
+ && d->control->echoMode() == QLineEdit::Normal);
connect(action, SIGNAL(triggered()), SLOT(cut()));
action = popup->addAction(QLineEdit::tr("&Copy") + ACCEL_KEY(QKeySequence::Copy));
- action->setEnabled(d->hasSelectedText() && d->echoMode == QLineEdit::Normal);
+ action->setEnabled(d->control->hasSelectedText()
+ && d->control->echoMode() == QLineEdit::Normal);
connect(action, SIGNAL(triggered()), SLOT(copy()));
action = popup->addAction(QLineEdit::tr("&Paste") + ACCEL_KEY(QKeySequence::Paste));
- action->setEnabled(!d->readOnly && !QApplication::clipboard()->text().isEmpty());
+ action->setEnabled(!d->control->isReadOnly() && !QApplication::clipboard()->text().isEmpty());
connect(action, SIGNAL(triggered()), SLOT(paste()));
#endif
action = popup->addAction(QLineEdit::tr("Delete"));
- action->setEnabled(!d->readOnly && !d->text.isEmpty() && d->hasSelectedText());
+ action->setEnabled(!d->control->isReadOnly() && !d->control->text().isEmpty() && d->control->hasSelectedText());
connect(action, SIGNAL(triggered()), SLOT(_q_deleteSelected()));
popup->addSeparator();
action = popup->addAction(QLineEdit::tr("Select All") + ACCEL_KEY(QKeySequence::SelectAll));
- action->setEnabled(!d->text.isEmpty() && !d->allSelected());
+ action->setEnabled(!d->control->text().isEmpty() && !d->control->allSelected());
d->selectAllAction = action;
connect(action, SIGNAL(triggered()), SLOT(selectAll()));
@@ -2772,9 +2028,9 @@ QMenu *QLineEdit::createStandardContextMenu()
#endif
#if defined(Q_WS_WIN)
- if (!d->readOnly && qt_use_rtl_extensions) {
+ if (!d->control->isReadOnly() && qt_use_rtl_extensions) {
#else
- if (!d->readOnly) {
+ if (!d->control->isReadOnly()) {
#endif
popup->addSeparator();
QUnicodeControlCharacterMenu *ctrlCharacterMenu = new QUnicodeControlCharacterMenu(this, popup);
@@ -2788,807 +2044,26 @@ QMenu *QLineEdit::createStandardContextMenu()
void QLineEdit::changeEvent(QEvent *ev)
{
Q_D(QLineEdit);
- if(ev->type() == QEvent::ActivationChange) {
+ switch(ev->type())
+ {
+ case QEvent::ActivationChange:
if (!palette().isEqual(QPalette::Active, QPalette::Inactive))
update();
- } else if (ev->type() == QEvent::FontChange
- || ev->type() == QEvent::StyleChange
- || ev->type() == QEvent::LayoutDirectionChange) {
- d->updateTextLayout();
- }
- QWidget::changeEvent(ev);
-}
-
-void QLineEditPrivate::_q_handleWindowActivate()
-{
- Q_Q(QLineEdit);
- if (!q->hasFocus() && q->hasSelectedText())
- q->deselect();
-}
-
-void QLineEditPrivate::_q_deleteSelected()
-{
- Q_Q(QLineEdit);
- if (!hasSelectedText())
- return;
-
- int priorState = undoState;
- q->resetInputContext();
- removeSelectedText();
- separate();
- finishChange(priorState);
-}
-
-void QLineEditPrivate::init(const QString& txt)
-{
- Q_Q(QLineEdit);
-#ifndef QT_NO_CURSOR
- q->setCursor(Qt::IBeamCursor);
-#endif
- q->setFocusPolicy(Qt::StrongFocus);
- q->setAttribute(Qt::WA_InputMethodEnabled);
- // Specifies that this widget can use more, but is able to survive on
- // less, horizontal space; and is fixed vertically.
- q->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed, QSizePolicy::LineEdit));
- q->setBackgroundRole(QPalette::Base);
- q->setAttribute(Qt::WA_KeyCompression);
- q->setMouseTracking(true);
- q->setAcceptDrops(true);
- text = txt;
- updateTextLayout();
- cursor = text.length();
-
- q->setAttribute(Qt::WA_MacShowFocusRect);
-}
-
-void QLineEditPrivate::updatePasswordEchoEditing(bool editing)
-{
- Q_Q(QLineEdit);
- passwordEchoEditing = editing;
- q->setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod(q));
- updateTextLayout();
- q->update();
-}
-
-void QLineEditPrivate::updateTextLayout()
-{
- // replace certain non-printable characters with spaces (to avoid
- // drawing boxes when using fonts that don't have glyphs for such
- // characters)
- Q_Q(QLineEdit);
- QString str = q->displayText();
- QChar* uc = str.data();
- for (int i = 0; i < (int)str.length(); ++i) {
- if ((uc[i] < 0x20 && uc[i] != 0x09)
- || uc[i] == QChar::LineSeparator
- || uc[i] == QChar::ParagraphSeparator
- || uc[i] == QChar::ObjectReplacementCharacter)
- uc[i] = QChar(0x0020);
- }
- textLayout.setFont(q->font());
- textLayout.setText(str);
- QTextOption option;
- option.setTextDirection(q->layoutDirection());
- option.setFlags(QTextOption::IncludeTrailingSpaces);
- textLayout.setTextOption(option);
-
- textLayout.beginLayout();
- QTextLine l = textLayout.createLine();
- textLayout.endLayout();
- ascent = qRound(l.ascent());
-}
-
-int QLineEditPrivate::xToPos(int x, QTextLine::CursorPosition betweenOrOn) const
-{
- QRect cr = adjustedContentsRect();
- x-= cr.x() - hscroll + horizontalMargin;
- QTextLine l = textLayout.lineAt(0);
- return l.xToCursor(x, betweenOrOn);
-}
-
-QRect QLineEditPrivate::cursorRect() const
-{
- Q_Q(const QLineEdit);
- QRect cr = adjustedContentsRect();
- int cix = cr.x() - hscroll + horizontalMargin;
- QTextLine l = textLayout.lineAt(0);
- int c = cursor;
- if (preeditCursor != -1)
- c += preeditCursor;
- cix += qRound(l.cursorToX(c));
- int ch = qMin(cr.height(), q->fontMetrics().height() + 1);
- int w = q->style()->pixelMetric(QStyle::PM_TextCursorWidth);
- return QRect(cix-5, vscroll, w + 9, ch);
-}
-
-QRect QLineEditPrivate::adjustedContentsRect() const
-{
- Q_Q(const QLineEdit);
- QStyleOptionFrameV2 opt;
- q->initStyleOption(&opt);
- QRect r = q->style()->subElementRect(QStyle::SE_LineEditContents, &opt, q);
- r.setX(r.x() + leftTextMargin);
- r.setY(r.y() + topTextMargin);
- r.setRight(r.right() - rightTextMargin);
- r.setBottom(r.bottom() - bottomTextMargin);
- return r;
-}
-
-bool QLineEditPrivate::fixup() // this function assumes that validate currently returns != Acceptable
-{
-#ifndef QT_NO_VALIDATOR
- if (validator) {
- QString textCopy = text;
- int cursorCopy = cursor;
- validator->fixup(textCopy);
- if (validator->validate(textCopy, cursorCopy) == QValidator::Acceptable) {
- if (textCopy != text || cursorCopy != cursor)
- setText(textCopy, cursorCopy);
- return true;
- }
- }
-#endif
- return false;
-}
-
-void QLineEditPrivate::moveCursor(int pos, bool mark)
-{
- Q_Q(QLineEdit);
- if (pos != cursor) {
- separate();
- if (maskData)
- pos = pos > cursor ? nextMaskBlank(pos) : prevMaskBlank(pos);
- }
- bool fullUpdate = mark || hasSelectedText();
- if (mark) {
- int anchor;
- if (selend > selstart && cursor == selstart)
- anchor = selend;
- else if (selend > selstart && cursor == selend)
- anchor = selstart;
- else
- anchor = cursor;
- selstart = qMin(anchor, pos);
- selend = qMax(anchor, pos);
- updateTextLayout();
- } else {
- deselect();
- }
- if (fullUpdate) {
- cursor = pos;
- q->update();
- } else {
- setCursorVisible(false);
- cursor = pos;
- setCursorVisible(true);
- if (!adjustedContentsRect().contains(cursorRect()))
- q->update();
- }
- QStyleOptionFrameV2 opt;
- q->initStyleOption(&opt);
- if (mark && !q->style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, q))
- setCursorVisible(false);
- if (mark || selDirty) {
- selDirty = false;
- emit q->selectionChanged();
- }
- q->updateMicroFocus();
- emitCursorPositionChanged();
-}
-
-void QLineEditPrivate::finishChange(int validateFromState, bool update, bool edited)
-{
- Q_Q(QLineEdit);
- bool lineDirty = selDirty;
- if (textDirty) {
- // do validation
- bool wasValidInput = validInput;
- validInput = true;
-#ifndef QT_NO_VALIDATOR
- if (validator) {
- validInput = false;
- QString textCopy = text;
- int cursorCopy = cursor;
- validInput = (validator->validate(textCopy, cursorCopy) != QValidator::Invalid);
- if (validInput) {
- if (text != textCopy) {
- setText(textCopy, cursorCopy);
- return;
- }
- cursor = cursorCopy;
- }
- }
-#endif
- if (validateFromState >= 0 && wasValidInput && !validInput) {
- undo(validateFromState);
- history.resize(undoState);
- if (modifiedState > undoState)
- modifiedState = -1;
- validInput = true;
- textDirty = false;
- }
- updateTextLayout();
- lineDirty |= textDirty;
- if (textDirty) {
- textDirty = false;
- QString actualText = maskData ? stripString(text) : text;
- if (edited)
- emit q->textEdited(actualText);
- q->updateMicroFocus();
-#ifndef QT_NO_COMPLETER
- if (edited && completer && completer->completionMode() != QCompleter::InlineCompletion)
- complete(-1); // update the popup on cut/paste/del
-#endif
- emit q->textChanged(actualText);
- }
-#ifndef QT_NO_ACCESSIBILITY
- QAccessible::updateAccessibility(q, 0, QAccessible::ValueChanged);
-#endif
- }
- if (selDirty) {
- selDirty = false;
- emit q->selectionChanged();
- }
- if (lineDirty || update)
- q->update();
- emitCursorPositionChanged();
-}
-
-void QLineEditPrivate::emitCursorPositionChanged()
-{
- Q_Q(QLineEdit);
- if (cursor != lastCursorPos) {
- const int oldLast = lastCursorPos;
- lastCursorPos = cursor;
- emit q->cursorPositionChanged(oldLast, cursor);
- }
-}
-
-void QLineEditPrivate::setText(const QString& txt, int pos, bool edited)
-{
- Q_Q(QLineEdit);
- q->resetInputContext();
- deselect();
- QString oldText = text;
- if (maskData) {
- text = maskString(0, txt, true);
- text += clearString(text.length(), maxLength - text.length());
- } else {
- text = txt.isEmpty() ? txt : txt.left(maxLength);
- }
- history.clear();
- modifiedState = undoState = 0;
- cursor = (pos < 0 || pos > text.length()) ? text.length() : pos;
- textDirty = (oldText != text);
- finishChange(-1, true, edited);
-}
-
-
-void QLineEditPrivate::setCursorVisible(bool visible)
-{
- Q_Q(QLineEdit);
- if ((bool)cursorVisible == visible)
- return;
- if (cursorTimer)
- cursorVisible = visible;
- QRect r = cursorRect();
- if (maskData)
- q->update();
- else
- q->update(r);
-}
-
-void QLineEditPrivate::addCommand(const Command& cmd)
-{
- if (separator && undoState && history[undoState-1].type != Separator) {
- history.resize(undoState + 2);
- history[undoState++] = Command(Separator, cursor, 0, selstart, selend);
- } else {
- history.resize(undoState + 1);
- }
- separator = false;
- history[undoState++] = cmd;
-}
-
-void QLineEditPrivate::insert(const QString& s)
-{
- if (hasSelectedText())
- addCommand(Command(SetSelection, cursor, 0, selstart, selend));
- if (maskData) {
- QString ms = maskString(cursor, s);
- for (int i = 0; i < (int) ms.length(); ++i) {
- addCommand (Command(DeleteSelection, cursor+i, text.at(cursor+i), -1, -1));
- addCommand(Command(Insert, cursor+i, ms.at(i), -1, -1));
- }
- text.replace(cursor, ms.length(), ms);
- cursor += ms.length();
- cursor = nextMaskBlank(cursor);
- textDirty = true;
- } else {
- int remaining = maxLength - text.length();
- if (remaining != 0) {
- text.insert(cursor, s.left(remaining));
- for (int i = 0; i < (int) s.left(remaining).length(); ++i)
- addCommand(Command(Insert, cursor++, s.at(i), -1, -1));
- textDirty = true;
- }
- }
-}
-
-void QLineEditPrivate::del(bool wasBackspace)
-{
- if (cursor < (int) text.length()) {
- if (hasSelectedText())
- addCommand(Command(SetSelection, cursor, 0, selstart, selend));
- addCommand (Command((CommandType)((maskData?2:0)+(wasBackspace?Remove:Delete)), cursor, text.at(cursor), -1, -1));
- if (maskData) {
- text.replace(cursor, 1, clearString(cursor, 1));
- addCommand(Command(Insert, cursor, text.at(cursor), -1, -1));
- } else {
- text.remove(cursor, 1);
- }
- textDirty = true;
- }
-}
-
-void QLineEditPrivate::removeSelectedText()
-{
- if (selstart < selend && selend <= (int) text.length()) {
- separate();
- int i ;
- addCommand(Command(SetSelection, cursor, 0, selstart, selend));
- if (selstart <= cursor && cursor < selend) {
- // cursor is within the selection. Split up the commands
- // to be able to restore the correct cursor position
- for (i = cursor; i >= selstart; --i)
- addCommand (Command(DeleteSelection, i, text.at(i), -1, 1));
- for (i = selend - 1; i > cursor; --i)
- addCommand (Command(DeleteSelection, i - cursor + selstart - 1, text.at(i), -1, -1));
- } else {
- for (i = selend-1; i >= selstart; --i)
- addCommand (Command(RemoveSelection, i, text.at(i), -1, -1));
- }
- if (maskData) {
- text.replace(selstart, selend - selstart, clearString(selstart, selend - selstart));
- for (int i = 0; i < selend - selstart; ++i)
- addCommand(Command(Insert, selstart + i, text.at(selstart + i), -1, -1));
- } else {
- text.remove(selstart, selend - selstart);
- }
- if (cursor > selstart)
- cursor -= qMin(cursor, selend) - selstart;
- deselect();
- textDirty = true;
-
- // adjust hscroll to avoid gap
- const int minRB = qMax(0, -q_func()->fontMetrics().minRightBearing());
- updateTextLayout();
- const QTextLine line = textLayout.lineAt(0);
- const int widthUsed = qRound(line.naturalTextWidth()) + 1 + minRB;
- hscroll = qMin(hscroll, widthUsed);
- }
-}
-
-void QLineEditPrivate::parseInputMask(const QString &maskFields)
-{
- int delimiter = maskFields.indexOf(QLatin1Char(';'));
- if (maskFields.isEmpty() || delimiter == 0) {
- if (maskData) {
- delete [] maskData;
- maskData = 0;
- maxLength = 32767;
- setText(QString());
- }
- return;
- }
-
- if (delimiter == -1) {
- blank = QLatin1Char(' ');
- inputMask = maskFields;
- } else {
- inputMask = maskFields.left(delimiter);
- blank = (delimiter + 1 < maskFields.length()) ? maskFields[delimiter + 1] : QLatin1Char(' ');
- }
-
- // calculate maxLength / maskData length
- maxLength = 0;
- QChar c = 0;
- for (int i=0; i<inputMask.length(); i++) {
- c = inputMask.at(i);
- if (i > 0 && inputMask.at(i-1) == QLatin1Char('\\')) {
- maxLength++;
- continue;
- }
- if (c != QLatin1Char('\\') && c != QLatin1Char('!') &&
- c != QLatin1Char('<') && c != QLatin1Char('>') &&
- c != QLatin1Char('{') && c != QLatin1Char('}') &&
- c != QLatin1Char('[') && c != QLatin1Char(']'))
- maxLength++;
- }
-
- delete [] maskData;
- maskData = new MaskInputData[maxLength];
-
- MaskInputData::Casemode m = MaskInputData::NoCaseMode;
- c = 0;
- bool s;
- bool escape = false;
- int index = 0;
- for (int i = 0; i < inputMask.length(); i++) {
- c = inputMask.at(i);
- if (escape) {
- s = true;
- maskData[index].maskChar = c;
- maskData[index].separator = s;
- maskData[index].caseMode = m;
- index++;
- escape = false;
- } else if (c == QLatin1Char('<')) {
- m = MaskInputData::Lower;
- } else if (c == QLatin1Char('>')) {
- m = MaskInputData::Upper;
- } else if (c == QLatin1Char('!')) {
- m = MaskInputData::NoCaseMode;
- } else if (c != QLatin1Char('{') && c != QLatin1Char('}') && c != QLatin1Char('[') && c != QLatin1Char(']')) {
- switch (c.unicode()) {
- case 'A':
- case 'a':
- case 'N':
- case 'n':
- case 'X':
- case 'x':
- case '9':
- case '0':
- case 'D':
- case 'd':
- case '#':
- case 'H':
- case 'h':
- case 'B':
- case 'b':
- s = false;
- break;
- case '\\':
- escape = true;
- default:
- s = true;
- break;
- }
-
- if (!escape) {
- maskData[index].maskChar = c;
- maskData[index].separator = s;
- maskData[index].caseMode = m;
- index++;
- }
- }
- }
- setText(text);
-}
-
-
-/* checks if the key is valid compared to the inputMask */
-bool QLineEditPrivate::isValidInput(QChar key, QChar mask) const
-{
- switch (mask.unicode()) {
- case 'A':
- if (key.isLetter())
- return true;
break;
- case 'a':
- if (key.isLetter() || key == blank)
- return true;
- break;
- case 'N':
- if (key.isLetterOrNumber())
- return true;
- break;
- case 'n':
- if (key.isLetterOrNumber() || key == blank)
- return true;
- break;
- case 'X':
- if (key.isPrint())
- return true;
- break;
- case 'x':
- if (key.isPrint() || key == blank)
- return true;
- break;
- case '9':
- if (key.isNumber())
- return true;
- break;
- case '0':
- if (key.isNumber() || key == blank)
- return true;
- break;
- case 'D':
- if (key.isNumber() && key.digitValue() > 0)
- return true;
+ case QEvent::FontChange:
+ d->control->setFont(font());
break;
- case 'd':
- if ((key.isNumber() && key.digitValue() > 0) || key == blank)
- return true;
- break;
- case '#':
- if (key.isNumber() || key == QLatin1Char('+') || key == QLatin1Char('-') || key == blank)
- return true;
- break;
- case 'B':
- if (key == QLatin1Char('0') || key == QLatin1Char('1'))
- return true;
- break;
- case 'b':
- if (key == QLatin1Char('0') || key == QLatin1Char('1') || key == blank)
- return true;
- break;
- case 'H':
- if (key.isNumber() || (key >= QLatin1Char('a') && key <= QLatin1Char('f')) || (key >= QLatin1Char('A') && key <= QLatin1Char('F')))
- return true;
+ case QEvent::StyleChange:
+ d->control->setPasswordCharacter(style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter));
+ update();
break;
- case 'h':
- if (key.isNumber() || (key >= QLatin1Char('a') && key <= QLatin1Char('f')) || (key >= QLatin1Char('A') && key <= QLatin1Char('F')) || key == blank)
- return true;
+ case QEvent::LayoutDirectionChange:
+ d->control->setLayoutDirection(layoutDirection());
break;
default:
break;
}
- return false;
-}
-
-bool QLineEditPrivate::hasAcceptableInput(const QString &str) const
-{
-#ifndef QT_NO_VALIDATOR
- QString textCopy = str;
- int cursorCopy = cursor;
- if (validator && validator->validate(textCopy, cursorCopy)
- != QValidator::Acceptable)
- return false;
-#endif
-
- if (!maskData)
- return true;
-
- if (str.length() != maxLength)
- return false;
-
- for (int i=0; i < maxLength; ++i) {
- if (maskData[i].separator) {
- if (str.at(i) != maskData[i].maskChar)
- return false;
- } else {
- if (!isValidInput(str.at(i), maskData[i].maskChar))
- return false;
- }
- }
- return true;
-}
-
-/*
- Applies the inputMask on \a str starting from position \a pos in the mask. \a clear
- specifies from where characters should be gotten when a separator is met in \a str - true means
- that blanks will be used, false that previous input is used.
- Calling this when no inputMask is set is undefined.
-*/
-QString QLineEditPrivate::maskString(uint pos, const QString &str, bool clear) const
-{
- if (pos >= (uint)maxLength)
- return QString::fromLatin1("");
-
- QString fill;
- fill = clear ? clearString(0, maxLength) : text;
-
- int strIndex = 0;
- QString s = QString::fromLatin1("");
- int i = pos;
- while (i < maxLength) {
- if (strIndex < str.length()) {
- if (maskData[i].separator) {
- s += maskData[i].maskChar;
- if (str[(int)strIndex] == maskData[i].maskChar)
- strIndex++;
- ++i;
- } else {
- if (isValidInput(str[(int)strIndex], maskData[i].maskChar)) {
- switch (maskData[i].caseMode) {
- case MaskInputData::Upper:
- s += str[(int)strIndex].toUpper();
- break;
- case MaskInputData::Lower:
- s += str[(int)strIndex].toLower();
- break;
- default:
- s += str[(int)strIndex];
- }
- ++i;
- } else {
- // search for separator first
- int n = findInMask(i, true, true, str[(int)strIndex]);
- if (n != -1) {
- if (str.length() != 1 || i == 0 || (i > 0 && (!maskData[i-1].separator || maskData[i-1].maskChar != str[(int)strIndex]))) {
- s += fill.mid(i, n-i+1);
- i = n + 1; // update i to find + 1
- }
- } else {
- // search for valid blank if not
- n = findInMask(i, true, false, str[(int)strIndex]);
- if (n != -1) {
- s += fill.mid(i, n-i);
- switch (maskData[n].caseMode) {
- case MaskInputData::Upper:
- s += str[(int)strIndex].toUpper();
- break;
- case MaskInputData::Lower:
- s += str[(int)strIndex].toLower();
- break;
- default:
- s += str[(int)strIndex];
- }
- i = n + 1; // updates i to find + 1
- }
- }
- }
- strIndex++;
- }
- } else
- break;
- }
-
- return s;
-}
-
-
-
-/*
- Returns a "cleared" string with only separators and blank chars.
- Calling this when no inputMask is set is undefined.
-*/
-QString QLineEditPrivate::clearString(uint pos, uint len) const
-{
- if (pos >= (uint)maxLength)
- return QString();
-
- QString s;
- int end = qMin((uint)maxLength, pos + len);
- for (int i=pos; i<end; i++)
- if (maskData[i].separator)
- s += maskData[i].maskChar;
- else
- s += blank;
-
- return s;
-}
-
-/*
- Strips blank parts of the input in a QLineEdit when an inputMask is set,
- separators are still included. Typically "127.0__.0__.1__" becomes "127.0.0.1".
-*/
-QString QLineEditPrivate::stripString(const QString &str) const
-{
- if (!maskData)
- return str;
-
- QString s;
- int end = qMin(maxLength, (int)str.length());
- for (int i=0; i < end; i++)
- if (maskData[i].separator)
- s += maskData[i].maskChar;
- else
- if (str[i] != blank)
- s += str[i];
-
- return s;
-}
-
-/* searches forward/backward in maskData for either a separator or a blank */
-int QLineEditPrivate::findInMask(int pos, bool forward, bool findSeparator, QChar searchChar) const
-{
- if (pos >= maxLength || pos < 0)
- return -1;
-
- int end = forward ? maxLength : -1;
- int step = forward ? 1 : -1;
- int i = pos;
-
- while (i != end) {
- if (findSeparator) {
- if (maskData[i].separator && maskData[i].maskChar == searchChar)
- return i;
- } else {
- if (!maskData[i].separator) {
- if (searchChar.isNull())
- return i;
- else if (isValidInput(searchChar, maskData[i].maskChar))
- return i;
- }
- }
- i += step;
- }
- return -1;
-}
-
-void QLineEditPrivate::undo(int until)
-{
- if (!isUndoAvailable())
- return;
- deselect();
- while (undoState && undoState > until) {
- Command& cmd = history[--undoState];
- switch (cmd.type) {
- case Insert:
- text.remove(cmd.pos, 1);
- cursor = cmd.pos;
- break;
- case SetSelection:
- selstart = cmd.selStart;
- selend = cmd.selEnd;
- cursor = cmd.pos;
- break;
- case Remove:
- case RemoveSelection:
- text.insert(cmd.pos, cmd.uc);
- cursor = cmd.pos + 1;
- break;
- case Delete:
- case DeleteSelection:
- text.insert(cmd.pos, cmd.uc);
- cursor = cmd.pos;
- break;
- case Separator:
- continue;
- }
- if (until < 0 && undoState) {
- Command& next = history[undoState-1];
- if (next.type != cmd.type && next.type < RemoveSelection
- && (cmd.type < RemoveSelection || next.type == Separator))
- break;
- }
- }
- textDirty = true;
- emitCursorPositionChanged();
-}
-
-void QLineEditPrivate::redo() {
- if (!isRedoAvailable())
- return;
- deselect();
- while (undoState < (int)history.size()) {
- Command& cmd = history[undoState++];
- switch (cmd.type) {
- case Insert:
- text.insert(cmd.pos, cmd.uc);
- cursor = cmd.pos + 1;
- break;
- case SetSelection:
- selstart = cmd.selStart;
- selend = cmd.selEnd;
- cursor = cmd.pos;
- break;
- case Remove:
- case Delete:
- case RemoveSelection:
- case DeleteSelection:
- text.remove(cmd.pos, 1);
- selstart = cmd.selStart;
- selend = cmd.selEnd;
- cursor = cmd.pos;
- break;
- case Separator:
- selstart = cmd.selStart;
- selend = cmd.selEnd;
- cursor = cmd.pos;
- break;
- }
- if (undoState < (int)history.size()) {
- Command& next = history[undoState];
- if (next.type != cmd.type && cmd.type < RemoveSelection && next.type != Separator
- && (next.type < RemoveSelection || cmd.type == Separator))
- break;
- }
- }
- textDirty = true;
- emitCursorPositionChanged();
+ QWidget::changeEvent(ev);
}
/*!
diff --git a/src/gui/widgets/qlineedit.h b/src/gui/widgets/qlineedit.h
index 0d01253..daac6a7 100644
--- a/src/gui/widgets/qlineedit.h
+++ b/src/gui/widgets/qlineedit.h
@@ -265,9 +265,11 @@ private:
friend class QDateTimeEdit;
#endif
Q_DISABLE_COPY(QLineEdit)
- Q_DECLARE_SCOPED_PRIVATE(QLineEdit)
+ Q_DECLARE_PRIVATE(QLineEdit)
Q_PRIVATE_SLOT(d_func(), void _q_handleWindowActivate())
Q_PRIVATE_SLOT(d_func(), void _q_deleteSelected())
+ Q_PRIVATE_SLOT(d_func(), void _q_textEdited(const QString &))
+ Q_PRIVATE_SLOT(d_func(), void _q_cursorPositionChanged(int, int))
#ifndef QT_NO_COMPLETER
Q_PRIVATE_SLOT(d_func(), void _q_completionHighlighted(QString))
#endif
diff --git a/src/gui/widgets/qlineedit_p.cpp b/src/gui/widgets/qlineedit_p.cpp
new file mode 100644
index 0000000..f0ec8ad
--- /dev/null
+++ b/src/gui/widgets/qlineedit_p.cpp
@@ -0,0 +1,253 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qlineedit.h"
+#include "qlineedit_p.h"
+
+#ifndef QT_NO_LINEEDIT
+
+#include "qabstractitemview.h"
+#include "qclipboard.h"
+#ifndef QT_NO_ACCESSIBILITY
+#include "qaccessible.h"
+#endif
+#ifndef QT_NO_IM
+#include "qinputcontext.h"
+#include "qlist.h"
+#endif
+
+QT_BEGIN_NAMESPACE
+
+const int QLineEditPrivate::verticalMargin(1);
+const int QLineEditPrivate::horizontalMargin(2);
+
+int QLineEditPrivate::xToPos(int x, QTextLine::CursorPosition betweenOrOn) const
+{
+ QRect cr = adjustedContentsRect();
+ x-= cr.x() - hscroll + horizontalMargin;
+ return control->xToPos(x, betweenOrOn);
+}
+
+QRect QLineEditPrivate::cursorRect() const
+{
+ QRect cr = adjustedContentsRect();
+ int cix = cr.x() - hscroll + horizontalMargin;
+ QRect crect = control->cursorRect();
+ crect.moveTo(crect.topLeft() + QPoint(cix, vscroll));
+ return crect;
+}
+
+#ifndef QT_NO_COMPLETER
+
+void QLineEditPrivate::_q_completionHighlighted(QString newText)
+{
+ Q_Q(QLineEdit);
+ if (control->completer()->completionMode() != QCompleter::InlineCompletion) {
+ q->setText(newText);
+ } else {
+ int c = control->cursor();
+ QString text = control->text();
+ q->setText(text.left(c) + newText.mid(c));
+ control->moveCursor(control->end(), false);
+ control->moveCursor(c, true);
+ }
+}
+
+#endif // QT_NO_COMPLETER
+
+void QLineEditPrivate::_q_clipboardChanged()
+{
+}
+
+void QLineEditPrivate::_q_handleWindowActivate()
+{
+ Q_Q(QLineEdit);
+ if (!q->hasFocus() && control->hasSelectedText())
+ control->deselect();
+}
+
+void QLineEditPrivate::_q_deleteSelected()
+{
+}
+
+void QLineEditPrivate::_q_textEdited(const QString &text)
+{
+ Q_Q(QLineEdit);
+#ifndef QT_NO_COMPLETER
+ if (control->completer() &&
+ control->completer()->completionMode() != QCompleter::InlineCompletion)
+ control->complete(-1); // update the popup on cut/paste/del
+#endif
+ emit q->textEdited(text);
+}
+
+void QLineEditPrivate::_q_cursorPositionChanged(int from, int to)
+{
+ Q_Q(QLineEdit);
+ q->update();
+ emit q->cursorPositionChanged(from, to);
+}
+
+void QLineEditPrivate::init(const QString& txt)
+{
+ Q_Q(QLineEdit);
+ control = new QLineControl(txt);
+ QObject::connect(control, SIGNAL(textChanged(const QString &)),
+ q, SIGNAL(textChanged(const QString &)));
+ QObject::connect(control, SIGNAL(textEdited(const QString &)),
+ q, SLOT(_q_textEdited(const QString &)));
+ QObject::connect(control, SIGNAL(cursorPositionChanged(int, int)),
+ q, SLOT(_q_cursorPositionChanged(int, int)));
+ QObject::connect(control, SIGNAL(selectionChanged()),
+ q, SIGNAL(selectionChanged()));
+ QObject::connect(control, SIGNAL(accepted()),
+ q, SIGNAL(returnPressed()));
+ QObject::connect(control, SIGNAL(editingFinished()),
+ q, SIGNAL(editingFinished()));
+
+ // for now, going completely overboard with updates.
+ QObject::connect(control, SIGNAL(selectionChanged()),
+ q, SLOT(update()));
+
+ QObject::connect(control, SIGNAL(displayTextChanged(const QString &)),
+ q, SLOT(update()));
+ control->setPasswordCharacter(q->style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter));
+#ifndef QT_NO_CURSOR
+ q->setCursor(Qt::IBeamCursor);
+#endif
+ q->setFocusPolicy(Qt::StrongFocus);
+ q->setAttribute(Qt::WA_InputMethodEnabled);
+ // Specifies that this widget can use more, but is able to survive on
+ // less, horizontal space; and is fixed vertically.
+ q->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed, QSizePolicy::LineEdit));
+ q->setBackgroundRole(QPalette::Base);
+ q->setAttribute(Qt::WA_KeyCompression);
+ q->setMouseTracking(true);
+ q->setAcceptDrops(true);
+
+ q->setAttribute(Qt::WA_MacShowFocusRect);
+}
+
+QRect QLineEditPrivate::adjustedContentsRect() const
+{
+ Q_Q(const QLineEdit);
+ QStyleOptionFrameV2 opt;
+ q->initStyleOption(&opt);
+ QRect r = q->style()->subElementRect(QStyle::SE_LineEditContents, &opt, q);
+ r.setX(r.x() + leftTextMargin);
+ r.setY(r.y() + topTextMargin);
+ r.setRight(r.right() - rightTextMargin);
+ r.setBottom(r.bottom() - bottomTextMargin);
+ return r;
+}
+
+void QLineEditPrivate::setCursorVisible(bool visible)
+{
+ Q_Q(QLineEdit);
+ if ((bool)cursorVisible == visible)
+ return;
+ cursorVisible = visible;
+ QRect r = cursorRect();
+ if (control->inputMask().isEmpty())
+ q->update(r);
+ else
+ q->update();
+}
+
+void QLineEditPrivate::updatePasswordEchoEditing(bool editing)
+{
+ Q_Q(QLineEdit);
+ control->updatePasswordEchoEditing(editing);
+ q->setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod());
+}
+
+/*!
+ This function is not intended as polymorphic usage. Just a shared code
+ fragment that calls QInputContext::mouseHandler for this
+ class.
+*/
+bool QLineEditPrivate::sendMouseEventToInputContext( QMouseEvent *e )
+{
+#if !defined QT_NO_IM
+ Q_Q(QLineEdit);
+ if ( control->composeMode() ) {
+ int tmp_cursor = xToPos(e->pos().x());
+ int mousePos = tmp_cursor - control->cursor();
+ if ( mousePos < 0 || mousePos > control->preeditAreaText().length() ) {
+ mousePos = -1;
+ // don't send move events outside the preedit area
+ if ( e->type() == QEvent::MouseMove )
+ return true;
+ }
+
+ QInputContext *qic = q->inputContext();
+ if ( qic )
+ // may be causing reset() in some input methods
+ qic->mouseHandler(mousePos, e);
+ if (!control->preeditAreaText().isEmpty())
+ return true;
+ }
+#else
+ Q_UNUSED(e);
+#endif
+
+ return false;
+}
+
+#ifndef QT_NO_DRAGANDDROP
+void QLineEditPrivate::drag()
+{
+ Q_Q(QLineEdit);
+ dndTimer.stop();
+ QMimeData *data = new QMimeData;
+ data->setText(control->selectedText());
+ QDrag *drag = new QDrag(q);
+ drag->setMimeData(data);
+ Qt::DropAction action = drag->start();
+ if (action == Qt::MoveAction && !control->isReadOnly() && drag->target() != q)
+ control->removeSelection();
+}
+
+#endif // QT_NO_DRAGANDDROP
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/gui/widgets/qlineedit_p.h b/src/gui/widgets/qlineedit_p.h
index 03029f9..b09c3f0 100644
--- a/src/gui/widgets/qlineedit_p.h
+++ b/src/gui/widgets/qlineedit_p.h
@@ -65,6 +65,8 @@
#include "QtCore/qpointer.h"
#include "QtGui/qlineedit.h"
+#include "private/qlinecontrol_p.h"
+
QT_BEGIN_NAMESPACE
class QLineEditPrivate : public QWidgetPrivate
@@ -73,169 +75,65 @@ class QLineEditPrivate : public QWidgetPrivate
public:
QLineEditPrivate()
- : cursor(0), preeditCursor(0), cursorTimer(0), frame(1),
- cursorVisible(0), hideCursor(false), separator(0), readOnly(0),
- dragEnabled(0), contextMenuEnabled(1), echoMode(0), textDirty(0),
- selDirty(0), validInput(1), clickCausedFocus(0),
- alignment(Qt::AlignLeading | Qt::AlignVCenter), ascent(0),
- maxLength(32767), hscroll(0), vscroll(0), lastCursorPos(-1), maskData(0),
- modifiedState(0), undoState(0), selstart(0), selend(0), userInput(false),
- emitingEditingFinished(false), passwordEchoEditing(false)
-#ifndef QT_NO_COMPLETER
- , completer(0)
-#endif
- , leftTextMargin(0), topTextMargin(0), rightTextMargin(0), bottomTextMargin(0)
- {
- }
+ : control(0), frame(1), contextMenuEnabled(1), cursorVisible(0),
+ dragEnabled(0), hscroll(0), vscroll(0), clickCausedFocus(0),
+ alignment(Qt::AlignLeading | Qt::AlignVCenter),
+ leftTextMargin(0), topTextMargin(0), rightTextMargin(0), bottomTextMargin(0)
+ {
+ }
~QLineEditPrivate()
{
- delete [] maskData;
}
+
+ QLineControl *control;
+
+#ifndef QT_NO_CONTEXTMENU
+ QPointer<QAction> selectAllAction;
+#endif
void init(const QString&);
- QString text;
- int cursor;
- int preeditCursor;
- int cursorTimer; // -1 for non blinking cursor.
+ int xToPos(int x, QTextLine::CursorPosition = QTextLine::CursorBetweenCharacters) const;
+ QRect cursorRect() const;
+ void setCursorVisible(bool visible);
+
+ void updatePasswordEchoEditing(bool);
+
+ inline bool shouldEnableInputMethod() const
+ {
+ return !control->isReadOnly() && (control->echoMode() == QLineEdit::Normal || control->echoMode() == QLineEdit::PasswordEchoOnEdit);
+ }
+
QPoint tripleClick;
QBasicTimer tripleClickTimer;
uint frame : 1;
+ uint contextMenuEnabled : 1;
uint cursorVisible : 1;
- uint hideCursor : 1; // used to hide the cursor inside preedit areas
- uint separator : 1;
- uint readOnly : 1;
uint dragEnabled : 1;
- uint contextMenuEnabled : 1;
- uint echoMode : 2;
- uint textDirty : 1;
- uint selDirty : 1;
- uint validInput : 1;
uint clickCausedFocus : 1;
- uint alignment;
- int ascent;
- int maxLength;
int hscroll;
int vscroll;
- int lastCursorPos;
-
-#ifndef QT_NO_CONTEXTMENU
- QPointer<QAction> selectAllAction;
-#endif
+ uint alignment;
+ static const int verticalMargin;
+ static const int horizontalMargin;
- inline void emitCursorPositionChanged();
bool sendMouseEventToInputContext(QMouseEvent *e);
- void finishChange(int validateFromState = -1, bool update = false, bool edited = true);
-
- QPointer<QValidator> validator;
- struct MaskInputData {
- enum Casemode { NoCaseMode, Upper, Lower };
- QChar maskChar; // either the separator char or the inputmask
- bool separator;
- Casemode caseMode;
- };
- QString inputMask;
- QChar blank;
- MaskInputData *maskData;
- inline int nextMaskBlank(int pos) {
- int c = findInMask(pos, true, false);
- separator |= (c != pos);
- return (c != -1 ? c : maxLength);
- }
- inline int prevMaskBlank(int pos) {
- int c = findInMask(pos, false, false);
- separator |= (c != pos);
- return (c != -1 ? c : 0);
- }
-
- void setCursorVisible(bool visible);
-
-
- // undo/redo handling
- enum CommandType { Separator, Insert, Remove, Delete, RemoveSelection, DeleteSelection, SetSelection };
- struct Command {
- inline Command() {}
- inline Command(CommandType t, int p, QChar c, int ss, int se) : type(t),uc(c),pos(p),selStart(ss),selEnd(se) {}
- uint type : 4;
- QChar uc;
- int pos, selStart, selEnd;
- };
- int modifiedState;
- int undoState;
- QVector<Command> history;
- void addCommand(const Command& cmd);
- void insert(const QString& s);
- void del(bool wasBackspace = false);
- void remove(int pos);
-
- inline void separate() { separator = true; }
- void undo(int until = -1);
- void redo();
- inline bool isUndoAvailable() const { return !readOnly && undoState; }
- inline bool isRedoAvailable() const { return !readOnly && undoState < (int)history.size(); }
-
- // selection
- int selstart, selend;
- inline bool allSelected() const { return !text.isEmpty() && selstart == 0 && selend == (int)text.length(); }
- inline bool hasSelectedText() const { return !text.isEmpty() && selend > selstart; }
- inline void deselect() { selDirty |= (selend > selstart); selstart = selend = 0; }
- void removeSelectedText();
-#ifndef QT_NO_CLIPBOARD
- void copy(bool clipboard = true) const;
-#endif
- inline bool inSelection(int x) const
- { if (selstart >= selend) return false;
- int pos = xToPos(x, QTextLine::CursorOnCharacter); return pos >= selstart && pos < selend; }
-
- // masking
- void parseInputMask(const QString &maskFields);
- bool isValidInput(QChar key, QChar mask) const;
- bool hasAcceptableInput(const QString &text) const;
- QString maskString(uint pos, const QString &str, bool clear = false) const;
- QString clearString(uint pos, uint len) const;
- QString stripString(const QString &str) const;
- int findInMask(int pos, bool forward, bool findSeparator, QChar searchChar = QChar()) const;
-
- // input methods
- bool composeMode() const { return !textLayout.preeditAreaText().isEmpty(); }
-
- // complex text layout
- QTextLayout textLayout;
- void updateTextLayout();
- void moveCursor(int pos, bool mark = false);
- void setText(const QString& txt, int pos = -1, bool edited = true);
- int xToPos(int x, QTextLine::CursorPosition = QTextLine::CursorBetweenCharacters) const;
- QRect cursorRect() const;
- bool fixup();
-
QRect adjustedContentsRect() const;
-#ifndef QT_NO_DRAGANDDROP
- // drag and drop
- QPoint dndPos;
- QBasicTimer dndTimer;
- void drag();
-#endif
-
+ void _q_clipboardChanged();
void _q_handleWindowActivate();
void _q_deleteSelected();
- bool userInput;
- bool emitingEditingFinished;
-
-#ifdef QT_KEYPAD_NAVIGATION
- QBasicTimer deleteAllTimer; // keypad navigation
- QString origText;
-#endif
-
- bool passwordEchoEditing;
- void updatePasswordEchoEditing(bool editing);
+ void _q_textEdited(const QString &);
+ void _q_cursorPositionChanged(int, int);
#ifndef QT_NO_COMPLETER
- QPointer<QCompleter> completer;
- void complete(int key = -1);
void _q_completionHighlighted(QString);
- bool advanceToEnabledItem(int n);
+#endif
+#ifndef QT_NO_DRAGANDDROP
+ QPoint dndPos;
+ QBasicTimer dndTimer;
+ void drag();
#endif
int leftTextMargin;
diff --git a/src/gui/widgets/qmaccocoaviewcontainer_mac.h b/src/gui/widgets/qmaccocoaviewcontainer_mac.h
index 0fdaac5..8ca1073 100644
--- a/src/gui/widgets/qmaccocoaviewcontainer_mac.h
+++ b/src/gui/widgets/qmaccocoaviewcontainer_mac.h
@@ -63,7 +63,7 @@ public:
void *cocoaView() const;
private:
- Q_DECLARE_SCOPED_PRIVATE(QMacCocoaViewContainer)
+ Q_DECLARE_PRIVATE(QMacCocoaViewContainer)
};
QT_END_NAMESPACE
diff --git a/src/gui/widgets/qmacnativewidget_mac.h b/src/gui/widgets/qmacnativewidget_mac.h
index 904108e..5c654b5 100644
--- a/src/gui/widgets/qmacnativewidget_mac.h
+++ b/src/gui/widgets/qmacnativewidget_mac.h
@@ -64,7 +64,7 @@ protected:
bool event(QEvent *ev);
private:
- Q_DECLARE_SCOPED_PRIVATE(QMacNativeWidget)
+ Q_DECLARE_PRIVATE(QMacNativeWidget)
};
QT_END_NAMESPACE
diff --git a/src/gui/widgets/qmainwindow.cpp b/src/gui/widgets/qmainwindow.cpp
index c9706cf..b75b5ea 100644
--- a/src/gui/widgets/qmainwindow.cpp
+++ b/src/gui/widgets/qmainwindow.cpp
@@ -1374,20 +1374,25 @@ bool QMainWindow::event(QEvent *event)
#ifdef Q_WS_MAC
case QEvent::Show:
if (unifiedTitleAndToolBarOnMac())
- macWindowToolbarShow(this, true);
+ d->layout->syncUnifiedToolbarVisibility();
+ d->layout->blockVisiblityCheck = false;
break;
-# ifdef QT_MAC_USE_COCOA
case QEvent::WindowStateChange:
{
+ if (isHidden()) {
+ // We are coming out of a minimize, leave things as is.
+ d->layout->blockVisiblityCheck = true;
+ }
+# ifdef QT_MAC_USE_COCOA
// We need to update the HIToolbar status when we go out of or into fullscreen.
QWindowStateChangeEvent *wce = static_cast<QWindowStateChangeEvent *>(event);
if ((windowState() & Qt::WindowFullScreen) || (wce->oldState() & Qt::WindowFullScreen)) {
d->layout->updateHIToolBarStatus();
}
+# endif // Cocoa
}
break;
-# endif // Cocoa
-#endif
+#endif // Q_WS_MAC
#if !defined(QT_NO_DOCKWIDGET) && !defined(QT_NO_CURSOR)
case QEvent::CursorChange:
if (d->cursorAdjusted) {
diff --git a/src/gui/widgets/qmainwindow.h b/src/gui/widgets/qmainwindow.h
index a221131..9c2fb88 100644
--- a/src/gui/widgets/qmainwindow.h
+++ b/src/gui/widgets/qmainwindow.h
@@ -202,7 +202,7 @@ protected:
bool event(QEvent *event);
private:
- Q_DECLARE_SCOPED_PRIVATE(QMainWindow)
+ Q_DECLARE_PRIVATE(QMainWindow)
Q_DISABLE_COPY(QMainWindow)
};
diff --git a/src/gui/widgets/qmainwindowlayout.cpp b/src/gui/widgets/qmainwindowlayout.cpp
index 526e7a5..3936a67 100644
--- a/src/gui/widgets/qmainwindowlayout.cpp
+++ b/src/gui/widgets/qmainwindowlayout.cpp
@@ -237,7 +237,7 @@ void QMainWindowLayoutState::apply(bool animated)
if (centralWidgetItem != 0) {
QMainWindowLayout *layout = qobject_cast<QMainWindowLayout*>(mainWindow->layout());
Q_ASSERT(layout != 0);
- layout->widgetAnimator->animate(centralWidgetItem->widget(), centralWidgetRect, animated);
+ layout->widgetAnimator.animate(centralWidgetItem->widget(), centralWidgetRect, animated);
}
#endif
}
@@ -426,42 +426,42 @@ QList<int> QMainWindowLayoutState::gapIndex(QWidget *widget,
return result;
}
-bool QMainWindowLayoutState::insertGap(QList<int> path, QLayoutItem *item)
+bool QMainWindowLayoutState::insertGap(const QList<int> &path, QLayoutItem *item)
{
if (path.isEmpty())
return false;
- int i = path.takeFirst();
+ int i = path.first();
#ifndef QT_NO_TOOLBAR
if (i == 0) {
Q_ASSERT(qobject_cast<QToolBar*>(item->widget()) != 0);
- return toolBarAreaLayout.insertGap(path, item);
+ return toolBarAreaLayout.insertGap(path.mid(1), item);
}
#endif
#ifndef QT_NO_DOCKWIDGET
if (i == 1) {
Q_ASSERT(qobject_cast<QDockWidget*>(item->widget()) != 0);
- return dockAreaLayout.insertGap(path, item);
+ return dockAreaLayout.insertGap(path.mid(1), item);
}
#endif //QT_NO_DOCKWIDGET
return false;
}
-void QMainWindowLayoutState::remove(QList<int> path)
+void QMainWindowLayoutState::remove(const QList<int> &path)
{
- int i = path.takeFirst();
+ int i = path.first();
#ifndef QT_NO_TOOLBAR
if (i == 0)
- toolBarAreaLayout.remove(path);
+ toolBarAreaLayout.remove(path.mid(1));
#endif
#ifndef QT_NO_DOCKWIDGET
if (i == 1)
- dockAreaLayout.remove(path);
+ dockAreaLayout.remove(path.mid(1));
#endif //QT_NO_DOCKWIDGET
}
@@ -501,88 +501,88 @@ bool QMainWindowLayoutState::isValid() const
return rect.isValid();
}
-QLayoutItem *QMainWindowLayoutState::item(QList<int> path)
+QLayoutItem *QMainWindowLayoutState::item(const QList<int> &path)
{
- int i = path.takeFirst();
+ int i = path.first();
#ifndef QT_NO_TOOLBAR
if (i == 0)
- return toolBarAreaLayout.item(path).widgetItem;
+ return toolBarAreaLayout.item(path.mid(1)).widgetItem;
#endif
#ifndef QT_NO_DOCKWIDGET
if (i == 1)
- return dockAreaLayout.item(path).widgetItem;
+ return dockAreaLayout.item(path.mid(1)).widgetItem;
#endif //QT_NO_DOCKWIDGET
return 0;
}
-QRect QMainWindowLayoutState::itemRect(QList<int> path) const
+QRect QMainWindowLayoutState::itemRect(const QList<int> &path) const
{
- int i = path.takeFirst();
+ int i = path.first();
#ifndef QT_NO_TOOLBAR
if (i == 0)
- return toolBarAreaLayout.itemRect(path);
+ return toolBarAreaLayout.itemRect(path.mid(1));
#endif
#ifndef QT_NO_DOCKWIDGET
if (i == 1)
- return dockAreaLayout.itemRect(path);
+ return dockAreaLayout.itemRect(path.mid(1));
#endif //QT_NO_DOCKWIDGET
return QRect();
}
-QRect QMainWindowLayoutState::gapRect(QList<int> path) const
+QRect QMainWindowLayoutState::gapRect(const QList<int> &path) const
{
- int i = path.takeFirst();
+ int i = path.first();
#ifndef QT_NO_TOOLBAR
if (i == 0)
- return toolBarAreaLayout.itemRect(path);
+ return toolBarAreaLayout.itemRect(path.mid(1));
#endif
#ifndef QT_NO_DOCKWIDGET
if (i == 1)
- return dockAreaLayout.gapRect(path);
+ return dockAreaLayout.gapRect(path.mid(1));
#endif //QT_NO_DOCKWIDGET
return QRect();
}
-QLayoutItem *QMainWindowLayoutState::plug(QList<int> path)
+QLayoutItem *QMainWindowLayoutState::plug(const QList<int> &path)
{
- int i = path.takeFirst();
+ int i = path.first();
#ifndef QT_NO_TOOLBAR
if (i == 0)
- return toolBarAreaLayout.plug(path);
+ return toolBarAreaLayout.plug(path.mid(1));
#endif
#ifndef QT_NO_DOCKWIDGET
if (i == 1)
- return dockAreaLayout.plug(path);
+ return dockAreaLayout.plug(path.mid(1));
#endif //QT_NO_DOCKWIDGET
return 0;
}
-QLayoutItem *QMainWindowLayoutState::unplug(QList<int> path, QMainWindowLayoutState *other)
+QLayoutItem *QMainWindowLayoutState::unplug(const QList<int> &path, QMainWindowLayoutState *other)
{
- int i = path.takeFirst();
+ int i = path.first();
#ifdef QT_NO_TOOLBAR
Q_UNUSED(other);
#else
if (i == 0)
- return toolBarAreaLayout.unplug(path, other ? &other->toolBarAreaLayout : 0);
+ return toolBarAreaLayout.unplug(path.mid(1), other ? &other->toolBarAreaLayout : 0);
#endif
#ifndef QT_NO_DOCKWIDGET
if (i == 1)
- return dockAreaLayout.unplug(path);
+ return dockAreaLayout.unplug(path.mid(1));
#endif //QT_NO_DOCKWIDGET
return 0;
@@ -939,16 +939,70 @@ void QMainWindowLayout::getStyleOptionInfo(QStyleOptionToolBar *option, QToolBar
void QMainWindowLayout::toggleToolBarsVisible()
{
- layoutState.toolBarAreaLayout.visible = !layoutState.toolBarAreaLayout.visible;
- if (!layoutState.mainWindow->isMaximized()){
- QPoint topLeft = parentWidget()->geometry().topLeft();
- QRect r = parentWidget()->geometry();
- r = layoutState.toolBarAreaLayout.rectHint(r);
- r.moveTo(topLeft);
- parentWidget()->setGeometry(r);
-// widgetAnimator->animate(parentWidget(), r, true);
- } else{
- update();
+ bool updateNonUnifiedParts = true;
+#ifdef Q_WS_MAC
+ if (layoutState.mainWindow->unifiedTitleAndToolBarOnMac()) {
+ // If we hit this case, someone has pressed the "toolbar button" which will
+ // toggle the unified toolbar visiblity, because that's what the user wants.
+ // We might be in a situation where someone has hidden all the toolbars
+ // beforehand (maybe in construction), but now they've hit this button and
+ // and are expecting the items to show. What do we do?
+ // 1) Check the visibility of all the toolbars, if one is visible, do nothing, this
+ // preserves what people would expect (these toolbars were visible when I clicked last time).
+ // 2) If NONE are visible, then show them all. Again, this preserves the user expectation
+ // of, "I want to see the toolbars." The user may get more toolbars than expected, but this
+ // is better seeing nothing.
+ // Don't worry about any of this if we are going invisible. This does mean we may get
+ // into issues when switching into and out of fullscreen mode, but this is probably minor.
+ // If we ever need to do hiding, that would have to be taken care of after the unified toolbar
+ // has finished hiding.
+ // People can of course handle the QEvent::ToolBarChange event themselves and do
+ // WHATEVER they want if they don't like what we are doing (though the unified toolbar
+ // will fire regardless).
+
+ // Check if we REALLY need to update the geometry below. If we only have items in the
+ // unified toolbar, all the docks will be empty, so there's very little point
+ // in doing the geometry as Apple will do it (we also avoid flicker in Cocoa as well).
+ // FWIW, layoutState.toolBarAreaLayout.visible and the state of the unified toolbar
+ // visibility can get out of sync. I really don't think it's a big issue. It is kept
+ // to a minimum because we only change the visibility if we absolutely must.
+ // update the "non unified parts."
+ updateNonUnifiedParts = !layoutState.toolBarAreaLayout.isEmpty();
+
+ // We get this function before the unified toolbar does its thing.
+ // So, the value will be opposite of what we expect.
+ bool goingVisible = !macWindowToolbarIsVisible(qt_mac_window_for(layoutState.mainWindow));
+ if (goingVisible) {
+ const int ToolBarCount = qtoolbarsInUnifiedToolbarList.size();
+ bool needAllVisible = true;
+ for (int i = 0; i < ToolBarCount; ++i) {
+ if (!qtoolbarsInUnifiedToolbarList.at(i)->isHidden()) {
+ needAllVisible = false;
+ break;
+ }
+ }
+ if (needAllVisible) {
+ QBoolBlocker blocker(blockVisiblityCheck); // Disable the visibilty check because
+ // the toggle has already happened.
+ for (int i = 0; i < ToolBarCount; ++i)
+ qtoolbarsInUnifiedToolbarList.at(i)->setVisible(true);
+ }
+ }
+ if (!updateNonUnifiedParts)
+ layoutState.toolBarAreaLayout.visible = goingVisible;
+ }
+#endif
+ if (updateNonUnifiedParts) {
+ layoutState.toolBarAreaLayout.visible = !layoutState.toolBarAreaLayout.visible;
+ if (!layoutState.mainWindow->isMaximized()) {
+ QPoint topLeft = parentWidget()->geometry().topLeft();
+ QRect r = parentWidget()->geometry();
+ r = layoutState.toolBarAreaLayout.rectHint(r);
+ r.moveTo(topLeft);
+ parentWidget()->setGeometry(r);
+ } else {
+ update();
+ }
}
}
@@ -1361,7 +1415,7 @@ QLayoutItem *QMainWindowLayout::takeAt(int index)
if (QLayoutItem *ret = layoutState.takeAt(index, &x)) {
// the widget might in fact have been destroyed by now
if (QWidget *w = ret->widget()) {
- widgetAnimator->abort(w);
+ widgetAnimator.abort(w);
if (w == pluggingWidget)
pluggingWidget = 0;
}
@@ -1528,75 +1582,28 @@ bool QMainWindowLayout::plug(QLayoutItem *widgetItem)
layoutState.remove(previousPath);
pluggingWidget = widget;
- if (dockOptions & QMainWindow::AnimatedDocks) {
- QRect globalRect = currentGapRect;
- globalRect.moveTopLeft(parentWidget()->mapToGlobal(globalRect.topLeft()));
+ QRect globalRect = currentGapRect;
+ globalRect.moveTopLeft(parentWidget()->mapToGlobal(globalRect.topLeft()));
#ifndef QT_NO_DOCKWIDGET
- if (qobject_cast<QDockWidget*>(widget) != 0) {
- QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(widget->layout());
- if (layout->nativeWindowDeco()) {
- globalRect.adjust(0, layout->titleHeight(), 0, 0);
- } else {
- int fw = widget->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, widget);
- globalRect.adjust(-fw, -fw, fw, fw);
- }
+ if (qobject_cast<QDockWidget*>(widget) != 0) {
+ QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(widget->layout());
+ if (layout->nativeWindowDeco()) {
+ globalRect.adjust(0, layout->titleHeight(), 0, 0);
+ } else {
+ int fw = widget->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, widget);
+ globalRect.adjust(-fw, -fw, fw, fw);
}
-#endif
- widgetAnimator->animate(widget, globalRect,
- dockOptions & QMainWindow::AnimatedDocks);
- } else {
-#ifndef QT_NO_DOCKWIDGET
- if (QDockWidget *dw = qobject_cast<QDockWidget*>(widget))
- dw->d_func()->plug(currentGapRect);
-#endif
-#ifndef QT_NO_TOOLBAR
- if (QToolBar *tb = qobject_cast<QToolBar*>(widget))
- tb->d_func()->plug(currentGapRect);
-#endif
- applyState(layoutState);
- savedState.clear();
-#ifndef QT_NO_DOCKWIDGET
- parentWidget()->update(layoutState.dockAreaLayout.separatorRegion());
-#endif
- currentGapPos.clear();
- updateGapIndicator();
- pluggingWidget = 0;
}
+#endif
+ widgetAnimator.animate(widget, globalRect, dockOptions & QMainWindow::AnimatedDocks);
return true;
}
-void QMainWindowLayout::allAnimationsFinished()
-{
-#ifndef QT_NO_DOCKWIDGET
- parentWidget()->update(layoutState.dockAreaLayout.separatorRegion());
-
-#ifndef QT_NO_TABBAR
- foreach (QTabBar *tab_bar, usedTabBars)
- tab_bar->show();
-#endif // QT_NO_TABBAR
-#endif // QT_NO_DOCKWIDGET
-
- updateGapIndicator();
-}
-
void QMainWindowLayout::animationFinished(QWidget *widget)
{
-
- /* This signal is delivered from QWidgetAnimator over a qeued connection. The problem is that
- the widget can be deleted. This is handled as follows:
-
- The animator only ever animates widgets that have been added to this layout. If a widget
- is deleted during animation, the widget's destructor removes the widget form this layout.
- This in turn aborts the animation (see takeAt()) and this signal will never be delivered.
-
- If the widget is deleted after the animation is finished but before this qeued signal
- is delivered, the widget is no longer in the layout and we catch it here. The key is that
- QMainWindowLayoutState::contains() never dereferences the pointer. */
-
- if (!layoutState.contains(widget))
- return;
-
+ //this function is called from within the Widget Animator whenever an animation is finished
+ //on a certain widget
#ifndef QT_NO_TOOLBAR
if (QToolBar *tb = qobject_cast<QToolBar*>(widget)) {
QToolBarLayout *tbl = qobject_cast<QToolBarLayout*>(tb->layout());
@@ -1609,32 +1616,44 @@ void QMainWindowLayout::animationFinished(QWidget *widget)
}
#endif
- if (widget != pluggingWidget)
- return;
+ if (widget == pluggingWidget) {
#ifndef QT_NO_DOCKWIDGET
- if (QDockWidget *dw = qobject_cast<QDockWidget*>(widget))
- dw->d_func()->plug(currentGapRect);
+ if (QDockWidget *dw = qobject_cast<QDockWidget*>(widget))
+ dw->d_func()->plug(currentGapRect);
#endif
#ifndef QT_NO_TOOLBAR
- if (QToolBar *tb = qobject_cast<QToolBar*>(widget))
- tb->d_func()->plug(currentGapRect);
+ if (QToolBar *tb = qobject_cast<QToolBar*>(widget))
+ tb->d_func()->plug(currentGapRect);
#endif
- applyState(layoutState, false);
#ifndef QT_NO_DOCKWIDGET
#ifndef QT_NO_TABBAR
- if (qobject_cast<QDockWidget*>(widget) != 0) {
- // info() might return null if the widget is destroyed while
- // animating but before the animationFinished signal is received.
- if (QDockAreaLayoutInfo *info = layoutState.dockAreaLayout.info(widget))
- info->setCurrentTab(widget);
- }
+ if (qobject_cast<QDockWidget*>(widget) != 0) {
+ // info() might return null if the widget is destroyed while
+ // animating but before the animationFinished signal is received.
+ if (QDockAreaLayoutInfo *info = layoutState.dockAreaLayout.info(widget))
+ info->setCurrentTab(widget);
+ }
#endif
#endif
- savedState.clear();
- currentGapPos.clear();
- pluggingWidget = 0;
+
+ savedState.clear();
+ currentGapPos.clear();
+ pluggingWidget = 0;
+ }
+
+ if (!widgetAnimator.animating()) {
+ //all animations are finished
+#ifndef QT_NO_DOCKWIDGET
+ parentWidget()->update(layoutState.dockAreaLayout.separatorRegion());
+#ifndef QT_NO_TABBAR
+ foreach (QTabBar *tab_bar, usedTabBars)
+ tab_bar->show();
+#endif // QT_NO_TABBAR
+#endif // QT_NO_DOCKWIDGET
+ }
+
updateGapIndicator();
}
@@ -1667,6 +1686,14 @@ QMainWindowLayout::QMainWindowLayout(QMainWindow *mainwindow)
#endif
#endif
#endif // QT_NO_DOCKWIDGET
+ , widgetAnimator(this)
+ , pluggingWidget(0)
+#ifndef QT_NO_RUBBERBAND
+ , gapIndicator(new QRubberBand(QRubberBand::Rectangle, mainwindow))
+#endif //QT_NO_RUBBERBAND
+#ifdef Q_WS_MAC
+ , blockVisiblityCheck(false)
+#endif
{
#ifndef QT_NO_DOCKWIDGET
#ifndef QT_NO_TABBAR
@@ -1680,20 +1707,13 @@ QMainWindowLayout::QMainWindowLayout(QMainWindow *mainwindow)
#endif // QT_NO_DOCKWIDGET
#ifndef QT_NO_RUBBERBAND
- gapIndicator = new QRubberBand(QRubberBand::Rectangle, mainwindow);
// For accessibility to identify this special widget.
gapIndicator->setObjectName(QLatin1String("qt_rubberband"));
-
gapIndicator->hide();
#endif
pluggingWidget = 0;
setObjectName(mainwindow->objectName() + QLatin1String("_layout"));
- widgetAnimator = new QWidgetAnimator(this);
- connect(widgetAnimator, SIGNAL(finished(QWidget*)),
- this, SLOT(animationFinished(QWidget*)), Qt::QueuedConnection);
- connect(widgetAnimator, SIGNAL(finishedAll()),
- this, SLOT(allAnimationsFinished()));
}
QMainWindowLayout::~QMainWindowLayout()
@@ -1795,14 +1815,8 @@ QLayoutItem *QMainWindowLayout::unplug(QWidget *widget)
void QMainWindowLayout::updateGapIndicator()
{
#ifndef QT_NO_RUBBERBAND
- if (widgetAnimator->animating() || currentGapPos.isEmpty()) {
- gapIndicator->hide();
- } else {
- if (gapIndicator->geometry() != currentGapRect)
- gapIndicator->setGeometry(currentGapRect);
- if (!gapIndicator->isVisible())
- gapIndicator->show();
- }
+ gapIndicator->setVisible(!widgetAnimator.animating() && !currentGapPos.isEmpty());
+ gapIndicator->setGeometry(currentGapRect);
#endif
}
diff --git a/src/gui/widgets/qmainwindowlayout_mac.mm b/src/gui/widgets/qmainwindowlayout_mac.mm
index 6632be7..61719c2 100644
--- a/src/gui/widgets/qmainwindowlayout_mac.mm
+++ b/src/gui/widgets/qmainwindowlayout_mac.mm
@@ -338,18 +338,16 @@ void QMainWindowLayout::updateHIToolBarStatus()
0, kWindowUnifiedTitleAndToolbarAttribute);
}
#endif
- macWindowToolbarShow(layoutState.mainWindow, useMacToolbar);
layoutState.mainWindow->setUpdatesEnabled(false); // reduces a little bit of flicker, not all though
if (!useMacToolbar) {
- OSWindowRef windowRef = qt_mac_window_for(parentWidget());
- macWindowToolbarShow(parentWidget(), false);
+ macWindowToolbarShow(layoutState.mainWindow, false);
// Move everything out of the HIToolbar into the main toolbar.
while (!qtoolbarsInUnifiedToolbarList.isEmpty()) {
// Should shrink the list by one every time.
layoutState.mainWindow->addToolBar(Qt::TopToolBarArea, qtoolbarsInUnifiedToolbarList.first());
}
- macWindowToolbarSet(windowRef, NULL);
+ macWindowToolbarSet(qt_mac_window_for(layoutState.mainWindow), 0);
} else {
QList<QToolBar *> toolbars = layoutState.mainWindow->findChildren<QToolBar *>();
for (int i = 0; i < toolbars.size(); ++i) {
@@ -359,6 +357,7 @@ void QMainWindowLayout::updateHIToolBarStatus()
layoutState.mainWindow->addToolBar(Qt::TopToolBarArea, toolbar);
}
}
+ syncUnifiedToolbarVisibility();
}
layoutState.mainWindow->setUpdatesEnabled(true);
}
@@ -439,7 +438,7 @@ void QMainWindowLayout::insertIntoMacToolbar(QToolBar *before, QToolBar *toolbar
#else
NSString *toolbarID = kQToolBarNSToolbarIdentifier;
toolbarID = [toolbarID stringByAppendingFormat:@"%p", toolbar];
- cocoaItemIDToToolbarHash.insert(QCFString::toQString(CFStringRef(toolbarID)), toolbar);
+ cocoaItemIDToToolbarHash.insert(qt_mac_NSStringToQString(toolbarID), toolbar);
[macToolbar insertItemWithItemIdentifier:toolbarID atIndex:beforeIndex];
#endif
}
@@ -487,6 +486,7 @@ void QMainWindowLayout::cleanUpMacToolbarItems()
void QMainWindowLayout::fixSizeInUnifiedToolbar(QToolBar *tb) const
{
+#ifdef QT_MAC_USE_COCOA
QHash<void *, QToolBar *>::const_iterator it = unifiedToolbarHash.constBegin();
NSToolbarItem *item = nil;
while (it != unifiedToolbarHash.constEnd()) {
@@ -507,5 +507,26 @@ void QMainWindowLayout::fixSizeInUnifiedToolbar(QToolBar *tb) const
nssize.height = size.height() - 2;
[item setMinSize:nssize];
}
+#else
+ Q_UNUSED(tb);
+#endif
}
+
+void QMainWindowLayout::syncUnifiedToolbarVisibility()
+{
+ if (blockVisiblityCheck)
+ return;
+
+ Q_ASSERT(layoutState.mainWindow->unifiedTitleAndToolBarOnMac());
+ bool show = false;
+ const int ToolBarCount = qtoolbarsInUnifiedToolbarList.count();
+ for (int i = 0; i < ToolBarCount; ++i) {
+ if (qtoolbarsInUnifiedToolbarList.at(i)->isVisible()) {
+ show = true;
+ break;
+ }
+ }
+ macWindowToolbarShow(layoutState.mainWindow, show);
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/widgets/qmainwindowlayout_p.h b/src/gui/widgets/qmainwindowlayout_p.h
index 26f8633..524fdbf 100644
--- a/src/gui/widgets/qmainwindowlayout_p.h
+++ b/src/gui/widgets/qmainwindowlayout_p.h
@@ -63,6 +63,7 @@
#include "QtCore/qset.h"
#include "QtCore/qbasictimer.h"
#include "private/qlayoutengine_p.h"
+#include "private/qwidgetanimator_p.h"
#include "qdockarealayout_p.h"
#include "qtoolbararealayout_p.h"
@@ -89,7 +90,6 @@ typedef const struct __CFString * CFStringRef;
QT_BEGIN_NAMESPACE
class QToolBar;
-class QWidgetAnimator;
class QRubberBand;
/* This data structure represents the state of all the tool-bars and dock-widgets. It's value based
@@ -128,9 +128,9 @@ public:
QLayoutItem *itemAt(int index, int *x) const;
QLayoutItem *takeAt(int index, int *x);
QList<int> indexOf(QWidget *widget) const;
- QLayoutItem *item(QList<int> path);
- QRect itemRect(QList<int> path) const;
- QRect gapRect(QList<int> path) const; // ### get rid of this, use itemRect() instead
+ QLayoutItem *item(const QList<int> &path);
+ QRect itemRect(const QList<int> &path) const;
+ QRect gapRect(const QList<int> &path) const; // ### get rid of this, use itemRect() instead
bool contains(QWidget *widget) const;
@@ -138,14 +138,14 @@ public:
QWidget *centralWidget() const;
QList<int> gapIndex(QWidget *widget, const QPoint &pos) const;
- bool insertGap(QList<int> path, QLayoutItem *item);
- void remove(QList<int> path);
+ bool insertGap(const QList<int> &path, QLayoutItem *item);
+ void remove(const QList<int> &path);
void remove(QLayoutItem *item);
void clear();
bool isValid() const;
- QLayoutItem *plug(QList<int> path);
- QLayoutItem *unplug(QList<int> path, QMainWindowLayoutState *savedState = 0);
+ QLayoutItem *plug(const QList<int> &path);
+ QLayoutItem *unplug(const QList<int> &path, QMainWindowLayoutState *savedState = 0);
void saveState(QDataStream &stream) const;
bool checkFormat(QDataStream &stream, bool pre43);
@@ -278,7 +278,7 @@ public:
// animations
- QWidgetAnimator *widgetAnimator;
+ QWidgetAnimator widgetAnimator;
QList<int> currentGapPos;
QRect currentGapRect;
QWidget *pluggingWidget;
@@ -295,10 +295,9 @@ public:
void applyState(QMainWindowLayoutState &newState, bool animate = true);
void restore(bool keepSavedState = false);
void updateHIToolBarStatus();
-
-private slots:
void animationFinished(QWidget *widget);
- void allAnimationsFinished();
+
+private Q_SLOTS:
#ifndef QT_NO_DOCKWIDGET
#ifndef QT_NO_TABBAR
void tabChanged();
@@ -336,6 +335,8 @@ public:
void cleanUpMacToolbarItems();
void fixSizeInUnifiedToolbar(QToolBar *tb) const;
bool useHIToolBar;
+ void syncUnifiedToolbarVisibility();
+ bool blockVisiblityCheck;
#endif
};
QT_END_NAMESPACE
diff --git a/src/gui/widgets/qmdiarea.h b/src/gui/widgets/qmdiarea.h
index f64397b..9f1014e 100644
--- a/src/gui/widgets/qmdiarea.h
+++ b/src/gui/widgets/qmdiarea.h
@@ -153,7 +153,7 @@ protected:
private:
Q_DISABLE_COPY(QMdiArea)
- Q_DECLARE_SCOPED_PRIVATE(QMdiArea)
+ Q_DECLARE_PRIVATE(QMdiArea)
Q_PRIVATE_SLOT(d_func(), void _q_deactivateAllWindows())
Q_PRIVATE_SLOT(d_func(), void _q_processWindowStateChanged(Qt::WindowStates, Qt::WindowStates))
Q_PRIVATE_SLOT(d_func(), void _q_currentTabChanged(int index))
diff --git a/src/gui/widgets/qmdisubwindow.cpp b/src/gui/widgets/qmdisubwindow.cpp
index 25bc724..e8de957 100644
--- a/src/gui/widgets/qmdisubwindow.cpp
+++ b/src/gui/widgets/qmdisubwindow.cpp
@@ -1066,7 +1066,7 @@ void QMdiSubWindowPrivate::createSystemMenu()
addToSystemMenu(CloseAction, QMdiSubWindow::tr("&Close"), SLOT(close()));
actions[CloseAction]->setIcon(style->standardIcon(QStyle::SP_TitleBarCloseButton, 0, q));
#if !defined(QT_NO_SHORTCUT)
- actions[CloseAction]->setShortcut(QKeySequence::Close);
+ actions[CloseAction]->setShortcuts(QKeySequence::Close);
#endif
updateActions();
}
@@ -1946,26 +1946,21 @@ QPalette QMdiSubWindowPrivate::desktopPalette() const
colorref2qrgb(GetSysColor(COLOR_CAPTIONTEXT)));
newPalette.setColor(QPalette::Inactive, QPalette::HighlightedText,
colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTIONTEXT)));
- if (QSysInfo::WindowsVersion != QSysInfo::WV_95
- && QSysInfo::WindowsVersion != QSysInfo::WV_NT) {
- colorsInitialized = true;
- BOOL hasGradient;
- QT_WA({
- SystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, &hasGradient, 0);
- } , {
- SystemParametersInfoA(SPI_GETGRADIENTCAPTIONS, 0, &hasGradient, 0);
- });
- if (hasGradient) {
- newPalette.setColor(QPalette::Active, QPalette::Base,
- colorref2qrgb(GetSysColor(COLOR_GRADIENTACTIVECAPTION)));
- newPalette.setColor(QPalette::Inactive, QPalette::Base,
- colorref2qrgb(GetSysColor(COLOR_GRADIENTINACTIVECAPTION)));
- } else {
- newPalette.setColor(QPalette::Active, QPalette::Base,
- newPalette.color(QPalette::Active, QPalette::Highlight));
- newPalette.setColor(QPalette::Inactive, QPalette::Base,
- newPalette.color(QPalette::Inactive, QPalette::Highlight));
- }
+
+ colorsInitialized = true;
+ BOOL hasGradient = false;
+ SystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, &hasGradient, 0);
+
+ if (hasGradient) {
+ newPalette.setColor(QPalette::Active, QPalette::Base,
+ colorref2qrgb(GetSysColor(COLOR_GRADIENTACTIVECAPTION)));
+ newPalette.setColor(QPalette::Inactive, QPalette::Base,
+ colorref2qrgb(GetSysColor(COLOR_GRADIENTINACTIVECAPTION)));
+ } else {
+ newPalette.setColor(QPalette::Active, QPalette::Base,
+ newPalette.color(QPalette::Active, QPalette::Highlight));
+ newPalette.setColor(QPalette::Inactive, QPalette::Base,
+ newPalette.color(QPalette::Inactive, QPalette::Highlight));
}
}
#endif // Q_WS_WIN
diff --git a/src/gui/widgets/qmdisubwindow.h b/src/gui/widgets/qmdisubwindow.h
index bfb523d..924cc9a 100644
--- a/src/gui/widgets/qmdisubwindow.h
+++ b/src/gui/widgets/qmdisubwindow.h
@@ -137,7 +137,7 @@ protected:
private:
Q_DISABLE_COPY(QMdiSubWindow)
- Q_DECLARE_SCOPED_PRIVATE(QMdiSubWindow)
+ Q_DECLARE_PRIVATE(QMdiSubWindow)
Q_PRIVATE_SLOT(d_func(), void _q_updateStaysOnTopHint())
Q_PRIVATE_SLOT(d_func(), void _q_enterInteractiveMode())
Q_PRIVATE_SLOT(d_func(), void _q_processFocusChanged(QWidget *, QWidget *))
diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp
index f1cbd65..6465975 100644
--- a/src/gui/widgets/qmenu.cpp
+++ b/src/gui/widgets/qmenu.cpp
@@ -144,7 +144,7 @@ public slots:
void onTrigger(QAction *action) { d_func()->activateAction(action, QAction::Trigger, false); }
void onHovered(QAction *action) { d_func()->activateAction(action, QAction::Hover, false); }
private:
- Q_DECLARE_SCOPED_PRIVATE(QTornOffMenu)
+ Q_DECLARE_PRIVATE(QTornOffMenu)
friend class QMenuPrivate;
};
@@ -164,6 +164,12 @@ void QMenuPrivate::init()
}
}
+int QMenuPrivate::scrollerHeight() const
+{
+ Q_Q(const QMenu);
+ return qMax(QApplication::globalStrut().height(), q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q));
+}
+
//Windows and KDE allows menus to cover the taskbar, while GNOME and Mac don't
QRect QMenuPrivate::popupGeometry(int screen) const
{
@@ -223,6 +229,10 @@ void QMenuPrivate::updateActionRects() const
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);
+ const int fw = style->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q);
+
+ const int sfcMargin = style->sizeFromContents(QStyle::CT_Menu, 0, QApplication::globalStrut(), q).width() - QApplication::globalStrut().width();
+ const int min_column_width = q->minimumWidth() - (sfcMargin + leftmargin + rightmargin + 2 * (fw + hmargin));
//for compatability now - will have to refactor this away..
tabWidth = 0;
@@ -258,7 +268,6 @@ void QMenuPrivate::updateActionRects() const
//let the style modify the above size..
QStyleOptionMenuItem opt;
q->initStyleOption(&opt, action);
- opt.rect = q->rect();
const QFontMetrics &fm = opt.fontMetrics;
QSize sz;
@@ -281,10 +290,7 @@ void QMenuPrivate::updateActionRects() const
tabWidth = qMax(int(tabWidth), qfm.width(seq));
#endif
}
- int w = fm.boundingRect(QRect(), Qt::TextSingleLine, s).width();
- w -= s.count(QLatin1Char('&')) * fm.width(QLatin1Char('&'));
- w += s.count(QLatin1String("&&")) * fm.width(QLatin1Char('&'));
- sz.setWidth(w);
+ sz.setWidth(fm.boundingRect(QRect(), Qt::TextSingleLine | Qt::TextShowMnemonic, s).width());
sz.setHeight(qMax(fm.height(), qfm.height()));
QIcon is = action->icon();
@@ -299,7 +305,7 @@ void QMenuPrivate::updateActionRects() const
if (!sz.isEmpty()) {
- max_column_width = qMax(max_column_width, sz.width());
+ max_column_width = qMax(min_column_width, qMax(max_column_width, sz.width()));
//wrapping
if (!scroll &&
y+sz.height()+vmargin > dh - (style->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, 0, q) * 2)) {
@@ -315,7 +321,6 @@ void QMenuPrivate::updateActionRects() const
max_column_width += tabWidth; //finally add in the tab width
//calculate position
- 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);
@@ -484,17 +489,17 @@ void QMenuPrivate::setSyncAction()
void QMenuPrivate::setFirstActionActive()
{
Q_Q(QMenu);
- const int scrollerHeight = q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q);
+ updateActionRects();
for(int i = 0, saccum = 0; i < actions.count(); i++) {
- QAction *act = actions.at(i);
const QRect &rect = actionRects.at(i);
if (rect.isNull())
continue;
if (scroll && scroll->scrollFlags & QMenuScroller::ScrollUp) {
saccum -= rect.height();
- if (saccum > scroll->scrollOffset-scrollerHeight)
+ if (saccum > scroll->scrollOffset - scrollerHeight())
continue;
}
+ QAction *act = actions.at(i);
if (!act->isSeparator() &&
(q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, q)
|| act->isEnabled())) {
@@ -673,17 +678,16 @@ void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation loc
Q_Q(QMenu);
if (!scroll || !scroll->scrollFlags)
return;
+ updateActionRects();
int newOffset = 0;
- const int scrollHeight = q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q);
- const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp) ? scrollHeight : 0;
- const int botScroll = (scroll->scrollFlags & QMenuScroller::ScrollDown) ? scrollHeight : 0;
+ const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp) ? scrollerHeight() : 0;
+ const int botScroll = (scroll->scrollFlags & QMenuScroller::ScrollDown) ? scrollerHeight() : 0;
const int vmargin = q->style()->pixelMetric(QStyle::PM_MenuVMargin, 0, q);
const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q);
if (location == QMenuScroller::ScrollTop) {
for(int i = 0, saccum = 0; i < actions.count(); i++) {
- QAction *act = actions.at(i);
- if (act == action) {
+ if (actions.at(i) == action) {
newOffset = topScroll - saccum;
break;
}
@@ -691,9 +695,8 @@ void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation loc
}
} else {
for(int i = 0, saccum = 0; i < actions.count(); i++) {
- QAction *act = actions.at(i);
saccum += actionRects.at(i).height();
- if (act == action) {
+ if (actions.at(i) == action) {
if (location == QMenuScroller::ScrollCenter)
newOffset = ((q->height() / 2) - botScroll) - (saccum - topScroll);
else
@@ -762,9 +765,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);
@@ -775,6 +788,7 @@ void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation loc
void QMenuPrivate::scrollMenu(QMenuScroller::ScrollLocation location, bool active)
{
Q_Q(QMenu);
+ updateActionRects();
if(location == QMenuScroller::ScrollBottom) {
for(int i = actions.size()-1; i >= 0; --i) {
QAction *act = actions.at(i);
@@ -814,9 +828,9 @@ void QMenuPrivate::scrollMenu(QMenuScroller::ScrollDirection direction, bool pag
Q_Q(QMenu);
if (!scroll || !(scroll->scrollFlags & direction)) //not really possible...
return;
- const int scrollHeight = q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q);
- const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp) ? scrollHeight : 0;
- const int botScroll = (scroll->scrollFlags & QMenuScroller::ScrollDown) ? scrollHeight : 0;
+ updateActionRects();
+ const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp) ? scrollerHeight() : 0;
+ const int botScroll = (scroll->scrollFlags & QMenuScroller::ScrollDown) ? scrollerHeight() : 0;
const int vmargin = q->style()->pixelMetric(QStyle::PM_MenuVMargin, 0, q);
const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q);
const int offset = topScroll ? topScroll-vmargin : 0;
@@ -863,13 +877,12 @@ bool QMenuPrivate::mouseEventTaken(QMouseEvent *e)
if (scroll && !activeMenu) { //let the scroller "steal" the event
bool isScroll = false;
if (pos.x() >= 0 && pos.x() < q->width()) {
- const int scrollerHeight = q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q);
for(int dir = QMenuScroller::ScrollUp; dir <= QMenuScroller::ScrollDown; dir = dir << 1) {
if (scroll->scrollFlags & dir) {
if (dir == QMenuScroller::ScrollUp)
- isScroll = (pos.y() <= scrollerHeight);
+ isScroll = (pos.y() <= scrollerHeight());
else if (dir == QMenuScroller::ScrollDown)
- isScroll = (pos.y() >= q->height()-scrollerHeight);
+ isScroll = (pos.y() >= q->height() - scrollerHeight());
if (isScroll) {
scroll->scrollDirection = dir;
break;
@@ -878,19 +891,17 @@ bool QMenuPrivate::mouseEventTaken(QMouseEvent *e)
}
}
if (isScroll) {
- if (!scroll->scrollTimer)
- scroll->scrollTimer = new QBasicTimer;
- scroll->scrollTimer->start(50, q);
+ scroll->scrollTimer.start(50, q);
return true;
- } else if (scroll->scrollTimer && scroll->scrollTimer->isActive()) {
- scroll->scrollTimer->stop();
+ } else {
+ scroll->scrollTimer.stop();
}
}
if (tearoff) { //let the tear off thingie "steal" the event..
QRect tearRect(0, 0, q->width(), q->style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, q));
if (scroll && scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)
- tearRect.translate(0, q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q));
+ tearRect.translate(0, scrollerHeight());
q->update(tearRect);
if (tearRect.contains(pos) && hasMouseMoved(e->globalPos())) {
setCurrentAction(0);
@@ -1351,8 +1362,7 @@ QMenu::~QMenu()
if (d->eventLoop)
d->eventLoop->exit();
- if (d->tornPopup)
- d->tornPopup->close();
+ hideTearOffMenu();
}
/*!
@@ -1563,8 +1573,8 @@ void QMenu::setTearOffEnabled(bool b)
Q_D(QMenu);
if (d->tearoff == b)
return;
- if (!b && d->tornPopup)
- d->tornPopup->close();
+ if (!b)
+ hideTearOffMenu();
d->tearoff = b;
d->itemsDirty = true;
@@ -1599,8 +1609,8 @@ bool QMenu::isTearOffMenuVisible() const
*/
void QMenu::hideTearOffMenu()
{
- if (d_func()->tornPopup)
- d_func()->tornPopup->close();
+ if (QWidget *w = d_func()->tornPopup)
+ w->close();
}
@@ -1703,9 +1713,7 @@ QSize QMenu::sizeHint() const
QSize s;
QStyleOption opt(0);
- opt.rect = rect();
- opt.palette = palette();
- opt.state = QStyle::State_None;
+ opt.init(this);
for (int i = 0; i < d->actionRects.count(); ++i) {
const QRect &rect = d->actionRects.at(i);
if (rect.isNull())
@@ -1715,8 +1723,6 @@ QSize QMenu::sizeHint() const
if (rect.right() >= s.width())
s.setWidth(rect.x() + rect.width());
}
- if (d->tearoff)
- s.rheight() += style()->pixelMetric(QStyle::PM_MenuTearoffHeight, &opt, this);
// Note that the action rects calculated above already include
// the top and left margins, so we only need to add margins for
// the bottom and right.
@@ -2076,6 +2082,8 @@ void QMenu::hideEvent(QHideEvent *)
d->hasHadMouse = false;
d->causedPopup.widget = 0;
d->causedPopup.action = 0;
+ if (d->scroll)
+ d->scroll->scrollTimer.stop(); //make sure the timer stops
}
/*!
@@ -2084,6 +2092,7 @@ void QMenu::hideEvent(QHideEvent *)
void QMenu::paintEvent(QPaintEvent *e)
{
Q_D(QMenu);
+ d->updateActionRects();
QPainter p(this);
QRegion emptyArea = QRegion(rect());
@@ -2116,18 +2125,17 @@ void QMenu::paintEvent(QPaintEvent *e)
const int fw = style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, this);
//draw the scroller regions..
if (d->scroll) {
- const int scrollerHeight = style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, this);
menuOpt.menuItemType = QStyleOptionMenuItem::Scroller;
menuOpt.state |= QStyle::State_Enabled;
if (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp) {
- menuOpt.rect.setRect(fw, fw, width() - (fw * 2), scrollerHeight);
+ menuOpt.rect.setRect(fw, fw, width() - (fw * 2), d->scrollerHeight());
emptyArea -= QRegion(menuOpt.rect);
p.setClipRect(menuOpt.rect);
style()->drawControl(QStyle::CE_MenuScroller, &menuOpt, &p, this);
}
if (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollDown) {
- menuOpt.rect.setRect(fw, height() - scrollerHeight - fw, width() - (fw * 2),
- scrollerHeight);
+ menuOpt.rect.setRect(fw, height() - d->scrollerHeight() - fw, width() - (fw * 2),
+ d->scrollerHeight());
emptyArea -= QRegion(menuOpt.rect);
menuOpt.state |= QStyle::State_DownArrow;
p.setClipRect(menuOpt.rect);
@@ -2140,7 +2148,7 @@ void QMenu::paintEvent(QPaintEvent *e)
menuOpt.rect.setRect(fw, fw, width() - (fw * 2),
style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this));
if (d->scroll && d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)
- menuOpt.rect.translate(0, style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, this));
+ menuOpt.rect.translate(0, d->scrollerHeight());
emptyArea -= QRegion(menuOpt.rect);
p.setClipRect(menuOpt.rect);
menuOpt.state = QStyle::State_None;
@@ -2370,6 +2378,7 @@ bool QMenu::focusNextPrevChild(bool next)
void QMenu::keyPressEvent(QKeyEvent *e)
{
Q_D(QMenu);
+ d->updateActionRects();
int key = e->key();
if (isRightToLeft()) { // in reverse mode open/close key for submenues are reversed
if (key == Qt::Key_Left)
@@ -2469,7 +2478,7 @@ void QMenu::keyPressEvent(QKeyEvent *e)
continue;
nextAction = next;
if (d->scroll && (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)) {
- int topVisible = style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, this);
+ int topVisible = d->scrollerHeight();
if (d->tearoff)
topVisible += style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this);
if (((y + d->scroll->scrollOffset) - topVisible) <= d->actionRects.at(next_i).height())
@@ -2500,10 +2509,9 @@ void QMenu::keyPressEvent(QKeyEvent *e)
continue;
nextAction = next;
if (d->scroll && (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollDown)) {
- const int scrollerHeight = style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, this);
- int bottomVisible = height()-scrollerHeight;
+ int bottomVisible = height() - d->scrollerHeight();
if (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)
- bottomVisible -= scrollerHeight;
+ bottomVisible -= d->scrollerHeight();
if (d->tearoff)
bottomVisible -= style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this);
if ((y + d->scroll->scrollOffset + d->actionRects.at(next_i).height()) > bottomVisible)
@@ -2519,8 +2527,7 @@ void QMenu::keyPressEvent(QKeyEvent *e)
}
if (nextAction) {
if (d->scroll && scroll_loc != QMenuPrivate::QMenuScroller::ScrollStay) {
- if (d->scroll->scrollTimer)
- d->scroll->scrollTimer->stop();
+ d->scroll->scrollTimer.stop();
d->scrollMenu(nextAction, scroll_loc);
}
d->setCurrentAction(nextAction, /*popup*/-1, QMenuPrivate::SelectedFromKeyboard);
@@ -2742,7 +2749,7 @@ void QMenu::mouseMoveEvent(QMouseEvent *e)
QAction *action = d->actionAt(e->pos());
if (!action) {
- if (d->hasHadMouse && !rect().contains(e->pos()))
+ if (d->hasHadMouse)
d->setCurrentAction(0);
return;
} else if(e->buttons()) {
@@ -2782,10 +2789,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();
@@ -3044,12 +3051,19 @@ bool QMenu::separatorsCollapsible() const
void QMenu::setSeparatorsCollapsible(bool collapse)
{
Q_D(QMenu);
+ if (d->collapsibleSeparators == collapse)
+ return;
+
d->collapsibleSeparators = collapse;
d->itemsDirty = 1;
if (isVisible()) {
d->updateActionRects();
update();
}
+#ifdef Q_WS_MAC
+ if (d->mac_menu)
+ d->syncSeparatorsCollapsible(collapse);
+#endif
}
#ifdef QT3_SUPPORT
diff --git a/src/gui/widgets/qmenu.h b/src/gui/widgets/qmenu.h
index 9f9cdf5..41890c4 100644
--- a/src/gui/widgets/qmenu.h
+++ b/src/gui/widgets/qmenu.h
@@ -77,7 +77,7 @@ class Q_GUI_EXPORT QMenu : public QWidget
{
private:
Q_OBJECT
- Q_DECLARE_SCOPED_PRIVATE(QMenu)
+ Q_DECLARE_PRIVATE(QMenu)
Q_PROPERTY(bool tearOffEnabled READ isTearOffEnabled WRITE setTearOffEnabled)
Q_PROPERTY(QString title READ title WRITE setTitle)
diff --git a/src/gui/widgets/qmenu_mac.mm b/src/gui/widgets/qmenu_mac.mm
index 77e98c4..e6239f4 100644
--- a/src/gui/widgets/qmenu_mac.mm
+++ b/src/gui/widgets/qmenu_mac.mm
@@ -458,7 +458,8 @@ OSStatus qt_mac_menu_event(EventHandlerCallRef er, EventRef event, void *)
int merged = 0;
const QMenuPrivate::QMacMenuPrivate *mac_menu = qmenu->d_func()->mac_menu;
- for(int i = 0; i < mac_menu->actionItems.size(); ++i) {
+ const int ActionItemsCount = mac_menu->actionItems.size();
+ for(int i = 0; i < ActionItemsCount; ++i) {
QMacMenuAction *action = mac_menu->actionItems.at(i);
if (action->action->isSeparator()) {
bool hide = false;
@@ -972,7 +973,7 @@ void Q_GUI_EXPORT qt_mac_set_menubar_merge(bool b) { qt_mac_no_menubar_merge = !
/*****************************************************************************
QMenu bindings
*****************************************************************************/
-QMenuPrivate::QMacMenuPrivate::QMacMenuPrivate(QMenuPrivate *menu) : menu(0), qmenu(menu)
+QMenuPrivate::QMacMenuPrivate::QMacMenuPrivate() : menu(0)
{
}
@@ -1300,61 +1301,22 @@ QMenuPrivate::QMacMenuPrivate::syncAction(QMacMenuAction *action)
#else
int itemIndex = [menu indexOfItem:item];
Q_ASSERT(itemIndex != -1);
-
- // Separator handling: Menu items and separators can be added to a QMenu in
- // any order (for example, add all the separators first and then "fill inn"
- // the menu items). Create NSMenuItem seperatorItems for the Qt separators,
- // and make sure that there are no double separators and no seprators
- // at the top or bottom of the menu.
- bool itemIsSeparator = action->action->isSeparator();
- bool previousItemIsSeparator = false;
- if (itemIndex > 0) {
- if ([[menu itemAtIndex : itemIndex - 1] isSeparatorItem])
- previousItemIsSeparator = true;
- }
- bool nexItemIsSeparator = false;
- if (itemIndex > 0 && itemIndex < [menu numberOfItems] -1) {
- if ([[menu itemAtIndex : itemIndex + 1] isSeparatorItem])
- nexItemIsSeparator = true;
- }
- bool itemIsAtBottomOfMenu = (itemIndex == [menu numberOfItems] - 1);
- bool itemIsAtTopOfMenu = (itemIndex == 0);
-
-
- if (itemIsSeparator) {
- // Create separators items for actions that are now separators
+ if (action->action->isSeparator()) {
action->menuItem = [NSMenuItem separatorItem];
[action->menuItem retain];
-
- // Hide duplicate/top/bottom separators.
- if (qmenu->collapsibleSeparators && (previousItemIsSeparator || itemIsAtBottomOfMenu || itemIsAtTopOfMenu)) {
- [action->menuItem setHidden : true];
- }
-
[menu insertItem: action->menuItem atIndex:itemIndex];
[menu removeItem:item];
[item release];
item = action->menuItem;
return;
- } else {
- // Create standard menu items for actions that are no longer separators
- if ([item isSeparatorItem]) {
- action->menuItem = createNSMenuItem(action->action->text());
- [menu insertItem:action->menuItem atIndex:itemIndex];
- [menu removeItem:item];
- [item release];
- item = action->menuItem;
- }
-
- // Show separators that should now be visible since a non-separator
- // item (the current item) was added.
- if (previousItemIsSeparator) {
- [[menu itemAtIndex : itemIndex - 1] setHidden : false];
- } else if (itemIsAtTopOfMenu && nexItemIsSeparator) {
- [[menu itemAtIndex : itemIndex + 1] setHidden : false];
- }
+ } else if ([item isSeparatorItem]) {
+ // I'm no longer a separator...
+ action->menuItem = createNSMenuItem(action->action->text());
+ [menu insertItem:action->menuItem atIndex:itemIndex];
+ [menu removeItem:item];
+ [item release];
+ item = action->menuItem;
}
-
#endif
//find text (and accel)
@@ -1376,8 +1338,9 @@ QMenuPrivate::QMacMenuPrivate::syncAction(QMacMenuAction *action)
accel = qt_mac_menu_merge_accel(action);
}
}
+ // Show multiple key sequences as part of the menu text.
if (accel.count() > 1)
- text += QLatin1String(" (****)"); //just to denote a multi stroke shortcut
+ text += QLatin1String(" (") + accel.toString(QKeySequence::NativeText) + QLatin1String(")");
QString finalString = qt_mac_removeMnemonics(text);
@@ -1459,14 +1422,15 @@ QMenuPrivate::QMacMenuPrivate::syncAction(QMacMenuAction *action)
data.whichData |= kMenuItemDataCmdKey;
data.whichData |= kMenuItemDataCmdKeyModifiers;
data.whichData |= kMenuItemDataCmdKeyGlyph;
- if (!accel.isEmpty()) {
+ if (accel.count() == 1) {
qt_mac_get_accel(accel[0], (quint32*)&data.cmdKeyModifiers, (quint32*)&data.cmdKeyGlyph);
if (data.cmdKeyGlyph == 0)
data.cmdKey = (UniChar)accel[0];
}
#else
[item setSubmenu:0];
- if (!accel.isEmpty()) {
+ // No key equivalent set for multiple key QKeySequence.
+ if (accel.count() == 1) {
[item setKeyEquivalent:keySequenceToKeyEqivalent(accel)];
[item setKeyEquivalentModifierMask:keySequenceModifierMask(accel)];
} else {
@@ -1538,7 +1502,7 @@ QMenuPrivate::macMenu(OSMenuRef merge)
if (mac_menu && mac_menu->menu)
return mac_menu->menu;
if (!mac_menu)
- mac_menu = new QMacMenuPrivate(this);
+ mac_menu = new QMacMenuPrivate;
mac_menu->menu = qt_mac_create_menu(q);
if (merge) {
#ifndef QT_MAC_USE_COCOA
@@ -1550,12 +1514,31 @@ QMenuPrivate::macMenu(OSMenuRef merge)
QList<QAction*> items = q->actions();
for(int i = 0; i < items.count(); i++)
mac_menu->addAction(items[i], 0, this);
+ syncSeparatorsCollapsible(collapsibleSeparators);
return mac_menu->menu;
}
/*!
\internal
*/
+void
+QMenuPrivate::syncSeparatorsCollapsible(bool collapse)
+{
+#ifndef QT_MAC_USE_COCOA
+ if (collapse)
+ ChangeMenuAttributes(mac_menu->menu, kMenuAttrCondenseSeparators, 0);
+ else
+ ChangeMenuAttributes(mac_menu->menu, 0, kMenuAttrCondenseSeparators);
+#else
+ qt_mac_menu_collapseSeparators(mac_menu->menu, collapse);
+#endif
+}
+
+
+
+/*!
+ \internal
+*/
void QMenuPrivate::setMacMenuEnabled(bool enable)
{
if (!macMenu(0))
diff --git a/src/gui/widgets/qmenu_p.h b/src/gui/widgets/qmenu_p.h
index d9ad422..0218dc7 100644
--- a/src/gui/widgets/qmenu_p.h
+++ b/src/gui/widgets/qmenu_p.h
@@ -170,6 +170,8 @@ public:
}
void init();
+ int scrollerHeight() const;
+
//item calculations
mutable uint itemsDirty : 1;
mutable uint maxIconWidth, tabWidth;
@@ -208,10 +210,10 @@ public:
enum ScrollDirection { ScrollNone=0, ScrollUp=0x01, ScrollDown=0x02 };
uint scrollFlags : 2, scrollDirection : 2;
int scrollOffset;
- QBasicTimer *scrollTimer;
+ QBasicTimer scrollTimer;
- QMenuScroller() : scrollFlags(ScrollNone), scrollDirection(ScrollNone), scrollOffset(0), scrollTimer(0) { }
- ~QMenuScroller() { delete scrollTimer; }
+ QMenuScroller() : scrollFlags(ScrollNone), scrollDirection(ScrollNone), scrollOffset(0) { }
+ ~QMenuScroller() { }
} *scroll;
void scrollMenu(QMenuScroller::ScrollLocation location, bool active=false);
void scrollMenu(QMenuScroller::ScrollDirection direction, bool page=false, bool active=false);
@@ -280,9 +282,8 @@ public:
struct QMacMenuPrivate {
QList<QMacMenuAction*> actionItems;
OSMenuRef menu;
- QMenuPrivate *qmenu;
- QMacMenuPrivate(QMenuPrivate *menu);
- ~QMacMenuPrivate();
+ QMacMenuPrivate();
+ ~QMacMenuPrivate();
bool merged(const QAction *action) const;
void addAction(QAction *, QMacMenuAction* =0, QMenuPrivate *qmenu = 0);
@@ -302,6 +303,7 @@ public:
} *mac_menu;
OSMenuRef macMenu(OSMenuRef merge);
void setMacMenuEnabled(bool enable = true);
+ void syncSeparatorsCollapsible(bool collapsible);
static QHash<OSMenuRef, OSMenuRef> mergeMenuHash;
static QHash<OSMenuRef, QMenuMergeList*> mergeMenuItemsHash;
#endif
diff --git a/src/gui/widgets/qmenu_symbian.cpp b/src/gui/widgets/qmenu_symbian.cpp
index 1b21b71..b0cd7c8 100644
--- a/src/gui/widgets/qmenu_symbian.cpp
+++ b/src/gui/widgets/qmenu_symbian.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: Qt Software Information (qt-info@nokia.com)
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
**
**
** $QT_BEGIN_LICENSE:LGPL$
@@ -33,7 +33,7 @@
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you are unsure which license is appropriate for your use, please
-** contact the sales department at qt-sales@nokia.com.
+** contact the sales department at http://www.qtsoftware.com/contact.
** $QT_END_LICENSE$
**
****************************************************************************/
diff --git a/src/gui/widgets/qmenubar.cpp b/src/gui/widgets/qmenubar.cpp
index 4607fc3..eaf03b3 100644
--- a/src/gui/widgets/qmenubar.cpp
+++ b/src/gui/widgets/qmenubar.cpp
@@ -218,7 +218,7 @@ void QMenuBarPrivate::updateGeometries()
bool hasHiddenActions = false;
for (int i = 0; i < actions.count(); ++i) {
const QRect &rect = actionRects.at(i);
- if (!menuRect.contains(rect)) {
+ if (rect.isValid() && !menuRect.contains(rect)) {
hasHiddenActions = true;
break;
}
@@ -229,7 +229,7 @@ void QMenuBarPrivate::updateGeometries()
menuRect = this->menuRect(true);
for (int i = 0; i < actions.count(); ++i) {
const QRect &rect = actionRects.at(i);
- if (!menuRect.contains(rect)) {
+ if (rect.isValid() && !menuRect.contains(rect)) {
hiddenActions.append(actions.at(i));
}
}
@@ -279,6 +279,7 @@ QRect QMenuBarPrivate::actionRect(QAction *act) const
void QMenuBarPrivate::focusFirstAction()
{
if(!currentAction) {
+ updateGeometries();
int index = 0;
while (index < actions.count() && actionRects.at(index).isNull()) ++index;
if (index < actions.count())
@@ -445,16 +446,12 @@ void QMenuBarPrivate::calcActionRects(int max_width, int start) const
continue; //we don't really position these!
} else {
const QString s = action->text();
- if(!s.isEmpty()) {
- const int w = fm.width(s)
- - s.count(QLatin1Char('&')) * fm.width(QLatin1Char('&'))
- + s.count(QLatin1String("&&")) * fm.width(QLatin1Char('&'));
- sz = QSize(w, fm.height());
- }
-
QIcon is = action->icon();
+ // If an icon is set, only the icon is visible
if (!is.isNull())
sz = sz.expandedTo(QSize(icone, icone));
+ else if (!s.isEmpty())
+ sz = fm.size(Qt::TextShowMnemonic, s);
}
//let the style modify the above size..
@@ -719,7 +716,7 @@ void QMenuBar::initStyleOption(QStyleOptionMenuItem *option, const QAction *acti
application examples} also provide menus using these classes.
\sa QMenu, QShortcut, QAction,
- {http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/index.html}{Introduction to Apple Human Interface Guidelines},
+ {http://developer.apple.com/documentation/UserExperience/Conceptual/AppleHIGuidelines/XHIGIntro/XHIGIntro.html}{Introduction to Apple Human Interface Guidelines},
{fowler}{GUI Design Handbook: Menu Bar}, {Menus Example}
*/
@@ -764,6 +761,7 @@ void QMenuBarPrivate::init()
QAction *QMenuBarPrivate::getNextAction(const int _start, const int increment) const
{
Q_Q(const QMenuBar);
+ const_cast<QMenuBarPrivate*>(this)->updateGeometries();
bool allowActiveAndDisabled = q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, q);
const int start = (_start == -1 && increment == -1) ? actions.count() : _start;
const int end = increment == -1 ? 0 : actions.count() - 1;
@@ -964,6 +962,13 @@ void QMenuBar::setActiveAction(QAction *act)
/*!
Removes all the actions from the menu bar.
+ \note On Mac OS X, menu items that have been merged to the system
+ menu bar are not removed by this function. One way to handle this
+ would be to remove the extra actions yourself. You can set the
+ \l{QAction::MenuRole}{menu role} on the different menus, so that
+ you know ahead of time which menu items get merged and which do
+ not. Then decide what to recreate or remove yourself.
+
\sa removeAction()
*/
void QMenuBar::clear()
@@ -1140,6 +1145,7 @@ void QMenuBar::mouseReleaseEvent(QMouseEvent *e)
void QMenuBar::keyPressEvent(QKeyEvent *e)
{
Q_D(QMenuBar);
+ d->updateGeometries();
int key = e->key();
if(isRightToLeft()) { // in reverse mode open/close key for submenues are reversed
if(key == Qt::Key_Left)
@@ -1630,6 +1636,7 @@ QSize QMenuBar::minimumSizeHint() const
ensurePolished();
QSize ret(0, 0);
+ const_cast<QMenuBarPrivate*>(d)->updateGeometries();
const int hmargin = style()->pixelMetric(QStyle::PM_MenuBarHMargin, 0, this);
const int vmargin = style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, this);
int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, this);
@@ -1782,6 +1789,9 @@ void QMenuBarPrivate::_q_internalShortcutActivated(int id)
activateAction(act, QAction::Trigger);
//100 is the same as the default value in QPushButton::animateClick
autoReleaseTimer.start(100, q);
+ } else if (act && q->style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation, 0, q)) {
+ // When we open a menu using a shortcut, we should end up in keyboard state
+ setKeyboardMode(true);
}
}
diff --git a/src/gui/widgets/qmenubar.h b/src/gui/widgets/qmenubar.h
index ddd2d67..1fda1c1 100644
--- a/src/gui/widgets/qmenubar.h
+++ b/src/gui/widgets/qmenubar.h
@@ -336,7 +336,7 @@ private:
#endif
private:
- Q_DECLARE_SCOPED_PRIVATE(QMenuBar)
+ Q_DECLARE_PRIVATE(QMenuBar)
Q_DISABLE_COPY(QMenuBar)
Q_PRIVATE_SLOT(d_func(), void _q_actionTriggered())
Q_PRIVATE_SLOT(d_func(), void _q_actionHovered())
diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp
index c2ef5e4..7d9d2b5 100644
--- a/src/gui/widgets/qplaintextedit.cpp
+++ b/src/gui/widgets/qplaintextedit.cpp
@@ -66,6 +66,8 @@
#include <qtexttable.h>
#include <qvariant.h>
+#include <qstandardgestures.h>
+
#include <qinputcontext.h>
#ifndef QT_NO_TEXTEDIT
@@ -255,7 +257,7 @@ QPlainTextDocumentLayoutPrivate *QPlainTextDocumentLayout::priv() const
*/
void QPlainTextDocumentLayout::requestUpdate()
{
- emit update(QRectF(0., -4., 1000000000., 1000000000.));
+ emit update(QRectF(0., -document()->documentMargin(), 1000000000., 1000000000.));
}
@@ -350,8 +352,7 @@ void QPlainTextDocumentLayout::documentChanged(int from, int /*charsRemoved*/, i
}
if (!d->blockUpdate)
- emit update(); // optimization potential
-
+ emit update(QRectF(0., -doc->documentMargin(), 1000000000., 1000000000.)); // optimization potential
}
@@ -732,6 +733,9 @@ QPlainTextEditPrivate::QPlainTextEditPrivate()
backgroundVisible = false;
centerOnScroll = false;
inDrag = false;
+#ifdef Q_WS_WIN
+ singleFingerPanEnabled = true;
+#endif
}
@@ -787,6 +791,9 @@ void QPlainTextEditPrivate::init(const QString &txt)
#ifndef QT_NO_CURSOR
viewport->setCursor(Qt::IBeamCursor);
#endif
+ originalOffsetY = 0;
+ panGesture = new QPanGesture(q);
+ QObject::connect(panGesture, SIGNAL(triggered()), q, SLOT(_q_gestureTriggered()));
}
void QPlainTextEditPrivate::_q_repaintContents(const QRectF &contentsRect)
@@ -2915,6 +2922,30 @@ QAbstractTextDocumentLayout::PaintContext QPlainTextEdit::getPaintContext() cons
(\a available is true) or unavailable (\a available is false).
*/
+void QPlainTextEditPrivate::_q_gestureTriggered()
+{
+ Q_Q(QPlainTextEdit);
+ QPanGesture *g = qobject_cast<QPanGesture*>(q->sender());
+ if (!g)
+ return;
+ QScrollBar *hBar = q->horizontalScrollBar();
+ QScrollBar *vBar = q->verticalScrollBar();
+ if (g->state() == Qt::GestureStarted)
+ originalOffsetY = vBar->value();
+ QSize totalOffset = g->totalOffset();
+ if (!totalOffset.isNull()) {
+ if (QApplication::isRightToLeft())
+ totalOffset.rwidth() *= -1;
+ // QPlainTextEdit scrolls by lines only in vertical direction
+ QFontMetrics fm(q->document()->defaultFont());
+ int lineHeight = fm.height();
+ int newX = hBar->value() - g->lastOffset().width();
+ int newY = originalOffsetY - totalOffset.height()/lineHeight;
+ hbar->setValue(newX);
+ vbar->setValue(newY);
+ }
+}
+
QT_END_NAMESPACE
#include "moc_qplaintextedit.cpp"
diff --git a/src/gui/widgets/qplaintextedit.h b/src/gui/widgets/qplaintextedit.h
index 2366a29..35bbc37 100644
--- a/src/gui/widgets/qplaintextedit.h
+++ b/src/gui/widgets/qplaintextedit.h
@@ -69,7 +69,7 @@ class QMimeData;
class Q_GUI_EXPORT QPlainTextEdit : public QAbstractScrollArea
{
Q_OBJECT
- Q_DECLARE_SCOPED_PRIVATE(QPlainTextEdit)
+ Q_DECLARE_PRIVATE(QPlainTextEdit)
Q_ENUMS(LineWrapMode)
Q_PROPERTY(bool tabChangesFocus READ tabChangesFocus WRITE setTabChangesFocus)
Q_PROPERTY(QString documentTitle READ documentTitle WRITE setDocumentTitle)
@@ -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;
};
@@ -277,7 +278,7 @@ class QPlainTextDocumentLayoutPrivate;
class Q_GUI_EXPORT QPlainTextDocumentLayout : public QAbstractTextDocumentLayout
{
Q_OBJECT
- Q_DECLARE_SCOPED_PRIVATE(QPlainTextDocumentLayout)
+ Q_DECLARE_PRIVATE(QPlainTextDocumentLayout)
Q_PROPERTY(int cursorWidth READ cursorWidth WRITE setCursorWidth)
public:
diff --git a/src/gui/widgets/qplaintextedit_p.h b/src/gui/widgets/qplaintextedit_p.h
index 851702d..739fd89 100644
--- a/src/gui/widgets/qplaintextedit_p.h
+++ b/src/gui/widgets/qplaintextedit_p.h
@@ -72,6 +72,7 @@ class QMimeData;
class QPlainTextEdit;
class ExtraArea;
+class QPanGesture;
class QPlainTextEditControl : public QTextControl
{
@@ -177,6 +178,10 @@ public:
void _q_cursorPositionChanged();
void _q_modificationChanged(bool);
+
+ void _q_gestureTriggered();
+ int originalOffsetY;
+ QPanGesture *panGesture;
};
QT_END_NAMESPACE
diff --git a/src/gui/widgets/qprintpreviewwidget.h b/src/gui/widgets/qprintpreviewwidget.h
index 240306f..d74bf93 100644
--- a/src/gui/widgets/qprintpreviewwidget.h
+++ b/src/gui/widgets/qprintpreviewwidget.h
@@ -58,7 +58,7 @@ class QPrintPreviewWidgetPrivate;
class Q_GUI_EXPORT QPrintPreviewWidget : public QWidget
{
Q_OBJECT
- Q_DECLARE_SCOPED_PRIVATE(QPrintPreviewWidget)
+ Q_DECLARE_PRIVATE(QPrintPreviewWidget)
public:
enum ViewMode {
diff --git a/src/gui/widgets/qprogressbar.cpp b/src/gui/widgets/qprogressbar.cpp
index ac3338b..7e40c0d 100644
--- a/src/gui/widgets/qprogressbar.cpp
+++ b/src/gui/widgets/qprogressbar.cpp
@@ -190,10 +190,11 @@ bool QProgressBarPrivate::repaintRequired() const
with setValue(). The progress bar can be rewound to the
beginning with reset().
- If minimum and maximum both are set to 0, the bar shows a busy indicator
- instead of a percentage of steps. This is useful, for example, when using
- QFtp or QHttp to download items when they are unable to determine the
- size of the item being downloaded.
+ If minimum and maximum both are set to 0, the bar shows a busy
+ indicator instead of a percentage of steps. This is useful, for
+ example, when using QFtp or QNetworkAccessManager to download
+ items when they are unable to determine the size of the item being
+ downloaded.
\table
\row \o \inlineimage macintosh-progressbar.png Screenshot of a Macintosh style progress bar
@@ -204,7 +205,7 @@ bool QProgressBarPrivate::repaintRequired() const
\o A progress bar shown in the Plastique widget style.
\endtable
- \sa QTimeLine, QProgressDialog, {fowler}{GUI Design Handbook: Progress Indicator}
+ \sa QProgressDialog, {fowler}{GUI Design Handbook: Progress Indicator}
*/
/*!
@@ -443,11 +444,11 @@ QSize QProgressBar::minimumSizeHint() const
QString QProgressBar::text() const
{
Q_D(const QProgressBar);
- if (d->maximum == 0 || d->value < d->minimum
+ if ((d->maximum == 0 && d->minimum == 0) || d->value < d->minimum
|| (d->value == INT_MIN && d->minimum == INT_MIN))
return QString();
- qint64 totalSteps = qint64(d->maximum) - qint64(d->minimum);
+ qint64 totalSteps = qint64(d->maximum) - d->minimum;
QString result = d->format;
result.replace(QLatin1String("%m"), QString::number(totalSteps));
@@ -461,7 +462,7 @@ QString QProgressBar::text() const
return result;
}
- int progress = int(((qreal(d->value) - qreal(d->minimum)) * 100.0) / totalSteps);
+ int progress = (qreal(d->value) - d->minimum) * 100.0 / totalSteps;
result.replace(QLatin1String("%p"), QString::number(progress));
return result;
}
diff --git a/src/gui/widgets/qprogressbar.h b/src/gui/widgets/qprogressbar.h
index de995b6..5ac6b85 100644
--- a/src/gui/widgets/qprogressbar.h
+++ b/src/gui/widgets/qprogressbar.h
@@ -117,7 +117,7 @@ protected:
void initStyleOption(QStyleOptionProgressBar *option) const;
private:
- Q_DECLARE_SCOPED_PRIVATE(QProgressBar)
+ Q_DECLARE_PRIVATE(QProgressBar)
Q_DISABLE_COPY(QProgressBar)
};
diff --git a/src/gui/widgets/qpushbutton.h b/src/gui/widgets/qpushbutton.h
index 1b4cb95..2264cc3 100644
--- a/src/gui/widgets/qpushbutton.h
+++ b/src/gui/widgets/qpushbutton.h
@@ -111,7 +111,7 @@ public:
private:
Q_DISABLE_COPY(QPushButton)
- Q_DECLARE_SCOPED_PRIVATE(QPushButton)
+ Q_DECLARE_PRIVATE(QPushButton)
#ifndef QT_NO_MENU
Q_PRIVATE_SLOT(d_func(), void _q_popupPressed())
#endif
diff --git a/src/gui/widgets/qradiobutton.h b/src/gui/widgets/qradiobutton.h
index d2eaa4d..e631bab 100644
--- a/src/gui/widgets/qradiobutton.h
+++ b/src/gui/widgets/qradiobutton.h
@@ -77,7 +77,7 @@ public:
#endif
private:
- Q_DECLARE_SCOPED_PRIVATE(QRadioButton)
+ Q_DECLARE_PRIVATE(QRadioButton)
Q_DISABLE_COPY(QRadioButton)
};
diff --git a/src/gui/widgets/qrubberband.h b/src/gui/widgets/qrubberband.h
index 629bc29..1e638fd 100644
--- a/src/gui/widgets/qrubberband.h
+++ b/src/gui/widgets/qrubberband.h
@@ -87,7 +87,7 @@ protected:
void initStyleOption(QStyleOptionRubberBand *option) const;
private:
- Q_DECLARE_SCOPED_PRIVATE(QRubberBand)
+ Q_DECLARE_PRIVATE(QRubberBand)
};
inline void QRubberBand::setGeometry(int ax, int ay, int aw, int ah)
diff --git a/src/gui/widgets/qscrollarea.h b/src/gui/widgets/qscrollarea.h
index d2179b8..d713e15 100644
--- a/src/gui/widgets/qscrollarea.h
+++ b/src/gui/widgets/qscrollarea.h
@@ -88,7 +88,7 @@ protected:
void scrollContentsBy(int dx, int dy);
private:
- Q_DECLARE_SCOPED_PRIVATE(QScrollArea)
+ Q_DECLARE_PRIVATE(QScrollArea)
Q_DISABLE_COPY(QScrollArea)
};
diff --git a/src/gui/widgets/qscrollbar.h b/src/gui/widgets/qscrollbar.h
index b9302b3..9d25359 100644
--- a/src/gui/widgets/qscrollbar.h
+++ b/src/gui/widgets/qscrollbar.h
@@ -92,7 +92,7 @@ private:
friend Q_GUI_EXPORT QStyleOptionSlider qt_qscrollbarStyleOption(QScrollBar *scrollBar);
Q_DISABLE_COPY(QScrollBar)
- Q_DECLARE_SCOPED_PRIVATE(QScrollBar)
+ Q_DECLARE_PRIVATE(QScrollBar)
};
#endif // QT_NO_SCROLLBAR
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/qsizegrip.h b/src/gui/widgets/qsizegrip.h
index 7e9e6ac..5a0fb3b 100644
--- a/src/gui/widgets/qsizegrip.h
+++ b/src/gui/widgets/qsizegrip.h
@@ -82,7 +82,7 @@ public:
#endif
private:
- Q_DECLARE_SCOPED_PRIVATE(QSizeGrip)
+ Q_DECLARE_PRIVATE(QSizeGrip)
Q_DISABLE_COPY(QSizeGrip)
Q_PRIVATE_SLOT(d_func(), void _q_showIfNotHidden())
};
diff --git a/src/gui/widgets/qslider.h b/src/gui/widgets/qslider.h
index 3ff3889..18c2603 100644
--- a/src/gui/widgets/qslider.h
+++ b/src/gui/widgets/qslider.h
@@ -122,7 +122,7 @@ private:
friend Q_GUI_EXPORT QStyleOptionSlider qt_qsliderStyleOption(QSlider *slider);
Q_DISABLE_COPY(QSlider)
- Q_DECLARE_SCOPED_PRIVATE(QSlider)
+ Q_DECLARE_PRIVATE(QSlider)
};
#endif // QT_NO_SLIDER
diff --git a/src/gui/widgets/qspinbox.cpp b/src/gui/widgets/qspinbox.cpp
index 9ec21d6..193b15c 100644
--- a/src/gui/widgets/qspinbox.cpp
+++ b/src/gui/widgets/qspinbox.cpp
@@ -50,6 +50,7 @@
#include <qdebug.h>
#include <math.h>
+#include <float.h>
QT_BEGIN_NAMESPACE
@@ -832,8 +833,8 @@ void QDoubleSpinBox::setRange(double minimum, double maximum)
Sets how many decimals the spinbox will use for displaying and
interpreting doubles.
- \warning The results might not be reliable with very high values
- for \a decimals.
+ \warning The maximum value for \a decimals is DBL_MAX_10_EXP +
+ DBL_DIG (ie. 323) because of the limitations of the double type.
Note: The maximum, minimum and value might change as a result of
changing this property.
@@ -849,7 +850,7 @@ int QDoubleSpinBox::decimals() const
void QDoubleSpinBox::setDecimals(int decimals)
{
Q_D(QDoubleSpinBox);
- d->decimals = qMax(0, decimals);
+ d->decimals = qBound(0, decimals, DBL_MAX_10_EXP + DBL_DIG);
setRange(minimum(), maximum()); // make sure values are rounded
setValue(value());
@@ -1214,7 +1215,7 @@ bool QDoubleSpinBoxPrivate::isIntermediateValue(const QString &str) const
return false;
}
if (doright) {
- QSBDEBUG("match %lld min_left %lld max_left %lld", match, min_left, max_left);
+ QSBDEBUG() << "match" << match << "min_left" << min_left << "max_left" << max_left;
if (!doleft) {
if (min_left == max_left) {
const bool ret = isIntermediateValueHelper(qAbs(left),
@@ -1481,7 +1482,7 @@ QString QDoubleSpinBoxPrivate::textFromValue(const QVariant &f) const
static bool isIntermediateValueHelper(qint64 num, qint64 min, qint64 max, qint64 *match)
{
- QSBDEBUG("%lld %lld %lld", num, min, max);
+ QSBDEBUG() << num << min << max;
if (num >= min && num <= max) {
if (match)
diff --git a/src/gui/widgets/qspinbox.h b/src/gui/widgets/qspinbox.h
index 96d7b96..a168528 100644
--- a/src/gui/widgets/qspinbox.h
+++ b/src/gui/widgets/qspinbox.h
@@ -119,7 +119,7 @@ Q_SIGNALS:
private:
Q_DISABLE_COPY(QSpinBox)
- Q_DECLARE_SCOPED_PRIVATE(QSpinBox)
+ Q_DECLARE_PRIVATE(QSpinBox)
};
class QDoubleSpinBoxPrivate;
@@ -176,7 +176,7 @@ Q_SIGNALS:
private:
Q_DISABLE_COPY(QDoubleSpinBox)
- Q_DECLARE_SCOPED_PRIVATE(QDoubleSpinBox)
+ Q_DECLARE_PRIVATE(QDoubleSpinBox)
};
#endif // QT_NO_SPINBOX
diff --git a/src/gui/widgets/qsplashscreen.h b/src/gui/widgets/qsplashscreen.h
index 23d4d34..d7c521c 100644
--- a/src/gui/widgets/qsplashscreen.h
+++ b/src/gui/widgets/qsplashscreen.h
@@ -87,7 +87,7 @@ protected:
private:
Q_DISABLE_COPY(QSplashScreen)
- Q_DECLARE_SCOPED_PRIVATE(QSplashScreen)
+ Q_DECLARE_PRIVATE(QSplashScreen)
};
#endif // QT_NO_SPLASHSCREEN
diff --git a/src/gui/widgets/qsplitter.h b/src/gui/widgets/qsplitter.h
index 5f16db2..ad5620e 100644
--- a/src/gui/widgets/qsplitter.h
+++ b/src/gui/widgets/qsplitter.h
@@ -142,7 +142,7 @@ public:
private:
Q_DISABLE_COPY(QSplitter)
- Q_DECLARE_SCOPED_PRIVATE(QSplitter)
+ Q_DECLARE_PRIVATE(QSplitter)
private:
friend class QSplitterHandle;
};
@@ -179,7 +179,7 @@ protected:
private:
Q_DISABLE_COPY(QSplitterHandle)
- Q_DECLARE_SCOPED_PRIVATE(QSplitterHandle)
+ Q_DECLARE_PRIVATE(QSplitterHandle)
};
#endif // QT_NO_SPLITTER
diff --git a/src/gui/widgets/qstackedwidget.h b/src/gui/widgets/qstackedwidget.h
index 6dd21bb..95d6d9f 100644
--- a/src/gui/widgets/qstackedwidget.h
+++ b/src/gui/widgets/qstackedwidget.h
@@ -88,7 +88,7 @@ protected:
private:
Q_DISABLE_COPY(QStackedWidget)
- Q_DECLARE_SCOPED_PRIVATE(QStackedWidget)
+ Q_DECLARE_PRIVATE(QStackedWidget)
};
#endif // QT_NO_STACKEDWIDGET
diff --git a/src/gui/widgets/qstatusbar.h b/src/gui/widgets/qstatusbar.h
index 28cb2a9..86d1cda 100644
--- a/src/gui/widgets/qstatusbar.h
+++ b/src/gui/widgets/qstatusbar.h
@@ -104,7 +104,7 @@ protected:
private:
Q_DISABLE_COPY(QStatusBar)
- Q_DECLARE_SCOPED_PRIVATE(QStatusBar)
+ Q_DECLARE_PRIVATE(QStatusBar)
};
#endif // QT_NO_STATUSBAR
diff --git a/src/gui/widgets/qtabbar.cpp b/src/gui/widgets/qtabbar.cpp
index 11cb6a1..6b027b1 100644
--- a/src/gui/widgets/qtabbar.cpp
+++ b/src/gui/widgets/qtabbar.cpp
@@ -87,13 +87,17 @@ void QTabBarPrivate::updateMacBorderMetrics()
// TODO: get metrics to preserve the bottom value
// TODO: test tab bar position
- // push the black line at the bottom of the menu bar down to the client are so we can paint over it
+ OSWindowRef window = qt_mac_window_for(q);
+
+ // push base line separator down to the client are so we can paint over it (Carbon)
metrics.top = (documentMode && q->isVisible()) ? 1 : 0;
metrics.bottom = 0;
metrics.left = 0;
metrics.right = 0;
-
- qt_mac_updateContentBorderMetricts(qt_mac_window_for(q), metrics);
+ qt_mac_updateContentBorderMetricts(window, metrics);
+
+ // hide the base line separator if the tabs have docuemnt mode enabled (Cocoa)
+ qt_mac_showBaseLineSeparator(window, !documentMode);
}
#endif
}
@@ -663,7 +667,7 @@ void QTabBarPrivate::refresh()
if (pressedIndex != -1
&& movable
&& QApplication::mouseButtons() == Qt::NoButton) {
- _q_moveTabFinished(pressedIndex);
+ moveTabFinished(pressedIndex);
if (!validIndex(pressedIndex))
pressedIndex = -1;
}
@@ -1662,26 +1666,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 +1690,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 +1716,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 +1784,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 +1823,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 +1870,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 23d914e..402f54b 100644
--- a/src/gui/widgets/qtabbar.h
+++ b/src/gui/widgets/qtabbar.h
@@ -212,11 +212,9 @@ Q_SIGNALS:
friend class QAccessibleTabBar;
private:
Q_DISABLE_COPY(QTabBar)
- Q_DECLARE_SCOPED_PRIVATE(QTabBar)
+ 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/qtabwidget.h b/src/gui/widgets/qtabwidget.h
index 138a612..10150af 100644
--- a/src/gui/widgets/qtabwidget.h
+++ b/src/gui/widgets/qtabwidget.h
@@ -234,7 +234,7 @@ Q_SIGNALS:
#endif // QT3_SUPPORT
private:
- Q_DECLARE_SCOPED_PRIVATE(QTabWidget)
+ Q_DECLARE_PRIVATE(QTabWidget)
Q_DISABLE_COPY(QTabWidget)
Q_PRIVATE_SLOT(d_func(), void _q_showTab(int))
Q_PRIVATE_SLOT(d_func(), void _q_removeTab(int))
diff --git a/src/gui/widgets/qtextbrowser.h b/src/gui/widgets/qtextbrowser.h
index b9a501f..d5bd956 100644
--- a/src/gui/widgets/qtextbrowser.h
+++ b/src/gui/widgets/qtextbrowser.h
@@ -125,7 +125,7 @@ public:
private:
Q_DISABLE_COPY(QTextBrowser)
- Q_DECLARE_SCOPED_PRIVATE(QTextBrowser)
+ Q_DECLARE_PRIVATE(QTextBrowser)
Q_PRIVATE_SLOT(d_func(), void _q_documentModified())
Q_PRIVATE_SLOT(d_func(), void _q_activateAnchor(const QString &))
Q_PRIVATE_SLOT(d_func(), void _q_highlightLink(const QString &))
diff --git a/src/gui/widgets/qtextedit.cpp b/src/gui/widgets/qtextedit.cpp
index 3bac94b..e5c4d4f 100644
--- a/src/gui/widgets/qtextedit.cpp
+++ b/src/gui/widgets/qtextedit.cpp
@@ -67,6 +67,8 @@
#include <qtexttable.h>
#include <qvariant.h>
+#include <qstandardgestures.h>
+
#include <qinputcontext.h>
#endif
@@ -116,6 +118,9 @@ QTextEditPrivate::QTextEditPrivate()
preferRichText = false;
showCursorOnInitialShow = true;
inDrag = false;
+#ifdef Q_WS_WIN
+ singleFingerPanEnabled = true;
+#endif
}
void QTextEditPrivate::createAutoBulletList()
@@ -183,6 +188,8 @@ void QTextEditPrivate::init(const QString &html)
#ifndef QT_NO_CURSOR
viewport->setCursor(Qt::IBeamCursor);
#endif
+ panGesture = new QPanGesture(q);
+ QObject::connect(panGesture, SIGNAL(triggered()), q, SLOT(_q_gestureTriggered()));
}
void QTextEditPrivate::_q_repaintContents(const QRectF &contentsRect)
@@ -2624,6 +2631,25 @@ void QTextEdit::ensureCursorVisible()
d->control->ensureCursorVisible();
}
+void QTextEditPrivate::_q_gestureTriggered()
+{
+ Q_Q(QTextEdit);
+ QPanGesture *g = qobject_cast<QPanGesture*>(q->sender());
+ if (!g)
+ return;
+ QScrollBar *hBar = q->horizontalScrollBar();
+ QScrollBar *vBar = q->verticalScrollBar();
+ QSize delta = g->lastOffset();
+ if (!delta.isNull()) {
+ if (QApplication::isRightToLeft())
+ delta.rwidth() *= -1;
+ int newX = hBar->value() - delta.width();
+ int newY = vBar->value() - delta.height();
+ hbar->setValue(newX);
+ vbar->setValue(newY);
+ }
+}
+
/*!
\enum QTextEdit::KeyboardAction
diff --git a/src/gui/widgets/qtextedit.h b/src/gui/widgets/qtextedit.h
index c1c6360..9e10e07 100644
--- a/src/gui/widgets/qtextedit.h
+++ b/src/gui/widgets/qtextedit.h
@@ -70,7 +70,7 @@ class QMimeData;
class Q_GUI_EXPORT QTextEdit : public QAbstractScrollArea
{
Q_OBJECT
- Q_DECLARE_SCOPED_PRIVATE(QTextEdit)
+ Q_DECLARE_PRIVATE(QTextEdit)
Q_FLAGS(AutoFormatting)
Q_ENUMS(LineWrapMode)
Q_PROPERTY(AutoFormatting autoFormatting READ autoFormatting WRITE setAutoFormatting)
@@ -414,6 +414,7 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_currentCharFormatChanged(const QTextCharFormat &))
Q_PRIVATE_SLOT(d_func(), void _q_adjustScrollbars())
Q_PRIVATE_SLOT(d_func(), void _q_ensureVisible(const QRectF &))
+ Q_PRIVATE_SLOT(d_func(), void _q_gestureTriggered())
friend class QTextEditControl;
friend class QTextDocument;
friend class QTextControl;
diff --git a/src/gui/widgets/qtextedit_p.h b/src/gui/widgets/qtextedit_p.h
index 75e7a35..cf87a86 100644
--- a/src/gui/widgets/qtextedit_p.h
+++ b/src/gui/widgets/qtextedit_p.h
@@ -70,7 +70,7 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_TEXTEDIT
class QMimeData;
-
+class QPanGesture;
class QTextEditPrivate : public QAbstractScrollAreaPrivate
{
Q_DECLARE_PUBLIC(QTextEdit)
@@ -130,6 +130,9 @@ public:
QString anchorToScrollToWhenVisible;
+ void _q_gestureTriggered();
+ QPanGesture *panGesture;
+
#ifdef QT_KEYPAD_NAVIGATION
QBasicTimer deleteAllTimer;
#endif
diff --git a/src/gui/widgets/qtoolbar.cpp b/src/gui/widgets/qtoolbar.cpp
index b635628..426c3e1 100644
--- a/src/gui/widgets/qtoolbar.cpp
+++ b/src/gui/widgets/qtoolbar.cpp
@@ -70,6 +70,8 @@
#include "qdebug.h"
+#define POPUP_TIMER_INTERVAL 500
+
QT_BEGIN_NAMESPACE
#ifdef Q_WS_MAC
@@ -87,14 +89,6 @@ static void qt_mac_updateToolBarButtonHint(QWidget *parentWidget)
void QToolBarPrivate::init()
{
Q_Q(QToolBar);
-
- waitForPopupTimer = new QTimer(q);
- waitForPopupTimer->setSingleShot(false);
- waitForPopupTimer->setInterval(500);
- QObject::connect(waitForPopupTimer, SIGNAL(timeout()), q, SLOT(_q_waitForPopup()));
-
- floatable = true;
- movable = true;
q->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed));
q->setBackgroundRole(QPalette::Button);
q->setAttribute(Qt::WA_Hover);
@@ -880,7 +874,7 @@ QAction *QToolBar::insertSeparator(QAction *before)
If you add a QToolButton with this method, the tools bar's
Qt::ToolButtonStyle will not be respected.
- Note: You should use QAction::setVisible() to change the
+ \note You should use QAction::setVisible() to change the
visibility of the widget. Using QWidget::setVisible(),
QWidget::show() and QWidget::hide() does not work.
@@ -1080,19 +1074,46 @@ static bool waitForPopup(QToolBar *tb, QWidget *popup)
return false;
}
+#if defined(Q_WS_MAC)
+static bool toolbarInUnifiedToolBar(QToolBar *toolbar)
+{
+ const QMainWindow *mainWindow = qobject_cast<const QMainWindow *>(toolbar->parentWidget());
+ return mainWindow && mainWindow->unifiedTitleAndToolBarOnMac()
+ && mainWindow->toolBarArea(toolbar) == Qt::TopToolBarArea;
+}
+#endif
+
/*! \reimp */
bool QToolBar::event(QEvent *event)
{
Q_D(QToolBar);
switch (event->type()) {
+ case QEvent::Timer:
+ if (d->waitForPopupTimer.timerId() == static_cast<QTimerEvent*>(event)->timerId()) {
+ QWidget *w = QApplication::activePopupWidget();
+ if (!waitForPopup(this, w)) {
+ d->waitForPopupTimer.stop();
+ if (!this->underMouse())
+ d->layout->setExpanded(false);
+ }
+ }
+ break;
case QEvent::Hide:
if (!isHidden())
break;
// fallthrough intended
case QEvent::Show:
d->toggleViewAction->setChecked(event->type() == QEvent::Show);
-#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)
+#if defined(Q_WS_MAC)
+ if (toolbarInUnifiedToolBar(this)) {
+ // I can static_cast because I did the qobject_cast in the if above, therefore
+ // we must have a QMainWindowLayout here.
+ QMainWindowLayout *mwLayout = static_cast<QMainWindowLayout *>(parentWidget()->layout());
+ mwLayout->fixSizeInUnifiedToolbar(this);
+ mwLayout->syncUnifiedToolbarVisibility();
+ }
+# if !defined(QT_MAC_USE_COCOA)
// Fall through
case QEvent::LayoutRequest: {
// There's currently no way to invalidate the size and let
@@ -1107,10 +1128,9 @@ bool QToolBar::event(QEvent *event)
}
if (needUpdate) {
- OSWindowRef windowRef = qt_mac_window_for(this);
- if (mainWindow->unifiedTitleAndToolBarOnMac()
- && mainWindow->toolBarArea(this) == Qt::TopToolBarArea
- && macWindowToolbarVisible(windowRef)) {
+ OSWindowRef windowRef = qt_mac_window_for(mainWindow);
+ if (toolbarInUnifiedToolBar(this)
+ && macWindowToolbarIsVisible(windowRef)) {
DisableScreenUpdates();
macWindowToolbarShow(this, false);
macWindowToolbarShow(this, true);
@@ -1122,7 +1142,8 @@ bool QToolBar::event(QEvent *event)
return earlyResult;
}
}
-#endif
+# endif // !QT_MAC_USE_COCOA
+#endif // Q_WS_MAC
break;
case QEvent::ParentChange:
d->layout->checkUsePopupMenu();
@@ -1141,6 +1162,10 @@ bool QToolBar::event(QEvent *event)
if (d->mouseReleaseEvent(static_cast<QMouseEvent*>(event)))
return true;
break;
+ case QEvent::HoverEnter:
+ case QEvent::HoverLeave:
+ // there's nothing special to do here and we don't want to update the whole widget
+ return true;
case QEvent::HoverMove: {
#ifndef QT_NO_CURSOR
QHoverEvent *e = static_cast<QHoverEvent*>(event);
@@ -1183,11 +1208,11 @@ bool QToolBar::event(QEvent *event)
QWidget *w = QApplication::activePopupWidget();
if (waitForPopup(this, w)) {
- d->waitForPopupTimer->start();
+ d->waitForPopupTimer.start(POPUP_TIMER_INTERVAL, this);
break;
}
- d->waitForPopupTimer->stop();
+ d->waitForPopupTimer.stop();
d->layout->setExpanded(false);
break;
}
@@ -1197,18 +1222,6 @@ bool QToolBar::event(QEvent *event)
return QWidget::event(event);
}
-void QToolBarPrivate::_q_waitForPopup()
-{
- Q_Q(QToolBar);
-
- QWidget *w = QApplication::activePopupWidget();
- if (!waitForPopup(q, w)) {
- waitForPopupTimer->stop();
- if (!q->underMouse())
- layout->setExpanded(false);
- }
-}
-
/*!
Returns a checkable action that can be used to show or hide this
toolbar.
diff --git a/src/gui/widgets/qtoolbar.h b/src/gui/widgets/qtoolbar.h
index 590a345..07502b3 100644
--- a/src/gui/widgets/qtoolbar.h
+++ b/src/gui/widgets/qtoolbar.h
@@ -162,12 +162,11 @@ public:
#endif
private:
- Q_DECLARE_SCOPED_PRIVATE(QToolBar)
+ Q_DECLARE_PRIVATE(QToolBar)
Q_DISABLE_COPY(QToolBar)
Q_PRIVATE_SLOT(d_func(), void _q_toggleView(bool))
Q_PRIVATE_SLOT(d_func(), void _q_updateIconSize(const QSize &))
Q_PRIVATE_SLOT(d_func(), void _q_updateToolButtonStyle(Qt::ToolButtonStyle))
- Q_PRIVATE_SLOT(d_func(), void _q_waitForPopup())
friend class QMainWindow;
friend class QMainWindowLayout;
diff --git a/src/gui/widgets/qtoolbar_p.h b/src/gui/widgets/qtoolbar_p.h
index b03c460..42ea97f 100644
--- a/src/gui/widgets/qtoolbar_p.h
+++ b/src/gui/widgets/qtoolbar_p.h
@@ -56,6 +56,7 @@
#include "qtoolbar.h"
#include "QtGui/qaction.h"
#include "private/qwidget_p.h"
+#include <QtCore/qbasictimer.h>
QT_BEGIN_NAMESPACE
@@ -70,7 +71,7 @@ class QToolBarPrivate : public QWidgetPrivate
public:
inline QToolBarPrivate()
- : explicitIconSize(false), explicitToolButtonStyle(false), movable(false),
+ : explicitIconSize(false), explicitToolButtonStyle(false), movable(true), floatable(true),
allowedAreas(Qt::AllToolBarAreas), orientation(Qt::Horizontal),
toolButtonStyle(Qt::ToolButtonIconOnly),
layout(0), state(0)
@@ -84,16 +85,15 @@ public:
void _q_toggleView(bool b);
void _q_updateIconSize(const QSize &sz);
void _q_updateToolButtonStyle(Qt::ToolButtonStyle style);
- void _q_waitForPopup();
bool explicitIconSize;
bool explicitToolButtonStyle;
bool movable;
+ bool floatable;
Qt::ToolBarAreas allowedAreas;
Qt::Orientation orientation;
Qt::ToolButtonStyle toolButtonStyle;
QSize iconSize;
- bool floatable;
QAction *toggleViewAction;
@@ -125,7 +125,7 @@ public:
void unplug(const QRect &r);
void plug(const QRect &r);
- QTimer *waitForPopupTimer;
+ QBasicTimer waitForPopupTimer;
};
#endif // QT_NO_TOOLBAR
diff --git a/src/gui/widgets/qtoolbararealayout.cpp b/src/gui/widgets/qtoolbararealayout.cpp
index db2afd6..b4a0ef0 100644
--- a/src/gui/widgets/qtoolbararealayout.cpp
+++ b/src/gui/widgets/qtoolbararealayout.cpp
@@ -156,21 +156,15 @@ void QToolBarAreaLayoutLine::fitLayout()
if (item.skip())
continue;
- QToolBarLayout *tblayout = qobject_cast<QToolBarLayout*>(item.widgetItem->widget()->layout());
- if (tblayout)
+ if (QToolBarLayout *tblayout = qobject_cast<QToolBarLayout*>(item.widgetItem->widget()->layout()))
tblayout->checkUsePopupMenu();
- int itemMin = pick(o, item.minimumSize());
- int itemHint = pick(o, item.sizeHint());
- //we ensure the extraspace is not too low
- item.size = qMax(item.size, itemHint);
- if (item.preferredSize > 0) {
- //preferredSize would be the default size
- item.size = item.preferredSize;
- }
+ const int itemMin = pick(o, item.minimumSize());
+ //preferredSize is the default if it is set, otherwise, we take the sizehint
+ item.size = item.preferredSize > 0 ? item.preferredSize : pick(o, item.sizeHint());
//the extraspace is the space above the item minimum sizehint
- int extraSpace = qMin(item.size - itemMin, extra);
+ const int extraSpace = qMin(item.size - itemMin, extra);
item.size = itemMin + extraSpace; //that is the real size
extra -= extraSpace;
@@ -932,7 +926,7 @@ void QToolBarAreaLayout::apply(bool animate)
if (visible && dock.o == Qt::Horizontal)
geo = QStyle::visualRect(dir, line.rect, geo);
- layout->widgetAnimator->animate(widget, geo, animate);
+ layout->widgetAnimator.animate(widget, geo, animate);
}
}
}
diff --git a/src/gui/widgets/qtoolbox.h b/src/gui/widgets/qtoolbox.h
index 242efa6..2c38967 100644
--- a/src/gui/widgets/qtoolbox.h
+++ b/src/gui/widgets/qtoolbox.h
@@ -124,7 +124,7 @@ public:
#endif
private:
- Q_DECLARE_SCOPED_PRIVATE(QToolBox)
+ Q_DECLARE_PRIVATE(QToolBox)
Q_DISABLE_COPY(QToolBox)
Q_PRIVATE_SLOT(d_func(), void _q_buttonClicked())
Q_PRIVATE_SLOT(d_func(), void _q_widgetDestroyed(QObject*))
diff --git a/src/gui/widgets/qtoolbutton.cpp b/src/gui/widgets/qtoolbutton.cpp
index 6dcbfec..2c85dc5 100644
--- a/src/gui/widgets/qtoolbutton.cpp
+++ b/src/gui/widgets/qtoolbutton.cpp
@@ -378,7 +378,17 @@ void QToolButton::initStyleOption(QStyleOptionToolButton *option) const
if (d->hasMenu())
option->features |= QStyleOptionToolButton::HasMenu;
#endif
- option->toolButtonStyle = d->toolButtonStyle;
+ if (d->toolButtonStyle == Qt::ToolButtonFollowStyle) {
+ option->toolButtonStyle = Qt::ToolButtonStyle(style()->styleHint(QStyle::SH_ToolButtonStyle, option, this));
+ } else
+ option->toolButtonStyle = d->toolButtonStyle;
+
+ if (option->toolButtonStyle == Qt::ToolButtonTextBesideIcon) {
+ // If the action is not prioritized, remove the text label to save space
+ if (d->defaultAction && d->defaultAction->priority() < QAction::NormalPriority)
+ option->toolButtonStyle = Qt::ToolButtonIconOnly;
+ }
+
if (d->icon.isNull() && d->arrowType == Qt::NoArrow && !forceNoText) {
if (!d->text.isEmpty())
option->toolButtonStyle = Qt::ToolButtonTextOnly;
@@ -476,6 +486,9 @@ QSize QToolButton::minimumSizeHint() const
The default is Qt::ToolButtonIconOnly.
+ To have the style of toolbuttons follow the system settings (as available
+ in GNOME and KDE desktop environments), set this property to Qt::ToolButtonFollowStyle.
+
QToolButton automatically connects this slot to the relevant
signal in the QMainWindow in which is resides.
*/
diff --git a/src/gui/widgets/qtoolbutton.h b/src/gui/widgets/qtoolbutton.h
index 7286096..1e7d678 100644
--- a/src/gui/widgets/qtoolbutton.h
+++ b/src/gui/widgets/qtoolbutton.h
@@ -127,7 +127,7 @@ protected:
private:
Q_DISABLE_COPY(QToolButton)
- Q_DECLARE_SCOPED_PRIVATE(QToolButton)
+ Q_DECLARE_PRIVATE(QToolButton)
#ifndef QT_NO_MENU
Q_PRIVATE_SLOT(d_func(), void _q_buttonPressed())
Q_PRIVATE_SLOT(d_func(), void _q_updateButtonDown())
diff --git a/src/gui/widgets/qvalidator.h b/src/gui/widgets/qvalidator.h
index a38b98f..5c27d1d 100644
--- a/src/gui/widgets/qvalidator.h
+++ b/src/gui/widgets/qvalidator.h
@@ -61,7 +61,7 @@ class Q_GUI_EXPORT QValidator : public QObject
{
Q_OBJECT
public:
- explicit QValidator(QObject * parent);
+ explicit QValidator(QObject * parent=0);
~QValidator();
enum State {
@@ -90,7 +90,7 @@ protected:
private:
Q_DISABLE_COPY(QValidator)
- Q_DECLARE_SCOPED_PRIVATE(QValidator)
+ Q_DECLARE_PRIVATE(QValidator)
};
class Q_GUI_EXPORT QIntValidator : public QValidator
@@ -100,7 +100,7 @@ class Q_GUI_EXPORT QIntValidator : public QValidator
Q_PROPERTY(int top READ top WRITE setTop)
public:
- explicit QIntValidator(QObject * parent);
+ explicit QIntValidator(QObject * parent=0);
QIntValidator(int bottom, int top, QObject * parent);
~QIntValidator();
@@ -168,7 +168,7 @@ public:
QObject * parent, const char *name);
#endif
private:
- Q_DECLARE_SCOPED_PRIVATE(QDoubleValidator)
+ Q_DECLARE_PRIVATE(QDoubleValidator)
Q_DISABLE_COPY(QDoubleValidator)
double b;
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 47b654e..3184140 100644
--- a/src/gui/widgets/qworkspace.cpp
+++ b/src/gui/widgets/qworkspace.cpp
@@ -110,11 +110,11 @@ bool QMDIControl::event(QEvent *event)
QStyle::SubControl ctrl = style()->hitTestComplexControl(QStyle::CC_MdiControls, &opt,
helpEvent->pos(), this);
if (ctrl == QStyle::SC_MdiCloseButton)
- QToolTip::showText(helpEvent->globalPos(), QWorkspace::tr("Close"));
+ QToolTip::showText(helpEvent->globalPos(), QWorkspace::tr("Close"), this);
else if (ctrl == QStyle::SC_MdiMinButton)
- QToolTip::showText(helpEvent->globalPos(), QWorkspace::tr("Minimize"));
+ QToolTip::showText(helpEvent->globalPos(), QWorkspace::tr("Minimize"), this);
else if (ctrl == QStyle::SC_MdiNormalButton)
- QToolTip::showText(helpEvent->globalPos(), QWorkspace::tr("Restore Down"));
+ QToolTip::showText(helpEvent->globalPos(), QWorkspace::tr("Restore Down"), this);
else
QToolTip::hideText();
#endif // QT_NO_TOOLTIP
@@ -228,7 +228,7 @@ void QMDIControl::paintEvent(QPaintEvent *)
class QWorkspaceTitleBar : public QWidget
{
Q_OBJECT
- Q_DECLARE_SCOPED_PRIVATE(QWorkspaceTitleBar)
+ Q_DECLARE_PRIVATE(QWorkspaceTitleBar)
Q_PROPERTY(bool autoRaise READ autoRaise WRITE setAutoRaise)
Q_PROPERTY(bool movable READ isMovable WRITE setMovable)
@@ -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/qworkspace.h b/src/gui/widgets/qworkspace.h
index 1a20d6c..8a64315 100644
--- a/src/gui/widgets/qworkspace.h
+++ b/src/gui/widgets/qworkspace.h
@@ -115,7 +115,7 @@ protected:
#endif
private:
- Q_DECLARE_SCOPED_PRIVATE(QWorkspace)
+ Q_DECLARE_PRIVATE(QWorkspace)
Q_DISABLE_COPY(QWorkspace)
Q_PRIVATE_SLOT(d_func(), void _q_normalizeActiveWindow())
Q_PRIVATE_SLOT(d_func(), void _q_minimizeActiveWindow())
diff --git a/src/gui/widgets/widgets.pri b/src/gui/widgets/widgets.pri
index cc03513..4567902 100644
--- a/src/gui/widgets/widgets.pri
+++ b/src/gui/widgets/widgets.pri
@@ -30,6 +30,7 @@ HEADERS += \
widgets/qlcdnumber.h \
widgets/qlineedit.h \
widgets/qlineedit_p.h \
+ widgets/qlinecontrol_p.h \
widgets/qmainwindow.h \
widgets/qmainwindowlayout_p.h \
widgets/qmdiarea.h \
@@ -101,7 +102,9 @@ SOURCES += \
widgets/qgroupbox.cpp \
widgets/qlabel.cpp \
widgets/qlcdnumber.cpp \
+ widgets/qlineedit_p.cpp \
widgets/qlineedit.cpp \
+ widgets/qlinecontrol.cpp \
widgets/qmainwindow.cpp \
widgets/qmainwindowlayout.cpp \
widgets/qmdiarea.cpp \