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
//-----------------------------------------------------------------------------
24
#include "ssdsingleclassbox.h"
25
#include "ssdtripleclassbox.h"
26
#include "ssddoubleclassbox.h"
27
#include "ssdclassnode.h"
28
#include "diagramviewer.h"
29
#include "inputfile.h"
30
#include "outputfile.h"
32
SSDTripleClassBox::SSDTripleClassBox(ShapeView *v, Grafport *g, int x, int y,
33
int w, int h): TripleClassBox(v, g, x, y, w, h) {
34
stereotypeLabel = new TextShape(v, g, this);
35
stereotypeLabel->SetOneLine(True);
36
stereotypeLabel->SetDescription("Stereotype");
37
string my_stereo = "<<SSDTripleClassBox>>";
38
stereotypeLabel->SetString(&my_stereo);
39
propertiesLabel = new TextShape(v, g, this);
40
propertiesLabel->SetOneLine(False);
41
propertiesLabel->SetDescription("Properties");
42
string my_props = "{ SSDTripleClassBox }";
43
propertiesLabel->SetString(&my_props);
44
showStereotype = False;
45
showProperties = False;
46
SetSize(w, RequiredHeight());
49
SSDTripleClassBox::~SSDTripleClassBox() {
50
delete stereotypeLabel;
51
delete propertiesLabel;
54
SSDTripleClassBox::SSDTripleClassBox(const SSDTripleClassBox &s):
56
showStereotype = s.showStereotype;
57
showProperties = s.showProperties;
58
stereotypeLabel = new TextShape(*(s.stereotypeLabel));
59
propertiesLabel = new TextShape(*(s.propertiesLabel));
60
stereotypeLabel->SetParent(this);
61
propertiesLabel->SetParent(this);
62
SetSize(s.GetWidth(), s.GetHeight());
65
SSDTripleClassBox::SSDTripleClassBox(const SSDDoubleClassBox &s):
67
showStereotype = s.IsShowStereotype();
68
showProperties = s.IsShowProperties();
69
stereotypeLabel = new TextShape(*s.GetStereotypeLabel());
70
propertiesLabel = new TextShape(*s.GetPropertiesLabel());
71
stereotypeLabel->SetParent(this);
72
propertiesLabel->SetParent(this);
74
AdjustSizes(GetName()->GetString());
77
SSDTripleClassBox::SSDTripleClassBox(const SSDSingleClassBox &s):
79
showStereotype = s.IsShowStereotype();
80
showProperties = s.IsShowProperties();
81
stereotypeLabel = new TextShape(*s.GetStereotypeLabel());
82
propertiesLabel = new TextShape(*s.GetPropertiesLabel());
83
stereotypeLabel->SetParent(this);
84
propertiesLabel->SetParent(this);
86
AdjustSizes(GetName()->GetString());
89
void SSDTripleClassBox::SetGrafport(Grafport *g) {
90
TripleClassBox::SetGrafport(g);
91
stereotypeLabel->SetGrafport(g);
92
propertiesLabel->SetGrafport(g);
95
void SSDTripleClassBox::SetView(ShapeView *v) {
96
TripleClassBox::SetView(v);
97
stereotypeLabel->SetView(v);
98
propertiesLabel->SetView(v);
101
bool SSDTripleClassBox::HasTextShape(TextShape *t) const {
102
if (TripleClassBox::HasTextShape(t))
104
if (GetStereotypeLabel() == t)
106
if (GetPropertiesLabel() == t)
111
bool SSDTripleClassBox::HasString(const string *s, bool sens, bool sub) const {
112
if (TripleClassBox::HasString(s, sens, sub))
114
if (showStereotype && stereotypeLabel->HasString(s, sens, sub))
116
if (showProperties && propertiesLabel->HasString(s, sens, sub))
121
bool SSDTripleClassBox::HasString(const string *s, bool sens, bool sub,
122
List<TextShape *> *list) {
123
bool b = TripleClassBox::HasString(s, sens, sub, list);
124
if (showStereotype && stereotypeLabel->HasString(s, sens, sub, list))
126
if (showProperties && propertiesLabel->HasString(s, sens, sub, list))
131
void SSDTripleClassBox::SetTextShape() {
132
TripleClassBox::SetTextShape();
134
if (!check(GetSubject() &&
135
GetSubject()->GetClassType()==Code::SSD_CLASS_NODE))
137
GetStereotypeLabel()->SetString(
138
((SSDClassNode *)GetSubject())->GetStereotype());
139
GetStereotypeLabel()->SetParent(this);
140
GetPropertiesLabel()->SetString(
141
((SSDClassNode *)GetSubject())->GetProperties());
142
GetPropertiesLabel()->SetParent(this);
143
// CalcPositionLabels();
146
void SSDTripleClassBox::SetFont(XFont *ft) {
147
TripleClassBox::SetFont(ft);
148
stereotypeLabel->SetFont(ft);
149
propertiesLabel->SetFont(ft);
150
// CalcPositionLabels();
153
void SSDTripleClassBox::SetTextColor(const string *c) {
154
TripleClassBox::SetTextColor(c);
155
stereotypeLabel->SetColor(c);
156
propertiesLabel->SetColor(c);
159
void SSDTripleClassBox::UpdateShowStereotype(bool b) {
160
if (b == showStereotype)
165
// CalcPositionLabels();
170
void SSDTripleClassBox::UpdateShowProperties(bool b) {
171
if (b == showProperties)
176
// CalcPositionLabels();
181
void SSDTripleClassBox::DrawTextShapes() {
182
string oldBackground;
183
Grafport *g = GetGrafport();
184
if (GetFillStyle() != FillStyle::UNFILLED) {
185
oldBackground = *g->GetBackgroundColor();
186
g->SetBackgroundColor(GetFillColor()->getstr());
188
NodeShape::DrawTextShapes();
189
int textHeight = GetName()->GetFontHeight();
190
int addLines = (showStereotype ? 1 : 0);
191
// min_firstboxlines : 2 when no <<stereotype>> / {props} shown
192
int min_firstboxlines = ((showStereotype || showProperties) ? 1 : 2);
193
int labelLines = max(GetName()->GetString()->lines(),min_firstboxlines);
194
// calculate first_compartmentHeight
196
addLines += GetPropertiesLabelString()->lines();
197
int snpHeight = (addLines+labelLines) * textHeight;
198
int dboxHeight = DoubleBoxHeight();
199
if (snpHeight < GetHeight()) {
200
g->DrawLine(GetLeftMost()+1, GetTopMost()+snpHeight+1,
202
GetTopMost()+snpHeight+1);
203
g->SetLineStyle(GetLineStyle());
206
for (GetLabels()->first(); !GetLabels()->done(); GetLabels()->next()) {
209
GetLabels()->cur()->Draw();
211
if (dboxHeight < GetHeight()) {
212
g->SetLineStyle(GetSeparatorLineStyle());
213
g->DrawLine(GetLeftMost()+1, GetTopMost()+dboxHeight,
215
GetTopMost()+dboxHeight);
216
g->SetLineStyle(GetLineStyle());
219
for (GetLabels2()->first(); !GetLabels2()->done(); GetLabels2()->next()) {
222
GetLabels2()->cur()->Draw();
224
if (GetFillStyle() != FillStyle::UNFILLED)
225
g->SetBackgroundColor(oldBackground.getstr());
227
stereotypeLabel->Draw();
229
propertiesLabel->Draw();
232
void SSDTripleClassBox::AdjustSize() {
233
int twd = RequiredWidth();
234
int ht = RequiredHeight();
235
if (twd > GetWidth() || ht != GetHeight()) {
236
int wd = max((twd+2*TEXTMARGIN), GetWidth());
238
GetViewer()->ShapePositionUpdate(this);
241
// CalcPositionLabels();
244
void SSDTripleClassBox::AdjustSizes(const string *) {
245
if (!GetViewer()->IsAutoResize()) {
246
// CalcPositionLabels();
249
int twd = RequiredWidth();
250
int ht = RequiredHeight();
251
if (twd > GetWidth() || GetHeight() != ht) {
252
int wd = max((twd+2*TEXTMARGIN), GetWidth());
254
GetViewer()->ShapePositionUpdate(this);
257
// CalcPositionLabels();
260
void SSDTripleClassBox::CalcPositionLabels() {
261
TripleClassBox::CalcPositionLabels();
263
Point pt = *GetPosition();
264
// calculate labelnameHeight first
265
int textHeight = GetName()->GetFontHeight();
266
int addLines = (showStereotype ? 1 : 0);
267
// min_firstboxlines : 2 when no <<stereotype>> / {props} shown
268
int min_firstboxlines = ((showStereotype || showProperties) ? 1 : 2);
269
int labelLines = max(GetName()->GetString()->lines(),min_firstboxlines);
270
int nameHeight = labelLines * textHeight;
271
// calculate first_compartmentHeight
273
addLines += GetPropertiesLabelString()->lines();
274
int snpHeight = (addLines+labelLines) * textHeight;
277
pt.y = GetTopMost() + textHeight + nameHeight/2;
279
pt.y = GetTopMost() + nameHeight/2;
280
GetName()->SetPosition(&pt);
282
pt.y = GetTopMost() + snpHeight;
283
pt.y += (3*textHeight)/4;
284
for (GetLabels()->first(); !GetLabels()->done(); GetLabels()->next()) {
285
TextShape *t = GetLabels()->cur();
286
// position and left adjust textshape
287
int w = t->GetStringWidth();
288
pt.x = GetLeftMost() + w/2 + TEXTMARGIN;
294
CalcPositionLabels2();
296
// set index label position.
297
pt.x = GetName()->GetPosition()->x + GetWidth()*5/12;
298
pt.y = GetName()->GetPosition()->y - nameHeight/4;
299
GetIndexLabel()->SetPosition(&pt);
302
CalcPositionStereotypeLabel();
304
CalcPositionPropertiesLabel();
307
void SSDTripleClassBox::CalcPositionLabels2() {
308
Point pt = *GetPosition();
309
pt.y = GetTopMost() + DoubleBoxHeight();
310
int textHeight = GetName()->GetFontHeight();
311
pt.y += (3*textHeight)/4;
312
for (GetLabels2()->first(); !GetLabels2()->done(); GetLabels2()->next()) {
313
TextShape *t = GetLabels2()->cur();
314
// position and left adjust textshape
315
int w = t->GetStringWidth();
316
// int h = t->GetHeight();
317
pt.x = GetLeftMost() + w/2 + TEXTMARGIN;
323
void SSDTripleClassBox::CalcPositionStereotypeLabel() {
324
int textHeight = GetName()->GetFontHeight();
326
pt.x = GetPosition()->x;
327
pt.y = GetTopMost() + textHeight/2;
328
stereotypeLabel->SetPosition(&pt);
331
void SSDTripleClassBox::CalcPositionPropertiesLabel() {
332
int textHeight = GetName()->GetFontHeight();
333
int addLines = (showStereotype ? 1 : 0);
334
// min_firstboxlines : 2 when no <<stereotype>> / {props} shown
335
int min_firstboxlines = ((showStereotype || showProperties) ? 1 : 2);
336
int labelLines = max(GetName()->GetString()->lines(),min_firstboxlines);
337
int snHeight = (addLines+labelLines) * textHeight;
339
int propHeight = (showProperties ?
340
GetPropertiesLabelString()->lines()*textHeight : 0);
342
pt.x = GetPosition()->x;
343
pt.y = GetTopMost() + snHeight + propHeight/2;
344
propertiesLabel->SetPosition(&pt);
347
int SSDTripleClassBox::RequiredHeight() {
348
// int textHeight = GetName()->GetFontHeight();
349
int addLines = (showStereotype ? 1 : 0);
350
// min_firstboxlines : 2 when no <<stereotype>> / {props} shown
351
// int min_firstboxlines = ((showStereotype || showProperties) ? 1 : 2);
352
// int labelLines = max(GetName()->GetString()->lines(),min_firstboxlines);
353
// calculate first_compartmentHeight
355
addLines += GetPropertiesLabelString()->lines();
356
// int snpHeight = (addLines+labelLines) * textHeight;
357
// int propHeight = GetPropertiesLabelString()->lines() * textHeight;
359
// int ht = (snpHeight + textHeight + GetLabels()->count()*textHeight);
360
// int ht2 = (snpHeight + int(1.5*textHeight) + GetLabels()->count()*textHeight +
361
// textHeight + GetLabels2()->count()*textHeight);
362
// int dboxHeight = DoubleBoxHeight();
363
int tboxHeight = TripleBoxHeight();
364
return max(tboxHeight, GetInitialHeight());
367
int SSDTripleClassBox::RequiredWidth() {
368
int twidth = GetName()->GetWidth();
370
twidth = max(twidth, GetStereotypeLabel()->GetWidth());
372
twidth = max(twidth, GetPropertiesLabel()->GetWidth());
374
for (GetLabels()->first(); !GetLabels()->done(); GetLabels()->next()) {
375
int wd = GetLabels()->cur()->GetStringWidth();
376
twidth = max(twidth, wd);
378
for (GetLabels2()->first(); !GetLabels2()->done(); GetLabels2()->next()) {
379
int wd = GetLabels2()->cur()->GetStringWidth();
380
twidth = max(twidth, wd);
385
int SSDTripleClassBox::DoubleBoxHeight() {
386
int textHeight = GetName()->GetFontHeight();
387
int addLines = (showStereotype ? 1 : 0);
388
// min_firstboxlines : 2 when no <<stereotype>> / {props} shown
389
int min_firstboxlines = ((showStereotype || showProperties) ? 1 : 2);
390
int labelLines = max(GetName()->GetString()->lines(),min_firstboxlines);
391
// calculate first_compartmentHeight
393
addLines += GetPropertiesLabelString()->lines();
394
int snpHeight = (addLines+labelLines) * textHeight;
396
return int(snpHeight + 1.5*textHeight);
398
return int(snpHeight + (1 + NrLabels())*textHeight);
401
int SSDTripleClassBox::TripleBoxHeight() {
403
int textHeight = GetName()->GetFontHeight();
404
int addLines = (showStereotype ? 1 : 0);
405
// min_firstboxlines : 2 when no <<stereotype>> / {props} shown
406
int min_firstboxlines = ((showStereotype || showProperties) ? 1 : 2);
407
int labelLines = max(GetName()->GetString()->lines(),min_firstboxlines);
408
// calculate first_compartmentHeight
410
addLines += GetPropertiesLabelString()->lines();
411
int snpHeight = (addLines+labelLines) * textHeight;
413
rval1 = int(snpHeight + 1.5*textHeight);
415
rval1 = int(snpHeight + (1 + NrLabels())*textHeight);
416
if (NrLabels2() == 0)
417
rval2 = int(1.0*textHeight);
419
rval2 = int((1 + NrLabels2())*textHeight);
420
return (rval1+rval2);
423
TextShape *SSDTripleClassBox::ChooseTextShape(int x, int y) {
424
// in first part (of the class name) ?
425
int textHeight = GetName()->GetFontHeight();
426
int addLines = (showStereotype ? 1 : 0);
427
// min_firstboxlines : 2 when no <<stereotype>> / {props} shown
428
int min_firstboxlines = ((showStereotype || showProperties) ? 1 : 2);
429
int labelLines = max(GetName()->GetString()->lines(),min_firstboxlines);
430
int snHeight = (addLines+labelLines) * textHeight;
431
// calculate first_compartmentHeight
433
addLines += GetPropertiesLabelString()->lines();
434
int snpHeight = (addLines+labelLines) * textHeight;
435
int dboxHeight = DoubleBoxHeight();
436
int pos_y = GetTopMost() + snpHeight;
437
int attr_y = GetTopMost() + dboxHeight;
439
if (showStereotype) {
440
if (y <= GetTopMost() + textHeight)
441
return GetStereotypeLabel();
443
if (GetViewer()->IsShowIndexes() && !IsFixedIndexLabel()) {
444
if (y <= GetName()->GetPosition()->y &&
445
x >= GetName()->GetPosition()->x + GetWidth()/3)
446
return GetIndexLabel();
448
if (y > GetTopMost() + snHeight)
449
return GetPropertiesLabel();
453
else if (y <= attr_y) { // in attribute part
454
pos_y += textHeight/2;
455
for (GetLabels()->first(); !GetLabels()->done();
456
GetLabels()->next()) {
458
if (pos_y >= GetBottomMost())
461
return GetLabels()->cur();
463
if (GetViewer()->IsEditing())
465
// somewhere down the list; create a new label.
466
TextShape *t = new TextShape(GetView(), GetGrafport(), this);
467
t->SetAlignment(TextAlign::LEFT);
468
t->SetSequence(GetLabels()->count());
469
t->SetDescription(&labelDescription);
470
t->SetFont(GetName()->GetFont());
471
t->SetColor(GetName()->GetColor());
474
// CalcPositionLabels();
475
// move text shape to a better position.
476
Point pt = *t->GetPosition();
477
pt.x += GetWidth()/2 - TEXTMARGIN;
482
else { // in operation part
483
pos_y = GetTopMost() + dboxHeight;
484
pos_y += textHeight/2;
485
for (GetLabels2()->first(); !GetLabels2()->done();
486
GetLabels2()->next()) {
488
if (pos_y >= GetBottomMost())
491
return GetLabels2()->cur();
493
if (GetViewer()->IsEditing())
495
// somewhere down the list; create a new label.
496
TextShape *t = new TextShape(GetView(), GetGrafport(), this);
497
t->SetAlignment(TextAlign::LEFT);
498
t->SetSequence(GetLabels2()->count());
499
t->SetDescription(&label2Description);
500
t->SetFont(GetName()->GetFont());
501
t->SetColor(GetName()->GetColor());
503
GetLabels2()->add(t);
504
CalcPositionLabels2();
505
// move text shape to a better position.
506
Point pt = *t->GetPosition();
507
pt.x += GetWidth()/2 - TEXTMARGIN;
512
return 0; // dummy statement shuts up compiler
515
void SSDTripleClassBox::UpdateStereotypeLabelString(const string *s) {
518
SetStereotypeLabelString(s);
523
void SSDTripleClassBox::UpdatePropertiesLabelString(const string *s) {
526
SetPropertiesLabelString(s);
531
bool SSDTripleClassBox::ReadMembers(InputFile *ifile, double format) {
532
if (!TripleClassBox::ReadMembers(ifile, format))
534
if (format >= 1.28) {
536
if (!ifile->ReadAttribute("ShowStereotype", &val))
538
showStereotype = (val == "True");
539
if (!ifile->ReadAttribute("ShowProperties", &val))
541
showProperties = (val == "True");
544
showStereotype = False;
545
showProperties = False;
550
void SSDTripleClassBox::WriteMembers(OutputFile *ofile) {
551
TripleClassBox::WriteMembers(ofile);
552
(*ofile) << "\t{ ShowStereotype " << (showStereotype?"True":"False") << " }\n";
553
(*ofile) << "\t{ ShowProperties " << (showProperties?"True":"False") << " }\n";