diff options
Diffstat (limited to 'src/dialogs')
-rw-r--r-- | src/dialogs/DefaultFileDialog.qml | 44 | ||||
-rw-r--r-- | src/dialogs/qquickabstractdialog.cpp | 8 | ||||
-rw-r--r-- | src/dialogs/qquickabstractdialog_p.h | 4 | ||||
-rw-r--r-- | src/dialogs/qquickabstractfiledialog.cpp | 82 | ||||
-rw-r--r-- | src/dialogs/qquickabstractfiledialog_p.h | 14 | ||||
-rw-r--r-- | src/dialogs/qquickfiledialog.cpp | 86 | ||||
-rw-r--r-- | src/dialogs/qquickfiledialog_p.h | 17 |
7 files changed, 137 insertions, 118 deletions
diff --git a/src/dialogs/DefaultFileDialog.qml b/src/dialogs/DefaultFileDialog.qml index 05232268..cc663ccb 100644 --- a/src/dialogs/DefaultFileDialog.qml +++ b/src/dialogs/DefaultFileDialog.qml @@ -51,10 +51,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 @@ -62,7 +91,6 @@ AbstractFileDialog { } Component.onCompleted: { - view.model.nameFilters = root.selectedNameFilterExtensions filterField.currentIndex = root.selectedNameFilterIndex root.favoriteFolders = settings.favoriteFolders } @@ -303,14 +331,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)) { @@ -438,7 +459,8 @@ AbstractFileDialog { anchors.verticalCenter: parent.verticalCenter onCurrentTextChanged: { root.selectNameFilter(currentText) - view.model.nameFilters = root.selectedNameFilterExtensions + if (view.model) + view.model.nameFilters = root.selectedNameFilterExtensions } } Button { diff --git a/src/dialogs/qquickabstractdialog.cpp b/src/dialogs/qquickabstractdialog.cpp index 53bdef8c..afc27b77 100644 --- a/src/dialogs/qquickabstractdialog.cpp +++ b/src/dialogs/qquickabstractdialog.cpp @@ -192,7 +192,7 @@ void QQuickAbstractDialog::setVisible(bool v) } } if (m_windowDecoration) { - m_windowDecoration->setProperty("dismissOnOuterClick", (m_modality == Qt::NonModal)); + setDecorationDismissBehavior(); m_windowDecoration->setVisible(v); } else if (m_dialogWindow) { if (v) { @@ -223,6 +223,7 @@ void QQuickAbstractDialog::decorationLoaded() QVariant contentVariant; contentVariant.setValue<QQuickItem*>(m_contentItem); m_windowDecoration->setProperty("content", contentVariant); + setDecorationDismissBehavior(); connect(m_windowDecoration, SIGNAL(dismissed()), this, SLOT(reject())); ok = true; qCDebug(lcWindow) << "using synthetic window decoration" << m_windowDecoration << "from" << m_decorationComponent->url(); @@ -312,6 +313,11 @@ QQuickWindow *QQuickAbstractDialog::parentWindow() return m_parentWindow; } +void QQuickAbstractDialog::setDecorationDismissBehavior() +{ + m_windowDecoration->setProperty("dismissOnOuterClick", (m_modality == Qt::NonModal)); +} + void QQuickAbstractDialog::setContentItem(QQuickItem *obj) { m_contentItem = obj; diff --git a/src/dialogs/qquickabstractdialog_p.h b/src/dialogs/qquickabstractdialog_p.h index da012e28..0a761bf3 100644 --- a/src/dialogs/qquickabstractdialog_p.h +++ b/src/dialogs/qquickabstractdialog_p.h @@ -155,7 +155,9 @@ protected: bool m_visible; Qt::WindowModality m_modality; -protected: // variables for pure-QML implementations only +protected: // variables and methods for pure-QML implementations only + void setDecorationDismissBehavior(); + QQuickItem *m_contentItem; QWindow *m_dialogWindow; QQuickItem *m_windowDecoration; diff --git a/src/dialogs/qquickabstractfiledialog.cpp b/src/dialogs/qquickabstractfiledialog.cpp index 3a0d4229..3bc79570 100644 --- a/src/dialogs/qquickabstractfiledialog.cpp +++ b/src/dialogs/qquickabstractfiledialog.cpp @@ -41,9 +41,10 @@ #include "qquickitem.h" #include <private/qguiapplication_p.h> +#include <QQmlEngine> +#include <QQuickWindow> #include <QRegularExpression> #include <QWindow> -#include <QQuickWindow> QT_BEGIN_NAMESPACE @@ -224,4 +225,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 + const QFileInfoList drives = QDir::drives(); + for (const 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 c43865ed..370a31cc 100644 --- a/src/dialogs/qquickabstractfiledialog_p.h +++ b/src/dialogs/qquickabstractfiledialog_p.h @@ -51,6 +51,8 @@ // We mean it. // +#include <QJSValue> +#include <QStandardPaths> #include <QQuickView> #include <QtGui/qpa/qplatformdialoghelper.h> #include <qpa/qplatformtheme.h> @@ -72,6 +74,8 @@ class QQuickAbstractFileDialog : public QQuickAbstractDialog Q_PROPERTY(QUrl fileUrl READ fileUrl NOTIFY selectionAccepted) Q_PROPERTY(QList<QUrl> 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); @@ -89,6 +93,8 @@ public: QUrl fileUrl() const; virtual QList<QUrl> fileUrls() const = 0; bool sidebarVisible() const { return m_sidebarVisible; } + QJSValue shortcuts(); + QJSValue __shortcuts(); public Q_SLOTS: void setVisible(bool v); @@ -109,13 +115,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<QFileDialogOptions> 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 66e8f389..263b4988 100644 --- a/src/dialogs/qquickfiledialog.cpp +++ b/src/dialogs/qquickfiledialog.cpp @@ -42,7 +42,6 @@ #include <QQmlEngine> #include <QJSValueIterator> #include <private/qguiapplication_p.h> -#include <private/qv4object_p.h> QT_BEGIN_NAMESPACE @@ -119,91 +118,6 @@ QList<QUrl> 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 - const QFileInfoList drives = QDir::drives(); - for (const 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 630ea4a8..5614e939 100644 --- a/src/dialogs/qquickfiledialog_p.h +++ b/src/dialogs/qquickfiledialog_p.h @@ -52,8 +52,6 @@ // #include "qquickabstractfiledialog_p.h" -#include <QJSValue> -#include <QStandardPaths> QT_BEGIN_NAMESPACE @@ -61,8 +59,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: @@ -70,12 +66,6 @@ public: ~QQuickFileDialog(); virtual QList<QUrl> fileUrls() const Q_DECL_OVERRIDE; - QJSValue shortcuts(); - QJSValue __shortcuts(); - -Q_SIGNALS: - void shortcutsChanged(); - public Q_SLOTS: void clearSelection(); bool addSelection(const QUrl &path); @@ -86,17 +76,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<QUrl> m_selections; Q_DISABLE_COPY(QQuickFileDialog) - QJSValue m_shortcuts; - QJSValue m_shortcutDetails; }; QT_END_NAMESPACE |