From 1fd42f81c4a9884f5b702ab9ff854393b2dc5256 Mon Sep 17 00:00:00 2001 From: Marko Živković Date: Wed, 17 Dec 2014 00:26:30 +0000 Subject: - Limiting number of empty files to 4 - Fixed small issue, where another new line was appended to files whenever the file was opened - Added translations for previously hard coded dialog messages. git-svn-id: https://svn.code.sf.net/p/xlogo4schools/svn/trunk@13 3b0d7934-f7ef-4143-9606-b51f2e2281fd --- logo/src/xlogo/kernel/userspace/UserSpace.java | 10 +++++- .../kernel/userspace/context/LogoContext.java | 15 +++++++++ .../src/xlogo/kernel/userspace/files/LogoFile.java | 14 ++++++-- logo/src/xlogo/storage/StorableDocument.java | 8 +++++ logo/src/xlogo/storage/WSManager.java | 7 ++-- logo/src/xlogo/storage/global/GlobalConfig.java | 22 +++++++------ logo/src/xlogo/storage/user/UserConfig.java | 2 -- .../xlogo/storage/workspace/WorkspaceConfig.java | 37 ++++++++++++++++------ 8 files changed, 88 insertions(+), 27 deletions(-) diff --git a/logo/src/xlogo/kernel/userspace/UserSpace.java b/logo/src/xlogo/kernel/userspace/UserSpace.java index 82010e9..6f2c065 100644 --- a/logo/src/xlogo/kernel/userspace/UserSpace.java +++ b/logo/src/xlogo/kernel/userspace/UserSpace.java @@ -30,6 +30,7 @@ package xlogo.kernel.userspace; import java.util.ArrayList; import java.util.Collection; +import xlogo.AppSettings; import xlogo.Logo; import xlogo.interfaces.BroadcasterErrorFileContainer; import xlogo.interfaces.X4SModeSwitcher; @@ -89,7 +90,7 @@ public class UserSpace implements X4SModeSwitcher, LogoFileContainer, Broadcaste * The application can still be used or terminated normally. At least the user has discovered a new bug and he or she * can report it. * - * TODO write a log file? + * TODO write a log file? Send an e-mail? * * @param e */ @@ -293,9 +294,16 @@ public class UserSpace implements X4SModeSwitcher, LogoFileContainer, Broadcaste return false; } + /** + * Fails with a message if there are more than the maximum allowed empty files in the current context + */ @Override public void createFile(String fileName) throws IOException { + if (contextManager.getContext().hasTooManyEmptyFiles()){ + DialogMessenger.getInstance().dispatchMessage(AppSettings.getInstance().translate("message.too.many.empty.files")); + return; + } try { filesManager.createFile(fileName); diff --git a/logo/src/xlogo/kernel/userspace/context/LogoContext.java b/logo/src/xlogo/kernel/userspace/context/LogoContext.java index 6c93e1e..6c4f979 100644 --- a/logo/src/xlogo/kernel/userspace/context/LogoContext.java +++ b/logo/src/xlogo/kernel/userspace/context/LogoContext.java @@ -40,6 +40,7 @@ import xlogo.kernel.userspace.GlobalVariableTable; import xlogo.kernel.userspace.PropertyListTable; import xlogo.kernel.userspace.files.LogoFile; import xlogo.kernel.userspace.procedures.Procedure; +import xlogo.storage.WSManager; import xlogo.storage.global.GlobalConfig; /** * A LogoContext contains all the symbol tables for execution of Logo programs

@@ -122,6 +123,20 @@ public class LogoContext return guiMap; } + public boolean hasTooManyEmptyFiles(){ + int max = WSManager.getWorkspaceConfig().getMaxEmptyFiles(); + int count = 0; + for(LogoFile file: files.values()){ + if (file.isEmpty()){ + count++; + if(count >= max){ + return true; + } + } + } + return false; + } + /* * Context dependent operations */ diff --git a/logo/src/xlogo/kernel/userspace/files/LogoFile.java b/logo/src/xlogo/kernel/userspace/files/LogoFile.java index e4ace39..693e3f3 100644 --- a/logo/src/xlogo/kernel/userspace/files/LogoFile.java +++ b/logo/src/xlogo/kernel/userspace/files/LogoFile.java @@ -359,6 +359,14 @@ public class LogoFile extends StorableDocument implements ExecutablesContainer, return userConfig.getSourceDirectory(); } + /** + * More efficient test without generating entire text + */ + @Override + public boolean isEmpty(){ + return allProcedures.isEmpty() || (allProcedures.size() == 1 && allProcedures.get(0).getText().isEmpty()); + } + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SERIALIZATION AND DESERIALIZATION * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * @@ -374,6 +382,9 @@ public class LogoFile extends StorableDocument implements ExecutablesContainer, text.append(proc.getText()); text.append("\n"); } + if (text.length() > 0){ + text.deleteCharAt(text.length() - 1); + } return text.toString(); } @@ -768,6 +779,5 @@ public class LogoFile extends StorableDocument implements ExecutablesContainer, for (ProcedureMapListener listener : procedureMapListeners) listener.undefined(getPlainName(), procedure); } - - + } diff --git a/logo/src/xlogo/storage/StorableDocument.java b/logo/src/xlogo/storage/StorableDocument.java index d3fe8ed..0551ff9 100644 --- a/logo/src/xlogo/storage/StorableDocument.java +++ b/logo/src/xlogo/storage/StorableDocument.java @@ -177,6 +177,14 @@ public abstract class StorableDocument extends Storable parseText(br); } + /** + * Whether the underlying text representation is the empty string + * @return + */ + public boolean isEmpty(){ + return getText().equals(""); + } + /** * Setting text will invalidate the current text. * The new text is then parsed to the concrete document structure. diff --git a/logo/src/xlogo/storage/WSManager.java b/logo/src/xlogo/storage/WSManager.java index e43c0f3..b9fb6b9 100644 --- a/logo/src/xlogo/storage/WSManager.java +++ b/logo/src/xlogo/storage/WSManager.java @@ -30,6 +30,7 @@ package xlogo.storage; import java.io.File; import java.io.IOException; +import xlogo.AppSettings; import xlogo.messages.async.dialog.DialogMessenger; import xlogo.storage.global.GlobalConfig; import xlogo.storage.user.UserConfig; @@ -384,9 +385,9 @@ public class WSManager { if (!isGlobalConfigDirectory(victim) && !isWorkspaceDirectory(victim) && !isUserDirectory(victim)) { - DialogMessenger.getInstance().dispatchError( - "Security Violation", - "Attempt to delete a directory that is not under control of this application: " + victim.toString()); + String title = AppSettings.getInstance().translate("error.security.violation.title"); + String message = AppSettings.getInstance().translate("error.attempt.delete.non.x4s.file"); + DialogMessenger.getInstance().dispatchError(title, message + ' ' + victim.toString()); throw new SecurityException(); } diff --git a/logo/src/xlogo/storage/global/GlobalConfig.java b/logo/src/xlogo/storage/global/GlobalConfig.java index 5c0a959..7e1a6e3 100644 --- a/logo/src/xlogo/storage/global/GlobalConfig.java +++ b/logo/src/xlogo/storage/global/GlobalConfig.java @@ -93,10 +93,9 @@ public class GlobalConfig extends StorableObject implements Serializable { } catch (Exception e) { logger.error("GlobalConfig was corrupted."); - DialogMessenger.getInstance().dispatchError( - "Error while loading configuration files", - "Could not read GlobalConfig file " + e.toString() - + "\n Instead creating a new one.\nYou might need to import you workspaces manually."); + String title = AppSettings.getInstance().translate("error.loading.config.files.title"); + String message = AppSettings.getInstance().translate("error.loading.config.files"); + DialogMessenger.getInstance().dispatchError(title, message + e.toString()); gcf.delete(); globalConfig = null; } @@ -112,8 +111,9 @@ public class GlobalConfig extends StorableObject implements Serializable { // Best effort : We will try to operate the program without storing anything on disk logger.error("Cannot store global config at " + gcf.getAbsolutePath() + ". Running in virtual mode."); globalConfig = getNewVirtualInstance(); - DialogMessenger.getInstance().dispatchError("Error while setting up XLogo4Schools", - "Could not create or open GlobalConfig file at default location: " + e.toString()); + String title = AppSettings.getInstance().translate("error.setting.up.x4s.title"); + String message = AppSettings.getInstance().translate("error.setting.up.x4s"); + DialogMessenger.getInstance().dispatchError(title, message + e.toString()); } } globalConfig.init(); @@ -155,9 +155,13 @@ public class GlobalConfig extends StorableObject implements Serializable { if (lostWorkspaces.size() > 0) { StringBuilder msg = new StringBuilder(); - msg.append("Some workspaces could not be found:\n"); // TODO translate + String message = AppSettings.getInstance().translate("message.some.workspaces.not.found"); + String at = AppSettings.getInstance().translate("word.at.filesystem.location"); + msg.append(message); for (Entry e : lostWorkspaces.entrySet()) { - msg.append("\t").append(e.getKey()).append(" at ").append(e.getValue()).append("\n"); + msg.append('\t').append(e.getKey()) + .append(' ').append(at).append(' ') + .append(e.getValue()).append('\n'); } DialogMessenger.getInstance().dispatchMessage(msg.toString()); } @@ -467,7 +471,7 @@ public class GlobalConfig extends StorableObject implements Serializable { */ public void leaveWorkspace() throws IOException { if (currentWorkspace == null) - throw new IllegalStateException("Attempt to leave workspace without being in one."); + throw new IllegalStateException(AppSettings.getInstance().translate("error.leaving.ws.without.being.in.one")); logger.trace("Leaving workspace: " + currentWorkspace.getWorkspaceName()); if (currentWorkspace.getActiveUser() != null) { diff --git a/logo/src/xlogo/storage/user/UserConfig.java b/logo/src/xlogo/storage/user/UserConfig.java index 2d6b1c0..ebe5584 100644 --- a/logo/src/xlogo/storage/user/UserConfig.java +++ b/logo/src/xlogo/storage/user/UserConfig.java @@ -403,8 +403,6 @@ public class UserConfig extends StorableObject implements Serializable // The below properties are essentially copied from the old XLogo // they might get (re)moved or changed - final String version="0.9.96pre 27/06/12"; // TODO not needed? new version? - /** * Drawing Quality */ diff --git a/logo/src/xlogo/storage/workspace/WorkspaceConfig.java b/logo/src/xlogo/storage/workspace/WorkspaceConfig.java index 3a09e41..7f67897 100644 --- a/logo/src/xlogo/storage/workspace/WorkspaceConfig.java +++ b/logo/src/xlogo/storage/workspace/WorkspaceConfig.java @@ -73,6 +73,7 @@ public class WorkspaceConfig extends StorableObject implements Serializable { public static final String VIRTUAL_WORKSPACE = "Guest Workspace (no automatic save)"; public static final String USB_DEFAULT_WORKSPACE = "XLogo4Schools"; public static final String USER_DEFAULT_WORKSPACE = "XLogo4Schools-Workspace"; + public static final int MAX_EMPTY_FILES = 4; private static Logger logger = LogManager.getLogger(WorkspaceConfig.class.getSimpleName()); @@ -325,12 +326,13 @@ public class WorkspaceConfig extends StorableObject implements Serializable { store(); } catch (IOException e) { - DialogMessenger.getInstance().dispatchError("Workspace Error", "Could not store workspace."); // TODO translate + String title = AppSettings.getInstance().translate("general.error.title"); + String message = AppSettings.getInstance().translate("error.could.not.store.ws"); + DialogMessenger.getInstance().dispatchError(title, message); } if (!existsUserPhysically(username)){ UserConfig.createNewUser(this, username); } - lastActiveUser = username; } @@ -390,8 +392,11 @@ public class WorkspaceConfig extends StorableObject implements Serializable { public UserConfig loadUser(String username) throws IOException { logger.trace("Loading user: " + username); if (!existsUserLogically(username)) { - DialogMessenger.getInstance().dispatchError("Workspace Error", - "Attempt to load inexistent user: " + username + ". Try to import this user."); + AppSettings as = AppSettings.getInstance(); + String title = as.translate("general.error.title"); + String msg1 = as.translate("error.attempt.load.inexistent.user"); + String msg2 = as.translate("error.suggest.try.to.import.user"); + DialogMessenger.getInstance().dispatchError(title, msg1 + username + ". " + msg2); return null; } @@ -404,7 +409,10 @@ public class WorkspaceConfig extends StorableObject implements Serializable { // but it does exist logically => it must have been corrupted externally. // => restore it. if (!getLocation().mkdirs()) { - DialogMessenger.getInstance().dispatchError("Workspace Error", "Could not make required directories."); + AppSettings as = AppSettings.getInstance(); + String title = as.translate("general.error.title"); + String msg = as.translate("error.could.not.make.directories"); + DialogMessenger.getInstance().dispatchError(title, msg); return null; } // user creation requires existence of the workspace on file system @@ -412,7 +420,10 @@ public class WorkspaceConfig extends StorableObject implements Serializable { store(); } catch (IOException e) { - DialogMessenger.getInstance().dispatchError("Workspace Error", "Could not store workspace."); + AppSettings as = AppSettings.getInstance(); + String title = as.translate("general.error.title"); + String msg = as.translate("error.could.not.store.ws"); + DialogMessenger.getInstance().dispatchError(title, msg); } return UserConfig.createNewUser(this, username); } @@ -432,14 +443,16 @@ public class WorkspaceConfig extends StorableObject implements Serializable { ArrayList users = new ArrayList(); if (WSManager.isWorkspaceDirectory(getLocation())) { - DialogMessenger.getInstance().dispatchError("Workspace Error", - "Current workspace was probably deleted. I will recreate it."); + AppSettings as = AppSettings.getInstance(); + String title = as.translate("general.error.title"); + String msg = as.translate("error.current.ws.deleted.I.will.recreate.it"); + DialogMessenger.getInstance().dispatchError(title, msg); try { store(); } catch (IOException e) { - DialogMessenger.getInstance().dispatchError("Workspace Error", - "I could not recreate the Workspace. Try to delete the Workspace and recreate it manually."); + String msg2 = as.translate("error.could.not.recreate.try.manually"); + DialogMessenger.getInstance().dispatchError(title, msg2); return users; } } @@ -662,6 +675,10 @@ public class WorkspaceConfig extends StorableObject implements Serializable { getContestSettings().setNOfContestBonusFiles(nOfContestBonusFiles); } + public int getMaxEmptyFiles(){ + return MAX_EMPTY_FILES; + } + /* * Syntax Highlighting */ -- cgit v1.2.3