diff options
| author | Shawn Rutledge <shawn.rutledge@digia.com> | 2015-03-17 10:55:31 +0100 |
|---|---|---|
| committer | Shawn Rutledge <shawn.rutledge@digia.com> | 2015-03-18 15:13:23 +0000 |
| commit | c9e558a64833a7f74e9c0423c35a73ed5229f112 (patch) | |
| tree | 8a0b679c906a35cc47e423ab6369585f9caeb16e /src | |
| parent | 9e6389591e781e76d17dc99f9395219785797b32 (diff) | |
FileDialog: expose several QStandardPaths in the shortcuts property
QStandardPaths::PicturesLocation is a specialized kind of file URL on iOS;
if this folder is set, then when the dialog is opened, it will be the new
dialog helper which uses the native picture gallery picker interface.
This will always work, so we do not need to check whether the path exists.
The application developer needs to have a way to get that platform-specific
(and odd-looking) URL by name, so the FileDialog.shortcuts property is now
public API: a map from programmatic names (similar to those in QStandardPaths)
to URLs. But DefaultFileDialog.qml should not display the names from this map,
because they are not translated to the user's language. So __shortcuts
is added as a private property providing a map from programmatic name to
an object containing the translated name and the URL.
This makes possible setting
FileDialog { folder: shortcuts.pictures }
which will open the special image gallery browser on iOS; and several
other paths from QStandardPaths can be set in the same way.
[ChangeLog][QtQuick.Dialogs] added FileDialog.shortcuts to enable setting
the starting folder to a standard system path. Setting folder to
shortcuts.pictures will result in a special image gallery dialog on iOS.
Change-Id: I14f04712eb4f44ff422ac91a8720b9e3ff8fb920
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@theqtcompany.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/dialogs/DefaultFileDialog.qml | 10 | ||||
| -rw-r--r-- | src/dialogs/qquickfiledialog.cpp | 73 | ||||
| -rw-r--r-- | src/dialogs/qquickfiledialog_p.h | 10 |
3 files changed, 62 insertions, 31 deletions
diff --git a/src/dialogs/DefaultFileDialog.qml b/src/dialogs/DefaultFileDialog.qml index db4d74bf1..0336695a0 100644 --- a/src/dialogs/DefaultFileDialog.qml +++ b/src/dialogs/DefaultFileDialog.qml @@ -73,7 +73,7 @@ AbstractFileDialog { property alias width: root.width property alias height: root.height property alias sidebarWidth: sidebar.width - property alias sidebarSplit: shortcuts.height + property alias sidebarSplit: shortcutsScroll.height property alias sidebarVisible: root.sidebarVisible property variant favoriteFolders: [] } @@ -169,7 +169,7 @@ AbstractFileDialog { height: parent.height - favoritesButtons.height ScrollView { - id: shortcuts + id: shortcutsScroll Component.onCompleted: { if (height < 1) height = sidebarSplitter.rowHeight * 4.65 @@ -178,7 +178,7 @@ AbstractFileDialog { height: 0 // initial width only; settings and onCompleted will override it ListView { id: shortcutsView - model: root.shortcuts + model: __shortcuts.length anchors.bottomMargin: ControlsPrivate.Settings.hasTouchScreen ? Screen.pixelDensity * 3.5 : anchors.margins implicitHeight: model.count * sidebarSplitter.rowHeight delegate: Item { @@ -187,7 +187,7 @@ AbstractFileDialog { height: shortcutLabel.implicitHeight * 1.5 Text { id: shortcutLabel - text: shortcutsView.model[index]["name"] + text: __shortcuts[Object.keys(__shortcuts)[index]].name anchors { verticalCenter: parent.verticalCenter left: parent.left @@ -204,7 +204,7 @@ AbstractFileDialog { } MouseArea { anchors.fill: parent - onClicked: root.folder = shortcutsView.model[index]["url"] + onClicked: root.folder = __shortcuts[Object.keys(__shortcuts)[index]].url } } } diff --git a/src/dialogs/qquickfiledialog.cpp b/src/dialogs/qquickfiledialog.cpp index 384642dd0..f2325a530 100644 --- a/src/dialogs/qquickfiledialog.cpp +++ b/src/dialogs/qquickfiledialog.cpp @@ -37,6 +37,7 @@ #include "qquickfiledialog_p.h" #include <QQuickItem> #include <QQmlEngine> +#include <QJSValueIterator> #include <private/qguiapplication_p.h> #include <private/qv4object_p.h> @@ -111,44 +112,70 @@ QList<QUrl> QQuickFileDialog::fileUrls() const return m_selections; } - -void QQuickFileDialog::addShortcut(int &i, const QString &name, const QString &path) +void QQuickFileDialog::addShortcut(uint &i, const QString &name, const QString &visibleName, const QString &path) { QJSEngine *engine = qmlEngine(this); + QUrl url = QUrl::fromLocalFile(path); QJSValue o = engine->newObject(); - o.setProperty("name", name); - o.setProperty("url", QUrl::fromLocalFile(path).toString()); - m_shortcuts.setProperty(i++, o); + o.setProperty("name", visibleName); + // TODO maybe some day QJSValue could directly store a QUrl + o.setProperty("url", url.toString()); + m_shortcutDetails.setProperty(name, o); + m_shortcuts.setProperty(name, url.toString()); + ++i; } -void QQuickFileDialog::addIfReadable(int &i, const QString &name, QStandardPaths::StandardLocation loc) +void QQuickFileDialog::addIfReadable(uint &i, const QString &name, const QString &visibleName, QStandardPaths::StandardLocation loc) { QStringList paths = QStandardPaths::standardLocations(loc); if (!paths.isEmpty() && QDir(paths.first()).isReadable()) - addShortcut(i, name, paths.first()); + addShortcut(i, name, visibleName, paths.first()); +} + +void QQuickFileDialog::populateShortcuts() +{ + QJSEngine *engine = qmlEngine(this); + m_shortcutDetails = engine->newObject(); + m_shortcuts = engine->newObject(); + uint i = 0; + + addIfReadable(i, QLatin1String("desktop"), QStandardPaths::displayName(QStandardPaths::DesktopLocation), QStandardPaths::DesktopLocation); + addIfReadable(i, QLatin1String("documents"), QStandardPaths::displayName(QStandardPaths::DocumentsLocation), QStandardPaths::DocumentsLocation); + addIfReadable(i, QLatin1String("music"), QStandardPaths::displayName(QStandardPaths::MusicLocation), QStandardPaths::MusicLocation); + addIfReadable(i, QLatin1String("movies"), QStandardPaths::displayName(QStandardPaths::MoviesLocation), QStandardPaths::MoviesLocation); + addIfReadable(i, QLatin1String("pictures"), QStandardPaths::displayName(QStandardPaths::PicturesLocation), QStandardPaths::PicturesLocation); + addIfReadable(i, QLatin1String("home"), QStandardPaths::displayName(QStandardPaths::HomeLocation), QStandardPaths::HomeLocation); + +#ifdef Q_OS_IOS + // PicturesLocation is a special URL, which we cannot check with QDir::isReadable() + addShortcut(i, QLatin1String("pictures"), tr("Pictures"), + QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).last()); +#else + // 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(i, fi.absoluteFilePath(), fi.absoluteFilePath(), fi.absoluteFilePath()); +#endif + + m_shortcutDetails.setProperty(QLatin1String("length"), i); } QJSValue QQuickFileDialog::shortcuts() { - if (m_shortcuts.isUndefined()) { - QJSEngine *engine = qmlEngine(this); - m_shortcuts = engine->newArray(); - int i = 0; - - addIfReadable(i, "Desktop", QStandardPaths::DesktopLocation); - addIfReadable(i, "Documents", QStandardPaths::DocumentsLocation); - addIfReadable(i, "Music", QStandardPaths::MusicLocation); - addIfReadable(i, "Movies", QStandardPaths::MoviesLocation); - addIfReadable(i, "Pictures", QStandardPaths::PicturesLocation); - addIfReadable(i, "Home", QStandardPaths::HomeLocation); - - QFileInfoList drives = QDir::drives(); - foreach (QFileInfo fi, drives) - addShortcut(i, fi.absoluteFilePath(), fi.absoluteFilePath()); - } + 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 90eeb2cef..c0ad09a39 100644 --- a/src/dialogs/qquickfiledialog_p.h +++ b/src/dialogs/qquickfiledialog_p.h @@ -58,7 +58,8 @@ class QQuickFileDialog : public QQuickAbstractFileDialog { Q_OBJECT Q_PROPERTY(QQuickItem* contentItem READ contentItem WRITE setContentItem DESIGNABLE false) - Q_PROPERTY(QJSValue shortcuts READ shortcuts CONSTANT) + Q_PROPERTY(QJSValue shortcuts READ shortcuts CONSTANT) // map of QStandardDirectory names to QUrls + Q_PROPERTY(QJSValue __shortcuts READ __shortcuts CONSTANT) // map of details for QML dialog implementations Q_CLASSINFO("DefaultProperty", "contentItem") // AbstractFileDialog in QML can have only one child public: @@ -67,6 +68,7 @@ public: virtual QList<QUrl> fileUrls() const; QJSValue shortcuts(); + QJSValue __shortcuts(); Q_SIGNALS: @@ -80,14 +82,16 @@ protected: Q_INVOKABLE QUrl pathToUrl(const QString &path) { return QUrl::fromLocalFile(path); } Q_INVOKABLE QUrl pathFolder(const QString &path); - void addShortcut(int &i, const QString &name, const QString &path); - void addIfReadable(int &i, const QString &name, QStandardPaths::StandardLocation loc); + void addShortcut(uint &i, const QString &name, const QString &visibleName, const QString &path); + void addIfReadable(uint &i, const QString &name, const QString &visibleName, QStandardPaths::StandardLocation loc); + void populateShortcuts(); private: QList<QUrl> m_selections; Q_DISABLE_COPY(QQuickFileDialog) QJSValue m_shortcuts; + QJSValue m_shortcutDetails; }; QT_END_NAMESPACE |
