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 <table/PortfolioData.h>
9 #include <db/Account.h>
10 #include <db/DBFactory.h>
11 #include <db/Portfolio.h>
12 #include <db/Portfolio2.h>
13 #include <db/Security.h>
14 #include <gui/XTrader.h>
15 #include <Resource.h>
16 #include <MHDate.h>
17 #include <MHString.h>
18 #include <FL/Fl.H>
19
20
21
22 /**
23 * @param Security* - The security object to load price data for. Caller is responsible for deleting object
24 */
PortfolioData(Account * a)25 PortfolioData::PortfolioData (Account* a) :
26 BaseData () {
27 aAccount = *a;
28 aVector = new MHVector (500);
29 aVectorSecurity = new MHVector (500);
30 aVectorTotal = new MHVector (500);
31 aVectorBalance = new MHVector (500);
32 aChoiceEvent = MHUtil::Allocate (Portfolio::EV_TRANSFER, 31);
33
34 Portfolio::Load (&aAccount, aVector);
35
36 for (int f = 0; f < Portfolio::EV_TRANSFER; f++)
37 STRNCPY (aChoiceEvent[f], Portfolio::GetEventName(f), 30)
38 reload ("Security");
39 calcBalance ();
40 }
41
42
43
44 /**
45 *
46 */
~PortfolioData()47 PortfolioData::~PortfolioData () {
48 MHUtil::Delete (aChoiceEvent, Portfolio::EV_TRANSFER);
49 if (aChoiceSecurity)
50 MHUtil::Delete (aChoiceSecurity, aVectorSecurity->Size() + 1);
51 aVector->Erase ();
52 aVectorSecurity->Erase ();
53 aVectorTotal->Erase ();
54 aVectorBalance->Erase ();
55 delete aVector;
56 delete aVectorSecurity;
57 delete aVectorTotal;
58 delete aVectorBalance;
59 }
60
61
62
63 /**
64 *
65 */
add()66 void PortfolioData::add () {
67 insert (aVector->Size());
68 }
69
70
71
72 /**
73 *
74 */
align(int row,int col)75 Fl_Align PortfolioData::align (int row, int col) {
76 switch (col) {
77 case 4:
78 case 5:
79 case 6:
80 case 7:
81 case 8:
82 return FL_ALIGN_RIGHT;
83
84 case 0:
85 case 1:
86 case 2:
87 case 3:
88 default:
89 return FL_ALIGN_LEFT;
90 }
91 }
92
93
94
95 /**
96 * Calc. transaction balance
97 */
calcBalance()98 void PortfolioData::calcBalance () {
99 double balance = aAccount.GetBalance();
100
101 aVectorTotal->Erase ();
102 aVectorBalance->Erase ();
103
104 for (int f = 0; f < aVector->Size(); f++) {
105 Portfolio2* p2 = (Portfolio2*) (*aVector)[f];
106
107 balance += p2->CashValue();
108 aVectorTotal->Push (new MHString (p2->CashValue()));
109 aVectorBalance->Push (new MHString (balance));
110 }
111 }
112
113
114
115 /**
116 *
117 */
choice(int row,int col,int & size,int & selected,char * label)118 const char** PortfolioData::choice (int row, int col, int& size, int& selected, char* label) {
119 int f;
120 Portfolio* p = (Portfolio*) aVector->Get (row);
121
122 switch (col) {
123 case 1:
124 // Portfolio events
125 size = Portfolio::EV_TRANSFER;
126 selected = 0;
127 for (f = 0; f < Portfolio::EV_TRANSFER; f++) {
128 if (strcmp (Portfolio::GetEventName(p->GetEvent()), aChoiceEvent[f]) == 0) {
129 selected = f;
130 break;
131 }
132 }
133 return (char const**) aChoiceEvent;
134
135 case 3:
136 // Security for portfolio buy/sell/dividend event
137 size = aVectorSecurity->Size() + 1;
138 selected = 0;
139
140 for (f = 0; f < aVectorSecurity->Size(); f++) {
141 Security* s = (Security*) (*aVectorSecurity)[f];
142 if (s->GetID() == p->GetSecurityID()) {
143 selected = f + 1;
144 break;
145 }
146 }
147 strncpy (label, STRING(SELECT_SECURITY), 99);
148 return (char const**) aChoiceSecurity;
149 }
150
151 return 0;
152 }
153
154
155
156 /**
157 *
158 */
editor_type(int row,int col,bool force_custom)159 FL_TABLE_EDITOR PortfolioData::editor_type (int row, int col, bool force_custom) {
160 switch (col) {
161 case 0:
162 case 2:
163 return FL_TEXT_EDITOR;
164
165 case 1:
166 return FL_LIST_EDITOR;
167
168 case 3:
169 return FL_DLG_LIST_EDITOR;
170
171 case 7:
172 case 8:
173 return FL_NO_EDITOR;
174
175 default:
176 return FL_FLOAT_EDITOR;
177 }
178 }
179
180
181
182 /**
183 *
184 */
erase(int row)185 void PortfolioData::erase (int row) {
186 if (row >= 0 && row < aVector->Size()) {
187 aVector->Erase (row);
188 dirty (true);
189 }
190 }
191
192
193
194 /**
195 *
196 */
insert(int row)197 void PortfolioData::insert (int row) {
198 MHDate d;
199 Portfolio* p = new Portfolio (d.Get (MHDate::LONG_DATE), Portfolio::EV_IN, 0, 0.0, 0.0, 0.0, 0, 0, "");
200
201 aVector->Insert (p, row);
202 aVectorTotal->Insert (new MHString(), row);
203 aVectorBalance->Insert (new MHString(), row);
204 dirty (true);
205 }
206
207
208
209 /**
210 *
211 */
reload(const char * message)212 void PortfolioData::reload (const char* message) {
213 if (strcmp (message, "Security") == 0) {
214 Portfolio::LoadSecurities (aVector);
215
216 if (aVectorSecurity->Size() > 0) MHUtil::Delete (aChoiceSecurity, aVectorSecurity->Size() + 1);
217 aVectorSecurity->Erase ();
218 Security::Load (aVectorSecurity);
219 aVectorSecurity->Sort (Security::SORT_NAME);
220
221 aChoiceSecurity = MHUtil::Allocate (aVectorSecurity->Size() + 1, 31);
222 STRNCPY (aChoiceSecurity[0], " ", 30)
223 for (int f = 1; f <= aVectorSecurity->Size(); f++) {
224 Security* s = (Security*) (*aVectorSecurity)[f - 1];
225 STRNCPY (aChoiceSecurity[f], s->GetName()->Get(), 30)
226 }
227 }
228 else if (strcmp (message, "Account") == 0) {
229 calcBalance ();
230 }
231 }
232
233
234
235 /**
236 *
237 */
save()238 int PortfolioData::save () {
239 Portfolio::Save (&aAccount, aVector);
240 calcBalance ();
241 dirty (false);
242 XTrader::SetInfo (STRING(DATA_SAVED));
243 XTrader::SendMessage (0, "Portfolio", "changed", "", &aAccount);
244 return -1;
245 }
246
247
248
249 /**
250 *
251 */
sort(int col,bool ascending)252 void PortfolioData::sort (int col, bool ascending) {
253 }
254
255
256
257 /**
258 *
259 */
value(const char * data,int row,int col)260 bool PortfolioData::value (const char* data, int row, int col) {
261 Portfolio* p = (Portfolio*) (*aVector)[row];
262
263 switch (col) {
264 case 0:
265 if (strcmp (p->GetDate()->Get(), data) == 0) return true;
266 if (MHDate::ValidDate (data) == false)
267 return false;
268 p->SetDate (data);
269 break;
270
271 case 1: {
272 for (int f = 0; f < Portfolio::EV_TRANSFER; f++) {
273 if (strcmp (Portfolio::GetEventName(f), data) == 0) {
274 p->SetEvent ((Portfolio::EVENT)f);
275 break;
276 }
277 }
278 break;
279 }
280
281 case 2:
282 p->SetMemo (data);
283 break;
284
285 case 3:
286 if (strcmp (data, "") == 0)
287 p->SetSecurityID (0);
288 else {
289 for (int f = 0; f < aVectorSecurity->Size(); f++) {
290 Security* s = (Security*) (*aVectorSecurity)[f];
291
292 if (strcmp (s->GetName()->Get(), data) == 0) {
293 if (p->GetEvent() >= Portfolio::EV_USE_SECURITY)
294 p->SetSecurityID (s->GetID());
295 else
296 p->SetSecurityID (0);
297 break;
298 }
299 }
300 }
301 p->LoadSecurity ();
302 break;
303
304 case 4:
305 p->SetVolume (atof(data));
306 break;
307
308 case 5:
309 p->SetPrice (atof(data));
310 break;
311
312 case 6:
313 p->SetCourtage (atof(data));
314 break;
315 }
316
317 if (p->GetEvent() < Portfolio::EV_USE_SECURITY) {
318 p->SetVolume (0.0);
319 p->SetCourtage (0.0);
320 p->SetSecurityID (0);
321 p->LoadSecurity ();
322 }
323
324 dirty (true);
325 return true;
326 }
327
328
329
330 /**
331 *
332 */
value(int row,int col)333 const char* PortfolioData::value (int row, int col) {
334 if (row == FL_LABEL_ROW)
335 return aAccount.GetAccount()->Get();
336 else if (row == FL_HEADER_ROW) {
337 switch (col) {
338 case 0:
339 return STRING(DATE);
340
341 case 1:
342 return STRING(TYPE);
343
344 case 2:
345 return STRING(MEMO);
346
347 case 3:
348 return STRING(SECURITY);
349
350 case 4:
351 return STRING(VOLUME);
352
353 case 5:
354 return STRING(PRICE);
355
356 case 6:
357 return STRING(COURTAGE);
358
359 case 7:
360 return STRING(TOTAL);
361
362 case 8:
363 return STRING(BALANCE);
364
365 default:
366 return "";
367 }
368 }
369 else {
370 Portfolio* p = (Portfolio*) (*aVector)[row];
371
372 switch (col) {
373 case 0:
374 return p->GetDate()->Get();
375
376 case 1:
377 return p->GetEventName(p->GetEvent());
378
379 case 2:
380 return p->GetMemo()->Get();
381
382 case 3:
383 return p->GetSecurity()->GetName()->Get();
384
385 case 4:
386 snprintf (aBuff, 30, "%.2f", p->GetVolume());
387 return aBuff;
388
389 case 5:
390 snprintf (aBuff, 30, "%.2f", p->GetPrice());
391 return aBuff;
392
393 case 6:
394 snprintf (aBuff, 30, "%.2f", p->GetCourtage());
395 return aBuff;
396
397 case 7:
398 return ((MHString*) (*aVectorTotal)[row])->Get();
399
400 case 8:
401 return ((MHString*) (*aVectorBalance)[row])->Get();
402
403 default:
404 return "";
405 }
406 }
407 }
408
409
410
411 /**
412 *
413 */
width(int col)414 int PortfolioData::width (int col) {
415 switch (col) {
416 case 2:
417 case 3:
418 return XTrader::FontSize() * 8;
419
420 default:
421 return XTrader::FontSize() * 6;
422 }
423 }
424