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