Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomasz Zarna2011-10-13 11:36:27 +0000
committerTomasz Zarna2011-10-13 11:36:27 +0000
commitf0e53ee2640b02d1f95f87dfcfa88331c3336845 (patch)
tree666e298f81221c128f3c0249c32154b1aef93861 /bundles/org.eclipse.compare.win32
parente4281ecfd04ac79545ba778419a1cfa257818d4c (diff)
downloadeclipse.platform.team-f0e53ee2640b02d1f95f87dfcfa88331c3336845.tar.gz
eclipse.platform.team-f0e53ee2640b02d1f95f87dfcfa88331c3336845.tar.xz
eclipse.platform.team-f0e53ee2640b02d1f95f87dfcfa88331c3336845.zip
bug 359032: Move plugins under bundles/org.eclipse.compare/plugins/ to
bundles/
Diffstat (limited to 'bundles/org.eclipse.compare.win32')
-rw-r--r--bundles/org.eclipse.compare.win32/.classpath7
-rw-r--r--bundles/org.eclipse.compare.win32/.project34
-rw-r--r--bundles/org.eclipse.compare.win32/.settings/org.eclipse.core.runtime.prefs2
-rw-r--r--bundles/org.eclipse.compare.win32/.settings/org.eclipse.jdt.core.prefs23
-rw-r--r--bundles/org.eclipse.compare.win32/.settings/org.eclipse.jdt.launching.prefs3
-rw-r--r--bundles/org.eclipse.compare.win32/META-INF/MANIFEST.MF19
-rw-r--r--bundles/org.eclipse.compare.win32/about.html28
-rw-r--r--bundles/org.eclipse.compare.win32/build.properties19
-rw-r--r--bundles/org.eclipse.compare.win32/icons/full/dlcl16/save.gifbin0 -> 378 bytes
-rw-r--r--bundles/org.eclipse.compare.win32/icons/full/elcl16/editor_area.gifbin0 -> 612 bytes
-rw-r--r--bundles/org.eclipse.compare.win32/icons/full/elcl16/save.gifbin0 -> 639 bytes
-rw-r--r--bundles/org.eclipse.compare.win32/plugin.properties17
-rw-r--r--bundles/org.eclipse.compare.win32/plugin.xml36
-rw-r--r--bundles/org.eclipse.compare.win32/src/org/eclipse/compare/internal/win32/AbstractMergeViewer.java288
-rw-r--r--bundles/org.eclipse.compare.win32/src/org/eclipse/compare/internal/win32/Activator.java66
-rw-r--r--bundles/org.eclipse.compare.win32/src/org/eclipse/compare/internal/win32/CompareWin32Messages.java37
-rw-r--r--bundles/org.eclipse.compare.win32/src/org/eclipse/compare/internal/win32/WordComparison.java480
-rw-r--r--bundles/org.eclipse.compare.win32/src/org/eclipse/compare/internal/win32/WordMergeViewer.java472
-rw-r--r--bundles/org.eclipse.compare.win32/src/org/eclipse/compare/internal/win32/WordMergeViewer.properties18
-rw-r--r--bundles/org.eclipse.compare.win32/src/org/eclipse/compare/internal/win32/WordViewerCreator.java29
-rw-r--r--bundles/org.eclipse.compare.win32/src/org/eclipse/compare/internal/win32/messages.properties25
21 files changed, 1603 insertions, 0 deletions
diff --git a/bundles/org.eclipse.compare.win32/.classpath b/bundles/org.eclipse.compare.win32/.classpath
new file mode 100644
index 000000000..2fbb7a23e
--- /dev/null
+++ b/bundles/org.eclipse.compare.win32/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.4"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.compare.win32/.project b/bundles/org.eclipse.compare.win32/.project
new file mode 100644
index 000000000..dd687751b
--- /dev/null
+++ b/bundles/org.eclipse.compare.win32/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.compare.win32</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
+ </natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.compare.win32/.settings/org.eclipse.core.runtime.prefs b/bundles/org.eclipse.compare.win32/.settings/org.eclipse.core.runtime.prefs
new file mode 100644
index 000000000..c522e1f4a
--- /dev/null
+++ b/bundles/org.eclipse.compare.win32/.settings/org.eclipse.core.runtime.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+line.separator=\n
diff --git a/bundles/org.eclipse.compare.win32/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.compare.win32/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..32a523dbe
--- /dev/null
+++ b/bundles/org.eclipse.compare.win32/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,23 @@
+#Tue Feb 01 14:37:12 CET 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.builder.cleanOutputFolder=clean
+org.eclipse.jdt.core.builder.duplicateResourceTask=warning
+org.eclipse.jdt.core.builder.invalidClasspath=abort
+org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore
+org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch
+org.eclipse.jdt.core.circularClasspath=error
+org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
+org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.4
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.maxProblemPerUnit=100
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning
+org.eclipse.jdt.core.compiler.source=1.3
+org.eclipse.jdt.core.incompatibleJDKLevel=ignore
+org.eclipse.jdt.core.incompleteClasspath=error
diff --git a/bundles/org.eclipse.compare.win32/.settings/org.eclipse.jdt.launching.prefs b/bundles/org.eclipse.compare.win32/.settings/org.eclipse.jdt.launching.prefs
new file mode 100644
index 000000000..44fca4e83
--- /dev/null
+++ b/bundles/org.eclipse.compare.win32/.settings/org.eclipse.jdt.launching.prefs
@@ -0,0 +1,3 @@
+#Tue Feb 01 14:37:12 CET 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=error
diff --git a/bundles/org.eclipse.compare.win32/META-INF/MANIFEST.MF b/bundles/org.eclipse.compare.win32/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..9e6ffa1ed
--- /dev/null
+++ b/bundles/org.eclipse.compare.win32/META-INF/MANIFEST.MF
@@ -0,0 +1,19 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.compare.win32;singleton:=true
+Bundle-Version: 1.0.200.qualifier
+Bundle-Vendor: %providerName
+Bundle-RequiredExecutionEnvironment: J2SE-1.4
+Eclipse-PlatformFilter: (osgi.os=win32)
+Require-Bundle: org.eclipse.compare;bundle-version="[3.5.0,4.0.0)",
+ org.eclipse.core.filesystem;bundle-version="[1.2.0,2.0.0)",
+ org.eclipse.ui.forms;bundle-version="[3.4.0,4.0.0)",
+ org.eclipse.ui.workbench;bundle-version="[3.5.0,4.0.0)",
+ org.eclipse.jface;bundle-version="[3.5.0,4.0.0)",
+ org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)",
+ org.eclipse.core.resources;bundle-version="[3.5.0,4.0.0)"
+Export-Package: org.eclipse.compare.internal.win32;x-internal:=true
+Bundle-Activator: org.eclipse.compare.internal.win32.Activator
+Bundle-ActivationPolicy: lazy
+Bundle-Localization: plugin
diff --git a/bundles/org.eclipse.compare.win32/about.html b/bundles/org.eclipse.compare.win32/about.html
new file mode 100644
index 000000000..460233046
--- /dev/null
+++ b/bundles/org.eclipse.compare.win32/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>June 2, 2006</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+</body>
+</html> \ No newline at end of file
diff --git a/bundles/org.eclipse.compare.win32/build.properties b/bundles/org.eclipse.compare.win32/build.properties
new file mode 100644
index 000000000..1b473f7ff
--- /dev/null
+++ b/bundles/org.eclipse.compare.win32/build.properties
@@ -0,0 +1,19 @@
+###############################################################################
+# Copyright (c) 2008, 2009 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
+###############################################################################
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ icons/,\
+ about.html,\
+ plugin.properties
+src.includes = about.html
diff --git a/bundles/org.eclipse.compare.win32/icons/full/dlcl16/save.gif b/bundles/org.eclipse.compare.win32/icons/full/dlcl16/save.gif
new file mode 100644
index 000000000..ad505a9c2
--- /dev/null
+++ b/bundles/org.eclipse.compare.win32/icons/full/dlcl16/save.gif
Binary files differ
diff --git a/bundles/org.eclipse.compare.win32/icons/full/elcl16/editor_area.gif b/bundles/org.eclipse.compare.win32/icons/full/elcl16/editor_area.gif
new file mode 100644
index 000000000..4b6b76831
--- /dev/null
+++ b/bundles/org.eclipse.compare.win32/icons/full/elcl16/editor_area.gif
Binary files differ
diff --git a/bundles/org.eclipse.compare.win32/icons/full/elcl16/save.gif b/bundles/org.eclipse.compare.win32/icons/full/elcl16/save.gif
new file mode 100644
index 000000000..499dd0ca6
--- /dev/null
+++ b/bundles/org.eclipse.compare.win32/icons/full/elcl16/save.gif
Binary files differ
diff --git a/bundles/org.eclipse.compare.win32/plugin.properties b/bundles/org.eclipse.compare.win32/plugin.properties
new file mode 100644
index 000000000..5b550f1b4
--- /dev/null
+++ b/bundles/org.eclipse.compare.win32/plugin.properties
@@ -0,0 +1,17 @@
+###############################################################################
+# Copyright (c) 2009 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
+###############################################################################
+#
+# Resource strings for Compare Win32 Plug-in
+#
+pluginName = Compare Support for Word
+providerName = Eclipse.org
+
+wordDocumentContentTypeName = Word Document
diff --git a/bundles/org.eclipse.compare.win32/plugin.xml b/bundles/org.eclipse.compare.win32/plugin.xml
new file mode 100644
index 000000000..76b02ea6d
--- /dev/null
+++ b/bundles/org.eclipse.compare.win32/plugin.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?> <!--
+ Copyright (c) 2008, 2011 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
+ -->
+
+<plugin>
+ <extension
+ point="org.eclipse.compare.contentMergeViewers">
+ <viewer
+ class="org.eclipse.compare.internal.win32.WordViewerCreator"
+ extensions="doc"
+ id="org.eclipse.compare.wordMergeViewer">
+ </viewer>
+ <contentTypeBinding
+ contentMergeViewerId="org.eclipse.compare.wordMergeViewer"
+ contentTypeId="org.eclipse.compare.wordDoc">
+ </contentTypeBinding>
+ </extension>
+
+ <extension
+ point="org.eclipse.core.contenttype.contentTypes">
+ <content-type
+ file-extensions="doc, docx"
+ id="org.eclipse.compare.wordDoc"
+ name="%wordDocumentContentTypeName">
+ </content-type>
+ </extension>
+
+</plugin>
diff --git a/bundles/org.eclipse.compare.win32/src/org/eclipse/compare/internal/win32/AbstractMergeViewer.java b/bundles/org.eclipse.compare.win32/src/org/eclipse/compare/internal/win32/AbstractMergeViewer.java
new file mode 100644
index 000000000..a66f37104
--- /dev/null
+++ b/bundles/org.eclipse.compare.win32/src/org/eclipse/compare/internal/win32/AbstractMergeViewer.java
@@ -0,0 +1,288 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.compare.internal.win32;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
+
+import org.eclipse.compare.CompareConfiguration;
+import org.eclipse.compare.IEditableContent;
+import org.eclipse.compare.IResourceProvider;
+import org.eclipse.compare.IStreamContentAccessor;
+import org.eclipse.compare.ITypedElement;
+import org.eclipse.compare.structuremergeviewer.Differencer;
+import org.eclipse.compare.structuremergeviewer.ICompareInput;
+import org.eclipse.core.filesystem.EFS;
+import org.eclipse.core.filesystem.IFileStore;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * Abstract class that caches any remote contents in local so that external
+ * tools can be used to show a comparison.
+ */
+public abstract class AbstractMergeViewer extends Viewer {
+
+ private Object input;
+ private File leftFile;
+ private File rightFile;
+ private File resultFile;
+ private final CompareConfiguration configuration;
+
+ public AbstractMergeViewer(CompareConfiguration configuration) {
+ this.configuration = configuration;
+ }
+
+ public Object getInput() {
+ return input;
+ }
+
+ public ISelection getSelection() {
+ return StructuredSelection.EMPTY;
+ }
+
+ public void refresh() {
+ // Nothing to do
+ }
+
+ public void setInput(Object input) {
+ this.input = input;
+ reset();
+ }
+
+ protected void reset() {
+ if (leftFile != null && leftFile.exists()) {
+ leftFile.delete();
+ }
+ if (rightFile != null && rightFile.exists()) {
+ rightFile.delete();
+ }
+ if (resultFile != null && resultFile.exists()) {
+ resultFile.delete();
+ }
+ leftFile = null;
+ rightFile = null;
+ resultFile = null;
+ }
+
+ public void setSelection(ISelection selection, boolean reveal) {
+ // Nothing to do
+ }
+
+ protected boolean isOneSided() {
+ if (input instanceof ICompareInput) {
+ ICompareInput ci = (ICompareInput) input;
+ int type = ci.getKind() & Differencer.CHANGE_TYPE_MASK;
+ return type != Differencer.CHANGE;
+ }
+ return false;
+ }
+
+ protected File getFileForSingleSide() throws CoreException {
+ File file = getFileForLeft();
+ if (file != null && file.exists())
+ return file;
+ return getFileForRight();
+ }
+
+ protected File getFileForRight() throws CoreException {
+ if (rightFile != null)
+ return rightFile;
+ ICompareInput ci = getCompareInput();
+ if (ci != null) {
+ ITypedElement right = ci.getRight();
+ File file = getLocalFile(right);
+ if (file != null) {
+ return file;
+ }
+ rightFile = cacheContents(right);
+ return rightFile;
+ }
+ return null;
+ }
+
+ protected File getFileForLeft() throws CoreException {
+ if (leftFile != null)
+ return leftFile;
+ ICompareInput ci = getCompareInput();
+ if (ci != null) {
+ ITypedElement left = ci.getLeft();
+ File file = getLocalFile(left);
+ if (file != null) {
+ return file;
+ }
+ leftFile = cacheContents(left);
+ return leftFile;
+ }
+ return null;
+ }
+
+ protected File getResultFile() throws IOException {
+ if (resultFile != null)
+ return resultFile;
+ resultFile = File.createTempFile("merge", ".doc"); //$NON-NLS-1$ //$NON-NLS-2$
+ resultFile.deleteOnExit();
+ // Need to delete the file so that clients will know that the files doesn't exist yet
+ resultFile.delete();
+ return resultFile;
+ }
+
+ protected boolean hasResultFile() {
+ return resultFile != null;
+ }
+
+ private File cacheContents(ITypedElement element) throws CoreException {
+ if (element instanceof IStreamContentAccessor) {
+ IStreamContentAccessor sca = (IStreamContentAccessor) element;
+ InputStream contents = sca.getContents();
+ if (contents != null) {
+ try {
+ return createTempFile(contents);
+ } catch (IOException e) {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0, e.getMessage(), e));
+ } finally {
+ try {
+ contents.close();
+ } catch (IOException e) {
+ // Ignore
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ private File createTempFile(InputStream contents) throws IOException {
+ File file = File.createTempFile("compare", ".doc"); //$NON-NLS-1$ //$NON-NLS-2$
+ file.deleteOnExit();
+ OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
+ try {
+ byte[] buffer = new byte[1024];
+ int length;
+ while ((length = contents.read(buffer)) != -1) {
+ out.write(buffer, 0, length);
+ }
+ return file;
+ } finally {
+ out.close();
+ }
+ }
+
+ protected ICompareInput getCompareInput() {
+ if (input instanceof ICompareInput) {
+ return (ICompareInput) input;
+ }
+ return null;
+ }
+
+ protected File getLocalFile(ITypedElement left) throws CoreException {
+ IFile file = getEclipseFile(left);
+ if (file != null) {
+ URI uri = file.getLocationURI();
+ IFileStore store = EFS.getStore(uri);
+ if (store != null) {
+ return store.toLocalFile(EFS.NONE, null);
+ }
+ }
+ return null;
+ }
+
+ protected IFile getEclipseFile(Object element) {
+ if (element instanceof IResourceProvider) {
+ IResourceProvider rp = (IResourceProvider) element;
+ IResource resource = rp.getResource();
+ if (resource.getType() == IResource.FILE) {
+ return (IFile)resource;
+ }
+ }
+ if (element instanceof IAdaptable) {
+ IAdaptable a = (IAdaptable) element;
+ Object result = a.getAdapter(IResource.class);
+ if (result == null) {
+ result = a.getAdapter(IFile.class);
+ }
+ if (result instanceof IFile) {
+ return (IFile) result;
+ }
+ }
+ return null;
+ }
+
+ protected IEditableContent getSaveTarget() {
+ IEditableContent left = getEditableLeft();
+ IEditableContent right = getEditableRight();
+ if (left != null && right == null) {
+ return left;
+ }
+ if (left == null && right != null) {
+ return right;
+ }
+ return null;
+ }
+
+ private IEditableContent getEditableLeft() {
+ ICompareInput compareInput = getCompareInput();
+ if (compareInput != null) {
+ ITypedElement left = compareInput.getLeft();
+ if (left instanceof IEditableContent && configuration.isLeftEditable()) {
+ return (IEditableContent) left;
+ }
+ }
+ return null;
+ }
+
+ private IEditableContent getEditableRight() {
+ ICompareInput compareInput = getCompareInput();
+ if (compareInput != null) {
+ ITypedElement right = compareInput.getRight();
+ if (right instanceof IEditableContent && configuration.isRightEditable()) {
+ return (IEditableContent) right;
+
+ }
+ }
+ return null;
+ }
+
+ protected byte[] asBytes(File file) throws IOException {
+ InputStream in = new BufferedInputStream(new FileInputStream(file));
+ try {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ byte[] buffer = new byte[1024];
+ int length;
+ while ((length = in.read(buffer)) != -1) {
+ out.write(buffer, 0, length);
+ }
+ out.close();
+ return out.toByteArray();
+ } finally {
+ in.close();
+ }
+ }
+
+ public CompareConfiguration getConfiguration() {
+ return configuration;
+ }
+}
diff --git a/bundles/org.eclipse.compare.win32/src/org/eclipse/compare/internal/win32/Activator.java b/bundles/org.eclipse.compare.win32/src/org/eclipse/compare/internal/win32/Activator.java
new file mode 100644
index 000000000..7b935df48
--- /dev/null
+++ b/bundles/org.eclipse.compare.win32/src/org/eclipse/compare/internal/win32/Activator.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.compare.internal.win32;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.core.runtime.Status;
+import org.osgi.framework.BundleContext;
+
+public class Activator extends Plugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.eclipse.compare.win32";
+
+ // The shared instance
+ private static Activator plugin;
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+ public static void log(Throwable e) {
+ log(new Status(IStatus.ERROR, PLUGIN_ID, 0, "Internal error", e));
+ }
+
+ public static void log(IStatus status) {
+ getDefault().getLog().log(status);
+ }
+}
diff --git a/bundles/org.eclipse.compare.win32/src/org/eclipse/compare/internal/win32/CompareWin32Messages.java b/bundles/org.eclipse.compare.win32/src/org/eclipse/compare/internal/win32/CompareWin32Messages.java
new file mode 100644
index 000000000..80fc1254b
--- /dev/null
+++ b/bundles/org.eclipse.compare.win32/src/org/eclipse/compare/internal/win32/CompareWin32Messages.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.compare.internal.win32;
+
+import org.eclipse.osgi.util.NLS;
+
+public class CompareWin32Messages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.compare.internal.win32.messages"; //$NON-NLS-1$
+ public static String WordComparison_0;
+ public static String WordComparison_1;
+ public static String WordComparison_16;
+ public static String WordComparison_2;
+ public static String WordComparison_3;
+ public static String WordComparison_4;
+ public static String WordComparison_6;
+ public static String WordComparison_9;
+ public static String WordMergeViewer_1;
+ public static String WordMergeViewer_2;
+ public static String WordMergeViewer_3;
+ public static String WordMergeViewer_4;
+ public static String WordMergeViewer_5;
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, CompareWin32Messages.class);
+ }
+
+ private CompareWin32Messages() {
+ }
+}
diff --git a/bundles/org.eclipse.compare.win32/src/org/eclipse/compare/internal/win32/WordComparison.java b/bundles/org.eclipse.compare.win32/src/org/eclipse/compare/internal/win32/WordComparison.java
new file mode 100644
index 000000000..def6628bc
--- /dev/null
+++ b/bundles/org.eclipse.compare.win32/src/org/eclipse/compare/internal/win32/WordComparison.java
@@ -0,0 +1,480 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.compare.internal.win32;
+
+import java.io.File;
+import java.util.Vector;
+
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.ole.win32.OLE;
+import org.eclipse.swt.ole.win32.OleAutomation;
+import org.eclipse.swt.ole.win32.OleClientSite;
+import org.eclipse.swt.ole.win32.OleFrame;
+import org.eclipse.swt.ole.win32.Variant;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.IWorkbenchWindow;
+
+/**
+ * Class that manages a Word document comparison using OLE.
+ */
+public class WordComparison {
+
+ private final OleFrame frame;
+ private OleClientSite site;
+ private boolean inplace;
+ private OleAutomation document;
+
+ public WordComparison(Composite composite) {
+ frame = new OleFrame(composite, SWT.NONE);
+ }
+
+ // These helper methods facilitate writing the OLE apps
+ private static Variant invoke(OleAutomation auto, String command) {
+ return auto.invoke(property(auto, command), new Variant[0]);
+ }
+
+ private static Variant invoke(OleAutomation auto, OleAutomation reference, String command) {
+ return auto.invoke(property(auto, reference, command), new Variant[0]);
+ }
+
+ private static Variant invoke(OleAutomation auto, OleAutomation reference, String command, String value) {
+ return auto.invoke(property(auto, reference, command), new Variant[] { new Variant(value) });
+ }
+
+ private static Variant invoke(OleAutomation auto, String command, int value) {
+ return auto.invoke(property(auto, command), new Variant[] { new Variant(value) });
+ }
+
+ private static Variant invoke(OleAutomation auto, String command, String value) {
+ return auto.invoke(property(auto, command), new Variant[] { new Variant(value) });
+ }
+
+ private static Variant getVariantProperty(OleAutomation auto, String name) {
+ Variant varResult = auto.getProperty(property(auto, name));
+ if (varResult != null && varResult.getType() != OLE.VT_EMPTY) {
+ return varResult;
+ }
+ throw new SWTException(NLS.bind(CompareWin32Messages.WordComparison_0, name));
+ }
+
+ private static OleAutomation getAutomationProperty(OleAutomation auto, String name) {
+ Variant varResult = getVariantProperty(auto, name);
+ try {
+ OleAutomation automation = varResult.getAutomation();
+ if (automation != null)
+ return automation;
+ } finally {
+ varResult.dispose();
+ }
+ throw new SWTException(NLS.bind(CompareWin32Messages.WordComparison_1, name));
+ }
+
+ private static OleAutomation getAutomationResult(OleAutomation auto, String command, int value) {
+ Variant varResult = invoke(auto, command, value);
+ if (varResult != null) {
+ try {
+ OleAutomation result = varResult.getAutomation();
+ if (result != null)
+ return result;
+ } finally {
+ varResult.dispose();
+ }
+ }
+ throw new SWTException(NLS.bind(CompareWin32Messages.WordComparison_2, command, Integer.toString(value)));
+ }
+
+ private static OleAutomation getAutomationResult(OleAutomation auto, String command, String value) {
+ Variant varResult = invoke(auto, command, value);
+ if (varResult != null) {
+ try {
+ OleAutomation result = varResult.getAutomation();
+ if (result != null)
+ return result;
+ } finally {
+ varResult.dispose();
+ }
+ }
+ throw new SWTException(NLS.bind(CompareWin32Messages.WordComparison_3, command, value));
+ }
+
+
+ /**
+ * <p>This methods workarounds the feature in doc documents. Some properties are not accessible
+ * using names when a diff document is created. The workaround is to obtain the id of the
+ * method from an original document and use it in the newly created one.</p>
+ *
+ * <p>An exception is thrown if the id cannot be retrieved</p>
+ *
+ * Reference information for id assignment: <a href="
+ * http://msdn.microsoft.com/en-us/library/w7a36sdf%28VS.80%29.aspx">http://msdn.microsoft.com/en-us/library/w7a36sdf%28VS.80%29.aspx</a>
+ *
+ * @param auto - object from which we want to get the property, must not be <code>null</code>
+ * @param reference - an reference object from which the property will be obtained.
+ * @param name - the name of the property, must not be <code>null</code>
+ */
+ private static int property(OleAutomation auto, OleAutomation reference, String name) {
+ int[] ids = auto.getIDsOfNames(new String[] { name });
+ if (ids != null) {
+ return ids[0];
+ }
+ if(reference == null) throw new SWTException(NLS.bind(CompareWin32Messages.WordComparison_4, name)) ;
+
+ // the property was not retrieved at that point, try to get it from the reference object
+ ids = reference.getIDsOfNames(new String[] { name });
+ if (ids == null) {
+ throw new SWTException(NLS.bind(CompareWin32Messages.WordComparison_4, name));
+ }
+ return ids[0];
+ }
+
+ private static int property(OleAutomation auto, String name) {
+ int[] ids = auto.getIDsOfNames(new String[] { name });
+ if (ids == null) throw new SWTException(NLS.bind(CompareWin32Messages.WordComparison_4, name));
+ return ids[0];
+ }
+
+ private static boolean setProperty(OleAutomation auto, String name, boolean value) {
+ return auto.setProperty(property(auto, name), new Variant(value));
+ }
+
+ /**
+ * Open the file at the given path as a document in Word.
+ *
+ * @param filePath
+ * the path of the file containing the document
+ * @param inplace
+ * whether Word is to be opened in-place or in a separate window
+ * @throws SWTException
+ * if the document could not be opened for some reason
+ */
+ public void openDocument(String filePath, boolean inplace) throws SWTException {
+ resetSite(inplace ? filePath : null);
+ if (inplace) {
+ site.doVerb(OLE.OLEIVERB_SHOW);
+ } else {
+ OleAutomation application = createApplication();
+ try {
+ // Track the external document we just opened
+ document = openDocument(application, filePath);
+ setDocumentVisible(document, true);
+ } finally {
+ application.dispose();
+ }
+ }
+ }
+
+ /**
+ * Compares the base document with the revised document and saves the
+ * comparison in the working copy which can then be opened using
+ * openDocument.
+ *
+ * @param baseDocument
+ * the base document
+ * @param revisedDocument
+ * the revised document
+ * @param workingCopy
+ * the working copy (will be overwritten)
+ * @throws SWTException
+ * if an SWT error occurs
+ */
+ public void createWorkingCopy(String baseDocument, String revisedDocument, String workingCopy) throws SWTException {
+ resetSite(null);
+ OleAutomation application = createApplication();
+ try {
+ OleAutomation document = openDocument(application, revisedDocument);
+ try {
+ setDocumentVisible(document,false);
+ compareDocument(document, baseDocument, revisedDocument);
+ OleAutomation activeDocument = getActiveDocument(application);
+ try {
+ Variant varResult = invoke(activeDocument, document, "SaveAs", workingCopy); //$NON-NLS-1$
+ if (varResult == null)
+ throw new SWTException(NLS.bind(CompareWin32Messages.WordComparison_6, workingCopy));
+ varResult.dispose();
+ } finally {
+ closeDocument(activeDocument, document);
+ }
+ } finally {
+ closeDocument(document, null);
+ }
+ } finally {
+ try {
+ //Quit application without saving any changes
+ int [] ids = application.getIDsOfNames(new String [] {"Quit", "SaveChanges"});
+ final Variant wdDoNotSaveChanges = new Variant(0);
+ Variant varResult = application.invoke(ids[0], new Variant[]{ wdDoNotSaveChanges }, new int[] {ids[1]});
+ if (varResult != null) {
+ varResult.dispose();
+ }
+ } catch (SWTException e) {
+ // We don't want to throw the exception as we may mask another exception
+ Activator.log(e);
+ } finally {
+ application.dispose();
+ }
+ }
+ }
+
+ private void closeDocument(OleAutomation document, OleAutomation reference) {
+ // Close the first document: destination.Close()
+ try {
+ Variant varResult = invoke(document, reference, "Close"); //$NON-NLS-1$
+ if (varResult != null) {
+ varResult.dispose();
+ }
+ } catch (SWTException e) {
+ // We don't want to throw the exception as we may mask another
+ // exception
+ Activator.log(e);
+ } finally {
+ document.dispose();
+ }
+ }
+
+ private void compareDocument(OleAutomation document, String baseDocument, String revisedDocument) {
+ // Compare to the second document: compare = destination.Compare(p1)
+ Variant varResult = invoke(document, "Compare", baseDocument); //$NON-NLS-1$
+ if (varResult == null)
+ throw new SWTException(NLS.bind(CompareWin32Messages.WordComparison_9, baseDocument, revisedDocument));
+ varResult.dispose();
+ }
+
+ private boolean getDocumentDirty(OleAutomation document) {
+ // word.document.Saved
+ if (document != null) {
+ Variant variantProperty = getVariantProperty(document, "Saved"); //$NON-NLS-1$
+ if (variantProperty != null) {
+ try {
+ return !variantProperty.getBoolean();
+ } finally {
+ variantProperty.dispose();
+ }
+ }
+ }
+ return false;
+ }
+
+ private void setDocumentVisible(OleAutomation document, boolean visible) {
+ // Hide it: destination.Windows[0].Visible=0|1
+ OleAutomation windows = getAutomationProperty(document, "Windows"); //$NON-NLS-1$
+ try {
+ OleAutomation window = getAutomationResult(windows, "Item", 1); //$NON-NLS-1$
+ try {
+ setProperty(window, "Visible", visible); //$NON-NLS-1$
+ } finally {
+ window.dispose();
+ }
+ } finally {
+ windows.dispose();
+ }
+ }
+
+ private OleAutomation openDocument(OleAutomation application, String doc) {
+ // Open the first document: word.Documents.Open(p2)
+ OleAutomation documents = getAutomationProperty(application, "Documents"); //$NON-NLS-1$
+ try {
+ OleAutomation document = getAutomationResult(documents, "Open", doc); //$NON-NLS-1$
+ if (document == null) {
+ throw new SWTException(NLS.bind(CompareWin32Messages.WordComparison_16, doc));
+ }
+ return document;
+ } finally {
+ documents.dispose();
+ }
+ }
+
+ private OleAutomation getActiveDocument(OleAutomation application) {
+ return getAutomationProperty(application, "ActiveDocument"); //$NON-NLS-1$
+ }
+
+ /*
+ * Create a handle to the application
+ */
+ private OleAutomation createApplication() {
+ return new OleAutomation(site);
+ }
+
+ /*
+ * When opening a new comparison, we want to close any existing site
+ * and create a new one.
+ */
+ private void resetSite(String filePath) {
+ if (site != null && !site.isDisposed()) {
+ disposeSite();
+ }
+ inplace = filePath != null;
+ if (inplace) {
+ site = new OleClientSite(frame, SWT.NONE, "Word.Document", new File(filePath)); //$NON-NLS-1$
+ } else {
+ site = new OleClientSite(frame, SWT.NONE, "Word.Application"); //$NON-NLS-1$
+ }
+ }
+
+ private void disposeSite() {
+ if (document != null) {
+ closeDocument(document, null);
+ document = null;
+ OleAutomation application = createApplication();
+ try {
+ OleAutomation documents = getAutomationProperty(application, "Documents"); //$NON-NLS-1$
+ try {
+ Variant property = getVariantProperty(documents, "Count"); //$NON-NLS-1$
+ if (property != null) {
+ try {
+ if (property.getLong() == 0) {
+ // There are no other documents open so close the application
+ Variant result = invoke(application, "Quit"); //$NON-NLS-1$
+ if (result != null) {
+ result.dispose();
+ }
+ }
+ } finally {
+ property.dispose();
+ }
+ }
+ } finally {
+ documents.dispose();
+ }
+ } finally {
+ application.dispose();
+ }
+ }
+ site.dispose();
+ site = null;
+ }
+
+ public void saveAsDocument(String doc) {
+ if (site == null || site.isDisposed()) return;
+ if (inplace) {
+ site.deactivateInPlaceClient();
+ site.save(new File(doc), true);
+ site.doVerb(OLE.OLEIVERB_SHOW);
+ } else if (document != null) {
+ try {
+ Variant variant = invoke(document, "SaveAs", doc); //$NON-NLS-1$
+ if (variant != null) {
+ variant.dispose();
+ }
+ } catch (SWTException e) {
+ // Ignore since this probably means the document was closed by the user
+ }
+ }
+ }
+
+ /**
+ * Return the OLEFrame for the comparison document.
+ * @return the OLEFrame for the comparison document
+ */
+ public OleFrame getFrame() {
+ return frame;
+ }
+
+ /**
+ * Dispose of the comparison.
+ */
+ public void dispose() {
+ try {
+ disposeSite();
+ } finally {
+ if (!frame.isDisposed()) {
+ frame.dispose();
+ }
+ }
+ }
+
+ /**
+ * Return whether the comparison document is dirty. This method handles
+ * both an in-place document and a document opened in a separate window.
+ * @return weather the comparison document is dirty
+ */
+ public boolean isDirty() {
+ return (inplace && site != null && !site.isDisposed() && site.isDirty())
+ || (!inplace && getDocumentDirty(document));
+ }
+
+ /**
+ * Initialize the workbench menus for proper menu merging
+ * Copied from org.eclipse.ui.internal.editorsupport.win32OleEditor
+ */
+ protected void initializeWorkbenchMenus(IWorkbenchWindow window) {
+ //If there was an OLE Error or nothing has been created yet
+ if (frame == null || frame.isDisposed())
+ return;
+ // Get the browser menu bar. If one does not exist then
+ // create it.
+ Shell shell = frame.getShell();
+ Menu menuBar = shell.getMenuBar();
+ if (menuBar == null) {
+ menuBar = new Menu(shell, SWT.BAR);
+ shell.setMenuBar(menuBar);
+ }
+
+ // Swap the file and window menus.
+ MenuItem[] windowMenu = new MenuItem[1];
+ MenuItem[] fileMenu = new MenuItem[1];
+ Vector containerItems = new Vector();
+
+ for (int i = 0; i < menuBar.getItemCount(); i++) {
+ MenuItem item = menuBar.getItem(i);
+ String id = ""; //$NON-NLS-1$
+ if (item.getData() instanceof IMenuManager)
+ id = ((IMenuManager) item.getData()).getId();
+ if (id.equals(IWorkbenchActionConstants.M_FILE))
+ fileMenu[0] = item;
+ else if (id.equals(IWorkbenchActionConstants.M_WINDOW))
+ windowMenu[0] = item;
+ else {
+ if (window.isApplicationMenu(id)) {
+ containerItems.addElement(item);
+ }
+ }
+ }
+ MenuItem[] containerMenu = new MenuItem[containerItems.size()];
+ containerItems.copyInto(containerMenu);
+ frame.setFileMenus(fileMenu);
+ frame.setContainerMenus(containerMenu);
+ frame.setWindowMenus(windowMenu);
+ }
+
+ /**
+ * Return whether the comparison document is being shown in-place or in
+ * a separate window.
+ * @return whether the comparison document is being shown in-place or in
+ * a separate window
+ */
+ public boolean isInplace() {
+ return inplace;
+ }
+
+ /**
+ * Return whether the comparison document is open.
+ * @return whether the comparison document is open
+ */
+ public boolean isOpen() {
+ return site != null && !site.isDisposed();
+ }
+
+ /**
+ * Close any open documents
+ */
+ public void close() {
+ if (isOpen()) {
+ disposeSite();
+ }
+ }
+}
diff --git a/bundles/org.eclipse.compare.win32/src/org/eclipse/compare/internal/win32/WordMergeViewer.java b/bundles/org.eclipse.compare.win32/src/org/eclipse/compare/internal/win32/WordMergeViewer.java
new file mode 100644
index 000000000..ac17d303f
--- /dev/null
+++ b/bundles/org.eclipse.compare.win32/src/org/eclipse/compare/internal/win32/WordMergeViewer.java
@@ -0,0 +1,472 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.compare.internal.win32;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.eclipse.compare.CompareConfiguration;
+import org.eclipse.compare.CompareEditorInput;
+import org.eclipse.compare.CompareUI;
+import org.eclipse.compare.CompareViewerPane;
+import org.eclipse.compare.IEditableContent;
+import org.eclipse.compare.IPropertyChangeNotifier;
+import org.eclipse.compare.ITypedElement;
+import org.eclipse.compare.contentmergeviewer.IFlushable;
+import org.eclipse.compare.structuremergeviewer.Differencer;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.util.SafeRunnable;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.part.PageBook;
+
+public class WordMergeViewer extends AbstractMergeViewer implements IFlushable, IPropertyChangeNotifier {
+
+ private static final String RESOURCE_BUNDLE_NAME = "org.eclipse.compare.internal.win32.WordMergeViewer"; //$NON-NLS-1$
+
+ private FormToolkit formToolkit;
+ private PageBook composite;
+ private Composite docArea;
+ private Composite textArea;
+ private Label description;
+ private WordComparison wordArea;
+ private boolean isDirty;
+ private ListenerList listeners = new ListenerList(ListenerList.IDENTITY);
+ private Action saveAction;
+ private ResourceBundle resourceBundle;
+ private Action inplaceAction;
+ private long resultFileTimestamp = -1;
+
+ public WordMergeViewer(Composite parent, CompareConfiguration configuration) {
+ super(configuration);
+ createContentArea(parent);
+ getControl().addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ handleDispose();
+ }
+ });
+ getControl().setData(CompareUI.COMPARE_VIEWER_TITLE, CompareWin32Messages.WordMergeViewer_1);
+ IToolBarManager toolBarManager = CompareViewerPane.getToolBarManager(parent);
+ if (toolBarManager != null) {
+ toolBarManager.removeAll();
+ initializeToolbar(toolBarManager);
+ }
+ updateEnablements();
+ }
+
+ private void createContentArea(Composite parent) {
+ formToolkit = new FormToolkit(parent.getDisplay());
+ composite = new PageBook(parent, SWT.NONE);
+ createDocArea(composite);
+ createTextArea(composite);
+ }
+
+ private void initializeToolbar(IToolBarManager toolBarManager) {
+ toolBarManager.add(new Separator("modes")); //$NON-NLS-1$
+ toolBarManager.add(new Separator("file")); //$NON-NLS-1$
+ CompareConfiguration configuration = getConfiguration();
+ // For now, only support saving if one side is editable
+ if (configuration.isRightEditable() || configuration.isLeftEditable()
+ && (configuration.isRightEditable() != configuration.isLeftEditable())) {
+ saveAction = new Action() {
+ public void run() {
+ saveDocument();
+ }
+ };
+ initAction(saveAction, getResourceBundle(), "action.save."); //$NON-NLS-1$
+ toolBarManager.appendToGroup("file", saveAction); //$NON-NLS-1$
+ }
+
+ inplaceAction = new Action(CompareWin32Messages.WordMergeViewer_2, Action.AS_CHECK_BOX) {
+ public void run() {
+ toggleInplaceExternalState();
+ }
+ };
+ initAction(inplaceAction, getResourceBundle(), "action.inplace."); //$NON-NLS-1$
+ toolBarManager.appendToGroup("modes", inplaceAction); //$NON-NLS-1$
+
+ toolBarManager.update(true);
+ }
+
+ /*
+ * Initialize the given Action from a ResourceBundle.
+ */
+ private static void initAction(IAction a, ResourceBundle bundle, String prefix) {
+
+ String labelKey= "label"; //$NON-NLS-1$
+ String tooltipKey= "tooltip"; //$NON-NLS-1$
+ String imageKey= "image"; //$NON-NLS-1$
+ String descriptionKey= "description"; //$NON-NLS-1$
+
+ if (prefix != null && prefix.length() > 0) {
+ labelKey= prefix + labelKey;
+ tooltipKey= prefix + tooltipKey;
+ imageKey= prefix + imageKey;
+ descriptionKey= prefix + descriptionKey;
+ }
+
+ a.setText(getString(bundle, labelKey, labelKey));
+ a.setToolTipText(getString(bundle, tooltipKey, null));
+ a.setDescription(getString(bundle, descriptionKey, null));
+
+ String relPath= getString(bundle, imageKey, null);
+ if (relPath != null && relPath.trim().length() > 0) {
+
+ String dPath;
+ String ePath;
+
+ if (relPath.indexOf("/") >= 0) { //$NON-NLS-1$
+ String path= relPath.substring(1);
+ dPath= 'd' + path;
+ ePath= 'e' + path;
+ } else {
+ dPath= "dlcl16/" + relPath; //$NON-NLS-1$
+ ePath= "elcl16/" + relPath; //$NON-NLS-1$
+ }
+
+ ImageDescriptor id= getImageDescriptor(dPath); // we set the disabled image first (see PR 1GDDE87)
+ if (id != null)
+ a.setDisabledImageDescriptor(id);
+ id= getImageDescriptor(ePath);
+ if (id != null) {
+ a.setImageDescriptor(id);
+ a.setHoverImageDescriptor(id);
+ }
+ }
+ }
+
+ private static ImageDescriptor getImageDescriptor(String relativePath) {
+ IPath path= new Path("$nl$/icons/full/").append(relativePath);
+ URL url= FileLocator.find(Activator.getDefault().getBundle(), path, null);
+ if (url == null)
+ return null;
+ return ImageDescriptor.createFromURL(url);
+ }
+
+ private static String getString(ResourceBundle bundle, String key, String dfltValue) {
+
+ if (bundle != null) {
+ try {
+ return bundle.getString(key);
+ } catch (MissingResourceException x) {
+ // fall through
+ }
+ }
+ return dfltValue;
+ }
+
+ private ResourceBundle getResourceBundle() {
+ if (resourceBundle == null) {
+ resourceBundle = ResourceBundle.getBundle(RESOURCE_BUNDLE_NAME);
+ }
+ return resourceBundle;
+ }
+
+ private Composite createComposite(Composite parent) {
+ return formToolkit.createComposite(parent);
+ }
+
+ private void updateEnablements() {
+ if (saveAction != null)
+ saveAction.setEnabled(isDirty());
+ inplaceAction.setChecked(wordArea.isInplace());
+ inplaceAction.setEnabled(wordArea.isOpen());
+ }
+
+
+ private void createDocArea(PageBook book) {
+ docArea = createComposite(book);
+ docArea.setLayout(GridLayoutFactory.fillDefaults().create());
+ wordArea = new WordComparison(docArea);
+ IWorkbenchPart workbenchPart = getConfiguration().getContainer().getWorkbenchPart();
+ if (workbenchPart != null) {
+ wordArea.initializeWorkbenchMenus(workbenchPart.getSite().getWorkbenchWindow());
+ }
+ wordArea.getFrame().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ wordArea.getFrame().setBackground(formToolkit.getColors().getBackground());
+ updateDirtyFlag();
+ }
+
+ private void createTextArea(PageBook book) {
+ textArea = createComposite(book);
+ textArea.setLayout(GridLayoutFactory.fillDefaults().extendedMargins(10, 10, 10, 10).create());
+ description = formToolkit.createLabel(textArea, getTextDescription(), SWT.WRAP);
+ description.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ }
+
+ protected void saveDocument() {
+ try {
+ File result = getResultFile();
+ wordArea.saveAsDocument(result.getAbsolutePath());
+ // Forward the saved content to the save target
+ IEditableContent saveTarget = getSaveTarget();
+ if (saveTarget == null) {
+ if (MessageDialog.openQuestion(WordMergeViewer.this.composite.getShell(), "Save to File?", "The compare editor is not saveable. Would you like to save your changes to another file?")) {
+ FileDialog dialog = new FileDialog(WordMergeViewer.this.composite.getShell(), SWT.SAVE);
+ String filename = dialog.open();
+ if (filename != null) {
+ wordArea.saveAsDocument(filename);
+ }
+ }
+ } else {
+ synchronized (result) {
+ if (result.exists()) {
+ saveTarget.setContent(asBytes(result));
+ resultFileTimestamp = result.lastModified();
+ }
+ }
+ }
+ updateEnablements();
+ } catch (IOException e) {
+ ErrorDialog.openError(WordMergeViewer.this.composite.getShell(), null, null, new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0, e.getMessage(), e));
+ } catch (SWTException e) {
+ ErrorDialog.openError(WordMergeViewer.this.composite.getShell(), null, null, new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0, e.getMessage(), e));
+ }
+ }
+
+ public void flush(IProgressMonitor monitor) {
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ if (isReallyDirty())
+ saveDocument();
+ }
+ });
+ }
+
+
+ protected void toggleInplaceExternalState() {
+ BusyIndicator.showWhile(Display.getDefault(), new Runnable() {
+ public void run() {
+ try {
+ if (isReallyDirty()) {
+ // If the file is dirty, save the result file before switching so our changes are not lost
+ try {
+ File result = getResultFile();
+ wordArea.saveAsDocument(result.getAbsolutePath());
+ } catch (IOException e) {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0, e.getMessage(), e));
+ }
+ }
+ openComparison(!wordArea.isInplace());
+ } catch (CoreException e) {
+ ErrorDialog.openError(WordMergeViewer.this.composite.getShell(), null, null, e.getStatus());
+ Activator.log(e);
+ }
+ }
+ });
+ }
+
+ private boolean isReallyDirty() {
+ return isDirty() || wordArea.isDirty();
+ }
+
+ private void openComparison(boolean inplace) throws CoreException {
+ try {
+ if (isOneSided()) {
+ File file = getFileForSingleSide();
+ if (file != null) {
+ try {
+ wordArea.openDocument(file.getAbsolutePath(), inplace);
+ } catch (SWTException e) {
+ throw new CoreException(new Status(IStatus.ERROR,
+ Activator.PLUGIN_ID, NLS.bind(
+ CompareWin32Messages.WordComparison_16,
+ file.getAbsolutePath()), e));
+ }
+ }
+ } else {
+ File left = getFileForLeft();
+ File right = getFileForRight();
+ if (left != null && right != null) {
+ File result = getResultFile();
+ int direction = getCompareInput().getKind() & Differencer.DIRECTION_MASK;
+ File base, revised;
+ if (direction == Differencer.RIGHT) {
+ base = left;
+ revised = right;
+ } else {
+ base = right;
+ revised = left;
+ }
+ synchronized (result) {
+ if (!result.exists()) {
+ wordArea.createWorkingCopy(base.getAbsolutePath(), revised.getAbsolutePath(), result.getAbsolutePath());
+ resultFileTimestamp = result.lastModified();
+ description.setText(getTextDescription());
+ }
+ try {
+ wordArea.openDocument(result.getAbsolutePath(), inplace);
+ } catch (SWTException e) {
+ throw new CoreException(new Status(IStatus.ERROR,
+ Activator.PLUGIN_ID, NLS.bind(
+ CompareWin32Messages.WordComparison_16,
+ result.getAbsolutePath()), e));
+ }
+ }
+ }
+ }
+ if (wordArea.isInplace()) {
+ composite.showPage(docArea);
+ } else {
+ composite.showPage(textArea);
+ }
+ } catch (SWTException e) {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0, e.getMessage(), e));
+ } catch (IOException e) {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0, e.getMessage(), e));
+ }
+ updateEnablements();
+ }
+
+ private String getTextDescription() {
+ if (saveAction != null &&hasResultFile()) {
+ IEditableContent saveTarget = getSaveTarget();
+ String name = CompareWin32Messages.WordMergeViewer_3;
+ if (saveTarget instanceof ITypedElement) {
+ ITypedElement te = (ITypedElement) saveTarget;
+ name = te.getName();
+ }
+ try {
+ return NLS.bind(CompareWin32Messages.WordMergeViewer_4, getResultFile().getName(), name);
+ } catch (IOException e) {
+ // This shouldn't happen since the result file has already been created
+ }
+ }
+ return CompareWin32Messages.WordMergeViewer_5;
+ }
+
+ public Control getControl() {
+ return composite;
+ }
+
+ public void setInput(Object input) {
+ super.setInput(input);
+ try {
+ openComparison(true);
+ } catch (CoreException e) {
+ ErrorDialog.openError(WordMergeViewer.this.composite.getShell(), null, null, e.getStatus());
+ Activator.log(e);
+ }
+ }
+
+ private void updateDirtyFlag() {
+ final Runnable dirtyFlagUpdater = new Runnable() {
+ public void run() {
+ if (wordArea.getFrame().isDisposed())
+ return;
+ boolean dirty = wordArea.isDirty();
+ if (hasResultFile()) {
+ try {
+ File resultFile = getResultFile();
+ synchronized (resultFile) {
+ if (resultFile.exists()) {
+ long lastModified = resultFile.lastModified();
+ if (lastModified != resultFileTimestamp) {
+ dirty = true;
+ }
+ }
+ }
+ } catch (IOException e) {
+ // Shouldn't happen since we only get the result file if it has already been created
+ }
+ }
+ if (isDirty() != dirty) {
+ setDirty(dirty);
+ }
+ composite.getDisplay().timerExec(1000, this);
+ }
+ };
+ dirtyFlagUpdater.run();
+ }
+
+ protected boolean isDirty() {
+ return isDirty;
+ }
+
+ protected void setDirty(boolean dirty) {
+ if (isDirty != dirty) {
+ isDirty = dirty;
+ updateEnablements();
+ firePropertyChange(CompareEditorInput.DIRTY_STATE, Boolean.valueOf(!isDirty), Boolean.valueOf(isDirty));
+ }
+ }
+
+ private void firePropertyChange(String property, Object oldValue, Object newValue) {
+ Object[] allListeners = listeners.getListeners();
+ final PropertyChangeEvent event = new PropertyChangeEvent(this, property, oldValue, newValue);
+ for (int i = 0; i < allListeners.length; i++) {
+ final IPropertyChangeListener listener = (IPropertyChangeListener)allListeners[i];
+ SafeRunner.run(new SafeRunnable() {
+ public void run() throws Exception {
+ listener.propertyChange(event);
+ }
+ });
+ }
+ }
+
+ public void addPropertyChangeListener(IPropertyChangeListener listener) {
+ listeners.add(listener);
+ }
+
+ public void removePropertyChangeListener(IPropertyChangeListener listener) {
+ listeners.remove(listener);
+ }
+
+ private void handleDispose() {
+ BusyIndicator.showWhile(Display.getDefault(), new Runnable() {
+ public void run() {
+ wordArea.dispose();
+ formToolkit.dispose();
+ reset();
+ }
+ });
+ }
+
+ protected void reset() {
+ if (wordArea.isOpen()) {
+ wordArea.close();
+ }
+ super.reset();
+ }
+}
diff --git a/bundles/org.eclipse.compare.win32/src/org/eclipse/compare/internal/win32/WordMergeViewer.properties b/bundles/org.eclipse.compare.win32/src/org/eclipse/compare/internal/win32/WordMergeViewer.properties
new file mode 100644
index 000000000..6118d570c
--- /dev/null
+++ b/bundles/org.eclipse.compare.win32/src/org/eclipse/compare/internal/win32/WordMergeViewer.properties
@@ -0,0 +1,18 @@
+###############################################################################
+# Copyright (c) 2008 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
+###############################################################################
+
+action.save.label=Save
+action.save.tooltip=Save the changes to the Word document comparison
+action.save.image=save.gif
+
+action.inplace.label=Edit Inplace
+action.inplace.tooltip=Toggle whether the word document is edited in-place or in a separate window
+action.inplace.image=editor_area.gif \ No newline at end of file
diff --git a/bundles/org.eclipse.compare.win32/src/org/eclipse/compare/internal/win32/WordViewerCreator.java b/bundles/org.eclipse.compare.win32/src/org/eclipse/compare/internal/win32/WordViewerCreator.java
new file mode 100644
index 000000000..85d6e05b6
--- /dev/null
+++ b/bundles/org.eclipse.compare.win32/src/org/eclipse/compare/internal/win32/WordViewerCreator.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.compare.internal.win32;
+
+import org.eclipse.compare.CompareConfiguration;
+import org.eclipse.compare.IViewerCreator;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Factory registered with the <code>org.eclipse.compare.contentMergeViewers</code>
+ * extension point to create a Word document comparison.
+ */
+public class WordViewerCreator implements IViewerCreator {
+
+ public Viewer createViewer(Composite parent, CompareConfiguration config) {
+ return new WordMergeViewer(parent, config);
+ }
+
+
+}
diff --git a/bundles/org.eclipse.compare.win32/src/org/eclipse/compare/internal/win32/messages.properties b/bundles/org.eclipse.compare.win32/src/org/eclipse/compare/internal/win32/messages.properties
new file mode 100644
index 000000000..0d0e4904e
--- /dev/null
+++ b/bundles/org.eclipse.compare.win32/src/org/eclipse/compare/internal/win32/messages.properties
@@ -0,0 +1,25 @@
+###############################################################################
+# Copyright (c) 2008 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
+###############################################################################
+# NLS_ENCODING=UTF-8
+# NLS_MESSAGEFORMAT_VAR
+WordMergeViewer_1=Word Document Compare
+WordMergeViewer_2=Inplace
+WordMergeViewer_3=<unknown>
+WordMergeViewer_4=The Word document comparison is being shown in a separate window. The comparison is using the temporary file ''{0}'' to host the comparison. To save this file back to ''{1}'', you will need to save this compare editor.
+WordMergeViewer_5=The Word document comparison is being shown in a separate window. You can click the 'Toggle in-place' toolbar button to have the document appear inside this pane.
+WordComparison_0=The property ''{0}'' could not be retrieved
+WordComparison_1=The property ''{0}'' could not be retrieved
+WordComparison_2=The command ''{0}'' with value ''{1}'' had no result
+WordComparison_3=The command ''{0}'' with value ''{1}'' had no result
+WordComparison_4=Invalid property name: {0}.
+WordComparison_6=Document ''{0}'' could not be saved
+WordComparison_9=The request to the Word application to perform the comparison between ''{0}'' and ''{1}'' failed. Comparing the files manually may succeed.
+WordComparison_16=The document at {0} could not be opened

Back to the top