-rw-r--r-- | noncore/tools/calculator/calculatorimpl.cpp | 73 |
1 files changed, 67 insertions, 6 deletions
diff --git a/noncore/tools/calculator/calculatorimpl.cpp b/noncore/tools/calculator/calculatorimpl.cpp index 3a6efe4..0925073 100644 --- a/noncore/tools/calculator/calculatorimpl.cpp +++ b/noncore/tools/calculator/calculatorimpl.cpp | |||
@@ -1,491 +1,552 @@ | |||
1 | /********************************************************************** | 1 | /********************************************************************** |
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | 2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. |
3 | ** | 3 | ** |
4 | ** This file is part of Qtopia Environment. | 4 | ** This file is part of Qtopia Environment. |
5 | ** | 5 | ** |
6 | ** This file may be distributed and/or modified under the terms of the | 6 | ** This file may be distributed and/or modified under the terms of the |
7 | ** GNU General Public License version 2 as published by the Free Software | 7 | ** GNU General Public License version 2 as published by the Free Software |
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | 8 | ** Foundation and appearing in the file LICENSE.GPL included in the |
9 | ** packaging of this file. | 9 | ** packaging of this file. |
10 | ** | 10 | ** |
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | 11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE |
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | 12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
13 | ** | 13 | ** |
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | 14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. |
15 | ** | 15 | ** |
16 | ** Contact info@trolltech.com if any conditions of this licensing are | 16 | ** Contact info@trolltech.com if any conditions of this licensing are |
17 | ** not clear to you. | 17 | ** not clear to you. |
18 | ** | 18 | ** |
19 | **********************************************************************/ | 19 | **********************************************************************/ |
20 | 20 | ||
21 | /* | 21 | /* |
22 | * 01/14/2002 Charles-Edouard Ruault <ce@ruault.com> | 22 | * 01/14/2002 Charles-Edouard Ruault <ce@ruault.com> |
23 | * Added support for Temperature conversions. | 23 | * Added support for Temperature conversions. |
24 | */ | 24 | */ |
25 | // Sat 03-09-2002 L.J. Potter added the inlined pixmaps here | ||
25 | 26 | ||
26 | #include "calculatorimpl.h" | 27 | #include "calculatorimpl.h" |
27 | 28 | ||
28 | #include <qpe/resource.h> | 29 | #include <qpe/resource.h> |
29 | #include <qpe/qmath.h> | 30 | #include <qpe/qmath.h> |
30 | #include <qpe/qpeapplication.h> | 31 | #include <qpe/qpeapplication.h> |
31 | 32 | ||
32 | #include <qpushbutton.h> | 33 | #include <qpushbutton.h> |
33 | #include <qcombobox.h> | 34 | #include <qcombobox.h> |
34 | #include <qlabel.h> | 35 | #include <qlabel.h> |
35 | #include <qfont.h> | 36 | #include <qfont.h> |
36 | #include <qlayout.h> | 37 | #include <qlayout.h> |
37 | #include <qstringlist.h> | 38 | #include <qstringlist.h> |
38 | #include <qfile.h> | 39 | #include <qfile.h> |
39 | #include <qtextstream.h> | 40 | #include <qtextstream.h> |
40 | #include <qmessagebox.h> | 41 | #include <qmessagebox.h> |
41 | #include <math.h> | 42 | #include <math.h> |
43 | /* XPM */ | ||
44 | static char *oneoverx_xpm[] = { | ||
45 | /* width height num_colors chars_per_pixel */ | ||
46 | " 13 11 2 1", | ||
47 | /* colors */ | ||
48 | ". c None", | ||
49 | "# c #000000", | ||
50 | /* pixels */ | ||
51 | "......#......", | ||
52 | ".....##......", | ||
53 | "......#......" | ||
54 | ".....###.....", | ||
55 | ".............", | ||
56 | "..#########..", | ||
57 | ".............", | ||
58 | "....##.##....", | ||
59 | "......#......", | ||
60 | "......#......", | ||
61 | "....##.##....", | ||
62 | }; | ||
63 | /* XPM */ | ||
64 | static char *ythrootofx_xpm[] = { | ||
65 | /* width height num_colors chars_per_pixel */ | ||
66 | " 13 11 2 1", | ||
67 | /* colors */ | ||
68 | ". c None", | ||
69 | "# c #000000", | ||
70 | /* pixels */ | ||
71 | "#.#..........", | ||
72 | "#.#..........", | ||
73 | "###...#######", | ||
74 | "..#..#.......", | ||
75 | "###..#.......", | ||
76 | ".....#.#...#.", | ||
77 | ".#..#...#.#..", | ||
78 | "#.#.#....#...", | ||
79 | "..#.#...#.#..", | ||
80 | "...#...#...#.", | ||
81 | "...#........." | ||
82 | }; | ||
83 | /* XPM */ | ||
84 | static char *xtopowerofy_xpm[] = { | ||
85 | /* width height num_colors chars_per_pixel */ | ||
86 | " 9 8 2 1", | ||
87 | /* colors */ | ||
88 | ". c None", | ||
89 | "# c #000000", | ||
90 | /* pixels */ | ||
91 | "......#.#", | ||
92 | "......#.#", | ||
93 | "......###", | ||
94 | "#...#...#", | ||
95 | ".#.#..###", | ||
96 | "..#......", | ||
97 | ".#.#.....", | ||
98 | "#...#...." | ||
99 | }; | ||
42 | 100 | ||
43 | CalculatorImpl::CalculatorImpl( QWidget * parent, const char * name, | 101 | CalculatorImpl::CalculatorImpl( QWidget * parent, const char * name, |
44 | WFlags f ) | 102 | WFlags f ) |
45 | : Calculator( parent, name, f ) | 103 | : Calculator( parent, name, f ) |
46 | { | 104 | { |
47 | xtopowerofy = Resource::loadPixmap("xtopowerofy"); | 105 | // xtopowerofy = Resource::loadPixmap("xtopowerofy"); |
48 | ythrootofx = Resource::loadPixmap("ythrootofx"); | 106 | // ythrootofx = Resource::loadPixmap("ythrootofx"); |
49 | oneoverx = Resource::loadPixmap("oneoverx"); | 107 | // oneoverx = Resource::loadPixmap("oneoverx"); |
50 | 108 | ||
51 | memMark = new QLabel( "m", LCD ); | 109 | memMark = new QLabel( "m", LCD ); |
52 | memMark->setFont( QFont( "helvetica", 12, QFont::Bold, TRUE ) ); | 110 | memMark->setFont( QFont( "helvetica", 12, QFont::Bold, TRUE ) ); |
53 | memMark->resize( 12, 12 ); | 111 | memMark->resize( 12, 12 ); |
54 | memMark->move( 4, 2 ); | 112 | memMark->move( 4, 2 ); |
55 | memMark->hide(); | 113 | memMark->hide(); |
56 | mem = 0; | 114 | mem = 0; |
57 | 115 | ||
58 | PushButtonMR->setEnabled( FALSE ); | 116 | PushButtonMR->setEnabled( FALSE ); |
59 | 117 | ||
60 | current_mode = max_mode = conversion_mode_count = 0; | 118 | current_mode = max_mode = conversion_mode_count = 0; |
61 | last_conversion = -1; | 119 | last_conversion = -1; |
62 | 120 | ||
63 | //bgr_command.insert( PushButtonFunction); | 121 | //bgr_command.insert( PushButtonFunction); |
64 | bgr_command.insert( PushButtonMPlus); | 122 | bgr_command.insert( PushButtonMPlus); |
65 | bgr_command.insert( PushButtonMR); | 123 | bgr_command.insert( PushButtonMR); |
66 | bgr_command.insert( PushButtonMC); | 124 | bgr_command.insert( PushButtonMC); |
67 | bgr_command.insert( PushButtonCE); | 125 | bgr_command.insert( PushButtonCE); |
68 | connect( &bgr_command, SIGNAL(clicked(int) ), this, SLOT(command_buttons(int))); | 126 | connect( &bgr_command, SIGNAL(clicked(int) ), this, SLOT(command_buttons(int))); |
69 | 127 | ||
70 | bgr_digits.insert(PushButton0); | 128 | bgr_digits.insert(PushButton0); |
71 | bgr_digits.insert(PushButton1); | 129 | bgr_digits.insert(PushButton1); |
72 | bgr_digits.insert(PushButton2); | 130 | bgr_digits.insert(PushButton2); |
73 | bgr_digits.insert(PushButton3); | 131 | bgr_digits.insert(PushButton3); |
74 | bgr_digits.insert(PushButton4); | 132 | bgr_digits.insert(PushButton4); |
75 | bgr_digits.insert(PushButton5); | 133 | bgr_digits.insert(PushButton5); |
76 | bgr_digits.insert(PushButton6); | 134 | bgr_digits.insert(PushButton6); |
77 | bgr_digits.insert(PushButton7); | 135 | bgr_digits.insert(PushButton7); |
78 | bgr_digits.insert(PushButton8); | 136 | bgr_digits.insert(PushButton8); |
79 | bgr_digits.insert(PushButton9); | 137 | bgr_digits.insert(PushButton9); |
80 | connect( &bgr_digits, SIGNAL(clicked(int) ), this, SLOT(enterNumber(int))); | 138 | connect( &bgr_digits, SIGNAL(clicked(int) ), this, SLOT(enterNumber(int))); |
81 | 139 | ||
82 | 140 | ||
83 | bgr_std.insert(PushButtonEquals); | 141 | bgr_std.insert(PushButtonEquals); |
84 | bgr_std.insert(PushButtonDecimal); | 142 | bgr_std.insert(PushButtonDecimal); |
85 | bgr_std.insert(PushButtonAdd); | 143 | bgr_std.insert(PushButtonAdd); |
86 | bgr_std.insert(PushButtonMinus); | 144 | bgr_std.insert(PushButtonMinus); |
87 | bgr_std.insert(PushButtonDivide); | 145 | bgr_std.insert(PushButtonDivide); |
88 | bgr_std.insert(PushButtonTimes); | 146 | bgr_std.insert(PushButtonTimes); |
89 | connect( &bgr_std, SIGNAL(clicked(int) ), this, SLOT(std_buttons(int))); | 147 | connect( &bgr_std, SIGNAL(clicked(int) ), this, SLOT(std_buttons(int))); |
90 | 148 | ||
91 | // change the / to a proper division signal | 149 | // change the / to a proper division signal |
92 | PushButtonDivide->setText(QChar(0xF7)); | 150 | PushButtonDivide->setText(QChar(0xF7)); |
93 | 151 | ||
94 | func_buttons[0] = PushButtonF1; | 152 | func_buttons[0] = PushButtonF1; |
95 | func_buttons[1] = PushButtonF2; | 153 | func_buttons[1] = PushButtonF2; |
96 | func_buttons[2] = PushButtonF3; | 154 | func_buttons[2] = PushButtonF3; |
97 | func_buttons[3] = PushButtonF4; | 155 | func_buttons[3] = PushButtonF4; |
98 | func_buttons[4] = PushButtonF5; | 156 | func_buttons[4] = PushButtonF5; |
99 | func_buttons[5] = PushButtonF6; | 157 | func_buttons[5] = PushButtonF6; |
100 | func_buttons[6] = PushButtonF7; | 158 | func_buttons[6] = PushButtonF7; |
101 | func_buttons[7] = PushButtonF8; | 159 | func_buttons[7] = PushButtonF8; |
102 | func_buttons[8] = PushButtonF9; | 160 | func_buttons[8] = PushButtonF9; |
103 | func_buttons[9] = PushButtonF10; | 161 | func_buttons[9] = PushButtonF10; |
104 | func_buttons[10] = PushButtonF11; | 162 | func_buttons[10] = PushButtonF11; |
105 | func_buttons[11] = PushButtonF12; | 163 | func_buttons[11] = PushButtonF12; |
106 | 164 | ||
107 | for ( int x = 0 ; x < func_button_count ; x++ ) { | 165 | for ( int x = 0 ; x < func_button_count ; x++ ) { |
108 | QPushButton* tmpbutton = func_buttons[x]; | 166 | QPushButton* tmpbutton = func_buttons[x]; |
109 | faces << tmpbutton->text(); | 167 | faces << tmpbutton->text(); |
110 | bgr_function.insert(tmpbutton); | 168 | bgr_function.insert(tmpbutton); |
111 | } | 169 | } |
112 | connect( &bgr_function, SIGNAL(clicked(int) ) , this, SLOT(do_convert(int) ) ); | 170 | connect( &bgr_function, SIGNAL(clicked(int) ) , this, SLOT(do_convert(int) ) ); |
113 | connect( &bgr_function, SIGNAL(clicked(int) ) , this, SLOT(std_funcs (int) ) ); | 171 | connect( &bgr_function, SIGNAL(clicked(int) ) , this, SLOT(std_funcs (int) ) ); |
114 | 172 | ||
115 | connect(ComboBoxFunction, SIGNAL(activated(int) ), this, SLOT(function_button(int) ) ); | 173 | connect(ComboBoxFunction, SIGNAL(activated(int) ), this, SLOT(function_button(int) ) ); |
116 | 174 | ||
117 | captions.append("Standard"); | 175 | captions.append("Standard"); |
118 | ComboBoxFunction->insertItem(captions.last()); | 176 | ComboBoxFunction->insertItem(captions.last()); |
119 | 177 | ||
120 | // now add in the conversion modes | 178 | // now add in the conversion modes |
121 | // when the menu gets done, these should be in a submenu | 179 | // when the menu gets done, these should be in a submenu |
122 | QString tmp = QPEApplication::qpeDir(); | 180 | QString tmp = QPEApplication::qpeDir(); |
123 | tmp += "etc/unit_conversion.dat"; | 181 | tmp += "etc/unit_conversion.dat"; |
124 | QFile myfile(tmp); | 182 | QFile myfile(tmp); |
125 | if ( !myfile.open( IO_Translate | IO_ReadOnly ) ) { | 183 | if ( !myfile.open( IO_Translate | IO_ReadOnly ) ) { |
126 | qDebug("Data file unit_conversion.dat not found\nNo conversion features will be available\n"+tmp); | 184 | qDebug("Data file unit_conversion.dat not found\nNo conversion features will be available\n"+tmp); |
127 | // disable the f button if no conv file available | 185 | // disable the f button if no conv file available |
128 | ComboBoxFunction->setEnabled(FALSE); | 186 | ComboBoxFunction->setEnabled(FALSE); |
129 | } | 187 | } |
130 | else { | 188 | else { |
131 | QString line, line2; | 189 | QString line, line2; |
132 | QTextStream ts(&myfile); | 190 | QTextStream ts(&myfile); |
133 | 191 | ||
134 | // first pass, see how many conversion types there are in order to allocate for them | 192 | // first pass, see how many conversion types there are in order to allocate for them |
135 | while ( ! ts.eof() ) { | 193 | while ( ! ts.eof() ) { |
136 | line = ts.readLine(); | 194 | line = ts.readLine(); |
137 | if ( line.contains ("STARTTYPE" ) ) | 195 | if ( line.contains ("STARTTYPE" ) ) |
138 | conversion_mode_count++; | 196 | conversion_mode_count++; |
139 | } | 197 | } |
140 | 198 | ||
141 | entry_list = new double[conversion_mode_count*func_button_count]; | 199 | entry_list = new double[conversion_mode_count*func_button_count]; |
142 | preoffset_list = new double[conversion_mode_count*func_button_count]; | 200 | preoffset_list = new double[conversion_mode_count*func_button_count]; |
143 | postoffset_list = new double[conversion_mode_count*func_button_count]; | 201 | postoffset_list = new double[conversion_mode_count*func_button_count]; |
144 | myfile.close(); | 202 | myfile.close(); |
145 | myfile.open( IO_Translate | IO_ReadOnly ); | 203 | myfile.open( IO_Translate | IO_ReadOnly ); |
146 | QTextStream ts2(&myfile); | 204 | QTextStream ts2(&myfile); |
147 | 205 | ||
148 | // second pass, read in values | 206 | // second pass, read in values |
149 | int x = 0; | 207 | int x = 0; |
150 | while ( ! ts2.eof() ) { | 208 | while ( ! ts2.eof() ) { |
151 | line = ts2.readLine(); | 209 | line = ts2.readLine(); |
152 | if ( line.contains("STARTTYPE") ) { | 210 | if ( line.contains("STARTTYPE") ) { |
153 | captions << line.remove(0,10); | 211 | captions << line.remove(0,10); |
154 | ComboBoxFunction->insertItem(captions.last()); | 212 | ComboBoxFunction->insertItem(captions.last()); |
155 | while ( !line.contains("ENDTYPE") ) { | 213 | while ( !line.contains("ENDTYPE") ) { |
156 | line = ts2.readLine(); | 214 | line = ts2.readLine(); |
157 | if ( line.contains("NAME") ) { | 215 | if ( line.contains("NAME") ) { |
158 | faces << line.remove(0,5); | 216 | faces << line.remove(0,5); |
159 | line2 = ts2.readLine(); | 217 | line2 = ts2.readLine(); |
160 | line2.remove(0,6); | 218 | line2.remove(0,6); |
161 | entry_list[x] = line2.toDouble(); | 219 | entry_list[x] = line2.toDouble(); |
162 | line2 = ts2.readLine(); | 220 | line2 = ts2.readLine(); |
163 | line2.remove(0,7); | 221 | line2.remove(0,7); |
164 | preoffset_list[x] = line2.toDouble(); | 222 | preoffset_list[x] = line2.toDouble(); |
165 | line2 = ts2.readLine(); | 223 | line2 = ts2.readLine(); |
166 | line2.remove(0,8); | 224 | line2.remove(0,8); |
167 | postoffset_list[x] = line2.toDouble(); | 225 | postoffset_list[x] = line2.toDouble(); |
168 | x++; | 226 | x++; |
169 | } | 227 | } |
170 | } | 228 | } |
171 | } | 229 | } |
172 | } | 230 | } |
173 | } | 231 | } |
174 | myfile.close(); | 232 | myfile.close(); |
175 | clear(); | 233 | clear(); |
176 | max_mode = pre_conv_modes_count + conversion_mode_count + post_conv_modes_count - 1; | 234 | max_mode = pre_conv_modes_count + conversion_mode_count + post_conv_modes_count - 1; |
177 | display_pixmap_faces(); | 235 | display_pixmap_faces(); |
178 | 236 | ||
179 | qApp->installEventFilter( this ); | 237 | qApp->installEventFilter( this ); |
180 | } | 238 | } |
181 | 239 | ||
182 | bool CalculatorImpl::eventFilter( QObject *o, QEvent *e ) | 240 | bool CalculatorImpl::eventFilter( QObject *o, QEvent *e ) |
183 | { | 241 | { |
184 | if ( e->type() == QEvent::KeyPress && state != sError ) { | 242 | if ( e->type() == QEvent::KeyPress && state != sError ) { |
185 | QKeyEvent *k = (QKeyEvent*)e; | 243 | QKeyEvent *k = (QKeyEvent*)e; |
186 | if ( k->key() >= Key_0 && k->key() <= Key_9 ) { | 244 | if ( k->key() >= Key_0 && k->key() <= Key_9 ) { |
187 | enterNumber( k->key() - Key_0 ); | 245 | enterNumber( k->key() - Key_0 ); |
188 | return true; | 246 | return true; |
189 | } else { | 247 | } else { |
190 | switch ( k->key() ) { | 248 | switch ( k->key() ) { |
191 | case Key_Equal: | 249 | case Key_Equal: |
192 | std_buttons(0); | 250 | std_buttons(0); |
193 | return true; | 251 | return true; |
194 | case Key_Period: | 252 | case Key_Period: |
195 | std_buttons(1); | 253 | std_buttons(1); |
196 | return true; | 254 | return true; |
197 | case Key_Plus: | 255 | case Key_Plus: |
198 | std_buttons(2); | 256 | std_buttons(2); |
199 | return true; | 257 | return true; |
200 | case Key_Minus: | 258 | case Key_Minus: |
201 | std_buttons(3); | 259 | std_buttons(3); |
202 | return true; | 260 | return true; |
203 | case Key_Slash: | 261 | case Key_Slash: |
204 | std_buttons(4); | 262 | std_buttons(4); |
205 | return true; | 263 | return true; |
206 | case Key_Asterisk: | 264 | case Key_Asterisk: |
207 | std_buttons(5); | 265 | std_buttons(5); |
208 | return true; | 266 | return true; |
209 | case Key_Percent: | 267 | case Key_Percent: |
210 | execOp( oPercent ); | 268 | execOp( oPercent ); |
211 | return true; | 269 | return true; |
212 | case Key_ParenLeft: | 270 | case Key_ParenLeft: |
213 | if ( current_mode < pre_conv_modes_count ) | 271 | if ( current_mode < pre_conv_modes_count ) |
214 | execOp( oOpenBrace ); | 272 | execOp( oOpenBrace ); |
215 | return true; | 273 | return true; |
216 | case Key_ParenRight: | 274 | case Key_ParenRight: |
217 | if ( current_mode < pre_conv_modes_count ) | 275 | if ( current_mode < pre_conv_modes_count ) |
218 | execOp( oCloseBrace ); | 276 | execOp( oCloseBrace ); |
219 | return true; | 277 | return true; |
220 | default: | 278 | default: |
221 | break; | 279 | break; |
222 | } | 280 | } |
223 | } | 281 | } |
224 | } | 282 | } |
225 | return Calculator::eventFilter( o, e ); | 283 | return Calculator::eventFilter( o, e ); |
226 | } | 284 | } |
227 | 285 | ||
228 | void CalculatorImpl::do_convert(int button) { | 286 | void CalculatorImpl::do_convert(int button) { |
229 | if ( state == sError ) | 287 | if ( state == sError ) |
230 | return; | 288 | return; |
231 | if ( current_mode >= pre_conv_modes_count && current_mode <= (max_mode - post_conv_modes_count) && | 289 | if ( current_mode >= pre_conv_modes_count && current_mode <= (max_mode - post_conv_modes_count) && |
232 | button < changeable_func_button_count ) { | 290 | button < changeable_func_button_count ) { |
233 | if ( last_conversion > -1 ) { | 291 | if ( last_conversion > -1 ) { |
234 | if( state == sNewNumber ){ | 292 | if( state == sNewNumber ){ |
235 | acc = (num+ preoffset_list[(current_mode - pre_conv_modes_count) * func_button_count + last_conversion]) | 293 | acc = (num+ preoffset_list[(current_mode - pre_conv_modes_count) * func_button_count + last_conversion]) |
236 | / (entry_list[(current_mode - pre_conv_modes_count) * func_button_count + last_conversion]) | 294 | / (entry_list[(current_mode - pre_conv_modes_count) * func_button_count + last_conversion]) |
237 | * (entry_list[(current_mode - pre_conv_modes_count) * func_button_count + button]) | 295 | * (entry_list[(current_mode - pre_conv_modes_count) * func_button_count + button]) |
238 | +postoffset_list[(current_mode - pre_conv_modes_count) * func_button_count + button]; | 296 | +postoffset_list[(current_mode - pre_conv_modes_count) * func_button_count + button]; |
239 | num = acc; | 297 | num = acc; |
240 | LCD->display( acc ); | 298 | LCD->display( acc ); |
241 | } else { | 299 | } else { |
242 | state = sNewNumber; | 300 | state = sNewNumber; |
243 | num = (num+ preoffset_list[(current_mode - pre_conv_modes_count) * func_button_count + last_conversion]) | 301 | num = (num+ preoffset_list[(current_mode - pre_conv_modes_count) * func_button_count + last_conversion]) |
244 | / (entry_list[(current_mode - pre_conv_modes_count) * func_button_count + last_conversion]) | 302 | / (entry_list[(current_mode - pre_conv_modes_count) * func_button_count + last_conversion]) |
245 | * (entry_list[(current_mode - pre_conv_modes_count) * func_button_count + button]) | 303 | * (entry_list[(current_mode - pre_conv_modes_count) * func_button_count + button]) |
246 | + postoffset_list[(current_mode - pre_conv_modes_count) * func_button_count + button];; | 304 | + postoffset_list[(current_mode - pre_conv_modes_count) * func_button_count + button];; |
247 | LCD->display( num ); | 305 | LCD->display( num ); |
248 | acc = num; | 306 | acc = num; |
249 | } | 307 | } |
250 | } | 308 | } |
251 | last_conversion = button; | 309 | last_conversion = button; |
252 | } | 310 | } |
253 | } | 311 | } |
254 | 312 | ||
255 | 313 | ||
256 | void CalculatorImpl::function_button(int mode){ | 314 | void CalculatorImpl::function_button(int mode){ |
257 | if ( state == sError ) | 315 | if ( state == sError ) |
258 | clear(); | 316 | clear(); |
259 | // dont need the next line when using a popup menu | 317 | // dont need the next line when using a popup menu |
260 | current_mode = mode; | 318 | current_mode = mode; |
261 | 319 | ||
262 | // reset the last conv | 320 | // reset the last conv |
263 | last_conversion = -1; | 321 | last_conversion = -1; |
264 | 322 | ||
265 | // set the caption | 323 | // set the caption |
266 | this->setCaption( captions[current_mode] ); | 324 | this->setCaption( captions[current_mode] ); |
267 | 325 | ||
268 | reset_conv(); | 326 | reset_conv(); |
269 | 327 | ||
270 | for ( int x = 0 ; x < changeable_func_button_count ; x++ ) { | 328 | for ( int x = 0 ; x < changeable_func_button_count ; x++ ) { |
271 | QPushButton* tmpbutton = func_buttons[x]; | 329 | QPushButton* tmpbutton = func_buttons[x]; |
272 | 330 | ||
273 | // if its a conversion , make it a toggle button | 331 | // if its a conversion , make it a toggle button |
274 | if ( current_mode >= pre_conv_modes_count && current_mode <= (max_mode - post_conv_modes_count) ) { | 332 | if ( current_mode >= pre_conv_modes_count && current_mode <= (max_mode - post_conv_modes_count) ) { |
275 | tmpbutton->setToggleButton(TRUE); | 333 | tmpbutton->setToggleButton(TRUE); |
276 | } else { | 334 | } else { |
277 | tmpbutton->setToggleButton(FALSE); | 335 | tmpbutton->setToggleButton(FALSE); |
278 | } | 336 | } |
279 | tmpbutton->setText( faces[current_mode * func_button_count + x] ); | 337 | tmpbutton->setText( faces[current_mode * func_button_count + x] ); |
280 | } | 338 | } |
281 | 339 | ||
282 | if ( current_mode == 0 ) display_pixmap_faces(); | 340 | if ( current_mode == 0 ) display_pixmap_faces(); |
283 | 341 | ||
284 | if ( current_mode >= pre_conv_modes_count && current_mode <= (max_mode - post_conv_modes_count) ) { | 342 | if ( current_mode >= pre_conv_modes_count && current_mode <= (max_mode - post_conv_modes_count) ) { |
285 | bgr_function.setExclusive(TRUE); | 343 | bgr_function.setExclusive(TRUE); |
286 | } else { | 344 | } else { |
287 | bgr_function.setExclusive(FALSE); | 345 | bgr_function.setExclusive(FALSE); |
288 | } | 346 | } |
289 | } | 347 | } |
290 | 348 | ||
291 | void CalculatorImpl::display_pixmap_faces() { | 349 | void CalculatorImpl::display_pixmap_faces() { |
350 | QPixmap image0( ( const char** ) xtopowerofy_xpm); | ||
292 | QPushButton* tmpbutton = func_buttons[5]; | 351 | QPushButton* tmpbutton = func_buttons[5]; |
293 | tmpbutton->setPixmap(xtopowerofy); | 352 | tmpbutton->setPixmap(image0); |
294 | 353 | ||
354 | QPixmap image1( ( const char** ) ythrootofx_xpm); | ||
295 | tmpbutton = func_buttons[6]; | 355 | tmpbutton = func_buttons[6]; |
296 | tmpbutton->setPixmap(ythrootofx); | 356 | tmpbutton->setPixmap(image1); |
297 | 357 | ||
358 | QPixmap image2( ( const char** ) oneoverx_xpm); | ||
298 | tmpbutton = func_buttons[3]; | 359 | tmpbutton = func_buttons[3]; |
299 | tmpbutton->setPixmap(oneoverx); | 360 | tmpbutton->setPixmap(image2); |
300 | } | 361 | } |
301 | 362 | ||
302 | void CalculatorImpl::clear() { | 363 | void CalculatorImpl::clear() { |
303 | acc = num = 0; | 364 | acc = num = 0; |
304 | operationStack.clear(); | 365 | operationStack.clear(); |
305 | state = sStart; | 366 | state = sStart; |
306 | numDecimals = 0; | 367 | numDecimals = 0; |
307 | numOpenBraces = 0; | 368 | numOpenBraces = 0; |
308 | flPoint = FALSE; | 369 | flPoint = FALSE; |
309 | LCD->display( 0 ); | 370 | LCD->display( 0 ); |
310 | fake = QString::null; | 371 | fake = QString::null; |
311 | 372 | ||
312 | reset_conv(); | 373 | reset_conv(); |
313 | } | 374 | } |
314 | 375 | ||
315 | void CalculatorImpl::reset_conv() { | 376 | void CalculatorImpl::reset_conv() { |
316 | for ( int x = 0 ; x < changeable_func_button_count ; x++ ) { | 377 | for ( int x = 0 ; x < changeable_func_button_count ; x++ ) { |
317 | QPushButton* tmpbutton = func_buttons[x]; | 378 | QPushButton* tmpbutton = func_buttons[x]; |
318 | 379 | ||
319 | // dont carry any selections into the next mode | 380 | // dont carry any selections into the next mode |
320 | if ( tmpbutton->state() == QPushButton::On ) { | 381 | if ( tmpbutton->state() == QPushButton::On ) { |
321 | tmpbutton->toggle(); | 382 | tmpbutton->toggle(); |
322 | } | 383 | } |
323 | } | 384 | } |
324 | 385 | ||
325 | last_conversion = -1; | 386 | last_conversion = -1; |
326 | } | 387 | } |
327 | 388 | ||
328 | void CalculatorImpl::std_buttons(int button) | 389 | void CalculatorImpl::std_buttons(int button) |
329 | { | 390 | { |
330 | if ( state == sError ) | 391 | if ( state == sError ) |
331 | return; | 392 | return; |
332 | execOp( (Operation)(button + oSum) ); | 393 | execOp( (Operation)(button + oSum) ); |
333 | } | 394 | } |
334 | 395 | ||
335 | void CalculatorImpl::std_funcs(int button) { | 396 | void CalculatorImpl::std_funcs(int button) { |
336 | if ( state == sError ) | 397 | if ( state == sError ) |
337 | return; | 398 | return; |
338 | if ( current_mode < pre_conv_modes_count || | 399 | if ( current_mode < pre_conv_modes_count || |
339 | button > changeable_func_button_count-1 ) { | 400 | button > changeable_func_button_count-1 ) { |
340 | Operation op; | 401 | Operation op; |
341 | if ( button < 10 ) | 402 | if ( button < 10 ) |
342 | op = (Operation)(button + oSin); | 403 | op = (Operation)(button + oSin); |
343 | else if ( button == 10 ) | 404 | else if ( button == 10 ) |
344 | op = oOpenBrace; | 405 | op = oOpenBrace; |
345 | else | 406 | else |
346 | op = oCloseBrace; | 407 | op = oCloseBrace; |
347 | execOp( op ); | 408 | execOp( op ); |
348 | } | 409 | } |
349 | } | 410 | } |
350 | 411 | ||
351 | void CalculatorImpl::execOp( Operation i ) | 412 | void CalculatorImpl::execOp( Operation i ) |
352 | { | 413 | { |
353 | switch (i) { | 414 | switch (i) { |
354 | // these operators only affect the current number. | 415 | // these operators only affect the current number. |
355 | case oDivX: | 416 | case oDivX: |
356 | case oLog: | 417 | case oLog: |
357 | case oLn: | 418 | case oLn: |
358 | case oSin: | 419 | case oSin: |
359 | case oCos: | 420 | case oCos: |
360 | case oTan: | 421 | case oTan: |
361 | num = evalExpr(i); | 422 | num = evalExpr(i); |
362 | break; | 423 | break; |
363 | 424 | ||
364 | case oAdd: | 425 | case oAdd: |
365 | case oSub: { | 426 | case oSub: { |
366 | processStack( oAdd ); | 427 | processStack( oAdd ); |
367 | Op op( num, i ); | 428 | Op op( num, i ); |
368 | operationStack.push( op ); | 429 | operationStack.push( op ); |
369 | break; | 430 | break; |
370 | } | 431 | } |
371 | case oDiv: | 432 | case oDiv: |
372 | case oMult: | 433 | case oMult: |
373 | case oRoot: | 434 | case oRoot: |
374 | case oXsquared: { | 435 | case oXsquared: { |
375 | processStack( oDiv ); | 436 | processStack( oDiv ); |
376 | Op op( num, i ); | 437 | Op op( num, i ); |
377 | operationStack.push( op ); | 438 | operationStack.push( op ); |
378 | break; | 439 | break; |
379 | } | 440 | } |
380 | case oChSign: | 441 | case oChSign: |
381 | num = -num; | 442 | num = -num; |
382 | LCD->display(num); | 443 | LCD->display(num); |
383 | return; | 444 | return; |
384 | 445 | ||
385 | case oOpenBrace: { | 446 | case oOpenBrace: { |
386 | Op op( 0, oOpenBrace ); | 447 | Op op( 0, oOpenBrace ); |
387 | operationStack.push( op ); | 448 | operationStack.push( op ); |
388 | numOpenBraces++; | 449 | numOpenBraces++; |
389 | state = sNewNumber; | 450 | state = sNewNumber; |
390 | return; | 451 | return; |
391 | } | 452 | } |
392 | case oCloseBrace: { | 453 | case oCloseBrace: { |
393 | if ( numOpenBraces == 0 ) | 454 | if ( numOpenBraces == 0 ) |
394 | return; | 455 | return; |
395 | processStack( oAdd ); | 456 | processStack( oAdd ); |
396 | if ( operationStack.top().operation != oOpenBrace ) | 457 | if ( operationStack.top().operation != oOpenBrace ) |
397 | qDebug( "Calculator: internal Error" ); | 458 | qDebug( "Calculator: internal Error" ); |
398 | operationStack.pop(); | 459 | operationStack.pop(); |
399 | state = sNewNumber; | 460 | state = sNewNumber; |
400 | numOpenBraces--; | 461 | numOpenBraces--; |
401 | break; | 462 | break; |
402 | } | 463 | } |
403 | 464 | ||
404 | case oPoint: | 465 | case oPoint: |
405 | flPoint = TRUE; | 466 | flPoint = TRUE; |
406 | return; | 467 | return; |
407 | 468 | ||
408 | case oPercent: | 469 | case oPercent: |
409 | processStack( oPercent ); | 470 | processStack( oPercent ); |
410 | break; | 471 | break; |
411 | 472 | ||
412 | 473 | ||
413 | case oSum: | 474 | case oSum: |
414 | processStack( oSum ); | 475 | processStack( oSum ); |
415 | break; | 476 | break; |
416 | 477 | ||
417 | default: | 478 | default: |
418 | return; | 479 | return; |
419 | }; | 480 | }; |
420 | 481 | ||
421 | if ( state == sError ) { | 482 | if ( state == sError ) { |
422 | LCD->display( "Error" ); | 483 | LCD->display( "Error" ); |
423 | return; | 484 | return; |
424 | } else { | 485 | } else { |
425 | LCD->display(num); | 486 | LCD->display(num); |
426 | } | 487 | } |
427 | state = sNewNumber; | 488 | state = sNewNumber; |
428 | numDecimals = 0; | 489 | numDecimals = 0; |
429 | flPoint = FALSE; | 490 | flPoint = FALSE; |
430 | } | 491 | } |
431 | 492 | ||
432 | 493 | ||
433 | void CalculatorImpl::processStack( int op ) | 494 | void CalculatorImpl::processStack( int op ) |
434 | { | 495 | { |
435 | //dubious percent hack, since the changeable operator precedences are | 496 | //dubious percent hack, since the changeable operator precedences are |
436 | //pretty much hardwired to be less than the non-changeable | 497 | //pretty much hardwired to be less than the non-changeable |
437 | bool percent = FALSE; | 498 | bool percent = FALSE; |
438 | if ( op == oPercent ) { | 499 | if ( op == oPercent ) { |
439 | percent = TRUE; | 500 | percent = TRUE; |
440 | op = oSum; | 501 | op = oSum; |
441 | } | 502 | } |
442 | while( !operationStack.isEmpty() && operationStack.top().operation >= op ) { | 503 | while( !operationStack.isEmpty() && operationStack.top().operation >= op ) { |
443 | Op operation = operationStack.pop(); | 504 | Op operation = operationStack.pop(); |
444 | acc = operation.number; | 505 | acc = operation.number; |
445 | if ( percent ) { | 506 | if ( percent ) { |
446 | if ( operation.operation == oAdd || operation.operation == oSub ) | 507 | if ( operation.operation == oAdd || operation.operation == oSub ) |
447 | num = acc*num/100; | 508 | num = acc*num/100; |
448 | else | 509 | else |
449 | num = num / 100; | 510 | num = num / 100; |
450 | } | 511 | } |
451 | num = evalExpr( operation.operation ); | 512 | num = evalExpr( operation.operation ); |
452 | percent = FALSE; | 513 | percent = FALSE; |
453 | } | 514 | } |
454 | } | 515 | } |
455 | 516 | ||
456 | 517 | ||
457 | double CalculatorImpl::evalExpr( int op ) { | 518 | double CalculatorImpl::evalExpr( int op ) { |
458 | double sum = 0; | 519 | double sum = 0; |
459 | 520 | ||
460 | switch( op ){ | 521 | switch( op ){ |
461 | case oPercent: sum = num / 100.; break; | 522 | case oPercent: sum = num / 100.; break; |
462 | case oDivX: | 523 | case oDivX: |
463 | if (num == 0) | 524 | if (num == 0) |
464 | state = sError; | 525 | state = sError; |
465 | else | 526 | else |
466 | sum = 1 / num; | 527 | sum = 1 / num; |
467 | break; | 528 | break; |
468 | case oXsquared: | 529 | case oXsquared: |
469 | sum = pow(acc,num); | 530 | sum = pow(acc,num); |
470 | break; | 531 | break; |
471 | case oChSign: (state == sStart) ? sum = -num : sum = -acc; break; | 532 | case oChSign: (state == sStart) ? sum = -num : sum = -acc; break; |
472 | case oSub: sum = acc - num; break; | 533 | case oSub: sum = acc - num; break; |
473 | case oMult: sum = acc * num; break; | 534 | case oMult: sum = acc * num; break; |
474 | case oAdd: sum = acc + num; break; | 535 | case oAdd: sum = acc + num; break; |
475 | case oDiv: { | 536 | case oDiv: { |
476 | if (num == 0) { | 537 | if (num == 0) { |
477 | state = sError; | 538 | state = sError; |
478 | } else { | 539 | } else { |
479 | sum = acc / num; | 540 | sum = acc / num; |
480 | } | 541 | } |
481 | break; | 542 | break; |
482 | } | 543 | } |
483 | case oRoot: | 544 | case oRoot: |
484 | /* the linux library is dumb, and can't to -x to 1/n | 545 | /* the linux library is dumb, and can't to -x to 1/n |
485 | when n is odd. (even and error of course is acceptable */ | 546 | when n is odd. (even and error of course is acceptable */ |
486 | if((acc < 0) && (int(num) == num) && (int(num) % 2 == 1 )) { | 547 | if((acc < 0) && (int(num) == num) && (int(num) % 2 == 1 )) { |
487 | sum = pow(-acc, 1 / num); | 548 | sum = pow(-acc, 1 / num); |
488 | sum = -sum; | 549 | sum = -sum; |
489 | } else { | 550 | } else { |
490 | sum = pow(acc, 1 / num); | 551 | sum = pow(acc, 1 / num); |
491 | } | 552 | } |