1 /**
2 *  Copyright Mikael H�gdahl - triyana@users.sourceforge.net
3 *
4 *  This source is distributed under the terms of the Q Public License version 1.0,
5 *  created by Trolltech (www.trolltech.com).
6 */
7 
8 #include "gui/XTrader.h"
9 #include "db/DBFactory.h"
10 #include "db/Import.h"
11 #include "db/Pref.h"
12 #include "dlg/AboutDlg.h"
13 #include "dlg/DownloadDlg.h"
14 #include "dlg/ExportDlg.h"
15 #include "dlg/InfoDlg.h"
16 #include "dlg/ProgressDlg.h"
17 #include "dlg/SetupDlg.h"
18 #include "dlg/SplitDlg.h"
19 #include "dlg/WorkSpaceDlg.h"
20 #include "Enums.h"
21 #include "gui/ChartView.h"
22 #include "gui/EditView.h"
23 #include "gui/ReportView.h"
24 #include "help/License.h"
25 #include "Progress.h"
26 #include "report/GuardReport.h"
27 #include "report/PortfolioReport.h"
28 #include "report/PriceReport.h"
29 #include "Resource.h"
30 #include "table/AccountData.h"
31 #include "table/GuardData.h"
32 #include "table/PriceData.h"
33 #include "table/ReportData.h"
34 #include "table/SecurityData.h"
35 #include "table/SetData.h"
36 #include "table/SetItemData.h"
37 #include <FL/Fl.H>
38 #include <FL/Fl_Box.H>
39 #include <FL/Fl_File_Chooser.H>
40 #include <fl/Fl_Layout.h>
41 #include <FL/Fl_Menu_Bar.H>
42 #include <fl/Fl_Table_Data.h>
43 #include <MHDate.h>
44 #include <MHDebug.h>
45 #include <MHFile.h>
46 #include <MHMessage.h>
47 
48 #ifdef WIN32
49     extern HINSTANCE fl_display;
50 #else
51     #include <FL/x.H>
52     #include <X11/xpm.h>
53     #include <xtrader.xpm>
54 #endif
55 
56         XTrader*     XTrader::aaApp     = 0;
57 static  ProgressDlg* aaProgress         = 0;
58 
59 
60 
61 /**
62 *  Update progressbar dialog during heavy work load
63 */
xtrader_update()64 void xtrader_update () {
65     aaProgress->Value (xtrader_done(), "");
66 }
67 
68 
69 
70 /**
71 *  Create application and main objects as menu, toolbar...
72 *  @param int  - Width
73 *  @param int  - Height
74 */
XTrader(int w,int h)75 XTrader::XTrader (int w, int h) :
76 Fl_Double_Window (w, h, STRING(APP_NAME)) {
77 
78     switch (DBFactory::GetPrefIntValue (STRING(PREF_THEME), 0, XTRADER_LAST_THEME - 1, 0)) {
79         case 1:
80             Fl::set_boxtype (FL_UP_BOX, FL_THIN_UP_BOX);
81             Fl::set_boxtype (FL_UP_FRAME, FL_THIN_UP_FRAME);
82             Fl::set_boxtype (FL_DOWN_FRAME, FL_THIN_DOWN_FRAME);
83             Fl::set_boxtype (FL_DOWN_BOX, FL_THIN_DOWN_BOX);
84             break;
85 
86         default:
87             Fl::scheme ("plastic");
88             break;
89     }
90 
91     aLayout         = new Fl_BorderLayout (0, 0, 0, 0);
92     aMenu           = new Fl_Menu_Bar (0, 0, 0, 25);
93     aTop            = new Fl_BorderLayout (0, 0, 0, 27);
94     aToolbar        = new Fl_HorizontalLayout (0, 0, 0, 0);
95     aTabs           = new Tabs (0, 0, 0, 0);
96     aStatus         = new Fl_Box (0, 0, 0, 20);
97     aListeners      = new MHMessage();
98     aLastClosedView = 0;
99     aaApp           = this;
100     aInitSize       = false;
101     aX = aY = aW = aH = 0;
102     aStatus->align (FL_ALIGN_INSIDE | FL_ALIGN_LEFT);
103     aStatus->box (FL_UP_BOX);
104     aLayout->space (5, 0, 0, 0);
105     aTop->space (0, 0, 0, 0);
106     aToolbar->space (2, 2);
107     aToolbar->box (FL_UP_BOX);
108 
109     aMenu->textsize (XTrader::FontSize ());
110     aTabs->labelsize (XTrader::FontSize ());
111     aStatus->labelsize (XTrader::FontSize ());
112     aStatus->labelfont(FL_COURIER);
113 
114     aTop->add (Fl_Layout::NORTH, aMenu);
115     aTop->add (Fl_Layout::CENTER, aToolbar);
116     aLayout->add (Fl_Layout::NORTH, aTop);
117     aLayout->add (Fl_Layout::CENTER, aTabs);
118     aLayout->add (Fl_Layout::SOUTH, aStatus);
119     add (aLayout);
120 
121     size_range (480, 360, 0, 0, 0, 0, 0);
122     resizable (this);
123     user_data (this);
124 
125     createMenu ();
126     callback ((Fl_Callback*)XTrader::cbClose_);
127 
128     BuildToolbar ();
129 }
130 
131 
132 
133 /**
134 *  Delete application.
135 *  Delete last closed view also, which are owned by nobody
136 */
~XTrader()137 XTrader::~XTrader (){
138     delete aListeners;
139     delete aLastClosedView;
140 }
141 
142 
143 
144 /**
145 *  Create application toolbar
146 */
BuildToolbar()147 void XTrader::BuildToolbar () {
148     MHVector    ve;
149     MHString    tool (DBFactory::GetPrefStringValue (STRING(PREF_TOOLBAR), ""));
150     int         buttons = 0;
151 
152     aTop->resize (0, 0, 0, 26);
153     aToolbar->resize (0, 0, 0, 0);
154     aToolbar->clear ();
155 
156     tool.Split (':', &ve);
157 
158     for (int f = 0; f < ve.Size(); f++) {
159         MHString* s = (MHString*) ve[f];
160 
161         if (s && s->Size() > 2) {
162             if (buttons == 0) {
163                 aTop->resize (0, 0, 0, 55);
164                 aToolbar->resize (0, 0, 0, 29);
165                 buttons = 1;
166             }
167 
168             int        cbId  = 0;
169             Fl_Button* b     = 0;
170 
171             if (*s == STRING(TOOL_DATABASE)) {
172                 cbId = Resource::MENU_SELECT_DATABASE;
173                 b    = new Fl_Button (0, 0, XTrader::FontSize() * 9, 0, STRING(TOOL_DATABASE));
174             }
175             else if (*s == STRING(TOOL_DOWNLOAD)) {
176                 cbId = Resource::MENU_DOWNLOAD;
177                 b    = new Fl_Button (0, 0, XTrader::FontSize() * 9, 0, STRING(TOOL_DOWNLOAD));
178             }
179             else if (*s == STRING(TOOL_EXPORT)) {
180                 cbId = Resource::MENU_EXPORT;
181                 b    = new Fl_Button (0, 0, XTrader::FontSize() * 9, 0, STRING(TOOL_EXPORT));
182             }
183             else if (*s == STRING(TOOL_IMPORT)) {
184                 cbId = Resource::MENU_IMPORT;
185                 b    = new Fl_Button (0, 0, XTrader::FontSize() * 9, 0, STRING(TOOL_IMPORT));
186             }
187             else if (*s == STRING(TOOL_PREFERENCE)) {
188                 cbId = Resource::MENU_SETTINGS;
189                 b    = new Fl_Button (0, 0, XTrader::FontSize() * 9, 0, STRING(TOOL_PREFERENCE));
190             }
191             else if (*s == STRING(TOOL_PORTFOLIO_CHART)) {
192                 cbId = Resource::MENU_PORTFOLIO_CHART;
193                 b    = new Fl_Button (0, 0, XTrader::FontSize() * 9, 0, STRING(TOOL_PORTFOLIO_CHART));
194             }
195             else if (*s == STRING(TOOL_PORTFOLIO_REPORT)) {
196                 cbId = Resource::MENU_PORTFOLIO_REPORT;
197                 b    = new Fl_Button (0, 0, XTrader::FontSize() * 9, 0, STRING(TOOL_PORTFOLIO_REPORT));
198             }
199             else if (*s == STRING(TOOL_PRICE_CHART)) {
200                 cbId = Resource::MENU_PRICE_CHART;
201                 b    = new Fl_Button (0, 0, XTrader::FontSize() * 9, 0, STRING(TOOL_PRICE_CHART));
202             }
203             else if (*s == STRING(TOOL_PRICE_REPORT)) {
204                 cbId = Resource::MENU_GUARD_EDIT;
205                 b    = new Fl_Button (0, 0, XTrader::FontSize() * 9, 0, STRING(TOOL_PRICE_REPORT));
206             }
207             else if (*s == STRING(TOOL_PRICE_WATCH)) {
208                 cbId = Resource::MENU_GUARD_EDIT;
209                 b    = new Fl_Button (0, 0, XTrader::FontSize() * 9, 0, STRING(TOOL_PRICE_WATCH));
210             }
211             else if (*s == STRING(TOOL_PRICE_WATCH_REPORT)) {
212                 cbId = Resource::MENU_GUARD_REPORT;
213                 b    = new Fl_Button (0, 0, XTrader::FontSize() * 9, 0, STRING(TOOL_PRICE_WATCH_REPORT));
214             }
215             else if (*s == STRING(TOOL_QUIT)) {
216                 cbId = Resource::MENU_QUIT;
217                 b    = new Fl_Button (0, 0, XTrader::FontSize() * 9, 0, STRING(TOOL_QUIT));
218             }
219             else if (*s == STRING(TOOL_VIEW_LOG)) {
220                 cbId = Resource::MENU_LOG;
221                 b    = new Fl_Button (0, 0, XTrader::FontSize() * 9, 0, STRING(TOOL_VIEW_LOG));
222             }
223             else if (*s == STRING(TOOL_WORKSPACE)) {
224                 cbId = Resource::MENU_WORKSPACE;
225                 b    = new Fl_Button (0, 0, XTrader::FontSize() * 9, 0, STRING(TOOL_WORKSPACE));
226             }
227 
228             if (cbId && b) {
229                 XTrader::FixButton (b);
230                 b->callback ((Fl_Callback*) XTrader::cbMenu_, (void*)cbId);
231                 aToolbar->add (b);
232             }
233         }
234     }
235 
236     ve.Erase ();
237     resize (x(), y(), w(), h());
238     Fl::redraw ();
239 }
240 
241 
242 
243 /**
244 *
245 */
cbClose()246 void XTrader::cbClose () {
247     if (Close() == true)
248         hide ();
249 }
250 
251 
252 /**
253  * Callback for file chooser
254  */
fc_callback(Fl_File_Chooser * fc,void * data)255 void fc_callback(Fl_File_Chooser *fc, void *data)
256 {
257 	XTrader *xt = static_cast<XTrader *>(data);
258 	const char *file = fc->value();
259 
260 	if (file && *file) {
261 		MHDate date;
262 		Import* import = 0;
263 		double start = MHUtil::Time();
264 
265 		XTrader::StartWork (STRING(INFO_IMPORTING));
266 		try {
267 			import = new Import (file);
268 			import->Read ();
269 			char buffer[100];
270 			snprintf (buffer, 99, "%s (%d %s / %.1fs) (%s=%d)", STRING(INFO_IMPORT_FINISHED), import->Rows(), STRING(ROWS), MHUtil::Time() - start, STRING(ERROR_), import->Errors());
271 			XTrader::SetMessage (buffer);
272 		}
273 		catch (const char* message) {
274 			XTrader::SetError (message);
275 		}
276 		XTrader::StopWork ("");
277 		delete import;
278 	}
279 }
280 
281 /**
282 *  Callback for all menu items
283 */
cbMenu(int id)284 void XTrader::cbMenu (int id) {
285     try {
286         switch (id) {
287             case Resource::MENU_ABOUT: {
288                 AboutDlg dlg;
289                 dlg.show_modal (this);
290                 break;
291             }
292 
293             case Resource::MENU_ACCOUNT_EDIT:
294                 createView ("EditAccount");
295                 break;
296 
297             case Resource::MENU_CLEAR_CACHE:
298                 DBFactory::Clear ();
299                 break;
300 
301             case Resource::MENU_DOWNLOAD: {
302                 DownloadDlg downloadDlg;
303                 downloadDlg.show_modal (this);
304                 break;
305             }
306 
307             case Resource::MENU_EXPORT: {
308                 ExportDlg exportDlg;
309                 exportDlg.show_modal (this);
310                 break;
311             }
312 
313             case Resource::MENU_GUARD_EDIT:
314                 createView ("EditGuard");
315                 break;
316 
317             case Resource::MENU_GUARD_REPORT:
318                 createView ("ReportGuard");
319                 break;
320 
321             case Resource::MENU_IMPORT: {
322                 Fl_File_Chooser *fc = new Fl_File_Chooser (STRING(DLG_IMPORT), STRING(DLG_IMPORT_FILTER), Fl_File_Chooser::SINGLE, "");
323                 fc->callback(fc_callback);
324                 delete fc;
325                 aListeners->Send (0, "Import", "changed", 0, 0);
326                 Fl::redraw ();
327                 break;
328             }
329 
330             case Resource::MENU_LICENSE: {
331                 char buffer[5000];
332                 strcpy (buffer, aaLicense);
333                 strcat (buffer, aaLicense2);
334                 strcat (buffer, aaLicense3);
335                 InfoDlg dlg (STRING(LICENSE), buffer);
336                 dlg.show_modal (this);
337                 break;
338             }
339 
340             case Resource::MENU_LOG: {
341                 MHString name = DBFactory::Database();
342                 name += "xtrader.log";
343                 int size   = MHFile::Size (name());
344                 char* buff = new char[size + 5];
345                 FILE* file = fopen (name(), "rb");
346                 buff[0] = '\0';
347                 if (file) fread (buff, sizeof(char), size, file);
348                 if (file) fclose (file);
349                 InfoDlg dlg (STRING(LOG), buff);
350                 dlg.show_modal (this);
351                 delete []buff;
352                 break;
353             }
354 
355             case Resource::MENU_PORTFOLIO_CHART:
356                 createView ("ChartPortfolio");
357                 break;
358 
359             case Resource::MENU_PORTFOLIO_EDIT:
360                 createView ("EditPortfolio");
361                 break;
362 
363             case Resource::MENU_PORTFOLIO_REPORT:
364                 createView ("ReportPortfolio");
365                 break;
366 
367             case Resource::MENU_PRICE_CHART:
368                 createView ("ChartPrice");
369                 break;
370 
371             case Resource::MENU_PRICE_EDIT:
372                 createView ("EditPrice");
373                 break;
374 
375             case Resource::MENU_PRICE_REPORT:
376                 createView ("ReportPrice");
377                 break;
378 
379             case Resource::MENU_QUIT:
380                 cbClose ();
381                 break;
382 
383             case Resource::MENU_README: {
384                 //InfoDlg dlg (STRING(README), aaReadme);
385                 //dlg.Show (this);
386                 break;
387             }
388 
389             case Resource::MENU_SECURITY_EDIT:
390                 createView ("EditSecurity");
391                 break;
392 
393             case Resource::MENU_SELECT_DATABASE: {
394                 char* dir = fl_dir_chooser (STRING(DLG_SELECT_DB), "", 0);
395                 if (dir && *dir && Close() == true) {
396                     DBFactory::Stop ();
397                     DBFactory::Start (dir);
398                     LoadWorkSpace ();
399                     XTrader::SetMessage (STRING(INFO_NEW_DATABASE));
400                 }
401                 else
402                     XTrader::SetError (STRING(INFO_CLOSE_ALL));
403                 break;
404             }
405 
406             case Resource::MENU_SET_EDIT:
407                 createView ("EditSet");
408                 break;
409 
410             case Resource::MENU_SET_ITEMS_EDIT:
411                 createView ("EditSetItems");
412                 break;
413 
414             case Resource::MENU_SETTINGS: {
415                 SetupDlg dlg;
416                 dlg.show_modal (this);
417                 break;
418             }
419 
420             case Resource::MENU_SPLIT: {
421                 SplitDlg splitDlg;
422                 splitDlg.show_modal (this);
423                 break;
424             }
425 
426             case Resource::MENU_WORKSPACE: {
427                 WorkSpaceDlg dlg;
428                 dlg.show_modal (this);
429                 break;
430             }
431 
432             case Resource::MENU_WRITEPROTECT: {
433                 Fl_Menu_Item* i = getMenuItem (STRING(MENU_WRITEPROTECT2));
434 
435                 if (i) {
436                     DBFactory::SetPrefIntValue (STRING(PREF_WRITEPROTECTED), 0, 1000, 0, i->value());
437                     SavePos ();
438                     SaveWorkSpace ();
439                     Pref::Save (DBFactory::LoadPref ());
440                 }
441                 break;
442             }
443 
444             default:
445                 break;
446         }
447     }
448     catch (const char* message) {
449         XTrader::SetError (message);
450     }
451     redraw ();
452 }
453 
454 
455 
456 /**
457 *  Close one view but check for unsaved data first
458 */
close(BaseView * view)459 void XTrader::close (BaseView* view) {
460     for (int f = 0; f < aTabs->children(); f++) {
461         BaseView* w = (BaseView*) aTabs->child (f);
462 
463         if (w == view) {
464             if (w->CanClose ()) {
465                 aTabs->remove (w);
466                 aListeners->RemoveListener (w);
467                 delete aLastClosedView;
468                 aLastClosedView = w;
469             }
470             break;
471         }
472     }
473     redraw ();
474 }
475 
476 
477 
478 /**
479 *  Close all views but if data has changed in view ask user
480 */
Close()481 bool XTrader::Close () {
482     if (DBFactory::GetPrefIntValue (STRING(PREF_WRITEPROTECTED), 0, 1000, 0) == 0) {
483        SavePos();
484        SaveWorkSpace();
485        Pref::Save (DBFactory::LoadPref ());
486     }
487 
488     while (aTabs->children() > 0) {
489         BaseView* w = (BaseView*) aTabs->child (0);
490 
491         if (w->CanClose ()) {
492             aTabs->remove (w);
493             aListeners->RemoveListener (w);
494             delete aLastClosedView;
495             aLastClosedView = w;
496         }
497         else {
498             aTabs->value (w);
499             redraw ();
500             return false;
501         }
502     }
503 
504     return true;
505 }
506 
507 
508 
509 /**
510 *  Create application menu
511 */
createMenu()512 void XTrader::createMenu () {
513     aMenu->add (STRING(MENU_IMPORT), 0, (Fl_Callback*) XTrader::cbMenu_, (void*)Resource::MENU_IMPORT);
514     aMenu->add (STRING(MENU_EXPORT), 0, (Fl_Callback*) XTrader::cbMenu_, (void*)Resource::MENU_EXPORT);
515     aMenu->add (STRING(MENU_DOWNLOAD), 0, (Fl_Callback*) XTrader::cbMenu_, (void*)Resource::MENU_DOWNLOAD, FL_MENU_DIVIDER);
516     //aMenu->add (STRING(MENU_SPLIT), 0, (Fl_Callback*) XTrader::cbMenu_, (void*)Resource::MENU_SPLIT, FL_MENU_DIVIDER);
517     aMenu->add (STRING(MENU_LOG), 0, (Fl_Callback*) XTrader::cbMenu_, (void*)Resource::MENU_LOG, FL_MENU_DIVIDER);
518     //aMenu->add (STRING(MENU_CLEAR_CACHE), 0, (Fl_Callback*) XTrader::cbMenu_, (void*)Resource::MENU_CLEAR_CACHE, FL_MENU_DIVIDER);
519     aMenu->add (STRING(MENU_QUIT), 0, (Fl_Callback*) XTrader::cbMenu_, (void*)Resource::MENU_QUIT);
520 
521     aMenu->add (STRING(MENU_SETTINGS), 0, (Fl_Callback*) XTrader::cbMenu_, (void*)Resource::MENU_SETTINGS);
522     aMenu->add (STRING(MENU_SELECT_DATABASE), 0, (Fl_Callback*) XTrader::cbMenu_, (void*)Resource::MENU_SELECT_DATABASE);
523     aMenu->add (STRING(MENU_WORKSPACE), 0, (Fl_Callback*) XTrader::cbMenu_, (void*)Resource::MENU_WORKSPACE);
524     aMenu->add (STRING(MENU_WRITEPROTECT), 0, (Fl_Callback*) XTrader::cbMenu_, (void*)Resource::MENU_WRITEPROTECT, FL_MENU_TOGGLE);
525 
526     aMenu->add (STRING(MENU_SECURITY_EDIT), 0, (Fl_Callback*) XTrader::cbMenu_, (void*)Resource::MENU_SECURITY_EDIT);
527     aMenu->add (STRING(MENU_SET_EDIT), 0, (Fl_Callback*) XTrader::cbMenu_, (void*)Resource::MENU_SET_EDIT);
528     aMenu->add (STRING(MENU_SET_ITEMS_EDIT), 0, (Fl_Callback*) XTrader::cbMenu_, (void*)Resource::MENU_SET_ITEMS_EDIT);
529     aMenu->add (STRING(MENU_PRICE_EDIT), 0, (Fl_Callback*) XTrader::cbMenu_, (void*)Resource::MENU_PRICE_EDIT);
530     aMenu->add (STRING(MENU_GUARD_EDIT), 0, (Fl_Callback*) XTrader::cbMenu_, (void*)Resource::MENU_GUARD_EDIT, FL_MENU_DIVIDER);
531     aMenu->add (STRING(MENU_PRICE_REPORT), 0, (Fl_Callback*) XTrader::cbMenu_, (void*)Resource::MENU_PRICE_REPORT);
532     aMenu->add (STRING(MENU_GUARD_REPORT), 0, (Fl_Callback*) XTrader::cbMenu_, (void*)Resource::MENU_GUARD_REPORT, FL_MENU_DIVIDER);
533     aMenu->add (STRING(MENU_PRICE_CHART), 0, (Fl_Callback*) XTrader::cbMenu_, (void*)Resource::MENU_PRICE_CHART);
534 
535     aMenu->add (STRING(MENU_ACCOUNT_EDIT), 0, (Fl_Callback*) XTrader::cbMenu_, (void*)Resource::MENU_ACCOUNT_EDIT);
536     aMenu->add (STRING(MENU_PORTFOLIO_EDIT), 0, (Fl_Callback*) XTrader::cbMenu_, (void*)Resource::MENU_PORTFOLIO_EDIT, FL_MENU_DIVIDER);
537     aMenu->add (STRING(MENU_PORTFOLIO_REPORT), 0, (Fl_Callback*) XTrader::cbMenu_, (void*)Resource::MENU_PORTFOLIO_REPORT, FL_MENU_DIVIDER);
538     aMenu->add (STRING(MENU_PORTFOLIO_CHART), 0, (Fl_Callback*) XTrader::cbMenu_, (void*)Resource::MENU_PORTFOLIO_CHART);
539 
540     aMenu->add (STRING(MENU_ABOUT), 0, (Fl_Callback*) XTrader::cbMenu_, (void*)Resource::MENU_ABOUT);
541     aMenu->add (STRING(MENU_LICENSE), 0, (Fl_Callback*) XTrader::cbMenu_, (void*)Resource::MENU_LICENSE);
542     //aMenu->add (STRING(MENU_README), 0, (Fl_Callback*) XTrader::cbMenu_, (void*)Resource::MENU_README);
543 }
544 
545 
546 
547 /**
548 *  Create a view with perhaps some data.
549 *  @param const char* - View + data name
550 *  @param const char* - Data class name, if 0 then do data is created
551 *  @return BaseView*  - The created view or 0
552 */
createView(const char * view)553 BaseView* XTrader::createView (const char* view) {
554     BaseView* b = 0;
555 
556     if (strcmp (view, "ChartPortfolio") == 0)
557         b = new ChartView ("ChartPortfolio", BaseView::PORTFOLIO, aTabs->x(), aTabs->y() + 20, aTabs->w(), aTabs->h() - 20, STRING(PORTFOLIO_CHART_VIEW));
558     else if (strcmp (view, "ChartPrice") == 0)
559         b = new ChartView ("ChartPrice", BaseView::SET_SETITEM, aTabs->x(), aTabs->y() + 20, aTabs->w(), aTabs->h() - 20, STRING(PRICE_CHART_VIEW));
560     else if (strcmp (view, "EditAccount") == 0) {
561         if (findView (STRING(ACCOUNT_EDIT_VIEW)) == true) return 0;
562         b = new EditView ("EditAccount", BaseView::NO_BROWSER, new AccountData(), aTabs->x(), aTabs->y() + 20, aTabs->w(), aTabs->h() - 20, STRING(ACCOUNT_EDIT_VIEW));
563     }
564     else if (strcmp (view, "EditGuard") == 0) {
565         if (findView (STRING(GUARD_EDIT_VIEW)) == true) return 0;
566         b = new EditView ("EditGuard", BaseView::NO_BROWSER, new GuardData(), aTabs->x(), aTabs->y() + 20, aTabs->w(), aTabs->h() - 20, STRING(GUARD_EDIT_VIEW));
567     }
568     else if (strcmp (view, "EditPortfolio") == 0) {
569         if (findView (STRING(PORTFOLIO_EDIT_VIEW)) == true) return 0;
570         b = new EditView ("EditPortfolio", BaseView::PORTFOLIO, 0, aTabs->x(), aTabs->y() + 20, aTabs->w(), aTabs->h() - 20, STRING(PORTFOLIO_EDIT_VIEW));
571     }
572     else if (strcmp (view, "EditSecurity") == 0) {
573         if (findView (STRING(SECURITY_EDIT_VIEW)) == true) return 0;
574         b = new EditView ("EditSecurity", BaseView::NO_BROWSER, new SecurityData(), aTabs->x(), aTabs->y() + 20, aTabs->w(), aTabs->h() - 20, STRING(SECURITY_EDIT_VIEW));
575     }
576     else if (strcmp (view, "EditSet") == 0) {
577         if (findView (STRING(SET_EDIT_VIEW)) == true) return 0;
578         b = new EditView ("EditSet", BaseView::NO_BROWSER, new SetData(), aTabs->x(), aTabs->y() + 20, aTabs->w(), aTabs->h() - 20, STRING(SET_EDIT_VIEW));
579     }
580     else if (strcmp (view, "EditSetItems") == 0) {
581         if (findView (STRING(SET_ITEMS_EDIT_VIEW)) == true) return 0;
582         b = new EditView ("EditSetItems", BaseView::SET, 0, aTabs->x(), aTabs->y() + 20, aTabs->w(), aTabs->h() - 20, STRING(SET_ITEMS_EDIT_VIEW));
583     }
584     else if (strcmp (view, "ReportGuard") == 0) {
585         if (findView (STRING(GUARD_REPORT)) == true) return 0;
586         b = new ReportView ("ReportGuard", BaseView::GUARD, new GuardReport (new Report()), aTabs->x(), aTabs->y() + 20, aTabs->w(), aTabs->h() - 20, STRING(GUARD_REPORT));
587     }
588     else if (strcmp (view, "ReportPortfolio") == 0)
589         b = new ReportView ("ReportPortfolio", BaseView::PORTFOLIO, 0, aTabs->x(), aTabs->y() + 20, aTabs->w(), aTabs->h() - 20, STRING(PORTFOLIO_REPORT_VIEW));
590     else if (strcmp (view, "EditPrice") == 0) {
591         if (findView (STRING(PRICE_EDIT_VIEW)) == true) return 0;
592         b = new EditView ("EditPrice", BaseView::SET_SETITEM, 0, aTabs->x(), aTabs->y() + 20, aTabs->w(), aTabs->h() - 20, STRING(PRICE_EDIT_VIEW));
593     }
594     else if (strcmp (view, "ReportPrice") == 0)
595         b = new ReportView ("ReportPrice", BaseView::SET, 0, aTabs->x(), aTabs->y() + 20, aTabs->w(), aTabs->h() - 20, STRING(PRICE_REPORT_VIEW));
596 
597     if (b) {
598         aListeners->AddListener (b);
599         aTabs->add (b);
600         aTabs->value (b);
601         /*aTabs->*/resize (x(), y(), w(), h());
602         redraw ();
603     }
604 
605     return b;
606 }
607 
608 
609 
610 /**
611 *  Check if view exist already, if so return true
612 */
findView(const char * label)613 bool XTrader::findView (const char* label) {
614     for (int f = 0; f < aTabs->children(); f++) {
615         BaseView* v = (BaseView*) aTabs->child (f);
616 
617         if (strcmp (label, v->label()) == 0) {
618             aTabs->value (v);
619             return true;
620         }
621     }
622     return false;
623 }
624 
625 
626 /**
627 *  Change button appearance
628 *  @param Fl_Button* - Button
629 */
FixButton(Fl_Button * b)630 void XTrader::FixButton (Fl_Button* b) {
631     switch (DBFactory::GetPrefIntValue (STRING(PREF_THEME), 0, XTRADER_LAST_THEME - 1, 0)) {
632         case 0: {
633             int col = DBFactory::GetPrefIntValue (STRING(PREF_BCOLOR), 0, 255, 0);
634             switch (col) {
635                 case 0:
636                     break;
637 
638                 default:
639                     b->color (col);
640                     break;
641             }
642             break;
643         }
644     }
645 
646     b->labelsize (XTrader::FontSize ());
647 }
648 
649 
650 
651 /**
652 *  Return the global font size
653 *  @return int  - Font size
654 */
FontSize()655 int XTrader::FontSize () {
656     switch (DBFactory::GetPrefIntValue (STRING(PREF_FONTSIZE), 0, XTRADER_LAST_FONT, XTRADER_FONT12)) {
657         case 0:
658             return 10;
659 
660         case 2:
661             return 14;
662 
663         default:
664             return 12;
665     }
666 }
667 
668 
669 
670 /**
671 *  Get menu item with help of menu text. Only the last part of a fltk menu string must be used (after the last "/").
672 */
getMenuItem(const char * label)673 Fl_Menu_Item* XTrader::getMenuItem (const char* label) {
674     Fl_Menu_Item* i = (Fl_Menu_Item*) aMenu->menu ();
675     for (int f = 0; f < aMenu->size(); f++) {
676         if (!i->text)
677             ;
678         else if (strcmp (i->text, label) == 0)
679             return i;
680         i++;
681     }
682     return 0;
683 }
684 
685 
686 
687 /**
688 *  Window event
689 */
handle(int event)690 int XTrader::handle (int event) {
691     switch (event) {
692         case FL_KEYDOWN:
693             //printf ("0 - %d - %d\n", Fl::event_key(), Fl::event_state());
694             BaseView* w = (BaseView*) aTabs->value ();
695             if (w)
696                 return w->handle (event);
697             break;
698     }
699     return Fl_Double_Window::handle (event);
700 }
701 
702 
703 
704 /**
705 *  Load work spaces
706 */
LoadWorkSpace()707 void XTrader::LoadWorkSpace () {
708     MHString s = DBFactory::GetPrefStringValue (STRING(PREF_WORKSPACE));
709     MHVector ve;
710 
711     aTabs->off (true);
712     s.Split (',', &ve);
713     //  For every view entry
714     for (int f = 0; f < ve.Size(); f++) {
715         MHString* s2 = (MHString*) ve[f];
716         MHVector  ve2;
717 
718         s2->Split(':', &ve2);
719         if (ve2.Size() > 0) {
720             MHString* name = (MHString*) ve2.Get(0);
721             BaseView* v    = createView (name->Get());
722 
723             if (v)
724                 v->LoadWorkSpace (s2->Get());
725         }
726         ve2.Erase ();
727     }
728     ve.Erase ();
729 
730     Fl_Menu_Item* item = getMenuItem (STRING(MENU_WRITEPROTECT2));
731 
732     if (item) {
733         if (DBFactory::GetPrefIntValue (STRING(PREF_WRITEPROTECTED), 0, 1000, 0) == 0)
734             item->clear ();
735         else
736             item->set ();
737     }
738 
739     BuildToolbar ();
740     aLabel = STRING(APP_NAME);
741     aLabel += " - ";
742     aLabel += DBFactory::GetWorkSpaceName ();
743     aLabel += " ";
744     aLabel += STRING(WORKSPACE);
745     label (aLabel());
746     aTabs->off (false);
747 }
748 
749 
750 
751 /**
752 *  Overides Fl_Widget::resize to take care of it's own resizes
753 *  and also resize menu, toolbar, statusbar and the tile window
754 *  @param int  - X pos of application
755 *  @param int  - Y pos of application
756 *  @param int  - Width of application
757 *  @param int  - Height of application
758 */
resize(int x,int y,int w,int h)759 void XTrader::resize (int x, int y, int w, int h) {
760     DBG ("XTrader::resize")
761 
762     DBG_LOG4 ("XTrader    %4d, %4d, %4d, %4d", x,y,w,h)
763 
764     aLayout->off (true);
765     aTabs->off (true);
766 
767     Fl_Double_Window::resize (x, y, w, h);
768 
769     DBG_LOG4 ("XTrader    %4d, %4d, %4d, %4d", this->x(), this->y(), this->w(), this->h())
770 
771     aLayout->off (false);
772     aLayout->resize (0, 0, w, h);
773     aTabs->off (false);
774     aTabs->resize (aTabs->x(), aTabs->y(), aTabs->w(), aTabs->h());
775 
776     //printf ("--------------\nX%3d, %4d   %4d, %4d\n", this->x(), this->y(), this->w(), this->h());
777     DBG_LOG4 ("XTrader    %4d, %4d, %4d, %4d", this->x(), this->y(), this->w(), this->h())
778     DBG_LOG4 ("aLayout    %4d, %4d, %4d, %4d", aLayout->x(),  aLayout->y(),  aLayout->w(),  aLayout->h())
779     DBG_LOG4 ("aTop       %4d, %4d, %4d, %4d", aTop->x(),     aTop->y(),     aTop->w(),     aTop->h())
780     DBG_LOG4 ("aMenu      %4d, %4d, %4d, %4d", aMenu->x(),    aMenu->y(),    aMenu->w(),    aMenu->h())
781     DBG_LOG4 ("aToolbar   %4d, %4d, %4d, %4d", aToolbar->x(), aToolbar->y(), aToolbar->w(), aToolbar->h())
782     DBG_LOG4 ("aTabs      %4d, %4d, %4d, %4d", aTabs->x(),    aTabs->y(),    aTabs->w(),    aTabs->h())
783     DBG_LOG4 ("aStatus    %4d, %4d, %4d, %4d", aStatus->x(),  aStatus->y(),  aStatus->w(),  aStatus->h())
784 }
785 
786 
787 
788 /**
789 *  Save position to database
790 */
SavePos()791 void XTrader::SavePos() {
792     DBFactory::SetPrefIntValue (STRING(PREF_APPX), 0, 1000,  20, this->x());
793     DBFactory::SetPrefIntValue (STRING(PREF_APPY), 0, 1000,  20, this->y());
794     DBFactory::SetPrefIntValue (STRING(PREF_APPW), 0, 3000, 640, this->w());
795     DBFactory::SetPrefIntValue (STRING(PREF_APPH), 0, 3000, 480, this->h());
796 }
797 
798 
799 
800 /**
801 *  Save work spaces
802 */
SaveWorkSpace()803 void XTrader::SaveWorkSpace() {
804     MHString s;
805 
806     for (int f = 0; f < aTabs->children(); f++) {
807         BaseView* v = (BaseView*) aTabs->child (f);
808         if (f > 0) s += ",";
809         s += v->GetWorkSpace ();
810     }
811     DBFactory::SetPrefStringValue (STRING(PREF_WORKSPACE), s());
812 }
813 
814 
815 
816 /**
817 *  Show application
818 */
Show(int argc,char ** argv)819 void XTrader::Show(int argc, char** argv) {
820     Fl::visual (FL_DOUBLE | FL_RGB);
821     size (DBFactory::GetPrefIntValue (STRING(PREF_APPW), 0, 3000, 800), DBFactory::GetPrefIntValue (STRING(PREF_APPH), 0, 3000, 600));
822     position (DBFactory::GetPrefIntValue (STRING(PREF_APPX), 0, 1000, 50), DBFactory::GetPrefIntValue (STRING(PREF_APPY), 0, 1000, 50));
823 
824     #ifdef WIN32
825         HICON i = LoadIcon (fl_display, MAKEINTRESOURCE(666));
826         icon ((char*) i);
827     #else
828         //fl_open_display ();
829         Pixmap pixmap, mask;
830         XpmAttributes attr;
831         memset(&attr, 0, sizeof(attr));
832         XpmCreatePixmapFromData(fl_display, DefaultRootWindow(fl_display), xtrader_xpm, &pixmap, &mask, &attr);
833         icon((char*) pixmap);
834     #endif
835 
836     show (argc, argv);
837 }
838 
839 
840 
841 /**
842 *  Start some time consuming work
843 */
StartWork(const char * message,int showtime)844 void XTrader::StartWork (const char* message, int showtime) {
845     DBG ("XTrader::StartWork")
846 
847     if (aaProgress)
848         XTrader::StopWork ("");
849 
850     aaProgress = new ProgressDlg (message, 0, showtime);
851     aaProgress->show_modal2 (XTrader::GetApp());
852 }
853 
854 
855 
856 /**
857 *  Stop thread or reset cursor
858 */
StopWork(const char * message)859 void XTrader::StopWork (const char* message) {
860     DBG ("XTrader::StopWork")
861 
862     if (aaProgress) {
863         MHUtil::Sleep (0.5);
864         aaProgress->hide();
865         delete aaProgress;
866         aaProgress = 0;
867         if (message && *message)
868             XTrader::SetMessage (message);
869     }
870 }
871