00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "umlview.h"
00014
00015
00016 #include <climits>
00017 #include <math.h>
00018
00019
00020 #include <qpixmap.h>
00021 #include <qpicture.h>
00022 #include <qprinter.h>
00023 #include <qpainter.h>
00024 #include <qstring.h>
00025 #include <qstringlist.h>
00026 #include <qobjectlist.h>
00027 #include <qobjectdict.h>
00028 #include <qdragobject.h>
00029 #include <qpaintdevicemetrics.h>
00030 #include <qfileinfo.h>
00031 #include <qptrlist.h>
00032 #include <qcolor.h>
00033 #include <qwmatrix.h>
00034 #include <qregexp.h>
00035
00036
00037 #include <ktempfile.h>
00038 #include <kio/netaccess.h>
00039 #include <kmessagebox.h>
00040 #include <kprinter.h>
00041 #include <kcursor.h>
00042 #include <kfiledialog.h>
00043 #include <kinputdialog.h>
00044 #include <klocale.h>
00045 #include <kdebug.h>
00046
00047
00048 #include "umlviewimageexporter.h"
00049 #include "listpopupmenu.h"
00050 #include "uml.h"
00051 #include "umldoc.h"
00052 #include "umlobject.h"
00053 #include "docwindow.h"
00054 #include "assocrules.h"
00055 #include "umlrole.h"
00056 #include "umlviewcanvas.h"
00057 #include "dialogs/classoptionspage.h"
00058 #include "dialogs/umlviewdialog.h"
00059 #include "clipboard/idchangelog.h"
00060 #include "clipboard/umldrag.h"
00061 #include "widget_factory.h"
00062 #include "floatingtextwidget.h"
00063 #include "classifierwidget.h"
00064 #include "classifier.h"
00065 #include "packagewidget.h"
00066 #include "package.h"
00067 #include "folder.h"
00068 #include "componentwidget.h"
00069 #include "nodewidget.h"
00070 #include "artifactwidget.h"
00071 #include "datatypewidget.h"
00072 #include "enumwidget.h"
00073 #include "entitywidget.h"
00074 #include "actorwidget.h"
00075 #include "usecasewidget.h"
00076 #include "notewidget.h"
00077 #include "boxwidget.h"
00078 #include "associationwidget.h"
00079 #include "objectwidget.h"
00080 #include "messagewidget.h"
00081 #include "statewidget.h"
00082 #include "forkjoinwidget.h"
00083 #include "activitywidget.h"
00084 #include "seqlinewidget.h"
00085 #include "uniqueid.h"
00086 #include "umllistviewitemlist.h"
00087 #include "umllistviewitem.h"
00088 #include "umllistview.h"
00089 #include "umlobjectlist.h"
00090 #include "association.h"
00091 #include "attribute.h"
00092 #include "model_utils.h"
00093 #include "object_factory.h"
00094 #include "umlwidget.h"
00095 #include "toolbarstatefactory.h"
00096
00097
00098
00099
00100
00101 #define MANUAL_CONTROL_DOUBLE_BUFFERING
00102
00103
00104 const int UMLView::defaultCanvasSize = 1300;
00105
00106 using namespace Uml;
00107
00108
00109
00110 UMLView::UMLView(UMLFolder *parentFolder) : QCanvasView(UMLApp::app()->getMainViewWidget()) {
00111 init();
00112 m_pDoc = UMLApp::app()->getDocument();
00113 m_pFolder = parentFolder;
00114 }
00115
00116 void UMLView::init() {
00117
00118 m_nID = Uml::id_None;
00119 m_pDoc = NULL;
00120 m_Documentation = "";
00121 m_Type = dt_Undefined;
00122 m_bUseSnapToGrid = false;
00123 m_bUseSnapComponentSizeToGrid = false;
00124 m_bShowSnapGrid = false;
00125 m_nSnapX = 10;
00126 m_nSnapY = 10;
00127 m_nZoom = 100;
00128 m_nCanvasWidth = UMLView::defaultCanvasSize;
00129 m_nCanvasHeight = UMLView::defaultCanvasSize;
00130 m_nCollaborationId = 0;
00131
00132
00133 m_AssociationList.setAutoDelete( true );
00134
00135
00136 m_bChildDisplayedDoc = false;
00137 m_bPaste = false;
00138 m_bActivated = false;
00139 m_bCreateObject = false;
00140 m_bDrawSelectedOnly = false;
00141 m_bPopupShowing = false;
00142 m_bStartedCut = false;
00143
00144 m_PastePoint = QPoint(0, 0);
00145 m_pIDChangesLog = 0;
00146 m_pMenu = 0;
00147
00148 m_pImageExporter = new UMLViewImageExporter(this);
00149
00150
00151 viewport() -> setBackgroundMode( Qt::NoBackground );
00152 setCanvas( new UMLViewCanvas( this ) );
00153
00154
00155
00156
00157
00158
00159 canvas() -> setUpdatePeriod( -1 );
00160 resizeContents(defaultCanvasSize, defaultCanvasSize);
00161 canvas() -> resize(defaultCanvasSize, defaultCanvasSize);
00162 setAcceptDrops(true);
00163 viewport() -> setAcceptDrops(true);
00164 setDragAutoScroll(false);
00165
00166 viewport() -> setMouseTracking(false);
00167
00168
00169 connect( this, SIGNAL(sigRemovePopupMenu()), this, SLOT(slotRemovePopupMenu() ) );
00170 connect( UMLApp::app(), SIGNAL( sigCutSuccessful() ),
00171 this, SLOT( slotCutSuccessful() ) );
00172
00173
00174
00175 m_pToolBarStateFactory = new ToolBarStateFactory(this);
00176 m_pToolBarState = m_pToolBarStateFactory->getState(WorkToolBar::tbb_Arrow);
00177
00178 }
00179
00180 UMLView::~UMLView() {
00181 delete m_pImageExporter;
00182
00183 if(m_pIDChangesLog) {
00184 delete m_pIDChangesLog;
00185 m_pIDChangesLog = 0;
00186 }
00187
00188
00189
00190
00191
00192
00193
00194
00195 blockSignals( true );
00196 removeAllWidgets();
00197
00198 delete m_pToolBarStateFactory;
00199 m_pToolBarStateFactory = NULL;
00200
00201
00202
00203
00204 delete canvas();
00205 }
00206
00207 QString UMLView::getName() const {
00208 return m_Name;
00209 }
00210
00211 void UMLView::setName(const QString &name) {
00212 m_Name = name;
00213 }
00214
00215 int UMLView::generateCollaborationId() {
00216 return ++m_nCollaborationId;
00217 }
00218
00219 void UMLView::print(KPrinter *pPrinter, QPainter & pPainter) {
00220 int height, width;
00221
00222 pPrinter->setFullPage( true );
00223 QPaintDeviceMetrics metrics(pPrinter);
00224 QFontMetrics fm = pPainter.fontMetrics();
00225 int fontHeight = fm.lineSpacing();
00226 uint left, right, top, bottom;
00227
00228 pPrinter->margins ( &top, &left, &bottom, &right );
00229
00230 left += 2;
00231 right += 2;
00232 top += 2;
00233 bottom += 2;
00234
00235 if(pPrinter->orientation() == KPrinter::Landscape) {
00236
00237 uint right_old = right;
00238
00239 right = top;
00240
00241 top = left;
00242
00243 left = bottom;
00244
00245 bottom = right_old;
00246 }
00247
00248
00249
00250 forceUpdateWidgetFontMetrics(&pPainter);
00251
00252 width = metrics.width() - left - right;
00253 height = metrics.height() - top - bottom;
00254
00255
00256 QRect rect = getDiagramRect();
00257
00258
00259 #if 0
00260 int offsetX = 0, offsetY = 0, widthX = 0, heightY = 0;
00261
00262 pPainter.translate(marginX, marginY);
00263
00264
00265 pPainter.setClipRect(marginX, marginY,
00266 width, metrics.height() - marginY * 2);
00267
00268
00269 int numPagesX = (int)ceil((double)rect.width()/(double)width);
00270 int numPagesY = (int)ceil((double)rect.height()/(double)height);
00271 int page = 0;
00272
00273
00274 for (int pageY = 0; pageY < numPagesY; ++pageY) {
00275
00276 offsetY = pageY * height + rect.y();
00277 heightY = (pageY + 1) * height > rect.height()
00278 ? rect.height() - pageY * height
00279 : height;
00280 for (int pageX = 0; pageX < numPagesX; ++pageX) {
00281
00282 offsetX = pageX * width + rect.x();
00283 widthX = (pageX + 1) * width > rect.width()
00284 ? rect.width() - pageX * width
00285 : width;
00286
00287
00288
00289 pPainter.translate(-offsetX,-offsetY);
00290 getDiagram(QRect(offsetX, offsetY,widthX, heightY),
00291 pPainter);
00292
00293
00294 pPainter.translate(offsetX,offsetY);
00295
00296
00297 QString string = i18n("Diagram: %2 Page %1").arg(page + 1).arg(getName());
00298 QColor textColor(50, 50, 50);
00299 pPainter.setPen(textColor);
00300 pPainter.drawLine(0, height + 2, width, height + 2);
00301 pPainter.drawText(0, height + 4, width, fontHeight, Qt::AlignLeft, string);
00302
00303 if(pageX+1 < numPagesX || pageY+1 < numPagesY) {
00304 pPrinter -> newPage();
00305 page++;
00306 }
00307 }
00308 }
00309 #else
00310
00311 pPainter.save();
00312
00313 int diagramHeight = rect.height();
00314
00315
00316
00317
00318
00319
00320 int footHeight = (2*fontHeight) + 7;
00321 int footTop = rect.y() + diagramHeight + 4+fontHeight;
00322 int drawHeight = diagramHeight + footHeight;
00323
00324
00325
00326 double dScaleX = (double)rect.width()/ (double)width;
00327 double dScaleY = (double)drawHeight/ (double)height;
00328
00329
00330
00331
00332 double dScaleUse = ( dScaleX > dScaleY )?dScaleX:dScaleY;
00333
00334 int windowWidth = (int)ceil(dScaleUse*width);
00335 int windowHeight = (int)ceil(dScaleUse*height);
00336 #ifdef DEBUG_PRINTING
00337 kDebug() << "drawHeight: " << drawHeight << ", width: " << rect.width()
00338 << "\nPageHeight: " << height << ", PageWidht: " << width
00339 << "\nScaleY: " << dScaleY << ", ScaleX: " << dScaleX
00340 << "\ndScaleUse: " << dScaleUse
00341 << "\nVirtualSize: Width: " << windowWidth << ", Height: " << windowHeight
00342 << "\nFoot Top: " << footTop
00343 << endl;
00344 #endif
00345
00346 pPainter.setWindow( rect.x(), rect.y(), windowWidth, windowHeight );
00347
00348
00349
00350
00351 pPainter.setViewport( left, top, width, height );
00352
00353
00354 getDiagram(QRect(rect.x(), rect.y(), windowWidth, diagramHeight), pPainter);
00355
00356
00357 QString string = i18n("Diagram: %2 Page %1").arg( 1).arg(getName());
00358 QColor textColor(50, 50, 50);
00359 pPainter.setPen(textColor);
00360 pPainter.drawLine(rect.x(), footTop , windowWidth, footTop);
00361 pPainter.drawText(rect.x(), footTop + 3, windowWidth, fontHeight, Qt::AlignLeft, string);
00362
00363
00364 pPainter.restore();
00365
00366 #endif
00367
00368 forceUpdateWidgetFontMetrics(0);
00369 }
00370
00371 void UMLView::setupNewWidget(UMLWidget *w) {
00372 w->setX( m_Pos.x() );
00373 w->setY( m_Pos.y() );
00374 w->setVisible( true );
00375 w->setActivated();
00376 w->setFont( getFont() );
00377 w->slotColorChanged( getID() );
00378 w->slotLineWidthChanged( getID() );
00379 resizeCanvasToItems();
00380 m_WidgetList.append( w );
00381 m_pDoc->setModified();
00382 }
00383
00384 void UMLView::contentsMouseReleaseEvent(QMouseEvent* ome) {
00385 m_pToolBarState->mouseRelease(ome);
00386 }
00387
00388 void UMLView::slotToolBarChanged(int c) {
00389 m_pToolBarState->cleanBeforeChange();
00390 m_pToolBarState = m_pToolBarStateFactory->getState((WorkToolBar::ToolBar_Buttons)c);
00391 m_pToolBarState->init();
00392
00393 m_bPaste = false;
00394 }
00395
00396 void UMLView::showEvent(QShowEvent* ) {
00397
00398 # ifdef MANUAL_CONTROL_DOUBLE_BUFFERING
00399
00400 canvas()->setDoubleBuffering( true );
00401
00402
00403
00404 canvas()-> setUpdatePeriod( 20 );
00405 # endif
00406
00407 UMLApp* theApp = UMLApp::app();
00408 WorkToolBar* tb = theApp->getWorkToolBar();
00409 connect(tb,SIGNAL(sigButtonChanged(int)), this, SLOT(slotToolBarChanged(int)));
00410 connect(this,SIGNAL(sigResetToolBar()), tb, SLOT(slotResetToolBar()));
00411 connect(m_pDoc, SIGNAL(sigObjectCreated(UMLObject *)),
00412 this, SLOT(slotObjectCreated(UMLObject *)));
00413 connect(this, SIGNAL(sigAssociationRemoved(AssociationWidget*)),
00414 UMLApp::app()->getDocWindow(), SLOT(slotAssociationRemoved(AssociationWidget*)));
00415 connect(this, SIGNAL(sigWidgetRemoved(UMLWidget*)),
00416 UMLApp::app()->getDocWindow(), SLOT(slotWidgetRemoved(UMLWidget*)));
00417 resetToolbar();
00418
00419 }
00420
00421 void UMLView::hideEvent(QHideEvent* ) {
00422 UMLApp* theApp = UMLApp::app();
00423 WorkToolBar* tb = theApp->getWorkToolBar();
00424 disconnect(tb,SIGNAL(sigButtonChanged(int)), this, SLOT(slotToolBarChanged(int)));
00425 disconnect(this,SIGNAL(sigResetToolBar()), tb, SLOT(slotResetToolBar()));
00426 disconnect(m_pDoc, SIGNAL(sigObjectCreated(UMLObject *)), this, SLOT(slotObjectCreated(UMLObject *)));
00427 disconnect(this, SIGNAL(sigAssociationRemoved(AssociationWidget*)),
00428 UMLApp::app()->getDocWindow(), SLOT(slotAssociationRemoved(AssociationWidget*)));
00429 disconnect(this, SIGNAL(sigWidgetRemoved(UMLWidget*)),
00430 UMLApp::app()->getDocWindow(), SLOT(slotWidgetRemoved(UMLWidget*)));
00431
00432 # ifdef MANUAL_CONTROL_DOUBLE_BUFFERING
00433
00434 canvas()->setDoubleBuffering( false );
00435
00436
00437
00438
00439 canvas()-> setUpdatePeriod( -1 );
00440 # endif
00441 }
00442
00443 void UMLView::slotObjectCreated(UMLObject* o) {
00444 m_bPaste = false;
00445
00446
00447 if (!m_bCreateObject) {
00448 return;
00449 }
00450
00451 UMLWidget* newWidget = Widget_Factory::createWidget(this, o);
00452 if (newWidget == NULL)
00453 return;
00454 newWidget->setVisible( true );
00455 newWidget->setActivated();
00456 newWidget->setFont( getFont() );
00457 newWidget->slotColorChanged( getID() );
00458 newWidget->slotLineWidthChanged( getID() );
00459 newWidget->updateComponentSize();
00460 if (m_Type == Uml::dt_Sequence) {
00461
00462
00463 ObjectWidget *ow = dynamic_cast<ObjectWidget*>(newWidget);
00464 if (ow)
00465 ow->moveEvent(NULL);
00466 }
00467 m_bCreateObject = false;
00468 m_WidgetList.append(newWidget);
00469 switch (o->getBaseType()) {
00470 case ot_Actor:
00471 case ot_UseCase:
00472 case ot_Class:
00473 case ot_Package:
00474 case ot_Component:
00475 case ot_Node:
00476 case ot_Artifact:
00477 case ot_Interface:
00478 case ot_Enum:
00479 case ot_Entity:
00480 case ot_Datatype:
00481 createAutoAssociations(newWidget);
00482
00483
00484
00485 for (UMLWidgetListIt it(m_WidgetList); it.current(); ++it) {
00486 UMLWidget *w = it.current();
00487 if (w != newWidget)
00488 createAutoAttributeAssociations(w);
00489 }
00490 break;
00491 default:
00492 break;
00493 }
00494 resizeCanvasToItems();
00495 }
00496
00497 void UMLView::slotObjectRemoved(UMLObject * o) {
00498 m_bPaste = false;
00499 Uml::IDType id = o->getID();
00500 UMLWidgetListIt it( m_WidgetList );
00501 UMLWidget *obj;
00502
00503 while ((obj = it.current()) != 0 ) {
00504 ++it;
00505 if(obj -> getID() != id)
00506 continue;
00507 removeWidget(obj);
00508 }
00509 }
00510
00511 void UMLView::contentsDragEnterEvent(QDragEnterEvent *e) {
00512 UMLDrag::LvTypeAndID_List tidList;
00513 if(!UMLDrag::getClip3TypeAndID(e, tidList)) {
00514 return;
00515 }
00516 UMLDrag::LvTypeAndID_It tidIt(tidList);
00517 UMLDrag::LvTypeAndID * tid = tidIt.current();
00518 if (!tid) {
00519 kDebug() << "UMLView::contentsDragEnterEvent: "
00520 << "UMLDrag::getClip3TypeAndID returned empty list" << endl;
00521 return;
00522 }
00523 ListView_Type lvtype = tid->type;
00524 Uml::IDType id = tid->id;
00525
00526 Diagram_Type diagramType = getType();
00527
00528 UMLObject* temp = 0;
00529
00530 if (Model_Utils::typeIsDiagram(lvtype)) {
00531 e->accept(true);
00532 return;
00533 }
00534
00535 if( diagramType == dt_State || diagramType == dt_Activity) {
00536 e->accept(false);
00537 return;
00538 }
00539
00540 if( !(temp = m_pDoc->findObjectById(id) ) ) {
00541 kDebug() << "object " << ID2STR(id) << " not found" << endl;
00542 e->accept(false);
00543 return;
00544 }
00545
00546
00547
00548 Object_Type ot = temp->getBaseType();
00549 bool bAccept = true;
00550 switch (diagramType) {
00551 case dt_UseCase:
00552 if ((widgetOnDiagram(id) && ot == ot_Actor) ||
00553 (ot != ot_Actor && ot != ot_UseCase))
00554 bAccept = false;
00555 break;
00556 case dt_Class:
00557 if (widgetOnDiagram(id) ||
00558 (ot != ot_Class &&
00559 ot != ot_Package &&
00560 ot != ot_Interface &&
00561 ot != ot_Enum &&
00562 ot != ot_Datatype)) {
00563 bAccept = false;
00564 }
00565 break;
00566 case dt_Sequence:
00567 case dt_Collaboration:
00568 if (ot != ot_Class &&
00569 ot != ot_Interface &&
00570 ot != ot_Actor)
00571 bAccept = false;
00572 break;
00573 case dt_Deployment:
00574 if (widgetOnDiagram(id))
00575 bAccept = false;
00576 else if (ot != ot_Interface &&
00577 ot != ot_Package &&
00578 ot != ot_Component &&
00579 ot != ot_Class &&
00580 ot != ot_Node)
00581 bAccept = false;
00582 else if (ot == ot_Package &&
00583 temp->getStereotype() != "subsystem")
00584 bAccept = false;
00585 break;
00586 case dt_Component:
00587 if (widgetOnDiagram(id) ||
00588 (ot != ot_Interface &&
00589 ot != ot_Package &&
00590 ot != ot_Component &&
00591 ot != ot_Artifact &&
00592 ot != ot_Class))
00593 bAccept = false;
00594 if (ot == ot_Class && !temp->getAbstract())
00595 bAccept = false;
00596 break;
00597 case dt_EntityRelationship:
00598 if (ot != ot_Entity)
00599 bAccept = false;
00600 break;
00601 default:
00602 break;
00603 }
00604 e->accept(bAccept);
00605 }
00606
00607 void UMLView::contentsDropEvent(QDropEvent *e) {
00608 UMLDrag::LvTypeAndID_List tidList;
00609 if( !UMLDrag::getClip3TypeAndID(e, tidList) ) {
00610 return;
00611 }
00612 UMLDrag::LvTypeAndID_It tidIt(tidList);
00613 UMLDrag::LvTypeAndID * tid = tidIt.current();
00614 if (!tid) {
00615 kDebug() << "UMLView::contentsDropEvent: "
00616 << "UMLDrag::getClip3TypeAndID returned empty list" << endl;
00617 return;
00618 }
00619 ListView_Type lvtype = tid->type;
00620 Uml::IDType id = tid->id;
00621
00622 if (Model_Utils::typeIsDiagram(lvtype)) {
00623 UMLWidget *w = NULL;
00624 for (w = m_WidgetList.first(); w; w = m_WidgetList.next()) {
00625 if (w->getBaseType() == Uml::wt_Note && w->onWidget(e->pos()))
00626 break;
00627 }
00628 if (w) {
00629 NoteWidget *note = static_cast<NoteWidget*>(w);
00630 note->setDiagramLink(id);
00631 }
00632 return;
00633 }
00634 UMLObject* o = m_pDoc->findObjectById(id);
00635 if( !o ) {
00636 kDebug() << "UMLView::contentsDropEvent: object id=" << ID2STR(id)
00637 << " not found" << endl;
00638 return;
00639 }
00640 m_bCreateObject = true;
00641 m_Pos = (e->pos() * 100 ) / m_nZoom;
00642
00643 slotObjectCreated(o);
00644
00645 m_pDoc -> setModified(true);
00646 }
00647
00648 ObjectWidget * UMLView::onWidgetLine( const QPoint &point ) {
00649 UMLWidget *obj;
00650 for (UMLWidgetListIt it(m_WidgetList); (obj = it.current()) != NULL; ++it) {
00651 ObjectWidget *ow = dynamic_cast<ObjectWidget*>(obj);
00652 if (ow == NULL)
00653 continue;
00654 SeqLineWidget *pLine = ow->getSeqLine();
00655 if (pLine == NULL) {
00656 kError() << "UMLView::onWidgetLine: SeqLineWidget of " << ow->getName()
00657 << " (id=" << ID2STR(ow->getLocalID()) << ") is NULL" << endl;
00658 continue;
00659 }
00660 if (pLine->onWidget(point))
00661 return ow;
00662 }
00663 return 0;
00664 }
00665
00666 UMLWidget *UMLView::getWidgetAt(QPoint p) {
00667 int relativeSize = 10000;
00668 UMLWidget *obj, *retObj = NULL;
00669 UMLWidgetListIt it(m_WidgetList);
00670 for (UMLWidgetListIt it(m_WidgetList); (obj = it.current()) != NULL; ++it) {
00671 const int s = obj->onWidget(p);
00672 if (!s)
00673 continue;
00674 if (s < relativeSize) {
00675 relativeSize = s;
00676 retObj = obj;
00677 }
00678 }
00679 return retObj;
00680 }
00681
00682 void UMLView::checkMessages(ObjectWidget * w) {
00683 if(getType() != dt_Sequence)
00684 return;
00685
00686 MessageWidgetListIt it( m_MessageList );
00687 MessageWidget *obj;
00688 while ( (obj = it.current()) != 0 ) {
00689 ++it;
00690 if(! obj -> contains(w))
00691 continue;
00692
00693 removeAssociations(obj);
00694 obj -> cleanup();
00695
00696 m_SelectedList.remove(obj);
00697 m_MessageList.remove(obj);
00698 delete obj;
00699 }
00700 }
00701
00702 bool UMLView::widgetOnDiagram(Uml::IDType id) {
00703 UMLWidget *obj;
00704
00705 UMLWidgetListIt it( m_WidgetList );
00706 while ( (obj = it.current()) != 0 ) {
00707 ++it;
00708 if(id == obj -> getID())
00709 return true;
00710 }
00711
00712 MessageWidgetListIt mit( m_MessageList );
00713 while ( (obj = (UMLWidget*)mit.current()) != 0 ) {
00714 ++mit;
00715 if(id == obj -> getID())
00716 return true;
00717 }
00718
00719 return false;
00720 }
00721
00722 void UMLView::contentsMouseMoveEvent(QMouseEvent* ome) {
00723 m_pToolBarState->mouseMove(ome);
00724 }
00725
00726
00727 UMLWidget * UMLView::findWidget( Uml::IDType id ) {
00728
00729 UMLWidgetListIt it( m_WidgetList );
00730 UMLWidget * obj = NULL;
00731 while ( (obj = it.current()) != 0 ) {
00732 ++it;
00733
00734 if( obj -> getBaseType() == wt_Object ) {
00735 if( static_cast<ObjectWidget *>( obj ) -> getLocalID() == id )
00736 return obj;
00737 } else if( obj -> getID() == id ) {
00738 return obj;
00739 }
00740 }
00741
00742 MessageWidgetListIt mit( m_MessageList );
00743 while ( (obj = (UMLWidget*)mit.current()) != 0 ) {
00744 ++mit;
00745 if( obj -> getID() == id )
00746 return obj;
00747 }
00748
00749 return 0;
00750 }
00751
00752
00753
00754 AssociationWidget * UMLView::findAssocWidget( Uml::IDType id ) {
00755 AssociationWidget *obj;
00756 AssociationWidgetListIt it( m_AssociationList );
00757 while ( (obj = it.current()) != 0 ) {
00758 ++it;
00759 UMLAssociation* umlassoc = obj -> getAssociation();
00760 if ( umlassoc && umlassoc->getID() == id ) {
00761 return obj;
00762 }
00763 }
00764 return 0;
00765 }
00766
00767 AssociationWidget * UMLView::findAssocWidget(UMLWidget *pWidgetA,
00768 UMLWidget *pWidgetB, const QString& roleNameB) {
00769 AssociationWidget *assoc;
00770 AssociationWidgetListIt it(m_AssociationList);
00771 while ((assoc = it.current()) != 0) {
00772 ++it;
00773 const Association_Type testType = assoc->getAssocType();
00774 if (testType != Uml::at_Association &&
00775 testType != Uml::at_UniAssociation &&
00776 testType != Uml::at_Composition &&
00777 testType != Uml::at_Aggregation)
00778 continue;
00779 if (pWidgetA->getID() == assoc->getWidgetID(A) &&
00780 pWidgetB->getID() == assoc->getWidgetID(B) &&
00781 assoc->getRoleName(Uml::B) == roleNameB)
00782 return assoc;
00783 }
00784 return 0;
00785 }
00786
00787
00788 AssociationWidget * UMLView::findAssocWidget(Association_Type at,
00789 UMLWidget *pWidgetA, UMLWidget *pWidgetB) {
00790 AssociationWidget *assoc;
00791 AssociationWidgetListIt it(m_AssociationList);
00792 while ((assoc = it.current()) != 0) {
00793 ++it;
00794 Association_Type testType = assoc->getAssocType();
00795 if (testType != at)
00796 continue;
00797 if (pWidgetA->getID() == assoc->getWidgetID(A) &&
00798 pWidgetB->getID() == assoc->getWidgetID(B))
00799 return assoc;
00800 }
00801 return 0;
00802 }
00803
00804 void UMLView::removeWidget(UMLWidget * o) {
00805 if(!o)
00806 return;
00807
00808 emit sigWidgetRemoved(o);
00809
00810 removeAssociations(o);
00811
00812 Widget_Type t = o->getBaseType();
00813 if(getType() == dt_Sequence && t == wt_Object)
00814 checkMessages( static_cast<ObjectWidget*>(o) );
00815
00816 o -> cleanup();
00817 m_SelectedList.remove(o);
00818 disconnect( this, SIGNAL( sigRemovePopupMenu() ), o, SLOT( slotRemovePopupMenu() ) );
00819 disconnect( this, SIGNAL( sigClearAllSelected() ), o, SLOT( slotClearAllSelected() ) );
00820 disconnect( this, SIGNAL(sigColorChanged(Uml::IDType)), o, SLOT(slotColorChanged(Uml::IDType)));
00821 if (t == wt_Message)
00822 m_MessageList.remove(static_cast<MessageWidget*>(o));
00823 else
00824 m_WidgetList.remove(o);
00825 m_pDoc->setModified();
00826 delete o;
00827 }
00828
00829 bool UMLView::getUseFillColor() const {
00830 return m_Options.uiState.useFillColor;
00831 }
00832
00833 void UMLView::setUseFillColor(bool ufc) {
00834 m_Options.uiState.useFillColor = ufc;
00835 }
00836
00837 QColor UMLView::getFillColor() const {
00838 return m_Options.uiState.fillColor;
00839 }
00840
00841 void UMLView::setFillColor(const QColor &color) {
00842 m_Options.uiState.fillColor = color;
00843 emit sigColorChanged( getID() );
00844 canvas()->setAllChanged();
00845 }
00846
00847 QColor UMLView::getLineColor() const {
00848 return m_Options.uiState.lineColor;
00849 }
00850
00851 void UMLView::setLineColor(const QColor &color) {
00852 m_Options.uiState.lineColor = color;
00853 emit sigColorChanged( getID() );
00854 canvas() -> setAllChanged();
00855 }
00856
00857 uint UMLView::getLineWidth() const {
00858 return m_Options.uiState.lineWidth;
00859 }
00860
00861 void UMLView::setLineWidth(uint width) {
00862 m_Options.uiState.lineWidth = width;
00863 emit sigLineWidthChanged( getID() );
00864 canvas() -> setAllChanged();
00865 }
00866
00867 void UMLView::contentsMouseDoubleClickEvent(QMouseEvent* ome) {
00868 m_pToolBarState->mouseDoubleClick(ome);
00869 }
00870
00871 QRect UMLView::getDiagramRect() {
00872 int startx, starty, endx, endy;
00873 startx = starty = INT_MAX;
00874 endx = endy = 0;
00875 UMLWidgetListIt it( m_WidgetList );
00876 UMLWidget *obj;
00877 while ( (obj = it.current()) != 0 ) {
00878 ++it;
00879 if (! obj->isVisible())
00880 continue;
00881 int objEndX = obj -> getX() + obj -> getWidth();
00882 int objEndY = obj -> getY() + obj -> getHeight();
00883 int objStartX = obj -> getX();
00884 int objStartY = obj -> getY();
00885 if (startx >= objStartX)
00886 startx = objStartX;
00887 if (starty >= objStartY)
00888 starty = objStartY;
00889 if(endx <= objEndX)
00890 endx = objEndX;
00891 if(endy <= objEndY)
00892 endy = objEndY;
00893 }
00894
00895 if (getType() == dt_Sequence ) {
00896 for (UMLWidgetListIt it(m_WidgetList); (obj = it.current()) != NULL; ++it) {
00897 ObjectWidget *ow = dynamic_cast<ObjectWidget*>(obj);
00898 if (ow == NULL)
00899 continue;
00900 int y = ow->getEndLineY();
00901 if (endy < y)
00902 endy = y;
00903 }
00904 }
00905
00906
00907
00908 AssociationWidgetListIt assoc_it (m_AssociationList);
00909 AssociationWidget * assoc_obj;
00910 QRect rect;
00911
00912 while ((assoc_obj = assoc_it.current()) != 0)
00913 {
00914
00915 rect = assoc_obj->getAssocLineRectangle();
00916
00917 if (startx >= rect.x())
00918 startx = rect.x();
00919 if (starty >= rect.y())
00920 starty = rect.y();
00921 if (endx <= rect.x() + rect.width())
00922 endx = rect.x() + rect.width();
00923 if (endy <= rect.y() + rect.height())
00924 endy = rect.y() + rect.height();
00925 ++assoc_it;
00926 }
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936 return QRect(startx, starty, endx - startx, endy - starty);
00937 }
00938
00939 void UMLView::setSelected(UMLWidget * w, QMouseEvent * ) {
00940
00941 if(!m_SelectedList.remove(w))
00942 m_SelectedList.append(w);
00943 int count = m_SelectedList.count();
00944
00945
00946
00947 if( count == 2 )
00948 updateDocumentation( true );
00949
00950
00951
00952 UMLApp::app()->slotCopyChanged();
00953 }
00954
00955 void UMLView::clearSelected() {
00956 m_SelectedList.clear();
00957 emit sigClearAllSelected();
00958
00959 }
00960
00961
00962 void UMLView::moveSelectedBy(int dX, int dY) {
00963 for (UMLWidget *w = m_SelectedList.first(); w; w = m_SelectedList.next())
00964 w->moveBy(dX, dY);
00965 }
00966
00967 void UMLView::selectionUseFillColor(bool useFC) {
00968 UMLWidget * temp = 0;
00969 for(temp=(UMLWidget *)m_SelectedList.first();temp;temp=(UMLWidget *)m_SelectedList.next())
00970 temp -> setUseFillColour(useFC);
00971 }
00972
00973 void UMLView::selectionSetFont( const QFont &font )
00974 {
00975 UMLWidget * temp = 0;
00976 for(temp=(UMLWidget *)m_SelectedList.first();temp;temp=(UMLWidget *)m_SelectedList.next())
00977 temp -> setFont( font );
00978 }
00979
00980 void UMLView::selectionSetLineColor( const QColor &color )
00981 {
00982 UMLWidget * temp = 0;
00983 for (temp = m_SelectedList.first(); temp; temp = m_SelectedList.next()) {
00984 temp->setLineColor(color);
00985 temp->setUsesDiagramLineColour(false);
00986 }
00987 AssociationWidgetList assoclist = getSelectedAssocs();
00988 for (AssociationWidget *aw = assoclist.first(); aw; aw = assoclist.next()) {
00989 aw->setLineColor(color);
00990 aw->setUsesDiagramLineColour(false);
00991 }
00992 }
00993
00994 void UMLView::selectionSetLineWidth( uint width )
00995 {
00996 UMLWidget * temp = 0;
00997 for (temp = m_SelectedList.first(); temp; temp = m_SelectedList.next()) {
00998 temp->setLineWidth(width);
00999 temp->setUsesDiagramLineWidth(false);
01000 }
01001 AssociationWidgetList assoclist = getSelectedAssocs();
01002 for (AssociationWidget *aw = assoclist.first(); aw; aw = assoclist.next()) {
01003 aw->setLineWidth(width);
01004 aw->setUsesDiagramLineWidth(false);
01005 }
01006 }
01007
01008 void UMLView::selectionSetFillColor( const QColor &color )
01009 {
01010 UMLWidget * temp = 0;
01011 for(temp=(UMLWidget *) m_SelectedList.first();
01012 temp;
01013 temp=(UMLWidget *)m_SelectedList.next()) {
01014 temp -> setFillColour( color );
01015 temp -> setUsesDiagramFillColour(false);
01016 }
01017 }
01018
01019 void UMLView::selectionToggleShow(int sel)
01020 {
01021
01022 for(UMLWidget *temp = (UMLWidget *)m_SelectedList.first();
01023 temp; temp=(UMLWidget *)m_SelectedList.next()) {
01024 Widget_Type type = temp->getBaseType();
01025 ClassifierWidget *cw = dynamic_cast<ClassifierWidget*>(temp);
01026
01027
01028 switch (sel)
01029 {
01030
01031
01032 case ListPopupMenu::mt_Show_Attributes_Selection:
01033 if (type == wt_Class)
01034 cw -> toggleShowAtts();
01035 break;
01036 case ListPopupMenu::mt_Show_Operations_Selection:
01037 if (cw)
01038 cw -> toggleShowOps();
01039 break;
01040 case ListPopupMenu::mt_Visibility_Selection:
01041 if (cw)
01042 cw -> toggleShowVisibility();
01043 break;
01044 case ListPopupMenu::mt_DrawAsCircle_Selection:
01045 if (type == wt_Interface)
01046 cw -> toggleDrawAsCircle();
01047 break;
01048 case ListPopupMenu::mt_Show_Operation_Signature_Selection:
01049 if (cw)
01050 cw -> toggleShowOpSigs();
01051 break;
01052 case ListPopupMenu::mt_Show_Attribute_Signature_Selection:
01053 if (type == wt_Class)
01054 cw -> toggleShowAttSigs();
01055 break;
01056 case ListPopupMenu::mt_Show_Packages_Selection:
01057 if (cw)
01058 cw -> toggleShowPackage();
01059 break;
01060 case ListPopupMenu::mt_Show_Stereotypes_Selection:
01061 if (type == wt_Class)
01062 cw -> toggleShowStereotype();
01063 break;
01064 case ListPopupMenu::mt_Show_Public_Only_Selection:
01065 if (cw)
01066 cw -> toggleShowPublicOnly();
01067 break;
01068 default:
01069 break;
01070 }
01071 }
01072 }
01073
01074 void UMLView::deleteSelection()
01075 {
01076
01077
01078
01079
01080 UMLWidget * temp = 0;
01081 for(temp=(UMLWidget *) m_SelectedList.first();
01082 temp;
01083 temp=(UMLWidget *)m_SelectedList.next())
01084 {
01085 if( temp -> getBaseType() == wt_Text &&
01086 ((FloatingTextWidget *)temp) -> getRole() != tr_Floating )
01087 {
01088 m_SelectedList.remove();
01089 m_SelectedList.prev();
01090 temp -> hide();
01091 } else {
01092 removeWidget(temp);
01093 }
01094 }
01095
01096
01097 AssociationWidgetListIt assoc_it( m_AssociationList );
01098 AssociationWidget* assocwidget = 0;
01099 while((assocwidget=assoc_it.current())) {
01100 ++assoc_it;
01101 if( assocwidget-> getSelected() )
01102 removeAssoc(assocwidget);
01103
01104 }
01105
01106
01107 MessageWidget * cur_msgWgt;
01108
01109
01110 for (cur_msgWgt = m_MessageList.first(); cur_msgWgt;
01111 cur_msgWgt = m_MessageList.next())
01112 {
01113 if (cur_msgWgt->getSelected() == true)
01114 {
01115 removeWidget(cur_msgWgt);
01116 }
01117 }
01118
01119
01120
01121 if (m_SelectedList.count() != 0)
01122 deleteSelection();
01123
01124
01125 m_SelectedList.clear();
01126 }
01127
01128 void UMLView::selectAll()
01129 {
01130 selectWidgets(0, 0, canvas()->width(), canvas()->height());
01131 }
01132
01133 Uml::IDType UMLView::getLocalID() {
01134 m_nLocalID = UniqueID::gen();
01135 return m_nLocalID;
01136 }
01137
01138 bool UMLView::isSavedInSeparateFile() {
01139 if (getOptionState().generalState.tabdiagrams) {
01140
01141
01142 return false;
01143 }
01144 const QString msgPrefix("UMLView::isSavedInSeparateFile(" + getName() + "): ");
01145 UMLListView *listView = UMLApp::app()->getListView();
01146 UMLListViewItem *lvItem = listView->findItem(m_nID);
01147 if (lvItem == NULL) {
01148 kError() << msgPrefix
01149 << "listView->findUMLObject(this) returns false" << endl;
01150 return false;
01151 }
01152 UMLListViewItem *parentItem = dynamic_cast<UMLListViewItem*>( lvItem->parent() );
01153 if (parentItem == NULL) {
01154 kError() << msgPrefix
01155 << "parent item in listview is not a UMLListViewItem (?)" << endl;
01156 return false;
01157 }
01158 const Uml::ListView_Type lvt = parentItem->getType();
01159 if (! Model_Utils::typeIsFolder(lvt))
01160 return false;
01161 UMLFolder *modelFolder = dynamic_cast<UMLFolder*>(parentItem->getUMLObject());
01162 if (modelFolder == NULL) {
01163 kError() << msgPrefix
01164 << "parent model object is not a UMLFolder (?)" << endl;
01165 return false;
01166 }
01167 QString folderFile = modelFolder->getFolderFile();
01168 return !folderFile.isEmpty();
01169 }
01170
01171 void UMLView::contentsMousePressEvent(QMouseEvent* ome) {
01172 m_pToolBarState->mousePress(ome);
01173
01174
01175
01176
01177
01178 if (!m_bChildDisplayedDoc) {
01179 UMLApp::app() -> getDocWindow() -> showDocumentation( this, true );
01180 }
01181 m_bChildDisplayedDoc = false;
01182 }
01183
01184 void UMLView::makeSelected (UMLWidget * uw) {
01185 if (uw == NULL)
01186 return;
01187 uw -> setSelected(true);
01188 m_SelectedList.remove(uw);
01189 m_SelectedList.append(uw);
01190 }
01191
01192 void UMLView::selectWidgetsOfAssoc (AssociationWidget * a) {
01193 if (!a)
01194 return;
01195 a -> setSelected(true);
01196
01197 makeSelected( a->getWidget(A) );
01198 makeSelected( a->getWidget(B) );
01199
01200 makeSelected( a->getMultiWidget(A) );
01201 makeSelected( a->getMultiWidget(B) );
01202 makeSelected( a->getRoleWidget(A) );
01203 makeSelected( a->getRoleWidget(B) );
01204 makeSelected( a->getChangeWidget(A) );
01205 makeSelected( a->getChangeWidget(B) );
01206 }
01207
01208 void UMLView::selectWidgets(int px, int py, int qx, int qy) {
01209 clearSelected();
01210
01211 QRect rect;
01212 if(px <= qx) {
01213 rect.setLeft(px);
01214 rect.setRight(qx);
01215 } else {
01216 rect.setLeft(qx);
01217 rect.setRight(px);
01218 }
01219 if(py <= qy) {
01220 rect.setTop(py);
01221 rect.setBottom(qy);
01222 } else {
01223 rect.setTop(qy);
01224 rect.setBottom(py);
01225 }
01226 UMLWidgetListIt it(m_WidgetList);
01227 UMLWidget * temp = NULL;
01228 while ( (temp = it.current()) != 0 ) {
01229 int x = temp -> getX();
01230 int y = temp -> getY();
01231 int w = temp -> getWidth();
01232 int h = temp -> getHeight();
01233 QRect rect2(x, y, w, h);
01234 ++it;
01235
01236 if( !rect.intersects(rect2) )
01237 continue;
01238
01239
01240 if (temp -> getBaseType() == wt_Text) {
01241 FloatingTextWidget *ft = static_cast<FloatingTextWidget*>(temp);
01242 Text_Role t = ft -> getRole();
01243 LinkWidget *lw = ft->getLink();
01244 MessageWidget * mw = dynamic_cast<MessageWidget*>(lw);
01245 if (mw) {
01246 makeSelected( mw );
01247 makeSelected( mw->getWidget(A) );
01248 makeSelected( mw->getWidget(B) );
01249 } else if (t != tr_Floating) {
01250 AssociationWidget * a = dynamic_cast<AssociationWidget*>(lw);
01251 if (a)
01252 selectWidgetsOfAssoc( a );
01253 }
01254 } else if(temp -> getBaseType() == wt_Message) {
01255 MessageWidget *mw = static_cast<MessageWidget*>(temp);
01256 makeSelected( mw -> getWidget(A) );
01257 makeSelected( mw -> getWidget(B) );
01258 }
01259 if(temp -> isVisible()) {
01260 makeSelected( temp );
01261 }
01262 }
01263 selectAssociations( true );
01264
01265
01266 MessageWidgetListIt itw( m_MessageList );
01267 MessageWidget *w = 0;
01268 while ( (w = itw.current()) != 0 ) {
01269 ++itw;
01270 if ( w -> getWidget(A) -> getSelected() &&
01271 w -> getWidget(B) -> getSelected() ) {
01272 makeSelected( w );
01273 }
01274 }
01275 }
01276
01277 void UMLView::getDiagram(const QRect &rect, QPixmap & diagram) {
01278 QPixmap pixmap(rect.x() + rect.width(), rect.y() + rect.height());
01279 QPainter painter(&pixmap);
01280 getDiagram(canvas()->rect(),painter);
01281 bitBlt(&diagram, QPoint(0, 0), &pixmap, rect);
01282 }
01283
01284 void UMLView::getDiagram(const QRect &area, QPainter & painter) {
01285
01286
01287
01288
01289 UMLWidget* widget = 0;
01290 for (widget=(UMLWidget*)m_SelectedList.first(); widget; widget=(UMLWidget*)m_SelectedList.next()) {
01291 widget->setSelected(false);
01292 }
01293 AssociationWidgetList selectedAssociationsList = getSelectedAssocs();
01294 AssociationWidget* association = 0;
01295 for (association=selectedAssociationsList.first(); association;
01296 association=selectedAssociationsList.next()) {
01297 association->setSelected(false);
01298 }
01299
01300
01301 bool showSnapGrid = getShowSnapGrid();
01302 setShowSnapGrid(false);
01303
01304 canvas()->drawArea(area, &painter);
01305
01306 setShowSnapGrid(showSnapGrid);
01307
01308 canvas()->setAllChanged();
01309
01310 for (widget=(UMLWidget *)m_SelectedList.first(); widget; widget=(UMLWidget *)m_SelectedList.next()) {
01311 widget->setSelected( true );
01312 }
01313 for (association=selectedAssociationsList.first(); association;
01314 association=selectedAssociationsList.next()) {
01315 association->setSelected(true);
01316 }
01317
01318 return;
01319 }
01320
01321 UMLViewImageExporter* UMLView::getImageExporter() {
01322 return m_pImageExporter;
01323 }
01324
01325 void UMLView::slotActivate() {
01326 m_pDoc->changeCurrentView(getID());
01327 }
01328
01329 UMLObjectList UMLView::getUMLObjects() {
01330 UMLObjectList list;
01331 for (UMLWidgetListIt it(m_WidgetList); it.current(); ++it) {
01332 UMLWidget *w = it.current();
01333 switch (w->getBaseType())
01334 {
01335 case wt_Actor:
01336 case wt_Class:
01337 case wt_Interface:
01338 case wt_Package:
01339 case wt_Component:
01340 case wt_Node:
01341 case wt_Artifact:
01342 case wt_UseCase:
01343 case wt_Object:
01344 list.append( w->getUMLObject() );
01345 break;
01346 default:
01347 break;
01348 }
01349 }
01350 return list;
01351 }
01352
01353 void UMLView::activate() {
01354 UMLWidgetListIt it( m_WidgetList );
01355 UMLWidget *obj;
01356
01357
01358 while ( (obj = it.current()) != 0 ) {
01359 ++it;
01360
01361 if(obj->isActivated() || obj->getBaseType() == wt_Message)
01362 continue;
01363
01364 if (obj->activate()) {
01365 obj->setVisible(true);
01366 } else {
01367 m_WidgetList.remove(obj);
01368 delete obj;
01369 }
01370 }
01371
01372 MessageWidgetListIt it2( m_MessageList );
01373
01374 while ( (obj = (UMLWidget*)it2.current()) != 0 ) {
01375 ++it2;
01376
01377 if(obj->isActivated())
01378 continue;
01379
01380 obj->activate(m_pDoc->getChangeLog());
01381 obj->setVisible( true );
01382
01383 }
01384
01385
01386 AssociationWidget *aw;
01387 for (AssociationWidgetListIt ait(m_AssociationList);
01388 (aw = ait.current()); ++ait) {
01389 if (aw->activate()) {
01390 if (m_PastePoint.x() != 0) {
01391 int x = m_PastePoint.x() - m_Pos.x();
01392 int y = m_PastePoint.y() - m_Pos.y();
01393 aw->moveEntireAssoc(x, y);
01394 }
01395 } else {
01396 m_AssociationList.remove(aw);
01397 }
01398 }
01399 }
01400
01401 int UMLView::getSelectCount(bool filterText) const {
01402 if (!filterText)
01403 return m_SelectedList.count();
01404 int counter = 0;
01405 const UMLWidget * temp = 0;
01406 for (UMLWidgetListIt iter(m_SelectedList); (temp = iter.current()) != 0; ++iter) {
01407 if (temp->getBaseType() == wt_Text) {
01408 const FloatingTextWidget *ft = static_cast<const FloatingTextWidget*>(temp);
01409 if (ft->getRole() == tr_Floating)
01410 counter++;
01411 } else {
01412 counter++;
01413 }
01414 }
01415 return counter;
01416 }
01417
01418
01419 bool UMLView::getSelectedWidgets(UMLWidgetList &WidgetList, bool filterText ) {
01420 const UMLWidget * temp = 0;
01421 for (UMLWidgetListIt it(m_SelectedList); (temp = it.current()) != NULL; ++it) {
01422 if (filterText && temp->getBaseType() == wt_Text) {
01423 const FloatingTextWidget *ft = static_cast<const FloatingTextWidget*>(temp);
01424 if (ft->getRole() == tr_Floating)
01425 WidgetList.append(temp);
01426 } else {
01427 WidgetList.append(temp);
01428 }
01429 }
01430 return true;
01431 }
01432
01433 AssociationWidgetList UMLView::getSelectedAssocs() {
01434 AssociationWidgetList assocWidgetList;
01435 AssociationWidgetListIt assoc_it( m_AssociationList );
01436 AssociationWidget* assocwidget = 0;
01437 while((assocwidget=assoc_it.current())) {
01438 ++assoc_it;
01439 if( assocwidget -> getSelected() )
01440 assocWidgetList.append(assocwidget);
01441 }
01442 return assocWidgetList;
01443 }
01444
01445 bool UMLView::addWidget( UMLWidget * pWidget , bool isPasteOperation ) {
01446 if( !pWidget ) {
01447 return false;
01448 }
01449 Widget_Type type = pWidget->getBaseType();
01450 if (isPasteOperation) {
01451 if (type == Uml::wt_Message)
01452 m_MessageList.append(static_cast<MessageWidget*>(pWidget));
01453 else
01454 m_WidgetList.append(pWidget);
01455 return true;
01456 }
01457 if (!isPasteOperation && findWidget(pWidget->getID())) {
01458 kError() << "UMLView::addWidget: Not adding "
01459 << "(id=" << ID2STR(pWidget->getID())
01460 << "/type=" << type << "/name=" << pWidget->getName()
01461 << ") because it's already there" << endl;
01462 return false;
01463 }
01464
01465 IDChangeLog * log = m_pDoc -> getChangeLog();
01466 if( isPasteOperation && (!log || !m_pIDChangesLog)) {
01467 kError()<<" Cant addWidget to view in paste op because a log is not open"<<endl;
01468 return false;
01469 }
01470 int wX = pWidget -> getX();
01471 int wY = pWidget -> getY();
01472 bool xIsOutOfRange = (wX <= 0 || wX >= FloatingTextWidget::restrictPositionMax);
01473 bool yIsOutOfRange = (wY <= 0 || wY >= FloatingTextWidget::restrictPositionMax);
01474 if (xIsOutOfRange || yIsOutOfRange) {
01475 QString name = pWidget->getName();
01476 if (name.isEmpty()) {
01477 FloatingTextWidget *ft = dynamic_cast<FloatingTextWidget*>(pWidget);
01478 if (ft)
01479 name = ft->getDisplayText();
01480 }
01481 kDebug() << "UMLView::addWidget (" << name << " type="
01482 << pWidget->getBaseType() << "): position (" << wX << ","
01483 << wY << ") is out of range" << endl;
01484 if (xIsOutOfRange) {
01485 pWidget->setX(0);
01486 wX = 0;
01487 }
01488 if (yIsOutOfRange) {
01489 pWidget->setY(0);
01490 wY = 0;
01491 }
01492 }
01493 if( wX < m_Pos.x() )
01494 m_Pos.setX( wX );
01495 if( wY < m_Pos.y() )
01496 m_Pos.setY( wY );
01497
01498
01499 switch( type ) {
01500
01501 case wt_Class:
01502 case wt_Package:
01503 case wt_Component:
01504 case wt_Node:
01505 case wt_Artifact:
01506 case wt_Interface:
01507 case wt_Enum:
01508 case wt_Entity:
01509 case wt_Datatype:
01510 case wt_Actor:
01511 case wt_UseCase:
01512 {
01513 Uml::IDType id = pWidget -> getID();
01514 Uml::IDType newID = log->findNewID( id );
01515 if( newID == Uml::id_None ) {
01516 if (id == Uml::id_None)
01517 return false;
01518 newID = id;
01519 } else
01520 pWidget -> setID( newID );
01521 UMLObject * pObject = m_pDoc -> findObjectById( newID );
01522 if( !pObject ) {
01523 kDebug() << "addWidget: Can't find UMLObject for id "
01524 << ID2STR(newID) << endl;
01525 return false;
01526 }
01527 pWidget -> setUMLObject( pObject );
01528
01529 if (findWidget(newID)) {
01530 kDebug() << "UMLView::addWidget: Not adding "
01531 << "(id=" << ID2STR(pWidget->getID())
01532 << "/type=" << pWidget->getBaseType()
01533 << "/name=" << pWidget->getName()
01534 << ") because it's already there" << endl;
01535 delete pWidget;
01536 return true;
01537 }
01538 m_WidgetList.append( pWidget );
01539 }
01540 break;
01541
01542 case wt_Message:
01543 case wt_Note:
01544 case wt_Box:
01545 case wt_Text:
01546 case wt_State:
01547 case wt_Activity:
01548 {
01549 Uml::IDType newID = m_pDoc->assignNewID( pWidget->getID() );
01550 pWidget->setID(newID);
01551 if (type != wt_Message) {
01552 m_WidgetList.append( pWidget );
01553 return true;
01554 }
01555
01556
01557 MessageWidget *pMessage = static_cast<MessageWidget *>( pWidget );
01558 if (pMessage == NULL) {
01559 kDebug() << "UMLView::addWidget(): pMessage is NULL" << endl;
01560 return false;
01561 }
01562 ObjectWidget *objWidgetA = pMessage -> getWidget(A);
01563 ObjectWidget *objWidgetB = pMessage -> getWidget(B);
01564 Uml::IDType waID = objWidgetA -> getLocalID();
01565 Uml::IDType wbID = objWidgetB -> getLocalID();
01566 Uml::IDType newWAID = m_pIDChangesLog ->findNewID( waID );
01567 Uml::IDType newWBID = m_pIDChangesLog ->findNewID( wbID );
01568 if( newWAID == Uml::id_None || newWBID == Uml::id_None ) {
01569 kDebug() << "Error with ids : " << ID2STR(newWAID)
01570 << " " << ID2STR(newWBID) << endl;
01571 return false;
01572 }
01573
01574
01575 objWidgetA -> setLocalID( newWAID );
01576 objWidgetB -> setLocalID( newWBID );
01577 FloatingTextWidget *ft = pMessage->getFloatingTextWidget();
01578 if (ft == NULL)
01579 kDebug() << "UMLView::addWidget: FloatingTextWidget of Message is NULL" << endl;
01580 else if (ft->getID() == Uml::id_None)
01581 ft->setID( UniqueID::gen() );
01582 else {
01583 Uml::IDType newTextID = m_pDoc->assignNewID( ft->getID() );
01584 ft->setID( newTextID );
01585 }
01586 m_MessageList.append( pMessage );
01587 }
01588 break;
01589
01590 case wt_Object:
01591 {
01592 ObjectWidget* pObjectWidget = static_cast<ObjectWidget*>(pWidget);
01593 if (pObjectWidget == NULL) {
01594 kDebug() << "UMLView::addWidget(): pObjectWidget is NULL" << endl;
01595 return false;
01596 }
01597 Uml::IDType nNewLocalID = getLocalID();
01598 Uml::IDType nOldLocalID = pObjectWidget -> getLocalID();
01599 m_pIDChangesLog->addIDChange( nOldLocalID, nNewLocalID );
01600 pObjectWidget -> setLocalID( nNewLocalID );
01601 UMLObject *pObject = m_pDoc->findObjectById(pWidget->getID());
01602 if( !pObject ) {
01603 kDebug() << "addWidget::Can't find UMLObject" << endl;
01604 return false;
01605 }
01606 pWidget -> setUMLObject( pObject );
01607 m_WidgetList.append( pWidget );
01608 }
01609 break;
01610
01611 default:
01612 kDebug() << "Trying to add an invalid widget type" << endl;
01613 return false;
01614 break;
01615 }
01616
01617 return true;
01618 }
01619
01620
01621 bool UMLView::addAssociation(AssociationWidget* pAssoc , bool isPasteOperation) {
01622
01623 if (!pAssoc) {
01624 return false;
01625 }
01626 const Association_Type type = pAssoc->getAssocType();
01627
01628 if( isPasteOperation )
01629 {
01630 IDChangeLog * log = m_pDoc -> getChangeLog();
01631
01632 if(!log )
01633 return false;
01634
01635 Uml::IDType ida = Uml::id_None, idb = Uml::id_None;
01636 if( getType() == dt_Collaboration || getType() == dt_Sequence ) {
01637
01638 ida = m_pIDChangesLog->findNewID( pAssoc->getWidgetID(A) );
01639 idb = m_pIDChangesLog->findNewID( pAssoc->getWidgetID(B) );
01640
01641
01642 if( ida == Uml::id_None && type == at_Anchor )
01643 ida = log->findNewID(pAssoc->getWidgetID(A));
01644 if( idb == Uml::id_None && type == at_Anchor )
01645 idb = log->findNewID(pAssoc->getWidgetID(B));
01646 } else {
01647 Uml::IDType oldIdA = pAssoc->getWidgetID(A);
01648 Uml::IDType oldIdB = pAssoc->getWidgetID(B);
01649 ida = log->findNewID( oldIdA );
01650 if (ida == Uml::id_None) {
01651 if (oldIdA == Uml::id_None)
01652 return false;
01653 ida = oldIdA;
01654 }
01655 idb = log->findNewID( oldIdB );
01656 if (idb == Uml::id_None) {
01657 if (oldIdB == Uml::id_None)
01658 return false;
01659 idb = oldIdB;
01660 }
01661 }
01662 if(ida == Uml::id_None || idb == Uml::id_None) {
01663 return false;
01664 }
01665
01666
01667
01668 pAssoc->setWidget(findWidget(ida), A);
01669 pAssoc->setWidget(findWidget(idb), B);
01670 }
01671
01672 UMLWidget * pWidgetA = findWidget(pAssoc->getWidgetID(A));
01673 UMLWidget * pWidgetB = findWidget(pAssoc->getWidgetID(B));
01674
01675 if (!pWidgetA || !pWidgetB) {
01676 return false;
01677 }
01678
01679
01680 if (!isPasteOperation && !m_pDoc->loading() &&
01681 !AssocRules::allowAssociation(type, pWidgetA, pWidgetB, false)) {
01682 kWarning() << "UMLView::addAssociation: allowAssociation returns false "
01683 << "for AssocType " << type << endl;
01684 return false;
01685 }
01686
01687
01688 AssociationWidgetListIt assoc_it( m_AssociationList );
01689 AssociationWidget* assocwidget = 0;
01690 while((assocwidget=assoc_it.current())) {
01691 ++assoc_it;
01692 if( *pAssoc == *assocwidget )
01693
01694
01695 return (isPasteOperation? true: false);
01696 }
01697
01698 m_AssociationList.append(pAssoc);
01699
01700 FloatingTextWidget *ft[5] = { pAssoc->getNameWidget(),
01701 pAssoc->getRoleWidget(A),
01702 pAssoc->getRoleWidget(B),
01703 pAssoc->getMultiWidget(A),
01704 pAssoc->getMultiWidget(B) };
01705 for (int i = 0; i < 5; i++) {
01706 FloatingTextWidget *flotxt = ft[i];
01707 if (flotxt) {
01708 flotxt->updateComponentSize();
01709 addWidget(flotxt);
01710 }
01711 }
01712
01713 return true;
01714 }
01715
01716 void UMLView::activateAfterLoad(bool bUseLog) {
01717 if (m_bActivated)
01718 return;
01719 if( bUseLog ) {
01720 beginPartialWidgetPaste();
01721 }
01722
01723
01724 activate();
01725
01726 if( bUseLog ) {
01727 endPartialWidgetPaste();
01728 }
01729 resizeCanvasToItems();
01730 setZoom( getZoom() );
01731 m_bActivated = true;
01732 }
01733
01734 void UMLView::beginPartialWidgetPaste() {
01735 delete m_pIDChangesLog;
01736 m_pIDChangesLog = 0;
01737
01738 m_pIDChangesLog = new IDChangeLog();
01739 m_bPaste = true;
01740 }
01741
01742 void UMLView::endPartialWidgetPaste() {
01743 delete m_pIDChangesLog;
01744 m_pIDChangesLog = 0;
01745
01746 m_bPaste = false;
01747 }
01748
01749 void UMLView::removeAssoc(AssociationWidget* pAssoc) {
01750 if(!pAssoc)
01751 return;
01752
01753 emit sigAssociationRemoved(pAssoc);
01754
01755 pAssoc->cleanup();
01756 m_AssociationList.remove(pAssoc);
01757 m_pDoc->setModified();
01758 }
01759
01760 void UMLView::removeAssocInViewAndDoc(AssociationWidget* a) {
01761
01762
01763
01764
01765 if(!a)
01766 return;
01767 if (a->getAssocType() == at_Containment) {
01768 UMLObject *objToBeMoved = a->getWidget(B)->getUMLObject();
01769 if (objToBeMoved != NULL) {
01770 UMLListView *lv = UMLApp::app()->getListView();
01771 lv->moveObject( objToBeMoved->getID(),
01772 Model_Utils::convert_OT_LVT(objToBeMoved),
01773 lv->theLogicalView() );
01774
01775
01776 } else {
01777 kDebug() << "removeAssocInViewAndDoc(containment): "
01778 << "objB is NULL" << endl;
01779 }
01780 } else {
01781
01782 m_pDoc->removeAssociation(a->getAssociation());
01783
01784 removeAssoc(a);
01785 }
01786 }
01787
01789 void UMLView::removeAssociations(UMLWidget* Widget) {
01790 AssociationWidgetListIt assoc_it(m_AssociationList);
01791 AssociationWidget* assocwidget = 0;
01792 while((assocwidget=assoc_it.current())) {
01793 ++assoc_it;
01794 if(assocwidget->contains(Widget)) {
01795 removeAssoc(assocwidget);
01796 }
01797 }
01798 }
01799
01800 void UMLView::selectAssociations(bool bSelect) {
01801 AssociationWidgetListIt assoc_it(m_AssociationList);
01802 AssociationWidget* assocwidget = 0;
01803 while((assocwidget=assoc_it.current())) {
01804 ++assoc_it;
01805 if(bSelect &&
01806 assocwidget->getWidget(A) && assocwidget->getWidget(A)->getSelected() &&
01807 assocwidget->getWidget(B) && assocwidget->getWidget(B)->getSelected() ) {
01808 assocwidget->setSelected(true);
01809 } else {
01810 assocwidget->setSelected(false);
01811 }
01812 }
01813 }
01814
01815 void UMLView::getWidgetAssocs(UMLObject* Obj, AssociationWidgetList & Associations) {
01816 if( ! Obj )
01817 return;
01818
01819 AssociationWidgetListIt assoc_it(m_AssociationList);
01820 AssociationWidget * assocwidget;
01821 while((assocwidget = assoc_it.current())) {
01822 if (assocwidget->getWidget(A)->getUMLObject() == Obj ||
01823 assocwidget->getWidget(B)->getUMLObject() == Obj)
01824 Associations.append(assocwidget);
01825 ++assoc_it;
01826 }
01827 }
01828
01829 void UMLView::closeEvent ( QCloseEvent * e ) {
01830 QWidget::closeEvent(e);
01831 }
01832
01833 void UMLView::removeAllAssociations() {
01834
01835 AssociationWidgetListIt assoc_it(m_AssociationList);
01836 AssociationWidget* assocwidget = 0;
01837 while((assocwidget=assoc_it.current()))
01838 {
01839 ++assoc_it;
01840 removeAssoc(assocwidget);
01841 }
01842 m_AssociationList.clear();
01843 }
01844
01845
01846 void UMLView::removeAllWidgets() {
01847
01848 UMLWidgetListIt it( m_WidgetList );
01849 UMLWidget * temp = 0;
01850 while ( (temp = it.current()) != 0 ) {
01851 ++it;
01852
01853
01854 if( !( temp -> getBaseType() == wt_Text &&
01855 ((FloatingTextWidget *)temp)-> getRole() != tr_Floating ) ) {
01856 removeWidget( temp );
01857 }
01858 }
01859 m_WidgetList.clear();
01860 }
01861
01862 void UMLView::showDocumentation( UMLObject * object, bool overwrite ) {
01863 UMLApp::app() -> getDocWindow() -> showDocumentation( object, overwrite );
01864 m_bChildDisplayedDoc = true;
01865 }
01866
01867 void UMLView::showDocumentation( UMLWidget * widget, bool overwrite ) {
01868 UMLApp::app() -> getDocWindow() -> showDocumentation( widget, overwrite );
01869 m_bChildDisplayedDoc = true;
01870 }
01871
01872 void UMLView::showDocumentation( AssociationWidget * widget, bool overwrite ) {
01873 UMLApp::app() -> getDocWindow() -> showDocumentation( widget, overwrite );
01874 m_bChildDisplayedDoc = true;
01875 }
01876
01877 void UMLView::updateDocumentation( bool clear ) {
01878 UMLApp::app() -> getDocWindow() -> updateDocumentation( clear );
01879 }
01880
01881 void UMLView::updateContainment(UMLCanvasObject *self) {
01882 if (self == NULL)
01883 return;
01884
01885
01886 UMLWidget *selfWidget = NULL, *newParentWidget = NULL;
01887 UMLPackage *newParent = self->getUMLPackage();
01888 for (UMLWidgetListIt wit(m_WidgetList); wit.current(); ++wit) {
01889 UMLWidget *w = wit.current();
01890 UMLObject *o = w->getUMLObject();
01891 if (o == self)
01892 selfWidget = w;
01893 else if (newParent != NULL && o == newParent)
01894 newParentWidget = w;
01895 }
01896 if (selfWidget == NULL)
01897 return;
01898
01899 for (AssociationWidgetListIt it(m_AssociationList); it.current(); ++it) {
01900 AssociationWidget *a = it.current();
01901 if (a->getAssocType() != Uml::at_Containment)
01902 continue;
01903
01904
01905 UMLWidget *wB = a->getWidget(B);
01906 UMLObject *roleBObj = wB->getUMLObject();
01907 if (roleBObj != self)
01908 continue;
01909 UMLWidget *wA = a->getWidget(A);
01910 UMLObject *roleAObj = wA->getUMLObject();
01911 if (roleAObj == newParent) {
01912
01913 return;
01914 }
01915 removeAssoc(a);
01916
01917
01918 break;
01919 }
01920 if (newParentWidget == NULL)
01921 return;
01922
01923 AssociationWidget *a = new AssociationWidget(this, newParentWidget,
01924 Uml::at_Containment, selfWidget);
01925 a->calculateEndingPoints();
01926 a->setActivated(true);
01927 m_AssociationList.append(a);
01928 }
01929
01930 void UMLView::createAutoAssociations( UMLWidget * widget ) {
01931 if (widget == NULL ||
01932 (m_Type != Uml::dt_Class &&
01933 m_Type != Uml::dt_Component &&
01934 m_Type != Uml::dt_Deployment &&
01935 m_Type != Uml::dt_EntityRelationship))
01936 return;
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964 UMLObject *tmpUmlObj = widget->getUMLObject();
01965 if (tmpUmlObj == NULL)
01966 return;
01967 UMLCanvasObject *umlObj = dynamic_cast<UMLCanvasObject*>(tmpUmlObj);
01968 if (umlObj == NULL)
01969 return;
01970 const UMLAssociationList& umlAssocs = umlObj->getAssociations();
01971 UMLAssociationListIt it(umlAssocs);
01972 UMLAssociation *assoc = NULL;
01973 Uml::IDType myID = umlObj->getID();
01974 while ((assoc = it.current()) != NULL) {
01975 ++it;
01976 UMLCanvasObject *other = NULL;
01977 UMLObject *roleAObj = assoc->getObject(A);
01978 if (roleAObj == NULL) {
01979 kDebug() << "createAutoAssociations: roleA object is NULL at UMLAssoc "
01980 << ID2STR(assoc->getID()) << endl;
01981 continue;
01982 }
01983 UMLObject *roleBObj = assoc->getObject(B);
01984 if (roleBObj == NULL) {
01985 kDebug() << "createAutoAssociations: roleB object is NULL at UMLAssoc "
01986 << ID2STR(assoc->getID()) << endl;
01987 continue;
01988 }
01989 if (roleAObj->getID() == myID) {
01990 other = static_cast<UMLCanvasObject*>(roleBObj);
01991 } else if (roleBObj->getID() == myID) {
01992 other = static_cast<UMLCanvasObject*>(roleAObj);
01993 } else {
01994 kDebug() << "createAutoAssociations: Can't find own object "
01995 << ID2STR(myID) << " in UMLAssoc "
01996 << ID2STR(assoc->getID()) << endl;
01997 continue;
01998 }
01999
02000
02001 Uml::IDType otherID = other->getID();
02002 UMLWidget *pOtherWidget;
02003 UMLWidgetListIt wit(m_WidgetList);
02004 while ((pOtherWidget = wit.current()) != NULL) {
02005 ++wit;
02006 if (pOtherWidget->getID() == otherID)
02007 break;
02008 }
02009 if (pOtherWidget == NULL)
02010 continue;
02011
02012
02013 UMLWidget *widgetA, *widgetB;
02014 if (myID == roleAObj->getID()) {
02015 widgetA = widget;
02016 widgetB = pOtherWidget;
02017 } else {
02018 widgetA = pOtherWidget;
02019 widgetB = widget;
02020 }
02021
02022 Uml::Association_Type assocType = assoc->getAssocType();
02023 AssociationWidget * assocwidget = findAssocWidget(assocType, widgetA, widgetB);
02024 if (assocwidget) {
02025 assocwidget->calculateEndingPoints();
02026 continue;
02027 }
02028
02029 if (!AssocRules::allowAssociation(assocType, widgetA, widgetB, false)) {
02030 kDebug() << "createAutoAssociations: not transferring assoc "
02031 << "of type " << assocType << endl;
02032 continue;
02033 }
02034
02035 assocwidget = new AssociationWidget( this );
02036 assocwidget->setWidget(widgetA, A);
02037 assocwidget->setWidget(widgetB, B);
02038 assocwidget->setAssocType(assocType);
02039 assocwidget->setUMLObject(assoc);
02040
02041
02042
02043 assocwidget->calculateEndingPoints();
02044 assocwidget->syncToModel();
02045 assocwidget->setActivated(true);
02046 if (! addAssociation(assocwidget))
02047 delete assocwidget;
02048 }
02049 createAutoAttributeAssociations(widget);
02050
02051 Uml::Object_Type t = umlObj->getBaseType();
02052 if (t == ot_Package || t == ot_Class || t == ot_Interface || t == ot_Component) {
02053
02054 UMLPackage *umlPkg = static_cast<UMLPackage*>(umlObj);
02055 UMLObjectList lst = umlPkg->containedObjects();
02056 for (UMLObject *obj = lst.first(); obj; obj = lst.next()) {
02057
02058 Uml::IDType id = obj->getID();
02059 for (UMLWidget *w = m_WidgetList.first(); w; w = m_WidgetList.next()) {
02060 if (w->getID() != id)
02061 continue;
02062
02063 if (widget->rect().contains(w->rect()))
02064 continue;
02065
02066 AssociationWidget *a = new AssociationWidget(this, widget,
02067 at_Containment, w);
02068 a->calculateEndingPoints();
02069 a->setActivated(true);
02070 if (! addAssociation(a))
02071 delete a;
02072 }
02073 }
02074 }
02075
02076 UMLPackage *parent = umlObj->getUMLPackage();
02077 if (parent == NULL)
02078 return;
02079
02080 Uml::IDType pkgID = parent->getID();
02081 UMLWidget *pWidget;
02082 UMLWidgetListIt wit(m_WidgetList);
02083 while ((pWidget = wit.current()) != NULL) {
02084 ++wit;
02085 if (pWidget->getID() == pkgID)
02086 break;
02087 }
02088 if (pWidget == NULL || pWidget->rect().contains(widget->rect()))
02089 return;
02090
02091 AssociationWidget *a = new AssociationWidget(this, pWidget, at_Containment, widget);
02092 a->calculateEndingPoints();
02093 a->setActivated(true);
02094 if (! addAssociation(a))
02095 delete a;
02096 }
02097
02098 void UMLView::createAutoAttributeAssociations(UMLWidget *widget) {
02099 if (widget == NULL || m_Type != Uml::dt_Class)
02100 return;
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128 UMLObject *tmpUmlObj = widget->getUMLObject();
02129 if (tmpUmlObj == NULL)
02130 return;
02131
02132 if (tmpUmlObj->getBaseType() == Uml::ot_Datatype) {
02133 UMLClassifier *dt = static_cast<UMLClassifier*>(tmpUmlObj);
02134 while (dt->originType() != NULL) {
02135 tmpUmlObj = dt->originType();
02136 if (tmpUmlObj->getBaseType() != Uml::ot_Datatype)
02137 break;
02138 dt = static_cast<UMLClassifier*>(tmpUmlObj);
02139 }
02140 }
02141 if (tmpUmlObj->getBaseType() != Uml::ot_Class)
02142 return;
02143 UMLClassifier * klass = static_cast<UMLClassifier*>(tmpUmlObj);
02144
02145 UMLAttributeList attrList = klass->getAttributeList();
02146 for (UMLAttributeListIt ait(attrList); ait.current(); ++ait) {
02147 UMLAttribute *attr = ait.current();
02148 createAutoAttributeAssociation(attr->getType(), attr, widget);
02149
02150
02151
02152
02153
02154
02155
02156
02157
02158
02159 }
02160 }
02161
02162 void UMLView::createAutoAttributeAssociation(UMLClassifier *type, UMLAttribute *attr,
02163 UMLWidget *widget ) {
02164 if (type == NULL) {
02165
02166
02167
02168 return;
02169 }
02170 Uml::Association_Type assocType = Uml::at_Composition;
02171 UMLWidget *w = findWidget( type->getID() );
02172 AssociationWidget *aw = NULL;
02173
02174 if (w) {
02175 aw = findAssocWidget(widget, w, attr->getName());
02176 if ( aw == NULL &&
02177
02178 AssocRules::allowAssociation(assocType, widget, w, false) ) {
02179
02180
02181 if (type->getStereotype() == "CORBAInterface")
02182 assocType = at_UniAssociation;
02183 AssociationWidget *a = new AssociationWidget (this, widget, assocType, w);
02184 a->setUMLObject(attr);
02185 a->calculateEndingPoints();
02186 a->setVisibility(attr->getVisibility(), B);
02187
02188
02189
02190
02191 a->setRoleName(attr->getName(), B);
02192 a->setActivated(true);
02193 if (! addAssociation(a))
02194 delete a;
02195 }
02196 }
02197
02198 if (type->getBaseType() == ot_Datatype) {
02199 UMLClassifier *dt = static_cast<UMLClassifier*>(type);
02200
02201 if (dt->isReference()) {
02202
02203 UMLClassifier *c = dt->originType();
02204 UMLWidget *w = c ? findWidget( c->getID() ) : 0;
02205
02206 if (w) {
02207 aw = findAssocWidget(widget, w, attr->getName());
02208 if (aw == NULL &&
02209
02210 AssocRules::allowAssociation(at_Aggregation, widget, w, false)) {
02211
02212
02213 AssociationWidget *a = new AssociationWidget
02214 (this, widget, at_Aggregation, w);
02215 a->setUMLObject(attr);
02216 a->calculateEndingPoints();
02217 a->setVisibility(attr->getVisibility(), B);
02218
02219 a->setMulti("0..1", B);
02220 a->setRoleName(attr->getName(), B);
02221 a->setActivated(true);
02222 if (! addAssociation(a))
02223 delete a;
02224 }
02225 }
02226 }
02227 }
02228 }
02229
02230 void UMLView::findMaxBoundingRectangle(const FloatingTextWidget* ft, int& px, int& py, int& qx, int& qy)
02231 {
02232 if (ft == NULL || !ft->isVisible())
02233 return;
02234
02235 int x = ft -> getX();
02236 int y = ft -> getY();
02237 int x1 = x + ft -> getWidth() - 1;
02238 int y1 = y + ft -> getHeight() - 1;
02239
02240 if (px == -1 || x < px)
02241 px = x;
02242 if (py == -1 || y < py)
02243 py = y;
02244 if (qx == -1 || x1 > qx)
02245 qx = x1;
02246 if (qy == -1 || y1 > qy)
02247 qy = y1;
02248 }
02249
02250 void UMLView::copyAsImage(QPixmap*& pix) {
02251
02252 QRect rect = getDiagramRect();
02253 QPixmap diagram( rect.width(), rect.height() );
02254
02255
02256 m_bDrawSelectedOnly = true;
02257 selectAssociations(true);
02258 getDiagram(rect, diagram);
02259
02260
02261 int px = -1, py = -1, qx = -1, qy = -1;
02262
02263
02264 for (UMLWidget* temp = m_SelectedList.first(); temp; temp = m_SelectedList.next()) {
02265 int x = temp -> getX();
02266 int y = temp -> getY();
02267 int x1 = x + temp -> width() - 1;
02268 int y1 = y + temp -> height() - 1;
02269 if(px == -1 || x < px) {
02270 px = x;
02271 }
02272 if(py == -1 || y < py) {
02273 py = y;
02274 }
02275 if(qx == -1 || x1 > qx) {
02276 qx = x1;
02277 }
02278 if(qy == -1 || y1 > qy) {
02279 qy = y1;
02280 }
02281 }
02282
02283
02284 AssociationWidget *a;
02285 AssociationWidgetListIt assoc_it(m_AssociationList);
02286
02287
02288
02289
02290 while ((a = assoc_it.current()) != NULL) {
02291 ++assoc_it;
02292 if (! a->getSelected())
02293 continue;
02294 const FloatingTextWidget* multiA = const_cast<FloatingTextWidget*>(a->getMultiWidget(A));
02295 const FloatingTextWidget* multiB = const_cast<FloatingTextWidget*>(a->getMultiWidget(B));
02296 const FloatingTextWidget* roleA = const_cast<FloatingTextWidget*>(a->getRoleWidget(A));
02297 const FloatingTextWidget* roleB = const_cast<FloatingTextWidget*>(a->getRoleWidget(B));
02298 const FloatingTextWidget* changeA = const_cast<FloatingTextWidget*>(a->getChangeWidget(A));
02299 const FloatingTextWidget* changeB = const_cast<FloatingTextWidget*>(a->getChangeWidget(B));
02300 findMaxBoundingRectangle(multiA, px, py, qx, qy);
02301 findMaxBoundingRectangle(multiB, px, py, qx, qy);
02302 findMaxBoundingRectangle(roleA, px, py, qx, qy);
02303 findMaxBoundingRectangle(roleB, px, py, qx, qy);
02304 findMaxBoundingRectangle(changeA, px, py, qx, qy);
02305 findMaxBoundingRectangle(changeB, px, py, qx, qy);
02306 }
02307
02308 QRect imageRect;
02309
02310
02311
02312 imageRect.setLeft( px - rect.left() );
02313 imageRect.setTop( py - rect.top() );
02314 imageRect.setRight( qx - rect.left() );
02315 imageRect.setBottom( qy - rect.top() );
02316
02317 pix = new QPixmap(imageRect.width(), imageRect.height());
02318 bitBlt(pix, QPoint(0, 0), &diagram, imageRect);
02319 m_bDrawSelectedOnly = false;
02320 }
02321
02322 void UMLView::setMenu() {
02323 slotRemovePopupMenu();
02324 ListPopupMenu::Menu_Type menu = ListPopupMenu::mt_Undefined;
02325 switch( getType() ) {
02326 case dt_Class:
02327 menu = ListPopupMenu::mt_On_Class_Diagram;
02328 break;
02329
02330 case dt_UseCase:
02331 menu = ListPopupMenu::mt_On_UseCase_Diagram;
02332 break;
02333
02334 case dt_Sequence:
02335 menu = ListPopupMenu::mt_On_Sequence_Diagram;
02336 break;
02337
02338 case dt_Collaboration:
02339 menu = ListPopupMenu::mt_On_Collaboration_Diagram;
02340 break;
02341
02342 case dt_State:
02343 menu = ListPopupMenu::mt_On_State_Diagram;
02344 break;
02345
02346 case dt_Activity:
02347 menu = ListPopupMenu::mt_On_Activity_Diagram;
02348 break;
02349
02350 case dt_Component:
02351 menu = ListPopupMenu::mt_On_Component_Diagram;
02352 break;
02353
02354 case dt_Deployment:
02355 menu = ListPopupMenu::mt_On_Deployment_Diagram;
02356 break;
02357
02358 case dt_EntityRelationship:
02359 menu = ListPopupMenu::mt_On_EntityRelationship_Diagram;
02360 break;
02361
02362 default:
02363 kWarning() << "setMenu() called on unknown diagram type" << endl;
02364 menu = ListPopupMenu::mt_Undefined;
02365 break;
02366 }
02367 if( menu != ListPopupMenu::mt_Undefined ) {
02368 m_pMenu = new ListPopupMenu(this, menu, this);
02369 connect(m_pMenu, SIGNAL(activated(int)), this, SLOT(slotMenuSelection(int)));
02370 m_pMenu->popup( mapToGlobal( contentsToViewport(worldMatrix().map(m_Pos)) ) );
02371 }
02372 }
02373
02374 void UMLView::slotRemovePopupMenu() {
02375 if(m_pMenu) {
02376 disconnect(m_pMenu, SIGNAL(activated(int)), this, SLOT(slotMenuSelection(int)));
02377 delete m_pMenu;
02378 m_pMenu = 0;
02379 }
02380 }
02381
02382 void UMLView::slotMenuSelection(int sel) {
02383 switch( (ListPopupMenu::Menu_Type)sel ) {
02384 case ListPopupMenu::mt_Undo:
02385 m_pDoc->loadUndoData();
02386 break;
02387
02388 case ListPopupMenu::mt_Redo:
02389 m_pDoc->loadRedoData();
02390 break;
02391
02392 case ListPopupMenu::mt_Clear:
02393 clearDiagram();
02394 break;
02395
02396 case ListPopupMenu::mt_Export_Image:
02397 m_pImageExporter->exportView();
02398 break;
02399
02400 case ListPopupMenu::mt_FloatText:
02401 {
02402 FloatingTextWidget* ft = new FloatingTextWidget(this);
02403 ft->changeTextDlg();
02404
02405 if(!FloatingTextWidget::isTextValid(ft->getText())) {
02406 delete ft;
02407 } else {
02408 ft->setID(UniqueID::gen());
02409 setupNewWidget(ft);
02410 }
02411 }
02412 break;
02413
02414 case ListPopupMenu::mt_UseCase:
02415 m_bCreateObject = true;
02416 Object_Factory::createUMLObject( ot_UseCase );
02417 break;
02418
02419 case ListPopupMenu::mt_Actor:
02420 m_bCreateObject = true;
02421 Object_Factory::createUMLObject( ot_Actor );
02422 break;
02423
02424 case ListPopupMenu::mt_Class:
02425 case ListPopupMenu::mt_Object:
02426 m_bCreateObject = true;
02427 Object_Factory::createUMLObject( ot_Class);
02428 break;
02429
02430 case ListPopupMenu::mt_Package:
02431 m_bCreateObject = true;
02432 Object_Factory::createUMLObject(ot_Package);
02433 break;
02434
02435 case ListPopupMenu::mt_Component:
02436 m_bCreateObject = true;
02437 Object_Factory::createUMLObject(ot_Component);
02438 break;
02439
02440 case ListPopupMenu::mt_Node:
02441 m_bCreateObject = true;
02442 Object_Factory::createUMLObject(ot_Node);
02443 break;
02444
02445 case ListPopupMenu::mt_Artifact:
02446 m_bCreateObject = true;
02447 Object_Factory::createUMLObject(ot_Artifact);
02448 break;
02449
02450 case ListPopupMenu::mt_Interface:
02451 m_bCreateObject = true;
02452 Object_Factory::createUMLObject(ot_Interface);
02453 break;
02454
02455 case ListPopupMenu::mt_Enum:
02456 m_bCreateObject = true;
02457 Object_Factory::createUMLObject(ot_Enum);
02458 break;
02459
02460 case ListPopupMenu::mt_Entity:
02461 m_bCreateObject = true;
02462 Object_Factory::createUMLObject(ot_Entity);
02463 break;
02464
02465 case ListPopupMenu::mt_Datatype:
02466 m_bCreateObject = true;
02467 Object_Factory::createUMLObject(ot_Datatype);
02468 break;
02469
02470 case ListPopupMenu::mt_Cut:
02471
02472 if ( m_SelectedList.count() &&
02473 UMLApp::app()->editCutCopy(true) ) {
02474 deleteSelection();
02475 m_pDoc->setModified(true);
02476 }
02477 break;
02478
02479 case ListPopupMenu::mt_Copy:
02480
02481 m_SelectedList.count() && UMLApp::app()->editCutCopy(true);
02482 break;
02483
02484 case ListPopupMenu::mt_Paste:
02485 m_PastePoint = m_Pos;
02486 m_Pos.setX( 2000 );
02487 m_Pos.setY( 2000 );
02488 UMLApp::app()->slotEditPaste();
02489
02490 m_PastePoint.setX( 0 );
02491 m_PastePoint.setY( 0 );
02492 break;
02493
02494 case ListPopupMenu::mt_Initial_State:
02495 {
02496 StateWidget* state = new StateWidget( this, StateWidget::Initial );
02497 setupNewWidget( state );
02498 }
02499 break;
02500
02501 case ListPopupMenu::mt_End_State:
02502 {
02503 StateWidget* state = new StateWidget( this, StateWidget::End );
02504 setupNewWidget( state );
02505 }
02506 break;
02507
02508 case ListPopupMenu::mt_State:
02509 {
02510 bool ok = false;
02511 QString name = KInputDialog::getText( i18n("Enter State Name"),
02512 i18n("Enter the name of the new state:"),
02513 i18n("new state"), &ok, UMLApp::app() );
02514 if ( ok ) {
02515 StateWidget* state = new StateWidget( this );
02516 state->setName( name );
02517 setupNewWidget( state );
02518 }
02519 }
02520 break;
02521
02522 case ListPopupMenu::mt_Initial_Activity:
02523 {
02524 ActivityWidget* activity = new ActivityWidget( this, ActivityWidget::Initial );
02525 setupNewWidget(activity);
02526 }
02527 break;
02528
02529
02530 case ListPopupMenu::mt_End_Activity:
02531 {
02532 ActivityWidget* activity = new ActivityWidget( this, ActivityWidget::End );
02533 setupNewWidget(activity);
02534 }
02535 break;
02536
02537 case ListPopupMenu::mt_Branch:
02538 {
02539 ActivityWidget* activity = new ActivityWidget( this, ActivityWidget::Branch );
02540 setupNewWidget(activity);
02541 }
02542 break;
02543
02544 case ListPopupMenu::mt_Activity:
02545 {
02546 bool ok = false;
02547 QString name = KInputDialog::getText( i18n("Enter Activity Name"),
02548 i18n("Enter the name of the new activity:"),
02549 i18n("new activity"), &ok, UMLApp::app() );
02550 if ( ok ) {
02551 ActivityWidget* activity = new ActivityWidget( this, ActivityWidget::Normal );
02552 activity->setName( name );
02553 setupNewWidget(activity);
02554 }
02555 }
02556 break;
02557
02558 case ListPopupMenu::mt_SnapToGrid:
02559 toggleSnapToGrid();
02560 m_pDoc->setModified();
02561 break;
02562
02563 case ListPopupMenu::mt_ShowSnapGrid:
02564 toggleShowGrid();
02565 m_pDoc->setModified();
02566 break;
02567
02568 case ListPopupMenu::mt_Properties:
02569 if (showPropDialog() == true)
02570 m_pDoc->setModified();
02571 break;
02572
02573 case ListPopupMenu::mt_Delete:
02574 m_pDoc->removeDiagram( getID() );
02575 break;
02576
02577 case ListPopupMenu::mt_Rename:
02578 {
02579 bool ok = false;
02580 QString name = KInputDialog::getText( i18n("Enter Diagram Name"),
02581 i18n("Enter the new name of the diagram:"),
02582 getName(), &ok, UMLApp::app() );
02583 if (ok) {
02584 setName(name);
02585 m_pDoc->signalDiagramRenamed(this);
02586 }
02587 }
02588 break;
02589
02590 default:
02591 break;
02592 }
02593 }
02594
02595 void UMLView::slotCutSuccessful() {
02596 if( m_bStartedCut ) {
02597 deleteSelection();
02598 m_bStartedCut = false;
02599 }
02600 }
02601
02602 void UMLView::slotShowView() {
02603 m_pDoc -> changeCurrentView( getID() );
02604 }
02605
02606 QPoint UMLView::getPastePoint() {
02607 QPoint point = m_PastePoint;
02608 point.setX( point.x() - m_Pos.x() );
02609 point.setY( point.y() - m_Pos.y() );
02610 return point;
02611 }
02612
02613 void UMLView::resetPastePoint() {
02614 m_PastePoint = m_Pos;
02615 }
02616
02617 int UMLView::snappedX (int x) {
02618 if (getSnapToGrid()) {
02619 int gridX = getSnapX();
02620 int modX = x % gridX;
02621 x -= modX;
02622 if (modX >= gridX / 2)
02623 x += gridX;
02624 }
02625 return x;
02626 }
02627
02628 int UMLView::snappedY (int y) {
02629 if (getSnapToGrid()) {
02630 int gridY = getSnapY();
02631 int modY = y % gridY;
02632 y -= modY;
02633 if (modY >= gridY / 2)
02634 y += gridY;
02635 }
02636 return y;
02637 }
02638
02639 bool UMLView::showPropDialog() {
02640 UMLViewDialog dlg( this, this );
02641 if( dlg.exec() ) {
02642 return true;
02643 }
02644 return false;
02645 }
02646
02647
02648 QFont UMLView::getFont() const {
02649 return m_Options.uiState.font;
02650 }
02651
02652 void UMLView::setFont(QFont font, bool changeAllWidgets ) {
02653 m_Options.uiState.font = font;
02654 if (!changeAllWidgets)
02655 return;
02656 for (UMLWidgetListIt wit(m_WidgetList); wit.current(); ++wit) {
02657 UMLWidget *w = wit.current();
02658 w->setFont(font);
02659 }
02660 }
02661
02662 void UMLView::setClassWidgetOptions( ClassOptionsPage * page ) {
02663 UMLWidget * pWidget = 0;
02664 UMLWidgetListIt wit( m_WidgetList );
02665 while ( (pWidget = wit.current()) != 0 ) {
02666 ++wit;
02667 Uml::Widget_Type wt = pWidget->getBaseType();
02668 if (wt == Uml::wt_Class || wt == Uml::wt_Interface) {
02669 page -> setWidget( static_cast<ClassifierWidget *>(pWidget) );
02670 page -> updateUMLWidget();
02671 }
02672 }
02673 }
02674
02675
02676 void UMLView::checkSelections() {
02677 UMLWidget * pWA = 0, * pWB = 0, * pTemp = 0;
02678
02679 for(pTemp=(UMLWidget *)m_SelectedList.first();pTemp;pTemp=(UMLWidget *)m_SelectedList.next()) {
02680 if( pTemp->getBaseType() == wt_Message && pTemp -> getSelected() ) {
02681 MessageWidget * pMessage = static_cast<MessageWidget *>( pTemp );
02682 pWA = pMessage -> getWidget(A);
02683 pWB = pMessage -> getWidget(B);
02684 if( !pWA -> getSelected() ) {
02685 pWA -> setSelectedFlag( true );
02686 m_SelectedList.append( pWA );
02687 }
02688 if( !pWB -> getSelected() ) {
02689 pWB -> setSelectedFlag( true );
02690 m_SelectedList.append( pWB );
02691 }
02692 }
02693 }
02694
02695 AssociationWidgetListIt it(m_AssociationList);
02696 AssociationWidget * pAssoc = 0;
02697 while((pAssoc = it.current())) {
02698 ++it;
02699 if( pAssoc -> getSelected() ) {
02700 pWA = pAssoc -> getWidget(A);
02701 pWB = pAssoc -> getWidget(B);
02702 if( !pWA -> getSelected() ) {
02703 pWA -> setSelectedFlag( true );
02704 m_SelectedList.append( pWA );
02705 }
02706 if( !pWB -> getSelected() ) {
02707 pWB -> setSelectedFlag( true );
02708 m_SelectedList.append( pWB );
02709 }
02710 }
02711 }
02712 }
02713
02714 bool UMLView::checkUniqueSelection()
02715 {
02716
02717 if (m_SelectedList.count() <= 0)
02718 return true;
02719
02720
02721 UMLWidget * pTemp = (UMLWidget *) m_SelectedList.first();
02722 Widget_Type tmpType = pTemp -> getBaseType();
02723
02724
02725 for ( pTemp = (UMLWidget *) m_SelectedList.first();
02726 pTemp;
02727 pTemp = (UMLWidget *) m_SelectedList.next() ) {
02728 if( pTemp->getBaseType() != tmpType)
02729 {
02730 return false;
02731 }
02732 }
02733
02734 return true;
02735 }
02736
02737 void UMLView::clearDiagram() {
02738 if( KMessageBox::Continue == KMessageBox::warningContinueCancel( this, i18n("You are about to delete "
02739 "the entire diagram.\nAre you sure?"),
02740 i18n("Delete Diagram?"),KGuiItem( i18n("&Delete"), "editdelete") ) ) {
02741 removeAllWidgets();
02742 }
02743 }
02744
02745 void UMLView::toggleSnapToGrid() {
02746 setSnapToGrid( !getSnapToGrid() );
02747 }
02748
02749 void UMLView::toggleSnapComponentSizeToGrid() {
02750 setSnapComponentSizeToGrid( !getSnapComponentSizeToGrid() );
02751 }
02752
02753 void UMLView::toggleShowGrid() {
02754 setShowSnapGrid( !getShowSnapGrid() );
02755 }
02756
02757 void UMLView::setSnapToGrid(bool bSnap) {
02758 m_bUseSnapToGrid = bSnap;
02759 emit sigSnapToGridToggled( getSnapToGrid() );
02760 }
02761
02762 void UMLView::setSnapComponentSizeToGrid(bool bSnap) {
02763 m_bUseSnapComponentSizeToGrid = bSnap;
02764 updateComponentSizes();
02765 emit sigSnapComponentSizeToGridToggled( getSnapComponentSizeToGrid() );
02766 }
02767
02768 bool UMLView::getShowSnapGrid() const {
02769 return m_bShowSnapGrid;
02770 }
02771
02772 void UMLView::setShowSnapGrid(bool bShow) {
02773 m_bShowSnapGrid = bShow;
02774 canvas()->setAllChanged();
02775 emit sigShowGridToggled( getShowSnapGrid() );
02776 }
02777
02778 bool UMLView::getShowOpSig() const {
02779 return m_Options.classState.showOpSig;
02780 }
02781
02782 void UMLView::setShowOpSig(bool bShowOpSig) {
02783 m_Options.classState.showOpSig = bShowOpSig;
02784 }
02785
02786 void UMLView::setZoom(int zoom) {
02787 if (zoom < 10) {
02788 zoom = 10;
02789 } else if (zoom > 500) {
02790 zoom = 500;
02791 }
02792
02793 QWMatrix wm;
02794 wm.scale(zoom/100.0,zoom/100.0);
02795 setWorldMatrix(wm);
02796
02797 m_nZoom = currentZoom();
02798 resizeCanvasToItems();
02799 }
02800
02801 int UMLView::currentZoom() {
02802 return (int)(worldMatrix().m11()*100.0);
02803 }
02804
02805 void UMLView::zoomIn() {
02806 QWMatrix wm = worldMatrix();
02807 wm.scale(1.5,1.5);
02808 setZoom( (int)(wm.m11()*100.0) );
02809 }
02810
02811 void UMLView::zoomOut() {
02812 QWMatrix wm = worldMatrix();
02813 wm.scale(2.0/3.0, 2.0/3.0);
02814 setZoom( (int)(wm.m11()*100.0) );
02815 }
02816
02817 void UMLView::fileLoaded() {
02818 setZoom( getZoom() );
02819 resizeCanvasToItems();
02820 }
02821
02822 void UMLView::setCanvasSize(int width, int height) {
02823 setCanvasWidth(width);
02824 setCanvasHeight(height);
02825 canvas()->resize(width, height);
02826 }
02827
02828 void UMLView::resizeCanvasToItems() {
02829 QRect canvasSize = getDiagramRect();
02830 int canvasWidth = canvasSize.right() + 5;
02831 int canvasHeight = canvasSize.bottom() + 5;
02832
02833
02834 int contentsX, contentsY;
02835 int contentsWMX, contentsWMY;
02836 viewportToContents(viewport()->width(), viewport()->height(), contentsX, contentsY);
02837 inverseWorldMatrix().map(contentsX, contentsY, &contentsWMX, &contentsWMY);
02838
02839 if (canvasWidth < contentsWMX) {
02840 canvasWidth = contentsWMX;
02841 }
02842
02843 if (canvasHeight < contentsWMY) {
02844 canvasHeight = contentsWMY;
02845 }
02846
02847 setCanvasSize(canvasWidth, canvasHeight);
02848 }
02849
02850 void UMLView::show() {
02851 QWidget::show();
02852 resizeCanvasToItems();
02853 }
02854
02855 void UMLView::updateComponentSizes() {
02856
02857 UMLWidgetListIt it( m_WidgetList );
02858 UMLWidget *obj;
02859 while ( (obj=(UMLWidget*)it.current()) != 0 ) {
02860 ++it;
02861 obj->updateComponentSize();
02862 }
02863 }
02864
02874 void UMLView::forceUpdateWidgetFontMetrics(QPainter * painter) {
02875 UMLWidgetListIt it( m_WidgetList );
02876 UMLWidget *obj;
02877
02878 while ((obj = it.current()) != 0 ) {
02879 ++it;
02880 obj->forceUpdateFontMetrics(painter);
02881 }
02882 }
02883
02884 void UMLView::saveToXMI( QDomDocument & qDoc, QDomElement & qElement ) {
02885 QDomElement viewElement = qDoc.createElement( "diagram" );
02886 viewElement.setAttribute( "xmi.id", ID2STR(m_nID) );
02887 viewElement.setAttribute( "name", getName() );
02888 viewElement.setAttribute( "type", m_Type );
02889 viewElement.setAttribute( "documentation", m_Documentation );
02890
02891 viewElement.setAttribute( "fillcolor", m_Options.uiState.fillColor.name() );
02892 viewElement.setAttribute( "linecolor", m_Options.uiState.lineColor.name() );
02893 viewElement.setAttribute( "linewidth", m_Options.uiState.lineWidth );
02894 viewElement.setAttribute( "usefillcolor", m_Options.uiState.useFillColor );
02895 viewElement.setAttribute( "font", m_Options.uiState.font.toString() );
02896
02897 viewElement.setAttribute( "showattsig", m_Options.classState.showAttSig );
02898 viewElement.setAttribute( "showatts", m_Options.classState.showAtts);
02899 viewElement.setAttribute( "showopsig", m_Options.classState.showOpSig );
02900 viewElement.setAttribute( "showops", m_Options.classState.showOps );
02901 viewElement.setAttribute( "showpackage", m_Options.classState.showPackage );
02902 viewElement.setAttribute( "showscope", m_Options.classState.showVisibility );
02903 viewElement.setAttribute( "showstereotype", m_Options.classState.showStereoType );
02904
02905 viewElement.setAttribute( "localid", ID2STR(m_nLocalID) );
02906 viewElement.setAttribute( "showgrid", m_bShowSnapGrid );
02907 viewElement.setAttribute( "snapgrid", m_bUseSnapToGrid );
02908 viewElement.setAttribute( "snapcsgrid", m_bUseSnapComponentSizeToGrid );
02909 viewElement.setAttribute( "snapx", m_nSnapX );
02910 viewElement.setAttribute( "snapy", m_nSnapY );
02911 viewElement.setAttribute( "zoom", m_nZoom );
02912 viewElement.setAttribute( "canvasheight", m_nCanvasHeight );
02913 viewElement.setAttribute( "canvaswidth", m_nCanvasWidth );
02914
02915 UMLWidget * widget = 0;
02916 UMLWidgetListIt w_it( m_WidgetList );
02917 QDomElement widgetElement = qDoc.createElement( "widgets" );
02918 while( ( widget = w_it.current() ) ) {
02919 ++w_it;
02920
02921
02922
02923
02924
02925 if (widget->getBaseType() != wt_Text ||
02926 static_cast<FloatingTextWidget*>(widget)->getLink() == NULL)
02927 widget->saveToXMI( qDoc, widgetElement );
02928 }
02929 viewElement.appendChild( widgetElement );
02930
02931 MessageWidgetListIt m_it( m_MessageList );
02932 QDomElement messageElement = qDoc.createElement( "messages" );
02933 while( ( widget = m_it.current() ) ) {
02934 ++m_it;
02935 widget -> saveToXMI( qDoc, messageElement );
02936 }
02937 viewElement.appendChild( messageElement );
02938
02939 QDomElement assocElement = qDoc.createElement( "associations" );
02940 if ( m_AssociationList.count() ) {
02941
02942
02943
02944
02945
02946
02947
02948
02949
02950
02951
02952 AssociationWidgetListIt a_it( m_AssociationList );
02953 AssociationWidget * assoc = 0;
02954 while( ( assoc = a_it.current() ) ) {
02955 ++a_it;
02956 assoc -> saveToXMI( qDoc, assocElement );
02957 }
02958
02959
02960 }
02961 viewElement.appendChild( assocElement );
02962 qElement.appendChild( viewElement );
02963 }
02964
02965 bool UMLView::loadFromXMI( QDomElement & qElement ) {
02966 QString id = qElement.attribute( "xmi.id", "-1" );
02967 m_nID = STR2ID(id);
02968 if( m_nID == Uml::id_None )
02969 return false;
02970 setName( qElement.attribute( "name", "" ) );
02971 QString type = qElement.attribute( "type", "0" );
02972 m_Documentation = qElement.attribute( "documentation", "" );
02973 QString localid = qElement.attribute( "localid", "0" );
02974
02975 QString font = qElement.attribute( "font", "" );
02976 if (!font.isEmpty()) {
02977 m_Options.uiState.font.fromString( font );
02978 m_Options.uiState.font.setUnderline(false);
02979 }
02980 QString fillcolor = qElement.attribute( "fillcolor", "" );
02981 QString linecolor = qElement.attribute( "linecolor", "" );
02982 QString linewidth = qElement.attribute( "linewidth", "" );
02983 QString usefillcolor = qElement.attribute( "usefillcolor", "0" );
02984 m_Options.uiState.useFillColor = (bool)usefillcolor.toInt();
02985
02986 QString temp = qElement.attribute( "showattsig", "0" );
02987 m_Options.classState.showAttSig = (bool)temp.toInt();
02988 temp = qElement.attribute( "showatts", "0" );
02989 m_Options.classState.showAtts = (bool)temp.toInt();
02990 temp = qElement.attribute( "showopsig", "0" );
02991 m_Options.classState.showOpSig = (bool)temp.toInt();
02992 temp = qElement.attribute( "showops", "0" );
02993 m_Options.classState.showOps = (bool)temp.toInt();
02994 temp = qElement.attribute( "showpackage", "0" );
02995 m_Options.classState.showPackage = (bool)temp.toInt();
02996 temp = qElement.attribute( "showscope", "0" );
02997 m_Options.classState.showVisibility = (bool)temp.toInt();
02998 temp = qElement.attribute( "showstereotype", "0" );
02999 m_Options.classState.showStereoType = (bool)temp.toInt();
03000
03001 QString showgrid = qElement.attribute( "showgrid", "0" );
03002 m_bShowSnapGrid = (bool)showgrid.toInt();
03003
03004 QString snapgrid = qElement.attribute( "snapgrid", "0" );
03005 m_bUseSnapToGrid = (bool)snapgrid.toInt();
03006
03007 QString snapcsgrid = qElement.attribute( "snapcsgrid", "0" );
03008 m_bUseSnapComponentSizeToGrid = (bool)snapcsgrid.toInt();
03009
03010 QString snapx = qElement.attribute( "snapx", "10" );
03011 m_nSnapX = snapx.toInt();
03012
03013 QString snapy = qElement.attribute( "snapy", "10" );
03014 m_nSnapY = snapy.toInt();
03015
03016 QString zoom = qElement.attribute( "zoom", "100" );
03017 m_nZoom = zoom.toInt();
03018
03019 QString height = qElement.attribute( "canvasheight", QString("%1").arg(UMLView::defaultCanvasSize) );
03020 m_nCanvasHeight = height.toInt();
03021
03022 QString width = qElement.attribute( "canvaswidth", QString("%1").arg(UMLView::defaultCanvasSize) );
03023 m_nCanvasWidth = width.toInt();
03024
03025 int nType = type.toInt();
03026 if (nType == -1 || nType >= 400) {
03027
03028
03029 switch (nType) {
03030 case 400:
03031 m_Type = Uml::dt_UseCase;
03032 break;
03033 case 401:
03034 m_Type = Uml::dt_Collaboration;
03035 break;
03036 case 402:
03037 m_Type = Uml::dt_Class;
03038 break;
03039 case 403:
03040 m_Type = Uml::dt_Sequence;
03041 break;
03042 case 404:
03043 m_Type = Uml::dt_State;
03044 break;
03045 case 405:
03046 m_Type = Uml::dt_Activity;
03047 break;
03048 case 406:
03049 m_Type = Uml::dt_Component;
03050 break;
03051 case 407:
03052 m_Type = Uml::dt_Deployment;
03053 break;
03054 case 408:
03055 m_Type = Uml::dt_EntityRelationship;
03056 break;
03057 default:
03058 m_Type = Uml::dt_Undefined;
03059 break;
03060 }
03061 } else {
03062 m_Type = (Uml::Diagram_Type)nType;
03063 }
03064 if( !fillcolor.isEmpty() )
03065 m_Options.uiState.fillColor = QColor( fillcolor );
03066 if( !linecolor.isEmpty() )
03067 m_Options.uiState.lineColor = QColor( linecolor );
03068 if( !linewidth.isEmpty() )
03069 m_Options.uiState.lineWidth = linewidth.toInt();
03070 m_nLocalID = STR2ID(localid);
03071
03072 QDomNode node = qElement.firstChild();
03073 bool widgetsLoaded = false, messagesLoaded = false, associationsLoaded = false;
03074 while (!node.isNull()) {
03075 QDomElement element = node.toElement();
03076 if (!element.isNull()) {
03077 if (element.tagName() == "widgets")
03078 widgetsLoaded = loadWidgetsFromXMI( element );
03079 else if (element.tagName() == "messages")
03080 messagesLoaded = loadMessagesFromXMI( element );
03081 else if (element.tagName() == "associations")
03082 associationsLoaded = loadAssociationsFromXMI( element );
03083 }
03084 node = node.nextSibling();
03085 }
03086
03087 if (!widgetsLoaded) {
03088 kWarning() << "failed umlview load on widgets" << endl;
03089 return false;
03090 }
03091 if (!messagesLoaded) {
03092 kWarning() << "failed umlview load on messages" << endl;
03093 return false;
03094 }
03095 if (!associationsLoaded) {
03096 kWarning() << "failed umlview load on associations" << endl;
03097 return false;
03098 }
03099 return true;
03100 }
03101
03102 bool UMLView::loadWidgetsFromXMI( QDomElement & qElement ) {
03103 UMLWidget* widget = 0;
03104 QDomNode node = qElement.firstChild();
03105 QDomElement widgetElement = node.toElement();
03106 while( !widgetElement.isNull() ) {
03107 widget = loadWidgetFromXMI(widgetElement);
03108 if (widget) {
03109 m_WidgetList.append( widget );
03110
03111
03112
03113
03114
03115 }
03116 node = widgetElement.nextSibling();
03117 widgetElement = node.toElement();
03118 }
03119
03120 return true;
03121 }
03122
03123 UMLWidget* UMLView::loadWidgetFromXMI(QDomElement& widgetElement) {
03124
03125 if ( !m_pDoc ) {
03126 kWarning() << "UMLView::loadWidgetFromXMI(): m_pDoc is NULL" << endl;
03127 return 0L;
03128 }
03129
03130 QString tag = widgetElement.tagName();
03131 QString idstr = widgetElement.attribute( "xmi.id", "-1" );
03132 UMLWidget* widget = Widget_Factory::makeWidgetFromXMI(tag, idstr, this);
03133 if (widget == NULL)
03134 return NULL;
03135 if (!widget->loadFromXMI(widgetElement)) {
03136 widget->cleanup();
03137 delete widget;
03138 return 0;
03139 }
03140 return widget;
03141 }
03142
03143 bool UMLView::loadMessagesFromXMI( QDomElement & qElement ) {
03144 MessageWidget * message = 0;
03145 QDomNode node = qElement.firstChild();
03146 QDomElement messageElement = node.toElement();
03147 while( !messageElement.isNull() ) {
03148 QString tag = messageElement.tagName();
03149 if (tag == "messagewidget" ||
03150 tag == "UML:MessageWidget" ) {
03151 message = new MessageWidget(this, sequence_message_asynchronous,
03152 Uml::id_Reserved);
03153 if( !message -> loadFromXMI( messageElement ) ) {
03154 delete message;
03155 return false;
03156 }
03157 m_MessageList.append( message );
03158 FloatingTextWidget *ft = message->getFloatingTextWidget();
03159 if (ft)
03160 m_WidgetList.append( ft );
03161 else if (message->getSequenceMessageType() != sequence_message_creation)
03162 kDebug() << "UMLView::loadMessagesFromXMI: ft is NULL"
03163 << " for message " << ID2STR(message->getID()) << endl;
03164 }
03165 node = messageElement.nextSibling();
03166 messageElement = node.toElement();
03167 }
03168 return true;
03169 }
03170
03171 bool UMLView::loadAssociationsFromXMI( QDomElement & qElement ) {
03172 QDomNode node = qElement.firstChild();
03173 QDomElement assocElement = node.toElement();
03174 int countr = 0;
03175 while( !assocElement.isNull() ) {
03176 QString tag = assocElement.tagName();
03177 if (tag == "assocwidget" ||
03178 tag == "UML:AssocWidget") {
03179 countr++;
03180 AssociationWidget *assoc = new AssociationWidget(this);
03181 if( !assoc->loadFromXMI( assocElement ) ) {
03182 kError() << "couldn't loadFromXMI association widget:"
03183 << assoc << ", bad XMI file? Deleting from umlview."
03184 << endl;
03185 delete assoc;
03186
03187
03188
03189
03190 } else {
03191 if(!addAssociation(assoc, false))
03192 {
03193 kError()<<"Couldnt addAssociation("<<assoc<<") to umlview, deleting."<<endl;
03194
03195 delete assoc;
03196
03197 }
03198 }
03199 }
03200 node = assocElement.nextSibling();
03201 assocElement = node.toElement();
03202 }
03203 return true;
03204 }
03205
03206 void UMLView::addObject(UMLObject *object)
03207 {
03208 m_bCreateObject = true;
03209 if (m_pDoc->addUMLObject(object))
03210 m_pDoc->signalUMLObjectCreated(object);
03211 else
03212 m_bCreateObject = false;
03213 }
03214
03215 bool UMLView::loadUisDiagramPresentation(QDomElement & qElement) {
03216 for (QDomNode node = qElement.firstChild(); !node.isNull(); node = node.nextSibling()) {
03217 QDomElement elem = node.toElement();
03218 QString tag = elem.tagName();
03219 if (! Uml::tagEq(tag, "Presentation")) {
03220 kError() << "ignoring unknown UisDiagramPresentation tag "
03221 << tag << endl;
03222 continue;
03223 }
03224 QDomNode n = elem.firstChild();
03225 QDomElement e = n.toElement();
03226 QString idStr;
03227 int x = 0, y = 0, w = 0, h = 0;
03228 while (!e.isNull()) {
03229 tag = e.tagName();
03230 kDebug() << "Presentation: tag = " << tag << endl;
03231 if (Uml::tagEq(tag, "Presentation.geometry")) {
03232 QDomNode gnode = e.firstChild();
03233 QDomElement gelem = gnode.toElement();
03234 QString csv = gelem.text();
03235 QStringList dim = QStringList::split(",", csv);
03236 x = dim[0].toInt();
03237 y = dim[1].toInt();
03238 w = dim[2].toInt();
03239 h = dim[3].toInt();
03240 } else if (Uml::tagEq(tag, "Presentation.style")) {
03241
03242 } else if (Uml::tagEq(tag, "Presentation.model")) {
03243 QDomNode mnode = e.firstChild();
03244 QDomElement melem = mnode.toElement();
03245 idStr = melem.attribute("xmi.idref", "");
03246 } else {
03247 kDebug() << "UMLView::uisLoadFromXMI: ignoring tag "
03248 << tag << endl;
03249 }
03250 n = n.nextSibling();
03251 e = n.toElement();
03252 }
03253 Uml::IDType id = STR2ID(idStr);
03254 UMLObject *o = m_pDoc->findObjectById(id);
03255 if (o == NULL) {
03256 kError() << "UMLView::uisLoadFromXMI: Cannot find object for id "
03257 << idStr << endl;
03258 } else {
03259 Uml::Object_Type ot = o->getBaseType();
03260 kDebug() << "Create widget for model object of type " << ot << endl;
03261 UMLWidget *widget = NULL;
03262 switch (ot) {
03263 case Uml::ot_Class:
03264 widget = new ClassifierWidget(this, static_cast<UMLClassifier*>(o));
03265 break;
03266 case Uml::ot_Association:
03267 {
03268 UMLAssociation *umla = static_cast<UMLAssociation*>(o);
03269 Uml::Association_Type at = umla->getAssocType();
03270 UMLObject* objA = umla->getObject(Uml::A);
03271 UMLObject* objB = umla->getObject(Uml::B);
03272 if (objA == NULL || objB == NULL) {
03273 kError() << "intern err 1" << endl;
03274 return false;
03275 }
03276 UMLWidget *wA = findWidget(objA->getID());
03277 UMLWidget *wB = findWidget(objB->getID());
03278 if (wA != NULL && wB != NULL) {
03279 AssociationWidget *aw =
03280 new AssociationWidget(this, wA, at, wB, umla);
03281 aw->syncToModel();
03282 m_AssociationList.append(aw);
03283 } else {
03284 kError() << "cannot create assocwidget from ("
03285 << wA << ", " << wB << ")" << endl;
03286 }
03287 break;
03288 }
03289 case Uml::ot_Role:
03290 {
03291 UMLRole *robj = static_cast<UMLRole*>(o);
03292 UMLAssociation *umla = robj->getParentAssociation();
03293
03294
03295
03296
03297 break;
03298 }
03299 default:
03300 kError() << "UMLView::uisLoadFromXMI: "
03301 << "Cannot create widget of type "
03302 << ot << endl;
03303 }
03304 if (widget) {
03305 kDebug() << "Widget: x=" << x << ", y=" << y
03306 << ", w=" << w << ", h=" << h << endl;
03307 widget->setX(x);
03308 widget->setY(y);
03309 widget->setSize(w, h);
03310 m_WidgetList.append(widget);
03311 }
03312 }
03313 }
03314 return true;
03315 }
03316
03317 bool UMLView::loadUISDiagram(QDomElement & qElement) {
03318 QString idStr = qElement.attribute( "xmi.id", "" );
03319 if (idStr.isEmpty())
03320 return false;
03321 m_nID = STR2ID(idStr);
03322 UMLListViewItem *ulvi = NULL;
03323 for (QDomNode node = qElement.firstChild(); !node.isNull(); node = node.nextSibling()) {
03324 if (node.isComment())
03325 continue;
03326 QDomElement elem = node.toElement();
03327 QString tag = elem.tagName();
03328 if (tag == "uisDiagramName") {
03329 setName( elem.text() );
03330 if (ulvi)
03331 ulvi->setText( getName() );
03332 } else if (tag == "uisDiagramStyle") {
03333 QString diagramStyle = elem.text();
03334 if (diagramStyle != "ClassDiagram") {
03335 kError() << "UMLView::uisLoadFromXMI: diagram style " << diagramStyle
03336 << " is not yet implemented" << endl;
03337 continue;
03338 }
03339 m_pDoc->setMainViewID(m_nID);
03340 m_Type = Uml::dt_Class;
03341 UMLListView *lv = UMLApp::app()->getListView();
03342 ulvi = new UMLListViewItem( lv->theLogicalView(), getName(),
03343 Uml::lvt_Class_Diagram, m_nID );
03344 } else if (tag == "uisDiagramPresentation") {
03345 loadUisDiagramPresentation(elem);
03346 } else if (tag != "uisToolName") {
03347 kDebug() << "UMLView::uisLoadFromXMI: ignoring tag " << tag << endl;
03348 }
03349 }
03350 return true;
03351 }
03352
03353
03354 #include "umlview.moc"