add FormatedString class, automatically translate to new locale when locale is set

This commit is contained in:
Xuan Sang LE 2018-03-10 20:42:09 +01:00
parent 88cf90ae50
commit 6367c321da
12 changed files with 75 additions and 39 deletions

View File

@ -87,7 +87,7 @@ class PromptDialog extends BasicDialog
resizable: false,
buttons: [
{
label: __("Ok"),
label: "__(Ok)",
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,7 +119,7 @@ class CalendarDialog extends BasicDialog
resizable: false,
buttons: [
{
label: __('Ok'),
label: "__(Ok)",
onclick: (d) ->
date = (d.find "content0").get "selectedDate"
if date
@ -129,7 +129,7 @@ class CalendarDialog extends BasicDialog
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

View File

@ -1,3 +1,32 @@
class FormatedString
constructor: (@fs, args) ->
@values = []
return unless args
@values[i] = args[i] for i in [0..args.length - 1]
toString: ()->
@
__: () ->
me = @
return __(@fs).replace /{(\d+)}/g, (match, number) ->
return if typeof me.values[number] != 'undefined' then me.values[number] else match
hash: () ->
@__().hash()
asBase64: () ->
@__().asBase64()
unescape: () ->
@__().unescape()
asUint8Array: () ->
@__().asUint8Array()
format: () ->
args = arguments
@values[i] = args[i] for i in [0..args.length - 1]
String.prototype.hash = () ->
hash = 5381
i = this.length
@ -19,7 +48,7 @@ String.prototype.unescape = () ->
d = d.replace /\\f/g, "\f"
d = d.replace /\\r/g, "\r"
d
String.prototype.asUnit8Array = () ->
String.prototype.asUint8Array = () ->
bytes = []
for i in [0..(@length - 1)]
bytes.push @charCodeAt i
@ -29,14 +58,18 @@ String.prototype.asUnit8Array = () ->
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
return new FormatedString(@, args)
String.prototype.f = () ->
args = arguments
return new FormatedString(@, args)
String.prototype.__ = () ->
match = @match(/^__\((.*)\)$/)
return window.__(match[1]) if match
return @
# language directive
this.__ = () ->
_API = window.OS.API
args = arguments
@ -44,7 +77,7 @@ this.__ = () ->
d = args[0]
_API.lang[d] = d unless _API.lang[d]
return _API.lang[d] unless args.length > 1
return String.prototype.format.apply _API.lang[d], (args[i] for i in [1 .. args.length - 1])
return String.prototype.format.apply d, (args[i] for i in [1 .. args.length - 1])
Date.prototype.toString = () ->
dd = @getDate()

View File

@ -408,7 +408,7 @@ self.OS.GUI =
_GUI.buildSystemMenu()
# push startup services
# TODO: get services list from user setting
_GUI.pushServices (v for v in _OS.setting.system.startup.services)
#_GUI.pushServices (v for v in _OS.setting.system.startup.services)
(_GUI.launch a) for a in _OS.setting.system.startup.apps
#_GUI.launch "DummyApp"
# initDM

View File

@ -5,8 +5,8 @@
<afx-file-view data-id = "fileview" view='tree' status = false></afx-file-view>
<input data-height = '26' type = "text" data-id = "filename" style="margin-left:5px; margin-right:5px;display:none;" />
<div data-height = '30' style=' text-align:right;padding-top:3px;'>
<afx-button data-id = "bt-ok" text = "Ok"></afx-button>
<afx-button data-id = "bt-cancel" text = "Cancel"></afx-button>
<afx-button data-id = "bt-ok" text = "__(Ok)"></afx-button>
<afx-button data-id = "bt-cancel" text = "__(Cancel)"></afx-button>
</div>
</afx-vbox>
</afx-hbox>

View File

@ -4,7 +4,7 @@
<div class = "treecontainer" ref="treecontainer">
<afx-tree-view ref = "treeview" observable = {root.observable}></afx-tree-view>
</div>
<div if = {status == true} class = "status" ref = "stbar"></div>
<afx-label if = {status == true} class = "status" ref = "stbar"></afx-label>
<script>
var self = this
self.root.observable = opts.observable || riot.observable()
@ -49,7 +49,7 @@
var h = $(self.root).outerHeight()
var w = $(self.root).width()
if(self.refs.stbar)
h -= ($(self.refs.stbar).height() + 10)
h -= ($(self.refs.stbar.root).height() + 10)
$(self.refs.listview.root).css("height", h + "px")
$(self.refs.gridview.root).css("height", h + "px")
$(self.refs.treecontainer).css("height", h + "px")
@ -126,7 +126,8 @@
f(getTreeData(d))
})
})
$(self.refs.stbar).html("")
if(self.refs.stbar)
self.refs.stbar.root.set("text", "")
switch (self.view) {
case 'icon':
$(self.refs.listview.root).show()
@ -200,8 +201,8 @@
self.selectedFile = e.data
if(self.onfileselect)
self.onfileselect(e.data)
$(self.refs.stbar).empty()
$(self.refs.stbar).append($("<span>").append(__("Selected: {0} ({1} bytes)", e.data.filename, e.data.size?e.data.size:"0")))//.html()
if(self.refs.stbar)
self.refs.stbar.root.set("text", __("Selected: {0} ({1} bytes)", e.data.filename, e.data.size?e.data.size:"0"))//.html()
})
self.root.observable.on("filedbclick", function(e){
if(e.id != self.rid ) return

View File

@ -33,7 +33,8 @@ class BaseFileHandler
@genealogy = re.split("/")
@basename = @genealogy[@genealogy.length - 1] unless @isRoot()
@ext = @basename.split( "." ).pop() unless @basename.lastIndexOf(".") is 0 or @basename.indexOf( "." ) is -1
asFileHandler: () ->
@
isRoot: () -> (not @genealogy) or (@genealogy.size is 0)
child: (name) ->

View File

@ -164,7 +164,7 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
.then (r) ->
_API.loaded q, "OK"
return f r.body unless p is "binary"
f r.body.asUnit8Array()
f r.body.asUint8Array()
.catch (err) ->
_API.loaded q, "FAIL"
_courrier.oserror __("VFS cannot read : {0}", me.path), (_API.throwe "OS.VFS"), err

View File

@ -196,7 +196,7 @@ class Files extends this.OS.GUI.BaseApplication
file.path.asFileHandler()
.move "#{me.currdir.path}/#{d}", (r) ->
me.error __("Fail to rename to {0}: {1}", d, r.error) if r.error
, __("Rename"), { label: __("File name"), value: file.filename }
, "__(Rename)", { label: "__(File name)", value: file.filename }
when "#{@name}-rm"
return unless file
@ -206,7 +206,7 @@ class Files extends this.OS.GUI.BaseApplication
file.path.asFileHandler()
.remove (r) ->
me.error __("Fail to delete {0}: {1}", file.filename, r.error) if r.error
, __("Delete") ,
,"__(Delete)" ,
{ iconclass: "fa fa-question-circle", text: __("Do you really want to delete: {0}?", file.filename) }
when "#{@name}-cut"
@ -247,7 +247,7 @@ class Files extends this.OS.GUI.BaseApplication
(d) ->
me.currdir.mk d, (r) ->
me.error __("Fail to create {0}: {1}", d, r.error) if r.error
, __("New folder"), { label: __("Folder name") }
, "__(New folder)", { label: "__(Folder name)" }
when "#{@name}-mkf"
@openDialog "PromptDialog",
@ -255,7 +255,7 @@ class Files extends this.OS.GUI.BaseApplication
fp = "#{me.currdir.path}/#{d}".asFileHandler()
fp.write "text/plain", (r) ->
me.error __("Fail to create {0}: {1}", d, r.error) if r.error
, __("New file"), { label: __("File name") }
, "__(New file)", { label: "__(File name)" }
when "#{@name}-info"
return unless file

View File

@ -58,7 +58,7 @@ class NotePad extends this.OS.GUI.BaseApplication
stup = (e) ->
c = me.editor.session.selection.getCursor()
l = me.editor.session.getLength()
$(stat).html __("Row {0}, col {1}, lines: {2}", c.row, c.column, l)
stat.set "text", __("Row {0}, col {1}, lines: {2}", c.row, c.column, l)
stup(0)
@.editor.getSession().selection.on "changeCursor", (e) -> stup(e)
@editormux = false
@ -133,6 +133,7 @@ class NotePad extends this.OS.GUI.BaseApplication
me = @
file = @fileview.get "selectedFile"
dir = if file then file.path.asFileHandler() else (@fileview.get "path").asFileHandler()
console.log dir
dir = dir.parent().asFileHandler() if file and file.type isnt "dir"
switch e.item.data.dataid
@ -141,7 +142,7 @@ class NotePad extends this.OS.GUI.BaseApplication
(d) ->
dir.mk d, (r) ->
me.error __("Fail to create {0}: {1}", d, r.error) if r.error
, __("New folder")
, "__(New folder)"
when "#{@name}-mkf"
@openDialog "PromptDialog",
@ -149,7 +150,7 @@ class NotePad extends this.OS.GUI.BaseApplication
fp = "#{dir.path}/#{d}".asFileHandler()
fp.write "", (r) ->
me.error __("Fail to create {0}: {1}", d, r.error) if r.error
, __("New file")
, "__(New file)"
when "#{@name}-rm"
return unless file
@openDialog "YesNoDialog",
@ -158,7 +159,7 @@ class NotePad extends this.OS.GUI.BaseApplication
file.path.asFileHandler()
.remove (r) ->
me.error __("Fail to delete {0}: {1}", file.filename, r.error) if r.error
, __("Delete") ,
, "__(Delete)" ,
{ iconclass: "fa fa-question-circle", text: __("Do you really want to delete: {0}?", file.filename) }
when "#{@name}-refresh"
@.chdir ( @fileview.get "path" )
@ -267,12 +268,12 @@ class NotePad extends this.OS.GUI.BaseApplication
me.tabarea.replaceItem me.currfile, file, false
me.currfile = file
me.save me.currfile
, __("Save as"), { file: me.currfile }
, "__(Save as)", { file: me.currfile }
switch e
when "#{@name}-Open"
@openDialog "FileDiaLog", ( d, f ) ->
me.open "#{d}/#{f}".asFileHandler()
, __("Open file")
, "__(Open file)"
when "#{@name}-Save"
@currfile.cache = @editor.getValue()
return @save @currfile if @currfile.basename
@ -292,7 +293,7 @@ class NotePad extends this.OS.GUI.BaseApplication
if d
v.dirty = false for v in dirties
me.quit()
, __("Quit"), { text: __("Ignore all {0} unsaved files ?", dirties.length) }
, "__(Quit)", { text: __("Ignore all {0} unsaved files ?", dirties.length) }
NotePad.singleton = false
NotePad.dependencies = [

View File

@ -11,7 +11,7 @@ afx-app-window[data-id="notepad"] afx-resizer{
background-color: transparent;
border-right: 1px solid #a6a6a6;
}
afx-app-window[data-id="notepad"] span[data-id="editorstat"]{
afx-app-window[data-id="notepad"] afx-label[data-id="editorstat"]{
padding:5px;
display: inline-block;
}

View File

@ -9,7 +9,7 @@
<afx-tab-container data-id="tabarea" data-height="26" closable = true></afx-tab-container>
<div data-id="datarea"></div>
<afx-hbox data-height="30" data-id="bottom-vbox">
<div ><span data-id = "editorstat"></span></div>
<afx-label data-id="editorstat"></afx-label>
<afx-list-view data-width="160" data-id = "themelist" dropdown = "true" width="135"></afx-list-view>
<afx-list-view data-width="125" data-id = "modelist" dropdown = "true" width="100"></afx-list-view>

View File

@ -1,7 +1,7 @@
afx-file-view {
position: relative;
}
afx-file-view div.status{
afx-file-view afx-label.status{
position: absolute;
bottom: 1px;
left:0px;