Single Line Menu Action in Eclipse RCP Workbench Coolbar - swt

I added a JFace action to the workbench coolbar of an RCP application using a subclass of the ActionBarAdvisor. For some reason the corresponding menu is drawn with what I guess is an extra line. It is causing the whole coolbar including the list of open perspectives to be way too tall:
Anyone know how to make it single-lined? I tried adding SWT.SINGLE style to the Action constructor, but that didn't help. Any help would be appreciated. Thanks.
ActionBarAdvisor.fillCoolBar() implementation:
protected void fillCoolBar(final ICoolBarManager coolBar) {
final IToolBarManager toolbar = new ToolBarManager(coolBar.getStyle());
coolBar.add(new ToolBarContributionItem(toolbar, "main"));
toolbar.add(new Pulldown());
}
Action implementation:
public class Pulldown extends Action {
public Pulldown() {
super("Saved Layouts");
setMenuCreator(menuCreator);
}
...
}

It's not direct the answer of your problem, but I would declare the button as menu extension with dropdown/radio style. Thus you don't have to change the code of the coolbar.Here is a tutorial about toolbar menu contributions.
<extension
point="org.eclipse.ui.menus">
<menuContribution
allPopups="false"
locationURI="toolbar:de.example.com">
<command
commandId="de.abas.erp.wb.base.marker.commands.PullDownCommand"
icon="icons/16x16/layouts.png"
label="Saved Layouts"
style="pulldown">
</command>
</menuContribution>
</extension>

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 do I hide Menu whose children are hidden?

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.

Eclipse RCP: Can I add a toolbar to an Editor Part?

I have succesfully managed to add view-specific toolbars to my RCP application by adding the following block to the org.eclipse.ui.menus extension point:
<menuContribution
allPopups="false"
locationURI="toolbar:my.package.path.views.ClassOfMyView">
<dynamic
class="my.package.path.toolbars.ViewToolBar"
id="MyViewToolbar">
</dynamic>
</menuContribution>
However, trying to do the same with my editorpart does not seem to work:
<menuContribution
allPopups="false"
locationURI="toolbar:my.package.path.views.ClassOfMyEditorPart">
<dynamic
class="my.package.path.toolbars.EditorPartToolBar"
id="MyEditorpartToolbar">
</dynamic>
</menuContribution>
Is there something obvious that I am missing, or is this simply not supported in RCP?
Following up on the hint about the Presentation API given by Tonny Madsen, I've come up with a solution to my problem. My solution is based on the following articles:
Eclipse RCP - Hide minimize / maximize buttons for editors and views (showing me how to supply my own presentation factory)
Incompatibilities between Eclipse 3.7 and 4.2 (helping me figure out why my presentation factory wasn't being used)
Custom RCP editor with the view header (helping me figure out how to make sure my presentation factory was being used)
To make my solution work, I ended up with changes in two files and a new class:
In the plugin.xml file, I added the following extension:
<extension point="org.eclipse.ui.presentationFactories">
<factory
name="Extended Presentation Factory"
class="org.eclipse.minicrm.ui.swt.custom.ExtendedPresentationFactory"
id="org.eclipse.minicrm.ui.swt.custom.ExtendedPresentationFactory"
/>
</extension>
This seems to be ignored by Eclipse 4.x, so to cater for those cases, I added the following line to the plugin_customisation.ini file:
org.eclipse.ui/presentationFactoryId = org.eclipse.minicrm.ui.swt.custom.ExtendedPresentationFactory
I then created the corresponding class:
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.ui.internal.presentations.util.TabbedStackPresentation;
import org.eclipse.ui.presentations.IStackPresentationSite;
import org.eclipse.ui.presentations.StackPresentation;
import org.eclipse.ui.presentations.WorkbenchPresentationFactory;
#SuppressWarnings("restriction")
public class ExtendedPresentationFactory extends WorkbenchPresentationFactory {
private ToolBarManager m_toolBarManager = null;
private ToolBar m_toolbar = null;
#Override
public StackPresentation createEditorPresentation(final Composite parent, final IStackPresentationSite site) {
final TabbedStackPresentation presentation = (TabbedStackPresentation) super.createViewPresentation(parent, site);
m_toolbar = new ToolBar(presentation.getTabFolder().getToolbarParent(), 0);
m_toolBarManager = new ToolBarManager(m_toolbar);
m_toolBarManager.add(new MyAction1());
m_toolBarManager.add(new MyAction2());
m_toolBarManager.add(new MyAction3());
m_toolBarManager.update(true);
presentation.getTabFolder().setToolbar(m_toolbar);
return presentation;
}
}
This adds a toolbar with three buttons to my editor area.
I will still need to fiddle with some of the finer points (placement etc), but for a start it satisfies my need for a toolbar in the editor area.
These are some important visual differences between editors and views:
Editors provide additional actions to the top-level menu and the tool bar; views do not*
Views have an independent menu bar and tool bar; editors do not
There are at most one active editor in a perspective; there can be any number of active views
The are at most one view of each “type”; there can be any number of editors*
Editors are all placed in the “editor area”; views are placed in a number of “view stacks”
Some of these differences (marked with * above) can be ironed out using various functionality of the RCP platform:
The interface ISaveblePart can give a view the same life-cycle as an editor.
The menues extension point can add items to the main menu and tool bar when a view is active.
The views extension point can be used to allow multiple views of the same type.
With Eclipse 4, you can also combine editors and views in the same stack or folder.
But adding a menu or tool bar as seen with views require more work! But it can be done using the Presentation API, where most of the visual difference can be ironed out.
One additional comment: It is not toolbar:my.package.path.views.ClassOfMyView but toolbar:id-of-the-view.

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);