| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #include "lc_actionpreselectionawarebase.h" |
| |
|
| | #include <QMouseEvent> |
| |
|
| | #include "lc_cursoroverlayinfo.h" |
| | #include "lc_graphicviewport.h" |
| | #include "rs_document.h" |
| | #include "rs_selection.h" |
| | #include "rs_settings.h" |
| |
|
| | LC_ActionPreSelectionAwareBase::LC_ActionPreSelectionAwareBase( |
| | const char *name, LC_ActionContext *actionContext, RS2::ActionType actionType, |
| | const QList<RS2::EntityType> &entityTypeList, const bool countSelectionDeep) |
| | :RS_ActionSelectBase(name, actionContext, actionType, entityTypeList), |
| | m_countDeep(countSelectionDeep){} |
| |
|
| | void LC_ActionPreSelectionAwareBase::doTrigger() { |
| | bool keepSelected = LC_GET_ONE_BOOL("Modify", "KeepModifiedSelected", true); |
| | doTrigger(keepSelected); |
| | |
| | } |
| |
|
| | LC_ActionPreSelectionAwareBase::~LC_ActionPreSelectionAwareBase() { |
| | m_selectedEntities.clear(); |
| | } |
| |
|
| | void LC_ActionPreSelectionAwareBase::doInitWithContextEntity(RS_Entity* contextEntity, [[maybe_unused]]const RS_Vector& clickPos) { |
| | if (isForceSelectContextEntity()) { |
| | contextEntity->setSelected(true); |
| | redrawDrawing(); |
| | } |
| | m_selectedEntities.push_back(contextEntity); |
| | onSelectionCompleted(true, true); |
| | } |
| |
|
| | void LC_ActionPreSelectionAwareBase::init(int status) { |
| | RS_PreviewActionInterface::init(status); |
| | if (status < 0){ |
| | m_selectedEntities.clear(); |
| | } |
| | else{ |
| | if (!m_selectionComplete) { |
| | unsigned int selectedCount = countSelectedEntities(); |
| | if (selectedCount > 0) { |
| | onSelectionCompleted(false, true); |
| | } |
| | } |
| | } |
| | } |
| |
|
| | unsigned int LC_ActionPreSelectionAwareBase::countSelectedEntities() { |
| | m_selectedEntities.clear(); |
| | m_document->collectSelected(m_selectedEntities, m_countDeep, m_catchForSelectionEntityTypes); |
| | unsigned int selectedCount = m_selectedEntities.size(); |
| | |
| | return selectedCount; |
| | } |
| |
|
| | void LC_ActionPreSelectionAwareBase::selectionFinishedByKey([[maybe_unused]]QKeyEvent *e, bool escape) { |
| | if (escape){ |
| | m_selectedEntities.clear(); |
| | finish(false); |
| | } |
| | else{ |
| | if (!m_selectionComplete) { |
| | onSelectionCompleted(false,false); |
| | } |
| | } |
| | } |
| |
|
| | void LC_ActionPreSelectionAwareBase::mousePressEvent(QMouseEvent * e) { |
| | if (!m_selectionComplete){ |
| | if (e->button() == Qt::LeftButton){ |
| | m_selectionCorner1 = toGraph(e); |
| | } |
| | } |
| | } |
| |
|
| | void LC_ActionPreSelectionAwareBase::proceedSelectedEntity(LC_MouseEvent* e) { |
| | if (e->isControl) { |
| | onSelectionCompleted(true, false); |
| | } |
| | } |
| |
|
| | void LC_ActionPreSelectionAwareBase::onMouseLeftButtonRelease(int status, LC_MouseEvent *e) { |
| | if (m_selectionComplete){ |
| | onMouseLeftButtonReleaseSelected(status, e); |
| | } |
| | else{ |
| | if (m_inBoxSelectionMode){ |
| | RS_Vector mouse = e->graphPoint; |
| | |
| | deletePreviewAndHighlights(); |
| |
|
| | |
| | RS_Vector ucsP1 = toUCS(m_selectionCorner1); |
| | RS_Vector ucsP2 = toUCS(mouse); |
| |
|
| | bool selectIntersecting = (ucsP1.x > ucsP2.x); |
| |
|
| | RS_Selection s(*m_container, m_viewport); |
| | bool performSelection = !e->isShift; |
| | bool alterSelectIntersecting = e->isControl; |
| | if (alterSelectIntersecting) { |
| | selectIntersecting = !selectIntersecting; |
| | } |
| |
|
| | |
| | RS_Vector wcsP1, wcsP2; |
| | m_viewport->worldBoundingBox(ucsP1, ucsP2, wcsP1, wcsP2); |
| |
|
| | if (m_catchForSelectionEntityTypes.isEmpty()){ |
| | s.selectWindow(RS2::EntityUnknown, wcsP1, wcsP2, performSelection, selectIntersecting); |
| | } |
| | else { |
| | s.selectWindow(m_catchForSelectionEntityTypes, wcsP1, wcsP2, performSelection, selectIntersecting); |
| | } |
| | updateSelectionWidget(); |
| | deletePreviewAndHighlights(); |
| | } |
| | else{ |
| | RS_Entity* entityToSelect = catchEntityByEvent(e, m_catchForSelectionEntityTypes); |
| | bool selectContour = e->isShift; |
| | if (selectEntity(entityToSelect, selectContour)) { |
| | proceedSelectedEntity(e); |
| | } |
| | } |
| | m_inBoxSelectionMode = false; |
| | m_selectionCorner1.valid = false; |
| | invalidateSnapSpot(); |
| | } |
| | } |
| |
|
| | void LC_ActionPreSelectionAwareBase::onMouseRightButtonRelease(int status, LC_MouseEvent *e) { |
| | if (m_selectionComplete) { |
| | onMouseRightButtonReleaseSelected(status, e); |
| | } |
| | else{ |
| | m_selectedEntities.clear(); |
| | finish(false); |
| | } |
| | } |
| |
|
| | void LC_ActionPreSelectionAwareBase::applyBoxSelectionModeIfNeeded(RS_Vector mouse) { |
| | if (m_selectionCorner1.valid && (m_viewport->toGuiDX(m_selectionCorner1.distanceTo(mouse)) > 10.0)){ |
| | m_inBoxSelectionMode = true; |
| | } |
| | } |
| |
|
| | void LC_ActionPreSelectionAwareBase::onMouseMoveEvent(int status, LC_MouseEvent *e) { |
| | if (m_selectionComplete){ |
| | onMouseMoveEventSelected(status, e); |
| | } |
| | else{ |
| | RS_Vector mouse = e->graphPoint; |
| | applyBoxSelectionModeIfNeeded(mouse); |
| | if (m_inBoxSelectionMode){ |
| | drawOverlayBox(m_selectionCorner1, mouse); |
| | if (m_infoCursorOverlayPrefs->enabled) { |
| | |
| | RS_Vector ucsP1 = toUCS(m_selectionCorner1); |
| | RS_Vector ucsP2 = toUCS(mouse); |
| | bool selectIntersecting = (ucsP1.x > ucsP2.x); |
| | bool deselect = e->isShift; |
| | bool alterSelectIntersecting = e->isControl; |
| | if (alterSelectIntersecting) { |
| | selectIntersecting = !selectIntersecting; |
| | } |
| | QString msg = deselect ? tr("De-Selecting") : tr("Selecting"); |
| | msg.append(tr(" entities ")); |
| | msg.append(selectIntersecting? tr("that intersect with box") : tr("that are within box")); |
| | m_infoCursorOverlayData->setZone2(msg); |
| | forceUpdateInfoCursor(mouse); |
| | } |
| | } |
| | else { |
| | selectionMouseMove(e); |
| | finishMouseMoveOnSelection(e); |
| | } |
| | } |
| | } |
| |
|
| | void LC_ActionPreSelectionAwareBase::drawSnapper() { |
| | if (m_selectionComplete) { |
| | RS_Snapper::drawSnapper(); |
| | } |
| | } |
| |
|
| | void LC_ActionPreSelectionAwareBase::updateMouseButtonHints() { |
| | if (m_selectionComplete){ |
| | updateMouseButtonHintsForSelected(getStatus()); |
| | } |
| | else{ |
| | if (m_inBoxSelectionMode){ |
| | updateMouseWidgetTRBack(tr("Choose second edge"), MOD_SHIFT_AND_CTRL(tr("Select/Deselect entities"), tr("Select Intersecting"))); |
| | } |
| | else { |
| | updateMouseButtonHintsForSelection(); |
| | } |
| | } |
| | } |
| |
|
| | void LC_ActionPreSelectionAwareBase::onSelectionCompleted([[maybe_unused]]bool singleEntity, bool fromInit) { |
| | setSelectionComplete(isAllowTriggerOnEmptySelection(), fromInit); |
| | updateMouseButtonHints(); |
| | if (m_selectionComplete) { |
| | trigger(); |
| | if (singleEntity) { |
| | deselectAll(); |
| | m_selectionComplete = false; |
| | } else { |
| | setStatus(-1); |
| | } |
| | updateSelectionWidget(); |
| | } |
| | } |
| |
|
| | void LC_ActionPreSelectionAwareBase::setSelectionComplete(bool allowEmptySelection, bool fromInit) { |
| | unsigned int selectedCount; |
| | if (fromInit) { |
| | selectedCount = m_selectedEntities.size(); |
| | } |
| | else{ |
| | selectedCount = countSelectedEntities(); |
| | } |
| | bool proceed = selectedCount > 0 || allowEmptySelection; |
| | if (proceed) { |
| | m_selectionComplete = true; |
| | updateMouseButtonHintsForSelected(getStatus()); |
| | } |
| | else{ |
| | commandMessage(tr("No valid entities selected, select them first")); |
| | } |
| | } |
| |
|
| | void LC_ActionPreSelectionAwareBase::updateMouseButtonHintsForSelected([[maybe_unused]]int status) { |
| | updateMouseWidget(); |
| | } |
| |
|
| | void LC_ActionPreSelectionAwareBase::onMouseLeftButtonReleaseSelected([[maybe_unused]]int status, [[maybe_unused]]LC_MouseEvent *pEvent) {} |
| |
|
| | void LC_ActionPreSelectionAwareBase::onMouseRightButtonReleaseSelected([[maybe_unused]]int status, [[maybe_unused]]LC_MouseEvent *pEvent) {} |
| |
|
| | void LC_ActionPreSelectionAwareBase::onMouseMoveEventSelected([[maybe_unused]] int status, [[maybe_unused]]LC_MouseEvent *event) {} |
| |
|
| | RS2::CursorType LC_ActionPreSelectionAwareBase::doGetMouseCursor(int status) { |
| | if (m_selectionComplete){ |
| | return doGetMouseCursorSelected(status); |
| | } |
| | else { |
| | return RS_ActionSelectBase::doGetMouseCursor(status); |
| | } |
| | } |
| |
|
| | RS2::CursorType LC_ActionPreSelectionAwareBase::doGetMouseCursorSelected([[maybe_unused]]int status) { |
| | return RS2::CadCursor; |
| | } |
| |
|
| | void LC_ActionPreSelectionAwareBase::finishMouseMoveOnSelection([[maybe_unused]]LC_MouseEvent *event) { |
| |
|
| | } |
| |
|
| | void LC_ActionPreSelectionAwareBase::doSelectEntity(RS_Entity *entityToSelect, bool selectContour) const { |
| | if (entityToSelect != nullptr){ |
| | RS_Selection s(*m_container, m_viewport); |
| | |
| | if (entityToSelect->isAtomic() && selectContour) { |
| | s.selectContour(entityToSelect); |
| | } |
| | else{ |
| | s.selectSingle(entityToSelect); |
| | } |
| | } |
| | } |
| |
|