Files
starruler-linux/scripts/gui/editor/locale.as
T
2018-07-17 14:15:37 +02:00

306 lines
7.3 KiB
ActionScript

import elements.GuiMarkupText;
import elements.GuiButton;
import elements.GuiTextbox;
import elements.GuiText;
import editor.fields;
import dialogs.Dialog;
import string getLocaleFile(IGuiElement@ elem) from "editor.editor";
bool localesInitialized = false;
void initLocaleMap() {
if(localesInitialized) {
loadLocaleMap();
localesInitialized = true;
}
}
dictionary localeMap;
dictionary localeValues;
string localeName;
void loadLocaleMap() {
localeName = settings::sLocale;
string resolved = resolve("locales/"+localeName);
if(!fileExists(resolved))
localeName = "english";
localeMap.deleteAll();
string folder = topMod.abspath+"/locales/"+localeName;
FileList list(folder, "*.txt", true, false);
for(uint i = 0, cnt = list.length; i < cnt; ++i) {
ReadFile file(list.path[i]);
string fname = "locales/"+localeName+"/"+list.basename[i];
while(file++) {
localeMap.set(file.key, fname);
localeValues.set(file.key, file.value);
}
}
}
string getFromLocale(string ident) {
loadLocaleMap();
if(ident.length != 0 && ident[0] == '#')
ident = ident.substr(1);
string val;
if(!localeValues.get(ident, val))
val = localize(ident);
return val;
}
void changeLocale(string ident, string value, string filename = "misc.txt") {
initLocaleMap();
if(topMod !is baseMod)
filename = topMod.ident+"_"+filename;
if(ident.length != 0 && ident[0] == '#')
ident = ident.substr(1);
//Check if it's in an existing locale
string fname;
if(localeMap.get(ident, fname)) {
filename = path_join(topMod.abspath, fname);
changeLocaleIn(filename, ident, value);
localeValues.set(ident, value);
}
else {
localeMap.set(ident, "locales/"+localeName+"/"+filename);
filename = path_join(path_join(topMod.abspath, "locales/"+localeName), filename);
changeLocaleIn(filename, ident, value);
localeValues.set(ident, value);
}
}
void ensureFile(const string& path) {
string dir = path_up(path);
array<string> folders;
while(!fileExists(dir) && dir.length != 0) {
folders.insertLast(dir);
dir = path_up(dir);
}
for(int i = int(folders.length-1); i >= 0; --i)
makeDirectory(folders[i]);
}
void changeLocaleIn(const string& filename, const string& ident, const string& value) {
array<string> lines;
int pos = -1;
//Read existing file
if(fileExists(filename)) {
ReadFile read(filename);
read.allowLines = true;
read.allowMultiline = false;
read.skipEmpty = false;
read.skipComments = false;
bool inMulti = false;
while(read++) {
if(inMulti) {
if(read.line.trimmed().startswith(">>"))
inMulti = false;
continue;
}
if(read.key == ident) {
pos = lines.length;
if(read.value.trimmed().startswith("<<"))
inMulti = true;
read.key = "";
continue;
}
lines.insertLast(read.line);
}
}
else {
if(value.length == 0)
return;
ensureFile(filename);
}
for(int i = lines.length-1; i >= 0; --i) {
if(lines[i].trimmed().length == 0)
lines.removeAt(i);
else
break;
}
//Manipulate lines
if(value.length != 0) {
string line = ident+": ";
if(value.findFirst("\n") == -1) {
line += escape(value);
}
else {
line += "<<\r\n";
array<string>@ splt = value.split("\n");
for(uint i = 0, cnt = splt.length; i < cnt; ++i) {
if(splt[i].length == 0)
line += "\r\n";
else
line += "\t"+splt[i].trimmed()+"\r\n";
}
line += ">>";
}
if(pos == -1)
lines.insertLast(line);
else
lines.insertAt(pos, line);
}
//Write new file
WriteFile write(filename);
for(uint i = 0, cnt = lines.length; i < cnt; ++i)
write.writeLine(lines[i]);
}
class LocaleEditor : Dialog {
LocaleField@ field;
GuiButton@ accept;
GuiButton@ cancel;
GuiText@ identLabel;
GuiTextbox@ identBox;
GuiButton@ identLoad;
GuiText@ valueLabel;
GuiTextbox@ valueBox;
GuiText@ previewLabel;
GuiPanel@ previewPanel;
GuiMarkupText@ previewBox;
bool changed = false;
string localeIdent;
string suffix;
string origValue;
LocaleEditor(LocaleField@ field) {
@this.field = field;
super(null);
width = 1000;
addTitle("Edit Locale");
string value;
localeIdent = field.value;
suffix = "";
if(localeIdent.length == 0 || localeIdent[0] != '#') {
value = localeIdent;
localeIdent = "";
}
else {
int sep = localeIdent.findFirst(":");
if(sep != -1) {
suffix = localeIdent.substr(sep);
localeIdent = localeIdent.substr(0, sep);
}
value = getFromLocale(localeIdent);
origValue = value;
}
@identLabel = GuiText(bg, Alignment(Left+10, Top+34, Width=80, Height=30), "Locale Key:");
identLabel.font = FT_Bold;
@identBox = GuiTextbox(bg, Alignment(Left+100, Top+34, Width=400, Height=30), localeIdent);
identBox.setIdentifierLimit();
identBox.characterLimit.insert('#');
@identLoad = GuiButton(bg, Alignment(Left+508, Top+34, Width=80, Height=30), "Load");
setMarkupTooltip(identLoad, "Load the value of the specified locale key into the value box. Will override anything already written.");
@valueLabel = GuiText(bg, Alignment(Left+10, Top+70, Left+0.5f-6, Top+100), "Value:");
valueLabel.font = FT_Bold;
@valueBox = GuiTextbox(bg, Alignment(Left+12, Top+100, Left+0.5f-6, Bottom-60));
valueBox.multiLine = true;
@previewLabel = GuiText(bg, Alignment(Left+0.5f+4, Top+70, Right-12, Top+100), "Preview:");
previewLabel.font = FT_Bold;
@previewPanel = GuiPanel(bg, Alignment(Left+0.5f+6, Top+100, Right-12, Bottom-60));
@previewBox = GuiMarkupText(previewPanel, recti_area(0,0,482,100));
@accept = GuiButton(bg, recti());
accept.text = locale::ACCEPT;
accept.tabIndex = 100;
@accept.callback = this;
accept.color = colors::Green;
@cancel = GuiButton(bg, recti());
cancel.text = locale::CANCEL;
cancel.tabIndex = 101;
@cancel.callback = this;
cancel.color = colors::Red;
alignAcceptButtons(accept, cancel);
valueBox.text = value;
previewBox.text = value;
valueBox.scroll = 0;
height = 500;
update();
bg.updateAbsolutePosition();
}
void update() {
previewBox.text = valueBox.text;
}
void confirm() {
if(changed) {
if(identBox.text.length != 0) {
string fname = field.filename;
if(fname.length == 0)
fname = getLocaleFile(field);
if(origValue != valueBox.text)
changeLocale(identBox.text, valueBox.text, fname);
}
}
localeIdent = identBox.text;
if(localeIdent.length == 0) {
field.value = valueBox.text;
}
else {
if(localeIdent[0] != '#')
localeIdent = "#"+localeIdent;
field.value = localeIdent+suffix;
}
field.emitConfirmed();
}
void focus() {
valueBox.focus();
}
bool onGuiEvent(const GuiEvent& event) {
if(event.type == GUI_Clicked && event.caller is accept && !Closed) {
confirm();
close();
return true;
}
if(event.type == GUI_Clicked && event.caller is cancel && !Closed) {
close();
return true;
}
if(event.type == GUI_Changed && (event.caller is valueBox || event.caller is identBox)) {
previewBox.text = valueBox.text;
previewPanel.updateAbsolutePosition();
changed = true;
return true;
}
if(event.type == GUI_Clicked) {
if(event.caller is identLoad) {
string v = getFromLocale(identBox.text);
valueBox.text = v;
previewBox.text = v;
previewPanel.updateAbsolutePosition();
changed = true;
return true;
}
}
return Dialog::onGuiEvent(event);
}
};
void openLocaleEditor(LocaleField@ field) {
LocaleEditor ed(field);
addDialog(ed);
ed.focus();
}