InlineEdit: Reuse edit message box to edit file content

Change-Id: Ie29042c97a3f53ac8e7496509b80f29c54b2c793
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/PageLinks.java b/gerrit-common/src/main/java/com/google/gerrit/common/PageLinks.java
index c0382da..89ed1ec 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/PageLinks.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/PageLinks.java
@@ -68,7 +68,7 @@
   }
 
   public static String toChange(final PatchSet.Id ps) {
-    return "/c/" + ps.getParentKey() + "/" + ps.get();
+    return "/c/" + ps.getParentKey() + "/" + ps.getId();
   }
 
   public static String toProject(final Project.NameKey p) {
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen2.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen2.java
index 36ecf08..a9936d5 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen2.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen2.java
@@ -638,9 +638,10 @@
     CallbackGroup group = new CallbackGroup();
     if (rev.is_edit()) {
       NativeMap<JsArray<CommentInfo>> emptyComment = NativeMap.create();
-      files.setRevisions(
+      files.set(
           b != null ? new PatchSet.Id(changeId, b._number()) : null,
-          new PatchSet.Id(changeId, rev._number()));
+          new PatchSet.Id(changeId, rev._number()),
+          style, editMessage, reply);
       files.setValue(info.edit().files(), myLastReply(info),
           emptyComment,
           emptyComment,
@@ -692,9 +693,10 @@
       group.add(new AsyncCallback<NativeMap<FileInfo>>() {
         @Override
         public void onSuccess(NativeMap<FileInfo> m) {
-          files.setRevisions(
+          files.set(
               base != null ? new PatchSet.Id(changeId, base._number()) : null,
-              new PatchSet.Id(changeId, rev._number()));
+              new PatchSet.Id(changeId, rev._number()),
+              style, editMessage, reply);
           files.setValue(m, myLastReply, comments.get(0),
               drafts.get(0), fileTableMode);
         }
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/EditFileAction.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/EditFileAction.java
new file mode 100644
index 0000000..d0c8fe7
--- /dev/null
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/EditFileAction.java
@@ -0,0 +1,80 @@
+//Copyright (C) 2013 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.google.gerrit.client.change;
+
+import com.google.gerrit.reviewdb.client.PatchSet;
+import com.google.gwt.event.logical.shared.CloseEvent;
+import com.google.gwt.event.logical.shared.CloseHandler;
+import com.google.gwt.user.client.ui.PopupPanel;
+import com.google.gwt.user.client.ui.Widget;
+import com.google.gwtexpui.globalkey.client.GlobalKey;
+import com.google.gwtexpui.user.client.PluginSafePopupPanel;
+
+class EditFileAction {
+ private final PatchSet.Id id;
+ private final String content;
+ private final String file;
+ private final ChangeScreen2.Style style;
+ private final Widget editMessageButton;
+ private final Widget relativeTo;
+
+ private EditFileBox editBox;
+ private PopupPanel popup;
+
+ EditFileAction(
+     PatchSet.Id id,
+     String content,
+     String file,
+     ChangeScreen2.Style style,
+     Widget editButton,
+     Widget replyButton) {
+   this.id = id;
+   this.content = content;
+   this.file = file;
+   this.style = style;
+   this.editMessageButton = editButton;
+   this.relativeTo = replyButton;
+ }
+
+ void onEdit() {
+   if (popup != null) {
+     popup.hide();
+     return;
+   }
+
+   if (editBox == null) {
+     editBox = new EditFileBox(
+         id,
+         content,
+         file);
+   }
+
+   final PluginSafePopupPanel p = new PluginSafePopupPanel(true);
+   p.setStyleName(style.replyBox());
+   p.addAutoHidePartner(editMessageButton.getElement());
+   p.addCloseHandler(new CloseHandler<PopupPanel>() {
+     @Override
+     public void onClose(CloseEvent<PopupPanel> event) {
+       if (popup == p) {
+         popup = null;
+       }
+     }
+   });
+   p.add(editBox);
+   p.showRelativeTo(relativeTo);
+   GlobalKey.dialog(p);
+   popup = p;
+ }
+}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/EditFileBox.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/EditFileBox.java
new file mode 100644
index 0000000..8ad05e07
--- /dev/null
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/EditFileBox.java
@@ -0,0 +1,56 @@
+//Copyright (C) 2013 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.google.gerrit.client.change;
+
+import com.google.gerrit.client.Gerrit;
+import com.google.gerrit.client.VoidResult;
+import com.google.gerrit.client.changes.ChangeFileApi;
+import com.google.gerrit.common.PageLinks;
+import com.google.gerrit.reviewdb.client.PatchSet;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.uibinder.client.UiHandler;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+class EditFileBox extends EditMessageBox {
+
+  private PatchSet.Id id;
+  private String file;
+
+  EditFileBox(
+      PatchSet.Id id,
+      String content,
+      String file) {
+    super(null, null, content);
+    this.id = id;
+    this.file = file;
+  }
+
+  @Override
+  @UiHandler("save")
+  void onSave(ClickEvent e) {
+    ChangeFileApi.putContent(id, file, message.getText().trim(),
+        new AsyncCallback<VoidResult>() {
+          @Override
+          public void onSuccess(VoidResult result) {
+            Gerrit.display(PageLinks.toChange(id.getParentKey()));
+            hide();
+          }
+
+          @Override
+          public void onFailure(Throwable caught) {
+          }
+        });
+  }
+}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/EditMessageBox.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/EditMessageBox.java
index 0fe91ca..264465d 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/EditMessageBox.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/EditMessageBox.java
@@ -97,7 +97,7 @@
     hide();
   }
 
-  private void hide() {
+  protected void hide() {
     for (Widget w = getParent(); w != null; w = w.getParent()) {
       if (w instanceof PopupPanel) {
         ((PopupPanel) w).hide();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/FileTable.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/FileTable.java
index 8f7b324..b35d012 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/FileTable.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/FileTable.java
@@ -17,12 +17,14 @@
 import com.google.gerrit.client.Dispatcher;
 import com.google.gerrit.client.Gerrit;
 import com.google.gerrit.client.changes.ChangeApi;
+import com.google.gerrit.client.changes.ChangeFileApi;
 import com.google.gerrit.client.changes.CommentInfo;
 import com.google.gerrit.client.changes.ReviewInfo;
 import com.google.gerrit.client.changes.Util;
 import com.google.gerrit.client.diff.FileInfo;
 import com.google.gerrit.client.patches.PatchUtil;
 import com.google.gerrit.client.rpc.CallbackGroup;
+import com.google.gerrit.client.rpc.GerritCallback;
 import com.google.gerrit.client.rpc.NativeMap;
 import com.google.gerrit.client.rpc.Natives;
 import com.google.gerrit.client.rpc.RestApi;
@@ -30,6 +32,7 @@
 import com.google.gerrit.reviewdb.client.Patch;
 import com.google.gerrit.reviewdb.client.Patch.ChangeType;
 import com.google.gerrit.reviewdb.client.PatchSet;
+import com.google.gerrit.reviewdb.client.PatchSet.Id;
 import com.google.gwt.core.client.GWT;
 import com.google.gwt.core.client.JsArray;
 import com.google.gwt.core.client.JsArrayString;
@@ -47,8 +50,9 @@
 import com.google.gwt.user.client.EventListener;
 import com.google.gwt.user.client.Window;
 import com.google.gwt.user.client.ui.FlowPanel;
-import com.google.gwt.user.client.ui.ImageResourceRenderer;
 import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
+import com.google.gwt.user.client.ui.ImageResourceRenderer;
+import com.google.gwt.user.client.ui.Widget;
 import com.google.gwt.user.client.ui.impl.HyperlinkImpl;
 import com.google.gwtexpui.globalkey.client.KeyCommand;
 import com.google.gwtexpui.progress.client.ProgressBar;
@@ -117,7 +121,7 @@
   private static void onEdit(NativeEvent e, int idx) {
     MyTable t = getMyTable(e);
     if (t != null) {
-      t.onEdit(InputElement.as(Element.as(e.getEventTarget())), idx);
+      t.onEdit(idx);
     }
   }
 
@@ -158,6 +162,9 @@
   private boolean register;
   private JsArrayString reviewed;
   private String scrollToPath;
+  private ChangeScreen2.Style style;
+  private Widget editButton;
+  private Widget replyButton;
 
   @Override
   protected void onLoad() {
@@ -165,9 +172,13 @@
     R.css().ensureInjected();
   }
 
-  void setRevisions(PatchSet.Id base, PatchSet.Id curr) {
+  public void set(Id base, Id curr, ChangeScreen2.Style style,
+      Widget editButton, Widget replyButton) {
     this.base = base;
     this.curr = curr;
+    this.style = style;
+    this.editButton = editButton;
+    this.replyButton = replyButton;
   }
 
   void setValue(NativeMap<FileInfo> fileMap,
@@ -282,8 +293,18 @@
           + curr.toString());
     }
 
-    void onEdit(InputElement checkbox, int idx) {
-      Window.alert("inline edit is not yet implemented");
+    void onEdit(int idx) {
+      final String path = list.get(idx).path();
+      ChangeFileApi.getContent(curr, path,
+          new GerritCallback<String>() {
+            @Override
+            public void onSuccess(String result) {
+              EditFileAction edit = new EditFileAction(
+                  curr, result, path,
+                  style, editButton, replyButton);
+              edit.onEdit();
+            }
+          });
     }
 
     void onReviewed(InputElement checkbox, int idx) {