Persisting users diff formatting preferences

When a user changes diff formatting preferences and clicks the
Update button the preferences will then be persisted in the database.
This way a user doesn't have to adjust the diff formatting
preferences each time it switches to the next file diff.

Bug: issue 579
Change-Id: I52cd1dcf702ed04046b236228f994fb9042243d9
Signed-off-by: Sasa Zivkov <sasa.zivkov@sap.com>
This commit is contained in:
Sasa Zivkov 2010-06-14 15:00:05 +02:00 committed by Shawn O. Pearce
parent 5a00b3161d
commit 077b2c5dd0
25 changed files with 512 additions and 154 deletions

View File

@ -16,6 +16,7 @@ package com.google.gerrit.common.data;
import com.google.gerrit.common.auth.SignInRequired;
import com.google.gerrit.reviewdb.Account;
import com.google.gerrit.reviewdb.AccountDiffPreference;
import com.google.gerrit.reviewdb.AccountGeneralPreferences;
import com.google.gerrit.reviewdb.AccountProjectWatch;
import com.google.gwt.user.client.rpc.AsyncCallback;
@ -32,10 +33,17 @@ public interface AccountService extends RemoteJsonService {
@SignInRequired
void myAccount(AsyncCallback<Account> callback);
@SignInRequired
void myDiffPreferences(AsyncCallback<AccountDiffPreference> callback);
@SignInRequired
void changePreferences(AccountGeneralPreferences pref,
AsyncCallback<VoidResult> gerritCallback);
@SignInRequired
void changeDiffPreferences(AccountDiffPreference diffPref,
AsyncCallback<VoidResult> callback);
@SignInRequired
void myProjectWatch(AsyncCallback<List<AccountProjectWatchInfo>> callback);

View File

@ -15,9 +15,11 @@
package com.google.gerrit.common.data;
import com.google.gerrit.reviewdb.Account;
import com.google.gerrit.reviewdb.AccountDiffPreference;
/** Data sent as part of the host page, to bootstrap the UI. */
public class HostPageData {
public Account account;
public AccountDiffPreference accountDiffPref;
public GerritConfig config;
}

View File

@ -14,17 +14,16 @@
package com.google.gerrit.common.data;
import static com.google.gerrit.reviewdb.AccountGeneralPreferences.WHOLE_FILE_CONTEXT;
import com.google.gerrit.common.data.PatchScriptSettings.Whitespace;
import com.google.gerrit.prettify.client.ClientSideFormatter;
import com.google.gerrit.prettify.common.EditList;
import com.google.gerrit.prettify.common.PrettyFormatter;
import com.google.gerrit.prettify.common.PrettySettings;
import com.google.gerrit.prettify.common.SparseFileContent;
import com.google.gerrit.prettify.common.SparseHtmlFile;
import com.google.gerrit.reviewdb.AccountDiffPreference;
import com.google.gerrit.reviewdb.Change;
import com.google.gerrit.reviewdb.Patch;
import com.google.gerrit.reviewdb.AccountDiffPreference.Whitespace;
import com.google.gerrit.reviewdb.Patch.ChangeType;
import org.eclipse.jgit.diff.Edit;
@ -178,7 +177,7 @@ public class PatchScript {
public Iterable<EditList.Hunk> getHunks() {
int ctx = settings.getContext();
if (ctx == WHOLE_FILE_CONTEXT) {
if (ctx == AccountDiffPreference.WHOLE_FILE_CONTEXT) {
ctx = Math.max(a.size(), b.size());
}
return new EditList(edits, ctx, a.size(), b.size()).getHunks();

View File

@ -15,33 +15,16 @@
package com.google.gerrit.common.data;
import com.google.gerrit.prettify.common.PrettySettings;
import com.google.gerrit.reviewdb.AccountGeneralPreferences;
import com.google.gerrit.reviewdb.CodedEnum;
import com.google.gerrit.reviewdb.AccountDiffPreference;
import com.google.gerrit.reviewdb.AccountDiffPreference.Whitespace;
public class PatchScriptSettings {
public static enum Whitespace implements CodedEnum {
IGNORE_NONE('N'), //
IGNORE_SPACE_AT_EOL('E'), //
IGNORE_SPACE_CHANGE('S'), //
IGNORE_ALL_SPACE('A');
private final char code;
private Whitespace(final char c) {
code = c;
}
public char getCode() {
return code;
}
}
protected int context;
protected Whitespace whitespace;
protected PrettySettings pretty;
public PatchScriptSettings() {
context = AccountGeneralPreferences.DEFAULT_CONTEXT;
context = AccountDiffPreference.DEFAULT_CONTEXT;
whitespace = Whitespace.IGNORE_NONE;
pretty = new PrettySettings();
}
@ -65,7 +48,7 @@ public class PatchScriptSettings {
}
public void setContext(final int ctx) {
assert 0 <= ctx || ctx == AccountGeneralPreferences.WHOLE_FILE_CONTEXT;
assert 0 <= ctx || ctx == AccountDiffPreference.WHOLE_FILE_CONTEXT;
context = ctx;
}

View File

@ -27,6 +27,7 @@ import com.google.gerrit.common.data.GerritConfig;
import com.google.gerrit.common.data.HostPageData;
import com.google.gerrit.common.data.SystemInfoService;
import com.google.gerrit.reviewdb.Account;
import com.google.gerrit.reviewdb.AccountDiffPreference;
import com.google.gerrit.reviewdb.AccountGeneralPreferences;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
@ -70,6 +71,7 @@ public class Gerrit implements EntryPoint {
private static String myHost;
private static GerritConfig myConfig;
private static Account myAccount;
private static AccountDiffPreference myAccountDiffPref;
private static TabPanel menuLeft;
private static LinkMenuBar menuRight;
@ -172,6 +174,15 @@ public class Gerrit implements EntryPoint {
return myAccount;
}
/** @return the currently signed in users's diff preferences; null if no diff preferences defined for the account */
public static AccountDiffPreference getAccountDiffPreference() {
return myAccountDiffPref;
}
public static void setAccountDiffPreference(AccountDiffPreference accountDiffPref) {
myAccountDiffPref = accountDiffPref;
}
/** @return true if the user is currently authenticated */
public static boolean isSignedIn() {
return getUserAccount() != null;
@ -203,6 +214,7 @@ public class Gerrit implements EntryPoint {
static void deleteSessionCookie() {
Cookies.removeCookie(SESSION_COOKIE);
myAccount = null;
myAccountDiffPref = null;
refreshMenuBar();
}
@ -234,6 +246,9 @@ public class Gerrit implements EntryPoint {
if (result.account != null) {
myAccount = result.account;
}
if (result.accountDiffPref != null) {
myAccountDiffPref = result.accountDiffPref;
}
onModuleLoad2();
}
});

View File

@ -24,7 +24,6 @@ public interface AccountConstants extends Constants {
String registeredOn();
String accountId();
String defaultContextFieldLabel();
String maximumPageSizeFieldLabel();
String contextWholeFile();
String showSiteHeader();

View File

@ -14,11 +14,8 @@
package com.google.gerrit.client.account;
import static com.google.gerrit.reviewdb.AccountGeneralPreferences.CONTEXT_CHOICES;
import static com.google.gerrit.reviewdb.AccountGeneralPreferences.DEFAULT_CONTEXT;
import static com.google.gerrit.reviewdb.AccountGeneralPreferences.DEFAULT_PAGESIZE;
import static com.google.gerrit.reviewdb.AccountGeneralPreferences.PAGESIZE_CHOICES;
import static com.google.gerrit.reviewdb.AccountGeneralPreferences.WHOLE_FILE_CONTEXT;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.rpc.GerritCallback;
@ -41,7 +38,6 @@ class PreferencePanel extends Composite {
private CheckBox showSiteHeader;
private CheckBox useFlashClipboard;
private CheckBox copySelfOnEmails;
private ListBox defaultContext;
private ListBox maximumPageSize;
private Button save;
@ -76,18 +72,6 @@ class PreferencePanel extends Composite {
}
maximumPageSize.addChangeHandler(onChangeSave);
defaultContext = new ListBox();
for (final short v : CONTEXT_CHOICES) {
final String label;
if (v == WHOLE_FILE_CONTEXT) {
label = Util.C.contextWholeFile();
} else {
label = Util.M.lines(v);
}
defaultContext.addItem(label, String.valueOf(v));
}
defaultContext.addChangeHandler(onChangeSave);
final int labelIdx, fieldIdx;
if (LocaleInfo.getCurrentLocale().isRTL()) {
labelIdx = 1;
@ -96,7 +80,7 @@ class PreferencePanel extends Composite {
labelIdx = 0;
fieldIdx = 1;
}
final Grid formGrid = new Grid(5, 2);
final Grid formGrid = new Grid(4, 2);
int row = 0;
formGrid.setText(row, labelIdx, "");
@ -115,10 +99,6 @@ class PreferencePanel extends Composite {
formGrid.setWidget(row, fieldIdx, maximumPageSize);
row++;
formGrid.setText(row, labelIdx, Util.C.defaultContextFieldLabel());
formGrid.setWidget(row, fieldIdx, defaultContext);
row++;
body.add(formGrid);
save = new Button(Util.C.buttonSaveChanges());
@ -150,7 +130,6 @@ class PreferencePanel extends Composite {
useFlashClipboard.setEnabled(on);
copySelfOnEmails.setEnabled(on);
maximumPageSize.setEnabled(on);
defaultContext.setEnabled(on);
}
private void display(final AccountGeneralPreferences p) {
@ -158,7 +137,6 @@ class PreferencePanel extends Composite {
useFlashClipboard.setValue(p.isUseFlashClipboard());
copySelfOnEmails.setValue(p.isCopySelfOnEmails());
setListBox(maximumPageSize, DEFAULT_PAGESIZE, p.getMaximumPageSize());
setListBox(defaultContext, DEFAULT_CONTEXT, p.getDefaultContext());
}
private void setListBox(final ListBox f, final short defaultValue,
@ -189,7 +167,6 @@ class PreferencePanel extends Composite {
p.setUseFlashClipboard(useFlashClipboard.getValue());
p.setCopySelfOnEmails(copySelfOnEmails.getValue());
p.setMaximumPageSize(getListBox(maximumPageSize, DEFAULT_PAGESIZE));
p.setDefaultContext(getListBox(defaultContext, DEFAULT_CONTEXT));
enable(false);
save.setEnabled(false);

View File

@ -14,8 +14,6 @@
package com.google.gerrit.client.patches;
import static com.google.gerrit.reviewdb.AccountGeneralPreferences.WHOLE_FILE_CONTEXT;
import com.google.gerrit.client.Dispatcher;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.RpcStatus;
@ -33,6 +31,7 @@ import com.google.gerrit.common.data.PatchScriptSettings;
import com.google.gerrit.common.data.PatchSetDetail;
import com.google.gerrit.prettify.client.ClientSideFormatter;
import com.google.gerrit.prettify.common.PrettyFactory;
import com.google.gerrit.reviewdb.AccountDiffPreference;
import com.google.gerrit.reviewdb.Change;
import com.google.gerrit.reviewdb.Patch;
import com.google.gerrit.reviewdb.PatchSet;
@ -234,7 +233,7 @@ public abstract class PatchScreen extends Screen implements
}
final int ctx = s.getContext();
if (ctx == WHOLE_FILE_CONTEXT && !last.getA().isWholeFile()) {
if (ctx == AccountDiffPreference.WHOLE_FILE_CONTEXT && !last.getA().isWholeFile()) {
// We don't have the entire file here, so we can't render it.
return false;
}

View File

@ -14,16 +14,14 @@
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.account.Util;
import com.google.gerrit.client.rpc.GerritCallback;
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.gerrit.reviewdb.AccountDiffPreference;
import com.google.gerrit.reviewdb.AccountDiffPreference.Whitespace;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.KeyCodes;
@ -43,6 +41,7 @@ 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;
import com.google.gwtjsonrpc.client.VoidResult;
public class PatchScriptSettingsPanel extends Composite implements
HasValueChangeHandlers<PatchScriptSettings> {
@ -71,7 +70,7 @@ public class PatchScriptSettingsPanel extends Composite implements
CheckBox intralineDifference;
@UiField
CheckBox showFullFile;
ListBox context;
@UiField
CheckBox whitespaceErrors;
@ -85,9 +84,24 @@ public class PatchScriptSettingsPanel extends Composite implements
@UiField
Button update;
/**
* Counts +1 for every setEnabled(true) and -1 for every setEnabled(false)
*
* The purpose is to prevent enabling widgets too early. It might happen that
* setEnabled(false) is called from this class and from an event handler
* of ValueChangeEvent in another class. The first setEnabled(true) would then
* enable widgets too early i.e. before the second setEnabled(true) is called.
*
* With this counter the setEnabled(true) will enable widgets only when
* setEnabledCounter == 0. Until it is less than zero setEnabled(true) will
* not enable the widgets.
*/
private int setEnabledCounter;
public PatchScriptSettingsPanel() {
initWidget(uiBinder.createAndBindUi(this));
initIgnoreWhitespace(ignoreWhitespace);
initContext(context);
if (!Gerrit.isSignedIn()) {
reviewed.setVisible(false);
}
@ -103,15 +117,11 @@ public class PatchScriptSettingsPanel extends Composite implements
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());
if (Gerrit.isSignedIn() && Gerrit.getAccountDiffPreference() != null) {
setValue(createPatchScriptSettings(Gerrit.getAccountDiffPreference()));
} else {
s.setContext(DEFAULT_CONTEXT);
setValue(new PatchScriptSettings());
}
setValue(s);
}
@Override
@ -121,12 +131,19 @@ public class PatchScriptSettingsPanel extends Composite implements
}
public void setEnabled(final boolean on) {
for (Widget w : (HasWidgets) getWidget()) {
if (w instanceof FocusWidget) {
((FocusWidget) w).setEnabled(on);
}
if (on) {
setEnabledCounter++;
} else {
setEnabledCounter--;
}
toggleEnabledStatus(on);
if (on && setEnabledCounter == 0 || !on) {
for (Widget w : (HasWidgets) getWidget()) {
if (w instanceof FocusWidget) {
((FocusWidget) w).setEnabled(on);
}
}
toggleEnabledStatus(on);
};
}
public void setEnableSmallFileFeatures(final boolean on) {
@ -135,10 +152,8 @@ public class PatchScriptSettingsPanel extends Composite implements
final PrettySettings p = getValue().getPrettySettings();
syntaxHighlighting.setValue(p.isSyntaxHighlighting());
showFullFile.setValue(getValue().getContext() == WHOLE_FILE_CONTEXT);
} else {
syntaxHighlighting.setValue(false);
showFullFile.setValue(false);
}
toggleEnabledStatus(update.isEnabled());
}
@ -157,12 +172,10 @@ public class PatchScriptSettingsPanel extends Composite implements
private void toggleEnabledStatus(final boolean on) {
intralineDifference.setEnabled(on & enableIntralineDifference);
syntaxHighlighting.setEnabled(on & enableSmallFileFeatures);
showFullFile.setEnabled(on & enableSmallFileFeatures);
final String title =
enableSmallFileFeatures ? null : PatchUtil.C.disabledOnLargeFiles();
syntaxHighlighting.setTitle(title);
showFullFile.setTitle(title);
}
public CheckBox getReviewedCheckBox() {
@ -178,12 +191,11 @@ public class PatchScriptSettingsPanel extends Composite implements
setIgnoreWhitespace(s.getWhitespace());
if (enableSmallFileFeatures) {
showFullFile.setValue(s.getContext() == WHOLE_FILE_CONTEXT);
syntaxHighlighting.setValue(p.isSyntaxHighlighting());
} else {
showFullFile.setValue(false);
syntaxHighlighting.setValue(false);
}
setContext(s.getContext());
tabWidth.setIntValue(p.getTabSize());
colWidth.setIntValue(p.getLineLength());
@ -204,20 +216,7 @@ public class PatchScriptSettingsPanel extends Composite implements
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);
}
s.setContext(getContext());
p.setTabSize(tabWidth.getIntValue());
p.setLineLength(colWidth.getIntValue());
p.setSyntaxHighlighting(syntaxHighlighting.getValue());
@ -227,6 +226,35 @@ public class PatchScriptSettingsPanel extends Composite implements
value = s;
fireEvent(new ValueChangeEvent<PatchScriptSettings>(s) {});
if (Gerrit.isSignedIn()) {
persistDiffPreferences();
}
}
private void persistDiffPreferences() {
setEnabled(false);
final AccountDiffPreference diffPref = new AccountDiffPreference(Gerrit.getUserAccount().getId());
diffPref.setIgnoreWhitespace(getIgnoreWhitespace());
diffPref.setTabSize(tabWidth.getIntValue());
diffPref.setLineLength(colWidth.getIntValue());
diffPref.setSyntaxHighlighting(syntaxHighlighting.getValue());
diffPref.setShowWhitespaceErrors(whitespaceErrors.getValue());
diffPref.setIntralineDifference(intralineDifference.getValue());
diffPref.setShowTabs(showTabs.getValue());
diffPref.setContext(getContext());
Util.ACCOUNT_SVC.changeDiffPreferences(diffPref, new GerritCallback<VoidResult>() {
@Override
public void onSuccess(VoidResult result) {
Gerrit.setAccountDiffPreference(diffPref);
setEnabled(true);
}
@Override
public void onFailure(Throwable caught) {
setEnabled(true);
}
});
}
private void initIgnoreWhitespace(ListBox ws) {
@ -240,6 +268,18 @@ public class PatchScriptSettingsPanel extends Composite implements
Whitespace.IGNORE_ALL_SPACE.name());
}
private void initContext(ListBox context) {
for (final short v : AccountDiffPreference.CONTEXT_CHOICES) {
final String label;
if (v == AccountDiffPreference.WHOLE_FILE_CONTEXT) {
label = Util.C.contextWholeFile();
} else {
label = Util.M.lines(v);
}
context.addItem(label, String.valueOf(v));
}
}
private Whitespace getIgnoreWhitespace() {
final int sel = ignoreWhitespace.getSelectedIndex();
if (0 <= sel) {
@ -257,4 +297,39 @@ public class PatchScriptSettingsPanel extends Composite implements
}
ignoreWhitespace.setSelectedIndex(0);
}
private short getContext() {
final int sel = context.getSelectedIndex();
if (0 <= sel) {
return Short.parseShort(context.getValue(sel));
}
return (short) value.getContext();
}
private void setContext(int ctx) {
String v = String.valueOf(ctx);
for (int i = 0; i < context.getItemCount(); i++) {
if (context.getValue(i).equals(v)) {
context.setSelectedIndex(i);
return;
}
}
context.setSelectedIndex(0);
}
private PatchScriptSettings createPatchScriptSettings(AccountDiffPreference diffPref) {
final PatchScriptSettings s = new PatchScriptSettings();
if (diffPref != null) {
s.setWhitespace(diffPref.getIgnoreWhitespace());
s.setContext(diffPref.getContext());
final PrettySettings p = s.getPrettySettings();
p.setTabSize(diffPref.getTabSize());
p.setLineLength(diffPref.getLineLength());
p.setSyntaxHighlighting(diffPref.isSyntaxHighlighting());
p.setIntralineDifference(diffPref.isIntralineDifference());
p.setShowWhiteSpaceErrors(diffPref.isShowWhitespaceErrors());
p.setShowTabs(diffPref.isShowTabs());
}
return s;
}
}

View File

@ -49,6 +49,7 @@ limitations under the License.
.controls .gwt-ListBox {
font-size: fontSize;
padding: 0;
margin-right: 1em;
}
.updateButton {
@ -61,13 +62,24 @@ limitations under the License.
<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 align='right'>Ignore Whitespace:</td>
<td align='right'>
<g:ListBox
ui:field='ignoreWhitespace'
visibleItemCount='1'
tabIndex='1'/>
</td>
</ui:msg>
<td align='right'>
<ui:msg>Tab Width:
<my:NpIntTextBox
ui:field='tabWidth'
width='2em'
visibleLength='2'
maxLength='2'
tabIndex='3'/>
</ui:msg>
</td>
@ -75,20 +87,13 @@ limitations under the License.
<g:CheckBox
ui:field='syntaxHighlighting'
text='Syntax Coloring'
tabIndex='4'>
tabIndex='5'>
<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>
@ -131,28 +136,27 @@ limitations under the License.
</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>
<ui:msg>
<td align='right'>Context:</td>
<td align='right'>
<g:ListBox
ui:field='context'
visibleItemCount='1'
tabIndex='2'/>
</td>
</ui:msg>
<td>
<td align='right'>
<ui:msg>Columns:
<my:NpIntTextBox
ui:field='colWidth'
width='2.5em'
visibleLength='3'
maxLength='3'
tabIndex='3'/>
tabIndex='4'/>
</ui:msg>
</td>
</tr>
</tr>
</table>
</g:HTMLPanel>
</ui:UiBinder>

View File

@ -158,6 +158,10 @@ public class HostPageServlet extends HttpServlet {
w.write(HPD_ID + ".account=");
json(((IdentifiedUser) user).getAccount(), w);
w.write(";");
w.write(HPD_ID + ".accountDiffPref=");
json(((IdentifiedUser) user).getAccountDiffPreference(), w);
w.write(";");
final byte[] userData = w.toString().getBytes("UTF-8");
raw = concat(page.part1, userData, page.part2);

View File

@ -20,6 +20,7 @@ import com.google.gerrit.common.data.AgreementInfo;
import com.google.gerrit.common.errors.NoSuchEntityException;
import com.google.gerrit.httpd.rpc.BaseServiceImplementation;
import com.google.gerrit.reviewdb.Account;
import com.google.gerrit.reviewdb.AccountDiffPreference;
import com.google.gerrit.reviewdb.AccountGeneralPreferences;
import com.google.gerrit.reviewdb.AccountProjectWatch;
import com.google.gerrit.reviewdb.Project;
@ -64,6 +65,16 @@ class AccountServiceImpl extends BaseServiceImplementation implements
callback.onSuccess(currentUser.get().getAccount());
}
@Override
public void myDiffPreferences(AsyncCallback<AccountDiffPreference> callback) {
run(callback, new Action<AccountDiffPreference>() {
@Override
public AccountDiffPreference run(ReviewDb db) throws OrmException {
return currentUser.get().getAccountDiffPreference();
}
});
}
public void changePreferences(final AccountGeneralPreferences pref,
final AsyncCallback<VoidResult> callback) {
run(callback, new Action<VoidResult>() {
@ -80,6 +91,23 @@ class AccountServiceImpl extends BaseServiceImplementation implements
});
}
@Override
public void changeDiffPreferences(final AccountDiffPreference diffPref,
AsyncCallback<VoidResult> callback) {
run(callback, new Action<VoidResult>(){
public VoidResult run(ReviewDb db) throws OrmException {
Account.Id accountId = getAccountId();
if (!diffPref.getAccountId().equals(getAccountId())) {
throw new IllegalArgumentException("diffPref.getAccountId() "
+ diffPref.getAccountId() + " doesn't match"
+ " the accountId of the signed in user " + getAccountId());
}
db.accountDiffPreferences().upsert(Collections.singleton(diffPref));
return VoidResult.INSTANCE;
}
});
}
public void myProjectWatch(
final AsyncCallback<List<AccountProjectWatchInfo>> callback) {
run(callback, new Action<List<AccountProjectWatchInfo>>() {

View File

@ -18,13 +18,13 @@ import com.google.gerrit.common.data.CommentDetail;
import com.google.gerrit.common.data.PatchScript;
import com.google.gerrit.common.data.PatchScriptSettings;
import com.google.gerrit.common.data.PatchScript.DisplayMethod;
import com.google.gerrit.common.data.PatchScriptSettings.Whitespace;
import com.google.gerrit.prettify.common.EditList;
import com.google.gerrit.prettify.common.SparseFileContent;
import com.google.gerrit.reviewdb.AccountGeneralPreferences;
import com.google.gerrit.reviewdb.AccountDiffPreference;
import com.google.gerrit.reviewdb.Change;
import com.google.gerrit.reviewdb.Patch;
import com.google.gerrit.reviewdb.PatchLineComment;
import com.google.gerrit.reviewdb.AccountDiffPreference.Whitespace;
import com.google.gerrit.reviewdb.Patch.PatchType;
import com.google.gerrit.server.FileTypeRegistry;
import com.google.gerrit.server.patch.PatchListEntry;
@ -96,7 +96,7 @@ class PatchScriptBuilder {
settings = s;
context = settings.getContext();
if (context == AccountGeneralPreferences.WHOLE_FILE_CONTEXT) {
if (context == AccountDiffPreference.WHOLE_FILE_CONTEXT) {
context = MAX_CONTEXT;
} else if (context > MAX_CONTEXT) {
context = MAX_CONTEXT;

View File

@ -17,7 +17,6 @@ package com.google.gerrit.httpd.rpc.patch;
import com.google.gerrit.common.data.CommentDetail;
import com.google.gerrit.common.data.PatchScript;
import com.google.gerrit.common.data.PatchScriptSettings;
import com.google.gerrit.common.data.PatchScriptSettings.Whitespace;
import com.google.gerrit.httpd.rpc.Handler;
import com.google.gerrit.reviewdb.Account;
import com.google.gerrit.reviewdb.Change;
@ -26,6 +25,7 @@ import com.google.gerrit.reviewdb.PatchLineComment;
import com.google.gerrit.reviewdb.PatchSet;
import com.google.gerrit.reviewdb.Project;
import com.google.gerrit.reviewdb.ReviewDb;
import com.google.gerrit.reviewdb.AccountDiffPreference.Whitespace;
import com.google.gerrit.reviewdb.Patch.ChangeType;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;

View File

@ -52,6 +52,10 @@ import java.sql.Timestamp;
* <li>{@link StarredChange}: user has starred the change, tracking
* notifications of updates on that change, or just book-marking it for faster
* future reference. One record per starred change.</li>
*
* <li>{@link AccountDiffPreference}: user's preferences for rendering side-to-side
* and unified diff</li>
*
* </ul>
*/
public final class Account {

View File

@ -0,0 +1,175 @@
// 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.reviewdb;
import com.google.gwtorm.client.Column;
/** Diff formatting preferences of an account */
public class AccountDiffPreference {
/** Default number of lines of context. */
public static final short DEFAULT_CONTEXT = 10;
/** Context setting to display the entire file. */
public static final short WHOLE_FILE_CONTEXT = -1;
/** Typical valid choices for the default context setting. */
public static final short[] CONTEXT_CHOICES =
{3, 10, 25, 50, 75, 100, WHOLE_FILE_CONTEXT};
public static enum Whitespace implements CodedEnum {
IGNORE_NONE('N'), //
IGNORE_SPACE_AT_EOL('E'), //
IGNORE_SPACE_CHANGE('S'), //
IGNORE_ALL_SPACE('A');
private final char code;
private Whitespace(final char c) {
code = c;
}
public char getCode() {
return code;
}
public static Whitespace forCode(final char c) {
for (final Whitespace s : Whitespace.values()) {
if (s.code == c) {
return s;
}
}
return null;
}
}
public static AccountDiffPreference createDefault(Account.Id accountId) {
AccountDiffPreference p = new AccountDiffPreference(accountId);
p.setIgnoreWhitespace(Whitespace.IGNORE_NONE);
p.setTabSize(8);
p.setLineLength(100);
p.setSyntaxHighlighting(true);
p.setShowWhitespaceErrors(true);
p.setIntralineDifference(true);
p.setShowTabs(true);
p.setContext(DEFAULT_CONTEXT);
return p;
}
@Column(id = 1, name = Column.NONE)
protected Account.Id accountId;
@Column(id = 2)
protected char ignoreWhitespace;
@Column(id = 3)
protected int tabSize;
@Column(id = 4)
protected int lineLength;
@Column(id = 5)
protected boolean syntaxHighlighting;
@Column(id = 6)
protected boolean showWhitespaceErrors;
@Column(id = 7)
protected boolean intralineDifference;
@Column(id = 8)
protected boolean showTabs;
/** Number of lines of context when viewing a patch. */
@Column(id = 9)
protected short context;
protected AccountDiffPreference() {
}
public AccountDiffPreference(Account.Id accountId) {
this.accountId = accountId;
}
public Account.Id getAccountId() {
return accountId;
}
public Whitespace getIgnoreWhitespace() {
return Whitespace.forCode(ignoreWhitespace);
}
public void setIgnoreWhitespace(Whitespace ignoreWhitespace) {
this.ignoreWhitespace = ignoreWhitespace.getCode();
}
public int getTabSize() {
return tabSize;
}
public void setTabSize(int tabSize) {
this.tabSize = tabSize;
}
public int getLineLength() {
return lineLength;
}
public void setLineLength(int lineLength) {
this.lineLength = lineLength;
}
public boolean isSyntaxHighlighting() {
return syntaxHighlighting;
}
public void setSyntaxHighlighting(boolean syntaxHighlighting) {
this.syntaxHighlighting = syntaxHighlighting;
}
public boolean isShowWhitespaceErrors() {
return showWhitespaceErrors;
}
public void setShowWhitespaceErrors(boolean showWhitespaceErrors) {
this.showWhitespaceErrors = showWhitespaceErrors;
}
public boolean isIntralineDifference() {
return intralineDifference;
}
public void setIntralineDifference(boolean intralineDifference) {
this.intralineDifference = intralineDifference;
}
public boolean isShowTabs() {
return showTabs;
}
public void setShowTabs(boolean showTabs) {
this.showTabs = showTabs;
}
/** Get the number of lines of context when viewing a patch. */
public short getContext() {
return context;
}
/** Set the number of lines of context when viewing a patch. */
public void setContext(final short s) {
context = s;
}
}

View File

@ -0,0 +1,26 @@
// 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.reviewdb;
import com.google.gwtorm.client.Access;
import com.google.gwtorm.client.OrmException;
import com.google.gwtorm.client.PrimaryKey;
public interface AccountDiffPreferenceAccess extends Access<AccountDiffPreference, Account.Id> {
@PrimaryKey("accountId")
AccountDiffPreference get(Account.Id key) throws OrmException;
}

View File

@ -18,15 +18,6 @@ import com.google.gwtorm.client.Column;
/** Preferences about a single user. */
public final class AccountGeneralPreferences {
/** Default number of lines of context. */
public static final short DEFAULT_CONTEXT = 10;
/** Context setting to display the entire file. */
public static final short WHOLE_FILE_CONTEXT = -1;
/** Typical valid choices for the default context setting. */
public static final short[] CONTEXT_CHOICES =
{3, 10, 25, 50, 75, 100, WHOLE_FILE_CONTEXT};
/** Default number of items to display per page. */
public static final short DEFAULT_PAGESIZE = 25;
@ -44,10 +35,6 @@ public final class AccountGeneralPreferences {
REPO_DOWNLOAD, PULL, CHECKOUT, CHERRY_PICK, FORMAT_PATCH;
}
/** Default number of lines of context when viewing a patch. */
@Column(id = 1)
protected short defaultContext;
/** Number of changes to show in a screen. */
@Column(id = 2)
protected short maximumPageSize;
@ -75,16 +62,6 @@ public final class AccountGeneralPreferences {
public AccountGeneralPreferences() {
}
/** Get the default number of lines of context when viewing a patch. */
public short getDefaultContext() {
return defaultContext;
}
/** Set the number of lines of context when viewing a patch. */
public void setDefaultContext(final short s) {
defaultContext = s;
}
public short getMaximumPageSize() {
return maximumPageSize;
}
@ -148,7 +125,6 @@ public final class AccountGeneralPreferences {
}
public void resetToDefaults() {
defaultContext = DEFAULT_CONTEXT;
maximumPageSize = DEFAULT_PAGESIZE;
showSiteHeader = true;
useFlashClipboard = true;

View File

@ -75,6 +75,9 @@ public interface ReviewDb extends Schema {
@Relation
AccountGroupAgreementAccess accountGroupAgreements();
@Relation
AccountDiffPreferenceAccess accountDiffPreferences();
@Relation
StarredChangeAccess starredChanges();

View File

@ -15,6 +15,7 @@
package com.google.gerrit.server;
import com.google.gerrit.reviewdb.Account;
import com.google.gerrit.reviewdb.AccountDiffPreference;
import com.google.gerrit.reviewdb.AccountGroup;
import com.google.gerrit.reviewdb.AccountProjectWatch;
import com.google.gerrit.reviewdb.Change;
@ -178,6 +179,20 @@ public class IdentifiedUser extends CurrentUser {
return state().getAccount();
}
public AccountDiffPreference getAccountDiffPreference() {
AccountDiffPreference diffPref;
try {
diffPref = dbProvider.get().accountDiffPreferences().get(getAccountId());
if (diffPref == null) {
diffPref = AccountDiffPreference.createDefault(getAccountId());
}
} catch (OrmException e) {
log.warn("Cannot query account diff preferences", e);
diffPref = AccountDiffPreference.createDefault(getAccountId());
}
return diffPref;
}
public Set<String> getEmailAddresses() {
if (emailAddresses == null) {
emailAddresses = state().getEmailAddresses();

View File

@ -14,9 +14,9 @@
package com.google.gerrit.server.patch;
import com.google.gerrit.common.data.PatchScriptSettings.Whitespace;
import com.google.gerrit.reviewdb.Change;
import com.google.gerrit.reviewdb.PatchSet;
import com.google.gerrit.reviewdb.AccountDiffPreference.Whitespace;
/** Provides a cached list of {@link PatchListEntry}. */
public interface PatchListCache {

View File

@ -14,12 +14,11 @@
package com.google.gerrit.server.patch;
import static com.google.gerrit.common.data.PatchScriptSettings.Whitespace.IGNORE_NONE;
import com.google.gerrit.common.data.PatchScriptSettings.Whitespace;
import com.google.gerrit.reviewdb.Change;
import com.google.gerrit.reviewdb.PatchSet;
import com.google.gerrit.reviewdb.Project;
import com.google.gerrit.reviewdb.AccountDiffPreference.Whitespace;
import com.google.gerrit.server.cache.Cache;
import com.google.gerrit.server.cache.CacheModule;
import com.google.gerrit.server.cache.EvictionPolicy;
@ -116,7 +115,7 @@ public class PatchListCacheImpl implements PatchListCache {
}
public PatchList get(final Change change, final PatchSet patchSet) {
return get(change, patchSet, IGNORE_NONE);
return get(change, patchSet, Whitespace.IGNORE_NONE);
}
public PatchList get(final Change change, final PatchSet patchSet,

View File

@ -21,8 +21,8 @@ import static org.eclipse.jgit.lib.ObjectIdSerialization.readNotNull;
import static org.eclipse.jgit.lib.ObjectIdSerialization.writeCanBeNull;
import static org.eclipse.jgit.lib.ObjectIdSerialization.writeNotNull;
import com.google.gerrit.common.data.PatchScriptSettings.Whitespace;
import com.google.gerrit.reviewdb.Project;
import com.google.gerrit.reviewdb.AccountDiffPreference.Whitespace;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.ObjectId;

View File

@ -32,7 +32,7 @@ import java.util.List;
/** A version of the database schema. */
public abstract class SchemaVersion {
/** The current schema version. */
private static final Class<? extends SchemaVersion> C = Schema_37.class;
private static final Class<? extends SchemaVersion> C = Schema_38.class;
public static class Module extends AbstractModule {
@Override

View File

@ -0,0 +1,67 @@
// 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.server.schema;
import com.google.gerrit.reviewdb.Account;
import com.google.gerrit.reviewdb.AccountDiffPreference;
import com.google.gerrit.reviewdb.ReviewDb;
import com.google.gwtorm.client.OrmException;
import com.google.gwtorm.jdbc.JdbcSchema;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
public class Schema_38 extends SchemaVersion {
@Inject
Schema_38(Provider<Schema_37> prior) {
super(prior);
}
/**
* Migrate the account.default_context column to account_diff_preferences.context column.
* <p>
* Other fields in account_diff_preferences will be filled in with their defaults as
* defined in the {@link AccountDiffPreference#createDefault(com.google.gerrit.reviewdb.Account.Id)}
*/
@Override
protected void migrateData(ReviewDb db, UpdateUI ui) throws OrmException,
SQLException {
List<AccountDiffPreference> newPrefs =
new ArrayList<AccountDiffPreference>();
Statement stmt = ((JdbcSchema) db).getConnection().createStatement();
try {
ResultSet result =
stmt.executeQuery("SELECT account_id, default_context"
+ " FROM accounts WHERE default_context <> 10");
while (result.next()) {
int accountId = result.getInt(1);
short defaultContext = result.getShort(2);
AccountDiffPreference diffPref = AccountDiffPreference.createDefault(new Account.Id(accountId));
diffPref.setContext(defaultContext);
newPrefs.add(diffPref);
}
} finally {
stmt.close();
}
db.accountDiffPreferences().insert(newPrefs);
}
}