wcalc  2.5
About: Wcalc is a natural-expression command-line calculator.
  Fossies Dox: wcalc-2.5.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

WcalcController.m
Go to the documentation of this file.
1 #include <pthread.h>
2 #include "calculator.h"
3 #include "variables.h"
4 #include "conversion.h"
5 #include "ErrorController.h"
6 #include "historyManager.h"
7 #include "WcalcController.h"
8 #include "string_manip.h"
9 #include "files.h"
10 #include "MyTextField.h"
11 #include "simpleCalc.h"
12 #include "list.h"
13 #include "number.h"
14 
15 #define KEYPAD_HEIGHT 165
16 #define MIN_WINDOW_WIDTH 171
17 #define MIN_WINDOW_HEIGHT_TOGGLED 112
18 #define MIN_WINDOW_HEIGHT_UNTOGGLED 277
19 #define FIELD_WIDTH_DIFFERENCE 22
20 #define MAX_WINDOW_SIZE 10000
21 
22 static char update_history = 0;
23 NSButton *e;
24 NSTextField *ef;
25 static NSString *curFile = NULL;
26 static pthread_mutex_t displayLock;
27 
28 @implementation WcalcController
29 
30 - (IBAction)toggleSize:(id)sender
31 {
32  static BOOL shrinking = TRUE;
33  NSRect mainwindow = [mainWindow frame];
34  NSRect expr = [ExpressionField frame];
35  NSRect prec = [PrecisionSlider frame];
36  NSRect ans = [AnswerField frame];
37  NSSize w;
38  NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
39 
40  if (shrinking) {
41  // if removing the keypad, change the window height
42  mainwindow.size.height -= KEYPAD_HEIGHT;
43  mainwindow.origin.y += KEYPAD_HEIGHT;
44  // this is set in case the calc starts up toggled (under other
45  // conditions it is not strictly necessary, because the ExpressionField
46  // has achieved the correct size automatically
47  expr.size.height = mainwindow.size.height
48  - ans.size.height
49  - prec.size.height
50  - 57 /* the size of the rest of the window, including title bar */;
51  [sizeToggleMenu setTitle:@"Show Keypad"];
52  } else {
53  // if adding the keypad, change the window height
54  mainwindow.size.height += KEYPAD_HEIGHT;
55  mainwindow.origin.y -= KEYPAD_HEIGHT;
56  mainwindow.size.width = MIN_WINDOW_WIDTH;
57  [sizeToggleMenu setTitle:@"Hide Keypad"];
58  }
59 
60  expr.size.width = prec.size.width = mainwindow.size.width - FIELD_WIDTH_DIFFERENCE;
61 
62  if (shrinking) {
63  [keypad removeFromSuperview];
64  expr.origin.y -= KEYPAD_HEIGHT;
65  prec.origin.y -= KEYPAD_HEIGHT;
66  } else {
67  expr.origin.y += KEYPAD_HEIGHT;
68  prec.origin.y += KEYPAD_HEIGHT;
69  }
70 
71  [ExpressionField removeFromSuperview];
72  [PrecisionSlider removeFromSuperview];
73 
74  if (sender != 0) {
75  [mainWindow setFrame:mainwindow display:TRUE animate:TRUE];
76  } else {
77  [mainWindow setFrame:mainwindow display:FALSE animate:FALSE];
78  }
79 
80  if (! shrinking) {
81  [superview addSubview:keypad];
82  w.width = MIN_WINDOW_WIDTH;
83  w.height = MIN_WINDOW_HEIGHT_UNTOGGLED + (ans.size.height - 21);
84  [mainWindow setMinSize:w];
85  w.width = MIN_WINDOW_WIDTH;
86  w.height = MAX_WINDOW_SIZE;
87  [mainWindow setMaxSize:w];
88  [prefs setObject:@"NO" forKey:@"toggled"];
89  } else {
90  w.width = MIN_WINDOW_WIDTH;
91  w.height = MIN_WINDOW_HEIGHT_TOGGLED + (ans.size.height - 21);
92  [mainWindow setMinSize:w];
93  w.width = MAX_WINDOW_SIZE;
94  w.height = MAX_WINDOW_SIZE;
95  [mainWindow setMaxSize:w];
96  [prefs setObject:@"YES" forKey:@"toggled"];
97  }
98 
99  [ExpressionField setFrame:expr];
100  [PrecisionSlider setFrame:prec];
101 
102  [superview addSubview:ExpressionField];
103  [superview addSubview:PrecisionSlider];
104 
105  [ExpressionField selectText:sender];
106 
107  shrinking = ! shrinking;
108 }
109 
110 - (IBAction)clear:(id)sender
111 {
112  if ([[ExpressionField stringValue] length]) {
113  [ExpressionField setStringValue:@""];
114  [ExpressionField selectText:self];
115  } else if ([[AnswerField stringValue] length]) {
116  [AnswerField setStringValue:@""];
117  [ExpressionField selectText:self];
118  }
119 }
120 
121 - (IBAction)menuConstant:(id)sender
122 {
123  NSString *str = [ExpressionField stringValue];
124  NSString *str2 = @"error!";
125 
126  switch ([sender tag]) {
127  case 1: str2 = [NSString stringWithFormat:@"%C", 0x03c0]; break;
128  case 2: str2 = @"e"; break;
129  case 3: str2 = [NSString stringWithFormat:@"%C", 0x03b3]; break;
130  case 4: str2 = @"g"; break;
131  case 5: str2 = @"Cc"; break;
132  case 8: str = @"K"; break;
133 
134  case 101: str2 = @"Z0"; break;
135  case 102: str2 = [NSString stringWithFormat:@"%C0", 0x03b5]; break;
136  case 103: str2 = [NSString stringWithFormat:@"%C0", 0x03bc]; break;
137  case 104: str2 = @"G"; break;
138  case 105: str2 = @"h"; break;
139  case 106: str2 = @"c"; break;
140 
141  case 201: str2 = [NSString stringWithFormat:@"%CB", 0x03bc]; break;
142  case 202: str2 = [NSString stringWithFormat:@"%CN", 0x03bc]; break;
143  case 203: str2 = @"G0"; break;
144  case 204: str2 = @"ec"; break;
145  case 205: str2 = @"Kj"; break;
146  case 206: str2 = @"Rk"; break;
147  case 207: str2 = [NSString stringWithFormat:@"%C0", 0x03a6]; break;
148 
149  case 301: str2 = [NSString stringWithFormat:@"M%C", 0x03b1]; break;
150  case 302: str2 = @"a0"; break;
151  case 303: str2 = @"Md"; break;
152  case 304: str2 = @"Me"; break;
153  case 305: str2 = @"re"; break;
154  case 306: str2 = @"eV"; break;
155  case 307: str2 = @"Gf"; break;
156  case 308: str2 = [NSString stringWithFormat:@"%C", 0x03b1]; break;
157  case 309: str2 = @"Eh"; break;
158  case 310: str2 = @"Mh"; break;
159  case 311: str2 = [NSString stringWithFormat:@"m%C", 0x03bc]; break;
160  case 312: str2 = @"Mn"; break;
161  case 313: str2 = @"Mp"; break;
162  case 314: str2 = [NSString stringWithFormat:@"R%C", 0x221E]; break;
163  case 315: str2 = [NSString stringWithFormat:@"M%C", 0x03c4]; break;
164 
165  case 401: str2 = @"u"; break;
166  case 402: str2 = @"Na"; break;
167  case 403: str2 = @"k"; break;
168  case 404: str2 = @"F"; break;
169  case 405: str2 = @"c1"; break;
170  case 406: str2 = @"n0"; break;
171  case 407: str2 = @"R"; break;
172  case 408: str2 = @"Vm"; break;
173  case 409: str2 = @"c2"; break;
174  case 410: str2 = [NSString stringWithFormat:@"%C", 0x03c3]; break;
175  case 411: str2 = @"b"; break;
176 
177  case 6: str2 = @"random"; break;
178  case 7: str2 = @"irandom"; break;
179  default: return;
180  }
181  if ([str length]) {
182  NSString *str3 = [NSString stringWithFormat:@"%C",0x00d7];
183  [ExpressionField setStringValue:[str stringByAppendingString:[str3 stringByAppendingString:str2]]];
184  } else {
185  [ExpressionField setStringValue:str2];
186  }
187 }
188 
189 - (IBAction)menuFunction:(id)sender
190 {
191  NSString *str = [[ExpressionField stringValue] stringByAppendingString:@")"];
192  NSString *str2;
193 
194  if ([str length] == 1) str = @"";
195 
196  switch ([sender tag]) {
197  case 1: str2 = @"sin("; break;
198  case 2: str2 = @"cos("; break;
199  case 3: str2 = @"tan("; break;
200  case 4: str2 = @"asin("; break;
201  case 5: str2 = @"acos("; break;
202  case 6: str2 = @"atan("; break;
203  case 7: str2 = @"sinh("; break;
204  case 8: str2 = @"cosh("; break;
205  case 9: str2 = @"tanh("; break;
206  case 10: str2 = @"asinh("; break;
207  case 11: str2 = @"acosh("; break;
208  case 12: str2 = @"atanh("; break;
209  case 13: str2 = @"log("; break;
210  case 14: str2 = @"ln("; break;
211  case 15: str2 = @"round("; break;
212  case 16: str2 = @"abs("; break;
213  case 17: str2 = @"sqrt("; break;
214  case 18: str2 = @"floor("; break;
215  case 19: str2 = @"ceil("; break;
216  case 20: str2 = @"cbrt("; break;
217  case 21: str2 = @"logtwo("; break;
218  case 22: str2 = @"cot("; break;
219  case 23: str2 = @"acot("; break;
220  case 24: str2 = @"coth("; break;
221  case 25: str2 = @"acoth("; break;
222  case 26: str2 = @"rand("; break;
223  case 27: str2 = @"irand("; break;
224  case 28: str2 = @"Gamma("; break;
225  case 29: str2 = @"lnGamma("; break;
226  case 30: str2 = @"zeta("; break;
227  case 31: str2 = @"sec("; break;
228  case 32: str2 = @"csc("; break;
229  case 33: str2 = @"asec("; break;
230  case 34: str2 = @"acsc("; break;
231  case 35: str2 = @"sech("; break;
232  case 36: str2 = @"csch("; break;
233  case 37: str2 = @"asech("; break;
234  case 38: str2 = @"acsch("; break;
235  case 39: str2 = @"eint("; break;
236  case 40: str2 = @"sinc("; break;
237  case 41: str2 = @"exp("; break;
238  case 42: str2 = @"fact("; break;
239  case 43: str2 = @"comp("; break;
240  default: return;
241  }
242  [ExpressionField setStringValue:[str2 stringByAppendingString:str]];
243 }
244 
245 - (void)awakeFromNib
246 {
247  NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
248  NSRect w;
249  NSSize bounds;
250  int prefsVersion;
251 
252  Dprintf("awakeFromNib\n");
253  prefsVersion = [prefs integerForKey:@"initialized"];
254  Dprintf("prefsVersion: %i\n", prefsVersion);
255  if (prefsVersion < 1) {
256  Dprintf("Upgrading prefs to v1\n");
257  [prefs setObject:@"-1" forKey:@"precision"];
258  [prefs setObject:@"NO" forKey:@"historyDuplicatesAllowed"];
259  [prefs setObject:@"NO" forKey:@"flagUndefinedVariables"];
260  [prefs setObject:@"YES" forKey:@"useRadians"];
261  [prefs setObject:@"0" forKey:@"outputFormat"];
262  [prefs setObject:@"YES" forKey:@"printPrefixes"];
263  [prefs setObject:@"NO" forKey:@"updateHistory"];
264  [prefs setObject:@"YES" forKey:@"strictSyntax"];
265  [prefs setObject:@"0" forKey:@"roundingIndication"];
266  [prefs setObject:@"NO" forKey:@"historyShowing"];
267  [prefs setObject:@"YES" forKey:@"rememberErrors"];
268  [prefs setObject:@"NO" forKey:@"baseShowing"];
269  [prefs setObject:@"YES" forKey:@"precisionGuard"];
270  [prefs setObject:@"NO" forKey:@"historyLimit"];
271  [prefs setObject:@"1000" forKey:@"historyLimitLength"];
272  [prefs setObject:@"NO" forKey:@"printInts"];
273  [prefs setObject:@"NO" forKey:@"simpleCalc"];
274  [prefs setObject:@"NO" forKey:@"printDelimiters"];
275  }
276  if (prefsVersion < 2) {
277  Dprintf("Upgrading prefs to v2\n");
278  [prefs setObject:@"YES" forKey:@"livePrecision"];
279  [prefs setObject:@"1024" forKey:@"internalPrecision"];
280  [prefs setObject:@"YES" forKey:@"cModStyle"];
281  }
282  if (prefsVersion < 3) {
283  Dprintf("Upgrading prefs to v3\n");
284  [prefs setObject:@"3" forKey:@"initialized"];
285  [prefs setObject:@"147" forKey:@"maxSliderPrecision"];
286  }
287  if (prefsVersion < 4) {
288  Dprintf("Upgrading prefs to v4\n");
289  [prefs setObject:@"4" forKey:@"initialized"];
290  [prefs setObject:@"1" forKey:@"engineeringNotation"];
291  }
292  if (prefsVersion < 5) {
293  Dprintf("Upgrading prefs to v5\n");
294  [prefs setObject:@"5" forKey:@"initialized"];
295  [prefs setObject:@"" forKey:@"alternateInputDecimalSeparator"];
296  [prefs setObject:@"" forKey:@"alternateInputThousandsSeparator"];
297  }
298  conf.precision = [prefs integerForKey:@"precision"];
299  switch([prefs integerForKey:@"engineeringNotation"]) {
300  case 1: conf.engineering = automatic; break;
301  case 2: conf.engineering = never; break;
302  case 3: conf.engineering = always; break;
303  }
304  conf.picky_variables = [prefs boolForKey:@"flagUndefinedVariables"];
305  conf.use_radians = [prefs boolForKey:@"useRadians"];
306  conf.output_format = [prefs integerForKey:@"outputFormat"];
307  conf.print_prefixes = [prefs boolForKey:@"printPrefixes"];
308  /* conf.strict_syntax = [prefs boolForKey:@"strictSyntax"]; */
309  conf.rounding_indication = [prefs integerForKey:@"roundingIndication"];
310  conf.precision_guard = [prefs boolForKey:@"precisionGuard"];
311  conf.print_ints = [prefs boolForKey:@"printInts"];
312  conf.print_commas = [prefs boolForKey:@"printDelimiters"];
313  conf.simple_calc = [prefs boolForKey:@"simpleCalc"];
314  conf.live_precision = [prefs boolForKey:@"livePrecision"];
315  [PrecisionSlider setMaxValue:[prefs floatForKey:@"maxSliderPrecision"]];
316  /* history preferences */
317  allow_duplicates = [prefs boolForKey:@"historyDuplicatesAllowed"];
318  update_history = [prefs boolForKey:@"updateHistory"];
319  conf.remember_errors = [prefs boolForKey:@"rememberErrors"];
320  conf.history_limit = [prefs boolForKey:@"historyLimit"];
321  conf.history_limit_len = [prefs integerForKey:@"historyLimitLen"];
322  {
323  NSDictionary *temp = [prefs dictionaryForKey:@"persistentVariables"];
324  NSEnumerator *enumerator = [temp keyEnumerator];
325  id key;
326 
327  while ((key = [enumerator nextObject])) {
328  putexp(strdup([key UTF8String]),strdup([[temp objectForKey:key] UTF8String]),"preloaded");
329  }
330  }
331  if ([prefs integerForKey:@"internalPrecision"] < 32) {
332  [prefs setObject:@"1024" forKey:@"internalPrecision"];
333  }
334  if ([prefs integerForKey:@"internalPrecision"] > 4096) {
335  [prefs setObject:@"4096" forKey:@"internalPrecision"];
336  }
337  init_numbers();
338  num_set_default_prec([prefs integerForKey:@"internalPrecision"]);
339  Dprintf("preferences read\n");
340 
341  [PrecisionSlider setIntValue:conf.precision];
342  Dprintf("precision slider\n");
343  just_answered = FALSE;
344 
345  /* Set up the character translation */
346  NSNumberFormatter *numFormat = [[[NSNumberFormatter alloc] init] autorelease];
347  if ([[numFormat decimalSeparator] length] > 0) {
348  Dprintf("NSDecimalSeparator > 0\n");
349  conf.dec_delimiter = [[numFormat decimalSeparator] characterAtIndex:0];
350  } else {
351  conf.dec_delimiter = '.';
352  }
353  Dprintf("NSDecimalSeparator set (%c)\n", conf.dec_delimiter);
354  if ([[numFormat groupingSeparator] length] > 0) {
355  Dprintf("NSGroupingSeparator > 0\n");
356  conf.thou_delimiter = [[numFormat groupingSeparator] characterAtIndex:0];
357  } else {
358  conf.thou_delimiter = 0;
359  }
360  Dprintf("NSGroupingSeparator set (%c)\n", conf.thou_delimiter);
361  if ([[prefs stringForKey:@"alternateInputDecimalSeparator"] length] > 0) {
362  conf.in_dec_delimiter = [[prefs stringForKey:@"alternateInputDecimalSeparator"] characterAtIndex:0];
363  Dprintf("alternate input dec sep (%c)\n", conf.in_dec_delimiter);
364  }
365  if ([[prefs stringForKey:@"alternateInputThousandsSeparator"] length] > 0) {
366  conf.in_thou_delimiter = [[prefs stringForKey:@"alternateInputThousandsSeparator"] characterAtIndex:0];
367  Dprintf("alternate input thou sep (%c)\n", conf.in_thou_delimiter);
368  }
369  if (conf.in_dec_delimiter != 0) {
370  [decimalKey setTitle:[NSString stringWithCString:&conf.in_dec_delimiter length:1]];
371  } else {
372  [decimalKey setTitle:[numFormat decimalSeparator]];
373  Dprintf("decimalKey title set\n");
374  }
375 
376  /* reset the window to the saved setting */
377  superview = [keypad superview];
378  [keypad retain];
379  [PrecisionSlider retain];
380  [ExpressionField retain];
381  Dprintf("interface retained\n");
382  [mainWindow useOptimizedDrawing:TRUE];
383  [mainWindow setFrameAutosaveName:@"wcalc"];
384  Dprintf("frame autosave set\n");
385  w = [mainWindow frame];
386  if ([prefs boolForKey:@"toggled"]) {
387  Dprintf("window is toggled\n");
388  w.size.height += KEYPAD_HEIGHT;
389  w.origin.y -= KEYPAD_HEIGHT;
390  [mainWindow setFrame:w display:TRUE animate:FALSE];
391  Dprintf("frame set\n");
392  [self toggleSize:0];
393  Dprintf("toggled\n");
394  } else {
395  Dprintf("window not toggled\n");
396  w.size.width = MIN_WINDOW_WIDTH;
397  [mainWindow setFrame:w display:TRUE animate:FALSE];
398  bounds.width = MIN_WINDOW_WIDTH;
399  bounds.height = MIN_WINDOW_HEIGHT_UNTOGGLED;
400  [mainWindow setMinSize:bounds];
401  bounds.width = MIN_WINDOW_WIDTH;
402  bounds.height = MAX_WINDOW_SIZE;
403  [mainWindow setMaxSize:bounds];
404  Dprintf("window size restored\n");
405  }
406  // w = [mainWindow frame];
407  // bounds = [mainWindow minSize];
408 
409  e = enterKey;
411 
412  /* this restores the drawer states */
413  if ([prefs boolForKey:@"historyShowing"]) {
414  Dprintf("history showing\n");
415  [NSTimer scheduledTimerWithTimeInterval:0 target:self selector:@selector(openIDrawer:) userInfo:nil repeats:NO];
416  Dprintf("history drawer displayed\n");
417  }
418  if ([prefs boolForKey:@"baseShowing"]) {
419  Dprintf("base showing\n");
420  [NSTimer scheduledTimerWithTimeInterval:0 target:self selector:@selector(openBDrawer:) userInfo:nil repeats:NO];
421  Dprintf("base drawer displayed\n");
422  }
423  Dprintf("done with drawers\n");
424 
425  /* set the correct expression display for simple_calc */
426  if (conf.simple_calc) {
427  Dprintf("simple calc\n");
428  [ExpressionField setStringValue:@"0"];
429  [AnswerField setStringValue:@"0"];
430  Dprintf("values zeroed\n");
431  simpleClearAll();
432  Dprintf("simple all cleared\n");
433  }
435  Dprintf("last answer cleared\n");
436  pthread_mutex_init(&displayLock,NULL);
437  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(quit:) name:NSWindowWillCloseNotification object:mainWindow];
438  NSUpdateDynamicServices();
439 }
440 
441 - (void)openBDrawer: (id) sender
442 {
443  [baseDrawer open];
444  [baseMenu setTitle:@"Close Base Drawer"];
445 }
446 
447 - (void)openIDrawer: (id) sender
448 {
449  [inspector openIt:sender];
450 }
451 
452 - (IBAction)setPrecision:(id)sender
453 {
454  int last_pres=0;
455  NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
456 
457  last_pres = [prefs integerForKey:@"precision"];
458 
459  if (last_pres == [PrecisionSlider intValue])
460  return;
461  else
462  last_pres = [PrecisionSlider intValue];
463 
464  Dprintf("setPrecision: %i to %i\n",conf.precision,last_pres);
465  conf.precision = last_pres;
466  [prefs setObject:[NSString stringWithFormat:@"%i",conf.precision] forKey:@"precision"];
467  Dprintf("setPrecision - prefs set\n");
468 
469  Dprintf("getting lock\n");
470  pthread_mutex_lock(&displayLock);
471  Dprintf("locked\n");
472  {
474  Dprintf("setPrecision - set_prettyanswer\n");
475  [self displayAnswer];
476  Dprintf("setPrecision - done\n");
477  }
478  pthread_mutex_unlock(&displayLock);
479  Dprintf("unlocked\n");
480 }
481 
482 - (IBAction)go:(id)sender
483 {
484  char * expression;
485  extern char * errstring;
486 
487  expression = strdup([[ExpressionField stringValue] UTF8String]);
488 
489  parseme(expression);
490  putval("a",last_answer,"previous answer");
491 
492  /* if it isn't an error (or if you want me to remember errors) record it in the history */
493  if (!errstring || (errstring && !strlen(errstring)) || conf.remember_errors) {
494  addToHistory(expression, last_answer);
495  free(expression);
496  }
497 
498  [self displayAnswer];
499 }
500 
502 {
503  extern char * errstring;
504 
505  Dprintf("displayAnswer\n");
506  /* if there is an error, display it */
507  if (errstring && strlen(errstring)) {
508  extern int scanerror;
509  scanerror = 0;
510  Dprintf("displayAnswer error %s\n",errstring);
511  [errorController throwAlert:[NSString stringWithUTF8String:errstring]];
512  free(errstring);
513  errstring = NULL;
514  }
515  /* display the answer */
516  Dprintf("displayAnswer - pretty_answer(%p)\n",pretty_answer);
517  Dprintf("displayAnswer - %s\n",pretty_answer);
518  [AnswerField setStringValue:[NSString stringWithFormat:@"%s",pretty_answer]];
519  [AnswerField setTextColor:(not_all_displayed?[NSColor redColor]:[NSColor blackColor])];
520  Dprintf("displayAnswer - changing size\n");
521  { // Make the Answerfield big enough to display the answer
522  NSRect curFrame, newFrame;
523  curFrame = [AnswerField frame];
524  Dprintf("displayAnswer - current size: %f x %f\n", curFrame.size.height, curFrame.size.width);
525  newFrame = curFrame;
526  // we set the height to a huge number because cellSizeForBounds only
527  // works "within" the specified bound, which we want because we want to
528  // limit the width.
529  newFrame.size.height = DBL_MAX;
530  newFrame.size = [[AnswerField cell] cellSizeForBounds:newFrame];
531  Dprintf("displayAnswer - needed size: %f x %f\n", newFrame.size.height, newFrame.size.width);
532  if (curFrame.size.height != newFrame.size.height) {
533  size_t newHeight = newFrame.size.height;
534  int difference = newHeight - curFrame.size.height;
535  NSRect windowFrame = [mainWindow frame];
536  int nonAnswerPixels = windowFrame.size.height - curFrame.size.height;
537  NSSize ms = [mainWindow minSize];
538 
539  newFrame = curFrame;
540  newFrame.size.height = newHeight;
541  ms.height += difference;
542  windowFrame.size.height += difference;
543  if (windowFrame.size.height < newFrame.size.height + nonAnswerPixels) {
544  windowFrame.size.height = newFrame.size.height + nonAnswerPixels;
545  }
546  windowFrame.origin.y -= difference;
547  curFrame = [ExpressionField frame];
548  [AnswerField setHidden:TRUE];
549  [ExpressionField setHidden:TRUE];
550  [mainWindow setFrame:windowFrame display:YES animate:YES];
551  windowFrame = [mainWindow frame];
552  /* At this point, the windowFrame may not be *quite* what I wanted it to be,
553  screens being of finite size and all... so we have to recalculate the size
554  that the AnswerField should be. */
555  newFrame.size.height = windowFrame.size.height - nonAnswerPixels;
556  [mainWindow setMinSize:ms];
557  [AnswerField setFrame:newFrame];
558  [ExpressionField setFrame:curFrame];
559  [AnswerField setHidden:FALSE];
560  [ExpressionField setHidden:FALSE];
561  }
562  }
563  Dprintf("displayAnswer - refresh inspector\n");
564  // if the drawer is open, refresh the data.
565  if ([inspectorWindow isVisible]) {
566  [variableList reloadData];
567  [historyList reloadData];
568  }
569  just_answered = TRUE;
570  // refresh the prefs if necessary
571  Dprintf("displayAnswer - refresh prefs\n");
572  if ([thePrefPanel isVisible])
573  [self displayPrefs:0];
574  Dprintf("displayAnswer - cleaning up\n");
575  [outputFormat2 selectCellWithTag:conf.output_format];
576  [ExpressionField selectText:self];
577  Dprintf("displayAnswer - done\n");
578 }
579 
580 - (IBAction)convert:(id)sender
581 {
582  int type = [convertType indexOfSelectedItem];
583  int from = [convertFrom selectedRow];
584  int to = [convertTo selectedRow];
585 
586  if (type < 0 || type > MAX_TYPE) return;
587  if (from < 0) return;
588  if (to < 0) return;
589 
590  uber_conversion(last_answer, type, from, to, last_answer);
592  [AnswerField setStringValue:[NSString stringWithUTF8String:(pretty_answer?pretty_answer:"Not Enough Memory")]];
593  putval("a",last_answer,"previous answer");
594  if ([inspectorWindow isVisible]) {
595  [variableList reloadData];
596  }
597 }
598 
599 - (IBAction)enterData:(id)sender
600 {
601  NSString * sent = [NSString stringWithString:[[sender attributedTitle] string]];
602  static short shiftdown = 0, capsdown = 0;
603  int tag;
604 
605  Dprintf("enterData\n");
606  [ExpressionField setSelectable:FALSE];
607  tag = [sender tag];
608  switch (tag) {
609  case 101: /* delete key on the onscreen keyboard */
610  if ([[ExpressionField stringValue] length] > 0) {
611  unsigned len = [[ExpressionField stringValue] length];
612  [ExpressionField setStringValue:[[ExpressionField stringValue] substringToIndex:len-1]];
613  }
614  break;
615  case 100: /* clear key on the onscreen keypad */
616  if (!conf.simple_calc) {
617  if ([[ExpressionField stringValue] length] > 0) {
618  [ExpressionField setStringValue:@""];
619  [ExpressionField selectText:self];
620  } else if ([[AnswerField stringValue] length] > 0) {
621  [AnswerField setStringValue:@""];
622  [ExpressionField selectText:self];
623  }
624  } else {
625  if (! [[ExpressionField stringValue] isEqualToString:@"0"]) {
626  [ExpressionField setStringValue:@"0"];
627  [ExpressionField selectText:self];
629  } else {
630  [AnswerField setStringValue:@"0"];
631  [ExpressionField selectText:self];
632  simpleClearAll();
633  }
634  }
635  break;
636  case 102: /* caps lock key on onscreen keyboard */
637  if (capsdown) {
638  [shiftKey1 setEnabled:true];
639  [shiftKey2 setEnabled:true];
640  capsdown = 0;
641  } else {
642  [shiftKey1 setEnabled:false];
643  [shiftKey2 setEnabled:false];
644  capsdown = 1;
645  }
646  break;
647  case 103: /* shift key on onscreen keyboard */
648  if (shiftdown) {
649  [shiftKey1 setState:NSOffState];
650  [shiftKey2 setState:NSOffState];
651  shiftdown = 0;
652  } else {
653  [shiftKey1 setState:NSOnState];
654  [shiftKey2 setState:NSOnState];
655  shiftdown = 1;
656  }
657  break;
658  case 104: /* = key on onscreen keypad */
659  if (! conf.simple_calc) {
660  [self go:sender];
661  } else {
662  char * expr = strdup([[ExpressionField stringValue] UTF8String]);
663  char * ret;
664  ret = simpleCalc('=',expr);
665  if (ret) {
666  [ExpressionField setStringValue:[NSString stringWithUTF8String:ret]];
667  free(ret);
668  } else {
669  [self displayAnswer];
670  [ExpressionField setStringValue:[AnswerField stringValue]];
671  }
672  free(expr);
673  }
674  break;
675  case 105: /* the divide key on the onscreen keypad */
676  case 106: /* the minus key on the onscreen keypad */
677  case 107: /* the times key on the onscreen keypad */
678  default:
679  if (! conf.simple_calc) { /* the real power of Wcalc */
680  if (just_answered == FALSE) {
681  [ExpressionField setStringValue:[[ExpressionField stringValue] stringByAppendingString:sent]];
682  } else if ([sent isEqualToString:@"+"] ||
683  [sent isEqualToString:@"-"] ||
684  [sent isEqualToString:@"*"] ||
685  [sent isEqualToString:@"/"] ||
686  [sent isEqualToString:@"%"] ||
687  [sent isEqualToString:@"("] ||
688  [sent isEqualToString:@"&"] ||
689  [sent isEqualToString:@"|"] ||
690  [sent isEqualToString:[NSString stringWithFormat:@"%C",0x00f7]]) {
691  [ExpressionField setStringValue:[[@"a" self] stringByAppendingString:sent]];
692  } else {
693  [ExpressionField setStringValue:sent];
694  }
695  if (shiftdown) {
696  [shiftKey1 setState:NSOffState];
697  [shiftKey2 setState:NSOffState];
698  shiftdown = 0;
699  }
700  just_answered = FALSE;
701  } else { /* stupid calculator */
702  char *ret, *expr;
703  expr = strdup([[ExpressionField stringValue] UTF8String]);
704  Dprintf("expr: %s\n",expr);
705  switch (tag) {
706  case 105: ret = simpleCalc('/', expr); break;
707  case 106: ret = simpleCalc('-', expr); break;
708  case 107: ret = simpleCalc('*', expr); break;
709  default: ret = simpleCalc([sent characterAtIndex:0], expr);
710  }
711  free(expr);
712  if (ret) {
713  [ExpressionField setStringValue:[NSString stringWithUTF8String:ret]];
714  free(ret);
715  } else {
716  [self displayAnswer];
717  [ExpressionField setStringValue:[AnswerField stringValue]];
718  }
719  }
720  break;
721  }
722  [ExpressionField setEditable:TRUE];
723 }
724 
725 - (IBAction)shConversions:(id)sender
726 {
727  static char initialized = 0;
728  if (! [conversionWindow isVisible]) {
729  [conversionWindow makeKeyAndOrderFront:self];
730  if (! initialized) {
731  [conversionWindow center];
732  initialized = 1;
733  }
734  } else {
735  [conversionWindow close];
736  }
737 }
738 
739 - (IBAction)showKeyboardDrawer:(id)sender
740 {
741  static char initialized = 0;
742  if (! [theKeyboard isVisible]) {
743  [theKeyboard setBecomesKeyOnlyIfNeeded:YES];
744  [theKeyboard orderFront:self];
745  if (! initialized) {
746  [theKeyboard center];
747  initialized = 1;
748  }
749  } else {
750  [theKeyboard close];
751  }
752 }
753 
754 - (IBAction)showBaseDrawer:(id)sender
755 {
756  NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
757  if (! [baseDrawer state]) {
758  [baseDrawer open];
759  [prefs setObject:@"YES" forKey:@"baseShowing"];
760  [baseMenu setTitle:@"Close Base Drawer"];
761  } else {
762  [baseDrawer close];
763  [prefs setObject:@"NO" forKey:@"baseShowing"];
764  [baseMenu setTitle:@"Open Base Drawer"];
765  }
766 }
767 
768 - (IBAction)setPrefs:(id)sender
769 {
770  short need_redraw = 0;
771  short olde;
772  NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
773  int tag = [sender tag];
774 
775  switch (tag) {
776  case 1: // Flag Undefined Variables
777  olde = conf.picky_variables;
778  conf.picky_variables = ([pickyVariables state]==NSOnState);
779  if (olde != conf.picky_variables) {
780  [prefs setObject:(conf.picky_variables?@"YES":@"NO") forKey:@"flagUndefinedVariables"];
781  }
782  break;
783  case 2: // Use Radians
784  olde = conf.use_radians;
785  conf.use_radians = ([useRadians state]==NSOnState);
786  if (olde != conf.use_radians) {
787  need_redraw = 2;
788  [prefs setObject:(conf.use_radians?@"YES":@"NO") forKey:@"useRadians"];
789  }
790  break;
791  case 3: // Use Engineering Notation
792  {
793  int savedas = 1;
794  olde = conf.engineering;
795  printf("index: %i\n", [sender indexOfSelectedItem]);
796  switch([sender indexOfSelectedItem]) {
797  case 0: conf.engineering = automatic; savedas = 1; break;
798  case 1: conf.engineering = never; savedas = 2; break;
799  case 2: conf.engineering = always; savedas = 3; break;
800  }
801  if (olde != conf.engineering) {
802  need_redraw = 1;
803  printf("integet: %i\n", conf.engineering);
804  [prefs setObject:[NSString stringWithFormat:@"%i",savedas] forKey:@"engineeringNotation"];
805  }
806  }
807  break;
808  case 4: // Allow Duplicates in History
809  olde = allow_duplicates;
810  allow_duplicates = ([historyDuplicates state]==NSOnState);
811  if (olde != allow_duplicates) {
812  [prefs setObject:(allow_duplicates?@"YES":@"NO") forKey:@"historyDuplicatesAllowed"];
813  }
814  break;
815  case 5: // Output Format
816  olde = conf.output_format;
817  conf.output_format = [[sender selectedCell] tag];
818  if (olde != conf.output_format) {
819  need_redraw = 1;
820  [prefs setObject:[NSString stringWithFormat:@"%i",conf.output_format] forKey:@"outputFormat"];
821  [printPrefixes setEnabled:(conf.output_format!=DECIMAL_FORMAT)];
822  [engineeringNotation setEnabled:(conf.output_format==DECIMAL_FORMAT)];
823  }
824  [outputFormat selectCellWithTag:conf.output_format];
825  [outputFormat2 selectCellWithTag:conf.output_format];
826  break;
827  case 6: // Print Prefixes
828  olde = conf.print_prefixes;
829  conf.print_prefixes = ([sender state]==NSOnState);
830  if (olde != conf.print_prefixes) {
831  need_redraw = 1;
832  [prefs setObject:(conf.print_prefixes?@"YES":@"NO") forKey:@"printPrefixes"];
833  }
834  break;
835  case 7: // Update History
836  olde = update_history;
837  update_history = ([sender state]==NSOnState);
838  if (olde != update_history) {
839  [prefs setObject:(update_history?@"YES":@"NO") forKey:@"updateHistory"];
840  }
841  break;
842  case 10: // Rounding Indication
843  olde = conf.rounding_indication;
844  conf.rounding_indication = [sender indexOfSelectedItem];
845  if (olde != conf.rounding_indication) {
846  need_redraw = 1;
847  [prefs setObject:[NSString stringWithFormat:@"%i",conf.rounding_indication] forKey:@"roundingIndication"];
848  }
849  break;
850  case 11: // Record errors in history
851  olde = conf.remember_errors;
852  conf.remember_errors = ([sender state]==NSOnState);
853  if (olde != conf.remember_errors) {
854  [prefs setObject:(conf.remember_errors?@"YES":@"NO") forKey:@"rememberErrors"];
855  }
856  break;
857  case 12: // Conservative precision
858  olde = conf.precision_guard;
859  conf.precision_guard = ([sender state]==NSOnState);
860  if (olde != conf.precision_guard) {
861  need_redraw = 2;
862  [prefs setObject:(conf.precision_guard?@"YES":@"NO") forKey:@"precisionGuard"];
863  }
864  break;
865  case 13: // History length limit toggle
866  olde = conf.history_limit;
867  conf.history_limit = ([sender state]==NSOnState);
868  [limitHistoryLen setEnabled:conf.history_limit];
869  [limitHistoryLenTag setEnabled:conf.history_limit];
870  if (olde != conf.history_limit) {
871  [prefs setObject:(conf.history_limit?@"YES":@"NO") forKey:@"historyLimit"];
872  }
873  break;
874  case 14: // History length limit
875  if ((unsigned)[sender intValue] != conf.history_limit_len) {
876  conf.history_limit_len = [sender intValue];
877  [prefs setObject:[NSString stringWithFormat:@"%i",conf.history_limit_len] forKey:@"historyLimitLength"];
878  }
879  break;
880  case 15: // Print ints
881  olde = conf.print_ints;
882  conf.print_ints = ([sender state]==NSOnState);
883  if (olde != conf.print_ints) {
884  need_redraw = 1;
885  [prefs setObject:(conf.print_ints?@"YES":@"NO") forKey:@"printInts"];
886  }
887  break;
888  case 16: // Simple calculator
889  olde = conf.simple_calc;
890  conf.simple_calc = ([sender state]==NSOnState);
891  if (olde != conf.simple_calc) {
892  [prefs setObject:(conf.simple_calc?@"YES":@"NO") forKey:@"simpleCalc"];
893  if (conf.simple_calc) {
894  [ExpressionField setStringValue:@"0"];
895  [AnswerField setStringValue:@"0"];
896  simpleClearAll();
897  } else {
898  [ExpressionField setStringValue:@""];
899  [AnswerField setStringValue:@""];
900  }
901  /* disable irrelevant preferences */
902  [historyDuplicates setEnabled:!conf.simple_calc];
903  [limitHistory setEnabled:!conf.simple_calc];
904  [limitHistoryLen setEnabled:!conf.simple_calc];
905  [limitHistoryLenTag setEnabled:!conf.simple_calc];
906  [pickyVariables setEnabled:!conf.simple_calc];
907  [rememberErrors setEnabled:!conf.simple_calc];
908  [updateHistory setEnabled:!conf.simple_calc];
909  [useRadians setEnabled:!conf.simple_calc];
910  }
911  break;
912  case 17:
913  olde = conf.print_commas;
914  conf.print_commas = ([sender state]==NSOnState);
915  if (olde != conf.print_commas) {
916  need_redraw = 1;
917  [prefs setObject:(conf.print_ints?@"YES":@"NO") forKey:@"printDelimiters"];
918  }
919  break;
920  case 18:
921  if ((unsigned)[sender intValue] != num_get_default_prec()) {
922  [bitsStepper takeIntValueFrom:sender];
923  num_set_default_prec([bitsStepper intValue]); // to handle limits placed on bitsStepper
924  [prefs setObject:[NSString stringWithFormat:@"%lu",num_get_default_prec()] forKey:@"internalPrecision"];
925  }
926  break;
927  case 19:
928  if ((unsigned)[bitsStepper intValue] != num_get_default_prec()) {
929  num_set_default_prec([bitsStepper intValue]);
930  need_redraw = 2;
931  [bitsPref takeIntValueFrom:bitsStepper];
932  [prefs setObject:[NSString stringWithFormat:@"%lu",num_get_default_prec()] forKey:@"internalPrecision"];
933  }
934  break;
935  case 20:
936  olde = conf.live_precision;
937  conf.live_precision = ([sender state] == NSOnState);
938  if (olde != conf.print_commas) {
939  [prefs setObject:(conf.live_precision?@"YES":@"NO") forKey:@"livePrecision"];
940  [PrecisionSlider setContinuous:(conf.live_precision?true:false)];
941  }
942  break;
943  case 21:
944  olde = conf.c_style_mod;
945  conf.c_style_mod = ([sender state] == NSOnState);
946  if (olde != conf.c_style_mod) {
947  need_redraw = 2;
948  [prefs setObject:(conf.c_style_mod?@"YES":@"NO") forKey:@"cModStyle"];
949  }
950  break;
951  case 22:
952  if ((unsigned)[sliderStepper intValue] != [PrecisionSlider maxValue]) {
953  unsigned long tmp = [sliderStepper intValue];
954  [PrecisionSlider setMaxValue:(double)tmp];
955  [sliderPref takeIntValueFrom:sliderStepper];
956  [prefs setObject:[NSString stringWithFormat:@"%lu",tmp] forKey:@"maxSliderPrecision"];
957  }
958  break;
959  case 23:
960  if ((double)[sender intValue] != [PrecisionSlider maxValue]) {
961  [sliderStepper takeIntValueFrom:sender];
962  // these handle limits placed on sliderStepper
963  [sliderPref takeIntValueFrom:sliderStepper];
964  [PrecisionSlider setMaxValue:[sliderStepper doubleValue]];
965  [prefs setObject:[NSString stringWithFormat:@"%lu",[sliderStepper intValue]] forKey:@"maxSliderPrecision"];
966  }
967  break;
968  case 24:
969  [altInputDecSep setEnabled:([sender state] == NSOnState)];
970  [altInputThouSep setEnabled:([sender state] == NSOnState)];
971  if ([sender state] != NSOnState) {
972  [altInputDecSep setStringValue:@""];
973  [altInputThouSep setStringValue:@""];
976  [decimalKey setTitle:[NSString stringWithCString:&conf.dec_delimiter length:1]];
977  [prefs setObject:@"" forKey:@"alternateInputDecimalSeparator"];
978  [prefs setObject:@"" forKey:@"alternateInputThousandsSeparator"];
979  }
980  break;
981  case 25:
982  if ([[sender stringValue] length] > 0) {
983  conf.in_dec_delimiter = [[sender stringValue] characterAtIndex:0];
984  [decimalKey setTitle:[NSString stringWithCString:&conf.in_dec_delimiter length:1]];
985  [prefs setObject:[[sender stringValue] substringToIndex:1] forKey:@"alternateInputDecimalSeparator"];
986  } else {
988  [decimalKey setTitle:[NSString stringWithCString:&conf.dec_delimiter length:1]];
989  [prefs setObject:@"" forKey:@"alternateInputDecimalSeparator"];
990  }
991  break;
992  case 26:
993  if ([[sender stringValue] length] > 0) {
994  conf.in_thou_delimiter = [[sender stringValue] characterAtIndex:0];
995  [prefs setObject:[[sender stringValue] substringToIndex:1] forKey:@"alternateInputThousandsSeparator"];
996  } else {
998  [prefs setObject:@"" forKey:@"alternateInputThousandsSeparator"];
999  }
1000  break;
1001  default: return;
1002  }
1003 
1004  switch (need_redraw) {
1005  case 2:
1006  if (update_history)
1007  recalculate = 1;
1008  [self go:sender];
1009  break;
1010  case 1:
1012  [AnswerField setStringValue:[NSString stringWithUTF8String:(pretty_answer?pretty_answer:"Not Enough Memory")]];
1013  [AnswerField setTextColor:((not_all_displayed)?([NSColor redColor]):([NSColor blackColor]))];
1014  break;
1015  }
1016  if ([inspectorWindow isVisible] || recalculate) {
1017  [historyList reloadData];
1018  }
1019  [ExpressionField selectText:self];
1020 }
1021 
1022 - (IBAction)showPrefs:(id)sender
1023 {
1024  //static char initialized = 0;
1025  [self displayPrefs:sender];
1026  [thePrefPanel setBecomesKeyOnlyIfNeeded:TRUE];
1027  [thePrefPanel orderFront:self];
1028  // centering at first
1029  /*if (! initialized) {
1030  initialized=1;
1031  [thePrefPanel center];
1032  }*/
1033  // this should be redundant
1034  [thePrefPanel setFrameAutosaveName:@"wcalc_prefs"];
1035  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(savePrefs:) name:NSWindowWillCloseNotification object:thePrefPanel];
1036 }
1037 
1038 - (IBAction)savePrefs:(id)sender
1039 {
1040  NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
1041 
1042  Dprintf("synching the prefs to disk\n");
1043  [prefs synchronize];
1044 }
1045 
1046 - (IBAction)open:(id)sender
1047 {
1048  int result;
1049  NSArray *fileTypes = [NSArray arrayWithObjects:@"txt",@"text",@"wcalc",
1050  NSFileTypeForHFSTypeCode('TEXT'), nil];
1051  NSOpenPanel *oPanel = [NSOpenPanel openPanel];
1052  [oPanel setAllowsMultipleSelection:NO];
1053  /* display the panel */
1054  result = [oPanel runModalForDirectory:nil file:nil types:fileTypes];
1055  /* if they clicked the OK button */
1056  if (result == NSOKButton) {
1057  NSArray *filesToOpen = [oPanel filenames];
1058  int i, count = [filesToOpen count];
1059  /* loop through the files to open (there should only be one, but
1060  it's good to be able to handle multiple anyway */
1061  for (i=0; i<count; i++) {
1062  int retval;
1063  extern char * errstring;
1064  curFile = [filesToOpen objectAtIndex:i];
1065  retval = loadState(strdup([curFile UTF8String]),1);
1066  if ([inspectorWindow isVisible]) {
1067  [variableList reloadData];
1068  [historyList reloadData];
1069  }
1070  /* if there is an error, display it */
1071  if (errstring && strlen(errstring)) {
1072  extern int scanerror;
1073  scanerror = 0;
1074  [errorController throwAlert:[NSString stringWithUTF8String:errstring]];
1075  free(errstring);
1076  errstring = NULL;
1077  }
1078  // refresh the prefs if necessary
1079  if ([thePrefPanel isVisible])
1080  [self displayPrefs:sender];
1081  [outputFormat2 selectCellWithTag:conf.output_format];
1082  if (retval)
1083  [self displayErrno:retval forFile:curFile];
1084  }
1085  }
1086 }
1087 
1088 - (void)displayErrno:(int)err forFile:(NSString*)filename
1089 {
1090  char * errstr;
1091  errstr = malloc(strlen(strerror(errno))+[filename length]+3);
1092  sprintf(errstr,"%s: %s",[filename UTF8String], strerror(errno));
1093  [errorController throwAlert:[NSString stringWithUTF8String:errstr]];
1094  free(errstr);
1095 }
1096 
1097 - (IBAction)saveAs:(id)sender
1098 {
1099  NSSavePanel *sp;
1100  int runResult;
1101  /* create or get the shared instance of NSSavePanel */
1102  sp = [NSSavePanel savePanel];
1103  /* set up new attributes */
1104  // [sp setAccessoryView:newView];
1105  [sp setRequiredFileType:@"txt"];
1106  /* display the NSSavePanel */
1107  runResult = [sp runModalForDirectory:nil file:@""];
1108  /* if successful, save file under designated name */
1109  if (runResult == NSOKButton) {
1110  curFile = [sp filename];
1111  [self save:sender];
1112  // if (![textData writeToFile:[sp filename] atomically:YES])
1113  // NSBeep();
1114  }
1115 }
1116 
1117 - (BOOL)validateMenuItem:(NSMenuItem *)anItem
1118 {
1119  switch ([anItem tag]) {
1120  case 1001: // save
1121  case 1002: // save as
1122  if (historyLength()) return YES;
1123  else return NO;
1124  break;
1125  default:
1126  return YES;
1127  }
1128 }
1129 
1130 - (IBAction)save:(id)sender
1131 {
1132  if (! curFile) {
1133  [self saveAs:sender];
1134  } else {
1135  int retval;
1136  retval = saveState(strdup([curFile UTF8String]));
1137  if (retval)
1138  [self displayErrno:retval forFile:curFile];
1139  }
1140 }
1141 
1142 - (IBAction)displayPrefs:(id)sender
1143 {
1144  switch (conf.engineering) {
1145  case automatic: [engineeringNotation selectItemAtIndex:0]; break;
1146  case never: [engineeringNotation selectItemAtIndex:1]; break;
1147  case always: [engineeringNotation selectItemAtIndex:2]; break;
1148  }
1149  [pickyVariables setState:(conf.picky_variables?NSOnState:NSOffState)];
1150  [historyDuplicates setState:(allow_duplicates?NSOnState:NSOffState)];
1151  [useRadians setState:(conf.use_radians?NSOnState:NSOffState)];
1152  [outputFormat selectCellWithTag:conf.output_format];
1153  [printPrefixes setState:(conf.print_prefixes?NSOnState:NSOffState)];
1154  [roundingIndication selectItemAtIndex:conf.rounding_indication];
1155  [rememberErrors setState:(conf.remember_errors?NSOnState:NSOffState)];
1156  [limitHistory setState:(conf.history_limit?NSOnState:NSOffState)];
1157  [printInts setState:(conf.print_ints?NSOnState:NSOffState)];
1158  [precisionGuard setState:(conf.precision_guard?NSOnState:NSOffState)];
1159  [simpleCalculator setState:(conf.simple_calc?NSOnState:NSOffState)];
1160  [printDelimiters setState:(conf.print_commas?NSOnState:NSOffState)];
1161  [bitsPref setIntValue:num_get_default_prec()];
1162  [bitsStepper setIntValue:num_get_default_prec()];
1163  [livePrecision setState:(conf.live_precision?NSOnState:NSOffState)];
1164  [cModPref setState:(conf.c_style_mod?NSOnState:NSOffState)];
1165  [sliderPref setIntValue:(int)[PrecisionSlider maxValue]];
1166  [sliderStepper setIntValue:(int)[PrecisionSlider maxValue]];
1167  [alternateInputPref setState:(conf.in_dec_delimiter != 0 || conf.in_thou_delimiter != 0)];
1168 
1169  /* disable irrelevant preferences */
1170  [historyDuplicates setEnabled:!conf.simple_calc];
1171  [limitHistory setEnabled:!conf.simple_calc];
1172  [pickyVariables setEnabled:!conf.simple_calc];
1173  [rememberErrors setEnabled:!conf.simple_calc];
1174  [updateHistory setEnabled:!conf.simple_calc];
1175  [useRadians setEnabled:!conf.simple_calc];
1176  [printPrefixes setEnabled:(conf.output_format!=DECIMAL_FORMAT)];
1177  [engineeringNotation setEnabled:(conf.output_format==DECIMAL_FORMAT)];
1178  [limitHistoryLen setEnabled:conf.history_limit&&!conf.simple_calc];
1179  [limitHistoryLenTag setEnabled:conf.history_limit&&!conf.simple_calc];
1180  [altInputDecSep setEnabled:[alternateInputPref state]];
1181  [altInputThouSep setEnabled:[alternateInputPref state]];
1182 
1183  [limitHistoryLen setStringValue:[NSString stringWithFormat:@"%lu",conf.history_limit_len]];
1184  if ([alternateInputPref state]) {
1185  [altInputDecSep setStringValue:[NSString stringWithFormat:@"%c",conf.in_dec_delimiter]];
1186  [altInputThouSep setStringValue:[NSString stringWithFormat:@"%c",conf.in_thou_delimiter]];
1187  }
1188 }
1189 
1190 - (IBAction)closeWindow:(id)sender
1191 {
1192  if ([inspectorWindow isKeyWindow]) {
1193  [inspectorWindow close];
1194  } else if ([persVarsWindow isKeyWindow]) {
1195  [persVarsWindow close];
1196  } else if ([mainWindow isKeyWindow]) {
1197  [mainWindow close];
1198  }
1199 }
1200 
1201 - (IBAction)quit:(id)sender
1202 {
1203  NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
1204 
1205  [prefs synchronize];
1206  clearHistory();
1207  cleanupvar();
1208  if (pretty_answer) {
1209  extern char *pa;
1211  if (pa) {
1212  free(pa);
1213  }
1214  }
1216  lists_cleanup();
1217  pthread_mutex_destroy(&displayLock);
1218  exit(EXIT_SUCCESS);
1219 }
1220 
1221 @end
WcalcController::conversionWindow
IBOutlet NSPanel * conversionWindow
Definition: WcalcController.h:68
_conf::history_limit_len
unsigned long history_limit_len
Definition: calculator.h:123
-[InspectorController openIt:]
IBAction openIt:(id sender)
Definition: InspectorController.m:10
_conf::picky_variables
unsigned int picky_variables
Definition: calculator.h:130
_conf::precision_guard
unsigned int precision_guard
Definition: calculator.h:136
_conf::engineering
enum engineering_modes engineering
Definition: calculator.h:129
_conf::c_style_mod
unsigned int c_style_mod
Definition: calculator.h:144
WcalcController::convertTo
IBOutlet NSTableView * convertTo
Definition: WcalcController.h:76
MyTextField.h
WcalcController::bitsStepper
IBOutlet NSStepper * bitsStepper
Definition: WcalcController.h:54
WcalcController::errorController
IBOutlet id errorController
Definition: WcalcController.h:62
uber_conversion
void uber_conversion(Number output, const int utype, const int fromunit, const int tounit, Number value)
Definition: conversion.c:1024
putexp
int putexp(const char *key, const char *value, const char *desc)
Definition: variables.c:244
WcalcController::rememberErrors
IBOutlet NSButton * rememberErrors
Definition: WcalcController.h:32
WcalcController::precisionGuard
IBOutlet NSButton * precisionGuard
Definition: WcalcController.h:35
WcalcController::historyList
IBOutlet id historyList
Definition: WcalcController.h:63
simpleClearEntry
void simpleClearEntry()
Definition: simpleCalc.c:127
WcalcController::theKeyboard
IBOutlet id theKeyboard
Definition: WcalcController.h:64
WcalcController::AnswerField
IBOutlet NSTextField * AnswerField
Definition: WcalcController.h:43
WcalcController::thePrefPanel
IBOutlet NSPanel * thePrefPanel
Definition: WcalcController.h:67
conf
struct _conf conf
Definition: calculator.c:111
curFile
static NSString * curFile
Definition: WcalcController.m:25
string_manip.h
_conf::simple_calc
unsigned int simple_calc
Definition: calculator.h:140
calculator.h
_conf::use_radians
unsigned int use_radians
Definition: calculator.h:131
pa
char * pa
Definition: calculator.c:108
WcalcController::shiftKey2
IBOutlet NSButton * shiftKey2
Definition: WcalcController.h:24
WcalcController::superview
NSView * superview
Definition: WcalcController.h:81
simpleClearAll
void simpleClearAll()
Definition: simpleCalc.c:147
_conf::history_limit
unsigned int history_limit
Definition: calculator.h:137
_conf::print_prefixes
unsigned int print_prefixes
Definition: calculator.h:133
free
void free(void *)
_conf::print_ints
unsigned int print_ints
Definition: calculator.h:139
WcalcController::decimalKey
IBOutlet NSButton * decimalKey
Definition: WcalcController.h:31
WcalcController::useRadians
IBOutlet NSButton * useRadians
Definition: WcalcController.h:28
WcalcController::printDelimiters
IBOutlet NSButton * printDelimiters
Definition: WcalcController.h:38
WcalcController::engineeringNotation
IBOutlet NSPopUpButton * engineeringNotation
Definition: WcalcController.h:70
WcalcController::altInputDecSep
IBOutlet NSTextField * altInputDecSep
Definition: WcalcController.h:49
FIELD_WIDTH_DIFFERENCE
#define FIELD_WIDTH_DIFFERENCE
Definition: WcalcController.m:19
parseme
void parseme(const char *pthis)
Definition: calculator.c:130
variables.h
WcalcController.h
recalculate
short recalculate
Definition: historyManager.c:40
num_init_set_ui
void num_init_set_ui(Number n, const unsigned int ui)
Definition: number.c:89
WcalcController::variableList
IBOutlet NSTableView * variableList
Definition: WcalcController.h:74
-[WcalcController save:]
IBAction save:(id sender)
Definition: WcalcController.m:1130
WcalcController::limitHistoryLen
IBOutlet NSTextField * limitHistoryLen
Definition: WcalcController.h:45
WcalcController::outputFormat2
IBOutlet NSMatrix * outputFormat2
Definition: WcalcController.h:58
MIN_WINDOW_HEIGHT_TOGGLED
#define MIN_WINDOW_HEIGHT_TOGGLED
Definition: WcalcController.m:17
WcalcController::baseDrawer
IBOutlet NSDrawer * baseDrawer
Definition: WcalcController.h:52
WcalcController::simpleCalculator
IBOutlet NSButton * simpleCalculator
Definition: WcalcController.h:37
errstring
char * errstring
Definition: parser.c:111
WcalcController::updateHistory
IBOutlet NSButton * updateHistory
Definition: WcalcController.h:29
_conf::in_dec_delimiter
char in_dec_delimiter
Definition: calculator.h:128
KEYPAD_HEIGHT
#define KEYPAD_HEIGHT
Definition: WcalcController.m:15
WcalcController::inspectorWindow
IBOutlet NSWindow * inspectorWindow
Definition: WcalcController.h:18
WcalcController::shiftKey1
IBOutlet NSButton * shiftKey1
Definition: WcalcController.h:23
-[WcalcController saveAs:]
IBAction saveAs:(id sender)
Definition: WcalcController.m:1097
MAX_TYPE
#define MAX_TYPE
Definition: conversion.h:40
WcalcController::limitHistory
IBOutlet NSButton * limitHistory
Definition: WcalcController.h:34
-[WcalcController displayPrefs:]
IBAction displayPrefs:(id sender)
Definition: WcalcController.m:1142
cleanupvar
void cleanupvar(void)
Definition: variables.c:34
set_prettyanswer
void set_prettyanswer(const Number num)
Definition: calculator.c:592
_conf::print_commas
unsigned int print_commas
Definition: calculator.h:142
MAX_WINDOW_SIZE
#define MAX_WINDOW_SIZE
Definition: WcalcController.m:20
_conf::rounding_indication
unsigned int rounding_indication
Definition: calculator.h:134
WcalcController::sliderStepper
IBOutlet NSStepper * sliderStepper
Definition: WcalcController.h:55
Dprintf
#define Dprintf(...)
Definition: calculator.h:23
init_numbers
void init_numbers(void)
Definition: number.c:26
loadState
int loadState(const char *filename, const int into_history)
Definition: files.c:261
_conf::dec_delimiter
char dec_delimiter
Definition: calculator.h:126
-[WcalcController displayErrno:forFile:]
void displayErrno:forFile:(int err, [forFile] NSString *filename)
Definition: WcalcController.m:1088
_conf::in_thou_delimiter
char in_thou_delimiter
Definition: calculator.h:127
update_history
static char update_history
Definition: WcalcController.m:22
WcalcController::persVarsWindow
IBOutlet NSWindow * persVarsWindow
Definition: WcalcController.h:19
WcalcController::convertType
IBOutlet NSPopUpButton * convertType
Definition: WcalcController.h:72
WcalcController::alternateInputPref
IBOutlet NSButton * alternateInputPref
Definition: WcalcController.h:41
malloc
void * malloc(size_t)
ErrorController.h
WcalcController::cModPref
IBOutlet NSButton * cModPref
Definition: WcalcController.h:40
e
NSButton * e
Definition: WcalcController.m:23
WcalcController::inspector
IBOutlet InspectorController * inspector
Definition: WcalcController.h:20
-[WcalcController displayAnswer]
void displayAnswer()
Definition: WcalcController.m:501
WcalcController::just_answered
bool just_answered
Definition: WcalcController.h:80
last_answer
Number last_answer
Definition: calculator.c:98
num_free
void num_free(Number n)
Definition: number.c:738
WcalcController::sizeToggleMenu
IBOutlet NSMenuItem * sizeToggleMenu
Definition: WcalcController.h:14
conversion.h
historyLength
size_t historyLength(void)
Definition: historyManager.c:189
scanerror
short scanerror
Definition: parser.c:110
WcalcController::keypad
IBOutlet id keypad
Definition: WcalcController.h:65
never
Definition: calculator.h:102
WcalcController::limitHistoryLenTag
IBOutlet NSTextField * limitHistoryLenTag
Definition: WcalcController.h:46
WcalcController::enterKey
IBOutlet NSButton * enterKey
Definition: WcalcController.h:33
simpleCalc.h
WcalcController::convertFrom
IBOutlet NSTableView * convertFrom
Definition: WcalcController.h:75
WcalcController::historyDuplicates
IBOutlet NSButton * historyDuplicates
Definition: WcalcController.h:25
ef
NSTextField * ef
Definition: WcalcController.m:24
MIN_WINDOW_HEIGHT_UNTOGGLED
#define MIN_WINDOW_HEIGHT_UNTOGGLED
Definition: WcalcController.m:18
pretty_answer
char * pretty_answer
Definition: calculator.c:99
saveState
int saveState(char *filename)
Definition: files.c:91
simpleCalc
char * simpleCalc(const unsigned char input, const char *expStr)
Definition: simpleCalc.c:39
_conf::live_precision
unsigned int live_precision
Definition: calculator.h:143
WcalcController::printPrefixes
IBOutlet NSButton * printPrefixes
Definition: WcalcController.h:27
WcalcController::livePrecision
IBOutlet NSButton * livePrecision
Definition: WcalcController.h:39
lists_cleanup
void lists_cleanup(void)
Definition: list.c:59
-[WcalcController go:]
IBAction go:(id sender)
Definition: WcalcController.m:482
MIN_WINDOW_WIDTH
#define MIN_WINDOW_WIDTH
Definition: WcalcController.m:16
automatic
Definition: calculator.h:102
WcalcController::bitsPref
IBOutlet NSTextField * bitsPref
Definition: WcalcController.h:47
WcalcController::mainWindow
IBOutlet NSWindow * mainWindow
Definition: WcalcController.h:17
WcalcController::pickyVariables
IBOutlet NSButton * pickyVariables
Definition: WcalcController.h:26
num_get_default_prec
num_prec_t num_get_default_prec()
Definition: number.c:479
addToHistory
void addToHistory(char *expression, Number answer)
Definition: historyManager.c:71
clearHistory
void clearHistory()
Definition: historyManager.c:57
_conf::precision
int precision
Definition: calculator.h:124
WcalcController::printInts
IBOutlet NSButton * printInts
Definition: WcalcController.h:36
num_set_default_prec
#define num_set_default_prec(prec)
Definition: number.h:133
displayLock
static pthread_mutex_t displayLock
Definition: WcalcController.m:26
_conf::thou_delimiter
char thou_delimiter
Definition: calculator.h:125
WcalcController::sliderPref
IBOutlet NSTextField * sliderPref
Definition: WcalcController.h:48
files.h
_conf::output_format
unsigned int output_format
Definition: calculator.h:132
WcalcController::PrecisionSlider
IBOutlet NSSlider * PrecisionSlider
Definition: WcalcController.h:60
WcalcController::baseMenu
IBOutlet NSMenuItem * baseMenu
Definition: WcalcController.h:11
WcalcController
Definition: WcalcController.h:8
list.h
WcalcController::roundingIndication
IBOutlet NSPopUpButton * roundingIndication
Definition: WcalcController.h:71
allow_duplicates
short allow_duplicates
Definition: historyManager.c:39
historyManager.h
WcalcController::outputFormat
IBOutlet NSMatrix * outputFormat
Definition: WcalcController.h:57
number.h
WcalcController::ExpressionField
IBOutlet NSTextField * ExpressionField
Definition: WcalcController.h:44
putval
int putval(const char *key, const mpfr_t value, const char *desc)
always
Definition: calculator.h:102
WcalcController::altInputThouSep
IBOutlet NSTextField * altInputThouSep
Definition: WcalcController.h:50
_conf::remember_errors
unsigned int remember_errors
Definition: calculator.h:135