ultimatepp/uppsrc2/rw/DesignerFile.cpp
cxl 9516965bb8 Added uppsrc2 nest
git-svn-id: svn://ultimatepp.org/upp/trunk@1175 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2009-05-14 06:44:11 +00:00

421 lines
9.9 KiB
C++

#include "Designer.h"
static Point sReadAB(CParser& p) {
Point pt;
p.PassChar('(');
pt.x = p.ReadInt();
p.PassChar(',');
pt.y = p.ReadInt();
p.PassChar(')');
return pt;
}
static String ReadVar(CParser& p) {
String var;
for(;;) {
if(p.IsId())
var << p.ReadId();
else
if(p.IsInt())
var << p.ReadInt();
else
if(p.Char('.'))
var << '.';
else
if(p.Char('['))
var << '[';
else
if(p.Char(']'))
var << ']';
else
return var;
}
}
void LayoutDesigner::LoadCtrl(CParser& p, ItemInfo& ii, int li) {
if(p.Id("ITEM")) {
p.PassChar('(');
if(p.IsId()) ii.classname = p.ReadIdt();
p.PassChar(',');
}
else
if(p.Id("UNTYPED"))
p.PassChar('(');
else
p.ThrowError("Bad item.");
if(p.IsId()) ii.variable = ReadVar(p);
if(strncmp(ii.variable, "dv___", 5) == 0)
ii.variable.Clear();
p.PassChar(',');
LogPos pos;
do {
if(p.Id("LeftPosZ") || p.Id("LeftPos")) {
Point pt = sReadAB(p);
pos.x = PosLeft(pt.x, pt.y);
}
else
if(p.Id("RightPosZ") || p.Id("RightPos")) {
Point pt = sReadAB(p);
pos.x = PosRight(pt.x, pt.y);
}
else
if(p.Id("HSizePosZ") || p.Id("HSizePos")) {
Point pt = sReadAB(p);
pos.x = PosSize(pt.x, pt.y);
}
else
if(p.Id("HCenterPosZ") || p.Id("HCenterPos")) {
Point pt = sReadAB(p);
pos.x = PosCenter(pt.x, pt.y);
}
else
if(p.Id("TopPosZ") || p.Id("TopPos")) {
Point pt = sReadAB(p);
pos.y = PosLeft(pt.x, pt.y);
}
else
if(p.Id("BottomPosZ") || p.Id("BottomPos")) {
Point pt = sReadAB(p);
pos.y = PosRight(pt.x, pt.y);
}
else
if(p.Id("VSizePosZ") || p.Id("VSizePos")) {
Point pt = sReadAB(p);
pos.y = PosSize(pt.x, pt.y);
}
else
if(p.Id("VCenterPosZ") || p.Id("VCenterPos")) {
Point pt = sReadAB(p);
pos.y = PosCenter(pt.x, pt.y);
}
else
if(p.Id("SetLabel")) {
p.PassChar('(');
if(p.IsString())
ii.label.At(li) = p.ReadString();
else
ii.labelid = p.ReadId();
p.PassChar(')');
}
else
if(p.Id("HelpC") || p.Id("Help") || p.Id("Description")) {
p.PassChar('(');
if(p.IsString())
ii.help.At(li) = p.ReadString();
else
ii.helpid = p.ReadId();
p.PassChar(')');
}
else
if(p.Id("Hide")) {
p.PassChar('(');
p.PassChar(')');
}
else
p.ThrowError("Invalid item modifier.");
}
while(p.Char('.'));
p.PassChar(')');
ii.pos = pos;
}
void LayoutDesigner::LoadLayoutFile(const char *_filename) {
SetLayout(-1);
layout.Clear();
langlist.Clear();
try {
filename = _filename;
String s = LoadFile(filename);
CParser p(s);
if(p.Id("#ifdef"))
p.Id("LAYOUTFILE");
while(p.Id("LAYOUT")) {
p.PassChar('(');
String name = p.ReadId();
p.PassChar(',');
int cx = p.ReadInt();
p.PassChar(',');
int cy = p.ReadInt();
p.PassChar(')');
const char *a = p.GetPtr();
const char *b = a;
Form& l = layout.Add();
l.name = name;
l.size = Size(cx, cy);
while(!p.IsEof() && !p.Id("END_LAYOUT"))
LoadCtrl(p, l.item.Add());
while(*a == '\n' || *a == '\r')
a++;
}
p.Id("#endif");
while(p.Id("#if")) {
p.PassId("LANGUAGE");
p.PassChar2('=', '=');
String langid = p.ReadId();
CParser::Pos idpos = p.GetPos();
if(*idpos.ptr == '(')
{
const char *b = idpos.ptr;
while(*idpos.ptr && *idpos.ptr++ != ')')
;
langid.Cat(b, idpos.ptr - b);
p.SetPos(idpos);
}
langlist.Add(langlist.GetCount(), langid);
VectorMap<String, String> map;
while(p.Id("txt")) {
p.PassChar('(');
String& txt = map.Add("txt" + p.ReadId());
p.PassChar(',');
txt = p.ReadString();
p.PassChar(')');
}
p.PassId("#endif");
for(int i = 0; i < layout.GetCount(); i++) {
Form& l = layout[i];
for(int i = 0; i < l.item.GetCount(); i++) {
ItemInfo& ii = l.item[i];
ii.label.Add(map.Get(ii.labelid, String()));
ii.help.Add(map.Get(ii.helpid, String()));
}
}
}
}
catch(CParser::Error& e) {
Exclamation(e);
filename.Clear();
}
MakeCaption();
SetupLayoutList();
SetLayout(layout.GetCount() ? 0 : -1, 0);
}
String SaveText(String mod, const Vector<String>& txt, bool lang, const String& name, int ii) {
mod = '.' + mod + '(';
if(lang) {
for(int i = 0; i < txt.GetCount(); i++)
if(!txt[i].IsEmpty())
return mod + name + Format("_%d", ii) + ')';
return String();
}
return txt.GetCount() && !txt[0].IsEmpty() ? mod + AsCString(txt[0]) + ')' : String();
}
String LayoutDesigner::SaveCtrl(const ItemInfo& ii, int i, const String& name, bool lang) const {
String out;
if(ii.classname.IsEmpty())
out << "\tUNTYPED(";
else
out << "\tITEM(" << ii.classname << ", ";
out << (ii.variable.IsEmpty() ? Format("dv___%d", i) : ii.variable) << ", ";
LogPos p = ii.pos;
const char *zfix = (qlib2_output ? "" : "Z");
switch(p.x.GetAlign()) {
case Ctrl::LEFT: out << Format("LeftPos%s(%d, %d).", zfix, p.x.GetA(), p.x.GetB()); break;
case Ctrl::RIGHT: out << Format("RightPos%s(%d, %d).", zfix, p.x.GetA(), p.x.GetB()); break;
case Ctrl::SIZE: out << Format("HSizePos%s(%d, %d).", zfix, p.x.GetA(), p.x.GetB()); break;
case Ctrl::CENTER: out << Format("HCenterPos%s(%d, %d).", zfix, p.x.GetB(), p.x.GetA()); break;
}
switch(p.y.GetAlign()) {
case Ctrl::TOP: out << Format("TopPos%s(%d, %d)", zfix, p.y.GetA(), p.y.GetB()); break;
case Ctrl::BOTTOM: out << Format("BottomPos%s(%d, %d)", zfix, p.y.GetA(), p.y.GetB()); break;
case Ctrl::SIZE: out << Format("VSizePos%s(%d, %d)", zfix, p.y.GetA(), p.y.GetB()); break;
case Ctrl::CENTER: out << Format("VCenterPos%s(%d, %d)", zfix, p.y.GetB(), p.y.GetA()); break;
}
out << SaveText("SetLabel", ii.label, lang, "txt" + name, i);
out << SaveText(qlib2_output ? "HelpC" : "Description", ii.help, lang, "txt" + name + "_HLP", i);
if(IsLayoutRef(ii.classname) && ii.variable.IsEmpty())
out << ".Hide()";
out << ")\n";
return out;
}
String txtSave(int li, const Vector<String>& txt, int ii, String name) {
for(int i = 0; i < txt.GetCount(); i++)
if(!txt[i].IsEmpty()) {
String s;
if(li < txt.GetCount())
s = txt[li];
return "txt(" + name + Format("_%d", ii) + ", " + AsCString(s) + ")\n";
}
return String();
}
String LayoutDesigner::GetLayoutFile() const {
int i;
Vector<int> layindex;
layindex.SetCount(layout.GetCount());
for(i = 0; i < layout.GetCount(); i++)
layindex[i] = i;
int maxswaps = layout.GetCount() * layout.GetCount();
for(i = 0; maxswaps > 0 && i < layindex.GetCount(); i++)
{
int lx = layindex[i];
const Form& l = layout[lx];
int maxref = -1;
String dummy;
for(int c = 0; c < l.item.GetCount(); c++)
maxref = max(maxref, FindIndex(layindex, ParseLayoutRef(l.item[c].classname, dummy)));
if(maxref > i)
{
layindex.Remove(i);
layindex.Insert(maxref, lx);
i--;
maxswaps--;
}
}
StringStream out;
out << "#ifdef LAYOUTFILE\n\n";
for(i = 0; i < layindex.GetCount(); i++) {
const Form& l = layout[layindex[i]];
out << "LAYOUT(" << l.name << ", " << l.size.cx << ", " << l.size.cy << ")\n";
for(int c = 0; c < l.item.GetCount(); c++)
out << SaveCtrl(l.item[c], c, l.name, langlist.GetCount());
out << "END_LAYOUT\n\n";
}
out << "#endif\n";
for(int li = 0; li < langlist.GetCount(); li++) {
out << "\n#if LANGUAGE == " << String(langlist.GetValue(li)) << "\n\n";
for(int i = 0; i < layindex.GetCount(); i++) {
const Form& l = layout[layindex[i]];
for(int c = 0; c < l.item.GetCount(); c++) {
out << txtSave(li, l.item[c].label, c, l.name);
out << txtSave(li, l.item[c].help, c, l.name + "_HLP");
}
out << '\n';
}
out << "#endif\n";
}
return out;
}
bool LayoutDesigner::SaveLayoutFile() {
String lf = GetLayoutFile();
if(::LoadFile(filename) != lf && !::SaveFile(filename, lf)) {
Exclamation("Error storing output file " + filename);
return false;
}
return true;
}
const char exts[] =
"Layout files (*.lay)|*.lay|"
"All files (*.*)|*.*|"
;
void LayoutDesigner::MakeCaption() {
String s;
if(layouti >= 0) {
s.Cat(layout[layouti].name);
if(!s.IsEmpty())
s.Cat(" - ");
}
s.Cat(filename.IsEmpty() ? "New layout file" : filename);
frame.Title(s);
}
bool LayoutDesigner::DoSave() {
if(filename.IsEmpty()) {
if(!SaveLayoutFileAs()) return false;
}
else
if(!SaveLayoutFile()) return false;
return true;
}
bool LayoutDesigner::PromptSave() {
return layout.GetCount() == 0
|| (!filename.IsEmpty() && GetLayoutFile() == LoadFile(filename))
|| !PromptYesNo("Save current file ?") || DoSave();
}
void LayoutDesigner::NewFile() {
if(!PromptSave()) return;
SetLayout(-1);
layout.Clear();
filename.Clear();
frame.Refresh();
MakeCaption();
SetupLayoutList();
}
void LayoutDesigner::OpenFile() {
if(!PromptSave()) return;
if(filesel.ExecuteOpen()) {
LoadLayoutFile(~filesel);
LruList.NewEntry(filename);
}
}
bool LayoutDesigner::SaveLayoutFileAs() {
filesel = filename;
if(!filesel.ExecuteSaveAs(NULL)) return false;
filename = filesel;
bool r = SaveLayoutFile();
if(r) LruList.NewEntry(filename);
MakeCaption();
return r;
}
void LayoutDesigner::SaveFileAs() {
SaveLayoutFileAs();
}
void LayoutDesigner::SaveFile() {
DoSave();
}
void LayoutDesigner::CloseFile() {
if(CloseLayoutFile())
{
#ifdef flagIDERW
SetTimeCallback(0, THISBACK(CloseDesigner), 555);
#endif
}
}
bool LayoutDesigner::CloseLayoutFile() {
if(layout.GetCount() && (filename.IsEmpty() || LoadFile(filename) != GetLayoutFile()))
switch(PromptYesNoCancel("Save current file ?")) {
case 1:
if(!DoSave()) return false;
case 0:
break;
default:
return false;
}
frame.Close();
return true;
}
void LayoutDesigner::LruOpen(const String& s) {
if(!PromptSave()) return;
LoadLayoutFile(s);
}
void LayoutDesigner::Serialize(Stream& s) {
int version = 1;
s.Magic();
s / version;
s % filesel;
LruList.Serialize(s);
splital.Serialize(s);
if(version == 0) {
Splitter d;
d.Serialize(s);
}
itab.SerializeHeader(s);
if(version >= 1)
frame.SerializePlacement(s);
else {
Rect r = frame.GetRect();
s % r;
frame.SetRect(r);
}
s % grid.x % grid.y;
s % ignoremin;
s % matrix.x % matrix.y % matrix.hspace % matrix.vspace;
s % usegrid;
s.Magic();
}