Source code for this tutorial is available on github as a single zip archive, as a Team Project Set or you can browse the files online.
Preparations
Create a new Plug-in Project called com.codeandme.coreexpressions.samples. Add dependencies to org.eclipse.ui, org.eclipse.core.runtime and com.codeandme.coreexpressions. Set the content of plugin.xml to
<?xml version="1.0" encoding="UTF-8"?> <?eclipse version="3.4"?> <plugin> <extension point="org.eclipse.ui.commands"> <command defaultHandler="com.codeandme.coreexpressions.samples.Login" id="com.codeandme.coreexpressions.commands.login" name="login"> </command> <command defaultHandler="com.codeandme.coreexpressions.samples.Logout" id="com.codeandme.coreexpressions.commands.logout" name="logout"> </command> </extension> </plugin>Add a new class com.codeandme.coreexpressions.samples.Login
package com.codeandme.coreexpressions.samples; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.commands.IHandler; import org.eclipse.ui.ISourceProvider; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.services.ISourceProviderService; import com.codeandme.coreexpressions.ExampleSourceProvider; public class Login extends AbstractHandler implements IHandler { @Override public Object execute(ExecutionEvent event) throws ExecutionException { ISourceProviderService service = (ISourceProviderService) PlatformUI.getWorkbench().getService( ISourceProviderService.class); ISourceProvider provider = service.getSourceProvider(ExampleSourceProvider.CURRENT_USER); if (provider instanceof ExampleSourceProvider) ((ExampleSourceProvider) provider).setCurrentUser("John Doe"); return null; } }and another class com.codeandme.coreexpressions.samples.Logout
package com.codeandme.coreexpressions.samples; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.commands.IHandler; import org.eclipse.ui.ISourceProvider; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.services.ISourceProviderService; import com.codeandme.coreexpressions.ExampleSourceProvider; public class Logout extends AbstractHandler implements IHandler { @Override public Object execute(ExecutionEvent event) throws ExecutionException { ISourceProviderService service = (ISourceProviderService) PlatformUI.getWorkbench().getService( ISourceProviderService.class); ISourceProvider provider = service.getSourceProvider(ExampleSourceProvider.CURRENT_USER); if (provider instanceof ExampleSourceProvider) ((ExampleSourceProvider) provider).setCurrentUser(null); return null; } }We will use these commands in a later step of our tutorial.
The first commands we use will simply bind to the commandId=org.eclipse.ui.file.exit.
Test 1: Enable for a specific view
Our first expression will reveal a toolbar item in the Project Explorer view when the view is active.
<menuContribution allPopups="false" locationURI="toolbar:org.eclipse.ui.navigator.ProjectExplorer"> <command commandId="org.eclipse.ui.file.exit" label="Test1" style="push"> <visibleWhen checkEnabled="false"> <with variable="activePartId"> <equals value="org.eclipse.ui.navigator.ProjectExplorer"> </equals> </with> </visibleWhen> </command> </menuContribution>We need to set checkEnabled on the visibleWhen element to false, otherwise the expression will not be active. The with section uses activePartId as source. It is a string containing the ID of the active view/editor (see description).
The equals section compares the source value with org.eclipse.ui.navigator.ProjectExplorer, returning true when the Project Explorer View is active.
Run your Plug-in as a new Eclipse application and activate the Project Explorer to see the toolbar entry appear/disappear.
Test 2: Enable when Projects are selected
Next we want a button to be visible when at least one project is selected.
<command commandId="org.eclipse.ui.file.exit" label="Test2" style="push"> <visibleWhen checkEnabled="false"> <with variable="selection"> <iterate operator="or"> <adapt type="org.eclipse.core.resources.IProject"> </adapt> </iterate> </with> </visibleWhen> </command>Now we use the selection source provider, which provides the current selection. The iterate operator is nice as it tests all elements of a collection. By setting operator to or we define that at least one element of the collection has to pass the test.
There exists an instanceof operator which we could use to check against org.eclipse.core.resources.IProject. Unfortunately not all projects implement that interface. Instead they use the adapter framework. Therefore we use the adapt operator to see if the element can be adapted to an IProject. Of course this works for all classes implementing the interface directly too.
Test 3: Enable when exactly 2 txt Files are selected
Now for something more complex. A button shall be visible when exactly two resources are selected and both have an extension of .txt.
<command commandId="org.eclipse.ui.file.exit" label="Test3" style="push"> <visibleWhen checkEnabled="false"> <with variable="selection"> <and> <iterate operator="and"> <test property="org.eclipse.core.resources.extension " value="txt"> </test> </iterate> <count value="2"> </count> </and> </with> </visibleWhen> </command>The property tester for file extensions is described in the documentation. The count operator counts the elements within a collection.
Test 4: Login/Logout
Let's add two more buttons for a very basic user login.
<extension point="org.eclipse.ui.menus"> <menuContribution allPopups="false" locationURI="menu:file?after=additions"> <command commandId="com.codeandme.coreexpressions.commands.login" label="Login" style="push"> <visibleWhen checkEnabled="false"> <with variable="com.codeandme.coreexpressions.currentStatus"> <or> <equals value="startup"> </equals> <equals value="logged off"> </equals> </or> </with> </visibleWhen> </command> <command commandId="com.codeandme.coreexpressions.commands.logout" label="Logoff" style="push"> <visibleWhen checkEnabled="false"> <with variable="com.codeandme.coreexpressions.currentUser"> <equals value="John Doe"> </equals> </with> </visibleWhen> </command> </menuContribution>We use dedicated commands that will set/reset the current user of our source provider from the previous post. The different source providers for both buttons do not necessarily make sense - we could achieve the same with just one source. Its just to give you an idea how it works.
We use our custom property tester to verify the current logon state and the current user.