xref: /trunk/main/sc/source/ui/unoobj/fielduno.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sc.hxx"
30 #include <svl/smplhint.hxx>
31 
32 
33 #include <editeng/eeitem.hxx>
34 
35 #include <editeng/editeng.hxx>
36 #include <editeng/editobj.hxx>
37 #include <editeng/flditem.hxx>
38 #include <rtl/uuid.h>
39 
40 #include <com/sun/star/beans/PropertyAttribute.hpp>
41 #include <com/sun/star/text/TextContentAnchorType.hpp>
42 #include <com/sun/star/text/WrapTextMode.hpp>
43 #include <com/sun/star/text/FilenameDisplayFormat.hpp>
44 
45 #include "fielduno.hxx"
46 #include "textuno.hxx"
47 #include "miscuno.hxx"
48 #include "docsh.hxx"
49 #include "hints.hxx"
50 #include "editsrc.hxx"
51 #include "cellsuno.hxx"
52 #include "servuno.hxx"      // fuer IDs
53 #include "unoguard.hxx"
54 #include "unonames.hxx"
55 #include "editutil.hxx"
56 
57 using namespace com::sun::star;
58 
59 //------------------------------------------------------------------------
60 
61 //  alles ohne Which-ID, Map nur fuer PropertySetInfo
62 
63 const SfxItemPropertySet* lcl_GetURLPropertySet()
64 {
65     static SfxItemPropertyMapEntry aURLPropertyMap_Impl[] =
66     {
67         {MAP_CHAR_LEN(SC_UNONAME_ANCTYPE),  0,  &getCppuType((text::TextContentAnchorType*)0), beans::PropertyAttribute::READONLY, 0 },
68         {MAP_CHAR_LEN(SC_UNONAME_ANCTYPES), 0,  &getCppuType((uno::Sequence<text::TextContentAnchorType>*)0), beans::PropertyAttribute::READONLY, 0 },
69         {MAP_CHAR_LEN(SC_UNONAME_REPR),     0,  &getCppuType((rtl::OUString*)0),    0, 0},
70         {MAP_CHAR_LEN(SC_UNONAME_TARGET),   0,  &getCppuType((rtl::OUString*)0),    0, 0},
71         {MAP_CHAR_LEN(SC_UNONAME_TEXTWRAP), 0,  &getCppuType((text::WrapTextMode*)0), beans::PropertyAttribute::READONLY, 0 },
72         {MAP_CHAR_LEN(SC_UNONAME_URL),      0,  &getCppuType((rtl::OUString*)0),    0, 0},
73         {0,0,0,0,0,0}
74     };
75     static SfxItemPropertySet aURLPropertySet_Impl( aURLPropertyMap_Impl );
76     return &aURLPropertySet_Impl;
77 }
78 
79 const SfxItemPropertySet* lcl_GetHeaderFieldPropertySet()
80 {
81     static SfxItemPropertyMapEntry aHeaderFieldPropertyMap_Impl[] =
82     {
83         {MAP_CHAR_LEN(SC_UNONAME_ANCTYPE),  0,  &getCppuType((text::TextContentAnchorType*)0), beans::PropertyAttribute::READONLY, 0 },
84         {MAP_CHAR_LEN(SC_UNONAME_ANCTYPES), 0,  &getCppuType((uno::Sequence<text::TextContentAnchorType>*)0), beans::PropertyAttribute::READONLY, 0 },
85         {MAP_CHAR_LEN(SC_UNONAME_TEXTWRAP), 0,  &getCppuType((text::WrapTextMode*)0), beans::PropertyAttribute::READONLY, 0 },
86         {0,0,0,0,0,0}
87     };
88     static SfxItemPropertySet aHeaderFieldPropertySet_Impl( aHeaderFieldPropertyMap_Impl );
89     return &aHeaderFieldPropertySet_Impl;
90 }
91 
92 const SfxItemPropertySet* lcl_GetFileFieldPropertySet()
93 {
94     static SfxItemPropertyMapEntry aFileFieldPropertyMap_Impl[] =
95     {
96         {MAP_CHAR_LEN(SC_UNONAME_ANCTYPE),  0,  &getCppuType((text::TextContentAnchorType*)0), beans::PropertyAttribute::READONLY, 0 },
97         {MAP_CHAR_LEN(SC_UNONAME_ANCTYPES), 0,  &getCppuType((uno::Sequence<text::TextContentAnchorType>*)0), beans::PropertyAttribute::READONLY, 0 },
98         {MAP_CHAR_LEN(SC_UNONAME_FILEFORM), 0,  &getCppuType((sal_Int16*)0),        0, 0 },
99         {MAP_CHAR_LEN(SC_UNONAME_TEXTWRAP), 0,  &getCppuType((text::WrapTextMode*)0), beans::PropertyAttribute::READONLY, 0 },
100         {0,0,0,0,0,0}
101     };
102     static SfxItemPropertySet aFileFieldPropertySet_Impl( aFileFieldPropertyMap_Impl );
103     return &aFileFieldPropertySet_Impl;
104 }
105 
106 //------------------------------------------------------------------------
107 
108 #define SCTEXTFIELD_SERVICE         "com.sun.star.text.TextField"
109 #define SCTEXTCONTENT_SERVICE       "com.sun.star.text.TextContent"
110 
111 SC_SIMPLE_SERVICE_INFO( ScCellFieldsObj, "ScCellFieldsObj", "com.sun.star.text.TextFields" )
112 SC_SIMPLE_SERVICE_INFO( ScHeaderFieldsObj, "ScHeaderFieldsObj", "com.sun.star.text.TextFields" )
113 
114 //------------------------------------------------------------------------
115 
116 //  ScUnoEditEngine nur um aus einer EditEngine die Felder herauszubekommen...
117 
118 enum ScUnoCollectMode
119 {
120     SC_UNO_COLLECT_NONE,
121     SC_UNO_COLLECT_COUNT,
122     SC_UNO_COLLECT_FINDINDEX,
123     SC_UNO_COLLECT_FINDPOS
124 };
125 
126 class ScUnoEditEngine : public ScEditEngineDefaulter
127 {
128     ScUnoCollectMode    eMode;
129     sal_uInt16              nFieldCount;
130     TypeId              aFieldType;
131     SvxFieldData*       pFound;         // lokale Kopie
132     sal_uInt16              nFieldPar;
133     xub_StrLen          nFieldPos;
134     sal_uInt16              nFieldIndex;
135 
136 public:
137                 ScUnoEditEngine(ScEditEngineDefaulter* pSource);
138                 ~ScUnoEditEngine();
139 
140                     //! nPos should be xub_StrLen
141     virtual String  CalcFieldValue( const SvxFieldItem& rField, sal_uInt16 nPara, sal_uInt16 nPos,
142                                     Color*& rTxtColor, Color*& rFldColor );
143 
144     sal_uInt16          CountFields(TypeId aType);
145     SvxFieldData*   FindByIndex(sal_uInt16 nIndex, TypeId aType);
146     SvxFieldData*   FindByPos(sal_uInt16 nPar, xub_StrLen nPos, TypeId aType);
147 
148     sal_uInt16          GetFieldPar() const     { return nFieldPar; }
149     xub_StrLen      GetFieldPos() const     { return nFieldPos; }
150 };
151 
152 ScUnoEditEngine::ScUnoEditEngine(ScEditEngineDefaulter* pSource) :
153     ScEditEngineDefaulter( *pSource ),
154     eMode( SC_UNO_COLLECT_NONE ),
155     nFieldCount( 0 ),
156     aFieldType( NULL ),
157     pFound( NULL )
158 {
159     if (pSource)
160     {
161         EditTextObject* pData = pSource->CreateTextObject();
162         SetText( *pData );
163         delete pData;
164     }
165 }
166 
167 ScUnoEditEngine::~ScUnoEditEngine()
168 {
169     delete pFound;
170 }
171 
172 String ScUnoEditEngine::CalcFieldValue( const SvxFieldItem& rField,
173             sal_uInt16 nPara, sal_uInt16 nPos, Color*& rTxtColor, Color*& rFldColor )
174 {
175     String aRet(EditEngine::CalcFieldValue( rField, nPara, nPos, rTxtColor, rFldColor ));
176     if (eMode != SC_UNO_COLLECT_NONE)
177     {
178         const SvxFieldData* pFieldData = rField.GetField();
179         if ( pFieldData )
180         {
181             if ( !aFieldType || pFieldData->Type() == aFieldType )
182             {
183                 if ( eMode == SC_UNO_COLLECT_FINDINDEX && !pFound && nFieldCount == nFieldIndex )
184                 {
185                     pFound = pFieldData->Clone();
186                     nFieldPar = nPara;
187                     nFieldPos = nPos;
188                 }
189                 if ( eMode == SC_UNO_COLLECT_FINDPOS && !pFound &&
190                         nPara == nFieldPar && nPos == nFieldPos )
191                 {
192                     pFound = pFieldData->Clone();
193                     nFieldIndex = nFieldCount;
194                 }
195                 ++nFieldCount;
196             }
197         }
198     }
199     return aRet;
200 }
201 
202 sal_uInt16 ScUnoEditEngine::CountFields(TypeId aType)
203 {
204     eMode = SC_UNO_COLLECT_COUNT;
205     aFieldType = aType;
206     nFieldCount = 0;
207     UpdateFields();
208     aFieldType = NULL;
209     eMode = SC_UNO_COLLECT_NONE;
210 
211     return nFieldCount;
212 }
213 
214 SvxFieldData* ScUnoEditEngine::FindByIndex(sal_uInt16 nIndex, TypeId aType)
215 {
216     eMode = SC_UNO_COLLECT_FINDINDEX;
217     nFieldIndex = nIndex;
218     aFieldType = aType;
219     nFieldCount = 0;
220     UpdateFields();
221     aFieldType = NULL;
222     eMode = SC_UNO_COLLECT_NONE;
223 
224     return pFound;
225 }
226 
227 SvxFieldData* ScUnoEditEngine::FindByPos(sal_uInt16 nPar, xub_StrLen nPos, TypeId aType)
228 {
229     eMode = SC_UNO_COLLECT_FINDPOS;
230     nFieldPar = nPar;
231     nFieldPos = nPos;
232     aFieldType = aType;
233     nFieldCount = 0;
234     UpdateFields();
235     aFieldType = NULL;
236     eMode = SC_UNO_COLLECT_NONE;
237 
238     return pFound;
239 }
240 
241 //------------------------------------------------------------------------
242 
243 ScCellFieldsObj::ScCellFieldsObj(ScDocShell* pDocSh, const ScAddress& rPos) :
244     pDocShell( pDocSh ),
245     aCellPos( rPos ),
246     mpRefreshListeners( NULL )
247 {
248     pDocShell->GetDocument()->AddUnoObject(*this);
249 
250     pEditSource = new ScCellEditSource( pDocShell, aCellPos );
251 }
252 
253 ScCellFieldsObj::~ScCellFieldsObj()
254 {
255     if (pDocShell)
256         pDocShell->GetDocument()->RemoveUnoObject(*this);
257 
258     delete pEditSource;
259 
260     // increment refcount to prevent double call off dtor
261     osl_incrementInterlockedCount( &m_refCount );
262 
263     if (mpRefreshListeners)
264     {
265         lang::EventObject aEvent;
266         aEvent.Source.set(static_cast<cppu::OWeakObject*>(this));
267         if (mpRefreshListeners)
268         {
269             mpRefreshListeners->disposeAndClear(aEvent);
270             DELETEZ( mpRefreshListeners );
271         }
272     }
273 }
274 
275 void ScCellFieldsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
276 {
277     if ( rHint.ISA( ScUpdateRefHint ) )
278     {
279 //        const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
280 
281         //! Ref-Update
282     }
283     else if ( rHint.ISA( SfxSimpleHint ) &&
284             ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
285     {
286         pDocShell = NULL;       // ungueltig geworden
287     }
288 
289     //  EditSource hat sich selber als Listener angemeldet
290 }
291 
292 // XIndexAccess (via XTextFields)
293 
294 ScCellFieldObj* ScCellFieldsObj::GetObjectByIndex_Impl(sal_Int32 Index) const
295 {
296     //! Feld-Funktionen muessen an den Forwarder !!!
297     ScEditEngineDefaulter* pEditEngine = ((ScCellEditSource*)pEditSource)->GetEditEngine();
298     ScUnoEditEngine aTempEngine(pEditEngine);
299 
300     if ( aTempEngine.FindByIndex( (sal_uInt16)Index, NULL ) )   // in der Zelle ist der Typ egal
301     {
302         sal_uInt16 nPar = aTempEngine.GetFieldPar();
303         xub_StrLen nPos = aTempEngine.GetFieldPos();
304         ESelection aSelection( nPar, nPos, nPar, nPos+1 );      // Feld ist 1 Zeichen
305         return new ScCellFieldObj( pDocShell, aCellPos, aSelection );
306     }
307     return NULL;
308 }
309 
310 sal_Int32 SAL_CALL ScCellFieldsObj::getCount() throw(uno::RuntimeException)
311 {
312     ScUnoGuard aGuard;
313 
314     //! Feld-Funktionen muessen an den Forwarder !!!
315     ScEditEngineDefaulter* pEditEngine = ((ScCellEditSource*)pEditSource)->GetEditEngine();
316     ScUnoEditEngine aTempEngine(pEditEngine);
317 
318     return aTempEngine.CountFields(NULL);       // Felder zaehlen, in Zelle ist der Typ egal
319 }
320 
321 uno::Any SAL_CALL ScCellFieldsObj::getByIndex( sal_Int32 nIndex )
322                             throw(lang::IndexOutOfBoundsException,
323                                     lang::WrappedTargetException, uno::RuntimeException)
324 {
325     ScUnoGuard aGuard;
326     uno::Reference<text::XTextField> xField(GetObjectByIndex_Impl(nIndex));
327     if (xField.is())
328         return uno::makeAny(xField);
329     else
330         throw lang::IndexOutOfBoundsException();
331 //    return uno::Any();
332 }
333 
334 uno::Type SAL_CALL ScCellFieldsObj::getElementType() throw(uno::RuntimeException)
335 {
336     ScUnoGuard aGuard;
337     return getCppuType((uno::Reference<text::XTextField>*)0);
338 }
339 
340 sal_Bool SAL_CALL ScCellFieldsObj::hasElements() throw(uno::RuntimeException)
341 {
342     ScUnoGuard aGuard;
343     return ( getCount() != 0 );
344 }
345 
346 uno::Reference<container::XEnumeration> SAL_CALL ScCellFieldsObj::createEnumeration()
347                                                     throw(uno::RuntimeException)
348 {
349     ScUnoGuard aGuard;
350     return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.TextFieldEnumeration")));
351 }
352 
353 void SAL_CALL ScCellFieldsObj::addContainerListener(
354                                 const uno::Reference<container::XContainerListener>& /* xListener */ )
355                                     throw(uno::RuntimeException)
356 {
357     DBG_ERROR("not implemented");
358 }
359 
360 void SAL_CALL ScCellFieldsObj::removeContainerListener(
361                                 const uno::Reference<container::XContainerListener>& /* xListener */ )
362                                     throw(uno::RuntimeException)
363 {
364     DBG_ERROR("not implemented");
365 }
366 
367 // XRefreshable
368 void SAL_CALL ScCellFieldsObj::refresh(  )
369                                     throw (uno::RuntimeException)
370 {
371     if (mpRefreshListeners)
372     {
373         //  Call all listeners.
374         uno::Sequence< uno::Reference< uno::XInterface > > aListeners(mpRefreshListeners->getElements());
375         sal_uInt32 nLength(aListeners.getLength());
376         if (nLength)
377         {
378             const uno::Reference< uno::XInterface >* pInterfaces = aListeners.getConstArray();
379             if (pInterfaces)
380             {
381                 lang::EventObject aEvent;
382                 aEvent.Source.set(uno::Reference< util::XRefreshable >(const_cast<ScCellFieldsObj*>(this)));
383                 sal_uInt32 i(0);
384                 while (i < nLength)
385                 {
386                     try
387                     {
388                         while(i < nLength)
389                         {
390                             static_cast< util::XRefreshListener* >(pInterfaces->get())->refreshed(aEvent);
391                             ++pInterfaces;
392                             ++i;
393                         }
394                     }
395                     catch(uno::RuntimeException&)
396                     {
397 //                      DBG_ERROR("a object is gone without to remove from Broadcaster");
398                         ++pInterfaces;
399                         ++i;
400                     }
401                 }
402             }
403         }
404     }
405 }
406 
407 void SAL_CALL ScCellFieldsObj::addRefreshListener( const uno::Reference< util::XRefreshListener >& xListener )
408                                     throw (uno::RuntimeException)
409 {
410     if (xListener.is())
411     {
412         ScUnoGuard aGuard;
413         if (!mpRefreshListeners)
414             mpRefreshListeners = new cppu::OInterfaceContainerHelper(aMutex);
415         mpRefreshListeners->addInterface(xListener);
416     }
417 }
418 
419 void SAL_CALL ScCellFieldsObj::removeRefreshListener( const uno::Reference<util::XRefreshListener >& xListener )
420                                     throw (uno::RuntimeException)
421 {
422     if (xListener.is())
423     {
424         ScUnoGuard aGuard;
425         if (mpRefreshListeners)
426             mpRefreshListeners->removeInterface(xListener);
427     }
428 }
429 
430 //------------------------------------------------------------------------
431 
432 //  Default-ctor wird fuer SMART_REFLECTION_IMPLEMENTATION gebraucht
433 
434 
435 //UNUSED2008-05  ScCellFieldObj::ScCellFieldObj() :
436 //UNUSED2008-05      OComponentHelper( getMutex() ),
437 //UNUSED2008-05      aPropSet( lcl_GetURLPropertyMap() ),
438 //UNUSED2008-05      pDocShell( NULL )
439 //UNUSED2008-05  {
440 //UNUSED2008-05      pEditSource = NULL;
441 //UNUSED2008-05  }
442 
443 ScCellFieldObj::ScCellFieldObj(ScDocShell* pDocSh, const ScAddress& rPos,
444                                             const ESelection& rSel) :
445     OComponentHelper( getMutex() ),
446     pPropSet( lcl_GetURLPropertySet() ),
447     pDocShell( pDocSh ),
448     aCellPos( rPos ),
449     aSelection( rSel )
450 {
451     //  pDocShell ist Null, wenn per ServiceProvider erzeugt
452 
453     if (pDocShell)
454     {
455         pDocShell->GetDocument()->AddUnoObject(*this);
456         pEditSource = new ScCellEditSource( pDocShell, aCellPos );
457     }
458     else
459         pEditSource = NULL;
460 }
461 
462 uno::Any SAL_CALL ScCellFieldObj::queryAggregation( const uno::Type& rType )
463                                                 throw(uno::RuntimeException)
464 {
465     SC_QUERYINTERFACE( text::XTextField )
466     SC_QUERYINTERFACE( text::XTextContent )         // parent of XTextField
467     SC_QUERYINTERFACE( beans::XPropertySet )
468     SC_QUERYINTERFACE( lang::XUnoTunnel )
469     SC_QUERYINTERFACE( lang::XServiceInfo )
470 
471     return OComponentHelper::queryAggregation( rType );     // XComponent
472 }
473 
474 uno::Sequence<uno::Type> SAL_CALL ScCellFieldObj::getTypes() throw(uno::RuntimeException)
475 {
476     static uno::Sequence<uno::Type> aTypes;
477     if ( aTypes.getLength() == 0 )
478     {
479         uno::Sequence<uno::Type> aParentTypes(OComponentHelper::getTypes());
480         long nParentLen = aParentTypes.getLength();
481         const uno::Type* pParentPtr = aParentTypes.getConstArray();
482 
483         aTypes.realloc( nParentLen + 4 );
484         uno::Type* pPtr = aTypes.getArray();
485         pPtr[nParentLen + 0] = getCppuType((const uno::Reference<text::XTextField>*)0);
486         pPtr[nParentLen + 1] = getCppuType((const uno::Reference<beans::XPropertySet>*)0);
487         pPtr[nParentLen + 2] = getCppuType((const uno::Reference<lang::XUnoTunnel>*)0);
488         pPtr[nParentLen + 3] = getCppuType((const uno::Reference<lang::XServiceInfo>*)0);
489 
490         for (long i=0; i<nParentLen; i++)
491             pPtr[i] = pParentPtr[i];                // parent types first
492     }
493     return aTypes;
494 }
495 
496 uno::Sequence<sal_Int8> SAL_CALL ScCellFieldObj::getImplementationId()
497                                                     throw(uno::RuntimeException)
498 {
499     static uno::Sequence< sal_Int8 > aId;
500     if( aId.getLength() == 0 )
501     {
502         aId.realloc( 16 );
503         rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
504     }
505     return aId;
506 }
507 
508 uno::Any SAL_CALL ScCellFieldObj::queryInterface( const uno::Type& rType )
509                                                 throw(uno::RuntimeException)
510 {
511     return OComponentHelper::queryInterface( rType );
512 }
513 
514 void SAL_CALL ScCellFieldObj::acquire() throw()
515 {
516     OComponentHelper::acquire();
517 }
518 
519 void SAL_CALL ScCellFieldObj::release() throw()
520 {
521     OComponentHelper::release();
522 }
523 
524 void ScCellFieldObj::InitDoc( ScDocShell* pDocSh, const ScAddress& rPos,
525                                         const ESelection& rSel )
526 {
527     if ( pDocSh && !pEditSource )
528     {
529         aCellPos = rPos;
530         aSelection = rSel;
531         pDocShell = pDocSh;
532 
533         pDocShell->GetDocument()->AddUnoObject(*this);
534         pEditSource = new ScCellEditSource( pDocShell, aCellPos );
535     }
536 }
537 
538 ScCellFieldObj::~ScCellFieldObj()
539 {
540     if (pDocShell)
541         pDocShell->GetDocument()->RemoveUnoObject(*this);
542 
543     delete pEditSource;
544 }
545 
546 void ScCellFieldObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
547 {
548     //! Updates fuer aSelection (muessen erst noch erzeugt werden) !!!!!!
549 
550     if ( rHint.ISA( ScUpdateRefHint ) )
551     {
552 //        const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
553 
554         //! Ref-Update
555     }
556     else if ( rHint.ISA( SfxSimpleHint ) &&
557             ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
558     {
559         pDocShell = NULL;       // ungueltig geworden
560     }
561 
562     //  EditSource hat sich selber als Listener angemeldet
563 }
564 
565 // per getImplementation gerufen:
566 
567 SvxFieldItem ScCellFieldObj::CreateFieldItem()
568 {
569     DBG_ASSERT( !pEditSource, "CreateFieldItem mit eingefuegtem Feld" );
570 
571     SvxURLField aField;
572     aField.SetFormat(SVXURLFORMAT_APPDEFAULT);
573     aField.SetURL( aUrl );
574     aField.SetRepresentation( aRepresentation );
575     aField.SetTargetFrame( aTarget );
576     return SvxFieldItem( aField, EE_FEATURE_FIELD );
577 }
578 
579 void ScCellFieldObj::DeleteField()
580 {
581     if (pEditSource)
582     {
583         SvxTextForwarder* pForwarder = pEditSource->GetTextForwarder();
584 //      pEditEngine->QuickDelete( aSelection );
585         pForwarder->QuickInsertText( String(), aSelection );
586         pEditSource->UpdateData();
587 
588         aSelection.nEndPara = aSelection.nStartPara;
589         aSelection.nEndPos  = aSelection.nStartPos;
590 
591         //! Broadcast, um Selektion in anderen Objekten anzupassen
592         //! (auch bei anderen Aktionen)
593     }
594 }
595 
596 // XTextField
597 
598 rtl::OUString SAL_CALL ScCellFieldObj::getPresentation( sal_Bool bShowCommand )
599                                                     throw(uno::RuntimeException)
600 {
601     ScUnoGuard aGuard;
602     String aRet;
603 
604     if (pEditSource)
605     {
606         //! Feld-Funktionen muessen an den Forwarder !!!
607         ScEditEngineDefaulter* pEditEngine = ((ScCellEditSource*)pEditSource)->GetEditEngine();
608         ScUnoEditEngine aTempEngine(pEditEngine);
609 
610         //  Typ egal (in Zellen gibts nur URLs)
611         SvxFieldData* pField = aTempEngine.FindByPos( aSelection.nStartPara, aSelection.nStartPos, 0 );
612         DBG_ASSERT(pField,"getPresentation: Feld nicht gefunden");
613         if (pField)
614         {
615             SvxURLField* pURL = (SvxURLField*)pField;
616             if (bShowCommand)
617                 aRet = pURL->GetURL();
618             else
619                 aRet = pURL->GetRepresentation();
620         }
621     }
622 
623     return aRet;
624 }
625 
626 // XTextContent
627 
628 void SAL_CALL ScCellFieldObj::attach( const uno::Reference<text::XTextRange>& xTextRange )
629                                 throw(lang::IllegalArgumentException, uno::RuntimeException)
630 {
631     ScUnoGuard aGuard;
632     if (xTextRange.is())
633     {
634         uno::Reference<text::XText> xText(xTextRange->getText());
635         if (xText.is())
636         {
637             xText->insertTextContent( xTextRange, this, sal_True );
638         }
639     }
640 }
641 
642 uno::Reference<text::XTextRange> SAL_CALL ScCellFieldObj::getAnchor() throw(uno::RuntimeException)
643 {
644     ScUnoGuard aGuard;
645     if (pDocShell)
646         return new ScCellObj( pDocShell, aCellPos );
647     return NULL;
648 }
649 
650 // XComponent
651 
652 void SAL_CALL ScCellFieldObj::dispose() throw(uno::RuntimeException)
653 {
654     OComponentHelper::dispose();
655 }
656 
657 void SAL_CALL ScCellFieldObj::addEventListener(
658                         const uno::Reference<lang::XEventListener>& xListener )
659                                                     throw(uno::RuntimeException)
660 {
661     OComponentHelper::addEventListener( xListener );
662 }
663 
664 void SAL_CALL ScCellFieldObj::removeEventListener(
665                         const uno::Reference<lang::XEventListener>& xListener )
666                                                     throw(uno::RuntimeException)
667 {
668     OComponentHelper::removeEventListener( xListener );
669 }
670 
671 // XPropertySet
672 
673 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScCellFieldObj::getPropertySetInfo()
674                                                         throw(uno::RuntimeException)
675 {
676     ScUnoGuard aGuard;
677     static uno::Reference<beans::XPropertySetInfo> aRef = pPropSet->getPropertySetInfo();
678     return aRef;
679 }
680 
681 void SAL_CALL ScCellFieldObj::setPropertyValue(
682                         const rtl::OUString& aPropertyName, const uno::Any& aValue )
683                 throw(beans::UnknownPropertyException, beans::PropertyVetoException,
684                         lang::IllegalArgumentException, lang::WrappedTargetException,
685                         uno::RuntimeException)
686 {
687     ScUnoGuard aGuard;
688     String aNameString(aPropertyName);
689     rtl::OUString aStrVal;
690     if (pEditSource)
691     {
692         //! Feld-Funktionen muessen an den Forwarder !!!
693         ScEditEngineDefaulter* pEditEngine = ((ScCellEditSource*)pEditSource)->GetEditEngine();
694         ScUnoEditEngine aTempEngine(pEditEngine);
695 
696         //  Typ egal (in Zellen gibts nur URLs)
697         SvxFieldData* pField = aTempEngine.FindByPos( aSelection.nStartPara, aSelection.nStartPos, 0 );
698         DBG_ASSERT(pField,"setPropertyValue: Feld nicht gefunden");
699         if (pField)
700         {
701             SvxURLField* pURL = (SvxURLField*)pField;   // ist eine Kopie in der ScUnoEditEngine
702 
703             sal_Bool bOk = sal_True;
704             if ( aNameString.EqualsAscii( SC_UNONAME_URL ) )
705             {
706                 if (aValue >>= aStrVal)
707                     pURL->SetURL( aStrVal );
708             }
709             else if ( aNameString.EqualsAscii( SC_UNONAME_REPR ) )
710             {
711                 if (aValue >>= aStrVal)
712                     pURL->SetRepresentation( aStrVal );
713             }
714             else if ( aNameString.EqualsAscii( SC_UNONAME_TARGET ) )
715             {
716                 if (aValue >>= aStrVal)
717                     pURL->SetTargetFrame( aStrVal );
718             }
719             else
720                 bOk = sal_False;
721 
722             if (bOk)
723             {
724                 pEditEngine->QuickInsertField( SvxFieldItem(*pField, EE_FEATURE_FIELD), aSelection );
725                 pEditSource->UpdateData();
726             }
727         }
728     }
729     else        // noch nicht eingefuegt
730     {
731         if ( aNameString.EqualsAscii( SC_UNONAME_URL ) )
732         {
733             if (aValue >>= aStrVal)
734                 aUrl = String( aStrVal );
735         }
736         else if ( aNameString.EqualsAscii( SC_UNONAME_REPR ) )
737         {
738             if (aValue >>= aStrVal)
739                 aRepresentation = String( aStrVal );
740         }
741         else if ( aNameString.EqualsAscii( SC_UNONAME_TARGET ) )
742         {
743             if (aValue >>= aStrVal)
744                 aTarget = String( aStrVal );
745         }
746     }
747 }
748 
749 uno::Any SAL_CALL ScCellFieldObj::getPropertyValue( const rtl::OUString& aPropertyName )
750                 throw(beans::UnknownPropertyException, lang::WrappedTargetException,
751                         uno::RuntimeException)
752 {
753     ScUnoGuard aGuard;
754     uno::Any aRet;
755     String aNameString(aPropertyName);
756 
757     // anchor type is always "as character", text wrap always "none"
758 
759     if ( aNameString.EqualsAscii( SC_UNONAME_ANCTYPE ) )
760         aRet <<= text::TextContentAnchorType_AS_CHARACTER;
761     else if ( aNameString.EqualsAscii( SC_UNONAME_ANCTYPES ) )
762     {
763         uno::Sequence<text::TextContentAnchorType> aSeq(1);
764         aSeq[0] = text::TextContentAnchorType_AS_CHARACTER;
765         aRet <<= aSeq;
766     }
767     else if ( aNameString.EqualsAscii( SC_UNONAME_TEXTWRAP ) )
768         aRet <<= text::WrapTextMode_NONE;
769     else if (pEditSource)
770     {
771         //! Feld-Funktionen muessen an den Forwarder !!!
772         ScEditEngineDefaulter* pEditEngine = ((ScCellEditSource*)pEditSource)->GetEditEngine();
773         ScUnoEditEngine aTempEngine(pEditEngine);
774 
775         //  Typ egal (in Zellen gibts nur URLs)
776         SvxFieldData* pField = aTempEngine.FindByPos( aSelection.nStartPara, aSelection.nStartPos, 0 );
777         DBG_ASSERT(pField,"getPropertyValue: Feld nicht gefunden");
778         if (pField)
779         {
780             SvxURLField* pURL = (SvxURLField*)pField;
781 
782             if ( aNameString.EqualsAscii( SC_UNONAME_URL ) )
783                 aRet <<= rtl::OUString( pURL->GetURL() );
784             else if ( aNameString.EqualsAscii( SC_UNONAME_REPR ) )
785                 aRet <<= rtl::OUString( pURL->GetRepresentation() );
786             else if ( aNameString.EqualsAscii( SC_UNONAME_TARGET ) )
787                 aRet <<= rtl::OUString( pURL->GetTargetFrame() );
788         }
789     }
790     else        // noch nicht eingefuegt
791     {
792         if ( aNameString.EqualsAscii( SC_UNONAME_URL ) )
793             aRet <<= rtl::OUString( aUrl );
794         else if ( aNameString.EqualsAscii( SC_UNONAME_REPR ) )
795             aRet <<= rtl::OUString( aRepresentation );
796         else if ( aNameString.EqualsAscii( SC_UNONAME_TARGET ) )
797             aRet <<= rtl::OUString( aTarget );
798     }
799     return aRet;
800 }
801 
802 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScCellFieldObj )
803 
804 // XUnoTunnel
805 
806 sal_Int64 SAL_CALL ScCellFieldObj::getSomething(
807                 const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
808 {
809     if ( rId.getLength() == 16 &&
810           0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
811                                     rId.getConstArray(), 16 ) )
812     {
813         return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
814     }
815     return 0;
816 }
817 
818 // static
819 const uno::Sequence<sal_Int8>& ScCellFieldObj::getUnoTunnelId()
820 {
821     static uno::Sequence<sal_Int8> * pSeq = 0;
822     if( !pSeq )
823     {
824         osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
825         if( !pSeq )
826         {
827             static uno::Sequence< sal_Int8 > aSeq( 16 );
828             rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
829             pSeq = &aSeq;
830         }
831     }
832     return *pSeq;
833 }
834 
835 // static
836 ScCellFieldObj* ScCellFieldObj::getImplementation(
837                                 const uno::Reference<text::XTextContent> xObj )
838 {
839     ScCellFieldObj* pRet = NULL;
840     uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
841     if (xUT.is())
842         pRet = reinterpret_cast<ScCellFieldObj*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
843     return pRet;
844 }
845 
846 // XServiceInfo
847 
848 rtl::OUString SAL_CALL ScCellFieldObj::getImplementationName() throw(uno::RuntimeException)
849 {
850     return rtl::OUString::createFromAscii( "ScCellFieldObj" );
851 }
852 
853 sal_Bool SAL_CALL ScCellFieldObj::supportsService( const rtl::OUString& rServiceName )
854                                                     throw(uno::RuntimeException)
855 {
856     String aServiceStr( rServiceName );
857     return aServiceStr.EqualsAscii( SCTEXTFIELD_SERVICE ) ||
858            aServiceStr.EqualsAscii( SCTEXTCONTENT_SERVICE );
859 }
860 
861 uno::Sequence<rtl::OUString> SAL_CALL ScCellFieldObj::getSupportedServiceNames()
862                                                     throw(uno::RuntimeException)
863 {
864     uno::Sequence<rtl::OUString> aRet(2);
865     rtl::OUString* pArray = aRet.getArray();
866     pArray[0] = rtl::OUString::createFromAscii( SCTEXTFIELD_SERVICE );
867     pArray[1] = rtl::OUString::createFromAscii( SCTEXTCONTENT_SERVICE );
868     return aRet;
869 }
870 
871 //------------------------------------------------------------------------
872 
873 ScHeaderFieldsObj::ScHeaderFieldsObj(ScHeaderFooterContentObj* pContent, sal_uInt16 nP, sal_uInt16 nT) :
874     pContentObj( pContent ),
875     nPart( nP ),
876     nType( nT ),
877     mpRefreshListeners( NULL )
878 {
879     DBG_ASSERT( pContentObj, "ScHeaderFieldsObj ohne Objekt?" );
880 
881     if (pContentObj)
882     {
883         pContentObj->acquire();     // darf nicht wegkommen
884         pEditSource = new ScHeaderFooterEditSource( pContentObj, nPart );
885     }
886     else
887         pEditSource = NULL;
888 }
889 
890 ScHeaderFieldsObj::~ScHeaderFieldsObj()
891 {
892     delete pEditSource;
893 
894     if (pContentObj)
895         pContentObj->release();
896 
897     // increment refcount to prevent double call off dtor
898     osl_incrementInterlockedCount( &m_refCount );
899 
900     if (mpRefreshListeners)
901     {
902         lang::EventObject aEvent;
903         aEvent.Source = static_cast<cppu::OWeakObject*>(this);
904         if (mpRefreshListeners)
905         {
906             mpRefreshListeners->disposeAndClear(aEvent);
907             DELETEZ( mpRefreshListeners );
908         }
909     }
910 }
911 
912 // XIndexAccess (via XTextFields)
913 
914 ScHeaderFieldObj* ScHeaderFieldsObj::GetObjectByIndex_Impl(sal_Int32 Index) const
915 {
916     //! Feld-Funktionen muessen an den Forwarder !!!
917     ScEditEngineDefaulter* pEditEngine = ((ScHeaderFooterEditSource*)pEditSource)->GetEditEngine();
918     ScUnoEditEngine aTempEngine(pEditEngine);
919 
920     TypeId aTypeId = NULL;
921     switch (nType)
922     {
923         case SC_SERVICE_PAGEFIELD:  aTypeId = TYPE(SvxPageField);    break;
924         case SC_SERVICE_PAGESFIELD: aTypeId = TYPE(SvxPagesField);   break;
925         case SC_SERVICE_DATEFIELD:  aTypeId = TYPE(SvxDateField);    break;
926         case SC_SERVICE_TIMEFIELD:  aTypeId = TYPE(SvxTimeField);    break;
927         case SC_SERVICE_TITLEFIELD: aTypeId = TYPE(SvxFileField);    break;
928         case SC_SERVICE_FILEFIELD:  aTypeId = TYPE(SvxExtFileField); break;
929         case SC_SERVICE_SHEETFIELD: aTypeId = TYPE(SvxTableField);   break;
930         // bei SC_SERVICE_INVALID bleibt TypeId Null
931     }
932     SvxFieldData* pData = aTempEngine.FindByIndex( (sal_uInt16)Index, aTypeId );
933     if ( pData )
934     {
935         sal_uInt16 nPar = aTempEngine.GetFieldPar();
936         xub_StrLen nPos = aTempEngine.GetFieldPos();
937 
938         sal_uInt16 nFieldType = nType;
939         if ( nFieldType == SC_SERVICE_INVALID )
940         {
941             if ( pData->ISA( SvxPageField ) )         nFieldType = SC_SERVICE_PAGEFIELD;
942             else if ( pData->ISA( SvxPagesField ) )   nFieldType = SC_SERVICE_PAGESFIELD;
943             else if ( pData->ISA( SvxDateField ) )    nFieldType = SC_SERVICE_DATEFIELD;
944             else if ( pData->ISA( SvxTimeField ) )    nFieldType = SC_SERVICE_TIMEFIELD;
945             else if ( pData->ISA( SvxFileField ) )    nFieldType = SC_SERVICE_TITLEFIELD;
946             else if ( pData->ISA( SvxExtFileField ) ) nFieldType = SC_SERVICE_FILEFIELD;
947             else if ( pData->ISA( SvxTableField ) )   nFieldType = SC_SERVICE_SHEETFIELD;
948         }
949 
950         ESelection aSelection( nPar, nPos, nPar, nPos+1 );      // Field is 1 character
951         return new ScHeaderFieldObj( pContentObj, nPart, nFieldType, aSelection );
952     }
953     return NULL;
954 }
955 
956 sal_Int32 SAL_CALL ScHeaderFieldsObj::getCount() throw(uno::RuntimeException)
957 {
958     ScUnoGuard aGuard;
959 
960     //! Feld-Funktionen muessen an den Forwarder !!!
961     ScEditEngineDefaulter* pEditEngine = ((ScHeaderFooterEditSource*)pEditSource)->GetEditEngine();
962     ScUnoEditEngine aTempEngine(pEditEngine);
963 
964     TypeId aTypeId = NULL;
965     switch (nType)
966     {
967         case SC_SERVICE_PAGEFIELD:  aTypeId = TYPE(SvxPageField);    break;
968         case SC_SERVICE_PAGESFIELD: aTypeId = TYPE(SvxPagesField);   break;
969         case SC_SERVICE_DATEFIELD:  aTypeId = TYPE(SvxDateField);    break;
970         case SC_SERVICE_TIMEFIELD:  aTypeId = TYPE(SvxTimeField);    break;
971         case SC_SERVICE_TITLEFIELD: aTypeId = TYPE(SvxFileField);    break;
972         case SC_SERVICE_FILEFIELD:  aTypeId = TYPE(SvxExtFileField); break;
973         case SC_SERVICE_SHEETFIELD: aTypeId = TYPE(SvxTableField);   break;
974     }
975     return aTempEngine.CountFields(aTypeId);        // Felder zaehlen
976 }
977 
978 uno::Any SAL_CALL ScHeaderFieldsObj::getByIndex( sal_Int32 nIndex )
979                             throw(lang::IndexOutOfBoundsException,
980                                     lang::WrappedTargetException, uno::RuntimeException)
981 {
982     ScUnoGuard aGuard;
983     uno::Reference<text::XTextField> xField(GetObjectByIndex_Impl(nIndex));
984     if (xField.is())
985         return uno::makeAny(xField);
986     else
987         throw lang::IndexOutOfBoundsException();
988 //    return uno::Any();
989 }
990 
991 uno::Type SAL_CALL ScHeaderFieldsObj::getElementType() throw(uno::RuntimeException)
992 {
993     ScUnoGuard aGuard;
994     return getCppuType((uno::Reference<text::XTextField>*)0);
995 }
996 
997 sal_Bool SAL_CALL ScHeaderFieldsObj::hasElements() throw(uno::RuntimeException)
998 {
999     ScUnoGuard aGuard;
1000     return ( getCount() != 0 );
1001 }
1002 
1003 uno::Reference<container::XEnumeration> SAL_CALL ScHeaderFieldsObj::createEnumeration()
1004                                                     throw(uno::RuntimeException)
1005 {
1006     ScUnoGuard aGuard;
1007     return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.TextFieldEnumeration")));
1008 }
1009 
1010 void SAL_CALL ScHeaderFieldsObj::addContainerListener(
1011                                 const uno::Reference<container::XContainerListener>& /* xListener */ )
1012                                     throw(uno::RuntimeException)
1013 {
1014     DBG_ERROR("not implemented");
1015 }
1016 
1017 void SAL_CALL ScHeaderFieldsObj::removeContainerListener(
1018                                 const uno::Reference<container::XContainerListener>& /* xListener */ )
1019                                     throw(uno::RuntimeException)
1020 {
1021     DBG_ERROR("not implemented");
1022 }
1023 
1024 // XRefreshable
1025 void SAL_CALL ScHeaderFieldsObj::refresh(  )
1026                                     throw (uno::RuntimeException)
1027 {
1028     if (mpRefreshListeners)
1029     {
1030         //  Call all listeners.
1031         uno::Sequence< uno::Reference< uno::XInterface > > aListeners(mpRefreshListeners->getElements());
1032         sal_uInt32 nLength(aListeners.getLength());
1033         if (nLength)
1034         {
1035             const uno::Reference< uno::XInterface >* pInterfaces = aListeners.getConstArray();
1036             if (pInterfaces)
1037             {
1038                 lang::EventObject aEvent;
1039                 aEvent.Source.set(uno::Reference< util::XRefreshable >(const_cast<ScHeaderFieldsObj*>(this)));
1040                 sal_uInt32 i(0);
1041                 while (i < nLength)
1042                 {
1043                     try
1044                     {
1045                         while(i < nLength)
1046                         {
1047                             static_cast< util::XRefreshListener* >(pInterfaces->get())->refreshed(aEvent);
1048                             ++pInterfaces;
1049                             ++i;
1050                         }
1051                     }
1052                     catch(uno::RuntimeException&)
1053                     {
1054 //                      DBG_ERROR("a object is gone without to remove from Broadcaster");
1055                         ++pInterfaces;
1056                         ++i;
1057                     }
1058                 }
1059             }
1060         }
1061     }
1062 }
1063 
1064 void SAL_CALL ScHeaderFieldsObj::addRefreshListener( const uno::Reference< util::XRefreshListener >& xListener )
1065                                     throw (uno::RuntimeException)
1066 {
1067     if (xListener.is())
1068     {
1069         ScUnoGuard aGuard;
1070         if (!mpRefreshListeners)
1071             mpRefreshListeners = new cppu::OInterfaceContainerHelper(aMutex);
1072         mpRefreshListeners->addInterface(xListener);
1073     }
1074 }
1075 
1076 void SAL_CALL ScHeaderFieldsObj::removeRefreshListener( const uno::Reference<util::XRefreshListener >& xListener )
1077                                     throw (uno::RuntimeException)
1078 {
1079     if (xListener.is())
1080     {
1081         ScUnoGuard aGuard;
1082         if (mpRefreshListeners)
1083             mpRefreshListeners->removeInterface(xListener);
1084     }
1085 }
1086 
1087 //------------------------------------------------------------------------
1088 
1089 SvxFileFormat lcl_UnoToSvxFileFormat( sal_Int16 nUnoValue )
1090 {
1091     switch( nUnoValue )
1092     {
1093         case text::FilenameDisplayFormat::FULL: return SVXFILEFORMAT_FULLPATH;
1094         case text::FilenameDisplayFormat::PATH: return SVXFILEFORMAT_PATH;
1095         case text::FilenameDisplayFormat::NAME: return SVXFILEFORMAT_NAME;
1096 //      case text::FilenameDisplayFormat::NAME_AND_EXT:
1097         default:
1098             return SVXFILEFORMAT_NAME_EXT;
1099     }
1100 }
1101 
1102 sal_Int16 lcl_SvxToUnoFileFormat( SvxFileFormat nSvxValue )
1103 {
1104     switch( nSvxValue )
1105     {
1106         case SVXFILEFORMAT_NAME_EXT:    return text::FilenameDisplayFormat::NAME_AND_EXT;
1107         case SVXFILEFORMAT_FULLPATH:    return text::FilenameDisplayFormat::FULL;
1108         case SVXFILEFORMAT_PATH:        return text::FilenameDisplayFormat::PATH;
1109 //      case SVXFILEFORMAT_NAME:
1110         default:
1111             return text::FilenameDisplayFormat::NAME;
1112     }
1113 }
1114 
1115 
1116 //  Default-ctor wird fuer SMART_REFLECTION_IMPLEMENTATION gebraucht
1117 //UNUSED2008-05  ScHeaderFieldObj::ScHeaderFieldObj() :
1118 //UNUSED2008-05      OComponentHelper( getMutex() ),
1119 //UNUSED2008-05      aPropSet( lcl_GetHeaderFieldPropertyMap() ),
1120 //UNUSED2008-05      pContentObj( NULL ),
1121 //UNUSED2008-05      nPart( 0 ),
1122 //UNUSED2008-05      nType( 0 ),
1123 //UNUSED2008-05      nFileFormat( SVXFILEFORMAT_NAME_EXT )
1124 //UNUSED2008-05  {
1125 //UNUSED2008-05      pEditSource = NULL;
1126 //UNUSED2008-05  }
1127 
1128 ScHeaderFieldObj::ScHeaderFieldObj(ScHeaderFooterContentObj* pContent, sal_uInt16 nP,
1129                                             sal_uInt16 nT, const ESelection& rSel) :
1130     OComponentHelper( getMutex() ),
1131     pPropSet( (nT == SC_SERVICE_FILEFIELD) ? lcl_GetFileFieldPropertySet() : lcl_GetHeaderFieldPropertySet() ),
1132     pContentObj( pContent ),
1133     nPart( nP ),
1134     nType( nT ),
1135     aSelection( rSel ),
1136     nFileFormat( SVXFILEFORMAT_NAME_EXT )
1137 {
1138     //  pContent ist Null, wenn per ServiceProvider erzeugt
1139 
1140     if (pContentObj)
1141     {
1142         pContentObj->acquire();     // darf nicht wegkommen
1143         pEditSource = new ScHeaderFooterEditSource( pContentObj, nPart );
1144     }
1145     else
1146         pEditSource = NULL;
1147 }
1148 
1149 uno::Any SAL_CALL ScHeaderFieldObj::queryAggregation( const uno::Type& rType )
1150                                                 throw(uno::RuntimeException)
1151 {
1152     SC_QUERYINTERFACE( text::XTextField )
1153     SC_QUERYINTERFACE( text::XTextContent )         // parent of XTextField
1154     SC_QUERYINTERFACE( beans::XPropertySet )
1155     SC_QUERYINTERFACE( lang::XUnoTunnel )
1156     SC_QUERYINTERFACE( lang::XServiceInfo )
1157 
1158     return OComponentHelper::queryAggregation( rType );     // XComponent
1159 }
1160 
1161 uno::Sequence<uno::Type> SAL_CALL ScHeaderFieldObj::getTypes() throw(uno::RuntimeException)
1162 {
1163     static uno::Sequence<uno::Type> aTypes;
1164     if ( aTypes.getLength() == 0 )
1165     {
1166         uno::Sequence<uno::Type> aParentTypes(OComponentHelper::getTypes());
1167         long nParentLen = aParentTypes.getLength();
1168         const uno::Type* pParentPtr = aParentTypes.getConstArray();
1169 
1170         aTypes.realloc( nParentLen + 4 );
1171         uno::Type* pPtr = aTypes.getArray();
1172         pPtr[nParentLen + 0] = getCppuType((const uno::Reference<text::XTextField>*)0);
1173         pPtr[nParentLen + 1] = getCppuType((const uno::Reference<beans::XPropertySet>*)0);
1174         pPtr[nParentLen + 2] = getCppuType((const uno::Reference<lang::XUnoTunnel>*)0);
1175         pPtr[nParentLen + 3] = getCppuType((const uno::Reference<lang::XServiceInfo>*)0);
1176 
1177         for (long i=0; i<nParentLen; i++)
1178             pPtr[i] = pParentPtr[i];                // parent types first
1179     }
1180     return aTypes;
1181 }
1182 
1183 uno::Sequence<sal_Int8> SAL_CALL ScHeaderFieldObj::getImplementationId()
1184                                                     throw(uno::RuntimeException)
1185 {
1186     static uno::Sequence< sal_Int8 > aId;
1187     if( aId.getLength() == 0 )
1188     {
1189         aId.realloc( 16 );
1190         rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
1191     }
1192     return aId;
1193 }
1194 
1195 uno::Any SAL_CALL ScHeaderFieldObj::queryInterface( const uno::Type& rType )
1196                                                 throw(uno::RuntimeException)
1197 {
1198     return OComponentHelper::queryInterface( rType );
1199 }
1200 
1201 void SAL_CALL ScHeaderFieldObj::acquire() throw()
1202 {
1203     OComponentHelper::acquire();
1204 }
1205 
1206 void SAL_CALL ScHeaderFieldObj::release() throw()
1207 {
1208     OComponentHelper::release();
1209 }
1210 
1211 void ScHeaderFieldObj::InitDoc( ScHeaderFooterContentObj* pContent, sal_uInt16 nP,
1212                                         const ESelection& rSel )
1213 {
1214     if ( pContent && !pEditSource )
1215     {
1216         DBG_ASSERT( !pContentObj, "ContentObj, aber kein EditSource?" );
1217 
1218         aSelection = rSel;
1219         nPart = nP;
1220         pContentObj = pContent;
1221 
1222         pContentObj->acquire();     // darf nicht wegkommen
1223         pEditSource = new ScHeaderFooterEditSource( pContentObj, nPart );
1224     }
1225 }
1226 
1227 ScHeaderFieldObj::~ScHeaderFieldObj()
1228 {
1229     delete pEditSource;
1230 
1231     if (pContentObj)
1232         pContentObj->release();
1233 }
1234 
1235 // per getImplementation gerufen:
1236 
1237 SvxFieldItem ScHeaderFieldObj::CreateFieldItem()
1238 {
1239     DBG_ASSERT( !pEditSource, "CreateFieldItem mit eingefuegtem Feld" );
1240 
1241     switch (nType)
1242     {
1243         case SC_SERVICE_PAGEFIELD:
1244             {
1245                 SvxPageField aField;
1246                 return SvxFieldItem( aField, EE_FEATURE_FIELD );
1247             }
1248         case SC_SERVICE_PAGESFIELD:
1249             {
1250                 SvxPagesField aField;
1251                 return SvxFieldItem( aField, EE_FEATURE_FIELD );
1252             }
1253         case SC_SERVICE_DATEFIELD:
1254             {
1255                 SvxDateField aField;
1256                 return SvxFieldItem( aField, EE_FEATURE_FIELD );
1257             }
1258         case SC_SERVICE_TIMEFIELD:
1259             {
1260                 SvxTimeField aField;
1261                 return SvxFieldItem( aField, EE_FEATURE_FIELD );
1262             }
1263         case SC_SERVICE_TITLEFIELD:
1264             {
1265                 SvxFileField aField;
1266                 return SvxFieldItem( aField, EE_FEATURE_FIELD );
1267             }
1268         case SC_SERVICE_FILEFIELD:
1269             {
1270                 SvxExtFileField aField;
1271                 aField.SetFormat( (SvxFileFormat) nFileFormat );
1272                 return SvxFieldItem( aField, EE_FEATURE_FIELD );
1273             }
1274         case SC_SERVICE_SHEETFIELD:
1275             {
1276                 SvxTableField aField;
1277                 return SvxFieldItem( aField, EE_FEATURE_FIELD );
1278             }
1279     }
1280 
1281     return SvxFieldItem( SvxFieldData(), EE_FEATURE_FIELD );
1282 }
1283 
1284 void ScHeaderFieldObj::DeleteField()
1285 {
1286     if (pEditSource)
1287     {
1288         SvxTextForwarder* pForwarder = pEditSource->GetTextForwarder();
1289 //      pEditEngine->QuickDelete( aSelection );
1290         pForwarder->QuickInsertText( String(), aSelection );
1291         pEditSource->UpdateData();
1292 
1293         aSelection.nEndPara = aSelection.nStartPara;
1294         aSelection.nEndPos  = aSelection.nStartPos;
1295 
1296         //! Broadcast, um Selektion in anderen Objekten anzupassen
1297         //! (auch bei anderen Aktionen)
1298     }
1299 }
1300 
1301 // XTextField
1302 
1303 rtl::OUString SAL_CALL ScHeaderFieldObj::getPresentation( sal_Bool /* bShowCommand */ )
1304                                                     throw(uno::RuntimeException)
1305 {
1306     ScUnoGuard aGuard;
1307     String aRet;
1308 
1309     if (pEditSource)
1310     {
1311         // Feld von der EditEngine formatieren lassen, bShowCommand gibt's nicht
1312 
1313         SvxTextForwarder* pForwarder = pEditSource->GetTextForwarder();
1314         aRet = pForwarder->GetText( aSelection );
1315     }
1316 
1317     return aRet;
1318 }
1319 
1320 // XTextContent
1321 
1322 void SAL_CALL ScHeaderFieldObj::attach( const uno::Reference<text::XTextRange>& xTextRange )
1323                                 throw(lang::IllegalArgumentException, uno::RuntimeException)
1324 {
1325     ScUnoGuard aGuard;
1326     if (xTextRange.is())
1327     {
1328         uno::Reference<text::XText> xText(xTextRange->getText());
1329         if (xText.is())
1330         {
1331             xText->insertTextContent( xTextRange, this, sal_True );
1332         }
1333     }
1334 }
1335 
1336 uno::Reference<text::XTextRange> SAL_CALL ScHeaderFieldObj::getAnchor() throw(uno::RuntimeException)
1337 {
1338     ScUnoGuard aGuard;
1339     if (pContentObj)
1340     {
1341         uno::Reference<text::XText> xText;
1342         if ( nPart == SC_HDFT_LEFT )
1343             xText = pContentObj->getLeftText();
1344         else if (nPart == SC_HDFT_CENTER)
1345             xText = pContentObj->getCenterText();
1346         else
1347             xText = pContentObj->getRightText();
1348         return uno::Reference<text::XTextRange>( xText, uno::UNO_QUERY );
1349     }
1350     return NULL;
1351 }
1352 
1353 // XComponent
1354 
1355 void SAL_CALL ScHeaderFieldObj::dispose() throw(uno::RuntimeException)
1356 {
1357     OComponentHelper::dispose();
1358 }
1359 
1360 void SAL_CALL ScHeaderFieldObj::addEventListener(
1361                         const uno::Reference<lang::XEventListener>& xListener )
1362                                                     throw(uno::RuntimeException)
1363 {
1364     OComponentHelper::addEventListener( xListener );
1365 }
1366 
1367 void SAL_CALL ScHeaderFieldObj::removeEventListener(
1368                         const uno::Reference<lang::XEventListener>& xListener )
1369                                                     throw(uno::RuntimeException)
1370 {
1371     OComponentHelper::removeEventListener( xListener );
1372 }
1373 
1374 // XPropertySet
1375 
1376 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScHeaderFieldObj::getPropertySetInfo()
1377                                                         throw(uno::RuntimeException)
1378 {
1379     ScUnoGuard aGuard;
1380     if (nType == SC_SERVICE_FILEFIELD)
1381     {
1382         //  file field has different properties
1383         static uno::Reference<beans::XPropertySetInfo> aFileFieldInfo = pPropSet->getPropertySetInfo();
1384         return aFileFieldInfo;
1385     }
1386     else
1387     {
1388         static uno::Reference<beans::XPropertySetInfo> aRef = pPropSet->getPropertySetInfo();
1389         return aRef;
1390     }
1391 }
1392 
1393 void SAL_CALL ScHeaderFieldObj::setPropertyValue(
1394                         const rtl::OUString& aPropertyName, const uno::Any& aValue )
1395                 throw(beans::UnknownPropertyException, beans::PropertyVetoException,
1396                         lang::IllegalArgumentException, lang::WrappedTargetException,
1397                         uno::RuntimeException)
1398 {
1399     ScUnoGuard aGuard;
1400     String aNameString(aPropertyName);
1401     if ( nType == SC_SERVICE_FILEFIELD && aNameString.EqualsAscii( SC_UNONAME_FILEFORM ) )
1402     {
1403         sal_Int16 nIntVal = 0;
1404         if ( aValue >>= nIntVal )
1405         {
1406             SvxFileFormat eFormat = lcl_UnoToSvxFileFormat( nIntVal );
1407             if (pEditSource)
1408             {
1409                 ScEditEngineDefaulter* pEditEngine = ((ScHeaderFooterEditSource*)pEditSource)->GetEditEngine();
1410                 ScUnoEditEngine aTempEngine(pEditEngine);
1411                 SvxFieldData* pField = aTempEngine.FindByPos(
1412                         aSelection.nStartPara, aSelection.nStartPos, TYPE(SvxExtFileField) );
1413                 DBG_ASSERT(pField,"setPropertyValue: Field not found");
1414                 if (pField)
1415                 {
1416                     SvxExtFileField* pExtFile = (SvxExtFileField*)pField;   // local to the ScUnoEditEngine
1417                     pExtFile->SetFormat( eFormat );
1418                     pEditEngine->QuickInsertField( SvxFieldItem(*pField, EE_FEATURE_FIELD), aSelection );
1419                     pEditSource->UpdateData();
1420                 }
1421             }
1422             else
1423                 nFileFormat = sal::static_int_cast<sal_Int16>(eFormat);     // not inserted yet - store value
1424         }
1425     }
1426 }
1427 
1428 uno::Any SAL_CALL ScHeaderFieldObj::getPropertyValue( const rtl::OUString& aPropertyName )
1429                 throw(beans::UnknownPropertyException, lang::WrappedTargetException,
1430                         uno::RuntimeException)
1431 {
1432     ScUnoGuard aGuard;
1433 
1434     //! Properties?
1435     uno::Any aRet;
1436     String aNameString(aPropertyName);
1437 
1438     // anchor type is always "as character", text wrap always "none"
1439 
1440     if ( aNameString.EqualsAscii( SC_UNONAME_ANCTYPE ) )
1441         aRet <<= text::TextContentAnchorType_AS_CHARACTER;
1442     else if ( aNameString.EqualsAscii( SC_UNONAME_ANCTYPES ) )
1443     {
1444         uno::Sequence<text::TextContentAnchorType> aSeq(1);
1445         aSeq[0] = text::TextContentAnchorType_AS_CHARACTER;
1446         aRet <<= aSeq;
1447     }
1448     else if ( aNameString.EqualsAscii( SC_UNONAME_TEXTWRAP ) )
1449         aRet <<= text::WrapTextMode_NONE;
1450     else if ( nType == SC_SERVICE_FILEFIELD && aNameString.EqualsAscii( SC_UNONAME_FILEFORM ) )
1451     {
1452         SvxFileFormat eFormat = SVXFILEFORMAT_NAME_EXT;
1453         if (pEditSource)
1454         {
1455             ScEditEngineDefaulter* pEditEngine = ((ScHeaderFooterEditSource*)pEditSource)->GetEditEngine();
1456             ScUnoEditEngine aTempEngine(pEditEngine);
1457             SvxFieldData* pField = aTempEngine.FindByPos(
1458                     aSelection.nStartPara, aSelection.nStartPos, TYPE(SvxExtFileField) );
1459             DBG_ASSERT(pField,"setPropertyValue: Field not found");
1460             if (pField)
1461             {
1462                 const SvxExtFileField* pExtFile = (const SvxExtFileField*)pField;
1463                 eFormat = pExtFile->GetFormat();
1464             }
1465         }
1466         else
1467             eFormat = (SvxFileFormat) nFileFormat;      // not inserted yet - use stored value
1468 
1469         sal_Int16 nIntVal = lcl_SvxToUnoFileFormat( eFormat );
1470         aRet <<= nIntVal;
1471     }
1472 
1473     return aRet;
1474 }
1475 
1476 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScHeaderFieldObj )
1477 
1478 // XUnoTunnel
1479 
1480 sal_Int64 SAL_CALL ScHeaderFieldObj::getSomething(
1481                 const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
1482 {
1483     if ( rId.getLength() == 16 &&
1484           0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
1485                                     rId.getConstArray(), 16 ) )
1486     {
1487         return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
1488     }
1489     return 0;
1490 }
1491 
1492 // static
1493 const uno::Sequence<sal_Int8>& ScHeaderFieldObj::getUnoTunnelId()
1494 {
1495     static uno::Sequence<sal_Int8> * pSeq = 0;
1496     if( !pSeq )
1497     {
1498         osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
1499         if( !pSeq )
1500         {
1501             static uno::Sequence< sal_Int8 > aSeq( 16 );
1502             rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
1503             pSeq = &aSeq;
1504         }
1505     }
1506     return *pSeq;
1507 }
1508 
1509 // static
1510 ScHeaderFieldObj* ScHeaderFieldObj::getImplementation(
1511                                 const uno::Reference<text::XTextContent> xObj )
1512 {
1513     ScHeaderFieldObj* pRet = NULL;
1514     uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
1515     if (xUT.is())
1516         pRet = reinterpret_cast<ScHeaderFieldObj*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
1517     return pRet;
1518 }
1519 
1520 // XServiceInfo
1521 
1522 rtl::OUString SAL_CALL ScHeaderFieldObj::getImplementationName() throw(uno::RuntimeException)
1523 {
1524     return rtl::OUString::createFromAscii( "ScHeaderFieldObj" );
1525 }
1526 
1527 sal_Bool SAL_CALL ScHeaderFieldObj::supportsService( const rtl::OUString& rServiceName )
1528                                                     throw(uno::RuntimeException)
1529 {
1530     String aServiceStr( rServiceName );
1531     return aServiceStr.EqualsAscii( SCTEXTFIELD_SERVICE ) ||
1532            aServiceStr.EqualsAscii( SCTEXTCONTENT_SERVICE );
1533 }
1534 
1535 uno::Sequence<rtl::OUString> SAL_CALL ScHeaderFieldObj::getSupportedServiceNames()
1536                                                     throw(uno::RuntimeException)
1537 {
1538     uno::Sequence<rtl::OUString> aRet(2);
1539     rtl::OUString* pArray = aRet.getArray();
1540     pArray[0] = rtl::OUString::createFromAscii( SCTEXTFIELD_SERVICE );
1541     pArray[1] = rtl::OUString::createFromAscii( SCTEXTCONTENT_SERVICE );
1542     return aRet;
1543 }
1544 
1545 //------------------------------------------------------------------------
1546 
1547 
1548 
1549 
1550