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