diff --git a/include/svx/diagram/DiagramHelper_svx.hxx b/include/svx/diagram/DiagramHelper_svx.hxx index 0bdc15fd5457..b733daa09b3c 100644 --- a/include/svx/diagram/DiagramHelper_svx.hxx +++ b/include/svx/diagram/DiagramHelper_svx.hxx @@ -128,8 +128,10 @@ public: bool ForceThemePtrRecreation() const { return mbForceThemePtrRecreation; }; // connect/disconnect to/from Group - void connectToSdrObjGroup(const css::uno::Reference< css::drawing::XShape >& rTarget); - void disconnectFromSdrObjGroup(); + void connectToSdrObjGroup( + const css::uno::Reference< css::drawing::XShape >& rTarget, + std::shared_ptr< svx::diagram::DiagramHelper_svx >* mpDiagramHelperFromUndo); + void disconnectFromSdrObjGroup(bool bEnableUndo); void AddAdditionalVisualization(SdrHdlList& rHdlList); diff --git a/include/svx/strings.hrc b/include/svx/strings.hrc index 19377dbae397..3ba17481f7e3 100644 --- a/include/svx/strings.hrc +++ b/include/svx/strings.hrc @@ -207,6 +207,7 @@ #define STR_DragMethMovHdl NC_("STR_DragMethMovHdl", "Move reference-point") #define STR_DragMethObjOwn NC_("STR_DragMethObjOwn", "Geometrically change %1") #define STR_DiagramModelDataChange NC_("STR_DiagramModelDataChange", "Diagram change %1") +#define STR_DiagramModelDissolveData NC_("STR_DiagramModelDissolveData", "Diagram model dissolve %1") #define STR_DragMethMove NC_("STR_DragMethMove", "Move %1") #define STR_DragMethResize NC_("STR_DragMethResize", "Resize %1") #define STR_DragMethRotate NC_("STR_DragMethRotate", "Rotate %1") diff --git a/include/svx/svdundo.hxx b/include/svx/svdundo.hxx index 53fdfdbf6419..15d09ecea84a 100644 --- a/include/svx/svdundo.hxx +++ b/include/svx/svdundo.hxx @@ -49,6 +49,7 @@ class SdrObjGeoData; namespace svx { namespace diagram { class DiagramDataState; + class DiagramHelper_svx; }} /** @@ -243,6 +244,21 @@ public: virtual OUString GetComment() const override; }; +class UNLESS_MERGELIBS(SVXCORE_DLLPUBLIC) SdrUndoDiagramDissolveModel final : public SdrUndoObj +{ + std::shared_ptr< svx::diagram::DiagramHelper_svx > mrDiagramHelper; + std::map maPreservedModelIDs; + +public: + SdrUndoDiagramDissolveModel(SdrObject& rNewObj); + virtual ~SdrUndoDiagramDissolveModel() override; + + virtual void Undo() override; + virtual void Redo() override; + + virtual OUString GetComment() const override; +}; + /** * Manipulation of an ObjList: New Object, DeleteObj, SetObjZLevel, Grouping, ... * Abstract base class. @@ -762,6 +778,7 @@ public: // Diagram ModelData changes virtual std::unique_ptr CreateUndoDiagramModelData( SdrObject& rObject, std::shared_ptr< svx::diagram::DiagramDataState >& rStartState ); + virtual std::unique_ptr CreateUndoDiagramDissolveModel( SdrObject& rObject ); // Layer virtual std::unique_ptr CreateUndoNewLayer(sal_uInt16 nLayerNum, SdrLayerAdmin& rNewLayerAdmin, SdrModel& rNewModel); diff --git a/oox/source/drawingml/diagram/diagramhelper_oox.cxx b/oox/source/drawingml/diagram/diagramhelper_oox.cxx index 61db150f97ca..cc96d7328bcd 100644 --- a/oox/source/drawingml/diagram/diagramhelper_oox.cxx +++ b/oox/source/drawingml/diagram/diagramhelper_oox.cxx @@ -525,7 +525,7 @@ void DiagramHelper_oox::doAnchor(const uno::Reference& rTarget) mpDiagramPtr->syncDiagramFontHeights(); // initialize connection to GroupObject - connectToSdrObjGroup(rTarget); + connectToSdrObjGroup(rTarget, nullptr); } const std::shared_ptr<::oox::drawingml::Theme>& DiagramHelper_oox::getOrCreateThemePtr( diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx index 2436f7b3e835..0f4b3f30121b 100644 --- a/sc/source/filter/xml/xmlexprt.cxx +++ b/sc/source/filter/xml/xmlexprt.cxx @@ -5407,6 +5407,9 @@ void ScXMLExport::IncrementProgressBar(bool bFlush, sal_Int32 nInc) ErrCode ScXMLExport::exportDoc( enum XMLTokenEnum eClass ) { ScDocument* pDoc = GetDocument(); + SdrModel* pModel = (nullptr != pDoc) ? pDoc->GetDrawLayer() : nullptr; + if (pModel) + pModel->incImportExport(); if( getExportFlags() & (SvXMLExportFlags::FONTDECLS|SvXMLExportFlags::STYLES| SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT) ) { @@ -5455,7 +5458,11 @@ ErrCode ScXMLExport::exportDoc( enum XMLTokenEnum eClass ) { pDoc->CreateAllNoteCaptions(); } - return SvXMLExport::exportDoc( eClass ); + + ErrCode aRetval(SvXMLExport::exportDoc( eClass )); + if (pModel) + pModel->decImportExport(); + return aRetval; } // XExporter diff --git a/sc/source/filter/xml/xmlwrap.cxx b/sc/source/filter/xml/xmlwrap.cxx index 9dc4e7d4a125..e7c2f7fbd4d7 100644 --- a/sc/source/filter/xml/xmlwrap.cxx +++ b/sc/source/filter/xml/xmlwrap.cxx @@ -483,6 +483,10 @@ bool ScXMLImportWrapper::Import( ImportFlags nMode, ErrCodeMsg& rError ) ErrCodeMsg nDocRetval(ERRCODE_NONE); if (nMode & ImportFlags::Content) { + SdrModel* pModel = rDoc.GetDrawLayer(); + if (pModel) + pModel->incImportExport(); + if (mrDocShell.GetCreateMode() == SfxObjectCreateMode::INTERNAL) // We only need to import content for external link cache document. xInfoSet->setPropertyValue(SC_UNO_ODS_IMPORT_STYLES, uno::Any(false)); @@ -504,6 +508,8 @@ bool ScXMLImportWrapper::Import( ImportFlags nMode, ErrCodeMsg& rError ) aDocArgs, true); + if (pModel) + pModel->decImportExport(); SAL_INFO( "sc.filter", "content import end" ); } if( xGraphicHelper.is() ) diff --git a/sc/source/ui/drawfunc/drawsh5.cxx b/sc/source/ui/drawfunc/drawsh5.cxx index 0aee24f8ff06..548eb396ef50 100644 --- a/sc/source/ui/drawfunc/drawsh5.cxx +++ b/sc/source/ui/drawfunc/drawsh5.cxx @@ -311,7 +311,7 @@ void ScDrawShell::ExecDrawFunc( SfxRequest& rReq ) else // SID_DIAGRAM_TO_GROUP { pView->UnmarkAll(); - pObj->getDiagramHelper()->disconnectFromSdrObjGroup(); + pObj->getDiagramHelper()->disconnectFromSdrObjGroup(true); pView->MarkObj(pObj, pView->GetSdrPageView()); } } diff --git a/sd/qa/unit/export-tests-ooxml2.cxx b/sd/qa/unit/export-tests-ooxml2.cxx index 3207e4d22861..e7482f4be1a6 100644 --- a/sd/qa/unit/export-tests-ooxml2.cxx +++ b/sd/qa/unit/export-tests-ooxml2.cxx @@ -1608,7 +1608,7 @@ CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest2, testSmartartRotation2) uno::Reference xShape(xPage->getByIndex(0), uno::UNO_QUERY); SdrObjGroup* pSdrObjGroup = dynamic_cast(SdrObject::getSdrObjectFromXShape(xShape)); - pSdrObjGroup->getDiagramHelper()->disconnectFromSdrObjGroup(); + pSdrObjGroup->getDiagramHelper()->disconnectFromSdrObjGroup(false); save(TestFilter::PPTX); diff --git a/sd/source/ui/func/fusel.cxx b/sd/source/ui/func/fusel.cxx index 9b7c244d0200..9e6634dc7464 100644 --- a/sd/source/ui/func/fusel.cxx +++ b/sd/source/ui/func/fusel.cxx @@ -698,6 +698,7 @@ bool FuSelection::MouseButtonUp(const MouseEvent& rMEvt) Point aPnt( mpWindow->PixelToLogic( rMEvt.GetPosPixel() ) ); sal_uInt16 nHitLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(HITPIX,0)).Width() ); sal_uInt16 nDrgLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(mpView->GetDragThresholdPixels(),0)).Width() ); + svx::diagram::DiagramFrameHdl* pDiagramFrameHdl(dynamic_cast(pHdl)); bool bWasDragged = false; if (mpView->IsFrameDragSingles() || !mpView->HasMarkablePoints()) @@ -751,20 +752,6 @@ bool FuSelection::MouseButtonUp(const MouseEvent& rMEvt) pSingleObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); } - if(!bWasDragged && nullptr != pSingleObj && pSingleObj->isDiagram() && pHdl) - { - // Check for click on svx::diagram::DiagramFrameHdl - // - if we hit a SdrHdl - // - if it was not moved - // - if single object is selected and it is a Diagram - svx::diagram::DiagramFrameHdl* pDiagramFrameHdl(dynamic_cast(pHdl)); - if(nullptr != pDiagramFrameHdl) - { - // let the DiagramFrameHdl decide what to do - svx::diagram::DiagramFrameHdl::clicked(aPnt); - } - } - /************************************************************** * Toggle between selection and rotation **************************************************************/ @@ -912,17 +899,30 @@ bool FuSelection::MouseButtonUp(const MouseEvent& rMEvt) if(!bWasDragged && nullptr != pSingleObj && pSingleObj->isDiagram()) { - const std::shared_ptr< svx::diagram::DiagramHelper_svx >& rDiagramHelper(pSingleObj->getDiagramHelper()); - if (rDiagramHelper) + if(nullptr != pDiagramFrameHdl) { - SdrPageView* pPV; - SdrObject* pCandidate = mpView->PickObj(aMDPos, mpView->getHitTolLog(), pPV, SdrSearchOptions::DEEP); - if (pCandidate && !pCandidate->isDiagram()) + // Check for click on svx::diagram::DiagramFrameHdl + // - if we hit a SdrHdl + // - if it was not moved + // - if single object is selected and it is a Diagram + // let the DiagramFrameHdl decide what to do + svx::diagram::DiagramFrameHdl::clicked(aPnt); + return true; + } + else + { + const std::shared_ptr< svx::diagram::DiagramHelper_svx >& rDiagramHelper(pSingleObj->getDiagramHelper()); + if (rDiagramHelper) { - rDiagramHelper->markDirectDiagramSubSelection(*pCandidate); - mpView->UnmarkAllObj(); - mpView->MarkObj(pSingleObj,pPV); - return true; + SdrPageView* pPV; + SdrObject* pCandidate = mpView->PickObj(aMDPos, mpView->getHitTolLog(), pPV, SdrSearchOptions::DEEP); + if (pCandidate && !pCandidate->isDiagram()) + { + rDiagramHelper->markDirectDiagramSubSelection(*pCandidate); + mpView->UnmarkAllObj(); + mpView->MarkObj(pSingleObj,pPV); + return true; + } } } } diff --git a/sd/source/ui/view/drviews3.cxx b/sd/source/ui/view/drviews3.cxx index f56324a0577a..cba2ed4a2189 100644 --- a/sd/source/ui/view/drviews3.cxx +++ b/sd/source/ui/view/drviews3.cxx @@ -520,7 +520,7 @@ void DrawViewShell::ExecCtrl(SfxRequest& rReq) else // SID_DIAGRAM_TO_GROUP { mpDrawView->UnmarkAll(); - pObj->getDiagramHelper()->disconnectFromSdrObjGroup(); + pObj->getDiagramHelper()->disconnectFromSdrObjGroup(true); mpDrawView->MarkObj(pObj, mpDrawView->GetSdrPageView()); } } diff --git a/svx/source/diagram/DiagramHelper_svx.cxx b/svx/source/diagram/DiagramHelper_svx.cxx index 2d88e9f5768b..16f43eda8461 100644 --- a/svx/source/diagram/DiagramHelper_svx.cxx +++ b/svx/source/diagram/DiagramHelper_svx.cxx @@ -39,6 +39,9 @@ #include #include #include +#include +#include +#include #include using namespace ::com::sun::star; @@ -433,12 +436,20 @@ SdrObjGroup* DiagramHelper_svx::getAssociatedRootShape() return dynamic_cast(SdrObject::getSdrObjectFromXShape(rxRootShape)); } -void DiagramHelper_svx::disconnectFromSdrObjGroup() +void DiagramHelper_svx::disconnectFromSdrObjGroup(bool bEnableUndo) { SdrObjGroup* pRootObject(getAssociatedRootShape()); if (nullptr != pRootObject) { + SdrModel& rDrawModel(pRootObject->getSdrModelFromSdrObject()); + const bool bUndo(bEnableUndo && rDrawModel.IsUndoEnabled()); + if (bUndo) + { + // create undo action + rDrawModel.AddUndo(rDrawModel.GetSdrUndoFactory().CreateUndoDiagramDissolveModel(*pRootObject)); + } + // remove locks. Do this before resetting RootShape below, it uses that applyLocksToDiagramObjects(false); accessRootShape().clear(); @@ -446,7 +457,9 @@ void DiagramHelper_svx::disconnectFromSdrObjGroup() } } -void DiagramHelper_svx::connectToSdrObjGroup(const css::uno::Reference< css::drawing::XShape >& rTarget) +void DiagramHelper_svx::connectToSdrObjGroup( + const css::uno::Reference< css::drawing::XShape >& rTarget, + std::shared_ptr< svx::diagram::DiagramHelper_svx >* mpDiagramHelperFromUndo) { SdrObjGroup* pRootObject(nullptr); uno::Reference< drawing::XShape >& rxRootShape(accessRootShape()); @@ -461,13 +474,18 @@ void DiagramHelper_svx::connectToSdrObjGroup(const css::uno::Reference< css::dra } // ensure unconnect if already connected - disconnectFromSdrObjGroup(); + disconnectFromSdrObjGroup(false); // connect to target rxRootShape = rTarget; pRootObject = dynamic_cast(SdrObject::getSdrObjectFromXShape(rxRootShape)); if (nullptr != pRootObject) - pRootObject->mp_DiagramHelper.reset(this); + { + if (nullptr != mpDiagramHelperFromUndo) + pRootObject->mp_DiagramHelper = *mpDiagramHelperFromUndo; + else + pRootObject->mp_DiagramHelper.reset(this); + } applyLocksToDiagramObjects(true); } @@ -636,6 +654,24 @@ DiagramHelperFactory_svx::DiagramHelperFactory_svx() DiagramHelperFactory_svx& DiagramHelperFactory_svx::getDiagramHelperFactory_svx() { + if (nullptr == pSingleGlobalDiagramHelperFactory_svx) + { + // This means that library oox is not yet loaded/initialized. + // This is a hack, but I do not know a better way to force + // library oox to load as by instantiating a service that lives + // there. + // NOTE: I also tried to use + // osl::Module aModule; + // aModule.load(u"oox" SAL_DLLEXTENSION ""_ustr); + // but that does not create pSingleGlobalDiagramHelperFactory_svx, + // so using UNO seems safer (?) + try + { + comphelper::getProcessServiceFactory()->createInstance(u"com.sun.star.comp.oox.FormatDetector"_ustr); + } + catch (const uno::Exception&) {} + } + assert(nullptr != pSingleGlobalDiagramHelperFactory_svx && "DiagramHelperFactory not yet initialized (!)"); return *pSingleGlobalDiagramHelperFactory_svx; } diff --git a/svx/source/svdraw/sdrundomanager.cxx b/svx/source/svdraw/sdrundomanager.cxx index 3d5fde475ac8..6c1f3d2585b8 100644 --- a/svx/source/svdraw/sdrundomanager.cxx +++ b/svx/source/svdraw/sdrundomanager.cxx @@ -65,7 +65,6 @@ bool SdrUndoManager::Undo() bool SdrUndoManager::Redo() { bool bRetval(false); - bool bClearRedoStack(false); if (isTextEditActive()) { @@ -75,47 +74,7 @@ bool SdrUndoManager::Redo() if (!bRetval) { - // Check if the current and thus to-be undone UndoAction is a SdrUndoDiagramModelData action - const bool bCurrentIsDiagramChange( - GetRedoActionCount() - && nullptr != dynamic_cast(GetRedoAction())); - - // no redo triggered up to now, trigger local one bRetval = SfxUndoManager::Redo(); - - // it was a SdrUndoDiagramModelData action and we have more Redo actions - if (bCurrentIsDiagramChange && GetRedoActionCount()) - { - const bool bNextIsDiagramChange( - nullptr != dynamic_cast(GetRedoAction())); - - // We have more Redo-actions and the 'next' one to be executed is *not* a - // SdrUndoDiagramModelData-action. This means that the already executed - // one had done a re-Layout/Re-create of the Diagram XShape/SdrObject - // representation based on the restored Diagram ModelData. When the next - // Redo action is something else (and thus will not itself re-create - // XShapes/SdrShapes) it may be that it is an UnGroup/Delete where a former - // as-content-of-Diagram created XShape/SdrShape is referenced, an action - // that references a XShape/SdrShape by pointer/reference. That - // pointer/reference *cannot* be valid anymore (now). - - // The problem here is that Undo/Redo actions historically reference - // XShapes/SdrShapes by pointer/reference, e.g. deleting means: remove - // from an SdrObjList and add to an Undo action. I is *not* - // address/incarnation-invariant in the sense to remember e.g. to - // remove the Nth object in the list (that would work). - - // It might be possible to solve/correct this better, but since it's - // a rare corner case just avoid the possible crash when continuing Redos - // by clearing the Redo-Stack here as a consequence - bClearRedoStack = !bNextIsDiagramChange; - } - } - - if (bClearRedoStack) - { - // clear Redo-Stack (explanation see above) - ClearRedo(); } return bRetval; diff --git a/svx/source/svdraw/svdundo.cxx b/svx/source/svdraw/svdundo.cxx index 018168f7e68f..f408870d79c6 100644 --- a/svx/source/svdraw/svdundo.cxx +++ b/svx/source/svdraw/svdundo.cxx @@ -46,8 +46,9 @@ #include #include #include +#include #include - +#include // iterates over all views and unmarks this SdrObject if it is marked static void ImplUnmarkObject( SdrObject* pObj ) @@ -676,6 +677,89 @@ OUString SdrUndoDiagramModelData::GetComment() const return ImpGetDescriptionStr(STR_DiagramModelDataChange); } +SdrUndoDiagramDissolveModel::SdrUndoDiagramDissolveModel(SdrObject& rNewObj) +: SdrUndoObj(rNewObj) +, mrDiagramHelper(rNewObj.getDiagramHelper()) +, maPreservedModelIDs() +{ + if(!mrDiagramHelper) + return; + + SdrObjGroup* pRootObject(mrDiagramHelper->getAssociatedRootShape()); + if (nullptr == pRootObject) + return; + + // also need to preserve DiagramModelIDs, these get deleted + // when the Diagram gets dissolved to a group + SdrObjListIter aIterator(*pRootObject, SdrIterMode::DeepNoGroups); + while (aIterator.IsMore()) + { + SdrObject* pCandidate(aIterator.Next()); + if (nullptr != pCandidate) + maPreservedModelIDs[pCandidate] = pCandidate->getDiagramDataModelID(); + } +} + +SdrUndoDiagramDissolveModel::~SdrUndoDiagramDissolveModel() +{ +} + +void SdrUndoDiagramDissolveModel::Undo() +{ + if(!mxObj) + return; + + if(mxObj->isDiagram()) + return; + + if(!mrDiagramHelper) + return; + + mrDiagramHelper->connectToSdrObjGroup(mxObj->getUnoShape(), &mrDiagramHelper); + + SdrObjGroup* pRootObject(mrDiagramHelper->getAssociatedRootShape()); + if (nullptr == pRootObject) + return; + + // ensure that if user did enter groups that is cleared, you + // cannot enter a Diagram + comphelper::dispatchCommand(u".uno:LeaveAllGroups"_ustr, {}); + + // also need to restore DiagramModelIDs, these got deleted + // when the Diagram was dissolved to a group + SdrObjListIter aIterator(*pRootObject, SdrIterMode::DeepNoGroups); + while (aIterator.IsMore()) + { + SdrObject* pCandidate(aIterator.Next()); + if (nullptr != pCandidate) + { + auto it = maPreservedModelIDs.find(pCandidate); + if (it != maPreservedModelIDs.end()) + pCandidate->setDiagramDataModelID(it->second); + } + } +} + +void SdrUndoDiagramDissolveModel::Redo() +{ + if(!mxObj) + return; + + if(!mxObj->isDiagram()) + return; + + mrDiagramHelper = mxObj->getDiagramHelper(); + if (!mrDiagramHelper) + return; + + mrDiagramHelper->disconnectFromSdrObjGroup(false); +} + +OUString SdrUndoDiagramDissolveModel::GetComment() const +{ + return ImpGetDescriptionStr(STR_DiagramModelDissolveData); +} + SdrUndoObjList::SdrUndoObjList(SdrObject& rNewObj, bool bOrdNumDirect) : SdrUndoObj(rNewObj) { @@ -1683,6 +1767,11 @@ std::unique_ptr SdrUndoFactory::CreateUndoDiagramModelData( SdrOb return std::make_unique( rObject, rStartState ); } +std::unique_ptr SdrUndoFactory::CreateUndoDiagramDissolveModel( SdrObject& rObject ) +{ + return std::make_unique( rObject ); +} + std::unique_ptr SdrUndoFactory::CreateUndoAttrObject( SdrObject& rObject, bool bStyleSheet1, bool bSaveText ) { return std::make_unique( rObject, bStyleSheet1, bSaveText ); diff --git a/sw/inc/fesh.hxx b/sw/inc/fesh.hxx index 2ee2ddd31323..f280e3846f33 100644 --- a/sw/inc/fesh.hxx +++ b/sw/inc/fesh.hxx @@ -167,6 +167,9 @@ enum class SwPasteSdr #define SW_LEAVE_FRAME 4 /// Allow SwFEShell::SelectObj() to select the TextBox of a shape. #define SW_ALLOW_TEXTBOX 8 +/// SmartArt/Diagram SubSelection needs to know in SwFEShell::SelectObj +/// if that action came from keyboard or mouse +#define SW_FROM_KLICK 16 enum class SwMove { diff --git a/sw/source/core/frmedt/feshview.cxx b/sw/source/core/frmedt/feshview.cxx index 067efc4020d1..325ee7acdaf7 100644 --- a/sw/source/core/frmedt/feshview.cxx +++ b/sw/source/core/frmedt/feshview.cxx @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -281,6 +282,12 @@ bool SwFEShell::SelectObj( const Point& rPt, sal_uInt8 nFlag, SdrObject *pObj ) } } + // for Diagrams force to the svx MarkObj version below that will handle + // SubSelection correctly. CAUTION: Keyboard travel calls the same method + // so make sure to only do that on mouseklick and if we got a position + if (pObj && 0 != rPt.getX() && 0 != rPt.getY() && (SW_FROM_KLICK & nFlag) && pObj->isDiagram()) + pObj = nullptr; + if ( pObj ) { OSL_ENSURE( !bEnterGroup, "SW_ENTER_GROUP is not supported" ); @@ -1580,6 +1587,27 @@ const SdrObject* SwFEShell::GetBestObject(bool bNext, GotoObjFlags eType, bool b const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); SdrPageView* pPV = Imp()->GetDrawView()->GetSdrPageView(); + if (rMrkList.GetMarkCount() == 1) + { + SdrMark* pM(rMrkList.GetMark(0)); + if (nullptr != pM) + { + SdrObject* pCandidate(pM->GetMarkedSdrObj()); + + if (nullptr != pCandidate) + { + const std::shared_ptr< svx::diagram::DiagramHelper_svx >& rDiagramHelper(pCandidate->getDiagramHelper()); + + if (rDiagramHelper) + { + // move SubSelection in given direction + if (rDiagramHelper->markNextDiagramSubSelection(bNext)) + return pCandidate; + } + } + } + } + MarkableObjectsOnly aDefaultFilter( pPV ); if ( !pFilter ) pFilter = &aDefaultFilter; @@ -1735,6 +1763,17 @@ const SdrObject* SwFEShell::GetBestObject(bool bNext, GotoObjFlags eType, bool b } } + if (nullptr != pBest) + { + const std::shared_ptr< svx::diagram::DiagramHelper_svx >& rDiagramHelper(pBest->getDiagramHelper()); + + if (rDiagramHelper) + // if it's a diagram, do the correct SubSelection in the + // given selection -> last SubObject may be selected when + // travelling backwards + rDiagramHelper->initSelectionByKeyboard(bNext); + } + return pBest; } diff --git a/sw/source/filter/xml/xmlexp.cxx b/sw/source/filter/xml/xmlexp.cxx index a523c49a79d2..34b24e4b4fe0 100644 --- a/sw/source/filter/xml/xmlexp.cxx +++ b/sw/source/filter/xml/xmlexp.cxx @@ -498,6 +498,10 @@ void SwXMLExport::SetBodyAttributes() void SwXMLExport::ExportContent_() { // export forms + SwDoc* pDoc(getDoc()); + SwDrawModel* pModel = (nullptr != pDoc ? pDoc->getIDocumentDrawModelAccess().GetDrawModel() : nullptr); + if( pModel ) + pModel->incImportExport(); Reference xDrawPageSupplier(GetModel(), UNO_QUERY); if (xDrawPageSupplier.is()) { @@ -547,6 +551,9 @@ void SwXMLExport::ExportContent_() Reference < XText > xText = xTextDoc->getText(); GetTextParagraphExport()->exportText( xText, m_bShowProgress ); } + + if( pModel ) + pModel->decImportExport(); } SwDoc* SwXMLExport::getDoc() diff --git a/sw/source/uibase/app/docshini.cxx b/sw/source/uibase/app/docshini.cxx index f7a19b3e72e5..4264ca5bb5bd 100644 --- a/sw/source/uibase/app/docshini.cxx +++ b/sw/source/uibase/app/docshini.cxx @@ -475,15 +475,17 @@ bool SwDocShell::Load( SfxMedium& rMedium ) // Define some settings for legacy ODF files that have different default values now // (if required, they will be overridden later when settings will be read) + SwDrawModel* pDrawModel(nullptr); if (IsOwnStorageFormat(rMedium)) { - SwDrawModel* pDrawModel = m_xDoc->getIDocumentDrawModelAccess().GetDrawModel(); + pDrawModel = m_xDoc->getIDocumentDrawModelAccess().GetDrawModel(); if (pDrawModel) { pDrawModel->SetCompatibilityFlag(SdrCompatibilityFlag::AnchoredTextOverflowLegacy, true); // legacy processing for tdf#99729 pDrawModel->SetCompatibilityFlag(SdrCompatibilityFlag::LegacyFontwork, true); // legacy processing for tdf#148000 + pDrawModel->incImportExport(); } } @@ -570,6 +572,9 @@ bool SwDocShell::Load( SfxMedium& rMedium ) // suppress SfxProgress, when we are Embedded mod->SetEmbeddedLoadSave( false ); + + if (pDrawModel) + pDrawModel->decImportExport(); } return bRet; diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx index 3dac31a29111..4295fb48fbd5 100644 --- a/sw/source/uibase/docvw/edtwin.cxx +++ b/sw/source/uibase/docvw/edtwin.cxx @@ -4832,7 +4832,7 @@ void SwEditWin::MouseButtonUp(const MouseEvent& rMEvt) if (!pShapeFormat) { pSdrView->UnmarkAllObj(); - rSh.SelectObj(aDocPos, 0, pObj); + rSh.SelectObj(aDocPos, SW_FROM_KLICK, pObj); if (rMEvt.IsLeft() && rMEvt.GetClicks() == 1 && SwModule::get()->GetUsrPref( dynamic_cast(&m_rView) != nullptr)-> diff --git a/sw/source/uibase/shells/drwbassh.cxx b/sw/source/uibase/shells/drwbassh.cxx index fc54ee5c6878..47add83a1013 100644 --- a/sw/source/uibase/shells/drwbassh.cxx +++ b/sw/source/uibase/shells/drwbassh.cxx @@ -494,7 +494,7 @@ void SwDrawBaseShell::Execute(SfxRequest& rReq) else // SID_DIAGRAM_TO_GROUP { pSdrView->UnmarkAll(); - pObj->getDiagramHelper()->disconnectFromSdrObjGroup(); + pObj->getDiagramHelper()->disconnectFromSdrObjGroup(true); pSdrView->MarkObj(pObj, pSdrView->GetSdrPageView()); } }