summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/tools/calculator/calculatorimpl.cpp498
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
43CalculatorImpl::CalculatorImpl( QWidget * parent, const char * name, 43CalculatorImpl::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
182bool CalculatorImpl::eventFilter( QObject *o, QEvent *e ) 182bool 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
228void CalculatorImpl::do_convert(int button) { 228void 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
256void CalculatorImpl::function_button(int mode){ 256void 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
328void CalculatorImpl::std_buttons(int button) 328void 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
335void CalculatorImpl::std_funcs(int button) { 335void 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
351void CalculatorImpl::execOp( Operation i ) 351void 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
433void CalculatorImpl::processStack( int op ) 433void 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
457double CalculatorImpl::evalExpr( int op ) { 457double 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
511void CalculatorImpl::enterNumber( int n ) 511void 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
579void CalculatorImpl::command_buttons(int i) { 579void 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}