xref: /trunk/main/sc/source/ui/unoobj/textuno.cxx (revision b3f79822)
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_sc.hxx"
26 
27 
28 
29 #include "scitems.hxx"
30 #include <editeng/eeitem.hxx>
31 #include <svx/svdpool.hxx>
32 #include <svx/svdobj.hxx>
33 #include <editeng/editeng.hxx>
34 #include <editeng/editobj.hxx>
35 #include <editeng/flditem.hxx>
36 #include <svx/unomid.hxx>
37 #include <editeng/unoprnms.hxx>
38 #include <editeng/unofored.hxx>
39 #include <rtl/uuid.h>
40 #include <vcl/virdev.hxx>
41 #include <com/sun/star/awt/FontSlant.hpp>
42 
43 #include <com/sun/star/beans/PropertyAttribute.hpp>
44 #include <editeng/unoipset.hxx>
45 #include "textuno.hxx"
46 #include "fielduno.hxx"
47 #include "servuno.hxx"
48 #include "editsrc.hxx"
49 #include "docsh.hxx"
50 #include "editutil.hxx"
51 #include "unoguard.hxx"
52 #include "miscuno.hxx"
53 #include "cellsuno.hxx"
54 #include "hints.hxx"
55 #include "patattr.hxx"
56 #include "cell.hxx"
57 #include "docfunc.hxx"
58 #include "scmod.hxx"
59 
60 using namespace com::sun::star;
61 
62 //------------------------------------------------------------------------
63 
lcl_GetHdFtPropertySet()64 const SvxItemPropertySet * lcl_GetHdFtPropertySet()
65 {
66     static SfxItemPropertyMapEntry aHdFtPropertyMap_Impl[] =
67 	{
68 		SVX_UNOEDIT_CHAR_PROPERTIES,
69 		SVX_UNOEDIT_FONT_PROPERTIES,
70 		SVX_UNOEDIT_PARA_PROPERTIES,
71 		SVX_UNOEDIT_NUMBERING_PROPERTIE,	// for completeness of service ParagraphProperties
72         {0,0,0,0,0,0}
73 	};
74 	static sal_Bool bTwipsSet = sal_False;
75 
76 	if (!bTwipsSet)
77 	{
78 		//	modify PropertyMap to include CONVERT_TWIPS flag for font height
79 		//	(headers/footers are in twips)
80 
81         SfxItemPropertyMapEntry* pEntry = aHdFtPropertyMap_Impl;
82 		while (pEntry->pName)
83 		{
84 			if ( ( pEntry->nWID == EE_CHAR_FONTHEIGHT ||
85 				   pEntry->nWID == EE_CHAR_FONTHEIGHT_CJK ||
86 				   pEntry->nWID == EE_CHAR_FONTHEIGHT_CTL ) &&
87 				 pEntry->nMemberId == MID_FONTHEIGHT )
88 			{
89 				pEntry->nMemberId |= CONVERT_TWIPS;
90 			}
91 
92 			++pEntry;
93 		}
94 		bTwipsSet = sal_True;
95 	}
96     static SvxItemPropertySet aHdFtPropertySet_Impl( aHdFtPropertyMap_Impl, SdrObject::GetGlobalDrawObjectItemPool() );
97 	return &aHdFtPropertySet_Impl;
98 }
99 
100 //------------------------------------------------------------------------
101 
102 SC_SIMPLE_SERVICE_INFO( ScHeaderFooterContentObj, "ScHeaderFooterContentObj", "com.sun.star.sheet.HeaderFooterContent" )
103 SC_SIMPLE_SERVICE_INFO( ScHeaderFooterTextObj, "ScHeaderFooterTextObj", "stardiv.one.Text.Text" )
104 
105 //------------------------------------------------------------------------
106 
ScHeaderFooterContentObj(const EditTextObject * pLeft,const EditTextObject * pCenter,const EditTextObject * pRight)107 ScHeaderFooterContentObj::ScHeaderFooterContentObj( const EditTextObject* pLeft,
108 													const EditTextObject* pCenter,
109 													const EditTextObject* pRight ) :
110 	pLeftText	( NULL ),
111 	pCenterText	( NULL ),
112 	pRightText	( NULL )
113 {
114 	if ( pLeft )
115 		pLeftText	= pLeft->Clone();
116 	if ( pCenter )
117 		pCenterText	= pCenter->Clone();
118 	if ( pRight )
119 		pRightText	= pRight->Clone();
120 }
121 
~ScHeaderFooterContentObj()122 ScHeaderFooterContentObj::~ScHeaderFooterContentObj()
123 {
124 	delete pLeftText;
125 	delete pCenterText;
126 	delete pRightText;
127 }
128 
AddListener(SfxListener & rListener)129 void ScHeaderFooterContentObj::AddListener( SfxListener& rListener )
130 {
131 	rListener.StartListening( aBC );
132 }
133 
RemoveListener(SfxListener & rListener)134 void ScHeaderFooterContentObj::RemoveListener( SfxListener& rListener )
135 {
136 	rListener.EndListening( aBC );
137 }
138 
UpdateText(sal_uInt16 nPart,EditEngine & rSource)139 void ScHeaderFooterContentObj::UpdateText( sal_uInt16 nPart, EditEngine& rSource )
140 {
141 	EditTextObject* pNew = rSource.CreateTextObject();
142 	switch (nPart)
143 	{
144 		case SC_HDFT_LEFT:
145 			delete pLeftText;
146 			pLeftText = pNew;
147 			break;
148 		case SC_HDFT_CENTER:
149 			delete pCenterText;
150 			pCenterText = pNew;
151 			break;
152 		default:				// SC_HDFT_RIGHT
153 			delete pRightText;
154 			pRightText = pNew;
155 			break;
156 	}
157 
158 	aBC.Broadcast( ScHeaderFooterChangedHint( nPart ) );
159 }
160 
161 // XHeaderFooterContent
162 
getLeftText()163 uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getLeftText()
164 												throw(uno::RuntimeException)
165 {
166 	ScUnoGuard aGuard;
167 	return new ScHeaderFooterTextObj( *this, SC_HDFT_LEFT );
168 }
169 
getCenterText()170 uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getCenterText()
171 												throw(uno::RuntimeException)
172 {
173 	ScUnoGuard aGuard;
174 	return new ScHeaderFooterTextObj( *this, SC_HDFT_CENTER );
175 }
176 
getRightText()177 uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getRightText()
178 												throw(uno::RuntimeException)
179 {
180 	ScUnoGuard aGuard;
181 	return new ScHeaderFooterTextObj( *this, SC_HDFT_RIGHT );
182 }
183 
184 // XUnoTunnel
185 
getSomething(const uno::Sequence<sal_Int8> & rId)186 sal_Int64 SAL_CALL ScHeaderFooterContentObj::getSomething(
187 				const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
188 {
189 	if ( rId.getLength() == 16 &&
190           0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
191 									rId.getConstArray(), 16 ) )
192 	{
193         return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
194 	}
195 	return 0;
196 }
197 
198 // static
getUnoTunnelId()199 const uno::Sequence<sal_Int8>& ScHeaderFooterContentObj::getUnoTunnelId()
200 {
201 	static uno::Sequence<sal_Int8> * pSeq = 0;
202 	if( !pSeq )
203 	{
204 		osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
205 		if( !pSeq )
206 		{
207 			static uno::Sequence< sal_Int8 > aSeq( 16 );
208 			rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
209 			pSeq = &aSeq;
210 		}
211 	}
212 	return *pSeq;
213 }
214 
215 // static
getImplementation(const uno::Reference<sheet::XHeaderFooterContent> xObj)216 ScHeaderFooterContentObj* ScHeaderFooterContentObj::getImplementation(
217 								const uno::Reference<sheet::XHeaderFooterContent> xObj )
218 {
219 	ScHeaderFooterContentObj* pRet = NULL;
220 	uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
221 	if (xUT.is())
222         pRet = reinterpret_cast<ScHeaderFooterContentObj*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
223 	return pRet;
224 }
225 
226 
227 //------------------------------------------------------------------------
228 
ScHeaderFooterTextData(ScHeaderFooterContentObj & rContent,sal_uInt16 nP)229 ScHeaderFooterTextData::ScHeaderFooterTextData( ScHeaderFooterContentObj& rContent,
230 													sal_uInt16 nP ) :
231 	rContentObj( rContent ),
232 	nPart( nP ),
233 	pEditEngine( NULL ),
234 	pForwarder( NULL ),
235 	bDataValid( sal_False ),
236 	bInUpdate( sal_False )
237 {
238 	rContentObj.acquire();				// must not go away
239 	rContentObj.AddListener( *this );
240 }
241 
~ScHeaderFooterTextData()242 ScHeaderFooterTextData::~ScHeaderFooterTextData()
243 {
244 	ScUnoGuard aGuard;		//	needed for EditEngine dtor
245 
246 	rContentObj.RemoveListener( *this );
247 
248 	delete pForwarder;
249 	delete pEditEngine;
250 
251 	rContentObj.release();
252 }
253 
Notify(SfxBroadcaster &,const SfxHint & rHint)254 void ScHeaderFooterTextData::Notify( SfxBroadcaster&, const SfxHint& rHint )
255 {
256 	if ( rHint.ISA( ScHeaderFooterChangedHint ) )
257 	{
258 		if ( ((const ScHeaderFooterChangedHint&)rHint).GetPart() == nPart )
259 		{
260 			if (!bInUpdate)				// not for own updates
261 				bDataValid = sal_False;		// text has to be fetched again
262 		}
263 	}
264 }
265 
GetTextForwarder()266 SvxTextForwarder* ScHeaderFooterTextData::GetTextForwarder()
267 {
268 	if (!pEditEngine)
269 	{
270 		SfxItemPool* pEnginePool = EditEngine::CreatePool();
271 		pEnginePool->FreezeIdRanges();
272 		ScHeaderEditEngine* pHdrEngine = new ScHeaderEditEngine( pEnginePool, sal_True );
273 
274 		pHdrEngine->EnableUndo( sal_False );
275 		pHdrEngine->SetRefMapMode( MAP_TWIP );
276 
277 		//	default font must be set, independently of document
278 		//	-> use global pool from module
279 
280 		SfxItemSet aDefaults( pHdrEngine->GetEmptyItemSet() );
281 		const ScPatternAttr& rPattern = (const ScPatternAttr&)SC_MOD()->GetPool().GetDefaultItem(ATTR_PATTERN);
282 		rPattern.FillEditItemSet( &aDefaults );
283 		//	FillEditItemSet adjusts font height to 1/100th mm,
284 		//	but for header/footer twips is needed, as in the PatternAttr:
285 		aDefaults.Put( rPattern.GetItem(ATTR_FONT_HEIGHT), EE_CHAR_FONTHEIGHT );
286 		aDefaults.Put( rPattern.GetItem(ATTR_CJK_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CJK );
287 		aDefaults.Put( rPattern.GetItem(ATTR_CTL_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CTL );
288 		pHdrEngine->SetDefaults( aDefaults );
289 
290 		ScHeaderFieldData aData;
291 		ScHeaderFooterTextObj::FillDummyFieldData( aData );
292 		pHdrEngine->SetData( aData );
293 
294 		pEditEngine = pHdrEngine;
295 		pForwarder = new SvxEditEngineForwarder(*pEditEngine);
296 	}
297 
298 	if (bDataValid)
299 		return pForwarder;
300 
301 	const EditTextObject* pData;
302 	if (nPart == SC_HDFT_LEFT)
303 		pData = rContentObj.GetLeftEditObject();
304 	else if (nPart == SC_HDFT_CENTER)
305 		pData = rContentObj.GetCenterEditObject();
306 	else
307 		pData = rContentObj.GetRightEditObject();
308 
309 	if (pData)
310 		pEditEngine->SetText(*pData);
311 
312 	bDataValid = sal_True;
313 	return pForwarder;
314 }
315 
UpdateData()316 void ScHeaderFooterTextData::UpdateData()
317 {
318 	if ( pEditEngine )
319 	{
320 		bInUpdate = sal_True;	// don't reset bDataValid during UpdateText
321 
322 		rContentObj.UpdateText( nPart, *pEditEngine );
323 
324 		bInUpdate = sal_False;
325 	}
326 }
327 
328 //------------------------------------------------------------------------
329 
ScHeaderFooterTextObj(ScHeaderFooterContentObj & rContent,sal_uInt16 nP)330 ScHeaderFooterTextObj::ScHeaderFooterTextObj( ScHeaderFooterContentObj& rContent,
331 												sal_uInt16 nP ) :
332 	aTextData( rContent, nP ),
333 	pUnoText( NULL )
334 {
335 	//	ScHeaderFooterTextData acquires rContent
336 	//	pUnoText is created on demand (getString/setString work without it)
337 }
338 
CreateUnoText_Impl()339 void ScHeaderFooterTextObj::CreateUnoText_Impl()
340 {
341 	if ( !pUnoText )
342 	{
343 		//	can't be aggregated because getString/setString is handled here
344 		ScSharedHeaderFooterEditSource aEditSource( &aTextData );
345 		pUnoText = new SvxUnoText( &aEditSource, lcl_GetHdFtPropertySet(), uno::Reference<text::XText>() );
346 		pUnoText->acquire();
347 	}
348 }
349 
~ScHeaderFooterTextObj()350 ScHeaderFooterTextObj::~ScHeaderFooterTextObj()
351 {
352 	if (pUnoText)
353 		pUnoText->release();
354 }
355 
GetUnoText()356 const SvxUnoText& ScHeaderFooterTextObj::GetUnoText()
357 {
358 	if (!pUnoText)
359 		CreateUnoText_Impl();
360 	return *pUnoText;
361 }
362 
363 // XText
364 
createTextCursor()365 uno::Reference<text::XTextCursor> SAL_CALL ScHeaderFooterTextObj::createTextCursor()
366 													throw(uno::RuntimeException)
367 {
368 	ScUnoGuard aGuard;
369 	return new ScHeaderFooterTextCursor( *this );
370 }
371 
createTextCursorByRange(const uno::Reference<text::XTextRange> & aTextPosition)372 uno::Reference<text::XTextCursor> SAL_CALL ScHeaderFooterTextObj::createTextCursorByRange(
373 									const uno::Reference<text::XTextRange>& aTextPosition )
374 													throw(uno::RuntimeException)
375 {
376 	ScUnoGuard aGuard;
377 	if (!pUnoText)
378 		CreateUnoText_Impl();
379 	return pUnoText->createTextCursorByRange(aTextPosition);
380 	//!	wie ScCellObj::createTextCursorByRange, wenn SvxUnoTextRange_getReflection verfuegbar
381 }
382 
FillDummyFieldData(ScHeaderFieldData & rData)383 void ScHeaderFooterTextObj::FillDummyFieldData( ScHeaderFieldData& rData )	// static
384 {
385 	String aDummy(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( "???" )));
386 	rData.aTitle		= aDummy;
387 	rData.aLongDocName	= aDummy;
388 	rData.aShortDocName	= aDummy;
389 	rData.aTabName		= aDummy;
390 	rData.nPageNo		= 1;
391 	rData.nTotalPages	= 99;
392 }
393 
getString()394 rtl::OUString SAL_CALL ScHeaderFooterTextObj::getString() throw(uno::RuntimeException)
395 {
396 	ScUnoGuard aGuard;
397 	rtl::OUString aRet;
398 	const EditTextObject* pData;
399 
400 	sal_uInt16 nPart = aTextData.GetPart();
401 	ScHeaderFooterContentObj& rContentObj = aTextData.GetContentObj();
402 
403 	if (nPart == SC_HDFT_LEFT)
404 		pData = rContentObj.GetLeftEditObject();
405 	else if (nPart == SC_HDFT_CENTER)
406 		pData = rContentObj.GetCenterEditObject();
407 	else
408 		pData = rContentObj.GetRightEditObject();
409 	if (pData)
410 	{
411 		// for pure text, no font info is needed in pool defaults
412 		ScHeaderEditEngine aEditEngine( EditEngine::CreatePool(), sal_True );
413 
414 		ScHeaderFieldData aData;
415 		FillDummyFieldData( aData );
416 		aEditEngine.SetData( aData );
417 
418 		aEditEngine.SetText(*pData);
419 		aRet = ScEditUtil::GetSpaceDelimitedString( aEditEngine );
420 	}
421 	return aRet;
422 }
423 
setString(const rtl::OUString & aText)424 void SAL_CALL ScHeaderFooterTextObj::setString( const rtl::OUString& aText ) throw(uno::RuntimeException)
425 {
426 	ScUnoGuard aGuard;
427 	String aString(aText);
428 
429 	// for pure text, no font info is needed in pool defaults
430 	ScHeaderEditEngine aEditEngine( EditEngine::CreatePool(), sal_True );
431 	aEditEngine.SetText( aString );
432 
433 	aTextData.GetContentObj().UpdateText( aTextData.GetPart(), aEditEngine );
434 }
435 
insertString(const uno::Reference<text::XTextRange> & xRange,const rtl::OUString & aString,sal_Bool bAbsorb)436 void SAL_CALL ScHeaderFooterTextObj::insertString( const uno::Reference<text::XTextRange>& xRange,
437 											const rtl::OUString& aString, sal_Bool bAbsorb )
438 								throw(uno::RuntimeException)
439 {
440 	ScUnoGuard aGuard;
441 	if (!pUnoText)
442 		CreateUnoText_Impl();
443 	pUnoText->insertString( xRange, aString, bAbsorb );
444 }
445 
insertControlCharacter(const uno::Reference<text::XTextRange> & xRange,sal_Int16 nControlCharacter,sal_Bool bAbsorb)446 void SAL_CALL ScHeaderFooterTextObj::insertControlCharacter(
447 											const uno::Reference<text::XTextRange>& xRange,
448 											sal_Int16 nControlCharacter, sal_Bool bAbsorb )
449 								throw(lang::IllegalArgumentException, uno::RuntimeException)
450 {
451 	ScUnoGuard aGuard;
452 	if (!pUnoText)
453 		CreateUnoText_Impl();
454 	pUnoText->insertControlCharacter( xRange, nControlCharacter, bAbsorb );
455 }
456 
insertTextContent(const uno::Reference<text::XTextRange> & xRange,const uno::Reference<text::XTextContent> & xContent,sal_Bool bAbsorb)457 void SAL_CALL ScHeaderFooterTextObj::insertTextContent(
458 											const uno::Reference<text::XTextRange >& xRange,
459 											const uno::Reference<text::XTextContent >& xContent,
460 											sal_Bool bAbsorb )
461 								throw(lang::IllegalArgumentException, uno::RuntimeException)
462 {
463 	ScUnoGuard aGuard;
464 	if ( xContent.is() && xRange.is() )
465 	{
466 		ScHeaderFieldObj* pHeaderField = ScHeaderFieldObj::getImplementation( xContent );
467 
468 		SvxUnoTextRangeBase* pTextRange =
469 			ScHeaderFooterTextCursor::getImplementation( xRange );
470 
471 #if 0
472 		if (!pTextRange)
473 			pTextRange = (SvxUnoTextRange*)xRange->getImplementation(
474 											SvxUnoTextRange_getReflection() );
475 		//!	bei SvxUnoTextRange testen, ob in passendem Objekt !!!
476 #endif
477 
478 		if ( pHeaderField && !pHeaderField->IsInserted() && pTextRange )
479 		{
480 			SvxEditSource* pEditSource = pTextRange->GetEditSource();
481 			ESelection aSelection(pTextRange->GetSelection());
482 
483 			if (!bAbsorb)
484 			{
485 				//	don't replace -> append at end
486 				aSelection.Adjust();
487 				aSelection.nStartPara = aSelection.nEndPara;
488 				aSelection.nStartPos  = aSelection.nEndPos;
489 			}
490 
491 			SvxFieldItem aItem(pHeaderField->CreateFieldItem());
492 
493 			SvxTextForwarder* pForwarder = pEditSource->GetTextForwarder();
494 			pForwarder->QuickInsertField( aItem, aSelection );
495 			pEditSource->UpdateData();
496 
497 			//	neue Selektion: ein Zeichen
498 			aSelection.Adjust();
499 			aSelection.nEndPara = aSelection.nStartPara;
500 			aSelection.nEndPos = aSelection.nStartPos + 1;
501 			pHeaderField->InitDoc( &aTextData.GetContentObj(), aTextData.GetPart(), aSelection );
502 
503 			//	#91431# for bAbsorb=sal_False, the new selection must be behind the inserted content
504 			//	(the xml filter relies on this)
505 			if (!bAbsorb)
506 				aSelection.nStartPos = aSelection.nEndPos;
507 
508 			pTextRange->SetSelection( aSelection );
509 
510 			return;
511 		}
512 	}
513 
514 	if (!pUnoText)
515 		CreateUnoText_Impl();
516 	pUnoText->insertTextContent( xRange, xContent, bAbsorb );
517 }
518 
removeTextContent(const uno::Reference<text::XTextContent> & xContent)519 void SAL_CALL ScHeaderFooterTextObj::removeTextContent(
520 											const uno::Reference<text::XTextContent>& xContent )
521 								throw(container::NoSuchElementException, uno::RuntimeException)
522 {
523 	ScUnoGuard aGuard;
524 	if ( xContent.is() )
525 	{
526 		ScHeaderFieldObj* pHeaderField = ScHeaderFieldObj::getImplementation( xContent );
527 		if ( pHeaderField && pHeaderField->IsInserted() )
528 		{
529 			//!	Testen, ob das Feld in dieser Zelle ist
530 			pHeaderField->DeleteField();
531 			return;
532 		}
533 	}
534 	if (!pUnoText)
535 		CreateUnoText_Impl();
536 	pUnoText->removeTextContent( xContent );
537 }
538 
getText()539 uno::Reference<text::XText> SAL_CALL ScHeaderFooterTextObj::getText() throw(uno::RuntimeException)
540 {
541 	ScUnoGuard aGuard;
542 	if (!pUnoText)
543 		CreateUnoText_Impl();
544 	return pUnoText->getText();
545 }
546 
getStart()547 uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextObj::getStart() throw(uno::RuntimeException)
548 {
549 	ScUnoGuard aGuard;
550 	if (!pUnoText)
551 		CreateUnoText_Impl();
552 	return pUnoText->getStart();
553 }
554 
getEnd()555 uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextObj::getEnd() throw(uno::RuntimeException)
556 {
557 	ScUnoGuard aGuard;
558 	if (!pUnoText)
559 		CreateUnoText_Impl();
560 	return pUnoText->getEnd();
561 }
562 
563 // XTextFieldsSupplier
564 
getTextFields()565 uno::Reference<container::XEnumerationAccess> SAL_CALL ScHeaderFooterTextObj::getTextFields()
566 												throw(uno::RuntimeException)
567 {
568 	ScUnoGuard aGuard;
569 	// all fields
570 	return new ScHeaderFieldsObj( &aTextData.GetContentObj(), aTextData.GetPart(), SC_SERVICE_INVALID );
571 }
572 
getTextFieldMasters()573 uno::Reference<container::XNameAccess> SAL_CALL ScHeaderFooterTextObj::getTextFieldMasters()
574 												throw(uno::RuntimeException)
575 {
576 	//	sowas gibts nicht im Calc (?)
577 	return NULL;
578 }
579 
580 // XTextRangeMover
581 
moveTextRange(const uno::Reference<text::XTextRange> & xRange,sal_Int16 nParagraphs)582 void SAL_CALL ScHeaderFooterTextObj::moveTextRange(
583 										const uno::Reference<text::XTextRange>& xRange,
584 										sal_Int16 nParagraphs )
585 										throw(uno::RuntimeException)
586 {
587 	ScUnoGuard aGuard;
588 	if (!pUnoText)
589 		CreateUnoText_Impl();
590 	pUnoText->moveTextRange( xRange, nParagraphs );
591 }
592 
593 // XEnumerationAccess
594 
createEnumeration()595 uno::Reference<container::XEnumeration> SAL_CALL ScHeaderFooterTextObj::createEnumeration()
596 												throw(uno::RuntimeException)
597 {
598 	ScUnoGuard aGuard;
599 	if (!pUnoText)
600 		CreateUnoText_Impl();
601 	return pUnoText->createEnumeration();
602 }
603 
604 // XElementAccess
605 
getElementType()606 uno::Type SAL_CALL ScHeaderFooterTextObj::getElementType() throw(uno::RuntimeException)
607 {
608 	ScUnoGuard aGuard;
609 	if (!pUnoText)
610 		CreateUnoText_Impl();
611 	return pUnoText->getElementType();
612 }
613 
hasElements()614 sal_Bool SAL_CALL ScHeaderFooterTextObj::hasElements() throw(uno::RuntimeException)
615 {
616 	ScUnoGuard aGuard;
617 	if (!pUnoText)
618 		CreateUnoText_Impl();
619 	return pUnoText->hasElements();
620 }
621 
622 //------------------------------------------------------------------------
623 
ScCellTextCursor(const ScCellTextCursor & rOther)624 ScCellTextCursor::ScCellTextCursor(const ScCellTextCursor& rOther) :
625 	SvxUnoTextCursor( rOther ),
626 	rTextObj( rOther.rTextObj )
627 {
628 	rTextObj.acquire();
629 }
630 
ScCellTextCursor(ScCellObj & rText)631 ScCellTextCursor::ScCellTextCursor(ScCellObj& rText) :
632 	SvxUnoTextCursor( rText.GetUnoText() ),
633 	rTextObj( rText )
634 {
635 	rTextObj.acquire();
636 }
637 
~ScCellTextCursor()638 ScCellTextCursor::~ScCellTextCursor() throw()
639 {
640 	rTextObj.release();
641 }
642 
643 // SvxUnoTextCursor methods reimplemented here to return the right objects:
644 
getText()645 uno::Reference<text::XText> SAL_CALL ScCellTextCursor::getText() throw(uno::RuntimeException)
646 {
647 	ScUnoGuard aGuard;
648 	return &rTextObj;
649 }
650 
getStart()651 uno::Reference<text::XTextRange> SAL_CALL ScCellTextCursor::getStart() throw(uno::RuntimeException)
652 {
653 	ScUnoGuard aGuard;
654 
655 	//!	use other object for range than cursor?
656 
657     ScCellTextCursor* pNew = new ScCellTextCursor( *this );
658 	uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
659 
660 	ESelection aNewSel(GetSelection());
661 	aNewSel.nEndPara = aNewSel.nStartPara;
662 	aNewSel.nEndPos  = aNewSel.nStartPos;
663 	pNew->SetSelection( aNewSel );
664 
665 	return xRange;
666 }
667 
getEnd()668 uno::Reference<text::XTextRange> SAL_CALL ScCellTextCursor::getEnd() throw(uno::RuntimeException)
669 {
670 	ScUnoGuard aGuard;
671 
672 	//!	use other object for range than cursor?
673 
674     ScCellTextCursor* pNew = new ScCellTextCursor( *this );
675     uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
676 
677 	ESelection aNewSel(GetSelection());
678 	aNewSel.nStartPara = aNewSel.nEndPara;
679 	aNewSel.nStartPos  = aNewSel.nEndPos;
680 	pNew->SetSelection( aNewSel );
681 
682 	return xRange;
683 }
684 
685 // XUnoTunnel
686 
getSomething(const uno::Sequence<sal_Int8> & rId)687 sal_Int64 SAL_CALL ScCellTextCursor::getSomething(
688 				const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
689 {
690 	if ( rId.getLength() == 16 &&
691           0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
692 									rId.getConstArray(), 16 ) )
693 	{
694         return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
695 	}
696 	return SvxUnoTextCursor::getSomething( rId );
697 }
698 
699 // static
getUnoTunnelId()700 const uno::Sequence<sal_Int8>& ScCellTextCursor::getUnoTunnelId()
701 {
702 	static uno::Sequence<sal_Int8> * pSeq = 0;
703 	if( !pSeq )
704 	{
705 		osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
706 		if( !pSeq )
707 		{
708 			static uno::Sequence< sal_Int8 > aSeq( 16 );
709 			rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
710 			pSeq = &aSeq;
711 		}
712 	}
713 	return *pSeq;
714 }
715 
716 // static
getImplementation(const uno::Reference<uno::XInterface> xObj)717 ScCellTextCursor* ScCellTextCursor::getImplementation( const uno::Reference<uno::XInterface> xObj )
718 {
719 	ScCellTextCursor* pRet = NULL;
720 	uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
721 	if (xUT.is())
722         pRet = reinterpret_cast<ScCellTextCursor*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
723 	return pRet;
724 }
725 
726 //------------------------------------------------------------------------
727 
ScHeaderFooterTextCursor(const ScHeaderFooterTextCursor & rOther)728 ScHeaderFooterTextCursor::ScHeaderFooterTextCursor(const ScHeaderFooterTextCursor& rOther) :
729 	SvxUnoTextCursor( rOther ),
730 	rTextObj( rOther.rTextObj )
731 {
732 	rTextObj.acquire();
733 }
734 
ScHeaderFooterTextCursor(ScHeaderFooterTextObj & rText)735 ScHeaderFooterTextCursor::ScHeaderFooterTextCursor(ScHeaderFooterTextObj& rText) :
736 	SvxUnoTextCursor( rText.GetUnoText() ),
737 	rTextObj( rText )
738 {
739 	rTextObj.acquire();
740 }
741 
~ScHeaderFooterTextCursor()742 ScHeaderFooterTextCursor::~ScHeaderFooterTextCursor() throw()
743 {
744 	rTextObj.release();
745 }
746 
747 // SvxUnoTextCursor methods reimplemented here to return the right objects:
748 
getText()749 uno::Reference<text::XText> SAL_CALL ScHeaderFooterTextCursor::getText() throw(uno::RuntimeException)
750 {
751 	ScUnoGuard aGuard;
752 	return &rTextObj;
753 }
754 
getStart()755 uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextCursor::getStart() throw(uno::RuntimeException)
756 {
757 	ScUnoGuard aGuard;
758 
759 	//!	use other object for range than cursor?
760 
761     ScHeaderFooterTextCursor* pNew = new ScHeaderFooterTextCursor( *this );
762     uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
763 
764 	ESelection aNewSel(GetSelection());
765 	aNewSel.nEndPara = aNewSel.nStartPara;
766 	aNewSel.nEndPos  = aNewSel.nStartPos;
767 	pNew->SetSelection( aNewSel );
768 
769 	return xRange;
770 }
771 
getEnd()772 uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextCursor::getEnd() throw(uno::RuntimeException)
773 {
774 	ScUnoGuard aGuard;
775 
776 	//!	use other object for range than cursor?
777 
778     ScHeaderFooterTextCursor* pNew = new ScHeaderFooterTextCursor( *this );
779 	uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
780 
781 	ESelection aNewSel(GetSelection());
782 	aNewSel.nStartPara = aNewSel.nEndPara;
783 	aNewSel.nStartPos  = aNewSel.nEndPos;
784 	pNew->SetSelection( aNewSel );
785 
786 	return xRange;
787 }
788 
789 // XUnoTunnel
790 
getSomething(const uno::Sequence<sal_Int8> & rId)791 sal_Int64 SAL_CALL ScHeaderFooterTextCursor::getSomething(
792 				const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
793 {
794 	if ( rId.getLength() == 16 &&
795           0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
796 									rId.getConstArray(), 16 ) )
797 	{
798         return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
799 	}
800 	return SvxUnoTextCursor::getSomething( rId );
801 }
802 
803 // static
getUnoTunnelId()804 const uno::Sequence<sal_Int8>& ScHeaderFooterTextCursor::getUnoTunnelId()
805 {
806 	static uno::Sequence<sal_Int8> * pSeq = 0;
807 	if( !pSeq )
808 	{
809 		osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
810 		if( !pSeq )
811 		{
812 			static uno::Sequence< sal_Int8 > aSeq( 16 );
813 			rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
814 			pSeq = &aSeq;
815 		}
816 	}
817 	return *pSeq;
818 }
819 
820 // static
getImplementation(const uno::Reference<uno::XInterface> xObj)821 ScHeaderFooterTextCursor* ScHeaderFooterTextCursor::getImplementation(
822 								const uno::Reference<uno::XInterface> xObj )
823 {
824 	ScHeaderFooterTextCursor* pRet = NULL;
825 	uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
826 	if (xUT.is())
827         pRet = reinterpret_cast<ScHeaderFooterTextCursor*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
828 	return pRet;
829 }
830 
831 //------------------------------------------------------------------------
832 
ScDrawTextCursor(const ScDrawTextCursor & rOther)833 ScDrawTextCursor::ScDrawTextCursor(const ScDrawTextCursor& rOther) :
834 	SvxUnoTextCursor( rOther ),
835 	xParentText( rOther.xParentText )
836 {
837 }
838 
ScDrawTextCursor(const uno::Reference<text::XText> & xParent,const SvxUnoTextBase & rText)839 ScDrawTextCursor::ScDrawTextCursor( const uno::Reference<text::XText>& xParent,
840 									const SvxUnoTextBase& rText ) :
841 	SvxUnoTextCursor( rText ),
842 	xParentText( xParent )
843 
844 {
845 }
846 
~ScDrawTextCursor()847 ScDrawTextCursor::~ScDrawTextCursor() throw()
848 {
849 }
850 
851 // SvxUnoTextCursor methods reimplemented here to return the right objects:
852 
getText()853 uno::Reference<text::XText> SAL_CALL ScDrawTextCursor::getText() throw(uno::RuntimeException)
854 {
855 	ScUnoGuard aGuard;
856 	return xParentText;
857 }
858 
getStart()859 uno::Reference<text::XTextRange> SAL_CALL ScDrawTextCursor::getStart() throw(uno::RuntimeException)
860 {
861 	ScUnoGuard aGuard;
862 
863 	//!	use other object for range than cursor?
864 
865 	ScDrawTextCursor* pNew = new ScDrawTextCursor( *this );
866     uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
867 
868 	ESelection aNewSel(GetSelection());
869 	aNewSel.nEndPara = aNewSel.nStartPara;
870 	aNewSel.nEndPos  = aNewSel.nStartPos;
871 	pNew->SetSelection( aNewSel );
872 
873 	return xRange;
874 }
875 
getEnd()876 uno::Reference<text::XTextRange> SAL_CALL ScDrawTextCursor::getEnd() throw(uno::RuntimeException)
877 {
878 	ScUnoGuard aGuard;
879 
880 	//!	use other object for range than cursor?
881 
882 	ScDrawTextCursor* pNew = new ScDrawTextCursor( *this );
883     uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
884 
885 	ESelection aNewSel(GetSelection());
886 	aNewSel.nStartPara = aNewSel.nEndPara;
887 	aNewSel.nStartPos  = aNewSel.nEndPos;
888 	pNew->SetSelection( aNewSel );
889 
890 	return xRange;
891 }
892 
893 // XUnoTunnel
894 
getSomething(const uno::Sequence<sal_Int8> & rId)895 sal_Int64 SAL_CALL ScDrawTextCursor::getSomething(
896                 const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
897 {
898     if ( rId.getLength() == 16 &&
899           0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
900                                     rId.getConstArray(), 16 ) )
901     {
902         return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
903     }
904     return SvxUnoTextCursor::getSomething( rId );
905 }
906 
907 // static
getUnoTunnelId()908 const uno::Sequence<sal_Int8>& ScDrawTextCursor::getUnoTunnelId()
909 {
910     static uno::Sequence<sal_Int8> * pSeq = 0;
911     if( !pSeq )
912     {
913         osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
914         if( !pSeq )
915         {
916             static uno::Sequence< sal_Int8 > aSeq( 16 );
917             rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
918             pSeq = &aSeq;
919         }
920     }
921     return *pSeq;
922 }
923 
924 // static
getImplementation(const uno::Reference<uno::XInterface> xObj)925 ScDrawTextCursor* ScDrawTextCursor::getImplementation( const uno::Reference<uno::XInterface> xObj )
926 {
927     ScDrawTextCursor* pRet = NULL;
928     uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
929     if (xUT.is())
930         pRet = reinterpret_cast<ScDrawTextCursor*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
931     return pRet;
932 }
933 
934 //------------------------------------------------------------------------
935 
ScSimpleEditSourceHelper()936 ScSimpleEditSourceHelper::ScSimpleEditSourceHelper()
937 {
938 	SfxItemPool* pEnginePool = EditEngine::CreatePool();
939 	pEnginePool->SetDefaultMetric( SFX_MAPUNIT_100TH_MM );
940 	pEnginePool->FreezeIdRanges();
941 
942 	pEditEngine = new ScFieldEditEngine( pEnginePool, NULL, sal_True );		// TRUE: become owner of pool
943 	pForwarder = new SvxEditEngineForwarder( *pEditEngine );
944 	pOriginalSource = new ScSimpleEditSource( pForwarder );
945 }
946 
~ScSimpleEditSourceHelper()947 ScSimpleEditSourceHelper::~ScSimpleEditSourceHelper()
948 {
949 	ScUnoGuard aGuard;		//	needed for EditEngine dtor
950 
951 	delete pOriginalSource;
952 	delete pForwarder;
953 	delete pEditEngine;
954 }
955 
ScEditEngineTextObj()956 ScEditEngineTextObj::ScEditEngineTextObj() :
957 	SvxUnoText( GetOriginalSource(), ScCellObj::GetEditPropertySet(), uno::Reference<text::XText>() )
958 {
959 }
960 
~ScEditEngineTextObj()961 ScEditEngineTextObj::~ScEditEngineTextObj() throw()
962 {
963 }
964 
SetText(const EditTextObject & rTextObject)965 void ScEditEngineTextObj::SetText( const EditTextObject& rTextObject )
966 {
967 	GetEditEngine()->SetText( rTextObject );
968 
969 	ESelection aSel;
970 	::GetSelection( aSel, GetEditSource()->GetTextForwarder() );
971 	SetSelection( aSel );
972 }
973 
CreateTextObject()974 EditTextObject* ScEditEngineTextObj::CreateTextObject()
975 {
976 	return GetEditEngine()->CreateTextObject();
977 }
978 
979 //------------------------------------------------------------------------
980 
ScCellTextData(ScDocShell * pDocSh,const ScAddress & rP)981 ScCellTextData::ScCellTextData(ScDocShell* pDocSh, const ScAddress& rP) :
982 	pDocShell( pDocSh ),
983 	aCellPos( rP ),
984 	pEditEngine( NULL ),
985 	pForwarder( NULL ),
986 	pOriginalSource( NULL ),
987 	bDataValid( sal_False ),
988 	bInUpdate( sal_False ),
989 	bDirty( sal_False ),
990 	bDoUpdate( sal_True )
991 {
992 	if (pDocShell)
993 		pDocShell->GetDocument()->AddUnoObject(*this);
994 }
995 
~ScCellTextData()996 ScCellTextData::~ScCellTextData()
997 {
998 	ScUnoGuard aGuard;		//	needed for EditEngine dtor
999 
1000 	if (pDocShell)
1001 	{
1002 		pDocShell->GetDocument()->RemoveUnoObject(*this);
1003 		pDocShell->GetDocument()->DisposeFieldEditEngine(pEditEngine);
1004 	}
1005 	else
1006 		delete pEditEngine;
1007 
1008 	delete pForwarder;
1009 
1010 	delete pOriginalSource;
1011 }
1012 
GetOriginalSource()1013 ScSharedCellEditSource* ScCellTextData::GetOriginalSource()
1014 {
1015 	if (!pOriginalSource)
1016 		pOriginalSource = new ScSharedCellEditSource( this );
1017 	return pOriginalSource;
1018 }
1019 
GetCellText(const ScAddress & rCellPos,String & rText)1020 void ScCellTextData::GetCellText(const ScAddress& rCellPos, String& rText)
1021 {
1022 	if (pDocShell)
1023 	{
1024 		ScDocument* pDoc = pDocShell->GetDocument();
1025 		pDoc->GetInputString( rCellPos.Col(), rCellPos.Row(), rCellPos.Tab(), rText );
1026     }
1027 }
1028 
GetTextForwarder()1029 SvxTextForwarder* ScCellTextData::GetTextForwarder()
1030 {
1031 	if (!pEditEngine)
1032 	{
1033 		if ( pDocShell )
1034 		{
1035 			ScDocument* pDoc = pDocShell->GetDocument();
1036 			pEditEngine = pDoc->CreateFieldEditEngine();
1037 		}
1038 		else
1039 		{
1040 			SfxItemPool* pEnginePool = EditEngine::CreatePool();
1041 			pEnginePool->FreezeIdRanges();
1042 			pEditEngine = new ScFieldEditEngine( pEnginePool, NULL, sal_True );
1043 		}
1044 		//	currently, GetPortions doesn't work if UpdateMode is sal_False,
1045 		//	this will be fixed (in EditEngine) by src600
1046 //		pEditEngine->SetUpdateMode( sal_False );
1047 		pEditEngine->EnableUndo( sal_False );
1048 		if (pDocShell)
1049 			pEditEngine->SetRefDevice(pDocShell->GetRefDevice());
1050 		else
1051 			pEditEngine->SetRefMapMode( MAP_100TH_MM );
1052 		pForwarder = new SvxEditEngineForwarder(*pEditEngine);
1053 	}
1054 
1055 	if (bDataValid)
1056 		return pForwarder;
1057 
1058 	String aText;
1059 
1060 	if (pDocShell)
1061 	{
1062 		ScDocument* pDoc = pDocShell->GetDocument();
1063 
1064 		SfxItemSet aDefaults( pEditEngine->GetEmptyItemSet() );
1065         if( const ScPatternAttr* pPattern =
1066                 pDoc->GetPattern( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab() ) )
1067         {
1068             pPattern->FillEditItemSet( &aDefaults );
1069             pPattern->FillEditParaItems( &aDefaults );  // including alignment etc. (for reading)
1070         }
1071 
1072 		const ScBaseCell* pCell = pDoc->GetCell( aCellPos );
1073 		if ( pCell && pCell->GetCellType() == CELLTYPE_EDIT )
1074 			pEditEngine->SetTextNewDefaults( *((const ScEditCell*)pCell)->GetData(), aDefaults );
1075 		else
1076 		{
1077 			GetCellText( aCellPos, aText );
1078 			if (aText.Len())
1079 				pEditEngine->SetTextNewDefaults( aText, aDefaults );
1080 			else
1081 				pEditEngine->SetDefaults(aDefaults);
1082 		}
1083 	}
1084 
1085 	bDataValid = sal_True;
1086 	return pForwarder;
1087 }
1088 
UpdateData()1089 void ScCellTextData::UpdateData()
1090 {
1091 	if ( bDoUpdate )
1092 	{
1093 		DBG_ASSERT(pEditEngine != NULL, "no EditEngine for UpdateData()");
1094 		if ( pDocShell && pEditEngine )
1095 		{
1096 			//	during the own UpdateData call, bDataValid must not be reset,
1097 			//	or things like attributes after the text would be lost
1098 			//	(are not stored in the cell)
1099 
1100 			bInUpdate = sal_True;	// prevents bDataValid from being reset
1101 
1102 			ScDocFunc aFunc(*pDocShell);
1103 			aFunc.PutData( aCellPos, *pEditEngine, sal_False, sal_True );	// always as text
1104 
1105 			bInUpdate = sal_False;
1106 			bDirty = sal_False;
1107 		}
1108 	}
1109 	else
1110 		bDirty = sal_True;
1111 }
1112 
Notify(SfxBroadcaster &,const SfxHint & rHint)1113 void ScCellTextData::Notify( SfxBroadcaster&, const SfxHint& rHint )
1114 {
1115 	if ( rHint.ISA( ScUpdateRefHint ) )
1116 	{
1117 //        const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
1118 
1119 		//!	Ref-Update
1120 	}
1121 	else if ( rHint.ISA( SfxSimpleHint ) )
1122 	{
1123 		sal_uLong nId = ((const SfxSimpleHint&)rHint).GetId();
1124 		if ( nId == SFX_HINT_DYING )
1125 		{
1126 			pDocShell = NULL;						// invalid now
1127 
1128 			DELETEZ( pForwarder );
1129 			DELETEZ( pEditEngine );		// EditEngine uses document's pool
1130 		}
1131 		else if ( nId == SFX_HINT_DATACHANGED )
1132 		{
1133 			if (!bInUpdate)							// not for own UpdateData calls
1134 				bDataValid = sal_False;					// text has to be read from the cell again
1135 		}
1136 	}
1137 }
1138 
ScCellTextObj(ScDocShell * pDocSh,const ScAddress & rP)1139 ScCellTextObj::ScCellTextObj(ScDocShell* pDocSh, const ScAddress& rP) :
1140 	ScCellTextData( pDocSh, rP ),
1141 	SvxUnoText( GetOriginalSource(), ScCellObj::GetEditPropertySet(), uno::Reference<text::XText>() )
1142 {
1143 }
1144 
~ScCellTextObj()1145 ScCellTextObj::~ScCellTextObj() throw()
1146 {
1147 }
1148 
1149