| // 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 com.google.gerrit.client.ErrorDialog; |
| 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.ListenableAccountDiffPreference; |
| import com.google.gerrit.client.ui.NpIntTextBox; |
| import com.google.gerrit.extensions.client.DiffPreferencesInfo; |
| import com.google.gerrit.extensions.client.DiffPreferencesInfo.Whitespace; |
| import com.google.gwt.core.client.GWT; |
| import com.google.gwt.dom.client.NodeList; |
| import com.google.gwt.dom.client.OptionElement; |
| import com.google.gwt.dom.client.SelectElement; |
| 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.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; |
| import com.google.gwtjsonrpc.common.VoidResult; |
| |
| public class PatchScriptSettingsPanel extends Composite { |
| private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class); |
| |
| interface MyUiBinder extends UiBinder<Widget, PatchScriptSettingsPanel> { |
| } |
| |
| private final ListenableAccountDiffPreference listenablePrefs; |
| private boolean enableIntralineDifference = true; |
| private boolean enableSmallFileFeatures = true; |
| |
| @UiField |
| ListBox ignoreWhitespace; |
| |
| @UiField |
| NpIntTextBox tabWidth; |
| |
| @UiField |
| NpIntTextBox colWidth; |
| |
| @UiField |
| CheckBox syntaxHighlighting; |
| |
| @UiField |
| CheckBox intralineDifference; |
| |
| @UiField |
| ListBox context; |
| |
| @UiField |
| CheckBox whitespaceErrors; |
| |
| @UiField |
| CheckBox showLineEndings; |
| |
| @UiField |
| CheckBox showTabs; |
| |
| @UiField |
| CheckBox manualReview; |
| |
| @UiField |
| CheckBox skipDeleted; |
| |
| @UiField |
| CheckBox skipUncommented; |
| |
| @UiField |
| CheckBox expandAllComments; |
| |
| @UiField |
| CheckBox retainHeader; |
| |
| @UiField |
| Button update; |
| |
| @UiField |
| Button save; |
| |
| /** |
| * 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(ListenableAccountDiffPreference prefs) { |
| listenablePrefs = prefs; |
| initWidget(uiBinder.createAndBindUi(this)); |
| initIgnoreWhitespace(ignoreWhitespace); |
| initContext(context); |
| if (!Gerrit.isSignedIn()) { |
| save.setVisible(false); |
| } |
| |
| KeyPressHandler onEnter = new KeyPressHandler() { |
| @Override |
| public void onKeyPress(KeyPressEvent event) { |
| if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) { |
| save(); |
| } |
| } |
| }; |
| tabWidth.addKeyPressHandler(onEnter); |
| colWidth.addKeyPressHandler(onEnter); |
| |
| display(); |
| } |
| |
| public void setEnabled(final boolean on) { |
| if (on) { |
| setEnabledCounter++; |
| } else { |
| setEnabledCounter--; |
| } |
| 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) { |
| enableSmallFileFeatures = on; |
| if (enableSmallFileFeatures) { |
| syntaxHighlighting.setValue(getValue().syntaxHighlighting); |
| } else { |
| syntaxHighlighting.setValue(false); |
| } |
| |
| NodeList<OptionElement> options = |
| context.getElement().<SelectElement>cast().getOptions(); |
| // WHOLE_FILE_CONTEXT is the last option in the list. |
| int lastIndex = options.getLength() - 1; |
| OptionElement currOption = options.getItem(lastIndex); |
| if (enableSmallFileFeatures) { |
| currOption.setDisabled(false); |
| } else { |
| currOption.setDisabled(true); |
| if (context.getSelectedIndex() == lastIndex) { |
| // Select the next longest context from WHOLE_FILE_CONTEXT |
| context.setSelectedIndex(lastIndex - 1); |
| } |
| } |
| toggleEnabledStatus(save.isEnabled()); |
| } |
| |
| public void setEnableIntralineDifference(final boolean on) { |
| enableIntralineDifference = on; |
| if (enableIntralineDifference) { |
| intralineDifference.setValue(getValue().intralineDifference); |
| } else { |
| intralineDifference.setValue(false); |
| } |
| toggleEnabledStatus(save.isEnabled()); |
| } |
| |
| private void toggleEnabledStatus(final boolean on) { |
| intralineDifference.setEnabled(on & enableIntralineDifference); |
| syntaxHighlighting.setEnabled(on & enableSmallFileFeatures); |
| |
| final String title = |
| enableSmallFileFeatures ? null : PatchUtil.C.disabledOnLargeFiles(); |
| syntaxHighlighting.setTitle(title); |
| } |
| |
| public DiffPreferencesInfo getValue() { |
| return listenablePrefs.get(); |
| } |
| |
| public void setValue(final DiffPreferencesInfo dp) { |
| listenablePrefs.set(dp); |
| display(); |
| } |
| |
| protected void display() { |
| final DiffPreferencesInfo dp = getValue(); |
| setIgnoreWhitespace(dp.ignoreWhitespace); |
| if (enableSmallFileFeatures) { |
| syntaxHighlighting.setValue(dp.syntaxHighlighting); |
| } else { |
| syntaxHighlighting.setValue(false); |
| } |
| setContext(dp.context); |
| |
| tabWidth.setIntValue(dp.tabSize); |
| colWidth.setIntValue(dp.lineLength); |
| intralineDifference.setValue(dp.intralineDifference); |
| whitespaceErrors.setValue(dp.showWhitespaceErrors); |
| showLineEndings.setValue(dp.showLineEndings); |
| showTabs.setValue(dp.showTabs); |
| skipDeleted.setValue(dp.skipDeleted); |
| skipUncommented.setValue(dp.skipUncommented); |
| expandAllComments.setValue(dp.expandAllComments); |
| retainHeader.setValue(dp.retainHeader); |
| manualReview.setValue(dp.manualReview); |
| } |
| |
| @UiHandler("update") |
| void onUpdate(@SuppressWarnings("unused") ClickEvent event) { |
| update(); |
| } |
| |
| @UiHandler("save") |
| void onSave(@SuppressWarnings("unused") ClickEvent event) { |
| save(); |
| } |
| |
| private void update() { |
| if (colWidth.getIntValue() <= 0) { |
| new ErrorDialog(PatchUtil.C.illegalNumberOfColumns()).center(); |
| return; |
| } |
| DiffPreferencesInfo dp = getValue(); |
| dp.ignoreWhitespace = getIgnoreWhitespace(); |
| dp.context = getContext(); |
| dp.tabSize = tabWidth.getIntValue(); |
| dp.lineLength = colWidth.getIntValue(); |
| dp.syntaxHighlighting = syntaxHighlighting.getValue(); |
| dp.intralineDifference = intralineDifference.getValue(); |
| dp.showWhitespaceErrors = whitespaceErrors.getValue(); |
| dp.showLineEndings = showLineEndings.getValue(); |
| dp.showTabs = showTabs.getValue(); |
| dp.skipDeleted = skipDeleted.getValue(); |
| dp.skipUncommented = skipUncommented.getValue(); |
| dp.expandAllComments = expandAllComments.getValue(); |
| dp.retainHeader = retainHeader.getValue(); |
| dp.manualReview = manualReview.getValue(); |
| |
| listenablePrefs.set(dp); |
| } |
| |
| private void save() { |
| update(); |
| if (Gerrit.isSignedIn()) { |
| persistDiffPreferences(); |
| } |
| } |
| |
| private void persistDiffPreferences() { |
| setEnabled(false); |
| listenablePrefs.save(new GerritCallback<VoidResult>() { |
| @Override |
| public void onSuccess(VoidResult result) { |
| setEnabled(true); |
| } |
| |
| @Override |
| public void onFailure(Throwable caught) { |
| setEnabled(true); |
| } |
| }); |
| } |
| |
| private void initIgnoreWhitespace(ListBox ws) { |
| ws.addItem(PatchUtil.C.whitespaceIGNORE_NONE(), // |
| Whitespace.IGNORE_NONE.name()); |
| ws.addItem(PatchUtil.C.whitespaceIGNORE_TRAILING(), // |
| Whitespace.IGNORE_TRAILING.name()); |
| ws.addItem(PatchUtil.C.whitespaceIGNORE_LEADING_AND_TRAILING(), // |
| Whitespace.IGNORE_LEADING_AND_TRAILING.name()); |
| ws.addItem(PatchUtil.C.whitespaceIGNORE_ALL(), // |
| Whitespace.IGNORE_ALL.name()); |
| } |
| |
| private void initContext(ListBox context) { |
| for (final short v : DiffPreferencesInfo.CONTEXT_CHOICES) { |
| final String label; |
| if (v == DiffPreferencesInfo.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) { |
| return Whitespace.valueOf(ignoreWhitespace.getValue(sel)); |
| } |
| return getValue().ignoreWhitespace; |
| } |
| |
| 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); |
| } |
| |
| private int getContext() { |
| final int sel = context.getSelectedIndex(); |
| if (0 <= sel) { |
| return Short.parseShort(context.getValue(sel)); |
| } |
| return getValue().context; |
| } |
| |
| 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); |
| } |
| } |