diff --git a/VioletProductSwing/VioletProduct.swing/.classpath b/VioletProductSwing/VioletProduct.swing/.classpath
new file mode 100644
index 0000000..3c2784a
--- /dev/null
+++ b/VioletProductSwing/VioletProduct.swing/.classpath
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/VioletProductSwing/VioletProduct.swing/.project b/VioletProductSwing/VioletProduct.swing/.project
new file mode 100644
index 0000000..c13b4a7
--- /dev/null
+++ b/VioletProductSwing/VioletProduct.swing/.project
@@ -0,0 +1,17 @@
+
+
+ VioletProduct.swing
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/VioletProductSwing/VioletProduct.swing/horstmann.eclipse.code.formatter.xml b/VioletProductSwing/VioletProduct.swing/horstmann.eclipse.code.formatter.xml
new file mode 100644
index 0000000..bef0923
--- /dev/null
+++ b/VioletProductSwing/VioletProduct.swing/horstmann.eclipse.code.formatter.xml
@@ -0,0 +1,246 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/VioletProductSwing/VioletProduct.swing/pom.xml b/VioletProductSwing/VioletProduct.swing/pom.xml
new file mode 100644
index 0000000..b8f1cef
--- /dev/null
+++ b/VioletProductSwing/VioletProduct.swing/pom.xml
@@ -0,0 +1,129 @@
+
+
+ 4.0.0
+ com.horstmann.violet.product.swing
+ com.horstmann.violet
+
+ Violet UML Editor
+ 2.0.0-SNAPSHOT
+ The java Swing based version of Violet
+
+
+ com.horstmann.violet.framework
+ com.horstmann.violet.framework
+ 2.0.0-SNAPSHOT
+
+
+ com.horstmann.violet.plugin
+ com.horstmann.violet.plugin.classdiagram
+ 2.0.0-SNAPSHOT
+
+
+ com.horstmann.violet.plugin
+ com.horstmann.violet.plugin.objectdiagram
+ 2.0.0-SNAPSHOT
+
+
+ com.horstmann.violet.plugin
+ com.horstmann.violet.plugin.activitydiagram
+ 2.0.0-SNAPSHOT
+
+
+ com.horstmann.violet.plugin
+ com.horstmann.violet.plugin.sequencediagram
+ 2.0.0-SNAPSHOT
+
+
+ com.horstmann.violet.plugin
+ com.horstmann.violet.plugin.statediagram
+ 2.0.0-SNAPSHOT
+
+
+ com.horstmann.violet.plugin
+ com.horstmann.violet.plugin.usecasediagram
+ 2.0.0-SNAPSHOT
+
+
+
+
+
+ src/main/resources
+
+
+ src/main/java
+
+ **/*.gif
+ **/*.jpg
+ **/*.png
+ **/*.txt
+ **/*.properties
+ **/*.xml
+
+
+
+
+
+ maven-compiler-plugin
+ 2.0.2
+
+
+ 1.6
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 1.3.3
+
+
+ package
+
+ shade
+
+
+
+
+ *:*
+
+ META-INF/*.SF
+ META-INF/*.DSA
+ META-INF/*.RSA
+
+
+
+
+
+ META-INF/services/com.horstmann.violet.framework.plugin.IDiagramPlugin
+
+
+ com.horstmann.violet.UMLEditorApplication
+
+
+
+
+
+
+
+
+
+
+ web.sourceforge.net
+ Violet's Maven Repository
+
+ sftp://web.sourceforge.net/home/groups/v/vi/violet/htdocs/maven2/repo
+
+
+
+
+
+ violet.repo
+ Violet's Maven repository (public access)
+ http://violet.sourceforge.net/maven2/repo/
+
+
+
+
diff --git a/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/UMLEditorApplet.java b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/UMLEditorApplet.java
new file mode 100644
index 0000000..e9fcb37
--- /dev/null
+++ b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/UMLEditorApplet.java
@@ -0,0 +1,125 @@
+/*
+ Violet - A program for editing UML diagrams.
+
+ Copyright (C) 2002 Cay S. Horstmann (http://horstmann.com)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package com.horstmann.violet;
+
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.JApplet;
+import javax.swing.JFrame;
+
+import com.horstmann.violet.application.gui.MainFrame;
+import com.horstmann.violet.framework.dialog.DialogFactory;
+import com.horstmann.violet.framework.dialog.DialogFactoryMode;
+import com.horstmann.violet.framework.file.chooser.IFileChooserService;
+import com.horstmann.violet.framework.file.chooser.JFileChooserService;
+import com.horstmann.violet.framework.file.persistence.IFilePersistenceService;
+import com.horstmann.violet.framework.file.persistence.StandardJavaFilePersistenceService;
+import com.horstmann.violet.framework.injection.bean.ManiocFramework.BeanFactory;
+import com.horstmann.violet.framework.injection.bean.ManiocFramework.BeanInjector;
+import com.horstmann.violet.framework.injection.bean.ManiocFramework.InjectedBean;
+import com.horstmann.violet.framework.plugin.PluginLoader;
+import com.horstmann.violet.framework.theme.ClassicMetalTheme;
+import com.horstmann.violet.framework.theme.ITheme;
+import com.horstmann.violet.framework.theme.ThemeManager;
+import com.horstmann.violet.framework.theme.VistaBlueTheme;
+import com.horstmann.violet.framework.userpreferences.AppletUserPreferencesDao;
+import com.horstmann.violet.framework.userpreferences.IUserPreferencesDao;
+
+/**
+ * A program for editing UML diagrams.
+ */
+public class UMLEditorApplet extends JApplet
+{
+
+ /*
+ * Applet entry point (non-Javadoc)
+ *
+ * @see java.applet.Applet#init()
+ */
+ public void init()
+ {
+ initBeanFactory();
+ BeanInjector.getInjector().inject(this);
+ createAppletWorkspace();
+ }
+
+ private void initBeanFactory() {
+ IUserPreferencesDao userPreferencesDao = new AppletUserPreferencesDao();
+ BeanFactory.getFactory().register(IUserPreferencesDao.class, userPreferencesDao);
+
+ ThemeManager themeManager = new ThemeManager();
+ ITheme theme1 = new ClassicMetalTheme();
+ ITheme theme2 = new VistaBlueTheme();
+ List themeList = new ArrayList();
+ themeList.add(theme1);
+ themeList.add(theme2);
+ themeManager.setInstalledThemes(themeList);
+ themeManager.setInstalledThemes(themeList);
+ BeanFactory.getFactory().register(ThemeManager.class, themeManager);
+ themeManager.applyPreferedTheme();
+
+ IFilePersistenceService filePersistenceService = new StandardJavaFilePersistenceService();
+ BeanFactory.getFactory().register(IFilePersistenceService.class, filePersistenceService);
+
+ DialogFactory dialogFactory = new DialogFactory(DialogFactoryMode.INTERNAL);
+ BeanFactory.getFactory().register(DialogFactory.class, dialogFactory);
+
+ IFileChooserService fileChooserService = new JFileChooserService();
+ BeanFactory.getFactory().register(IFileChooserService.class, fileChooserService);
+
+ }
+
+
+ /**
+ * Creates workspace when application works as an applet. It contains :
+ * + plugins loading + GUI theme management + launging argments to open diagram
+ */
+ private void createAppletWorkspace()
+ {
+ installPlugins();
+ MainFrame mainFrame = new MainFrame();
+ mainFrame.setExtendedState(JFrame.MAXIMIZED_BOTH);
+ mainFrame.addWindowListener(new WindowAdapter()
+ {
+ public void windowClosed(WindowEvent e)
+ {
+ System.out.println("editor closed");
+ }
+ });
+ setContentPane(mainFrame.getContentPane());
+ setJMenuBar(mainFrame.getJMenuBar());
+ }
+
+ /**
+ * Install plugins
+ */
+ private void installPlugins()
+ {
+ this.pluginLoader.installPlugins();
+ }
+
+ @InjectedBean
+ private PluginLoader pluginLoader;
+
+}
\ No newline at end of file
diff --git a/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/UMLEditorApplication.java b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/UMLEditorApplication.java
new file mode 100644
index 0000000..2b8da15
--- /dev/null
+++ b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/UMLEditorApplication.java
@@ -0,0 +1,216 @@
+/*
+ Violet - A program for editing UML diagrams.
+
+ Copyright (C) 2002 Cay S. Horstmann (http://horstmann.com)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package com.horstmann.violet;
+
+import java.io.File;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+
+import javax.swing.JFrame;
+
+import com.horstmann.violet.application.gui.MainFrame;
+import com.horstmann.violet.application.gui.SplashScreen;
+import com.horstmann.violet.framework.dialog.DialogFactory;
+import com.horstmann.violet.framework.dialog.DialogFactoryMode;
+import com.horstmann.violet.framework.file.GraphFile;
+import com.horstmann.violet.framework.file.IFile;
+import com.horstmann.violet.framework.file.IGraphFile;
+import com.horstmann.violet.framework.file.LocalFile;
+import com.horstmann.violet.framework.file.chooser.IFileChooserService;
+import com.horstmann.violet.framework.file.chooser.JFileChooserService;
+import com.horstmann.violet.framework.file.persistence.IFilePersistenceService;
+import com.horstmann.violet.framework.file.persistence.StandardJavaFilePersistenceService;
+//tms import com.horstmann.violet.framework.file.persistence.XStreamBasedPersistenceService;
+import com.horstmann.violet.framework.injection.bean.ManiocFramework.BeanFactory;
+import com.horstmann.violet.framework.injection.bean.ManiocFramework.BeanInjector;
+import com.horstmann.violet.framework.injection.bean.ManiocFramework.InjectedBean;
+import com.horstmann.violet.framework.plugin.PluginLoader;
+import com.horstmann.violet.framework.theme.ClassicMetalTheme;
+import com.horstmann.violet.framework.theme.ITheme;
+import com.horstmann.violet.framework.theme.ThemeManager;
+import com.horstmann.violet.framework.theme.VistaBlueTheme;
+import com.horstmann.violet.framework.userpreferences.DefaultUserPreferencesDao;
+import com.horstmann.violet.framework.userpreferences.IUserPreferencesDao;
+import com.horstmann.violet.framework.userpreferences.UserPreferencesService;
+import com.horstmann.violet.framework.util.VersionChecker;
+import com.horstmann.violet.workspace.IWorkspace;
+import com.horstmann.violet.workspace.Workspace;
+
+/**
+ * A program for editing UML diagrams.
+ */
+public class UMLEditorApplication
+{
+
+ /**
+ * Standalone application entry point
+ *
+ * @param args (could contains file to open)
+ */
+ public static void main(String[] args)
+ {
+ for (int i = 0; i < args.length; i++)
+ {
+ String arg = args[i];
+ if ("-reset".equals(arg))
+ {
+ initBeanFactory();
+ UserPreferencesService service = BeanFactory.getFactory().getBean(UserPreferencesService.class);
+ service.reset();
+ System.out.println("User preferences reset done.");
+ }
+ if ("-english".equals(arg))
+ {
+ Locale.setDefault(Locale.ENGLISH);
+ System.out.println("Language forced to english.");
+ }
+ if ("-help".equals(arg) || "-?".equals(arg))
+ {
+ System.out.println("Violet UML Editor command line help. Options are :");
+ System.out.println("-reset to reset user preferences,");
+ System.out.println("-english to force language to english.");
+ return;
+ }
+ }
+ new UMLEditorApplication(args);
+ }
+
+ /**
+ * Default constructor
+ *
+ * @param filesToOpen
+ */
+ private UMLEditorApplication(String[] filesToOpen)
+ {
+ initBeanFactory();
+ BeanInjector.getInjector().inject(this);
+ createDefaultWorkspace(filesToOpen);
+ }
+
+ private static void initBeanFactory() {
+ IUserPreferencesDao userPreferencesDao = new DefaultUserPreferencesDao();
+ BeanFactory.getFactory().register(IUserPreferencesDao.class, userPreferencesDao);
+
+ ThemeManager themeManager = new ThemeManager();
+ ITheme theme1 = new ClassicMetalTheme();
+ ITheme theme2 = new VistaBlueTheme();
+ List themeList = new ArrayList();
+ themeList.add(theme1);
+ themeList.add(theme2);
+ themeManager.setInstalledThemes(themeList);
+ themeManager.applyPreferedTheme();
+ BeanFactory.getFactory().register(ThemeManager.class, themeManager);
+ themeManager.applyPreferedTheme();
+
+ IFilePersistenceService filePersistenceService = null;//tms new XStreamBasedPersistenceService();
+ BeanFactory.getFactory().register(IFilePersistenceService.class, filePersistenceService);
+
+ DialogFactory dialogFactory = new DialogFactory(DialogFactoryMode.INTERNAL);
+ BeanFactory.getFactory().register(DialogFactory.class, dialogFactory);
+
+ IFileChooserService fileChooserService = new JFileChooserService();
+ BeanFactory.getFactory().register(IFileChooserService.class, fileChooserService);
+ }
+
+
+
+ /**
+ * Creates workspace when application works as a standalone one. It contains :
+ * + plugins loading + GUI theme management + a spash screen
+ * + jvm checking
+ * + command line args
+ * + last workspace restore
+ */
+ private void createDefaultWorkspace(String[] filesToOpen)
+ {
+ installPlugins();
+ SplashScreen splashScreen = new SplashScreen();
+ splashScreen.setVisible(true);
+ this.versionChecker.check();
+ MainFrame mainFrame = new MainFrame();
+ mainFrame.setExtendedState(JFrame.MAXIMIZED_BOTH);
+ SplashScreen.displayOverEditor(mainFrame, 1000);
+ Set fullList = new HashSet();
+ Set lastSessionFiles = (Set) this.userPreferencesService.getOpenedFilesDuringLastSession(); //tms added cast to (set)
+ fullList.addAll(lastSessionFiles);
+ for (String aFileToOpen : filesToOpen)
+ {
+ try
+ {
+ LocalFile localFile = new LocalFile(new File(aFileToOpen));
+ fullList.add(localFile);
+ }
+ catch (IOException e)
+ {
+ // There's nothing to do. We're starting the program
+ // Some logs should be nive
+ e.printStackTrace();
+ }
+ }
+ // Open files
+ for (IFile aFile : lastSessionFiles)
+ {
+ try
+ {
+ IGraphFile graphFile = new GraphFile(aFile);
+ IWorkspace workspace = new Workspace(graphFile);
+ mainFrame.addTabbedPane(workspace);
+ }
+ catch (Exception e)
+ {
+ System.err.println("Unable to open file " + aFile.getFilename() + "from location " + aFile.getDirectory());
+ userPreferencesService.removeOpenedFile(aFile);
+ System.err.println("Removed from user preferences!");
+ }
+ }
+ IFile activeFile = this.userPreferencesService.getActiveDiagramFile();
+ mainFrame.setActiveDiagramPanel(activeFile);
+ mainFrame.setVisible(true);
+ splashScreen.setVisible(false);
+ splashScreen.dispose();
+ }
+
+ /**
+ * Install plugins
+ */
+ private void installPlugins()
+ {
+
+ this.pluginLoader.installPlugins();
+ }
+
+
+ @InjectedBean
+ private VersionChecker versionChecker;
+
+ @InjectedBean
+ private PluginLoader pluginLoader;
+
+ @InjectedBean
+ private UserPreferencesService userPreferencesService;
+
+
+}
\ No newline at end of file
diff --git a/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/UMLEditorWebStart.java b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/UMLEditorWebStart.java
new file mode 100644
index 0000000..cce6dc4
--- /dev/null
+++ b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/UMLEditorWebStart.java
@@ -0,0 +1,119 @@
+/*
+ Violet - A program for editing UML diagrams.
+
+ Copyright (C) 2002 Cay S. Horstmann (http://horstmann.com)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package com.horstmann.violet;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.JFrame;
+
+import com.horstmann.violet.application.gui.MainFrame;
+import com.horstmann.violet.framework.dialog.DialogFactory;
+import com.horstmann.violet.framework.dialog.DialogFactoryMode;
+import com.horstmann.violet.framework.file.chooser.IFileChooserService;
+import com.horstmann.violet.framework.file.chooser.JNLPFileChooserService;
+import com.horstmann.violet.framework.file.persistence.IFilePersistenceService;
+import com.horstmann.violet.framework.file.persistence.StandardJavaFilePersistenceService;
+import com.horstmann.violet.framework.injection.bean.ManiocFramework.BeanFactory;
+import com.horstmann.violet.framework.injection.bean.ManiocFramework.BeanInjector;
+import com.horstmann.violet.framework.injection.bean.ManiocFramework.InjectedBean;
+import com.horstmann.violet.framework.plugin.PluginLoader;
+import com.horstmann.violet.framework.theme.ClassicMetalTheme;
+import com.horstmann.violet.framework.theme.ITheme;
+import com.horstmann.violet.framework.theme.ThemeManager;
+import com.horstmann.violet.framework.theme.VistaBlueTheme;
+import com.horstmann.violet.framework.userpreferences.IUserPreferencesDao;
+import com.horstmann.violet.framework.userpreferences.JNLPUserPreferencesDao;
+
+/**
+ * A program for editing UML diagrams.
+ */
+public class UMLEditorWebStart
+{
+
+ /**
+ * Standalone application entry point
+ *
+ * @param args (could contains file to open)
+ */
+ public static void main(String[] args)
+ {
+ new UMLEditorWebStart();
+ }
+
+ /**
+ * Default constructor
+ */
+ private UMLEditorWebStart() {
+ initBeanFactory();
+ BeanInjector.getInjector().inject(this);
+ createWebstartWorkspace();
+ }
+
+ private void initBeanFactory() {
+ IUserPreferencesDao userPreferencesDao = new JNLPUserPreferencesDao();
+ BeanFactory.getFactory().register(IUserPreferencesDao.class, userPreferencesDao);
+
+ ThemeManager themeManager = new ThemeManager();
+ ITheme theme1 = new ClassicMetalTheme();
+ ITheme theme2 = new VistaBlueTheme();
+ List themeList = new ArrayList();
+ themeList.add(theme1);
+ themeList.add(theme2);
+ themeManager.setInstalledThemes(themeList);
+ themeManager.setInstalledThemes(themeList);
+ BeanFactory.getFactory().register(ThemeManager.class, themeManager);
+ themeManager.applyPreferedTheme();
+
+ IFilePersistenceService filePersistenceService = new StandardJavaFilePersistenceService();
+ BeanFactory.getFactory().register(IFilePersistenceService.class, filePersistenceService);
+
+ DialogFactory dialogFactory = new DialogFactory(DialogFactoryMode.INTERNAL);
+ BeanFactory.getFactory().register(DialogFactory.class, dialogFactory);
+
+ IFileChooserService fileChooserService = new JNLPFileChooserService();
+ BeanFactory.getFactory().register(IFileChooserService.class, fileChooserService);
+ }
+
+ /**
+ * Creates workspace when application works from java web start. It contains : + plugins loading + GUI theme management
+ */
+ private void createWebstartWorkspace()
+ {
+ installPlugins();
+ MainFrame mainFrame = new MainFrame();
+ mainFrame.setExtendedState(JFrame.MAXIMIZED_BOTH);
+ mainFrame.setVisible(true);
+ }
+
+ /**
+ * Install plugins
+ */
+ private void installPlugins()
+ {
+ this.pluginLoader.installPlugins();
+ }
+
+
+ @InjectedBean
+ private PluginLoader pluginLoader;
+
+}
\ No newline at end of file
diff --git a/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/ApplicationStopper.java b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/ApplicationStopper.java
new file mode 100644
index 0000000..76da544
--- /dev/null
+++ b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/ApplicationStopper.java
@@ -0,0 +1,123 @@
+package com.horstmann.violet.application;
+
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.ImageIcon;
+import javax.swing.JOptionPane;
+
+import com.horstmann.violet.application.gui.MainFrame;
+import com.horstmann.violet.framework.dialog.DialogFactory;
+import com.horstmann.violet.framework.file.IGraphFile;
+import com.horstmann.violet.framework.injection.bean.ManiocFramework.BeanInjector;
+import com.horstmann.violet.framework.injection.bean.ManiocFramework.InjectedBean;
+import com.horstmann.violet.framework.injection.resources.ResourceBundleInjector;
+import com.horstmann.violet.framework.injection.resources.annotation.ResourceBundleBean;
+import com.horstmann.violet.framework.userpreferences.UserPreferencesService;
+import com.horstmann.violet.workspace.IWorkspace;
+
+public class ApplicationStopper
+{
+
+ public ApplicationStopper()
+ {
+ BeanInjector.getInjector().inject(this);
+ ResourceBundleInjector.getInjector().inject(this);
+ }
+
+ /**
+ * Exits the program if no graphs have been modified or if the user agrees to abandon modified graphs or save its.
+ */
+ public void exitProgram(MainFrame mainFrame)
+ {
+ boolean ok = isItReadyToExit(mainFrame);
+ if (ok)
+ {
+ System.exit(0);
+ }
+ }
+
+ /**
+ * Asks user to save changes before exit.
+ *
+ * @return true is all is saved either false
+ */
+ private boolean isItReadyToExit(MainFrame mainFrame)
+ {
+ List dirtyWorkspaceList = new ArrayList();
+ List workspaceList = mainFrame.getWorkspaceList();
+ if (workspaceList.size() == 0) return true;
+ for (IWorkspace aWorkspacel : workspaceList)
+ {
+ IGraphFile graphFile = aWorkspacel.getGraphFile();
+ if (graphFile.isSaveRequired())
+ {
+ dirtyWorkspaceList.add(aWorkspacel);
+ }
+ }
+ int unsavedCount = dirtyWorkspaceList.size();
+ IWorkspace activeWorkspace = mainFrame.getActiveWorkspace();
+ if (unsavedCount > 0)
+ {
+ // ask user if it is ok to close
+ String message = MessageFormat.format(this.dialogExitMessage, new Object[]
+ {
+ new Integer(unsavedCount)
+ });
+ JOptionPane optionPane = new JOptionPane(message, JOptionPane.CLOSED_OPTION, JOptionPane.YES_NO_CANCEL_OPTION,
+ this.dialogExitIcon);
+ dialogFactory.showDialog(optionPane, this.dialogExitTitle, true);
+
+ int result = JOptionPane.YES_OPTION;
+ if (!JOptionPane.UNINITIALIZED_VALUE.equals(optionPane.getValue()))
+ {
+ result = ((Integer) optionPane.getValue()).intValue();
+ }
+
+ if (result == JOptionPane.CANCEL_OPTION)
+ {
+ return false;
+ }
+ if (result == JOptionPane.YES_OPTION)
+ {
+ for (IWorkspace aDirtyWorkspace : dirtyWorkspaceList)
+ {
+ aDirtyWorkspace.getGraphFile().save();
+ }
+ this.userPreferencesService.setActiveDiagramFile(activeWorkspace.getGraphFile());
+ return true;
+ }
+ if (result == JOptionPane.NO_OPTION)
+ {
+ this.userPreferencesService.setActiveDiagramFile(activeWorkspace.getGraphFile());
+ return true;
+ }
+ }
+ if (unsavedCount == 0)
+ {
+ if (activeWorkspace != null)
+ {
+ this.userPreferencesService.setActiveDiagramFile(activeWorkspace.getGraphFile());
+ }
+ return true;
+ }
+ return false;
+ }
+
+ @ResourceBundleBean(key = "dialog.exit.icon")
+ private ImageIcon dialogExitIcon;
+
+ @ResourceBundleBean(key = "dialog.exit.ok")
+ private String dialogExitMessage;
+
+ @ResourceBundleBean(key = "dialog.exit.title")
+ private String dialogExitTitle;
+
+ @InjectedBean
+ private DialogFactory dialogFactory;
+
+ @InjectedBean
+ private UserPreferencesService userPreferencesService;
+
+}
diff --git a/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/ApplicationStopper.properties b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/ApplicationStopper.properties
new file mode 100644
index 0000000..15d7ae9
--- /dev/null
+++ b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/ApplicationStopper.properties
@@ -0,0 +1,3 @@
+dialog.exit.title=Exit
+dialog.exit.ok={0} diagram{0,choice,1#|2#s} {0,choice,1#has|2#have} modified. Save changes?
+dialog.exit.icon=/icons/64x64/exit.png
diff --git a/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/ApplicationStopper_fr.properties b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/ApplicationStopper_fr.properties
new file mode 100644
index 0000000..1700754
--- /dev/null
+++ b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/ApplicationStopper_fr.properties
@@ -0,0 +1,3 @@
+dialog.exit.title=Quitter
+dialog.exit.ok={0} diagramme{0,choice,1#|2#s} modifi\u00e9{0,choice,1#|2#s}. Enregistrer les changements?
+dialog.exit.icon=/icons/64x64/exit.png
diff --git a/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/gui/MainFrame.java b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/gui/MainFrame.java
new file mode 100644
index 0000000..47d5a3a
--- /dev/null
+++ b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/gui/MainFrame.java
@@ -0,0 +1,421 @@
+/*
+ Violet - A program for editing UML diagrams.
+
+ Copyright (C) 2008 Cay S. Horstmann (http://horstmann.com)
+ Alexandre de Pellegrin (http://alexdp.free.fr);
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package com.horstmann.violet.application.gui;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.GradientPaint;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Paint;
+import java.awt.Toolkit;
+import java.awt.event.MouseWheelListener;
+import java.awt.geom.Point2D;
+import java.beans.BeanInfo;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.JFrame;
+import javax.swing.JMenuBar;
+import javax.swing.JPanel;
+import javax.swing.JTabbedPane;
+import javax.swing.SwingUtilities;
+import javax.swing.border.EmptyBorder;
+
+import com.horstmann.violet.application.help.AboutDialog;
+import com.horstmann.violet.application.menu.MenuFactory;
+import com.horstmann.violet.framework.dialog.DialogFactory;
+import com.horstmann.violet.framework.file.GraphFile;
+import com.horstmann.violet.framework.file.IFile;
+import com.horstmann.violet.framework.file.IGraphFile;
+import com.horstmann.violet.framework.file.chooser.IFileChooserService;
+import com.horstmann.violet.framework.injection.bean.ManiocFramework.BeanInjector;
+import com.horstmann.violet.framework.injection.bean.ManiocFramework.InjectedBean;
+import com.horstmann.violet.framework.injection.resources.ResourceBundleInjector;
+import com.horstmann.violet.framework.injection.resources.annotation.ResourceBundleBean;
+import com.horstmann.violet.framework.theme.ITheme;
+import com.horstmann.violet.framework.theme.ThemeManager;
+import com.horstmann.violet.product.diagram.abstracts.IGraph;
+import com.horstmann.violet.product.diagram.abstracts.node.AbstractNode;
+import com.horstmann.violet.product.diagram.abstracts.property.ArrowHead;
+import com.horstmann.violet.product.diagram.abstracts.property.BentStyle;
+import com.horstmann.violet.product.diagram.abstracts.property.LineStyle;
+import com.horstmann.violet.workspace.IWorkspace;
+import com.horstmann.violet.workspace.IWorkspaceListener;
+import com.horstmann.violet.workspace.Workspace;
+
+/**
+ * This desktop frame contains panes that show graphs.
+ *
+ * @author Alexandre de Pellegrin
+ */
+@ResourceBundleBean(resourceReference = AboutDialog.class)
+public class MainFrame extends JFrame
+{
+ /**
+ * Constructs a blank frame with a desktop pane but no graph windows.
+ *
+ */
+ public MainFrame()
+ {
+ BeanInjector.getInjector().inject(this);
+ ResourceBundleInjector.getInjector().inject(this);
+ setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
+ this.dialogFactory.setDialogOwner(this);
+ decorateFrame();
+ setInitialSize();
+ createMenuBar();
+ getContentPane().add(this.getMainPanel());
+ }
+
+ /**
+ * Sets initial size on startup
+ */
+ private void setInitialSize()
+ {
+ Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+ int screenWidth = (int) screenSize.getWidth();
+ int screenHeight = (int) screenSize.getHeight();
+ setBounds(screenWidth / 16, screenHeight / 16, screenWidth * 7 / 8, screenHeight * 7 / 8);
+ // For screenshots only -> setBounds(50, 50, 850, 650);
+ }
+
+ /**
+ * Decorates the frame (title, icon...)
+ */
+ private void decorateFrame()
+ {
+ setTitle(this.applicationName);
+ setIconImage(this.applicationIcon);
+ }
+
+ /**
+ * Creates menu bar
+ */
+ private void createMenuBar()
+ {
+ JMenuBar menuBar = new JMenuBar();
+ menuBar.setFont(this.themeManager.getTheme().getMenubarFont());
+ MenuFactory menuFactory = getMenuFactory();
+ menuBar.add(menuFactory.getFileMenu(this));
+ menuBar.add(menuFactory.getEditMenu(this));
+ menuBar.add(menuFactory.getViewMenu(this));
+ menuBar.add(menuFactory.getHelpMenu(this));
+ setJMenuBar(menuBar);
+ }
+
+ /**
+ * Adds a tabbed pane (only if not already added)
+ *
+ * @param c the component to display in the internal frame
+ */
+ public void addTabbedPane(final IWorkspace workspace)
+ {
+ replaceWelcomePanelByTabbedPane();
+ if (this.workspaceList.contains(workspace))
+ {
+ return;
+ }
+ this.workspaceList.add(workspace);
+ this.getTabbedPane().add(workspace.getTitle(), workspace.getAWTComponent());
+ listenToDiagramPanelEvents(workspace);
+ // Use invokeLater to prevent exception
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ public void run()
+ {
+ getTabbedPane().setSelectedIndex(workspaceList.size() - 1);
+ workspace.getEditorPart().getSwingComponent().requestFocus();
+ }
+ });
+ }
+
+ /**
+ * Add a listener to perform action when something happens on this diagram
+ *
+ * @param diagramPanel
+ */
+ private void listenToDiagramPanelEvents(final IWorkspace diagramPanel)
+ {
+ diagramPanel.addListener(new IWorkspaceListener()
+ {
+ public void titleChanged(String newTitle)
+ {
+ int pos = workspaceList.indexOf(diagramPanel);
+ getTabbedPane().setTitleAt(pos, newTitle);
+ }
+
+ public void graphCouldBeSaved()
+ {
+ // nothing to do here
+ }
+
+ public void mustOpenfile(IFile file)
+ {
+ try
+ {
+ IGraphFile graphFile = new GraphFile(file);
+ IWorkspace newWorkspace = new Workspace(graphFile);
+ addTabbedPane(newWorkspace);
+ }
+ catch (IOException e)
+ {
+ DialogFactory.getInstance().showErrorDialog(e.getMessage());
+ }
+ }
+ });
+ }
+
+ private void replaceWelcomePanelByTabbedPane()
+ {
+ WelcomePanel welcomePanel = this.getWelcomePanel();
+ JTabbedPane tabbedPane = getTabbedPane();
+ getMainPanel().remove(welcomePanel);
+ getMainPanel().add(tabbedPane, BorderLayout.CENTER);
+ repaint();
+ }
+
+ private void replaceTabbedPaneByWelcomePanel()
+ {
+ this.welcomePanel = null;
+ WelcomePanel welcomePanel = this.getWelcomePanel();
+ JTabbedPane tabbedPane = getTabbedPane();
+ getMainPanel().remove(tabbedPane);
+ getMainPanel().add(welcomePanel, BorderLayout.CENTER);
+ repaint();
+ }
+
+ /**
+ * @return the tabbed pane that contains diagram panels
+ */
+ public JTabbedPane getTabbedPane()
+ {
+ if (this.tabbedPane == null)
+ {
+ this.tabbedPane = new JTabbedPane()
+ {
+ public void paint(Graphics g)
+ {
+ Graphics2D g2 = (Graphics2D) g;
+ Paint currentPaint = g2.getPaint();
+ ITheme LAF = themeManager.getTheme();
+ GradientPaint paint = new GradientPaint(getWidth() / 2, -getHeight() / 4, LAF.getWelcomeBackgroundStartColor(),
+ getWidth() / 2, getHeight() + getHeight() / 4, LAF.getWelcomeBackgroundEndColor());
+ g2.setPaint(paint);
+ g2.fillRect(0, 0, getWidth(), getHeight());
+ g2.setPaint(currentPaint);
+ super.paint(g);
+ }
+ };
+ this.tabbedPane.setOpaque(false);
+ MouseWheelListener[] mouseWheelListeners = this.tabbedPane.getMouseWheelListeners();
+ for (int i = 0; i < mouseWheelListeners.length; i++)
+ {
+ this.tabbedPane.removeMouseWheelListener(mouseWheelListeners[i]);
+ }
+ }
+ return this.tabbedPane;
+ }
+
+ /**
+ * Removes a diagram panel from this editor frame
+ *
+ * @param diagramPanel
+ */
+ public void removeDiagramPanel(IWorkspace diagramPanel)
+ {
+ if (!this.workspaceList.contains(diagramPanel))
+ {
+ return;
+ }
+ JTabbedPane tp = getTabbedPane();
+ int pos = this.workspaceList.indexOf(diagramPanel);
+ tp.remove(pos);
+ this.workspaceList.remove(diagramPanel);
+ if (tp.getTabCount() == 0)
+ {
+ replaceTabbedPaneByWelcomePanel();
+ }
+ }
+
+ /**
+ * Looks for an opened diagram from its file path and focus it
+ *
+ * @param diagramFilePath diagram file path
+ */
+ public void setActiveDiagramPanel(IFile aGraphFile)
+ {
+ if (aGraphFile == null) return;
+ for (IWorkspace aDiagramPanel : this.workspaceList)
+ {
+ IFile toCompare = aDiagramPanel.getGraphFile();
+ boolean isSameFilename = aGraphFile.getFilename().equals(toCompare.getFilename());
+ if (isSameFilename)
+ {
+ int pos = this.workspaceList.indexOf(aDiagramPanel);
+ JTabbedPane tp = getTabbedPane();
+ tp.setSelectedIndex(pos);
+ return;
+ }
+ }
+ }
+
+ /**
+ * @return true if at least a diagram is displayed
+ */
+ public boolean isThereAnyDiagramDisplayed()
+ {
+ return !this.workspaceList.isEmpty();
+ }
+
+ public List getWorkspaceList()
+ {
+ return workspaceList;
+ }
+
+ /**
+ * @return selected diagram file path (or null if not one is selected; that should never happen)
+ */
+ public IWorkspace getActiveWorkspace()
+ {
+ JTabbedPane tp = getTabbedPane();
+ int pos = tp.getSelectedIndex();
+ if (pos >= 0)
+ {
+ return this.workspaceList.get(pos);
+ }
+ throw new RuntimeException("Error while retreiving current active diagram panel");
+ }
+
+ private WelcomePanel getWelcomePanel()
+ {
+ if (this.welcomePanel == null)
+ {
+ this.welcomePanel = new WelcomePanel(this.getMenuFactory().getFileMenu(this));
+ }
+ return this.welcomePanel;
+ }
+
+ private JPanel getMainPanel() {
+ if (this.mainPanel == null) {
+ this.mainPanel = new JPanel(new BorderLayout());
+ this.mainPanel.setBorder(new EmptyBorder(0, 0, 0, 0));
+ this.mainPanel.add(this.getWelcomePanel(), BorderLayout.CENTER);
+ JPanel bottomBorderPanel = new JPanel();
+ ITheme cLAF = this.themeManager.getTheme();
+ bottomBorderPanel.setBackground(cLAF.getMenubarBackgroundColor().darker());
+ bottomBorderPanel.setBorder(new EmptyBorder(0, 0, 0, 0));
+ bottomBorderPanel.setSize(getContentPane().getWidth(), 8);
+ this.mainPanel.add(bottomBorderPanel, BorderLayout.SOUTH);
+ }
+ return this.mainPanel;
+ }
+
+ /**
+ * @return the menu factory instance
+ */
+ public MenuFactory getMenuFactory()
+ {
+ if (this.menuFactory == null)
+ {
+ menuFactory = new MenuFactory();
+ }
+ return this.menuFactory;
+ }
+
+ /**
+ * Tabbed pane instance
+ */
+ private JTabbedPane tabbedPane;
+
+ /**
+ * Panel added is not diagram is opened
+ */
+ private WelcomePanel welcomePanel;
+
+ /**
+ * Main panel
+ */
+ private JPanel mainPanel;
+
+ /**
+ * Menu factory instance
+ */
+ private MenuFactory menuFactory;
+
+ /**
+ * GUI Theme manager
+ */
+ @InjectedBean
+ private ThemeManager themeManager;
+
+ /**
+ * Needed to display dialog boxes
+ */
+ @InjectedBean
+ private DialogFactory dialogFactory;
+
+ /**
+ * Needed to open files
+ */
+ @InjectedBean
+ private IFileChooserService fileChooserService;
+
+ @ResourceBundleBean(key="app.name")
+ private String applicationName;
+
+ @ResourceBundleBean(key="app.icon")
+ private Image applicationIcon;
+
+ /**
+ * All disgram workspaces
+ */
+ private List workspaceList = new ArrayList();
+
+ // workaround for bug #4646747 in J2SE SDK 1.4.0
+ private static java.util.HashMap, BeanInfo> beanInfos;
+ static
+ {
+ beanInfos = new java.util.HashMap, BeanInfo>();
+ Class>[] cls = new Class>[]
+ {
+ Point2D.Double.class,
+ BentStyle.class,
+ ArrowHead.class,
+ LineStyle.class,
+ IGraph.class,
+ AbstractNode.class,
+ };
+ for (int i = 0; i < cls.length; i++)
+ {
+ try
+ {
+ beanInfos.put(cls[i], java.beans.Introspector.getBeanInfo(cls[i]));
+ }
+ catch (java.beans.IntrospectionException ex)
+ {
+ }
+ }
+ }
+}
diff --git a/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/gui/SplashScreen.java b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/gui/SplashScreen.java
new file mode 100644
index 0000000..0e3bc36
--- /dev/null
+++ b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/gui/SplashScreen.java
@@ -0,0 +1,122 @@
+/*
+ Violet - A program for editing UML diagrams.
+
+ Copyright (C) 2007 Cay S. Horstmann (http://horstmann.com)
+ Alexandre de Pellegrin (http://alexdp.free.fr);
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package com.horstmann.violet.application.gui;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.Toolkit;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+
+import javax.swing.ImageIcon;
+import javax.swing.JLabel;
+import javax.swing.JWindow;
+import javax.swing.SwingUtilities;
+
+import com.horstmann.violet.application.help.AboutDialog;
+import com.horstmann.violet.framework.injection.resources.ResourceBundleInjector;
+import com.horstmann.violet.framework.injection.resources.annotation.ResourceBundleBean;
+
+/**
+ * Violet's splash screen
+ *
+ * @author Alexandre de Pellegrin
+ *
+ */
+@ResourceBundleBean(resourceReference = AboutDialog.class)
+public class SplashScreen extends JWindow
+{
+
+ public SplashScreen()
+ {
+ super();
+ prepare();
+ }
+
+ public SplashScreen(MainFrame editorFrame)
+ {
+ super(editorFrame);
+ prepare();
+ }
+
+ private void prepare()
+ {
+ ResourceBundleInjector.getInjector().inject(this);
+ JLabel l = new JLabel(this.image);
+ getContentPane().add(l, BorderLayout.CENTER);
+ pack();
+
+ Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+ Dimension labelSize = l.getPreferredSize();
+
+ // Put image at the middle of the screen
+ setLocation(screenSize.width / 2 - (labelSize.width / 2), screenSize.height / 2 - (labelSize.height / 2));
+ }
+
+ public static void displayOverEditor(MainFrame editorFrame, int waitTime)
+ {
+ final SplashScreen splashScreen = new SplashScreen(editorFrame);
+
+ splashScreen.addMouseListener(new MouseAdapter()
+ {
+ public void mousePressed(MouseEvent e)
+ {
+ splashScreen.setVisible(false);
+ splashScreen.dispose();
+ }
+ });
+ final int pause = waitTime;
+ final Runnable closerRunner = new Runnable()
+ {
+ public void run()
+ {
+ splashScreen.setVisible(false);
+ splashScreen.dispose();
+ }
+ };
+ Runnable waitRunner = new Runnable()
+ {
+ public void run()
+ {
+ try
+ {
+ Thread.sleep(pause);
+ SwingUtilities.invokeAndWait(closerRunner);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ // can catch InvocationTargetException
+ // can catch InterruptedException
+ }
+ }
+ };
+
+ splashScreen.setVisible(true);
+ Thread splashThread = new Thread(waitRunner, "SplashThread");
+ splashThread.start();
+ }
+
+ @ResourceBundleBean(key="dialog.about.image")
+ private ImageIcon image;
+
+}
diff --git a/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/gui/WelcomePanel.html b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/gui/WelcomePanel.html
new file mode 100644
index 0000000..136f458
--- /dev/null
+++ b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/gui/WelcomePanel.html
@@ -0,0 +1,6 @@
+
+
+
+Welcome
+
+
\ No newline at end of file
diff --git a/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/gui/WelcomePanel.java b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/gui/WelcomePanel.java
new file mode 100644
index 0000000..9e3e5bc
--- /dev/null
+++ b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/gui/WelcomePanel.java
@@ -0,0 +1,325 @@
+/*
+ Violet - A program for editing UML diagrams.
+
+ Copyright (C) 2007 Cay S. Horstmann (http://horstmann.com)
+ Alexandre de Pellegrin (http://alexdp.free.fr);
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package com.horstmann.violet.application.gui;
+
+import java.awt.BasicStroke;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.GradientPaint;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.Paint;
+import java.awt.RenderingHints;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import javax.swing.BoxLayout;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.JPanel;
+import javax.swing.JTextPane;
+import javax.swing.border.EmptyBorder;
+import javax.swing.event.HyperlinkEvent;
+import javax.swing.event.HyperlinkListener;
+
+import org.apache.batik.dom.svg.SAXSVGDocumentFactory;
+import org.apache.batik.swing.JSVGCanvas;
+import org.apache.batik.util.XMLResourceDescriptor;
+import org.w3c.dom.svg.SVGDocument;
+
+import com.horstmann.violet.application.menu.FileMenu;
+import com.horstmann.violet.application.swingextension.WelcomeButtonUI;
+import com.horstmann.violet.framework.injection.bean.ManiocFramework.BeanInjector;
+import com.horstmann.violet.framework.injection.bean.ManiocFramework.InjectedBean;
+import com.horstmann.violet.framework.injection.resources.ResourceBundleInjector;
+import com.horstmann.violet.framework.injection.resources.annotation.ResourceBundleBean;
+import com.horstmann.violet.framework.theme.ITheme;
+import com.horstmann.violet.framework.theme.ThemeManager;
+
+public class WelcomePanel extends JPanel {
+
+ public WelcomePanel(FileMenu fileMenu) {
+ ResourceBundleInjector.getInjector().inject(this);
+ BeanInjector.getInjector().inject(this);
+ this.fileMenu = fileMenu;
+
+ setOpaque(false);
+ setLayout(new BorderLayout());
+
+ JPanel panel = new JPanel() {
+ @Override
+ protected void paintComponent(Graphics g) {
+ int x = 34;
+ int y = 34;
+ int w = getWidth() - 68;
+ int h = getHeight() - 68;
+ int arc = 30;
+
+ Graphics2D g2 = (Graphics2D) g.create();
+ g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+
+ g2.setColor(Color.WHITE);
+ g2.fillRoundRect(x, y, w, h, arc, arc);
+
+ g2.setStroke(new BasicStroke(3f));
+ g2.setColor(themeManager.getTheme().getWelcomeBackgroundEndColor());
+ g2.drawRoundRect(x, y, w, h, arc, arc);
+
+ g2.dispose();
+ }
+ };
+ panel.setOpaque(false);
+ panel.setLayout(new GridBagLayout());
+
+ JTextPane editorPane = new JTextPane();
+ editorPane.setEditable(false);
+ editorPane.setContentType("text/html");
+ try {
+ editorPane.setPage(this.getClass().getResource("WelcomePanel.html"));
+ } catch (IOException e1) {
+ // TODO Auto-generated catch block
+ e1.printStackTrace();
+ }
+
+ // JEditorPane editorPane = new JEditorPane("text/html",
+ // "Welcome");
+ editorPane.setOpaque(false);
+ editorPane.setBorder(new EmptyBorder(40, 40, 40, 40));
+ editorPane.addHyperlinkListener(new HyperlinkListener() {
+ @Override
+ public void hyperlinkUpdate(HyperlinkEvent e) {
+ if (HyperlinkEvent.EventType.ACTIVATED != e.getEventType()) {
+ return;
+ }
+ URL url = e.getURL();
+ System.out.println(e.getDescription());
+ System.out.println(leftPanelIcon);
+ }
+ });
+
+ GridBagConstraints c = new GridBagConstraints();
+ c.anchor = GridBagConstraints.CENTER;
+ c.weightx = 1;
+ c.weighty = 1;
+ c.gridx = 0;
+ c.gridy = 0;
+ c.insets = new Insets(40, 40, 40, 40);
+ c.fill = GridBagConstraints.BOTH;
+
+ panel.add(getWelcomeSVGImage(), c);
+
+ add(panel, BorderLayout.CENTER);
+ add(getFootTextPanel(), BorderLayout.SOUTH);
+
+ }
+
+ public void paint(Graphics g) {
+ Graphics2D g2 = (Graphics2D) g;
+ Paint currentPaint = g2.getPaint();
+ ITheme cLAF = this.themeManager.getTheme();
+ GradientPaint paint = new GradientPaint(getWidth() / 2, -getHeight() / 4, cLAF.getWelcomeBackgroundStartColor(), getWidth() / 2, getHeight() + getHeight() / 4,
+ cLAF.getWelcomeBackgroundEndColor());
+ g2.setPaint(paint);
+ g2.fillRect(0, 0, getWidth(), getHeight());
+ g2.setPaint(currentPaint);
+ super.paint(g);
+ }
+
+ private JPanel getLeftPanel() {
+ if (this.leftPanel == null) {
+ leftPanel = new JPanel();
+ leftPanel.setOpaque(false);
+ leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.Y_AXIS));
+ leftPanel.setBorder(new EmptyBorder(0, 0, 0, 45));
+
+ final JMenu newMenu = this.fileMenu.getFileNewMenu();
+ for (int i = 0; i < newMenu.getItemCount(); i++) {
+ final JMenuItem item = newMenu.getItem(i);
+ String label = item.getText();
+ JButton newDiagramShortcut = new JButton(label.toLowerCase());
+ newDiagramShortcut.setUI(new WelcomeButtonUI());
+ newDiagramShortcut.setAlignmentX(Component.RIGHT_ALIGNMENT);
+ newDiagramShortcut.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ item.doClick();
+ }
+ });
+ leftPanel.add(newDiagramShortcut);
+ }
+
+ }
+ return this.leftPanel;
+ }
+
+ private JPanel getRightPanel() {
+ if (this.rightPanel == null) {
+ this.rightPanel = new JPanel();
+ this.rightPanel.setOpaque(false);
+ this.rightPanel.setLayout(new BoxLayout(rightPanel, BoxLayout.Y_AXIS));
+ this.rightPanel.setBorder(new EmptyBorder(0, 45, 0, 45));
+
+ final JMenu recentMenu = this.fileMenu.getFileRecentMenu();
+ for (int i = 0; i < recentMenu.getItemCount(); i++) {
+ final JMenuItem item = recentMenu.getItem(i);
+ String label = item.getText();
+ JButton fileShortcut = new JButton(label.toLowerCase());
+ fileShortcut.setUI(new WelcomeButtonUI());
+ fileShortcut.setAlignmentX(Component.LEFT_ALIGNMENT);
+ fileShortcut.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ item.doClick();
+ }
+ });
+ rightPanel.add(fileShortcut);
+ }
+
+ }
+ return this.rightPanel;
+ }
+
+ private JPanel getLeftTitlePanel() {
+ if (this.leftTitlePanel == null) {
+ JLabel icon = new JLabel();
+ icon.setIcon(this.leftPanelIcon);
+
+ JLabel title = new JLabel(this.fileMenu.getFileNewMenu().getText().toLowerCase());
+ ITheme cLAF = ThemeManager.getInstance().getTheme();
+ title.setFont(cLAF.getWelcomeBigFont());
+ title.setForeground(cLAF.getWelcomeBigForegroundColor());
+ title.setBorder(new EmptyBorder(0, 30, 0, 0));
+
+ JPanel panel = new JPanel();
+ panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
+ panel.add(icon);
+ panel.add(title);
+ panel.setOpaque(false);
+
+ this.leftTitlePanel = new JPanel();
+ this.leftTitlePanel.setOpaque(false);
+ this.leftTitlePanel.setLayout(new BorderLayout());
+ this.leftTitlePanel.add(panel, BorderLayout.EAST);
+ this.leftTitlePanel.setBorder(new EmptyBorder(0, 0, 30, 45));
+ }
+ return this.leftTitlePanel;
+ }
+
+ private JPanel getRightTitlePanel() {
+ if (this.rightTitlePanel == null) {
+ JLabel icon = new JLabel();
+ icon.setIcon(this.rightPanelIcon);
+ icon.setAlignmentX(Component.LEFT_ALIGNMENT);
+
+ JLabel title = new JLabel(this.fileMenu.getFileRecentMenu().getText().toLowerCase());
+ ITheme cLAF = this.themeManager.getTheme();
+ title.setFont(cLAF.getWelcomeBigFont());
+ title.setForeground(cLAF.getWelcomeBigForegroundColor());
+ title.setBorder(new EmptyBorder(0, 0, 0, 30));
+
+ JPanel panel = new JPanel();
+ panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
+ panel.add(title);
+ panel.add(icon);
+ panel.setOpaque(false);
+
+ this.rightTitlePanel = new JPanel();
+ this.rightTitlePanel.setOpaque(false);
+ this.rightTitlePanel.setLayout(new BorderLayout());
+ this.rightTitlePanel.add(panel, BorderLayout.WEST);
+ this.rightTitlePanel.setBorder(new EmptyBorder(0, 45, 30, 0));
+ }
+ return this.rightTitlePanel;
+ }
+
+ private JPanel getFootTextPanel() {
+ if (this.footTextPanel == null) {
+ this.footTextPanel = new JPanel();
+ this.footTextPanel.setOpaque(false);
+ this.footTextPanel.setBorder(new EmptyBorder(0, 0, 10, 0));
+ this.footTextPanel.setLayout(new BoxLayout(this.footTextPanel, BoxLayout.Y_AXIS));
+ this.footTextPanel.setAlignmentX(Component.CENTER_ALIGNMENT);
+
+ JLabel text = new JLabel(this.footText);
+ ITheme cLAF = this.themeManager.getTheme();
+ text.setFont(cLAF.getWelcomeSmallFont());
+ text.setForeground(cLAF.getWelcomeBigForegroundColor());
+ text.setAlignmentX(Component.CENTER_ALIGNMENT);
+
+ this.footTextPanel.add(text);
+ }
+
+ return this.footTextPanel;
+ }
+
+ private JSVGCanvas getWelcomeSVGImage() {
+ if (this.welcomeSVGImage == null) {
+ this.welcomeSVGImage = new JSVGCanvas();
+ InputStream templateStream = this.getClass().getResourceAsStream("test.svg");
+ String parser = XMLResourceDescriptor.getXMLParserClassName();
+ SAXSVGDocumentFactory f = new SAXSVGDocumentFactory(parser);
+ SVGDocument doc = null;
+ try {
+ doc = f.createSVGDocument(null, templateStream);
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ this.welcomeSVGImage.setSVGDocument(doc);
+ }
+ return this.welcomeSVGImage;
+ }
+
+ private JSVGCanvas welcomeSVGImage;
+
+ private JPanel footTextPanel;;
+
+ private JPanel rightTitlePanel;
+
+ private JPanel leftTitlePanel;
+
+ private JPanel leftPanel;
+
+ private JPanel rightPanel;
+
+ private FileMenu fileMenu;
+
+ @ResourceBundleBean(key = "welcomepanel.new_diagram.icon")
+ private ImageIcon leftPanelIcon;
+
+ @ResourceBundleBean(key = "welcomepanel.recent_files.icon")
+ private ImageIcon rightPanelIcon;
+
+ @ResourceBundleBean(key = "welcomepanel.foot_text")
+ private String footText;
+
+ @InjectedBean
+ private ThemeManager themeManager;
+
+}
diff --git a/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/gui/WelcomePanel.properties b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/gui/WelcomePanel.properties
new file mode 100644
index 0000000..aefc4ad
--- /dev/null
+++ b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/gui/WelcomePanel.properties
@@ -0,0 +1,3 @@
+welcomepanel.foot_text=Violet UML Editor by Cay S. Horstmann and Alexandre de Pellegrin. Powered by Java, 2011.
+welcomepanel.new_diagram.icon=/icons/72x72/welcome_create.png
+welcomepanel.recent_files.icon=/icons/72x72/welcome_open.png
diff --git a/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/gui/WelcomePanel_fr.properties b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/gui/WelcomePanel_fr.properties
new file mode 100644
index 0000000..58943b9
--- /dev/null
+++ b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/gui/WelcomePanel_fr.properties
@@ -0,0 +1,3 @@
+welcomepanel.foot_text=Violet UML Editor par Cay S. Horstmann et Alexandre de Pellegrin. Powered by Java, 2011.
+welcomepanel.new_diagram.icon=/icons/72x72/welcome_create.png
+welcomepanel.recent_files.icon=/icons/72x72/welcome_open.png
diff --git a/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/help/AboutDialog.java b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/help/AboutDialog.java
new file mode 100644
index 0000000..c5fbbe7
--- /dev/null
+++ b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/help/AboutDialog.java
@@ -0,0 +1,391 @@
+/*
+ Violet - A program for editing UML diagrams.
+
+ Copyright (C) 2007 Cay S. Horstmann (http://horstmann.com)
+ Alexandre de Pellegrin (http://alexdp.free.fr);
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package com.horstmann.violet.application.help;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Point;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.net.URL;
+import java.security.AccessControlException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.JTextPane;
+import javax.swing.WindowConstants;
+import javax.swing.border.EmptyBorder;
+import javax.swing.table.AbstractTableModel;
+
+import com.horstmann.violet.application.swingextension.VerticalAutoScrollPane;
+import com.horstmann.violet.framework.injection.resources.ResourceBundleInjector;
+import com.horstmann.violet.framework.injection.resources.annotation.ResourceBundleBean;
+
+/**
+ * The About dialog box of ganttproject
+ */
+public class AboutDialog extends JDialog
+{
+
+ public AboutDialog(JFrame parent)
+ {
+ super(parent);
+ ResourceBundleInjector.getInjector().inject(this);
+ this.setTitle(this.dialogTitle);
+ this.setLocationRelativeTo(null);
+ this.setModal(true);
+ this.setResizable(false);
+ this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+ this.getContentPane().setLayout(new BorderLayout());
+
+ JPanel buttonPanel = getButtonPanel();
+ this.getContentPane().add(getVersionPanel(), BorderLayout.CENTER);
+ this.getContentPane().add(buttonPanel, BorderLayout.SOUTH);
+
+ this.pack();
+ setLocation(parent);
+
+ }
+
+ private JPanel getButtonPanel()
+ {
+ JPanel buttonPanel = new JPanel();
+ buttonPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
+ buttonPanel.setLayout(new GridBagLayout());
+ GridBagConstraints c = new GridBagConstraints();
+ c.anchor = GridBagConstraints.WEST;
+ c.weightx = 1;
+ c.gridx = 0;
+ c.gridy = 0;
+ buttonPanel.add(this.nextButton, c);
+ c = new GridBagConstraints();
+ c.anchor = GridBagConstraints.EAST;
+ c.weightx = 1;
+ c.gridx = 1;
+ c.gridy = 0;
+ JButton closeButton = new JButton(this.closeButtonLabel);
+ closeButton.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ dispose();
+ }
+ });
+ this.getRootPane().setDefaultButton(closeButton);
+ buttonPanel.add(closeButton, c);
+ return buttonPanel;
+ }
+
+ private void setLocation(JFrame parent)
+ {
+ Point point = parent.getLocationOnScreen();
+ int x = (int) point.getX() + parent.getWidth() / 2;
+ int y = (int) point.getY() + parent.getHeight() / 2;
+ setLocation(x - getWidth() / 2, y - getHeight() / 2);
+ }
+
+ private JPanel getSystemInfoPanel()
+ {
+ if (this.systemInfoPanel == null)
+ {
+ JTable table = new JTable();
+ AboutTableModel tableModel = new AboutTableModel(new String[]
+ {
+ tableSysInfoCol1,
+ tableSysInfoCol2
+ });
+ try
+ {
+ Enumeration> e = System.getProperties().propertyNames();
+ while (e.hasMoreElements())
+ {
+ String prop = (String) e.nextElement();
+ String value = System.getProperty(prop);
+ tableModel.addEntry(new String[]
+ {
+ prop,
+ value
+ });
+ }
+ }
+ catch (AccessControlException e)
+ {
+ // Well, we tried...
+ }
+ table.setModel(tableModel);
+ table.getColumnModel().getColumn(0).setPreferredWidth(170);
+ table.getColumnModel().getColumn(1).setPreferredWidth(380);
+ JScrollPane pane = new JScrollPane();
+ pane.getViewport().add(table);
+ this.systemInfoPanel = new JPanel(new BorderLayout());
+ this.systemInfoPanel.add(pane);
+ }
+ this.nextButton.setText(this.showVersionButtonLabel);
+ removeActionListener(this.nextButton);
+ this.nextButton.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ getContentPane().remove(getSystemInfoPanel());
+ getContentPane().add(getVersionPanel(), BorderLayout.CENTER);
+ getContentPane().repaint();
+ }
+ });
+ return this.systemInfoPanel;
+ }
+
+ private JPanel getAuthorsPanel()
+ {
+ if (this.authorsPanel == null)
+ {
+ JLabel image = new JLabel(this.violetBanner);
+ JTextPane tp = new JTextPane();
+ try
+ {
+ URL url = getClass().getResource(this.authorsFilePath);
+ tp.setPage(url);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ tp.setBorder(new EmptyBorder(0,0,0,0));
+ authorsScrollPane = new VerticalAutoScrollPane();
+ authorsScrollPane.setBackground(new Color(255, 255, 255));
+ authorsScrollPane.setForeground(new Color(0, 0, 0));
+ authorsScrollPane.setOpaque(true);
+ authorsScrollPane.setBorder(new EmptyBorder(20, 20, 20, 20));
+ authorsScrollPane.getViewport().add(tp);
+ this.authorsPanel = new JPanel(new BorderLayout());
+ this.authorsPanel.add(image, BorderLayout.NORTH);
+ this.authorsPanel.add(authorsScrollPane, BorderLayout.CENTER);
+ }
+ this.nextButton.setText(this.showLicenceButtonLabel);
+ removeActionListener(this.nextButton);
+ this.nextButton.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ getContentPane().remove(getAuthorsPanel());
+ authorsScrollPane.reset();
+ getContentPane().add(getLicensePanel(), BorderLayout.CENTER);
+ getContentPane().repaint();
+ }
+ });
+ this.authorsScrollPane.animate();
+ return this.authorsPanel;
+ }
+
+ private JPanel getLicensePanel()
+ {
+ if (this.licensePanel == null)
+ {
+ JTextPane tp = new JTextPane();
+ JScrollPane js = new JScrollPane();
+ js.getViewport().add(tp);
+
+ try
+ {
+ URL url = getClass().getResource(this.licenceFilePath);
+ tp.setPage(url);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+
+ this.licensePanel = new JPanel(new BorderLayout());
+ this.licensePanel.add(js);
+
+ }
+ this.nextButton.setText(this.showSystemInfoButtonLabel);
+ removeActionListener(this.nextButton);
+ this.nextButton.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ getContentPane().remove(getLicensePanel());
+ getContentPane().add(getSystemInfoPanel(), BorderLayout.CENTER);
+ getContentPane().repaint();
+ }
+ });
+ return this.licensePanel;
+ }
+
+ private JPanel getVersionPanel()
+ {
+ if (this.versionPanel == null)
+ {
+ JLabel image = new JLabel(this.image);
+ JLabel text = new JLabel(this.versionText);
+ text.setBorder(new EmptyBorder(0, 0, 0, 4));
+ this.versionPanel = new JPanel();
+ this.versionPanel.setLayout(new GridBagLayout());
+ GridBagConstraints c = new GridBagConstraints();
+ c.anchor = GridBagConstraints.CENTER;
+ c.weightx = 1;
+ c.gridx = 0;
+ c.gridy = 0;
+ this.versionPanel.add(image, c);
+ c = new GridBagConstraints();
+ c.anchor = GridBagConstraints.EAST;
+ c.weightx = 1;
+ c.gridx = 0;
+ c.gridy = 1;
+ this.versionPanel.add(text, c);
+ }
+ this.nextButton.setText(this.showAuthorsButtonLabel);
+ removeActionListener(this.nextButton);
+ this.nextButton.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ getContentPane().remove(getVersionPanel());
+ getContentPane().add(getAuthorsPanel(), BorderLayout.CENTER);
+ getContentPane().repaint();
+ }
+ });
+ return this.versionPanel;
+ }
+
+ private void removeActionListener(JButton button)
+ {
+ ActionListener[] listeners = button.getActionListeners();
+ for (int i = 0; i < listeners.length; i++)
+ {
+ button.removeActionListener(listeners[i]);
+ }
+ }
+
+ private class AboutTableModel extends AbstractTableModel
+ {
+
+ public AboutTableModel(String[] columnNames)
+ {
+ this.columnNames = columnNames;
+ }
+
+ public void addEntry(String[] entry)
+ {
+ data.add(entry);
+ fireTableRowsInserted(data.size() - 1, data.size() - 1);
+ }
+
+ public int getColumnCount()
+ {
+ return columnNames.length;
+ }
+
+ public int getRowCount()
+ {
+ return data.size();
+ }
+
+ public String getColumnName(int col)
+ {
+ return columnNames[col];
+ }
+
+ public Class> getColumnClass(int c)
+ {
+ return String.class;
+ }
+
+ public Object getValueAt(int row, int col)
+ {
+ String[] entry = (String[]) data.get(row);
+ return entry[col];
+ }
+
+ public boolean isCellEditable(int row, int col)
+ {
+ return false;
+ }
+
+ private String[] columnNames;
+ private List data = new ArrayList();
+ }
+
+ private JPanel versionPanel;
+
+ private JPanel authorsPanel;
+
+ private JPanel licensePanel;
+
+ private JPanel systemInfoPanel;
+
+ private VerticalAutoScrollPane authorsScrollPane;
+
+ private JButton nextButton = new JButton();
+
+ @ResourceBundleBean(key="dialog.title")
+ private String dialogTitle;
+
+ @ResourceBundleBean(key="dialog.button.label")
+ private String closeButtonLabel;
+
+ @ResourceBundleBean(key="systeminfo.col1")
+ private String tableSysInfoCol1;
+
+ @ResourceBundleBean(key="systeminfo.col2")
+ private String tableSysInfoCol2;
+
+ @ResourceBundleBean(key="dialog.button.show_version")
+ private String showVersionButtonLabel;
+
+ @ResourceBundleBean(key="authors.banner")
+ private ImageIcon violetBanner;
+
+ @ResourceBundleBean(key="authors.file")
+ private String authorsFilePath;
+
+ @ResourceBundleBean(key="dialog.button.show_license")
+ private String showLicenceButtonLabel;
+
+ @ResourceBundleBean(key="license.file")
+ private String licenceFilePath;
+
+ @ResourceBundleBean(key="dialog.button.show_systeminfo")
+ private String showSystemInfoButtonLabel;
+
+ @ResourceBundleBean(key="dialog.about.image")
+ private ImageIcon image;
+
+ @ResourceBundleBean(key="app.version.text")
+ private String versionText;
+
+ @ResourceBundleBean(key="dialog.button.show_authors")
+ private String showAuthorsButtonLabel;
+
+
+}
diff --git a/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/help/AboutDialog.properties b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/help/AboutDialog.properties
new file mode 100644
index 0000000..cfbfc6b
--- /dev/null
+++ b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/help/AboutDialog.properties
@@ -0,0 +1,15 @@
+app.name=Violet UML Editor
+app.icon=/icons/16x16/violet.png
+app.version.text=Version 2.0.0-alpha (2011-09-23)
+dialog.title=About Violet UML Editor
+dialog.about.image=about-violet.png
+dialog.button.label=Close
+dialog.button.show_authors=Authors and Credits >
+dialog.button.show_license=License >
+dialog.button.show_systeminfo=System Informations >
+dialog.button.show_version=Version >
+systeminfo.col1=Property
+systeminfo.col2=Value
+authors.banner=about-violet-banner.png
+authors.file=credits.txt
+license.file=license.txt
diff --git a/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/help/AboutDialog_fr.properties b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/help/AboutDialog_fr.properties
new file mode 100644
index 0000000..ef932e5
--- /dev/null
+++ b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/help/AboutDialog_fr.properties
@@ -0,0 +1,14 @@
+app.name=Violet UML Editor
+app.icon=/icons/16x16/violet.png
+dialog.title=A propos de Violet UML Editor
+dialog.about.image=about-violet.png
+dialog.button.label=Fermer
+dialog.button.show_authors=Auteurs et Remerciements >
+dialog.button.show_license=Licence >
+dialog.button.show_systeminfo=Informations syst\u00E8me >
+dialog.button.show_version=Version >
+systeminfo.col1=Propri\u00E9t\u00E9
+systeminfo.col2=Valeur
+authors.banner=about-violet-banner.png
+authors.file=credits.txt
+license.file=license.txt
diff --git a/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/help/HelpManager.java b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/help/HelpManager.java
new file mode 100644
index 0000000..df9839d
--- /dev/null
+++ b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/help/HelpManager.java
@@ -0,0 +1,93 @@
+package com.horstmann.violet.application.help;
+
+import java.awt.Toolkit;
+import java.text.MessageFormat;
+
+import javax.swing.ImageIcon;
+import javax.swing.JOptionPane;
+
+import com.horstmann.violet.framework.dialog.DialogFactory;
+import com.horstmann.violet.framework.injection.resources.annotation.ResourceBundleBean;
+import com.horstmann.violet.framework.util.BrowserLauncher;
+import com.horstmann.violet.framework.util.ClipboardPipe;
+
+public class HelpManager
+{
+ private static HelpManager instance;
+
+ private HelpManager() {
+
+ }
+
+ public static HelpManager getInstance() {
+ if (instance == null) {
+ instance = new HelpManager();
+ }
+ return instance;
+ }
+
+
+
+
+
+ /**
+ * Opens online help
+ */
+ public void openUserGuide()
+ {
+ boolean isOK = BrowserLauncher.openURL(this.userGuideURL);
+ if (!isOK)
+ {
+ openBrowser(this.userGuideURL);
+ }
+
+ }
+
+ /**
+ * Goes to homepage
+ */
+ public void openHomepage()
+ {
+ boolean isOK = BrowserLauncher.openURL(this.homePageURL);
+ if (!isOK)
+ {
+ openBrowser(this.homePageURL);
+ }
+
+ }
+
+ /**
+ * Launch web browser or copy url to clipoard if failed
+ *
+ * @param url
+ */
+ private void openBrowser(String url)
+ {
+ String message = MessageFormat.format(this.errorMessageTemplate, new Object[]
+ {
+ url
+ });
+ JOptionPane optionPane = new JOptionPane();
+ optionPane.setMessage(message);
+ optionPane.setIcon(this.errorImageIcon);
+ ClipboardPipe pipe = new ClipboardPipe(url);
+ Toolkit.getDefaultToolkit().getSystemClipboard().setContents(pipe, null);
+ DialogFactory.getInstance().showDialog(optionPane, this.errorDialogBoxTitle, true);
+ }
+
+ @ResourceBundleBean(key = "help.userguide.url")
+ private String userGuideURL;
+
+ @ResourceBundleBean(key = "help.homepage.url")
+ private String homePageURL;
+
+ @ResourceBundleBean(key = "dialog.open_url_failed.ok")
+ private String errorMessageTemplate;
+
+ @ResourceBundleBean(key = "dialog.open_url_failed.title")
+ private String errorDialogBoxTitle;
+
+ @ResourceBundleBean(key = "dialog.open_url_failed.icon")
+ private ImageIcon errorImageIcon;
+
+}
diff --git a/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/help/HelpManager.properties b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/help/HelpManager.properties
new file mode 100644
index 0000000..1e2347b
--- /dev/null
+++ b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/help/HelpManager.properties
@@ -0,0 +1,5 @@
+dialog.open_url_failed.title=Web browser opening error
+dialog.open_url_failed.icon=/icons/64x64/error.png
+dialog.open_url_failed.ok=Failed to open {0}\nYou should try to open it directly with your web browser.\n(Url has been copied to clipboard. Just paste it!)
+help.userguide.url=http://violet.sourceforge.net/help.php?lang=en
+help.homepage.url=http://violet.sourceforge.net/index.php?lang=en
\ No newline at end of file
diff --git a/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/help/HelpManager_fr.properties b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/help/HelpManager_fr.properties
new file mode 100644
index 0000000..65fe491
--- /dev/null
+++ b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/help/HelpManager_fr.properties
@@ -0,0 +1,5 @@
+dialog.open_url_failed.title=Erreur d'ouverture du navigateur internet
+dialog.open_url_failed.icon=/icons/64x64/error.png
+dialog.open_url_failed.ok=Impossible d'ouvrir {0}\nVous pouvez l'ouvrir directement via votre navigateur internet.\n(L'url a \u00e9t\u00e9 copi\u00e9e dans votre presse papier. Collez-la simplement!)
+help.userguide.url=http://violet.sourceforge.net/help.php?lang=fr
+help.homepage.url=http://violet.sourceforge.net/index.php?lang=fr
\ No newline at end of file
diff --git a/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/help/credits.txt b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/help/credits.txt
new file mode 100644
index 0000000..72822df
--- /dev/null
+++ b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/help/credits.txt
@@ -0,0 +1,126 @@
+
+
+
+
+
+By Cay S. Horstmann (http://www.horstmann.com)
+and Alexandre de Pellegrin (http://alexdp.free.fr)
+
+
+
+
+
+
+
+
+
+
+
+
+
+This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions.
+
+
+
+
+
+
+
+
+
+
+
+
+Thanks to :
+Avi Bercovich
+Andrew Brandt
+Lars Arne Brekken
+Chandler Burgess
+Jørgen Cederberg
+Robert Colburn
+Piyush Devnani
+Jeremy Driver
+Jay Dunning
+Morten Elling
+Cris Fuhrman
+Igor Garcia
+Mark George
+Mike Godfrey
+Daniel Guerrero
+Stefan Gründel
+Wee Jin Goh
+Laurent Hayoun
+Graham King
+Peter Kehl
+Sebastian Kurt
+Raymund J. Lin
+Kevin McConnell
+Matijs Moest
+Tri Nguyen
+Evelyn Obaid
+Norbert Oertel
+Johannes Päivinen
+Bill Pine
+Bruce Raggett
+Zack Rubinstein
+Grant Talarico
+Jordan Thompson
+Simon Tokumine
+Jesper Trägårdh
+Trygve Utstumo
+Glenn Vanmarcke
+Sam Watkins
+Martin Wehner
+Raphael Wimmer
+Ed Zaron
+Marc Godin
+Karine Lignon
+Victor Freches
+Alexandre Debril
+[Your name must be here] <- contribute!
+
+
+
+
+
+
+
+
+
+
+
+
+Special thanks from Alexandre de Pellegrin : to my wife for her patience and her encouragements.
+
+
+
+
+
+
+
+
+
+
+
+
+
+If you like this software, don't hesitate to talk about it around you. Any suggestions? Send feedback and contribute!
+
+
+
+
+
+
+
+
+
+
+
+
+
+By Cay S. Horstmann (http://www.horstmann.com)
+and Alexandre de Pellegrin (http://alexdp.free.fr)
+
+
+
+
diff --git a/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/help/license.txt b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/help/license.txt
new file mode 100644
index 0000000..5b6e7c6
--- /dev/null
+++ b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/help/license.txt
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ , 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/menu/EditMenu.java b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/menu/EditMenu.java
new file mode 100644
index 0000000..6aa8fa0
--- /dev/null
+++ b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/menu/EditMenu.java
@@ -0,0 +1,283 @@
+/*
+ Violet - A program for editing UML diagrams.
+
+ Copyright (C) 2007 Cay S. Horstmann (http://horstmann.com)
+ Alexandre de Pellegrin (http://alexdp.free.fr);
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package com.horstmann.violet.application.menu;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.List;
+
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+
+import com.horstmann.violet.application.gui.MainFrame;
+import com.horstmann.violet.framework.injection.resources.ResourceBundleInjector;
+import com.horstmann.violet.framework.injection.resources.annotation.ResourceBundleBean;
+import com.horstmann.violet.workspace.editorpart.IEditorPart;
+import com.horstmann.violet.workspace.editorpart.IEditorPartBehaviorManager;
+import com.horstmann.violet.workspace.editorpart.behavior.CutCopyPasteBehavior;
+import com.horstmann.violet.workspace.editorpart.behavior.EditSelectedBehavior;
+import com.horstmann.violet.workspace.editorpart.behavior.SelectAllBehavior;
+import com.horstmann.violet.workspace.editorpart.behavior.SelectByDistanceBehavior;
+import com.horstmann.violet.workspace.editorpart.behavior.UndoRedoCompoundBehavior;
+
+/**
+ * Edit menu
+ *
+ * @author Alexandre de Pellegrin
+ *
+ */
+@ResourceBundleBean(resourceReference = MenuFactory.class)
+public class EditMenu extends JMenu
+{
+
+ /**
+ * Default constructor
+ *
+ * @param mainFrame where is attached this menu
+ * @param factory for accessing to external resources
+ */
+ @ResourceBundleBean(key = "edit")
+ public EditMenu(final MainFrame mainFrame)
+ {
+ ResourceBundleInjector.getInjector().inject(this);
+ this.mainFrame = mainFrame;
+ this.createMenu();
+ }
+
+ /**
+ * Initializes menu
+ */
+ private void createMenu()
+ {
+ undo.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent event)
+ {
+ if (isThereAnyWorkspaceDisplayed()) {
+ IEditorPart activeEditorPart = getActiveEditorPart();
+ IEditorPartBehaviorManager behaviorManager = activeEditorPart.getBehaviorManager();
+ List found = behaviorManager.getBehaviors(UndoRedoCompoundBehavior.class);
+ if (found.size() != 1) {
+ return;
+ }
+ found.get(0).undo();
+ }
+ }
+ });
+ this.add(undo);
+
+ redo.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent event)
+ {
+ if (isThereAnyWorkspaceDisplayed()) {
+ IEditorPart activeEditorPart = getActiveEditorPart();
+ IEditorPartBehaviorManager behaviorManager = activeEditorPart.getBehaviorManager();
+ List found = behaviorManager.getBehaviors(UndoRedoCompoundBehavior.class);
+ if (found.size() != 1) {
+ return;
+ }
+ found.get(0).redo();
+ }
+ }
+ });
+ this.add(redo);
+
+ properties.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent event)
+ {
+ if (isThereAnyWorkspaceDisplayed()) {
+ IEditorPart activeEditorPart = getActiveEditorPart();
+ IEditorPartBehaviorManager behaviorManager = activeEditorPart.getBehaviorManager();
+ List found = behaviorManager.getBehaviors(EditSelectedBehavior.class);
+ if (found.size() != 1) {
+ return;
+ }
+ found.get(0).editSelected();
+ }
+ }
+ });
+ this.add(properties);
+
+ cut.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent event)
+ {
+ if (isThereAnyWorkspaceDisplayed()) {
+ IEditorPart activeEditorPart = getActiveEditorPart();
+ IEditorPartBehaviorManager behaviorManager = activeEditorPart.getBehaviorManager();
+ List found = behaviorManager.getBehaviors(CutCopyPasteBehavior.class);
+ if (found.size() != 1) {
+ return;
+ }
+ found.get(0).cut();
+ }
+ }
+ });
+ this.add(cut);
+
+ copy.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent event)
+ {
+ if (isThereAnyWorkspaceDisplayed()) {
+ IEditorPart activeEditorPart = getActiveEditorPart();
+ IEditorPartBehaviorManager behaviorManager = activeEditorPart.getBehaviorManager();
+ List found = behaviorManager.getBehaviors(CutCopyPasteBehavior.class);
+ if (found.size() != 1) {
+ return;
+ }
+ found.get(0).copy();
+ }
+ }
+ });
+ this.add(copy);
+
+ paste.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent event)
+ {
+ if (isThereAnyWorkspaceDisplayed()) {
+ IEditorPart activeEditorPart = getActiveEditorPart();
+ IEditorPartBehaviorManager behaviorManager = activeEditorPart.getBehaviorManager();
+ List found = behaviorManager.getBehaviors(CutCopyPasteBehavior.class);
+ if (found.size() != 1) {
+ return;
+ }
+ found.get(0).paste();
+ }
+ }
+ });
+ this.add(paste);
+
+ delete.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent event)
+ {
+ if (isThereAnyWorkspaceDisplayed()) getActiveEditorPart().removeSelected();
+ }
+ });
+ this.add(delete);
+
+ selectAll.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent event)
+ {
+ if (isThereAnyWorkspaceDisplayed()) {
+ IEditorPart activeEditorPart = getActiveEditorPart();
+ IEditorPartBehaviorManager behaviorManager = activeEditorPart.getBehaviorManager();
+ List found = behaviorManager.getBehaviors(SelectAllBehavior.class);
+ if (found.size() != 1) {
+ return;
+ }
+ found.get(0).selectAllGraphElements();
+ }
+ }
+ });
+ this.add(selectAll);
+
+ selectNext.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent event)
+ {
+ if (isThereAnyWorkspaceDisplayed()) {
+ IEditorPart activeEditorPart = getActiveEditorPart();
+ IEditorPartBehaviorManager behaviorManager = activeEditorPart.getBehaviorManager();
+ List found = behaviorManager.getBehaviors(SelectByDistanceBehavior.class);
+ if (found.size() != 1) {
+ return;
+ }
+ found.get(0).selectAnotherGraphElement(1);
+ }
+ }
+ });
+ this.add(selectNext);
+
+ selectPrevious.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent event)
+ {
+ if (isThereAnyWorkspaceDisplayed()) {
+ IEditorPart activeEditorPart = getActiveEditorPart();
+ IEditorPartBehaviorManager behaviorManager = activeEditorPart.getBehaviorManager();
+ List found = behaviorManager.getBehaviors(SelectByDistanceBehavior.class);
+ if (found.size() != 1) {
+ return;
+ }
+ found.get(0).selectAnotherGraphElement(-1);
+ }
+ }
+ });
+ this.add(selectPrevious);
+
+ }
+
+ /**
+ * @return current editor
+ */
+ private IEditorPart getActiveEditorPart()
+ {
+ return this.mainFrame.getActiveWorkspace().getEditorPart();
+ }
+
+ /**
+ * @return true id at least one workspace is reachable
+ */
+ private boolean isThereAnyWorkspaceDisplayed()
+ {
+ return mainFrame.getWorkspaceList().size() > 0;
+ }
+
+ /** Application frame */
+ private MainFrame mainFrame;
+
+ @ResourceBundleBean(key = "edit.undo")
+ private JMenuItem undo;
+
+ @ResourceBundleBean(key = "edit.redo")
+ private JMenuItem redo;
+
+ @ResourceBundleBean(key = "edit.properties")
+ private JMenuItem properties;
+
+ @ResourceBundleBean(key = "edit.cut")
+ private JMenuItem cut;
+
+ @ResourceBundleBean(key = "edit.copy")
+ private JMenuItem copy;
+
+ @ResourceBundleBean(key = "edit.paste")
+ private JMenuItem paste;
+
+ @ResourceBundleBean(key = "edit.delete")
+ private JMenuItem delete;
+
+ @ResourceBundleBean(key = "edit.select_all")
+ private JMenuItem selectAll;
+
+ @ResourceBundleBean(key = "edit.select_next")
+ private JMenuItem selectNext;
+
+ @ResourceBundleBean(key = "edit.select_previous")
+ private JMenuItem selectPrevious;
+}
diff --git a/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/menu/FileMenu.java b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/menu/FileMenu.java
new file mode 100644
index 0000000..03905df
--- /dev/null
+++ b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/menu/FileMenu.java
@@ -0,0 +1,566 @@
+/*
+ Violet - A program for editing UML diagrams.
+
+ Copyright (C) 2007 Cay S. Horstmann (http://horstmann.com)
+ Alexandre de Pellegrin (http://alexdp.free.fr);
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package com.horstmann.violet.application.menu;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.List;
+
+import javax.swing.ImageIcon;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+
+import com.horstmann.violet.application.ApplicationStopper;
+import com.horstmann.violet.application.gui.MainFrame;
+import com.horstmann.violet.framework.dialog.DialogFactory;
+import com.horstmann.violet.framework.file.GraphFile;
+import com.horstmann.violet.framework.file.IFile;
+import com.horstmann.violet.framework.file.IGraphFile;
+import com.horstmann.violet.framework.file.chooser.IFileChooserService;
+import com.horstmann.violet.framework.file.naming.ExtensionFilter;
+import com.horstmann.violet.framework.file.naming.FileNamingService;
+import com.horstmann.violet.framework.file.persistence.IFileReader;
+import com.horstmann.violet.framework.file.persistence.IFileWriter;
+import com.horstmann.violet.framework.injection.bean.ManiocFramework.BeanInjector;
+import com.horstmann.violet.framework.injection.bean.ManiocFramework.InjectedBean;
+import com.horstmann.violet.framework.injection.resources.ResourceBundleInjector;
+import com.horstmann.violet.framework.injection.resources.annotation.ResourceBundleBean;
+import com.horstmann.violet.framework.plugin.IDiagramPlugin;
+import com.horstmann.violet.framework.plugin.PluginRegistry;
+import com.horstmann.violet.framework.userpreferences.UserPreferencesService;
+import com.horstmann.violet.product.diagram.abstracts.IGraph;
+import com.horstmann.violet.workspace.IWorkspace;
+import com.horstmann.violet.workspace.Workspace;
+
+/**
+ * Represents the file menu on the editor frame
+ *
+ * @author Alexandre de Pellegrin
+ *
+ */
+@ResourceBundleBean(resourceReference = MenuFactory.class)
+public class FileMenu extends JMenu
+{
+
+ /**
+ * Default constructor
+ *
+ * @param mainFrame
+ */
+ @ResourceBundleBean(key = "file")
+ public FileMenu(MainFrame mainFrame)
+ {
+ ResourceBundleInjector.getInjector().inject(this);
+ BeanInjector.getInjector().inject(this);
+ this.mainFrame = mainFrame;
+ createMenu();
+ addWindowsClosingListener();
+ }
+
+ /**
+ * @return 'new file' menu
+ */
+ public JMenu getFileNewMenu()
+ {
+ return this.fileNewMenu;
+ }
+
+ /**
+ * @return recently opened file menu
+ */
+ public JMenu getFileRecentMenu()
+ {
+ return this.fileRecentMenu;
+ }
+
+ /**
+ * Initialize the menu
+ */
+ private void createMenu()
+ {
+ initFileNewMenu();
+ initFileOpenItem();
+ initFileCloseItem();
+ initFileRecentMenu();
+ initFileSaveItem();
+ initFileSaveAsItem();
+ initFileExportMenu();
+ initFilePrintItem();
+ initFileExitItem();
+
+ this.add(this.fileNewMenu);
+ this.add(this.fileOpenItem);
+ this.add(this.fileCloseItem);
+ this.add(this.fileRecentMenu);
+ this.add(this.fileSaveItem);
+ this.add(this.fileSaveAsItem);
+ this.add(this.fileExportMenu);
+ this.add(this.filePrintItem);
+ this.add(this.fileExitItem);
+
+ }
+
+ /**
+ * Add frame listener to detect closing request
+ */
+ private void addWindowsClosingListener()
+ {
+ this.mainFrame.addWindowListener(new WindowAdapter()
+ {
+ public void windowClosing(WindowEvent event)
+ {
+ stopper.exitProgram(mainFrame);
+ }
+ });
+ }
+
+ /**
+ * Init exit menu entry
+ */
+ private void initFileExitItem()
+ {
+ this.fileExitItem.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ stopper.exitProgram(mainFrame);
+ }
+ });
+ if (this.fileChooserService == null) this.fileExitItem.setEnabled(false);
+ }
+
+ /**
+ * Init export submenu
+ */
+ private void initFileExportMenu()
+ {
+ initFileExportToImageItem();
+ initFileExportToClipboardItem();
+ initFileExportToJavaItem();
+ initFileExportToPythonItem();
+
+ this.fileExportMenu.add(this.fileExportToImageItem);
+ this.fileExportMenu.add(this.fileExportToClipBoardItem);
+ // this.fileExportMenu.add(this.fileExportToJavaItem);
+ // this.fileExportMenu.add(this.fileExportToPythonItem);
+
+ if (this.fileChooserService == null) this.fileExportMenu.setEnabled(false);
+ }
+
+ /**
+ * Init export to python menu entry
+ */
+ private void initFileExportToPythonItem()
+ {
+ this.fileExportToPythonItem.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ IWorkspace workspace = (Workspace) mainFrame.getActiveWorkspace();
+ if (workspace != null)
+ {
+ }
+ }
+ });
+ }
+
+ /**
+ * Init export to java menu entry
+ */
+ private void initFileExportToJavaItem()
+ {
+ this.fileExportToJavaItem.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ IWorkspace workspace = (Workspace) mainFrame.getActiveWorkspace();
+ if (workspace != null)
+ {
+ }
+ }
+ });
+ }
+
+ /**
+ * Init export to clipboard menu entry
+ */
+ private void initFileExportToClipboardItem()
+ {
+ this.fileExportToClipBoardItem.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ IWorkspace workspace = (Workspace) mainFrame.getActiveWorkspace();
+ if (workspace != null)
+ {
+ workspace.getGraphFile().exportToClipboard();
+ }
+ }
+ });
+ }
+
+ /**
+ * Init export to image menu entry
+ */
+ private void initFileExportToImageItem()
+ {
+ this.fileExportToImageItem.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ IWorkspace workspace = (Workspace) mainFrame.getActiveWorkspace();
+ if (workspace != null)
+ {
+ try
+ {
+ ExtensionFilter exportFilter = fileNamingService.getImageExtensionFilter();
+ IFileWriter fileSaver = fileChooserService.chooseAndGetFileWriter(exportFilter);
+ OutputStream out = fileSaver.getOutputStream();
+ if (out != null)
+ {
+ String filename = fileSaver.getFileDefinition().getFilename();
+ String extension = exportFilter.getExtension();
+ if (filename.toLowerCase().endsWith(extension.toLowerCase())) {
+ String format = extension.replace(".", "");
+ workspace.getGraphFile().exportImage(out, format);
+ }
+ }
+ }
+ catch (Exception e1)
+ {
+ throw new RuntimeException(e1);
+ }
+ }
+ }
+ });
+ }
+
+ /**
+ * Init 'save as' menu entry
+ */
+ private void initFileSaveAsItem()
+ {
+ this.fileSaveAsItem.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ IWorkspace workspace = (Workspace) mainFrame.getActiveWorkspace();
+ if (workspace != null)
+ {
+ IGraphFile graphFile = workspace.getGraphFile();
+ graphFile.saveToNewLocation();
+ }
+ }
+ });
+ if (this.fileChooserService == null) this.fileSaveAsItem.setEnabled(false);
+ }
+
+ /**
+ * Init save menu entry
+ */
+ private void initFileSaveItem()
+ {
+ this.fileSaveItem.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ IWorkspace workspace = mainFrame.getActiveWorkspace();
+ if (workspace != null)
+ {
+ workspace.getGraphFile().save();
+ }
+ }
+ });
+ if (this.fileChooserService == null || (this.fileChooserService != null && this.fileChooserService.isWebStart()))
+ {
+ this.fileSaveItem.setEnabled(false);
+ }
+ }
+
+ /**
+ * Init print menu entry
+ */
+ private void initFilePrintItem()
+ {
+ this.filePrintItem.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ IWorkspace workspace = (Workspace) mainFrame.getActiveWorkspace();
+ if (workspace != null)
+ {
+ workspace.getGraphFile().exportToPrinter();
+ }
+ }
+ });
+ if (this.fileChooserService == null) this.filePrintItem.setEnabled(false);
+ }
+
+ /**
+ * Init close menu entry
+ */
+ private void initFileCloseItem()
+ {
+ this.fileCloseItem.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent event)
+ {
+ IWorkspace workspace = (Workspace) mainFrame.getActiveWorkspace();
+ if (workspace != null)
+ {
+ IGraphFile graphFile = workspace.getGraphFile();
+ if (graphFile.isSaveRequired())
+ {
+ JOptionPane optionPane = new JOptionPane();
+ optionPane.setMessage(dialogCloseMessage);
+ optionPane.setOptionType(JOptionPane.YES_NO_CANCEL_OPTION);
+ optionPane.setIcon(dialogCloseIcon);
+ dialogFactory.showDialog(optionPane, dialogCloseTitle, true);
+
+ int result = JOptionPane.CANCEL_OPTION;
+ if (!JOptionPane.UNINITIALIZED_VALUE.equals(optionPane.getValue()))
+ {
+ result = ((Integer) optionPane.getValue()).intValue();
+ }
+
+ if (result == JOptionPane.YES_OPTION)
+ {
+ String filename = graphFile.getFilename();
+ if (filename == null) {
+ graphFile.saveToNewLocation();
+ }
+ if (filename != null) {
+ graphFile.save();
+ }
+ if (!graphFile.isSaveRequired()) {
+ mainFrame.removeDiagramPanel(workspace);
+ userPreferencesService.removeOpenedFile(graphFile);
+ }
+ }
+ if (result == JOptionPane.NO_OPTION)
+ {
+ mainFrame.removeDiagramPanel(workspace);
+ userPreferencesService.removeOpenedFile(graphFile);
+ }
+ }
+ if (!graphFile.isSaveRequired())
+ {
+ mainFrame.removeDiagramPanel(workspace);
+ userPreferencesService.removeOpenedFile(graphFile);
+ }
+ }
+ }
+ });
+ }
+
+ /**
+ * Init open menu entry
+ */
+ private void initFileOpenItem()
+ {
+ this.fileOpenItem.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent event)
+ {
+ try
+ {
+ IFileReader fileOpener = fileChooserService.chooseAndGetFileReader();
+ if (fileOpener == null) {
+ // Action cancelled by user
+ return;
+ }
+ IFile selectedFile = fileOpener.getFileDefinition();
+ IGraphFile graphFile = new GraphFile(selectedFile);
+ IWorkspace workspace = new Workspace(graphFile);
+ mainFrame.addTabbedPane(workspace);
+ userPreferencesService.addOpenedFile(graphFile);
+ userPreferencesService.addRecentFile(graphFile);
+ }
+ catch (IOException e)
+ {
+ dialogFactory.showWarningDialog(e.getMessage());
+ }
+ }
+ });
+ if (this.fileChooserService == null) this.fileOpenItem.setEnabled(false);
+ }
+
+ /**
+ * Init new menu entry
+ */
+ public void initFileNewMenu()
+ {
+ List diagramPlugins = this.pluginRegistry.getDiagramPlugins();
+ for (final IDiagramPlugin aDiagramPlugin : diagramPlugins)
+ {
+ JMenuItem item = new JMenuItem(aDiagramPlugin.getName());
+ item.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent event)
+ {
+ Class extends IGraph> graphClass = aDiagramPlugin.getGraphClass();
+ IGraphFile graphFile = new GraphFile(graphClass);
+ IWorkspace diagramPanel = new Workspace(graphFile);
+ mainFrame.addTabbedPane(diagramPanel);
+ }
+ });
+ fileNewMenu.add(item);
+ }
+ }
+
+ /**
+ * Init recent menu entry
+ */
+ public void initFileRecentMenu()
+ {
+ // Set entries on startup
+ refreshFileRecentMenu();
+ // Refresh recent files list each time the global file menu gets the focus
+ this.addFocusListener(new FocusListener()
+ {
+
+ public void focusGained(FocusEvent e)
+ {
+ refreshFileRecentMenu();
+ }
+
+ public void focusLost(FocusEvent e)
+ {
+ // Nothing to do
+ }
+
+ });
+ if (this.fileChooserService == null || (this.fileChooserService != null && this.fileChooserService.isWebStart()))
+ {
+ this.fileRecentMenu.setEnabled(false);
+ }
+ }
+
+ /**
+ * Updates file recent menu
+ */
+ private void refreshFileRecentMenu()
+ {
+ fileRecentMenu.removeAll();
+ for (final IFile aFile : userPreferencesService.getRecentFiles())
+ {
+ String name = aFile.getFilename();
+ JMenuItem item = new JMenuItem(name);
+ fileRecentMenu.add(item);
+ item.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent event)
+ {
+ try {
+ IGraphFile graphFile = new GraphFile(aFile);
+ IWorkspace workspace = new Workspace(graphFile);
+ mainFrame.addTabbedPane(workspace);
+ } catch (IOException e) {
+ dialogFactory.showErrorDialog(e.getMessage());
+ }
+ }
+ });
+ }
+ }
+
+ /** The file chooser to use with with menu */
+ @InjectedBean
+ private IFileChooserService fileChooserService;
+
+ /** Application stopper */
+ private ApplicationStopper stopper = new ApplicationStopper();
+
+ /** Plugin registry */
+ @InjectedBean
+ private PluginRegistry pluginRegistry;
+
+ /** DialogBox handler */
+ @InjectedBean
+ private DialogFactory dialogFactory;
+
+ /** Access to user preferences */
+ @InjectedBean
+ private UserPreferencesService userPreferencesService;
+
+ /** File services */
+ @InjectedBean
+ private FileNamingService fileNamingService;
+
+ /** Application main frame */
+ private MainFrame mainFrame;
+
+ @ResourceBundleBean(key = "file.new")
+ private JMenu fileNewMenu;
+
+ @ResourceBundleBean(key = "file.open")
+ private JMenuItem fileOpenItem;
+
+ @ResourceBundleBean(key = "file.recent")
+ private JMenu fileRecentMenu;
+
+ @ResourceBundleBean(key = "file.close")
+ private JMenuItem fileCloseItem;
+
+ @ResourceBundleBean(key = "file.save")
+ private JMenuItem fileSaveItem;
+
+ @ResourceBundleBean(key = "file.save_as")
+ private JMenuItem fileSaveAsItem;
+
+ @ResourceBundleBean(key = "file.export_to_image")
+ private JMenuItem fileExportToImageItem;
+
+ @ResourceBundleBean(key = "file.export_to_clipboard")
+ private JMenuItem fileExportToClipBoardItem;
+
+ @ResourceBundleBean(key = "file.export_to_java")
+ private JMenuItem fileExportToJavaItem;
+
+ @ResourceBundleBean(key = "file.export_to_python")
+ private JMenuItem fileExportToPythonItem;
+
+ @ResourceBundleBean(key = "file.export")
+ private JMenu fileExportMenu;
+
+ @ResourceBundleBean(key = "file.print")
+ private JMenuItem filePrintItem;
+
+ @ResourceBundleBean(key = "file.exit")
+ private JMenuItem fileExitItem;
+
+ @ResourceBundleBean(key = "dialog.close.title")
+ private String dialogCloseTitle;
+
+ @ResourceBundleBean(key = "dialog.close.ok")
+ private String dialogCloseMessage;
+
+ @ResourceBundleBean(key = "dialog.close.icon")
+ private ImageIcon dialogCloseIcon;
+
+}
diff --git a/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/menu/HelpMenu.java b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/menu/HelpMenu.java
new file mode 100644
index 0000000..244ee92
--- /dev/null
+++ b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/menu/HelpMenu.java
@@ -0,0 +1,121 @@
+/*
+ Violet - A program for editing UML diagrams.
+
+ Copyright (C) 2007 Cay S. Horstmann (http://horstmann.com)
+ Alexandre de Pellegrin (http://alexdp.free.fr);
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package com.horstmann.violet.application.menu;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.JFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+
+import com.horstmann.violet.application.gui.MainFrame;
+import com.horstmann.violet.application.help.AboutDialog;
+import com.horstmann.violet.application.help.HelpManager;
+import com.horstmann.violet.framework.injection.resources.ResourceBundleInjector;
+import com.horstmann.violet.framework.injection.resources.annotation.ResourceBundleBean;
+
+/**
+ * Help menu
+ *
+ * @author Alexandre de Pellegrin
+ *
+ */
+@ResourceBundleBean(resourceReference = MenuFactory.class)
+public class HelpMenu extends JMenu
+{
+
+ /**
+ * Default constructor
+ *
+ * @param mainFrame where this menu is atatched
+ * @param factory to access to external resources such as texts, icons
+ */
+ @ResourceBundleBean(key = "help")
+ public HelpMenu(MainFrame mainFrame)
+ {
+ ResourceBundleInjector.getInjector().inject(this);
+ this.mainFrame = mainFrame;
+ this.createMenu();
+ }
+
+ /**
+ * Initializes menu
+ */
+ private void createMenu()
+ {
+
+ userGuideItem.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ HelpManager.getInstance().openUserGuide();
+ }
+
+ });
+ this.add(userGuideItem);
+
+ homepageItem.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ HelpManager.getInstance().openHomepage();
+ }
+
+ });
+ this.add(homepageItem);
+
+ aboutItem.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ AboutDialog dialog = new AboutDialog(mainFrame);
+ dialog.setVisible(true);
+ }
+
+ });
+ this.add(aboutItem);
+
+ }
+
+
+
+
+
+
+ /**
+ * Main app frame where this menu is attached to
+ */
+ private JFrame mainFrame;
+
+ @ResourceBundleBean(key = "help.userguide")
+ private JMenuItem userGuideItem;
+
+ @ResourceBundleBean(key = "help.homepage")
+ private JMenuItem homepageItem;
+
+ @ResourceBundleBean(key = "help.about")
+ private JMenuItem aboutItem;
+
+
+
+}
diff --git a/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/menu/MenuFactory.java b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/menu/MenuFactory.java
new file mode 100644
index 0000000..7590f20
--- /dev/null
+++ b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/menu/MenuFactory.java
@@ -0,0 +1,95 @@
+/*
+ Violet - A program for editing UML diagrams.
+
+ Copyright (C) 2007 Cay S. Horstmann (http://horstmann.com)
+ Alexandre de Pellegrin (http://alexdp.free.fr);
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package com.horstmann.violet.application.menu;
+
+import com.horstmann.violet.application.gui.MainFrame;
+
+/**
+ * Menu factory
+ *
+ * Be careful, it is not a singleton
+ *
+ * @author Alexandre de Pellegrin
+ *
+ */
+public class MenuFactory
+{
+
+ /**
+ * @param mainFrame
+ * @return edit menu
+ */
+ public EditMenu getEditMenu(MainFrame mainFrame)
+ {
+ if (this.editMenu == null)
+ {
+ this.editMenu = new EditMenu(mainFrame);
+ }
+ return this.editMenu;
+ }
+
+ /**
+ * @param editorFrame
+ * @return file menu
+ */
+ public FileMenu getFileMenu(MainFrame editorFrame)
+ {
+ if (this.fileMenu == null)
+ {
+ this.fileMenu = new FileMenu(editorFrame);
+ }
+ return this.fileMenu;
+ }
+
+ /**
+ * @param editorFrame
+ * @return help menu
+ */
+ public HelpMenu getHelpMenu(MainFrame editorFrame)
+ {
+ if (this.helpMenu == null)
+ {
+ this.helpMenu = new HelpMenu(editorFrame);
+ }
+ return this.helpMenu;
+ }
+
+ /**
+ * @param editorFrame
+ * @return view menu
+ */
+ public ViewMenu getViewMenu(MainFrame editorFrame)
+ {
+ if (this.viewMenu == null)
+ {
+ this.viewMenu = new ViewMenu(editorFrame);
+ }
+ return this.viewMenu;
+ }
+
+
+ private EditMenu editMenu;
+ private FileMenu fileMenu;
+ private HelpMenu helpMenu;
+ private ViewMenu viewMenu;
+
+}
diff --git a/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/menu/MenuFactory.properties b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/menu/MenuFactory.properties
new file mode 100644
index 0000000..a2d0244
--- /dev/null
+++ b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/menu/MenuFactory.properties
@@ -0,0 +1,140 @@
+file.text=File
+file.mnemonic=F
+file.new.text=New
+file.new.mnemonic=N
+file.new.icon=/icons/16x16/new.png
+file.open.text=Open
+file.open.mnemonic=O
+file.open.accelerator=ctrl O
+file.open_remote.text=Open remote file
+file.open_remote.mnemonic=R
+file.open_remote.accelerator=ctrl R
+file.close.text=Close
+file.close.mnemonic=C
+file.close.accelerator=ctrl W
+file.open.icon=/icons/16x16/open.png
+file.recent.text=Recent files
+file.recent.mnemonic=R
+file.save.text=Save
+file.save.mnemonic=S
+file.save.accelerator=ctrl S
+file.save.icon=/icons/16x16/save.png
+file.save_as.text=Save as
+file.save_as.mnemonic=A
+file.save_as.icon=/icons/16x16/saveas.png
+file.export.text=Export to
+file.export.mnemonic=E
+file.export.icon=/icons/16x16/export.png
+file.export_to_image.text=Image file
+file.export_to_clipboard.text=Clipboard
+file.export_to_xmi.text=XMI exchange format
+file.export_to_java.text=Java code
+file.export_to_python.text=Python code
+file.print.text=Print
+file.print.mnemonic=P
+file.print.icon=/icons/16x16/print.png
+file.exit.text=Exit
+file.exit.mnemonic=Q
+file.exit.accelerator=ctrl Q
+file.link.text=Linked to
+file.link.open.text=Open diagram
+edit.text=Edit
+edit.mnemonic=E
+edit.undo.text=Undo
+edit.undo.mnemonic=U
+edit.undo.accelerator=ctrl Z
+edit.undo.icon=/icons/16x16/undo.png
+edit.redo.text=Redo
+edit.redo.mnemonic=R
+edit.redo.accelerator=ctrl Y
+edit.redo.icon=/icons/16x16/redo.png
+edit.properties.text=Properties
+edit.properties.mnemonic=O
+edit.properties.accelerator=ctrl ENTER
+edit.properties.icon=/icons/16x16/properties.png
+edit.delete.text=Delete
+edit.delete.mnemonic=D
+edit.delete.accelerator=DELETE
+edit.delete.icon=/icons/16x16/delete.png
+edit.cut.text=Cut
+edit.cut.mnemonic=T
+edit.cut.accelerator=ctrl X
+edit.cut.icon=/icons/16x16/cut.png
+edit.copy.text=Copy
+edit.copy.mnemonic=C
+edit.copy.accelerator=ctrl C
+edit.copy.icon=/icons/16x16/copy.png
+edit.paste.text=Paste
+edit.paste.mnemonic=P
+edit.paste.accelerator=ctrl V
+edit.paste.icon=/icons/16x16/paste.png
+edit.select_all.text=Select All
+edit.select_all.mnemonic=A
+edit.select_all.accelerator=ctrl A
+edit.select_next.text=Select Next
+edit.select_next.mnemonic=N
+edit.select_next.accelerator=ctrl RIGHT
+edit.select_previous.text=Select Previous
+edit.select_previous.mnemonic=V
+edit.select_previous.accelerator=ctrl LEFT
+dialog.export_to_clipboard.title=To clipboard...
+dialog.export_to_clipboard.ok=Current diagram image exported to clipboard
+dialog.export_to_clipboard.icon=/icons/64x64/exporttoclipboard.png
+dialog.export_to_xmi.error=Only class diagrams could be exported to XMI
+dialog.error.title=Error
+dialog.error.unsupported_image={0} not supported
+dialog.close.title=Close
+dialog.close.ok=Diagram has been modified. Save changes?
+dialog.close.icon=/icons/64x64/save.png
+dialog.change_laf.title=Restart needed
+dialog.change_laf.ok=The selected look and feel will be applied on next restart.
+dialog.change_laf.icon=/icons/64x64/information.png
+dialog.open_url_failed.title=Web browser opening error
+dialog.open_url_failed.icon=/icons/64x64/error.png
+dialog.open_url_failed.ok=Failed to open {0}\nYou should try to open it directly with your web browser.\n(Url has been copied to clipboard. Just paste it!)
+view.text=View
+view.mnemonic=V
+view.zoom_out.text=Zoom out
+view.zoom_out.mnemonic=Z
+view.zoom_out.accelerator=ctrl MINUS
+view.zoom_out.icon=/icons/16x16/zoomout.png
+view.zoom_in.text=Zoom in
+view.zoom_in.mnemonic=O
+view.zoom_in.accelerator=ctrl EQUALS
+view.zoom_in.icon=/icons/16x16/zoomin.png
+view.smaller_grid.text=Smaller grid
+view.smaller_grid.mnemonic=S
+view.grow_drawing_area.text=Grow drawing area
+view.grow_drawing_area.mnemonic=G
+view.clip_drawing_area.text=Clip drawing area
+view.clip_drawing_area.mnemonic=C
+view.larger_grid.text=Larger grid
+view.larger_grid.mnemonic=L
+view.hide_grid.text=Hide grid
+view.hide_grid.mnemonic=H
+view.change_laf.text=Change Look&Feel
+window.text=Window
+window.mnemonic=W
+window.next.text=Next
+window.next.mnemonic=N
+window.next.accelerator=ctrl TAB
+window.previous.text=Previous
+window.previous.mnemonic=P
+window.previous.accelerator=ctrl shift TAB
+window.maximize.text=Maximize
+window.maximize.mnemonic=M
+window.restore.text=Restore
+window.restore.mnemonic=R
+window.close.text=Close
+window.close.mnemonic=C
+window.close.accelerator=ctrl W
+help.text=Help
+help.mnemonic=H
+help.about.text=About Violet UML Editor...
+help.about.mnemonic=A
+help.userguide.text=User guide (online)
+help.userguide.mnemonic=G
+help.userguide.url=http://violet.sourceforge.net/help.php?lang=en
+help.homepage.text=Home Page
+help.homepage.mnemonic=H
+help.homepage.url=http://violet.sourceforge.net/index.php?lang=en
\ No newline at end of file
diff --git a/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/menu/MenuFactory_fr.properties b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/menu/MenuFactory_fr.properties
new file mode 100644
index 0000000..8dc72c6
--- /dev/null
+++ b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/menu/MenuFactory_fr.properties
@@ -0,0 +1,127 @@
+file.text=Fichier
+file.mnemonic=F
+file.new.text=Nouveau
+file.new.mnemonic=N
+file.new.icon=/icons/16x16/new.png
+file.open.text=Ouvrir
+file.open.mnemonic=O
+file.open.accelerator=ctrl O
+file.openRemote.text=Ouvrir document partag\u00e9
+file.openRemote.mnemonic=R
+file.openRemote.accelerator=ctrl R
+file.close.text=Fermer
+file.close.mnemonic=F
+file.close.accelerator=ctrl W
+file.open.icon=/icons/16x16/open.png
+file.recent.text=Fichiers r\u00e9cents
+file.recent.mnemonic=R
+file.save.text=Enregistrer
+file.save.mnemonic=S
+file.save.accelerator=ctrl S
+file.save.icon=/icons/16x16/save.png
+file.save_as.text=Enregistrer sous
+file.save_as.mnemonic=A
+file.save_as.icon=/icons/16x16/saveas.png
+file.export.text=Exporter vers
+file.export.mnemonic=E
+file.export.icon=/icons/16x16/export.png
+file.export_to_image.text=Fichier image
+file.export_to_clipboard.text=Presse papier
+file.export_to_xmi.text=Format d'\u00e9change XMI
+file.export_to_java.text=Code Java
+file.export_to_python.text=Code Python
+file.print.text=Imprimer
+file.print.mnemonic=P
+file.print.icon=/icons/16x16/print.png
+file.exit.text=Quitter
+file.exit.mnemonic=Q
+file.exit.accelerator=ctrl Q
+file.link.text=Li\u00e9 \u00e0
+file.link.open.text=Ouvrir le diagramme
+edit.text=Edition
+edit.mnemonic=E
+edit.undo.text=Annuler
+edit.undo.mnemonic=A
+edit.undo.accelerator=ctrl Z
+edit.undo.icon=/icons/16x16/undo.png
+edit.redo.text=R\u00e9tablir
+edit.redo.mnemonic=R
+edit.redo.accelerator=ctrl Y
+edit.redo.icon=/icons/16x16/redo.png
+edit.properties.text=Propri\u00e9t\u00e9s
+edit.properties.mnemonic=P
+edit.properties.accelerator=ctrl ENTER
+edit.properties.icon=/icons/16x16/properties.png
+edit.delete.text=Supprimer
+edit.delete.mnemonic=S
+edit.delete.accelerator=DELETE
+edit.delete.icon=/icons/16x16/delete.png
+edit.cut.text=Couper
+edit.cut.mnemonic=O
+edit.cut.accelerator=ctrl X
+edit.cut.icon=/icons/16x16/cut.png
+edit.copy.text=Copier
+edit.copy.mnemonic=I
+edit.copy.accelerator=ctrl C
+edit.copy.icon=/icons/16x16/copy.png
+edit.paste.text=Coller
+edit.paste.mnemonic=L
+edit.paste.accelerator=ctrl V
+edit.paste.icon=/icons/16x16/paste.png
+edit.select_all.text=S\u00e9l\u00e9ctionner tout
+edit.select_all.mnemonic=A
+edit.select_all.accelerator=ctrl A
+edit.select_next.text=S\u00e9l\u00e9ctionner suivant
+edit.select_next.mnemonic=U
+edit.select_next.accelerator=ctrl RIGHT
+edit.select_previous.text=S\u00e9l\u00e9ctionner pr\u00e9c\u00e9dent
+edit.select_previous.mnemonic=D
+edit.select_previous.accelerator=ctrl LEFT
+dialog.export_to_clipboard.title=Vers le presse papier...
+dialog.export_to_clipboard.ok=Image du diagramme en cours export\u00e9e vers le presse papier
+dialog.export_to_clipboard.icon=/icons/64x64/exporttoclipboard.png
+dialog.export_to_xmi.error=Seuls les diagrammes de classe peuvent \u00eatre export\u00e9s en XMI
+dialog.error.title=Erreur
+dialog.error.unsupported_image={0} non support\u00e9
+dialog.close.title=Fermer
+dialog.close.ok=Diagramme modifi\u00e9. Enregistrer les changements ?
+dialog.close.icon=/icons/64x64/save.png
+dialog.change_laf.title=Red\u00e9marrage n\u00e9cessaire
+dialog.change_laf.ok=Le th\u00e8me graphique s\u00e9l\u00e9ctionn\u00e9 ne sera appliqu\u00e9 qu'au prochain red\u00e9marrage.
+dialog.change_laf.icon=/icons/64x64/information.png
+dialog.open_url_failed.title=Erreur d'ouverture du navigateur internet
+dialog.open_url_failed.icon=/icons/64x64/error.png
+dialog.open_url_failed.ok=Impossible d'ouvrir {0}\nVous pouvez l'ouvrir directement via votre navigateur internet.\n(L'url a \u00e9t\u00e9 copi\u00e9e dans votre presse papier. Collez-la simplement!)
+view.text=Affichage
+view.mnemonic=A
+view.zoom_out.text=Zoom avant
+view.zoom_out.mnemonic=V
+view.zoom_out.accelerator=ctrl MINUS
+view.zoom_out.icon=/icons/16x16/zoomout.png
+view.zoom_in.text=Zoom arri\u00e8re
+view.zoom_in.mnemonic=R
+view.zoom_in.accelerator=ctrl EQUALS
+view.zoom_in.icon=/icons/16x16/zoomin.png
+view.smaller_grid.text=R\u00e9duire la grille
+view.smaller_grid.mnemonic=D
+view.grow_drawing_area.text=Augmenter l'espace de dessin
+view.grow_drawing_area.mnemonic=A
+view.clip_drawing_area.text=Rogner l'espace de dessin
+view.clip_drawing_area.mnemonic=O
+view.larger_grid.text=Elargir la grille
+view.larger_grid.mnemonic=E
+view.hide_grid.text=Cacher la grille
+view.hide_grid.mnemonic=C
+view.change_laf.text=Changer de th\u00e8me graphique
+help.text=?
+help.mnemonic=?
+help.about.text=A propos de Violet UML Editor...
+help.about.mnemonic=A
+help.license.text=Licence
+help.license.mnemonic=L
+help.userguide.text=Guide utilisateur (en ligne)
+help.userguide.mnemonic=G
+help.userguide.url=http://violet.sourceforge.net/help.php?lang=fr
+help.homepage.text=Site internet
+help.homepage.mnemonic=S
+help.homepage.url=http://violet.sourceforge.net/index.php?lang=fr
\ No newline at end of file
diff --git a/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/menu/MenuUtils.java b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/menu/MenuUtils.java
new file mode 100644
index 0000000..915e5d0
--- /dev/null
+++ b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/menu/MenuUtils.java
@@ -0,0 +1,49 @@
+package com.horstmann.violet.application.menu;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.MenuElement;
+
+public class MenuUtils
+{
+
+ public static void alterMenuBar(JMenuBar menuBar)
+ {
+
+ MenuElement[] subMenuElements = menuBar.getSubElements();
+ List menuEntryStack = new ArrayList();
+ if (subMenuElements.length > 0)
+ {
+ menuEntryStack.addAll(Arrays.asList(subMenuElements));
+ }
+ while (!menuEntryStack.isEmpty())
+ {
+ MenuElement menuElement = menuEntryStack.get(0);
+ if (menuElement instanceof JMenuItem)
+ {
+ final JMenuItem menuItem = (JMenuItem) menuElement;
+ menuItem.addActionListener(new ActionListener()
+ {
+
+ public void actionPerformed(ActionEvent e)
+ {
+ System.out.println(menuItem.getName());
+ }
+
+ });
+ }
+ MenuElement[] subElements = menuElement.getSubElements();
+ if (subElements.length > 0)
+ {
+ menuEntryStack.addAll(Arrays.asList(subElements));
+ }
+ menuEntryStack.remove(0);
+ }
+ }
+}
diff --git a/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/menu/ViewMenu.java b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/menu/ViewMenu.java
new file mode 100644
index 0000000..7e059de
--- /dev/null
+++ b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/menu/ViewMenu.java
@@ -0,0 +1,331 @@
+/*
+ Violet - A program for editing UML diagrams.
+
+ Copyright (C) 2007 Cay S. Horstmann (http://horstmann.com)
+ Alexandre de Pellegrin (http://alexdp.free.fr);
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package com.horstmann.violet.application.menu;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.List;
+
+import javax.swing.ButtonGroup;
+import javax.swing.ImageIcon;
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.event.MenuEvent;
+import javax.swing.event.MenuListener;
+
+import com.horstmann.violet.application.gui.MainFrame;
+import com.horstmann.violet.framework.dialog.DialogFactory;
+import com.horstmann.violet.framework.injection.bean.ManiocFramework.BeanInjector;
+import com.horstmann.violet.framework.injection.bean.ManiocFramework.InjectedBean;
+import com.horstmann.violet.framework.injection.resources.ResourceBundleInjector;
+import com.horstmann.violet.framework.injection.resources.annotation.ResourceBundleBean;
+import com.horstmann.violet.framework.theme.ITheme;
+import com.horstmann.violet.framework.theme.ThemeInfo;
+import com.horstmann.violet.framework.theme.ThemeManager;
+import com.horstmann.violet.workspace.IWorkspace;
+import com.horstmann.violet.workspace.editorpart.IEditorPart;
+
+/**
+ * View menu
+ *
+ * @author Alexandre de Pellegrin
+ *
+ */
+@ResourceBundleBean(resourceReference = MenuFactory.class)
+public class ViewMenu extends JMenu
+{
+
+ /**
+ * Default constructor
+ *
+ * @param mainFrame where this menu is attached
+ */
+ @ResourceBundleBean(key = "view")
+ public ViewMenu(MainFrame mainFrame)
+ {
+ BeanInjector.getInjector().inject(this);
+ ResourceBundleInjector.getInjector().inject(this);
+ this.mainFrame = mainFrame;
+ this.createMenu();
+ }
+
+ /**
+ * Initializes menu
+ */
+ private void createMenu()
+ {
+
+ zoomOut.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent event)
+ {
+ performZoomOut();
+ }
+ });
+ this.add(zoomOut);
+
+ zoomIn.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent event)
+ {
+ performZoomIn();
+ }
+ });
+ this.add(zoomIn);
+
+ growDrawingArea.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent event)
+ {
+ performGrowDrawingArea();
+ }
+ });
+ this.add(growDrawingArea);
+
+ clipDrawingArea.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent event)
+ {
+ performClipDrawingArea();
+ }
+ });
+ this.add(clipDrawingArea);
+
+ smallerGrid.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent event)
+ {
+ performDisplaySmallerGrid();
+ }
+ });
+ this.add(smallerGrid);
+
+ largerGrid.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent event)
+ {
+ performDisplayLargerGrid();
+ }
+ });
+ this.add(largerGrid);
+
+ hideGridItem.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent event)
+ {
+ performHideGrid(event);
+ }
+ });
+
+ this.addMenuListener(new MenuListener()
+ {
+ public void menuSelected(MenuEvent event)
+ {
+ if (mainFrame.getWorkspaceList().size() == 0) return;
+ IWorkspace activeWorkspace = mainFrame.getActiveWorkspace();
+ IEditorPart activeEditor = activeWorkspace.getEditorPart();
+ hideGridItem.setSelected(!activeEditor.getGrid().isVisible());
+ }
+
+ public void menuDeselected(MenuEvent event)
+ {
+ }
+
+ public void menuCanceled(MenuEvent event)
+ {
+ }
+ });
+
+ ButtonGroup lookAndFeelButtonGroup = new ButtonGroup();
+ String preferedLafName = this.themeManager.getPreferedLookAndFeel();
+ List themes = this.themeManager.getInstalledThemes();
+ for (ITheme aTheme : themes)
+ {
+ ThemeInfo themeInfo = aTheme.getThemeInfo();
+ String themeName = themeInfo.getName();
+ final String themeClassName = themeInfo.getThemeClass().getName();
+ JMenuItem lafMenu = new JCheckBoxMenuItem(themeName);
+ lafMenu.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ performChangeLookAndFeel(themeClassName);
+ }
+ });
+ changeLookAndFeelMenu.add(lafMenu);
+ lookAndFeelButtonGroup.add(lafMenu);
+ if (themeClassName.equals(preferedLafName))
+ {
+ lafMenu.setSelected(true);
+ }
+ }
+ this.add(changeLookAndFeelMenu);
+
+ }
+
+ /**
+ * Performs zoom out action
+ */
+ private void performZoomOut()
+ {
+ if (mainFrame.getWorkspaceList().size() == 0) return;
+ IWorkspace workspace = mainFrame.getActiveWorkspace();
+ workspace.getEditorPart().changeZoom(-1);
+ }
+
+ /**
+ * Performs zoom in action
+ */
+ private void performZoomIn()
+ {
+ if (mainFrame.getWorkspaceList().size() == 0) return;
+ IWorkspace workspace = mainFrame.getActiveWorkspace();
+ workspace.getEditorPart().changeZoom(1);
+ }
+
+ /**
+ * Performs gros drawing area action
+ */
+ private void performGrowDrawingArea()
+ {
+ if (mainFrame.getWorkspaceList().size() == 0) return;
+ IWorkspace workspace = mainFrame.getActiveWorkspace();
+ workspace.getEditorPart().growDrawingArea();
+ }
+
+ /**
+ * Performs clip drawing area action
+ */
+ private void performClipDrawingArea()
+ {
+ if (mainFrame.getWorkspaceList().size() == 0) return;
+ IWorkspace workspace = mainFrame.getActiveWorkspace();
+ workspace.getEditorPart().clipDrawingArea();
+ }
+
+ /**
+ * Performs display smaller grid action
+ */
+ private void performDisplaySmallerGrid()
+ {
+ if (mainFrame.getWorkspaceList().size() == 0) return;
+ IWorkspace workspace = mainFrame.getActiveWorkspace();
+ IEditorPart editorPart = workspace.getEditorPart();
+ editorPart.getGrid().changeGridSize(-1);
+ editorPart.getSwingComponent().repaint();
+ }
+
+ /**
+ * Performs display larger grid action
+ */
+ private void performDisplayLargerGrid()
+ {
+ if (mainFrame.getWorkspaceList().size() == 0) return;
+ IWorkspace workspace = mainFrame.getActiveWorkspace();
+ IEditorPart editorPart = workspace.getEditorPart();
+ editorPart.getGrid().changeGridSize(1);
+ editorPart.getSwingComponent().repaint();
+ }
+
+ /**
+ * Performs hist grid action
+ *
+ * @param event that handle the checkbox menu item to know if the hide sould be shown or not
+ */
+ private void performHideGrid(ActionEvent event)
+ {
+ if (mainFrame.getWorkspaceList().size() == 0) return;
+ IWorkspace workspace = mainFrame.getActiveWorkspace();
+ boolean isHidden = hideGridItem.isSelected();
+ IEditorPart editorPart = workspace.getEditorPart();
+ if (isHidden)
+ {
+ editorPart.getGrid().setVisible(false);
+ }
+ else
+ {
+ editorPart.getGrid().setVisible(true);
+ }
+ editorPart.getSwingComponent().repaint();
+ }
+
+ /**
+ * Performs look and feel change
+ *
+ * @param className look and feel or pgs theme class name
+ */
+ private void performChangeLookAndFeel(String className)
+ {
+ this.themeManager.setPreferedLookAndFeel(className);
+ JOptionPane optionPane = new JOptionPane();
+ optionPane.setMessage(changeLAFDialogMessage);
+ optionPane.setIcon(changeLAFDialogIcon);
+ this.dialogFactory.showDialog(optionPane, changeLAFDialogTitle, true);
+ }
+
+ /**
+ * Current editor frame
+ */
+ private MainFrame mainFrame;
+
+ @ResourceBundleBean(key = "view.zoom_out")
+ private JMenuItem zoomOut;
+
+ @ResourceBundleBean(key = "view.zoom_in")
+ private JMenuItem zoomIn;
+
+ @ResourceBundleBean(key = "view.grow_drawing_area")
+ private JMenuItem growDrawingArea;
+
+ @ResourceBundleBean(key = "view.clip_drawing_area")
+ private JMenuItem clipDrawingArea;
+
+ @ResourceBundleBean(key = "view.smaller_grid")
+ private JMenuItem smallerGrid;
+
+ @ResourceBundleBean(key = "view.larger_grid")
+ private JMenuItem largerGrid;
+
+ @ResourceBundleBean(key = "view.hide_grid")
+ private JCheckBoxMenuItem hideGridItem;
+
+ @ResourceBundleBean(key = "view.change_laf")
+ private JMenu changeLookAndFeelMenu;
+
+ @ResourceBundleBean(key = "dialog.change_laf.title")
+ private String changeLAFDialogTitle;
+
+ @ResourceBundleBean(key = "dialog.change_laf.ok")
+ private String changeLAFDialogMessage;
+
+ @ResourceBundleBean(key = "dialog.change_laf.icon")
+ private ImageIcon changeLAFDialogIcon;
+
+ @InjectedBean
+ private DialogFactory dialogFactory;
+
+ @InjectedBean
+ private ThemeManager themeManager;
+
+}
diff --git a/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/swingextension/VerticalAutoScrollPane.java b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/swingextension/VerticalAutoScrollPane.java
new file mode 100644
index 0000000..d33db25
--- /dev/null
+++ b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/swingextension/VerticalAutoScrollPane.java
@@ -0,0 +1,74 @@
+/*
+ Violet - A program for editing UML diagrams.
+
+ Copyright (C) 2007 Cay S. Horstmann (http://horstmann.com)
+ Alexandre de Pellegrin (http://alexdp.free.fr);
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package com.horstmann.violet.application.swingextension;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.JScrollBar;
+import javax.swing.JScrollPane;
+import javax.swing.Timer;
+
+/**
+ * This panel scrolls its content vertically
+ *
+ * @author Alexandre de Pellegrin
+ *
+ */
+public class VerticalAutoScrollPane extends JScrollPane implements ActionListener
+{
+
+ public VerticalAutoScrollPane()
+ {
+ setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
+ }
+
+ public void reset()
+ {
+ getVerticalScrollBar().setValue(0);
+ }
+
+ public void animate()
+ {
+ if (timer != null)
+ {
+ timer.stop();
+ }
+ timer = new Timer(50, this);
+ timer.setInitialDelay(2000);
+ timer.start();
+ }
+
+ public void actionPerformed(ActionEvent e)
+ {
+ JScrollBar verticalScrollBar = getVerticalScrollBar();
+ verticalScrollBar.setValue(verticalScrollBar.getValue() + 2);
+ if (verticalScrollBar.getValue() >= verticalScrollBar.getMaximum())
+ {
+ timer.stop();
+ }
+ }
+
+ private Timer timer;
+
+}
diff --git a/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/swingextension/WelcomeButtonUI.java b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/swingextension/WelcomeButtonUI.java
new file mode 100644
index 0000000..33e07c2
--- /dev/null
+++ b/VioletProductSwing/VioletProduct.swing/src/main/java/com/horstmann/violet/application/swingextension/WelcomeButtonUI.java
@@ -0,0 +1,69 @@
+/*
+ Violet - A program for editing UML diagrams.
+
+ Copyright (C) 2007 Cay S. Horstmann (http://horstmann.com)
+ Alexandre de Pellegrin (http://alexdp.free.fr);
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package com.horstmann.violet.application.swingextension;
+
+import java.awt.Cursor;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+
+import javax.swing.AbstractButton;
+import javax.swing.ButtonModel;
+import javax.swing.border.EmptyBorder;
+import javax.swing.plaf.basic.BasicButtonUI;
+
+import com.horstmann.violet.framework.theme.ThemeManager;
+
+public class WelcomeButtonUI extends BasicButtonUI
+{
+
+ public WelcomeButtonUI()
+ {
+ super();
+ }
+
+ protected void installDefaults(AbstractButton b)
+ {
+ super.installDefaults(b);
+ b.setOpaque(false);
+ b.setBorderPainted(false);
+ b.setRolloverEnabled(true);
+ b.setFont(ThemeManager.getInstance().getTheme().getWelcomeBigFont());
+ b.setBorder(new EmptyBorder(0, 0, 0, 0));
+ }
+
+ protected void paintText(Graphics g, AbstractButton b, Rectangle textRect, String text)
+ {
+
+ ButtonModel model = b.getModel();
+ if (model.isRollover())
+ {
+ b.setForeground(ThemeManager.getInstance().getTheme().getWelcomeBigRolloverForegroundColor());
+ b.setCursor(new Cursor(Cursor.HAND_CURSOR));
+ }
+ else
+ {
+ b.setForeground(ThemeManager.getInstance().getTheme().getWelcomeBigForegroundColor());
+ }
+ super.paintText(g, b, textRect, text);
+ }
+
+}