Updates referencesource to .NET 4.7
[mono-project.git] / mcs / class / referencesource / System.WorkflowServices / System / Workflow / Activities / Design / OperationPickerDialog.cs
blob4a7018c1d4b0f0d6b9ae2d9e6becf29a3b022d72
1 //------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation. All rights reserved.
3 //------------------------------------------------------------
5 namespace System.Workflow.Activities.Design
7 using System;
8 using System.Collections.Generic;
9 using System.ComponentModel;
10 using System.Drawing;
11 using System.Reflection;
12 using System.Runtime;
13 using System.ServiceModel;
14 using System.Windows.Forms;
15 using System.Windows.Forms.Design;
16 using System.Workflow.Activities;
17 using System.Workflow.ComponentModel;
18 using System.Workflow.ComponentModel.Design;
20 partial class OperationPickerDialog : Form
22 private OperationInfoBase selectedOperation;
23 private ServiceContractListItemList serviceContracts;
24 private IServiceProvider serviceProvider = null;
26 public OperationPickerDialog(IServiceProvider serviceProvider, bool allowNewContracts)
28 if (serviceProvider == null)
30 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("serviceProvider");
32 this.serviceProvider = serviceProvider;
33 //Set dialog fonts
34 IUIService uisvc = (IUIService) this.serviceProvider.GetService(typeof(IUIService));
35 if (uisvc != null)
37 this.Font = (Font) uisvc.Styles["DialogFont"];
39 InitializeComponent();
40 this.serviceContracts = new ServiceContractListItemList(this.operationsListBox);
41 this.operationsListBox.ServiceProvider = this.serviceProvider;
42 this.toolStripButton1.Visible = allowNewContracts;
45 public OperationInfoBase SelectedOperation
47 get
49 return selectedOperation;
51 internal set
53 if (value == null)
55 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value");
57 selectedOperation = value;
58 SelectServiceOperation(value);
62 public void AddServiceOperation(OperationInfoBase operationInfo, Activity implementingActivity)
64 if (operationInfo == null)
66 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("operationInfo");
69 TypedOperationInfo typedOperationInfo = operationInfo as TypedOperationInfo;
70 OperationInfo workflowOperationInfo = operationInfo as OperationInfo;
71 string contractName = operationInfo.GetContractFullName(null);
72 // Do not add operation if the contractName is not valid. Not throwing here gives the user to fix
73 // a broken contract/operation by selecting a different operation from the UI.
74 if (String.IsNullOrEmpty(contractName))
76 return;
78 ServiceContractListItem serviceContract = this.serviceContracts.Find(contractName);
80 if (typedOperationInfo != null)
82 if (serviceContract == null)
84 serviceContract = new ServiceContractListItem(this.operationsListBox);
85 serviceContract.Validating += new CancelEventHandler(ServiceContractValidating);
86 serviceContract.Name = contractName;
87 serviceContract.ContractType = typedOperationInfo.ContractType;
88 serviceContract.IsCustomContract = false;
89 AddServiceContract(serviceContract);
92 TypedServiceOperationListItem operationItem = new TypedServiceOperationListItem();
93 operationItem.Validating += new CancelEventHandler(ServiceOperationValidating);
94 operationItem.Name = typedOperationInfo.Name;
95 operationItem.Operation = typedOperationInfo;
97 operationItem.ImplementingActivities.Add(implementingActivity);
98 serviceContract.AddOperation(operationItem);
100 else if (workflowOperationInfo != null)
102 if (serviceContract == null)
104 serviceContract = new ServiceContractListItem(this.operationsListBox);
105 serviceContract.Validating += new CancelEventHandler(ServiceContractValidating);
106 serviceContract.Name = workflowOperationInfo.ContractName;
107 serviceContract.IsCustomContract = true;
108 AddServiceContract(serviceContract);
110 WorkflowServiceOperationListItem workflowOperationItem = new WorkflowServiceOperationListItem();
111 workflowOperationItem.Validating += new CancelEventHandler(ServiceOperationValidating);
112 workflowOperationItem.Operation = workflowOperationInfo;
113 workflowOperationItem.ImplementingActivities.Add(implementingActivity);
114 serviceContract.AddOperation(workflowOperationItem);
119 protected override void OnHelpButtonClicked(CancelEventArgs e)
121 e.Cancel = true;
122 GetHelp();
125 protected override void OnHelpRequested(HelpEventArgs e)
127 e.Handled = true;
128 GetHelp();
131 private void AddHelpListItem()
133 if (this.operationsListBox.Items.Count == 0)
135 this.operationsListBox.Items.Add(new HelpListItem());
139 private void addOperationButton_Click(object sender, EventArgs e)
141 ServiceContractListItem serviceContractListItem = this.operationsListBox.SelectedItem as ServiceContractListItem;
142 Fx.Assert(serviceContractListItem != null, "service contract list item cannot be null");
143 Fx.Assert(serviceContractListItem.IsCustomContract, " this should work only on a custom contract item");
144 WorkflowServiceOperationListItem newWorkflowServiceOperationListItem = serviceContractListItem.CreateOperation();
145 newWorkflowServiceOperationListItem.Validating += new CancelEventHandler(ServiceOperationValidating);
146 this.AddServiceOperation(newWorkflowServiceOperationListItem);
147 serviceContractListItem.SelectionOperation(newWorkflowServiceOperationListItem);
150 private void AddServiceContract(ServiceContractListItem serviceContractListItem)
152 String key = serviceContractListItem.Name;
153 if (this.serviceContracts.Find(key) == null)
155 RemoveHelpListItem();
156 serviceContracts.Add(serviceContractListItem);
157 operationsListBox.Items.Add(serviceContractListItem);
160 private void AddServiceOperation(ServiceOperationListItem serviceOperation)
162 if (serviceOperation == null)
164 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("serviceOperation");
166 String key = serviceOperation.ContractName;
167 ServiceContractListItem serviceContract = this.serviceContracts.Find(key);
168 serviceContract.AddOperation(serviceOperation);
169 serviceContract.SelectionOperation(serviceOperation);
172 private void cancelButton_Click(object sender, EventArgs e)
174 this.DialogResult = DialogResult.Cancel;
175 this.Close();
178 private void GetHelp()
180 DesignerHelpers.ShowHelpFromKeyword(this.serviceProvider, typeof(OperationPickerDialog).FullName + ".UI");
182 private List<MethodInfo> GetMethodsFromInterface(Type serviceContractInterfaceType)
184 List<MethodInfo> methodInfos = new List<MethodInfo>();
185 Queue<Type> interfacesQueue = new Queue<Type>();
186 List<Type> interfacesList = new List<Type>();
187 interfacesQueue.Enqueue(serviceContractInterfaceType);
189 while (interfacesQueue.Count > 0)
191 Type currentInterfaceType = interfacesQueue.Dequeue();
192 interfacesList.Add(currentInterfaceType);
193 foreach (Type baseInteface in currentInterfaceType.GetInterfaces())
195 if (!interfacesList.Contains(baseInteface))
197 interfacesQueue.Enqueue(baseInteface);
200 methodInfos.AddRange(currentInterfaceType.GetMethods());
202 return methodInfos;
205 private void ImportContract(Type serviceContractType)
208 foreach (MethodInfo methodInfo in GetMethodsFromInterface(serviceContractType))
210 if (!ServiceOperationHelpers.IsValidServiceOperation(methodInfo))
212 continue;
214 TypedServiceOperationListItem operationItem = new TypedServiceOperationListItem();
215 operationItem.Validating += new CancelEventHandler(ServiceOperationValidating);
216 operationItem.Name = ServiceOperationHelpers.GetOperationName(this.serviceProvider, methodInfo);
217 operationItem.Operation.ContractType = serviceContractType;
218 operationItem.Operation.Name = ServiceOperationHelpers.GetOperationName(this.serviceProvider, methodInfo);
219 this.AddServiceOperation(operationItem);
223 void ImportContractButtonClicked(object sender, EventArgs e)
225 using (TypeBrowserDialog typeBrowserDialog = new TypeBrowserDialog(serviceProvider as IServiceProvider, new ServiceContractsTypeFilterProvider(), "System.String"))
227 typeBrowserDialog.ShowDialog();
228 if (typeBrowserDialog.SelectedType != null)
230 ServiceContractListItem contractItem = new ServiceContractListItem(this.operationsListBox);
231 contractItem.Validating += new CancelEventHandler(ServiceContractValidating);
232 contractItem.Name = typeBrowserDialog.SelectedType.FullName;
233 contractItem.ContractType = typeBrowserDialog.SelectedType;
234 contractItem.IsCustomContract = false;
235 CancelEventArgs cancelEventArgs = new CancelEventArgs();
236 contractItem.Validating.Invoke(contractItem, cancelEventArgs);
237 if (cancelEventArgs.Cancel)
239 return;
241 AddServiceContract(contractItem);
243 ImportContract(typeBrowserDialog.SelectedType);
248 void NewContractButtonClicked(object sender, EventArgs e)
250 ServiceContractListItem contractItem = this.serviceContracts.CreateWithUniqueName();
251 contractItem.Validating += new CancelEventHandler(ServiceContractValidating);
252 contractItem.IsCustomContract = true;
253 this.AddServiceContract(contractItem);
254 WorkflowServiceOperationListItem newWorkflowServiceOperationListItem = contractItem.CreateOperation();
255 newWorkflowServiceOperationListItem.Validating += new CancelEventHandler(ServiceOperationValidating);
256 this.AddServiceOperation(newWorkflowServiceOperationListItem);
257 contractItem.SelectionOperation(newWorkflowServiceOperationListItem);
260 private void okButton_Click(object sender, EventArgs e)
262 object selectedObject = operationsListBox.SelectedItem;
263 if (selectedObject == null)
265 selectedOperation = null;
267 if (selectedObject is TypedServiceOperationListItem)
269 selectedOperation = ((TypedServiceOperationListItem) selectedObject).Operation;
271 else if (selectedObject is WorkflowServiceOperationListItem)
273 selectedOperation = ((WorkflowServiceOperationListItem) selectedObject).Operation;
275 else
277 // dont close the dialog when contracts are selected
278 return;
280 this.DialogResult = DialogResult.OK;
281 this.Close();
284 private void OperationPickerDialogLoad(object sender, EventArgs e)
286 if (this.serviceContracts.Count == 0)
288 AddHelpListItem();
290 foreach (ServiceContractListItem serviceContractListItem in this.serviceContracts)
292 if (!serviceContractListItem.IsCustomContract)
294 ImportContract(serviceContractListItem.ContractType);
297 this.importContractButton.Click += new EventHandler(ImportContractButtonClicked);
298 this.operationsListBox.DoubleClick += new EventHandler(operationsListBox_DoubleClick);
299 this.operationsListBox.SelectedIndexChanged += new EventHandler(operationsListBox_SelectedIndexChanged);
300 this.addOperationButton.Click += new EventHandler(addOperationButton_Click);
301 this.toolStripButton1.Click += new EventHandler(NewContractButtonClicked);
302 this.okButton.Click += new EventHandler(okButton_Click);
305 // This is to make the selected operation the selected item in the operationsListBox.
306 // This needs to be done to work around the Microsoft bug causing selection events to not fire till form is loaded.
307 if (this.selectedOperation != null)
309 SelectServiceOperation(this.selectedOperation);
311 else // select the first operation if no selectedoperation is set
313 if (operationsListBox.Items.Count > 0)
315 operationsListBox.SetSelected(0, true);
321 void operationsListBox_DoubleClick(object sender, EventArgs e)
323 okButton_Click(sender, e);
326 private void operationsListBox_SelectedIndexChanged(object sender, EventArgs e)
328 if (operationsListBox.SelectedItemViewControl != null)
330 this.addOperationButton.Visible = false;
331 detailsViewPanel.Visible = false;
332 // Give the old details control a chance to valiadte its fields before tearing it down.
333 foreach (Control control in detailsViewPanel.Controls)
335 UserControl userControl = control as UserControl;
336 if (userControl != null)
338 userControl.ValidateChildren();
341 detailsViewPanel.Controls.Clear();
342 operationsListBox.SelectedItemViewControl.Dock = DockStyle.Fill;
343 detailsViewPanel.Controls.Add(operationsListBox.SelectedItemViewControl);
344 detailsViewPanel.Visible = true;
345 if (operationsListBox.SelectedItem is ServiceOperationListItem)
347 this.okButton.Enabled = true;
349 else
351 this.okButton.Enabled = false;
352 ServiceContractListItem serviceContractListItem = this.operationsListBox.SelectedItem as ServiceContractListItem;
353 if ((serviceContractListItem != null) && (serviceContractListItem.IsCustomContract))
355 this.addOperationButton.Visible = true;
362 private void RemoveHelpListItem()
364 if (this.operationsListBox.Items.Count > 0 && this.operationsListBox.Items[0] is HelpListItem)
366 this.operationsListBox.Items.Clear();
370 private void SelectServiceOperation(OperationInfoBase operationInfo)
372 Fx.Assert(operationInfo != null, "operationInfo cannot be null");
373 ServiceContractListItem serviceContract = this.serviceContracts.Find(operationInfo.GetContractFullName(null));
374 // Dont select operation if the contract cannot be found in the serviceContracts list
375 if (serviceContract == null)
377 return;
379 ServiceOperationListItem operationItem = null;
380 if (operationInfo is OperationInfo)
382 operationItem = new WorkflowServiceOperationListItem();
383 operationItem.Validating += new CancelEventHandler(ServiceOperationValidating);
385 operationItem.Name = operationInfo.Name;
386 ((WorkflowServiceOperationListItem) operationItem).Operation = operationInfo as OperationInfo;
389 else if (operationInfo is TypedOperationInfo)
391 operationItem = new TypedServiceOperationListItem();
392 operationItem.Validating += new CancelEventHandler(ServiceOperationValidating);
393 operationItem.Name = operationInfo.Name;
394 ((TypedServiceOperationListItem) operationItem).Operation = operationInfo as TypedOperationInfo;
397 serviceContract.SelectionOperation(operationItem);
400 void ServiceContractValidating(object sender, CancelEventArgs e)
402 ServiceContractListItem serviceContractListItem = (ServiceContractListItem) sender;
404 if (string.IsNullOrEmpty(serviceContractListItem.Name))
406 e.Cancel = true;
407 string errorString = SR2.GetString(SR2.ContractNameCannotBeEmpty);
408 DesignerHelpers.ShowMessage(this.serviceProvider, errorString, System.Workflow.ComponentModel.Design.DR.GetString(System.Workflow.ComponentModel.Design.DR.WorkflowDesignerTitle), MessageBoxButtons.OK,
409 MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
412 bool duplicatesFound = false;
413 foreach (ServiceContractListItem foundContract in serviceContracts)
415 if (foundContract == serviceContractListItem)
417 continue;
420 // allow reimport of existing imported contracts
421 if (!serviceContractListItem.IsCustomContract && serviceContractListItem.ContractType.Equals(foundContract.ContractType))
423 continue;
426 if (foundContract.Name.Equals(serviceContractListItem.Name))
428 duplicatesFound = true;
429 break;
433 // contract names must be unique
434 if (duplicatesFound)
437 e.Cancel = true;
438 string errorString = SR2.GetString(SR2.ContractNameMustBeUnique);
439 DesignerHelpers.ShowMessage(this.serviceProvider, errorString, System.Workflow.ComponentModel.Design.DR.GetString(System.Workflow.ComponentModel.Design.DR.WorkflowDesignerTitle), MessageBoxButtons.OK,
440 MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
448 void ServiceOperationValidating(object sender, CancelEventArgs e)
451 ServiceOperationListItem serviceOperationListItem = (ServiceOperationListItem) sender;
452 string newOperationName = serviceOperationListItem.Name;
453 string contractName = serviceOperationListItem.ContractName;
454 if (string.IsNullOrEmpty(newOperationName))
456 e.Cancel = true;
457 string errorString = SR2.GetString(SR2.OperationNameCannotBeEmpty);
458 DesignerHelpers.ShowMessage(this.serviceProvider, errorString, System.Workflow.ComponentModel.Design.DR.GetString(System.Workflow.ComponentModel.Design.DR.WorkflowDesignerTitle), MessageBoxButtons.OK,
459 MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
462 Fx.Assert(!string.IsNullOrEmpty(contractName), "contract name should be valid to run this check");
463 ServiceContractListItem contractListItem = serviceContracts.Find(contractName);
464 Fx.Assert(contractListItem != null, "contract should be present in the list to run this check");
466 // operation names must be unique inside a contract
467 bool duplicatesFound = false;
468 foreach (ServiceOperationListItem foundOperation in contractListItem.Operations)
470 if (foundOperation == serviceOperationListItem)
472 continue;
474 if (foundOperation.Name.Equals(newOperationName))
476 duplicatesFound = true;
477 break;
481 if (duplicatesFound)
484 e.Cancel = true;
485 string errorString = SR2.GetString(SR2.OperationNameMustBeUnique);
486 DesignerHelpers.ShowMessage(this.serviceProvider, errorString, System.Workflow.ComponentModel.Design.DR.GetString(System.Workflow.ComponentModel.Design.DR.WorkflowDesignerTitle), MessageBoxButtons.OK,
487 MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
493 [ListItemView(typeof(HelpListItemViewControl))]
494 [ListItemDetailView(typeof(ListItemViewControl))]
495 private class HelpListItem
499 private class HelpListItemViewControl : ListItemViewControl
502 protected override void OnLoad(EventArgs e)
504 this.Width = this.Parent.Width - 10;
505 Label label = new Label();
506 label.ForeColor = System.Drawing.SystemColors.GrayText;
507 label.Dock = DockStyle.Fill;
508 this.Font = new Font(this.Font, FontStyle.Italic);
509 label.Text = SR2.GetString(SR2.AddOperationsUsingImportAddButtons);
510 this.Controls.Add(label);
514 private class ServiceContractsTypeFilterProvider : ITypeFilterProvider
517 string ITypeFilterProvider.FilterDescription
519 get { return SR2.GetString(SR2.ChooseAServiceContractFromBelow); }
521 bool ITypeFilterProvider.CanFilterType(Type type, bool throwOnError)
523 if (!type.IsInterface)
525 return false;
527 if (type.IsDefined(typeof(ServiceContractAttribute), true))
529 return true;
531 else
533 return false;