InlineEdit: Allow to rename files in the UI
This change allows to rename files that are not contained in the
change. Renaming of files that already exist in the change (i.e.
from the file table) will be added later.
Change-Id: Iee396e73dc246bd232cca005af7e8f4f9041340c
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen.java
index 88f8408..8a27fd0 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen.java
@@ -191,6 +191,7 @@
@UiField Button reviewMode;
@UiField Button addFile;
@UiField Button deleteFile;
+ @UiField Button renameFile;
@UiField Button expandAll;
@UiField Button collapseAll;
@UiField QuickApprove quickApprove;
@@ -201,6 +202,7 @@
private DownloadAction downloadAction;
private AddFileAction addFileAction;
private DeleteFileAction deleteFileAction;
+ private RenameFileAction renameFileAction;
public ChangeScreen(Change.Id changeId, String base, String revision,
boolean openReplyBox, FileTable.Mode mode) {
@@ -486,6 +488,7 @@
editMode.setVisible(fileTableMode == FileTable.Mode.REVIEW);
addFile.setVisible(!editMode.isVisible());
deleteFile.setVisible(!editMode.isVisible());
+ renameFile.setVisible(!editMode.isVisible());
reviewMode.setVisible(!editMode.isVisible());
addFileAction = new AddFileAction(
changeId, info.revision(revision),
@@ -493,6 +496,9 @@
deleteFileAction = new DeleteFileAction(
changeId, info.revision(revision),
style, addFile);
+ renameFileAction = new RenameFileAction(
+ changeId, info.revision(revision),
+ style, addFile);
} else {
editMode.setVisible(false);
addFile.setVisible(false);
@@ -670,6 +676,7 @@
editMode.setVisible(false);
addFile.setVisible(true);
deleteFile.setVisible(true);
+ renameFile.setVisible(true);
reviewMode.setVisible(true);
}
@@ -680,6 +687,7 @@
editMode.setVisible(true);
addFile.setVisible(false);
deleteFile.setVisible(false);
+ renameFile.setVisible(false);
reviewMode.setVisible(false);
}
@@ -693,6 +701,11 @@
deleteFileAction.onDelete();
}
+ @UiHandler("renameFile")
+ void onRenameFile(@SuppressWarnings("unused") ClickEvent e) {
+ renameFileAction.onRename();
+ }
+
private void refreshFileTable() {
int idx = diffBase.getSelectedIndex();
if (0 <= idx) {
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen.ui.xml b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen.ui.xml
index 280455a..6f8d3aa 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen.ui.xml
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen.ui.xml
@@ -496,6 +496,13 @@
<ui:attribute name='title'/>
<div><ui:msg>Delete…</ui:msg></div>
</g:Button>
+ <g:Button ui:field='renameFile'
+ title='Rename file in the repository'
+ styleName=''
+ visible='false'>
+ <ui:attribute name='title'/>
+ <div><ui:msg>Rename…</ui:msg></div>
+ </g:Button>
<div class='{style.headerButtons}'>
<g:Button ui:field='openAll'
styleName=''
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/RenameFileAction.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/RenameFileAction.java
new file mode 100644
index 0000000..1f11e65
--- /dev/null
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/RenameFileAction.java
@@ -0,0 +1,71 @@
+//Copyright (C) 2015 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.changes.ChangeInfo.RevisionInfo;
+import com.google.gerrit.reviewdb.client.Change;
+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 RenameFileAction {
+ private final Change.Id changeId;
+ private final RevisionInfo revision;
+ private final ChangeScreen.Style style;
+ private final Widget renameButton;
+
+ private RenameFileBox renameBox;
+ private PopupPanel popup;
+
+ RenameFileAction(Change.Id changeId, RevisionInfo revision,
+ ChangeScreen.Style style, Widget renameButton) {
+ this.changeId = changeId;
+ this.revision = revision;
+ this.style = style;
+ this.renameButton = renameButton;
+ }
+
+ void onRename() {
+ if (popup != null) {
+ popup.hide();
+ return;
+ }
+
+ if (renameBox == null) {
+ renameBox = new RenameFileBox(changeId, revision);
+ }
+ renameBox.clearPath();
+
+ final PluginSafePopupPanel p = new PluginSafePopupPanel(true);
+ p.setStyleName(style.replyBox());
+ p.addAutoHidePartner(renameButton.getElement());
+ p.addCloseHandler(new CloseHandler<PopupPanel>() {
+ @Override
+ public void onClose(CloseEvent<PopupPanel> event) {
+ if (popup == p) {
+ popup = null;
+ }
+ }
+ });
+ p.add(renameBox);
+ p.showRelativeTo(renameButton);
+ GlobalKey.dialog(p);
+ renameBox.setFocus(true);
+ popup = p;
+ }
+}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/RenameFileBox.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/RenameFileBox.java
new file mode 100644
index 0000000..77348f7
--- /dev/null
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/RenameFileBox.java
@@ -0,0 +1,107 @@
+//Copyright (C) 2015 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.ChangeEditApi;
+import com.google.gerrit.client.changes.ChangeInfo.RevisionInfo;
+import com.google.gerrit.client.ui.RemoteSuggestBox;
+import com.google.gerrit.common.PageLinks;
+import com.google.gerrit.reviewdb.client.Change;
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.logical.shared.CloseEvent;
+import com.google.gwt.event.logical.shared.CloseHandler;
+import com.google.gwt.uibinder.client.UiBinder;
+import com.google.gwt.uibinder.client.UiField;
+import com.google.gwt.uibinder.client.UiHandler;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.HTMLPanel;
+import com.google.gwt.user.client.ui.PopupPanel;
+import com.google.gwt.user.client.ui.Widget;
+import com.google.gwtexpui.globalkey.client.NpTextBox;
+
+class RenameFileBox extends Composite {
+ interface Binder extends UiBinder<HTMLPanel, RenameFileBox> {}
+ private static final Binder uiBinder = GWT.create(Binder.class);
+
+ private final Change.Id changeId;
+
+ @UiField Button rename;
+ @UiField Button cancel;
+
+ @UiField(provided = true)
+ RemoteSuggestBox path;
+ @UiField NpTextBox newPath;
+
+ RenameFileBox(Change.Id changeId, RevisionInfo revision) {
+ this.changeId = changeId;
+
+ path = new RemoteSuggestBox(new PathSuggestOracle(changeId, revision));
+ path.addCloseHandler(new CloseHandler<RemoteSuggestBox>() {
+ @Override
+ public void onClose(CloseEvent<RemoteSuggestBox> event) {
+ hide();
+ }
+ });
+
+ initWidget(uiBinder.createAndBindUi(this));
+ }
+
+ void setFocus(boolean focus) {
+ path.setFocus(focus);
+ }
+
+ void clearPath() {
+ path.setText("");
+ }
+
+ @UiHandler("rename")
+ void onRename(@SuppressWarnings("unused") ClickEvent e) {
+ rename(path.getText(), newPath.getText());
+ }
+
+ private void rename(String path, String newPath) {
+ hide();
+ ChangeEditApi.rename(changeId.get(), path, newPath,
+ new AsyncCallback<VoidResult>() {
+ @Override
+ public void onSuccess(VoidResult result) {
+ Gerrit.display(PageLinks.toChangeInEditMode(changeId));
+ }
+
+ @Override
+ public void onFailure(Throwable caught) {
+ }
+ });
+ }
+
+ @UiHandler("cancel")
+ void onCancel(@SuppressWarnings("unused") ClickEvent e) {
+ hide();
+ }
+
+ private void hide() {
+ for (Widget w = getParent(); w != null; w = w.getParent()) {
+ if (w instanceof PopupPanel) {
+ ((PopupPanel) w).hide();
+ break;
+ }
+ }
+ }
+}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/RenameFileBox.ui.xml b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/RenameFileBox.ui.xml
new file mode 100644
index 0000000..27849ee
--- /dev/null
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/RenameFileBox.ui.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<ui:UiBinder
+ xmlns:ui='urn:ui:com.google.gwt.uibinder'
+ xmlns:c='urn:import:com.google.gwtexpui.globalkey.client'
+ xmlns:u='urn:import:com.google.gerrit.client.ui'
+ xmlns:g='urn:import:com.google.gwt.user.client.ui'>
+ <ui:with field='res' type='com.google.gerrit.client.change.Resources'/>
+ <ui:style>
+ .cancel { float: right; }
+ </ui:style>
+ <g:HTMLPanel>
+ <div class='{res.style.section}'>
+ <ui:msg>Old: <u:RemoteSuggestBox ui:field='path' visibleLength='86'/></ui:msg>
+ </div>
+ <div class='{res.style.section}'>
+ <ui:msg>New: <c:NpTextBox ui:field='newPath' visibleLength='86'/></ui:msg>
+ </div>
+ <div class='{res.style.section}'>
+ <g:Button ui:field='rename'
+ title='Rename file in the repository'
+ styleName='{res.style.button}'>
+ <ui:attribute name='title'/>
+ <div><ui:msg>Rename</ui:msg></div>
+ </g:Button>
+ <g:Button ui:field='cancel'
+ styleName='{res.style.button}'
+ addStyleNames='{style.cancel}'>
+ <div>Cancel</div>
+ </g:Button>
+ </div>
+ </g:HTMLPanel>
+</ui:UiBinder>
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeEditApi.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeEditApi.java
index 22204dc..a00e329 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeEditApi.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeEditApi.java
@@ -72,6 +72,15 @@
editFile(id, path).delete(cb);
}
+ /** Rename a file in the pending edit. */
+ public static void rename(int id, String path, String newPath,
+ AsyncCallback<VoidResult> cb) {
+ Input in = Input.create();
+ in.old_path(path);
+ in.new_path(newPath);
+ ChangeApi.edit(id).post(in, cb);
+ }
+
/** Restore (undo delete/modify) a file in the pending edit. */
public static void restore(int id, String path, AsyncCallback<VoidResult> cb) {
Input in = Input.create();
@@ -93,6 +102,8 @@
}
final native void restore_path(String p) /*-{ this.restore_path=p }-*/;
+ final native void old_path(String p) /*-{ this.old_path=p }-*/;
+ final native void new_path(String p) /*-{ this.new_path=p }-*/;
protected Input() {
}