From 53fa52bb604ab28ee37aba26e155486e94c66dec Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 27 Aug 2013 14:50:59 +0200 Subject: TabView: fix dynamic tab handling Task-number: QTBUG-33162 Change-Id: I873b37bd157230f80237fd40f3e5149fbd0207ca Reviewed-by: Volker Krause Reviewed-by: Jens Bache-Wiig --- src/controls/TabView.qml | 35 +++++++++++++++++++++----------- tests/auto/controls/data/tst_tabview.qml | 22 ++++++++++++++++++++ 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/src/controls/TabView.qml b/src/controls/TabView.qml index 6319d72c..cd8a023a 100644 --- a/src/controls/TabView.qml +++ b/src/controls/TabView.qml @@ -95,12 +95,14 @@ FocusScope { Returns the newly added tab. */ function insertTab(index, title, component) { - var tab = tabcomp.createObject(stack) + var tab = tabcomp.createObject() tab.sourceComponent = component - tab.parent = stack tab.title = title - tab.__inserted = true + // insert at appropriate index first, then set the parent to + // avoid onChildrenChanged appending it to the end of the list __tabs.insert(index, {tab: tab}) + tab.__inserted = true + tab.parent = stack __setOpacities() return tab } @@ -203,8 +205,17 @@ FocusScope { property int frameWidth property string style + property bool completed: false - Component.onCompleted: addTabs(stack.children) + Component.onCompleted: { + addTabs(stack.children) + completed = true + } + + onChildrenChanged: { + if (completed) + stack.addTabs(stack.children) + } function addTabs(tabs) { var tabAdded = false @@ -212,12 +223,11 @@ FocusScope { var tab = tabs[i] if (!tab.__inserted && tab.Accessible.role === Accessible.LayeredPane) { tab.__inserted = true - if (tab.parent === root) { - tab.parent = stack - // a tab added dynamically by Component::createObject() and passing the - // tab view as a parent should also get automatically removed when destructed + // reparent tabs created dynamically by createObject(tabView) + tab.parent = stack + // a dynamically added tab should also get automatically removed when destructed + if (completed) tab.Component.onDestruction.connect(stack.onDynamicTabDestroyed.bind(tab)) - } __tabs.append({tab: tab}) tabAdded = true } @@ -227,9 +237,10 @@ FocusScope { } function onDynamicTabDestroyed() { - for (var i = 0; i < stack.children.length; ++i) { - if (this === stack.children[i]) { - root.removeTab(i) + for (var i = 0; i < __tabs.count; ++i) { + if (__tabs.get(i).tab === this) { + __tabs.remove(i, 1) + __setOpacities() break } } diff --git a/tests/auto/controls/data/tst_tabview.qml b/tests/auto/controls/data/tst_tabview.qml index 8093ebc3..708f0383 100644 --- a/tests/auto/controls/data/tst_tabview.qml +++ b/tests/auto/controls/data/tst_tabview.qml @@ -223,6 +223,28 @@ TestCase { tabView.destroy() } + function test_dynamicModel() { + var test_tabView = ' \ + import QtQuick 2.1; \ + import QtQuick.Controls 1.0; \ + TabView { \ + id: tabView; \ + property alias repeater: repeater; \ + Repeater { id: repeater; Tab { } } \ + } ' + + var tabView = Qt.createQmlObject(test_tabView, testCase, '') + compare(tabView.count, 0) + + tabView.repeater.model = 4 + compare(tabView.count, 4) + + tabView.repeater.model = 0 + compare(tabView.count, 0) + + tabView.destroy() + } + function test_mousePressOnTabBar() { var test_tabView = 'import QtQuick 2.1; \ import QtQuick.Controls 1.0; \ -- cgit v1.2.1 From 9548940ced977afe6949121ae106154320f6a0b1 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Wed, 4 Sep 2013 17:35:35 +0200 Subject: Menu: Fix popup closing when moving mouse to submenu Task-number: QTBUG-32673 Change-Id: I1a083f6d7b231b1e3d60012306faf5ad4c573f5e Reviewed-by: Jens Bache-Wiig --- src/controls/Menu.qml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/controls/Menu.qml b/src/controls/Menu.qml index e89099db..6c9f8fd2 100644 --- a/src/controls/Menu.qml +++ b/src/controls/Menu.qml @@ -258,7 +258,15 @@ MenuPrivate { if (!currentItem || !currentItem.contains(Qt.point(pos.x - currentItem.x, pos.y - currentItem.y))) { if (currentItem && !pressed && currentItem.isSubmenu) currentItem.closeSubMenu() - currentItem = column.childAt(pos.x, pos.y) + var itemUnderMouse = column.childAt(pos.x, pos.y) + if (itemUnderMouse) { + currentItem = itemUnderMouse + } else { + var itemItem = currentItem.item + if (!itemItem.contains(itemItem.mapFromItem(column, pos))) + currentItem = null + } + if (currentItem) { root.__currentIndex = currentItem.menuItemIndex if (currentItem.isSubmenu && !currentItem.menuItem.__popupVisible) -- cgit v1.2.1 From 5520918af2cfb00618765820df2a28916a12c626 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Fri, 6 Sep 2013 10:16:23 +0200 Subject: Set the menu role for the QPlatformMenuItem to the default QAction has a default menu role which is passed on to the QPlatformMenuItem. But as QtQuickControls does not use QAction, we need to set the default menu role explicitly to TextHeuristicRole. This fixes the merging of menu items on Mac. Task-number: QTBUG-31883 Change-Id: I24f0e265f8ceca376db9970d62e8f79a646fef3b Reviewed-by: Jens Bache-Wiig Reviewed-by: Gabriel de Dietrich --- src/controls/qquickmenuitem.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/controls/qquickmenuitem.cpp b/src/controls/qquickmenuitem.cpp index ed03b336..2fda7e00 100644 --- a/src/controls/qquickmenuitem.cpp +++ b/src/controls/qquickmenuitem.cpp @@ -55,6 +55,8 @@ QQuickMenuBase::QQuickMenuBase(QObject *parent) : QObject(parent), m_visible(true), m_parentMenu(0), m_container(0), m_visualItem(0) { m_platformItem = QGuiApplicationPrivate::platformTheme()->createPlatformMenuItem(); + if (m_platformItem) + m_platformItem->setRole(QPlatformMenuItem::TextHeuristicRole); } QQuickMenuBase::~QQuickMenuBase() -- cgit v1.2.1 From 6bcacdecb8445a5ad9a31f6bdac99cde076e6295 Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Tue, 10 Sep 2013 12:44:35 +0200 Subject: Fix incorrect spinbox validation at startup The problem was that the validator was applied during the object creation which means the incorrect decimal values were applied and the initial value was incorrectly changed. Task-number: QTBUG-33309 Change-Id: Ic1ace174b9059b9c6ce24fd88b81c5edd7318e80 Reviewed-by: Caroline Chao Reviewed-by: J-P Nurmi --- src/controls/SpinBox.qml | 5 +++-- tests/auto/controls/data/tst_spinbox.qml | 10 ++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/controls/SpinBox.qml b/src/controls/SpinBox.qml index b1f87cec..6f62c3a3 100644 --- a/src/controls/SpinBox.qml +++ b/src/controls/SpinBox.qml @@ -229,8 +229,9 @@ Control { validator: SpinBoxValidator { id: validator - onTextChanged: input.text = validator.text - Component.onCompleted: input.text = validator.text + property bool ready: false // Delay validation until all properties are ready + onTextChanged: if (ready) input.text = validator.text + Component.onCompleted: {input.text = validator.text ; ready = true} } onAccepted: { input.text = validator.text diff --git a/tests/auto/controls/data/tst_spinbox.qml b/tests/auto/controls/data/tst_spinbox.qml index 267e9c4b..ed39f080 100644 --- a/tests/auto/controls/data/tst_spinbox.qml +++ b/tests/auto/controls/data/tst_spinbox.qml @@ -87,6 +87,16 @@ Item { spinbox.destroy() } + function test_initial_value() { + var spinbox = Qt.createQmlObject('import QtQuick.Controls 1.0; SpinBox {decimals: 3 ; value: 0.25}', container, '') + compare(spinbox.value, 0.25) + spinbox.destroy() + + spinbox = Qt.createQmlObject('import QtQuick.Controls 1.0; SpinBox {value: 0.25 ; decimals: 3}', container, '') + compare(spinbox.value, 0.25) + spinbox.destroy() + } + function test_keyboard_input_data() { return [ {tag: "1", input: [Qt.Key_1], value: 1}, -- cgit v1.2.1 From 82081e737038262c82c2e408d412fc80a607bf9f Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Thu, 5 Sep 2013 17:28:06 +0200 Subject: Menu: Fix keyboard navigation on Windows The Windows QPA plugin doesn't trigger activated window events for popups, resulting on the popup window not being the application focus window, and therefore, the popup window's content item not getting focus. This results in key pressed events not being sent to the menu item. We workaround this by emitting the window activated event ourselves right after the popup window is exposed. Task-number: QTBUG-33175 Change-Id: I77d1eb33b71af2232a6be6d0f7c6b480bffc10d4 Reviewed-by: Gabriel de Dietrich Reviewed-by: Jens Bache-Wiig --- src/controls/qquickmenupopupwindow.cpp | 28 ++++++++++++++++++++++++++-- src/controls/qquickmenupopupwindow_p.h | 3 +++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/controls/qquickmenupopupwindow.cpp b/src/controls/qquickmenupopupwindow.cpp index b44b082c..dd68b15c 100644 --- a/src/controls/qquickmenupopupwindow.cpp +++ b/src/controls/qquickmenupopupwindow.cpp @@ -42,14 +42,15 @@ #include "qquickmenupopupwindow_p.h" #include +#include #include #include QT_BEGIN_NAMESPACE QQuickMenuPopupWindow::QQuickMenuPopupWindow(QWindow *parent) : - QQuickWindow(parent), m_mouseMoved(false), m_itemAt(0), - m_parentItem(0), m_menuContentItem(0) + QQuickWindow(parent), m_mouseMoved(false), m_needsActivatedEvent(true), + m_itemAt(0), m_parentItem(0), m_menuContentItem(0) { setFlags(Qt::Popup); setModality(Qt::WindowModal); @@ -235,4 +236,27 @@ void QQuickMenuPopupWindow::forwardEventToTransientParent(QMouseEvent *e) } } +void QQuickMenuPopupWindow::exposeEvent(QExposeEvent *e) +{ + if (isExposed() && m_needsActivatedEvent) { + m_needsActivatedEvent = false; + QWindowSystemInterface::handleWindowActivated(this, Qt::PopupFocusReason); + } else if (!isExposed() && !m_needsActivatedEvent) { + m_needsActivatedEvent = true; + if (QWindow *tp = transientParent()) + QWindowSystemInterface::handleWindowActivated(tp, Qt::PopupFocusReason); + } + QQuickWindow::exposeEvent(e); +} + +void QQuickMenuPopupWindow::hideEvent(QHideEvent *e) +{ + if (QWindow *tp = !m_needsActivatedEvent ? transientParent() : 0) { + m_needsActivatedEvent = true; + QWindowSystemInterface::handleWindowActivated(tp, Qt::PopupFocusReason); + } + + QQuickWindow::hideEvent(e); +} + QT_END_NAMESPACE diff --git a/src/controls/qquickmenupopupwindow_p.h b/src/controls/qquickmenupopupwindow_p.h index aead2bd8..b515ec3d 100644 --- a/src/controls/qquickmenupopupwindow_p.h +++ b/src/controls/qquickmenupopupwindow_p.h @@ -81,11 +81,14 @@ protected: void mousePressEvent(QMouseEvent *); void mouseReleaseEvent(QMouseEvent *); void mouseMoveEvent(QMouseEvent *); + void exposeEvent(QExposeEvent *); + void hideEvent(QHideEvent *); private: void forwardEventToTransientParent(QMouseEvent *); bool m_mouseMoved; + bool m_needsActivatedEvent; QQuickItem *m_itemAt; QPointF m_oldItemPos; QQuickItem *m_parentItem; -- cgit v1.2.1 From 4eb3400843cafcedffa47fb8a272704bca4e9473 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Thu, 5 Sep 2013 17:29:10 +0200 Subject: Menu: Enable mnemonic menu navigation We also added a new mnemonic specific shortcut context matcher. This prevents two menu items with the same mnemonic but within different menus to be reported as ambiguous. Task-number: QTBUG-33030 ChangeLog: Added mnemonic navigation for menus Change-Id: I192c9aacba4d15851fe65bf9201251962fe976d5 Reviewed-by: J-P Nurmi --- examples/quick/controls/gallery/main.qml | 18 +++++----- src/controls/ApplicationWindow.qml | 2 ++ src/controls/Menu.qml | 51 +++++++++++++++++++------- src/controls/MenuBar.qml | 62 ++++++++++++++++++++++++++++++-- src/controls/qquickaction.cpp | 37 ++++++++++++++++++- src/controls/qquickmenu.cpp | 4 ++- src/controls/qquickmenu_p.h | 4 ++- src/controls/qquickmenuitem.cpp | 7 ++++ src/controls/qquickmenuitem_p.h | 3 +- src/private/qquickstyleitem.cpp | 3 +- src/styles/Desktop/MenuBarStyle.qml | 7 ++++ src/styles/Desktop/MenuStyle.qml | 7 ++++ 12 files changed, 176 insertions(+), 29 deletions(-) diff --git a/examples/quick/controls/gallery/main.qml b/examples/quick/controls/gallery/main.qml index ec00627b..2896c356 100644 --- a/examples/quick/controls/gallery/main.qml +++ b/examples/quick/controls/gallery/main.qml @@ -111,20 +111,20 @@ ApplicationWindow { Action { id: a1 - text: "Align Left" + text: "Align &Left" checkable: true Component.onCompleted: checked = true } Action { id: a2 - text: "Center" + text: "&Center" checkable: true } Action { id: a3 - text: "Align Right" + text: "Align &Right" checkable: true } } @@ -138,18 +138,18 @@ ApplicationWindow { MenuItem { action: pasteAction } MenuSeparator {} Menu { - title: "Text Format" + title: "Text &Format" MenuItem { action: a1 } MenuItem { action: a2 } MenuItem { action: a3 } MenuSeparator { } - MenuItem { text: "Allow Hyphenation"; checkable: true } + MenuItem { text: "Allow &Hyphenation"; checkable: true } } Menu { - title: "Font Style" - MenuItem { text: "Bold"; checkable: true } - MenuItem { text: "Italic"; checkable: true } - MenuItem { text: "Underline"; checkable: true } + title: "Font &Style" + MenuItem { text: "&Bold"; checkable: true } + MenuItem { text: "&Italic"; checkable: true } + MenuItem { text: "&Underline"; checkable: true } } } diff --git a/src/controls/ApplicationWindow.qml b/src/controls/ApplicationWindow.qml index 364b2b11..8967a8a1 100644 --- a/src/controls/ApplicationWindow.qml +++ b/src/controls/ApplicationWindow.qml @@ -133,6 +133,8 @@ Window { id: backgroundItem anchors.fill: parent + Keys.forwardTo: [menuBar.__contentItem] + Item { id: contentArea anchors.top: toolBarArea.bottom diff --git a/src/controls/Menu.qml b/src/controls/Menu.qml index 6c9f8fd2..525b0737 100644 --- a/src/controls/Menu.qml +++ b/src/controls/Menu.qml @@ -133,7 +133,7 @@ MenuPrivate { property Component style: Qt.createComponent(Settings.style + "/MenuStyle.qml", root) /*! \internal */ - property var __menuBar: null + property var __parentContentItem: __parentMenu.__contentItem /*! \internal */ property int __currentIndex: -1 /*! \internal */ @@ -144,6 +144,8 @@ MenuPrivate { sourceComponent: __menuComponent active: !root.__isNative && root.__popupVisible focus: true + Keys.forwardTo: item ? [item, root.__parentContentItem] : [] + property bool altPressed: root.__parentContentItem ? root.__parentContentItem.altPressed : false } /*! \internal */ @@ -174,14 +176,30 @@ MenuPrivate { } focus: true - Keys.forwardTo: __menuBar ? [__menuBar] : [] + property var mnemonicsMap: ({}) + + Keys.onPressed: { + var item = null + if (!(event.modifiers & Qt.AltModifier) + && (item = mnemonicsMap[event.text.toUpperCase()])) { + if (item.isSubmenu) { + root.__currentIndex = item.menuItemIndex + item.showSubMenu(true) + item.menuItem.__currentIndex = 0 + } else { + triggerAndDismiss(item) + } + event.accepted = true + } else { + event.accepted = false + } + } + Keys.onEscapePressed: root.__dismissMenu() Keys.onDownPressed: { - if (root.__currentIndex < 0) { - root.__currentIndex = 0 - return - } + if (root.__currentIndex < 0) + root.__currentIndex = -1 for (var i = root.__currentIndex + 1; i < root.items.length && !canBeHovered(i); i++) @@ -204,13 +222,13 @@ MenuPrivate { } Keys.onLeftPressed: { - if (root.__parentMenu) + if ((event.accepted = root.__parentMenu.hasOwnProperty("title"))) __closeMenu() } Keys.onRightPressed: { var item = itemsRepeater.itemAt(root.__currentIndex) - if (item && item.isSubmenu) { + if ((event.accepted = (item && item.isSubmenu))) { item.showSubMenu(true) item.menuItem.__currentIndex = 0 } @@ -220,8 +238,9 @@ MenuPrivate { Keys.onReturnPressed: menuFrameLoader.triggerAndDismiss() Keys.onEnterPressed: menuFrameLoader.triggerAndDismiss() - function triggerAndDismiss() { - var item = itemsRepeater.itemAt(root.__currentIndex) + function triggerAndDismiss(item) { + if (!item) + item = itemsRepeater.itemAt(root.__currentIndex) if (item && !item.isSeparator) { root.__dismissMenu() if (!item.isSubmenu) @@ -261,7 +280,7 @@ MenuPrivate { var itemUnderMouse = column.childAt(pos.x, pos.y) if (itemUnderMouse) { currentItem = itemUnderMouse - } else { + } else if (currentItem) { var itemItem = currentItem.item if (!itemItem.contains(itemItem.mapFromItem(column, pos))) currentItem = null @@ -294,6 +313,7 @@ MenuPrivate { readonly property bool isSubmenu: !!menuItem && menuItem.type === MenuItemType.Menu property bool selected: !isSeparator && root.__currentIndex === index property string text: isSubmenu ? menuItem.title : !isSeparator ? menuItem.text : "" + property bool showUnderlined: __contentItem.altPressed property int menuItemIndex: index @@ -328,7 +348,14 @@ MenuPrivate { } } - Component.onCompleted: menuItem.__visualItem = menuItemLoader + Component.onCompleted: { + menuItem.__visualItem = menuItemLoader + + var title = text + var ampersandPos = title.indexOf("&") + if (ampersandPos !== -1) + menuFrameLoader.mnemonicsMap[title[ampersandPos + 1].toUpperCase()] = menuItemLoader + } } } diff --git a/src/controls/MenuBar.qml b/src/controls/MenuBar.qml index eabb4d48..a126c7c6 100644 --- a/src/controls/MenuBar.qml +++ b/src/controls/MenuBar.qml @@ -82,6 +82,8 @@ MenuBarPrivate { sourceComponent: __menuBarComponent active: !root.__isNative focus: true + Keys.forwardTo: [item] + property bool altPressed: item ? item.altPressed : false } /*! \internal */ @@ -118,7 +120,51 @@ MenuBarPrivate { value: menuMouseArea.z - 1 } - focus: openedMenuIndex !== -1 + focus: true + + property bool altPressed: false + property bool altPressedAgain: false + property var mnemonicsMap: ({}) + + Keys.onPressed: { + var action = null + if (event.key === Qt.Key_Alt) { + if (!altPressed) + altPressed = true + else + altPressedAgain = true + } else if (altPressed && (action = mnemonicsMap[event.text.toUpperCase()])) { + preselectMenuItem = true + action.trigger() + event.accepted = true + } + } + + function dismissActiveFocus(event, reason) { + if (reason) { + altPressedAgain = false + altPressed = false + openedMenuIndex = -1 + root.__contentItem.parent.forceActiveFocus() + } else { + event.accepted = false + } + } + + Keys.onReleased: dismissActiveFocus(event, altPressedAgain && openedMenuIndex === -1) + Keys.onEscapePressed: dismissActiveFocus(event, openedMenuIndex === -1) + + function maybeOpenFirstMenu(event) { + if (altPressed && openedMenuIndex === -1) { + preselectMenuItem = true + openedMenuIndex = 0 + } else { + event.accepted = false + } + } + + Keys.onUpPressed: maybeOpenFirstMenu(event) + Keys.onDownPressed: maybeOpenFirstMenu(event) Keys.onLeftPressed: { if (openedMenuIndex > 0) { @@ -128,7 +174,7 @@ MenuBarPrivate { } Keys.onRightPressed: { - if (openedMenuIndex < root.menus.length - 1) { + if (openedMenuIndex !== -1 && openedMenuIndex < root.menus.length - 1) { preselectMenuItem = true openedMenuIndex++ } @@ -177,6 +223,7 @@ MenuBarPrivate { property var menuItem: modelData property bool selected: menuMouseArea.hoveredItem === menuItemLoader property bool sunken: menuItem.__popupVisible || menuBarLoader.openedMenuIndex === index + property bool showUnderlined: menuBarLoader.altPressed sourceComponent: menuBarLoader.menuItemStyle property int menuItemIndex: index @@ -203,9 +250,18 @@ MenuBarPrivate { } } + Connections { + target: menuItem.__action + onTriggered: menuBarLoader.openedMenuIndex = menuItemIndex + } + Component.onCompleted: { menuItem.__visualItem = menuItemLoader - menuItem.__menuBar = menuBarLoader + + var title = menuItem.title + var ampersandPos = title.indexOf("&") + if (ampersandPos !== -1) + menuBarLoader.mnemonicsMap[title[ampersandPos + 1].toUpperCase()] = menuItem.__action } } } diff --git a/src/controls/qquickaction.cpp b/src/controls/qquickaction.cpp index e240d111..6a031404 100644 --- a/src/controls/qquickaction.cpp +++ b/src/controls/qquickaction.cpp @@ -41,6 +41,7 @@ #include "qquickaction_p.h" #include "qquickexclusivegroup_p.h" +#include "qquickmenuitem_p.h" #include #include @@ -203,6 +204,8 @@ void QQuickAction::setText(const QString &text) emit textChanged(); } +namespace { + bool qShortcutContextMatcher(QObject *o, Qt::ShortcutContext context) { switch (context) { @@ -226,6 +229,38 @@ bool qShortcutContextMatcher(QObject *o, Qt::ShortcutContext context) return false; } +bool qMnemonicContextMatcher(QObject *o, Qt::ShortcutContext context) +{ + switch (context) { + case Qt::ApplicationShortcut: + return true; + case Qt::WindowShortcut: { + QObject *w = o; + while (w && !w->isWindowType()) { + w = w->parent(); + if (QQuickItem * item = qobject_cast(w)) + w = item->window(); + else if (QQuickMenuBase *mb = qobject_cast(w)) { + QQuickItem *vi = mb->visualItem(); + if (vi && vi->isVisible()) + w = vi->window(); + else + break; // Non visible menu objects don't get mnemonic match + } + } + if (w && w == QGuiApplication::focusWindow()) + return true; + } + case Qt::WidgetShortcut: + case Qt::WidgetWithChildrenShortcut: + break; + } + + return false; +} + +} // namespace + QString QQuickAction::shortcut() const { return m_shortcut.toString(QKeySequence::NativeText); @@ -262,7 +297,7 @@ void QQuickAction::setMnemonicFromText(const QString &text) if (!m_mnemonic.isEmpty()) { Qt::ShortcutContext context = Qt::WindowShortcut; - QGuiApplicationPrivate::instance()->shortcutMap.addShortcut(this, m_mnemonic, context, qShortcutContextMatcher); + QGuiApplicationPrivate::instance()->shortcutMap.addShortcut(this, m_mnemonic, context, qMnemonicContextMatcher); } } diff --git a/src/controls/qquickmenu.cpp b/src/controls/qquickmenu.cpp index 2dbaf952..f65d7044 100644 --- a/src/controls/qquickmenu.cpp +++ b/src/controls/qquickmenu.cpp @@ -401,8 +401,10 @@ void QQuickMenu::__popup(qreal x, qreal y, int atItemIndex) void QQuickMenu::setMenuContentItem(QQuickItem *item) { - if (m_menuContentItem != item) + if (m_menuContentItem != item) { m_menuContentItem = item; + emit menuContentItemChanged(); + } } void QQuickMenu::setPopupVisible(bool v) diff --git a/src/controls/qquickmenu_p.h b/src/controls/qquickmenu_p.h index 54f7451b..f15e6caa 100644 --- a/src/controls/qquickmenu_p.h +++ b/src/controls/qquickmenu_p.h @@ -68,11 +68,12 @@ class QQuickMenu : public QQuickMenuText Q_PROPERTY(int __selectedIndex READ selectedIndex WRITE setSelectedIndex NOTIFY __selectedIndexChanged) Q_PROPERTY(bool __popupVisible READ popupVisible NOTIFY popupVisibleChanged) - Q_PROPERTY(QQuickItem *__contentItem READ menuContentItem WRITE setMenuContentItem) + Q_PROPERTY(QQuickItem *__contentItem READ menuContentItem WRITE setMenuContentItem NOTIFY menuContentItemChanged) Q_PROPERTY(int __minimumWidth READ minimumWidth WRITE setMinimumWidth) Q_PROPERTY(QFont __font READ font WRITE setFont) Q_PROPERTY(qreal __xOffset READ xOffset WRITE setXOffset) Q_PROPERTY(qreal __yOffset READ yOffset WRITE setYOffset) + Q_PROPERTY(QQuickAction *__action READ action CONSTANT) public: Q_INVOKABLE void popup(); @@ -98,6 +99,7 @@ Q_SIGNALS: void __selectedIndexChanged(); void __menuClosed(); void popupVisibleChanged(); + void menuContentItemChanged(); public: QQuickMenu(QObject *parent = 0); diff --git a/src/controls/qquickmenuitem.cpp b/src/controls/qquickmenuitem.cpp index 2fda7e00..4d276ac1 100644 --- a/src/controls/qquickmenuitem.cpp +++ b/src/controls/qquickmenuitem.cpp @@ -84,6 +84,13 @@ void QQuickMenuBase::setVisible(bool v) } } +QObject *QQuickMenuBase::parentMenuOrMenuBar() const +{ + if (!m_parentMenu) + return parent(); + return m_parentMenu; +} + QQuickMenu *QQuickMenuBase::parentMenu() const { return m_parentMenu; diff --git a/src/controls/qquickmenuitem_p.h b/src/controls/qquickmenuitem_p.h index 02e7f5e3..791a0edb 100644 --- a/src/controls/qquickmenuitem_p.h +++ b/src/controls/qquickmenuitem_p.h @@ -78,7 +78,7 @@ class QQuickMenuBase: public QObject Q_PROPERTY(bool visible READ visible WRITE setVisible NOTIFY visibleChanged) Q_PROPERTY(QQuickMenuItemType::MenuItemType type READ type CONSTANT) - Q_PROPERTY(QQuickMenu *__parentMenu READ parentMenu CONSTANT) + Q_PROPERTY(QObject *__parentMenu READ parentMenuOrMenuBar CONSTANT) Q_PROPERTY(bool __isNative READ isNative CONSTANT) Q_PROPERTY(QQuickItem *__visualItem READ visualItem WRITE setVisualItem) @@ -93,6 +93,7 @@ public: virtual void setVisible(bool); QQuickMenu *parentMenu() const; + QObject *parentMenuOrMenuBar() const; virtual void setParentMenu(QQuickMenu *parentMenu); QQuickMenuItemContainer *container() const; diff --git a/src/private/qquickstyleitem.cpp b/src/private/qquickstyleitem.cpp index b8edbd2d..d0f3e26e 100644 --- a/src/private/qquickstyleitem.cpp +++ b/src/private/qquickstyleitem.cpp @@ -318,7 +318,6 @@ void QQuickStyleItem::initStyleOption() if (!m_styleoption) m_styleoption = new QStyleOptionTab(); - QStyleOptionTab *opt = qstyleoption_cast(m_styleoption); opt->text = text(); @@ -396,6 +395,7 @@ void QQuickStyleItem::initStyleOption() QStyleOptionMenuItem *opt = qstyleoption_cast(m_styleoption); opt->text = text(); opt->menuItemType = QStyleOptionMenuItem::Normal; + setProperty("_q_showUnderlined", m_hints["showUnderlined"].toBool()); if (const QFont *font = QGuiApplicationPrivate::platformTheme()->font(QPlatformTheme::MenuBarFont)) { opt->font = *font; @@ -443,6 +443,7 @@ void QQuickStyleItem::initStyleOption() } if (m_properties["icon"].canConvert()) opt->icon = m_properties["icon"].value(); + setProperty("_q_showUnderlined", m_hints["showUnderlined"].toBool()); if (const QFont *font = QGuiApplicationPrivate::platformTheme()->font(m_itemType == ComboBoxItem ? QPlatformTheme::ComboMenuItemFont : QPlatformTheme::MenuFont)) { opt->font = *font; diff --git a/src/styles/Desktop/MenuBarStyle.qml b/src/styles/Desktop/MenuBarStyle.qml index 291df0fb..f1d7b353 100644 --- a/src/styles/Desktop/MenuBarStyle.qml +++ b/src/styles/Desktop/MenuBarStyle.qml @@ -51,6 +51,8 @@ Style { width: implicitWidth + 2 * (pixelMetric("menubarhmargin") + pixelMetric("menubarpanelwidth")) height: implicitHeight + 2 * (pixelMetric("menubarvmargin") + pixelMetric("menubarpanelwidth")) + pixelMetric("spacebelowmenubar") + + Accessible.role: Accessible.MenuBar } property Component menuItem: StyleItem { @@ -66,5 +68,10 @@ Style { enabled: menuItem.enabled selected: (parent && parent.selected) || sunken sunken: parent && parent.sunken + + hints: { "showUnderlined": showUnderlined } + + Accessible.role: Accessible.MenuItem + Accessible.name: StyleHelpers.removeMnemonics(text) } } diff --git a/src/styles/Desktop/MenuStyle.qml b/src/styles/Desktop/MenuStyle.qml index 960a163d..d659c25d 100644 --- a/src/styles/Desktop/MenuStyle.qml +++ b/src/styles/Desktop/MenuStyle.qml @@ -65,6 +65,8 @@ Style { } color: __syspal.window } + + Accessible.role: Accessible.PopupMenu } property Component menuItem: StyleItem { @@ -81,6 +83,8 @@ Style { selected: !!parent && parent.selected on: !!menuItem && !!menuItem["checkable"] && menuItem.checked + hints: { "showUnderlined": showUnderlined } + properties: { "checkable": !!menuItem && !!menuItem["checkable"], "exclusive": !!menuItem && !!menuItem["exclusiveGroup"], @@ -88,5 +92,8 @@ Style { "isSubmenu": isSubmenu, "icon": !!menuItem && menuItem.__icon } + + Accessible.role: Accessible.MenuItem + Accessible.name: StyleHelpers.removeMnemonics(text) } } -- cgit v1.2.1 From 04e000d2b1719696581bb4ae6ec21e39236ef38c Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 18 Sep 2013 13:43:59 +0200 Subject: Fix Tab ownership issue that has been blocking stable->dev merge Change-Id: Ifcae96687bcc54486d7f16b1e1002e54394b914d Reviewed-by: Gabriel de Dietrich --- src/controls/TabView.qml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/controls/TabView.qml b/src/controls/TabView.qml index cd8a023a..bee7b3eb 100644 --- a/src/controls/TabView.qml +++ b/src/controls/TabView.qml @@ -95,7 +95,9 @@ FocusScope { Returns the newly added tab. */ function insertTab(index, title, component) { - var tab = tabcomp.createObject() + // 'loader' parent is a pending workaround while waiting for: + // https://codereview.qt-project.org/#change,65788 + var tab = tabcomp.createObject(loader) tab.sourceComponent = component tab.title = title // insert at appropriate index first, then set the parent to -- cgit v1.2.1