source: trunk/src/org/expeditee/actions/Misc.java@ 190

Last change on this file since 190 was 190, checked in by ra33, 16 years ago

Added some math stuff... able to group numbers inside a rectangle

File size: 21.6 KB
RevLine 
[4]1package org.expeditee.actions;
2
3import java.awt.Color;
[78]4import java.awt.Image;
[4]5import java.awt.image.BufferedImage;
[78]6import java.awt.image.VolatileImage;
[4]7import java.io.File;
8import java.io.FileNotFoundException;
9import java.io.IOException;
[72]10import java.lang.reflect.Method;
[70]11import java.util.ArrayList;
[108]12import java.util.Collection;
[4]13import java.util.List;
14
15import javax.imageio.ImageIO;
16
17import org.expeditee.gui.DisplayIO;
18import org.expeditee.gui.Frame;
19import org.expeditee.gui.FrameGraphics;
20import org.expeditee.gui.FrameIO;
21import org.expeditee.gui.FrameMouseActions;
[121]22import org.expeditee.gui.MessageBay;
[72]23import org.expeditee.gui.TimeKeeper;
[4]24import org.expeditee.items.Item;
[162]25import org.expeditee.items.ItemUtils;
[4]26import org.expeditee.items.Text;
[190]27import org.expeditee.math.ExpediteeJEP;
[90]28import org.expeditee.stats.CometStats;
[4]29import org.expeditee.stats.SessionStats;
30import org.expeditee.stats.StatsLogger;
[90]31import org.expeditee.stats.TreeStats;
[156]32import org.nfunk.jep.Node;
[190]33import org.nfunk.jep.ParseException;
[4]34
35/**
[105]36 * A list of miscellaneous Actions and Actions specific to Expeditee
[4]37 *
38 */
39public class Misc {
40 /**
41 * Causes the system to beep
42 */
[181]43 public static void beep() {
[4]44 java.awt.Toolkit.getDefaultToolkit().beep();
45 }
46
47 /**
48 * Forces a repaint of the current Frame
49 */
[181]50 public static void display() {
51 FrameGraphics.refresh(false);
[4]52 }
53
54 /**
55 * Restores the current frame to the last saved version currently on the
56 * hard disk
57 */
[181]58 public static void restore() {
[4]59 FrameIO.Reload();
[121]60 // MessageBay.displayMessage("Restoration complete.");
[4]61 }
62
63 /**
64 * Toggles AudienceMode on or off
65 */
[181]66 public static void toggleAudienceMode() {
[4]67 FrameGraphics.ToggleAudienceMode();
68 }
69
70 /**
71 * Toggles TwinFrames mode on or off
72 */
[181]73 public static void toggleTwinFramesMode() {
[4]74 DisplayIO.ToggleTwinFrames();
75 }
76
77 /**
78 * If the given Item is a Text Item, then the text of the Item is
79 * interpreted as actions, if not this method does nothing.
80 *
81 * @param current
82 * The Item to read the Actions from
83 */
[181]84 public static void runItem(Item current) throws Exception {
[4]85 if (current instanceof Text) {
[80]86 List<String> actions = ((Text) current).getTextList();
[4]87 for (String action : actions) {
[181]88 if (!action.equalsIgnoreCase("runitem")) {
[160]89 Actions.PerformAction(DisplayIO.getCurrentFrame(), current,
90 action);
91 }
[4]92 }
[156]93 } else {
94 MessageBay.errorMessage("Item must be a text item.");
[4]95 }
96 }
97
98 /**
99 * Prompts the user to confirm deletion of the current Frame, and deletes if
100 * the user chooses. After deletion this action calls back(), to ensure the
101 * deleted frame is not still being shown
102 *
103 */
104 public static void DeleteFrame() {
105 Frame toDelete = DisplayIO.getCurrentFrame();
[80]106 String deletedFrame = toDelete.getName();
[7]107 String deletedFrameNameLowercase = deletedFrame.toLowerCase();
[97]108 String errorMessage = "Error deleting " + deletedFrame;
[4]109 try {
[154]110 String deletedFrameName = FrameIO.DeleteFrame(toDelete);
111 if (deletedFrameName != null) {
112 DisplayIO.Back();
[156]113 // Remove any links on the previous frame to the one being
114 // deleted
[4]115 Frame current = DisplayIO.getCurrentFrame();
116 for (Item i : current.getItems())
117 if (i.getLink() != null
[7]118 && i.getAbsoluteLink().toLowerCase().equals(
119 deletedFrameNameLowercase)) {
[4]120 i.setLink(null);
121 }
[154]122 MessageBay.displayMessage(deletedFrame + " renamed "
123 + deletedFrameName);
[156]124 // FrameGraphics.Repaint();
[97]125 return;
[4]126 }
[115]127 } catch (IOException ioe) {
128 if (ioe.getMessage() != null)
129 errorMessage += ". " + ioe.getMessage();
[97]130 } catch (SecurityException se) {
[115]131 if (se.getMessage() != null)
132 errorMessage += ". " + se.getMessage();
[97]133 } catch (Exception e) {
134 e.printStackTrace();
[4]135 }
[121]136 MessageBay.errorMessage(errorMessage);
[4]137 }
138
139 /**
140 * Loads the Frame linked to by the given Item. The first Item on the Frame
141 * that is not the title or name is then placed on the cursor. If the given
142 * Item has no link, or no item is found then this is a no-op.
143 *
144 * @param current
145 * The Item that links to the Frame that the Item will be loaded
146 * from.
147 */
[181]148 public static Item GetItemFromChildFrame(Item current) {
149 return getFromChildFrame(current, false);
[70]150 }
[163]151
[162]152 public static void GetItemsFromChildFrame(Item current) {
153 getItemsFromChildFrame(current, false);
154 }
[72]155
[70]156 /**
[72]157 * Loads the Frame linked to by the given Item. The first Text Item on the
158 * Frame that is not the title or name is then placed on the cursor. If the
159 * given Item has no link, or no item is found then this is a no-op.
[70]160 *
161 * @param current
162 * The Item that links to the Frame that the Item will be loaded
163 * from.
164 */
[181]165 public static Item GetTextFromChildFrame(Item current) {
166 return getFromChildFrame(current, true);
[70]167 }
[72]168
[181]169 private static Item getFromChildFrame(Item current, boolean textOnly) {
[70]170 Item item = getFirstBodyItemOnChildFrame(current, textOnly);
[4]171 // if no item was found
[181]172 if (item != null) {
173 // copy the item and switch
174 item = item.copy();
175 item.setPosition(DisplayIO.getMouseX(), FrameMouseActions.getY());
[4]176 }
[181]177 return item;
[4]178 }
[163]179
[162]180 private static void getItemsFromChildFrame(Item current, boolean textOnly) {
181 Collection<Item> items = getItemsOnChildFrame(current, textOnly);
182 // if no item was found
183 if (items == null || items.size() == 0) {
184 return;
185 }
[4]186
[162]187 // copy the item and switch
188 Collection<Item> copies = ItemUtils.CopyItems(items);
[163]189 Item first = items.iterator().next();
190 float deltaX = DisplayIO.getMouseX() - first.getX();
191 float deltaY = FrameMouseActions.getY() - first.getY();
192 for (Item i : copies) {
193 if (i.isVisible())
194 i.setXY(i.getX() + deltaX, i.getY() + deltaY);
[162]195 i.setParent(null);
196 }
197 FrameMouseActions.pickup(copies);
198 FrameGraphics.Repaint();
199 }
200
[4]201 /**
202 * Sets the given Item to have the Given Color. Color can be null (for
203 * default)
204 *
205 * @param toChange
206 * The Item to set the Color.
207 * @param toUse
208 * The Color to give the Item.
209 */
[181]210 public static void SetItemBackgroundColor(Item toChange, Color toUse) {
[4]211 if (toChange == null)
212 return;
213
214 toChange.setBackgroundColor(toUse);
215 FrameGraphics.Repaint();
216 }
217
218 /**
219 * Sets the given Item to have the Given Color. Color can be null (for
220 * default)
221 *
222 * @param toChange
223 * The Item to set the Color.
224 * @param toUse
225 * The Color to give the Item.
226 */
[181]227 public static void SetItemColor(Item toChange, Color toUse) {
[4]228 if (toChange == null)
229 return;
230
231 toChange.setColor(toUse);
232 FrameGraphics.Repaint();
233 }
234
235 /**
[70]236 * Creates a new Text Object containing general statistics for the current
237 * session. The newly created Text Object is then attached to the cursor via
238 * FrameMouseActions.pickup(Item)
[4]239 */
[21]240 public static void GetSessionStats() {
[115]241 attachStatsToCursor(SessionStats.getCurrentStats());
[70]242 }
[4]243
[86]244 /**
245 * Creates a new Text Object containing statistics for the current tree.
246 */
[181]247 public static String GetCometStats(Frame frame) {
[90]248 TimeKeeper timer = new TimeKeeper();
[121]249 MessageBay.displayMessage("Computing comet stats...");
[105]250 CometStats cometStats = new CometStats(frame);
[181]251 String result = cometStats.toString();
[121]252 MessageBay.overwriteMessage("Comet stats time: "
[90]253 + timer.getElapsedStringSeconds());
[181]254 return result;
[90]255 }
[86]256
[181]257 public static String GetTreeStats(Frame frame) {
[90]258 TimeKeeper timer = new TimeKeeper();
[121]259 MessageBay.displayMessage("Computing tree stats...");
[90]260
[105]261 TreeStats treeStats = new TreeStats(frame);
[181]262 String result = treeStats.toString();
[121]263 MessageBay.overwriteMessage("Tree stats time: "
[90]264 + timer.getElapsedStringSeconds());
[181]265 return result;
266
[86]267 }
268
[115]269 /**
270 * Creates a text item and attaches it to the cursor.
271 *
272 * @param itemText
273 * the text to attach to the cursor
274 */
275 public static void attachStatsToCursor(String itemText) {
[72]276 SessionStats.CreatedText();
277 Frame current = DisplayIO.getCurrentFrame();
[78]278 Item text = current.getStatsTextItem(itemText);
[4]279 FrameMouseActions.pickup(text);
280 FrameGraphics.Repaint();
281 }
282
[115]283 public static void attachTextToCursor(String itemText) {
284 SessionStats.CreatedText();
285 Frame current = DisplayIO.getCurrentFrame();
286 Item text = current.getTextItem(itemText);
287 FrameMouseActions.pickup(text);
288 FrameGraphics.Repaint();
289 }
290
[4]291 /**
[70]292 * Creates a new Text Object containing statistics for moving, deleting and
293 * creating items in the current session. The newly created Text Object is
294 * then attached to the cursor via FrameMouseActions.pickup(Item)
295 */
[181]296 public static String getItemStats() {
297 return SessionStats.getItemStats();
[70]298 }
299
300 /**
301 * Creates a new Text Object containing statistics for the time between
302 * events triggered by the user through mouse clicks and key presses. The
303 * newly created Text Object is then attached to the cursor via
304 * FrameMouseActions.pickup(Item)
305 */
[181]306 public static String getEventStats() {
307 return SessionStats.getEventStats();
[70]308 }
309
310 /**
[4]311 * Creates a new Text Object containing the contents of the current frames
312 * file.
313 */
[181]314 public static String getFrameFile(Frame frame) {
315 return FrameIO.ForceSaveFrame(frame);
[4]316 }
[7]317
[4]318 /**
319 * Creates a new Text Object containing the available fonts.
320 */
[181]321 public static String getFontNames() {
[115]322 Collection<String> availableFonts = Actions.getFonts().values();
[4]323 StringBuilder fontsList = new StringBuilder();
[7]324 for (String s : availableFonts) {
[115]325 fontsList.append(s).append(Text.LINE_SEPARATOR);
[4]326 }
[115]327 fontsList.deleteCharAt(fontsList.length() - 1);
[7]328
[181]329 return fontsList.toString();
[115]330 }
[4]331
[181]332 public static String getUnicodeCharacters(int start, int finish) {
[154]333 if (start < 0 && finish < 0) {
[115]334 throw new RuntimeException("Parameters must be non negative");
335 }
[154]336 // Swap the start and finish if they are inthe wrong order
337 if (start > finish) {
[115]338 start += finish;
[154]339 finish = start - finish;
[115]340 start = start - finish;
341 }
342 StringBuilder charList = new StringBuilder();
343 int count = 0;
[154]344 charList.append(String.format("Unicode block 0x%x - 0x%x", start,
345 finish));
[115]346 System.out.println();
[154]347 // charList.append("Unicode block: ").append(String.format(format,
348 // args))
349 for (char i = (char) start; i < (char) finish; i++) {
[115]350 if (Character.isDefined(i)) {
[154]351 if (count++ % 64 == 0)
[115]352 charList.append(Text.LINE_SEPARATOR);
353 charList.append(Character.valueOf(i));
354 }
355 }
[181]356 return charList.toString();
[4]357 }
[154]358
[115]359 /**
360 * Gets a single block of Unicode characters.
[154]361 *
362 * @param start
363 * the start of the block
[115]364 */
[181]365 public static String getUnicodeCharacters(int start) {
366 return getUnicodeCharacters(start, start + 256);
[115]367 }
[154]368
[181]369 public static String getMathSymbols() {
370 return getUnicodeCharacters('\u2200', '\u2300');
[115]371 }
[4]372
373 /**
374 * Resets the statistics back to zero.
375 */
[181]376 public static void repaint() {
[4]377 StatsLogger.WriteStatsFile();
378 SessionStats.resetStats();
379 }
380
381 /**
382 * Loads a frame with the given name and saves it as a JPEG image.
383 *
384 * @param framename
385 * The name of the Frame to save
386 */
[181]387 public static void jpegFrame(String framename) {
[80]388 ImageFrame(framename, "JPEG");
[4]389 }
390
391 /**
392 * Saves the current frame as a JPEG image. This is the same as calling
[80]393 * JpegFrame(currentFrame.getName())
[4]394 */
[181]395 public static void jpegFrame() {
[80]396 ImageFrame(DisplayIO.getCurrentFrame().getName(), "JPEG");
[4]397 }
398
[181]399 public static void jpgFrame() {
400 jpegFrame();
[80]401 }
402
[4]403 /**
404 * Loads a frame with the given name and saves it as a PNG image.
405 *
406 * @param framename
407 * The name of the Frame to save
408 */
409 public static void PNGFrame(String framename) {
410 ImageFrame(framename, "PNG");
411 }
412
413 /**
414 * Saves the current frame as a PNG image. This is the same as calling
[80]415 * PNGFrame(currentFrame.getName())
[4]416 */
417 public static void PNGFrame() {
[80]418 ImageFrame(DisplayIO.getCurrentFrame().getName(), "PNG");
[4]419 }
420
[86]421 public static String SaveImage(BufferedImage screen, String format,
422 String directory, String fileName) {
[80]423 // Check if we need to append the suffix
424 if (fileName.indexOf('.') < 0)
[86]425 fileName += "." + format.toLowerCase();
[80]426
427 try {
428 // set up the file for output
429 String fullFileName = directory + fileName;
430 File out = new File(fullFileName);
431 if (!out.getParentFile().exists())
432 out.mkdirs();
433
434 // If the image is successfully written out return the fileName
435 if (ImageIO.write(screen, format, out))
436 return fileName;
437
438 } catch (Exception e) {
439 e.printStackTrace();
440 }
441 return null;
442 }
[86]443
[80]444 public static String ImageFrame(Frame frame, String format, String directory) {
445 assert (frame != null);
[86]446
[181]447 Image oldBuffer = frame.getBuffer();
448 frame.setBuffer(null);
449 // Jpeg only works properly with volitile frames
450 // Png transparency only works with bufferedImage form
451 Image frameBuffer = FrameGraphics.getBuffer(frame, false, format
452 .equalsIgnoreCase("jpeg"));
453 // Make sure overlay stuff doesnt disapear on the frame visible on the
454 // screen
455 frame.setBuffer(oldBuffer);
456 BufferedImage screen = null;
[80]457
[181]458 if (frameBuffer instanceof VolatileImage) {
459 // If its the current frame it will be a volitive image
[80]460 screen = ((VolatileImage) frameBuffer).getSnapshot();
461 } else {
[181]462 assert (frameBuffer instanceof BufferedImage);
463 screen = (BufferedImage) frameBuffer;
[80]464 }
465 return SaveImage(screen, format, directory, frame.getExportFileName());
466 }
467
[4]468 /**
469 * Saves the Frame with the given Framename as an image of the given format.
470 *
471 * @param framename
472 * The name of the Frame to save as an image
473 * @param format
474 * The Image format to use (i.e. "PNG", "BMP", etc)
475 */
476 public static void ImageFrame(String framename, String format) {
477 Frame loaded = FrameIO.LoadFrame(framename);
478
479 // if the frame was loaded successfully
480 if (loaded != null) {
[80]481 String path = FrameIO.IMAGES_PATH;
482 String frameName = ImageFrame(loaded, format, path);
483 if (frameName != null)
[154]484 MessageBay.displayMessage("Frame successfully saved to " + path
485 + frameName);
[80]486 else
[121]487 MessageBay.errorMessage("Could not find image writer for "
[80]488 + format + " format");
[4]489 // if the frame was not loaded successfully, alert the user
[181]490 } else {
[121]491 MessageBay.displayMessage("Frame '" + framename
[4]492 + "' could not be found.");
[181]493 }
[4]494 }
495
496 /**
497 * Displays a message in the message box area.
498 *
499 * @param message
500 * the message to display
501 */
502 public static void MessageLn(String message) {
[121]503 MessageBay.displayMessage(message);
[4]504 }
505
506 public static void MessageLn2(String message, String message2) {
[121]507 MessageBay.displayMessage(message + " " + message2);
[4]508 }
509
510 public static void CopyFile(String existingFile, String newFileName) {
511 try {
[7]512 // TODO is there a built in method which will do this faster?
513
[154]514 MessageBay.displayMessage("Copying file " + existingFile + " to "
515 + newFileName + "...");
[7]516 FrameIO.copyFile(existingFile, newFileName);
[121]517 MessageBay.displayMessage("File copied successfully");
[4]518 } catch (FileNotFoundException e) {
[121]519 MessageBay.displayMessage("Error opening file: " + existingFile);
[7]520 } catch (Exception e) {
[121]521 MessageBay.displayMessage("File could not be copied");
[4]522 }
523 }
524
525 /**
[72]526 * Runs two methods alternatively a specified number of times and reports on
527 * the time spent running each method.
528 *
529 * @param fullMethodNameA
530 * @param fullMethodNameB
531 * @param repsPerTest
532 * the number of time each method is run per test
533 * @param tests
534 * the number of tests to conduct
535 *
536 */
537 public static void CompareMethods(String fullMethodNameA,
538 String fullMethodNameB, int repsPerTest, int tests) {
539 try {
540 String classNameA = getClassName(fullMethodNameA);
541 String classNameB = getClassName(fullMethodNameB);
542 String methodNameA = getMethodName(fullMethodNameA);
543 String methodNameB = getMethodName(fullMethodNameB);
544
[176]545 Class<?> classA = Class.forName(classNameA);
546 Class<?> classB = Class.forName(classNameB);
[72]547 Method methodA = classA.getDeclaredMethod(methodNameA,
548 new Class[] {});
549 Method methodB = classB.getDeclaredMethod(methodNameB,
550 new Class[] {});
551 TimeKeeper timeKeeper = new TimeKeeper();
552 long timeA = 0;
553 long timeB = 0;
554 // Run the tests
555 for (int i = 0; i < tests; i++) {
556 // Test methodA
557 timeKeeper.restart();
558 for (int j = 0; j < repsPerTest; j++) {
[80]559 methodA.invoke((Object) null, new Object[] {});
[72]560 }
561 timeA += timeKeeper.getElapsedMillis();
562 timeKeeper.restart();
563 // Test methodB
564 for (int j = 0; j < repsPerTest; j++) {
[80]565 methodB.invoke((Object) null, new Object[] {});
[72]566 }
567 timeB += timeKeeper.getElapsedMillis();
568 }
569
570 float aveTimeA = timeA * 1000F / repsPerTest / tests;
571 float aveTimeB = timeB * 1000F / repsPerTest / tests;
572 // Display Results
[121]573 MessageBay.displayMessage("Average Execution Time");
574 MessageBay.displayMessage(methodNameA + ": "
[72]575 + TimeKeeper.Formatter.format(aveTimeA) + "us");
[121]576 MessageBay.displayMessage(methodNameB + ": "
[72]577 + TimeKeeper.Formatter.format(aveTimeB) + "us");
578 } catch (Exception e) {
[121]579 MessageBay.errorMessage(e.getClass().getSimpleName() + ": "
[72]580 + e.getMessage());
581 }
582 }
583
584 public static String getClassName(String fullMethodName) {
585 assert (fullMethodName != null);
586 assert (fullMethodName.length() > 0);
587 int lastPeriod = fullMethodName.lastIndexOf('.');
588 if (lastPeriod > 0 && lastPeriod < fullMethodName.length() - 1)
589 return fullMethodName.substring(0, lastPeriod);
590 throw new RuntimeException("Invalid method name: " + fullMethodName);
591 }
592
593 public static String getMethodName(String methodName) {
594 assert (methodName != null);
595 assert (methodName.length() > 0);
596 int lastPeriod = methodName.lastIndexOf('.');
597 if (lastPeriod > 0 && lastPeriod < methodName.length() - 1)
598 return methodName.substring(1 + lastPeriod);
599 throw new RuntimeException("Invalid method name: " + methodName);
600 }
601
602 /**
[4]603 * Loads the Frame linked to by the given Item. The first Item on the Frame
604 * that is not the title or name is then placed on the current frame. The
605 * item that was clicked on is placed on the frame it was linked to and the
606 * link is switched to the item from the child frame. If the given Item has
607 * no link, or no item is found then this is a no-op.
608 *
609 * @param current
610 * The Item that links to the Frame that the Item will be loaded
611 * from.
612 */
613 public static void SwapItemWithItemOnChildFrame(Item current) {
[70]614 Item item = getFirstBodyItemOnChildFrame(current, false);
[4]615 // if no item was found
616 if (item == null) {
617 return;
618 }
619
620 // swap the items parents
621 Frame parentFrame = current.getParent();
622 Frame childFrame = item.getParent();
623 current.setParent(childFrame);
624 item.setParent(parentFrame);
625
626 // swap the items on the frames
627 parentFrame.removeItem(current);
628 childFrame.removeItem(item);
629 parentFrame.addItem(item);
630 childFrame.addItem(current);
631
632 // swap the items links
[74]633 item.setActions(current.getAction());
[80]634 item.setLink(childFrame.getName());
635 current.setLink(parentFrame.getName());
[4]636 // current.setLink(null);
[74]637 current.setActions(null);
[4]638
639 FrameGraphics.Repaint();
640 }
641
[72]642 private static Item getFirstBodyItemOnChildFrame(Item current,
643 boolean textOnly) {
[4]644 // the item must link to a frame
645 if (current.getLink() == null) {
[121]646 MessageBay
647 .displayMessage("Cannot get item from child - this item has no link");
[4]648 return null;
649 }
650
651 Frame child = FrameIO.LoadFrame(current.getAbsoluteLink());
652
653 // if the frame could not be loaded
654 if (child == null) {
[121]655 MessageBay.errorMessage("Could not load child frame.");
[4]656 return null;
657 }
658
659 // find the first non-title and non-name item
[70]660 List<Item> body = new ArrayList<Item>();
[72]661 if (textOnly)
[70]662 body.addAll(child.getBodyTextItems(false));
663 else
664 body.addAll(child.getItems());
[4]665 Item item = null;
666
667 for (Item i : body)
[80]668 if (i != child.getTitleItem() && !i.isAnnotation()) {
[4]669 item = i;
670 break;
671 }
672
673 // if no item was found
674 if (item == null) {
[121]675 MessageBay.displayMessage("No item found to copy");
[4]676 return null;
677 }
678
679 return item;
680 }
[163]681
[162]682 private static Collection<Item> getItemsOnChildFrame(Item current,
683 boolean textOnly) {
684 // the item must link to a frame
685 if (current.getLink() == null) {
686 MessageBay
687 .displayMessage("Cannot get item from child - this item has no link");
688 return null;
689 }
690 Frame child = FrameIO.LoadFrame(current.getAbsoluteLink());
[156]691
[162]692 // if the frame could not be loaded
693 if (child == null) {
694 MessageBay.errorMessage("Could not load child frame.");
695 return null;
696 }
697
698 // find the first non-title and non-name item
699 Collection<Item> body = new ArrayList<Item>();
700 if (textOnly)
701 body.addAll(child.getBodyTextItems(false));
702 else
703 body.addAll(child.getItems());
[163]704
[162]705 return body;
706 }
707
[156]708 public static void calculate(Frame frame, Item toCalculate) {
709 if (toCalculate instanceof Text) {
710 Text text = (Text) toCalculate;
[161]711 ExpediteeJEP myParser = new ExpediteeJEP();
712 myParser.addVariables(frame);
713 String linkedFrame = toCalculate.getAbsoluteLink();
714 if (linkedFrame != null) {
715 myParser.addVariables(FrameIO.LoadFrame(linkedFrame));
[156]716 }
[162]717 myParser.resetObserver();
[160]718
[156]719 // Do the calculation
[190]720 String formulaFullCase = text.getText().replace('\n', ' ');
721 String formula = formulaFullCase.toLowerCase();
722
723 try {
724 Node node = myParser.parse(formula);
725 Object result = myParser.evaluate(node);
726 text.setText(result.toString());
727 text.setFormula(formulaFullCase);
728 if (text.isFloating()) {
729 text.setPosition(FrameMouseActions.MouseX,
730 FrameMouseActions.MouseY);
731 FrameMouseActions.resetOffset();
[161]732 } else {
[190]733 text.getParentOrCurrentFrame().change();
[156]734 }
[190]735 } catch (ParseException e) {
736 MessageBay.errorMessage("Parse error "
737 + e.getMessage().replace("\n", ""));
738 } catch (Exception e) {
739 MessageBay.errorMessage("evaluation error "
740 + e.getMessage().replace("\n", ""));
741 e.printStackTrace();
[156]742 }
743 }
744 }
[181]745
746 /**
747 * Attach an item to the cursor.
748 *
749 * @param item
750 */
751 public static void attachToCursor(Item item) {
752 item.setParent(null);
753 FrameMouseActions.pickup(item);
754 FrameGraphics.Repaint();
755 }
[4]756}
Note: See TracBrowser for help on using the repository browser.