mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-16 14:16:09 -06:00
724 lines
17 KiB
C++
724 lines
17 KiB
C++
#include "ide.h"
|
|
|
|
struct FileLine : Moveable<FileLine> {
|
|
String file;
|
|
int line;
|
|
};
|
|
|
|
struct LngEntry : Moveable<LngEntry, DeepCopyOption<LngEntry> > {
|
|
bool added;
|
|
VectorMap<int, String> text;
|
|
Vector<FileLine> fileline;
|
|
|
|
LngEntry(const LngEntry& e, int) { added = e.added; text <<= e.text; fileline <<= e.fileline; }
|
|
LngEntry() {}
|
|
|
|
void AddFileLine(CParser& p) {
|
|
FileLine& fl = fileline.Add();
|
|
fl.file = p.GetFileName();
|
|
fl.line = p.GetLine();
|
|
}
|
|
};
|
|
|
|
struct TFile : Moveable<TFile> {
|
|
bool dirty;
|
|
bool java;
|
|
String package, file;
|
|
VectorMap<String, LngEntry> map;
|
|
Vector<int> ls;
|
|
|
|
void MakeLS() {
|
|
Index<int> lngset;
|
|
lngset.Add(LNG_enUS);
|
|
for(int i = 0; i < map.GetCount(); i++)
|
|
for(int j = 0; j < map[i].text.GetCount(); j++)
|
|
lngset.FindAdd(map[i].text.GetKey(j));
|
|
ls = lngset.PickKeys();
|
|
Sort(ls);
|
|
}
|
|
|
|
rval_default(TFile);
|
|
TFile() { dirty = false; }
|
|
};
|
|
|
|
void t_error(CParser& p)
|
|
{
|
|
PutConsole(p.GetFileName() + Format("(%d): t_/tt_ works only with plain text literals", p.GetLine()));
|
|
}
|
|
|
|
void LngParseCFile(const String& fn, VectorMap<String, LngEntry>& lng)
|
|
{
|
|
String data = LoadFile(fn);
|
|
CParser p(data, fn);
|
|
try {
|
|
while(!p.IsEof()) {
|
|
if((p.Id("t_") || p.Id("tt_")) && p.Char('('))
|
|
if(p.IsString()) {
|
|
String tid = p.ReadString();
|
|
LngEntry& le = lng.GetAdd(tid);
|
|
le.text.GetAdd(LNG_enUS) = GetENUS(tid);
|
|
le.AddFileLine(p);
|
|
le.added = true;
|
|
if(!p.Char(')'))
|
|
t_error(p);
|
|
}
|
|
else
|
|
t_error(p);
|
|
else
|
|
p.SkipTerm();
|
|
}
|
|
}
|
|
catch(CParser::Error e) {
|
|
PutConsole(e);
|
|
ShowConsole();
|
|
}
|
|
}
|
|
|
|
const Index<int>& LngIndex()
|
|
{
|
|
static Index<int> l;
|
|
if(l.GetCount() == 0) {
|
|
const int *x = GetAllLanguages();
|
|
while(*x)
|
|
l.Add(*x++);
|
|
}
|
|
return l;
|
|
}
|
|
|
|
bool LngParseTFile(const String& fn, VectorMap<String, LngEntry>& lng)
|
|
{
|
|
String data = LoadFile(fn);
|
|
CParser p(data, fn);
|
|
try {
|
|
if(p.Char('#'))
|
|
while(!p.IsEof()) {
|
|
if(p.IsChar2('T', '_'))
|
|
break;
|
|
else
|
|
p.SkipTerm();
|
|
}
|
|
String id;
|
|
while(!p.IsEof()) {
|
|
if(p.Id("T_")) {
|
|
p.PassChar('(');
|
|
id = Null;
|
|
do
|
|
id.Cat(p.ReadString());
|
|
while(p.Char('+'));
|
|
p.PassChar(')');
|
|
lng.GetAdd(id).added = false;
|
|
}
|
|
else {
|
|
if(IsNull(id))
|
|
p.ThrowError("missing T_");
|
|
String lngs = p.ReadId();
|
|
p.PassChar('(');
|
|
if(lngs.GetLength() == 4) {
|
|
int lang = LNG_(ToUpper(lngs[0]), ToUpper(lngs[1]), ToUpper(lngs[2]), ToUpper(lngs[3]));
|
|
if(LngIndex().Find(lang) >= 0) {
|
|
String lt;
|
|
do
|
|
lt.Cat(p.ReadString());
|
|
while(p.Char('+'));
|
|
lng.GetAdd(id).text.GetAdd(lang) = lt;
|
|
p.PassChar(')');
|
|
continue;
|
|
}
|
|
}
|
|
p.ThrowError("invalid language");
|
|
}
|
|
}
|
|
}
|
|
catch(CParser::Error e) {
|
|
PutConsole(e);
|
|
ShowConsole();
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
String CreateTFile(const VectorMap<String, LngEntry>& map, const Vector<int>& lngset, bool rep, bool obsolete, bool java)
|
|
{
|
|
const char *linepfx = (java ? " + " : " ");
|
|
int ascflags = (java ? 0 : ASCSTRING_OCTALHI) | ASCSTRING_SMART;
|
|
|
|
String out;
|
|
String cfile;
|
|
out << "#ifdef _MSC_VER\r\n#pragma setlocale(\"C\")\r\n#endif";
|
|
|
|
for(int i = 0; i < map.GetCount(); i++) {
|
|
if(i) out << "\r\n";
|
|
const LngEntry& e = map[i];
|
|
String nc;
|
|
if(e.fileline.GetCount())
|
|
nc = e.fileline[0].file;
|
|
if(nc != cfile) {
|
|
cfile = nc;
|
|
if(!IsNull(cfile) && !rep)
|
|
out << "\r\n// " << GetFileName(cfile) << "\r\n\r\n";
|
|
if(IsNull(cfile) && obsolete)
|
|
out << "\r\n// Obsolete\r\n\r\n";
|
|
}
|
|
if(!IsNull(cfile) || rep || obsolete) {
|
|
String id = map.GetKey(i);
|
|
out << "T_(" << AsCString(id, 70, linepfx, ascflags) << ")\r\n";
|
|
for(int j = 0; j < lngset.GetCount(); j++) {
|
|
int lang = lngset[j];
|
|
if(rep || lang != LNG_enUS) {
|
|
int q = e.text.Find(lang);
|
|
if(!rep || q >= 0 && !IsNull(e.text[q])) {
|
|
int c = (lang >> 15) & 31;
|
|
if(c) {
|
|
out.Cat(c + 'a' - 1);
|
|
c = (lang >> 10) & 31;
|
|
if(c) {
|
|
out.Cat(c + 'a' - 1);
|
|
c = (lang >> 5) & 31;
|
|
if(c) {
|
|
out.Cat(c + 'A' - 1);
|
|
c = lang & 31;
|
|
if(c) out.Cat(c + 'A' - 1);
|
|
}
|
|
}
|
|
}
|
|
out << '(' << AsCString(q >= 0 ? e.text[q] : String(), 70,
|
|
linepfx, ascflags) << ")\r\n";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return out;
|
|
}
|
|
|
|
struct LangDlg : WithLangLayout<TopWindow> {
|
|
void Serialize(Stream& s);
|
|
|
|
Vector<TFile>& tfile;
|
|
|
|
void AddLang();
|
|
void RemoveLang();
|
|
|
|
void AddLangAll();
|
|
void RemoveLangAll();
|
|
|
|
void EnterFile();
|
|
void EnterText();
|
|
void ToggleWork();
|
|
|
|
void LangMenu(Bar& bar);
|
|
|
|
bool ShouldWrite(int i) { return file.Get(i, 1); }
|
|
|
|
typedef LangDlg CLASSNAME;
|
|
|
|
LangDlg(Vector<TFile>& map);
|
|
};
|
|
|
|
void LangDlg::Serialize(Stream& s)
|
|
{
|
|
SerializePlacement(s);
|
|
String f = file.GetKey();
|
|
int l = lang.GetKey();
|
|
String t = text.GetKey();
|
|
s % f % l % t;
|
|
file.FindSetCursor(f);
|
|
lang.FindSetCursor(l);
|
|
text.FindSetCursor(t);
|
|
}
|
|
|
|
void LangDlg::AddLang()
|
|
{
|
|
if(!file.IsCursor())
|
|
return;
|
|
WithAddLangLayout<TopWindow> dlg;
|
|
CtrlLayoutOKCancel(dlg, "Add language");
|
|
dlg.lang <<= dlg.Breaker(999);
|
|
TFile& tf = tfile[file.GetCursor()];
|
|
Vector<int>& ls = tf.ls;
|
|
for(;;) {
|
|
int l = ~dlg.lang;
|
|
dlg.ok.Enable((l & 31) && FindIndex(ls, l) < 0);
|
|
switch(dlg.Run()) {
|
|
case IDOK:
|
|
l = ~dlg.lang;
|
|
if(FindIndex(ls, l) < 0) {
|
|
ls.Add(l);
|
|
tf.dirty = true;
|
|
Sort(ls);
|
|
EnterFile();
|
|
lang.FindSetCursor(l);
|
|
return;
|
|
}
|
|
break;
|
|
case IDCANCEL:
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void LangDlg::AddLangAll()
|
|
{
|
|
WithAddLangLayout<TopWindow> dlg;
|
|
CtrlLayoutOKCancel(dlg, "Add to all");
|
|
if(dlg.Run() != IDOK)
|
|
return;
|
|
int l = ~dlg.lang;
|
|
for(int i = 0; i < tfile.GetCount(); i++) {
|
|
TFile& tf = tfile[i];
|
|
Vector<int>& ls = tf.ls;
|
|
if(FindIndex(ls, l) < 0) {
|
|
ls.Add(l);
|
|
tf.dirty = true;
|
|
Sort(ls);
|
|
}
|
|
}
|
|
EnterFile();
|
|
lang.FindSetCursor(l);
|
|
}
|
|
|
|
void LangDlg::RemoveLang()
|
|
{
|
|
if(file.IsCursor() && lang.IsCursor() && (int)lang.GetKey() != LNG_enUS
|
|
&& PromptOKCancel("Remove selected language version?")) {
|
|
TFile& tf = tfile[file.GetCursor()];
|
|
tf.ls.Remove(lang.GetCursor());
|
|
tf.dirty = true;
|
|
EnterFile();
|
|
}
|
|
}
|
|
|
|
void LangDlg::RemoveLangAll()
|
|
{
|
|
WithAddLangLayout<TopWindow> dlg;
|
|
CtrlLayoutOKCancel(dlg, "Remove from all");
|
|
if(file.IsCursor() && lang.IsCursor())
|
|
dlg.lang <<= tfile[file.GetCursor()].ls[lang.GetCursor()];
|
|
if(dlg.Run() != IDOK)
|
|
return;
|
|
int l = ~dlg.lang;
|
|
for(int i = 0; i < tfile.GetCount(); i++) {
|
|
TFile& tf = tfile[i];
|
|
Vector<int>& ls = tf.ls;
|
|
int q = FindIndex(ls, l);
|
|
if(q >= 0) {
|
|
ls.Remove(q);
|
|
tf.dirty = true;
|
|
Sort(ls);
|
|
}
|
|
}
|
|
EnterFile();
|
|
lang.FindSetCursor(l);
|
|
}
|
|
|
|
void LangDlg::LangMenu(Bar& bar)
|
|
{
|
|
bar.Add(file.IsCursor(), "Add..", THISBACK(AddLang));
|
|
bar.Add(lang.IsCursor(), "Remove", THISBACK(RemoveLang));
|
|
bar.Separator();
|
|
bar.Add(file.IsCursor(), "Add to all..", THISBACK(AddLangAll));
|
|
bar.Add(lang.IsCursor(), "Remove from all..", THISBACK(RemoveLangAll));
|
|
}
|
|
|
|
struct FontAndColorDisplay : Display {
|
|
Font font;
|
|
Color color;
|
|
|
|
void Paint(Draw& w, const Rect& r, const Value& q,
|
|
Color ink, Color paper, dword s) const {
|
|
w.DrawRect(r, paper);
|
|
String vt = q;
|
|
const char *txt = GetENUS(vt);
|
|
int x = r.left;
|
|
if(txt != ~vt) {
|
|
String id(~vt, txt - 1);
|
|
w.DrawText(x, r.top, id, font, txt[-1] == '\a' ? LtRed : Magenta);
|
|
x += GetTextSize(id, font).cx + 6;
|
|
}
|
|
w.DrawText(x, r.top, AsCString(txt), font, ink);
|
|
}
|
|
|
|
FontAndColorDisplay(Font f, Color c) : font(f), color(c) {}
|
|
};
|
|
|
|
void LangDlg::EnterFile()
|
|
{
|
|
TFile& tf = tfile[file.GetCursor()];
|
|
Sort(tf.ls);
|
|
|
|
lang.Clear();
|
|
for(int i = 0; i < tf.ls.GetCount(); i++)
|
|
lang.Add(tf.ls[i], LNGAsText(tf.ls[i]));
|
|
lang.GoBegin();
|
|
|
|
static FontAndColorDisplay normal(Arial(11)(), Null);
|
|
static FontAndColorDisplay added(Arial(11)().Bold(), Null);
|
|
static FontAndColorDisplay obsolete(Arial(11)().Italic(), Null);
|
|
|
|
text.Clear();
|
|
for(int i = 0; i < tf.map.GetCount(); i++) {
|
|
text.Add(tf.map.GetKey(i));
|
|
LngEntry& e = tf.map[i];
|
|
Display *d;
|
|
if(e.fileline.GetCount() == 0)
|
|
d = &obsolete;
|
|
else
|
|
if(e.added)
|
|
d = &added;
|
|
else
|
|
d = &normal;
|
|
text.SetDisplay(text.GetCount() - 1, 0, *d);
|
|
}
|
|
text.GoBegin();
|
|
}
|
|
|
|
void LangDlg::EnterText()
|
|
{
|
|
source.Clear();
|
|
VectorMap<String, LngEntry>& map = tfile[file.GetCursor()].map;
|
|
int q = text.GetCursor();
|
|
if(q < 0 || q >= map.GetCount())
|
|
return;
|
|
LngEntry& e = map[q];
|
|
for(int i = 0; i < e.fileline.GetCount(); i++) {
|
|
FileLine& f = e.fileline[i];
|
|
source.Add(f.file, f.line, GetFileName(f.file) + " (" + AsString(f.line) + ")");
|
|
}
|
|
}
|
|
|
|
void LangDlg::ToggleWork()
|
|
{
|
|
if(file.GetCount()) {
|
|
bool q = !(int)file.Get(0, 1);
|
|
for(int i = 0; i < file.GetCount(); i++)
|
|
file.Set(i, 1, q);
|
|
}
|
|
}
|
|
|
|
LangDlg::LangDlg(Vector<TFile>& tfile)
|
|
: tfile(tfile)
|
|
{
|
|
CtrlLayoutOKCancel(*this, "Translation files");
|
|
file.AddColumn("File");
|
|
HeaderCtrl::Column& m = file.AddColumn().Ctrls<Option>().HeaderTab();
|
|
m.SetImage(IdeImg::work());
|
|
m.WhenAction = THISBACK(ToggleWork);
|
|
file.WhenEnterRow = THISBACK(EnterFile);
|
|
file.ColumnWidths("144 27");
|
|
|
|
lang.AddIndex();
|
|
lang.AddColumn("Versions");
|
|
lang.WhenBar = THISBACK(LangMenu);
|
|
|
|
text.AddColumn("Text");
|
|
text.WhenEnterRow = THISBACK(EnterText);
|
|
|
|
source.AddIndex();
|
|
source.AddIndex();
|
|
source.AddColumn("Source");
|
|
source.WhenLeftDouble = Breaker(IDYES);
|
|
|
|
for(int i = 0; i < tfile.GetCount(); i++)
|
|
file.Add(tfile[i].package + '/' + tfile[i].file, 1);
|
|
file.GoBegin();
|
|
|
|
Icon(IdeImg::Language());
|
|
Sizeable().Zoomable();
|
|
}
|
|
|
|
class ExportTrDlg : public WithExportTrLayout<TopWindow> {
|
|
SelectDirButton of;
|
|
typedef ExportTrDlg CLASSNAME;
|
|
|
|
public:
|
|
ExportTrDlg();
|
|
};
|
|
|
|
ExportTrDlg::ExportTrDlg()
|
|
{
|
|
CtrlLayoutOKCancel(*this, "Export .tr file");
|
|
|
|
DlCharsetD(charset);
|
|
of.Attach(folder);
|
|
|
|
charset <<= CHARSET_UTF8;
|
|
lang <<= LNG_ENGLISH;
|
|
}
|
|
|
|
String ExportTr(const Vector<TFile>& tfile, int& cs)
|
|
{
|
|
ExportTrDlg dlg;
|
|
LoadFromGlobal(dlg, "tr-export");
|
|
int c = dlg.Run();
|
|
StoreToGlobal(dlg, "tr-export");
|
|
if(c != IDOK)
|
|
return Null;
|
|
int lng = ~dlg.lang;
|
|
cs = ~dlg.charset;
|
|
String fn = AppendFileName(~dlg.folder, LNGAsText(lng) + "." + CharsetName(cs) + ".tr");
|
|
FileOut out(fn);
|
|
if(!out) {
|
|
Exclamation("Unable to open the output file:&[* \1" + fn);
|
|
return Null;
|
|
}
|
|
out << "LANGUAGE " << AsCString(LNGAsText(SetLNGCharset(lng, cs))) << ";\r\n";
|
|
for(int i = 0; i < tfile.GetCount(); i++) {
|
|
const TFile& m = tfile[i];
|
|
out << "// " << m.package << "/" << m.file << "\r\n";
|
|
for(int j = 0; j < m.map.GetCount(); j++)
|
|
out << AsCString(m.map.GetKey(j), 70) << ",\r\n"
|
|
<< "\t" << AsCString(ToCharset(cs, m.map[j].text.Get(lng, ""), CHARSET_UTF8),
|
|
60, "\t", ASCSTRING_SMART)
|
|
<< ";\r\n\r\n";
|
|
}
|
|
return fn;
|
|
}
|
|
|
|
void Ide::SyncT(int kind)
|
|
{
|
|
console.Clear();
|
|
String filepath = GetActiveFilePath();
|
|
SaveFile();
|
|
|
|
TFile repository;
|
|
LngParseTFile(ConfigFile("repository.t"), repository.map);
|
|
|
|
if(kind == 1) {
|
|
FileSel fs;
|
|
fs.ActiveDir(AnySourceFs().GetActiveDir());
|
|
fs.Type("Runtime translation file (*.tr)", "*.tr");
|
|
fs.AllFilesType();
|
|
LoadFromGlobal(fs, "fs-tr");
|
|
bool b = fs.ExecuteOpen("Import translation file");
|
|
StoreToGlobal(fs, "fs-tr");
|
|
if(!b) return;
|
|
String tr = LoadFile(~fs);
|
|
CParser p(tr);
|
|
try {
|
|
while(!p.IsEof()) {
|
|
p.PassId("LANGUAGE");
|
|
int lang = LNGFromText(p.ReadString());
|
|
if(!lang)
|
|
p.ThrowError("Invalid language");
|
|
p.PassChar(';');
|
|
byte cs = GetLNGCharset(lang);
|
|
lang &= LNGC_(255, 255, 255, 255, 0);
|
|
while(p.IsString()) {
|
|
String id = p.ReadString();
|
|
p.PassChar(',');
|
|
repository.map.GetAdd(id).text.GetAdd(lang) = ToCharset(CHARSET_UTF8, p.ReadString(), cs);
|
|
p.PassChar(';');
|
|
}
|
|
}
|
|
}
|
|
catch(CParser::Error& e) {
|
|
PutConsole(e);
|
|
Exclamation("Failed: \1" + e);
|
|
return;
|
|
}
|
|
}
|
|
|
|
Vector<TFile> tfile;
|
|
Vector<int> mainsT;
|
|
|
|
Progress pi;
|
|
const Workspace& wspc = IdeWorkspace();
|
|
pi.SetTotal(wspc.GetCount());
|
|
for(int iPackage = 0; iPackage < wspc.GetCount(); iPackage++) {
|
|
const Package& pk = wspc.GetPackage(iPackage);
|
|
String n = wspc[iPackage];
|
|
pi.SetText("Scanning " + n);
|
|
if(pi.StepCanceled()) return;
|
|
VectorMap<String, LngEntry> pmap;
|
|
for(int iFile = 0; iFile < pk.file.GetCount(); iFile++) {
|
|
String file = SourcePath(n, pk.file[iFile]);
|
|
LngParseCFile(SourcePath(GetActivePackage(), file), pmap);
|
|
}
|
|
bool localT = false;
|
|
for(int iFile = 0; iFile < pk.file.GetCount(); iFile++) {
|
|
String file = SourcePath(n, pk.file[iFile]);
|
|
String ext = GetFileExt(file);
|
|
if(ext == ".t" || ext == ".jt") {
|
|
VectorMap<String, LngEntry> tmap(pmap, 0);
|
|
if(LngParseTFile(file, tmap)) {
|
|
TFile& tf = tfile.Add();
|
|
tf.java = (ext == ".jt");
|
|
tf.package = n;
|
|
tf.file = pk.file[iFile];
|
|
tf.map = pick(tmap);
|
|
tf.MakeLS();
|
|
// mark that we've found a local translation file
|
|
localT = true;
|
|
|
|
// store index of main package translation(s) file(s)
|
|
if(iPackage == 0)
|
|
mainsT.Add(tfile.GetCount() - 1);
|
|
}
|
|
}
|
|
}
|
|
// if no local translation file(s), we append translation to
|
|
// main package one(s), if any
|
|
if(!localT && iPackage > 0)
|
|
{
|
|
for(int i = 0; i < mainsT.GetCount(); i++)
|
|
{
|
|
VectorMap<String, LngEntry> &map = tfile[mainsT[i]].map;
|
|
for(int iEntry = 0; iEntry < pmap.GetCount(); iEntry++)
|
|
{
|
|
int idx = map.Find(pmap.GetKey(iEntry));
|
|
if(idx < 0)
|
|
{
|
|
map.Add(pmap.GetKey(iEntry), pmap[iEntry]);
|
|
idx = map.GetCount() - 1;
|
|
}
|
|
LngEntry &entry = map[idx];
|
|
if(!entry.fileline.GetCount())
|
|
{
|
|
LngEntry &pEntry = pmap[iEntry];
|
|
for(int iLc = 0; iLc < pEntry.fileline.GetCount(); iLc++)
|
|
{
|
|
FileLine &fl = entry.fileline.Add();
|
|
String file = GetFileName(pEntry.fileline[iLc].file);
|
|
file = "PACKAGE '" + GetFileName(n) + "' FILE '" + file + "'";
|
|
fl.file = file;
|
|
fl.line = pEntry.fileline[iLc].line;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(kind == 2) {
|
|
for(int i = 0; i < tfile.GetCount(); i++) {
|
|
TFile& tf = tfile[i];
|
|
for(int ii = 0; ii < tf.map.GetCount(); ii++) {
|
|
LngEntry& tle = tf.map[ii];
|
|
LngEntry& rle = repository.map.GetAdd(tf.map.GetKey(ii));
|
|
for(int l = 0; l < tle.text.GetCount(); l++)
|
|
if(!IsNull(tle.text[l]))
|
|
rle.text.GetAdd(tle.text.GetKey(l)) = tle.text[l];
|
|
}
|
|
}
|
|
|
|
int cs;
|
|
String fn = ExportTr(tfile, cs);
|
|
if(!IsNull(fn)) {
|
|
EditFile(fn);
|
|
int c = filelist.GetCursor();
|
|
FlushFile();
|
|
ActiveFile().charset = (byte)cs;
|
|
SavePackage();
|
|
PackageCursor();
|
|
if(c >= 0)
|
|
filelist.SetCursor(c);
|
|
editor.ClearUndo();
|
|
}
|
|
return;
|
|
}
|
|
|
|
LangDlg dlg(tfile);
|
|
LoadFromWorkspace(dlg, "Tdlg");
|
|
switch(dlg.Execute()) {
|
|
case IDCANCEL:
|
|
return;
|
|
case IDYES:
|
|
if(dlg.source.IsCursor()) {
|
|
EditFile(dlg.source.Get(0));
|
|
editor.SetCursor(editor.GetPos(editor.GetLineNo((int)dlg.source.Get(1) - 1)));
|
|
editor.CenterCursor();
|
|
editor.SetFocus();
|
|
StoreToWorkspace(dlg, "Tdlg");
|
|
return;
|
|
}
|
|
}
|
|
StoreToWorkspace(dlg, "Tdlg");
|
|
|
|
FlushFile();
|
|
|
|
for(int i = 0; i < tfile.GetCount(); i++) {
|
|
TFile& tf = tfile[i];
|
|
for(int ii = 0; ii < tf.map.GetCount(); ii++) {
|
|
int q = repository.map.Find(tf.map.GetKey(ii));
|
|
if(q >= 0) {
|
|
LngEntry& tle = tf.map[ii];
|
|
LngEntry& rle = repository.map[q];
|
|
for(int l = 0; l < tf.ls.GetCount(); l++) {
|
|
q = rle.text.Find(tf.ls[l]);
|
|
if(q >= 0)
|
|
tle.text.GetAdd(tf.ls[l]) = rle.text[q];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pi.SetTotal(tfile.GetCount());
|
|
for(int i = 0; i < tfile.GetCount(); i++) {
|
|
TFile& tf = tfile[i];
|
|
String td = CreateTFile(tf.map, tf.ls, false, !dlg.remove, tf.java);
|
|
String fp = SourcePath(tf.package, tf.file);
|
|
pi.SetText("Storing " + tf.package + '/' + tf.file);
|
|
if(pi.StepCanceled())
|
|
break;
|
|
if(dlg.ShouldWrite(i) && LoadFile(fp) != td)
|
|
::SaveFile(fp, td);
|
|
}
|
|
|
|
repository.MakeLS();
|
|
::SaveFile(ConfigFile("repository.t"), CreateTFile(repository.map, repository.ls, true, false, false));
|
|
FileCursor();
|
|
}
|
|
|
|
void Ide::ConvertST()
|
|
{
|
|
if(!PromptYesNo("Convert project to t_ translations?"))
|
|
return;
|
|
|
|
FlushFile();
|
|
|
|
TFile repository;
|
|
LngParseTFile(ConfigFile("repository.t"), repository.map);
|
|
|
|
Progress pi;
|
|
const Workspace& wspc = IdeWorkspace();
|
|
pi.SetTotal(wspc.GetCount());
|
|
for(int i = 0; i < wspc.GetCount(); i++) {
|
|
const Package& pk = wspc.GetPackage(i);
|
|
String n = wspc[i];
|
|
pi.SetText("Converting " + n);
|
|
if(pi.StepCanceled()) return;
|
|
VectorMap<String, LngEntry> pmap;
|
|
for(int i = 0; i < pk.file.GetCount(); i++) {
|
|
String file = SourcePath(n, pk.file[i]);
|
|
String data = LoadFile(file);
|
|
CParser p(data);
|
|
String r;
|
|
const char *b = data;
|
|
while(!p.IsEof()) {
|
|
p.Spaces();
|
|
const char *w = p.GetPtr();
|
|
if(p.Id("s_") && p.Char('(') && p.IsId()) {
|
|
String id = p.ReadId();
|
|
int q = repository.map.Find(id);
|
|
if(q >= 0) {
|
|
LngEntry& e = repository.map[q];
|
|
q = e.text.Find(LNG_enUS);
|
|
if(q >= 0) {
|
|
r.Cat(b, w);
|
|
r.Cat("t_(");
|
|
r.Cat(AsCString(e.text[q]));
|
|
b = p.GetPtr();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
p.SkipTerm();
|
|
}
|
|
r.Cat(b);
|
|
if(r != data)
|
|
::SaveFile(file, r);
|
|
}
|
|
}
|
|
|
|
FileCursor();
|
|
}
|