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 <osl/diagnose.h>
23 #include <tools/debug.hxx>
24 #include <svl/style.hxx>
25 #include <com/sun/star/i18n/WordType.hpp>
27 #include <svl/itemset.hxx>
28 #include <editeng/editeng.hxx>
29 #include <editeng/editdata.hxx>
30 #include <editeng/outliner.hxx>
31 #include <editeng/unoedhlp.hxx>
32 #include <svl/poolitem.hxx>
33 #include <vcl/wrkwin.hxx>
34 #include <editeng/eeitem.hxx>
36 #include <editeng/unoforou.hxx>
37 #include <editeng/unofored.hxx>
38 #include <editeng/outlobj.hxx>
39 #include "unofored_internal.hxx"
41 using namespace ::com::sun::star
;
44 SvxOutlinerForwarder::SvxOutlinerForwarder( Outliner
& rOutl
, bool bOutlText
/* = false */ ) :
46 bOutlinerText( bOutlText
),
47 mnParaAttribsCache( 0 )
51 SvxOutlinerForwarder::~SvxOutlinerForwarder()
56 sal_Int32
SvxOutlinerForwarder::GetParagraphCount() const
58 return rOutliner
.GetParagraphCount();
61 sal_Int32
SvxOutlinerForwarder::GetTextLen( sal_Int32 nParagraph
) const
63 return rOutliner
.GetEditEngine().GetTextLen( nParagraph
);
66 OUString
SvxOutlinerForwarder::GetText( const ESelection
& rSel
) const
68 //! GetText (ESelection) should probably also be in the Outliner
69 // in the time being use as the hack for the EditEngine:
70 EditEngine
* pEditEngine
= const_cast<EditEngine
*>(&rOutliner
.GetEditEngine());
71 return pEditEngine
->GetText( rSel
);
74 static SfxItemSet
ImplOutlinerForwarderGetAttribs( const ESelection
& rSel
, EditEngineAttribs nOnlyHardAttrib
, EditEngine
& rEditEngine
)
76 if( rSel
.nStartPara
== rSel
.nEndPara
)
78 GetAttribsFlags nFlags
= GetAttribsFlags::NONE
;
80 switch( nOnlyHardAttrib
)
82 case EditEngineAttribs::All
:
83 nFlags
= GetAttribsFlags::ALL
;
85 case EditEngineAttribs::OnlyHard
:
86 nFlags
= GetAttribsFlags::CHARATTRIBS
;
89 OSL_FAIL("unknown flags for SvxOutlinerForwarder::GetAttribs");
91 return rEditEngine
.GetAttribs( rSel
.nStartPara
, rSel
.nStartPos
, rSel
.nEndPos
, nFlags
);
95 return rEditEngine
.GetAttribs( rSel
, nOnlyHardAttrib
);
99 SfxItemSet
SvxOutlinerForwarder::GetAttribs( const ESelection
& rSel
, EditEngineAttribs nOnlyHardAttrib
) const
101 if( mpAttribsCache
&& ( EditEngineAttribs::All
== nOnlyHardAttrib
) )
103 // have we the correct set in cache?
104 if( maAttribCacheSelection
== rSel
)
106 // yes! just return the cache
107 return *mpAttribsCache
;
111 // no, we need delete the old cache
112 mpAttribsCache
.reset();
116 //! Does it not exist on the Outliner?
117 //! and why is the GetAttribs on the EditEngine not a const?
118 EditEngine
& rEditEngine
= const_cast<EditEngine
&>(rOutliner
.GetEditEngine());
120 SfxItemSet
aSet( ImplOutlinerForwarderGetAttribs( rSel
, nOnlyHardAttrib
, rEditEngine
) );
122 if( EditEngineAttribs::All
== nOnlyHardAttrib
)
124 mpAttribsCache
.reset(new SfxItemSet( aSet
));
125 maAttribCacheSelection
= rSel
;
128 SfxStyleSheet
* pStyle
= rEditEngine
.GetStyleSheet( rSel
.nStartPara
);
130 aSet
.SetParent( &(pStyle
->GetItemSet() ) );
135 SfxItemSet
SvxOutlinerForwarder::GetParaAttribs( sal_Int32 nPara
) const
137 if( mpParaAttribsCache
)
139 // have we the correct set in cache?
140 if( nPara
== mnParaAttribsCache
)
142 // yes! just return the cache
143 return *mpParaAttribsCache
;
147 // no, we need delete the old cache
148 mpParaAttribsCache
.reset();
152 mpParaAttribsCache
.reset(new SfxItemSet( rOutliner
.GetParaAttribs( nPara
) ));
153 mnParaAttribsCache
= nPara
;
155 EditEngine
& rEditEngine
= const_cast<EditEngine
&>(rOutliner
.GetEditEngine());
157 SfxStyleSheet
* pStyle
= rEditEngine
.GetStyleSheet( nPara
);
159 mpParaAttribsCache
->SetParent( &(pStyle
->GetItemSet() ) );
161 return *mpParaAttribsCache
;
164 void SvxOutlinerForwarder::SetParaAttribs( sal_Int32 nPara
, const SfxItemSet
& rSet
)
168 const SfxItemSet
* pOldParent
= rSet
.GetParent();
170 const_cast<SfxItemSet
*>(&rSet
)->SetParent( nullptr );
172 rOutliner
.SetParaAttribs( nPara
, rSet
);
175 const_cast<SfxItemSet
*>(&rSet
)->SetParent( pOldParent
);
178 void SvxOutlinerForwarder::RemoveAttribs( const ESelection
& rSelection
)
180 rOutliner
.RemoveAttribs( rSelection
, false/*bRemoveParaAttribs*/, 0 );
183 SfxItemPool
* SvxOutlinerForwarder::GetPool() const
185 return rOutliner
.GetEmptyItemSet().GetPool();
188 void SvxOutlinerForwarder::GetPortions( sal_Int32 nPara
, std::vector
<sal_Int32
>& rList
) const
190 const_cast<EditEngine
&>(rOutliner
.GetEditEngine()).GetPortions( nPara
, rList
);
193 void SvxOutlinerForwarder::QuickInsertText( const OUString
& rText
, const ESelection
& rSel
)
196 if( rText
.isEmpty() )
198 rOutliner
.QuickDelete( rSel
);
202 rOutliner
.QuickInsertText( rText
, rSel
);
206 void SvxOutlinerForwarder::QuickInsertLineBreak( const ESelection
& rSel
)
209 rOutliner
.QuickInsertLineBreak( rSel
);
212 void SvxOutlinerForwarder::QuickInsertField( const SvxFieldItem
& rFld
, const ESelection
& rSel
)
215 rOutliner
.QuickInsertField( rFld
, rSel
);
218 void SvxOutlinerForwarder::QuickSetAttribs( const SfxItemSet
& rSet
, const ESelection
& rSel
)
221 rOutliner
.QuickSetAttribs( rSet
, rSel
);
224 OUString
SvxOutlinerForwarder::CalcFieldValue( const SvxFieldItem
& rField
, sal_Int32 nPara
, sal_Int32 nPos
, boost::optional
<Color
>& rpTxtColor
, boost::optional
<Color
>& rpFldColor
)
226 return rOutliner
.CalcFieldValue( rField
, nPara
, nPos
, rpTxtColor
, rpFldColor
);
229 void SvxOutlinerForwarder::FieldClicked( const SvxFieldItem
& /*rField*/, sal_Int32
/*nPara*/, sal_Int32
/*nPos*/ )
233 bool SvxOutlinerForwarder::IsValid() const
235 // cannot reliably query outliner state
236 // while in the middle of an update
237 return rOutliner
.GetUpdateMode();
240 SfxItemState
SvxOutlinerForwarder::GetItemState( const ESelection
& rSel
, sal_uInt16 nWhich
) const
242 return GetSvxEditEngineItemState( rOutliner
.GetEditEngine(), rSel
, nWhich
);
245 SfxItemState
SvxOutlinerForwarder::GetItemState( sal_Int32 nPara
, sal_uInt16 nWhich
) const
247 const SfxItemSet
& rSet
= rOutliner
.GetParaAttribs( nPara
);
248 return rSet
.GetItemState( nWhich
);
252 void SvxOutlinerForwarder::flushCache()
254 mpAttribsCache
.reset();
255 mpParaAttribsCache
.reset();
258 LanguageType
SvxOutlinerForwarder::GetLanguage( sal_Int32 nPara
, sal_Int32 nIndex
) const
260 return rOutliner
.GetLanguage(nPara
, nIndex
);
263 sal_Int32
SvxOutlinerForwarder::GetFieldCount( sal_Int32 nPara
) const
265 return rOutliner
.GetEditEngine().GetFieldCount(nPara
);
268 EFieldInfo
SvxOutlinerForwarder::GetFieldInfo( sal_Int32 nPara
, sal_uInt16 nField
) const
270 return rOutliner
.GetEditEngine().GetFieldInfo( nPara
, nField
);
273 EBulletInfo
SvxOutlinerForwarder::GetBulletInfo( sal_Int32 nPara
) const
275 return rOutliner
.GetBulletInfo( nPara
);
278 tools::Rectangle
SvxOutlinerForwarder::GetCharBounds( sal_Int32 nPara
, sal_Int32 nIndex
) const
280 // EditEngine's 'internal' methods like GetCharacterBounds()
281 // don't rotate for vertical text.
282 Size
aSize( rOutliner
.CalcTextSize() );
283 // swap width and height
284 long tmp
= aSize
.Width();
285 aSize
.setWidth(aSize
.Height());
286 aSize
.setHeight(tmp
);
287 bool bIsVertical( rOutliner
.IsVertical() );
289 // #108900# Handle virtual position one-past-the end of the string
290 if( nIndex
>= GetTextLen(nPara
) )
292 tools::Rectangle aLast
;
296 // use last character, if possible
297 aLast
= rOutliner
.GetEditEngine().GetCharacterBounds( EPosition(nPara
, nIndex
-1) );
299 // move at end of this last character, make one pixel wide
300 aLast
.Move( aLast
.Right() - aLast
.Left(), 0 );
301 aLast
.SetSize( Size(1, aLast
.GetHeight()) );
304 aLast
= SvxEditSourceHelper::EEToUserSpace( aLast
, aSize
, bIsVertical
);
308 // #109864# Bounds must lie within the paragraph
309 aLast
= GetParaBounds( nPara
);
311 // #109151# Don't use paragraph height, but line height
312 // instead. aLast is already CTL-correct
314 aLast
.SetSize( Size( rOutliner
.GetLineHeight(nPara
), 1 ) );
316 aLast
.SetSize( Size( 1, rOutliner
.GetLineHeight(nPara
) ) );
323 return SvxEditSourceHelper::EEToUserSpace( rOutliner
.GetEditEngine().GetCharacterBounds( EPosition(nPara
, nIndex
) ),
324 aSize
, bIsVertical
);
328 tools::Rectangle
SvxOutlinerForwarder::GetParaBounds( sal_Int32 nPara
) const
330 return rOutliner
.GetParaBounds( nPara
);
333 MapMode
SvxOutlinerForwarder::GetMapMode() const
335 return rOutliner
.GetRefMapMode();
338 OutputDevice
* SvxOutlinerForwarder::GetRefDevice() const
340 return rOutliner
.GetRefDevice();
343 bool SvxOutlinerForwarder::GetIndexAtPoint( const Point
& rPos
, sal_Int32
& nPara
, sal_Int32
& nIndex
) const
345 Size
aSize( rOutliner
.CalcTextSize() );
346 // swap width and height
347 long tmp
= aSize
.Width();
348 aSize
.setWidth(aSize
.Height());
349 aSize
.setHeight(tmp
);
350 Point
aEEPos( SvxEditSourceHelper::UserSpaceToEE( rPos
,
352 rOutliner
.IsVertical() ));
354 EPosition aDocPos
= rOutliner
.GetEditEngine().FindDocPosition( aEEPos
);
356 nPara
= aDocPos
.nPara
;
357 nIndex
= aDocPos
.nIndex
;
362 bool SvxOutlinerForwarder::GetWordIndices( sal_Int32 nPara
, sal_Int32 nIndex
, sal_Int32
& nStart
, sal_Int32
& nEnd
) const
364 ESelection aRes
= rOutliner
.GetEditEngine().GetWord( ESelection(nPara
, nIndex
, nPara
, nIndex
), css::i18n::WordType::DICTIONARY_WORD
);
366 if( aRes
.nStartPara
== nPara
&&
367 aRes
.nStartPara
== aRes
.nEndPara
)
369 nStart
= aRes
.nStartPos
;
378 bool SvxOutlinerForwarder::GetAttributeRun( sal_Int32
& nStartIndex
, sal_Int32
& nEndIndex
, sal_Int32 nPara
, sal_Int32 nIndex
, bool bInCell
) const
380 SvxEditSourceHelper::GetAttributeRun( nStartIndex
, nEndIndex
, rOutliner
.GetEditEngine(), nPara
, nIndex
, bInCell
);
384 sal_Int32
SvxOutlinerForwarder::GetLineCount( sal_Int32 nPara
) const
386 return rOutliner
.GetLineCount(nPara
);
389 sal_Int32
SvxOutlinerForwarder::GetLineLen( sal_Int32 nPara
, sal_Int32 nLine
) const
391 return rOutliner
.GetLineLen(nPara
, nLine
);
394 void SvxOutlinerForwarder::GetLineBoundaries( /*out*/sal_Int32
&rStart
, /*out*/sal_Int32
&rEnd
, sal_Int32 nPara
, sal_Int32 nLine
) const
396 return rOutliner
.GetEditEngine().GetLineBoundaries( rStart
, rEnd
, nPara
, nLine
);
399 sal_Int32
SvxOutlinerForwarder::GetLineNumberAtIndex( sal_Int32 nPara
, sal_Int32 nIndex
) const
401 return rOutliner
.GetEditEngine().GetLineNumberAtIndex( nPara
, nIndex
);
404 bool SvxOutlinerForwarder::QuickFormatDoc( bool )
406 rOutliner
.QuickFormatDoc();
411 bool SvxOutlinerForwarder::Delete( const ESelection
& rSelection
)
414 rOutliner
.QuickDelete( rSelection
);
415 rOutliner
.QuickFormatDoc();
420 bool SvxOutlinerForwarder::InsertText( const OUString
& rStr
, const ESelection
& rSelection
)
423 rOutliner
.QuickInsertText( rStr
, rSelection
);
424 rOutliner
.QuickFormatDoc();
429 sal_Int16
SvxOutlinerForwarder::GetDepth( sal_Int32 nPara
) const
431 DBG_ASSERT( 0 <= nPara
&& nPara
< GetParagraphCount(), "SvxOutlinerForwarder::GetDepth: Invalid paragraph index");
433 Paragraph
* pPara
= rOutliner
.GetParagraph( nPara
);
435 sal_Int16 nLevel
= -1;
438 nLevel
= rOutliner
.GetDepth( nPara
);
443 bool SvxOutlinerForwarder::SetDepth( sal_Int32 nPara
, sal_Int16 nNewDepth
)
445 DBG_ASSERT( 0 <= nPara
&& nPara
< GetParagraphCount(), "SvxOutlinerForwarder::SetDepth: Invalid paragraph index");
447 if( (nNewDepth
>= -1) && (nNewDepth
<= 9) && (0 <= nPara
&& nPara
< GetParagraphCount()) )
449 Paragraph
* pPara
= rOutliner
.GetParagraph( nPara
);
452 rOutliner
.SetDepth( pPara
, nNewDepth
);
454 // const bool bOutlinerText = pSdrObject && (pSdrObject->GetObjInventor() == SdrInventor::Default) && (pSdrObject->GetObjIdentifier() == OBJ_OUTLINETEXT);
456 rOutliner
.SetLevelDependentStyleSheet( nPara
);
465 sal_Int32
SvxOutlinerForwarder::GetNumberingStartValue( sal_Int32 nPara
)
467 if( 0 <= nPara
&& nPara
< GetParagraphCount() )
469 return rOutliner
.GetNumberingStartValue( nPara
);
473 OSL_FAIL( "SvxOutlinerForwarder::GetNumberingStartValue)(), Invalid paragraph index");
478 void SvxOutlinerForwarder::SetNumberingStartValue( sal_Int32 nPara
, sal_Int32 nNumberingStartValue
)
480 if( 0 <= nPara
&& nPara
< GetParagraphCount() )
482 rOutliner
.SetNumberingStartValue( nPara
, nNumberingStartValue
);
486 OSL_FAIL( "SvxOutlinerForwarder::SetNumberingStartValue)(), Invalid paragraph index");
490 bool SvxOutlinerForwarder::IsParaIsNumberingRestart( sal_Int32 nPara
)
492 if( 0 <= nPara
&& nPara
< GetParagraphCount() )
494 return rOutliner
.IsParaIsNumberingRestart( nPara
);
498 OSL_FAIL( "SvxOutlinerForwarder::IsParaIsNumberingRestart)(), Invalid paragraph index");
503 void SvxOutlinerForwarder::SetParaIsNumberingRestart( sal_Int32 nPara
, bool bParaIsNumberingRestart
)
505 if( 0 <= nPara
&& nPara
< GetParagraphCount() )
507 rOutliner
.SetParaIsNumberingRestart( nPara
, bParaIsNumberingRestart
);
511 OSL_FAIL( "SvxOutlinerForwarder::SetParaIsNumberingRestart)(), Invalid paragraph index");
515 const SfxItemSet
* SvxOutlinerForwarder::GetEmptyItemSetPtr()
517 EditEngine
& rEditEngine
= const_cast< EditEngine
& >( rOutliner
.GetEditEngine() );
518 return &rEditEngine
.GetEmptyItemSet();
521 void SvxOutlinerForwarder::AppendParagraph()
523 EditEngine
& rEditEngine
= const_cast< EditEngine
& >( rOutliner
.GetEditEngine() );
524 rEditEngine
.InsertParagraph( rEditEngine
.GetParagraphCount(), OUString() );
527 sal_Int32
SvxOutlinerForwarder::AppendTextPortion( sal_Int32 nPara
, const OUString
&rText
, const SfxItemSet
& /*rSet*/ )
531 EditEngine
& rEditEngine
= const_cast< EditEngine
& >( rOutliner
.GetEditEngine() );
532 sal_Int32 nParaCount
= rEditEngine
.GetParagraphCount();
533 DBG_ASSERT( 0 <= nPara
&& nPara
< nParaCount
, "paragraph index out of bounds" );
534 if (0 <= nPara
&& nPara
< nParaCount
)
536 nLen
= rEditEngine
.GetTextLen( nPara
);
537 rEditEngine
.QuickInsertText( rText
, ESelection( nPara
, nLen
, nPara
, nLen
) );
543 void SvxOutlinerForwarder::CopyText(const SvxTextForwarder
& rSource
)
545 const SvxOutlinerForwarder
* pSourceForwarder
= dynamic_cast< const SvxOutlinerForwarder
* >( &rSource
);
546 if( !pSourceForwarder
)
548 std::unique_ptr
<OutlinerParaObject
> pNewOutlinerParaObject
= pSourceForwarder
->rOutliner
.CreateParaObject();
549 rOutliner
.SetText( *pNewOutlinerParaObject
);
553 sal_Int32
SvxTextForwarder::GetNumberingStartValue( sal_Int32
)
558 void SvxTextForwarder::SetNumberingStartValue( sal_Int32
, sal_Int32
)
562 bool SvxTextForwarder::IsParaIsNumberingRestart( sal_Int32
)
567 void SvxTextForwarder::SetParaIsNumberingRestart( sal_Int32
, bool )
572 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */