InlineEdit: Implement CM3 integration, using new screen
Add new screen for editing file and commit message content and dispatch to it when a user navigates to a file or commit message in change edit mode from file table. Two buttons are rendered in header of new edit screen: cancel and save. Clicking on both of them takes user to CS2. To differentiate between diff mode and edit mode in dispatcher, new panel is used: ",edit"; "cm" is not used any more, as only CS2 is supported: c/1/1/foo.txt opens SBS2 screen, whereas c/1/1/foo.txt,edit opens new edit screen with integrated CM3 editor. Navigation in edit mode is harmonized from all places: file table and SBS2 now using new edit screen to edit file and commit message content. Edit file content popup dialog is only used in two places: When adding new file to change edit or clicking on "Edit Message" button. In former case this dialog is preserved until it is replaced by repository browser. The usage of edit file icon in file table was dropped. Change-Id: I4d70463357b82a8a3d675dd18b3ea5af99a434b0
This commit is contained in:
@@ -79,6 +79,7 @@ import com.google.gerrit.client.dashboards.DashboardList;
|
||||
import com.google.gerrit.client.diff.DisplaySide;
|
||||
import com.google.gerrit.client.diff.SideBySide2;
|
||||
import com.google.gerrit.client.documentation.DocScreen;
|
||||
import com.google.gerrit.client.editor.EditScreen;
|
||||
import com.google.gerrit.client.groups.GroupApi;
|
||||
import com.google.gerrit.client.groups.GroupInfo;
|
||||
import com.google.gerrit.client.patches.PatchScreen;
|
||||
@@ -169,6 +170,15 @@ public class Dispatcher {
|
||||
}
|
||||
}
|
||||
|
||||
public static String toEditScreen(PatchSet.Id revision, String fileName) {
|
||||
Change.Id c = revision.getParentKey();
|
||||
StringBuilder p = new StringBuilder();
|
||||
p.append("/c/").append(c).append("/");
|
||||
p.append(revision.getId()).append("/").append(KeyUtil.encode(fileName));
|
||||
p.append(",edit");
|
||||
return p.toString();
|
||||
}
|
||||
|
||||
public static String toPublish(PatchSet.Id ps) {
|
||||
Change.Id c = ps.getParentKey();
|
||||
return "/c/" + c + "/" + ps.get() + ",publish";
|
||||
@@ -735,6 +745,8 @@ public class Dispatcher {
|
||||
patchTable,//
|
||||
top,//
|
||||
baseId);//
|
||||
} else if (panel.equals("edit")) {
|
||||
return new EditScreen(id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -697,11 +697,9 @@ public class ChangeScreen2 extends Screen {
|
||||
files.set(
|
||||
b != null ? new PatchSet.Id(changeId, b._number()) : null,
|
||||
new PatchSet.Id(changeId, rev._number()),
|
||||
style, editMessage, reply, edit != null);
|
||||
files.setValue(info.edit().files(), myLastReply(info),
|
||||
emptyComment,
|
||||
emptyComment,
|
||||
fileTableMode);
|
||||
style, editMessage, reply, fileTableMode, edit != null);
|
||||
files.setValue(info.edit().files(), myLastReply(info), emptyComment,
|
||||
emptyComment);
|
||||
} else {
|
||||
loadDiff(b, rev, myLastReply(info), group);
|
||||
}
|
||||
@@ -752,9 +750,8 @@ public class ChangeScreen2 extends Screen {
|
||||
files.set(
|
||||
base != null ? new PatchSet.Id(changeId, base._number()) : null,
|
||||
new PatchSet.Id(changeId, rev._number()),
|
||||
style, editMessage, reply, edit != null);
|
||||
files.setValue(m, myLastReply, comments.get(0),
|
||||
drafts.get(0), fileTableMode);
|
||||
style, editMessage, reply, fileTableMode, edit != null);
|
||||
files.setValue(m, myLastReply, comments.get(0), drafts.get(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -17,9 +17,9 @@ 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.client.rpc.GerritCallback;
|
||||
import com.google.gerrit.client.ui.TextBoxChangeListener;
|
||||
import com.google.gerrit.common.PageLinks;
|
||||
import com.google.gerrit.reviewdb.client.Patch;
|
||||
import com.google.gerrit.reviewdb.client.PatchSet;
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.core.client.Scheduler;
|
||||
@@ -28,7 +28,6 @@ import com.google.gwt.event.dom.client.ClickEvent;
|
||||
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;
|
||||
@@ -50,18 +49,6 @@ class EditFileBox extends Composite {
|
||||
@UiField Button save;
|
||||
@UiField Button cancel;
|
||||
|
||||
private AsyncCallback<VoidResult> cb = new AsyncCallback<VoidResult>() {
|
||||
@Override
|
||||
public void onSuccess(VoidResult result) {
|
||||
Gerrit.display(PageLinks.toChangeInEditMode(id.getParentKey()));
|
||||
hide();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
}
|
||||
};
|
||||
|
||||
EditFileBox(
|
||||
PatchSet.Id id,
|
||||
String fileC,
|
||||
@@ -94,11 +81,14 @@ class EditFileBox extends Composite {
|
||||
|
||||
@UiHandler("save")
|
||||
void onSave(@SuppressWarnings("unused") ClickEvent e) {
|
||||
if (Patch.COMMIT_MSG.equals(file.getText())) {
|
||||
ChangeFileApi.putMessage(id, content.getText(), cb);
|
||||
} else {
|
||||
ChangeFileApi.putContent(id, file.getText(), content.getText(), cb);
|
||||
ChangeFileApi.putContent(id, file.getText(), content.getText(),
|
||||
new GerritCallback<VoidResult>() {
|
||||
@Override
|
||||
public void onSuccess(VoidResult result) {
|
||||
Gerrit.display(PageLinks.toChangeInEditMode(id.getParentKey()));
|
||||
hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@UiHandler("cancel")
|
||||
|
||||
@@ -25,7 +25,6 @@ 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;
|
||||
@@ -87,19 +86,15 @@ public class FileTable extends FlowPanel {
|
||||
String deltaColumn2();
|
||||
String inserted();
|
||||
String deleted();
|
||||
String editButton();
|
||||
String removeButton();
|
||||
}
|
||||
|
||||
public static enum Mode {
|
||||
REVIEW,
|
||||
@SuppressWarnings("hiding")
|
||||
EDIT
|
||||
}
|
||||
|
||||
private static final String DELETE;
|
||||
private static final String EDIT;
|
||||
private static final String EDIT_MESSAGE;
|
||||
private static final String RESTORE;
|
||||
private static final String REVIEWED;
|
||||
private static final String OPEN;
|
||||
@@ -108,24 +103,16 @@ public class FileTable extends FlowPanel {
|
||||
|
||||
static {
|
||||
DELETE = DOM.createUniqueId().replace('-', '_');
|
||||
EDIT = DOM.createUniqueId().replace('-', '_');
|
||||
EDIT_MESSAGE = DOM.createUniqueId().replace('-', '_');
|
||||
RESTORE = DOM.createUniqueId().replace('-', '_');
|
||||
REVIEWED = DOM.createUniqueId().replace('-', '_');
|
||||
OPEN = DOM.createUniqueId().replace('-', '_');
|
||||
init(DELETE, EDIT, EDIT_MESSAGE, RESTORE, REVIEWED, OPEN);
|
||||
init(DELETE, RESTORE, REVIEWED, OPEN);
|
||||
}
|
||||
|
||||
private static final native void init(String d, String e, String m, String t, String r, String o) /*-{
|
||||
private static final native void init(String d, String t, String r, String o) /*-{
|
||||
$wnd[d] = $entry(function(e,i) {
|
||||
@com.google.gerrit.client.change.FileTable::onDelete(Lcom/google/gwt/dom/client/NativeEvent;I)(e,i)
|
||||
});
|
||||
$wnd[e] = $entry(function(e,i) {
|
||||
@com.google.gerrit.client.change.FileTable::onEdit(Lcom/google/gwt/dom/client/NativeEvent;I)(e,i)
|
||||
});
|
||||
$wnd[m] = $entry(function(e,i) {
|
||||
@com.google.gerrit.client.change.FileTable::onEditMessage(Lcom/google/gwt/dom/client/NativeEvent;I)(e,i)
|
||||
});
|
||||
$wnd[t] = $entry(function(e,i) {
|
||||
@com.google.gerrit.client.change.FileTable::onRestore(Lcom/google/gwt/dom/client/NativeEvent;I)(e,i)
|
||||
});
|
||||
@@ -137,20 +124,6 @@ public class FileTable extends FlowPanel {
|
||||
});
|
||||
}-*/;
|
||||
|
||||
private static void onEdit(NativeEvent e, int idx) {
|
||||
MyTable t = getMyTable(e);
|
||||
if (t != null) {
|
||||
t.onEdit(idx);
|
||||
}
|
||||
}
|
||||
|
||||
private static void onEditMessage(NativeEvent e, int idx) {
|
||||
MyTable t = getMyTable(e);
|
||||
if (t != null) {
|
||||
t.onEditMessage(idx);
|
||||
}
|
||||
}
|
||||
|
||||
private static void onDelete(NativeEvent e, int idx) {
|
||||
MyTable t = getMyTable(e);
|
||||
if (t != null) {
|
||||
@@ -206,6 +179,7 @@ public class FileTable extends FlowPanel {
|
||||
private Widget editButton;
|
||||
private Widget replyButton;
|
||||
private boolean editExists;
|
||||
private Mode mode;
|
||||
|
||||
@Override
|
||||
protected void onLoad() {
|
||||
@@ -214,25 +188,25 @@ public class FileTable extends FlowPanel {
|
||||
}
|
||||
|
||||
public void set(PatchSet.Id base, PatchSet.Id curr, ChangeScreen2.Style style,
|
||||
Widget editButton, Widget replyButton, boolean editExists) {
|
||||
Widget editButton, Widget replyButton, Mode mode, boolean editExists) {
|
||||
this.base = base;
|
||||
this.curr = curr;
|
||||
this.style = style;
|
||||
this.editButton = editButton;
|
||||
this.replyButton = replyButton;
|
||||
this.mode = mode;
|
||||
this.editExists = editExists;
|
||||
}
|
||||
|
||||
void setValue(NativeMap<FileInfo> fileMap,
|
||||
Timestamp myLastReply,
|
||||
NativeMap<JsArray<CommentInfo>> comments,
|
||||
NativeMap<JsArray<CommentInfo>> drafts,
|
||||
Mode mode) {
|
||||
NativeMap<JsArray<CommentInfo>> drafts) {
|
||||
JsArray<FileInfo> list = fileMap.values();
|
||||
FileInfo.sortFileInfoByPath(list);
|
||||
|
||||
DisplayCommand cmd = new DisplayCommand(fileMap, list,
|
||||
myLastReply, comments, drafts, mode);
|
||||
myLastReply, comments, drafts);
|
||||
if (cmd.execute()) {
|
||||
cmd.showProgressBar();
|
||||
Scheduler.get().scheduleIncremental(cmd);
|
||||
@@ -293,7 +267,9 @@ public class FileTable extends FlowPanel {
|
||||
private String url(FileInfo info) {
|
||||
return info.binary()
|
||||
? Dispatcher.toUnified(base, curr, info.path())
|
||||
: Dispatcher.toSideBySide(base, curr, info.path());
|
||||
: mode == Mode.REVIEW
|
||||
? Dispatcher.toSideBySide(base, curr, info.path())
|
||||
: Dispatcher.toEditScreen(curr, info.path());
|
||||
}
|
||||
|
||||
private final class MyTable extends NavigationTable<FileInfo> {
|
||||
@@ -335,34 +311,6 @@ public class FileTable extends FlowPanel {
|
||||
+ curr.toString());
|
||||
}
|
||||
|
||||
void onEdit(int idx) {
|
||||
final String path = list.get(idx).path();
|
||||
final PatchSet.Id id = editExists && curr.get() != 0
|
||||
? new PatchSet.Id(curr.getParentKey(), 0)
|
||||
: curr;
|
||||
ChangeFileApi.getContent(id, path,
|
||||
new GerritCallback<String>() {
|
||||
@Override
|
||||
public void onSuccess(String result) {
|
||||
EditFileAction edit = new EditFileAction(
|
||||
id, result, path, style, editButton, replyButton);
|
||||
edit.onEdit();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void onEditMessage(@SuppressWarnings("unused") int idx) {
|
||||
ChangeFileApi.getMessage(curr,
|
||||
new GerritCallback<String>() {
|
||||
@Override
|
||||
public void onSuccess(String r) {
|
||||
EditFileAction edit = new EditFileAction(
|
||||
curr, r, Patch.COMMIT_MSG, style, editButton, replyButton);
|
||||
edit.onEdit();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void onDelete(int idx) {
|
||||
String path = list.get(idx).path();
|
||||
ChangeFileApi.deleteContent(curr, path,
|
||||
@@ -491,7 +439,6 @@ public class FileTable extends FlowPanel {
|
||||
private final NativeMap<JsArray<CommentInfo>> comments;
|
||||
private final NativeMap<JsArray<CommentInfo>> drafts;
|
||||
private final boolean hasUser;
|
||||
private final Mode mode;
|
||||
private boolean attached;
|
||||
private int row;
|
||||
private double start;
|
||||
@@ -505,15 +452,13 @@ public class FileTable extends FlowPanel {
|
||||
JsArray<FileInfo> list,
|
||||
Timestamp myLastReply,
|
||||
NativeMap<JsArray<CommentInfo>> comments,
|
||||
NativeMap<JsArray<CommentInfo>> drafts,
|
||||
Mode mode) {
|
||||
NativeMap<JsArray<CommentInfo>> drafts) {
|
||||
this.myTable = new MyTable(map, list);
|
||||
this.list = list;
|
||||
this.myLastReply = myLastReply;
|
||||
this.comments = comments;
|
||||
this.drafts = drafts;
|
||||
this.hasUser = Gerrit.isSignedIn();
|
||||
this.mode = mode;
|
||||
myTable.addStyleName(R.css().table());
|
||||
}
|
||||
|
||||
@@ -589,7 +534,6 @@ public class FileTable extends FlowPanel {
|
||||
if (mode == Mode.REVIEW) {
|
||||
sb.openTh().setStyleName(R.css().reviewed()).closeTh();
|
||||
} else {
|
||||
sb.openTh().setStyleName(R.css().editButton()).closeTh();
|
||||
sb.openTh().setStyleName(R.css().removeButton()).closeTh();
|
||||
}
|
||||
sb.openTh().setStyleName(R.css().status()).closeTh();
|
||||
@@ -611,7 +555,6 @@ public class FileTable extends FlowPanel {
|
||||
if (mode == Mode.REVIEW) {
|
||||
columnReviewed(sb, info);
|
||||
} else {
|
||||
columnEdit(sb, info);
|
||||
columnDeleteRestore(sb, info);
|
||||
}
|
||||
columnStatus(sb, info);
|
||||
@@ -638,28 +581,19 @@ public class FileTable extends FlowPanel {
|
||||
sb.closeTd();
|
||||
}
|
||||
|
||||
private void columnEdit(SafeHtmlBuilder sb, FileInfo info) {
|
||||
sb.openTd().setStyleName(R.css().editButton());
|
||||
if (hasUser && isEditable(info)) {
|
||||
boolean m = Patch.COMMIT_MSG.equals(info.path());
|
||||
sb.openElement("button")
|
||||
.setAttribute("title",
|
||||
m ? Resources.C.editMessage() : Resources.C.editFileInline())
|
||||
.setAttribute("onclick",
|
||||
(m ? EDIT_MESSAGE : EDIT) + "(event," + info._row() + ")")
|
||||
.append(new ImageResourceRenderer().render(Gerrit.RESOURCES.edit()))
|
||||
.closeElement("button");
|
||||
}
|
||||
sb.closeTd();
|
||||
}
|
||||
|
||||
private void columnPathEdit(SafeHtmlBuilder sb, FileInfo info) {
|
||||
sb.openTd().setStyleName(R.css().pathColumn());
|
||||
String path = info.path();
|
||||
sb.openAnchor();
|
||||
|
||||
if (!isEditable(info)) {
|
||||
sb.setAttribute("onclick", RESTORE + "(event," + info._row() + ")");
|
||||
} else {
|
||||
sb.setAttribute("href", "#" + url(info))
|
||||
.setAttribute("onclick", OPEN + "(event," + info._row()
|
||||
+ ")");
|
||||
}
|
||||
if (!Patch.COMMIT_MSG.equals(path)) {
|
||||
sb.openAnchor()
|
||||
.setAttribute("onclick", (isEditable(info) ? EDIT : RESTORE)
|
||||
+ "(event," + info._row() + ")");
|
||||
int commonPrefixLen = commonPrefix(path);
|
||||
if (commonPrefixLen > 0) {
|
||||
sb.openSpan().setStyleName(R.css().commonPrefix())
|
||||
@@ -667,10 +601,10 @@ public class FileTable extends FlowPanel {
|
||||
.closeSpan();
|
||||
}
|
||||
sb.append(path.substring(commonPrefixLen));
|
||||
sb.closeAnchor();
|
||||
} else {
|
||||
sb.append(Util.C.commitMessage());
|
||||
}
|
||||
sb.closeAnchor();
|
||||
sb.closeTd();
|
||||
}
|
||||
|
||||
@@ -845,8 +779,7 @@ public class FileTable extends FlowPanel {
|
||||
if (mode == Mode.REVIEW) {
|
||||
sb.openTh().setStyleName(R.css().reviewed()).closeTh();
|
||||
} else {
|
||||
sb.openTh().setStyleName(R.css().editButton()).closeTh();
|
||||
sb.openTh().setStyleName(R.css().editButton()).closeTh();
|
||||
sb.openTh().setStyleName(R.css().removeButton()).closeTh();
|
||||
}
|
||||
sb.openTh().setStyleName(R.css().status()).closeTh();
|
||||
sb.openTd().closeTd(); // path
|
||||
|
||||
@@ -86,15 +86,6 @@
|
||||
background-color: #d44;
|
||||
}
|
||||
|
||||
.editButton button {
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
margin: 0 0 0 5px;
|
||||
border: 0;
|
||||
background-color: transparent;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.removeButton button {
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
|
||||
@@ -15,9 +15,11 @@
|
||||
package com.google.gerrit.client.changes;
|
||||
|
||||
import com.google.gerrit.client.VoidResult;
|
||||
import com.google.gerrit.client.rpc.GerritCallback;
|
||||
import com.google.gerrit.client.rpc.NativeString;
|
||||
import com.google.gerrit.client.rpc.RestApi;
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gerrit.reviewdb.client.Patch;
|
||||
import com.google.gerrit.reviewdb.client.PatchSet;
|
||||
import com.google.gwt.core.client.JavaScriptObject;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
@@ -67,21 +69,44 @@ public class ChangeFileApi {
|
||||
wrapper(cb));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the contents of a file or commit message in a PatchSet or change
|
||||
* edit.
|
||||
**/
|
||||
public static void getContentOrMessage(PatchSet.Id id, String path,
|
||||
AsyncCallback<String> cb) {
|
||||
if (Patch.COMMIT_MSG.equals(path)) {
|
||||
getMessage(id, cb);
|
||||
} else {
|
||||
contentEditOrPs(id, path).get(wrapper(cb));
|
||||
}
|
||||
}
|
||||
|
||||
/** Put contents into a File in a change edit. */
|
||||
public static void putContent(PatchSet.Id id, String filename,
|
||||
String content, AsyncCallback<VoidResult> result) {
|
||||
String content, GerritCallback<VoidResult> result) {
|
||||
contentEdit(id.getParentKey(), filename).put(content, result);
|
||||
}
|
||||
|
||||
/** Put contents into a File or commit message in a change edit. */
|
||||
public static void putContentOrMessage(PatchSet.Id id, String path,
|
||||
String content, GerritCallback<VoidResult> result) {
|
||||
if (Patch.COMMIT_MSG.equals(path)) {
|
||||
putMessage(id, content, result);
|
||||
} else {
|
||||
contentEdit(id.getParentKey(), path).put(content, result);
|
||||
}
|
||||
}
|
||||
|
||||
/** Put message into a change edit. */
|
||||
public static void putMessage(PatchSet.Id id, String m,
|
||||
AsyncCallback<VoidResult> r) {
|
||||
private static void putMessage(PatchSet.Id id, String m,
|
||||
GerritCallback<VoidResult> r) {
|
||||
putMessage(id.getParentKey(), m, r);
|
||||
}
|
||||
|
||||
/** Put message into a change edit. */
|
||||
public static void putMessage(Change.Id id, String m,
|
||||
AsyncCallback<VoidResult> r) {
|
||||
GerritCallback<VoidResult> r) {
|
||||
ChangeApi.change(id.get()).view("edit:message").put(m, r);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,12 +16,9 @@ package com.google.gerrit.client.diff;
|
||||
|
||||
import com.google.gerrit.client.Dispatcher;
|
||||
import com.google.gerrit.client.Gerrit;
|
||||
import com.google.gerrit.client.VoidResult;
|
||||
import com.google.gerrit.client.WebLinkInfo;
|
||||
import com.google.gerrit.client.changes.ChangeFileApi;
|
||||
import com.google.gerrit.client.changes.ChangeInfo.RevisionInfo;
|
||||
import com.google.gerrit.client.patches.PatchUtil;
|
||||
import com.google.gerrit.client.rpc.GerritCallback;
|
||||
import com.google.gerrit.client.rpc.Natives;
|
||||
import com.google.gerrit.client.ui.InlineHyperlink;
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
@@ -30,7 +27,6 @@ import com.google.gerrit.reviewdb.client.PatchSet;
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.core.client.JsArray;
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.event.dom.client.ClickHandler;
|
||||
import com.google.gwt.resources.client.CssResource;
|
||||
import com.google.gwt.uibinder.client.UiBinder;
|
||||
import com.google.gwt.uibinder.client.UiField;
|
||||
@@ -114,8 +110,7 @@ class PatchSetSelectBox2 extends Composite {
|
||||
if (!Patch.COMMIT_MSG.equals(path)) {
|
||||
linkPanel.add(createDownloadLink());
|
||||
}
|
||||
if (open && idActive != null && Gerrit.isSignedIn()
|
||||
&& !Patch.COMMIT_MSG.equals(path)) {
|
||||
if (open && idActive != null && Gerrit.isSignedIn()) {
|
||||
if ((editExists && idActive.get() == 0)
|
||||
|| (!editExists && idActive.get() == currentPatchSet)) {
|
||||
linkPanel.add(createEditIcon());
|
||||
@@ -130,37 +125,10 @@ class PatchSetSelectBox2 extends Composite {
|
||||
}
|
||||
|
||||
private Widget createEditIcon() {
|
||||
final Anchor anchor = new Anchor(
|
||||
new ImageResourceRenderer().render(Gerrit.RESOURCES.edit()));
|
||||
anchor.addClickHandler(new ClickHandler() {
|
||||
boolean editing = false;
|
||||
@Override
|
||||
public void onClick(ClickEvent event) {
|
||||
final PatchSet.Id id = (idActive == null) ? other.idActive : idActive;
|
||||
editing = !editing;
|
||||
parent.editSideB(editing);
|
||||
|
||||
if (editing) {
|
||||
ChangeFileApi.getContent(id, path,
|
||||
new GerritCallback<String>() {
|
||||
@Override
|
||||
public void onSuccess(String content) {
|
||||
parent.setSideBContent(content);
|
||||
}
|
||||
});
|
||||
anchor.setHTML(new ImageResourceRenderer().render(Gerrit.RESOURCES.save()));
|
||||
} else {
|
||||
anchor.setHTML(new ImageResourceRenderer().render(Gerrit.RESOURCES.edit()));
|
||||
String siteBContent = parent.getSideBContent();
|
||||
ChangeFileApi.putContent(id, path, siteBContent,
|
||||
new GerritCallback<VoidResult>() {
|
||||
@Override
|
||||
public void onSuccess(VoidResult result) {
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
PatchSet.Id id = (idActive == null) ? other.idActive : idActive;
|
||||
Anchor anchor = new Anchor(
|
||||
new ImageResourceRenderer().render(Gerrit.RESOURCES.edit()),
|
||||
"#" + Dispatcher.toEditScreen(id, path));
|
||||
anchor.setTitle(PatchUtil.C.edit());
|
||||
return anchor;
|
||||
}
|
||||
|
||||
@@ -138,8 +138,6 @@ public class SideBySide2 extends Screen {
|
||||
private List<HandlerRegistration> handlers;
|
||||
private PreferencesAction prefsAction;
|
||||
private int reloadVersionId;
|
||||
private KeyMap sbsKeyMap;
|
||||
private boolean isEdited = false;
|
||||
|
||||
public SideBySide2(
|
||||
PatchSet.Id base,
|
||||
@@ -349,7 +347,7 @@ public class SideBySide2 extends Screen {
|
||||
cm.on("cursorActivity", updateActiveLine(cm));
|
||||
cm.on("gutterClick", onGutterClick(cm));
|
||||
cm.on("focus", updateActiveLine(cm));
|
||||
sbsKeyMap = KeyMap.create()
|
||||
cm.addKeyMap(KeyMap.create()
|
||||
.on("A", upToChange(true))
|
||||
.on("U", upToChange(false))
|
||||
.on("[", header.navigate(Direction.PREV))
|
||||
@@ -415,8 +413,7 @@ public class SideBySide2 extends Screen {
|
||||
public void run() {
|
||||
cm.execCommand("selectAll");
|
||||
}
|
||||
});
|
||||
cm.addKeyMap(sbsKeyMap);
|
||||
}));
|
||||
if (prefs.renderEntireFile()) {
|
||||
cm.addKeyMap(RENDER_ENTIRE_FILE_KEYMAP);
|
||||
}
|
||||
@@ -428,9 +425,6 @@ public class SideBySide2 extends Screen {
|
||||
|
||||
@Override
|
||||
public void handle(CodeMirror cm, LineCharacter anchor, LineCharacter head) {
|
||||
if (isEdited) {
|
||||
return;
|
||||
}
|
||||
if (anchor == head
|
||||
|| (anchor.getLine() == head.getLine()
|
||||
&& anchor.getCh() == head.getCh())) {
|
||||
@@ -549,30 +543,6 @@ public class SideBySide2 extends Screen {
|
||||
}));
|
||||
}
|
||||
|
||||
public void editSideB(boolean state) {
|
||||
isEdited = state;
|
||||
cmB.setOption("readOnly", !state);
|
||||
JumpKeys.enable(!state);
|
||||
if (state) {
|
||||
removeKeyHandlerRegistrations();
|
||||
cmB.removeKeyMap(sbsKeyMap);
|
||||
cmB.setOption("keyMap", "default");
|
||||
cmB.focus();
|
||||
} else {
|
||||
cmB.setOption("keyMap", "vim_ro");
|
||||
cmB.addKeyMap(sbsKeyMap);
|
||||
registerKeys();
|
||||
}
|
||||
}
|
||||
|
||||
public String getSideBContent() {
|
||||
return cmB.getValue();
|
||||
}
|
||||
|
||||
public void setSideBContent(String content) {
|
||||
cmB.setValue(content);
|
||||
}
|
||||
|
||||
private void display(final CommentsCollections comments) {
|
||||
setThemeStyles(prefs.theme().isDark());
|
||||
setShowTabs(prefs.showTabs());
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
// 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.google.gerrit.client.editor;
|
||||
|
||||
import com.google.gerrit.client.Gerrit;
|
||||
import com.google.gerrit.client.VoidResult;
|
||||
import com.google.gerrit.client.changes.ChangeFileApi;
|
||||
import com.google.gerrit.client.rpc.CallbackGroup;
|
||||
import com.google.gerrit.client.rpc.GerritCallback;
|
||||
import com.google.gerrit.client.rpc.ScreenLoadCallback;
|
||||
import com.google.gerrit.client.ui.Screen;
|
||||
import com.google.gerrit.common.PageLinks;
|
||||
import com.google.gerrit.reviewdb.client.Patch;
|
||||
import com.google.gerrit.reviewdb.client.PatchSet;
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.dom.client.Element;
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.event.dom.client.KeyPressEvent;
|
||||
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.Window;
|
||||
import com.google.gwt.user.client.ui.Button;
|
||||
import com.google.gwt.user.client.ui.HTMLPanel;
|
||||
import com.google.gwtexpui.globalkey.client.GlobalKey;
|
||||
|
||||
import net.codemirror.lib.CodeMirror;
|
||||
import net.codemirror.lib.Configuration;
|
||||
|
||||
public class EditScreen extends Screen {
|
||||
|
||||
interface Binder extends UiBinder<HTMLPanel, EditScreen> {}
|
||||
private static final Binder uiBinder = GWT.create(Binder.class);
|
||||
|
||||
private final PatchSet.Id revision;
|
||||
private final String path;
|
||||
private CodeMirror cm;
|
||||
|
||||
@UiField Element filePath;
|
||||
@UiField Button cancel;
|
||||
@UiField Button save;
|
||||
@UiField Element editor;
|
||||
|
||||
public EditScreen(Patch.Key patch) {
|
||||
this.revision = patch.getParentKey();
|
||||
this.path = patch.get();
|
||||
add(uiBinder.createAndBindUi(this));
|
||||
addDomHandler(GlobalKey.STOP_PROPAGATION, KeyPressEvent.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInitUI() {
|
||||
super.onInitUI();
|
||||
setHeaderVisible(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLoad() {
|
||||
super.onLoad();
|
||||
CallbackGroup cmGroup = new CallbackGroup();
|
||||
CodeMirror.initLibrary(cmGroup.add(CallbackGroup.<Void> emptyCallback()));
|
||||
initPath();
|
||||
ChangeFileApi.getContentOrMessage(revision, path,
|
||||
cmGroup.addFinal(new ScreenLoadCallback<String>(this) {
|
||||
@Override
|
||||
protected void preDisplay(String content) {
|
||||
initEditor(content);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShowView() {
|
||||
super.onShowView();
|
||||
int rest = Gerrit.getHeaderFooterHeight()
|
||||
+ 30; // Estimate
|
||||
cm.setHeight(Window.getClientHeight() - rest);
|
||||
cm.refresh();
|
||||
cm.focus();
|
||||
}
|
||||
|
||||
@UiHandler("save")
|
||||
void onSave(@SuppressWarnings("unused") ClickEvent e) {
|
||||
ChangeFileApi.putContentOrMessage(revision, path, cm.getValue(),
|
||||
new GerritCallback<VoidResult>() {
|
||||
@Override
|
||||
public void onSuccess(VoidResult result) {
|
||||
Gerrit.display(PageLinks.toChangeInEditMode(
|
||||
revision.getParentKey()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@UiHandler("cancel")
|
||||
void onCancel(@SuppressWarnings("unused") ClickEvent e) {
|
||||
Gerrit.display(PageLinks.toChangeInEditMode(revision.getParentKey()));
|
||||
}
|
||||
|
||||
private void initEditor(String content) {
|
||||
cm = CodeMirror.create(editor, getConfig());
|
||||
cm.setValue(content);
|
||||
}
|
||||
|
||||
private Configuration getConfig() {
|
||||
// TODO(davido): Retrieve user preferences from AllUsers repository
|
||||
// TODO(davido): Retrieve file content type to activate syntax highlighting
|
||||
return Configuration.create()
|
||||
.set("readOnly", false)
|
||||
.set("cursorBlinkRate", 0)
|
||||
.set("cursorHeight", 0.85)
|
||||
.set("lineNumbers", true)
|
||||
.set("tabSize", 4)
|
||||
.set("lineWrapping", false)
|
||||
.set("styleSelectedText", true)
|
||||
.set("showTrailingSpace", true)
|
||||
.set("keyMap", "default");
|
||||
}
|
||||
|
||||
private void initPath() {
|
||||
filePath.setInnerText(path);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
|
||||
xmlns:g='urn:import:com.google.gwt.user.client.ui'
|
||||
xmlns:e='urn:import:com.google.gerrit.client.editor'>
|
||||
<ui:style>
|
||||
@eval trimColor com.google.gerrit.client.Gerrit.getTheme().trimColor;
|
||||
|
||||
@def HEADER_HEIGHT 30px;
|
||||
@def BUTTON_HEIGHT 14px;
|
||||
|
||||
.infoLine {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 10px;
|
||||
height: HEADER_HEIGHT;
|
||||
padding-left: 25px;
|
||||
}
|
||||
|
||||
.headerLine {
|
||||
position: relative;
|
||||
background-color: trimColor;
|
||||
height: HEADER_HEIGHT;
|
||||
margin: 0 -5px;
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.headerButtons button:disabled,
|
||||
#change_infoTable button:disabled,
|
||||
.popdown button:disabled {
|
||||
background-color: #999;
|
||||
}
|
||||
|
||||
.headerButtons button {
|
||||
margin: 6px 3px 0 0;
|
||||
text-align: center;
|
||||
font-size: 8pt;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
border: 2px solid;
|
||||
color: rgba(0, 0, 0, 0.15);
|
||||
background-color: #f5f5f5;
|
||||
-webkit-border-radius: 2px;
|
||||
-webkit-box-sizing: content-box;
|
||||
}
|
||||
|
||||
.headerButtons button div {
|
||||
color: #444;
|
||||
min-width: 54px;
|
||||
white-space: nowrap;
|
||||
height: BUTTON_HEIGHT;
|
||||
line-height: BUTTON_HEIGHT;
|
||||
}
|
||||
|
||||
.infoLineHeaderButtons {
|
||||
display: inline-block;
|
||||
height: HEADER_HEIGHT;
|
||||
line-height: HEADER_HEIGHT;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.path {
|
||||
white-space: nowrap;
|
||||
}
|
||||
</ui:style>
|
||||
<g:HTMLPanel>
|
||||
<g:HTMLPanel styleName='{style.headerLine}'>
|
||||
<div class='{style.infoLine}'>
|
||||
<div class='{style.headerButtons} {style.infoLineHeaderButtons}'>
|
||||
<g:Button ui:field='cancel'
|
||||
styleName=''
|
||||
title='Cancel'>
|
||||
<ui:attribute name='title'/>
|
||||
<div><ui:msg>Cancel</ui:msg></div>
|
||||
</g:Button>
|
||||
<g:Button ui:field='save'
|
||||
styleName=''
|
||||
title='Save'>
|
||||
<ui:attribute name='title'/>
|
||||
<div><ui:msg>Save</ui:msg></div>
|
||||
</g:Button>
|
||||
|
|
||||
<span class='{style.path}' ui:field='filePath'/>
|
||||
</div>
|
||||
</div>
|
||||
</g:HTMLPanel>
|
||||
<div ui:field='editor' />
|
||||
</g:HTMLPanel>
|
||||
</ui:UiBinder>
|
||||
@@ -41,6 +41,10 @@ public class CodeMirror extends JavaScriptObject {
|
||||
return m;
|
||||
}-*/;
|
||||
|
||||
public static CodeMirror create(Element parent, Configuration cfg) {
|
||||
return create(null, parent, cfg);
|
||||
}
|
||||
|
||||
public final native void setOption(String option, boolean value) /*-{
|
||||
this.setOption(option, value);
|
||||
}-*/;
|
||||
@@ -95,15 +99,7 @@ public class CodeMirror extends JavaScriptObject {
|
||||
|
||||
private final native void addLineClassNative(LineHandle line, String where,
|
||||
String lineClass) /*-{
|
||||
try {
|
||||
this.addLineClass(line, where, lineClass);
|
||||
} catch (err) {
|
||||
if ("TypeError: Cannot read property 'parrent' of undefinded" == err.toString()) {
|
||||
// ignore CodeMirror bug after going to new line
|
||||
return;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
}-*/;
|
||||
|
||||
public final void removeLineClass(int line, LineClassWhere where,
|
||||
|
||||
Reference in New Issue
Block a user