/******************************************************************************** * * * (c) Copyright 2010 Verizon Communications USA and The Open University UK * * * * This software is freely distributed in accordance with * * the GNU Lesser General Public (LGPL) license, version 3 or later * * as published by the Free Software Foundation. * * For details see LGPL: http://www.fsf.org/licensing/licenses/lgpl.html * * and GPL: http://www.fsf.org/licensing/licenses/gpl-3.0.html * * * * This software is provided by the copyright holders and contributors "as is" * * and any express or implied warranties, including, but not limited to, the * * implied warranties of merchantability and fitness for a particular purpose * * are disclaimed. In no event shall the copyright owner or contributors be * * liable for any direct, indirect, incidental, special, exemplary, or * * consequential damages (including, but not limited to, procurement of * * substitute goods or services; loss of use, data, or profits; or business * * interruption) however caused and on any theory of liability, whether in * * contract, strict liability, or tort (including negligence or otherwise) * * arising in any way out of the use of this software, even if advised of the * * possibility of such damage. * * * ********************************************************************************/ package com.compendium.ui.stencils; import java.io.File; import java.util.Date; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import javax.help.HelpBroker; import javax.help.HelpSet; import javax.swing.ImageIcon; import javax.swing.JTabbedPane; import javax.swing.SwingUtilities; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import com.compendium.LanguageProperties; import com.compendium.ProjectCompendium; import com.compendium.core.ICoreConstants; import com.compendium.core.datamodel.IModel; import com.compendium.io.xml.XMLReader; import com.compendium.ui.IUIConstants; import com.compendium.ui.ProjectCompendiumFrame; import com.compendium.ui.UIImages; /** * This class manages all the stencils * * @author Michelle Bachler * @version 1.0 */ public class UIStencilManager implements IUIConstants, ICoreConstants { /** * class's own logger */ final Logger log = LoggerFactory.getLogger(getClass()); /**A reference to the system file path separator*/ public final static String sFS = System.getProperty("file.separator"); //$NON-NLS-1$ /**A reference to the node image directory*/ public final static String sPATH = "System"+sFS+"resources"+sFS+"Stencils"+sFS; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ /** A list of all stencils.*/ private Hashtable htStencils = new Hashtable(10); /** A list of stencil currently displayed.*/ private Hashtable htDisplayedStencils = new Hashtable(10); /** The parent frame for this class.*/ private ProjectCompendiumFrame oParent = null; /** The HelpSet to use for toolbar help.*/ private HelpSet mainHS = null; /** The HelpBroker to use for toolbar help.*/ private HelpBroker mainHB = null; /** Reference to the model for the current database.*/ private IModel oModel = null; /** The tabbedpane to hold the open stencil panels.*/ private JTabbedPane oTabbedPane = null; /** * Constructor. Create a new instance of UIStencilManager, with the given proerties. * @param parent com.compendium.ui.ProjectCompendiumFrame, the parent frame for the application. * @param hs the helpset to use. * @param hb the HelpBroker to use. */ public UIStencilManager(ProjectCompendiumFrame parent, HelpSet hs, HelpBroker hb) { oParent = parent; mainHS = hs; mainHB = hb; oTabbedPane = new JTabbedPane(); oTabbedPane.setTabPlacement(JTabbedPane.TOP); } /** * Return the tabbed pane that holds the stencil set panels. */ public JTabbedPane getTabbedPane() { return oTabbedPane; } /** * Update the look and feel of all the htStencils */ public void updateLAF() { SwingUtilities.updateComponentTreeUI(oTabbedPane); for(Enumeration e = htStencils.elements(); e.hasMoreElements();) { UIStencilSet oStencilSet = (UIStencilSet)e.nextElement(); SwingUtilities.updateComponentTreeUI(oStencilSet); } } /** * Return the stencil set with the given name. * @param UIStencilSet The stencil set with the given name. */ public UIStencilSet getStencilSet(String sName) { UIStencilSet oStencilSet = null; for(Enumeration e = htStencils.keys();e.hasMoreElements();) { String name = (String)e.nextElement(); if (sName.equals(name)) oStencilSet = (UIStencilSet)htStencils.get(name); } return oStencilSet; } /** * Return a list of all the stencil names currently existing. * @param Vector, list of all the stencil names. */ public Vector getStencilNames() { Vector names = new Vector(10); for(Enumeration e = htStencils.keys();e.hasMoreElements();) { String name = (String)e.nextElement(); names.addElement(name); } return names; } /** * Check the passed stencil set name to see if it already exists. * @param sName the name to check. * @return boolean true if the name has already been used, else false; */ public boolean checkName(String sName) { boolean exists = false; for(Enumeration e = htStencils.keys();e.hasMoreElements();) { String name = (String)e.nextElement(); if (sName.equals(name)) return true; } return exists; } /** * Add a stencil to this manager's list. * @param oStencil, the stencil to add. */ public void addStencilSet(String sOldName, UIStencilSet oStencil) { if (!htStencils.containsKey(sOldName)) { htStencils.put(oStencil.getName(), oStencil); } else { htStencils.remove(sOldName); htStencils.put(oStencil.getName(), oStencil); if (htDisplayedStencils.containsKey(sOldName)) { UIStencilSet oldSet = (UIStencilSet)htDisplayedStencils.get(sOldName); htDisplayedStencils.remove(sOldName); htDisplayedStencils.put(oStencil.getName(), oStencil); // IF VISIBLE, UPDATE int index= oTabbedPane.indexOfComponent(oldSet); if (index > -1) { oTabbedPane.removeTabAt(index); if (!oStencil.isDrawn()) oStencil.draw(); oTabbedPane.insertTab(oStencil.getTabName(), null, oStencil, oStencil.getName(), index); oStencil.refreshStencilSet(); oTabbedPane.validate(); oTabbedPane.repaint(); } } } } /** * Remove a stencil from this manager's list. * @param oStencil the stencil to remove. * @return boolean true if added, else false. */ public boolean removeStencilSet(UIStencilSet oStencil) { boolean removed = false; String sName = oStencil.getName(); if (htStencils.containsKey(sName)) { htStencils.remove(sName); closeStencilSet(sName, oStencil); removed = true; } return removed; } /** * Open the stencil with the given name to those currently displayed. * @param sName, the name of the stencil set. * @return boolean, true if opened, else false. */ public boolean openStencilSet(String sName) { boolean opened = false; if (htStencils.containsKey(sName) && !htDisplayedStencils.containsKey(sName)) { UIStencilSet oStencil = (UIStencilSet)htStencils.get(sName); htDisplayedStencils.put(sName, oStencil); if (!oStencil.isDrawn()) { oStencil.draw(); } oTabbedPane.addTab(oStencil.getTabName(), null, oStencil, oStencil.getName()); oTabbedPane.setSelectedComponent(oStencil); opened = true; } if (htDisplayedStencils.size() == 1) { ProjectCompendium.APP.oTabbedPane.addTab(LanguageProperties.getString(LanguageProperties.STENCILS_BUNDLE, "UIStencilManager.stencils"), oTabbedPane); //$NON-NLS-1$ ProjectCompendium.APP.oTabbedPane.setSelectedComponent(oTabbedPane); ProjectCompendium.APP.oSplitter.resetToPreferredSizes(); } return opened; } /** * close the UIStencil panel from those currently displayed. * @param sName, the name of the stencil set. * @param oStencil the stencil set. * @return boolean true if closed, else false. */ public boolean closeStencilSet(String sName, Object set) { boolean closed = false; if (htDisplayedStencils.containsKey(sName)) { oTabbedPane.remove((UIStencilSet)htDisplayedStencils.get(sName)); htDisplayedStencils.remove(sName); closed = true; } if (htDisplayedStencils.size() == 0) { ProjectCompendium.APP.oTabbedPane.remove(oTabbedPane); ProjectCompendium.APP.oSplitter.resetToPreferredSizes(); } return closed; } /** * Return the stencil item associated with the given shortcut number. * @param nShortcut the shortcut number to check for. * @return DraggableStencilIcon the associated item, or null if not found. */ public DraggableStencilIcon getItemForShortcut(int nShortcut) { DraggableStencilIcon oIcon = null; UIStencilSet set = (UIStencilSet)oTabbedPane.getSelectedComponent(); if (set != null) { oIcon = set.getItemForShortcut(nShortcut); } return oIcon; } /** * Load the stencil data from the XML files where it has been save. */ public void loadStencils() { oModel = ProjectCompendium.APP.getModel(); htStencils.clear(); String errorMessage = ""; try { File main = new File("System"+sFS+"resources"+sFS+"Stencils"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ File oStencils[] = main.listFiles(); String stencilName = ""; File nextStencil = null; String nextMessage = ""; for (int i=0; i< oStencils.length; i++) { stencilName = ""; nextStencil = null; try { nextStencil = oStencils[i]; if (nextStencil.isDirectory()) { String folderName = nextStencil.getName(); File oChildren[] = nextStencil.listFiles(); for (int j=0; j< oChildren.length; j++) { File next = oChildren[j]; stencilName = next.getName(); if (stencilName.endsWith(".xml")) { //$NON-NLS-1$ loadFile(next.getAbsolutePath(), stencilName, folderName); } } } } catch (Exception e) { log.info("Exception: Stencil - "+nextStencil.getName()+" could not be loaded due to: "+e.getLocalizedMessage()); nextMessage = ""; if (!stencilName.equals("")) { nextMessage = stencilName.substring(0, stencilName.length()-4); } else if (nextStencil != null) { nextMessage = nextStencil.getName(); } errorMessage += nextMessage+"\n"; } } } catch(Exception ex) { log.error("Error...", ex); } if (!errorMessage.equals("")) { errorMessage = LanguageProperties.getString(LanguageProperties.STENCILS_BUNDLE, "UIStencilManager.loadError1")+"\n"+LanguageProperties.getString(LanguageProperties.STENCILS_BUNDLE, "UIStencilManager.loadError2")+"\n\n"+errorMessage;//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ ProjectCompendium.APP.displayError(errorMessage); } } /** * Load the stencil data for the given filename. * @param sFullPath the path of the file to load. * @param sFileName the filename for this stencil. * @param sFolderName the folder name for this stencil. */ public void loadFile(String sFullPath, String sFileName, String sFolderName) throws Exception { XMLReader reader = new XMLReader(); Document document = reader.read(sFullPath, true); if (document == null) log.info(LanguageProperties.getString(LanguageProperties.STENCILS_BUNDLE, "UIStencilManager.notFoundStencilData")+sFolderName); //$NON-NLS-1$ Node data = document.getDocumentElement(); if (data == null) throw new Exception(LanguageProperties.getString(LanguageProperties.STENCILS_BUNDLE, "UIStencilManager.stencil")+sFileName+" "+LanguageProperties.getString(LanguageProperties.STENCILS_BUNDLE, "UIStencilManager.notLoaded")); //$NON-NLS-1$ //$NON-NLS-2$ storeStencil(data, sFileName, sFolderName); } /** * Store stendil data against name. * @param data the Node XML data object for the stencil to create. * @param sFileName the filename for this stencil. * @param sFolderName the folder name for this stencil. */ private void storeStencil(Node node, String sFileName, String sFolderName) { NamedNodeMap attrs = node.getAttributes(); Attr name = (Attr)attrs.getNamedItem("name"); //$NON-NLS-1$ String sName = new String(name.getValue()); Attr oTabName = (Attr)attrs.getNamedItem("tabname"); //$NON-NLS-1$ String sTabName = ""; //$NON-NLS-1$ if (oTabName != null) sTabName = new String(oTabName.getValue()); if (sTabName.equals("")) //$NON-NLS-1$ sTabName = sName; UIStencilSet oSet = createStencil(node, sName, sTabName, sFileName, sFolderName); addStencilSet(sName, oSet); } /** * Create a stencil panel from the given data. * @param node the Node XML data object for the stencil to create * @param sName the name of the stencil. * @param sFileName the filename of the stencil. */ private UIStencilSet createStencil(Node node, String sName, String sTabName, String sFileName, String sFolderName) { UIStencilSet oStencil = null; if (node.hasChildNodes()) { oStencil = new UIStencilSet(this, sFileName, sFolderName, sName, sTabName); Node items = XMLReader.getFirstChildWithTagName(node, "items"); //$NON-NLS-1$ Vector vtItems = XMLReader.getChildrenWithTagName(items, "item"); //$NON-NLS-1$ if (vtItems.size() > 0) { int count = vtItems.size(); for (int i=0; i<count; i++) { Node child = (Node)vtItems.elementAt(i); NamedNodeMap attrs = child.getAttributes(); Attr oLabel = (Attr)attrs.getNamedItem("label"); //$NON-NLS-1$ String sLabel = new String(oLabel.getValue()); Attr oTip = (Attr)attrs.getNamedItem("tooltip"); //$NON-NLS-1$ String sTip = new String(oTip.getValue()); Attr oImage = (Attr)attrs.getNamedItem("image"); //$NON-NLS-1$ String sImage = new String(oImage.getValue()); sImage = sPATH+sFolderName+sFS+UIStencilSet.sNODEIMAGEDIR+sFS+sImage; Attr oPaletteImage = (Attr)attrs.getNamedItem("paletteimage"); //$NON-NLS-1$ String sPaletteImage = ""; //$NON-NLS-1$ if (oPaletteImage != null) sPaletteImage = new String(oPaletteImage.getValue()); if (!sPaletteImage.equals("")) //$NON-NLS-1$ sPaletteImage = sPATH+sFolderName+sFS+UIStencilSet.sPALETTEIMAGEDIR+sFS+sPaletteImage; Attr oBackgroundImage = (Attr)attrs.getNamedItem("backgroundimage"); //$NON-NLS-1$ String sBackgroundImage = ""; //$NON-NLS-1$ if (oBackgroundImage != null) sBackgroundImage = new String(oBackgroundImage.getValue()); if (!sBackgroundImage.equals("")) //$NON-NLS-1$ sBackgroundImage = sPATH+sFolderName+sFS+UIStencilSet.sBACKGROUNDIMAGEDIR+sFS+sBackgroundImage; Attr oTemplate = (Attr)attrs.getNamedItem("template"); //$NON-NLS-1$ String sTemplate = ""; //$NON-NLS-1$ if (oTemplate != null) sTemplate = new String(oTemplate.getValue()); if (!sTemplate.equals("")) //$NON-NLS-1$ sTemplate = sPATH+sFolderName+sFS+UIStencilSet.sTEMPLATEDIR+sFS+sTemplate; Attr oType = (Attr)attrs.getNamedItem("type"); //$NON-NLS-1$ int nType = new Integer(oType.getValue()).intValue(); Attr oShortcut = (Attr)attrs.getNamedItem("shortcut"); //$NON-NLS-1$ int nShortcut = new Integer(oShortcut.getValue()).intValue(); Vector vtTags = loadTags(XMLReader.getFirstChildWithTagName(child, "tags")); //$NON-NLS-1$ ImageIcon oIcon = null; if (sPaletteImage.equals("")) //$NON-NLS-1$ oIcon = UIImages.thumbnailIcon(sImage); else oIcon = UIImages.thumbnailIcon(sPaletteImage); DraggableStencilIcon item = new DraggableStencilIcon(sImage, sPaletteImage, sBackgroundImage, sTemplate, sLabel, sTip, nType, nShortcut, vtTags, oIcon); oStencil.loadStencilItem(item); } } } return oStencil; } /** * Extract the tags list from the given data. * @param node the Node XML data object for the tags to create */ private Vector loadTags(Node node) { Vector vtTags = new Vector(10); if (node != null && node.hasChildNodes()) { Vector vtTagItems = XMLReader.getChildrenWithTagName(node, "tag"); //$NON-NLS-1$ if (vtTagItems.size() > 0) { int count = vtTagItems.size(); for (int i=0; i<count; i++) { Node child = (Node)vtTagItems.elementAt(i); NamedNodeMap attrs = child.getAttributes(); String sID = ((Attr)attrs.getNamedItem("id")).getValue(); //$NON-NLS-1$ String sName = ((Attr)attrs.getNamedItem("name")).getValue(); //$NON-NLS-1$ String sAuthor = ((Attr)attrs.getNamedItem("author")).getValue(); //$NON-NLS-1$ String sDescription = ((Attr)attrs.getNamedItem("description")).getValue(); //$NON-NLS-1$ String sBehavior = ((Attr)attrs.getNamedItem("behavior")).getValue(); //$NON-NLS-1$ long created = new Long( ((Attr)attrs.getNamedItem("created")).getValue() ).longValue(); //$NON-NLS-1$ long lastModified = new Long( ((Attr)attrs.getNamedItem("lastModified")).getValue() ).longValue(); //$NON-NLS-1$ Date dCreationDate = new Date(created); Date dModificationDate = new Date(lastModified); Vector code = new Vector(7); code.addElement(sID); code.addElement(sName); code.addElement(sAuthor); code.addElement(sDescription); code.addElement(sBehavior); code.addElement(dCreationDate); code.addElement(dModificationDate); vtTags.add(code); } } } return vtTags; } /** * @return Returns the htDisplayedStencils. */ public Hashtable getHtDisplayedStencils() { return htDisplayedStencils; } }