add localisation support, allow multi-languages

This commit is contained in:
Xuan Sang LE 2018-03-09 19:54:33 +01:00
parent 696114e2f7
commit 9e0cd29030
27 changed files with 370 additions and 170 deletions

View File

@ -6,6 +6,7 @@ NC=\033[0m
coffees= src/core/core.coffee\ coffees= src/core/core.coffee\
src/core/api.coffee\ src/core/api.coffee\
src/core/lang/generator.coffee\
src/core/settings.coffee\ src/core/settings.coffee\
src/core/handlers/RemoteHandler.coffee\ src/core/handlers/RemoteHandler.coffee\
src/core/vfs.coffee\ src/core/vfs.coffee\
@ -56,7 +57,8 @@ testdata:
cp src/core/handlers/jsons/* $(BUILDDIR)/resources/jsons cp src/core/handlers/jsons/* $(BUILDDIR)/resources/jsons
build_tags: build_tags:
@echo "$(BLUE)Building tag files$(NC)" @echo "$(BLUE)Building tag files$(NC)"
-mkdir $(BUILDDIR)/resources -mkdir $(BUILDDIR)/resources
-mkdir $(BUILDDIR)/resources/languages
-rm $(BUILDDIR)/resources/antos_tags.js -rm $(BUILDDIR)/resources/antos_tags.js
for f in src/core/tags/*; do (cat "$${f}"; echo) >> $(BUILDDIR)/resources/antos_tags.js; done for f in src/core/tags/*; do (cat "$${f}"; echo) >> $(BUILDDIR)/resources/antos_tags.js; done

View File

@ -77,8 +77,8 @@ class BaseApplication extends this.OS.GUI.BaseModel
[{ [{
text: _OS.APP[@name].meta.name, text: _OS.APP[@name].meta.name,
child: [ child: [
{ text: "About", dataid: "#{@name}-about" }, { text: __("About"), dataid: "#{@name}-about" },
{ text: "Exit", dataid: "#{@name}-exit" } { text: __("Exit"), dataid: "#{@name}-exit" }
] ]
}] }]
mn = mn.concat @menu() || [] mn = mn.concat @menu() || []

View File

@ -87,7 +87,7 @@ class PromptDialog extends BasicDialog
resizable: false, resizable: false,
buttons: [ buttons: [
{ {
label: "0k", label: __("0k"),
onclick: (d) -> onclick: (d) ->
txt = (d.find "content1").value txt = (d.find "content1").value
return d.quit() if txt is "" return d.quit() if txt is ""
@ -95,7 +95,7 @@ class PromptDialog extends BasicDialog
d.quit() d.quit()
}, },
{ {
label: "Cancel", label: __("Cancel"),
onclick: (d) -> d.quit() onclick: (d) -> d.quit()
} }
], ],
@ -119,17 +119,17 @@ class CalendarDialog extends BasicDialog
resizable: false, resizable: false,
buttons: [ buttons: [
{ {
label: 'Ok', label: __('Ok'),
onclick: (d) -> onclick: (d) ->
date = (d.find "content0").get "selectedDate" date = (d.find "content0").get "selectedDate"
if date if date
d.handler date if d.handler d.handler date if d.handler
d.quit() d.quit()
else else
d.notify "Please select a date" d.notify __("Please select a date")
}, },
{ {
label: 'Cancel', label: __('Cancel'),
onclick: (d) -> d.quit() onclick: (d) -> d.quit()
} }
] ]
@ -145,7 +145,7 @@ class ColorPickerDialog extends BasicDialog
resizable: false, resizable: false,
buttons: [ buttons: [
{ {
label: 'Ok', label: __('Ok'),
onclick: (d) -> onclick: (d) ->
c = (d.find "content0").get "selectedColor" c = (d.find "content0").get "selectedColor"
if c if c
@ -155,7 +155,7 @@ class ColorPickerDialog extends BasicDialog
d.notify "Please select a color" d.notify "Please select a color"
}, },
{ {
label: 'Cancel', label: __('Cancel'),
onclick: (d) -> d.quit() onclick: (d) -> d.quit()
} }
] ]
@ -169,7 +169,7 @@ class InfoDialog extends BasicDialog
width: 250, width: 250,
height: 300, height: 300,
resizable: true, resizable: true,
buttons: [ { label: 'Cancel', onclick: (d) -> d.quit() } ], buttons: [ { label: __('Cancel'), onclick: (d) -> d.quit() } ],
filldata: (d) -> filldata: (d) ->
return unless d.data return unless d.data
rows = [] rows = []
@ -188,12 +188,12 @@ class YesNoDialog extends BasicDialog
resizable: true, resizable: true,
buttons: [ buttons: [
{ {
label: "Yes", onclick: (d) -> label: __("Yes"), onclick: (d) ->
d.handler true if d.handler d.handler true if d.handler
d.quit() d.quit()
}, },
{ {
label: "No", onclick: (d) -> label: __("No"), onclick: (d) ->
d.handler false if d.handler d.handler false if d.handler
d.quit() d.quit()
} }
@ -215,14 +215,14 @@ class SelectionDialog extends BasicDialog
resizable: false, resizable: false,
buttons: [ buttons: [
{ {
label: "Ok", onclick: (d) -> label: __("Ok"), onclick: (d) ->
el = d.find "content0" el = d.find "content0"
it = el.get "selected" it = el.get "selected"
return unless it return unless it
d.handler it if d.handler d.handler it if d.handler
d.quit() d.quit()
}, },
{ label: "Cancel", onclick: (d) -> d.quit() } { label: __("Cancel"), onclick: (d) -> d.quit() }
], ],
filldata: (d) -> filldata: (d) ->
return unless d.data return unless d.data
@ -243,7 +243,7 @@ class AboutDialog extends BaseDialog
main: () -> main: () ->
mt = @meta() mt = @meta()
@scheme.set "apptitle", "About: #{mt.name}" @scheme.set "apptitle", __("About: {0}",mt.name)
(@find "mylabel").set "*", {icon:mt.icon, iconclass:mt.iconclass, text:"#{mt.name}(v#{mt.version})"} (@find "mylabel").set "*", {icon:mt.icon, iconclass:mt.iconclass, text:"#{mt.name}(v#{mt.version})"}
($ @find "mydesc").html mt.description ($ @find "mydesc").html mt.description
# grid data for author info # grid data for author info
@ -270,13 +270,13 @@ class FileDiaLog extends BaseDialog
fileview.set "fetch", (e, f) -> fileview.set "fetch", (e, f) ->
return unless e.child return unless e.child
e.child.path.asFileHandler().read (d) -> e.child.path.asFileHandler().read (d) ->
return me.error "Resource not found #{e.child.path}" if d.error return me.error __("Resource not found: {0}", e.child.path) if d.error
f d.result f d.result
location.set "onlistselect", (e) -> location.set "onlistselect", (e) ->
return unless e and e.data.path return unless e and e.data.path
e.data.path.asFileHandler().read (d) -> e.data.path.asFileHandler().read (d) ->
if(d.error) if(d.error)
return me.error "Resource not found #{e.data.path}" return me.error __("Resource not found: {0}", e.data.path)
fileview.set "path", e.data.path fileview.set "path", e.data.path
fileview.set "data", d.result fileview.set "data", d.result
location.set "items", ( i for i in @systemsetting.VFS.mountpoints when i.type isnt "app" ) location.set "items", ( i for i in @systemsetting.VFS.mountpoints when i.type isnt "app" )
@ -286,7 +286,7 @@ class FileDiaLog extends BaseDialog
($ filename).val f.filename if f.type is "file" ($ filename).val f.filename if f.type is "file"
(@find "bt-ok").set "onbtclick", (e) -> (@find "bt-ok").set "onbtclick", (e) ->
f = fileview.get "selectedFile" f = fileview.get "selectedFile"
return me.notify "Please select a file" unless f return me.notify __("Please select a file") unless f
if me.data and me.data.mimes if me.data and me.data.mimes
#verify the mime #verify the mime
m = false m = false
@ -294,7 +294,7 @@ class FileDiaLog extends BaseDialog
if f.mime.match (new RegExp v, "g") if f.mime.match (new RegExp v, "g")
m = true m = true
break break
return me.notify "Only #{me.data.mimes.join(",")} could be selected" unless m return me.notify __("Only {0} could be selected", me.data.mimes.join(",")) unless m
d = f.path d = f.path
d = f.path.asFileHandler().parent() if f.type is "file" d = f.path.asFileHandler().parent() if f.type is "file"
me.handler d, ($ filename).val(), f.path if me.handler me.handler d, ($ filename).val(), f.path if me.handler

View File

@ -43,7 +43,7 @@ class BaseModel
@dialog.show() @dialog.show()
return return
if not _GUI.subwindows[d] if not _GUI.subwindows[d]
@error "Dialog #{d} not found" @error __("Dialog {0} not found", d)
return return
@dialog = new _GUI.subwindows[d]() @dialog = new _GUI.subwindows[d]()
#@dialog.observable = riot.observable() unless @dialog #@dialog.observable = riot.observable() unless @dialog

View File

@ -26,6 +26,22 @@ String.prototype.asUnit8Array = () ->
bytes = new Uint8Array(bytes) bytes = new Uint8Array(bytes)
return bytes return bytes
if not String.prototype.format
String.prototype.format = () ->
args = arguments
return @replace /{(\d+)}/g, (match, number) ->
return if typeof args[number] != 'undefined' then args[number] else match
# language directive
this.__ = () ->
_API = window.OS.API
args = arguments
return "Undefined" unless args.length > 0
d = args[0]
h = if typeof d is "string" then d.hash() else d
_API.lang[h] = d unless _API.lang[h]
return _API.lang[h] unless args.length > 1
return String.prototype.format.apply _API.lang[h], (args[i] for i in [1 .. args.length - 1])
Date.prototype.toString = () -> Date.prototype.toString = () ->
dd = @getDate() dd = @getDate()
mm = @getMonth() + 1 mm = @getMonth() + 1
@ -51,6 +67,7 @@ self.OS.API =
handler: {} handler: {}
shared: {} # shared libraries shared: {} # shared libraries
searchHandler:{} searchHandler:{}
lang:{}
#request a user data #request a user data
mid: () -> mid: () ->
return _courrier.getMID() return _courrier.getMID()
@ -178,7 +195,7 @@ self.OS.API =
_courrier.trigger "sharedlibraryloaded", l _courrier.trigger "sharedlibraryloaded", l
f() if f f() if f
, (e, s) -> , (e, s) ->
_courrier.oserror "Cannot load 3rd library at: #{l}", e, r _courrier.oserror __("Cannot load 3rd library at: {0}", l), e, r
else else
path = "os:///scripts/" path = "os:///scripts/"
js = "#{path}#{l}.js" js = "#{path}#{l}.js"
@ -196,7 +213,7 @@ self.OS.API =
_courrier.trigger "sharedlibraryloaded", l _courrier.trigger "sharedlibraryloaded", l
f() if f f() if f
else else
console.log l, "Library exist, no need to load" console.log l, "Library exist, no need to load"
_courrier.trigger "sharedlibraryloaded", l _courrier.trigger "sharedlibraryloaded", l
requires:(libs, f) -> requires:(libs, f) ->
@ -228,6 +245,15 @@ self.OS.API =
onsearch: (name, fn) -> onsearch: (name, fn) ->
self.OS.API.searchHandler[name] = fn unless self.OS.API.searchHandler[name] self.OS.API.searchHandler[name] = fn unless self.OS.API.searchHandler[name]
setLanguage: (name) ->
path = "resources/languages/#{name}.json"
_API.get path, (d) ->
_OS.setting.user.language = name
_API.lang = d
, (e, s) ->
_courrier.oserror __("Language file {0} not found", path), e, s
, "json"
throwe: (n) -> throwe: (n) ->
err = undefined err = undefined
try try

View File

@ -5,7 +5,7 @@ class DB
_API.handler.dbquery "save", { table: @table, data: d }, f _API.handler.dbquery "save", { table: @table, data: d }, f
delete: (c, f) -> delete: (c, f) ->
rq = { table: @table } rq = { table: @table }
return ( _courrier.oserror "Unknown condition for delete command", return ( _courrier.oserror __("VDB Unknown condition for delete command"),
(_API.throwe "OS.DB"), c ) unless c and c isnt "" (_API.throwe "OS.DB"), c ) unless c and c isnt ""
if isNaN c if isNaN c
rq.cond = c rq.cond = c

View File

@ -9,7 +9,7 @@ self.OS.GUI =
META: {} META: {}
SYS_MENU: [ SYS_MENU: [
{ {
text: "Applications", text: __("Applications"),
child: [], child: [],
dataid: "sys-apps" dataid: "sys-apps"
iconclass: "fa fa-adn", iconclass: "fa fa-adn",
@ -54,7 +54,7 @@ self.OS.GUI =
return return
if not _GUI.subwindows[d] if not _GUI.subwindows[d]
ex = _API.throwe "Dialog" ex = _API.throwe "Dialog"
return _courrier.oserror "Dialog #{d} not found", ex, null return _courrier.oserror __("Dialog {0} not found", d), ex, null
_GUI.dialog = new _GUI.subwindows[d]() _GUI.dialog = new _GUI.subwindows[d]()
_GUI.dialog.parent = _GUI _GUI.dialog.parent = _GUI
_GUI.dialog.handler = f _GUI.dialog.handler = f
@ -73,7 +73,7 @@ self.OS.GUI =
return _PM.createProcess srv, _OS.APP[srv] if _OS.APP[srv] return _PM.createProcess srv, _OS.APP[srv] if _OS.APP[srv]
(e, s) -> (e, s) ->
_courrier.trigger "srvroutineready", srv _courrier.trigger "srvroutineready", srv
_courrier.osfail "Cannot read service script: #{srv} ", e, s _courrier.osfail __("Cannot read service script: {0}", srv), e, s
appsByMime: (mime) -> appsByMime: (mime) ->
metas = ( v for k, v of _OS.setting.system.packages when v and v.app ) metas = ( v for k, v of _OS.setting.system.packages when v and v.app )
@ -88,7 +88,7 @@ self.OS.GUI =
return false return false
return false return false
catch e catch e
_courrier.osfail "Find app by mimes #{mime}", e, mime _courrier.osfail __("Error find app by mimes {0}", mime), e, mime
( f m, i if m ) for m, i in mimes ( f m, i if m ) for m, i in mimes
return apps return apps
@ -101,14 +101,14 @@ self.OS.GUI =
openWith: (it) -> openWith: (it) ->
return unless it return unless it
return _GUI.launch it.app if it.type is "app" and it.app return _GUI.launch it.app if it.type is "app" and it.app
return _courrier.osinfo "Application#{it.text} is not executable" if it.type is "app" return _courrier.osinfo __("Application {0} is not executable", it.text) if it.type is "app"
apps = _GUI.appsByMime ( if it.type is "dir" then "dir" else it.mime ) apps = _GUI.appsByMime ( if it.type is "dir" then "dir" else it.mime )
return _courrier.osinfo "No application available to open #{it.filename}" if apps.length is 0 return _courrier.osinfo __("No application available to open {0}", it.filename) if apps.length is 0
return _GUI.launch apps[0].app, [it.path] if apps.length is 1 return _GUI.launch apps[0].app, [it.path] if apps.length is 1
list = ( { text: e.app, icon: e.icon, iconclass: e.iconclass } for e in apps ) list = ( { text: e.app, icon: e.icon, iconclass: e.iconclass } for e in apps )
_GUI.openDialog "SelectionDialog", ( d ) -> _GUI.openDialog "SelectionDialog", ( d ) ->
_GUI.launch d.text, [it.path] _GUI.launch d.text, [it.path]
, "Open width", list , __("Open with"), list
forceLaunch: (app, args) -> forceLaunch: (app, args) ->
console.log "This method is used for developing only, please use the launch method instead" console.log "This method is used for developing only, please use the launch method instead"
@ -305,8 +305,8 @@ self.OS.GUI =
desktop[0].set "selected", -1 if e.target is desktop[0] desktop[0].set "selected", -1 if e.target is desktop[0]
($ "#sysdock").get(0).set "selectedApp", null ($ "#sysdock").get(0).set "selectedApp", null
menu = [ menu = [
{ text: "Open", dataid: "desktop-open" }, { text: __("Open"), dataid: "desktop-open" },
{ text: "Refresh", dataid: "desktop-refresh" } { text: __("Refresh"), dataid: "desktop-refresh" }
] ]
menu = menu.concat ( v for k, v of _OS.setting.desktop.menu) menu = menu.concat ( v for k, v of _OS.setting.desktop.menu)
m.set "items", menu m.set "items", menu
@ -331,7 +331,7 @@ self.OS.GUI =
# mount it # mount it
riot.mount desktop riot.mount desktop
, (e, s) -> , (e, s) ->
alert "System fall: Cannot init desktop manager" alert __("System fail: Cannot init desktop manager")
console.log s, e console.log s, e
refreshSystemMenu: () -> refreshSystemMenu: () ->
@ -340,11 +340,11 @@ self.OS.GUI =
_GUI.SYS_MENU[0].child.push v for k, v of _OS.setting.system.packages when (v and v.app) _GUI.SYS_MENU[0].child.push v for k, v of _OS.setting.system.packages when (v and v.app)
_GUI.SYS_MENU.push v for k, v of _OS.setting.system.menu _GUI.SYS_MENU.push v for k, v of _OS.setting.system.menu
_GUI.SYS_MENU.push _GUI.SYS_MENU.push
text: "Toggle Full screen", text: __("Toggle Full screen"),
dataid: "os-fullsize", dataid: "os-fullsize",
iconclass: "fa fa-tv" iconclass: "fa fa-tv"
_GUI.SYS_MENU.push _GUI.SYS_MENU.push
text: "Log out", text: __("Log out"),
dataid: "sys-logout", dataid: "sys-logout",
iconclass: "fa fa-user-times" iconclass: "fa fa-user-times"
buildSystemMenu: () -> buildSystemMenu: () ->
@ -378,7 +378,7 @@ self.OS.GUI =
($ "#txtpass").keyup (e) -> ($ "#txtpass").keyup (e) ->
($ "#btlogin").click() if e.which is 13 ($ "#btlogin").click() if e.which is 13
, (e, s) -> , (e, s) ->
alert "System fall: Cannot init login screen" alert __("System fail: Cannot init login screen")
startAntOS: (conf) -> startAntOS: (conf) ->
# clean up things # clean up things

View File

@ -10,36 +10,36 @@ self.OS.API.handler =
scandir: (p, c ) -> scandir: (p, c ) ->
path = "#{_REST}/fs/scandir" path = "#{_REST}/fs/scandir"
_API.post path, { path: p }, c, (e, s) -> _API.post path, { path: p }, c, (e, s) ->
_courrier.osfail "Fail to scan directory: #{p}", e, s _courrier.osfail __("Fail to scan directory: {0}", p), e, s
mkdir: (p, c ) -> mkdir: (p, c ) ->
path = "#{_REST}/fs/mkdir" path = "#{_REST}/fs/mkdir"
_API.post path, { path: p }, c, (e, s) -> _API.post path, { path: p }, c, (e, s) ->
_courrier.osfail "Fail to create directory: #{p}", e, s _courrier.osfail __("Fail to create directory: {0}", p), e, s
sharefile: (p, pub , c) -> sharefile: (p, pub , c) ->
path = "#{_REST}/fs/publish" path = "#{_REST}/fs/publish"
_API.post path, { path: p , publish: pub }, c, (e, s) -> _API.post path, { path: p , publish: pub }, c, (e, s) ->
_courrier.osfail "Fail to publish file: #{p}", e, s _courrier.osfail __("Fail to publish file: {0}", p), e, s
fileinfo: (p, c) -> fileinfo: (p, c) ->
path = "#{_REST}/fs/fileinfo" path = "#{_REST}/fs/fileinfo"
_API.post path, { path: p }, c, (e, s) -> _API.post path, { path: p }, c, (e, s) ->
_courrier.osfail "Fail to get file metadata: #{p}", e, s _courrier.osfail __("Fail to get file meta data: {0}", p), e, s
readfile: (p, c, t) -> readfile: (p, c, t) ->
path = "#{_REST}/fs/get/" path = "#{_REST}/fs/get/"
_API.get path + p, c, (e, s) -> _API.get path + p, c, (e, s) ->
_courrier.osfail "Fail to read file: #{p}", e, s _courrier.osfail __("Fail to read file: {0}", p), e, s
, t , t
move: (s, d, c) -> move: (s, d, c) ->
path = "#{_REST}/fs/move" path = "#{_REST}/fs/move"
_API.post path, { src: s, dest: d }, c, (e, s) -> _API.post path, { src: s, dest: d }, c, (e, s) ->
_courrier.osfail "Fail to move file: #{s} -> #{d}", e, s _courrier.osfail __("Fail to move file: {0} -> {1}", s, d), e, s
delete: (p , c) -> delete: (p , c) ->
path = "#{_REST}/fs/delete" path = "#{_REST}/fs/delete"
_API.post path, { path: p }, c, (e, s) -> _API.post path, { path: p }, c, (e, s) ->
_courrier.osfail "Fail to delete: #{p}", e, s _courrier.osfail __("Fail to delete: {0}", p), e, s
fileblob: (p, c) -> fileblob: (p, c) ->
path = "#{_REST}/fs/get/" path = "#{_REST}/fs/get/"
@ -49,44 +49,44 @@ self.OS.API.handler =
packages: (d, c) -> packages: (d, c) ->
path = "#{_REST}/system/packages" path = "#{_REST}/system/packages"
_API.post path, d, c, (e, s) -> _API.post path, d, c, (e, s) ->
_courrier.osfail "Fail to #{d.command} package", e, s _courrier.osfail __("Fail to {0} package", d.command), e, s
upload: (d, c) -> upload: (d, c) ->
path = "#{_REST}/fs/upload" path = "#{_REST}/fs/upload"
_API.upload path, d, c, (e, s) -> _API.upload path, d, c, (e, s) ->
_courrier.osfail "Fail to upload file to: #{d}", e, s _courrier.osfail __("Fail to upload file to: {0}", d), e, s
write: (p, d , c) -> write: (p, d , c) ->
path = "#{_REST}/fs/write" path = "#{_REST}/fs/write"
_API.post path, { path: p, data: d }, c, (e, s) -> _API.post path, { path: p, data: d }, c, (e, s) ->
_courrier.osfail "Fail to write to file: #{p}", e, s _courrier.osfail __("Fail to write to file: {0}", p), e, s
scanapp: (p, c ) -> scanapp: (p, c ) ->
path = "#{_REST}/system/application" path = "#{_REST}/system/application"
auth: (c) -> auth: (c) ->
p = "#{_REST}/system/auth" p = "#{_REST}/system/auth"
_API.post p, {}, c, () -> _API.post p, {}, c, () ->
alert "Resource not found: #{p}" alert __("Resource not found: {0}", p)
login: (d, c) -> login: (d, c) ->
p = "#{_REST}/system/login" p = "#{_REST}/system/login"
_API.post p, d, c, () -> _API.post p, d, c, () ->
alert "Resource not found: #{p}" alert __("Resource not found: {0}", p)
logout: () -> logout: () ->
p = "#{_REST}/system/logout" p = "#{_REST}/system/logout"
_API.post p, {}, (d) -> _API.post p, {}, (d) ->
_OS.boot() _OS.boot()
, () -> , () ->
alert "Resource not found #{p}" alert __("Resource not found: {0}", p)
setting: (f) -> setting: (f) ->
p = "#{_REST}/system/settings" p = "#{_REST}/system/settings"
_API.post p, _OS.setting, (d) -> _API.post p, _OS.setting, (d) ->
_courrier.oserror "Cannot save system setting", d.error if d.error _courrier.oserror __("Cannot save system setting"), d.error if d.error
f() if f f() if f
, (e, s) -> , (e, s) ->
_courrier.osfail "Fail to make request: #{p}", e, s _courrier.osfail __("Fail to make request: {0}", p), e, s
f() if f f() if f
dbquery: (cmd, d, c) -> dbquery: (cmd, d, c) ->
path = "#{_REST}/db/#{cmd}" path = "#{_REST}/db/#{cmd}"
_API.post path, d, c, (e, s) -> _API.post path, d, c, (e, s) ->
_courrier.osfail "Fail to query data from database: #{path}", e, s _courrier.osfail __("Fail to query data from database: {0}", path), e, s

133
src/core/lang/en_GB.json Normal file
View File

@ -0,0 +1,133 @@
{
"182526600":"About",
"1728416751":"Logout",
"374360126":"This feature is not implemented yet",
"193429273":"New",
"2087881073":"Open",
"2087429796":"Save",
"2752946774":"Save as",
"193404632":"Pid",
"2087422178":"Name",
"2087427261":"Type",
"2843369965":"Alive (ms)",
"2535492479":"Application",
"3856720312":"Service",
"3424459089":"Cannot add new category",
"463938484":"Add category",
"363586160":"Cannot Edit category",
"2424497641":"Edit category",
"3805835340":"Delete category",
"2240681887":"Do you really want to delete: {0}?",
"3156273522":"Please select a category",
"4164367416":"Cannot save section: {0}",
"1192966569":"New section entry for {0}",
"2824455713":"Please select a section to move",
"1501625444":"Cannot move section",
"808187119":"Move to",
"300219980":"Please select a section to edit",
"135303592":"Modify section entry",
"1766808808":"Cannot export file for embeding to text",
"1217236556":"Select image file",
"1968305551":"Preview",
"4222677540":"Cannot fetch the entry content",
"912714953":"Cannot delete: {0}",
"3999757701":"Delete a post",
"3306560909":"Do you really want to delete this post ?",
"3727585409":"Cannot fetch user data",
"2639330688":"Full name must be entered",
"3465321180":"Cannot save user data",
"2286635345":"User data updated",
"2963875715":"Cannot fetch CV categories",
"2893553849":"Cannot delete all content of: {0} [{1}]",
"1900521681":"Cannot delete the category: {0} [{1}]",
"3357186118":"Section list is empty, please add one",
"3413006975":"Found {0} sections",
"1144919321":"Cannot delete the section: {0}",
"2644553141":"Delete section",
"3876829319":"Please insert a title in the text: beginning with heading",
"3245026722":"Please enter tags",
"1973052887":"Cannot save blog: {0}",
"2178779206":"No post found: {0}",
"3030608041":"Created: {0}",
"3030607100":"Updated: {0}",
"2531202798":"Please select a parent category",
"3588217300":"Please enter category name",
"4030690575":"Parent can not be the category itself",
"2422876246":"Title or content must not be blank",
"1873707161":"Cannot load 3rd library at: {0}",
"657074596":"Language file {0} not found",
"1322116428":"Applications",
"2087421738":"Home",
"2601558679":"Desktop",
"5862649":"OS",
"3390737312":"Google Drive",
"1121690732":"Shared",
"5861310":"0k",
"1434146403":"Cancel",
"2144977206":"Please select a date",
"193433354":"Yes",
"5861188":"No",
"5861313":"Ok",
"3689040132":"About: {0}",
"3772680544":"Resource not found: {0}",
"2523816740":"Please select a file",
"1865792728":"Only {0} could be selected",
"4229049240":"Dialog {0} not found",
"2838461131":"VDB Unknown condition for delete command",
"2960050010":"VFS unknown handler: {0}",
"1343590195":"VFS Cannot encode file: {0}",
"173279772":"VFS unknown action: {0}",
"4019955188":"{0} is not a directory",
"83405614":"Unknown API setting for {0}",
"3786481511":"User abort the authentication",
"4162337765":"Authentication",
"2930246978":"Would you like to login to {0}?",
"2202007582":"VFS cannot init {0}: {1}",
"2790700937":"VFS cannot get meta data for {0}",
"364661042":"VFS cannot save : {0}",
"3957553505":"VFS cannot read : {0}",
"4093931543":"VFS cannot create : {0}",
"4069871534":"VFS cannot write : {0}",
"2117555914":"VFS cannot delete : {0}",
"3287790145":"VFS cannot download file : {0}",
"894347874":"VFS cannot move : {0}",
"3486928966":"Fail to scan directory: {0}",
"3755150205":"Fail to create directory: {0}",
"3480594191":"Fail to publish file: {0}",
"2765007501":"Fail to get file meta data: {0}",
"3576800228":"Fail to read file: {0}",
"1708235907":"Fail to move file: {0} -> {1}",
"2173516457":"Fail to delete: {0}",
"3625310256":"Fail to {0} package",
"3500805390":"Fail to upload file to: {0}",
"166470768":"Fail to write to file: {0}",
"1533928590":"Cannot save system setting",
"4029431747":"Fail to make request: {0}",
"3283805977":"Fail to query data from database: {0}",
"2087960229":"Exit",
"2772420848":"Cannot read service script: {0}",
"2458026955":"Error find app by mimes {0}",
"1570757462":"Application {0} is not executable",
"1037620478":"No application available to open {0}",
"759608531":"Open with",
"1346677432":"Refresh",
"2941901658":"System fail: Cannot init desktop manager",
"3474507048":"Toggle Full screen",
"1205381487":"Log out",
"1949044628":"System fail: Cannot init login screen",
"4008767138":"Read more",
"566874284":"Kill process",
"165499909":"Title",
"3336612961":"Subtitle",
"69825113":"(Location)",
"2087699155":"From",
"4219309361":"Full name",
"2117088275":"Address",
"165407801":"Phone",
"173181097":"Email",
"193413550":"Url",
"2454725172":"Short biblio",
"3455523987":"Categories",
"2088336676":"Tags"
}

26
src/core/lang/gen.sh Executable file
View File

@ -0,0 +1,26 @@
#!/bin/bash
ord() {
LC_CTYPE=C printf '%d' "'$1"
}
hash(){
text=$1
node -e "var hash, i, text;text='$1';hash = 5381;i = text.length;while (i) {hash = (hash * 33) ^ text.charCodeAt(--i);}; console.log(hash >>> 0)"
}
echo "{" > "tmp.json"
grep --include=\*.coffee -roh "$1" -e '__("[^"]*"' |while read -r line ; do
SUBSTRING=$(echo $line| cut -d'"' -f 2)
hs=$(hash "$SUBSTRING")
echo -e "\t\"$hs\":\"$SUBSTRING\"," >> "tmp.json"
done
grep --include=\*.html -roh './src/' -e '"__(.*)"' | while read -r line; do
SUBSTRING=${line:4:-2}
hs=$(hash "$SUBSTRING")
echo -e "\t\"$hs\":\"$SUBSTRING\"," >> "tmp.json"
done
echo "}" >> "tmp.json"
# remove duplicate entry
echo "remove duplicate line"
echo ""> $2
awk '!a[$0]++' "tmp.json" >> $2
rm tmp.json

View File

@ -3,17 +3,18 @@
_OS.setting.applications = conf.applications if conf.applications _OS.setting.applications = conf.applications if conf.applications
_OS.setting.appearance = conf.appearance if conf.appearance _OS.setting.appearance = conf.appearance if conf.appearance
_OS.setting.user = conf.user _OS.setting.user = conf.user
_OS.setting.user.language = "en_GB" unless conf.user.language
_OS.setting.VFS = conf.VFS if conf.VFS _OS.setting.VFS = conf.VFS if conf.VFS
_OS.setting.desktop.path = "home:///.desktop" unless _OS.setting.desktop.path _OS.setting.desktop.path = "home:///.desktop" unless _OS.setting.desktop.path
_OS.setting.desktop.menu = {} unless _OS.setting.desktop.menu _OS.setting.desktop.menu = {} unless _OS.setting.desktop.menu
_OS.setting.VFS.mountpoints = [ _OS.setting.VFS.mountpoints = [
#TODO: multi app try to write to this object, it neet to be cloned #TODO: multi app try to write to this object, it neet to be cloned
{ text: "Applications", path: 'app:///', iconclass: "fa fa-adn", type: "app" }, { text: __("Applications"), path: 'app:///', iconclass: "fa fa-adn", type: "app" },
{ text: "Home", path: 'home:///', iconclass: "fa fa-home", type: "fs" }, { text: __("Home"), path: 'home:///', iconclass: "fa fa-home", type: "fs" },
{ text: "Desktop", path: _OS.setting.desktop.path , iconclass: "fa fa-desktop", type: "fs" }, { text: __("Desktop"), path: _OS.setting.desktop.path , iconclass: "fa fa-desktop", type: "fs" },
{ text: "OS", path: 'os:///', iconclass: "fa fa-inbox", type: "fs" }, { text: __("OS"), path: 'os:///', iconclass: "fa fa-inbox", type: "fs" },
{ text: "Google Drive", path: 'gdv:///', iconclass: "fa fa-inbox", type: "fs" }, { text: __("Google Drive"), path: 'gdv:///', iconclass: "fa fa-inbox", type: "fs" },
{ text: "Shared", path: 'shared:///' , iconclass: "fa fa-share-square", type: "fs" } { text: __("Shared"), path: 'shared:///' , iconclass: "fa fa-share-square", type: "fs" }
] if not _OS.setting.VFS.mountpoints ] if not _OS.setting.VFS.mountpoints
_OS.setting.system = conf.system if conf.system _OS.setting.system = conf.system if conf.system
@ -44,7 +45,7 @@
} unless _OS.setting.VFS.gdrive } unless _OS.setting.VFS.gdrive
#search for app #search for app
_API.onsearch "Applications", (t) -> _API.onsearch __("Applications"), (t) ->
ar = [] ar = []
term = new RegExp t, "i" term = new RegExp t, "i"
for k, v of _OS.setting.system.packages when v.app for k, v of _OS.setting.system.packages when v.app

View File

@ -3,7 +3,7 @@
<afx-grid-view data-id ={"grid_" + rid} style = "height:100%;" ref = "grid" header = {header}> </afx-grid-view> <afx-grid-view data-id ={"grid_" + rid} style = "height:100%;" ref = "grid" header = {header}> </afx-grid-view>
<script > <script >
this.header = [{value:"Sun"},{value:"Mon"},{value:"Tue"},{value:"Wed"},{value:"Thu"},{value:"Fri"},{value:"Sat"}] this.header = [{value:__("Sun")},{value:__("Mon")},{value:__("Tue")},{value:__("Wed")},{value:__("Thu")},{value:__("Fri")},{value:__("Sat")}]
this.root.observable = opts.observable this.root.observable = opts.observable
var self = this var self = this
this.day = 0 this.day = 0
@ -62,7 +62,7 @@
self.year = date.getFullYear() self.year = date.getFullYear()
var now ={ d:(new Date()).getDate(), m:(new Date()).getMonth(), y:(new Date()).getFullYear()} var now ={ d:(new Date()).getDate(), m:(new Date()).getMonth(), y:(new Date()).getFullYear()}
months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] months = [__('January'), __('February'), __('March'), __('April'), __('May'), __('June'), __('July'), __('August'), __('September'), __('October'), __('November'), __('December')]
this_month = new Date(self.year, self.month, 1) this_month = new Date(self.year, self.month, 1)
next_month = new Date(self.year, self.month + 1, 1) next_month = new Date(self.year, self.month + 1, 1)

View File

@ -20,7 +20,7 @@
this.fetch = opts.fetch this.fetch = opts.fetch
this.chdir = opts.chdir this.chdir = opts.chdir
this.rid = $(self.root).attr("data-id") || Math.floor(Math.random() * 100000) + 1 this.rid = $(self.root).attr("data-id") || Math.floor(Math.random() * 100000) + 1
this.header = [{value:"File name"},{value: "Type", width:150}, {value: "Size", width:70}] this.header = [{value:__("File name")},{value: __("Type"), width:150}, {value: __("Size"), width:70}]
self.root.set = function(k,v) self.root.set = function(k,v)
{ {
@ -200,7 +200,7 @@
if(self.onfileselect) if(self.onfileselect)
self.onfileselect(e.data) self.onfileselect(e.data)
$(self.refs.stbar).empty() $(self.refs.stbar).empty()
$(self.refs.stbar).append($("<span>").append("Selected: " + e.data.filename + " (" + e.data.size + " bytes)"))//.html() $(self.refs.stbar).append($("<span>").append(__("Selected: {0} ({1} bytes)", e.data.filename, e.data.size)))//.html()
}) })
self.root.observable.on("filedbclick", function(e){ self.root.observable.on("filedbclick", function(e){
if(e.id != self.rid ) return if(e.id != self.rid ) return

View File

@ -2,7 +2,7 @@
<span style = {color?"color:" + color:""} > <span style = {color?"color:" + color:""} >
<i if={iconclass} class = {iconclass} ></i> <i if={iconclass} class = {iconclass} ></i>
<i if={icon} class="icon-style" style = { "background: url("+icon+");background-size: 100% 100%;background-repeat: no-repeat;" }></i> <i if={icon} class="icon-style" style = { "background: url("+icon+");background-size: 100% 100%;background-repeat: no-repeat;" }></i>
{ text } { parse(text) }
</span> </span>
<script> <script>
this.iconclass = opts.iconclass this.iconclass = opts.iconclass
@ -29,5 +29,16 @@
{ {
return self[k] return self[k]
} }
parse(text)
{
if(!text) return ""
match = text.match(/^__\(([^\)]*)\)$/)
if(match)
{
return window.__(match[1])
}
else
return text
}
</script> </script>
</afx-label> </afx-label>

View File

@ -2,7 +2,7 @@ String.prototype.asFileHandler = () ->
list = @split ":///" list = @split ":///"
handlers = _API.VFS.findHandlers list[0] handlers = _API.VFS.findHandlers list[0]
if not handlers or handlers.length is 0 if not handlers or handlers.length is 0
_courrier.osfail "VFS unknown handler: #{@}", (_API.throwe "OS.VFS"), @ _courrier.osfail __("VFS unknown handler: {0}", @), (_API.throwe "OS.VFS"), @
return null return null
return new handlers[0](@) return new handlers[0](@)
@ -63,7 +63,7 @@ class BaseFileHandler
reader.onload = () -> reader.onload = () ->
f reader.result f reader.result
reader.onerror = (e) -> reader.onerror = (e) ->
return _courrier.osfail "Cannot ecode file: #{me.path}", (_API.throwe "OS.VFS"), e return _courrier.osfail __("VFS Cannot encode file: {0}", me.path), (_API.throwe "OS.VFS"), e
parent: () -> parent: () ->
return @ if @isRoot() return @ if @isRoot()
return (@protocol + ":///" + (@genealogy.slice 0 , @genealogy.length - 1).join "/") return (@protocol + ":///" + (@genealogy.slice 0 , @genealogy.length - 1).join "/")
@ -132,7 +132,7 @@ class BaseFileHandler
# for main action read, write, remove, execute # for main action read, write, remove, execute
# must be implemented by subclasses # must be implemented by subclasses
action: (n, p, f) -> action: (n, p, f) ->
return _courrier.osfail "VFS unknown action: #{n}", (_API.throwe "OS.VFS"), n return _courrier.osfail __("VFS unknown action: {0}", n), (_API.throwe "OS.VFS"), n
# now export the class # now export the class
self.OS.API.VFS.BaseFileHandler = BaseFileHandler self.OS.API.VFS.BaseFileHandler = BaseFileHandler
@ -154,7 +154,7 @@ class RemoteFileHandler extends self.OS.API.VFS.BaseFileHandler
return _API.handler.fileblob @path, f if p is "binary" return _API.handler.fileblob @path, f if p is "binary"
_API.handler.readfile @path, f, if p then p else "text" _API.handler.readfile @path, f, if p then p else "text"
when "mk" when "mk"
return f { error: "#{@path} is not a directory" } if @info.type is "file" return f { error: __("{0} is not a directory", @path) } if @info.type is "file"
_API.handler.mkdir "#{@path}/#{p}", f _API.handler.mkdir "#{@path}/#{p}", f
when "write" when "write"
@sendB64 p, (data) -> @sendB64 p, (data) ->
@ -174,7 +174,7 @@ class RemoteFileHandler extends self.OS.API.VFS.BaseFileHandler
when "move" when "move"
_API.handler.move @path, p, f _API.handler.move @path, p, f
else else
return _courrier.osfail "VFS unknown action: #{n}", (_API.throwe "OS.VFS"), n return _courrier.osfail __("VFS unknown action: {0}", n), (_API.throwe "OS.VFS"), n
self.OS.API.VFS.register "^(home|desktop|os|Untitled)$", RemoteFileHandler self.OS.API.VFS.register "^(home|desktop|os|Untitled)$", RemoteFileHandler
@ -217,7 +217,7 @@ class ApplicationHandler extends self.OS.API.VFS.BaseFileHandler
when "move" when "move"
return return
else else
return _courrier.osfail "VFS unknown action: #{n}", (_API.throwe "OS.VFS"), n return _courrier.osfail __("VFS unknown action: {0}", n), (_API.throwe "OS.VFS"), n
self.OS.API.VFS.register "^app$", ApplicationHandler self.OS.API.VFS.register "^app$", ApplicationHandler
@ -267,7 +267,7 @@ class BufferFileHandler extends self.OS.API.VFS.BaseFileHandler
when "move" when "move"
return return
else else
return _courrier.osfail "VFS unknown action: #{n}", (_API.throwe "OS.VFS"), n return _courrier.osfail __("VFS unknown action: {0}", n), (_API.throwe "OS.VFS"), n
self.OS.API.VFS.register "^mem$", BufferFileHandler self.OS.API.VFS.register "^mem$", BufferFileHandler
@ -309,6 +309,6 @@ class SharedFileHandler extends self.OS.API.VFS.BaseFileHandler
when "move" when "move"
return return
else else
return _courrier.osfail "VFS unknown action: #{n}", (_API.throwe "OS.VFS"), n return _courrier.osfail __("VFS unknown action: {0}", n), (_API.throwe "OS.VFS"), n
self.OS.API.VFS.register "^shared$", SharedFileHandler self.OS.API.VFS.register "^shared$", SharedFileHandler

View File

@ -7,7 +7,7 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
super path super path
me = @ me = @
@setting = _OS.setting.VFS.gdrive @setting = _OS.setting.VFS.gdrive
return _courrier.oserror "Unknown API setting for google drive VFS", (_API.throwe "OS.VFS"), null unless @setting return _courrier.oserror __("Unknown API setting for {0}", "GAPI"), (_API.throwe "OS.VFS"), null unless @setting
@gid = 'root' if @isRoot() @gid = 'root' if @isRoot()
@cache = "" @cache = ""
@ -41,12 +41,13 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
gapi.auth2.getAuthInstance().isSignedIn.listen (r) -> gapi.auth2.getAuthInstance().isSignedIn.listen (r) ->
fn(r) fn(r)
_GUI.openDialog "YesNoDialog", (d) -> _GUI.openDialog "YesNoDialog", (d) ->
return _courrier.osinfo "User abort the authentification" unless d return _courrier.osinfo __("User abort the authentication") unless d
fn(gapi.auth2.getAuthInstance().isSignedIn.get()) fn(gapi.auth2.getAuthInstance().isSignedIn.get())
, "Authentification", { text: "Would you like to login to Google Drive ?" } , __("Authentication")
, { text: __("Would you like to login to {0}?", "Google Drive") }
.catch (err) -> .catch (err) ->
_API.loaded q, "FAIL" _API.loaded q, "FAIL"
_courrier.oserror "VFS cannot init GAPI: #{err.error}", (_API.throwe "OS.VFS"), err _courrier.oserror __("VFS cannot init {0}: {1}", "GAPI",err.error), (_API.throwe "OS.VFS"), err
meta: (f) -> meta: (f) ->
me = @ me = @
@ -67,7 +68,7 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
f(r) f(r)
.catch (err) -> .catch (err) ->
_API.loaded q, "FAIL" _API.loaded q, "FAIL"
_courrier.oserror "VFS cannot get meta #{me.gid}", (_API.throwe "OS.VFS"), err _courrier.oserror __("VFS cannot get meta data for {0}", me.gid), (_API.throwe "OS.VFS"), err
else else
#console.log "Find file in ", me.parent() #console.log "Find file in ", me.parent()
fp = me.parent().asFileHandler() fp = me.parent().asFileHandler()
@ -89,7 +90,7 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
f { result: r.result.files[0] } f { result: r.result.files[0] }
.catch (err) -> .catch (err) ->
_API.loaded q1, "FAIL" _API.loaded q1, "FAIL"
_courrier.oserror "VFS cannot get meta #{me.path}", (_API.throwe "OS.VFS"), err _courrier.oserror __("VFS cannot get meta data for {0}", me.path), (_API.throwe "OS.VFS"), err
fields: () -> fields: () ->
return "webContentLink, id, name,mimeType,description, kind, parents, properties, iconLink, createdTime, modifiedTime, owners, permissions, fullFileExtension, fileExtension, size" return "webContentLink, id, name,mimeType,description, kind, parents, properties, iconLink, createdTime, modifiedTime, owners, permissions, fullFileExtension, fileExtension, size"
@ -111,7 +112,7 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
_API.loading q, "GAPI" _API.loading q, "GAPI"
error = (e, s) -> error = (e, s) ->
_API.loaded q, "FAIL" _API.loaded q, "FAIL"
_courrier.oserror "VFS cannot save : #{me.path}", e, s _courrier.oserror __("VFS cannot save : {0}", me.path), e, s
xhr.onreadystatechange = () -> xhr.onreadystatechange = () ->
if ( xhr.readyState == 4 ) if ( xhr.readyState == 4 )
if ( xhr.status == 200 ) if ( xhr.status == 200 )
@ -154,7 +155,7 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
f { result: r.result.files } f { result: r.result.files }
.catch (err) -> .catch (err) ->
_API.loaded q, "FAIL" _API.loaded q, "FAIL"
_courrier.oserror "VFS cannot read #{me.path}", (_API.throwe "OS.VFS"), err _courrier.oserror __("VFS cannot read : {0}", me.path), (_API.throwe "OS.VFS"), err
else else
gapi.client.drive.files.get { gapi.client.drive.files.get {
fileId: me.info.id, fileId: me.info.id,
@ -166,10 +167,10 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
f r.body.asUnit8Array() f r.body.asUnit8Array()
.catch (err) -> .catch (err) ->
_API.loaded q, "FAIL" _API.loaded q, "FAIL"
_courrier.oserror "VFS cannot get read #{me.path}", (_API.throwe "OS.VFS"), err _courrier.oserror __("VFS cannot read : {0}", me.path), (_API.throwe "OS.VFS"), err
when "mk" when "mk"
return f { error: "#{@path} is not a directory" } unless @isFolder() return f { error: __("{0} is not a directory", @path) } unless @isFolder()
meta = meta =
name: p, name: p,
parents: [@info.id], parents: [@info.id],
@ -182,12 +183,12 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
.then (r) -> .then (r) ->
_API.loaded q, "OK" _API.loaded q, "OK"
#console.log r #console.log r
return _courrier.oserror "VFS cannot create : #{p}", (_API.throwe "OS.VFS"), r unless r and r.result return _courrier.oserror __("VFS cannot create : {0}", p), (_API.throwe "OS.VFS"), r unless r and r.result
G_CACHE[me.child p] = { id: r.result.id, mime: "dir" } G_CACHE[me.child p] = { id: r.result.id, mime: "dir" }
f r f r
.catch (err) -> .catch (err) ->
_API.loaded q, "FAIL" _API.loaded q, "FAIL"
_courrier.oserror "VFS cannot create #{p}", (_API.throwe "OS.VFS"), err _courrier.oserror __("VFS cannot create : {0}", p), (_API.throwe "OS.VFS"), err
return return
@ -211,12 +212,12 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
} }
.then (r) -> .then (r) ->
_API.loaded q, "OK" _API.loaded q, "OK"
return _courrier.oserror "VFS cannot write : #{me.path}", (_API.throwe "OS.VFS"), r unless r and r.result return _courrier.oserror __("VFS cannot write : {0}", me.path), (_API.throwe "OS.VFS"), r unless r and r.result
G_CACHE[me.path] = { id: r.result.id, mime: p } G_CACHE[me.path] = { id: r.result.id, mime: p }
me.save r.result.id, p, f me.save r.result.id, p, f
.catch (err) -> .catch (err) ->
_API.loaded q, "FAIL" _API.loaded q, "FAIL"
_courrier.oserror "VFS cannot write #{me.path}", (_API.throwe "OS.VFS"), err _courrier.oserror __("VFS cannot write : {0}", me.path), (_API.throwe "OS.VFS"), err
when "upload" when "upload"
return unless @isFolder() return unless @isFolder()
@ -244,12 +245,12 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
.then (r) -> .then (r) ->
#console.log r #console.log r
_API.loaded q, "OK" _API.loaded q, "OK"
return _courrier.oserror "VFS cannot delete : #{me.path}", (_API.throwe "OS.VFS"), r unless r return _courrier.oserror __("VFS cannot delete : {0}", me.path), (_API.throwe "OS.VFS"), r unless r
G_CACHE[me.path] = null G_CACHE[me.path] = null
f { result: true } f { result: true }
.catch (err) -> .catch (err) ->
_API.loaded q, "FAIL" _API.loaded q, "FAIL"
_courrier.oserror "VFS cannot delete #{me.path}", (_API.throwe "OS.VFS"), err _courrier.oserror __("VFS cannot delete : {0}", me.path), (_API.throwe "OS.VFS"), err
when "publish" when "publish"
_API.loaded q, "OK" _API.loaded q, "OK"
@ -262,7 +263,7 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
} }
.then (r) -> .then (r) ->
_API.loaded q, "OK" _API.loaded q, "OK"
return _courrier.oserror "VFS cannot get file : #{me.path}", (_API.throwe "OS.VFS"), r unless r.body return _courrier.oserror __("VFS cannot download file : {0}", me.path), (_API.throwe "OS.VFS"), r unless r.body
bytes = [] bytes = []
for i in [0..(r.body.length - 1)] for i in [0..(r.body.length - 1)]
bytes.push r.body.charCodeAt i bytes.push r.body.charCodeAt i
@ -271,7 +272,7 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
_API.saveblob me.basename, blob _API.saveblob me.basename, blob
.catch (err) -> .catch (err) ->
_API.loaded q, "FAIL" _API.loaded q, "FAIL"
_courrier.oserror "VFS cannot fetch #{me.path}", (_API.throwe "OS.VFS"), err _courrier.oserror __("VFS cannot download file : {0}", me.path), (_API.throwe "OS.VFS"), err
when "move" when "move"
dest = p.asFileHandler().parent().asFileHandler() dest = p.asFileHandler().parent().asFileHandler()
@ -285,16 +286,16 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
} }
.then (r) -> .then (r) ->
_API.loaded q, "OK" _API.loaded q, "OK"
return _courrier.oserror "VFS cannot move : #{me.path}", (_API.throwe "OS.VFS"), r unless r return _courrier.oserror __("VFS cannot move : {0}", me.path), (_API.throwe "OS.VFS"), r unless r
f r f r
.catch (err) -> .catch (err) ->
_API.loaded q, "FAIL" _API.loaded q, "FAIL"
_courrier.oserror "VFS cannot move #{me.gid}", (_API.throwe "OS.VFS"), err _courrier.oserror __("VFS cannot move : {0}", me.gid), (_API.throwe "OS.VFS"), err
, (err) -> , (err) ->
_API.loaded q, "FAIL" _API.loaded q, "FAIL"
else else
_API.loaded q, "FAIL" _API.loaded q, "FAIL"
return _courrier.osfail "VFS unknown action: #{n}", (_API.throwe "OS.VFS"), n return _courrier.osfail __("VFS unknown action: {0}", n), (_API.throwe "OS.VFS"), n
self.OS.API.VFS.register "^gdv$", GoogleDriveHandler self.OS.API.VFS.register "^gdv$", GoogleDriveHandler

View File

@ -14,7 +14,7 @@ class ActivityMonitor extends this.OS.GUI.BaseApplication
app = _PM.appByPid item[0].value app = _PM.appByPid item[0].value
app.quit() if app app.quit() if app
header = [{width:50,value:"Pid"},{value:"Name"}, {value:"Type", width:80},{width:75,value:"Alive (ms)"}] header = [{width:50,value:__("Pid")},{value:__("Name")}, {value:__("Type"), width:80},{width:75,value:__("Alive (ms)")}]
@gdata = @gdata =
processes:{} processes:{}
alive:[] alive:[]
@ -36,7 +36,7 @@ class ActivityMonitor extends this.OS.GUI.BaseApplication
{icon:if _APP[a.name].type == 1 then _APP[a.name].meta.icon else a.icon, {icon:if _APP[a.name].type == 1 then _APP[a.name].meta.icon else a.icon,
iconclass:if _APP[a.name].type == 1 then _APP[a.name].meta.iconclass else a.iconclass, iconclass:if _APP[a.name].type == 1 then _APP[a.name].meta.iconclass else a.iconclass,
value:a.name}, value:a.name},
{value: if _APP[a.name].type == 1 then "Application" else "Service"} {value: if _APP[a.name].type == 1 then __("Application") else __("Service")}
{value: now - a.birth} {value: now - a.birth}
] ]
me.gdata.alive.push a.pid me.gdata.alive.push a.pid

View File

@ -1,6 +1,6 @@
<afx-app-window data-id = "am-window" apptitle="" width="400" height="300"> <afx-app-window data-id = "am-window" apptitle="" width="400" height="300">
<afx-vbox> <afx-vbox>
<afx-grid-view data-id = "mygrid"></afx-grid-view> <afx-grid-view data-id = "mygrid"></afx-grid-view>
<afx-button data-height="30" data-id = "btkill" text = "Kill process" iconclass="fa fa-times"></afx-button> <afx-button data-height="30" data-id = "btkill" text = "__(Kill process)" iconclass="fa fa-times"></afx-button>
</afx-vbox> </afx-vbox>
</afx-app-window> </afx-app-window>

View File

@ -2,30 +2,30 @@
<afx-vbox > <afx-vbox >
<div data-height="5"></div> <div data-height="5"></div>
<afx-hbox data-height = "30" > <afx-hbox data-height = "30" >
<afx-label data-width= "70" text = "Title:"></afx-label> <afx-label data-width= "70" text = "__(Title)"></afx-label>
<input type = "text" name="title" input-class = "user-input"/> <input type = "text" name="title" input-class = "user-input"/>
</afx-hbox> </afx-hbox>
<afx-hbox data-height = "30" > <afx-hbox data-height = "30" >
<afx-label text = "Subtitle:" data-width= "70"></afx-label> <afx-label text = "__(Subtitle)" data-width= "70"></afx-label>
<input type = "text" name="subtitle" input-class = "user-input"/> <input type = "text" name="subtitle" input-class = "user-input"/>
</afx-hbox> </afx-hbox>
<afx-hbox data-height = "30" > <afx-hbox data-height = "30" >
<afx-label text = "Location:" data-width= "70"></afx-label> <afx-label text = "__((Location))" data-width= "70"></afx-label>
<input type = "text" name="location" input-class = "user-input"/> <input type = "text" name="location" input-class = "user-input"/>
</afx-hbox> </afx-hbox>
<afx-hbox data-height = "30" > <afx-hbox data-height = "30" >
<afx-label text = "From:" data-width= "70"></afx-label> <afx-label text = "__(From)" data-width= "70"></afx-label>
<input type = "text" name="start" input-class = "user-input"/> <input type = "text" name="start" input-class = "user-input"/>
<afx-label text = "To:" style="text-align:center;" data-width= "70"></afx-label> <afx-label text = "To:" style="text-align:center;" data-width= "70"></afx-label>
<input type = "text" name="end" input-class = "user-input"/> <input type = "text" name="end" input-class = "user-input"/>
</afx-hbox> </afx-hbox>
<afx-label data-height = "30" text = "Content:" style = "margin-left:5px;"/> <afx-label data-height = "30" text = "Content" style = "margin-left:5px;"/>
<div data-id="editor-container"> <div data-id="editor-container">
<textarea name="content" data-id = "contentarea" /> <textarea name="content" data-id = "contentarea" />
</div> </div>
<afx-hbox data-height = "35"> <afx-hbox data-height = "35">
<div></div> <div></div>
<afx-button iconclass = "fa fa-save" data-id = "bt-cv-sec-save" data-width="60" text = "Save"/> <afx-button iconclass = "fa fa-save" data-id = "bt-cv-sec-save" data-width="60" text = "__(Save)"/>
</afx-hbox> </afx-hbox>
</afx-vbox> </afx-vbox>
</afx-app-window> </afx-app-window>

View File

@ -2,9 +2,9 @@ class BloggerCategoryDialog extends this.OS.GUI.BasicDialog
constructor: () -> constructor: () ->
super "BloggerCategoryDialog", { super "BloggerCategoryDialog", {
tags: [ tags: [
{ tag: "afx-label", att: "data-height = '20', text = 'Pick a parent:'" }, { tag: "afx-label", att: "data-height = '20', text = 'Pick a parent'" },
{ tag: "afx-tree-view" }, { tag: "afx-tree-view" },
{ tag: "afx-label", att: "data-height = '20', text = 'Category name:'" }, { tag: "afx-label", att: "data-height = '20', text = 'Category name'" },
{ tag: "input", att: "type = 'text' data-height = '20'" } { tag: "input", att: "type = 'text' data-height = '20'" }
], ],
width: 200, width: 200,
@ -15,10 +15,10 @@ class BloggerCategoryDialog extends this.OS.GUI.BasicDialog
label: "0k", label: "0k",
onclick: (d) -> onclick: (d) ->
sel = (d.find "content1").get "selectedItem" sel = (d.find "content1").get "selectedItem"
return d.notify "Please select a parent category" unless sel return d.notify __("Please select a parent category") unless sel
val = (d.find "content3").value val = (d.find "content3").value
return d.notify "Please enter category name" if val is "" and not d.data.selonly return d.notify __("Please enter category name") if val is "" and not d.data.selonly
return d.notify "Parent can not be the category itself" if d.data.cat and d.data.cat.id is sel.id return d.notify __("Parent can not be the category itself") if d.data.cat and d.data.cat.id is sel.id
d.handler { p: sel, value: val } if d.handler d.handler { p: sel, value: val } if d.handler
d.quit() d.quit()
}, },
@ -66,7 +66,7 @@ class BloggerCVSectionDiaglog extends this.OS.GUI.BaseDialog
($ (@select '[class="CodeMirror cm-s-paper CodeMirror-wrap"]')[0]).css "min-height", "50px" ($ (@select '[class="CodeMirror cm-s-paper CodeMirror-wrap"]')[0]).css "min-height", "50px"
@on "vboxchange", () -> @on "vboxchange", () ->
me.resizeContent() me.resizeContent()
console.log "resize content"
inputs = me.select "[input-class='user-input']" inputs = me.select "[input-class='user-input']"
(($ v).val me.data[v.name] for v in inputs ) if me.data (($ v).val me.data[v.name] for v in inputs ) if me.data
@editor.value me.data.content if me.data and me.data.content @editor.value me.data.content if me.data and me.data.content
@ -75,7 +75,7 @@ class BloggerCVSectionDiaglog extends this.OS.GUI.BaseDialog
console.log inputs console.log inputs
data[v.name] = ($ v).val() for v in inputs data[v.name] = ($ v).val() for v in inputs
data.content = me.editor.value() data.content = me.editor.value()
return me.notify "Title or content must not be blank" if data.title is "" and data.content is "" return me.notify __("Title or content must not be blank") if data.title is "" and data.content is ""
#return me.notify "Content must not be blank" if data.content is "" #return me.notify "Content must not be blank" if data.content is ""
data.id = me.data.id if me.data and me.data.id data.id = me.data.id if me.data and me.data.id
me.handler data if me.handler me.handler data if me.handler

View File

@ -42,11 +42,11 @@ class Blogger extends this.OS.GUI.BaseApplication
pid: d.p.id, pid: d.p.id,
publish: 1 publish: 1
me.cvcatdb.save c, (r) -> me.cvcatdb.save c, (r) ->
me.error "Cannot add new category" if r.error me.error __("Cannot add new category") if r.error
me.refreshCVCat() me.refreshCVCat()
#update the list #update the list
, "Add category", { tree: me.cvlist.get "data" } , __("Add category"), { tree: me.cvlist.get "data" }
(@find "cv-cat-edit").set "onbtclick", (e) -> (@find "cv-cat-edit").set "onbtclick", (e) ->
cat = me.cvlist.get "selectedItem" cat = me.cvlist.get "selectedItem"
@ -59,9 +59,9 @@ class Blogger extends this.OS.GUI.BaseApplication
name: d.value name: d.value
me.cvcatdb.save c, (r) -> me.cvcatdb.save c, (r) ->
return me.error "Cannot Edit category" if r.error return me.error __("Cannot Edit category") if r.error
me.refreshCVCat() me.refreshCVCat()
, "Edit category", { tree: (me.cvlist.get "data"), cat: cat } , __("Edit category"), { tree: (me.cvlist.get "data"), cat: cat }
(@find "cv-cat-del").set "onbtclick", (e) -> (@find "cv-cat-del").set "onbtclick", (e) ->
cat = me.cvlist.get "selectedItem" cat = me.cvlist.get "selectedItem"
@ -70,26 +70,26 @@ class Blogger extends this.OS.GUI.BaseApplication
(d) -> (d) ->
return unless d return unless d
me.deleteCVCat cat me.deleteCVCat cat
, "Delete cagegory" , , __("Delete category") ,
{ iconclass: "fa fa-question-circle", text: "Do you really want to delete: #{cat.name} ?" } { iconclass: "fa fa-question-circle", text: __("Do you really want to delete: {0}?", cat.name) }
(@find "cv-sec-add").set "onbtclick", (e) -> (@find "cv-sec-add").set "onbtclick", (e) ->
cat = me.cvlist.get "selectedItem" cat = me.cvlist.get "selectedItem"
return me.notify "Please select a category" unless cat and cat.id isnt 0 return me.notify __("Please select a category") unless cat and cat.id isnt 0
me.openDialog "BloggerCVSectionDiaglog", (d) -> me.openDialog "BloggerCVSectionDiaglog", (d) ->
d.cid = Number cat.id d.cid = Number cat.id
d.start = Number d.start d.start = Number d.start
d.end = Number d.end d.end = Number d.end
d.publish = 1 d.publish = 1
me.cvsecdb.save d, (r) -> me.cvsecdb.save d, (r) ->
return me.error "Cannot save section: #{r.error}" if r.error return me.error __("Cannot save section: {0}", r.error) if r.error
me.CVSectionByCID Number(cat.id) me.CVSectionByCID Number(cat.id)
, "New section entry for #{cat.name}", null , __("New section entry for {0}", cat.name), null
(@find "cv-sec-move").set "onbtclick", (e) -> (@find "cv-sec-move").set "onbtclick", (e) ->
sec = (me.find "cv-sec-list").get "selected" sec = (me.find "cv-sec-list").get "selected"
return me.notify "Please select a section to move" unless sec return me.notify __("Please select a section to move") unless sec
me.openDialog "BloggerCategoryDialog", (d) -> me.openDialog "BloggerCategoryDialog", (d) ->
c = c =
@ -97,14 +97,14 @@ class Blogger extends this.OS.GUI.BaseApplication
cid: d.p.id cid: d.p.id
me.cvsecdb.save c, (r) -> me.cvsecdb.save c, (r) ->
return me.error "Cannot move section" if r.error return me.error __("Cannot move section") if r.error
me.CVSectionByCID(sec.cid) me.CVSectionByCID(sec.cid)
(me.find "cv-sec-list").set "selected", -1 (me.find "cv-sec-list").set "selected", -1
, "Move to", { tree: (me.cvlist.get "data"), selonly: true } , __("Move to"), { tree: (me.cvlist.get "data"), selonly: true }
(@find "cv-sec-edit").set "onbtclick", (e) -> (@find "cv-sec-edit").set "onbtclick", (e) ->
sec = (me.find "cv-sec-list").get "selected" sec = (me.find "cv-sec-list").get "selected"
return me.notify "Please select a section to edit" unless sec return me.notify __("Please select a section to edit") unless sec
me.openDialog "BloggerCVSectionDiaglog", (d) -> me.openDialog "BloggerCVSectionDiaglog", (d) ->
d.cid = Number sec.cid d.cid = Number sec.cid
@ -112,10 +112,10 @@ class Blogger extends this.OS.GUI.BaseApplication
d.end = Number d.end d.end = Number d.end
d.publish = Number sec.publish d.publish = Number sec.publish
me.cvsecdb.save d, (r) -> me.cvsecdb.save d, (r) ->
return me.error "Cannot save section: #{r.error}" if r.error return me.error __("Cannot save section: {0}", r.error) if r.error
me.CVSectionByCID Number(sec.cid) me.CVSectionByCID Number(sec.cid)
, "Modify section entry", sec , __("Modify section entry"), sec
@editor = new SimpleMDE @editor = new SimpleMDE
element: me.find "markarea" element: me.find "markarea"
@ -124,14 +124,14 @@ class Blogger extends this.OS.GUI.BaseApplication
indentWithTabs: true indentWithTabs: true
toolbar: [ toolbar: [
{ {
name: "new", name: __("New"),
className: "fa fa-file", className: "fa fa-file",
action: (e) -> action: (e) ->
me.bloglist.set "selected", -1 me.bloglist.set "selected", -1
me.clearEditor() me.clearEditor()
}, },
{ {
name: "save", name: __("Save"),
className: "fa fa-save", className: "fa fa-save",
action: (e) -> action: (e) ->
me.saveBlog() me.saveBlog()
@ -145,10 +145,10 @@ class Blogger extends this.OS.GUI.BaseApplication
action: (e) -> action: (e) ->
me.openDialog "FileDiaLog", (d, n, p) -> me.openDialog "FileDiaLog", (d, n, p) ->
p.asFileHandler().publish (r) -> p.asFileHandler().publish (r) ->
return me.error "Cannot export file for embeding to text" if r.error return me.error __("Cannot export file for embeding to text") if r.error
doc = me.editor.codemirror.getDoc() doc = me.editor.codemirror.getDoc()
doc.replaceSelection "![](#{me._api.handler.shared}/#{r.result})" doc.replaceSelection "![](#{me._api.handler.shared}/#{r.result})"
, "Select image file", { mimes: ["image/.*"] } , __("Select image file"), { mimes: ["image/.*"] }
}, },
{ {
name:"Youtube", name:"Youtube",
@ -159,7 +159,7 @@ class Blogger extends this.OS.GUI.BaseApplication
} }
"|", "|",
{ {
name: "preview", name: __("Preview"),
className: "fa fa-eye no-disable", className: "fa fa-eye no-disable",
action: (e) -> action: (e) ->
me.previewOn = !me.previewOn me.previewOn = !me.previewOn
@ -170,7 +170,7 @@ class Blogger extends this.OS.GUI.BaseApplication
sel = me.bloglist.get "selected" sel = me.bloglist.get "selected"
return unless sel return unless sel
me.blogdb.get Number(sel.id), (r) -> me.blogdb.get Number(sel.id), (r) ->
me.error "Cannot fetch the entry content" if r.error me.error __("Cannot fetch the entry content") if r.error
me.editor.value atob(r.result.content) me.editor.value atob(r.result.content)
me.inputtags.value = r.result.tags me.inputtags.value = r.result.tags
(me.find "blog-publish").set "swon", (if Number(r.result.publish) then true else false) (me.find "blog-publish").set "swon", (if Number(r.result.publish) then true else false)
@ -179,12 +179,12 @@ class Blogger extends this.OS.GUI.BaseApplication
me.openDialog "YesNoDialog", (b) -> me.openDialog "YesNoDialog", (b) ->
return unless b return unless b
me.blogdb.delete e.item.item.id, (r) -> me.blogdb.delete e.item.item.id, (r) ->
return me.error "Cannot delete: #{r.error}" if r.error return me.error __("Cannot delete: {0}", r.error) if r.error
me.bloglist.remove e.item.item, true me.bloglist.remove e.item.item, true
me.bloglist.set "selected", -1 me.bloglist.set "selected", -1
me.clearEditor() me.clearEditor()
, "Delete a post" , , __("Delete a post") ,
{ iconclass: "fa fa-question-circle", text: "Do you really want to delete this post ?" } { iconclass: "fa fa-question-circle", text: __("Do you really want to delete this post ?") }
return false return false
@bindKey "CTRL-S", () -> @bindKey "CTRL-S", () ->
sel = me.tabbar.get "selidx" sel = me.tabbar.get "selidx"
@ -199,7 +199,7 @@ class Blogger extends this.OS.GUI.BaseApplication
when 0 #user info when 0 #user info
@userdb.get null, (d) -> @userdb.get null, (d) ->
return me.error "Cannot fetch user data" if d.error return me.error __("Cannot fetch user data") if d.error
me.user = d.result[0] me.user = d.result[0]
inputs = me.select "[input-class='user-input']" inputs = me.select "[input-class='user-input']"
($ v).val me.user[v.name] for v in inputs ($ v).val me.user[v.name] for v in inputs
@ -212,11 +212,11 @@ class Blogger extends this.OS.GUI.BaseApplication
me = @ me = @
inputs = @select "[input-class='user-input']" inputs = @select "[input-class='user-input']"
@user[v.name] = ($ v).val() for v in inputs @user[v.name] = ($ v).val() for v in inputs
return @notify "Full name must be entered" if not @user.fullname or @user.fullname is "" return @notify __("Full name must be entered") if not @user.fullname or @user.fullname is ""
#console.log @user #console.log @user
@userdb.save @user, (r) -> @userdb.save @user, (r) ->
return me.error "Cannot save user data" if r.error return me.error __("Cannot save user data") if r.error
return me.notify "User data updated" return me.notify __("User data updated")
# PORFOLIO TAB # PORFOLIO TAB
@ -232,7 +232,7 @@ class Blogger extends this.OS.GUI.BaseApplication
@cvcatdb.find cnd, (d) -> @cvcatdb.find cnd, (d) ->
if d.error if d.error
me.cvlist.set "data", data me.cvlist.set "data", data
return me.notify "Cannot fetch CV categories" return me.notify __("Cannot fetch CV categories")
me.fetchCVCat d.result, data, "0" me.fetchCVCat d.result, data, "0"
me.cvlist.set "data", data me.cvlist.set "data", data
#it = (me.cvlist.find "pid", "2")[0] #it = (me.cvlist.find "pid", "2")[0]
@ -258,10 +258,10 @@ class Blogger extends this.OS.GUI.BaseApplication
cond = ({ "=": { cid: v } } for v in ids) cond = ({ "=": { cid: v } } for v in ids)
# delete all content # delete all content
@cvsecdb.delete { "or": cond }, (r) -> @cvsecdb.delete { "or": cond }, (r) ->
return me.error "Cannot delete all content of: #{cat.name} [#{r.error}]" if r.error return me.error __("Cannot delete all content of: {0} [{1}]", cat.name, r.error) if r.error
cond = ({ "=": { id: v } } for v in ids) cond = ({ "=": { id: v } } for v in ids)
me.cvcatdb.delete { "or": cond }, (re) -> me.cvcatdb.delete { "or": cond }, (re) ->
return me.error "Cannot delete the category: #{cat.name} [#{re.error}]" if re.error return me.error __("Cannot delete the category: {0} [{1}]", cat.name, re.error) if re.error
me.refreshCVCat() me.refreshCVCat()
CVSectionByCID: (cid) -> CVSectionByCID: (cid) ->
@ -273,10 +273,10 @@ class Blogger extends this.OS.GUI.BaseApplication
order: order:
start: "DESC" start: "DESC"
@cvsecdb.find cond, (d) -> @cvsecdb.find cond, (d) ->
return me.notify "Section list is empty, please add one" if d.error return me.notify __("Section list is empty, please add one") if d.error
v.text = v.title for v in d.result v.text = v.title for v in d.result
items = [] items = []
$(me.find "cv-sec-status").html "Found #{d.result.length} sections" $(me.find "cv-sec-status").html __("Found {0} sections", d.result.length)
for v in d.result for v in d.result
v.text = v.title v.text = v.title
v.complex = true v.complex = true
@ -298,10 +298,10 @@ class Blogger extends this.OS.GUI.BaseApplication
me.openDialog "YesNoDialog", (b) -> me.openDialog "YesNoDialog", (b) ->
return unless b return unless b
me.cvsecdb.delete e.item.item.id, (r) -> me.cvsecdb.delete e.item.item.id, (r) ->
return me.error "Cannot delete the section: #{r.error}" if r.error return me.error __("Cannot delete the section: {0}", r.error) if r.error
el.remove e.item.item, true el.remove e.item.item, true
, "Delete section" , , __("Delete section") ,
{ iconclass: "fa fa-question-circle", text: "Do you really want to delete: #{e.item.item.text} ?" } { iconclass: "fa fa-question-circle", text: __("Do you really want to delete: {0}?",e.item.item.text) }
return false return false
el.set "items", items el.set "items", items
@ -312,8 +312,8 @@ class Blogger extends this.OS.GUI.BaseApplication
tags = @inputtags.value tags = @inputtags.value
content = @editor.value() content = @editor.value()
title = (new RegExp "^#+(.*)\n", "g").exec content title = (new RegExp "^#+(.*)\n", "g").exec content
return @notify "Please insert a title in the text: beginning with heading" unless title and title.length is 2 return @notify __("Please insert a title in the text: beginning with heading") unless title and title.length is 2
return @notify "Please enter tags" if tags is "" return @notify __("Please enter tags") if tags is ""
d = new Date() d = new Date()
data = data =
content: content.asBase64() content: content.asBase64()
@ -328,7 +328,7 @@ class Blogger extends this.OS.GUI.BaseApplication
data.id = sel.id if sel data.id = sel.id if sel
#save the data #save the data
@blogdb.save data, (r) -> @blogdb.save data, (r) ->
return me.error "Cannot save blog: #{r.error}" if r.error return me.error __("Cannot save blog: {0}", r.error) if r.error
me.loadBlogs() me.loadBlogs()
process: (text) -> process: (text) ->
@ -377,15 +377,15 @@ class Blogger extends this.OS.GUI.BaseApplication
"utimestr" "utimestr"
] ]
@blogdb.find cond, (r) -> @blogdb.find cond, (r) ->
return me.notify "No post found: #{r.error}" if r.error return me.notify __("No post found: {0}", r.error) if r.error
console.log r.result console.log r.result
for v in r.result for v in r.result
v.text = v.title v.text = v.title
v.complex = true v.complex = true
v.closable = true v.closable = true
v.detail = [ v.detail = [
{ text: "Created: #{v.ctimestr}", class: "blog-dates" }, { text: __("Created: {0}", v.ctimestr), class: "blog-dates" },
{ text: "Updated: #{v.utimestr}", class: "blog-dates" }] { text: __("Updated: {0}", v.utimestr), class: "blog-dates" }]
me.bloglist.set "items", r.result me.bloglist.set "items", r.result
if selidx isnt -1 if selidx isnt -1
me.bloglist.set "selected", selidx me.bloglist.set "selected", selidx

View File

@ -5,26 +5,26 @@
<afx-hbox data-id="user-container" data-height="100%"> <afx-hbox data-id="user-container" data-height="100%">
<afx-vbox> <afx-vbox>
<afx-hbox data-height = "30"> <afx-hbox data-height = "30">
<afx-label data-width= "70" text = "Full name:"></afx-label> <afx-label data-width= "70" text = "__(Full name)"></afx-label>
<input type = "text" name="fullname" input-class = "user-input"/> <input type = "text" name="fullname" input-class = "user-input"/>
</afx-hbox> </afx-hbox>
<afx-hbox data-height = "30"> <afx-hbox data-height = "30">
<afx-label text = "Address:" data-width= "70"></afx-label> <afx-label text = "__(Address)" data-width= "70"></afx-label>
<input type = "text" name="address" input-class = "user-input"/> <input type = "text" name="address" input-class = "user-input"/>
</afx-hbox> </afx-hbox>
<afx-hbox data-height = "30"> <afx-hbox data-height = "30">
<afx-label text = "Phone:" data-width= "70"></afx-label> <afx-label text = "__(Phone)" data-width= "70"></afx-label>
<input type = "text" name="Phone" input-class = "user-input"/> <input type = "text" name="Phone" input-class = "user-input"/>
</afx-hbox> </afx-hbox>
<afx-hbox data-height = "30"> <afx-hbox data-height = "30">
<afx-label text = "Email:" data-width= "70"></afx-label> <afx-label text = "__(Email)" data-width= "70"></afx-label>
<input type = "text" name="email" input-class = "user-input"/> <input type = "text" name="email" input-class = "user-input"/>
</afx-hbox> </afx-hbox>
<afx-hbox data-height = "30"> <afx-hbox data-height = "30">
<afx-label text = "Url:" data-width= "70"></afx-label> <afx-label text = "__(Url)" data-width= "70"></afx-label>
<input type = "text" name="url" input-class = "user-input"/> <input type = "text" name="url" input-class = "user-input"/>
</afx-hbox> </afx-hbox>
<afx-label data-height = "30" text = "Short biblio:"/> <afx-label data-height = "30" text = "__(Short biblio)"/>
<textarea name="shortbiblio" input-class = "user-input"/> <textarea name="shortbiblio" input-class = "user-input"/>
<afx-hbox data-height = "35"> <afx-hbox data-height = "35">
<div></div> <div></div>
@ -34,7 +34,7 @@
</afx-hbox> </afx-hbox>
<afx-hbox data-id="cv-container" data-height="100%"> <afx-hbox data-id="cv-container" data-height="100%">
<afx-vbox data-width="150" min-width="100"> <afx-vbox data-width="150" min-width="100">
<afx-label class = "cat-header" data-height = "23" text = "Categories" iconclass = "fa fa-bars"></afx-label> <afx-label class = "cat-header" data-height = "23" text = "__(Categories)" iconclass = "fa fa-bars"></afx-label>
<afx-tree-view data-id = "cv-list" ></afx-tree-view> <afx-tree-view data-id = "cv-list" ></afx-tree-view>
<afx-hbox data-height="30" class = "cv-side-bar-btn"> <afx-hbox data-height="30" class = "cv-side-bar-btn">
<afx-button data-id = "cv-cat-add" data-width = "25" text = "" iconclass = "fa fa-plus-circle"></afx-button> <afx-button data-id = "cv-cat-add" data-width = "25" text = "" iconclass = "fa fa-plus-circle"></afx-button>
@ -60,7 +60,7 @@
<div data-id = "editor-container"> <div data-id = "editor-container">
<textarea data-id="markarea" ></textarea> <textarea data-id="markarea" ></textarea>
</div> </div>
<afx-label text = "Tags:" style="font-weight:bold;" data-height="25" ></afx-label> <afx-label text = "__(Tags)" style="font-weight:bold;" data-height="25" ></afx-label>
<afx-hbox data-height="25"> <afx-hbox data-height="25">
<input type = "text" data-id = "input-tags" /> <input type = "text" data-id = "input-tags" />
<div data-width="5"></div> <div data-width="5"></div>

View File

@ -61,10 +61,10 @@ class CodeBlock extends this.OS.GUI.BaseApplication
menu = [{ menu = [{
text: "File", text: "File",
child: [ child: [
{ text: "New", dataid: "#{@name}-New", shortcut: "A-N" }, { text: __("New"), dataid: "#{@name}-New", shortcut: "A-N" },
{ text: "Open", dataid: "#{@name}-Open", shortcut: "A-O" }, { text: __("Open"), dataid: "#{@name}-Open", shortcut: "A-O" },
{ text: "Save", dataid: "#{@name}-Save", shortcut: "C-S" }, { text: __("Save"), dataid: "#{@name}-Save", shortcut: "C-S" },
{ text: "Save as", dataid: "#{@name}-Saveas", shortcut: "A-W" } { text: __("Save as"), dataid: "#{@name}-Saveas", shortcut: "A-W" }
], ],
onmenuselect: (e) -> me.actionFile e.item.data.dataid onmenuselect: (e) -> me.actionFile e.item.data.dataid
}] }]

View File

@ -97,7 +97,7 @@ class PushNotification extends this.OS.GUI.BaseService
PushNotification.scheme = """ PushNotification.scheme = """
<afx-dummy> <afx-dummy>
<afx-overlay data-id = "notifyzone" width = "250"> <afx-overlay data-id = "notifyzone" width = "250">
<afx-button text = "Clear all" data-id = "btclear"></afx-button> <afx-button text = "__(Clear all)" data-id = "btclear"></afx-button>
<afx-list-view data-id="notifylist"></afx-list-view> <afx-list-view data-id="notifylist"></afx-list-view>
</afx-overlay> </afx-overlay>
<afx-overlay data-id = "feedzone" width = "250"> <afx-overlay data-id = "feedzone" width = "250">

View File

@ -7,17 +7,17 @@ class UserService extends this.OS.GUI.BaseService
me = @ me = @
@child = [ @child = [
{ {
text: "About", dataid: "user-about", text: __("About"), dataid: "user-about",
iconclass: "fa fa-user-circle-o" iconclass: "fa fa-user-circle-o"
}, },
{ {
text: "Logout", dataid: "sys-logout", text: __("Logout"), dataid: "sys-logout",
iconclass: "fa fa-user-times" iconclass: "fa fa-user-times"
} }
] ]
@onmenuselect = (d) -> @onmenuselect = (d) ->
return window.OS.exit() if d.item.data.dataid is "sys-logout" return window.OS.exit() if d.item.data.dataid is "sys-logout"
me.notify "This feature is not implemented yet" me.notify __("This feature is not implemented yet")
awake: (e) -> awake: (e) ->
cleanup: (evt) -> cleanup: (evt) ->

View File

@ -7,7 +7,7 @@
</afx-vbox> </afx-vbox>
<afx-resizer data-width = "5" ></afx-resizer> <afx-resizer data-width = "5" ></afx-resizer>
<afx-vbox> <afx-vbox>
<afx-button data-height="30" text="Read more" iconclass="fa fa-camera-retro fa-lg" id="button"></afx-button> <afx-button data-height="30" text="__(Read more)" iconclass="fa fa-camera-retro fa-lg" id="button"></afx-button>
<afx-switch enable= true data-height="30"></afx-switch> <afx-switch enable= true data-height="30"></afx-switch>
<afx-calendar-view></afx-calendar-view> <afx-calendar-view></afx-calendar-view>
<afx-resizer data-height = "5" ></afx-resizer> <afx-resizer data-height = "5" ></afx-resizer>

View File

@ -124,7 +124,7 @@ class MarketPlace extends this.OS.GUI.BaseApplication
app.path.asFileHandler().remove (r) -> app.path.asFileHandler().remove (r) ->
return me.error "Cannot uninstall package: #{r.error}" if r.error return me.error "Cannot uninstall package: #{r.error}" if r.error
me.notify "Package uninstalled" me.notify "Package uninstalled"
me.systemsetting.system.packages[name] = undefined delete me.systemsetting.system.packages[name]
me._gui.refreshSystemMenu() me._gui.refreshSystemMenu()
me.appDetail sel me.appDetail sel
, "Uninstall" , , "Uninstall" ,