[160558] Screenshot feature for WSDL and XSD Editors
diff --git a/bundles/org.eclipse.wst.xsd.ui/icons/dtool16/capturescreen.gif b/bundles/org.eclipse.wst.xsd.ui/icons/dtool16/capturescreen.gif
new file mode 100644
index 0000000..dc43919
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsd.ui/icons/dtool16/capturescreen.gif
Binary files differ
diff --git a/bundles/org.eclipse.wst.xsd.ui/icons/etool16/capturescreen.gif b/bundles/org.eclipse.wst.xsd.ui/icons/etool16/capturescreen.gif
new file mode 100644
index 0000000..a372975
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsd.ui/icons/etool16/capturescreen.gif
Binary files differ
diff --git a/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/editor/XSDMultiPageEditorContributor.java b/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/editor/XSDMultiPageEditorContributor.java
index a2a8562..b595c7f 100644
--- a/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/editor/XSDMultiPageEditorContributor.java
+++ b/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/editor/XSDMultiPageEditorContributor.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2001, 2006 IBM Corporation and others.
+ * Copyright (c) 2001, 2007 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -20,6 +20,7 @@
 import org.eclipse.gef.ui.actions.ZoomComboContributionItem;
 import org.eclipse.gef.ui.actions.ZoomInRetargetAction;
 import org.eclipse.gef.ui.actions.ZoomOutRetargetAction;
+import org.eclipse.jface.action.Action;
 import org.eclipse.jface.action.IAction;
 import org.eclipse.jface.action.IMenuManager;
 import org.eclipse.jface.action.IToolBarManager;
@@ -40,6 +41,7 @@
 import org.eclipse.ui.texteditor.ITextEditorActionConstants;
 import org.eclipse.wst.sse.ui.internal.ISourceViewerActionBarContributor;
 import org.eclipse.wst.xsd.ui.internal.actions.IXSDToolbarAction;
+import org.eclipse.wst.xsd.ui.internal.adt.actions.CaptureScreenAction;
 import org.eclipse.wst.xsd.ui.internal.adt.actions.DeleteAction;
 
 /**
@@ -57,6 +59,7 @@
   protected List fPartListeners= new ArrayList();
   ZoomInRetargetAction zoomInRetargetAction;
   ZoomOutRetargetAction zoomOutRetargetAction;
+  Action captureScreenAction;
   ZoomComboContributionItem zoomComboContributionItem;
   /**
    * Creates a multi-page contributor.
@@ -67,6 +70,7 @@
     sourceViewerActionContributor = new SourcePageActionContributor();
     zoomInRetargetAction = new ZoomInRetargetAction();
     zoomOutRetargetAction = new ZoomOutRetargetAction();
+    captureScreenAction = new CaptureScreenAction();
     fPartListeners.add(zoomInRetargetAction);
     fPartListeners.add(zoomOutRetargetAction);
   }
@@ -203,6 +207,7 @@
 
     menu.add(zoomInRetargetAction);
     menu.add(zoomOutRetargetAction);
+    menu.add(captureScreenAction);
 
     menu.updateAll(true);
   }
@@ -221,6 +226,7 @@
     String[] zoomStrings = new String[] { ZoomManager.FIT_ALL, ZoomManager.FIT_HEIGHT, ZoomManager.FIT_WIDTH };
     zoomComboContributionItem = new ZoomComboContributionItem(getPage(), zoomStrings);
     manager.add(zoomComboContributionItem);
+    manager.add(captureScreenAction);
   }
   
   
diff --git a/bundles/org.eclipse.wst.xsd.ui/src-adt/org/eclipse/wst/xsd/ui/internal/adt/actions/CaptureScreenAction.java b/bundles/org.eclipse.wst.xsd.ui/src-adt/org/eclipse/wst/xsd/ui/internal/adt/actions/CaptureScreenAction.java
new file mode 100644
index 0000000..a746967
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsd.ui/src-adt/org/eclipse/wst/xsd/ui/internal/adt/actions/CaptureScreenAction.java
@@ -0,0 +1,237 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsd.ui.internal.adt.actions;
+
+import java.io.File;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.SWTGraphics;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.gef.GraphicalViewer;
+import org.eclipse.gef.LayerConstants;
+import org.eclipse.gef.editparts.LayerManager;
+import org.eclipse.gef.editparts.ScalableRootEditPart;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.ImageLoader;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.wst.xsd.ui.internal.adt.editor.Messages;
+import org.eclipse.wst.xsd.ui.internal.editor.XSDEditorPlugin;
+
+public class CaptureScreenAction extends Action
+{
+
+  private static String last_screen_capture_path = System.getProperty("user.home");
+  private static String last_screen_capture_file_name = Messages._UI_ACTION_CAPTURE_SCREEN_DEFAULT_FILE_NAME;
+  private static String last_screen_capture_file_extension = ".jpeg";
+
+  public CaptureScreenAction()
+  {
+    setText(Messages._UI_CAPTURE_SCREEN_ACTION_TEXT);
+    setToolTipText(Messages._UI_CAPTURE_SCREEN_ACTION_TOOLTIPTEXT);
+    setImageDescriptor(XSDEditorPlugin.getImageDescriptor("icons/etool16/capturescreen.gif"));
+  }
+
+  public void run()
+  {
+    ImageExporter imageExporter = new ImageExporter();
+    imageExporter.save(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor(), (GraphicalViewer) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor().getAdapter(GraphicalViewer.class));
+
+  }
+
+  public class ImageExporter
+  {
+    public boolean save(IEditorPart editorPart, GraphicalViewer viewer, String saveFilePath, int format)
+    {
+      Assert.isNotNull(editorPart, "null editorPart passed to ImageExporter.save"); //$NON-NLS-1$
+      Assert.isNotNull(viewer, "null viewer passed to ImageExporter.save"); //$NON-NLS-1$
+      Assert.isNotNull(saveFilePath, "null saveFilePath passed to ImageExporter.save"); //$NON-NLS-1$
+
+      if (format != SWT.IMAGE_BMP && format != SWT.IMAGE_JPEG && format != SWT.IMAGE_ICO)
+        throw new IllegalArgumentException(Messages._UI_ACTION_CAPTURE_SCREEN_FORMAT_NOT_SUPPORTED);
+
+      try
+      {
+        saveEditorContentsAsImage(editorPart, viewer, saveFilePath, format);
+      }
+      catch (Exception ex)
+      {
+        MessageDialog.openError(editorPart.getEditorSite().getShell(), Messages._UI_ACTION_CAPTURE_SCREEN_ERROR_TITLE, Messages._UI_ACTION_CAPTURE_SCREEN_ERROR_DESCRIPTION);
+        return false;
+      }
+
+      return true;
+    }
+
+    public boolean save(IEditorPart editorPart, GraphicalViewer viewer)
+    {
+      Assert.isNotNull(editorPart, "null editorPart passed to ImageExporter.save"); //$NON-NLS-1$
+      Assert.isNotNull(viewer, "null viewer passed to ImageExporter.save"); //$NON-NLS-1$
+
+      String saveFilePath = getSaveFilePath(editorPart, viewer, -1);
+      if (saveFilePath == null)
+        return false;
+
+      File file = new File(saveFilePath);
+      if (file.exists() && file.isFile())
+      {
+        if (!MessageDialog.openQuestion(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), Messages._UI_ACTION_CAPTURE_SCREEN_OVERWRITE_CONFIRMATION_QUESTION, Messages._UI_ACTION_CAPTURE_SCREEN_OVERWRITE_CONFIRMATION_1 + " "
+            + saveFilePath + " " + Messages._UI_ACTION_CAPTURE_SCREEN_OVERWRITE_CONFIRMATION_2))
+        {
+          return false;
+        }
+      }
+
+      int format = SWT.IMAGE_JPEG;
+      if (saveFilePath.endsWith(".jpeg")) //$NON-NLS-1$
+        format = SWT.IMAGE_JPEG;
+      else if (saveFilePath.endsWith(".bmp")) //$NON-NLS-1$
+        format = SWT.IMAGE_BMP;
+      else if (saveFilePath.endsWith(".ico")) //$NON-NLS-1$
+        format = SWT.IMAGE_ICO;
+      else if (saveFilePath.endsWith(".png")) //$NON-NLS-1$
+        format = SWT.IMAGE_PNG;
+      else if (saveFilePath.endsWith(".gif")) //$NON-NLS-1$
+        format = SWT.IMAGE_GIF;
+      else if (saveFilePath.endsWith(".tiff")) //$NON-NLS-1$
+        format = SWT.IMAGE_TIFF;
+
+      return save(editorPart, viewer, saveFilePath, format);
+
+    }
+
+    private String getSaveFilePath(IEditorPart editorPart, GraphicalViewer viewer, int format)
+    {
+      String filePath;
+
+      FileDialog fileDialog = new FileDialog(editorPart.getEditorSite().getShell(), SWT.SAVE);
+
+      String[] filterExtensions = new String[] { "*.jpeg", "*.bmp", "*.tif" /*
+                                                                             * ,"*.ico",
+                                                                             * "*.png",
+                                                                             * "*.gif"
+                                                                             */}; //$NON-NLS-1$  //$NON-NLS-1$  //$NON-NLS-1$
+      if (format == SWT.IMAGE_BMP)
+        filterExtensions = new String[] { "*.bmp" }; //$NON-NLS-1$
+      else if (format == SWT.IMAGE_JPEG)
+        filterExtensions = new String[] { "*.jpeg" }; //$NON-NLS-1$
+      else if (format == SWT.IMAGE_ICO)
+        filterExtensions = new String[] { "*.ico" }; //$NON-NLS-1$
+      else if (format == SWT.IMAGE_PNG)
+        filterExtensions = new String[] { "*.png" }; //$NON-NLS-1$
+      else if (format == SWT.IMAGE_GIF)
+        filterExtensions = new String[] { "*.gif" }; //$NON-NLS-1$
+      else if (format == SWT.IMAGE_TIFF)
+        filterExtensions = new String[] { "*.tiff" }; //$NON-NLS-1$
+
+      fileDialog.setFileName(obtainNextFileName());
+      fileDialog.setFilterExtensions(filterExtensions);
+
+      filePath = fileDialog.open();
+
+      last_screen_capture_path = fileDialog.getFilterPath();
+      String fileName = fileDialog.getFileName();
+      last_screen_capture_file_name = fileName.substring(0, fileName.indexOf('.'));
+      last_screen_capture_file_extension = fileName.substring(fileName.indexOf('.'));
+
+      return filePath;
+    }
+
+    private void saveEditorContentsAsImage(IEditorPart editorPart, GraphicalViewer viewer, String saveFilePath, int format)
+    {
+      /*
+       * 1. First get the figure whose visuals we want to save as image. So we
+       * would like to save the rooteditpart which actually hosts all the
+       * printable layers.
+       * 
+       * NOTE: ScalableRootEditPart manages layers and is registered
+       * graphicalviewer's editpartregistry with the key LayerManager.ID ...
+       * well that is because ScalableRootEditPart manages all layers that are
+       * hosted on a FigureCanvas. Many layers exist for doing different things
+       */
+      ScalableRootEditPart rootEditPart = (ScalableRootEditPart) viewer.getEditPartRegistry().get(LayerManager.ID);
+      IFigure rootFigure = ((LayerManager) rootEditPart).getLayer(LayerConstants.PRINTABLE_LAYERS);// rootEditPart.getFigure();
+      Rectangle rootFigureBounds = rootFigure.getBounds();
+
+      /*
+       * 2. Now we want to get the GC associated with the control on which all
+       * figures are painted by SWTGraphics. For that first get the SWT Control
+       * associated with the viewer on which the rooteditpart is set as contents
+       */
+      Control figureCanvas = viewer.getControl();
+      GC figureCanvasGC = new GC(figureCanvas);
+
+      /*
+       * 3. Create a new Graphics for an Image onto which we want to paint
+       * rootFigure
+       */
+      Image img = new Image(null, rootFigureBounds.width, rootFigureBounds.height);
+      GC imageGC = new GC(img);
+      imageGC.setBackground(figureCanvasGC.getBackground());
+      imageGC.setForeground(figureCanvasGC.getForeground());
+      imageGC.setFont(figureCanvasGC.getFont());
+      imageGC.setLineStyle(figureCanvasGC.getLineStyle());
+      imageGC.setLineWidth(figureCanvasGC.getLineWidth());
+      imageGC.setXORMode(figureCanvasGC.getXORMode());
+      Graphics imgGraphics = new SWTGraphics(imageGC);
+
+      /* 4. Draw rootFigure onto image. After that image will be ready for save */
+      rootFigure.paint(imgGraphics);
+
+      /* 5. Save image */
+      ImageData[] imgData = new ImageData[1];
+      imgData[0] = img.getImageData();
+
+      ImageLoader imgLoader = new ImageLoader();
+      imgLoader.data = imgData;
+      imgLoader.save(saveFilePath, format);
+
+      /* release OS resources */
+      figureCanvasGC.dispose();
+      imageGC.dispose();
+      img.dispose();
+
+    }
+
+    String obtainNextFileName()
+    {
+
+      int aux = last_screen_capture_file_name.length() - 1;
+      while (Character.isDigit(last_screen_capture_file_name.charAt(aux)))
+      {
+        aux--;
+      }
+
+      String nonNumeratedfileName = last_screen_capture_file_name.substring(0, aux + 1);
+      String filePath = last_screen_capture_path + System.getProperty("file.separator") + nonNumeratedfileName + last_screen_capture_file_extension;
+
+      int counter = 1;
+      File file = new File(filePath);
+      while (file.exists())
+      {
+        filePath = last_screen_capture_path + System.getProperty("file.separator") + nonNumeratedfileName + counter++ + last_screen_capture_file_extension;
+        file = new File(filePath);
+      }
+
+      return filePath;
+    }
+
+  }
+}
diff --git a/bundles/org.eclipse.wst.xsd.ui/src-adt/org/eclipse/wst/xsd/ui/internal/adt/editor/Messages.java b/bundles/org.eclipse.wst.xsd.ui/src-adt/org/eclipse/wst/xsd/ui/internal/adt/editor/Messages.java
index bacb0b9..7fb195e 100644
--- a/bundles/org.eclipse.wst.xsd.ui/src-adt/org/eclipse/wst/xsd/ui/internal/adt/editor/Messages.java
+++ b/bundles/org.eclipse.wst.xsd.ui/src-adt/org/eclipse/wst/xsd/ui/internal/adt/editor/Messages.java
@@ -38,4 +38,13 @@
   public static String _UI_LABEL_SOURCE;
   public static String _UI_LABEL_VIEW;
   public static String _UI_HOVER_VIEW_MODE_DESCRIPTION;
+  public static String _UI_ACTION_CAPTURE_SCREEN_OVERWRITE_CONFIRMATION_QUESTION;
+  public static String _UI_ACTION_CAPTURE_SCREEN_OVERWRITE_CONFIRMATION_1;
+  public static String _UI_ACTION_CAPTURE_SCREEN_OVERWRITE_CONFIRMATION_2;
+  public static String _UI_ACTION_CAPTURE_SCREEN_ERROR_TITLE;
+  public static String _UI_ACTION_CAPTURE_SCREEN_ERROR_DESCRIPTION;
+  public static String _UI_ACTION_CAPTURE_SCREEN_FORMAT_NOT_SUPPORTED;
+  public static String _UI_CAPTURE_SCREEN_ACTION_TEXT;
+  public static String _UI_CAPTURE_SCREEN_ACTION_TOOLTIPTEXT;
+  public static String _UI_ACTION_CAPTURE_SCREEN_DEFAULT_FILE_NAME;
 }
diff --git a/bundles/org.eclipse.wst.xsd.ui/src-adt/org/eclipse/wst/xsd/ui/internal/adt/editor/messages.properties b/bundles/org.eclipse.wst.xsd.ui/src-adt/org/eclipse/wst/xsd/ui/internal/adt/editor/messages.properties
index 43cc209..12aec32 100644
--- a/bundles/org.eclipse.wst.xsd.ui/src-adt/org/eclipse/wst/xsd/ui/internal/adt/editor/messages.properties
+++ b/bundles/org.eclipse.wst.xsd.ui/src-adt/org/eclipse/wst/xsd/ui/internal/adt/editor/messages.properties
@@ -21,4 +21,13 @@
 _UI_ACTION_NEW=New...
 _UI_ACTION_ADD_FIELD=Add Field
 _UI_LABEL_VIEW=View:
-_UI_HOVER_VIEW_MODE_DESCRIPTION=Change the view mode of the editor
\ No newline at end of file
+_UI_HOVER_VIEW_MODE_DESCRIPTION=Change the view mode of the editor
+_UI_ACTION_CAPTURE_SCREEN_OVERWRITE_CONFIRMATION_QUESTION=Question
+_UI_ACTION_CAPTURE_SCREEN_OVERWRITE_CONFIRMATION_1=The file
+_UI_ACTION_CAPTURE_SCREEN_OVERWRITE_CONFIRMATION_2=already exists. Do you want to replace the existing file?
+_UI_ACTION_CAPTURE_SCREEN_ERROR_TITLE=Error
+_UI_ACTION_CAPTURE_SCREEN_ERROR_DESCRIPTION=Could not save editor contents
+_UI_ACTION_CAPTURE_SCREEN_FORMAT_NOT_SUPPORTED=Format not supported
+_UI_CAPTURE_SCREEN_ACTION_TEXT = Capture screen
+_UI_CAPTURE_SCREEN_ACTION_TOOLTIPTEXT = Capture screen
+_UI_ACTION_CAPTURE_SCREEN_DEFAULT_FILE_NAME = ScreenCapture
\ No newline at end of file