Bug 268608 - find/replace action disabled on first opening of console

Whenever a new console page is opened in the Console View, a
FindReplaceAction is registered for this console page. The target of
this action is set before the new console page is set as active by the
PageBookView. This results in either a disabled find/edit action, if
there was no previous console page, or an action which targets the
previously active console page. I.e. the user either cannot search in
the new console page, or searches in an old one. This is also true when
switching between consoles, or when closing the Console View and
re-opening it.

Two points are important here. First, global actions of TextConsolePage
pages are only updated on creation of the action, or if the selection in
the console's text widget changes. And second, PageBookView.showPageRec
will set the current page only after the SWT control of the new page is
created (i.e. only after the new actions are updated). Therefore the
target of the global find/replace action is updated only when a new
console page is created, and its updated with the wrong current page.

This change ensures that the FindReplaceAction has the correct target
page and its enabled state is correct, both when switching pages and
when opening new ones. Namely, the selection of a TestConsolePage is
"reset" after the new page is created and shown.

Change-Id: I22c368acce902d12f83274c6df12e013fb7afaa3
Signed-off-by: Simeon Andreev <simeon.danailov.andreev@gmail.com>
diff --git a/org.eclipse.debug.tests/src/org/eclipse/debug/tests/console/ConsoleTests.java b/org.eclipse.debug.tests/src/org/eclipse/debug/tests/console/ConsoleTests.java
index 0a84135..607f70e 100644
--- a/org.eclipse.debug.tests/src/org/eclipse/debug/tests/console/ConsoleTests.java
+++ b/org.eclipse.debug.tests/src/org/eclipse/debug/tests/console/ConsoleTests.java
@@ -14,14 +14,22 @@
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
 
-import org.eclipse.jface.text.IDocument;
-
-import org.eclipse.ui.console.IConsoleConstants;
-import org.eclipse.ui.console.IOConsoleOutputStream;
-import org.eclipse.ui.console.MessageConsole;
-
+import org.eclipse.core.commands.Command;
 import org.eclipse.debug.tests.AbstractDebugTest;
 import org.eclipse.debug.tests.TestUtil;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchCommandConstants;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.commands.ICommandService;
+import org.eclipse.ui.console.ConsolePlugin;
+import org.eclipse.ui.console.IConsole;
+import org.eclipse.ui.console.IConsoleConstants;
+import org.eclipse.ui.console.IConsoleManager;
+import org.eclipse.ui.console.IOConsole;
+import org.eclipse.ui.console.IOConsoleOutputStream;
+import org.eclipse.ui.console.MessageConsole;
 
 import junit.framework.TestCase;
 
@@ -146,4 +154,34 @@
 		}
 	}
 
+	/**
+	 * Validate that we can use find and replace after opening a console in the
+	 * Console View.
+	 *
+	 * @see <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=268608">bug
+	 *      268608</a>
+	 */
+	public void testFindReplaceIsEnabledOnConsoleOpen() throws Exception {
+		IWorkbenchPage activePage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+		IViewPart consoleView = activePage.showView(IConsoleConstants.ID_CONSOLE_VIEW);
+
+		IOConsole console = new IOConsole("Test Console 7", IConsoleConstants.MESSAGE_CONSOLE_TYPE, null, true); //$NON-NLS-1$
+		console.getDocument().set("some text"); //$NON-NLS-1$
+
+		IConsoleManager consoleManager = ConsolePlugin.getDefault().getConsoleManager();
+		IConsole[] consoles = { console };
+
+		try {
+			consoleManager.addConsoles(consoles);
+			consoleManager.showConsoleView(console);
+			TestUtil.waitForJobs(getName(), 100, 3000);
+
+			ICommandService commandService = PlatformUI.getWorkbench().getService(ICommandService.class);
+			Command command = commandService.getCommand(IWorkbenchCommandConstants.EDIT_FIND_AND_REPLACE);
+			TestCase.assertTrue("expected FindReplace command to be enabled after opening console", command.isEnabled());
+		} finally {
+			consoleManager.removeConsoles(consoles);
+			activePage.hideView(consoleView);
+		}
+	}
 }
diff --git a/org.eclipse.ui.console/src/org/eclipse/ui/internal/console/ConsoleView.java b/org.eclipse.ui.console/src/org/eclipse/ui/internal/console/ConsoleView.java
index a69f1ed..ab03b3a 100644
--- a/org.eclipse.ui.console/src/org/eclipse/ui/internal/console/ConsoleView.java
+++ b/org.eclipse.ui.console/src/org/eclipse/ui/internal/console/ConsoleView.java
@@ -52,6 +52,8 @@
 import org.eclipse.ui.console.IConsoleManager;
 import org.eclipse.ui.console.IConsolePageParticipant;
 import org.eclipse.ui.console.IConsoleView;
+import org.eclipse.ui.console.TextConsolePage;
+import org.eclipse.ui.console.TextConsoleViewer;
 import org.eclipse.ui.contexts.IContextActivation;
 import org.eclipse.ui.contexts.IContextService;
 import org.eclipse.ui.part.IPage;
@@ -185,6 +187,16 @@
 		if (page instanceof IOConsolePage) {
 			((IOConsolePage) page).setWordWrap(fWordWrap);
 		}
+		/*
+		 * Bug 268608: cannot invoke find/replace after opening console
+		 *
+		 * Global actions of TextConsolePage must be updated here,
+		 * but they are only updated on a selection change.
+		 */
+		if (page instanceof TextConsolePage) {
+			TextConsoleViewer viewer = ((TextConsolePage) page).getViewer();
+			viewer.setSelection(viewer.getSelection());
+		}
 	}
 
 	/**