00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "umlwidget.h"
00014
00015 #include <qpainter.h>
00016 #include <qcolor.h>
00017 #include <kdebug.h>
00018 #include <kcolordialog.h>
00019 #include <kfontdialog.h>
00020 #include <kmessagebox.h>
00021
00022 #include "umlwidgetcontroller.h"
00023 #include "umlobject.h"
00024 #include "classifier.h"
00025 #include "uniqueid.h"
00026 #include "uml.h"
00027 #include "umldoc.h"
00028 #include "umlview.h"
00029 #include "umlclassifierlistitemlist.h"
00030 #include "codegenerator.h"
00031 #include "codegenerators/simplecodegenerator.h"
00032 #include "listpopupmenu.h"
00033 #include "associationwidget.h"
00034 #include "dialogs/settingsdlg.h"
00035 #include "codedocument.h"
00036 #include "floatingtextwidget.h"
00037 #include "docwindow.h"
00038 #include "dialogs/classpropdlg.h"
00039 #include "clipboard/idchangelog.h"
00040
00041 using namespace Uml;
00042
00043
00044 UMLWidget::UMLWidget( UMLView * view, UMLObject * o, UMLWidgetController *widgetController )
00045 : WidgetBase(view), QCanvasRectangle( view->canvas() ),
00046 m_pMenu(0)
00047 {
00048 if (widgetController) {
00049 m_widgetController = widgetController;
00050 } else {
00051 m_widgetController = new UMLWidgetController(this);
00052 }
00053 init();
00054 m_pObject = o;
00055 if(m_pObject) {
00056 connect( m_pObject, SIGNAL(modified()), this, SLOT(updateWidget()) );
00057 m_nId = m_pObject->getID();
00058 }
00059 }
00060
00061 UMLWidget::UMLWidget(UMLView * view, Uml::IDType id , UMLWidgetController *widgetController )
00062 : WidgetBase(view), QCanvasRectangle( view->canvas() ),
00063 m_pMenu(0)
00064 {
00065 if (widgetController) {
00066 m_widgetController = widgetController;
00067 } else {
00068 m_widgetController = new UMLWidgetController(this);
00069 }
00070 init();
00071 if (id == Uml::id_None)
00072 m_nId = UniqueID::gen();
00073 else
00074 m_nId = id;
00075 }
00076
00077 UMLWidget::~UMLWidget() {
00078
00079 delete m_widgetController;
00080 cleanup();
00081 }
00082
00083 UMLWidget& UMLWidget::operator=(const UMLWidget& other) {
00084 if (this == &other)
00085 return *this;
00086
00087
00088 m_bUseFillColour = other.m_bUseFillColour;
00089 m_nId = other.m_nId;
00090 m_Type = other.m_Type;
00091 setX( other.getX() );
00092 setY( other.getY() );
00093 m_Assocs = other.m_Assocs;
00094 m_Font = other.m_Font;
00095 QCanvasRectangle::setSize( other.width(), other.height() );
00096 m_bUsesDiagramFillColour = other.m_bUsesDiagramFillColour;
00097 m_bUsesDiagramLineColour = other.m_bUsesDiagramLineColour;
00098 m_bUsesDiagramLineWidth = other.m_bUsesDiagramLineWidth;
00099 m_bUsesDiagramUseFillColour = other.m_bUsesDiagramUseFillColour;
00100 m_LineColour = other.m_LineColour;
00101 m_LineWidth = other.m_LineWidth;
00102 m_FillColour = other.m_FillColour;
00103 m_bIsInstance = other.m_bIsInstance;
00104 m_instanceName = other.m_instanceName;
00105
00106
00107 m_bSelected = other.m_bSelected;
00108 m_bStartMove = other.m_bStartMove;
00109 m_nPosX = other.m_nPosX;
00110 m_pObject = other.m_pObject;
00111 m_pView = other.m_pView;
00112 m_pMenu = other.m_pMenu;
00113 m_bResizable = other.m_bResizable;
00114 for (unsigned i = 0; i < FT_INVALID; i++)
00115 m_pFontMetrics[i] = other.m_pFontMetrics[i];
00116 m_bActivated = other.m_bActivated;
00117 m_bIgnoreSnapToGrid = other.m_bIgnoreSnapToGrid;
00118 m_bIgnoreSnapComponentSizeToGrid = other.m_bIgnoreSnapComponentSizeToGrid;
00119 return *this;
00120 }
00121
00122 bool UMLWidget::operator==(const UMLWidget& other) {
00123 if( this == &other )
00124 return true;
00125
00126 if(m_Type != other.m_Type) {
00127 return false;
00128 }
00129
00130 if (getID() != other.getID())
00131 return false;
00132
00133
00134
00135
00136 if (m_Assocs.count() != other.m_Assocs.count()) {
00137 return false;
00138 }
00139
00140
00141
00142 AssociationWidgetListIt assoc_it( m_Assocs );
00143 AssociationWidgetListIt assoc_it2( other.m_Assocs );
00144 AssociationWidget * assoc = 0, *assoc2 = 0;
00145 while ( ((assoc=assoc_it.current()) != 0) && ((assoc2=assoc_it2.current()) != 0)) {
00146 ++assoc_it;
00147 ++assoc_it2;
00148 if(!(*assoc == *assoc2)) {
00149 return false;
00150 }
00151 }
00152
00153 return true;
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168 }
00169
00170 void UMLWidget::mouseMoveEvent(QMouseEvent* me) {
00171 m_widgetController->mouseMoveEvent(me);
00172 }
00173
00174 void UMLWidget::mousePressEvent(QMouseEvent *me) {
00175 m_widgetController->mousePressEvent(me);
00176 }
00177
00178 void UMLWidget::updateWidget()
00179 {
00180 updateComponentSize();
00181 adjustAssocs( getX(), getY() );
00182 if (m_Type == Uml::wt_Class) {
00183 m_pView->createAutoAttributeAssociations(this);
00184 }
00185 if(isVisible())
00186 update();
00187 }
00188
00189 QSize UMLWidget::calculateSize() {
00190 return QSize(20, 20);
00191 }
00192
00193 void UMLWidget::constrain(int& width, int& height) {
00194 const QSize minSize = calculateSize();
00195 if (width < minSize.width())
00196 width = minSize.width();
00197 if (height < minSize.height())
00198 height = minSize.height();
00199 }
00200
00201 void UMLWidget::mouseReleaseEvent(QMouseEvent *me) {
00202 m_widgetController->mouseReleaseEvent(me);
00203 }
00204
00205 void UMLWidget::init() {
00206 m_nId = Uml::id_None;
00207 m_bIsInstance = false;
00208 if (m_pView) {
00209 m_bUseFillColour = true;
00210 m_bUsesDiagramFillColour = true;
00211 m_bUsesDiagramUseFillColour = true;
00212 const Settings::OptionState& optionState = m_pView->getOptionState();
00213 m_FillColour = optionState.uiState.fillColor;
00214 m_Font = optionState.uiState.font;
00215 m_bShowStereotype = optionState.classState.showStereoType;
00216 } else {
00217 kError() << "UMLWidget::init: SERIOUS PROBLEM - m_pView is NULL" << endl;
00218 m_bUseFillColour = false;
00219 m_bUsesDiagramFillColour = false;
00220 m_bUsesDiagramUseFillColour = false;
00221 m_bShowStereotype = false;
00222 }
00223
00224 for (int i = 0; i < (int)FT_INVALID; ++i)
00225 m_pFontMetrics[(UMLWidget::FontType)i] = 0;
00226
00227 m_bResizable = true;
00228
00229 m_bSelected = false;
00230 m_bStartMove = false;
00231 m_bActivated = false;
00232 m_bIgnoreSnapToGrid = false;
00233 m_bIgnoreSnapComponentSizeToGrid = false;
00234 m_pMenu = 0;
00235 m_pDoc = UMLApp::app()->getDocument();
00236 m_nPosX = 0;
00237 connect( m_pView, SIGNAL( sigRemovePopupMenu() ), this, SLOT( slotRemovePopupMenu() ) );
00238 connect( m_pView, SIGNAL( sigClearAllSelected() ), this, SLOT( slotClearAllSelected() ) );
00239
00240 connect( m_pView, SIGNAL(sigColorChanged(Uml::IDType)), this, SLOT(slotColorChanged(Uml::IDType)));
00241 connect( m_pView, SIGNAL(sigLineWidthChanged(Uml::IDType)), this, SLOT(slotLineWidthChanged(Uml::IDType)));
00242
00243
00244
00245 m_pObject = NULL;
00246 setZ(m_origZ = 2);
00247 }
00248
00249 void UMLWidget::slotMenuSelection(int sel) {
00250 QFont font;
00251 QColor newColour;
00252 const Uml::Widget_Type wt = m_Type;
00253 UMLWidget* widget = 0;
00254
00255 switch(sel) {
00256 case ListPopupMenu::mt_Rename:
00257 m_pDoc -> renameUMLObject(m_pObject);
00258
00259 break;
00260
00261 case ListPopupMenu::mt_Delete:
00262
00263 m_pView -> removeWidget(this);
00264 break;
00265
00266
00267 case ListPopupMenu::mt_Properties:
00268 if (wt == wt_Actor || wt == wt_UseCase ||
00269 wt == wt_Package || wt == wt_Interface || wt == wt_Datatype ||
00270 wt == wt_Component || wt == wt_Artifact ||
00271 wt == wt_Node || wt == wt_Enum || wt == wt_Entity ||
00272 (wt == wt_Class && m_pView -> getType() == dt_Class)) {
00273 showProperties();
00274 } else if (wt == wt_Object) {
00275 m_pObject->showProperties();
00276 } else {
00277 kWarning() << "making properties dialog for unknown widget type" << endl;
00278 }
00279
00280 break;
00281
00282 case ListPopupMenu::mt_Line_Color:
00283 case ListPopupMenu::mt_Line_Color_Selection:
00284 widget = m_pView->getFirstMultiSelectedWidget();
00285 if (widget) { newColour = widget->getLineColor(); }
00286 if( KColorDialog::getColor(newColour) ) {
00287 m_pView -> selectionSetLineColor( newColour );
00288 m_pDoc -> setModified(true);
00289 }
00290 break;
00291
00292 case ListPopupMenu::mt_Fill_Color:
00293 case ListPopupMenu::mt_Fill_Color_Selection:
00294 widget = m_pView->getFirstMultiSelectedWidget();
00295 if (widget) { newColour = widget->getFillColour(); }
00296 if ( KColorDialog::getColor(newColour) ) {
00297 m_pView -> selectionSetFillColor( newColour );
00298 m_pDoc -> setModified(true);
00299 }
00300 break;
00301
00302 case ListPopupMenu::mt_Use_Fill_Color:
00303 m_bUseFillColour = !m_bUseFillColour;
00304 m_bUsesDiagramUseFillColour = false;
00305 m_pView->selectionUseFillColor( m_bUseFillColour );
00306 break;
00307 case ListPopupMenu::mt_Show_Attributes_Selection:
00308 case ListPopupMenu::mt_Show_Operations_Selection:
00309 case ListPopupMenu::mt_Visibility_Selection:
00310 case ListPopupMenu::mt_DrawAsCircle_Selection:
00311 case ListPopupMenu::mt_Show_Operation_Signature_Selection:
00312 case ListPopupMenu::mt_Show_Attribute_Signature_Selection:
00313 case ListPopupMenu::mt_Show_Packages_Selection:
00314 case ListPopupMenu::mt_Show_Stereotypes_Selection:
00315 case ListPopupMenu::mt_Show_Public_Only_Selection:
00316 m_pView->selectionToggleShow(sel);
00317 m_pDoc->setModified(true);
00318 break;
00319
00320 case ListPopupMenu::mt_ViewCode: {
00321 UMLClassifier *c = dynamic_cast<UMLClassifier*>(m_pObject);
00322 if(c)
00323 {
00324 UMLApp::app()->viewCodeDocument(c);
00325 }
00326 break;
00327 }
00328
00329 case ListPopupMenu::mt_Delete_Selection:
00330 m_pView -> deleteSelection();
00331 break;
00332
00333 case ListPopupMenu::mt_Change_Font:
00334 font = getFont();
00335 if( KFontDialog::getFont( font, false, m_pView ) )
00336 {
00337 setFont( font );
00338 m_pDoc->setModified(true);
00339 }
00340 break;
00341
00342 case ListPopupMenu::mt_Change_Font_Selection:
00343 font = getFont();
00344 if( KFontDialog::getFont( font, false, m_pView ) )
00345 {
00346 m_pView -> selectionSetFont( font );
00347 m_pDoc->setModified(true);
00348 }
00349 break;
00350
00351 case ListPopupMenu::mt_Cut:
00352 m_pView -> setStartedCut();
00353 UMLApp::app() -> slotEditCut();
00354 break;
00355
00356 case ListPopupMenu::mt_Copy:
00357 UMLApp::app() -> slotEditCopy();
00358 break;
00359
00360 case ListPopupMenu::mt_Paste:
00361 UMLApp::app() -> slotEditPaste();
00362 break;
00363
00364 case ListPopupMenu::mt_Refactoring:
00365
00366 if(dynamic_cast<UMLClassifier*>(m_pObject))
00367 {
00368 UMLApp::app()->refactor(static_cast<UMLClassifier*>(m_pObject));
00369 }
00370 break;
00371
00372 case ListPopupMenu::mt_Clone:
00373
00374 {
00375 UMLObject *pClone = m_pObject->clone();
00376 m_pView->addObject(pClone);
00377 }
00378 break;
00379
00380 case ListPopupMenu::mt_Rename_MultiA:
00381 case ListPopupMenu::mt_Rename_MultiB:
00382 case ListPopupMenu::mt_Rename_Name:
00383 case ListPopupMenu::mt_Rename_RoleAName:
00384 case ListPopupMenu::mt_Rename_RoleBName:
00385 {
00386 FloatingTextWidget *ft = static_cast<FloatingTextWidget*>(this);
00387 ft->handleRename();
00388 break;
00389 }
00390 }
00391 }
00392
00393 void UMLWidget::slotWidgetMoved(Uml::IDType ) {}
00394
00395 void UMLWidget::slotColorChanged(Uml::IDType viewID) {
00396
00397 if(m_pView->getID() != viewID) {
00398 return;
00399 }
00400 if ( m_bUsesDiagramFillColour ) {
00401 m_FillColour = m_pView->getFillColor();
00402 }
00403 if ( m_bUsesDiagramLineColour ) {
00404 m_LineColour = m_pView->getLineColor();
00405 }
00406 if ( m_bUsesDiagramUseFillColour ) {
00407 m_bUseFillColour = m_pView->getUseFillColor();
00408 }
00409 update();
00410 }
00411
00412 void UMLWidget::slotLineWidthChanged(Uml::IDType viewID) {
00413
00414 if(m_pView->getID() != viewID) {
00415 return;
00416 }
00417 if ( m_bUsesDiagramLineWidth ) {
00418 m_LineWidth = m_pView->getLineWidth();
00419 }
00420 update();
00421 }
00422
00423 void UMLWidget::mouseDoubleClickEvent( QMouseEvent * me ) {
00424 m_widgetController->mouseDoubleClickEvent(me);
00425 }
00426
00427 void UMLWidget::setUseFillColour(bool fc) {
00428 m_bUseFillColour = fc;
00429 m_bUsesDiagramUseFillColour = false;
00430 update();
00431 }
00432
00433 void UMLWidget::setLineColor(const QColor &colour) {
00434 WidgetBase::setLineColor(colour);
00435 update();
00436 }
00437
00438 void UMLWidget::setLineWidth(uint width) {
00439 WidgetBase::setLineWidth(width);
00440 update();
00441 }
00442
00443 void UMLWidget::setFillColour(const QColor &colour) {
00444 m_FillColour = colour;
00445 m_bUsesDiagramFillColour = false;
00446 update();
00447 }
00448
00449 void UMLWidget::drawSelected(QPainter * p, int offsetX, int offsetY) {
00450 int w = width();
00451 int h = height();
00452 int s = 4;
00453 QBrush brush(blue);
00454 p -> fillRect(offsetX, offsetY, s, s, brush);
00455 p -> fillRect(offsetX, offsetY + h - s, s, s, brush);
00456 p -> fillRect(offsetX + w - s, offsetY, s, s, brush);
00457
00458
00459 if (m_bResizable) {
00460 brush.setColor(Qt::red);
00461 const int right = offsetX + w;
00462 const int bottom = offsetY + h;
00463 p->drawLine(right - s, offsetY + h - 1, offsetX + w - 1, offsetY + h - s);
00464 p->drawLine(right - (s*2), bottom - 1, right - 1, bottom - (s*2) );
00465 p->drawLine(right - (s*3), bottom - 1, right - 1, bottom - (s*3) );
00466 } else {
00467 p->fillRect(offsetX + w - s, offsetY + h - s, s, s, brush);
00468 }
00469 }
00470
00471 bool UMLWidget::activate(IDChangeLog* ) {
00472 if (widgetHasUMLObject(m_Type) && m_pObject == NULL) {
00473 m_pObject = m_pDoc->findObjectById(m_nId);
00474 if (m_pObject == NULL) {
00475 kError() << "UMLWidget::activate: cannot find UMLObject with id="
00476 << ID2STR(m_nId) << endl;
00477 return false;
00478 }
00479 }
00480 setFont(m_Font);
00481 setSize(getWidth(), getHeight());
00482 m_bActivated = true;
00483 updateComponentSize();
00484 if (m_pView->getPaste()) {
00485 FloatingTextWidget * ft = 0;
00486 QPoint point = m_pView -> getPastePoint();
00487 int x = point.x() + getX();
00488 int y = point.y() + getY();
00489 x = x < 0?0:x;
00490 y = y < 0?0:y;
00491 if( m_pView -> getType() == dt_Sequence ) {
00492 switch( getBaseType() ) {
00493 case wt_Object:
00494 case wt_Message:
00495 setY( getY() );
00496 setX( x );
00497 break;
00498
00499 case wt_Text:
00500 ft = static_cast<FloatingTextWidget *>( this );
00501 if (ft->getRole() == tr_Seq_Message) {
00502 setX( x );
00503 setY( getY() );
00504 } else {
00505 setX( getX() );
00506 setY( getY() );
00507 }
00508 break;
00509
00510 default:
00511 setY( y );
00512 break;
00513 }
00514 }
00515 else {
00516 setX( x );
00517 setY( y );
00518 }
00519 }
00520 else {
00521 setX( getX() );
00522 setY( getY() );
00523 }
00524 if ( m_pView -> getPaste() )
00525 m_pView -> createAutoAssociations( this );
00526 updateComponentSize();
00527 return true;
00528 }
00529
00531 bool UMLWidget::isActivated() {
00532 return m_bActivated;
00533 }
00534
00535 void UMLWidget::setActivated(bool Active ) {
00536 m_bActivated = Active;
00537 }
00538
00539 void UMLWidget::addAssoc(AssociationWidget* pAssoc) {
00540 if (pAssoc && !m_Assocs.contains(pAssoc)) {
00541 m_Assocs.append(pAssoc);
00542 }
00543 }
00544
00545 void UMLWidget::removeAssoc(AssociationWidget* pAssoc) {
00546 if(pAssoc) {
00547 m_Assocs.remove(pAssoc);
00548 }
00549 }
00550
00551 void UMLWidget::adjustAssocs(int x, int y)
00552 {
00553
00554
00555
00556
00557
00558
00559
00561 if ( m_pDoc->loading() ) {
00562
00563
00564 return;
00565 }
00566 AssociationWidgetListIt assoc_it(m_Assocs);
00567 AssociationWidget* assocwidget = 0;
00568 while ((assocwidget = assoc_it.current())) {
00569 ++assoc_it;
00570 assocwidget->saveIdealTextPositions();
00571 }
00572 assoc_it.toFirst();
00573 while ((assocwidget = assoc_it.current())) {
00574 ++assoc_it;
00575 assocwidget->widgetMoved(this, x, y);
00576 }
00577 }
00578
00579 void UMLWidget::adjustUnselectedAssocs(int x, int y)
00580 {
00581 AssociationWidgetListIt assoc_it(m_Assocs);
00582 AssociationWidget* assocwidget = 0;
00583 while ((assocwidget = assoc_it.current())) {
00584 ++assoc_it;
00585 if(!assocwidget->getSelected())
00586 assocwidget->saveIdealTextPositions();
00587 }
00588 assoc_it.toFirst();
00589 while ((assocwidget = assoc_it.current())) {
00590 ++assoc_it;
00591 if(!assocwidget->getSelected())
00592 assocwidget->widgetMoved(this, x, y);
00593 }
00594 }
00595
00596 void UMLWidget::showProperties() {
00597
00598
00599 DocWindow *docwindow = UMLApp::app()->getDocWindow();
00600 docwindow->updateDocumentation( false );
00601 ClassPropDlg *dlg = new ClassPropDlg((QWidget*)UMLApp::app(), this);
00602
00603 if (dlg->exec()) {
00604 docwindow->showDocumentation( getUMLObject() , true );
00605 m_pDoc->setModified(true);
00606 }
00607 dlg->close(true);
00608 }
00609
00610 void UMLWidget::startPopupMenu( const QPoint &At) {
00611 slotRemovePopupMenu();
00612
00613
00614
00615 int count = m_pView->getSelectCount(true);
00616
00617
00618
00619
00620 bool multi = (m_bSelected && count > 1);
00621
00622
00623 bool unique = false;
00624
00625
00626
00627 if (multi == true)
00628 unique = m_pView -> checkUniqueSelection();
00629
00630
00631 m_pMenu = new ListPopupMenu(m_pView, this, multi, unique);
00632
00633
00634 CodeGenerator * currentCG = UMLApp::app()->getGenerator();
00635 if(currentCG && dynamic_cast<SimpleCodeGenerator*>(currentCG))
00636 m_pMenu->setItemEnabled(ListPopupMenu::mt_ViewCode, false);
00637
00638 m_pMenu->popup(At);
00639
00640 connect(m_pMenu, SIGNAL(activated(int)), this, SLOT(slotMenuSelection(int)));
00641 }
00642
00643 void UMLWidget::slotRemovePopupMenu() {
00644 if(m_pMenu) {
00645 disconnect(m_pMenu, SIGNAL(activated(int)), this, SLOT(slotMenuSelection(int)));
00646 delete m_pMenu;
00647 m_pMenu = 0;
00648 }
00649 }
00650
00651 int UMLWidget::onWidget(const QPoint & p) {
00652 const int w = width();
00653 const int h = height();
00654 const int left = getX();
00655 const int right = left + w;
00656 const int top = getY();
00657 const int bottom = top + h;
00658 if (p.x() < left || p.x() > right ||
00659 p.y() < top || p.y() > bottom)
00660 return 0;
00661 return (w + h) / 2;
00662 }
00663
00664 void UMLWidget::moveBy(int dx, int dy) {
00665 int newX = getX() + dx;
00666 int newY = getY() + dy;
00667 setX(newX);
00668 setY(newY);
00669 adjustAssocs(newX, newY);
00670 }
00671
00672 void UMLWidget::setPen(QPainter & p) {
00673 p.setPen( QPen(m_LineColour, m_LineWidth) );
00674 }
00675
00676 void UMLWidget::drawShape(QPainter &p ) {
00677 draw( p, getX(), getY() );
00678 }
00679
00680 void UMLWidget::setSelected(bool _select) {
00681 const Uml::Widget_Type wt = m_Type;
00682 if( _select ) {
00683 if( m_pView -> getSelectCount() == 0 ) {
00684 if ( widgetHasUMLObject(wt) ) {
00685 m_pView->showDocumentation(m_pObject, false);
00686 } else {
00687 m_pView->showDocumentation(this, false);
00688 }
00689 }
00690
00691
00692
00693 } else {
00694
00695
00696
00697 if( m_bSelected )
00698 m_pView -> updateDocumentation( true );
00699 }
00700 m_bSelected = _select;
00701
00702 const QPoint pos(getX(), getY());
00703 UMLWidget *bkgnd = m_pView->getWidgetAt(pos);
00704 if (bkgnd && bkgnd != this && _select) {
00705 kDebug() << "UMLWidget::setSelected: setting Z to "
00706 << bkgnd->getZ() + 1 << ", SelectState: " << _select << endl;
00707 setZ( bkgnd->getZ() + 1 );
00708 } else {
00709 setZ( m_origZ );
00710 }
00711
00712 update();
00713
00714
00715
00716 UMLApp::app()->slotCopyChanged();
00717 }
00718
00719 void UMLWidget::slotClearAllSelected()
00720 {
00721 setSelected( false );
00722 }
00723
00724 void UMLWidget::setView(UMLView * v) {
00725
00726 disconnect( m_pView, SIGNAL( sigRemovePopupMenu() ), this, SLOT( slotRemovePopupMenu() ) );
00727 disconnect( m_pView, SIGNAL( sigClearAllSelected() ), this, SLOT( slotClearAllSelected() ) );
00728 disconnect( m_pView, SIGNAL(sigColorChanged(Uml::IDType)), this, SLOT(slotColorChanged(Uml::IDType)));
00729 disconnect( m_pView, SIGNAL(sigLineWidthChanged(Uml::IDType)), this, SLOT(slotLineWidthChanged(Uml::IDType)));
00730 m_pView = v;
00731 connect( m_pView, SIGNAL( sigRemovePopupMenu() ), this, SLOT( slotRemovePopupMenu() ) );
00732 connect( m_pView, SIGNAL( sigClearAllSelected() ), this, SLOT( slotClearAllSelected() ) );
00733 connect( m_pView, SIGNAL(sigColorChanged(Uml::IDType)), this, SLOT(slotColorChanged(Uml::IDType)));
00734 connect( m_pView, SIGNAL(sigLineWidthChanged(Uml::IDType)), this, SLOT(slotLineWidthChanged(Uml::IDType)));
00735 }
00736
00737 void UMLWidget::setX( int x ) {
00738 if (!m_bIgnoreSnapToGrid) {
00739 x = m_pView->snappedX(x);
00740 }
00741 QCanvasItem::setX( (double)x );
00742 }
00743
00744 void UMLWidget::setY( int y ) {
00745 if (!m_bIgnoreSnapToGrid){
00746 y = m_pView->snappedX(y);
00747 }
00748 QCanvasItem::setY( (double)y );
00749 }
00750
00751 void UMLWidget::setZ(int z) {
00752 m_origZ = getZ();
00753 QCanvasItem::setZ(z);
00754 }
00755
00756 void UMLWidget::setName(const QString &strName) {
00757 if (m_pObject)
00758 m_pObject->setName(strName);
00759 else
00760 m_Text = strName;
00761 updateComponentSize();
00762 adjustAssocs( getX(), getY() );
00763 }
00764
00765 QString UMLWidget::getName() const {
00766 if (m_pObject)
00767 return m_pObject->getName();
00768 return m_Text;
00769 }
00770
00771 void UMLWidget::cleanup() {
00772 }
00773
00774 void UMLWidget::slotSnapToGrid( ) {
00775 setX( getX() );
00776 setY( getY() );
00777 }
00778
00779 bool UMLWidget::widgetHasUMLObject(Uml::Widget_Type type) {
00780 if (type == wt_Actor ||
00781 type == wt_UseCase ||
00782 type == wt_Class ||
00783 type == wt_Interface ||
00784 type == wt_Enum ||
00785 type == wt_Datatype ||
00786 type == wt_Package ||
00787 type == wt_Component ||
00788 type == wt_Node ||
00789 type == wt_Artifact ||
00790 type == wt_Object) {
00791 return true;
00792 } else {
00793 return false;
00794 }
00795 }
00796
00797 void UMLWidget::setIgnoreSnapToGrid(bool to) {
00798 m_bIgnoreSnapToGrid = to;
00799 }
00800
00801 bool UMLWidget::getIgnoreSnapToGrid() const {
00802 return m_bIgnoreSnapToGrid;
00803 }
00804
00805 void UMLWidget::setSize(int width,int height) {
00806
00807 if (!m_bIgnoreSnapComponentSizeToGrid
00808 && m_pView -> getSnapComponentSizeToGrid() )
00809 {
00810
00811 int numX = width / m_pView->getSnapX();
00812 int numY = height / m_pView->getSnapY();
00813
00814 if (width > numX * m_pView->getSnapX())
00815 width = (numX + 1) * m_pView->getSnapX();
00816 if (height > numY * m_pView->getSnapY())
00817 height = (numY + 1) * m_pView->getSnapY();
00818 }
00819
00820 QCanvasRectangle::setSize(width,height);
00821 }
00822
00823 void UMLWidget::updateComponentSize() {
00824 if (m_pDoc->loading())
00825 return;
00826 const QSize minSize = calculateSize();
00827 const int w = minSize.width();
00828 const int h = minSize.height();
00829 setSize(w, h);
00830 adjustAssocs( getX(), getY() );
00831 }
00832
00833 void UMLWidget::setDefaultFontMetrics(UMLWidget::FontType fontType) {
00834 setupFontType(m_Font, fontType);
00835 setFontMetrics(fontType, QFontMetrics(m_Font));
00836 }
00837
00838 void UMLWidget::setupFontType(QFont &font, UMLWidget::FontType fontType) {
00839 switch(fontType){
00840 case FT_NORMAL:
00841 font.setBold(false);
00842 font.setItalic(false);
00843 font.setUnderline(false);
00844 break;
00845 case FT_BOLD:
00846 font.setBold(true);
00847 font.setItalic(false);
00848 font.setUnderline(false);
00849 break;
00850 case FT_ITALIC:
00851 font.setBold(false);
00852 font.setItalic(true);
00853 font.setUnderline(false);
00854 break;
00855 case FT_UNDERLINE:
00856 font.setBold(false);
00857 font.setItalic(false);
00858 font.setUnderline(true);
00859 break;
00860 case FT_BOLD_ITALIC:
00861 font.setBold(true);
00862 font.setItalic(true);
00863 font.setUnderline(false);
00864 break;
00865 case FT_BOLD_UNDERLINE:
00866 font.setBold(true);
00867 font.setItalic(false);
00868 font.setUnderline(true);
00869 break;
00870 case FT_ITALIC_UNDERLINE:
00871 font.setBold(false);
00872 font.setItalic(true);
00873 font.setUnderline(true);
00874 break;
00875 case FT_BOLD_ITALIC_UNDERLINE:
00876 font.setBold(true);
00877 font.setItalic(true);
00878 font.setUnderline(true);
00879 break;
00880 default: return;
00881 }
00882 }
00883
00884 void UMLWidget::setDefaultFontMetrics(UMLWidget::FontType fontType, QPainter &painter) {
00885 setupFontType(m_Font, fontType);
00886 painter.setFont(m_Font);
00887 setFontMetrics(fontType, painter.fontMetrics());
00888 }
00889
00890
00891 QFontMetrics &UMLWidget::getFontMetrics(UMLWidget::FontType fontType) {
00892 if (m_pFontMetrics[fontType] == 0) {
00893 setDefaultFontMetrics(fontType);
00894 }
00895 return *m_pFontMetrics[fontType];
00896 }
00897
00898 void UMLWidget::setFontMetrics(UMLWidget::FontType fontType, QFontMetrics fm) {
00899 delete m_pFontMetrics[fontType];
00900 m_pFontMetrics[fontType] = new QFontMetrics(fm);
00901 }
00902
00903 QFont UMLWidget::getFont() const {
00904 return m_Font;
00905 }
00906
00907 void UMLWidget::setFont( QFont font ) {
00908 m_Font = font;
00909 forceUpdateFontMetrics(0);
00910 if (m_pDoc->loading())
00911 return;
00912 update();
00913 }
00914
00915 void UMLWidget::forceUpdateFontMetrics(QPainter *painter) {
00916 if (painter == 0) {
00917 for (int i = 0; i < (int)UMLWidget::FT_INVALID; ++i) {
00918 if (m_pFontMetrics[(UMLWidget::FontType)i]!=0)
00919 setDefaultFontMetrics((UMLWidget::FontType)i);
00920 }
00921 } else {
00922 for (int i2 = 0; i2 < (int)UMLWidget::FT_INVALID; ++i2) {
00923 if (m_pFontMetrics[(UMLWidget::FontType)i2]!=0)
00924 setDefaultFontMetrics((UMLWidget::FontType)i2,*painter);
00925 }
00926 }
00927
00928 updateComponentSize();
00929 }
00930
00931 void UMLWidget::setShowStereotype(bool _status) {
00932 m_bShowStereotype = _status;
00933 updateComponentSize();
00934 update();
00935 }
00936
00937 bool UMLWidget::getShowStereotype() const {
00938 return m_bShowStereotype;
00939 }
00940
00941 void UMLWidget::moveEvent(QMoveEvent *me) {
00942 }
00943
00944 void UMLWidget::saveToXMI( QDomDocument & qDoc, QDomElement & qElement ) {
00945
00946
00947
00948
00949 WidgetBase::saveToXMI(qDoc, qElement);
00950 qElement.setAttribute( "xmi.id", ID2STR(getID()) );
00951 qElement.setAttribute( "font", m_Font.toString() );
00952 qElement.setAttribute( "usefillcolor", m_bUseFillColour );
00953 qElement.setAttribute( "x", getX() );
00954 qElement.setAttribute( "y", getY() );
00955 qElement.setAttribute( "width", getWidth() );
00956 qElement.setAttribute( "height", getHeight() );
00957
00958 qElement.setAttribute( "usesdiagramfillcolor", m_bUsesDiagramFillColour );
00959 qElement.setAttribute( "usesdiagramusefillcolor", m_bUsesDiagramUseFillColour );
00960 if (m_bUsesDiagramFillColour) {
00961 qElement.setAttribute( "fillcolor", "none" );
00962 } else {
00963 qElement.setAttribute( "fillcolor", m_FillColour.name() );
00964 }
00965 qElement.setAttribute("isinstance", m_bIsInstance);
00966 if (!m_instanceName.isEmpty())
00967 qElement.setAttribute("instancename", m_instanceName);
00968 if (m_bShowStereotype)
00969 qElement.setAttribute("showstereotype", m_bShowStereotype);
00970 }
00971
00972 bool UMLWidget::loadFromXMI( QDomElement & qElement ) {
00973 WidgetBase::loadFromXMI(qElement);
00974 QString id = qElement.attribute( "xmi.id", "-1" );
00975 QString font = qElement.attribute( "font", "" );
00976 QString usefillcolor = qElement.attribute( "usefillcolor", "1" );
00977 QString x = qElement.attribute( "x", "0" );
00978 QString y = qElement.attribute( "y", "0" );
00979 QString h = qElement.attribute( "height", "0" );
00980 QString w = qElement.attribute( "width", "0" );
00981
00982
00983
00984
00985
00986 QString fillColour = qElement.attribute( "fillcolour", "none" );
00987 fillColour = qElement.attribute( "fillcolor", fillColour );
00988 QString usesDiagramFillColour = qElement.attribute( "usesdiagramfillcolour", "1" );
00989 usesDiagramFillColour = qElement.attribute( "usesdiagramfillcolor", usesDiagramFillColour );
00990 QString usesDiagramUseFillColour = qElement.attribute( "usesdiagramusefillcolour", "1" );
00991 usesDiagramUseFillColour = qElement.attribute( "usesdiagramusefillcolor", usesDiagramUseFillColour );
00992
00993 m_nId = STR2ID(id);
00994
00995 if( !font.isEmpty() ) {
00996
00997 m_Font.fromString(font);
00998
00999 } else {
01000 kWarning() << "Using default font " << m_Font.toString()
01001 << " for widget with xmi.id " << ID2STR(m_nId) << endl;
01002
01003 }
01004 m_bUseFillColour = (bool)usefillcolor.toInt();
01005 m_bUsesDiagramFillColour = (bool)usesDiagramFillColour.toInt();
01006 m_bUsesDiagramUseFillColour = (bool)usesDiagramUseFillColour.toInt();
01007 setSize( w.toInt(), h.toInt() );
01008 setX( x.toInt() );
01009 setY( y.toInt() );
01010 if (fillColour != "none") {
01011 m_FillColour = QColor(fillColour);
01012 }
01013 QString isinstance = qElement.attribute("isinstance", "0");
01014 m_bIsInstance = (bool)isinstance.toInt();
01015 m_instanceName = qElement.attribute("instancename", "");
01016 QString showstereo = qElement.attribute("showstereotype", "0");
01017 m_bShowStereotype = (bool)showstereo.toInt();
01018 return true;
01019 }
01020
01021 UMLWidgetController* UMLWidget::getWidgetController() {
01022 return m_widgetController;
01023 }
01024
01025 #include "umlwidget.moc"