diff --git a/blackMosquito.png b/blackMosquito.png
index 68821071..16c5d2a6 100644
Binary files a/blackMosquito.png and b/blackMosquito.png differ
diff --git a/buttleofx/MainWindow.qml b/buttleofx/MainWindow.qml
index 9f1069a2..2e9d3e85 100644
--- a/buttleofx/MainWindow.qml
+++ b/buttleofx/MainWindow.qml
@@ -1,10 +1,10 @@
-import QtQuick 2.0
-import QtQuick.Controls 1.0
-import QtQuick.Layouts 1.0
import QtQml 2.1
+import QtQuick 2.0
import QuickMamba 1.0
-import QtQuick.Dialogs 1.1
import QtQuick.Window 2.1
+import QtQuick.Dialogs 1.1
+import QtQuick.Layouts 1.0
+import QtQuick.Controls 1.0
import QtQuick.LocalStorage 2.0
import "gui/graph/qml"
@@ -13,6 +13,7 @@ import "gui/paramEditor/qml"
import "gui/browser_v2/qml"
import "gui/plugin/qml"
import "gui/shortcut/qml"
+import "gui/dialogs"
ApplicationWindow {
property var settingsDatabase: getInitializedDatabase()
@@ -72,19 +73,16 @@ ApplicationWindow {
property string urlOfFileToSave: _buttleData.urlOfFileToSave
-
// TopFocusHandler {
// anchors.fill: parent
// }
Keys.onPressed: {
-
// Viewer
if ((event.key == Qt.Key_1) && (event.modifiers & Qt.KeypadModifier)) {
player.changeViewer(1)
}
if ((event.key == Qt.Key_2) && (event.modifiers & Qt.KeypadModifier)) {
-
player.changeViewer(2)
}
if ((event.key == Qt.Key_3) && (event.modifiers & Qt.KeypadModifier)) {
@@ -119,15 +117,15 @@ ApplicationWindow {
}
}
- property bool aNodeIsSelected:true
+ property bool aNodeIsSelected: true
// Window of hint for plugins
PluginWindow {
id: doc
title: "Plugin's Documentation"
- selectedNodeLabel: _buttleData.currentSelectedNodeWrappers.count!=0 ? _buttleData.currentSelectedNodeWrappers.get(0).name : ""
- selectedNodeDoc: _buttleData.currentSelectedNodeWrappers.count!=0 ? _buttleData.currentSelectedNodeWrappers.get(0).pluginDoc : ""
- selectedNodeGroup: _buttleData.currentSelectedNodeWrappers.count!=0 ? _buttleData.currentSelectedNodeWrappers.get(0).pluginGroup : ""
+ selectedNodeLabel: _buttleData.currentSelectedNodeWrappers.count != 0 ? _buttleData.currentSelectedNodeWrappers.get(0).name : ""
+ selectedNodeDoc: _buttleData.currentSelectedNodeWrappers.count != 0 ? _buttleData.currentSelectedNodeWrappers.get(0).pluginDoc : ""
+ selectedNodeGroup: _buttleData.currentSelectedNodeWrappers.count != 0 ? _buttleData.currentSelectedNodeWrappers.get(0).pluginGroup : ""
}
// Window of shortcuts
@@ -136,103 +134,58 @@ ApplicationWindow {
title: "Shortcuts"
}
- FileDialog {
+ BrowserOpenDialog{
id: finderLoadGraph
- title: "Open a graph"
- nameFilters: [ "All files (*)" ]
- selectedNameFilter: "All files (*)"
-
- onAccepted: {
- if (finderLoadGraph.fileUrl) {
- _buttleData.loadData(finderLoadGraph.fileUrl)
- }
- }
}
- FileDialog {
+ BrowserSaveDialog{
id: finderSaveGraph
- title: "Save the graph"
- nameFilters: [ "All files (*)" ]
- selectedNameFilter: "All files (*)"
-
- onAccepted: {
- if (finderSaveGraph.fileUrl) {
- _buttleData.saveData(finderSaveGraph.fileUrl)
- }
- }
-
- selectExisting: false
}
- MessageDialog {
+ ExitDialog {
id: openGraph
- title:"Save the graph?"
- icon: StandardIcon.Warning
- modality: Qt.WindowStaysOnTopHint && Qt.WindowModal
- text: urlOfFileToSave == "" ? "Save graph changes before closing ?" : "Save " + _buttleData.getFileName(urlOfFileToSave) + " changes before closing ?"
- detailedText: "If you don't save the graph, unsaved modifications will be lost. "
- standardButtons: StandardButton.Yes | StandardButton.No | StandardButton.Abort
- Component.onCompleted: visible = false
-
- onYes: {
- if(urlOfFileToSave!="") {
+ visible: false
+ dialogText: "Do you want to save before closing this file?
If you don't, all unsaved changes will be lost"
+
+ onSaveButtonClicked: {
+ if (urlOfFileToSave != "") {
_buttleData.saveData(urlOfFileToSave)
- } else{
- finderSaveGraph.open()
+ } else {
+ finderSaveGraph.show("open")
}
}
- onNo: {
- finderLoadGraph.open()
+ onDiscardButtonClicked: {
+ finderLoadGraph.visible = true
}
- onRejected: {}
}
- MessageDialog {
+ ExitDialog {
id: newGraph
- title: "Save the graph?"
- icon: StandardIcon.Warning
- modality: Qt.WindowStaysOnTopHint && Qt.WindowModal
- text: urlOfFileToSave == "" ? "Save graph changes before closing ?" : "Save " + _buttleData.getFileName(urlOfFileToSave) + " changes before closing ?"
- detailedText: "If you don't save the graph, unsaved modifications will be lost. "
- standardButtons: StandardButton.Yes | StandardButton.No | StandardButton.Abort
- Component.onCompleted: visible = false
-
- onYes: {
- if (urlOfFileToSave!="") {
+ visible: false
+ dialogText: "Do you want to save before closing this file?
If you don't, all unsaved changes will be lost"
+
+ onSaveButtonClicked: {
+ if (urlOfFileToSave != "") {
_buttleData.saveData(urlOfFileToSave)
- _buttleData.newData()
} else {
- finderSaveGraph.open()
- _buttleData.newData()
+ finderSaveGraph.show("new")
}
}
- onNo: {
- _buttleData.newData()
- }
+ onDiscardButtonClicked: _buttleData.newData()
}
- MessageDialog {
+ ExitDialog {
id: closeButtle
- title: "Save the graph?"
- icon: StandardIcon.Warning
- modality: Qt.WindowStaysOnTopHint && Qt.WindowModal
- text: urlOfFileToSave == "" ? "Save graph changes before closing ?" : "Save " + _buttleData.getFileName(urlOfFileToSave) + " changes before closing ?"
- detailedText: "If you don't save the graph, unsaved modifications will be lost. "
- standardButtons: StandardButton.Yes | StandardButton.No | StandardButton.Abort
- Component.onCompleted: visible = false
-
- onYes: {
- if(urlOfFileToSave!="") {
+ visible: false
+
+ onSaveButtonClicked: {
+ if (urlOfFileToSave != "") {
_buttleData.saveData(urlOfFileToSave)
} else {
- finderSaveGraph.open()
- finderSaveGraph.close()
- finderSaveGraph.open()
+ finderSaveGraph.show("close")
}
}
- onNo: {
- Qt.quit()
- }
+ onDiscardButtonClicked: Qt.quit()
}
menuBar: MenuBar {
@@ -247,7 +200,7 @@ ApplicationWindow {
if (!_buttleData.graphCanBeSaved) {
_buttleData.newData()
} else {
- newGraph.open()
+ newGraph.visible = true
}
}
}
@@ -258,11 +211,9 @@ ApplicationWindow {
onTriggered: {
if (!_buttleData.graphCanBeSaved) {
- finderLoadGraph.open()
+ finderLoadGraph.visible = true
} else {
- openGraph.open()
- openGraph.close()
- openGraph.open()
+ openGraph.visible = true
}
}
}
@@ -270,14 +221,14 @@ ApplicationWindow {
MenuItem {
text: "Save"
shortcut: "Ctrl+S"
- enabled: _buttleData.graphCanBeSaved && urlOfFileToSave != "" ? true : false
+ enabled: _buttleData.graphCanBeSaved && urlOfFileToSave != ""
onTriggered: _buttleData.saveData(urlOfFileToSave)
}
MenuItem {
text: "Save As"
shortcut: "Ctrl+Shift+S"
- onTriggered: finderSaveGraph.open()
+ onTriggered: finderSaveGraph.visible = true
}
MenuSeparator { }
@@ -290,7 +241,7 @@ ApplicationWindow {
if (!_buttleData.graphCanBeSaved) {
Qt.quit()
} else {
- closeButtle.open()
+ closeButtle.visible = true
}
}
}
@@ -303,7 +254,7 @@ ApplicationWindow {
id: undoRedoStack
title: "Undo/Redo stack"
- property variant undoRedoList:_buttleData.graphCanBeSaved ? _buttleManager.undoRedoStack:_buttleManager.undoRedoStack
+ property variant undoRedoList: _buttleData.graphCanBeSaved ? _buttleManager.undoRedoStack : _buttleManager.undoRedoStack
Instantiator {
model: undoRedoStack.undoRedoList
@@ -414,10 +365,11 @@ ApplicationWindow {
title: "Nodes"
Instantiator {
- model: _buttleData.getMenu(1,"")
+ model: _buttleData.getMenu(1, "")
+
Menu {
id: firstMenu
- title:object
+ title: object
__parentContentItem: nodesMenu.__contentItem // To remove warning
Instantiator {
@@ -447,11 +399,11 @@ ApplicationWindow {
}
Instantiator {
- model: _buttleData.getMenu(2,firstMenu.title)
+ model: _buttleData.getMenu(2, firstMenu.title)
Menu {
id: secondMenu
- title:object
+ title: object
__parentContentItem: nodesMenu.__contentItem // To remove warning
Instantiator {
@@ -481,11 +433,11 @@ ApplicationWindow {
}
Instantiator {
- model: _buttleData.getMenu(3,secondMenu.title)
+ model: _buttleData.getMenu(3, secondMenu.title)
Menu {
id: thirdMenu
- title:object
+ title: object
__parentContentItem: nodesMenu.__contentItem // To remove warning
Instantiator {
@@ -515,10 +467,10 @@ ApplicationWindow {
}
Instantiator {
- model: _buttleData.getMenu(4,thirdMenu.title)
+ model: _buttleData.getMenu(4, thirdMenu.title)
Menu {
- id:fourthMenu
+ id: fourthMenu
title: object
__parentContentItem: nodesMenu.__contentItem // To remove warning
@@ -549,7 +501,7 @@ ApplicationWindow {
}
Instantiator {
- model: _buttleData.getMenu(5,fourthMenu.title)
+ model: _buttleData.getMenu(5, fourthMenu.title)
Menu {
id: fifthMenu
@@ -622,7 +574,6 @@ ApplicationWindow {
}
}
-
Menu {
title: "View"
@@ -704,29 +655,41 @@ ApplicationWindow {
MenuItem {
text: "Browser"
checkable: true
- checked: browser.parent.visible==true ? true : false
- onTriggered: browser.parent.visible == false ? browser.parent.visible=true : browser.parent.visible=false
+ checked: browser.parent.visible
+
+ onTriggered: {
+ browser.parent.visible = !browser.parent.visible
+ }
}
MenuItem {
text: "Viewer"
checkable: true
- checked: player.parent.visible==true ? true : false
- onTriggered: player.parent.visible == false ? player.parent.visible=true : player.parent.visible=false
+ checked: player.parent.visible
+
+ onTriggered: {
+ player.parent.visible = !player.parent.visible
+ }
}
MenuItem {
text: "Graph"
checkable: true
- checked: graphEditor.parent.visible==true ? true : false
- onTriggered: graphEditor.parent.visible == false ? graphEditor.parent.visible=true : graphEditor.parent.visible=false
+ checked: graphEditor.parent.visible
+
+ onTriggered: {
+ graphEditor.parent.visible = !graphEditor.parent.visible
+ }
}
MenuItem {
text: "Parameters"
checkable: true
- checked: paramEditor.parent.visible==true ? true : false
- onTriggered: paramEditor.parent.visible == false ? paramEditor.parent.visible=true : paramEditor.parent.visible=false
+ checked: paramEditor.parent.visible
+
+ onTriggered: {
+ paramEditor.parent.visible = !paramEditor.parent.visible
+ }
}
*/
}
@@ -743,7 +706,6 @@ ApplicationWindow {
}
*/
-
// This rectangle represents the zone under the menu, it allows to define the anchors.fill and margins for the SplitterRow
Rectangle {
id: modulsContainer
@@ -816,6 +778,7 @@ ApplicationWindow {
z: -1
visible: selectedView == 1 || selectedView == 2
children: lastSelectedView[3]
+
}
}
}
@@ -825,7 +788,7 @@ ApplicationWindow {
id: subviews
visible: false
- property variant parentBeforeFullscreen : null
+ property variant parentBeforeFullscreen: null
Player {
id: player
@@ -841,7 +804,7 @@ ApplicationWindow {
}
}
onButtonFullscreenClicked:
- if (parent != fullscreenContent){
+ if (parent != fullscreenContent) {
subviews.parentBeforeFullscreen = parent
fullscreenWindow.visibility = Window.FullScreen
fullscreenContent.children = player
@@ -861,7 +824,7 @@ ApplicationWindow {
}
}
onButtonFullscreenClicked:
- if (parent != fullscreenContent){
+ if (parent != fullscreenContent) {
subviews.parentBeforeFullscreen = parent
fullscreenWindow.visibility = Window.FullScreen
fullscreenContent.children = graphEditor
@@ -883,7 +846,7 @@ ApplicationWindow {
}
}
onButtonFullscreenClicked:
- if (parent != fullscreenContent){
+ if (parent != fullscreenContent) {
subviews.parentBeforeFullscreen = parent
fullscreenWindow.visibility = Window.FullScreen
fullscreenContent.children = paramEditor
@@ -903,7 +866,7 @@ ApplicationWindow {
}
}
onButtonFullscreenClicked:
- if (parent != fullscreenContent){
+ if (parent != fullscreenContent) {
subviews.parentBeforeFullscreen = parent
fullscreenWindow.visibility = Window.FullScreen
fullscreenContent.children = advancedParamEditor
@@ -930,6 +893,12 @@ ApplicationWindow {
fullscreenContent.children = browser
}
}
+
+ Connections{
+ target: browser.fileWindow
+ onItemClicked: isSupported ? browser.fileWindow.onItemClickedSlot(pathImg) : 0
+ onItemDoubleClicked: isSupported ? browser.fileWindow.onItemDoubleClickedSlot(absolutePath) : 0
+ }
}
Item {
diff --git a/buttleofx/data/buttleData.py b/buttleofx/data/buttleData.py
index 755cd73b..4dcf31bc 100644
--- a/buttleofx/data/buttleData.py
+++ b/buttleofx/data/buttleData.py
@@ -524,9 +524,8 @@ def loadData(self, url='buttleofx/backup/data.bofx'):
"""
Loads all data from a Json file (the default Json file if no url is given)
"""
-
- filepath = QtCore.QUrl(url).toLocalFile()
-
+ Qurl = QtCore.QUrl(url)
+ filepath = (Qurl.isLocalFile() and Qurl.toLocalFile()) or url
self.newData()
with open(filepath, 'r') as f:
@@ -647,14 +646,21 @@ def saveData(self, url):
"""
Saves all data in a json file
"""
+ # If called from Python, it could be a str or a QUrl
if isinstance(url, str):
- # If called from Python, it could be a str or a QUrl.
- filepath = QtCore.QUrl.fromLocalFile(url).toLocalFile()
+ filepath = url
else:
- filepath = QtCore.QUrl(url).toLocalFile()
+ filepath = url.toLocalFile() if url.isLocalFile() else url.toString()
+
+ if filepath.endswith('buttleSave_now.bofx'):
+ filepath = os.path.dirname(filepath)
- if not filepath.lower().endswith(".bofx"):
- filepath = filepath + ".bofx"
+ # if destination path is a folder, we create a file name containing date and time of now
+ if os.path.isdir(filepath):
+ filepath = os.path.join(filepath, 'buttleSave%s' % datetime.today().strftime('%m_%d_%y_%I_%M'))
+
+ if not filepath.lower().endswith('.bofx'):
+ filepath += '.bofx'
with io.open(filepath, 'w', encoding='utf-8') as f:
dictJson = {
@@ -675,8 +681,8 @@ def saveData(self, url):
# Graph
dictJson["graph"] = self.getGraph().object_to_dict()
- # Graph : currentSeletedNodes
- for node in self.getGraph().getNodes():
+ # Graph : currentSelectedNodes
+ for node in self._graph.getNodes():
if node.getName() in self.getCurrentSelectedNodeNames():
dictJson["graph"]["currentSelectedNodes"].append(node.getName())
@@ -736,6 +742,9 @@ def zoom(self, width, height, nodeWidth, zoomCoeff, graphPreviousWidth, graphPre
def getButtlePath(self):
return self._buttlePath
+ def getHomeDir(self):
+ return os.path.expanduser("~")
+
def getCurrentConnectionWrapper(self):
"""
Returns the current currentConnectionWrapper.
@@ -1036,6 +1045,7 @@ def graphCanBeSaved(self):
# filePath
buttlePath = QtCore.pyqtProperty(str, getButtlePath, constant=True)
+ homeDir = QtCore.pyqtProperty(str, getHomeDir, constant=True)
# Current param, view, and selected node
currentParamNodeChanged = QtCore.pyqtSignal()
@@ -1092,12 +1102,12 @@ def graphCanBeSaved(self):
globalButtleData = ButtleData()
-def _decode_dict(dict_):
+def _decode_dict(_dict):
"""
This function will recursively pass in nested dicts, and will convert
all str elements into string (essential for some Tuttle functions).
"""
- for key in dict_:
- if isinstance(dict_[key], str):
- dict_[key] = str(dict_[key])
- return dict_
+ for key in _dict:
+ if isinstance(_dict[key], str):
+ _dict[key] = str(_dict[key])
+ return _dict
diff --git a/buttleofx/gui/browser_v2/actions/browserAction.py b/buttleofx/gui/browser_v2/actions/browserAction.py
index 4c03c186..2e423683 100644
--- a/buttleofx/gui/browser_v2/actions/browserAction.py
+++ b/buttleofx/gui/browser_v2/actions/browserAction.py
@@ -7,12 +7,12 @@
from buttleofx.gui.browser_v2.actions.actionManager import globalActionManager
from buttleofx.gui.browser_v2.actions.actionWrapper import ActionWrapper
-from buttleofx.gui.browser_v2.browserModel import globalBrowserModel
from buttleofx.gui.browser_v2.browserItem import BrowserItem
from buttleofx.gui.browser_v2.actions.concreteActions.copy import Copy
from buttleofx.gui.browser_v2.actions.concreteActions.move import Move
from buttleofx.gui.browser_v2.actions.concreteActions.create import Create
from buttleofx.gui.browser_v2.actions.concreteActions.delete import Delete
+from buttleofx.gui.browser_v2.browserModel import globalBrowserDialog, globalBrowser
class BrowserAction(QtCore.QObject):
@@ -21,11 +21,11 @@ class BrowserAction(QtCore.QObject):
"""
cacheChanged = QtCore.pyqtSignal()
- def __init__(self):
+ def __init__(self, bModel):
logging.debug('BrowserAction begin constructor')
QtCore.QObject.__init__(self)
self._cacheActions = None # for copy, move actions
- self._browserModel = globalBrowserModel
+ self._browserModel = bModel
logging.debug('BrowserAction end constructor')
def pushCache(self, listActions):
@@ -99,4 +99,5 @@ def handleNew(self, typeItem):
isCache = QtCore.pyqtProperty(bool, isEmptyCache, notify=cacheChanged)
-globalBrowserAction = BrowserAction()
+globalBrowserAction = BrowserAction(globalBrowser)
+globalBrowserActionDialog = BrowserAction(globalBrowserDialog)
diff --git a/buttleofx/gui/browser_v2/browserModel.py b/buttleofx/gui/browser_v2/browserModel.py
index c0ce20b3..9c3cf9b6 100644
--- a/buttleofx/gui/browser_v2/browserModel.py
+++ b/buttleofx/gui/browser_v2/browserModel.py
@@ -42,6 +42,7 @@ def __init__(self, path=op.expanduser("~/"), sync=False, showSeq=True, hideDotFi
"""
QtCore.QObject.__init__(self, parent)
self._currentPath = path
+ self._bufferBrowserItems = [] # used when recursive process: fix async signal connection when add object
self._browserItems = [] # used only in python side
self._browserItemsModel = QObjectListModel(self) # used for UI
self._filter = filterFiles
@@ -98,6 +99,7 @@ def updateItems(self, recursivePattern):
return
self.clearItemsSync.emit()
+ self._bufferBrowserItems.clear()
detectOption = sequenceParser.eDetectionDefaultWithDotFile
if self._hideDotFiles:
detectOption = sequenceParser.eDetectionDefault
@@ -146,6 +148,7 @@ def pushBrowserItems(self, allItems, toModel=True):
if not self._isSync:
itemToAdd.moveToThread(self.thread())
self.addItemSync.emit(itemToAdd, toModel)
+ self._bufferBrowserItems.append(itemToAdd)
@QtCore.pyqtSlot(object, bool)
def onAddItemSync(self, bItem, toModel=True):
@@ -174,9 +177,8 @@ def searchRecursively(self, pattern, modelRequester):
if modelRequester.getParallelThread().isStopped():
return
- listToBrowse = self._browserItems
+ listToBrowse = self._bufferBrowserItems
if self == modelRequester:
- listToBrowse = self._browserItems.copy() # copy: _browserItems deleted line after
modelRequester.clearItemsSync.emit()
for bItem in listToBrowse: # 1st pass, all files in current dir
@@ -417,4 +419,5 @@ def selectItemTo(self, index):
loading = QtCore.pyqtProperty(bool, isLoading, notify=loadingChanged)
-globalBrowserModel = BrowserModel()
+globalBrowser = BrowserModel()
+globalBrowserDialog = BrowserModel()
diff --git a/buttleofx/gui/browser_v2/qml/Browser.qml b/buttleofx/gui/browser_v2/qml/Browser.qml
index e951a14b..fe2ffbad 100644
--- a/buttleofx/gui/browser_v2/qml/Browser.qml
+++ b/buttleofx/gui/browser_v2/qml/Browser.qml
@@ -9,7 +9,13 @@ Rectangle {
height: 600
color: "#353535"
+ property alias fileWindow: fileWindow
+ property alias navBar: navBar
+ property bool showTab: true
+ property variant bModel: _browser
+ property variant bAction: _browserAction
property int visitedFolderListIndex: 0
+
signal buttonCloseClicked(bool clicked)
signal buttonFullscreenClicked(bool clicked)
@@ -22,6 +28,13 @@ Rectangle {
++ visitedFolderListIndex
}
+ function popVisitedFolder(){
+ if (visitedFolderList.count > 0 && visitedFolderListIndex > 0) {
+ -- visitedFolderListIndex
+ bModel.currentPath = visitedFolderList.get(visitedFolderListIndex).url
+ }
+ }
+
// Recently visited folder stack
ListModel {
id: visitedFolderList
@@ -32,9 +45,10 @@ Rectangle {
spacing: 0
Tab {
- Layout.fillWidth: true
id: tabBar
+ Layout.fillWidth: true
name: "Browser"
+ visible: root.showTab
onCloseClicked: root.buttonCloseClicked(true)
onFullscreenClicked: root.buttonFullscreenClicked(true)
}
@@ -44,9 +58,10 @@ Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: childrenRect.height
- property var model: _browser
+ property var model: root.bModel
property alias visitedFolderList: visitedFolderList
property alias visitedFolderListIndex: root.visitedFolderListIndex
+
onPushVisitedFolder: {
root.pushVisitedFolder(path)
}
@@ -54,10 +69,8 @@ Rectangle {
Rectangle {
id: separator
-
Layout.fillWidth: true
Layout.preferredHeight: 1
-
color: "#00b2a1"
}
@@ -67,7 +80,8 @@ Rectangle {
Layout.fillWidth: true
Layout.fillHeight: true
- property var model: _browser
+ property var model: root.bModel
+ property var bAction: root.bAction
property alias visitedFolderList: visitedFolderList
property alias visitedFolderListIndex: root.visitedFolderListIndex
@@ -76,4 +90,14 @@ Rectangle {
}
}
}
+
+ Keys.onPressed: {
+ if ((event.modifiers & Qt.ControlModifier) && (event.key == Qt.Key_L)){
+ navBar.toggleUrlEdit()
+ }
+
+ if (event.key == Qt.Key_Backspace){
+ popVisitedFolder()
+ }
+ }
}
diff --git a/buttleofx/gui/browser_v2/qml/FileWindow.qml b/buttleofx/gui/browser_v2/qml/FileWindow.qml
index 8d52b73d..d216b683 100644
--- a/buttleofx/gui/browser_v2/qml/FileWindow.qml
+++ b/buttleofx/gui/browser_v2/qml/FileWindow.qml
@@ -9,8 +9,9 @@ Rectangle {
id: root
color: "transparent"
- //TODO: think about standalone
- function handleGraphViewerClick(pathImg){
+ // defaults slots
+ function onItemClickedSlot(pathImg){
+ // handleGraphViewerClick
// We come to the temporary viewer
player.changeViewer(11)
@@ -28,7 +29,9 @@ Rectangle {
_buttleData.currentViewerIndex = 10 // We assign to the viewer the 10th view
_buttleEvent.emitViewerChangedSignal()
}
- function handleGraphViewerDoubleClick(browserItem){
+
+ function onItemDoubleClickedSlot(absolutePath){
+ // handleGraphViewerDoubleClick
_buttleData.currentGraphWrapper = _buttleData.graphWrapper
_buttleData.currentGraphIsGraph()
@@ -40,12 +43,14 @@ Rectangle {
_buttleData.currentViewerNodeWrapper = player.lastNodeWrapper
player.changeViewer(player.lastView)
}
- _buttleManager.nodeManager.dropFile(browserItem.path, 10, 10)
+ _buttleManager.nodeManager.dropFile(absolutePath, 10, 10)
}
+ signal itemClicked(string absolutePath, string pathImg, bool isFolder, bool isSupported)
+ signal itemDoubleClicked(string absolutePath, string pathImg, bool isFolder, bool isSupported)
signal pushVisitedFolder(string path)
- Keys.onEscapePressed: root.model.unselectAllItems()
+ Keys.onEscapePressed: root.model.unselectAllItems()
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
@@ -76,7 +81,7 @@ Rectangle {
iconName: "edit-select-all"
shortcut: StandardKey.SelectAll
onTriggered: {
- _browser.selectAllItems()
+ root.model.selectAllItems()
}
}
@@ -85,7 +90,7 @@ Rectangle {
iconName: "reload"
shortcut: StandardKey.Refresh
onTriggered: {
- _browser.refresh()
+ root.model.refresh()
}
}
MenuSeparator{}
@@ -103,8 +108,8 @@ Rectangle {
iconName: "folder-new"
shortcut: StandardKey.New
onTriggered: {
- _browserAction.handleNew("Folder")
- _browser.refresh()
+ root.bAction.handleNew("Folder")
+ root.model.refresh()
}
}
MenuItem{
@@ -113,8 +118,8 @@ Rectangle {
iconName: "document-new"
shortcut: StandardKey.UnknownKey
onTriggered: {
- _browserAction.handleNew("File")
- _browser.refresh()
+ root.bAction.handleNew("File")
+ root.model.refresh()
}
}
MenuSeparator{}
@@ -124,7 +129,7 @@ Rectangle {
shortcut: StandardKey.Copy
iconName: "edit-copy"
onTriggered: {
- _browserAction.handleCopy()
+ root.bAction.handleCopy()
}
}
MenuItem{
@@ -133,21 +138,21 @@ Rectangle {
iconName: "edit-cut"
shortcut: StandardKey.Cut
onTriggered: {
- _browserAction.handleMove()
+ root.bAction.handleMove()
}
}
MenuItem{
text:"Paste"
iconName: "edit-paste"
shortcut: StandardKey.Paste
- enabled: _browserAction.isCache
+ enabled: root.bAction.isCache
onTriggered: {
var destination=""
- if(_browser.selectedItems.count == 1 && _browser.selectedItems.get(0).isFolder())
- destination = _browser.selectedItems.get(0).path
+ if(root.model.selectedItems.count == 1 && root.model.selectedItems.get(0).isFolder())
+ destination = root.model.selectedItems.get(0).path
- _browserAction.handlePaste(destination)
- _browser.refresh()
+ root.bAction.handlePaste(destination)
+ root.model.refresh()
}
}
@@ -157,8 +162,8 @@ Rectangle {
iconName: "edit-delete"
shortcut: StandardKey.Deletes
onTriggered: {
- _browserAction.handleDelete()
- _browser.refresh()
+ root.bAction.handleDelete()
+ root.model.refresh()
}
}
@@ -323,12 +328,7 @@ Rectangle {
}
else if(mouse.button == Qt.LeftButton){
- if(!model.object.isFolder()){
- if (model.object.isSupported()){
- handleGraphViewerClick(model.object.path)
- }
- }
-
+ root.itemClicked(model.object.path, model.object.path, model.object.isFolder(), model.object.isSupported())
if ((mouse.modifiers & Qt.ShiftModifier))
root.model.selectItemTo(index)
else if ((mouse.modifiers & Qt.ControlModifier))
@@ -338,17 +338,15 @@ Rectangle {
}
}
onDoubleClicked: {
+ root.itemDoubleClicked(model.object.path, model.object.path, model.object.isFolder(), model.object.isSupported())
+
+ // we ensure this behavior by default
if (model.object.isFolder()) {
pushVisitedFolder(model.object.path)
root.model.currentPath = model.object.path
}
-
- // If it's an image, we create a node
- else if (model.object.isSupported())
- handleGraphViewerDoubleClick(model.object)
}
}
-
}
}
diff --git a/buttleofx/gui/browser_v2/qml/NavBar.qml b/buttleofx/gui/browser_v2/qml/NavBar.qml
index bbe98787..44fb866b 100644
--- a/buttleofx/gui/browser_v2/qml/NavBar.qml
+++ b/buttleofx/gui/browser_v2/qml/NavBar.qml
@@ -7,12 +7,22 @@ import QtQuick.Controls.Styles 1.0
Rectangle {
id: root
color: "#2E2E2E"
-
clip: true
signal pushVisitedFolder(string path)
property alias searchLayout: searchLayoutRectangle
+ function toggleUrlEdit(visibility){
+ visibility = visibility !== undefined ? visibility : breadCrum.visible
+ breadCrum.visible = !visibility
+ textEditContainer.visible = visibility
+
+ if(visibility)
+ texteditPath.forceActiveFocus()
+ }
+
+ Component.onCompleted: toggleUrlEdit(true)
+
QtObject {
id: m;
property bool searchEnabled: false
@@ -43,26 +53,17 @@ Rectangle {
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
tooltip: "Previous"
- iconSource:
- if (hovered)
- "img/previous_hover.png"
- else
- "img/previous.png"
+ iconSource: hovered ? "img/previous_hover.png" : "img/previous.png"
style:
- ButtonStyle {
- background: Rectangle {
- anchors.fill: parent
- color: "transparent"
+ ButtonStyle {
+ background: Rectangle {
+ anchors.fill: parent
+ color: "transparent"
+ }
}
- }
- onClicked: {
- if (visitedFolderList.count > 0 && visitedFolderListIndex > 0) {
- -- visitedFolderListIndex
- model.currentPath = visitedFolderList.get(visitedFolderListIndex).url
- }
- }
+ onClicked: popVisitedFolder()
}
Button {
@@ -260,7 +261,8 @@ Rectangle {
}
Keys.onReleased: {
- if(event.key === Qt.Key_Shift || event.key === Qt.Key_Alt)
+ if(event.key === Qt.Key_Shift || event.key === Qt.Key_Alt || event.key === Qt.Key_Control
+ || (event.key === Qt.Key_Control && event.key === Qt.Key_L))
return
root.model.currentPath = texteditPath.text
graySuggestion.fill()
@@ -311,7 +313,6 @@ Rectangle {
}
function show() {
- console.log(root.model.listFolderNavBar.count)
if(!root.model.listFolderNavBar.count)
return
this.__popup(0, 0)
@@ -330,16 +331,10 @@ Rectangle {
clip: true
MouseArea {
- anchors.fill: parent
- propagateComposedEvents: true
- onDoubleClicked: {
- if (breadCrum.visible)
- breadCrum.visible = false
-
- if (!textEditContainer.visible){
- textEditContainer.visible = true
- texteditPath.forceActiveFocus()
- }
+ anchors.fill: parent
+ propagateComposedEvents: true
+ onDoubleClicked: {
+ root.toggleUrlEdit()
}
}
delegate: component
@@ -513,7 +508,7 @@ Rectangle {
anchors.fill: parent
anchors.margins: 2
- placeholderText: "Enter your search ..."
+ placeholderText: "Search ..."
style: TextFieldStyle {
selectionColor: "#00b2a1"
@@ -525,7 +520,7 @@ Rectangle {
}
}
onAccepted: {
- _browser.loadData(text.trim())
+ root.model.loadData(text.trim())
}
onFocusChanged: {
diff --git a/buttleofx/gui/dialogs/BrowserDialog.qml b/buttleofx/gui/dialogs/BrowserDialog.qml
new file mode 100644
index 00000000..122d0224
--- /dev/null
+++ b/buttleofx/gui/dialogs/BrowserDialog.qml
@@ -0,0 +1,40 @@
+import QtQuick 2.2
+import QtQuick.Layouts 1.1
+import QtQml 2.1
+import QtQuick 2.0
+import QtQuick.Window 2.1
+import QtQuick.Dialogs 1.1
+import QtQuick.Controls 1.0
+import QtQuick.Controls.Styles 1.0
+
+
+import "../browser_v2/qml/"
+
+// common part of open and save browserDialog (Abstract behavior)
+// the connecitons are done in 'subclasses'
+
+Window{
+ id: finderBrowser
+ title: 'Finder Browser'
+ width: 630
+ height: 380
+ visible: false
+ flags: "Dialog"
+ modality: "ApplicationModal"
+ property alias browser: browser
+ property bool showTab: false
+
+ Browser {
+ id: browser
+ bModel: _browserDialog
+ bAction: _browserActionDialog
+ anchors.fill: parent
+ showTab: finderBrowser.showTab
+ }
+ onVisibleChanged:{
+ if(visible == false)
+ browser.bModel.stopLoading()
+ else
+ browser.navBar.toggleUrlEdit(true)
+ }
+}
diff --git a/buttleofx/gui/dialogs/BrowserOpenDialog.qml b/buttleofx/gui/dialogs/BrowserOpenDialog.qml
new file mode 100644
index 00000000..d73d6ec0
--- /dev/null
+++ b/buttleofx/gui/dialogs/BrowserOpenDialog.qml
@@ -0,0 +1,16 @@
+import QtQuick 2.0
+
+BrowserDialog{
+ id: root
+ title: 'Open Graph'
+
+ Connections{
+ target: root.browser.fileWindow
+ onItemDoubleClicked:{
+ if (!isFolder && absolutePath != "") {
+ _buttleData.loadData(absolutePath)
+ root.visible = false
+ }
+ }
+ }
+}
diff --git a/buttleofx/gui/dialogs/BrowserSaveDialog.qml b/buttleofx/gui/dialogs/BrowserSaveDialog.qml
new file mode 100644
index 00000000..f2492bcd
--- /dev/null
+++ b/buttleofx/gui/dialogs/BrowserSaveDialog.qml
@@ -0,0 +1,111 @@
+import QtQuick 2.2
+import QtQuick.Layouts 1.1
+import QtQml 2.1
+import QtQuick 2.0
+import QtQuick.Window 2.1
+import QtQuick.Dialogs 1.1
+import QtQuick.Controls 1.0
+import QtQuick.Controls.Styles 1.0
+
+
+import "../browser_v2/qml/"
+
+// BrowserSave dialog: used to save a comp.
+// the connecitons are done MainWindow.qml (i.e the Component which use this dialog)
+
+BrowserDialog{
+ id: root
+ title: 'Save the Graph'
+ signal saveButtonClicked(string absoluteFilePath)
+ property variant idBrowserOpenDialog: undefined
+ property string action
+
+ function show(doAction) {
+ root.action = doAction
+ root.visible = true
+ }
+
+
+ onSaveButtonClicked: {
+ if (absoluteFilePath != "") {
+ _buttleData.urlOfFileToSave = absoluteFilePath
+ _buttleData.saveData(_buttleData.urlOfFileToSave)
+
+ root.visible = false
+
+ if (root.action == "open" && idBrowserOpenDialog)
+ idBrowserOpenDialog.visible = true
+ else if (root.action == "new")
+ _buttleData.newData()
+ else if (root.action == "close")
+ Qt.quit()
+ }
+ }
+
+ RowLayout {
+ id: bottomRow
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ anchors.bottom: parent.bottom
+ width: root.width - 8
+ spacing: 0
+
+ TextField {
+ id: entryBar
+ Layout.fillWidth: true
+ style:
+ TextFieldStyle {
+ selectionColor: "#00b2a1"
+ textColor: "#2E2E2E"
+ background: Rectangle {
+ id: entryStyle
+ color: "#DDDDDD"
+ border.color: "#00b2a1"
+ radius: 3
+ border.width: 1
+ states: [
+ State {
+ name: "out"
+ when: !entryBar.focus
+ PropertyChanges {
+ target: entryStyle
+ border.width: 0
+ }
+ }
+ ]
+ }
+ }
+ }
+
+ Button{
+ text: "Save"
+ onClicked: saveButtonClicked(entryBar.text)
+
+ style: ButtonStyle {
+ background: Rectangle {
+ id: buttonRectangle
+ radius: 3
+ implicitWidth: 100
+ implicitHeight: 25
+
+ border.color: "#9F9C99";
+ border.width: 1;
+
+ gradient: Gradient {
+ GradientStop { position: 0; color: control.pressed ? "#EFEBE7" : "#EFEBE7" }
+ GradientStop { position: .5; color: control.pressed ? "#D9D9D9" : "#EFEBE7" }
+ GradientStop { position: 0; color: control.pressed ? "#EFEBE7" : "#EFEBE7" }
+ }
+ }
+ }
+ }
+ }
+
+ Connections{
+ target: root.browser.fileWindow
+ onItemClicked: {
+ entryBar.text = absolutePath + (isFolder ? '/buttleSave_now.bofx' : '')
+ }
+ }
+ Component.onCompleted: entryBar.text = root.browser.bModel.currentPath + 'buttleSave_now.bofx'
+}
diff --git a/buttleofx/gui/dialogs/ExitDialog.qml b/buttleofx/gui/dialogs/ExitDialog.qml
new file mode 100644
index 00000000..5dff85de
--- /dev/null
+++ b/buttleofx/gui/dialogs/ExitDialog.qml
@@ -0,0 +1,111 @@
+import QtQuick 2.1
+import QtQuick.Window 2.1
+import QtQuick.Layouts 1.0
+import QtQuick.Controls 1.0
+import QtQuick.Controls.Styles 1.0
+
+Window {
+ id: exitDialog
+ width: 470
+ height: 120
+ title: "Save Changes?"
+ color: "#272727"
+ flags: Qt.Dialog
+ modality: "ApplicationModal"
+
+ property string dialogText: "Do you want to save before exiting?
If you don't, all unsaved changes will be lost."
+
+ signal saveButtonClicked
+ signal discardButtonClicked
+
+ Component {
+ id: buttonStyle
+
+ ButtonStyle {
+ background: Rectangle {
+ id: buttonRectangle
+ radius: 6
+ implicitWidth: 100
+ implicitHeight: 25
+
+ border.color: "#9F9C99";
+ border.width: 1;
+ opacity: 0.7
+
+ gradient: Gradient {
+ GradientStop { position: 0; color: control.pressed ? "#EFEBE7" : "#EFEBE7" }
+ GradientStop { position: .5; color: control.pressed ? "#D9D9D9" : "#EFEBE7" }
+ GradientStop { position: 0; color: control.pressed ? "#EFEBE7" : "#EFEBE7" }
+ }
+
+ states:
+ State {
+ name: "mouse-over";
+ when: control.hovered
+ PropertyChanges {
+ target: buttonRectangle;
+ border.color: "#00B2A1";
+ opacity: 1}
+ }
+ transitions: Transition {
+ NumberAnimation {
+ properties: "opacity, border.width";
+ easing.type: Easing.InOutQuad;
+ duration: 200
+ }
+ }
+ }
+ }
+ }
+
+ ColumnLayout {
+ anchors.centerIn: parent
+ spacing: 15
+
+ RowLayout {
+ spacing: 20
+
+ Image { source: "../img/icons/cropped-buttle.png" }
+
+ Text {
+ text: dialogText
+ color: "#FEFEFE"
+ }
+ }
+
+ RowLayout {
+ anchors.horizontalCenter: parent.horizontalCenter
+ spacing: 6
+
+ Button {
+ id: saveButton
+ text: "Save"
+ style: buttonStyle
+ isDefault: true
+
+ onClicked: {
+ exitDialog.saveButtonClicked()
+ exitDialog.visible = false
+ }
+ }
+
+ Button {
+ id: discardButton
+ text: "Discard"
+ style: buttonStyle
+
+ onClicked: {
+ exitDialog.discardButtonClicked()
+ exitDialog.visible = false
+ }
+ }
+
+ Button {
+ id: abortButton
+ text: "Abort"
+ style: buttonStyle
+ onClicked: exitDialog.visible = false
+ }
+ }
+ }
+}
diff --git a/buttleofx/gui/dialogs/FileViewerDialog.qml b/buttleofx/gui/dialogs/FileViewerDialog.qml
new file mode 100644
index 00000000..956323e5
--- /dev/null
+++ b/buttleofx/gui/dialogs/FileViewerDialog.qml
@@ -0,0 +1,228 @@
+import QtQuick 2.1
+import QtQuick.Window 2.1
+import QtQuick.Layouts 1.0
+import QtQuick.Controls 1.0
+import QtQuick.Controls.Styles 1.0
+import Qt.labs.folderlistmodel 2.1
+
+Window {
+ id: fileViewerWindow
+ width: 630
+ height: 380
+ color: "#141414"
+ flags: Qt.Dialog
+
+ property string buttonText
+ property string folderModelFolder
+ property string entryBarText: entryBar.text
+
+ signal buttonClicked(string currentFile)
+
+ FolderListModel {
+ id: folderModel
+ showDirsFirst: true
+ folder: _buttleData.homeDir
+ }
+
+ ColumnLayout {
+ anchors.fill: parent
+ anchors.margins: 4
+
+ RowLayout {
+ id: headerBar
+ anchors.top: parent.top
+ anchors.leftMargin: parent.spacing
+ anchors.rightMargin: parent.spacing
+
+ Button {
+ id: parentFolderButton
+ width: 15
+ height: 15
+
+ iconSource:
+ if (hovered) {
+ "../browser_v2/qml/img/parent_hover.png"
+ } else {
+ "../browser_v2/qml/img/parent.png"
+ }
+
+ style:
+ ButtonStyle {
+ background: Rectangle {
+ anchors.fill: parent
+ color: "transparent"
+ }
+ }
+
+ onClicked: {
+ folderModel.folder = folderModel.parentFolder
+ }
+ }
+
+ Rectangle {
+ Layout.fillWidth: true
+ height: 24
+ color: "black"
+ radius: 5
+ border.color: "grey"
+
+ TextInput {
+ id: urlBar
+ x: 5
+ y: 4
+
+ text: folderModel.folder.toString().substring(7)
+ readOnly: true
+ selectByMouse: true
+ Layout.fillWidth: true
+
+ color: "white"
+ selectionColor: "#00b2a1"
+ }
+ }
+ }
+
+ ScrollView {
+ anchors.fill: parent
+
+ style: ScrollViewStyle {
+ scrollBarBackground: Rectangle {
+ id: scrollBar
+ width: styleData.hovered ? 8 : 4
+ color: "transparent"
+
+ Behavior on width { PropertyAnimation { easing.type: Easing.InOutQuad ; duration: 200 } }
+ }
+
+ handle: Item {
+ implicitWidth: 15
+ Rectangle {
+ color: "#00b2a1"
+ anchors.fill: parent
+ }
+ }
+
+ decrementControl : Rectangle {
+ visible: false
+ }
+
+ incrementControl : Rectangle {
+ visible: false
+ }
+ }
+
+ GridView {
+ id: folderView
+ model: folderModel
+ anchors.fill: parent
+ anchors.topMargin: 20
+ cellWidth: 150
+ cellHeight: 100
+ boundsBehavior: Flickable.StopAtBounds
+ focus: true
+
+ highlight: Rectangle {
+ width: folderView.cellWidth
+ height: folderView.cellHeight
+ color: "#00b2a1"
+ radius: 4
+
+ x: folderView.currentItem.x
+ y: folderView.currentItem.y
+ Behavior on x { SmoothedAnimation { duration: -1; velocity: -1 } }
+ Behavior on y { SmoothedAnimation { duration: -1; velocity: -1 } }
+ }
+
+ delegate: Rectangle {
+ width: folderView.cellWidth
+ height: folderView.cellHeight
+ color: "transparent"
+
+ Rectangle{
+ Image {
+ anchors.horizontalCenter: parent.horizontalCenter
+ width: 55
+ height: 55
+ asynchronous: true
+ fillMode: Image.PreserveAspectFit
+ sourceSize.width: width
+ sourceSize.height: height
+ property variant supportedFormats: ["bmp", "gif", "jpg", "jpeg", "png", "pbm", "pgm", "ppm", "xbm", "xpm"]
+
+ source: {
+ if (folderModel.isFolder(index)) {
+ "../browser_v2/qml/img/folder-icon.png"
+ } else if (supportedFormats.indexOf(folderModel.get(index, "fileSuffix").toLowerCase()) != -1) {
+ folderModel.get(index, "filePath")
+ } else {
+ "../browser_v2/qml/img/file-icon.png"
+ }
+ }
+ }
+
+ Text {
+ text: fileName
+ color: "white"
+ width: folderView.cellWidth - 10
+ horizontalAlignment: Text.AlignHCenter
+ wrapMode: Text.WrapAnywhere
+ }
+ }
+
+ MouseArea {
+ anchors.fill: parent
+
+ onClicked: {
+ folderView.currentIndex = index
+ if (!folderModel.isFolder(index)) {
+ entryBar.text = folderModel.get(index, "fileName")
+ } else {
+ entryBar.text = ""
+ }
+ }
+ onDoubleClicked: {
+ if (folderModel.isFolder(index)) {
+ folderModel.folder = folderModel.get(index, "filePath")
+ }
+ }
+ }
+ }
+ }
+ }
+
+ RowLayout {
+ id: bottomRow
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ anchors.bottom: parent.bottom
+
+ TextField {
+ id: entryBar
+ Layout.fillWidth: true
+ }
+
+ Button {
+ text: buttonText
+
+ style:
+ ButtonStyle {
+ background: Rectangle {
+ radius: 6
+ implicitWidth: 100
+ implicitHeight: 25
+
+ border.color: control.hovered ? "#00B2A1" : "#9F9C99"
+ border.width: control.hovered ? 3 : 2
+
+ gradient: Gradient {
+ GradientStop { position: 0; color: control.pressed ? "#EFEBE7" : "#EFEBE7" }
+ GradientStop { position: .5; color: control.pressed ? "#D9D9D9" : "#EFEBE7" }
+ GradientStop { position: 0; color: control.pressed ? "#EFEBE7" : "#EFEBE7" }
+ }
+ }
+ }
+ onClicked: fileViewerWindow.buttonClicked(folderModel.folder + "/" + entryBarText)
+ }
+ }
+ }
+}
diff --git a/buttleofx/gui/graph/qml/FinderLoadGraph.qml b/buttleofx/gui/graph/qml/FinderLoadGraph.qml
deleted file mode 100644
index 5462f2f6..00000000
--- a/buttleofx/gui/graph/qml/FinderLoadGraph.qml
+++ /dev/null
@@ -1,18 +0,0 @@
-import QtQuick 2.0
-import QtQuick.Dialogs 1.0
-
-FileDialog {
- signal getFileUrl(string fileurl)
-
- id: finderLoadGraph
- title: "Open a graph"
- folder: _buttleData.buttlePath
- nameFilters: ["ButtleOFX Graph files (*.bofx)", "All files (*)"]
- selectedNameFilter: "All files (*)"
-
- onAccepted: {
- console.log(finderLoadGraph.fileUrl)
- _buttleData.loadData(finderLoadGraph.fileUrl)
- getFileUrl(finderLoadGraph.fileUrl)
- }
-}
diff --git a/buttleofx/gui/graph/qml/FinderSaveGraph.qml b/buttleofx/gui/graph/qml/FinderSaveGraph.qml
deleted file mode 100644
index 34a964f7..00000000
--- a/buttleofx/gui/graph/qml/FinderSaveGraph.qml
+++ /dev/null
@@ -1,19 +0,0 @@
-import QtQuick 2.0
-import QtQuick.Dialogs 1.0
-
-FileDialog {
- signal getFileUrl(string fileurl)
-
- id: finderSaveGraph
- title: "Save the graph"
- folder: _buttleData.buttlePath
- nameFilters: ["ButtleOFX Graph files (*.bofx)", "All files (*)"]
- selectedNameFilter: "All files (*)"
-
- onAccepted: {
- _buttleData.saveData(finderSaveGraph.fileUrl)
- getFileUrl(finderSaveGraph.fileUrl)
- }
-
- selectExisting: false
-}
diff --git a/buttleofx/gui/graph/qml/Tools.qml b/buttleofx/gui/graph/qml/Tools.qml
index 857a4c63..3ed7baad 100644
--- a/buttleofx/gui/graph/qml/Tools.qml
+++ b/buttleofx/gui/graph/qml/Tools.qml
@@ -1,7 +1,7 @@
import QtQuick 2.0
-import QtQuick.Dialogs 1.0
import "../../plugin/qml"
+import "../../dialogs"
Rectangle {
id: tools
@@ -13,6 +13,32 @@ Rectangle {
signal clickCreationNode(string nodeType)
+ BrowserOpenDialog{
+ id: finderLoadGraph
+ }
+
+ BrowserSaveDialog{
+ id: finderSaveGraph
+ }
+
+ ExitDialog {
+ id: openGraph
+ visible: false
+ dialogText: "Do you want to save before closing this file?
If you don't, all unsaved changes will be lost"
+
+ onSaveButtonClicked: {
+ if (urlOfFileToSave != "") {
+ _buttleData.saveData(urlOfFileToSave)
+ finderLoadGraph.visible = true
+ } else {
+ finderSaveGraph.show("open")
+ }
+ }
+ onDiscardButtonClicked: {
+ finderLoadGraph.visible = true
+ }
+ }
+
gradient: Gradient {
GradientStop { position: 0.0; color: gradian2 }
GradientStop { position: 0.85; color: gradian2 }
@@ -39,13 +65,13 @@ Rectangle {
locked: false
onClicked: {
- if (pluginVisible==true){
- pluginVisible=false
+ if (pluginVisible == true){
+ pluginVisible = false
} else {
- pluginVisible=true
+ pluginVisible = true
}
- editNode=false
+ editNode = false
}
}
@@ -62,11 +88,9 @@ Rectangle {
editNode = false
if (!_buttleData.graphCanBeSaved) {
- finderLoadGraph.open()
+ finderLoadGraph.visible = true
} else {
- openGraph.open()
- openGraph.close()
- openGraph.open()
+ openGraph.visible = true
}
}
}
@@ -82,10 +106,11 @@ Rectangle {
onClicked: {
pluginVisible = false
editNode = false
+
if (urlOfFileToSave != "") {
_buttleData.saveData(urlOfFileToSave)
} else {
- finderSaveGraph.open()
+ finderSaveGraph.show("save")
}
}
}
diff --git a/buttleofx/gui/img/icons/cropped-buttle.png b/buttleofx/gui/img/icons/cropped-buttle.png
new file mode 100644
index 00000000..20e4a95a
Binary files /dev/null and b/buttleofx/gui/img/icons/cropped-buttle.png differ
diff --git a/buttleofx/main.py b/buttleofx/main.py
index 23fc3840..8f2df621 100644
--- a/buttleofx/main.py
+++ b/buttleofx/main.py
@@ -38,8 +38,8 @@
from buttleofx.event import globalButtleEvent
from buttleofx.manager import globalButtleManager
from buttleofx.core.undo_redo.manageTools import globalCommandManager
-from buttleofx.gui.browser_v2.browserModel import BrowserModel, globalBrowserModel
-from buttleofx.gui.browser_v2.actions.browserAction import globalBrowserAction
+from buttleofx.gui.browser_v2.browserModel import BrowserModel, globalBrowser, globalBrowserDialog
+from buttleofx.gui.browser_v2.actions.browserAction import globalBrowserAction, globalBrowserActionDialog
from buttleofx.gui.browser_v2.actions.browserAction import globalActionManager
from PyQt5 import QtCore, QtGui, QtQml, QtQuick, QtWidgets
@@ -80,48 +80,50 @@
class EventFilter(QtCore.QObject):
+ def __init__(self, app, engine):
+ self.mainApp = app
+ self.mainEngine = engine
+ self.buttleData = globalButtleData
+ super(EventFilter, self).__init__()
+
+ def onSaveDialogButtonClicked(self, fileToSave):
+ self.buttleData.urlOfFileToSave = fileToSave
+ self.buttleData.saveData(QtCore.QUrl(self.buttleData.urlOfFileToSave))
+ QtCore.QCoreApplication.quit()
+
+ def onExitDialogDiscardButtonClicked(self):
+ QtCore.QCoreApplication.quit()
+
+ def onExitDialogSaveButtonClicked(self):
+ if self.buttleData.urlOfFileToSave:
+ self.buttleData.saveData(self.buttleData.urlOfFileToSave)
+ QtCore.QCoreApplication.quit()
+ else:
+ saveDialogComponent = QtQml.QQmlComponent(self.mainEngine)
+ saveDialogComponent.loadUrl(QtCore.QUrl(os.path.dirname(os.path.abspath(__file__)) + '/gui/dialogs/BrowserSaveDialog.qml'))
+ saveDialog = saveDialogComponent.create()
+ saveDialog.saveButtonClicked.connect(self.onSaveDialogButtonClicked)
+ saveDialog.show()
+
def eventFilter(self, receiver, event):
if event.type() == QtCore.QEvent.KeyPress:
- # If alt f4 event ignored
+ # If Alt F4 event ignored
if event.modifiers() == QtCore.Qt.AltModifier and event.key() == QtCore.Qt.Key_F4:
event.ignore()
if event.type() != QtCore.QEvent.Close:
return QtCore.QObject.eventFilter(self, receiver, event)
if not isinstance(receiver, QtQuick.QQuickWindow) or not receiver.title() == "ButtleOFX":
return False
- if not globalButtleData.graphCanBeSaved:
- return False
- msgBox = QtWidgets.QMessageBox()
- msgBox.setText("Save graph changes before closing ?")
- msgBox.setModal(True)
- msgBox.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
- msgBox.setInformativeText("If you don't save the graph, unsaved modifications will be lost.")
- msgBox.setStandardButtons(
- QtWidgets.QMessageBox.Save | QtWidgets.QMessageBox.Discard | QtWidgets.QMessageBox.Abort)
- msgBox.setDefaultButton(QtWidgets.QMessageBox.Save)
- ret = msgBox.exec_()
-
- if ret == QtWidgets.QMessageBox.Save:
- if globalButtleData.urlOfFileToSave:
- # Save on the already existing file
- globalButtleData.saveData(globalButtleData.urlOfFileToSave)
- # Close the application
- return QtCore.QObject.eventFilter(self, receiver, event)
-
- # This project has never been saved, so ask the user on which file to save.
- dialog = QtWidgets.QFileDialog()
- fileToSave = dialog.getSaveFileName(None, "Save the graph", os.path.expanduser("~"))[0]
- if not (fileToSave.endswith(".bofx")):
- fileToSave += ".bofx"
- globalButtleData.urlOfFileToSave = fileToSave
- globalButtleData.saveData(fileToSave)
- # Close the application
- return QtCore.QObject.eventFilter(self, receiver, event)
+ if not self.buttleData.graphCanBeSaved:
+ return False
- if ret == QtWidgets.QMessageBox.Discard:
- # Close the application
- return QtCore.QObject.eventFilter(self, receiver, event)
+ exitDialogComponent = QtQml.QQmlComponent(self.mainEngine)
+ exitDialogComponent.loadUrl(QtCore.QUrl(os.path.dirname(os.path.abspath(__file__)) + '/gui/dialogs/ExitDialog.qml'))
+ exitDialog = exitDialogComponent.create()
+ exitDialog.saveButtonClicked.connect(self.onExitDialogSaveButtonClicked)
+ exitDialog.discardButtonClicked.connect(self.onExitDialogDiscardButtonClicked)
+ exitDialog.show()
# Don't call the parent class, so we don't close the application
return True
@@ -237,15 +239,17 @@ def main(argv, app):
parser.add_argument('folder', nargs='?', help='Folder to browse')
args = parser.parse_args()
- globalBrowserModel.setCurrentPath(os.path.abspath(args.folder) if args.folder else globalBrowserModel.getHomePath())
+ globalBrowser.setCurrentPath(os.path.abspath(args.folder) if args.folder else globalBrowser.getHomePath())
# Expose data to QML
rc = engine.rootContext()
rc.setContextProperty("_buttleApp", app)
rc.setContextProperty("_buttleData", globalButtleData)
rc.setContextProperty("_buttleManager", buttleManager)
rc.setContextProperty("_buttleEvent", globalButtleEvent)
- rc.setContextProperty("_browser", globalBrowserModel)
+ rc.setContextProperty("_browser", globalBrowser)
+ rc.setContextProperty("_browserDialog", globalBrowserDialog)
rc.setContextProperty("_browserAction", globalBrowserAction)
+ rc.setContextProperty("_browserActionDialog", globalBrowserActionDialog)
rc.setContextProperty("_actionManager", globalActionManager)
iconPath = os.path.join(currentFilePath, "../blackMosquito.png")
@@ -284,9 +288,11 @@ def main(argv, app):
logging.debug("Watch directory: %s", parentDir)
qic.addFilesFromDirectory(parentDir, recursive=True)
- aFilter = EventFilter()
+ aFilter = EventFilter(app, engine)
app.installEventFilter(aFilter)
- globalBrowserModel.loadData()
+
+ globalBrowser.loadData()
+ globalBrowserDialog.loadData()
with globalActionManager:
topLevelItem.show()