Coverage Report - org.argouml.uml.diagram.DiagramSettings
 
Classes in this File Line Coverage Branch Coverage Complexity
DiagramSettings
69%
87/125
51%
39/76
2.784
DiagramSettings$1
60%
3/5
0%
0/2
2.784
DiagramSettings$2
60%
3/5
0%
0/2
2.784
DiagramSettings$3
60%
3/5
N/A
2.784
DiagramSettings$4
60%
3/5
N/A
2.784
DiagramSettings$StereotypeStyle
84%
11/13
37%
3/8
2.784
 
 1  
 /* $Id: DiagramSettings.java 17850 2010-01-12 19:53:35Z linus $
 2  
  *****************************************************************************
 3  
  * Copyright (c) 2009 Contributors - see below
 4  
  * All rights reserved. This program and the accompanying materials
 5  
  * are made available under the terms of the Eclipse Public License v1.0
 6  
  * which accompanies this distribution, and is available at
 7  
  * http://www.eclipse.org/legal/epl-v10.html
 8  
  *
 9  
  * Contributors:
 10  
  *    mvw
 11  
  *****************************************************************************
 12  
  *
 13  
  * Some portions of this file was previously release using the BSD License:
 14  
  */
 15  
 
 16  
 // Copyright (c) 2008, 2009 The Regents of the University of California. All
 17  
 // Rights Reserved. Permission to use, copy, modify, and distribute this
 18  
 // software and its documentation without fee, and without a written
 19  
 // agreement is hereby granted, provided that the above copyright notice
 20  
 // and this paragraph appear in all copies. This software program and
 21  
 // documentation are copyrighted by The Regents of the University of
 22  
 // California. The software program and documentation are supplied "AS
 23  
 // IS", without any accompanying services from The Regents. The Regents
 24  
 // does not warrant that the operation of the program will be
 25  
 // uninterrupted or error-free. The end-user understands that the program
 26  
 // was developed for research purposes and is advised not to rely
 27  
 // exclusively on the program for any reason. IN NO EVENT SHALL THE
 28  
 // UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
 29  
 // SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
 30  
 // ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
 31  
 // THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
 32  
 // SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY
 33  
 // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 34  
 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
 35  
 // PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
 36  
 // CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
 37  
 // UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 38  
 
 39  
 package org.argouml.uml.diagram;
 40  
 
 41  
 import java.awt.Font;
 42  
 import java.beans.PropertyChangeEvent;
 43  
 
 44  
 import org.argouml.application.events.ArgoDiagramAppearanceEvent;
 45  
 import org.argouml.application.events.ArgoEventPump;
 46  
 import org.argouml.application.events.ArgoEventTypes;
 47  
 import org.argouml.configuration.Configuration;
 48  
 import org.argouml.configuration.ConfigurationKey;
 49  
 import org.argouml.kernel.ProfileConfiguration;
 50  
 import org.argouml.notation.NotationSettings;
 51  
 import org.tigris.gef.undo.Memento;
 52  
 
 53  
 /**
 54  
  * Diagram appearance settings.  This includes basic things like colors and
 55  
  * fonts, as well as the {@link NotationSettings} which contain all the settings
 56  
  * that control text formatting.
 57  
  * <p>
 58  
  * The settings are designed to work in a hierarchical fashion with any settings
 59  
  * that are defaulted at the current level inheriting from the next level in
 60  
  * the hierarchy.  A typical hierarchy would be Fig->StyleSheet->Project where 
 61  
  * a style sheet is a named set of attributes that can be applied as a set to
 62  
  * a fig (perhaps in conjunction with a stereotype).  The hierarchy which is
 63  
  * currently used in ArgoUML is Fig->Diagram->Project, although there's no
 64  
  * support for changing anything but the Project (and a few of the attributes
 65  
  * managed directly by GEF).
 66  
  * <p>
 67  
  * Notation settings have a semantic meaning in the UML, which
 68  
  * defines the difference between notation settings and 
 69  
  * diagram appearance settings.
 70  
  * 
 71  
  * @author Tom Morris <tfmorris@gmail.com>
 72  
  */
 73  3872
 public class DiagramSettings {
 74  
 
 75  
     /*
 76  
      * The special value <code>null</code> is used internally to indicate that
 77  
      * the default value should be inherited from the next level of settings.
 78  
      */
 79  
     
 80  
     /**
 81  
      * Enumeration representing different stereotype presentation styles
 82  
      */
 83  2768
     public enum StereotypeStyle {
 84  
         
 85  
         // *IMPORTANT* - These MUST remain in order!
 86  
         
 87  
         /**
 88  
          * Textual rendering for stereotype
 89  
          */
 90  900
         TEXTUAL(DiagramAppearance.STEREOTYPE_VIEW_TEXTUAL), 
 91  
         /**
 92  
          * Stereotype rendered with large icon
 93  
          */
 94  900
         BIG_ICON(DiagramAppearance.STEREOTYPE_VIEW_BIG_ICON), 
 95  
         /**
 96  
          * Stereotype rendered with small icon
 97  
          */
 98  900
         SMALL_ICON(DiagramAppearance.STEREOTYPE_VIEW_SMALL_ICON);
 99  
        
 100  2700
         StereotypeStyle(int value) {
 101  2700
             assert value == this.ordinal();
 102  2700
         }
 103  
         
 104  
 
 105  
         /**
 106  
          * Convert old style int representation to an enum.  The enum returned
 107  
          * is the one at the given ordinal (ie this is the inverse of the
 108  
          * mapping done by ordinal()).
 109  
          * 
 110  
          * @param value one of the defined int values in DiagramAppearance
 111  
          * @return the corresponding StereotypeView enum
 112  
          */
 113  
         public static StereotypeStyle getEnum(int value) {
 114  968
             int counter = 0;
 115  968
             for (StereotypeStyle sv : StereotypeStyle.values()) {
 116  968
                 if (counter == value) {
 117  968
                     return sv;
 118  
                 }
 119  0
                 counter++;
 120  
             }
 121  0
             return null;
 122  
         }
 123  
     }
 124  
     
 125  
 //    private static final StereotypeView[] stereotypeViewMap;
 126  
 //    
 127  
 //    static {
 128  
 //        stereotypeViewMap = new StereotypeView[3];
 129  
 //        StereotypeView.
 130  
 //        stereotypeViewMap[DiagramAppearance.STEREOTYPE_VIEW_TEXTUAL] = 
 131  
 //            StereotypeView.TEXTUAL;
 132  
 //        stereotypeViewMap[DiagramAppearance.STEREOTYPE_VIEW_BIG_ICON] = 
 133  
 //            StereotypeView.BIG_ICON;
 134  
 //        stereotypeViewMap[DiagramAppearance.STEREOTYPE_VIEW_SMALL_ICON] = 
 135  
 //            StereotypeView.SMALL_ICON;
 136  
 //    }
 137  
     
 138  
     /**
 139  
      * Next level in the settings hierarchy to inherit from if the value
 140  
      * isn't set (ie is <default>) at the current level.
 141  
      */
 142  
     private DiagramSettings parent;
 143  
     
 144  
     private NotationSettings notationSettings;
 145  
 
 146  
     /* Diagram appearance settings with project scope: */
 147  
     private String fontName;
 148  
     private Integer fontSize;
 149  
     
 150  
     // We can not remove this and have the application manage things directly
 151  
     // based on the font, since only the names should be bold.
 152  
     private Boolean showBoldNames;
 153  
 
 154  
     private Boolean showBidirectionalArrows;
 155  
     
 156  
     private Integer defaultShadowWidth;
 157  
     
 158  
     private StereotypeStyle defaultStereotypeView;
 159  
 
 160  
     /* Some cached fonts based on the above settings */
 161  
     private Font fontPlain;
 162  
     private Font fontItalic;
 163  
     private Font fontBold;
 164  
     private Font fontBoldItalic;
 165  
 
 166  
     /**
 167  
      * Construct an empty diagram settings with no parent and all values
 168  
      * defaulted. <p>
 169  
      */
 170  
     public DiagramSettings() {
 171  2039
         this(null);
 172  2039
     }
 173  
     
 174  
     /**
 175  
      * Construct a DiagramSettings object which inherits from the given
 176  
      * parent settings (e.g. project default diagram settings).
 177  
      * 
 178  
      * @param parentSettings settings to inherit from if default values aren't
 179  
      * overridden.
 180  
      */
 181  
     public DiagramSettings(DiagramSettings parentSettings) {
 182  2039
         super();
 183  2039
         parent = parentSettings;
 184  2039
         if (parentSettings == null) {
 185  2039
             notationSettings = new NotationSettings();
 186  
         } else {
 187  0
             notationSettings = 
 188  
                 new NotationSettings(parent.getNotationSettings());
 189  
         }
 190  2039
         recomputeFonts();
 191  2039
     }
 192  
 
 193  
     /**
 194  
      * Send all events when the settings are changed to refresh
 195  
      * anything rendered with these settings.
 196  
      */
 197  
     public void notifyOfChangedSettings() {
 198  
         /*
 199  
          * Since body ever looks
 200  
          * at the type of the diagram appearance event, we can simplify from
 201  
          * sending every existing event to one event only. But since there is no
 202  
          * catch-all event defined, we just use one. Rationale: reduce the
 203  
          * number of total refreshes of the drawing.
 204  
          */
 205  12
         ConfigurationKey key = 
 206  
             Configuration.makeKey("diagramappearance", "all");
 207  12
         ArgoEventPump.fireEvent(new ArgoDiagramAppearanceEvent(
 208  
                 ArgoEventTypes.DIAGRAM_FONT_CHANGED, new PropertyChangeEvent(
 209  
                         this, key.getKey(),  "0", "0")));
 210  12
     }
 211  
 
 212  
     /**
 213  
      * Initialize the diagram settings with application default values 
 214  
      * from the Configuration retrieved from disk.
 215  
      */
 216  
     public void initFromConfiguration() {
 217  968
         setShowBoldNames(Configuration.getBoolean(
 218  
                 DiagramAppearance.KEY_SHOW_BOLD_NAMES));
 219  
         
 220  968
         setShowBidirectionalArrows(!Configuration.getBoolean(
 221  
                 DiagramAppearance.KEY_HIDE_BIDIRECTIONAL_ARROWS, true));
 222  
         
 223  968
         setDefaultShadowWidth(Configuration.getInteger(
 224  
                 DiagramAppearance.KEY_DEFAULT_SHADOW_WIDTH, 1));
 225  
 
 226  968
         setDefaultStereotypeView(Configuration.getInteger(
 227  
                 ProfileConfiguration.KEY_DEFAULT_STEREOTYPE_VIEW,
 228  
                 DiagramAppearance.STEREOTYPE_VIEW_TEXTUAL));
 229  
 
 230  968
         setFontName(
 231  
                 DiagramAppearance.getInstance().getConfiguredFontName());
 232  968
         setFontSize(
 233  
                 Configuration.getInteger(DiagramAppearance.KEY_FONT_SIZE));
 234  968
     }
 235  
 
 236  
     /**
 237  
      * @return Returns the notationSettings.
 238  
      */
 239  
     public NotationSettings getNotationSettings() {
 240  2039
         return notationSettings;
 241  
     }
 242  
 
 243  
 
 244  
     /**
 245  
      * @param notationSettings The notationSettings to set.
 246  
      */
 247  
     public void setNotationSettings(NotationSettings notationSettings) {
 248  0
         this.notationSettings = notationSettings;
 249  0
     }
 250  
 
 251  
 
 252  
     /**
 253  
      * @return Returns <code>true</code> if we show bold names.
 254  
      */
 255  
     public boolean isShowBoldNames() {
 256  124
         if (showBoldNames == null) {
 257  0
             if (parent != null) {
 258  0
                 return parent.isShowBoldNames();
 259  
             } else {
 260  0
                 return false;
 261  
             }
 262  
         }
 263  124
         return showBoldNames;
 264  
     }
 265  
 
 266  
     /**
 267  
      * @param showem <code>true</code> if names are to be shown in bold font.
 268  
      */
 269  
     public void setShowBoldNames(final boolean showem) {
 270  980
         if (showBoldNames != null && showBoldNames == showem) {
 271  12
             return;
 272  
         }
 273  
 
 274  968
         Memento memento = new Memento() {
 275  
             public void redo() {
 276  968
                 showBoldNames = showem;
 277  968
             }
 278  
 
 279  
             public void undo() {
 280  0
                 showBoldNames = !showem;
 281  0
             }
 282  
         };
 283  968
         doUndoable(memento);
 284  968
     }
 285  
 
 286  
    
 287  
     /**
 288  
      * @return Returns <code>true</code> if we show the arrows when
 289  
      * both association ends of an association are navigable.
 290  
      */
 291  
     public boolean isShowBidirectionalArrows() {
 292  124
         if (showBidirectionalArrows == null) {
 293  0
             if (parent != null) {
 294  0
                 return parent.isShowBidirectionalArrows();
 295  
             } else {
 296  0
                 return false;
 297  
             }
 298  
         }
 299  124
         return showBidirectionalArrows;
 300  
     }
 301  
 
 302  
     /**
 303  
      * @param showem <code>true</code> if both arrows are to be shown when
 304  
      * both association ends of an association are navigable.
 305  
      */
 306  
     public void setShowBidirectionalArrows(final boolean showem) {
 307  980
         if (showBidirectionalArrows != null 
 308  
                 && showBidirectionalArrows == showem) {
 309  12
             return;
 310  
         }
 311  
 
 312  968
         Memento memento = new Memento() {
 313  
             public void redo() {
 314  968
                 showBidirectionalArrows = showem;
 315  968
             }
 316  
 
 317  
             public void undo() {
 318  0
                 showBidirectionalArrows = !showem;
 319  0
             }
 320  
         };
 321  968
         doUndoable(memento);
 322  
 
 323  968
     }
 324  
 
 325  
 
 326  
     /**
 327  
      * @return Returns the shadow width.
 328  
      */
 329  
     public int getDefaultShadowWidth() {
 330  1195
         if (defaultShadowWidth == null) {
 331  1071
             if (parent != null) {
 332  0
                 return parent.getDefaultShadowWidth();
 333  
             } else {
 334  1071
                 return 0;
 335  
             }
 336  
         }
 337  124
         return defaultShadowWidth;
 338  
     }
 339  
 
 340  
     /**
 341  
      * @param newWidth The Shadow Width.
 342  
      */
 343  
     public void setDefaultShadowWidth(final int newWidth) {
 344  980
         if (defaultShadowWidth != null && defaultShadowWidth == newWidth) {
 345  12
             return;
 346  
         }
 347  
 
 348  968
         final Integer oldValue = defaultShadowWidth;
 349  
 
 350  968
         Memento memento = new Memento() {
 351  
             public void redo() {
 352  968
                 defaultShadowWidth = newWidth;
 353  968
             }
 354  
 
 355  
             public void undo() {
 356  0
                 defaultShadowWidth = oldValue;
 357  0
             }
 358  
         };
 359  968
         doUndoable(memento);
 360  
 
 361  968
     }
 362  
 
 363  
 
 364  
     /**
 365  
      * @return Returns the default stereotype view
 366  
      * TODO: Enumeration here?
 367  
      */
 368  
     public StereotypeStyle getDefaultStereotypeView() {
 369  1171
         if (defaultStereotypeView == null) {
 370  1071
             if (parent != null) {
 371  0
                 return parent.getDefaultStereotypeView();
 372  
             } else {
 373  1071
                 return StereotypeStyle.TEXTUAL;
 374  
             }
 375  
         }
 376  100
         return defaultStereotypeView;
 377  
     }
 378  
 
 379  
     /**
 380  
      * @return Returns the default stereotype view as an int compatible with
 381  
      * old users of DiagramAppearance-defined ints.
 382  
      * @deprecated for 0.27.2 by tfmorris.  For backward compatibility only.
 383  
      */
 384  
     public int getDefaultStereotypeViewInt() {
 385  100
         return getDefaultStereotypeView().ordinal();
 386  
     }
 387  
     
 388  
     /**
 389  
      * @param newView the default stereotype view
 390  
      * @deprecated for 0.27.2 by tfmorris. Not for use in new code. Only for
 391  
      *             help in transitioning to enum based methods. Use
 392  
      *             {@link #setDefaultStereotypeView(StereotypeStyle)}.
 393  
      */
 394  
     public void setDefaultStereotypeView(final int newView) {
 395  968
         StereotypeStyle sv = StereotypeStyle.getEnum(newView);
 396  968
         if (sv == null) {
 397  0
             throw new IllegalArgumentException("Bad argument " + newView);
 398  
         }
 399  968
         setDefaultStereotypeView(sv);
 400  968
     }
 401  
 
 402  
     /**
 403  
      * @param newView the default stereotype view
 404  
      */
 405  
     public void setDefaultStereotypeView(final StereotypeStyle newView) {
 406  968
         if (defaultStereotypeView != null && defaultStereotypeView == newView) {
 407  0
             return;
 408  
         }
 409  
 
 410  968
         final StereotypeStyle oldValue = defaultStereotypeView;
 411  
 
 412  968
         Memento memento = new Memento() {
 413  
             public void redo() {
 414  968
                 defaultStereotypeView = newView;
 415  968
             }
 416  
 
 417  
             public void undo() {
 418  0
                 defaultStereotypeView = oldValue;
 419  0
             }
 420  
         };
 421  968
         doUndoable(memento);
 422  968
     }
 423  
 
 424  
 
 425  
     /**
 426  
      * Diagram font name. <p>
 427  
      * 
 428  
      * @return diagram font name.
 429  
      */
 430  
     public String getFontName() {
 431  5170
         if (fontName == null) {
 432  3110
             if (parent != null) {
 433  0
                 return parent.getFontName();
 434  
             } else {
 435  3110
                 return "Dialog";
 436  
             }
 437  
         }
 438  2060
         return fontName;
 439  
     }
 440  
 
 441  
     /**
 442  
      * Diagram font name.
 443  
      * @param newFontName diagram font name.
 444  
      */
 445  
     public void setFontName(String newFontName) {
 446  980
         if (fontName != null && fontName.equals(newFontName)) {
 447  12
             return;
 448  
         }
 449  968
         fontName = newFontName;
 450  968
         recomputeFonts();
 451  968
     }
 452  
 
 453  
     /**
 454  
      * Diagram font size. <p>
 455  
      *
 456  
      * @return diagram font size.
 457  
      */
 458  
     public int getFontSize() {
 459  5170
         if (fontSize == null) {
 460  4078
             if (parent != null) {
 461  0
                 return parent.getFontSize();
 462  
             } else {
 463  4078
                 return 10;
 464  
             }
 465  
         }
 466  1092
         return fontSize;
 467  
     }
 468  
 
 469  
     /**
 470  
      * Diagram font size.
 471  
      * @param newFontSize diagram font size.
 472  
      */
 473  
     public void setFontSize(int newFontSize) {
 474  980
         if (fontSize != null && fontSize == newFontSize) {
 475  12
             return;
 476  
         }
 477  968
         fontSize = newFontSize;
 478  968
         recomputeFonts();
 479  968
     }
 480  
 
 481  
     private void recomputeFonts() {
 482  
         // If we've got a local (uninherited) font name or size or if we've got
 483  
         // no parent to inherit from recompute our cached fonts
 484  3975
         if ((fontName != null && !"".equals(fontName) && fontSize != null)
 485  
                 || parent == null) {
 486  3975
             String name = getFontName();
 487  3975
             int size = getFontSize();
 488  3975
             fontPlain = new Font(name, Font.PLAIN, size);
 489  3975
             fontItalic = new Font(name, Font.ITALIC, size);
 490  3975
             fontBold = new Font(name, Font.BOLD, size);
 491  3975
             fontBoldItalic = new Font(name, Font.BOLD | Font.ITALIC, size);
 492  3975
         } else {
 493  0
             fontPlain = null;
 494  0
             fontItalic = null;
 495  0
             fontBold = null;
 496  0
             fontBoldItalic = null;
 497  
         }
 498  3975
     }
 499  
 
 500  
     /**
 501  
      * Returns the Plain diagram font which corresponds
 502  
      * to selected parameters.
 503  
      *
 504  
      * @return plain diagram font
 505  
      */
 506  
     public Font getFontPlain() {
 507  0
         if (fontPlain == null) {
 508  0
             return parent.getFontPlain();
 509  
         }
 510  0
         return fontPlain;
 511  
     }
 512  
 
 513  
     /**
 514  
      * Returns the Italic diagram font which corresponds
 515  
      * to selected parameters.
 516  
      *
 517  
      * @return italic diagram font
 518  
      */
 519  
     public Font getFontItalic() {
 520  0
         if (fontItalic == null) {
 521  0
             return parent.getFontItalic();
 522  
         }
 523  0
         return fontItalic;
 524  
     }
 525  
 
 526  
     /**
 527  
      * Returns the Bold diagram font which corresponds
 528  
      * to selected parameters.
 529  
      *
 530  
      * @return bold diagram font
 531  
      */
 532  
     public Font getFontBold() {
 533  0
         if (fontBold == null) {
 534  0
             return parent.getFontBold();
 535  
         }
 536  0
         return fontBold;
 537  
     }
 538  
 
 539  
     /**
 540  
      * Returns the Bold-Italic diagram font which corresponds
 541  
      * to selected parameters.
 542  
      *
 543  
      * @return bold-italic diagram font
 544  
      */
 545  
     public Font getFontBoldItalic() {
 546  0
         if (fontBoldItalic == null) {
 547  0
             return parent.getFontBoldItalic();
 548  
         }
 549  0
         return fontBoldItalic;
 550  
     }
 551  
 
 552  
     /**
 553  
      * Utility function to convert a font style integer into a Font.
 554  
      *
 555  
      * @param fontStyle the style; see the predefined constants in Font
 556  
      * @return the Font that corresponds to the style
 557  
      */
 558  
     public Font getFont(int fontStyle) {
 559  0
         if ((fontStyle & Font.ITALIC) != 0) {
 560  0
             if ((fontStyle & Font.BOLD) != 0) {
 561  0
                 return getFontBoldItalic();
 562  
             } else {
 563  0
                 return getFontItalic();
 564  
             }
 565  
         } else {
 566  0
             if ((fontStyle & Font.BOLD) != 0) {
 567  0
                 return getFontBold();
 568  
             } else {
 569  0
                 return getFontPlain();
 570  
             }
 571  
         }
 572  
     }
 573  
 
 574  
     private void doUndoable(Memento memento) {
 575  
         // TODO: Undo should be managed externally or we should be given 
 576  
         // an Undo manager to use (the project's) rather than using a global one
 577  
 //        if (DiagramUndoManager.getInstance().isGenerateMementos()) {
 578  
 //            DiagramUndoManager.getInstance().addMemento(memento);
 579  
 //        }
 580  3872
         memento.redo();
 581  
         // TODO: Mark diagram/project as dirty?
 582  3872
     }
 583  
 }
 584