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 .
23 * export of all variable related text fields (and database display field)
25 #include <txtvfldi.hxx>
26 #include <xmloff/xmltoken.hxx>
27 #include <xmloff/txtimp.hxx>
28 #include <xmloff/xmlnamespace.hxx>
29 #include <xmloff/namespacemap.hxx>
30 #include <xmloff/i18nmap.hxx>
31 #include <xmloff/xmlimp.hxx>
32 #include <xmloff/xmluconv.hxx>
33 #include <xmloff/xmlement.hxx>
34 #include <com/sun/star/frame/XModel.hpp>
35 #include <com/sun/star/text/SetVariableType.hpp>
36 #include <com/sun/star/text/XDependentTextField.hpp>
37 #include <com/sun/star/text/XTextFieldsSupplier.hpp>
38 #include <com/sun/star/beans/XPropertySet.hpp>
39 #include <com/sun/star/beans/XPropertySetInfo.hpp>
40 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
41 #include <com/sun/star/xml/sax/XAttributeList.hpp>
42 #include <com/sun/star/style/NumberingType.hpp>
43 #include <com/sun/star/container/XIndexReplace.hpp>
45 #include <sax/tools/converter.hxx>
47 #include <rtl/ustring.hxx>
48 #include <osl/diagnose.h>
49 #include <sal/log.hxx>
51 #include <tools/debug.hxx>
52 #include <tools/diagnose_ex.h>
56 constexpr char16_t sAPI_fieldmaster_prefix
[] = u
"com.sun.star.text.FieldMaster.";
57 constexpr OUStringLiteral sAPI_get_expression
= u
"GetExpression";
58 constexpr OUStringLiteral sAPI_set_expression
= u
"SetExpression";
59 constexpr OUStringLiteral sAPI_user
= u
"User";
60 constexpr OUStringLiteral sAPI_database
= u
"com.sun.star.text.TextField.Database";
63 constexpr OUStringLiteral sAPI_content
= u
"Content";
64 constexpr OUStringLiteral sAPI_sub_type
= u
"SubType";
65 constexpr OUStringLiteral sAPI_number_format
= u
"NumberFormat";
66 constexpr OUStringLiteral sAPI_is_visible
= u
"IsVisible";
67 constexpr OUStringLiteral sAPI_current_presentation
= u
"CurrentPresentation";
70 using namespace ::com::sun::star
;
71 using namespace ::com::sun::star::uno
;
72 using namespace ::com::sun::star::beans
;
73 using namespace ::com::sun::star::text
;
74 using namespace ::com::sun::star::style
;
75 using namespace ::xmloff::token
;
78 // XMLVarFieldImportContext: superclass for all variable related fields
81 XMLVarFieldImportContext::XMLVarFieldImportContext(
82 SvXMLImport
& rImport
, XMLTextImportHelper
& rHlp
,
83 const OUString
& pServiceName
,
84 bool bFormula
, bool bFormulaDefault
,
85 bool bDescription
, bool bHelp
, bool bHint
, bool bVisible
,
86 bool bIsDisplayFormula
,
87 bool bType
, bool bStyle
, bool bValue
,
89 XMLTextFieldImportContext(rImport
, rHlp
, pServiceName
),
90 aValueHelper(rImport
, rHlp
, bType
, bStyle
, bValue
, false),
91 bDisplayFormula(false),
94 bDescriptionOK(false),
98 bSetFormula(bFormula
),
99 bSetFormulaDefault(bFormulaDefault
),
100 bSetDescription(bDescription
),
103 bSetVisible(bVisible
),
104 bSetDisplayFormula(bIsDisplayFormula
),
105 bSetPresentation(bPresentation
)
109 void XMLVarFieldImportContext::ProcessAttribute(
110 sal_Int32 nAttrToken
,
111 std::string_view sAttrValue
)
115 case XML_ELEMENT(TEXT
, XML_NAME
):
116 sName
= OUString::fromUtf8(sAttrValue
);
117 bValid
= true; // we assume: field with name is valid!
119 case XML_ELEMENT(TEXT
, XML_DESCRIPTION
):
120 sDescription
= OUString::fromUtf8(sAttrValue
);
121 bDescriptionOK
= true;
123 case XML_ELEMENT(TEXT
, XML_HELP
):
124 sHelp
= OUString::fromUtf8(sAttrValue
);
127 case XML_ELEMENT(TEXT
, XML_HINT
):
128 sHint
= OUString::fromUtf8(sAttrValue
);
131 case XML_ELEMENT(TEXT
, XML_FORMULA
):
134 sal_uInt16 nPrefix
= GetImport().GetNamespaceMap().
135 GetKeyByAttrValueQName(OUString::fromUtf8(sAttrValue
), &sTmp
);
136 if( XML_NAMESPACE_OOOW
== nPrefix
)
142 sFormula
= OUString::fromUtf8(sAttrValue
);
145 case XML_ELEMENT(TEXT
, XML_DISPLAY
):
146 if (IsXMLToken(sAttrValue
, XML_FORMULA
))
148 bDisplayFormula
= true;
149 bDisplayNone
= false;
152 else if (IsXMLToken(sAttrValue
, XML_VALUE
))
154 bDisplayFormula
= false;
155 bDisplayNone
= false;
158 else if (IsXMLToken(sAttrValue
, XML_NONE
))
160 bDisplayFormula
= false;
164 DBG_ASSERT(!(bDisplayFormula
&& bDisplayNone
),
165 "illegal display values");
168 // delegate all others to value helper
169 aValueHelper
.ProcessAttribute(nAttrToken
, sAttrValue
);
174 void XMLVarFieldImportContext::PrepareField(
175 const Reference
<XPropertySet
> & xPropertySet
)
177 // bSetName: not implemented
181 if (!bFormulaOK
&& bSetFormulaDefault
)
183 sFormula
= GetContent();
189 xPropertySet
->setPropertyValue(sAPI_content
, Any(sFormula
));
193 if (bSetDescription
&& bDescriptionOK
)
195 xPropertySet
->setPropertyValue("Hint", Any(sDescription
));
198 if (bSetHelp
&& bHelpOK
)
200 xPropertySet
->setPropertyValue("Help", Any(sHelp
));
203 if (bSetHint
&& bHintOK
)
205 xPropertySet
->setPropertyValue("Tooltip", Any(sHint
));
208 if (bSetVisible
&& bDisplayOK
)
210 bool bTmp
= !bDisplayNone
;
211 xPropertySet
->setPropertyValue(sAPI_is_visible
, Any(bTmp
));
214 // workaround for #no-bug#: display formula by default
215 if (xPropertySet
->getPropertySetInfo()->
216 hasPropertyByName("IsShowFormula") &&
219 bDisplayFormula
= false;
220 bSetDisplayFormula
= true;
224 if (bSetDisplayFormula
)
226 bool bTmp
= bDisplayFormula
&& bDisplayOK
;
227 xPropertySet
->setPropertyValue("IsShowFormula", Any(bTmp
));
230 // delegate to value helper
231 aValueHelper
.SetDefault(GetContent());
232 aValueHelper
.PrepareField(xPropertySet
);
234 // finally, set the current presentation
235 if (bSetPresentation
)
238 aAny
<<= GetContent();
239 xPropertySet
->setPropertyValue(sAPI_current_presentation
, aAny
);
244 // variable set fields
247 XMLSetVarFieldImportContext::XMLSetVarFieldImportContext(
248 SvXMLImport
& rImport
, XMLTextImportHelper
& rHlp
,
249 const OUString
& pServiceName
, VarType eVarType
,
250 bool bFormula
, bool bFormulaDefault
,
251 bool bDescription
, bool bHelp
, bool bHint
, bool bVisible
, bool bIsDisplayFormula
,
252 bool bType
, bool bStyle
, bool bValue
, bool bPresentation
) :
253 XMLVarFieldImportContext(rImport
, rHlp
, pServiceName
,
254 bFormula
, bFormulaDefault
,
255 bDescription
, bHelp
, bHint
, bVisible
, bIsDisplayFormula
,
256 bType
, bStyle
, bValue
, bPresentation
),
261 void XMLSetVarFieldImportContext::endFastElement(sal_Int32
)
263 // should we call PrepareField on the field, or rather on it's master?
264 // currently: call on field (just like superclass)
265 // possible alternatives: call on master
266 // call field or master depending on variable
267 // PrepareMaster() in addition to PrepareField()
269 DBG_ASSERT(!GetServiceName().isEmpty(), "no service name for element!");
273 DBG_ASSERT(!GetName().isEmpty(), "variable name needed!");
276 Reference
<XPropertySet
> xMaster
;
277 if (FindFieldMaster(xMaster
))
279 // create field/Service
280 Reference
<XPropertySet
> xPropSet
;
281 if (CreateField(xPropSet
, "com.sun.star.text.TextField." + GetServiceName()))
283 Reference
<XDependentTextField
> xDepTextField(xPropSet
, UNO_QUERY
);
284 if (xDepTextField
.is())
286 // attach field to field master
287 xDepTextField
->attachTextFieldMaster(xMaster
);
289 // attach field to document
290 Reference
<XTextContent
> xTextContent(xPropSet
, UNO_QUERY
);
291 if (xTextContent
.is())
294 // insert, set field properties and exit!
295 GetImportHelper().InsertTextContent(xTextContent
);
296 PrepareField(xPropSet
);
297 } catch (lang::IllegalArgumentException
& /*e*/)
299 // ignore e: #i54023#
308 // above: exit on success; so for all error cases we end up here!
309 // write element content
310 GetImportHelper().InsertString(GetContent());
313 bool XMLSetVarFieldImportContext::FindFieldMaster(
314 Reference
<XPropertySet
> & xMaster
)
316 // currently: delegate to XMLVariableDeclImportContext;
317 // should eventually go here
318 return XMLVariableDeclImportContext::FindFieldMaster(xMaster
,
329 XMLSequenceFieldImportContext::XMLSequenceFieldImportContext(
330 SvXMLImport
& rImport
, XMLTextImportHelper
& rHlp
) :
331 XMLSetVarFieldImportContext(rImport
, rHlp
, sAPI_set_expression
,
335 false, false, false, false,
337 false, false, false, true),
339 sNumFormat(OUString('1')),
340 sNumFormatSync(GetXMLToken(XML_FALSE
)),
345 void XMLSequenceFieldImportContext::ProcessAttribute(
346 sal_Int32 nAttrToken
, std::string_view sAttrValue
)
350 case XML_ELEMENT(STYLE
, XML_NUM_FORMAT
):
351 sNumFormat
= OUString::fromUtf8(sAttrValue
);
353 case XML_ELEMENT(STYLE
, XML_NUM_LETTER_SYNC
):
354 sNumFormatSync
= OUString::fromUtf8(sAttrValue
);
356 case XML_ELEMENT(TEXT
, XML_REF_NAME
):
357 sRefName
= OUString::fromUtf8(sAttrValue
);
361 // delegate to super class (name, formula)
362 XMLSetVarFieldImportContext::ProcessAttribute(nAttrToken
,
368 void XMLSequenceFieldImportContext::PrepareField(
369 const Reference
<XPropertySet
> & xPropertySet
)
371 // delegate to super class (formula)
372 XMLSetVarFieldImportContext::PrepareField(xPropertySet
);
375 sal_Int16 nNumType
= NumberingType::ARABIC
;
376 GetImport().GetMM100UnitConverter().convertNumFormat( nNumType
, sNumFormat
, sNumFormatSync
);
377 xPropertySet
->setPropertyValue(sAPI_number_format
, Any(nNumType
));
379 // handle reference name
382 Any aAny
= xPropertySet
->getPropertyValue("SequenceValue");
383 sal_Int16 nValue
= 0;
385 GetImportHelper().InsertSequenceID(sRefName
, GetName(), nValue
);
390 // variable set field
393 XMLVariableSetFieldImportContext::XMLVariableSetFieldImportContext(
394 SvXMLImport
& rImport
, XMLTextImportHelper
& rHlp
) :
395 XMLSetVarFieldImportContext(rImport
, rHlp
, sAPI_set_expression
,
397 // formula, value&type, style,
407 void XMLVariableSetFieldImportContext::PrepareField(
408 const Reference
<XPropertySet
> & xPropertySet
)
412 aAny
<<= (IsStringValue()? SetVariableType::STRING
: SetVariableType::VAR
);
413 xPropertySet
->setPropertyValue(sAPI_sub_type
, aAny
);
415 // the remainder is handled by super class
416 XMLSetVarFieldImportContext::PrepareField(xPropertySet
);
420 // variable input field
423 XMLVariableInputFieldImportContext::XMLVariableInputFieldImportContext(
424 SvXMLImport
& rImport
, XMLTextImportHelper
& rHlp
) :
425 XMLSetVarFieldImportContext(rImport
, rHlp
, sAPI_set_expression
,
427 // description, display none/formula,
428 // value&type, style, formula
437 void XMLVariableInputFieldImportContext::PrepareField(
438 const Reference
<XPropertySet
> & xPropertySet
)
440 // set type (input field)
442 xPropertySet
->setPropertyValue("Input", Any(true));
445 aAny
<<= (IsStringValue()? SetVariableType::STRING
: SetVariableType::VAR
);
446 xPropertySet
->setPropertyValue(sAPI_sub_type
, aAny
);
448 // the remainder is handled by super class
449 XMLSetVarFieldImportContext::PrepareField(xPropertySet
);
456 XMLUserFieldImportContext::XMLUserFieldImportContext(
457 SvXMLImport
& rImport
, XMLTextImportHelper
& rHlp
) :
458 XMLSetVarFieldImportContext(rImport
, rHlp
, sAPI_user
,
460 // display none/formula, style
462 false, false, false, true,
473 // bug: doesn't work (SO API lacking)
474 XMLUserFieldInputImportContext::XMLUserFieldInputImportContext(
475 SvXMLImport
& rImport
, XMLTextImportHelper
& rHlp
) :
476 XMLVarFieldImportContext(rImport
, rHlp
, "InputUser",
477 // description, style
481 false /*???*/, true, false,
486 void XMLUserFieldInputImportContext::PrepareField(
487 const Reference
<XPropertySet
> & xPropertySet
)
489 xPropertySet
->setPropertyValue(sAPI_content
, Any(GetName()));
491 // delegate to super class
492 XMLVarFieldImportContext::PrepareField(xPropertySet
);
496 // variable get field
499 XMLVariableGetFieldImportContext::XMLVariableGetFieldImportContext(
500 SvXMLImport
& rImport
, XMLTextImportHelper
& rHlp
) :
501 XMLVarFieldImportContext(rImport
, rHlp
, sAPI_get_expression
,
502 // style, display formula
511 void XMLVariableGetFieldImportContext::PrepareField(
512 const Reference
<XPropertySet
> & xPropertySet
)
515 xPropertySet
->setPropertyValue(sAPI_content
, Any(GetName()));
517 // the remainder is handled by super class
518 XMLVarFieldImportContext::PrepareField(xPropertySet
);
525 XMLExpressionFieldImportContext::XMLExpressionFieldImportContext(
526 SvXMLImport
& rImport
, XMLTextImportHelper
& rHlp
) :
527 XMLVarFieldImportContext(rImport
, rHlp
, sAPI_get_expression
,
528 // formula, type, style, display formula
535 bValid
= true; // always valid
539 void XMLExpressionFieldImportContext::PrepareField(
540 const Reference
<XPropertySet
> & xPropertySet
)
542 xPropertySet
->setPropertyValue(sAPI_sub_type
, Any(sal_Int16(SetVariableType::FORMULA
)));
544 // delegate to super class
545 XMLVarFieldImportContext::PrepareField(xPropertySet
);
552 XMLTextInputFieldImportContext::XMLTextInputFieldImportContext(
553 SvXMLImport
& rImport
, XMLTextImportHelper
& rHlp
) :
554 XMLVarFieldImportContext(rImport
, rHlp
, "Input",
562 bValid
= true; // always valid
565 void XMLTextInputFieldImportContext::PrepareField(
566 const Reference
<XPropertySet
> & xPropertySet
)
568 XMLVarFieldImportContext::PrepareField(xPropertySet
);
570 xPropertySet
->setPropertyValue(sAPI_content
, Any(GetContent()));
574 // table formula field
577 XMLTableFormulaImportContext::XMLTableFormulaImportContext(
578 SvXMLImport
& rImport
,
579 XMLTextImportHelper
& rHlp
) :
580 XMLTextFieldImportContext(rImport
, rHlp
, "TableFormula"),
581 aValueHelper(rImport
, rHlp
, false, true, false, true),
582 bIsShowFormula(false)
586 void XMLTableFormulaImportContext::ProcessAttribute(
587 sal_Int32 nAttrToken
,
588 std::string_view sAttrValue
)
592 case XML_ELEMENT(TEXT
, XML_FORMULA
):
593 aValueHelper
.ProcessAttribute( nAttrToken
, sAttrValue
);
594 bValid
= true; // we need a formula!
597 case XML_ELEMENT(STYLE
, XML_DATA_STYLE_NAME
):
598 aValueHelper
.ProcessAttribute( nAttrToken
, sAttrValue
);
600 case XML_ELEMENT(TEXT
, XML_DISPLAY
):
601 if ( sAttrValue
== "formula" )
602 bIsShowFormula
= true;
605 // unknown attribute -> ignore
606 XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken
, sAttrValue
);
611 void XMLTableFormulaImportContext::PrepareField(
612 const Reference
<XPropertySet
> & xPropertySet
)
614 // set format and formula
615 aValueHelper
.PrepareField( xPropertySet
);
619 // set 'show formula' and presentation
620 xPropertySet
->setPropertyValue( "IsShowFormula", Any(bIsShowFormula
) );
622 aAny
<<= GetContent();
623 xPropertySet
->setPropertyValue( "CurrentPresentation", aAny
);
627 // variable declarations
629 // Should be adapted to XMLVarField-/XMLSetVarFieldImportContext scheme!
632 // declaration container import (<variable/user-field/sequence-decls>)
635 XMLVariableDeclsImportContext::XMLVariableDeclsImportContext(
636 SvXMLImport
& rImport
, XMLTextImportHelper
& rHlp
, enum VarType eVarType
) :
637 SvXMLImportContext(rImport
),
638 eVarDeclsContextType(eVarType
),
643 css::uno::Reference
< css::xml::sax::XFastContextHandler
> XMLVariableDeclsImportContext::createFastChildContext(
645 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
647 SvXMLImportContextRef xImportContext
;
649 if( IsTokenInNamespace(nElement
, XML_NAMESPACE_TEXT
) )
651 enum XMLTokenEnum eElementName
;
652 switch (eVarDeclsContextType
)
654 case VarTypeSequence
:
655 eElementName
= XML_SEQUENCE_DECL
;
658 eElementName
= XML_VARIABLE_DECL
;
660 case VarTypeUserField
:
661 eElementName
= XML_USER_FIELD_DECL
;
664 OSL_FAIL("unknown field type!");
665 eElementName
= XML_SEQUENCE_DECL
;
669 if( nElement
== XML_ELEMENT(TEXT
, eElementName
) )
671 return new XMLVariableDeclImportContext(
672 GetImport(), rImportHelper
, nElement
, xAttrList
,
673 eVarDeclsContextType
);
677 // if no context was created, use default context
682 // declaration import (<variable/user-field/sequence-decl> elements)
685 XMLVariableDeclImportContext::XMLVariableDeclImportContext(
686 SvXMLImport
& rImport
, XMLTextImportHelper
& rHlp
,
688 const Reference
<xml::sax::XFastAttributeList
> & xAttrList
,
689 enum VarType eVarType
) :
690 SvXMLImportContext(rImport
)
692 // bug?? which properties for userfield/userfieldmaster
693 XMLValueImportHelper
aValueHelper(rImport
, rHlp
, true, false, true, false);
694 sal_Unicode
cSeparationChar('.');
696 sal_Int8
nNumLevel(-1);
699 if (nElement
!= XML_ELEMENT(TEXT
, XML_SEQUENCE_DECL
) &&
700 nElement
!= XML_ELEMENT(TEXT
, XML_VARIABLE_DECL
) &&
701 nElement
!= XML_ELEMENT(TEXT
, XML_USER_FIELD_DECL
) )
704 // TODO: check validity (need name!)
707 for (auto &aIter
: sax_fastparser::castToFastAttributeList( xAttrList
))
709 switch (aIter
.getToken())
711 case XML_ELEMENT(TEXT
, XML_NAME
):
712 sName
= aIter
.toString();
714 case XML_ELEMENT(TEXT
, XML_DISPLAY_OUTLINE_LEVEL
):
717 bool const bRet
= ::sax::Converter::convertNumber(
718 nLevel
, aIter
.toView(), 0,
719 GetImport().GetTextImport()->GetChapterNumbering()->
723 nNumLevel
= static_cast< sal_Int8
>( nLevel
-1 ); // API numbers -1..9
727 case XML_ELEMENT(TEXT
, XML_SEPARATION_CHARACTER
):
729 static_cast<char>(aIter
.toString().toChar());
733 // delegate to value helper
734 aValueHelper
.ProcessAttribute(aIter
.getToken(), aIter
.toView());
739 Reference
<XPropertySet
> xFieldMaster
;
740 if (!FindFieldMaster(xFieldMaster
, GetImport(), rHlp
,
744 // now we have a field master: process attributes!
749 case VarTypeSequence
:
750 xFieldMaster
->setPropertyValue("ChapterNumberingLevel", Any(nNumLevel
));
754 OUString
sStr(&cSeparationChar
, 1);
755 xFieldMaster
->setPropertyValue(
756 "NumberingSeparator", Any(sStr
));
761 // set string or non-string SubType (#93192#)
762 // The SubType was already set in the FindFieldMaster
763 // method, but it needs to be adjusted if it's a string.
764 aAny
<<= aValueHelper
.IsStringValue()
765 ? SetVariableType::STRING
: SetVariableType::VAR
;
766 xFieldMaster
->setPropertyValue(sAPI_sub_type
, aAny
);
769 case VarTypeUserField
:
771 bool bTmp
= !aValueHelper
.IsStringValue();
772 xFieldMaster
->setPropertyValue("IsExpression", Any(bTmp
));
773 aValueHelper
.PrepareField(xFieldMaster
);
777 OSL_FAIL("unknown varfield type");
782 bool XMLVariableDeclImportContext::FindFieldMaster(
783 Reference
<XPropertySet
> & xMaster
, SvXMLImport
& rImport
,
784 XMLTextImportHelper
& rImportHelper
,
785 const OUString
& sVarName
, enum VarType eVarType
)
787 static sal_Int32 nCollisionCount
= 0;
790 // currently: no family in use! Use 0.
791 OUString sName
= rImportHelper
.GetRenameMap().Get(
792 sal::static_int_cast
< sal_uInt16
>(eVarType
), sVarName
);
794 // get text fields supplier and field masters
795 Reference
<XTextFieldsSupplier
> xTextFieldsSupp(rImport
.GetModel(),
797 Reference
<container::XNameAccess
> xFieldMasterNameAccess
=
798 xTextFieldsSupp
->getTextFieldMasters();
800 OUString sVarServiceName
=
801 OUString::Concat(sAPI_fieldmaster_prefix
) +
802 sAPI_set_expression
+
806 OUString sUserServiceName
=
807 OUString::Concat(sAPI_fieldmaster_prefix
) +
812 if (xFieldMasterNameAccess
->hasByName(sVarServiceName
)) {
813 // variable field master already in document
815 Any aAny
= xFieldMasterNameAccess
->getByName(sVarServiceName
);
818 aAny
= xMaster
->getPropertyValue(sAPI_sub_type
);
822 enum VarType eFMVarType
=
823 (SetVariableType::SEQUENCE
== nType
) ?
824 VarTypeSequence
: VarTypeSimple
;
826 if (eFMVarType
!= eVarType
)
829 OUString
sNew(sName
+ "_renamed_" + OUString::number(nCollisionCount
));
831 // FIXME! can't find if name is taken already!!!!
833 rImportHelper
.GetRenameMap().Add(
834 sal::static_int_cast
< sal_uInt16
>(eVarType
), sName
, sNew
);
836 // call FindFieldMaster recursively to create new master
837 return FindFieldMaster(xMaster
, rImport
, rImportHelper
,
840 } else if (xFieldMasterNameAccess
->hasByName(sUserServiceName
)) {
841 // user field: get field master
842 Any aAny
= xFieldMasterNameAccess
->getByName(sUserServiceName
);
845 if (VarTypeUserField
!= eVarType
) {
847 // find new name that is not taken
848 OUString
sNew(sName
+ "_renamed_" + OUString::number(nCollisionCount
));
850 // FIXME! can't find if name is taken already!!!!
852 rImportHelper
.GetRenameMap().Add(
853 sal::static_int_cast
< sal_uInt16
>(eVarType
), sName
, sNew
);
855 // call FindFieldMaster recursively to create new master
856 return FindFieldMaster(xMaster
, rImport
, rImportHelper
,
860 // field name not used: create field master
862 // import -> model is MultiServiceFactory -> createInstance
863 Reference
<lang::XMultiServiceFactory
>
864 xFactory(rImport
.GetModel(),UNO_QUERY
);
865 if( xFactory
.is() ) {
867 OUString sService
= sAPI_fieldmaster_prefix
868 + ((eVarType
==VarTypeUserField
) ?
869 OUString(sAPI_user
) : OUString(sAPI_set_expression
));
870 Reference
<XInterface
> xIfc
=
871 xFactory
->createInstance( sService
);
873 Reference
<XPropertySet
> xTmp( xIfc
, UNO_QUERY
);
877 xMaster
->setPropertyValue("Name", Any(sName
));
879 if (eVarType
!= VarTypeUserField
) {
880 // set subtype for setexp field
882 aAny
<<= ((eVarType
== VarTypeSimple
) ?
883 SetVariableType::VAR
:
884 SetVariableType::SEQUENCE
);
885 xMaster
->setPropertyValue(sAPI_sub_type
, aAny
);
886 } // else : user field: no subtype
896 DBG_ASSERT(xMaster
.is(), "no field master found!?!");
901 // Database Display field import
904 XMLDatabaseDisplayImportContext::XMLDatabaseDisplayImportContext(
905 SvXMLImport
& rImport
, XMLTextImportHelper
& rHlp
) :
906 XMLDatabaseFieldImportContext(rImport
, rHlp
, sAPI_database
, false),
907 aValueHelper(rImport
, rHlp
, false, true, false, false),
914 void XMLDatabaseDisplayImportContext::ProcessAttribute(
915 sal_Int32 nAttrToken
, std::string_view sAttrValue
)
919 case XML_ELEMENT(TEXT
, XML_COLUMN_NAME
):
920 sColumnName
= OUString::fromUtf8(sAttrValue
);
923 case XML_ELEMENT(TEXT
, XML_DISPLAY
):
925 bool bNone
= IsXMLToken( sAttrValue
, XML_NONE
);
926 bool bValue
= IsXMLToken( sAttrValue
, XML_VALUE
);
928 bDisplayOK
= bNone
|| bValue
;
931 case XML_ELEMENT(TEXT
, XML_DATABASE_NAME
):
932 case XML_ELEMENT(TEXT
, XML_TABLE_NAME
):
933 case XML_ELEMENT(TEXT
, XML_TABLE_TYPE
):
934 // handled by super class
935 XMLDatabaseFieldImportContext::ProcessAttribute(nAttrToken
,
939 // remainder handled by value helper
940 aValueHelper
.ProcessAttribute(nAttrToken
, sAttrValue
);
944 bValid
= m_bTableOK
&& m_bDatabaseOK
&& bColumnOK
;
947 void XMLDatabaseDisplayImportContext::endFastElement(sal_Int32
)
949 // we have an EndElement of our own, because database fields need
950 // to be attached to a field master before they can be inserted into
951 // the document. Database stuff (database, table, column) all goes
952 // to the field master, value & style go to the field.
957 // so here goes: we start with the master
958 Reference
<XPropertySet
> xMaster
;
960 // create and prepare field master first
961 if (CreateField(xMaster
,
962 "com.sun.star.text.FieldMaster.Database"))
965 xMaster
->setPropertyValue("DataColumnName", Any(sColumnName
));
967 // fieldmaster takes database, table and column name
968 XMLDatabaseFieldImportContext::PrepareField(xMaster
);
971 Reference
<XPropertySet
> xField
;
972 if (CreateField(xField
,
975 // attach field master
976 Reference
<XDependentTextField
> xDepField(xField
, UNO_QUERY
);
979 // attach field to field master
980 xDepField
->attachTextFieldMaster(xMaster
);
982 // attach field to document
983 Reference
<XTextContent
> xTextContent(xField
, UNO_QUERY
);
984 if (xTextContent
.is())
986 // insert, set field properties and exit!
989 GetImportHelper().InsertTextContent(xTextContent
);
991 // prepare field: format from database?
992 bool bTmp
= !aValueHelper
.IsFormatOK();
993 xField
->setPropertyValue("DataBaseFormat", Any(bTmp
));
995 // value, value-type and format done by value helper
996 aValueHelper
.PrepareField(xField
);
1001 xField
->setPropertyValue(sAPI_is_visible
, Any(bDisplay
));
1005 aAny
<<= GetContent();
1006 xField
->setPropertyValue(sAPI_current_presentation
, aAny
);
1011 catch (const lang::IllegalArgumentException
&)
1013 TOOLS_WARN_EXCEPTION("xmloff.text", "Failed to insert text content");
1021 // above: exit on success; so for all error cases we end up here!
1022 // write element content
1023 GetImportHelper().InsertString(GetContent());
1027 // value import helper
1033 XML_VALUE_TYPE_STRING
,
1034 XML_VALUE_TYPE_FLOAT
,
1035 XML_VALUE_TYPE_CURRENCY
,
1036 XML_VALUE_TYPE_PERCENTAGE
,
1037 XML_VALUE_TYPE_DATE
,
1038 XML_VALUE_TYPE_TIME
,
1039 XML_VALUE_TYPE_BOOLEAN
1044 SvXMLEnumMapEntry
<ValueType
> const aValueTypeMap
[] =
1046 { XML_FLOAT
, XML_VALUE_TYPE_FLOAT
},
1047 { XML_CURRENCY
, XML_VALUE_TYPE_CURRENCY
},
1048 { XML_PERCENTAGE
, XML_VALUE_TYPE_PERCENTAGE
},
1049 { XML_DATE
, XML_VALUE_TYPE_DATE
},
1050 { XML_TIME
, XML_VALUE_TYPE_TIME
},
1051 { XML_BOOLEAN
, XML_VALUE_TYPE_BOOLEAN
},
1052 { XML_STRING
, XML_VALUE_TYPE_STRING
},
1053 { XML_TOKEN_INVALID
, ValueType(0) }
1056 XMLValueImportHelper::XMLValueImportHelper(
1057 SvXMLImport
& rImprt
,
1058 XMLTextImportHelper
& rHlp
,
1059 bool bType
, bool bStyle
, bool bValue
, bool bFormula
) :
1066 bIsDefaultLanguage(true),
1070 bStringValueOK(false),
1076 bSetFormula(bFormula
)
1080 void XMLValueImportHelper::ProcessAttribute(
1081 sal_Int32 nAttrToken
, std::string_view sAttrValue
)
1085 case XML_ELEMENT(TEXT
, XML_VALUE_TYPE
): // #i32362#: src680m48++ saves text:value-type
1086 case XML_ELEMENT(OFFICE
, XML_VALUE_TYPE
):
1089 ValueType eValueType
= XML_VALUE_TYPE_STRING
;
1090 bool bRet
= SvXMLUnitConverter::convertEnum(
1091 eValueType
, sAttrValue
, aValueTypeMap
);
1096 case XML_VALUE_TYPE_STRING
:
1099 case XML_VALUE_TYPE_FLOAT
:
1100 case XML_VALUE_TYPE_CURRENCY
:
1101 case XML_VALUE_TYPE_PERCENTAGE
:
1102 case XML_VALUE_TYPE_DATE
:
1103 case XML_VALUE_TYPE_TIME
:
1104 case XML_VALUE_TYPE_BOOLEAN
:
1105 bStringType
= false;
1109 OSL_FAIL("unknown value type");
1115 case XML_ELEMENT(TEXT
, XML_VALUE
):
1116 case XML_ELEMENT(OFFICE
, XML_VALUE
):
1119 bool const bRet
= ::sax::Converter::convertDouble(fTmp
,sAttrValue
);
1126 case XML_ELEMENT(TEXT
, XML_TIME_VALUE
):
1127 case XML_ELEMENT(OFFICE
, XML_TIME_VALUE
):
1131 ::sax::Converter::convertDuration(fTmp
, sAttrValue
);
1138 case XML_ELEMENT(TEXT
, XML_DATE_VALUE
):
1139 case XML_ELEMENT(OFFICE
, XML_DATE_VALUE
):
1142 bool bRet
= rImport
.GetMM100UnitConverter().
1143 convertDateTime(fTmp
,sAttrValue
);
1150 case XML_ELEMENT(OFFICE
, XML_BOOLEAN_VALUE
):
1153 bool bRet
= ::sax::Converter::convertBool(bTmp
, sAttrValue
);
1155 fValue
= (bTmp
? 1.0 : 0.0);
1160 bRet
= ::sax::Converter::convertDouble(fTmp
, sAttrValue
);
1168 case XML_ELEMENT(TEXT
, XML_STRING_VALUE
):
1169 case XML_ELEMENT(OFFICE
, XML_STRING_VALUE
):
1170 sValue
= OUString::fromUtf8(sAttrValue
);
1171 bStringValueOK
= true;
1174 case XML_ELEMENT(TEXT
, XML_FORMULA
):
1177 sal_uInt16 nPrefix
= rImport
.GetNamespaceMap().
1178 GetKeyByAttrValueQName(OUString::fromUtf8(sAttrValue
), &sTmp
);
1179 if( XML_NAMESPACE_OOOW
== nPrefix
)
1185 sFormula
= OUString::fromUtf8(sAttrValue
);
1189 case XML_ELEMENT(STYLE
, XML_DATA_STYLE_NAME
):
1191 sal_Int32 nKey
= rHelper
.GetDataStyleKey(
1192 OUString::fromUtf8(sAttrValue
), &bIsDefaultLanguage
);
1201 XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken
, sAttrValue
);
1205 void XMLValueImportHelper::PrepareField(
1206 const Reference
<XPropertySet
> & xPropertySet
)
1212 // ??? how to set type?
1217 aAny
<<= !bFormulaOK
? sDefault
: sFormula
;
1218 xPropertySet
->setPropertyValue(sAPI_content
, aAny
);
1222 if (bSetStyle
&& bFormatOK
)
1224 xPropertySet
->setPropertyValue(sAPI_number_format
, Any(nFormatKey
));
1226 if( xPropertySet
->getPropertySetInfo()->
1227 hasPropertyByName( "IsFixedLanguage" ) )
1229 bool bIsFixedLanguage
= ! bIsDefaultLanguage
;
1230 xPropertySet
->setPropertyValue( "IsFixedLanguage", Any(bIsFixedLanguage
) );
1234 // value: string or float
1239 aAny
<<= !bStringValueOK
? sDefault
: sValue
;
1240 xPropertySet
->setPropertyValue(sAPI_content
, aAny
);
1244 xPropertySet
->setPropertyValue("Value", Any(fValue
));
1249 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */