diff --git a/src/board/UBBoardView.cpp b/src/board/UBBoardView.cpp index 70fd7368..7334ad49 100644 --- a/src/board/UBBoardView.cpp +++ b/src/board/UBBoardView.cpp @@ -95,6 +95,7 @@ UBBoardView::UBBoardView (UBBoardController* pController, QWidget* pParent, bool , mLongPressInterval(1000) , mIsDragInProgress(false) , mMultipleSelectionIsEnabled(false) + , _movingItem(nullptr) , bIsControl(isControl) , bIsDesktop(isDesktop) { @@ -119,6 +120,7 @@ UBBoardView::UBBoardView (UBBoardController* pController, int pStartLayer, int p , mLongPressInterval(1000) , mIsDragInProgress(false) , mMultipleSelectionIsEnabled(false) + , _movingItem(nullptr) , bIsControl(isControl) , bIsDesktop(isDesktop) { @@ -178,7 +180,7 @@ void UBBoardView::init () unsetCursor(); - movingItem = NULL; + setMovingItem(NULL); mWidgetMoved = false; } @@ -482,7 +484,7 @@ void UBBoardView::handleItemsSelection(QGraphicsItem *item) if (item) { // item has group as first parent - it is any item or UBGraphicsStrokesGroup. - if(item->parentItem() && UBGraphicsGroupContainerItem::Type == movingItem->parentItem()->type()) + if(item->parentItem() && UBGraphicsGroupContainerItem::Type == getMovingItem()->parentItem()->type()) return; // delegate buttons shouldn't selected @@ -578,7 +580,7 @@ Here we determines cases when items should to get mouse press event at pressing case UBGraphicsGroupContainerItem::Type: if(currentTool == UBStylusTool::Play) { - movingItem = NULL; + setMovingItem(NULL); return true; } return false; @@ -648,10 +650,10 @@ bool UBBoardView::itemShouldBeMoved(QGraphicsItem *item) if (!(mMouseButtonIsPressed || mTabletStylusIsPressed)) return false; - if (movingItem->data(UBGraphicsItemData::ItemLocked).toBool()) + if (getMovingItem()->data(UBGraphicsItemData::ItemLocked).toBool()) return false; - if (movingItem->parentItem() && UBGraphicsGroupContainerItem::Type == movingItem->parentItem()->type() && !movingItem->isSelected() && movingItem->parentItem()->isSelected()) + if (getMovingItem()->parentItem() && UBGraphicsGroupContainerItem::Type == getMovingItem()->parentItem()->type() && !getMovingItem()->isSelected() && getMovingItem()->parentItem()->isSelected()) return false; UBStylusTool::Enum currentTool = (UBStylusTool::Enum)UBDrawingController::drawingController()->stylusTool(); @@ -759,13 +761,13 @@ void UBBoardView::handleItemMousePress(QMouseEvent *event) // Determining item who will take mouse press event //all other items will be deselected and if all item will be deselected, then // wrong item can catch mouse press. because selected items placed on the top - movingItem = determineItemToPress(movingItem); - handleItemsSelection(movingItem); + setMovingItem(determineItemToPress(getMovingItem())); + handleItemsSelection(getMovingItem()); if (isMultipleSelectionEnabled()) return; - if (itemShouldReceiveMousePressEvent(movingItem)){ + if (itemShouldReceiveMousePressEvent(getMovingItem())){ QGraphicsView::mousePressEvent (event); QGraphicsItem* item = determineItemToPress(scene()->itemAt(this->mapToScene(event->localPos().toPoint()), transform())); @@ -780,17 +782,17 @@ void UBBoardView::handleItemMousePress(QMouseEvent *event) if ((*it)->pos().x() < 0 || (*it)->pos().y() < 0) (*it)->setPos(0,item->boundingRect().size().height()); } - movingItem = item; + setMovingItem(item); } else { - if (movingItem) + if (getMovingItem()) { - UBGraphicsItem *graphicsItem = dynamic_cast(movingItem); + UBGraphicsItem *graphicsItem = dynamic_cast(getMovingItem()); if (graphicsItem) graphicsItem->Delegate()->startUndoStep(); - movingItem->clearFocus(); + getMovingItem()->clearFocus(); } if (suspendedMousePressEvent) @@ -799,7 +801,7 @@ void UBBoardView::handleItemMousePress(QMouseEvent *event) suspendedMousePressEvent = NULL; } - if (itemShouldReceiveSuspendedMousePressEvent(movingItem)) + if (itemShouldReceiveSuspendedMousePressEvent(getMovingItem())) { suspendedMousePressEvent = new QMouseEvent(event->type(), event->pos(), event->button(), event->buttons(), event->modifiers()); } @@ -809,14 +811,14 @@ void UBBoardView::handleItemMousePress(QMouseEvent *event) void UBBoardView::handleItemMouseMove(QMouseEvent *event) { // determine item to move (maybee we need to move group of item or his parent. - movingItem = determineItemToMove(movingItem); + setMovingItem(determineItemToMove(getMovingItem())); // items should be moved not every mouse move. - if (movingItem && itemShouldBeMoved(movingItem) && (mMouseButtonIsPressed || mTabletStylusIsPressed)) + if (getMovingItem() && itemShouldBeMoved(getMovingItem()) && (mMouseButtonIsPressed || mTabletStylusIsPressed)) { QPointF scenePos = mapToScene(event->pos()); - QPointF newPos = movingItem->pos() + scenePos - mLastPressedMousePos; - movingItem->setPos(newPos); + QPointF newPos = getMovingItem()->pos() + scenePos - mLastPressedMousePos; + getMovingItem()->setPos(newPos); mLastPressedMousePos = scenePos; mWidgetMoved = true; event->accept(); @@ -826,21 +828,21 @@ void UBBoardView::handleItemMouseMove(QMouseEvent *event) QPointF posBeforeMove; QPointF posAfterMove; - if (movingItem) - posBeforeMove = movingItem->pos(); + if (getMovingItem()) + posBeforeMove = getMovingItem()->pos(); QGraphicsView::mouseMoveEvent (event); - if (movingItem) - posAfterMove = movingItem->pos(); + if (getMovingItem()) + posAfterMove = getMovingItem()->pos(); mWidgetMoved = ((posAfterMove-posBeforeMove).manhattanLength() != 0); // a cludge for terminate moving of w3c widgets. // in some cases w3c widgets catches mouse move and doesn't sends that events to web page, // at simple - in google map widget - mouse move events doesn't comes to web page from rectangle of wearch bar on bottom right corner of widget. - if (movingItem && mWidgetMoved && UBGraphicsW3CWidgetItem::Type == movingItem->type()) - movingItem->setPos(posBeforeMove); + if (getMovingItem() && mWidgetMoved && UBGraphicsW3CWidgetItem::Type == getMovingItem()->type()) + getMovingItem()->setPos(posBeforeMove); } } @@ -992,7 +994,7 @@ void UBBoardView::mousePressEvent (QMouseEvent *event) } mMouseDownPos = event->pos (); - movingItem = scene()->itemAt(this->mapToScene(event->localPos().toPoint()), QTransform()); + setMovingItem(scene()->itemAt(this->mapToScene(event->localPos().toPoint()), QTransform())); if (event->button () == Qt::LeftButton && isInteractive()) { @@ -1024,11 +1026,11 @@ void UBBoardView::mousePressEvent (QMouseEvent *event) return; } - if (scene()->backgroundObject() == movingItem) - movingItem = NULL; + if (scene()->backgroundObject() == getMovingItem()) + setMovingItem(NULL); connect(&mLongPressTimer, SIGNAL(timeout()), this, SLOT(longPressEvent())); - if (!movingItem && !mController->cacheIsVisible()) + if (!getMovingItem() && !mController->cacheIsVisible()) mLongPressTimer.start(); handleItemMousePress(event); @@ -1143,7 +1145,7 @@ void UBBoardView::mouseMoveEvent (QMouseEvent *event) bool rubberMove = (currentTool != (UBStylusTool::Play)) && (mMouseButtonIsPressed || mTabletStylusIsPressed) - && !movingItem; + && !getMovingItem(); if (rubberMove) { QRect bandRect(mMouseDownPos, event->pos()); @@ -1229,6 +1231,11 @@ void UBBoardView::mouseMoveEvent (QMouseEvent *event) } +void UBBoardView::movingItemDestroyed(QObject*) +{ + setMovingItem(nullptr); +} + void UBBoardView::mouseReleaseEvent (QMouseEvent *event) { UBStylusTool::Enum currentTool = (UBStylusTool::Enum)UBDrawingController::drawingController ()->stylusTool (); @@ -1245,60 +1252,60 @@ void UBBoardView::mouseReleaseEvent (QMouseEvent *event) return; } - UBGraphicsItem *graphicsItem = dynamic_cast(movingItem); + UBGraphicsItem *graphicsItem = dynamic_cast(getMovingItem()); if (graphicsItem) graphicsItem->Delegate()->commitUndoStep(); bool bReleaseIsNeed = true; - if (movingItem != determineItemToPress(scene()->itemAt(this->mapToScene(event->localPos().toPoint()), QTransform()))) + if (getMovingItem() != determineItemToPress(scene()->itemAt(this->mapToScene(event->localPos().toPoint()), QTransform()))) { - movingItem = NULL; + setMovingItem(nullptr); bReleaseIsNeed = false; } if (mWidgetMoved) { mWidgetMoved = false; - movingItem = NULL; + setMovingItem(nullptr); } else - if (movingItem && (!isCppTool(movingItem) || UBGraphicsCurtainItem::Type == movingItem->type())) + if (getMovingItem() && (!isCppTool(getMovingItem()) || UBGraphicsCurtainItem::Type == getMovingItem()->type())) { if (suspendedMousePressEvent) { QGraphicsView::mousePressEvent(suspendedMousePressEvent); // suspendedMousePressEvent is deleted by old Qt event loop - movingItem = NULL; + setMovingItem(NULL); delete suspendedMousePressEvent; suspendedMousePressEvent = NULL; bReleaseIsNeed = true; } else { - if (isUBItem(movingItem) && - DelegateButton::Type != movingItem->type() && - UBGraphicsDelegateFrame::Type != movingItem->type() && - UBGraphicsCache::Type != movingItem->type() && - QGraphicsWebView::Type != movingItem->type() && // for W3C widgets as Tools. - !(!isMultipleSelectionEnabled() && movingItem->parentItem() && UBGraphicsWidgetItem::Type == movingItem->type() && UBGraphicsGroupContainerItem::Type == movingItem->parentItem()->type())) + if (isUBItem(getMovingItem()) && + DelegateButton::Type != getMovingItem()->type() && + UBGraphicsDelegateFrame::Type != getMovingItem()->type() && + UBGraphicsCache::Type != getMovingItem()->type() && + QGraphicsWebView::Type != getMovingItem()->type() && // for W3C widgets as Tools. + !(!isMultipleSelectionEnabled() && getMovingItem()->parentItem() && UBGraphicsWidgetItem::Type == getMovingItem()->type() && UBGraphicsGroupContainerItem::Type == getMovingItem()->parentItem()->type())) { bReleaseIsNeed = false; - if (movingItem->isSelected() && isMultipleSelectionEnabled()) - movingItem->setSelected(false); + if (getMovingItem()->isSelected() && isMultipleSelectionEnabled()) + getMovingItem()->setSelected(false); else - if (movingItem->parentItem() && movingItem->parentItem()->isSelected() && isMultipleSelectionEnabled()) - movingItem->parentItem()->setSelected(false); + if (getMovingItem()->parentItem() && getMovingItem()->parentItem()->isSelected() && isMultipleSelectionEnabled()) + getMovingItem()->parentItem()->setSelected(false); else { - if (movingItem->isSelected()) + if (getMovingItem()->isSelected()) bReleaseIsNeed = true; - UBGraphicsTextItem* textItem = dynamic_cast(movingItem); - UBGraphicsMediaItem* movieItem = dynamic_cast(movingItem); + UBGraphicsTextItem* textItem = dynamic_cast(getMovingItem()); + UBGraphicsMediaItem* movieItem = dynamic_cast(getMovingItem()); if(textItem) textItem->setSelected(true); else if(movieItem) movieItem->setSelected(true); else - movingItem->setSelected(true); + getMovingItem()->setSelected(true); } } @@ -1315,20 +1322,20 @@ void UBBoardView::mouseReleaseEvent (QMouseEvent *event) else if (currentTool == UBStylusTool::Text) { bool bReleaseIsNeed = true; - if (movingItem != determineItemToPress(scene()->itemAt(this->mapToScene(event->localPos().toPoint()), QTransform()))) + if (getMovingItem() != determineItemToPress(scene()->itemAt(this->mapToScene(event->localPos().toPoint()), QTransform()))) { - movingItem = NULL; + setMovingItem(NULL); bReleaseIsNeed = false; } - UBGraphicsItem *graphicsItem = dynamic_cast(movingItem); + UBGraphicsItem *graphicsItem = dynamic_cast(getMovingItem()); if (graphicsItem) graphicsItem->Delegate()->commitUndoStep(); if (mWidgetMoved) { mWidgetMoved = false; - movingItem = NULL; + setMovingItem(NULL); if (scene () && mRubberBand && mIsCreatingTextZone) { QRect rubberRect = mRubberBand->geometry (); @@ -1343,37 +1350,37 @@ void UBBoardView::mouseReleaseEvent (QMouseEvent *event) textItem->setFocus(); } } - else if (movingItem && (!isCppTool(movingItem) || UBGraphicsCurtainItem::Type == movingItem->type())) + else if (getMovingItem() && (!isCppTool(getMovingItem()) || UBGraphicsCurtainItem::Type == getMovingItem()->type())) { if (suspendedMousePressEvent) { QGraphicsView::mousePressEvent(suspendedMousePressEvent); // suspendedMousePressEvent is deleted by old Qt event loop - movingItem = NULL; + setMovingItem(NULL); delete suspendedMousePressEvent; suspendedMousePressEvent = NULL; bReleaseIsNeed = true; } else{ - if (isUBItem(movingItem) && - DelegateButton::Type != movingItem->type() && - QGraphicsSvgItem::Type != movingItem->type() && - UBGraphicsDelegateFrame::Type != movingItem->type() && - UBGraphicsCache::Type != movingItem->type() && - QGraphicsWebView::Type != movingItem->type() && // for W3C widgets as Tools. - !(!isMultipleSelectionEnabled() && movingItem->parentItem() && UBGraphicsWidgetItem::Type == movingItem->type() && UBGraphicsGroupContainerItem::Type == movingItem->parentItem()->type())) + if (isUBItem(getMovingItem()) && + DelegateButton::Type != getMovingItem()->type() && + QGraphicsSvgItem::Type != getMovingItem()->type() && + UBGraphicsDelegateFrame::Type != getMovingItem()->type() && + UBGraphicsCache::Type != getMovingItem()->type() && + QGraphicsWebView::Type != getMovingItem()->type() && // for W3C widgets as Tools. + !(!isMultipleSelectionEnabled() && getMovingItem()->parentItem() && UBGraphicsWidgetItem::Type == getMovingItem()->type() && UBGraphicsGroupContainerItem::Type == getMovingItem()->parentItem()->type())) { bReleaseIsNeed = false; - if (movingItem->isSelected() && isMultipleSelectionEnabled()) - movingItem->setSelected(false); + if (getMovingItem()->isSelected() && isMultipleSelectionEnabled()) + getMovingItem()->setSelected(false); else - if (movingItem->parentItem() && movingItem->parentItem()->isSelected() && isMultipleSelectionEnabled()) - movingItem->parentItem()->setSelected(false); + if (getMovingItem()->parentItem() && getMovingItem()->parentItem()->isSelected() && isMultipleSelectionEnabled()) + getMovingItem()->parentItem()->setSelected(false); else { - if (movingItem->isSelected()) + if (getMovingItem()->isSelected()) bReleaseIsNeed = true; - movingItem->setSelected(true); + getMovingItem()->setSelected(true); } } @@ -1394,14 +1401,14 @@ void UBBoardView::mouseReleaseEvent (QMouseEvent *event) } if (mWidgetMoved) { - movingItem->setSelected(false); - movingItem = NULL; + getMovingItem()->setSelected(false); + setMovingItem(NULL); mWidgetMoved = false; } else { if (suspendedMousePressEvent) { QGraphicsView::mousePressEvent(suspendedMousePressEvent); // suspendedMousePressEvent is deleted by old Qt event loop - movingItem = NULL; + setMovingItem(NULL); delete suspendedMousePressEvent; suspendedMousePressEvent = NULL; } @@ -1453,7 +1460,7 @@ void UBBoardView::mouseReleaseEvent (QMouseEvent *event) mMouseButtonIsPressed = false; mPendingStylusReleaseEvent = false; mTabletStylusIsPressed = false; - movingItem = NULL; + setMovingItem(NULL); mLongPressTimer.stop(); emit mouseReleased(); diff --git a/src/board/UBBoardView.h b/src/board/UBBoardView.h index 07694701..fd3ed451 100644 --- a/src/board/UBBoardView.h +++ b/src/board/UBBoardView.h @@ -156,7 +156,32 @@ private: bool mWidgetMoved; QPointF mLastPressedMousePos; - QGraphicsItem *movingItem; + + + /* when an item is moved around, the tracking must stop if the object is deleted */ + QGraphicsItem *_movingItem; + + QGraphicsItem *getMovingItem() { + return _movingItem; + } + + void setMovingItem(QGraphicsItem *item) { + // if the current moving item is a qobject, it MUST be disconnected + if (_movingItem) { + QObject *moving_item_obj = dynamic_cast(_movingItem); + if (moving_item_obj != nullptr) + disconnect(moving_item_obj, &QObject::destroyed, this, &UBBoardView::movingItemDestroyed); + } + + // attach the new moving item if relevant + if (item) { + QObject *item_obj = dynamic_cast(item); + if (item_obj != nullptr) + connect(item_obj, &QObject::destroyed, this, &UBBoardView::movingItemDestroyed); + } + _movingItem = item; + } + QMouseEvent *suspendedMousePressEvent; bool moveRubberBand; @@ -177,11 +202,10 @@ private: static bool hasSelectedParents(QGraphicsItem * item); private slots: - void settingChanged(QVariant newValue); + void movingItemDestroyed(QObject* item = nullptr); public slots: - void virtualKeyboardActivated(bool b); void longPressEvent();