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>
35 using namespace ::com::sun::star
;
39 SvxEditEngineForwarder::SvxEditEngineForwarder( EditEngine
& rEngine
) :
40 rEditEngine( rEngine
)
44 SvxEditEngineForwarder::~SvxEditEngineForwarder()
46 // the EditEngine may need to be deleted from the outside
49 sal_Int32
SvxEditEngineForwarder::GetParagraphCount() const
51 return rEditEngine
.GetParagraphCount();
54 sal_Int32
SvxEditEngineForwarder::GetTextLen( sal_Int32 nParagraph
) const
56 return rEditEngine
.GetTextLen( nParagraph
);
59 OUString
SvxEditEngineForwarder::GetText( const ESelection
& rSel
) const
61 return convertLineEnd(rEditEngine
.GetText(rSel
, LINEEND_LF
), GetSystemLineEnd());
64 SfxItemSet
SvxEditEngineForwarder::GetAttribs( const ESelection
& rSel
, EditEngineAttribs nOnlyHardAttrib
) const
66 if( rSel
.nStartPara
== rSel
.nEndPara
)
69 switch( nOnlyHardAttrib
)
71 case EditEngineAttribs_All
:
72 nFlags
= GETATTRIBS_ALL
;
74 case EditEngineAttribs_HardAndPara
:
75 nFlags
= GETATTRIBS_PARAATTRIBS
|GETATTRIBS_CHARATTRIBS
;
77 case EditEngineAttribs_OnlyHard
:
78 nFlags
= GETATTRIBS_CHARATTRIBS
;
81 OSL_FAIL("unknown flags for SvxOutlinerForwarder::GetAttribs");
84 return rEditEngine
.GetAttribs( rSel
.nStartPara
, rSel
.nStartPos
, rSel
.nEndPos
, nFlags
);
88 return rEditEngine
.GetAttribs( rSel
, nOnlyHardAttrib
);
92 SfxItemSet
SvxEditEngineForwarder::GetParaAttribs( sal_Int32 nPara
) const
94 SfxItemSet
aSet( rEditEngine
.GetParaAttribs( nPara
) );
96 sal_uInt16 nWhich
= EE_PARA_START
;
97 while( nWhich
<= EE_PARA_END
)
99 if( aSet
.GetItemState( nWhich
, true ) != SFX_ITEM_ON
)
101 if( rEditEngine
.HasParaAttrib( nPara
, nWhich
) )
102 aSet
.Put( rEditEngine
.GetParaAttrib( nPara
, nWhich
) );
110 void SvxEditEngineForwarder::SetParaAttribs( sal_Int32 nPara
, const SfxItemSet
& rSet
)
112 rEditEngine
.SetParaAttribs( nPara
, rSet
);
115 void SvxEditEngineForwarder::RemoveAttribs( const ESelection
& rSelection
, bool bRemoveParaAttribs
, sal_uInt16 nWhich
)
117 rEditEngine
.RemoveAttribs( rSelection
, bRemoveParaAttribs
, nWhich
);
120 SfxItemPool
* SvxEditEngineForwarder::GetPool() const
122 return rEditEngine
.GetEmptyItemSet().GetPool();
125 void SvxEditEngineForwarder::GetPortions( sal_Int32 nPara
, std::vector
<sal_Int32
>& rList
) const
127 rEditEngine
.GetPortions( nPara
, rList
);
130 void SvxEditEngineForwarder::QuickInsertText( const OUString
& rText
, const ESelection
& rSel
)
132 rEditEngine
.QuickInsertText( rText
, rSel
);
135 void SvxEditEngineForwarder::QuickInsertLineBreak( const ESelection
& rSel
)
137 rEditEngine
.QuickInsertLineBreak( rSel
);
140 void SvxEditEngineForwarder::QuickInsertField( const SvxFieldItem
& rFld
, const ESelection
& rSel
)
142 rEditEngine
.QuickInsertField( rFld
, rSel
);
145 void SvxEditEngineForwarder::QuickSetAttribs( const SfxItemSet
& rSet
, const ESelection
& rSel
)
147 rEditEngine
.QuickSetAttribs( rSet
, rSel
);
150 bool SvxEditEngineForwarder::IsValid() const
152 // cannot reliably query EditEngine state
153 // while in the middle of an update
154 return rEditEngine
.GetUpdateMode();
157 OUString
SvxEditEngineForwarder::CalcFieldValue( const SvxFieldItem
& rField
, sal_Int32 nPara
, sal_Int32 nPos
, Color
*& rpTxtColor
, Color
*& rpFldColor
)
159 return rEditEngine
.CalcFieldValue( rField
, nPara
, nPos
, rpTxtColor
, rpFldColor
);
162 void SvxEditEngineForwarder::FieldClicked( const SvxFieldItem
& rField
, sal_Int32 nPara
, sal_Int32 nPos
)
164 rEditEngine
.FieldClicked( rField
, nPara
, nPos
);
167 sal_uInt16
GetSvxEditEngineItemState( EditEngine
& rEditEngine
, const ESelection
& rSel
, sal_uInt16 nWhich
)
169 std::vector
<EECharAttrib
> aAttribs
;
171 const SfxPoolItem
* pLastItem
= NULL
;
173 SfxItemState eState
= SFX_ITEM_DEFAULT
;
175 // check all paragraphs inside the selection
176 for( sal_Int32 nPara
= rSel
.nStartPara
; nPara
<= rSel
.nEndPara
; nPara
++ )
178 SfxItemState eParaState
= SFX_ITEM_DEFAULT
;
180 // calculate start and endpos for this paragraph
182 if( rSel
.nStartPara
== nPara
)
183 nPos
= rSel
.nStartPos
;
185 sal_Int32 nEndPos
= rSel
.nEndPos
;
186 if( rSel
.nEndPara
!= nPara
)
187 nEndPos
= rEditEngine
.GetTextLen( nPara
);
190 // get list of char attribs
191 rEditEngine
.GetCharAttribs( nPara
, aAttribs
);
193 bool bEmpty
= true; // we found no item inside the selection of this paragraph
194 bool bGaps
= false; // we found items but theire gaps between them
195 sal_Int32 nLastEnd
= nPos
;
197 const SfxPoolItem
* pParaItem
= NULL
;
199 for(std::vector
<EECharAttrib
>::const_iterator i
= aAttribs
.begin(); i
< aAttribs
.end(); ++i
)
201 DBG_ASSERT(i
->pAttr
, "GetCharAttribs gives corrupt data");
203 const bool bEmptyPortion
= i
->nStart
== i
->nEnd
;
204 if((!bEmptyPortion
&& i
->nStart
>= nEndPos
) ||
205 (bEmptyPortion
&& i
->nStart
> nEndPos
))
206 break; // break if we are already behind our selection
208 if((!bEmptyPortion
&& i
->nEnd
<= nPos
) ||
209 (bEmptyPortion
&& i
->nEnd
< nPos
))
210 continue; // or if the attribute ends before our selection
212 if(i
->pAttr
->Which() != nWhich
)
213 continue; // skip if is not the searched item
215 // if we already found an item
218 // ... and its different to this one than the state is dont care
219 if(*pParaItem
!= *(i
->pAttr
))
220 return SFX_ITEM_DONTCARE
;
223 pParaItem
= i
->pAttr
;
228 if(!bGaps
&& i
->nStart
> nLastEnd
)
234 if( !bEmpty
&& !bGaps
&& nLastEnd
< ( nEndPos
- 1 ) )
238 eParaState
= SFX_ITEM_DEFAULT
;
240 eParaState
= SFX_ITEM_DONTCARE
;
242 eParaState
= SFX_ITEM_SET
;
244 // if we already found an item check if we found the same
247 if( (pParaItem
== NULL
) || (*pLastItem
!= *pParaItem
) )
248 return SFX_ITEM_DONTCARE
;
252 pLastItem
= pParaItem
;
260 sal_uInt16
SvxEditEngineForwarder::GetItemState( const ESelection
& rSel
, sal_uInt16 nWhich
) const
262 return GetSvxEditEngineItemState( rEditEngine
, rSel
, nWhich
);
265 sal_uInt16
SvxEditEngineForwarder::GetItemState( sal_Int32 nPara
, sal_uInt16 nWhich
) const
267 const SfxItemSet
& rSet
= rEditEngine
.GetParaAttribs( nPara
);
268 return rSet
.GetItemState( nWhich
);
271 LanguageType
SvxEditEngineForwarder::GetLanguage( sal_Int32 nPara
, sal_Int32 nIndex
) const
273 return rEditEngine
.GetLanguage(nPara
, nIndex
);
276 sal_Int32
SvxEditEngineForwarder::GetFieldCount( sal_Int32 nPara
) const
278 return rEditEngine
.GetFieldCount(nPara
);
281 EFieldInfo
SvxEditEngineForwarder::GetFieldInfo( sal_Int32 nPara
, sal_uInt16 nField
) const
283 return rEditEngine
.GetFieldInfo( nPara
, nField
);
286 EBulletInfo
SvxEditEngineForwarder::GetBulletInfo( sal_Int32
) const
288 return EBulletInfo();
291 Rectangle
SvxEditEngineForwarder::GetCharBounds( sal_Int32 nPara
, sal_Int32 nIndex
) const
294 // EditEngine's 'internal' methods like GetCharacterBounds()
295 // don't rotate for vertical text.
296 Size
aSize( rEditEngine
.CalcTextWidth(), rEditEngine
.GetTextHeight() );
297 ::std::swap( aSize
.Width(), aSize
.Height() );
298 bool bIsVertical( rEditEngine
.IsVertical() );
300 // #108900# Handle virtual position one-past-the end of the string
301 if( nIndex
>= rEditEngine
.GetTextLen(nPara
) )
307 // use last character, if possible
308 aLast
= rEditEngine
.GetCharacterBounds( EPosition(nPara
, nIndex
-1) );
310 // move at end of this last character, make one pixel wide
311 aLast
.Move( aLast
.Right() - aLast
.Left(), 0 );
312 aLast
.SetSize( Size(1, aLast
.GetHeight()) );
315 aLast
= SvxEditSourceHelper::EEToUserSpace( aLast
, aSize
, bIsVertical
);
319 // #109864# Bounds must lie within the paragraph
320 aLast
= GetParaBounds( nPara
);
322 // #109151# Don't use paragraph height, but line height
323 // instead. aLast is already CTL-correct
325 aLast
.SetSize( Size( rEditEngine
.GetLineHeight(nPara
,0), 1 ) );
327 aLast
.SetSize( Size( 1, rEditEngine
.GetLineHeight(nPara
,0) ) );
334 return SvxEditSourceHelper::EEToUserSpace( rEditEngine
.GetCharacterBounds( EPosition(nPara
, nIndex
) ),
335 aSize
, bIsVertical
);
339 Rectangle
SvxEditEngineForwarder::GetParaBounds( sal_Int32 nPara
) const
341 const Point aPnt
= rEditEngine
.GetDocPosTopLeft( nPara
);
344 sal_uLong nTextWidth
;
346 if( rEditEngine
.IsVertical() )
349 // Hargl. EditEngine's 'external' methods return the rotated
350 // dimensions, 'internal' methods like GetTextHeight( n )
352 nWidth
= rEditEngine
.GetTextHeight( nPara
);
353 nHeight
= rEditEngine
.GetTextHeight();
354 nTextWidth
= rEditEngine
.GetTextHeight();
356 return Rectangle( nTextWidth
- aPnt
.Y() - nWidth
, 0, nTextWidth
- aPnt
.Y(), nHeight
);
360 nWidth
= rEditEngine
.CalcTextWidth();
361 nHeight
= rEditEngine
.GetTextHeight( nPara
);
363 return Rectangle( 0, aPnt
.Y(), nWidth
, aPnt
.Y() + nHeight
);
367 MapMode
SvxEditEngineForwarder::GetMapMode() const
369 return rEditEngine
.GetRefMapMode();
372 OutputDevice
* SvxEditEngineForwarder::GetRefDevice() const
374 return rEditEngine
.GetRefDevice();
377 bool SvxEditEngineForwarder::GetIndexAtPoint( const Point
& rPos
, sal_Int32
& nPara
, sal_Int32
& nIndex
) const
379 Size
aSize( rEditEngine
.CalcTextWidth(), rEditEngine
.GetTextHeight() );
380 ::std::swap( aSize
.Width(), aSize
.Height() );
381 Point
aEEPos( SvxEditSourceHelper::UserSpaceToEE( rPos
,
383 rEditEngine
.IsVertical() ));
385 EPosition aDocPos
= rEditEngine
.FindDocPosition( aEEPos
);
387 nPara
= aDocPos
.nPara
;
388 nIndex
= aDocPos
.nIndex
;
393 bool SvxEditEngineForwarder::GetWordIndices( sal_Int32 nPara
, sal_Int32 nIndex
, sal_Int32
& nStart
, sal_Int32
& nEnd
) const
395 ESelection aRes
= rEditEngine
.GetWord( ESelection(nPara
, nIndex
, nPara
, nIndex
), com::sun::star::i18n::WordType::DICTIONARY_WORD
);
397 if( aRes
.nStartPara
== nPara
&&
398 aRes
.nStartPara
== aRes
.nEndPara
)
400 nStart
= aRes
.nStartPos
;
409 bool SvxEditEngineForwarder::GetAttributeRun( sal_Int32
& nStartIndex
, sal_Int32
& nEndIndex
, sal_Int32 nPara
, sal_Int32 nIndex
, bool bInCell
) const
411 return SvxEditSourceHelper::GetAttributeRun( nStartIndex
, nEndIndex
, rEditEngine
, nPara
, nIndex
, bInCell
);
414 sal_Int32
SvxEditEngineForwarder::GetLineCount( sal_Int32 nPara
) const
416 return rEditEngine
.GetLineCount(nPara
);
419 sal_Int32
SvxEditEngineForwarder::GetLineLen( sal_Int32 nPara
, sal_Int32 nLine
) const
421 return rEditEngine
.GetLineLen(nPara
, nLine
);
424 void SvxEditEngineForwarder::GetLineBoundaries( /*out*/sal_Int32
&rStart
, /*out*/sal_Int32
&rEnd
, sal_Int32 nPara
, sal_Int32 nLine
) const
426 rEditEngine
.GetLineBoundaries(rStart
, rEnd
, nPara
, nLine
);
429 sal_Int32
SvxEditEngineForwarder::GetLineNumberAtIndex( sal_Int32 nPara
, sal_Int32 nIndex
) const
431 return rEditEngine
.GetLineNumberAtIndex(nPara
, nIndex
);
435 bool SvxEditEngineForwarder::QuickFormatDoc( bool )
437 rEditEngine
.QuickFormatDoc();
442 bool SvxEditEngineForwarder::Delete( const ESelection
& rSelection
)
444 rEditEngine
.QuickDelete( rSelection
);
445 rEditEngine
.QuickFormatDoc();
450 bool SvxEditEngineForwarder::InsertText( const OUString
& rStr
, const ESelection
& rSelection
)
452 rEditEngine
.QuickInsertText( rStr
, rSelection
);
453 rEditEngine
.QuickFormatDoc();
458 sal_Int16
SvxEditEngineForwarder::GetDepth( sal_Int32
) const
460 // EditEngine does not support outline depth
464 bool SvxEditEngineForwarder::SetDepth( sal_Int32
, sal_Int16 nNewDepth
)
466 // EditEngine does not support outline depth
467 return nNewDepth
== -1;
470 const SfxItemSet
* SvxEditEngineForwarder::GetEmptyItemSetPtr()
472 return &rEditEngine
.GetEmptyItemSet();
475 void SvxEditEngineForwarder::AppendParagraph()
477 rEditEngine
.InsertParagraph( rEditEngine
.GetParagraphCount(), OUString() );
480 sal_Int32
SvxEditEngineForwarder::AppendTextPortion( sal_Int32 nPara
, const OUString
&rText
, const SfxItemSet
& /*rSet*/ )
484 sal_Int32 nParaCount
= rEditEngine
.GetParagraphCount();
485 DBG_ASSERT( nPara
< nParaCount
, "paragraph index out of bounds" );
486 if (0 <= nPara
&& nPara
< nParaCount
)
488 nLen
= rEditEngine
.GetTextLen( nPara
);
489 rEditEngine
.QuickInsertText( rText
, ESelection( nPara
, nLen
, nPara
, nLen
) );
495 void SvxEditEngineForwarder::CopyText(const SvxTextForwarder
& rSource
)
497 const SvxEditEngineForwarder
* pSourceForwarder
= dynamic_cast< const SvxEditEngineForwarder
* >( &rSource
);
498 if( !pSourceForwarder
)
500 EditTextObject
* pNewTextObject
= pSourceForwarder
->rEditEngine
.CreateTextObject();
501 rEditEngine
.SetText( *pNewTextObject
);
502 delete pNewTextObject
;
507 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */