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

Last change on this file since 1079 was 1079, checked in by davidb, 8 years ago

Comments added to track some useful StackOverflow articles on custom git-merging

File size: 44.1 KB
Line 
1/**
2 * Misc.java
3 * Copyright (C) 2010 New Zealand Digital Library, http://expeditee.org
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19package org.expeditee.actions;
20
21import java.awt.Color;
22import java.awt.Desktop;
23import java.awt.Image;
24import java.awt.image.BufferedImage;
25import java.awt.image.VolatileImage;
26import java.io.BufferedReader;
27import java.io.File;
28import java.io.FileNotFoundException;
29import java.io.IOException;
30import java.io.InputStream;
31import java.io.InputStreamReader;
32import java.lang.reflect.Method;
33import java.net.URI;
34import java.net.URISyntaxException;
35import java.net.URL;
36import java.net.URLClassLoader;
37import java.util.ArrayList;
38import java.util.Collection;
39import java.util.LinkedList;
40import java.util.List;
41import java.util.Map;
42import java.util.Map.Entry;
43import java.util.Set;
44import java.util.jar.Attributes;
45import java.util.jar.JarFile;
46
47import javax.imageio.ImageIO;
48
49import org.expeditee.gui.AttributeUtils;
50import org.expeditee.gui.Browser;
51import org.expeditee.io.Conversion;
52import org.expeditee.gui.DisplayIO;
53import org.expeditee.io.ExpReader;
54import org.expeditee.gui.Frame;
55import org.expeditee.gui.FrameGraphics;
56import org.expeditee.gui.FrameIO;
57import org.expeditee.gui.FrameKeyboardActions;
58import org.expeditee.gui.FrameMouseActions;
59import org.expeditee.gui.FrameUtils;
60import org.expeditee.gui.FreeItems;
61import org.expeditee.gui.MessageBay;
62import org.expeditee.gui.MessageBay.Progress;
63import org.expeditee.gui.Reminders;
64import org.expeditee.gui.TimeKeeper;
65import org.expeditee.importer.FrameDNDTransferHandler;
66import org.expeditee.items.Item;
67import org.expeditee.items.ItemUtils;
68import org.expeditee.items.Line;
69import org.expeditee.items.Text;
70import org.expeditee.items.XRayable;
71import org.expeditee.items.widgets.InteractiveWidget;
72import org.expeditee.items.widgets.WidgetCorner;
73import org.expeditee.items.widgets.WidgetEdge;
74import org.expeditee.math.ExpediteeJEP;
75import org.expeditee.settings.UserSettings;
76import org.expeditee.simple.SString;
77import org.expeditee.stats.CometStats;
78import org.expeditee.stats.DocumentStatsFast;
79import org.expeditee.stats.SessionStats;
80import org.expeditee.stats.StatsLogger;
81import org.expeditee.stats.TreeStats;
82import org.nfunk.jep.Node;
83import org.nfunk.jep.ParseException;
84
85import com.lowagie.text.Font;
86
87
88
89/**
90 * A list of miscellaneous Actions and Actions specific to Expeditee
91 *
92 */
93public class Misc {
94
95 /**
96 * Causes the system to beep
97 */
98 public static void beep() {
99 java.awt.Toolkit.getDefaultToolkit().beep();
100 }
101
102 /**
103 * Returns an Item located at the specified position.
104 * kgas1 - 23/01/2012
105 * @param x
106 * @param y
107 * @return
108 */
109 public static Item getItemAtPosition(int x, int y, Frame f)
110 {
111 Frame current = f;
112 List<Item> allItems = current.getItems();
113
114 for(Item i : allItems)
115 {
116 if(i.getX() == x && i.getY() == y)
117 return i;
118 }
119
120 return null;
121 }
122
123 /**
124 * Returns an item containing a specified piece of data.
125 * kgas1 - 7/06/2012
126 * @param s
127 * @param f
128 * @return
129 */
130 public static Item getItemContainingData(String s, Frame f){
131
132 Frame current = f;
133
134 List<Item> allItems = current.getItems();
135
136
137 for(Item i : allItems){
138
139
140 if(i.getData() != null && i.getData().size() > 0){
141 if(i.getData().contains(s)){
142 return i;
143 }
144 }
145 }
146
147 return null;
148 }
149
150 public static void openURL(Item item){
151
152 if(item.getData() != null && item.getData().size() > 0){
153
154 String url = item.getData().get(0);
155 openURL(url);
156 }
157
158 //openURL("http://www.google.com");
159 }
160 /**
161 * Treats a string as a URL and attempts to open it
162 */
163 public static void openURL(String siteURL){
164
165 try {
166 URL check = new URL(siteURL);
167 Desktop.getDesktop().browse(new URI(siteURL));
168
169 } catch (IOException| URISyntaxException e) {
170
171 MessageBay.displayMessage("'" + siteURL + "' is not a valid URL");
172 }
173 }
174 /**
175 * Backs up the current frame as a default and saves it to the file
176 */
177 public static void setRestorePoint()
178 {
179 Frame current = DisplayIO.getCurrentFrame();
180 current.change();
181 FrameIO.SaveFrameAsRestore(current, true, true);
182 }
183 /**
184 * Forces a repaint of the current Frame
185 */
186 public static void display() {
187 FrameGraphics.refresh(false);
188 }
189
190 public static String getWindowSize() {
191 return Browser.getWindows()[0].getSize().toString();
192 }
193
194 /**
195 * Restores the current frame to the last saved version currently on the
196 * hard disk
197 */
198 public static void restore() {
199 FrameIO.Reload();
200 // MessageBay.displayMessage("Restoration complete.");
201 }
202
203 /**
204 * Toggles AudienceMode on or off
205 */
206 public static void toggleAudienceMode() {
207 FrameGraphics.ToggleAudienceMode();
208 }
209
210 /**
211 * Toggles TwinFrames mode on or off
212 */
213 public static void toggleTwinFramesMode() {
214 DisplayIO.ToggleTwinFrames();
215 }
216
217 /**
218 * If the given Item is a Text Item, then the text of the Item is
219 * interpreted as actions, if not this method does nothing.
220 *
221 * @param current
222 * The Item to read the Actions from
223 */
224 public static void runItem(Item current) throws Exception {
225 if (current instanceof Text) {
226 List<String> actions = ((Text) current).getTextList();
227 for (String action : actions) {
228 if (!action.equalsIgnoreCase("runitem")) {
229 Actions.PerformAction(DisplayIO.getCurrentFrame(), current,
230 action);
231 }
232 }
233 } else {
234 MessageBay.errorMessage("Item must be a text item.");
235 }
236 }
237
238 /**
239 * Prompts the user to confirm deletion of the current Frame, and deletes if
240 * the user chooses. After deletion this action calls back(), to ensure the
241 * deleted frame is not still being shown
242 *
243 */
244 public static void DeleteFrame(Frame toDelete) {
245 String deletedFrame = toDelete.getName();
246 String deletedFrameNameLowercase = deletedFrame.toLowerCase();
247 String errorMessage = "Error deleting " + deletedFrame;
248 try {
249 String deletedFrameName = FrameIO.DeleteFrame(toDelete);
250 if (deletedFrameName != null) {
251 DisplayIO.Back();
252 // Remove any links on the previous frame to the one being
253 // deleted
254 Frame current = DisplayIO.getCurrentFrame();
255 for (Item i : current.getItems())
256 if (i.getLink() != null
257 && i.getAbsoluteLink().toLowerCase().equals(
258 deletedFrameNameLowercase)) {
259 i.setLink(null);
260 }
261 MessageBay.displayMessage(deletedFrame + " renamed "
262 + deletedFrameName);
263 // FrameGraphics.Repaint();
264 return;
265 }
266 } catch (IOException ioe) {
267 if (ioe.getMessage() != null)
268 errorMessage += ". " + ioe.getMessage();
269 } catch (SecurityException se) {
270 if (se.getMessage() != null)
271 errorMessage += ". " + se.getMessage();
272 } catch (Exception e) {
273 e.printStackTrace();
274 }
275 MessageBay.errorMessage(errorMessage);
276 }
277
278 /**
279 * Loads the Frame linked to by the given Item. The first Item on the Frame
280 * that is not the title or name is then placed on the cursor. If the given
281 * Item has no link, or no item is found then this is a no-op.
282 *
283 * @param current
284 * The Item that links to the Frame that the Item will be loaded
285 * from.
286 */
287 public static Item GetItemFromChildFrame(Item current) {
288 return getFromChildFrame(current, false);
289 }
290
291 public static void GetItemsFromChildFrame(Item current) {
292 getItemsFromChildFrame(current, false);
293 }
294
295 /**
296 * Loads the Frame linked to by the given Item. The first Text Item on the
297 * Frame that is not the title or name is then placed on the cursor. If the
298 * given Item has no link, or no item is found then this is a no-op.
299 *
300 * @param current
301 * The Item that links to the Frame that the Item will be loaded
302 * from.
303 */
304 public static Item GetTextFromChildFrame(Item current) {
305 return getFromChildFrame(current, true);
306 }
307
308 private static Item getFromChildFrame(Item current, boolean textOnly) {
309 Item item = getFirstBodyItemOnChildFrame(current, textOnly);
310 // if no item was found
311 if (item != null) {
312 // copy the item and switch
313 item = item.copy();
314 item.setPosition(DisplayIO.getMouseX(), FrameMouseActions.getY());
315 }
316 return item;
317 }
318
319 private static void getItemsFromChildFrame(Item current, boolean textOnly) {
320 Collection<Item> items = getItemsOnChildFrame(current, textOnly);
321 // if no item was found
322 if (items == null || items.size() == 0) {
323 return;
324 }
325
326 // copy the item and switch
327 Collection<Item> copies = ItemUtils.CopyItems(items);
328 Item first = items.iterator().next();
329 float deltaX = DisplayIO.getMouseX() - first.getX();
330 float deltaY = FrameMouseActions.getY() - first.getY();
331 for (Item i : copies) {
332 if (i.isVisible())
333 i.setXY(i.getX() + deltaX, i.getY() + deltaY);
334 i.setParent(null);
335 }
336 FrameMouseActions.pickup(copies);
337 FrameGraphics.Repaint();
338 }
339
340 /**
341 * Sets the given Item to have the Given Color. Color can be null (for
342 * default)
343 *
344 * @param toChange
345 * The Item to set the Color.
346 * @param toUse
347 * The Color to give the Item.
348 */
349 public static void SetItemBackgroundColor(Item toChange, Color toUse) {
350 if (toChange == null)
351 return;
352
353 toChange.setBackgroundColor(toUse);
354 FrameGraphics.Repaint();
355 }
356
357 /**
358 * Sets the given Item to have the Given Color. Color can be null (for
359 * default)
360 *
361 * @param toChange
362 * The Item to set the Color.
363 * @param toUse
364 * The Color to give the Item.
365 */
366 public static void SetItemColor(Item toChange, Color toUse) {
367 if (toChange == null)
368 return;
369
370 toChange.setColor(toUse);
371 FrameGraphics.Repaint();
372 }
373
374 /**
375 * Creates a new Text Object containing general statistics for the current
376 * session. The newly created Text Object is then attached to the cursor via
377 * FrameMouseActions.pickup(Item)
378 */
379 public static void GetSessionStats() {
380 attachStatsToCursor(SessionStats.getCurrentStats());
381 }
382
383 /**
384 * Creates a new Text Object containing statistics for the current tree.
385 */
386 public static String GetCometStats(Frame frame) {
387 TimeKeeper timer = new TimeKeeper();
388 MessageBay.displayMessage("Computing comet stats...");
389 CometStats cometStats = new CometStats(frame);
390 String result = cometStats.toString();
391 MessageBay.overwriteMessage("Comet stats time: "
392 + timer.getElapsedStringSeconds());
393 return result;
394 }
395
396 public static String GetTreeStats(Frame frame) {
397 TimeKeeper timer = new TimeKeeper();
398 MessageBay.displayMessage("Computing tree stats...");
399
400 TreeStats treeStats = new TreeStats(frame);
401 String result = treeStats.toString();
402 MessageBay.overwriteMessage("Tree stats time: "
403 + timer.getElapsedStringSeconds());
404 return result;
405
406 }
407
408 public static String GetDocumentStats(Frame frame) {
409 TimeKeeper timer = new TimeKeeper();
410 MessageBay.displayMessage("Computing document stats...");
411 FrameIO.ForceSaveFrame(frame);
412 DocumentStatsFast docStats = new DocumentStatsFast(frame.getName(),
413 frame.getTitle());
414 String result = docStats.toString();
415
416 MessageBay.overwriteMessage("Document stats time: "
417 + timer.getElapsedStringSeconds());
418 return result;
419
420 }
421
422 /**
423 * Creates a text item and attaches it to the cursor.
424 *
425 * @param itemText
426 * the text to attach to the cursor
427 */
428 public static void attachStatsToCursor(String itemText) {
429 SessionStats.CreatedText();
430 Frame current = DisplayIO.getCurrentFrame();
431 Item text = current.getStatsTextItem(itemText);
432 FrameMouseActions.pickup(text);
433 FrameGraphics.Repaint();
434 }
435
436 public static void attachTextToCursor(String itemText) {
437 SessionStats.CreatedText();
438 Frame current = DisplayIO.getCurrentFrame();
439 Item text = current.getTextItem(itemText);
440 FrameMouseActions.pickup(text);
441 FrameGraphics.Repaint();
442 }
443
444 /**
445 * Creates a new Text Object containing statistics for moving, deleting and
446 * creating items in the current session. The newly created Text Object is
447 * then attached to the cursor via FrameMouseActions.pickup(Item)
448 */
449 public static String getItemStats() {
450 return SessionStats.getItemStats();
451 }
452
453 /**
454 * Creates a new Text Object containing statistics for the time between
455 * events triggered by the user through mouse clicks and key presses. The
456 * newly created Text Object is then attached to the cursor via
457 * FrameMouseActions.pickup(Item)
458 */
459 public static String getEventStats() {
460 return SessionStats.getEventStats();
461 }
462
463 /**
464 * Creates a new Text Object containing the contents of the current frames
465 * file.
466 */
467 public static String getFrameFile(Frame frame) {
468 return FrameIO.ForceSaveFrame(frame);
469 }
470
471 /**
472 * Creates a new Text Object containing the available fonts.
473 */
474 public static String getFontNames() {
475 Collection<String> availableFonts = Actions.getFonts().values();
476 StringBuilder fontsList = new StringBuilder();
477 for (String s : availableFonts) {
478 fontsList.append(s).append(Text.LINE_SEPARATOR);
479 }
480 fontsList.deleteCharAt(fontsList.length() - 1);
481
482 return fontsList.toString();
483 }
484 /**
485 * Creates a new Text Object containing the available fonts already loaded into Expeditee.
486 */
487 public static String getExpediteeFontNames(){
488
489 StringBuilder fontsList = new StringBuilder();
490
491 for (String s: Text.FONT_WHEEL){
492
493 fontsList.append(s).append(Text.LINE_SEPARATOR);
494 }
495
496 for (Entry<String, java.awt.Font> entry: Text.FONT_WHEEL_ADDITIONAL_LOOKUP.entrySet()){
497
498 String fontName = entry.getKey();
499 fontsList.append(fontName).append(Text.LINE_SEPARATOR);
500 }
501 //add the default soon too
502 fontsList.deleteCharAt(fontsList.length() - 1);
503 return fontsList.toString();
504 }
505
506 public static String getUnicodeCharacters(int start, int finish) {
507 if (start < 0 && finish < 0) {
508 throw new RuntimeException("Parameters must be non negative");
509 }
510 // Swap the start and finish if they are inthe wrong order
511 if (start > finish) {
512 start += finish;
513 finish = start - finish;
514 start = start - finish;
515 }
516 StringBuilder charList = new StringBuilder();
517 int count = 0;
518 charList.append(String.format("Unicode block 0x%x - 0x%x", start,
519 finish));
520 System.out.println();
521 // charList.append("Unicode block: ").append(String.format(format,
522 // args))
523 for (char i = (char) start; i < (char) finish; i++) {
524 if (Character.isDefined(i)) {
525 if (count++ % 64 == 0)
526 charList.append(Text.LINE_SEPARATOR);
527 charList.append(Character.valueOf(i));
528 }
529 }
530 return charList.toString();
531 }
532
533 /**
534 * Gets a single block of Unicode characters.
535 *
536 * @param start
537 * the start of the block
538 */
539 public static String getUnicodeCharacters(int start) {
540 return getUnicodeCharacters(start, start + 256);
541 }
542
543 /**
544 * Get a single Unicode character
545 *
546 * @param codePoint
547 * the Unicode codePoint
548 */
549 public static String getUnicodeCharacter(int codePoint) {
550 char codePointChar = (char) codePoint;
551 if (Character.isDefined(codePointChar)) {
552 return Character.valueOf(codePointChar).toString();
553 }
554 else {
555 MessageBay.errorMessage("Character value '" + codePoint +"' not defined");
556 return "";
557 }
558 }
559
560 public static String getMathSymbols() {
561 return getUnicodeCharacters('\u2200', '\u2300');
562 }
563
564 /**
565 * Resets the statistics back to zero.
566 */
567 public static void repaint() {
568 StatsLogger.WriteStatsFile();
569 SessionStats.resetStats();
570 }
571
572 /**
573 * Loads a frame with the given name and saves it as a JPEG image.
574 *
575 * @param framename
576 * The name of the Frame to save
577 */
578 public static void jpegFrame(String framename) {
579 ImageFrame(framename, "JPEG");
580 }
581
582 /**
583 * Saves the current frame as a JPEG image. This is the same as calling
584 * JpegFrame(currentFrame.getName())
585 */
586 public static void jpegFrame() {
587 ImageFrame(DisplayIO.getCurrentFrame().getName(), "JPEG");
588 }
589
590 public static void jpgFrame() {
591 jpegFrame();
592 }
593
594 /**
595 * Loads a frame with the given name and saves it as a PNG image.
596 *
597 * @param framename
598 * The name of the Frame to save
599 */
600 public static void PNGFrame(String framename) {
601 ImageFrame(framename, "PNG");
602 }
603
604 /**
605 * Saves the current frame as a PNG image. This is the same as calling
606 * PNGFrame(currentFrame.getName())
607 */
608 public static void PNGFrame(Frame frame) {
609 ImageFrame(frame.getName(), "PNG");
610 }
611
612 public static String SaveImage(BufferedImage screen, String format,
613 String directory, String fileName) {
614 String suffix = "." + format.toLowerCase();
615 String shortFileName = fileName;
616 // Check if we need to append the suffix
617 if (fileName.indexOf('.') < 0)
618 fileName += suffix;
619 else
620 shortFileName = fileName.substring(0, fileName.length() - suffix.length());
621
622 try {
623 int count = 2;
624 // set up the file for output
625 File out = new File(directory + fileName);
626 while (out.exists()) {
627 fileName = shortFileName + "_" + count++ + suffix;
628 out = new File(directory + fileName);
629 }
630
631 if (!out.getParentFile().exists())
632 out.mkdirs();
633
634 // If the image is successfully written out return the fileName
635 if (ImageIO.write(screen, format, out))
636 return fileName;
637
638 } catch (Exception e) {
639 e.printStackTrace();
640 }
641 return null;
642 }
643
644 public static String ImageFrame(Frame frame, String format, String directory) {
645 assert (frame != null);
646
647 Image oldBuffer = frame.getBuffer();
648 frame.setBuffer(null);
649 // Jpeg only works properly with volitile frames
650 // Png transparency only works with bufferedImage form
651 Image frameBuffer = FrameGraphics.getBuffer(frame, false, format
652 .equalsIgnoreCase("jpeg"));
653 // Make sure overlay stuff doesnt disapear on the frame visible on the
654 // screen
655 frame.setBuffer(oldBuffer);
656 BufferedImage screen = null;
657
658 if (frameBuffer instanceof VolatileImage) {
659 // If its the current frame it will be a volitive image
660 screen = ((VolatileImage) frameBuffer).getSnapshot();
661 } else {
662 assert (frameBuffer instanceof BufferedImage);
663 screen = (BufferedImage) frameBuffer;
664 }
665 return SaveImage(screen, format, directory, frame.getExportFileName());
666 }
667
668 /**
669 * Saves the Frame with the given Framename as an image of the given format.
670 *
671 * @param framename
672 * The name of the Frame to save as an image
673 * @param format
674 * The Image format to use (i.e. "PNG", "BMP", etc)
675 */
676 public static void ImageFrame(String framename, String format) {
677 Frame loaded = FrameIO.LoadFrame(framename);
678
679 // if the frame was loaded successfully
680 if (loaded != null) {
681 String path = FrameIO.EXPORTS_DIR;
682 String frameName = ImageFrame(loaded, format, path);
683 if (frameName != null)
684 MessageBay.displayMessage("Frame successfully saved to " + path
685 + frameName);
686 else
687 MessageBay.errorMessage("Could not find image writer for "
688 + format + " format");
689 // if the frame was not loaded successfully, alert the user
690 } else {
691 MessageBay.displayMessage("Frame '" + framename
692 + "' could not be found.");
693 }
694 }
695
696 public static void MessageLn(Item message) {
697 if (message instanceof Text)
698 MessageBay.displayMessage((Text) message);
699 }
700
701 /**
702 * Displays a message in the message box area.
703 *
704 * @param message
705 * the message to display
706 */
707 public static void MessageLn(String message) {
708 MessageBay.displayMessage(message);
709 }
710
711 public static void MessageLn2(String message, String message2) {
712 MessageBay.displayMessage(message + " " + message2);
713 }
714
715 public static void CopyFile(String existingFile, String newFileName) {
716 try {
717 // TODO is there a built in method which will do this faster?
718
719 MessageBay.displayMessage("Copying file " + existingFile + " to "
720 + newFileName + "...");
721 FrameIO.copyFile(existingFile, newFileName);
722 MessageBay.displayMessage("File copied successfully");
723 } catch (FileNotFoundException e) {
724 MessageBay.displayMessage("Error opening file: " + existingFile);
725 } catch (Exception e) {
726 MessageBay.displayMessage("File could not be copied");
727 }
728 }
729
730 /**
731 * Runs two methods alternatively a specified number of times and reports on
732 * the time spent running each method.
733 *
734 * @param fullMethodNameA
735 * @param fullMethodNameB
736 * @param repsPerTest
737 * the number of time each method is run per test
738 * @param tests
739 * the number of tests to conduct
740 *
741 */
742 public static void CompareMethods(String fullMethodNameA,
743 String fullMethodNameB, int repsPerTest, int tests) {
744 try {
745 String classNameA = getClassName(fullMethodNameA);
746 String classNameB = getClassName(fullMethodNameB);
747 String methodNameA = getMethodName(fullMethodNameA);
748 String methodNameB = getMethodName(fullMethodNameB);
749
750 Class<?> classA = Class.forName(classNameA);
751 Class<?> classB = Class.forName(classNameB);
752 Method methodA = classA.getDeclaredMethod(methodNameA,
753 new Class[] {});
754 Method methodB = classB.getDeclaredMethod(methodNameB,
755 new Class[] {});
756 TimeKeeper timeKeeper = new TimeKeeper();
757 long timeA = 0;
758 long timeB = 0;
759 // Run the tests
760 for (int i = 0; i < tests; i++) {
761 // Test methodA
762 timeKeeper.restart();
763 for (int j = 0; j < repsPerTest; j++) {
764 methodA.invoke((Object) null, new Object[] {});
765 }
766 timeA += timeKeeper.getElapsedMillis();
767 timeKeeper.restart();
768 // Test methodB
769 for (int j = 0; j < repsPerTest; j++) {
770 methodB.invoke((Object) null, new Object[] {});
771 }
772 timeB += timeKeeper.getElapsedMillis();
773 }
774
775 float aveTimeA = timeA * 1000F / repsPerTest / tests;
776 float aveTimeB = timeB * 1000F / repsPerTest / tests;
777 // Display Results
778 MessageBay.displayMessage("Average Execution Time");
779 MessageBay.displayMessage(methodNameA + ": "
780 + TimeKeeper.Formatter.format(aveTimeA) + "us");
781 MessageBay.displayMessage(methodNameB + ": "
782 + TimeKeeper.Formatter.format(aveTimeB) + "us");
783 } catch (Exception e) {
784 MessageBay.errorMessage(e.getClass().getSimpleName() + ": "
785 + e.getMessage());
786 }
787 }
788
789 public static String getClassName(String fullMethodName) {
790 assert (fullMethodName != null);
791 assert (fullMethodName.length() > 0);
792 int lastPeriod = fullMethodName.lastIndexOf('.');
793 if (lastPeriod > 0 && lastPeriod < fullMethodName.length() - 1)
794 return fullMethodName.substring(0, lastPeriod);
795 throw new RuntimeException("Invalid method name: " + fullMethodName);
796 }
797
798 public static String getMethodName(String methodName) {
799 assert (methodName != null);
800 assert (methodName.length() > 0);
801 int lastPeriod = methodName.lastIndexOf('.');
802 if (lastPeriod > 0 && lastPeriod < methodName.length() - 1)
803 return methodName.substring(1 + lastPeriod);
804 throw new RuntimeException("Invalid method name: " + methodName);
805 }
806
807 /**
808 * Loads the Frame linked to by the given Item. The first Item on the Frame
809 * that is not the title or name is then placed on the current frame. The
810 * item that was clicked on is placed on the frame it was linked to and the
811 * link is switched to the item from the child frame. If the given Item has
812 * no link, or no item is found then this is a no-op.
813 *
814 * @param current
815 * The Item that links to the Frame that the Item will be loaded
816 * from.
817 */
818 public static void SwapItemWithItemOnChildFrame(Item current) {
819 Item item = getFirstBodyItemOnChildFrame(current, false);
820 // if no item was found
821 if (item == null) {
822 return;
823 }
824
825 // swap the items parents
826 Frame parentFrame = current.getParent();
827 Frame childFrame = item.getParent();
828 current.setParent(childFrame);
829 item.setParent(parentFrame);
830
831 // swap the items on the frames
832 parentFrame.removeItem(current);
833 childFrame.removeItem(item);
834 parentFrame.addItem(item);
835 childFrame.addItem(current);
836
837 // swap the items links
838 item.setActions(current.getAction());
839 item.setLink(childFrame.getName());
840 current.setLink(parentFrame.getName());
841 // current.setLink(null);
842 current.setActions(null);
843
844 FrameGraphics.Repaint();
845 }
846
847 private static Item getFirstBodyItemOnChildFrame(Item current,
848 boolean textOnly) {
849 // the item must link to a frame
850 if (current.getLink() == null) {
851 MessageBay
852 .displayMessage("Cannot get item from child - this item has no link");
853 return null;
854 }
855
856 Frame child = FrameIO.LoadFrame(current.getAbsoluteLink());
857
858 // if the frame could not be loaded
859 if (child == null) {
860 MessageBay.errorMessage("Could not load child frame.");
861 return null;
862 }
863
864 // find the first non-title and non-name item
865 List<Item> body = new ArrayList<Item>();
866 if (textOnly)
867 body.addAll(child.getBodyTextItems(false));
868 else
869 body.addAll(child.getItems());
870 Item item = null;
871
872 for (Item i : body)
873 if (i != child.getTitleItem() && !i.isAnnotation()) {
874 item = i;
875 break;
876 }
877
878 // if no item was found
879 if (item == null) {
880 MessageBay.displayMessage("No item found to copy");
881 return null;
882 }
883
884 return item;
885 }
886
887 private static Collection<Item> getItemsOnChildFrame(Item current,
888 boolean textOnly) {
889 // the item must link to a frame
890 if (current.getLink() == null) {
891 MessageBay
892 .displayMessage("Cannot get item from child - this item has no link");
893 return null;
894 }
895 Frame child = FrameIO.LoadFrame(current.getAbsoluteLink());
896
897 // if the frame could not be loaded
898 if (child == null) {
899 MessageBay.errorMessage("Could not load child frame.");
900 return null;
901 }
902
903 // find the first non-title and non-name item
904 Collection<Item> body = new ArrayList<Item>();
905 if (textOnly)
906 body.addAll(child.getBodyTextItems(false));
907 else
908 body.addAll(child.getItems());
909
910 return body;
911 }
912
913 public static void calculate(Frame frame, Item toCalculate) {
914 if (toCalculate instanceof Text) {
915 Text text = (Text) toCalculate;
916 ExpediteeJEP myParser = new ExpediteeJEP();
917 myParser.addVariables(frame);
918 String linkedFrame = toCalculate.getAbsoluteLink();
919 if (linkedFrame != null) {
920 myParser.addVariables(FrameIO.LoadFrame(linkedFrame));
921 }
922 myParser.resetObserver();
923
924 // Do the calculation
925 String formulaFullCase = text.getText().replace('\n', ' ');
926 String formula = formulaFullCase.toLowerCase();
927
928 try {
929 Node node = myParser.parse(formula);
930 Object result = myParser.evaluate(node);
931 text.setText(result.toString(), true);
932 text.setFormula(formulaFullCase);
933 if (text.isFloating()) {
934 text.setPosition(FrameMouseActions.MouseX,
935 FrameMouseActions.MouseY);
936 FrameMouseActions.resetOffset();
937 } else {
938 text.getParentOrCurrentFrame().change();
939 }
940 } catch (ParseException e) {
941 MessageBay.errorMessage("Parse error "
942 + e.getMessage().replace("\n", ""));
943 } catch (Exception e) {
944 MessageBay.errorMessage("evaluation error "
945 + e.getMessage().replace("\n", ""));
946 e.printStackTrace();
947 }
948 }
949 }
950
951 /**
952 * Attach an item to the cursor.
953 *
954 * @param item
955 */
956 public static void attachToCursor(Item item) {
957 item.setParent(null);
958 FrameMouseActions.pickup(item);
959 FrameGraphics.Repaint();
960 }
961
962 public static void attachToCursor(Collection<Item> items) {
963 for (Item i : items) {
964 i.setParent(null);
965 i.invalidateAll();
966 }
967 FrameMouseActions.pickup(items);
968 // TODO figure out why this isnt repainting stuff immediately
969 // All of text item doesnt repaint until the cursor is moved
970 FrameGraphics.requestRefresh(true);
971 }
972
973 public static void importFiles(Item item) {
974 List<File> files = new LinkedList<File>();
975 for (String s : item.getText().split("\\s+")) {
976 File file = new File(s.trim());
977 if (file.exists()) {
978 files.add(file);
979 }
980 }
981 try {
982 FrameDNDTransferHandler.getInstance().importFileList(files,
983 FrameMouseActions.getPosition());
984 } catch (Exception e) {
985 }
986 }
987
988 public static void importFile(Item item) {
989 File file = new File(item.getText().trim());
990 if (file.exists()) {
991 try {
992 FrameDNDTransferHandler.getInstance().importFile(file,
993 FrameMouseActions.getPosition());
994 } catch (Exception e) {
995 e.printStackTrace();
996 }
997 }
998 }
999
1000 public static Item createPolygon(Item item, int sides) {
1001 if (item instanceof Text) {
1002 try {
1003 SString s = new SString(item.getText());
1004 sides = s.integerValue().intValue();
1005 } catch (NumberFormatException e) {
1006 }
1007 }
1008
1009 if (sides < 3) {
1010 MessageBay.errorMessage("Shapes must have at least 3 sides");
1011 }
1012 double angle = -(180 - ((sides - 2) * 180.0F) / sides);
1013 double curAngle = 0;
1014 double size = 50F;
1015 if (item.isLineEnd() && item.getLines().size() > 0) {
1016 item = item.getLines().get(0);
1017 }
1018 // Use line length to determine the size of the shape
1019 if (item instanceof Line) {
1020 size = ((Line) item).getLength();
1021 }
1022
1023 float curX = FrameMouseActions.MouseX;
1024 float curY = FrameMouseActions.MouseY;
1025
1026 Collection<Item> newItems = new LinkedList<Item>();
1027 Item[] d = new Item[sides];
1028 // create dots
1029 Frame current = DisplayIO.getCurrentFrame();
1030 for (int i = 0; i < d.length; i++) {
1031 d[i] = current.createDot();
1032 newItems.add(d[i]);
1033 d[i].setPosition(curX, curY);
1034 curX += (float) (Math.cos((curAngle) * Math.PI / 180.0) * size);
1035 curY += (float) (Math.sin((curAngle) * Math.PI / 180.0) * size);
1036
1037 curAngle += angle;
1038 }
1039 // create lines
1040 for (int i = 1; i < d.length; i++) {
1041 newItems.add(new Line(d[i - 1], d[i], current.getNextItemID()));
1042 }
1043 newItems.add(new Line(d[d.length - 1], d[0], current.getNextItemID()));
1044
1045 current.addAllItems(newItems);
1046 if (item instanceof Text) {
1047 for (Item i : item.getAllConnected()) {
1048 if (i instanceof Line) {
1049 item = i;
1050 break;
1051 }
1052 }
1053 }
1054
1055 Color newColor = item.getColor();
1056 if (newColor != null) {
1057 d[0].setColor(item.getColor());
1058 if (item instanceof Text && item.getBackgroundColor() != null) {
1059 d[0].setFillColor(item.getBackgroundColor());
1060 } else {
1061 d[0].setFillColor(item.getFillColor());
1062 }
1063 }
1064 float newThickness = item.getThickness();
1065 if (newThickness > 0) {
1066 d[0].setThickness(newThickness);
1067 }
1068
1069 ItemUtils.EnclosedCheck(newItems);
1070 FrameGraphics.refresh(false);
1071
1072 return d[0];
1073 }
1074
1075 public static void StopReminder() {
1076 Reminders.stop();
1077 }
1078
1079 public static void print(String file) {
1080 try {
1081 if (Browser._theBrowser.isMinimumVersion6()) {
1082 if (Desktop.isDesktopSupported()) {
1083 Desktop.getDesktop().print(new File(file));
1084 }
1085 }
1086 } catch (Exception e) {
1087 MessageBay.errorMessage("Printing error: " + e.getMessage());
1088 }
1089 }
1090
1091 public static int wordCount(String paragraph) {
1092 return paragraph.trim().split("\\s+").length + 1;
1093 }
1094
1095 public static int wordCount(Frame frame) {
1096 int count = 0;
1097
1098 for (Text t : frame.getBodyTextItems(false)) {
1099 count += wordCount(t.getText());
1100 }
1101
1102 return count;
1103 }
1104
1105 public static void moveToPublic(Frame frame) {
1106 FrameIO.moveFrameset(frame.getFramesetName(), FrameIO.PUBLIC_PATH);
1107 }
1108
1109 public static void moveToPrivate(Frame frame) {
1110 FrameIO.moveFrameset(frame.getFramesetName(), FrameIO.FRAME_PATH);
1111 }
1112
1113 /**
1114 * Returns the value of a specified item attribute.
1115 *
1116 * @param item
1117 * from which to extract the value
1118 * @param attribute
1119 * name of an items attribute
1120 * @return the value of the attribute
1121 */
1122 public static String extract(Item item, String attribute) {
1123 return AttributeUtils.getAttribute(item, attribute);
1124 }
1125
1126 /**
1127 * Launches items.widgets.Browser and uses Text item as URL.
1128 * @param text Text item which passes contents as URL for browser.
1129 * @throws Exception
1130 */
1131 public static void startLoboBrowser(Item text) throws Exception {
1132 if (!(text instanceof Text)) {
1133 MessageBay.errorMessage("Must be a text item.");
1134 return;
1135 }
1136 if(text.getLink() != null) {
1137 MessageBay.errorMessage("Text item cannot have link.");
1138 return;
1139 }
1140
1141 FreeItems.getInstance().clear(); // remove url text from cursor
1142
1143 Text wt = new Text("@iw:org.expeditee.items.widgets.Browser"); // create new text item for browser widget
1144 wt.setParent(DisplayIO.getCurrentFrame()); // set parent of text source for InteractiveWidget.createWidget()
1145 wt.setXY(FrameMouseActions.getX(), FrameMouseActions.getY());
1146 // create widget from text item
1147 org.expeditee.items.widgets.Browser browser = (org.expeditee.items.widgets.Browser) InteractiveWidget.createWidget(wt);
1148
1149 if(FreeItems.textOnlyAttachedToCursor()) { // navigates to url specified by the text item
1150 browser.navigate(text.getText());
1151 } else {
1152 browser.navigate("http://www.waikato.ac.nz");
1153 }
1154
1155 FrameMouseActions.pickup(browser.getItems()); // attach browser widget to mouse
1156 }
1157
1158 /**
1159 * Text item becomes link to new frame containing items.widgets.Browser and uses Text item as URL for browser.
1160 * @param text Text item which passes contents as URL for browser and becomes link to the browser's new frame.
1161 * @throws Exception
1162 */
1163 public static void startLoboBrowserNewFrame(Item text) throws Exception {
1164 if (!(text instanceof Text)) {
1165 MessageBay.errorMessage("Must be a text item.");
1166 return;
1167 }
1168 if(text.getLink() != null) { // text item can't already have a link
1169 MessageBay.errorMessage("Text item already has link.");
1170 return;
1171 }
1172
1173 // Create new frame and text item for browser widget and parse created frame; loads browser widget
1174 Frame frame = FrameIO.CreateNewFrame(text);
1175 frame.addText(0, 50, "@iw:org.expeditee.items.widgets.Browser", null);
1176 FrameUtils.Parse(frame);
1177
1178 for(InteractiveWidget iw : frame.getInteractiveWidgets()) { // may be other widgets on frame
1179 if(iw instanceof org.expeditee.items.widgets.Browser) {
1180 // Set browser to 'full screen'
1181 iw.setSize(-1, -1, -1, -1, Browser._theBrowser.getWidth(), Browser._theBrowser.getHeight()
1182 - MessageBay.MESSAGE_BUFFER_HEIGHT - 80);
1183
1184 // If there is a text item attached to cursor use it as url for browser
1185 if(FreeItems.textOnlyAttachedToCursor()) {
1186 text.setLink("" + frame.getNumber());
1187 ((org.expeditee.items.widgets.Browser)iw).navigate(text.getText());
1188 } else {
1189 // Navigate to www.waikato.ac.nz by default if no url supplied and create new text item to be the link
1190 ((org.expeditee.items.widgets.Browser)iw).navigate("http://www.waikato.ac.nz");
1191 Text t = new Text("http://www.waikato.ac.nz");
1192 t.setParent(DisplayIO.getCurrentFrame()); // set parent of text source for InteractiveWidget.createWidget()
1193 t.setXY(FrameMouseActions.getX(), FrameMouseActions.getY());
1194 t.setLink("" + frame.getNumber()); // link url text to new browser frame
1195 FrameMouseActions.pickup(t); // Attach new text link to cursor
1196 }
1197 }
1198 }
1199
1200 FrameIO.SaveFrame(frame); // save frame to disk
1201 }
1202
1203 private static boolean startWidget(String name) throws Exception {
1204 String fullName = Actions.getClassName(name);
1205 if(fullName == null) {
1206 return false;
1207 }
1208 MessageBay.displayMessage("Creating new \"" + fullName + "\"");
1209
1210 FreeItems.getInstance().clear();
1211 Text wt = new Text("@iw:" + fullName); // create new text item for browser widget
1212 wt.setParent(DisplayIO.getCurrentFrame()); // set parent of text source for InteractiveWidget.createWidget()
1213 wt.setXY(FrameMouseActions.getX(), FrameMouseActions.getY()); // move to the mouse cursor
1214 InteractiveWidget widget = InteractiveWidget.createWidget(wt);
1215 FrameMouseActions.pickup(widget.getItems());
1216
1217 return true;
1218 }
1219
1220 private static void runUnknown(String command) throws Exception {
1221 if(startWidget(command)) {
1222 return;
1223 }
1224
1225 Actions.PerformAction(DisplayIO.getCurrentFrame(), null, command);
1226 }
1227
1228 public static void run(String command) throws Exception {
1229 if(command == null) {
1230 MessageBay.warningMessage("Please provide a command to run");
1231 return;
1232 }
1233 int firstSpace = command.indexOf(" ");
1234 if(firstSpace == -1) {
1235 runUnknown(command);
1236 return;
1237 }
1238 String argLower = command.toLowerCase();
1239 String name = argLower.substring(0, firstSpace).trim(); // first word
1240 String args = argLower.substring(firstSpace).trim(); // remainder after first word
1241 if(name == "action" || name == "agent") {
1242 if(args.length() > 0) {
1243 Actions.PerformAction(DisplayIO.getCurrentFrame(), null, args);
1244 } else {
1245 MessageBay.displayMessage("Please specify an action/agent name");
1246 }
1247 } else if(name == "widget") {
1248 if(args.length() > 0) {
1249 if(!startWidget(args)) {
1250 MessageBay.displayMessage("Widget \"" + name + "\" does not exist");
1251 }
1252 } else {
1253 MessageBay.displayMessage("Please specify a widget name");
1254 }
1255 } else {
1256 runUnknown(command);
1257 }
1258 }
1259
1260 public static void run(Item item) throws Exception {
1261 if(item == null) {
1262 MessageBay.warningMessage("Please provide a command to run");
1263 return;
1264 }
1265 run(((Text)item).getText());
1266 }
1267
1268 /**
1269 * Rebuilds the home frame restoring its original presentation.
1270 * Basically removes all items on the frame and reruns FrameUtils.CreateDefaultProfile().
1271 */
1272 public static void resetHomeFrame() {
1273 Frame homeFrame = FrameIO.LoadFrame(UserSettings.HomeFrame.get());
1274 homeFrame.removeAllItems(homeFrame.getItems());
1275 homeFrame.addText(0, 0, "title", null);
1276 FrameUtils.CreateDefaultProfile(UserSettings.UserName.get(), homeFrame);
1277 }
1278
1279 /**
1280 * Loads and runs an executable jar file in a new Thread
1281 * @param jar path to the jar file to run
1282 */
1283 public static void runJar(String jar) throws Exception {
1284 File jf = new File(jar);
1285 if(!jf.exists()) {
1286 System.err.println("jar '" + jar + "' could not be found");
1287 return;
1288 }
1289 JarFile jarFile = new JarFile(jf);
1290
1291 String mainClassName = (String) jarFile.getManifest().getMainAttributes().get(new Attributes.Name("Main-Class"));
1292 if(mainClassName == null) {
1293 System.err.println("jar '" + jar + "' does not have a Main-Class entry");
1294 jarFile.close();
1295 return;
1296 }
1297 jarFile.close();
1298 System.out.println("Main-Class = " + mainClassName);
1299
1300 ClassLoader classLoader = ClassLoader.getSystemClassLoader();
1301
1302 Method addURL = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
1303 addURL.setAccessible(true);
1304 addURL.invoke(classLoader, jf.toURI().toURL());
1305
1306 final Class<?> jarClass = classLoader.loadClass(mainClassName);
1307
1308 final Method main = jarClass.getDeclaredMethod("main", String[].class);
1309
1310 new Thread(new Runnable() {
1311 public void run() {
1312 try {
1313 main.invoke(jarClass, new Object[] {new String[0]});
1314 } catch (Exception e) {
1315 System.out.println("Failed to start jar");
1316 e.printStackTrace();
1317 }
1318 }
1319 }).start();
1320 }
1321
1322 public static void pan(Frame frame, int x, int y) {
1323 for (Item i : frame.getAllItems()) {
1324 if (i instanceof WidgetEdge || i instanceof WidgetCorner) {
1325 continue;
1326 }
1327 else {
1328 int new_x = i.getX();
1329 int new_y = i.getY();
1330
1331 if (!i.isAnchoredX()) {
1332 new_x += x;
1333 }
1334
1335 if (!i.isAnchoredY()) {
1336 new_y += y;
1337 }
1338
1339 if(i instanceof XRayable) {
1340 i.setPosition(new_x,new_y);
1341 }
1342 else {
1343 i.setXY(new_x,new_y);
1344 }
1345 }
1346 // update the polygon, otherwise stuff moves but leaves it's outline behind
1347 i.updatePolygon();
1348 }
1349
1350 for (InteractiveWidget iw : frame.getInteractiveWidgets()) {
1351
1352 int new_x = iw.getX();
1353 int new_y = iw.getY();
1354
1355 if (!iw.isAnchoredX()) {
1356 new_x += x;
1357 }
1358
1359 if (!iw.isAnchoredY()) {
1360 new_y += y;
1361 }
1362
1363 iw.setPosition(new_x,new_y);
1364
1365 }
1366
1367 // make sure we save the panning of the frame
1368 frame.change();
1369 // redraw everything
1370 FrameKeyboardActions.Refresh();
1371 }
1372
1373 public static void pan(Frame frame, String pan) {
1374 String[] split = pan.split("\\s+");
1375 int x = 0;
1376 int y = 0;
1377 try {
1378 if(split.length != 2) throw new Exception();
1379 x = Integer.parseInt(split[0]);
1380 y = Integer.parseInt(split[1]);
1381 } catch(Exception e) {
1382 MessageBay.errorMessage("Panning takes 2 integer arguments");
1383 return;
1384 }
1385 pan(frame, x, y);
1386 }
1387
1388 public static void pan(Frame frame, Text pan) {
1389 pan(frame, pan.getText());
1390 }
1391
1392 public static String exec(String cmd) throws Exception {
1393
1394 String[] command;
1395
1396 // run command through sh if possible
1397 if(System.getProperty("os.name").toLowerCase().indexOf("win") == -1) {
1398 command = new String[] { "sh", "-c", cmd };
1399 } else {
1400 command = cmd.split("\\s+");
1401 }
1402
1403 ProcessBuilder pb = new ProcessBuilder(command);
1404 pb.redirectErrorStream(true);
1405 Process ps = pb.start();
1406
1407 BufferedReader in = new BufferedReader(new InputStreamReader(ps.getInputStream()));
1408 StringBuffer sb = new StringBuffer();
1409 String line;
1410 while ((line = in.readLine()) != null) {
1411 sb.append(line).append('\n');
1412 }
1413 ps.waitFor();
1414 in.close();
1415
1416 if(sb.length() > 0) {
1417 sb.deleteCharAt(sb.length() - 1);
1418 }
1419 return sb.toString();
1420 }
1421
1422 public static void testProgress() {
1423 new Thread(new Runnable() {
1424
1425 @Override
1426 public void run() {
1427 Progress p = MessageBay.displayProgress("Loading something");
1428 for(int i = 1; i <= 100; i++) {
1429 try {
1430 Thread.sleep(100);
1431 p.set(i);
1432 } catch (Exception e) {
1433 e.printStackTrace();
1434 }
1435 }
1436 }
1437
1438 }).start();
1439 }
1440
1441 public static void getIDs(Frame f) {
1442 for(Item i : f.getAllItems()) {
1443 System.out.println(i + " (" + i.getID() + ")");
1444 }
1445 }
1446
1447 public static void flushResources() {
1448 FrameUtils.extractResources(true);
1449 MessageBay.displayMessage("Re-extracted resources, Expeditee may need to be restarted for certain resources to be reloaded");
1450 }
1451
1452 // Some experimental actions to do with keeping framesets stored within a Git repository
1453
1454
1455 // For custom merge, some potentially useful information at:
1456 // http://stackoverflow.com/questions/23140240/git-how-do-i-add-a-custom-merge-strategy
1457 // http://stackoverflow.com/questions/7607125/git-merge-conflict-to-always-take-the-newest-file
1458
1459 protected static String gitexe = "git";
1460
1461 protected static void runGitCommand(Frame frame, List<String> cmd_array) {
1462
1463 String framePath = frame.getPath();
1464 String frameName = frame.getName();
1465
1466 String frameDir = framePath + Conversion.getFramesetName(frameName)
1467 + File.separator;
1468 String localFname = Conversion.getFrameNumber(frameName)
1469 + ExpReader.EXTENTION;
1470
1471 ProcessBuilder process_builder = new ProcessBuilder(cmd_array);
1472
1473 process_builder.directory(new File(frameDir));
1474
1475 /*
1476 System.err.println("\nPATH:");
1477
1478 Map<String, String> env_map = process_builder.environment();
1479
1480 for (Entry<String, String> entry: env_map.entrySet()) {
1481 String key = entry.getKey();
1482 String value = entry.getValue();
1483 System.err.println(key + " = " + value);
1484 }
1485 */
1486
1487
1488 try {
1489 final Process process = process_builder.start();
1490 InputStream is = process.getInputStream();
1491 InputStreamReader isr = new InputStreamReader(is);
1492 BufferedReader br = new BufferedReader(isr);
1493 String line;
1494 while ((line = br.readLine()) != null) {
1495 System.out.println(line);
1496 }
1497 System.out.println("Program terminated!");
1498 }
1499 catch (Exception e) {
1500 e.printStackTrace();
1501 }
1502
1503 }
1504
1505 public static void GitPushFrame() {
1506
1507 FrameKeyboardActions.Save();
1508
1509 Frame current = DisplayIO.getCurrentFrame();
1510 String userName = UserSettings.ProfileName.get();
1511
1512 String frameName = current.getName();
1513 String localFname = Conversion.getFrameNumber(frameName)+ ExpReader.EXTENTION;
1514
1515 List<String> status_cmd_array = new ArrayList<String>();
1516 status_cmd_array.add(gitexe);
1517 status_cmd_array.add("status");
1518 status_cmd_array.add(".");
1519
1520 List<String> add_cmd_array = new ArrayList<String>();
1521 add_cmd_array.add(gitexe);
1522 add_cmd_array.add("add");
1523 add_cmd_array.add(localFname);
1524 add_cmd_array.add("frame.inf");
1525
1526 runGitCommand(current,add_cmd_array);
1527
1528 List<String> commit_cmd_array = new ArrayList<String>();
1529 commit_cmd_array.add(gitexe);
1530 commit_cmd_array.add("commit");
1531 commit_cmd_array.add("-m");
1532 commit_cmd_array.add("expeditee-edit-"+userName);
1533
1534 runGitCommand(current,commit_cmd_array);
1535
1536 List<String> push_cmd_array = new ArrayList<String>();
1537 push_cmd_array.add(gitexe);
1538 push_cmd_array.add("push");
1539 push_cmd_array.add("origin");
1540 push_cmd_array.add("master");
1541
1542 runGitCommand(current,push_cmd_array);
1543 }
1544
1545 public static void GitPullFrame() {
1546 Frame current = DisplayIO.getCurrentFrame();
1547
1548 List<String> cmd_array = new ArrayList<String>();
1549 cmd_array.add(gitexe);
1550 cmd_array.add("pull");
1551 cmd_array.add("origin");
1552 cmd_array.add("master");
1553 runGitCommand(current,cmd_array);
1554
1555 FrameIO.Reload();
1556 FrameKeyboardActions.Refresh();
1557 }
1558
1559}
Note: See TracBrowser for help on using the repository browser.