diff --git a/mix/CMakeLists.txt b/mix/CMakeLists.txt
index 44cd9c12a..874656f89 100644
--- a/mix/CMakeLists.txt
+++ b/mix/CMakeLists.txt
@@ -20,6 +20,11 @@ if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") AND NOT (CMAKE_CXX_COMPILER_VER
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-inconsistent-missing-override")
endif ()
+#TODO: remove once qt 5.5.1 is out
+if (APPLE)
+ qt5_add_resources(UI_RESOURCES osx.qrc)
+endif()
+
find_package (Qt5WebEngine)
if (APPLE)
# TODO: remove indirect dependencies once macdeployqt is fixed
diff --git a/mix/FileIo.cpp b/mix/FileIo.cpp
index 1c9faa896..525715d5a 100644
--- a/mix/FileIo.cpp
+++ b/mix/FileIo.cpp
@@ -224,3 +224,11 @@ void FileIo::deleteFile(QString const& _path)
QFile file(pathFromUrl(_path));
file.remove();
}
+
+QUrl FileIo::pathFolder(QString const& _path)
+{
+ QFileInfo info(_path);
+ if (info.exists() && info.isDir())
+ return QUrl::fromLocalFile(_path);
+ return QUrl::fromLocalFile(QFileInfo(_path).absolutePath());
+}
diff --git a/mix/FileIo.h b/mix/FileIo.h
index eb5bc6cad..0db399a73 100644
--- a/mix/FileIo.h
+++ b/mix/FileIo.h
@@ -71,6 +71,11 @@ public:
/// delete a directory
Q_INVOKABLE void deleteDir(QString const& _url);
+ //TODO: remove once qt 5.5.1 is out
+ Q_INVOKABLE QString urlToPath(QUrl const& _url) { return _url.toLocalFile(); }
+ Q_INVOKABLE QUrl pathToUrl(QString const& _path) { return QUrl::fromLocalFile(_path); }
+ Q_INVOKABLE QUrl pathFolder(QString const& _path);
+
private:
QString getHomePath() const;
QString pathFromUrl(QString const& _url);
diff --git a/mix/MixApplication.cpp b/mix/MixApplication.cpp
index d81a4f6b2..4972b6cf5 100644
--- a/mix/MixApplication.cpp
+++ b/mix/MixApplication.cpp
@@ -41,6 +41,9 @@
extern int qInitResources_js();
using namespace dev::mix;
+
+
+
ApplicationService::ApplicationService()
{
#ifdef ETH_HAVE_WEBENGINE
diff --git a/mix/MixClient.cpp b/mix/MixClient.cpp
index 4f4139701..89b749629 100644
--- a/mix/MixClient.cpp
+++ b/mix/MixClient.cpp
@@ -284,7 +284,7 @@ void MixClient::mine()
RLPStream header;
h.streamRLP(header);
m_postMine.sealBlock(header.out());
- bc().import(m_postMine.blockData(), m_stateDB, ImportRequirements::Everything & ~ImportRequirements::ValidSeal);
+ bc().import(m_postMine.blockData(), m_stateDB, (ImportRequirements::Everything & ~ImportRequirements::ValidSeal) != 0);
m_postMine.sync(bc());
m_preMine = m_postMine;
}
diff --git a/mix/osx.qrc b/mix/osx.qrc
new file mode 100644
index 000000000..ef302c2d5
--- /dev/null
+++ b/mix/osx.qrc
@@ -0,0 +1,5 @@
+
+
+ qml/MacFileDialog.qml
+
+
diff --git a/mix/qml.qrc b/mix/qml.qrc
index c1901c220..50795d08b 100644
--- a/mix/qml.qrc
+++ b/mix/qml.qrc
@@ -34,6 +34,7 @@
qml/QStringTypeView.qml
qml/QVariableDeclaration.qml
qml/QVariableDefinition.qml
+ qml/QFileDialog.qml
qml/SourceSansProBold.qml
qml/SourceSansProLight.qml
qml/SourceSansProRegular.qml
diff --git a/mix/qml/Application.qml b/mix/qml/Application.qml
index 188d87be9..b05673ce8 100644
--- a/mix/qml/Application.qml
+++ b/mix/qml/Application.qml
@@ -281,11 +281,12 @@ ApplicationWindow {
onTriggered: openProjectFileDialog.open()
}
- FileDialog {
+ QFileDialog {
id: openProjectFileDialog
visible: false
title: qsTr("Open a Project")
selectFolder: true
+ selectExisting: true
onAccepted: {
var path = openProjectFileDialog.fileUrl.toString();
path += "/";
@@ -333,11 +334,12 @@ ApplicationWindow {
onTriggered: addExistingFileDialog.open()
}
- FileDialog {
+ QFileDialog {
id: addExistingFileDialog
visible: false
title: qsTr("Add a File")
selectFolder: false
+ selectExisting: true
onAccepted: {
var paths = addExistingFileDialog.fileUrls;
projectModel.addExistingFiles(paths);
diff --git a/mix/qml/MacFileDialog.qml b/mix/qml/MacFileDialog.qml
new file mode 100644
index 000000000..f1995588f
--- /dev/null
+++ b/mix/qml/MacFileDialog.qml
@@ -0,0 +1,298 @@
+import QtQuick 2.2
+import QtQuick.Controls 1.2
+import QtQuick.Controls.Private 1.0 as ControlsPrivate
+import QtQuick.Dialogs 1.2
+import QtQuick.Dialogs.Private 1.1
+import QtQuick.Layouts 1.1
+import QtQuick.Window 2.1
+import Qt.labs.folderlistmodel 2.1
+import Qt.labs.settings 1.0
+
+AbstractDialog {
+
+ id: root
+
+ property string folder: view.model.folder
+ property var nameFilters: []
+ property bool selectFolder: false
+ property bool selectExisting: true
+ property int selectedNameFilterIndex: -1
+ property var selectedNameFilterExtensions: []
+ property string selection: ""
+ property alias fileUrl: root.selection
+
+
+ function selectNameFilter(text) {
+ }
+
+ function clearSelection(text) {
+ selection = "";
+ }
+
+ function addSelection(text) {
+ selection = text;
+ }
+
+ onVisibleChanged: {
+ if (visible) {
+ view.needsWidthAdjustment = true
+ view.selection.clear()
+ view.focus = true
+ }
+ }
+
+ Component.onCompleted: {
+ folder = fileIo.pathToUrl(fileIo.homePath);
+ view.model.nameFilters = root.selectedNameFilterExtensions
+ filterField.currentIndex = root.selectedNameFilterIndex
+ root.favoriteFolders = settings.favoriteFolders
+ }
+
+ Component.onDestruction: {
+ settings.favoriteFolders = root.favoriteFolders
+ }
+
+ property Settings settings: Settings {
+ category: "QQControlsFileDialog"
+ property alias width: root.width
+ property alias height: root.height
+ property variant favoriteFolders: []
+ }
+
+ property bool showFocusHighlight: false
+ property SystemPalette palette: SystemPalette { }
+ property var favoriteFolders: []
+
+ function dirDown(path) {
+ view.selection.clear()
+ root.folder = "file://" + path
+ }
+ function dirUp() {
+ view.selection.clear()
+ if (view.model.parentFolder != "")
+ root.folder = view.model.parentFolder
+ }
+ function acceptSelection() {
+ // transfer the view's selections to QQuickFileDialog
+ clearSelection()
+ if (selectFolder && view.selection.count === 0)
+ addSelection(folder)
+ else {
+ view.selection.forEach(function(idx) {
+ if (view.model.isFolder(idx)) {
+ if (selectFolder)
+ addSelection(view.model.get(idx, "fileURL"))
+ } else {
+ if (!selectFolder)
+ addSelection(view.model.get(idx, "fileURL"))
+ }
+ })
+ }
+ accept()
+ }
+
+ property Action dirUpAction: Action {
+ text: "\ue810"
+ shortcut: "Ctrl+U"
+ onTriggered: dirUp()
+ tooltip: qsTr("Go up to the folder containing this one")
+ }
+
+ Rectangle {
+ id: window
+ implicitWidth: Math.min(root.__maximumDimension, Math.max(Screen.pixelDensity * 100, view.implicitWidth))
+ implicitHeight: Math.min(root.__maximumDimension, Screen.pixelDensity * 80)
+ color: root.palette.window
+
+ Binding {
+ target: view.model
+ property: "folder"
+ value: root.folder
+ }
+ Binding {
+ target: currentPathField
+ property: "text"
+ value: fileIo.urlToPath(root.folder)
+ }
+ Keys.onPressed: {
+ event.accepted = true
+ switch (event.key) {
+ case Qt.Key_Back:
+ case Qt.Key_Escape:
+ reject()
+ break
+ default:
+ event.accepted = false
+ break
+ }
+ }
+ Keys.forwardTo: [view.flickableItem]
+
+
+ TableView {
+ id: view
+ sortIndicatorVisible: true
+ width: parent.width
+ anchors.top: titleBar.bottom
+ anchors.bottom: bottomBar.top
+
+ property bool needsWidthAdjustment: true
+ selectionMode: root.selectMultiple ?
+ (ControlsPrivate.Settings.hasTouchScreen ? SelectionMode.MultiSelection : SelectionMode.ExtendedSelection) :
+ SelectionMode.SingleSelection
+ onRowCountChanged: if (needsWidthAdjustment && rowCount > 0) {
+ 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
+ }
+
+ onActivated: if (view.focus) {
+ if (view.selection.count > 0 && view.model.isFolder(row)) {
+ dirDown(view.model.get(row, "filePath"))
+ } else {
+ root.acceptSelection()
+ }
+ }
+ onClicked: currentPathField.text = view.model.get(row, "filePath")
+
+
+ TableViewColumn {
+ id: fileNameColumn
+ role: "fileName"
+ title: qsTr("Filename")
+ delegate: Item {
+ implicitWidth: pathText.implicitWidth + pathText.anchors.leftMargin + pathText.anchors.rightMargin
+
+ Text {
+ id: fileIcon
+ width: height
+ verticalAlignment: Text.AlignVCenter
+ font.family: iconFont.name
+ property alias unicode: fileIcon.text
+ FontLoader { id: iconFont; source: "qrc:/QtQuick/Dialogs/qml/icons.ttf"; onNameChanged: console.log("custom font" + name) }
+ x: 4
+ height: parent.height - 2
+ unicode: view.model.isFolder(styleData.row) ? "\ue804" : "\ue802"
+ }
+ Text {
+ id: pathText
+ text: styleData.value
+ anchors {
+ left: parent.left
+ right: parent.right
+ leftMargin: 36 + 6
+ rightMargin: 4
+ verticalCenter: parent.verticalCenter
+ }
+ color: styleData.textColor
+ elide: Text.ElideRight
+ renderType: ControlsPrivate.Settings.isMobile ? Text.QtRendering : Text.NativeRendering
+ }
+ }
+ }
+ TableViewColumn {
+ role: "fileSuffix"
+ title: qsTr("Type", "file type (extension)")
+ // TODO should not need to create a whole new component just to customize the text value
+ // something like textFormat: function(text) { return view.model.get(styleData.row, "fileIsDir") ? "folder" : text }
+ delegate: Item {
+ implicitWidth: sizeText.implicitWidth + sizeText.anchors.leftMargin + sizeText.anchors.rightMargin
+ Text {
+ id: sizeText
+ text: view.model.get(styleData.row, "fileIsDir") ? "folder" : styleData.value
+ anchors {
+ left: parent.left
+ right: parent.right
+ leftMargin: 4
+ rightMargin: 4
+ verticalCenter: parent.verticalCenter
+ }
+ color: styleData.textColor
+ elide: Text.ElideRight
+ renderType: ControlsPrivate.Settings.isMobile ? Text.QtRendering : Text.NativeRendering
+ }
+ }
+ }
+ TableViewColumn {
+ role: "fileSize"
+ title: qsTr("Size", "file size")
+ horizontalAlignment: Text.AlignRight
+ }
+ TableViewColumn { id: modifiedColumn; role: "fileModified" ; title: qsTr("Modified", "last-modified time") }
+ TableViewColumn { id: accessedColumn; role: "fileAccessed" ; title: qsTr("Accessed", "last-accessed time") }
+ }
+
+ ToolBar {
+ id: titleBar
+ RowLayout {
+ anchors.fill: parent
+ ToolButton {
+ action: dirUpAction
+ //style: IconButtonStyle { }
+ Layout.maximumWidth: height * 1.5
+ }
+ TextField {
+ id: currentPathField
+ Layout.fillWidth: true
+ function doAccept() {
+ root.clearSelection()
+ if (root.addSelection(fileIo.pathToUrl(text)))
+ root.accept()
+ else
+ root.folder = fileIo.pathFolder(text)
+ }
+ onAccepted: doAccept()
+ }
+ }
+ }
+ Item {
+ id: bottomBar
+ width: parent.width
+ height: buttonRow.height + buttonRow.spacing * 2
+ anchors.bottom: parent.bottom
+
+ Row {
+ id: buttonRow
+ anchors.right: parent.right
+ anchors.rightMargin: spacing
+ anchors.verticalCenter: parent.verticalCenter
+ spacing: 4
+ ComboBox {
+ id: filterField
+ model: root.nameFilters
+ visible: !selectFolder
+ width: bottomBar.width - cancelButton.width - okButton.width - parent.spacing * 6
+ anchors.verticalCenter: parent.verticalCenter
+ onCurrentTextChanged: {
+ root.selectNameFilter(currentText)
+ view.model.nameFilters = root.selectedNameFilterExtensions
+ }
+ }
+ Button {
+ id: cancelButton
+ text: qsTr("Cancel")
+ onClicked: root.reject()
+ }
+ Button {
+ id: okButton
+ text: root.selectFolder ? qsTr("Choose") : (selectExisting ? qsTr("Open") : qsTr("Save"))
+ onClicked: {
+ if (view.model.isFolder(view.currentIndex) && !selectFolder)
+ dirDown(view.model.get(view.currentIndex, "filePath"))
+ else if (!(root.selectExisting))
+ currentPathField.doAccept()
+ else
+ root.acceptSelection()
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/mix/qml/NewProjectDialog.qml b/mix/qml/NewProjectDialog.qml
index 77b6c513a..ab35d5c5e 100644
--- a/mix/qml/NewProjectDialog.qml
+++ b/mix/qml/NewProjectDialog.qml
@@ -105,7 +105,7 @@ Item
}
- FileDialog {
+ QFileDialog {
id: createProjectFileDialog
visible: false
title: qsTr("Please choose a path for the project")
diff --git a/mix/qml/PackagingStep.qml b/mix/qml/PackagingStep.qml
index 26b5c8540..8ee383f56 100644
--- a/mix/qml/PackagingStep.qml
+++ b/mix/qml/PackagingStep.qml
@@ -27,11 +27,12 @@ Rectangle {
visible = true
}
- FileDialog {
+ QFileDialog {
id: ressourcesFolder
visible: false
title: qsTr("Please choose a path")
selectFolder: true
+ selectExisting: true
property variant target
onAccepted: {
var u = ressourcesFolder.fileUrl.toString();
diff --git a/mix/qml/QFileDialog.qml b/mix/qml/QFileDialog.qml
new file mode 100644
index 000000000..5ce2ad41c
--- /dev/null
+++ b/mix/qml/QFileDialog.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.2
+import QtQuick.Controls 1.2
+import QtQuick.Dialogs 1.2
+
+FileDialog { }
diff --git a/mix/qml/StateDialog.qml b/mix/qml/StateDialog.qml
index cd19751b6..a2d384b3d 100644
--- a/mix/qml/StateDialog.qml
+++ b/mix/qml/StateDialog.qml
@@ -124,7 +124,7 @@ Dialog {
importJsonFileDialog.open()
}
}
- FileDialog {
+ QFileDialog {
id: importJsonFileDialog
visible: false
title: qsTr("Select State File")