380 lines
13 KiB
C#
380 lines
13 KiB
C#
using System;
|
|
using System.Drawing;
|
|
using System.Drawing.Drawing2D;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Runtime.InteropServices;
|
|
using System.Windows.Forms;
|
|
using Newtonsoft.Json;
|
|
|
|
namespace UseCases
|
|
{
|
|
public partial class FrmMain : Form
|
|
{
|
|
[DllImport("kernel32")]
|
|
static extern bool AllocConsole();
|
|
|
|
enum AddAction
|
|
{
|
|
Nothing,
|
|
Actor,
|
|
UseCase
|
|
}
|
|
|
|
public FrmMain()
|
|
{
|
|
//get the command line arguments
|
|
var args = Environment.GetCommandLineArgs();
|
|
|
|
InitializeComponent();
|
|
|
|
//check if there are multiple arguments
|
|
if (args.Count() > 1)
|
|
{
|
|
//check if first arguments is a file
|
|
if (File.Exists(args[1]))
|
|
{
|
|
//try to open the file
|
|
OpenFile(args[1]);
|
|
}
|
|
else
|
|
{
|
|
Diagram = new Diagram();
|
|
//initialise default values
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//initialise default values
|
|
Diagram = new Diagram();
|
|
}
|
|
}
|
|
|
|
#region variables
|
|
|
|
//actors and usecases
|
|
public Diagram Diagram { get; private set; }
|
|
|
|
//drawing variables
|
|
private readonly Font _myFont = new Font("Sans Sherif", 20f, FontStyle.Regular);
|
|
private readonly Pen _drawingPen = new Pen(Color.Black, 3f);
|
|
|
|
//adding elements
|
|
private AddAction _toAdd = AddAction.Nothing;
|
|
|
|
private IDrawable _dragged = null;
|
|
|
|
//edit tracker
|
|
private bool _hasEdited = false;
|
|
|
|
#endregion
|
|
|
|
#region menustrip
|
|
|
|
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
Close();
|
|
}
|
|
|
|
private void btAddActor_Click(object sender, EventArgs e)
|
|
{
|
|
_toAdd = AddAction.Actor;
|
|
}
|
|
|
|
private void btAddUseCase_Click(object sender, EventArgs e)
|
|
{
|
|
_toAdd = AddAction.UseCase;
|
|
}
|
|
|
|
//save in json format
|
|
private void btSave_Click(object sender, EventArgs e)
|
|
{
|
|
//show save file dialog and quit if canceled
|
|
var saveDiag = new SaveFileDialog {Filter = @"*.ucd|*.ucd"};
|
|
if (saveDiag.ShowDialog() != DialogResult.OK) return;
|
|
_hasEdited = false;
|
|
|
|
Diagram.Size = Size;
|
|
Diagram.Maximized = WindowState == FormWindowState.Maximized;
|
|
//save to file
|
|
var serialized = JsonConvert.SerializeObject(Diagram, Utils.SerializerSettings);
|
|
File.WriteAllText(saveDiag.FileName, serialized);
|
|
}
|
|
|
|
//save png format
|
|
private void btSaveImage_Click(object sender, EventArgs e)
|
|
{
|
|
//show save file dialog and quit if canceled
|
|
var saveDiag = new SaveFileDialog {Filter = @"*.png|*.png"};
|
|
if (saveDiag.ShowDialog() != DialogResult.OK) return;
|
|
//create bitmap and draw usecases and actors to it
|
|
var bmp = new Bitmap(Size.Width, Size.Height);
|
|
var g = Graphics.FromImage(bmp);
|
|
DrawElements(g);
|
|
//save image to file
|
|
bmp.Save(saveDiag.FileName);
|
|
}
|
|
|
|
//open json format
|
|
private void btOpen_Click(object sender, EventArgs e)
|
|
{
|
|
//check if anything has been edited
|
|
if (_hasEdited)
|
|
{
|
|
if (
|
|
MessageBox.Show(@"Are you sure you want to load a new file?", @"Load new file",
|
|
MessageBoxButtons.YesNo) == DialogResult.No)
|
|
return;
|
|
}
|
|
|
|
//show open file dialog and quit if canceled
|
|
var openDiag = new OpenFileDialog {Filter = @"*.ucd|*ucd"};
|
|
if (openDiag.ShowDialog() != DialogResult.OK) return;
|
|
//open the file
|
|
OpenFile(openDiag.FileName);
|
|
|
|
Refresh();
|
|
}
|
|
|
|
private void clearToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
//check if user realy wants to clear the diagram else return
|
|
if (MessageBox.Show(@"Are you sure you want to clear the diagram?", @"Clear", MessageBoxButtons.YesNo) !=
|
|
DialogResult.Yes) return;
|
|
//clear lists and refresh screen
|
|
Diagram = new Diagram(new Size(430, 372));
|
|
// _actors.Clear();
|
|
// _useCases.Clear();
|
|
WindowState = FormWindowState.Normal;
|
|
Size = Diagram.Size;
|
|
Refresh();
|
|
}
|
|
|
|
private void controlsToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
MessageBox.Show(@"Pres Ctrl+A or click Add>Actor to add an Actor
|
|
Press Ctrl+U or click File>Use Case to add a Use Case
|
|
Click somwhere on screen to add Use Case or Actor at that position
|
|
Leave name empty to remove
|
|
Click and drag to move usecase or actor
|
|
Press Ctrl+S or click File>Save to save the diagram
|
|
Press Ctrl+Shift+S or click File>Save as image to save diagram as image
|
|
Click File>Clear to clear the diagram
|
|
Press Alt+F4 or click the cross or click File>Exit to close the form
|
|
Click Help>Controls to view this message
|
|
Click Help>About to view information about the application", @"Controls");
|
|
}
|
|
|
|
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
MessageBox.Show(@"Use Case Designer by Rick Rongen
|
|
Version 1.0
|
|
|
|
Developed by order of Fontys Hogerescholen ICT Eindhoven", @"About");
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region functions
|
|
/// <summary>
|
|
/// Opens an file into form and shows error if it could not be loaded
|
|
/// </summary>
|
|
/// <param name="filename">full path of ile to load</param>
|
|
private void OpenFile(string filename)
|
|
{
|
|
//try to open file
|
|
try
|
|
{
|
|
Diagram = JsonConvert.DeserializeObject<Diagram>(File.ReadAllText(filename), Utils.SerializerSettings);
|
|
WindowState = Diagram.Maximized ? FormWindowState.Maximized : FormWindowState.Normal;
|
|
Size = Diagram.Size;
|
|
Refresh();
|
|
}
|
|
catch (JsonException jex)
|
|
{
|
|
//show the console with the error if the user wan't to see it
|
|
if (
|
|
MessageBox.Show(
|
|
$@"Error while loading {filename}\n
|
|
Invallid format or broken data\nGeeks may check console for the exception, pres yes to show console",
|
|
@"Error occured, show console?", MessageBoxButtons.YesNo) == DialogResult.Yes) AllocConsole();
|
|
Console.WriteLine(jex.ToString());
|
|
}
|
|
catch (IOException ioex)
|
|
{
|
|
//show the console with the error if the user wan't to see it
|
|
if (
|
|
MessageBox.Show(
|
|
$@"Error while loading {filename}\nCouldn't open the file or there was an encoding issue.",
|
|
@"Error occured, show console?", MessageBoxButtons.YesNo) == DialogResult.Yes) AllocConsole();
|
|
Console.WriteLine(ioex.ToString());
|
|
}
|
|
finally
|
|
{
|
|
_hasEdited = false;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Draws all ellements in actors and useCases to the graphics object
|
|
/// </summary>
|
|
/// <param name="g">graphics object</param>
|
|
private void DrawElements(Graphics g)
|
|
{
|
|
g.SmoothingMode = SmoothingMode.AntiAlias;
|
|
foreach (var drawable in Diagram.Drawable)
|
|
{
|
|
drawable.Draw(g, _myFont, _drawingPen);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region mouse
|
|
|
|
//handle creation of components
|
|
private void frmMain_Click(object sender, EventArgs e)
|
|
{
|
|
var pos = PointToClient(MousePosition);
|
|
switch (_toAdd)
|
|
{
|
|
case AddAction.Actor:
|
|
//create new actor
|
|
var adiag = new EditActor();
|
|
if (adiag.ShowDialog() == DialogResult.OK && adiag.ActorName != "")
|
|
{
|
|
Diagram.Actors.Add(new Actor(adiag.ActorName, pos));
|
|
}
|
|
|
|
Refresh();
|
|
break;
|
|
case AddAction.UseCase:
|
|
//create new useCase
|
|
var udiag = new editUseCase(Diagram.Actors) {UseCase = new UseCase(), CasePos = pos};
|
|
if (udiag.ShowDialog() == DialogResult.OK && udiag.UseCase.Name != "")
|
|
{
|
|
Diagram.UseCases.Add(udiag.UseCase);
|
|
udiag.UseCase.Actors.ForEach(Console.WriteLine);
|
|
}
|
|
|
|
Refresh();
|
|
break;
|
|
default:
|
|
case AddAction.Nothing:
|
|
break;
|
|
}
|
|
|
|
_toAdd = AddAction.Nothing;
|
|
if (Diagram.UseCases.Any() || Diagram.Actors.Any()) _hasEdited = true;
|
|
}
|
|
|
|
//handle editing of components
|
|
private void frmMain_DoubleClick(object sender, EventArgs e)
|
|
{
|
|
var mousepos = PointToClient(MousePosition);
|
|
var closest = GetClosestDrawable(mousepos);
|
|
|
|
switch (closest)
|
|
{
|
|
case null:
|
|
return;
|
|
case Actor actor:
|
|
var edAcDiag = new EditActor(actor.Name);
|
|
if (edAcDiag.ShowDialog() == DialogResult.OK)
|
|
{
|
|
if (edAcDiag.ActorName == "")
|
|
{
|
|
//remove actor if name is equal to ""
|
|
Diagram.Actors.Remove(actor);
|
|
foreach (var usecase in Diagram.UseCases)
|
|
{
|
|
//remove this actor from all refering usecases
|
|
usecase.Actors.Remove(actor);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//update name
|
|
actor.Name = edAcDiag.ActorName;
|
|
}
|
|
}
|
|
break;
|
|
case UseCase useCase:
|
|
var edUcDiag = new editUseCase(Diagram.Actors)
|
|
{
|
|
UseCase = useCase,
|
|
CasePos = useCase.Position
|
|
};
|
|
if (edUcDiag.ShowDialog() == DialogResult.OK)
|
|
{
|
|
if (edUcDiag.UseCase.Name == "")
|
|
{
|
|
//remove usecase if name is equal to ""
|
|
Diagram.UseCases.Remove(useCase);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
Refresh();
|
|
}
|
|
|
|
//move usecase or actor
|
|
private void frmMain_MouseUp(object sender, MouseEventArgs e)
|
|
{
|
|
if (e.Button == MouseButtons.Left && _toAdd == AddAction.Nothing)
|
|
{
|
|
_dragged = null;
|
|
}
|
|
}
|
|
|
|
private void frmMain_MouseDown(object sender, MouseEventArgs e)
|
|
{
|
|
//quit if not left mousebutton or adding item
|
|
if (e.Button != MouseButtons.Left || _toAdd != AddAction.Nothing) return;
|
|
|
|
//get mouse position in client
|
|
var mousepos = PointToClient(MousePosition);
|
|
|
|
var closest = GetClosestDrawable(mousepos);
|
|
if (closest == null)
|
|
return;
|
|
_dragged = closest;
|
|
}
|
|
|
|
private void frmMain_MouseMove(object sender, MouseEventArgs e)
|
|
{
|
|
if (_dragged == null) return;
|
|
_dragged.Position = PointToClient(MousePosition);
|
|
Refresh();
|
|
}
|
|
|
|
private IDrawable GetClosestDrawable(Point position, double maxDistance = 30d)
|
|
{
|
|
if (!Diagram.UseCases.Any() && !Diagram.Actors.Any())
|
|
return null; // No items to check
|
|
var comm = Diagram.Drawable.Select(org => new
|
|
{
|
|
original = org,
|
|
distance = Math.Sqrt(Math.Pow(org.Position.X - position.X, 2) +
|
|
Math.Pow(org.Position.Y - position.Y, 2))
|
|
}).Aggregate((a1, a2) => a1.distance < a2.distance ? a1 : a2);
|
|
return comm.distance > maxDistance ? null : comm.original;
|
|
}
|
|
|
|
#endregion
|
|
|
|
private void frmMain_Paint(object sender, PaintEventArgs e)
|
|
{
|
|
//draw actors, use cases and lines
|
|
DrawElements(e.Graphics);
|
|
}
|
|
|
|
private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
|
|
{
|
|
if (!_hasEdited) return;
|
|
if (MessageBox.Show(@"Are you sure you want to exit?", @"exit", MessageBoxButtons.YesNo) !=
|
|
DialogResult.Yes)
|
|
e.Cancel = true;
|
|
}
|
|
}
|
|
} |