[Libreoffice-commits] core.git: 4 commits - starmath/source sw/inc sw/source

Caolán McNamara caolanm at redhat.com
Wed Feb 11 04:00:35 PST 2015


 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 <caolanm at 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 <caolanm at 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 <caolanm at 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 <caolanm at 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();


More information about the Libreoffice-commits mailing list