Changeset 1242 for trunk/src/org/expeditee/gui
- Timestamp:
- 03/15/19 16:48:00 (5 years ago)
- Location:
- trunk/src/org/expeditee/gui
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/expeditee/gui/Browser.java
r1224 r1242 536 536 } 537 537 538 protected static Frame loadProfile(String userName) 539 { 538 protected static Frame loadProfile(String userName) { 540 539 Frame profile = FrameIO.LoadProfile(userName); 541 540 542 541 if (profile == null) { 543 542 try { 544 profile = FrameIO.CreateNewProfile(userName );543 profile = FrameIO.CreateNewProfile(userName, null); 545 544 } catch (Exception e) { 546 545 // TODO tell the user that there was a problem creating the -
trunk/src/org/expeditee/gui/Frame.java
r1229 r1242 19 19 package org.expeditee.gui; 20 20 21 import java.io.File; 21 22 import java.sql.Time; 22 23 import java.util.ArrayList; … … 35 36 import org.expeditee.core.Image; 36 37 import org.expeditee.core.bounds.PolygonBounds; 38 import org.expeditee.gio.EcosystemManager; 39 import org.expeditee.gio.gesture.Gesture; 40 import org.expeditee.gio.gesture.Gesture.GestureType; 37 41 import org.expeditee.gio.gesture.StandardGestureActions; 42 import org.expeditee.gio.gesture.StandardGestureActions.StandardGestureType; 43 import org.expeditee.gio.gesture.data.RefreshGestureData; 38 44 import org.expeditee.gio.input.KBMInputEvent.Key; 39 45 import org.expeditee.gio.input.StandardInputEventListeners; 40 46 import org.expeditee.io.Conversion; 47 import org.expeditee.io.ExpReader; 41 48 import org.expeditee.items.Constraint; 42 49 import org.expeditee.items.Dot; … … 132 139 // for drawing purposes 133 140 private List<Widget> _iWidgets = new ArrayList<Widget>(); 141 142 // frame data 143 private Item frameData = new Text("Frame Data"); 134 144 135 145 private int _lineCount = 0; … … 167 177 168 178 /** Default constructor, nothing is set. */ 169 public Frame() 170 { 179 public Frame() { 171 180 } 172 181 … … 292 301 * true if the frame should be recalculated first. 293 302 */ 294 public void notifyObservers(boolean bRecalculate) 295 { 303 public void notifyObservers(boolean bRecalculate) { 296 304 if (bRecalculate) { 297 305 recalculate(); … … 1799 1807 * @return The newly created Text Item 1800 1808 */ 1801 public Text createBlankText(String templateType) 1802 { 1809 public Text createBlankText(String templateType) { 1810 File file = new File(getFramePathReal()); 1811 long fileLastModified = file.lastModified(); 1812 long frameLastModified = this.getLastModifyPrecise(); 1813 //if (ExpReader.getVersion(getFramePathReal()) > this._version) { 1814 if (fileLastModified > frameLastModified) { 1815 GestureType refreshGestureType = StandardGestureActions.getInstance().gestureType(StandardGestureType.REFRESH); 1816 RefreshGestureData refreshGestureData = new RefreshGestureData(true, false); 1817 try { 1818 StandardGestureActions.getInstance().onGesture(new Gesture(refreshGestureType, refreshGestureData)); 1819 EcosystemManager.getMiscManager().beep(); 1820 } catch (NullPointerException e) { 1821 //Detected more recent data on file system than on Frame in memory. Unfortunately not in a position to cause a refresh. 1822 } 1823 } 1824 1803 1825 SessionStats.CreatedText(); 1804 1826 Text t; … … 1834 1856 return t; 1835 1857 } 1836 1837 public Item createDot() 1838 { 1858 1859 /** 1860 * Returns the data associated with the frame. 1861 * @return 1862 */ 1863 public List<String> getData() { 1864 return frameData.getData(); 1865 } 1866 1867 /** 1868 * Adds a piece of data to be associated with the frame. 1869 * @param dataItem 1870 */ 1871 public void addToData(String dataItem) { 1872 frameData.addToData(dataItem); 1873 } 1874 1875 /** 1876 * Returns the path (String) to the .exp file that this Frame represents. 1877 * This follows redirects, meaning that it provides the actual file from which 1878 * the frames data is drawn from. 1879 * @return The path to the .exp file that this Frame represents 1880 * @see getFramePathLogical 1881 * @see getFramesetPath 1882 */ 1883 public String getFramePathReal() { 1884 String framesetPath = getFramesetPath(); 1885 String redirect = ExpReader.redirectTo(getFramePathLogical()); 1886 1887 if (redirect == null) { 1888 return getFramePathLogical(); 1889 } 1890 1891 while (redirect != null) { 1892 framesetPath = getFramesetPath() + redirect; 1893 redirect = ExpReader.redirectTo(redirect); 1894 } 1895 return framesetPath; 1896 } 1897 1898 /** 1899 * Returns the path (String) to the .exp file that this Frame represents. 1900 * Does not follow redirects, opting to instead provide the logical path to this file. 1901 * @return The path to the .exp file that this Frame represents 1902 * @see getFramePathReal 1903 * @see getFramesetPath 1904 */ 1905 public String getFramePathLogical() { 1906 return getFramesetPath() + this.getNumber() + ExpReader.EXTENTION; 1907 } 1908 1909 /** 1910 * Returns the path (String) to the frameset directory that the file that this Frame represents is contained within. 1911 * @return The path to this Frames frameset directory 1912 * @see getFramesetPathLogical 1913 * @see getFramesetPathReal 1914 */ 1915 public String getFramesetPath() { 1916 return this.getPath() + File.separator + this.getFramesetName() + File.separator; 1917 } 1918 1919 public Item createDot() { 1839 1920 Item dot = new Dot(DisplayController.getMouseX(), DisplayController.getMouseY(), getNextItemID()); 1840 1921 … … 2462 2543 { 2463 2544 Collection<Item> allItems = new LinkedHashSet<Item>(_body); 2545 2464 2546 allItems.addAll(_overlayItems); 2465 2547 allItems.addAll(_vectorItems); -
trunk/src/org/expeditee/gui/FrameIO.java
r1232 r1242 33 33 import java.io.Writer; 34 34 import java.nio.channels.FileChannel; 35 import java.nio.file.Paths; 35 36 import java.sql.Time; 37 import java.util.Arrays; 36 38 import java.util.Collection; 37 39 import java.util.HashMap; 38 40 import java.util.LinkedList; 39 41 import java.util.List; 42 import java.util.Map; 43 import java.util.stream.Collectors; 40 44 41 45 import org.expeditee.actions.Actions; 42 46 import org.expeditee.agents.ExistingFramesetException; 47 import org.expeditee.agents.InvalidFramesetNameException; 43 48 import org.expeditee.auth.Authenticator; 44 49 import org.expeditee.auth.EncryptedExpReader; 45 50 import org.expeditee.auth.EncryptedExpWriter; 46 51 import org.expeditee.auth.gui.MailBay; 52 import org.expeditee.gio.EcosystemManager; 47 53 import org.expeditee.io.Conversion; 48 54 import org.expeditee.io.ExpReader; … … 59 65 import org.expeditee.items.UserAppliedPermission; 60 66 import org.expeditee.network.FrameShare; 67 import org.expeditee.setting.Setting; 61 68 import org.expeditee.settings.UserSettings; 62 69 import org.expeditee.settings.folders.FolderSettings; … … 79 86 80 87 public static void changeParentFolder(String newFolder) { 88 // Partial Paths. 81 89 PARENT_FOLDER = newFolder; 90 String resourcesPublicPath = PARENT_FOLDER + "resources-public" + File.separator; 91 String resourcesPrivateIndividualPath = PARENT_FOLDER + "resources-" + UserSettings.UserName.get() + File.separator; 92 93 // Standard paths. 82 94 PUBLIC_PATH = PARENT_FOLDER + "public" + File.separator; 83 FRAME_PATH = PARENT_FOLDER + "framesets" + File.separator;84 95 MESSAGES_PATH = PARENT_FOLDER + "messages" + File.separator; 85 96 TRASH_PATH = PARENT_FOLDER + "trash" + File.separator; 86 IMAGES_PATH = PARENT_FOLDER + IMAGES_FOLDER;87 97 HELP_PATH = PARENT_FOLDER + "documentation" + File.separator; 88 DICT_PATH = PARENT_FOLDER + "dict" + File.separator;89 FONT_PATH = PARENT_FOLDER + "fonts" + File.separator;90 98 PROFILE_PATH = PARENT_FOLDER + "profiles" + File.separator; 91 99 EXPORTS_DIR = PARENT_FOLDER + "exports" + File.separator; 92 100 STATISTICS_DIR = PARENT_FOLDER + "statistics" + File.separator; 93 101 LOGS_DIR = PARENT_FOLDER + "logs" + File.separator; 94 SHARED_BY_ME_FRAMESETS = PARENT_FOLDER + "framesets-shared-by-me" + File.separator; 95 SHARED_WITH_ME_FRAMESETS = PARENT_FOLDER + "framesets-shared-with-me" + File.separator; 96 } 97 98 /** 99 * The default location for storing the framesets. Each frameset has its own 100 * subdirectory in this directory. 101 */ 102 public static String IMAGES_FOLDER = "images" + File.separator; 103 102 103 // New regime paths. 104 if (UserSettings.multiUserMode) { 105 SHARED_FRAMESETS_PATH = resourcesPrivateIndividualPath + "framesets-shared" + File.separator; 106 RESOURCES_PRIVATE = PARENT_FOLDER + "resources-private" + File.separator; 107 RESOURCES_PATH = resourcesPublicPath + "documentation" + File.separator; 108 FRAME_PRIVATE_PATH = resourcesPrivateIndividualPath + "framesets" + File.separator; 109 IMAGES_PRIVATE_PATH = resourcesPrivateIndividualPath + "images" + File.separator; 110 CONTACTS_PATH = resourcesPrivateIndividualPath + "contacts" + File.separator; 111 } else { 112 // If we are using the old regime then these paths should not be used. 113 SHARED_FRAMESETS_PATH = null; 114 RESOURCES_PRIVATE = null; 115 RESOURCES_PATH = null; 116 FRAME_PRIVATE_PATH = null; 117 IMAGES_PRIVATE_PATH = null; 118 CONTACTS_PATH = null; 119 } 120 121 // Conditional paths 122 if (UserSettings.multiUserMode) { 123 FONT_PATH = resourcesPublicPath + "fonts" + File.separator; 124 DICT_PATH = resourcesPublicPath + "dict" + File.separator; 125 IMAGES_PATH = resourcesPublicPath + "images" + File.separator; 126 FRAME_PATH = resourcesPublicPath + "framesets" + File.separator; 127 } else { 128 FONT_PATH = PARENT_FOLDER + "fonts" + File.separator; 129 DICT_PATH = PARENT_FOLDER + "dict" + File.separator; 130 IMAGES_PATH = PARENT_FOLDER + "images" + File.separator; 131 FRAME_PATH = PARENT_FOLDER + "framesets" + File.separator; 132 } 133 } 134 135 // The parent path that all others are relative to. Also referred to as Expeditee Home. 136 public static String PARENT_FOLDER; 137 138 // The below paths are categorised based on their use in the new/old regime. See UserSettings.appendDefaultFolders for more inforamtion. 139 // Paths used by Both the new regime (multiuser mode) and the old regime. 140 public static String PROFILE_PATH; 141 public static String FRAME_PATH; 142 public static String MESSAGES_PATH; 143 public static String IMAGES_PATH; 144 public static String PUBLIC_PATH; 104 145 public static String TRASH_PATH; 105 106 public static String PARENT_FOLDER; 107 108 public static String FRAME_PATH; 109 110 public static String MESSAGES_PATH; 111 112 public static String PUBLIC_PATH; 113 114 public static String IMAGES_PATH; 115 146 147 // Paths used by both the new regime and the old regime, that points to different locations based on regime setting. 148 public static String FONT_PATH; 149 public static String DICT_PATH; 150 public static String EXPORTS_DIR; 151 public static String STATISTICS_DIR; 152 public static String LOGS_DIR; 153 154 // Paths used only by new regime. 155 public static String SHARED_FRAMESETS_PATH; 156 public static String CONTACTS_PATH; 157 public static String RESOURCES_PRIVATE; 158 public static String RESOURCES_PATH; 159 public static String FRAME_PRIVATE_PATH; 160 public static String IMAGES_PRIVATE_PATH; 161 162 // Paths used only by old regime. 116 163 public static String HELP_PATH; 117 118 public static String FONT_PATH;119 164 165 // Paths that appear to be unused. 120 166 public static String TEMPLATES_PATH; 167 168 // Variables for controlling cache functionality. 169 public static final int MAX_NAME_LENGTH = 64; 170 public static final int MAX_CACHE = 100; 171 private static HashMap<String, Frame> _Cache = new FrameCache(); 172 private static boolean ENABLE_CACHE = true; 173 private static boolean _UseCache = true; 174 private static boolean _SuspendedCache = false; 121 175 122 public static String DICT_PATH; 123 124 public static String PROFILE_PATH; 125 126 public static String EXPORTS_DIR; 127 128 public static String STATISTICS_DIR; 176 private static final String INF_FILENAME = "frame.inf"; 129 177 130 public static String SHARED_BY_ME_FRAMESETS;131 132 public static String SHARED_WITH_ME_FRAMESETS;133 134 public static String LOGS_DIR;135 136 private static final String INF_FILENAME = "frame.inf";137 138 public static final String ILLEGAL_CHARS = ";:\\/?";139 140 public static final int MAX_NAME_LENGTH = 64;141 142 public static final int MAX_CACHE = 100;143 144 private static HashMap<String, Frame> _Cache = new FrameCache();145 146 // private static HashMap<String, String> _FramesetNameCache = new147 // HashMap<String, String>();148 149 private static boolean ENABLE_CACHE = true;150 151 private static boolean _UseCache = true;152 153 private static boolean _SuspendedCache = false;154 155 178 // All methods are static, this should not be instantiated 156 179 private FrameIO() { … … 202 225 } 203 226 227 /** 228 * Loads a frame with the specified name. 229 * By using a dot separated framename, users are able to specify the path to find the frameset in. 230 * @param frameName The frame to load. 231 * @return the loaded frame 232 */ 204 233 public static Frame LoadFrame(String frameName) { 205 return LoadFrame(frameName, null, false); 234 if (frameName.contains(".")) { 235 String[] split = frameName.split("\\."); 236 String[] pathSplit = Arrays.copyOfRange(split, 0, split.length - 1); 237 String name = split[split.length - 1]; 238 String path = Arrays.asList(pathSplit).stream().collect(Collectors.joining(File.separator)); 239 return LoadFrame(name, Paths.get(FrameIO.PARENT_FOLDER).resolve(path).toString() + File.separator, false); 240 } else { 241 return LoadFrame(frameName, null, false); //framesets-bryce.home1 242 } 206 243 } 207 244 … … 214 251 return null; 215 252 } 216 253 217 254 String frameNameLower = frameName.toLowerCase(); 218 255 // first try reading from cache … … 221 258 Frame frame = _Cache.get(frameNameLower); 222 259 223 // if frame i scache is older than the one on disk then don't use the cached one224 String p = frame.getPath() + frame.getNumber() + ".exp";225 File file = new File(p);226 if ( file.lastModified()<= frame.getLastModifyPrecise()) {260 // if frame in cache is older than the one on disk then don't use the cached one 261 File file = new File(frame.getFramePathReal()); 262 long lastModified = file.lastModified(); 263 if (lastModified <= frame.getLastModifyPrecise()) { 227 264 return frame; 228 265 } … … 232 269 + " from disk."); 233 270 234 return LoadFromDisk(frameName, path, ignoreAnnotations); 271 Frame fromDisk = LoadFromDisk(frameName, path, ignoreAnnotations); 272 return fromDisk; 235 273 } 236 274 … … 250 288 251 289 try{ 252 FileInputStream source_fis = new FileInputStream(source); 253 inputChannel = source_fis.getChannel(); 290 FileInputStream source_fis = new FileInputStream(source); 291 inputChannel = source_fis.getChannel(); 292 293 FileOutputStream dest_fos = new FileOutputStream(dest); 294 outputChannel = dest_fos.getChannel(); 254 295 255 FileOutputStream dest_fos = new FileOutputStream(dest); 256 outputChannel = dest_fos.getChannel(); 257 258 outputChannel.transferFrom(inputChannel, 0, inputChannel.size()); 259 inputChannel.close(); 260 outputChannel.close(); 261 source_fis.close(); 262 dest_fos.close(); 296 outputChannel.transferFrom(inputChannel, 0, inputChannel.size()); 297 inputChannel.close(); 298 outputChannel.close(); 299 source_fis.close(); 300 dest_fos.close(); 263 301 } 264 302 catch(Exception e){ … … 301 339 302 340 if (knownPath != null) { 303 loaded = LoadKnow Path(knownPath, framename);341 loaded = LoadKnownPath(knownPath, framename); 304 342 } else { 305 343 List<String> directoriesToSearch = FolderSettings.FrameDirs.get(); 306 344 307 if ( UserSettings.Authenticated.get()) {345 if (Authenticator.Authenticated) { 308 346 // if we are running Expeditee Authenticated, consult user profile as location for framesets first 309 347 String profilePath = FrameIO.PROFILE_PATH + UserSettings.UserName.get() + File.separator; … … 312 350 313 351 for (String path : directoriesToSearch) { 314 loaded = LoadKnow Path(path, framename);352 loaded = LoadKnownPath(path, framename); 315 353 if (loaded != null) { 316 354 break; … … 325 363 if (loaded != null) { 326 364 FrameUtils.Parse(loaded, true, ignoreAnnotations); 365 FrameIO.setSavedProperties(loaded); 327 366 } 328 367 … … 357 396 /** 358 397 * Gets the full path and file name of the frame. 359 * 398 * This is a alias for Frame::getFramePathLogical 360 399 * @param path- 361 400 * the directory in which to look for the frameset containing the … … 475 514 } 476 515 477 private static Frame LoadKnow Path(String path, String frameName) {516 private static Frame LoadKnownPath(String path, String frameName) { 478 517 String fullPath = getFrameFullPathName(path, frameName); 479 518 if (fullPath == null) { … … 483 522 try { 484 523 FrameReader reader; 485 524 525 // Get the frameset name. 526 int i = frameName.length() - 1; 527 for (; i >= 0; i--) { 528 if (!Character.isDigit(frameName.charAt(i))) { 529 break; 530 } 531 } 532 if (i < 0) { 533 System.err.println("LoadKnownFrame was provided with a invalid Frame name: " + frameName); 534 return null; 535 } 536 String framesetName = frameName.substring(0, i + 1); 537 538 String redirectTo = ExpReader.redirectTo(fullPath); 539 while (redirectTo != null) { 540 fullPath = path + framesetName + File.separator + redirectTo; 541 redirectTo = ExpReader.redirectTo(fullPath); 542 } 543 486 544 if (fullPath.endsWith(ExpReader.EXTENTION)) { 487 545 if (EncryptedExpReader.isEncryptedExpediteeFile(fullPath)) { 488 //final boolean isProfile = frameName.startsWith(UserSettings.UserName.get());489 //reader = new EncryptedExpReader(frameName, isProfile);490 546 reader = new EncryptedExpReader(frameName); 491 547 } else { … … 919 975 920 976 private static boolean isValidFrameNameChar(char c) { 921 return Character.isLetterOrDigit(c) || c == '-';977 return c == '-' || c == '.' || Character.isLetterOrDigit(c); 922 978 } 923 979 … … 952 1008 * 953 1009 * @param toSave 954 * The Frame to save to disk1010 * The Frame to save to disk 955 1011 * @param inc 956 * True if the saved frames counter should be incremented, false 957 * otherwise. 1012 * True if the saved frames counter should be incremented, false otherwise. 958 1013 * @param checkBackup 959 * True if the frame should be checked for the back up tag 960 */ 961 public static String SaveFrame(Frame toSave, boolean inc, 962 boolean checkBackup) { 963 1014 * True if the frame should be checked for the back up tag 1015 */ 1016 public static String SaveFrame(Frame toSave, boolean inc, boolean checkBackup) { 964 1017 // TODO When loading a frame maybe append onto the event history too- 965 1018 // with a break to indicate the end of a session 966 1019 967 1020 if (toSave == null || !toSave.hasChanged() || toSave.isSaved()) { 968 1021 return ""; … … 982 1035 983 1036 // Save frame that is not local through the Networking classes 984 // TODO985 1037 if (!toSave.isLocal()) { 986 1038 return FrameShare.getInstance().saveFrame(toSave); … … 1012 1064 try { 1013 1065 // if its a new frame or an existing Exp frame... 1014 if (fullPath == null || fullPath.endsWith(ExpReader.EXTENTION)) { 1015 if (UserSettings.Authenticated.get() && 1016 toSave.getNumber() != Authenticator.PUBLIC_KEY_FRAME && 1066 if (fullPath == null || fullPath.endsWith(ExpReader.EXTENTION)) { 1067 if (toSave.getNumber() != Authenticator.CREDENTIALS_FRAME && 1017 1068 toSave.getEncryptionLabel() != null) { 1018 1069 writer = new EncryptedExpWriter(toSave.getEncryptionLabel()); … … 1022 1073 savedVersion = ExpReader.getVersion(fullPath); 1023 1074 } 1075 1076 // Is the file this would be saved to a redirect? 1077 String redirectTo = ExpReader.redirectTo(fullPath); 1078 if (redirectTo != null) { 1079 String redirectedPath = toSave.getFramePathReal(); 1080 writer.setOutputLocation(redirectedPath); 1081 } 1082 1024 1083 } else { 1025 1084 writer = new KMSWriter(); … … 1042 1101 // Check if we are trying to save an out of date version 1043 1102 String framesetName = toSave.getFramesetName(); 1044 long frameLastModify = toSave.getLastModifyPrecise();1045 long fileLastModify = new File(fullPath).lastModified();1046 boolean versionConflict = frameLastModify < fileLastModify;1047 1103 boolean isBayFrameset = 1048 1104 framesetName.equalsIgnoreCase(MessageBay.MESSAGES_FRAMESET_NAME) || 1049 1105 framesetName.equalsIgnoreCase(MailBay.EXPEDITEE_MAIL_FRAMESET_NAME); 1050 if ((savedVersion > toSave.getVersion() || versionConflict) && !isBayFrameset) { 1106 long frameLastModify = toSave.getLastModifyPrecise(); 1107 long fileLastModify = new File(toSave.getFramePathReal()).lastModified(); 1108 boolean fileModifyConflict = fileLastModify > frameLastModify && !isBayFrameset; 1109 boolean versionConflict = savedVersion > toSave.getVersion() && !isBayFrameset; 1110 if (fileModifyConflict || versionConflict) { 1051 1111 // remove this frame from the cache if it is there 1052 1112 // This will make sure links to the original are set correctly … … 1063 1123 Text originalMessage = new Text(-1); 1064 1124 originalMessage.setColor(MessageBay.ERROR_COLOR); 1065 originalMessage.setText(original.getName() 1066 + " was updated by another user."); 1125 StringBuilder message = new StringBuilder(original.getName() 1126 + " was updated by another user. "); 1127 if (fileModifyConflict) { 1128 message.append("{ File modify conflict }"); 1129 } 1130 if (versionConflict) { 1131 message.append("{ Version conflict }"); 1132 } 1133 originalMessage.setText(message.toString()); 1067 1134 originalMessage.setLink(original.getName()); 1068 1135 Text yourMessage = new Text(-1); … … 1073 1140 MessageBay.displayMessage(originalMessage); 1074 1141 MessageBay.displayMessage(yourMessage); 1142 EcosystemManager.getMiscManager().beep(); 1075 1143 } else if (checkBackup 1076 1144 && ItemUtils.ContainsExactTag(toSave.getItems(), … … 1112 1180 ResumeCache(); 1113 1181 } 1114 // Update general stuff about frame1115 setSavedProperties(toSave);1116 1182 1117 1183 // int oldMode = FrameGraphics.getMode(); 1118 1184 // if (oldMode != FrameGraphics.MODE_XRAY) 1119 1185 // FrameGraphics.setMode(FrameGraphics.MODE_XRAY, true); 1186 1120 1187 writer.writeFrame(toSave); 1121 1188 // FrameGraphics.setMode(oldMode, true); 1122 1189 toSave.setSaved(); 1190 1191 // Update general stuff about frame 1192 setSavedProperties(toSave); 1193 1123 1194 if (inc) { 1124 1195 SessionStats.SavedFrame(toSave.getName()); … … 1144 1215 // re-parsing) 1145 1216 if (isProfileFrame(toSave)) { 1146 Frame profile = FrameIO.LoadFrame(toSave.getFramesetName() 1147 + "1"); 1217 Frame profile = FrameIO.LoadFrame(toSave.getFramesetName() + "1"); 1148 1218 assert (profile != null); 1149 1219 FrameUtils.ParseProfile(profile); … … 1155 1225 return null; 1156 1226 } 1227 toSave.notifyObservers(false); 1157 1228 1158 1229 return writer.getFileContents(); … … 1212 1283 _Cache.put(toAdd.getName().toLowerCase(), toAdd); 1213 1284 } 1285 1286 public static void ClearCache() { 1287 _Cache.clear(); 1288 } 1214 1289 1215 1290 /** … … 1241 1316 } 1242 1317 1243 public static Frame CreateNewProfile(String username ) throws Exception{1318 public static Frame CreateNewProfile(String username, Map<String, Setting> initialSettings) throws InvalidFramesetNameException, ExistingFramesetException { 1244 1319 Frame profile = CreateFrameset(username, PROFILE_PATH, true); 1245 FrameUtils.CreateDefaultProfile(username, profile );1320 FrameUtils.CreateDefaultProfile(username, profile, initialSettings); 1246 1321 return profile; 1247 1322 } … … 1477 1552 } 1478 1553 1479 public static Frame CreateFrameset(String frameset, String path, boolean recreate) throws Exception 1480 { 1554 public static Frame CreateFrameset(String frameset, String path, boolean recreate) throws InvalidFramesetNameException, ExistingFramesetException { 1481 1555 String conversion = frameset + " --> "; 1482 1556 1483 1557 if (!isValidFramesetName(frameset)) { 1484 throw new Exception("Invalid frameset name");1558 throw new InvalidFramesetNameException(frameset); 1485 1559 } 1486 1560 … … 1557 1631 base.setOwner(UserSettings.UserName.get()); 1558 1632 SaveFrame(base, true); 1633 1634 FrameIO.setSavedProperties(base); 1559 1635 1560 1636 Logger.Log(Logger.SYSTEM, Logger.NEW_FRAMESET, "Created new frameset: " + frameset); … … 1801 1877 e.printStackTrace(); 1802 1878 } 1803 // } else {1804 //1805 //1806 //1807 // MessageBay1808 // .errorMessage("Recieved save request for unknown public frame: "1809 // + frameName);1810 // }1811 1879 } 1812 1880 … … 1822 1890 toSave.setActiveTime(activeTime); 1823 1891 } 1824 1825 1892 } -
trunk/src/org/expeditee/gui/FrameUtils.java
r1220 r1242 24 24 import java.io.IOException; 25 25 import java.io.InputStream; 26 import java.lang.reflect.InvocationTargetException; 26 27 import java.net.JarURLConnection; 28 import java.net.URISyntaxException; 27 29 import java.net.URL; 28 30 import java.net.URLConnection; 31 import java.nio.file.Path; 32 import java.nio.file.Paths; 29 33 import java.util.ArrayList; 30 34 import java.util.Arrays; … … 36 40 import java.util.LinkedList; 37 41 import java.util.List; 42 import java.util.Map; 38 43 import java.util.jar.JarEntry; 39 44 import java.util.jar.JarFile; 45 import java.util.stream.Collectors; 40 46 import java.util.zip.ZipEntry; 41 47 48 import org.expeditee.agents.ExistingFramesetException; 49 import org.expeditee.agents.InvalidFramesetNameException; 42 50 import org.expeditee.auth.gui.MailBay; 43 51 import org.expeditee.core.Colour; … … 67 75 import org.expeditee.items.widgets.WidgetCorner; 68 76 import org.expeditee.items.widgets.WidgetEdge; 77 import org.expeditee.setting.Setting; 69 78 import org.expeditee.settings.Settings; 70 79 import org.expeditee.settings.UserSettings; … … 76 85 77 86 /** 78 * The list of known start pages framesets which will have prepopulated 79 * links inthe home frame.87 * The list of known start pages framesets which will have prepopulated links in 88 * the home frame. 80 89 */ 81 90 public static final String[] startPages = { "exploratorysearch", "webbrowser" }; … … 99 108 private static Item _tdfcItem = null; 100 109 101 public static float getResponseTimeTotal() 102 { 110 public static float getResponseTimeTotal() { 103 111 return _ResponseTimeSum; 104 112 } 105 113 106 public static float getLastResponseTime() 107 { 114 public static float getLastResponseTime() { 108 115 return _LastResponse; 109 116 } 110 117 111 118 /** 112 * Checks if the given top Item is above the given bottom Item, allowing for 113 * theX coordinates to be off by a certain width...119 * Checks if the given top Item is above the given bottom Item, allowing for the 120 * X coordinates to be off by a certain width... 114 121 * 115 122 * @param item1 … … 140 147 141 148 // Ensure the two items 142 if ((minX >= startX && minX <= endX) 143 || (maxX >= startX && maxX <= endX) 144 || (startX >= minX && startX <= maxX) 149 if ((minX >= startX && minX <= endX) || (maxX >= startX && maxX <= endX) || (startX >= minX && startX <= maxX) 145 150 || (endX >= minX && endX <= maxX)) { 146 151 return true; … … 150 155 } 151 156 152 public static boolean sameBulletType(String bullet1, String bullet2) 153 { 157 public static boolean sameBulletType(String bullet1, String bullet2) { 154 158 if (bullet1 == null || bullet2 == null) { 155 159 return false; … … 160 164 } 161 165 162 if (Character.isLetter(bullet1.charAt(0)) 163 && Character.isLetter(bullet2.charAt(0))) { 166 if (Character.isLetter(bullet1.charAt(0)) && Character.isLetter(bullet2.charAt(0))) { 164 167 return true; 165 168 } 166 169 167 if (Character.isDigit(bullet1.charAt(0)) 168 && Character.isDigit(bullet2.charAt(0))) { 170 if (Character.isDigit(bullet1.charAt(0)) && Character.isDigit(bullet2.charAt(0))) { 169 171 return true; 170 172 } … … 205 207 * @return 206 208 */ 207 public static int Align(List<Text> toAlign, boolean moveAll, int adjust, 208 List<Item> changedItems) { 209 public static int Align(List<Text> toAlign, boolean moveAll, int adjust, List<Item> changedItems) { 209 210 Collections.sort(toAlign); 210 211 211 212 /* 212 * Single items dont need alignment But if there are two items we may 213 * still wantto format them... ie if they are too close together.213 * Single items dont need alignment But if there are two items we may still want 214 * to format them... ie if they are too close together. 214 215 */ 215 216 if (toAlign.size() < 1) { … … 232 233 lastBullet = StandardGestureActions.getAutoBullet(above.getText()); 233 234 } else { 234 lastBullet = StandardGestureActions.getBullet(toAlign.get(0) 235 .getText()); 235 lastBullet = StandardGestureActions.getBullet(toAlign.get(0).getText()); 236 236 } 237 237 if (needsRenumbering(lastBullet)) { … … 251 251 252 252 // if we changed the item, add to changedItems list 253 if (changedItems != null 254 && oldText != currentText.getText() 253 if (changedItems != null && oldText != currentText.getText() 255 254 && !changedItems.contains(currentText)) { 256 255 Item copy = currentText.copy(); … … 293 292 294 293 if (UserSettings.FormatSpacingMax.get() != null) { 295 double maxSpace = UserSettings.FormatSpacingMax.get() 296 * above.getSize(); 294 double maxSpace = UserSettings.FormatSpacingMax.get() * above.getSize(); 297 295 if (maxSpace < space) { 298 296 space = (int) Math.round(maxSpace); … … 301 299 302 300 if (UserSettings.FormatSpacingMin.get() != null) { 303 double minSpace = UserSettings.FormatSpacingMin.get() 304 * above.getSize(); 301 double minSpace = UserSettings.FormatSpacingMin.get() * above.getSize(); 305 302 if (minSpace > space) { 306 303 space = (int) Math.round(minSpace); … … 309 306 310 307 // Need to do things differently for FORMAT than for DROPPING 311 if (moveAll && above != curr.getNameItem() 312 && above != curr.getTitleItem()) { 308 if (moveAll && above != curr.getNameItem() && above != curr.getTitleItem()) { 313 309 x = above.getX(); 314 int y = above.getBounds().getMaxY() 315 + space 316 + (from.getY() - from.getBounds().getMinY()); 317 318 if (changedItems != null 319 && (from.getX() != x || from.getY() != y) 320 && !changedItems.contains(from)) { 310 int y = above.getBounds().getMaxY() + space + (from.getY() - from.getBounds().getMinY()); 311 312 if (changedItems != null && (from.getX() != x || from.getY() != y) && !changedItems.contains(from)) { 321 313 Item copy = from.copy(); 322 314 copy.setID(from.getID()); … … 343 335 int newPos = bottom + space + diff; 344 336 345 if (changedItems != null 346 && ((moveAll && current.getX() != x) || current.getY() != newPos) 337 if (changedItems != null && ((moveAll && current.getX() != x) || current.getY() != newPos) 347 338 && !changedItems.contains(current)) { 348 339 Item copy = current.copy(); … … 411 402 // next move 412 403 if (opposite.hasChanged() && opposite.equals(toSave)) { 413 if (EcosystemManager.getGraphicsManager().showDialog("Changes", "Leaving this frame will discard changes made in the " + side + " Frame. Continue?")) { 404 if (EcosystemManager.getGraphicsManager().showDialog("Changes", 405 "Leaving this frame will discard changes made in the " + side + " Frame. Continue?")) { 414 406 FrameIO.SaveFrame(toSave); 415 407 DisplayController.Reload(DisplayController.getSideFrameIsOn(opposite)); … … 420 412 } else if (opposite.hasOverlay(toSave)) { 421 413 if (toSave.hasChanged()) { 422 if (EcosystemManager.getGraphicsManager().showDialog("Changes", "Leaving this frame will discard changes made in the " + side + " Frame. Continue?")) { 414 if (EcosystemManager.getGraphicsManager().showDialog("Changes", 415 "Leaving this frame will discard changes made in the " + side + " Frame. Continue?")) { 423 416 FrameIO.SaveFrame(toSave); 424 417 DisplayController.Reload(DisplayController.getSideFrameIsOn(opposite)); … … 440 433 } 441 434 442 // TODO: consider reloating this method to Frame class? 443 protected static Item getAnnotation(Frame frame, String annotationStr) 444 { 435 // TODO: consider reloating this method to Frame class? 436 protected static Item getAnnotation(Frame frame, String annotationStr) { 445 437 Item matched_item = null; 446 438 447 439 // check for an updated template... 448 for (Item i : frame.getAnnotationItems()) { 440 for (Item i : frame.getAnnotationItems()) { 449 441 450 442 if (ItemUtils.startsWithTag(i, annotationStr)) { … … 458 450 } 459 451 460 protected static void doFrameTransition(Item frameTransition, Frame from, Frame to) 461 { 462 String s = frameTransition.getText(); 452 protected static void doFrameTransition(Item frameTransition, Frame from, Frame to) { 453 String s = frameTransition.getText(); 463 454 String[] s_array = s.split(":"); 464 if (s_array.length > 1){455 if (s_array.length > 1) { 465 456 String slide_mode_method = s_array[1].trim(); 466 457 467 458 FrameTransition transition = new FrameTransition(from.getBuffer(), slide_mode_method); 468 459 469 460 DisplayController.setTransition(from, transition); 470 461 471 462 System.out.println("Triggered on annotation: " + s); 472 463 } else { 473 464 System.err.println("Warning: failed to detect frameTransition type"); 474 // TODO: print list as a result of reflection listing 475 } 476 } 465 // TODO: print list as a result of reflection listing 466 } 467 } 477 468 478 469 /** 479 470 * Displays the given Frame on the display. If the current frame has changed 480 471 * since the last save then it will be saved before the switch is made. The 481 * caller can also dictate whether the current frame is added to the 482 * back-stackor not.472 * caller can also dictate whether the current frame is added to the back-stack 473 * or not. 483 474 * 484 475 * @param toDisplay 485 476 * The Frame to display on the screen 486 477 * @param addToBack 487 * True if the current Frame should be added to the back-stack, 488 * Falseotherwise478 * True if the current Frame should be added to the back-stack, False 479 * otherwise 489 480 */ 490 public static void DisplayFrame(Frame toDisplay, boolean addToBack, boolean incrementStats) 491 { 481 public static void DisplayFrame(Frame toDisplay, boolean addToBack, boolean incrementStats) { 492 482 if (toDisplay == null) { 493 483 return; 494 484 } 495 485 496 486 final PermissionPair framePermissions = toDisplay.getPermission(); 497 if (framePermissions != null && framePermissions.getPermission(toDisplay.getOwner()) == UserAppliedPermission.denied) { 487 if (framePermissions != null 488 && framePermissions.getPermission(toDisplay.getOwner()) == UserAppliedPermission.denied) { 498 489 MessageBay.errorMessage("Insufficient permissions to navigate to frame: " + toDisplay.getName()); 499 490 return; … … 569 560 // Only need to worry about frame transitions when in Audience Mode 570 561 571 // Test to see if frame transition specified through annotation, and perform it if one if found 562 // Test to see if frame transition specified through annotation, and perform it 563 // if one if found 572 564 Item frameTransition = getAnnotation(toDisplay, "@frameTransition"); 573 565 if (frameTransition != null) { 574 doFrameTransition(frameTransition, current,toDisplay);566 doFrameTransition(frameTransition, current, toDisplay); 575 567 } 576 568 } … … 586 578 587 579 /** 588 * Loads and displays the Frame with the given framename, and adds the 589 * currentframe to the back-stack if required.580 * Loads and displays the Frame with the given framename, and adds the current 581 * frame to the back-stack if required. 590 582 * 591 583 * @param framename 592 584 * The name of the Frame to load and display 593 585 * @param addToBack 594 * True if the current Frame should be added to the back-stack, 595 * falseotherwise586 * True if the current Frame should be added to the back-stack, false 587 * otherwise 596 588 */ 597 public static void DisplayFrame(String frameName, boolean addToBack, 598 boolean incrementStats) { 589 public static void DisplayFrame(String frameName, boolean addToBack, boolean incrementStats) { 599 590 Frame newFrame = getFrame(frameName); 600 591 … … 606 597 607 598 /** 608 * Loads and displays the Frame with the given framename and adds the 609 * current frame to the back-stack. This is the same as calling610 * DisplayFrame(framename,true)599 * Loads and displays the Frame with the given framename and adds the current 600 * frame to the back-stack. This is the same as calling DisplayFrame(framename, 601 * true) 611 602 * 612 603 * @param framename … … 629 620 630 621 /** 631 * Creates a new Picture Item from the given Text source Item and adds it to 632 * thegiven Frame.622 * Creates a new Picture Item from the given Text source Item and adds it to the 623 * given Frame. 633 624 * 634 625 * @return True if the image was created successfully, false otherwise … … 647 638 // MessageBay.errorMessage("Expected image path after @i:"); 648 639 } else { 649 MessageBay.errorMessage("Image " + imagePath 650 + " could not be loaded"); 640 MessageBay.errorMessage("Image " + imagePath + " could not be loaded"); 651 641 } 652 642 return false; … … 658 648 659 649 /** 660 * Creates an interactive widget and adds it to a frame. If txt has no 661 * parentthe parent will be set to frame.650 * Creates an interactive widget and adds it to a frame. If txt has no parent 651 * the parent will be set to frame. 662 652 * 663 653 * @param frame … … 713 703 } 714 704 715 public static List<String> ParseProfile(Frame profile) 716 { 705 public static List<String> ParseProfile(Frame profile) { 717 706 List<String> errors = new LinkedList<String>(); 718 707 719 708 if (profile == null) { 720 709 return errors; … … 722 711 723 712 /* 724 * Make sure the correct cursor shows when turning off the custom cursor 725 * andreparsing the profile frame713 * Make sure the correct cursor shows when turning off the custom cursor and 714 * reparsing the profile frame 726 715 */ 727 716 FreeItems.getCursor().clear(); … … 739 728 continue; 740 729 } 741 730 742 731 String attribute = attributeFullCase.trim().toLowerCase().replaceAll("^@", ""); 743 732 … … 764 753 * @param profile 765 754 */ 766 public static void loadFirstFrame(Frame profile) 767 { 755 public static void loadFirstFrame(Frame profile) { 768 756 if (UserSettings.HomeFrame.get() == null) { 769 757 UserSettings.HomeFrame.set(profile.getName()); … … 781 769 } 782 770 783 public static Colour[] getColorWheel(Frame frame) 784 { 771 public static Colour[] getColorWheel(Frame frame) { 785 772 if (frame != null) { 786 773 List<Text> textItems = frame.getBodyTextItems(false); … … 797 784 } 798 785 799 public static String getLink(Item item, String alt) 800 { 786 public static String getLink(Item item, String alt) { 801 787 if (item == null || !(item instanceof Text)) { 802 788 return alt; … … 816 802 } 817 803 818 public static String getDir(String name) 819 { 804 public static String getDir(String name) { 820 805 if (name != null) { 821 806 File tester = new File(name); … … 833 818 } 834 819 835 public static ArrayList<String> getDirs(Item item) 836 { 820 public static ArrayList<String> getDirs(Item item) { 837 821 ArrayList<String> dirsToAdd = new ArrayList<String>(); 838 822 String dirListFrameName = item.getAbsoluteLink(); … … 857 841 } 858 842 859 public static void Parse(Frame toParse) 860 { 843 public static void Parse(Frame toParse) { 861 844 Parse(toParse, false); 862 845 } 863 846 864 847 /** 865 * Checks for any special Annotation items and updates the display as 866 * necessary.Special Items: Images, overlays, sort.848 * Checks for any special Annotation items and updates the display as necessary. 849 * Special Items: Images, overlays, sort. 867 850 * 868 851 */ 869 public static void Parse(Frame toParse, boolean firstParse) 870 { 852 public static void Parse(Frame toParse, boolean firstParse) { 871 853 Parse(toParse, firstParse, false); 872 854 } … … 877 859 * @param firstParse 878 860 * @param ignoreAnnotations 879 * used to prevent infinate loops such as when performing TDFC 880 * with an ao tag linked to a frame with an frameImage of a frame881 * whichalso has an ao tag on it.861 * used to prevent infinate loops such as when performing TDFC with 862 * an ao tag linked to a frame with an frameImage of a frame which 863 * also has an ao tag on it. 882 864 */ 883 public static void Parse(Frame toParse, boolean firstParse, boolean ignoreAnnotations) 884 { 865 public static void Parse(Frame toParse, boolean firstParse, boolean ignoreAnnotations) { 885 866 // TODO check why we are getting toParse == null... when profile frame 886 867 // is being created and change the lines below … … 892 873 ItemUtils.EnclosedCheck(toParse.getItems()); 893 874 } 894 875 895 876 List<Item> items = toParse.getItems(); 896 877 … … 937 918 } 938 919 939 // DotType pointtype = DotType.square;940 // boolean filledPoints = true;920 // DotType pointtype = DotType.square; 921 // boolean filledPoints = true; 941 922 942 923 UserAppliedPermission permission = toParse.getUserAppliedPermission(); … … 958 939 Text txt = (Text) i; 959 940 String line = txt.getFirstLine(); 960 line = ItemUtils.StripTag(line, 961 ItemUtils.GetTag(ItemUtils.TAG_POINTTYPE)); 941 line = ItemUtils.StripTag(line, ItemUtils.GetTag(ItemUtils.TAG_POINTTYPE)); 962 942 963 943 if (line != null) { 964 944 line = line.toLowerCase(); 965 945 if (line.indexOf(" ") > 0) { 966 String fill = line.substring(line 967 .indexOf(" ") + 1); 946 String fill = line.substring(line.indexOf(" ") + 1); 968 947 if (fill.startsWith("nofill")) { 969 // filledPoints = false;948 // filledPoints = false; 970 949 } else { 971 // filledPoints = true;950 // filledPoints = true; 972 951 } 973 952 } 974 953 975 954 if (line.startsWith("circle")) { 976 // pointtype = DotType.circle;955 // pointtype = DotType.circle; 977 956 } else { 978 // pointtype = DotType.square;957 // pointtype = DotType.square; 979 958 } 980 959 } 981 }// check for new VECTOR items 982 else if (!DisplayController.isXRayMode() 983 && ItemUtils.startsWithTag(i, 984 ItemUtils.TAG_VECTOR) 960 } // check for new VECTOR items 961 else if (!DisplayController.isXRayMode() && ItemUtils.startsWithTag(i, ItemUtils.TAG_VECTOR) 985 962 && i.getLink() != null) { 986 963 if (!i.getAbsoluteLink().equals(toParse.getName())) { 987 addVector(vectors, UserAppliedPermission.none, 988 permission, i); 964 addVector(vectors, UserAppliedPermission.none, permission, i); 989 965 } 990 966 } else if (!DisplayController.isXRayMode() 991 && ItemUtils.startsWithTag(i, 992 ItemUtils.TAG_ACTIVE_VECTOR) 993 && i.getLink() != null) { 967 && ItemUtils.startsWithTag(i, ItemUtils.TAG_ACTIVE_VECTOR) && i.getLink() != null) { 994 968 if (!i.getAbsoluteLink().equals(toParse.getName())) { 995 addVector(vectors, 996 UserAppliedPermission.followLinks, 997 permission, i); 969 addVector(vectors, UserAppliedPermission.followLinks, permission, i); 998 970 } 999 971 } 1000 972 // check for new OVERLAY items 1001 else if (!ignoreAnnotations && ItemUtils.startsWithTag(i, ItemUtils.TAG_OVERLAY) && i.getLink() != null) { 973 else if (!ignoreAnnotations && ItemUtils.startsWithTag(i, ItemUtils.TAG_OVERLAY) 974 && i.getLink() != null) { 1002 975 if (i.getAbsoluteLink().equalsIgnoreCase(toParse.getName())) { 1003 976 // This frame contains an active overlay which … … 1014 987 } 1015 988 // check for ACTIVE_OVERLAY items 1016 else if (!ignoreAnnotations 1017 && ItemUtils.startsWithTag(i, 1018 ItemUtils.TAG_ACTIVE_OVERLAY) 989 else if (!ignoreAnnotations && ItemUtils.startsWithTag(i, ItemUtils.TAG_ACTIVE_OVERLAY) 1019 990 && i.getLink() != null) { 1020 991 String link = i.getAbsoluteLink(); … … 1022 993 // This frame contains an active overlay which 1023 994 // points to itself 1024 MessageBay 1025 .errorMessage(toParse.getName() 1026 + " contains an @ao which links to itself"); 995 MessageBay.errorMessage(toParse.getName() + " contains an @ao which links to itself"); 1027 996 continue; 1028 997 } … … 1032 1001 if (current != null) { 1033 1002 for (Overlay o : current.getOverlays()) { 1034 if (o.Frame.getName() 1035 .equalsIgnoreCase(link)) { 1003 if (o.Frame.getName().equalsIgnoreCase(link)) { 1036 1004 overlayFrame = o.Frame; 1037 1005 } … … 1043 1011 1044 1012 // get level if specified 1045 String level = new AttributeValuePair(i.getText()) 1046 .getValue(); 1013 String level = new AttributeValuePair(i.getText()).getValue(); 1047 1014 // default permission (if none is specified) 1048 PermissionPair permissionLevel = new PermissionPair( 1049 level,UserAppliedPermission.followLinks);1015 PermissionPair permissionLevel = new PermissionPair(level, 1016 UserAppliedPermission.followLinks); 1050 1017 1051 1018 if (overlayFrame != null) { 1052 Overlay existingOverlay = Overlay.getOverlay( 1053 overlays, overlayFrame); 1019 Overlay existingOverlay = Overlay.getOverlay(overlays, overlayFrame); 1054 1020 // If it wasn't in the list create it and add 1055 1021 // it. 1056 1022 if (existingOverlay == null) { 1057 Overlay newOverlay = new Overlay( 1058 overlayFrame, 1059 permissionLevel 1060 .getPermission(overlayFrame 1061 .getOwner())); 1023 Overlay newOverlay = new Overlay(overlayFrame, 1024 permissionLevel.getPermission(overlayFrame.getOwner())); 1062 1025 i.setOverlay(newOverlay); 1063 1026 overlays.add(newOverlay); 1064 1027 } else { 1065 existingOverlay.Frame 1066 .setPermission(permissionLevel); 1028 existingOverlay.Frame.setPermission(permissionLevel); 1067 1029 } 1068 1030 } … … 1071 1033 else { 1072 1034 if (!DisplayController.isXRayMode()) { 1073 if (ItemUtils.startsWithTag(i, 1074 ItemUtils.TAG_IMAGE, true)) { 1035 if (ItemUtils.startsWithTag(i, ItemUtils.TAG_IMAGE, true)) { 1075 1036 if (!i.hasEnclosures()) { 1076 1037 createPicture(toParse, (Text) i); 1077 1038 } 1078 1039 // check for frame images 1079 } else if (ItemUtils.startsWithTag(i, 1080 ItemUtils.TAG_FRAME_IMAGE) 1081 && i.getLink() != null 1082 && !i.getAbsoluteLink() 1083 .equalsIgnoreCase( 1084 toParse.getName())) { 1040 } else if (ItemUtils.startsWithTag(i, ItemUtils.TAG_FRAME_IMAGE) && i.getLink() != null 1041 && !i.getAbsoluteLink().equalsIgnoreCase(toParse.getName())) { 1085 1042 XRayable image = null; 1086 1043 if (i.hasEnclosures()) { … … 1095 1052 // FrameImage 1096 1053 toParse.addItem(image); 1097 } else if (ItemUtils.startsWithTag(i, 1098 ItemUtils.TAG_BITMAP_IMAGE) 1099 && i.getLink() != null 1100 && !i.getAbsoluteLink() 1101 .equalsIgnoreCase( 1102 toParse.getName())) { 1054 } else if (ItemUtils.startsWithTag(i, ItemUtils.TAG_BITMAP_IMAGE) && i.getLink() != null 1055 && !i.getAbsoluteLink().equalsIgnoreCase(toParse.getName())) { 1103 1056 XRayable image = null; 1104 1057 if (i.hasEnclosures()) { … … 1116 1069 } else if (ItemUtils.startsWithTag(i, "@c")) { 1117 1070 // Can only have a @c 1118 if (!i.hasEnclosures() 1119 && i.getLines().size() == 1) { 1071 if (!i.hasEnclosures() && i.getLines().size() == 1) { 1120 1072 toParse.addItem(new Circle((Text) i)); 1121 1073 } 1122 1074 // Check for JSItem 1123 } else if (ItemUtils.startsWithTag(i, "@js")) {1075 } else if (ItemUtils.startsWithTag(i, "@js")) { 1124 1076 toParse.addItem(new JSItem((Text) i)); 1125 1077 // Check for interactive widgets … … 1138 1090 Logger.Log(e); 1139 1091 e.printStackTrace(); 1140 MessageBay.warningMessage("Exception occured when loading " 1141 + i.getClass().getSimpleName() + "(ID: " + i.getID() 1142 + ") " + e.getMessage() != null ? e.getMessage() : ""); 1092 MessageBay.warningMessage("Exception occured when loading " + i.getClass().getSimpleName() + "(ID: " 1093 + i.getID() + ") " + e.getMessage() != null ? e.getMessage() : ""); 1143 1094 } 1144 1095 } … … 1146 1097 /* 1147 1098 * for (Item i : items) { if (i instanceof Dot) { ((Dot) 1148 * i).setPointType(pointtype); ((Dot) i).useFilledPoints(filledPoints); 1149 * } } 1099 * i).setPointType(pointtype); ((Dot) i).useFilledPoints(filledPoints); } } 1150 1100 */ 1151 1101 … … 1166 1116 * @param i 1167 1117 */ 1168 private static void addVector(List<Vector> vectors, UserAppliedPermission defaultPermission, UserAppliedPermission framePermission, Item i)1169 {1118 private static void addVector(List<Vector> vectors, UserAppliedPermission defaultPermission, 1119 UserAppliedPermission framePermission, Item i) { 1170 1120 // TODO It is possible to get into an infinite loop if a 1171 1121 // frame contains an @ao which leads to a frame with an … … 1174 1124 1175 1125 // Get the permission from off the vector frame 1176 UserAppliedPermission vectorPermission = UserAppliedPermission.getPermission(vector.getAnnotationValue("permission"), defaultPermission); 1177 1126 UserAppliedPermission vectorPermission = UserAppliedPermission 1127 .getPermission(vector.getAnnotationValue("permission"), defaultPermission); 1128 1178 1129 // If the frame permission is lower, use that 1179 1130 vectorPermission = UserAppliedPermission.min(vectorPermission, framePermission); 1180 1131 1181 1132 // Highest permissable permission for vectors is copy 1182 1133 vectorPermission = UserAppliedPermission.min(vectorPermission, UserAppliedPermission.copy); … … 1195 1146 } 1196 1147 1197 public static Item onItem(float floatX, float floatY, boolean changeLastEdited) 1198 { 1148 public static Item onItem(float floatX, float floatY, boolean changeLastEdited) { 1199 1149 return onItem(DisplayController.getCurrentFrame(), floatX, floatY, changeLastEdited); 1200 1150 } 1201 1151 1202 1152 /** 1203 * Searches through the list of items on this frame to find one at the given 1204 * x,ycoordinates.1153 * Searches through the list of items on this frame to find one at the given x,y 1154 * coordinates. 1205 1155 * 1206 1156 * @param x … … 1255 1205 } else { 1256 1206 if (LastEdited != null) { 1257 if (LastEdited.contains(x, y) 1258 && !FreeItems.getInstance().contains(LastEdited) 1207 if (LastEdited.contains(x, y) && !FreeItems.getInstance().contains(LastEdited) 1259 1208 && LastEdited.getParent() == DisplayController.getCurrentFrame() 1260 && LastEdited.getParent().getItems().contains(LastEdited)) 1261 { 1209 && LastEdited.getParent().getItems().contains(LastEdited)) { 1262 1210 LastEdited.setOverlayPermission(UserAppliedPermission.full); 1263 1211 return LastEdited; … … 1273 1221 1274 1222 // do not check annotation items in audience mode 1275 //TODO: Upon hover of Rubbish Bin, Undo and Restore Widgets, flickering occurs depending on the mouse distance from a corner. Resolve this. 1223 // TODO: Upon hover of Rubbish Bin, Undo and Restore Widgets, flickering occurs 1224 // depending on the mouse distance from a corner. Resolve this. 1276 1225 if (i.isVisible() && !(DisplayController.isAudienceMode() && i.isAnnotation())) { 1277 1226 if (i instanceof WidgetCorner) { … … 1283 1232 Widget iw = wc.getWidgetSource(); 1284 1233 1285 if(iw.getBounds().contains(x, y)){ 1286 1287 if( !FreeItems.getInstance().contains(i)) 1288 { 1289 possibles.add(i); 1234 if (iw.getBounds().contains(x, y)) { 1235 1236 if (!FreeItems.getInstance().contains(i)) { 1237 possibles.add(i); 1290 1238 } 1291 } 1239 } 1292 1240 } 1293 1241 } 1294 1242 } 1295 1243 1296 if (i.contains(new Point(x, y))) {1297 if (!FreeItems.getInstance().contains(i)) {1298 possibles.add(i); 1244 if (i.contains(new Point(x, y))) { 1245 if (!FreeItems.getInstance().contains(i)) { 1246 possibles.add(i); 1299 1247 } 1300 1248 } … … 1316 1264 // return closest x,y pair to mouse 1317 1265 Item closest = possibles.get(0); 1318 int distance = (int) Math.round(Math.sqrt(Math.pow( 1319 Math.abs(closest.getX() - x), 2) 1320 + Math.pow(Math.abs(closest.getY() - y), 2))); 1266 int distance = (int) Math.round( 1267 Math.sqrt(Math.pow(Math.abs(closest.getX() - x), 2) + Math.pow(Math.abs(closest.getY() - y), 2))); 1321 1268 1322 1269 for (Item i : possibles) { 1323 int d = (int) Math .round(Math.sqrt(Math.pow(Math.abs(i.getX() - x),1324 2) + Math.pow(Math.abs(i.getY() - y), 2)));1270 int d = (int) Math 1271 .round(Math.sqrt(Math.pow(Math.abs(i.getX() - x), 2) + Math.pow(Math.abs(i.getY() - y), 2))); 1325 1272 1326 1273 // System.out.println(d); … … 1336 1283 } 1337 1284 1338 } 1285 } 1339 1286 1340 1287 return closest; 1341 1288 } 1342 1289 1343 1290 /** 1344 1291 * Checks if the mouse is currently over an item. 1345 1292 * 1346 * @return 1347 * True if the mouse is over any item, false otherwise. 1293 * @return True if the mouse is over any item, false otherwise. 1348 1294 */ 1349 public static boolean hasCurrentItem() 1350 { 1295 public static boolean hasCurrentItem() { 1351 1296 return getCurrentItem() != null; 1352 1297 } 1353 1298 1354 public synchronized static Item getCurrentItem() 1355 { 1356 return onItem(DisplayController.getCurrentFrame(), DisplayController.getMouseX(), DisplayController.getMouseY(), true); 1357 } 1358 1359 public static PolygonBounds getEnlosingPolygon() 1360 { 1299 public synchronized static Item getCurrentItem() { 1300 return onItem(DisplayController.getCurrentFrame(), DisplayController.getMouseX(), DisplayController.getMouseY(), 1301 true); 1302 } 1303 1304 public static PolygonBounds getEnlosingPolygon() { 1361 1305 Collection<Item> enclosure = getEnclosingLineEnds(); 1362 1306 1363 1307 if (enclosure == null || enclosure.size() == 0) { 1364 1308 return null; … … 1373 1317 * @return 1374 1318 */ 1375 public static Collection<Item> getCurrentItems() 1376 { 1319 public static Collection<Item> getCurrentItems() { 1377 1320 return getCurrentItems(getCurrentItem()); 1378 1321 } 1379 1322 1380 public static Collection<Item> getCurrentItems(Item currentItem) 1381 { 1323 public static Collection<Item> getCurrentItems(Item currentItem) { 1382 1324 Collection<Item> enclosure = getEnclosingLineEnds(); 1383 1325 1384 1326 if (enclosure == null || enclosure.size() == 0) { 1385 1327 return null; … … 1388 1330 Item firstItem = enclosure.iterator().next(); 1389 1331 1390 Collection<Item> enclosed = getItemsEnclosedBy(DisplayController.getCurrentFrame(), firstItem.getEnclosedShape()); 1332 Collection<Item> enclosed = getItemsEnclosedBy(DisplayController.getCurrentFrame(), 1333 firstItem.getEnclosedShape()); 1391 1334 1392 1335 // Brook: enclosed widgets are to be fully enclosed, never partially 1393 1336 /* 1394 * MIKE says: but doesn't this mean that widgets are treated differently 1395 * from ALL other object which only need to be partially enclosed to be 1396 * picked up 1337 * MIKE says: but doesn't this mean that widgets are treated differently from 1338 * ALL other object which only need to be partially enclosed to be picked up 1397 1339 */ 1398 1340 List<Widget> enclosedWidgets = new LinkedList<Widget>(); … … 1412 1354 } 1413 1355 } 1414 1356 1415 1357 if (i instanceof WidgetCorner) { 1416 1358 if (!enclosedWidgets.contains(((WidgetCorner) i).getWidgetSource())) { … … 1418 1360 } 1419 1361 } 1420 1362 1421 1363 i.setHighlightMode(Item.HighlightMode.None); 1422 1364 i.setHighlightColorToDefault(); … … 1435 1377 1436 1378 /** 1437 * Gets the collection of Dot items that form the enclosure nearest to the current mouse position. 1379 * Gets the collection of Dot items that form the enclosure nearest to the 1380 * current mouse position. 1438 1381 */ 1439 public static Collection<Item> getEnclosingLineEnds() 1440 { 1382 public static Collection<Item> getEnclosingLineEnds() { 1441 1383 return getEnclosingLineEnds(new Point(DisplayController.getMouseX(), DisplayController.getMouseY())); 1442 1384 } 1443 1385 1444 1386 /** 1445 * Gets the collection of Dot items that form the enclosure nearest to the given position. 1387 * Gets the collection of Dot items that form the enclosure nearest to the given 1388 * position. 1446 1389 */ 1447 public static Collection<Item> getEnclosingLineEnds(Point position) 1448 { 1390 public static Collection<Item> getEnclosingLineEnds(Point position) { 1449 1391 // update enclosed shapes 1450 1392 Frame current = DisplayController.getCurrentFrame(); … … 1484 1426 if (used.size() == 1) { 1485 1427 return used.get(0).getEnclosingDots(); 1486 // otherwise, determine which polygon is closest to the cursor1428 // otherwise, determine which polygon is closest to the cursor 1487 1429 } else { 1488 1430 Collections.sort(used, new Comparator<Item>() { … … 1503 1445 1504 1446 if (i < p2.getPointCount()) { 1505 diff2 = Math.abs(p2.getPoint(i).getX() - mouseX) 1447 diff2 = Math.abs(p2.getPoint(i).getX() - mouseX) + Math.abs(p2.getPoint(i).getY() - mouseY); 1506 1448 } 1507 1449 … … 1544 1486 // TODO Remove this method!! 1545 1487 // Can just getItemsWithin be used? 1546 public static Collection<Item> getItemsEnclosedBy(Frame frame, PolygonBounds poly) 1547 { 1488 public static Collection<Item> getItemsEnclosedBy(Frame frame, PolygonBounds poly) { 1548 1489 Collection<Item> contained = frame.getItemsWithin(poly); 1549 1490 … … 1570 1511 return results; 1571 1512 } 1513 1514 public static void CreateDefaultProfile(String profileFor, Frame profile) { 1515 CreateDefaultProfile(profileFor, profile, null); 1516 } 1572 1517 1573 1518 /** 1574 * Fills the given Frame with default profile tags 1519 * Copies the content from the default profile to the specified profile. 1520 * @param profileFor Name of profile that is destination of copy. 1521 * @param profile Profile being setup. 1522 * @param specifiedTextSettings text settings to provide a default value for in the new profile 1523 * @param specifiedGenericSettings generic settings to provide a default value for in the new profile 1575 1524 */ 1576 public static void CreateDefaultProfile(String username, Frame profile) 1577 { 1578 Text title = profile.getTitleItem(); 1579 if (username.equals(UserSettings.DEFAULT_PROFILE_NAME)) { 1525 public static void CreateDefaultProfile(String profileFor, Frame profile, 1526 Map<String, Setting> specifiedSettings) { 1527 // If this is already the default profile then nothing (other than setting 1528 // title) needs to be done. 1529 Text titleItem = profile.getTitleItem(); 1530 Text title = titleItem; 1531 if (!profileFor.equals(UserSettings.DEFAULT_PROFILE_NAME)) { 1532 // If this profile is not the default profile, copy it from the default profile 1533 // instead of generating a new profile 1534 // (this allows the possibility of modifying the default profile and having any 1535 // new profiles get those modifications) 1536 Frame defaultFrame = FrameIO.LoadProfile(UserSettings.DEFAULT_PROFILE_NAME); 1537 if (defaultFrame == null) { 1538 try { 1539 // If we do not have a default to copy, create one. 1540 defaultFrame = FrameIO.CreateNewProfile(UserSettings.DEFAULT_PROFILE_NAME, null); 1541 } catch (InvalidFramesetNameException invalidNameEx) { 1542 MessageBay.errorMessage("Failed to create default profile named: " 1543 + UserSettings.DEFAULT_PROFILE_NAME + ". " 1544 + "Profile names must start and end with a letter and must contain only letters and numbers."); 1545 return; 1546 } catch (ExistingFramesetException existingFramesetEx) { 1547 MessageBay.errorMessage("Failed to create the desired default frameset: " 1548 + UserSettings.DEFAULT_PROFILE_NAME + ", " 1549 + "because it already exists. This should never happen as we shouldn't be asking to create it if it already exists."); 1550 return; 1551 } 1552 } 1553 1554 MessageBay.suppressMessages(true); 1555 int lastNumber = FrameIO.getLastNumber(defaultFrame.getFramesetName()); 1556 for (int i = 1; i <= lastNumber; i++) { 1557 // Load in next default, if it doesn't exist continue loop. 1558 defaultFrame = FrameIO.LoadFrame(defaultFrame.getFramesetName() + i); 1559 if (defaultFrame == null) { 1560 continue; 1561 } 1562 1563 // Create the next next (currently blank) profile frame. 1564 // If there is frame gaps in the default (say if there is no 4.exp but there is 1565 // a 5.exp) then retain those gaps. 1566 // This way copied relative links work. 1567 while (profile.getNumber() < defaultFrame.getNumber()) { 1568 profile = FrameIO.CreateFrame(profile.getFramesetName(), null, null); 1569 } 1570 // Ensure we are working from a blank slate. 1571 profile.reset(); 1572 profile.removeAllItems(profile.getAllItems()); 1573 1574 // For each item on defaultFrame: 1575 // 1. Set all items to be relatively linked so once copied their links correctly 1576 // point to the frame on the created profile rather than the default profile. 1577 // 2. Copy item from defaultFrame to the current profile frame being 1578 // constructed. 1579 // 3. Replace settings values of copied items with those specified in 1580 // specifiedSettings (if present) 1581 for (Item item : defaultFrame.getAllItems()) { 1582 item.setRelativeLink(); 1583 } 1584 profile.addAllItems(defaultFrame.getAllItems()); 1585 if (i == 1 && titleItem != null) { 1586 titleItem.setText(profileFor + "'s Profile"); 1587 } 1588 String category = profile.getTitle(); 1589 List<String> settingsKeys = null; 1590 if (specifiedSettings != null) { 1591 settingsKeys = specifiedSettings.keySet().stream().filter(key -> 1592 key.startsWith(category)).collect(Collectors.toList()); 1593 } 1594 if (settingsKeys != null) { 1595 for (String key: settingsKeys) { 1596 Setting setting = specifiedSettings.get(key); 1597 String name = setting.getName(); 1598 Text representation = setting.generateRepresentation(name.substring(0, 1).toUpperCase() + name.substring(1).toLowerCase(), profile.getFramesetName()); 1599 Collection<Text> canditates = profile.getTextItems(); 1600 canditates.removeIf(text -> !text.getText().startsWith(representation.getText().split(" ")[0])); 1601 canditates.forEach(text -> { 1602 Point backupPos = text.getPosition(); 1603 Item.DuplicateItem(representation, text); 1604 text.setText(representation.getText()); 1605 text.setPosition(backupPos); 1606 }); 1607 } 1608 } 1609 FrameIO.SaveFrame(profile); 1610 } 1611 MessageBay.suppressMessages(false); 1612 } else { 1580 1613 title.setText("Default Profile Frame"); 1581 } else { 1582 // if this profile is not the default profile, copy it from the default profile instead of generating a new profile 1583 // (this allows the possibility of modifying the default profile and having any new profiles get those modifications) 1584 Frame nextDefault = FrameIO.LoadProfile(UserSettings.DEFAULT_PROFILE_NAME); 1585 if (nextDefault == null) { 1586 try { 1587 nextDefault = FrameIO.CreateNewProfile(UserSettings.DEFAULT_PROFILE_NAME); 1588 } catch (Exception e) { 1589 // TODO tell the user that there was a problem creating the 1590 // profile frame and close nicely 1591 e.printStackTrace(); 1592 } 1593 } 1594 // load profile frame and set title correctly 1595 profile.reset(); 1596 profile.removeAllItems(profile.getAllItems()); 1597 // set relative link on all items so their links will correctly point to the page on the current profile rather than on the default profile 1598 for(Item i : nextDefault.getAllItems()) { 1599 i.setRelativeLink(); 1600 } 1601 profile.addAllItems(ItemUtils.CopyItems(nextDefault.getAllItems())); 1602 profile.setTitle(username + "'s Profile Frame"); 1603 FrameIO.SaveFrame(profile); 1604 1605 Frame nextProfile = profile; 1606 MessageBay.suppressMessages(true); 1607 while((nextDefault = FrameIO.LoadNext(nextDefault)) != null) { 1608 // in case there are gaps in the frame numbering of the default profile (e.g. if a user has edited it), 1609 // we need to replicate those gaps in the copied profile so the links will work correctly 1610 while(nextProfile.getNumber() < nextDefault.getNumber()) { 1611 nextProfile = FrameIO.CreateFrame(profile.getFramesetName(), null, null); 1612 } 1613 // if the new profile has a frame number higher than the current frame number in the default profile, 1614 // the new profile must already exist, so just exit 1615 // (TODO: should we wipe the frames instead?) 1616 if(nextProfile.getNumber() > nextDefault.getNumber()) { 1617 break; 1618 } 1619 nextProfile.reset(); 1620 nextProfile.removeAllItems(nextProfile.getAllItems()); 1621 // set relative link on all items so their links will correctly point to the page on the current profile rather than on the default profile 1622 for(Item i : nextDefault.getAllItems()) { 1623 i.setRelativeLink(); 1624 } 1625 nextProfile.addAllItems(ItemUtils.CopyItems(nextDefault.getAllItems())); 1626 FrameIO.SaveFrame(nextProfile); 1627 } 1628 MessageBay.suppressMessages(false); 1629 1630 return; 1631 } 1632 1633 // int spacing = 50; 1634 final int intialYPos = 75; 1635 int xPos = 75; 1636 int yPos = intialYPos; 1637 1638 // yPos += spacing; 1639 // profile.addText(xPos, yPos, "@HomeFrame", null, profile.getName()); 1640 // yPos += spacing; 1641 // String defaultFrameName = profile.getFramesetName() + "0"; 1642 // profile.addText(xPos, yPos, "@DefaultFrame", null, defaultFrameName); 1643 // yPos += spacing; 1644 // 1645 // profile.addText(xPos, yPos, "@InitialWidth: " 1646 // + UserSettings.InitialWidth, null); 1647 // yPos += spacing; 1648 // 1649 // profile.addText(xPos, yPos, "@InitialHeight: " 1650 // + UserSettings.InitialHeight, null); 1651 // yPos += spacing; 1652 // 1653 // Text t = profile.addText(xPos, yPos, "@ItemTemplate", null); 1654 // t.setColor(null); 1655 // 1656 // yPos += spacing; 1657 // t = profile.addText(xPos, yPos, "@AnnotationTemplate", null); 1658 // t.setColor(Color.gray); 1659 // 1660 // yPos += spacing; 1661 // t = profile.addText(xPos, yPos, "@CommentTemplate", null); 1662 // t.setColor(Color.green.darker()); 1663 // 1664 // yPos += spacing; 1665 // t = profile.addText(xPos, yPos, "@StatsTemplate", null); 1666 // t.setColor(Color.BLACK); 1667 // t.setBackgroundColor(new Color(0.9F, 0.9F, 0.9F)); 1668 // t.setFamily(Text.MONOSPACED_FONT); 1669 // t.setSize(14); 1670 1671 Text t; 1672 1673 xPos = 300; 1674 // yPos = intialYPos + spacing; 1675 yPos = 100; 1676 1677 // Add documentation links 1678 File helpDirectory = new File(FrameIO.HELP_PATH); 1679 if (helpDirectory != null) { 1680 File[] helpFramesets = helpDirectory.listFiles(); 1681 if (helpFramesets != null) { 1682 1683 // Add the title for the help index 1684 Text help = profile.addText(xPos, yPos, "@Expeditee Help", null); 1685 help.setSize(25); 1686 help.setFontStyle("Bold"); 1687 help.setFamily("SansSerif"); 1688 help.setColor(TemplateSettings.ColorWheel.get()[3]); 1689 1690 xPos += 25; 1691 System.out.println("Installing frameset: "); 1692 1693 boolean first_item = true; 1694 1695 for (File helpFrameset : helpFramesets) { 1696 String framesetName = helpFrameset.getName(); 1697 if (!FrameIO.isValidFramesetName(framesetName)) { 1698 continue; 1614 int xPos = 300; 1615 int yPos = 100; 1616 Text t; 1617 1618 // Add documentation links 1619 File helpDirectory = new File(FrameIO.HELP_PATH); 1620 if (helpDirectory != null) { 1621 File[] helpFramesets = helpDirectory.listFiles(); 1622 if (helpFramesets != null) { 1623 1624 // Add the title for the help index 1625 Text help = profile.addText(xPos, yPos, "@Expeditee Help", null); 1626 help.setSize(25); 1627 help.setFontStyle("Bold"); 1628 help.setFamily("SansSerif"); 1629 help.setColor(TemplateSettings.ColorWheel.get()[3]); 1630 1631 xPos += 25; 1632 System.out.println("Installing frameset: "); 1633 1634 boolean first_item = true; 1635 for (File helpFrameset : helpFramesets) { 1636 String framesetName = helpFrameset.getName(); 1637 if (!FrameIO.isValidFramesetName(framesetName)) { 1638 continue; 1639 } 1640 1641 if (first_item) { 1642 System.out.print(" " + framesetName); 1643 first_item = false; 1644 } else { 1645 System.out.print(", " + framesetName); 1646 } 1647 System.out.flush(); 1648 1649 Frame indexFrame = FrameIO.LoadFrame(framesetName + '1'); 1650 // Look through the folder for help index pages 1651 if (indexFrame != null && ItemUtils.FindTag(indexFrame.getItems(), "@HelpIndex") != null) { 1652 // yPos += spacing; 1653 yPos += 30; 1654 t = profile.addText(xPos, yPos, '@' + indexFrame.getFramesetName(), null); 1655 t.setLink(indexFrame.getName()); 1656 t.setColor(Colour.GREY); 1657 } 1699 1658 } 1700 1701 if (first_item) { 1702 System.out.print(" " + framesetName); 1703 first_item = false; 1704 } 1705 else { 1706 System.out.print(", " + framesetName); 1707 } 1708 System.out.flush(); 1709 1710 Frame indexFrame = FrameIO.LoadFrame(framesetName + '1'); 1711 // Look through the folder for help index pages 1712 if (indexFrame != null 1713 && ItemUtils.FindTag(indexFrame.getItems(), 1714 "@HelpIndex") != null) { 1715 // yPos += spacing; 1716 yPos += 30; 1717 t = profile.addText(xPos, yPos, 1718 '@' + indexFrame.getFramesetName(), null); 1719 t.setLink(indexFrame.getName()); 1720 t.setColor(Colour.GREY); 1721 } 1722 } 1723 System.out.println(); 1724 } 1725 } 1726 1727 xPos = 50; 1728 yPos = 100; 1729 1730 // Populate Start Pages and Settings 1731 File framesetDirectory = new File(FrameIO.FRAME_PATH); 1732 1733 if (framesetDirectory.exists()) { 1734 File[] startpagesFramesets = framesetDirectory.listFiles(); 1735 1736 if (startpagesFramesets != null) { 1737 // Add Start Page title 1738 Text templates = profile.addText(xPos, yPos, "@Start Pages", 1739 null); 1740 templates.setSize(25); 1741 templates.setFontStyle("Bold"); 1742 templates.setFamily("SansSerif"); 1743 templates.setColor(TemplateSettings.ColorWheel.get()[3]); 1744 1745 xPos += 25; 1746 1747 // Start Pages should be the first frame in its own frameset + 1748 // frameset name should be present in FrameUtils.startPages[]. 1749 for (File startpagesFrameset : startpagesFramesets) { 1750 String framesetName = startpagesFrameset.getName(); 1751 1752 // Only add link if frameset is a startpage 1753 for (int i = 0; i < startPages.length; i++) { 1754 if (framesetName.equals(startPages[i])) { 1755 Frame indexFrame = FrameIO 1756 .LoadFrame(framesetName + '1'); 1757 1758 // Add start page link 1759 if (indexFrame != null) { 1760 yPos += 30; 1761 t = profile.addText(xPos, yPos, 1762 '@' + indexFrame.getFramesetName(), 1763 null); 1764 t.setLink(indexFrame.getName()); 1765 t.setColor(Colour.GREY); 1659 System.out.println(); 1660 } 1661 } 1662 1663 xPos = 50; 1664 yPos = 100; 1665 1666 // Populate Start Pages and Settings 1667 File framesetDirectory = new File(FrameIO.FRAME_PATH); 1668 1669 if (framesetDirectory.exists()) { 1670 File[] startpagesFramesets = framesetDirectory.listFiles(); 1671 1672 if (startpagesFramesets != null) { 1673 // Add Start Page title 1674 Text templates = profile.addText(xPos, yPos, "@Start Pages", null); 1675 templates.setSize(25); 1676 templates.setFontStyle("Bold"); 1677 templates.setFamily("SansSerif"); 1678 templates.setColor(TemplateSettings.ColorWheel.get()[3]); 1679 1680 xPos += 25; 1681 1682 // Start Pages should be the first frame in its own frameset + 1683 // frameset name should be present in FrameUtils.startPages[]. 1684 for (File startpagesFrameset : startpagesFramesets) { 1685 String framesetName = startpagesFrameset.getName(); 1686 1687 // Only add link if frameset is a startpage 1688 for (int i = 0; i < startPages.length; i++) { 1689 if (framesetName.equals(startPages[i])) { 1690 Frame indexFrame = FrameIO.LoadFrame(framesetName + '1'); 1691 1692 // Add start page link 1693 if (indexFrame != null) { 1694 yPos += 30; 1695 t = profile.addText(xPos, yPos, '@' + indexFrame.getFramesetName(), null); 1696 t.setLink(indexFrame.getName()); 1697 t.setColor(Colour.GREY); 1698 } 1766 1699 } 1767 1700 } … … 1769 1702 } 1770 1703 } 1771 } 1772 1773 FrameIO.SaveFrame(profile); 1774 1775 // Populate settings frameset 1776 Settings.Init(); 1777 t = profile.addText(550, 100, "@Settings", null); 1778 t.setSize((float) 25.0); 1779 t.setFamily("SansSerif"); 1780 t.setFontStyle("Bold"); 1781 t.setColor(Colour.GREY); 1782 Settings.generateSettingsTree(t); 1783 1784 FrameIO.SaveFrame(profile); 1785 } 1786 1787 private static void checkTDFCItemWaiting(Frame currentFrame) 1788 { 1704 1705 FrameIO.SaveFrame(profile); 1706 1707 // Populate settings frameset 1708 Settings.Init(); 1709 t = profile.addText(550, 100, "@Settings", null); 1710 t.setSize((float) 25.0); 1711 t.setFamily("SansSerif"); 1712 t.setFontStyle("Bold"); 1713 t.setColor(Colour.GREY); 1714 Settings.generateSettingsTree(t); 1715 1716 FrameIO.SaveFrame(profile); 1717 } 1718 } 1719 1720 private static void checkTDFCItemWaiting(Frame currentFrame) { 1789 1721 Item tdfcItem = FrameUtils.getTdfcItem(); 1790 1722 // if there is a TDFC Item waiting … … 1806 1738 } 1807 1739 1808 public static void setTdfcItem(Item _tdfcItem) 1809 { 1740 public static void setTdfcItem(Item _tdfcItem) { 1810 1741 FrameUtils._tdfcItem = _tdfcItem; 1811 1742 } 1812 1743 1813 public static Item getTdfcItem() 1814 { 1744 public static Item getTdfcItem() { 1815 1745 return FrameUtils._tdfcItem; 1816 1746 } 1817 1747 1818 public static void setLastEdited(Text lastEdited) 1819 { 1748 public static void setLastEdited(Text lastEdited) { 1820 1749 // If the lastEdited is being changed then check if its @i 1821 1750 Frame toReparse = null; … … 1834 1763 // around it 1835 1764 String text = LastEdited.getText(); 1836 if (text.startsWith("@i:") 1837 && !Character 1838 .isDigit(text.charAt(text.length() - 1))) { 1839 Collection<Item> enclosure = FrameUtils 1840 .getEnclosingLineEnds(LastEdited.getPosition()); 1765 if (text.startsWith("@i:") && !Character.isDigit(text.charAt(text.length() - 1))) { 1766 Collection<Item> enclosure = FrameUtils.getEnclosingLineEnds(LastEdited.getPosition()); 1841 1767 if (enclosure != null) { 1842 1768 for (Item i : enclosure) { 1843 1769 if (i.isLineEnd() && i.isEnclosed()) { 1844 DisplayController.getCurrentFrame().removeAllItems( 1845 enclosure); 1770 DisplayController.getCurrentFrame().removeAllItems(enclosure); 1846 1771 AxisAlignedBoxBounds rect = i.getEnclosedBox(); 1847 LastEdited 1848 .setText(LastEdited.getText() 1849 + " " 1850 + Math.round(rect 1851 .getWidth())); 1772 LastEdited.setText(LastEdited.getText() + " " + Math.round(rect.getWidth())); 1852 1773 LastEdited.setPosition(rect.getTopLeft()); 1853 1774 LastEdited.setThickness(i.getThickness()); … … 1892 1813 } 1893 1814 } 1894 1815 1895 1816 /** 1896 * Extracts files/folders from the assets/resources folder directly into 1897 * ${PARENT_FOLDER} (~/.expeditee) 1898 * 1899 * @param force if true, resources will be extracted even if they have already been extracted before 1817 * Extracts files/folders from assets/resources-public and assets/resources-private 1818 * to {Expeditee Home}/resources-public and {Expeditee Home}/resources-private respectively. 1819 * @param force if true, resources will be extracted even ifthey have already been extracted before. 1900 1820 */ 1901 public static void extractResources(boolean force) 1902 { 1903 File check = new File(FrameIO.PARENT_FOLDER + ".res"); 1821 public static void extractResources(boolean force) { 1822 // Extract private resources 1823 Path resourcesPrivate = Paths.get(FrameIO.PARENT_FOLDER).resolve("resources-private"); 1824 extractResources("org/expeditee/assets/resources-private", resourcesPrivate, force); 1904 1825 1905 if(!force && check.exists()) { 1826 // Extract public resources 1827 Path resourcesPublic = Paths.get(FrameIO.PARENT_FOLDER).resolve("resources-public"); 1828 extractResources("org/expeditee/assets/resources-public", resourcesPublic, force); 1829 } 1830 1831 private static void extractResources(String source, Path destination, boolean force) { 1832 // If resources have already been extracted, and we are not forcing the extraction, there is nothing to do. 1833 if (!force && destination.resolve(".res").toFile().exists()) { 1906 1834 return; 1907 1835 } 1908 1836 1909 System.out.println("Extracting/Installing resources :");1837 System.out.println("Extracting/Installing resources to: " + destination.getFileName()); 1910 1838 1911 try { 1912 check.getParentFile().mkdirs(); 1913 check.createNewFile(); 1914 1915 ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 1916 URL docURL = classLoader.getResource("org/expeditee/assets/resources"); 1917 1918 // copy files from the jar file to the profile folder 1919 if (docURL.getProtocol().equals("jar")) { 1920 JarURLConnection ju_connection=(JarURLConnection)docURL.openConnection(); 1921 JarFile jf =ju_connection.getJarFile(); 1839 // Create the destination 1840 destination.getParent().toFile().mkdirs(); 1841 1842 ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 1843 URL resourceUrl = classLoader.getResource(source); 1844 if (resourceUrl.getProtocol().equals("jar")) { 1845 try { 1846 JarURLConnection ju_connection = (JarURLConnection) resourceUrl.openConnection(); 1847 JarFile jf = ju_connection.getJarFile(); 1922 1848 Enumeration<JarEntry> jarEntries = jf.entries(); 1923 String res = "org/expeditee/assets/resources/"; 1924 int resLength = res.length(); 1925 1926 ZipEntry ze; 1927 1928 while(jarEntries.hasMoreElements()) { 1929 ze = jarEntries.nextElement(); 1930 if(!ze.getName().startsWith(res)) { 1931 continue; 1932 } 1933 File out = new File(FrameIO.PARENT_FOLDER + ze.getName().substring(resLength)); 1934 // System.out.println("Didn't crash here " + out.getPath()); 1935 // if(out.exists()) { 1936 // continue; 1937 // } 1938 if(ze.isDirectory()) { 1939 // System.out.println(out.getPath() + " IS DIRECTORY"); 1940 out.mkdirs(); 1941 continue; 1942 } 1943 FileOutputStream fOut = null; 1944 InputStream fIn = null; 1945 try { 1946 // System.out.println(out.getPath()); 1947 fOut = new FileOutputStream(out); 1948 fIn = classLoader.getResourceAsStream(ze.getName()); 1949 byte[] bBuffer = new byte[1024]; 1950 int nLen; 1951 while ((nLen = fIn.read(bBuffer)) > 0) { 1952 fOut.write(bBuffer, 0, nLen); 1953 } 1954 fOut.flush(); 1955 } catch (Exception e) { 1956 e.printStackTrace(); 1957 } finally { 1958 if(fOut != null) { 1959 fOut.close(); 1960 } 1961 if(fIn != null) { 1962 fIn.close(); 1963 } 1964 } 1965 } 1966 1967 // Copy files from the source folder to the profile folder 1968 } else if (docURL.getProtocol().equals("bundleresource")) { 1969 final URLConnection urlConnection = docURL.openConnection(); 1970 final Class<?> c = urlConnection.getClass(); 1971 final java.lang.reflect.Method toInvoke = c.getMethod("getFileURL"); 1972 final URL fileURL = (URL)toInvoke.invoke(urlConnection); 1973 extractResourcesFromFolder(new File(fileURL.getPath())); 1974 } else { 1975 File folder = new File(docURL.toURI().getPath()); 1976 extractResourcesFromFolder(folder); 1977 } 1978 } 1979 catch (Exception e) { 1980 e.printStackTrace(); 1981 } 1982 } 1983 1984 private static void extractResourcesFromFolder(File folder) throws IOException 1985 { 1849 extractFromJarFile(classLoader, jarEntries, source, destination); 1850 } catch (IOException e) { 1851 System.err.println("Error: FrameUtils::extractResources. Exception whilst extracting resources from Jar File. Message: " + e.getMessage()); 1852 } 1853 } else if (resourceUrl.getProtocol().equals("bundleresource")) { 1854 try { 1855 URLConnection urlConnection = resourceUrl.openConnection(); 1856 Class<?> c = urlConnection.getClass(); 1857 java.lang.reflect.Method toInvoke = c.getMethod("getFileURL"); 1858 URL fileURL = (URL) toInvoke.invoke(urlConnection); 1859 extractResourcesFromFolder(new File(fileURL.getPath()), source, destination); 1860 } catch (IOException e) { 1861 System.err.println("Error: FrameUtils::extractResources. Problem opening connection to bundleresource. Message: " + e.getMessage()); 1862 } catch (NoSuchMethodException e) { 1863 System.err.println("Error: FrameUtils::extractResources. Unable to find method URLConnection::getFileURL. Message: " + e.getMessage()); 1864 } catch (InvocationTargetException e) { 1865 System.err.println("Error: FrameUtils::extractResources. Problem invoking URLConnection::getFileURL. Message: " + e.getMessage()); 1866 } catch (IllegalAccessException e) { 1867 System.err.println("Error: FrameUtils::extractResources. Problem invoking URLConnection::getFileURL. Message: " + e.getMessage()); 1868 } 1869 } else { 1870 try { 1871 File folder = new File(resourceUrl.toURI().getPath()); 1872 extractResourcesFromFolder(folder, source, destination); 1873 } catch (URISyntaxException e) { 1874 System.err.println("Error: FrameUtils::extractResources. Problem converting URL to URI. Message: " + e.getMessage()); 1875 } catch (IOException e) { 1876 System.err.println("Error: FrameUtils::extractResources. Exception whilst extracting resources from folder. Message: " + e.getMessage()); 1877 } 1878 } 1879 1880 // Create the .res file to signal completion 1881 try { 1882 destination.resolve(".res").toFile().createNewFile(); 1883 } catch (IOException e) { 1884 System.err.println("Error: FrameUtils::extractResources. Unable to create the .res file to flag that resources have been extracted. Message: " + e.getMessage()); 1885 } 1886 } 1887 1888 private static void extractFromJarFile(ClassLoader classLoader, Enumeration<JarEntry> jarEntries, String source, Path destination) throws IOException { 1889 while (jarEntries.hasMoreElements()) { 1890 ZipEntry ze = jarEntries.nextElement(); 1891 if (!ze.getName().startsWith(source)) { 1892 continue; 1893 } 1894 File out = destination.resolve(ze.getName().substring(source.length())).toFile(); 1895 if (ze.isDirectory()) { 1896 out.mkdirs(); 1897 continue; 1898 } 1899 FileOutputStream fOut = null; 1900 InputStream fIn = null; 1901 try { 1902 fOut = new FileOutputStream(out); 1903 fIn = classLoader.getResourceAsStream(ze.getName()); 1904 byte[] bBuffer = new byte[1024]; 1905 int nLen; 1906 while ((nLen = fIn.read(bBuffer)) > 0) { 1907 fOut.write(bBuffer, 0, nLen); 1908 } 1909 fOut.flush(); 1910 } catch (Exception e) { 1911 e.printStackTrace(); 1912 } finally { 1913 if (fOut != null) { 1914 fOut.close(); 1915 } 1916 if (fIn != null) { 1917 fIn.close(); 1918 } 1919 } 1920 } 1921 } 1922 1923 private static void extractResourcesFromFolder(File folder, String source, Path destination) throws IOException { 1986 1924 LinkedList<File> items = new LinkedList<File>(); 1987 1925 items.addAll(Arrays.asList(folder.listFiles())); 1988 1926 LinkedList<File> files = new LinkedList<File>(); 1989 String res = "org" + File.separator + "expeditee" + File.separator + "assets" + File.separator + "resources";1990 int resLength = res.length();1991 1927 1992 1928 while (items.size() > 0) { 1993 1929 File file = items.remove(0); 1994 if (file.isFile()) {1995 if (!file.getName().contains(".svn")) {1930 if (file.isFile()) { 1931 if (!file.getName().contains(".svn")) { 1996 1932 files.add(file); 1997 1933 } … … 2003 1939 } 2004 1940 for (File file : files) { 2005 System.out.println(file.getPath()); 2006 File out = new File(FrameIO.PARENT_FOLDER + file.getPath().substring(file.getPath().indexOf(res) + resLength)); 2007 // if(out.exists()) { 2008 // continue; 2009 // } 1941 String path = file.getPath(); 1942 System.out.println(path); 1943 Path relativize = folder.toPath().relativize(Paths.get(file.getPath())); 1944 File out = destination.resolve(relativize).toFile(); 2010 1945 copyFile(file, out, true); 2011 1946 } … … 2017 1952 * @throws IOException 2018 1953 */ 2019 public static void copyFile(File src, File dst, boolean overWrite) throws IOException 2020 { 2021 if(!overWrite && dst.exists()) { 1954 public static void copyFile(File src, File dst, boolean overWrite) throws IOException { 1955 if (!overWrite && dst.exists()) { 2022 1956 return; 2023 1957 } 2024 1958 2025 1959 dst.getParentFile().mkdirs(); 2026 1960 FileOutputStream fOut = null; … … 2039 1973 e.printStackTrace(); 2040 1974 } finally { 2041 if (fOut != null) {1975 if (fOut != null) { 2042 1976 fOut.close(); 2043 1977 } 2044 if (fIn != null) {1978 if (fIn != null) { 2045 1979 fIn.close(); 2046 1980 } … … 2048 1982 } 2049 1983 2050 public static Text getLastEdited() 2051 { 1984 public static Text getLastEdited() { 2052 1985 return LastEdited; 2053 1986 } 2054 1987 2055 public static Collection<Text> getCurrentTextItems() 2056 { 1988 public static Collection<Text> getCurrentTextItems() { 2057 1989 Collection<Text> currentTextItems = new LinkedHashSet<Text>(); 2058 1990 Collection<Item> currentItems = getCurrentItems(null);
Note:
See TracChangeset
for help on using the changeset viewer.