SideBySide2: Allow the user to select the syntax highlighter
This can be useful if Gerrit does not magically recognize a particular file format. Temporarily forcing on a single mode may make it easier to review the file. Change-Id: I61af2841bdc76cb29b124f10b0946b39c804d823
This commit is contained in:
@@ -32,6 +32,8 @@ import com.google.gerrit.reviewdb.client.AccountDiffPreference;
|
|||||||
import com.google.gerrit.reviewdb.client.AccountDiffPreference.Theme;
|
import com.google.gerrit.reviewdb.client.AccountDiffPreference.Theme;
|
||||||
import com.google.gerrit.reviewdb.client.AccountDiffPreference.Whitespace;
|
import com.google.gerrit.reviewdb.client.AccountDiffPreference.Whitespace;
|
||||||
import com.google.gwt.core.client.GWT;
|
import com.google.gwt.core.client.GWT;
|
||||||
|
import com.google.gwt.core.client.Scheduler;
|
||||||
|
import com.google.gwt.core.client.Scheduler.RepeatingCommand;
|
||||||
import com.google.gwt.event.dom.client.ChangeEvent;
|
import com.google.gwt.event.dom.client.ChangeEvent;
|
||||||
import com.google.gwt.event.dom.client.ClickEvent;
|
import com.google.gwt.event.dom.client.ClickEvent;
|
||||||
import com.google.gwt.event.dom.client.KeyDownEvent;
|
import com.google.gwt.event.dom.client.KeyDownEvent;
|
||||||
@@ -52,6 +54,12 @@ import com.google.gwt.user.client.ui.ListBox;
|
|||||||
import com.google.gwt.user.client.ui.PopupPanel;
|
import com.google.gwt.user.client.ui.PopupPanel;
|
||||||
import com.google.gwt.user.client.ui.ToggleButton;
|
import com.google.gwt.user.client.ui.ToggleButton;
|
||||||
|
|
||||||
|
import net.codemirror.lib.ModeInjector;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
/** Displays current diff preferences. */
|
/** Displays current diff preferences. */
|
||||||
class PreferencesBox extends Composite {
|
class PreferencesBox extends Composite {
|
||||||
interface Binder extends UiBinder<HTMLPanel, PreferencesBox> {}
|
interface Binder extends UiBinder<HTMLPanel, PreferencesBox> {}
|
||||||
@@ -83,6 +91,7 @@ class PreferencesBox extends Composite {
|
|||||||
@UiField ToggleButton expandAllComments;
|
@UiField ToggleButton expandAllComments;
|
||||||
@UiField ToggleButton renderEntireFile;
|
@UiField ToggleButton renderEntireFile;
|
||||||
@UiField ListBox theme;
|
@UiField ListBox theme;
|
||||||
|
@UiField ListBox mode;
|
||||||
@UiField Button apply;
|
@UiField Button apply;
|
||||||
@UiField Button save;
|
@UiField Button save;
|
||||||
|
|
||||||
@@ -92,6 +101,7 @@ class PreferencesBox extends Composite {
|
|||||||
initWidget(uiBinder.createAndBindUi(this));
|
initWidget(uiBinder.createAndBindUi(this));
|
||||||
initIgnoreWhitespace();
|
initIgnoreWhitespace();
|
||||||
initTheme();
|
initTheme();
|
||||||
|
initMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -146,6 +156,11 @@ class PreferencesBox extends Composite {
|
|||||||
renderEntireFile.setEnabled(view.canEnableRenderEntireFile(prefs));
|
renderEntireFile.setEnabled(view.canEnableRenderEntireFile(prefs));
|
||||||
setTheme(prefs.theme());
|
setTheme(prefs.theme());
|
||||||
|
|
||||||
|
mode.setEnabled(prefs.syntaxHighlighting());
|
||||||
|
if (prefs.syntaxHighlighting()) {
|
||||||
|
setMode(view.getContentType());
|
||||||
|
}
|
||||||
|
|
||||||
switch (view.getIntraLineStatus()) {
|
switch (view.getIntraLineStatus()) {
|
||||||
case OFF:
|
case OFF:
|
||||||
case OK:
|
case OK:
|
||||||
@@ -288,9 +303,35 @@ class PreferencesBox extends Composite {
|
|||||||
@UiHandler("syntaxHighlighting")
|
@UiHandler("syntaxHighlighting")
|
||||||
void onSyntaxHighlighting(ValueChangeEvent<Boolean> e) {
|
void onSyntaxHighlighting(ValueChangeEvent<Boolean> e) {
|
||||||
prefs.syntaxHighlighting(e.getValue());
|
prefs.syntaxHighlighting(e.getValue());
|
||||||
|
mode.setEnabled(prefs.syntaxHighlighting());
|
||||||
|
if (prefs.syntaxHighlighting()) {
|
||||||
|
setMode(view.getContentType());
|
||||||
|
}
|
||||||
view.setSyntaxHighlighting(prefs.syntaxHighlighting());
|
view.setSyntaxHighlighting(prefs.syntaxHighlighting());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@UiHandler("mode")
|
||||||
|
void onMode(ChangeEvent e) {
|
||||||
|
final String m = mode.getValue(mode.getSelectedIndex());
|
||||||
|
prefs.syntaxHighlighting(true);
|
||||||
|
syntaxHighlighting.setValue(true, false);
|
||||||
|
Scheduler.get().scheduleFixedDelay(new RepeatingCommand() {
|
||||||
|
@Override
|
||||||
|
public boolean execute() {
|
||||||
|
if (prefs.syntaxHighlighting() && view.isAttached()) {
|
||||||
|
view.operation(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
view.getCmFromSide(DisplaySide.A).setOption("mode", m);
|
||||||
|
view.getCmFromSide(DisplaySide.B).setOption("mode", m);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
|
|
||||||
@UiHandler("whitespaceErrors")
|
@UiHandler("whitespaceErrors")
|
||||||
void onWhitespaceErrors(ValueChangeEvent<Boolean> e) {
|
void onWhitespaceErrors(ValueChangeEvent<Boolean> e) {
|
||||||
prefs.showWhitespaceErrors(e.getValue());
|
prefs.showWhitespaceErrors(e.getValue());
|
||||||
@@ -385,6 +426,51 @@ class PreferencesBox extends Composite {
|
|||||||
IGNORE_ALL_SPACE.name());
|
IGNORE_ALL_SPACE.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final Map<String, String> NAME_TO_MODE;
|
||||||
|
private static final Map<String, String> NORMALIZED_MODES;
|
||||||
|
static {
|
||||||
|
NAME_TO_MODE = new TreeMap<String, String>();
|
||||||
|
NORMALIZED_MODES = new HashMap<String, String>();
|
||||||
|
for (String type : ModeInjector.getKnownMimeTypes()) {
|
||||||
|
String name = type;
|
||||||
|
if (name.startsWith("text/x-")) {
|
||||||
|
name = name.substring("text/x-".length());
|
||||||
|
} else if (name.startsWith("text/")) {
|
||||||
|
name = name.substring("text/".length());
|
||||||
|
} else if (name.startsWith("application/")) {
|
||||||
|
name = name.substring("application/".length());
|
||||||
|
}
|
||||||
|
|
||||||
|
String normalized = NAME_TO_MODE.get(name);
|
||||||
|
if (normalized == null) {
|
||||||
|
normalized = type;
|
||||||
|
NAME_TO_MODE.put(name, normalized);
|
||||||
|
}
|
||||||
|
NORMALIZED_MODES.put(type, normalized);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initMode() {
|
||||||
|
for (Map.Entry<String, String> e : NAME_TO_MODE.entrySet()) {
|
||||||
|
mode.addItem(e.getKey(), e.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setMode(String modeType) {
|
||||||
|
if (modeType != null && !modeType.isEmpty()) {
|
||||||
|
if (NORMALIZED_MODES.containsKey(modeType)) {
|
||||||
|
modeType =NORMALIZED_MODES.get(modeType);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < mode.getItemCount(); i++) {
|
||||||
|
if (mode.getValue(i).equals(modeType)) {
|
||||||
|
mode.setSelectedIndex(i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mode.setSelectedIndex(0);
|
||||||
|
}
|
||||||
|
|
||||||
private void setTheme(Theme v) {
|
private void setTheme(Theme v) {
|
||||||
String name = v != null ? v.name() : Theme.DEFAULT.name();
|
String name = v != null ? v.name() : Theme.DEFAULT.name();
|
||||||
for (int i = 0; i < theme.getItemCount(); i++) {
|
for (int i = 0; i < theme.getItemCount(); i++) {
|
||||||
|
|||||||
@@ -203,6 +203,10 @@ limitations under the License.
|
|||||||
<g:downFace><ui:msg>Show</ui:msg></g:downFace>
|
<g:downFace><ui:msg>Show</ui:msg></g:downFace>
|
||||||
</g:ToggleButton></td>
|
</g:ToggleButton></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th><ui:msg>Language</ui:msg></th>
|
||||||
|
<td><g:ListBox ui:field='mode'/></td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th><ui:msg>Whitespace Errors</ui:msg></th>
|
<th><ui:msg>Whitespace Errors</ui:msg></th>
|
||||||
<td><g:ToggleButton ui:field='whitespaceErrors'>
|
<td><g:ToggleButton ui:field='whitespaceErrors'>
|
||||||
|
|||||||
@@ -591,6 +591,10 @@ public class SideBySide2 extends Screen {
|
|||||||
|| (prefs.context() != WHOLE_FILE_CONTEXT && prefs.context() < 100);
|
|| (prefs.context() != WHOLE_FILE_CONTEXT && prefs.context() < 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getContentType() {
|
||||||
|
return getContentType(diff.meta_b());
|
||||||
|
}
|
||||||
|
|
||||||
void setThemeStyles(boolean d) {
|
void setThemeStyles(boolean d) {
|
||||||
if (d) {
|
if (d) {
|
||||||
diffTable.addStyleName(DiffTable.style.dark());
|
diffTable.addStyleName(DiffTable.style.dark());
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import com.google.gwt.user.client.rpc.AsyncCallback;
|
|||||||
|
|
||||||
import net.codemirror.mode.Modes;
|
import net.codemirror.mode.Modes;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -94,6 +95,10 @@ public class ModeInjector {
|
|||||||
return real != null ? real : mode;
|
return real != null ? real : mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Collection<String> getKnownMimeTypes() {
|
||||||
|
return mimeModes.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
private static native boolean isModeLoaded(String n)
|
private static native boolean isModeLoaded(String n)
|
||||||
/*-{ return $wnd.CodeMirror.modes.hasOwnProperty(n); }-*/;
|
/*-{ return $wnd.CodeMirror.modes.hasOwnProperty(n); }-*/;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user