1 #include "Form.hpp"
2 #include "IniConfig.hpp"
3
4 static int tempFormsCount = 0;
5
Form()6 Form:: Form() : _Current(-1) {}
~Form()7 Form::~Form() { Clear(); }
8
Load(const String & file)9 bool Form::Load(const String& file)
10 {
11 Clear();
12
13 if (!FileExists(file))
14 return false;
15
16 if (GetFileExt(file) == ".fz")
17 {
18 String s = ZDecompress(LoadFile(file));
19 if (!LoadFromXML(*this, s))
20 return false;
21 _File = file;
22 return true;
23 }
24
25 if (!LoadFromXMLFile(*this, file))
26 return false;
27 _File = file;
28 return true;
29 }
30
Layout(const String & layout,Font font)31 bool Form::Layout(const String& layout, Font font)
32 {
33 _Current = -1;
34 for (int i = 0; i < _Layouts.GetCount(); ++i)
35 if (_Layouts[i].Get("Form.Name") == layout)
36 {
37 _Current = i;
38 return Generate(font);
39 }
40 return false;
41 }
42
Generate(Font font)43 bool Form::Generate(Font font)
44 {
45 if (!IsLayout())
46 return false;
47
48 Clear(false);
49
50 Size sz = _Layouts[_Current].GetFormSize();
51 SetRect( Rect(Point(0, 0), Size(HorzLayoutZoom(sz.cx), VertLayoutZoom(sz.cy))) );
52
53 Vector<FormObject>* p = &_Layouts[_Current].GetObjects();
54
55 if (_Layouts[_Current].GetBool("Form.MinimizeBox", false)) MinimizeBox();
56 if (_Layouts[_Current].GetBool("Form.MaximizeBox", false)) MaximizeBox();
57
58 #ifdef PLATFORM_WIN32
59 if (_Layouts[_Current].GetBool("Form.ToolWindow", false)) ToolWindow();
60 #endif
61
62 if (_Layouts[_Current].GetBool("Form.Sizeable", false)) Sizeable();
63
64 Title(_Layouts[_Current].Get("Form.Title"));
65
66 for (int i = 0; i < p->GetCount(); ++i)
67 {
68 Font objFont = font;
69 int h = (*p)[i].GetNumber("Font.Height", 0);
70 if (h != 0) objFont.Height( VertLayoutZoom(h) );
71 if (font.GetHeight() == 0) objFont.Height( StdFont().GetHeight() );
72 Ctrl *c = NULL;
73
74 if ((*p)[i].Get("Type") == "Button")
75 {
76 Button *b = &_Ctrls.Create<Button>((*p)[i].Get("Variable"));
77 b->SetFont(objFont);
78 b->SetLabel((*p)[i].Get("Label"));
79 b->Tip((*p)[i].Get("Tip"));
80 *b <<= THISBACK1(OnAction, (*p)[i].Get("Action"));
81 c = b;
82 }
83
84 if ((*p)[i].Get("Type") == "EditField")
85 {
86 EditField *e = &_Ctrls.Create<EditField>((*p)[i].Get("Variable"));
87 e->SetFont(objFont);
88 if ((*p)[i].Get("Style") == "Password")
89 e->Password();
90 e->Tip((*p)[i].Get("Tip"));
91 if ((*p)[i].Get("TextAlign") == "Right")
92 e->AlignRight();
93
94 c = e;
95 }
96
97 if ((*p)[i].Get("Type") == "Label")
98 {
99 Label *e = &_Ctrls.Create<Label>((*p)[i].Get("Variable"));
100 e->SetFont(objFont);
101 Color fontColor = Black();
102 LoadFromString(fontColor, Decode64((*p)[i].Get("Font.Color",
103 StoreAsString(fontColor))));
104 e->SetInk(fontColor);
105 String align = (*p)[i].Get("Text.Align");
106 if (align == "Center") e->SetAlign(ALIGN_CENTER);
107 if (align == "Right") e->SetAlign(ALIGN_RIGHT);
108 if (align == "Left") e->SetAlign(ALIGN_LEFT);
109 e->SetLabel((*p)[i].Get("Label"));
110 c = e;
111 }
112
113 if ((*p)[i].Get("Type") == "DropDate")
114 {
115 DropDate *e = &_Ctrls.Create<DropDate>((*p)[i].Get("Variable"));
116 e->SetFont(objFont);
117 c = e;
118 }
119
120 if ((*p)[i].Get("Type") == "ProgressBar")
121 {
122 ProgressIndicator *e = &_Ctrls.Create<ProgressIndicator>((*p)[i].Get("Variable"));
123 e->Set(
124 (*p)[i].GetNumber("ProgressBar.Initial", 0),
125 (*p)[i].GetNumber("ProgressBar.Total", 100));
126 c = e;
127 }
128
129 if ((*p)[i].Get("Type") == "EditInt")
130 {
131 EditInt *e = &_Ctrls.Create<EditInt>((*p)[i].Get("Variable"));
132 e->SetFont(objFont);
133 e->Min((*p)[i].GetNumber("Min", INT_MIN, INT_MAX, INT_MIN));
134 e->Max((*p)[i].GetNumber("Max", INT_MIN, INT_MAX, INT_MAX));
135 c = e;
136 }
137
138 if ((*p)[i].Get("Type") == "GridCtrl")
139 {
140 GridCtrl *e = &_Ctrls.Create<GridCtrl>((*p)[i].Get("Variable"));
141 e->Chameleon();
142 c = e;
143
144 String src = (*p)[i].Get("Grid.Columns");
145 ReplaceString(src, ";", "\r\n");
146 StringStream s;
147 s.Open(src);
148 IniFile f;
149 f.Load(s);
150
151 Vector<String> names = f.EnumNames("Columns");
152
153 for (int j = 0; j < names.GetCount(); ++j)
154 {
155 int n = ScanInt(names[j]);
156
157 if (AsString(n) != names[j])
158 continue;
159
160 Vector<String> values = f.GetArray("Columns", names[j]);
161 if (values.GetCount() != 3)
162 continue;
163 if (values[1] == "Left") e->AddColumn(values[0]).HeaderAlignCenterLeft();
164 else if (values[1] == "Right") e->AddColumn(values[0]).HeaderAlignCenterRight();
165 else e->AddColumn(values[0]).HeaderAlignCenter();
166 }
167 }
168
169 if ((*p)[i].Get("Type") == "TabCtrl")
170 {
171 TabCtrl *e = &_Ctrls.Create<TabCtrl>((*p)[i].Get("Variable"));
172 TabCtrl::Style& style = e->StyleDefault().Write();
173 style.font = objFont;
174 style.tabheight = objFont.GetHeight() + VertLayoutZoom(10);
175 e->SetStyle(style);
176
177 String src = (*p)[i].Get("Tab.Content");
178 ReplaceString(src, ";", "\r\n");
179 StringStream s;
180 s.Open(src);
181 IniFile f;
182 f.Load(s);
183
184 Vector<String> names = f.EnumNames("Tabs");
185 VectorMap<int, Vector<String> > cache;
186
187 for (int j = 0; j < names.GetCount(); ++j)
188 {
189 int n = ScanInt(names[j]);
190
191 if (AsString(n) != names[j])
192 continue;
193
194 Vector<String> values = f.GetArray("Tabs", names[j]);
195 if (values.GetCount() != 3)
196 continue;
197
198 if (values[0] == t_("Current form"))
199 values[0] = _File;
200
201 Container *cont = &_Ctrls.Create<Container>("TemporaryContainer"
202 + AsString(tempFormsCount));
203
204 Form *f = &_Ctrls.Create<Form>("TemporaryForm" + AsString(tempFormsCount++));
205
206 if (values[0] != _File)
207 {
208 if (!f->Load(GetFileDirectory(_File) + "\\" + values[0]))
209 continue;
210 }
211 else
212 {
213 int lay = HasLayout(values[1]);
214 if (lay < 0)
215 continue;
216 f->GetLayouts().Add(_Layouts[lay]);
217 }
218
219 if (!f->Layout(values[1], objFont))
220 continue;
221
222 cont->Set(*f, f->GetSize());
223 cont->SizePos();
224 e->Add(*cont, values[2]);
225 }
226
227 if (e->GetCount())
228 {
229 int active = (*p)[i].GetNumber("Tab.Active", -1, -1);
230
231 if (active < 0)
232 active = 0;
233
234 if (active >= e->GetCount())
235 active = e->GetCount() - 1;
236
237 e->Set(active);
238 }
239
240 c = e;
241 }
242
243 if ((*p)[i].Get("Type") == "Form")
244 {
245 Form *f = &_Ctrls.Create<Form>((*p)[i].Get("Variable"));
246 f->SignalHandler = SignalHandler;
247 String path = (*p)[i].Get("Form.Path");
248 (*p)[i].Get("Form.PathType") == "Relative"
249 ? f->Load(::GetFileDirectory(_File) + "\\" + path)
250 : f->Load(path);
251 f->Layout((*p)[i].Get("Form.Layout"), objFont);
252 f->Script = Script;
253 c = f;
254 }
255
256 if (!c) continue;
257
258 switch((*p)[i].GetHAlign())
259 {
260 case Ctrl::LEFT:
261 c->LeftPosZ((*p)[i].GetRect().left, (*p)[i].GetRect().Width());
262 break;
263 case Ctrl::RIGHT:
264 c->RightPosZ(sz.cx - (*p)[i].GetRect().left - (*p)[i].GetRect().Width(), (*p)[i].GetRect().Width());
265 break;
266 case Ctrl::SIZE:
267 c->HSizePosZ((*p)[i].GetRect().left, sz.cx - (*p)[i].GetRect().left - (*p)[i].GetRect().Width());
268 break;
269 case Ctrl::CENTER:
270 c->HCenterPosZ((*p)[i].GetRect().Width());
271 }
272
273 switch((*p)[i].GetVAlign())
274 {
275 case Ctrl::TOP:
276 c->TopPosZ((*p)[i].GetRect().top, (*p)[i].GetRect().Height());
277 break;
278 case Ctrl::BOTTOM:
279 c->BottomPosZ(sz.cy - (*p)[i].GetRect().top - (*p)[i].GetRect().Height(), (*p)[i].GetRect().Height());
280 break;
281 case Ctrl::SIZE:
282 c->VSizePosZ((*p)[i].GetRect().top, sz.cy - (*p)[i].GetRect().top - (*p)[i].GetRect().Height());
283 break;
284 case Ctrl::CENTER:
285 c->VCenterPosZ((*p)[i].GetRect().Height());
286 }
287
288 String frame = (*p)[i].Get("Frame");
289
290 if (frame == "Null frame") c->SetFrame(NullFrame());
291 if (frame == "Field frame") c->SetFrame(FieldFrame());
292 if (frame == "Inset frame") c->SetFrame(InsetFrame());
293 if (frame == "Outset frame") c->SetFrame(OutsetFrame());
294 if (frame == "Thin inset frame") c->SetFrame(ThinInsetFrame());
295 if (frame == "Thin outset frame") c->SetFrame(ThinOutsetFrame());
296 if (frame == "Black frame") c->SetFrame(BlackFrame());
297 if (frame == "Button frame") c->SetFrame(ButtonFrame());
298 if (frame == "Top separator frame") c->SetFrame(TopSeparatorFrame());
299 if (frame == "Left separator frame") c->SetFrame(LeftSeparatorFrame());
300 if (frame == "Right separator frame") c->SetFrame(RightSeparatorFrame());
301 if (frame == "Bottom separator frame") c->SetFrame(BottomSeparatorFrame());
302
303 AddChild(c);
304 }
305
306 return true;
307 }
308
ExecuteForm()309 String Form::ExecuteForm()
310 {
311 if (!IsLayout())
312 return "Error";
313
314 WhenClose = TopWindow::Breaker(0);
315 int result;
316
317 for (;;)
318 {
319 result = TopWindow::Execute();
320
321 if (result == 0)
322 return "Close";
323
324 if (result < 0)
325 return _Rejectors[ abs(result) - 1 ];
326
327 Vector<FormObject>* p = &_Layouts[_Current].GetObjects();
328 bool null = false;
329 for (int i = 0; i < p->GetCount(); ++i)
330 {
331 if ((*p)[i].GetBool("NotNull"))
332 if (IsNull(~_Ctrls[i]))
333 {
334 PromptOK("Необходимо заполнить поле: " + (*p)[i].Get("Variable"));
335 null = true;
336 break;
337 }
338 }
339 if (null)
340 continue;
341
342 break;
343 }
344
345 return _Acceptors[ result - 1 ];
346 }
347
Clear(bool all)348 void Form::Clear(bool all)
349 {
350 if (all) _Layouts.Clear();
351 _Rejectors.Clear();
352 _Acceptors.Clear();
353 _Ctrls.Clear();
354 Script.Clear();
355 }
356
HasLayout(const String & layout)357 int Form::HasLayout(const String& layout)
358 {
359 for (int i = 0; i < _Layouts.GetCount(); ++i)
360 if (_Layouts[i].Get("Form.Name") == layout)
361 return i;
362 return -1;
363 }
364
OnAction(const String & action)365 void Form::OnAction(const String& action)
366 {
367 SignalHandler(Script, "OnAction", action);
368 }
369
Exit(const String & action)370 bool Form::Exit(const String& action)
371 {
372 return SetCallback(action, TopWindow::Rejector(0));
373 }
374
Acceptor(const String & action)375 bool Form::Acceptor(const String& action)
376 {
377 if (SetCallback(action, TopWindow::Acceptor( _Acceptors.GetCount() + 1 )))
378 {
379 _Acceptors << action;
380 return true;
381 }
382 return false;
383 }
384
Rejector(const String & action)385 bool Form::Rejector(const String& action)
386 {
387 if (SetCallback(action, TopWindow::Rejector( -(_Rejectors.GetCount() + 1) )))
388 {
389 _Rejectors << action;
390 return true;
391 }
392 return false;
393 }
394
SetCallback(const String & action,Callback c)395 bool Form::SetCallback(const String& action, Callback c)
396 {
397 if (!IsLayout())
398 return false;
399
400 Vector<FormObject>* p = &_Layouts[_Current].GetObjects();
401 for (int i = 0; i < p->GetCount(); ++i)
402 {
403 if ((*p)[i].Get("Type") == "Button")
404 if ((*p)[i].Get("Action") == action)
405 {
406 _Ctrls[i] <<= c;
407 return true;
408 }
409 }
410
411 return false;
412 }
413
GetData(const String & var)414 Value Form::GetData(const String& var)
415 {
416 if (!IsLayout())
417 return false;
418
419 Vector<FormObject>* p = &_Layouts[_Current].GetObjects();
420 for (int i = 0; i < p->GetCount(); ++i)
421 {
422 if ((*p)[i].Get("Variable") == var)
423 return ~_Ctrls[i];
424 }
425 return Value();
426 }
427
GetCtrl(const String & var)428 Ctrl* Form::GetCtrl(const String& var)
429 {
430 if (!IsLayout())
431 return NULL;
432
433 Vector<FormObject>* p = &_Layouts[_Current].GetObjects();
434 for (int i = 0; i < p->GetCount(); ++i)
435 {
436 if ((*p)[i].Get("Variable") == var)
437 return &_Ctrls[i];
438 }
439 return NULL;
440 }
441