How do I clear the selection in my Eclipse RCP application?
Basically I would like to clear it on escape key down:
Display display = PlatformUI.createDisplay();
display.addFilter(SWT.KeyDown, new Listener() {
#Override
public void handleEvent(Event event) {
if (event.character == SWT.ESC) {
// if this is escape key, clear selection in the application
}
}
});
I thought I would be able to do something like PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService().clearSelection()/setSelection(IStructuredSelection.EMPTY), but no go.
You need to look up the ISelectionProvider rather than the ISelectionService. That will provide you with a setSelection() method.
You can get the selction provider from the site:
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActivePart().getSite().getSelectionProvider();
or
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor().getSite().getSelectionProvider();
Note that some of those return values could be null so add the appropriate checks.
You can't clear the selection provided by the selection service directly.
The selection the service returns is provided by a 'selection provider' (ISelectionProvider) for the current part.
You can get the selection provider from an IWorkbenchPart with IWorkbenchPart.getSite().getSelectionProvider().
ISelectionProvider has a setSelection method but it often does nothing or throws an exception so you may not be able to clear the selection.
Related
I have a requirement wherein on a single click in the cell, normal editing must be possible and on double clicking in the cell a dialog should open for editing the cell. The two are possible individually. I see a method "boolean supportMultiEdit(IConfigRegistry configRegistry, List configLabels)" but there is no example to show the working. Has anyone used it or can show it's configuration.
Multi edit means it is possible to edit multiple cells at once. This is of course done in an editor, as it makes no sense to perform multi edit inline. You should rather have a look at openInline(IConfigRegistry, List<String>) or even better the EditConfigAttributes#OPEN_IN_DIALOG to solve what you are looking for.
But you are actually seeking for a way to handle opening an editor differently on different UI interactions. So you need to register the corresponding UI bindings. This is already discussed in the NatTable Forum.
And the EditorExample shows quite a lot of possible configuration options available for editing. And almost every editable example shows multi editing capabilities. You simply need to select multiple cells you want to edit and then start typing or pressing F2.
The following code would do the trick with a configuration based on a label that is added in the UI binding action:
public class OpenEditorConfiguration extends AbstractRegistryConfiguration {
#Override
public void configureRegistry(IConfigRegistry configRegistry) {
configRegistry.registerConfigAttribute(
EditConfigAttributes.OPEN_IN_DIALOG,
Boolean.TRUE,
DisplayMode.EDIT,
"open_in_dialog");
}
#Override
public void configureUiBindings(UiBindingRegistry uiBindingRegistry) {
uiBindingRegistry.registerDoubleClickBinding(
new CellEditorMouseEventMatcher(GridRegion.BODY),
new IMouseAction() {
#Override
public void run(NatTable natTable, MouseEvent event) {
int columnPosition = natTable.getColumnPositionByX(event.x);
int rowPosition = natTable.getRowPositionByY(event.y);
ILayerCell cell = natTable.getCellByPosition(columnPosition, rowPosition);
cell.getConfigLabels().add("open_in_dialog");
natTable.doCommand(new EditCellCommand(
natTable,
natTable.getConfigRegistry(),
cell));
}
});
}
}
I have a org.apache.wicket.markup.html.panel.FeedbackPanel in my panelA class. The feedback panel is instantiated in a panelA constructor with one message to display -> feedbackPanel.info("displayFirstTime"). I am navigating to a new page and later to the previous panelA with a command
target.getPage().get(BasePage.CONTENT_PANEL_ID).replaceWith(panelA);
but the message "displayFirstTime" won't be displayed on the feedback panel again.
I have made it with overriding a panel onBeforeRender method
#Override
public void onBeforeRender() {
super.onBeforeRender();
if (again_displayCondition) {
this.info("displayFirstTime");
}
}
but it's not a clean solution.
Is it possible or how to make it, that when moving to a panelA page for the 2nd time the feedback message will be also displayed ?
Wicket uses application.getApplicationSettings().getFeedbackMessageCleanupFilter() to delete the feedback messages at the end of the request cycle.
By default it will delete all already rendered messages.
You can setup a custom cleanup filter that may leave some of the messages, e.g. if they implement some interface. For example:
component.info(new DoNotDeleteMe("The actual message here."));
and your filter will have to check:
#Override
public boolean accept(FeedbackMessage message)
{
if (message.getMessage() instanceOf DoNotDeleteMe) {
return false;
}
return message.isRendered();
}
Make sure you implement DoNotDeleteMe#toString() so that it renders properly. Or you will have to use a custom FeedbackPanel too.
DoNotDeleteMe must implement java.io.Serializable!
For an RCP E4 Text Editor application implemented with a StyledText/SourceViewer it is necessary receive the status of the inset key.
Once received the state (insert, smart-insert), the application shall modify the cursor icon and notify other parts the INSERT state (i.e. notify to the status bar control like in a normal plain text editor behavior).
SWT.INSERT only listens for the key to be pressed, but nothing if the StyledText is in INSERT MODE.
styledText.addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e){
if(e.keyCode == SWT.INSERT){
System.out.println("INSERT KEY PRESSED!!!");
}
}
};
I have avoided to extend
org.eclipse.ui.texteditor.AbstractTextEditor
and use the method
getInsertMode()
since the application is intended to be pure E4 text editor.
Any hint?
Thanks in advance
First off you need to tell the StyledText not to do the default action when it sees the Insert key:
textWidget.setKeyBinding(SWT.INSERT, SWT.NULL);
Next you need to define a Command, Handler and Key Binding in the context for the editor to deal with the Insert key.
The Handler for the insert command can update the status display and shoyld then tell the StyledText to update the overwrite mode:
textWidget.invokeAction(ST.TOGGLE_OVERWRITE);
Also note that Mac keyboards don't have an Insert key!
Since I found some difficulties to deal with the INSERT_KEY within a sourceviewer control for E4 RCP text editor, I will write extra details to gregg449's answer (great help from him as everytime!).
Following the above answer, I have created Binding Context, Binding Table, Command, Handler and added the Binding Context to the required Part (the part implementing the SourceViewer).
The next code is for SourceViewer and InserKey Handler:
public class CheckKeyBindingSourceViewer extends ITextEditorPart{
public SourceViewer sv = null;
public StyledText st = null;
#PostConstruct
public void postConstruct(Composite parent) {
sv = new SourceViewer(parent, null, null, true, SWT.MULTI | SWT.V_SCROLL |SWT.H_SCROLL);
IDocument doc = new Document("");
sv.setDocument(doc);
st = sv.getTextWidget();
//tell the StyledText not to do the default action when it sees the Insert key
st.setKeyBinding(SWT.INSERT, SWT.NULL);
}
}
public class InsertKeyHandler {
#Execute
public void execute(#Named(IServiceConstants.ACTIVE_PART) MPart activePart) {
if (activePart.getObject() instanceof ITextEditorPart){
ITextEditorPart theSourceViewer = (ITextEditorPart) activePart.getObject();
theSourceViewer.st.invokeAction(ST.TOGGLE_OVERWRITE);
//TODO
//Change cursor sourcewiewer, notify to Statusbar...
}
}
}
The next figure shows the Application.e4xmi with the Binding Context and Binding Table created.
Note that if you do not add the supplementary tag "type:user" to the Binding Table, the bindings are not working at all.
This is not reflected into vogella's tutorial (http://www.vogella.com/tutorials/EclipseRCP/article.html) neither his book.
The only place I found this information was at stackoverflow question:
eclipse rcp keybindings don't work
I'm using eclipse Mars (4.5.0) for both Linux and Windows, I do not know if for newer verions this 'bug' is solved.
I successfully extended the PyDev editor in Eclipse with a side-by-side display, but I can't copy the contents of the extra SourceViewer that I added. I can select some text in the display, but when I press Ctrl+C, it always copies the main PyDev editor's selected text.
I found an article on key bindings in Eclipse editors, but the code there seems incomplete and a bit out-of-date. How can I configure the copy command to copy from whichever SourceViewer has focus?
The reason I want to do this is that I've written a tool for live coding in Python, and it would be much easier for users to submit bug reports if they could just copy the display and paste it into the bug description.
David Green's article was a good start, but it took a bit of digging to make it all work. I published a full example project on GitHub, and I'll post a couple of snippets here.
The TextViewerSupport class wires up a new action handler for each command you want to delegate to the extra text viewer. If you have multiple text viewers, just instantiate a TextViewerSupport object for each of them. It wires up everything in its constructor.
public TextViewerSupport(TextViewer textViewer) {
this.textViewer = textViewer;
StyledText textWidget = textViewer.getTextWidget();
textWidget.addFocusListener(this);
textWidget.addDisposeListener(this);
IWorkbenchWindow window = PlatformUI.getWorkbench()
.getActiveWorkbenchWindow();
handlerService = (IHandlerService) window
.getService(IHandlerService.class);
if (textViewer.getTextWidget().isFocusControl()) {
activateContext();
}
}
The activateContext() method has a list of all the commands you want to delegate, and registers a new handler for each one. This was one of the changes from David's article; his ITextEditorActionDefinitionIds has been deprecated and replaced with IWorkbenchCommandConstants.
protected void activateContext() {
if (handlerActivations.isEmpty()) {
activateHandler(ITextOperationTarget.COPY,
IWorkbenchCommandConstants.EDIT_COPY);
}
}
// Add a single handler.
protected void activateHandler(int operation, String actionDefinitionId) {
StyledText textWidget = textViewer.getTextWidget();
IHandler actionHandler = createActionHandler(operation,
actionDefinitionId);
IHandlerActivation handlerActivation = handlerService.activateHandler(
actionDefinitionId, actionHandler,
new ActiveFocusControlExpression(textWidget));
handlerActivations.add(handlerActivation);
}
// Create a handler that delegates to the text viewer.
private IHandler createActionHandler(final int operation,
String actionDefinitionId) {
Action action = new Action() {
#Override
public void run() {
if (textViewer.canDoOperation(operation)) {
textViewer.doOperation(operation);
}
}
};
action.setActionDefinitionId(actionDefinitionId);
return new ActionHandler(action);
}
The ActiveFocusControlExpression gives the new handler a high enough priority that it will replace the standard handler, and it's almost identical to David's version. However, to get it to compile, I had to add extra dependencies to my plug-in manifest: I imported packages org.eclipse.core.expressions and org.eclipse.ui.texteditor.
I'm using GEF. I have a graphical editor with some "boxes" implemented. Now, I want to add a double-click listener to each box (Rectangle).
I tried to add a listener to the GraphicalViewer but it did not work.
In the GraphicalEditPart of the "box" for which you want to add the listener, you have to override the performRequest(Request req) method. When the framework identifies a double-click on the part's figure, it calls this method with a request that has req.getType()==RequestConstants.REQ_OPEN. You can take over from here.
Complete code to test that his works:
#Override
public void performRequest(Request req) {
if(req.getType() == RequestConstants.REQ_OPEN) {
System.out.println("requested double-click.");
}
}
Hope this does the trick.
I am not familiar with GEF myself, however I found this in documentation:
GraphicalEditor abstraction sets the EditDomain - handler for editing events
EditDomain interface with methods for handling events - e.g. double click
Tutorial on how to implement editing of models through GUI in GEF (using EditDomain)
viewer.getControl().addListener(SWT.MouseDoubleClick, new Listener() {
#Override
public void handleEvent(Event event) {
//write the double click action
});