umlwidgetcontroller.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "umlwidgetcontroller.h"
00014
00015
00016 #include <qevent.h>
00017 #include <qpoint.h>
00018
00019
00020 #include <kcursor.h>
00021 #include <kdebug.h>
00022 #include <klocale.h>
00023
00024
00025 #include "umlwidget.h"
00026 #include "umlwidgetlist.h"
00027 #include "umlnamespace.h"
00028 #include "uml.h"
00029 #include "umldoc.h"
00030 #include "umlview.h"
00031 #include "umlobject.h"
00032 #include "listpopupmenu.h"
00033 #include "classifierwidget.h"
00034 #include "associationwidget.h"
00035 #include "messagewidget.h"
00036
00037 using namespace Uml;
00038
00039 UMLWidgetController::UMLWidgetController(UMLWidget *widget) {
00040 m_widget = widget;
00041
00042 m_pressOffsetX = m_pressOffsetY = 0;
00043 m_oldX = m_oldY = 0;
00044 m_oldW = m_oldH = 0;
00045 m_minSelectedX = m_minSelectedY = m_maxSelectedX = m_maxSelectedY = 0;
00046
00047 m_shiftPressed = false;
00048 m_leftButtonDown = m_middleButtonDown = m_rightButtonDown = false;
00049 m_inMoveArea = m_inResizeArea = 0;
00050 m_wasSelected = m_moved = m_resized = 0;
00051 }
00052
00053 UMLWidgetController::~UMLWidgetController() {
00054 }
00055
00056 void UMLWidgetController::mousePressEvent(QMouseEvent *me) {
00057
00058 if (m_leftButtonDown || m_middleButtonDown || m_rightButtonDown) {
00059 return;
00060 }
00061
00062 if (me->button() == Qt::LeftButton) {
00063 m_leftButtonDown = true;
00064 } else if (me->button() == Qt::RightButton) {
00065 m_rightButtonDown = true;
00066 } else {
00067 m_middleButtonDown = true;
00068 return;
00069 }
00070
00071
00072
00073 saveWidgetValues(me);
00074
00075 m_oldStatusBarMsg = UMLApp::app()->getStatusBarMsg();
00076
00077 if (me->state() == Qt::ShiftButton || me->state() == Qt::ControlButton) {
00078 m_shiftPressed = true;
00079
00080 if (me->button() == Qt::LeftButton) {
00081 m_inMoveArea = true;
00082 }
00083
00084 if (!m_widget->m_bSelected) {
00085 selectMultiple(me);
00086 } else if (!m_rightButtonDown) {
00087 m_wasSelected = false;
00088 }
00089 return;
00090 }
00091
00092 m_shiftPressed = false;
00093
00094 int count = m_widget->m_pView->getSelectCount(true);
00095 if (me->button() == Qt::LeftButton) {
00096 if (m_widget->m_bSelected && count > 1) {
00097
00098 m_inMoveArea = true;
00099 lastUpdate.start();
00100 return;
00101 }
00102
00103 if (isInResizeArea(me)) {
00104 m_inResizeArea = true;
00105 } else {
00106 m_inMoveArea = true;
00107 }
00108 }
00109
00110
00111 if (!m_widget->m_bSelected || count > 1) {
00112 selectSingle(me);
00113 } else if (!m_rightButtonDown) {
00114 m_wasSelected = false;
00115 }
00116 }
00117
00118 void UMLWidgetController::mouseMoveEvent(QMouseEvent* me) {
00119 if (!m_leftButtonDown)
00120 return;
00121
00122 if (m_inResizeArea) {
00123 resize(me);
00124 return;
00125 }
00126
00127 if (!m_moved) {
00128 UMLApp::app()->getDocument()->writeToStatusBar(i18n("Hold shift or ctrl to move in X axis. Hold shift and control to move in Y axis. Right button click to cancel move."));
00129
00130 m_moved = true;
00131
00132 m_widget->m_bStartMove = true;
00133
00134 setSelectionBounds();
00135 }
00136
00137 QPoint positionDifference = getPositionDifference(me);
00138 int diffX = positionDifference.x();
00139 int diffY = positionDifference.y();
00140
00141 if ((me->state() & Qt::ShiftButton) && (me->state() & Qt::ControlButton)) {
00142
00143 diffX = 0;
00144 } else if ((me->state() & Qt::ShiftButton) || (me->state() & Qt::ControlButton)) {
00145
00146 diffY = 0;
00147 }
00148
00149
00150
00151 constrainMovementForAllWidgets(diffX, diffY);
00152
00153
00154
00155
00156 if (diffX == 0 && diffY == 0) {
00157 return;
00158 }
00159
00160 UMLWidgetListIt it(m_selectedWidgetsList);
00161 UMLWidget* widget;
00162 it.toFirst();
00163
00164 bool update = false;
00165 if (lastUpdate.elapsed() > 25) {
00166 update = true;
00167 lastUpdate.restart();
00168
00169
00170
00171
00172 m_widget->adjustUnselectedAssocs(diffX, diffY);
00173 }
00174
00175 while ((widget = it.current()) != 0) {
00176 ++it;
00177 widget->getWidgetController()->moveWidgetBy(diffX, diffY);
00178 }
00179
00180
00181
00182 AssociationWidgetList awl = m_widget->m_pView->getSelectedAssocs();
00183 AssociationWidget *aw = NULL;
00184 for (AssociationWidgetListIt ai(awl); (aw = ai.current()) != NULL; ++ai) {
00185 if (aw->getSelected()) {
00186 aw->moveEntireAssoc(diffX, diffY);
00187 }
00188 }
00189
00190 m_widget->m_pView->resizeCanvasToItems();
00191 updateSelectionBounds(diffX, diffY);
00192 }
00193
00194 void UMLWidgetController::mouseReleaseEvent(QMouseEvent *me) {
00195 if (me->button() != Qt::LeftButton && me->button() != Qt::RightButton) {
00196 if (m_middleButtonDown) {
00197 m_middleButtonDown = false;
00198 resetSelection();
00199 }
00200 } else if (me->button() == Qt::LeftButton) {
00201 if (m_leftButtonDown) {
00202 m_leftButtonDown = false;
00203
00204 if (!m_moved && !m_resized) {
00205 if (!m_shiftPressed && (m_widget->m_pView->getSelectCount(true) > 1)) {
00206 selectSingle(me);
00207 } else if (!m_wasSelected) {
00208 deselect(me);
00209 }
00210 } else {
00211 if (m_moved) {
00212 m_moved = false;
00213
00214
00215
00216 UMLWidgetListIt it(m_selectedWidgetsList);
00217 UMLWidget* widget;
00218 it.toFirst();
00219 while ((widget = it.current()) != 0) {
00220 ++it;
00221 widget->adjustAssocs(widget->getX(), widget->getY());
00222 }
00223
00224 m_widget->m_bStartMove = false;
00225 } else {
00226 m_resized = false;
00227 }
00228
00229 if ((m_inMoveArea && wasPositionChanged()) ||
00230 (m_inResizeArea && wasSizeChanged())) {
00231 m_widget->m_pDoc->setModified(true);
00232 }
00233
00234 UMLApp::app()->getDocument()->writeToStatusBar(m_oldStatusBarMsg);
00235 }
00236
00237 if (m_inResizeArea) {
00238 m_inResizeArea = false;
00239 m_widget->m_pView->setCursor(KCursor::arrowCursor());
00240 } else {
00241 m_inMoveArea = false;
00242 }
00243 }
00244 } else if (me->button() == Qt::RightButton) {
00245 if (m_rightButtonDown) {
00246 m_rightButtonDown = false;
00247 showPopupMenu(me);
00248 } else if (m_leftButtonDown) {
00249
00250 QMouseEvent move(QMouseEvent::MouseMove,
00251 QPoint(m_oldX + m_pressOffsetX, m_oldY + m_pressOffsetY),
00252 Qt::LeftButton, Qt::NoButton);
00253 mouseMoveEvent(&move);
00254 QMouseEvent release(QMouseEvent::MouseButtonRelease,
00255 QPoint(m_oldX + m_pressOffsetX, m_oldY + m_pressOffsetY),
00256 Qt::LeftButton, Qt::NoButton);
00257 mouseReleaseEvent(&release);
00258 }
00259 }
00260
00261
00262 UMLWidget *bkgnd = m_widget->m_pView->getWidgetAt(me->pos());
00263 if (bkgnd) {
00264
00265
00266 m_widget->setZ(bkgnd->getZ() + 1);
00267 } else {
00268 m_widget->setZ(0);
00269 }
00270 }
00271
00272 void UMLWidgetController::mouseDoubleClickEvent(QMouseEvent *me) {
00273 if (me->button() != Qt::LeftButton) {
00274 return;
00275 }
00276
00277 selectSingle(me);
00278
00279 doMouseDoubleClick(me);
00280 }
00281
00282 bool UMLWidgetController::isInResizeArea(QMouseEvent *me) {
00283 const int m = 10;
00284
00285 if (m_widget->m_bResizable &&
00286 me->x() >= (m_widget->getX() + m_widget->width() - m) &&
00287 me->y() >= (m_widget->getY() + m_widget->height() - m)) {
00288 m_widget->m_pView->setCursor(getResizeCursor());
00289 return true;
00290 } else {
00291 m_widget->m_pView->setCursor(KCursor::arrowCursor());
00292 return false;
00293 }
00294 }
00295
00296 QCursor UMLWidgetController::getResizeCursor() {
00297 return KCursor::sizeFDiagCursor();
00298 }
00299
00300 void UMLWidgetController::resizeWidget(int newW, int newH) {
00301 m_widget->setSize(newW, newH);
00302 }
00303
00304 void UMLWidgetController::moveWidgetBy(int diffX, int diffY) {
00305 m_widget->setX(m_widget->getX() + diffX);
00306 m_widget->setY(m_widget->getY() + diffY);
00307 }
00308
00309 void UMLWidgetController::constrainMovementForAllWidgets(int &, int &) {
00310 }
00311
00312 void UMLWidgetController::doMouseDoubleClick(QMouseEvent *) {
00313 m_widget->slotMenuSelection(ListPopupMenu::mt_Properties);
00314 }
00315
00316 void UMLWidgetController::resetSelection() {
00317 m_widget->m_pView->clearSelected();
00318 m_widget->m_pView->resetToolbar();
00319 m_widget->setSelected(false);
00320
00321 m_wasSelected = false;
00322 }
00323
00324 void UMLWidgetController::selectSingle(QMouseEvent *me) {
00325 m_widget->m_pView->clearSelected();
00326
00327
00328
00329 selectMultiple(me);
00330 }
00331
00332 void UMLWidgetController::selectMultiple(QMouseEvent *me) {
00333 m_widget->m_bSelected = true;
00334 m_widget->setSelected(m_widget->m_bSelected);
00335 m_widget->m_pView->setSelected(m_widget, me);
00336
00337 m_wasSelected = true;
00338 }
00339
00340 void UMLWidgetController::deselect(QMouseEvent *me) {
00341 m_widget->m_bSelected = false;
00342 m_widget->setSelected(m_widget->m_bSelected);
00343 m_widget->m_pView->setSelected(m_widget, me);
00344
00345 }
00346
00347 void UMLWidgetController::saveWidgetValues(QMouseEvent *me) {
00348 m_pressOffsetX = me->x() - m_widget->getX();
00349 m_pressOffsetY = me->y() - m_widget->getY();
00350
00351 m_oldX = m_widget->getX();
00352 m_oldY = m_widget->getY();
00353
00354 m_oldW = m_widget->width();
00355 m_oldH = m_widget->height();
00356 }
00357
00358 void UMLWidgetController::setSelectionBounds() {
00359 if (m_widget->m_pView->getSelectCount() > 0) {
00360 m_selectedWidgetsList.clear();
00361 m_widget->m_pView->getSelectedWidgets(m_selectedWidgetsList, false);
00362
00363 updateSelectionBounds(1, 1);
00364 }
00365 }
00366
00367
00368 void UMLWidgetController::updateSelectionBounds(int diffX, int diffY) {
00369 if (diffX != 0) {
00370 m_minSelectedX = getSmallestX(m_selectedWidgetsList);
00371 m_maxSelectedX = getBiggestX(m_selectedWidgetsList);
00372 }
00373 if (diffY != 0) {
00374 m_minSelectedY = getSmallestY(m_selectedWidgetsList);
00375 m_maxSelectedY = getBiggestY(m_selectedWidgetsList);
00376 }
00377 }
00378
00379 void UMLWidgetController::resize(QMouseEvent *me) {
00380 UMLApp::app()->getDocument()->writeToStatusBar(i18n("Hold shift or ctrl to move in X axis. Hold shift and control to move in Y axis. Right button click to cancel resize."));
00381
00382 m_resized = true;
00383
00384 int newW = m_oldW + me->x() - m_widget->getX() - m_pressOffsetX;
00385 int newH = m_oldH + me->y() - m_widget->getY() - m_pressOffsetY;
00386
00387 if ((me->state() & Qt::ShiftButton) && (me->state() & Qt::ControlButton)) {
00388
00389 newW = m_oldW;
00390 } else if ((me->state() & Qt::ShiftButton) || (me->state() & Qt::ControlButton)) {
00391
00392 newH = m_oldH;
00393 }
00394
00395 m_widget->constrain(newW, newH);
00396 resizeWidget(newW, newH);
00397 m_widget->adjustAssocs(m_widget->getX(), m_widget->getY());
00398
00399 m_widget->m_pView->resizeCanvasToItems();
00400 }
00401
00402
00403 int UMLWidgetController::getSmallestX(const UMLWidgetList &widgetList) {
00404 UMLWidgetListIt it(widgetList);
00405 UMLWidget* widget;
00406
00407 widget = it.toFirst();
00408
00409 if (NULL == widget) return 0;
00410 int smallestX = widget->getX();
00411 ++it;
00412
00413 while ((widget = it.current()) != 0) {
00414 ++it;
00415 if (smallestX > widget->getX())
00416 smallestX = widget->getX();
00417 }
00418
00419 return smallestX;
00420 }
00421
00422
00423 int UMLWidgetController::getSmallestY(const UMLWidgetList &widgetList) {
00424 UMLWidgetListIt it(widgetList);
00425 UMLWidget* widget;
00426
00427 widget = it.toFirst();
00428
00429 if (NULL == widget) return 0;
00430 int smallestY = widget->getY();
00431 ++it;
00432
00433 while ((widget = it.current()) != 0) {
00434 ++it;
00435 if (smallestY > widget->getY())
00436 smallestY = widget->getY();
00437 }
00438
00439 return smallestY;
00440 }
00441
00442
00443 int UMLWidgetController::getBiggestX(const UMLWidgetList &widgetList) {
00444 UMLWidgetListIt it(widgetList);
00445 UMLWidget* widget;
00446
00447 widget = it.toFirst();
00448
00449 if (NULL == widget) return 0;
00450 int biggestX = widget->getX();
00451 biggestX += it.current()->getWidth();
00452 ++it;
00453
00454 while ((widget = it.current()) != 0) {
00455 ++it;
00456 if (biggestX < widget->getX() + widget->getWidth())
00457 biggestX = widget->getX() + widget->getWidth();
00458 }
00459
00460 return biggestX;
00461 }
00462
00463
00464 int UMLWidgetController::getBiggestY(const UMLWidgetList &widgetList) {
00465 UMLWidgetListIt it(widgetList);
00466 UMLWidget* widget;
00467
00468 widget = it.toFirst();
00469
00470 if (NULL == widget) return 0;
00471 int biggestY = widget->getY();
00472 biggestY += it.current()->getHeight();
00473 ++it;
00474
00475 while ((widget = it.current()) != 0) {
00476 ++it;
00477 if (biggestY < widget->getY() + widget->getHeight())
00478 biggestY = widget->getY() + widget->getHeight();
00479 }
00480
00481 return biggestY;
00482 }
00483
00484 QPoint UMLWidgetController::getPositionDifference(QMouseEvent* me) {
00485
00486
00487
00488
00489
00490
00491
00492
00493 int newX = me->x() + m_widget->getX() - m_oldX - m_pressOffsetX;
00494 int newY = me->y() + m_widget->getY() - m_oldY - m_pressOffsetY;
00495 int maxX = m_widget->m_pView->canvas()->width();
00496 int maxY = m_widget->m_pView->canvas()->height();
00497
00498 m_oldX = newX;
00499 m_oldY = newY;
00500
00501 if (newX + (m_minSelectedX - m_widget->getX()) < 0) {
00502
00503 newX = m_widget->getX() - m_minSelectedX;
00504 }
00505 if (newY + (m_minSelectedY - m_widget->getY()) < 0) {
00506
00507 newY = m_widget->getY() - m_minSelectedY;
00508 }
00509 if (newX + (m_maxSelectedX - m_widget->getX()) > maxX) {
00510
00511 newX = maxX - (m_maxSelectedX - m_widget->getX());
00512 }
00513 if (newY + (m_maxSelectedY - m_widget->getY()) > maxY) {
00514
00515 newY = maxY - (m_maxSelectedY - m_widget->getY());
00516 }
00517
00518 newX -= m_widget->getX();
00519 newY -= m_widget->getY();
00520
00521 return QPoint(newX, newY);
00522 }
00523
00524 void UMLWidgetController::showPopupMenu(QMouseEvent *me) {
00525
00526 if (m_widget->m_pMenu) {
00527 return;
00528 }
00529 m_widget->startPopupMenu(me->globalPos());
00530 }
00531
00532 bool UMLWidgetController::wasSizeChanged() {
00533 return m_oldW != m_widget->getWidth() || m_oldH != m_widget->getHeight();
00534 }
00535
00536 bool UMLWidgetController::wasPositionChanged() {
00537 return m_oldX != m_widget->getX() || m_oldY != m_widget->getY();
00538 }
This file is part of the documentation for umbrello Version 3.1.0.