GTK+/Kalkulator 0.0.1 - gui.cpp

Z Wikibooks, biblioteki wolnych podręczników.
Przejdź do nawigacji Przejdź do wyszukiwania
  1 #include "gui.hpp"
  2 #include <string.h>
  3 #include <gdk/gdkkeysyms.h>
  4 
  5 //#define DEBUG
  6 //#define INFO
  7 
  8 
  9 GUIKalkulator::GUIKalkulator()
 10 {
 11   #ifdef INFO 
 12   __debug("GUIKalkulator konstruktor",false);
 13   #endif
 14   combocount = 0;
 15 }
 16 
 17 GUIKalkulator::~GUIKalkulator()
 18 {
 19   #ifdef INFO 
 20   __debug("GUIKalkulator destruktor",false);
 21   #endif
 22 }
 23 
 24 void GUIKalkulator::init(int argc, char** argv)
 25 {
 26   #ifdef INFO 
 27   __debug("GUIKalkulator init()",false);
 28   #endif
 29   gtk_init(&argc, &argv);
 30 }
 31 
 32 void GUIKalkulator::build()
 33 {
 34   #ifdef INFO 
 35   __debug("GUIKalkulator bulid()",false);
 36   #endif
 37   mainwindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 38  
 39   g_signal_connect(G_OBJECT(mainwindow),"delete_event",G_CALLBACK(delete_event),this);
 40   g_signal_connect(G_OBJECT(mainwindow),"destroy",G_CALLBACK(destroy),this);
 41   gtk_widget_set_events (mainwindow, GDK_KEY_PRESS_MASK);
 42   g_signal_connect (G_OBJECT (mainwindow),"key_press_event",G_CALLBACK(mainwindow_key_press_event),this);
 43  
 44   gtk_window_set_title(GTK_WINDOW(mainwindow),"Kalkulator");
 45   gtk_window_set_resizable(GTK_WINDOW(mainwindow),FALSE);
 46   
 47   // tabela
 48   /*
 49         0/0 - 1 - 2 - 3 - 4 - 5 - 6
 50         1 | _ | _ | _ | _ | _ | _ |
 51         2 | _ | _ | _ | _ | _ | _ |
 52         3 | _ | _ | _ | _ | _ | _ |
 53         4 | _ | _ | _ | _ | _ | _ |
 54         5 | _ | _ | _ | _ | _ | _ | Add
 55    */
 56   table = gtk_table_new(5,6,TRUE);
 57   gtk_container_set_border_width(GTK_CONTAINER(table),5);
 58   //gtk_container_add(GTK_CONTAINER(mainwindow),table);
 59 
 60   // entry
 61   entry = gtk_entry_new();
 62   gtk_entry_set_alignment(GTK_ENTRY(entry),1);
 63   GdkColor entry_color; // kolor
 64   gdk_color_parse("#eaf8d9",&entry_color);
 65   gtk_widget_modify_base(entry,GTK_STATE_NORMAL,&entry_color);
 66   // 0,6 - szerokość od 0 do 6
 67   // 0,1 - wysokość od 0 do 1
 68   gtk_table_attach_defaults(GTK_TABLE(table),entry,0,6,0,1);
 69   gtk_widget_set_size_request(entry,-1,30);
 70   //czcionka
 71   pangofont = pango_font_description_new();
 72   pango_font_description_set_size(pangofont,17 * PANGO_SCALE );
 73   pango_font_description_set_weight(pangofont,PANGO_WEIGHT_BOLD);
 74   gtk_widget_modify_font(entry,pangofont);
 75   pango_font_description_free(pangofont);
 76   //bez zaznaczania
 77   gtk_editable_set_editable(GTK_EDITABLE(entry),false);
 78   
 79   // przyciski 1
 80   // 0,1 - szerokość od 0 do 1
 81   // 1,2 - wysokość od 1 do 2
 82   button1 = gtk_button_new_with_label("1");
 83   g_signal_connect(G_OBJECT(button1),"clicked",G_CALLBACK(btn_1_clicked),this);
 84   gtk_table_attach_defaults(GTK_TABLE(table),button1,0,1,1,2);
 85   
 86   // przyciski 2
 87   button2 = gtk_button_new_with_label("2");
 88   g_signal_connect(G_OBJECT(button2),"clicked",G_CALLBACK(btn_2_clicked),this);
 89   gtk_table_attach_defaults(GTK_TABLE(table),button2,1,2,1,2);
 90   
 91   // przyciski 3
 92   button3 = gtk_button_new_with_label("3");
 93   g_signal_connect(G_OBJECT(button3),"clicked",G_CALLBACK(btn_3_clicked),this);
 94   gtk_table_attach_defaults(GTK_TABLE(table),button3,2,3,1,2);
 95   
 96   // drugi wiersz
 97   // przyciski 4
 98   button4 = gtk_button_new_with_label("4");
 99   g_signal_connect(G_OBJECT(button4),"clicked",G_CALLBACK(btn_4_clicked),this);
100   gtk_table_attach_defaults(GTK_TABLE(table),button4,0,1,2,3);
101   
102   // przyciski 5
103   button5 = gtk_button_new_with_label("5");
104   g_signal_connect(G_OBJECT(button5),"clicked",G_CALLBACK(btn_5_clicked),this);
105   gtk_table_attach_defaults(GTK_TABLE(table),button5,1,2,2,3);
106   
107   // przyciski 6
108   button6 = gtk_button_new_with_label("6");
109   g_signal_connect(G_OBJECT(button6),"clicked",G_CALLBACK(btn_6_clicked),this);
110   gtk_table_attach_defaults(GTK_TABLE(table),button6,2,3,2,3);
111   
112   // trzeci wiersz
113   // przyciski 7
114   button7 = gtk_button_new_with_label("7");
115   g_signal_connect(G_OBJECT(button7),"clicked",G_CALLBACK(btn_7_clicked),this);
116   gtk_table_attach_defaults(GTK_TABLE(table),button7,0,1,3,4);
117   
118   // przyciski 8
119   button8 = gtk_button_new_with_label("8");
120   g_signal_connect(G_OBJECT(button8),"clicked",G_CALLBACK(btn_8_clicked),this);
121   gtk_table_attach_defaults(GTK_TABLE(table),button8,1,2,3,4);
122   
123   // przyciski 9
124   button9 = gtk_button_new_with_label("9");
125   g_signal_connect(G_OBJECT(button9),"clicked",G_CALLBACK(btn_9_clicked),this);
126   gtk_table_attach_defaults(GTK_TABLE(table),button9,2,3,3,4);
127   
128   // przyciski 0
129   button0 = gtk_button_new_with_label("0");
130   g_signal_connect(G_OBJECT(button0),"clicked",G_CALLBACK(btn_0_clicked),this);
131   gtk_table_attach_defaults(GTK_TABLE(table),button0,3,4,3,4);
132   
133   // przyciski <-
134   buttonback = gtk_button_new_with_label("<-");
135   g_signal_connect(G_OBJECT(buttonback),"clicked",G_CALLBACK(btn_back_clicked),this);
136   gtk_table_attach_defaults(GTK_TABLE(table),buttonback,3,4,2,3);
137   
138   // przyciski AC
139   buttonclear = gtk_button_new_with_label("AC");
140   g_signal_connect(G_OBJECT(buttonclear),"clicked",G_CALLBACK(btn_clear_clicked),this);
141   gtk_table_attach_defaults(GTK_TABLE(table),buttonclear,3,4,1,2);
142   
143   // przyciski +
144   buttonadd = gtk_button_new_with_label("+");
145   g_signal_connect(G_OBJECT(buttonadd),"clicked",G_CALLBACK(btn_add_clicked),this);
146   gtk_table_attach_defaults(GTK_TABLE(table),buttonadd,4,5,1,2);
147   
148   // przyciski -
149   buttonsub = gtk_button_new_with_label("-");
150   g_signal_connect(G_OBJECT(buttonsub),"clicked",G_CALLBACK(btn_sub_clicked),this);
151   gtk_table_attach_defaults(GTK_TABLE(table),buttonsub,4,5,2,3);
152   
153   // przyciski *
154   buttonmulti = gtk_button_new_with_label("*");
155   g_signal_connect(G_OBJECT(buttonmulti),"clicked",G_CALLBACK(btn_multi_clicked),this);
156   gtk_table_attach_defaults(GTK_TABLE(table),buttonmulti,4,5,3,4);
157   
158   // przyciski /
159   buttondiv = gtk_button_new_with_label("/");
160   g_signal_connect(G_OBJECT(buttondiv),"clicked",G_CALLBACK(btn_div_clicked),this);
161   gtk_table_attach_defaults(GTK_TABLE(table),buttondiv,5,6,1,2);
162    
163   // przyciski =
164   buttonresult = gtk_button_new_with_label("=");
165   g_signal_connect(G_OBJECT(buttonresult),"clicked",G_CALLBACK(btn_result_clicked),this);
166   gtk_table_attach_defaults(GTK_TABLE(table),buttonresult,5,6,3,4);
167 
168   // przyciski ,
169   buttoncomma = gtk_button_new_with_label(",");
170   g_signal_connect(G_OBJECT(buttoncomma),"clicked",G_CALLBACK(btn_comma_clicked),this);
171   gtk_table_attach_defaults(GTK_TABLE(table),buttoncomma,5,6,2,3);
172   
173   // przyciski -/+
174   buttonsigned = gtk_button_new_with_label("-/+");
175   g_signal_connect(G_OBJECT(buttonsigned),"clicked",G_CALLBACK(btn_signed_clicked),this);
176   gtk_table_attach_defaults(GTK_TABLE(table),buttonsigned,0,1,4,5);
177  
178   // przyciski M+
179   buttonaddmem = gtk_button_new_with_label("M+");
180   g_signal_connect(G_OBJECT(buttonaddmem),"clicked",G_CALLBACK(btn_addmem_clicked),this);
181   gtk_table_attach_defaults(GTK_TABLE(table),buttonaddmem,1,2,4,5);
182   
183   // lista z zapamietanymi liczbami
184   comboreadmem = gtk_combo_box_new_text();
185   gtk_table_attach_defaults(GTK_TABLE(table),comboreadmem,2,5,4,5);
186   gtk_combo_box_append_text(GTK_COMBO_BOX(comboreadmem),"Czytaj z pamięci");
187   combocount++;
188   gtk_combo_box_set_active(GTK_COMBO_BOX(comboreadmem),0);
189   g_signal_connect(G_OBJECT(comboreadmem),"changed",G_CALLBACK(btn_readmem_clicked),this);
190   gtk_widget_set_sensitive(comboreadmem,FALSE);
191   atk_object_set_name(
192         gtk_widget_get_accessible(comboreadmem),
193         "Zapamietane liczby"); 
194   atk_object_set_description(
195         gtk_widget_get_accessible(comboreadmem),
196         "Ustaw poziom efektu kontrast"); 
197   
198   // przyciski MC
199   buttonclearmem = gtk_button_new_with_label("MC");
200   g_signal_connect(G_OBJECT(buttonclearmem),"clicked",G_CALLBACK(btn_clearmem_clicked),this);
201   gtk_table_attach_defaults(GTK_TABLE(table),buttonclearmem,5,6,4,5);
202   gtk_widget_set_sensitive(buttonclearmem,FALSE);
203   
204   /*
205         GtkMenuBar
206             GtkMenuItem
207                 GtkMenu
208                     GtkImageMenuItem
209                     GtkMenuItem
210             GtkMenuItem
211                 GtkMenu
212                     GtkMenuItem
213                     GtkMenuItem
214             GtkMenuItem
215                 GtkMenu
216                     GtkMenuItem
217   */
218   menubar = gtk_menu_bar_new();
219 
220   menu_kalkulator = gtk_menu_new();
221   menuitem_close = gtk_menu_item_new_with_label("Zamknij");
222   gtk_menu_shell_append(GTK_MENU_SHELL(menu_kalkulator),menuitem_close);
223   g_signal_connect(G_OBJECT(menuitem_close),"activate",G_CALLBACK(menu_item_close),this);
224 
225   menu_help = gtk_menu_new();
226   menuitem_help = gtk_menu_item_new_with_label("Pomoc");
227   gtk_menu_shell_append(GTK_MENU_SHELL(menu_help),menuitem_help);
228   g_signal_connect(G_OBJECT(menuitem_help),"activate",G_CALLBACK(menu_item_help),this);
229   
230   menuitem_bar_kalkulator = gtk_menu_item_new_with_label("Kalkulator");
231   gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem_bar_kalkulator),menu_kalkulator);
232   gtk_menu_shell_append(GTK_MENU_SHELL(menubar),menuitem_bar_kalkulator);
233 
234   menuitem_bar_about = gtk_menu_item_new_with_label("O programie");
235   gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem_bar_about),menu_help);
236   gtk_menu_shell_append(GTK_MENU_SHELL(menubar),menuitem_bar_about);
237   
238   vbox_menu = gtk_vbox_new(FALSE,0);
239   gtk_box_pack_start(GTK_BOX(vbox_menu),menubar,FALSE,TRUE,0);
240   
241   
242   vbox = gtk_vbox_new(FALSE,0);
243   gtk_box_pack_start(GTK_BOX(vbox),vbox_menu,FALSE,FALSE,0);
244   gtk_box_pack_start(GTK_BOX(vbox),table,FALSE,FALSE,0);
245   
246   gtk_container_add(GTK_CONTAINER(mainwindow),vbox);
247 }
248 
249 void GUIKalkulator::run()
250 {
251   #ifdef INFO 
252   __debug("GUIKalkulator run()",false);
253   #endif
254   gtk_widget_show_all(mainwindow);
255   gtk_main();
256 }
257 
258 gboolean GUIKalkulator::delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
259 {
260   //GUIKalkulator *gui_kalkulator = static_cast<GUIKalkulator*>(data);
261   #ifdef INFO 
262   //gui_kalkulator->__debug("GUIKalkulator delete_event()",false);
263   static_cast<GUIKalkulator*>(data)->__debug("GUIKalkulator delete_event()",false);
264   #endif
265   return FALSE;
266 }
267 
268 void GUIKalkulator::destroy(GtkWidget *widget, gpointer data)
269 {
270   #ifdef INFO 
271   static_cast<GUIKalkulator*>(data)->__debug("GUIKalkulator destroy(gtk_main_quit)",false);
272   #endif
273   gtk_main_quit();
274 }
275 
276 void GUIKalkulator::_numeric_btn_clicked_event(btn_id button, GUIKalkulator* gui_kalkulator)
277 {
278   const char *number = _btn_id_to_char(button);
279   
280   #ifdef INFO 
281   __debug("GUIKalkulator _numeric_btn_clicked_event()",false);
282   g_print("clicked: %s\n",number);
283   #endif
284   
285   int len(0);
286   gint8 test(0); 
287   // 1 - poprzednio wciśnięto '=' na wyświetlaczu jest wynik, można na nim wynkonać nowe działania,
288   //     ale wybrano nową cyfre, co sugeruje przerwanie dotychczasowego działania i
289   //     rezpoczęcie nowego - wszystko jest zerowane podobnie jak podczas 'AC'
290   // 2 - na wyswietlaczu jest wynik, np. po wywołaniu jednego z przycisków działań ('+'),
291   //     wybrano nową cyfrę, więc definiujemy value2 - wyświetlacz jest czyszczony
292   // 3 - na wyświetlaczu jest wynik, przed kolejnymi działaniami zostaje modyfikowany
293   //     przez dodanie części ułamkowej, czyli wciśnięto przycisk ','
294   // 4 - zaczynamy wprowadzań drugą wartość po przycisku działania
295   
296   if (get_is_result() && get_prev_button() == Button_result)
297   {
298     test = 1;
299     #ifdef DEBUG 
300     g_print("\ntest 1 ;)\n");
301     #endif
302   }
303   else if (get_is_result() && 
304            (get_prev_button() == Button_add   ||
305             get_prev_button() == Button_sub   ||
306             get_prev_button() == Button_multi ||
307             get_prev_button() == Button_div)   )
308   {
309     test = 2;
310     #ifdef DEBUG 
311     g_print("\ntest 2 ;)\n");
312     #endif
313   }  
314   else if (get_is_result() == false && 
315            get_button_cache_comma() == Button_comma && 
316            get_button_cache_result() == Button_result)
317   {
318     test = 3;
319     #ifdef DEBUG 
320     g_print("\ntest 3 ;)\n");
321     #endif
322   }
323   else if (get_prev_button() == Button_add ||
324            get_prev_button() == Button_sub ||
325            get_prev_button() == Button_multi ||
326            get_prev_button() == Button_div )
327   {
328     test = 4;
329     #ifdef DEBUG 
330     g_print("\ntest 4 ;)\n");
331     #endif
332   }
333   
334   switch (test)
335   {
336     case 1:
337       if (get_is_value1())
338         del_value1();
339       if (get_is_value2())
340         del_value2();
341       
342       set_operation(NoSelectOprt);
343       set_prev_operation(NoSelectOprt);
344       set_is_result(FALSE);
345       set_prev_button(NoSelectBtn);
346     
347       gtk_entry_set_text(GTK_ENTRY(entry),"");
348       len = strlen(GTK_ENTRY(entry)->text);
349       gtk_editable_insert_text(GTK_EDITABLE(entry),number,1,&len);
350       
351       break;
352     
353     case 2:
354       gtk_entry_set_text(GTK_ENTRY(entry),"");
355       set_is_result(FALSE);
356       
357       len = strlen(GTK_ENTRY(entry)->text);
358       gtk_editable_insert_text(GTK_EDITABLE(entry),number,1,&len);
359       
360       break;
361     
362     case 3:
363       len = strlen(GTK_ENTRY(entry)->text);
364       gtk_editable_insert_text(GTK_EDITABLE(entry),number,1,&len);
365       
366       set_value1(gtk_entry_get_text(GTK_ENTRY(entry)));
367       
368       break;
369     
370     case 4:
371       gtk_entry_set_text(GTK_ENTRY(entry),"");
372       
373       len = strlen(GTK_ENTRY(entry)->text);
374       gtk_editable_insert_text(GTK_EDITABLE(entry),number,1,&len);
375       set_is_result(FALSE);
376     
377       break;
378     
379     default:
380       len = strlen(GTK_ENTRY(entry)->text);
381       gtk_editable_insert_text(GTK_EDITABLE(entry),number,1,&len);
382   }
383   
384   set_prev_button(button);
385   #ifdef DEBUG
386   __debug("GUIKalkulator _numeric_btn_clicked_event()",true);
387   #endif
388 }
389 
390 void GUIKalkulator::_calculate_btn_clicked_event(operation_id operation)
391 {
392   #ifdef INFO 
393   __debug("GUIKalkulator _calculate_btn_clicked_event()",false);
394   g_print("clicked: %s\n",_operation_id_to_char(operation));
395   #endif
396   
397   gint8 test = 0,
398         prev_operation_tmp = FALSE;
399   gchar *text_entry = GTK_ENTRY(entry)->text;
400   
401   // +,-,*,/
402   set_operation(operation);
403 
404   // test
405   if (get_is_value1() == FALSE && 
406       get_is_value2() == FALSE &&
407       strlen(text_entry) > 0)
408   {
409     // nalezy ustawić value1
410     test = 1;
411     #ifdef DEBUG
412     g_print("\ntest 1\n");
413     #endif
414   }
415   else if (get_is_value1() == TRUE && 
416            get_is_value2() == FALSE &&
417            strlen(text_entry) > 0 &&
418            get_prev_button() != Button_add &&
419            get_prev_button() != Button_sub &&
420            get_prev_button() != Button_multi &&
421            get_prev_button() != Button_div &&
422            get_prev_button() != Button_result &&
423            get_prev_button() != Button_back && // po <- * zle!
424            (get_button_cache_comma()!= Button_comma || get_button_cache_result() != Button_result) && // ,
425            ((get_prev_button() == Button_signed && get_button_cache_result() != Button_result) ||     // -/+
426             get_prev_button() != Button_signed)
427           )
428   {  
429     test = 2;
430     #ifdef DEBUG
431     g_print("\ntest 2\n");
432     #endif
433   }
434   else if (get_button_cache_result() == Button_result && 
435            get_prev_button() == Button_back) 
436   {
437     set_value1(gtk_entry_get_text(GTK_ENTRY(entry)));
438   }
439 
440   switch (test)
441   {
442     case 1:
443       set_value1(gtk_entry_get_text(GTK_ENTRY(entry)));
444       gtk_entry_set_text(GTK_ENTRY(entry),"");
445       break;
446 
447     case 2:
448       set_value2(gtk_entry_get_text(GTK_ENTRY(entry)));
449       #ifdef DEBUG
450       g_print("\nval1: %s",get_value1());
451       g_print("\nval2: %s",get_value2());
452       #endif
453       // gdy po wielokrotnych operacji następuje zmiana
454       // wynik obliczyć według poprzednio wybranej operacji
455       // np. 5 + 5 (10)- 5 = 15
456       if (get_operation() != get_prev_operation())
457         prev_operation_tmp = TRUE;
458 
459       calculate(prev_operation_tmp);
460       del_value2();
461       /*
462        *  kalkulator->value1 (wynik)
463        *  kalkulator->value2 (puste)
464        */
465       set_is_result(true);
466       gtk_entry_set_text(GTK_ENTRY(entry), get_value1());
467       set_button_cache_result(Button_result);
468       break;
469   }
470 
471   set_prev_button(_operation_id_to_btn_id(operation));
472   
473   set_button_cache_comma(NoSelectBtn);
474   set_button_cache_result(NoSelectBtn);
475   
476   // zabezpiecza nas przed tym: 
477   // np. 1 + 5 * daje w wyniku 5 ponieważ wykonał rodzaj operacji 
478   // domyślny dla obecnie (statnlio) wciśniętego przycisku, czyli *
479   set_prev_operation(get_operation());
480   
481   #ifdef DEBUG
482   __debug("GUIKalkulator _calculate_btn_clicked_event()",true);
483   #endif
484 }
485 
486 void GUIKalkulator::btn_1_clicked(GtkWidget *widget, gpointer data)
487 {
488   GUIKalkulator *gui_kalkulator = static_cast<GUIKalkulator*>(data);
489   gui_kalkulator->_numeric_btn_clicked_event(Button_1, NULL);
490 }
491 
492 void GUIKalkulator::btn_2_clicked(GtkWidget *widget, gpointer data)
493 {
494   GUIKalkulator *gui_kalkulator = static_cast<GUIKalkulator*>(data);
495   gui_kalkulator->_numeric_btn_clicked_event(Button_2, NULL);
496 }
497 
498 void GUIKalkulator::btn_3_clicked(GtkWidget *widget, gpointer data)
499 {
500   GUIKalkulator *gui_kalkulator = static_cast<GUIKalkulator*>(data);
501   gui_kalkulator->_numeric_btn_clicked_event(Button_3, NULL);
502 }
503 
504 void GUIKalkulator::btn_4_clicked(GtkWidget *widget, gpointer data)
505 {
506   GUIKalkulator *gui_kalkulator = static_cast<GUIKalkulator*>(data);
507   gui_kalkulator->_numeric_btn_clicked_event(Button_4, NULL);
508 }
509 
510 void GUIKalkulator::btn_5_clicked(GtkWidget *widget, gpointer data)
511 {
512   GUIKalkulator *gui_kalkulator = static_cast<GUIKalkulator*>(data);
513   gui_kalkulator->_numeric_btn_clicked_event(Button_5, NULL);
514 }
515 
516 void GUIKalkulator::btn_6_clicked(GtkWidget *widget, gpointer data)
517 {
518   GUIKalkulator *gui_kalkulator = static_cast<GUIKalkulator*>(data);
519   gui_kalkulator->_numeric_btn_clicked_event(Button_6, NULL);
520 }
521 
522 void GUIKalkulator::btn_7_clicked(GtkWidget *widget, gpointer data)
523 {
524   GUIKalkulator *gui_kalkulator = static_cast<GUIKalkulator*>(data);
525   gui_kalkulator->_numeric_btn_clicked_event(Button_7, NULL);
526 }
527 
528 void GUIKalkulator::btn_8_clicked(GtkWidget *widget, gpointer data)
529 {
530   GUIKalkulator *gui_kalkulator = static_cast<GUIKalkulator*>(data);
531   gui_kalkulator->_numeric_btn_clicked_event(Button_8, NULL);
532 }
533 
534 void GUIKalkulator::btn_9_clicked(GtkWidget *widget, gpointer data)
535 {
536   GUIKalkulator *gui_kalkulator = static_cast<GUIKalkulator*>(data);
537   gui_kalkulator->_numeric_btn_clicked_event(Button_9, NULL);
538 }
539 
540 void GUIKalkulator::btn_0_clicked(GtkWidget *widget, gpointer data)
541 {
542   GUIKalkulator *gui_kalkulator = static_cast<GUIKalkulator*>(data);
543   gui_kalkulator->_numeric_btn_clicked_event(Button_0, NULL);
544 }
545 
546 void GUIKalkulator::btn_comma_clicked(GtkWidget *widget, gpointer data)
547 {
548   GUIKalkulator *gui_kalkulator = static_cast<GUIKalkulator*>(data);
549   int len(0);
550   
551   #ifdef INFO 
552   gui_kalkulator->__debug("GUIKalkulator clicked: ,",false);
553   #endif
554   bool cachecomma = false;
555   
556   if (gui_kalkulator->get_button_cache_comma()!= Button_comma)
557   {
558     if (strlen(GTK_ENTRY(gui_kalkulator->entry)->text) != 0)
559     {
560       len = strlen(GTK_ENTRY(gui_kalkulator->entry)->text);
561       gtk_editable_insert_text(GTK_EDITABLE(gui_kalkulator->entry),",",1,&len);
562       
563       // synchronizacja wyniku (value1) ze zmianami na wyświetlaczu 
564       if (gui_kalkulator->get_is_result() && 
565           gui_kalkulator->get_prev_button() == Button_result)
566       {
567         gui_kalkulator->set_value1(gtk_entry_get_text(GTK_ENTRY(gui_kalkulator->entry)));
568         gui_kalkulator->set_is_result(FALSE); // to już nie jest wynik, to nowa wartość! ale potrzebne aby poszło do value2
569       }
570       cachecomma = true;
571     }
572     else
573     {
574       gui_kalkulator->dialog = gtk_message_dialog_new(GTK_WINDOW(gui_kalkulator->mainwindow),
575                                     GTK_DIALOG_MODAL,GTK_MESSAGE_WARNING,GTK_BUTTONS_OK,
576                                     "Przecinek nie może być wprowadzony jako pierwszy!\nPowinien wystepować po liczbie.");
577       gtk_dialog_run (GTK_DIALOG (gui_kalkulator->dialog));
578       gtk_widget_destroy (gui_kalkulator->dialog);
579     }
580   }
581   else
582   {
583     gui_kalkulator->dialog = gtk_message_dialog_new(GTK_WINDOW(gui_kalkulator->mainwindow),
584                                     GTK_DIALOG_MODAL,GTK_MESSAGE_WARNING,GTK_BUTTONS_OK,
585                                     "Wprowadzona liczba zawiera już przecinek!\nNie można wprowadzić przecinka drugi raz.");
586     gtk_dialog_run (GTK_DIALOG (gui_kalkulator->dialog));
587     gtk_widget_destroy (gui_kalkulator->dialog);
588   }
589   
590   if (cachecomma)
591     gui_kalkulator->set_button_cache_comma(Button_comma);
592   
593   gui_kalkulator->set_prev_button(Button_comma);
594   #ifdef DEBUG
595   gui_kalkulator->__debug("GUIKalkulator btn_comma_clicked()",true);
596   #endif
597 }
598 
599 void GUIKalkulator::btn_back_clicked(GtkWidget *widget, gpointer data)
600 {
601   GUIKalkulator *gui_kalkulator = static_cast<GUIKalkulator*>(data);
602   GString *tmp=NULL;
603   #ifdef INFO 
604   gui_kalkulator->__debug("GUIKalkulator clicked: <-",false);
605   #endif
606   tmp = g_string_new(gtk_entry_get_text(GTK_ENTRY(gui_kalkulator->entry)));
607   tmp = g_string_truncate(tmp,tmp->len-1);
608   gtk_entry_set_text(GTK_ENTRY(gui_kalkulator->entry), g_string_free(tmp,FALSE));
609   
610   // synchronizacja wyniku (value1) ze zmianami na wyświetlaczu 
611   if (gui_kalkulator->get_is_result())
612   {
613     gui_kalkulator->set_is_result(FALSE); // to już nie jest wynik, to nowa wartość!
614   }
615   
616   gui_kalkulator->set_prev_button(Button_back);
617 }
618 
619 void GUIKalkulator::btn_clear_clicked(GtkWidget *widget, gpointer data)
620 {
621   GUIKalkulator *gui_kalkulator = static_cast<GUIKalkulator*>(data);
622   #ifdef INFO 
623   gui_kalkulator->__debug("GUIKalkulator clicked: C",false);
624   #endif
625   if (gui_kalkulator->get_is_value1())
626     gui_kalkulator->del_value1(); 
627   if (gui_kalkulator->get_is_value2())
628     gui_kalkulator->del_value2(); 
629   
630   gui_kalkulator->set_operation(NoSelectOprt);
631   gui_kalkulator->set_prev_operation(NoSelectOprt);
632   gui_kalkulator->set_is_result(FALSE);
633   gui_kalkulator->set_prev_button(NoSelectBtn);
634   gui_kalkulator->set_button_cache_comma(NoSelectBtn);
635   gui_kalkulator->set_button_cache_result(NoSelectBtn);
636   
637   gtk_entry_set_text(GTK_ENTRY(gui_kalkulator->entry),"");
638 
639   gui_kalkulator->set_prev_button(Button_clear);
640   
641   #ifdef DEBUG
642   gui_kalkulator->__debug("GUIKalkulator clicked: C",true);
643   #endif
644 }
645 
646 void GUIKalkulator::btn_add_clicked(GtkWidget *widget, gpointer data)
647 {
648   static_cast<GUIKalkulator*>(data)->_calculate_btn_clicked_event(Add);
649 }
650 
651 void GUIKalkulator::btn_sub_clicked(GtkWidget *widget, gpointer data)
652 {
653   static_cast<GUIKalkulator*>(data)->_calculate_btn_clicked_event(Sub);
654 }
655 
656 void GUIKalkulator::btn_multi_clicked(GtkWidget *widget, gpointer data)
657 {
658   static_cast<GUIKalkulator*>(data)->_calculate_btn_clicked_event(Multi);
659 }
660 
661 void GUIKalkulator::btn_div_clicked(GtkWidget *widget, gpointer data)
662 {
663   static_cast<GUIKalkulator*>(data)->_calculate_btn_clicked_event(Div);
664 }
665 
666 void GUIKalkulator::btn_result_clicked(GtkWidget *widget, gpointer data)
667 {
668   GUIKalkulator *gui_kalkulator = static_cast<GUIKalkulator*>(data);
669   gchar *text_entry = GTK_ENTRY(gui_kalkulator->entry)->text;
670   #ifdef INFO 
671   gui_kalkulator->__debug("GUIKalkulator clicked: =",false);
672   #endif
673 
674   if (gui_kalkulator->get_is_value1() == TRUE && 
675       gui_kalkulator->get_is_value2() == FALSE &&
676       strlen (text_entry) > 0 &&
677       gui_kalkulator->get_prev_button() != Button_add &&
678       gui_kalkulator->get_prev_button() != Button_sub &&
679       gui_kalkulator->get_prev_button() != Button_multi &&
680       gui_kalkulator->get_prev_button() != Button_div &&
681       gui_kalkulator->get_prev_button() != Button_result &&
682       gui_kalkulator->get_prev_button() != Button_comma )
683   {
684     gui_kalkulator->set_value2(gtk_entry_get_text(GTK_ENTRY(gui_kalkulator->entry)));
685     
686     gui_kalkulator->calculate(FALSE);
687     gui_kalkulator->del_value2();
688     /*
689      *  kalkulator->value1 (wynik)
690      *  kalkulator->value2 (puste)
691      */
692     
693     gtk_entry_set_text(GTK_ENTRY(gui_kalkulator->entry), gui_kalkulator->get_value1());
694     gui_kalkulator->set_button_cache_result(Button_result);
695   }
696   
697   gui_kalkulator->set_prev_button(Button_result);
698   
699   gui_kalkulator->set_button_cache_comma(NoSelectBtn);
700   
701   #ifdef DEBUG
702   gui_kalkulator->__debug("GUIKalkulator clicked: =",true); 
703   #endif
704 }
705 
706 void GUIKalkulator::btn_signed_clicked(GtkWidget *widget, gpointer data)
707 {
708   GUIKalkulator *gui_kalkulator = static_cast<GUIKalkulator*>(data);
709   int *pos = new int(0);
710   #ifdef INFO 
711   gui_kalkulator->__debug("GUIKalkulator clicked: -/+",false);
712   #endif
713   
714   char *sig = gtk_editable_get_chars(GTK_EDITABLE(gui_kalkulator->entry),0,1);
715   
716   if (strcmp(sig,"-")) // 0 == equal
717     gtk_editable_insert_text(GTK_EDITABLE(gui_kalkulator->entry),"-",1,pos);
718   else
719     gtk_editable_delete_text(GTK_EDITABLE(gui_kalkulator->entry),0,1);
720   
721   // synchronizacja wyniku (value1) ze zmianami na wyświetlaczu 
722   //if (gui_kalkulator->get_is_result()) // checkit!
723   {
724     gui_kalkulator->set_value1(gtk_entry_get_text(GTK_ENTRY(gui_kalkulator->entry)));
725   }
726 
727   g_free(sig);
728   gui_kalkulator->set_prev_button(Button_signed);
729   #ifdef DEBUG
730   gui_kalkulator->__debug("GUIKalkulator clicked: -/+",true); 
731   #endif
732 }
733 
734 void GUIKalkulator::btn_addmem_clicked(GtkWidget *widget, gpointer data)
735 {
736   GUIKalkulator *gui_kalkulator = static_cast<GUIKalkulator*>(data);
737   #ifdef INFO 
738   gui_kalkulator->__debug("GUIKalkulator clicked: M+",false);
739   #endif
740   
741   if (strlen(GTK_ENTRY(gui_kalkulator->entry)->text) == 0)
742   {
743     gui_kalkulator->dialog = gtk_message_dialog_new(GTK_WINDOW(gui_kalkulator->mainwindow),
744                                     GTK_DIALOG_MODAL,GTK_MESSAGE_WARNING,GTK_BUTTONS_OK,
745                                     "Brak wartości do wprowadzenia!\nWyświetlacz jest pusty.");
746     gtk_dialog_run (GTK_DIALOG (gui_kalkulator->dialog));
747     gtk_widget_destroy (gui_kalkulator->dialog);
748   }
749   else
750   {
751     gui_kalkulator->add_to_memory(gtk_entry_get_text(GTK_ENTRY(gui_kalkulator->entry)));
752     gtk_combo_box_append_text(GTK_COMBO_BOX(gui_kalkulator->comboreadmem),gtk_entry_get_text(GTK_ENTRY(gui_kalkulator->entry)));
753     gui_kalkulator->combocount++;
754     gtk_widget_set_sensitive(gui_kalkulator->buttonclearmem,TRUE);
755     gtk_widget_set_sensitive(gui_kalkulator->comboreadmem,TRUE);
756   }
757     
758   gui_kalkulator->set_prev_button(Button_addmem);
759   #ifdef DEBUG
760   gui_kalkulator->__debug("GUIKalkulator clicked: M+",true); 
761   
762   if (gui_kalkulator->memory_count() == gui_kalkulator->combocount-1) // -pierwsza pozycja nie bedąca liczbą
763   {
764     cout << "\nIlość elementów listy zgadza się z ilością elementów w combobox" << endl
765          << "combocount: " << gui_kalkulator->combocount << endl
766          << "memory_count(): " << gui_kalkulator->memory_count() << endl;
767   }
768   else
769     cout << "\nIlość elementów listy NIE zgadza się z ilością elementów w combobox" << endl;
770   
771   #endif
772 }
773 
774 void GUIKalkulator::btn_readmem_clicked(GtkWidget *widget, gpointer data)
775 {
776   GUIKalkulator *gui_kalkulator = static_cast<GUIKalkulator*>(data);
777   #ifdef INFO 
778   gui_kalkulator->__debug("GUIKalkulator clicked: readmem",false);
779   #endif
780   gchar *select;
781   select = gtk_combo_box_get_active_text(GTK_COMBO_BOX(gui_kalkulator->comboreadmem));
782   if (select[0] != 'C' && select[1] != 'z' && select[2] != 'y')
783   {
784     if ((strlen(GTK_ENTRY(gui_kalkulator->entry)->text) == 0) ||
785         (strlen(GTK_ENTRY(gui_kalkulator->entry)->text) != 0 &&
786         (gui_kalkulator->get_prev_button() == Button_add ||
787         gui_kalkulator->get_prev_button() == Button_sub ||
788         gui_kalkulator->get_prev_button() == Button_multi ||
789         gui_kalkulator->get_prev_button() == Button_div)))
790     {
791       gtk_entry_set_text(GTK_ENTRY(gui_kalkulator->entry),select);
792       g_free(select);
793       // umożliwia wybranie drugi raz tej samej liczby
794       gtk_combo_box_set_active(GTK_COMBO_BOX(gui_kalkulator->comboreadmem),0);
795       gtk_widget_set_sensitive(gui_kalkulator->comboreadmem,TRUE);
796     }
797     else
798     {
799       gui_kalkulator->dialog = gtk_message_dialog_new(GTK_WINDOW(gui_kalkulator->mainwindow),
800                                     GTK_DIALOG_MODAL,GTK_MESSAGE_WARNING,GTK_BUTTONS_OK,
801       "Wprowadzono już liczbę!\nJeżeli nie jest to kolejna liczba następująca po działaniu (+,-,*,/) wyświetlacz musi być pusty.");
802       gtk_dialog_run (GTK_DIALOG (gui_kalkulator->dialog));
803       gtk_widget_destroy (gui_kalkulator->dialog);
804       // umożliwia wybranie drugi raz tej samej liczby
805       gtk_combo_box_set_active(GTK_COMBO_BOX(gui_kalkulator->comboreadmem),0);
806       gtk_widget_set_sensitive(gui_kalkulator->comboreadmem,TRUE);
807     }
808   }
809   
810   gui_kalkulator->set_prev_button(Button_readmem);
811   #ifdef DEBUG
812   gui_kalkulator->__debug("GUIKalkulator clicked: -/+",true); 
813   #endif
814 }
815 
816 void GUIKalkulator::btn_clearmem_clicked(GtkWidget *widget, gpointer data)
817 {
818   GUIKalkulator *gui_kalkulator = static_cast<GUIKalkulator*>(data);
819   #ifdef INFO 
820   gui_kalkulator->__debug("GUIKalkulator clicked: MC",false);
821   #endif
822   
823   gui_kalkulator->memory_free();
824   // combocoun liczone od 1
825   // index w funkcji od 0
826   // dlatego pozwalamy sobie na natychmiastowe zmniejszenie --combocount
827   gtk_combo_box_set_active(GTK_COMBO_BOX(gui_kalkulator->comboreadmem),0); 
828   // zapobiega naruszeniu pamięci
829   while(gui_kalkulator->combocount>1)
830     gtk_combo_box_remove_text(GTK_COMBO_BOX(gui_kalkulator->comboreadmem),--gui_kalkulator->combocount);
831   
832   gtk_widget_set_sensitive(gui_kalkulator->buttonclearmem,FALSE);
833   gtk_widget_set_sensitive(gui_kalkulator->comboreadmem,FALSE);
834   
835   gui_kalkulator->set_prev_button(Button_clearmem);
836   #ifdef DEBUG
837   gui_kalkulator->__debug("GUIKalkulator clicked: MC",true); 
838   #endif
839 }
840 
841 void GUIKalkulator::menu_item_close(GtkMenuItem *menuitem, gpointer data)
842 {
843   //GUIKalkulator *gui_kalkulator = static_cast<GUIKalkulator*>(data);
844   #ifdef INFO 
845   //gui_kalkulator->__debug("GUIKalkulator: MENU->close",false);
846   static_cast<GUIKalkulator*>(data)->__debug("GUIKalkulator: MENU->close",false);
847   #endif
848   gtk_main_quit();
849 }
850 
851 void GUIKalkulator::menu_item_help(GtkMenuItem *menuitem, gpointer data)
852 {
853   GUIKalkulator *gui_kalkulator = static_cast<GUIKalkulator*>(data);
854   #ifdef INFO 
855   gui_kalkulator->__debug("GUIKalkulator: MENU->about",false);
856   #endif
857   
858   static const gchar *authors = "Grzegorz Kuczyński <gk180984@interia.pl>";
859   static const gchar comments[] = "Jest to program demonstracyjny, \nnapisany w celach edukacyjnych GTK+.\n\nPo prostu dla zabawy :)";
860   static const gchar copyright[] = "Copyright \xc2\xa9 2009 Grzegorz Kuczyńśki\n";
861   
862   gui_kalkulator->dialog = gtk_about_dialog_new();
863   gtk_about_dialog_set_program_name(GTK_ABOUT_DIALOG(gui_kalkulator->dialog),"Kalkulator");
864   gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(gui_kalkulator->dialog),"0.0.1");
865   gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(gui_kalkulator->dialog),comments);
866   gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(gui_kalkulator->dialog),&authors);
867   gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(gui_kalkulator->dialog),copyright);
868   gtk_dialog_run (GTK_DIALOG (gui_kalkulator->dialog));
869 
870   gtk_widget_destroy (gui_kalkulator->dialog);
871 }
872 
873 gboolean GUIKalkulator::mainwindow_key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
874 {
875   GUIKalkulator *gui_kalkulator = static_cast<GUIKalkulator*>(data);
876   #ifdef INFO 
877   gui_kalkulator->__debug("GUIKalkulator: key press",false);
878   #endif
879   
880   GdkEvent ev;
881   ev.key.keyval = event->keyval;
882   
883   // Można by było tak...
884   /**********************
885   switch(event->keyval)
886   {
887     case GDK_KP_0: gui_kalkulator->_numeric_btn_clicked_event(Button_0,NULL); break;
888     case GDK_KP_1: gui_kalkulator->_numeric_btn_clicked_event(Button_1,NULL); break;
889     case GDK_KP_2: gui_kalkulator->_numeric_btn_clicked_event(Button_2,NULL); break;
890     case GDK_KP_3: gui_kalkulator->_numeric_btn_clicked_event(Button_3,NULL); break;
891     case GDK_KP_4: gui_kalkulator->_numeric_btn_clicked_event(Button_4,NULL); break;
892     case GDK_KP_5: gui_kalkulator->_numeric_btn_clicked_event(Button_5,NULL); break;
893     case GDK_KP_6: gui_kalkulator->_numeric_btn_clicked_event(Button_6,NULL); break;
894     case GDK_KP_7: gui_kalkulator->_numeric_btn_clicked_event(Button_7,NULL); break;
895     case GDK_KP_8: gui_kalkulator->_numeric_btn_clicked_event(Button_8,NULL); break;
896     case GDK_KP_9: gui_kalkulator->_numeric_btn_clicked_event(Button_9,NULL); break;
897     case GDK_KP_Add: gui_kalkulator->_calculate_btn_clicked_event(Add); break;
898     case GDK_KP_Divide: gui_kalkulator->_calculate_btn_clicked_event(Div); break;
899     case GDK_KP_Subtract: gui_kalkulator->_calculate_btn_clicked_event(Sub); break;
900     case GDK_KP_Multiply: gui_kalkulator->_calculate_btn_clicked_event(Multi); break;
901     case GDK_KP_Enter: gui_kalkulator->btn_result_clicked(gui_kalkulator->buttonresult,gui_kalkulator); break;
902     case GDK_comma: gui_kalkulator->btn_comma_clicked(gui_kalkulator->buttoncomma,gui_kalkulator); break;
903     case GDK_BackSpace: gui_kalkulator->btn_back_clicked(gui_kalkulator->buttonback,gui_kalkulator); break;
904   }
905   **********************/
906   // ...ale trzeba by było w każdym wypadku ustawić wszystkie zmienne typu set_prev_button itp
907   // ponieważ wszystkie obliczenia i sterowanie opiera się na informacjach zawartych
908   // własnie w tych zmienneych.
909   //
910   // Tak jest lepiej ponieważ symulujemy wciśnięcie tych przycisków, tak jak byśmy je wciskali 
911   // sami, więc nie trzeba się martwić przepływem sterowania.
912   switch(event->keyval)
913   {
914     case GDK_KP_0: g_signal_emit_by_name(G_OBJECT(gui_kalkulator->button0),"clicked");break;
915     case GDK_KP_1: g_signal_emit_by_name(G_OBJECT(gui_kalkulator->button1),"clicked");break;
916     case GDK_KP_2: g_signal_emit_by_name(G_OBJECT(gui_kalkulator->button2),"clicked");break;
917     case GDK_KP_3: g_signal_emit_by_name(G_OBJECT(gui_kalkulator->button3),"clicked");break;
918     case GDK_KP_4: g_signal_emit_by_name(G_OBJECT(gui_kalkulator->button4),"clicked");break;
919     case GDK_KP_5: g_signal_emit_by_name(G_OBJECT(gui_kalkulator->button5),"clicked");break;
920     case GDK_KP_6: g_signal_emit_by_name(G_OBJECT(gui_kalkulator->button6),"clicked");break;
921     case GDK_KP_7: g_signal_emit_by_name(G_OBJECT(gui_kalkulator->button7),"clicked");break;
922     case GDK_KP_8: g_signal_emit_by_name(G_OBJECT(gui_kalkulator->button8),"clicked");break;
923     case GDK_KP_9: g_signal_emit_by_name(G_OBJECT(gui_kalkulator->button9),"clicked");break;
924     case GDK_KP_Add: g_signal_emit_by_name(G_OBJECT(gui_kalkulator->buttonadd),"clicked");break;
925     case GDK_KP_Divide: g_signal_emit_by_name(G_OBJECT(gui_kalkulator->buttondiv),"clicked");break;
926     case GDK_KP_Subtract: g_signal_emit_by_name(G_OBJECT(gui_kalkulator->buttonsub),"clicked");break;
927     case GDK_KP_Multiply: g_signal_emit_by_name(G_OBJECT(gui_kalkulator->buttonmulti),"clicked");break;
928     case GDK_KP_Enter: g_signal_emit_by_name(G_OBJECT(gui_kalkulator->buttonresult),"clicked");break;
929     case GDK_KP_Separator: g_signal_emit_by_name(G_OBJECT(gui_kalkulator->buttoncomma),"clicked");break;
930     case GDK_BackSpace: g_signal_emit_by_name(G_OBJECT(gui_kalkulator->buttonback),"clicked");break;
931   }
932   
933   return true;
934 }