summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/tools/calculator/calculatorimpl.cpp9
1 files changed, 2 insertions, 7 deletions
diff --git a/noncore/tools/calculator/calculatorimpl.cpp b/noncore/tools/calculator/calculatorimpl.cpp
index 05cb9b5..21c1e2e 100644
--- a/noncore/tools/calculator/calculatorimpl.cpp
+++ b/noncore/tools/calculator/calculatorimpl.cpp
@@ -1,735 +1,730 @@
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// Sat 03-09-2002 L.J. Potter added the inlined pixmaps here
26 26
27#include "calculatorimpl.h" 27#include "calculatorimpl.h"
28 28
29/* OPIE */ 29/* OPIE */
30#include <opie2/odebug.h> 30#include <opie2/odebug.h>
31#include <qpe/resource.h>
32#include <qpe/qmath.h> 31#include <qpe/qmath.h>
33#include <qpe/qpeapplication.h> 32#include <qpe/qpeapplication.h>
34using namespace Opie::Core; 33using namespace Opie::Core;
35 34
36/* QT */ 35/* QT */
37#include <qpushbutton.h> 36#include <qpushbutton.h>
38#include <qcombobox.h> 37#include <qcombobox.h>
39#include <qlabel.h> 38#include <qlabel.h>
40#include <qfont.h> 39#include <qfont.h>
41#include <qlayout.h> 40#include <qlayout.h>
42#include <qstringlist.h> 41#include <qstringlist.h>
43#include <qfile.h> 42#include <qfile.h>
44#include <qtextstream.h> 43#include <qtextstream.h>
45#include <qmessagebox.h> 44#include <qmessagebox.h>
46 45
47/* STD */ 46/* STD */
48#include <math.h> 47#include <math.h>
49 48
50/* XPM */ 49/* XPM */
51static char *oneoverx_xpm[] = { 50static char *oneoverx_xpm[] = {
52/* width height num_colors chars_per_pixel */ 51/* width height num_colors chars_per_pixel */
53" 13 11 2 1", 52" 13 11 2 1",
54/* colors */ 53/* colors */
55". c None", 54". c None",
56"# c #000000", 55"# c #000000",
57/* pixels */ 56/* pixels */
58"......#......", 57"......#......",
59".....##......", 58".....##......",
60"......#......" 59"......#......"
61".....###.....", 60".....###.....",
62".............", 61".............",
63"..#########..", 62"..#########..",
64".............", 63".............",
65"....##.##....", 64"....##.##....",
66"......#......", 65"......#......",
67"......#......", 66"......#......",
68"....##.##....", 67"....##.##....",
69}; 68};
70/* XPM */ 69/* XPM */
71static char *ythrootofx_xpm[] = { 70static char *ythrootofx_xpm[] = {
72/* width height num_colors chars_per_pixel */ 71/* width height num_colors chars_per_pixel */
73" 13 11 2 1", 72" 13 11 2 1",
74/* colors */ 73/* colors */
75". c None", 74". c None",
76"# c #000000", 75"# c #000000",
77/* pixels */ 76/* pixels */
78"#.#..........", 77"#.#..........",
79"#.#..........", 78"#.#..........",
80"###...#######", 79"###...#######",
81"..#..#.......", 80"..#..#.......",
82"###..#.......", 81"###..#.......",
83".....#.#...#.", 82".....#.#...#.",
84".#..#...#.#..", 83".#..#...#.#..",
85"#.#.#....#...", 84"#.#.#....#...",
86"..#.#...#.#..", 85"..#.#...#.#..",
87"...#...#...#.", 86"...#...#...#.",
88"...#........." 87"...#........."
89}; 88};
90/* XPM */ 89/* XPM */
91static char *xtopowerofy_xpm[] = { 90static char *xtopowerofy_xpm[] = {
92/* width height num_colors chars_per_pixel */ 91/* width height num_colors chars_per_pixel */
93" 9 8 2 1", 92" 9 8 2 1",
94/* colors */ 93/* colors */
95". c None", 94". c None",
96"# c #000000", 95"# c #000000",
97/* pixels */ 96/* pixels */
98"......#.#", 97"......#.#",
99"......#.#", 98"......#.#",
100"......###", 99"......###",
101"#...#...#", 100"#...#...#",
102".#.#..###", 101".#.#..###",
103"..#......", 102"..#......",
104".#.#.....", 103".#.#.....",
105"#...#...." 104"#...#...."
106}; 105};
107 106
108CalculatorImpl::CalculatorImpl( QWidget * parent, const char * name, 107CalculatorImpl::CalculatorImpl( QWidget * parent, const char * name,
109 WFlags f ) 108 WFlags f )
110 : Calculator( parent, name, f ) 109 : Calculator( parent, name, f )
111{ 110{
112// xtopowerofy = Resource::loadPixmap("xtopowerofy");
113// ythrootofx = Resource::loadPixmap("ythrootofx");
114// oneoverx = Resource::loadPixmap("oneoverx");
115
116 memMark = new QLabel( "m", LCD ); 111 memMark = new QLabel( "m", LCD );
117 memMark->setFont( QFont( "helvetica", 12, QFont::Bold, TRUE ) ); 112 memMark->setFont( QFont( "helvetica", 12, QFont::Bold, TRUE ) );
118 memMark->resize( 12, 12 ); 113 memMark->resize( 12, 12 );
119 memMark->move( 4, 2 ); 114 memMark->move( 4, 2 );
120 memMark->hide(); 115 memMark->hide();
121 mem = 0; 116 mem = 0;
122 117
123 PushButtonMR->setEnabled( FALSE ); 118 PushButtonMR->setEnabled( FALSE );
124 119
125 current_mode = max_mode = conversion_mode_count = 0; 120 current_mode = max_mode = conversion_mode_count = 0;
126 last_conversion = -1; 121 last_conversion = -1;
127 122
128 // translation trick mode - with this stuff parsed in from a file is translatable 123 // translation trick mode - with this stuff parsed in from a file is translatable
129 QObject::tr("Standard"); 124 QObject::tr("Standard");
130 QObject::tr("Weight"); 125 QObject::tr("Weight");
131 QObject::tr("Distance"); 126 QObject::tr("Distance");
132 QObject::tr("Area"); 127 QObject::tr("Area");
133 QObject::tr("Temperatures"); 128 QObject::tr("Temperatures");
134 QObject::tr("Volume"); 129 QObject::tr("Volume");
135 QObject::tr("acres"); 130 QObject::tr("acres");
136 QObject::tr("°C"); 131 QObject::tr("C");
137 QObject::tr("carats"); 132 QObject::tr("carats");
138 QObject::tr("cm"); 133 QObject::tr("cm");
139 QObject::tr("cu cm"); 134 QObject::tr("cu cm");
140 QObject::tr("cu ft"); 135 QObject::tr("cu ft");
141 QObject::tr("cu in"); 136 QObject::tr("cu in");
142 QObject::tr("°F"); 137 QObject::tr("F");
143 QObject::tr("fl oz (US)"); 138 QObject::tr("fl oz (US)");
144 QObject::tr("ft"); 139 QObject::tr("ft");
145 QObject::tr("g"); 140 QObject::tr("g");
146 QObject::tr("gal (US)"); 141 QObject::tr("gal (US)");
147 QObject::tr("hectares"); 142 QObject::tr("hectares");
148 QObject::tr("in"); 143 QObject::tr("in");
149 QObject::tr("kg"); 144 QObject::tr("kg");
150 QObject::tr("km"); 145 QObject::tr("km");
151 QObject::tr("l"); 146 QObject::tr("l");
152 QObject::tr("lb"); 147 QObject::tr("lb");
153 QObject::tr("Lg tons"); 148 QObject::tr("Lg tons");
154 QObject::tr("m"); 149 QObject::tr("m");
155 QObject::tr("mg"); 150 QObject::tr("mg");
156 QObject::tr("mi"); 151 QObject::tr("mi");
157 QObject::tr("ml"); 152 QObject::tr("ml");
158 QObject::tr("mm"); 153 QObject::tr("mm");
159 QObject::tr("naut. mi"); 154 QObject::tr("naut. mi");
160 QObject::tr("oz"); 155 QObject::tr("oz");
161 QObject::tr("points"); 156 QObject::tr("points");
162 QObject::tr("pt"); 157 QObject::tr("pt");
163 QObject::tr("qt"); 158 QObject::tr("qt");
164 QObject::tr("sq cm"); 159 QObject::tr("sq cm");
165 QObject::tr("sq ft"); 160 QObject::tr("sq ft");
166 QObject::tr("sq in"); 161 QObject::tr("sq in");
167 QObject::tr("sq km"); 162 QObject::tr("sq km");
168 QObject::tr("sq m"); 163 QObject::tr("sq m");
169 QObject::tr("sq mi"); 164 QObject::tr("sq mi");
170 QObject::tr("sq mm"); 165 QObject::tr("sq mm");
171 QObject::tr("sq yd"); 166 QObject::tr("sq yd");
172 QObject::tr("st"); 167 QObject::tr("st");
173 QObject::tr("St tons"); 168 QObject::tr("St tons");
174 QObject::tr("tblspoon"); 169 QObject::tr("tblspoon");
175 QObject::tr("teaspoons"); 170 QObject::tr("teaspoons");
176 QObject::tr("tonnes"); 171 QObject::tr("tonnes");
177 QObject::tr("yd"); 172 QObject::tr("yd");
178 173
179 174
180//bgr_command.insert( PushButtonFunction); 175//bgr_command.insert( PushButtonFunction);
181 bgr_command.insert( PushButtonMPlus); 176 bgr_command.insert( PushButtonMPlus);
182 bgr_command.insert( PushButtonMR); 177 bgr_command.insert( PushButtonMR);
183 bgr_command.insert( PushButtonMC); 178 bgr_command.insert( PushButtonMC);
184 bgr_command.insert( PushButtonCE); 179 bgr_command.insert( PushButtonCE);
185 connect( &bgr_command, SIGNAL(clicked(int) ), this, SLOT(command_buttons(int))); 180 connect( &bgr_command, SIGNAL(clicked(int) ), this, SLOT(command_buttons(int)));
186 181
187 bgr_digits.insert(PushButton0); 182 bgr_digits.insert(PushButton0);
188 bgr_digits.insert(PushButton1); 183 bgr_digits.insert(PushButton1);
189 bgr_digits.insert(PushButton2); 184 bgr_digits.insert(PushButton2);
190 bgr_digits.insert(PushButton3); 185 bgr_digits.insert(PushButton3);
191 bgr_digits.insert(PushButton4); 186 bgr_digits.insert(PushButton4);
192 bgr_digits.insert(PushButton5); 187 bgr_digits.insert(PushButton5);
193 bgr_digits.insert(PushButton6); 188 bgr_digits.insert(PushButton6);
194 bgr_digits.insert(PushButton7); 189 bgr_digits.insert(PushButton7);
195 bgr_digits.insert(PushButton8); 190 bgr_digits.insert(PushButton8);
196 bgr_digits.insert(PushButton9); 191 bgr_digits.insert(PushButton9);
197 connect( &bgr_digits, SIGNAL(clicked(int) ), this, SLOT(enterNumber(int))); 192 connect( &bgr_digits, SIGNAL(clicked(int) ), this, SLOT(enterNumber(int)));
198 193
199 194
200 bgr_std.insert(PushButtonEquals); 195 bgr_std.insert(PushButtonEquals);
201 bgr_std.insert(PushButtonDecimal); 196 bgr_std.insert(PushButtonDecimal);
202 bgr_std.insert(PushButtonAdd); 197 bgr_std.insert(PushButtonAdd);
203 bgr_std.insert(PushButtonMinus); 198 bgr_std.insert(PushButtonMinus);
204 bgr_std.insert(PushButtonDivide); 199 bgr_std.insert(PushButtonDivide);
205 bgr_std.insert(PushButtonTimes); 200 bgr_std.insert(PushButtonTimes);
206 connect( &bgr_std, SIGNAL(clicked(int) ), this, SLOT(std_buttons(int))); 201 connect( &bgr_std, SIGNAL(clicked(int) ), this, SLOT(std_buttons(int)));
207 202
208// change the / to a proper division signal 203// change the / to a proper division signal
209 PushButtonDivide->setText(QChar(0xF7)); 204 PushButtonDivide->setText(QChar(0xF7));
210 205
211 func_buttons[0] = PushButtonF1; 206 func_buttons[0] = PushButtonF1;
212 func_buttons[1] = PushButtonF2; 207 func_buttons[1] = PushButtonF2;
213 func_buttons[2] = PushButtonF3; 208 func_buttons[2] = PushButtonF3;
214 func_buttons[3] = PushButtonF4; 209 func_buttons[3] = PushButtonF4;
215 func_buttons[4] = PushButtonF5; 210 func_buttons[4] = PushButtonF5;
216 func_buttons[5] = PushButtonF6; 211 func_buttons[5] = PushButtonF6;
217 func_buttons[6] = PushButtonF7; 212 func_buttons[6] = PushButtonF7;
218 func_buttons[7] = PushButtonF8; 213 func_buttons[7] = PushButtonF8;
219 func_buttons[8] = PushButtonF9; 214 func_buttons[8] = PushButtonF9;
220 func_buttons[9] = PushButtonF10; 215 func_buttons[9] = PushButtonF10;
221 func_buttons[10] = PushButtonF11; 216 func_buttons[10] = PushButtonF11;
222 func_buttons[11] = PushButtonF12; 217 func_buttons[11] = PushButtonF12;
223 218
224 for ( int x = 0 ; x < func_button_count ; x++ ) { 219 for ( int x = 0 ; x < func_button_count ; x++ ) {
225 QPushButton* tmpbutton = func_buttons[x]; 220 QPushButton* tmpbutton = func_buttons[x];
226 faces << tmpbutton->text(); 221 faces << tmpbutton->text();
227 bgr_function.insert(tmpbutton); 222 bgr_function.insert(tmpbutton);
228 } 223 }
229 connect( &bgr_function, SIGNAL(clicked(int) ) , this, SLOT(do_convert(int) ) ); 224 connect( &bgr_function, SIGNAL(clicked(int) ) , this, SLOT(do_convert(int) ) );
230 connect( &bgr_function, SIGNAL(clicked(int) ) , this, SLOT(std_funcs(int) ) ); 225 connect( &bgr_function, SIGNAL(clicked(int) ) , this, SLOT(std_funcs(int) ) );
231 226
232 connect(ComboBoxFunction, SIGNAL(activated(int) ), this, SLOT(function_button(int) ) ); 227 connect(ComboBoxFunction, SIGNAL(activated(int) ), this, SLOT(function_button(int) ) );
233 228
234 captions.append(tr("Standard")); 229 captions.append(tr("Standard"));
235 ComboBoxFunction->insertItem(captions.last()); 230 ComboBoxFunction->insertItem(captions.last());
236 231
237 // now add in the conversion modes 232 // now add in the conversion modes
238 // when the menu gets done, these should be in a submenu 233 // when the menu gets done, these should be in a submenu
239 QString tmp = QPEApplication::qpeDir(); 234 QString tmp = QPEApplication::qpeDir();
240 tmp += "etc/unit_conversion.dat"; 235 tmp += "etc/unit_conversion.dat";
241 QFile myfile(tmp); 236 QFile myfile(tmp);
242 if ( !myfile.open( IO_Translate | IO_ReadOnly ) ) { 237 if ( !myfile.open( IO_Translate | IO_ReadOnly ) ) {
243 odebug << "Data file unit_conversion.dat not found\nNo conversion features will be available\n"+tmp << oendl; 238 odebug << "Data file unit_conversion.dat not found\nNo conversion features will be available\n"+tmp << oendl;
244 // disable the f button if no conv file available 239 // disable the f button if no conv file available
245 ComboBoxFunction->setEnabled(FALSE); 240 ComboBoxFunction->setEnabled(FALSE);
246 } 241 }
247 else { 242 else {
248 QString line, line2; 243 QString line, line2;
249 QTextStream ts(&myfile); 244 QTextStream ts(&myfile);
250 245
251 // first pass, see how many conversion types there are in order to allocate for them 246 // first pass, see how many conversion types there are in order to allocate for them
252 while ( ! ts.eof() ) { 247 while ( ! ts.eof() ) {
253 line = ts.readLine(); 248 line = ts.readLine();
254 if ( line.contains ("STARTTYPE" ) ) 249 if ( line.contains ("STARTTYPE" ) )
255 conversion_mode_count++; 250 conversion_mode_count++;
256 } 251 }
257 252
258 entry_list = new double[conversion_mode_count*func_button_count]; 253 entry_list = new double[conversion_mode_count*func_button_count];
259 preoffset_list = new double[conversion_mode_count*func_button_count]; 254 preoffset_list = new double[conversion_mode_count*func_button_count];
260 postoffset_list = new double[conversion_mode_count*func_button_count]; 255 postoffset_list = new double[conversion_mode_count*func_button_count];
261 myfile.close(); 256 myfile.close();
262 myfile.open( IO_Translate | IO_ReadOnly ); 257 myfile.open( IO_Translate | IO_ReadOnly );
263 QTextStream ts2(&myfile); 258 QTextStream ts2(&myfile);
264 259
265 // second pass, read in values 260 // second pass, read in values
266 int x = 0; 261 int x = 0;
267 while ( ! ts2.eof() ) { 262 while ( ! ts2.eof() ) {
268 line = ts2.readLine(); 263 line = ts2.readLine();
269 if ( line.contains("STARTTYPE") ) { 264 if ( line.contains("STARTTYPE") ) {
270 captions << tr( line.remove(0,10) ); 265 captions << tr( line.remove(0,10) );
271 ComboBoxFunction->insertItem(captions.last()); 266 ComboBoxFunction->insertItem(captions.last());
272 while ( !line.contains("ENDTYPE") ) { 267 while ( !line.contains("ENDTYPE") ) {
273 line = ts2.readLine(); 268 line = ts2.readLine();
274 if ( line.contains("NAME") ) { 269 if ( line.contains("NAME") ) {
275 faces << tr( line.remove(0,5) ); 270 faces << tr( line.remove(0,5) );
276 line2 = ts2.readLine(); 271 line2 = ts2.readLine();
277 line2.remove(0,6); 272 line2.remove(0,6);
278 entry_list[x] = line2.toDouble(); 273 entry_list[x] = line2.toDouble();
279 line2 = ts2.readLine(); 274 line2 = ts2.readLine();
280 line2.remove(0,7); 275 line2.remove(0,7);
281 preoffset_list[x] = line2.toDouble(); 276 preoffset_list[x] = line2.toDouble();
282 line2 = ts2.readLine(); 277 line2 = ts2.readLine();
283 line2.remove(0,8); 278 line2.remove(0,8);
284 postoffset_list[x] = line2.toDouble(); 279 postoffset_list[x] = line2.toDouble();
285 x++; 280 x++;
286 } 281 }
287 } 282 }
288 } 283 }
289 } 284 }
290 } 285 }
291 myfile.close(); 286 myfile.close();
292 clear(); 287 clear();
293 max_mode = pre_conv_modes_count + conversion_mode_count + post_conv_modes_count - 1; 288 max_mode = pre_conv_modes_count + conversion_mode_count + post_conv_modes_count - 1;
294 display_pixmap_faces(); 289 display_pixmap_faces();
295 290
296 qApp->installEventFilter( this ); 291 qApp->installEventFilter( this );
297} 292}
298 293
299bool CalculatorImpl::eventFilter( QObject *o, QEvent *e ) 294bool CalculatorImpl::eventFilter( QObject *o, QEvent *e )
300{ 295{
301 if ( e->type() == QEvent::KeyPress && state != sError ) { 296 if ( e->type() == QEvent::KeyPress && state != sError ) {
302 QKeyEvent *k = (QKeyEvent*)e; 297 QKeyEvent *k = (QKeyEvent*)e;
303 if ( k->key() >= Key_0 && k->key() <= Key_9 ) { 298 if ( k->key() >= Key_0 && k->key() <= Key_9 ) {
304 enterNumber( k->key() - Key_0 ); 299 enterNumber( k->key() - Key_0 );
305 return true; 300 return true;
306 } else { 301 } else {
307 switch ( k->key() ) { 302 switch ( k->key() ) {
308 case Key_Equal: 303 case Key_Equal:
309 std_buttons(0); 304 std_buttons(0);
310 return true; 305 return true;
311 case Key_Period: 306 case Key_Period:
312 std_buttons(1); 307 std_buttons(1);
313 return true; 308 return true;
314 case Key_Plus: 309 case Key_Plus:
315 std_buttons(2); 310 std_buttons(2);
316 return true; 311 return true;
317 case Key_Minus: 312 case Key_Minus:
318 std_buttons(3); 313 std_buttons(3);
319 return true; 314 return true;
320 case Key_Slash: 315 case Key_Slash:
321 std_buttons(4); 316 std_buttons(4);
322 return true; 317 return true;
323 case Key_Asterisk: 318 case Key_Asterisk:
324 std_buttons(5); 319 std_buttons(5);
325 return true; 320 return true;
326 case Key_Percent: 321 case Key_Percent:
327 execOp( oPercent ); 322 execOp( oPercent );
328 return true; 323 return true;
329 case Key_ParenLeft: 324 case Key_ParenLeft:
330 if ( current_mode < pre_conv_modes_count ) 325 if ( current_mode < pre_conv_modes_count )
331 execOp( oOpenBrace ); 326 execOp( oOpenBrace );
332 return true; 327 return true;
333 case Key_ParenRight: 328 case Key_ParenRight:
334 if ( current_mode < pre_conv_modes_count ) 329 if ( current_mode < pre_conv_modes_count )
335 execOp( oCloseBrace ); 330 execOp( oCloseBrace );
336 return true; 331 return true;
337 default: 332 default:
338 break; 333 break;
339 } 334 }
340 } 335 }
341 } 336 }
342 return Calculator::eventFilter( o, e ); 337 return Calculator::eventFilter( o, e );
343} 338}
344 339
345void CalculatorImpl::do_convert(int button) { 340void CalculatorImpl::do_convert(int button) {
346 if ( state == sError ) 341 if ( state == sError )
347 return; 342 return;
348 if ( current_mode >= pre_conv_modes_count && current_mode <= (max_mode - post_conv_modes_count) && 343 if ( current_mode >= pre_conv_modes_count && current_mode <= (max_mode - post_conv_modes_count) &&
349 button < changeable_func_button_count ) { 344 button < changeable_func_button_count ) {
350 if ( last_conversion > -1 ) { 345 if ( last_conversion > -1 ) {
351 if( state == sNewNumber ){ 346 if( state == sNewNumber ){
352 acc = (num+ preoffset_list[(current_mode - pre_conv_modes_count) * func_button_count + last_conversion]) 347 acc = (num+ preoffset_list[(current_mode - pre_conv_modes_count) * func_button_count + last_conversion])
353 / (entry_list[(current_mode - pre_conv_modes_count) * func_button_count + last_conversion]) 348 / (entry_list[(current_mode - pre_conv_modes_count) * func_button_count + last_conversion])
354 * (entry_list[(current_mode - pre_conv_modes_count) * func_button_count + button]) 349 * (entry_list[(current_mode - pre_conv_modes_count) * func_button_count + button])
355 +postoffset_list[(current_mode - pre_conv_modes_count) * func_button_count + button]; 350 +postoffset_list[(current_mode - pre_conv_modes_count) * func_button_count + button];
356 num = acc; 351 num = acc;
357 LCD->display( acc ); 352 LCD->display( acc );
358 } else { 353 } else {
359 state = sNewNumber; 354 state = sNewNumber;
360 num = (num+ preoffset_list[(current_mode - pre_conv_modes_count) * func_button_count + last_conversion]) 355 num = (num+ preoffset_list[(current_mode - pre_conv_modes_count) * func_button_count + last_conversion])
361 / (entry_list[(current_mode - pre_conv_modes_count) * func_button_count + last_conversion]) 356 / (entry_list[(current_mode - pre_conv_modes_count) * func_button_count + last_conversion])
362 * (entry_list[(current_mode - pre_conv_modes_count) * func_button_count + button]) 357 * (entry_list[(current_mode - pre_conv_modes_count) * func_button_count + button])
363 + postoffset_list[(current_mode - pre_conv_modes_count) * func_button_count + button];; 358 + postoffset_list[(current_mode - pre_conv_modes_count) * func_button_count + button];;
364 LCD->display( num ); 359 LCD->display( num );
365 acc = num; 360 acc = num;
366 } 361 }
367 } 362 }
368 last_conversion = button; 363 last_conversion = button;
369 } 364 }
370} 365}
371 366
372 367
373void CalculatorImpl::function_button(int mode){ 368void CalculatorImpl::function_button(int mode){
374 if ( state == sError ) 369 if ( state == sError )
375 clear(); 370 clear();
376 // dont need the next line when using a popup menu 371 // dont need the next line when using a popup menu
377 current_mode = mode; 372 current_mode = mode;
378 373
379 // reset the last conv 374 // reset the last conv
380 last_conversion = -1; 375 last_conversion = -1;
381 376
382 // set the caption 377 // set the caption
383 this->setCaption( captions[current_mode] ); 378 this->setCaption( captions[current_mode] );
384 379
385 reset_conv(); 380 reset_conv();
386 381
387 for ( int x = 0 ; x < changeable_func_button_count ; x++ ) { 382 for ( int x = 0 ; x < changeable_func_button_count ; x++ ) {
388 QPushButton* tmpbutton = func_buttons[x]; 383 QPushButton* tmpbutton = func_buttons[x];
389 384
390 // if its a conversion , make it a toggle button 385 // if its a conversion , make it a toggle button
391 if ( current_mode >= pre_conv_modes_count && current_mode <= (max_mode - post_conv_modes_count) ) { 386 if ( current_mode >= pre_conv_modes_count && current_mode <= (max_mode - post_conv_modes_count) ) {
392 tmpbutton->setToggleButton(TRUE); 387 tmpbutton->setToggleButton(TRUE);
393 } else { 388 } else {
394 tmpbutton->setToggleButton(FALSE); 389 tmpbutton->setToggleButton(FALSE);
395 } 390 }
396 tmpbutton->setText( faces[current_mode * func_button_count + x] ); 391 tmpbutton->setText( faces[current_mode * func_button_count + x] );
397 } 392 }
398 393
399 if ( current_mode == 0 ) display_pixmap_faces(); 394 if ( current_mode == 0 ) display_pixmap_faces();
400 395
401 if ( current_mode >= pre_conv_modes_count && current_mode <= (max_mode - post_conv_modes_count) ) { 396 if ( current_mode >= pre_conv_modes_count && current_mode <= (max_mode - post_conv_modes_count) ) {
402 bgr_function.setExclusive(TRUE); 397 bgr_function.setExclusive(TRUE);
403 } else { 398 } else {
404 bgr_function.setExclusive(FALSE); 399 bgr_function.setExclusive(FALSE);
405 } 400 }
406} 401}
407 402
408void CalculatorImpl::display_pixmap_faces() { 403void CalculatorImpl::display_pixmap_faces() {
409 QPixmap image0( ( const char** ) xtopowerofy_xpm); 404 QPixmap image0( ( const char** ) xtopowerofy_xpm);
410 QPushButton* tmpbutton = func_buttons[5]; 405 QPushButton* tmpbutton = func_buttons[5];
411 tmpbutton->setPixmap(image0); 406 tmpbutton->setPixmap(image0);
412 407
413 QPixmap image1( ( const char** ) ythrootofx_xpm); 408 QPixmap image1( ( const char** ) ythrootofx_xpm);
414 tmpbutton = func_buttons[6]; 409 tmpbutton = func_buttons[6];
415 tmpbutton->setPixmap(image1); 410 tmpbutton->setPixmap(image1);
416 411
417 QPixmap image2( ( const char** ) oneoverx_xpm); 412 QPixmap image2( ( const char** ) oneoverx_xpm);
418 tmpbutton = func_buttons[3]; 413 tmpbutton = func_buttons[3];
419 tmpbutton->setPixmap(image2); 414 tmpbutton->setPixmap(image2);
420} 415}
421 416
422void CalculatorImpl::clear() { 417void CalculatorImpl::clear() {
423 acc = num = 0; 418 acc = num = 0;
424 operationStack.clear(); 419 operationStack.clear();
425 state = sStart; 420 state = sStart;
426 numDecimals = 0; 421 numDecimals = 0;
427 numOpenBraces = 0; 422 numOpenBraces = 0;
428 flPoint = FALSE; 423 flPoint = FALSE;
429 LCD->display( 0 ); 424 LCD->display( 0 );
430 fake = QString::null; 425 fake = QString::null;
431 426
432 reset_conv(); 427 reset_conv();
433} 428}
434 429
435void CalculatorImpl::reset_conv() { 430void CalculatorImpl::reset_conv() {
436 for ( int x = 0 ; x < changeable_func_button_count ; x++ ) { 431 for ( int x = 0 ; x < changeable_func_button_count ; x++ ) {
437 QPushButton* tmpbutton = func_buttons[x]; 432 QPushButton* tmpbutton = func_buttons[x];
438 433
439 // dont carry any selections into the next mode 434 // dont carry any selections into the next mode
440 if ( tmpbutton->state() == QPushButton::On ) { 435 if ( tmpbutton->state() == QPushButton::On ) {
441 tmpbutton->toggle(); 436 tmpbutton->toggle();
442 } 437 }
443 } 438 }
444 439
445 last_conversion = -1; 440 last_conversion = -1;
446} 441}
447 442
448void CalculatorImpl::std_buttons(int button) 443void CalculatorImpl::std_buttons(int button)
449{ 444{
450 if ( state == sError ) 445 if ( state == sError )
451 return; 446 return;
452 execOp( (Operation)(button + oSum) ); 447 execOp( (Operation)(button + oSum) );
453} 448}
454 449
455void CalculatorImpl::std_funcs(int button) { 450void CalculatorImpl::std_funcs(int button) {
456 if ( state == sError ) 451 if ( state == sError )
457 return; 452 return;
458 if ( current_mode < pre_conv_modes_count || 453 if ( current_mode < pre_conv_modes_count ||
459 button > changeable_func_button_count-1 ) { 454 button > changeable_func_button_count-1 ) {
460 Operation op; 455 Operation op;
461 if ( button < 10 ) 456 if ( button < 10 )
462 op = (Operation)(button + oSin); 457 op = (Operation)(button + oSin);
463 else if ( button == 10 ) 458 else if ( button == 10 )
464 op = oOpenBrace; 459 op = oOpenBrace;
465 else 460 else
466 op = oCloseBrace; 461 op = oCloseBrace;
467 execOp( op ); 462 execOp( op );
468 } 463 }
469} 464}
470 465
471void CalculatorImpl::execOp( Operation i ) 466void CalculatorImpl::execOp( Operation i )
472{ 467{
473 switch (i) { 468 switch (i) {
474 // these operators only affect the current number. 469 // these operators only affect the current number.
475 case oDivX: 470 case oDivX:
476 case oLog: 471 case oLog:
477 case oLn: 472 case oLn:
478 case oSin: 473 case oSin:
479 case oCos: 474 case oCos:
480 case oTan: 475 case oTan:
481 num = evalExpr(i); 476 num = evalExpr(i);
482 break; 477 break;
483 478
484 case oAdd: 479 case oAdd:
485 case oSub: { 480 case oSub: {
486 processStack( oAdd ); 481 processStack( oAdd );
487 Op op( num, i ); 482 Op op( num, i );
488 operationStack.push( op ); 483 operationStack.push( op );
489 break; 484 break;
490 } 485 }
491 case oDiv: 486 case oDiv:
492 case oMult: 487 case oMult:
493 case oRoot: 488 case oRoot:
494 case oXsquared: { 489 case oXsquared: {
495 processStack( oDiv ); 490 processStack( oDiv );
496 Op op( num, i ); 491 Op op( num, i );
497 operationStack.push( op ); 492 operationStack.push( op );
498 break; 493 break;
499 } 494 }
500 case oChSign: 495 case oChSign:
501 num = -num; 496 num = -num;
502 LCD->display(num); 497 LCD->display(num);
503 return; 498 return;
504 499
505 case oOpenBrace: { 500 case oOpenBrace: {
506 Op op( 0, oOpenBrace ); 501 Op op( 0, oOpenBrace );
507 operationStack.push( op ); 502 operationStack.push( op );
508 numOpenBraces++; 503 numOpenBraces++;
509 state = sNewNumber; 504 state = sNewNumber;
510 return; 505 return;
511 } 506 }
512 case oCloseBrace: { 507 case oCloseBrace: {
513 if ( numOpenBraces == 0 ) 508 if ( numOpenBraces == 0 )
514 return; 509 return;
515 processStack( oAdd ); 510 processStack( oAdd );
516 if ( operationStack.top().operation != oOpenBrace ) 511 if ( operationStack.top().operation != oOpenBrace )
517 odebug << "Calculator: internal Error" << oendl; 512 odebug << "Calculator: internal Error" << oendl;
518 operationStack.pop(); 513 operationStack.pop();
519 state = sNewNumber; 514 state = sNewNumber;
520 numOpenBraces--; 515 numOpenBraces--;
521 break; 516 break;
522 } 517 }
523 518
524 case oPoint: 519 case oPoint:
525 flPoint = TRUE; 520 flPoint = TRUE;
526 return; 521 return;
527 522
528 case oPercent: 523 case oPercent:
529 processStack( oPercent ); 524 processStack( oPercent );
530 break; 525 break;
531 526
532 527
533 case oSum: 528 case oSum:
534 processStack( oSum ); 529 processStack( oSum );
535 break; 530 break;
536 531
537 default: 532 default:
538 return; 533 return;
539 }; 534 };
540 535
541 if ( state == sError ) { 536 if ( state == sError ) {
542 LCD->display( "Error" ); 537 LCD->display( "Error" );
543 return; 538 return;
544 } else { 539 } else {
545 LCD->display(num); 540 LCD->display(num);
546 } 541 }
547 state = sNewNumber; 542 state = sNewNumber;
548 numDecimals = 0; 543 numDecimals = 0;
549 flPoint = FALSE; 544 flPoint = FALSE;
550} 545}
551 546
552 547
553void CalculatorImpl::processStack( int op ) 548void CalculatorImpl::processStack( int op )
554{ 549{
555 //dubious percent hack, since the changeable operator precedences are 550 //dubious percent hack, since the changeable operator precedences are
556 //pretty much hardwired to be less than the non-changeable 551 //pretty much hardwired to be less than the non-changeable
557 bool percent = FALSE; 552 bool percent = FALSE;
558 if ( op == oPercent ) { 553 if ( op == oPercent ) {
559 percent = TRUE; 554 percent = TRUE;
560 op = oSum; 555 op = oSum;
561 } 556 }
562 while( !operationStack.isEmpty() && operationStack.top().operation >= op ) { 557 while( !operationStack.isEmpty() && operationStack.top().operation >= op ) {
563 Op operation = operationStack.pop(); 558 Op operation = operationStack.pop();
564 acc = operation.number; 559 acc = operation.number;
565 if ( percent ) { 560 if ( percent ) {
566 if ( operation.operation == oAdd || operation.operation == oSub ) 561 if ( operation.operation == oAdd || operation.operation == oSub )
567 num = acc*num/100; 562 num = acc*num/100;
568 else 563 else
569 num = num / 100; 564 num = num / 100;
570 } 565 }
571 num = evalExpr( operation.operation ); 566 num = evalExpr( operation.operation );
572 percent = FALSE; 567 percent = FALSE;
573 } 568 }
574} 569}
575 570
576 571
577double CalculatorImpl::evalExpr( int op ) { 572double CalculatorImpl::evalExpr( int op ) {
578 double sum = 0; 573 double sum = 0;
579 574
580 switch( op ){ 575 switch( op ){
581 case oPercent: sum = num / 100.; break; 576 case oPercent: sum = num / 100.; break;
582 case oDivX: 577 case oDivX:
583 if (num == 0) 578 if (num == 0)
584 state = sError; 579 state = sError;
585 else 580 else
586 sum = 1 / num; 581 sum = 1 / num;
587 break; 582 break;
588 case oXsquared: 583 case oXsquared:
589 sum = pow(acc,num); 584 sum = pow(acc,num);
590 break; 585 break;
591 case oChSign: (state == sStart) ? sum = -num : sum = -acc; break; 586 case oChSign: (state == sStart) ? sum = -num : sum = -acc; break;
592 case oSub: sum = acc - num; break; 587 case oSub: sum = acc - num; break;
593 case oMult: sum = acc * num; break; 588 case oMult: sum = acc * num; break;
594 case oAdd: sum = acc + num; break; 589 case oAdd: sum = acc + num; break;
595 case oDiv: { 590 case oDiv: {
596 if (num == 0) { 591 if (num == 0) {
597 state = sError; 592 state = sError;
598 } else { 593 } else {
599 sum = acc / num; 594 sum = acc / num;
600 } 595 }
601 break; 596 break;
602 } 597 }
603 case oRoot: 598 case oRoot:
604 /* the linux library is dumb, and can't to -x to 1/n 599 /* the linux library is dumb, and can't to -x to 1/n
605 when n is odd. (even and error of course is acceptable */ 600 when n is odd. (even and error of course is acceptable */
606 if((acc < 0) && (int(num) == num) && (int(num) % 2 == 1 )) { 601 if((acc < 0) && (int(num) == num) && (int(num) % 2 == 1 )) {
607 sum = pow(-acc, 1 / num); 602 sum = pow(-acc, 1 / num);
608 sum = -sum; 603 sum = -sum;
609 } else { 604 } else {
610 sum = pow(acc, 1 / num); 605 sum = pow(acc, 1 / num);
611 } 606 }
612 break; 607 break;
613 case oLog: 608 case oLog:
614 sum = log10(num); 609 sum = log10(num);
615 break; 610 break;
616 case oLn: 611 case oLn:
617 sum = log(num); 612 sum = log(num);
618 break; 613 break;
619 case oTan: sum = qTan(num);break; 614 case oTan: sum = qTan(num);break;
620 case oSin: sum = qSin(num);break; 615 case oSin: sum = qSin(num);break;
621 case oCos: sum = qCos(num);break; 616 case oCos: sum = qCos(num);break;
622 default: sum = num; break; 617 default: sum = num; break;
623 } 618 }
624 619
625 if ( isinf( sum ) || isnan( sum ) ) 620 if ( isinf( sum ) || isnan( sum ) )
626 state = sError; 621 state = sError;
627 return sum; 622 return sum;
628} 623}
629 624
630 625
631void CalculatorImpl::enterNumber( int n ) 626void CalculatorImpl::enterNumber( int n )
632{ 627{
633 if ( state == sError ) 628 if ( state == sError )
634 return; 629 return;
635 if( state == sStart ){ 630 if( state == sStart ){
636 if( LCD->value() > 0 ){ 631 if( LCD->value() > 0 ){
637 QString s = QString::number( LCD->value(), 'g', LCD->numDigits()); 632 QString s = QString::number( LCD->value(), 'g', LCD->numDigits());
638 if( s.length() > (uint)(LCD->numDigits() - 2)) return; 633 if( s.length() > (uint)(LCD->numDigits() - 2)) return;
639 634
640 } else if( (int)fake.length() >= LCD->numDigits() || numDecimals >=12 ){ 635 } else if( (int)fake.length() >= LCD->numDigits() || numDecimals >=12 ){
641 return; 636 return;
642 } 637 }
643 } 638 }
644 639
645 if( state == sNewNumber ){ 640 if( state == sNewNumber ){
646 state = sStart; 641 state = sStart;
647 acc = 0; 642 acc = 0;
648 if( flPoint ){ 643 if( flPoint ){
649 numDecimals = 1; 644 numDecimals = 1;
650 num = n / pow(10, numDecimals); 645 num = n / pow(10, numDecimals);
651 } else 646 } else
652 num = n; 647 num = n;
653 } else if( flPoint ){ 648 } else if( flPoint ){
654 numDecimals++; 649 numDecimals++;
655 if( num < 0 ){ 650 if( num < 0 ){
656 num -= n / pow(10, numDecimals); 651 num -= n / pow(10, numDecimals);
657 } else { 652 } else {
658 num += n / pow(10, numDecimals); 653 num += n / pow(10, numDecimals);
659 } 654 }
660 } else { 655 } else {
661 num *= 10; 656 num *= 10;
662 if( num < 0 ) 657 if( num < 0 )
663 num -= n; 658 num -= n;
664 else 659 else
665 num += n; 660 num += n;
666 } 661 }
667 662
668 // We need feedback in the calc display while entering fl.point zeros. 663 // We need feedback in the calc display while entering fl.point zeros.
669 // This is a small hack to display sequences like: 0.000 and 1.100 664 // This is a small hack to display sequences like: 0.000 and 1.100
670 double integer, fraction; 665 double integer, fraction;
671 fraction = modf( num, &integer ); 666 fraction = modf( num, &integer );
672 if( flPoint ){ 667 if( flPoint ){
673 QString is, fs, zeros; 668 QString is, fs, zeros;
674 669
675 is = QString::number( integer, 'g', 13 ); 670 is = QString::number( integer, 'g', 13 );
676 fs = QString::number( fraction, 'g', numDecimals ); 671 fs = QString::number( fraction, 'g', numDecimals );
677 if( fs.contains('e') ){ 672 if( fs.contains('e') ){
678 fs = QString::number( fraction, 'f', LCD->numDigits() ); 673 fs = QString::number( fraction, 'f', LCD->numDigits() );
679 } 674 }
680 fs = fs.mid( 2, numDecimals ); 675 fs = fs.mid( 2, numDecimals );
681 676
682 if( (integer == 0) && (fraction == 0) ) 677 if( (integer == 0) && (fraction == 0) )
683 fake = "0."; 678 fake = "0.";
684 else if( (integer != 0) && (fraction == 0) ) 679 else if( (integer != 0) && (fraction == 0) )
685 fake = is + "."; 680 fake = is + ".";
686 else 681 else
687 fake = is + "." + fs; 682 fake = is + "." + fs;
688 683
689 zeros.fill( '0', (numDecimals - fs.length()) ); 684 zeros.fill( '0', (numDecimals - fs.length()) );
690 fake += zeros; 685 fake += zeros;
691 // ### This code sets LCD->value() to zero since it sets a text 686 // ### This code sets LCD->value() to zero since it sets a text
692 // ### Avoid getting the current value from LCD->value() for 687 // ### Avoid getting the current value from LCD->value() for
693 // ### calculations. 688 // ### calculations.
694 LCD->display( fake ); 689 LCD->display( fake );
695 } else 690 } else
696 LCD->display( num ); 691 LCD->display( num );
697} 692}
698 693
699void CalculatorImpl::command_buttons(int i) { 694void CalculatorImpl::command_buttons(int i) {
700 if ( state == sError && i != 3 ) 695 if ( state == sError && i != 3 )
701 return; 696 return;
702 switch (i) { 697 switch (i) {
703 case 0: // M+ 698 case 0: // M+
704 mem += num; 699 mem += num;
705 if( mem != 0 ){ 700 if( mem != 0 ){
706 memMark->show(); 701 memMark->show();
707 PushButtonMR->setEnabled( TRUE ); }; 702 PushButtonMR->setEnabled( TRUE ); };
708 state = sNewNumber; 703 state = sNewNumber;
709 break; 704 break;
710 case 1: // MR 705 case 1: // MR
711 acc = num = mem; 706 acc = num = mem;
712 state = sNewNumber; 707 state = sNewNumber;
713 LCD->display( mem ); 708 LCD->display( mem );
714 break; 709 break;
715 case 2: // MC 710 case 2: // MC
716 mem = 0; 711 mem = 0;
717 memMark->hide(); 712 memMark->hide();
718 PushButtonMR->setEnabled( FALSE ); 713 PushButtonMR->setEnabled( FALSE );
719 break; 714 break;
720 case 3: // CE 715 case 3: // CE
721 if ( state == sStart ) { 716 if ( state == sStart ) {
722 // clear the entered number on the first press 717 // clear the entered number on the first press
723 state = sNewNumber; 718 state = sNewNumber;
724 num = acc = 0; 719 num = acc = 0;
725 flPoint = FALSE; 720 flPoint = FALSE;
726 LCD->display( 0 ); 721 LCD->display( 0 );
727 fake = QString::null; 722 fake = QString::null;
728 numDecimals = 0; 723 numDecimals = 0;
729 } else { 724 } else {
730 clear(); 725 clear();
731 } 726 }
732 break; 727 break;
733 }; 728 };
734 729
735} 730}