diff --git a/interface/resources/qml/dialogs/FileDialog.qml b/interface/resources/qml/dialogs/FileDialog.qml index 4c02c94f03..70841bdda4 100644 --- a/interface/resources/qml/dialogs/FileDialog.qml +++ b/interface/resources/qml/dialogs/FileDialog.qml @@ -6,11 +6,19 @@ import Qt.labs.settings 1.0 import ".." import "../windows" import "../styles" +import "../controls" as VrControls +import "fileDialog" -// Work in progress.... +//FIXME implement shortcuts for favorite location ModalWindow { id: root - HifiConstants { id: hifi } + + property bool selectDirectory: false; + property bool showHidden: false; + // FIXME implement + property bool multiSelect: false; + // FIXME implement + property bool saveDialog: false; signal selectedFile(var file); signal canceled(); @@ -18,149 +26,144 @@ ModalWindow { width: 640 height: 480 - property string settingsName: "" - property alias folder: folderModel.folder + property var helper: fileDialogHelper + property alias model: fileTableView.model property alias filterModel: selectionType.model + property alias folder: model.folder Rectangle { anchors.fill: parent color: "white" - Settings { - // fixme, combine with a property to allow different saved locations - category: "FileOpenLastFolder." + settingsName - property alias folder: folderModel.folder + Row { + id: navControls + anchors { left: parent.left; top: parent.top; margins: 8 } + spacing: 8 + // FIXME implement back button +// VrControls.FontAwesome { +// id: backButton +// text: "\uf0a8" +// size: currentDirectory.height +// enabled: d.backStack.length != 0 +// MouseArea { anchors.fill: parent; onClicked: d.navigateBack() } +// } + VrControls.FontAwesome { + id: upButton + text: "\uf0aa" + size: currentDirectory.height + color: enabled ? "black" : "gray" + MouseArea { anchors.fill: parent; onClicked: d.navigateUp() } + } + VrControls.FontAwesome { + id: homeButton + property var destination: helper.home(); + visible: destination ? true : false + text: "\uf015" + size: currentDirectory.height + MouseArea { anchors.fill: parent; onClicked: model.folder = parent.destination } + } } TextField { id: currentDirectory - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - anchors.margins: 8 - readOnly: true - text: folderModel.folder + anchors { left: navControls.right; right: parent.right; top: parent.top; margins: 8 } + property var lastValidFolder: helper.urlToPath(model.folder) + onLastValidFolderChanged: text = lastValidFolder; + + // FIXME add support auto-completion + onAccepted: { + if (!helper.validFolder(text)) { + text = lastValidFolder; + return + } + model.folder = helper.pathToUrl(text); + } + } - Component { - id: fileItemDelegate - Item { - clip: true - Text { - x: 3 - id: columnText - anchors.verticalCenter: parent.verticalCenter -// font.pointSize: 12 - color: tableView.activeFocus && styleData.row === tableView.currentRow ? "yellow" : styleData.textColor - elide: styleData.elideMode - text: getText(); - font.italic: folderModel.get(styleData.row, "fileIsDir") ? true : false + QtObject { + id: d + property var currentSelectionUrl; + readonly property string currentSelectionPath: helper.urlToPath(currentSelectionUrl); + property bool currentSelectionIsFolder; + property var backStack: [] + property var tableViewConnection: Connections { target: fileTableView; onCurrentRowChanged: d.update(); } + property var modelConnection: Connections { target: model; onFolderChanged: d.update(); } + Component.onCompleted: update(); + function update() { + var row = fileTableView.currentRow; + if (row === -1 && root.selectDirectory) { + currentSelectionUrl = fileTableView.model.folder; + currentSelectionIsFolder = true; + return; + } - Connections { - target: tableView - //onCurrentRowChanged: columnText.color = (tableView.activeFocus && styleData.row === tableView.currentRow ? "yellow" : styleData.textColor) - } + currentSelectionUrl = fileTableView.model.get(row, "fileURL"); + currentSelectionIsFolder = fileTableView.model.isFolder(row); + if (root.selectDirectory || !currentSelectionIsFolder) { + currentSelection.text = helper.urlToPath(currentSelectionUrl); + } + } - function getText() { - switch (styleData.column) { - //case 1: return Date.fromLocaleString(locale, styleData.value, "yyyy-MM-dd hh:mm:ss"); - case 2: return folderModel.get(styleData.row, "fileIsDir") ? "" : formatSize(styleData.value); - default: return styleData.value; - } - } - - function formatSize(size) { - var suffixes = [ "bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" ]; - var suffixIndex = 0 - while ((size / 1024.0) > 1.1) { - size /= 1024.0; - ++suffixIndex; - } - - size = Math.round(size*1000)/1000; - size = size.toLocaleString() - - return size + " " + suffixes[suffixIndex]; - } + function navigateUp() { + if (model.parentFolder && model.parentFolder !== "") { + model.folder = model.parentFolder + return true; } } } - TableView { - id: tableView - focus: true + FileTableView { + id: fileTableView + anchors { left: parent.left; right: parent.right; top: currentDirectory.bottom; bottom: currentSelection.top; margins: 8 } + onDoubleClicked: navigateToRow(row); model: FolderListModel { - id: folderModel - showDotAndDotDot: true + id: model showDirsFirst: true - onFolderChanged: { - tableView.currentRow = -1; - tableView.positionViewAtRow(0, ListView.Beginning) + showDotAndDotDot: false + showFiles: !root.selectDirectory + // For some reason, declaring these bindings directly in the targets doesn't + // work for setting the initial state + Component.onCompleted: { + currentDirectory.lastValidFolder = Qt.binding(function() { return helper.urlToPath(model.folder); }); + upButton.enabled = Qt.binding(function() { return (model.parentFolder && model.parentFolder != "") ? true : false; }); + showFiles = !root.selectDirectory } } - anchors.top: currentDirectory.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: selectionType.top - anchors.margins: 8 - itemDelegate: fileItemDelegate -// rowDelegate: Rectangle { -// id: rowDelegate -// color: styleData.selected ? "#7f0000ff" : "#00000000" -// Connections { target: folderModel; onFolderChanged: rowDelegate.visible = false } -// Connections { target: tableView; onCurrentRowChanged: rowDelegate.visible = true; } -// } - TableViewColumn { - role: "fileName" - title: "Name" - width: 400 - } - TableViewColumn { - role: "fileModified" - title: "Date Modified" - width: 200 - } - TableViewColumn { - role: "fileSize" - title: "Size" - width: 200 + function navigateToRow(row) { + currentRow = row; + navigateToCurrentRow(); } - Keys.onReturnPressed: selectCurrentFile(); - onDoubleClicked: { currentRow = row; selectCurrentFile(); } - onCurrentRowChanged: currentSelection.text = model.get(currentRow, "fileName"); - KeyNavigation.left: cancelButton - KeyNavigation.right: selectionType + function navigateToCurrentRow() { + var row = fileTableView.currentRow + var isFolder = model.isFolder(row); + var file = model.get(row, "fileURL"); + if (isFolder) { + fileTableView.model.folder = file + currentRow = -1; + } else { + root.selectedFile(file); + root.close(); + } + } } - TextField { id: currentSelection - anchors.right: selectionType.left - anchors.rightMargin: 8 - anchors.left: parent.left - anchors.leftMargin: 8 - anchors.top: selectionType.top + anchors { right: root.selectDirectory ? parent.right : selectionType.left; rightMargin: 8; left: parent.left; leftMargin: 8; top: selectionType.top } + readOnly: true } ComboBox { id: selectionType - anchors.bottom: buttonRow.top - anchors.bottomMargin: 8 - anchors.right: parent.right - anchors.rightMargin: 8 - anchors.left: buttonRow.left - - model: ListModel { - ListElement { text: "All Files (*.*)"; filter: "*.*" } - } - - onCurrentIndexChanged: { - folderModel.nameFilters = [ filterModel.get(currentIndex).filter ] - } - KeyNavigation.left: tableView + anchors { bottom: buttonRow.top; bottomMargin: 8; right: parent.right; rightMargin: 8; left: buttonRow.left } + visible: !selectDirectory + model: ListModel { ListElement { text: "All Files (*.*)"; filter: "*.*" } } +// onCurrentIndexChanged: model.nameFilters = [ filterModel.get(currentIndex).filter ] + KeyNavigation.left: fileTableView KeyNavigation.right: openButton } @@ -177,16 +180,16 @@ ModalWindow { text: "Cancel" KeyNavigation.up: selectionType KeyNavigation.left: openButton - KeyNavigation.right: tableView.contentItem + KeyNavigation.right: fileTableView.contentItem Keys.onReturnPressed: { canceled(); root.enabled = false } onClicked: { canceled(); close() } } Button { id: openButton - text: "Open" - enabled: tableView.currentRow != -1 && !folderModel.get(tableView.currentRow, "fileIsDir") - onClicked: selectCurrentFile(); - Keys.onReturnPressed: selectCurrentFile(); + text: root.selectDirectory ? "Choose" : "Open" + enabled: currentSelection.text ? true : false + onClicked: { selectedFile(d.currentSelectionUrl); close(); } + Keys.onReturnPressed: { selectedFile(d.currentSelectionUrl); close(); } KeyNavigation.up: selectionType KeyNavigation.left: selectionType @@ -195,26 +198,8 @@ ModalWindow { } } - function selectCurrentFile() { - var row = tableView.currentRow - console.log("Selecting row " + row) - var fileName = folderModel.get(row, "fileName"); - if (fileName === "..") { - folderModel.folder = folderModel.parentFolder - } else if (folderModel.isFolder(row)) { - folderModel.folder = folderModel.get(row, "fileURL"); - } else { - selectedFile(folderModel.get(row, "fileURL")); - close(); - } - - } - - Keys.onPressed: { - if (event.key === Qt.Key_Backspace && folderModel.parentFolder && folderModel.parentFolder != "") { - console.log("Navigating to " + folderModel.parentFolder) - folderModel.folder = folderModel.parentFolder + if (event.key === Qt.Key_Backspace && d.navigateUp()) { event.accepted = true } } diff --git a/interface/resources/qml/dialogs/fileDialog/FileTableView.qml b/interface/resources/qml/dialogs/fileDialog/FileTableView.qml new file mode 100644 index 0000000000..aa5264ad34 --- /dev/null +++ b/interface/resources/qml/dialogs/fileDialog/FileTableView.qml @@ -0,0 +1,59 @@ +import QtQuick 2.0 +import QtQuick.Controls 1.4 + +TableView { + id: root + + itemDelegate: Component { + Item { + clip: true + Text { + x: 3 + anchors.verticalCenter: parent.verticalCenter + color: root.activeFocus && styleData.row === root.currentRow ? "yellow" : styleData.textColor + elide: styleData.elideMode + text: getText(); + font.italic: root.model.get(styleData.row, "fileIsDir") ? true : false + + function getText() { + switch (styleData.column) { + //case 1: return Date.fromLocaleString(locale, styleData.value, "yyyy-MM-dd hh:mm:ss"); + case 2: return root.model.get(styleData.row, "fileIsDir") ? "" : formatSize(styleData.value); + default: return styleData.value; + } + } + function formatSize(size) { + var suffixes = [ "bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" ]; + var suffixIndex = 0 + while ((size / 1024.0) > 1.1) { + size /= 1024.0; + ++suffixIndex; + } + + size = Math.round(size*1000)/1000; + size = size.toLocaleString() + + return size + " " + suffixes[suffixIndex]; + } + } + } + } + + TableViewColumn { + role: "fileName" + title: "Name" + width: 400 + } + TableViewColumn { + role: "fileModified" + title: "Date Modified" + width: 200 + } + TableViewColumn { + role: "fileSize" + title: "Size" + width: 200 + } +} + + diff --git a/interface/resources/qml/hifi/dialogs/preferences/Avatar.qml b/interface/resources/qml/hifi/dialogs/preferences/Avatar.qml new file mode 100644 index 0000000000..9c19b80357 --- /dev/null +++ b/interface/resources/qml/hifi/dialogs/preferences/Avatar.qml @@ -0,0 +1,33 @@ +import QtQuick 2.5 +import QtQuick.Controls 1.4 as Original +import "." + +Preference { + id: root + property alias spinner: spinner + height: spinner.height + + + Component.onCompleted: { + spinner.value = preference.value; + } + + function save() { + preference.value = spinner.value; + preference.save(); + } + + Text { + text: root.label + anchors.verticalCenter: spinner.verticalCenter + } + + Original.SpinBox { + id: spinner + decimals: preference.decimals + minimumValue: preference.min + maximumValue: preference.max + width: 100 + anchors { right: parent.right } + } +} diff --git a/interface/resources/qml/hifi/dialogs/preferences/AvatarBrowser.qml b/interface/resources/qml/hifi/dialogs/preferences/AvatarBrowser.qml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/libraries/ui/src/FileDialogHelper.cpp b/libraries/ui/src/FileDialogHelper.cpp new file mode 100644 index 0000000000..f8a0929702 --- /dev/null +++ b/libraries/ui/src/FileDialogHelper.cpp @@ -0,0 +1,40 @@ +// +// OffscreenUi.cpp +// interface/src/render-utils +// +// Created by Bradley Austin Davis on 2015-04-04 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#include "FileDialogHelper.h" + +#include +#include + + +QUrl FileDialogHelper::home() { + return pathToUrl(QStandardPaths::standardLocations(QStandardPaths::HomeLocation)[0]); +} + +QStringList FileDialogHelper::standardPath(StandardLocation location) { + return QStandardPaths::standardLocations(static_cast(location)); +} + +QString FileDialogHelper::urlToPath(const QUrl& url) { + return url.toLocalFile(); +} + +bool FileDialogHelper::validPath(const QString& path) { + return QFile(path).exists(); +} + +bool FileDialogHelper::validFolder(const QString& path) { + return QDir(path).exists(); +} + +QUrl FileDialogHelper::pathToUrl(const QString& path) { + return QUrl::fromLocalFile(path); +} + diff --git a/libraries/ui/src/FileDialogHelper.h b/libraries/ui/src/FileDialogHelper.h new file mode 100644 index 0000000000..edb702eeda --- /dev/null +++ b/libraries/ui/src/FileDialogHelper.h @@ -0,0 +1,57 @@ +// +// Created by Bradley Austin Davis on 2016-01-21 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#pragma once +#ifndef hifi_ui_FileDialogHelper_h +#define hifi_ui_FileDialogHelper_h + +#include +#include +#include +#include +#include + + +class FileDialogHelper : public QObject { + Q_OBJECT + Q_ENUMS(StandardLocation) + +public: + // Do not re-order, must match QDesktopServices + enum StandardLocation { + DesktopLocation, + DocumentsLocation, + FontsLocation, + ApplicationsLocation, + MusicLocation, + MoviesLocation, + PicturesLocation, + TempLocation, + HomeLocation, + DataLocation, + CacheLocation, + GenericDataLocation, + RuntimeLocation, + ConfigLocation, + DownloadLocation, + GenericCacheLocation, + GenericConfigLocation, + AppDataLocation, + AppConfigLocation, + AppLocalDataLocation = DataLocation + }; + + Q_INVOKABLE QUrl home(); + Q_INVOKABLE QStringList standardPath(StandardLocation location); + Q_INVOKABLE QString urlToPath(const QUrl& url); + Q_INVOKABLE bool validPath(const QString& path); + Q_INVOKABLE bool validFolder(const QString& path); + Q_INVOKABLE QUrl pathToUrl(const QString& path); +}; + + +#endif diff --git a/libraries/ui/src/OffscreenUi.cpp b/libraries/ui/src/OffscreenUi.cpp index 047c55be37..70a07db664 100644 --- a/libraries/ui/src/OffscreenUi.cpp +++ b/libraries/ui/src/OffscreenUi.cpp @@ -17,8 +17,10 @@ #include #include +#include "FileDialogHelper.h" #include "VrMenu.h" + // Needs to match the constants in resources/qml/Global.js class OffscreenFlags : public QObject { Q_OBJECT @@ -74,7 +76,6 @@ public: } }; -static UrlHandler * urlHandler { nullptr }; static OffscreenFlags* offscreenFlags { nullptr }; // This hack allows the QML UI to work with keys that are also bound as @@ -102,10 +103,9 @@ void OffscreenUi::create(QOpenGLContext* context) { OffscreenQmlSurface::create(context); auto rootContext = getRootContext(); - offscreenFlags = new OffscreenFlags(); - rootContext->setContextProperty("offscreenFlags", offscreenFlags); - urlHandler = new UrlHandler(); - rootContext->setContextProperty("urlHandler", urlHandler); + rootContext->setContextProperty("offscreenFlags", offscreenFlags = new OffscreenFlags()); + rootContext->setContextProperty("urlHandler", new UrlHandler()); + rootContext->setContextProperty("fileDialogHelper", new FileDialogHelper()); } void OffscreenUi::show(const QUrl& url, const QString& name, std::function f) { diff --git a/tests/ui/qml/Stubs.qml b/tests/ui/qml/Stubs.qml index f46fad3652..3f60876e81 100644 --- a/tests/ui/qml/Stubs.qml +++ b/tests/ui/qml/Stubs.qml @@ -5,6 +5,11 @@ import QtQuick.Controls 1.4 // This is useful for testing inside Qt creator where these services don't actually exist. Item { + Item { + objectName: "offscreenFlags" + property bool navigationFocused: false + } + Item { objectName: "urlHandler" function fixupUrl(url) { return url; } diff --git a/tests/ui/qml/main.qml b/tests/ui/qml/main.qml index 9bc919437f..b6a6b47814 100644 --- a/tests/ui/qml/main.qml +++ b/tests/ui/qml/main.qml @@ -16,34 +16,18 @@ ApplicationWindow { height: 720 title: qsTr("Scratch App") - Component { id: listModelBuilder; ListModel{} } - - function menuItemsToModel(menu) { - var items = menu.items - var newListModel = listModelBuilder.createObject(desktop); - for (var i = 0; i < items.length; ++i) { - var item = items[i]; - switch (item.type) { - case 2: - newListModel.append({"type":item.type, "name": item.title, "item": item}) - break; - case 1: - newListModel.append({"type":item.type, "name": item.text, "item": item}) - break; - case 0: - newListModel.append({"type":item.type, "name": "-----", "item": item}) - break; - } - } - return newListModel; - } - Desktop { id: desktop anchors.fill: parent - StubMenu { id: stubMenu } + rootMenu: StubMenu { id: rootMenu } Component.onCompleted: offscreenWindow = appWindow + MouseArea { + anchors.fill: parent + acceptedButtons: Qt.RightButton + onClicked: desktop.popupMenu(Qt.vector2d(mouseX, mouseY)); + } + Row { id: testButtons anchors { margins: 8; left: parent.left; top: parent.top } @@ -52,6 +36,7 @@ ApplicationWindow { property var tabs: []; property var urls: []; + /* Button { text: "restore all" onClicked: { @@ -72,6 +57,7 @@ ApplicationWindow { blue.enabled = !blue.enabled } } + */ Button { text: "Show Long Error" onClicked: { @@ -93,21 +79,13 @@ ApplicationWindow { } } Button { - text: "Open File" + text: "Open Directory" property var builder: Component { - FileDialog { } + FileDialog { selectDirectory: true } } - ListModel { - id: jsFilters - ListElement { text: "Javascript Files (*.js)"; filter: "*.js" } - ListElement { text: "All Files (*.*)"; filter: "*.*" } - } onClicked: { - var fileDialogProperties = { - filterModel: jsFilters - } - var fileDialog = builder.createObject(desktop, fileDialogProperties); + var fileDialog = builder.createObject(desktop); fileDialog.canceled.connect(function(){ console.log("Cancelled") }) @@ -116,24 +94,31 @@ ApplicationWindow { }) } } + Button { - text: "Focus Test" + text: "Open File" + property var builder: Component { + FileDialog { + folder: "file:///C:/users/bdavis"; + filterModel: ListModel { + ListElement { text: "Javascript Files (*.js)"; filter: "*.js" } + ListElement { text: "All Files (*.*)"; filter: "*.*" } + } + } + } + onClicked: { - var item = desktop; - while (item) { - console.log(item); - item = item.parent; - } - item = appWindow - while (item) { - console.log(item); - item = item.parent; - } - console.log(appWindow.activeFocusItem); + var fileDialog = builder.createObject(desktop); + fileDialog.canceled.connect(function(){ + console.log("Cancelled") + }) + fileDialog.selectedFile.connect(function(file){ + console.log("Selected " + file) + }) } } } - +/* Window { id: blue closable: true @@ -189,109 +174,6 @@ ApplicationWindow { color: "yellow" } } + */ } - - /* - Arcane.Test { - anchors.centerIn: parent - height: 600; width: 600 - } - - - Item { - id: desktop - anchors.fill: parent - objectName: Desktop._OFFSCREEN_ROOT_OBJECT_NAME - property bool uiVisible: true - property variant toolbars: { "_root" : null } - focus: true - - - - Rectangle { - id: root - Vr.Constants { id: vr } - implicitWidth: 384; implicitHeight: 640 - anchors.centerIn: parent - color: vr.windows.colors.background - border.color: vr.controls.colors.background - border.width: vr.styles.borderWidth - radius: vr.styles.borderRadius - RunningScripts { } - } - - FileDialog { - id: fileDialog - width: 800; height: 600 - anchors.centerIn: parent - onSelectedFile: console.log("Chose file " + file) - } - Timer { - id: timer - running: false - interval: 100 - onTriggered: wireFrameContainer.enabled = true - } - - Item { - id: wireFrameContainer - objectName: Desktop._OFFSCREEN_DIALOG_OBJECT_NAME - anchors.fill: parent - onEnabledChanged: if (!enabled) timer.running = true - - NewUi.Main { - id: wireFrame - anchors.fill: parent - - property var offscreenFlags: Item { - property bool navigationFocused: false - } - - property var urlHandler: Item { - function fixupUrl(url) { - var urlString = url.toString(); - if (urlString.indexOf("https://metaverse.highfidelity.com/") !== -1 && - urlString.indexOf("access_token") === -1) { - console.log("metaverse URL, fixing") - return urlString + "?access_token=875885020b1d5f1ea694ce971c8601fa33ffd77f61851be01ed1e3fde8cabbe9" - } - return url - } - - function canHandleUrl(url) { - var urlString = url.toString(); - if (urlString.indexOf("hifi://") === 0) { - console.log("Can handle hifi addresses: " + urlString) - return true; - } - - if (urlString.indexOf(".svo.json?") !== -1) { - console.log("Can handle svo json addresses: " + urlString) - return true; - } - - if (urlString.indexOf(".js?") !== -1) { - console.log("Can handle javascript addresses: " + urlString) - return true; - } - - return false - } - - function handleUrl(url) { - return true - } - } - - property var addressManager: Item { - function navigate(url) { - console.log("Navigate to: " + url); - } - } - } - } - Keys.onMenuPressed: desktop.uiVisible = !desktop.uiVisible - Keys.onEscapePressed: desktop.uiVisible = !desktop.uiVisible - } -*/ } diff --git a/tests/ui/qmlscratch.pro b/tests/ui/qmlscratch.pro index 156833ce4e..81974ffee8 100644 --- a/tests/ui/qmlscratch.pro +++ b/tests/ui/qmlscratch.pro @@ -4,7 +4,8 @@ QT += gui qml quick xml webengine widgets CONFIG += c++11 -SOURCES += src/main.cpp +SOURCES += src/main.cpp \ + ../../libraries/ui/src/FileDialogHelper.cpp # Additional import path used to resolve QML modules in Qt Creator's code model QML_IMPORT_PATH = @@ -96,4 +97,10 @@ DISTFILES += \ ../../interface/resources/qml/hifi/dialogs/preferences/Slider.qml \ ../../interface/resources/qml/hifi/dialogs/preferences/Preference.qml \ ../../interface/resources/qml/hifi/dialogs/preferences/SpinBox.qml \ - ../../interface/resources/qml/hifi/dialogs/preferences/CheckBox.qml + ../../interface/resources/qml/hifi/dialogs/preferences/CheckBox.qml \ + ../../interface/resources/qml/dialogs/fileDialog/FileTableView.qml \ + ../../interface/resources/qml/hifi/dialogs/preferences/Avatar.qml \ + ../../interface/resources/qml/hifi/dialogs/preferences/AvatarBrowser.qml + +HEADERS += \ + ../../libraries/ui/src/FileDialogHelper.h diff --git a/tests/ui/src/main.cpp b/tests/ui/src/main.cpp index 70738b974c..19c0626164 100644 --- a/tests/ui/src/main.cpp +++ b/tests/ui/src/main.cpp @@ -3,6 +3,7 @@ #include #include +#include "../../../libraries/ui/src/FileDialogHelper.h" class Preference : public QObject { @@ -82,13 +83,14 @@ int main(int argc, char *argv[]) { addImportPath(engine, "../../../interface/resources/qml"); engine.load(QUrl(QStringLiteral("qml/Stubs.qml"))); - setChild(engine, "rootMenu"); + setChild(engine, "offscreenFlags"); setChild(engine, "Account"); setChild(engine, "Desktop"); setChild(engine, "ScriptDiscoveryService"); setChild(engine, "MenuHelper"); setChild(engine, "urlHandler"); engine.rootContext()->setContextProperty("DebugQML", true); + engine.rootContext()->setContextProperty("fileDialogHelper", new FileDialogHelper()); //engine.load(QUrl(QStringLiteral("qrc:/qml/gallery/main.qml"))); engine.load(QUrl(QStringLiteral("qml/main.qml")));