377 lines
12 KiB
C#
377 lines
12 KiB
C#
using System;
|
||
using System.CodeDom;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using System.ComponentModel;
|
||
using System.ComponentModel.Design;
|
||
using System.ComponentModel.Design.Serialization;
|
||
using System.Drawing;
|
||
using System.Drawing.Design;
|
||
using System.Windows.Forms;
|
||
using System.Windows.Forms.Design;
|
||
|
||
namespace ICSharpCode.FormsDesigner.Services
|
||
{
|
||
/// IMenuCommandService implementation.
|
||
public class MenuCommandService : System.ComponentModel.Design.IMenuCommandService
|
||
{
|
||
// the host
|
||
private IDesignerHost host;
|
||
// commandId-command mapping
|
||
private IDictionary commands;
|
||
// menuItem-verb mapping
|
||
private Dictionary<ToolStripMenuItem, DesignerVerb> menuItemVerb;
|
||
// the global verbs collection.
|
||
private DesignerVerbCollection globalVerbs;
|
||
// we use the same context menu over-and-over
|
||
private ContextMenuStrip contextMenu;
|
||
// we keep the lastSelectedComponent around
|
||
private IComponent lastSelectedComponent;
|
||
|
||
public MenuCommandService(IDesignerHost host)
|
||
{
|
||
this.host = host;
|
||
commands = new Hashtable();
|
||
globalVerbs = new DesignerVerbCollection();
|
||
menuItemVerb = new Dictionary<ToolStripMenuItem,DesignerVerb>();
|
||
contextMenu = new ContextMenuStrip();
|
||
lastSelectedComponent = null;
|
||
//roman//
|
||
this.AddCommand(new MenuCommand(ShowProperties, StandardCommands.PropertiesWindow));
|
||
this.AddCommand(new MenuCommand(ViewCode, StandardCommands.ViewCode));
|
||
}
|
||
|
||
//roman//
|
||
public void ShowProperties(object sender, EventArgs e)
|
||
{
|
||
VisualPascalABC.VisualPABCSingleton.MainForm.PropertiesWindowVisible = true;
|
||
}
|
||
|
||
public void ViewCode(object sender, EventArgs e)
|
||
{
|
||
if (VisualPascalABC.VisualPABCSingleton.MainForm._currentCodeFileDocument.DesignerAndCodeTabs.SelectedTab != null)
|
||
{
|
||
//VisualPascalABC.Form1.Form1_object.CahngedSelectedTab();
|
||
VisualPascalABC.VisualPABCSingleton.MainForm._currentCodeFileDocument.DesignerAndCodeTabs.SelectedTab =
|
||
VisualPascalABC.VisualPABCSingleton.MainForm._currentCodeFileDocument.TextPage;
|
||
}
|
||
}
|
||
//roman//
|
||
|
||
#region Implementation of IMenuCommandService
|
||
|
||
/// called to add a MenuCommand
|
||
public void AddCommand(System.ComponentModel.Design.MenuCommand command)
|
||
{
|
||
if (command == null)
|
||
{
|
||
throw new ArgumentException("command");
|
||
}
|
||
// don't add commands twice
|
||
if (FindCommand(command.CommandID) == null)
|
||
{
|
||
commands.Add(command.CommandID, command);
|
||
}
|
||
}
|
||
|
||
/// called to remove a MenuCommand
|
||
public void RemoveCommand(System.ComponentModel.Design.MenuCommand command)
|
||
{
|
||
if(command==null)
|
||
{
|
||
throw new ArgumentException("command");
|
||
}
|
||
commands.Remove(command.CommandID);
|
||
}
|
||
|
||
/// called when to add a global verb
|
||
public void AddVerb(System.ComponentModel.Design.DesignerVerb verb)
|
||
{
|
||
if(verb==null)
|
||
{
|
||
throw new ArgumentException("verb");
|
||
}
|
||
globalVerbs.Add(verb);
|
||
// create a menu item for the verb and add it to the context menu
|
||
ToolStripMenuItem menuItem = new ToolStripMenuItem(verb.Text);
|
||
menuItem.Click += new EventHandler(MenuItemClickHandler);
|
||
menuItemVerb.Add(menuItem,verb);
|
||
contextMenu.Items.Add(menuItem);
|
||
}
|
||
/// called to remove global verb
|
||
public void RemoveVerb(System.ComponentModel.Design.DesignerVerb verb)
|
||
{
|
||
if(verb==null)
|
||
{
|
||
throw new ArgumentException("verb");
|
||
}
|
||
|
||
globalVerbs.Remove(verb);
|
||
|
||
// find the menu item associated with the verb
|
||
ToolStripMenuItem associatedMenuItem = null;
|
||
foreach(KeyValuePair<ToolStripMenuItem, DesignerVerb> de in menuItemVerb)
|
||
{
|
||
if(de.Value==verb)
|
||
{
|
||
associatedMenuItem=de.Key as ToolStripMenuItem;
|
||
break;
|
||
}
|
||
}
|
||
// if we found the verb's menu item, remove it
|
||
if(associatedMenuItem!=null)
|
||
{
|
||
menuItemVerb.Remove(associatedMenuItem);
|
||
}
|
||
// remove the verb from the context menu too
|
||
contextMenu.Items.Remove(associatedMenuItem);
|
||
}
|
||
/// returns the MenuCommand associated with the commandId.
|
||
public System.ComponentModel.Design.MenuCommand FindCommand(System.ComponentModel.Design.CommandID commandID)
|
||
{
|
||
return commands[commandID] as MenuCommand;
|
||
}
|
||
|
||
/// called to invoke a command
|
||
public bool GlobalInvoke(System.ComponentModel.Design.CommandID commandID)
|
||
{
|
||
bool result = false;
|
||
MenuCommand command = FindCommand(commandID);
|
||
if (command != null)
|
||
{
|
||
command.Invoke();
|
||
result = true;
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/// called to show the context menu for the selected component.
|
||
public void ShowContextMenu(System.ComponentModel.Design.CommandID menuID, int x, int y)
|
||
{
|
||
ISelectionService selectionService = host.GetService(typeof(ISelectionService)) as ISelectionService;
|
||
// get the primary component
|
||
IComponent primarySelection = selectionService.PrimarySelection as IComponent;
|
||
// if the he clicked on the same component again then just show the context
|
||
// menu. otherwise, we have to throw away the previous
|
||
// set of local menu items and create new ones for the newly
|
||
// selected component
|
||
if (lastSelectedComponent != primarySelection)
|
||
{
|
||
// remove all non-global menu items from the context menu
|
||
ResetContextMenu();
|
||
// get the designer
|
||
IDesigner designer = host.GetDesigner(primarySelection);
|
||
// not all controls need a desinger
|
||
if(designer!=null)
|
||
{
|
||
// get designer's verbs
|
||
DesignerVerbCollection verbs = designer.Verbs;
|
||
foreach (DesignerVerb verb in verbs)
|
||
{
|
||
// add new menu items to the context menu
|
||
CreateAndAddLocalVerb(verb);
|
||
}
|
||
}
|
||
}
|
||
// we only show designer context menus for controls
|
||
|
||
Control comp = primarySelection as Control; //roman//
|
||
if (comp == null)
|
||
comp = VisualPascalABC.VisualPABCSingleton.MainForm;
|
||
|
||
ToolStripMenuItem[] menuItems1 = new ToolStripMenuItem[VisualPascalABC.VisualPABCSingleton.MainForm.cm_Designer.Items.Count];
|
||
ToolStripMenuItem[] menuItems2 = new ToolStripMenuItem[contextMenu.Items.Count];
|
||
VisualPascalABC.VisualPABCSingleton.MainForm.cm_Designer.Items.CopyTo(menuItems1, 0);
|
||
contextMenu.Items.CopyTo(menuItems2, 0);
|
||
ContextMenuStrip menu = new ContextMenuStrip();
|
||
menu.Items.AddRange(menuItems1);
|
||
if (menuItems2.Length > 0)
|
||
menu.Items.Add(new ToolStripSeparator());
|
||
menu.Items.AddRange(menuItems2);
|
||
Point pt = comp.PointToScreen(new Point(0, 0));
|
||
menu.Show(comp, new Point(x - pt.X, y - pt.Y));
|
||
/*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:
|
||
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD> menu.Items.AddRange(menuItems1); <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> VisualPascalABC.Form1.Form1_object.cm_Designer,
|
||
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> menu.Items.AddRange(menuItems2);
|
||
*/
|
||
menu.Closed += delegate
|
||
{
|
||
VisualPascalABC.VisualPABCSingleton.MainForm.cm_Designer.Items.Clear();
|
||
contextMenu.Items.Clear();
|
||
VisualPascalABC.VisualPABCSingleton.MainForm.cm_Designer.Items.AddRange(menuItems1);
|
||
contextMenu.Items.AddRange(menuItems2);
|
||
return;
|
||
};
|
||
// keep the selected component for next time
|
||
lastSelectedComponent = primarySelection;
|
||
}
|
||
|
||
/// returns the the current designer verbs
|
||
public System.ComponentModel.Design.DesignerVerbCollection Verbs
|
||
{
|
||
get
|
||
{
|
||
// create a new collection
|
||
DesignerVerbCollection availableVerbs = new DesignerVerbCollection();
|
||
// add the global verbs
|
||
if(globalVerbs!=null && globalVerbs.Count>0)
|
||
{
|
||
availableVerbs.AddRange(globalVerbs);
|
||
}
|
||
// now add the local verbs
|
||
ISelectionService selectionService = host.GetService(typeof(ISelectionService)) as ISelectionService;
|
||
IComponent primaryComponent = selectionService.PrimarySelection as IComponent;
|
||
if(primaryComponent!=null)
|
||
{
|
||
IDesigner designer = host.GetDesigner(primaryComponent);
|
||
if(designer!=null && designer.Verbs!=null && designer.Verbs.Count>0)
|
||
{
|
||
availableVerbs.AddRange(designer.Verbs);
|
||
}
|
||
}
|
||
return availableVerbs;
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
/// called to invoke menu item verbs
|
||
private void MenuItemClickHandler(object sender, EventArgs e)
|
||
{
|
||
// get the menu item
|
||
ToolStripMenuItem menuItem = sender as ToolStripMenuItem;
|
||
if(menuItem!=null)
|
||
{
|
||
// get and invoke the verb
|
||
DesignerVerb verb = menuItemVerb[menuItem] as DesignerVerb;
|
||
if(verb!=null)
|
||
{
|
||
try
|
||
{
|
||
verb.Invoke();
|
||
}
|
||
catch{}
|
||
}
|
||
}
|
||
}
|
||
/// removes all local verbs from the context menu
|
||
private void ResetContextMenu()
|
||
{
|
||
if(contextMenu!=null && contextMenu.Items!=null && contextMenu.Items.Count>0)
|
||
{
|
||
ToolStripMenuItem[] menuItemArray = new ToolStripMenuItem[contextMenu.Items.Count];
|
||
contextMenu.Items.CopyTo(menuItemArray,0);
|
||
foreach(ToolStripMenuItem menuItem in menuItemArray)
|
||
{
|
||
// if its not in the global list, remove it
|
||
if(!IsInGlobalList(menuItem.Text))
|
||
{
|
||
contextMenu.Items.Remove(menuItem);
|
||
}
|
||
// get rid of the menu item from the mapping
|
||
menuItemVerb.Remove(menuItem);
|
||
}
|
||
}
|
||
}
|
||
/// removes a local verb
|
||
private void RemoveLocalVerb(DesignerVerb verb)
|
||
{
|
||
if(verb==null)
|
||
{
|
||
throw new ArgumentException("verb");
|
||
}
|
||
// get the associated menuItem
|
||
ToolStripMenuItem menuItem = GetMenuItemForVerb(verb);
|
||
if(menuItem!=null)
|
||
{
|
||
// undo mapping
|
||
menuItemVerb.Remove(menuItem);
|
||
// remove from context menu
|
||
contextMenu.Items.Remove(menuItem);
|
||
}
|
||
}
|
||
/// creats and adds a local verb
|
||
private void CreateAndAddLocalVerb(DesignerVerb verb)
|
||
{
|
||
if(verb==null)
|
||
{
|
||
throw new ArgumentException("verb");
|
||
}
|
||
VerifyVerb(verb);
|
||
// create a menu item for the verb
|
||
ToolStripMenuItem menuItem = new ToolStripMenuItem(verb.Text);
|
||
// attach the menu item click listener
|
||
menuItem.Click += new EventHandler(MenuItemClickHandler);
|
||
// do the menuItem-verb mapping
|
||
menuItemVerb.Add(menuItem,verb);
|
||
// add to context menu
|
||
contextMenu.Items.Add(menuItem);
|
||
}
|
||
/// returns the MenuItem associated with the verb
|
||
private ToolStripMenuItem GetMenuItemForVerb(DesignerVerb verb)
|
||
{
|
||
ToolStripMenuItem menuItem = null;
|
||
if(menuItemVerb!=null && menuItemVerb.Count>0)
|
||
{
|
||
foreach(KeyValuePair<ToolStripMenuItem, DesignerVerb> de in menuItemVerb)
|
||
{
|
||
DesignerVerb dv = de.Value as DesignerVerb;
|
||
if(dv==verb)
|
||
{
|
||
menuItem = de.Key as ToolStripMenuItem;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
return menuItem;
|
||
}
|
||
/// returns true if the verb is in the global verb collection
|
||
private bool IsInGlobalList(string verbText)
|
||
{
|
||
bool found = false;
|
||
if(globalVerbs!=null && globalVerbs.Count>0)
|
||
{
|
||
foreach(DesignerVerb dv in globalVerbs)
|
||
{
|
||
if(string.Compare(dv.Text,verbText,true)==0)
|
||
{
|
||
found=true;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
return found;
|
||
}
|
||
/// we can't add the same verb twice
|
||
private void VerifyVerb(DesignerVerb verb)
|
||
{
|
||
if(verb==null)
|
||
{
|
||
throw new ArgumentException("verb");
|
||
}
|
||
// make sure the verb is not in the global list
|
||
if(globalVerbs!=null && globalVerbs.Count>0)
|
||
{
|
||
foreach(DesignerVerb dv in globalVerbs)
|
||
{
|
||
if(string.Compare(dv.Text,verb.Text,true)==0)
|
||
{
|
||
throw new Exception("Cannot add the same verb twice.");
|
||
}
|
||
}
|
||
}
|
||
// now check the menuItemVerb mapping
|
||
if(menuItemVerb!=null && menuItemVerb.Count>0)
|
||
{
|
||
foreach(DesignerVerb dv in menuItemVerb.Values)
|
||
{
|
||
if(string.Compare(dv.Text,verb.Text,true)==0)
|
||
{
|
||
throw new Exception("Cannot add the same verb twice.");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|