diff options
author | Daniel Sikeler <d.sikeler94@gmail.com> | 2014-11-05 13:06:46 +0000 |
---|---|---|
committer | Michael Stahl <mstahl@redhat.com> | 2014-12-02 13:45:46 +0000 |
commit | a143d7d14db9b12064391879822120260eda2702 (patch) | |
tree | 33212c917ce15dee00d1677490a412c3c373af6e | |
parent | ababde703007557c59595d551efb118cf84a3911 (diff) |
De-/Increase fontsize when multi-sized text
I did the changes proposed in https://gerrit.libreoffice.org/#/c/11857/
I also tested it with a mixture of CJK and CTL text
Change-Id: Ic75f557b8c0a68f43abbd8c28b2222945e9361b7
Reviewed-on: https://gerrit.libreoffice.org/13152
Reviewed-by: Michael Stahl <mstahl@redhat.com>
Tested-by: Michael Stahl <mstahl@redhat.com>
-rw-r--r-- | sw/inc/editsh.hxx | 13 | ||||
-rw-r--r-- | sw/source/core/edit/edattr.cxx | 214 | ||||
-rw-r--r-- | sw/source/uibase/shells/txtattr.cxx | 46 |
3 files changed, 99 insertions, 174 deletions
diff --git a/sw/inc/editsh.hxx b/sw/inc/editsh.hxx index b59cc50e94cc..a8b4d7041e2c 100644 --- a/sw/inc/editsh.hxx +++ b/sw/inc/editsh.hxx @@ -235,16 +235,11 @@ 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. + /** Get RES_CHRATR_* 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 ); + * If parts of the selection have different scripttypes, the items with corresponding WhichIds are also collected. + * @return a vector of pairs. The pair contains a SfxPoolItem and a SwPaM, in which the item is valid and can be changed. */ + std::vector<std::pair< const SfxPoolItem*, std::unique_ptr<SwPaM>>> GetItemWithPaM( 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 3832048de6ab..bc4651b7ec4a 100644 --- a/sw/source/core/edit/edattr.cxx +++ b/sw/source/core/edit/edattr.cxx @@ -21,7 +21,6 @@ #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> @@ -283,178 +282,107 @@ SwTxtFmtColl* SwEditShell::GetPaMTxtFmtColl( SwPaM* pPaM ) const return NULL; } -std::vector<const SfxPoolItem*> SwEditShell::GetCurItem( sal_uInt16 nWhich ) +std::vector<std::pair< const SfxPoolItem*, std::unique_ptr<SwPaM> >> SwEditShell::GetItemWithPaM( sal_uInt16 nWhich ) { - std::vector<const SfxPoolItem*> vItem; + std::vector<std::pair< const SfxPoolItem*, std::unique_ptr<SwPaM> >> 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(); + sal_uLong nSttNd = pPaM->Start()->nNode.GetIndex(), + nEndNd = pPaM->End()->nNode.GetIndex(); + sal_Int32 nSttCnt = pPaM->Start()->nContent.GetIndex(); + sal_Int32 nEndCnt = pPaM->End()->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); - } + SwPaM* pNewPaM = 0; + const SfxPoolItem* pItem = 0; // for all the nodes in the current selection for( sal_uLong n = nSttNd; n <= nEndNd; ++n ) { SwNode* pNd = GetDoc()->GetNodes()[ n ]; - switch( pNd->GetNodeType() ) + if( pNd->IsTxtNode() ) { - case ND_TEXTNODE: + SwTxtNode* pTxtNd = static_cast< SwTxtNode* >( pNd ); + const sal_Int32 nStt = (n == nSttNd) ? nSttCnt : 0; + const sal_Int32 nEnd = (n == nEndNd) + ? nEndCnt : pTxtNd->GetTxt().getLength(); + const SwScriptInfo* pScriptInfo = SwScriptInfo::GetScriptInfo( *pTxtNd ); + sal_uInt8 nScript = pScriptInfo ? pScriptInfo->ScriptType( nStt ) : css::i18n::ScriptType::WEAK; + nWhich = GetWhichOfScript( nWhich, nScript ); + + // item from attribute set + if( pTxtNd->HasSwAttrSet() ) { - SwTxtNode* pTxtNd = static_cast<SwTxtNode*>(pNd); - const sal_Int32 nStt = (n == nSttNd) ? nSttCnt : 0; - const sal_Int32 nEnd = (n == nEndNd) - ? nEndCnt : pTxtNd->GetTxt().getLength(); + pNewPaM = new SwPaM(*pNd, nStt, *pNd, nEnd); + pItem = pTxtNd->GetSwAttrSet().GetItem( nWhich ); + vItem.push_back( std::make_pair( pItem, std::unique_ptr<SwPaM>(pNewPaM) ) ); + } - // 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() ) + if( !pTxtNd->HasHints() ) + continue; + + // items with limited range + 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 || + pHt->Which() == RES_TXTATR_CHARFMT || + pHt->Which() == RES_TXTATR_INETFMT ) { - const size_t nSize = pTxtNd->GetpSwpHints()->Count(); - for (size_t m = 0; m < nSize; m++) + const sal_Int32 nAttrStart = pHt->GetStart(); + const sal_Int32* pAttrEnd = pHt->End(); + + // Ignore items not in selection + if( nAttrStart > nEnd ) + break; + if( *pAttrEnd <= nStt ) + continue; + + nScript = pScriptInfo ? pScriptInfo->ScriptType( nStt ) : css::i18n::ScriptType::WEAK; + nWhich = GetWhichOfScript( nWhich, nScript ); + const SfxItemSet* pAutoSet = CharFmt::GetItemSet( pHt->GetAttr() ); + if( pAutoSet ) { - const SwTxtAttr* pHt = (*pTxtNd->GetpSwpHints())[m]; - if ( pHt->Which() == RES_TXTATR_AUTOFMT ) + SfxItemIter aItemIter( *pAutoSet ); + pItem = aItemIter.GetCurItem(); + while( pItem ) { - 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 ) + if( pItem->Which() == nWhich ) { - pItemIter.reset( new SfxItemIter( *pAutoSet )); - pItem = pItemIter->GetCurItem(); - while ( pItem ) - { - if ( pItem->Which() == nWhich ) - { - vItem.push_back( pItem ); - break; - } - pItem = pItemIter->NextItem(); - } + 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; + pNewPaM = new SwPaM(*pNd, nStart, *pNd, nStop); + vItem.push_back( std::make_pair( pItem, std::unique_ptr<SwPaM>(pNewPaM) ) ); + break; } + pItem = aItemIter.NextItem(); + } + // default item + if( !pItem && !pTxtNd->HasSwAttrSet() ) + { + pNewPaM = new SwPaM(*pNd, nStt, *pNd, nEnd); + pItem = pAutoSet->GetPool()->GetPoolDefaultItem( nWhich ); + vItem.push_back( std::make_pair( pItem, std::unique_ptr<SwPaM>(pNewPaM)) ); } } } } - break; - case ND_GRFNODE: - case ND_OLENODE: - break; - - default: - pNd = 0; } } } while ( ( pPaM = static_cast<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 = static_cast<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 || !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 = static_cast<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 0fb0e58e0056..4588b2e24db0 100644 --- a/sw/source/uibase/shells/txtattr.cxx +++ b/sw/source/uibase/shells/txtattr.cxx @@ -225,29 +225,25 @@ void SwTextShell::ExecCharAttrArgs(SfxRequest &rReq) sal_uInt16 nScriptTypes = rWrtSh.GetScriptType(); const SvxFontHeightItem* pSize( static_cast<const SvxFontHeightItem*>( aSetItem.GetItemOfScript( nScriptTypes ) ) ); - std::vector<SwPaM*> vPaM; - std::vector<const SfxPoolItem*> vItem; + std::vector<std::pair< const SfxPoolItem*, std::unique_ptr<SwPaM> >> vItems; 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()) ) ); + vItems.push_back( std::make_pair( pSize, std::unique_ptr<SwPaM>(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(); + vItems = rWrtSh.GetItemWithPaM( RES_CHRATR_FONTSIZE ); + rWrtSh.StartUndo( UNDO_INSATTR, NULL); - for ( ; iPaM != vPaM.end() && iItem != vItem.end(); ++iPaM, ++iItem ) + for( std::pair< const SfxPoolItem*, std::unique_ptr<SwPaM> >& iPair : vItems ) { - rWrtSh.GetPaMAttr( *iPaM, aSetItem.GetItemSet() ); + std::unique_ptr<SwPaM> pPaM = std::move(iPair.second); + const SfxPoolItem* pItem = iPair.first; + rWrtSh.GetPaMAttr( pPaM.get(), aSetItem.GetItemSet() ); aAttrSet.SetRanges( aSetItem.GetItemSet().GetRanges() ); - pSize = static_cast<const SvxFontHeightItem*>( *iItem ); + pSize = static_cast<const SvxFontHeightItem*>( pItem ); if (pSize) { SvxFontHeightItem aSize(*pSize); @@ -265,9 +261,8 @@ void SwTextShell::ExecCharAttrArgs(SfxRequest &rReq) if( pColl ) pColl->SetFmtAttr( aAttrSet ); else - rWrtSh.SetAttrSet( aAttrSet, 0, *iPaM ); + rWrtSh.SetAttrSet( aAttrSet, 0, pPaM.get() ); } - delete *iPaM; } rWrtSh.EndUndo( UNDO_INSATTR, NULL); rReq.Done(); @@ -627,21 +622,28 @@ void SwTextShell::GetAttrState(SfxItemSet &rSet) const SvxFontHeightItem* pSize( static_cast<const SvxFontHeightItem*>( aSetItem.GetItemOfScript( rSh.GetScriptType() ) ) ); - 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 ); else if( nSize == nFontInc ) rSet.DisableItem( FN_SHRINK_FONT_SIZE ); } + else + { + std::vector<std::pair< const SfxPoolItem*, std::unique_ptr<SwPaM> >> + vFontHeight = rSh.GetItemWithPaM( RES_CHRATR_FONTSIZE ); + for ( std::pair< const SfxPoolItem*, std::unique_ptr<SwPaM>>& pIt : vFontHeight ) + { + pSize = static_cast<const SvxFontHeightItem*>( pIt.first ); + sal_uInt32 nSize = pSize->GetHeight(); + if( nSize == nFontMaxSz ) + rSet.DisableItem( FN_GROW_FONT_SIZE ); + else if( nSize == nFontInc ) + rSet.DisableItem( FN_SHRINK_FONT_SIZE ); + } + } nSlot = 0; } break; |