using System; using System.IO; using System.Drawing; using System.Reflection; using System.Collections; using System.Diagnostics; using System.Globalization; using System.CodeDom.Compiler; using System.Windows.Forms; using System.ComponentModel; using System.Drawing.Design; using System.Drawing.Drawing2D; using System.Collections.Generic; using System.Windows.Forms.Design; using System.ComponentModel.Design; using System.ComponentModel.Design.Serialization; using Microsoft.Win32; using System.Workflow.ComponentModel.Compiler; namespace System.Workflow.ComponentModel.Design { /// /// Summary description for ThemeConfigurationDialog. /// [Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")] public sealed class ThemeConfigurationDialog : System.Windows.Forms.Form { #region [....] Generated Members private System.Windows.Forms.Button button3; private System.Windows.Forms.TreeView designerTreeView; private System.Windows.Forms.Label themeNameLabel; private System.Windows.Forms.Label themeLocationLabel; private System.Windows.Forms.TextBox themeNameTextBox; private System.Windows.Forms.Panel themePanel; private System.Windows.Forms.Panel themeConfigPanel; private System.Windows.Forms.Panel dummyPreviewPanel; private System.Windows.Forms.TextBox themeLocationTextBox; private System.Windows.Forms.Label previewLabel; private System.Windows.Forms.Label selectDesignerLabel; private System.Windows.Forms.PropertyGrid propertiesGrid; private System.Windows.Forms.Button themeLocationButton; private System.Windows.Forms.Button okButton; private System.Windows.Forms.Button cancelButton; private System.Windows.Forms.Button previewButton; private System.ComponentModel.IContainer components = null; #endregion #region Member Variables private IServiceProvider serviceProvider; private bool previewShown = false; private WorkflowTheme bufferedTheme; private DesignerPreview designerPreview; private Splitter splitter; private TableLayoutPanel okCancelTableLayoutPanel; private TableLayoutPanel nameLocationTableLayoutPanel; private bool themeDirty = false; #endregion #region Constructor/Destructor public ThemeConfigurationDialog(IServiceProvider serviceProvider) : this(serviceProvider, null) { } public ThemeConfigurationDialog(IServiceProvider serviceProvider, WorkflowTheme theme) { if (serviceProvider == null) throw new ArgumentNullException("serviceProvider"); this.serviceProvider = serviceProvider; if (theme == null) { this.bufferedTheme = new WorkflowTheme(); this.themeDirty = true; } else { this.bufferedTheme = theme; this.themeDirty = false; } this.bufferedTheme.ReadOnly = false; InitializeComponent(); this.themeLocationButton.AutoSize = true; //Set dialog fonts Font = StandardFont; SystemEvents.UserPreferenceChanged += new UserPreferenceChangedEventHandler(OnOperatingSystemSettingsChanged); } /// /// Clean up any resources being used. /// protected override void Dispose(bool disposing) { if (disposing) { if (components != null) components.Dispose(); SystemEvents.UserPreferenceChanged -= new UserPreferenceChangedEventHandler(OnOperatingSystemSettingsChanged); if (this.designerPreview != null) { this.designerPreview.Dispose(); this.designerPreview = null; } if (this.bufferedTheme != null) { ((IDisposable)this.bufferedTheme).Dispose(); this.bufferedTheme = null; } } base.Dispose(disposing); } #endregion #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ThemeConfigurationDialog)); this.designerTreeView = new System.Windows.Forms.TreeView(); this.themeNameLabel = new System.Windows.Forms.Label(); this.themeLocationLabel = new System.Windows.Forms.Label(); this.themeNameTextBox = new System.Windows.Forms.TextBox(); this.nameLocationTableLayoutPanel = new System.Windows.Forms.TableLayoutPanel(); this.themeLocationButton = new System.Windows.Forms.Button(); this.themeLocationTextBox = new System.Windows.Forms.TextBox(); this.button3 = new System.Windows.Forms.Button(); this.okButton = new System.Windows.Forms.Button(); this.cancelButton = new System.Windows.Forms.Button(); this.themePanel = new System.Windows.Forms.Panel(); this.themeConfigPanel = new System.Windows.Forms.Panel(); this.propertiesGrid = new System.Windows.Forms.PropertyGrid(); this.previewLabel = new System.Windows.Forms.Label(); this.selectDesignerLabel = new System.Windows.Forms.Label(); this.dummyPreviewPanel = new System.Windows.Forms.Panel(); this.previewButton = new System.Windows.Forms.Button(); this.okCancelTableLayoutPanel = new System.Windows.Forms.TableLayoutPanel(); this.nameLocationTableLayoutPanel.SuspendLayout(); this.themePanel.SuspendLayout(); this.themeConfigPanel.SuspendLayout(); this.okCancelTableLayoutPanel.SuspendLayout(); this.SuspendLayout(); // // designerTreeView // resources.ApplyResources(this.designerTreeView, "designerTreeView"); this.designerTreeView.Name = "designerTreeView"; // // themeNameLabel // resources.ApplyResources(this.themeNameLabel, "themeNameLabel"); this.themeNameLabel.Margin = new System.Windows.Forms.Padding(0, 0, 3, 3); this.themeNameLabel.Name = "themeNameLabel"; // // themeLocationLabel // resources.ApplyResources(this.themeLocationLabel, "themeLocationLabel"); this.themeLocationLabel.Margin = new System.Windows.Forms.Padding(0, 3, 3, 0); this.themeLocationLabel.Name = "themeLocationLabel"; // // themeNameTextBox // resources.ApplyResources(this.themeNameTextBox, "themeNameTextBox"); this.nameLocationTableLayoutPanel.SetColumnSpan(this.themeNameTextBox, 2); this.themeNameTextBox.Margin = new System.Windows.Forms.Padding(3, 0, 0, 3); this.themeNameTextBox.Name = "themeNameTextBox"; // // nameLocationTableLayoutPanel // resources.ApplyResources(this.nameLocationTableLayoutPanel, "nameLocationTableLayoutPanel"); this.nameLocationTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); this.nameLocationTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); this.nameLocationTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); this.nameLocationTableLayoutPanel.Controls.Add(this.themeNameLabel, 0, 0); this.nameLocationTableLayoutPanel.Controls.Add(this.themeNameTextBox, 1, 0); this.nameLocationTableLayoutPanel.Controls.Add(this.themeLocationButton, 2, 1); this.nameLocationTableLayoutPanel.Controls.Add(this.themeLocationLabel, 0, 1); this.nameLocationTableLayoutPanel.Controls.Add(this.themeLocationTextBox, 1, 1); this.nameLocationTableLayoutPanel.Name = "nameLocationTableLayoutPanel"; this.nameLocationTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); this.nameLocationTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); // // themeLocationButton // resources.ApplyResources(this.themeLocationButton, "themeLocationButton"); this.themeLocationButton.Margin = new System.Windows.Forms.Padding(3, 3, 0, 0); this.themeLocationButton.Name = "themeLocationButton"; // // themeLocationTextBox // resources.ApplyResources(this.themeLocationTextBox, "themeLocationTextBox"); this.themeLocationTextBox.Margin = new System.Windows.Forms.Padding(3, 3, 3, 0); this.themeLocationTextBox.Name = "themeLocationTextBox"; // // button3 // resources.ApplyResources(this.button3, "button3"); this.button3.Name = "button3"; // // okButton // resources.ApplyResources(this.okButton, "okButton"); this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK; this.okButton.Margin = new System.Windows.Forms.Padding(0, 0, 3, 0); this.okButton.Name = "okButton"; // // cancelButton // resources.ApplyResources(this.cancelButton, "cancelButton"); this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.cancelButton.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0); this.cancelButton.Name = "cancelButton"; // // themePanel // this.themePanel.Controls.Add(this.themeConfigPanel); this.themePanel.Controls.Add(this.previewLabel); this.themePanel.Controls.Add(this.selectDesignerLabel); this.themePanel.Controls.Add(this.dummyPreviewPanel); resources.ApplyResources(this.themePanel, "themePanel"); this.themePanel.Margin = new System.Windows.Forms.Padding(4); this.themePanel.Name = "themePanel"; // // themeConfigPanel // this.themeConfigPanel.Controls.Add(this.designerTreeView); this.themeConfigPanel.Controls.Add(this.propertiesGrid); resources.ApplyResources(this.themeConfigPanel, "themeConfigPanel"); this.themeConfigPanel.Name = "themeConfigPanel"; // // propertiesGrid // this.propertiesGrid.CommandsVisibleIfAvailable = true; resources.ApplyResources(this.propertiesGrid, "propertiesGrid"); this.propertiesGrid.Name = "propertiesGrid"; this.propertiesGrid.ToolbarVisible = false; // // previewLabel // resources.ApplyResources(this.previewLabel, "previewLabel"); this.previewLabel.Name = "previewLabel"; // // selectDesignerLabel // resources.ApplyResources(this.selectDesignerLabel, "selectDesignerLabel"); this.selectDesignerLabel.Name = "selectDesignerLabel"; // // dummyPreviewPanel // resources.ApplyResources(this.dummyPreviewPanel, "dummyPreviewPanel"); this.dummyPreviewPanel.Name = "dummyPreviewPanel"; // // previewButton // resources.ApplyResources(this.previewButton, "previewButton"); this.previewButton.Margin = new System.Windows.Forms.Padding(3, 0, 0, 0); this.previewButton.Name = "previewButton"; // // okCancelTableLayoutPanel // resources.ApplyResources(this.okCancelTableLayoutPanel, "okCancelTableLayoutPanel"); this.okCancelTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33F)); this.okCancelTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33F)); this.okCancelTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33F)); this.okCancelTableLayoutPanel.Controls.Add(this.okButton, 0, 0); this.okCancelTableLayoutPanel.Controls.Add(this.cancelButton, 1, 0); this.okCancelTableLayoutPanel.Controls.Add(this.previewButton, 2, 0); this.okCancelTableLayoutPanel.Name = "okCancelTableLayoutPanel"; this.okCancelTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); // // ThemeConfigurationDialog // this.AcceptButton = this.okButton; this.CancelButton = this.cancelButton; resources.ApplyResources(this, "$this"); this.Controls.Add(this.nameLocationTableLayoutPanel); this.Controls.Add(this.okCancelTableLayoutPanel); this.Controls.Add(this.themePanel); this.Controls.Add(this.button3); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "ThemeConfigurationDialog"; this.ShowInTaskbar = false; this.HelpButton = true; this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; this.nameLocationTableLayoutPanel.ResumeLayout(false); this.nameLocationTableLayoutPanel.PerformLayout(); this.themePanel.ResumeLayout(false); this.themeConfigPanel.ResumeLayout(false); this.okCancelTableLayoutPanel.ResumeLayout(false); this.okCancelTableLayoutPanel.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); } #endregion #region Properties and Methods public WorkflowTheme ComposedTheme { get { return this.bufferedTheme; } } protected override void OnLoad(EventArgs e) { base.OnLoad(e); try { Cursor.Current = Cursors.WaitCursor; InitializeControls(); } finally { Cursor.Current = Cursors.Default; } } protected override void OnClosing(CancelEventArgs e) { base.OnClosing(e); this.bufferedTheme.ReadOnly = true; } #endregion #region Helper Functions private Font StandardFont { get { Font font = SystemInformation.MenuFont; if (this.serviceProvider != null) { IUIService uisvc = (IUIService)this.serviceProvider.GetService(typeof(IUIService)); if (uisvc != null) font = (Font)uisvc.Styles["DialogFont"]; } return font; } } private void InitializeControls() { HelpButtonClicked += new CancelEventHandler(OnHelpClicked); this.themeNameTextBox.Text = this.bufferedTheme.Name; this.themeLocationTextBox.Text = this.bufferedTheme.FilePath; this.propertiesGrid.PropertySort = PropertySort.Categorized; //Make sure that size and location are changed after adding the control to the parent //this will autoscale the control correctly this.designerPreview = new DesignerPreview(this); this.dummyPreviewPanel.Parent.Controls.Add(this.designerPreview); this.designerPreview.TabStop = false; this.designerPreview.Location = this.dummyPreviewPanel.Location; this.designerPreview.Size = this.dummyPreviewPanel.Size; this.dummyPreviewPanel.Visible = false; this.designerPreview.Parent.Controls.Remove(this.dummyPreviewPanel); this.designerTreeView.ShowLines = false; this.designerTreeView.ShowPlusMinus = false; this.designerTreeView.ShowRootLines = false; this.designerTreeView.ShowNodeToolTips = true; this.designerTreeView.HideSelection = false; this.designerTreeView.ItemHeight = Math.Max(this.designerTreeView.ItemHeight, 18); ThemeConfigHelpers.PopulateActivities(this.serviceProvider, this.designerTreeView); this.themeConfigPanel.Controls.Remove(this.designerTreeView); this.themeConfigPanel.Controls.Remove(this.propertiesGrid); this.designerTreeView.Dock = DockStyle.Left; this.splitter = new Splitter(); this.splitter.Dock = DockStyle.Left; this.propertiesGrid.Dock = DockStyle.Fill; this.themeConfigPanel.Controls.AddRange(new Control[] { this.propertiesGrid, this.splitter, this.designerTreeView }); this.themePanel.Paint += new PaintEventHandler(OnThemePanelPaint); this.previewButton.Click += new EventHandler(OnPreviewClicked); this.designerTreeView.AfterSelect += new TreeViewEventHandler(OnDesignerSelectionChanged); this.themeLocationButton.Click += new EventHandler(OnThemeLocationClicked); this.okButton.Click += new EventHandler(OnOk); this.propertiesGrid.PropertyValueChanged += new PropertyValueChangedEventHandler(OnThemePropertyChanged); this.themeNameTextBox.TextChanged += new EventHandler(OnThemeChanged); this.themeLocationTextBox.TextChanged += new EventHandler(OnThemeChanged); this.designerTreeView.SelectedNode = (this.designerTreeView.Nodes.Count > 0) ? this.designerTreeView.Nodes[0] : null; this.designerTreeView.SelectedNode.EnsureVisible(); ShowPreview = true; } private void OnThemeChanged(object sender, EventArgs e) { this.themeDirty = true; } private void OnThemePropertyChanged(object sender, PropertyValueChangedEventArgs e) { this.themeDirty = true; } private bool ValidateControls(out string error, out Control control) { error = String.Empty; control = null; if (this.themeNameTextBox.Text == null || this.themeNameTextBox.Text.Trim().Length == 0) { error = DR.GetString(DR.ThemeNameNotValid); control = this.themeNameTextBox; return false; } if (this.themeLocationTextBox.Text == null) { error = DR.GetString(DR.ThemePathNotValid); control = this.themeNameTextBox; return false; } string path = this.themeLocationTextBox.Text.Trim(); if (path.IndexOfAny(Path.GetInvalidPathChars()) >= 0 || !Path.IsPathRooted(path) || !Path.HasExtension(path)) { error = DR.GetString(DR.ThemePathNotValid); control = this.themeLocationTextBox; return false; } string fileName = Path.GetFileNameWithoutExtension(path); string extension = Path.GetExtension(path); if (fileName == null || fileName.Trim().Length == 0 || extension == null || extension.Trim().Length == 0) { error = DR.GetString(DR.ThemePathNotValid); control = this.themeLocationTextBox; return false; } if (!extension.Equals(WorkflowTheme.DefaultThemeFileExtension.Replace("*", ""), StringComparison.Ordinal)) { error = DR.GetString(DR.ThemeFileNotXml); control = this.themeLocationTextBox; return false; } return true; } private void OnOk(object sender, EventArgs e) { string error = String.Empty; Control control = null; if (!ValidateControls(out error, out control)) { DialogResult = DialogResult.None; DesignerHelpers.ShowError(this.serviceProvider, error); if (control != null) { TextBox textBox = control as TextBox; if (textBox != null) { textBox.SelectionStart = 0; textBox.SelectionLength = (textBox.Text != null) ? textBox.Text.Length : 0; } control.Focus(); } return; } //Before we try saving show the warning if the user has changed the theme path if (!this.bufferedTheme.FilePath.Equals(this.themeLocationTextBox.Text.Trim(), StringComparison.OrdinalIgnoreCase)) { if (DialogResult.No == DesignerHelpers.ShowMessage(this.serviceProvider, DR.GetString(DR.UpdateRelativePaths), DR.GetString(DR.WorkflowDesignerTitle), MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1)) { DialogResult = DialogResult.None; return; } } if (this.themeDirty) { try { Cursor.Current = Cursors.WaitCursor; ThemeConfigHelpers.EnsureDesignerThemes(this.serviceProvider, this.bufferedTheme, ThemeConfigHelpers.GetAllTreeNodes(this.designerTreeView)); this.bufferedTheme.ReadOnly = false; this.bufferedTheme.Name = this.themeNameTextBox.Text.Trim(); this.bufferedTheme.Description = DR.GetString(DR.ThemeDescription); this.bufferedTheme.Save(this.themeLocationTextBox.Text.Trim()); this.themeDirty = false; this.bufferedTheme.ReadOnly = true; } catch { DesignerHelpers.ShowError(this.serviceProvider, DR.GetString(DR.ThemeFileCreationError)); this.themeLocationTextBox.SelectionStart = 0; this.themeLocationTextBox.SelectionLength = (this.themeLocationTextBox.Text != null) ? this.themeLocationTextBox.Text.Length : 0; this.themeLocationTextBox.Focus(); DialogResult = DialogResult.None; } finally { Cursor.Current = Cursors.Default; } } } private void OnHelpClicked(object sender, CancelEventArgs e) { e.Cancel = true; ShowHelp(); } protected override void OnHelpRequested(HelpEventArgs e) { ShowHelp(); e.Handled = true; } private void ShowHelp() { DesignerHelpers.ShowHelpFromKeyword(this.serviceProvider, typeof(ThemeConfigurationDialog).FullName + ".UI"); } private void OnThemePanelPaint(object sender, PaintEventArgs e) { e.Graphics.DrawRectangle(SystemPens.ControlDark, 0, 0, this.themePanel.ClientSize.Width - 1, this.themePanel.ClientSize.Height - 2); if (this.previewShown) { Point top = new Point(this.propertiesGrid.Right + (this.dummyPreviewPanel.Left - this.propertiesGrid.Right) / 2, this.themePanel.Margin.Top); Point bottom = new Point(top.X, this.themePanel.Height - this.themePanel.Margin.Bottom); e.Graphics.DrawLine(SystemPens.ControlDark, top, bottom); } Size margin = new Size(8, 8); using (Pen framePen = new Pen(Color.Black, 1)) { framePen.DashStyle = DashStyle.Dot; e.Graphics.DrawLine(framePen, this.designerPreview.Left - margin.Width, this.designerPreview.Top - 1, this.designerPreview.Right + margin.Width, this.designerPreview.Top - 1); e.Graphics.DrawLine(framePen, this.designerPreview.Left - margin.Width, this.designerPreview.Bottom + 1, this.designerPreview.Right + margin.Width, this.designerPreview.Bottom + 1); e.Graphics.DrawLine(framePen, this.designerPreview.Left - 1, this.designerPreview.Top - margin.Height, this.designerPreview.Left - 1, this.designerPreview.Bottom + margin.Height); e.Graphics.DrawLine(framePen, this.designerPreview.Right + 1, this.designerPreview.Top - margin.Height, this.designerPreview.Right + 1, this.designerPreview.Bottom + margin.Height); } } private void OnDesignerSelectionChanged(object sender, TreeViewEventArgs eventArgs) { //We need to select the theme of the selected designer Type activityType = (eventArgs.Node != null && typeof(Activity).IsAssignableFrom(eventArgs.Node.Tag as System.Type)) ? eventArgs.Node.Tag as System.Type : null; IDesigner previewedDesigner = this.designerPreview.UpdatePreview(activityType); object[] selectedObjects = null; if (activityType == null) { if (eventArgs.Node != null) selectedObjects = (eventArgs.Node.Parent == null) ? new object[] { this.bufferedTheme.AmbientTheme } : ThemeConfigHelpers.GetDesignerThemes(this.serviceProvider, this.bufferedTheme, eventArgs.Node); } else { selectedObjects = (previewedDesigner != null) ? new object[] { this.bufferedTheme.GetDesignerTheme(previewedDesigner as ActivityDesigner) } : null; } this.propertiesGrid.SelectedObjects = selectedObjects; } private void OnPreviewClicked(object sender, EventArgs e) { ShowPreview = !ShowPreview; } private void OnThemeLocationClicked(object sender, EventArgs e) { SaveFileDialog fileDialog = new SaveFileDialog(); fileDialog.AddExtension = true; fileDialog.DefaultExt = WorkflowTheme.DefaultThemeFileExtension; fileDialog.Filter = DR.GetString(DR.ThemeFileFilter); fileDialog.RestoreDirectory = false; if (fileDialog.ShowDialog(this) == DialogResult.OK) { this.themeLocationTextBox.Text = fileDialog.FileName; } } private bool ShowPreview { get { return this.previewShown; } set { this.previewShown = value; this.previewLabel.Visible = this.previewShown; this.designerPreview.Visible = this.previewShown; if (this.previewShown) { this.themePanel.Width = this.designerPreview.Right + ((this.designerPreview.Left - this.propertiesGrid.Right) / 2); this.previewButton.Text = DR.GetString(DR.Preview) + " <<"; } else { this.themePanel.Width = this.themeConfigPanel.Right + this.themeConfigPanel.Left; this.previewButton.Text = DR.GetString(DR.Preview) + " >>"; } Width = this.themePanel.Right + this.themePanel.Left + Margin.Left + Margin.Right; this.themePanel.Invalidate(); } } private void OnOperatingSystemSettingsChanged(object sender, UserPreferenceChangedEventArgs e) { // if (e.Category == UserPreferenceCategory.Color || e.Category == UserPreferenceCategory.VisualStyle) Font = StandardFont; } #endregion #region Class ThemeHelpers private static class ThemeConfigHelpers { internal static void PopulateActivities(IServiceProvider serviceProvider, TreeView treeView) { List activityTypes = new List(); //***************STOCK TYPES************* List stockActivityTypeNames = new List(); stockActivityTypeNames.Add(DesignerHelpers.SequentialWorkflowTypeRef); stockActivityTypeNames.Add(DesignerHelpers.StateMachineWorkflowTypeRef); stockActivityTypeNames.Add(DesignerHelpers.IfElseBranchTypeRef); stockActivityTypeNames.Add(typeof(FaultHandlersActivity).AssemblyQualifiedName); stockActivityTypeNames.Add(DesignerHelpers.EventHandlersTypeRef); stockActivityTypeNames.Add(typeof(CompensationHandlerActivity).AssemblyQualifiedName); stockActivityTypeNames.Add(typeof(CancellationHandlerActivity).AssemblyQualifiedName); foreach (string stockTypeName in stockActivityTypeNames) { Type stockType = Type.GetType(stockTypeName, false); if (stockType == null) Debug.Assert(false, string.Format(CultureInfo.CurrentCulture, "Could not load type '{0}'", stockTypeName)); else activityTypes.Add(stockType); } //***************NON PREVIWABLE DESIGNER TYPES************* IList nonpreviewableDesignerTypes = new List(); //These designer might be designers such as CADesigner which we eliminated //We have just kept the code so that in future if this functionality is needed //we can add it //Populate the designer combobox treeView.BeginUpdate(); treeView.Nodes.Clear(); //Work around: ***WE DISPLAY THE COMMON PROPERTIES FOR WORKFLOW AND APPLY THEM RECURSIVELY TO DESIGNERS TreeNode workflowNode = new TreeNode(DR.GetString(DR.WorkflowDesc)); treeView.Nodes.Add(workflowNode); //Now we go thru the toolbox items and get all the items which are not in our assembly IToolboxService toolboxService = serviceProvider.GetService(typeof(IToolboxService)) as IToolboxService; ITypeProviderCreator typeProviderCreator = serviceProvider.GetService(typeof(ITypeProviderCreator)) as ITypeProviderCreator; if (toolboxService != null && typeProviderCreator != null) { ToolboxItemCollection toolboxItems = toolboxService.GetToolboxItems(); foreach (ToolboxItem toolboxItem in toolboxItems) { bool customWinOEActivityType = (toolboxItem is ActivityToolboxItem); if (!customWinOEActivityType) { foreach (ToolboxItemFilterAttribute filter in toolboxItem.Filter) { if (filter.FilterString.StartsWith("Microsoft.Workflow.VSDesigner", StringComparison.OrdinalIgnoreCase) || filter.FilterString.StartsWith("System.Workflow.ComponentModel", StringComparison.OrdinalIgnoreCase)) { customWinOEActivityType = true; break; } } } if (customWinOEActivityType) { Type type = null; Assembly assembly = typeProviderCreator.GetTransientAssembly(toolboxItem.AssemblyName); if (assembly != null) type = assembly.GetType(toolboxItem.TypeName); if (type != null) { ConstructorInfo[] constructors = type.GetConstructors(); foreach (ConstructorInfo constructor in constructors) { if (constructor.IsPublic && constructor.GetParameters().GetLength(0) == 0) activityTypes.Add(type); } } } } } foreach (Type type in activityTypes) { Type designerBaseType = (type.FullName.Equals(DesignerHelpers.SequentialWorkflowTypeRef, StringComparison.OrdinalIgnoreCase)) ? typeof(IRootDesigner) : typeof(IDesigner); Type designerType = ActivityDesigner.GetDesignerType(serviceProvider, type, designerBaseType); if (designerType != null && !nonpreviewableDesignerTypes.Contains(designerType)) { object[] attribs = designerType.GetCustomAttributes(typeof(ActivityDesignerThemeAttribute), true); ActivityDesignerThemeAttribute themeAttrib = (attribs != null && attribs.GetLength(0) > 0) ? attribs[0] as ActivityDesignerThemeAttribute : null; if (themeAttrib != null) { Image image = ActivityToolboxItem.GetToolboxImage(type); if (treeView.ImageList == null) { treeView.ImageList = new ImageList(); treeView.ImageList.ColorDepth = ColorDepth.Depth32Bit; Image standardImage = DR.GetImage(DR.Activity) as Image; treeView.ImageList.Images.Add(standardImage, AmbientTheme.TransparentColor); } TreeNode parentNode = ThemeConfigHelpers.GetCatagoryNodeForDesigner(designerType, ThemeConfigHelpers.GetAllTreeNodes(treeView)); if (parentNode != null) { int imageIndex = (image != null) ? treeView.ImageList.Images.Add(image, AmbientTheme.TransparentColor) : 0; TreeNode nodeToInsert = (imageIndex >= 0) ? new TreeNode(ActivityToolboxItem.GetToolboxDisplayName(type), imageIndex, imageIndex) : new TreeNode(ActivityToolboxItem.GetToolboxDisplayName(type)); nodeToInsert.Tag = type; //We always make sure that cata----es are at the end int index = parentNode.Nodes.Count - 1; while (index >= 0 && parentNode.Nodes[index].Tag is System.Type) index = index - 1; parentNode.Nodes.Insert(index, nodeToInsert); } } } } treeView.TreeViewNodeSorter = new ThemeTreeNodeComparer(); treeView.Sort(); treeView.Nodes[0].ExpandAll(); treeView.EndUpdate(); } internal static TreeNode GetCatagoryNodeForDesigner(Type designerType, TreeNode[] treeNodes) { if (designerType == null) throw new ArgumentNullException("designerType"); if (treeNodes == null) throw new ArgumentNullException("treeNodes"); if (treeNodes.Length == 0) throw new ArgumentException(SR.GetString(SR.Error_InvalidArgumentValue), "treeNodes"); CategoryAttribute parentCatagoryAttribute = null; CategoryAttribute designerCatagoryAttribute = null; Type baseType = designerType; while (baseType != typeof(object) && parentCatagoryAttribute == null) { object[] attribs = baseType.GetCustomAttributes(typeof(CategoryAttribute), false); if (attribs != null && attribs.GetLength(0) > 0) { if (designerCatagoryAttribute == null) designerCatagoryAttribute = attribs[0] as CategoryAttribute; else parentCatagoryAttribute = attribs[0] as CategoryAttribute; } baseType = baseType.BaseType; } if (designerCatagoryAttribute == null) return null; //Search for the catagory TreeNode catagoryNode = null; TreeNode parentCatagoryTreeNode = treeNodes[0]; foreach (TreeNode item in treeNodes) { if (parentCatagoryAttribute != null && parentCatagoryAttribute.Category == item.Text && (item.Tag == null || !typeof(Activity).IsAssignableFrom(item.Tag.GetType()))) parentCatagoryTreeNode = item; //We found the catagory if (designerCatagoryAttribute.Category == item.Text && (item.Tag == null || !typeof(Activity).IsAssignableFrom(item.Tag.GetType()))) { catagoryNode = item; break; } } if (catagoryNode == null) { Debug.Assert(parentCatagoryTreeNode != null); if (parentCatagoryTreeNode != null) { //Work around : ***WE DISPLAY THE COMMON PROPERTIES FROM KNOWN DESIGNERCATA----ES //WE WILL EVENTUALLY REMOVE THIS WHEN WE CREATE AN MECHANISM TO SHARE COMMON //PROPERTIES IN THEMES catagoryNode = new TreeNode(designerCatagoryAttribute.Category); parentCatagoryTreeNode.Nodes.Add(catagoryNode); } } return catagoryNode; } internal static DesignerTheme[] GetDesignerThemes(IServiceProvider serviceProvider, WorkflowTheme workflowTheme, TreeNode selectedNode) { ArrayList designerThemes = new ArrayList(); Queue nodes = new Queue(); nodes.Enqueue(selectedNode); while (nodes.Count > 0) { TreeNode treeNode = nodes.Dequeue(); Type activityType = treeNode.Tag as System.Type; if (activityType != null) { Type designerBaseType = (activityType.FullName.Equals(DesignerHelpers.SequentialWorkflowTypeRef, StringComparison.OrdinalIgnoreCase)) ? typeof(IRootDesigner) : typeof(IDesigner); Type designerType = ActivityDesigner.GetDesignerType(serviceProvider, activityType, designerBaseType); if (designerType != null) { DesignerTheme designerTheme = workflowTheme.GetTheme(designerType); if (designerTheme != null) designerThemes.Add(designerTheme); } } else { foreach (TreeNode childNode in treeNode.Nodes) nodes.Enqueue(childNode); } } return ((DesignerTheme[])designerThemes.ToArray(typeof(DesignerTheme))); } internal static TreeNode[] GetAllTreeNodes(TreeView treeView) { List items = new List(); Queue nodeCollections = new Queue(); nodeCollections.Enqueue(treeView.Nodes); while (nodeCollections.Count > 0) { TreeNodeCollection nodeCollection = nodeCollections.Dequeue(); foreach (TreeNode treeNode in nodeCollection) { items.Add(treeNode); if (treeNode.Nodes.Count > 0) nodeCollections.Enqueue(treeNode.Nodes); } } return items.ToArray(); } internal static void EnsureDesignerThemes(IServiceProvider serviceProvider, WorkflowTheme workflowTheme, TreeNode[] items) { //We need to recurse thru the themes and make sure that we have all the designer themes created foreach (TreeNode item in items) { DesignerTheme designerTheme = null; Type activityType = item.Tag as Type; if (activityType != null) { Type designerBaseType = (activityType.FullName.Equals(DesignerHelpers.SequentialWorkflowTypeRef, StringComparison.OrdinalIgnoreCase)) ? typeof(IRootDesigner) : typeof(IDesigner); Type designerType = ActivityDesigner.GetDesignerType(serviceProvider, activityType, designerBaseType); if (designerType != null) designerTheme = workflowTheme.GetTheme(designerType); } } } } #endregion #region Class ThemeTreeNodeComparer internal sealed class ThemeTreeNodeComparer : IComparer { #region IComparer Members int IComparer.Compare(object x, object y) { TreeNode treeNode1 = x as TreeNode; TreeNode treeNode2 = y as TreeNode; if (treeNode1.Nodes.Count > treeNode2.Nodes.Count) return 1; else return String.Compare(treeNode1.Text, treeNode2.Text, StringComparison.CurrentCulture); } #endregion } #endregion #region Class DesignerPreview internal sealed class DesignerPreview : UserControl { private ThemeConfigurationDialog parent = null; private PreviewDesignSurface surface = null; internal DesignerPreview(ThemeConfigurationDialog parent) { BackColor = Color.White; this.parent = parent; } protected override void OnLoad(EventArgs e) { base.OnLoad(e); SuspendLayout(); this.surface = new PreviewDesignSurface(this.parent.serviceProvider); PreviewWorkflowDesignerLoader loader = new PreviewWorkflowDesignerLoader(); this.surface.BeginLoad(loader); //Add the root activity IDesignerHost host = this.surface.GetService(typeof(IDesignerHost)) as IDesignerHost; Debug.Assert(host != null); // Activity rootDecl = host.CreateComponent(Type.GetType(DesignerHelpers.SequentialWorkflowTypeRef)) as Activity; rootDecl.Name = "ThemeSequentialWorkflow"; WorkflowDesignerLoader.AddActivityToDesigner(this.surface, rootDecl as Activity); //Create the readonly workflow ReadonlyWorkflow workflowView = new ReadonlyWorkflow(this.parent, this.surface as IServiceProvider); workflowView.TabStop = false; workflowView.Dock = DockStyle.Fill; Controls.Add(workflowView); host.Activate(); ResumeLayout(true); } protected override void Dispose(bool disposing) { if (disposing && this.surface != null) { IDesignerHost host = GetService(typeof(IDesignerHost)) as IDesignerHost; if (host != null && host.RootComponent != null) WorkflowDesignerLoader.RemoveActivityFromDesigner(this.surface, host.RootComponent as Activity); ReadonlyWorkflow workflowView = (Controls.Count > 0) ? Controls[0] as ReadonlyWorkflow : null; Controls.Clear(); if (workflowView != null) { workflowView.Dispose(); workflowView = null; } this.surface.Dispose(); this.surface = null; } base.Dispose(disposing); } internal IDesigner UpdatePreview(Type activityType) { bool dummyPreview = false; //if we have a dummy preview activity IDesignerHost host = this.surface.GetService(typeof(IDesignerHost)) as IDesignerHost; Debug.Assert(host != null); CompositeActivity rootDecl = host.RootComponent as CompositeActivity; Debug.Assert(rootDecl != null); if (host == null || rootDecl == null) return null; IComponent previewActivity = null; try { //Remove earlier activities while (rootDecl.Activities.Count > 0) { Activity declToDelete = rootDecl.Activities[0]; rootDecl.Activities.Remove(declToDelete); WorkflowDesignerLoader.RemoveActivityFromDesigner(this.surface, declToDelete); } //Add new activities to preview if (activityType == null || activityType.FullName.Equals(DesignerHelpers.SequentialWorkflowTypeRef, StringComparison.OrdinalIgnoreCase)) { AddDummyActivity(rootDecl as CompositeActivity, Type.GetType(DesignerHelpers.CodeActivityTypeRef)); dummyPreview = true; } else { IComponent[] components = null; object[] attribs = activityType.GetCustomAttributes(typeof(ToolboxItemAttribute), false); ToolboxItemAttribute toolboxItemAttrib = (attribs != null && attribs.GetLength(0) > 0) ? attribs[0] as ToolboxItemAttribute : null; if (toolboxItemAttrib != null && toolboxItemAttrib.ToolboxItemType != null && typeof(ActivityToolboxItem).IsAssignableFrom(toolboxItemAttrib.ToolboxItemType)) { ActivityToolboxItem item = Activator.CreateInstance(toolboxItemAttrib.ToolboxItemType, new object[] { activityType }) as ActivityToolboxItem; components = item.CreateComponents(host); } if (components == null) components = new IComponent[] { Activator.CreateInstance(activityType) as IComponent }; Activity activity = (components != null && components.Length > 0) ? components[0] as Activity : null; if (activity != null) { rootDecl.Activities.Add(activity); EnsureUniqueId(activity); WorkflowDesignerLoader.AddActivityToDesigner(this.surface, activity); CompositeActivityDesigner compositeDesigner = host.GetDesigner(rootDecl) as CompositeActivityDesigner; ActivityDesigner activityDesigner = host.GetDesigner(activity) as ActivityDesigner; if (compositeDesigner != null && activityDesigner != null) compositeDesigner.EnsureVisibleContainedDesigner(activityDesigner); /* // */ } } ISelectionService selectionService = host.GetService(typeof(ISelectionService)) as ISelectionService; if (selectionService != null) selectionService.SetSelectedComponents(new IComponent[] { rootDecl }); ReadonlyWorkflow workflowView = (Controls.Count > 0) ? Controls[0] as ReadonlyWorkflow : null; if (workflowView != null) workflowView.PerformLayout(); previewActivity = (rootDecl.Activities.Count > 0 && !dummyPreview) ? rootDecl.Activities[0] : rootDecl; } catch { } return (previewActivity != null) ? host.GetDesigner(previewActivity) : null; } private void AddDummyActivity(CompositeActivity parentActivity, Type activityType) { IDesignerHost host = this.surface.GetService(typeof(IDesignerHost)) as IDesignerHost; Debug.Assert(host != null); if (host == null) return; Activity dummyActivity = Activator.CreateInstance(activityType) as Activity; Debug.Assert(dummyActivity != null); if (dummyActivity == null) return; parentActivity.Activities.Add(dummyActivity); EnsureUniqueId(dummyActivity); WorkflowDesignerLoader.AddActivityToDesigner(this.surface, dummyActivity); } private void EnsureUniqueId(Activity addedActivity) { Dictionary identifiers = new Dictionary(); Queue Activities = new Queue(); Activities.Enqueue(addedActivity); while (Activities.Count > 0) { Activity Activity = Activities.Dequeue(); string fullTypeName = Activity.GetType().FullName; int id = (identifiers.ContainsKey(fullTypeName)) ? identifiers[fullTypeName] : 1; Activity.Name = Activity.GetType().Name + id.ToString(CultureInfo.InvariantCulture); id += 1; if (identifiers.ContainsKey(fullTypeName)) identifiers[fullTypeName] = id; else identifiers.Add(fullTypeName, id); CompositeActivity compositeActivity = Activity as CompositeActivity; if (compositeActivity != null) { foreach (Activity activity in compositeActivity.Activities) Activities.Enqueue(activity); } } } #region Class PreviewDesignSurface private sealed class PreviewDesignSurface : DesignSurface { internal PreviewDesignSurface(IServiceProvider parentProvider) : base(new PreviewDesignerServiceProvider(parentProvider)) { ITypeProvider typeProvider = GetService(typeof(ITypeProvider)) as ITypeProvider; if (typeProvider == null) { TypeProvider provider = new TypeProvider(this); provider.AddAssemblyReference(typeof(string).Assembly.Location); ServiceContainer.AddService(typeof(ITypeProvider), provider, true); } } protected override IDesigner CreateDesigner(IComponent component, bool rootDesigner) { IDesigner designer = base.CreateDesigner(component, rootDesigner); Activity activity = component as Activity; if (designer == null && !rootDesigner && activity != null) designer = ActivityDesigner.CreateDesigner(activity.Site, activity); return designer; } #region Class PreviewDesignerServiceProvider private sealed class PreviewDesignerServiceProvider : IServiceProvider { private IServiceProvider serviceProvider; internal PreviewDesignerServiceProvider(IServiceProvider serviceProvider) { this.serviceProvider = serviceProvider; } #region IServiceProvider Members object IServiceProvider.GetService(Type serviceType) { if (serviceType == typeof(IPropertyValueUIService)) return null; return this.serviceProvider.GetService(serviceType); } #endregion } #endregion } #endregion #region Class PreviewWorkflowDesignerLoader private class PreviewWorkflowDesignerLoader : WorkflowDesignerLoader { public override TextReader GetFileReader(string filePath) { return null; } public override TextWriter GetFileWriter(string filePath) { return null; } public override string FileName { get { return String.Empty; } } } #endregion #region Class ReadOnly Workflow private class ReadonlyWorkflow : WorkflowView { private ThemeConfigurationDialog themeConfigDialog = null; internal ReadonlyWorkflow(ThemeConfigurationDialog themeConfigDialog, IServiceProvider serviceProvider) : base(serviceProvider) { this.themeConfigDialog = themeConfigDialog; this.themeConfigDialog.propertiesGrid.PropertyValueChanged += new PropertyValueChangedEventHandler(OnThemePropertyChanged); this.EnableFitToScreen = false; AddDesignerMessageFilter(new ReadonlyMessageFilter()); } protected override void Dispose(bool disposing) { base.Dispose(disposing); if (this.themeConfigDialog != null && this.themeConfigDialog.propertiesGrid != null) this.themeConfigDialog.propertiesGrid.PropertyValueChanged -= new PropertyValueChangedEventHandler(OnThemePropertyChanged); } protected override void OnPaint(PaintEventArgs e) { if (this.themeConfigDialog == null) { base.OnPaint(e); return; } using (BufferedTheme bufferedTheme = new BufferedTheme(this.themeConfigDialog.bufferedTheme)) base.OnPaint(e); } protected override void OnLayout(LayoutEventArgs levent) { if (this.themeConfigDialog != null) { using (BufferedTheme bufferedTheme = new BufferedTheme(this.themeConfigDialog.bufferedTheme)) base.OnLayout(levent); Size maxExtent = ActiveLayout.Extent; Size size = Size; PointF zoom = new PointF((float)size.Width / (float)maxExtent.Width, (float)size.Height / (float)maxExtent.Height); Zoom = Convert.ToInt32((Math.Min(zoom.X, zoom.Y) * 100)); } } private void OnThemePropertyChanged(object sender, PropertyValueChangedEventArgs e) { if (this.themeConfigDialog != null) { using (BufferedTheme bufferedTheme = new BufferedTheme(this.themeConfigDialog.bufferedTheme)) base.OnThemeChange(WorkflowTheme.CurrentTheme, EventArgs.Empty); } } #region Class BufferedTheme private sealed class BufferedTheme : IDisposable { private WorkflowTheme oldTheme = null; internal BufferedTheme(WorkflowTheme themeToApply) { if (themeToApply != null && WorkflowTheme.CurrentTheme != themeToApply) { WorkflowTheme.EnableChangeNotification = false; this.oldTheme = WorkflowTheme.CurrentTheme; WorkflowTheme.CurrentTheme = themeToApply; } } void IDisposable.Dispose() { if (this.oldTheme != null && WorkflowTheme.CurrentTheme != this.oldTheme) { WorkflowTheme.CurrentTheme.ReadOnly = false; //this was themeToApply passed into constructor, need to make it r/w again WorkflowTheme.CurrentTheme = this.oldTheme; WorkflowTheme.EnableChangeNotification = true; } } } #endregion } #endregion } #endregion } }