+
+
+
\ No newline at end of file
diff --git a/src/locales/en.json b/src/locales/en.json
index e5cd4aaf..34e71557 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -105,7 +105,12 @@
"SaveRestart": "Save & Restart",
"SaveClose": "Save & close",
"SuccessfullySaved": "{filename} successfully saved.",
- "FailedSave": "{filename} could not be uploaded!"
+ "FailedSave": "{filename} could not be uploaded!",
+ "UnsavedChanges": "Unsaved Changes",
+ "UnsavedChangesMessage": "Do you want to save your changes made to {filename}?",
+ "UnsavedChangesSubMessage": "Your changes will be lost if you don't save them. You can disable this message in the editor settings.",
+ "DontSave": "Don't save",
+ "Cancel": "Cancel"
},
"Files": {
"GCodeFiles": "G-Code Files",
@@ -664,6 +669,13 @@
"ShowAxes": "Show Axes",
"MinFeed" :"Min Feed Rate",
"MaxFeed" : "Max Feed Rate"
+ },
+ "EditorTab": {
+ "Editor": "Editor",
+ "UseEscToClose": "Use ESC to close editor",
+ "UseEscToCloseDescription": "Allows the ESC key to close the editor",
+ "ConfirmUnsavedChanges": "Prompt to save or discard unsaved changes",
+ "ConfirmUnsavedChangesDescription": "If enabled, the editor requires a confirmation to either save or discard the changes made. If disabled, changes are silently discarded."
}
},
"GCodeViewer":{
diff --git a/src/store/editor/index.ts b/src/store/editor/index.ts
index cfb7b252..5dff1e16 100644
--- a/src/store/editor/index.ts
+++ b/src/store/editor/index.ts
@@ -20,7 +20,9 @@ export const getDefaultState = (): EditorState => {
total: 0,
speed: '',
},
- cancelToken: null
+ cancelToken: null,
+ loadedHash: '',
+ changed: false
}
}
diff --git a/src/store/editor/mutations.ts b/src/store/editor/mutations.ts
index be8fcc23..874fb38a 100644
--- a/src/store/editor/mutations.ts
+++ b/src/store/editor/mutations.ts
@@ -2,8 +2,10 @@ import { getDefaultState } from './index'
import {MutationTree} from 'vuex'
import {EditorState} from '@/store/editor/types'
import Vue from 'vue'
+import { sha256 } from 'js-sha256'
export const mutations: MutationTree = {
+
reset(state) {
Object.assign(state, getDefaultState())
},
@@ -25,6 +27,13 @@ export const mutations: MutationTree = {
Vue.set(state, 'fileroot', payload.fileroot)
Vue.set(state, 'filepath', payload.filepath)
Vue.set(state, 'sourcecode', payload.file)
+
+ // Because the used editor converts all Windows-Style line endings with unix ones on load,
+ // the hash is computed with the source always having unix-style line endings.
+ // https://github.com/codemirror/CodeMirror/issues/3395
+
+ Vue.set(state, 'loadedHash', sha256(payload.file.replace(/(?:\r\n|\r|\n)/g, '\n')))
+ Vue.set(state, 'changed', false)
Vue.set(state, 'bool', true)
},
@@ -42,5 +51,24 @@ export const mutations: MutationTree = {
updateSourcecode(state, payload) {
Vue.set(state, 'sourcecode', payload)
+
+ // To check if a file has been changed by the user, we need to calculate a hash
+ // (or otherwise we would need to save the full file in memory twice). Simply listening
+ // to the changed event is not enough, because if the user types an "a" and then deletes
+ // the "a" again, the file would still be shown as changed, even though the edited file
+ // is equal to the stored file.
+
+ // I've tested this functionality with huge text files (60MB G-Code) and while calculating
+ // the hash took 2 seconds per run, the editor itself is pretty laggy even without hash
+ // calculations. Hash calculations with typical config file sizes (50KB) only take 1 or 2ms
+ // on my machine, so I guess this is acceptable for most use cases.
+
+ if (sha256(payload) != state.loadedHash)
+ state.changed = true
+ else
+ state.changed = false
}
+
}
+
+
diff --git a/src/store/editor/types.ts b/src/store/editor/types.ts
index d8e622cb..fa2d6f3d 100644
--- a/src/store/editor/types.ts
+++ b/src/store/editor/types.ts
@@ -13,5 +13,7 @@ export interface EditorState {
total: number
speed: string
},
- cancelToken: any
+ cancelToken: any,
+ loadedHash: string,
+ changed: boolean
}
\ No newline at end of file
diff --git a/src/store/gui/index.ts b/src/store/gui/index.ts
index 9c5d13f7..1cc5600f 100644
--- a/src/store/gui/index.ts
+++ b/src/store/gui/index.ts
@@ -167,7 +167,9 @@ export const getDefaultState = (): GuiState => {
}
},
editor: {
- minimap: false
+ minimap: false,
+ escToClose: true,
+ confirmUnsavedChanges: true
},
//moonraker DB api dont accept camel case key names
remotePrinters: [],
@@ -194,7 +196,7 @@ export const getDefaultState = (): GuiState => {
voxelWidth: 1,
voxelHeight: 1,
specularLighting: false,
- }
+ },
}
}