How do I hide Menu whose children are hidden? - eclipse

I have some menus on Main Menu in Eclipse 4 Application Project whose children are contributed with the help of fragments from different plugins. I have applied permissions on sub-menus according to logged in user.
My problem is even after no sub-menu of a menu has the permission and none of them is visible but still menu is visible. I want to hide that menu. Any Suggestions.
Update: My class for model Processor and plugin.xml
public class MenuProcessor {
public MenuProcessor(){}
#Execute
public void execute(#Named("application_luna.menu.contract(fo)") MMenu menu)
{
if(menu.getChildren().isEmpty())
menu.setVisible(false);
}
}
<extension
id="com.swte.approval.ui.fragment"
point="org.eclipse.e4.workbench.model">
<fragment
uri="fragment.e4xmi">
</fragment>
<processor
apply="always"
beforefragment="false"
class="com.swte.approval.ui.MenuProcessor1">
<element
id="application_luna.menu.contract(fo)">
</element>
</processor>
`

You could do this with a processor on the menu.
You declare the processor in the plugin.xml as part of the 'org.eclipse.e4.workbench.model' extension point.
<extension
id="playerFragment"
point="org.eclipse.e4.workbench.model">
... other elmeents
<processor
beforefragment="false"
class="package.MenuProcessor">
<element
id="menu.id">
</element>
</processor>
</extension>
The declaration names the class to run and the model element that it applies to.
The processor code could then inject the named menu and make it invisible if there are no children. Something like (not tested):
public class MenuProcessor
{
#Inject #Named("menu.id")
private MMenu menu;
#Execute
public void execute()
{
if (menu.getChildren().isEmpty())
menu.setVisible(false);
}
Note: you must inject the menu element as a field in the class, specifying it as a parameter on the execute method will not work. This is because the element is only available for injection when the class is constructed.

Related

Eclipse hide action or actionset in Navigate menu

I am extending an extension point org.eclipse.ui.actionSets where I am creating element actionSet which contains action element inside. This asctionset is placed inside Navigate menu of eclipse For example:
<actionSet
label="%CNavigationActionSet.label"
description="%CNavigationActionSet.description"
visible="false"
id="xxx.ui.NavigationActionSet">
<action
class="xxx.opentype.OpenTypeAction"
definitionId="xxx.navigate.opentype"
helpContextId="xxxui.open_type_action"
icon="icons/xxx.gif"
id="xxx.ui.actions.OpenType"
label="Open Element"
menubarPath="navigate/open.ext2"
toolbarPath="org.eclipse.search.searchActionSet/Search"
tooltip="%OpenTypeAction.tooltip">
</action>
</actionSet>
Now I want to hide this action when certain conditions are met in Eclipse. Is there a way to hide (set visibility to false etc.) of this action in navigate menu?
Right now best what I figured out is to disable action when conditions are met, but this is not enough:
public class OpenTypeAction implements IWorkbenchWindowActionDelegate {
//... some code
#Override
public void selectionChanged(IAction action, ISelection selection) {
action.setEnabled(!areConditionsMet());
}
//... some code
}
/Edit: Solution for me would be also to hide whole actionSet instead of action, is that possible?
/Edit2: To clarify what my conditions are - my editor can contain files with multiple file extensions, I want to show this action only for files which end with certain file extension.

How to create custom image decorator in java file using eclipse plugin

I would like to use some decorators in my Eclipse plugin. I have created a plugin where I created my own editor for my own .test file. If the user edits .test file and saves it. The file must show some decorations not only the .test file but also the project must show the decorator. I am stuck with this problem I can't find any good tutorial to create decorators.
I Have seen some of the websites like https://www.eclipse.org/articles/Article-Decorators/decorators.html but I couldn't get the exact point.
Will some one please tell me how to create custom decorator for my eclipse plugin.
A ILightweightLabelDecorator is the most common type of decorator
Declare this in your plugin.xml with something like this:
<extension point="org.eclipse.ui.decorators">
<decorator
id="my.decorator.id"
class="my.decorator.Decorator"
label="My Decorator"
state="true"
lightweight="true"
adaptable="true">
<enablement>
<objectClass name="org.eclipse.core.resources.IResource"/>
</enablement>
</decorator>
</extension>
You will have to adjust the enablement to suit what you want.
Your decorator class would be something like:
public class Decorator extends BaseLabelDecorator implements ILightweightLabelDecorator
{
#Override
public void decorate(final Object element, final IDecoration decoration)
{
// TODO call decoration methods to add overlay images or prefix / suffix text
}
}

Update property view on click of project explorer, eclipse plugin

I have created a custom project in project explorer. Whenever I click on custom project folder currently it shows default property sheet but I want to customize this property sheet.
I have gone through the tabbed property example but I am not able customize it.
Please can anyone provide me some sample examples or code for same.
Thanks.
how to connect that property view to an editor or project explorer
model classes for you custom project and its folders should implement IAdaptable interface and return an object implementing IPropertySource that describes given element. it will be passed to properties view automatically when you click on the element.
alternativelly, you can avoid implementing IAdaptable and create an IAdapterFactory that converts an instance of you project/folder element into corresponding IPropertySoure but then you have to make Eclipse framework aware of your IAdapterFactory implementation.
public class MyProjectAdapterFactory implements IAdapterFactory {
#Override
public Object getAdapter(Object adaptableObject, Class adapterType) {
if (adapterType== IPropertySource.class && adaptableObject instanceof MyProject){
return new MyProjectPropertySource((MyProject) adaptableObject);
}
return null;
}
#Override
public Class[] getAdapterList() {
return new Class[] { IPropertySource.class };
}
}
register it in you plugin.xml file:
<extension point="org.eclipse.core.runtime.adapters">
<factory adaptableType="my.example.MyProject" class="my.example.MyProjectAdapterFactory">
<adapter type="org.eclipse.ui.views.properties.IPropertySource"/>
</factory>
</extension>
look at the full tutorial: http://www.vogella.de/articles/EclipsePlugIn/article.html

Eclipse RCP: how to get Show View menu instead of a dialog

I've added to my perspective's org.eclipse.ui.menus
<command
commandId="org.eclipse.ui.views.showView"
style="pulldown">
</command>
This adds Show View item to main menu, but this item is not a menu (as in the Eclipse Window menu). Instead pressing it shows a dialog where I can select a view. How do I get a menu instead?
You have to create ContributionItem class like below:
public class MyShowViewContributionItem extends org.eclipse.ui.internal.ShowViewMenu {
public MyShowViewContributionItem() {
this("om.myplugin.myShowViewId");
}
public MyShowViewContributionItem(String id) {
super(org.eclipse.ui.PlatformUI.getWorkbench().getActiveWorkbenchWindow(), id);
}
}
then in your plugin.xml org.eclipse.ui.menus extension:
<menu
label="My Show View">
<dynamic
class="com.myplugin.MyShowViewContributionItem"
id="com.myplugin.myShowViewId">
</dynamic>
</menu>
Cheers,
Max
Just to share on my recent experiment in trying to do the same thing, what Max suggested in his answer will work but leaves you using internal code (resulting in a 'Discouraged Access' warning).
Another approach is to build the menu through your applications action bar advisor. Although, this approach will leave you to having to write code (oppose to use providing menu contributions in the plugin XML definition). Consider the following example:
public class ApplicationActionBarAdvisor extends ActionBarAdvisor
{
private IContributionItem contributionOpenPerspective;
private IContributionItem contributionShowView;
...
protected void makeActions(IWorkbenchWindow window)
{
...
contributionOpenPerspective = ContributionItemFactory.
PERSPECTIVES_SHORTLIST.create(window);
contributionShowView = ContributionItemFactory.
VIEWS_SHORTLIST.create(window);
...
}
protected void fillMenuBar(IMenuManager menuBar)
{
...
MenuManager windowMenu = new MenuManager("&Window",
IWorkbenchActionConstants.M_WINDOW);
menuBar.add(windowMenu);
MenuManager openPerspectiveMenu = new MenuManager("&Open Perspective");
openPerspectiveMenu.add(perspectivesContribution);
windowMenu.add(openPerspectiveMenu);
MenuManager showViewMenu = new MenuManager("Show &View");
showViewMenu.add(viewsContribution);
windowMenu.add(showViewMenu);
...
}
}
A possible downside to this approach is with the interaction between menus created in the advisor and menus created by menu contributions. Since advisor menu items are created before menu contributions, you are left to deal with adding more sorting logic in your menu contributions. This might be fine for most people, however, you lose the 'feel' of a centralized menu structure from org.eclipse.ui.menus (even if the feeling is an illusion when other plugins come into play with their own menu contributions).
I've also included the building of a perspective menu as well; completely option, but I added it if anyone was attempting to perform the same menu building with perspectives.

Eclipse RCP menus & actions: Configure or code?

This is a general question but my current problem revolves around menu handling.
In a normal plugin with contributes menu actions you would configure ActionSets etc in the plugin.xml configuration. This is obviously sensible.
I am working on a RCP application (actually RAP) and I'm wondering if it's worth the effort to configure everything via plugin.xml. My plugin does not have to interact with an other unknown plugins so, theoretically, I have control. I can add menus and actions programmatically.
I have been trying to configure a menu which contains a submenu. I have tried defining ActionSets and linking one inside the other but without success. Some items need to be disabled depending on the user role.
I figure I could have coded the whole lot in a few minutes but I'm not sure if that fits with the eclipse 'ethos'.
What opinions are out there? The application will get fairly big so I'd like to get the approach right from the start. Perhaps someone can point me at an example for configuring a nested menu :-)
My opinion is that the plugin.xml implementation is the way to go.
My main two reasons for using this method:
It's really easy to reconfigure and reorganize the menus and buttons without writing java code.
Very clear hierarchical visualization of the menu trees.
Here is a code snippet that implements menus and submenus. In this example, they are added to the main menu.
You can paste this into your plugin.xml:
<extension
name="Main Menu Contributions"
point="org.eclipse.ui.menus">
<menuContribution
allPopups="false"
locationURI="menu:org.eclipse.ui.main.menu">
<menu
id="fileMenu"
label="File">
<command
commandId="org.eclipse.ui.file.exit"
label="Exit"
style="push">
</command>
</menu>
<menu
label="Edit">
<command
commandId="org.eclipse.ui.edit.selectAll"
label="Select All"
style="push">
</command>
<menu
label="Submenu">
<command
commandId="org.eclipse.ui.edit.selectAll"
label="Select All Submenu"
style="push">
</command>
<command
commandId="org.eclipse.ui.edit.delete"
label="Delete submenu"
style="push">
</command>
</menu>
</menu>
</menuContribution>
</extension>
For activating/deactivating a menu, you have to use Core Expressions to enable/disable command handlers. If a command doesn't have any active handlers attached, it will be disabled. So, the menu item that calls that command will also be disabled.
The following code snippets show how to create a button on the toolbar of a view and have it be enabled/disabled depending of a variable's value. Bare in mind that you will have to change some things in this code to make it work. Most of the changes are for reference names and class implementation.
Create the button in the toolbar (plugin.xml):
<extension
name="View Toolbar Contributions"
point="org.eclipse.ui.menus">
<menuContribution
allPopups="false"
locationURI="toolbar:myapp.views.MyView">
<command
commandId="myapp.commands.PauseSound"
icon=""
label="Pause Playback Sound"
style="push"
tooltip="Pause">
</command>
</menuContribution>
</extension>
Create the command (plugin.xml):
<extension
id="myapp.commands.PauseSound"
name="Pause sound command"
point="org.eclipse.ui.commands">
<command
id="myapp.commands.PauseSound"
name="Pause Sound">
</command>
</extension>
Create the command handler (plugin.xml):
<extension
point="org.eclipse.ui.handlers">
<handler
commandId="myapp.commands.PauseSound">
<activeWhen>
<with
variable="myapp.commands.sourceprovider.active">
<or>
<equals
value="PLAYING">
</equals>
<equals
value="PAUSED">
</equals>
</or>
</with>
</activeWhen>
<class
class="myapp.rcp.commands.toolbar.PausePlayback">
</class>
</handler>
</extension>
Create the state variable for the command (plugin.xml):
<extension
point="org.eclipse.ui.services">
<sourceProvider
provider="myapp.commands.sourceprovider.CommandState">
<variable
name="myapp.commands.sourceprovider.active"
priorityLevel="workbench">
</variable>
</sourceProvider>
</extension>
Implement the class that changes the variable's state:
public class CommandState extends AbstractSourceProvider {
public final static String STATE = "myapp.commands.sourceprovider.active";
public final static String STOPPED = "STOPPED";
public final static String PLAYING = "PLAYING";
public final static String PAUSED = "PAUSED";
public final static String NOT_LOADED = "NOT_LOADED";
enum State {
NOT_LOADED, PLAYING, PAUSED, STOPPED
};
private State curState = State.NOT_LOADED;
#Override
public void dispose() {
}
#Override
public String[] getProvidedSourceNames() {
return new String[] { STATE };
}
// You cannot return NULL
#SuppressWarnings("unchecked")
#Override
public Map getCurrentState() {
Map map = new HashMap(1);
if (curState == State.PLAYING)
map.put(STATE, PLAYING);
else if (curState == State.STOPPED)
map.put(STATE, STOPPED);
else if (curState == State.PAUSED)
map.put(STATE, PAUSED);
return map;
}
public void setPlaying() {
fireSourceChanged(ISources.WORKBENCH, STATE, PLAYING);
}
public void setPaused() {
fireSourceChanged(ISources.WORKBENCH, STATE, PAUSED);
}
public void setStopped() {
fireSourceChanged(ISources.WORKBENCH, STATE, STOPPED);
}
public void setNotLoaded() {
fireSourceChanged(ISources.WORKBENCH, STATE, NOT_LOADED);
}
}
More details on how to implement these features can be found at these locations:
Eclipse Commands Tutorial
Limiting Visibility of Commands
For Eclipse there are two different ways to contributing to the Workbench: Actions and Commands.
I definitely recommend the Commands as the newer and more advanced than Actions.
The drawbacks of Actions as specified here (1):
The UI and handling are always tied. There is no way you can separate each other
While Actions can be contributed to different parts of the workbench (popup menu/tool bar), all of them were different extension points and so you end up duplicating the XML in multiple places. The worst of it is that not all the extension points expect the same configuration.
Specifying Actions in multiple places is a maintenance nightmare. If you have to change the icon of an action, you need to change in all the places.
Another issue with duplicating Actions in plugin.xml is that multiple instance of the same Actions will be created in the memory
(1) Actions vs Commands
If you are writing the RCP application, the good practice is to create the place holders in your ActionBarAdvisor. While that would define the basic structure of your menus and toolbars, you can extend menuContributions and using commands to contribute the actual menu/tool items.
For adding actions in RCP you can also use ApplicationActinBarAcvisor.It is more easy than the above mentioned solution
In this u just have to first declare the action as an object of IWorkbenchAction, then in method "protected void makeActions(IWorkbenchWindow window)" u can register it.
And the last step is to add it into menu.
Following code will help u out.
1.First declare the action :-
private IWorkbenchAction newAction
2.Registering action :-
protected void makeActions(IWorkbenchWindow window) {
newAction = ActionFactory.NEW_WIZARD_DROP_DOWN.create(window);
register(newAction);
newAction.setText("New");
3.Last step is to add the action in menu:-
MenuManager filemenu = new MenuManager("&File", "file");
filemenu.add(newAction);
You can also add the action in toolbar as follows:-
protected void fillCoolBar(ICoolBarManager coolBar) {
IToolBarManager toolbar = new ToolBarManager(coolBar.getStyle());
coolBar.add(toolbar);
toolbar.add(newAction);