File: AuthoringOM\Design\Dialogs\ThemeConfigurationDialog.cs
Project: ndp\cdf\src\WF\Common\System.Workflow.ComponentModel.csproj (System.Workflow.ComponentModel)
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>
    /// Summary description for ThemeConfigurationDialog.
    /// </summary>
    [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 Microsoft 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);
        }
 
        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        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
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        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<Type> activityTypes = new List<Type>();
 
                //***************STOCK TYPES*************
                List<String> stockActivityTypeNames = new List<string>();
                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<Type> nonpreviewableDesignerTypes = new List<Type>();
 
                //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<TreeNode> nodes = new Queue<TreeNode>();
                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<TreeNode> items = new List<TreeNode>();
                Queue<TreeNodeCollection> nodeCollections = new Queue<TreeNodeCollection>();
                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<string, int> identifiers = new Dictionary<string, int>();
                Queue<Activity> Activities = new Queue<Activity>();
                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
    }
}