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
9 * IBM - Initial API and implementation
11 package org.eclipse.webbrowser.internal;
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.*;
27 * An integrated Web browser, defined as an editor to make
28 * better use of the desktop.
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;
36 protected TextAction cutAction;
37 protected TextAction copyAction;
38 protected TextAction pasteAction;
40 protected IResourceChangeListener resourceListener;
43 * WebBrowserEditor constructor comment.
45 public WebBrowserEditor() {
50 * Creates the SWT controls for this workbench part.
52 * Clients should not call this method (the workbench calls this method at
56 * For implementors this is a multi-step process:
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>
67 * @param parent the parent control
69 public void createPartControl(Composite parent) {
70 IWebBrowserEditorInput input = getWebBrowserEditorInput();
73 if (input == null || input.isToolbarVisible() == false)
74 webBrowser = new WebBrowser(parent, false, input.isStatusbarVisible());
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);
82 webBrowser.setURL(initialURL);
83 webBrowser.editor = this;
86 public void dispose() {
87 if (image != null && !image.isDisposed())
91 if (resourceListener != null)
92 ResourcesPlugin.getWorkspace().removeResourceChangeListener(resourceListener);
96 * Saves the contents of this editor.
98 * Subclasses must override this method to implement the open-save-close lifecycle
99 * for an editor. For greater details, see <code>IEditorPart</code>
104 public void doSave(IProgressMonitor monitor) { }
107 * Saves the contents of this editor to another object.
109 * Subclasses must override this method to implement the open-save-close lifecycle
110 * for an editor. For greater details, see <code>IEditorPart</code>
115 public void doSaveAs() { }
118 * Returns the copy action.
120 * @return org.eclipse.jface.action.IAction
122 public IAction getCopyAction() {
127 * Returns the cut action.
129 * @return org.eclipse.jface.action.IAction
131 public IAction getCutAction() {
136 * Returns the paste action.
138 * @return org.eclipse.jface.action.IAction
140 public IAction getPasteAction() {
145 * Returns the web editor input, if available.
147 * @return org.eclipse.webbrowser.IWebBrowserEditorInput
149 protected IWebBrowserEditorInput getWebBrowserEditorInput() {
150 IEditorInput input = getEditorInput();
151 if (input instanceof IWebBrowserEditorInput)
152 return (IWebBrowserEditorInput) input;
157 * Sets the cursor and selection state for this editor to the passage defined
158 * by the given marker.
160 * Subclasses may override. For greater details, see <code>IEditorPart</code>
165 public void gotoMarker(IMarker marker) { }
168 * Initializes the editor part with a site and input.
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:
175 * if (!(input instanceof IFileEditorInput))
176 * throw new PartInitException("Invalid Input: Must be IFileEditorInput");
178 * setInput(editorInput);
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();
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");
193 addResourceListener(file);
194 input = new WebBrowserEditorInput(url, WebBrowserEditorInput.SHOW_ALL | WebBrowserEditorInput.SAVE_URL);
196 if (input instanceof IWebBrowserEditorInput) {
197 IWebBrowserEditorInput wbei = (IWebBrowserEditorInput) input;
199 if (wbei.getURL() != null)
200 initialURL = wbei.getURL().toExternalForm();
201 if (webBrowser != null) {
202 webBrowser.setURL(initialURL);
203 site.getWorkbenchWindow().getActivePage().bringToTop(this);
206 setPartName(wbei.getName());
207 setTitleToolTip(wbei.getToolTipText());
209 Image oldImage = image;
210 ImageDescriptor id = wbei.getImageDescriptor();
211 image = id.createImage();
213 setTitleImage(image);
214 if (oldImage != null && !oldImage.isDisposed())
222 * Returns whether the contents of this editor have changed since the last save
225 * Subclasses must override this method to implement the open-save-close lifecycle
226 * for an editor. For greater details, see <code>IEditorPart</code>
231 public boolean isDirty() {
236 * Returns whether the "save as" operation is supported by this editor.
238 * Subclasses must override this method to implement the open-save-close lifecycle
239 * for an editor. For greater details, see <code>IEditorPart</code>
244 public boolean isSaveAsAllowed() {
249 * Returns true if this editor has a toolbar.
253 public boolean isToolbarVisible() {
254 IWebBrowserEditorInput input = getWebBrowserEditorInput();
255 if (input == null || input.isToolbarVisible())
262 * Open the input in the internal Web browser.
264 public static void open(IWebBrowserEditorInput input) {
265 IWorkbenchWindow workbenchWindow = WebBrowserUIPlugin.getInstance().getWorkbench().getActiveWorkbenchWindow();
266 IWorkbenchPage page = workbenchWindow.getActivePage();
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);
284 page.openEditor(input, WebBrowserEditor.WEB_BROWSER_EDITOR_ID);
285 } catch (Exception e) {
286 Trace.trace(Trace.SEVERE, "Error opening Web browser", e);
291 * Asks this part to take focus within the workbench.
293 * Clients should not call this method (the workbench calls this method at
294 * appropriate times).
297 public void setFocus() {
298 if (webBrowser != null) {
299 if (webBrowser.combo != null)
300 webBrowser.combo.setFocus();
302 webBrowser.browser.setFocus();
303 webBrowser.updateHistory();
308 * Update the actions.
310 protected void updateActions() {
311 if (cutAction != null)
313 if (copyAction != null)
315 if (pasteAction != null)
316 pasteAction.update();
320 * Close the editor correctly.
322 protected void closeEditor() {
323 Display.getDefault().asyncExec(new Runnable() {
325 getEditorSite().getPage().closeEditor(WebBrowserEditor.this, false);
331 * Adds a resource change listener to see if the file is deleted.
333 protected void addResourceListener(final IResource resource) {
334 if (resource == null)
337 resourceListener = new IResourceChangeListener() {
338 public void resourceChanged(IResourceChangeEvent event) {
340 event.getDelta().accept(new IResourceDeltaVisitor() {
341 public boolean visit(IResourceDelta delta) {
342 IResource res = delta.getResource();
344 if (res == null || !res.equals(resource))
347 if (delta.getKind() != IResourceDelta.REMOVED)
350 Display.getDefault().asyncExec(new Runnable() {
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);
357 if (dialog.open() != 0)
364 } catch (Exception e) {
365 Trace.trace(Trace.SEVERE, "Error listening for resource deletion", e);
369 ResourcesPlugin.getWorkspace().addResourceChangeListener(resourceListener);