Added word wrap option (problem: conflicts with folding)
[phpeclipse.git] / net.sourceforge.phpeclipse.webbrowser / src / net / sourceforge / phpeclipse / webbrowser / internal / BrowserManager.java
1 /**********************************************************************
2  * Copyright (c) 2003 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7   *
8  * Contributors:
9  *    IBM - Initial API and implementation
10  **********************************************************************/
11 package net.sourceforge.phpeclipse.webbrowser.internal;
12
13 import java.io.ByteArrayInputStream;
14 import java.io.InputStreamReader;
15 import java.io.Reader;
16 import java.io.StringWriter;
17 import java.util.ArrayList;
18 import java.util.Iterator;
19 import java.util.List;
20
21 import net.sourceforge.phpeclipse.webbrowser.IExternalWebBrowser;
22 import net.sourceforge.phpeclipse.webbrowser.IExternalWebBrowserWorkingCopy;
23 import net.sourceforge.phpeclipse.webbrowser.IInternalWebBrowser;
24 import net.sourceforge.phpeclipse.webbrowser.IWebBrowser;
25
26 import org.eclipse.core.runtime.IStatus;
27 import org.eclipse.core.runtime.Preferences;
28 import org.eclipse.core.runtime.Status;
29 import org.eclipse.ui.IMemento;
30 import org.eclipse.ui.XMLMemento;
31
32 /**
33  *  
34  */
35 public class BrowserManager {
36   private static final int ADD = 0;
37
38   private static final int CHANGE = 1;
39
40   private static final int REMOVE = 2;
41
42   protected List browsers;
43
44   protected IWebBrowser currentBrowser;
45
46   protected List browserListeners = new ArrayList();
47
48   private Preferences.IPropertyChangeListener pcl;
49
50   protected boolean ignorePreferenceChanges = false;
51
52   protected static BrowserManager instance;
53
54   public static BrowserManager getInstance() {
55     if (instance == null)
56       instance = new BrowserManager();
57     return instance;
58   }
59
60   private BrowserManager() {
61     pcl = new Preferences.IPropertyChangeListener() {
62       public void propertyChange(Preferences.PropertyChangeEvent event) {
63         if (ignorePreferenceChanges)
64           return;
65         String property = event.getProperty();
66         if (property.equals("browsers")) {
67           loadBrowsers();
68         }
69       }
70     };
71
72     WebBrowserUIPlugin.getInstance().getPluginPreferences().addPropertyChangeListener(pcl);
73   }
74
75   protected void dispose() {
76     WebBrowserUIPlugin.getInstance().getPluginPreferences().removePropertyChangeListener(pcl);
77
78     // clear the cache
79     if (browsers != null) {
80       Iterator iterator = browsers.iterator();
81       while (iterator.hasNext()) {
82         Object obj = iterator.next();
83         if (obj instanceof IInternalWebBrowser) {
84           IInternalWebBrowser wb = (IInternalWebBrowser) obj;
85           if (wb.getClearHistoryOnExit())
86             WebBrowserPreference.setInternalWebBrowserHistory(null);
87         }
88       }
89     }
90   }
91
92   public IExternalWebBrowserWorkingCopy createExternalWebBrowser() {
93     return new ExternalWebBrowserWorkingCopy();
94   }
95
96   public List getWebBrowsers() {
97     if (browsers == null)
98       loadBrowsers();
99     return new ArrayList(browsers);
100   }
101
102   protected void loadBrowsers() {
103     Trace.trace(Trace.FINEST, "Loading web browsers");
104
105     Preferences prefs = WebBrowserUIPlugin.getInstance().getPluginPreferences();
106     String xmlString = prefs.getString("browsers");
107     if (xmlString != null && xmlString.length() > 0) {
108       browsers = new ArrayList();
109
110       try {
111         ByteArrayInputStream in = new ByteArrayInputStream(xmlString.getBytes());
112         Reader reader = new InputStreamReader(in);
113         IMemento memento = XMLMemento.createReadRoot(reader);
114
115         IMemento child = memento.getChild("internal");
116         if (child != null) {
117           InternalWebBrowser browser = new InternalWebBrowser();
118           browser.load(child);
119           browsers.add(browser);
120         }
121
122         IMemento[] children = memento.getChildren("external");
123         int size = children.length;
124         for (int i = 0; i < size; i++) {
125           ExternalWebBrowser browser = new ExternalWebBrowser();
126           browser.load(children[i]);
127           browsers.add(browser);
128         }
129
130         Integer current = memento.getInteger("current");
131         if (current != null) {
132           currentBrowser = (IWebBrowser) browsers.get(current.intValue());
133         }
134       } catch (Exception e) {
135         Trace.trace(Trace.WARNING, "Could not load browsers: " + e.getMessage());
136       }
137       addInternalBrowser(browsers);
138       if (currentBrowser == null && browsers.size() > 0)
139         currentBrowser = (IWebBrowser) browsers.get(0);
140     } else {
141       setupDefaultBrowsers();
142       saveBrowsers();
143       return;
144     }
145   }
146
147   protected void saveBrowsers() {
148     try {
149       ignorePreferenceChanges = true;
150       XMLMemento memento = XMLMemento.createWriteRoot("web-browsers");
151
152       Iterator iterator = browsers.iterator();
153       while (iterator.hasNext()) {
154         Object obj = iterator.next();
155         if (obj instanceof InternalWebBrowser) {
156           InternalWebBrowser browser = (InternalWebBrowser) obj;
157           IMemento child = memento.createChild("internal");
158           browser.save(child);
159         } else if (obj instanceof ExternalWebBrowser) {
160           ExternalWebBrowser browser = (ExternalWebBrowser) obj;
161           IMemento child = memento.createChild("external");
162           browser.save(child);
163         }
164       }
165
166       memento.putInteger("current", browsers.indexOf(currentBrowser));
167
168       StringWriter writer = new StringWriter();
169       memento.save(writer);
170       String xmlString = writer.getBuffer().toString();
171       Preferences prefs = WebBrowserUIPlugin.getInstance().getPluginPreferences();
172       prefs.setValue("browsers", xmlString);
173       WebBrowserUIPlugin.getInstance().savePluginPreferences();
174     } catch (Exception e) {
175       Trace.trace(Trace.SEVERE, "Could not save browsers", e);
176     }
177     ignorePreferenceChanges = false;
178   }
179
180   protected void addInternalBrowser(List browserList) {
181     if (browserList == null)
182       return;
183
184     Iterator iterator = browserList.iterator();
185     while (iterator.hasNext()) {
186       IWebBrowser browser = (IWebBrowser) iterator.next();
187       if (browser instanceof IInternalWebBrowser)
188         return;
189     }
190
191     // add the internal browser if we can
192     WebBrowserUIPlugin.getInstance().getLog().log(
193         new Status(IStatus.INFO, WebBrowserUIPlugin.PLUGIN_ID, 0, WebBrowserUtil.canUseInternalWebBrowser() + "/"
194             + WebBrowserUtil.isInternalBrowserOperational(), null));
195     if (!WebBrowserUtil.canUseInternalWebBrowser() || !WebBrowserUtil.isInternalBrowserOperational())
196       return;
197
198     browserList.add(0, new InternalWebBrowser());
199   }
200
201   private void setupDefaultBrowsers() {
202     browsers = new ArrayList();
203
204     addInternalBrowser(browsers);
205
206     // handle all the EXTERNAL browsers by criteria and add those too at startup
207     WebBrowserUtil.addFoundBrowsers(browsers);
208
209     // by default, if internal is there, that is current, else set the first external one
210     if (!browsers.isEmpty())
211       currentBrowser = (IWebBrowser) browsers.get(0);
212   }
213
214   protected void addBrowser(IExternalWebBrowser browser) {
215     if (browsers == null)
216       loadBrowsers();
217     if (!browsers.contains(browser))
218       browsers.add(browser);
219     fireWebBrowserEvent(browser, ADD);
220     saveBrowsers();
221   }
222
223   protected void removeWebBrowser(IExternalWebBrowser browser) {
224     if (browsers == null)
225       loadBrowsers();
226     browsers.remove(browser);
227     fireWebBrowserEvent(browser, REMOVE);
228   }
229
230   // Internal Web browser CAN be "edited", just not created or removed
231   protected void browserChanged(IWebBrowser browser) {
232     fireWebBrowserEvent(browser, CHANGE);
233     saveBrowsers();
234   }
235
236   /**
237    * Add Web browser listener.
238    * 
239    * @param listener
240    */
241   public void addWebBrowserListener(IWebBrowserListener listener) {
242     browserListeners.add(listener);
243   }
244
245   /**
246    * Remove Web browser listener.
247    * 
248    * @param listener
249    */
250   public void removeWebBrowserListener(IWebBrowserListener listener) {
251     browserListeners.remove(listener);
252   }
253
254   /**
255    * Fire a Web browser event.
256    * 
257    * @param browser
258    * @param type
259    */
260   protected void fireWebBrowserEvent(IWebBrowser browser, int type) {
261     Object[] obj = browserListeners.toArray();
262
263     int size = obj.length;
264     for (int i = 0; i < size; i++) {
265       IWebBrowserListener listener = (IWebBrowserListener) obj[i];
266       if (type == ADD)
267         listener.browserAdded(browser);
268       else if (type == CHANGE)
269         listener.browserChanged(browser);
270       else if (type == REMOVE)
271         listener.browserRemoved(browser);
272     }
273   }
274
275   public IWebBrowser getCurrentWebBrowser() {
276     if (browsers == null)
277       loadBrowsers();
278
279     return currentBrowser;
280   }
281
282   public void setCurrentWebBrowser(IWebBrowser wb) {
283     if (browsers.contains(wb))
284       currentBrowser = wb;
285     saveBrowsers();
286   }
287 }