From 4998538c94ed8cb029b8849a60b3f7528eae8311 Mon Sep 17 00:00:00 2001 From: Filippo Cucchetto Date: Mon, 17 Aug 2015 17:10:35 +0200 Subject: Fixed key event propagation with submenus When a menu receive a Key_Right event and its subMenu popupwindow is already visible, the event should be discarded. In this way the event can forwarded up to the menubar for moving to the next root menu. Change-Id: Ifeb402f66fdac9fcf3a541456b929d11d36ad00d Reviewed-by: J-P Nurmi --- src/controls/MenuBar.qml | 2 ++ src/controls/Private/MenuContentItem.qml | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/controls/MenuBar.qml b/src/controls/MenuBar.qml index 444185cc..8d49a1ed 100644 --- a/src/controls/MenuBar.qml +++ b/src/controls/MenuBar.qml @@ -246,6 +246,8 @@ MenuBarPrivate { } } + Keys.forwardTo: d.openedMenuIndex !== -1 ? [root.menus[d.openedMenuIndex].__contentItem] : [] + Row { id: row x: d.style ? d.style.padding.left : 0 diff --git a/src/controls/Private/MenuContentItem.qml b/src/controls/Private/MenuContentItem.qml index a0b346c4..c208e093 100644 --- a/src/controls/Private/MenuContentItem.qml +++ b/src/controls/Private/MenuContentItem.qml @@ -138,9 +138,13 @@ Loader { Keys.onRightPressed: { var item = content.menuItemAt(__menu.__currentIndex) - if ((event.accepted = (item && item.styleData.type === MenuItemType.Menu))) { + if (item && item.styleData.type === MenuItemType.Menu + && !item.__menuItem.__popupVisible) { item.__showSubMenu(true) item.__menuItem.__currentIndex = 0 + event.accepted = true + } else { + event.accepted = false } } -- cgit v1.2.1 From 4849fd5a81593b09f046073d9cd5be9742d45326 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Tue, 26 Jan 2016 13:40:40 +0100 Subject: FileDialog: create FolderListModel asynchronously when first opened This is only for the QML dialog implementation. The incubator should be able to do this without any UI freeze, however there can still be a delay when opening the dialog. It's better to delay at that time instead of during application startup. Task-number: QTBUG-46477 Change-Id: I31bada236ecbcfeb98ab98c511c65f95f1a1f83c Reviewed-by: Richard Moe Gustavsen --- src/dialogs/DefaultFileDialog.qml | 44 +++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/src/dialogs/DefaultFileDialog.qml b/src/dialogs/DefaultFileDialog.qml index 4c59381e..02815f17 100644 --- a/src/dialogs/DefaultFileDialog.qml +++ b/src/dialogs/DefaultFileDialog.qml @@ -48,10 +48,39 @@ import "qml" AbstractFileDialog { id: root - folder: view.model.folder + Component { + id: modelComponent + FolderListModel { + showFiles: !root.selectFolder + nameFilters: root.selectedNameFilterExtensions + sortField: (view.sortIndicatorColumn === 0 ? FolderListModel.Name : + (view.sortIndicatorColumn === 1 ? FolderListModel.Type : + (view.sortIndicatorColumn === 2 ? FolderListModel.Size : FolderListModel.LastModified))) + sortReversed: view.sortIndicatorOrder === Qt.DescendingOrder + } + } onVisibleChanged: { if (visible) { + // If the TableView doesn't have a model yet, create it asynchronously to avoid a UI freeze + if (!view.model) { + var incubator = modelComponent.incubateObject(null, { }) + function init(model) { + view.model = model + model.nameFilters = root.selectedNameFilterExtensions + root.folder = model.folder + } + + if (incubator.status === Component.Ready) { + init(incubator.object) + } else { + incubator.onStatusChanged = function(status) { + if (status === Component.Ready) + init(incubator.object) + } + } + } + view.needsWidthAdjustment = true view.selection.clear() view.focus = true @@ -59,7 +88,6 @@ AbstractFileDialog { } Component.onCompleted: { - view.model.nameFilters = root.selectedNameFilterExtensions filterField.currentIndex = root.selectedNameFilterIndex root.favoriteFolders = settings.favoriteFolders } @@ -300,14 +328,7 @@ AbstractFileDialog { resizeColumnsToContents() needsWidthAdjustment = false } - model: FolderListModel { - showFiles: !root.selectFolder - nameFilters: root.selectedNameFilterExtensions - sortField: (view.sortIndicatorColumn === 0 ? FolderListModel.Name : - (view.sortIndicatorColumn === 1 ? FolderListModel.Type : - (view.sortIndicatorColumn === 2 ? FolderListModel.Size : FolderListModel.LastModified))) - sortReversed: view.sortIndicatorOrder === Qt.DescendingOrder - } + model: null onActivated: if (view.focus) { if (view.selection.count > 0 && view.model.isFolder(row)) { @@ -435,7 +456,8 @@ AbstractFileDialog { anchors.verticalCenter: parent.verticalCenter onCurrentTextChanged: { root.selectNameFilter(currentText) - view.model.nameFilters = root.selectedNameFilterExtensions + if (view.model) + view.model.nameFilters = root.selectedNameFilterExtensions } } Button { -- cgit v1.2.1 From 144bc5cedd9af5e62fe7210bac7df2c19d20c41b Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Tue, 26 Jan 2016 14:32:59 +0100 Subject: FileDialog: move shortcuts properties up to QQuickAbstractFileDialog QQuickQFileDialog does not inherit QQuickFileDialog, so the documented shortcuts property was not defined if your platform happens to use the QFileDialog implementation. As long as we are moving the public property, it's easiest to move everything related to shortcuts. Task-number: QTBUG-50673 Change-Id: Ic2baf4a3c83ca12edf11d7d011aaa78a389e0fde Reviewed-by: Richard Moe Gustavsen --- src/dialogs/qquickabstractfiledialog.cpp | 82 +++++++++++++++++++++++++++++- src/dialogs/qquickabstractfiledialog_p.h | 14 +++++- src/dialogs/qquickfiledialog.cpp | 86 -------------------------------- src/dialogs/qquickfiledialog_p.h | 17 ------- 4 files changed, 94 insertions(+), 105 deletions(-) diff --git a/src/dialogs/qquickabstractfiledialog.cpp b/src/dialogs/qquickabstractfiledialog.cpp index 233a2db7..26c7218b 100644 --- a/src/dialogs/qquickabstractfiledialog.cpp +++ b/src/dialogs/qquickabstractfiledialog.cpp @@ -38,9 +38,10 @@ #include "qquickitem.h" #include +#include +#include #include #include -#include QT_BEGIN_NAMESPACE @@ -221,4 +222,83 @@ void QQuickAbstractFileDialog::updateModes() emit fileModeChanged(); } +void QQuickAbstractFileDialog::addShortcut(const QString &name, const QString &visibleName, const QString &path) +{ + QQmlEngine *engine = qmlEngine(this); + QUrl url = QUrl::fromLocalFile(path); + + // Since the app can have bindings to the shortcut, we always add it + // to the public API, even if the directory doesn't (yet) exist. + m_shortcuts.setProperty(name, url.toString()); + + // ...but we are more strict about showing it as a clickable link inside the dialog + if (visibleName.isEmpty() || !QDir(path).exists()) + return; + + QJSValue o = engine->newObject(); + o.setProperty("name", visibleName); + // TODO maybe some day QJSValue could directly store a QUrl + o.setProperty("url", url.toString()); + + int length = m_shortcutDetails.property(QLatin1String("length")).toInt(); + m_shortcutDetails.setProperty(length, o); +} + +void QQuickAbstractFileDialog::addShortcutFromStandardLocation(const QString &name, QStandardPaths::StandardLocation loc, bool local) +{ + if (m_selectExisting) { + QStringList readPaths = QStandardPaths::standardLocations(loc); + QString path = readPaths.isEmpty() ? QString() : local ? readPaths.first() : readPaths.last(); + addShortcut(name, QStandardPaths::displayName(loc), path); + } else { + QString path = QStandardPaths::writableLocation(loc); + addShortcut(name, QStandardPaths::displayName(loc), path); + } +} + +void QQuickAbstractFileDialog::populateShortcuts() +{ + QJSEngine *engine = qmlEngine(this); + m_shortcutDetails = engine->newArray(); + m_shortcuts = engine->newObject(); + + addShortcutFromStandardLocation(QLatin1String("desktop"), QStandardPaths::DesktopLocation); + addShortcutFromStandardLocation(QLatin1String("documents"), QStandardPaths::DocumentsLocation); + addShortcutFromStandardLocation(QLatin1String("music"), QStandardPaths::MusicLocation); + addShortcutFromStandardLocation(QLatin1String("movies"), QStandardPaths::MoviesLocation); + addShortcutFromStandardLocation(QLatin1String("home"), QStandardPaths::HomeLocation); + +#ifndef Q_OS_IOS + addShortcutFromStandardLocation(QLatin1String("pictures"), QStandardPaths::PicturesLocation); +#else + // On iOS we point pictures to the system picture folder when loading + addShortcutFromStandardLocation(QLatin1String("pictures"), QStandardPaths::PicturesLocation, !m_selectExisting); +#endif + +#ifndef Q_OS_IOS + // on iOS, this returns only "/", which is never a useful path to read or write anything + QFileInfoList drives = QDir::drives(); + foreach (QFileInfo fi, drives) + addShortcut(fi.absoluteFilePath(), fi.absoluteFilePath(), fi.absoluteFilePath()); +#endif + + emit shortcutsChanged(); +} + +QJSValue QQuickAbstractFileDialog::shortcuts() +{ + if (m_shortcuts.isUndefined()) + populateShortcuts(); + + return m_shortcuts; +} + +QJSValue QQuickAbstractFileDialog::__shortcuts() +{ + if (m_shortcutDetails.isUndefined()) + populateShortcuts(); + + return m_shortcutDetails; +} + QT_END_NAMESPACE diff --git a/src/dialogs/qquickabstractfiledialog_p.h b/src/dialogs/qquickabstractfiledialog_p.h index 9275c1da..8f094783 100644 --- a/src/dialogs/qquickabstractfiledialog_p.h +++ b/src/dialogs/qquickabstractfiledialog_p.h @@ -48,6 +48,8 @@ // We mean it. // +#include +#include #include #include #include @@ -69,6 +71,8 @@ class QQuickAbstractFileDialog : public QQuickAbstractDialog Q_PROPERTY(QUrl fileUrl READ fileUrl NOTIFY selectionAccepted) Q_PROPERTY(QList fileUrls READ fileUrls NOTIFY selectionAccepted) Q_PROPERTY(bool sidebarVisible READ sidebarVisible WRITE setSidebarVisible NOTIFY sidebarVisibleChanged) + Q_PROPERTY(QJSValue shortcuts READ shortcuts NOTIFY shortcutsChanged) // map of QStandardDirectory names to QUrls + Q_PROPERTY(QJSValue __shortcuts READ __shortcuts NOTIFY shortcutsChanged) // map of details for QML dialog implementations public: QQuickAbstractFileDialog(QObject *parent = 0); @@ -86,6 +90,8 @@ public: QUrl fileUrl() const; virtual QList fileUrls() const = 0; bool sidebarVisible() const { return m_sidebarVisible; } + QJSValue shortcuts(); + QJSValue __shortcuts(); public Q_SLOTS: void setVisible(bool v); @@ -106,13 +112,19 @@ Q_SIGNALS: void fileModeChanged(); void selectionAccepted(); void sidebarVisibleChanged(); + void shortcutsChanged(); protected: - virtual void updateModes(); + void updateModes(); + void addShortcut(const QString &name, const QString &visibleName, const QString &path); + void addShortcutFromStandardLocation(const QString &name, QStandardPaths::StandardLocation loc, bool local = true); + void populateShortcuts(); protected: QPlatformFileDialogHelper *m_dlgHelper; QSharedPointer m_options; + QJSValue m_shortcuts; + QJSValue m_shortcutDetails; bool m_selectExisting; bool m_selectMultiple; bool m_selectFolder; diff --git a/src/dialogs/qquickfiledialog.cpp b/src/dialogs/qquickfiledialog.cpp index 6fb15314..65507260 100644 --- a/src/dialogs/qquickfiledialog.cpp +++ b/src/dialogs/qquickfiledialog.cpp @@ -39,7 +39,6 @@ #include #include #include -#include QT_BEGIN_NAMESPACE @@ -116,91 +115,6 @@ QList QQuickFileDialog::fileUrls() const return m_selections; } -void QQuickFileDialog::addShortcut(const QString &name, const QString &visibleName, const QString &path) -{ - QJSEngine *engine = qmlEngine(this); - QUrl url = QUrl::fromLocalFile(path); - - // Since the app can have bindings to the shortcut, we always add it - // to the public API, even if the directory doesn't (yet) exist. - m_shortcuts.setProperty(name, url.toString()); - - // ...but we are more strict about showing it as a clickable link inside the dialog - if (visibleName.isEmpty() || !QDir(path).exists()) - return; - - QJSValue o = engine->newObject(); - o.setProperty("name", visibleName); - // TODO maybe some day QJSValue could directly store a QUrl - o.setProperty("url", url.toString()); - - int length = m_shortcutDetails.property(QLatin1String("length")).toInt(); - m_shortcutDetails.setProperty(length, o); -} - -void QQuickFileDialog::addShortcutFromStandardLocation(const QString &name, QStandardPaths::StandardLocation loc, bool local) -{ - if (m_selectExisting) { - QStringList readPaths = QStandardPaths::standardLocations(loc); - QString path = readPaths.isEmpty() ? QString() : local ? readPaths.first() : readPaths.last(); - addShortcut(name, QStandardPaths::displayName(loc), path); - } else { - QString path = QStandardPaths::writableLocation(loc); - addShortcut(name, QStandardPaths::displayName(loc), path); - } -} - -void QQuickFileDialog::populateShortcuts() -{ - QJSEngine *engine = qmlEngine(this); - m_shortcutDetails = engine->newArray(); - m_shortcuts = engine->newObject(); - - addShortcutFromStandardLocation(QLatin1String("desktop"), QStandardPaths::DesktopLocation); - addShortcutFromStandardLocation(QLatin1String("documents"), QStandardPaths::DocumentsLocation); - addShortcutFromStandardLocation(QLatin1String("music"), QStandardPaths::MusicLocation); - addShortcutFromStandardLocation(QLatin1String("movies"), QStandardPaths::MoviesLocation); - addShortcutFromStandardLocation(QLatin1String("home"), QStandardPaths::HomeLocation); - -#ifndef Q_OS_IOS - addShortcutFromStandardLocation(QLatin1String("pictures"), QStandardPaths::PicturesLocation); -#else - // On iOS we point pictures to the system picture folder when loading - addShortcutFromStandardLocation(QLatin1String("pictures"), QStandardPaths::PicturesLocation, !m_selectExisting); -#endif - -#ifndef Q_OS_IOS - // on iOS, this returns only "/", which is never a useful path to read or write anything - QFileInfoList drives = QDir::drives(); - foreach (QFileInfo fi, drives) - addShortcut(fi.absoluteFilePath(), fi.absoluteFilePath(), fi.absoluteFilePath()); -#endif - - emit shortcutsChanged(); -} - -void QQuickFileDialog::updateModes() -{ - QQuickAbstractFileDialog::updateModes(); - populateShortcuts(); -} - -QJSValue QQuickFileDialog::shortcuts() -{ - if (m_shortcuts.isUndefined()) - populateShortcuts(); - - return m_shortcuts; -} - -QJSValue QQuickFileDialog::__shortcuts() -{ - if (m_shortcutDetails.isUndefined()) - populateShortcuts(); - - return m_shortcutDetails; -} - /*! \qmlproperty bool AbstractFileDialog::visible diff --git a/src/dialogs/qquickfiledialog_p.h b/src/dialogs/qquickfiledialog_p.h index 1dd65531..b621fed5 100644 --- a/src/dialogs/qquickfiledialog_p.h +++ b/src/dialogs/qquickfiledialog_p.h @@ -49,8 +49,6 @@ // #include "qquickabstractfiledialog_p.h" -#include -#include QT_BEGIN_NAMESPACE @@ -58,8 +56,6 @@ class QQuickFileDialog : public QQuickAbstractFileDialog { Q_OBJECT Q_PROPERTY(QQuickItem* contentItem READ contentItem WRITE setContentItem DESIGNABLE false) - Q_PROPERTY(QJSValue shortcuts READ shortcuts NOTIFY shortcutsChanged) // map of QStandardDirectory names to QUrls - Q_PROPERTY(QJSValue __shortcuts READ __shortcuts NOTIFY shortcutsChanged) // map of details for QML dialog implementations Q_CLASSINFO("DefaultProperty", "contentItem") // AbstractFileDialog in QML can have only one child public: @@ -67,12 +63,6 @@ public: ~QQuickFileDialog(); virtual QList fileUrls() const Q_DECL_OVERRIDE; - QJSValue shortcuts(); - QJSValue __shortcuts(); - -Q_SIGNALS: - void shortcutsChanged(); - public Q_SLOTS: void clearSelection(); bool addSelection(const QUrl &path); @@ -83,17 +73,10 @@ protected: Q_INVOKABLE QUrl pathToUrl(const QString &path) { return QUrl::fromLocalFile(path); } Q_INVOKABLE QUrl pathFolder(const QString &path); - void addShortcut(const QString &name, const QString &visibleName, const QString &path); - void addShortcutFromStandardLocation(const QString &name, QStandardPaths::StandardLocation loc, bool local = true); - void populateShortcuts(); - void updateModes() Q_DECL_OVERRIDE; - private: QList m_selections; Q_DISABLE_COPY(QQuickFileDialog) - QJSValue m_shortcuts; - QJSValue m_shortcutDetails; }; QT_END_NAMESPACE -- cgit v1.2.1 From fc9c57cf8b66bafbcaa6957bb22293047aa3d9df Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 19 Jan 2016 13:15:33 +0100 Subject: Revert "Adjust popup position by offset of the view in the toplevel window" This reverts commit c717082c098bbfc96848457436ca83db7b83e4c8, which was applied to fix popup position mapping for window containers. However, that change lead to a release blocker by breaking the very same use case with QQuickWidget, which is used by Qt Creator and is considered the modern alternative to those problematic window containers. Change-Id: I72c6d4985668a8dc1d4e1cf6e98f7597bc7c1d8f Task-number: QTBUG-49097 Reviewed-by: Friedemann Kleint Reviewed-by: Paul Olav Tvete Reviewed-by: Frederik Gladhorn Reviewed-by: Robert Loehning --- src/controls/qquickpopupwindow.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/controls/qquickpopupwindow.cpp b/src/controls/qquickpopupwindow.cpp index cfab5bd5..88d91137 100644 --- a/src/controls/qquickpopupwindow.cpp +++ b/src/controls/qquickpopupwindow.cpp @@ -67,7 +67,6 @@ void QQuickPopupWindow::show() if (QWindow *tp = transientParent()) { if (m_parentItem) { QPointF pos = m_parentItem->mapToItem(m_parentItem->window()->contentItem(), QPointF(posx, posy)); - pos += tp->mapFromGlobal(m_parentItem->window()->mapToGlobal(QPoint())); posx = pos.x(); posy = pos.y(); } -- cgit v1.2.1