1*63bba73cSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*63bba73cSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*63bba73cSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*63bba73cSAndrew Rist  * distributed with this work for additional information
6*63bba73cSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*63bba73cSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*63bba73cSAndrew Rist  * "License"); you may not use this file except in compliance
9*63bba73cSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*63bba73cSAndrew Rist  *
11*63bba73cSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*63bba73cSAndrew Rist  *
13*63bba73cSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*63bba73cSAndrew Rist  * software distributed under the License is distributed on an
15*63bba73cSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*63bba73cSAndrew Rist  * KIND, either express or implied.  See the License for the
17*63bba73cSAndrew Rist  * specific language governing permissions and limitations
18*63bba73cSAndrew Rist  * under the License.
19*63bba73cSAndrew Rist  *
20*63bba73cSAndrew Rist  *************************************************************/
21*63bba73cSAndrew Rist 
22*63bba73cSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_xmloff.hxx"
26cdf0e10cSrcweir #include "XMLIndexMarkExport.hxx"
27cdf0e10cSrcweir #include <tools/debug.hxx>
28cdf0e10cSrcweir #include <rtl/ustring.hxx>
29cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
30cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
31cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySetInfo.hpp>
32cdf0e10cSrcweir #include <xmloff/xmltoken.hxx>
33cdf0e10cSrcweir #include "xmloff/xmlnmspe.hxx"
34cdf0e10cSrcweir #include <xmloff/xmlexp.hxx>
35cdf0e10cSrcweir #include <xmloff/xmluconv.hxx>
36cdf0e10cSrcweir 
37cdf0e10cSrcweir 
38cdf0e10cSrcweir using namespace ::xmloff::token;
39cdf0e10cSrcweir 
40cdf0e10cSrcweir using ::rtl::OUString;
41cdf0e10cSrcweir using ::rtl::OUStringBuffer;
42cdf0e10cSrcweir using ::com::sun::star::beans::XPropertySet;
43cdf0e10cSrcweir using ::com::sun::star::beans::XPropertySetInfo;
44cdf0e10cSrcweir using ::com::sun::star::uno::Reference;
45cdf0e10cSrcweir using ::com::sun::star::uno::Any;
46cdf0e10cSrcweir 
47cdf0e10cSrcweir 
48cdf0e10cSrcweir 
XMLIndexMarkExport(SvXMLExport & rExp,XMLTextParagraphExport & rParaExp)49cdf0e10cSrcweir XMLIndexMarkExport::XMLIndexMarkExport(
50cdf0e10cSrcweir 	SvXMLExport& rExp,
51cdf0e10cSrcweir 	XMLTextParagraphExport& rParaExp)
52cdf0e10cSrcweir :	sLevel(RTL_CONSTASCII_USTRINGPARAM("Level"))
53cdf0e10cSrcweir ,	sUserIndexName(RTL_CONSTASCII_USTRINGPARAM("UserIndexName"))
54cdf0e10cSrcweir ,	sPrimaryKey(RTL_CONSTASCII_USTRINGPARAM("PrimaryKey"))
55cdf0e10cSrcweir ,	sSecondaryKey(RTL_CONSTASCII_USTRINGPARAM("SecondaryKey"))
56cdf0e10cSrcweir ,	sDocumentIndexMark(RTL_CONSTASCII_USTRINGPARAM("DocumentIndexMark"))
57cdf0e10cSrcweir ,	sIsStart(RTL_CONSTASCII_USTRINGPARAM("IsStart"))
58cdf0e10cSrcweir ,	sIsCollapsed(RTL_CONSTASCII_USTRINGPARAM("IsCollapsed"))
59cdf0e10cSrcweir ,	sAlternativeText(RTL_CONSTASCII_USTRINGPARAM("AlternativeText"))
60cdf0e10cSrcweir ,	sTextReading(RTL_CONSTASCII_USTRINGPARAM("TextReading"))
61cdf0e10cSrcweir ,	sPrimaryKeyReading(RTL_CONSTASCII_USTRINGPARAM("PrimaryKeyReading"))
62cdf0e10cSrcweir ,	sSecondaryKeyReading(RTL_CONSTASCII_USTRINGPARAM("SecondaryKeyReading"))
63cdf0e10cSrcweir ,	sMainEntry(RTL_CONSTASCII_USTRINGPARAM("IsMainEntry"))
64cdf0e10cSrcweir ,	rExport(rExp)
65cdf0e10cSrcweir ,	rParaExport(rParaExp)
66cdf0e10cSrcweir {
67cdf0e10cSrcweir }
68cdf0e10cSrcweir 
69cdf0e10cSrcweir const enum XMLTokenEnum lcl_pTocMarkNames[] =
70cdf0e10cSrcweir 	{ XML_TOC_MARK, XML_TOC_MARK_START, XML_TOC_MARK_END };
71cdf0e10cSrcweir const enum XMLTokenEnum lcl_pUserIndexMarkName[] =
72cdf0e10cSrcweir 	{ XML_USER_INDEX_MARK,
73cdf0e10cSrcweir 		  XML_USER_INDEX_MARK_START, XML_USER_INDEX_MARK_END };
74cdf0e10cSrcweir const enum XMLTokenEnum lcl_pAlphaIndexMarkName[] =
75cdf0e10cSrcweir 	{ XML_ALPHABETICAL_INDEX_MARK,
76cdf0e10cSrcweir 		  XML_ALPHABETICAL_INDEX_MARK_START,
77cdf0e10cSrcweir 		  XML_ALPHABETICAL_INDEX_MARK_END };
78cdf0e10cSrcweir 
79cdf0e10cSrcweir 
~XMLIndexMarkExport()80cdf0e10cSrcweir XMLIndexMarkExport::~XMLIndexMarkExport()
81cdf0e10cSrcweir {
82cdf0e10cSrcweir }
83cdf0e10cSrcweir 
ExportIndexMark(const Reference<XPropertySet> & rPropSet,sal_Bool bAutoStyles)84cdf0e10cSrcweir void XMLIndexMarkExport::ExportIndexMark(
85cdf0e10cSrcweir 	const Reference<XPropertySet> & rPropSet,
86cdf0e10cSrcweir 	sal_Bool bAutoStyles)
87cdf0e10cSrcweir {
88cdf0e10cSrcweir 	/// index marks have no styles!
89cdf0e10cSrcweir 	if (!bAutoStyles)
90cdf0e10cSrcweir 	{
91cdf0e10cSrcweir 		const enum XMLTokenEnum * pElements = NULL;
92cdf0e10cSrcweir 		sal_Int8 nElementNo = -1;
93cdf0e10cSrcweir 
94cdf0e10cSrcweir 		// get index mark
95cdf0e10cSrcweir 		Any aAny;
96cdf0e10cSrcweir 		aAny = rPropSet->getPropertyValue(sDocumentIndexMark);
97cdf0e10cSrcweir 		Reference<XPropertySet> xIndexMarkPropSet;
98cdf0e10cSrcweir 		aAny >>= xIndexMarkPropSet;
99cdf0e10cSrcweir 
100cdf0e10cSrcweir 		// common: handling of start, end, collapsed entries and
101cdf0e10cSrcweir 		// alternative text
102cdf0e10cSrcweir 
103cdf0e10cSrcweir 		// collapsed/alternative text entry?
104cdf0e10cSrcweir 		aAny = rPropSet->getPropertyValue(sIsCollapsed);
105cdf0e10cSrcweir 		if (*(sal_Bool *)aAny.getValue())
106cdf0e10cSrcweir 		{
107cdf0e10cSrcweir 			// collapsed entry: needs alternative text
108cdf0e10cSrcweir 			nElementNo = 0;
109cdf0e10cSrcweir 
110cdf0e10cSrcweir 			aAny = xIndexMarkPropSet->getPropertyValue(sAlternativeText);
111cdf0e10cSrcweir 			OUString sTmp;
112cdf0e10cSrcweir 			aAny >>= sTmp;
113cdf0e10cSrcweir 			DBG_ASSERT(sTmp.getLength() > 0,
114cdf0e10cSrcweir 					   "collapsed index mark without alternative text");
115cdf0e10cSrcweir 			rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_STRING_VALUE, sTmp);
116cdf0e10cSrcweir 		}
117cdf0e10cSrcweir 		else
118cdf0e10cSrcweir 		{
119cdf0e10cSrcweir 			// start and end entries: has ID
120cdf0e10cSrcweir 			aAny = rPropSet->getPropertyValue(sIsStart);
121cdf0e10cSrcweir 			nElementNo = *(sal_Bool *)aAny.getValue() ? 1 : 2;
122cdf0e10cSrcweir 
123cdf0e10cSrcweir 			// generate ID
124cdf0e10cSrcweir 			OUStringBuffer sBuf;
125cdf0e10cSrcweir 			GetID(sBuf, xIndexMarkPropSet);
126cdf0e10cSrcweir 			rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_ID,
127cdf0e10cSrcweir                                  sBuf.makeStringAndClear());
128cdf0e10cSrcweir 		}
129cdf0e10cSrcweir 
130cdf0e10cSrcweir 		// distinguish between TOC, user, alphab. index marks by
131cdf0e10cSrcweir 		// asking for specific properties
132cdf0e10cSrcweir 		// Export attributes for -mark-start and -mark elements,
133cdf0e10cSrcweir 		// but not for -mark-end
134cdf0e10cSrcweir 		Reference<XPropertySetInfo> xPropertySetInfo =
135cdf0e10cSrcweir 			xIndexMarkPropSet->getPropertySetInfo();
136cdf0e10cSrcweir 		if (xPropertySetInfo->hasPropertyByName(sUserIndexName))
137cdf0e10cSrcweir 		{
138cdf0e10cSrcweir 			// user index mark
139cdf0e10cSrcweir 			pElements = lcl_pUserIndexMarkName;
140cdf0e10cSrcweir 			if (nElementNo != 2)
141cdf0e10cSrcweir 			{
142cdf0e10cSrcweir 				ExportUserIndexMarkAttributes(xIndexMarkPropSet);
143cdf0e10cSrcweir 			}
144cdf0e10cSrcweir 		}
145cdf0e10cSrcweir 		else if (xPropertySetInfo->hasPropertyByName(sPrimaryKey))
146cdf0e10cSrcweir 		{
147cdf0e10cSrcweir 			// alphabetical index mark
148cdf0e10cSrcweir 			pElements = lcl_pAlphaIndexMarkName;
149cdf0e10cSrcweir 			if (nElementNo != 2)
150cdf0e10cSrcweir 			{
151cdf0e10cSrcweir 				ExportAlphabeticalIndexMarkAttributes(xIndexMarkPropSet);
152cdf0e10cSrcweir 			}
153cdf0e10cSrcweir 		}
154cdf0e10cSrcweir 		else
155cdf0e10cSrcweir 		{
156cdf0e10cSrcweir 			// table of content:
157cdf0e10cSrcweir 			pElements = lcl_pTocMarkNames;
158cdf0e10cSrcweir 			if (nElementNo != 2)
159cdf0e10cSrcweir 			{
160cdf0e10cSrcweir 				ExportTOCMarkAttributes(xIndexMarkPropSet);
161cdf0e10cSrcweir 			}
162cdf0e10cSrcweir 		}
163cdf0e10cSrcweir 
164cdf0e10cSrcweir 		// export element
165cdf0e10cSrcweir 		DBG_ASSERT(pElements != NULL, "illegal element array");
166cdf0e10cSrcweir 		DBG_ASSERT(nElementNo >= 0, "illegal name array index");
167cdf0e10cSrcweir 		DBG_ASSERT(nElementNo <= 2, "illegal name array index");
168cdf0e10cSrcweir 
169cdf0e10cSrcweir 		if ((pElements != NULL) && (nElementNo != -1))
170cdf0e10cSrcweir 		{
171cdf0e10cSrcweir 			SvXMLElementExport aElem(rExport,
172cdf0e10cSrcweir 									 XML_NAMESPACE_TEXT,
173cdf0e10cSrcweir 									 pElements[nElementNo],
174cdf0e10cSrcweir 									 sal_False, sal_False);
175cdf0e10cSrcweir 		}
176cdf0e10cSrcweir 	}
177cdf0e10cSrcweir }
178cdf0e10cSrcweir 
ExportTOCMarkAttributes(const Reference<XPropertySet> & rPropSet)179cdf0e10cSrcweir void XMLIndexMarkExport::ExportTOCMarkAttributes(
180cdf0e10cSrcweir 	const Reference<XPropertySet> & rPropSet)
181cdf0e10cSrcweir {
182cdf0e10cSrcweir 	// outline level
183cdf0e10cSrcweir 	sal_Int16 nLevel = 0;
184cdf0e10cSrcweir 	Any aAny = rPropSet->getPropertyValue(sLevel);
185cdf0e10cSrcweir 	aAny >>= nLevel;
186cdf0e10cSrcweir 	OUStringBuffer sBuf;
187cdf0e10cSrcweir 	SvXMLUnitConverter::convertNumber(sBuf, (sal_Int32)nLevel + 1);
188cdf0e10cSrcweir 	rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_OUTLINE_LEVEL,
189cdf0e10cSrcweir 							 sBuf.makeStringAndClear());
190cdf0e10cSrcweir }
191cdf0e10cSrcweir 
lcl_ExportPropertyString(SvXMLExport & rExport,const Reference<XPropertySet> & rPropSet,const OUString sProperty,XMLTokenEnum eToken,Any & rAny)192cdf0e10cSrcweir void lcl_ExportPropertyString( SvXMLExport& rExport,
193cdf0e10cSrcweir                                const Reference<XPropertySet> & rPropSet,
194cdf0e10cSrcweir                                const OUString sProperty,
195cdf0e10cSrcweir                                XMLTokenEnum eToken,
196cdf0e10cSrcweir                                Any& rAny )
197cdf0e10cSrcweir {
198cdf0e10cSrcweir     rAny = rPropSet->getPropertyValue( sProperty );
199cdf0e10cSrcweir 
200cdf0e10cSrcweir 	OUString sValue;
201cdf0e10cSrcweir 	if( rAny >>= sValue )
202cdf0e10cSrcweir     {
203cdf0e10cSrcweir         if( sValue.getLength() > 0 )
204cdf0e10cSrcweir         {
205cdf0e10cSrcweir             rExport.AddAttribute( XML_NAMESPACE_TEXT, eToken, sValue );
206cdf0e10cSrcweir         }
207cdf0e10cSrcweir 	}
208cdf0e10cSrcweir }
209cdf0e10cSrcweir 
lcl_ExportPropertyBool(SvXMLExport & rExport,const Reference<XPropertySet> & rPropSet,const OUString sProperty,XMLTokenEnum eToken,Any & rAny)210cdf0e10cSrcweir void lcl_ExportPropertyBool( SvXMLExport& rExport,
211cdf0e10cSrcweir                              const Reference<XPropertySet> & rPropSet,
212cdf0e10cSrcweir                              const OUString sProperty,
213cdf0e10cSrcweir                              XMLTokenEnum eToken,
214cdf0e10cSrcweir                              Any& rAny )
215cdf0e10cSrcweir {
216cdf0e10cSrcweir     rAny = rPropSet->getPropertyValue( sProperty );
217cdf0e10cSrcweir 
218cdf0e10cSrcweir 	sal_Bool bValue = sal_Bool();
219cdf0e10cSrcweir 	if( rAny >>= bValue )
220cdf0e10cSrcweir     {
221cdf0e10cSrcweir         if( bValue )
222cdf0e10cSrcweir         {
223cdf0e10cSrcweir             rExport.AddAttribute( XML_NAMESPACE_TEXT, eToken, XML_TRUE );
224cdf0e10cSrcweir         }
225cdf0e10cSrcweir 	}
226cdf0e10cSrcweir }
227cdf0e10cSrcweir 
ExportUserIndexMarkAttributes(const Reference<XPropertySet> & rPropSet)228cdf0e10cSrcweir void XMLIndexMarkExport::ExportUserIndexMarkAttributes(
229cdf0e10cSrcweir 	const Reference<XPropertySet> & rPropSet)
230cdf0e10cSrcweir {
231cdf0e10cSrcweir 	// name of user index
232cdf0e10cSrcweir 	// (unless it's the default index; then it has no name)
233cdf0e10cSrcweir     Any aAny;
234cdf0e10cSrcweir     lcl_ExportPropertyString( rExport, rPropSet, sUserIndexName, XML_INDEX_NAME, aAny );
235cdf0e10cSrcweir 
236cdf0e10cSrcweir     // additionally export outline level; just reuse ExportTOCMarkAttributes
237cdf0e10cSrcweir     ExportTOCMarkAttributes( rPropSet );
238cdf0e10cSrcweir }
239cdf0e10cSrcweir 
ExportAlphabeticalIndexMarkAttributes(const Reference<XPropertySet> & rPropSet)240cdf0e10cSrcweir void XMLIndexMarkExport::ExportAlphabeticalIndexMarkAttributes(
241cdf0e10cSrcweir 	const Reference<XPropertySet> & rPropSet)
242cdf0e10cSrcweir {
243cdf0e10cSrcweir 	// primary and secondary keys (if available)
244cdf0e10cSrcweir     Any aAny;
245cdf0e10cSrcweir     lcl_ExportPropertyString( rExport, rPropSet, sTextReading, XML_STRING_VALUE_PHONETIC, aAny );
246cdf0e10cSrcweir     lcl_ExportPropertyString( rExport, rPropSet, sPrimaryKey, XML_KEY1, aAny );
247cdf0e10cSrcweir     lcl_ExportPropertyString( rExport, rPropSet, sPrimaryKeyReading, XML_KEY1_PHONETIC, aAny );
248cdf0e10cSrcweir     lcl_ExportPropertyString( rExport, rPropSet, sSecondaryKey, XML_KEY2, aAny );
249cdf0e10cSrcweir     lcl_ExportPropertyString( rExport, rPropSet, sSecondaryKeyReading, XML_KEY2_PHONETIC, aAny );
250cdf0e10cSrcweir     lcl_ExportPropertyBool( rExport, rPropSet, sMainEntry, XML_MAIN_ENTRY, aAny );
251cdf0e10cSrcweir }
252cdf0e10cSrcweir 
GetID(OUStringBuffer & sBuf,const Reference<XPropertySet> & rPropSet)253cdf0e10cSrcweir void XMLIndexMarkExport::GetID(
254cdf0e10cSrcweir 	OUStringBuffer& sBuf,
255cdf0e10cSrcweir 	const Reference<XPropertySet> & rPropSet)
256cdf0e10cSrcweir {
257cdf0e10cSrcweir 	static const sal_Char sPrefix[] = "IMark";
258cdf0e10cSrcweir 
259cdf0e10cSrcweir 	// HACK: use address of object to form identifier
260cdf0e10cSrcweir 	sal_Int64 nId = sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(rPropSet.get()));
261cdf0e10cSrcweir 	sBuf.appendAscii(sPrefix, sizeof(sPrefix)-1);
262cdf0e10cSrcweir 	sBuf.append(nId);
263cdf0e10cSrcweir }
264