• Skip to content
  • Skip to link menu
KDE 4.0 API Reference
  • KDE API Reference
  • kdesdk
  • Sitemap
  • Contact Us
 

umbrello/umbrello

umlcanvasobject.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *                                                                         *
00003  *   This program is free software; you can redistribute it and/or modify  *
00004  *   it under the terms of the GNU General Public License as published by  *
00005  *   the Free Software Foundation; either version 2 of the License, or     *
00006  *   (at your option) any later version.                                   *
00007  *                                                                         *
00008  *   copyright (C) 2003-2007                                               *
00009  *   Umbrello UML Modeller Authors <uml-devel@uml.sf.net>                  *
00010  ***************************************************************************/
00011 
00012 // own header
00013 #include "umlcanvasobject.h"
00014 
00015 // qt/kde includes
00016 #include <kdebug.h>
00017 #include <klocale.h>
00018 
00019 // local includes
00020 #include "uml.h"
00021 #include "umldoc.h"
00022 #include "classifier.h"
00023 #include "association.h"
00024 #include "attribute.h"
00025 #include "operation.h"
00026 #include "template.h"
00027 #include "stereotype.h"
00028 #include "clipboard/idchangelog.h"
00029 
00030 UMLCanvasObject::UMLCanvasObject(const QString & name, Uml::IDType id)
00031         : UMLObject(name, id)
00032 {
00033     init();
00034 }
00035 
00036 UMLCanvasObject::~UMLCanvasObject() {
00037     //removeAllAssociations();
00038     /* No! This is way too late to do that.
00039       It should have been called explicitly before destructing the
00040       UMLCanvasObject.
00041       Here is an example crash that happens if we rely on
00042       removeAllAssociations() at this point:
00043 #4  0x415aac7f in __dynamic_cast () from /usr/lib/libstdc++.so.5
00044 #5  0x081acdbd in UMLCanvasObject::removeAllAssociations() (this=0x89e5b08)
00045     at umlcanvasobject.cpp:83
00046 #6  0x081ac9fa in ~UMLCanvasObject (this=0x89e5b08) at umlcanvasobject.cpp:29
00047 #7  0x08193ffc in ~UMLPackage (this=0x89e5b08) at package.cpp:35
00048 #8  0x0813cbf6 in ~UMLClassifier (this=0x89e5b08) at classifier.cpp:40
00049 #9  0x081af3a6 in UMLDoc::closeDocument() (this=0x8468b10) at umldoc.cpp:284
00050      */
00051     if (associations())
00052         uDebug() << "UMLCanvasObject destructor: FIXME: there are still associations()";
00053 }
00054 
00055 UMLAssociationList UMLCanvasObject::getSpecificAssocs(Uml::Association_Type assocType) {
00056     UMLAssociationList list;
00057     UMLObject *o = NULL;
00058     for (UMLObjectListIt oit(m_List); oit.hasNext(); ) {
00059         o = oit.next();
00060         if (o->getBaseType() != Uml::ot_Association)
00061             continue;
00062         UMLAssociation *a = static_cast<UMLAssociation*>(o);
00063         if (a->getAssocType() == assocType)
00064             list.append(a);
00065     }
00066     return list;
00067 }
00068 
00069 bool UMLCanvasObject::addAssociationEnd(UMLAssociation* assoc) {
00070     // add association only if not already present in list
00071     if(!hasAssociation(assoc))
00072     {
00073         m_List.append( assoc );
00074 
00075         // Don't emit signals during load from XMI
00076         UMLObject::emitModified();
00077         emit sigAssociationEndAdded(assoc);
00078         return true;
00079     }
00080     return false;
00081 }
00082 
00083 bool UMLCanvasObject::hasAssociation(UMLAssociation* assoc) {
00084     if(m_List.count(assoc) > 0)
00085         return true;
00086     return false;
00087 }
00088 
00089 int UMLCanvasObject::removeAssociationEnd(UMLAssociation * assoc) {
00090     if(!hasAssociation(assoc) || !m_List.removeAll(assoc)) {
00091         uWarning() << "can't find given assoc in list" << endl;
00092         return -1;
00093     }
00094     UMLObject::emitModified();
00095     emit sigAssociationEndRemoved(assoc);
00096     return m_List.count();
00097 }
00098 
00099 void UMLCanvasObject::removeAllAssociationEnds() {
00100     for (int i = 0; i < m_List.count(); ) {
00101         UMLObject *o = m_List.at(i);
00102         if (o->getBaseType() != Uml::ot_Association) {
00103             ++i;
00104             continue;
00105         }
00106         UMLAssociation *assoc = static_cast<UMLAssociation*>(o);
00107         //umldoc->slotRemoveUMLObject(assoc);
00108         UMLObject* objA = assoc->getObject(Uml::A);
00109         UMLObject* objB = assoc->getObject(Uml::B);
00110         UMLCanvasObject *roleAObj = dynamic_cast<UMLCanvasObject*>(objA);
00111         if (roleAObj) {
00112             roleAObj->removeAssociationEnd(assoc);
00113         } else if (objA)
00114             uDebug() << m_Name << ": objA " << objA->getName() << " is not a UMLCanvasObject"
00115                 << endl;
00116         else
00117             uDebug() << m_Name << "): objA is NULL" << endl;
00118         UMLCanvasObject *roleBObj = dynamic_cast<UMLCanvasObject*>(objB);
00119         if (roleBObj) {
00120             roleBObj->removeAssociationEnd(assoc);
00121         } else if (objB)
00122             uDebug() << m_Name << "): objB " << objB->getName() << " is not a UMLCanvasObject"
00123                 << endl;
00124         else
00125             uDebug() << m_Name << "): objB is NULL" << endl;
00126         m_List.removeAt(i);
00127     }
00128 }
00129 
00130 void UMLCanvasObject::removeAllChildObjects() {
00131     removeAllAssociationEnds();
00132     while ( !m_List.isEmpty() ) {
00133         delete m_List.takeFirst();
00134     }
00135 }
00136 
00137 QString UMLCanvasObject::uniqChildName( const Uml::Object_Type type,
00138                                         const QString &prefix /* = QString() */ ) {
00139     QString currentName = prefix;
00140     if (currentName.isEmpty()) {
00141         switch (type) {
00142             case Uml::ot_Association:
00143                 currentName = i18n("new_association");
00144                 break;
00145             case Uml::ot_Attribute:
00146                 currentName = i18n("new_attribute");
00147                 break;
00148             case Uml::ot_Template:
00149                 currentName = i18n("new_template");
00150                 break;
00151             case Uml::ot_Operation:
00152                 currentName = i18n("new_operation");
00153                 break;
00154             case Uml::ot_EnumLiteral:
00155                 currentName = i18n("new_literal");
00156                 break;
00157             case Uml::ot_EntityAttribute:
00158                 currentName = i18n("new_field");
00159                 break;
00160             case Uml::ot_UniqueConstraint:
00161                 currentName = i18n( "new_unique_constraint" );
00162                 break;
00163             case Uml::ot_ForeignKeyConstraint:
00164                 currentName = i18n( "new_fkey_constraint" );
00165                 break;
00166             case Uml::ot_CheckConstraint:
00167                 currentName = i18n( "new_check_constraint" );
00168                 break;
00169             default:
00170                 uWarning() << "uniqChildName() called for unknown child type " << type;
00171                 return "ERROR_in_UMLCanvasObject_uniqChildName";
00172         }
00173     }
00174 
00175     QString name = currentName;
00176     for (int number = 1; findChildObject(name); ++number) {
00177         name = currentName + '_' + QString::number(number);
00178     }
00179     return name;
00180 }
00181 
00182 UMLObject * UMLCanvasObject::findChildObject(const QString &n, Uml::Object_Type t) {
00183     const bool caseSensitive = UMLApp::app()->activeLanguageIsCaseSensitive();
00184     UMLObject *obj = NULL;
00185     for (UMLObjectListIt oit(m_List); oit.hasNext(); ) {
00186         obj = oit.next();
00187         if (t != Uml::ot_UMLObject && obj->getBaseType() != t)
00188             continue;
00189         if (caseSensitive) {
00190             if (obj->getName() == n)
00191                 return obj;
00192         } else if (obj->getName().toLower() == n.toLower()) {
00193             return obj;
00194         }
00195     }
00196     return NULL;
00197 }
00198 
00199 UMLObject* UMLCanvasObject::findChildObjectById(Uml::IDType id, bool /* considerAncestors */) {
00200     UMLObject *o = NULL;
00201     for (UMLObjectListIt oit(m_List); oit.hasNext(); ) {
00202         o = oit.next();
00203         if (o->getID() == id)
00204             return o;
00205     }
00206     return 0;
00207 }
00208 
00209 void UMLCanvasObject::init() {
00210 
00211 }
00212 
00213 bool UMLCanvasObject::operator==(const UMLCanvasObject& rhs) {
00214     if (this == &rhs) {
00215         return true;
00216     }
00217     if ( !UMLObject::operator==(rhs) ) {
00218         return false;
00219     }
00220     if ( m_List.count() != rhs.m_List.count() ) {
00221         return false;
00222     }
00223     if ( &m_List != &(rhs.m_List) ) {
00224         return false;
00225     }
00226     return true;
00227 }
00228 
00229 void UMLCanvasObject::copyInto(UMLObject *lhs) const
00230 {
00231     UMLObject::copyInto(lhs);
00232 
00233     // TODO Associations are not copied at the moment. This because
00234     // the duplicate function (on umlwidgets) do not copy the associations.
00235     //
00236     //target->m_List = m_List;
00237 }
00238 
00239 int UMLCanvasObject::associations() {
00240     int count = 0;
00241     UMLObject *obj = NULL;
00242     for (UMLObjectListIt oit(m_List); oit.hasNext(); ) {
00243         obj = oit.next();
00244         if (obj->getBaseType() == Uml::ot_Association)
00245             count++;
00246     }
00247     return count;
00248 }
00249 
00250 UMLAssociationList UMLCanvasObject::getAssociations() {
00251     UMLAssociationList assocs;
00252     UMLObject *o = NULL;
00253     for (UMLObjectListIt oit(m_List); oit.hasNext() ; ) {
00254         o = oit.next();
00255         if (o->getBaseType() != Uml::ot_Association)
00256             continue;
00257         UMLAssociation *assoc = static_cast<UMLAssociation*>(o);
00258         assocs.append(assoc);
00259     }
00260     return assocs;
00261 }
00262 
00263 UMLClassifierList UMLCanvasObject::getSuperClasses() {
00264     UMLClassifierList list;
00265     UMLAssociationList assocs = getAssociations();
00266     foreach (UMLAssociation* a , assocs ) {
00267         if ((a->getAssocType() != Uml::at_Generalization &&
00268              a->getAssocType() != Uml::at_Realization) ||
00269                 a->getObjectId(Uml::A) != getID() )
00270             continue;
00271         UMLClassifier *c = dynamic_cast<UMLClassifier*>(a->getObject(Uml::B));
00272         if (c)
00273             list.append(c);
00274         else
00275             uDebug() << m_Name << ": generalization's other end is not a "
00276                 << "UMLClassifier (id= " << ID2STR(a->getObjectId(Uml::B)) << ")"
00277                 << endl;
00278     }
00279     return list;
00280 }
00281 
00282 UMLClassifierList UMLCanvasObject::getSubClasses() {
00283     UMLClassifierList list;
00284     UMLAssociationList assocs = getAssociations();
00285     foreach (UMLAssociation* a , assocs ) {
00286         if ((a->getAssocType() != Uml::at_Generalization &&
00287              a->getAssocType() != Uml::at_Realization) ||
00288                 a->getObjectId(Uml::B) != getID() )
00289             continue;
00290         UMLClassifier *c = dynamic_cast<UMLClassifier*>(a->getObject(Uml::A));
00291         if (c)
00292             list.append(c);
00293         else
00294             uDebug() << "specialization's other end is not a UMLClassifier"
00295                 << " (id=" << ID2STR(a->getObjectId(Uml::A)) << ")" << endl;
00296     }
00297     return list;
00298 }
00299 
00300 UMLAssociationList UMLCanvasObject::getRealizations() {
00301     return getSpecificAssocs(Uml::at_Realization);
00302 }
00303 
00304 UMLAssociationList UMLCanvasObject::getAggregations() {
00305     return getSpecificAssocs(Uml::at_Aggregation);
00306 }
00307 
00308 UMLAssociationList UMLCanvasObject::getCompositions() {
00309     return getSpecificAssocs(Uml::at_Composition);
00310 }
00311 
00312 UMLAssociationList UMLCanvasObject::getRelationships() {
00313     return getSpecificAssocs(Uml::at_Relationship);
00314 }
00315 
00316 bool UMLCanvasObject::resolveRef() {
00317     bool overallSuccess = UMLObject::resolveRef();
00318     for (UMLObjectListIt ait(m_List); ait.hasNext(); ) {
00319         UMLObject *obj = ait.next();
00320         if (! obj->resolveRef()) {
00321             m_List.removeAll(obj);
00322             overallSuccess = false;
00323         }
00324     }
00325     return overallSuccess;
00326 }
00327 
00328 #include "umlcanvasobject.moc"
00329 

umbrello/umbrello

Skip menu "umbrello/umbrello"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdesdk

Skip menu "kdesdk"
  • kate
  •     kate
  • umbrello
  •   umbrello
Generated for kdesdk by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal