diff options
Diffstat (limited to 'src/gui/widgets')
41 files changed, 579 insertions, 266 deletions
diff --git a/src/gui/widgets/qabstractscrollarea_p.h b/src/gui/widgets/qabstractscrollarea_p.h index 7c72859..9a0d66f 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 Q_AUTOTEST_EXPORT QAbstractScrollAreaPrivate: public QFramePrivate +class Q_GUI_EXPORT QAbstractScrollAreaPrivate: public QFramePrivate { Q_DECLARE_PUBLIC(QAbstractScrollArea) diff --git a/src/gui/widgets/qabstractslider.cpp b/src/gui/widgets/qabstractslider.cpp index 2888490..522d472 100644 --- a/src/gui/widgets/qabstractslider.cpp +++ b/src/gui/widgets/qabstractslider.cpp @@ -712,7 +712,15 @@ bool QAbstractSliderPrivate::scrollByDelta(Qt::Orientation orientation, Qt::Keyb offset_accumulated = 0; offset_accumulated += stepsToScrollF; +#ifndef Q_WS_MAC + // Dont't scroll more than one page in any case: stepsToScroll = qBound(-pageStep, int(offset_accumulated), pageStep); +#else + // Native UI-elements on Mac can scroll hundreds of lines at a time as + // a result of acceleration. So keep the same behaviour in Qt, and + // dont restrict stepsToScroll to certain maximum (pageStep): + stepsToScroll = int(offset_accumulated); +#endif offset_accumulated -= int(offset_accumulated); if (stepsToScroll == 0) return false; diff --git a/src/gui/widgets/qabstractspinbox.cpp b/src/gui/widgets/qabstractspinbox.cpp index 4a6235c..7e2f20d 100644 --- a/src/gui/widgets/qabstractspinbox.cpp +++ b/src/gui/widgets/qabstractspinbox.cpp @@ -1248,8 +1248,11 @@ void QAbstractSpinBox::contextMenuEvent(QContextMenuEvent *event) #else Q_D(QAbstractSpinBox); - d->reset(); QPointer<QMenu> menu = d->edit->createStandardContextMenu(); + if (!menu) + return; + + d->reset(); QAction *selAll = new QAction(tr("&Select All"), menu); menu->insertAction(d->edit->d_func()->selectAllAction, diff --git a/src/gui/widgets/qcheckbox.cpp b/src/gui/widgets/qcheckbox.cpp index 4e0ff66..bc0900e 100644 --- a/src/gui/widgets/qcheckbox.cpp +++ b/src/gui/widgets/qcheckbox.cpp @@ -291,7 +291,7 @@ QSize QCheckBox::sizeHint() const QFontMetrics fm = fontMetrics(); QStyleOptionButton opt; initStyleOption(&opt); - QSize sz = style()->itemTextRect(fm, QRect(0, 0, 1, 1), Qt::TextShowMnemonic, false, + QSize sz = style()->itemTextRect(fm, QRect(), Qt::TextShowMnemonic, false, text()).size(); if (!opt.icon.isNull()) sz = QSize(sz.width() + opt.iconSize.width() + 4, qMax(sz.height(), opt.iconSize.height())); diff --git a/src/gui/widgets/qcocoamenu_mac.mm b/src/gui/widgets/qcocoamenu_mac.mm index a7e0b79..ce85919 100644 --- a/src/gui/widgets/qcocoamenu_mac.mm +++ b/src/gui/widgets/qcocoamenu_mac.mm @@ -46,6 +46,7 @@ #import <private/qcocoamenuloader_mac_p.h> #include <private/qt_cocoa_helpers_mac_p.h> #include <private/qapplication_p.h> +#include <private/qaction_p.h> #include <QtGui/QMenu> @@ -70,6 +71,7 @@ QT_USE_NAMESPACE self = [super init]; if (self) { qmenu = menu; + previousAction = 0; [self setAutoenablesItems:NO]; [self setDelegate:self]; } @@ -81,13 +83,20 @@ QT_USE_NAMESPACE Q_UNUSED(menu); if (!item) { - // ### According to the docs everything will be highlighted. Not sure what we should do in - // Qt, so just return. + if (previousAction) { + qt_mac_clear_status_text(previousAction); + previousAction = 0; + } return; } - if (QAction *action = reinterpret_cast<QAction *>([item tag])) + if (QAction *action = reinterpret_cast<QAction *>([item tag])) { + QMenu *qtmenu = static_cast<QT_MANGLE_NAMESPACE(QCocoaMenu) *>(menu)->qmenu; + previousAction = action; action->activate(QAction::Hover); + qt_mac_menu_emit_hovered(qtmenu, action); + action->showStatusText(0); // 0 widget -> action's parent + } } - (void)menuWillOpen:(NSMenu*)menu; @@ -100,9 +109,13 @@ QT_USE_NAMESPACE qt_mac_menu_collapseSeparators(menu, qtmenu->separatorsCollapsible()); } -- (void)menuWillClose:(NSMenu*)menu; +- (void)menuDidClose:(NSMenu*)menu; { qt_mac_emit_menuSignals(((QT_MANGLE_NAMESPACE(QCocoaMenu) *)menu)->qmenu, false); + if (previousAction) { + qt_mac_clear_status_text(previousAction); + previousAction = 0; + } } - (BOOL)hasShortcut:(NSMenu *)menu forKey:(NSString *)key forModifiers:(NSUInteger)modifier @@ -194,6 +207,18 @@ void qt_mac_emit_menuSignals(QMenu *menu, bool show) } qt_mac_menus_open_count += delta; } + +void qt_mac_clear_status_text(QAction *action) +{ + action->d_func()->showStatusText(0, QString()); +} + +void qt_mac_menu_emit_hovered(QMenu *menu, QAction *action) +{ + emit menu->hovered(action); +} + + QT_END_NAMESPACE #endif diff --git a/src/gui/widgets/qcocoamenu_mac_p.h b/src/gui/widgets/qcocoamenu_mac_p.h index 9f50c40..d6ac8c5 100644 --- a/src/gui/widgets/qcocoamenu_mac_p.h +++ b/src/gui/widgets/qcocoamenu_mac_p.h @@ -55,13 +55,14 @@ #import <Cocoa/Cocoa.h> QT_FORWARD_DECLARE_CLASS(QMenu) +QT_FORWARD_DECLARE_CLASS(QAction) #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5 @protocol NSMenuDelegate <NSObject> - (void)menu:(NSMenu*)menu willHighlightItem:(NSMenuItem*)item; - (void)menuWillOpen:(NSMenu*)menu; -- (void)menuWillClose:(NSMenu*)menu; +- (void)menuDidClose:(NSMenu*)menu; - (BOOL)hasShortcut:(NSMenu *)menu forKey:(NSString *)key forModifiers:(NSUInteger)modifier whichItem:(NSMenuItem**)outItem; @end @@ -71,6 +72,7 @@ QT_FORWARD_DECLARE_CLASS(QMenu) @interface QT_MANGLE_NAMESPACE(QCocoaMenu) : NSMenu <NSMenuDelegate> { QMenu *qmenu; + QAction *previousAction; } - (id)initWithQMenu:(QMenu*)menu; - (BOOL)menuHasKeyEquivalent:(NSMenu *)menu forEvent:(NSEvent *)event target:(id *)target action:(SEL *)action; diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp index 7d02e14..c16f18a 100644 --- a/src/gui/widgets/qcombobox.cpp +++ b/src/gui/widgets/qcombobox.cpp @@ -1276,7 +1276,8 @@ QComboBox::~QComboBox() By default, this property has a value of 10. - \note This property is ignored for non-editable comboboxes in Mac style. + \note This property is ignored for non-editable comboboxes in styles that returns + false for QStyle::SH_ComboBox_Popup such as the Mac style or the Gtk+ Style. */ int QComboBox::maxVisibleItems() const { @@ -2356,7 +2357,7 @@ void QComboBox::showPopup() toCheck.push(idx); #endif ++count; - if (!usePopup && count > d->maxVisibleItems) { + if (!usePopup && count >= d->maxVisibleItems) { toCheck.clear(); break; } diff --git a/src/gui/widgets/qcombobox.h b/src/gui/widgets/qcombobox.h index 9b19a66..fb9af9f 100644 --- a/src/gui/widgets/qcombobox.h +++ b/src/gui/widgets/qcombobox.h @@ -111,10 +111,10 @@ public: bool hasFrame() const; inline int findText(const QString &text, - Qt::MatchFlags flags = Qt::MatchExactly|Qt::MatchCaseSensitive) const + Qt::MatchFlags flags = static_cast<Qt::MatchFlags>(Qt::MatchExactly|Qt::MatchCaseSensitive)) const { return findData(text, Qt::DisplayRole, flags); } int findData(const QVariant &data, int role = Qt::UserRole, - Qt::MatchFlags flags = Qt::MatchExactly|Qt::MatchCaseSensitive) const; + Qt::MatchFlags flags = static_cast<Qt::MatchFlags>(Qt::MatchExactly|Qt::MatchCaseSensitive)) const; enum InsertPolicy { NoInsert, diff --git a/src/gui/widgets/qdatetimeedit.cpp b/src/gui/widgets/qdatetimeedit.cpp index 762db86..50fa9c9 100644 --- a/src/gui/widgets/qdatetimeedit.cpp +++ b/src/gui/widgets/qdatetimeedit.cpp @@ -1175,7 +1175,7 @@ void QDateTimeEdit::keyPressEvent(QKeyEvent *event) return; } } QAbstractSpinBox::keyPressEvent(event); - if (select && !(event->modifiers() & Qt::ShiftModifier) && !d->edit->hasSelectedText()) { + if (select && !d->edit->hasSelectedText()) { if (inserted && d->sectionAt(d->edit->cursorPosition()) == QDateTimeParser::NoSectionIndex) { QString str = d->displayText(); int pos = d->edit->cursorPosition(); diff --git a/src/gui/widgets/qdialogbuttonbox.cpp b/src/gui/widgets/qdialogbuttonbox.cpp index 6a0e363..cc74a53 100644 --- a/src/gui/widgets/qdialogbuttonbox.cpp +++ b/src/gui/widgets/qdialogbuttonbox.cpp @@ -103,7 +103,7 @@ QT_BEGIN_NAMESPACE You can mix and match normal buttons and standard buttons. Currently the buttons are laid out in the following way if the button box is horizontal: - \table 100% + \table \row \o \inlineimage buttonbox-gnomelayout-horizontal.png GnomeLayout Horizontal \o Button box laid out in horizontal GnomeLayout \row \o \inlineimage buttonbox-kdelayout-horizontal.png KdeLayout Horizontal @@ -116,25 +116,23 @@ QT_BEGIN_NAMESPACE The buttons are laid out the following way if the button box is vertical: - \table 100% + \table + \row \o GnomeLayout + \o KdeLayout + \o MacLayout + \o WinLayout \row \o \inlineimage buttonbox-gnomelayout-vertical.png GnomeLayout Vertical - \o Button box laid out in vertical GnomeLayout - \row \o \inlineimage buttonbox-kdelayout-vertical.png KdeLayout Vertical - \o Button box laid out in vertical KdeLayout - \row \o \inlineimage buttonbox-maclayout-vertical.png MacLayout Vertical - \o Button box laid out in vertical MacLayout - \row \o \inlineimage buttonbox-winlayout-vertical.png WinLayout Vertical - \o Button box laid out in vertical WinLayout + \o \inlineimage buttonbox-kdelayout-vertical.png KdeLayout Vertical + \o \inlineimage buttonbox-maclayout-vertical.png MacLayout Vertical + \o \inlineimage buttonbox-winlayout-vertical.png WinLayout Vertical \endtable Additionally, button boxes that contain only buttons with ActionRole or - HelpRole can be considered modeless and have an alternate look on the mac: + HelpRole can be considered modeless and have an alternate look on Mac OS X: - \table 100% - \row \o \inlineimage buttonbox-mac-modeless-horizontal.png Screenshot of modeless horizontal MacLayout - \o modeless horizontal MacLayout - \row \o \inlineimage buttonbox-mac-modeless-vertical.png Screenshot of modeless vertical MacLayout - \o modeless vertical MacLayout + \table + \row \o modeless horizontal MacLayout + \o \inlineimage buttonbox-mac-modeless-horizontal.png Screenshot of modeless horizontal MacLayout \endtable When a button is clicked in the button box, the clicked() signal is emitted diff --git a/src/gui/widgets/qdockarealayout.cpp b/src/gui/widgets/qdockarealayout.cpp index 794863b..806654c 100644 --- a/src/gui/widgets/qdockarealayout.cpp +++ b/src/gui/widgets/qdockarealayout.cpp @@ -220,15 +220,17 @@ static quintptr tabId(const QDockAreaLayoutItem &item) } #endif +static const int zero = 0; + QDockAreaLayoutInfo::QDockAreaLayoutInfo() - : sep(0), dockPos(QInternal::LeftDock), o(Qt::Horizontal), mainWindow(0) + : sep(&zero), dockPos(QInternal::LeftDock), o(Qt::Horizontal), mainWindow(0) #ifndef QT_NO_TABBAR , tabbed(false), tabBar(0), tabBarShape(QTabBar::RoundedSouth), tabBarVisible(false) #endif { } -QDockAreaLayoutInfo::QDockAreaLayoutInfo(int _sep, QInternal::DockPosition _dockPos, +QDockAreaLayoutInfo::QDockAreaLayoutInfo(const int *_sep, QInternal::DockPosition _dockPos, Qt::Orientation _o, int tbshape, QMainWindow *window) : sep(_sep), dockPos(_dockPos), o(_o), mainWindow(window) @@ -281,7 +283,7 @@ QSize QDockAreaLayoutInfo::minimumSize() const #endif { if (!first) - a += sep; + a += *sep; a += pick(o, min_size); } b = qMax(b, perp(o, min_size)); @@ -349,7 +351,7 @@ QSize QDockAreaLayoutInfo::maximumSize() const #endif { if (!first) - a += sep; + a += *sep; a += pick(o, max_size); } b = qMin(b, perp(o, max_size)); @@ -415,7 +417,7 @@ QSize QDockAreaLayoutInfo::sizeHint() const { if (previous && !gap && !(previous->flags & QDockAreaLayoutItem::GapItem) && !previous->hasFixedSize(o)) { - a += sep; + a += *sep; } a += gap ? item.size : pick(o, size_hint); } @@ -491,7 +493,7 @@ static int realMinSize(const QDockAreaLayoutInfo &info) min = pick(info.o, item.minimumSize()); if (!first) - result += info.sep; + result += *info.sep; result += min; first = false; @@ -516,7 +518,7 @@ static int realMaxSize(const QDockAreaLayoutInfo &info) max = pick(info.o, item.maximumSize()); if (!first) - result += info.sep; + result += *info.sep; result += max; if (result >= QWIDGETSIZE_MAX) @@ -555,7 +557,7 @@ void QDockAreaLayoutInfo::fitItems() if (!(previous->flags & QDockAreaLayoutItem::GapItem)) { QLayoutStruct &ls = layout_struct_list[j++]; ls.init(); - ls.minimumSize = ls.maximumSize = ls.sizeHint = previous->hasFixedSize(o) ? 0 : sep; + ls.minimumSize = ls.maximumSize = ls.sizeHint = previous->hasFixedSize(o) ? 0 : *sep; ls.empty = false; } } @@ -938,7 +940,7 @@ int QDockAreaLayoutInfo::separatorMove(int index, int delta) if (item.skip()) { ls.empty = true; } else { - const int separatorSpace = item.hasFixedSize(o) ? 0 : sep; + const int separatorSpace = item.hasFixedSize(o) ? 0 : *sep; ls.empty = false; ls.pos = item.pos; ls.size = item.size + separatorSpace; @@ -956,7 +958,7 @@ int QDockAreaLayoutInfo::separatorMove(int index, int delta) if (item.skip()) continue; QLayoutStruct &ls = list[i]; - const int separatorSpace = item.hasFixedSize(o) ? 0 : sep; + const int separatorSpace = item.hasFixedSize(o) ? 0 : *sep; item.size = ls.size - separatorSpace; item.pos = ls.pos; if (item.subinfo != 0) { @@ -1041,11 +1043,11 @@ QLayoutItem *QDockAreaLayoutInfo::plug(const QList<int> &path) int next = this->next(index); if (prev != -1 && !(item_list.at(prev).flags & QDockAreaLayoutItem::GapItem)) { - item.pos += sep; - item.size -= sep; + item.pos += *sep; + item.size -= *sep; } if (next != -1 && !(item_list.at(next).flags & QDockAreaLayoutItem::GapItem)) - item.size -= sep; + item.size -= *sep; QPoint pos; rpick(o, pos) = item.pos; @@ -1083,11 +1085,11 @@ QLayoutItem *QDockAreaLayoutInfo::unplug(const QList<int> &path) #endif { if (prev != -1 && !(item_list.at(prev).flags & QDockAreaLayoutItem::GapItem)) { - item.pos -= sep; - item.size += sep; + item.pos -= *sep; + item.size += *sep; } if (next != -1 && !(item_list.at(next).flags & QDockAreaLayoutItem::GapItem)) - item.size += sep; + item.size += *sep; } return item.widgetItem; @@ -1255,9 +1257,9 @@ bool QDockAreaLayoutInfo::insertGap(const QList<int> &path, QLayoutItem *dockWid QRect r = dockedGeometry(dockWidgetItem->widget()); gap_size = pick(o, r.size()); if (prev != -1 && !(item_list.at(prev).flags & QDockAreaLayoutItem::GapItem)) - sep_size += sep; + sep_size += *sep; if (next != -1 && !(item_list.at(next).flags & QDockAreaLayoutItem::GapItem)) - sep_size += sep; + sep_size += *sep; } if (gap_size + sep_size > space) gap_size = pick(o, gap_item.minimumSize()); @@ -1364,7 +1366,7 @@ QRect QDockAreaLayoutInfo::separatorRect(int index) const QPoint pos = rect.topLeft(); rpick(o, pos) = item.pos + item.size; QSize s = rect.size(); - rpick(o, s) = sep; + rpick(o, s) = *sep; return QRect(pos, s); } @@ -1413,7 +1415,7 @@ QList<int> QDockAreaLayoutInfo::findSeparator(const QPoint &_pos) const continue; QRect sepRect = separatorRect(i); - if (!sepRect.isNull() && sep == 1) + if (!sepRect.isNull() && *sep == 1) sepRect.adjust(-2, -2, 2, 2); //we also make sure we don't find a separator that's not there if (sepRect.contains(_pos) && !item.hasFixedSize(o)) { @@ -1560,7 +1562,7 @@ void QDockAreaLayoutInfo::apply(bool animate) } } #ifndef QT_NO_TABBAR - if (sep == 1) + if (*sep == 1) updateSeparatorWidgets(); #endif //QT_NO_TABBAR } @@ -1983,7 +1985,10 @@ bool QDockAreaLayoutInfo::restoreState(QDataStream &stream, QList<QDockWidget*> emit widget->dockLocationChanged(toDockWidgetArea(dockPos)); } } - + if (testing) { + //was it is not really added to the layout, we need to delete the object here + delete item.widgetItem; + } } } else if (nextMarker == SequenceMarker) { int dummy; @@ -2013,7 +2018,7 @@ bool QDockAreaLayoutInfo::restoreState(QDataStream &stream, QList<QDockWidget*> updateTabBar(); setCurrentTabId(tabId(item_list.at(index))); } - if (!testing && sep == 1) + if (!testing && *sep == 1) updateSeparatorWidgets(); #endif @@ -2276,13 +2281,13 @@ QDockAreaLayout::QDockAreaLayout(QMainWindow *win) : fallbackToSizeHints(true) const int tabShape = 0; #endif docks[QInternal::LeftDock] - = QDockAreaLayoutInfo(sep, QInternal::LeftDock, Qt::Vertical, tabShape, win); + = QDockAreaLayoutInfo(&sep, QInternal::LeftDock, Qt::Vertical, tabShape, win); docks[QInternal::RightDock] - = QDockAreaLayoutInfo(sep, QInternal::RightDock, Qt::Vertical, tabShape, win); + = QDockAreaLayoutInfo(&sep, QInternal::RightDock, Qt::Vertical, tabShape, win); docks[QInternal::TopDock] - = QDockAreaLayoutInfo(sep, QInternal::TopDock, Qt::Horizontal, tabShape, win); + = QDockAreaLayoutInfo(&sep, QInternal::TopDock, Qt::Horizontal, tabShape, win); docks[QInternal::BottomDock] - = QDockAreaLayoutInfo(sep, QInternal::BottomDock, Qt::Horizontal, tabShape, win); + = QDockAreaLayoutInfo(&sep, QInternal::BottomDock, Qt::Horizontal, tabShape, win); centralWidgetItem = 0; @@ -2994,8 +2999,7 @@ bool QDockAreaLayout::restoreDockWidget(QDockWidget *dockWidget) QRect r = constrainedRect(placeHolder->topLevelRect, desktop.screenGeometry(dockWidget)); dockWidget->d_func()->setWindowState(true, true, r); } - dockWidget->show(); -// dockWidget->setVisible(!placeHolder->hidden); + dockWidget->setVisible(!placeHolder->hidden); #ifdef Q_WS_X11 if (placeHolder->window) // gets rid of the X11BypassWindowManager window flag dockWidget->d_func()->setWindowState(true); @@ -3031,7 +3035,7 @@ void QDockAreaLayout::addDockWidget(QInternal::DockPosition pos, QDockWidget *do #else int tbshape = 0; #endif - QDockAreaLayoutInfo new_info(sep, pos, orientation, tbshape, mainWindow); + QDockAreaLayoutInfo new_info(&sep, pos, orientation, tbshape, mainWindow); new_info.item_list.append(new QDockAreaLayoutInfo(info)); new_info.item_list.append(dockWidgetItem); info = new_info; @@ -3327,6 +3331,12 @@ void QDockAreaLayout::keepSize(QDockWidget *w) item.flags |= QDockAreaLayoutItem::KeepSize; } +void QDockAreaLayout::styleChangedEvent() +{ + sep = mainWindow->style()->pixelMetric(QStyle::PM_DockWidgetSeparatorExtent, 0, mainWindow); + fitLayout(); +} + QT_END_NAMESPACE #endif // QT_NO_DOCKWIDGET diff --git a/src/gui/widgets/qdockarealayout_p.h b/src/gui/widgets/qdockarealayout_p.h index 0bc1aa9..0088f00 100644 --- a/src/gui/widgets/qdockarealayout_p.h +++ b/src/gui/widgets/qdockarealayout_p.h @@ -128,7 +128,7 @@ class Q_AUTOTEST_EXPORT QDockAreaLayoutInfo { public: QDockAreaLayoutInfo(); - QDockAreaLayoutInfo(int _sep, QInternal::DockPosition _dockPos, Qt::Orientation _o, + QDockAreaLayoutInfo(const int *_sep, QInternal::DockPosition _dockPos, Qt::Orientation _o, int tbhape, QMainWindow *window); QSize minimumSize() const; @@ -189,7 +189,7 @@ public: QMainWindowLayout *mainWindowLayout() const; - int sep; + const int *sep; mutable QVector<QWidget*> separatorWidgets; QInternal::DockPosition dockPos; Qt::Orientation o; @@ -300,6 +300,7 @@ public: QSet<QTabBar*> usedTabBars() const; QSet<QWidget*> usedSeparatorWidgets() const; #endif //QT_NO_TABBAR + void styleChangedEvent(); }; QT_END_NAMESPACE diff --git a/src/gui/widgets/qdockwidget.cpp b/src/gui/widgets/qdockwidget.cpp index fdace46..54189de 100644 --- a/src/gui/widgets/qdockwidget.cpp +++ b/src/gui/widgets/qdockwidget.cpp @@ -1010,7 +1010,7 @@ void QDockWidgetPrivate::setWindowState(bool floating, bool unplug, const QRect if (!floating && parent) { QMainWindowLayout *mwlayout = qobject_cast<QMainWindowLayout *>(q->parentWidget()->layout()); - if (!mwlayout || mwlayout->dockWidgetArea(q) == Qt::NoDockWidgetArea) + if (mwlayout && mwlayout->dockWidgetArea(q) == Qt::NoDockWidgetArea) return; // this dockwidget can't be redocked } diff --git a/src/gui/widgets/qfocusframe.cpp b/src/gui/widgets/qfocusframe.cpp index d9cd5bb..4f20bce0 100644 --- a/src/gui/widgets/qfocusframe.cpp +++ b/src/gui/widgets/qfocusframe.cpp @@ -53,11 +53,14 @@ class QFocusFramePrivate : public QWidgetPrivate { Q_DECLARE_PUBLIC(QFocusFrame) QWidget *widget; - + QWidget *frameParent; + bool showFrameAboveWidget; public: QFocusFramePrivate() { widget = 0; + frameParent = 0; sendChildEvents = false; + showFrameAboveWidget = false; } void updateSize(); void update(); @@ -66,10 +69,10 @@ public: void QFocusFramePrivate::update() { Q_Q(QFocusFrame); - q->setParent(widget->parentWidget()); + q->setParent(frameParent); updateSize(); if (q->parentWidget()->rect().intersects(q->geometry())) { - if (q->style()->styleHint(QStyle::SH_FocusFrame_AboveWidget, 0, q)) + if (showFrameAboveWidget) q->raise(); else q->stackUnder(widget); @@ -84,7 +87,10 @@ void QFocusFramePrivate::updateSize() Q_Q(QFocusFrame); int vmargin = q->style()->pixelMetric(QStyle::PM_FocusFrameVMargin), hmargin = q->style()->pixelMetric(QStyle::PM_FocusFrameHMargin); - QRect geom(widget->x()-hmargin, widget->y()-vmargin, + QPoint pos(widget->x(), widget->y()); + if (q->parentWidget() != widget->parentWidget()) + pos = widget->parentWidget()->mapTo(q->parentWidget(), pos); + QRect geom(pos.x()-hmargin, pos.y()-vmargin, widget->width()+(hmargin*2), widget->height()+(vmargin*2)); if(q->geometry() == geom) return; @@ -176,14 +182,52 @@ void QFocusFrame::setWidget(QWidget *widget) { Q_D(QFocusFrame); - if(widget == d->widget) - return; - if(d->widget) - d->widget->removeEventFilter(this); - if(widget && !widget->isWindow() && widget->parentWidget()->windowType() != Qt::SubWindow) { + if (style()->styleHint(QStyle::SH_FocusFrame_AboveWidget, 0, this)) + d->showFrameAboveWidget = true; + else + d->showFrameAboveWidget = false; + + if (widget == d->widget) + return; + if (d->widget) { + // Remove event filters from the widget hierarchy. + QWidget *p = d->widget; + do { + p->removeEventFilter(this); + if (!d->showFrameAboveWidget || p == d->frameParent) + break; + p = p->parentWidget(); + }while (p); + } + if (widget && !widget->isWindow() && widget->parentWidget()->windowType() != Qt::SubWindow) { d->widget = widget; - widget->installEventFilter(this); + d->widget->installEventFilter(this); + QWidget *p = widget->parentWidget(); + QWidget *prev = 0; + if (d->showFrameAboveWidget) { + // Find the right parent for the focus frame. + while (p) { + // Traverse the hirerarchy of the 'widget' for setting event filter. + // During this if come across toolbar or a top level, use that + // as the parent for the focus frame. If we find a scroll area + // use its viewport as the parent. + bool isScrollArea = false; + if (p->isWindow() || p->inherits("QToolBar") || (isScrollArea = p->inherits("QAbstractScrollArea"))) { + d->frameParent = p; + // The previous one in the hierarchy will be the viewport. + if (prev && isScrollArea) + d->frameParent = prev; + break; + } else { + p->installEventFilter(this); + prev = p; + p = p->parentWidget(); + } + } + } else { + d->frameParent = p; + } d->update(); } else { d->widget = 0; @@ -210,9 +254,15 @@ QFocusFrame::widget() const void QFocusFrame::paintEvent(QPaintEvent *) { + Q_D(QFocusFrame); QStylePainter p(this); QStyleOption option; initStyleOption(&option); + int vmargin = style()->pixelMetric(QStyle::PM_FocusFrameVMargin); + int hmargin = style()->pixelMetric(QStyle::PM_FocusFrameHMargin); + QWidgetPrivate *wd = qt_widget_private(d->widget); + QRect rect = wd->clipRect().adjusted(0, 0, hmargin*2, vmargin*2); + p.setClipRect(rect); p.drawControl(QStyle::CE_FocusFrame, option); } @@ -233,7 +283,13 @@ QFocusFrame::eventFilter(QObject *o, QEvent *e) hide(); break; case QEvent::ParentChange: - d->update(); + if (d->showFrameAboveWidget) { + QWidget *w = d->widget; + setWidget(0); + setWidget(w); + } else { + d->update(); + } break; case QEvent::Show: d->update(); @@ -254,6 +310,19 @@ QFocusFrame::eventFilter(QObject *o, QEvent *e) default: break; } + } else if (d->showFrameAboveWidget) { + // Handle changes in the parent widgets we are monitoring. + switch(e->type()) { + case QEvent::Move: + case QEvent::Resize: + d->updateSize(); + break; + case QEvent::ZOrderChange: + raise(); + break; + default: + break; + } } return false; } diff --git a/src/gui/widgets/qlabel.cpp b/src/gui/widgets/qlabel.cpp index 8428ad7..b81f04f 100644 --- a/src/gui/widgets/qlabel.cpp +++ b/src/gui/widgets/qlabel.cpp @@ -781,6 +781,95 @@ Qt::TextInteractionFlags QLabel::textInteractionFlags() const return d->textInteractionFlags; } +/*! + Selects text from position \a start and for \a length characters. + + \sa selectedText() + + \bold{Note:} The textInteractionFlags set on the label need to include + either TextSelectableByMouse or TextSelectableByKeyboard. + + \since 4.7 +*/ +void QLabel::setSelection(int start, int length) +{ + Q_D(QLabel); + if (d->control) { + d->ensureTextPopulated(); + QTextCursor cursor = d->control->textCursor(); + cursor.setPosition(start); + cursor.setPosition(start + length, QTextCursor::KeepAnchor); + d->control->setTextCursor(cursor); + } +} + +/*! + \property QLabel::hasSelectedText + \brief whether there is any text selected + + hasSelectedText() returns true if some or all of the text has been + selected by the user; otherwise returns false. + + By default, this property is false. + + \sa selectedText() + + \bold{Note:} The textInteractionFlags set on the label need to include + either TextSelectableByMouse or TextSelectableByKeyboard. + + \since 4.7 +*/ +bool QLabel::hasSelectedText() const +{ + Q_D(const QLabel); + if (d->control) + return d->control->textCursor().hasSelection(); + return false; +} + +/*! + \property QLabel::selectedText + \brief the selected text + + If there is no selected text this property's value is + an empty string. + + By default, this property contains an empty string. + + \sa hasSelectedText() + + \bold{Note:} The textInteractionFlags set on the label need to include + either TextSelectableByMouse or TextSelectableByKeyboard. + + \since 4.7 +*/ +QString QLabel::selectedText() const +{ + Q_D(const QLabel); + if (d->control) + return d->control->textCursor().selectedText(); + return QString(); +} + +/*! + selectionStart() returns the index of the first selected character in the + label or -1 if no text is selected. + + \sa selectedText() + + \bold{Note:} The textInteractionFlags set on the label need to include + either TextSelectableByMouse or TextSelectableByKeyboard. + + \since 4.7 +*/ +int QLabel::selectionStart() const +{ + Q_D(const QLabel); + if (d->control && d->control->textCursor().hasSelection()) + return d->control->textCursor().selectionStart(); + return -1; +} + /*!\reimp */ QSize QLabel::sizeHint() const @@ -862,8 +951,8 @@ void QLabel::contextMenuEvent(QContextMenuEvent *ev) return; } ev->accept(); - menu->exec(ev->globalPos()); - delete menu; + menu->setAttribute(Qt::WA_DeleteOnClose); + menu->popup(ev->globalPos()); #endif } diff --git a/src/gui/widgets/qlabel.h b/src/gui/widgets/qlabel.h index d916078..54babb1 100644 --- a/src/gui/widgets/qlabel.h +++ b/src/gui/widgets/qlabel.h @@ -65,6 +65,8 @@ class Q_GUI_EXPORT QLabel : public QFrame Q_PROPERTY(int indent READ indent WRITE setIndent) Q_PROPERTY(bool openExternalLinks READ openExternalLinks WRITE setOpenExternalLinks) Q_PROPERTY(Qt::TextInteractionFlags textInteractionFlags READ textInteractionFlags WRITE setTextInteractionFlags) + Q_PROPERTY(bool hasSelectedText READ hasSelectedText) + Q_PROPERTY(QString selectedText READ selectedText) public: explicit QLabel(QWidget *parent=0, Qt::WindowFlags f=0); @@ -111,6 +113,11 @@ public: void setTextInteractionFlags(Qt::TextInteractionFlags flags); Qt::TextInteractionFlags textInteractionFlags() const; + void setSelection(int, int); + bool hasSelectedText() const; + QString selectedText() const; + int selectionStart() const; + public Q_SLOTS: void setText(const QString &); void setPixmap(const QPixmap &); diff --git a/src/gui/widgets/qlabel_p.h b/src/gui/widgets/qlabel_p.h index 21eb128..fba7224 100644 --- a/src/gui/widgets/qlabel_p.h +++ b/src/gui/widgets/qlabel_p.h @@ -55,7 +55,7 @@ #include "qlabel.h" -#include "../text/qtextdocumentlayout_p.h" +#include "private/qtextdocumentlayout_p.h" #include "private/qtextcontrol_p.h" #include "qtextdocumentfragment.h" #include "qframe_p.h" diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp index 9ec0feb..8e715a9 100644 --- a/src/gui/widgets/qlinecontrol.cpp +++ b/src/gui/widgets/qlinecontrol.cpp @@ -136,9 +136,9 @@ void QLineControl::copy(QClipboard::Mode mode) const \sa insert() */ -void QLineControl::paste() +void QLineControl::paste(QClipboard::Mode clipboardMode) { - QString clip = QApplication::clipboard()->text(QClipboard::Clipboard); + QString clip = QApplication::clipboard()->text(clipboardMode); if (!clip.isEmpty() || hasSelectedText()) { separate(); //make it a separate undo/redo command insert(clip); @@ -1576,8 +1576,14 @@ void QLineControl::processKeyEvent(QKeyEvent* event) copy(); } else if (event == QKeySequence::Paste) { - if (!isReadOnly()) - paste(); + if (!isReadOnly()) { + QClipboard::Mode mode = QClipboard::Clipboard; +#ifdef Q_WS_X11 + if (event->modifiers() == (Qt::CTRL | Qt::SHIFT) && event->key() == Qt::Key_Insert) + mode = QClipboard::Selection; +#endif + paste(mode); + } } else if (event == QKeySequence::Cut) { if (!isReadOnly()) { diff --git a/src/gui/widgets/qlinecontrol_p.h b/src/gui/widgets/qlinecontrol_p.h index 3f1bc2c..dd82581 100644 --- a/src/gui/widgets/qlinecontrol_p.h +++ b/src/gui/widgets/qlinecontrol_p.h @@ -128,7 +128,7 @@ public: #ifndef QT_NO_CLIPBOARD void copy(QClipboard::Mode mode = QClipboard::Clipboard) const; - void paste(); + void paste(QClipboard::Mode mode = QClipboard::Clipboard); #endif int cursor() const; diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp index 2d2df92..817547c 100644 --- a/src/gui/widgets/qlineedit.cpp +++ b/src/gui/widgets/qlineedit.cpp @@ -383,8 +383,6 @@ void QLineEdit::setText(const QString& text) d->control->setText(text); } -// ### Qt 4.7: remove this #if guard -#if (QT_VERSION >= 0x407000) || defined(Q_WS_MAEMO_5) /*! \since 4.7 @@ -414,7 +412,6 @@ void QLineEdit::setPlaceholderText(const QString& placeholderText) update(); } } -#endif /*! \property QLineEdit::displayText @@ -542,11 +539,16 @@ void QLineEdit::setEchoMode(EchoMode mode) if (mode == (EchoMode)d->control->echoMode()) return; Qt::InputMethodHints imHints = inputMethodHints(); - if (mode == Password) { + if (mode == Password || mode == NoEcho) { imHints |= Qt::ImhHiddenText; } else { imHints &= ~Qt::ImhHiddenText; } + if (mode != Normal) { + imHints |= (Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText); + } else { + imHints &= ~(Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText); + } setInputMethodHints(imHints); d->control->setEchoMode(mode); update(); @@ -1637,12 +1639,8 @@ void QLineEdit::keyPressEvent(QKeyEvent *event) if (!hasEditFocus() && !(event->modifiers() & Qt::ControlModifier)) { if (!event->text().isEmpty() && event->text().at(0).isPrint() && !isReadOnly()) - { setEditFocus(true); -#ifndef Q_OS_SYMBIAN - clear(); -#endif - } else { + else { event->ignore(); return; } @@ -1698,12 +1696,8 @@ void QLineEdit::inputMethodEvent(QInputMethodEvent *e) // commit text as they focus out without interfering with focus if (QApplication::keypadNavigationEnabled() && hasFocus() && !hasEditFocus() - && !e->preeditString().isEmpty()) { + && !e->preeditString().isEmpty()) setEditFocus(true); -#ifndef Q_OS_SYMBIAN - selectAll(); // so text is replaced rather than appended to -#endif - } #endif d->control->processInputMethodEvent(e); @@ -2046,9 +2040,10 @@ void QLineEdit::dropEvent(QDropEvent* e) */ void QLineEdit::contextMenuEvent(QContextMenuEvent *event) { - QPointer<QMenu> menu = createStandardContextMenu(); - menu->exec(event->globalPos()); - delete menu; + if (QMenu *menu = createStandardContextMenu()) { + menu->setAttribute(Qt::WA_DeleteOnClose); + menu->popup(event->globalPos()); + } } #if defined(Q_WS_WIN) diff --git a/src/gui/widgets/qlineedit.h b/src/gui/widgets/qlineedit.h index fa04bfc..94e0dbe 100644 --- a/src/gui/widgets/qlineedit.h +++ b/src/gui/widgets/qlineedit.h @@ -83,10 +83,7 @@ class Q_GUI_EXPORT QLineEdit : public QWidget Q_PROPERTY(bool undoAvailable READ isUndoAvailable) Q_PROPERTY(bool redoAvailable READ isRedoAvailable) Q_PROPERTY(bool acceptableInput READ hasAcceptableInput) -// ### Qt 4.7: remove this #if guard -#if (QT_VERSION >= 0x407000) || defined(Q_WS_MAEMO_5) Q_PROPERTY(QString placeholderText READ placeholderText WRITE setPlaceholderText) -#endif public: explicit QLineEdit(QWidget* parent=0); @@ -102,11 +99,8 @@ public: QString displayText() const; -// ### Qt 4.7: remove this #if guard -#if (QT_VERSION >= 0x407000) || defined(Q_WS_MAEMO_5) QString placeholderText() const; void setPlaceholderText(const QString &); -#endif int maxLength() const; void setMaxLength(int); diff --git a/src/gui/widgets/qmainwindow.cpp b/src/gui/widgets/qmainwindow.cpp index 16a7c31..d2eda80 100644 --- a/src/gui/widgets/qmainwindow.cpp +++ b/src/gui/widgets/qmainwindow.cpp @@ -1374,6 +1374,7 @@ bool QMainWindow::event(QEvent *event) #endif // QT_NO_STATUSTIP case QEvent::StyleChange: + d->layout->layoutState.dockAreaLayout.styleChangedEvent(); if (!d->explicitIconSize) setIconSize(QSize()); break; @@ -1453,7 +1454,8 @@ void QMainWindow::setUnifiedTitleAndToolBarOnMac(bool set) return; // ### Disable the unified toolbar when using anything but the native graphics system. - if (windowSurface()) + // ### Disable when using alien widgets as well + if (windowSurface() || testAttribute(Qt::WA_NativeWindow) == false) return; d->useHIToolBar = set; @@ -1535,11 +1537,15 @@ void QMainWindow::contextMenuEvent(QContextMenuEvent *event) #ifndef QT_NO_MENU QMenu *popup = createPopupMenu(); - if (popup && !popup->isEmpty()) { - popup->exec(event->globalPos()); - event->accept(); + if (popup) { + if (!popup->isEmpty()) { + popup->setAttribute(Qt::WA_DeleteOnClose); + popup->popup(event->globalPos()); + event->accept(); + } else { + delete popup; + } } - delete popup; #endif } #endif // QT_NO_CONTEXTMENU diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index a9978f9..404d46e 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -85,9 +85,8 @@ QT_BEGIN_NAMESPACE -QPointer<QMenu> QMenuPrivate::mouseDown; -QBasicTimer QMenuPrivate::menuDelayTimer; -QBasicTimer QMenuPrivate::sloppyDelayTimer; +QMenu *QMenuPrivate::mouseDown = 0; +int QMenuPrivate::sloppyDelayTimer = 0; /* QMenu code */ // internal class used for the torn off popup @@ -261,9 +260,6 @@ void QMenuPrivate::updateActionRects() const icone = style->pixelMetric(QStyle::PM_SmallIconSize, &opt, q); const int fw = style->pixelMetric(QStyle::PM_MenuPanelWidth, &opt, q); const int deskFw = style->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, &opt, q); - - const int sfcMargin = style->sizeFromContents(QStyle::CT_Menu, &opt, QApplication::globalStrut(), q).width() - QApplication::globalStrut().width(); - const int min_column_width = q->minimumWidth() - (sfcMargin + leftmargin + rightmargin + 2 * (fw + hmargin)); const int tearoffHeight = tearoff ? style->pixelMetric(QStyle::PM_MenuTearoffHeight, &opt, q) : 0; //for compatability now - will have to refactor this away.. @@ -337,7 +333,7 @@ void QMenuPrivate::updateActionRects() const if (!sz.isEmpty()) { - max_column_width = qMax(min_column_width, qMax(max_column_width, sz.width())); + max_column_width = qMax(max_column_width, sz.width()); //wrapping if (!scroll && y+sz.height()+vmargin > dh - (deskFw * 2)) { @@ -351,6 +347,10 @@ void QMenuPrivate::updateActionRects() const } max_column_width += tabWidth; //finally add in the tab width + const int sfcMargin = style->sizeFromContents(QStyle::CT_Menu, &opt, QApplication::globalStrut(), q).width() - QApplication::globalStrut().width(); + const int min_column_width = q->minimumWidth() - (sfcMargin + leftmargin + rightmargin + 2 * (fw + hmargin)); + max_column_width = qMax(min_column_width, max_column_width); + //calculate position const int base_y = vmargin + fw + topmargin + @@ -487,8 +487,8 @@ void QMenuPrivate::popupAction(QAction *action, int delay, bool activateFirst) if (action && action->isEnabled()) { if (!delay) q->internalDelayedPopup(); - else - QMenuPrivate::menuDelayTimer.start(delay, q); + else if (!menuDelayTimer.isActive() && (!action->menu() || !action->menu()->isVisible())) + menuDelayTimer.start(delay, q); if (activateFirst && action->menu()) action->menu()->d_func()->setFirstActionActive(); } else if (QMenu *menu = activeMenu) { //hide the current item @@ -543,15 +543,6 @@ void QMenuPrivate::setCurrentAction(QAction *action, int popup, SelectionReason { Q_Q(QMenu); tearoffHighlighted = 0; - if (action == currentAction) { - if (!action || !action->menu() || action->menu() == activeMenu) { - if(QMenu *menu = qobject_cast<QMenu*>(causedPopup.widget)) { - if(causedPopup.action && menu->d_func()->activeMenu == q) - menu->d_func()->setCurrentAction(causedPopup.action, 0, reason, false); - } - } - return; - } if (currentAction) q->update(actionRect(currentAction)); @@ -565,6 +556,7 @@ void QMenuPrivate::setCurrentAction(QAction *action, int popup, SelectionReason #ifdef QT3_SUPPORT emitHighlighted = action; #endif + currentAction = action; if (action) { if (!action->isSeparator()) { @@ -2309,9 +2301,7 @@ void QMenu::mouseReleaseEvent(QMouseEvent *e) QAction *action = d->actionAt(e->pos()); if (action && action == d->currentAction) { - if (action->menu()) - action->menu()->d_func()->setFirstActionActive(); - else { + if (!action->menu()){ #if defined(Q_WS_WIN) //On Windows only context menus can be activated with the right button if (e->button() == Qt::LeftButton || d->topCausedWidget() == 0) @@ -2385,8 +2375,8 @@ QMenu::event(QEvent *e) } } break; case QEvent::ContextMenu: - if(QMenuPrivate::menuDelayTimer.isActive()) { - QMenuPrivate::menuDelayTimer.stop(); + if(d->menuDelayTimer.isActive()) { + d->menuDelayTimer.stop(); internalDelayedPopup(); } break; @@ -2819,7 +2809,7 @@ void QMenu::mouseMoveEvent(QMouseEvent *e) } if (d->sloppyRegion.contains(e->pos())) { d->sloppyAction = action; - QMenuPrivate::sloppyDelayTimer.start(style()->styleHint(QStyle::SH_Menu_SubMenuPopupDelay, 0, this)*6, this); + QMenuPrivate::sloppyDelayTimer = startTimer(style()->styleHint(QStyle::SH_Menu_SubMenuPopupDelay, 0, this)*6); } else { d->setCurrentAction(action, style()->styleHint(QStyle::SH_Menu_SubMenuPopupDelay, 0, this)); } @@ -2857,11 +2847,12 @@ QMenu::timerEvent(QTimerEvent *e) d->scrollMenu((QMenuPrivate::QMenuScroller::ScrollDirection)d->scroll->scrollDirection); if (d->scroll->scrollFlags == QMenuPrivate::QMenuScroller::ScrollNone) d->scroll->scrollTimer.stop(); - } else if(QMenuPrivate::menuDelayTimer.timerId() == e->timerId()) { - QMenuPrivate::menuDelayTimer.stop(); + } else if(d->menuDelayTimer.timerId() == e->timerId()) { + d->menuDelayTimer.stop(); internalDelayedPopup(); - } else if(QMenuPrivate::sloppyDelayTimer.timerId() == e->timerId()) { - QMenuPrivate::sloppyDelayTimer.stop(); + } else if(QMenuPrivate::sloppyDelayTimer == e->timerId()) { + killTimer(QMenuPrivate::sloppyDelayTimer); + QMenuPrivate::sloppyDelayTimer = 0; internalSetSloppyAction(); } else if(d->searchBufferTimer.timerId() == e->timerId()) { d->searchBuffer.clear(); diff --git a/src/gui/widgets/qmenu.h b/src/gui/widgets/qmenu.h index 47dff2b..a040afa 100644 --- a/src/gui/widgets/qmenu.h +++ b/src/gui/widgets/qmenu.h @@ -417,6 +417,7 @@ private: friend OSStatus qt_mac_menu_event(EventHandlerCallRef, EventRef, void *); friend bool qt_mac_activate_action(OSMenuRef, uint, QAction::ActionEvent, bool); friend void qt_mac_emit_menuSignals(QMenu *, bool); + friend void qt_mac_menu_emit_hovered(QMenu *menu, QAction *action); #endif }; diff --git a/src/gui/widgets/qmenu_mac.mm b/src/gui/widgets/qmenu_mac.mm index 7e4bbb5..43722a1 100644 --- a/src/gui/widgets/qmenu_mac.mm +++ b/src/gui/widgets/qmenu_mac.mm @@ -247,7 +247,7 @@ bool qt_mac_activate_action(MenuRef menu, uint command, QAction::ActionEvent act //now walk up firing for each "caused" widget (like in the platform independent menu) QWidget *caused = 0; - if (GetMenuItemProperty(menu, 0, kMenuCreatorQt, kMenuPropertyCausedQWidget, sizeof(caused), 0, &caused) == noErr) { + if (action_e == QAction::Hover && GetMenuItemProperty(menu, 0, kMenuCreatorQt, kMenuPropertyCausedQWidget, sizeof(caused), 0, &caused) == noErr) { MenuRef caused_menu = 0; if (QMenu *qmenu2 = qobject_cast<QMenu*>(caused)) caused_menu = qmenu2->macMenu(); @@ -260,25 +260,17 @@ bool qt_mac_activate_action(MenuRef menu, uint command, QAction::ActionEvent act QWidget *widget = 0; GetMenuItemProperty(caused_menu, 0, kMenuCreatorQt, kMenuPropertyQWidget, sizeof(widget), 0, &widget); if (QMenu *qmenu = qobject_cast<QMenu*>(widget)) { - if (action_e == QAction::Trigger) { - emit qmenu->triggered(action->action); - } else if (action_e == QAction::Hover) { - action->action->showStatusText(widget); - emit qmenu->hovered(action->action); - } + action->action->showStatusText(widget); + emit qmenu->hovered(action->action); } else if (QMenuBar *qmenubar = qobject_cast<QMenuBar*>(widget)) { - if (action_e == QAction::Trigger) { - emit qmenubar->triggered(action->action); - } else if (action_e == QAction::Hover) { - action->action->showStatusText(widget); - emit qmenubar->hovered(action->action); - } + action->action->showStatusText(widget); + emit qmenubar->hovered(action->action); break; //nothing more.. } //walk up if (GetMenuItemProperty(caused_menu, 0, kMenuCreatorQt, kMenuPropertyCausedQWidget, - sizeof(caused), 0, &caused) != noErr) + sizeof(caused), 0, &caused) != noErr) break; if (QMenu *qmenu2 = qobject_cast<QMenu*>(caused)) caused_menu = qmenu2->macMenu(); @@ -649,7 +641,7 @@ static NSMenuItem *createNSMenuItem(const QString &title) NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:qt_mac_QStringToNSString(title) action:@selector(qtDispatcherToQAction:) keyEquivalent:@""]; - [item setTarget:getMenuLoader()]; + [item setTarget:nil]; return item; } #endif @@ -749,32 +741,6 @@ bool qt_mac_menubar_is_open() return qt_mac_menus_open_count > 0; } -void qt_mac_clear_menubar() -{ - if (QApplication::testAttribute(Qt::AA_MacPluginApplication)) - return; - -#ifndef QT_MAC_USE_COCOA - MenuRef clear_menu = 0; - if (CreateNewMenu(0, 0, &clear_menu) == noErr) { - SetRootMenu(clear_menu); - ReleaseMenu(clear_menu); - } else { - qWarning("QMenu: Internal error at %s:%d", __FILE__, __LINE__); - } - ClearMenuBar(); - qt_mac_command_set_enabled(0, kHICommandPreferences, false); - InvalMenuBar(); -#else - QMacCocoaAutoReleasePool pool; - QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader(); - NSMenu *menu = [loader menu]; - [loader ensureAppMenuInMenu:menu]; - [NSApp setMainMenu:menu]; -#endif -} - - QMacMenuAction::~QMacMenuAction() { #ifdef QT_MAC_USE_COCOA @@ -958,14 +924,27 @@ static QString qt_mac_menu_merge_text(QMacMenuAction *action) else if (action->command == kHICommandQuit) ret = QMenuBar::tr("Quit %1").arg(qAppName()); #else - else if (action->menuItem == [loader aboutMenuItem]) - ret = QMenuBar::tr("About %1").arg(qAppName()); - else if (action->menuItem == [loader aboutQtMenuItem]) - ret = QMenuBar::tr("About Qt"); - else if (action->menuItem == [loader preferencesMenuItem]) - ret = QMenuBar::tr("Preferences"); - else if (action->menuItem == [loader quitMenuItem]) - ret = QMenuBar::tr("Quit %1").arg(qAppName()); + else if (action->menuItem == [loader aboutMenuItem]) { + if (action->action->text() == QString("About %1").arg(qAppName())) + ret = QMenuBar::tr("About %1").arg(qAppName()); + else + ret = action->action->text(); + } else if (action->menuItem == [loader aboutQtMenuItem]) { + if (action->action->text() == QString("About Qt")) + ret = QMenuBar::tr("About Qt"); + else + ret = action->action->text(); + } else if (action->menuItem == [loader preferencesMenuItem]) { + if (action->action->text() == QString("Preferences")) + ret = QMenuBar::tr("Preferences"); + else + ret = action->action->text(); + } else if (action->menuItem == [loader quitMenuItem]) { + if (action->action->text() == QString("Quit %1").arg(qAppName())) + ret = QMenuBar::tr("About %1").arg(qAppName()); + else + ret = action->action->text(); + } #endif return ret; } @@ -1130,7 +1109,7 @@ QMenuPrivate::QMacMenuPrivate::addAction(QMacMenuAction *action, QMacMenuAction action->menu = merge; [cmd retain]; [cmd setAction:@selector(qtDispatcherToQAction:)]; - [cmd setTarget:getMenuLoader()]; + [cmd setTarget:nil]; [action->menuItem release]; action->menuItem = cmd; QMenuMergeList *list = QMenuPrivate::mergeMenuItemsHash.value(merge); @@ -1936,43 +1915,53 @@ static bool qt_mac_is_ancestor(QWidget* possibleAncestor, QWidget *child) Returns true if the entries of menuBar should be disabled, based on the modality type of modalWidget. */ -static bool qt_mac_should_disable_menu(QMenuBar *menuBar, QWidget *modalWidget) +static bool qt_mac_should_disable_menu(QMenuBar *menuBar) { - if (modalWidget == 0 || menuBar == 0) + QWidget *modalWidget = qApp->activeModalWidget(); + if (!modalWidget) return false; - // If there is an application modal window on - // screen, the entries of the menubar should be disabled: + if (menuBar && menuBar == menubars()->value(modalWidget)) + // The menu bar is owned by the modal widget. + // In that case we should enable it: + return false; + + // When there is an application modal window on screen, the entries of + // the menubar should be disabled. The exception in Qt is that if the + // modal window is the only window on screen, then we enable the menu bar. QWidget *w = modalWidget; + QWidgetList topLevelWidgets = QApplication::topLevelWidgets(); while (w) { - if (w->isVisible() && w->windowModality() == Qt::ApplicationModal) - return true; + if (w->isVisible() && w->windowModality() == Qt::ApplicationModal) { + for (int i=0; i<topLevelWidgets.size(); ++i) { + QWidget *top = topLevelWidgets.at(i); + if (w != top && top->isVisible()) { + // INVARIANT: we found another visible window + // on screen other than our modalWidget. We therefore + // disable the menu bar to follow normal modality logic: + return true; + } + } + // INVARIANT: We have only one window on screen that happends + // to be application modal. We choose to enable the menu bar + // in that case to e.g. enable the quit menu item. + return false; + } w = w->parentWidget(); } // INVARIANT: modalWidget is window modal. Disable menu entries - // if the menu bar belongs to an ancestor of modalWidget: - return qt_mac_is_ancestor(menuBar->parentWidget(), modalWidget); + // if the menu bar belongs to an ancestor of modalWidget. If menuBar + // is nil, we understand it as the default menu bar set by the nib: + return menuBar ? qt_mac_is_ancestor(menuBar->parentWidget(), modalWidget) : false; } -/*! - \internal - - This function will update the current menu bar and set it as the - active menu bar in the Menu Manager. - - \warning This function is not portable. - - \sa QMenu::macMenu(), QMenuBar::macMenu() -*/ -bool QMenuBar::macUpdateMenuBar() +static QWidget *findWindowThatShouldDisplayMenubar() { - cancelAllMenuTracking(); - QMenuBar *mb = 0; - //find a menu bar QWidget *w = qApp->activeWindow(); - if (!w) { + // We have no active window on screen. Try to + // find a window from the list of top levels: QWidgetList tlws = QApplication::topLevelWidgets(); for(int i = 0; i < tlws.size(); ++i) { QWidget *tlw = tlws.at(i); @@ -1983,6 +1972,12 @@ bool QMenuBar::macUpdateMenuBar() } } } + return w; +} + +static QMenuBar *findMenubarForWindow(QWidget *w) +{ + QMenuBar *mb = 0; if (w) { mb = menubars()->value(w); #ifndef QT_NO_MAINWINDOW @@ -1996,11 +1991,77 @@ bool QMenuBar::macUpdateMenuBar() while(w && !mb) mb = menubars()->value((w = w->parentWidget())); } - if (!mb) + + if (!mb) { + // We could not find a menu bar for the window. Lets + // check if we have a global (parentless) menu bar instead: mb = fallback; - //now set it + } + + return mb; +} + +void qt_mac_clear_menubar() +{ + if (QApplication::testAttribute(Qt::AA_MacPluginApplication)) + return; + +#ifndef QT_MAC_USE_COCOA + MenuRef clear_menu = 0; + if (CreateNewMenu(0, 0, &clear_menu) == noErr) { + SetRootMenu(clear_menu); + ReleaseMenu(clear_menu); + } else { + qWarning("QMenu: Internal error at %s:%d", __FILE__, __LINE__); + } + ClearMenuBar(); + qt_mac_command_set_enabled(0, kHICommandPreferences, false); + InvalMenuBar(); +#else + QMacCocoaAutoReleasePool pool; + QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader(); + NSMenu *menu = [loader menu]; + [loader ensureAppMenuInMenu:menu]; + [NSApp setMainMenu:menu]; + const bool modal = qt_mac_should_disable_menu(0); + if (qt_mac_current_menubar.qmenubar || modal != qt_mac_current_menubar.modal) + qt_mac_set_modal_state(menu, modal); + qt_mac_current_menubar.qmenubar = 0; + qt_mac_current_menubar.modal = modal; +#endif +} + +/*! + \internal + + This function will update the current menu bar and set it as the + active menu bar in the Menu Manager. + + \warning This function is not portable. + + \sa QMenu::macMenu(), QMenuBar::macMenu() +*/ +bool QMenuBar::macUpdateMenuBar() +{ +#ifdef QT_MAC_USE_COCOA + QMacCocoaAutoReleasePool pool; + if (!qt_cocoaPostMessage(getMenuLoader(), @selector(qtUpdateMenubar))) + return QMenuBarPrivate::macUpdateMenuBarImmediatly(); + return true; +#else + return QMenuBarPrivate::macUpdateMenuBarImmediatly(); +#endif +} + +bool QMenuBarPrivate::macUpdateMenuBarImmediatly() +{ bool ret = false; + cancelAllMenuTracking(); + QWidget *w = findWindowThatShouldDisplayMenubar(); + QMenuBar *mb = findMenubarForWindow(w); + if (mb && mb->isNativeMenuBar()) { + bool modal = QApplicationPrivate::modalState(); #ifdef QT_MAC_USE_COCOA QMacCocoaAutoReleasePool pool; #endif @@ -2030,16 +2091,18 @@ bool QMenuBar::macUpdateMenuBar() } } #endif - QWidget *modalWidget = qApp->activeModalWidget(); - if (mb != menubars()->value(modalWidget)) { - qt_mac_set_modal_state(menu, qt_mac_should_disable_menu(mb, modalWidget)); - } + // Check if menu is modally shaddowed and should be disabled: + modal = qt_mac_should_disable_menu(mb); + if (mb != qt_mac_current_menubar.qmenubar || modal != qt_mac_current_menubar.modal) + qt_mac_set_modal_state(menu, modal); } qt_mac_current_menubar.qmenubar = mb; - qt_mac_current_menubar.modal = QApplicationPrivate::modalState(); + qt_mac_current_menubar.modal = modal; ret = true; } else if (qt_mac_current_menubar.qmenubar && qt_mac_current_menubar.qmenubar->isNativeMenuBar()) { - const bool modal = QApplicationPrivate::modalState(); + // INVARIANT: The currently active menu bar (if any) is not native. But we do have a + // native menu bar from before. So we need to decide whether or not is should be enabled: + const bool modal = qt_mac_should_disable_menu(qt_mac_current_menubar.qmenubar); if (modal != qt_mac_current_menubar.modal) { ret = true; if (OSMenuRef menu = qt_mac_current_menubar.qmenubar->macMenu()) { @@ -2051,16 +2114,15 @@ bool QMenuBar::macUpdateMenuBar() [NSApp setMainMenu:menu]; syncMenuBarItemsVisiblity(qt_mac_current_menubar.qmenubar->d_func()->mac_menubar); #endif - QWidget *modalWidget = qApp->activeModalWidget(); - if (qt_mac_current_menubar.qmenubar != menubars()->value(modalWidget)) { - qt_mac_set_modal_state(menu, qt_mac_should_disable_menu(mb, modalWidget)); - } + qt_mac_set_modal_state(menu, modal); } qt_mac_current_menubar.modal = modal; } } - if(!ret) + + if (!ret) { qt_mac_clear_menubar(); + } return ret; } @@ -2131,3 +2193,4 @@ static OSMenuRef qt_mac_create_menu(QWidget *w) QT_END_NAMESPACE + diff --git a/src/gui/widgets/qmenu_p.h b/src/gui/widgets/qmenu_p.h index 495872c..39cbbd8 100644 --- a/src/gui/widgets/qmenu_p.h +++ b/src/gui/widgets/qmenu_p.h @@ -202,7 +202,7 @@ public: bool activationRecursionGuard; //selection - static QPointer<QMenu> mouseDown; + static QMenu *mouseDown; QPoint mousePopupPos; uint hasHadMouse : 1; uint aboutToHide : 1; @@ -212,7 +212,7 @@ public: QAction *selectAction; QAction *cancelAction; #endif - static QBasicTimer menuDelayTimer; + QBasicTimer menuDelayTimer; enum SelectionReason { SelectedFromKeyboard, SelectedFromElsewhere @@ -272,7 +272,7 @@ public: mutable bool hasCheckableItems; //sloppy selection - static QBasicTimer sloppyDelayTimer; + static int sloppyDelayTimer; mutable QAction *sloppyAction; QRegion sloppyRegion; diff --git a/src/gui/widgets/qmenu_symbian.cpp b/src/gui/widgets/qmenu_symbian.cpp index 7224768..4a9cfed 100644 --- a/src/gui/widgets/qmenu_symbian.cpp +++ b/src/gui/widgets/qmenu_symbian.cpp @@ -48,7 +48,7 @@ #include <private/qapplication_p.h> #include <private/qmenu_p.h> #include <private/qmenubar_p.h> -#include <qt_s60_p.h> +#include <private/qt_s60_p.h> #include <QtCore/qlibrary.h> #ifdef Q_WS_S60 diff --git a/src/gui/widgets/qmenubar_p.h b/src/gui/widgets/qmenubar_p.h index e4db6ce..82070fe 100644 --- a/src/gui/widgets/qmenubar_p.h +++ b/src/gui/widgets/qmenubar_p.h @@ -196,6 +196,7 @@ public: return 0; } } *mac_menubar; + static bool macUpdateMenuBarImmediatly(); bool macWidgetHasNativeMenubar(QWidget *widget); void macCreateMenuBar(QWidget *); void macDestroyMenuBar(); diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp index ab598d9..ef9fac3 100644 --- a/src/gui/widgets/qplaintextedit.cpp +++ b/src/gui/widgets/qplaintextedit.cpp @@ -911,6 +911,7 @@ void QPlainTextEditPrivate::pageUpDown(QTextCursor::MoveOperation op, QTextCurso setTopBlock(block.blockNumber(), line); if (moveCursor) { + cursor.setVisualNavigation(true); // move using movePosition to keep the cursor's x lastY += verticalOffset(); bool moved = false; @@ -1319,6 +1320,26 @@ QTextCursor QPlainTextEdit::textCursor() const return d->control->textCursor(); } +/*! + Returns the reference of the anchor at position \a pos, or an + empty string if no anchor exists at that point. + + \since 4.7 + */ +QString QPlainTextEdit::anchorAt(const QPoint &pos) const +{ + Q_D(const QPlainTextEdit); + int cursorPos = d->control->hitTest(pos + QPoint(d->horizontalOffset(), + d->verticalOffset()), + Qt::ExactHit); + if (cursorPos < 0) + return QString(); + + QTextDocumentPrivate *pieceTable = document()->docHandle(); + QTextDocumentPrivate::FragmentIterator it = pieceTable->find(cursorPos); + QTextCharFormat fmt = pieceTable->formatCollection()->charFormat(it->format); + return fmt.anchorHref(); +} /*! Undoes the last operation. @@ -2393,7 +2414,7 @@ void QPlainTextEdit::setReadOnly(bool ro) then the focus policy is also automatically set to Qt::ClickFocus. The default value depends on whether the QPlainTextEdit is read-only - or editable, and whether it is a QTextBrowser or not. + or editable. */ void QPlainTextEdit::setTextInteractionFlags(Qt::TextInteractionFlags flags) diff --git a/src/gui/widgets/qplaintextedit.h b/src/gui/widgets/qplaintextedit.h index 15cf0967..106ae6d 100644 --- a/src/gui/widgets/qplaintextedit.h +++ b/src/gui/widgets/qplaintextedit.h @@ -159,6 +159,8 @@ public: QRect cursorRect(const QTextCursor &cursor) const; QRect cursorRect() const; + QString anchorAt(const QPoint &pos) const; + bool overwriteMode() const; void setOverwriteMode(bool overwrite); diff --git a/src/gui/widgets/qradiobutton.cpp b/src/gui/widgets/qradiobutton.cpp index d73ff2f..20b6c720 100644 --- a/src/gui/widgets/qradiobutton.cpp +++ b/src/gui/widgets/qradiobutton.cpp @@ -195,7 +195,7 @@ QSize QRadioButton::sizeHint() const ensurePolished(); QStyleOptionButton opt; initStyleOption(&opt); - QSize sz = style()->itemTextRect(fontMetrics(), QRect(0, 0, 1, 1), Qt::TextShowMnemonic, + QSize sz = style()->itemTextRect(fontMetrics(), QRect(), Qt::TextShowMnemonic, false, text()).size(); if (!opt.icon.isNull()) sz = QSize(sz.width() + opt.iconSize.width() + 4, qMax(sz.height(), opt.iconSize.height())); diff --git a/src/gui/widgets/qscrollbar.cpp b/src/gui/widgets/qscrollbar.cpp index 4eff260..c0eeb2f 100644 --- a/src/gui/widgets/qscrollbar.cpp +++ b/src/gui/widgets/qscrollbar.cpp @@ -523,6 +523,7 @@ bool QScrollBar::event(QEvent *event) break; #ifndef QT_NO_WHEELEVENT case QEvent::Wheel: { + event->ignore(); // override wheel event without adding virtual function override QWheelEvent *ev = static_cast<QWheelEvent *>(event); int delta = ev->delta(); diff --git a/src/gui/widgets/qsplitter.cpp b/src/gui/widgets/qsplitter.cpp index 965094e..597b28b 100644 --- a/src/gui/widgets/qsplitter.cpp +++ b/src/gui/widgets/qsplitter.cpp @@ -1276,7 +1276,6 @@ void QSplitter::childEvent(QChildEvent *c) if (!c->child()->isWidgetType()) return; QWidget *w = static_cast<QWidget*>(c->child()); - if (c->added() && !d->blockChildAdd && !w->isWindow() && !d->findWidget(w)) { d->insertWidget_helper(d->list.count(), w, false); } else if (c->polished() && !d->blockChildAdd) { @@ -1306,25 +1305,23 @@ void QSplitter::setRubberBand(int pos) Q_D(QSplitter); if (pos < 0) { if (d->rubberBand) - QTimer::singleShot(0, d->rubberBand, SLOT(deleteLater())); + d->rubberBand->deleteLater(); return; } QRect r = contentsRect(); const int rBord = 3; // customizable? int hw = handleWidth(); if (!d->rubberBand) { - d->rubberBand = new QRubberBand(QRubberBand::Line); + QBoolBlocker b(d->blockChildAdd); + d->rubberBand = new QRubberBand(QRubberBand::Line, this); // For accessibility to identify this special widget. d->rubberBand->setObjectName(QLatin1String("qt_rubberband")); } - if (d->orient == Qt::Horizontal) - d->rubberBand->setGeometry(QRect(QPoint(pos + hw / 2 - rBord, r.y()), - QSize(2 * rBord, r.height())).translated(mapToGlobal(QPoint()))); - else - d->rubberBand->setGeometry(QRect(QPoint(r.x(), pos + hw / 2 - rBord), - QSize(r.width(), 2 * rBord)).translated(mapToGlobal(QPoint()))); - if (!d->rubberBand->isVisible()) - d->rubberBand->show(); + + const QRect newGeom = d->orient == Qt::Horizontal ? QRect(QPoint(pos + hw / 2 - rBord, r.y()), QSize(2 * rBord, r.height())) + : QRect(QPoint(r.x(), pos + hw / 2 - rBord), QSize(r.width(), 2 * rBord)); + d->rubberBand->setGeometry(newGeom); + d->rubberBand->show(); } /*! @@ -1555,16 +1552,14 @@ QSize QSplitter::sizeHint() const ensurePolished(); int l = 0; int t = 0; - QObjectList childList = children(); - for (int i = 0; i < childList.size(); ++i) { - if (QWidget *w = qobject_cast<QWidget *>(childList.at(i))) { - if (w->isHidden()) - continue; - QSize s = w->sizeHint(); - if (s.isValid()) { - l += d->pick(s); - t = qMax(t, d->trans(s)); - } + for (int i = 0; i < d->list.size(); ++i) { + QWidget *w = d->list.at(i)->widget; + if (w->isHidden()) + continue; + QSize s = w->sizeHint(); + if (s.isValid()) { + l += d->pick(s); + t = qMax(t, d->trans(s)); } } return orientation() == Qt::Horizontal ? QSize(l, t) : QSize(t, l); diff --git a/src/gui/widgets/qtabbar.cpp b/src/gui/widgets/qtabbar.cpp index 22e8255..7559311 100644 --- a/src/gui/widgets/qtabbar.cpp +++ b/src/gui/widgets/qtabbar.cpp @@ -1947,7 +1947,8 @@ void QTabBar::changeEvent(QEvent *event) { Q_D(QTabBar); if (event->type() == QEvent::StyleChange) { - d->elideMode = Qt::TextElideMode(style()->styleHint(QStyle::SH_TabBar_ElideMode, 0, this)); + if (!d->elideModeSetByUser) + d->elideMode = Qt::TextElideMode(style()->styleHint(QStyle::SH_TabBar_ElideMode, 0, this)); if (!d->useScrollButtonsSetByUser) d->useScrollButtons = !style()->styleHint(QStyle::SH_TabBar_PreferNoArrows, 0, this); d->refresh(); @@ -1980,6 +1981,7 @@ void QTabBar::setElideMode(Qt::TextElideMode mode) { Q_D(QTabBar); d->elideMode = mode; + d->elideModeSetByUser = true; d->refresh(); } diff --git a/src/gui/widgets/qtabbar_p.h b/src/gui/widgets/qtabbar_p.h index 7588035..83636e6 100644 --- a/src/gui/widgets/qtabbar_p.h +++ b/src/gui/widgets/qtabbar_p.h @@ -75,7 +75,7 @@ class QTabBarPrivate : public QWidgetPrivate public: QTabBarPrivate() :currentIndex(-1), pressedIndex(-1), shape(QTabBar::RoundedNorth), layoutDirty(false), - drawBase(true), scrollOffset(0), useScrollButtonsSetByUser(false) , expanding(true), closeButtonOnTabs(false), + drawBase(true), scrollOffset(0), elideModeSetByUser(false), useScrollButtonsSetByUser(false), expanding(true), closeButtonOnTabs(false), selectionBehaviorOnRemove(QTabBar::SelectRightTab), paintWithOffsets(true), movable(false), dragInProgress(false), documentMode(false), movingTab(0) #ifdef Q_WS_MAC @@ -186,6 +186,7 @@ public: void makeVisible(int index); QSize iconSize; Qt::TextElideMode elideMode; + bool elideModeSetByUser; bool useScrollButtons; bool useScrollButtonsSetByUser; diff --git a/src/gui/widgets/qtextedit.cpp b/src/gui/widgets/qtextedit.cpp index b6886b4..4541730 100644 --- a/src/gui/widgets/qtextedit.cpp +++ b/src/gui/widgets/qtextedit.cpp @@ -1212,12 +1212,9 @@ void QTextEdit::keyPressEvent(QKeyEvent *e) default: if (QApplication::keypadNavigationEnabled()) { if (!hasEditFocus() && !(e->modifiers() & Qt::ControlModifier)) { - if (e->text()[0].isPrint()) { + if (e->text()[0].isPrint()) setEditFocus(true); -#ifndef Q_OS_SYMBIAN - clear(); -#endif - } else { + else { e->ignore(); return; } @@ -1677,12 +1674,8 @@ void QTextEdit::inputMethodEvent(QInputMethodEvent *e) #ifdef QT_KEYPAD_NAVIGATION if (d->control->textInteractionFlags() & Qt::TextEditable && QApplication::keypadNavigationEnabled() - && !hasEditFocus()) { + && !hasEditFocus()) setEditFocus(true); -#ifndef Q_OS_SYMBIAN - selectAll(); // so text is replaced rather than appended to -#endif - } #endif d->sendControlEvent(e); ensureCursorVisible(); diff --git a/src/gui/widgets/qtoolbar.cpp b/src/gui/widgets/qtoolbar.cpp index 8beda55..7ed27ea 100644 --- a/src/gui/widgets/qtoolbar.cpp +++ b/src/gui/widgets/qtoolbar.cpp @@ -533,6 +533,14 @@ void QToolBarPrivate::plug(const QRect &r) /*! + \fn void QToolBar::visibilityChanged(bool visible) + \since 4.7 + + This signal is emitted when the toolbar becomes \a visible (or + invisible). This happens when the widget is hidden or shown. +*/ + +/*! Constructs a QToolBar with the given \a parent. */ QToolBar::QToolBar(QWidget *parent) @@ -1122,6 +1130,7 @@ bool QToolBar::event(QEvent *event) // fallthrough intended case QEvent::Show: d->toggleViewAction->setChecked(event->type() == QEvent::Show); + emit visibilityChanged(event->type() == QEvent::Show); #if defined(Q_WS_MAC) if (toolbarInUnifiedToolBar(this)) { // I can static_cast because I did the qobject_cast in the if above, therefore diff --git a/src/gui/widgets/qtoolbar.h b/src/gui/widgets/qtoolbar.h index 90f20dd..b733477 100644 --- a/src/gui/widgets/qtoolbar.h +++ b/src/gui/widgets/qtoolbar.h @@ -143,6 +143,7 @@ Q_SIGNALS: void iconSizeChanged(const QSize &iconSize); void toolButtonStyleChanged(Qt::ToolButtonStyle toolButtonStyle); void topLevelChanged(bool topLevel); + void visibilityChanged(bool visible); protected: void actionEvent(QActionEvent *event); diff --git a/src/gui/widgets/qvalidator.cpp b/src/gui/widgets/qvalidator.cpp index a5276d3..0b5cc5a 100644 --- a/src/gui/widgets/qvalidator.cpp +++ b/src/gui/widgets/qvalidator.cpp @@ -400,8 +400,10 @@ QValidator::State QIntValidator::validate(QString & input, int&) const qlonglong entered = QLocalePrivate::bytearrayToLongLong(buff.constData(), 10, &ok, &overflow); if (overflow || !ok) return Invalid; - if (entered >= b && entered <= t) - return Acceptable; + if (entered >= b && entered <= t) { + locale().toInt(input, &ok); + return ok ? Acceptable : Intermediate; + } if (entered >= 0) { // the -entered < b condition is necessary to allow people to type @@ -412,6 +414,20 @@ QValidator::State QIntValidator::validate(QString & input, int&) const } } +/*! \reimp */ +void QIntValidator::fixup(QString &input) const +{ + QByteArray buff; + if (!locale().d()->validateChars(input, QLocalePrivate::IntegerMode, &buff)) { + QLocale cl(QLocale::C); + if (!cl.d()->validateChars(input, QLocalePrivate::IntegerMode, &buff)) + return; + } + bool ok, overflow; + qlonglong entered = QLocalePrivate::bytearrayToLongLong(buff.constData(), 10, &ok, &overflow); + if (ok && !overflow) + input = locale().toString(entered); +} /*! Sets the range of the validator to only accept integers between \a diff --git a/src/gui/widgets/qvalidator.h b/src/gui/widgets/qvalidator.h index 30afbd6..63734ca 100644 --- a/src/gui/widgets/qvalidator.h +++ b/src/gui/widgets/qvalidator.h @@ -105,6 +105,7 @@ public: ~QIntValidator(); QValidator::State validate(QString &, int &) const; + void fixup(QString &input) const; void setBottom(int); void setTop(int); @@ -136,10 +137,11 @@ class Q_GUI_EXPORT QDoubleValidator : public QValidator Q_PROPERTY(double bottom READ bottom WRITE setBottom) Q_PROPERTY(double top READ top WRITE setTop) Q_PROPERTY(int decimals READ decimals WRITE setDecimals) + Q_ENUMS(Notation) Q_PROPERTY(Notation notation READ notation WRITE setNotation) public: - explicit QDoubleValidator(QObject * parent); + explicit QDoubleValidator(QObject * parent = 0); QDoubleValidator(double bottom, double top, int decimals, QObject * parent); ~QDoubleValidator(); @@ -183,7 +185,7 @@ class Q_GUI_EXPORT QRegExpValidator : public QValidator Q_PROPERTY(QRegExp regExp READ regExp WRITE setRegExp) public: - explicit QRegExpValidator(QObject *parent); + explicit QRegExpValidator(QObject *parent = 0); QRegExpValidator(const QRegExp& rx, QObject *parent); ~QRegExpValidator(); diff --git a/src/gui/widgets/widgets.pri b/src/gui/widgets/widgets.pri index 6883dd8..937b8d6 100644 --- a/src/gui/widgets/widgets.pri +++ b/src/gui/widgets/widgets.pri @@ -164,6 +164,6 @@ wince*: { !static: QMAKE_WRITE_DEFAULT_RC = 1 } -symbian*: { +symbian: { SOURCES += widgets/qmenu_symbian.cpp } |