1
//------------------------------------------------------------------------------
3
// This file is part of Toolkit for Conceptual Modeling (TCM).
4
// (c) copyright 2001, University of Twente.
5
// Author: Henk van de Zandschulp (henkz@cs.utwente.nl).
7
// TCM is free software; you can redistribute it and/or modify
8
// it under the terms of the GNU General Public License as published by
9
// the Free Software Foundation; either version 2 of the License, or
10
// (at your option) any later version.
12
// TCM is distributed in the hope that it will be useful,
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
// GNU General Public License for more details.
17
// You should have received a copy of the GNU General Public License
18
// along with TCM; if not, write to the Free Software Foundation, Inc.,
19
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
//-----------------------------------------------------------------------------
22
#include "inputfile.h"
23
#include "outputfile.h"
24
#include "cbinteraction.h"
26
#include "cbdmessage.h"
28
#include "shapeview.h"
30
#include "diagramviewer.h"
34
CBInteraction::CBInteraction(CBGraph *g, Subject *n1, Subject *n2):
35
BinaryRelationship(g, n1, n2) {
36
messages = new List<CBDMessage *>;
38
//add an initial message
39
string *dummy_msg = new string("edit this >");
40
SetMessage(dummy_msg, 0 , False);
43
CBInteraction::~CBInteraction() {
49
bool CBInteraction::SetConstraint(string *cons, const string *nm) {
50
// empty constraint is allowed
52
if (*nm == "" || True) { //HZ_TMP 2B solved with bison...
61
Subject::NameErrType CBInteraction::SetMessage(const CBDMessage *m, unsigned n, bool update) {
62
if (*m->GetString() != "" && m->GetString()->letters() == 0)
63
return Subject::IMPOSSIBLE_NAME;
64
// Check for double messages.
66
if (n >= messages->count() ||
67
*(*messages)[n]->GetString() != *m->GetString() || !update)
68
return Subject::HAS_ACTION;
72
if (!update) // add new msg
73
messages->add((CBDMessage *)m);
75
CBDMessage *dummy = (*messages)[n];
76
dummy->SetString(m->GetString());
84
Subject::NameErrType CBInteraction::SetMessage(string *s, unsigned n, bool update) {
86
CBDMessage::DirectionType msgDir = CBDMessage::TOSHAPE; //init
89
if (txt.endsWith(">") || txt.endsWith("v")) {
90
msgDir = CBDMessage::TOSHAPE;
91
txt.remove(); //last char
93
if (txt.endsWith("<") || txt.endsWith("^")) {
94
msgDir = CBDMessage::FROMSHAPE;
95
txt.remove(); //last char
99
if (*s != "" && s->letters() == 0)
100
return Subject::IMPOSSIBLE_NAME;
101
// Check for double messages.
103
if (!update) { // add ??
104
if (*s != "") { // add valid new msg
105
CBDMessage *msg = new CBDMessage(&txt,msgDir, CBDMessage::FLATFLOW);
110
CBDMessage *dummy = (*messages)[n];
112
if ((dummy->GetDirection() != msgDir) &&
113
(msgDir != CBDMessage::NONE)) {
114
dummy->SetDirection(msgDir);
116
dummy->SetString(&txt);
118
messages->removei(n);
120
*s = txt; // return stripped(?) string
126
Subject::NameErrType CBInteraction::SetMessage(string *s, unsigned n, bool update, bool toggle) {
128
CBDMessage::DirectionType msgDir = CBDMessage::TOSHAPE; //init
130
if (update && n>0) { //existing msg : reset init
131
msgDir = (*messages)[n]->GetDirection();
132
} //existing msg : reset init
135
if (txt.endsWith(">") || txt.endsWith("v")) {
136
msgDir = CBDMessage::TOSHAPE;
137
txt.remove(); //last char
139
if (txt.endsWith("<") || txt.endsWith("^")) {
140
msgDir = CBDMessage::FROMSHAPE;
141
txt.remove(); //last char
146
if (txt.endsWith(">") || txt.endsWith("v")) {
147
msgDir = (!toggle ? CBDMessage::TOSHAPE : CBDMessage::FROMSHAPE);
148
txt.remove(); //last char
150
if (txt.endsWith("<") || txt.endsWith("^")) {
151
msgDir = (!toggle ? CBDMessage::FROMSHAPE : CBDMessage::TOSHAPE);
152
txt.remove(); //last char
156
if (*s != "" && s->letters() == 0)
157
return Subject::IMPOSSIBLE_NAME;
158
// Check for double messages.
160
if (!update) { // add ??
161
if (*s != "") { // add valid new msg
162
CBDMessage *msg = new CBDMessage(&txt, msgDir, CBDMessage::FLATFLOW);
167
CBDMessage *dummy = (*messages)[n];
168
if ((dummy->GetDirection() != msgDir) &&
169
(msgDir != CBDMessage::NONE)) {
170
dummy->SetDirection(msgDir);
172
dummy->SetString(&txt);
174
messages->removei(n);
177
*s = txt; // return stripped(?) string
182
const CBDMessage *CBInteraction::GetMessage(unsigned n) {
183
if (n < messages->count()) {
184
return (*messages)[n];
190
bool CBInteraction::HasMessage(const CBDMessage *m) {
191
for (messages->first(); !messages->done(); messages->next()) {
192
CBDMessage *at = messages->cur();
193
if (*at->GetString() == *m->GetString())
200
void CBInteraction::WriteMembers(OutputFile *ofile) {
201
BinaryRelationship::WriteMembers(ofile);
203
unsigned num = messages->count();
205
(*ofile) << "\t{ Messages " << num << " }\n";
207
for (unsigned i=0; i<num; i++) {
208
(*ofile) << "\t{ Message " << '"'
209
<< *(*messages)[i]->GetString() << '"' << " }\n";
210
CBDMessage::DirectionType2String((*messages)[i]->GetDirection(), &x);
211
(*ofile) << "\t{ Direction " << x << " }\n";
212
CBDMessage::ControlFlowType2String((*messages)[i]->GetFlow(), &x);
213
(*ofile) << "\t{ Flow " << x << " }\n";
217
bool CBInteraction::ReadMembers(InputFile *ifile, double format) {
218
if (!BinaryRelationship::ReadMembers(ifile, format))
221
if (!ifile->ReadAttribute("Messages", &val))
223
unsigned numItems = val.toint();
225
string *a = new string;
226
CBDMessage::DirectionType direction;
227
CBDMessage::ControlFlowType flow;
229
// Read messages data
230
for (int i=0; i<(int) numItems; i++) {
231
if (!ifile->ReadStringAttribute("Message", a)) {
235
if (!ifile->ReadAttribute("Direction", &val))
237
direction = CBDMessage::String2DirectionType(&val);
238
if (!ifile->ReadAttribute("Flow", &val))
240
flow = CBDMessage::String2ControlFlowType(&val);
241
if (i == 0) //overrule dummy "edit this" message
243
messages->add(new CBDMessage(a, direction, flow));