xref: /trunk/main/editeng/source/uno/unoforou.cxx (revision 1fd82021)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_editeng.hxx"
26 
27 #include <algorithm>
28 #include <svl/style.hxx>
29 #include <com/sun/star/i18n/WordType.hpp>
30 
31 #include <svl/itemset.hxx>
32 #include <editeng/editeng.hxx>
33 #include <editeng/editdata.hxx>
34 #include <editeng/outliner.hxx>
35 #include <editeng/unoedhlp.hxx>
36 #include <svl/poolitem.hxx>
37 #include <vcl/wrkwin.hxx>
38 #include <editeng/eeitem.hxx>
39 
40 #include <editeng/unoforou.hxx>
41 #include <editeng/unofored.hxx>
42 #include <editeng/outlobj.hxx>
43 
44 using namespace ::com::sun::star;
45 
46 //------------------------------------------------------------------------
47 
48 SvxOutlinerForwarder::SvxOutlinerForwarder( Outliner& rOutl, sal_Bool bOutlText /* = sal_False */ ) :
49 	rOutliner( rOutl ),
50     bOutlinerText( bOutlText ),
51     mpAttribsCache( NULL ),
52     mpParaAttribsCache( NULL ),
53     mnParaAttribsCache( 0 )
54 {
55 }
56 
57 SvxOutlinerForwarder::~SvxOutlinerForwarder()
58 {
59 	flushCache();
60 }
61 
62 sal_uInt32 SvxOutlinerForwarder::GetParagraphCount() const
63 {
64 	return rOutliner.GetParagraphCount();
65 }
66 
67 sal_uInt16 SvxOutlinerForwarder::GetTextLen( sal_uInt32 nParagraph ) const
68 {
69 	return rOutliner.GetEditEngine().GetTextLen( nParagraph );
70 }
71 
72 String SvxOutlinerForwarder::GetText( const ESelection& rSel ) const
73 {
74 	//!	GetText(ESelection) sollte es wohl auch mal am Outliner geben
75 	//	solange den Hack fuer die EditEngine uebernehmen:
76 	EditEngine* pEditEngine = (EditEngine*)&rOutliner.GetEditEngine();
77 	return pEditEngine->GetText( rSel, LINEEND_LF );
78 }
79 
80 static SfxItemSet ImplOutlinerForwarderGetAttribs( const ESelection& rSel, sal_Bool bOnlyHardAttrib, EditEngine& rEditEngine )
81 {
82 	if( rSel.nStartPara == rSel.nEndPara )
83 	{
84 		sal_uInt8 nFlags = 0;
85 
86 		switch( bOnlyHardAttrib )
87 		{
88 		case EditEngineAttribs_All:
89 			nFlags = GETATTRIBS_ALL;
90 			break;
91 		case EditEngineAttribs_HardAndPara:
92 			nFlags = GETATTRIBS_PARAATTRIBS|GETATTRIBS_CHARATTRIBS;
93 			break;
94 		case EditEngineAttribs_OnlyHard:
95 			nFlags = GETATTRIBS_CHARATTRIBS;
96 			break;
97 		default:
98 			DBG_ERROR("unknown flags for SvxOutlinerForwarder::GetAttribs");
99 		}
100 		return rEditEngine.GetAttribs( rSel.nStartPara, rSel.nStartPos, rSel.nEndPos, nFlags );
101 	}
102 	else
103 	{
104 		return rEditEngine.GetAttribs( rSel, bOnlyHardAttrib );
105 	}
106 }
107 
108 SfxItemSet SvxOutlinerForwarder::GetAttribs( const ESelection& rSel, sal_Bool bOnlyHardAttrib ) const
109 {
110 	if( mpAttribsCache && ( 0 == bOnlyHardAttrib ) )
111 	{
112 		// have we the correct set in cache?
113 		if( ((SvxOutlinerForwarder*)this)->maAttribCacheSelection.IsEqual(rSel) )
114 		{
115 			// yes! just return the cache
116 			return *mpAttribsCache;
117 		}
118 		else
119 		{
120 			// no, we need delete the old cache
121 			delete mpAttribsCache;
122 			mpAttribsCache = NULL;
123 		}
124 	}
125 
126 	//!	gibt's das nicht am Outliner ???
127 	//!	und warum ist GetAttribs an der EditEngine nicht const?
128 	EditEngine& rEditEngine = (EditEngine&)rOutliner.GetEditEngine();
129 
130 	SfxItemSet aSet( ImplOutlinerForwarderGetAttribs( rSel, bOnlyHardAttrib, rEditEngine ) );
131 
132 	if( 0 == bOnlyHardAttrib )
133 	{
134 		mpAttribsCache = new SfxItemSet( aSet );
135 		maAttribCacheSelection = rSel;
136 	}
137 
138 	SfxStyleSheet* pStyle = rEditEngine.GetStyleSheet( rSel.nStartPara );
139 	if( pStyle )
140 		aSet.SetParent( &(pStyle->GetItemSet() ) );
141 
142 	return aSet;
143 }
144 
145 SfxItemSet SvxOutlinerForwarder::GetParaAttribs( sal_uInt32 nPara ) const
146 {
147 	if( mpParaAttribsCache )
148 	{
149 		// have we the correct set in cache?
150 		if( nPara == mnParaAttribsCache )
151 		{
152 			// yes! just return the cache
153 			return *mpParaAttribsCache;
154 		}
155 		else
156 		{
157 			// no, we need delete the old cache
158 			delete mpParaAttribsCache;
159 			mpParaAttribsCache = NULL;
160 		}
161 	}
162 
163 	mpParaAttribsCache = new SfxItemSet( rOutliner.GetParaAttribs( nPara ) );
164 	mnParaAttribsCache = nPara;
165 
166 	EditEngine& rEditEngine = (EditEngine&)rOutliner.GetEditEngine();
167 
168 	SfxStyleSheet* pStyle = rEditEngine.GetStyleSheet( nPara );
169 	if( pStyle )
170 		mpParaAttribsCache->SetParent( &(pStyle->GetItemSet() ) );
171 
172 	return *mpParaAttribsCache;
173 }
174 
175 void SvxOutlinerForwarder::SetParaAttribs( sal_uInt32 nPara, const SfxItemSet& rSet )
176 {
177 	flushCache();
178 
179 	const SfxItemSet* pOldParent = rSet.GetParent();
180 	if( pOldParent )
181 		((SfxItemSet*)&rSet)->SetParent( NULL );
182 
183 	rOutliner.SetParaAttribs( nPara, rSet );
184 
185 	if( pOldParent )
186 		((SfxItemSet*)&rSet)->SetParent( pOldParent );
187 }
188 
189 void SvxOutlinerForwarder::RemoveAttribs( const ESelection& rSelection, sal_Bool bRemoveParaAttribs, sal_uInt16 nWhich )
190 {
191     rOutliner.RemoveAttribs( rSelection, bRemoveParaAttribs, nWhich );
192 }
193 
194 SfxItemPool* SvxOutlinerForwarder::GetPool() const
195 {
196 	return rOutliner.GetEmptyItemSet().GetPool();
197 }
198 
199 void SvxOutlinerForwarder::GetPortions( sal_uInt32 nPara, SvUShorts& rList ) const
200 {
201 	((EditEngine&)rOutliner.GetEditEngine()).GetPortions( nPara, rList );
202 }
203 
204 void SvxOutlinerForwarder::QuickInsertText( const String& rText, const ESelection& rSel )
205 {
206 	flushCache();
207 	if( rText.Len() == 0 )
208 	{
209 		rOutliner.QuickDelete( rSel );
210 	}
211 	else
212 	{
213 		rOutliner.QuickInsertText( rText, rSel );
214 	}
215 }
216 
217 void SvxOutlinerForwarder::QuickInsertLineBreak( const ESelection& rSel )
218 {
219 	flushCache();
220 	rOutliner.QuickInsertLineBreak( rSel );
221 }
222 
223 void SvxOutlinerForwarder::QuickInsertField( const SvxFieldItem& rFld, const ESelection& rSel )
224 {
225 	flushCache();
226 	rOutliner.QuickInsertField( rFld, rSel );
227 }
228 
229 void SvxOutlinerForwarder::QuickSetAttribs( const SfxItemSet& rSet, const ESelection& rSel )
230 {
231 	flushCache();
232 	rOutliner.QuickSetAttribs( rSet, rSel );
233 }
234 
235 XubString SvxOutlinerForwarder::CalcFieldValue( const SvxFieldItem& rField, sal_uInt32 nPara, sal_uInt16 nPos, Color*& rpTxtColor, Color*& rpFldColor )
236 {
237 	return rOutliner.CalcFieldValue( rField, nPara, nPos, rpTxtColor, rpFldColor );
238 }
239 
240 void SvxOutlinerForwarder::FieldClicked( const SvxFieldItem& rField, sal_uInt16 nPara, xub_StrLen nPos )
241 {
242     rOutliner.FieldClicked( rField, nPara, nPos );
243 }
244 
245 sal_Bool SvxOutlinerForwarder::IsValid() const
246 {
247     // cannot reliably query outliner state
248     // while in the middle of an update
249     return rOutliner.GetUpdateMode();
250 }
251 
252 extern sal_uInt16 GetSvxEditEngineItemState( EditEngine& rEditEngine, const ESelection& rSel, sal_uInt16 nWhich );
253 
254 sal_uInt16 SvxOutlinerForwarder::GetItemState( const ESelection& rSel, sal_uInt16 nWhich ) const
255 {
256 	return GetSvxEditEngineItemState( (EditEngine&)rOutliner.GetEditEngine(), rSel, nWhich );
257 }
258 
259 sal_uInt16 SvxOutlinerForwarder::GetItemState( sal_uInt32 nPara, sal_uInt16 nWhich ) const
260 {
261 	const SfxItemSet& rSet = rOutliner.GetParaAttribs( nPara );
262 	return rSet.GetItemState( nWhich );
263 }
264 
265 
266 void SvxOutlinerForwarder::flushCache()
267 {
268 	if( mpAttribsCache )
269 	{
270 		delete mpAttribsCache;
271 		mpAttribsCache = NULL;
272 	}
273 
274 	if( mpParaAttribsCache )
275 	{
276 		delete mpParaAttribsCache;
277 		mpParaAttribsCache = NULL;
278 	}
279 }
280 
281 LanguageType SvxOutlinerForwarder::GetLanguage( sal_uInt16 nPara, sal_uInt16 nIndex ) const
282 {
283     return rOutliner.GetLanguage(nPara, nIndex);
284 }
285 
286 sal_uInt16 SvxOutlinerForwarder::GetFieldCount( sal_uInt16 nPara ) const
287 {
288     return rOutliner.GetEditEngine().GetFieldCount(nPara);
289 }
290 
291 EFieldInfo SvxOutlinerForwarder::GetFieldInfo( sal_uInt16 nPara, sal_uInt16 nField ) const
292 {
293     return rOutliner.GetEditEngine().GetFieldInfo( nPara, nField );
294 }
295 
296 EBulletInfo SvxOutlinerForwarder::GetBulletInfo( sal_uInt16 nPara ) const
297 {
298     return rOutliner.GetBulletInfo( nPara );
299 }
300 
301 Rectangle SvxOutlinerForwarder::GetCharBounds( sal_uInt16 nPara, sal_uInt16 nIndex ) const
302 {
303     // #101701#
304     // EditEngine's 'internal' methods like GetCharacterBounds()
305     // don't rotate for vertical text.
306     Size aSize( rOutliner.CalcTextSize() );
307     ::std::swap( aSize.Width(), aSize.Height() );
308     bool bIsVertical( rOutliner.IsVertical() == sal_True );
309 
310     // #108900# Handle virtual position one-past-the end of the string
311     if( nIndex >= GetTextLen(nPara) )
312     {
313         Rectangle aLast;
314 
315         if( nIndex )
316         {
317             // use last character, if possible
318             aLast = rOutliner.GetEditEngine().GetCharacterBounds( EPosition(nPara, nIndex-1) );
319 
320             // move at end of this last character, make one pixel wide
321             aLast.Move( aLast.Right() - aLast.Left(), 0 );
322             aLast.SetSize( Size(1, aLast.GetHeight()) );
323 
324             // take care for CTL
325             aLast = SvxEditSourceHelper::EEToUserSpace( aLast, aSize, bIsVertical );
326         }
327         else
328         {
329             // #109864# Bounds must lie within the paragraph
330             aLast = GetParaBounds( nPara );
331 
332             // #109151# Don't use paragraph height, but line height
333             // instead. aLast is already CTL-correct
334             if( bIsVertical)
335                 aLast.SetSize( Size( rOutliner.GetLineHeight(nPara,0), 1 ) );
336             else
337                 aLast.SetSize( Size( 1, rOutliner.GetLineHeight(nPara,0) ) );
338         }
339 
340         return aLast;
341     }
342     else
343     {
344         return SvxEditSourceHelper::EEToUserSpace( rOutliner.GetEditEngine().GetCharacterBounds( EPosition(nPara, nIndex) ),
345                                                    aSize, bIsVertical );
346     }
347 }
348 
349 Rectangle SvxOutlinerForwarder::GetParaBounds( sal_uInt16 nPara ) const
350 {
351     Point aPnt = rOutliner.GetDocPosTopLeft( nPara );
352     Size aSize = rOutliner.CalcTextSize();
353 
354     if( rOutliner.IsVertical() )
355     {
356         // #101701#
357         // Hargl. Outliner's 'external' methods return the rotated
358         // dimensions, 'internal' methods like GetTextHeight( n )
359         // don't rotate.
360         sal_uLong nWidth = rOutliner.GetTextHeight( nPara );
361 
362         return Rectangle( aSize.Width() - aPnt.Y() - nWidth, 0, aSize.Width() - aPnt.Y(), aSize.Height() );
363     }
364     else
365     {
366         sal_uLong nHeight = rOutliner.GetTextHeight( nPara );
367 
368         return Rectangle( 0, aPnt.Y(), aSize.Width(), aPnt.Y() + nHeight );
369     }
370 }
371 
372 MapMode SvxOutlinerForwarder::GetMapMode() const
373 {
374     return rOutliner.GetRefMapMode();
375 }
376 
377 OutputDevice* SvxOutlinerForwarder::GetRefDevice() const
378 {
379     return rOutliner.GetRefDevice();
380 }
381 
382 sal_Bool SvxOutlinerForwarder::GetIndexAtPoint( const Point& rPos, sal_uInt16& nPara, sal_uInt16& nIndex ) const
383 {
384     // #101701#
385     Size aSize( rOutliner.CalcTextSize() );
386     ::std::swap( aSize.Width(), aSize.Height() );
387     Point aEEPos( SvxEditSourceHelper::UserSpaceToEE( rPos,
388                                                       aSize,
389                                                       rOutliner.IsVertical() == sal_True ));
390 
391     EPosition aDocPos = rOutliner.GetEditEngine().FindDocPosition( aEEPos );
392 
393     nPara = aDocPos.nPara;
394     nIndex = aDocPos.nIndex;
395 
396     return sal_True;
397 }
398 
399 sal_Bool SvxOutlinerForwarder::GetWordIndices( sal_uInt16 nPara, sal_uInt16 nIndex, sal_uInt16& nStart, sal_uInt16& nEnd ) const
400 {
401     ESelection aRes = rOutliner.GetEditEngine().GetWord( ESelection(nPara, nIndex, nPara, nIndex), com::sun::star::i18n::WordType::DICTIONARY_WORD );
402 
403     if( aRes.nStartPara == nPara &&
404         aRes.nStartPara == aRes.nEndPara )
405     {
406         nStart = aRes.nStartPos;
407         nEnd = aRes.nEndPos;
408 
409         return sal_True;
410     }
411 
412     return sal_False;
413 }
414 sal_Bool SvxOutlinerForwarder::GetAttributeRun( sal_uInt16& nStartIndex, sal_uInt16& nEndIndex, sal_uInt32 nPara, sal_uInt16 nIndex, sal_Bool bInCell ) const
415 {
416     return SvxEditSourceHelper::GetAttributeRun( nStartIndex, nEndIndex, rOutliner.GetEditEngine(), nPara, nIndex, bInCell );
417 }
418 
419 sal_uInt16 SvxOutlinerForwarder::GetLineCount( sal_uInt16 nPara ) const
420 {
421     return static_cast < sal_uInt16 >( rOutliner.GetLineCount(nPara) );
422 }
423 
424 sal_uInt16 SvxOutlinerForwarder::GetLineLen( sal_uInt16 nPara, sal_uInt16 nLine ) const
425 {
426     return rOutliner.GetLineLen(nPara, nLine);
427 }
428 
429 void SvxOutlinerForwarder::GetLineBoundaries( /*out*/sal_uInt16 &rStart, /*out*/sal_uInt16 &rEnd, sal_uInt16 nPara, sal_uInt16 nLine ) const
430 {
431     return rOutliner.GetEditEngine().GetLineBoundaries( rStart, rEnd, nPara, nLine );
432 }
433 
434 sal_uInt16 SvxOutlinerForwarder::GetLineNumberAtIndex( sal_uInt16 nPara, sal_uInt16 nIndex ) const
435 {
436     return rOutliner.GetEditEngine().GetLineNumberAtIndex( nPara, nIndex );
437 }
438 
439 sal_Bool SvxOutlinerForwarder::QuickFormatDoc( sal_Bool )
440 {
441     rOutliner.QuickFormatDoc();
442 
443     return sal_True;
444 }
445 
446 sal_Bool SvxOutlinerForwarder::Delete( const ESelection& rSelection )
447 {
448 	flushCache();
449     rOutliner.QuickDelete( rSelection );
450     rOutliner.QuickFormatDoc();
451 
452     return sal_True;
453 }
454 
455 sal_Bool SvxOutlinerForwarder::InsertText( const String& rStr, const ESelection& rSelection )
456 {
457 	flushCache();
458     rOutliner.QuickInsertText( rStr, rSelection );
459     rOutliner.QuickFormatDoc();
460 
461     return sal_True;
462 }
463 
464 sal_Int16 SvxOutlinerForwarder::GetDepth( sal_uInt16 nPara ) const
465 {
466     DBG_ASSERT( nPara < GetParagraphCount(), "SvxOutlinerForwarder::GetDepth: Invalid paragraph index");
467 
468     Paragraph* pPara = rOutliner.GetParagraph( nPara );
469 
470     sal_Int16 nLevel = -1;
471 
472     if( pPara )
473         nLevel = rOutliner.GetDepth( nPara );
474 
475     return nLevel;
476 }
477 
478 sal_Bool SvxOutlinerForwarder::SetDepth( sal_uInt16 nPara, sal_Int16 nNewDepth )
479 {
480     DBG_ASSERT( nPara < GetParagraphCount(), "SvxOutlinerForwarder::SetDepth: Invalid paragraph index");
481 
482     if( (nNewDepth >= -1) && (nNewDepth <= 9) && (nPara < GetParagraphCount()) )
483     {
484         Paragraph* pPara = rOutliner.GetParagraph( nPara );
485         if( pPara )
486         {
487             rOutliner.SetDepth( pPara, nNewDepth );
488 
489 //			const bool bOutlinerText = pSdrObject && (pSdrObject->GetObjInventor() == SdrInventor) && (pSdrObject->GetObjIdentifier() == OBJ_OUTLINETEXT);
490             if( bOutlinerText )
491                 rOutliner.SetLevelDependendStyleSheet( nPara );
492 
493             return sal_True;
494         }
495     }
496 
497     return sal_False;
498 }
499 
500 sal_Int16 SvxOutlinerForwarder::GetNumberingStartValue( sal_uInt16 nPara )
501 {
502     if( nPara < GetParagraphCount() )
503     {
504         return rOutliner.GetNumberingStartValue( nPara );
505     }
506     else
507     {
508         DBG_ERROR( "SvxOutlinerForwarder::GetNumberingStartValue)(), Invalid paragraph index");
509         return -1;
510     }
511 }
512 
513 void SvxOutlinerForwarder::SetNumberingStartValue(  sal_uInt16 nPara, sal_Int16 nNumberingStartValue )
514 {
515     if( nPara < GetParagraphCount() )
516     {
517         rOutliner.SetNumberingStartValue( nPara, nNumberingStartValue );
518     }
519     else
520     {
521         DBG_ERROR( "SvxOutlinerForwarder::SetNumberingStartValue)(), Invalid paragraph index");
522     }
523 }
524 
525 sal_Bool SvxOutlinerForwarder::IsParaIsNumberingRestart( sal_uInt16 nPara )
526 {
527     if( nPara < GetParagraphCount() )
528     {
529         return rOutliner.IsParaIsNumberingRestart( nPara );
530     }
531     else
532     {
533         DBG_ERROR( "SvxOutlinerForwarder::IsParaIsNumberingRestart)(), Invalid paragraph index");
534         return sal_False;
535     }
536 }
537 
538 void SvxOutlinerForwarder::SetParaIsNumberingRestart(  sal_uInt16 nPara, sal_Bool bParaIsNumberingRestart )
539 {
540     if( nPara < GetParagraphCount() )
541     {
542         rOutliner.SetParaIsNumberingRestart( nPara, bParaIsNumberingRestart );
543     }
544     else
545     {
546         DBG_ERROR( "SvxOutlinerForwarder::SetParaIsNumberingRestart)(), Invalid paragraph index");
547     }
548 }
549 
550 const SfxItemSet * SvxOutlinerForwarder::GetEmptyItemSetPtr()
551 {
552     EditEngine& rEditEngine = const_cast< EditEngine& >( rOutliner.GetEditEngine() );
553     return &rEditEngine.GetEmptyItemSet();
554 }
555 
556 void SvxOutlinerForwarder::AppendParagraph()
557 {
558     EditEngine& rEditEngine = const_cast< EditEngine& >( rOutliner.GetEditEngine() );
559     rEditEngine.InsertParagraph( rEditEngine.GetParagraphCount(), String::EmptyString() );
560 }
561 
562 xub_StrLen SvxOutlinerForwarder::AppendTextPortion( sal_uInt16 nPara, const String &rText, const SfxItemSet & /*rSet*/ )
563 {
564     xub_StrLen nLen = 0;
565 
566     EditEngine& rEditEngine = const_cast< EditEngine& >( rOutliner.GetEditEngine() );
567     sal_uInt32 nParaCount = rEditEngine.GetParagraphCount();
568     DBG_ASSERT( nPara < nParaCount, "paragraph index out of bounds" );
569     if (/*0 <= nPara && */nPara < nParaCount)
570     {
571         nLen = rEditEngine.GetTextLen( nPara );
572         rEditEngine.QuickInsertText( rText, ESelection( nPara, nLen, nPara, nLen ) );
573     }
574 
575     return nLen;
576 }
577 
578 void  SvxOutlinerForwarder::CopyText(const SvxTextForwarder& rSource)
579 {
580     const SvxOutlinerForwarder* pSourceForwarder = dynamic_cast< const SvxOutlinerForwarder* >( &rSource );
581     if( !pSourceForwarder )
582         return;
583     OutlinerParaObject* pNewOutlinerParaObject = pSourceForwarder->rOutliner.CreateParaObject();
584     rOutliner.SetText( *pNewOutlinerParaObject );
585     delete pNewOutlinerParaObject;
586 }
587 
588 //------------------------------------------------------------------------
589 
590 
591 sal_Int16 SvxTextForwarder::GetNumberingStartValue( sal_uInt16 )
592 {
593     return -1;
594 }
595 
596 void SvxTextForwarder::SetNumberingStartValue( sal_uInt16, sal_Int16 )
597 {
598 }
599 
600 sal_Bool SvxTextForwarder::IsParaIsNumberingRestart( sal_uInt16  )
601 {
602     return sal_False;
603 }
604 
605 void SvxTextForwarder::SetParaIsNumberingRestart( sal_uInt16, sal_Bool )
606 {
607 }
608 
609 //------------------------------------------------------------------------
610 
611