-rw-r--r-- | noncore/tools/calculator/calculatorimpl.cpp | 498 |
1 files changed, 249 insertions, 249 deletions
diff --git a/noncore/tools/calculator/calculatorimpl.cpp b/noncore/tools/calculator/calculatorimpl.cpp index 1b93c7f..3a6efe4 100644 --- a/noncore/tools/calculator/calculatorimpl.cpp +++ b/noncore/tools/calculator/calculatorimpl.cpp | |||
@@ -32,25 +32,25 @@ | |||
32 | #include <qpushbutton.h> | 32 | #include <qpushbutton.h> |
33 | #include <qcombobox.h> | 33 | #include <qcombobox.h> |
34 | #include <qlabel.h> | 34 | #include <qlabel.h> |
35 | #include <qfont.h> | 35 | #include <qfont.h> |
36 | #include <qlayout.h> | 36 | #include <qlayout.h> |
37 | #include <qstringlist.h> | 37 | #include <qstringlist.h> |
38 | #include <qfile.h> | 38 | #include <qfile.h> |
39 | #include <qtextstream.h> | 39 | #include <qtextstream.h> |
40 | #include <qmessagebox.h> | 40 | #include <qmessagebox.h> |
41 | #include <math.h> | 41 | #include <math.h> |
42 | 42 | ||
43 | CalculatorImpl::CalculatorImpl( QWidget * parent, const char * name, | 43 | CalculatorImpl::CalculatorImpl( QWidget * parent, const char * name, |
44 | WFlags f ) | 44 | WFlags f ) |
45 | : Calculator( parent, name, f ) | 45 | : Calculator( parent, name, f ) |
46 | { | 46 | { |
47 | xtopowerofy = Resource::loadPixmap("xtopowerofy"); | 47 | xtopowerofy = Resource::loadPixmap("xtopowerofy"); |
48 | ythrootofx = Resource::loadPixmap("ythrootofx"); | 48 | ythrootofx = Resource::loadPixmap("ythrootofx"); |
49 | oneoverx = Resource::loadPixmap("oneoverx"); | 49 | oneoverx = Resource::loadPixmap("oneoverx"); |
50 | 50 | ||
51 | memMark = new QLabel( "m", LCD ); | 51 | memMark = new QLabel( "m", LCD ); |
52 | memMark->setFont( QFont( "helvetica", 12, QFont::Bold, TRUE ) ); | 52 | memMark->setFont( QFont( "helvetica", 12, QFont::Bold, TRUE ) ); |
53 | memMark->resize( 12, 12 ); | 53 | memMark->resize( 12, 12 ); |
54 | memMark->move( 4, 2 ); | 54 | memMark->move( 4, 2 ); |
55 | memMark->hide(); | 55 | memMark->hide(); |
56 | mem = 0; | 56 | mem = 0; |
@@ -111,160 +111,160 @@ CalculatorImpl::CalculatorImpl( QWidget * parent, const char * name, | |||
111 | } | 111 | } |
112 | connect( &bgr_function, SIGNAL(clicked(int) ) , this, SLOT(do_convert(int) ) ); | 112 | connect( &bgr_function, SIGNAL(clicked(int) ) , this, SLOT(do_convert(int) ) ); |
113 | connect( &bgr_function, SIGNAL(clicked(int) ) , this, SLOT(std_funcs (int) ) ); | 113 | connect( &bgr_function, SIGNAL(clicked(int) ) , this, SLOT(std_funcs (int) ) ); |
114 | 114 | ||
115 | connect(ComboBoxFunction, SIGNAL(activated(int) ), this, SLOT(function_button(int) ) ); | 115 | connect(ComboBoxFunction, SIGNAL(activated(int) ), this, SLOT(function_button(int) ) ); |
116 | 116 | ||
117 | captions.append("Standard"); | 117 | captions.append("Standard"); |
118 | ComboBoxFunction->insertItem(captions.last()); | 118 | ComboBoxFunction->insertItem(captions.last()); |
119 | 119 | ||
120 | // now add in the conversion modes | 120 | // now add in the conversion modes |
121 | // when the menu gets done, these should be in a submenu | 121 | // when the menu gets done, these should be in a submenu |
122 | QString tmp = QPEApplication::qpeDir(); | 122 | QString tmp = QPEApplication::qpeDir(); |
123 | tmp += "/etc/unit_conversion.dat"; | 123 | tmp += "etc/unit_conversion.dat"; |
124 | QFile myfile(tmp); | 124 | QFile myfile(tmp); |
125 | if ( !myfile.open( IO_Translate | IO_ReadOnly ) ) { | 125 | if ( !myfile.open( IO_Translate | IO_ReadOnly ) ) { |
126 | // QMessageBox::warning(this, "Warning", "Data file\nunit_conversion.dat\nnot found\nNo conversion\nfeatures will\nbe available"); | 126 | 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 | 127 | // disable the f button if no conv file available |
128 | ComboBoxFunction->setEnabled(FALSE); | 128 | ComboBoxFunction->setEnabled(FALSE); |
129 | } | 129 | } |
130 | else { | 130 | else { |
131 | QString line, line2; | 131 | QString line, line2; |
132 | QTextStream ts(&myfile); | 132 | QTextStream ts(&myfile); |
133 | 133 | ||
134 | // first pass, see how many conversion types there are in order to allocate for them | 134 | // first pass, see how many conversion types there are in order to allocate for them |
135 | while ( ! ts.eof() ) { | 135 | while ( ! ts.eof() ) { |
136 | line = ts.readLine(); | 136 | line = ts.readLine(); |
137 | if ( line.contains ("STARTTYPE" ) ) | 137 | if ( line.contains ("STARTTYPE" ) ) |
138 | conversion_mode_count++; | 138 | conversion_mode_count++; |
139 | } | 139 | } |
140 | 140 | ||
141 | entry_list = new double[conversion_mode_count*func_button_count]; | 141 | entry_list = new double[conversion_mode_count*func_button_count]; |
142 | preoffset_list = new double[conversion_mode_count*func_button_count]; | 142 | preoffset_list = new double[conversion_mode_count*func_button_count]; |
143 | postoffset_list = new double[conversion_mode_count*func_button_count]; | 143 | postoffset_list = new double[conversion_mode_count*func_button_count]; |
144 | myfile.close(); | 144 | myfile.close(); |
145 | myfile.open( IO_Translate | IO_ReadOnly ); | 145 | myfile.open( IO_Translate | IO_ReadOnly ); |
146 | QTextStream ts2(&myfile); | 146 | QTextStream ts2(&myfile); |
147 | 147 | ||
148 | // second pass, read in values | 148 | // second pass, read in values |
149 | int x = 0; | 149 | int x = 0; |
150 | while ( ! ts2.eof() ) { | 150 | while ( ! ts2.eof() ) { |
151 | line = ts2.readLine(); | 151 | line = ts2.readLine(); |
152 | if ( line.contains("STARTTYPE") ) { | 152 | if ( line.contains("STARTTYPE") ) { |
153 | captions << line.remove(0,10); | 153 | captions << line.remove(0,10); |
154 | ComboBoxFunction->insertItem(captions.last()); | 154 | ComboBoxFunction->insertItem(captions.last()); |
155 | while ( !line.contains("ENDTYPE") ) { | 155 | while ( !line.contains("ENDTYPE") ) { |
156 | line = ts2.readLine(); | 156 | line = ts2.readLine(); |
157 | if ( line.contains("NAME") ) { | 157 | if ( line.contains("NAME") ) { |
158 | faces << line.remove(0,5); | 158 | faces << line.remove(0,5); |
159 | line2 = ts2.readLine(); | 159 | line2 = ts2.readLine(); |
160 | line2.remove(0,6); | 160 | line2.remove(0,6); |
161 | entry_list[x] = line2.toDouble(); | 161 | entry_list[x] = line2.toDouble(); |
162 | line2 = ts2.readLine(); | 162 | line2 = ts2.readLine(); |
163 | line2.remove(0,7); | 163 | line2.remove(0,7); |
164 | preoffset_list[x] = line2.toDouble(); | 164 | preoffset_list[x] = line2.toDouble(); |
165 | line2 = ts2.readLine(); | 165 | line2 = ts2.readLine(); |
166 | line2.remove(0,8); | 166 | line2.remove(0,8); |
167 | postoffset_list[x] = line2.toDouble(); | 167 | postoffset_list[x] = line2.toDouble(); |
168 | x++; | 168 | x++; |
169 | } | 169 | } |
170 | } | 170 | } |
171 | } | 171 | } |
172 | } | 172 | } |
173 | } | 173 | } |
174 | myfile.close(); | 174 | myfile.close(); |
175 | clear(); | 175 | clear(); |
176 | max_mode = pre_conv_modes_count + conversion_mode_count + post_conv_modes_count - 1; | 176 | max_mode = pre_conv_modes_count + conversion_mode_count + post_conv_modes_count - 1; |
177 | display_pixmap_faces(); | 177 | display_pixmap_faces(); |
178 | 178 | ||
179 | qApp->installEventFilter( this ); | 179 | qApp->installEventFilter( this ); |
180 | } | 180 | } |
181 | 181 | ||
182 | bool CalculatorImpl::eventFilter( QObject *o, QEvent *e ) | 182 | bool CalculatorImpl::eventFilter( QObject *o, QEvent *e ) |
183 | { | 183 | { |
184 | if ( e->type() == QEvent::KeyPress && state != sError ) { | 184 | if ( e->type() == QEvent::KeyPress && state != sError ) { |
185 | QKeyEvent *k = (QKeyEvent*)e; | 185 | QKeyEvent *k = (QKeyEvent*)e; |
186 | if ( k->key() >= Key_0 && k->key() <= Key_9 ) { | 186 | if ( k->key() >= Key_0 && k->key() <= Key_9 ) { |
187 | enterNumber( k->key() - Key_0 ); | 187 | enterNumber( k->key() - Key_0 ); |
188 | return true; | 188 | return true; |
189 | } else { | 189 | } else { |
190 | switch ( k->key() ) { | 190 | switch ( k->key() ) { |
191 | case Key_Equal: | 191 | case Key_Equal: |
192 | std_buttons(0); | 192 | std_buttons(0); |
193 | return true; | 193 | return true; |
194 | case Key_Period: | 194 | case Key_Period: |
195 | std_buttons(1); | 195 | std_buttons(1); |
196 | return true; | 196 | return true; |
197 | case Key_Plus: | 197 | case Key_Plus: |
198 | std_buttons(2); | 198 | std_buttons(2); |
199 | return true; | 199 | return true; |
200 | case Key_Minus: | 200 | case Key_Minus: |
201 | std_buttons(3); | 201 | std_buttons(3); |
202 | return true; | 202 | return true; |
203 | case Key_Slash: | 203 | case Key_Slash: |
204 | std_buttons(4); | 204 | std_buttons(4); |
205 | return true; | 205 | return true; |
206 | case Key_Asterisk: | 206 | case Key_Asterisk: |
207 | std_buttons(5); | 207 | std_buttons(5); |
208 | return true; | 208 | return true; |
209 | case Key_Percent: | 209 | case Key_Percent: |
210 | execOp( oPercent ); | 210 | execOp( oPercent ); |
211 | return true; | 211 | return true; |
212 | case Key_ParenLeft: | 212 | case Key_ParenLeft: |
213 | if ( current_mode < pre_conv_modes_count ) | 213 | if ( current_mode < pre_conv_modes_count ) |
214 | execOp( oOpenBrace ); | 214 | execOp( oOpenBrace ); |
215 | return true; | 215 | return true; |
216 | case Key_ParenRight: | 216 | case Key_ParenRight: |
217 | if ( current_mode < pre_conv_modes_count ) | 217 | if ( current_mode < pre_conv_modes_count ) |
218 | execOp( oCloseBrace ); | 218 | execOp( oCloseBrace ); |
219 | return true; | 219 | return true; |
220 | default: | 220 | default: |
221 | break; | 221 | break; |
222 | } | 222 | } |
223 | } | 223 | } |
224 | } | 224 | } |
225 | return Calculator::eventFilter( o, e ); | 225 | return Calculator::eventFilter( o, e ); |
226 | } | 226 | } |
227 | 227 | ||
228 | void CalculatorImpl::do_convert(int button) { | 228 | void CalculatorImpl::do_convert(int button) { |
229 | if ( state == sError ) | 229 | if ( state == sError ) |
230 | return; | 230 | return; |
231 | if ( current_mode >= pre_conv_modes_count && current_mode <= (max_mode - post_conv_modes_count) && | 231 | if ( current_mode >= pre_conv_modes_count && current_mode <= (max_mode - post_conv_modes_count) && |
232 | button < changeable_func_button_count ) { | 232 | button < changeable_func_button_count ) { |
233 | if ( last_conversion > -1 ) { | 233 | if ( last_conversion > -1 ) { |
234 | if( state == sNewNumber ){ | 234 | if( state == sNewNumber ){ |
235 | acc = (num+ preoffset_list[(current_mode - pre_conv_modes_count) * func_button_count + last_conversion]) | 235 | 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]) | 236 | / (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]) | 237 | * (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]; | 238 | +postoffset_list[(current_mode - pre_conv_modes_count) * func_button_count + button]; |
239 | num = acc; | 239 | num = acc; |
240 | LCD->display( acc ); | 240 | LCD->display( acc ); |
241 | } else { | 241 | } else { |
242 | state = sNewNumber; | 242 | state = sNewNumber; |
243 | num = (num+ preoffset_list[(current_mode - pre_conv_modes_count) * func_button_count + last_conversion]) | 243 | 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]) | 244 | / (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]) | 245 | * (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];; | 246 | + postoffset_list[(current_mode - pre_conv_modes_count) * func_button_count + button];; |
247 | LCD->display( num ); | 247 | LCD->display( num ); |
248 | acc = num; | 248 | acc = num; |
249 | } | 249 | } |
250 | } | 250 | } |
251 | last_conversion = button; | 251 | last_conversion = button; |
252 | } | 252 | } |
253 | } | 253 | } |
254 | 254 | ||
255 | 255 | ||
256 | void CalculatorImpl::function_button(int mode){ | 256 | void CalculatorImpl::function_button(int mode){ |
257 | if ( state == sError ) | 257 | if ( state == sError ) |
258 | clear(); | 258 | clear(); |
259 | // dont need the next line when using a popup menu | 259 | // dont need the next line when using a popup menu |
260 | current_mode = mode; | 260 | current_mode = mode; |
261 | 261 | ||
262 | // reset the last conv | 262 | // reset the last conv |
263 | last_conversion = -1; | 263 | last_conversion = -1; |
264 | 264 | ||
265 | // set the caption | 265 | // set the caption |
266 | this->setCaption( captions[current_mode] ); | 266 | this->setCaption( captions[current_mode] ); |
267 | 267 | ||
268 | reset_conv(); | 268 | reset_conv(); |
269 | 269 | ||
270 | for ( int x = 0 ; x < changeable_func_button_count ; x++ ) { | 270 | for ( int x = 0 ; x < changeable_func_button_count ; x++ ) { |
@@ -319,297 +319,297 @@ void CalculatorImpl::reset_conv() { | |||
319 | // dont carry any selections into the next mode | 319 | // dont carry any selections into the next mode |
320 | if ( tmpbutton->state() == QPushButton::On ) { | 320 | if ( tmpbutton->state() == QPushButton::On ) { |
321 | tmpbutton->toggle(); | 321 | tmpbutton->toggle(); |
322 | } | 322 | } |
323 | } | 323 | } |
324 | 324 | ||
325 | last_conversion = -1; | 325 | last_conversion = -1; |
326 | } | 326 | } |
327 | 327 | ||
328 | void CalculatorImpl::std_buttons(int button) | 328 | void CalculatorImpl::std_buttons(int button) |
329 | { | 329 | { |
330 | if ( state == sError ) | 330 | if ( state == sError ) |
331 | return; | 331 | return; |
332 | execOp( (Operation)(button + oSum) ); | 332 | execOp( (Operation)(button + oSum) ); |
333 | } | 333 | } |
334 | 334 | ||
335 | void CalculatorImpl::std_funcs(int button) { | 335 | void CalculatorImpl::std_funcs(int button) { |
336 | if ( state == sError ) | 336 | if ( state == sError ) |
337 | return; | 337 | return; |
338 | if ( current_mode < pre_conv_modes_count || | 338 | if ( current_mode < pre_conv_modes_count || |
339 | button > changeable_func_button_count-1 ) { | 339 | button > changeable_func_button_count-1 ) { |
340 | Operation op; | 340 | Operation op; |
341 | if ( button < 10 ) | 341 | if ( button < 10 ) |
342 | op = (Operation)(button + oSin); | 342 | op = (Operation)(button + oSin); |
343 | else if ( button == 10 ) | 343 | else if ( button == 10 ) |
344 | op = oOpenBrace; | 344 | op = oOpenBrace; |
345 | else | 345 | else |
346 | op = oCloseBrace; | 346 | op = oCloseBrace; |
347 | execOp( op ); | 347 | execOp( op ); |
348 | } | 348 | } |
349 | } | 349 | } |
350 | 350 | ||
351 | void CalculatorImpl::execOp( Operation i ) | 351 | void CalculatorImpl::execOp( Operation i ) |
352 | { | 352 | { |
353 | switch (i) { | 353 | switch (i) { |
354 | // these operators only affect the current number. | 354 | // these operators only affect the current number. |
355 | case oDivX: | 355 | case oDivX: |
356 | case oLog: | 356 | case oLog: |
357 | case oLn: | 357 | case oLn: |
358 | case oSin: | 358 | case oSin: |
359 | case oCos: | 359 | case oCos: |
360 | case oTan: | 360 | case oTan: |
361 | num = evalExpr(i); | 361 | num = evalExpr(i); |
362 | break; | 362 | break; |
363 | 363 | ||
364 | case oAdd: | 364 | case oAdd: |
365 | case oSub: { | 365 | case oSub: { |
366 | processStack( oAdd ); | 366 | processStack( oAdd ); |
367 | Op op( num, i ); | 367 | Op op( num, i ); |
368 | operationStack.push( op ); | 368 | operationStack.push( op ); |
369 | break; | 369 | break; |
370 | } | 370 | } |
371 | case oDiv: | 371 | case oDiv: |
372 | case oMult: | 372 | case oMult: |
373 | case oRoot: | 373 | case oRoot: |
374 | case oXsquared: { | 374 | case oXsquared: { |
375 | processStack( oDiv ); | 375 | processStack( oDiv ); |
376 | Op op( num, i ); | 376 | Op op( num, i ); |
377 | operationStack.push( op ); | 377 | operationStack.push( op ); |
378 | break; | 378 | break; |
379 | } | 379 | } |
380 | case oChSign: | 380 | case oChSign: |
381 | num = -num; | 381 | num = -num; |
382 | LCD->display(num); | 382 | LCD->display(num); |
383 | return; | 383 | return; |
384 | 384 | ||
385 | case oOpenBrace: { | 385 | case oOpenBrace: { |
386 | Op op( 0, oOpenBrace ); | 386 | Op op( 0, oOpenBrace ); |
387 | operationStack.push( op ); | 387 | operationStack.push( op ); |
388 | numOpenBraces++; | 388 | numOpenBraces++; |
389 | state = sNewNumber; | 389 | state = sNewNumber; |
390 | return; | 390 | return; |
391 | } | 391 | } |
392 | case oCloseBrace: { | 392 | case oCloseBrace: { |
393 | if ( numOpenBraces == 0 ) | 393 | if ( numOpenBraces == 0 ) |
394 | return; | 394 | return; |
395 | processStack( oAdd ); | 395 | processStack( oAdd ); |
396 | if ( operationStack.top().operation != oOpenBrace ) | 396 | if ( operationStack.top().operation != oOpenBrace ) |
397 | qDebug( "Calculator: internal Error" ); | 397 | qDebug( "Calculator: internal Error" ); |
398 | operationStack.pop(); | 398 | operationStack.pop(); |
399 | state = sNewNumber; | 399 | state = sNewNumber; |
400 | numOpenBraces--; | 400 | numOpenBraces--; |
401 | break; | 401 | break; |
402 | } | 402 | } |
403 | 403 | ||
404 | case oPoint: | 404 | case oPoint: |
405 | flPoint = TRUE; | 405 | flPoint = TRUE; |
406 | return; | 406 | return; |
407 | 407 | ||
408 | case oPercent: | 408 | case oPercent: |
409 | processStack( oPercent ); | 409 | processStack( oPercent ); |
410 | break; | 410 | break; |
411 | 411 | ||
412 | 412 | ||
413 | case oSum: | 413 | case oSum: |
414 | processStack( oSum ); | 414 | processStack( oSum ); |
415 | break; | 415 | break; |
416 | 416 | ||
417 | default: | 417 | default: |
418 | return; | 418 | return; |
419 | }; | 419 | }; |
420 | 420 | ||
421 | if ( state == sError ) { | 421 | if ( state == sError ) { |
422 | LCD->display( "Error" ); | 422 | LCD->display( "Error" ); |
423 | return; | 423 | return; |
424 | } else { | 424 | } else { |
425 | LCD->display(num); | 425 | LCD->display(num); |
426 | } | 426 | } |
427 | state = sNewNumber; | 427 | state = sNewNumber; |
428 | numDecimals = 0; | 428 | numDecimals = 0; |
429 | flPoint = FALSE; | 429 | flPoint = FALSE; |
430 | } | 430 | } |
431 | 431 | ||
432 | 432 | ||
433 | void CalculatorImpl::processStack( int op ) | 433 | void CalculatorImpl::processStack( int op ) |
434 | { | 434 | { |
435 | //dubious percent hack, since the changeable operator precedences are | 435 | //dubious percent hack, since the changeable operator precedences are |
436 | //pretty much hardwired to be less than the non-changeable | 436 | //pretty much hardwired to be less than the non-changeable |
437 | bool percent = FALSE; | 437 | bool percent = FALSE; |
438 | if ( op == oPercent ) { | 438 | if ( op == oPercent ) { |
439 | percent = TRUE; | 439 | percent = TRUE; |
440 | op = oSum; | 440 | op = oSum; |
441 | } | 441 | } |
442 | while( !operationStack.isEmpty() && operationStack.top().operation >= op ) { | 442 | while( !operationStack.isEmpty() && operationStack.top().operation >= op ) { |
443 | Op operation = operationStack.pop(); | 443 | Op operation = operationStack.pop(); |
444 | acc = operation.number; | 444 | acc = operation.number; |
445 | if ( percent ) { | 445 | if ( percent ) { |
446 | if ( operation.operation == oAdd || operation.operation == oSub ) | 446 | if ( operation.operation == oAdd || operation.operation == oSub ) |
447 | num = acc*num/100; | 447 | num = acc*num/100; |
448 | else | 448 | else |
449 | num = num / 100; | 449 | num = num / 100; |
450 | } | 450 | } |
451 | num = evalExpr( operation.operation ); | 451 | num = evalExpr( operation.operation ); |
452 | percent = FALSE; | 452 | percent = FALSE; |
453 | } | 453 | } |
454 | } | 454 | } |
455 | 455 | ||
456 | 456 | ||
457 | double CalculatorImpl::evalExpr( int op ) { | 457 | double CalculatorImpl::evalExpr( int op ) { |
458 | double sum = 0; | 458 | double sum = 0; |
459 | 459 | ||
460 | switch( op ){ | 460 | switch( op ){ |
461 | case oPercent: sum = num / 100.; break; | 461 | case oPercent: sum = num / 100.; break; |
462 | case oDivX: | 462 | case oDivX: |
463 | if (num == 0) | 463 | if (num == 0) |
464 | state = sError; | 464 | state = sError; |
465 | else | 465 | else |
466 | sum = 1 / num; | 466 | sum = 1 / num; |
467 | break; | 467 | break; |
468 | case oXsquared: | 468 | case oXsquared: |
469 | sum = pow(acc,num); | 469 | sum = pow(acc,num); |
470 | break; | 470 | break; |
471 | case oChSign: (state == sStart) ? sum = -num : sum = -acc; break; | 471 | case oChSign: (state == sStart) ? sum = -num : sum = -acc; break; |
472 | case oSub: sum = acc - num; break; | 472 | case oSub: sum = acc - num; break; |
473 | case oMult: sum = acc * num; break; | 473 | case oMult: sum = acc * num; break; |
474 | case oAdd: sum = acc + num; break; | 474 | case oAdd: sum = acc + num; break; |
475 | case oDiv: { | 475 | case oDiv: { |
476 | if (num == 0) { | 476 | if (num == 0) { |
477 | state = sError; | 477 | state = sError; |
478 | } else { | 478 | } else { |
479 | sum = acc / num; | 479 | sum = acc / num; |
480 | } | 480 | } |
481 | break; | 481 | break; |
482 | } | 482 | } |
483 | case oRoot: | 483 | case oRoot: |
484 | /* the linux library is dumb, and can't to -x to 1/n | 484 | /* 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 */ | 485 | when n is odd. (even and error of course is acceptable */ |
486 | if((acc < 0) && (int(num) == num) && (int(num) % 2 == 1 )) { | 486 | if((acc < 0) && (int(num) == num) && (int(num) % 2 == 1 )) { |
487 | sum = pow(-acc, 1 / num); | 487 | sum = pow(-acc, 1 / num); |
488 | sum = -sum; | 488 | sum = -sum; |
489 | } else { | 489 | } else { |
490 | sum = pow(acc, 1 / num); | 490 | sum = pow(acc, 1 / num); |
491 | } | 491 | } |
492 | break; | 492 | break; |
493 | case oLog: | 493 | case oLog: |
494 | sum = log10(num); | 494 | sum = log10(num); |
495 | break; | 495 | break; |
496 | case oLn: | 496 | case oLn: |
497 | sum = log(num); | 497 | sum = log(num); |
498 | break; | 498 | break; |
499 | case oTan: sum = qTan(num);break; | 499 | case oTan: sum = qTan(num);break; |
500 | case oSin: sum = qSin(num);break; | 500 | case oSin: sum = qSin(num);break; |
501 | case oCos: sum = qCos(num);break; | 501 | case oCos: sum = qCos(num);break; |
502 | default: sum = num; break; | 502 | default: sum = num; break; |
503 | } | 503 | } |
504 | 504 | ||
505 | if ( isinf( sum ) || isnan( sum ) ) | 505 | if ( isinf( sum ) || isnan( sum ) ) |
506 | state = sError; | 506 | state = sError; |
507 | return sum; | 507 | return sum; |
508 | } | 508 | } |
509 | 509 | ||
510 | 510 | ||
511 | void CalculatorImpl::enterNumber( int n ) | 511 | void CalculatorImpl::enterNumber( int n ) |
512 | { | 512 | { |
513 | if ( state == sError ) | 513 | if ( state == sError ) |
514 | return; | 514 | return; |
515 | if( state == sStart ){ | 515 | if( state == sStart ){ |
516 | if( LCD->value() > 0 ){ | 516 | if( LCD->value() > 0 ){ |
517 | QString s = QString::number( LCD->value(), 'g', LCD->numDigits()); | 517 | QString s = QString::number( LCD->value(), 'g', LCD->numDigits()); |
518 | if( s.length() > (uint)(LCD->numDigits() - 2)) return; | 518 | if( s.length() > (uint)(LCD->numDigits() - 2)) return; |
519 | 519 | ||
520 | } else if( (int)fake.length() >= LCD->numDigits() || numDecimals >=12 ){ | 520 | } else if( (int)fake.length() >= LCD->numDigits() || numDecimals >=12 ){ |
521 | return; | 521 | return; |
522 | } | 522 | } |
523 | } | 523 | } |
524 | 524 | ||
525 | if( state == sNewNumber ){ | 525 | if( state == sNewNumber ){ |
526 | state = sStart; | 526 | state = sStart; |
527 | acc = 0; | 527 | acc = 0; |
528 | if( flPoint ){ | 528 | if( flPoint ){ |
529 | numDecimals = 1; | 529 | numDecimals = 1; |
530 | num = n / pow(10, numDecimals); | 530 | num = n / pow(10, numDecimals); |
531 | } else | 531 | } else |
532 | num = n; | 532 | num = n; |
533 | } else if( flPoint ){ | 533 | } else if( flPoint ){ |
534 | numDecimals++; | 534 | numDecimals++; |
535 | if( num < 0 ){ | 535 | if( num < 0 ){ |
536 | num -= n / pow(10, numDecimals); | 536 | num -= n / pow(10, numDecimals); |
537 | } else { | 537 | } else { |
538 | num += n / pow(10, numDecimals); | 538 | num += n / pow(10, numDecimals); |
539 | } | 539 | } |
540 | } else { | 540 | } else { |
541 | num *= 10; | 541 | num *= 10; |
542 | if( num < 0 ) | 542 | if( num < 0 ) |
543 | num -= n; | 543 | num -= n; |
544 | else | 544 | else |
545 | num += n; | 545 | num += n; |
546 | } | 546 | } |
547 | 547 | ||
548 | // We need feedback in the calc display while entering fl.point zeros. | 548 | // We need feedback in the calc display while entering fl.point zeros. |
549 | // This is a small hack to display sequences like: 0.000 and 1.100 | 549 | // This is a small hack to display sequences like: 0.000 and 1.100 |
550 | double integer, fraction; | 550 | double integer, fraction; |
551 | fraction = modf( num, &integer ); | 551 | fraction = modf( num, &integer ); |
552 | if( flPoint ){ | 552 | if( flPoint ){ |
553 | QString is, fs, zeros; | 553 | QString is, fs, zeros; |
554 | 554 | ||
555 | is = QString::number( integer, 'g', 13 ); | 555 | is = QString::number( integer, 'g', 13 ); |
556 | fs = QString::number( fraction, 'g', numDecimals ); | 556 | fs = QString::number( fraction, 'g', numDecimals ); |
557 | if( fs.contains('e') ){ | 557 | if( fs.contains('e') ){ |
558 | fs = QString::number( fraction, 'f', LCD->numDigits() ); | 558 | fs = QString::number( fraction, 'f', LCD->numDigits() ); |
559 | } | 559 | } |
560 | fs = fs.mid( 2, numDecimals ); | 560 | fs = fs.mid( 2, numDecimals ); |
561 | 561 | ||
562 | if( (integer == 0) && (fraction == 0) ) | 562 | if( (integer == 0) && (fraction == 0) ) |
563 | fake = "0."; | 563 | fake = "0."; |
564 | else if( (integer != 0) && (fraction == 0) ) | 564 | else if( (integer != 0) && (fraction == 0) ) |
565 | fake = is + "."; | 565 | fake = is + "."; |
566 | else | 566 | else |
567 | fake = is + "." + fs; | 567 | fake = is + "." + fs; |
568 | 568 | ||
569 | zeros.fill( '0', (numDecimals - fs.length()) ); | 569 | zeros.fill( '0', (numDecimals - fs.length()) ); |
570 | fake += zeros; | 570 | fake += zeros; |
571 | // ### This code sets LCD->value() to zero since it sets a text | 571 | // ### This code sets LCD->value() to zero since it sets a text |
572 | // ### Avoid getting the current value from LCD->value() for | 572 | // ### Avoid getting the current value from LCD->value() for |
573 | // ### calculations. | 573 | // ### calculations. |
574 | LCD->display( fake ); | 574 | LCD->display( fake ); |
575 | } else | 575 | } else |
576 | LCD->display( num ); | 576 | LCD->display( num ); |
577 | } | 577 | } |
578 | 578 | ||
579 | void CalculatorImpl::command_buttons(int i) { | 579 | void CalculatorImpl::command_buttons(int i) { |
580 | if ( state == sError && i != 3 ) | 580 | if ( state == sError && i != 3 ) |
581 | return; | 581 | return; |
582 | switch (i) { | 582 | switch (i) { |
583 | case 0: // M+ | 583 | case 0: // M+ |
584 | mem += num; | 584 | mem += num; |
585 | if( mem != 0 ){ | 585 | if( mem != 0 ){ |
586 | memMark->show(); | 586 | memMark->show(); |
587 | PushButtonMR->setEnabled( TRUE ); }; | 587 | PushButtonMR->setEnabled( TRUE ); }; |
588 | state = sNewNumber; | 588 | state = sNewNumber; |
589 | break; | 589 | break; |
590 | case 1: // MR | 590 | case 1: // MR |
591 | acc = num = mem; | 591 | acc = num = mem; |
592 | state = sNewNumber; | 592 | state = sNewNumber; |
593 | LCD->display( mem ); | 593 | LCD->display( mem ); |
594 | break; | 594 | break; |
595 | case 2: // MC | 595 | case 2: // MC |
596 | mem = 0; | 596 | mem = 0; |
597 | memMark->hide(); | 597 | memMark->hide(); |
598 | PushButtonMR->setEnabled( FALSE ); | 598 | PushButtonMR->setEnabled( FALSE ); |
599 | break; | 599 | break; |
600 | case 3: // CE | 600 | case 3: // CE |
601 | if ( state == sStart ) { | 601 | if ( state == sStart ) { |
602 | // clear the entered number on the first press | 602 | // clear the entered number on the first press |
603 | state = sNewNumber; | 603 | state = sNewNumber; |
604 | num = acc = 0; | 604 | num = acc = 0; |
605 | flPoint = FALSE; | 605 | flPoint = FALSE; |
606 | LCD->display( 0 ); | 606 | LCD->display( 0 ); |
607 | fake = QString::null; | 607 | fake = QString::null; |
608 | numDecimals = 0; | 608 | numDecimals = 0; |
609 | } else { | 609 | } else { |
610 | clear(); | 610 | clear(); |
611 | } | 611 | } |
612 | break; | 612 | break; |
613 | }; | 613 | }; |
614 | 614 | ||
615 | } | 615 | } |