1   /**
2    * Distribution License:
3    * BibleDesktop is free software; you can redistribute it and/or modify it under
4    * the terms of the GNU General Public License, version 2 as published by
5    * the Free Software Foundation. This program is distributed in the hope
6    * that it will be useful, but WITHOUT ANY WARRANTY; without even the
7    * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
8    * See the GNU General Public License for more details.
9    *
10   * The License is available on the internet at:
11   *       http://www.gnu.org/copyleft/gpl.html
12   * or by writing to:
13   *      Free Software Foundation, Inc.
14   *      59 Temple Place - Suite 330
15   *      Boston, MA 02111-1307, USA
16   *
17   * Copyright: 2007
18   *     The copyright to this program is held by it's authors.
19   *
20   * ID: $Id: org.eclipse.jdt.ui.prefs 1178 2006-11-06 12:48:02Z dmsmith $
21   */
22  
23  package org.crosswire.common.swing.desktop;
24  
25  import java.awt.Dimension;
26  import java.awt.Frame;
27  import java.awt.Point;
28  import java.awt.Window;
29  import java.io.IOException;
30  import java.net.URI;
31  
32  import org.crosswire.common.util.CWProject;
33  import org.crosswire.common.util.FileUtil;
34  import org.crosswire.common.util.Logger;
35  import org.crosswire.common.util.NetUtil;
36  import org.crosswire.common.util.PropertyMap;
37  import org.crosswire.common.util.ResourceUtil;
38  import org.crosswire.common.util.StringUtil;
39  
40  /**
41   * Window layout persistence mechanism. Intended to be flexible enough to allow
42   * persisting size, position, layout of multiple windows.
43   * 
44   * @see gnu.gpl.License for license details.<br>
45   *      The copyright to this program is held by it's authors.
46   * @author Adam Thomas [adam-thomas at cox dot net]
47   * @author DM Smith [dmsmith555 at yahoo dot com]
48   */
49  public class LayoutPersistence {
50  
51      /**
52       * Creates the singleton persistence object capable of storing and
53       * retrieving layout information on behalf windows.
54       */
55      private LayoutPersistence() {
56          try {
57              settings = ResourceUtil.getProperties(getClass());
58          } catch (IOException e) {
59              settings = new PropertyMap();
60          }
61      }
62  
63      /**
64       * All access to LayoutPersistence is through this single instance.
65       * 
66       * @return the singleton instance
67       */
68      public static LayoutPersistence instance() {
69          return instance;
70      }
71  
72      /**
73       * Indicates whether the window passed to the constructor has had layout
74       * information persisted.
75       * 
76       * @param window
77       *            the window to persist
78       * @return Returns true is layout information for the current window has
79       *         been persisted, otherwise returns false
80       */
81      public synchronized boolean isLayoutPersisted(Window window) {
82          return settings.containsKey(window.getName());
83      }
84  
85      /**
86       * Stores the current window's layout information.
87       * 
88       * @param window
89       *            the window to persist
90       */
91      public synchronized void saveLayout(Window window) {
92          int state = Frame.NORMAL;
93          if (window instanceof Frame) {
94              Frame frame = (Frame) window;
95              state = frame.getExtendedState();
96          }
97  
98          settings.put(window.getName(), StringUtil.join(new String[] {
99                  Integer.toString(state), Integer.toString(window.getWidth()), Integer.toString(window.getHeight()), Integer.toString(window.getX()),
100                 Integer.toString(window.getY())
101         }, "_")
102                 );
103 
104         try {
105             URI outputURI = CWProject.instance().getWritableURI(getClass().getName(), FileUtil.EXTENSION_PROPERTIES);
106             NetUtil.storeProperties(settings, outputURI, "Persistent Window properties");
107         } catch (IOException ex) {
108             log.error(ex.getLocalizedMessage(), ex);
109         }
110     }
111 
112     /**
113      * Loads and restores the layout to the window that was passed to the
114      * constructor.
115      * 
116      * @param window
117      *            the window to persist
118      */
119     public synchronized void restoreLayout(Window window) {
120         String[] parts = StringUtil.split(settings.get(window.getName()), '_');
121 
122         // If our window did not have saved settings do nothing.
123         if (parts == null || parts.length == 0) {
124             return;
125         }
126 
127         if (window instanceof Frame) {
128             Frame frame = (Frame) window;
129             frame.setExtendedState(Integer.parseInt(parts[STATE]));
130         }
131 
132         window.setSize(new Dimension(Integer.parseInt(parts[WIDTH]), Integer.parseInt(parts[HEIGHT])));
133         window.setLocation(new Point(Integer.parseInt(parts[LOCATION_X]), Integer.parseInt(parts[LOCATION_Y])));
134     }
135 
136     /**
137      * Provide class logging capabilities
138      */
139     private static final Logger log = Logger.getLogger(LayoutPersistence.class);
140 
141     /**
142      * The persistence storage and retrieval object
143      */
144     private PropertyMap settings;
145 
146     /**
147      * Suffix for window state key
148      */
149     private static final int STATE = 0;
150 
151     /**
152      * Suffix for window width key
153      */
154     private static final int WIDTH = 1;
155 
156     /**
157      * Suffix for window height key
158      */
159     private static final int HEIGHT = 2;
160 
161     /**
162      * Suffix for window location x key
163      */
164     private static final int LOCATION_X = 3;
165 
166     /**
167      * Suffix for window location y key
168      */
169     private static final int LOCATION_Y = 4;
170 
171     /**
172      * The singleton instance of this class.
173      */
174     private static LayoutPersistence instance = new LayoutPersistence();
175 
176 }
177