Initial version from the webtools project; sligthly modified for phpeclipse
[phpeclipse.git] / net.sourceforge.phpeclipse.webbrowser / src / org / eclipse / webbrowser / internal / WebBrowserEditor.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 org.eclipse.webbrowser.internal;
12
13 import java.net.URL;
14 import org.eclipse.swt.graphics.Image;
15 import org.eclipse.swt.widgets.Composite;
16 import org.eclipse.swt.widgets.Display;
17 import org.eclipse.jface.action.IAction;
18 import org.eclipse.jface.dialogs.IDialogConstants;
19 import org.eclipse.jface.dialogs.MessageDialog;
20 import org.eclipse.jface.resource.ImageDescriptor;
21 import org.eclipse.core.runtime.*;
22 import org.eclipse.core.resources.*;
23 import org.eclipse.ui.*;
24 import org.eclipse.ui.part.*;
25 import org.eclipse.webbrowser.*;
26 /**
27  * An integrated Web browser, defined as an editor to make
28  * better use of the desktop.
29  */
30 public class WebBrowserEditor extends EditorPart {
31         public static final String WEB_BROWSER_EDITOR_ID = "org.eclipse.webbrowser";
32         protected WebBrowser webBrowser;
33         protected String initialURL;
34         protected Image image;
35
36         protected TextAction cutAction;
37         protected TextAction copyAction;
38         protected TextAction pasteAction;
39         
40         protected IResourceChangeListener resourceListener;
41
42         /**
43          * WebBrowserEditor constructor comment.
44          */
45         public WebBrowserEditor() {
46                 super();
47         }
48         
49         /**
50          * Creates the SWT controls for this workbench part.
51          * <p>
52          * Clients should not call this method (the workbench calls this method at
53          * appropriate times).
54          * </p>
55          * <p>
56          * For implementors this is a multi-step process:
57          * <ol>
58          *   <li>Create one or more controls within the parent.</li>
59          *   <li>Set the parent layout as needed.</li>
60          *   <li>Register any global actions with the <code>IActionService</code>.</li>
61          *   <li>Register any popup menus with the <code>IActionService</code>.</li>
62          *   <li>Register a selection provider with the <code>ISelectionService</code>
63          *     (optional). </li>
64          * </ol>
65          * </p>
66          *
67          * @param parent the parent control
68          */
69         public void createPartControl(Composite parent) {
70                 IWebBrowserEditorInput input = getWebBrowserEditorInput();
71                 
72                 
73                 if (input == null || input.isToolbarVisible() == false)
74                         webBrowser = new WebBrowser(parent, false, input.isStatusbarVisible());
75                 else {
76                         webBrowser = new WebBrowser(parent, true, input.isStatusbarVisible());
77                         cutAction = new TextAction(webBrowser, TextAction.CUT);
78                         copyAction = new TextAction(webBrowser, TextAction.COPY);
79                         pasteAction = new TextAction(webBrowser, TextAction.PASTE);
80                 }
81                 
82                 webBrowser.setURL(initialURL);
83                 webBrowser.editor = this;
84         }
85         
86         public void dispose() {
87                 if (image != null && !image.isDisposed())
88                         image.dispose();
89                 image = null;
90
91                 if (resourceListener != null)
92                         ResourcesPlugin.getWorkspace().removeResourceChangeListener(resourceListener);
93         }
94         
95         /* (non-Javadoc)
96          * Saves the contents of this editor.
97          * <p>
98          * Subclasses must override this method to implement the open-save-close lifecycle
99          * for an editor.  For greater details, see <code>IEditorPart</code>
100          * </p>
101          *
102          * @see IEditorPart
103          */
104         public void doSave(IProgressMonitor monitor) { }
105
106         /* (non-Javadoc)
107          * Saves the contents of this editor to another object.
108          * <p>
109          * Subclasses must override this method to implement the open-save-close lifecycle
110          * for an editor.  For greater details, see <code>IEditorPart</code>
111          * </p>
112          *
113          * @see IEditorPart
114          */
115         public void doSaveAs() { }
116         
117         /**
118          * Returns the copy action.
119          *
120          * @return org.eclipse.jface.action.IAction
121          */
122         public IAction getCopyAction() {
123                 return copyAction;
124         }
125         
126         /**
127          * Returns the cut action.
128          *
129          * @return org.eclipse.jface.action.IAction
130          */
131         public IAction getCutAction() {
132                 return cutAction;
133         }
134         
135         /**
136          * Returns the paste action.
137          *
138          * @return org.eclipse.jface.action.IAction
139          */
140         public IAction getPasteAction() {
141                 return pasteAction;
142         }
143         
144         /**
145          * Returns the web editor input, if available.
146          *
147          * @return org.eclipse.webbrowser.IWebBrowserEditorInput
148          */
149         protected IWebBrowserEditorInput getWebBrowserEditorInput() {
150                 IEditorInput input = getEditorInput();
151                 if (input instanceof IWebBrowserEditorInput)
152                         return (IWebBrowserEditorInput) input;
153                 return null;
154         }
155         
156         /* (non-Javadoc)
157          * Sets the cursor and selection state for this editor to the passage defined
158          * by the given marker.
159          * <p>
160          * Subclasses may override.  For greater details, see <code>IEditorPart</code>
161          * </p>
162          *
163          * @see IEditorPart
164          */
165         public void gotoMarker(IMarker marker) { }
166         
167         /* (non-Javadoc)
168          * Initializes the editor part with a site and input.
169          * <p>
170          * Subclasses of <code>EditorPart</code> must implement this method.  Within
171          * the implementation subclasses should verify that the input type is acceptable
172          * and then save the site and input.  Here is sample code:
173          * </p>
174          * <pre>
175          *              if (!(input instanceof IFileEditorInput))
176          *                      throw new PartInitException("Invalid Input: Must be IFileEditorInput");
177          *              setSite(site);
178          *              setInput(editorInput);
179          * </pre>
180          */
181         public void init(IEditorSite site, IEditorInput input) {
182                 Trace.trace(Trace.FINEST, "Opening browser: " + input);
183                 if (input instanceof IFileEditorInput) {
184                         IFileEditorInput fei = (IFileEditorInput) input;
185                         IFile file = fei.getFile();
186                         URL url = null;
187                         try {
188                                 if (file != null && file.exists())
189                                         url = file.getLocation().toFile().toURL();
190                         } catch (Exception e) {
191                                 Trace.trace(Trace.SEVERE, "Error getting URL to file");
192                         }
193                         addResourceListener(file);
194                         input = new WebBrowserEditorInput(url, WebBrowserEditorInput.SHOW_ALL | WebBrowserEditorInput.SAVE_URL);
195                 }
196                 if (input instanceof IWebBrowserEditorInput) {
197                         IWebBrowserEditorInput wbei = (IWebBrowserEditorInput) input;
198                         initialURL = null;
199                         if (wbei.getURL() != null)
200                                 initialURL = wbei.getURL().toExternalForm();
201                         if (webBrowser != null) {
202                                 webBrowser.setURL(initialURL);
203                                 site.getWorkbenchWindow().getActivePage().bringToTop(this);
204                         }
205         
206                         setPartName(wbei.getName());
207                         setTitleToolTip(wbei.getToolTipText());
208
209                         Image oldImage = image;
210                         ImageDescriptor id = wbei.getImageDescriptor();
211                         image = id.createImage();
212
213                         setTitleImage(image);
214                         if (oldImage != null && !oldImage.isDisposed())
215                                 oldImage.dispose();
216                 }
217                 setSite(site);
218                 setInput(input);
219         }
220         
221         /* (non-Javadoc)
222          * Returns whether the contents of this editor have changed since the last save
223          * operation.
224          * <p>
225          * Subclasses must override this method to implement the open-save-close lifecycle
226          * for an editor.  For greater details, see <code>IEditorPart</code>
227          * </p>
228          *
229          * @see IEditorPart
230          */
231         public boolean isDirty() {
232                 return false;
233         }
234         
235         /* (non-Javadoc)
236          * Returns whether the "save as" operation is supported by this editor.
237          * <p>
238          * Subclasses must override this method to implement the open-save-close lifecycle
239          * for an editor.  For greater details, see <code>IEditorPart</code>
240          * </p>
241          *
242          * @see IEditorPart
243          */
244         public boolean isSaveAsAllowed() {
245                 return false;
246         }
247         
248         /**
249          * Returns true if this editor has a toolbar.
250          *
251          * @return boolean
252          */
253         public boolean isToolbarVisible() {
254                 IWebBrowserEditorInput input = getWebBrowserEditorInput();
255                 if (input == null || input.isToolbarVisible())
256                         return true;
257                 else
258                         return false;
259         }
260         
261         /**
262          * Open the input in the internal Web browser.
263          */
264         public static void open(IWebBrowserEditorInput input) {
265                 IWorkbenchWindow workbenchWindow = WebBrowserUIPlugin.getInstance().getWorkbench().getActiveWorkbenchWindow();
266                 IWorkbenchPage page = workbenchWindow.getActivePage();
267
268                 try {
269                         IEditorReference[] editors = page.getEditorReferences();
270                         int size = editors.length;
271                         for (int i = 0; i < size; i++) {
272                                 if (WEB_BROWSER_EDITOR_ID.equals(editors[i].getId())) {
273                                         IEditorPart editor = editors[i].getEditor(true);
274                                         if (editor != null && editor instanceof WebBrowserEditor) {
275                                                 WebBrowserEditor webEditor = (WebBrowserEditor) editor;
276                                                 if (input.canReplaceInput(webEditor.getWebBrowserEditorInput())) {
277                                                         editor.init(editor.getEditorSite(), input);
278                                                         return;
279                                                 }
280                                         }
281                                 }
282                         }
283                         
284                         page.openEditor(input, WebBrowserEditor.WEB_BROWSER_EDITOR_ID);
285                 } catch (Exception e) {
286                         Trace.trace(Trace.SEVERE, "Error opening Web browser", e);
287                 }
288         }
289         
290         /**
291          * Asks this part to take focus within the workbench.
292          * <p>
293          * Clients should not call this method (the workbench calls this method at
294          * appropriate times).
295          * </p>
296          */
297         public void setFocus() {
298                 if (webBrowser != null) {
299                         if (webBrowser.combo != null)
300                                 webBrowser.combo.setFocus();
301                         else
302                                 webBrowser.browser.setFocus();
303                         webBrowser.updateHistory();
304                 }
305         }
306         
307         /**
308          * Update the actions.
309          */
310         protected void updateActions() {
311                 if (cutAction != null)
312                         cutAction.update();
313                 if (copyAction != null)
314                         copyAction.update();
315                 if (pasteAction != null)
316                         pasteAction.update();
317         }
318
319         /**
320          * Close the editor correctly.
321          */
322         protected void closeEditor() {
323                 Display.getDefault().asyncExec(new Runnable() {
324                         public void run() {
325                                 getEditorSite().getPage().closeEditor(WebBrowserEditor.this, false);
326                         }
327                 });
328         }
329         
330         /**
331          * Adds a resource change listener to see if the file is deleted.
332          */
333         protected void addResourceListener(final IResource resource) {
334                 if (resource == null)
335                         return;
336         
337                 resourceListener = new IResourceChangeListener() {
338                         public void resourceChanged(IResourceChangeEvent event) {
339                                 try {
340                                         event.getDelta().accept(new IResourceDeltaVisitor() {
341                                                 public boolean visit(IResourceDelta delta) {
342                                                         IResource res = delta.getResource();
343                                                                                                                 
344                                                         if (res == null || !res.equals(resource))
345                                                                 return true;
346
347                                                         if (delta.getKind() != IResourceDelta.REMOVED)
348                                                                 return true;
349                                                         
350                                                         Display.getDefault().asyncExec(new Runnable() {
351                                                                 public void run() {
352                                                                         String title = WebBrowserUIPlugin.getResource("%dialogResourceDeletedTitle");
353                                                                         String message = WebBrowserUIPlugin.getResource("%dialogResourceDeletedMessage", resource.getName());
354                                                                         String[] labels = new String[] {WebBrowserUIPlugin.getResource("%dialogResourceDeletedIgnore"), IDialogConstants.CLOSE_LABEL};
355                                                                         MessageDialog dialog = new MessageDialog(getEditorSite().getShell(), title, null, message, MessageDialog.INFORMATION, labels, 0);
356
357                                                                         if (dialog.open() != 0)
358                                                                                 closeEditor();
359                                                                 }
360                                                         });
361                                                         return false;
362                                                 }
363                                         });
364                                 } catch (Exception e) {
365                                         Trace.trace(Trace.SEVERE, "Error listening for resource deletion", e);
366                                 }
367                         }
368                 };
369                 ResourcesPlugin.getWorkspace().addResourceChangeListener(resourceListener);
370         }
371 }