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

Daniel Sikeler d.sikeler94 at gmail.com
Mon Nov 3 03:26:46 PST 2014


 sw/inc/editsh.hxx                   |   11 ++
 sw/source/core/edit/edattr.cxx      |  176 +++++++++++++++++++++++++++++++++++-
 sw/source/uibase/shells/txtattr.cxx |   65 +++++++++----
 3 files changed, 232 insertions(+), 20 deletions(-)

New commits:
commit 98c95ce3a759a6f691c20cb1e376fa54a9dfdbc0
Author: Daniel Sikeler <d.sikeler94 at gmail.com>
Date:   Mon Sep 22 08:26:06 2014 +0000

    fdo#35862 De-/Increase font when multi-sized text
    
    Added two new function to the SwEditShell.
    The first returns all items of a specific WhichId wich belong to the current selection. The items from the attribute set and from the hints are used.
    The second returns SwPaMs separated at borders of an itemtype  identified by its WhichId. The SwPaMs must be deleted after yous.
    
    Change-Id: I00e6d1b0f75b9f184343711c6d2bdc7e5694c711
    Reviewed-on: https://gerrit.libreoffice.org/11857
    Tested-by: Samuel Mehrbrodt <s.mehrbrodt at gmail.com>
    Reviewed-by: Samuel Mehrbrodt <s.mehrbrodt at gmail.com>

diff --git a/sw/inc/editsh.hxx b/sw/inc/editsh.hxx
index b869896..06aed3a 100644
--- a/sw/inc/editsh.hxx
+++ b/sw/inc/editsh.hxx
@@ -233,6 +233,17 @@ public:
     void SetAttrItem( const SfxPoolItem&, sal_uInt16 nFlags = 0 );
     void SetAttrSet( const SfxItemSet&, sal_uInt16 nFlags = 0, SwPaM* pCrsr = NULL );
 
+    /** Get all items of one type in the current selection.
+     * @param nWhich WhichId of the collected items.
+     * @return Vector with the items.*/
+    std::vector<const SfxPoolItem*> GetCurItem( sal_uInt16 nWhich );
+
+    /** Splits the current SwPaM in smaller ones.
+     * The borders of an itemtype are used as separator. The SwPaMs must be deleted after use.
+     * @param nWhich WhichId of the item to separate at.
+     * @return Vector with the smaller SwPaMs*/
+    std::vector<SwPaM*> GetSplitPaM( sal_uInt16 nWhich );
+
     /**
      * Get the paragraph format attribute(s) of the current selection.
      *
diff --git a/sw/source/core/edit/edattr.cxx b/sw/source/core/edit/edattr.cxx
index 4cf6687..009f837 100644
--- a/sw/source/core/edit/edattr.cxx
+++ b/sw/source/core/edit/edattr.cxx
@@ -18,10 +18,10 @@
  */
 
 #include <hintids.hxx>
-
 #include <editeng/tstpitem.hxx>
 #include <editeng/lrspitem.hxx>
 #include <editeng/scripttypeitem.hxx>
+#include <editeng/fhgtitem.hxx>
 #include <com/sun/star/i18n/ScriptType.hpp>
 #include <txatbase.hxx>
 #include <txtftn.hxx>
@@ -42,10 +42,12 @@
 #include <txtfrm.hxx>
 #include <scriptinfo.hxx>
 #include <svl/ctloptions.hxx>
+#include <svl/itemiter.hxx>
 #include <charfmt.hxx>
 #include <numrule.hxx>
 
 #include <algorithm>
+#include <charatr.hxx>
 
 /*
  * hard Formatting (Attributes)
@@ -281,6 +283,178 @@ SwTxtFmtColl* SwEditShell::GetPaMTxtFmtColl( SwPaM* pPaM ) const
     return NULL;
 }
 
+std::vector<const SfxPoolItem*> SwEditShell::GetCurItem( sal_uInt16 nWhich )
+{
+    std::vector<const SfxPoolItem*> vItem;
+    SwPaM* pPaM = GetCrsr();
+    SwPaM* pStartPaM = pPaM;
+    do { // for all the point and mark (selections)
+
+        // get the start and the end node of the current selection
+        sal_uLong nSttNd = pPaM->GetMark()->nNode.GetIndex(),
+              nEndNd = pPaM->GetPoint()->nNode.GetIndex();
+        sal_Int32 nSttCnt = pPaM->GetMark()->nContent.GetIndex();
+        sal_Int32 nEndCnt = pPaM->GetPoint()->nContent.GetIndex();
+
+        // reverse start and end if there number aren't sorted correctly
+        if( nSttNd > nEndNd || ( nSttNd == nEndNd && nSttCnt > nEndCnt ))
+        {
+            std::swap(nSttNd, nEndNd);
+            std::swap(nSttCnt, nEndCnt);
+        }
+
+        // for all the nodes in the current selection
+        for( sal_uLong n = nSttNd; n <= nEndNd; ++n )
+        {
+            SwNode* pNd = GetDoc()->GetNodes()[ n ];
+            switch( pNd->GetNodeType() )
+            {
+            case ND_TEXTNODE:
+                {
+                    SwTxtNode* pTxtNd = (SwTxtNode*) pNd;
+                    const sal_Int32 nStt = (n == nSttNd) ? nSttCnt : 0;
+                    const sal_Int32 nEnd = (n == nEndNd)
+                        ? nEndCnt : pTxtNd->GetTxt().getLength();
+
+                    // item from attribute set or default item
+                    if ( pTxtNd->HasSwAttrSet() )
+                    {
+                        const SwAttrSet aSet = pTxtNd->GetSwAttrSet();
+                        vItem.push_back( &(aSet.GetSize()) );
+                    }
+                    // items with limited range
+                    if ( pTxtNd->HasHints() )
+                    {
+                        const size_t nSize = pTxtNd->GetpSwpHints()->Count();
+                        for (size_t m = 0; m < nSize; m++)
+                        {
+                            const SwTxtAttr* pHt = (*pTxtNd->GetpSwpHints())[m];
+                            if ( pHt->Which() == RES_TXTATR_AUTOFMT )
+                            {
+                                const sal_Int32 nAttrStart = pHt->GetStart();
+                                const sal_Int32* pAttrEnd = pHt->End();
+
+                                // Ignore items not in selection
+                                if ( nAttrStart > nEnd )
+                                    break;
+                                if ( !pAttrEnd || *pAttrEnd <= nStt )
+                                    continue;
+
+                                boost::scoped_ptr< SfxItemIter > pItemIter;
+                                const SfxPoolItem* pItem = 0;
+                                const SfxItemSet* pAutoSet =
+                                    CharFmt::GetItemSet ( pHt->GetAttr() );
+                                if ( pAutoSet )
+                                {
+                                    pItemIter.reset( new SfxItemIter( *pAutoSet ));
+                                    pItem = pItemIter->GetCurItem();
+                                    while ( pItem )
+                                    {
+                                        if ( pItem->Which() == nWhich )
+                                        {
+                                            vItem.push_back( pItem );
+                                            break;
+                                        }
+                                        pItem = pItemIter->NextItem();
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+                break;
+            case ND_GRFNODE:
+            case ND_OLENODE:
+                break;
+
+            default:
+                pNd = 0;
+            }
+        }
+    } while ( ( pPaM = (SwPaM*)pPaM->GetNext() ) != pStartPaM );
+    return vItem;
+}
+
+std::vector<SwPaM*> SwEditShell::GetSplitPaM( sal_uInt16 nWhich)
+{
+    std::vector<SwPaM*> vPaMs;
+    SwPaM* pPaM = GetCrsr();
+    SwPaM* pStartPaM = pPaM;
+    do { // for all the point and mark (selections)
+
+        // get the start and the end node of the current selection
+        sal_uLong nSttNd = pPaM->GetMark()->nNode.GetIndex(),
+              nEndNd = pPaM->GetPoint()->nNode.GetIndex();
+        sal_Int32 nSttCnt = pPaM->GetMark()->nContent.GetIndex();
+        sal_Int32 nEndCnt = pPaM->GetPoint()->nContent.GetIndex();
+
+        // reverse start and end if there number aren't sorted correctly
+        if( nSttNd > nEndNd || ( nSttNd == nEndNd && nSttCnt > nEndCnt ))
+        {
+            std::swap(nSttNd, nEndNd);
+            std::swap(nSttCnt, nEndCnt);
+        }
+
+        // for all the nodes in the current selection
+        for( sal_uLong n = nSttNd; n <= nEndNd; ++n )
+        {
+            SwNode* pNd = GetDoc()->GetNodes()[ n ];
+            switch( pNd->GetNodeType() )
+            {
+            case ND_TEXTNODE:
+                {
+                    SwTxtNode* pTxtNd = (SwTxtNode*) pNd;
+                    const sal_Int32 nStt = (n == nSttNd) ? nSttCnt : 0;
+                    const sal_Int32 nEnd = (n == nEndNd)
+                        ? nEndCnt : pTxtNd->GetTxt().getLength();
+                    if ( pTxtNd->HasSwAttrSet() )
+                    {
+                        SwPaM* pNewPaM = new SwPaM(*pNd, nStt, *pNd, nEnd);
+                        vPaMs.push_back( pNewPaM );
+                    }
+                    if ( pTxtNd->HasHints() )
+                    {
+                        const size_t nSize = pTxtNd->GetpSwpHints()->Count();
+                        for (size_t m = 0; m < nSize; m++)
+                        {
+                            const SwTxtAttr* pHt = (*pTxtNd->GetpSwpHints())[m];
+                            const SfxItemSet* pAutoSet =
+                                      CharFmt::GetItemSet ( pHt->GetAttr() );
+                            if ( isTXTATR_NOEND( pHt->Which() ) || !pAutoSet->HasItem( nWhich ) )
+                                continue;
+                            const sal_Int32 nAttrStart = pHt->GetStart();
+                            const sal_Int32* pAttrEnd = pHt->End();
+                            if ( nAttrStart > nEnd )
+                                break;
+                            if ( !pAttrEnd || *pAttrEnd <= nStt )
+                                continue;
+                            sal_Int32 nStart = 0, nStop = 0;
+                            if ( nAttrStart < nStt ) //Attribut starts before selection
+                                nStart = nStt;
+                            else
+                                nStart = nAttrStart;
+                            if ( *pAttrEnd > nEnd ) //Attribut ends after selection
+                                nStop = nEnd;
+                            else
+                                nStop = *pAttrEnd;
+                            SwPaM* pNewPaM = new SwPaM(*pNd, nStart, *pNd, nStop);
+                            vPaMs.push_back( pNewPaM );
+                        }
+                    }
+                }
+                break;
+            case ND_GRFNODE:
+            case ND_OLENODE:
+                break;
+
+            default:
+                pNd = 0;
+            }
+        }
+    } while ( ( pPaM = (SwPaM*)pPaM->GetNext() ) != pStartPaM );
+    return vPaMs;
+}
+
 bool SwEditShell::GetCurFtn( SwFmtFtn* pFillFtn )
 {
     // The cursor must be positioned on the current footnotes anchor:
diff --git a/sw/source/uibase/shells/txtattr.cxx b/sw/source/uibase/shells/txtattr.cxx
index 22b6583..9c9adcb 100644
--- a/sw/source/uibase/shells/txtattr.cxx
+++ b/sw/source/uibase/shells/txtattr.cxx
@@ -223,31 +223,53 @@ void SwTextShell::ExecCharAttrArgs(SfxRequest &rReq)
             SfxItemSet aAttrSet( rPool, aSetItem.GetItemSet().GetRanges() );
 
             sal_uInt16 nScriptTypes = rWrtSh.GetScriptType();
-
             const SvxFontHeightItem* pSize( static_cast<const SvxFontHeightItem*>(
                                         aSetItem.GetItemOfScript( nScriptTypes ) ) );
-
-            if (pSize)
+            std::vector<SwPaM*> vPaM;
+            std::vector<const SfxPoolItem*> vItem;
+            if ( pSize ) // selected text has one size
+            {
+                vItem.push_back( pSize );
+                // must create new one, otherwise document is without pam
+                SwPaM* pPaM = rWrtSh.GetCrsr();
+                vPaM.push_back( new SwPaM( *(pPaM->GetMark()), *(pPaM->GetPoint()) ) );
+            }
+            else
+            {
+                vPaM = rWrtSh.GetSplitPaM( RES_CHRATR_FONTSIZE );
+                vItem = rWrtSh.GetCurItem ( RES_CHRATR_FONTSIZE );
+            }
+            std::vector<SwPaM*>::iterator iPaM = vPaM.begin();
+            std::vector<const SfxPoolItem*>::const_iterator iItem = vItem.begin();
+            rWrtSh.StartUndo( UNDO_INSATTR, NULL);
+            for ( ; iPaM != vPaM.end() && iItem != vItem.end(); ++iPaM, ++iItem )
             {
-                SvxFontHeightItem aSize(*pSize);
+                rWrtSh.GetPaMAttr( *iPaM, aSetItem.GetItemSet() );
+                aAttrSet.SetRanges( aSetItem.GetItemSet().GetRanges() );
 
-                sal_uInt32 nSize = aSize.GetHeight();
+                pSize = static_cast<const SvxFontHeightItem*>( *iItem );
+                if (pSize)
+                {
+                    SvxFontHeightItem aSize(*pSize);
 
-                if ( nSlot == FN_GROW_FONT_SIZE && ( nSize += nFontInc ) > nFontMaxSz )
-                    nSize = nFontMaxSz;
-                else if ( nSlot == FN_SHRINK_FONT_SIZE && ( nSize -= nFontInc ) < nFontInc )
-                    nSize = nFontInc;
+                    sal_uInt32 nSize = aSize.GetHeight();
 
-                aSize.SetHeight( nSize );
-                aSetItem.PutItemForScriptType( nScriptTypes, aSize );
-                aAttrSet.Put( aSetItem.GetItemSet() );
+                    if ( nSlot == FN_GROW_FONT_SIZE && ( nSize += nFontInc ) > nFontMaxSz )
+                        nSize = nFontMaxSz;
+                    else if ( nSlot == FN_SHRINK_FONT_SIZE && ( nSize -= nFontInc ) < nFontInc )
+                        nSize = nFontInc;
 
-                if( pColl )
-                    pColl->SetFmtAttr( aAttrSet );
-                else
-                    rWrtSh.SetAttrSet( aAttrSet );
+                    aSize.SetHeight( nSize );
+                    aSetItem.PutItemForScriptType( nScriptTypes, aSize );
+                    aAttrSet.Put( aSetItem.GetItemSet() );
+                    if( pColl )
+                        pColl->SetFmtAttr( aAttrSet );
+                    else
+                        rWrtSh.SetAttrSet( aAttrSet, 0, *iPaM );
+                }
+                delete *iPaM;
             }
-
+            rWrtSh.EndUndo( UNDO_INSATTR, NULL);
             rReq.Done();
         }
         break;
@@ -605,10 +627,15 @@ void SwTextShell::GetAttrState(SfxItemSet &rSet)
                 const SvxFontHeightItem* pSize( static_cast<const SvxFontHeightItem*>(
                                             aSetItem.GetItemOfScript( rSh.GetScriptType() ) ) );
 
-                if( !pSize )
-                    rSet.DisableItem( nSlot );
+                std::vector<const SfxPoolItem*> vFontHeight;
+                if( pSize ) // selection is of one size
+                    vFontHeight.push_back( pSize );
                 else
+                    vFontHeight = rSh.GetCurItem( RES_CHRATR_FONTSIZE );
+
+                for ( const SfxPoolItem* pIt : vFontHeight )
                 {
+                    pSize = static_cast<const SvxFontHeightItem*>(pIt);
                     sal_uInt32 nSize = pSize->GetHeight();
                     if( nSize == nFontMaxSz )
                         rSet.DisableItem( FN_GROW_FONT_SIZE );


More information about the Libreoffice-commits mailing list