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
RevLine 
[4]1package org.expeditee.actions;
2
3import java.awt.Color;
[309]4import java.awt.Desktop;
[78]5import java.awt.Image;
[4]6import java.awt.image.BufferedImage;
[78]7import java.awt.image.VolatileImage;
[4]8import java.io.File;
9import java.io.FileNotFoundException;
10import java.io.IOException;
[72]11import java.lang.reflect.Method;
[70]12import java.util.ArrayList;
[108]13import java.util.Collection;
[242]14import java.util.LinkedList;
[4]15import java.util.List;
16
17import javax.imageio.ImageIO;
18
[376]19import org.expeditee.gui.AttributeUtils;
[309]20import org.expeditee.gui.Browser;
[4]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;
[514]26import org.expeditee.gui.FrameUtils;
27import org.expeditee.gui.FreeItems;
[121]28import org.expeditee.gui.MessageBay;
[284]29import org.expeditee.gui.Reminders;
[72]30import org.expeditee.gui.TimeKeeper;
[278]31import org.expeditee.importer.FrameDNDTransferHandler;
[514]32import org.expeditee.io.ExpClipReader;
[4]33import org.expeditee.items.Item;
[162]34import org.expeditee.items.ItemUtils;
[247]35import org.expeditee.items.Line;
[4]36import org.expeditee.items.Text;
[514]37import org.expeditee.items.widgets.InteractiveWidget;
[190]38import org.expeditee.math.ExpediteeJEP;
[278]39import org.expeditee.simple.SString;
[90]40import org.expeditee.stats.CometStats;
[376]41import org.expeditee.stats.DocumentStatsFast;
[4]42import org.expeditee.stats.SessionStats;
43import org.expeditee.stats.StatsLogger;
[90]44import org.expeditee.stats.TreeStats;
[156]45import org.nfunk.jep.Node;
[190]46import org.nfunk.jep.ParseException;
[4]47
[438]48
49
[4]50/**
[105]51 * A list of miscellaneous Actions and Actions specific to Expeditee
[4]52 *
53 */
54public class Misc {
[438]55
[4]56 /**
57 * Causes the system to beep
58 */
[181]59 public static void beep() {
[4]60 java.awt.Toolkit.getDefaultToolkit().beep();
61 }
[438]62
[4]63 /**
[438]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
[441]75 for(Item i : allItems)
76 {
[438]77 if(i.getX() == x && i.getY() == y)
78 return i;
79 }
80
81 return null;
82 }
83
[441]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 */
[438]91 public static Item getItemContainingData(String s, Frame f){
[441]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 }
[438]110
111 /**
[4]112 * Forces a repaint of the current Frame
113 */
[181]114 public static void display() {
115 FrameGraphics.refresh(false);
[4]116 }
[412]117
118 public static String getWindowSize() {
119 return Browser.getWindows()[0].getSize().toString();
120 }
[4]121
122 /**
123 * Restores the current frame to the last saved version currently on the
124 * hard disk
125 */
[181]126 public static void restore() {
[4]127 FrameIO.Reload();
[121]128 // MessageBay.displayMessage("Restoration complete.");
[4]129 }
130
131 /**
132 * Toggles AudienceMode on or off
133 */
[181]134 public static void toggleAudienceMode() {
[4]135 FrameGraphics.ToggleAudienceMode();
136 }
137
138 /**
139 * Toggles TwinFrames mode on or off
140 */
[181]141 public static void toggleTwinFramesMode() {
[4]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 */
[181]152 public static void runItem(Item current) throws Exception {
[4]153 if (current instanceof Text) {
[80]154 List<String> actions = ((Text) current).getTextList();
[4]155 for (String action : actions) {
[181]156 if (!action.equalsIgnoreCase("runitem")) {
[160]157 Actions.PerformAction(DisplayIO.getCurrentFrame(), current,
158 action);
159 }
[4]160 }
[156]161 } else {
162 MessageBay.errorMessage("Item must be a text item.");
[4]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 */
[282]172 public static void DeleteFrame(Frame toDelete) {
[80]173 String deletedFrame = toDelete.getName();
[7]174 String deletedFrameNameLowercase = deletedFrame.toLowerCase();
[97]175 String errorMessage = "Error deleting " + deletedFrame;
[4]176 try {
[154]177 String deletedFrameName = FrameIO.DeleteFrame(toDelete);
178 if (deletedFrameName != null) {
179 DisplayIO.Back();
[156]180 // Remove any links on the previous frame to the one being
181 // deleted
[4]182 Frame current = DisplayIO.getCurrentFrame();
183 for (Item i : current.getItems())
184 if (i.getLink() != null
[7]185 && i.getAbsoluteLink().toLowerCase().equals(
186 deletedFrameNameLowercase)) {
[4]187 i.setLink(null);
188 }
[154]189 MessageBay.displayMessage(deletedFrame + " renamed "
190 + deletedFrameName);
[156]191 // FrameGraphics.Repaint();
[97]192 return;
[4]193 }
[115]194 } catch (IOException ioe) {
195 if (ioe.getMessage() != null)
196 errorMessage += ". " + ioe.getMessage();
[97]197 } catch (SecurityException se) {
[115]198 if (se.getMessage() != null)
199 errorMessage += ". " + se.getMessage();
[97]200 } catch (Exception e) {
201 e.printStackTrace();
[4]202 }
[121]203 MessageBay.errorMessage(errorMessage);
[4]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 */
[181]215 public static Item GetItemFromChildFrame(Item current) {
216 return getFromChildFrame(current, false);
[70]217 }
[163]218
[162]219 public static void GetItemsFromChildFrame(Item current) {
220 getItemsFromChildFrame(current, false);
221 }
[72]222
[70]223 /**
[72]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.
[70]227 *
228 * @param current
229 * The Item that links to the Frame that the Item will be loaded
230 * from.
231 */
[181]232 public static Item GetTextFromChildFrame(Item current) {
233 return getFromChildFrame(current, true);
[70]234 }
[72]235
[181]236 private static Item getFromChildFrame(Item current, boolean textOnly) {
[70]237 Item item = getFirstBodyItemOnChildFrame(current, textOnly);
[4]238 // if no item was found
[181]239 if (item != null) {
240 // copy the item and switch
241 item = item.copy();
242 item.setPosition(DisplayIO.getMouseX(), FrameMouseActions.getY());
[4]243 }
[181]244 return item;
[4]245 }
[163]246
[162]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 }
[4]253
[162]254 // copy the item and switch
255 Collection<Item> copies = ItemUtils.CopyItems(items);
[163]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);
[162]262 i.setParent(null);
263 }
264 FrameMouseActions.pickup(copies);
265 FrameGraphics.Repaint();
266 }
267
[4]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 */
[181]277 public static void SetItemBackgroundColor(Item toChange, Color toUse) {
[4]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 */
[181]294 public static void SetItemColor(Item toChange, Color toUse) {
[4]295 if (toChange == null)
296 return;
297
298 toChange.setColor(toUse);
299 FrameGraphics.Repaint();
300 }
301
302 /**
[70]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)
[4]306 */
[21]307 public static void GetSessionStats() {
[115]308 attachStatsToCursor(SessionStats.getCurrentStats());
[70]309 }
[4]310
[86]311 /**
312 * Creates a new Text Object containing statistics for the current tree.
313 */
[181]314 public static String GetCometStats(Frame frame) {
[90]315 TimeKeeper timer = new TimeKeeper();
[121]316 MessageBay.displayMessage("Computing comet stats...");
[105]317 CometStats cometStats = new CometStats(frame);
[181]318 String result = cometStats.toString();
[121]319 MessageBay.overwriteMessage("Comet stats time: "
[90]320 + timer.getElapsedStringSeconds());
[181]321 return result;
[90]322 }
[86]323
[181]324 public static String GetTreeStats(Frame frame) {
[90]325 TimeKeeper timer = new TimeKeeper();
[121]326 MessageBay.displayMessage("Computing tree stats...");
[90]327
[105]328 TreeStats treeStats = new TreeStats(frame);
[181]329 String result = treeStats.toString();
[121]330 MessageBay.overwriteMessage("Tree stats time: "
[90]331 + timer.getElapsedStringSeconds());
[181]332 return result;
333
[86]334 }
[376]335
[362]336 public static String GetDocumentStats(Frame frame) {
337 TimeKeeper timer = new TimeKeeper();
338 MessageBay.displayMessage("Computing document stats...");
[376]339 FrameIO.ForceSaveFrame(frame);
340 DocumentStatsFast docStats = new DocumentStatsFast(frame.getName(),
341 frame.getTitle());
342 String result = docStats.toString();
[86]343
[362]344 MessageBay.overwriteMessage("Document stats time: "
345 + timer.getElapsedStringSeconds());
346 return result;
347
348 }
349
[115]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) {
[72]357 SessionStats.CreatedText();
358 Frame current = DisplayIO.getCurrentFrame();
[78]359 Item text = current.getStatsTextItem(itemText);
[4]360 FrameMouseActions.pickup(text);
361 FrameGraphics.Repaint();
362 }
363
[115]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 }
[438]371
[4]372 /**
[70]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 */
[181]377 public static String getItemStats() {
378 return SessionStats.getItemStats();
[70]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 */
[181]387 public static String getEventStats() {
388 return SessionStats.getEventStats();
[70]389 }
390
391 /**
[4]392 * Creates a new Text Object containing the contents of the current frames
393 * file.
394 */
[181]395 public static String getFrameFile(Frame frame) {
396 return FrameIO.ForceSaveFrame(frame);
[4]397 }
[7]398
[4]399 /**
400 * Creates a new Text Object containing the available fonts.
401 */
[181]402 public static String getFontNames() {
[115]403 Collection<String> availableFonts = Actions.getFonts().values();
[4]404 StringBuilder fontsList = new StringBuilder();
[7]405 for (String s : availableFonts) {
[115]406 fontsList.append(s).append(Text.LINE_SEPARATOR);
[4]407 }
[115]408 fontsList.deleteCharAt(fontsList.length() - 1);
[7]409
[181]410 return fontsList.toString();
[115]411 }
[4]412
[181]413 public static String getUnicodeCharacters(int start, int finish) {
[154]414 if (start < 0 && finish < 0) {
[115]415 throw new RuntimeException("Parameters must be non negative");
416 }
[154]417 // Swap the start and finish if they are inthe wrong order
418 if (start > finish) {
[115]419 start += finish;
[154]420 finish = start - finish;
[115]421 start = start - finish;
422 }
423 StringBuilder charList = new StringBuilder();
424 int count = 0;
[154]425 charList.append(String.format("Unicode block 0x%x - 0x%x", start,
426 finish));
[115]427 System.out.println();
[154]428 // charList.append("Unicode block: ").append(String.format(format,
429 // args))
430 for (char i = (char) start; i < (char) finish; i++) {
[115]431 if (Character.isDefined(i)) {
[154]432 if (count++ % 64 == 0)
[115]433 charList.append(Text.LINE_SEPARATOR);
434 charList.append(Character.valueOf(i));
435 }
436 }
[181]437 return charList.toString();
[4]438 }
[154]439
[115]440 /**
441 * Gets a single block of Unicode characters.
[154]442 *
443 * @param start
444 * the start of the block
[115]445 */
[181]446 public static String getUnicodeCharacters(int start) {
447 return getUnicodeCharacters(start, start + 256);
[115]448 }
[154]449
[181]450 public static String getMathSymbols() {
451 return getUnicodeCharacters('\u2200', '\u2300');
[115]452 }
[4]453
454 /**
455 * Resets the statistics back to zero.
456 */
[181]457 public static void repaint() {
[4]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 */
[181]468 public static void jpegFrame(String framename) {
[80]469 ImageFrame(framename, "JPEG");
[4]470 }
471
472 /**
473 * Saves the current frame as a JPEG image. This is the same as calling
[80]474 * JpegFrame(currentFrame.getName())
[4]475 */
[181]476 public static void jpegFrame() {
[80]477 ImageFrame(DisplayIO.getCurrentFrame().getName(), "JPEG");
[4]478 }
479
[181]480 public static void jpgFrame() {
481 jpegFrame();
[80]482 }
483
[4]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
[80]496 * PNGFrame(currentFrame.getName())
[4]497 */
[376]498 public static void PNGFrame(Frame frame) {
499 ImageFrame(frame.getName(), "PNG");
[4]500 }
501
[86]502 public static String SaveImage(BufferedImage screen, String format,
503 String directory, String fileName) {
[376]504 String suffix = "." + format.toLowerCase();
505 String shortFileName = fileName;
[80]506 // Check if we need to append the suffix
507 if (fileName.indexOf('.') < 0)
[376]508 fileName += suffix;
509 else
510 shortFileName = fileName.substring(0, fileName.length() - suffix.length());
[80]511
512 try {
[376]513 int count = 2;
[80]514 // set up the file for output
[376]515 File out = new File(directory + fileName);
516 while (out.exists()) {
517 fileName = shortFileName + "_" + count++ + suffix;
518 out = new File(directory + fileName);
519 }
520
[80]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 }
[86]533
[80]534 public static String ImageFrame(Frame frame, String format, String directory) {
535 assert (frame != null);
[86]536
[181]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;
[80]547
[181]548 if (frameBuffer instanceof VolatileImage) {
549 // If its the current frame it will be a volitive image
[80]550 screen = ((VolatileImage) frameBuffer).getSnapshot();
551 } else {
[181]552 assert (frameBuffer instanceof BufferedImage);
553 screen = (BufferedImage) frameBuffer;
[80]554 }
555 return SaveImage(screen, format, directory, frame.getExportFileName());
556 }
557
[4]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) {
[406]571 String path = FrameIO.EXPORTS_DIR;
[80]572 String frameName = ImageFrame(loaded, format, path);
573 if (frameName != null)
[154]574 MessageBay.displayMessage("Frame successfully saved to " + path
575 + frameName);
[80]576 else
[121]577 MessageBay.errorMessage("Could not find image writer for "
[80]578 + format + " format");
[4]579 // if the frame was not loaded successfully, alert the user
[181]580 } else {
[121]581 MessageBay.displayMessage("Frame '" + framename
[4]582 + "' could not be found.");
[181]583 }
[4]584 }
585
[336]586 public static void MessageLn(Item message) {
587 if (message instanceof Text)
588 MessageBay.displayMessage((Text) message);
589 }
590
[4]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) {
[121]598 MessageBay.displayMessage(message);
[4]599 }
600
601 public static void MessageLn2(String message, String message2) {
[121]602 MessageBay.displayMessage(message + " " + message2);
[4]603 }
604
605 public static void CopyFile(String existingFile, String newFileName) {
606 try {
[7]607 // TODO is there a built in method which will do this faster?
608
[154]609 MessageBay.displayMessage("Copying file " + existingFile + " to "
610 + newFileName + "...");
[7]611 FrameIO.copyFile(existingFile, newFileName);
[121]612 MessageBay.displayMessage("File copied successfully");
[4]613 } catch (FileNotFoundException e) {
[121]614 MessageBay.displayMessage("Error opening file: " + existingFile);
[7]615 } catch (Exception e) {
[121]616 MessageBay.displayMessage("File could not be copied");
[4]617 }
618 }
619
620 /**
[72]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
[176]640 Class<?> classA = Class.forName(classNameA);
641 Class<?> classB = Class.forName(classNameB);
[72]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++) {
[80]654 methodA.invoke((Object) null, new Object[] {});
[72]655 }
656 timeA += timeKeeper.getElapsedMillis();
657 timeKeeper.restart();
658 // Test methodB
659 for (int j = 0; j < repsPerTest; j++) {
[80]660 methodB.invoke((Object) null, new Object[] {});
[72]661 }
662 timeB += timeKeeper.getElapsedMillis();
663 }
664
665 float aveTimeA = timeA * 1000F / repsPerTest / tests;
666 float aveTimeB = timeB * 1000F / repsPerTest / tests;
667 // Display Results
[121]668 MessageBay.displayMessage("Average Execution Time");
669 MessageBay.displayMessage(methodNameA + ": "
[72]670 + TimeKeeper.Formatter.format(aveTimeA) + "us");
[121]671 MessageBay.displayMessage(methodNameB + ": "
[72]672 + TimeKeeper.Formatter.format(aveTimeB) + "us");
673 } catch (Exception e) {
[121]674 MessageBay.errorMessage(e.getClass().getSimpleName() + ": "
[72]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 /**
[4]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) {
[70]709 Item item = getFirstBodyItemOnChildFrame(current, false);
[4]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
[74]728 item.setActions(current.getAction());
[80]729 item.setLink(childFrame.getName());
730 current.setLink(parentFrame.getName());
[4]731 // current.setLink(null);
[74]732 current.setActions(null);
[4]733
734 FrameGraphics.Repaint();
735 }
736
[72]737 private static Item getFirstBodyItemOnChildFrame(Item current,
738 boolean textOnly) {
[4]739 // the item must link to a frame
740 if (current.getLink() == null) {
[121]741 MessageBay
742 .displayMessage("Cannot get item from child - this item has no link");
[4]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) {
[121]750 MessageBay.errorMessage("Could not load child frame.");
[4]751 return null;
752 }
753
754 // find the first non-title and non-name item
[70]755 List<Item> body = new ArrayList<Item>();
[72]756 if (textOnly)
[70]757 body.addAll(child.getBodyTextItems(false));
758 else
759 body.addAll(child.getItems());
[4]760 Item item = null;
761
762 for (Item i : body)
[80]763 if (i != child.getTitleItem() && !i.isAnnotation()) {
[4]764 item = i;
765 break;
766 }
767
768 // if no item was found
769 if (item == null) {
[121]770 MessageBay.displayMessage("No item found to copy");
[4]771 return null;
772 }
773
774 return item;
775 }
[163]776
[162]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());
[156]786
[162]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());
[163]799
[162]800 return body;
801 }
802
[156]803 public static void calculate(Frame frame, Item toCalculate) {
804 if (toCalculate instanceof Text) {
805 Text text = (Text) toCalculate;
[161]806 ExpediteeJEP myParser = new ExpediteeJEP();
807 myParser.addVariables(frame);
808 String linkedFrame = toCalculate.getAbsoluteLink();
809 if (linkedFrame != null) {
810 myParser.addVariables(FrameIO.LoadFrame(linkedFrame));
[156]811 }
[162]812 myParser.resetObserver();
[160]813
[156]814 // Do the calculation
[190]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);
[390]821 text.setText(result.toString(), true);
[190]822 text.setFormula(formulaFullCase);
823 if (text.isFloating()) {
824 text.setPosition(FrameMouseActions.MouseX,
825 FrameMouseActions.MouseY);
826 FrameMouseActions.resetOffset();
[161]827 } else {
[190]828 text.getParentOrCurrentFrame().change();
[156]829 }
[190]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();
[156]837 }
838 }
839 }
[181]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 }
[242]851
[278]852 public static void attachToCursor(Collection<Item> items) {
853 for (Item i : items) {
854 i.setParent(null);
[311]855 i.invalidateAll();
[278]856 }
857 FrameMouseActions.pickup(items);
[311]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);
[278]861 }
862
[247]863 public static void importFiles(Item item) {
[242]864 List<File> files = new LinkedList<File>();
[282]865 for (String s : item.getText().split("\\s+")) {
866 File file = new File(s.trim());
[247]867 if (file.exists()) {
[242]868 files.add(file);
869 }
870 }
871 try {
872 FrameDNDTransferHandler.getInstance().importFileList(files,
873 FrameMouseActions.getPosition());
874 } catch (Exception e) {
875 }
876 }
[247]877
878 public static void importFile(Item item) {
[282]879 File file = new File(item.getText().trim());
[247]880 if (file.exists()) {
881 try {
882 FrameDNDTransferHandler.getInstance().importFile(file,
883 FrameMouseActions.getPosition());
884 } catch (Exception e) {
885 e.printStackTrace();
886 }
887 }
[242]888 }
[247]889
[278]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
[247]899 if (sides < 3) {
900 MessageBay.errorMessage("Shapes must have at least 3 sides");
901 }
[278]902 double angle = -(180 - ((sides - 2) * 180.0F) / sides);
[247]903 double curAngle = 0;
904 double size = 50F;
[282]905 if (item.isLineEnd() && item.getLines().size() > 0) {
[247]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);
[294]936 if (item instanceof Text) {
937 for (Item i : item.getAllConnected()) {
938 if (i instanceof Line) {
[278]939 item = i;
940 break;
941 }
942 }
943 }
[294]944
945 Color newColor = item.getColor();
946 if (newColor != null) {
[278]947 d[0].setColor(item.getColor());
[294]948 if (item instanceof Text && item.getBackgroundColor() != null) {
949 d[0].setFillColor(item.getBackgroundColor());
[311]950 } else {
[294]951 d[0].setFillColor(item.getFillColor());
952 }
[278]953 }
[294]954 float newThickness = item.getThickness();
955 if (newThickness > 0) {
956 d[0].setThickness(newThickness);
957 }
[247]958
959 ItemUtils.EnclosedCheck(newItems);
960 FrameGraphics.refresh(false);
[278]961
962 return d[0];
[247]963 }
[294]964
[284]965 public static void StopReminder() {
966 Reminders.stop();
967 }
[311]968
969 public static void print(String file) {
[309]970 try {
[464]971 if (Browser._theBrowser.isMinimumVersion6()) {
[309]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 }
[362]980
981 public static int wordCount(String paragraph) {
982 return paragraph.trim().split("\\s+").length + 1;
983 }
[376]984
[362]985 public static int wordCount(Frame frame) {
986 int count = 0;
[376]987
988 for (Text t : frame.getBodyTextItems(false)) {
[362]989 count += wordCount(t.getText());
990 }
[376]991
[362]992 return count;
993 }
[376]994
995 public static void moveToPublic(Frame frame) {
[362]996 FrameIO.moveFrameset(frame.getFramesetName(), FrameIO.PUBLIC_PATH);
997 }
[376]998
999 public static void moveToPrivate(Frame frame) {
[362]1000 FrameIO.moveFrameset(frame.getFramesetName(), FrameIO.FRAME_PATH);
1001 }
[376]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 }
[514]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 }
[4]1083}
Note: See TracBrowser for help on using the repository browser.