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

Last change on this file since 514 was 514, checked in by csl14, 11 years ago

Added startBrowser and startBrowserNewFrame actions - creates lobo browser widget and navigates to url supplied by text item

File size: 30.9 KB
Line 
1package org.expeditee.actions;
2
3import java.awt.Color;
4import java.awt.Desktop;
5import java.awt.Image;
6import java.awt.image.BufferedImage;
7import java.awt.image.VolatileImage;
8import java.io.File;
9import java.io.FileNotFoundException;
10import java.io.IOException;
11import java.lang.reflect.Method;
12import java.util.ArrayList;
13import java.util.Collection;
14import java.util.LinkedList;
15import java.util.List;
16
17import javax.imageio.ImageIO;
18
19import org.expeditee.gui.AttributeUtils;
20import org.expeditee.gui.Browser;
21import org.expeditee.gui.DisplayIO;
22import org.expeditee.gui.Frame;
23import org.expeditee.gui.FrameGraphics;
24import org.expeditee.gui.FrameIO;
25import org.expeditee.gui.FrameMouseActions;
26import org.expeditee.gui.FrameUtils;
27import org.expeditee.gui.FreeItems;
28import org.expeditee.gui.MessageBay;
29import org.expeditee.gui.Reminders;
30import org.expeditee.gui.TimeKeeper;
31import org.expeditee.importer.FrameDNDTransferHandler;
32import org.expeditee.io.ExpClipReader;
33import org.expeditee.items.Item;
34import org.expeditee.items.ItemUtils;
35import org.expeditee.items.Line;
36import org.expeditee.items.Text;
37import org.expeditee.items.widgets.InteractiveWidget;
38import org.expeditee.math.ExpediteeJEP;
39import org.expeditee.simple.SString;
40import org.expeditee.stats.CometStats;
41import org.expeditee.stats.DocumentStatsFast;
42import org.expeditee.stats.SessionStats;
43import org.expeditee.stats.StatsLogger;
44import org.expeditee.stats.TreeStats;
45import org.nfunk.jep.Node;
46import org.nfunk.jep.ParseException;
47
48
49
50/**
51 * A list of miscellaneous Actions and Actions specific to Expeditee
52 *
53 */
54public class Misc {
55
56 /**
57 * Causes the system to beep
58 */
59 public static void beep() {
60 java.awt.Toolkit.getDefaultToolkit().beep();
61 }
62
63 /**
64 * Returns an Item located at the specified position.
65 * kgas1 - 23/01/2012
66 * @param x
67 * @param y
68 * @return
69 */
70 public static Item getItemAtPosition(int x, int y, Frame f)
71 {
72 Frame current = f;
73 List<Item> allItems = current.getItems();
74
75 for(Item i : allItems)
76 {
77 if(i.getX() == x && i.getY() == y)
78 return i;
79 }
80
81 return null;
82 }
83
84 /**
85 * Returns an item containing a specified piece of data.
86 * kgas1 - 7/06/2012
87 * @param s
88 * @param f
89 * @return
90 */
91 public static Item getItemContainingData(String s, Frame f){
92
93 Frame current = f;
94
95 List<Item> allItems = current.getItems();
96
97
98 for(Item i : allItems){
99
100
101 if(i.getData() != null && i.getData().size() > 0){
102 if(i.getData().contains(s)){
103 return i;
104 }
105 }
106 }
107
108 return null;
109 }
110
111 /**
112 * Forces a repaint of the current Frame
113 */
114 public static void display() {
115 FrameGraphics.refresh(false);
116 }
117
118 public static String getWindowSize() {
119 return Browser.getWindows()[0].getSize().toString();
120 }
121
122 /**
123 * Restores the current frame to the last saved version currently on the
124 * hard disk
125 */
126 public static void restore() {
127 FrameIO.Reload();
128 // MessageBay.displayMessage("Restoration complete.");
129 }
130
131 /**
132 * Toggles AudienceMode on or off
133 */
134 public static void toggleAudienceMode() {
135 FrameGraphics.ToggleAudienceMode();
136 }
137
138 /**
139 * Toggles TwinFrames mode on or off
140 */
141 public static void toggleTwinFramesMode() {
142 DisplayIO.ToggleTwinFrames();
143 }
144
145 /**
146 * If the given Item is a Text Item, then the text of the Item is
147 * interpreted as actions, if not this method does nothing.
148 *
149 * @param current
150 * The Item to read the Actions from
151 */
152 public static void runItem(Item current) throws Exception {
153 if (current instanceof Text) {
154 List<String> actions = ((Text) current).getTextList();
155 for (String action : actions) {
156 if (!action.equalsIgnoreCase("runitem")) {
157 Actions.PerformAction(DisplayIO.getCurrentFrame(), current,
158 action);
159 }
160 }
161 } else {
162 MessageBay.errorMessage("Item must be a text item.");
163 }
164 }
165
166 /**
167 * Prompts the user to confirm deletion of the current Frame, and deletes if
168 * the user chooses. After deletion this action calls back(), to ensure the
169 * deleted frame is not still being shown
170 *
171 */
172 public static void DeleteFrame(Frame toDelete) {
173 String deletedFrame = toDelete.getName();
174 String deletedFrameNameLowercase = deletedFrame.toLowerCase();
175 String errorMessage = "Error deleting " + deletedFrame;
176 try {
177 String deletedFrameName = FrameIO.DeleteFrame(toDelete);
178 if (deletedFrameName != null) {
179 DisplayIO.Back();
180 // Remove any links on the previous frame to the one being
181 // deleted
182 Frame current = DisplayIO.getCurrentFrame();
183 for (Item i : current.getItems())
184 if (i.getLink() != null
185 && i.getAbsoluteLink().toLowerCase().equals(
186 deletedFrameNameLowercase)) {
187 i.setLink(null);
188 }
189 MessageBay.displayMessage(deletedFrame + " renamed "
190 + deletedFrameName);
191 // FrameGraphics.Repaint();
192 return;
193 }
194 } catch (IOException ioe) {
195 if (ioe.getMessage() != null)
196 errorMessage += ". " + ioe.getMessage();
197 } catch (SecurityException se) {
198 if (se.getMessage() != null)
199 errorMessage += ". " + se.getMessage();
200 } catch (Exception e) {
201 e.printStackTrace();
202 }
203 MessageBay.errorMessage(errorMessage);
204 }
205
206 /**
207 * Loads the Frame linked to by the given Item. The first Item on the Frame
208 * that is not the title or name is then placed on the cursor. If the given
209 * Item has no link, or no item is found then this is a no-op.
210 *
211 * @param current
212 * The Item that links to the Frame that the Item will be loaded
213 * from.
214 */
215 public static Item GetItemFromChildFrame(Item current) {
216 return getFromChildFrame(current, false);
217 }
218
219 public static void GetItemsFromChildFrame(Item current) {
220 getItemsFromChildFrame(current, false);
221 }
222
223 /**
224 * Loads the Frame linked to by the given Item. The first Text Item on the
225 * Frame that is not the title or name is then placed on the cursor. If the
226 * given Item has no link, or no item is found then this is a no-op.
227 *
228 * @param current
229 * The Item that links to the Frame that the Item will be loaded
230 * from.
231 */
232 public static Item GetTextFromChildFrame(Item current) {
233 return getFromChildFrame(current, true);
234 }
235
236 private static Item getFromChildFrame(Item current, boolean textOnly) {
237 Item item = getFirstBodyItemOnChildFrame(current, textOnly);
238 // if no item was found
239 if (item != null) {
240 // copy the item and switch
241 item = item.copy();
242 item.setPosition(DisplayIO.getMouseX(), FrameMouseActions.getY());
243 }
244 return item;
245 }
246
247 private static void getItemsFromChildFrame(Item current, boolean textOnly) {
248 Collection<Item> items = getItemsOnChildFrame(current, textOnly);
249 // if no item was found
250 if (items == null || items.size() == 0) {
251 return;
252 }
253
254 // copy the item and switch
255 Collection<Item> copies = ItemUtils.CopyItems(items);
256 Item first = items.iterator().next();
257 float deltaX = DisplayIO.getMouseX() - first.getX();
258 float deltaY = FrameMouseActions.getY() - first.getY();
259 for (Item i : copies) {
260 if (i.isVisible())
261 i.setXY(i.getX() + deltaX, i.getY() + deltaY);
262 i.setParent(null);
263 }
264 FrameMouseActions.pickup(copies);
265 FrameGraphics.Repaint();
266 }
267
268 /**
269 * Sets the given Item to have the Given Color. Color can be null (for
270 * default)
271 *
272 * @param toChange
273 * The Item to set the Color.
274 * @param toUse
275 * The Color to give the Item.
276 */
277 public static void SetItemBackgroundColor(Item toChange, Color toUse) {
278 if (toChange == null)
279 return;
280
281 toChange.setBackgroundColor(toUse);
282 FrameGraphics.Repaint();
283 }
284
285 /**
286 * Sets the given Item to have the Given Color. Color can be null (for
287 * default)
288 *
289 * @param toChange
290 * The Item to set the Color.
291 * @param toUse
292 * The Color to give the Item.
293 */
294 public static void SetItemColor(Item toChange, Color toUse) {
295 if (toChange == null)
296 return;
297
298 toChange.setColor(toUse);
299 FrameGraphics.Repaint();
300 }
301
302 /**
303 * Creates a new Text Object containing general statistics for the current
304 * session. The newly created Text Object is then attached to the cursor via
305 * FrameMouseActions.pickup(Item)
306 */
307 public static void GetSessionStats() {
308 attachStatsToCursor(SessionStats.getCurrentStats());
309 }
310
311 /**
312 * Creates a new Text Object containing statistics for the current tree.
313 */
314 public static String GetCometStats(Frame frame) {
315 TimeKeeper timer = new TimeKeeper();
316 MessageBay.displayMessage("Computing comet stats...");
317 CometStats cometStats = new CometStats(frame);
318 String result = cometStats.toString();
319 MessageBay.overwriteMessage("Comet stats time: "
320 + timer.getElapsedStringSeconds());
321 return result;
322 }
323
324 public static String GetTreeStats(Frame frame) {
325 TimeKeeper timer = new TimeKeeper();
326 MessageBay.displayMessage("Computing tree stats...");
327
328 TreeStats treeStats = new TreeStats(frame);
329 String result = treeStats.toString();
330 MessageBay.overwriteMessage("Tree stats time: "
331 + timer.getElapsedStringSeconds());
332 return result;
333
334 }
335
336 public static String GetDocumentStats(Frame frame) {
337 TimeKeeper timer = new TimeKeeper();
338 MessageBay.displayMessage("Computing document stats...");
339 FrameIO.ForceSaveFrame(frame);
340 DocumentStatsFast docStats = new DocumentStatsFast(frame.getName(),
341 frame.getTitle());
342 String result = docStats.toString();
343
344 MessageBay.overwriteMessage("Document stats time: "
345 + timer.getElapsedStringSeconds());
346 return result;
347
348 }
349
350 /**
351 * Creates a text item and attaches it to the cursor.
352 *
353 * @param itemText
354 * the text to attach to the cursor
355 */
356 public static void attachStatsToCursor(String itemText) {
357 SessionStats.CreatedText();
358 Frame current = DisplayIO.getCurrentFrame();
359 Item text = current.getStatsTextItem(itemText);
360 FrameMouseActions.pickup(text);
361 FrameGraphics.Repaint();
362 }
363
364 public static void attachTextToCursor(String itemText) {
365 SessionStats.CreatedText();
366 Frame current = DisplayIO.getCurrentFrame();
367 Item text = current.getTextItem(itemText);
368 FrameMouseActions.pickup(text);
369 FrameGraphics.Repaint();
370 }
371
372 /**
373 * Creates a new Text Object containing statistics for moving, deleting and
374 * creating items in the current session. The newly created Text Object is
375 * then attached to the cursor via FrameMouseActions.pickup(Item)
376 */
377 public static String getItemStats() {
378 return SessionStats.getItemStats();
379 }
380
381 /**
382 * Creates a new Text Object containing statistics for the time between
383 * events triggered by the user through mouse clicks and key presses. The
384 * newly created Text Object is then attached to the cursor via
385 * FrameMouseActions.pickup(Item)
386 */
387 public static String getEventStats() {
388 return SessionStats.getEventStats();
389 }
390
391 /**
392 * Creates a new Text Object containing the contents of the current frames
393 * file.
394 */
395 public static String getFrameFile(Frame frame) {
396 return FrameIO.ForceSaveFrame(frame);
397 }
398
399 /**
400 * Creates a new Text Object containing the available fonts.
401 */
402 public static String getFontNames() {
403 Collection<String> availableFonts = Actions.getFonts().values();
404 StringBuilder fontsList = new StringBuilder();
405 for (String s : availableFonts) {
406 fontsList.append(s).append(Text.LINE_SEPARATOR);
407 }
408 fontsList.deleteCharAt(fontsList.length() - 1);
409
410 return fontsList.toString();
411 }
412
413 public static String getUnicodeCharacters(int start, int finish) {
414 if (start < 0 && finish < 0) {
415 throw new RuntimeException("Parameters must be non negative");
416 }
417 // Swap the start and finish if they are inthe wrong order
418 if (start > finish) {
419 start += finish;
420 finish = start - finish;
421 start = start - finish;
422 }
423 StringBuilder charList = new StringBuilder();
424 int count = 0;
425 charList.append(String.format("Unicode block 0x%x - 0x%x", start,
426 finish));
427 System.out.println();
428 // charList.append("Unicode block: ").append(String.format(format,
429 // args))
430 for (char i = (char) start; i < (char) finish; i++) {
431 if (Character.isDefined(i)) {
432 if (count++ % 64 == 0)
433 charList.append(Text.LINE_SEPARATOR);
434 charList.append(Character.valueOf(i));
435 }
436 }
437 return charList.toString();
438 }
439
440 /**
441 * Gets a single block of Unicode characters.
442 *
443 * @param start
444 * the start of the block
445 */
446 public static String getUnicodeCharacters(int start) {
447 return getUnicodeCharacters(start, start + 256);
448 }
449
450 public static String getMathSymbols() {
451 return getUnicodeCharacters('\u2200', '\u2300');
452 }
453
454 /**
455 * Resets the statistics back to zero.
456 */
457 public static void repaint() {
458 StatsLogger.WriteStatsFile();
459 SessionStats.resetStats();
460 }
461
462 /**
463 * Loads a frame with the given name and saves it as a JPEG image.
464 *
465 * @param framename
466 * The name of the Frame to save
467 */
468 public static void jpegFrame(String framename) {
469 ImageFrame(framename, "JPEG");
470 }
471
472 /**
473 * Saves the current frame as a JPEG image. This is the same as calling
474 * JpegFrame(currentFrame.getName())
475 */
476 public static void jpegFrame() {
477 ImageFrame(DisplayIO.getCurrentFrame().getName(), "JPEG");
478 }
479
480 public static void jpgFrame() {
481 jpegFrame();
482 }
483
484 /**
485 * Loads a frame with the given name and saves it as a PNG image.
486 *
487 * @param framename
488 * The name of the Frame to save
489 */
490 public static void PNGFrame(String framename) {
491 ImageFrame(framename, "PNG");
492 }
493
494 /**
495 * Saves the current frame as a PNG image. This is the same as calling
496 * PNGFrame(currentFrame.getName())
497 */
498 public static void PNGFrame(Frame frame) {
499 ImageFrame(frame.getName(), "PNG");
500 }
501
502 public static String SaveImage(BufferedImage screen, String format,
503 String directory, String fileName) {
504 String suffix = "." + format.toLowerCase();
505 String shortFileName = fileName;
506 // Check if we need to append the suffix
507 if (fileName.indexOf('.') < 0)
508 fileName += suffix;
509 else
510 shortFileName = fileName.substring(0, fileName.length() - suffix.length());
511
512 try {
513 int count = 2;
514 // set up the file for output
515 File out = new File(directory + fileName);
516 while (out.exists()) {
517 fileName = shortFileName + "_" + count++ + suffix;
518 out = new File(directory + fileName);
519 }
520
521 if (!out.getParentFile().exists())
522 out.mkdirs();
523
524 // If the image is successfully written out return the fileName
525 if (ImageIO.write(screen, format, out))
526 return fileName;
527
528 } catch (Exception e) {
529 e.printStackTrace();
530 }
531 return null;
532 }
533
534 public static String ImageFrame(Frame frame, String format, String directory) {
535 assert (frame != null);
536
537 Image oldBuffer = frame.getBuffer();
538 frame.setBuffer(null);
539 // Jpeg only works properly with volitile frames
540 // Png transparency only works with bufferedImage form
541 Image frameBuffer = FrameGraphics.getBuffer(frame, false, format
542 .equalsIgnoreCase("jpeg"));
543 // Make sure overlay stuff doesnt disapear on the frame visible on the
544 // screen
545 frame.setBuffer(oldBuffer);
546 BufferedImage screen = null;
547
548 if (frameBuffer instanceof VolatileImage) {
549 // If its the current frame it will be a volitive image
550 screen = ((VolatileImage) frameBuffer).getSnapshot();
551 } else {
552 assert (frameBuffer instanceof BufferedImage);
553 screen = (BufferedImage) frameBuffer;
554 }
555 return SaveImage(screen, format, directory, frame.getExportFileName());
556 }
557
558 /**
559 * Saves the Frame with the given Framename as an image of the given format.
560 *
561 * @param framename
562 * The name of the Frame to save as an image
563 * @param format
564 * The Image format to use (i.e. "PNG", "BMP", etc)
565 */
566 public static void ImageFrame(String framename, String format) {
567 Frame loaded = FrameIO.LoadFrame(framename);
568
569 // if the frame was loaded successfully
570 if (loaded != null) {
571 String path = FrameIO.EXPORTS_DIR;
572 String frameName = ImageFrame(loaded, format, path);
573 if (frameName != null)
574 MessageBay.displayMessage("Frame successfully saved to " + path
575 + frameName);
576 else
577 MessageBay.errorMessage("Could not find image writer for "
578 + format + " format");
579 // if the frame was not loaded successfully, alert the user
580 } else {
581 MessageBay.displayMessage("Frame '" + framename
582 + "' could not be found.");
583 }
584 }
585
586 public static void MessageLn(Item message) {
587 if (message instanceof Text)
588 MessageBay.displayMessage((Text) message);
589 }
590
591 /**
592 * Displays a message in the message box area.
593 *
594 * @param message
595 * the message to display
596 */
597 public static void MessageLn(String message) {
598 MessageBay.displayMessage(message);
599 }
600
601 public static void MessageLn2(String message, String message2) {
602 MessageBay.displayMessage(message + " " + message2);
603 }
604
605 public static void CopyFile(String existingFile, String newFileName) {
606 try {
607 // TODO is there a built in method which will do this faster?
608
609 MessageBay.displayMessage("Copying file " + existingFile + " to "
610 + newFileName + "...");
611 FrameIO.copyFile(existingFile, newFileName);
612 MessageBay.displayMessage("File copied successfully");
613 } catch (FileNotFoundException e) {
614 MessageBay.displayMessage("Error opening file: " + existingFile);
615 } catch (Exception e) {
616 MessageBay.displayMessage("File could not be copied");
617 }
618 }
619
620 /**
621 * Runs two methods alternatively a specified number of times and reports on
622 * the time spent running each method.
623 *
624 * @param fullMethodNameA
625 * @param fullMethodNameB
626 * @param repsPerTest
627 * the number of time each method is run per test
628 * @param tests
629 * the number of tests to conduct
630 *
631 */
632 public static void CompareMethods(String fullMethodNameA,
633 String fullMethodNameB, int repsPerTest, int tests) {
634 try {
635 String classNameA = getClassName(fullMethodNameA);
636 String classNameB = getClassName(fullMethodNameB);
637 String methodNameA = getMethodName(fullMethodNameA);
638 String methodNameB = getMethodName(fullMethodNameB);
639
640 Class<?> classA = Class.forName(classNameA);
641 Class<?> classB = Class.forName(classNameB);
642 Method methodA = classA.getDeclaredMethod(methodNameA,
643 new Class[] {});
644 Method methodB = classB.getDeclaredMethod(methodNameB,
645 new Class[] {});
646 TimeKeeper timeKeeper = new TimeKeeper();
647 long timeA = 0;
648 long timeB = 0;
649 // Run the tests
650 for (int i = 0; i < tests; i++) {
651 // Test methodA
652 timeKeeper.restart();
653 for (int j = 0; j < repsPerTest; j++) {
654 methodA.invoke((Object) null, new Object[] {});
655 }
656 timeA += timeKeeper.getElapsedMillis();
657 timeKeeper.restart();
658 // Test methodB
659 for (int j = 0; j < repsPerTest; j++) {
660 methodB.invoke((Object) null, new Object[] {});
661 }
662 timeB += timeKeeper.getElapsedMillis();
663 }
664
665 float aveTimeA = timeA * 1000F / repsPerTest / tests;
666 float aveTimeB = timeB * 1000F / repsPerTest / tests;
667 // Display Results
668 MessageBay.displayMessage("Average Execution Time");
669 MessageBay.displayMessage(methodNameA + ": "
670 + TimeKeeper.Formatter.format(aveTimeA) + "us");
671 MessageBay.displayMessage(methodNameB + ": "
672 + TimeKeeper.Formatter.format(aveTimeB) + "us");
673 } catch (Exception e) {
674 MessageBay.errorMessage(e.getClass().getSimpleName() + ": "
675 + e.getMessage());
676 }
677 }
678
679 public static String getClassName(String fullMethodName) {
680 assert (fullMethodName != null);
681 assert (fullMethodName.length() > 0);
682 int lastPeriod = fullMethodName.lastIndexOf('.');
683 if (lastPeriod > 0 && lastPeriod < fullMethodName.length() - 1)
684 return fullMethodName.substring(0, lastPeriod);
685 throw new RuntimeException("Invalid method name: " + fullMethodName);
686 }
687
688 public static String getMethodName(String methodName) {
689 assert (methodName != null);
690 assert (methodName.length() > 0);
691 int lastPeriod = methodName.lastIndexOf('.');
692 if (lastPeriod > 0 && lastPeriod < methodName.length() - 1)
693 return methodName.substring(1 + lastPeriod);
694 throw new RuntimeException("Invalid method name: " + methodName);
695 }
696
697 /**
698 * Loads the Frame linked to by the given Item. The first Item on the Frame
699 * that is not the title or name is then placed on the current frame. The
700 * item that was clicked on is placed on the frame it was linked to and the
701 * link is switched to the item from the child frame. If the given Item has
702 * no link, or no item is found then this is a no-op.
703 *
704 * @param current
705 * The Item that links to the Frame that the Item will be loaded
706 * from.
707 */
708 public static void SwapItemWithItemOnChildFrame(Item current) {
709 Item item = getFirstBodyItemOnChildFrame(current, false);
710 // if no item was found
711 if (item == null) {
712 return;
713 }
714
715 // swap the items parents
716 Frame parentFrame = current.getParent();
717 Frame childFrame = item.getParent();
718 current.setParent(childFrame);
719 item.setParent(parentFrame);
720
721 // swap the items on the frames
722 parentFrame.removeItem(current);
723 childFrame.removeItem(item);
724 parentFrame.addItem(item);
725 childFrame.addItem(current);
726
727 // swap the items links
728 item.setActions(current.getAction());
729 item.setLink(childFrame.getName());
730 current.setLink(parentFrame.getName());
731 // current.setLink(null);
732 current.setActions(null);
733
734 FrameGraphics.Repaint();
735 }
736
737 private static Item getFirstBodyItemOnChildFrame(Item current,
738 boolean textOnly) {
739 // the item must link to a frame
740 if (current.getLink() == null) {
741 MessageBay
742 .displayMessage("Cannot get item from child - this item has no link");
743 return null;
744 }
745
746 Frame child = FrameIO.LoadFrame(current.getAbsoluteLink());
747
748 // if the frame could not be loaded
749 if (child == null) {
750 MessageBay.errorMessage("Could not load child frame.");
751 return null;
752 }
753
754 // find the first non-title and non-name item
755 List<Item> body = new ArrayList<Item>();
756 if (textOnly)
757 body.addAll(child.getBodyTextItems(false));
758 else
759 body.addAll(child.getItems());
760 Item item = null;
761
762 for (Item i : body)
763 if (i != child.getTitleItem() && !i.isAnnotation()) {
764 item = i;
765 break;
766 }
767
768 // if no item was found
769 if (item == null) {
770 MessageBay.displayMessage("No item found to copy");
771 return null;
772 }
773
774 return item;
775 }
776
777 private static Collection<Item> getItemsOnChildFrame(Item current,
778 boolean textOnly) {
779 // the item must link to a frame
780 if (current.getLink() == null) {
781 MessageBay
782 .displayMessage("Cannot get item from child - this item has no link");
783 return null;
784 }
785 Frame child = FrameIO.LoadFrame(current.getAbsoluteLink());
786
787 // if the frame could not be loaded
788 if (child == null) {
789 MessageBay.errorMessage("Could not load child frame.");
790 return null;
791 }
792
793 // find the first non-title and non-name item
794 Collection<Item> body = new ArrayList<Item>();
795 if (textOnly)
796 body.addAll(child.getBodyTextItems(false));
797 else
798 body.addAll(child.getItems());
799
800 return body;
801 }
802
803 public static void calculate(Frame frame, Item toCalculate) {
804 if (toCalculate instanceof Text) {
805 Text text = (Text) toCalculate;
806 ExpediteeJEP myParser = new ExpediteeJEP();
807 myParser.addVariables(frame);
808 String linkedFrame = toCalculate.getAbsoluteLink();
809 if (linkedFrame != null) {
810 myParser.addVariables(FrameIO.LoadFrame(linkedFrame));
811 }
812 myParser.resetObserver();
813
814 // Do the calculation
815 String formulaFullCase = text.getText().replace('\n', ' ');
816 String formula = formulaFullCase.toLowerCase();
817
818 try {
819 Node node = myParser.parse(formula);
820 Object result = myParser.evaluate(node);
821 text.setText(result.toString(), true);
822 text.setFormula(formulaFullCase);
823 if (text.isFloating()) {
824 text.setPosition(FrameMouseActions.MouseX,
825 FrameMouseActions.MouseY);
826 FrameMouseActions.resetOffset();
827 } else {
828 text.getParentOrCurrentFrame().change();
829 }
830 } catch (ParseException e) {
831 MessageBay.errorMessage("Parse error "
832 + e.getMessage().replace("\n", ""));
833 } catch (Exception e) {
834 MessageBay.errorMessage("evaluation error "
835 + e.getMessage().replace("\n", ""));
836 e.printStackTrace();
837 }
838 }
839 }
840
841 /**
842 * Attach an item to the cursor.
843 *
844 * @param item
845 */
846 public static void attachToCursor(Item item) {
847 item.setParent(null);
848 FrameMouseActions.pickup(item);
849 FrameGraphics.Repaint();
850 }
851
852 public static void attachToCursor(Collection<Item> items) {
853 for (Item i : items) {
854 i.setParent(null);
855 i.invalidateAll();
856 }
857 FrameMouseActions.pickup(items);
858 // TODO figure out why this isnt repainting stuff immediately
859 // All of text item doesnt repaint until the cursor is moved
860 FrameGraphics.requestRefresh(true);
861 }
862
863 public static void importFiles(Item item) {
864 List<File> files = new LinkedList<File>();
865 for (String s : item.getText().split("\\s+")) {
866 File file = new File(s.trim());
867 if (file.exists()) {
868 files.add(file);
869 }
870 }
871 try {
872 FrameDNDTransferHandler.getInstance().importFileList(files,
873 FrameMouseActions.getPosition());
874 } catch (Exception e) {
875 }
876 }
877
878 public static void importFile(Item item) {
879 File file = new File(item.getText().trim());
880 if (file.exists()) {
881 try {
882 FrameDNDTransferHandler.getInstance().importFile(file,
883 FrameMouseActions.getPosition());
884 } catch (Exception e) {
885 e.printStackTrace();
886 }
887 }
888 }
889
890 public static Item createPolygon(Item item, int sides) {
891 if (item instanceof Text) {
892 try {
893 SString s = new SString(item.getText());
894 sides = s.integerValue().intValue();
895 } catch (NumberFormatException e) {
896 }
897 }
898
899 if (sides < 3) {
900 MessageBay.errorMessage("Shapes must have at least 3 sides");
901 }
902 double angle = -(180 - ((sides - 2) * 180.0F) / sides);
903 double curAngle = 0;
904 double size = 50F;
905 if (item.isLineEnd() && item.getLines().size() > 0) {
906 item = item.getLines().get(0);
907 }
908 // Use line length to determine the size of the shape
909 if (item instanceof Line) {
910 size = ((Line) item).getLength();
911 }
912
913 float curX = FrameMouseActions.MouseX;
914 float curY = FrameMouseActions.MouseY;
915
916 Collection<Item> newItems = new LinkedList<Item>();
917 Item[] d = new Item[sides];
918 // create dots
919 Frame current = DisplayIO.getCurrentFrame();
920 for (int i = 0; i < d.length; i++) {
921 d[i] = current.createDot();
922 newItems.add(d[i]);
923 d[i].setPosition(curX, curY);
924 curX += (float) (Math.cos((curAngle) * Math.PI / 180.0) * size);
925 curY += (float) (Math.sin((curAngle) * Math.PI / 180.0) * size);
926
927 curAngle += angle;
928 }
929 // create lines
930 for (int i = 1; i < d.length; i++) {
931 newItems.add(new Line(d[i - 1], d[i], current.getNextItemID()));
932 }
933 newItems.add(new Line(d[d.length - 1], d[0], current.getNextItemID()));
934
935 current.addAllItems(newItems);
936 if (item instanceof Text) {
937 for (Item i : item.getAllConnected()) {
938 if (i instanceof Line) {
939 item = i;
940 break;
941 }
942 }
943 }
944
945 Color newColor = item.getColor();
946 if (newColor != null) {
947 d[0].setColor(item.getColor());
948 if (item instanceof Text && item.getBackgroundColor() != null) {
949 d[0].setFillColor(item.getBackgroundColor());
950 } else {
951 d[0].setFillColor(item.getFillColor());
952 }
953 }
954 float newThickness = item.getThickness();
955 if (newThickness > 0) {
956 d[0].setThickness(newThickness);
957 }
958
959 ItemUtils.EnclosedCheck(newItems);
960 FrameGraphics.refresh(false);
961
962 return d[0];
963 }
964
965 public static void StopReminder() {
966 Reminders.stop();
967 }
968
969 public static void print(String file) {
970 try {
971 if (Browser._theBrowser.isMinimumVersion6()) {
972 if (Desktop.isDesktopSupported()) {
973 Desktop.getDesktop().print(new File(file));
974 }
975 }
976 } catch (Exception e) {
977 MessageBay.errorMessage("Printing error: " + e.getMessage());
978 }
979 }
980
981 public static int wordCount(String paragraph) {
982 return paragraph.trim().split("\\s+").length + 1;
983 }
984
985 public static int wordCount(Frame frame) {
986 int count = 0;
987
988 for (Text t : frame.getBodyTextItems(false)) {
989 count += wordCount(t.getText());
990 }
991
992 return count;
993 }
994
995 public static void moveToPublic(Frame frame) {
996 FrameIO.moveFrameset(frame.getFramesetName(), FrameIO.PUBLIC_PATH);
997 }
998
999 public static void moveToPrivate(Frame frame) {
1000 FrameIO.moveFrameset(frame.getFramesetName(), FrameIO.FRAME_PATH);
1001 }
1002
1003 /**
1004 * Returns the value of a specified item attribute.
1005 *
1006 * @param item
1007 * from which to extract the value
1008 * @param attribute
1009 * name of an items attribute
1010 * @return the value of the attribute
1011 */
1012 public static String extract(Item item, String attribute) {
1013 return AttributeUtils.getAttribute(item, attribute);
1014 }
1015
1016 /**
1017 * Launches items.widgets.Browser and uses Text item as URL.
1018 * @param text Text item which passes contents as URL for browser.
1019 * @throws Exception
1020 */
1021 public static void startBrowser(Item text) throws Exception {
1022 if (text instanceof Text) {
1023 FreeItems.getInstance().clear(); // remove url text from cursor
1024
1025 Text wt = new Text("@iw:org.expeditee.items.widgets.Browser"); // create new text item for browser widget
1026 wt.setParent(DisplayIO.getCurrentFrame()); // set parent of text source for InteractiveWidget.createWidget()
1027 wt.setXY(FrameMouseActions.getX(), FrameMouseActions.getY());
1028 // create widget from text item
1029 org.expeditee.items.widgets.Browser browser = (org.expeditee.items.widgets.Browser) InteractiveWidget.createWidget(wt);
1030
1031 if(FreeItems.textOnlyAttachedToCursor()) { // navigates to url specified by the text item
1032 browser.navigate(text.getText());
1033 } else {
1034 browser.navigate("http://www.waikato.ac.nz");
1035 }
1036
1037 FrameMouseActions.pickup(browser.getItems()); // attach browser widget to mouse
1038 } else {
1039 MessageBay.errorMessage("Must be a text item.");
1040 }
1041 }
1042
1043 /**
1044 * Text item becomes link to new frame containing items.widgets.Browser and uses Text item as URL for browser.
1045 * @param text Text item which passes contents as URL for browser and becomes link to the browser's new frame.
1046 * @throws Exception
1047 */
1048 public static void startBrowserNewFrame(Item text) throws Exception {
1049 System.out.println("test");
1050 if (!(text instanceof Text)) {
1051 MessageBay.errorMessage("Must be a text item.");
1052 return;
1053 }
1054 if(text.getLink() != null) { // text item can't already have a link
1055 MessageBay.errorMessage("Text item already has link.");
1056 return;
1057 }
1058
1059 Frame frame = FrameIO.CreateNewFrame(text); // create new frame for browser
1060 frame.addText(50, 50, "@iw:org.expeditee.items.widgets.Browser", null); // create new text item for browser widget
1061 FrameUtils.Parse(frame); // parse created frame; loads browser widget
1062
1063 for(InteractiveWidget iw : frame.getInteractiveWidgets()) { // may be other widgets on frame
1064 if(iw instanceof org.expeditee.items.widgets.Browser) {
1065 // If there is a text item attached to cursor use it as url for browser
1066 if(FreeItems.textOnlyAttachedToCursor()) {
1067 text.setLink("" + frame.getNumber());
1068 ((org.expeditee.items.widgets.Browser)iw).navigate(text.getText());
1069 } else {
1070 // Navigate to www.waikato.ac.nz by default if no url supplied and create new text item to be the link
1071 ((org.expeditee.items.widgets.Browser)iw).navigate("http://www.waikato.ac.nz");
1072 Text t = new Text("http://www.waikato.ac.nz");
1073 t.setParent(DisplayIO.getCurrentFrame()); // set parent of text source for InteractiveWidget.createWidget()
1074 t.setXY(FrameMouseActions.getX(), FrameMouseActions.getY());
1075 t.setLink("" + frame.getNumber()); // link url text to new browser frame
1076 FrameMouseActions.pickup(t); // Attach new text link to cursor
1077 }
1078 }
1079 }
1080
1081 FrameIO.SaveFrame(frame); // save frame to disk
1082 }
1083}
Note: See TracBrowser for help on using the repository browser.