using System; using System.Text; using System.ComponentModel; using System.Drawing; using System.Collections; using System.Windows.Forms; namespace DevComponents.DotNetBar { #region ICommand /// /// Defines an interface that represents the Command associated with an BaseItem instance. /// public interface ICommand { /// /// Executes the command without specifying the source of the command. /// void Execute(); /// /// Executes the command and specifies the source of the command. /// void Execute(ICommandSource commandSource); /// /// Executes the code associated with the command. /// event EventHandler Executed; /// /// Provides the opportunity to cancel the execution of the command. This event occurs before the Executed event. /// event CancelEventHandler PreviewExecuted; /// /// Gets or sets the text associated with the items that are using command. /// string Text { get; set; } /// /// Gets or sets the value of Checked property if item associated with the command support it. /// bool Checked { get; set; } /// /// Gets or sets the value of Visible property if item associated with the command support it. /// bool Visible { get; set; } /// /// Gets or sets the value of Image property if item associated with the command support it. /// Image Image { get; set; } /// /// Gets or sets the value of small image (ImageSmall) property if item associated with the command support it. /// Image ImageSmall { get; set; } /// /// Gets or sets the value of Enabled property for items associated with the command. /// bool Enabled { get; set; } /// /// Called when CommandSource is registered for the command. /// /// CommandSource registered. void CommandSourceRegistered(ICommandSource source); /// /// Called when CommandSource is unregistered for the command. /// /// CommandSource unregistered. void CommandSourceUnregistered(ICommandSource source); /// /// Sets an property value on the subscribers through the reflection. If subscriber does not have /// specified property with value type its value is not set. /// /// Property name to set. /// Property value. void SetValue(string propertyName, object value); } #endregion #region ICommandSource /// /// Defines an interface for the object that knows how to invoke a command. /// public interface ICommandSource { /// /// Gets or sets the command that will be executed when the command source is invoked. /// ICommand Command { get;set;} /// /// Gets or sets user defined data value that can be passed to the command when it is executed. /// object CommandParameter { get;set;} } #endregion #region Command /// /// Defines an command that is associated with an instance of BaseItem /// [ToolboxItem(true), DesignTimeVisible(true), ToolboxBitmap(typeof(Command), "Command.ico"), DefaultEvent("Executed")] public class Command : Component, ICommand { #region ICommand Members /// /// Initializes a new instance of the Command class with the specified container. /// /// An IContainer that represents the container for the command. public Command(IContainer container) : this() { container.Add(this); } /// /// Initializes a new instance of the Command class with the specified container. /// /// An IContainer that represents the container for the command. public Command(IContainer container, EventHandler commandExecutedEventHandler) : this() { container.Add(this); Executed += commandExecutedEventHandler; } /// /// Initializes a new instance of the Command class with the specified execute event handler. /// public Command(EventHandler commandExecutedEventHandler) : this() { Executed += commandExecutedEventHandler; } /// /// Initializes a new instance of the Command class. /// public Command() { } /// /// Executes the command. /// public virtual void Execute() { Execute(null); } /// /// Executes the command. /// public virtual void Execute(ICommandSource commandSource) { CancelEventArgs e = new CancelEventArgs(); OnPreviewExecuted(commandSource, e); if (e.Cancel) return; OnExecuted(commandSource, new EventArgs()); } /// /// Executes the code associated with the command when an instance of BaseItem is clicked. /// public event EventHandler Executed; /// /// Raises the Execute event. /// /// Provides event data. protected virtual void OnExecuted(ICommandSource commandSource, EventArgs e) { EventHandler eh = Executed; if (eh != null) eh(commandSource, e); } /// /// Occurs before the Executed event and allows you to cancel the firing of Executed event. /// public event CancelEventHandler PreviewExecuted; /// /// Raises the PreviewExecuted event. /// /// Provides event data. protected virtual void OnPreviewExecuted(ICommandSource commandSource, CancelEventArgs e) { CancelEventHandler eh = PreviewExecuted; if (eh != null) eh(commandSource, e); } private string _Text = null; private bool _TextSet = false; /// /// Gets or sets the Text that is assigned to all command sources that are using this command and have Text property. /// [Localizable(true), Description("Indicates Text that is assigned to all command sources that are using this command and have Text property.")] [Editor("DevComponents.DotNetBar.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] public string Text { get { return _Text; } set { _Text = value; _TextSet = true; OnTextChanged(); } } /// /// Called when Text property is set. /// protected virtual void OnTextChanged() { SetTextProperty(); } /// /// Sets the Text property on all subscribers to the command Text. /// protected virtual void SetTextProperty() { IsSyncingCommand = true; try { ArrayList list = GetSubscribers(); ArrayList removeList = new ArrayList(list.Count); string text = _Text; if (this.GetDesignMode()) { foreach (object item in list) { if (IsTextPropertyChanged(item, text)) SetPropertyValue(item, "Text", text); else removeList.Add(item); } } else { foreach (object item in list) { if (IsTextPropertyChanged(item, text)) SetTextProperty(item, text); else removeList.Add(item); } } foreach (object item in removeList) list.Remove(item); RecalcLayout(list); } finally { IsSyncingCommand = false; } } private bool IsTextPropertyChanged(object item, string text) { if (item is ComboBoxItem) { ComboBoxItem cb = item as ComboBoxItem; if (cb.DropDownStyle == ComboBoxStyle.DropDownList) { if (cb.SelectedItem is ComboBoxItem) return ((ComboBoxItem)cb.SelectedItem).Text != text; else if (cb.SelectedItem != null) return cb.SelectedItem.ToString() != text; return cb.ComboBoxEx.Text != text; } else return cb.Text != text; } else if (item is BaseItem) return ((BaseItem)item).Text != text; else if (item is TabItem) return ((TabItem)item).Text != text; else if (item is Control) return ((Control)item).Text != text; else return GetPropertyValue(item, "Text") != text; return true; } protected virtual void SetTextProperty(object item, string text) { if (item is ComboBoxItem) { ComboBoxItem cb = item as ComboBoxItem; if (cb.DropDownStyle == ComboBoxStyle.DropDownList) { if (cb.ComboBoxEx.Text != text) { if (text == "" || text == null) cb.SelectedIndex = -1; else cb.SelectedIndex = cb.ComboBoxEx.FindString(text); } } else cb.Text = text; } else if (item is BaseItem) ((BaseItem)item).Text = text; else if (item is TabItem) ((TabItem)item).Text = text; else if (item is Control) ((Control)item).Text = text; else SetPropertyValue(item, "Text", text); } private void RecalcLayout(ArrayList list) { if (!CommandManager.AutoUpdateLayout) return; ArrayList processedControls = new ArrayList(list.Count); foreach (object item in list) { if (item is BaseItem) { Control c = ((BaseItem)item).ContainerControl as Control; if (BarFunctions.IsHandleValid(c) && !processedControls.Contains(c)) { InvokeRecalcLayout(c); processedControls.Add(c); } } } } private void InvokeRecalcLayout(Control control) { if (control is Bar) ((Bar)control).RecalcLayout(); else if (control is RibbonBar && ((RibbonBar)control).Parent is RibbonPanel && !((RibbonPanel)((RibbonBar)control).Parent).DefaultLayout) { ((RibbonBar)control).RecalcLayout(); ((RibbonPanel)((RibbonBar)control).Parent).PerformLayout(); } else if (control is ItemControl) ((ItemControl)control).RecalcLayout(); else if (control is BaseItemControl) ((BaseItemControl)control).RecalcLayout(); else if (control is MenuPanel) ((MenuPanel)control).RecalcLayout(); else if (control is ExplorerBar) ((ExplorerBar)control).RecalcLayout(); else if (control is SideBar) ((SideBar)control).RecalcLayout(); } private bool GetDesignMode() { if (this.Site != null) return this.Site.DesignMode; return false; } protected virtual void SetPropertyValue(object item, string propertyName, object value) { if (!CommandManager.UseReflection) return; PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(item); PropertyDescriptor prop = properties.Find(propertyName, false); if (prop != null) prop.SetValue(item, value); } protected virtual object GetPropertyValue(object item, string propertyName) { if (!CommandManager.UseReflection) return null; PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(item); PropertyDescriptor prop = properties.Find(propertyName, false); if (prop != null) return prop.GetValue(item); return null; } /// /// Sets an property value on the subscribers through the reflection. If subscriber does not have /// specified property with value type its value is not set. /// /// Property name to set. /// Property value. public void SetValue(string propertyName, object value) { IsSyncingCommand = true; try { ArrayList list = GetSubscribers(); Type valueType = null; if (value != null) valueType = value.GetType(); ArrayList processedControls = new ArrayList(list.Count); foreach (object item in list) { PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(item); PropertyDescriptor prop = properties.Find(propertyName, false); if (prop != null && (valueType == null || prop.PropertyType == valueType)) { prop.SetValue(item, value); processedControls.Add(item); } } RecalcLayout(processedControls); } finally { IsSyncingCommand = false; } } private ArrayList GetSubscribers() { return CommandManager.GetSubscribers(this); } /// /// Gets whether property is set and whether it will be applied to items associated with the command. /// /// public bool ShouldSerializeText() { return _TextSet; } /// /// Resets the property to its default value and disables its propagation to items that are associated with command. /// public void ResetText() { _TextSet = false; _Text = null; } private bool _Checked = false; private bool _CheckedSet = false; /// /// Gets or sets the value for the Checked property that is assigned to the command subscribers using this command and have Checked property. /// [Description("Indicates value for the Checked property that is assigned to the command subscribers using this command and have Checked property.")] public bool Checked { get { return _Checked; } set { _Checked = value; _CheckedSet = true; OnCheckedChanged(); } } protected virtual void OnCheckedChanged() { SetCheckedProperty(); } protected virtual void SetCheckedProperty() { IsSyncingCommand = true; try { ArrayList list = GetSubscribers(); bool check = _Checked; foreach (object item in list) { SetCheckedProperty(item, check); } } finally { IsSyncingCommand = false; } } private bool _IsSyncingCommand = false; /// /// Gets whether the command is in process of syncing its state to all subscribers. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool IsSyncingCommand { get { return _IsSyncingCommand; } private set { _IsSyncingCommand = value; } } protected virtual void SetCheckedProperty(object item, bool check) { if (item is ButtonItem) ((ButtonItem)item).Checked = check; else if (item is ButtonX) ((ButtonX)item).Checked = check; else if (item is CheckBoxItem) ((CheckBoxItem)item).Checked = check; else if (item is SwitchButtonItem) ((SwitchButtonItem)item).Value = check; else SetPropertyValue(item, "Checked", check); } /// /// Gets whether property is set and whether it will be applied to items associated with the command. /// /// public bool ShouldSerializeChecked() { return _CheckedSet; } /// /// Resets the property to its default value and disables its propagation to items that are associated with command. /// public void ResetChecked() { _CheckedSet = false; _Checked = false; } private bool _Visible = false; private bool _VisibleSet = false; /// /// Gets or sets the value for the Visible property that is assigned to the command subscribers using this command and have Visible property. /// [Description("Indicates value for the Visible property that is assigned to the command subscribers using this command and have Visible property.")] public bool Visible { get { return _Visible; } set { _Visible = value; _VisibleSet = true; OnVisibleChanged(); } } protected virtual void OnVisibleChanged() { SetVisibleProperty(); } protected virtual void SetVisibleProperty() { ArrayList list = GetSubscribers(); bool visible = _Visible; foreach (object item in list) { SetVisibleProperty(item, visible); } } protected virtual void SetVisibleProperty(object item, bool visible) { ArrayList list = GetSubscribers(); if (this.DesignMode) SetPropertyValue(item, "Visible", visible); else { if (item is BaseItem) ((BaseItem)item).Visible = visible; else if (item is Control) ((Control)item).Visible = visible; else SetPropertyValue(item, "Visible", visible); } RecalcLayout(list); } /// /// Gets whether property is set and whether it will be applied to items associated with the command. /// /// public bool ShouldSerializeVisible() { return _VisibleSet; } /// /// Resets the property to its default value and disables its propagation to items that are associated with command. /// public void ResetVisible() { _VisibleSet = false; _Visible = false; } private Image _Image = null; private bool _ImageSet = false; /// /// Gets or sets the image that is assigned to the command subscribers using this command and have Image property. /// [Description("Indicates image that is assigned to the command subscribers using this command and have Image property."), Localizable(true)] public Image Image { get { return _Image; } set { _Image = value; _ImageSet = true; OnImageChanged(); } } protected virtual void OnImageChanged() { SetImageProperty(); } protected virtual void SetImageProperty() { IsSyncingCommand = true; try { ArrayList list = GetSubscribers(); Image image = _Image; if (this.GetDesignMode()) { foreach (object item in list) { if (item is ButtonItem) { ButtonItem button = item as ButtonItem; bool qatButton = false; if (button.ContainerControl is RibbonStrip) { RibbonStrip rs = button.ContainerControl as RibbonStrip; if (rs.Parent is RibbonControl && ((RibbonControl)rs.Parent).QuickToolbarItems.Contains(button)) qatButton = true; } else if (button.ContainerControl is Ribbon.QatToolbar) qatButton = true; if (qatButton && image != null && (image.Width > 16 || image.Height > 16)) { button.UseSmallImage = true; if (button.ImageSmall == null) TypeDescriptor.GetProperties(button)["ImageFixedSize"].SetValue(button, new Size(16, 16)); } } SetPropertyValue(item, "Image", image); } } else { foreach (object item in list) { SetImageProperty(item, image); } } RecalcLayout(list); } finally { IsSyncingCommand = false; } } protected virtual void SetImageProperty(object item, Image image) { if (item is ButtonItem) ((ButtonItem)item).Image = image; else if (item is ExplorerBarGroupItem) ((ExplorerBarGroupItem)item).Image = image; else if (item is LabelItem) ((LabelItem)item).Image = image; else if (item is SideBarPanelItem) ((SideBarPanelItem)item).Image = image; else if (item is TabItem) ((TabItem)item).Image = image; else if (item is ButtonX) ((ButtonX)item).Image = image; else if (item is LabelX) ((LabelX)item).Image = image; else if (item is DevComponents.DotNetBar.Controls.ReflectionImage) ((DevComponents.DotNetBar.Controls.ReflectionImage)item).Image = image; else if (item is BubbleButton) ((BubbleButton)item).Image = image; else SetPropertyValue(item, "Image", image); } /// /// Gets whether property is set and whether it will be applied to items associated with the command. /// /// public bool ShouldSerializeImage() { return _ImageSet; } /// /// Resets the property to its default value and disables its propagation to items that are associated with command. /// public void ResetImage() { _ImageSet = false; _Image = null; } private Image _ImageSmall = null; private bool _ImageSmallSet = false; /// /// Gets or sets the small image that is assigned to the command subscribers using this command and have ImageSmall property. /// [Description("Indicates small image that is assigned to the command subscribers using this command and have ImageSmall property."), Localizable(true)] public Image ImageSmall { get { return _ImageSmall; } set { _ImageSmall = value; _ImageSmallSet = true; OnImageSmallChanged(); } } protected virtual void OnImageSmallChanged() { SetImageSmallProperty(); } protected virtual void SetImageSmallProperty() { IsSyncingCommand = true; try { ArrayList list = GetSubscribers(); Image image = _ImageSmall; foreach (object item in list) { SetImageSmallProperty(item, image); } RecalcLayout(list); } finally { IsSyncingCommand = false; } } protected virtual void SetImageSmallProperty(object item, Image image) { if (item is ButtonItem) ((ButtonItem)item).ImageSmall = image; else SetPropertyValue(item, "ImageSmall", image); } /// /// Gets whether property is set and whether it will be applied to items associated with the command. /// /// public bool ShouldSerializeImageSmall() { return _ImageSmallSet; } /// /// Resets the property to its default value and disables its propagation to items that are associated with command. /// public void ResetImageSmall() { _ImageSmallSet = false; _ImageSmall = null; } private bool _Enabled = true; private bool _EnabledSet = false; /// /// Gets or sets the value for Enabled property assigned to the command subscribers using this command and have Enabled property. /// [Description("Indicates value for Enabled property assigned to the command subscribers using this command and have Enabled property.")] public bool Enabled { get { return _Enabled; } set { _Enabled = value; _EnabledSet = true; OnEnabledChanged(); } } protected virtual void OnEnabledChanged() { SetEnabledProperty(); } protected virtual void SetEnabledProperty() { IsSyncingCommand = true; try { ArrayList list = GetSubscribers(); bool enabled = _Enabled; foreach (object item in list) { SetEnabledProperty(item, enabled); } } finally { IsSyncingCommand = false; } } protected virtual void SetEnabledProperty(object item, bool enabled) { if (item is BaseItem) ((BaseItem)item).Enabled = enabled; else if (item is Control) ((Control)item).Enabled = enabled; else SetPropertyValue(item, "Enabled", enabled); } /// /// Gets whether property is set and whether it will be applied to items associated with the command. /// /// public bool ShouldSerializeEnabled() { return _EnabledSet; } /// /// Resets the property to its default value and disables its propagation to items that are associated with command. /// public void ResetEnabled() { _EnabledSet = false; _Enabled = false; } /// /// Called when CommandSource is registered for the command. /// /// CommandSource registered. public virtual void CommandSourceRegistered(ICommandSource source) { if (source == null || this.GetDesignMode()) return; if (_EnabledSet) SetEnabledProperty(source, _Enabled); if (_CheckedSet) SetCheckedProperty(source, _Checked); if(_ImageSet) SetImageProperty(source, _Image); if(_ImageSmallSet) SetImageSmallProperty(source, _ImageSmall); if(_TextSet) SetTextProperty(source, _Text); if (_VisibleSet) SetVisibleProperty(source, _Visible); } /// /// Called when CommandSource is unregistered for the command. /// /// CommandSource unregistered. public virtual void CommandSourceUnregistered(ICommandSource source) { } #endregion #region Component Implementation protected override void Dispose(bool disposing) { if(disposing) CommandManager.UnRegisterCommand(this); base.Dispose(disposing); } private string _Name = ""; /// /// Returns name of the node that can be used to identify it from the code. /// [Browsable(false), Category("Design"), Description("Indicates the name used to identify node.")] public string Name { get { if (this.Site != null) _Name = this.Site.Name; return _Name; } set { if (this.Site != null) this.Site.Name = value; if (value == null) _Name = ""; else _Name = value; } } #endregion } #endregion }