I searched all over the net but couldn't find a working solution how to create pull-down menu entries for a menu item in a toolbar in Eclipse programmatically. To create them using plugin.xml is smooth, but is there some way to do it from code? Why to do that?
I want to create a little plugin which offers the user the possibility to create a random number of entries which should be accessible thru a single menu item (button) with a pull-down menu in the main toolbar.
I'm quite new to Eclipse plugin development. As I already said doing in plugin.xml is no problem :
<extension point="org.eclipse.ui.menus">
<menuContribution locationURI="toolbar:org.eclipse.ui.main.toolbar?after=additions">
<toolbar id="pulldown.items.toolbars.sampleToolbar">
<command
commandId="pulldown.items.commands.sampleCommand"
icon="icons/sample.gif"
tooltip="Say hello world"
id="pulldown.items.toolbars.sampleCommand"
style="pulldown">
</command>
</toolbar>
</menuContribution>
<menuContribution locationURI="menu:pulldown.items.toolbars.sampleCommand">
<command
commandId="pulldown.items.commands.sampleCommand"
label="Message 1" style="push">
<parameter name="pulldown.items.msg" value="Some message"/>
</command>
<separator name="nothing" visible="false"/>
<command
commandId="pulldown.items.commands.sampleCommand"
label="Message 2" style="push">
<parameter name="pulldown.items.msg" value="Some other message"/>
</command>
</menuContribution>
</extension>
I tried to find the information about this commands in the following objects but couldn't find any. Don't bother me using getWorkbenchWindows()[0] this code is executed on plugin startup and there is no active window available.
Activator act = Activator.getDefault();
IWorkbench workbench = act.getWorkbench();
WorkbenchWindow window = (WorkbenchWindow)workbench.getWorkbenchWindows()[0];
CoolBarManager cbm = window.getCoolBarManager();
ToolBarContributionItem item =
(ToolBarContributionItem)cbm.find("pulldown.items.toolbars.SampleToolbar");
IToolBarManager tbm = item.getToolBarManager();
CommandContributionItem citem =
(CommandContributionItem)tbm.find("pulldown.items.toolbars.sampleCommand");
ParameterizedCommand cmd = citem.getCommand();
All objects are valid but they contain neither one of the above defined parameterized commands. All parameters in the commands I could find are only containing the definition but no value is specified.
Have a look at the class attribute of the menuContribution element. Via a this you can write a Java class (extending org.eclipse.ui.menus.ExtensionContributionFactory) that will contribute the wanted menu entries dynamically. In this case all sub-elements of the menuContribution will be ignored.
As an alternative to providing an entire ExtensionsContributionFactory (which would work fine), you could add the dynamic element in your existing XML and then supply a CompoundContributionItem to create the dynamic part of your toolitem dropdown.
Related
I'm defining my own perspective using:
<extension point="org.eclipse.ui.perspectives">
In my implementation of IPerspectiveFactory::createInitialLayout() I want to use IPageLayout.addActionSet() which points to a new actionset. But actionsets are deprecated; what is the recommended alternative?
The reason I want to add a new actionset is I want the Run menu to display debug actions, but not run actions. If I use layout.addActionSet(IDebugUIConstants.LAUNCH_ACTION_SET) I get both. So I figured I'd define my own actionset with just the debug variants in. But I'd like to use a non deprecated API. What's the recom
The alternative is to use the org.eclipse.ui.menus extension point for menu items. However you can't add this to a perspective, instead you have to use the visibleWhen element to control when the menu is shown.
For example this is how the PDE plugin adds a menu to the Navigate menu when the plugin development perspective is active or the search action set is in use:
<extension
point="org.eclipse.ui.menus">
<menuContribution
locationURI="menu:navigate?after=open.ext2">
<separator
name="org.eclipse.pde.ui.openPluginArtifactSeparator"
visible="true">
</separator>
<command
commandId="org.eclipse.pde.ui.openPluginArtifact"
icon="$nl$/icons/obj16/open_artifact_obj.gif"
label="%pluginsearch.action.menu.name">
<visibleWhen>
<or>
<with
variable="activeWorkbenchWindow.currentPerspective">
<equals
value="org.eclipse.pde.ui.PDEPerspective">
</equals>
</with>
<with
variable="activeContexts">
<iterate
operator="or">
<equals
value="org.eclipse.pde.ui.SearchActionSet">
</equals>
</iterate>
</with>
</or>
</visibleWhen>
</command>
</menuContribution>
Although action sets are deprecated they are not going to be removed for a long time as a lot of Eclipse code still uses them, so you may just want to stick with them.
I have a combo box with descriptions that are long in length. I'm trying to find the best way to show the full description. One thing I came across was the title attribute which causes a popup to show on hover. I tried to use the "attrs" property in XPages to add a title property, but xp:selectItem and xp:selectItems "attrs" do not appear in the HTML output.
Anyone have any ideas or a different method to try? Thanks for any thoughts.
EDIT: I ended up changing the combo box into a dialog pick list. This satisfied my requirements.
Did you consider using xe:djComboBox from Extension Library?
See http://www-10.lotus.com/ldd/ddwiki.nsf/dx/djComboBox_Dojo_Combo_Box_ddxl853
<xe:djComboBox id="djComboBox1" value="#{sessionScope.djComboBox1}"
tooltipPosition="auto">
<xe:this.dojoAttributes>
<xp:dojoAttribute name="autoComplete" value="false">
</xp:dojoAttribute>
<xp:dojoAttribute name="labelType" value="html">
</xp:dojoAttribute>
</xe:this.dojoAttributes>
<xp:selectItems>
<xp:this.value>
<![CDATA[#{javascript:return new Array("<b>Apples</b>|apples", "Oranges|oranges")}]]>
</xp:this.value>
</xp:selectItems>
</xe:djComboBox>
Each element in array should have following format "label|value|description|disabled", where only label is mandatory. See: http://publib.boulder.ibm.com/infocenter/domhelp/v8r0/index.jsp?topic=%2Fcom.ibm.designer.domino.ui.doc%2Fwpd_controls_cref_selectitems.html
If the description of your items is so long that they dont fit in a combobox you could either:
Change the length of the combobox using css.
Retrieve the description and only display a portion of it (lets say first 100 chars ).
Descriptions in comboboxes should be 'descriptive' ( hence the word description ). I would go for the second approach and add something in front of the description so the description is still usefull for the users.
For instance when have a list of projects. These titles are 100+ characters long. Instead of displaying the full description. Cut them of and use the project code as a prefix so that it will display
ProjectCode - {first 100 chars of description}.
This way users still know what they select because of the project code.
I've spent days trying to figure this out and I give up.
I am a LotusScript programmer and have been trying to learn XPages. All of the examples and sample programs I've studied only touch on pieces of this.
Can someone explain to me step by step how to use the Selected property of the Extension Library Navigator control?
I have created my own custom control based on the layout control from the Extension Library and created a custom property called navigationPath. I also created a navigator custom control that has 5 Page Link Nodes. In the "Selected" property of each Page Link Node, I put the following SSJS:
if(compositeData.navigationPath == "/Home/ApplicationPool"){
return true
}else{
return false
}
/Home/ApplicationPool corresponds to the value I put in the "Selection" property of the particular Page Link Node.
In each layout custom control, I set the "navigationPath" property to compositeData.navigationPath.
What did I miss?
there is a selected and selection property and they mean very different things and can't be used at the same time. In the code example in your question above you are using the selected property which is the wrong one in this case.
Your treeNodes in the navigator should be setup to use the selection property, this is a RegEx value that is used to see if it matches the value passed into the application layout via the custom property.
<xe:navigator id="navigator1" expandable="true" expandEffect="wipe">
<xe:this.treeNodes>
<xe:pageTreeNode label="nodeName" page="/page.xsp" selection="/Home/ApplicationPool" />
</xe:this.treeNodes>
</xe:navigator>
As you can see you don't need to use any SSJS to evaluate a true/false outcome. Just match the value in the treeNode to the one in the XPage's applicationLayout control.
If your using tabs in the layout titleBar then you can set a selection property there also that uses the format /Home/.* which will make that tab highlighted for every XPage that have /Home/ at the start of it's navigationpath custom property. Don;t forget it is RegEx so any valid RegEx statement can be used here adding more power to this particular property.
For the tree nodes in the navigator control you define the name of the xpage to open and then the related selection. Example:
<xe:pageTreeNode page="/text.xsp" selection="/Home/Test" label="Test page">
</xe:pageTreeNode>
For the individual xpages using the applicationLayout you define a value for navigationPath. If this value matches an entry in one of the tree nodes the naviagor control, then the corresponding menu item will be highlighted in the browser. The best way to define the value of the navigationPath is by using a custom property (as you are using). Here's an example of that:
<xe:applicationLayout id="applicationLayout1">
<xe:this.configuration>
<xe:oneuiApplication navigationPath="${javascript:compositeData.navigationPath}" ...
You can see examples of using all this in the Extension Library Teamroom and Discussion templates.
Based on my explanation on how to use it, I can see that you are not using the selection property on the navigation control correct. You just need to define a unique value for each tree node (which then will be used if it matches navigationPath on the individual xpages).
So for your specific example change your selection property to just return: "/Home/ApplicationPool"
I have a custom document library template with content types. This works fine but the only thing that I would like to add is that when a user instantiates a new document library based on that template, that is has a predefined folder structure already in place.
I have tried adding Module tags in my schema.xml but this doesn't seem to work.
I know that it is possible to provision a document library with files and folders with a ListInstance feature but this is not possible in this case. I would like that the predefined folder structure is part of the document library template.
Is this possible?
Thanks
Maarten
If You want to achieve this using Document Library Definition. I don't think that would be achievable. What you can do is take help of list /document library templates.
1 Create a custom Doclibary the way you want.
2. create the desired folder structure. without uploading any documents.
3, Save the doc library as template by going to Doclibray settings ( make sure you store the template along with content stored into it)
Another method (which I must blog on soon) is to fake a list creation event. I add an empty view definition with a custom aspx page to the list template. The custom page simply executes some custom functionality on the list, deletes the initialisation view, then redirects to the normal view. It's a little messy, and it will only work if the list is created through the UI, but it works.
Here is a very quick example. You already have your list template. In the schema.xml file, add a new View to the Views element like so:
<Views>
<!-- Below is a blank view used to kick of initialisation after list creation. -->
<View DisplayName="Initialise" Type="HTML" DefaultView="TRUE" WebPartZoneID="Main" SetupPath="pages\Scratch\init.aspx" Hidden="TRUE" Url="_init.aspx">
<Toolbar Type="Standard" />
<ViewHeader />
<ViewBody />
<ViewFooter />
<ViewEmpty />
<ViewFields />
<ViewData />
<Query />
</View>
<!-- standard views would be here -->
</Views>
You may be able to go without the empty elements in there. That was something I was going to test further before blogging on it. But this will get the job done. The important things are:
This view is the first view and DefaultView is set to TRUE.
The SetupPath is set to a custom page that you will provision with your solution.
For the custom page (init.aspx in my example), I just made a copy of ...\12\TEMPLATE\Pages\viewpage.aspx and changed what the page inherits from. You could do this with inline code, but I used a codebehind assembly. So first line of that file becomes:
<%# Page language="C#" MasterPageFile="~masterurl/default.master" Inherits="SharePointScratch.InitPage,SharePointScratch,Version=1.0.0.0,Culture=neutral,PublicKeyToken=xxxxxxxxxxxxxxxx" %>
And then the codebehind:
using System;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
namespace SharePointScratch
{
public class InitPage : System.Web.UI.Page
{
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
SPList list = SPContext.Current.List;
list.ParentWeb.AllowUnsafeUpdates = true;
// Create you folder structure here...
// Fix the views by deleting the initialisation view.
SPView view = SPContext.Current.ViewContext.View;
list.Views.Delete(view.ID);
list.Update();
list.ParentWeb.AllowUnsafeUpdates = false;
// Redirect to the new default view.
SPUtility.Redirect(list.DefaultViewUrl, SPRedirectFlags.Default, this.Context);
}
}
}
Basically, we are relying on the SharePoint default behavior to display the default view of a list after creation. A custom view is inserted in the schema with the sole intention of firing off some custom code. The custom code does, well, whatever you want. After this, you clean up by deleting the special view from the template and redirecting back to the view.
I am developing a Sharepoint Solution, that implements a new list. This list has an event receiver attached to a Custom Content type.
I am using VSeWSS 1.3 for this task and it's going ok (the content type gets created, a list is created and bound to the content type, the event receiver triggers successfully.
My only concern is that in the created list, it always show the base Content Type (Item CT with Title field). Through the Web GUI I can hide this content type, but I can't find where to do that in my XML definitions, or make it on the solution to avoid double tasks when deploying.
Any suggestions??
You will have to edit the Schema.xml for your custom list. Find the <ContentTypes> tag and remove any you do not wish to be shown.
Your list definition will have a guid (eg. <Elements Id="0a8594c8-5cf1-492e-88ce-df943830c88c") that will specify the list from the schema xml (e.g.<List Name="... ...Id="0a8594c8-5cf1-492e-88ce-df943830c88c">)
I am not sure what the implementation is for, usually there is a feature.xml to combine the previous xml files together (e.g.<ElementManifests><ElementManifest Location="MyFeature\ListDefinition.xml" /><ElementFile Location="MyFeature\schema.xml" />)
In the schema.xml you need to make 2 changes
in the <List> element add the following attribute:
EnableContentTypes="TRUE"
the <ContentTypes> element should contain a <ContentType> element that specifes your custom Content type.
for example:
<?xml version="1.0"?>
<List
xmlns:ows="Microsoft SharePoint"
Title="List_Title"
FolderCreation="FALSE"
Direction="$Resources:Direction;"
Url="Lists/List_Title"
BaseType="0"
Name="List_Title"
Id="51D716AC-DF9D-4ebb-9F8E-9134EEBB7C39"
Type="100"
xmlns="http://schemas.microsoft.com/sharepoint/"
EnableContentTypes="TRUE"
>
<MetaData>
<ContentTypes>
<ContentTypeRef ID="0x01..." />
</ContentTypes>
Both answers helped me, but I found also that you need to specify the columns again in the List Definition (not only in the Content Type), because otherwise, they won't show up in the list.