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 #include "layerimport.hxx"
31 #include "formenums.hxx"
32 #include "elementimport.hxx"
33 #include "officeforms.hxx"
34 #include "strings.hxx"
35 #include "formstyles.hxx"
36 #include <xmloff/xmlictxt.hxx>
37 #include <xmloff/xmlstyle.hxx>
38 #include <xmloff/families.hxx>
39 #include <xmloff/xmlprmap.hxx>
40 #include <xmloff/prstylei.hxx>
41 #include <xmloff/xmlimp.hxx>
42 #include "XMLEventImportHelper.hxx"
43 #include <xmloff/xmlimppr.hxx>
44 #include <xmloff/xmlnumfi.hxx>
45 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
46 #include <com/sun/star/form/FormSubmitEncoding.hpp>
47 #include <com/sun/star/form/FormSubmitMethod.hpp>
48 #include <com/sun/star/sdb/CommandType.hpp>
49 #include <com/sun/star/form/NavigationBarMode.hpp>
50 #include <com/sun/star/form/TabulatorCycle.hpp>
51 #include <com/sun/star/form/FormButtonType.hpp>
52 #include <com/sun/star/awt/ScrollBarOrientation.hpp>
53 #include <com/sun/star/awt/VisualEffect.hpp>
54 #include <com/sun/star/form/ListSourceType.hpp>
55 #include <tools/wintypes.hxx>		// for check states
56 #include <com/sun/star/lang/Locale.hpp>
57 #include <xmloff/controlpropertyhdl.hxx>
58 #include "controlpropertymap.hxx"
59 #include "formevents.hxx"
60 #include "formcellbinding.hxx"
61 #include "xmloff/xformsimport.hxx"
62 #include <xmloff/xmltoken.hxx>
63 #include "xmloff/xmlnmspe.hxx"
64 #include <rtl/logfile.hxx>
65 #include <algorithm>
66 
67 SV_IMPL_REF( SvXMLStylesContext );
68 
69 //.........................................................................
70 namespace xmloff
71 {
72 //.........................................................................
73 
74 using namespace ::com::sun::star::uno;
75 using namespace ::com::sun::star::awt;
76 using namespace ::com::sun::star::lang;
77 using namespace ::com::sun::star::beans;
78 using namespace ::com::sun::star::container;
79 using namespace ::com::sun::star::drawing;
80 using namespace ::com::sun::star::xml;
81 using namespace ::com::sun::star::util;
82 using namespace ::com::sun::star::form;
83 using namespace ::com::sun::star::sdb;
84 
85 //=====================================================================
86 //= OFormLayerXMLImport_Impl
87 //=====================================================================
88 //---------------------------------------------------------------------
89 OFormLayerXMLImport_Impl::OFormLayerXMLImport_Impl(SvXMLImport& _rImporter)
90 	:m_rImporter(_rImporter)
91 	,m_pAutoStyles(NULL)
92 {
93 	// build the attribute2property map
94 	// string properties which are exported as attributes
95 	m_aAttributeMetaData.addStringProperty(
96 		OAttributeMetaData::getCommonControlAttributeName(CCA_NAME), PROPERTY_NAME);
97 	m_aAttributeMetaData.addStringProperty(
98 		OAttributeMetaData::getCommonControlAttributeName(CCA_IMAGE_DATA), PROPERTY_IMAGEURL);
99 	m_aAttributeMetaData.addStringProperty(
100 		OAttributeMetaData::getCommonControlAttributeName(CCA_LABEL), PROPERTY_LABEL);
101 	m_aAttributeMetaData.addStringProperty(
102 		OAttributeMetaData::getCommonControlAttributeName(CCA_TARGET_LOCATION), PROPERTY_TARGETURL);
103 	m_aAttributeMetaData.addStringProperty(
104 		OAttributeMetaData::getCommonControlAttributeName(CCA_TITLE), PROPERTY_TITLE);
105 	m_aAttributeMetaData.addStringProperty(
106 		OAttributeMetaData::getCommonControlAttributeName(CCA_TARGET_FRAME), PROPERTY_TARGETFRAME, "_blank");
107 	m_aAttributeMetaData.addStringProperty(
108 		OAttributeMetaData::getDatabaseAttributeName(DA_DATA_FIELD), PROPERTY_DATAFIELD);
109 	m_aAttributeMetaData.addStringProperty(
110 		OAttributeMetaData::getFormAttributeName(faCommand), PROPERTY_COMMAND);
111 	m_aAttributeMetaData.addStringProperty(
112 		OAttributeMetaData::getFormAttributeName(faDatasource), PROPERTY_DATASOURCENAME);
113 	m_aAttributeMetaData.addStringProperty(
114 		OAttributeMetaData::getFormAttributeName(faFilter), PROPERTY_FILTER);
115 	m_aAttributeMetaData.addStringProperty(
116 		OAttributeMetaData::getFormAttributeName(faOrder), PROPERTY_ORDER);
117 
118 	// properties not added because they're already present in another form
119 	OSL_ENSURE(
120 		0 == ::rtl::OUString::createFromAscii(OAttributeMetaData::getCommonControlAttributeName(CCA_TARGET_LOCATION)).compareToAscii(
121 			OAttributeMetaData::getFormAttributeName(faAction)),
122 		"OFormLayerXMLImport_Impl::OFormLayerXMLImport_Impl: invalid attribute names (1)!");
123 		// if this fails, we would have to add a translation from faAction->PROPERTY_TARGETURL
124 		// We did not because we already have one CCA_TARGET_LOCATION->PROPERTY_TARGETURL,
125 		// and CCA_TARGET_LOCATION and faAction should be represented by the same attribute
126 
127 	OSL_ENSURE(
128 		0 == ::rtl::OUString::createFromAscii(OAttributeMetaData::getCommonControlAttributeName(CCA_NAME)).compareToAscii(
129 			OAttributeMetaData::getFormAttributeName(faName)),
130 		"OFormLayerXMLImport_Impl::OFormLayerXMLImport_Impl: invalid attribute names (2)!");
131 		// the same for faName, CCA_NAME and PROPERTY_NAME
132 
133 	// boolean properties which are exported as attributes
134 	m_aAttributeMetaData.addBooleanProperty(
135 		OAttributeMetaData::getCommonControlAttributeName(CCA_CURRENT_SELECTED), PROPERTY_STATE, sal_False);
136 	m_aAttributeMetaData.addBooleanProperty(
137 		OAttributeMetaData::getCommonControlAttributeName(CCA_DISABLED), PROPERTY_ENABLED, sal_False, sal_True);
138 	m_aAttributeMetaData.addBooleanProperty(
139 		OAttributeMetaData::getCommonControlAttributeName(CCA_DROPDOWN), PROPERTY_DROPDOWN, sal_False);
140 	m_aAttributeMetaData.addBooleanProperty(
141 		OAttributeMetaData::getCommonControlAttributeName(CCA_PRINTABLE), PROPERTY_PRINTABLE, sal_True);
142 	m_aAttributeMetaData.addBooleanProperty(
143 		OAttributeMetaData::getCommonControlAttributeName(CCA_READONLY), PROPERTY_READONLY, sal_False);
144 	m_aAttributeMetaData.addBooleanProperty(
145 		OAttributeMetaData::getCommonControlAttributeName(CCA_SELECTED), PROPERTY_DEFAULT_STATE, sal_False);
146 	m_aAttributeMetaData.addBooleanProperty(
147 		OAttributeMetaData::getCommonControlAttributeName(CCA_TAB_STOP), PROPERTY_TABSTOP, sal_True);
148 	m_aAttributeMetaData.addBooleanProperty(
149 		OAttributeMetaData::getDatabaseAttributeName(DA_CONVERT_EMPTY), PROPERTY_EMPTY_IS_NULL, sal_False);
150 	m_aAttributeMetaData.addBooleanProperty(
151 		OAttributeMetaData::getSpecialAttributeName(SCA_VALIDATION), PROPERTY_STRICTFORMAT, sal_False);
152 	m_aAttributeMetaData.addBooleanProperty(
153 		OAttributeMetaData::getSpecialAttributeName(SCA_MULTI_LINE), PROPERTY_MULTILINE, sal_False);
154 	m_aAttributeMetaData.addBooleanProperty(
155 		OAttributeMetaData::getSpecialAttributeName(SCA_AUTOMATIC_COMPLETION), PROPERTY_AUTOCOMPLETE, sal_False);
156 	m_aAttributeMetaData.addBooleanProperty(
157 		OAttributeMetaData::getSpecialAttributeName(SCA_MULTIPLE), PROPERTY_MULTISELECTION, sal_False);
158 	m_aAttributeMetaData.addBooleanProperty(
159 		OAttributeMetaData::getSpecialAttributeName(SCA_DEFAULT_BUTTON), PROPERTY_DEFAULTBUTTON, sal_False);
160 	m_aAttributeMetaData.addBooleanProperty(
161 		OAttributeMetaData::getSpecialAttributeName(SCA_IS_TRISTATE), PROPERTY_TRISTATE, sal_False);
162 	m_aAttributeMetaData.addBooleanProperty(
163 		OAttributeMetaData::getFormAttributeName(faAllowDeletes), PROPERTY_ALLOWDELETES, sal_True);
164 	m_aAttributeMetaData.addBooleanProperty(
165 		OAttributeMetaData::getFormAttributeName(faAllowInserts), PROPERTY_ALLOWINSERTS, sal_True);
166 	m_aAttributeMetaData.addBooleanProperty(
167 		OAttributeMetaData::getFormAttributeName(faAllowUpdates), PROPERTY_ALLOWUPDATES, sal_True);
168 	m_aAttributeMetaData.addBooleanProperty(
169 		OAttributeMetaData::getFormAttributeName(faApplyFilter), PROPERTY_APPLYFILTER, sal_False);
170 	m_aAttributeMetaData.addBooleanProperty(
171 		OAttributeMetaData::getFormAttributeName(faEscapeProcessing), PROPERTY_ESCAPEPROCESSING, sal_True);
172 	m_aAttributeMetaData.addBooleanProperty(
173 		OAttributeMetaData::getFormAttributeName(faIgnoreResult), PROPERTY_IGNORERESULT, sal_False);
174 	m_aAttributeMetaData.addBooleanProperty(
175 		OAttributeMetaData::getSpecialAttributeName( SCA_TOGGLE ), PROPERTY_TOGGLE, sal_False );
176 	m_aAttributeMetaData.addBooleanProperty(
177 		OAttributeMetaData::getSpecialAttributeName( SCA_FOCUS_ON_CLICK ), PROPERTY_FOCUS_ON_CLICK, sal_True );
178 	m_aAttributeMetaData.addBooleanProperty(
179 		OAttributeMetaData::getDatabaseAttributeName( DA_INPUT_REQUIRED ), PROPERTY_INPUT_REQUIRED, sal_False );
180 
181 	// the int16 attributes
182 	m_aAttributeMetaData.addInt16Property(
183 		OAttributeMetaData::getCommonControlAttributeName(CCA_MAX_LENGTH), PROPERTY_MAXTEXTLENGTH, 0);
184 	m_aAttributeMetaData.addInt16Property(
185 		OAttributeMetaData::getCommonControlAttributeName(CCA_SIZE), PROPERTY_LINECOUNT, 5);
186 	m_aAttributeMetaData.addInt16Property(
187 		OAttributeMetaData::getCommonControlAttributeName(CCA_TAB_INDEX), PROPERTY_TABINDEX, 0);
188 	m_aAttributeMetaData.addInt16Property(
189 		OAttributeMetaData::getDatabaseAttributeName(DA_BOUND_COLUMN), PROPERTY_BOUNDCOLUMN, 0);
190 
191 	// the int32 attributes
192 	m_aAttributeMetaData.addInt32Property(
193 		OAttributeMetaData::getSpecialAttributeName( SCA_PAGE_STEP_SIZE ), PROPERTY_BLOCK_INCREMENT, 10 );
194 
195 	// the enum attributes
196 	m_aAttributeMetaData.addEnumProperty(
197 		OAttributeMetaData::getCommonControlAttributeName( CCA_VISUAL_EFFECT ), PROPERTY_VISUAL_EFFECT,
198 		VisualEffect::LOOK3D, OEnumMapper::getEnumMap( OEnumMapper::epVisualEffect ),
199 		&::getCppuType( static_cast< sal_Int16* >( NULL ) ) );
200 	m_aAttributeMetaData.addEnumProperty(
201 		OAttributeMetaData::getCommonControlAttributeName( CCA_ORIENTATION ), PROPERTY_ORIENTATION,
202 		ScrollBarOrientation::HORIZONTAL, OEnumMapper::getEnumMap( OEnumMapper::epOrientation ),
203 		&::getCppuType( static_cast< sal_Int32* >( NULL ) ) );
204 	m_aAttributeMetaData.addEnumProperty(
205 		OAttributeMetaData::getCommonControlAttributeName(CCA_BUTTON_TYPE), PROPERTY_BUTTONTYPE,
206 		FormButtonType_PUSH, OEnumMapper::getEnumMap(OEnumMapper::epButtonType),
207 		&::getCppuType( static_cast<FormButtonType*>(NULL) ));
208 	m_aAttributeMetaData.addEnumProperty(
209 		OAttributeMetaData::getDatabaseAttributeName(DA_LIST_SOURCE_TYPE), PROPERTY_LISTSOURCETYPE,
210 		ListSourceType_VALUELIST, OEnumMapper::getEnumMap(OEnumMapper::epListSourceType),
211 		&::getCppuType( static_cast<ListSourceType*>(NULL) ));
212 	m_aAttributeMetaData.addEnumProperty(
213 		OAttributeMetaData::getSpecialAttributeName(SCA_STATE), PROPERTY_DEFAULT_STATE, STATE_NOCHECK,
214 		OEnumMapper::getEnumMap(OEnumMapper::epCheckState),
215 		&::getCppuType( static_cast< sal_Int16* >(NULL)));
216 	m_aAttributeMetaData.addEnumProperty(
217 		OAttributeMetaData::getSpecialAttributeName(SCA_CURRENT_STATE), PROPERTY_STATE, STATE_NOCHECK,
218 		OEnumMapper::getEnumMap(OEnumMapper::epCheckState),
219 		&::getCppuType( static_cast< sal_Int16* >(NULL)));
220 	m_aAttributeMetaData.addEnumProperty(
221 		OAttributeMetaData::getFormAttributeName(faEnctype), PROPERTY_SUBMIT_ENCODING,
222 		FormSubmitEncoding_URL, OEnumMapper::getEnumMap(OEnumMapper::epSubmitEncoding),
223 		&::getCppuType( static_cast<FormSubmitEncoding*>(NULL) ));
224 	m_aAttributeMetaData.addEnumProperty(
225 		OAttributeMetaData::getFormAttributeName(faMethod), PROPERTY_SUBMIT_METHOD,
226 		FormSubmitMethod_GET, OEnumMapper::getEnumMap(OEnumMapper::epSubmitMethod),
227 		&::getCppuType( static_cast<FormSubmitMethod*>(NULL) ));
228 	m_aAttributeMetaData.addEnumProperty(
229 		OAttributeMetaData::getFormAttributeName(faCommandType), PROPERTY_COMMAND_TYPE,
230 		CommandType::COMMAND, OEnumMapper::getEnumMap(OEnumMapper::epCommandType));
231 	m_aAttributeMetaData.addEnumProperty(
232 		OAttributeMetaData::getFormAttributeName(faNavigationMode), PROPERTY_NAVIGATION,
233 		NavigationBarMode_NONE, OEnumMapper::getEnumMap(OEnumMapper::epNavigationType),
234 		&::getCppuType( static_cast<NavigationBarMode*>(NULL) ));
235 	m_aAttributeMetaData.addEnumProperty(
236 		OAttributeMetaData::getFormAttributeName(faTabbingCycle), PROPERTY_CYCLE,
237 		TabulatorCycle_RECORDS, OEnumMapper::getEnumMap(OEnumMapper::epTabCyle),
238 		&::getCppuType( static_cast<TabulatorCycle*>(NULL) ));
239 
240 	// 'initialize'
241 	m_aCurrentPageIds = m_aControlIds.end();
242 }
243 
244 //---------------------------------------------------------------------
245 OFormLayerXMLImport_Impl::~OFormLayerXMLImport_Impl()
246 {
247 	// outlined to allow forward declaration of OAttribute2Property in the header
248 
249 	if (m_pAutoStyles)
250 		m_pAutoStyles->ReleaseRef();
251 }
252 
253 //---------------------------------------------------------------------
254 void OFormLayerXMLImport_Impl::setAutoStyleContext(SvXMLStylesContext* _pNewContext)
255 {
256 	OSL_ENSURE(!m_pAutoStyles, "OFormLayerXMLImport_Impl::setAutoStyleContext: not to be called twice!");
257 	m_pAutoStyles = _pNewContext;
258 	if (m_pAutoStyles)
259 		m_pAutoStyles->AddRef();
260 }
261 
262 //---------------------------------------------------------------------
263 void OFormLayerXMLImport_Impl::applyControlNumberStyle(const Reference< XPropertySet >& _rxControlModel, const ::rtl::OUString& _rControlNumerStyleName)
264 {
265 	OSL_ENSURE(_rxControlModel.is() && (0 != _rControlNumerStyleName.getLength()),
266 		"OFormLayerXMLImport_Impl::applyControlNumberStyle: invalid arguments (this will crash)!");
267 
268 	OSL_ENSURE(m_pAutoStyles, "OFormLayerXMLImport_Impl::applyControlNumberStyle: have no auto style context!");
269 	if (!m_pAutoStyles)
270 	{
271 		m_pAutoStyles = m_rImporter.GetShapeImport()->GetAutoStylesContext();
272 		if (m_pAutoStyles)
273 			m_pAutoStyles->AddRef();
274 	}
275 
276 	if (m_pAutoStyles)
277 	{
278 		const SvXMLStyleContext* pStyle = m_pAutoStyles->FindStyleChildContext(XML_STYLE_FAMILY_DATA_STYLE, _rControlNumerStyleName);
279 		if (pStyle)
280 		{
281 			const SvXMLNumFormatContext* pDataStyle = static_cast<const SvXMLNumFormatContext*>(pStyle);
282 
283 			// set this format at the control model
284 			try
285 			{
286 				// the models number format supplier and formats
287 				Reference< XNumberFormatsSupplier > xFormatsSupplier;
288 				_rxControlModel->getPropertyValue(PROPERTY_FORMATSSUPPLIER) >>= xFormatsSupplier;
289 				Reference< XNumberFormats > xFormats;
290 				if (xFormatsSupplier.is())
291 					xFormats = xFormatsSupplier->getNumberFormats();
292 				OSL_ENSURE(xFormats.is(), "OFormLayerXMLImport_Impl::applyControlNumberStyle: could not obtain the controls number formats!");
293 
294 				// obtain a key
295 				if (xFormats.is())
296 				{
297 			        sal_Int32 nFormatKey = const_cast<SvXMLNumFormatContext*>(pDataStyle)->CreateAndInsert( xFormatsSupplier );
298 					OSL_ENSURE(-1 != nFormatKey, "OFormLayerXMLImport_Impl::applyControlNumberStyle: could not obtain a format key!");
299 
300                     // set the format on the control model
301 					_rxControlModel->setPropertyValue(PROPERTY_FORMATKEY, makeAny(nFormatKey));
302 				}
303 			}
304 			catch(const Exception&)
305 			{
306 				OSL_ENSURE(sal_False, "OFormLayerXMLImport_Impl::applyControlNumberStyle: couldn't set the format!");
307 			}
308 		}
309 		else
310 			OSL_ENSURE(sal_False, "OFormLayerXMLImport_Impl::applyControlNumberStyle: did not find the style with the given name!");
311 	}
312 }
313 
314 //---------------------------------------------------------------------
315 void OFormLayerXMLImport_Impl::registerCellValueBinding( const Reference< XPropertySet >& _rxControlModel, const ::rtl::OUString& _rCellAddress )
316 {
317     OSL_ENSURE( _rxControlModel.is() && _rCellAddress.getLength(),
318         "OFormLayerXMLImport_Impl::registerCellValueBinding: invalid arguments!" );
319     m_aCellValueBindings.push_back( ModelStringPair( _rxControlModel, _rCellAddress ) );
320 }
321 
322 //---------------------------------------------------------------------
323 void OFormLayerXMLImport_Impl::registerXFormsValueBinding(
324     const Reference< XPropertySet >& _rxControlModel,
325     const ::rtl::OUString& _rBindingID )
326 {
327     // TODO: is an empty binding name allowed?
328     OSL_ENSURE( _rxControlModel.is(), "need  model" );
329 
330     m_aXFormsValueBindings.push_back(
331         ModelStringPair( _rxControlModel, _rBindingID ) );
332 }
333 
334 //---------------------------------------------------------------------
335 void OFormLayerXMLImport_Impl::registerXFormsListBinding(
336     const Reference< XPropertySet >& _rxControlModel,
337     const ::rtl::OUString& _rBindingID )
338 {
339     // TODO: is an empty binding name allowed?
340     OSL_ENSURE( _rxControlModel.is(), "need  model" );
341 
342     m_aXFormsListBindings.push_back(
343         ModelStringPair( _rxControlModel, _rBindingID ) );
344 }
345 
346 //---------------------------------------------------------------------
347 void OFormLayerXMLImport_Impl::registerXFormsSubmission(
348     const Reference< XPropertySet >& _rxControlModel,
349     const ::rtl::OUString& _rSubmissionID )
350 {
351     // TODO: is an empty binding name allowed?
352     OSL_ENSURE( _rxControlModel.is(), "need  model" );
353 
354     m_aXFormsSubmissions.push_back(
355         ModelStringPair( _rxControlModel, _rSubmissionID ) );
356 }
357 
358 //---------------------------------------------------------------------
359 void OFormLayerXMLImport_Impl::registerCellRangeListSource( const Reference< XPropertySet >& _rxControlModel, const ::rtl::OUString& _rCellRangeAddress )
360 {
361     OSL_ENSURE( _rxControlModel.is() && _rCellRangeAddress.getLength(),
362         "OFormLayerXMLImport_Impl::registerCellRangeListSource: invalid arguments!" );
363     m_aCellRangeListSources.push_back( ModelStringPair( _rxControlModel, _rCellRangeAddress ) );
364 }
365 //---------------------------------------------------------------------
366 const SvXMLStyleContext* OFormLayerXMLImport_Impl::getStyleElement(const ::rtl::OUString& _rStyleName) const
367 {
368 	OSL_ENSURE( m_pAutoStyles, "OFormLayerXMLImport_Impl::getStyleElement: have no auto style context!" );
369 		// did you use setAutoStyleContext?
370 
371 	const SvXMLStyleContext* pControlStyle =
372 		m_pAutoStyles ? m_pAutoStyles->FindStyleChildContext( XML_STYLE_FAMILY_TEXT_PARAGRAPH, _rStyleName ) : NULL;
373 	OSL_ENSURE( pControlStyle || !m_pAutoStyles,
374 				::rtl::OString( "OFormLayerXMLImport_Impl::getStyleElement: did not find the style named \"" )
375 			+=	::rtl::OString( _rStyleName.getStr(), _rStyleName.getLength(), RTL_TEXTENCODING_ASCII_US )
376 			+=	::rtl::OString( "\"!" ) );
377 	return pControlStyle;
378 }
379 
380 //---------------------------------------------------------------------
381 void OFormLayerXMLImport_Impl::enterEventContext()
382 {
383 	// install our own translation table. We need to disable the other tables because of name conflicts.
384 	m_rImporter.GetEventImport().PushTranslationTable();
385 	m_rImporter.GetEventImport().AddTranslationTable(g_pFormsEventTranslation);
386 }
387 
388 //---------------------------------------------------------------------
389 void OFormLayerXMLImport_Impl::leaveEventContext()
390 {
391 	// install the original event tables.
392 	m_rImporter.GetEventImport().PopTranslationTable();
393 }
394 
395 //---------------------------------------------------------------------
396 void OFormLayerXMLImport_Impl::registerControlId(const Reference< XPropertySet >& _rxControl, const ::rtl::OUString& _rId)
397 {
398 	OSL_ENSURE(m_aCurrentPageIds != m_aControlIds.end(), "OFormLayerXMLImport_Impl::registerControlId: no current page!");
399 	OSL_ENSURE(_rId.getLength(), "OFormLayerXMLImport_Impl::registerControlId: invalid (empty) control id!");
400 
401 	OSL_ENSURE(m_aCurrentPageIds->second.end() == m_aCurrentPageIds->second.find(_rId), "OFormLayerXMLImport_Impl::registerControlId: control id already used!");
402 	m_aCurrentPageIds->second[_rId] = _rxControl;
403 }
404 
405 //---------------------------------------------------------------------
406 void OFormLayerXMLImport_Impl::registerControlReferences(const Reference< XPropertySet >& _rxControl, const ::rtl::OUString& _rReferringControls)
407 {
408 	OSL_ENSURE(_rReferringControls.getLength(), "OFormLayerXMLImport_Impl::registerControlReferences: invalid (empty) control id list!");
409 	OSL_ENSURE(_rxControl.is(), "OFormLayerXMLImport_Impl::registerControlReferences: invalid (NULL) control!");
410 	m_aControlReferences.push_back( ModelStringPair( _rxControl, _rReferringControls ) );
411 }
412 
413 //---------------------------------------------------------------------
414 void OFormLayerXMLImport_Impl::startPage(const Reference< XDrawPage >& _rxDrawPage)
415 {
416 	m_xCurrentPageFormsSupp.clear();
417 
418 	OSL_ENSURE(_rxDrawPage.is(), "OFormLayerXMLImport_Impl::startPage: NULL page!");
419 	m_xCurrentPageFormsSupp = m_xCurrentPageFormsSupp.query( _rxDrawPage );
420 	OSL_ENSURE( m_xCurrentPageFormsSupp.is(), "OFormLayerXMLImport_Impl::startPage: invalid draw page (no XFormsSupplier)!" );
421 	if ( !m_xCurrentPageFormsSupp.is() )
422 		return;
423 
424 	// add a new entry to our page map
425 	::std::pair< MapDrawPage2MapIterator, bool > aPagePosition;
426 	aPagePosition =
427 		m_aControlIds.insert(MapDrawPage2Map::value_type(_rxDrawPage, MapString2PropertySet()));
428 	OSL_ENSURE(aPagePosition.second, "OFormLayerXMLImport_Impl::startPage: already imported this page!");
429 	m_aCurrentPageIds = aPagePosition.first;
430 }
431 
432 //---------------------------------------------------------------------
433 void OFormLayerXMLImport_Impl::endPage()
434 {
435 	OSL_ENSURE( m_xCurrentPageFormsSupp.is(), "OFormLayerXMLImport_Impl::endPage: sure you called startPage before?" );
436 
437 	// do some knittings for the controls which are referring to each other
438 	try
439 	{
440 		static const sal_Unicode s_nSeparator = ',';
441 		::rtl::OUString sReferring;
442 		::rtl::OUString sCurrentReferring;
443 		::rtl::OUString sSeparator(&s_nSeparator, 1);
444 		Reference< XPropertySet > xCurrentReferring;
445 		sal_Int32 nSeparator, nPrevSep;
446         ::std::vector< ModelStringPair >::const_iterator aEnd = m_aControlReferences.end();
447         for	(	::std::vector< ModelStringPair >::const_iterator aReferences = m_aControlReferences.begin();
448 				aReferences != aEnd;
449 				++aReferences
450 			)
451 		{
452 			// the list of control ids is comma separated
453 
454 			// in a list of n ids there are only n-1 separators ... have to catch this last id
455 			// -> normalize the list
456 			sReferring = aReferences->second;
457 			sReferring += sSeparator;
458 
459 			nPrevSep = -1;
460 			while (-1 != (nSeparator = sReferring.indexOf(s_nSeparator, nPrevSep + 1)))
461 			{
462 				sCurrentReferring = sReferring.copy(nPrevSep + 1, nSeparator - nPrevSep - 1);
463 				xCurrentReferring = lookupControlId(sCurrentReferring);
464 				if (xCurrentReferring.is())
465 					// if this condition fails, this is an error, but lookupControlId should have asserted this ...
466 					xCurrentReferring->setPropertyValue( PROPERTY_CONTROLLABEL, makeAny( aReferences->first ) );
467 
468 				nPrevSep = nSeparator;
469 			}
470 		}
471 	}
472 	catch(Exception&)
473 	{
474 		OSL_ENSURE(sal_False, "OFormLayerXMLImport_Impl::endPage: unable to knit the control references (caught an exception)!");
475 	}
476 
477 	// now that we have all children of the forms collection, attach the events
478 	Reference< XIndexAccess > xIndexContainer;
479     if ( m_xCurrentPageFormsSupp.is() && m_xCurrentPageFormsSupp->hasForms() )
480         xIndexContainer = xIndexContainer.query( m_xCurrentPageFormsSupp->getForms() );
481 	if ( xIndexContainer.is() )
482 		ODefaultEventAttacherManager::setEvents( xIndexContainer );
483 
484 	// clear the structures for the control references.
485 	m_aControlReferences.clear();
486 
487 	// and no we have no current page anymore
488 	m_aCurrentPageIds = m_aControlIds.end();
489 }
490 
491 //---------------------------------------------------------------------
492 Reference< XPropertySet > OFormLayerXMLImport_Impl::lookupControlId(const ::rtl::OUString& _rControlId)
493 {
494 	OSL_ENSURE(m_aCurrentPageIds != m_aControlIds.end(), "OFormLayerXMLImport_Impl::lookupControlId: no current page!");
495 	Reference< XPropertySet > xReturn;
496 	if (m_aCurrentPageIds != m_aControlIds.end())
497 	{
498 		ConstMapString2PropertySetIterator aPos = m_aCurrentPageIds->second.find(_rControlId);
499 		if (m_aCurrentPageIds->second.end() != aPos)
500 			xReturn = aPos->second;
501 		else
502 			OSL_ENSURE(sal_False, "OFormLayerXMLImport_Impl::lookupControlId: invalid control id (did not find it)!");
503 	}
504 	return xReturn;
505 }
506 
507 //---------------------------------------------------------------------
508 SvXMLImportContext* OFormLayerXMLImport_Impl::createOfficeFormsContext(
509 	SvXMLImport& _rImport,
510 	sal_uInt16 _nPrefix,
511 	const rtl::OUString& _rLocalName)
512 {
513 	return new OFormsRootImport( _rImport, _nPrefix, _rLocalName );
514 }
515 
516 //---------------------------------------------------------------------
517 SvXMLImportContext* OFormLayerXMLImport_Impl::createContext(const sal_uInt16 _nPrefix, const rtl::OUString& _rLocalName,
518 	const Reference< sax::XAttributeList >&)
519 {
520     SvXMLImportContext* pContext = NULL;
521     if ( 0 == _rLocalName.compareToAscii( "form" ) )
522     {
523         if ( m_xCurrentPageFormsSupp.is() )
524             pContext = new OFormImport(*this, *this, _nPrefix, _rLocalName, m_xCurrentPageFormsSupp->getForms() );
525     }
526     else if (  ( _nPrefix == XML_NAMESPACE_XFORMS
527             && ( xmloff::token::IsXMLToken( _rLocalName, xmloff::token::XML_MODEL ) ) )
528             )
529     {
530         pContext = createXFormsModelContext( m_rImporter, _nPrefix, _rLocalName );
531     }
532 
533     if ( !pContext )
534     {
535         OSL_ENSURE( false, "unknown element" );
536         pContext =
537             new SvXMLImportContext(m_rImporter, _nPrefix, _rLocalName);
538     }
539 
540 	return pContext;
541 }
542 
543 //---------------------------------------------------------------------
544 void OFormLayerXMLImport_Impl::seekPage(const Reference< XDrawPage >& _rxDrawPage)
545 {
546 	OSL_ENSURE(m_aCurrentPageIds == m_aControlIds.end(), "OFormLayerXMLImport_Impl::seekPage: importing another page currently! This will smash your import!");
547 	m_aCurrentPageIds = m_aControlIds.find(_rxDrawPage);
548 	OSL_ENSURE(m_aCurrentPageIds != m_aControlIds.end(), "OFormLayerXMLImport_Impl::seekPage: did not find the given page (perhaps it has not been imported, yet?)!");
549 }
550 
551 //---------------------------------------------------------------------
552 void OFormLayerXMLImport_Impl::documentDone( )
553 {
554     SvXMLImport& rImport = getGlobalContext();
555     if ( ( rImport.getImportFlags() & IMPORT_CONTENT ) == 0 )
556         return;
557 
558     // create (and bind) the spreadsheet cell bindings
559     if  (   !m_aCellValueBindings.empty()
560         &&  FormCellBindingHelper::isCellBindingAllowed( rImport.GetModel() )
561         )
562     {
563         static ::rtl::OUString s_sIndex( RTL_CONSTASCII_USTRINGPARAM( ":index" ) );
564         ::std::vector< ModelStringPair >::const_iterator aEnd = m_aCellValueBindings.end();
565         for (   ::std::vector< ModelStringPair >::const_iterator aCellBindings = m_aCellValueBindings.begin();
566                 aCellBindings != aEnd;
567                 ++aCellBindings
568             )
569         {
570             try
571             {
572                 FormCellBindingHelper aHelper( aCellBindings->first, rImport.GetModel() );
573                 OSL_ENSURE( aHelper.isCellBindingAllowed(), "OFormLayerXMLImport_Impl::documentDone: can't bind this control model!" );
574                 if ( aHelper.isCellBindingAllowed() )
575                 {
576                     // There are special bindings for listboxes. See
577                     // OListAndComboImport::doRegisterCellValueBinding for a comment on this HACK.
578                     ::rtl::OUString sBoundCellAddress( aCellBindings->second );
579                     sal_Int32 nIndicator = sBoundCellAddress.lastIndexOf( s_sIndex );
580 
581                     bool bUseIndexBinding = false;
582                     if ( nIndicator != -1 )
583                     {
584                         sBoundCellAddress = sBoundCellAddress.copy( 0, nIndicator );
585                         bUseIndexBinding = true;
586                     }
587 
588                     aHelper.setBinding( aHelper.createCellBindingFromStringAddress( sBoundCellAddress, bUseIndexBinding ) );
589                 }
590             }
591             catch( const Exception& )
592             {
593                 OSL_ENSURE( sal_False, "OFormLayerXMLImport_Impl::documentDone: caught an exception while binding to a cell!" );
594             }
595         }
596         m_aCellValueBindings.clear();
597     }
598 
599     // the same for the spreadsheet cell range list sources
600     if  (   !m_aCellRangeListSources.empty()
601         &&  FormCellBindingHelper::isListCellRangeAllowed( rImport.GetModel() )
602         )
603     {
604         for (   ::std::vector< ModelStringPair >::const_iterator aRangeBindings = m_aCellRangeListSources.begin();
605                 aRangeBindings != m_aCellRangeListSources.end();
606                 ++aRangeBindings
607             )
608         {
609             try
610             {
611                 FormCellBindingHelper aHelper( aRangeBindings->first, rImport.GetModel() );
612                 OSL_ENSURE( aHelper.isListCellRangeAllowed(), "OFormLayerXMLImport_Impl::documentDone: can't bind this control model!" );
613                 if ( aHelper.isListCellRangeAllowed() )
614                 {
615                     aHelper.setListSource( aHelper.createCellListSourceFromStringAddress( aRangeBindings->second ) );
616                 }
617             }
618             catch( const Exception& )
619             {
620                 OSL_ENSURE( sal_False, "OFormLayerXMLImport_Impl::documentDone: caught an exception while binding to a cell range!" );
621             }
622         }
623         m_aCellRangeListSources.clear();
624     }
625 
626     // process XForms-bindings; call registerXFormsValueBinding for each
627     std::for_each( m_aXFormsValueBindings.begin(),
628                    m_aXFormsValueBindings.end(),
629                    bind1st( ptr_fun( bindXFormsValueBinding ),
630                             rImport.GetModel() ) );
631     // same for list bindings
632     std::for_each( m_aXFormsListBindings.begin(),
633                    m_aXFormsListBindings.end(),
634                    bind1st( ptr_fun( bindXFormsListBinding ),
635                             rImport.GetModel() ) );
636     // same for submissions
637     std::for_each( m_aXFormsSubmissions.begin(),
638                    m_aXFormsSubmissions.end(),
639                    bind1st( ptr_fun( bindXFormsSubmission ),
640                             rImport.GetModel() ) );
641 }
642 
643 //.........................................................................
644 }	// namespace xmloff
645 //.........................................................................
646 
647