bump product version to 5.0.4.1
[LibreOffice.git] / xmloff / source / text / txtvfldi.cxx
blobadc415f25c4c4038fc8461c0dee73e507caa6f1b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 /** @#file
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/xmlnumi.hxx>
29 #include <xmloff/xmlnmspe.hxx>
30 #include <xmloff/nmspmap.hxx>
31 #include <xmloff/i18nmap.hxx>
32 #include <xmloff/xmlimp.hxx>
33 #include <xmloff/xmluconv.hxx>
34 #include <xmloff/xmlement.hxx>
35 #include <com/sun/star/text/SetVariableType.hpp>
36 #include <com/sun/star/text/XTextField.hpp>
37 #include <com/sun/star/text/XDependentTextField.hpp>
38 #include <com/sun/star/text/XTextFieldsSupplier.hpp>
39 #include <com/sun/star/beans/XPropertySet.hpp>
40 #include <com/sun/star/beans/XPropertySetInfo.hpp>
41 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
42 #include <com/sun/star/xml/sax/XAttributeList.hpp>
44 #include <sax/tools/converter.hxx>
46 #include <rtl/ustring.hxx>
47 #include <osl/diagnose.h>
49 #include <tools/debug.hxx>
52 // service names
53 static const sal_Char sAPI_textfield_prefix[] = "com.sun.star.text.TextField.";
54 static const sal_Char sAPI_fieldmaster_prefix[] = "com.sun.star.text.FieldMaster.";
55 static const sal_Char sAPI_input[] = "Input";
56 static const sal_Char sAPI_input_user[] = "InputUser";
57 static const sal_Char sAPI_get_expression[] = "GetExpression";
58 static const sal_Char sAPI_set_expression[] = "SetExpression";
59 static const sal_Char sAPI_user[] = "User";
60 static const sal_Char sAPI_table_formula[] = "TableFormula";
61 static const sal_Char sAPI_database[] = "com.sun.star.text.TextField.Database";
62 static const sal_Char sAPI_fieldmaster_database[] = "com.sun.star.text.FieldMaster.Database";
64 // property names
65 static const sal_Char sAPI_hint[] = "Hint";
66 static const sal_Char sAPI_help[] = "Help";
67 static const sal_Char sAPI_tooltip[] = "Tooltip";
68 static const sal_Char sAPI_content[] = "Content";
69 static const sal_Char sAPI_sub_type[] = "SubType";
70 static const sal_Char sAPI_is_expression[] = "IsExpression";
71 static const sal_Char sAPI_is_input[] = "Input";
72 static const sal_Char sAPI_is_show_formula[] = "IsShowFormula";
73 static const sal_Char sAPI_number_format[] = "NumberFormat";
74 static const sal_Char sAPI_name[] = "Name";
75 static const sal_Char sAPI_numbering_separator[] = "NumberingSeparator";
76 static const sal_Char sAPI_chapter_numbering_level[]= "ChapterNumberingLevel";
77 static const sal_Char sAPI_value[] = "Value";
78 static const sal_Char sAPI_is_visible[] = "IsVisible";
79 static const sal_Char sAPI_data_column_name[] = "DataColumnName";
80 static const sal_Char sAPI_is_data_base_format[] = "DataBaseFormat";
81 static const sal_Char sAPI_current_presentation[] = "CurrentPresentation";
82 static const sal_Char sAPI_sequence_value[] = "SequenceValue";
83 static const sal_Char sAPI_is_fixed_language[] = "IsFixedLanguage";
87 using namespace ::com::sun::star;
88 using namespace ::com::sun::star::uno;
89 using namespace ::com::sun::star::beans;
90 using namespace ::com::sun::star::text;
91 using namespace ::com::sun::star::style;
92 using namespace ::xmloff::token;
97 // XMLVarFieldImportContext: superclass for all variable related fields
100 TYPEINIT1( XMLVarFieldImportContext, XMLTextFieldImportContext );
102 XMLVarFieldImportContext::XMLVarFieldImportContext(
103 SvXMLImport& rImport, XMLTextImportHelper& rHlp,
104 const sal_Char* pServiceName, sal_uInt16 nPrfx,
105 const OUString& rLocalName,
106 bool bFormula, bool bFormulaDefault,
107 bool bDescription, bool bHelp, bool bHint, bool bVisible,
108 bool bIsDisplayFormula,
109 bool bType, bool bStyle, bool bValue,
110 bool bPresentation) :
111 XMLTextFieldImportContext(rImport, rHlp, pServiceName, nPrfx, rLocalName),
112 sPropertyContent(sAPI_content),
113 sPropertyHint(sAPI_hint),
114 sPropertyHelp(sAPI_help),
115 sPropertyTooltip(sAPI_tooltip),
116 sPropertyIsVisible(sAPI_is_visible),
117 sPropertyIsDisplayFormula(sAPI_is_show_formula),
118 sPropertyCurrentPresentation(sAPI_current_presentation),
119 aValueHelper(rImport, rHlp, bType, bStyle, bValue, false),
120 bDisplayFormula(false),
121 bDisplayNone(false),
122 bNameOK(false),
123 bFormulaOK(false),
124 bDescriptionOK(false),
125 bHelpOK(false),
126 bHintOK(false),
127 bDisplayOK(false),
128 bSetFormula(bFormula),
129 bSetFormulaDefault(bFormulaDefault),
130 bSetDescription(bDescription),
131 bSetHelp(bHelp),
132 bSetHint(bHint),
133 bSetVisible(bVisible),
134 bSetDisplayFormula(bIsDisplayFormula),
135 bSetPresentation(bPresentation)
139 void XMLVarFieldImportContext::ProcessAttribute(
140 sal_uInt16 nAttrToken,
141 const OUString& sAttrValue )
143 switch (nAttrToken)
145 case XML_TOK_TEXTFIELD_NAME:
146 sName = sAttrValue;
147 bNameOK = true;
148 bValid = true; // we assume: field with name is valid!
149 break;
150 case XML_TOK_TEXTFIELD_DESCRIPTION:
151 sDescription = sAttrValue;
152 bDescriptionOK = true;
153 break;
154 case XML_TOK_TEXTFIELD_HELP:
155 sHelp = sAttrValue;
156 bHelpOK = true;
157 break;
158 case XML_TOK_TEXTFIELD_HINT:
159 sHint = sAttrValue;
160 bHintOK = true;
161 break;
162 case XML_TOK_TEXTFIELD_FORMULA:
164 OUString sTmp;
165 sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
166 _GetKeyByAttrName( sAttrValue, &sTmp, false );
167 if( XML_NAMESPACE_OOOW == nPrefix )
169 sFormula = sTmp;
170 bFormulaOK = true;
172 else
173 sFormula = sAttrValue;
175 break;
176 case XML_TOK_TEXTFIELD_DISPLAY:
177 if (IsXMLToken(sAttrValue, XML_FORMULA))
179 bDisplayFormula = true;
180 bDisplayNone = false;
181 bDisplayOK = true;
183 else if (IsXMLToken(sAttrValue, XML_VALUE))
185 bDisplayFormula = false;
186 bDisplayNone = false;
187 bDisplayOK = true;
189 else if (IsXMLToken(sAttrValue, XML_NONE))
191 bDisplayFormula = false;
192 bDisplayNone = true;
193 bDisplayOK = true;
194 } // else: no change
195 DBG_ASSERT(!(bDisplayFormula && bDisplayNone),
196 "illegal display values");
197 break;
198 default:
199 // delegate all others to value helper
200 aValueHelper.ProcessAttribute(nAttrToken, sAttrValue);
201 break;
205 void XMLVarFieldImportContext::PrepareField(
206 const Reference<XPropertySet> & xPropertySet)
208 // bSetName: not implemented
210 if (bSetFormula)
212 if (!bFormulaOK && bSetFormulaDefault)
214 sFormula = GetContent();
215 bFormulaOK = true;
218 if (bFormulaOK)
220 Any aAny;
221 aAny <<= sFormula;
222 xPropertySet->setPropertyValue(sPropertyContent, aAny);
226 if (bSetDescription && bDescriptionOK)
228 Any aAny;
229 aAny <<= sDescription;
230 xPropertySet->setPropertyValue(sPropertyHint, aAny);
233 if (bSetHelp && bHelpOK)
235 Any aAny;
236 aAny <<= sHelp;
237 xPropertySet->setPropertyValue(sPropertyHelp, aAny);
240 if (bSetHint && bHintOK)
242 Any aAny;
243 aAny <<= sHint;
244 xPropertySet->setPropertyValue(sPropertyTooltip, aAny);
247 if (bSetVisible && bDisplayOK)
249 Any aAny;
250 sal_Bool bTmp = ! (bDisplayNone && bDisplayOK);
251 aAny.setValue( &bTmp, cppu::UnoType<bool>::get());
252 xPropertySet->setPropertyValue(sPropertyIsVisible, aAny);
255 // workaround for #no-bug#: display formula by default
256 if (xPropertySet->getPropertySetInfo()->
257 hasPropertyByName(sPropertyIsDisplayFormula) &&
258 !bSetDisplayFormula)
260 bDisplayFormula = false;
261 bSetDisplayFormula = true;
265 if (bSetDisplayFormula)
267 Any aAny;
268 sal_Bool bTmp = bDisplayFormula && bDisplayOK;
269 aAny.setValue( &bTmp, cppu::UnoType<bool>::get());
270 xPropertySet->setPropertyValue(sPropertyIsDisplayFormula, aAny);
273 // delegate to value helper
274 aValueHelper.SetDefault(GetContent());
275 aValueHelper.PrepareField(xPropertySet);
277 // finally, set the curren presentation
278 if (bSetPresentation)
280 Any aAny;
281 aAny <<= GetContent();
282 xPropertySet->setPropertyValue(sPropertyCurrentPresentation, aAny);
291 // variable set fields
294 TYPEINIT1( XMLSetVarFieldImportContext, XMLVarFieldImportContext );
296 XMLSetVarFieldImportContext::XMLSetVarFieldImportContext(
297 SvXMLImport& rImport, XMLTextImportHelper& rHlp,
298 const sal_Char* pServiceName, sal_uInt16 nPrfx,
299 const OUString& rLocalName, VarType eVarType,
300 bool bFormula, bool bFormulaDefault,
301 bool bDescription, bool bHelp, bool bHint, bool bVisible, bool bIsDisplayFormula,
302 bool bType, bool bStyle, bool bValue, bool bPresentation) :
303 XMLVarFieldImportContext(rImport, rHlp, pServiceName,
304 nPrfx, rLocalName,
305 bFormula, bFormulaDefault,
306 bDescription, bHelp, bHint, bVisible, bIsDisplayFormula,
307 bType, bStyle, bValue, bPresentation),
308 eFieldType(eVarType)
312 void XMLSetVarFieldImportContext::EndElement()
314 // should we call PrepareField on the field, or rather on it's master?
315 // currently: call on field (just like superclass)
316 // possible alternatives: call on master
317 // call field or master depending on variable
318 // PrepareMaster() in addition to PrepareField()
320 DBG_ASSERT(!GetServiceName().isEmpty(), "no service name for element!");
322 if (bValid)
324 DBG_ASSERT(!GetName().isEmpty(), "variable name needed!");
326 // find field master
327 Reference<XPropertySet> xMaster;
328 if (FindFieldMaster(xMaster))
330 // create field/Service
331 Reference<XPropertySet> xPropSet;
332 if (CreateField(xPropSet, sAPI_textfield_prefix + GetServiceName()))
334 Reference<XDependentTextField> xDepTextField(xPropSet, UNO_QUERY);
335 if (xDepTextField.is())
337 // attach field to field master
338 xDepTextField->attachTextFieldMaster(xMaster);
340 // attach field to document
341 Reference<XTextContent> xTextContent(xPropSet, UNO_QUERY);
342 if (xTextContent.is())
344 try {
345 // insert, set field properties and exit!
346 GetImportHelper().InsertTextContent(xTextContent);
347 PrepareField(xPropSet);
348 } catch (lang::IllegalArgumentException & /*e*/)
350 // ignore e: #i54023#
352 return;
359 // above: exit on success; so for all error cases we end up here!
360 // write element content
361 GetImportHelper().InsertString(GetContent());
364 bool XMLSetVarFieldImportContext::FindFieldMaster(
365 Reference<XPropertySet> & xMaster)
367 // currently: delegate to XMLVariableDeclImportContext;
368 // should eventually go here
369 return XMLVariableDeclImportContext::FindFieldMaster(xMaster,
370 GetImport(),
371 GetImportHelper(),
372 GetName(),
373 eFieldType);
379 // sequence field
382 TYPEINIT1( XMLSequenceFieldImportContext, XMLSetVarFieldImportContext );
384 XMLSequenceFieldImportContext::XMLSequenceFieldImportContext(
385 SvXMLImport& rImport, XMLTextImportHelper& rHlp,
386 sal_uInt16 nPrfx, const OUString& rLocalName) :
387 XMLSetVarFieldImportContext(rImport, rHlp, sAPI_set_expression,
388 nPrfx, rLocalName, VarTypeSequence,
389 // formula
390 true, true,
391 false, false, false, false,
392 false,
393 false, false, false, true),
395 sPropertyNumberFormat(sAPI_number_format),
396 sPropertySequenceValue(sAPI_sequence_value),
397 sNumFormat(OUString('1')),
398 sNumFormatSync(GetXMLToken(XML_FALSE)),
399 bRefNameOK(false)
403 void XMLSequenceFieldImportContext::ProcessAttribute(
404 sal_uInt16 nAttrToken, const OUString& sAttrValue )
406 switch (nAttrToken)
408 case XML_TOK_TEXTFIELD_NUM_FORMAT:
409 sNumFormat = sAttrValue;
410 break;
411 case XML_TOK_TEXTFIELD_NUM_LETTER_SYNC:
412 sNumFormatSync = sAttrValue;
413 break;
414 case XML_TOK_TEXTFIELD_REF_NAME:
415 sRefName = sAttrValue;
416 bRefNameOK = true;
417 break;
418 default:
419 // delegate to super class (name, formula)
420 XMLSetVarFieldImportContext::ProcessAttribute(nAttrToken,
421 sAttrValue);
422 break;
423 } // switch
426 void XMLSequenceFieldImportContext::PrepareField(
427 const Reference<XPropertySet> & xPropertySet)
429 // delegate to super class (formula)
430 XMLSetVarFieldImportContext::PrepareField(xPropertySet);
432 // set format
433 sal_Int16 nNumType = NumberingType::ARABIC;
434 GetImport().GetMM100UnitConverter().convertNumFormat( nNumType, sNumFormat, sNumFormatSync );
435 Any aAny;
436 aAny <<= nNumType;
437 xPropertySet->setPropertyValue(sPropertyNumberFormat, aAny);
439 // handle reference name
440 if (bRefNameOK)
442 aAny = xPropertySet->getPropertyValue(sPropertySequenceValue);
443 sal_Int16 nValue = 0;
444 aAny >>= nValue;
445 GetImportHelper().InsertSequenceID(sRefName, GetName(), nValue);
452 // variable set field
455 TYPEINIT1( XMLVariableSetFieldImportContext, XMLSetVarFieldImportContext );
457 XMLVariableSetFieldImportContext::XMLVariableSetFieldImportContext(
458 SvXMLImport& rImport, XMLTextImportHelper& rHlp,
459 sal_uInt16 nPrfx, const OUString& rLocalName) :
460 XMLSetVarFieldImportContext(rImport, rHlp, sAPI_set_expression,
461 nPrfx, rLocalName, VarTypeSimple,
462 // formula, value&type, style,
463 // display none
464 true, true,
465 false, false, false,
466 true, false,
467 true, true, true,
468 true),
469 sPropertySubType(sAPI_sub_type)
473 void XMLVariableSetFieldImportContext::PrepareField(
474 const Reference<XPropertySet> & xPropertySet)
476 // set type
477 Any aAny;
478 aAny <<= (IsStringValue()? SetVariableType::STRING : SetVariableType::VAR);
479 xPropertySet->setPropertyValue(sPropertySubType, aAny);
481 // the remainder is handled by super class
482 XMLSetVarFieldImportContext::PrepareField(xPropertySet);
488 // variable input field
491 TYPEINIT1( XMLVariableInputFieldImportContext, XMLSetVarFieldImportContext );
493 XMLVariableInputFieldImportContext::XMLVariableInputFieldImportContext(
494 SvXMLImport& rImport, XMLTextImportHelper& rHlp, sal_uInt16 nPrfx,
495 const OUString& rLocalName) :
496 XMLSetVarFieldImportContext(rImport, rHlp, sAPI_set_expression,
497 nPrfx, rLocalName, VarTypeSimple,
498 // description, display none/formula,
499 // value&type, style, formula
500 true, true,
501 true, true, true,
502 true, false,
503 true, true, true,
504 true),
505 sPropertySubType(sAPI_sub_type),
506 sPropertyIsInput(sAPI_is_input)
510 void XMLVariableInputFieldImportContext::PrepareField(
511 const Reference<XPropertySet> & xPropertySet)
513 // set type (input field)
514 Any aAny;
515 sal_Bool bTrue = sal_True;
516 aAny.setValue( &bTrue, cppu::UnoType<bool>::get() );
517 xPropertySet->setPropertyValue(sPropertyIsInput, aAny);
519 // set type
520 aAny <<= (IsStringValue()? SetVariableType::STRING : SetVariableType::VAR);
521 xPropertySet->setPropertyValue(sPropertySubType, aAny);
523 // the remainder is handled by super class
524 XMLSetVarFieldImportContext::PrepareField(xPropertySet);
530 // user field
533 TYPEINIT1( XMLUserFieldImportContext, XMLSetVarFieldImportContext );
535 XMLUserFieldImportContext::XMLUserFieldImportContext(
536 SvXMLImport& rImport, XMLTextImportHelper& rHlp,
537 sal_uInt16 nPrfx, const OUString& rLocalName) :
538 XMLSetVarFieldImportContext(rImport, rHlp, sAPI_user, nPrfx,
539 rLocalName, VarTypeUserField,
540 // display none/formula, style
541 false, false,
542 false, false, false, true,
543 true,
544 false, true, false,
545 false)
552 // user input field
555 TYPEINIT1( XMLUserFieldInputImportContext, XMLVarFieldImportContext );
557 // bug: doesn't work (SO API lacking)
558 XMLUserFieldInputImportContext::XMLUserFieldInputImportContext(
559 SvXMLImport& rImport, XMLTextImportHelper& rHlp, sal_uInt16 nPrfx,
560 const OUString& rLocalName) :
561 XMLVarFieldImportContext(rImport, rHlp, sAPI_input_user,
562 nPrfx, rLocalName,
563 // description, style
564 false, false,
565 true, false, false,
566 false, false,
567 false /*???*/, true, false,
568 false)
572 void XMLUserFieldInputImportContext::PrepareField(
573 const Reference<XPropertySet> & xPropertySet)
575 Any aAny;
576 aAny <<= GetName();
577 xPropertySet->setPropertyValue(sPropertyContent, aAny);
579 // delegate to super class
580 XMLVarFieldImportContext::PrepareField(xPropertySet);
585 // variable get field
588 TYPEINIT1( XMLVariableGetFieldImportContext, XMLVarFieldImportContext );
590 XMLVariableGetFieldImportContext::XMLVariableGetFieldImportContext(
591 SvXMLImport& rImport, XMLTextImportHelper& rHlp,
592 sal_uInt16 nPrfx, const OUString& rLocalName) :
593 XMLVarFieldImportContext(rImport, rHlp, sAPI_get_expression,
594 nPrfx, rLocalName,
595 // style, display formula
596 false, false,
597 false, false, false,
598 false, true,
599 true, true, false,
600 true)
604 void XMLVariableGetFieldImportContext::PrepareField(
605 const Reference<XPropertySet> & xPropertySet)
607 // set name
608 Any aAny;
609 aAny <<= GetName();
610 xPropertySet->setPropertyValue(sPropertyContent, aAny);
612 // the remainder is handled by super class
613 XMLVarFieldImportContext::PrepareField(xPropertySet);
619 // expression field
622 TYPEINIT1( XMLExpressionFieldImportContext, XMLVarFieldImportContext );
624 XMLExpressionFieldImportContext::XMLExpressionFieldImportContext(
625 SvXMLImport& rImport, XMLTextImportHelper& rHlp,
626 sal_uInt16 nPrfx, const OUString& rLocalName) :
627 XMLVarFieldImportContext(rImport, rHlp, sAPI_get_expression,
628 nPrfx, rLocalName,
629 // formula, type, style, display formula
630 true, true,
631 false, false, false,
632 false, true,
633 true, true, false,
634 true),
635 sPropertySubType(sAPI_sub_type)
637 bValid = true; // always valid
641 void XMLExpressionFieldImportContext::PrepareField(
642 const Reference<XPropertySet> & xPropertySet)
644 sal_Int16 nSubType = SetVariableType::FORMULA;
645 Any aAny;
646 aAny <<= nSubType;
647 xPropertySet->setPropertyValue(sPropertySubType, aAny);
649 // delegate to super class
650 XMLVarFieldImportContext::PrepareField(xPropertySet);
656 // text input field
659 TYPEINIT1( XMLTextInputFieldImportContext, XMLVarFieldImportContext );
661 XMLTextInputFieldImportContext::XMLTextInputFieldImportContext(
662 SvXMLImport& rImport, XMLTextImportHelper& rHlp,
663 sal_uInt16 nPrfx, const OUString& sLocalName) :
664 XMLVarFieldImportContext(rImport, rHlp, sAPI_input,
665 nPrfx, sLocalName,
666 // description
667 false, false,
668 true, true, true,
669 false, false,
670 false, false, false,
671 false),
672 sPropertyContent(sAPI_content)
674 bValid = true; // always valid
677 void XMLTextInputFieldImportContext::PrepareField(
678 const Reference<XPropertySet> & xPropertySet)
680 XMLVarFieldImportContext::PrepareField(xPropertySet);
682 Any aAny;
683 aAny <<= GetContent();
684 xPropertySet->setPropertyValue(sPropertyContent, aAny);
689 // table formula field
692 TYPEINIT1( XMLTableFormulaImportContext, XMLTextFieldImportContext );
694 XMLTableFormulaImportContext::XMLTableFormulaImportContext(
695 SvXMLImport& rImport,
696 XMLTextImportHelper& rHlp,
697 sal_uInt16 nPrfx,
698 const OUString& rLocalName) :
699 XMLTextFieldImportContext(rImport, rHlp, sAPI_table_formula,
700 nPrfx, rLocalName),
701 sPropertyIsShowFormula("IsShowFormula"),
702 sPropertyCurrentPresentation(
703 "CurrentPresentation"),
704 aValueHelper(rImport, rHlp, false, true, false, true),
705 bIsShowFormula(false)
709 XMLTableFormulaImportContext::~XMLTableFormulaImportContext()
713 void XMLTableFormulaImportContext::ProcessAttribute(
714 sal_uInt16 nAttrToken,
715 const OUString& sAttrValue )
717 switch (nAttrToken)
719 case XML_TOK_TEXTFIELD_FORMULA:
720 aValueHelper.ProcessAttribute( nAttrToken, sAttrValue );
721 bValid = true; // we need a formula!
722 break;
724 case XML_TOK_TEXTFIELD_DATA_STYLE_NAME:
725 aValueHelper.ProcessAttribute( nAttrToken, sAttrValue );
726 break;
727 case XML_TOK_TEXTFIELD_DISPLAY:
728 if ( sAttrValue == "formula" )
729 bIsShowFormula = true;
730 break;
731 default:
732 // unknown attribute -> ignore
733 break;
737 void XMLTableFormulaImportContext::PrepareField(
738 const Reference<XPropertySet> & xPropertySet)
740 // set format and formula
741 aValueHelper.PrepareField( xPropertySet );
743 Any aAny;
745 // set 'show formula' and presentation
746 aAny.setValue( &bIsShowFormula, cppu::UnoType<bool>::get() );
747 xPropertySet->setPropertyValue( sPropertyIsShowFormula, aAny );
749 aAny <<= GetContent();
750 xPropertySet->setPropertyValue( sPropertyCurrentPresentation, aAny );
756 // variable declarations
758 // Should be adapted to XMLVarField-/XMLSetVarFieldImportContext scheme!
764 // declaration containter import (<variable/user-field/sequence-decls>)
767 TYPEINIT1( XMLVariableDeclsImportContext, SvXMLImportContext );
769 XMLVariableDeclsImportContext::XMLVariableDeclsImportContext(
770 SvXMLImport& rImport, XMLTextImportHelper& rHlp, sal_uInt16 nPrfx,
771 const OUString& rLocalName, enum VarType eVarType) :
772 SvXMLImportContext(rImport, nPrfx, rLocalName),
773 eVarDeclsContextType(eVarType),
774 rImportHelper(rHlp)
778 SvXMLImportContext* XMLVariableDeclsImportContext::CreateChildContext(
779 sal_uInt16 nPrefix, const OUString& rLocalName,
780 const Reference<xml::sax::XAttributeList> & xAttrList )
782 enum XMLTokenEnum eElementName;
783 SvXMLImportContext* pImportContext = NULL;
785 if( XML_NAMESPACE_TEXT == nPrefix )
787 switch (eVarDeclsContextType)
789 case VarTypeSequence:
790 eElementName = XML_SEQUENCE_DECL;
791 break;
792 case VarTypeSimple:
793 eElementName = XML_VARIABLE_DECL;
794 break;
795 case VarTypeUserField:
796 eElementName = XML_USER_FIELD_DECL;
797 break;
798 default:
799 OSL_FAIL("unknown field type!");
800 eElementName = XML_SEQUENCE_DECL;
801 break;
804 if( IsXMLToken( rLocalName, eElementName ) )
806 pImportContext = new XMLVariableDeclImportContext(
807 GetImport(), rImportHelper, nPrefix, rLocalName, xAttrList,
808 eVarDeclsContextType);
812 // if no context was created, use default context
813 if (NULL == pImportContext) {
814 pImportContext = SvXMLImportContext::CreateChildContext(nPrefix,
815 rLocalName,
816 xAttrList);
819 return pImportContext;
825 // declaration import (<variable/user-field/sequence-decl> elements)
828 TYPEINIT1( XMLVariableDeclImportContext, SvXMLImportContext );
830 XMLVariableDeclImportContext::XMLVariableDeclImportContext(
831 SvXMLImport& rImport, XMLTextImportHelper& rHlp,
832 sal_uInt16 nPrfx, const OUString& rLocalName,
833 const Reference<xml::sax::XAttributeList> & xAttrList,
834 enum VarType eVarType) :
835 SvXMLImportContext(rImport, nPrfx, rLocalName),
836 // bug?? which properties for userfield/userfieldmaster
837 sPropertySubType(sAPI_sub_type),
838 sPropertyNumberingLevel(sAPI_chapter_numbering_level),
839 sPropertyNumberingSeparator(sAPI_numbering_separator),
840 sPropertyIsExpression(sAPI_is_expression),
841 aValueHelper(rImport, rHlp, true, false, true, false),
842 nNumLevel(-1), cSeparationChar('.')
844 if ( (XML_NAMESPACE_TEXT == nPrfx) &&
845 ( ( IsXMLToken( rLocalName, XML_SEQUENCE_DECL )) ||
846 ( IsXMLToken( rLocalName, XML_VARIABLE_DECL)) ||
847 ( IsXMLToken( rLocalName, XML_USER_FIELD_DECL)) )) {
849 // TODO: check validity (need name!)
851 // parse attributes
852 sal_Int16 nLength = xAttrList->getLength();
853 for(sal_Int16 i=0; i<nLength; i++) {
855 OUString sLocalName;
856 sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
857 GetKeyByAttrName( xAttrList->getNameByIndex(i), &sLocalName );
859 sal_uInt16 nToken = rHlp.
860 GetTextFieldAttrTokenMap().Get(nPrefix, sLocalName);
862 switch (nToken)
864 case XML_TOK_TEXTFIELD_NAME:
865 sName = xAttrList->getValueByIndex(i);
866 break;
867 case XML_TOK_TEXTFIELD_NUMBERING_LEVEL:
869 sal_Int32 nLevel;
870 bool const bRet = ::sax::Converter::convertNumber(
871 nLevel, xAttrList->getValueByIndex(i), 0,
872 GetImport().GetTextImport()->GetChapterNumbering()->
873 getCount());
874 if (bRet)
876 nNumLevel = static_cast< sal_Int8 >( nLevel-1 ); // API numbers -1..9
878 break;
880 case XML_TOK_TEXTFIELD_NUMBERING_SEPARATOR:
881 cSeparationChar =
882 (sal_Char)xAttrList->getValueByIndex(i).toChar();
883 break;
885 default:
886 // delegate to value helper
887 aValueHelper.ProcessAttribute(nToken,
888 xAttrList->getValueByIndex(i));
889 break;
893 Reference<XPropertySet> xFieldMaster;
894 if (FindFieldMaster(xFieldMaster, GetImport(), rHlp,
895 sName, eVarType))
897 // now we have a field master: process attributes!
898 Any aAny;
900 switch (eVarType)
902 case VarTypeSequence:
903 aAny <<= nNumLevel;
904 xFieldMaster->setPropertyValue(sPropertyNumberingLevel, aAny);
906 if (nNumLevel >= 0)
908 OUString sStr(&cSeparationChar, 1);
909 aAny <<= sStr;
910 xFieldMaster->setPropertyValue(
911 sPropertyNumberingSeparator, aAny);
913 break;
914 case VarTypeSimple:
916 // set string or non-string SubType (#93192#)
917 // The SubType was already set in the FindFieldMaster
918 // method, but it needs to be adjusted if it's a string.
919 aAny <<= aValueHelper.IsStringValue()
920 ? SetVariableType::STRING : SetVariableType::VAR;
921 xFieldMaster->setPropertyValue(sPropertySubType, aAny);
923 break;
924 case VarTypeUserField:
926 sal_Bool bTmp = !aValueHelper.IsStringValue();
927 aAny.setValue(&bTmp, cppu::UnoType<bool>::get());
928 xFieldMaster->setPropertyValue(sPropertyIsExpression, aAny);
929 aValueHelper.PrepareField(xFieldMaster);
930 break;
932 default:
933 OSL_FAIL("unknown varfield type");
934 } // switch
935 } // else: no field master found/constructed
936 } // else: no sequence-decl
941 bool XMLVariableDeclImportContext::FindFieldMaster(
942 Reference<XPropertySet> & xMaster, SvXMLImport& rImport,
943 XMLTextImportHelper& rImportHelper,
944 const OUString& sVarName, enum VarType eVarType)
946 static sal_Int32 nCollisionCount = 0;
948 // rename field
949 // currently: no family in use! Use 0.
950 OUString sName = rImportHelper.GetRenameMap().Get(
951 sal::static_int_cast< sal_uInt16 >(eVarType), sVarName);
953 // get text fields supplier and field masters
954 Reference<XTextFieldsSupplier> xTextFieldsSupp(rImport.GetModel(),
955 UNO_QUERY);
956 Reference<container::XNameAccess> xFieldMasterNameAccess(
957 xTextFieldsSupp->getTextFieldMasters(), UNO_QUERY);
959 OUStringBuffer sBuffer;
960 sBuffer.appendAscii(sAPI_fieldmaster_prefix);
961 sBuffer.appendAscii(sAPI_set_expression);
962 sBuffer.appendAscii(".");
963 sBuffer.append(sName);
964 OUString sVarServiceName = sBuffer.makeStringAndClear();
966 sBuffer.appendAscii(sAPI_fieldmaster_prefix);
967 sBuffer.appendAscii(sAPI_user);
968 sBuffer.appendAscii(".");
969 sBuffer.append(sName);
970 OUString sUserServiceName = sBuffer.makeStringAndClear();
972 if (xFieldMasterNameAccess->hasByName(sVarServiceName)) {
973 // variable field master already in document
975 Any aAny = xFieldMasterNameAccess->getByName(sVarServiceName);
976 aAny >>= xMaster;
978 aAny = xMaster->getPropertyValue(
979 // sPropertySubType
980 OUString(sAPI_sub_type)
982 sal_Int16 nType = 0;
983 aAny >>= nType;
985 enum VarType eFMVarType =
986 (SetVariableType::SEQUENCE == nType) ?
987 VarTypeSequence : VarTypeSimple;
989 if (eFMVarType != eVarType)
991 OUString sNew;
993 // FIXME! can't find if name is taken already!!!!
995 nCollisionCount++;
996 OUStringBuffer aBuf;
997 aBuf.append(sName);
998 aBuf.appendAscii("_renamed_");
999 aBuf.append(nCollisionCount);
1000 sNew = aBuf.makeStringAndClear();
1002 rImportHelper.GetRenameMap().Add(
1003 sal::static_int_cast< sal_uInt16 >(eVarType), sName, sNew);
1005 // call FindFieldMaster recursively to create new master
1006 return FindFieldMaster(xMaster, rImport, rImportHelper,
1007 sNew, eVarType);
1009 } else if (xFieldMasterNameAccess->hasByName(sUserServiceName)) {
1010 // user field: get field master
1011 Any aAny = xFieldMasterNameAccess->getByName(sUserServiceName);
1012 aAny >>= xMaster;
1014 if (VarTypeUserField != eVarType) {
1015 // find new name that is not taken
1016 OUString sNew;
1018 // FIXME! can't find if name is taken already!!!!
1020 nCollisionCount++;
1021 OUStringBuffer aBuf;
1022 aBuf.append(sName);
1023 aBuf.appendAscii("_renamed_");
1024 aBuf.append(nCollisionCount);
1025 sNew = aBuf.makeStringAndClear();
1027 rImportHelper.GetRenameMap().Add(
1028 sal::static_int_cast< sal_uInt16 >(eVarType), sName, sNew);
1030 // call FindFieldMaster recursively to create new master
1031 return FindFieldMaster(xMaster, rImport, rImportHelper,
1032 sNew, eVarType);
1034 } else {
1035 // field name not used: create field master
1037 // import -> model is MultiServiceFactory -> createInstance
1038 Reference<lang::XMultiServiceFactory>
1039 xFactory(rImport.GetModel(),UNO_QUERY);
1040 if( xFactory.is() ) {
1042 OUStringBuffer sService;
1043 sService.appendAscii(sAPI_fieldmaster_prefix);
1044 sService.appendAscii((eVarType==VarTypeUserField) ?
1045 sAPI_user : sAPI_set_expression);
1046 Reference<XInterface> xIfc =
1047 xFactory->createInstance( sService.makeStringAndClear() );
1048 if (xIfc.is()) {
1049 Reference<XPropertySet> xTmp( xIfc, UNO_QUERY );
1050 xMaster = xTmp;
1052 // set name
1053 Any aAny;
1054 aAny <<= sName;
1055 xMaster->setPropertyValue(
1056 // sPropertyName
1057 OUString(sAPI_name)
1058 , aAny);
1060 if (eVarType != VarTypeUserField) {
1061 // set subtype for setexp field
1063 aAny <<= ((eVarType == VarTypeSimple) ?
1064 SetVariableType::VAR :
1065 SetVariableType::SEQUENCE);
1066 xMaster->setPropertyValue(
1067 // sPropertySubType
1068 OUString(sAPI_sub_type)
1069 , aAny);
1070 } // else : user field: no subtype
1072 } else {
1073 return false;
1075 } else {
1076 return false;
1080 DBG_ASSERT(xMaster.is(), "no field master found!?!");
1081 return true;
1086 // Database Display field import
1090 TYPEINIT1( XMLDatabaseDisplayImportContext, XMLDatabaseFieldImportContext );
1092 XMLDatabaseDisplayImportContext::XMLDatabaseDisplayImportContext(
1093 SvXMLImport& rImport, XMLTextImportHelper& rHlp, sal_uInt16 nPrfx,
1094 const OUString& rLocalName) :
1095 XMLDatabaseFieldImportContext(rImport, rHlp, sAPI_database,
1096 nPrfx, rLocalName, false),
1097 sPropertyColumnName(sAPI_data_column_name),
1098 sPropertyDatabaseFormat(sAPI_is_data_base_format),
1099 sPropertyCurrentPresentation(sAPI_current_presentation),
1100 sPropertyIsVisible(sAPI_is_visible),
1101 aValueHelper(rImport, rHlp, false, true, false, false),
1102 bColumnOK(false),
1103 bDisplay( true ),
1104 bDisplayOK( false )
1108 void XMLDatabaseDisplayImportContext::ProcessAttribute(
1109 sal_uInt16 nAttrToken, const OUString& sAttrValue )
1111 switch (nAttrToken)
1113 case XML_TOK_TEXTFIELD_COLUMN_NAME:
1114 sColumnName = sAttrValue;
1115 bColumnOK = true;
1116 break;
1117 case XML_TOK_TEXTFIELD_DISPLAY:
1119 bool bNone = IsXMLToken( sAttrValue, XML_NONE );
1120 bool bValue = IsXMLToken( sAttrValue, XML_VALUE );
1121 bDisplay = bValue;
1122 bDisplayOK = bNone || bValue;
1124 break;
1125 case XML_TOK_TEXTFIELD_DATABASE_NAME:
1126 case XML_TOK_TEXTFIELD_TABLE_NAME:
1127 case XML_TOK_TEXTFIELD_TABLE_TYPE:
1128 // handled by super class
1129 XMLDatabaseFieldImportContext::ProcessAttribute(nAttrToken,
1130 sAttrValue);
1131 break;
1132 default:
1133 // remainder handled by value helper
1134 aValueHelper.ProcessAttribute(nAttrToken, sAttrValue);
1135 break;
1138 bValid = bTableOK && bDatabaseOK && bColumnOK;
1141 void XMLDatabaseDisplayImportContext::EndElement()
1143 // we have an EndElement of our own, because database fields need
1144 // to be attached to a field master before they can be inserted into
1145 // the document. Database stuff (database, table, column) all goes
1146 // to the field master, value & style go to the field.
1148 if (bValid)
1151 // so here goes: we start with the master
1152 Reference<XPropertySet> xMaster;
1154 // create and prepare field master first
1155 if (CreateField(xMaster,
1156 OUString(
1157 sAPI_fieldmaster_database)))
1159 Any aAny;
1160 aAny <<= sColumnName;
1161 xMaster->setPropertyValue(sPropertyColumnName, aAny);
1163 // fieldmaster takes database, table and column name
1164 XMLDatabaseFieldImportContext::PrepareField(xMaster);
1166 // create field
1167 Reference<XPropertySet> xField;
1168 if (CreateField(xField,
1169 OUString(
1170 sAPI_database)))
1172 // attach field master
1173 Reference<XDependentTextField> xDepField(xField, UNO_QUERY);
1174 if (xDepField.is())
1176 // attach field to field master
1177 xDepField->attachTextFieldMaster(xMaster);
1179 // attach field to document
1180 Reference<XTextContent> xTextContent(xField, UNO_QUERY);
1181 if (xTextContent.is())
1183 // insert, set field properties and exit!
1184 GetImportHelper().InsertTextContent(xTextContent);
1186 // prepare field: format from database?
1187 sal_Bool bTmp = !aValueHelper.IsFormatOK();
1188 aAny.setValue( &bTmp, cppu::UnoType<bool>::get() );
1189 xField->setPropertyValue(sPropertyDatabaseFormat,aAny);
1191 // value, value-type and format done by value helper
1192 aValueHelper.PrepareField(xField);
1194 // visibility
1195 if( bDisplayOK )
1197 aAny.setValue( &bDisplay, cppu::UnoType<bool>::get() );
1198 xField->setPropertyValue(sPropertyIsVisible, aAny);
1201 // set presentation
1202 aAny <<= GetContent();
1203 xField->setPropertyValue(sPropertyCurrentPresentation,
1204 aAny);
1206 // success!
1207 return;
1214 // above: exit on success; so for all error cases we end up here!
1215 // write element content
1216 GetImportHelper().InsertString(GetContent());
1221 // value import helper
1224 enum ValueType
1226 XML_VALUE_TYPE_STRING,
1227 XML_VALUE_TYPE_FLOAT,
1228 XML_VALUE_TYPE_CURRENCY,
1229 XML_VALUE_TYPE_PERCENTAGE,
1230 XML_VALUE_TYPE_DATE,
1231 XML_VALUE_TYPE_TIME,
1232 XML_VALUE_TYPE_BOOLEAN
1235 static SvXMLEnumMapEntry const aValueTypeMap[] =
1237 { XML_FLOAT, XML_VALUE_TYPE_FLOAT },
1238 { XML_CURRENCY, XML_VALUE_TYPE_CURRENCY },
1239 { XML_PERCENTAGE, XML_VALUE_TYPE_PERCENTAGE },
1240 { XML_DATE, XML_VALUE_TYPE_DATE },
1241 { XML_TIME, XML_VALUE_TYPE_TIME },
1242 { XML_BOOLEAN, XML_VALUE_TYPE_BOOLEAN },
1243 { XML_STRING, XML_VALUE_TYPE_STRING },
1244 { XML_TOKEN_INVALID, 0 }
1247 XMLValueImportHelper::XMLValueImportHelper(
1248 SvXMLImport& rImprt,
1249 XMLTextImportHelper& rHlp,
1250 bool bType, bool bStyle, bool bValue, bool bFormula) :
1251 sPropertyContent(sAPI_content),
1252 sPropertyValue(sAPI_value),
1253 sPropertyNumberFormat(sAPI_number_format),
1254 sPropertyIsFixedLanguage(sAPI_is_fixed_language),
1256 rImport(rImprt),
1257 rHelper(rHlp),
1259 fValue(0.0),
1260 nFormatKey(0),
1261 bIsDefaultLanguage(true),
1263 bStringType(false),
1264 bFormatOK(false),
1265 bTypeOK(false),
1266 bStringValueOK(false),
1267 bFloatValueOK(false),
1268 bFormulaOK(false),
1270 bSetType(bType),
1271 bSetValue(bValue),
1272 bSetStyle(bStyle),
1273 bSetFormula(bFormula),
1275 bStringDefault(true),
1276 bFormulaDefault(true)
1280 XMLValueImportHelper::~XMLValueImportHelper()
1284 void XMLValueImportHelper::ProcessAttribute(
1285 sal_uInt16 nAttrToken, const OUString& sAttrValue )
1287 switch (nAttrToken)
1289 case XML_TOK_TEXTFIELD_VALUE_TYPE:
1291 // convert enum
1292 sal_uInt16 nTmp = 0;
1293 bool bRet = SvXMLUnitConverter::convertEnum(
1294 nTmp, sAttrValue, aValueTypeMap);
1296 if (bRet) {
1297 ValueType eValueType = (ValueType)nTmp;
1299 bTypeOK = true;
1301 switch (eValueType)
1303 case XML_VALUE_TYPE_STRING:
1304 bStringType = true;
1305 break;
1306 case XML_VALUE_TYPE_FLOAT:
1307 case XML_VALUE_TYPE_CURRENCY:
1308 case XML_VALUE_TYPE_PERCENTAGE:
1309 case XML_VALUE_TYPE_DATE:
1310 case XML_VALUE_TYPE_TIME:
1311 case XML_VALUE_TYPE_BOOLEAN:
1312 bStringType = false;
1313 break;
1315 default:
1316 OSL_FAIL("unknown value type");
1317 bTypeOK = false;
1320 break;
1323 case XML_TOK_TEXTFIELD_VALUE:
1325 double fTmp;
1326 bool const bRet = ::sax::Converter::convertDouble(fTmp,sAttrValue);
1327 if (bRet) {
1328 bFloatValueOK = true;
1329 fValue = fTmp;
1331 break;
1334 case XML_TOK_TEXTFIELD_TIME_VALUE:
1336 double fTmp;
1337 bool const bRet =
1338 ::sax::Converter::convertDuration(fTmp, sAttrValue);
1339 if (bRet) {
1340 bFloatValueOK = true;
1341 fValue = fTmp;
1343 break;
1346 case XML_TOK_TEXTFIELD_DATE_VALUE:
1348 double fTmp;
1349 bool bRet = rImport.GetMM100UnitConverter().
1350 convertDateTime(fTmp,sAttrValue);
1351 if (bRet) {
1352 bFloatValueOK = true;
1353 fValue = fTmp;
1355 break;
1358 case XML_TOK_TEXTFIELD_BOOL_VALUE:
1360 bool bTmp(false);
1361 bool bRet = ::sax::Converter::convertBool(bTmp, sAttrValue);
1362 if (bRet) {
1363 bFloatValueOK = true;
1364 fValue = (bTmp ? 1.0 : 0.0);
1366 else
1368 double fTmp;
1369 bRet = ::sax::Converter::convertDouble(fTmp, sAttrValue);
1370 if (bRet) {
1371 bFloatValueOK = true;
1372 fValue = fTmp;
1375 break;
1378 case XML_TOK_TEXTFIELD_STRING_VALUE:
1379 sValue = sAttrValue;
1380 bStringValueOK = true;
1381 break;
1383 case XML_TOK_TEXTFIELD_FORMULA:
1385 OUString sTmp;
1386 sal_uInt16 nPrefix = rImport.GetNamespaceMap().
1387 _GetKeyByAttrName( sAttrValue, &sTmp, false );
1388 if( XML_NAMESPACE_OOOW == nPrefix )
1390 sFormula = sTmp;
1391 bFormulaOK = true;
1393 else
1394 sFormula = sAttrValue;
1396 break;
1398 case XML_TOK_TEXTFIELD_DATA_STYLE_NAME:
1400 sal_Int32 nKey = rHelper.GetDataStyleKey(
1401 sAttrValue, &bIsDefaultLanguage);
1402 if (-1 != nKey)
1404 nFormatKey = nKey;
1405 bFormatOK = true;
1407 break;
1409 } // switch
1412 void XMLValueImportHelper::PrepareField(
1413 const Reference<XPropertySet> & xPropertySet)
1415 Any aAny;
1417 if (bSetType)
1419 // ??? how to set type?
1422 if (bSetFormula)
1424 aAny <<= (!bFormulaOK && bFormulaDefault) ? sDefault : sFormula;
1425 xPropertySet->setPropertyValue(sPropertyContent, aAny);
1428 // format/style
1429 if (bSetStyle && bFormatOK)
1431 aAny <<= nFormatKey;
1432 xPropertySet->setPropertyValue(sPropertyNumberFormat, aAny);
1434 if( xPropertySet->getPropertySetInfo()->
1435 hasPropertyByName( sPropertyIsFixedLanguage ) )
1437 sal_Bool bIsFixedLanguage = ! bIsDefaultLanguage;
1438 aAny.setValue( &bIsFixedLanguage, cppu::UnoType<bool>::get() );
1439 xPropertySet->setPropertyValue( sPropertyIsFixedLanguage, aAny );
1443 // value: string or float
1444 if (bSetValue)
1446 if (bStringType)
1448 aAny <<= (!bStringValueOK && bStringDefault) ? sDefault : sValue;
1449 xPropertySet->setPropertyValue(sPropertyContent, aAny);
1451 else
1453 aAny <<= fValue;
1454 xPropertySet->setPropertyValue(sPropertyValue, aAny);
1459 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */