⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 crdiagram.c

📁 这个工具集提供以下结构化分析和UML分析中所用的图形化绘图工具:ER-diagrams, data and event flow diagrams and state-transition diagr
💻 C
📖 第 1 页 / 共 2 页
字号:
		SetLineEnd2(LineEnd::EMPTY);		break;	case 2: SetEdgeType(Code::FUNCTION);		SetLineType(Code::T1_LINE);		SetEdgeLineStyle(LineStyle::SOLID);		SetLineEnd1(LineEnd::EMPTY);		SetLineEnd2(LineEnd::FILLED_ARROW);		break;	case 3: SetEdgeType(Code::COMPONENT_FUNCTION);		SetLineType(Code::T1_LINE);		SetEdgeLineStyle(LineStyle::DASHED);		SetLineEnd1(LineEnd::EMPTY);		SetLineEnd2(LineEnd::FILLED_ARROW);		break;	case 4: SetEdgeType(Code::ISA_RELATIONSHIP);		SetLineType(Code::LINE);		SetEdgeLineStyle(LineStyle::SOLID);		SetLineEnd1(LineEnd::EMPTY);		SetLineEnd2(LineEnd::FILLED_ARROW);		break;	case 5: SetEdgeType(Code::EMPTY_EDGE);		SetLineType(Code::LINE);		SetEdgeLineStyle(LineStyle::SOLID);		SetLineEnd1(LineEnd::EMPTY);		SetLineEnd2(LineEnd::EMPTY);		break;	case 6: SetEdgeType(Code::FUNCTION);		SetLineType(Code::LINE);		SetEdgeLineStyle(LineStyle::SOLID);		SetLineEnd1(LineEnd::FILLED_ARROW);		SetLineEnd2(LineEnd::FILLED_ARROW);		break;	default:		error("%s, line %d: impl error: "			"unknown edge type selected\n", __FILE__,__LINE__);	}}bool CRDiagram::SetText(TextShape *t, const string *s) {	const string *d = t->GetDescription();	Subject *subj = t->GetParent()->GetSubject();	if (*d == "Attribute" && subj->GetClassType()==Code::CLASS_NODE)		return SetAttribute((ClassNode *)subj, s, t->GetSequence());	else if (*d == "Operation" && subj->GetClassType()==Code::CLASS_NODE)		return SetOperation((ClassNode *)subj, s, t->GetSequence());	else		return ERDiagram::SetText(t, s);}void CRDiagram::MakeErrorMessage(ClassNode *cl, 		ClassNode::TextErrType result, 		const string *s, string *txt) {	*txt = "class '" + *cl->GetName() + "' ";	if (result == ClassNode::ATTRIBUTE_EXISTS)		*txt += "already has an attribute '" + *s + "'"; 	else if (result == ClassNode::OPERATION_EXISTS)		*txt += "already has an operation '" + *s + "'"; 	else if (result == ClassNode::FUNCTION_EXISTS)		*txt += "already has a function '" + *s + "'"; 	else if (result == ClassNode::COMPONENT_EXISTS)		*txt += "already has a component function '" + *s + "'"; 	else if (result == ClassNode::RELATION_EXISTS)		*txt += "is already engaged in binary relationship '" + *s + "'"; 	else if (result == ClassNode::IMPOSSIBLE_ATTRIBUTE)		*txt = "'" + *s + "' wrong syntax\nfor an attribute declaration";	else if (result == ClassNode::IMPOSSIBLE_OPERATION)		*txt = "'" + *s + "' wrong syntax\nfor an operation declaration";}bool CRDiagram::SetAttribute(ClassNode *cl, const string *s, unsigned nr) {	List<GShape *> shapes;	GetDiagramViewer()->GetShapes(cl, &shapes);	unsigned m = nr;	// split string in different strings (separated by newline).	// each string becomes a new attribute.	string ss(*s);	char *str = (char *)ss.getstr();	char *x = strtok(str, "\r");	char empty[2] = "";	if (x == 0)		x = empty;	while (x != 0) {		string *ns = new string(x);		bool update = True;		ClassNode::TextErrType result;		if (m == nr)			result = cl->SetAttribute(ns, m, True);		else { // m != r			result = cl->SetAttribute(ns, m, False);			update = False;		}		string txt;		MakeErrorMessage(cl, result, ns, &txt);		if (result != ClassNode::MEMBER_OK) {			ShowDialog(MessageDialog::ERROR, "Error", &txt);			// delete the newly created attributes.			*ns = "";			for (shapes.first(); !shapes.done(); shapes.next()) {				if (shapes.cur()->GetClassType() != Code::BOX) {					DoubleBox *db = 						(DoubleBox *)(shapes.cur());					if (db->NrLabels()-1 == m)						db->UpdateLabel(ns, m, update);				}			}			delete ns;			return False;		}		// update the double box shapes.		for (shapes.first(); !shapes.done(); shapes.next()) {			if (shapes.cur()->GetClassType() != Code::BOX)				((DoubleBox *)shapes.cur())->					UpdateLabel(ns, m, update);		}		if (!shapes.first()) {			error( "%s, line %d: impl error: "				"shape does not exist!\n", __FILE__, __LINE__);			return False;		}		m++;		x = strtok(0, "\r");		delete ns;	}	return True;}bool CRDiagram::SetOperation(ClassNode *cl, const string *s, unsigned nr) {	List<GShape *> shapes;	GetDiagramViewer()->GetShapes(cl, &shapes);	string ss(*s);	char *str = (char *)ss.getstr();	unsigned m = nr;	char empty[2] = "";	char *x = strtok(str, "\r");	if (x == 0)		x = empty;	while (x != 0) {		string *ns = new string(x);		bool update = True;		ClassNode::TextErrType result;		if (m == nr) {			result = cl->SetOperation(ns, m, True);		}		else { // m != r			result = cl->SetOperation(ns, m, False);			update = False;		}		string txt;		MakeErrorMessage(cl, result, ns, &txt);		if (result != ClassNode::MEMBER_OK) {			ShowDialog(MessageDialog::ERROR, "Error", &txt);			// delete the newly created operations.			*ns = "";			for (shapes.first(); !shapes.done(); shapes.next()) {				if (shapes.cur()->GetClassType() == 						Code::TRIPLE_BOX) {					TripleBox *tb = 						(TripleBox *)(shapes.cur());					if (tb->NrLabels2()-1 == m)						tb->UpdateLabel2(ns, m, update);				}			}			delete ns;			return False;		}		// update the triple box shapes.		for (shapes.first(); !shapes.done(); shapes.next()) {			if (shapes.cur()->GetClassType() == Code::TRIPLE_BOX) 				((TripleBox *)shapes.cur())->					UpdateLabel2(ns, m, update);		} 		if (!shapes.first()) {			error( "%s, line %d: impl error: "				"shape does not exist!\n", __FILE__, __LINE__);			return False;		}		m++;		x = strtok(0, "\r");		delete ns;	}	return True;}void CRDiagram::CheckDocument() {	chkbuf = "";	unsigned total = 0;	// Check that binary relationships are named.	total += crChecks->CheckNamelessBinaryRelationships(chkbuf);	if (total == 0)		total += crChecks->CheckDoubleNamelessEdges(			Code::BINARY_RELATIONSHIP, Code::CLASS_NODE, 			Code::CLASS_NODE, chkbuf);	// Check that classes are named.	total += crChecks->CheckNamelessNodes(Code::CLASS_NODE, chkbuf);	// double nodes can occur after cut-copy-paste	total += crChecks->CheckDoubleNodes(Code::CLASS_NODE, chkbuf);	// Check that functions and component functions are identifiable.	total += crChecks->CheckDoubleNamelessFunctions(		Code::CLASS_NODE, Code::CLASS_NODE, chkbuf);	// Check that tax. and mode junctions are connected correctly.	total += crChecks->CheckJunctionCoherence(		Code::TAXONOMY_JUNCTION, Code::ISA_RELATIONSHIP, 		Code::EMPTY_EDGE, 2, chkbuf);	total += crChecks->CheckJunctionCoherence(		Code::MODE_JUNCTION, Code::ISA_RELATIONSHIP, 		Code::EMPTY_EDGE, 2, chkbuf);	// Check that classes have not 1 comp. function.	total += crChecks->CheckCountEdgesFrom(		Code::CLASS_NODE, Code::COMPONENT_FUNCTION, 2, INT_MAX, 		True, False, chkbuf);	// Check that rel. classes are not spec. of classes.	total += crChecks->CheckRelationshipIsaClassNode(chkbuf);	ReportCheck(total, &chkbuf);}bool CRDiagram::CheckTaxonomyCombination(Edge *edge) {	// checks if adding the edge does not make a static partition 	// (with tax.junction) part of a dynamic partition (with modejunction).	int eType = edge->GetClassType();	Subject *n1 = edge->GetSubject1();	Subject *n2 = edge->GetSubject2();	int n1Type = n1->GetClassType();	int n2Type = n2->GetClassType();	bool correct = True;	if (eType == Code::EMPTY_EDGE) {		Subject *nX = 0;		if (n1Type == Code::CLASS_NODE && 		    n2Type == Code::MODE_JUNCTION)			nX = n1;		else if (n1Type == Code::MODE_JUNCTION && 			 n2Type == Code::CLASS_NODE) 			nX = n2;		if (nX) {			List<Subject *> edges;			GetGraph()->GetEdges(&edges, Code::ISA_RELATIONSHIP);			for (edges.first(); !edges.done(); edges.next()) {				Edge *e = (Edge *)edges.cur();				if (nX == e->GetSubject2()) {					int t=e->GetSubject1()->GetClassType();					if (t == Code::CLASS_NODE || 						t == Code::TAXONOMY_JUNCTION)						correct = False;				}			}		}	}	else if (eType == Code::ISA_RELATIONSHIP) {		if (n1Type == Code::CLASS_NODE || 		    n1Type == Code::TAXONOMY_JUNCTION) {			List<Subject *> edges;			GetGraph()->GetEdges(&edges, Code::EMPTY_EDGE);			for (edges.first(); !edges.done(); edges.next()) {				Edge *e = (Edge *)edges.cur();				if (n2==e->GetSubject1()) {					if (e->GetSubject2()->GetClassType() == 					    Code::MODE_JUNCTION)						correct = False;				}				else if (n2==e->GetSubject2()) {					if (e->GetSubject1()->GetClassType() == 					    Code::MODE_JUNCTION)						correct = False;				}			} 		}	}	if (!correct) {		string txt = "Dynamic specialization (with ModeJunction) cannot "			 "be specialized\n into a static specialization "			 "(with TaxonomyJunction)";		ShowDialog(MessageDialog::ERROR, "Error", &txt);	}	return correct;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -