Merge changes I826fdc7d,I2e1cbe93

* changes:
  Implementing UI for range comment
  Fix handling of comment sides
This commit is contained in:
Shawn Pearce
2013-08-15 06:31:28 +00:00
committed by Gerrit Code Review
13 changed files with 278 additions and 132 deletions

View File

@@ -16,12 +16,18 @@ package com.google.gerrit.client.diff;
import com.google.gerrit.client.changes.CommentInfo; import com.google.gerrit.client.changes.CommentInfo;
import com.google.gerrit.client.diff.PaddingManager.PaddingWidgetWrapper; import com.google.gerrit.client.diff.PaddingManager.PaddingWidgetWrapper;
import com.google.gerrit.client.diff.SideBySide2.DisplaySide;
import com.google.gerrit.client.diff.SideBySide2.DiffChunkInfo; import com.google.gerrit.client.diff.SideBySide2.DiffChunkInfo;
import com.google.gerrit.client.diff.SidePanel.GutterWrapper; import com.google.gerrit.client.diff.SidePanel.GutterWrapper;
import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Composite;
import net.codemirror.lib.CodeMirror;
import net.codemirror.lib.Configuration;
import net.codemirror.lib.TextMarker;
import net.codemirror.lib.TextMarker.FromTo;
/** An HtmlPanel for displaying a comment */ /** An HtmlPanel for displaying a comment */
abstract class CommentBox extends Composite { abstract class CommentBox extends Composite {
static { static {
@@ -31,8 +37,27 @@ abstract class CommentBox extends Composite {
private PaddingManager widgetManager; private PaddingManager widgetManager;
private PaddingWidgetWrapper selfWidgetWrapper; private PaddingWidgetWrapper selfWidgetWrapper;
private SideBySide2 parent; private SideBySide2 parent;
private CodeMirror cm;
private DisplaySide side;
private DiffChunkInfo diffChunkInfo; private DiffChunkInfo diffChunkInfo;
private GutterWrapper gutterWrapper; private GutterWrapper gutterWrapper;
private FromTo fromTo;
private TextMarker rangeMarker;
private TextMarker rangeHighlightMarker;
CommentBox(CodeMirror cm, CommentInfo info, DisplaySide side) {
this.cm = cm;
this.side = side;
CommentRange range = info.range();
if (range != null) {
fromTo = FromTo.create(range);
rangeMarker = cm.markText(
fromTo.getFrom(),
fromTo.getTo(),
Configuration.create()
.set("className", DiffTable.style.range()));
}
}
@Override @Override
protected void onLoad() { protected void onLoad() {
@@ -49,8 +74,7 @@ abstract class CommentBox extends Composite {
assert selfWidgetWrapper != null; assert selfWidgetWrapper != null;
selfWidgetWrapper.getWidget().changed(); selfWidgetWrapper.getWidget().changed();
if (diffChunkInfo != null) { if (diffChunkInfo != null) {
parent.resizePaddingOnOtherSide(getCommentInfo().side(), parent.resizePaddingOnOtherSide(side, diffChunkInfo.getEnd());
diffChunkInfo.getEnd());
} else { } else {
assert widgetManager != null; assert widgetManager != null;
widgetManager.resizePaddingWidget(); widgetManager.resizePaddingWidget();
@@ -64,6 +88,7 @@ abstract class CommentBox extends Composite {
void setOpen(boolean open) { void setOpen(boolean open) {
resizePaddingWidget(); resizePaddingWidget();
setRangeHighlight(open);
} }
PaddingManager getPaddingManager() { PaddingManager getPaddingManager() {
@@ -94,7 +119,36 @@ abstract class CommentBox extends Composite {
gutterWrapper = wrapper; gutterWrapper = wrapper;
} }
void setRangeHighlight(boolean highlight) {
if (fromTo != null) {
if (highlight && rangeHighlightMarker == null) {
rangeHighlightMarker = cm.markText(
fromTo.getFrom(),
fromTo.getTo(),
Configuration.create()
.set("className", DiffTable.style.rangeHighlight()));
} else if (!highlight && rangeHighlightMarker != null) {
rangeHighlightMarker.clear();
rangeHighlightMarker = null;
}
}
}
void clearRange() {
if (rangeMarker != null) {
rangeMarker.clear();
}
}
GutterWrapper getGutterWrapper() { GutterWrapper getGutterWrapper() {
return gutterWrapper; return gutterWrapper;
} }
DisplaySide getSide() {
return side;
}
CodeMirror getCm() {
return cm;
}
} }

View File

@@ -16,6 +16,9 @@ package com.google.gerrit.client.diff;
import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.JavaScriptObject;
import net.codemirror.lib.LineCharacter;
import net.codemirror.lib.TextMarker.FromTo;
public class CommentRange extends JavaScriptObject { public class CommentRange extends JavaScriptObject {
public static CommentRange create(int sl, int sc, int el, int ec) { public static CommentRange create(int sl, int sc, int el, int ec) {
CommentRange r = createObject().cast(); CommentRange r = createObject().cast();
@@ -23,6 +26,18 @@ public class CommentRange extends JavaScriptObject {
return r; return r;
} }
public static CommentRange create(FromTo fromTo) {
if (fromTo == null) {
return null;
}
LineCharacter from = fromTo.getFrom();
LineCharacter to = fromTo.getTo();
return create(
from.getLine() + 1, from.getCh(),
to.getLine() + 1, to.getCh());
}
public final native int start_line() /*-{ return this.start_line; }-*/; public final native int start_line() /*-{ return this.start_line; }-*/;
public final native int start_character() /*-{ return this.start_character; }-*/; public final native int start_character() /*-{ return this.start_character; }-*/;
public final native int end_line() /*-{ return this.end_line; }-*/; public final native int end_line() /*-{ return this.end_line; }-*/;

View File

@@ -14,7 +14,7 @@
package com.google.gerrit.client.diff; package com.google.gerrit.client.diff;
import com.google.gerrit.common.changes.Side; import com.google.gerrit.client.diff.SideBySide2.DisplaySide;
import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.Element;
import com.google.gwt.resources.client.CssResource; import com.google.gwt.resources.client.CssResource;
@@ -40,6 +40,8 @@ class DiffTable extends Composite {
String activeLine(); String activeLine();
String activeLineBg(); String activeLineBg();
String hideNumber(); String hideNumber();
String range();
String rangeHighlight();
} }
@UiField @UiField
@@ -87,10 +89,10 @@ class DiffTable extends Composite {
private SideBySide2 host; private SideBySide2 host;
DiffTable(SideBySide2 host, String path) { DiffTable(SideBySide2 host, String path) {
patchSelectBoxA = new PatchSelectBox2(this, Side.PARENT); patchSelectBoxA = new PatchSelectBox2(this, DisplaySide.A);
patchSelectBoxB = new PatchSelectBox2(this, Side.REVISION); patchSelectBoxB = new PatchSelectBox2(this, DisplaySide.B);
fileCommentPanelA = new FileCommentPanel(host, this, path, Side.PARENT); fileCommentPanelA = new FileCommentPanel(host, this, path, DisplaySide.A);
fileCommentPanelB = new FileCommentPanel(host, this, path, Side.REVISION); fileCommentPanelB = new FileCommentPanel(host, this, path, DisplaySide.B);
initWidget(uiBinder.createAndBindUi(this)); initWidget(uiBinder.createAndBindUi(this));
this.host = host; this.host = host;
} }
@@ -111,21 +113,21 @@ class DiffTable extends Composite {
host.resizeCodeMirror(); host.resizeCodeMirror();
} }
private FileCommentPanel getPanelFromSide(Side side) { private FileCommentPanel getPanelFromSide(DisplaySide side) {
return side == Side.PARENT ? fileCommentPanelA : fileCommentPanelB; return side == DisplaySide.A ? fileCommentPanelA : fileCommentPanelB;
} }
void createOrEditFileComment(Side side) { void createOrEditFileComment(DisplaySide side) {
getPanelFromSide(side).createOrEditFileComment(); getPanelFromSide(side).createOrEditFileComment();
updateFileCommentVisibility(false); updateFileCommentVisibility(false);
} }
void addFileCommentBox(CommentBox box, Side side) { void addFileCommentBox(CommentBox box) {
getPanelFromSide(side).addFileComment(box); getPanelFromSide(box.getSide()).addFileComment(box);
} }
void onRemoveDraftBox(DraftBox box, Side side) { void onRemoveDraftBox(DraftBox box) {
getPanelFromSide(side).onRemoveDraftBox(box); getPanelFromSide(box.getSide()).onRemoveDraftBox(box);
} }
int getHeaderHeight() { int getHeaderHeight() {

View File

@@ -76,6 +76,12 @@ limitations under the License.
.activeLineBg { .activeLineBg {
background-color: #E0FFFF !important; background-color: #E0FFFF !important;
} }
.range {
background-color: #ffd500 !important;
}
.rangeHighlight {
background-color: #ffff00 !important;
}
.cm-searching { .cm-searching {
background-color: #ffa !important; background-color: #ffa !important;
} }

View File

@@ -18,9 +18,9 @@ import com.google.gerrit.client.FormatUtil;
import com.google.gerrit.client.changes.CommentApi; import com.google.gerrit.client.changes.CommentApi;
import com.google.gerrit.client.changes.CommentInfo; import com.google.gerrit.client.changes.CommentInfo;
import com.google.gerrit.client.changes.CommentInput; import com.google.gerrit.client.changes.CommentInput;
import com.google.gerrit.client.diff.SideBySide2.DisplaySide;
import com.google.gerrit.client.rpc.GerritCallback; import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.ui.CommentLinkProcessor; import com.google.gerrit.client.ui.CommentLinkProcessor;
import com.google.gerrit.common.changes.Side;
import com.google.gerrit.reviewdb.client.PatchSet; import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.JavaScriptObject;
@@ -59,7 +59,6 @@ class DraftBox extends CommentBox {
private static final int MAX_LINES = 30; private static final int MAX_LINES = 30;
private final SideBySide2 parent; private final SideBySide2 parent;
private final CodeMirror cm;
private final CommentLinkProcessor linkProcessor; private final CommentLinkProcessor linkProcessor;
private final PatchSet.Id psId; private final PatchSet.Id psId;
private CommentInfo comment; private CommentInfo comment;
@@ -82,15 +81,17 @@ class DraftBox extends CommentBox {
@UiField Button discard2; @UiField Button discard2;
DraftBox( DraftBox(
SideBySide2 parent, SideBySide2 sideBySide,
CodeMirror cm, CodeMirror cm,
DisplaySide side,
CommentLinkProcessor clp, CommentLinkProcessor clp,
PatchSet.Id id, PatchSet.Id id,
CommentInfo info) { CommentInfo info) {
this.parent = parent; super(cm, info, side);
this.cm = cm;
this.linkProcessor = clp; parent = sideBySide;
this.psId = id; linkProcessor = clp;
psId = id;
initWidget(uiBinder.createAndBindUi(this)); initWidget(uiBinder.createAndBindUi(this));
expandTimer = new Timer() { expandTimer = new Timer() {
@@ -136,7 +137,7 @@ class DraftBox extends CommentBox {
message.setHTML(linkProcessor.apply( message.setHTML(linkProcessor.apply(
new SafeHtmlBuilder().append(msg).wikify())); new SafeHtmlBuilder().append(msg).wikify()));
} }
this.comment = info; comment = info;
} }
@Override @Override
@@ -178,6 +179,7 @@ class DraftBox extends CommentBox {
UIObject.setVisible(p_view, !edit); UIObject.setVisible(p_view, !edit);
UIObject.setVisible(p_edit, edit); UIObject.setVisible(p_edit, edit);
setRangeHighlight(edit);
if (edit) { if (edit) {
final String msg = comment.message() != null final String msg = comment.message() != null
? comment.message().trim() ? comment.message().trim()
@@ -215,16 +217,17 @@ class DraftBox extends CommentBox {
if (replyToBox != null) { if (replyToBox != null) {
replyToBox.unregisterReplyBox(); replyToBox.unregisterReplyBox();
} }
Side side = comment.side(); clearRange();
setRangeHighlight(false);
removeFromParent(); removeFromParent();
if (!getCommentInfo().has_line()) { if (!getCommentInfo().has_line()) {
parent.removeFileCommentBox(this, side); parent.removeFileCommentBox(this);
return; return;
} }
PaddingManager manager = getPaddingManager(); PaddingManager manager = getPaddingManager();
manager.remove(this); manager.remove(this);
parent.removeDraft(this, side, comment.line() - 1); parent.removeDraft(this, comment.line() - 1);
cm.focus(); getCm().focus();
getSelfWidgetWrapper().getWidget().clear(); getSelfWidgetWrapper().getWidget().clear();
getGutterWrapper().remove(); getGutterWrapper().remove();
Scheduler.get().scheduleDeferred(new ScheduledCommand() { Scheduler.get().scheduleDeferred(new ScheduledCommand() {
@@ -292,7 +295,7 @@ class DraftBox extends CommentBox {
} else { } else {
CommentApi.updateDraft(psId, original.id(), input, cb); CommentApi.updateDraft(psId, original.id(), input, cb);
} }
cm.focus(); getCm().focus();
} }
private void enableEdit(boolean on) { private void enableEdit(boolean on) {
@@ -309,7 +312,7 @@ class DraftBox extends CommentBox {
removeUI(); removeUI();
} else { } else {
setEdit(false); setEdit(false);
cm.focus(); getCm().focus();
} }
} }
@@ -347,7 +350,7 @@ class DraftBox extends CommentBox {
return; return;
} else { } else {
setEdit(false); setEdit(false);
cm.focus(); getCm().focus();
return; return;
} }
} }

View File

@@ -16,7 +16,7 @@ package com.google.gerrit.client.diff;
import com.google.gerrit.client.Gerrit; import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.changes.CommentInfo; import com.google.gerrit.client.changes.CommentInfo;
import com.google.gerrit.common.changes.Side; import com.google.gerrit.client.diff.SideBySide2.DisplaySide;
import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.FlowPanel;
@@ -33,11 +33,11 @@ class FileCommentPanel extends Composite {
private SideBySide2 parent; private SideBySide2 parent;
private DiffTable table; private DiffTable table;
private String path; private String path;
private Side side; private DisplaySide side;
private List<CommentBox> boxes; private List<CommentBox> boxes;
private FlowPanel body; private FlowPanel body;
FileCommentPanel(SideBySide2 host, DiffTable table, String path, Side side) { FileCommentPanel(SideBySide2 host, DiffTable table, String path, DisplaySide side) {
this.parent = host; this.parent = host;
this.table = table; this.table = table;
this.path = path; this.path = path;
@@ -54,10 +54,10 @@ class FileCommentPanel extends Composite {
if (boxes.isEmpty()) { if (boxes.isEmpty()) {
CommentInfo info = CommentInfo.createFile( CommentInfo info = CommentInfo.createFile(
path, path,
side, parent.getStoredSideFromDisplaySide(side),
null, null,
null); null);
addFileComment(parent.addDraftBox(info)); addFileComment(parent.addDraftBox(info, side));
} else { } else {
CommentBox box = boxes.get(boxes.size() - 1); CommentBox box = boxes.get(boxes.size() - 1);
if (box instanceof DraftBox) { if (box instanceof DraftBox) {

View File

@@ -14,7 +14,7 @@
package com.google.gerrit.client.diff; package com.google.gerrit.client.diff;
import com.google.gerrit.common.changes.Side; import com.google.gerrit.client.diff.SideBySide2.DisplaySide;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@@ -98,8 +98,8 @@ class LineMapper {
* - | 6 * - | 6
* ... * ...
*/ */
LineOnOtherInfo lineOnOther(Side mySide, int line) { LineOnOtherInfo lineOnOther(DisplaySide mySide, int line) {
List<LineGap> lineGaps = mySide == Side.PARENT ? lineMapAtoB : lineMapBtoA; List<LineGap> lineGaps = mySide == DisplaySide.A ? lineMapAtoB : lineMapBtoA;
// Create a dummy LineGap for the search. // Create a dummy LineGap for the search.
int ret = Collections.binarySearch(lineGaps, new LineGap(line)); int ret = Collections.binarySearch(lineGaps, new LineGap(line));
if (ret == -1) { if (ret == -1) {

View File

@@ -15,8 +15,8 @@
package com.google.gerrit.client.diff; package com.google.gerrit.client.diff;
import com.google.gerrit.client.Gerrit; import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.diff.SideBySide2.DisplaySide;
import com.google.gerrit.client.patches.PatchUtil; import com.google.gerrit.client.patches.PatchUtil;
import com.google.gerrit.common.changes.Side;
import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiBinder;
@@ -38,9 +38,9 @@ class PatchSelectBox2 extends Composite {
Image icon; Image icon;
private DiffTable table; private DiffTable table;
private Side side; private DisplaySide side;
PatchSelectBox2(DiffTable table, Side side) { PatchSelectBox2(DiffTable table, DisplaySide side) {
initWidget(uiBinder.createAndBindUi(this)); initWidget(uiBinder.createAndBindUi(this));
icon.setTitle(PatchUtil.C.addFileCommentToolTip()); icon.setTitle(PatchUtil.C.addFileCommentToolTip());
icon.addStyleName(Gerrit.RESOURCES.css().link()); icon.addStyleName(Gerrit.RESOURCES.css().link());

View File

@@ -21,6 +21,7 @@ import com.google.gerrit.client.changes.CommentApi;
import com.google.gerrit.client.changes.CommentInfo; import com.google.gerrit.client.changes.CommentInfo;
import com.google.gerrit.client.changes.CommentInput; import com.google.gerrit.client.changes.CommentInput;
import com.google.gerrit.client.changes.Util; import com.google.gerrit.client.changes.Util;
import com.google.gerrit.client.diff.SideBySide2.DisplaySide;
import com.google.gerrit.client.patches.PatchUtil; import com.google.gerrit.client.patches.PatchUtil;
import com.google.gerrit.client.rpc.GerritCallback; import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.ui.CommentLinkProcessor; import com.google.gerrit.client.ui.CommentLinkProcessor;
@@ -39,6 +40,8 @@ import com.google.gwt.user.client.ui.UIObject;
import com.google.gwt.user.client.ui.Widget; import com.google.gwt.user.client.ui.Widget;
import com.google.gwtexpui.safehtml.client.SafeHtmlBuilder; import com.google.gwtexpui.safehtml.client.SafeHtmlBuilder;
import net.codemirror.lib.CodeMirror;
/** An HtmlPanel for displaying a published comment */ /** An HtmlPanel for displaying a published comment */
class PublishedBox extends CommentBox { class PublishedBox extends CommentBox {
interface Binder extends UiBinder<HTMLPanel, PublishedBox> {} interface Binder extends UiBinder<HTMLPanel, PublishedBox> {}
@@ -68,9 +71,13 @@ class PublishedBox extends CommentBox {
PublishedBox( PublishedBox(
SideBySide2 parent, SideBySide2 parent,
CodeMirror cm,
DisplaySide side,
CommentLinkProcessor clp, CommentLinkProcessor clp,
PatchSet.Id psId, PatchSet.Id psId,
CommentInfo info) { CommentInfo info) {
super(cm, info, side);
this.parent = parent; this.parent = parent;
this.psId = psId; this.psId = psId;
this.comment = info; this.comment = info;
@@ -137,7 +144,7 @@ class PublishedBox extends CommentBox {
} }
DraftBox addReplyBox() { DraftBox addReplyBox() {
DraftBox box = parent.addDraftBox(parent.createReply(comment)); DraftBox box = parent.addDraftBox(parent.createReply(comment), getSide());
registerReplyBox(box); registerReplyBox(box);
return box; return box;
} }
@@ -148,7 +155,7 @@ class PublishedBox extends CommentBox {
} else if (replyBox == null) { } else if (replyBox == null) {
DraftBox box = addReplyBox(); DraftBox box = addReplyBox();
if (!getCommentInfo().has_line()) { if (!getCommentInfo().has_line()) {
parent.addFileCommentBox(box, comment.side()); parent.addFileCommentBox(box);
} }
} else { } else {
openReplyBox(); openReplyBox();
@@ -176,10 +183,10 @@ class PublishedBox extends CommentBox {
public void onSuccess(CommentInfo result) { public void onSuccess(CommentInfo result) {
done.setEnabled(true); done.setEnabled(true);
setOpen(false); setOpen(false);
DraftBox box = parent.addDraftBox(result); DraftBox box = parent.addDraftBox(result, getSide());
registerReplyBox(box); registerReplyBox(box);
if (!getCommentInfo().has_line()) { if (!getCommentInfo().has_line()) {
parent.addFileCommentBox(box, comment.side()); parent.addFileCommentBox(box);
} }
} }
}); });

View File

@@ -78,6 +78,7 @@ import net.codemirror.lib.LineCharacter;
import net.codemirror.lib.LineWidget; import net.codemirror.lib.LineWidget;
import net.codemirror.lib.ModeInjector; import net.codemirror.lib.ModeInjector;
import net.codemirror.lib.ScrollInfo; import net.codemirror.lib.ScrollInfo;
import net.codemirror.lib.TextMarker.FromTo;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@@ -90,6 +91,10 @@ public class SideBySide2 extends Screen {
interface Binder extends UiBinder<FlowPanel, SideBySide2> {} interface Binder extends UiBinder<FlowPanel, SideBySide2> {}
private static Binder uiBinder = GWT.create(Binder.class); private static Binder uiBinder = GWT.create(Binder.class);
enum DisplaySide {
A, B;
}
private static final JsArrayString EMPTY = private static final JsArrayString EMPTY =
JavaScriptObject.createArray().cast(); JavaScriptObject.createArray().cast();
@@ -108,8 +113,10 @@ public class SideBySide2 extends Screen {
private Timer scrollTimerA; private Timer scrollTimerA;
private Timer scrollTimerB; private Timer scrollTimerB;
private HandlerRegistration resizeHandler; private HandlerRegistration resizeHandler;
private JsArray<CommentInfo> published; private JsArray<CommentInfo> publishedBase;
private JsArray<CommentInfo> drafts; private JsArray<CommentInfo> publishedRevision;
private JsArray<CommentInfo> draftsBase;
private JsArray<CommentInfo> draftsRevision;
private DiffInfo diff; private DiffInfo diff;
private LineMapper mapper; private LineMapper mapper;
private CommentLinkProcessor commentLinkProcessor; private CommentLinkProcessor commentLinkProcessor;
@@ -176,16 +183,14 @@ public class SideBySide2 extends Screen {
} }
})); }));
if (base != null) { if (base != null) {
CommentApi.comments(base, group.add(getCommentCallback(false))); CommentApi.comments(base, group.add(getCommentCallback(DisplaySide.A, false)));
} }
CommentApi.comments(revision, group.add(getCommentCallback(false))); CommentApi.comments(revision, group.add(getCommentCallback(DisplaySide.B, false)));
if (Gerrit.isSignedIn()) { if (Gerrit.isSignedIn()) {
if (base != null) { if (base != null) {
CommentApi.drafts(base, group.add(getCommentCallback(true))); CommentApi.drafts(base, group.add(getCommentCallback(DisplaySide.A, true)));
} }
CommentApi.drafts(revision, group.add(getCommentCallback(true))); CommentApi.drafts(revision, group.add(getCommentCallback(DisplaySide.B, true)));
} else {
drafts = JsArray.createArray().cast();
} }
ConfigInfoCache.get(revision.getParentKey(), group.addFinal( ConfigInfoCache.get(revision.getParentKey(), group.addFinal(
new ScreenLoadCallback<ConfigInfoCache.Entry>(SideBySide2.this) { new ScreenLoadCallback<ConfigInfoCache.Entry>(SideBySide2.this) {
@@ -321,31 +326,30 @@ public class SideBySide2 extends Screen {
} }
private GerritCallback<NativeMap<JsArray<CommentInfo>>> getCommentCallback( private GerritCallback<NativeMap<JsArray<CommentInfo>>> getCommentCallback(
final boolean toDrafts) { final DisplaySide side, final boolean toDrafts) {
return new GerritCallback<NativeMap<JsArray<CommentInfo>>>() { return new GerritCallback<NativeMap<JsArray<CommentInfo>>>() {
@Override @Override
public void onSuccess(NativeMap<JsArray<CommentInfo>> result) { public void onSuccess(NativeMap<JsArray<CommentInfo>> result) {
JsArray<CommentInfo> in = result.get(path); JsArray<CommentInfo> in = result.get(path);
if (in != null) { if (in != null) {
addAllToCommentList(in, toDrafts); if (toDrafts) {
if (side == DisplaySide.A) {
draftsBase = in;
} else {
draftsRevision = in;
}
} else {
if (side == DisplaySide.A) {
publishedBase = in;
} else {
publishedRevision = in;
}
}
} }
} }
}; };
} }
private void addAllToCommentList(JsArray<CommentInfo> in, boolean toDrafts) {
if (toDrafts && drafts == null) {
drafts = in;
} else if (!toDrafts && published == null) {
published = in;
} else {
JsArray<CommentInfo> dest = toDrafts ? drafts : published;
for (int i = 0; i < in.length(); i++) {
dest.push(in.get(i));
}
}
}
private void display(DiffInfo diffInfo) { private void display(DiffInfo diffInfo) {
cmA = displaySide(diffInfo.meta_a(), diffInfo.text_a(), diffTable.cmA); cmA = displaySide(diffInfo.meta_a(), diffInfo.text_a(), diffTable.cmA);
cmB = displaySide(diffInfo.meta_b(), diffInfo.text_b(), diffTable.cmB); cmB = displaySide(diffInfo.meta_b(), diffInfo.text_b(), diffTable.cmB);
@@ -356,17 +360,22 @@ public class SideBySide2 extends Screen {
lineActiveBoxMap = new HashMap<LineHandle, CommentBox>(); lineActiveBoxMap = new HashMap<LineHandle, CommentBox>();
lineLastPublishedBoxMap = new HashMap<LineHandle, PublishedBox>(); lineLastPublishedBoxMap = new HashMap<LineHandle, PublishedBox>();
linePaddingManagerMap = new HashMap<LineHandle, PaddingManager>(); linePaddingManagerMap = new HashMap<LineHandle, PaddingManager>();
if (published != null) { if (publishedBase != null || publishedRevision != null) {
publishedMap = new HashMap<String, PublishedBox>(published.length()); publishedMap = new HashMap<String, PublishedBox>();
renderPublished();
} }
if (drafts != null) { if (publishedBase != null) {
renderDrafts(); renderPublished(publishedBase);
}
if (publishedRevision != null) {
renderPublished(publishedRevision);
}
if (draftsBase != null) {
renderDrafts(draftsBase);
}
if (draftsRevision != null) {
renderDrafts(draftsRevision);
} }
renderSkips(); renderSkips();
published = null;
drafts = null;
skips = null;
registerCmEvents(cmA); registerCmEvents(cmA);
registerCmEvents(cmB); registerCmEvents(cmB);
resizeHandler = Window.addResizeHandler(new ResizeHandler() { resizeHandler = Window.addResizeHandler(new ResizeHandler() {
@@ -470,29 +479,29 @@ public class SideBySide2 extends Screen {
} }
} }
private DraftBox addNewDraft(CodeMirror cm, int line) { private DraftBox addNewDraft(CodeMirror cm, int line, FromTo fromTo) {
DisplaySide side = getSideFromCm(cm);
return addDraftBox(CommentInfo.createRange( return addDraftBox(CommentInfo.createRange(
path, path,
getSideFromCm(cm), getStoredSideFromDisplaySide(side),
line + 1, line + 1,
null, null,
null, null,
null)); CommentRange.create(fromTo)), side);
} }
CommentInfo createReply(CommentInfo replyTo) { CommentInfo createReply(CommentInfo replyTo) {
if (!replyTo.has_line()) { if (!replyTo.has_line() && replyTo.range() == null) {
return CommentInfo.createFile(path, replyTo.side(), replyTo.id(), null); return CommentInfo.createFile(path, replyTo.side(), replyTo.id(), null);
} else { } else {
return CommentInfo.createRange(path, replyTo.side(), replyTo.line(), return CommentInfo.createRange(path, replyTo.side(), replyTo.line(),
replyTo.id(), null, null); replyTo.id(), null, replyTo.range());
} }
} }
DraftBox addDraftBox(CommentInfo info) { DraftBox addDraftBox(CommentInfo info, DisplaySide side) {
Side side = info.side();
CodeMirror cm = getCmFromSide(side); CodeMirror cm = getCmFromSide(side);
final DraftBox box = new DraftBox(this, cm, commentLinkProcessor, final DraftBox box = new DraftBox(this, cm, side, commentLinkProcessor,
getPatchSetIdFromSide(side), info); getPatchSetIdFromSide(side), info);
if (info.id() == null) { if (info.id() == null) {
Scheduler.get().scheduleDeferred(new ScheduledCommand() { Scheduler.get().scheduleDeferred(new ScheduledCommand() {
@@ -514,8 +523,8 @@ public class SideBySide2 extends Screen {
CommentBox addCommentBox(CommentInfo info, CommentBox box) { CommentBox addCommentBox(CommentInfo info, CommentBox box) {
diffTable.add(box); diffTable.add(box);
Side mySide = info.side(); DisplaySide side = box.getSide();
CodeMirror cm = mySide == Side.PARENT ? cmA : cmB; CodeMirror cm = getCmFromSide(side);
CodeMirror other = otherCm(cm); CodeMirror other = otherCm(cm);
int line = info.line() - 1; // CommentInfo is 1-based, but CM is 0-based int line = info.line() - 1; // CommentInfo is 1-based, but CM is 0-based
LineHandle handle = cm.getLineHandle(line); LineHandle handle = cm.getLineHandle(line);
@@ -528,9 +537,9 @@ public class SideBySide2 extends Screen {
addPaddingWidget(cm, DiffTable.style.padding(), line, 0, Unit.PX, 0)); addPaddingWidget(cm, DiffTable.style.padding(), line, 0, Unit.PX, 0));
linePaddingManagerMap.put(handle, manager); linePaddingManagerMap.put(handle, manager);
} }
int lineToPad = mapper.lineOnOther(mySide, line).getLine(); int lineToPad = mapper.lineOnOther(side, line).getLine();
LineHandle otherHandle = other.getLineHandle(lineToPad); LineHandle otherHandle = other.getLineHandle(lineToPad);
DiffChunkInfo myChunk = getDiffChunk(mySide, line); DiffChunkInfo myChunk = getDiffChunk(side, line);
DiffChunkInfo otherChunk = getDiffChunk(getSideFromCm(other), lineToPad); DiffChunkInfo otherChunk = getDiffChunk(getSideFromCm(other), lineToPad);
PaddingManager otherManager; PaddingManager otherManager;
if (linePaddingManagerMap.containsKey(otherHandle)) { if (linePaddingManagerMap.containsKey(otherHandle)) {
@@ -562,20 +571,20 @@ public class SideBySide2 extends Screen {
return box; return box;
} }
void removeDraft(DraftBox box, Side side, int line) { void removeDraft(DraftBox box, int line) {
LineHandle handle = getCmFromSide(side).getLineHandle(line); LineHandle handle = getCmFromSide(box.getSide()).getLineHandle(line);
lineActiveBoxMap.remove(handle); lineActiveBoxMap.remove(handle);
if (lineLastPublishedBoxMap.containsKey(handle)) { if (lineLastPublishedBoxMap.containsKey(handle)) {
lineActiveBoxMap.put(handle, lineLastPublishedBoxMap.get(handle)); lineActiveBoxMap.put(handle, lineLastPublishedBoxMap.get(handle));
} }
} }
void addFileCommentBox(CommentBox box, Side side) { void addFileCommentBox(CommentBox box) {
diffTable.addFileCommentBox(box, side); diffTable.addFileCommentBox(box);
} }
void removeFileCommentBox(DraftBox box, Side side) { void removeFileCommentBox(DraftBox box) {
diffTable.onRemoveDraftBox(box, side); diffTable.onRemoveDraftBox(box);
} }
private List<CommentInfo> sortComment(JsArray<CommentInfo> unsorted) { private List<CommentInfo> sortComment(JsArray<CommentInfo> unsorted) {
@@ -592,16 +601,24 @@ public class SideBySide2 extends Screen {
return sorted; return sorted;
} }
private void renderPublished() { private void renderPublished(JsArray<CommentInfo> published) {
List<CommentInfo> sorted = sortComment(published); List<CommentInfo> sorted = sortComment(published);
for (CommentInfo info : sorted) { for (CommentInfo info : sorted) {
Side side = info.side(); DisplaySide side;
if (info.side() == Side.PARENT) {
if (base != null) {
continue;
}
side = DisplaySide.A;
} else {
side = published == publishedBase ? DisplaySide.A : DisplaySide.B;
}
CodeMirror cm = getCmFromSide(side); CodeMirror cm = getCmFromSide(side);
PublishedBox box = new PublishedBox(this, commentLinkProcessor, PublishedBox box = new PublishedBox(this, cm, side, commentLinkProcessor,
getPatchSetIdFromSide(side), info); getPatchSetIdFromSide(side), info);
publishedMap.put(info.id(), box); publishedMap.put(info.id(), box);
if (!info.has_line()) { if (!info.has_line()) {
diffTable.addFileCommentBox(box, side); diffTable.addFileCommentBox(box);
continue; continue;
} }
int line = info.line() - 1; int line = info.line() - 1;
@@ -612,21 +629,29 @@ public class SideBySide2 extends Screen {
} }
} }
private void renderDrafts() { private void renderDrafts(JsArray<CommentInfo> drafts) {
List<CommentInfo> sorted = sortComment(drafts); List<CommentInfo> sorted = sortComment(drafts);
for (CommentInfo info : sorted) { for (CommentInfo info : sorted) {
Side side = info.side(); DisplaySide side;
if (info.side() == Side.PARENT) {
if (base != null) {
continue;
}
side = DisplaySide.A;
} else {
side = drafts == draftsBase ? DisplaySide.A : DisplaySide.B;
}
DraftBox box = new DraftBox( DraftBox box = new DraftBox(
this, getCmFromSide(side), commentLinkProcessor, this, getCmFromSide(side), side, commentLinkProcessor,
getPatchSetIdFromSide(side), info); getPatchSetIdFromSide(side), info);
if (published != null) { if (publishedBase != null || publishedRevision != null) {
PublishedBox replyToBox = publishedMap.get(info.in_reply_to()); PublishedBox replyToBox = publishedMap.get(info.in_reply_to());
if (replyToBox != null) { if (replyToBox != null) {
replyToBox.registerReplyBox(box); replyToBox.registerReplyBox(box);
} }
} }
if (!info.has_line()) { if (!info.has_line()) {
diffTable.addFileCommentBox(box, side); diffTable.addFileCommentBox(box);
continue; continue;
} }
lineActiveBoxMap.put( lineActiveBoxMap.put(
@@ -723,16 +748,20 @@ public class SideBySide2 extends Screen {
return me == cmA ? cmB : cmA; return me == cmA ? cmB : cmA;
} }
private PatchSet.Id getPatchSetIdFromSide(Side side) { private PatchSet.Id getPatchSetIdFromSide(DisplaySide side) {
return side == Side.PARENT && base != null ? base : revision; return side == DisplaySide.A && base != null ? base : revision;
} }
private CodeMirror getCmFromSide(Side side) { private CodeMirror getCmFromSide(DisplaySide side) {
return side == Side.PARENT ? cmA : cmB; return side == DisplaySide.A ? cmA : cmB;
} }
private Side getSideFromCm(CodeMirror cm) { private DisplaySide getSideFromCm(CodeMirror cm) {
return cm == cmA ? Side.PARENT : Side.REVISION; return cm == cmA ? DisplaySide.A : DisplaySide.B;
}
Side getStoredSideFromDisplaySide(DisplaySide side) {
return side == DisplaySide.A && base == null ? Side.PARENT : Side.REVISION;
} }
private void markEdit(CodeMirror cm, JsArrayString lines, private void markEdit(CodeMirror cm, JsArrayString lines,
@@ -848,7 +877,7 @@ public class SideBySide2 extends Screen {
if (info.isAligned()) { if (info.isAligned()) {
double myHeight = cm.heightAtLine(line); double myHeight = cm.heightAtLine(line);
double otherHeight = other.heightAtLine(info.getLine()); double otherHeight = other.heightAtLine(info.getLine());
if (myHeight != otherHeight) { if (myHeight != otherHeight) {
other.scrollToY(other.getScrollInfo().getTop() + otherHeight - myHeight); other.scrollToY(other.getScrollInfo().getTop() + otherHeight - myHeight);
other.setScrollSetAt(System.currentTimeMillis()); other.setScrollSetAt(System.currentTimeMillis());
} }
@@ -888,7 +917,7 @@ public class SideBySide2 extends Screen {
other.removeLineClass(otherActiveLine, other.removeLineClass(otherActiveLine,
LineClassWhere.BACKGROUND, DiffTable.style.activeLineBg()); LineClassWhere.BACKGROUND, DiffTable.style.activeLineBg());
} }
LineHandle handle = cm.getLineHandleVisualStart(cm.getCursor().getLine()); LineHandle handle = cm.getLineHandleVisualStart(cm.getCursor("end").getLine());
cm.setActiveLine(handle); cm.setActiveLine(handle);
if (cm.somethingSelected()) { if (cm.somethingSelected()) {
return; return;
@@ -914,9 +943,12 @@ public class SideBySide2 extends Screen {
@Override @Override
public void handle(CodeMirror instance, int line, String gutter, public void handle(CodeMirror instance, int line, String gutter,
NativeEvent clickEvent) { NativeEvent clickEvent) {
instance.setCursor(LineCharacter.create(line)); if (!(cm.hasActiveLine() &&
instance.setActiveLine(instance.getLineHandle(line)); instance.getLineNumber(cm.getActiveLine()) == line)) {
insertNewDraft(instance).run(); instance.setCursor(LineCharacter.create(line));
instance.setActiveLine(cm.getLineHandle(line));
}
insertNewDraft(cm).run();
} }
}; };
} }
@@ -935,8 +967,12 @@ public class SideBySide2 extends Screen {
LineHandle handle = cm.getActiveLine(); LineHandle handle = cm.getActiveLine();
int line = cm.getLineNumber(handle); int line = cm.getLineNumber(handle);
CommentBox box = lineActiveBoxMap.get(handle); CommentBox box = lineActiveBoxMap.get(handle);
if (box == null) { FromTo fromTo = cm.getSelectedRange();
lineActiveBoxMap.put(handle, addNewDraft(cm, line)); if (cm.somethingSelected()) {
lineActiveBoxMap.put(handle,
addNewDraft(cm, line, fromTo.getTo().getLine() == line ? fromTo : null));
} else if (box == null) {
lineActiveBoxMap.put(handle, addNewDraft(cm, line, null));
} else if (box instanceof DraftBox) { } else if (box instanceof DraftBox) {
((DraftBox) box).setEdit(true); ((DraftBox) box).setEdit(true);
} else { } else {
@@ -995,7 +1031,7 @@ public class SideBySide2 extends Screen {
}; };
} }
private DiffChunkInfo getDiffChunk(Side side, int line) { private DiffChunkInfo getDiffChunk(DisplaySide side, int line) {
for (DiffChunkInfo info : diffChunks) { for (DiffChunkInfo info : diffChunks) {
if (info.getSide() == side && info.getStart() <= line && if (info.getSide() == side && info.getStart() <= line &&
line <= info.getEnd()) { line <= info.getEnd()) {
@@ -1005,7 +1041,7 @@ public class SideBySide2 extends Screen {
return null; return null;
} }
void resizePaddingOnOtherSide(Side mySide, int line) { void resizePaddingOnOtherSide(DisplaySide mySide, int line) {
CodeMirror cm = getCmFromSide(mySide); CodeMirror cm = getCmFromSide(mySide);
LineHandle handle = cm.getLineHandle(line); LineHandle handle = cm.getLineHandle(line);
final LinePaddingWidgetWrapper otherWrapper = linePaddingOnOtherSideMap.get(handle); final LinePaddingWidgetWrapper otherWrapper = linePaddingOnOtherSideMap.get(handle);
@@ -1051,7 +1087,7 @@ public class SideBySide2 extends Screen {
} }
// TODO: Maybe integrate this with PaddingManager. // TODO: Maybe integrate this with PaddingManager.
private RenderLineHandler resizeLinePadding(final Side side) { private RenderLineHandler resizeLinePadding(final DisplaySide side) {
return new RenderLineHandler() { return new RenderLineHandler() {
@Override @Override
public void handle(final CodeMirror instance, final LineHandle handle, public void handle(final CodeMirror instance, final LineHandle handle,
@@ -1142,17 +1178,17 @@ public class SideBySide2 extends Screen {
} }
static class DiffChunkInfo { static class DiffChunkInfo {
private Side side; private DisplaySide side;
private int start; private int start;
private int end; private int end;
DiffChunkInfo(Side side, int start, int end) { DiffChunkInfo(DisplaySide side, int start, int end) {
this.side = side; this.side = side;
this.start = start; this.start = start;
this.end = end; this.end = end;
} }
Side getSide() { DisplaySide getSide() {
return side; return side;
} }

View File

@@ -19,6 +19,8 @@ import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent; import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.rpc.AsyncCallback;
import net.codemirror.lib.TextMarker.FromTo;
/** /**
* Glue to connect CodeMirror to be callable from GWT. * Glue to connect CodeMirror to be callable from GWT.
* *
@@ -205,6 +207,10 @@ public class CodeMirror extends JavaScriptObject {
return this.getCursor(start); return this.getCursor(start);
}-*/; }-*/;
public final FromTo getSelectedRange() {
return FromTo.create(getCursor("start"), getCursor("end"));
};
public final native void setCursor(LineCharacter lineCh) /*-{ public final native void setCursor(LineCharacter lineCh) /*-{
this.setCursor(lineCh); this.setCursor(lineCh);
}-*/; }-*/;

View File

@@ -14,6 +14,7 @@
package net.codemirror.lib; package net.codemirror.lib;
import com.google.gerrit.client.diff.CommentRange;
import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.JavaScriptObject;
/** Object that represents a text marker within CodeMirror */ /** Object that represents a text marker within CodeMirror */
@@ -30,9 +31,25 @@ public class TextMarker extends JavaScriptObject {
} }
public static class FromTo extends JavaScriptObject { public static class FromTo extends JavaScriptObject {
public static FromTo create(LineCharacter from, LineCharacter to) {
FromTo fromTo = createObject().cast();
fromTo.setFrom(from);
fromTo.setTo(to);
return fromTo;
}
public static FromTo create(CommentRange range) {
return create(
LineCharacter.create(range.start_line() - 1, range.start_character()),
LineCharacter.create(range.end_line() - 1, range.end_character()));
}
public final native LineCharacter getFrom() /*-{ return this.from; }-*/; public final native LineCharacter getFrom() /*-{ return this.from; }-*/;
public final native LineCharacter getTo() /*-{ return this.to; }-*/; public final native LineCharacter getTo() /*-{ return this.to; }-*/;
public final native void setFrom(LineCharacter from) /*-{ this.from = from; }-*/;
public final native void setTo(LineCharacter to) /*-{ this.to = to; }-*/;
protected FromTo() { protected FromTo() {
} }
} }

View File

@@ -17,7 +17,7 @@ package com.google.gerrit.client.diff;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import com.google.gerrit.client.diff.LineMapper.LineOnOtherInfo; import com.google.gerrit.client.diff.LineMapper.LineOnOtherInfo;
import com.google.gerrit.common.changes.Side; import com.google.gerrit.client.diff.SideBySide2.DisplaySide;
import org.junit.Test; import org.junit.Test;
@@ -53,9 +53,9 @@ public class LineMapperTest {
LineMapper mapper = new LineMapper(); LineMapper mapper = new LineMapper();
mapper.appendCommon(10); mapper.appendCommon(10);
assertEquals(new LineOnOtherInfo(9, true), assertEquals(new LineOnOtherInfo(9, true),
mapper.lineOnOther(Side.PARENT, 9)); mapper.lineOnOther(DisplaySide.A, 9));
assertEquals(new LineOnOtherInfo(9, true), assertEquals(new LineOnOtherInfo(9, true),
mapper.lineOnOther(Side.REVISION, 9)); mapper.lineOnOther(DisplaySide.B, 9));
} }
@Test @Test
@@ -63,9 +63,9 @@ public class LineMapperTest {
LineMapper mapper = new LineMapper(); LineMapper mapper = new LineMapper();
mapper.appendCommon(10); mapper.appendCommon(10);
assertEquals(new LineOnOtherInfo(10, true), assertEquals(new LineOnOtherInfo(10, true),
mapper.lineOnOther(Side.PARENT, 10)); mapper.lineOnOther(DisplaySide.A, 10));
assertEquals(new LineOnOtherInfo(10, true), assertEquals(new LineOnOtherInfo(10, true),
mapper.lineOnOther(Side.REVISION, 10)); mapper.lineOnOther(DisplaySide.B, 10));
} }
@Test @Test
@@ -73,7 +73,7 @@ public class LineMapperTest {
LineMapper mapper = new LineMapper(); LineMapper mapper = new LineMapper();
mapper.appendInsert(10); mapper.appendInsert(10);
assertEquals(new LineOnOtherInfo(-1, false), assertEquals(new LineOnOtherInfo(-1, false),
mapper.lineOnOther(Side.REVISION, 9)); mapper.lineOnOther(DisplaySide.B, 9));
} }
@Test @Test
@@ -81,9 +81,9 @@ public class LineMapperTest {
LineMapper mapper = new LineMapper(); LineMapper mapper = new LineMapper();
mapper.appendInsert(10); mapper.appendInsert(10);
assertEquals(new LineOnOtherInfo(0, true), assertEquals(new LineOnOtherInfo(0, true),
mapper.lineOnOther(Side.REVISION, 10)); mapper.lineOnOther(DisplaySide.B, 10));
assertEquals(new LineOnOtherInfo(10, true), assertEquals(new LineOnOtherInfo(10, true),
mapper.lineOnOther(Side.PARENT, 0)); mapper.lineOnOther(DisplaySide.A, 0));
} }
@Test @Test
@@ -91,7 +91,7 @@ public class LineMapperTest {
LineMapper mapper = new LineMapper(); LineMapper mapper = new LineMapper();
mapper.appendDelete(10); mapper.appendDelete(10);
assertEquals(new LineOnOtherInfo(-1, false), assertEquals(new LineOnOtherInfo(-1, false),
mapper.lineOnOther(Side.PARENT, 9)); mapper.lineOnOther(DisplaySide.A, 9));
} }
@Test @Test
@@ -99,8 +99,8 @@ public class LineMapperTest {
LineMapper mapper = new LineMapper(); LineMapper mapper = new LineMapper();
mapper.appendDelete(10); mapper.appendDelete(10);
assertEquals(new LineOnOtherInfo(0, true), assertEquals(new LineOnOtherInfo(0, true),
mapper.lineOnOther(Side.PARENT, 10)); mapper.lineOnOther(DisplaySide.A, 10));
assertEquals(new LineOnOtherInfo(10, true), assertEquals(new LineOnOtherInfo(10, true),
mapper.lineOnOther(Side.REVISION, 0)); mapper.lineOnOther(DisplaySide.B, 0));
} }
} }