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