/* 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.workspace; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.ResourceBundle; import com.horstmann.violet.framework.file.IFile; import com.horstmann.violet.framework.file.IGraphFile; import com.horstmann.violet.framework.file.IGraphFileListener; import com.horstmann.violet.framework.injection.bean.ManiocFramework.BeanInjector; import com.horstmann.violet.framework.injection.bean.ManiocFramework.InjectedBean; import com.horstmann.violet.framework.plugin.IDiagramPlugin; import com.horstmann.violet.framework.plugin.PluginRegistry; import com.horstmann.violet.product.diagram.abstracts.IGraph; import com.horstmann.violet.product.diagram.abstracts.Id; import com.horstmann.violet.workspace.editorpart.EditorPart; import com.horstmann.violet.workspace.editorpart.IEditorPart; import com.horstmann.violet.workspace.editorpart.IEditorPartBehaviorManager; import com.horstmann.violet.workspace.editorpart.behavior.AddEdgeBehavior; import com.horstmann.violet.workspace.editorpart.behavior.AddNodeBehavior; import com.horstmann.violet.workspace.editorpart.behavior.AddTransitionPointBehavior; import com.horstmann.violet.workspace.editorpart.behavior.ChangeToolByWeelBehavior; import com.horstmann.violet.workspace.editorpart.behavior.ColorizeBehavior; import com.horstmann.violet.workspace.editorpart.behavior.CutCopyPasteBehavior; import com.horstmann.violet.workspace.editorpart.behavior.DragGraphBehavior; import com.horstmann.violet.workspace.editorpart.behavior.DragSelectedBehavior; import com.horstmann.violet.workspace.editorpart.behavior.DragTransitionPointBehavior; import com.horstmann.violet.workspace.editorpart.behavior.EditSelectedBehavior; import com.horstmann.violet.workspace.editorpart.behavior.FileCouldBeSavedBehavior; import com.horstmann.violet.workspace.editorpart.behavior.ResizeNodeBehavior; import com.horstmann.violet.workspace.editorpart.behavior.SelectAllBehavior; import com.horstmann.violet.workspace.editorpart.behavior.SelectByClickBehavior; import com.horstmann.violet.workspace.editorpart.behavior.SelectByDistanceBehavior; import com.horstmann.violet.workspace.editorpart.behavior.SelectByLassoBehavior; import com.horstmann.violet.workspace.editorpart.behavior.ShowMenuOnRightClickBehavior; import com.horstmann.violet.workspace.editorpart.behavior.SwingRepaintingBehavior; import com.horstmann.violet.workspace.editorpart.behavior.UndoRedoCompoundBehavior; import com.horstmann.violet.workspace.editorpart.behavior.ZoomByWheelBehavior; import com.horstmann.violet.workspace.sidebar.ISideBar; import com.horstmann.violet.workspace.sidebar.SideBar; import com.horstmann.violet.workspace.sidebar.graphtools.GraphTool; import com.horstmann.violet.workspace.sidebar.graphtools.IGraphToolsBarListener; /** * Diagram workspace. It is a kind of package composed by a diagram put in a scroll panel, a side bar for tools and a status bar. * This the class to use when you want to work with diagrams outside from Violet (in Eclipse or NetBeans for example) * * @author Alexandre de Pellegrin */ public class Workspace implements IWorkspace { /** * Constructs a diagram panel with the specified graph * * @param graphFile */ public Workspace(IGraphFile graphFile) { this.graphFile = graphFile; init(); } /** * Constructs a diagram panel with the specified graph and a specified id * * @param graphFile * @param id unique id */ public Workspace(IGraphFile graphFile, Id id) { this.graphFile = graphFile; this.id = id; init(); } private void init() { BeanInjector.getInjector().inject(this); setTitle(getGraphName()); this.graphFile.addListener(new IGraphFileListener() { public void onFileModified() { updateTitle(true); fireSaveNeeded(); } public void onFileSaved() { setTitle(getGraphName()); updateTitle(false); } }); getAWTComponent().prepareLayout(); } /** * @return graph filename or the corresponding diagram name if the graph <br/> * hasn't been saved yet. */ private String getGraphName() { String filename = this.graphFile.getFilename(); if (filename != null) { return filename; } List<IDiagramPlugin> diagramPlugins = this.pluginRegistry.getDiagramPlugins(); Class<? extends IGraph> searchedClass = this.graphFile.getGraph().getClass(); for (IDiagramPlugin aDiagramPlugin : diagramPlugins) { if (aDiagramPlugin.getGraphClass().equals(searchedClass)) { return aDiagramPlugin.getName(); } } return resourceBundle.getString("workspace.unknown"); } @Override public IGraphFile getGraphFile() { return this.graphFile; } @Override public IEditorPart getEditorPart() { if (this.graphEditor == null) { this.graphEditor = new EditorPart(this.graphFile.getGraph()); IEditorPartBehaviorManager behaviorManager = this.graphEditor.getBehaviorManager(); behaviorManager.addBehavior(new SelectByLassoBehavior(this.graphEditor, this.getSideBar().getGraphToolsBar())); behaviorManager.addBehavior(new SelectByClickBehavior(this.graphEditor, this.getSideBar().getGraphToolsBar())); behaviorManager.addBehavior(new SelectByDistanceBehavior(this.graphEditor)); behaviorManager.addBehavior(new SelectAllBehavior(this.graphEditor, this.getSideBar().getGraphToolsBar())); behaviorManager.addBehavior(new AddNodeBehavior(this.graphEditor, this.getSideBar().getGraphToolsBar())); behaviorManager.addBehavior(new AddEdgeBehavior(this.graphEditor, this.getSideBar().getGraphToolsBar())); behaviorManager.addBehavior(new AddTransitionPointBehavior(this.graphEditor, this.getSideBar().getGraphToolsBar())); behaviorManager.addBehavior(new DragSelectedBehavior(this.graphEditor, this.getSideBar().getGraphToolsBar())); behaviorManager.addBehavior(new DragTransitionPointBehavior(this.graphEditor, this.getSideBar().getGraphToolsBar())); behaviorManager.addBehavior(new DragGraphBehavior(this)); behaviorManager.addBehavior(new EditSelectedBehavior(this.graphEditor)); behaviorManager.addBehavior(new FileCouldBeSavedBehavior(this.getGraphFile())); behaviorManager.addBehavior(new ResizeNodeBehavior(this.graphEditor, this.getSideBar().getGraphToolsBar())); behaviorManager.addBehavior(new ZoomByWheelBehavior(this.getEditorPart())); behaviorManager.addBehavior(new ChangeToolByWeelBehavior(this.getSideBar().getGraphToolsBar())); behaviorManager.addBehavior(new ShowMenuOnRightClickBehavior(this.graphEditor)); behaviorManager.addBehavior(new UndoRedoCompoundBehavior(this.graphEditor)); behaviorManager.addBehavior(new CutCopyPasteBehavior(this.graphEditor)); behaviorManager.addBehavior(new SwingRepaintingBehavior(this.graphEditor)); behaviorManager.addBehavior(new ColorizeBehavior(this, this.getSideBar().getColorChoiceBar())); } return this.graphEditor; } @Override public ISideBar getSideBar() { if (this.sideBar == null) { this.sideBar = new SideBar(this); this.sideBar.getGraphToolsBar().addListener(new IGraphToolsBarListener() { public void toolSelectionChanged(GraphTool tool) { getEditorPart().getSelectionHandler().setSelectedTool(tool); } }); } return this.sideBar; } @Override public String getTitle() { return title; } @Override public void setTitle(String newValue) { title = newValue; fireTitleChanged(newValue); } /** * Fires a event to indicate that the title has been changed * * @param newTitle */ private void fireTitleChanged(String newTitle) { List<IWorkspaceListener> tl = cloneListeners(); int size = tl.size(); if (size == 0) return; for (int i = 0; i < size; ++i) { IWorkspaceListener aListener = tl.get(i); aListener.titleChanged(newTitle); } } /** * Set a status indicating that the graph needs to be saved * * @param isSaveNeeded */ private void updateTitle(boolean isSaveNeeded) { String aTitle = getTitle(); String prefix = resourceBundle.getString("workspace.unsaved") + " "; if (isSaveNeeded) { if (!aTitle.startsWith(prefix)) { setTitle(prefix + aTitle); } } if (!isSaveNeeded) { if (aTitle.startsWith(prefix)) { setTitle(aTitle.substring(prefix.length(), aTitle.length() - 1)); } } } @Override public String getFilePath() { return filePath; } @Override public void setFilePath(String path) { filePath = path; File file = new File(path); setTitle(file.getName()); } @Override public synchronized void addListener(IWorkspaceListener l) { if (!this.listeners.contains(l)) { this.listeners.add(l); } } @SuppressWarnings("unchecked") private synchronized List<IWorkspaceListener> cloneListeners() { return (List<IWorkspaceListener>) new ArrayList<IWorkspaceListener>(this.listeners); } /** * Fire an event to all listeners by calling */ public void fireMustOpenFile(IFile aFile) { List<IWorkspaceListener> tl = cloneListeners(); int size = tl.size(); if (size == 0) return; for (int i = 0; i < size; ++i) { IWorkspaceListener l = tl.get(i); l.mustOpenfile(aFile); } } /** * Fire an event to all listeners by calling */ private void fireSaveNeeded() { List<IWorkspaceListener> tl = cloneListeners(); int size = tl.size(); if (size == 0) return; for (int i = 0; i < size; ++i) { IWorkspaceListener l = tl.get(i); l.graphCouldBeSaved(); } } @Override public Id getId() { if (this.id == null) { this.id = new Id(); } return this.id; } @Override public WorkspacePanel getAWTComponent() { if (this.workspacePanel == null) { this.workspacePanel = new WorkspacePanel(this); } return this.workspacePanel; } @Override public void setAWTComponent(WorkspacePanel workspacePanel) { this.workspacePanel = workspacePanel; } public WorkspacePanel workspacePanel; private IGraphFile graphFile; private IEditorPart graphEditor; private ISideBar sideBar; private String filePath; private String title; private List<IWorkspaceListener> listeners = new ArrayList<IWorkspaceListener>(); private Id id; protected static ResourceBundle resourceBundle = ResourceBundle.getBundle("properties.OtherStrings", Locale.getDefault()); @InjectedBean private PluginRegistry pluginRegistry; }