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 .
21 #include <osl/diagnose.h>
22 #include <tools/debug.hxx>
23 #include <svl/style.hxx>
24 #include <com/sun/star/i18n/WordType.hpp>
26 #include <svl/itemset.hxx>
27 #include <editeng/editeng.hxx>
28 #include <editeng/editdata.hxx>
29 #include <editeng/outliner.hxx>
30 #include <editeng/unoedhlp.hxx>
31 #include <svl/poolitem.hxx>
33 #include <editeng/unoforou.hxx>
34 #include <editeng/outlobj.hxx>
35 #include "unofored_internal.hxx"
37 using namespace ::com::sun::star
;
40 SvxOutlinerForwarder::SvxOutlinerForwarder( Outliner
& rOutl
, bool bOutlText
/* = false */ ) :
42 bOutlinerText( bOutlText
),
43 mnParaAttribsCache( 0 )
47 SvxOutlinerForwarder::~SvxOutlinerForwarder()
52 sal_Int32
SvxOutlinerForwarder::GetParagraphCount() const
54 return rOutliner
.GetParagraphCount();
57 sal_Int32
SvxOutlinerForwarder::GetTextLen( sal_Int32 nParagraph
) const
59 return rOutliner
.GetEditEngine().GetTextLen( nParagraph
);
62 OUString
SvxOutlinerForwarder::GetText( const ESelection
& rSel
) const
64 //! GetText (ESelection) should probably also be in the Outliner
65 // in the time being use as the hack for the EditEngine:
66 EditEngine
* pEditEngine
= const_cast<EditEngine
*>(&rOutliner
.GetEditEngine());
67 return pEditEngine
->GetText( rSel
);
70 static SfxItemSet
ImplOutlinerForwarderGetAttribs( const ESelection
& rSel
, EditEngineAttribs nOnlyHardAttrib
, EditEngine
& rEditEngine
)
72 if( rSel
.nStartPara
== rSel
.nEndPara
)
74 GetAttribsFlags nFlags
= GetAttribsFlags::NONE
;
76 switch( nOnlyHardAttrib
)
78 case EditEngineAttribs::All
:
79 nFlags
= GetAttribsFlags::ALL
;
81 case EditEngineAttribs::OnlyHard
:
82 nFlags
= GetAttribsFlags::CHARATTRIBS
;
85 OSL_FAIL("unknown flags for SvxOutlinerForwarder::GetAttribs");
87 return rEditEngine
.GetAttribs( rSel
.nStartPara
, rSel
.nStartPos
, rSel
.nEndPos
, nFlags
);
91 return rEditEngine
.GetAttribs( rSel
, nOnlyHardAttrib
);
95 SfxItemSet
SvxOutlinerForwarder::GetAttribs( const ESelection
& rSel
, EditEngineAttribs nOnlyHardAttrib
) const
97 if( mpAttribsCache
&& ( EditEngineAttribs::All
== nOnlyHardAttrib
) )
99 // have we the correct set in cache?
100 if( maAttribCacheSelection
== rSel
)
102 // yes! just return the cache
103 return *mpAttribsCache
;
107 // no, we need delete the old cache
108 mpAttribsCache
.reset();
112 //! Does it not exist on the Outliner?
113 //! and why is the GetAttribs on the EditEngine not a const?
114 EditEngine
& rEditEngine
= const_cast<EditEngine
&>(rOutliner
.GetEditEngine());
116 SfxItemSet
aSet( ImplOutlinerForwarderGetAttribs( rSel
, nOnlyHardAttrib
, rEditEngine
) );
118 if( EditEngineAttribs::All
== nOnlyHardAttrib
)
120 mpAttribsCache
.reset(new SfxItemSet( aSet
));
121 maAttribCacheSelection
= rSel
;
124 SfxStyleSheet
* pStyle
= rEditEngine
.GetStyleSheet( rSel
.nStartPara
);
126 aSet
.SetParent( &(pStyle
->GetItemSet() ) );
131 SfxItemSet
SvxOutlinerForwarder::GetParaAttribs( sal_Int32 nPara
) const
133 if( mpParaAttribsCache
)
135 // have we the correct set in cache?
136 if( nPara
== mnParaAttribsCache
)
138 // yes! just return the cache
139 return *mpParaAttribsCache
;
143 // no, we need delete the old cache
144 mpParaAttribsCache
.reset();
148 mpParaAttribsCache
.reset(new SfxItemSet( rOutliner
.GetParaAttribs( nPara
) ));
149 mnParaAttribsCache
= nPara
;
151 EditEngine
& rEditEngine
= const_cast<EditEngine
&>(rOutliner
.GetEditEngine());
153 SfxStyleSheet
* pStyle
= rEditEngine
.GetStyleSheet( nPara
);
155 mpParaAttribsCache
->SetParent( &(pStyle
->GetItemSet() ) );
157 return *mpParaAttribsCache
;
160 void SvxOutlinerForwarder::SetParaAttribs( sal_Int32 nPara
, const SfxItemSet
& rSet
)
164 const SfxItemSet
* pOldParent
= rSet
.GetParent();
166 const_cast<SfxItemSet
*>(&rSet
)->SetParent( nullptr );
168 rOutliner
.SetParaAttribs( nPara
, rSet
);
171 const_cast<SfxItemSet
*>(&rSet
)->SetParent( pOldParent
);
174 void SvxOutlinerForwarder::RemoveAttribs( const ESelection
& rSelection
)
176 rOutliner
.RemoveAttribs( rSelection
, false/*bRemoveParaAttribs*/, 0 );
179 SfxItemPool
* SvxOutlinerForwarder::GetPool() const
181 return rOutliner
.GetEmptyItemSet().GetPool();
184 void SvxOutlinerForwarder::GetPortions( sal_Int32 nPara
, std::vector
<sal_Int32
>& rList
) const
186 const_cast<EditEngine
&>(rOutliner
.GetEditEngine()).GetPortions( nPara
, rList
);
189 void SvxOutlinerForwarder::QuickInsertText( const OUString
& rText
, const ESelection
& rSel
)
192 if( rText
.isEmpty() )
194 rOutliner
.QuickDelete( rSel
);
198 rOutliner
.QuickInsertText( rText
, rSel
);
202 void SvxOutlinerForwarder::QuickInsertLineBreak( const ESelection
& rSel
)
205 rOutliner
.QuickInsertLineBreak( rSel
);
208 void SvxOutlinerForwarder::QuickInsertField( const SvxFieldItem
& rFld
, const ESelection
& rSel
)
211 rOutliner
.QuickInsertField( rFld
, rSel
);
214 void SvxOutlinerForwarder::QuickSetAttribs( const SfxItemSet
& rSet
, const ESelection
& rSel
)
217 rOutliner
.QuickSetAttribs( rSet
, rSel
);
220 OUString
SvxOutlinerForwarder::CalcFieldValue( const SvxFieldItem
& rField
, sal_Int32 nPara
, sal_Int32 nPos
, std::optional
<Color
>& rpTxtColor
, std::optional
<Color
>& rpFldColor
)
222 return rOutliner
.CalcFieldValue( rField
, nPara
, nPos
, rpTxtColor
, rpFldColor
);
225 void SvxOutlinerForwarder::FieldClicked( const SvxFieldItem
& /*rField*/ )
229 bool SvxOutlinerForwarder::IsValid() const
231 // cannot reliably query outliner state
232 // while in the middle of an update
233 return rOutliner
.GetUpdateMode();
236 SfxItemState
SvxOutlinerForwarder::GetItemState( const ESelection
& rSel
, sal_uInt16 nWhich
) const
238 return GetSvxEditEngineItemState( rOutliner
.GetEditEngine(), rSel
, nWhich
);
241 SfxItemState
SvxOutlinerForwarder::GetItemState( sal_Int32 nPara
, sal_uInt16 nWhich
) const
243 const SfxItemSet
& rSet
= rOutliner
.GetParaAttribs( nPara
);
244 return rSet
.GetItemState( nWhich
);
248 void SvxOutlinerForwarder::flushCache()
250 mpAttribsCache
.reset();
251 mpParaAttribsCache
.reset();
254 LanguageType
SvxOutlinerForwarder::GetLanguage( sal_Int32 nPara
, sal_Int32 nIndex
) const
256 return rOutliner
.GetLanguage(nPara
, nIndex
);
259 sal_Int32
SvxOutlinerForwarder::GetFieldCount( sal_Int32 nPara
) const
261 return rOutliner
.GetEditEngine().GetFieldCount(nPara
);
264 EFieldInfo
SvxOutlinerForwarder::GetFieldInfo( sal_Int32 nPara
, sal_uInt16 nField
) const
266 return rOutliner
.GetEditEngine().GetFieldInfo( nPara
, nField
);
269 EBulletInfo
SvxOutlinerForwarder::GetBulletInfo( sal_Int32 nPara
) const
271 return rOutliner
.GetBulletInfo( nPara
);
274 tools::Rectangle
SvxOutlinerForwarder::GetCharBounds( sal_Int32 nPara
, sal_Int32 nIndex
) const
276 // EditEngine's 'internal' methods like GetCharacterBounds()
277 // don't rotate for vertical text.
278 Size
aSize( rOutliner
.CalcTextSize() );
279 // swap width and height
280 tools::Long tmp
= aSize
.Width();
281 aSize
.setWidth(aSize
.Height());
282 aSize
.setHeight(tmp
);
283 bool bIsVertical( rOutliner
.IsVertical() );
285 // #108900# Handle virtual position one-past-the end of the string
286 if( nIndex
>= GetTextLen(nPara
) )
288 tools::Rectangle aLast
;
292 // use last character, if possible
293 aLast
= rOutliner
.GetEditEngine().GetCharacterBounds( EPosition(nPara
, nIndex
-1) );
295 // move at end of this last character, make one pixel wide
296 aLast
.Move( aLast
.Right() - aLast
.Left(), 0 );
297 aLast
.SetSize( Size(1, aLast
.GetHeight()) );
300 aLast
= SvxEditSourceHelper::EEToUserSpace( aLast
, aSize
, bIsVertical
);
304 // #109864# Bounds must lie within the paragraph
305 aLast
= GetParaBounds( nPara
);
307 // #109151# Don't use paragraph height, but line height
308 // instead. aLast is already CTL-correct
310 aLast
.SetSize( Size( rOutliner
.GetLineHeight(nPara
), 1 ) );
312 aLast
.SetSize( Size( 1, rOutliner
.GetLineHeight(nPara
) ) );
319 return SvxEditSourceHelper::EEToUserSpace( rOutliner
.GetEditEngine().GetCharacterBounds( EPosition(nPara
, nIndex
) ),
320 aSize
, bIsVertical
);
324 tools::Rectangle
SvxOutlinerForwarder::GetParaBounds( sal_Int32 nPara
) const
326 return rOutliner
.GetParaBounds( nPara
);
329 MapMode
SvxOutlinerForwarder::GetMapMode() const
331 return rOutliner
.GetRefMapMode();
334 OutputDevice
* SvxOutlinerForwarder::GetRefDevice() const
336 return rOutliner
.GetRefDevice();
339 bool SvxOutlinerForwarder::GetIndexAtPoint( const Point
& rPos
, sal_Int32
& nPara
, sal_Int32
& nIndex
) const
341 Size
aSize( rOutliner
.CalcTextSize() );
342 // swap width and height
343 tools::Long tmp
= aSize
.Width();
344 aSize
.setWidth(aSize
.Height());
345 aSize
.setHeight(tmp
);
346 Point
aEEPos( SvxEditSourceHelper::UserSpaceToEE( rPos
,
348 rOutliner
.IsVertical() ));
350 EPosition aDocPos
= rOutliner
.GetEditEngine().FindDocPosition( aEEPos
);
352 nPara
= aDocPos
.nPara
;
353 nIndex
= aDocPos
.nIndex
;
358 bool SvxOutlinerForwarder::GetWordIndices( sal_Int32 nPara
, sal_Int32 nIndex
, sal_Int32
& nStart
, sal_Int32
& nEnd
) const
360 ESelection aRes
= rOutliner
.GetEditEngine().GetWord( ESelection(nPara
, nIndex
, nPara
, nIndex
), css::i18n::WordType::DICTIONARY_WORD
);
362 if( aRes
.nStartPara
== nPara
&&
363 aRes
.nStartPara
== aRes
.nEndPara
)
365 nStart
= aRes
.nStartPos
;
374 bool SvxOutlinerForwarder::GetAttributeRun( sal_Int32
& nStartIndex
, sal_Int32
& nEndIndex
, sal_Int32 nPara
, sal_Int32 nIndex
, bool bInCell
) const
376 SvxEditSourceHelper::GetAttributeRun( nStartIndex
, nEndIndex
, rOutliner
.GetEditEngine(), nPara
, nIndex
, bInCell
);
380 sal_Int32
SvxOutlinerForwarder::GetLineCount( sal_Int32 nPara
) const
382 return rOutliner
.GetLineCount(nPara
);
385 sal_Int32
SvxOutlinerForwarder::GetLineLen( sal_Int32 nPara
, sal_Int32 nLine
) const
387 return rOutliner
.GetLineLen(nPara
, nLine
);
390 void SvxOutlinerForwarder::GetLineBoundaries( /*out*/sal_Int32
&rStart
, /*out*/sal_Int32
&rEnd
, sal_Int32 nPara
, sal_Int32 nLine
) const
392 return rOutliner
.GetEditEngine().GetLineBoundaries( rStart
, rEnd
, nPara
, nLine
);
395 sal_Int32
SvxOutlinerForwarder::GetLineNumberAtIndex( sal_Int32 nPara
, sal_Int32 nIndex
) const
397 return rOutliner
.GetEditEngine().GetLineNumberAtIndex( nPara
, nIndex
);
400 bool SvxOutlinerForwarder::QuickFormatDoc( bool )
402 rOutliner
.QuickFormatDoc();
407 bool SvxOutlinerForwarder::Delete( const ESelection
& rSelection
)
410 rOutliner
.QuickDelete( rSelection
);
411 rOutliner
.QuickFormatDoc();
416 bool SvxOutlinerForwarder::InsertText( const OUString
& rStr
, const ESelection
& rSelection
)
419 rOutliner
.QuickInsertText( rStr
, rSelection
);
420 rOutliner
.QuickFormatDoc();
425 sal_Int16
SvxOutlinerForwarder::GetDepth( sal_Int32 nPara
) const
427 DBG_ASSERT( 0 <= nPara
&& nPara
< GetParagraphCount(), "SvxOutlinerForwarder::GetDepth: Invalid paragraph index");
429 Paragraph
* pPara
= rOutliner
.GetParagraph( nPara
);
431 sal_Int16 nLevel
= -1;
434 nLevel
= rOutliner
.GetDepth( nPara
);
439 bool SvxOutlinerForwarder::SetDepth( sal_Int32 nPara
, sal_Int16 nNewDepth
)
441 DBG_ASSERT( 0 <= nPara
&& nPara
< GetParagraphCount(), "SvxOutlinerForwarder::SetDepth: Invalid paragraph index");
443 if( (nNewDepth
>= -1) && (nNewDepth
<= 9) && (0 <= nPara
&& nPara
< GetParagraphCount()) )
445 Paragraph
* pPara
= rOutliner
.GetParagraph( nPara
);
448 rOutliner
.SetDepth( pPara
, nNewDepth
);
450 // const bool bOutlinerText = pSdrObject && (pSdrObject->GetObjInventor() == SdrInventor::Default) && (pSdrObject->GetObjIdentifier() == OBJ_OUTLINETEXT);
452 rOutliner
.SetLevelDependentStyleSheet( nPara
);
461 sal_Int32
SvxOutlinerForwarder::GetNumberingStartValue( sal_Int32 nPara
)
463 if( 0 <= nPara
&& nPara
< GetParagraphCount() )
465 return rOutliner
.GetNumberingStartValue( nPara
);
469 OSL_FAIL( "SvxOutlinerForwarder::GetNumberingStartValue)(), Invalid paragraph index");
474 void SvxOutlinerForwarder::SetNumberingStartValue( sal_Int32 nPara
, sal_Int32 nNumberingStartValue
)
476 if( 0 <= nPara
&& nPara
< GetParagraphCount() )
478 rOutliner
.SetNumberingStartValue( nPara
, nNumberingStartValue
);
482 OSL_FAIL( "SvxOutlinerForwarder::SetNumberingStartValue)(), Invalid paragraph index");
486 bool SvxOutlinerForwarder::IsParaIsNumberingRestart( sal_Int32 nPara
)
488 if( 0 <= nPara
&& nPara
< GetParagraphCount() )
490 return rOutliner
.IsParaIsNumberingRestart( nPara
);
494 OSL_FAIL( "SvxOutlinerForwarder::IsParaIsNumberingRestart)(), Invalid paragraph index");
499 void SvxOutlinerForwarder::SetParaIsNumberingRestart( sal_Int32 nPara
, bool bParaIsNumberingRestart
)
501 if( 0 <= nPara
&& nPara
< GetParagraphCount() )
503 rOutliner
.SetParaIsNumberingRestart( nPara
, bParaIsNumberingRestart
);
507 OSL_FAIL( "SvxOutlinerForwarder::SetParaIsNumberingRestart)(), Invalid paragraph index");
511 const SfxItemSet
* SvxOutlinerForwarder::GetEmptyItemSetPtr()
513 EditEngine
& rEditEngine
= const_cast< EditEngine
& >( rOutliner
.GetEditEngine() );
514 return &rEditEngine
.GetEmptyItemSet();
517 void SvxOutlinerForwarder::AppendParagraph()
519 EditEngine
& rEditEngine
= const_cast< EditEngine
& >( rOutliner
.GetEditEngine() );
520 rEditEngine
.InsertParagraph( rEditEngine
.GetParagraphCount(), OUString() );
523 sal_Int32
SvxOutlinerForwarder::AppendTextPortion( sal_Int32 nPara
, const OUString
&rText
, const SfxItemSet
& /*rSet*/ )
527 EditEngine
& rEditEngine
= const_cast< EditEngine
& >( rOutliner
.GetEditEngine() );
528 sal_Int32 nParaCount
= rEditEngine
.GetParagraphCount();
529 DBG_ASSERT( 0 <= nPara
&& nPara
< nParaCount
, "paragraph index out of bounds" );
530 if (0 <= nPara
&& nPara
< nParaCount
)
532 nLen
= rEditEngine
.GetTextLen( nPara
);
533 rEditEngine
.QuickInsertText( rText
, ESelection( nPara
, nLen
, nPara
, nLen
) );
539 void SvxOutlinerForwarder::CopyText(const SvxTextForwarder
& rSource
)
541 const SvxOutlinerForwarder
* pSourceForwarder
= dynamic_cast< const SvxOutlinerForwarder
* >( &rSource
);
542 if( !pSourceForwarder
)
544 std::unique_ptr
<OutlinerParaObject
> pNewOutlinerParaObject
= pSourceForwarder
->rOutliner
.CreateParaObject();
545 rOutliner
.SetText( *pNewOutlinerParaObject
);
549 sal_Int32
SvxTextForwarder::GetNumberingStartValue( sal_Int32
)
554 void SvxTextForwarder::SetNumberingStartValue( sal_Int32
, sal_Int32
)
558 bool SvxTextForwarder::IsParaIsNumberingRestart( sal_Int32
)
563 void SvxTextForwarder::SetParaIsNumberingRestart( sal_Int32
, bool )
568 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */