1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_xmloff.hxx"
30 
31 
32 #include "XMLIndexBibliographyConfigurationContext.hxx"
33 #include "XMLIndexBibliographyEntryContext.hxx"
34 #include <xmloff/xmlictxt.hxx>
35 #include <xmloff/xmlimp.hxx>
36 #include <xmloff/txtimp.hxx>
37 #include <xmloff/nmspmap.hxx>
38 #include "xmloff/xmlnmspe.hxx"
39 #include <xmloff/xmltoken.hxx>
40 #include <xmloff/xmluconv.hxx>
41 #include <tools/debug.hxx>
42 #include <rtl/ustring.hxx>
43 #include <com/sun/star/beans/XPropertySet.hpp>
44 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
45 
46 using namespace ::com::sun::star::text;
47 using namespace ::com::sun::star::uno;
48 using namespace ::xmloff::token;
49 
50 using ::rtl::OUString;
51 using ::com::sun::star::xml::sax::XAttributeList;
52 using ::com::sun::star::beans::PropertyValue;
53 using ::com::sun::star::beans::XPropertySet;
54 using ::com::sun::star::lang::XMultiServiceFactory;
55 
56 const sal_Char sAPI_FieldMaster_Bibliography[] =
57 								"com.sun.star.text.FieldMaster.Bibliography";
58 
59 
60 TYPEINIT1( XMLIndexBibliographyConfigurationContext, SvXMLStyleContext );
61 
62 XMLIndexBibliographyConfigurationContext::XMLIndexBibliographyConfigurationContext(
63 	SvXMLImport& rImport,
64 	sal_uInt16 nPrfx,
65 	const OUString& rLocalName,
66 	const Reference<XAttributeList> & xAttrList) :
67 		SvXMLStyleContext(rImport, nPrfx, rLocalName, xAttrList, XML_STYLE_FAMILY_TEXT_BIBLIOGRAPHYCONFIG),
68 		sFieldMaster_Bibliography(
69 			RTL_CONSTASCII_USTRINGPARAM(sAPI_FieldMaster_Bibliography)),
70 		sBracketBefore(RTL_CONSTASCII_USTRINGPARAM("BracketBefore")),
71 		sBracketAfter(RTL_CONSTASCII_USTRINGPARAM("BracketAfter")),
72 		sIsNumberEntries(RTL_CONSTASCII_USTRINGPARAM("IsNumberEntries")),
73 		sIsSortByPosition(RTL_CONSTASCII_USTRINGPARAM("IsSortByPosition")),
74 		sSortKeys(RTL_CONSTASCII_USTRINGPARAM("SortKeys")),
75 		sSortKey(RTL_CONSTASCII_USTRINGPARAM("SortKey")),
76 		sIsSortAscending(RTL_CONSTASCII_USTRINGPARAM("IsSortAscending")),
77         sSortAlgorithm(RTL_CONSTASCII_USTRINGPARAM("SortAlgorithm")),
78         sLocale(RTL_CONSTASCII_USTRINGPARAM("Locale")),
79 		sSuffix(),
80 		sPrefix(),
81         sAlgorithm(),
82         aLocale(),
83 		bNumberedEntries(sal_False),
84 		bSortByPosition(sal_True)
85 {
86 }
87 
88 XMLIndexBibliographyConfigurationContext::~XMLIndexBibliographyConfigurationContext()
89 {
90 }
91 
92 void XMLIndexBibliographyConfigurationContext::StartElement(
93 	const Reference<XAttributeList> & xAttrList)
94 {
95 	sal_Int16 nLength = xAttrList->getLength();
96 	for(sal_Int16 nAttr = 0; nAttr < nLength; nAttr++)
97 	{
98 		OUString sLocalName;
99 		sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
100 			GetKeyByAttrName( xAttrList->getNameByIndex(nAttr),
101 							  &sLocalName );
102 
103         ProcessAttribute(nPrefix, sLocalName,
104                          xAttrList->getValueByIndex(nAttr));
105 		// else: ignore
106 	}
107 }
108 
109 void XMLIndexBibliographyConfigurationContext::ProcessAttribute(
110     sal_uInt16 nPrefix,
111 	OUString sLocalName,
112 	OUString sValue)
113 {
114     if( XML_NAMESPACE_TEXT == nPrefix )
115     {
116         if( IsXMLToken(sLocalName, XML_PREFIX) )
117         {
118             sPrefix = sValue;
119         }
120         else if( IsXMLToken(sLocalName, XML_SUFFIX) )
121         {
122             sSuffix = sValue;
123         }
124         else if( IsXMLToken(sLocalName, XML_NUMBERED_ENTRIES) )
125         {
126             sal_Bool bTmp;
127             if( SvXMLUnitConverter::convertBool(bTmp, sValue) )
128             {
129                 bNumberedEntries = bTmp;
130             }
131         }
132         else if( IsXMLToken(sLocalName, XML_SORT_BY_POSITION) )
133         {
134             sal_Bool bTmp;
135             if (SvXMLUnitConverter::convertBool(bTmp, sValue))
136             {
137                 bSortByPosition = bTmp;
138             }
139         }
140         else if( IsXMLToken(sLocalName, XML_SORT_ALGORITHM) )
141         {
142             sAlgorithm = sValue;
143         }
144 	}
145     else if( XML_NAMESPACE_FO == nPrefix )
146     {
147         if( IsXMLToken(sLocalName, XML_LANGUAGE) )
148         {
149             aLocale.Language = sValue;
150         }
151         else if( IsXMLToken(sLocalName, XML_COUNTRY) )
152         {
153             aLocale.Country = sValue;
154         }
155     }
156 }
157 
158 
159 SvXMLImportContext *XMLIndexBibliographyConfigurationContext::CreateChildContext(
160 	sal_uInt16 nPrefix,
161 	const OUString& rLocalName,
162 	const Reference<XAttributeList> & xAttrList )
163 {
164 	OUString sKey;
165 	sal_Bool bSort(sal_True);
166 
167 	// process children here and use default context!
168 	if ( ( nPrefix == XML_NAMESPACE_TEXT ) &&
169          IsXMLToken( rLocalName, XML_SORT_KEY ) )
170 	{
171 		sal_Int16 nLength = xAttrList->getLength();
172 		for(sal_Int16 nAttr = 0; nAttr < nLength; nAttr++)
173 		{
174 			OUString sLocalName;
175 			sal_uInt16 nPrfx = GetImport().GetNamespaceMap().
176 				GetKeyByAttrName( xAttrList->getNameByIndex(nAttr),
177 								  &sLocalName );
178 
179 			if (nPrfx == XML_NAMESPACE_TEXT)
180 			{
181 				if ( IsXMLToken( sLocalName, XML_KEY ) )
182 				{
183 					sKey = xAttrList->getValueByIndex(nAttr);
184 				}
185 				else if ( IsXMLToken( sLocalName, XML_SORT_ASCENDING ) )
186 				{
187 					sal_Bool bTmp;
188 					if (SvXMLUnitConverter::convertBool(
189 						bTmp, xAttrList->getValueByIndex(nAttr)))
190 					{
191 						bSort = bTmp;
192 					}
193 				}
194 			}
195 		}
196 
197 		// valid data?
198 		sal_uInt16 nKey;
199 		if (SvXMLUnitConverter::convertEnum(nKey, sKey,
200 											aBibliographyDataFieldMap))
201 		{
202 
203 			Any aAny;
204 			Sequence<PropertyValue> aKey(2);
205 
206 			PropertyValue aNameValue;
207 			aNameValue.Name = sSortKey;
208 			aAny <<= (sal_Int16)nKey;
209 			aNameValue.Value = aAny;
210 			aKey[0] = aNameValue;
211 
212 			PropertyValue aSortValue;
213 			aSortValue.Name = sIsSortAscending;
214 			aAny.setValue(&bSort, ::getBooleanCppuType());
215 			aSortValue.Value = aAny;
216 			aKey[1] = aSortValue;
217 
218 			aSortKeys.push_back(aKey);
219 		}
220 	}
221 
222 	return SvXMLImportContext::CreateChildContext(nPrefix, rLocalName,
223 												  xAttrList);
224 }
225 
226 void XMLIndexBibliographyConfigurationContext::CreateAndInsert(sal_Bool)
227 {
228 	// (code almost the same as export...)
229 
230 	// insert and block mode is handled in insertStyleFamily
231 
232 	// first: get field master
233 	// (we'll create one, and get the only master for this type)
234 	Reference<XMultiServiceFactory> xFactory(GetImport().GetModel(),UNO_QUERY);
235 	if( xFactory.is() )
236 	{
237 		Sequence<rtl::OUString> aServices = xFactory->getAvailableServiceNames();
238 		sal_Bool bFound(sal_False);
239 		sal_Int32 i(0);
240 		sal_Int32 nServiceCount(aServices.getLength());
241 		while (i < nServiceCount && !bFound)
242 		{
243 			if (aServices[i].equals(sFieldMaster_Bibliography))
244 			// here we should use a methode which compares in reverse order if available
245 			// #85282#
246 				bFound = sal_True;
247 			else
248 				i++;
249 		}
250 		if (bFound)
251 		{
252 			Reference<XInterface> xIfc =
253 				xFactory->createInstance(sFieldMaster_Bibliography);
254 			if( xIfc.is() )
255 			{
256 				Reference<XPropertySet> xPropSet( xIfc, UNO_QUERY );
257 				Any aAny;
258 
259                 aAny <<= sSuffix;
260                 xPropSet->setPropertyValue(sBracketAfter, aAny);
261 
262                 aAny <<= sPrefix;
263                 xPropSet->setPropertyValue(sBracketBefore, aAny);
264 
265 				aAny.setValue(&bNumberedEntries, ::getBooleanCppuType());
266 				xPropSet->setPropertyValue(sIsNumberEntries, aAny);
267 
268 				aAny.setValue(&bSortByPosition, ::getBooleanCppuType());
269 				xPropSet->setPropertyValue(sIsSortByPosition, aAny);
270 
271                 if( (aLocale.Language.getLength() > 0) &&
272                     (aLocale.Country.getLength() > 0)     )
273                 {
274                     aAny <<= aLocale;
275                     xPropSet->setPropertyValue(sLocale, aAny);
276                 }
277 
278                 if( sAlgorithm.getLength() > 0 )
279                 {
280                     aAny <<= sAlgorithm;
281                     xPropSet->setPropertyValue(sSortAlgorithm, aAny);
282                 }
283 
284 				sal_Int32 nCount = aSortKeys.size();
285 				Sequence<Sequence<PropertyValue> > aKeysSeq(nCount);
286 				for(i = 0; i < nCount; i++)
287 				{
288 					aKeysSeq[i] = aSortKeys[i];
289 				}
290 				aAny <<= aKeysSeq;
291 				xPropSet->setPropertyValue(sSortKeys, aAny);
292 			}
293 			// else: can't get FieldMaster -> ignore
294 		}
295 	}
296 	// else: can't even get Factory -> ignore
297 }
298