/******************************************************************************** * * * (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.popups; import java.awt.AWTException; import java.awt.Point; import java.awt.Robot; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Date; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.SwingUtilities; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.compendium.LanguageProperties; import com.compendium.ProjectCompendium; import com.compendium.core.ICoreConstants; import com.compendium.core.datamodel.Code; import com.compendium.core.datamodel.IModel; import com.compendium.core.datamodel.NodeSummary; import com.compendium.core.datamodel.PCSession; import com.compendium.core.datamodel.ShortCutNodeSummary; import com.compendium.core.datamodel.View; import com.compendium.ui.IUIArrange; import com.compendium.ui.UIAlign; import com.compendium.ui.UILink; import com.compendium.ui.UIMapViewFrame; import com.compendium.ui.UINode; import com.compendium.ui.UIUtilities; import com.compendium.ui.UIViewPane; import com.compendium.ui.dialogs.UIExportDialog; import com.compendium.ui.dialogs.UIExportViewDialog; import com.compendium.ui.dialogs.UIImportDialog; import com.compendium.ui.edits.DeleteEdit; import com.compendium.ui.plaf.NodeUI; import com.compendium.ui.plaf.ViewPaneUI; import com.compendium.ui.stencils.DraggableStencilIcon; /** * This class has generic methods for the right-click menu options for * map and map node right-click menus * * @author Michelle Bachler */ public abstract class UIBaseMapPopupMenu extends UIBasePopupMenu implements ActionListener{ /** * class's own logger */ final Logger log = LoggerFactory.getLogger(getClass()); /** The JMenu to perform a arrange operation.*/ protected JMenu mnuArrange = null; /** The JMenuItem to perform a arrange operation.*/ protected JMenuItem miMenuItemLeftRightArrange = null; /** The JMenuItem to perform a arrange operation.*/ protected JMenuItem miMenuItemTopDownArrange = null; /** The JMenu to perform a arrange operation.*/ protected JMenu mnuViewAlign = null; /** The JMenuItem to perform a arrange operation.*/ protected JMenuItem miMenuItemAlignTop = null; /** The JMenuItem to perform a arrange operation.*/ protected JMenuItem miMenuItemAlignMiddle = null; /** The JMenuItem to perform a arrange operation.*/ protected JMenuItem miMenuItemAlignBottom = null; /** The JMenuItem to perform a arrange operation.*/ protected JMenuItem miMenuItemAlignLeft = null; /** The JMenuItem to perform a arrange operation.*/ protected JMenuItem miMenuItemAlignCenter = null; /** The JMenuItem to perform a arrange operation.*/ protected JMenuItem miMenuItemAlignRight = null; /** The JMenuItem to delink the currently selected nodes, or the node associated with this popup.*/ protected JMenuItem miMenuItemDelink = null; /** The JMenuItem to import an external folder of image files into the current map.*/ protected JMenuItem miImportImageFolder = null; /** JMenuItem to export the current map to a Jpge file.*/ protected JMenuItem miSaveAsJpeg = null; /** The ViewPaneUI associated with this popup menu.*/ protected ViewPaneUI oViewPaneUI = null; /** The UIViewPane associated with this popup menu.*/ protected UIViewPane oViewPane = null; /** * Constructor. * @param title the title for this popup menu. */ public UIBaseMapPopupMenu(String title) { super(title); } /** * Constructor. Create the menus and items and draws the popup menu. * @param title, the title for this popup menu. * @param viewpaneUI com.compendium.ui.plaf.ViewPaneUI, the associated map for this popup menu. */ public UIBaseMapPopupMenu(String title, ViewPaneUI viewpaneUI) { super(title); setViewPaneUI(viewpaneUI); init(); } /** * Add the menu noption to save the current map as a JPeg. */ protected void addSaveAsJPEG() { miSaveAsJpeg = new JMenuItem(LanguageProperties.getString(LanguageProperties.POPUPS_BUNDLE, "UIBaseMapPopupMenu.jpegFile")); //$NON-NLS-1$ miSaveAsJpeg.addActionListener(this); mnuExport.add(miSaveAsJpeg); } /** * Add the menu item to import and image folder. */ protected void addImportImage() { miImportImageFolder = new JMenuItem(LanguageProperties.getString(LanguageProperties.POPUPS_BUNDLE, "UIBaseMapPopupMenu.imageFolder")); //$NON-NLS-1$ miImportImageFolder.addActionListener(this); mnuImport.add(miImportImageFolder); } /** * Add the menu item to delink selected nodes. */ protected void addDelink() { miMenuItemDelink = new JMenuItem(LanguageProperties.getString(LanguageProperties.POPUPS_BUNDLE, "UIBaseMapPopupMenu.delink")); //$NON-NLS-1$ miMenuItemDelink.addActionListener(this); add(miMenuItemDelink); } /** * Create the arrange submenu and items */ protected void createArrangeMenu() { // Begin edit, Lakshmi (11/3/05) // include Top - Down and Left - Right Option in Arrange Menu. mnuArrange = new JMenu(LanguageProperties.getString(LanguageProperties.POPUPS_BUNDLE, "UIBaseMapPopupMenu.arrange")); //$NON-NLS-1$ mnuArrange.addActionListener(this); miMenuItemLeftRightArrange = new JMenuItem(LanguageProperties.getString(LanguageProperties.POPUPS_BUNDLE, "UIBaseMapPopupMenu.leftToRight")); //$NON-NLS-1$ miMenuItemLeftRightArrange.addActionListener(this); mnuArrange.add(miMenuItemLeftRightArrange); mnuArrange.addSeparator(); miMenuItemTopDownArrange = new JMenuItem(LanguageProperties.getString(LanguageProperties.POPUPS_BUNDLE, "UIBaseMapPopupMenu.topDown")); //$NON-NLS-1$ miMenuItemTopDownArrange.addActionListener(this); mnuArrange.add(miMenuItemTopDownArrange); add(mnuArrange); } /** * Create the view align submenu and items */ protected void createViewAlignMenu() { mnuViewAlign = new JMenu(LanguageProperties.getString(LanguageProperties.POPUPS_BUNDLE, "UIBaseMapPopupMenu.align")); //$NON-NLS-1$ mnuViewAlign.setEnabled(true); miMenuItemAlignLeft = new JMenuItem(LanguageProperties.getString(LanguageProperties.POPUPS_BUNDLE, "UIBaseMapPopupMenu.left")); //$NON-NLS-1$ miMenuItemAlignLeft.addActionListener(this); mnuViewAlign.add(miMenuItemAlignLeft); miMenuItemAlignCenter = new JMenuItem(LanguageProperties.getString(LanguageProperties.POPUPS_BUNDLE, "UIBaseMapPopupMenu.center")); //$NON-NLS-1$ miMenuItemAlignCenter.addActionListener(this); mnuViewAlign.add(miMenuItemAlignCenter); miMenuItemAlignRight = new JMenuItem(LanguageProperties.getString(LanguageProperties.POPUPS_BUNDLE, "UIBaseMapPopupMenu.right")); //$NON-NLS-1$ miMenuItemAlignRight.addActionListener(this); mnuViewAlign.add(miMenuItemAlignRight); mnuViewAlign.addSeparator(); miMenuItemAlignTop = new JMenuItem(LanguageProperties.getString(LanguageProperties.POPUPS_BUNDLE, "UIBaseMapPopupMenu.top")); //$NON-NLS-1$ miMenuItemAlignTop.addActionListener(this); mnuViewAlign.add(miMenuItemAlignTop); miMenuItemAlignMiddle = new JMenuItem(LanguageProperties.getString(LanguageProperties.POPUPS_BUNDLE, "UIBaseMapPopupMenu.middle")); //$NON-NLS-1$ miMenuItemAlignMiddle.addActionListener(this); mnuViewAlign.add(miMenuItemAlignMiddle); miMenuItemAlignBottom = new JMenuItem(LanguageProperties.getString(LanguageProperties.POPUPS_BUNDLE, "UIBaseMapPopupMenu.bottom")); //$NON-NLS-1$ miMenuItemAlignBottom.addActionListener(this); mnuViewAlign.add(miMenuItemAlignBottom); add(mnuViewAlign); } /** * Set the UIViewPane associated with this popup menu. * @param viewPane com.compendium.ui.UIViewPane, the UIViewPane associated with this popup menu. */ public void setViewPane(UIViewPane viewPane) { oViewPane = viewPane; } /** * Set the associated ViewPaneUI. * @param viewpaneUI com.compendium.ui.plaf.ViewPaneUI, the associated map for this popup menu. */ public void setViewPaneUI(ViewPaneUI viewpaneUI) { oViewPaneUI = viewpaneUI; oViewPane = oViewPaneUI.getViewPane(); } /** * Handles the event of an option being selected. * @param evt, the event associated with the option being selected. */ public void actionPerformed(ActionEvent evt) { ProjectCompendium.APP.setWaitCursor(); Object source = evt.getSource(); if(source.equals(miMenuItemTopDownArrange)) { ProjectCompendium.APP.onViewArrange(IUIArrange.TOPDOWN); } else if(source.equals(miMenuItemLeftRightArrange)) { ProjectCompendium.APP.onViewArrange(IUIArrange.LEFTRIGHT); } else if(source.equals(miMenuItemAlignTop)) ProjectCompendium.APP.onViewAlign(UIAlign.TOP); else if(source.equals(miMenuItemAlignCenter)) ProjectCompendium.APP.onViewAlign(UIAlign.CENTER); else if(source.equals(miMenuItemAlignBottom)) ProjectCompendium.APP.onViewAlign(UIAlign.BOTTOM); else if(source.equals(miMenuItemAlignRight)) ProjectCompendium.APP.onViewAlign(UIAlign.RIGHT); else if(source.equals(miMenuItemAlignMiddle)) ProjectCompendium.APP.onViewAlign(UIAlign.MIDDLE); else if(source.equals(miMenuItemAlignLeft)) ProjectCompendium.APP.onViewAlign(UIAlign.LEFT); else if (source.equals(miImportImageFolder)) { importImageFolder(); } else if(source.equals(miMenuItemDelink)) { delinkNodes(); } else if (source.equals(miSaveAsJpeg)) { ProjectCompendium.APP.onSaveAsJpeg(); } else { super.actionPerformed(evt); } ProjectCompendium.APP.setDefaultCursor(); } /** * Change the type of the selected nodes to the given stencil item * Subclasses should implement this method. */ protected void changeStencilType(DraggableStencilIcon item) { String sImage = item.getImage(); String sBackgroundImage = item.getBackgroundImage(); String sTemplate = item.getTemplate(); String sLabel = item.getLabel(); int nType = item.getNodeType(); Vector vtTags = item.getTags(); String sAuthor= oViewPane.getCurrentAuthor(); for(Enumeration e = oViewPane.getSelectedNodes();e.hasMoreElements();) { UINode uinode = (UINode)e.nextElement(); boolean changeType = false; if (uinode.getType() != nType) { if (uinode.setType(item.getNodeType())) { changeType = true; } } else { changeType = true; } if (changeType) { // ADD LABEL IF NODE HAS NO LABEL if (uinode.getText().equals("")) { uinode.setText(sLabel); } // ADD REFERENCE IMAGE uinode.setReferenceIcon(sImage); try { uinode.getNode().setSource(uinode.getNode().getSource(), sImage, sAuthor); //$NON-NLS-1$ } catch(Exception ex) { log.info("error in UIViewPane.createNodeFromStencil) \n\n"+ex.getMessage()); //$NON-NLS-1$ } // ADD THE TAGS IModel oModel = ProjectCompendium.APP.getModel(); PCSession oSession = oModel.getSession(); NodeSummary nodeSum = uinode.getNode(); int count = vtTags.size(); for(int i=0; i<count;i++) { Vector data = (Vector)vtTags.elementAt(i); String sID = (String)data.elementAt(0); String sName = (String)data.elementAt(1); String sTheAuthor = (String)data.elementAt(2); String sDescription = (String)data.elementAt(3); String sBehavior = (String)data.elementAt(4); Date dCreated = (Date)data.elementAt(5); Date dLastModified = (Date)data.elementAt(6); Code codeObj = null; try { // CHECK IF ALREADY IN DATABASE Vector existingCodesForName = (oModel.getCodeService()).getCodeIDs(oSession, sName); if (existingCodesForName.size() == 0) { codeObj = oModel.getCodeService().createCode(oSession, sID, sTheAuthor, dCreated, dLastModified, sName, sDescription, sBehavior); oModel.addCode(codeObj); } else { String existingCodeID = (String)existingCodesForName.elementAt(0); codeObj = oModel.getCodeService().getCode(oSession, existingCodeID); } nodeSum.addCode(codeObj); } catch(Exception ex) { log.info("Unable to add tag = "+codeObj.getName()+"\n\ndue to:\n\n"+ex.getMessage()); } //$NON-NLS-1$ //$NON-NLS-2$ } // ADD BACKGROUND IMAGE AND TEMPLATE IF REQUIRED if (uinode.getNode() instanceof View) { View view = (View)uinode.getNode(); if (sBackgroundImage != null && !sBackgroundImage.equals("")) { //$NON-NLS-1$ try { view.setBackgroundImage(sBackgroundImage); view.updateViewLayer(); } catch(Exception ex) { log.info("error in UIViewPane.createNodeFromStencil) \n\n"+ex.getMessage()); //$NON-NLS-1$ } } if (sTemplate != null && !sTemplate.equals("")) { //$NON-NLS-1$ UIMapViewFrame mapFrame = null; try { view.initializeMembers(); mapFrame = new UIMapViewFrame(view, view.getLabel()); } catch(Exception ex) { log.error("Error...", ex); } if (mapFrame != null) { ProjectCompendium.APP.onTemplateImport(sTemplate, mapFrame.getViewPane()); } } } uinode.getUI().refreshBounds(); oViewPane.setSelectedNode(uinode,ICoreConstants.MULTISELECT); uinode.requestFocus(); } } } /** * Change the type of all selected nodes to the given type. * @param type the new type to set the selected nodes to. */ protected void changeType(int nType) { for(Enumeration e = oViewPane.getSelectedNodes();e.hasMoreElements();) { UINode uinode = (UINode)e.nextElement(); if (uinode.setType(nType)) { oViewPane.setSelectedNode(uinode,ICoreConstants.MULTISELECT); uinode.requestFocus(); } } } /** * Process a node creation request. * @param nType, the type of the new node to create. */ protected void createNode(int nType) { // MOVE THE MOUSE POINTER TO THE CORRECT POSITION try { Point pos = new Point(nX, nY); SwingUtilities.convertPointToScreen(pos, oViewPane); Robot rob = new Robot(); rob.mouseMove(pos.x, pos.y); } catch(AWTException ex) {} // MOVE X AN Y FOR NODE OUT A BIT SO MOUSEPOINTER NOT RIGHT ON EDGE nX -= 20; nY -= 20; oViewPaneUI.addNewNode(nType, nX, nY); } /** * Import an image folder. */ protected void importImageFolder() { ProjectCompendium.APP.onFileImportImageFolder(oViewPane.getViewFrame()); } /** * Move the first page of details of the currently selected nodes into their respective labels. */ protected void moveDetailToLabel() { for(Enumeration e = oViewPane.getSelectedNodes();e.hasMoreElements();) { UINode uinode = (UINode)e.nextElement(); uinode.onMoveDetails(); } ProjectCompendium.APP.setStatus(""); //$NON-NLS-1$ oViewPane.getUI().redraw(); } /** * Move the labels of the currently selected nodes into their respective details pages. */ protected void moveLabelToDetail() { for(Enumeration e = oViewPane.getSelectedNodes();e.hasMoreElements();) { UINode uinode = (UINode)e.nextElement(); uinode.onMoveLabel(); } ProjectCompendium.APP.setStatus(""); //$NON-NLS-1$ oViewPane.getUI().redraw(); } /** * Handle a Questmap import request. * @param showViewList, true if importing to mulitpl views, else false. */ protected void onImportFile(boolean showViewList) { UIImportDialog uid = new UIImportDialog(ProjectCompendium.APP, showViewList); uid.setViewPaneUI(oViewPaneUI); uid.setVisible(true); } /** * Exports the current view to a HTML outline file. */ protected void onExportFile() { UIExportDialog export = new UIExportDialog(ProjectCompendium.APP, oViewPane.getViewFrame()); export.setVisible(true); } /** * Exports the current view to a HTML Views file. */ protected void onExportView() { UIExportViewDialog dialog2 = new UIExportViewDialog(ProjectCompendium.APP, oViewPane.getViewFrame()); UIUtilities.centerComponent(dialog2, ProjectCompendium.APP); dialog2.setVisible(true); } /** * Mark the currently selected Nodes as seen. */ protected void markSeen() { try { Enumeration e = oViewPane.getSelectedNodes(); for(;e.hasMoreElements();){ UINode node = (UINode) e.nextElement(); NodeSummary oNode = node.getNode(); oNode.setState(ICoreConstants.READSTATE); } } catch(Exception io) { log.info(LanguageProperties.getString(LanguageProperties.POPUPS_BUNDLE, "UIBasePopupMenu.unableMarkRead")); //$NON-NLS-1$ } } /** * Mark the currently selected nodes as unseen. */ protected void markUnseen() { try { Enumeration e = oViewPane.getSelectedNodes(); for(;e.hasMoreElements();){ UINode node = (UINode) e.nextElement(); NodeSummary oNode = node.getNode(); oNode.setState(ICoreConstants.UNREADSTATE); } } catch(Exception io) { log.info(LanguageProperties.getString(LanguageProperties.POPUPS_BUNDLE, "UIBasePopupMenu.unableMarkUnread")); //$NON-NLS-1$ } } /** * delink the currently selected nodes. */ protected void delinkNodes() { for(Enumeration e = oViewPane.getSelectedNodes();e.hasMoreElements();) { UINode uinode = (UINode)e.nextElement(); NodeUI nodeui = (uinode.getUI()); ProjectCompendium.APP.setStatus(LanguageProperties.getString(LanguageProperties.POPUPS_BUNDLE, "UINodePopupMenu.delinking") + nodeui.getUINode().getNode().getLabel()); //$NON-NLS-1$ nodeui.delink(); } ProjectCompendium.APP.setStatus(""); //$NON-NLS-1$ } /** * Create Shortcuts for the selected nodes. */ protected void shortcutNodes() { int nOffset = 55; Vector uinodes = new Vector(50); for(Enumeration e = oViewPane.getSelectedNodes();e.hasMoreElements();) { UINode uinode = (UINode)e.nextElement(); if( !(uinode.getNode() instanceof ShortCutNodeSummary) ) { NodeUI nodeui = (uinode.getUI()); ProjectCompendium.APP.setStatus(LanguageProperties.getString(LanguageProperties.POPUPS_BUNDLE, "UIBasePopupMenu.makingShortcut") + nodeui.getUINode().getNode().getLabel()); //$NON-NLS-1$ int x = uinode.getX(); int y = uinode.getY(); UINode tmpuinode = oViewPaneUI.createShortCutNode(uinode, x+nOffset, y+nOffset); uinodes.addElement(tmpuinode); } } oViewPane.setSelectedNode(null, ICoreConstants.DESELECTALL); oViewPane.setSelectedLink(null, ICoreConstants.DESELECTALL); for(int i=0;i<uinodes.size();i++) { UINode uinode = (UINode)uinodes.elementAt(i); uinode.requestFocus(); uinode.setSelected(true); oViewPane.setSelectedNode(uinode,ICoreConstants.MULTISELECT); } ProjectCompendium.APP.setStatus(""); //$NON-NLS-1$ oViewPane.getUI().redraw(); } /** * Clone the currently selected nodes. */ protected void cloneNodes() { int nOffset = 55; Hashtable cloneNodes = new Hashtable(); Vector uinodes = new Vector(50); for(Enumeration e = oViewPane.getSelectedNodes();e.hasMoreElements();) { UINode uinode = (UINode)e.nextElement(); NodeUI nodeui = (uinode.getUI()); ProjectCompendium.APP.setStatus(LanguageProperties.getString(LanguageProperties.POPUPS_BUNDLE, "UIBasePopupMenu.cloning") + nodeui.getUINode().getNode().getLabel()); //$NON-NLS-1$ int x = uinode.getX(); int y = uinode.getY(); UINode tmpuinode = oViewPaneUI.createCloneNode(uinode, x+nOffset, y+nOffset); cloneNodes.put(uinode,tmpuinode); uinodes.addElement(tmpuinode); } oViewPane.setSelectedNode(null, ICoreConstants.DESELECTALL); for(int i=0;i<uinodes.size();i++) { UINode uinode = (UINode)uinodes.elementAt(i); uinode.requestFocus(); uinode.setSelected(true); oViewPane.setSelectedNode(uinode,ICoreConstants.MULTISELECT); } ProjectCompendium.APP.setStatus(""); //$NON-NLS-1$ Vector linkList = new Vector(); for(Enumeration e = oViewPane.getSelectedLinks();e.hasMoreElements();) { UILink link = (UILink)e.nextElement(); UINode uiFrom = link.getFromNode(); UINode uiTo = link.getToNode(); if ((cloneNodes.get(uiFrom) != null) && (cloneNodes.get(uiTo) != null) ) { UILink tmpLink = (uiFrom.getUI()).createLink( (UINode)cloneNodes.get(uiFrom), (UINode)cloneNodes.get(uiTo), link.getLink().getType(), link.getLinkProperties()); linkList.addElement(tmpLink); } } oViewPane.setSelectedLink(null, ICoreConstants.DESELECTALL); for(int i=0;i<linkList.size();i++) { UILink uiLink = (UILink)linkList.elementAt(i); uiLink.setSelected(true); oViewPane.setSelectedLink(uiLink,ICoreConstants.MULTISELECT); } } /** * Delete the currently selected nodes. */ protected void delete() { DeleteEdit edit = new DeleteEdit(oViewPane.getViewFrame()); oViewPane.deleteSelectedNodesAndLinks(edit); oViewPane.getViewFrame().getUndoListener().postEdit(edit); ProjectCompendium.APP.setTrashBinIcon(); } }