diff --git a/core/src/main/java/hudson/Functions.java b/core/src/main/java/hudson/Functions.java index f6be654b0b..34e17e9c10 100644 --- a/core/src/main/java/hudson/Functions.java +++ b/core/src/main/java/hudson/Functions.java @@ -792,7 +792,8 @@ public class Functions { */ public static String getIconFilePath(Action a) { String name = a.getIconFileName(); - if(name.startsWith("/")) + if (name==null) return null; + if (name.startsWith("/")) return name.substring(1); else return "images/24x24/"+name; diff --git a/core/src/main/java/hudson/model/Actionable.java b/core/src/main/java/hudson/model/Actionable.java index 7ab30a3a30..24ae3c091b 100644 --- a/core/src/main/java/hudson/model/Actionable.java +++ b/core/src/main/java/hudson/model/Actionable.java @@ -23,11 +23,20 @@ */ package hudson.model; +import hudson.model.queue.Tasks; +import jenkins.model.ModelObjectWithContextMenu; +import org.apache.commons.jelly.Script; +import org.apache.commons.jelly.XMLOutput; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.WebApp; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; +import org.kohsuke.stapler.jelly.JellyClassTearOff; +import org.kohsuke.stapler.jelly.JellyFacet; +import org.xml.sax.helpers.DefaultHandler; +import java.util.ArrayList; import java.util.List; import java.util.Vector; import java.util.concurrent.CopyOnWriteArrayList; @@ -38,7 +47,7 @@ import java.util.concurrent.CopyOnWriteArrayList; * @author Kohsuke Kawaguchi */ @ExportedBean -public abstract class Actionable extends AbstractModelObject { +public abstract class Actionable extends AbstractModelObject implements ModelObjectWithContextMenu { /** * Actions contributed to this model object. * @@ -119,4 +128,22 @@ public abstract class Actionable extends AbstractModelObject { } return null; } + + public ContextMenu doContextMenu(StaplerRequest request, StaplerResponse response) throws Exception { + ContextMenu c = new ContextMenu(); + + WebApp webApp = WebApp.getCurrent(); + Script s = webApp.getMetaClass(this).getTearOff(JellyClassTearOff.class).findScript("sidepanel"); + if (s==null) { + // fallback + c.addAll(getActions()); + } else { + JellyFacet facet = webApp.getFacet(JellyFacet.class); + request.setAttribute("taskTags",c); + request.setAttribute("mode","side-panel"); + facet.scriptInvoker.invokeScript(request,response,s,this,new XMLOutput(new DefaultHandler())); + } + + return c; + } } diff --git a/core/src/main/java/jenkins/model/Jenkins.java b/core/src/main/java/jenkins/model/Jenkins.java index b0ca07ac69..a87b84e1f7 100755 --- a/core/src/main/java/jenkins/model/Jenkins.java +++ b/core/src/main/java/jenkins/model/Jenkins.java @@ -293,7 +293,7 @@ import java.util.regex.Pattern; * @author Kohsuke Kawaguchi */ @ExportedBean -public class Jenkins extends AbstractCIBase implements ModifiableItemGroup, StaplerProxy, StaplerFallback, ViewGroup, AccessControlled, DescriptorByNameOwner { +public class Jenkins extends AbstractCIBase implements ModifiableItemGroup, StaplerProxy, StaplerFallback, ViewGroup, AccessControlled, DescriptorByNameOwner, ModelObjectWithContextMenu { private transient final Queue queue; /** @@ -2894,6 +2894,10 @@ public class Jenkins extends AbstractCIBase implements ModifiableItemGroup items = new ArrayList(); + + public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object o) throws IOException, ServletException { + rsp.serveExposedBean(req,this,Flavor.JSON); + } + + public ContextMenu add(String url, String text) { + items.add(new MenuItem(url,text)); + return this; + } + + public ContextMenu addAll(Collection actions) { + for (Action a : actions) + add(a); + return this; + } + + public ContextMenu add(Action a) { + StaplerRequest req = Stapler.getCurrentRequest(); + String text = a.getDisplayName(); + String icon = Functions.getIconFilePath(a); + String url = Functions.getActionUrl(req.findAncestor(ModelObject.class).getUrl(),a); + + return add(url,icon,text); + } + + public ContextMenu add(String url, String icon, String text) { + if (text != null && icon != null && url != null) + items.add(new MenuItem(url," "+text)); + return this; + } + } + + @ExportedBean + public class MenuItem { + @Exported + public String url; + @Exported + public String text; + + public MenuItem(String url, String text) { + this.url = url; + this.text = text; + } + } +} diff --git a/core/src/main/resources/lib/layout/task.jelly b/core/src/main/resources/lib/layout/task.jelly index 4b2bcd66af..22eaeeeac0 100644 --- a/core/src/main/resources/lib/layout/task.jelly +++ b/core/src/main/resources/lib/layout/task.jelly @@ -94,8 +94,12 @@ THE SOFTWARE.
+ + ${taskTags!=null ? taskTags.add(href,icon,title) : null} + ${taskTags} + - +