Support for directory browsing

This commit is contained in:
Brad Davis 2016-01-22 00:31:05 -08:00
parent 2026821d9e
commit c7186590ea
11 changed files with 364 additions and 294 deletions

View file

@ -6,11 +6,19 @@ import Qt.labs.settings 1.0
import ".." import ".."
import "../windows" import "../windows"
import "../styles" import "../styles"
import "../controls" as VrControls
import "fileDialog"
// Work in progress.... //FIXME implement shortcuts for favorite location
ModalWindow { ModalWindow {
id: root 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 selectedFile(var file);
signal canceled(); signal canceled();
@ -18,149 +26,144 @@ ModalWindow {
width: 640 width: 640
height: 480 height: 480
property string settingsName: "" property var helper: fileDialogHelper
property alias folder: folderModel.folder property alias model: fileTableView.model
property alias filterModel: selectionType.model property alias filterModel: selectionType.model
property alias folder: model.folder
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
color: "white" color: "white"
Settings { Row {
// fixme, combine with a property to allow different saved locations id: navControls
category: "FileOpenLastFolder." + settingsName anchors { left: parent.left; top: parent.top; margins: 8 }
property alias folder: folderModel.folder 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 { TextField {
id: currentDirectory id: currentDirectory
anchors.left: parent.left anchors { left: navControls.right; right: parent.right; top: parent.top; margins: 8 }
anchors.right: parent.right property var lastValidFolder: helper.urlToPath(model.folder)
anchors.top: parent.top onLastValidFolderChanged: text = lastValidFolder;
anchors.margins: 8
readOnly: true // FIXME add support auto-completion
text: folderModel.folder onAccepted: {
if (!helper.validFolder(text)) {
text = lastValidFolder;
return
}
model.folder = helper.pathToUrl(text);
}
} }
Component { QtObject {
id: fileItemDelegate id: d
Item { property var currentSelectionUrl;
clip: true readonly property string currentSelectionPath: helper.urlToPath(currentSelectionUrl);
Text { property bool currentSelectionIsFolder;
x: 3 property var backStack: []
id: columnText property var tableViewConnection: Connections { target: fileTableView; onCurrentRowChanged: d.update(); }
anchors.verticalCenter: parent.verticalCenter property var modelConnection: Connections { target: model; onFolderChanged: d.update(); }
// font.pointSize: 12 Component.onCompleted: update();
color: tableView.activeFocus && styleData.row === tableView.currentRow ? "yellow" : styleData.textColor
elide: styleData.elideMode
text: getText();
font.italic: folderModel.get(styleData.row, "fileIsDir") ? true : false
function update() {
var row = fileTableView.currentRow;
if (row === -1 && root.selectDirectory) {
currentSelectionUrl = fileTableView.model.folder;
currentSelectionIsFolder = true;
return;
}
Connections { currentSelectionUrl = fileTableView.model.get(row, "fileURL");
target: tableView currentSelectionIsFolder = fileTableView.model.isFolder(row);
//onCurrentRowChanged: columnText.color = (tableView.activeFocus && styleData.row === tableView.currentRow ? "yellow" : styleData.textColor) if (root.selectDirectory || !currentSelectionIsFolder) {
} currentSelection.text = helper.urlToPath(currentSelectionUrl);
}
}
function getText() { function navigateUp() {
switch (styleData.column) { if (model.parentFolder && model.parentFolder !== "") {
//case 1: return Date.fromLocaleString(locale, styleData.value, "yyyy-MM-dd hh:mm:ss"); model.folder = model.parentFolder
case 2: return folderModel.get(styleData.row, "fileIsDir") ? "" : formatSize(styleData.value); return true;
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];
}
} }
} }
} }
TableView { FileTableView {
id: tableView id: fileTableView
focus: true anchors { left: parent.left; right: parent.right; top: currentDirectory.bottom; bottom: currentSelection.top; margins: 8 }
onDoubleClicked: navigateToRow(row);
model: FolderListModel { model: FolderListModel {
id: folderModel id: model
showDotAndDotDot: true
showDirsFirst: true showDirsFirst: true
onFolderChanged: { showDotAndDotDot: false
tableView.currentRow = -1; showFiles: !root.selectDirectory
tableView.positionViewAtRow(0, ListView.Beginning) // 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 { function navigateToRow(row) {
role: "fileName" currentRow = row;
title: "Name" navigateToCurrentRow();
width: 400
}
TableViewColumn {
role: "fileModified"
title: "Date Modified"
width: 200
}
TableViewColumn {
role: "fileSize"
title: "Size"
width: 200
} }
Keys.onReturnPressed: selectCurrentFile(); function navigateToCurrentRow() {
onDoubleClicked: { currentRow = row; selectCurrentFile(); } var row = fileTableView.currentRow
onCurrentRowChanged: currentSelection.text = model.get(currentRow, "fileName"); var isFolder = model.isFolder(row);
KeyNavigation.left: cancelButton var file = model.get(row, "fileURL");
KeyNavigation.right: selectionType if (isFolder) {
fileTableView.model.folder = file
currentRow = -1;
} else {
root.selectedFile(file);
root.close();
}
}
} }
TextField { TextField {
id: currentSelection id: currentSelection
anchors.right: selectionType.left anchors { right: root.selectDirectory ? parent.right : selectionType.left; rightMargin: 8; left: parent.left; leftMargin: 8; top: selectionType.top }
anchors.rightMargin: 8 readOnly: true
anchors.left: parent.left
anchors.leftMargin: 8
anchors.top: selectionType.top
} }
ComboBox { ComboBox {
id: selectionType id: selectionType
anchors.bottom: buttonRow.top anchors { bottom: buttonRow.top; bottomMargin: 8; right: parent.right; rightMargin: 8; left: buttonRow.left }
anchors.bottomMargin: 8 visible: !selectDirectory
anchors.right: parent.right model: ListModel { ListElement { text: "All Files (*.*)"; filter: "*.*" } }
anchors.rightMargin: 8 // onCurrentIndexChanged: model.nameFilters = [ filterModel.get(currentIndex).filter ]
anchors.left: buttonRow.left KeyNavigation.left: fileTableView
model: ListModel {
ListElement { text: "All Files (*.*)"; filter: "*.*" }
}
onCurrentIndexChanged: {
folderModel.nameFilters = [ filterModel.get(currentIndex).filter ]
}
KeyNavigation.left: tableView
KeyNavigation.right: openButton KeyNavigation.right: openButton
} }
@ -177,16 +180,16 @@ ModalWindow {
text: "Cancel" text: "Cancel"
KeyNavigation.up: selectionType KeyNavigation.up: selectionType
KeyNavigation.left: openButton KeyNavigation.left: openButton
KeyNavigation.right: tableView.contentItem KeyNavigation.right: fileTableView.contentItem
Keys.onReturnPressed: { canceled(); root.enabled = false } Keys.onReturnPressed: { canceled(); root.enabled = false }
onClicked: { canceled(); close() } onClicked: { canceled(); close() }
} }
Button { Button {
id: openButton id: openButton
text: "Open" text: root.selectDirectory ? "Choose" : "Open"
enabled: tableView.currentRow != -1 && !folderModel.get(tableView.currentRow, "fileIsDir") enabled: currentSelection.text ? true : false
onClicked: selectCurrentFile(); onClicked: { selectedFile(d.currentSelectionUrl); close(); }
Keys.onReturnPressed: selectCurrentFile(); Keys.onReturnPressed: { selectedFile(d.currentSelectionUrl); close(); }
KeyNavigation.up: selectionType KeyNavigation.up: selectionType
KeyNavigation.left: 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: { Keys.onPressed: {
if (event.key === Qt.Key_Backspace && folderModel.parentFolder && folderModel.parentFolder != "") { if (event.key === Qt.Key_Backspace && d.navigateUp()) {
console.log("Navigating to " + folderModel.parentFolder)
folderModel.folder = folderModel.parentFolder
event.accepted = true event.accepted = true
} }
} }

View file

@ -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
}
}

View file

@ -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 }
}
}

View file

@ -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 <QtCore/QDir>
#include <QtCore/QFile>
QUrl FileDialogHelper::home() {
return pathToUrl(QStandardPaths::standardLocations(QStandardPaths::HomeLocation)[0]);
}
QStringList FileDialogHelper::standardPath(StandardLocation location) {
return QStandardPaths::standardLocations(static_cast<QStandardPaths::StandardLocation>(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);
}

View file

@ -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 <QtCore/QObject>
#include <QtCore/QStandardPaths>
#include <QtCore/QUrl>
#include <QtCore/QString>
#include <QtCore/QStringList>
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

View file

@ -17,8 +17,10 @@
#include <AbstractUriHandler.h> #include <AbstractUriHandler.h>
#include <AccountManager.h> #include <AccountManager.h>
#include "FileDialogHelper.h"
#include "VrMenu.h" #include "VrMenu.h"
// Needs to match the constants in resources/qml/Global.js // Needs to match the constants in resources/qml/Global.js
class OffscreenFlags : public QObject { class OffscreenFlags : public QObject {
Q_OBJECT Q_OBJECT
@ -74,7 +76,6 @@ public:
} }
}; };
static UrlHandler * urlHandler { nullptr };
static OffscreenFlags* offscreenFlags { nullptr }; static OffscreenFlags* offscreenFlags { nullptr };
// This hack allows the QML UI to work with keys that are also bound as // 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); OffscreenQmlSurface::create(context);
auto rootContext = getRootContext(); auto rootContext = getRootContext();
offscreenFlags = new OffscreenFlags(); rootContext->setContextProperty("offscreenFlags", offscreenFlags = new OffscreenFlags());
rootContext->setContextProperty("offscreenFlags", offscreenFlags); rootContext->setContextProperty("urlHandler", new UrlHandler());
urlHandler = new UrlHandler(); rootContext->setContextProperty("fileDialogHelper", new FileDialogHelper());
rootContext->setContextProperty("urlHandler", urlHandler);
} }
void OffscreenUi::show(const QUrl& url, const QString& name, std::function<void(QQmlContext*, QObject*)> f) { void OffscreenUi::show(const QUrl& url, const QString& name, std::function<void(QQmlContext*, QObject*)> f) {

View file

@ -5,6 +5,11 @@ import QtQuick.Controls 1.4
// This is useful for testing inside Qt creator where these services don't actually exist. // This is useful for testing inside Qt creator where these services don't actually exist.
Item { Item {
Item {
objectName: "offscreenFlags"
property bool navigationFocused: false
}
Item { Item {
objectName: "urlHandler" objectName: "urlHandler"
function fixupUrl(url) { return url; } function fixupUrl(url) { return url; }

View file

@ -16,34 +16,18 @@ ApplicationWindow {
height: 720 height: 720
title: qsTr("Scratch App") 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 { Desktop {
id: desktop id: desktop
anchors.fill: parent anchors.fill: parent
StubMenu { id: stubMenu } rootMenu: StubMenu { id: rootMenu }
Component.onCompleted: offscreenWindow = appWindow Component.onCompleted: offscreenWindow = appWindow
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.RightButton
onClicked: desktop.popupMenu(Qt.vector2d(mouseX, mouseY));
}
Row { Row {
id: testButtons id: testButtons
anchors { margins: 8; left: parent.left; top: parent.top } anchors { margins: 8; left: parent.left; top: parent.top }
@ -52,6 +36,7 @@ ApplicationWindow {
property var tabs: []; property var tabs: [];
property var urls: []; property var urls: [];
/*
Button { Button {
text: "restore all" text: "restore all"
onClicked: { onClicked: {
@ -72,6 +57,7 @@ ApplicationWindow {
blue.enabled = !blue.enabled blue.enabled = !blue.enabled
} }
} }
*/
Button { Button {
text: "Show Long Error" text: "Show Long Error"
onClicked: { onClicked: {
@ -93,21 +79,13 @@ ApplicationWindow {
} }
} }
Button { Button {
text: "Open File" text: "Open Directory"
property var builder: Component { property var builder: Component {
FileDialog { } FileDialog { selectDirectory: true }
} }
ListModel {
id: jsFilters
ListElement { text: "Javascript Files (*.js)"; filter: "*.js" }
ListElement { text: "All Files (*.*)"; filter: "*.*" }
}
onClicked: { onClicked: {
var fileDialogProperties = { var fileDialog = builder.createObject(desktop);
filterModel: jsFilters
}
var fileDialog = builder.createObject(desktop, fileDialogProperties);
fileDialog.canceled.connect(function(){ fileDialog.canceled.connect(function(){
console.log("Cancelled") console.log("Cancelled")
}) })
@ -116,24 +94,31 @@ ApplicationWindow {
}) })
} }
} }
Button { 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: { onClicked: {
var item = desktop; var fileDialog = builder.createObject(desktop);
while (item) { fileDialog.canceled.connect(function(){
console.log(item); console.log("Cancelled")
item = item.parent; })
} fileDialog.selectedFile.connect(function(file){
item = appWindow console.log("Selected " + file)
while (item) { })
console.log(item);
item = item.parent;
}
console.log(appWindow.activeFocusItem);
} }
} }
} }
/*
Window { Window {
id: blue id: blue
closable: true closable: true
@ -189,109 +174,6 @@ ApplicationWindow {
color: "yellow" 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
}
*/
} }

View file

@ -4,7 +4,8 @@ QT += gui qml quick xml webengine widgets
CONFIG += c++11 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 # Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH = QML_IMPORT_PATH =
@ -96,4 +97,10 @@ DISTFILES += \
../../interface/resources/qml/hifi/dialogs/preferences/Slider.qml \ ../../interface/resources/qml/hifi/dialogs/preferences/Slider.qml \
../../interface/resources/qml/hifi/dialogs/preferences/Preference.qml \ ../../interface/resources/qml/hifi/dialogs/preferences/Preference.qml \
../../interface/resources/qml/hifi/dialogs/preferences/SpinBox.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

View file

@ -3,6 +3,7 @@
#include <QtWebEngine> #include <QtWebEngine>
#include <QFileSystemModel> #include <QFileSystemModel>
#include "../../../libraries/ui/src/FileDialogHelper.h"
class Preference : public QObject { class Preference : public QObject {
@ -82,13 +83,14 @@ int main(int argc, char *argv[]) {
addImportPath(engine, "../../../interface/resources/qml"); addImportPath(engine, "../../../interface/resources/qml");
engine.load(QUrl(QStringLiteral("qml/Stubs.qml"))); engine.load(QUrl(QStringLiteral("qml/Stubs.qml")));
setChild(engine, "rootMenu"); setChild(engine, "offscreenFlags");
setChild(engine, "Account"); setChild(engine, "Account");
setChild(engine, "Desktop"); setChild(engine, "Desktop");
setChild(engine, "ScriptDiscoveryService"); setChild(engine, "ScriptDiscoveryService");
setChild(engine, "MenuHelper"); setChild(engine, "MenuHelper");
setChild(engine, "urlHandler"); setChild(engine, "urlHandler");
engine.rootContext()->setContextProperty("DebugQML", true); engine.rootContext()->setContextProperty("DebugQML", true);
engine.rootContext()->setContextProperty("fileDialogHelper", new FileDialogHelper());
//engine.load(QUrl(QStringLiteral("qrc:/qml/gallery/main.qml"))); //engine.load(QUrl(QStringLiteral("qrc:/qml/gallery/main.qml")));
engine.load(QUrl(QStringLiteral("qml/main.qml"))); engine.load(QUrl(QStringLiteral("qml/main.qml")));