umbrello/umbrello
umlcanvasobject.cpp
Go to the documentation of this file.00001 /*************************************************************************** 00002 * This program is free software; you can redistribute it and/or modify * 00003 * it under the terms of the GNU General Public License as published by * 00004 * the Free Software Foundation; either version 2 of the License, or * 00005 * (at your option) any later version. * 00006 * * 00007 * copyright (C) 2003-2009 * 00008 * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> * 00009 ***************************************************************************/ 00010 00011 // own header 00012 #include "umlcanvasobject.h" 00013 00014 // local includes 00015 #include "uml.h" 00016 #include "umldoc.h" 00017 #include "classifier.h" 00018 #include "association.h" 00019 #include "attribute.h" 00020 #include "operation.h" 00021 #include "template.h" 00022 #include "stereotype.h" 00023 #include "idchangelog.h" 00024 00025 // kde includes 00026 #include <kdebug.h> 00027 #include <klocale.h> 00028 00035 UMLCanvasObject::UMLCanvasObject(const QString & name, Uml::IDType id) 00036 : UMLObject(name, id) 00037 { 00038 } 00039 00043 UMLCanvasObject::~UMLCanvasObject() 00044 { 00045 //removeAllAssociations(); 00046 // No! This is way too late to do that. 00047 // It should have been called explicitly before destructing the 00048 // UMLCanvasObject. 00049 if (associations()) 00050 uDebug() << "UMLCanvasObject destructor: FIXME: there are still associations()"; 00051 } 00052 00059 UMLAssociationList UMLCanvasObject::getSpecificAssocs(Uml::Association_Type assocType) 00060 { 00061 UMLAssociationList list; 00062 UMLObject *o = NULL; 00063 for (UMLObjectListIt oit(m_List); oit.hasNext(); ) { 00064 o = oit.next(); 00065 uIgnoreZeroPointer(o); 00066 if (o->getBaseType() != Uml::ot_Association) 00067 continue; 00068 UMLAssociation *a = static_cast<UMLAssociation*>(o); 00069 if (a->getAssocType() == assocType) 00070 list.append(a); 00071 } 00072 return list; 00073 } 00074 00081 bool UMLCanvasObject::addAssociationEnd(UMLAssociation* assoc) 00082 { 00083 Q_ASSERT(assoc); 00084 // add association only if not already present in list 00085 if (!hasAssociation(assoc)) 00086 { 00087 m_List.append( assoc ); 00088 00089 // Don't emit signals during load from XMI 00090 UMLObject::emitModified(); 00091 emit sigAssociationEndAdded(assoc); 00092 return true; 00093 } 00094 return false; 00095 } 00096 00102 bool UMLCanvasObject::hasAssociation(UMLAssociation* assoc) 00103 { 00104 if (m_List.count(assoc) > 0) { 00105 return true; 00106 } 00107 return false; 00108 } 00109 00116 int UMLCanvasObject::removeAssociationEnd(UMLAssociation * assoc) 00117 { 00118 if (!hasAssociation(assoc) || !m_List.removeAll(assoc)) { 00119 uWarning() << "can not find given assoc in list"; 00120 return -1; 00121 } 00122 UMLObject::emitModified(); 00123 emit sigAssociationEndRemoved(assoc); 00124 return m_List.count(); 00125 } 00126 00130 void UMLCanvasObject::removeAllAssociationEnds() 00131 { 00132 for (int i = 0; i < m_List.count(); i++) { 00133 UMLObject *o = m_List.at(i); 00134 uIgnoreZeroPointer(o); 00135 if (o->getBaseType() != Uml::ot_Association) { 00136 continue; 00137 } 00138 UMLAssociation *assoc = static_cast<UMLAssociation*>(o); 00139 //umldoc->slotRemoveUMLObject(assoc); 00140 UMLObject* objA = assoc->getObject(Uml::A); 00141 UMLObject* objB = assoc->getObject(Uml::B); 00142 UMLCanvasObject *roleAObj = dynamic_cast<UMLCanvasObject*>(objA); 00143 if (roleAObj) { 00144 roleAObj->removeAssociationEnd(assoc); 00145 } else if (objA) 00146 uDebug() << m_Name << ": objA " << objA->getName() << " is not a UMLCanvasObject"; 00147 else 00148 uDebug() << m_Name << "): objA is NULL"; 00149 UMLCanvasObject *roleBObj = dynamic_cast<UMLCanvasObject*>(objB); 00150 if (roleBObj) { 00151 roleBObj->removeAssociationEnd(assoc); 00152 } else if (objB) 00153 uDebug() << m_Name << "): objB " << objB->getName() << " is not a UMLCanvasObject"; 00154 else 00155 uDebug() << m_Name << "): objB is NULL"; 00156 } 00157 } 00158 00164 void UMLCanvasObject::removeAllChildObjects() 00165 { 00166 if (!m_List.isEmpty()) { 00167 removeAllAssociationEnds(); 00168 m_List.clear(); 00169 } 00170 } 00171 00183 QString UMLCanvasObject::uniqChildName( const Uml::Object_Type type, 00184 const QString &prefix /* = QString() */ ) 00185 { 00186 QString currentName; 00187 currentName = prefix; 00188 if (currentName.isEmpty()) { 00189 switch (type) { 00190 case Uml::ot_Association: 00191 currentName = i18n("new_association"); 00192 break; 00193 case Uml::ot_Attribute: 00194 currentName = i18n("new_attribute"); 00195 break; 00196 case Uml::ot_Template: 00197 currentName = i18n("new_template"); 00198 break; 00199 case Uml::ot_Operation: 00200 currentName = i18n("new_operation"); 00201 break; 00202 case Uml::ot_EnumLiteral: 00203 currentName = i18n("new_literal"); 00204 break; 00205 case Uml::ot_EntityAttribute: 00206 currentName = i18n("new_field"); 00207 break; 00208 case Uml::ot_UniqueConstraint: 00209 currentName = i18n( "new_unique_constraint" ); 00210 break; 00211 case Uml::ot_ForeignKeyConstraint: 00212 currentName = i18n( "new_fkey_constraint" ); 00213 break; 00214 case Uml::ot_CheckConstraint: 00215 currentName = i18n( "new_check_constraint" ); 00216 break; 00217 default: 00218 uWarning() << "uniqChildName() called for unknown child type " << type; 00219 return "ERROR_in_UMLCanvasObject_uniqChildName"; 00220 } 00221 } 00222 00223 QString name = currentName; 00224 for (int number = 1; findChildObject(name); ++number) { 00225 name = currentName + '_' + QString::number(number); 00226 } 00227 return name; 00228 } 00229 00238 UMLObject * UMLCanvasObject::findChildObject(const QString &n, Uml::Object_Type t) 00239 { 00240 const bool caseSensitive = UMLApp::app()->activeLanguageIsCaseSensitive(); 00241 UMLObject *obj = NULL; 00242 for (UMLObjectListIt oit(m_List); oit.hasNext(); ) { 00243 obj = oit.next(); 00244 uIgnoreZeroPointer(obj); 00245 if (t != Uml::ot_UMLObject && obj->getBaseType() != t) 00246 continue; 00247 if (caseSensitive) { 00248 if (obj->getName() == n) 00249 return obj; 00250 } else if (obj->getName().toLower() == n.toLower()) { 00251 return obj; 00252 } 00253 } 00254 return NULL; 00255 } 00256 00264 UMLObject* UMLCanvasObject::findChildObjectById(Uml::IDType id, bool considerAncestors) 00265 { 00266 Q_UNUSED(considerAncestors); 00267 UMLObject *o = NULL; 00268 for (UMLObjectListIt oit(m_List); oit.hasNext(); ) { 00269 o = oit.next(); 00270 uIgnoreZeroPointer(o); 00271 if (o->getID() == id) 00272 return o; 00273 } 00274 return 0; 00275 } 00276 00280 bool UMLCanvasObject::operator==(const UMLCanvasObject& rhs) 00281 { 00282 if (this == &rhs) { 00283 return true; 00284 } 00285 if ( !UMLObject::operator==(rhs) ) { 00286 return false; 00287 } 00288 if ( m_List.count() != rhs.m_List.count() ) { 00289 return false; 00290 } 00291 if ( &m_List != &(rhs.m_List) ) { 00292 return false; 00293 } 00294 return true; 00295 } 00296 00301 void UMLCanvasObject::copyInto(UMLObject *lhs) const 00302 { 00303 UMLObject::copyInto(lhs); 00304 00305 // TODO Associations are not copied at the moment. This because 00306 // the duplicate function (on umlwidgets) do not copy the associations. 00307 // 00308 //target->m_List = m_List; 00309 } 00310 00317 int UMLCanvasObject::associations() 00318 { 00319 int count = 0; 00320 UMLObject *obj = NULL; 00321 for (UMLObjectListIt oit(m_List); oit.hasNext(); ) { 00322 obj = oit.next(); 00323 uIgnoreZeroPointer(obj); 00324 if (obj->getBaseType() == Uml::ot_Association) 00325 count++; 00326 } 00327 return count; 00328 } 00329 00335 UMLAssociationList UMLCanvasObject::getAssociations() 00336 { 00337 UMLAssociationList assocs; 00338 UMLObject *o = NULL; 00339 for (UMLObjectListIt oit(m_List); oit.hasNext() ; ) { 00340 o = oit.next(); 00341 uIgnoreZeroPointer(o); 00342 if (o->getBaseType() != Uml::ot_Association) 00343 continue; 00344 UMLAssociation *assoc = static_cast<UMLAssociation*>(o); 00345 assocs.append(assoc); 00346 } 00347 return assocs; 00348 } 00349 00357 UMLClassifierList UMLCanvasObject::getSuperClasses() 00358 { 00359 UMLClassifierList list; 00360 UMLAssociationList assocs = getAssociations(); 00361 foreach (UMLAssociation* a , assocs ) { 00362 uIgnoreZeroPointer(a); 00363 if ((a->getAssocType() != Uml::at_Generalization && 00364 a->getAssocType() != Uml::at_Realization) || 00365 a->getObjectId(Uml::A) != getID() ) 00366 continue; 00367 UMLClassifier *c = dynamic_cast<UMLClassifier*>(a->getObject(Uml::B)); 00368 if (c) 00369 list.append(c); 00370 else 00371 uDebug() << m_Name << ": generalization's other end is not a " 00372 << "UMLClassifier (id= " << ID2STR(a->getObjectId(Uml::B)) << ")"; 00373 } 00374 return list; 00375 } 00376 00384 UMLClassifierList UMLCanvasObject::getSubClasses() 00385 { 00386 UMLClassifierList list; 00387 UMLAssociationList assocs = getAssociations(); 00388 foreach (UMLAssociation* a , assocs ) { 00389 uIgnoreZeroPointer(a); 00390 if ((a->getAssocType() != Uml::at_Generalization && 00391 a->getAssocType() != Uml::at_Realization) || 00392 a->getObjectId(Uml::B) != getID() ) 00393 continue; 00394 UMLClassifier *c = dynamic_cast<UMLClassifier*>(a->getObject(Uml::A)); 00395 if (c) 00396 list.append(c); 00397 else 00398 uDebug() << "specialization's other end is not a UMLClassifier" 00399 << " (id=" << ID2STR(a->getObjectId(Uml::A)) << ")"; 00400 } 00401 return list; 00402 } 00403 00409 UMLAssociationList UMLCanvasObject::getRealizations() 00410 { 00411 return getSpecificAssocs(Uml::at_Realization); 00412 } 00413 00419 UMLAssociationList UMLCanvasObject::getAggregations() 00420 { 00421 return getSpecificAssocs(Uml::at_Aggregation); 00422 } 00423 00429 UMLAssociationList UMLCanvasObject::getCompositions() 00430 { 00431 return getSpecificAssocs(Uml::at_Composition); 00432 } 00433 00439 UMLAssociationList UMLCanvasObject::getRelationships() 00440 { 00441 return getSpecificAssocs(Uml::at_Relationship); 00442 } 00443 00447 bool UMLCanvasObject::resolveRef() 00448 { 00449 bool overallSuccess = UMLObject::resolveRef(); 00450 for (UMLObjectListIt ait(m_List); ait.hasNext(); ) { 00451 UMLObject *obj = ait.next(); 00452 uIgnoreZeroPointer(obj); 00453 if (! obj->resolveRef()) { 00454 m_List.removeAll(obj); 00455 overallSuccess = false; 00456 } 00457 } 00458 return overallSuccess; 00459 } 00460 00461 #include "umlcanvasobject.moc" 00462
KDE 4.4 API Reference