/******************************************************************************** * * * (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; import java.awt.Point; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.compendium.LanguageProperties; import com.compendium.ProjectCompendium; import com.compendium.core.datamodel.IModel; import com.compendium.core.datamodel.NodePosition; import com.compendium.core.datamodel.PCSession; import com.compendium.core.datamodel.View; import com.compendium.core.datamodel.services.IViewService; /** * UIAlign defines code to align the selected nodes of a map. * @author Lakshmi Prabhakaran * */ public class UIAlign { /** * class's own logger */ final Logger log = LoggerFactory.getLogger(getClass()); /** The value for the Top Align option.*/ public static final String TOP = "top"; //$NON-NLS-1$ /** The value for the Center Align option.*/ public static final String CENTER = "center"; //$NON-NLS-1$ /** The value for the Bottom Align option.*/ public static final String BOTTOM = "bottom"; //$NON-NLS-1$ /** The value for the Left Align option.*/ public static final String LEFT = "left"; //$NON-NLS-1$ /** The value for the Middle Align option.*/ public static final String MIDDLE = "middle"; //$NON-NLS-1$ /** The value for the Right Align option.*/ public static final String RIGHT = "right"; //$NON-NLS-1$ /** The view service for accessing the databse.*/ private IViewService vs = null; /** The session object for the current user with the current database.*/ private PCSession session = null; /** Used for undo operations.*/ private Hashtable nodePositionsCloneHashtable = new Hashtable(); /** Used for redo operations.*/ private Hashtable nodePositionsCloneHashtableForRedo = new Hashtable(); /** The selected align option.*/ private String alignOption = null; /** The selected nodes to perform align.*/ private Vector vtSelectedNodes = new Vector(); /** * Constructor. * @param option */ public UIAlign(String option){ this.alignOption = option; } /** * performs aligning * @param viewFrame com.compenduim.ui.UIViewFrame, the frame of the map view to align. */ public void alignNodes(UIViewFrame viewFrame){ View view = viewFrame.getView(); UIViewPane uiViewPane = ((UIMapViewFrame)viewFrame).getViewPane(); if(uiViewPane.getNumberOfSelectedNodes() > 1){ for (Enumeration e = uiViewPane.getSelectedNodes(); e.hasMoreElements() ;) { UINode node = (UINode) e.nextElement(); if(node != null) vtSelectedNodes.add(node); }//end for Vector vtTemp = processNodes(view); for(int i = vtTemp.size()-1; i >= 0; i--) { String nodeId = ((NodePosition)vtTemp.elementAt(i)).getNode().getId(); UINode uinode = ((UINode) ((UIMapViewFrame)viewFrame).getViewPane().get(nodeId)); if(uinode != null) { // ALLOW FOR FACT VIEW MIGHT BE SCALED int width = uinode.getWidth(); if (uiViewPane != null) { Point p = UIUtilities.scalePoint(width, width, uiViewPane.getScale()); width = p.x; } Point p = uinode.getNodePosition().getPos(); if (uiViewPane != null) { Point loc = UIUtilities.transformPoint(p.x, p.y, uiViewPane.getScale()); uinode.setBounds(loc.x, loc.y, uinode.getWidth(), uinode.getHeight()); } uinode.updateLinks(); try { view.setNodePosition(nodeId, p); } catch(Exception ex) { log.error("Error...", ex); log.info("Error: (UIAlign.alignNodes) \n\n"+ex.getMessage()); //$NON-NLS-1$ } }//end if }//end for if (uiViewPane != null) uiViewPane.repaint(); vtTemp.clear(); try { vtTemp = vs.getNodePositions(session, view.getId()); } catch(Exception ex) { ProjectCompendium.APP.displayError(LanguageProperties.getString(LanguageProperties.UI_GENERAL_BUNDLE, "UIAlign.cannotGetNodes") + view.getLabel()+". " + ex.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$ }//end catch nodePositionsCloneHashtableForRedo.clear(); for ( int i = 0; i < vtTemp.size(); i++) { nodePositionsCloneHashtableForRedo.put( ((NodePosition)vtTemp.elementAt(i)).getNode().getId(), ((NodePosition)vtTemp.elementAt(i)).getClone()); }//end for }//end if }//alignNodes /** * process the nodes to align. * @param view com.compendium.core.datamodel.View, the view to align. */ private Vector processNodes(View view){ Vector vtTemp = new Vector(); IModel model = ProjectCompendium.APP.getModel(); session = model.getSession(); vs = model.getViewService(); try { vtTemp = vs.getNodePositions(session, view.getId()); } catch(Exception ex) { ProjectCompendium.APP.displayError(LanguageProperties.getString(LanguageProperties.UI_GENERAL_BUNDLE, "UIAlign.cannotGetNodes") + view.getLabel()+"." + ex.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$ } nodePositionsCloneHashtable.clear(); for ( int i = 0; i < vtTemp.size(); i++) { nodePositionsCloneHashtable.put( ((NodePosition)vtTemp.elementAt(i)).getNode().getId(), ((NodePosition)vtTemp.elementAt(i)).getClone()); } if(alignOption.equals(TOP)){ alignTop(); }else if (alignOption.equals(MIDDLE)){ alignMiddle(); }else if (alignOption.equals(BOTTOM)){ alignBottom(); }else if (alignOption.equals(LEFT)){ alignLeft(); } else if (alignOption.equals(CENTER)){ alignCenter(); }else if (alignOption.equals(RIGHT)){ alignRight(); }//end else return vtTemp; }//processNodes /** * To perform right align */ private void alignRight() { double rightXPos = 0.0; for(int i = 0; i < vtSelectedNodes.size() ; i++){ UINode uiNode = (UINode) vtSelectedNodes.get(i); double scale = uiNode.getScale(); double xPos = uiNode.getNodePosition().getXPos(); if (i == 0 || rightXPos < (xPos + (uiNode.getWidth()/ scale))){ rightXPos = xPos + (uiNode.getWidth()/ scale); }//end if }//end for for(int i = 0; i < vtSelectedNodes.size() ; i++){ UINode node = (UINode) vtSelectedNodes.get(i); double scale = node.getScale(); Point p = node.getNodePosition().getPos(); Point pt = new Point (); pt.setLocation(rightXPos - (node.getWidth()/ scale), (double)p.y); node.getNodePosition().setPos(pt); node.setLocation(pt); }//end for }//alignRight /** * To perform center align */ private void alignCenter() { double sXPos = 0; double lXPos = 0; double center = 0; for(int i = 0; i < vtSelectedNodes.size() ; i++){ UINode uiNode = (UINode) vtSelectedNodes.get(i); double scale = uiNode.getScale(); Point p = uiNode.getNodePosition().getPos(); double xPos = uiNode.getNodePosition().getXPos(); double width = (uiNode.getWidth()/ scale); if(i == 0 || sXPos > xPos){ sXPos = xPos; }//end if if(i == 0 || lXPos < (xPos +width) ) { lXPos = xPos + width; } }//end for center = (sXPos + lXPos) /2 ; //To check if it is already centered boolean isCenter = true; for(int i = 0; i < vtSelectedNodes.size() ; i++){ UINode node = (UINode) vtSelectedNodes.get(i); double scale = node.getScale(); Point p = node.getNodePosition().getPos(); double width = (node.getWidth()/ scale); if((node.getLocation().getX() + ( width / 2)) != center) { isCenter = false; }//end if }//end for if(!isCenter){ // To put the nodes at the center for(int i = 0; i < vtSelectedNodes.size() ; i++){ UINode node = (UINode) vtSelectedNodes.get(i); double scale = node.getScale(); double width = (node.getWidth()/ scale) ; Point p = node.getNodePosition().getPos(); Point pt = new Point(); pt.setLocation(center - ( width /2) ,p.y); node.getNodePosition().setPos(pt); node.setLocation(pt); }//end for }//end if }//alignCenter /** * To perform left align */ private void alignLeft() { double leftXPos = 0; for(int i = 0; i < vtSelectedNodes.size() ; i++){ UINode uiNode = (UINode) vtSelectedNodes.get(i); double scale = uiNode.getScale(); double xPos = uiNode.getNodePosition().getXPos(); if (i == 0 || leftXPos > xPos){ leftXPos = xPos; }//end if }//end for for(int i = 0; i < vtSelectedNodes.size() ; i++){ UINode node = (UINode) vtSelectedNodes.get(i); double scale = node.getScale(); Point p = node.getNodePosition().getPos(); Point pt = new Point(); pt.setLocation(leftXPos ,p.y); node.getNodePosition().setPos(pt); node.setLocation(pt); }//end for }//alignLeft /** * To perform bottom align */ private void alignBottom() { double bottomYPos = -1; for(int i = 0; i < vtSelectedNodes.size() ; i++){ UINode uiNode = (UINode) vtSelectedNodes.get(i); double scale = uiNode.getScale(); double yPos = uiNode.getNodePosition().getYPos(); double height = (int)(uiNode.getHeight()/scale) ; if (i == 0 || bottomYPos < (yPos + height)){ bottomYPos = yPos + height; }//end if }//end for for(int i = 0; i < vtSelectedNodes.size() ; i++){ UINode node = (UINode) vtSelectedNodes.get(i); double scale = node.getScale(); Point p = node.getNodePosition().getPos(); double height = (node.getHeight()/scale) ; Point pt = new Point(); pt.setLocation(p.x , bottomYPos - height); node.getNodePosition().setPos(pt); node.setLocation(pt); }//end for }//alignBottom /** * To perform middle align */ private void alignMiddle() { double sYPos = 0; double lYPos = 0; double middle = 0; for(int i = 0; i < vtSelectedNodes.size() ; i++){ UINode uiNode = (UINode) vtSelectedNodes.get(i); double scale = uiNode.getScale(); double yPos = uiNode.getNodePosition().getYPos(); double height = (uiNode.getHeight()/scale); if(i == 0 || sYPos > yPos){ sYPos = yPos; }//end if if(i == 0 || lYPos < (yPos + height) ) { lYPos = yPos + height; } }//end for middle = (lYPos + sYPos)/2 ; //To check if it is already in the middle boolean isMiddle = true; for(int i = 0; i < vtSelectedNodes.size() ; i++){ UINode node = (UINode) vtSelectedNodes.get(i); double scale = node.getScale(); double height = (node.getHeight()/scale) ; Point p = node.getNodePosition().getPos(); if((p.x + (height / 2))!= middle) { isMiddle = false; }//end if }//end for if(!isMiddle){ // To put the nodes at the center for(int i = 0; i < vtSelectedNodes.size() ; i++){ UINode node = (UINode) vtSelectedNodes.get(i); double scale = node.getScale(); double height = node.getHeight()/scale ; Point p = node.getNodePosition().getPos(); Point pt = new Point(); pt.setLocation(p.x,(middle - (height/2))); node.getNodePosition().setPos(pt); node.setLocation(pt); }//end for }//end if }//alignMiddle /** * To perform Top align */ private void alignTop(){ double topYPos = -1; for(int i = 0; i < vtSelectedNodes.size() ; i++){ UINode uiNode = (UINode) vtSelectedNodes.get(i); double scale = uiNode.getScale(); double yPos = uiNode.getNodePosition().getYPos(); if (i == 0 || topYPos > yPos){ topYPos = yPos; }//end if }//end for for(int i = 0; i < vtSelectedNodes.size() ; i++){ UINode node = (UINode) vtSelectedNodes.get(i); double scale = node.getScale(); Point p = node.getNodePosition().getPos(); Point pt = new Point(); pt.setLocation(p.x , topYPos); node.getNodePosition().setPos(pt); node.setLocation(pt); }//end for }//align Top // ******** UNDO / REDO **************// /** * Undo the last align for the given frame * @param viewFrame com.compendium.ui.UIViewFrame, the frame to undo the align for. */ public void undoAlign(UIViewFrame viewFrame) { UIViewPane pane = ((UIMapViewFrame)viewFrame).getViewPane(); for(Enumeration e = nodePositionsCloneHashtable.keys(); e.hasMoreElements();) { String nodeID = (String)e.nextElement(); UINode uinode = (UINode)pane.get(nodeID); NodePosition np = (NodePosition)nodePositionsCloneHashtable.get(nodeID); Point loc = UIUtilities.transformPoint(np.getXPos(), np.getYPos(), pane.getScale()); uinode.setBounds(loc.x, loc.y, uinode.getWidth(), uinode.getHeight()); uinode.updateLinks(); try { viewFrame.getView().setNodePosition(nodeID, np.getPos()); } catch(Exception ex) { log.info("Error: (UIAlign.undoAlign) \n\n"+ex.getMessage()); //$NON-NLS-1$ } } pane.repaint(); }//undoAlign /** * Redo the last align for the given frame * @param viewFrame com.compendium.ui.UIViewFrame, the frame to undo the align for. */ public void redoAlign(UIViewFrame viewFrame) { UIViewPane pane = ((UIMapViewFrame)viewFrame).getViewPane(); for(Enumeration e = nodePositionsCloneHashtableForRedo.keys(); e.hasMoreElements();) { String nodeID = (String)e.nextElement(); UINode uinode = (UINode)pane.get(nodeID); NodePosition np = (NodePosition)nodePositionsCloneHashtableForRedo.get(nodeID); Point loc = UIUtilities.transformPoint(np.getXPos(), np.getYPos(), pane.getScale()); uinode.setBounds(loc.x, loc.y, uinode.getWidth(), uinode.getHeight()); uinode.updateLinks(); try { viewFrame.getView().setNodePosition(nodeID, np.getPos()); } catch(Exception ex) { log.info("Error: (UIAlign.redoAlign) \n\n"+ex.getMessage()); //$NON-NLS-1$ } } pane.repaint(); }//redoAlign }//UIAlign