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