public void ExecuteCustomAction([NotNull] IActionDefinition action) { string text = null; bool warning = false; try { switch (action.Name) { case "AddThreatType": using (var dialog = new ThreatTypeCreationDialog(_model)) { if (dialog.ShowDialog(Form.ActiveForm) == DialogResult.OK) { text = "Add Threat Type"; } } break; case "AddMitigation": if (_currentRow.Tag is IThreatType threatType2) { using (var dialog2 = new ThreatTypeMitigationSelectionDialog(threatType2)) { if (dialog2.ShowDialog(Form.ActiveForm) == DialogResult.OK) { text = "Add Mitigation"; } } } break; case "RemoveThreatType": var selected = _currentRow?.GridPanel?.SelectedCells?.OfType <GridCell>() .Select(x => x.GridRow) .Where(x => x.Tag is IThreatType) .Distinct() .ToArray(); if (_currentRow != null) { if ((selected?.Length ?? 0) > 1) { var outcome = MessageBox.Show(Form.ActiveForm, $"You have selected {selected.Length} Threat Types. Do you want to remove them all?\nPlease click 'Yes' to remove all selected Threat Types,\nNo to remove only the last one you selected, '{_currentRow?.Tag?.ToString()}'.\nPress Cancel to abort.", "Remove Threat Types", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button3); switch (outcome) { case DialogResult.Yes: bool removed = true; foreach (var row in selected) { bool r = false; if (row.Tag is IThreatType tt) { r = _model.RemoveThreatType(tt.Id); } removed &= r; if (r && row == _currentRow) { _properties.Item = null; _currentRow = null; } } if (removed) { text = "Remove Threat Types"; } else { warning = true; text = "One or more Threat Types cannot be removed."; } break; case DialogResult.No: if (_currentRow != null && _currentRow.Tag is IThreatType tt2) { if (_model.RemoveThreatType(tt2.Id)) { _properties.Item = null; _currentRow = null; text = "Remove Threat Type"; } else { warning = true; text = "The Threat Type cannot be removed."; } } break; } } else if (_currentRow != null && _currentRow.Tag is IThreatType threatType3 && MessageBox.Show(Form.ActiveForm, $"You are about to remove Threat Type '{threatType3.Name}'. Are you sure?", "Remove Threat Type", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.Yes) { if (_model.RemoveThreatType(threatType3.Id)) { text = "Threat Type removal"; _properties.Item = null; } else { warning = true; text = "The Threat Type cannot be removed."; } } } break; case "RemoveMitigation": var selected2 = _currentRow?.GridPanel?.SelectedCells?.OfType <GridCell>() .Select(x => x.GridRow) .Where(x => x.Tag is IThreatTypeMitigation) .Distinct() .ToArray(); if (_currentRow != null) { if ((selected2?.Length ?? 0) > 1) { var name = (_currentRow.Tag as IThreatTypeMitigation)?.Mitigation.Name; var outcome = MessageBox.Show(Form.ActiveForm, $"You have selected {selected2.Length} Mitigations associations. Do you want to remove them all?\nPlease click 'Yes' to remove all selected Mitigations associations,\nNo to remove only the last one you selected, '{name}'.\nPress Cancel to abort.", "Remove Mitigations associations", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button3); switch (outcome) { case DialogResult.Yes: bool removed = true; foreach (var row in selected2) { bool r = false; if (row.Tag is IThreatTypeMitigation m && m.ThreatType is IThreatType mThreatType) { r = mThreatType.RemoveMitigation(m.MitigationId); } removed &= r; if (r && row == _currentRow) { _properties.Item = null; _currentRow = null; } } if (removed) { text = "Remove Mitigation associations"; } else { warning = true; text = "One or more Mitigation associations cannot be removed."; } break; case DialogResult.No: if (_currentRow != null && _currentRow.Tag is IThreatTypeMitigation m2 && m2.ThreatType is IThreatType m2ThreatType) { if (m2ThreatType.RemoveMitigation(m2.MitigationId)) { _properties.Item = null; _currentRow = null; text = "Remove Mitigation association"; } else { warning = true; text = "The Mitigation association cannot be removed."; } } break; } } else if (_currentRow != null && _currentRow.Tag is IThreatTypeMitigation mitigation && MessageBox.Show(Form.ActiveForm, $"You are about to disassociate Mitigation '{mitigation.Mitigation.Name}'. Are you sure?", "Remove Mitigation association", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.Yes) { if (mitigation.ThreatType.RemoveMitigation(mitigation.MitigationId)) { text = "Remove Mitigation association"; _properties.Item = null; } else { warning = true; text = "The Mitigation association cannot be removed."; } } } break; case "OpenAllNodes": try { _loading = true; _grid.PrimaryGrid.ExpandAll(10); Application.DoEvents(); } finally { _loading = false; } break; case "OpenBranch": try { _loading = true; if (_currentRow != null) { _currentRow.ExpandAll(10); _currentRow.Expanded = true; Application.DoEvents(); } } finally { _loading = false; } break; case "Collapse": try { _loading = true; _grid.PrimaryGrid.CollapseAll(); Application.DoEvents(); } finally { _loading = false; } break; case "Refresh": LoadModel(); break; } if (warning) { ShowWarning?.Invoke(text); } else if (text != null) { ShowMessage?.Invoke($"{text} has been executed successfully."); } } catch { ShowWarning?.Invoke($"An error occurred during the execution of the action."); throw; } }
public void ExecuteCustomAction([NotNull] IActionDefinition action) { var schemaManager = new ModelConfigPropertySchemaManager(_diagram.Model); var schema = schemaManager.GetSchema(); var hpt = schema.GetPropertyType("Diagram Layout Horizontal Spacing"); var vpt = schema.GetPropertyType("Diagram Layout Vertical Spacing"); var h = _diagram.Model.GetProperty(hpt) as IPropertyInteger; var v = _diagram.Model.GetProperty(vpt) as IPropertyInteger; var hFloat = (float)(h?.Value ?? 150f); var vFloat = (float)(h?.Value ?? 100f); switch (action.Name) { case "CreateExtInteractor": var interactor = _diagram.Model?.AddEntity <IExternalInteractor>(); var p1 = GetFreePoint(new PointF(hFloat, vFloat), new SizeF(100, 100), hFloat, vFloat); AddShape(_diagram.AddShape(interactor, p1)); CheckRefresh(); break; case "CreateProcess": var process = _diagram.Model?.AddEntity <IProcess>(); var p2 = GetFreePoint(new PointF(hFloat, vFloat), new SizeF(100, 100), hFloat, vFloat); AddShape(_diagram.AddShape(process, p2)); CheckRefresh(); break; case "CreateDataStore": var dataStore = _diagram.Model?.AddEntity <IDataStore>(); var p3 = GetFreePoint(new PointF(hFloat, vFloat), new SizeF(100, 100), hFloat, vFloat); AddShape(_diagram.AddShape(dataStore, p3)); CheckRefresh(); break; case "CreateTrustBoundary": var trustBoundary = _diagram.Model?.AddGroup <ITrustBoundary>(); var p4 = GetFreePoint(new PointF(350, 200), new SizeF(600, 300), hFloat, 200 + vFloat); AddShape(_diagram.AddShape(trustBoundary, p4, new SizeF(600, 300))); CheckRefresh(); break; case "CreateThreatType": using (var dialog = new ThreatTypeCreationDialog(_diagram.Model)) { dialog.ShowDialog(Form.ActiveForm); } break; case "RemoveDiagram": if (MessageBox.Show(Form.ActiveForm, "Are you sure you want to remove the current Diagram from the Model?", "Delete Diagram", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.Yes) { if (_factory.Delete(this)) { ShowMessage("Diagram removed successfully."); } else { ShowWarning?.Invoke("Diagram removal has failed."); } } break; case "FixDiagram": var fixDiagram = new FixDiagram(); if (fixDiagram.ShowDialog(Form.ActiveForm) == DialogResult.OK) { switch (fixDiagram.Issue) { case DiagramIssue.TooSmall: HandleTooSmall(); break; case DiagramIssue.TooLarge: HandleTooLarge(); break; } } break; case "AlignH": _graph.AlignHorizontally(); break; case "AlignV": _graph.AlignVertically(); break; case "AlignT": _graph.AlignTops(); break; case "AlignB": _graph.AlignBottoms(); break; case "AlignL": _graph.AlignLeftSides(); break; case "AlignR": _graph.AlignRightSides(); break; case "Layout": if (MessageBox.Show("Are you sure you want to automatically layout the Diagram?", "Automatic Layout confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.Yes) { _graph.DoLayout(h?.Value ?? 200, v?.Value ?? 100); } break; case "MarkerToggle": switch (MarkerStatusTrigger.CurrentStatus) { case MarkerStatus.Full: MarkerStatusTrigger.RaiseMarkerStatusUpdated(MarkerStatus.Hidden); break; case MarkerStatus.Hidden: MarkerStatusTrigger.RaiseMarkerStatusUpdated(MarkerStatus.Full); break; default: throw new ArgumentOutOfRangeException(); } break; case "ZoomIn": _graph.ZoomIn(); break; case "ZoomOut": _graph.ZoomOut(); break; case "ZoomNormal": _graph.ZoomNormal(); break; case "ZoomFit": _graph.ZoomToFit(); break; case "Clipboard": _loading = true; _graph.ToClipboard(); _loading = false; break; case "File": var dialog2 = new SaveFileDialog(); dialog2.CreatePrompt = false; dialog2.OverwritePrompt = true; dialog2.AddExtension = true; dialog2.AutoUpgradeEnabled = true; dialog2.CheckPathExists = true; dialog2.DefaultExt = "png"; dialog2.Filter = "PNG (*.png)|*.png|JPEG (*.jpg)|*.jpg|GIF (*.gif)|Bitmap (*.bmp)"; dialog2.SupportMultiDottedExtensions = true; dialog2.Title = "Export Diagram as Image"; dialog2.RestoreDirectory = true; if (dialog2.ShowDialog(Form.ActiveForm) == DialogResult.OK) { _loading = true; _graph.ToFile(dialog2.FileName); _loading = false; } break; default: if (action.Tag is IShapesContextAwareAction shapesAction) { var selection = _graph.Selection.ToArray(); List <IShape> shapes = new List <IShape>(); List <ILink> links = new List <ILink>(); foreach (var shape in selection) { RecursivelyAddShapes(shapes, links, shape); } if (shapes.Any()) { shapesAction.Execute(shapes, links); } } break; } }