Allow user to modify patch display settings

Users can now set the size of tabs, the number of columns displayed,
and also toggle the various flags associated with our pretty printer
like syntax coloring or intraline difference.

Change-Id: Ic86894b76fdc7f7d5e8a494227e2e8a22dd3b1b1
Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
Shawn O. Pearce
2010-02-26 16:37:06 -08:00
parent c23529ddf9
commit 721754c312
11 changed files with 555 additions and 148 deletions

View File

@@ -28,6 +28,7 @@ import com.google.gerrit.reviewdb.Patch.ChangeType;
import org.eclipse.jgit.diff.Edit; import org.eclipse.jgit.diff.Edit;
import java.util.List; import java.util.List;
import static com.google.gerrit.reviewdb.AccountGeneralPreferences.*;
public class PatchScript { public class PatchScript {
public static enum DisplayMethod { public static enum DisplayMethod {
@@ -111,6 +112,10 @@ public class PatchScript {
return settings; return settings;
} }
public void setSettings(PatchScriptSettings s) {
settings = s;
}
public boolean isIgnoreWhitespace() { public boolean isIgnoreWhitespace() {
return settings.getWhitespace() != Whitespace.IGNORE_NONE; return settings.getWhitespace() != Whitespace.IGNORE_NONE;
} }
@@ -158,7 +163,10 @@ public class PatchScript {
} }
public Iterable<EditList.Hunk> getHunks() { public Iterable<EditList.Hunk> getHunks() {
final int ctx = settings.getContext(); int ctx = settings.getContext();
if (ctx == WHOLE_FILE_CONTEXT) {
ctx = Math.max(a.size(), b.size());
}
return new EditList(edits, ctx, a.size(), b.size()).getHunks(); return new EditList(edits, ctx, a.size(), b.size()).getHunks();
} }
} }

View File

@@ -30,8 +30,6 @@ public interface PatchConstants extends Constants {
String patchHeaderOld(); String patchHeaderOld();
String patchHeaderNew(); String patchHeaderNew();
String showFullFiles();
String ignoreWhitespace();
String patchHistoryTitle(); String patchHistoryTitle();
String upToChange(); String upToChange();
@@ -50,7 +48,6 @@ public interface PatchConstants extends Constants {
String commentDiscard(); String commentDiscard();
String commentCancelEdit(); String commentCancelEdit();
String whitespaceIgnoreLabel();
String whitespaceIGNORE_NONE(); String whitespaceIGNORE_NONE();
String whitespaceIGNORE_SPACE_AT_EOL(); String whitespaceIGNORE_SPACE_AT_EOL();
String whitespaceIGNORE_SPACE_CHANGE(); String whitespaceIGNORE_SPACE_CHANGE();

View File

@@ -12,9 +12,6 @@ confirmDiscard = Discard this comment?
noDifference = No Differences noDifference = No Differences
patchHeaderOld = Old Version patchHeaderOld = Old Version
patchHeaderNew = New Version patchHeaderNew = New Version
showFullFiles = Show full files
ignoreWhitespace = Ignore whitespace
patchHistoryTitle = Patch History patchHistoryTitle = Patch History
upToChange = Up to change upToChange = Up to change
@@ -33,7 +30,6 @@ commentSaveDraft = Save draft comment
commentDiscard = Discard draft comment commentDiscard = Discard draft comment
commentCancelEdit = Cancel comment edit commentCancelEdit = Cancel comment edit
whitespaceIgnoreLabel=Ignore Whitespace:
whitespaceIGNORE_NONE=None whitespaceIGNORE_NONE=None
whitespaceIGNORE_SPACE_AT_EOL=At Line End whitespaceIGNORE_SPACE_AT_EOL=At Line End
whitespaceIGNORE_SPACE_CHANGE=Leading, At Line End whitespaceIGNORE_SPACE_CHANGE=Leading, At Line End

View File

@@ -14,7 +14,6 @@
package com.google.gerrit.client.patches; package com.google.gerrit.client.patches;
import static com.google.gerrit.reviewdb.AccountGeneralPreferences.DEFAULT_CONTEXT;
import static com.google.gerrit.reviewdb.AccountGeneralPreferences.WHOLE_FILE_CONTEXT; import static com.google.gerrit.reviewdb.AccountGeneralPreferences.WHOLE_FILE_CONTEXT;
import com.google.gerrit.client.Dispatcher; import com.google.gerrit.client.Dispatcher;
@@ -32,15 +31,11 @@ import com.google.gerrit.common.PageLinks;
import com.google.gerrit.common.data.PatchScript; import com.google.gerrit.common.data.PatchScript;
import com.google.gerrit.common.data.PatchScriptSettings; import com.google.gerrit.common.data.PatchScriptSettings;
import com.google.gerrit.common.data.PatchSetDetail; import com.google.gerrit.common.data.PatchSetDetail;
import com.google.gerrit.common.data.PatchScriptSettings.Whitespace;
import com.google.gerrit.prettify.client.ClientSideFormatter; import com.google.gerrit.prettify.client.ClientSideFormatter;
import com.google.gerrit.prettify.common.PrettyFactory; import com.google.gerrit.prettify.common.PrettyFactory;
import com.google.gerrit.reviewdb.AccountGeneralPreferences;
import com.google.gerrit.reviewdb.Change; import com.google.gerrit.reviewdb.Change;
import com.google.gerrit.reviewdb.Patch; import com.google.gerrit.reviewdb.Patch;
import com.google.gerrit.reviewdb.PatchSet; import com.google.gerrit.reviewdb.PatchSet;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.KeyPressEvent; import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.logical.shared.CloseEvent; import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.CloseHandler; import com.google.gwt.event.logical.shared.CloseHandler;
@@ -52,13 +47,11 @@ import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.Command; import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DeferredCommand; import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.DisclosurePanel; import com.google.gwt.user.client.ui.DisclosurePanel;
import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Grid; import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HasHorizontalAlignment; import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Widget; import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter; import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
import com.google.gwtexpui.globalkey.client.GlobalKey; import com.google.gwtexpui.globalkey.client.GlobalKey;
@@ -91,7 +84,9 @@ public abstract class PatchScreen extends Screen {
public Unified(final Patch.Key id, final int patchIndex, public Unified(final Patch.Key id, final int patchIndex,
final PatchTable patchTable) { final PatchTable patchTable) {
super(id, patchIndex, patchTable); super(id, patchIndex, patchTable);
scriptSettings.getPrettySettings().setSyntaxHighlighting(false); final PatchScriptSettings s = settingsPanel.getValue();
s.getPrettySettings().setSyntaxHighlighting(false);
settingsPanel.setValue(s);
} }
@Override @Override
@@ -131,11 +126,10 @@ public abstract class PatchScreen extends Screen {
protected PatchTable fileList; protected PatchTable fileList;
protected PatchSet.Id idSideA; protected PatchSet.Id idSideA;
protected PatchSet.Id idSideB; protected PatchSet.Id idSideB;
protected final PatchScriptSettings scriptSettings; protected PatchScriptSettingsPanel settingsPanel;
private DisclosurePanel historyPanel; private DisclosurePanel historyPanel;
private HistoryTable historyTable; private HistoryTable historyTable;
private CheckBox reviewedFlag;
private FlowPanel contentPanel; private FlowPanel contentPanel;
private Label noDifference; private Label noDifference;
private AbstractPatchContentTable contentTable; private AbstractPatchContentTable contentTable;
@@ -184,25 +178,63 @@ public abstract class PatchScreen extends Screen {
idSideA = diffSideA; // null here means we're diff'ing from the Base idSideA = diffSideA; // null here means we're diff'ing from the Base
idSideB = diffSideB != null ? diffSideB : id.getParentKey(); idSideB = diffSideB != null ? diffSideB : id.getParentKey();
this.patchIndex = patchIndex; this.patchIndex = patchIndex;
scriptSettings = new PatchScriptSettings();
initContextLines(); settingsPanel = new PatchScriptSettingsPanel();
settingsPanel
.addValueChangeHandler(new ValueChangeHandler<PatchScriptSettings>() {
@Override
public void onValueChange(ValueChangeEvent<PatchScriptSettings> event) {
update(event.getValue());
}
});
settingsPanel.getReviewedCheckBox().addValueChangeHandler(
new ValueChangeHandler<Boolean>() {
@Override
public void onValueChange(ValueChangeEvent<Boolean> event) {
setReviewedByCurrentUser(event.getValue());
}
});
} }
/** private void update(PatchScriptSettings s) {
* Initialize the context lines to the user's preference, or to the default if (lastScript != null && canReuse(s, lastScript)) {
* number if the user is not logged in. lastScript.setSettings(s);
*/ RpcStatus.INSTANCE.onRpcStart(null);
private void initContextLines() { settingsPanel.setEnabled(false);
if (Gerrit.isSignedIn()) { DeferredCommand.addCommand(new Command() {
final AccountGeneralPreferences p = @Override
Gerrit.getUserAccount().getGeneralPreferences(); public void execute() {
scriptSettings.setContext(p.getDefaultContext()); try {
onResult(lastScript, false /* not the first time */);
} finally {
RpcStatus.INSTANCE.onRpcComplete(null);
}
}
});
} else { } else {
scriptSettings.setContext(DEFAULT_CONTEXT); refresh(false);
} }
} }
private boolean canReuse(PatchScriptSettings s, PatchScript last) {
if (last.getSettings().getWhitespace() != s.getWhitespace()) {
// Whitespace ignore setting requires server computation.
return false;
}
final int ctx = s.getContext();
if (ctx == WHOLE_FILE_CONTEXT && !last.getA().isWholeFile()) {
// We don't have the entire file here, so we can't render it.
return false;
}
if (last.getSettings().getContext() < ctx && !last.getA().isWholeFile()) {
// We don't have sufficient context.
return false;
}
return true;
}
@Override @Override
protected void onInitUI() { protected void onInitUI() {
super.onInitUI(); super.onInitUI();
@@ -222,7 +254,7 @@ public abstract class PatchScreen extends Screen {
historyPanel.addOpenHandler(cacheOpenState); historyPanel.addOpenHandler(cacheOpenState);
historyPanel.addCloseHandler(cacheCloseState); historyPanel.addCloseHandler(cacheCloseState);
add(historyPanel); add(historyPanel);
initDisplayControls(); add(settingsPanel);
noDifference = new Label(PatchUtil.C.noDifference()); noDifference = new Label(PatchUtil.C.noDifference());
noDifference.setStyleName(Gerrit.RESOURCES.css().patchNoDifference()); noDifference.setStyleName(Gerrit.RESOURCES.css().patchNoDifference());
@@ -262,81 +294,7 @@ public abstract class PatchScreen extends Screen {
}); });
} }
private void initDisplayControls() { void setReviewedByCurrentUser(boolean reviewed) {
final Grid displayControls = new Grid(0, 5);
displayControls.setStyleName(Gerrit.RESOURCES.css()
.patchScreenDisplayControls());
add(displayControls);
createIgnoreWhitespace(displayControls, 0, 0);
createContext(displayControls, 0, 2);
}
/**
* Add the contextual widgets for this patch: "Show full files" and
* "Keep unreviewed"
*/
private void createContext(final Grid parent, final int row, final int col) {
parent.resizeRows(row + 1);
// Show full files
final CheckBox cb = new CheckBox(PatchUtil.C.showFullFiles());
cb.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
@Override
public void onValueChange(ValueChangeEvent<Boolean> event) {
final PatchScript last = lastScript;
if (event.getValue()) {
scriptSettings.setContext(WHOLE_FILE_CONTEXT);
if (last != null && last.getA().isWholeFile()) {
final int max = Math.max(last.getA().size(), last.getB().size());
last.getSettings().setContext(max);
updateNoRpc(last);
return;
}
} else {
// Restore the context lines to the user's preference
initContextLines();
final int n = scriptSettings.getContext();
if (last != null && n <= last.getSettings().getContext()) {
last.getSettings().setContext(n);
updateNoRpc(last);
return;
}
}
refresh(false /* not the first time */);
}
private void updateNoRpc(final PatchScript last) {
RpcStatus.INSTANCE.onRpcStart(null);
DeferredCommand.addCommand(new Command() {
@Override
public void execute() {
try {
onResult(last, false /* not the first time */);
} finally {
RpcStatus.INSTANCE.onRpcComplete(null);
}
}
});
}
});
parent.setWidget(row, col + 1, cb);
// "Reviewed" check box
if (Gerrit.isSignedIn()) {
reviewedFlag = new CheckBox(PatchUtil.C.reviewed());
reviewedFlag.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
@Override
public void onValueChange(ValueChangeEvent<Boolean> event) {
setReviewedByCurrentUser(event.getValue());
}
});
parent.setWidget(row, col + 2, reviewedFlag);
}
}
private void setReviewedByCurrentUser(boolean reviewed) {
if (fileList != null) { if (fileList != null) {
fileList.updateReviewedStatus(patchKey, reviewed); fileList.updateReviewedStatus(patchKey, reviewed);
} }
@@ -355,32 +313,6 @@ public abstract class PatchScreen extends Screen {
}); });
} }
private void createIgnoreWhitespace(final Grid parent, final int row,
final int col) {
parent.resizeRows(row + 1);
final ListBox ws = new ListBox();
ws.addItem(PatchUtil.C.whitespaceIGNORE_NONE(), Whitespace.IGNORE_NONE
.name());
ws.addItem(PatchUtil.C.whitespaceIGNORE_SPACE_AT_EOL(),
Whitespace.IGNORE_SPACE_AT_EOL.name());
ws.addItem(PatchUtil.C.whitespaceIGNORE_SPACE_CHANGE(),
Whitespace.IGNORE_SPACE_CHANGE.name());
ws.addItem(PatchUtil.C.whitespaceIGNORE_ALL_SPACE(),
Whitespace.IGNORE_ALL_SPACE.name());
ws.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
final int sel = ws.getSelectedIndex();
if (0 <= sel) {
scriptSettings.setWhitespace(Whitespace.valueOf(ws.getValue(sel)));
refresh(false /* not the first time */);
}
}
});
parent.setText(row, col, PatchUtil.C.whitespaceIgnoreLabel());
parent.setWidget(row, col + 1, ws);
}
private Widget createNextPrevLinks() { private Widget createNextPrevLinks() {
final Grid table = new Grid(1, 3); final Grid table = new Grid(1, 3);
final CellFormatter fmt = table.getCellFormatter(); final CellFormatter fmt = table.getCellFormatter();
@@ -436,8 +368,9 @@ public abstract class PatchScreen extends Screen {
protected void refresh(final boolean isFirst) { protected void refresh(final boolean isFirst) {
final int rpcseq = ++rpcSequence; final int rpcseq = ++rpcSequence;
lastScript = null; lastScript = null;
PatchUtil.DETAIL_SVC.patchScript(patchKey, idSideA, idSideB, settingsPanel.setEnabled(false);
scriptSettings, new ScreenLoadCallback<PatchScript>(this) { PatchUtil.DETAIL_SVC.patchScript(patchKey, idSideA, idSideB, //
settingsPanel.getValue(), new ScreenLoadCallback<PatchScript>(this) {
@Override @Override
protected void preDisplay(final PatchScript result) { protected void preDisplay(final PatchScript result) {
if (rpcSequence == rpcseq) { if (rpcSequence == rpcseq) {
@@ -448,6 +381,7 @@ public abstract class PatchScreen extends Screen {
@Override @Override
public void onFailure(final Throwable caught) { public void onFailure(final Throwable caught) {
if (rpcSequence == rpcseq) { if (rpcSequence == rpcseq) {
settingsPanel.setEnabled(true);
super.onFailure(caught); super.onFailure(caught);
} }
} }
@@ -495,11 +429,12 @@ public abstract class PatchScreen extends Screen {
contentTable.finishDisplay(); contentTable.finishDisplay();
} }
showPatch(hasDifferences); showPatch(hasDifferences);
settingsPanel.setEnabled(true);
lastScript = script; lastScript = script;
// Mark this file reviewed as soon we display the diff screen // Mark this file reviewed as soon we display the diff screen
if (Gerrit.isSignedIn() && isFirst) { if (Gerrit.isSignedIn() && isFirst) {
reviewedFlag.setValue(true); settingsPanel.getReviewedCheckBox().setValue(true);
setReviewedByCurrentUser(true /* reviewed */); setReviewedByCurrentUser(true /* reviewed */);
} }
} }

View File

@@ -0,0 +1,218 @@
// Copyright (C) 2010 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.patches;
import static com.google.gerrit.reviewdb.AccountGeneralPreferences.DEFAULT_CONTEXT;
import static com.google.gerrit.reviewdb.AccountGeneralPreferences.WHOLE_FILE_CONTEXT;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.ui.NpIntTextBox;
import com.google.gerrit.common.data.PatchScriptSettings;
import com.google.gerrit.common.data.PatchScriptSettings.Whitespace;
import com.google.gerrit.prettify.common.PrettySettings;
import com.google.gerrit.reviewdb.Account;
import com.google.gerrit.reviewdb.AccountGeneralPreferences;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.event.logical.shared.HasValueChangeHandlers;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
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.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Widget;
public class PatchScriptSettingsPanel extends Composite implements
HasValueChangeHandlers<PatchScriptSettings> {
private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);
interface MyUiBinder extends UiBinder<Widget, PatchScriptSettingsPanel> {
}
private PatchScriptSettings value;
@UiField
ListBox ignoreWhitespace;
@UiField
NpIntTextBox tabWidth;
@UiField
NpIntTextBox colWidth;
@UiField
CheckBox syntaxHighlighting;
@UiField
CheckBox intralineDifference;
@UiField
CheckBox showFullFile;
@UiField
CheckBox whitespaceErrors;
@UiField
CheckBox showTabs;
@UiField
CheckBox reviewed;
@UiField
Button update;
public PatchScriptSettingsPanel() {
initWidget(uiBinder.createAndBindUi(this));
initIgnoreWhitespace(ignoreWhitespace);
if (!Gerrit.isSignedIn()) {
reviewed.setVisible(false);
}
KeyPressHandler onEnter = new KeyPressHandler() {
@Override
public void onKeyPress(KeyPressEvent event) {
if (event.getCharCode() == KeyCodes.KEY_ENTER) {
update();
}
}
};
tabWidth.addKeyPressHandler(onEnter);
colWidth.addKeyPressHandler(onEnter);
final PatchScriptSettings s = new PatchScriptSettings();
if (Gerrit.isSignedIn()) {
final Account u = Gerrit.getUserAccount();
final AccountGeneralPreferences pref = u.getGeneralPreferences();
s.setContext(pref.getDefaultContext());
} else {
s.setContext(DEFAULT_CONTEXT);
}
setValue(s);
}
@Override
public HandlerRegistration addValueChangeHandler(
ValueChangeHandler<PatchScriptSettings> handler) {
return super.addHandler(handler, ValueChangeEvent.getType());
}
public void setEnabled(final boolean on) {
for (Widget w : (HasWidgets) getWidget()) {
if (w instanceof FocusWidget) {
((FocusWidget) w).setEnabled(on);
}
}
}
public CheckBox getReviewedCheckBox() {
return reviewed;
}
public PatchScriptSettings getValue() {
return value;
}
public void setValue(final PatchScriptSettings s) {
final PrettySettings p = s.getPrettySettings();
setIgnoreWhitespace(s.getWhitespace());
showFullFile.setValue(s.getContext() == WHOLE_FILE_CONTEXT);
tabWidth.setIntValue(p.getTabSize());
colWidth.setIntValue(p.getLineLength());
syntaxHighlighting.setValue(p.isSyntaxHighlighting());
intralineDifference.setValue(p.isIntralineDifference());
whitespaceErrors.setValue(p.isShowWhiteSpaceErrors());
showTabs.setValue(p.isShowTabs());
value = s;
}
@UiHandler("update")
void onUpdate(ClickEvent event) {
update();
}
private void update() {
PatchScriptSettings s = new PatchScriptSettings(getValue());
PrettySettings p = s.getPrettySettings();
s.setWhitespace(getIgnoreWhitespace());
if (showFullFile.getValue()) {
s.setContext(WHOLE_FILE_CONTEXT);
} else if (Gerrit.isSignedIn()) {
final Account u = Gerrit.getUserAccount();
final AccountGeneralPreferences pref = u.getGeneralPreferences();
if (pref.getDefaultContext() == WHOLE_FILE_CONTEXT) {
s.setContext(DEFAULT_CONTEXT);
} else {
s.setContext(pref.getDefaultContext());
}
} else {
s.setContext(DEFAULT_CONTEXT);
}
p.setTabSize(tabWidth.getIntValue());
p.setLineLength(colWidth.getIntValue());
p.setSyntaxHighlighting(syntaxHighlighting.getValue());
p.setIntralineDifference(intralineDifference.getValue());
p.setShowWhiteSpaceErrors(whitespaceErrors.getValue());
p.setShowTabs(p.isShowTabs());
value = s;
fireEvent(new ValueChangeEvent<PatchScriptSettings>(s) {});
}
private void initIgnoreWhitespace(ListBox ws) {
ws.addItem(PatchUtil.C.whitespaceIGNORE_NONE(), //
Whitespace.IGNORE_NONE.name());
ws.addItem(PatchUtil.C.whitespaceIGNORE_SPACE_AT_EOL(), //
Whitespace.IGNORE_SPACE_AT_EOL.name());
ws.addItem(PatchUtil.C.whitespaceIGNORE_SPACE_CHANGE(), //
Whitespace.IGNORE_SPACE_CHANGE.name());
ws.addItem(PatchUtil.C.whitespaceIGNORE_ALL_SPACE(), //
Whitespace.IGNORE_ALL_SPACE.name());
}
private Whitespace getIgnoreWhitespace() {
final int sel = ignoreWhitespace.getSelectedIndex();
if (0 <= sel) {
return Whitespace.valueOf(ignoreWhitespace.getValue(sel));
}
return value.getWhitespace();
}
private void setIgnoreWhitespace(Whitespace s) {
for (int i = 0; i < ignoreWhitespace.getItemCount(); i++) {
if (ignoreWhitespace.getValue(i).equals(s.name())) {
ignoreWhitespace.setSelectedIndex(i);
return;
}
}
ignoreWhitespace.setSelectedIndex(0);
}
}

View File

@@ -0,0 +1,158 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2010 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:my='urn:import:com.google.gerrit.client.ui'
ui:generateFormat='com.google.gwt.i18n.rebind.format.PropertiesFormat'
ui:generateKeys='com.google.gwt.i18n.rebind.keygen.MD5KeyGenerator'
ui:generateLocales='default,en'
>
<ui:style>
@external .gwt-TextBox;
@external .gwt-ListBox;
@def fontSize 8pt;
.controls {
border: none;
border-collapse: separate;
border-spacing: 0;
}
.controls td {
font-size: fontSize;
padding: 0;
white-space: nowrap;
}
.gwt-TextBox {
font-size: fontSize;
padding: 0;
text-align: right;
}
.gwt-ListBox {
font-size: fontSize;
padding: 0;
}
.updateButton {
margin-left: 1em;
margin-right: 1em;
font-size: fontSize;
}
</ui:style>
<g:HTMLPanel>
<table class='{style.controls}'>
<tr valign='top'>
<td colspan='2'>
<ui:msg>
Ignore Whitespace:
<g:ListBox
ui:field='ignoreWhitespace'
visibleItemCount='1'
tabIndex='1'/>
</ui:msg>
</td>
<td rowspan='2'>
<g:CheckBox
ui:field='syntaxHighlighting'
text='Syntax Coloring'
tabIndex='4'>
<ui:attribute name='text'/>
</g:CheckBox>
<br/>
<g:CheckBox
ui:field='intralineDifference'
text='Intraline Difference'
tabIndex='5'>
<ui:attribute name='text'/>
</g:CheckBox>
<br/>
<g:CheckBox
ui:field='showFullFile'
text='Show Full File'
tabIndex='6'>
<ui:attribute name='text'/>
</g:CheckBox>
</td>
<td rowspan='2'>
<g:CheckBox
ui:field='whitespaceErrors'
text='Whitespace Errors'
tabIndex='7'>
<ui:attribute name='text'/>
</g:CheckBox>
<br/>
<g:CheckBox
ui:field='showTabs'
text='Show Tabs'
tabIndex='8'>
<ui:attribute name='text'/>
</g:CheckBox>
</td>
<td valign='bottom' rowspan='2'>
<g:Button
ui:field='update'
text='Update'
styleName='{style.updateButton}'
tabIndex='9'>
<ui:attribute name='text'/>
</g:Button>
</td>
<td>
<g:CheckBox
ui:field='reviewed'
text='Reviewed'
tabIndex='10'>
<ui:attribute name='text'/>
</g:CheckBox>
</td>
</tr>
<tr valign='top'>
<td>
<ui:msg>Tab Width:
<my:NpIntTextBox
ui:field='tabWidth'
width='2em'
visibleLength='2'
maxLength='2'
tabIndex='2'/>
</ui:msg>
</td>
<td>
<ui:msg>Columns:
<my:NpIntTextBox
ui:field='colWidth'
width='2.5em'
visibleLength='3'
maxLength='3'
tabIndex='3'/>
</ui:msg>
</td>
</tr>
</table>
</g:HTMLPanel>
</ui:UiBinder>

View File

@@ -0,0 +1,77 @@
// Copyright (C) 2010 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.ui;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwtexpui.globalkey.client.NpTextBox;
/** Text box that accepts only integer values. */
public class NpIntTextBox extends NpTextBox {
private int intValue;
public NpIntTextBox() {
init();
}
public NpIntTextBox(Element element) {
super(element);
init();
}
private void init() {
addKeyPressHandler(new KeyPressHandler() {
@Override
public void onKeyPress(KeyPressEvent event) {
char c = event.getCharCode();
if (c < '0' || '9' < c) {
switch (c) {
case KeyCodes.KEY_BACKSPACE:
case KeyCodes.KEY_LEFT:
case KeyCodes.KEY_RIGHT:
case KeyCodes.KEY_HOME:
case KeyCodes.KEY_END:
case KeyCodes.KEY_TAB:
break;
default:
if (!event.isAnyModifierKeyDown()) {
event.preventDefault();
}
break;
}
}
}
});
}
public int getIntValue() {
String txt = getText().trim();
if (!txt.isEmpty()) {
try {
intValue = Integer.parseInt(getText());
} catch (NumberFormatException e) {
}
}
return intValue;
}
public void setIntValue(int v) {
intValue = v;
setText(Integer.toString(v));
}
}

View File

@@ -21,6 +21,7 @@ import com.google.gerrit.common.data.PatchScript.DisplayMethod;
import com.google.gerrit.common.data.PatchScriptSettings.Whitespace; import com.google.gerrit.common.data.PatchScriptSettings.Whitespace;
import com.google.gerrit.prettify.common.EditList; import com.google.gerrit.prettify.common.EditList;
import com.google.gerrit.prettify.common.SparseFileContent; import com.google.gerrit.prettify.common.SparseFileContent;
import com.google.gerrit.reviewdb.AccountGeneralPreferences;
import com.google.gerrit.reviewdb.Change; import com.google.gerrit.reviewdb.Change;
import com.google.gerrit.reviewdb.Patch; import com.google.gerrit.reviewdb.Patch;
import com.google.gerrit.reviewdb.PatchLineComment; import com.google.gerrit.reviewdb.PatchLineComment;
@@ -93,7 +94,13 @@ class PatchScriptBuilder {
void setSettings(final PatchScriptSettings s) { void setSettings(final PatchScriptSettings s) {
settings = s; settings = s;
context = settings.getContext(); context = settings.getContext();
if (context == AccountGeneralPreferences.WHOLE_FILE_CONTEXT) {
context = MAX_CONTEXT;
} else if (context > MAX_CONTEXT) {
context = MAX_CONTEXT;
}
} }
void setTrees(final ObjectId a, final ObjectId b) { void setTrees(final ObjectId a, final ObjectId b) {

View File

@@ -20,7 +20,6 @@ import com.google.gerrit.common.data.PatchScriptSettings;
import com.google.gerrit.common.data.PatchScriptSettings.Whitespace; import com.google.gerrit.common.data.PatchScriptSettings.Whitespace;
import com.google.gerrit.httpd.rpc.Handler; import com.google.gerrit.httpd.rpc.Handler;
import com.google.gerrit.reviewdb.Account; import com.google.gerrit.reviewdb.Account;
import com.google.gerrit.reviewdb.AccountGeneralPreferences;
import com.google.gerrit.reviewdb.Change; import com.google.gerrit.reviewdb.Change;
import com.google.gerrit.reviewdb.Patch; import com.google.gerrit.reviewdb.Patch;
import com.google.gerrit.reviewdb.PatchLineComment; import com.google.gerrit.reviewdb.PatchLineComment;
@@ -171,18 +170,8 @@ class PatchScriptFactory extends Handler<PatchScript> {
return patchListCache.get(key); return patchListCache.get(key);
} }
private PatchScriptBuilder newBuilder(final PatchList list, Repository git) private PatchScriptBuilder newBuilder(final PatchList list, Repository git) {
throws NoSuchChangeException {
final PatchScriptSettings s = new PatchScriptSettings(settings); final PatchScriptSettings s = new PatchScriptSettings(settings);
final int ctx = settings.getContext();
if (ctx == AccountGeneralPreferences.WHOLE_FILE_CONTEXT)
s.setContext(PatchScriptBuilder.MAX_CONTEXT);
else if (0 <= ctx && ctx <= PatchScriptBuilder.MAX_CONTEXT)
s.setContext(ctx);
else
throw new NoSuchChangeException(changeId);
final PatchScriptBuilder b = builderFactory.get(); final PatchScriptBuilder b = builderFactory.get();
b.setRepository(git); b.setRepository(git);
b.setChange(change); b.setChange(change);

View File

@@ -303,7 +303,18 @@ public abstract class PrettyFormatter implements SparseHtmlFile {
} }
private String toHTML(SparseFileContent src) { private String toHTML(SparseFileContent src) {
SafeHtml html = colorLineEdits(src); SafeHtml html;
if (settings.isIntralineDifference()) {
html = colorLineEdits(src);
} else {
SafeHtmlBuilder b = new SafeHtmlBuilder();
for (int index = src.first(); index < src.size(); index = src.next(index)) {
b.append(src.get(index));
b.append('\n');
}
html = b;
}
if (settings.isShowWhiteSpaceErrors()) { if (settings.isShowWhiteSpaceErrors()) {
// We need to do whitespace errors before showing tabs, because // We need to do whitespace errors before showing tabs, because

View File

@@ -22,6 +22,7 @@ public class PrettySettings {
protected int tabSize; protected int tabSize;
protected boolean showTabs; protected boolean showTabs;
protected boolean syntaxHighlighting; protected boolean syntaxHighlighting;
protected boolean intralineDifference;
public PrettySettings() { public PrettySettings() {
showWhiteSpaceErrors = true; showWhiteSpaceErrors = true;
@@ -29,6 +30,7 @@ public class PrettySettings {
tabSize = 2; tabSize = 2;
showTabs = true; showTabs = true;
syntaxHighlighting = true; syntaxHighlighting = true;
intralineDifference = true;
} }
public PrettySettings(PrettySettings pretty) { public PrettySettings(PrettySettings pretty) {
@@ -38,6 +40,7 @@ public class PrettySettings {
tabSize = pretty.tabSize; tabSize = pretty.tabSize;
showTabs = pretty.showTabs; showTabs = pretty.showTabs;
syntaxHighlighting = pretty.syntaxHighlighting; syntaxHighlighting = pretty.syntaxHighlighting;
intralineDifference = pretty.intralineDifference;
} }
public String getFilename() { public String getFilename() {
@@ -92,4 +95,12 @@ public class PrettySettings {
public void setSyntaxHighlighting(final boolean on) { public void setSyntaxHighlighting(final boolean on) {
syntaxHighlighting = on; syntaxHighlighting = on;
} }
public boolean isIntralineDifference() {
return intralineDifference;
}
public void setIntralineDifference(final boolean on) {
intralineDifference = on;
}
} }