GTK+/Kalkulator 0.0.1 - kalkulator.cpp

Z Wikibooks, biblioteki wolnych podręczników.
Przejdź do nawigacji Przejdź do wyszukiwania
  1 #include <stdlib.h>
  2 #include <string>
  3 #include <iostream>
  4 #include <sstream>
  5 #include <locale>
  6 
  7 #include "kalkulator.hpp"
  8 
  9 //#define DEBUG
 10 //#define INFO
 11 //#define NEW_VERSION_CALCULATE
 12 //#define WIN
 13 
 14 using namespace std;
 15 
 16 
 17 Kalkulator::Kalkulator()
 18 {
 19   #ifdef INFO
 20   __debug("Kalkulator konstruktor",false);
 21   #endif
 22   value1 = NULL;
 23   value2 = NULL;
 24   operation = NoSelectOprt;
 25   prev_operation = NoSelectOprt;
 26   is_value1 = FALSE;
 27   is_value2 = FALSE;
 28   is_result = FALSE;
 29   prev_button = NoSelectBtn;
 30   button_cache_comma = NoSelectBtn; 
 31   button_cache_result = NoSelectBtn; 
 32   memory = NULL;
 33 }
 34 
 35 Kalkulator::~Kalkulator()
 36 {
 37   #ifdef INFO
 38   __debug("Kalkulator destruktor",false);
 39   #endif
 40   memory_free();
 41 }
 42 
 43 const char* Kalkulator::_btn_id_to_char(btn_id val)
 44 {
 45   return   val==Button_1 ? "1" :
 46            val==Button_2 ? "2" :
 47            val==Button_3 ? "3" :
 48            val==Button_4 ? "4" :
 49            val==Button_5 ? "5" :
 50            val==Button_6 ? "6" :
 51            val==Button_7 ? "7" :
 52            val==Button_8 ? "8" :
 53            val==Button_9 ? "9" :
 54            val==Button_0 ? "0" :
 55            val==Button_add ? "Button_add" :
 56            val==Button_sub ? "Button_sub" :
 57            val==Button_multi ? "Button_multi" :
 58            val==Button_div ? "Button_div" :
 59            val==Button_result ? "Button_result" :
 60            val==Button_comma ? "Button_comma" :
 61            val==Button_back ? "Button_back" :
 62            val==Button_clear ? "Button_clear" :
 63            val==Button_signed ? "Button_signed" :
 64            val==Button_addmem ? "Button_addmem" :
 65            val==Button_readmem ? "Button_readmem" :
 66            val==Button_clearmem ? "Button_clearmem" :
 67            "NoSelectBtn(22)";
 68 }
 69 
 70 const char* Kalkulator::_operation_id_to_char(operation_id val)
 71 {
 72   return   val==Add ? "+" :
 73            val==Sub ? "-" :
 74            val==Multi ? "*" :
 75            val==Div ? "/" :
 76            "NoSelectOprt(5)";
 77 }
 78 
 79 btn_id Kalkulator::_operation_id_to_btn_id(operation_id val)
 80 {
 81   return   val==Add ? Button_add :
 82            val==Sub ? Button_sub :
 83            val==Multi ? Button_multi : 
 84            val==Div ? Button_div :
 85            NoSelectBtn;
 86 }
 87 
 88 void Kalkulator::__debug(const gchar* event, bool data)
 89 {
 90   if (data)
 91   {
 92     printf (
 93 "\n ===================[DEBUG]=====================\n \
 94 event: %s \n \
 95  - - - - -\n \
 96 Struktura:\n \
 97   value1: %s \n \
 98   value2: %s \n \
 99   operation: %s \n \
100   prev_operation: %s \n \
101   is_value1: %s \n \
102   is_value2: %s \n \
103   is_result: %s \n \
104   prev_button: %s \n \
105   button_cahce_comma: %s \n \
106   button_cahce_result: %s \n \
107   memory: %s \n \
108 ===============================================\n\n\n",
109       event,
110       is_value1? value1->str :"",
111       is_value2? value2->str :"",
112       _operation_id_to_char(operation),
113       _operation_id_to_char(prev_operation),
114       is_value1?"TRUE":"FALSE",
115       is_value2?"TRUE":"FALSE",
116       is_result?"TRUE":"FALSE",
117       _btn_id_to_char(prev_button),
118       _btn_id_to_char(button_cache_comma),
119       _btn_id_to_char(button_cache_result),
120       memory? "TRUE": "NULL");
121     
122     if (memory)
123     {
124       cout << "Spis liczb w pamięci:" << endl;
125       memory_print();
126       cout << endl;
127     }
128   }
129   else
130     cout << event << endl;
131 }
132 
133 #ifndef NEW_VERSION_CALCULATE
134 void Kalkulator::calculate(bool prev_operation_priv)
135 {
136   #ifndef WIN  
137   long double d_value1=0,
138   #else
139   double d_value1=0,
140   #endif
141          d_value2=0,
142          d_result=0;
143   int len, test(0);
144   char s_result[50];
145   string ss_result;
146   bool is_comma(false);
147   
148   d_value1 = strtod( value1->str, NULL );
149   d_value2 = strtod( value2->str, NULL );
150   
151   if (prev_operation_priv)
152   {
153     test = prev_operation==Add ? 1 :
154            prev_operation==Sub ? 2 :
155            prev_operation==Multi ? 3 :
156            prev_operation==Div ? 4 :
157            NoSelectOprt;
158   }
159   else
160   {
161     test = operation==Add ? 1 :
162            operation==Sub ? 2 :
163            operation==Multi ? 3 :
164            operation==Div ? 4 :
165            NoSelectOprt;
166   }
167   
168   switch(test)
169   {
170     case 1:
171       d_result = d_value1 + d_value2;
172       break;
173     case 2:
174       d_result = d_value1 - d_value2;
175       break;
176     case 3:
177       d_result = d_value1 * d_value2;
178       break;
179     case 4:
180       if ( d_value2 != 0.0 )
181         d_result = d_value1 / d_value2;
182       else
183         d_result = d_value1;
184       break;
185     case 5:
186       // Checkit!
187       break;
188   }
189 
190   len = sprintf( s_result, "%Lf", d_result );
191   // można to spr.
192   // if ( !len ) ...
193   ss_result = s_result;
194 
195   for (unsigned int i=0; i < ss_result.length(); i++)
196   {
197     if (ss_result[i] == ',')
198     {
199       is_comma = true;
200       #ifdef DEBUG
201       cout << "\nis comma\n";
202       #endif
203       break;
204     }
205   }
206   // tylko ,
207   if (is_comma)
208   {
209     // usuwamy końcowe 0
210     while (ss_result[ss_result.length()-1] == '0')
211       ss_result.erase((ss_result.length()-1),1);
212     // usuwamy przecinek jeżeli za nim byo same 0
213     if (ss_result[ss_result.length()-1] == ',')
214       ss_result.erase((ss_result.length()-1),1);
215   }
216   
217   set_value1(ss_result.c_str());
218   set_is_result(true);
219   
220   #ifdef DEBUG
221     printf ("calculateby to %Lg , %Lg wynik to: %Lg \n",d_value1,d_value2,d_result);
222   #endif
223 }
224 #endif
225 
226 #ifdef NEW_VERSION_CALCULATE
227 void Kalkulator::calculate(bool prev_operation_priv)
228 {
229   #ifndef WIN  
230   long double d_value1=0,
231   #else
232   double d_value1=0,
233   #endif
234          d_value2=0,
235          d_result=0;
236   
237   cout << "long double: " << sizeof(long double) << endl;
238   cout << "float: " << sizeof(float) << endl;
239   cout << "long: " << sizeof(long) << endl;
240   
241   bool is_comma(false);
242   int len, test(0);
243   string s_result, s1, s2;
244   //string str1 = value1->str, str2 = value2->str;
245   istringstream str1;
246   istringstream str2;
247   ostringstream rst;
248   
249   //s1.imbue(locale("pl_PL"));
250   //s2.imbue(locale("pl_PL")); 
251   
252   str1.str(value1->str);
253   str2.str(value2->str);
254   
255   s1 = str1.str();
256   s2 = str2.str();
257   
258   for (unsigned int i=0; i < s1.length(); i++)
259   {
260     if (s1[i] == '.')
261     {
262       s1.replace(i,1,1,',');
263       //is_comma = true;
264       break;
265     }
266   }
267   for (unsigned int i=0; i < s2.length(); i++)
268   {
269     if (s2[i] == '.')
270     {
271       s2.replace(i,1,1,',');
272       //is_comma = true;
273       break;
274     }
275   }
276   str1.str(s1);
277   str2.str(s1);
278   
279   // char* -> double
280   str1 >> d_value1;
281   //str2 >> fixed >> dec >> d_value2;
282   str2 >> d_value2;
283   str1 >> s1;
284   str2 >> s2;
285   cout << "\nval1: " << d_value1 << " s1: " << s1 << endl;
286   cout << "\nval2: " << d_value2 << " s2: " << s2 << endl;
287   cout << "\n s1: " << s1 << " s2: " << s2 << endl;
288   if (prev_operation_priv)
289   {
290     test = prev_operation==Add ? 1 :
291            prev_operation==Sub ? 2 :
292            prev_operation==Multi ? 3 :
293            prev_operation==Div ? 4 :
294            NoSelectOprt;
295   }
296   else
297   {
298     test = operation==Add ? 1 :
299            operation==Sub ? 2 :
300            operation==Multi ? 3 :
301            operation==Div ? 4 :
302            NoSelectOprt;
303   }
304   switch(test)
305   {
306   case 1:
307     d_result = d_value1 + d_value2;
308     break;
309   case 2:
310     d_result = d_value1 - d_value2;
311     break;
312   case 3:
313     d_result = d_value1 * d_value2;
314     break;
315   case 4:
316     if ( d_value2 != 0.0 )
317       d_result = d_value1 / d_value2;
318     else
319       d_result = d_value1;
320     break;
321   case 5:
322     // Checkit!
323     break;
324   }
325    
326   rst << fixed << dec << d_result;
327   s_result = rst.str(); 
328   cout << "\n s_result: " << s_result << endl;
329   //for (unsigned int i=0; i < s_result.length(); i++)
330   //{
331   //  if (s_result[i] == '.')
332   //  {
333   //    s_result.replace(i,1,1,',');
334   //    is_comma = true;
335   //    break;
336   //  }
337   //}
338   for (unsigned int i=0; i < s_result.length(); i++)
339   {
340     if (s_result[i] == ',')
341     {
342       is_comma = true;
343       break;
344     }
345   }
346   cout << "\n s_result: " << s_result << endl;
347   if (is_comma)
348   {
349     // usuwamy końcowe 0
350     while (s_result[s_result.length()-1] == '0')
351       s_result.erase((s_result.length()-1),1);
352     // usuwamy przecinek jeżeli za nim byo same 0
353     if (s_result[s_result.length()-1] == ',')
354       s_result.erase((s_result.length()-1),1);
355   }
356   set_value1(s_result.c_str());
357 
358   set_is_result(true);
359   
360   #ifdef DEBUG
361   cout << "\nval1: " << d_value1 << " val2: " << d_value2 << " rst: " << d_result << endl;
362   #endif
363 }
364 #endif
365 
366 char* Kalkulator::get_value1()
367 {
368   if (is_value1) 
369     return value1->str;
370   else 
371     return NULL;
372 }
373 
374 void Kalkulator::set_value1(const gchar *val) 
375 {
376   if (is_value1)
377   {
378     g_string_free(value1,TRUE);
379     value1 = g_string_new(val);
380   }
381   else
382   {
383     value1 = g_string_new(val);
384     is_value1 = TRUE;
385   }
386 }
387 
388 bool Kalkulator::del_value1()
389 {
390   if (is_value1)
391   {
392     g_string_free(value1,TRUE);
393     is_value1 = FALSE;
394     return TRUE;
395   }
396   else
397     return FALSE;
398 }
399 
400 char* Kalkulator::get_value2()
401 {
402   if (is_value2) 
403     return value2->str;
404   else 
405     return NULL;
406 }
407 
408 void Kalkulator::set_value2(const gchar *val) 
409 {
410   if (is_value2)
411   {
412     g_string_free(value2,TRUE);
413     value2 = g_string_new(val);
414   }
415   else
416   {
417     value2 = g_string_new(val);
418     is_value2 = TRUE;
419   }
420 }
421 
422 bool Kalkulator::del_value2()
423 {
424   if (is_value2)
425   {
426     g_string_free(value2,TRUE);
427     is_value2 = FALSE;
428     return TRUE;
429   }
430   else
431     return FALSE;
432 }
433 
434 void Kalkulator::add_to_memory(const gchar *val)
435 {
436   GString *tmp = g_string_new(val);
437   memory = g_list_append(memory, tmp);
438 }
439 
440 void Kalkulator::memory_free()
441 {
442   int n(0);
443   // zwalniamy pamięć, na którą wskazują wskaźniki w liście
444   // zobacz: http://mail.gnome.org/archives/gtk-app-devel-list/2005-January/msg00357.html
445   while (memory)
446   {
447     GList *tmp = g_list_nth(memory,n++);
448     if (tmp)
449       g_string_free((GString*)tmp->data,TRUE);
450     else
451       break;
452   }
453   // zwalniamy pamięć, której używa lista
454   g_list_free(memory);
455   memory = NULL;
456 }
457 
458 void Kalkulator::memory_print()
459 {
460   int n(0);
461   while (memory)
462   {
463     GList *tmp = g_list_nth(memory,n++);
464     if (tmp)
465       g_print("\n[ mem %d: %s ]",n,((GString*)tmp->data)->str);
466     else
467       break;
468   }
469 }
470 
471 guint Kalkulator::memory_count()
472 {
473   return g_list_length(memory);
474 }