1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: unofored.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
35 #include <svx/eeitem.hxx>
36 #include <com/sun/star/i18n/WordType.hpp>
38 #include <svtools/itemset.hxx>
39 #include <svx/editeng.hxx>
40 #include <svx/editview.hxx>
41 #include <unoedhlp.hxx>
42 #include <svx/editdata.hxx>
43 #include <svx/outliner.hxx>
44 #include <svx/editobj.hxx> // nur fuer die GetText-Kruecke
46 #include <svx/unofored.hxx>
48 using namespace ::com::sun::star
;
50 //------------------------------------------------------------------------
52 SvxEditEngineForwarder::SvxEditEngineForwarder( EditEngine
& rEngine
) :
53 rEditEngine( rEngine
)
57 SvxEditEngineForwarder::~SvxEditEngineForwarder()
59 // die EditEngine muss ggf. von aussen geloescht werden
62 USHORT
SvxEditEngineForwarder::GetParagraphCount() const
64 return rEditEngine
.GetParagraphCount();
67 USHORT
SvxEditEngineForwarder::GetTextLen( USHORT nParagraph
) const
69 return rEditEngine
.GetTextLen( nParagraph
);
72 String
SvxEditEngineForwarder::GetText( const ESelection
& rSel
) const
74 String aRet
= rEditEngine
.GetText( rSel
, LINEEND_LF
);
75 aRet
.ConvertLineEnd();
79 SfxItemSet
SvxEditEngineForwarder::GetAttribs( const ESelection
& rSel
, BOOL bOnlyHardAttrib
) const
81 if( rSel
.nStartPara
== rSel
.nEndPara
)
84 switch( bOnlyHardAttrib
)
86 case EditEngineAttribs_All
:
87 nFlags
= GETATTRIBS_ALL
;
89 case EditEngineAttribs_HardAndPara
:
90 nFlags
= GETATTRIBS_PARAATTRIBS
|GETATTRIBS_CHARATTRIBS
;
92 case EditEngineAttribs_OnlyHard
:
93 nFlags
= GETATTRIBS_CHARATTRIBS
;
96 DBG_ERROR("unknown flags for SvxOutlinerForwarder::GetAttribs");
99 return rEditEngine
.GetAttribs( rSel
.nStartPara
, rSel
.nStartPos
, rSel
.nEndPos
, nFlags
);
103 return rEditEngine
.GetAttribs( rSel
, bOnlyHardAttrib
);
107 SfxItemSet
SvxEditEngineForwarder::GetParaAttribs( USHORT nPara
) const
109 SfxItemSet
aSet( rEditEngine
.GetParaAttribs( nPara
) );
111 USHORT nWhich
= EE_PARA_START
;
112 while( nWhich
<= EE_PARA_END
)
114 if( aSet
.GetItemState( nWhich
, TRUE
) != SFX_ITEM_ON
)
116 if( rEditEngine
.HasParaAttrib( nPara
, nWhich
) )
117 aSet
.Put( rEditEngine
.GetParaAttrib( nPara
, nWhich
) );
125 void SvxEditEngineForwarder::SetParaAttribs( USHORT nPara
, const SfxItemSet
& rSet
)
127 rEditEngine
.SetParaAttribs( nPara
, rSet
);
130 void SvxEditEngineForwarder::RemoveAttribs( const ESelection
& rSelection
, sal_Bool bRemoveParaAttribs
, sal_uInt16 nWhich
)
132 rEditEngine
.RemoveAttribs( rSelection
, bRemoveParaAttribs
, nWhich
);
135 SfxItemPool
* SvxEditEngineForwarder::GetPool() const
137 return rEditEngine
.GetEmptyItemSet().GetPool();
140 void SvxEditEngineForwarder::GetPortions( USHORT nPara
, SvUShorts
& rList
) const
142 rEditEngine
.GetPortions( nPara
, rList
);
145 void SvxEditEngineForwarder::QuickInsertText( const String
& rText
, const ESelection
& rSel
)
147 rEditEngine
.QuickInsertText( rText
, rSel
);
150 void SvxEditEngineForwarder::QuickInsertLineBreak( const ESelection
& rSel
)
152 rEditEngine
.QuickInsertLineBreak( rSel
);
155 void SvxEditEngineForwarder::QuickInsertField( const SvxFieldItem
& rFld
, const ESelection
& rSel
)
157 rEditEngine
.QuickInsertField( rFld
, rSel
);
160 void SvxEditEngineForwarder::QuickSetAttribs( const SfxItemSet
& rSet
, const ESelection
& rSel
)
162 rEditEngine
.QuickSetAttribs( rSet
, rSel
);
165 BOOL
SvxEditEngineForwarder::IsValid() const
167 // cannot reliably query EditEngine state
168 // while in the middle of an update
169 return rEditEngine
.GetUpdateMode();
172 XubString
SvxEditEngineForwarder::CalcFieldValue( const SvxFieldItem
& rField
, USHORT nPara
, USHORT nPos
, Color
*& rpTxtColor
, Color
*& rpFldColor
)
174 return rEditEngine
.CalcFieldValue( rField
, nPara
, nPos
, rpTxtColor
, rpFldColor
);
177 USHORT
GetSvxEditEngineItemState( EditEngine
& rEditEngine
, const ESelection
& rSel
, USHORT nWhich
)
179 EECharAttribArray aAttribs
;
181 const SfxPoolItem
* pLastItem
= NULL
;
183 SfxItemState eState
= SFX_ITEM_DEFAULT
;
185 // check all paragraphs inside the selection
186 for( USHORT nPara
= rSel
.nStartPara
; nPara
<= rSel
.nEndPara
; nPara
++ )
188 SfxItemState eParaState
= SFX_ITEM_DEFAULT
;
190 // calculate start and endpos for this paragraph
192 if( rSel
.nStartPara
== nPara
)
193 nPos
= rSel
.nStartPos
;
195 USHORT nEndPos
= rSel
.nEndPos
;
196 if( rSel
.nEndPara
!= nPara
)
197 nEndPos
= rEditEngine
.GetTextLen( nPara
);
200 // get list of char attribs
201 rEditEngine
.GetCharAttribs( nPara
, aAttribs
);
203 BOOL bEmpty
= TRUE
; // we found no item inside the selektion of this paragraph
204 BOOL bGaps
= FALSE
; // we found items but theire gaps between them
205 USHORT nLastEnd
= nPos
;
207 const SfxPoolItem
* pParaItem
= NULL
;
209 for( USHORT nAttrib
= 0; nAttrib
< aAttribs
.Count(); nAttrib
++ )
211 struct EECharAttrib aAttrib
= aAttribs
.GetObject( nAttrib
);
212 DBG_ASSERT( aAttrib
.pAttr
, "GetCharAttribs gives corrupt data" );
214 const sal_Bool bEmptyPortion
= aAttrib
.nStart
== aAttrib
.nEnd
;
215 if( (!bEmptyPortion
&& (aAttrib
.nStart
>= nEndPos
)) || (bEmptyPortion
&& (aAttrib
.nStart
> nEndPos
)) )
216 break; // break if we are already behind our selektion
218 if( (!bEmptyPortion
&& (aAttrib
.nEnd
<= nPos
)) || (bEmptyPortion
&& (aAttrib
.nEnd
< nPos
)) )
219 continue; // or if the attribute ends before our selektion
221 if( aAttrib
.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
!= *aAttrib
.pAttr
)
229 return SFX_ITEM_DONTCARE
;
233 pParaItem
= aAttrib
.pAttr
;
239 if( !bGaps
&& aAttrib
.nStart
> nLastEnd
)
242 nLastEnd
= aAttrib
.nEnd
;
245 if( !bEmpty
&& !bGaps
&& nLastEnd
< ( nEndPos
- 1 ) )
248 // since we have no portion with our item or if there were gaps
249 if( bEmpty || bGaps )
251 // we need to check the paragraph item
252 const SfxItemSet& rParaSet = rEditEngine.GetParaAttribs( nPara );
253 if( rParaSet.GetItemState( nWhich ) == SFX_ITEM_SET )
255 eState = SFX_ITEM_SET;
256 // get item from the paragraph
257 const SfxPoolItem* pTempItem = rParaSet.GetItem( nWhich );
260 if( *pParaItem != *pTempItem )
261 return SFX_ITEM_DONTCARE;
265 pParaItem = pTempItem;
268 // set if theres no last item or if its the same
269 eParaState = SFX_ITEM_SET;
273 eParaState = SFX_ITEM_DEFAULT;
277 // gaps and item not set in paragraph, thats a dont care
278 return SFX_ITEM_DONTCARE;
283 eParaState = SFX_ITEM_SET;
287 eParaState
= SFX_ITEM_DEFAULT
;
289 eParaState
= SFX_ITEM_DONTCARE
;
291 eParaState
= SFX_ITEM_SET
;
293 // if we already found an item check if we found the same
296 if( (pParaItem
== NULL
) || (*pLastItem
!= *pParaItem
) )
297 return SFX_ITEM_DONTCARE
;
301 pLastItem
= pParaItem
;
309 USHORT
SvxEditEngineForwarder::GetItemState( const ESelection
& rSel
, USHORT nWhich
) const
311 return GetSvxEditEngineItemState( rEditEngine
, rSel
, nWhich
);
314 USHORT
SvxEditEngineForwarder::GetItemState( USHORT nPara
, USHORT nWhich
) const
316 const SfxItemSet
& rSet
= rEditEngine
.GetParaAttribs( nPara
);
317 return rSet
.GetItemState( nWhich
);
320 LanguageType
SvxEditEngineForwarder::GetLanguage( USHORT nPara
, USHORT nIndex
) const
322 return rEditEngine
.GetLanguage(nPara
, nIndex
);
325 USHORT
SvxEditEngineForwarder::GetFieldCount( USHORT nPara
) const
327 return rEditEngine
.GetFieldCount(nPara
);
330 EFieldInfo
SvxEditEngineForwarder::GetFieldInfo( USHORT nPara
, USHORT nField
) const
332 return rEditEngine
.GetFieldInfo( nPara
, nField
);
335 EBulletInfo
SvxEditEngineForwarder::GetBulletInfo( USHORT
) const
337 return EBulletInfo();
340 Rectangle
SvxEditEngineForwarder::GetCharBounds( USHORT nPara
, USHORT nIndex
) const
343 // EditEngine's 'internal' methods like GetCharacterBounds()
344 // don't rotate for vertical text.
345 Size
aSize( rEditEngine
.CalcTextWidth(), rEditEngine
.GetTextHeight() );
346 ::std::swap( aSize
.Width(), aSize
.Height() );
347 bool bIsVertical( rEditEngine
.IsVertical() == TRUE
);
349 // #108900# Handle virtual position one-past-the end of the string
350 if( nIndex
>= rEditEngine
.GetTextLen(nPara
) )
356 // use last character, if possible
357 aLast
= rEditEngine
.GetCharacterBounds( EPosition(nPara
, nIndex
-1) );
359 // move at end of this last character, make one pixel wide
360 aLast
.Move( aLast
.Right() - aLast
.Left(), 0 );
361 aLast
.SetSize( Size(1, aLast
.GetHeight()) );
364 aLast
= SvxEditSourceHelper::EEToUserSpace( aLast
, aSize
, bIsVertical
);
368 // #109864# Bounds must lie within the paragraph
369 aLast
= GetParaBounds( nPara
);
371 // #109151# Don't use paragraph height, but line height
372 // instead. aLast is already CTL-correct
374 aLast
.SetSize( Size( rEditEngine
.GetLineHeight(nPara
,0), 1 ) );
376 aLast
.SetSize( Size( 1, rEditEngine
.GetLineHeight(nPara
,0) ) );
383 return SvxEditSourceHelper::EEToUserSpace( rEditEngine
.GetCharacterBounds( EPosition(nPara
, nIndex
) ),
384 aSize
, bIsVertical
);
388 Rectangle
SvxEditEngineForwarder::GetParaBounds( USHORT nPara
) const
390 const Point aPnt
= rEditEngine
.GetDocPosTopLeft( nPara
);
395 if( rEditEngine
.IsVertical() )
398 // Hargl. EditEngine's 'external' methods return the rotated
399 // dimensions, 'internal' methods like GetTextHeight( n )
401 nWidth
= rEditEngine
.GetTextHeight( nPara
);
402 nHeight
= rEditEngine
.GetTextHeight();
403 nTextWidth
= rEditEngine
.GetTextHeight();
405 return Rectangle( nTextWidth
- aPnt
.Y() - nWidth
, 0, nTextWidth
- aPnt
.Y(), nHeight
);
409 nWidth
= rEditEngine
.CalcTextWidth();
410 nHeight
= rEditEngine
.GetTextHeight( nPara
);
412 return Rectangle( 0, aPnt
.Y(), nWidth
, aPnt
.Y() + nHeight
);
416 MapMode
SvxEditEngineForwarder::GetMapMode() const
418 return rEditEngine
.GetRefMapMode();
421 OutputDevice
* SvxEditEngineForwarder::GetRefDevice() const
423 return rEditEngine
.GetRefDevice();
426 sal_Bool
SvxEditEngineForwarder::GetIndexAtPoint( const Point
& rPos
, USHORT
& nPara
, USHORT
& nIndex
) const
429 Size
aSize( rEditEngine
.CalcTextWidth(), rEditEngine
.GetTextHeight() );
430 ::std::swap( aSize
.Width(), aSize
.Height() );
431 Point
aEEPos( SvxEditSourceHelper::UserSpaceToEE( rPos
,
433 rEditEngine
.IsVertical() == TRUE
));
435 EPosition aDocPos
= rEditEngine
.FindDocPosition( aEEPos
);
437 nPara
= aDocPos
.nPara
;
438 nIndex
= aDocPos
.nIndex
;
443 sal_Bool
SvxEditEngineForwarder::GetWordIndices( USHORT nPara
, USHORT nIndex
, USHORT
& nStart
, USHORT
& nEnd
) const
445 ESelection aRes
= rEditEngine
.GetWord( ESelection(nPara
, nIndex
, nPara
, nIndex
), com::sun::star::i18n::WordType::DICTIONARY_WORD
);
447 if( aRes
.nStartPara
== nPara
&&
448 aRes
.nStartPara
== aRes
.nEndPara
)
450 nStart
= aRes
.nStartPos
;
459 sal_Bool
SvxEditEngineForwarder::GetAttributeRun( USHORT
& nStartIndex
, USHORT
& nEndIndex
, USHORT nPara
, USHORT nIndex
) const
461 return SvxEditSourceHelper::GetAttributeRun( nStartIndex
, nEndIndex
, rEditEngine
, nPara
, nIndex
);
464 USHORT
SvxEditEngineForwarder::GetLineCount( USHORT nPara
) const
466 return rEditEngine
.GetLineCount(nPara
);
469 USHORT
SvxEditEngineForwarder::GetLineLen( USHORT nPara
, USHORT nLine
) const
471 return rEditEngine
.GetLineLen(nPara
, nLine
);
474 void SvxEditEngineForwarder::GetLineBoundaries( /*out*/USHORT
&rStart
, /*out*/USHORT
&rEnd
, USHORT nPara
, USHORT nLine
) const
476 rEditEngine
.GetLineBoundaries(rStart
, rEnd
, nPara
, nLine
);
479 USHORT
SvxEditEngineForwarder::GetLineNumberAtIndex( USHORT nPara
, USHORT nIndex
) const
481 return rEditEngine
.GetLineNumberAtIndex(nPara
, nIndex
);
485 sal_Bool
SvxEditEngineForwarder::QuickFormatDoc( BOOL
)
487 rEditEngine
.QuickFormatDoc();
492 sal_Bool
SvxEditEngineForwarder::Delete( const ESelection
& rSelection
)
494 rEditEngine
.QuickDelete( rSelection
);
495 rEditEngine
.QuickFormatDoc();
500 sal_Bool
SvxEditEngineForwarder::InsertText( const String
& rStr
, const ESelection
& rSelection
)
502 rEditEngine
.QuickInsertText( rStr
, rSelection
);
503 rEditEngine
.QuickFormatDoc();
508 sal_Int16
SvxEditEngineForwarder::GetDepth( USHORT
) const
510 // EditEngine does not support outline depth
514 sal_Bool
SvxEditEngineForwarder::SetDepth( USHORT
, sal_Int16 nNewDepth
)
516 // EditEngine does not support outline depth
517 return nNewDepth
== -1 ? sal_True
: sal_False
;
520 const SfxItemSet
* SvxEditEngineForwarder::GetEmptyItemSetPtr()
522 return &rEditEngine
.GetEmptyItemSet();
525 void SvxEditEngineForwarder::AppendParagraph()
527 rEditEngine
.InsertParagraph( rEditEngine
.GetParagraphCount(), String::EmptyString() );
530 xub_StrLen
SvxEditEngineForwarder::AppendTextPortion( USHORT nPara
, const String
&rText
, const SfxItemSet
& /*rSet*/ )
534 USHORT nParaCount
= rEditEngine
.GetParagraphCount();
535 DBG_ASSERT( nPara
< nParaCount
, "paragraph index out of bounds" );
536 if (/*0 <= nPara && */nPara
< nParaCount
)
538 nLen
= rEditEngine
.GetTextLen( nPara
);
539 rEditEngine
.QuickInsertText( rText
, ESelection( nPara
, nLen
, nPara
, nLen
) );
545 void SvxEditEngineForwarder::CopyText(const SvxTextForwarder
& rSource
)
547 const SvxEditEngineForwarder
* pSourceForwarder
= dynamic_cast< const SvxEditEngineForwarder
* >( &rSource
);
548 if( !pSourceForwarder
)
550 EditTextObject
* pNewTextObject
= pSourceForwarder
->rEditEngine
.CreateTextObject();
551 rEditEngine
.SetText( *pNewTextObject
);
552 delete pNewTextObject
;
555 //------------------------------------------------------------------------