/* Copyright (c) Cloud Software Group, Inc. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the * following disclaimer in the documentation and/or other * materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ using System; using System.Windows.Forms; using System.Drawing; using XenAdmin.Core; using XenAdmin.Model; using XenAdmin.XenSearch; using XenAPI; namespace XenAdmin.Controls.XenSearch { public class ResourceSelectButton : DropDownComboButton, IAcceptGroups { private class ResourceRenderer : ToolStripProfessionalRenderer { private static int RIGHT_MARGIN = 2; private static int TOP_MARGIN = 2; protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e) { // The TextColor for a disabled item is ignored, so we have to temporarily enable the item. bool enabled = e.Item.Enabled; e.Item.Enabled = true; base.OnRenderItemText(e); e.Item.Enabled = enabled; // Draw an icon just before the text starts String s = e.Text; String sSpaces = String.Empty; // sSpaces will be the spaces at the beginning of s for (int i = 0; i < s.Length && s[i] == ' '; ++i) sSpaces += ' '; Size indent = Drawing.MeasureText(sSpaces, e.TextFont); Image im = Images.GetImage16For(e.Item.Tag as IXenObject); e.Graphics.DrawImage(im, indent.Width - im.Width - RIGHT_MARGIN, e.TextRectangle.Top + TOP_MARGIN, im.Width, im.Height); } } private static string INDENT = " "; private QueryScope scope = null; private FolderListItem folderListItem = null; public ResourceSelectButton() : base() { contextMenuStrip.ShowImageMargin = false; contextMenuStrip.Renderer = new ResourceRenderer(); } protected override void SetButtonTextFromItem(ToolStripItem item) { IXenObject o = item.Tag as IXenObject; if (o is Folder) // for folders we want to show the full pathname using a FolderListItem { Text = String.Empty; folderListItem = new FolderListItem(o.opaque_ref, FolderListItem.AllowSearch.None, false); folderListItem.Parent = this; } else { Text = Helpers.GetName(o); folderListItem = null; } this.Invalidate(); } protected override void OnPaint(PaintEventArgs pevent) { base.OnPaint(pevent); if (folderListItem != null) { Rectangle r = pevent.ClipRectangle; r.Location = new Point(6, 4); r.Width -= 21; r.Height -= 6; folderListItem.DrawSelf(pevent.Graphics, r, false); } } public IAcceptGroups Add(Grouping grouping, object group, int indent) { ToolStripMenuItem menuItem = new ToolStripMenuItem(); IXenObject o = group as IXenObject; if (o != null) { // Pad the item name with spaces on the left. This is nasty, but we // don't know any way to specify a width or padding in pixels and have // it affect the area on which we can write or the width of the tool // strip; so it seems necessary to fool the framework in this way. menuItem.Text = INDENT; for (int i = 0; i < indent; ++i) menuItem.Text += INDENT; menuItem.Text += Helpers.GetName(o).EscapeAmpersands(); menuItem.Tag = o; if (scope != null && !scope.WantType(o)) { menuItem.Enabled = false; menuItem.BackColor = System.Drawing.Color.Gainsboro; menuItem.ForeColor = DefaultForeColor; } AddItem(menuItem); } return this; } public void FinishedInThisGroup(bool defaultExpand) { } public void Populate(Search search) { ClearItems(); scope = search?.Query?.QueryScope; search?.PopulateAdapters(this); } } }