Kaydet (Commit) 98c95ce3 authored tarafından Daniel Sikeler's avatar Daniel Sikeler Kaydeden (comit) Samuel Mehrbrodt

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/11857Tested-by: 's avatarSamuel Mehrbrodt <s.mehrbrodt@gmail.com>
Reviewed-by: 's avatarSamuel Mehrbrodt <s.mehrbrodt@gmail.com>
üst fe1f258d
......@@ -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.
*
......
......@@ -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:
......
......@@ -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 );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment