blob: 822bc74350a60d992e046460f0882de1ce78a033 [file] [log] [blame]
// 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.diff;
import com.google.gerrit.client.DiffObject;
import com.google.gerrit.client.Dispatcher;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.blame.BlameInfo;
import com.google.gerrit.client.changes.ChangeApi;
import com.google.gerrit.client.changes.Util;
import com.google.gerrit.client.info.ChangeInfo.RevisionInfo;
import com.google.gerrit.client.info.WebLinkInfo;
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;
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.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;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.ImageResourceRenderer;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwtorm.client.KeyUtil;
import java.util.List;
import net.codemirror.lib.CodeMirror;
/** HTMLPanel to select among patch sets */
class PatchSetSelectBox extends Composite {
interface Binder extends UiBinder<HTMLPanel, PatchSetSelectBox> {}
private static final Binder uiBinder = GWT.create(Binder.class);
interface BoxStyle extends CssResource {
String selected();
}
@UiField Image icon;
@UiField HTMLPanel linkPanel;
@UiField BoxStyle style;
private DiffScreen parent;
private DisplaySide side;
private boolean sideA;
private String path;
private Change.Id changeId;
private PatchSet.Id revision;
private DiffObject idActive;
private PatchSetSelectBox other;
PatchSetSelectBox(
DiffScreen parent, DisplaySide side, Change.Id changeId, DiffObject diffObject, String path) {
initWidget(uiBinder.createAndBindUi(this));
icon.setTitle(PatchUtil.C.addFileCommentToolTip());
icon.addStyleName(Gerrit.RESOURCES.css().link());
this.parent = parent;
this.side = side;
this.sideA = side == DisplaySide.A;
this.changeId = changeId;
this.revision = diffObject.asPatchSetId();
this.idActive = diffObject;
this.path = path;
}
void setUpPatchSetNav(
JsArray<RevisionInfo> list,
int parents,
DiffInfo.FileMeta meta,
boolean editExists,
boolean current,
boolean open,
boolean binary) {
InlineHyperlink selectedLink = null;
if (sideA) {
if (parents <= 1) {
InlineHyperlink link = createLink(PatchUtil.C.patchBase(), DiffObject.base());
linkPanel.add(link);
selectedLink = link;
} else {
for (int i = parents; i > 0; i--) {
PatchSet.Id id = new PatchSet.Id(changeId, -i);
InlineHyperlink link = createLink(Util.M.diffBaseParent(i), DiffObject.patchSet(id));
linkPanel.add(link);
if (revision != null && id.equals(revision)) {
selectedLink = link;
}
}
InlineHyperlink link = createLink(Util.C.autoMerge(), DiffObject.autoMerge());
linkPanel.add(link);
if (selectedLink == null) {
selectedLink = link;
}
}
}
for (int i = 0; i < list.length(); i++) {
RevisionInfo r = list.get(i);
InlineHyperlink link =
createLink(r.id(), DiffObject.patchSet(new PatchSet.Id(changeId, r._number())));
linkPanel.add(link);
if (revision != null && r.id().equals(revision.getId())) {
selectedLink = link;
}
}
if (selectedLink != null) {
selectedLink.setStyleName(style.selected());
}
if (meta == null) {
return;
}
if (!Patch.isMagic(path)) {
linkPanel.add(createDownloadLink());
}
if (!binary && open && !idActive.isBaseOrAutoMerge() && Gerrit.isSignedIn()) {
if ((editExists && idActive.isEdit()) || (!editExists && current)) {
linkPanel.add(createEditIcon());
}
}
List<WebLinkInfo> webLinks = Natives.asList(meta.webLinks());
if (webLinks != null) {
for (WebLinkInfo webLink : webLinks) {
linkPanel.add(webLink.toAnchor());
}
}
}
void setUpBlame(
final CodeMirror cm, final boolean isBase, final PatchSet.Id rev, final String path) {
if (!Patch.isMagic(path) && Gerrit.isSignedIn() && Gerrit.info().change().allowBlame()) {
Anchor blameIcon = createBlameIcon();
blameIcon.addClickHandler(
new ClickHandler() {
@Override
public void onClick(ClickEvent clickEvent) {
if (cm.extras().getBlameInfo() != null) {
cm.extras().toggleAnnotation();
} else {
ChangeApi.blame(rev, path, isBase)
.get(
new GerritCallback<JsArray<BlameInfo>>() {
@Override
public void onSuccess(JsArray<BlameInfo> lines) {
cm.extras().toggleAnnotation(lines);
}
});
}
}
});
linkPanel.add(blameIcon);
}
}
private Widget createEditIcon() {
PatchSet.Id id =
idActive.isBaseOrAutoMerge() ? other.idActive.asPatchSetId() : idActive.asPatchSetId();
Anchor anchor =
new Anchor(
new ImageResourceRenderer().render(Gerrit.RESOURCES.edit()),
"#" + Dispatcher.toEditScreen(id, path));
anchor.setTitle(PatchUtil.C.edit());
return anchor;
}
private Anchor createBlameIcon() {
Anchor anchor = new Anchor(new ImageResourceRenderer().render(Gerrit.RESOURCES.blame()));
anchor.setTitle(PatchUtil.C.blame());
return anchor;
}
static void link(PatchSetSelectBox a, PatchSetSelectBox b) {
a.other = b;
b.other = a;
}
private InlineHyperlink createLink(String label, DiffObject id) {
assert other != null;
if (sideA) {
assert !other.idActive.isBaseOrAutoMerge();
}
DiffObject diffBase = sideA ? id : other.idActive;
DiffObject revision = sideA ? other.idActive : id;
return new InlineHyperlink(
label,
parent.isSideBySide()
? Dispatcher.toSideBySide(diffBase, revision.asPatchSetId(), path)
: Dispatcher.toUnified(diffBase, revision.asPatchSetId(), path));
}
private Anchor createDownloadLink() {
DiffObject diffObject = idActive.isBaseOrAutoMerge() ? other.idActive : idActive;
String sideURL = idActive.isBaseOrAutoMerge() ? "1" : "0";
String base = GWT.getHostPageBaseURL() + "cat/";
Anchor anchor =
new Anchor(
new ImageResourceRenderer().render(Gerrit.RESOURCES.downloadIcon()),
base + KeyUtil.encode(diffObject.asPatchSetId() + "," + path) + "^" + sideURL);
anchor.setTitle(PatchUtil.C.download());
return anchor;
}
@UiHandler("icon")
void onIconClick(@SuppressWarnings("unused") ClickEvent e) {
parent.getCmFromSide(side).scrollToY(0);
parent.getCommentManager().insertNewDraft(side, 0);
}
}