Eclipse JFace :: How to get rid of key binding conflicts while working in a multipage editor - eclipse

I have an editor with multipage in which each page has copy paste delete actions and f3 navigation action. I create context and activate and deactivate the actions
Below is how the plugin.xml looks like :
<extension
point="org.eclipse.ui.bindings">
<key
commandId="com.sap.adt.wda.controller.ui.navigate"
contextId="com.sap.adt.wda.controller.ui.contextTabScope"
schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
sequence="F3">
</key>
</extension>
<extension
point="org.eclipse.ui.contexts">
<context
description="%context_navigateToController_ymsg"
id="com.sap.adt.wda.controller.ui.contextTabScope"
name="%context_navigateToController_yins"
parentId="org.eclipse.ui.contexts.window">
</context>
</extension>
It is done through activation and deactivation of context. Below is the code snippet.
private void activateHandlers() {
IContextService contextService = (IContextService) (PlatformUI.getWorkbench().getService(IContextService.class));
if (contextService != null) {
activation = contextService.activateContext(IControllerConstants.CONTEXT_TAB_ECLIPSE_CONTEXT_ID);
}
IEditorSite site = getEditor().getEditorSite();
IHandlerService service = (IHandlerService) site.getService(IHandlerService.class);
IHandlerActivation navigateHandlerActivation = service.activateHandler(NavigationHandler.COMMAND_ID, new NavigationHandler());
activatedHandlers = new ArrayList<IHandlerActivation>();
activatedHandlers.add(navigateHandlerActivation);
}
public void deactivateHandlers() {
IContextService contextService = (IContextService) (PlatformUI.getWorkbench().getService(IContextService.class));
contextService.deactivateContext(activation);
IHandlerService service = (IHandlerService) getEditor().getEditorSite().getService(IHandlerService.class);
if (activatedHandlers != null) {
service.deactivateHandlers(activatedHandlers);
activatedHandlers = null;
}
}
These two methods are called respectively from the page change to activate the context once the page is active and deactivate when the page is not active.
The problem is that it still conflicts with another opened editor as when I switch between editors, pagechange is not even called!! Please tell me what is the best way to implement this.

Add focus listener on sourceViewer of editor
focusListener = new FocusListener() {
#Override
public void focusLost(FocusEvent e) {
deactivateHandlers();
}
#Override
public void focusGained(FocusEvent arg0) {
activateHandlers();
}
};
sourceViewer.getTextWidget().addFocusListener(focusListener);
On switch of every page the focusLost and focusGained will be called.
Override activateHandlers() and deactivateHandlers() to enable and disable respective handlers for each parts of editor

Related

Eclipse plugin - add mouse listener to an editor everytime its opened

I am developing an Eclipse plugin and I need to store the click location in X and Y axis coordinates.
So far, I am doing this by using the org.eclipse.ui.IStartup interface and using this in the class implementing it:
#Override
public void earlyStartup() {
IWorkbench wb = PlatformUI.getWorkbench();
wb.addWindowListener(generateWindowListener());
}
And the in the given method I do this:
private IWindowListener generateWindowListener()
{
return new IWindowListener() {
private MouseListener clickMouseListener = new ClickMouseListener();
#Override
public void windowOpened(IWorkbenchWindow window) {
//Nothing
}
#Override
public void windowDeactivated(IWorkbenchWindow window) {
System.out.println("deactivaed");
IWorkbenchPage activePage = window.getActivePage();
activePage.getActiveEditor().getAdapter(org.eclipse.swt.widgets.Control.class).addMouseListener(clickMouseListener);
}
#Override
public void windowClosed(IWorkbenchWindow window) {
//Nothing
}
#Override
public void windowActivated(IWorkbenchWindow window) {
System.out.println("activated");
IWorkbenchPage activePage = window.getActivePage();
activePage.getActiveEditor().getAdapter(org.eclipse.swt.widgets.Control.class).addMouseListener(clickMouseListener);
}
};
}
So I basically register a listener to the general workbench with the intent to register a new MouseListener - where I save the coordinates - on newly opened editors.
This, however, works only if the entire eclipse window is minimized/maximized, as this listener is bound to the main window. If a new editor is opened, nothing happens (as it probably should work).
I would like to register new MouseListeners everytime a new editor is opened/activated/clicked on - so I can register them to the editor right when a new editor is opened. How can I subscribe/listen to any events related to editors (mostly activated/open new editor) so I can then subscribe a MouseListener to the editor and get current X and Y axis of the mouse-clicks?
Thank for any suggestions.
Use an IPartListener to listen to part events in a workbench window:
IPartService partService = window.getPartService();
partService.addPartListener(listener);
This will tell you about all editors (and views) being opened, closed, activiated, ....
In the early startup method the workbench window is not yet available. Use Display.asyncExec to delay running your code until the UI initialization is complete:
Display.getDefault().asyncExec(new Runnable() {
#Override
public void run() {
IPartService service = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getPartService();
......
}
});

How to enable and disable items in the menu contribution?

I am trying to use a property tester on a menu contribution that I have done for my eclipse plugin.
Basically I added a new menu in the main menu bar (by extending menu:org.eclipse.ui.main.menu and adding a menu). I then added my commands in there with the correct handlers.
Everything works as expected.
My only problem is that I am not able to decide when to have them active.
I am trying to use the activeWhen for my handlers. i want them to be active when there is certain data on a server.
I tried using a property tester but it does not get called everytime. It only gets called when you select a different view.
What is the correct way of doing this?
EDIT: here is the code I am using
http://pastebin.com/TGtZaBtM
My property tester runs because I print out stuff when it does.
The only problem is that it does not run every time the menu is opened.
I would like it to run every time so that I can check if a user is logged in or not.
I'm probably answering late...
Anyway to do that, I always define a sourceProvider and some variable using the org.eclipse.ui.services extension point:
As example for a pause action somewhere in a toolbar, here is the piece of code of the source provider and its definition in the plugins.xml:
<extension
point="org.eclipse.ui.services">
<sourceProvider
provider="DataCollectionSourceProvider">
<variable
name="Pause"
priorityLevel="workbench">
</variable>
</sourceProvider>
</extension>
source provider:
public class DataCollectionSourceProvider extends AbstractSourceProvider {
public final static String ID = "DataCollectionSourceProvider";
public final static String ID_PAUSED = "Pause";
public final static String VAL_TRUE = "TRUE";
public final static String VAL_FALSE = "FALSE";
/**
* #return the instance of this source provider in this workbench
*/
public static DataCollectionSourceProvider getInstance() {
ISourceProviderService sourceProviderService = ISourceProviderService)PlatformUI.getWorkbench().getService(ISourceProviderService.class);
DataCollectionSourceProvider dcProvider = (DataCollectionSourceProvider)sourceProviderService.getSourceProvider(ID);
return dcProvider;
}
private boolean paused = false;
public DataCollectionSourceProvider() {
// do nothing
}
#Override
public Map<?, ?> getCurrentState() {
String value = null;
Map<String, String> map = new HashMap<String, String>(2);
// fake variable (my id)
map.put(ID, VAL_TRUE);
// paused state
value = paused ? VAL_TRUE : VAL_FALSE;
map.put(ID_PAUSED, value);
return map;
}
#Override
public String[] getProvidedSourceNames() {
return new String[] { ID, ID_PAUSED };
}
public void setPaused(boolean paused) {
this.paused = paused;
String value = paused ? VAL_TRUE : VAL_FALSE;
fireSourceChanged(ISources.WORKBENCH, ID_PAUSED, value);
}
}
Then on your org.eclipse.ui.handlers contribution, add the enableWhen by using the variable from its defined id:
<extension
point="org.eclipse.ui.handlers">
<handler
commandId="__your_command_id__">
<class
class="__your_handler_class__">
</class>
<enabledWhen>
<with
variable="Pause">
<equals
value="FALSE">
</equals>
</with>
</enabledWhen>
</handler>
</extension>
At last, if you want to update the handler/action state, you just have to call the following piece of code somewhere in your code
DataCollectionSourceProvider.getInstance().setPause(...)
At a quick glance: You are using 'activeWhen' in your handler. You can probably try using 'enabledWhen' in the XML
You can also look into overriding isEnabled() in your Handler. This will work, when your plugin is activated. Look into the docs for more information.

Enable/Disbale eclispe rcp editor via menu when clicking on a TreeViewer element

In my eclipse RCP application I have a TreeViewer from where I can select different editors, for drawing elements, which show up after double clicking. In my top menu I have an option that allows to enable/disbale the drawing. The action for the editors looks like the following:
public class EnableEditorAction implements IEditorActionDelegate {
IEditor hallEditor = null;
#Override
public void run(IAction action) {
if (hallEditor != null){
hallEditor.setMachineHallEditMode(true);
}
}
#Override
public void setActiveEditor(IAction action, IEditorPart targetEditor) {
// check for enabled
boolean bEnabled = false;
if (targetEditor != null && targetEditor instanceof IMachineHallEditor) {
hallEditor = (IMachineHallEditor) targetEditor;
bEnabled = !hallEditor.isMachineHallEditingMode();
}
action.setEnabled(bEnabled);
}
#Override
public void selectionChanged(IAction action, ISelection selection) {
if (hallEditor != null) {
action.setEnabled(!hallEditor.isMachineHallEditingMode());
}
}
}
The problem I have is that the menu option is only enabled when clicking inside an editor. What i want is to enable the menu option also after clicking on one of the editors in the TreeViewer to the left.
How would I do that?
First, you don't need to check if targetEditor is null, since the action is already hooked to the editor via plugin.xml.
Second, I can see that you have an API isMachineHallEditingMode(). This should tell you if the left tree is selected, and the action should work properly.
It's important to set your action to always enabled in the plugin.xml. The Enables for: parameter should be empty, because enablement handling is done in your selectionChanged.
public class EnableEditorAction implements IEditorActionDelegate {
IEditor hallEditor;
#Override
public void run(IAction action) {
hallEditor.setMachineHallEditMode(true);
}
#Override
public void setActiveEditor(IAction action, IEditorPart targetEditor) {
hallEditor = (IMachineHallEditor) targetEditor;
}
#Override
public void selectionChanged(IAction action, ISelection selection) {
action.setEnabled(!hallEditor.isMachineHallEditingMode());
}
}

DragSourceListener never called while dragging and dropping file inside eclipse project explorer

I am working on eclipse plugin that will allow a java bean to be dragged onto jsp file then on the drop event some code generators will be called.
I'm attempting to use the extension point "org.eclipse.ui.dropActions" but drag and drop listeners never get called .Is there any way to attach drag and drop listener to IFile object.
Am I on the right track with the DropActionDelegate?
Code:
DragListener
class DragListener implements DragSourceListener {
#Override
public void dragFinished(DragSourceEvent event) {
System.out.println("Finish");
}
#Override
public void dragSetData(DragSourceEvent event) {
PluginTransferData p;
p = new PluginTransferData (
"dream_action", // must be id of registered drop action
"some_data".getBytes() // may be of arbitrary type
);
event.data = p;
}
#Override
public void dragStart(DragSourceEvent event) {
// TODO Auto-generated method stub
System.out.println("Start");
}
}
DropActionDelegate
class DropActionDelegate implements IDropActionDelegate {
#Override
public boolean run(Object source, Object target) {
String Data= (String) target;
return true;
}
}
Plugin.xml
<extension point="org.eclipse.ui.dropActions">
<action
id="dream_action"
class="newdreamfileplugin.wizards.DropActionDelegate">
</action>
</extension>
Thanks.
Solved it.Finally i created my own navigator using org.eclipse.ui.navigator.navigatorContent extension which have a property dropAssistant.

How can I hook into Eclipse editor events in my own plugin?

I don't want to create my own editor but I would like to extend existing editors by hooking into their editing events.
For example whenever the text changes in a text or xml editor I would get a callback and be able to react to the change.
Does such a suitable extension point exist?
You can do this by accessing the IEditorPart, use getAdapter(IDocument.class) and then add a listener to this...
But this is really a hack... ;-)
EDIT: On request, here is a little more code.
public void hookToEditor() {
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
if (page == null) return;
IEditorPart editor = page.getActiveEditor();
if (editor == null) return;
IDocument doc = (IDocument) editor.getAdapter(IDocument.class);
if (doc == null) return;
doc.addDocumentListener(new IDocumentListener() {
#Override
public void documentChanged(DocumentEvent event) {
// Do something
}
#Override
public void documentAboutToBeChanged(DocumentEvent event) {
// About to do something
}
});
}
Note that
there are many ways to get the page - e.g. via the current site
there are just as many ways to get the editor part - e.g. via a handler
many editors don't have a embedded document - e.g. PDE editors
You can add resource change listener.
IResourceChangeListener listener = new IResourceChangeListener() {
#Override
public void resourceChanged(IResourceChangeEvent arg0) {
System.out.println("Text changed");
}
};
ResourcesPlugin.getWorkspace().addResourceChangeListener(listener);