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 <editeng/eeitem.hxx>
23 #include <com/sun/star/i18n/WordType.hpp>
25 #include <svl/itemset.hxx>
26 #include <editeng/editeng.hxx>
27 #include <editeng/editview.hxx>
28 #include <editeng/unoedhlp.hxx>
29 #include <editeng/editdata.hxx>
30 #include <editeng/outliner.hxx>
31 #include <editeng/editobj.hxx>
33 #include <editeng/unofored.hxx>
34 #include <unofored_internal.hxx>
36 using namespace ::com::sun::star
;
40 SvxEditEngineForwarder::SvxEditEngineForwarder( EditEngine
& rEngine
) :
41 rEditEngine( rEngine
)
45 SvxEditEngineForwarder::~SvxEditEngineForwarder()
47 // the EditEngine may need to be deleted from the outside
50 sal_Int32
SvxEditEngineForwarder::GetParagraphCount() const
52 return rEditEngine
.GetParagraphCount();
55 sal_Int32
SvxEditEngineForwarder::GetTextLen( sal_Int32 nParagraph
) const
57 return rEditEngine
.GetTextLen( nParagraph
);
60 OUString
SvxEditEngineForwarder::GetText( const ESelection
& rSel
) const
62 return convertLineEnd(rEditEngine
.GetText(rSel
, LINEEND_LF
), GetSystemLineEnd());
65 SfxItemSet
SvxEditEngineForwarder::GetAttribs( const ESelection
& rSel
, EditEngineAttribs nOnlyHardAttrib
) const
67 if( rSel
.nStartPara
== rSel
.nEndPara
)
69 GetAttribsFlags nFlags
= GetAttribsFlags::NONE
;
70 switch( nOnlyHardAttrib
)
72 case EditEngineAttribs_All
:
73 nFlags
= GetAttribsFlags::ALL
;
75 case EditEngineAttribs_HardAndPara
:
76 nFlags
= GetAttribsFlags::PARAATTRIBS
|GetAttribsFlags::CHARATTRIBS
;
78 case EditEngineAttribs_OnlyHard
:
79 nFlags
= GetAttribsFlags::CHARATTRIBS
;
82 OSL_FAIL("unknown flags for SvxOutlinerForwarder::GetAttribs");
85 return rEditEngine
.GetAttribs( rSel
.nStartPara
, rSel
.nStartPos
, rSel
.nEndPos
, nFlags
);
89 return rEditEngine
.GetAttribs( rSel
, nOnlyHardAttrib
);
93 SfxItemSet
SvxEditEngineForwarder::GetParaAttribs( sal_Int32 nPara
) const
95 SfxItemSet
aSet( rEditEngine
.GetParaAttribs( nPara
) );
97 sal_uInt16 nWhich
= EE_PARA_START
;
98 while( nWhich
<= EE_PARA_END
)
100 if( aSet
.GetItemState( nWhich
, true ) != SfxItemState::SET
)
102 if( rEditEngine
.HasParaAttrib( nPara
, nWhich
) )
103 aSet
.Put( rEditEngine
.GetParaAttrib( nPara
, nWhich
) );
111 void SvxEditEngineForwarder::SetParaAttribs( sal_Int32 nPara
, const SfxItemSet
& rSet
)
113 rEditEngine
.SetParaAttribs( nPara
, rSet
);
116 void SvxEditEngineForwarder::RemoveAttribs( const ESelection
& rSelection
, bool bRemoveParaAttribs
, sal_uInt16 nWhich
)
118 rEditEngine
.RemoveAttribs( rSelection
, bRemoveParaAttribs
, nWhich
);
121 SfxItemPool
* SvxEditEngineForwarder::GetPool() const
123 return rEditEngine
.GetEmptyItemSet().GetPool();
126 void SvxEditEngineForwarder::GetPortions( sal_Int32 nPara
, std::vector
<sal_Int32
>& rList
) const
128 rEditEngine
.GetPortions( nPara
, rList
);
131 void SvxEditEngineForwarder::QuickInsertText( const OUString
& rText
, const ESelection
& rSel
)
133 rEditEngine
.QuickInsertText( rText
, rSel
);
136 void SvxEditEngineForwarder::QuickInsertLineBreak( const ESelection
& rSel
)
138 rEditEngine
.QuickInsertLineBreak( rSel
);
141 void SvxEditEngineForwarder::QuickInsertField( const SvxFieldItem
& rFld
, const ESelection
& rSel
)
143 rEditEngine
.QuickInsertField( rFld
, rSel
);
146 void SvxEditEngineForwarder::QuickSetAttribs( const SfxItemSet
& rSet
, const ESelection
& rSel
)
148 rEditEngine
.QuickSetAttribs( rSet
, rSel
);
151 bool SvxEditEngineForwarder::IsValid() const
153 // cannot reliably query EditEngine state
154 // while in the middle of an update
155 return rEditEngine
.GetUpdateMode();
158 OUString
SvxEditEngineForwarder::CalcFieldValue( const SvxFieldItem
& rField
, sal_Int32 nPara
, sal_Int32 nPos
, Color
*& rpTxtColor
, Color
*& rpFldColor
)
160 return rEditEngine
.CalcFieldValue( rField
, nPara
, nPos
, rpTxtColor
, rpFldColor
);
163 void SvxEditEngineForwarder::FieldClicked( const SvxFieldItem
& rField
, sal_Int32 nPara
, sal_Int32 nPos
)
165 rEditEngine
.FieldClicked( rField
, nPara
, nPos
);
168 SfxItemState
GetSvxEditEngineItemState( EditEngine
& rEditEngine
, const ESelection
& rSel
, sal_uInt16 nWhich
)
170 std::vector
<EECharAttrib
> aAttribs
;
172 const SfxPoolItem
* pLastItem
= NULL
;
174 SfxItemState eState
= SfxItemState::DEFAULT
;
176 // check all paragraphs inside the selection
177 for( sal_Int32 nPara
= rSel
.nStartPara
; nPara
<= rSel
.nEndPara
; nPara
++ )
179 SfxItemState eParaState
= SfxItemState::DEFAULT
;
181 // calculate start and endpos for this paragraph
183 if( rSel
.nStartPara
== nPara
)
184 nPos
= rSel
.nStartPos
;
186 sal_Int32 nEndPos
= rSel
.nEndPos
;
187 if( rSel
.nEndPara
!= nPara
)
188 nEndPos
= rEditEngine
.GetTextLen( nPara
);
191 // get list of char attribs
192 rEditEngine
.GetCharAttribs( nPara
, aAttribs
);
194 bool bEmpty
= true; // we found no item inside the selection of this paragraph
195 bool bGaps
= false; // we found items but theire gaps between them
196 sal_Int32 nLastEnd
= nPos
;
198 const SfxPoolItem
* pParaItem
= NULL
;
200 for(std::vector
<EECharAttrib
>::const_iterator i
= aAttribs
.begin(); i
< aAttribs
.end(); ++i
)
202 DBG_ASSERT(i
->pAttr
, "GetCharAttribs gives corrupt data");
204 const bool bEmptyPortion
= i
->nStart
== i
->nEnd
;
205 if((!bEmptyPortion
&& i
->nStart
>= nEndPos
) ||
206 (bEmptyPortion
&& i
->nStart
> nEndPos
))
207 break; // break if we are already behind our selection
209 if((!bEmptyPortion
&& i
->nEnd
<= nPos
) ||
210 (bEmptyPortion
&& i
->nEnd
< nPos
))
211 continue; // or if the attribute ends before our selection
213 if(i
->pAttr
->Which() != nWhich
)
214 continue; // skip if is not the searched item
216 // if we already found an item
219 // ... and its different to this one than the state is dont care
220 if(*pParaItem
!= *(i
->pAttr
))
221 return SfxItemState::DONTCARE
;
224 pParaItem
= i
->pAttr
;
229 if(!bGaps
&& i
->nStart
> nLastEnd
)
235 if( !bEmpty
&& !bGaps
&& nLastEnd
< ( nEndPos
- 1 ) )
239 eParaState
= SfxItemState::DEFAULT
;
241 eParaState
= SfxItemState::DONTCARE
;
243 eParaState
= SfxItemState::SET
;
245 // if we already found an item check if we found the same
248 if( (pParaItem
== NULL
) || (*pLastItem
!= *pParaItem
) )
249 return SfxItemState::DONTCARE
;
253 pLastItem
= pParaItem
;
261 SfxItemState
SvxEditEngineForwarder::GetItemState( const ESelection
& rSel
, sal_uInt16 nWhich
) const
263 return GetSvxEditEngineItemState( rEditEngine
, rSel
, nWhich
);
266 SfxItemState
SvxEditEngineForwarder::GetItemState( sal_Int32 nPara
, sal_uInt16 nWhich
) const
268 const SfxItemSet
& rSet
= rEditEngine
.GetParaAttribs( nPara
);
269 return rSet
.GetItemState( nWhich
);
272 LanguageType
SvxEditEngineForwarder::GetLanguage( sal_Int32 nPara
, sal_Int32 nIndex
) const
274 return rEditEngine
.GetLanguage(nPara
, nIndex
);
277 sal_Int32
SvxEditEngineForwarder::GetFieldCount( sal_Int32 nPara
) const
279 return rEditEngine
.GetFieldCount(nPara
);
282 EFieldInfo
SvxEditEngineForwarder::GetFieldInfo( sal_Int32 nPara
, sal_uInt16 nField
) const
284 return rEditEngine
.GetFieldInfo( nPara
, nField
);
287 EBulletInfo
SvxEditEngineForwarder::GetBulletInfo( sal_Int32
) const
289 return EBulletInfo();
292 Rectangle
SvxEditEngineForwarder::GetCharBounds( sal_Int32 nPara
, sal_Int32 nIndex
) const
295 // EditEngine's 'internal' methods like GetCharacterBounds()
296 // don't rotate for vertical text.
297 Size
aSize( rEditEngine
.CalcTextWidth(), rEditEngine
.GetTextHeight() );
298 ::std::swap( aSize
.Width(), aSize
.Height() );
299 bool bIsVertical( rEditEngine
.IsVertical() );
301 // #108900# Handle virtual position one-past-the end of the string
302 if( nIndex
>= rEditEngine
.GetTextLen(nPara
) )
308 // use last character, if possible
309 aLast
= rEditEngine
.GetCharacterBounds( EPosition(nPara
, nIndex
-1) );
311 // move at end of this last character, make one pixel wide
312 aLast
.Move( aLast
.Right() - aLast
.Left(), 0 );
313 aLast
.SetSize( Size(1, aLast
.GetHeight()) );
316 aLast
= SvxEditSourceHelper::EEToUserSpace( aLast
, aSize
, bIsVertical
);
320 // #109864# Bounds must lie within the paragraph
321 aLast
= GetParaBounds( nPara
);
323 // #109151# Don't use paragraph height, but line height
324 // instead. aLast is already CTL-correct
326 aLast
.SetSize( Size( rEditEngine
.GetLineHeight(nPara
,0), 1 ) );
328 aLast
.SetSize( Size( 1, rEditEngine
.GetLineHeight(nPara
,0) ) );
335 return SvxEditSourceHelper::EEToUserSpace( rEditEngine
.GetCharacterBounds( EPosition(nPara
, nIndex
) ),
336 aSize
, bIsVertical
);
340 Rectangle
SvxEditEngineForwarder::GetParaBounds( sal_Int32 nPara
) const
342 const Point aPnt
= rEditEngine
.GetDocPosTopLeft( nPara
);
345 sal_uLong nTextWidth
;
347 if( rEditEngine
.IsVertical() )
350 // Hargl. EditEngine's 'external' methods return the rotated
351 // dimensions, 'internal' methods like GetTextHeight( n )
353 nWidth
= rEditEngine
.GetTextHeight( nPara
);
354 nHeight
= rEditEngine
.GetTextHeight();
355 nTextWidth
= rEditEngine
.GetTextHeight();
357 return Rectangle( nTextWidth
- aPnt
.Y() - nWidth
, 0, nTextWidth
- aPnt
.Y(), nHeight
);
361 nWidth
= rEditEngine
.CalcTextWidth();
362 nHeight
= rEditEngine
.GetTextHeight( nPara
);
364 return Rectangle( 0, aPnt
.Y(), nWidth
, aPnt
.Y() + nHeight
);
368 MapMode
SvxEditEngineForwarder::GetMapMode() const
370 return rEditEngine
.GetRefMapMode();
373 OutputDevice
* SvxEditEngineForwarder::GetRefDevice() const
375 return rEditEngine
.GetRefDevice();
378 bool SvxEditEngineForwarder::GetIndexAtPoint( const Point
& rPos
, sal_Int32
& nPara
, sal_Int32
& nIndex
) const
380 Size
aSize( rEditEngine
.CalcTextWidth(), rEditEngine
.GetTextHeight() );
381 ::std::swap( aSize
.Width(), aSize
.Height() );
382 Point
aEEPos( SvxEditSourceHelper::UserSpaceToEE( rPos
,
384 rEditEngine
.IsVertical() ));
386 EPosition aDocPos
= rEditEngine
.FindDocPosition( aEEPos
);
388 nPara
= aDocPos
.nPara
;
389 nIndex
= aDocPos
.nIndex
;
394 bool SvxEditEngineForwarder::GetWordIndices( sal_Int32 nPara
, sal_Int32 nIndex
, sal_Int32
& nStart
, sal_Int32
& nEnd
) const
396 ESelection aRes
= rEditEngine
.GetWord( ESelection(nPara
, nIndex
, nPara
, nIndex
), com::sun::star::i18n::WordType::DICTIONARY_WORD
);
398 if( aRes
.nStartPara
== nPara
&&
399 aRes
.nStartPara
== aRes
.nEndPara
)
401 nStart
= aRes
.nStartPos
;
410 bool SvxEditEngineForwarder::GetAttributeRun( sal_Int32
& nStartIndex
, sal_Int32
& nEndIndex
, sal_Int32 nPara
, sal_Int32 nIndex
, bool bInCell
) const
412 return SvxEditSourceHelper::GetAttributeRun( nStartIndex
, nEndIndex
, rEditEngine
, nPara
, nIndex
, bInCell
);
415 sal_Int32
SvxEditEngineForwarder::GetLineCount( sal_Int32 nPara
) const
417 return rEditEngine
.GetLineCount(nPara
);
420 sal_Int32
SvxEditEngineForwarder::GetLineLen( sal_Int32 nPara
, sal_Int32 nLine
) const
422 return rEditEngine
.GetLineLen(nPara
, nLine
);
425 void SvxEditEngineForwarder::GetLineBoundaries( /*out*/sal_Int32
&rStart
, /*out*/sal_Int32
&rEnd
, sal_Int32 nPara
, sal_Int32 nLine
) const
427 rEditEngine
.GetLineBoundaries(rStart
, rEnd
, nPara
, nLine
);
430 sal_Int32
SvxEditEngineForwarder::GetLineNumberAtIndex( sal_Int32 nPara
, sal_Int32 nIndex
) const
432 return rEditEngine
.GetLineNumberAtIndex(nPara
, nIndex
);
436 bool SvxEditEngineForwarder::QuickFormatDoc( bool )
438 rEditEngine
.QuickFormatDoc();
443 bool SvxEditEngineForwarder::Delete( const ESelection
& rSelection
)
445 rEditEngine
.QuickDelete( rSelection
);
446 rEditEngine
.QuickFormatDoc();
451 bool SvxEditEngineForwarder::InsertText( const OUString
& rStr
, const ESelection
& rSelection
)
453 rEditEngine
.QuickInsertText( rStr
, rSelection
);
454 rEditEngine
.QuickFormatDoc();
459 sal_Int16
SvxEditEngineForwarder::GetDepth( sal_Int32
) const
461 // EditEngine does not support outline depth
465 bool SvxEditEngineForwarder::SetDepth( sal_Int32
, sal_Int16 nNewDepth
)
467 // EditEngine does not support outline depth
468 return nNewDepth
== -1;
471 const SfxItemSet
* SvxEditEngineForwarder::GetEmptyItemSetPtr()
473 return &rEditEngine
.GetEmptyItemSet();
476 void SvxEditEngineForwarder::AppendParagraph()
478 rEditEngine
.InsertParagraph( rEditEngine
.GetParagraphCount(), OUString() );
481 sal_Int32
SvxEditEngineForwarder::AppendTextPortion( sal_Int32 nPara
, const OUString
&rText
, const SfxItemSet
& /*rSet*/ )
485 sal_Int32 nParaCount
= rEditEngine
.GetParagraphCount();
486 DBG_ASSERT( nPara
< nParaCount
, "paragraph index out of bounds" );
487 if (0 <= nPara
&& nPara
< nParaCount
)
489 nLen
= rEditEngine
.GetTextLen( nPara
);
490 rEditEngine
.QuickInsertText( rText
, ESelection( nPara
, nLen
, nPara
, nLen
) );
496 void SvxEditEngineForwarder::CopyText(const SvxTextForwarder
& rSource
)
498 const SvxEditEngineForwarder
* pSourceForwarder
= dynamic_cast< const SvxEditEngineForwarder
* >( &rSource
);
499 if( !pSourceForwarder
)
501 EditTextObject
* pNewTextObject
= pSourceForwarder
->rEditEngine
.CreateTextObject();
502 rEditEngine
.SetText( *pNewTextObject
);
503 delete pNewTextObject
;
508 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */