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