Update Reference Sources to .NET Framework 4.6.1
[mono.git] / mcs / class / referencesource / System.Workflow.ComponentModel / AuthoringOM / Design / Dialogs / ThemeConfigurationDialog.cs
1 using System;
2 using System.IO;
3 using System.Drawing;
4 using System.Reflection;
5 using System.Collections;
6 using System.Diagnostics;
7 using System.Globalization;
8 using System.CodeDom.Compiler;
9 using System.Windows.Forms;
10 using System.ComponentModel;
11 using System.Drawing.Design;
12 using System.Drawing.Drawing2D;
13 using System.Collections.Generic;
14 using System.Windows.Forms.Design;
15 using System.ComponentModel.Design;
16 using System.ComponentModel.Design.Serialization;
17 using Microsoft.Win32;
18 using System.Workflow.ComponentModel.Compiler;
19
20 namespace System.Workflow.ComponentModel.Design
21 {
22     /// <summary>
23     /// Summary description for ThemeConfigurationDialog.
24     /// </summary>
25     [Obsolete("The System.Workflow.* types are deprecated.  Instead, please use the new types from System.Activities.*")]
26     public sealed class ThemeConfigurationDialog : System.Windows.Forms.Form
27     {
28         #region [....] Generated Members
29         private System.Windows.Forms.Button button3;
30         private System.Windows.Forms.TreeView designerTreeView;
31         private System.Windows.Forms.Label themeNameLabel;
32         private System.Windows.Forms.Label themeLocationLabel;
33         private System.Windows.Forms.TextBox themeNameTextBox;
34         private System.Windows.Forms.Panel themePanel;
35         private System.Windows.Forms.Panel themeConfigPanel;
36         private System.Windows.Forms.Panel dummyPreviewPanel;
37         private System.Windows.Forms.TextBox themeLocationTextBox;
38         private System.Windows.Forms.Label previewLabel;
39         private System.Windows.Forms.Label selectDesignerLabel;
40         private System.Windows.Forms.PropertyGrid propertiesGrid;
41         private System.Windows.Forms.Button themeLocationButton;
42         private System.Windows.Forms.Button okButton;
43         private System.Windows.Forms.Button cancelButton;
44         private System.Windows.Forms.Button previewButton;
45
46         private System.ComponentModel.IContainer components = null;
47         #endregion
48
49         #region Member Variables
50         private IServiceProvider serviceProvider;
51         private bool previewShown = false;
52         private WorkflowTheme bufferedTheme;
53         private DesignerPreview designerPreview;
54         private Splitter splitter;
55         private TableLayoutPanel okCancelTableLayoutPanel;
56         private TableLayoutPanel nameLocationTableLayoutPanel;
57         private bool themeDirty = false;
58         #endregion
59
60         #region Constructor/Destructor
61         public ThemeConfigurationDialog(IServiceProvider serviceProvider)
62             : this(serviceProvider, null)
63         {
64         }
65
66         public ThemeConfigurationDialog(IServiceProvider serviceProvider, WorkflowTheme theme)
67         {
68             if (serviceProvider == null)
69                 throw new ArgumentNullException("serviceProvider");
70
71             this.serviceProvider = serviceProvider;
72
73             if (theme == null)
74             {
75                 this.bufferedTheme = new WorkflowTheme();
76                 this.themeDirty = true;
77             }
78             else
79             {
80                 this.bufferedTheme = theme;
81                 this.themeDirty = false;
82             }
83
84             this.bufferedTheme.ReadOnly = false;
85
86             InitializeComponent();
87             this.themeLocationButton.AutoSize = true;
88
89             //Set dialog fonts
90             Font = StandardFont;
91             SystemEvents.UserPreferenceChanged += new UserPreferenceChangedEventHandler(OnOperatingSystemSettingsChanged);
92         }
93
94         /// <summary>
95         /// Clean up any resources being used.
96         /// </summary>
97         protected override void Dispose(bool disposing)
98         {
99             if (disposing)
100             {
101                 if (components != null)
102                     components.Dispose();
103
104                 SystemEvents.UserPreferenceChanged -= new UserPreferenceChangedEventHandler(OnOperatingSystemSettingsChanged);
105
106                 if (this.designerPreview != null)
107                 {
108                     this.designerPreview.Dispose();
109                     this.designerPreview = null;
110                 }
111
112                 if (this.bufferedTheme != null)
113                 {
114                     ((IDisposable)this.bufferedTheme).Dispose();
115                     this.bufferedTheme = null;
116                 }
117             }
118             base.Dispose(disposing);
119         }
120         #endregion
121
122         #region Windows Form Designer generated code
123         /// <summary>
124         /// Required method for Designer support - do not modify
125         /// the contents of this method with the code editor.
126         /// </summary>
127         private void InitializeComponent()
128         {
129             System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ThemeConfigurationDialog));
130             this.designerTreeView = new System.Windows.Forms.TreeView();
131             this.themeNameLabel = new System.Windows.Forms.Label();
132             this.themeLocationLabel = new System.Windows.Forms.Label();
133             this.themeNameTextBox = new System.Windows.Forms.TextBox();
134             this.nameLocationTableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
135             this.themeLocationButton = new System.Windows.Forms.Button();
136             this.themeLocationTextBox = new System.Windows.Forms.TextBox();
137             this.button3 = new System.Windows.Forms.Button();
138             this.okButton = new System.Windows.Forms.Button();
139             this.cancelButton = new System.Windows.Forms.Button();
140             this.themePanel = new System.Windows.Forms.Panel();
141             this.themeConfigPanel = new System.Windows.Forms.Panel();
142             this.propertiesGrid = new System.Windows.Forms.PropertyGrid();
143             this.previewLabel = new System.Windows.Forms.Label();
144             this.selectDesignerLabel = new System.Windows.Forms.Label();
145             this.dummyPreviewPanel = new System.Windows.Forms.Panel();
146             this.previewButton = new System.Windows.Forms.Button();
147             this.okCancelTableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
148             this.nameLocationTableLayoutPanel.SuspendLayout();
149             this.themePanel.SuspendLayout();
150             this.themeConfigPanel.SuspendLayout();
151             this.okCancelTableLayoutPanel.SuspendLayout();
152             this.SuspendLayout();
153             // 
154             // designerTreeView
155             // 
156             resources.ApplyResources(this.designerTreeView, "designerTreeView");
157             this.designerTreeView.Name = "designerTreeView";
158             // 
159             // themeNameLabel
160             // 
161             resources.ApplyResources(this.themeNameLabel, "themeNameLabel");
162             this.themeNameLabel.Margin = new System.Windows.Forms.Padding(0, 0, 3, 3);
163             this.themeNameLabel.Name = "themeNameLabel";
164             // 
165             // themeLocationLabel
166             // 
167             resources.ApplyResources(this.themeLocationLabel, "themeLocationLabel");
168             this.themeLocationLabel.Margin = new System.Windows.Forms.Padding(0, 3, 3, 0);
169             this.themeLocationLabel.Name = "themeLocationLabel";
170             // 
171             // themeNameTextBox
172             // 
173             resources.ApplyResources(this.themeNameTextBox, "themeNameTextBox");
174             this.nameLocationTableLayoutPanel.SetColumnSpan(this.themeNameTextBox, 2);
175             this.themeNameTextBox.Margin = new System.Windows.Forms.Padding(3, 0, 0, 3);
176             this.themeNameTextBox.Name = "themeNameTextBox";
177             // 
178             // nameLocationTableLayoutPanel
179             // 
180             resources.ApplyResources(this.nameLocationTableLayoutPanel, "nameLocationTableLayoutPanel");
181             this.nameLocationTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
182             this.nameLocationTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
183             this.nameLocationTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
184             this.nameLocationTableLayoutPanel.Controls.Add(this.themeNameLabel, 0, 0);
185             this.nameLocationTableLayoutPanel.Controls.Add(this.themeNameTextBox, 1, 0);
186             this.nameLocationTableLayoutPanel.Controls.Add(this.themeLocationButton, 2, 1);
187             this.nameLocationTableLayoutPanel.Controls.Add(this.themeLocationLabel, 0, 1);
188             this.nameLocationTableLayoutPanel.Controls.Add(this.themeLocationTextBox, 1, 1);
189             this.nameLocationTableLayoutPanel.Name = "nameLocationTableLayoutPanel";
190             this.nameLocationTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
191             this.nameLocationTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
192             // 
193             // themeLocationButton
194             // 
195             resources.ApplyResources(this.themeLocationButton, "themeLocationButton");
196             this.themeLocationButton.Margin = new System.Windows.Forms.Padding(3, 3, 0, 0);
197             this.themeLocationButton.Name = "themeLocationButton";
198             // 
199             // themeLocationTextBox
200             // 
201             resources.ApplyResources(this.themeLocationTextBox, "themeLocationTextBox");
202             this.themeLocationTextBox.Margin = new System.Windows.Forms.Padding(3, 3, 3, 0);
203             this.themeLocationTextBox.Name = "themeLocationTextBox";
204             // 
205             // button3
206             // 
207             resources.ApplyResources(this.button3, "button3");
208             this.button3.Name = "button3";
209             // 
210             // okButton
211             // 
212             resources.ApplyResources(this.okButton, "okButton");
213             this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK;
214             this.okButton.Margin = new System.Windows.Forms.Padding(0, 0, 3, 0);
215             this.okButton.Name = "okButton";
216             // 
217             // cancelButton
218             // 
219             resources.ApplyResources(this.cancelButton, "cancelButton");
220             this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
221             this.cancelButton.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
222             this.cancelButton.Name = "cancelButton";
223             // 
224             // themePanel
225             // 
226             this.themePanel.Controls.Add(this.themeConfigPanel);
227             this.themePanel.Controls.Add(this.previewLabel);
228             this.themePanel.Controls.Add(this.selectDesignerLabel);
229             this.themePanel.Controls.Add(this.dummyPreviewPanel);
230             resources.ApplyResources(this.themePanel, "themePanel");
231             this.themePanel.Margin = new System.Windows.Forms.Padding(4);
232             this.themePanel.Name = "themePanel";
233             // 
234             // themeConfigPanel
235             // 
236             this.themeConfigPanel.Controls.Add(this.designerTreeView);
237             this.themeConfigPanel.Controls.Add(this.propertiesGrid);
238             resources.ApplyResources(this.themeConfigPanel, "themeConfigPanel");
239             this.themeConfigPanel.Name = "themeConfigPanel";
240             // 
241             // propertiesGrid
242             // 
243             this.propertiesGrid.CommandsVisibleIfAvailable = true;
244             resources.ApplyResources(this.propertiesGrid, "propertiesGrid");
245             this.propertiesGrid.Name = "propertiesGrid";
246             this.propertiesGrid.ToolbarVisible = false;
247             // 
248             // previewLabel
249             // 
250             resources.ApplyResources(this.previewLabel, "previewLabel");
251             this.previewLabel.Name = "previewLabel";
252             // 
253             // selectDesignerLabel
254             // 
255             resources.ApplyResources(this.selectDesignerLabel, "selectDesignerLabel");
256             this.selectDesignerLabel.Name = "selectDesignerLabel";
257             // 
258             // dummyPreviewPanel
259             // 
260             resources.ApplyResources(this.dummyPreviewPanel, "dummyPreviewPanel");
261             this.dummyPreviewPanel.Name = "dummyPreviewPanel";
262             // 
263             // previewButton
264             // 
265             resources.ApplyResources(this.previewButton, "previewButton");
266             this.previewButton.Margin = new System.Windows.Forms.Padding(3, 0, 0, 0);
267             this.previewButton.Name = "previewButton";
268             // 
269             // okCancelTableLayoutPanel
270             // 
271             resources.ApplyResources(this.okCancelTableLayoutPanel, "okCancelTableLayoutPanel");
272             this.okCancelTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33F));
273             this.okCancelTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33F));
274             this.okCancelTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33F));
275             this.okCancelTableLayoutPanel.Controls.Add(this.okButton, 0, 0);
276             this.okCancelTableLayoutPanel.Controls.Add(this.cancelButton, 1, 0);
277             this.okCancelTableLayoutPanel.Controls.Add(this.previewButton, 2, 0);
278             this.okCancelTableLayoutPanel.Name = "okCancelTableLayoutPanel";
279             this.okCancelTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
280             // 
281             // ThemeConfigurationDialog
282             // 
283             this.AcceptButton = this.okButton;
284             this.CancelButton = this.cancelButton;
285             resources.ApplyResources(this, "$this");
286             this.Controls.Add(this.nameLocationTableLayoutPanel);
287             this.Controls.Add(this.okCancelTableLayoutPanel);
288             this.Controls.Add(this.themePanel);
289             this.Controls.Add(this.button3);
290             this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
291             this.MaximizeBox = false;
292             this.MinimizeBox = false;
293             this.Name = "ThemeConfigurationDialog";
294             this.ShowInTaskbar = false;
295             this.HelpButton = true;
296             this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
297             this.nameLocationTableLayoutPanel.ResumeLayout(false);
298             this.nameLocationTableLayoutPanel.PerformLayout();
299             this.themePanel.ResumeLayout(false);
300             this.themeConfigPanel.ResumeLayout(false);
301             this.okCancelTableLayoutPanel.ResumeLayout(false);
302             this.okCancelTableLayoutPanel.PerformLayout();
303             this.ResumeLayout(false);
304             this.PerformLayout();
305
306         }
307         #endregion
308
309         #region Properties and Methods
310         public WorkflowTheme ComposedTheme
311         {
312             get
313             {
314                 return this.bufferedTheme;
315             }
316         }
317
318         protected override void OnLoad(EventArgs e)
319         {
320             base.OnLoad(e);
321
322             try
323             {
324                 Cursor.Current = Cursors.WaitCursor;
325                 InitializeControls();
326             }
327             finally
328             {
329                 Cursor.Current = Cursors.Default;
330             }
331         }
332
333         protected override void OnClosing(CancelEventArgs e)
334         {
335             base.OnClosing(e);
336
337             this.bufferedTheme.ReadOnly = true;
338         }
339         #endregion
340
341         #region Helper Functions
342         private Font StandardFont
343         {
344             get
345             {
346                 Font font = SystemInformation.MenuFont;
347                 if (this.serviceProvider != null)
348                 {
349                     IUIService uisvc = (IUIService)this.serviceProvider.GetService(typeof(IUIService));
350                     if (uisvc != null)
351                         font = (Font)uisvc.Styles["DialogFont"];
352                 }
353                 return font;
354             }
355         }
356
357         private void InitializeControls()
358         {
359             HelpButtonClicked += new CancelEventHandler(OnHelpClicked);
360
361             this.themeNameTextBox.Text = this.bufferedTheme.Name;
362             this.themeLocationTextBox.Text = this.bufferedTheme.FilePath;
363
364             this.propertiesGrid.PropertySort = PropertySort.Categorized;
365
366             //Make sure that size and location are changed after adding the control to the parent
367             //this will autoscale the control correctly
368             this.designerPreview = new DesignerPreview(this);
369             this.dummyPreviewPanel.Parent.Controls.Add(this.designerPreview);
370             this.designerPreview.TabStop = false;
371             this.designerPreview.Location = this.dummyPreviewPanel.Location;
372             this.designerPreview.Size = this.dummyPreviewPanel.Size;
373             this.dummyPreviewPanel.Visible = false;
374             this.designerPreview.Parent.Controls.Remove(this.dummyPreviewPanel);
375
376             this.designerTreeView.ShowLines = false;
377             this.designerTreeView.ShowPlusMinus = false;
378             this.designerTreeView.ShowRootLines = false;
379             this.designerTreeView.ShowNodeToolTips = true;
380             this.designerTreeView.HideSelection = false;
381             this.designerTreeView.ItemHeight = Math.Max(this.designerTreeView.ItemHeight, 18);
382             ThemeConfigHelpers.PopulateActivities(this.serviceProvider, this.designerTreeView);
383
384             this.themeConfigPanel.Controls.Remove(this.designerTreeView);
385             this.themeConfigPanel.Controls.Remove(this.propertiesGrid);
386             this.designerTreeView.Dock = DockStyle.Left;
387             this.splitter = new Splitter();
388             this.splitter.Dock = DockStyle.Left;
389             this.propertiesGrid.Dock = DockStyle.Fill;
390             this.themeConfigPanel.Controls.AddRange(new Control[] { this.propertiesGrid, this.splitter, this.designerTreeView });
391
392             this.themePanel.Paint += new PaintEventHandler(OnThemePanelPaint);
393             this.previewButton.Click += new EventHandler(OnPreviewClicked);
394             this.designerTreeView.AfterSelect += new TreeViewEventHandler(OnDesignerSelectionChanged);
395             this.themeLocationButton.Click += new EventHandler(OnThemeLocationClicked);
396             this.okButton.Click += new EventHandler(OnOk);
397             this.propertiesGrid.PropertyValueChanged += new PropertyValueChangedEventHandler(OnThemePropertyChanged);
398             this.themeNameTextBox.TextChanged += new EventHandler(OnThemeChanged);
399             this.themeLocationTextBox.TextChanged += new EventHandler(OnThemeChanged);
400
401             this.designerTreeView.SelectedNode = (this.designerTreeView.Nodes.Count > 0) ? this.designerTreeView.Nodes[0] : null;
402             this.designerTreeView.SelectedNode.EnsureVisible();
403
404             ShowPreview = true;
405         }
406
407         private void OnThemeChanged(object sender, EventArgs e)
408         {
409             this.themeDirty = true;
410         }
411
412         private void OnThemePropertyChanged(object sender, PropertyValueChangedEventArgs e)
413         {
414             this.themeDirty = true;
415         }
416
417         private bool ValidateControls(out string error, out Control control)
418         {
419             error = String.Empty;
420             control = null;
421
422             if (this.themeNameTextBox.Text == null || this.themeNameTextBox.Text.Trim().Length == 0)
423             {
424                 error = DR.GetString(DR.ThemeNameNotValid);
425                 control = this.themeNameTextBox;
426                 return false;
427             }
428
429             if (this.themeLocationTextBox.Text == null)
430             {
431                 error = DR.GetString(DR.ThemePathNotValid);
432                 control = this.themeNameTextBox;
433                 return false;
434             }
435
436             string path = this.themeLocationTextBox.Text.Trim();
437             if (path.IndexOfAny(Path.GetInvalidPathChars()) >= 0 ||
438                 !Path.IsPathRooted(path) ||
439                 !Path.HasExtension(path))
440             {
441                 error = DR.GetString(DR.ThemePathNotValid);
442                 control = this.themeLocationTextBox;
443                 return false;
444             }
445
446             string fileName = Path.GetFileNameWithoutExtension(path);
447             string extension = Path.GetExtension(path);
448             if (fileName == null || fileName.Trim().Length == 0 ||
449                 extension == null || extension.Trim().Length == 0)
450             {
451                 error = DR.GetString(DR.ThemePathNotValid);
452                 control = this.themeLocationTextBox;
453                 return false;
454             }
455
456             if (!extension.Equals(WorkflowTheme.DefaultThemeFileExtension.Replace("*", ""), StringComparison.Ordinal))
457             {
458                 error = DR.GetString(DR.ThemeFileNotXml);
459                 control = this.themeLocationTextBox;
460                 return false;
461             }
462
463             return true;
464         }
465
466         private void OnOk(object sender, EventArgs e)
467         {
468             string error = String.Empty;
469             Control control = null;
470             if (!ValidateControls(out error, out control))
471             {
472                 DialogResult = DialogResult.None;
473                 DesignerHelpers.ShowError(this.serviceProvider, error);
474                 if (control != null)
475                 {
476                     TextBox textBox = control as TextBox;
477                     if (textBox != null)
478                     {
479                         textBox.SelectionStart = 0;
480                         textBox.SelectionLength = (textBox.Text != null) ? textBox.Text.Length : 0;
481                     }
482                     control.Focus();
483                 }
484                 return;
485             }
486
487             //Before we try saving show the warning if the user has changed the theme path
488             if (!this.bufferedTheme.FilePath.Equals(this.themeLocationTextBox.Text.Trim(), StringComparison.OrdinalIgnoreCase))
489             {
490                 if (DialogResult.No == DesignerHelpers.ShowMessage(this.serviceProvider, DR.GetString(DR.UpdateRelativePaths), DR.GetString(DR.WorkflowDesignerTitle), MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1))
491                 {
492                     DialogResult = DialogResult.None;
493                     return;
494                 }
495             }
496
497             if (this.themeDirty)
498             {
499                 try
500                 {
501                     Cursor.Current = Cursors.WaitCursor;
502
503                     ThemeConfigHelpers.EnsureDesignerThemes(this.serviceProvider, this.bufferedTheme, ThemeConfigHelpers.GetAllTreeNodes(this.designerTreeView));
504                     this.bufferedTheme.ReadOnly = false;
505                     this.bufferedTheme.Name = this.themeNameTextBox.Text.Trim();
506                     this.bufferedTheme.Description = DR.GetString(DR.ThemeDescription);
507                     this.bufferedTheme.Save(this.themeLocationTextBox.Text.Trim());
508                     this.themeDirty = false;
509                     this.bufferedTheme.ReadOnly = true;
510                 }
511                 catch
512                 {
513                     DesignerHelpers.ShowError(this.serviceProvider, DR.GetString(DR.ThemeFileCreationError));
514                     this.themeLocationTextBox.SelectionStart = 0;
515                     this.themeLocationTextBox.SelectionLength = (this.themeLocationTextBox.Text != null) ? this.themeLocationTextBox.Text.Length : 0;
516                     this.themeLocationTextBox.Focus();
517                     DialogResult = DialogResult.None;
518                 }
519                 finally
520                 {
521                     Cursor.Current = Cursors.Default;
522                 }
523             }
524         }
525
526         private void OnHelpClicked(object sender, CancelEventArgs e)
527         {
528             e.Cancel = true;
529             ShowHelp();
530         }
531
532         protected override void OnHelpRequested(HelpEventArgs e)
533         {
534             ShowHelp();
535             e.Handled = true;
536         }
537
538         private void ShowHelp()
539         {
540             DesignerHelpers.ShowHelpFromKeyword(this.serviceProvider, typeof(ThemeConfigurationDialog).FullName + ".UI");
541         }
542
543         private void OnThemePanelPaint(object sender, PaintEventArgs e)
544         {
545             e.Graphics.DrawRectangle(SystemPens.ControlDark, 0, 0, this.themePanel.ClientSize.Width - 1, this.themePanel.ClientSize.Height - 2);
546
547             if (this.previewShown)
548             {
549                 Point top = new Point(this.propertiesGrid.Right + (this.dummyPreviewPanel.Left - this.propertiesGrid.Right) / 2, this.themePanel.Margin.Top);
550                 Point bottom = new Point(top.X, this.themePanel.Height - this.themePanel.Margin.Bottom);
551                 e.Graphics.DrawLine(SystemPens.ControlDark, top, bottom);
552             }
553
554             Size margin = new Size(8, 8);
555             using (Pen framePen = new Pen(Color.Black, 1))
556             {
557                 framePen.DashStyle = DashStyle.Dot;
558                 e.Graphics.DrawLine(framePen, this.designerPreview.Left - margin.Width, this.designerPreview.Top - 1, this.designerPreview.Right + margin.Width, this.designerPreview.Top - 1);
559                 e.Graphics.DrawLine(framePen, this.designerPreview.Left - margin.Width, this.designerPreview.Bottom + 1, this.designerPreview.Right + margin.Width, this.designerPreview.Bottom + 1);
560                 e.Graphics.DrawLine(framePen, this.designerPreview.Left - 1, this.designerPreview.Top - margin.Height, this.designerPreview.Left - 1, this.designerPreview.Bottom + margin.Height);
561                 e.Graphics.DrawLine(framePen, this.designerPreview.Right + 1, this.designerPreview.Top - margin.Height, this.designerPreview.Right + 1, this.designerPreview.Bottom + margin.Height);
562             }
563         }
564
565         private void OnDesignerSelectionChanged(object sender, TreeViewEventArgs eventArgs)
566         {
567             //We need to select the theme of the selected designer
568             Type activityType = (eventArgs.Node != null && typeof(Activity).IsAssignableFrom(eventArgs.Node.Tag as System.Type)) ? eventArgs.Node.Tag as System.Type : null;
569             IDesigner previewedDesigner = this.designerPreview.UpdatePreview(activityType);
570
571             object[] selectedObjects = null;
572             if (activityType == null)
573             {
574                 if (eventArgs.Node != null)
575                     selectedObjects = (eventArgs.Node.Parent == null) ? new object[] { this.bufferedTheme.AmbientTheme } : ThemeConfigHelpers.GetDesignerThemes(this.serviceProvider, this.bufferedTheme, eventArgs.Node);
576             }
577             else
578             {
579                 selectedObjects = (previewedDesigner != null) ? new object[] { this.bufferedTheme.GetDesignerTheme(previewedDesigner as ActivityDesigner) } : null;
580             }
581
582             this.propertiesGrid.SelectedObjects = selectedObjects;
583         }
584
585         private void OnPreviewClicked(object sender, EventArgs e)
586         {
587             ShowPreview = !ShowPreview;
588         }
589
590         private void OnThemeLocationClicked(object sender, EventArgs e)
591         {
592             SaveFileDialog fileDialog = new SaveFileDialog();
593             fileDialog.AddExtension = true;
594             fileDialog.DefaultExt = WorkflowTheme.DefaultThemeFileExtension;
595             fileDialog.Filter = DR.GetString(DR.ThemeFileFilter);
596             fileDialog.RestoreDirectory = false;
597             if (fileDialog.ShowDialog(this) == DialogResult.OK)
598             {
599                 this.themeLocationTextBox.Text = fileDialog.FileName;
600             }
601         }
602
603         private bool ShowPreview
604         {
605             get
606             {
607                 return this.previewShown;
608             }
609
610             set
611             {
612                 this.previewShown = value;
613                 this.previewLabel.Visible = this.previewShown;
614                 this.designerPreview.Visible = this.previewShown;
615
616                 if (this.previewShown)
617                 {
618                     this.themePanel.Width = this.designerPreview.Right + ((this.designerPreview.Left - this.propertiesGrid.Right) / 2);
619                     this.previewButton.Text = DR.GetString(DR.Preview) + " <<";
620                 }
621                 else
622                 {
623                     this.themePanel.Width = this.themeConfigPanel.Right + this.themeConfigPanel.Left;
624                     this.previewButton.Text = DR.GetString(DR.Preview) + " >>";
625                 }
626                 Width = this.themePanel.Right + this.themePanel.Left + Margin.Left + Margin.Right;
627                 this.themePanel.Invalidate();
628             }
629         }
630
631         private void OnOperatingSystemSettingsChanged(object sender, UserPreferenceChangedEventArgs e)
632         {
633             //
634
635             if (e.Category == UserPreferenceCategory.Color || e.Category == UserPreferenceCategory.VisualStyle)
636                 Font = StandardFont;
637         }
638         #endregion
639
640         #region Class ThemeHelpers
641         private static class ThemeConfigHelpers
642         {
643             internal static void PopulateActivities(IServiceProvider serviceProvider, TreeView treeView)
644             {
645                 List<Type> activityTypes = new List<Type>();
646
647                 //***************STOCK TYPES*************
648                 List<String> stockActivityTypeNames = new List<string>();
649                 stockActivityTypeNames.Add(DesignerHelpers.SequentialWorkflowTypeRef);
650                 stockActivityTypeNames.Add(DesignerHelpers.StateMachineWorkflowTypeRef);
651                 stockActivityTypeNames.Add(DesignerHelpers.IfElseBranchTypeRef);
652                 stockActivityTypeNames.Add(typeof(FaultHandlersActivity).AssemblyQualifiedName);
653                 stockActivityTypeNames.Add(DesignerHelpers.EventHandlersTypeRef);
654                 stockActivityTypeNames.Add(typeof(CompensationHandlerActivity).AssemblyQualifiedName);
655                 stockActivityTypeNames.Add(typeof(CancellationHandlerActivity).AssemblyQualifiedName);
656
657                 foreach (string stockTypeName in stockActivityTypeNames)
658                 {
659                     Type stockType = Type.GetType(stockTypeName, false);
660                     if (stockType == null)
661                         Debug.Assert(false, string.Format(CultureInfo.CurrentCulture, "Could not load type '{0}'", stockTypeName));
662                     else
663                         activityTypes.Add(stockType);
664                 }
665
666                 //***************NON PREVIWABLE DESIGNER TYPES*************
667                 IList<Type> nonpreviewableDesignerTypes = new List<Type>();
668
669                 //These designer might be designers such as CADesigner which we eliminated
670                 //We have just kept the code so that in future if this functionality is needed
671                 //we can add it
672
673                 //Populate the designer combobox
674                 treeView.BeginUpdate();
675                 treeView.Nodes.Clear();
676
677                 //Work around: ***WE DISPLAY THE COMMON PROPERTIES FOR WORKFLOW AND APPLY THEM RECURSIVELY TO DESIGNERS
678                 TreeNode workflowNode = new TreeNode(DR.GetString(DR.WorkflowDesc));
679                 treeView.Nodes.Add(workflowNode);
680
681                 //Now we go thru the toolbox items and get all the items which are not in our assembly
682                 IToolboxService toolboxService = serviceProvider.GetService(typeof(IToolboxService)) as IToolboxService;
683                 ITypeProviderCreator typeProviderCreator = serviceProvider.GetService(typeof(ITypeProviderCreator)) as ITypeProviderCreator;
684                 if (toolboxService != null && typeProviderCreator != null)
685                 {
686                     ToolboxItemCollection toolboxItems = toolboxService.GetToolboxItems();
687                     foreach (ToolboxItem toolboxItem in toolboxItems)
688                     {
689                         bool customWinOEActivityType = (toolboxItem is ActivityToolboxItem);
690                         if (!customWinOEActivityType)
691                         {
692                             foreach (ToolboxItemFilterAttribute filter in toolboxItem.Filter)
693                             {
694                                 if (filter.FilterString.StartsWith("Microsoft.Workflow.VSDesigner", StringComparison.OrdinalIgnoreCase) ||
695                                     filter.FilterString.StartsWith("System.Workflow.ComponentModel", StringComparison.OrdinalIgnoreCase))
696                                 {
697                                     customWinOEActivityType = true;
698                                     break;
699                                 }
700                             }
701                         }
702
703                         if (customWinOEActivityType)
704                         {
705                             Type type = null;
706                             Assembly assembly = typeProviderCreator.GetTransientAssembly(toolboxItem.AssemblyName);
707                             if (assembly != null)
708                                 type = assembly.GetType(toolboxItem.TypeName);
709                             if (type != null)
710                             {
711                                 ConstructorInfo[] constructors = type.GetConstructors();
712                                 foreach (ConstructorInfo constructor in constructors)
713                                 {
714                                     if (constructor.IsPublic && constructor.GetParameters().GetLength(0) == 0)
715                                         activityTypes.Add(type);
716                                 }
717                             }
718                         }
719                     }
720                 }
721
722                 foreach (Type type in activityTypes)
723                 {
724                     Type designerBaseType = (type.FullName.Equals(DesignerHelpers.SequentialWorkflowTypeRef, StringComparison.OrdinalIgnoreCase)) ? typeof(IRootDesigner) : typeof(IDesigner);
725                     Type designerType = ActivityDesigner.GetDesignerType(serviceProvider, type, designerBaseType);
726                     if (designerType != null && !nonpreviewableDesignerTypes.Contains(designerType))
727                     {
728                         object[] attribs = designerType.GetCustomAttributes(typeof(ActivityDesignerThemeAttribute), true);
729                         ActivityDesignerThemeAttribute themeAttrib = (attribs != null && attribs.GetLength(0) > 0) ? attribs[0] as ActivityDesignerThemeAttribute : null;
730                         if (themeAttrib != null)
731                         {
732                             Image image = ActivityToolboxItem.GetToolboxImage(type);
733                             if (treeView.ImageList == null)
734                             {
735                                 treeView.ImageList = new ImageList();
736                                 treeView.ImageList.ColorDepth = ColorDepth.Depth32Bit;
737                                 Image standardImage = DR.GetImage(DR.Activity) as Image;
738                                 treeView.ImageList.Images.Add(standardImage, AmbientTheme.TransparentColor);
739                             }
740
741                             TreeNode parentNode = ThemeConfigHelpers.GetCatagoryNodeForDesigner(designerType, ThemeConfigHelpers.GetAllTreeNodes(treeView));
742                             if (parentNode != null)
743                             {
744                                 int imageIndex = (image != null) ? treeView.ImageList.Images.Add(image, AmbientTheme.TransparentColor) : 0;
745                                 TreeNode nodeToInsert = (imageIndex >= 0) ? new TreeNode(ActivityToolboxItem.GetToolboxDisplayName(type), imageIndex, imageIndex) : new TreeNode(ActivityToolboxItem.GetToolboxDisplayName(type));
746                                 nodeToInsert.Tag = type;
747
748                                 //We always make sure that cata----es are at the end
749                                 int index = parentNode.Nodes.Count - 1;
750                                 while (index >= 0 && parentNode.Nodes[index].Tag is System.Type)
751                                     index = index - 1;
752                                 parentNode.Nodes.Insert(index, nodeToInsert);
753                             }
754                         }
755                     }
756                 }
757
758                 treeView.TreeViewNodeSorter = new ThemeTreeNodeComparer();
759                 treeView.Sort();
760                 treeView.Nodes[0].ExpandAll();
761                 treeView.EndUpdate();
762             }
763
764             internal static TreeNode GetCatagoryNodeForDesigner(Type designerType, TreeNode[] treeNodes)
765             {
766                 if (designerType == null)
767                     throw new ArgumentNullException("designerType");
768                 if (treeNodes == null)
769                     throw new ArgumentNullException("treeNodes");
770                 if (treeNodes.Length == 0)
771                     throw new ArgumentException(SR.GetString(SR.Error_InvalidArgumentValue), "treeNodes");
772
773                 CategoryAttribute parentCatagoryAttribute = null;
774                 CategoryAttribute designerCatagoryAttribute = null;
775                 Type baseType = designerType;
776                 while (baseType != typeof(object) && parentCatagoryAttribute == null)
777                 {
778                     object[] attribs = baseType.GetCustomAttributes(typeof(CategoryAttribute), false);
779                     if (attribs != null && attribs.GetLength(0) > 0)
780                     {
781                         if (designerCatagoryAttribute == null)
782                             designerCatagoryAttribute = attribs[0] as CategoryAttribute;
783                         else
784                             parentCatagoryAttribute = attribs[0] as CategoryAttribute;
785                     }
786                     baseType = baseType.BaseType;
787                 }
788
789                 if (designerCatagoryAttribute == null)
790                     return null;
791
792                 //Search for the catagory
793                 TreeNode catagoryNode = null;
794                 TreeNode parentCatagoryTreeNode = treeNodes[0];
795
796                 foreach (TreeNode item in treeNodes)
797                 {
798                     if (parentCatagoryAttribute != null && parentCatagoryAttribute.Category == item.Text && (item.Tag == null || !typeof(Activity).IsAssignableFrom(item.Tag.GetType())))
799                         parentCatagoryTreeNode = item;
800
801                     //We found the catagory
802                     if (designerCatagoryAttribute.Category == item.Text && (item.Tag == null || !typeof(Activity).IsAssignableFrom(item.Tag.GetType())))
803                     {
804                         catagoryNode = item;
805                         break;
806                     }
807                 }
808
809                 if (catagoryNode == null)
810                 {
811                     Debug.Assert(parentCatagoryTreeNode != null);
812                     if (parentCatagoryTreeNode != null)
813                     {
814                         //Work around : ***WE DISPLAY THE COMMON PROPERTIES FROM KNOWN DESIGNERCATA----ES
815                         //WE WILL EVENTUALLY REMOVE THIS WHEN WE CREATE AN MECHANISM TO SHARE COMMON
816                         //PROPERTIES IN THEMES
817                         catagoryNode = new TreeNode(designerCatagoryAttribute.Category);
818                         parentCatagoryTreeNode.Nodes.Add(catagoryNode);
819                     }
820                 }
821
822                 return catagoryNode;
823             }
824
825             internal static DesignerTheme[] GetDesignerThemes(IServiceProvider serviceProvider, WorkflowTheme workflowTheme, TreeNode selectedNode)
826             {
827                 ArrayList designerThemes = new ArrayList();
828                 Queue<TreeNode> nodes = new Queue<TreeNode>();
829                 nodes.Enqueue(selectedNode);
830                 while (nodes.Count > 0)
831                 {
832                     TreeNode treeNode = nodes.Dequeue();
833                     Type activityType = treeNode.Tag as System.Type;
834                     if (activityType != null)
835                     {
836                         Type designerBaseType = (activityType.FullName.Equals(DesignerHelpers.SequentialWorkflowTypeRef, StringComparison.OrdinalIgnoreCase)) ? typeof(IRootDesigner) : typeof(IDesigner);
837                         Type designerType = ActivityDesigner.GetDesignerType(serviceProvider, activityType, designerBaseType);
838                         if (designerType != null)
839                         {
840                             DesignerTheme designerTheme = workflowTheme.GetTheme(designerType);
841                             if (designerTheme != null)
842                                 designerThemes.Add(designerTheme);
843                         }
844                     }
845                     else
846                     {
847                         foreach (TreeNode childNode in treeNode.Nodes)
848                             nodes.Enqueue(childNode);
849                     }
850                 }
851
852                 return ((DesignerTheme[])designerThemes.ToArray(typeof(DesignerTheme)));
853             }
854
855             internal static TreeNode[] GetAllTreeNodes(TreeView treeView)
856             {
857                 List<TreeNode> items = new List<TreeNode>();
858                 Queue<TreeNodeCollection> nodeCollections = new Queue<TreeNodeCollection>();
859                 nodeCollections.Enqueue(treeView.Nodes);
860                 while (nodeCollections.Count > 0)
861                 {
862                     TreeNodeCollection nodeCollection = nodeCollections.Dequeue();
863                     foreach (TreeNode treeNode in nodeCollection)
864                     {
865                         items.Add(treeNode);
866                         if (treeNode.Nodes.Count > 0)
867                             nodeCollections.Enqueue(treeNode.Nodes);
868                     }
869                 }
870
871                 return items.ToArray();
872             }
873
874             internal static void EnsureDesignerThemes(IServiceProvider serviceProvider, WorkflowTheme workflowTheme, TreeNode[] items)
875             {
876                 //We need to recurse thru the themes and make sure that we have all the designer themes created
877                 foreach (TreeNode item in items)
878                 {
879                     DesignerTheme designerTheme = null;
880                     Type activityType = item.Tag as Type;
881                     if (activityType != null)
882                     {
883                         Type designerBaseType = (activityType.FullName.Equals(DesignerHelpers.SequentialWorkflowTypeRef, StringComparison.OrdinalIgnoreCase)) ? typeof(IRootDesigner) : typeof(IDesigner);
884                         Type designerType = ActivityDesigner.GetDesignerType(serviceProvider, activityType, designerBaseType);
885                         if (designerType != null)
886                             designerTheme = workflowTheme.GetTheme(designerType);
887                     }
888                 }
889             }
890         }
891         #endregion
892
893         #region Class ThemeTreeNodeComparer
894         internal sealed class ThemeTreeNodeComparer : IComparer
895         {
896             #region IComparer Members
897             int IComparer.Compare(object x, object y)
898             {
899                 TreeNode treeNode1 = x as TreeNode;
900                 TreeNode treeNode2 = y as TreeNode;
901
902                 if (treeNode1.Nodes.Count > treeNode2.Nodes.Count)
903                     return 1;
904                 else
905                     return String.Compare(treeNode1.Text, treeNode2.Text, StringComparison.CurrentCulture);
906             }
907             #endregion
908         }
909         #endregion
910
911         #region Class DesignerPreview
912         internal sealed class DesignerPreview : UserControl
913         {
914             private ThemeConfigurationDialog parent = null;
915             private PreviewDesignSurface surface = null;
916
917             internal DesignerPreview(ThemeConfigurationDialog parent)
918             {
919                 BackColor = Color.White;
920                 this.parent = parent;
921             }
922
923             protected override void OnLoad(EventArgs e)
924             {
925                 base.OnLoad(e);
926
927                 SuspendLayout();
928
929                 this.surface = new PreviewDesignSurface(this.parent.serviceProvider);
930                 PreviewWorkflowDesignerLoader loader = new PreviewWorkflowDesignerLoader();
931                 this.surface.BeginLoad(loader);
932
933                 //Add the root activity
934                 IDesignerHost host = this.surface.GetService(typeof(IDesignerHost)) as IDesignerHost;
935                 Debug.Assert(host != null);
936
937                 //
938                 Activity rootDecl = host.CreateComponent(Type.GetType(DesignerHelpers.SequentialWorkflowTypeRef)) as Activity;
939                 rootDecl.Name = "ThemeSequentialWorkflow";
940                 WorkflowDesignerLoader.AddActivityToDesigner(this.surface, rootDecl as Activity);
941
942                 //Create the readonly workflow
943                 ReadonlyWorkflow workflowView = new ReadonlyWorkflow(this.parent, this.surface as IServiceProvider);
944                 workflowView.TabStop = false;
945                 workflowView.Dock = DockStyle.Fill;
946                 Controls.Add(workflowView);
947
948                 host.Activate();
949
950                 ResumeLayout(true);
951             }
952
953             protected override void Dispose(bool disposing)
954             {
955                 if (disposing && this.surface != null)
956                 {
957                     IDesignerHost host = GetService(typeof(IDesignerHost)) as IDesignerHost;
958                     if (host != null && host.RootComponent != null)
959                         WorkflowDesignerLoader.RemoveActivityFromDesigner(this.surface, host.RootComponent as Activity);
960
961                     ReadonlyWorkflow workflowView = (Controls.Count > 0) ? Controls[0] as ReadonlyWorkflow : null;
962                     Controls.Clear();
963                     if (workflowView != null)
964                     {
965                         workflowView.Dispose();
966                         workflowView = null;
967                     }
968
969                     this.surface.Dispose();
970                     this.surface = null;
971                 }
972
973                 base.Dispose(disposing);
974             }
975
976             internal IDesigner UpdatePreview(Type activityType)
977             {
978                 bool dummyPreview = false; //if we have a dummy preview activity
979                 IDesignerHost host = this.surface.GetService(typeof(IDesignerHost)) as IDesignerHost;
980                 Debug.Assert(host != null);
981
982                 CompositeActivity rootDecl = host.RootComponent as CompositeActivity;
983                 Debug.Assert(rootDecl != null);
984                 if (host == null || rootDecl == null)
985                     return null;
986
987                 IComponent previewActivity = null;
988                 try
989                 {
990                     //Remove earlier activities
991                     while (rootDecl.Activities.Count > 0)
992                     {
993                         Activity declToDelete = rootDecl.Activities[0];
994                         rootDecl.Activities.Remove(declToDelete);
995                         WorkflowDesignerLoader.RemoveActivityFromDesigner(this.surface, declToDelete);
996                     }
997
998                     //Add new activities to preview
999                     if (activityType == null || activityType.FullName.Equals(DesignerHelpers.SequentialWorkflowTypeRef, StringComparison.OrdinalIgnoreCase))
1000                     {
1001                         AddDummyActivity(rootDecl as CompositeActivity, Type.GetType(DesignerHelpers.CodeActivityTypeRef));
1002                         dummyPreview = true;
1003                     }
1004                     else
1005                     {
1006                         IComponent[] components = null;
1007                         object[] attribs = activityType.GetCustomAttributes(typeof(ToolboxItemAttribute), false);
1008                         ToolboxItemAttribute toolboxItemAttrib = (attribs != null && attribs.GetLength(0) > 0) ? attribs[0] as ToolboxItemAttribute : null;
1009                         if (toolboxItemAttrib != null && toolboxItemAttrib.ToolboxItemType != null && typeof(ActivityToolboxItem).IsAssignableFrom(toolboxItemAttrib.ToolboxItemType))
1010                         {
1011                             ActivityToolboxItem item = Activator.CreateInstance(toolboxItemAttrib.ToolboxItemType, new object[] { activityType }) as ActivityToolboxItem;
1012                             components = item.CreateComponents(host);
1013                         }
1014
1015                         if (components == null)
1016                             components = new IComponent[] { Activator.CreateInstance(activityType) as IComponent };
1017
1018                         Activity activity = (components != null && components.Length > 0) ? components[0] as Activity : null;
1019                         if (activity != null)
1020                         {
1021                             rootDecl.Activities.Add(activity);
1022                             EnsureUniqueId(activity);
1023
1024                             WorkflowDesignerLoader.AddActivityToDesigner(this.surface, activity);
1025                             CompositeActivityDesigner compositeDesigner = host.GetDesigner(rootDecl) as CompositeActivityDesigner;
1026                             ActivityDesigner activityDesigner = host.GetDesigner(activity) as ActivityDesigner;
1027                             if (compositeDesigner != null && activityDesigner != null)
1028                                 compositeDesigner.EnsureVisibleContainedDesigner(activityDesigner);
1029                             /*
1030                                                         //
1031
1032
1033
1034
1035
1036
1037 */
1038                         }
1039                     }
1040
1041
1042                     ISelectionService selectionService = host.GetService(typeof(ISelectionService)) as ISelectionService;
1043                     if (selectionService != null)
1044                         selectionService.SetSelectedComponents(new IComponent[] { rootDecl });
1045
1046                     ReadonlyWorkflow workflowView = (Controls.Count > 0) ? Controls[0] as ReadonlyWorkflow : null;
1047                     if (workflowView != null)
1048                         workflowView.PerformLayout();
1049
1050                     previewActivity = (rootDecl.Activities.Count > 0 && !dummyPreview) ? rootDecl.Activities[0] : rootDecl;
1051                 }
1052                 catch
1053                 {
1054                 }
1055
1056                 return (previewActivity != null) ? host.GetDesigner(previewActivity) : null;
1057             }
1058
1059             private void AddDummyActivity(CompositeActivity parentActivity, Type activityType)
1060             {
1061                 IDesignerHost host = this.surface.GetService(typeof(IDesignerHost)) as IDesignerHost;
1062                 Debug.Assert(host != null);
1063                 if (host == null)
1064                     return;
1065
1066                 Activity dummyActivity = Activator.CreateInstance(activityType) as Activity;
1067                 Debug.Assert(dummyActivity != null);
1068                 if (dummyActivity == null)
1069                     return;
1070
1071                 parentActivity.Activities.Add(dummyActivity);
1072                 EnsureUniqueId(dummyActivity);
1073                 WorkflowDesignerLoader.AddActivityToDesigner(this.surface, dummyActivity);
1074             }
1075
1076             private void EnsureUniqueId(Activity addedActivity)
1077             {
1078                 Dictionary<string, int> identifiers = new Dictionary<string, int>();
1079                 Queue<Activity> Activities = new Queue<Activity>();
1080                 Activities.Enqueue(addedActivity);
1081                 while (Activities.Count > 0)
1082                 {
1083                     Activity Activity = Activities.Dequeue();
1084                     string fullTypeName = Activity.GetType().FullName;
1085
1086                     int id = (identifiers.ContainsKey(fullTypeName)) ? identifiers[fullTypeName] : 1;
1087                     Activity.Name = Activity.GetType().Name + id.ToString(CultureInfo.InvariantCulture);
1088                     id += 1;
1089
1090                     if (identifiers.ContainsKey(fullTypeName))
1091                         identifiers[fullTypeName] = id;
1092                     else
1093                         identifiers.Add(fullTypeName, id);
1094
1095                     CompositeActivity compositeActivity = Activity as CompositeActivity;
1096                     if (compositeActivity != null)
1097                     {
1098                         foreach (Activity activity in compositeActivity.Activities)
1099                             Activities.Enqueue(activity);
1100                     }
1101                 }
1102             }
1103
1104             #region Class PreviewDesignSurface
1105             private sealed class PreviewDesignSurface : DesignSurface
1106             {
1107                 internal PreviewDesignSurface(IServiceProvider parentProvider)
1108                     : base(new PreviewDesignerServiceProvider(parentProvider))
1109                 {
1110                     ITypeProvider typeProvider = GetService(typeof(ITypeProvider)) as ITypeProvider;
1111                     if (typeProvider == null)
1112                     {
1113                         TypeProvider provider = new TypeProvider(this);
1114                         provider.AddAssemblyReference(typeof(string).Assembly.Location);
1115                         ServiceContainer.AddService(typeof(ITypeProvider), provider, true);
1116                     }
1117                 }
1118
1119                 protected override IDesigner CreateDesigner(IComponent component, bool rootDesigner)
1120                 {
1121                     IDesigner designer = base.CreateDesigner(component, rootDesigner);
1122                     Activity activity = component as Activity;
1123                     if (designer == null && !rootDesigner && activity != null)
1124                         designer = ActivityDesigner.CreateDesigner(activity.Site, activity);
1125                     return designer;
1126                 }
1127
1128                 #region Class PreviewDesignerServiceProvider
1129                 private sealed class PreviewDesignerServiceProvider : IServiceProvider
1130                 {
1131                     private IServiceProvider serviceProvider;
1132
1133                     internal PreviewDesignerServiceProvider(IServiceProvider serviceProvider)
1134                     {
1135                         this.serviceProvider = serviceProvider;
1136                     }
1137
1138                     #region IServiceProvider Members
1139                     object IServiceProvider.GetService(Type serviceType)
1140                     {
1141                         if (serviceType == typeof(IPropertyValueUIService))
1142                             return null;
1143                         return this.serviceProvider.GetService(serviceType);
1144                     }
1145                     #endregion
1146                 }
1147                 #endregion
1148             }
1149             #endregion
1150
1151             #region Class PreviewWorkflowDesignerLoader
1152             private class PreviewWorkflowDesignerLoader : WorkflowDesignerLoader
1153             {
1154                 public override TextReader GetFileReader(string filePath)
1155                 {
1156                     return null;
1157                 }
1158
1159                 public override TextWriter GetFileWriter(string filePath)
1160                 {
1161                     return null;
1162                 }
1163
1164                 public override string FileName
1165                 {
1166                     get
1167                     {
1168                         return String.Empty;
1169                     }
1170                 }
1171             }
1172             #endregion
1173
1174             #region Class ReadOnly Workflow
1175             private class ReadonlyWorkflow : WorkflowView
1176             {
1177                 private ThemeConfigurationDialog themeConfigDialog = null;
1178
1179                 internal ReadonlyWorkflow(ThemeConfigurationDialog themeConfigDialog, IServiceProvider serviceProvider)
1180                     : base(serviceProvider)
1181                 {
1182                     this.themeConfigDialog = themeConfigDialog;
1183                     this.themeConfigDialog.propertiesGrid.PropertyValueChanged += new PropertyValueChangedEventHandler(OnThemePropertyChanged);
1184                     this.EnableFitToScreen = false;
1185
1186                     AddDesignerMessageFilter(new ReadonlyMessageFilter());
1187                 }
1188
1189                 protected override void Dispose(bool disposing)
1190                 {
1191                     base.Dispose(disposing);
1192
1193                     if (this.themeConfigDialog != null && this.themeConfigDialog.propertiesGrid != null)
1194                         this.themeConfigDialog.propertiesGrid.PropertyValueChanged -= new PropertyValueChangedEventHandler(OnThemePropertyChanged);
1195                 }
1196
1197                 protected override void OnPaint(PaintEventArgs e)
1198                 {
1199                     if (this.themeConfigDialog == null)
1200                     {
1201                         base.OnPaint(e);
1202                         return;
1203                     }
1204
1205                     using (BufferedTheme bufferedTheme = new BufferedTheme(this.themeConfigDialog.bufferedTheme))
1206                         base.OnPaint(e);
1207                 }
1208
1209                 protected override void OnLayout(LayoutEventArgs levent)
1210                 {
1211                     if (this.themeConfigDialog != null)
1212                     {
1213                         using (BufferedTheme bufferedTheme = new BufferedTheme(this.themeConfigDialog.bufferedTheme))
1214                             base.OnLayout(levent);
1215
1216                         Size maxExtent = ActiveLayout.Extent;
1217                         Size size = Size;
1218                         PointF zoom = new PointF((float)size.Width / (float)maxExtent.Width, (float)size.Height / (float)maxExtent.Height);
1219                         Zoom = Convert.ToInt32((Math.Min(zoom.X, zoom.Y) * 100));
1220                     }
1221                 }
1222
1223                 private void OnThemePropertyChanged(object sender, PropertyValueChangedEventArgs e)
1224                 {
1225                     if (this.themeConfigDialog != null)
1226                     {
1227                         using (BufferedTheme bufferedTheme = new BufferedTheme(this.themeConfigDialog.bufferedTheme))
1228                             base.OnThemeChange(WorkflowTheme.CurrentTheme, EventArgs.Empty);
1229                     }
1230                 }
1231
1232                 #region Class BufferedTheme
1233                 private sealed class BufferedTheme : IDisposable
1234                 {
1235                     private WorkflowTheme oldTheme = null;
1236
1237                     internal BufferedTheme(WorkflowTheme themeToApply)
1238                     {
1239                         if (themeToApply != null && WorkflowTheme.CurrentTheme != themeToApply)
1240                         {
1241                             WorkflowTheme.EnableChangeNotification = false;
1242                             this.oldTheme = WorkflowTheme.CurrentTheme;
1243                             WorkflowTheme.CurrentTheme = themeToApply;
1244                         }
1245                     }
1246
1247                     void IDisposable.Dispose()
1248                     {
1249                         if (this.oldTheme != null && WorkflowTheme.CurrentTheme != this.oldTheme)
1250                         {
1251                             WorkflowTheme.CurrentTheme.ReadOnly = false; //this was themeToApply passed into constructor, need to make it r/w again
1252                             WorkflowTheme.CurrentTheme = this.oldTheme;
1253                             WorkflowTheme.EnableChangeNotification = true;
1254                         }
1255                     }
1256                 }
1257                 #endregion
1258             }
1259             #endregion
1260         }
1261         #endregion
1262     }
1263 }