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

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