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\
src/core/api.coffee\
src/core/lang/generator.coffee\
src/core/settings.coffee\
src/core/handlers/RemoteHandler.coffee\
src/core/vfs.coffee\
@ -56,7 +57,8 @@ testdata:
cp src/core/handlers/jsons/* $(BUILDDIR)/resources/jsons
build_tags:
@echo "$(BLUE)Building tag files$(NC)"
-mkdir $(BUILDDIR)/resources
-mkdir $(BUILDDIR)/resources
-mkdir $(BUILDDIR)/resources/languages
-rm $(BUILDDIR)/resources/antos_tags.js
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,
child: [
{ text: "About", dataid: "#{@name}-about" },
{ text: "Exit", dataid: "#{@name}-exit" }
{ text: __("About"), dataid: "#{@name}-about" },
{ text: __("Exit"), dataid: "#{@name}-exit" }
]
}]
mn = mn.concat @menu() || []

View File

@ -87,7 +87,7 @@ class PromptDialog extends BasicDialog
resizable: false,
buttons: [
{
label: "0k",
label: __("0k"),
onclick: (d) ->
txt = (d.find "content1").value
return d.quit() if txt is ""
@ -95,7 +95,7 @@ class PromptDialog extends BasicDialog
d.quit()
},
{
label: "Cancel",
label: __("Cancel"),
onclick: (d) -> d.quit()
}
],
@ -119,17 +119,17 @@ class CalendarDialog extends BasicDialog
resizable: false,
buttons: [
{
label: 'Ok',
label: __('Ok'),
onclick: (d) ->
date = (d.find "content0").get "selectedDate"
if date
d.handler date if d.handler
d.quit()
else
d.notify "Please select a date"
d.notify __("Please select a date")
},
{
label: 'Cancel',
label: __('Cancel'),
onclick: (d) -> d.quit()
}
]
@ -145,7 +145,7 @@ class ColorPickerDialog extends BasicDialog
resizable: false,
buttons: [
{
label: 'Ok',
label: __('Ok'),
onclick: (d) ->
c = (d.find "content0").get "selectedColor"
if c
@ -155,7 +155,7 @@ class ColorPickerDialog extends BasicDialog
d.notify "Please select a color"
},
{
label: 'Cancel',
label: __('Cancel'),
onclick: (d) -> d.quit()
}
]
@ -169,7 +169,7 @@ class InfoDialog extends BasicDialog
width: 250,
height: 300,
resizable: true,
buttons: [ { label: 'Cancel', onclick: (d) -> d.quit() } ],
buttons: [ { label: __('Cancel'), onclick: (d) -> d.quit() } ],
filldata: (d) ->
return unless d.data
rows = []
@ -188,12 +188,12 @@ class YesNoDialog extends BasicDialog
resizable: true,
buttons: [
{
label: "Yes", onclick: (d) ->
label: __("Yes"), onclick: (d) ->
d.handler true if d.handler
d.quit()
},
{
label: "No", onclick: (d) ->
label: __("No"), onclick: (d) ->
d.handler false if d.handler
d.quit()
}
@ -215,14 +215,14 @@ class SelectionDialog extends BasicDialog
resizable: false,
buttons: [
{
label: "Ok", onclick: (d) ->
label: __("Ok"), onclick: (d) ->
el = d.find "content0"
it = el.get "selected"
return unless it
d.handler it if d.handler
d.quit()
},
{ label: "Cancel", onclick: (d) -> d.quit() }
{ label: __("Cancel"), onclick: (d) -> d.quit() }
],
filldata: (d) ->
return unless d.data
@ -243,7 +243,7 @@ class AboutDialog extends BaseDialog
main: () ->
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 "mydesc").html mt.description
# grid data for author info
@ -270,13 +270,13 @@ class FileDiaLog extends BaseDialog
fileview.set "fetch", (e, f) ->
return unless e.child
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
location.set "onlistselect", (e) ->
return unless e and e.data.path
e.data.path.asFileHandler().read (d) ->
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 "data", d.result
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"
(@find "bt-ok").set "onbtclick", (e) ->
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
#verify the mime
m = false
@ -294,7 +294,7 @@ class FileDiaLog extends BaseDialog
if f.mime.match (new RegExp v, "g")
m = true
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.asFileHandler().parent() if f.type is "file"
me.handler d, ($ filename).val(), f.path if me.handler

View File

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

View File

@ -26,6 +26,22 @@ String.prototype.asUnit8Array = () ->
bytes = new Uint8Array(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 = () ->
dd = @getDate()
mm = @getMonth() + 1
@ -51,6 +67,7 @@ self.OS.API =
handler: {}
shared: {} # shared libraries
searchHandler:{}
lang:{}
#request a user data
mid: () ->
return _courrier.getMID()
@ -178,7 +195,7 @@ self.OS.API =
_courrier.trigger "sharedlibraryloaded", l
f() if f
, (e, s) ->
_courrier.oserror "Cannot load 3rd library at: #{l}", e, r
_courrier.oserror __("Cannot load 3rd library at: {0}", l), e, r
else
path = "os:///scripts/"
js = "#{path}#{l}.js"
@ -196,7 +213,7 @@ self.OS.API =
_courrier.trigger "sharedlibraryloaded", l
f() if f
else
console.log l, "Library exist, no need to load"
console.log l, "Library exist, no need to load"
_courrier.trigger "sharedlibraryloaded", l
requires:(libs, f) ->
@ -228,6 +245,15 @@ self.OS.API =
onsearch: (name, fn) ->
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) ->
err = undefined
try

View File

@ -5,7 +5,7 @@ class DB
_API.handler.dbquery "save", { table: @table, data: d }, f
delete: (c, f) ->
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 ""
if isNaN c
rq.cond = c

View File

@ -9,7 +9,7 @@ self.OS.GUI =
META: {}
SYS_MENU: [
{
text: "Applications",
text: __("Applications"),
child: [],
dataid: "sys-apps"
iconclass: "fa fa-adn",
@ -54,7 +54,7 @@ self.OS.GUI =
return
if not _GUI.subwindows[d]
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.parent = _GUI
_GUI.dialog.handler = f
@ -73,7 +73,7 @@ self.OS.GUI =
return _PM.createProcess srv, _OS.APP[srv] if _OS.APP[srv]
(e, s) ->
_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) ->
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
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
return apps
@ -101,14 +101,14 @@ self.OS.GUI =
openWith: (it) ->
return unless it
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 )
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
list = ( { text: e.app, icon: e.icon, iconclass: e.iconclass } for e in apps )
_GUI.openDialog "SelectionDialog", ( d ) ->
_GUI.launch d.text, [it.path]
, "Open width", list
, __("Open with"), list
forceLaunch: (app, args) ->
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]
($ "#sysdock").get(0).set "selectedApp", null
menu = [
{ text: "Open", dataid: "desktop-open" },
{ text: "Refresh", dataid: "desktop-refresh" }
{ text: __("Open"), dataid: "desktop-open" },
{ text: __("Refresh"), dataid: "desktop-refresh" }
]
menu = menu.concat ( v for k, v of _OS.setting.desktop.menu)
m.set "items", menu
@ -331,7 +331,7 @@ self.OS.GUI =
# mount it
riot.mount desktop
, (e, s) ->
alert "System fall: Cannot init desktop manager"
alert __("System fail: Cannot init desktop manager")
console.log s, e
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.push v for k, v of _OS.setting.system.menu
_GUI.SYS_MENU.push
text: "Toggle Full screen",
text: __("Toggle Full screen"),
dataid: "os-fullsize",
iconclass: "fa fa-tv"
_GUI.SYS_MENU.push
text: "Log out",
text: __("Log out"),
dataid: "sys-logout",
iconclass: "fa fa-user-times"
buildSystemMenu: () ->
@ -378,7 +378,7 @@ self.OS.GUI =
($ "#txtpass").keyup (e) ->
($ "#btlogin").click() if e.which is 13
, (e, s) ->
alert "System fall: Cannot init login screen"
alert __("System fail: Cannot init login screen")
startAntOS: (conf) ->
# clean up things

View File

@ -10,36 +10,36 @@ self.OS.API.handler =
scandir: (p, c ) ->
path = "#{_REST}/fs/scandir"
_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 ) ->
path = "#{_REST}/fs/mkdir"
_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) ->
path = "#{_REST}/fs/publish"
_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) ->
path = "#{_REST}/fs/fileinfo"
_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) ->
path = "#{_REST}/fs/get/"
_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
move: (s, d, c) ->
path = "#{_REST}/fs/move"
_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) ->
path = "#{_REST}/fs/delete"
_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) ->
path = "#{_REST}/fs/get/"
@ -49,44 +49,44 @@ self.OS.API.handler =
packages: (d, c) ->
path = "#{_REST}/system/packages"
_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) ->
path = "#{_REST}/fs/upload"
_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) ->
path = "#{_REST}/fs/write"
_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 ) ->
path = "#{_REST}/system/application"
auth: (c) ->
p = "#{_REST}/system/auth"
_API.post p, {}, c, () ->
alert "Resource not found: #{p}"
alert __("Resource not found: {0}", p)
login: (d, c) ->
p = "#{_REST}/system/login"
_API.post p, d, c, () ->
alert "Resource not found: #{p}"
alert __("Resource not found: {0}", p)
logout: () ->
p = "#{_REST}/system/logout"
_API.post p, {}, (d) ->
_OS.boot()
, () ->
alert "Resource not found #{p}"
alert __("Resource not found: {0}", p)
setting: (f) ->
p = "#{_REST}/system/settings"
_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
, (e, s) ->
_courrier.osfail "Fail to make request: #{p}", e, s
_courrier.osfail __("Fail to make request: {0}", p), e, s
f() if f
dbquery: (cmd, d, c) ->
path = "#{_REST}/db/#{cmd}"
_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.appearance = conf.appearance if conf.appearance
_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.desktop.path = "home:///.desktop" unless _OS.setting.desktop.path
_OS.setting.desktop.menu = {} unless _OS.setting.desktop.menu
_OS.setting.VFS.mountpoints = [
#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: "Home", path: 'home:///', iconclass: "fa fa-home", 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: "Google Drive", path: 'gdv:///', iconclass: "fa fa-inbox", type: "fs" },
{ text: "Shared", path: 'shared:///' , iconclass: "fa fa-share-square", type: "fs" }
{ text: __("Applications"), path: 'app:///', iconclass: "fa fa-adn", type: "app" },
{ text: __("Home"), path: 'home:///', iconclass: "fa fa-home", 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: __("Google Drive"), path: 'gdv:///', iconclass: "fa fa-inbox", type: "fs" },
{ text: __("Shared"), path: 'shared:///' , iconclass: "fa fa-share-square", type: "fs" }
] if not _OS.setting.VFS.mountpoints
_OS.setting.system = conf.system if conf.system
@ -44,7 +45,7 @@
} unless _OS.setting.VFS.gdrive
#search for app
_API.onsearch "Applications", (t) ->
_API.onsearch __("Applications"), (t) ->
ar = []
term = new RegExp t, "i"
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>
<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
var self = this
this.day = 0
@ -62,7 +62,7 @@
self.year = 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)
next_month = new Date(self.year, self.month + 1, 1)

View File

@ -20,7 +20,7 @@
this.fetch = opts.fetch
this.chdir = opts.chdir
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)
{
@ -200,7 +200,7 @@
if(self.onfileselect)
self.onfileselect(e.data)
$(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){
if(e.id != self.rid ) return

View File

@ -2,7 +2,7 @@
<span style = {color?"color:" + color:""} >
<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>
{ text }
{ parse(text) }
</span>
<script>
this.iconclass = opts.iconclass
@ -29,5 +29,16 @@
{
return self[k]
}
parse(text)
{
if(!text) return ""
match = text.match(/^__\(([^\)]*)\)$/)
if(match)
{
return window.__(match[1])
}
else
return text
}
</script>
</afx-label>

View File

@ -2,7 +2,7 @@ String.prototype.asFileHandler = () ->
list = @split ":///"
handlers = _API.VFS.findHandlers list[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 new handlers[0](@)
@ -63,7 +63,7 @@ class BaseFileHandler
reader.onload = () ->
f reader.result
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: () ->
return @ if @isRoot()
return (@protocol + ":///" + (@genealogy.slice 0 , @genealogy.length - 1).join "/")
@ -132,7 +132,7 @@ class BaseFileHandler
# for main action read, write, remove, execute
# must be implemented by subclasses
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
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"
_API.handler.readfile @path, f, if p then p else "text"
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
when "write"
@sendB64 p, (data) ->
@ -174,7 +174,7 @@ class RemoteFileHandler extends self.OS.API.VFS.BaseFileHandler
when "move"
_API.handler.move @path, p, f
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
@ -217,7 +217,7 @@ class ApplicationHandler extends self.OS.API.VFS.BaseFileHandler
when "move"
return
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
@ -267,7 +267,7 @@ class BufferFileHandler extends self.OS.API.VFS.BaseFileHandler
when "move"
return
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
@ -309,6 +309,6 @@ class SharedFileHandler extends self.OS.API.VFS.BaseFileHandler
when "move"
return
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

View File

@ -7,7 +7,7 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
super path
me = @
@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()
@cache = ""
@ -41,12 +41,13 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
gapi.auth2.getAuthInstance().isSignedIn.listen (r) ->
fn(r)
_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())
, "Authentification", { text: "Would you like to login to Google Drive ?" }
, __("Authentication")
, { text: __("Would you like to login to {0}?", "Google Drive") }
.catch (err) ->
_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) ->
me = @
@ -67,7 +68,7 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
f(r)
.catch (err) ->
_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
#console.log "Find file in ", me.parent()
fp = me.parent().asFileHandler()
@ -89,7 +90,7 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
f { result: r.result.files[0] }
.catch (err) ->
_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: () ->
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"
error = (e, s) ->
_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 = () ->
if ( xhr.readyState == 4 )
if ( xhr.status == 200 )
@ -154,7 +155,7 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
f { result: r.result.files }
.catch (err) ->
_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
gapi.client.drive.files.get {
fileId: me.info.id,
@ -166,10 +167,10 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
f r.body.asUnit8Array()
.catch (err) ->
_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"
return f { error: "#{@path} is not a directory" } unless @isFolder()
return f { error: __("{0} is not a directory", @path) } unless @isFolder()
meta =
name: p,
parents: [@info.id],
@ -182,12 +183,12 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
.then (r) ->
_API.loaded q, "OK"
#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" }
f r
.catch (err) ->
_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
@ -211,12 +212,12 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
}
.then (r) ->
_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 }
me.save r.result.id, p, f
.catch (err) ->
_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"
return unless @isFolder()
@ -244,12 +245,12 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
.then (r) ->
#console.log r
_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
f { result: true }
.catch (err) ->
_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"
_API.loaded q, "OK"
@ -262,7 +263,7 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
}
.then (r) ->
_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 = []
for i in [0..(r.body.length - 1)]
bytes.push r.body.charCodeAt i
@ -271,7 +272,7 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
_API.saveblob me.basename, blob
.catch (err) ->
_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"
dest = p.asFileHandler().parent().asFileHandler()
@ -285,16 +286,16 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
}
.then (r) ->
_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
.catch (err) ->
_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) ->
_API.loaded q, "FAIL"
else
_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

View File

@ -14,7 +14,7 @@ class ActivityMonitor extends this.OS.GUI.BaseApplication
app = _PM.appByPid item[0].value
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 =
processes:{}
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,
iconclass:if _APP[a.name].type == 1 then _APP[a.name].meta.iconclass else a.iconclass,
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}
]
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-vbox>
<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-app-window>

View File

@ -2,30 +2,30 @@
<afx-vbox >
<div data-height="5"></div>
<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"/>
</afx-hbox>
<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"/>
</afx-hbox>
<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"/>
</afx-hbox>
<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"/>
<afx-label text = "To:" style="text-align:center;" data-width= "70"></afx-label>
<input type = "text" name="end" input-class = "user-input"/>
</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">
<textarea name="content" data-id = "contentarea" />
</div>
<afx-hbox data-height = "35">
<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-vbox>
</afx-app-window>

View File

@ -2,9 +2,9 @@ class BloggerCategoryDialog extends this.OS.GUI.BasicDialog
constructor: () ->
super "BloggerCategoryDialog", {
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-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'" }
],
width: 200,
@ -15,10 +15,10 @@ class BloggerCategoryDialog extends this.OS.GUI.BasicDialog
label: "0k",
onclick: (d) ->
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
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 __("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
d.handler { p: sel, value: val } if d.handler
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"
@on "vboxchange", () ->
me.resizeContent()
console.log "resize content"
inputs = me.select "[input-class='user-input']"
(($ 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
@ -75,7 +75,7 @@ class BloggerCVSectionDiaglog extends this.OS.GUI.BaseDialog
console.log inputs
data[v.name] = ($ v).val() for v in inputs
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 ""
data.id = me.data.id if me.data and me.data.id
me.handler data if me.handler

View File

@ -42,11 +42,11 @@ class Blogger extends this.OS.GUI.BaseApplication
pid: d.p.id,
publish: 1
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()
#update the list
, "Add category", { tree: me.cvlist.get "data" }
, __("Add category"), { tree: me.cvlist.get "data" }
(@find "cv-cat-edit").set "onbtclick", (e) ->
cat = me.cvlist.get "selectedItem"
@ -59,9 +59,9 @@ class Blogger extends this.OS.GUI.BaseApplication
name: d.value
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()
, "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) ->
cat = me.cvlist.get "selectedItem"
@ -70,26 +70,26 @@ class Blogger extends this.OS.GUI.BaseApplication
(d) ->
return unless d
me.deleteCVCat cat
, "Delete cagegory" ,
{ iconclass: "fa fa-question-circle", text: "Do you really want to delete: #{cat.name} ?" }
, __("Delete category") ,
{ iconclass: "fa fa-question-circle", text: __("Do you really want to delete: {0}?", cat.name) }
(@find "cv-sec-add").set "onbtclick", (e) ->
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) ->
d.cid = Number cat.id
d.start = Number d.start
d.end = Number d.end
d.publish = 1
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)
, "New section entry for #{cat.name}", null
, __("New section entry for {0}", cat.name), null
(@find "cv-sec-move").set "onbtclick", (e) ->
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) ->
c =
@ -97,14 +97,14 @@ class Blogger extends this.OS.GUI.BaseApplication
cid: d.p.id
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.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) ->
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) ->
d.cid = Number sec.cid
@ -112,10 +112,10 @@ class Blogger extends this.OS.GUI.BaseApplication
d.end = Number d.end
d.publish = Number sec.publish
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)
, "Modify section entry", sec
, __("Modify section entry"), sec
@editor = new SimpleMDE
element: me.find "markarea"
@ -124,14 +124,14 @@ class Blogger extends this.OS.GUI.BaseApplication
indentWithTabs: true
toolbar: [
{
name: "new",
name: __("New"),
className: "fa fa-file",
action: (e) ->
me.bloglist.set "selected", -1
me.clearEditor()
},
{
name: "save",
name: __("Save"),
className: "fa fa-save",
action: (e) ->
me.saveBlog()
@ -145,10 +145,10 @@ class Blogger extends this.OS.GUI.BaseApplication
action: (e) ->
me.openDialog "FileDiaLog", (d, n, p) ->
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.replaceSelection "![](#{me._api.handler.shared}/#{r.result})"
, "Select image file", { mimes: ["image/.*"] }
, __("Select image file"), { mimes: ["image/.*"] }
},
{
name:"Youtube",
@ -159,7 +159,7 @@ class Blogger extends this.OS.GUI.BaseApplication
}
"|",
{
name: "preview",
name: __("Preview"),
className: "fa fa-eye no-disable",
action: (e) ->
me.previewOn = !me.previewOn
@ -170,7 +170,7 @@ class Blogger extends this.OS.GUI.BaseApplication
sel = me.bloglist.get "selected"
return unless sel
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.inputtags.value = r.result.tags
(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) ->
return unless b
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.set "selected", -1
me.clearEditor()
, "Delete a post" ,
{ iconclass: "fa fa-question-circle", text: "Do you really want to delete this post ?" }
, __("Delete a post") ,
{ iconclass: "fa fa-question-circle", text: __("Do you really want to delete this post ?") }
return false
@bindKey "CTRL-S", () ->
sel = me.tabbar.get "selidx"
@ -199,7 +199,7 @@ class Blogger extends this.OS.GUI.BaseApplication
when 0 #user info
@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]
inputs = me.select "[input-class='user-input']"
($ v).val me.user[v.name] for v in inputs
@ -212,11 +212,11 @@ class Blogger extends this.OS.GUI.BaseApplication
me = @
inputs = @select "[input-class='user-input']"
@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
@userdb.save @user, (r) ->
return me.error "Cannot save user data" if r.error
return me.notify "User data updated"
return me.error __("Cannot save user data") if r.error
return me.notify __("User data updated")
# PORFOLIO TAB
@ -232,7 +232,7 @@ class Blogger extends this.OS.GUI.BaseApplication
@cvcatdb.find cnd, (d) ->
if d.error
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.cvlist.set "data", data
#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)
# delete all content
@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)
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()
CVSectionByCID: (cid) ->
@ -273,10 +273,10 @@ class Blogger extends this.OS.GUI.BaseApplication
order:
start: "DESC"
@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
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
v.text = v.title
v.complex = true
@ -298,10 +298,10 @@ class Blogger extends this.OS.GUI.BaseApplication
me.openDialog "YesNoDialog", (b) ->
return unless b
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
, "Delete section" ,
{ iconclass: "fa fa-question-circle", text: "Do you really want to delete: #{e.item.item.text} ?" }
, __("Delete section") ,
{ iconclass: "fa fa-question-circle", text: __("Do you really want to delete: {0}?",e.item.item.text) }
return false
el.set "items", items
@ -312,8 +312,8 @@ class Blogger extends this.OS.GUI.BaseApplication
tags = @inputtags.value
content = @editor.value()
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 enter tags" if tags is ""
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 ""
d = new Date()
data =
content: content.asBase64()
@ -328,7 +328,7 @@ class Blogger extends this.OS.GUI.BaseApplication
data.id = sel.id if sel
#save the data
@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()
process: (text) ->
@ -377,15 +377,15 @@ class Blogger extends this.OS.GUI.BaseApplication
"utimestr"
]
@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
for v in r.result
v.text = v.title
v.complex = true
v.closable = true
v.detail = [
{ text: "Created: #{v.ctimestr}", class: "blog-dates" },
{ text: "Updated: #{v.utimestr}", class: "blog-dates" }]
{ text: __("Created: {0}", v.ctimestr), class: "blog-dates" },
{ text: __("Updated: {0}", v.utimestr), class: "blog-dates" }]
me.bloglist.set "items", r.result
if selidx isnt -1
me.bloglist.set "selected", selidx

View File

@ -5,26 +5,26 @@
<afx-hbox data-id="user-container" data-height="100%">
<afx-vbox>
<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"/>
</afx-hbox>
<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"/>
</afx-hbox>
<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"/>
</afx-hbox>
<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"/>
</afx-hbox>
<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"/>
</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"/>
<afx-hbox data-height = "35">
<div></div>
@ -34,7 +34,7 @@
</afx-hbox>
<afx-hbox data-id="cv-container" data-height="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-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>
@ -60,7 +60,7 @@
<div data-id = "editor-container">
<textarea data-id="markarea" ></textarea>
</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">
<input type = "text" data-id = "input-tags" />
<div data-width="5"></div>

View File

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

View File

@ -97,7 +97,7 @@ class PushNotification extends this.OS.GUI.BaseService
PushNotification.scheme = """
<afx-dummy>
<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-overlay>
<afx-overlay data-id = "feedzone" width = "250">

View File

@ -7,17 +7,17 @@ class UserService extends this.OS.GUI.BaseService
me = @
@child = [
{
text: "About", dataid: "user-about",
text: __("About"), dataid: "user-about",
iconclass: "fa fa-user-circle-o"
},
{
text: "Logout", dataid: "sys-logout",
text: __("Logout"), dataid: "sys-logout",
iconclass: "fa fa-user-times"
}
]
@onmenuselect = (d) ->
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) ->
cleanup: (evt) ->

View File

@ -7,7 +7,7 @@
</afx-vbox>
<afx-resizer data-width = "5" ></afx-resizer>
<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-calendar-view></afx-calendar-view>
<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) ->
return me.error "Cannot uninstall package: #{r.error}" if r.error
me.notify "Package uninstalled"
me.systemsetting.system.packages[name] = undefined
delete me.systemsetting.system.packages[name]
me._gui.refreshSystemMenu()
me.appDetail sel
, "Uninstall" ,