Merge "Add formatter for .docx, .pptx and .xlsx files"
diff --git a/src/main/java/com/googlesource/gerrit/plugins/xdocs/Module.java b/src/main/java/com/googlesource/gerrit/plugins/xdocs/Module.java
index a526560..3f73760 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/xdocs/Module.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/xdocs/Module.java
@@ -20,6 +20,7 @@
 import com.google.gerrit.extensions.registration.DynamicMap;
 import com.google.gerrit.extensions.registration.DynamicSet;
 import com.google.gerrit.extensions.webui.BranchWebLink;
+import com.google.gerrit.extensions.webui.DiffWebLink;
 import com.google.gerrit.extensions.webui.FileWebLink;
 import com.google.gerrit.extensions.webui.GerritTopMenu;
 import com.google.gerrit.extensions.webui.ProjectWebLink;
@@ -27,6 +28,8 @@
 import com.google.gerrit.server.config.FactoryModule;
 import com.google.inject.Inject;
 
+import com.googlesource.gerrit.plugins.xdocs.client.SideBySideDiffPreviewWebLink;
+import com.googlesource.gerrit.plugins.xdocs.client.UnifiedDiffPreviewWebLink;
 import com.googlesource.gerrit.plugins.xdocs.formatter.AsciidoctorFormatter;
 import com.googlesource.gerrit.plugins.xdocs.formatter.DocxFormatter;
 import com.googlesource.gerrit.plugins.xdocs.formatter.Formatter;
@@ -72,6 +75,10 @@
         .to(XDocWebLink.class);
     DynamicSet.bind(binder(), FileWebLink.class)
         .to(XDocWebLink.class);
+    DynamicSet.bind(binder(), DiffWebLink.class)
+        .to(SideBySideDiffPreviewWebLink.class);
+    DynamicSet.bind(binder(), DiffWebLink.class)
+        .to(UnifiedDiffPreviewWebLink.class);
 
     DynamicSet.bind(binder(), TopMenu.class).toInstance(new TopMenu() {
       @Override
diff --git a/src/main/java/com/googlesource/gerrit/plugins/xdocs/client/Resources.java b/src/main/java/com/googlesource/gerrit/plugins/xdocs/client/Resources.java
new file mode 100644
index 0000000..45bc259
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/xdocs/client/Resources.java
@@ -0,0 +1,26 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.xdocs.client;
+
+import com.google.gwt.resources.client.ImageResource;
+
+public interface Resources extends com.google.gerrit.client.Resources {
+
+  @Source("sideBySideDiffPreview.png")
+  public ImageResource sideBySideDiffPreview();
+
+  @Source("unifiedDiffPreview.png")
+  public ImageResource unifiedDiffPreview();
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/xdocs/client/SideBySideDiffPreviewWebLink.java b/src/main/java/com/googlesource/gerrit/plugins/xdocs/client/SideBySideDiffPreviewWebLink.java
new file mode 100644
index 0000000..bed011e
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/xdocs/client/SideBySideDiffPreviewWebLink.java
@@ -0,0 +1,72 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.xdocs.client;
+
+import com.google.gerrit.extensions.annotations.PluginName;
+import com.google.gerrit.extensions.common.DiffWebLinkInfo;
+import com.google.gerrit.extensions.restapi.Url;
+import com.google.gerrit.extensions.webui.DiffWebLink;
+import com.google.inject.Inject;
+
+import com.googlesource.gerrit.plugins.xdocs.formatter.Formatters;
+import com.googlesource.gerrit.plugins.xdocs.formatter.Formatters.FormatterProvider;
+
+public class SideBySideDiffPreviewWebLink implements DiffWebLink {
+  private static final String SIDE_BY_SIDE_PREVIEW_DIFF = "side-by-side preview diff";
+
+  private final String pluginName;
+  private final Formatters formatters;
+
+  @Inject
+  SideBySideDiffPreviewWebLink(
+      @PluginName String pluginName,
+      Formatters formatters) {
+    this.pluginName = pluginName;
+    this.formatters = formatters;
+  }
+
+  @Override
+  public DiffWebLinkInfo getDiffLink(String projectName, int changeId,
+      Integer patchSetIdA, String revisionA, String fileNameA, int patchSetIdB,
+      String revisionB, String fileNameB) {
+    FormatterProvider formatter = formatters.get(projectName, fileNameB);
+    if (formatter == null) {
+      return null;
+    }
+
+    return DiffWebLinkInfo.forSideBySideDiffView(SIDE_BY_SIDE_PREVIEW_DIFF,
+        "plugins/" + pluginName + "/static/sideBySideDiffPreview.png",
+        getUrl(pluginName, changeId, patchSetIdA, patchSetIdB, fileNameB),
+        Target.SELF);
+  }
+
+  public static String getUrl(String pluginName, int changeId,
+      Integer patchSetIdA, int patchSetIdB, String fileName) {
+    StringBuilder url = new StringBuilder();
+    url.append("#/x/");
+    url.append(pluginName);
+    url.append("/c/");
+    url.append(changeId);
+    url.append("/");
+    if (patchSetIdA != null) {
+      url.append(patchSetIdA);
+      url.append("..");
+    }
+    url.append(patchSetIdB);
+    url.append("/");
+    url.append(Url.encode(fileName));
+    return url.toString();
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/xdocs/client/UnifiedDiffPreviewWebLink.java b/src/main/java/com/googlesource/gerrit/plugins/xdocs/client/UnifiedDiffPreviewWebLink.java
new file mode 100644
index 0000000..d52ca4c
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/xdocs/client/UnifiedDiffPreviewWebLink.java
@@ -0,0 +1,59 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.xdocs.client;
+
+import com.google.gerrit.extensions.annotations.PluginName;
+import com.google.gerrit.extensions.common.DiffWebLinkInfo;
+import com.google.gerrit.extensions.webui.DiffWebLink;
+import com.google.inject.Inject;
+
+import com.googlesource.gerrit.plugins.xdocs.formatter.Formatters;
+import com.googlesource.gerrit.plugins.xdocs.formatter.Formatters.FormatterProvider;
+
+public class UnifiedDiffPreviewWebLink implements DiffWebLink {
+  private static final String UNIFIED_PREVIEW_DIFF = "unified preview diff";
+
+  private final String pluginName;
+  private final Formatters formatters;
+
+  @Inject
+  UnifiedDiffPreviewWebLink(
+      @PluginName String pluginName,
+      Formatters formatters) {
+    this.pluginName = pluginName;
+    this.formatters = formatters;
+  }
+
+  @Override
+  public DiffWebLinkInfo getDiffLink(String projectName, int changeId,
+      Integer patchSetIdA, String revisionA, String fileNameA, int patchSetIdB,
+      String revisionB, String fileNameB) {
+    FormatterProvider formatter = formatters.get(projectName, fileNameB);
+    if (formatter == null) {
+      return null;
+    }
+
+    return DiffWebLinkInfo.forUnifiedDiffView(UNIFIED_PREVIEW_DIFF,
+        "plugins/" + pluginName + "/static/unifiedDiffPreview.png",
+        getUrl(pluginName, changeId, patchSetIdA, patchSetIdB, fileNameB),
+        Target.SELF);
+  }
+
+  private static String getUrl(String pluginName, int changeId,
+      Integer patchSetIdA, int patchSetIdB, String fileName) {
+    return SideBySideDiffPreviewWebLink.getUrl(pluginName, changeId,
+        patchSetIdA, patchSetIdB, fileName) + ",unified";
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/xdocs/client/XDocDiffScreen.java b/src/main/java/com/googlesource/gerrit/plugins/xdocs/client/XDocDiffScreen.java
index 12606b6..cff00ea 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/xdocs/client/XDocDiffScreen.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/xdocs/client/XDocDiffScreen.java
@@ -31,13 +31,14 @@
 import com.googlesource.gerrit.plugins.xdocs.client.ChangeInfo.RevisionInfo;
 
 public abstract class XDocDiffScreen extends VerticalPanel {
-  private final String changeId;
-  private final String path;
-  private String revisionA;
-  private String revisionB;
-  private int patchSet;
-  private Integer base;
+  protected final String changeId;
+  protected final String path;
+  protected String revisionA;
+  protected String revisionB;
+  protected int patchSet;
+  protected Integer base;
   private FlowPanel iconPanel;
+  private FlowPanel additionalIconPanel;
 
   XDocDiffScreen(String changeId, final String patchSet, String path) {
     setStyleName("xdocs-panel");
@@ -51,6 +52,7 @@
       public void onSuccess(ChangeInfo change) {
         setRevisions(change, patchSet);
         addHeader(change);
+        init();
         display(change);
       }
 
@@ -119,11 +121,16 @@
     iconPanel = new FlowPanel();
     iconPanel.setStyleName("xdocs-icon-panel");
     p.add(iconPanel);
+    additionalIconPanel = new FlowPanel();
+    iconPanel.add(additionalIconPanel);
     addNavigationButtons(change);
 
     add(p);
   }
 
+  protected void init() {
+  }
+
   private Widget getPathHeader(ChangeInfo change) {
     HorizontalPanel p = new HorizontalPanel();
     p.setStyleName("xdocs-file-header");
@@ -196,7 +203,7 @@
     return link;
   }
 
-  private static InlineHyperlink createIcon(ImageResource res, String tooltip, String target) {
+  protected static InlineHyperlink createIcon(ImageResource res, String tooltip, String target) {
     InlineHyperlink l = new InlineHyperlink(
         AbstractImagePrototype.create(res).getHTML(), true, target);
     if (tooltip != null) {
@@ -205,6 +212,10 @@
     return l;
   }
 
+  protected void addIcon(InlineHyperlink icon) {
+    additionalIconPanel.add(icon);
+  }
+
   private String toPreview(ChangeInfo change, int patchSet,
       Integer base, FileInfo file) {
     String panel = getPanel();
diff --git a/src/main/java/com/googlesource/gerrit/plugins/xdocs/client/XDocSideBySideDiffScreen.java b/src/main/java/com/googlesource/gerrit/plugins/xdocs/client/XDocSideBySideDiffScreen.java
index 9209a36..e9b0861 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/xdocs/client/XDocSideBySideDiffScreen.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/xdocs/client/XDocSideBySideDiffScreen.java
@@ -64,4 +64,16 @@
   private String getRevisionSideB() {
     return getRevisionA() + "->" + getRevisionB();
   }
+
+  @Override
+  protected void init() {
+    addIcon(createIcon(
+        XDocsPlugin.RESOURCES.sideBySideDiff(),
+        "side-by-side text diff",
+        XDocsPlugin.getSideBySideDiffUrl(changeId, base, patchSet, path)));
+    addIcon(createIcon(
+        XDocsPlugin.RESOURCES.unifiedDiffPreview(),
+        "unified preview diff",
+        XDocsPlugin.getUnifiedPreviewDiffUrl(changeId, base, patchSet, path)));
+  }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/xdocs/client/XDocUnifiedDiffScreen.java b/src/main/java/com/googlesource/gerrit/plugins/xdocs/client/XDocUnifiedDiffScreen.java
index 551d76e..9004ad7 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/xdocs/client/XDocUnifiedDiffScreen.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/xdocs/client/XDocUnifiedDiffScreen.java
@@ -52,4 +52,16 @@
   protected String getPanel() {
     return "unified";
   }
+
+  @Override
+  protected void init() {
+    addIcon(createIcon(
+        XDocsPlugin.RESOURCES.unifiedDiff(),
+        "unified text diff",
+        XDocsPlugin.getUnifiedDiffUrl(changeId, base, patchSet, path)));
+    addIcon(createIcon(
+        XDocsPlugin.RESOURCES.sideBySideDiffPreview(),
+        "side-by-side preview diff",
+        XDocsPlugin.getSideBySidePreviewDiffUrl(changeId, base, patchSet, path)));
+  }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/xdocs/client/XDocsPlugin.java b/src/main/java/com/googlesource/gerrit/plugins/xdocs/client/XDocsPlugin.java
index 71c2714..3d62ac3 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/xdocs/client/XDocsPlugin.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/xdocs/client/XDocsPlugin.java
@@ -14,10 +14,10 @@
 
 package com.googlesource.gerrit.plugins.xdocs.client;
 
-import com.google.gerrit.client.Resources;
 import com.google.gerrit.plugin.client.Plugin;
 import com.google.gerrit.plugin.client.PluginEntryPoint;
 import com.google.gwt.core.client.GWT;
+import com.google.gwt.http.client.URL;
 
 public class XDocsPlugin extends PluginEntryPoint {
   public static final Resources RESOURCES = GWT.create(Resources.class);
@@ -33,4 +33,41 @@
     Plugin.get().screenRegex("c/(.*)/([0-9]+(\\.{2}[0-9]+)?)/(.*)",
         new XDocSideBySideDiffScreen.Factory());
   }
+
+  public static String getSideBySideDiffUrl(String changeId,
+      Integer patchSetIdA, int patchSetIdB, String fileName) {
+    StringBuilder url = new StringBuilder();
+    url.append("/c/");
+    url.append(changeId);
+    url.append("/");
+    if (patchSetIdA != null) {
+      url.append(patchSetIdA);
+      url.append("..");
+    }
+    url.append(patchSetIdB);
+    url.append("/");
+    url.append(URL.encode(fileName));
+    return url.toString();
+  }
+
+  public static String getUnifiedDiffUrl(String changeId, Integer patchSetIdA,
+      int patchSetIdB, String fileName) {
+    return getSideBySideDiffUrl(changeId, patchSetIdA, patchSetIdB, fileName)
+        + ",unified";
+  }
+
+  public static String getSideBySidePreviewDiffUrl(String changeId,
+      Integer patchSetIdA, int patchSetIdB, String fileName) {
+    StringBuilder url = new StringBuilder();
+    url.append("/x/");
+    url.append(Plugin.get().getPluginName());
+    url.append(getSideBySideDiffUrl(changeId, patchSetIdA, patchSetIdB, fileName));
+    return url.toString();
+  }
+
+  public static String getUnifiedPreviewDiffUrl(String changeId,
+      Integer patchSetIdA, int patchSetIdB, String fileName) {
+    return getSideBySidePreviewDiffUrl(changeId, patchSetIdA, patchSetIdB,
+        fileName) + ",unified";
+  }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/xdocs/public/xdocs.css b/src/main/java/com/googlesource/gerrit/plugins/xdocs/public/xdocs.css
index e7364b9..cc538e2 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/xdocs/public/xdocs.css
+++ b/src/main/java/com/googlesource/gerrit/plugins/xdocs/public/xdocs.css
@@ -33,6 +33,10 @@
   padding-right: 3px;
 }
 
+.xdocs-icon-panel div {
+  float: left;
+}
+
 .xdocs-panel iframe {
   width: 100%;
   border-width: 1px;
diff --git a/src/main/resources/com/googlesource/gerrit/plugins/xdocs/client/sideBySideDiffPreview.png b/src/main/resources/com/googlesource/gerrit/plugins/xdocs/client/sideBySideDiffPreview.png
new file mode 100644
index 0000000..4525590
--- /dev/null
+++ b/src/main/resources/com/googlesource/gerrit/plugins/xdocs/client/sideBySideDiffPreview.png
Binary files differ
diff --git a/src/main/resources/com/googlesource/gerrit/plugins/xdocs/client/unifiedDiffPreview.png b/src/main/resources/com/googlesource/gerrit/plugins/xdocs/client/unifiedDiffPreview.png
new file mode 100644
index 0000000..7625730
--- /dev/null
+++ b/src/main/resources/com/googlesource/gerrit/plugins/xdocs/client/unifiedDiffPreview.png
Binary files differ
diff --git a/src/main/resources/static/sideBySideDiffPreview.png b/src/main/resources/static/sideBySideDiffPreview.png
new file mode 100644
index 0000000..4525590
--- /dev/null
+++ b/src/main/resources/static/sideBySideDiffPreview.png
Binary files differ
diff --git a/src/main/resources/static/unifiedDiffPreview.png b/src/main/resources/static/unifiedDiffPreview.png
new file mode 100644
index 0000000..7625730
--- /dev/null
+++ b/src/main/resources/static/unifiedDiffPreview.png
Binary files differ