~ubuntu-branches/ubuntu/intrepid/tcm/intrepid

« back to all changes in this revision

Viewing changes to src/sd/dv/ssddiagram.c

  • Committer: Bazaar Package Importer
  • Author(s): Otavio Salvador
  • Date: 2003-07-03 20:08:21 UTC
  • Revision ID: james.westby@ubuntu.com-20030703200821-se4xtqx25e5miczi
Tags: upstream-2.20
ImportĀ upstreamĀ versionĀ 2.20

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//------------------------------------------------------------------------------
 
2
//
 
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).
 
7
//
 
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.
 
12
//
 
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.
 
17
//
 
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
//-----------------------------------------------------------------------------
 
22
#include "ssdgraph.h"
 
23
#include "ssdwindow.h"
 
24
#include "ssdviewer.h"
 
25
#include "ssdchecks.h"
 
26
#include "messagedialog.h"
 
27
#include "ssdtripleclassbox.h"
 
28
#include "ssddoubleclassbox.h"
 
29
#include "ssdsingleclassbox.h"
 
30
#include "ssdsingleobjectbox.h"
 
31
#include "ssddoubleobjectbox.h"
 
32
#include "c2r2line.h"
 
33
#include "ssdr2line.h"
 
34
#include "ssdrcline.h"
 
35
#include "ssdbinaryassociationedge.h"
 
36
#include "ssdobjectlinkedge.h"
 
37
#include "ssdparticipantlinkedge.h"
 
38
#include "ssdgeneralizationedge.h"
 
39
#include "ssdassociationlinkedge.h"
 
40
#include "ssdaggregationedge.h"
 
41
#include "ssdcompositionedge.h"
 
42
#include "commentlink.h"
 
43
#include "ssdclassnode.h"
 
44
#include "ssdobjectnode.h"
 
45
#include "ssdgeneralizationnode.h"
 
46
#include "ssdaggregationnode.h"
 
47
#include "ssdassociationnode.h"
 
48
#include "diamond.h"
 
49
#include "emptyedge.h"
 
50
#include "miniellipse.h"
 
51
#include "blackdot.h"
 
52
#include "textbox.h"
 
53
#include "comment.h"
 
54
#include "notebox.h"
 
55
#include "hexagon.h"
 
56
#include "note.h"
 
57
#include "ssddiagram.h"
 
58
#include <stdio.h>
 
59
#include <limits.h>
 
60
 
 
61
const int SSDDiagram::MINI_ELLIPSE_WIDTH = 8;
 
62
const int SSDDiagram::MINI_ELLIPSE_HEIGHT = 8;
 
63
 
 
64
SSDDiagram::SSDDiagram(Config *c, SSDWindow *d, SSDViewer *v, SSDGraph *g): 
 
65
           ERDiagram(c, d, v, g) {
 
66
        UpdateNodeType(1);
 
67
        UpdateEdgeType(1);
 
68
        ssdChecks = new SSDChecks(this, g);
 
69
}
 
70
 
 
71
SSDDiagram::~SSDDiagram() {
 
72
        delete ssdChecks;
 
73
}
 
74
 
 
75
Thing *SSDDiagram::CreateThing(int classNr) {
 
76
        Grafport *g = GetDiagramViewer()->GetGrafport();
 
77
        ShapeView *v = GetDiagramViewer()->GetCurView();
 
78
        SSDGraph *cg = (SSDGraph *)GetGraph();
 
79
        Thing *thing = 0;
 
80
        if (classNr == Code::VIEW)
 
81
                thing = new ShapeView(GetDiagramViewer());
 
82
 
 
83
        // node shapes (the simple triplebox, doublebox and box are used
 
84
        // in older file formats.
 
85
        else if (classNr==Code::SSD_TRIPLE_CLASS_BOX||classNr==Code::TRIPLE_BOX)
 
86
                thing = new SSDTripleClassBox(v, g, 0, 0); 
 
87
        else if (classNr==Code::SSD_DOUBLE_CLASS_BOX||classNr==Code::DOUBLE_BOX)
 
88
                thing = new SSDDoubleClassBox(v, g, 0, 0); 
 
89
        else if (classNr==Code::SSD_SINGLE_CLASS_BOX||classNr==Code::BOX)
 
90
                thing = new SSDSingleClassBox(v, g, 0, 0); 
 
91
        else if (classNr==Code::SSD_DOUBLE_OBJECT_BOX)
 
92
                thing = new SSDDoubleObjectBox(v, g, 0, 0); 
 
93
        else if (classNr==Code::SSD_SINGLE_OBJECT_BOX)
 
94
                thing = new SSDSingleObjectBox(v, g, 0, 0); 
 
95
        else if (classNr == Code::MINI_ELLIPSE) {
 
96
                MiniEllipse *el = new MiniEllipse(v, g, 0, 0);
 
97
                el->SetResizable(True);
 
98
                thing = el;
 
99
        }
 
100
        else if (classNr == Code::BLACK_DOT)
 
101
                thing = new BlackDot(v, g, 0, 0);
 
102
        else if (classNr==Code::TEXT_BOX)
 
103
                thing = new TextBox(v, g, 0, 0); 
 
104
        else if (classNr==Code::NOTE_BOX)
 
105
                thing = new NoteBox(v, g, 0, 0); 
 
106
        else if (classNr==Code::DIAMOND)
 
107
                thing = new Diamond(v, g, 0, 0); 
 
108
 
 
109
        // lines
 
110
        else if (classNr==Code::T4_LINE || 
 
111
                 classNr==Code::C2R2_LINE)
 
112
                thing = new C2R2Line(v, g, 0, 0, 0);
 
113
        else if (classNr==Code::LINE)
 
114
                thing = new Line(v, g, 0, 0, 0);
 
115
        else if (classNr==Code::SSD_RCLINE)
 
116
                thing = new SSDRCLine(v, g, 0, 0, 0);
 
117
        else if (classNr==Code::SSD_R2LINE || classNr==Code::T2_LINE)
 
118
                thing = new SSDR2Line(v, g, 0, 0, 0);
 
119
 
 
120
        // nodes
 
121
        else if (classNr==Code::CLASS_NODE || classNr==Code::SSD_CLASS_NODE)
 
122
                thing = new SSDClassNode(cg);
 
123
        else if (classNr==Code::SSD_OBJECT_NODE)
 
124
                thing = new SSDObjectNode(cg);
 
125
        else if (classNr==Code::TAXONOMY_JUNCTION || classNr==Code::SSD_GENERALIZATION_NODE)
 
126
                thing = new SSDGeneralizationNode(cg);
 
127
        else if (classNr==Code::SSD_AGGREGATION_NODE)
 
128
                thing = new SSDAggregationNode(cg);
 
129
        else if (classNr == Code::RELATIONSHIP_NODE || classNr==Code::SSD_ASSOCIATION_NODE)
 
130
                thing = new SSDAssociationNode(cg);
 
131
        else if (classNr==Code::NOTE)
 
132
                thing = new Note(cg);
 
133
        else if (classNr==Code::COMMENT)
 
134
                thing = new Comment(cg);
 
135
 
 
136
        // edges
 
137
        else if (classNr==Code::BINARY_RELATIONSHIP || classNr==Code::SSD_BINARY_ASSOCIATION_EDGE)
 
138
                thing = new SSDBinaryAssociationEdge(cg, 0, 0);
 
139
        else if (classNr==Code::SSD_ASSOCIATION_LINK_EDGE)
 
140
                thing = new SSDAssociationLinkEdge(cg, 0, 0);
 
141
        else if (classNr==Code::COMMENT_LINK)
 
142
                thing = new CommentLink(cg, 0, 0);
 
143
        else if (classNr==Code::ISA_RELATIONSHIP || classNr==Code::SSD_GENERALIZATION_EDGE)
 
144
                thing = new SSDGeneralizationEdge(cg, 0, 0);
 
145
        else if (classNr==Code::SSD_OBJECT_LINK_EDGE)
 
146
                thing = new SSDObjectLinkEdge(cg, 0, 0);
 
147
        else if (classNr==Code::SSD_PARTICIPANT_LINK_EDGE)
 
148
                thing = new SSDParticipantLinkEdge(cg, 0, 0);
 
149
        else if (classNr==Code::EMPTY_EDGE)     //Compatibility
 
150
                thing = new EmptyEdge(cg, 0, 0);
 
151
        else if (classNr==Code::SSD_AGGREGATION_EDGE)
 
152
                thing = new SSDAggregationEdge(cg, 0, 0);
 
153
        else if (classNr==Code::SSD_COMPOSITION_EDGE)
 
154
                thing = new SSDCompositionEdge(cg, 0, 0);
 
155
 
 
156
        else
 
157
                error("%s, line %d: impl error: wrong class number %d\n", 
 
158
                        __FILE__, __LINE__, classNr);
 
159
        return thing;
 
160
}
 
161
 
 
162
Node *SSDDiagram::CreateNode(){
 
163
        Node *node = 0;
 
164
        SSDGraph *g = (SSDGraph *)GetGraph();
 
165
 
 
166
        if (GetNodeType()==Code::NOTE)
 
167
                node = new Note(g);
 
168
        else if (GetNodeType()==Code::SSD_GENERALIZATION_NODE)
 
169
                node = new SSDGeneralizationNode(g);
 
170
        else if (GetNodeType()==Code::SSD_AGGREGATION_NODE)
 
171
                node = new SSDAggregationNode(g);
 
172
        else if (GetNodeType()==Code::SSD_CLASS_NODE)
 
173
                node = new SSDClassNode(g);
 
174
        else if (GetNodeType()==Code::SSD_OBJECT_NODE)
 
175
                node = new SSDObjectNode(g);
 
176
        else if (GetNodeType()==Code::SSD_ASSOCIATION_NODE)
 
177
                node = new SSDAssociationNode(g);
 
178
        else if (GetNodeType()==Code::COMMENT)
 
179
                node = new Comment(g);
 
180
        else
 
181
                error( "%s, line %d: impl error: unknown node type\n", 
 
182
                        __FILE__, __LINE__);
 
183
        return node;
 
184
}
 
185
 
 
186
Edge *SSDDiagram::CreateEdge(Subject *subj1, Subject* subj2){
 
187
        if (!CheckEdgeConstraints(subj1, subj2))
 
188
                return 0;
 
189
        Edge* edge = 0;
 
190
        SSDGraph *g = (SSDGraph *)GetGraph();
 
191
        if (GetEdgeType()==Code::COMMENT_LINK)
 
192
                edge = new CommentLink(g, subj1, subj2);
 
193
        else if (GetEdgeType() == Code::SSD_ASSOCIATION_LINK_EDGE)
 
194
                edge = new SSDAssociationLinkEdge(g, subj1, subj2);
 
195
        else if (GetEdgeType() == Code::SSD_BINARY_ASSOCIATION_EDGE)
 
196
                edge = new SSDBinaryAssociationEdge(g, subj1, subj2);
 
197
        else if (GetEdgeType() == Code::SSD_GENERALIZATION_EDGE)
 
198
                edge = new SSDGeneralizationEdge(g, subj1, subj2);
 
199
        else if (GetEdgeType() == Code::SSD_OBJECT_LINK_EDGE)
 
200
                edge = new SSDObjectLinkEdge(g, subj1, subj2);
 
201
        else if (GetEdgeType() == Code::SSD_PARTICIPANT_LINK_EDGE)
 
202
                edge = new SSDParticipantLinkEdge(g, subj1, subj2);
 
203
        else if (GetEdgeType() == Code::SSD_AGGREGATION_EDGE)
 
204
                edge = new SSDAggregationEdge(g, subj1, subj2);
 
205
        else if (GetEdgeType() == Code::SSD_COMPOSITION_EDGE)
 
206
                edge = new SSDCompositionEdge(g, subj1, subj2);
 
207
        else
 
208
                error( "%s, line %d: impl error: unknown edge type\n", 
 
209
                        __FILE__, __LINE__);
 
210
 
 
211
        if (GetEdgeType() == Code::SSD_GENERALIZATION_EDGE) {
 
212
                if (!CheckIsaLoop(edge)) {
 
213
                        delete edge;
 
214
                        return 0;
 
215
                }
 
216
        }
 
217
        return edge;
 
218
}
 
219
 
 
220
NodeShape *SSDDiagram::CreateNodeShape(Node* node, int x, int y) {
 
221
        NodeShape* shape = 0;
 
222
        Grafport *g = GetDiagramViewer()->GetGrafport();
 
223
        ShapeView *v = GetDiagramViewer()->GetCurView();
 
224
        if (GetNodeShapeType() == Code::SSD_SINGLE_CLASS_BOX)
 
225
                shape = new SSDSingleClassBox(v, g, x, y);
 
226
        else if (GetNodeShapeType() == Code::SSD_DOUBLE_CLASS_BOX)
 
227
                shape = new SSDDoubleClassBox(v, g, x, y);
 
228
        else if (GetNodeShapeType() == Code::SSD_TRIPLE_CLASS_BOX)
 
229
                shape = new SSDTripleClassBox(v, g, x, y);
 
230
        else if (GetNodeShapeType() == Code::SSD_SINGLE_OBJECT_BOX)
 
231
                shape = new SSDSingleObjectBox(v, g, x, y);
 
232
        else if (GetNodeShapeType() == Code::SSD_DOUBLE_OBJECT_BOX)
 
233
                shape = new SSDDoubleObjectBox(v, g, x, y);
 
234
        else if (GetNodeShapeType() == Code::MINI_ELLIPSE) {
 
235
                shape = new MiniEllipse(v, g, x, y);
 
236
                shape->SetResizable(True);
 
237
        }
 
238
        else if (GetNodeShapeType() == Code::BLACK_DOT)
 
239
                shape = new BlackDot(v, g, x, y);
 
240
        else if (GetNodeShapeType() == Code::NOTE_BOX)
 
241
                shape = new NoteBox(v, g, x, y);
 
242
        else if (GetNodeShapeType() == Code::TEXT_BOX)
 
243
                shape = new TextBox(v, g, x, y);
 
244
        else if (GetNodeShapeType() == Code::DIAMOND)
 
245
                shape = new Diamond(v, g, x, y);
 
246
        else
 
247
                error( "%s, line %d: impl error: "
 
248
                        "node shape type doesn't exist\n", __FILE__, __LINE__);
 
249
        
 
250
        if (check(shape)) {
 
251
                shape->SetSubject(node);
 
252
                shape->SetTextShape();
 
253
                if (GetNodeShapeType() == Code::MINI_ELLIPSE)
 
254
                        shape->SetFixedName(False);
 
255
        }
 
256
        return shape;
 
257
}
 
258
 
 
259
Line *SSDDiagram::CreateLine(Edge* edge, GShape *from, GShape *to, List<Point*> *l) {
 
260
        Grafport *g = GetDiagramViewer()->GetGrafport();
 
261
        ShapeView *v = GetDiagramViewer()->GetCurView();
 
262
        Line* line = 0;
 
263
        if (GetLineType()== Code::C2R2_LINE)
 
264
                line = new C2R2Line(v, g, from, to, l, IsCurve());
 
265
        else if (GetLineType()== Code::SSD_R2LINE)
 
266
                line = new SSDR2Line(v, g, from, to, l, IsCurve());
 
267
        else if (GetLineType()== Code::SSD_RCLINE)
 
268
                line = new SSDRCLine(v, g, from, to, l, IsCurve());
 
269
        else if (GetLineType()== Code::LINE)
 
270
                line = new Line(v, g, from, to, l, IsCurve());
 
271
        else
 
272
                error( "%s, line %d: impl error: "
 
273
                        "edge shape type does not exist\n", __FILE__, __LINE__);
 
274
        
 
275
        if (check(line)) {
 
276
                line->SetSubject(edge);
 
277
                line->SetTextShape();
 
278
                line->SetEnd1(GetLineEnd1());
 
279
                line->SetEnd2(GetLineEnd2());
 
280
 
 
281
                if (GetEdgeType()==Code::SSD_GENERALIZATION_EDGE) {
 
282
                        if (to->GetClassType()==Code::MINI_ELLIPSE)
 
283
                                line->SetEnd2(LineEnd::EMPTY);
 
284
                }
 
285
 
 
286
                if (GetEdgeType()==Code::SSD_COMPOSITION_EDGE ||
 
287
                    GetEdgeType()==Code::SSD_AGGREGATION_EDGE) {
 
288
                        if (to->GetClassType()==Code::BLACK_DOT)
 
289
                                line->SetEnd2(LineEnd::EMPTY);
 
290
                }
 
291
                if (GetEdgeType()==Code::COMMENT_LINK ||
 
292
                    GetEdgeType()==Code::SSD_AGGREGATION_EDGE ||
 
293
                    GetEdgeType()==Code::SSD_COMPOSITION_EDGE ||
 
294
                    GetEdgeType()==Code::SSD_PARTICIPANT_LINK_EDGE)
 
295
                        line->SetFixedName(True);
 
296
        }
 
297
        return line;
 
298
}
 
299
 
 
300
void SSDDiagram::UpdateNodeType(int num) {
 
301
        ((DiagramWindow *)GetMainWindow())->SetNodeName(num);
 
302
        switch (num) {
 
303
        case 1: SetNodeType(Code::SSD_CLASS_NODE);
 
304
                SetNodeShapeType(Code::SSD_SINGLE_CLASS_BOX);
 
305
                SetNodeLineStyle(LineStyle::SOLID);
 
306
                break;
 
307
        case 2: SetNodeType(Code::SSD_CLASS_NODE);
 
308
                SetNodeShapeType(Code::SSD_DOUBLE_CLASS_BOX);
 
309
                SetNodeLineStyle(LineStyle::SOLID);
 
310
                break;
 
311
        case 3: SetNodeType(Code::SSD_CLASS_NODE);
 
312
                SetNodeShapeType(Code::SSD_TRIPLE_CLASS_BOX);
 
313
                SetNodeLineStyle(LineStyle::SOLID);
 
314
                break;
 
315
        case 4: SetNodeType(Code::SSD_ASSOCIATION_NODE);
 
316
                SetNodeShapeType(Code::DIAMOND);
 
317
                SetNodeLineStyle(LineStyle::SOLID);
 
318
                break;
 
319
        case 5: SetNodeType(Code::COMMENT);
 
320
                SetNodeShapeType(Code::TEXT_BOX);
 
321
                SetNodeLineStyle(LineStyle::INVISIBLE);
 
322
                break;
 
323
        case 6: SetNodeType(Code::SSD_OBJECT_NODE);
 
324
                SetNodeShapeType(Code::SSD_SINGLE_OBJECT_BOX);
 
325
                SetNodeLineStyle(LineStyle::SOLID);
 
326
                break;
 
327
        case 7: SetNodeType(Code::SSD_OBJECT_NODE);
 
328
                SetNodeShapeType(Code::SSD_DOUBLE_OBJECT_BOX);
 
329
                SetNodeLineStyle(LineStyle::SOLID);
 
330
                break;
 
331
        case 8: SetNodeType(Code::NOTE);
 
332
                SetNodeShapeType(Code::NOTE_BOX);
 
333
                SetNodeLineStyle(LineStyle::SOLID);
 
334
                break;
 
335
        case 9: SetNodeType(Code::SSD_GENERALIZATION_NODE);
 
336
                SetNodeShapeType(Code::MINI_ELLIPSE);
 
337
                SetNodeLineStyle(LineStyle::SOLID);
 
338
                break;
 
339
        case 10: SetNodeType(Code::SSD_AGGREGATION_NODE);
 
340
                SetNodeShapeType(Code::BLACK_DOT);
 
341
                SetNodeLineStyle(LineStyle::SOLID);
 
342
                break;
 
343
        default:
 
344
                error("%s, line %d: impl error: "
 
345
                        "unknown node type selected\n", __FILE__,__LINE__);
 
346
        }
 
347
}
 
348
 
 
349
void SSDDiagram::UpdateEdgeType(int num) {
 
350
        ((DiagramWindow *)GetMainWindow())->SetEdgeName(num);
 
351
        switch(num) {
 
352
        case 1: SetEdgeType(Code::SSD_BINARY_ASSOCIATION_EDGE);
 
353
                SetLineType(Code::C2R2_LINE);
 
354
                SetEdgeLineStyle(LineStyle::SOLID);
 
355
                SetLineEnd1(LineEnd::EMPTY);
 
356
                SetLineEnd2(LineEnd::EMPTY);
 
357
                break;
 
358
        case 2: SetEdgeType(Code::SSD_PARTICIPANT_LINK_EDGE);
 
359
                SetLineType(Code::SSD_RCLINE);
 
360
                SetEdgeLineStyle(LineStyle::SOLID);
 
361
                SetLineEnd1(LineEnd::EMPTY);
 
362
                SetLineEnd2(LineEnd::EMPTY);
 
363
                break;
 
364
        case 3: SetEdgeType(Code::SSD_ASSOCIATION_LINK_EDGE);
 
365
                SetLineType(Code::LINE);
 
366
                SetEdgeLineStyle(LineStyle::DASHED);
 
367
                SetLineEnd1(LineEnd::EMPTY);
 
368
                SetLineEnd2(LineEnd::EMPTY);
 
369
                break;
 
370
        case 4: SetEdgeType(Code::COMMENT_LINK);
 
371
                SetLineType(Code::LINE);
 
372
                SetEdgeLineStyle(LineStyle::WIDE_DOTTED);
 
373
                SetLineEnd1(LineEnd::EMPTY);
 
374
                SetLineEnd2(LineEnd::EMPTY);
 
375
                break;
 
376
        case 5: SetEdgeType(Code::SSD_OBJECT_LINK_EDGE);
 
377
                SetLineType(Code::SSD_R2LINE);
 
378
                SetEdgeLineStyle(LineStyle::SOLID);
 
379
                SetLineEnd1(LineEnd::EMPTY);
 
380
                SetLineEnd2(LineEnd::EMPTY);
 
381
                break;
 
382
        case 6: SetEdgeType(Code::SSD_GENERALIZATION_EDGE);
 
383
                SetLineType(Code::LINE);
 
384
                SetEdgeLineStyle(LineStyle::SOLID);
 
385
                SetLineEnd1(LineEnd::EMPTY);
 
386
                SetLineEnd2(LineEnd::WHITE_TRIANGLE);
 
387
                break;
 
388
        case 7: SetEdgeType(Code::SSD_AGGREGATION_EDGE);
 
389
                SetLineType(Code::C2R2_LINE);
 
390
                SetEdgeLineStyle(LineStyle::SOLID);
 
391
                SetLineEnd1(LineEnd::EMPTY);
 
392
                SetLineEnd2(LineEnd::WHITE_DIAMOND);
 
393
                break;
 
394
        case 8: SetEdgeType(Code::SSD_COMPOSITION_EDGE);
 
395
                SetLineType(Code::C2R2_LINE);
 
396
                SetEdgeLineStyle(LineStyle::SOLID);
 
397
                SetLineEnd1(LineEnd::EMPTY);
 
398
                SetLineEnd2(LineEnd::BLACK_DIAMOND);
 
399
                break;
 
400
        default:
 
401
                error("%s, line %d: impl error: "
 
402
                        "unknown edge type selected\n", __FILE__,__LINE__);
 
403
        }
 
404
}
 
405
 
 
406
bool SSDDiagram::SetText(TextShape *t, const string *s) {
 
407
        const string *d = t->GetDescription();
 
408
        Subject *subj = t->GetParent()->GetSubject();
 
409
        if (*d == "Attribute" && subj->GetClassType()==Code::SSD_CLASS_NODE)
 
410
                return SetAttribute((StringListNode*)subj, s, t->GetSequence());
 
411
        else if (*d == "Attribute" && subj->GetClassType()==Code::SSD_OBJECT_NODE)
 
412
                return SetAttribute((StringListNode*)subj, s, t->GetSequence());
 
413
        else if (*d == "Operation" && subj->GetClassType()==Code::SSD_CLASS_NODE)
 
414
                return SetOperation((StringListNode2 *)subj, s, t->GetSequence());
 
415
        else if (*d == "Stereotype" && subj->GetClassType()==Code::SSD_CLASS_NODE)
 
416
                return SetStereotype((SSDClassNode*)subj, s);
 
417
        else if (*d == "Properties" && subj->GetClassType()==Code::SSD_CLASS_NODE)
 
418
                return SetProperties((SSDClassNode*)subj, s);
 
419
        else if (*d == "Role Name" && subj->GetClassType()==Code::SSD_OBJECT_LINK_EDGE)
 
420
                return SetRoleName(subj, s, t->GetSequence());
 
421
        else if (*d == "Role Name" && subj->GetClassType()==Code::SSD_PARTICIPANT_LINK_EDGE)
 
422
                return SetRoleName(subj, s, t->GetSequence());
 
423
        else
 
424
                return ERDiagram::SetText(t, s);
 
425
}
 
426
 
 
427
bool SSDDiagram::SetStereotype(SSDClassNode *object, const string *s) {
 
428
        // StringListNode::StringErrorType reason = object->SetStereotype(s);
 
429
        (void)object->SetStereotype(s);
 
430
        // update all shapes in the viewer.
 
431
        List<GShape *> shapes;
 
432
        GetDiagramViewer()->GetShapes(object, &shapes);
 
433
        for (check(shapes.first()); !shapes.done(); shapes.next()) {
 
434
                const string *str = object->GetStereotype();
 
435
                GShape *shape = shapes.cur();
 
436
                if (check(!shape->IsTextShape())) {
 
437
                        if (shape->GetClassType()==Code::SSD_SINGLE_CLASS_BOX) { 
 
438
                                SSDSingleClassBox *bs = (SSDSingleClassBox *)shape;
 
439
                                bs->UpdateStereotypeLabelString(str); 
 
440
                        }
 
441
                        else if (shape->GetClassType()==Code::SSD_DOUBLE_CLASS_BOX) { 
 
442
                                SSDDoubleClassBox *dbs = (SSDDoubleClassBox *)shape;
 
443
                                dbs->UpdateStereotypeLabelString(str); 
 
444
                        }
 
445
                        else if (shape->GetClassType()==Code::SSD_TRIPLE_CLASS_BOX) { 
 
446
                                SSDTripleClassBox *tbs = (SSDTripleClassBox *)shape;
 
447
                                tbs->UpdateStereotypeLabelString(str); 
 
448
                        }
 
449
                        if (GetDiagramViewer()->IsAutoResize())
 
450
                                shape->AdjustSize();
 
451
                }
 
452
        }
 
453
        IncChanges();
 
454
        return True;
 
455
}
 
456
 
 
457
bool SSDDiagram::SetProperties(SSDClassNode *object, const string *s) {
 
458
        (void) object->SetProperties(s);
 
459
        // StringListNode::StringErrorType reason = object->SetProperties(s);
 
460
        // update all shapes in the viewer.
 
461
        List<GShape *> shapes;
 
462
        GetDiagramViewer()->GetShapes(object, &shapes);
 
463
        for (check(shapes.first()); !shapes.done(); shapes.next()) {
 
464
                const string *str = object->GetProperties();
 
465
                GShape *shape = shapes.cur();
 
466
                if (check(!shape->IsTextShape())) {
 
467
                        if (shape->GetClassType()==Code::SSD_SINGLE_CLASS_BOX) { 
 
468
                                SSDSingleClassBox *bs = (SSDSingleClassBox *)shape;
 
469
                                bs->UpdatePropertiesLabelString(str); 
 
470
                        }
 
471
                        else if (shape->GetClassType()==Code::SSD_DOUBLE_CLASS_BOX) { 
 
472
                                SSDDoubleClassBox *dbs = (SSDDoubleClassBox *)shape;
 
473
                                dbs->UpdatePropertiesLabelString(str); 
 
474
                        }
 
475
                        else if (shape->GetClassType()==Code::SSD_TRIPLE_CLASS_BOX) { 
 
476
                                SSDTripleClassBox *tbs = (SSDTripleClassBox *)shape;
 
477
                                tbs->UpdatePropertiesLabelString(str); 
 
478
                        }
 
479
                        if (GetDiagramViewer()->IsAutoResize())
 
480
                                shape->AdjustSize();
 
481
                }
 
482
        }
 
483
        IncChanges();
 
484
        return True;
 
485
}
 
486
 
 
487
bool SSDDiagram::SetRoleName(Subject *subject, const string *s, unsigned nr) {
 
488
        List<GShape *> shapes;
 
489
        GetDiagramViewer()->GetShapes(subject, &shapes);
 
490
        bool succes = True;
 
491
        if (subject->GetClassType() == Code::SSD_OBJECT_LINK_EDGE) {
 
492
                SSDObjectLinkEdge *edge = (SSDObjectLinkEdge *)subject;
 
493
                if (nr == 1) {
 
494
                        if (!edge->SetRoleName1(s))
 
495
                                succes = False;
 
496
                }
 
497
                else {
 
498
                        if (!edge->SetRoleName2(s))
 
499
                                succes = False;
 
500
                }
 
501
        }
 
502
        else if (subject->GetClassType() == Code::SSD_PARTICIPANT_LINK_EDGE) {
 
503
                succes = ((SSDParticipantLinkEdge *)subject)->SetRoleName(s);
 
504
        }
 
505
 
 
506
        if (!succes) {
 
507
                string txt = "'" + *s + "' is not a possible role name";
 
508
                ShowDialog(MessageDialog::ERROR, "Error", &txt);
 
509
                return False;
 
510
        }
 
511
        if (check(shapes.first())) {
 
512
                do {
 
513
                        Shape *shape = shapes.cur();
 
514
                        if (shape->GetClassType()==Code::SSD_R2LINE) {
 
515
                                if (nr == 1)
 
516
                                        ((SSDR2Line *)shape)->UpdateTextShape1(s);
 
517
                                else 
 
518
                                        ((SSDR2Line *)shape)->UpdateTextShape2(s);
 
519
                        }
 
520
                        else if (shape->GetClassType()==Code::SSD_RCLINE)
 
521
                                ((SSDRCLine *)shape)->UpdateTextShape2(s);
 
522
                } while (shapes.next());
 
523
        }
 
524
        else 
 
525
                return False;
 
526
        return True;
 
527
}
 
528
 
 
529
void SSDDiagram::MakeErrorMessage(StringListNode *,
 
530
                StringListNode::StringErrorType result, const string *s, string *txt) {
 
531
        if (result == StringListNode::STRING_SYNTAX_ERROR)
 
532
                *txt += "syntax error: '" + *s + "'";
 
533
        else if (result == StringListNode::STRING_ALREADY_EXISTS)
 
534
                *txt += "'" + *s + "' already exists";
 
535
}
 
536
 
 
537
bool SSDDiagram::SetAttribute(StringListNode *node, const string *s, unsigned nr) {
 
538
        List <GShape *> shapes;
 
539
        GetDiagramViewer()->GetShapes(node, &shapes);
 
540
        unsigned m = nr;
 
541
        // split string in different strings (separated by newline).
 
542
        // each string becomes a new attribute.
 
543
        string ss(*s);
 
544
        char *str = (char *)ss.getstr();
 
545
        char *x = strtok(str, "\r");
 
546
        char empty[2] = "";
 
547
        if (x == 0)
 
548
                x = empty;
 
549
        while (x != 0) {
 
550
                string *ns = new string(x);
 
551
                bool update = True;
 
552
                StringListNode::StringErrorType result;
 
553
                if (m == nr)
 
554
                        result = node->SetString(ns, m, True);
 
555
                else { // m != r
 
556
                        result = node->SetString(ns, m, False);
 
557
                        update = False;
 
558
                }
 
559
                string txt;
 
560
                MakeErrorMessage(node, result, ns, &txt);
 
561
                if (result != StringListNode::STRING_OK) {
 
562
                        ShowDialog(MessageDialog::ERROR, "Error", &txt);
 
563
                        // delete the newly created attributes.
 
564
                        *ns = "";
 
565
                        for (shapes.first(); !shapes.done(); shapes.next()) {
 
566
                                int type = shapes.cur()->GetClassType();
 
567
                                if (type != Code::BOX && 
 
568
                                    type != Code::SSD_SINGLE_CLASS_BOX) {
 
569
                                        DoubleBox *db = 
 
570
                                                (DoubleBox *)(shapes.cur());
 
571
                                        if (db->NrLabels()-1 == m)
 
572
                                                db->UpdateLabel(ns, m, update);
 
573
                                }
 
574
                        }
 
575
                        delete ns;
 
576
                        return False;
 
577
                }
 
578
                // update the double box shapes.
 
579
                for (shapes.first(); !shapes.done(); shapes.next()) {
 
580
                        int type = shapes.cur()->GetClassType();
 
581
                        if (type != Code::BOX && 
 
582
                            type != Code::SSD_SINGLE_CLASS_BOX)
 
583
                                ((DoubleBox *)shapes.cur())->UpdateLabel(ns, m, update);
 
584
                }
 
585
                if (!shapes.first()) {
 
586
                        error( "%s, line %d: impl error: "
 
587
                                "shape does not exist!\n", __FILE__, __LINE__);
 
588
                        return False;
 
589
                }
 
590
                m++;
 
591
                x = strtok(0, "\r");
 
592
                delete ns;
 
593
        }
 
594
        return True;
 
595
}
 
596
 
 
597
bool SSDDiagram::SetOperation(StringListNode2 *node, const string *s, unsigned nr) {
 
598
        List<GShape *> shapes;
 
599
        GetDiagramViewer()->GetShapes(node, &shapes);
 
600
        string ss(*s);
 
601
        char *str = (char *)ss.getstr();
 
602
        unsigned m = nr;
 
603
        char *x = strtok(str, "\r");
 
604
        char empty[2] = "";
 
605
        if (x == 0)
 
606
                x = empty;
 
607
        while (x != 0) {
 
608
                string *ns = new string(x);
 
609
                bool update = True;
 
610
                StringListNode::StringErrorType result;
 
611
                if (m == nr) {
 
612
                        result = node->SetString2(ns, m, True);
 
613
                }
 
614
                else { // m != r
 
615
                        result = node->SetString2(ns, m, False);
 
616
                        update = False;
 
617
                }
 
618
                string txt;
 
619
                MakeErrorMessage(node, result, ns, &txt);
 
620
                if (result != StringListNode::STRING_OK) {
 
621
                        ShowDialog(MessageDialog::ERROR, "Error", &txt);
 
622
                        // delete the newly created operations.
 
623
                        *ns = "";
 
624
                        for (shapes.first(); !shapes.done(); shapes.next()) {
 
625
                                if (shapes.cur()->GetClassType() == 
 
626
                                                Code::SSD_TRIPLE_CLASS_BOX) {
 
627
                                        TripleBox *tb = 
 
628
                                                (TripleBox *)(shapes.cur());
 
629
                                        if (tb->NrLabels2()-1 == m)
 
630
                                                tb->UpdateLabel2(ns, m, update);
 
631
                                }
 
632
                        }
 
633
                        delete ns;
 
634
                        return False;
 
635
                }
 
636
                // update the triple box shapes.
 
637
                for (shapes.first(); !shapes.done(); shapes.next()) {
 
638
                        if (shapes.cur()->GetClassType() == Code::SSD_TRIPLE_CLASS_BOX) 
 
639
                                ((TripleBox *)shapes.cur())->
 
640
                                        UpdateLabel2(ns, m, update);
 
641
                } 
 
642
                if (!shapes.first()) {
 
643
                        error( "%s, line %d: impl error: "
 
644
                                "shape does not exist!\n", __FILE__, __LINE__);
 
645
                        return False;
 
646
                }
 
647
                m++;
 
648
                x = strtok(0, "\r");
 
649
                delete ns;
 
650
        }
 
651
        return True;
 
652
}
 
653
 
 
654
 
 
655
void SSDDiagram::CheckDocument() {
 
656
        chkbuf = "";
 
657
        unsigned total = 0;
 
658
        total += ssdChecks->CheckDoubleNamelessEdges(
 
659
                        Code::SSD_BINARY_ASSOCIATION_EDGE, Code::SSD_CLASS_NODE, 
 
660
                        Code::SSD_CLASS_NODE, chkbuf);
 
661
        // Check that object classes are named.
 
662
        total += ssdChecks->CheckNamelessNodes(Code::SSD_CLASS_NODE, chkbuf);
 
663
        total += ssdChecks->CheckNamelessNodes(Code::SSD_ASSOCIATION_NODE, chkbuf);
 
664
        total += ssdChecks->CheckNamelessNodes(Code::SSD_OBJECT_NODE, chkbuf);
 
665
        // double nodes can occur after cut-copy-paste
 
666
        total += ssdChecks->CheckDoubleNodes(Code::SSD_CLASS_NODE, chkbuf);
 
667
        total += ssdChecks->CheckDoubleNodes(Code::SSD_OBJECT_NODE, chkbuf);
 
668
        ReportCheck(total, &chkbuf);
 
669
}