author | llornkcor <llornkcor> | 2002-02-17 16:45:31 (UTC) |
---|---|---|
committer | llornkcor <llornkcor> | 2002-02-17 16:45:31 (UTC) |
commit | f47194f17380a4af76d185036eff2dc4d1a44bed (patch) (side-by-side diff) | |
tree | 13466a7a8623e73624902ac814b539c990c3e578 | |
parent | 0f454a59bab0cf9d41e8d778f37c56e9a8a13e72 (diff) | |
download | opie-f47194f17380a4af76d185036eff2dc4d1a44bed.zip opie-f47194f17380a4af76d185036eff2dc4d1a44bed.tar.gz opie-f47194f17380a4af76d185036eff2dc4d1a44bed.tar.bz2 |
fixed small bug in desktop version, where conversion dat wasn't being found.
-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 @@ -1,615 +1,615 @@ /********************************************************************** ** Copyright (C) 2000 Trolltech AS. All rights reserved. ** ** This file is part of Qtopia Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ /* * 01/14/2002 Charles-Edouard Ruault <ce@ruault.com> * Added support for Temperature conversions. */ #include "calculatorimpl.h" #include <qpe/resource.h> #include <qpe/qmath.h> #include <qpe/qpeapplication.h> #include <qpushbutton.h> #include <qcombobox.h> #include <qlabel.h> #include <qfont.h> #include <qlayout.h> #include <qstringlist.h> #include <qfile.h> #include <qtextstream.h> #include <qmessagebox.h> #include <math.h> CalculatorImpl::CalculatorImpl( QWidget * parent, const char * name, - WFlags f ) + WFlags f ) : Calculator( parent, name, f ) { xtopowerofy = Resource::loadPixmap("xtopowerofy"); ythrootofx = Resource::loadPixmap("ythrootofx"); oneoverx = Resource::loadPixmap("oneoverx"); memMark = new QLabel( "m", LCD ); memMark->setFont( QFont( "helvetica", 12, QFont::Bold, TRUE ) ); memMark->resize( 12, 12 ); memMark->move( 4, 2 ); memMark->hide(); mem = 0; PushButtonMR->setEnabled( FALSE ); current_mode = max_mode = conversion_mode_count = 0; last_conversion = -1; //bgr_command.insert( PushButtonFunction); bgr_command.insert( PushButtonMPlus); bgr_command.insert( PushButtonMR); bgr_command.insert( PushButtonMC); bgr_command.insert( PushButtonCE); connect( &bgr_command, SIGNAL(clicked(int) ), this, SLOT(command_buttons(int))); bgr_digits.insert(PushButton0); bgr_digits.insert(PushButton1); bgr_digits.insert(PushButton2); bgr_digits.insert(PushButton3); bgr_digits.insert(PushButton4); bgr_digits.insert(PushButton5); bgr_digits.insert(PushButton6); bgr_digits.insert(PushButton7); bgr_digits.insert(PushButton8); bgr_digits.insert(PushButton9); connect( &bgr_digits, SIGNAL(clicked(int) ), this, SLOT(enterNumber(int))); bgr_std.insert(PushButtonEquals); bgr_std.insert(PushButtonDecimal); bgr_std.insert(PushButtonAdd); bgr_std.insert(PushButtonMinus); bgr_std.insert(PushButtonDivide); bgr_std.insert(PushButtonTimes); connect( &bgr_std, SIGNAL(clicked(int) ), this, SLOT(std_buttons(int))); // change the / to a proper division signal PushButtonDivide->setText(QChar(0xF7)); func_buttons[0] = PushButtonF1; func_buttons[1] = PushButtonF2; func_buttons[2] = PushButtonF3; func_buttons[3] = PushButtonF4; func_buttons[4] = PushButtonF5; func_buttons[5] = PushButtonF6; func_buttons[6] = PushButtonF7; func_buttons[7] = PushButtonF8; func_buttons[8] = PushButtonF9; func_buttons[9] = PushButtonF10; func_buttons[10] = PushButtonF11; func_buttons[11] = PushButtonF12; for ( int x = 0 ; x < func_button_count ; x++ ) { QPushButton* tmpbutton = func_buttons[x]; faces << tmpbutton->text(); bgr_function.insert(tmpbutton); } connect( &bgr_function, SIGNAL(clicked(int) ) , this, SLOT(do_convert(int) ) ); connect( &bgr_function, SIGNAL(clicked(int) ) , this, SLOT(std_funcs (int) ) ); connect(ComboBoxFunction, SIGNAL(activated(int) ), this, SLOT(function_button(int) ) ); captions.append("Standard"); ComboBoxFunction->insertItem(captions.last()); // now add in the conversion modes // when the menu gets done, these should be in a submenu QString tmp = QPEApplication::qpeDir(); - tmp += "/etc/unit_conversion.dat"; + tmp += "etc/unit_conversion.dat"; QFile myfile(tmp); if ( !myfile.open( IO_Translate | IO_ReadOnly ) ) { - // QMessageBox::warning(this, "Warning", "Data file\nunit_conversion.dat\nnot found\nNo conversion\nfeatures will\nbe available"); + qDebug("Data file unit_conversion.dat not found\nNo conversion features will be available\n"+tmp); // disable the f button if no conv file available ComboBoxFunction->setEnabled(FALSE); } else { QString line, line2; QTextStream ts(&myfile); // first pass, see how many conversion types there are in order to allocate for them while ( ! ts.eof() ) { line = ts.readLine(); if ( line.contains ("STARTTYPE" ) ) conversion_mode_count++; } entry_list = new double[conversion_mode_count*func_button_count]; - preoffset_list = new double[conversion_mode_count*func_button_count]; - postoffset_list = new double[conversion_mode_count*func_button_count]; + preoffset_list = new double[conversion_mode_count*func_button_count]; + postoffset_list = new double[conversion_mode_count*func_button_count]; myfile.close(); myfile.open( IO_Translate | IO_ReadOnly ); QTextStream ts2(&myfile); // second pass, read in values int x = 0; while ( ! ts2.eof() ) { line = ts2.readLine(); if ( line.contains("STARTTYPE") ) { captions << line.remove(0,10); - ComboBoxFunction->insertItem(captions.last()); + ComboBoxFunction->insertItem(captions.last()); while ( !line.contains("ENDTYPE") ) { line = ts2.readLine(); if ( line.contains("NAME") ) { faces << line.remove(0,5); line2 = ts2.readLine(); line2.remove(0,6); entry_list[x] = line2.toDouble(); - line2 = ts2.readLine(); + line2 = ts2.readLine(); line2.remove(0,7); preoffset_list[x] = line2.toDouble(); - line2 = ts2.readLine(); + line2 = ts2.readLine(); line2.remove(0,8); postoffset_list[x] = line2.toDouble(); x++; } } } } } myfile.close(); clear(); max_mode = pre_conv_modes_count + conversion_mode_count + post_conv_modes_count - 1; display_pixmap_faces(); qApp->installEventFilter( this ); } bool CalculatorImpl::eventFilter( QObject *o, QEvent *e ) { if ( e->type() == QEvent::KeyPress && state != sError ) { - QKeyEvent *k = (QKeyEvent*)e; - if ( k->key() >= Key_0 && k->key() <= Key_9 ) { - enterNumber( k->key() - Key_0 ); - return true; - } else { - switch ( k->key() ) { - case Key_Equal: - std_buttons(0); - return true; - case Key_Period: - std_buttons(1); - return true; - case Key_Plus: - std_buttons(2); - return true; - case Key_Minus: - std_buttons(3); - return true; - case Key_Slash: - std_buttons(4); - return true; - case Key_Asterisk: - std_buttons(5); - return true; - case Key_Percent: - execOp( oPercent ); - return true; - case Key_ParenLeft: - if ( current_mode < pre_conv_modes_count ) - execOp( oOpenBrace ); - return true; - case Key_ParenRight: - if ( current_mode < pre_conv_modes_count ) - execOp( oCloseBrace ); - return true; - default: - break; - } - } + QKeyEvent *k = (QKeyEvent*)e; + if ( k->key() >= Key_0 && k->key() <= Key_9 ) { + enterNumber( k->key() - Key_0 ); + return true; + } else { + switch ( k->key() ) { + case Key_Equal: + std_buttons(0); + return true; + case Key_Period: + std_buttons(1); + return true; + case Key_Plus: + std_buttons(2); + return true; + case Key_Minus: + std_buttons(3); + return true; + case Key_Slash: + std_buttons(4); + return true; + case Key_Asterisk: + std_buttons(5); + return true; + case Key_Percent: + execOp( oPercent ); + return true; + case Key_ParenLeft: + if ( current_mode < pre_conv_modes_count ) + execOp( oOpenBrace ); + return true; + case Key_ParenRight: + if ( current_mode < pre_conv_modes_count ) + execOp( oCloseBrace ); + return true; + default: + break; + } + } } return Calculator::eventFilter( o, e ); } void CalculatorImpl::do_convert(int button) { if ( state == sError ) - return; + return; if ( current_mode >= pre_conv_modes_count && current_mode <= (max_mode - post_conv_modes_count) && - button < changeable_func_button_count ) { + button < changeable_func_button_count ) { if ( last_conversion > -1 ) { if( state == sNewNumber ){ - acc = (num+ preoffset_list[(current_mode - pre_conv_modes_count) * func_button_count + last_conversion]) + acc = (num+ preoffset_list[(current_mode - pre_conv_modes_count) * func_button_count + last_conversion]) / (entry_list[(current_mode - pre_conv_modes_count) * func_button_count + last_conversion]) - * (entry_list[(current_mode - pre_conv_modes_count) * func_button_count + button]) - +postoffset_list[(current_mode - pre_conv_modes_count) * func_button_count + button]; - num = acc; + * (entry_list[(current_mode - pre_conv_modes_count) * func_button_count + button]) + +postoffset_list[(current_mode - pre_conv_modes_count) * func_button_count + button]; + num = acc; LCD->display( acc ); } else { state = sNewNumber; num = (num+ preoffset_list[(current_mode - pre_conv_modes_count) * func_button_count + last_conversion]) / (entry_list[(current_mode - pre_conv_modes_count) * func_button_count + last_conversion]) - * (entry_list[(current_mode - pre_conv_modes_count) * func_button_count + button]) - + postoffset_list[(current_mode - pre_conv_modes_count) * func_button_count + button];; + * (entry_list[(current_mode - pre_conv_modes_count) * func_button_count + button]) + + postoffset_list[(current_mode - pre_conv_modes_count) * func_button_count + button];; LCD->display( num ); acc = num; } } last_conversion = button; } } void CalculatorImpl::function_button(int mode){ - if ( state == sError ) - clear(); + if ( state == sError ) + clear(); // dont need the next line when using a popup menu current_mode = mode; // reset the last conv last_conversion = -1; // set the caption this->setCaption( captions[current_mode] ); reset_conv(); for ( int x = 0 ; x < changeable_func_button_count ; x++ ) { QPushButton* tmpbutton = func_buttons[x]; // if its a conversion , make it a toggle button if ( current_mode >= pre_conv_modes_count && current_mode <= (max_mode - post_conv_modes_count) ) { tmpbutton->setToggleButton(TRUE); } else { tmpbutton->setToggleButton(FALSE); } tmpbutton->setText( faces[current_mode * func_button_count + x] ); } if ( current_mode == 0 ) display_pixmap_faces(); if ( current_mode >= pre_conv_modes_count && current_mode <= (max_mode - post_conv_modes_count) ) { bgr_function.setExclusive(TRUE); } else { bgr_function.setExclusive(FALSE); } } void CalculatorImpl::display_pixmap_faces() { QPushButton* tmpbutton = func_buttons[5]; tmpbutton->setPixmap(xtopowerofy); tmpbutton = func_buttons[6]; tmpbutton->setPixmap(ythrootofx); tmpbutton = func_buttons[3]; tmpbutton->setPixmap(oneoverx); } void CalculatorImpl::clear() { acc = num = 0; operationStack.clear(); state = sStart; numDecimals = 0; numOpenBraces = 0; flPoint = FALSE; LCD->display( 0 ); fake = QString::null; reset_conv(); } void CalculatorImpl::reset_conv() { for ( int x = 0 ; x < changeable_func_button_count ; x++ ) { QPushButton* tmpbutton = func_buttons[x]; // dont carry any selections into the next mode if ( tmpbutton->state() == QPushButton::On ) { tmpbutton->toggle(); } } last_conversion = -1; } void CalculatorImpl::std_buttons(int button) { if ( state == sError ) - return; + return; execOp( (Operation)(button + oSum) ); } void CalculatorImpl::std_funcs(int button) { if ( state == sError ) - return; + return; if ( current_mode < pre_conv_modes_count || - button > changeable_func_button_count-1 ) { - Operation op; - if ( button < 10 ) - op = (Operation)(button + oSin); - else if ( button == 10 ) - op = oOpenBrace; - else - op = oCloseBrace; + button > changeable_func_button_count-1 ) { + Operation op; + if ( button < 10 ) + op = (Operation)(button + oSin); + else if ( button == 10 ) + op = oOpenBrace; + else + op = oCloseBrace; execOp( op ); } } void CalculatorImpl::execOp( Operation i ) { switch (i) { - // these operators only affect the current number. - case oDivX: - case oLog: - case oLn: - case oSin: - case oCos: - case oTan: - num = evalExpr(i); - break; - - case oAdd: - case oSub: { - processStack( oAdd ); - Op op( num, i ); - operationStack.push( op ); - break; - } - case oDiv: - case oMult: - case oRoot: - case oXsquared: { - processStack( oDiv ); - Op op( num, i ); - operationStack.push( op ); - break; - } - case oChSign: - num = -num; - LCD->display(num); - return; - - case oOpenBrace: { - Op op( 0, oOpenBrace ); - operationStack.push( op ); - numOpenBraces++; - state = sNewNumber; - return; - } - case oCloseBrace: { - if ( numOpenBraces == 0 ) - return; - processStack( oAdd ); - if ( operationStack.top().operation != oOpenBrace ) - qDebug( "Calculator: internal Error" ); - operationStack.pop(); - state = sNewNumber; - numOpenBraces--; - break; - } - - case oPoint: - flPoint = TRUE; - return; - - case oPercent: - processStack( oPercent ); - break; - - - case oSum: - processStack( oSum ); - break; - - default: - return; + // these operators only affect the current number. + case oDivX: + case oLog: + case oLn: + case oSin: + case oCos: + case oTan: + num = evalExpr(i); + break; + + case oAdd: + case oSub: { + processStack( oAdd ); + Op op( num, i ); + operationStack.push( op ); + break; + } + case oDiv: + case oMult: + case oRoot: + case oXsquared: { + processStack( oDiv ); + Op op( num, i ); + operationStack.push( op ); + break; + } + case oChSign: + num = -num; + LCD->display(num); + return; + + case oOpenBrace: { + Op op( 0, oOpenBrace ); + operationStack.push( op ); + numOpenBraces++; + state = sNewNumber; + return; + } + case oCloseBrace: { + if ( numOpenBraces == 0 ) + return; + processStack( oAdd ); + if ( operationStack.top().operation != oOpenBrace ) + qDebug( "Calculator: internal Error" ); + operationStack.pop(); + state = sNewNumber; + numOpenBraces--; + break; + } + + case oPoint: + flPoint = TRUE; + return; + + case oPercent: + processStack( oPercent ); + break; + + + case oSum: + processStack( oSum ); + break; + + default: + return; }; - + if ( state == sError ) { - LCD->display( "Error" ); - return; + LCD->display( "Error" ); + return; } else { - LCD->display(num); + LCD->display(num); } state = sNewNumber; numDecimals = 0; flPoint = FALSE; } void CalculatorImpl::processStack( int op ) { //dubious percent hack, since the changeable operator precedences are //pretty much hardwired to be less than the non-changeable bool percent = FALSE; if ( op == oPercent ) { - percent = TRUE; - op = oSum; + percent = TRUE; + op = oSum; } while( !operationStack.isEmpty() && operationStack.top().operation >= op ) { - Op operation = operationStack.pop(); - acc = operation.number; - if ( percent ) { - if ( operation.operation == oAdd || operation.operation == oSub ) - num = acc*num/100; - else - num = num / 100; - } - num = evalExpr( operation.operation ); - percent = FALSE; + Op operation = operationStack.pop(); + acc = operation.number; + if ( percent ) { + if ( operation.operation == oAdd || operation.operation == oSub ) + num = acc*num/100; + else + num = num / 100; + } + num = evalExpr( operation.operation ); + percent = FALSE; } } double CalculatorImpl::evalExpr( int op ) { double sum = 0; switch( op ){ case oPercent: sum = num / 100.; break; - case oDivX: - if (num == 0) - state = sError; - else - sum = 1 / num; - break; + case oDivX: + if (num == 0) + state = sError; + else + sum = 1 / num; + break; case oXsquared: - sum = pow(acc,num); - break; + sum = pow(acc,num); + break; case oChSign: (state == sStart) ? sum = -num : sum = -acc; break; - case oSub: sum = acc - num; break; - case oMult: sum = acc * num; break; - case oAdd: sum = acc + num; break; + case oSub: sum = acc - num; break; + case oMult: sum = acc * num; break; + case oAdd: sum = acc + num; break; case oDiv: { - if (num == 0) { - state = sError; - } else { - sum = acc / num; - } - break; - } - case oRoot: - /* the linux library is dumb, and can't to -x to 1/n - when n is odd. (even and error of course is acceptable */ + if (num == 0) { + state = sError; + } else { + sum = acc / num; + } + break; + } + case oRoot: + /* the linux library is dumb, and can't to -x to 1/n + when n is odd. (even and error of course is acceptable */ if((acc < 0) && (int(num) == num) && (int(num) % 2 == 1 )) { - sum = pow(-acc, 1 / num); - sum = -sum; - } else { - sum = pow(acc, 1 / num); - } - break; + sum = pow(-acc, 1 / num); + sum = -sum; + } else { + sum = pow(acc, 1 / num); + } + break; case oLog: - sum = log10(num); - break; - case oLn: - sum = log(num); - break; + sum = log10(num); + break; + case oLn: + sum = log(num); + break; case oTan: sum = qTan(num);break; case oSin: sum = qSin(num);break; case oCos: sum = qCos(num);break; - default: sum = num; break; + default: sum = num; break; } - + if ( isinf( sum ) || isnan( sum ) ) - state = sError; + state = sError; return sum; } void CalculatorImpl::enterNumber( int n ) { if ( state == sError ) - return; + return; if( state == sStart ){ - if( LCD->value() > 0 ){ - QString s = QString::number( LCD->value(), 'g', LCD->numDigits()); - if( s.length() > (uint)(LCD->numDigits() - 2)) return; + if( LCD->value() > 0 ){ + QString s = QString::number( LCD->value(), 'g', LCD->numDigits()); + if( s.length() > (uint)(LCD->numDigits() - 2)) return; - } else if( (int)fake.length() >= LCD->numDigits() || numDecimals >=12 ){ - return; - } + } else if( (int)fake.length() >= LCD->numDigits() || numDecimals >=12 ){ + return; + } } if( state == sNewNumber ){ - state = sStart; - acc = 0; - if( flPoint ){ - numDecimals = 1; - num = n / pow(10, numDecimals); - } else - num = n; + state = sStart; + acc = 0; + if( flPoint ){ + numDecimals = 1; + num = n / pow(10, numDecimals); + } else + num = n; } else if( flPoint ){ - numDecimals++; - if( num < 0 ){ - num -= n / pow(10, numDecimals); - } else { - num += n / pow(10, numDecimals); - } + numDecimals++; + if( num < 0 ){ + num -= n / pow(10, numDecimals); + } else { + num += n / pow(10, numDecimals); + } } else { - num *= 10; - if( num < 0 ) - num -= n; - else - num += n; + num *= 10; + if( num < 0 ) + num -= n; + else + num += n; } // We need feedback in the calc display while entering fl.point zeros. // This is a small hack to display sequences like: 0.000 and 1.100 double integer, fraction; fraction = modf( num, &integer ); if( flPoint ){ - QString is, fs, zeros; - - is = QString::number( integer, 'g', 13 ); - fs = QString::number( fraction, 'g', numDecimals ); - if( fs.contains('e') ){ - fs = QString::number( fraction, 'f', LCD->numDigits() ); - } - fs = fs.mid( 2, numDecimals ); - - if( (integer == 0) && (fraction == 0) ) - fake = "0."; - else if( (integer != 0) && (fraction == 0) ) - fake = is + "."; - else - fake = is + "." + fs; - - zeros.fill( '0', (numDecimals - fs.length()) ); - fake += zeros; - // ### This code sets LCD->value() to zero since it sets a text - // ### Avoid getting the current value from LCD->value() for - // ### calculations. - LCD->display( fake ); + QString is, fs, zeros; + + is = QString::number( integer, 'g', 13 ); + fs = QString::number( fraction, 'g', numDecimals ); + if( fs.contains('e') ){ + fs = QString::number( fraction, 'f', LCD->numDigits() ); + } + fs = fs.mid( 2, numDecimals ); + + if( (integer == 0) && (fraction == 0) ) + fake = "0."; + else if( (integer != 0) && (fraction == 0) ) + fake = is + "."; + else + fake = is + "." + fs; + + zeros.fill( '0', (numDecimals - fs.length()) ); + fake += zeros; + // ### This code sets LCD->value() to zero since it sets a text + // ### Avoid getting the current value from LCD->value() for + // ### calculations. + LCD->display( fake ); } else - LCD->display( num ); + LCD->display( num ); } void CalculatorImpl::command_buttons(int i) { if ( state == sError && i != 3 ) - return; + return; switch (i) { case 0: // M+ - mem += num; + mem += num; if( mem != 0 ){ - memMark->show(); - PushButtonMR->setEnabled( TRUE ); }; - state = sNewNumber; + memMark->show(); + PushButtonMR->setEnabled( TRUE ); }; + state = sNewNumber; break; case 1: // MR - acc = num = mem; - state = sNewNumber; + acc = num = mem; + state = sNewNumber; LCD->display( mem ); break; case 2: // MC mem = 0; memMark->hide(); PushButtonMR->setEnabled( FALSE ); break; case 3: // CE - if ( state == sStart ) { - // clear the entered number on the first press - state = sNewNumber; - num = acc = 0; - flPoint = FALSE; - LCD->display( 0 ); - fake = QString::null; - numDecimals = 0; - } else { - clear(); - } + if ( state == sStart ) { + // clear the entered number on the first press + state = sNewNumber; + num = acc = 0; + flPoint = FALSE; + LCD->display( 0 ); + fake = QString::null; + numDecimals = 0; + } else { + clear(); + } break; }; } |