1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
31 #include <editeng/eeitem.hxx>
32 #include <com/sun/star/i18n/WordType.hpp>
34 #include <svl/itemset.hxx>
35 #include <editeng/editeng.hxx>
36 #include <editeng/editview.hxx>
37 #include <editeng/unoedhlp.hxx>
38 #include <editeng/editdata.hxx>
39 #include <editeng/outliner.hxx>
40 #include <editeng/editobj.hxx> // only for the GetText crutch
42 #include <editeng/unofored.hxx>
44 using namespace ::com::sun::star
;
46 //------------------------------------------------------------------------
48 SvxEditEngineForwarder::SvxEditEngineForwarder( EditEngine
& rEngine
) :
49 rEditEngine( rEngine
)
53 SvxEditEngineForwarder::~SvxEditEngineForwarder()
55 // the EditEngine may need to be deleted from the outside
58 sal_uInt16
SvxEditEngineForwarder::GetParagraphCount() const
60 return rEditEngine
.GetParagraphCount();
63 sal_uInt16
SvxEditEngineForwarder::GetTextLen( sal_uInt16 nParagraph
) const
65 return rEditEngine
.GetTextLen( nParagraph
);
68 String
SvxEditEngineForwarder::GetText( const ESelection
& rSel
) const
70 return convertLineEnd(rEditEngine
.GetText(rSel
, LINEEND_LF
), GetSystemLineEnd());
73 SfxItemSet
SvxEditEngineForwarder::GetAttribs( const ESelection
& rSel
, sal_Bool bOnlyHardAttrib
) const
75 if( rSel
.nStartPara
== rSel
.nEndPara
)
78 switch( bOnlyHardAttrib
)
80 case EditEngineAttribs_All
:
81 nFlags
= GETATTRIBS_ALL
;
83 case EditEngineAttribs_HardAndPara
:
84 nFlags
= GETATTRIBS_PARAATTRIBS
|GETATTRIBS_CHARATTRIBS
;
86 case EditEngineAttribs_OnlyHard
:
87 nFlags
= GETATTRIBS_CHARATTRIBS
;
90 OSL_FAIL("unknown flags for SvxOutlinerForwarder::GetAttribs");
93 return rEditEngine
.GetAttribs( rSel
.nStartPara
, rSel
.nStartPos
, rSel
.nEndPos
, nFlags
);
97 return rEditEngine
.GetAttribs( rSel
, bOnlyHardAttrib
);
101 SfxItemSet
SvxEditEngineForwarder::GetParaAttribs( sal_uInt16 nPara
) const
103 SfxItemSet
aSet( rEditEngine
.GetParaAttribs( nPara
) );
105 sal_uInt16 nWhich
= EE_PARA_START
;
106 while( nWhich
<= EE_PARA_END
)
108 if( aSet
.GetItemState( nWhich
, sal_True
) != SFX_ITEM_ON
)
110 if( rEditEngine
.HasParaAttrib( nPara
, nWhich
) )
111 aSet
.Put( rEditEngine
.GetParaAttrib( nPara
, nWhich
) );
119 void SvxEditEngineForwarder::SetParaAttribs( sal_uInt16 nPara
, const SfxItemSet
& rSet
)
121 rEditEngine
.SetParaAttribs( nPara
, rSet
);
124 void SvxEditEngineForwarder::RemoveAttribs( const ESelection
& rSelection
, sal_Bool bRemoveParaAttribs
, sal_uInt16 nWhich
)
126 rEditEngine
.RemoveAttribs( rSelection
, bRemoveParaAttribs
, nWhich
);
129 SfxItemPool
* SvxEditEngineForwarder::GetPool() const
131 return rEditEngine
.GetEmptyItemSet().GetPool();
134 void SvxEditEngineForwarder::GetPortions( sal_uInt16 nPara
, std::vector
<sal_uInt16
>& rList
) const
136 rEditEngine
.GetPortions( nPara
, rList
);
139 void SvxEditEngineForwarder::QuickInsertText( const String
& rText
, const ESelection
& rSel
)
141 rEditEngine
.QuickInsertText( rText
, rSel
);
144 void SvxEditEngineForwarder::QuickInsertLineBreak( const ESelection
& rSel
)
146 rEditEngine
.QuickInsertLineBreak( rSel
);
149 void SvxEditEngineForwarder::QuickInsertField( const SvxFieldItem
& rFld
, const ESelection
& rSel
)
151 rEditEngine
.QuickInsertField( rFld
, rSel
);
154 void SvxEditEngineForwarder::QuickSetAttribs( const SfxItemSet
& rSet
, const ESelection
& rSel
)
156 rEditEngine
.QuickSetAttribs( rSet
, rSel
);
159 sal_Bool
SvxEditEngineForwarder::IsValid() const
161 // cannot reliably query EditEngine state
162 // while in the middle of an update
163 return rEditEngine
.GetUpdateMode();
166 XubString
SvxEditEngineForwarder::CalcFieldValue( const SvxFieldItem
& rField
, sal_uInt16 nPara
, sal_uInt16 nPos
, Color
*& rpTxtColor
, Color
*& rpFldColor
)
168 return rEditEngine
.CalcFieldValue( rField
, nPara
, nPos
, rpTxtColor
, rpFldColor
);
171 void SvxEditEngineForwarder::FieldClicked( const SvxFieldItem
& rField
, sal_uInt16 nPara
, xub_StrLen nPos
)
173 rEditEngine
.FieldClicked( rField
, nPara
, nPos
);
176 sal_uInt16
GetSvxEditEngineItemState( EditEngine
& rEditEngine
, const ESelection
& rSel
, sal_uInt16 nWhich
)
178 std::vector
<EECharAttrib
> aAttribs
;
180 const SfxPoolItem
* pLastItem
= NULL
;
182 SfxItemState eState
= SFX_ITEM_DEFAULT
;
184 // check all paragraphs inside the selection
185 for( sal_uInt16 nPara
= rSel
.nStartPara
; nPara
<= rSel
.nEndPara
; nPara
++ )
187 SfxItemState eParaState
= SFX_ITEM_DEFAULT
;
189 // calculate start and endpos for this paragraph
191 if( rSel
.nStartPara
== nPara
)
192 nPos
= rSel
.nStartPos
;
194 sal_uInt16 nEndPos
= rSel
.nEndPos
;
195 if( rSel
.nEndPara
!= nPara
)
196 nEndPos
= rEditEngine
.GetTextLen( nPara
);
199 // get list of char attribs
200 rEditEngine
.GetCharAttribs( nPara
, aAttribs
);
202 sal_Bool bEmpty
= sal_True
; // we found no item inside the selektion of this paragraph
203 sal_Bool bGaps
= sal_False
; // we found items but theire gaps between them
204 sal_uInt16 nLastEnd
= nPos
;
206 const SfxPoolItem
* pParaItem
= NULL
;
208 for(std::vector
<EECharAttrib
>::const_iterator i
= aAttribs
.begin(); i
< aAttribs
.end(); ++i
)
210 DBG_ASSERT(i
->pAttr
, "GetCharAttribs gives corrupt data");
212 const sal_Bool bEmptyPortion
= i
->nStart
== i
->nEnd
;
213 if((!bEmptyPortion
&& i
->nStart
>= nEndPos
) ||
214 (bEmptyPortion
&& i
->nStart
> nEndPos
))
215 break; // break if we are already behind our selektion
217 if((!bEmptyPortion
&& i
->nEnd
<= nPos
) ||
218 (bEmptyPortion
&& i
->nEnd
< nPos
))
219 continue; // or if the attribute ends before our selektion
221 if(i
->pAttr
->Which() != nWhich
)
222 continue; // skip if is not the searched item
224 // if we already found an item
227 // ... and its different to this one than the state is dont care
228 if(*pParaItem
!= *(i
->pAttr
))
229 return SFX_ITEM_DONTCARE
;
232 pParaItem
= i
->pAttr
;
237 if(!bGaps
&& i
->nStart
> nLastEnd
)
243 if( !bEmpty
&& !bGaps
&& nLastEnd
< ( nEndPos
- 1 ) )
247 eParaState
= SFX_ITEM_DEFAULT
;
249 eParaState
= SFX_ITEM_DONTCARE
;
251 eParaState
= SFX_ITEM_SET
;
253 // if we already found an item check if we found the same
256 if( (pParaItem
== NULL
) || (*pLastItem
!= *pParaItem
) )
257 return SFX_ITEM_DONTCARE
;
261 pLastItem
= pParaItem
;
269 sal_uInt16
SvxEditEngineForwarder::GetItemState( const ESelection
& rSel
, sal_uInt16 nWhich
) const
271 return GetSvxEditEngineItemState( rEditEngine
, rSel
, nWhich
);
274 sal_uInt16
SvxEditEngineForwarder::GetItemState( sal_uInt16 nPara
, sal_uInt16 nWhich
) const
276 const SfxItemSet
& rSet
= rEditEngine
.GetParaAttribs( nPara
);
277 return rSet
.GetItemState( nWhich
);
280 LanguageType
SvxEditEngineForwarder::GetLanguage( sal_uInt16 nPara
, sal_uInt16 nIndex
) const
282 return rEditEngine
.GetLanguage(nPara
, nIndex
);
285 sal_uInt16
SvxEditEngineForwarder::GetFieldCount( sal_uInt16 nPara
) const
287 return rEditEngine
.GetFieldCount(nPara
);
290 EFieldInfo
SvxEditEngineForwarder::GetFieldInfo( sal_uInt16 nPara
, sal_uInt16 nField
) const
292 return rEditEngine
.GetFieldInfo( nPara
, nField
);
295 EBulletInfo
SvxEditEngineForwarder::GetBulletInfo( sal_uInt16
) const
297 return EBulletInfo();
300 Rectangle
SvxEditEngineForwarder::GetCharBounds( sal_uInt16 nPara
, sal_uInt16 nIndex
) const
303 // EditEngine's 'internal' methods like GetCharacterBounds()
304 // don't rotate for vertical text.
305 Size
aSize( rEditEngine
.CalcTextWidth(), rEditEngine
.GetTextHeight() );
306 ::std::swap( aSize
.Width(), aSize
.Height() );
307 bool bIsVertical( rEditEngine
.IsVertical() == sal_True
);
309 // #108900# Handle virtual position one-past-the end of the string
310 if( nIndex
>= rEditEngine
.GetTextLen(nPara
) )
316 // use last character, if possible
317 aLast
= rEditEngine
.GetCharacterBounds( EPosition(nPara
, nIndex
-1) );
319 // move at end of this last character, make one pixel wide
320 aLast
.Move( aLast
.Right() - aLast
.Left(), 0 );
321 aLast
.SetSize( Size(1, aLast
.GetHeight()) );
324 aLast
= SvxEditSourceHelper::EEToUserSpace( aLast
, aSize
, bIsVertical
);
328 // #109864# Bounds must lie within the paragraph
329 aLast
= GetParaBounds( nPara
);
331 // #109151# Don't use paragraph height, but line height
332 // instead. aLast is already CTL-correct
334 aLast
.SetSize( Size( rEditEngine
.GetLineHeight(nPara
,0), 1 ) );
336 aLast
.SetSize( Size( 1, rEditEngine
.GetLineHeight(nPara
,0) ) );
343 return SvxEditSourceHelper::EEToUserSpace( rEditEngine
.GetCharacterBounds( EPosition(nPara
, nIndex
) ),
344 aSize
, bIsVertical
);
348 Rectangle
SvxEditEngineForwarder::GetParaBounds( sal_uInt16 nPara
) const
350 const Point aPnt
= rEditEngine
.GetDocPosTopLeft( nPara
);
353 sal_uLong nTextWidth
;
355 if( rEditEngine
.IsVertical() )
358 // Hargl. EditEngine's 'external' methods return the rotated
359 // dimensions, 'internal' methods like GetTextHeight( n )
361 nWidth
= rEditEngine
.GetTextHeight( nPara
);
362 nHeight
= rEditEngine
.GetTextHeight();
363 nTextWidth
= rEditEngine
.GetTextHeight();
365 return Rectangle( nTextWidth
- aPnt
.Y() - nWidth
, 0, nTextWidth
- aPnt
.Y(), nHeight
);
369 nWidth
= rEditEngine
.CalcTextWidth();
370 nHeight
= rEditEngine
.GetTextHeight( nPara
);
372 return Rectangle( 0, aPnt
.Y(), nWidth
, aPnt
.Y() + nHeight
);
376 MapMode
SvxEditEngineForwarder::GetMapMode() const
378 return rEditEngine
.GetRefMapMode();
381 OutputDevice
* SvxEditEngineForwarder::GetRefDevice() const
383 return rEditEngine
.GetRefDevice();
386 sal_Bool
SvxEditEngineForwarder::GetIndexAtPoint( const Point
& rPos
, sal_uInt16
& nPara
, sal_uInt16
& nIndex
) const
388 Size
aSize( rEditEngine
.CalcTextWidth(), rEditEngine
.GetTextHeight() );
389 ::std::swap( aSize
.Width(), aSize
.Height() );
390 Point
aEEPos( SvxEditSourceHelper::UserSpaceToEE( rPos
,
392 rEditEngine
.IsVertical() == sal_True
));
394 EPosition aDocPos
= rEditEngine
.FindDocPosition( aEEPos
);
396 nPara
= aDocPos
.nPara
;
397 nIndex
= aDocPos
.nIndex
;
402 sal_Bool
SvxEditEngineForwarder::GetWordIndices( sal_uInt16 nPara
, sal_uInt16 nIndex
, sal_uInt16
& nStart
, sal_uInt16
& nEnd
) const
404 ESelection aRes
= rEditEngine
.GetWord( ESelection(nPara
, nIndex
, nPara
, nIndex
), com::sun::star::i18n::WordType::DICTIONARY_WORD
);
406 if( aRes
.nStartPara
== nPara
&&
407 aRes
.nStartPara
== aRes
.nEndPara
)
409 nStart
= aRes
.nStartPos
;
418 sal_Bool
SvxEditEngineForwarder::GetAttributeRun( sal_uInt16
& nStartIndex
, sal_uInt16
& nEndIndex
, sal_uInt16 nPara
, sal_uInt16 nIndex
) const
420 return SvxEditSourceHelper::GetAttributeRun( nStartIndex
, nEndIndex
, rEditEngine
, nPara
, nIndex
);
423 sal_uInt16
SvxEditEngineForwarder::GetLineCount( sal_uInt16 nPara
) const
425 return rEditEngine
.GetLineCount(nPara
);
428 sal_uInt16
SvxEditEngineForwarder::GetLineLen( sal_uInt16 nPara
, sal_uInt16 nLine
) const
430 return rEditEngine
.GetLineLen(nPara
, nLine
);
433 void SvxEditEngineForwarder::GetLineBoundaries( /*out*/sal_uInt16
&rStart
, /*out*/sal_uInt16
&rEnd
, sal_uInt16 nPara
, sal_uInt16 nLine
) const
435 rEditEngine
.GetLineBoundaries(rStart
, rEnd
, nPara
, nLine
);
438 sal_uInt16
SvxEditEngineForwarder::GetLineNumberAtIndex( sal_uInt16 nPara
, sal_uInt16 nIndex
) const
440 return rEditEngine
.GetLineNumberAtIndex(nPara
, nIndex
);
444 sal_Bool
SvxEditEngineForwarder::QuickFormatDoc( sal_Bool
)
446 rEditEngine
.QuickFormatDoc();
451 sal_Bool
SvxEditEngineForwarder::Delete( const ESelection
& rSelection
)
453 rEditEngine
.QuickDelete( rSelection
);
454 rEditEngine
.QuickFormatDoc();
459 sal_Bool
SvxEditEngineForwarder::InsertText( const String
& rStr
, const ESelection
& rSelection
)
461 rEditEngine
.QuickInsertText( rStr
, rSelection
);
462 rEditEngine
.QuickFormatDoc();
467 sal_Int16
SvxEditEngineForwarder::GetDepth( sal_uInt16
) const
469 // EditEngine does not support outline depth
473 sal_Bool
SvxEditEngineForwarder::SetDepth( sal_uInt16
, sal_Int16 nNewDepth
)
475 // EditEngine does not support outline depth
476 return nNewDepth
== -1 ? sal_True
: sal_False
;
479 const SfxItemSet
* SvxEditEngineForwarder::GetEmptyItemSetPtr()
481 return &rEditEngine
.GetEmptyItemSet();
484 void SvxEditEngineForwarder::AppendParagraph()
486 rEditEngine
.InsertParagraph( rEditEngine
.GetParagraphCount(), String::EmptyString() );
489 xub_StrLen
SvxEditEngineForwarder::AppendTextPortion( sal_uInt16 nPara
, const String
&rText
, const SfxItemSet
& /*rSet*/ )
493 sal_uInt16 nParaCount
= rEditEngine
.GetParagraphCount();
494 DBG_ASSERT( nPara
< nParaCount
, "paragraph index out of bounds" );
495 if (/*0 <= nPara && */nPara
< nParaCount
)
497 nLen
= rEditEngine
.GetTextLen( nPara
);
498 rEditEngine
.QuickInsertText( rText
, ESelection( nPara
, nLen
, nPara
, nLen
) );
504 void SvxEditEngineForwarder::CopyText(const SvxTextForwarder
& rSource
)
506 const SvxEditEngineForwarder
* pSourceForwarder
= dynamic_cast< const SvxEditEngineForwarder
* >( &rSource
);
507 if( !pSourceForwarder
)
509 EditTextObject
* pNewTextObject
= pSourceForwarder
->rEditEngine
.CreateTextObject();
510 rEditEngine
.SetText( *pNewTextObject
);
511 delete pNewTextObject
;
514 //------------------------------------------------------------------------
516 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */