starmath/source/cursor.cxx | 12 ++++++-- sw/inc/fesh.hxx | 1 sw/source/core/doc/docfly.cxx | 11 +++++-- sw/source/core/frmedt/feshview.cxx | 49 ++++++++++++++++++++++++--------- sw/source/core/inc/sortedobjs.hxx | 5 ++- sw/source/core/layout/fly.cxx | 8 +++++ sw/source/core/layout/sortedobjs.cxx | 51 ++++++++++++++++++++++++----------- sw/source/core/txtnode/ndtxt.cxx | 8 +++++ sw/source/uibase/shells/drwbassh.cxx | 4 +- 9 files changed, 112 insertions(+), 37 deletions(-)
New commits: commit 70f0b3917688e7c462917d97d39443d6e75502fb Author: Caolán McNamara <caol...@redhat.com> Date: Wed Feb 11 11:36:58 2015 +0000 Resolves: tdf#70062 avoid crash on ungrouping "ac char" group If you can't group a char-anchored thing with something else, then you can't ungroup a selection that contains a char-anchored group. You can group together non-char anchored things, then change the anchor type to get a char-anchored group to get into this situation. Change-Id: Id627bd11e2c749ad08fb902bf88f937ff5f06a12 diff --git a/sw/inc/fesh.hxx b/sw/inc/fesh.hxx index 821323a..55ef44b 100644 --- a/sw/inc/fesh.hxx +++ b/sw/inc/fesh.hxx @@ -506,6 +506,7 @@ public: it is possible that there are groups included. */ bool IsGroupAllowed() const; + bool IsUnGroupAllowed() const; void MirrorSelection( bool bHorizontal ); ///< Vertical if FALSE. diff --git a/sw/source/core/frmedt/feshview.cxx b/sw/source/core/frmedt/feshview.cxx index b75bdae..f092a6c 100644 --- a/sw/source/core/frmedt/feshview.cxx +++ b/sw/source/core/frmedt/feshview.cxx @@ -2073,6 +2073,25 @@ bool SwFEShell::IsGroupSelected() return false; } +namespace +{ + bool HasSuitableGroupingAnchor(const SdrObject* pObj) + { + bool bSuitable = true; + SwFrmFmt* pFrmFmt(::FindFrmFmt(const_cast<SdrObject*>(pObj))); + if (!pFrmFmt) + { + OSL_FAIL( "<HasSuitableGroupingAnchor> - missing frame format" ); + bSuitable = false; + } + else if (FLY_AS_CHAR == pFrmFmt->GetAnchor().GetAnchorId()) + { + bSuitable = false; + } + return bSuitable; + } +} + // Change return type. // Adjustments for drawing objects in header/footer: // allow group, only if all selected objects are in the same header/footer @@ -2095,18 +2114,7 @@ bool SwFEShell::IsGroupAllowed() const pUpGroup = pObj->GetUpGroup(); if ( bIsGroupAllowed ) - { - SwFrmFmt* pFrmFmt( ::FindFrmFmt( const_cast<SdrObject*>(pObj) ) ); - if ( !pFrmFmt ) - { - OSL_FAIL( "<SwFEShell::IsGroupAllowed()> - missing frame format" ); - bIsGroupAllowed = false; - } - else if ( FLY_AS_CHAR == pFrmFmt->GetAnchor().GetAnchorId() ) - { - bIsGroupAllowed = false; - } - } + bIsGroupAllowed = HasSuitableGroupingAnchor(pObj); // check, if all selected objects are in the // same header/footer or not in header/footer. @@ -2143,13 +2151,28 @@ bool SwFEShell::IsGroupAllowed() const } } } - } } return bIsGroupAllowed; } +bool SwFEShell::IsUnGroupAllowed() const +{ + bool bIsUnGroupAllowed = false; + + const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); + for (size_t i = 0; i < rMrkList.GetMarkCount(); ++i) + { + const SdrObject* pObj = rMrkList.GetMark(i)->GetMarkedSdrObj(); + bIsUnGroupAllowed = HasSuitableGroupingAnchor(pObj); + if (!bIsUnGroupAllowed) + break; + } + + return bIsUnGroupAllowed; +} + // The group gets the anchor and the contactobject of the first in the selection void SwFEShell::GroupSelection() { diff --git a/sw/source/uibase/shells/drwbassh.cxx b/sw/source/uibase/shells/drwbassh.cxx index 75f4c6a..348fff2 100644 --- a/sw/source/uibase/shells/drwbassh.cxx +++ b/sw/source/uibase/shells/drwbassh.cxx @@ -400,7 +400,7 @@ void SwDrawBaseShell::Execute(SfxRequest &rReq) break; case SID_UNGROUP: - if (pSh->IsGroupSelected()) + if (pSh->IsGroupSelected() && pSh->IsUnGroupAllowed()) { pSh->UnGroupSelection(); rBind.Invalidate(SID_GROUP); @@ -652,7 +652,7 @@ void SwDrawBaseShell::GetState(SfxItemSet& rSet) rSet.DisableItem( nWhich ); break; case SID_UNGROUP: - if ( !rSh.IsGroupSelected() || bProtected ) + if ( !rSh.IsGroupSelected() || bProtected || !rSh.IsUnGroupAllowed() ) rSet.DisableItem( nWhich ); break; case SID_ENTER_GROUP: commit 0dec8ad842273be1d2b3e7e9da2110872fcc3de5 Author: Caolán McNamara <caol...@redhat.com> Date: Wed Feb 11 11:08:40 2015 +0000 OSL_ENSURE->assert when followed by unconditional dereference Change-Id: Id3072473c1a4f52f606dbcfc87aa4a69ab2c012d diff --git a/sw/source/core/doc/docfly.cxx b/sw/source/core/doc/docfly.cxx index acd472d..6c26ce4 100644 --- a/sw/source/core/doc/docfly.cxx +++ b/sw/source/core/doc/docfly.cxx @@ -910,10 +910,10 @@ bool SwDoc::ChgAnchor( const SdrMarkList& _rMrkList, // the attribute. const sal_Int32 nIndx( xOldAsCharAnchorPos->nContent.GetIndex() ); SwTxtNode* pTxtNode( xOldAsCharAnchorPos->nNode.GetNode().GetTxtNode() ); - OSL_ENSURE( pTxtNode, "<SwDoc::ChgAnchor(..)> - missing previous anchor text node for as-character anchored object" ); - OSL_ENSURE( pTxtNode->HasHints(), "Missing FlyInCnt-Hint." ); + assert(pTxtNode && "<SwDoc::ChgAnchor(..)> - missing previous anchor text node for as-character anchored object"); SwTxtAttr * const pHnt = pTxtNode->GetTxtAttrForCharAt( nIndx, RES_TXTATR_FLYCNT ); + assert(pHnt && "Missing FlyInCnt-Hint."); const_cast<SwFmtFlyCnt&>(pHnt->GetFlyCnt()).SetFlyFmt(); // They are disconnected. We now have to destroy the attribute. commit 0a6a151c4b7c78a363fb64598fbda39db4f42d07 Author: Caolán McNamara <caol...@redhat.com> Date: Wed Feb 11 10:51:13 2015 +0000 Related: tdf#70062 keep drawing anchor objects sorted take attachment from tdf#70062, ungroup the bottom pair, anchor as char the left one, anchor as char the right one asserts with debugging stl on unsorted container Change-Id: I3ae763f6d61445f9118ee573a98c69d7a6ee6e4b diff --git a/sw/source/core/doc/docfly.cxx b/sw/source/core/doc/docfly.cxx index 5548ccd..acd472d 100644 --- a/sw/source/core/doc/docfly.cxx +++ b/sw/source/core/doc/docfly.cxx @@ -737,7 +737,8 @@ bool SwDoc::ChgAnchor( const SdrMarkList& _rMrkList, _eAnchorType = eOldAnchorType; SwFmtAnchor aNewAnch( _eAnchorType ); - Rectangle aObjRect( pContact->GetAnchoredObj( pObj )->GetObjRect().SVRect() ); + SwAnchoredObject *pAnchoredObj = pContact->GetAnchoredObj(pObj); + Rectangle aObjRect(pAnchoredObj->GetObjRect().SVRect()); const Point aPt( aObjRect.TopLeft() ); switch ( _eAnchorType ) @@ -894,6 +895,10 @@ bool SwDoc::ChgAnchor( const SdrMarkList& _rMrkList, } } + // we have changed the anchoring attributes, and those are used to + // order the object in its sorted list, so update its position + pAnchoredObj->UpdateObjInSortedList(); + // #i54336# if (xOldAsCharAnchorPos) { diff --git a/sw/source/core/inc/sortedobjs.hxx b/sw/source/core/inc/sortedobjs.hxx index 9605360..a57ed15 100644 --- a/sw/source/core/inc/sortedobjs.hxx +++ b/sw/source/core/inc/sortedobjs.hxx @@ -74,7 +74,8 @@ class SwSortedObjs @return boolean, indicating success of the update. */ - bool Update( SwAnchoredObject& _rAnchoredObj ); + bool Update(SwAnchoredObject& _rAnchoredObj); + void UpdateAll(); /** Position of object <_rAnchoredObj> in sorted list @@ -85,6 +86,8 @@ class SwSortedObjs Number of the list position of object <_rAnchoredObj> */ size_t ListPosOf( const SwAnchoredObject& _rAnchoredObj ) const; + + bool is_sorted() const; }; #endif diff --git a/sw/source/core/layout/fly.cxx b/sw/source/core/layout/fly.cxx index b8b942b..529d194 100644 --- a/sw/source/core/layout/fly.cxx +++ b/sw/source/core/layout/fly.cxx @@ -2069,6 +2069,8 @@ void SwFrm::RemoveFly( SwFlyFrm *pToRemove ) void SwFrm::AppendDrawObj( SwAnchoredObject& _rNewObj ) { + assert(!mpDrawObjs || mpDrawObjs->is_sorted()); + if ( !_rNewObj.ISA(SwAnchoredDrawObject) ) { OSL_FAIL( "SwFrm::AppendDrawObj(..) - anchored object of unexpected type -> object not appended" ); @@ -2078,10 +2080,12 @@ void SwFrm::AppendDrawObj( SwAnchoredObject& _rNewObj ) if ( !_rNewObj.GetDrawObj()->ISA(SwDrawVirtObj) && _rNewObj.GetAnchorFrm() && _rNewObj.GetAnchorFrm() != this ) { + assert(!mpDrawObjs || mpDrawObjs->is_sorted()); // perform disconnect from layout, if 'master' drawing object is appended // to a new frame. static_cast<SwDrawContact*>(::GetUserCall( _rNewObj.GetDrawObj() ))-> DisconnectFromLayout( false ); + assert(!mpDrawObjs || mpDrawObjs->is_sorted()); } if ( _rNewObj.GetAnchorFrm() != this ) @@ -2136,6 +2140,8 @@ void SwFrm::AppendDrawObj( SwAnchoredObject& _rNewObj ) if( pLayout && pLayout->IsAnyShellAccessible() ) pSh->Imp()->AddAccessibleObj( _rNewObj.GetDrawObj() ); } + + assert(!mpDrawObjs || mpDrawObjs->is_sorted()); } void SwFrm::RemoveDrawObj( SwAnchoredObject& _rToRemoveObj ) @@ -2159,6 +2165,8 @@ void SwFrm::RemoveDrawObj( SwAnchoredObject& _rToRemoveObj ) DELETEZ( mpDrawObjs ); _rToRemoveObj.ChgAnchorFrm( 0 ); + + assert(!mpDrawObjs || mpDrawObjs->is_sorted()); } void SwFrm::InvalidateObjs( const bool _bInvaPosOnly, diff --git a/sw/source/core/layout/sortedobjs.cxx b/sw/source/core/layout/sortedobjs.cxx index 0fef218..5893a48 100644 --- a/sw/source/core/layout/sortedobjs.cxx +++ b/sw/source/core/layout/sortedobjs.cxx @@ -60,6 +60,18 @@ SwAnchoredObject* SwSortedObjs::operator[]( size_t _nIndex ) const return pAnchoredObj; } +namespace +{ + int GetAnchorWeight(RndStdIds eAnchor) + { + if (eAnchor == FLY_AT_CHAR) + return 0; + if (eAnchor == FLY_AS_CHAR) + return 1; + return 2; + } +} + struct ObjAnchorOrder { bool operator()( const SwAnchoredObject* _pListedAnchoredObj, @@ -122,26 +134,25 @@ struct ObjAnchorOrder // --> OD 2006-11-29 #???# - objects have to be ordered by anchor node position // Thus, compare content anchor node positions and anchor type, // if not anchored at-paragraph - if ((pAnchorListed->GetAnchorId() != FLY_AT_PARA) && - (pAnchorNew ->GetAnchorId() != FLY_AT_PARA) && - pCntntAnchorListed && pCntntAnchorNew ) + if (pCntntAnchorListed && pCntntAnchorNew) { - if ( pCntntAnchorListed->nContent != pCntntAnchorNew->nContent ) - { - return pCntntAnchorListed->nContent < pCntntAnchorNew->nContent; - } - else if ((pAnchorListed->GetAnchorId() == FLY_AT_CHAR) && - (pAnchorNew ->GetAnchorId() == FLY_AS_CHAR)) - { - return true; - } - else if ((pAnchorListed->GetAnchorId() == FLY_AS_CHAR) && - (pAnchorNew ->GetAnchorId() == FLY_AT_CHAR)) + sal_Int32 nListedIndex = pAnchorListed->GetAnchorId() != FLY_AT_PARA ? + pCntntAnchorListed->nContent.GetIndex() : 0; + sal_Int32 nNewIndex = pAnchorNew->GetAnchorId() != FLY_AT_PARA ? + pCntntAnchorNew->nContent.GetIndex() : 0; + if (nListedIndex != nNewIndex) { - return false; + return nListedIndex < nNewIndex; } } + int nAnchorListedWeight = GetAnchorWeight(pAnchorListed->GetAnchorId()); + int nAnchorNewWeight = GetAnchorWeight(pAnchorNew->GetAnchorId()); + if (nAnchorListedWeight != nAnchorNewWeight) + { + return nAnchorListedWeight < nAnchorNewWeight; + } + // objects anchored at the same content and at the same content anchor // node position with the same anchor type // Thus, compare its wrapping style including its layer @@ -193,6 +204,11 @@ struct ObjAnchorOrder } }; +bool SwSortedObjs::is_sorted() const +{ + return std::is_sorted(maSortedObjLst.begin(), maSortedObjLst.end(), ObjAnchorOrder()); +} + bool SwSortedObjs::Insert( SwAnchoredObject& _rAnchoredObj ) { // #i51941# @@ -264,6 +280,11 @@ bool SwSortedObjs::Update( SwAnchoredObject& _rAnchoredObj ) return Contains( _rAnchoredObj ); } +void SwSortedObjs::UpdateAll() +{ + std::stable_sort(maSortedObjLst.begin(), maSortedObjLst.end(), ObjAnchorOrder()); +} + size_t SwSortedObjs::ListPosOf( const SwAnchoredObject& _rAnchoredObj ) const { std::vector< SwAnchoredObject* >::const_iterator aIter = diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx index 18da646..9b1b4a2 100644 --- a/sw/source/core/txtnode/ndtxt.cxx +++ b/sw/source/core/txtnode/ndtxt.cxx @@ -82,6 +82,7 @@ #include <SwNodeNum.hxx> #include <svl/intitem.hxx> #include <list.hxx> +#include <sortedobjs.hxx> #include <switerator.hxx> #include <attrhint.hxx> #include <boost/scoped_ptr.hpp> @@ -1178,6 +1179,13 @@ void SwTxtNode::Update( { getIDocumentMarkAccess()->assureSortedMarkContainers(); } + + //Any drawing objects anchored into this text node may be sorted by their + //anchor position which may have changed here, so resort them + SwCntntFrm* pCntntFrm = getLayoutFrm(GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout()); + SwSortedObjs* pSortedObjs = pCntntFrm ? pCntntFrm->GetDrawObjs() : NULL; + if (pSortedObjs) + pSortedObjs->UpdateAll(); } void SwTxtNode::_ChgTxtCollUpdateNum( const SwTxtFmtColl *pOldColl, commit 39611d60204cd18e278ea822cfe3ef7ea09e6389 Author: Caolán McNamara <caol...@redhat.com> Date: Wed Feb 11 09:15:29 2015 +0000 coverity#1267649 Logically dead code and coverity#1267645 Logically dead code coverity#1267651 Logically dead code Change-Id: If92e17708576bf11cefc28f903a24ad271b826c8 diff --git a/starmath/source/cursor.cxx b/starmath/source/cursor.cxx index 9a45577..4318a3b 100644 --- a/starmath/source/cursor.cxx +++ b/starmath/source/cursor.cxx @@ -262,9 +262,11 @@ void SmCursor::Delete(){ SmStructureNode* pLineParent = pLine->GetParent(); //Find line offset in parent int nLineOffset = pLineParent->IndexOfSubNode(pLine); - assert(nLineOffset != -1); //pLine must be a child of its parent! if (nLineOffset == -1) + { + SAL_WARN("starmath", "pLine must be a child of its parent!"); return; + } //Position after delete SmCaretPos PosAfterDelete; @@ -813,9 +815,11 @@ bool SmCursor::InsertRow() { SmStructureNode *pLineParent = pLine->GetParent(); int nParentIndex = pLineParent->IndexOfSubNode(pLine); - assert(nParentIndex != -1); //pLine must be a subnode of pLineParent if (nParentIndex == -1) + { + SAL_WARN("starmath", "pLine must be a subnode of pLineParent!"); return false; + } //Discover the context of this command SmTableNode *pTable = NULL; @@ -934,9 +938,11 @@ void SmCursor::InsertFraction() { //Find Parent and offset in parent SmStructureNode *pLineParent = pLine->GetParent(); int nParentIndex = pLineParent->IndexOfSubNode(pLine); - assert(nParentIndex != -1); //pLine must be a subnode of pLineParent! if (nParentIndex == -1) + { + SAL_WARN("starmath", "pLine must be a subnode of pLineParent!"); return; + } //We begin modifying the tree here BeginEdit();
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits