1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <fielduno.hxx>
22 #include <textuno.hxx>
23 #include <miscuno.hxx>
26 #include <editsrc.hxx>
27 #include <unonames.hxx>
28 #include <editutil.hxx>
30 #include <svl/hint.hxx>
32 #include <vcl/svapp.hxx>
34 #include <editeng/eeitem.hxx>
36 #include <editeng/editeng.hxx>
37 #include <editeng/editobj.hxx>
38 #include <editeng/flditem.hxx>
39 #include <comphelper/sequence.hxx>
40 #include <cppuhelper/supportsservice.hxx>
42 #include <com/sun/star/beans/PropertyAttribute.hpp>
43 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
44 #include <com/sun/star/text/TextContentAnchorType.hpp>
45 #include <com/sun/star/text/WrapTextMode.hpp>
46 #include <com/sun/star/text/FilenameDisplayFormat.hpp>
47 #include <com/sun/star/text/textfield/Type.hpp>
49 using namespace com::sun::star
;
53 // no Which-ID here, map only for PropertySetInfo
55 const SfxItemPropertySet
* getDateTimePropertySet()
57 static const SfxItemPropertyMapEntry aMapContent
[] =
59 { SC_UNONAME_DATETIME
, 0, cppu::UnoType
<util::DateTime
>::get(), 0, 0 },
60 { SC_UNONAME_ISFIXED
, 0, cppu::UnoType
<bool>::get(), 0, 0 },
61 { SC_UNONAME_ISDATE
, 0, cppu::UnoType
<bool>::get(), 0, 0 },
62 { SC_UNONAME_NUMFMT
, 0, cppu::UnoType
<sal_Int32
>::get(), 0, 0 },
64 static SfxItemPropertySet
aMap(aMapContent
);
68 const SfxItemPropertySet
* getEmptyPropertySet()
70 static SfxItemPropertySet
aMap({});
74 const SfxItemPropertySet
* lcl_GetURLPropertySet()
76 static const SfxItemPropertyMapEntry aURLPropertyMap_Impl
[] =
78 { SC_UNONAME_ANCTYPE
, 0, cppu::UnoType
<text::TextContentAnchorType
>::get(), beans::PropertyAttribute::READONLY
, 0 },
79 { SC_UNONAME_ANCTYPES
, 0, cppu::UnoType
<uno::Sequence
<text::TextContentAnchorType
>>::get(), beans::PropertyAttribute::READONLY
, 0 },
80 { SC_UNONAME_REPR
, 0, cppu::UnoType
<OUString
>::get(), 0, 0},
81 { SC_UNONAME_TARGET
, 0, cppu::UnoType
<OUString
>::get(), 0, 0},
82 { SC_UNONAME_TEXTWRAP
, 0, cppu::UnoType
<text::WrapTextMode
>::get(), beans::PropertyAttribute::READONLY
, 0 },
83 { SC_UNONAME_URL
, 0, cppu::UnoType
<OUString
>::get(), 0, 0},
85 static SfxItemPropertySet
aURLPropertySet_Impl( aURLPropertyMap_Impl
);
86 return &aURLPropertySet_Impl
;
89 const SfxItemPropertySet
* lcl_GetHeaderFieldPropertySet()
91 static const SfxItemPropertyMapEntry aHeaderFieldPropertyMap_Impl
[] =
93 { SC_UNONAME_ANCTYPE
, 0, cppu::UnoType
<text::TextContentAnchorType
>::get(), beans::PropertyAttribute::READONLY
, 0 },
94 { SC_UNONAME_ANCTYPES
, 0, cppu::UnoType
<uno::Sequence
<text::TextContentAnchorType
>>::get(), beans::PropertyAttribute::READONLY
, 0 },
95 { SC_UNONAME_TEXTWRAP
, 0, cppu::UnoType
<text::WrapTextMode
>::get(), beans::PropertyAttribute::READONLY
, 0 },
97 static SfxItemPropertySet
aHeaderFieldPropertySet_Impl( aHeaderFieldPropertyMap_Impl
);
98 return &aHeaderFieldPropertySet_Impl
;
101 const SfxItemPropertySet
* lcl_GetFileFieldPropertySet()
103 static const SfxItemPropertyMapEntry aFileFieldPropertyMap_Impl
[] =
105 { SC_UNONAME_ANCTYPE
, 0, cppu::UnoType
<text::TextContentAnchorType
>::get(), beans::PropertyAttribute::READONLY
, 0 },
106 { SC_UNONAME_ANCTYPES
, 0, cppu::UnoType
<uno::Sequence
<text::TextContentAnchorType
>>::get(), beans::PropertyAttribute::READONLY
, 0 },
107 { SC_UNONAME_FILEFORM
, 0, cppu::UnoType
<sal_Int16
>::get(), 0, 0 },
108 { SC_UNONAME_TEXTWRAP
, 0, cppu::UnoType
<text::WrapTextMode
>::get(), beans::PropertyAttribute::READONLY
, 0 },
110 static SfxItemPropertySet
aFileFieldPropertySet_Impl( aFileFieldPropertyMap_Impl
);
111 return &aFileFieldPropertySet_Impl
;
114 SvxFileFormat
lcl_UnoToSvxFileFormat( sal_Int16 nUnoValue
)
118 case text::FilenameDisplayFormat::FULL
: return SvxFileFormat::PathFull
;
119 case text::FilenameDisplayFormat::PATH
: return SvxFileFormat::PathOnly
;
120 case text::FilenameDisplayFormat::NAME
: return SvxFileFormat::NameOnly
;
122 return SvxFileFormat::NameAndExt
;
126 sal_Int16
lcl_SvxToUnoFileFormat( SvxFileFormat nSvxValue
)
130 case SvxFileFormat::NameAndExt
: return text::FilenameDisplayFormat::NAME_AND_EXT
;
131 case SvxFileFormat::PathFull
: return text::FilenameDisplayFormat::FULL
;
132 case SvxFileFormat::PathOnly
: return text::FilenameDisplayFormat::PATH
;
134 return text::FilenameDisplayFormat::NAME
;
140 SC_SIMPLE_SERVICE_INFO( ScCellFieldsObj
, u
"ScCellFieldsObj"_ustr
, u
"com.sun.star.text.TextFields"_ustr
)
141 SC_SIMPLE_SERVICE_INFO( ScHeaderFieldsObj
, u
"ScHeaderFieldsObj"_ustr
, u
"com.sun.star.text.TextFields"_ustr
)
145 enum ScUnoCollectMode
148 SC_UNO_COLLECT_COUNT
,
149 SC_UNO_COLLECT_FINDINDEX
,
150 SC_UNO_COLLECT_FINDPOS
154 * This class exists solely to allow searching through field items. TODO:
155 * Look into providing the same functionality directly in EditEngine, to
156 * avoid having this class altogether.
158 class ScUnoEditEngine
: public ScEditEngineDefaulter
160 ScUnoCollectMode eMode
;
161 sal_uInt16 nFieldCount
;
162 sal_Int32 mnFieldType
;
163 std::unique_ptr
<SvxFieldData
>
164 pFound
; // local copy
167 sal_uInt16 nFieldIndex
;
170 explicit ScUnoEditEngine(ScEditEngineDefaulter
* pSource
);
172 virtual OUString
CalcFieldValue( const SvxFieldItem
& rField
, sal_Int32 nPara
, sal_Int32 nPos
,
173 std::optional
<Color
>& rTxtColor
, std::optional
<Color
>& rFldColor
, std::optional
<FontLineStyle
>& rFldLineStyle
) override
;
175 sal_uInt16
CountFields();
176 SvxFieldData
* FindByIndex(sal_uInt16 nIndex
);
177 SvxFieldData
* FindByPos(const EPaM
& rPos
, sal_Int32 nType
);
179 sal_Int32
GetFieldPar() const { return nFieldPar
; }
180 sal_Int32
GetFieldPos() const { return nFieldPos
; }
185 ScUnoEditEngine::ScUnoEditEngine(ScEditEngineDefaulter
* pSource
)
186 : ScEditEngineDefaulter(*pSource
)
187 , eMode(SC_UNO_COLLECT_NONE
)
189 , mnFieldType(text::textfield::Type::UNSPECIFIED
)
194 std::unique_ptr
<EditTextObject
> pData
= pSource
->CreateTextObject();
195 SetTextCurrentDefaults( *pData
);
198 OUString
ScUnoEditEngine::CalcFieldValue( const SvxFieldItem
& rField
,
199 sal_Int32 nPara
, sal_Int32 nPos
, std::optional
<Color
>& rTxtColor
, std::optional
<Color
>& rFldColor
, std::optional
<FontLineStyle
>& rFldLineStyle
)
201 OUString
aRet(EditEngine::CalcFieldValue( rField
, nPara
, nPos
, rTxtColor
, rFldColor
, rFldLineStyle
));
202 if (eMode
!= SC_UNO_COLLECT_NONE
)
204 const SvxFieldData
* pFieldData
= rField
.GetField();
207 if (mnFieldType
== text::textfield::Type::UNSPECIFIED
|| pFieldData
->GetClassId() == mnFieldType
)
209 if ( eMode
== SC_UNO_COLLECT_FINDINDEX
&& !pFound
&& nFieldCount
== nFieldIndex
)
211 pFound
= pFieldData
->Clone();
215 if ( eMode
== SC_UNO_COLLECT_FINDPOS
&& !pFound
&&
216 nPara
== nFieldPar
&& nPos
== nFieldPos
)
218 pFound
= pFieldData
->Clone();
219 nFieldIndex
= nFieldCount
;
228 sal_uInt16
ScUnoEditEngine::CountFields()
230 eMode
= SC_UNO_COLLECT_COUNT
;
231 mnFieldType
= text::textfield::Type::UNSPECIFIED
;
234 eMode
= SC_UNO_COLLECT_NONE
;
239 SvxFieldData
* ScUnoEditEngine::FindByIndex(sal_uInt16 nIndex
)
241 eMode
= SC_UNO_COLLECT_FINDINDEX
;
242 nFieldIndex
= nIndex
;
243 mnFieldType
= text::textfield::Type::UNSPECIFIED
;
246 eMode
= SC_UNO_COLLECT_NONE
;
251 SvxFieldData
* ScUnoEditEngine::FindByPos(const EPaM
& rPos
, sal_Int32 nType
)
253 eMode
= SC_UNO_COLLECT_FINDPOS
;
254 nFieldPar
= rPos
.nPara
;
255 nFieldPos
= rPos
.nIndex
;
259 mnFieldType
= text::textfield::Type::UNSPECIFIED
;
260 eMode
= SC_UNO_COLLECT_NONE
;
265 ScCellFieldsObj::ScCellFieldsObj(
266 uno::Reference
<text::XTextRange
> xContent
,
267 ScDocShell
* pDocSh
, const ScAddress
& rPos
) :
268 mxContent(std::move(xContent
)),
272 pDocShell
->GetDocument().AddUnoObject(*this);
274 mpEditSource
.reset( new ScCellEditSource( pDocShell
, aCellPos
) );
277 ScCellFieldsObj::~ScCellFieldsObj()
283 pDocShell
->GetDocument().RemoveUnoObject(*this);
285 mpEditSource
.reset();
288 // increment refcount to prevent double call off dtor
289 osl_atomic_increment( &m_refCount
);
291 std::unique_lock
g(aMutex
);
292 if (maRefreshListeners
.getLength(g
))
294 lang::EventObject aEvent
;
295 aEvent
.Source
.set(getXWeak());
296 maRefreshListeners
.disposeAndClear(g
, aEvent
);
300 void ScCellFieldsObj::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
302 if ( rHint
.GetId() == SfxHintId::ScUpdateRef
)
304 //! update of references
306 else if ( rHint
.GetId() == SfxHintId::Dying
)
308 pDocShell
= nullptr; // became invalid
311 // EditSource registered itself as a listener
314 // XIndexAccess (via XTextFields)
316 uno::Reference
<text::XTextField
> ScCellFieldsObj::GetObjectByIndex_Impl(sal_Int32 Index
) const
318 //! Field functions have to be passed to the forwarder !!!
319 ScEditEngineDefaulter
* pEditEngine
= mpEditSource
->GetEditEngine();
320 ScUnoEditEngine
aTempEngine(pEditEngine
);
321 SvxFieldData
* pData
= aTempEngine
.FindByIndex(static_cast<sal_uInt16
>(Index
));
323 return uno::Reference
<text::XTextField
>();
325 sal_Int32 nPar
= aTempEngine
.GetFieldPar();
326 sal_Int32 nPos
= aTempEngine
.GetFieldPos();
327 ESelection
aSelection( nPar
, nPos
, nPar
, nPos
+1 ); // Field size is 1 character
329 sal_Int32 eType
= pData
->GetClassId();
330 uno::Reference
<text::XTextField
> xRet(
331 new ScEditFieldObj(mxContent
, std::make_unique
<ScCellEditSource
>(pDocShell
, aCellPos
), eType
, aSelection
));
335 sal_Int32 SAL_CALL
ScCellFieldsObj::getCount()
337 SolarMutexGuard aGuard
;
339 //! Field functions have to be passed to the forwarder !!!
340 ScEditEngineDefaulter
* pEditEngine
= mpEditSource
->GetEditEngine();
341 ScUnoEditEngine
aTempEngine(pEditEngine
);
343 return aTempEngine
.CountFields(); // count the fields, we don't care about their type in the cell
346 uno::Any SAL_CALL
ScCellFieldsObj::getByIndex( sal_Int32 nIndex
)
348 SolarMutexGuard aGuard
;
349 uno::Reference
<text::XTextField
> xField(GetObjectByIndex_Impl(nIndex
));
351 throw lang::IndexOutOfBoundsException();
353 return uno::Any(xField
);
356 uno::Type SAL_CALL
ScCellFieldsObj::getElementType()
358 return cppu::UnoType
<text::XTextField
>::get();
361 sal_Bool SAL_CALL
ScCellFieldsObj::hasElements()
363 SolarMutexGuard aGuard
;
364 return ( getCount() != 0 );
367 uno::Reference
<container::XEnumeration
> SAL_CALL
ScCellFieldsObj::createEnumeration()
369 SolarMutexGuard aGuard
;
370 return new ScIndexEnumeration(this, u
"com.sun.star.text.TextFieldEnumeration"_ustr
);
373 void SAL_CALL
ScCellFieldsObj::addContainerListener(
374 const uno::Reference
<container::XContainerListener
>& /* xListener */ )
376 OSL_FAIL("not implemented");
379 void SAL_CALL
ScCellFieldsObj::removeContainerListener(
380 const uno::Reference
<container::XContainerListener
>& /* xListener */ )
382 OSL_FAIL("not implemented");
386 void SAL_CALL
ScCellFieldsObj::refresh( )
388 std::unique_lock
g(aMutex
);
389 if (maRefreshListeners
.getLength(g
))
391 // Call all listeners.
392 lang::EventObject aEvent
;
393 aEvent
.Source
.set(uno::Reference
< util::XRefreshable
>(this));
394 maRefreshListeners
.notifyEach( g
, &util::XRefreshListener::refreshed
, aEvent
);
398 void SAL_CALL
ScCellFieldsObj::addRefreshListener( const uno::Reference
< util::XRefreshListener
>& xListener
)
402 std::unique_lock
g(aMutex
);
403 maRefreshListeners
.addInterface(g
, xListener
);
407 void SAL_CALL
ScCellFieldsObj::removeRefreshListener( const uno::Reference
<util::XRefreshListener
>& xListener
)
411 std::unique_lock
g(aMutex
);
412 maRefreshListeners
.removeInterface(g
, xListener
);
416 ScHeaderFieldsObj::ScHeaderFieldsObj(ScHeaderFooterTextData
& rData
) :
419 mpEditSource
.reset( new ScHeaderFooterEditSource(rData
) );
422 ScHeaderFieldsObj::~ScHeaderFieldsObj()
424 mpEditSource
.reset();
426 // increment refcount to prevent double call of dtor
427 osl_atomic_increment( &m_refCount
);
429 std::unique_lock
g(aMutex
);
430 if (maRefreshListeners
.getLength(g
))
432 lang::EventObject aEvent
;
433 aEvent
.Source
= getXWeak();
434 maRefreshListeners
.disposeAndClear(g
, aEvent
);
438 // XIndexAccess (via XTextFields)
440 uno::Reference
<text::XTextField
> ScHeaderFieldsObj::GetObjectByIndex_Impl(sal_Int32 Index
) const
442 //! Field functions have to be passed to the forwarder !!!
443 ScEditEngineDefaulter
* pEditEngine
= mpEditSource
->GetEditEngine();
444 ScUnoEditEngine
aTempEngine(pEditEngine
);
446 SvxFieldData
* pData
= aTempEngine
.FindByIndex(static_cast<sal_uInt16
>(Index
));
450 // Get the parent text range instance.
451 uno::Reference
<text::XTextRange
> xTextRange
;
452 rtl::Reference
<ScHeaderFooterContentObj
> xContentObj
= mrData
.GetContentObj();
453 if (!xContentObj
.is())
454 throw uno::RuntimeException(u
""_ustr
);
456 uno::Reference
<text::XText
> xText
;
458 switch ( mrData
.GetPart() )
460 case ScHeaderFooterPart::LEFT
:
461 xText
= xContentObj
->getLeftText();
463 case ScHeaderFooterPart::CENTER
:
464 xText
= xContentObj
->getCenterText();
466 case ScHeaderFooterPart::RIGHT
:
467 xText
= xContentObj
->getRightText();
473 sal_Int32 nPar
= aTempEngine
.GetFieldPar();
474 sal_Int32 nPos
= aTempEngine
.GetFieldPos();
475 ESelection
aSelection( nPar
, nPos
, nPar
, nPos
+1 ); // Field size is 1 character
477 sal_Int32 eRealType
= pData
->GetClassId();
478 uno::Reference
<text::XTextField
> xRet(
479 new ScEditFieldObj(xTextRange
, std::make_unique
<ScHeaderFooterEditSource
>(mrData
), eRealType
, aSelection
));
483 sal_Int32 SAL_CALL
ScHeaderFieldsObj::getCount()
485 SolarMutexGuard aGuard
;
487 //! Field functions have to be passed to the forwarder !!!
488 ScEditEngineDefaulter
* pEditEngine
= mpEditSource
->GetEditEngine();
489 ScUnoEditEngine
aTempEngine(pEditEngine
);
490 return aTempEngine
.CountFields();
493 uno::Any SAL_CALL
ScHeaderFieldsObj::getByIndex( sal_Int32 nIndex
)
495 SolarMutexGuard aGuard
;
496 uno::Reference
<text::XTextField
> xField(GetObjectByIndex_Impl(nIndex
));
498 throw lang::IndexOutOfBoundsException();
500 return uno::Any(xField
);
503 uno::Type SAL_CALL
ScHeaderFieldsObj::getElementType()
505 return cppu::UnoType
<text::XTextField
>::get();
508 sal_Bool SAL_CALL
ScHeaderFieldsObj::hasElements()
510 SolarMutexGuard aGuard
;
511 return ( getCount() != 0 );
514 uno::Reference
<container::XEnumeration
> SAL_CALL
ScHeaderFieldsObj::createEnumeration()
516 SolarMutexGuard aGuard
;
517 return new ScIndexEnumeration(this, u
"com.sun.star.text.TextFieldEnumeration"_ustr
);
520 void SAL_CALL
ScHeaderFieldsObj::addContainerListener(
521 const uno::Reference
<container::XContainerListener
>& /* xListener */ )
523 OSL_FAIL("not implemented");
526 void SAL_CALL
ScHeaderFieldsObj::removeContainerListener(
527 const uno::Reference
<container::XContainerListener
>& /* xListener */ )
529 OSL_FAIL("not implemented");
533 void SAL_CALL
ScHeaderFieldsObj::refresh( )
535 std::unique_lock
g(aMutex
);
536 if (maRefreshListeners
.getLength(g
))
538 // Call all listeners.
539 lang::EventObject aEvent
;
540 aEvent
.Source
.set(uno::Reference
< util::XRefreshable
>(this));
541 maRefreshListeners
.notifyEach( g
, &util::XRefreshListener::refreshed
, aEvent
);
545 void SAL_CALL
ScHeaderFieldsObj::addRefreshListener( const uno::Reference
< util::XRefreshListener
>& xListener
)
549 std::unique_lock
g(aMutex
);
550 maRefreshListeners
.addInterface(g
, xListener
);
554 void SAL_CALL
ScHeaderFieldsObj::removeRefreshListener( const uno::Reference
<util::XRefreshListener
>& xListener
)
558 std::unique_lock
g(aMutex
);
559 maRefreshListeners
.removeInterface(g
, xListener
);
563 SvxFieldData
& ScEditFieldObj::getData()
569 case text::textfield::Type::DATE
:
570 mpData
.reset(new SvxDateField
);
572 case text::textfield::Type::EXTENDED_FILE
:
574 new SvxExtFileField(OUString(), SvxFileType::Var
, SvxFileFormat::NameAndExt
));
576 case text::textfield::Type::PAGE
:
577 mpData
.reset(new SvxPageField
);
579 case text::textfield::Type::PAGES
:
580 mpData
.reset(new SvxPagesField
);
582 case text::textfield::Type::TABLE
:
583 mpData
.reset(new SvxTableField
);
585 case text::textfield::Type::TIME
:
586 mpData
.reset(new SvxTimeField
);
588 case text::textfield::Type::EXTENDED_TIME
:
591 mpData
.reset(new SvxDateField
);
593 mpData
.reset(new SvxExtTimeField
);
596 case text::textfield::Type::DOCINFO_TITLE
:
597 mpData
.reset(new SvxFileField
);
599 case text::textfield::Type::URL
:
601 new SvxURLField(OUString(), OUString(), SvxURLFormat::AppDefault
));
604 mpData
.reset(new SvxFieldData
);
610 void ScEditFieldObj::setPropertyValueURL(const OUString
& rName
, const css::uno::Any
& rVal
)
615 // Edit engine instance already exists for this field item. Use it.
616 ScEditEngineDefaulter
* pEditEngine
= mpEditSource
->GetEditEngine();
617 ScUnoEditEngine
aTempEngine(pEditEngine
);
619 // don't care about the type (only URLs can be found in the cells)
620 SvxFieldData
* pField
= aTempEngine
.FindByPos(
621 aSelection
.start
, text::textfield::Type::UNSPECIFIED
);
622 OSL_ENSURE(pField
,"setPropertyValue: Field not found");
626 if (pField
->GetClassId() != text::textfield::Type::URL
)
627 // Make sure this is indeed a URL field.
630 SvxURLField
* pURL
= static_cast<SvxURLField
*>(pField
);
632 if (rName
== SC_UNONAME_URL
)
634 if (rVal
>>= aStrVal
)
635 pURL
->SetURL(aStrVal
);
637 else if (rName
== SC_UNONAME_REPR
)
639 if (rVal
>>= aStrVal
)
640 pURL
->SetRepresentation(aStrVal
);
642 else if (rName
== SC_UNONAME_TARGET
)
644 if (rVal
>>= aStrVal
)
645 pURL
->SetTargetFrame(aStrVal
);
648 throw beans::UnknownPropertyException(rName
);
650 pEditEngine
->QuickInsertField( SvxFieldItem(*pField
, EE_FEATURE_FIELD
), aSelection
);
651 mpEditSource
->UpdateData();
655 // Edit engine instance not yet present. Store the item data for later use.
656 SvxURLField
& rData
= static_cast<SvxURLField
&>(getData());
657 if (rName
== SC_UNONAME_URL
)
659 if (rVal
>>= aStrVal
)
660 rData
.SetURL(aStrVal
);
662 else if (rName
== SC_UNONAME_REPR
)
664 if (rVal
>>= aStrVal
)
665 rData
.SetRepresentation(aStrVal
);
667 else if (rName
== SC_UNONAME_TARGET
)
669 if (rVal
>>= aStrVal
)
670 rData
.SetTargetFrame(aStrVal
);
673 throw beans::UnknownPropertyException(rName
);
676 uno::Any
ScEditFieldObj::getPropertyValueURL(const OUString
& rName
)
680 // anchor type is always "as character", text wrap always "none"
684 //! Field functions have to be passed to the forwarder !!!
685 ScEditEngineDefaulter
* pEditEngine
= mpEditSource
->GetEditEngine();
686 ScUnoEditEngine
aTempEngine(pEditEngine
);
688 // don't care about the type (only URLs can be found in the cells)
689 const SvxFieldData
* pField
= aTempEngine
.FindByPos(
690 aSelection
.start
, text::textfield::Type::UNSPECIFIED
);
691 OSL_ENSURE(pField
,"getPropertyValue: Field not found");
693 throw uno::RuntimeException();
695 if (pField
->GetClassId() != text::textfield::Type::URL
)
696 throw uno::RuntimeException();
698 const SvxURLField
* pURL
= static_cast<const SvxURLField
*>(pField
);
700 if (rName
== SC_UNONAME_URL
)
701 aRet
<<= pURL
->GetURL();
702 else if (rName
== SC_UNONAME_REPR
)
703 aRet
<<= pURL
->GetRepresentation();
704 else if (rName
== SC_UNONAME_TARGET
)
705 aRet
<<= pURL
->GetTargetFrame();
707 throw beans::UnknownPropertyException(rName
);
709 else // not inserted yet
711 const SvxURLField
& rURL
= static_cast<const SvxURLField
&>(getData());
713 if (rName
== SC_UNONAME_URL
)
714 aRet
<<= rURL
.GetURL();
715 else if (rName
== SC_UNONAME_REPR
)
716 aRet
<<= rURL
.GetRepresentation();
717 else if (rName
== SC_UNONAME_TARGET
)
718 aRet
<<= rURL
.GetTargetFrame();
720 throw beans::UnknownPropertyException(rName
);
725 void ScEditFieldObj::setPropertyValueFile(const OUString
& rName
, const uno::Any
& rVal
)
727 if (rName
!= SC_UNONAME_FILEFORM
)
728 throw beans::UnknownPropertyException(rName
);
730 sal_Int16 nIntVal
= 0;
731 if (!(rVal
>>= nIntVal
))
734 SvxFileFormat eFormat
= lcl_UnoToSvxFileFormat(nIntVal
);
737 ScEditEngineDefaulter
* pEditEngine
= mpEditSource
->GetEditEngine();
738 ScUnoEditEngine
aTempEngine(pEditEngine
);
739 SvxFieldData
* pField
= aTempEngine
.FindByPos(
740 aSelection
.start
, text::textfield::Type::EXTENDED_FILE
);
741 OSL_ENSURE(pField
, "setPropertyValueFile: Field not found");
744 SvxExtFileField
* pExtFile
= static_cast<SvxExtFileField
*>(pField
); // local to the ScUnoEditEngine
745 pExtFile
->SetFormat(eFormat
);
746 pEditEngine
->QuickInsertField(SvxFieldItem(*pField
, EE_FEATURE_FIELD
), aSelection
);
747 mpEditSource
->UpdateData();
752 SvxExtFileField
& rExtFile
= static_cast<SvxExtFileField
&>(getData());
753 rExtFile
.SetFormat(eFormat
);
758 uno::Any
ScEditFieldObj::getPropertyValueFile(const OUString
& rName
)
761 if (rName
!= SC_UNONAME_FILEFORM
)
762 throw beans::UnknownPropertyException(rName
);
764 SvxFileFormat eFormat
= SvxFileFormat::NameAndExt
;
765 const SvxFieldData
* pField
= nullptr;
768 ScEditEngineDefaulter
* pEditEngine
= mpEditSource
->GetEditEngine();
769 ScUnoEditEngine
aTempEngine(pEditEngine
);
770 pField
= aTempEngine
.FindByPos(
771 aSelection
.start
, text::textfield::Type::EXTENDED_FILE
);
776 OSL_ENSURE(pField
, "setPropertyValueFile: Field not found");
778 throw uno::RuntimeException();
780 const SvxExtFileField
* pExtFile
= static_cast<const SvxExtFileField
*>(pField
);
781 eFormat
= pExtFile
->GetFormat();
782 sal_Int16 nIntVal
= lcl_SvxToUnoFileFormat(eFormat
);
788 void ScEditFieldObj::setPropertyValueDateTime(const OUString
& rName
, const uno::Any
& rVal
)
792 // Field already inserted.
793 ScEditEngineDefaulter
* pEditEngine
= mpEditSource
->GetEditEngine();
794 ScUnoEditEngine
aTempEngine(pEditEngine
);
795 SvxFieldData
* pField
= aTempEngine
.FindByPos(aSelection
.start
, meType
);
801 case text::textfield::Type::DATE
:
803 SvxDateField
* p
= static_cast<SvxDateField
*>(pField
);
804 if (rName
== SC_UNONAME_ISDATE
)
806 // Do nothing for now.
808 else if (rName
== SC_UNONAME_ISFIXED
)
810 SvxDateType eType
= rVal
.get
<bool>() ? SvxDateType::Fix
: SvxDateType::Var
;
813 else if (rName
== SC_UNONAME_DATETIME
)
815 maDateTime
= rVal
.get
<util::DateTime
>();
816 Date
aDate(maDateTime
.Day
, maDateTime
.Month
, maDateTime
.Year
);
817 p
->SetFixDate(aDate
);
819 else if (rName
== SC_UNONAME_NUMFMT
)
821 mnNumFormat
= rVal
.get
<sal_Int32
>();
822 p
->SetFormat(static_cast<SvxDateFormat
>(mnNumFormat
));
825 throw beans::UnknownPropertyException(rName
);
828 case text::textfield::Type::TIME
:
830 // SvxTimeField doesn't have any attributes.
831 if (rName
!= SC_UNONAME_ISDATE
&& rName
!= SC_UNONAME_ISFIXED
&&
832 rName
!= SC_UNONAME_DATETIME
&& rName
!= SC_UNONAME_NUMFMT
)
833 throw beans::UnknownPropertyException(rName
);
836 case text::textfield::Type::EXTENDED_TIME
:
838 SvxExtTimeField
* p
= static_cast<SvxExtTimeField
*>(pField
);
839 if (rName
== SC_UNONAME_ISDATE
)
841 // Do nothing for now.
843 else if (rName
== SC_UNONAME_ISFIXED
)
845 SvxTimeType eType
= rVal
.get
<bool>() ? SvxTimeType::Fix
: SvxTimeType::Var
;
848 else if (rName
== SC_UNONAME_DATETIME
)
850 maDateTime
= rVal
.get
<util::DateTime
>();
851 tools::Time
aTime(maDateTime
);
852 p
->SetFixTime(aTime
);
854 else if (rName
== SC_UNONAME_NUMFMT
)
856 mnNumFormat
= rVal
.get
<sal_Int32
>();
857 p
->SetFormat(static_cast<SvxTimeFormat
>(mnNumFormat
));
860 throw beans::UnknownPropertyException(rName
);
864 throw beans::UnknownPropertyException(rName
);
869 if (rName
== SC_UNONAME_ISDATE
)
870 mbIsDate
= rVal
.get
<bool>();
871 else if (rName
== SC_UNONAME_ISFIXED
)
872 mbIsFixed
= rVal
.get
<bool>();
873 else if (rName
== SC_UNONAME_DATETIME
)
874 maDateTime
= rVal
.get
<util::DateTime
>();
875 else if (rName
== SC_UNONAME_NUMFMT
)
876 mnNumFormat
= rVal
.get
<sal_Int32
>();
878 throw beans::UnknownPropertyException(rName
);
882 uno::Any
ScEditFieldObj::getPropertyValueDateTime(const OUString
& rName
)
886 // Field already inserted.
887 ScEditEngineDefaulter
* pEditEngine
= mpEditSource
->GetEditEngine();
888 ScUnoEditEngine
aTempEngine(pEditEngine
);
889 SvxFieldData
* pField
= aTempEngine
.FindByPos(aSelection
.start
, meType
);
891 throw uno::RuntimeException();
895 case text::textfield::Type::DATE
:
897 SvxDateField
* p
= static_cast<SvxDateField
*>(pField
);
898 if (rName
== SC_UNONAME_ISDATE
)
899 return uno::Any(true);
901 if (rName
== SC_UNONAME_ISFIXED
)
902 return uno::Any(p
->GetType() == SvxDateType::Fix
);
904 if (rName
== SC_UNONAME_DATETIME
)
906 Date
aD(p
->GetFixDate());
907 maDateTime
.Year
= aD
.GetYear();
908 maDateTime
.Month
= aD
.GetMonth();
909 maDateTime
.Day
= aD
.GetDay();
910 maDateTime
.Hours
= 0;
911 maDateTime
.Minutes
= 0;
912 maDateTime
.Seconds
= 0;
913 maDateTime
.NanoSeconds
= 0;
914 return uno::Any(maDateTime
);
917 if (rName
== SC_UNONAME_NUMFMT
)
918 return uno::Any(static_cast<sal_Int32
>(p
->GetFormat()));
921 case text::textfield::Type::TIME
:
923 // SvxTimeField doesn't have any attributes.
924 if (rName
== SC_UNONAME_ISDATE
)
925 return uno::Any(false);
927 if (rName
== SC_UNONAME_ISFIXED
)
928 return uno::Any(false);
930 if (rName
== SC_UNONAME_DATETIME
)
931 // This is the best we can do.
932 return uno::Any(maDateTime
);
934 if (rName
== SC_UNONAME_NUMFMT
)
936 return uno::Any(sal_Int32(0));
939 case text::textfield::Type::EXTENDED_TIME
:
941 SvxExtTimeField
* p
= static_cast<SvxExtTimeField
*>(pField
);
942 if (rName
== SC_UNONAME_ISDATE
)
943 return uno::Any(false);
945 if (rName
== SC_UNONAME_ISFIXED
)
946 return uno::Any(p
->GetType() == SvxTimeType::Fix
);
948 if (rName
== SC_UNONAME_DATETIME
)
950 tools::Time
aT(tools::Time::fromEncodedTime(p
->GetFixTime()));
952 maDateTime
.Month
= 0;
954 maDateTime
.Hours
= aT
.GetHour();
955 maDateTime
.Minutes
= aT
.GetMin();
956 maDateTime
.Seconds
= aT
.GetSec();
957 maDateTime
.NanoSeconds
= aT
.GetNanoSec();
958 return uno::Any(maDateTime
);
961 if (rName
== SC_UNONAME_NUMFMT
)
962 return uno::Any(static_cast<sal_Int32
>(p
->GetFormat()));
971 if (rName
== SC_UNONAME_ISDATE
)
972 return uno::Any(mbIsDate
);
974 if (rName
== SC_UNONAME_ISFIXED
)
975 return uno::Any(mbIsFixed
);
977 if (rName
== SC_UNONAME_DATETIME
)
978 return uno::Any(maDateTime
);
980 if (rName
== SC_UNONAME_NUMFMT
)
981 return uno::Any(mnNumFormat
);
984 throw beans::UnknownPropertyException(rName
);
987 void ScEditFieldObj::setPropertyValueSheet(const OUString
& rName
, const uno::Any
& rVal
)
991 // Edit engine instance already exists for this field item. Use it.
992 ScEditEngineDefaulter
* pEditEngine
= mpEditSource
->GetEditEngine();
993 ScUnoEditEngine
aTempEngine(pEditEngine
);
995 // don't care about the type (only URLs can be found in the cells)
996 SvxFieldData
* pField
= aTempEngine
.FindByPos(
997 aSelection
.start
, text::textfield::Type::UNSPECIFIED
);
998 OSL_ENSURE(pField
,"setPropertyValue: Field not found");
1002 if (pField
->GetClassId() != text::textfield::Type::TABLE
)
1003 // Make sure this is indeed a URL field.
1006 SvxTableField
* p
= static_cast<SvxTableField
*>(pField
);
1008 if (rName
!= SC_UNONAME_TABLEPOS
)
1009 throw beans::UnknownPropertyException(rName
);
1011 sal_Int32 nTab
= rVal
.get
<sal_Int32
>();
1015 pEditEngine
->QuickInsertField(SvxFieldItem(*pField
, EE_FEATURE_FIELD
), aSelection
);
1016 mpEditSource
->UpdateData();
1020 // Edit engine instance not yet present. Store the item data for later use.
1021 SvxTableField
& r
= static_cast<SvxTableField
&>(getData());
1022 if (rName
!= SC_UNONAME_TABLEPOS
)
1023 throw beans::UnknownPropertyException(rName
);
1025 sal_Int32 nTab
= rVal
.get
<sal_Int32
>();
1029 ScEditFieldObj::ScEditFieldObj(
1030 uno::Reference
<text::XTextRange
> xContent
,
1031 std::unique_ptr
<ScEditSource
> pEditSrc
, sal_Int32 eType
, const ESelection
& rSel
) :
1033 mpEditSource(std::move(pEditSrc
)),
1035 meType(eType
), mpContent(std::move(xContent
)), mnNumFormat(0), mbIsDate(false), mbIsFixed(false)
1039 case text::textfield::Type::DOCINFO_TITLE
:
1040 pPropSet
= getEmptyPropertySet();
1042 case text::textfield::Type::EXTENDED_FILE
:
1043 pPropSet
= lcl_GetFileFieldPropertySet();
1045 case text::textfield::Type::URL
:
1046 pPropSet
= lcl_GetURLPropertySet();
1048 case text::textfield::Type::DATE
:
1049 case text::textfield::Type::TIME
:
1050 case text::textfield::Type::EXTENDED_TIME
:
1051 pPropSet
= getDateTimePropertySet();
1054 pPropSet
= lcl_GetHeaderFieldPropertySet();
1057 if (meType
== text::textfield::Type::DATE
)
1061 void ScEditFieldObj::InitDoc(
1062 const uno::Reference
<text::XTextRange
>& rContent
, std::unique_ptr
<ScEditSource
> pEditSrc
, const ESelection
& rSel
)
1066 mpContent
= rContent
;
1070 mpEditSource
= std::move( pEditSrc
);
1074 ScEditFieldObj::~ScEditFieldObj()
1078 SvxFieldItem
ScEditFieldObj::CreateFieldItem()
1080 OSL_ENSURE( !mpEditSource
, "CreateFieldItem with inserted field" );
1081 return SvxFieldItem(getData(), EE_FEATURE_FIELD
);
1084 void ScEditFieldObj::DeleteField()
1088 SvxTextForwarder
* pForwarder
= mpEditSource
->GetTextForwarder();
1089 pForwarder
->QuickInsertText( OUString(), aSelection
);
1090 mpEditSource
->UpdateData();
1092 aSelection
.CollapseToStart();
1094 //! Broadcast in order to adjust selection in other objects
1095 //! (also for other actions)
1099 bool ScEditFieldObj::IsInserted() const
1101 return mpEditSource
!= nullptr;
1106 OUString SAL_CALL
ScEditFieldObj::getPresentation( sal_Bool bShowCommand
)
1108 SolarMutexGuard aGuard
;
1113 //! Field functions have to be passed to the forwarder !!!
1114 ScEditEngineDefaulter
* pEditEngine
= mpEditSource
->GetEditEngine();
1115 ScUnoEditEngine
aTempEngine(pEditEngine
);
1117 // don't care about the type (only URLs can be found in the cells)
1118 const SvxFieldData
* pField
= aTempEngine
.FindByPos(
1119 aSelection
.start
, text::textfield::Type::UNSPECIFIED
);
1120 OSL_ENSURE(pField
,"getPresentation: Field not found");
1126 case text::textfield::Type::URL
:
1128 if (pField
->GetClassId() != text::textfield::Type::URL
)
1129 // Not a URL field, but URL is expected.
1130 throw uno::RuntimeException();
1132 const SvxURLField
* pURL
= static_cast<const SvxURLField
*>(pField
);
1133 return bShowCommand
? pURL
->GetURL() : pURL
->GetRepresentation();
1144 void SAL_CALL
ScEditFieldObj::attach( const uno::Reference
<text::XTextRange
>& xTextRange
)
1146 SolarMutexGuard aGuard
;
1147 if (xTextRange
.is())
1149 uno::Reference
<text::XText
> xText(xTextRange
->getText());
1152 xText
->insertTextContent( xTextRange
, this, true );
1157 uno::Reference
<text::XTextRange
> SAL_CALL
ScEditFieldObj::getAnchor()
1159 SolarMutexGuard aGuard
;
1165 uno::Reference
<beans::XPropertySetInfo
> SAL_CALL
ScEditFieldObj::getPropertySetInfo()
1167 SolarMutexGuard aGuard
;
1168 uno::Reference
<beans::XPropertySetInfo
> aRef
= pPropSet
->getPropertySetInfo();
1172 void SAL_CALL
ScEditFieldObj::setPropertyValue(
1173 const OUString
& aPropertyName
, const uno::Any
& aValue
)
1175 SolarMutexGuard aGuard
;
1176 if (aPropertyName
== SC_UNONAME_ANCHOR
)
1178 aValue
>>= mpContent
;
1184 case text::textfield::Type::URL
:
1185 setPropertyValueURL(aPropertyName
, aValue
);
1187 case text::textfield::Type::EXTENDED_FILE
:
1188 setPropertyValueFile(aPropertyName
, aValue
);
1190 case text::textfield::Type::DATE
:
1191 case text::textfield::Type::TIME
:
1192 case text::textfield::Type::EXTENDED_TIME
:
1193 setPropertyValueDateTime(aPropertyName
, aValue
);
1195 case text::textfield::Type::TABLE
:
1196 setPropertyValueSheet(aPropertyName
, aValue
);
1198 case text::textfield::Type::DOCINFO_TITLE
:
1200 throw beans::UnknownPropertyException(OUString::number(meType
));
1204 uno::Any SAL_CALL
ScEditFieldObj::getPropertyValue( const OUString
& aPropertyName
)
1206 SolarMutexGuard aGuard
;
1207 if (aPropertyName
== SC_UNONAME_TEXTFIELD_TYPE
)
1208 return uno::Any(meType
);
1210 if (aPropertyName
== SC_UNONAME_ANCHOR
)
1211 return uno::Any(mpContent
);
1213 if (aPropertyName
== SC_UNONAME_ANCTYPE
)
1216 aRet
<<= text::TextContentAnchorType_AS_CHARACTER
;
1219 if (aPropertyName
== SC_UNONAME_ANCTYPES
)
1222 uno::Sequence
<text::TextContentAnchorType
> aSeq
{ text::TextContentAnchorType_AS_CHARACTER
};
1226 if (aPropertyName
== SC_UNONAME_TEXTWRAP
)
1229 aRet
<<= text::WrapTextMode_NONE
;
1235 case text::textfield::Type::URL
:
1236 return getPropertyValueURL(aPropertyName
);
1237 case text::textfield::Type::EXTENDED_FILE
:
1238 return getPropertyValueFile(aPropertyName
);
1239 case text::textfield::Type::DATE
:
1240 case text::textfield::Type::TIME
:
1241 case text::textfield::Type::EXTENDED_TIME
:
1242 return getPropertyValueDateTime(aPropertyName
);
1243 case text::textfield::Type::DOCINFO_TITLE
:
1245 throw beans::UnknownPropertyException(OUString::number(meType
));
1249 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScEditFieldObj
)
1253 OUString SAL_CALL
ScEditFieldObj::getImplementationName()
1255 return u
"ScEditFieldObj"_ustr
;
1258 sal_Bool SAL_CALL
ScEditFieldObj::supportsService( const OUString
& rServiceName
)
1260 return cppu::supportsService(this, rServiceName
);
1263 uno::Sequence
<OUString
> SAL_CALL
ScEditFieldObj::getSupportedServiceNames()
1265 return {u
"com.sun.star.text.TextField"_ustr
,
1266 u
"com.sun.star.text.TextContent"_ustr
};
1269 uno::Sequence
<uno::Type
> SAL_CALL
ScEditFieldObj::getTypes()
1271 return comphelper::concatSequences(
1272 ScEditFieldObj_Base::getTypes(),
1273 uno::Sequence
<uno::Type
>
1275 cppu::UnoType
<text::XTextField
>::get(),
1276 cppu::UnoType
<beans::XPropertySet
>::get(),
1277 cppu::UnoType
<lang::XUnoTunnel
>::get(),
1278 cppu::UnoType
<lang::XServiceInfo
>::get()
1282 uno::Sequence
<sal_Int8
> SAL_CALL
ScEditFieldObj::getImplementationId()
1284 return css::uno::Sequence
<sal_Int8
>();
1287 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */