aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobin Stocker2010-11-02 10:43:00 (EDT)
committerMatthias Sohn2010-11-09 18:33:21 (EST)
commit6bbea8ebb8dfff86cdf8f8f6c6aa4582719eec0b (patch)
tree1b2fecbcedb9918b672cdb94301f7af3b6e394d7
parent3fe3bc1baa91c811c7269257dce7baa27ba2fc83 (diff)
downloadegit-6bbea8ebb8dfff86cdf8f8f6c6aa4582719eec0b.zip
egit-6bbea8ebb8dfff86cdf8f8f6c6aa4582719eec0b.tar.gz
egit-6bbea8ebb8dfff86cdf8f8f6c6aa4582719eec0b.tar.bz2
Optionally hard-wrap commit messagerefs/changes/44/1244/5
When "hard-wrap" is enabled in the new Commit Dialog preference page, the commit message editor automatically inserts newlines as the user is typing the commit message. The text width is 70. If a line the user is typing would be longer than that, a newline is automatically inserted before the last word. Existing newlines are not touched, to allow for manual formatting (e.g. ASCII graphics). The editor shows the commit message in a configurable font that defaults to the text font. This font is usually fixed-width, so that the margin line can be shown after exactly 70 characters. CQ: 4628 Bug: 329489 Change-Id: Ic8ae2f99b595f5f994af3cdb08b9363d2d53e685 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
-rw-r--r--org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/dialogs/commit/CommitMessageAreaTest.java141
-rw-r--r--org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/AllLocalTests.java2
-rw-r--r--org.eclipse.egit.ui/plugin.properties3
-rw-r--r--org.eclipse.egit.ui/plugin.xml22
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/PluginPreferenceInitializer.java1
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIPreferences.java4
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java12
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CommitDialog.java26
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CommitMessageArea.java183
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/CommitDialogPreferencePage.java48
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties5
11 files changed, 440 insertions, 7 deletions
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/dialogs/commit/CommitMessageAreaTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/dialogs/commit/CommitMessageAreaTest.java
new file mode 100644
index 0000000..819b98d
--- /dev/null
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/dialogs/commit/CommitMessageAreaTest.java
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Robin Stocker
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.ui.dialogs.commit;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.List;
+
+import org.eclipse.egit.ui.internal.dialogs.CommitMessageArea;
+import org.eclipse.egit.ui.internal.dialogs.CommitMessageArea.WrapEdit;
+import org.junit.Test;
+
+public class CommitMessageAreaTest {
+
+ @Test
+ public void dontWrapShortText() {
+ String input = "short message";
+ assertWrappedEquals(input, input);
+ }
+
+ @Test
+ public void dontWrapAlreadyWrappedText() {
+ String input = "This is a test of wrapping\n\nDid it work?\n\nHm?";
+ assertWrappedEquals(input, input);
+ }
+
+ @Test
+ public void dontWrapMaximumLengthText() {
+ String input = "123456789 123456789 123456789 123456789 123456789 123456789 123456789.";
+ assertWrappedEquals(input, input);
+ }
+
+ @Test
+ public void wrapOverlengthText() {
+ String input = "123456789 123456789 123456789 123456789 123456789 123456789 123456789. 123";
+ String expected = "123456789 123456789 123456789 123456789 123456789 123456789 123456789.\n123";
+ assertWrappedEquals(expected, input);
+ }
+
+ @Test
+ public void wrapOverlengthTextByOne() {
+ String input = "123456789 123456789 123456789 123456789 123456789 123456789 123456789ab";
+ String expected = "123456789 123456789 123456789 123456789 123456789 123456789\n123456789ab";
+ assertWrappedEquals(expected, input);
+ }
+
+ @Test
+ public void wrapOverlengthText2() {
+ String input = "123456789 123456789 123456789 123456789 123456789 123456789. 12345678901234";
+ String expected = "123456789 123456789 123456789 123456789 123456789 123456789.\n12345678901234";
+ assertWrappedEquals(expected, input);
+ }
+
+ public void wrapOverlengthTextTwice() {
+ String input = "123456789 123456789 123456789 123456789 123456789 123456789 123456789. "
+ + "123456789 123456789 123456789 123456789 123456789 123456789 123456789. "
+ + "123456789 123456789 123456789 123456789 123456789 123456789 123456789.";
+ String expected = "123456789 123456789 123456789 123456789 123456789 123456789 123456789.\n"
+ + "123456789 123456789 123456789 123456789 123456789 123456789 123456789.\n"
+ + "123456789 123456789 123456789 123456789 123456789 123456789 123456789.";
+ assertWrappedEquals(expected, input);
+ }
+
+ @Test
+ public void dontWrapWordLongerThanOneLineAtStart() {
+ String input = "12345678901234567890123456789012345678901234567890123456789012345678901234567890 the previous was longer than a line";
+ String expected = "12345678901234567890123456789012345678901234567890123456789012345678901234567890\nthe previous was longer than a line";
+ assertWrappedEquals(expected, input);
+ }
+
+ @Test
+ public void dontWrapWordLongerThanOneLine() {
+ String input = "This has to be on its own line: 12345678901234567890123456789012345678901234567890123456789012345678901234567890 this not";
+ String expected = "This has to be on its own line:\n12345678901234567890123456789012345678901234567890123456789012345678901234567890\nthis not";
+ assertWrappedEquals(expected, input);
+ }
+
+ @Test
+ public void wrapSecondLongLine() {
+ String input = "First line\n123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789.";
+ String expected = "First line\n123456789 123456789 123456789 123456789 123456789 123456789 123456789\n123456789.";
+ assertWrappedEquals(expected, input);
+ }
+
+ @Test
+ public void keepExistingNewlines() {
+ String input = "This\n\nis\nall\nok\n123456789 123456789 123456789 123456789 123456789 123456789 123456789.";
+ assertWrappedEquals(input, input);
+ }
+
+ @Test
+ public void keepNewlineAtEnd() {
+ String input = "Newline\nat\nend\n";
+ assertWrappedEquals(input, input);
+ }
+
+ @Test
+ public void keepWhitespace() {
+ String input = " this is deliberate whitespace";
+ assertWrappedEquals(input, input);
+ }
+
+ @Test
+ public void keepTrailingSpace() {
+ String input = "space at end ";
+ assertWrappedEquals(input, input);
+ }
+
+ private static void assertWrappedEquals(String expected, String input) {
+ assertWrappedEqualsOnUnix(expected, input);
+ assertWrappedEqualsOnWindows(expected, input);
+ }
+
+ private static void assertWrappedEqualsOnUnix(String expected, String input) {
+ String wrapped = wrap(input, "\n");
+ assertEquals(expected, wrapped);
+ }
+
+ private static void assertWrappedEqualsOnWindows(String expected,
+ String input) {
+ String wrapped = wrap(input.replaceAll("\n", "\r\n"), "\r\n");
+ assertEquals(expected.replaceAll("\n", "\r\n"), wrapped);
+ }
+
+ private static String wrap(String text, String lineDelimiter) {
+ StringBuilder sb = new StringBuilder(text);
+ List<WrapEdit> wrapEdits = CommitMessageArea.calculateWrapEdits(text, 70,
+ lineDelimiter);
+ for (WrapEdit wrapEdit : wrapEdits) {
+ sb.replace(wrapEdit.getStart(),
+ wrapEdit.getStart() + wrapEdit.getLength(), lineDelimiter);
+ }
+ return sb.toString();
+ }
+}
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/AllLocalTests.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/AllLocalTests.java
index ef5c6c5..65486e3 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/AllLocalTests.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/AllLocalTests.java
@@ -8,6 +8,7 @@
*******************************************************************************/
package org.eclipse.egit.ui.test;
+import org.eclipse.egit.ui.dialogs.commit.CommitMessageAreaTest;
import org.eclipse.egit.ui.prefpages.configuration.GlobalConfigurationPageTest;
import org.eclipse.egit.ui.test.history.HistoryViewTest;
import org.eclipse.egit.ui.test.team.actions.AllTeamActionTests;
@@ -27,6 +28,7 @@ import org.junit.runners.Suite.SuiteClasses;
SharingWizardTest.class, //
AllTeamActionTests.class, //
HistoryViewTest.class, //
+ CommitMessageAreaTest.class,
TraceConfigurationDialogTest.class,
SynchronizeViewTest.class})
public class AllLocalTests {
diff --git a/org.eclipse.egit.ui/plugin.properties b/org.eclipse.egit.ui/plugin.properties
index 69b75b2..d6b3bfc 100644
--- a/org.eclipse.egit.ui/plugin.properties
+++ b/org.eclipse.egit.ui/plugin.properties
@@ -55,6 +55,8 @@ Theme_CommitGraphHighlightFont_label=Commit graph highlight font
Theme_CommitGraphHighlightFont_description=This font is used to highlight matching commits in the revision history.
Theme_CommitMessageFont_label=Commit message font
Theme_CommitMessageFont_description=This font is used to show a commit message.
+Theme_CommitMessageEditorFont_label=Commit message editor font
+Theme_CommitMessageEditorFont_description=This font is used when entering a commit message.
Theme_UncommittedChangeForegroundColor_label=Uncommitted Change (Foreground)
Theme_UncommittedChangeForegroundColor_description=This color is used for the foreground color for resources that have outgoing changes.
Theme_UncommittedChangeBackgroundColor_label=Uncommitted Change (Background)
@@ -65,6 +67,7 @@ Theme_UncommittedChangeFont_description=The font used to display outgoing change
GitPreferences_name=Git
GitPreferences_WindowCachePreferencePage_name=Window Cache
GitPreferences_DecoratorPreferencePage_name=Label Decorations
+GitPreferences_CommitDialogPreferencePage_name=Commit Dialog
ShareProjectCommand_name=Share with Git
ShareProjectCommand_desc=Share the project using Git
diff --git a/org.eclipse.egit.ui/plugin.xml b/org.eclipse.egit.ui/plugin.xml
index ffc2c12..ee2c43c 100644
--- a/org.eclipse.egit.ui/plugin.xml
+++ b/org.eclipse.egit.ui/plugin.xml
@@ -328,7 +328,7 @@
id="org.eclipse.egit.ui.keyword.git">
</keywordReference>
</page>
- <page
+ <page
category="org.eclipse.egit.ui.GitPreferences"
class="org.eclipse.egit.ui.internal.preferences.GlobalConfigurationPreferencePage"
id="org.eclipse.egit.ui.internal.preferences.GlobalConfigurationPreferencePage"
@@ -336,7 +336,16 @@
<keywordReference
id="org.eclipse.egit.ui.keyword.git">
</keywordReference>
- </page>
+ </page>
+ <page
+ category="org.eclipse.egit.ui.GitPreferences"
+ class="org.eclipse.egit.ui.internal.preferences.CommitDialogPreferencePage"
+ id="org.eclipse.egit.ui.internal.preferences.CommitDialogPreferencePage"
+ name="%GitPreferences_CommitDialogPreferencePage_name">
+ <keywordReference
+ id="org.eclipse.egit.ui.keyword.git">
+ </keywordReference>
+ </page>
</extension>
<extension point="org.eclipse.ui.propertyPages">
@@ -441,6 +450,15 @@
%Theme_UncommittedChangeFont_description
</description>
</fontDefinition>
+ <fontDefinition
+ categoryId="org.eclipse.egit.ui.GitTheme"
+ defaultsTo="org.eclipse.jface.textfont"
+ id="org.eclipse.egit.ui.CommitMessageEditorFont"
+ label="%Theme_CommitMessageEditorFont_label">
+ <description>
+ %Theme_CommitMessageEditorFont_description
+ </description>
+ </fontDefinition>
</extension>
<!-- ********** QuickDiff text editor support ************** -->
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/PluginPreferenceInitializer.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/PluginPreferenceInitializer.java
index 2908bfc..4d0c355 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/PluginPreferenceInitializer.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/PluginPreferenceInitializer.java
@@ -64,6 +64,7 @@ public class PluginPreferenceInitializer extends AbstractPreferenceInitializer {
store.setDefault(UIPreferences.FINDTOOLBAR_IGNORE_CASE, true);
store.setDefault(UIPreferences.FINDTOOLBAR_FIND_IN, 2);
+ store.setDefault(UIPreferences.COMMIT_DIALOG_HARD_WRAP_MESSAGE, true);
store.setDefault(UIPreferences.REFESH_ON_INDEX_CHANGE, true);
store.setDefault(UIPreferences.REFESH_ONLY_WHEN_ACTIVE, true);
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIPreferences.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIPreferences.java
index 0d3c7f1..57a20ea 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIPreferences.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIPreferences.java
@@ -50,6 +50,8 @@ public class UIPreferences {
public final static String FINDTOOLBAR_COMMITTER = "findtoolbar_committer"; //$NON-NLS-1$
/** */
public final static String FINDTOOLBAR_FIND_IN = "findtoolbar_find_in"; //$NON-NLS-1$
+ /** */
+ public final static String COMMIT_DIALOG_HARD_WRAP_MESSAGE = "commit_dialog_hard_wrap_message"; //$NON-NLS-1$
/** */
public final static String THEME_CommitGraphNormalFont = "org.eclipse.egit.ui.CommitGraphNormalFont"; //$NON-NLS-1$
@@ -58,6 +60,8 @@ public class UIPreferences {
/** */
public final static String THEME_CommitMessageFont = "org.eclipse.egit.ui.CommitMessageFont"; //$NON-NLS-1$
/** */
+ public final static String THEME_CommitMessageEditorFont = "org.eclipse.egit.ui.CommitMessageEditorFont"; //$NON-NLS-1$
+ /** */
public final static String THEME_UncommittedChangeForegroundColor = "org.eclipse.egit.ui.UncommittedChangeForegroundColor"; //$NON-NLS-1$
/** */
public final static String THEME_UncommittedChangeBackgroundColor = "org.eclipse.egit.ui.UncommittedChangeBackgroundColor"; //$NON-NLS-1$
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java
index 118463b..e3cf4cd 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java
@@ -1303,6 +1303,9 @@ public class UIText extends NLS {
public static String CommitDialog_AddChangeIdTooltip;
/** */
+ public static String CommitDialog_ConfigureLink;
+
+ /** */
public static String ConfigurationEditorComponent_AddButton;
/** */
@@ -1792,6 +1795,15 @@ public class UIText extends NLS {
public static String BranchSelectionDialog_Rename;
/** */
+ public static String CommitDialogPreferencePage_title;
+
+ /** */
+ public static String CommitDialogPreferencePage_hardWrapMessage;
+
+ /** */
+ public static String CommitDialogPreferencePage_hardWrapMessageTooltip;
+
+ /** */
public static String Decorator_exceptionMessage;
/** */
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CommitDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CommitDialog.java
index 91352f3..f14a4a2 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CommitDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CommitDialog.java
@@ -47,6 +47,7 @@ import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.preference.PreferenceDialog;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
@@ -72,12 +73,14 @@ import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
@@ -89,6 +92,7 @@ import org.eclipse.team.core.RepositoryProvider;
import org.eclipse.team.core.history.IFileHistory;
import org.eclipse.team.core.history.IFileHistoryProvider;
import org.eclipse.team.core.history.IFileRevision;
+import org.eclipse.ui.dialogs.PreferencesUtil;
import org.eclipse.ui.model.WorkbenchLabelProvider;
/**
@@ -194,8 +198,10 @@ public class CommitDialog extends Dialog {
label.setLayoutData(GridDataFactory.fillDefaults().span(2, 1).grab(true, false).create());
commitText = new CommitMessageArea(container, commitMessage);
+ Point size = commitText.getTextWidget().getSize();
+ int minHeight = commitText.getTextWidget().getLineHeight() * 3;
commitText.setLayoutData(GridDataFactory.fillDefaults().span(2, 1).grab(true, true)
- .hint(600, 200).create());
+ .hint(size).minSize(size.x, minHeight).align(SWT.FILL, SWT.FILL).create());
commitText.setText(commitMessage);
// allow to commit with ctrl-enter
@@ -241,6 +247,20 @@ public class CommitDialog extends Dialog {
committerHandler = UIUtils.addPreviousValuesContentProposalToText(committerText, COMMITTER_VALUES_PREF);
+ Link preferencesLink = new Link(container, SWT.NONE);
+ preferencesLink.setText(UIText.CommitDialog_ConfigureLink);
+ preferencesLink.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ String preferencePageId = "org.eclipse.egit.ui.internal.preferences.CommitDialogPreferencePage"; //$NON-NLS-1$
+ PreferenceDialog dialog = PreferencesUtil
+ .createPreferenceDialogOn(null, preferencePageId,
+ new String[] { preferencePageId }, null);
+ dialog.open();
+ commitText.reconfigure();
+ }
+ });
+
amendingButton = new Button(container, SWT.CHECK);
if (amending) {
amendingButton.setSelection(amending);
@@ -599,7 +619,7 @@ public class CommitDialog extends Dialog {
* @return The message the user entered
*/
public String getCommitMessage() {
- return commitMessage.replaceAll(Text.DELIMITER, "\n"); //$NON-NLS-1$;
+ return commitMessage;
}
/**
@@ -740,7 +760,7 @@ public class CommitDialog extends Dialog {
@Override
protected void okPressed() {
- commitMessage = commitText.getText();
+ commitMessage = commitText.getCommitMessage();
author = authorText.getText().trim();
committer = committerText.getText().trim();
signedOff = signedOffButton.getSelection();
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CommitMessageArea.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CommitMessageArea.java
index aebcfcd..adb9594 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CommitMessageArea.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CommitMessageArea.java
@@ -12,9 +12,13 @@
package org.eclipse.egit.ui.internal.dialogs;
import java.util.Iterator;
+import java.util.LinkedList;
import java.util.List;
+import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.UIPreferences;
import org.eclipse.egit.ui.UIText;
+import org.eclipse.egit.ui.UIUtils;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
@@ -47,7 +51,11 @@ import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
@@ -118,6 +126,7 @@ public class CommitMessageArea extends Composite {
}
private final SourceViewer sourceViewer;
+ private ModifyListener hardWrapModifyListener;
/**
* @param parent
@@ -130,10 +139,19 @@ public class CommitMessageArea extends Composite {
AnnotationModel annotationModel = new AnnotationModel();
sourceViewer = new SourceViewer(this, null, null, true, SWT.MULTI
| SWT.V_SCROLL | SWT.WRAP);
- getTextWidget().setIndent(2);
+ getTextWidget().setFont(UIUtils
+ .getFont(UIPreferences.THEME_CommitMessageEditorFont));
+
+ int endSpacing = 2;
+ int textWidth = getCharWidth() * 70 + endSpacing;
+ int textHeight = getLineHeight() * 7;
+ Point size = getTextWidget().computeSize(textWidth, textHeight);
+ getTextWidget().setSize(size);
createMarginPainter();
+ configureHardWrap();
+
final SourceViewerDecorationSupport support = configureAnnotationPreferences();
final IHandlerActivation handlerActivation = installQuickFixActionHandler();
@@ -153,6 +171,39 @@ public class CommitMessageArea extends Composite {
});
}
+ private void configureHardWrap() {
+ if (shouldHardWrap()) {
+ if (hardWrapModifyListener == null) {
+ final StyledText textWidget = getTextWidget();
+
+ hardWrapModifyListener = new ModifyListener() {
+
+ private boolean active = true;
+
+ public void modifyText(ModifyEvent e) {
+ if (!active) {
+ return;
+ }
+ String lineDelimiter = textWidget.getLineDelimiter();
+ List<WrapEdit> wrapEdits = calculateWrapEdits(textWidget.getText(), 70, lineDelimiter);
+ // Prevent infinite loop because replaceTextRange causes a ModifyEvent
+ active = false;
+ for (WrapEdit wrapEdit : wrapEdits) {
+ textWidget.replaceTextRange(wrapEdit.getStart(), wrapEdit.getLength(), lineDelimiter);
+ }
+ active = true;
+ }
+ };
+ textWidget.addModifyListener(hardWrapModifyListener);
+ }
+ } else {
+ if (hardWrapModifyListener != null) {
+ getTextWidget().removeModifyListener(hardWrapModifyListener);
+ hardWrapModifyListener = null;
+ }
+ }
+ }
+
private void configureContextMenu() {
final TextViewerAction cutAction = new TextViewerAction(sourceViewer, ITextOperationTarget.CUT);
cutAction.setText(UIText.CommitMessageArea_cut);
@@ -311,12 +362,31 @@ public class CommitMessageArea extends Composite {
private void createMarginPainter() {
MarginPainter marginPainter = new MarginPainter(sourceViewer);
- marginPainter.setMarginRulerColumn(65);
+ marginPainter.setMarginRulerColumn(70);
marginPainter.setMarginRulerColor(Display.getDefault().getSystemColor(
SWT.COLOR_GRAY));
sourceViewer.addPainter(marginPainter);
}
+ private int getCharWidth() {
+ GC gc = new GC(getTextWidget());
+ int charWidth = gc.getFontMetrics().getAverageCharWidth();
+ gc.dispose();
+ return charWidth;
+ }
+
+ private int getLineHeight() {
+ return getTextWidget().getLineHeight();
+ }
+
+ /**
+ * @return if the commit message should be hard-wrapped (preference)
+ */
+ private static boolean shouldHardWrap() {
+ return Activator.getDefault().getPreferenceStore()
+ .getBoolean(UIPreferences.COMMIT_DIALOG_HARD_WRAP_MESSAGE);
+ }
+
/**
* @return widget
*/
@@ -352,6 +422,24 @@ public class CommitMessageArea extends Composite {
}
/**
+ * Return the commit message, converting platform-specific line endings.
+ *
+ * @return commit message
+ */
+ public String getCommitMessage() {
+ String text = getText();
+ text = text.replaceAll(getTextWidget().getLineDelimiter(), "\n"); //$NON-NLS-1$
+ return text;
+ }
+
+ /**
+ * Reconfigure this widget if a preference has changed.
+ */
+ public void reconfigure() {
+ configureHardWrap();
+ }
+
+ /**
* @return text
*/
public String getText() {
@@ -372,4 +460,95 @@ public class CommitMessageArea extends Composite {
return getTextWidget().setFocus();
}
+ /**
+ * Calculate a list of {@link WrapEdit} which can be applied to the text to
+ * get a new text that is wrapped at word boundaries. Existing line breaks
+ * are left alone (text is not reflowed).
+ *
+ * @param text
+ * the text to calculate the wrap edits for
+ * @param maxLineLength
+ * the maximum line length
+ * @param lineDelimiter
+ * line delimiter used in text and for wrapping
+ * @return a list of {@link WrapEdit} objects which specify how the text
+ * should be edited to obtain the wrapped text. Offsets of later
+ * edits are already adjusted for the fact that wrapping a line may
+ * shift the text backwards. So the list can just be iterated and
+ * each edit applied in order.
+ */
+ public static List<WrapEdit> calculateWrapEdits(final String text, final int maxLineLength, final String lineDelimiter) {
+ List<WrapEdit> wrapEdits = new LinkedList<WrapEdit>();
+
+ int offset = 0;
+ int lineDelimiterLength = lineDelimiter.length();
+
+ String[] chunks = text.split(lineDelimiter, -1);
+ for (int chunkIndex = 0; chunkIndex < chunks.length; chunkIndex++) {
+ String chunk = chunks[chunkIndex];
+
+ String[] words = chunk.split(" ", -1); //$NON-NLS-1$
+ int lineLength = 0;
+
+ for (int wordIndex = 0; wordIndex < words.length; wordIndex++) {
+ String word = words[wordIndex];
+
+ int wordLength = word.length();
+ int newLineLength = lineLength + wordLength + 1 /* the space */;
+ if (newLineLength > maxLineLength) {
+ /* don't break before a single long word */
+ if (lineLength != 0) {
+ wrapEdits.add(new WrapEdit(offset, 1));
+ /* adjust for the shifting of text after the edit is applied */
+ offset += lineDelimiterLength;
+ }
+ lineLength = 0;
+ } else if (wordIndex != 0) {
+ lineLength += 1;
+ offset += 1;
+ }
+ offset += wordLength;
+ lineLength += wordLength;
+ }
+
+ if (chunkIndex != chunks.length - 1) {
+ offset += lineDelimiterLength;
+ }
+ }
+
+ return wrapEdits;
+ }
+
+ /**
+ * Edit for replacing a space with a line delimiter to wrap a long line.
+ */
+ public static class WrapEdit {
+ private int start;
+ private int length;
+
+ /**
+ * @param start see {@link #getStart()}
+ * @param length see {@link #getLength()}
+ */
+ public WrapEdit(int start, int length) {
+ this.start = start;
+ this.length = length;
+ }
+
+ /**
+ * @return character offset of where the edit should be applied on the
+ * text
+ */
+ public int getStart() {
+ return start;
+ }
+
+ /**
+ * @return number of characters which should be replaced by the line
+ * delimiter
+ */
+ public int getLength() {
+ return length;
+ }
+ }
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/CommitDialogPreferencePage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/CommitDialogPreferencePage.java
new file mode 100644
index 0000000..8c85546
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/CommitDialogPreferencePage.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Robin Stocker <robin@nibor.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.preferences;
+
+import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.ui.UIText;
+import org.eclipse.jface.preference.BooleanFieldEditor;
+import org.eclipse.jface.preference.FieldEditorPreferencePage;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+
+/** Preferences for commit dialog. */
+public class CommitDialogPreferencePage extends FieldEditorPreferencePage
+ implements IWorkbenchPreferencePage {
+
+ /** */
+ public CommitDialogPreferencePage() {
+ super(GRID);
+ setTitle(UIText.CommitDialogPreferencePage_title);
+ }
+
+ public void init(IWorkbench workbench) {
+ // Nothing to do
+ }
+
+ @Override
+ protected IPreferenceStore doGetPreferenceStore() {
+ return Activator.getDefault().getPreferenceStore();
+ }
+
+ @Override
+ protected void createFieldEditors() {
+ BooleanFieldEditor hardWrap = new BooleanFieldEditor(
+ UIPreferences.COMMIT_DIALOG_HARD_WRAP_MESSAGE,
+ UIText.CommitDialogPreferencePage_hardWrapMessage,
+ getFieldEditorParent());
+ hardWrap.getDescriptionControl(getFieldEditorParent()).setToolTipText(UIText.CommitDialogPreferencePage_hardWrapMessageTooltip);
+ addField(hardWrap);
+ }
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties
index 8cecdb5..8ad3a63 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties
@@ -455,6 +455,7 @@ CommitDialog_StatusUnknown=Unknown
CommitDialog_StatusUntracked=Untracked
CommitDialog_AddChangeIdLabel=Compute Change-Id for Gerrit Code Review
CommitDialog_AddChangeIdTooltip=Inserts the final id when you press Commit
+CommitDialog_ConfigureLink=<a>Configure Preferences...</a>
ConfigureRemoteWizard_WizardTitle_Change=Change remote configuration {0}
ConfigureRemoteWizard_WizardTitle_New=Create a new remote configuration
@@ -598,6 +599,10 @@ RefreshPreferencePage_title=Git Detected Workspace Refresh
RefreshPreferencesPage_RefreshOnlyWhenActive=Refresh only when workbench is &active
RefreshPreferencesPage_RefreshWhenIndexChange=Refresh resources when &index changes
+CommitDialogPreferencePage_title=Commit Dialog
+CommitDialogPreferencePage_hardWrapMessage=Hard-wrap commit message
+CommitDialogPreferencePage_hardWrapMessageTooltip=Wrap text in commit message editor while typing
+
BranchAction_branchFailed=Branch failed
BranchAction_cannotCheckout=Cannot checkout now
BranchAction_checkingOut=Checking out {0}