Ptidej-v5.2-master/POM Tests/data/ArgoUML_0.28/src/org/argouml/uml/diagram/DiagramSettings.java
// $Id: DiagramSettings.java 16633 2009-01-16 16:48:31Z tfmorris $
// Copyright (c) 2008, 2009 The Regents of the University of California. All
// Rights Reserved. Permission to use, copy, modify, and distribute this
// software and its documentation without fee, and without a written
// agreement is hereby granted, provided that the above copyright notice
// and this paragraph appear in all copies. This software program and
// documentation are copyrighted by The Regents of the University of
// California. The software program and documentation are supplied "AS
// IS", without any accompanying services from The Regents. The Regents
// does not warrant that the operation of the program will be
// uninterrupted or error-free. The end-user understands that the program
// was developed for research purposes and is advised not to rely
// exclusively on the program for any reason. IN NO EVENT SHALL THE
// UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
// SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
// ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
// THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
// PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
// CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
// UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

package org.argouml.uml.diagram;

import java.awt.Font;

import org.argouml.notation.NotationSettings;
import org.tigris.gef.undo.Memento;

/**
 * Diagram appearance settings.  This includes basic things like colors and
 * fonts, as well as the {@link NotationSettings} which contain all the settings
 * that control text formatting.
 * <p>
 * The settings are designed to work in a hierarchical fashion with any settings
 * that are defaulted at the current level inheriting from the next level in
 * the hierarchy.  A typical hierarchy would be Fig->StyleSheet->Project where 
 * a style sheet is a named set of attributes that can be applied as a set to
 * a fig (perhaps in conjunction with a stereotype).  The hierarchy which is
 * currently used in ArgoUML is Fig->Diagram->Project, although there's no
 * support for changing anything but the Project (and a few of the attributes
 * managed directly by GEF).
 * 
 * @author Tom Morris <tfmorris@gmail.com>
 */
public class DiagramSettings {

    /*
     * The special value <code>null</code> is used internally to indicate that
     * the default value should be inherited from the next level of settings.
     */
    
    /**
     * Enumeration representing different stereotype presentation styles
     */
    public enum StereotypeStyle {
        
        // *IMPORTANT* - These MUST remain in order!
        
        /**
         * Textual rendering for stereotype
         */
        TEXTUAL(DiagramAppearance.STEREOTYPE_VIEW_TEXTUAL), 
        /**
         * Stereotype rendered with large icon
         */
        BIG_ICON(DiagramAppearance.STEREOTYPE_VIEW_BIG_ICON), 
        /**
         * Stereotype rendered with small icon
         */
        SMALL_ICON(DiagramAppearance.STEREOTYPE_VIEW_SMALL_ICON);
       
        StereotypeStyle(int value) {
            assert value == this.ordinal();
        }
        

        /**
         * Convert old style int representation to an enum.  The enum returned
         * is the one at the given ordinal (ie this is the inverse of the
         * mapping done by ordinal()).
         * 
         * @param value one of the defined int values in DiagramAppearance
         * @return the corresponding StereotypeView enum
         */
        public static StereotypeStyle getEnum(int value) {
            int counter = 0;
            for (StereotypeStyle sv : StereotypeStyle.values()) {
                if (counter == value) {
                    return sv;
                }
                counter++;
            }
            return null;
        }
    }
    
//    private static final StereotypeView[] stereotypeViewMap;
//    
//    static {
//        stereotypeViewMap = new StereotypeView[3];
//        StereotypeView.
//        stereotypeViewMap[DiagramAppearance.STEREOTYPE_VIEW_TEXTUAL] = 
//            StereotypeView.TEXTUAL;
//        stereotypeViewMap[DiagramAppearance.STEREOTYPE_VIEW_BIG_ICON] = 
//            StereotypeView.BIG_ICON;
//        stereotypeViewMap[DiagramAppearance.STEREOTYPE_VIEW_SMALL_ICON] = 
//            StereotypeView.SMALL_ICON;
//    }
    
    /**
     * Next level in the settings hierarchy to inherit from if the value
     * isn't set (ie is <default>) at the current level.
     */
    private DiagramSettings parent;
    
    private NotationSettings notationSettings;

    /* Diagram appearance settings with project scope: */
    private String fontName;
    private Integer fontSize;
    
    // TODO: Can we remove this and have the application manage things directly
    // based on the font?
    private Boolean showBoldNames;
    
    /* Some cached fonts based on the above settings */
    private Font fontPlain;
    private Font fontItalic;
    private Font fontBold;
    private Font fontBoldItalic;
    
    private Boolean showBidirectionalArrows;
    
    private Integer defaultShadowWidth;
    
    private StereotypeStyle defaultStereotypeView;


    /**
     * Construct an empty project settings with no parent and all values
     * defaulted. <p>
     */
    public DiagramSettings() {
        this(null);
    }
    
    
    /**
     * Construct a DiagramSettings object which inherits from the given
     * parent settings (e.g. project default diagram settings).
     * 
     * @param parentSettings settings to inherit from if default values aren't
     * overridden.
     */
    public DiagramSettings(DiagramSettings parentSettings) {
        super();
        parent = parentSettings;
        if (parentSettings == null) {
            notationSettings = new NotationSettings();
        } else {
            notationSettings = 
                new NotationSettings(parent.getNotationSettings());
        }
        recomputeFonts();
    }

    
    /**
     * @return Returns the notationSettings.
     */
    public NotationSettings getNotationSettings() {
        return notationSettings;
    }


    /**
     * @param notationSettings The notationSettings to set.
     */
    public void setNotationSettings(NotationSettings notationSettings) {
        this.notationSettings = notationSettings;
    }


    /**
     * @return Returns <code>true</code> if we show bold names.
     */
    public boolean isShowBoldNames() {
        if (showBoldNames == null) {
            if (parent != null) {
                return parent.isShowBoldNames();
            } else {
                return false;
            }
        }
        return showBoldNames;
    }

    /**
     * @param showem <code>true</code> if names are to be shown in bold font.
     */
    public void setShowBoldNames(final boolean showem) {
        if (showBoldNames != null && showBoldNames == showem) {
            return;
        }

        Memento memento = new Memento() {
            public void redo() {
                showBoldNames = showem;
            }

            public void undo() {
                showBoldNames = !showem;
            }
        };
        doUndoable(memento);
    }

   
    /**
     * @return Returns <code>true</code> if we show the arrows when
     * both association ends of an association are navigable.
     */
    public boolean isShowBidirectionalArrows() {
        if (showBidirectionalArrows == null) {
            if (parent != null) {
                return parent.isShowBidirectionalArrows();
            } else {
                return false;
            }
        }
        return showBidirectionalArrows;
    }

    /**
     * @param showem <code>true</code> if both arrows are to be shown when
     * both association ends of an association are navigable.
     */
    public void setShowBidirectionalArrows(final boolean showem) {
        if (showBidirectionalArrows != null 
                && showBidirectionalArrows == showem) {
            return;
        }

        Memento memento = new Memento() {
            public void redo() {
                showBidirectionalArrows = showem;
            }

            public void undo() {
                showBidirectionalArrows = !showem;
            }
        };
        doUndoable(memento);

    }


    /**
     * @return Returns the shadow width.
     */
    public int getDefaultShadowWidth() {
        if (defaultShadowWidth == null) {
            if (parent != null) {
                return parent.getDefaultShadowWidth();
            } else {
                return 0;
            }
        }
        return defaultShadowWidth;
    }

    /**
     * @param newWidth The Shadow Width.
     */
    public void setDefaultShadowWidth(final int newWidth) {
        if (defaultShadowWidth != null && defaultShadowWidth == newWidth) {
            return;
        }

        final Integer oldValue = defaultShadowWidth;

        Memento memento = new Memento() {
            public void redo() {
                defaultShadowWidth = newWidth;
            }

            public void undo() {
                defaultShadowWidth = oldValue;
            }
        };
        doUndoable(memento);

    }


    /**
     * @return Returns the default stereotype view
     * TODO: Enumeration here?
     */
    public StereotypeStyle getDefaultStereotypeView() {
        if (defaultStereotypeView == null) {
            if (parent != null) {
                return parent.getDefaultStereotypeView();
            } else {
                return StereotypeStyle.TEXTUAL;
            }
        }
        return defaultStereotypeView;
    }

    /**
     * @return Returns the default stereotype view as an int compatible with
     * old users of DiagramAppearance-defined ints.
     * @deprecated for 0.27.2 by tfmorris.  For backward compatibility only.
     */
    public int getDefaultStereotypeViewInt() {
        return getDefaultStereotypeView().ordinal();
    }
    
    /**
     * @param newView the default stereotype view
     * @deprecated for 0.27.2 by tfmorris. Not for use in new code. Only for
     *             help in transitioning to enum based methods. Use
     *             {@link #setDefaultStereotypeView(StereotypeStyle)}.
     */
    public void setDefaultStereotypeView(final int newView) {
        StereotypeStyle sv = StereotypeStyle.getEnum(newView);
        if (sv == null) {
            throw new IllegalArgumentException("Bad argument " + newView);
        }
        setDefaultStereotypeView(sv);
    }

    /**
     * @param newView the default stereotype view
     */
    public void setDefaultStereotypeView(final StereotypeStyle newView) {
        if (defaultStereotypeView != null && defaultStereotypeView == newView) {
            return;
        }

        final StereotypeStyle oldValue = defaultStereotypeView;

        Memento memento = new Memento() {
            public void redo() {
                defaultStereotypeView = newView;
            }

            public void undo() {
                defaultStereotypeView = oldValue;
            }
        };
        doUndoable(memento);
    }


    /**
     * Diagram font name. <p>
     * 
     * @return diagram font name.
     */
    public String getFontName() {
        if (fontName == null) {
            if (parent != null) {
                return parent.getFontName();
            } else {
                return "Dialog";
            }
        }
        return fontName;
    }

    /**
     * Diagram font name.
     * @param newFontName diagram font name.
     */
    public void setFontName(String newFontName) {
        if (fontName != null && fontName.equals(newFontName)) {
            return;
        }
        fontName = newFontName;
        recomputeFonts();
    }

    /**
     * Diagram font size. <p>
     *
     * @return diagram font size.
     */
    public int getFontSize() {
        if (fontSize == null) {
            if (parent != null) {
                return parent.getFontSize();
            } else {
                return 10;
            }
        }
        return fontSize;
    }

    /**
     * Diagram font size.
     * @param newFontSize diagram font size.
     */
    public void setFontSize(int newFontSize) {
        if (fontSize != null && fontSize == newFontSize) {
            return;
        }
        fontSize = newFontSize;
        recomputeFonts();
    }

    private void recomputeFonts() {
        // If we've got a local (uninherited) font name or size or if we've got
        // no parent to inherit from recompute our cached fonts
        if ((fontName != null && !"".equals(fontName) && fontSize != null)
                || parent == null) {
            String name = getFontName();
            int size = getFontSize();
            fontPlain = new Font(name, Font.PLAIN, size);
            fontItalic = new Font(name, Font.ITALIC, size);
            fontBold = new Font(name, Font.BOLD, size);
            fontBoldItalic = new Font(name, Font.BOLD | Font.ITALIC, size);
        } else {
            fontPlain = null;
            fontItalic = null;
            fontBold = null;
            fontBoldItalic = null;
        }
    }

    /**
     * Returns the Plain diagram font which corresponds
     * to selected parameters.
     *
     * @return plain diagram font
     */
    public Font getFontPlain() {
        if (fontPlain == null) {
            return parent.getFontPlain();
        }
        return fontPlain;
    }

    /**
     * Returns the Italic diagram font which corresponds
     * to selected parameters.
     *
     * @return italic diagram font
     */
    public Font getFontItalic() {
        if (fontItalic == null) {
            return parent.getFontItalic();
        }
        return fontItalic;
    }

    /**
     * Returns the Bold diagram font which corresponds
     * to selected parameters.
     *
     * @return bold diagram font
     */
    public Font getFontBold() {
        if (fontBold == null) {
            return parent.getFontBold();
        }
        return fontBold;
    }

    /**
     * Returns the Bold-Italic diagram font which corresponds
     * to selected parameters.
     *
     * @return bold-italic diagram font
     */
    public Font getFontBoldItalic() {
        if (fontBoldItalic == null) {
            return parent.getFontBoldItalic();
        }
        return fontBoldItalic;
    }

    /**
     * Utility function to convert a font style integer into a Font.
     *
     * @param fontStyle the style; see the predefined constants in Font
     * @return the Font that corresponds to the style
     */
    public Font getFont(int fontStyle) {
        if ((fontStyle & Font.ITALIC) != 0) {
            if ((fontStyle & Font.BOLD) != 0) {
                return getFontBoldItalic();
            } else {
                return getFontItalic();
            }
        } else {
            if ((fontStyle & Font.BOLD) != 0) {
                return getFontBold();
            } else {
                return getFontPlain();
            }
        }
    }
    

    private void doUndoable(Memento memento) {
        // TODO: Undo should be managed externally or we should be given 
        // an Undo manager to use (the project's) rather than using a global one
//        if (DiagramUndoManager.getInstance().isGenerateMementos()) {
//            DiagramUndoManager.getInstance().addMemento(memento);
//        }
        memento.redo();
        // TODO: Mark diagram/project as dirty?
    }
}

