Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CADability/MenuResource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -304,14 +304,16 @@ static public MenuWithHandler[] CreateContextMenuWithHandler(string[] menuIDs, I
/// <param name="MenuName">Name of the menu to load: the "Name" attribute of a "MainMenu" node or the "MenuId" attribute of a "Popup" node</param>
/// <param name="main">true to load a main menu, false to load a popup (context) menu</param>
/// <param name="handler">Command handler which handles the menu commands</param>
/// <returns>The menu entries</returns>
/// <returns>The menu entries, an empty array if there is no menu with this name (e.g. for a null name)</returns>
static public MenuWithHandler[] LoadMenuDefinition(string MenuName, bool main, ICommandHandler handler)
{
List<MenuWithHandler> result = new List<MenuWithHandler>();
ICommandHandler Handler = handler;
if (MenuName == null) return result.ToArray(); // e.g. an object without a context menu of its own, like a picture
XmlNode MenuNode;
if (main) MenuNode = mMenuDocument.SelectSingleNode("Menus/MainMenu[@Name='" + MenuName + "']");
else MenuNode = mMenuDocument.SelectSingleNode("Menus//Popup[@MenuId='" + MenuName + "']");
if (MenuNode == null) return result.ToArray();
for (XmlNode nd = MenuNode.FirstChild; nd != null; nd = nd.NextSibling)
{
LoadMenu(nd, result, Handler);
Expand Down
2 changes: 1 addition & 1 deletion CADability/UnscaledGeoObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ IGeoObject IGeoObjectShowProperty.GetGeoObject()

string IGeoObjectShowProperty.GetContextMenuId()
{
throw new Exception("The method or operation is not implemented.");
return null; // no context menu of its own
}

#endregion
Expand Down
2 changes: 1 addition & 1 deletion CADability/UnscaledIcon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ IGeoObject IGeoObjectShowProperty.GetGeoObject()

string IGeoObjectShowProperty.GetContextMenuId()
{
throw new Exception("The method or operation is not implemented.");
return null; // no context menu of its own
}

#endregion
Expand Down
45 changes: 45 additions & 0 deletions tests/CADability.Tests/ContextMenuTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using CADability.GeoObject;
using CADability.UserInterface;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace CADability.Tests
{
/// <summary>
/// The context menu of a selected object: <see cref="CADability.Actions.SelectObjectsAction"/> loads the menu whose id the object's
/// <see cref="IGeoObjectShowProperty"/> returns. Pictures, icons and unscaled objects have no menu of their own and
/// return null; a right click on a selected picture threw a NullReferenceException in
/// <see cref="MenuResource.LoadMenuDefinition"/>.
/// </summary>
[TestClass]
public class ContextMenuTests
{
[TestMethod]
public void AMissingMenuIsEmpty()
{
Assert.AreEqual(0, MenuResource.LoadMenuDefinition(null, false, null).Length);
Assert.AreEqual(0, MenuResource.LoadMenuDefinition("MenuId.DoesNotExist", false, null).Length);
Assert.AreEqual(0, MenuResource.LoadMenuDefinition("No Such Main Menu", true, null).Length);
}

[TestMethod]
public void AnExistingMenuIsLoaded()
{
// the context menu of the path of a picture
MenuWithHandler[] menu = MenuResource.LoadMenuDefinition("MenuId.Picture.Path", false, null);
CollectionAssert.AreEqual(new[] { "MenuId.Picture.Path.Reload", "MenuId.Picture.Path.Open" }, menu.Select(m => m.ID).ToArray());
}

[TestMethod]
[DataRow(typeof(ShowPropertyPicture))]
[DataRow(typeof(ShowPropertyUnscaledIcon))]
[DataRow(typeof(ShowPropertyUnscaledGeoObject))]
public void TheContextMenuOfObjectsWithoutAMenuOfTheirOwnCanBeLoaded(Type showPropertyType)
{
// what SelectObjectsAction.OnMouseUp does for a single selected object; the id does not depend on the state
// of the property, so an uninitialized one (without a frame) is enough
IGeoObjectShowProperty showProperty = (IGeoObjectShowProperty)System.Runtime.CompilerServices.RuntimeHelpers.GetUninitializedObject(showPropertyType);
MenuWithHandler[] menu = MenuResource.LoadMenuDefinition(showProperty.GetContextMenuId(), false, showProperty as ICommandHandler);
Assert.AreEqual(0, menu.Length);
}
}
}
Loading