1
//------------------------------------------------------------------------------
3
// This file is part of Toolkit for Conceptual Modeling (TCM).
4
// (c) copyright 1999, Vrije Universiteit Amsterdam and University of Twente.
5
// Author: Frank Dehne (frank@cs.vu.nl).
6
// Author: Henk van de Zandschulp (henkz@cs.utwente.nl).
8
// TCM is free software; you can redistribute it and/or modify
9
// it under the terms of the GNU General Public License as published by
10
// the Free Software Foundation; either version 2 of the License, or
11
// (at your option) any later version.
13
// TCM is distributed in the hope that it will be useful,
14
// but WITHOUT ANY WARRANTY; without even the implied warranty of
15
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
// GNU General Public License for more details.
18
// You should have received a copy of the GNU General Public License
19
// along with TCM; if not, write to the Free Software Foundation, Inc.,
20
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
//-----------------------------------------------------------------------------
26
#include "messagedialog.h"
27
#include "ucdsingleclassbox.h"
29
#include "ucdactornode.h"
30
#include "ucdusecasenode.h"
31
#include "ucdbinaryassociationedge.h"
32
#include "ucdboundarybox.h"
33
#include "ucdgeneralizationedge.h"
34
#include "commentlink.h"
35
#include "ucdsystemnode.h"
41
#include "ucdiagram.h"
46
UCDiagram::UCDiagram(Config *c, UCWindow *d, UCViewer *v, UCGraph *g):
47
ERDiagram(c, d, v, g) {
50
ucChecks = new UCChecks(this, g);
53
UCDiagram::~UCDiagram() {
57
Thing *UCDiagram::CreateThing(int classNr) {
58
Grafport *g = GetDiagramViewer()->GetGrafport();
59
ShapeView *v = GetDiagramViewer()->GetCurView();
60
UCGraph *cg = (UCGraph *)GetGraph();
62
if (classNr == Code::VIEW)
63
thing = new ShapeView(GetDiagramViewer());
66
else if (classNr==Code::UCD_SINGLE_CLASS_BOX)
67
thing = new UCDSingleClassBox(v, g, 0, 0);
68
else if (classNr == Code::STICKMAN)
69
thing = new StickMan(v, g, 0, 0);
70
else if (classNr == Code::ELLIPSE)
71
thing = new Ellipse(v, g, 0, 0);
72
else if (classNr == Code::UCD_BOUNDARY_BOX)
73
thing = new UCDBoundaryBox(v, g, 0, 0);
74
else if (classNr==Code::NOTE_BOX)
75
thing = new NoteBox(v, g, 0, 0);
76
else if (classNr==Code::TEXT_BOX)
77
thing = new TextBox(v, g, 0, 0);
80
else if (classNr==Code::T4_LINE || classNr==Code::C2R2_LINE)
81
thing = new C2R2Line(v, g, 0, 0, 0);
82
else if (classNr==Code::LINE)
83
thing = new Line(v, g, 0, 0, 0);
86
else if (classNr==Code::UCD_ACTOR_NODE)
87
thing = new UCDActorNode(cg);
88
else if (classNr==Code::UCD_USE_CASE_NODE)
89
thing = new UCDUseCaseNode(cg);
90
else if (classNr==Code::UCD_SYSTEM_NODE)
91
thing = new UCDSystemNode(cg);
92
else if (classNr==Code::COMMENT)
93
thing = new Comment(cg);
94
else if (classNr==Code::NOTE)
98
else if (classNr==Code::BINARY_RELATIONSHIP || classNr==Code::UCD_BINARY_ASSOCIATION_EDGE)
99
thing = new UCDBinaryAssociationEdge(cg, 0, 0);
100
else if (classNr==Code::ISA_RELATIONSHIP || classNr==Code::UCD_GENERALIZATION_EDGE)
101
thing = new UCDGeneralizationEdge(cg, 0, 0);
102
else if (classNr==Code::COMMENT_LINK)
103
thing = new CommentLink(cg, 0, 0);
106
error("%s, line %d: impl error: wrong class number %d\n",
107
__FILE__, __LINE__, classNr);
111
Node *UCDiagram::CreateNode(){
113
UCGraph *g = (UCGraph *)GetGraph();
115
if (GetNodeType()==Code::UCD_ACTOR_NODE)
116
node = new UCDActorNode(g);
117
else if (GetNodeType()==Code::UCD_USE_CASE_NODE)
118
node = new UCDUseCaseNode(g);
119
else if (GetNodeType()==Code::UCD_SYSTEM_NODE)
120
node = new UCDSystemNode(g);
121
else if (GetNodeType()==Code::COMMENT)
122
node = new Comment(g);
123
else if (GetNodeType()==Code::NOTE)
126
error( "%s, line %d: impl error: unknown node type\n",
131
Edge *UCDiagram::CreateEdge(Subject *subj1, Subject* subj2){
132
if (!CheckEdgeConstraints(subj1, subj2))
135
UCGraph *g = (UCGraph *)GetGraph();
136
if (GetEdgeType() == Code::UCD_BINARY_ASSOCIATION_EDGE)
137
edge = new UCDBinaryAssociationEdge(g, subj1, subj2);
138
else if (GetEdgeType() == Code::UCD_GENERALIZATION_EDGE)
139
edge = new UCDGeneralizationEdge(g, subj1, subj2);
140
else if (GetEdgeType()==Code::COMMENT_LINK)
141
edge = new CommentLink(g, subj1, subj2);
143
error( "%s, line %d: impl error: unknown edge type\n",
146
if (GetEdgeType() == Code::UCD_GENERALIZATION_EDGE) {
147
if (!CheckIsaLoop(edge)) {
155
NodeShape *UCDiagram::CreateNodeShape(Node* node, int x, int y) {
156
NodeShape* shape = 0;
157
Grafport *g = GetDiagramViewer()->GetGrafport();
158
ShapeView *v = GetDiagramViewer()->GetCurView();
159
if (GetNodeShapeType() == Code::STICKMAN)
160
shape = new StickMan(v, g, x, y);
161
else if (GetNodeShapeType() == Code::UCD_SINGLE_CLASS_BOX)
162
shape = new UCDSingleClassBox(v, g, x, y);
163
else if (GetNodeShapeType() == Code::ELLIPSE)
164
shape = new Ellipse(v, g, x, y);
165
else if (GetNodeShapeType() == Code::UCD_BOUNDARY_BOX)
166
shape = new UCDBoundaryBox(v, g, x, y);
167
else if (GetNodeShapeType() == Code::TEXT_BOX)
168
shape = new TextBox(v, g, x, y);
169
else if (GetNodeShapeType() == Code::NOTE_BOX)
170
shape = new NoteBox(v, g, x, y);
172
error( "%s, line %d: impl error: "
173
"node shape type doesn't exist\n", __FILE__, __LINE__);
176
shape->SetSubject(node);
177
shape->SetTextShape();
182
Line *UCDiagram::CreateLine(Edge* edge, GShape *from, GShape *to, List<Point*> *l) {
183
Grafport *g = GetDiagramViewer()->GetGrafport();
184
ShapeView *v = GetDiagramViewer()->GetCurView();
186
if (GetLineType()== Code::C2R2_LINE)
187
line = new C2R2Line(v, g, from, to, l, IsCurve());
188
else if (GetLineType()== Code::LINE)
189
line = new Line(v, g, from, to, l, IsCurve());
191
error( "%s, line %d: impl error: "
192
"edge shape type does not exist\n", __FILE__, __LINE__);
195
line->SetSubject(edge);
196
line->SetTextShape();
197
line->SetEnd1(GetLineEnd1());
198
line->SetEnd2(GetLineEnd2());
200
if (GetEdgeType()==Code::COMMENT_LINK)
201
line->SetFixedName(True);
206
void UCDiagram::UpdateNodeType(int num) {
207
((DiagramWindow *)GetMainWindow())->SetNodeName(num);
209
case 1: SetNodeType(Code::UCD_ACTOR_NODE);
210
SetNodeShapeType(Code::STICKMAN);
211
SetNodeLineStyle(LineStyle::SOLID);
213
case 2: SetNodeType(Code::UCD_ACTOR_NODE);
214
SetNodeShapeType(Code::UCD_SINGLE_CLASS_BOX);
215
SetNodeLineStyle(LineStyle::SOLID);
217
case 3: SetNodeType(Code::UCD_USE_CASE_NODE);
218
SetNodeShapeType(Code::ELLIPSE);
219
SetNodeLineStyle(LineStyle::SOLID);
221
case 4: SetNodeType(Code::UCD_SYSTEM_NODE);
222
SetNodeShapeType(Code::UCD_BOUNDARY_BOX);
223
SetNodeLineStyle(LineStyle::SOLID);
225
case 5: SetNodeType(Code::NOTE);
226
SetNodeShapeType(Code::NOTE_BOX);
227
SetNodeLineStyle(LineStyle::SOLID);
229
case 6: SetNodeType(Code::COMMENT);
230
SetNodeShapeType(Code::TEXT_BOX);
231
SetNodeLineStyle(LineStyle::INVISIBLE);
234
error("%s, line %d: impl error: "
235
"unknown node type selected\n", __FILE__,__LINE__);
239
void UCDiagram::UpdateEdgeType(int num) {
240
((DiagramWindow *)GetMainWindow())->SetEdgeName(num);
242
case 1: SetEdgeType(Code::UCD_BINARY_ASSOCIATION_EDGE);
243
SetLineType(Code::C2R2_LINE);
244
SetEdgeLineStyle(LineStyle::SOLID);
245
SetLineEnd1(LineEnd::EMPTY);
246
SetLineEnd2(LineEnd::EMPTY);
248
case 2: SetEdgeType(Code::UCD_GENERALIZATION_EDGE);
249
SetLineType(Code::LINE);
250
SetEdgeLineStyle(LineStyle::SOLID);
251
SetLineEnd1(LineEnd::EMPTY);
252
SetLineEnd2(LineEnd::WHITE_TRIANGLE);
254
case 3: SetEdgeType(Code::COMMENT_LINK);
255
SetLineType(Code::LINE);
256
SetEdgeLineStyle(LineStyle::WIDE_DOTTED);
257
SetLineEnd1(LineEnd::EMPTY);
258
SetLineEnd2(LineEnd::EMPTY);
262
error("%s, line %d: impl error: "
263
"unknown edge type selected\n", __FILE__,__LINE__);
267
void UCDiagram::CheckDocument() {
270
// Check that actors and use cases are named.
271
total += ucChecks->CheckNamelessNodes(Code::UCD_ACTOR_NODE, chkbuf);
272
total += ucChecks->CheckNamelessNodes(Code::UCD_USE_CASE_NODE, chkbuf);
274
// double nodes can occur after cut-copy-paste
275
total += ucChecks->CheckDoubleNodes(Code::UCD_ACTOR_NODE, chkbuf);
276
total += ucChecks->CheckDoubleNodes(Code::UCD_USE_CASE_NODE, chkbuf);
278
ReportCheck(total, &chkbuf);
281
bool UCDiagram::CheckEdgeConstraints(Subject *subj1, Subject *subj2) {
282
// Check possible connections (subj-subj-edge matrix).
283
if (!CheckConnection(subj1, subj2))
285
// int subj1Type = subj1->GetClassType();
286
// int subj2Type = subj2->GetClassType();
287
// Check for double is_a between same nodes.
288
if (GetEdgeType()==Code::UCD_GENERALIZATION_EDGE &&
289
GetGraph()->IsConnected(subj1, subj2, Code::UCD_GENERALIZATION_EDGE)) {
290
string txt = "Cannot add another ";
291
txt += Code::GetName(GetEdgeType());
293
ShowDialog(MessageDialog::ERROR, "Error", &txt);
300
bool UCDiagram::CheckIsaLoop(Edge *edge) {
301
if (GetEdgeType() == Code::UCD_GENERALIZATION_EDGE) {
302
GetGraph()->AddEdge(edge);
303
Subject *n1 = edge->GetSubject1();
304
if (GetGraph()->PathExists(n1, n1, Code::UCD_GENERALIZATION_EDGE)) {
305
string txt = "'is_a loops' are not allowed";
306
ShowDialog(MessageDialog::ERROR, "Error", &txt);
307
GetGraph()->RemoveEdge(edge);
310
GetGraph()->RemoveEdge(edge);
315
bool UCDiagram::SetText(TextShape *t, const string *s) {
316
const string *description = t->GetDescription();
317
Subject *subj = t->GetParent()->GetSubject();
318
if (*description == "Cardinality Constraint")
319
return SetConstraint(subj, s, t->GetSequence());
320
else if (*description == "Role Name")
321
return SetRoleName(subj, s, t->GetSequence()%2);
323
return Diagram::SetText(t, s);
326
bool UCDiagram::SetConstraint(Subject *subject, const string *s, unsigned nr) {
327
List<GShape *> shapes;
328
GetDiagramViewer()->GetShapes(subject, &shapes);
329
bool wrong_syntax = False;
330
Edge *e = (Edge *)subject;
331
int eType = e->GetClassType();
332
if (eType == Code::UCD_BINARY_ASSOCIATION_EDGE) {
333
BinaryRelationship *edge = (BinaryRelationship *)subject;
335
if (!edge->SetConstraint1(s))
339
if (!edge->SetConstraint2(s))
344
string txt = "'" + *s + "' wrong syntax\n for a "
345
"cardinality constraint";
346
ShowDialog(MessageDialog::ERROR, "Error", &txt);
349
if (check(shapes.first())) {
352
((C2R2Line *)shapes.cur())->UpdateTextShape1(s);
354
((C2R2Line *)shapes.cur())->UpdateTextShape2(s);
356
while (shapes.next());
363
bool UCDiagram::SetRoleName(Subject *subject, const string *s, unsigned nr) {
364
List<GShape *> shapes;
365
GetDiagramViewer()->GetShapes(subject, &shapes);
366
BinaryRelationship *edge = (BinaryRelationship *)subject;
369
if (!edge->SetRoleName1(s))
373
if (!edge->SetRoleName2(s))
377
string txt = "'" + *s + "' is not a possible role name";
378
ShowDialog(MessageDialog::ERROR, "Error", &txt);
381
if (check(shapes.first())) {
383
Shape *shape = shapes.cur();
385
((C2R2Line *)shape)->UpdateTextShape3(s);
387
((C2R2Line *)shape)->UpdateTextShape4(s);
388
} while (shapes.next());