1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
22 #include <svl/style.hxx>
23 #include <com/sun/star/i18n/WordType.hpp>
25 #include <svl/itemset.hxx>
26 #include <editeng/editeng.hxx>
27 #include <editeng/editdata.hxx>
28 #include <editeng/outliner.hxx>
29 #include <editeng/unoedhlp.hxx>
30 #include <svl/poolitem.hxx>
31 #include <vcl/wrkwin.hxx>
32 #include <editeng/eeitem.hxx>
34 #include <editeng/unoforou.hxx>
35 #include <editeng/unofored.hxx>
36 #include <editeng/outlobj.hxx>
37 #include <unofored_internal.hxx>
39 using namespace ::com::sun::star
;
43 SvxOutlinerForwarder::SvxOutlinerForwarder( Outliner
& rOutl
, bool bOutlText
/* = false */ ) :
45 bOutlinerText( bOutlText
),
46 mpAttribsCache( NULL
),
47 mpParaAttribsCache( NULL
),
48 mnParaAttribsCache( 0 )
52 SvxOutlinerForwarder::~SvxOutlinerForwarder()
57 sal_Int32
SvxOutlinerForwarder::GetParagraphCount() const
59 return rOutliner
.GetParagraphCount();
62 sal_Int32
SvxOutlinerForwarder::GetTextLen( sal_Int32 nParagraph
) const
64 return rOutliner
.GetEditEngine().GetTextLen( nParagraph
);
67 OUString
SvxOutlinerForwarder::GetText( const ESelection
& rSel
) const
69 //! GetText (ESelection) should probably also be in the Outliner
70 // in the time being use as the hack for the EditEngine:
71 EditEngine
* pEditEngine
= const_cast<EditEngine
*>(&rOutliner
.GetEditEngine());
72 return pEditEngine
->GetText( rSel
, LINEEND_LF
);
75 static SfxItemSet
ImplOutlinerForwarderGetAttribs( const ESelection
& rSel
, EditEngineAttribs nOnlyHardAttrib
, EditEngine
& rEditEngine
)
77 if( rSel
.nStartPara
== rSel
.nEndPara
)
79 GetAttribsFlags nFlags
= GetAttribsFlags::NONE
;
81 switch( nOnlyHardAttrib
)
83 case EditEngineAttribs_All
:
84 nFlags
= GetAttribsFlags::ALL
;
86 case EditEngineAttribs_HardAndPara
:
87 nFlags
= GetAttribsFlags::PARAATTRIBS
|GetAttribsFlags::CHARATTRIBS
;
89 case EditEngineAttribs_OnlyHard
:
90 nFlags
= GetAttribsFlags::CHARATTRIBS
;
93 OSL_FAIL("unknown flags for SvxOutlinerForwarder::GetAttribs");
95 return rEditEngine
.GetAttribs( rSel
.nStartPara
, rSel
.nStartPos
, rSel
.nEndPos
, nFlags
);
99 return rEditEngine
.GetAttribs( rSel
, nOnlyHardAttrib
);
103 SfxItemSet
SvxOutlinerForwarder::GetAttribs( const ESelection
& rSel
, EditEngineAttribs nOnlyHardAttrib
) const
105 if( mpAttribsCache
&& ( EditEngineAttribs_All
== nOnlyHardAttrib
) )
107 // have we the correct set in cache?
108 if( const_cast<SvxOutlinerForwarder
*>(this)->maAttribCacheSelection
.IsEqual(rSel
) )
110 // yes! just return the cache
111 return *mpAttribsCache
;
115 // no, we need delete the old cache
116 delete mpAttribsCache
;
117 mpAttribsCache
= NULL
;
121 //! Does it not exist on the Outliner?
122 //! and why is the GetAttribs on the EditEngine not a const?
123 EditEngine
& rEditEngine
= (EditEngine
&)rOutliner
.GetEditEngine();
125 SfxItemSet
aSet( ImplOutlinerForwarderGetAttribs( rSel
, nOnlyHardAttrib
, rEditEngine
) );
127 if( EditEngineAttribs_All
== nOnlyHardAttrib
)
129 mpAttribsCache
= new SfxItemSet( aSet
);
130 maAttribCacheSelection
= rSel
;
133 SfxStyleSheet
* pStyle
= rEditEngine
.GetStyleSheet( rSel
.nStartPara
);
135 aSet
.SetParent( &(pStyle
->GetItemSet() ) );
140 SfxItemSet
SvxOutlinerForwarder::GetParaAttribs( sal_Int32 nPara
) const
142 if( mpParaAttribsCache
)
144 // have we the correct set in cache?
145 if( nPara
== mnParaAttribsCache
)
147 // yes! just return the cache
148 return *mpParaAttribsCache
;
152 // no, we need delete the old cache
153 delete mpParaAttribsCache
;
154 mpParaAttribsCache
= NULL
;
158 mpParaAttribsCache
= new SfxItemSet( rOutliner
.GetParaAttribs( nPara
) );
159 mnParaAttribsCache
= nPara
;
161 EditEngine
& rEditEngine
= (EditEngine
&)rOutliner
.GetEditEngine();
163 SfxStyleSheet
* pStyle
= rEditEngine
.GetStyleSheet( nPara
);
165 mpParaAttribsCache
->SetParent( &(pStyle
->GetItemSet() ) );
167 return *mpParaAttribsCache
;
170 void SvxOutlinerForwarder::SetParaAttribs( sal_Int32 nPara
, const SfxItemSet
& rSet
)
174 const SfxItemSet
* pOldParent
= rSet
.GetParent();
176 const_cast<SfxItemSet
*>(&rSet
)->SetParent( NULL
);
178 rOutliner
.SetParaAttribs( nPara
, rSet
);
181 const_cast<SfxItemSet
*>(&rSet
)->SetParent( pOldParent
);
184 void SvxOutlinerForwarder::RemoveAttribs( const ESelection
& rSelection
, bool bRemoveParaAttribs
, sal_uInt16 nWhich
)
186 rOutliner
.RemoveAttribs( rSelection
, bRemoveParaAttribs
, nWhich
);
189 SfxItemPool
* SvxOutlinerForwarder::GetPool() const
191 return rOutliner
.GetEmptyItemSet().GetPool();
194 void SvxOutlinerForwarder::GetPortions( sal_Int32 nPara
, std::vector
<sal_Int32
>& rList
) const
196 ((EditEngine
&)rOutliner
.GetEditEngine()).GetPortions( nPara
, rList
);
199 void SvxOutlinerForwarder::QuickInsertText( const OUString
& rText
, const ESelection
& rSel
)
202 if( rText
.isEmpty() )
204 rOutliner
.QuickDelete( rSel
);
208 rOutliner
.QuickInsertText( rText
, rSel
);
212 void SvxOutlinerForwarder::QuickInsertLineBreak( const ESelection
& rSel
)
215 rOutliner
.QuickInsertLineBreak( rSel
);
218 void SvxOutlinerForwarder::QuickInsertField( const SvxFieldItem
& rFld
, const ESelection
& rSel
)
221 rOutliner
.QuickInsertField( rFld
, rSel
);
224 void SvxOutlinerForwarder::QuickSetAttribs( const SfxItemSet
& rSet
, const ESelection
& rSel
)
227 rOutliner
.QuickSetAttribs( rSet
, rSel
);
230 OUString
SvxOutlinerForwarder::CalcFieldValue( const SvxFieldItem
& rField
, sal_Int32 nPara
, sal_Int32 nPos
, Color
*& rpTxtColor
, Color
*& rpFldColor
)
232 return rOutliner
.CalcFieldValue( rField
, nPara
, nPos
, rpTxtColor
, rpFldColor
);
235 void SvxOutlinerForwarder::FieldClicked( const SvxFieldItem
& rField
, sal_Int32 nPara
, sal_Int32 nPos
)
237 rOutliner
.FieldClicked( rField
, nPara
, nPos
);
240 bool SvxOutlinerForwarder::IsValid() const
242 // cannot reliably query outliner state
243 // while in the middle of an update
244 return rOutliner
.GetUpdateMode();
247 SfxItemState
SvxOutlinerForwarder::GetItemState( const ESelection
& rSel
, sal_uInt16 nWhich
) const
249 return GetSvxEditEngineItemState( (EditEngine
&)rOutliner
.GetEditEngine(), rSel
, nWhich
);
252 SfxItemState
SvxOutlinerForwarder::GetItemState( sal_Int32 nPara
, sal_uInt16 nWhich
) const
254 const SfxItemSet
& rSet
= rOutliner
.GetParaAttribs( nPara
);
255 return rSet
.GetItemState( nWhich
);
259 void SvxOutlinerForwarder::flushCache()
263 delete mpAttribsCache
;
264 mpAttribsCache
= NULL
;
267 if( mpParaAttribsCache
)
269 delete mpParaAttribsCache
;
270 mpParaAttribsCache
= NULL
;
274 LanguageType
SvxOutlinerForwarder::GetLanguage( sal_Int32 nPara
, sal_Int32 nIndex
) const
276 return rOutliner
.GetLanguage(nPara
, nIndex
);
279 sal_Int32
SvxOutlinerForwarder::GetFieldCount( sal_Int32 nPara
) const
281 return rOutliner
.GetEditEngine().GetFieldCount(nPara
);
284 EFieldInfo
SvxOutlinerForwarder::GetFieldInfo( sal_Int32 nPara
, sal_uInt16 nField
) const
286 return rOutliner
.GetEditEngine().GetFieldInfo( nPara
, nField
);
289 EBulletInfo
SvxOutlinerForwarder::GetBulletInfo( sal_Int32 nPara
) const
291 return rOutliner
.GetBulletInfo( nPara
);
294 Rectangle
SvxOutlinerForwarder::GetCharBounds( sal_Int32 nPara
, sal_Int32 nIndex
) const
296 // EditEngine's 'internal' methods like GetCharacterBounds()
297 // don't rotate for vertical text.
298 Size
aSize( rOutliner
.CalcTextSize() );
299 ::std::swap( aSize
.Width(), aSize
.Height() );
300 bool bIsVertical( rOutliner
.IsVertical() );
302 // #108900# Handle virtual position one-past-the end of the string
303 if( nIndex
>= GetTextLen(nPara
) )
309 // use last character, if possible
310 aLast
= rOutliner
.GetEditEngine().GetCharacterBounds( EPosition(nPara
, nIndex
-1) );
312 // move at end of this last character, make one pixel wide
313 aLast
.Move( aLast
.Right() - aLast
.Left(), 0 );
314 aLast
.SetSize( Size(1, aLast
.GetHeight()) );
317 aLast
= SvxEditSourceHelper::EEToUserSpace( aLast
, aSize
, bIsVertical
);
321 // #109864# Bounds must lie within the paragraph
322 aLast
= GetParaBounds( nPara
);
324 // #109151# Don't use paragraph height, but line height
325 // instead. aLast is already CTL-correct
327 aLast
.SetSize( Size( rOutliner
.GetLineHeight(nPara
,0), 1 ) );
329 aLast
.SetSize( Size( 1, rOutliner
.GetLineHeight(nPara
,0) ) );
336 return SvxEditSourceHelper::EEToUserSpace( rOutliner
.GetEditEngine().GetCharacterBounds( EPosition(nPara
, nIndex
) ),
337 aSize
, bIsVertical
);
341 Rectangle
SvxOutlinerForwarder::GetParaBounds( sal_Int32 nPara
) const
343 Point aPnt
= rOutliner
.GetDocPosTopLeft( nPara
);
344 Size aSize
= rOutliner
.CalcTextSize();
346 if( rOutliner
.IsVertical() )
348 // Hargl. Outliner's 'external' methods return the rotated
349 // dimensions, 'internal' methods like GetTextHeight( n )
351 sal_uLong nWidth
= rOutliner
.GetTextHeight( nPara
);
353 return Rectangle( aSize
.Width() - aPnt
.Y() - nWidth
, 0, aSize
.Width() - aPnt
.Y(), aSize
.Height() );
357 sal_uLong nHeight
= rOutliner
.GetTextHeight( nPara
);
359 return Rectangle( 0, aPnt
.Y(), aSize
.Width(), aPnt
.Y() + nHeight
);
363 MapMode
SvxOutlinerForwarder::GetMapMode() const
365 return rOutliner
.GetRefMapMode();
368 OutputDevice
* SvxOutlinerForwarder::GetRefDevice() const
370 return rOutliner
.GetRefDevice();
373 bool SvxOutlinerForwarder::GetIndexAtPoint( const Point
& rPos
, sal_Int32
& nPara
, sal_Int32
& nIndex
) const
375 Size
aSize( rOutliner
.CalcTextSize() );
376 ::std::swap( aSize
.Width(), aSize
.Height() );
377 Point
aEEPos( SvxEditSourceHelper::UserSpaceToEE( rPos
,
379 rOutliner
.IsVertical() ));
381 EPosition aDocPos
= rOutliner
.GetEditEngine().FindDocPosition( aEEPos
);
383 nPara
= aDocPos
.nPara
;
384 nIndex
= aDocPos
.nIndex
;
389 bool SvxOutlinerForwarder::GetWordIndices( sal_Int32 nPara
, sal_Int32 nIndex
, sal_Int32
& nStart
, sal_Int32
& nEnd
) const
391 ESelection aRes
= rOutliner
.GetEditEngine().GetWord( ESelection(nPara
, nIndex
, nPara
, nIndex
), com::sun::star::i18n::WordType::DICTIONARY_WORD
);
393 if( aRes
.nStartPara
== nPara
&&
394 aRes
.nStartPara
== aRes
.nEndPara
)
396 nStart
= aRes
.nStartPos
;
405 bool SvxOutlinerForwarder::GetAttributeRun( sal_Int32
& nStartIndex
, sal_Int32
& nEndIndex
, sal_Int32 nPara
, sal_Int32 nIndex
, bool bInCell
) const
407 return SvxEditSourceHelper::GetAttributeRun( nStartIndex
, nEndIndex
, rOutliner
.GetEditEngine(), nPara
, nIndex
, bInCell
);
410 sal_Int32
SvxOutlinerForwarder::GetLineCount( sal_Int32 nPara
) const
412 return rOutliner
.GetLineCount(nPara
);
415 sal_Int32
SvxOutlinerForwarder::GetLineLen( sal_Int32 nPara
, sal_Int32 nLine
) const
417 return rOutliner
.GetLineLen(nPara
, nLine
);
420 void SvxOutlinerForwarder::GetLineBoundaries( /*out*/sal_Int32
&rStart
, /*out*/sal_Int32
&rEnd
, sal_Int32 nPara
, sal_Int32 nLine
) const
422 return rOutliner
.GetEditEngine().GetLineBoundaries( rStart
, rEnd
, nPara
, nLine
);
425 sal_Int32
SvxOutlinerForwarder::GetLineNumberAtIndex( sal_Int32 nPara
, sal_Int32 nIndex
) const
427 return rOutliner
.GetEditEngine().GetLineNumberAtIndex( nPara
, nIndex
);
430 bool SvxOutlinerForwarder::QuickFormatDoc( bool )
432 rOutliner
.QuickFormatDoc();
437 bool SvxOutlinerForwarder::Delete( const ESelection
& rSelection
)
440 rOutliner
.QuickDelete( rSelection
);
441 rOutliner
.QuickFormatDoc();
446 bool SvxOutlinerForwarder::InsertText( const OUString
& rStr
, const ESelection
& rSelection
)
449 rOutliner
.QuickInsertText( rStr
, rSelection
);
450 rOutliner
.QuickFormatDoc();
455 sal_Int16
SvxOutlinerForwarder::GetDepth( sal_Int32 nPara
) const
457 DBG_ASSERT( 0 <= nPara
&& nPara
< GetParagraphCount(), "SvxOutlinerForwarder::GetDepth: Invalid paragraph index");
459 Paragraph
* pPara
= rOutliner
.GetParagraph( nPara
);
461 sal_Int16 nLevel
= -1;
464 nLevel
= rOutliner
.GetDepth( nPara
);
469 bool SvxOutlinerForwarder::SetDepth( sal_Int32 nPara
, sal_Int16 nNewDepth
)
471 DBG_ASSERT( 0 <= nPara
&& nPara
< GetParagraphCount(), "SvxOutlinerForwarder::SetDepth: Invalid paragraph index");
473 if( (nNewDepth
>= -1) && (nNewDepth
<= 9) && (0 <= nPara
&& nPara
< GetParagraphCount()) )
475 Paragraph
* pPara
= rOutliner
.GetParagraph( nPara
);
478 rOutliner
.SetDepth( pPara
, nNewDepth
);
480 // const bool bOutlinerText = pSdrObject && (pSdrObject->GetObjInventor() == SdrInventor) && (pSdrObject->GetObjIdentifier() == OBJ_OUTLINETEXT);
482 rOutliner
.SetLevelDependendStyleSheet( nPara
);
491 sal_Int32
SvxOutlinerForwarder::GetNumberingStartValue( sal_Int32 nPara
)
493 if( 0 <= nPara
&& nPara
< GetParagraphCount() )
495 return rOutliner
.GetNumberingStartValue( nPara
);
499 OSL_FAIL( "SvxOutlinerForwarder::GetNumberingStartValue)(), Invalid paragraph index");
504 void SvxOutlinerForwarder::SetNumberingStartValue( sal_Int32 nPara
, sal_Int32 nNumberingStartValue
)
506 if( 0 <= nPara
&& nPara
< GetParagraphCount() )
508 rOutliner
.SetNumberingStartValue( nPara
, nNumberingStartValue
);
512 OSL_FAIL( "SvxOutlinerForwarder::SetNumberingStartValue)(), Invalid paragraph index");
516 bool SvxOutlinerForwarder::IsParaIsNumberingRestart( sal_Int32 nPara
)
518 if( 0 <= nPara
&& nPara
< GetParagraphCount() )
520 return rOutliner
.IsParaIsNumberingRestart( nPara
);
524 OSL_FAIL( "SvxOutlinerForwarder::IsParaIsNumberingRestart)(), Invalid paragraph index");
529 void SvxOutlinerForwarder::SetParaIsNumberingRestart( sal_Int32 nPara
, bool bParaIsNumberingRestart
)
531 if( 0 <= nPara
&& nPara
< GetParagraphCount() )
533 rOutliner
.SetParaIsNumberingRestart( nPara
, bParaIsNumberingRestart
);
537 OSL_FAIL( "SvxOutlinerForwarder::SetParaIsNumberingRestart)(), Invalid paragraph index");
541 const SfxItemSet
* SvxOutlinerForwarder::GetEmptyItemSetPtr()
543 EditEngine
& rEditEngine
= const_cast< EditEngine
& >( rOutliner
.GetEditEngine() );
544 return &rEditEngine
.GetEmptyItemSet();
547 void SvxOutlinerForwarder::AppendParagraph()
549 EditEngine
& rEditEngine
= const_cast< EditEngine
& >( rOutliner
.GetEditEngine() );
550 rEditEngine
.InsertParagraph( rEditEngine
.GetParagraphCount(), OUString() );
553 sal_Int32
SvxOutlinerForwarder::AppendTextPortion( sal_Int32 nPara
, const OUString
&rText
, const SfxItemSet
& /*rSet*/ )
557 EditEngine
& rEditEngine
= const_cast< EditEngine
& >( rOutliner
.GetEditEngine() );
558 sal_Int32 nParaCount
= rEditEngine
.GetParagraphCount();
559 DBG_ASSERT( 0 <= nPara
&& nPara
< nParaCount
, "paragraph index out of bounds" );
560 if (0 <= nPara
&& nPara
< nParaCount
)
562 nLen
= rEditEngine
.GetTextLen( nPara
);
563 rEditEngine
.QuickInsertText( rText
, ESelection( nPara
, nLen
, nPara
, nLen
) );
569 void SvxOutlinerForwarder::CopyText(const SvxTextForwarder
& rSource
)
571 const SvxOutlinerForwarder
* pSourceForwarder
= dynamic_cast< const SvxOutlinerForwarder
* >( &rSource
);
572 if( !pSourceForwarder
)
574 OutlinerParaObject
* pNewOutlinerParaObject
= pSourceForwarder
->rOutliner
.CreateParaObject();
575 rOutliner
.SetText( *pNewOutlinerParaObject
);
576 delete pNewOutlinerParaObject
;
582 sal_Int32
SvxTextForwarder::GetNumberingStartValue( sal_Int32
)
587 void SvxTextForwarder::SetNumberingStartValue( sal_Int32
, sal_Int32
)
591 bool SvxTextForwarder::IsParaIsNumberingRestart( sal_Int32
)
596 void SvxTextForwarder::SetParaIsNumberingRestart( sal_Int32
, bool )
602 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */