Bug 343023 - Clear the initial stack trace console message on the first
edit
The JavaStackTraceConsole shows a simple help message when opened for
the first time. If this message is still shown if user types something
for the first time the message is cleared.
Change-Id: Ia298428293493b95a0e61833857b2662d6a9b338
Signed-off-by: Paul Pazderski <paul-eclipse@ppazderski.de>
diff --git a/org.eclipse.jdt.debug.tests/console tests/org/eclipse/jdt/debug/tests/console/JavaStackTraceConsoleTest.java b/org.eclipse.jdt.debug.tests/console tests/org/eclipse/jdt/debug/tests/console/JavaStackTraceConsoleTest.java
index 466ed03..d11b319 100644
--- a/org.eclipse.jdt.debug.tests/console tests/org/eclipse/jdt/debug/tests/console/JavaStackTraceConsoleTest.java
+++ b/org.eclipse.jdt.debug.tests/console tests/org/eclipse/jdt/debug/tests/console/JavaStackTraceConsoleTest.java
@@ -11,6 +11,7 @@
* Contributors:
* SAP SE - initial API and implementation
* Paul Pazderski - Bug 546900: Tests to check initial console content and content persistence
+ * Paul Pazderski - Bug 343023: Tests for 'clear initial content on first edit'
*******************************************************************************/
package org.eclipse.jdt.debug.tests.console;
@@ -26,17 +27,30 @@
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.debug.tests.AbstractDebugTest;
+import org.eclipse.jdt.debug.tests.TestUtil;
import org.eclipse.jdt.debug.ui.console.JavaStackTraceConsoleFactory;
import org.eclipse.jdt.internal.debug.ui.console.ConsoleMessages;
import org.eclipse.jdt.internal.debug.ui.console.JavaStackTraceConsole;
+import org.eclipse.jdt.internal.debug.ui.console.JavaStackTraceConsolePage;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.BadPositionCategoryException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.Position;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.ST;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IViewReference;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.IConsoleManager;
+import org.eclipse.ui.console.TextConsoleViewer;
import org.eclipse.ui.internal.console.ConsoleHyperlinkPosition;
+import org.eclipse.ui.internal.console.ConsoleView;
/**
* Tests {@link JavaStackTraceConsole}
@@ -171,6 +185,90 @@
assertEquals("Failed to restore previous content.", storedContent, fConsole.getDocument().get());
}
+ /**
+ * Test for Bug 343023. Test if initial content is cleared on first edit and not cleared if it was changed programmatically before.
+ */
+ public void testClearInitialContent() {
+ PlatformUI.getWorkbench().getDisplay().syncExec(() -> {
+ // type at start of initial content
+ TextConsoleViewer viewer = getConsolesViewer();
+ viewer.getTextWidget().invokeAction(ST.TEXT_START);
+ doKeyStroke(viewer.getTextWidget(), 'a');
+ assertEquals("Initial content was not cleared.", "a", fConsole.getDocument().get());
+ doKeyStroke(viewer.getTextWidget(), 'b');
+ assertEquals("Content was cleared again.", "ab", fConsole.getDocument().get());
+ removeConsole(false);
+
+ // type inside initial content
+ initConsole(true);
+ viewer = getConsolesViewer();
+ viewer.getTextWidget().setCaretOffset(5);
+ doKeyStroke(viewer.getTextWidget(), 'a');
+ assertEquals("Initial content was not cleared.", "a", fConsole.getDocument().get());
+ doKeyStroke(viewer.getTextWidget(), 'b');
+ assertEquals("Content was cleared again.", "ab", fConsole.getDocument().get());
+ removeConsole(false);
+
+ // type at end of initial content
+ initConsole(true);
+ viewer = getConsolesViewer();
+ viewer.getTextWidget().invokeAction(ST.TEXT_END);
+ doKeyStroke(viewer.getTextWidget(), 'a');
+ assertEquals("Initial content was not cleared.", "a", fConsole.getDocument().get());
+ doKeyStroke(viewer.getTextWidget(), 'b');
+ assertEquals("Content was cleared again.", "ab", fConsole.getDocument().get());
+ removeConsole(false);
+
+ // select all initial content
+ initConsole(true);
+ viewer = getConsolesViewer();
+ viewer.getTextWidget().selectAll();
+ doKeyStroke(viewer.getTextWidget(), 'a');
+ assertEquals("Initial content was not cleared.", "a", fConsole.getDocument().get());
+ doKeyStroke(viewer.getTextWidget(), 'b');
+ assertEquals("Content was cleared again.", "ab", fConsole.getDocument().get());
+ removeConsole(false);
+
+ // select part of initial content
+ initConsole(true);
+ viewer = getConsolesViewer();
+ viewer.getTextWidget().setSelection(5, 10);
+ doKeyStroke(viewer.getTextWidget(), 'a');
+ assertEquals("Initial content was not cleared.", "a", fConsole.getDocument().get());
+ doKeyStroke(viewer.getTextWidget(), 'b');
+ assertEquals("Content was cleared again.", "ab", fConsole.getDocument().get());
+ removeConsole(false);
+
+ // paste inside initial content
+ initConsole(true);
+ viewer = getConsolesViewer();
+ viewer.getTextWidget().setCaretOffset(5);
+ viewer.getTextWidget().insert("at foo.bar.Type.method1(IILjava/lang/String;)V(Type.java:1)");
+ assertEquals("Initial content was not cleared.", "at foo.bar.Type.method1(IILjava/lang/String;)V(Type.java:1)", fConsole.getDocument().get());
+ doKeyStroke(viewer.getTextWidget(), 'b');
+ assertTrue("Content was cleared again.", fConsole.getDocument().getLength() > 5);
+ removeConsole(false);
+
+ // user edit after something already modified the content (expect no magic clear)
+ initConsole(true);
+ viewer = getConsolesViewer();
+ String text = "Text set programmatically";
+ viewer.getTextWidget().setText(text);
+ viewer.getTextWidget().invokeAction(ST.TEXT_END);
+ doKeyStroke(viewer.getTextWidget(), '!');
+ assertEquals(text + "!", fConsole.getDocument().get());
+ removeConsole(true); // preserve content this time!
+
+ // check first edit does not clear if console is initialized with custom content
+ initConsole(false);
+ viewer = getConsolesViewer();
+ int lengthBefore = fConsole.getDocument().getLength();
+ doKeyStroke(viewer.getTextWidget(), 'a');
+ assertEquals("Custom content was cleared.", lengthBefore + 1, fConsole.getDocument().getLength());
+ // do not remove last console so tearDown can do something
+ });
+ }
+
private IDocument consoleDocumentWithText(String text) throws InterruptedException {
IDocument document = fConsole.getDocument();
document.set(text);
@@ -223,4 +321,45 @@
public void assertInitialContent() {
assertEquals("Console not loaded with initial content.", ConsoleMessages.JavaStackTraceConsole_0, fConsole.getDocument().get());
}
+
+ /**
+ * Tries to get the viewer of the currently tested console.
+ *
+ * @return the consoles viewer
+ */
+ private TextConsoleViewer getConsolesViewer() {
+ TestUtil.waitForJobs(getName(), 100, DEFAULT_TIMEOUT);
+ IWorkbenchWindow workbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ assertNotNull(workbenchWindow);
+ IWorkbenchPage activePage = workbenchWindow.getActivePage();
+ assertNotNull(activePage);
+ JavaStackTraceConsolePage page = null;
+ for (IViewReference vref : activePage.getViewReferences()) {
+ IViewPart view = vref.getView(false);
+ if (view instanceof ConsoleView) {
+ ConsoleView consoleView = (ConsoleView) view;
+ if (consoleView.getConsole() == fConsole && consoleView.getCurrentPage() instanceof JavaStackTraceConsolePage) {
+ page = (JavaStackTraceConsolePage) consoleView.getCurrentPage();
+ break;
+ }
+ }
+ }
+ assertNotNull(page);
+ return page.getViewer();
+ }
+
+ /**
+ * Simulate user pressing a key.
+ *
+ * @param widget
+ * widget to type in
+ * @param c
+ * character to type
+ */
+ private void doKeyStroke(StyledText widget, char c) {
+ final Event e = new Event();
+ e.character = c;
+ widget.notifyListeners(SWT.KeyDown, e);
+ widget.notifyListeners(SWT.KeyUp, e);
+ }
}
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/console/JavaStackTraceConsole.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/console/JavaStackTraceConsole.java
index aeb5a88..6ab52b4 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/console/JavaStackTraceConsole.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/console/JavaStackTraceConsole.java
@@ -11,6 +11,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Paul Pazderski - Bug 546900: Fix IO handling in JavaStacktraceConsole
+ * Paul Pazderski - Bug 343023: Clear the initial stack trace console message on first edit
*******************************************************************************/
package org.eclipse.jdt.internal.debug.ui.console;
@@ -33,7 +34,9 @@
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
import org.eclipse.jdt.internal.debug.ui.JavaDebugImages;
import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.text.rules.FastPartitioner;
import org.eclipse.jface.text.rules.RuleBasedPartitionScanner;
import org.eclipse.jface.util.IPropertyChangeListener;
@@ -87,6 +90,19 @@
}
}
};
+ /** Memorize if stack trace console is showing the initial "How to use" text at the moment. */
+ boolean showsUsageHint = false;
+ /** Document listener to recognize if initial "How to use" text is changed programmatically. Removes itself after first document change. */
+ private final IDocumentListener documentsFirstChangeListener = new IDocumentListener() {
+ @Override
+ public void documentAboutToBeChanged(DocumentEvent event) {
+ }
+ @Override
+ public void documentChanged(DocumentEvent event) {
+ event.getDocument().removeDocumentListener(documentsFirstChangeListener);
+ showsUsageHint = false;
+ }
+ };
/**
* Constructor
@@ -122,6 +138,8 @@
}
} else {
getDocument().set(ConsoleMessages.JavaStackTraceConsole_0);
+ getDocument().addDocumentListener(documentsFirstChangeListener);
+ showsUsageHint = true;
}
}
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/console/JavaStackTraceConsoleViewer.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/console/JavaStackTraceConsoleViewer.java
index 47a954b..bc24d96 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/console/JavaStackTraceConsoleViewer.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/console/JavaStackTraceConsoleViewer.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2012 IBM Corporation and others.
+ * Copyright (c) 2005, 2019 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -10,20 +10,18 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Paul Pazderski - Bug 343023: Clear the initial stack trace console message on first edit
*******************************************************************************/
package org.eclipse.jdt.internal.debug.ui.console;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.Composite;
-
-import org.eclipse.jface.preference.IPreferenceStore;
-
-import org.eclipse.jface.text.ITextOperationTarget;
-
-import org.eclipse.ui.console.TextConsoleViewer;
-
import org.eclipse.jdt.internal.debug.ui.IJDIPreferencesConstants;
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.DocumentCommand;
+import org.eclipse.jface.text.ITextOperationTarget;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.console.TextConsoleViewer;
/**
* provides the viewer for Java stack trace consoles
@@ -44,7 +42,24 @@
getTextWidget().setOrientation(SWT.LEFT_TO_RIGHT);
IPreferenceStore fPreferenceStore = JDIDebugUIPlugin.getDefault().getPreferenceStore();
- fAutoFormat = fPreferenceStore.getBoolean(IJDIPreferencesConstants.PREF_AUTO_FORMAT_JSTCONSOLE);
+ fAutoFormat = fPreferenceStore.getBoolean(IJDIPreferencesConstants.PREF_AUTO_FORMAT_JSTCONSOLE);
+ }
+
+ /**
+ * Additional to the parents customization this override implements the clearing of the initial stack trace console content on first edit. It
+ * modifies the first event as if the user selected the whole initial content before typing.
+ *
+ * @param command
+ * the document command representing the verify event
+ */
+ @Override
+ protected void customizeDocumentCommand(DocumentCommand command) {
+ if (fConsole.showsUsageHint) {
+ command.offset = 0;
+ command.length = getDocument().getLength();
+ command.caretOffset = command.length;
+ }
+ super.customizeDocumentCommand(command);
}
/**
@@ -54,8 +69,9 @@
public void doOperation(int operation) {
super.doOperation(operation);
- if (fAutoFormat && operation == ITextOperationTarget.PASTE)
+ if (fAutoFormat && operation == ITextOperationTarget.PASTE) {
fConsole.format();
+ }
}
/**