GTK+/Kalkulator 0.0.1 - kalkulator.cpp
< GTK+
#include <stdlib.h>
#include <string>
#include <iostream>
#include <sstream>
#include <locale>
#include "kalkulator.hpp"
//#define DEBUG
//#define INFO
//#define NEW_VERSION_CALCULATE
//#define WIN
using namespace std;
Kalkulator::Kalkulator()
{
#ifdef INFO
__debug("Kalkulator konstruktor",false);
#endif
value1 = NULL;
value2 = NULL;
operation = NoSelectOprt;
prev_operation = NoSelectOprt;
is_value1 = FALSE;
is_value2 = FALSE;
is_result = FALSE;
prev_button = NoSelectBtn;
button_cache_comma = NoSelectBtn;
button_cache_result = NoSelectBtn;
memory = NULL;
}
Kalkulator::~Kalkulator()
{
#ifdef INFO
__debug("Kalkulator destruktor",false);
#endif
memory_free();
}
const char* Kalkulator::_btn_id_to_char(btn_id val)
{
return val==Button_1 ? "1" :
val==Button_2 ? "2" :
val==Button_3 ? "3" :
val==Button_4 ? "4" :
val==Button_5 ? "5" :
val==Button_6 ? "6" :
val==Button_7 ? "7" :
val==Button_8 ? "8" :
val==Button_9 ? "9" :
val==Button_0 ? "0" :
val==Button_add ? "Button_add" :
val==Button_sub ? "Button_sub" :
val==Button_multi ? "Button_multi" :
val==Button_div ? "Button_div" :
val==Button_result ? "Button_result" :
val==Button_comma ? "Button_comma" :
val==Button_back ? "Button_back" :
val==Button_clear ? "Button_clear" :
val==Button_signed ? "Button_signed" :
val==Button_addmem ? "Button_addmem" :
val==Button_readmem ? "Button_readmem" :
val==Button_clearmem ? "Button_clearmem" :
"NoSelectBtn(22)";
}
const char* Kalkulator::_operation_id_to_char(operation_id val)
{
return val==Add ? "+" :
val==Sub ? "-" :
val==Multi ? "*" :
val==Div ? "/" :
"NoSelectOprt(5)";
}
btn_id Kalkulator::_operation_id_to_btn_id(operation_id val)
{
return val==Add ? Button_add :
val==Sub ? Button_sub :
val==Multi ? Button_multi :
val==Div ? Button_div :
NoSelectBtn;
}
void Kalkulator::__debug(const gchar* event, bool data)
{
if (data)
{
printf (
"\n ===================[DEBUG]=====================\n \
event: %s \n \
- - - - -\n \
Struktura:\n \
value1: %s \n \
value2: %s \n \
operation: %s \n \
prev_operation: %s \n \
is_value1: %s \n \
is_value2: %s \n \
is_result: %s \n \
prev_button: %s \n \
button_cahce_comma: %s \n \
button_cahce_result: %s \n \
memory: %s \n \
===============================================\n\n\n",
event,
is_value1? value1->str :"",
is_value2? value2->str :"",
_operation_id_to_char(operation),
_operation_id_to_char(prev_operation),
is_value1?"TRUE":"FALSE",
is_value2?"TRUE":"FALSE",
is_result?"TRUE":"FALSE",
_btn_id_to_char(prev_button),
_btn_id_to_char(button_cache_comma),
_btn_id_to_char(button_cache_result),
memory? "TRUE": "NULL");
if (memory)
{
cout << "Spis liczb w pamięci:" << endl;
memory_print();
cout << endl;
}
}
else
cout << event << endl;
}
#ifndef NEW_VERSION_CALCULATE
void Kalkulator::calculate(bool prev_operation_priv)
{
#ifndef WIN
long double d_value1=0,
#else
double d_value1=0,
#endif
d_value2=0,
d_result=0;
int len, test(0);
char s_result[50];
string ss_result;
bool is_comma(false);
d_value1 = strtod( value1->str, NULL );
d_value2 = strtod( value2->str, NULL );
if (prev_operation_priv)
{
test = prev_operation==Add ? 1 :
prev_operation==Sub ? 2 :
prev_operation==Multi ? 3 :
prev_operation==Div ? 4 :
NoSelectOprt;
}
else
{
test = operation==Add ? 1 :
operation==Sub ? 2 :
operation==Multi ? 3 :
operation==Div ? 4 :
NoSelectOprt;
}
switch(test)
{
case 1:
d_result = d_value1 + d_value2;
break;
case 2:
d_result = d_value1 - d_value2;
break;
case 3:
d_result = d_value1 * d_value2;
break;
case 4:
if ( d_value2 != 0.0 )
d_result = d_value1 / d_value2;
else
d_result = d_value1;
break;
case 5:
// Checkit!
break;
}
len = sprintf( s_result, "%Lf", d_result );
// można to spr.
// if ( !len ) ...
ss_result = s_result;
for (unsigned int i=0; i < ss_result.length(); i++)
{
if (ss_result[i] == ',')
{
is_comma = true;
#ifdef DEBUG
cout << "\nis comma\n";
#endif
break;
}
}
// tylko ,
if (is_comma)
{
// usuwamy końcowe 0
while (ss_result[ss_result.length()-1] == '0')
ss_result.erase((ss_result.length()-1),1);
// usuwamy przecinek jeżeli za nim byo same 0
if (ss_result[ss_result.length()-1] == ',')
ss_result.erase((ss_result.length()-1),1);
}
set_value1(ss_result.c_str());
set_is_result(true);
#ifdef DEBUG
printf ("calculateby to %Lg , %Lg wynik to: %Lg \n",d_value1,d_value2,d_result);
#endif
}
#endif
#ifdef NEW_VERSION_CALCULATE
void Kalkulator::calculate(bool prev_operation_priv)
{
#ifndef WIN
long double d_value1=0,
#else
double d_value1=0,
#endif
d_value2=0,
d_result=0;
cout << "long double: " << sizeof(long double) << endl;
cout << "float: " << sizeof(float) << endl;
cout << "long: " << sizeof(long) << endl;
bool is_comma(false);
int len, test(0);
string s_result, s1, s2;
//string str1 = value1->str, str2 = value2->str;
istringstream str1;
istringstream str2;
ostringstream rst;
//s1.imbue(locale("pl_PL"));
//s2.imbue(locale("pl_PL"));
str1.str(value1->str);
str2.str(value2->str);
s1 = str1.str();
s2 = str2.str();
for (unsigned int i=0; i < s1.length(); i++)
{
if (s1[i] == '.')
{
s1.replace(i,1,1,',');
//is_comma = true;
break;
}
}
for (unsigned int i=0; i < s2.length(); i++)
{
if (s2[i] == '.')
{
s2.replace(i,1,1,',');
//is_comma = true;
break;
}
}
str1.str(s1);
str2.str(s1);
// char* -> double
str1 >> d_value1;
//str2 >> fixed >> dec >> d_value2;
str2 >> d_value2;
str1 >> s1;
str2 >> s2;
cout << "\nval1: " << d_value1 << " s1: " << s1 << endl;
cout << "\nval2: " << d_value2 << " s2: " << s2 << endl;
cout << "\n s1: " << s1 << " s2: " << s2 << endl;
if (prev_operation_priv)
{
test = prev_operation==Add ? 1 :
prev_operation==Sub ? 2 :
prev_operation==Multi ? 3 :
prev_operation==Div ? 4 :
NoSelectOprt;
}
else
{
test = operation==Add ? 1 :
operation==Sub ? 2 :
operation==Multi ? 3 :
operation==Div ? 4 :
NoSelectOprt;
}
switch(test)
{
case 1:
d_result = d_value1 + d_value2;
break;
case 2:
d_result = d_value1 - d_value2;
break;
case 3:
d_result = d_value1 * d_value2;
break;
case 4:
if ( d_value2 != 0.0 )
d_result = d_value1 / d_value2;
else
d_result = d_value1;
break;
case 5:
// Checkit!
break;
}
rst << fixed << dec << d_result;
s_result = rst.str();
cout << "\n s_result: " << s_result << endl;
//for (unsigned int i=0; i < s_result.length(); i++)
//{
// if (s_result[i] == '.')
// {
// s_result.replace(i,1,1,',');
// is_comma = true;
// break;
// }
//}
for (unsigned int i=0; i < s_result.length(); i++)
{
if (s_result[i] == ',')
{
is_comma = true;
break;
}
}
cout << "\n s_result: " << s_result << endl;
if (is_comma)
{
// usuwamy końcowe 0
while (s_result[s_result.length()-1] == '0')
s_result.erase((s_result.length()-1),1);
// usuwamy przecinek jeżeli za nim byo same 0
if (s_result[s_result.length()-1] == ',')
s_result.erase((s_result.length()-1),1);
}
set_value1(s_result.c_str());
set_is_result(true);
#ifdef DEBUG
cout << "\nval1: " << d_value1 << " val2: " << d_value2 << " rst: " << d_result << endl;
#endif
}
#endif
char* Kalkulator::get_value1()
{
if (is_value1)
return value1->str;
else
return NULL;
}
void Kalkulator::set_value1(const gchar *val)
{
if (is_value1)
{
g_string_free(value1,TRUE);
value1 = g_string_new(val);
}
else
{
value1 = g_string_new(val);
is_value1 = TRUE;
}
}
bool Kalkulator::del_value1()
{
if (is_value1)
{
g_string_free(value1,TRUE);
is_value1 = FALSE;
return TRUE;
}
else
return FALSE;
}
char* Kalkulator::get_value2()
{
if (is_value2)
return value2->str;
else
return NULL;
}
void Kalkulator::set_value2(const gchar *val)
{
if (is_value2)
{
g_string_free(value2,TRUE);
value2 = g_string_new(val);
}
else
{
value2 = g_string_new(val);
is_value2 = TRUE;
}
}
bool Kalkulator::del_value2()
{
if (is_value2)
{
g_string_free(value2,TRUE);
is_value2 = FALSE;
return TRUE;
}
else
return FALSE;
}
void Kalkulator::add_to_memory(const gchar *val)
{
GString *tmp = g_string_new(val);
memory = g_list_append(memory, tmp);
}
void Kalkulator::memory_free()
{
int n(0);
// zwalniamy pamięć, na którą wskazują wskaźniki w liście
// zobacz: http://mail.gnome.org/archives/gtk-app-devel-list/2005-January/msg00357.html
while (memory)
{
GList *tmp = g_list_nth(memory,n++);
if (tmp)
g_string_free((GString*)tmp->data,TRUE);
else
break;
}
// zwalniamy pamięć, której używa lista
g_list_free(memory);
memory = NULL;
}
void Kalkulator::memory_print()
{
int n(0);
while (memory)
{
GList *tmp = g_list_nth(memory,n++);
if (tmp)
g_print("\n[ mem %d: %s ]",n,((GString*)tmp->data)->str);
else
break;
}
}
guint Kalkulator::memory_count()
{
return g_list_length(memory);
}