From 60bae901a00dc2352dee81d52a3048c54d288dda Mon Sep 17 00:00:00 2001 From: Xuan Sang LE Date: Sun, 28 Jan 2018 16:33:49 +0100 Subject: [PATCH] VFS (contd) --- src/core/BaseDialog.coffee | 13 +++++-- src/core/schemes/filedialog.html | 3 +- src/core/tags/afx-file-view.js | 4 +- src/core/tags/afx-float-list.js | 1 + src/core/tags/afx-list-view.js | 3 +- src/core/vfs.coffee | 16 ++++++-- src/packages/Files/main.coffee | 7 ++++ src/packages/NotePad/main.coffee | 65 ++++++++++++++++++++++++-------- 8 files changed, 87 insertions(+), 25 deletions(-) diff --git a/src/core/BaseDialog.coffee b/src/core/BaseDialog.coffee index 8f7e744..a7c7989 100644 --- a/src/core/BaseDialog.coffee +++ b/src/core/BaseDialog.coffee @@ -246,6 +246,7 @@ class FileDiaLog extends BaseDialog main: () -> fileview = @find "fileview" location = @find "location" + filename = @find "filename" me = @ @scheme.set "apptitle", "#{@title}" fileview.set "fetch", (e, f) -> @@ -262,14 +263,20 @@ class FileDiaLog extends BaseDialog fileview.set "data", d.result location.set "items", ( i for i in @systemsetting.VFS.mountpoints when i.type isnt "app" ) location.set "selected", 0 unless location.get "selected" + fileview.set "onfileselect", (f) -> + ($ filename).val f.filename if f.type is "file" (@find "bt-ok").set "onbtclick", (e) -> f = fileview.get "selectedFile" return unless f - return unless f.type is "file" or ( me.data and me.data.seldir ) - me.handler f if me.handler + d = f.path + d = f.path.asFileHandler().parent() if f.type is "file" + me.handler d, ($ filename).val() if me.handler + #sel = if me.data and me.data.selection then me.data.selection else "file" + #me.handler f, ($ filename).val() if me.handler and ((f.type is sel) or (sel is "*")) me.quit() (@find "bt-cancel").set "onbtclick", (e) -> me.quit() - + ($ filename).css("display", "block").val @data.file.basename or "Untitled" if @data and @data.file + this.OS.register "FileDiaLog", FileDiaLog \ No newline at end of file diff --git a/src/core/schemes/filedialog.html b/src/core/schemes/filedialog.html index 1d60918..b830c6c 100644 --- a/src/core/schemes/filedialog.html +++ b/src/core/schemes/filedialog.html @@ -1,8 +1,9 @@ - + +
diff --git a/src/core/tags/afx-file-view.js b/src/core/tags/afx-file-view.js index 64ecd6c..a65153e 100644 --- a/src/core/tags/afx-file-view.js +++ b/src/core/tags/afx-file-view.js @@ -180,13 +180,15 @@ self.root.observable.on("fileselect", function(e){ if(e.id != self.rid) return self.selectedFile = e.data + if(self.onfileselect) + self.onfileselect(e.data) $(self.refs.stbar).html("Selected: " + e.data.filename + " (" + e.data.size + " bytes)") }) self.root.observable.on("filedbclick", function(e){ if(e.id != self.rid ) return if(e.data.type == "file" && self.onfileopen) self.onfileopen(e.data) - else if(self.chdir) + else if(self.chdir && e.data.type == "dir") self.chdir(e.data.path) }) calibre_size() diff --git a/src/core/tags/afx-float-list.js b/src/core/tags/afx-float-list.js index 5eada50..3a68c4a 100644 --- a/src/core/tags/afx-float-list.js +++ b/src/core/tags/afx-float-list.js @@ -141,6 +141,7 @@ } _autoselect(it,i) { + if(self.selidx == i) return true if(!it.selected || it.selected == false) return false var data = { id:self.rid, diff --git a/src/core/tags/afx-list-view.js b/src/core/tags/afx-list-view.js index 016dfd3..6bb6908 100644 --- a/src/core/tags/afx-list-view.js +++ b/src/core/tags/afx-list-view.js @@ -22,7 +22,6 @@ { if(k == "selected") { - console.log("selected", v) if(self.selidx != -1) self.items[self.selidx].selected =false if(self.items[v]) self.items[v].selected = true @@ -122,7 +121,7 @@ _autoselect(it,i) { if(!it.selected || it.selected == false) return false - //if(self.selidx == i) return false + if(self.selidx == i) return true var data = { id:self.rid, data:it, diff --git a/src/core/vfs.coffee b/src/core/vfs.coffee index 4048316..97cc9e8 100644 --- a/src/core/vfs.coffee +++ b/src/core/vfs.coffee @@ -4,6 +4,12 @@ String.prototype.hash = () -> hash = (hash * 33) ^ this.charCodeAt(--i) while i hash >>> 0 +String.prototype.asBase64 = () -> + tmp = encodeURIComponent this + return btoa ( tmp.replace /%([0-9A-F]{2})/g, (match, p1) -> + return String.fromCharCode (parseInt p1, 16) + ) + String.prototype.asFileHandler = () -> list = this.split ":///" switch list[0] @@ -16,12 +22,12 @@ this.OS.API.VFS = {} class BasicFileHandler constructor: (path) -> + @dirty = false + @cache = undefined @setPath path setPath: (p) -> @ready = false - @dirty = false - @cache = undefined return unless p @path = p list = @path.split ":///" @@ -39,10 +45,14 @@ class BasicFileHandler return false if not @basename @basename[0] is "." - hash: () -> + hash: () -> return -1 unless @path return @path.hash() + getb64: (m) -> + return "" unless @cache + b64 = @cache.asBase64() + return "data:#{m};base64,#{b64}" parent: () -> return @ if @isRoot() return (@protocol + ":///" + (@genealogy.slice 0 , @genealogy.length - 1).join "/") diff --git a/src/packages/Files/main.coffee b/src/packages/Files/main.coffee index bff1737..aa288b3 100644 --- a/src/packages/Files/main.coffee +++ b/src/packages/Files/main.coffee @@ -36,6 +36,7 @@ class Files extends this.OS.GUI.BaseApplication @view.set "chdir", (p) -> me.chdir p @view.set "fetch", (e, f) -> return unless e.child + return if e.child.filename is "[..]" e.child.path.asFileHandler().read (d) -> return me.error "Resource not found #{e.child.path}" if d.error f d.result @@ -66,6 +67,12 @@ class Files extends this.OS.GUI.BaseApplication if(d.error) return me.error "Resource not found #{p}" me.currdir = dir + if not dir.isRoot() + p = dir.parent().asFileHandler() + p.filename = "[..]" + p.type = "dir" + #p.size = 0 + d.result.unshift p ($ me.navinput).val dir.path me.view.set "path", dir.path me.view.set "data", d.result diff --git a/src/packages/NotePad/main.coffee b/src/packages/NotePad/main.coffee index f70c638..7166da9 100644 --- a/src/packages/NotePad/main.coffee +++ b/src/packages/NotePad/main.coffee @@ -43,9 +43,9 @@ class NotePad extends this.OS.GUI.BaseApplication mode: m.theme, selected: if m.theme is "ace/theme/monokai" then true else false } for k, m of themes.themesByName - themelist.set "items", ldata themelist.set "onlistselect", (e) -> me.editor.setTheme e.data.mode + themelist.set "items", ldata stat = @find "editorstat" #status @@ -71,12 +71,15 @@ class NotePad extends this.OS.GUI.BaseApplication @fileview.set "chdir", (d) -> me.chdir d @fileview.set "fetch", (e, f) -> return unless e.child + return if e.child.filename is "[..]" e.child.path.asFileHandler().read (d) -> return me.error "Resource not found #{e.child.path}" if d.error f d.result @fileview.set "onfileopen", (e) -> + return if e.type is "dir" me.open e.path.asFileHandler() - @location.set "onlistselect", (e) -> me.chdir e.data.path + @location.set "onlistselect", (e) -> + me.chdir e.data.path @location.set "items", ( i for i in @systemsetting.VFS.mountpoints when i.type isnt "app" ) @location.set "selected", 0 unless @location.get "selected" @tabarea = @find "tabarea" @@ -101,11 +104,18 @@ class NotePad extends this.OS.GUI.BaseApplication return @newtab file if file.path.toString() is "Untitled" me = @ file.read (_d) -> - d = if typeof _d is "string" then _d else JSON.stringify _d - me.scheme.set "apptitle", file.basename + d = if typeof _d is "string" then _d else JSON.stringify _d #TODO file.cache = d or "" me.newtab file + save: (file) -> + me = @ + file.write (file.getb64 "text/plain"), (d) -> + return me.error "Error saving file #{file.basename}" if d.error + file.dirty = false + file.text = file.basename + me.tabarea.update() + findTabByFile: (file) -> lst = @tabarea.get "items" its = ( i for d, i in lst when d.hash() is file.hash() ) @@ -136,6 +146,7 @@ class NotePad extends this.OS.GUI.BaseApplication #return if i is @tabarea.get "selidx" file = (@tabarea.get "items")[i] return unless file + @scheme.set "apptitle", file.text.toString() #return if file is @currfile if @currfile isnt file @currfile.cache = @editor.getValue() @@ -155,16 +166,23 @@ class NotePad extends this.OS.GUI.BaseApplication @editor.selection.moveTo file.cursor.row, file.cursor.column @editor.focus() - chdir: (p) -> + chdir: (pth) -> + #console.log "called", @_api.throwe("FCK") + return unless pth me = @ - me._api.handler.scandir p, - (d) -> - if(d.error) - return me.error "Resource not found #{p}" - me.fileview.set "path", p - me.fileview.set "data", d.result - , (e, s) -> - me.error "Cannot chdir #{p}" + dir = pth.asFileHandler() + dir.read (d) -> + if(d.error) + return me.error "Resource not found #{p}" + if not dir.isRoot() + p = dir.parent().asFileHandler() + p.filename = "[..]" + p.type = "dir" + #p.size = 0 + d.result.unshift p + ($ me.navinput).val dir.path + me.fileview.set "path", pth + me.fileview.set "data", d.result menu: () -> me = @ @@ -172,16 +190,33 @@ class NotePad extends this.OS.GUI.BaseApplication text: "File", child: [ { text: "Open", dataid: "#{@name}-Open" }, - { text: "Close", dataid: "#{@name}-Close" } + { text: "Save", dataid: "#{@name}-Save" }, + { text: "Save as", dataid: "#{@name}-Saveas" } ], onmenuselect: (e) -> me.actionFile e }] menu actionFile: (e) -> + me = @ + saveas = () -> + me.openDialog "FileDiaLog", (d, n) -> + me.currfile.setPath "#{d}/#{n}" + me.save me.currfile + , "Save as", { file: me.currfile } switch e.item.data.dataid when "#{@name}-Open" - @openDialog "FileDiaLog", null, "Select file", { seldir: true } + @openDialog "FileDiaLog", ( d, f ) -> + me.open "#{d}/#{f}".asFileHandler() + , "Open file" + when "#{@name}-Save" + @currfile.cache = @editor.getValue() + return @save @currfile if @currfile.basename + saveas() + when "#{@name}-Saveas" + @currfile.cache = @editor.getValue() + saveas() + NotePad.singleton = false this.OS.register "NotePad", NotePad \ No newline at end of file