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 3342 : static const SvxItemPropertySet * lcl_GetHdFtPropertySet()
53 : {
54 : static SfxItemPropertyMapEntry aHdFtPropertyMap_Impl[] =
55 : {
56 2548 : SVX_UNOEDIT_CHAR_PROPERTIES,
57 52 : SVX_UNOEDIT_FONT_PROPERTIES,
58 728 : SVX_UNOEDIT_PARA_PROPERTIES,
59 104 : SVX_UNOEDIT_NUMBERING_PROPERTIE, // for completeness of service ParagraphProperties
60 : { OUString(), 0, css::uno::Type(), 0, 0 }
61 6826 : };
62 : static bool bTwipsSet = false;
63 :
64 3342 : if (!bTwipsSet)
65 : {
66 : // modify PropertyMap to include CONVERT_TWIPS flag for font height
67 : // (headers/footers are in twips)
68 :
69 52 : SfxItemPropertyMapEntry* pEntry = aHdFtPropertyMap_Impl;
70 3536 : while (!pEntry->aName.isEmpty())
71 : {
72 6812 : if ( ( pEntry->nWID == EE_CHAR_FONTHEIGHT ||
73 6708 : pEntry->nWID == EE_CHAR_FONTHEIGHT_CJK ||
74 3484 : pEntry->nWID == EE_CHAR_FONTHEIGHT_CTL ) &&
75 156 : pEntry->nMemberId == MID_FONTHEIGHT )
76 : {
77 0 : pEntry->nMemberId |= CONVERT_TWIPS;
78 : }
79 :
80 3432 : ++pEntry;
81 : }
82 52 : bTwipsSet = true;
83 : }
84 3342 : static SvxItemPropertySet aHdFtPropertySet_Impl( aHdFtPropertyMap_Impl, SdrObject::GetGlobalDrawObjectItemPool() );
85 3342 : 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 3550 : ScHeaderFooterContentObj::ScHeaderFooterContentObj( const EditTextObject* pLeft,
92 : const EditTextObject* pCenter,
93 : const EditTextObject* pRight ) :
94 3550 : mxLeftText(new ScHeaderFooterTextObj(*this, SC_HDFT_LEFT, pLeft)),
95 3550 : mxCenterText(new ScHeaderFooterTextObj(*this, SC_HDFT_CENTER, pCenter)),
96 10650 : mxRightText(new ScHeaderFooterTextObj(*this, SC_HDFT_RIGHT, pRight))
97 : {
98 3550 : }
99 :
100 7100 : ScHeaderFooterContentObj::~ScHeaderFooterContentObj() {}
101 :
102 3138 : const EditTextObject* ScHeaderFooterContentObj::GetLeftEditObject() const
103 : {
104 3138 : return mxLeftText->GetTextObject();
105 : }
106 :
107 3150 : const EditTextObject* ScHeaderFooterContentObj::GetCenterEditObject() const
108 : {
109 3150 : return mxCenterText->GetTextObject();
110 : }
111 :
112 3138 : const EditTextObject* ScHeaderFooterContentObj::GetRightEditObject() const
113 : {
114 3138 : return mxRightText->GetTextObject();
115 : }
116 :
117 : // XHeaderFooterContent
118 :
119 4070 : uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getLeftText()
120 : throw(uno::RuntimeException, std::exception)
121 : {
122 4070 : SolarMutexGuard aGuard;
123 4070 : uno::Reference<text::XText> xInt(*mxLeftText, uno::UNO_QUERY);
124 4070 : return xInt;
125 : }
126 :
127 4776 : uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getCenterText()
128 : throw(uno::RuntimeException, std::exception)
129 : {
130 4776 : SolarMutexGuard aGuard;
131 4776 : uno::Reference<text::XText> xInt(*mxCenterText, uno::UNO_QUERY);
132 4776 : return xInt;
133 : }
134 :
135 4064 : uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getRightText()
136 : throw(uno::RuntimeException, std::exception)
137 : {
138 4064 : SolarMutexGuard aGuard;
139 4064 : uno::Reference<text::XText> xInt(*mxRightText, uno::UNO_QUERY);
140 4064 : return xInt;
141 : }
142 :
143 : // XUnoTunnel
144 :
145 2724 : sal_Int64 SAL_CALL ScHeaderFooterContentObj::getSomething(
146 : const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException, std::exception)
147 : {
148 5448 : if ( rId.getLength() == 16 &&
149 2724 : 0 == memcmp( getUnoTunnelId().getConstArray(),
150 5448 : rId.getConstArray(), 16 ) )
151 : {
152 2724 : 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 5448 : const uno::Sequence<sal_Int8>& ScHeaderFooterContentObj::getUnoTunnelId()
163 : {
164 5448 : return theScHeaderFooterContentObjUnoTunnelId::get().getSeq();
165 : }
166 :
167 2724 : ScHeaderFooterContentObj* ScHeaderFooterContentObj::getImplementation(
168 : const uno::Reference<sheet::XHeaderFooterContent> xObj )
169 : {
170 2724 : ScHeaderFooterContentObj* pRet = NULL;
171 2724 : uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
172 2724 : if (xUT.is())
173 2724 : pRet = reinterpret_cast<ScHeaderFooterContentObj*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
174 2724 : return pRet;
175 : }
176 :
177 10650 : ScHeaderFooterTextData::ScHeaderFooterTextData(
178 : ScHeaderFooterContentObj& 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 10650 : bDataValid(false)
185 : {
186 10650 : }
187 :
188 10650 : ScHeaderFooterTextData::~ScHeaderFooterTextData()
189 : {
190 10650 : SolarMutexGuard aGuard; // needed for EditEngine dtor
191 :
192 10650 : delete pForwarder;
193 10650 : delete pEditEngine;
194 10650 : delete mpTextObj;
195 10650 : }
196 :
197 135816 : SvxTextForwarder* ScHeaderFooterTextData::GetTextForwarder()
198 : {
199 135816 : if (!pEditEngine)
200 : {
201 3342 : SfxItemPool* pEnginePool = EditEngine::CreatePool();
202 3342 : pEnginePool->FreezeIdRanges();
203 3342 : ScHeaderEditEngine* pHdrEngine = new ScHeaderEditEngine( pEnginePool, true );
204 :
205 3342 : pHdrEngine->EnableUndo( false );
206 3342 : pHdrEngine->SetRefMapMode( MAP_TWIP );
207 :
208 : // default font must be set, independently of document
209 : // -> use global pool from module
210 :
211 3342 : SfxItemSet aDefaults( pHdrEngine->GetEmptyItemSet() );
212 3342 : const ScPatternAttr& rPattern = static_cast<const ScPatternAttr&>(SC_MOD()->GetPool().GetDefaultItem(ATTR_PATTERN));
213 3342 : 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 3342 : aDefaults.Put( rPattern.GetItem(ATTR_FONT_HEIGHT), EE_CHAR_FONTHEIGHT );
217 3342 : aDefaults.Put( rPattern.GetItem(ATTR_CJK_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CJK );
218 3342 : aDefaults.Put( rPattern.GetItem(ATTR_CTL_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CTL );
219 3342 : pHdrEngine->SetDefaults( aDefaults );
220 :
221 6684 : ScHeaderFieldData aData;
222 3342 : ScHeaderFooterTextObj::FillDummyFieldData( aData );
223 3342 : pHdrEngine->SetData( aData );
224 :
225 3342 : pEditEngine = pHdrEngine;
226 6684 : pForwarder = new SvxEditEngineForwarder(*pEditEngine);
227 : }
228 :
229 135816 : if (bDataValid)
230 132464 : return pForwarder;
231 :
232 3352 : if (mpTextObj)
233 2788 : pEditEngine->SetText(*mpTextObj);
234 :
235 3352 : bDataValid = true;
236 3352 : return pForwarder;
237 : }
238 :
239 9276 : void ScHeaderFooterTextData::UpdateData()
240 : {
241 9276 : if (pEditEngine)
242 : {
243 9276 : delete mpTextObj;
244 9276 : mpTextObj = pEditEngine->CreateTextObject();
245 : }
246 9276 : }
247 :
248 7730 : void ScHeaderFooterTextData::UpdateData(EditEngine& rEditEngine)
249 : {
250 7730 : delete mpTextObj;
251 7730 : mpTextObj = rEditEngine.CreateTextObject();
252 7730 : bDataValid = false;
253 7730 : }
254 :
255 10650 : ScHeaderFooterTextObj::ScHeaderFooterTextObj(
256 : ScHeaderFooterContentObj& rContent, sal_uInt16 nP, const EditTextObject* pTextObj) :
257 10650 : aTextData(rContent, nP, pTextObj)
258 : {
259 : // ScHeaderFooterTextData acquires rContent
260 : // pUnoText is created on demand (getString/setString work without it)
261 10650 : }
262 :
263 3342 : void ScHeaderFooterTextObj::CreateUnoText_Impl()
264 : {
265 3342 : if (!mxUnoText.is())
266 : {
267 : // can't be aggregated because getString/setString is handled here
268 3342 : ScHeaderFooterEditSource aEditSrc(aTextData);
269 3342 : mxUnoText.set(new SvxUnoText(&aEditSrc, lcl_GetHdFtPropertySet(), uno::Reference<text::XText>()));
270 : }
271 3342 : }
272 :
273 21300 : ScHeaderFooterTextObj::~ScHeaderFooterTextObj() {}
274 :
275 9426 : const EditTextObject* ScHeaderFooterTextObj::GetTextObject() const
276 : {
277 9426 : return aTextData.GetTextObject();
278 : }
279 :
280 2278 : const SvxUnoText& ScHeaderFooterTextObj::GetUnoText()
281 : {
282 2278 : if (!mxUnoText.is())
283 1876 : CreateUnoText_Impl();
284 2278 : return *mxUnoText;
285 : }
286 :
287 : // XText
288 :
289 2278 : uno::Reference<text::XTextCursor> SAL_CALL ScHeaderFooterTextObj::createTextCursor()
290 : throw(uno::RuntimeException, std::exception)
291 : {
292 2278 : SolarMutexGuard aGuard;
293 2278 : return new ScHeaderFooterTextCursor( *this );
294 : }
295 :
296 1486 : uno::Reference<text::XTextCursor> SAL_CALL ScHeaderFooterTextObj::createTextCursorByRange(
297 : const uno::Reference<text::XTextRange>& aTextPosition )
298 : throw(uno::RuntimeException, std::exception)
299 : {
300 1486 : SolarMutexGuard aGuard;
301 1486 : if (!mxUnoText.is())
302 0 : CreateUnoText_Impl();
303 1486 : return mxUnoText->createTextCursorByRange(aTextPosition);
304 : //! wie ScCellObj::createTextCursorByRange, wenn SvxUnoTextRange_getReflection verfuegbar
305 : }
306 :
307 4428 : void ScHeaderFooterTextObj::FillDummyFieldData( ScHeaderFieldData& rData )
308 : {
309 4428 : OUString aDummy("???");
310 4428 : rData.aTitle = aDummy;
311 4428 : rData.aLongDocName = aDummy;
312 4428 : rData.aShortDocName = aDummy;
313 4428 : rData.aTabName = aDummy;
314 4428 : rData.nPageNo = 1;
315 4428 : rData.nTotalPages = 99;
316 4428 : }
317 :
318 1254 : OUString SAL_CALL ScHeaderFooterTextObj::getString() throw(uno::RuntimeException, std::exception)
319 : {
320 1254 : SolarMutexGuard aGuard;
321 1254 : OUString aRet;
322 : const EditTextObject* pData;
323 :
324 1254 : sal_uInt16 nPart = aTextData.GetPart();
325 1254 : ScHeaderFooterContentObj& rContentObj = aTextData.GetContentObj();
326 :
327 1254 : if (nPart == SC_HDFT_LEFT)
328 414 : pData = rContentObj.GetLeftEditObject();
329 840 : else if (nPart == SC_HDFT_CENTER)
330 426 : pData = rContentObj.GetCenterEditObject();
331 : else
332 414 : pData = rContentObj.GetRightEditObject();
333 1254 : if (pData)
334 : {
335 : // for pure text, no font info is needed in pool defaults
336 1086 : ScHeaderEditEngine aEditEngine( EditEngine::CreatePool(), true );
337 :
338 2172 : ScHeaderFieldData aData;
339 1086 : FillDummyFieldData( aData );
340 1086 : aEditEngine.SetData( aData );
341 :
342 1086 : aEditEngine.SetText(*pData);
343 2172 : aRet = ScEditUtil::GetSpaceDelimitedString( aEditEngine );
344 : }
345 1254 : return aRet;
346 : }
347 :
348 7730 : void SAL_CALL ScHeaderFooterTextObj::setString( const OUString& aText ) throw(uno::RuntimeException, std::exception)
349 : {
350 7730 : SolarMutexGuard aGuard;
351 15460 : OUString aString(aText);
352 :
353 : // for pure text, no font info is needed in pool defaults
354 15460 : ScHeaderEditEngine aEditEngine(EditEngine::CreatePool(), true);
355 7730 : aEditEngine.SetText( aString );
356 15460 : aTextData.UpdateData(aEditEngine);
357 7730 : }
358 :
359 3186 : 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 3186 : SolarMutexGuard aGuard;
364 3186 : if (!mxUnoText.is())
365 0 : CreateUnoText_Impl();
366 3186 : mxUnoText->insertString( xRange, aString, bAbsorb );
367 3186 : }
368 :
369 1502 : 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 1502 : SolarMutexGuard aGuard;
375 1502 : if (!mxUnoText.is())
376 0 : CreateUnoText_Impl();
377 1502 : mxUnoText->insertControlCharacter( xRange, nControlCharacter, bAbsorb );
378 1502 : }
379 :
380 2328 : 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 2328 : SolarMutexGuard aGuard;
387 2328 : if ( xContent.is() && xRange.is() )
388 : {
389 2326 : ScEditFieldObj* pHeaderField = ScEditFieldObj::getImplementation( xContent );
390 :
391 : SvxUnoTextRangeBase* pTextRange =
392 2326 : ScHeaderFooterTextCursor::getImplementation( xRange );
393 :
394 2326 : if ( pHeaderField && !pHeaderField->IsInserted() && pTextRange )
395 : {
396 2326 : SvxEditSource* pEditSource = pTextRange->GetEditSource();
397 2326 : ESelection aSelection(pTextRange->GetSelection());
398 :
399 2326 : if (!bAbsorb)
400 : {
401 : // don't replace -> append at end
402 2326 : aSelection.Adjust();
403 2326 : aSelection.nStartPara = aSelection.nEndPara;
404 2326 : aSelection.nStartPos = aSelection.nEndPos;
405 : }
406 :
407 2326 : SvxFieldItem aItem(pHeaderField->CreateFieldItem());
408 :
409 2326 : SvxTextForwarder* pForwarder = pEditSource->GetTextForwarder();
410 2326 : pForwarder->QuickInsertField( aItem, aSelection );
411 2326 : pEditSource->UpdateData();
412 :
413 : // neue Selektion: ein Zeichen
414 2326 : aSelection.Adjust();
415 2326 : aSelection.nEndPara = aSelection.nStartPara;
416 2326 : aSelection.nEndPos = aSelection.nStartPos + 1;
417 :
418 4652 : uno::Reference<text::XTextRange> xTextRange;
419 2326 : switch (aTextData.GetPart())
420 : {
421 : case SC_HDFT_LEFT:
422 : {
423 : uno::Reference<text::XTextRange> xTemp(
424 544 : aTextData.GetContentObj().getLeftText(), uno::UNO_QUERY);
425 544 : xTextRange = xTemp;
426 : }
427 544 : break;
428 : case SC_HDFT_CENTER:
429 : {
430 : uno::Reference<text::XTextRange> xTemp(
431 1242 : aTextData.GetContentObj().getCenterText(), uno::UNO_QUERY);
432 1242 : xTextRange = xTemp;
433 : }
434 1242 : break;
435 : case SC_HDFT_RIGHT:
436 : {
437 : uno::Reference<text::XTextRange> xTemp(
438 540 : aTextData.GetContentObj().getRightText(), uno::UNO_QUERY);
439 540 : xTextRange = xTemp;
440 : }
441 540 : break;
442 : }
443 :
444 2326 : 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 2326 : if (!bAbsorb)
449 2326 : aSelection.nStartPos = aSelection.nEndPos;
450 :
451 2326 : pTextRange->SetSelection( aSelection );
452 :
453 6978 : return;
454 : }
455 : }
456 :
457 2 : if (!mxUnoText.is())
458 0 : CreateUnoText_Impl();
459 4 : mxUnoText->insertTextContent( xRange, xContent, bAbsorb );
460 : }
461 :
462 2 : void SAL_CALL ScHeaderFooterTextObj::removeTextContent(
463 : const uno::Reference<text::XTextContent>& xContent )
464 : throw(container::NoSuchElementException, uno::RuntimeException, std::exception)
465 : {
466 2 : SolarMutexGuard aGuard;
467 2 : if ( xContent.is() )
468 : {
469 2 : ScEditFieldObj* pHeaderField = ScEditFieldObj::getImplementation(xContent);
470 2 : if ( pHeaderField && pHeaderField->IsInserted() )
471 : {
472 : //! Testen, ob das Feld in dieser Zelle ist
473 2 : pHeaderField->DeleteField();
474 4 : return;
475 : }
476 : }
477 0 : if (!mxUnoText.is())
478 0 : CreateUnoText_Impl();
479 0 : mxUnoText->removeTextContent( xContent );
480 : }
481 :
482 10 : uno::Reference<text::XText> SAL_CALL ScHeaderFooterTextObj::getText() throw(uno::RuntimeException, std::exception)
483 : {
484 10 : SolarMutexGuard aGuard;
485 10 : if (!mxUnoText.is())
486 2 : CreateUnoText_Impl();
487 10 : return mxUnoText->getText();
488 : }
489 :
490 2 : uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextObj::getStart() throw(uno::RuntimeException, std::exception)
491 : {
492 2 : SolarMutexGuard aGuard;
493 2 : if (!mxUnoText.is())
494 0 : CreateUnoText_Impl();
495 2 : return mxUnoText->getStart();
496 : }
497 :
498 4 : uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextObj::getEnd() throw(uno::RuntimeException, std::exception)
499 : {
500 4 : SolarMutexGuard aGuard;
501 4 : if (!mxUnoText.is())
502 0 : CreateUnoText_Impl();
503 4 : return mxUnoText->getEnd();
504 : }
505 :
506 : // XTextFieldsSupplier
507 :
508 2 : uno::Reference<container::XEnumerationAccess> SAL_CALL ScHeaderFooterTextObj::getTextFields()
509 : throw(uno::RuntimeException, std::exception)
510 : {
511 2 : SolarMutexGuard aGuard;
512 : // all fields
513 2 : 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 1466 : uno::Reference<container::XEnumeration> SAL_CALL ScHeaderFooterTextObj::createEnumeration()
539 : throw(uno::RuntimeException, std::exception)
540 : {
541 1466 : SolarMutexGuard aGuard;
542 1466 : if (!mxUnoText.is())
543 1464 : CreateUnoText_Impl();
544 1466 : return mxUnoText->createEnumeration();
545 : }
546 :
547 : // XElementAccess
548 :
549 2 : uno::Type SAL_CALL ScHeaderFooterTextObj::getElementType() throw(uno::RuntimeException, std::exception)
550 : {
551 2 : SolarMutexGuard aGuard;
552 2 : if (!mxUnoText.is())
553 0 : CreateUnoText_Impl();
554 2 : return mxUnoText->getElementType();
555 : }
556 :
557 2 : sal_Bool SAL_CALL ScHeaderFooterTextObj::hasElements() throw(uno::RuntimeException, std::exception)
558 : {
559 2 : SolarMutexGuard aGuard;
560 2 : if (!mxUnoText.is())
561 0 : CreateUnoText_Impl();
562 2 : return mxUnoText->hasElements();
563 : }
564 :
565 6 : ScCellTextCursor::ScCellTextCursor(const ScCellTextCursor& rOther) :
566 : SvxUnoTextCursor( rOther ),
567 6 : rTextObj( rOther.rTextObj )
568 : {
569 6 : rTextObj.acquire();
570 6 : }
571 :
572 26 : ScCellTextCursor::ScCellTextCursor(ScCellObj& rText) :
573 26 : SvxUnoTextCursor( rText.GetUnoText() ),
574 26 : rTextObj( rText )
575 : {
576 26 : rTextObj.acquire();
577 26 : }
578 :
579 96 : ScCellTextCursor::~ScCellTextCursor() throw()
580 : {
581 32 : rTextObj.release();
582 64 : }
583 :
584 : // SvxUnoTextCursor methods reimplemented here to return the right objects:
585 :
586 4 : uno::Reference<text::XText> SAL_CALL ScCellTextCursor::getText() throw(uno::RuntimeException, std::exception)
587 : {
588 4 : SolarMutexGuard aGuard;
589 4 : return &rTextObj;
590 : }
591 :
592 4 : uno::Reference<text::XTextRange> SAL_CALL ScCellTextCursor::getStart() throw(uno::RuntimeException, std::exception)
593 : {
594 4 : SolarMutexGuard aGuard;
595 :
596 : //! use other object for range than cursor?
597 :
598 4 : ScCellTextCursor* pNew = new ScCellTextCursor( *this );
599 4 : uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
600 :
601 4 : ESelection aNewSel(GetSelection());
602 4 : aNewSel.nEndPara = aNewSel.nStartPara;
603 4 : aNewSel.nEndPos = aNewSel.nStartPos;
604 4 : pNew->SetSelection( aNewSel );
605 :
606 4 : return xRange;
607 : }
608 :
609 2 : uno::Reference<text::XTextRange> SAL_CALL ScCellTextCursor::getEnd() throw(uno::RuntimeException, std::exception)
610 : {
611 2 : SolarMutexGuard aGuard;
612 :
613 : //! use other object for range than cursor?
614 :
615 2 : ScCellTextCursor* pNew = new ScCellTextCursor( *this );
616 2 : uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
617 :
618 2 : ESelection aNewSel(GetSelection());
619 2 : aNewSel.nStartPara = aNewSel.nEndPara;
620 2 : aNewSel.nStartPos = aNewSel.nEndPos;
621 2 : pNew->SetSelection( aNewSel );
622 :
623 2 : return xRange;
624 : }
625 :
626 : // XUnoTunnel
627 :
628 24 : sal_Int64 SAL_CALL ScCellTextCursor::getSomething(
629 : const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException, std::exception)
630 : {
631 48 : if ( rId.getLength() == 16 &&
632 24 : 0 == memcmp( getUnoTunnelId().getConstArray(),
633 48 : rId.getConstArray(), 16 ) )
634 : {
635 12 : return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
636 : }
637 12 : return SvxUnoTextCursor::getSomething( rId );
638 : }
639 :
640 : namespace
641 : {
642 : class theScCellTextCursorUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theScCellTextCursorUnoTunnelId> {};
643 : }
644 :
645 530 : const uno::Sequence<sal_Int8>& ScCellTextCursor::getUnoTunnelId()
646 : {
647 530 : return theScCellTextCursorUnoTunnelId::get().getSeq();
648 : }
649 :
650 506 : ScCellTextCursor* ScCellTextCursor::getImplementation( const uno::Reference<uno::XInterface> xObj )
651 : {
652 506 : ScCellTextCursor* pRet = NULL;
653 506 : uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
654 506 : if (xUT.is())
655 506 : pRet = reinterpret_cast<ScCellTextCursor*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
656 506 : return pRet;
657 : }
658 :
659 3314 : ScHeaderFooterTextCursor::ScHeaderFooterTextCursor(const ScHeaderFooterTextCursor& rOther) :
660 : SvxUnoTextCursor( rOther ),
661 3314 : rTextObj( rOther.rTextObj )
662 : {
663 3314 : rTextObj.acquire();
664 3314 : }
665 :
666 2278 : ScHeaderFooterTextCursor::ScHeaderFooterTextCursor(ScHeaderFooterTextObj& rText) :
667 2278 : SvxUnoTextCursor( rText.GetUnoText() ),
668 2278 : rTextObj( rText )
669 : {
670 2278 : rTextObj.acquire();
671 2278 : }
672 :
673 16776 : ScHeaderFooterTextCursor::~ScHeaderFooterTextCursor() throw()
674 : {
675 5592 : rTextObj.release();
676 11184 : }
677 :
678 : // SvxUnoTextCursor methods reimplemented here to return the right objects:
679 :
680 1468 : uno::Reference<text::XText> SAL_CALL ScHeaderFooterTextCursor::getText() throw(uno::RuntimeException, std::exception)
681 : {
682 1468 : SolarMutexGuard aGuard;
683 1468 : return &rTextObj;
684 : }
685 :
686 3312 : uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextCursor::getStart() throw(uno::RuntimeException, std::exception)
687 : {
688 3312 : SolarMutexGuard aGuard;
689 :
690 : //! use other object for range than cursor?
691 :
692 3312 : ScHeaderFooterTextCursor* pNew = new ScHeaderFooterTextCursor( *this );
693 3312 : uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
694 :
695 3312 : ESelection aNewSel(GetSelection());
696 3312 : aNewSel.nEndPara = aNewSel.nStartPara;
697 3312 : aNewSel.nEndPos = aNewSel.nStartPos;
698 3312 : pNew->SetSelection( aNewSel );
699 :
700 3312 : return xRange;
701 : }
702 :
703 2 : uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextCursor::getEnd() throw(uno::RuntimeException, std::exception)
704 : {
705 2 : SolarMutexGuard aGuard;
706 :
707 : //! use other object for range than cursor?
708 :
709 2 : ScHeaderFooterTextCursor* pNew = new ScHeaderFooterTextCursor( *this );
710 2 : uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
711 :
712 2 : ESelection aNewSel(GetSelection());
713 2 : aNewSel.nStartPara = aNewSel.nEndPara;
714 2 : aNewSel.nStartPos = aNewSel.nEndPos;
715 2 : pNew->SetSelection( aNewSel );
716 :
717 2 : return xRange;
718 : }
719 :
720 : // XUnoTunnel
721 :
722 10542 : sal_Int64 SAL_CALL ScHeaderFooterTextCursor::getSomething(
723 : const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException, std::exception)
724 : {
725 21084 : if ( rId.getLength() == 16 &&
726 10542 : 0 == memcmp( getUnoTunnelId().getConstArray(),
727 21084 : rId.getConstArray(), 16 ) )
728 : {
729 2326 : return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
730 : }
731 8216 : return SvxUnoTextCursor::getSomething( rId );
732 : }
733 :
734 : namespace
735 : {
736 : class theScHeaderFooterTextCursorUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theScHeaderFooterTextCursorUnoTunnelId> {};
737 : }
738 :
739 12868 : const uno::Sequence<sal_Int8>& ScHeaderFooterTextCursor::getUnoTunnelId()
740 : {
741 12868 : return theScHeaderFooterTextCursorUnoTunnelId::get().getSeq();
742 : }
743 :
744 2326 : ScHeaderFooterTextCursor* ScHeaderFooterTextCursor::getImplementation(
745 : const uno::Reference<uno::XInterface> xObj )
746 : {
747 2326 : ScHeaderFooterTextCursor* pRet = NULL;
748 2326 : uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
749 2326 : if (xUT.is())
750 2326 : pRet = reinterpret_cast<ScHeaderFooterTextCursor*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
751 2326 : return pRet;
752 : }
753 :
754 256 : ScDrawTextCursor::ScDrawTextCursor(const ScDrawTextCursor& rOther) :
755 : SvxUnoTextCursor( rOther ),
756 256 : xParentText( rOther.xParentText )
757 : {
758 256 : }
759 :
760 140 : ScDrawTextCursor::ScDrawTextCursor( const uno::Reference<text::XText>& xParent,
761 : const SvxUnoTextBase& rText ) :
762 : SvxUnoTextCursor( rText ),
763 140 : xParentText( xParent )
764 :
765 : {
766 140 : }
767 :
768 792 : ScDrawTextCursor::~ScDrawTextCursor() throw()
769 : {
770 792 : }
771 :
772 : // SvxUnoTextCursor methods reimplemented here to return the right objects:
773 :
774 54 : uno::Reference<text::XText> SAL_CALL ScDrawTextCursor::getText() throw(uno::RuntimeException, std::exception)
775 : {
776 54 : SolarMutexGuard aGuard;
777 54 : return xParentText;
778 : }
779 :
780 256 : uno::Reference<text::XTextRange> SAL_CALL ScDrawTextCursor::getStart() throw(uno::RuntimeException, std::exception)
781 : {
782 256 : SolarMutexGuard aGuard;
783 :
784 : //! use other object for range than cursor?
785 :
786 256 : ScDrawTextCursor* pNew = new ScDrawTextCursor( *this );
787 256 : uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
788 :
789 256 : ESelection aNewSel(GetSelection());
790 256 : aNewSel.nEndPara = aNewSel.nStartPara;
791 256 : aNewSel.nEndPos = aNewSel.nStartPos;
792 256 : pNew->SetSelection( aNewSel );
793 :
794 256 : 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 534 : sal_Int64 SAL_CALL ScDrawTextCursor::getSomething(
817 : const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException, std::exception)
818 : {
819 1068 : if ( rId.getLength() == 16 &&
820 534 : 0 == memcmp( getUnoTunnelId().getConstArray(),
821 1068 : rId.getConstArray(), 16 ) )
822 : {
823 34 : return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
824 : }
825 500 : return SvxUnoTextCursor::getSomething( rId );
826 : }
827 :
828 : namespace
829 : {
830 : class theScDrawTextCursorUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theScDrawTextCursorUnoTunnelId> {};
831 : }
832 :
833 968 : const uno::Sequence<sal_Int8>& ScDrawTextCursor::getUnoTunnelId()
834 : {
835 968 : return theScDrawTextCursorUnoTunnelId::get().getSeq();
836 : }
837 :
838 434 : ScDrawTextCursor* ScDrawTextCursor::getImplementation( const uno::Reference<uno::XInterface> xObj )
839 : {
840 434 : ScDrawTextCursor* pRet = NULL;
841 434 : uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
842 434 : if (xUT.is())
843 434 : pRet = reinterpret_cast<ScDrawTextCursor*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
844 434 : 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 166 : 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 166 : bDoUpdate( true )
900 : {
901 166 : if (pDocShell)
902 166 : pDocShell->GetDocument().AddUnoObject(*this);
903 166 : }
904 :
905 402 : ScCellTextData::~ScCellTextData()
906 : {
907 150 : SolarMutexGuard aGuard; // needed for EditEngine dtor
908 :
909 150 : if (pDocShell)
910 : {
911 39 : pDocShell->GetDocument().RemoveUnoObject(*this);
912 39 : pDocShell->GetDocument().DisposeFieldEditEngine(pEditEngine);
913 : }
914 : else
915 111 : delete pEditEngine;
916 :
917 150 : delete pForwarder;
918 :
919 150 : delete pOriginalSource;
920 252 : }
921 :
922 20 : ScCellEditSource* ScCellTextData::GetOriginalSource()
923 : {
924 20 : if (!pOriginalSource)
925 20 : pOriginalSource = new ScCellEditSource(pDocShell, aCellPos);
926 20 : return pOriginalSource;
927 : }
928 :
929 92 : void ScCellTextData::GetCellText(const ScAddress& rCellPos, OUString& rText)
930 : {
931 92 : if (pDocShell)
932 : {
933 92 : ScDocument& rDoc = pDocShell->GetDocument();
934 92 : rDoc.GetInputString( rCellPos.Col(), rCellPos.Row(), rCellPos.Tab(), rText );
935 : }
936 92 : }
937 :
938 3880 : SvxTextForwarder* ScCellTextData::GetTextForwarder()
939 : {
940 3880 : if (!pEditEngine)
941 : {
942 94 : if ( pDocShell )
943 : {
944 94 : ScDocument& rDoc = pDocShell->GetDocument();
945 94 : 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 94 : pEditEngine->EnableUndo( false );
957 94 : if (pDocShell)
958 94 : pEditEngine->SetRefDevice(pDocShell->GetRefDevice());
959 : else
960 0 : pEditEngine->SetRefMapMode( MAP_100TH_MM );
961 94 : pForwarder = new SvxEditEngineForwarder(*pEditEngine);
962 : }
963 :
964 3880 : if (bDataValid)
965 3758 : return pForwarder;
966 :
967 122 : OUString aText;
968 :
969 122 : if (pDocShell)
970 : {
971 122 : ScDocument& rDoc = pDocShell->GetDocument();
972 :
973 122 : SfxItemSet aDefaults( pEditEngine->GetEmptyItemSet() );
974 122 : if( const ScPatternAttr* pPattern =
975 122 : rDoc.GetPattern( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab() ) )
976 : {
977 122 : pPattern->FillEditItemSet( &aDefaults );
978 122 : pPattern->FillEditParaItems( &aDefaults ); // including alignment etc. (for reading)
979 : }
980 :
981 122 : if (rDoc.GetCellType(aCellPos) == CELLTYPE_EDIT)
982 : {
983 20 : const EditTextObject* pObj = rDoc.GetEditText(aCellPos);
984 20 : if (pObj)
985 20 : pEditEngine->SetTextNewDefaults(*pObj, aDefaults);
986 : }
987 : else
988 : {
989 102 : GetCellText(aCellPos, aText);
990 102 : if (!aText.isEmpty())
991 60 : pEditEngine->SetTextNewDefaults(aText, aDefaults);
992 : else
993 42 : pEditEngine->SetDefaults(aDefaults);
994 122 : }
995 : }
996 :
997 122 : bDataValid = true;
998 122 : return pForwarder;
999 : }
1000 :
1001 434 : void ScCellTextData::UpdateData()
1002 : {
1003 434 : if ( bDoUpdate )
1004 : {
1005 : OSL_ENSURE(pEditEngine != NULL, "no EditEngine for UpdateData()");
1006 434 : 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 434 : bInUpdate = true; // prevents bDataValid from being reset
1012 434 : pDocShell->GetDocFunc().PutData(aCellPos, *pEditEngine, true); // always as text
1013 :
1014 434 : bInUpdate = false;
1015 434 : bDirty = false;
1016 : }
1017 : }
1018 : else
1019 0 : bDirty = true;
1020 434 : }
1021 :
1022 4667 : void ScCellTextData::Notify( SfxBroadcaster&, const SfxHint& rHint )
1023 : {
1024 4667 : if ( dynamic_cast<const ScUpdateRefHint*>(&rHint) )
1025 : {
1026 : // const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
1027 :
1028 : //! Ref-Update
1029 : }
1030 4667 : else if ( dynamic_cast<const SfxSimpleHint*>(&rHint) )
1031 : {
1032 4667 : sal_uLong nId = static_cast<const SfxSimpleHint&>(rHint).GetId();
1033 4667 : if ( nId == SFX_HINT_DYING )
1034 : {
1035 127 : pDocShell = NULL; // invalid now
1036 :
1037 127 : DELETEZ( pForwarder );
1038 127 : DELETEZ( pEditEngine ); // EditEngine uses document's pool
1039 : }
1040 4540 : else if ( nId == SFX_HINT_DATACHANGED )
1041 : {
1042 4540 : if (!bInUpdate) // not for own UpdateData calls
1043 3880 : bDataValid = false; // text has to be read from the cell again
1044 : }
1045 : }
1046 4667 : }
1047 :
1048 20 : ScCellTextObj::ScCellTextObj(ScDocShell* pDocSh, const ScAddress& rP) :
1049 : ScCellTextData( pDocSh, rP ),
1050 20 : SvxUnoText( GetOriginalSource(), ScCellObj::GetEditPropertySet(), uno::Reference<text::XText>() )
1051 : {
1052 20 : }
1053 :
1054 40 : ScCellTextObj::~ScCellTextObj() throw()
1055 : {
1056 268 : }
1057 :
1058 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|