umbrello API Documentation

classifierwidget.cpp

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) 2004-2007                                               *
00009  *   Umbrello UML Modeller Authors <uml-devel@uml.sf.net>                  *
00010  ***************************************************************************/
00011 
00012 // own header
00013 #include "classifierwidget.h"
00014 // qt/kde includes
00015 #include <qpainter.h>
00016 #include <kdebug.h>
00017 // app includes
00018 #include "classifier.h"
00019 #include "operation.h"
00020 #include "template.h"
00021 #include "associationwidget.h"
00022 #include "umlview.h"
00023 #include "umldoc.h"
00024 #include "uml.h"
00025 #include "listpopupmenu.h"
00026 #include "object_factory.h"
00027 
00028 ClassifierWidget::ClassifierWidget(UMLView * view, UMLClassifier *c)
00029   : UMLWidget(view, c) {
00030     init();
00031     if (c != NULL && c->isInterface()) {
00032         WidgetBase::setBaseType(Uml::wt_Interface);
00033         m_bShowStereotype = true;
00034         m_bShowAttributes = false;
00035         updateSigs();
00036     }
00037 }
00038 
00039 ClassifierWidget::~ClassifierWidget() {
00040     if (m_pAssocWidget)
00041         m_pAssocWidget->removeAssocClassLine();
00042 }
00043 
00044 const int ClassifierWidget::MARGIN = 5;
00045 const int ClassifierWidget::CIRCLE_SIZE = 30;
00046 
00047 void ClassifierWidget::init() {
00048     WidgetBase::setBaseType(Uml::wt_Class);
00049 
00050     const Settings::OptionState& ops = m_pView->getOptionState();
00051     m_bShowAccess = ops.classState.showVisibility;
00052     m_bShowOperations = ops.classState.showOps;
00053     m_bShowPublicOnly = false;
00054     m_bShowPackage = ops.classState.showPackage;
00055     m_ShowAttSigs = Uml::st_ShowSig;
00056     /* setShowOpSigs( ops.classState.showOpSig );
00057       Cannot do that because we get "pure virtual method called". Open code:
00058      */
00059     if( !ops.classState.showOpSig ) {
00060         if (m_bShowAccess)
00061             m_ShowOpSigs = Uml::st_NoSig;
00062         else
00063             m_ShowOpSigs = Uml::st_NoSigNoVis;
00064 
00065     } else if (m_bShowAccess)
00066         m_ShowOpSigs = Uml::st_ShowSig;
00067     else
00068         m_ShowOpSigs = Uml::st_SigNoVis;
00069 
00070     m_bShowAttributes = ops.classState.showAtts;
00071     m_bShowStereotype = ops.classState.showStereoType;
00072     m_bDrawAsCircle = false;
00073     m_pAssocWidget = NULL;
00074     setShowAttSigs( ops.classState.showAttSig );
00075 }
00076 
00077 void ClassifierWidget::updateSigs() {
00078     //turn on scope
00079     if (m_bShowAccess) {
00080         if (m_ShowOpSigs == Uml::st_NoSigNoVis) {
00081             m_ShowOpSigs = Uml::st_NoSig;
00082         } else if (m_ShowOpSigs == Uml::st_SigNoVis) {
00083             m_ShowOpSigs = Uml::st_ShowSig;
00084         }
00085     } else { //turn off scope
00086         if (m_ShowOpSigs == Uml::st_ShowSig) {
00087             m_ShowOpSigs = Uml::st_SigNoVis;
00088         } else if (m_ShowOpSigs == Uml::st_NoSig) {
00089             m_ShowOpSigs = Uml::st_NoSigNoVis;
00090         }
00091     }
00092     if (m_bShowAccess) {
00093         if (m_ShowAttSigs == Uml::st_NoSigNoVis)
00094             m_ShowAttSigs = Uml::st_NoSig;
00095         else if (m_ShowAttSigs == Uml::st_SigNoVis)
00096             m_ShowAttSigs = Uml::st_ShowSig;
00097     } else {
00098         if (m_ShowAttSigs == Uml::st_ShowSig)
00099             m_ShowAttSigs = Uml::st_SigNoVis;
00100         else if(m_ShowAttSigs == Uml::st_NoSig)
00101             m_ShowAttSigs = Uml::st_NoSigNoVis;
00102     }
00103     updateComponentSize();
00104     update();
00105 }
00106 
00107 void ClassifierWidget::toggleShowStereotype()
00108 {
00109     m_bShowStereotype = !m_bShowStereotype;
00110     updateSigs();
00111     updateComponentSize();
00112     update();
00113 }
00114 
00115 bool ClassifierWidget::getShowOps() const {
00116     return m_bShowOperations;
00117 }
00118 
00119 void ClassifierWidget::setShowOps(bool _show) {
00120     m_bShowOperations = _show;
00121     updateSigs();
00122     updateComponentSize();
00123     update();
00124 }
00125 
00126 void ClassifierWidget::toggleShowOps() {
00127     m_bShowOperations = !m_bShowOperations;
00128     updateSigs();
00129     updateComponentSize();
00130     update();
00131 }
00132 
00133 bool ClassifierWidget::getShowPublicOnly() const {
00134     return m_bShowPublicOnly;
00135 }
00136 
00137 void ClassifierWidget::setShowPublicOnly(bool _status) {
00138     m_bShowPublicOnly = _status;
00139     updateComponentSize();
00140     update();
00141 }
00142 
00143 void ClassifierWidget::toggleShowPublicOnly() {
00144     m_bShowPublicOnly = !m_bShowPublicOnly;
00145     updateComponentSize();
00146     update();
00147 }
00148 
00149 bool ClassifierWidget::getShowVisibility() const {
00150     return m_bShowAccess;
00151 }
00152 
00153 void ClassifierWidget::setShowVisibility(bool _visibility) {
00154     m_bShowAccess = _visibility;
00155     updateSigs();
00156     updateComponentSize();
00157     update();
00158 }
00159 
00160 void ClassifierWidget::toggleShowVisibility() {
00161     m_bShowAccess = !m_bShowAccess;
00162     updateSigs();
00163     updateComponentSize();
00164     update();
00165 }
00166 
00167 Uml::Signature_Type ClassifierWidget::getShowOpSigs() const {
00168     return m_ShowOpSigs;
00169 }
00170 
00171 void ClassifierWidget::setShowOpSigs(bool _status) {
00172     if( !_status ) {
00173         if (m_bShowAccess)
00174             m_ShowOpSigs = Uml::st_NoSig;
00175         else
00176             m_ShowOpSigs = Uml::st_NoSigNoVis;
00177     } else if (m_bShowAccess)
00178         m_ShowOpSigs = Uml::st_ShowSig;
00179     else
00180         m_ShowOpSigs = Uml::st_SigNoVis;
00181     updateComponentSize();
00182     update();
00183 }
00184 
00185 void ClassifierWidget::toggleShowOpSigs() {
00186     if (m_ShowOpSigs == Uml::st_ShowSig || m_ShowOpSigs == Uml::st_SigNoVis) {
00187         if (m_bShowAccess) {
00188             m_ShowOpSigs = Uml::st_NoSig;
00189         } else {
00190             m_ShowOpSigs = Uml::st_NoSigNoVis;
00191         }
00192     } else if (m_bShowAccess) {
00193         m_ShowOpSigs = Uml::st_ShowSig;
00194     } else {
00195         m_ShowOpSigs = Uml::st_SigNoVis;
00196     }
00197     updateComponentSize();
00198     update();
00199 }
00200 
00201 bool ClassifierWidget::getShowPackage() const {
00202     return m_bShowPackage;
00203 }
00204 
00205 void ClassifierWidget::setShowPackage(bool _status) {
00206     m_bShowPackage = _status;
00207     updateComponentSize();
00208     update();
00209 }
00210 
00211 void ClassifierWidget::toggleShowPackage() {
00212     m_bShowPackage = !m_bShowPackage;
00213     updateSigs();
00214     updateComponentSize();
00215     update();
00216 }
00217 
00218 void ClassifierWidget::setOpSignature(Uml::Signature_Type sig) {
00219     m_ShowOpSigs = sig;
00220     updateSigs();
00221     updateComponentSize();
00222     update();
00223 }
00224 
00225 void ClassifierWidget::setShowAtts(bool _show) {
00226     m_bShowAttributes = _show;
00227     updateSigs();
00228 
00229     updateComponentSize();
00230     update();
00231 }
00232 
00233 void ClassifierWidget::setAttSignature(Uml::Signature_Type sig) {
00234     m_ShowAttSigs = sig;
00235     updateSigs();
00236     updateComponentSize();
00237     update();
00238 }
00239 
00240 void ClassifierWidget::setShowAttSigs(bool _status) {
00241     if( !_status ) {
00242         if (m_bShowAccess)
00243             m_ShowAttSigs = Uml::st_NoSig;
00244         else
00245             m_ShowAttSigs = Uml::st_NoSigNoVis;
00246     }
00247     else if (m_bShowAccess)
00248         m_ShowAttSigs = Uml::st_ShowSig;
00249     else
00250         m_ShowAttSigs = Uml::st_SigNoVis;
00251     if (UMLApp::app()->getDocument()->loading())
00252         return;
00253     updateComponentSize();
00254     update();
00255 }
00256 
00257 void ClassifierWidget::toggleShowAtts()
00258 {
00259     m_bShowAttributes = !m_bShowAttributes;
00260     updateSigs();
00261     updateComponentSize();
00262     update();
00263 }
00264 
00265 void ClassifierWidget::toggleShowAttSigs()
00266 {
00267     if (m_ShowAttSigs == Uml::st_ShowSig ||
00268             m_ShowAttSigs == Uml::st_SigNoVis) {
00269         if (m_bShowAccess) {
00270             m_ShowAttSigs = Uml::st_NoSig;
00271         } else {
00272             m_ShowAttSigs = Uml::st_NoSigNoVis;
00273         }
00274     } else if (m_bShowAccess) {
00275         m_ShowAttSigs = Uml::st_ShowSig;
00276     } else {
00277         m_ShowAttSigs = Uml::st_SigNoVis;
00278     }
00279     updateComponentSize();
00280     update();
00281 }
00282 
00283 int ClassifierWidget::displayedMembers(Uml::Object_Type ot) {
00284     int count = 0;
00285     UMLClassifierListItemList list = getClassifier()->getFilteredList(ot);
00286     for (UMLClassifierListItem *m = list.first(); m; m = list.next()) {
00287       if (!(m_bShowPublicOnly && m->getVisibility() != Uml::Visibility::Public))
00288             count++;
00289     }
00290     return count;
00291 }
00292 
00293 int ClassifierWidget::displayedOperations() {
00294     if (!m_bShowOperations)
00295         return 0;
00296     return displayedMembers(Uml::ot_Operation);
00297 }
00298 
00299 QSize ClassifierWidget::calculateSize() {
00300     if (!m_pObject) {
00301         return UMLWidget::calculateSize();
00302     }
00303     if (getClassifier()->isInterface() && m_bDrawAsCircle) {
00304         return calculateAsCircleSize();
00305     }
00306 
00307     const QFontMetrics &fm = getFontMetrics(UMLWidget::FT_NORMAL);
00308     const int fontHeight = fm.lineSpacing();
00309     // width is the width of the longest 'word'
00310     int width = 0, height = 0;
00311 
00312     // consider stereotype
00313     if (m_bShowStereotype && !m_pObject->getStereotype().isEmpty()) {
00314         height += fontHeight;
00315         // ... width
00316         const QFontMetrics &bfm = UMLWidget::getFontMetrics(UMLWidget::FT_BOLD);
00317         const int stereoWidth = bfm.size(0,m_pObject->getStereotype(true)).width();
00318         if (stereoWidth > width)
00319             width = stereoWidth;
00320     }
00321 
00322     // consider name
00323     height += fontHeight;
00324     // ... width
00325     QString displayedName;
00326     if (m_bShowPackage)
00327         displayedName = m_pObject->getFullyQualifiedName();
00328     else
00329         displayedName = m_pObject->getName();
00330     const UMLWidget::FontType nft = (m_pObject->getAbstract() ? FT_BOLD_ITALIC : FT_BOLD);
00331     //const int nameWidth = getFontMetrics(nft).boundingRect(displayName).width();
00332     const int nameWidth = UMLWidget::getFontMetrics(nft).size(0,displayedName).width();
00333     if (nameWidth > width)
00334         width = nameWidth;
00335 
00336     // consider attributes
00337     const int numAtts = displayedAttributes();
00338     if (numAtts == 0) {
00339         height += fontHeight / 2;  // no atts, so just add a bit of space
00340     } else {
00341         height += fontHeight * numAtts;
00342         // calculate width of the attributes
00343         UMLClassifierListItemList list = getClassifier()->getFilteredList(Uml::ot_Attribute);
00344         for (UMLClassifierListItem *a = list.first(); a; a = list.next()) {
00345             if (m_bShowPublicOnly && a->getVisibility() != Uml::Visibility::Public)
00346                 continue;
00347             const int attWidth = fm.size(0,a->toString(m_ShowAttSigs)).width();
00348             if (attWidth > width)
00349                 width = attWidth;
00350         }
00351     }
00352 
00353     // consider operations
00354     const int numOps = displayedOperations();
00355     if (numOps == 0) {
00356         height += fontHeight / 2;  // no ops, so just add a bit of space
00357     } else {
00358         height += numOps * fontHeight;
00359         // ... width
00360         UMLOperationList list(getClassifier()->getOpList());
00361         for (UMLOperation* op = list.first(); op; op = list.next()) {
00362                   if (m_bShowPublicOnly && op->getVisibility() != Uml::Visibility::Public)
00363                 continue;
00364             const QString displayedOp = op->toString(m_ShowOpSigs);
00365             UMLWidget::FontType oft;
00366             oft = (op->getAbstract() ? UMLWidget::FT_ITALIC : UMLWidget::FT_NORMAL);
00367             const int w = UMLWidget::getFontMetrics(oft).size(0,displayedOp).width();
00368             if (w > width)
00369                 width = w;
00370         }
00371     }
00372 
00373     // consider template box _as last_ !
00374     QSize templatesBoxSize = calculateTemplatesBoxSize();
00375     if (templatesBoxSize.width() != 0) {
00376         // add width to largest 'word'
00377         width += templatesBoxSize.width() / 2;
00378     }
00379     if (templatesBoxSize.height() != 0) {
00380         height += templatesBoxSize.height() - MARGIN;
00381     }
00382 
00383 
00384     // allow for height margin
00385     if (!m_bShowOperations && !m_bShowAttributes && !m_bShowStereotype) {
00386         height += MARGIN * 2;
00387     }
00388 
00389     // allow for width margin
00390     width += MARGIN * 2;
00391 
00392     return QSize(width, height);
00393 }
00394 
00395 void ClassifierWidget::slotMenuSelection(int sel) {
00396     ListPopupMenu::Menu_Type mt = (ListPopupMenu::Menu_Type)sel;
00397     switch (mt) {
00398     case ListPopupMenu::mt_Attribute:
00399     case ListPopupMenu::mt_Operation:
00400         {
00401             UMLDoc *doc = UMLApp::app()->getDocument();
00402             Uml::Object_Type ot = ListPopupMenu::convert_MT_OT(mt);
00403             if (Object_Factory::createChildObject(getClassifier(), ot))
00404                 doc->setModified();
00405             updateComponentSize();
00406             update();
00407             break;
00408         }
00409     case ListPopupMenu::mt_Show_Operations:
00410     case ListPopupMenu::mt_Show_Operations_Selection:
00411         toggleShowOps();
00412         break;
00413 
00414     case ListPopupMenu::mt_Show_Attributes:
00415     case ListPopupMenu::mt_Show_Attributes_Selection:
00416         toggleShowAtts();
00417         break;
00418 
00419     case ListPopupMenu::mt_Show_Public_Only:
00420     case ListPopupMenu::mt_Show_Public_Only_Selection:
00421         toggleShowPublicOnly();
00422         break;
00423 
00424     case ListPopupMenu::mt_Show_Operation_Signature:
00425     case ListPopupMenu::mt_Show_Operation_Signature_Selection:
00426         toggleShowOpSigs();
00427         break;
00428 
00429     case ListPopupMenu::mt_Show_Attribute_Signature:
00430     case ListPopupMenu::mt_Show_Attribute_Signature_Selection:
00431         toggleShowAttSigs();
00432         break;
00433 
00434     case ListPopupMenu::mt_Visibility:
00435     case ListPopupMenu::mt_Visibility_Selection:
00436         toggleShowVisibility();
00437         break;
00438 
00439     case ListPopupMenu::mt_Show_Packages:
00440     case ListPopupMenu::mt_Show_Packages_Selection:
00441         toggleShowPackage();
00442         break;
00443 
00444     case ListPopupMenu::mt_Show_Stereotypes:
00445     case ListPopupMenu::mt_Show_Stereotypes_Selection:
00446         toggleShowStereotype();
00447         break;
00448 
00449     case ListPopupMenu::mt_DrawAsCircle:
00450     case ListPopupMenu::mt_DrawAsCircle_Selection:
00451         toggleDrawAsCircle();
00452         break;
00453 
00454     case ListPopupMenu::mt_ChangeToClass:
00455     case ListPopupMenu::mt_ChangeToClass_Selection:
00456         changeToClass();
00457         break;
00458 
00459     case ListPopupMenu::mt_ChangeToInterface:
00460     case ListPopupMenu::mt_ChangeToInterface_Selection:
00461         changeToInterface();
00462         break;
00463 
00464     default:
00465         UMLWidget::slotMenuSelection(sel);
00466         break;
00467     }
00468 }
00469 
00470 QSize ClassifierWidget::calculateTemplatesBoxSize() {
00471     UMLTemplateList list = getClassifier()->getTemplateList();
00472     int count = list.count();
00473     if (count == 0) {
00474         return QSize(0, 0);
00475     }
00476 
00477     int width, height;
00478     height = width = 0;
00479 
00480     QFont font = UMLWidget::getFont();
00481     font.setItalic(false);
00482     font.setUnderline(false);
00483     font.setBold(false);
00484     const QFontMetrics fm(font);
00485 
00486     height = count * fm.lineSpacing() + (MARGIN*2);
00487 
00488     for (UMLTemplate *t = list.first(); t; t = list.next()) {
00489         int textWidth = fm.size(0, t->toString() ).width();
00490         if (textWidth > width)
00491             width = textWidth;
00492     }
00493 
00494     width += (MARGIN*2);
00495     return QSize(width, height);
00496 }
00497 
00498 int ClassifierWidget::displayedAttributes() {
00499     if (!m_bShowAttributes)
00500         return 0;
00501     return displayedMembers(Uml::ot_Attribute);
00502 }
00503 
00504 void ClassifierWidget::setClassAssocWidget(AssociationWidget *assocwidget) {
00505     m_pAssocWidget = assocwidget;
00506     UMLAssociation *umlassoc = NULL;
00507     if (assocwidget)
00508         umlassoc = assocwidget->getAssociation();
00509     getClassifier()->setClassAssoc(umlassoc);
00510 }
00511 
00512 AssociationWidget *ClassifierWidget::getClassAssocWidget() {
00513     return m_pAssocWidget;
00514 }
00515 
00516 UMLClassifier *ClassifierWidget::getClassifier() {
00517     return static_cast<UMLClassifier*>(m_pObject);
00518 }
00519 
00520 void ClassifierWidget::draw(QPainter & p, int offsetX, int offsetY) {
00521     UMLWidget::setPen(p);
00522     if ( UMLWidget::getUseFillColour() )
00523         p.setBrush( UMLWidget::getFillColour() );
00524     else
00525         p.setBrush( m_pView->viewport()->backgroundColor() );
00526 
00527     if (getClassifier()->isInterface() && m_bDrawAsCircle) {
00528         drawAsCircle(p, offsetX, offsetY);
00529         return;
00530     }
00531 
00532     // Draw the bounding rectangle
00533     QSize templatesBoxSize = calculateTemplatesBoxSize();
00534     m_bodyOffsetY = offsetY;
00535     if (templatesBoxSize.height() > 0)
00536         m_bodyOffsetY += templatesBoxSize.height() - MARGIN;
00537     int w = width();
00538     if (templatesBoxSize.width() > 0)
00539         w -= templatesBoxSize.width() / 2;
00540     int h = height();
00541     if (templatesBoxSize.height() > 0)
00542         h -= templatesBoxSize.height() - MARGIN;
00543     p.drawRect(offsetX, m_bodyOffsetY, w, h);
00544 
00545     QFont font = UMLWidget::getFont();
00546     font.setUnderline(false);
00547     font.setItalic(false);
00548     const QFontMetrics fm = UMLWidget::getFontMetrics(UMLWidget::FT_NORMAL);
00549     const int fontHeight = fm.lineSpacing();
00550 
00551     //If there are any templates then draw them
00552     UMLTemplateList tlist = getClassifier()->getTemplateList();
00553     if ( tlist.count() > 0 ) {
00554         UMLWidget::setPen(p);
00555         QPen pen = p.pen();
00556         pen.setStyle(Qt::DotLine);
00557         p.setPen(pen);
00558         p.drawRect( offsetX + width() - templatesBoxSize.width(), offsetY,
00559                     templatesBoxSize.width(), templatesBoxSize.height() );
00560         p.setPen( QPen(Qt::black) );
00561         font.setBold(false);
00562         p.setFont(font);
00563         const int x = offsetX + width() - templatesBoxSize.width() + MARGIN;
00564         int y = offsetY + MARGIN;
00565         for ( UMLTemplate *t = tlist.first(); t; t = tlist.next() ) {
00566             QString text = t->toString();
00567             p.drawText(x, y, fm.size(0,text).width(), fontHeight, Qt::AlignVCenter, text);
00568             y += fontHeight;
00569         }
00570     }
00571 
00572     const int textX = offsetX + MARGIN;
00573     const int textWidth = w - MARGIN * 2;
00574 
00575     p.setPen(QPen(Qt::black));
00576 
00577     // draw stereotype
00578     font.setBold(true);
00579     QString stereo = m_pObject->getStereotype();
00580     /* if no stereotype is given we don't want to show the empty << >> */
00581     const bool showStereotype = (m_bShowStereotype && !stereo.isEmpty());
00582     const bool showNameOnly = (!m_bShowOperations && !m_bShowAttributes && !showStereotype);
00583     int nameHeight = fontHeight;
00584     if (showNameOnly) {
00585         nameHeight = h;
00586     } else if (showStereotype) {
00587         p.setFont(font);
00588         stereo = m_pObject->getStereotype(true);
00589         p.drawText(textX, m_bodyOffsetY, textWidth, fontHeight, Qt::AlignCenter, stereo);
00590         m_bodyOffsetY += fontHeight;
00591     }
00592 
00593     // draw name
00594     QString name;
00595     if (m_bShowPackage) {
00596         name = m_pObject->getFullyQualifiedName();
00597     } else {
00598         name = this->getName();
00599     }
00600     font.setItalic( m_pObject->getAbstract() );
00601     p.setFont(font);
00602     p.drawText(textX, m_bodyOffsetY, textWidth, nameHeight, Qt::AlignCenter, name);
00603     if (!showNameOnly) {
00604         m_bodyOffsetY += fontHeight;
00605         UMLWidget::setPen(p);
00606         p.drawLine(offsetX, m_bodyOffsetY, offsetX + w - 1, m_bodyOffsetY);
00607         p.setPen(QPen(Qt::black));
00608     }
00609     font.setBold(false);
00610     font.setItalic(false);
00611     p.setFont(font);
00612 
00613     // draw attributes
00614     const int numAtts = displayedAttributes();
00615     if (m_bShowAttributes) {
00616         drawMembers(p, Uml::ot_Attribute, m_ShowAttSigs, textX,
00617                     m_bodyOffsetY, fontHeight);
00618     }
00619 
00620     // draw dividing line between attributes and operations
00621     if (!showNameOnly) {
00622         if (numAtts == 0)
00623             m_bodyOffsetY += fontHeight / 2;  // no atts, so just add a bit of space
00624         else
00625             m_bodyOffsetY += fontHeight * numAtts;
00626         UMLWidget::setPen(p);
00627         p.drawLine(offsetX, m_bodyOffsetY, offsetX + w - 1, m_bodyOffsetY);
00628         p.setPen(QPen(Qt::black));
00629     }
00630 
00631     // draw operations
00632     if (m_bShowOperations) {
00633         drawMembers(p, Uml::ot_Operation, m_ShowOpSigs, textX,
00634                     m_bodyOffsetY, fontHeight);
00635     }
00636 
00637     if (UMLWidget::m_bSelected)
00638         UMLWidget::drawSelected(&p, offsetX, offsetY);
00639 }
00640 
00641 void ClassifierWidget::drawAsCircle(QPainter& p, int offsetX, int offsetY) {
00642     int w = width();
00643 
00644     const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
00645     const int fontHeight  = fm.lineSpacing();
00646     QString name;
00647     if ( m_bShowPackage ) {
00648         name = m_pObject->getFullyQualifiedName();
00649     } else {
00650         name = this -> getName();
00651     }
00652 
00653     p.drawEllipse(offsetX + w/2 - CIRCLE_SIZE/2, offsetY, CIRCLE_SIZE, CIRCLE_SIZE);
00654     p.setPen( QPen(Qt::black) );
00655 
00656     QFont font = UMLWidget::getFont();
00657     p.setFont(font);
00658     p.drawText(offsetX, offsetY + CIRCLE_SIZE, w, fontHeight, Qt::AlignCenter, name);
00659 
00660     if (m_bSelected) {
00661         drawSelected(&p, offsetX, offsetY);
00662     }
00663 }
00664 
00665 QSize ClassifierWidget::calculateAsCircleSize() {
00666     const QFontMetrics &fm = UMLWidget::getFontMetrics(UMLWidget::FT_ITALIC_UNDERLINE);
00667     const int fontHeight = fm.lineSpacing();
00668 
00669     int height = CIRCLE_SIZE + fontHeight;
00670 
00671     int width = CIRCLE_SIZE;
00672     QString displayedName;
00673     if (m_bShowPackage) {
00674         displayedName = m_pObject->getFullyQualifiedName();
00675     } else {
00676         displayedName = m_pObject->getName();
00677     }
00678     const int nameWidth = fm.size(0,displayedName).width();
00679     if (nameWidth > width)
00680         width = nameWidth;
00681     width += MARGIN * 2;
00682 
00683     return QSize(width, height);
00684 }
00685 
00686 void ClassifierWidget::drawMembers(QPainter & p, Uml::Object_Type ot, Uml::Signature_Type sigType,
00687                                    int x, int y, int fontHeight) {
00688     QFont f = UMLWidget::getFont();
00689     f.setBold(false);
00690     UMLClassifierListItemList list = getClassifier()->getFilteredList(ot);
00691     for (UMLClassifierListItem *obj = list.first(); obj; obj = list.next()) {
00692           if (m_bShowPublicOnly && obj->getVisibility() != Uml::Visibility::Public)
00693             continue;
00694         QString text = obj->toString(sigType);
00695         f.setItalic( obj->getAbstract() );
00696         f.setUnderline( obj->getStatic() );
00697         p.setFont( f );
00698         QFontMetrics fontMetrics(f);
00699         p.drawText(x, y, fontMetrics.size(0,text).width(), fontHeight, Qt::AlignVCenter, text);
00700         f.setItalic(false);
00701         f.setUnderline(false);
00702         p.setFont(f);
00703         y += fontHeight;
00704     }
00705 }
00706 
00707 void ClassifierWidget::setDrawAsCircle(bool drawAsCircle) {
00708     m_bDrawAsCircle = drawAsCircle;
00709     updateComponentSize();
00710     update();
00711 }
00712 
00713 bool ClassifierWidget::getDrawAsCircle() const {
00714     return m_bDrawAsCircle;
00715 }
00716 
00717 void ClassifierWidget::toggleDrawAsCircle() {
00718     m_bDrawAsCircle = !m_bDrawAsCircle;
00719     updateSigs();
00720     updateComponentSize();
00721     update();
00722 }
00723 
00724 void ClassifierWidget::changeToClass() {
00725     WidgetBase::setBaseType(Uml::wt_Class);
00726     getClassifier()->setBaseType(Uml::ot_Class);
00727 
00728     const Settings::OptionState& ops = m_pView->getOptionState();
00729     m_bShowAttributes = ops.classState.showAtts;
00730     m_bShowStereotype = ops.classState.showStereoType;
00731 
00732     updateComponentSize();
00733     update();
00734 }
00735 
00736 void ClassifierWidget::changeToInterface() {
00737     WidgetBase::setBaseType(Uml::wt_Interface);
00738     getClassifier()->setBaseType(Uml::ot_Interface);
00739 
00740     m_bShowAttributes = false;
00741     m_bShowStereotype = true;
00742 
00743     updateComponentSize();
00744     update();
00745 }
00746 
00747 void ClassifierWidget::adjustAssocs(int x, int y) {
00748     UMLWidget::adjustAssocs(x, y);
00749 
00750     if (m_pDoc->loading() || m_pAssocWidget == 0) {
00751         return;
00752     }
00753 
00754     m_pAssocWidget->computeAssocClassLine();
00755 }
00756 
00757 void ClassifierWidget::saveToXMI(QDomDocument & qDoc, QDomElement & qElement) {
00758     QDomElement conceptElement;
00759     UMLClassifier *umlc = getClassifier();
00760     if (umlc->isInterface())
00761         conceptElement = qDoc.createElement("interfacewidget");
00762     else
00763         conceptElement = qDoc.createElement("classwidget");
00764     UMLWidget::saveToXMI( qDoc, conceptElement );
00765     conceptElement.setAttribute( "showoperations", m_bShowOperations );
00766     conceptElement.setAttribute( "showpubliconly", m_bShowPublicOnly );
00767     conceptElement.setAttribute( "showopsigs", m_ShowOpSigs );
00768     conceptElement.setAttribute( "showpackage", m_bShowPackage );
00769     conceptElement.setAttribute( "showscope", m_bShowAccess );
00770     if (! umlc->isInterface()) {
00771         conceptElement.setAttribute("showattributes", m_bShowAttributes);
00772         conceptElement.setAttribute("showattsigs", m_ShowAttSigs);
00773     }
00774     if (umlc->isInterface() || umlc->getAbstract())
00775         conceptElement.setAttribute("drawascircle", m_bDrawAsCircle);
00776     qElement.appendChild( conceptElement );
00777 }
00778 
00779 bool ClassifierWidget::loadFromXMI(QDomElement & qElement) {
00780     if (!UMLWidget::loadFromXMI(qElement))
00781         return false;
00782     QString showatts = qElement.attribute( "showattributes", "0" );
00783     QString showops = qElement.attribute( "showoperations", "1" );
00784     QString showpubliconly = qElement.attribute( "showpubliconly", "0" );
00785     QString showattsigs = qElement.attribute( "showattsigs", "600" );
00786     QString showopsigs = qElement.attribute( "showopsigs", "600" );
00787     QString showpackage = qElement.attribute( "showpackage", "0" );
00788     QString showscope = qElement.attribute( "showscope", "0" );
00789     QString drawascircle = qElement.attribute("drawascircle", "0");
00790 
00791     m_bShowAttributes = (bool)showatts.toInt();
00792     m_bShowOperations = (bool)showops.toInt();
00793     m_bShowPublicOnly = (bool)showpubliconly.toInt();
00794     m_ShowAttSigs = (Uml::Signature_Type)showattsigs.toInt();
00795     m_ShowOpSigs = (Uml::Signature_Type)showopsigs.toInt();
00796     m_bShowPackage = (bool)showpackage.toInt();
00797     m_bShowAccess = (bool)showscope.toInt();
00798     m_bDrawAsCircle = (bool)drawascircle.toInt();
00799 
00800     return true;
00801 }
00802 
KDE Logo
This file is part of the documentation for umbrello Version 3.1.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Jun 26 08:07:55 2007 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003