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);