1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_framework.hxx"
26 
27 #include <stdio.h>
28 
29 //_________________________________________________________________________________________________________________
30 //	my own includes
31 //_________________________________________________________________________________________________________________
32 
33 #include <threadhelp/resetableguard.hxx>
34 #include <xml/toolboxdocumenthandler.hxx>
35 #include <macros/debug.hxx>
36 #include <xml/toolboxconfigurationdefines.hxx>
37 
38 //_________________________________________________________________________________________________________________
39 //	interface includes
40 //_________________________________________________________________________________________________________________
41 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
42 #include <com/sun/star/ui/ItemType.hpp>
43 #include <com/sun/star/ui/ItemStyle.hpp>
44 #include <com/sun/star/beans/XPropertySet.hpp>
45 
46 //_________________________________________________________________________________________________________________
47 //	other includes
48 //_________________________________________________________________________________________________________________
49 
50 #include <sal/config.h>
51 #include <vcl/svapp.hxx>
52 #include <vcl/toolbox.hxx>
53 #include <rtl/ustrbuf.hxx>
54 
55 #include <comphelper/attributelist.hxx>
56 
57 //_________________________________________________________________________________________________________________
58 //	namespace
59 //_________________________________________________________________________________________________________________
60 
61 using namespace ::com::sun::star::uno;
62 using namespace ::com::sun::star::beans;
63 using namespace ::com::sun::star::container;
64 using namespace ::com::sun::star::xml::sax;
65 
66 
67 #define TOOLBAR_DOCTYPE				"<!DOCTYPE toolbar:toolbar PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\" \"toolbar.dtd\">"
68 
69 namespace framework
70 {
71 
72 // Property names of a menu/menu item ItemDescriptor
73 static const char ITEM_DESCRIPTOR_COMMANDURL[]	= "CommandURL";
74 static const char ITEM_DESCRIPTOR_HELPURL[]		= "HelpURL";
75 static const char ITEM_DESCRIPTOR_TOOLTIP[]		= "Tooltip";
76 static const char ITEM_DESCRIPTOR_LABEL[]		= "Label";
77 static const char ITEM_DESCRIPTOR_TYPE[]		= "Type";
78 static const char ITEM_DESCRIPTOR_STYLE[]		= "Style";
79 static const char ITEM_DESCRIPTOR_VISIBLE[]		= "IsVisible";
80 static const char ITEM_DESCRIPTOR_WIDTH[]		= "Width";
81 
ExtractToolbarParameters(const Sequence<PropertyValue> rProp,::rtl::OUString & rCommandURL,::rtl::OUString & rLabel,::rtl::OUString & rHelpURL,::rtl::OUString & rTooltip,sal_Int16 & rStyle,sal_Int16 & rWidth,sal_Bool & rVisible,sal_Int16 & rType)82 static void ExtractToolbarParameters( const Sequence< PropertyValue >	rProp,
83 									  ::rtl::OUString&					rCommandURL,
84 									  ::rtl::OUString&					rLabel,
85 									  ::rtl::OUString&					rHelpURL,
86 									  ::rtl::OUString&					rTooltip,
87 									  sal_Int16&						rStyle,
88 									  sal_Int16&						rWidth,
89 									  sal_Bool&							rVisible,
90 									  sal_Int16&						rType )
91 {
92 	for ( sal_Int32 i = 0; i < rProp.getLength(); i++ )
93 	{
94 		if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_COMMANDURL ))
95 		{
96 			rProp[i].Value >>= rCommandURL;
97 			rCommandURL = rCommandURL.intern();
98 		}
99 		else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_HELPURL ))
100 			rProp[i].Value >>= rHelpURL;
101 		else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_TOOLTIP ))
102 			rProp[i].Value >>= rTooltip;
103 		else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_LABEL ))
104 			rProp[i].Value >>= rLabel;
105 		else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_TYPE ))
106 			rProp[i].Value >>= rType;
107 		else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_VISIBLE ))
108 			rProp[i].Value >>= rVisible;
109 		else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_WIDTH ))
110 			rProp[i].Value >>= rWidth;
111 		else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_STYLE ))
112 			rProp[i].Value >>= rStyle;
113 	}
114 }
115 
116 struct ToolboxStyleItem
117 {
118 	sal_Int16 nBit;
119 	const char* attrName;
120 };
121 
122 ToolboxStyleItem Styles[ ] = {
123 	{ ::com::sun::star::ui::ItemStyle::RADIO_CHECK, ATTRIBUTE_ITEMSTYLE_RADIO },
124 	{ ::com::sun::star::ui::ItemStyle::ALIGN_LEFT, ATTRIBUTE_ITEMSTYLE_LEFT },
125 	{ ::com::sun::star::ui::ItemStyle::AUTO_SIZE, ATTRIBUTE_ITEMSTYLE_AUTO },
126 	{ ::com::sun::star::ui::ItemStyle::REPEAT, ATTRIBUTE_ITEMSTYLE_REPEAT },
127 	{ ::com::sun::star::ui::ItemStyle::DROPDOWN_ONLY, ATTRIBUTE_ITEMSTYLE_DROPDOWNONLY },
128 	{ ::com::sun::star::ui::ItemStyle::DROP_DOWN, ATTRIBUTE_ITEMSTYLE_DROPDOWN },
129 	{ ::com::sun::star::ui::ItemStyle::ICON, ATTRIBUTE_ITEMSTYLE_IMAGE },
130 	{ ::com::sun::star::ui::ItemStyle::TEXT, ATTRIBUTE_ITEMSTYLE_TEXT },
131 };
132 
133 sal_Int32 nStyleItemEntries = sizeof( Styles ) / sizeof( Styles[ 0 ] );
134 
135 struct ToolBarEntryProperty
136 {
137 	OReadToolBoxDocumentHandler::ToolBox_XML_Namespace	nNamespace;
138 	char												aEntryName[20];
139 };
140 
141 ToolBarEntryProperty ToolBoxEntries[OReadToolBoxDocumentHandler::TB_XML_ENTRY_COUNT] =
142 {
143 	{ OReadToolBoxDocumentHandler::TB_NS_TOOLBAR,	ELEMENT_TOOLBAR				},
144 	{ OReadToolBoxDocumentHandler::TB_NS_TOOLBAR,	ELEMENT_TOOLBARITEM			},
145 	{ OReadToolBoxDocumentHandler::TB_NS_TOOLBAR,	ELEMENT_TOOLBARSPACE		},
146 	{ OReadToolBoxDocumentHandler::TB_NS_TOOLBAR,	ELEMENT_TOOLBARBREAK		},
147 	{ OReadToolBoxDocumentHandler::TB_NS_TOOLBAR,	ELEMENT_TOOLBARSEPARATOR	},
148 	{ OReadToolBoxDocumentHandler::TB_NS_TOOLBAR,	ATTRIBUTE_TEXT				},
149 	{ OReadToolBoxDocumentHandler::TB_NS_TOOLBAR,	ATTRIBUTE_BITMAP			},
150 	{ OReadToolBoxDocumentHandler::TB_NS_XLINK,		ATTRIBUTE_URL				},
151 	{ OReadToolBoxDocumentHandler::TB_NS_TOOLBAR,	ATTRIBUTE_ITEMBITS			},
152 	{ OReadToolBoxDocumentHandler::TB_NS_TOOLBAR,	ATTRIBUTE_VISIBLE			},
153 	{ OReadToolBoxDocumentHandler::TB_NS_TOOLBAR,	ATTRIBUTE_WIDTH				},
154 	{ OReadToolBoxDocumentHandler::TB_NS_TOOLBAR,	ATTRIBUTE_USER				},
155 	{ OReadToolBoxDocumentHandler::TB_NS_TOOLBAR,	ATTRIBUTE_HELPID			},
156 	{ OReadToolBoxDocumentHandler::TB_NS_TOOLBAR,	ATTRIBUTE_ITEMSTYLE			},
157 	{ OReadToolBoxDocumentHandler::TB_NS_TOOLBAR,	ATTRIBUTE_UINAME			},
158 	{ OReadToolBoxDocumentHandler::TB_NS_TOOLBAR,	ATTRIBUTE_TOOLTIP			},
159 };
160 
OReadToolBoxDocumentHandler(const Reference<XIndexContainer> & rItemContainer)161 OReadToolBoxDocumentHandler::OReadToolBoxDocumentHandler( const Reference< XIndexContainer >& rItemContainer ) :
162 	ThreadHelpBase( &Application::GetSolarMutex() ),
163 	m_rItemContainer( rItemContainer ),
164 	m_aType( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_TYPE )),
165 	m_aLabel( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_LABEL )),
166 	m_aStyle( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_STYLE )),
167 	m_aHelpURL( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_HELPURL )),
168 	m_aTooltip( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_TOOLTIP )),
169 	m_aIsVisible( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_VISIBLE )),
170 	m_aCommandURL( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_COMMANDURL ))
171  {
172 	::rtl::OUString aNamespaceToolBar( RTL_CONSTASCII_USTRINGPARAM( XMLNS_TOOLBAR ));
173 	::rtl::OUString aNamespaceXLink( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK ));
174 	::rtl::OUString aSeparator( RTL_CONSTASCII_USTRINGPARAM( XMLNS_FILTER_SEPARATOR ));
175 
176 	// create hash map
177 	for ( int i = 0; i < (int)TB_XML_ENTRY_COUNT; i++ )
178 	{
179 		if ( ToolBoxEntries[i].nNamespace == TB_NS_TOOLBAR )
180 		{
181 			::rtl::OUString temp( aNamespaceToolBar );
182 			temp += aSeparator;
183 			temp += ::rtl::OUString::createFromAscii( ToolBoxEntries[i].aEntryName );
184 			m_aToolBoxMap.insert( ToolBoxHashMap::value_type( temp, (ToolBox_XML_Entry)i ) );
185 		}
186 		else
187 		{
188 			::rtl::OUString temp( aNamespaceXLink );
189 			temp += aSeparator;
190 			temp += ::rtl::OUString::createFromAscii( ToolBoxEntries[i].aEntryName );
191 			m_aToolBoxMap.insert( ToolBoxHashMap::value_type( temp, (ToolBox_XML_Entry)i ) );
192 		}
193 	}
194 
195 	// pre-calculate a hash code for all style strings to speed up xml read process
196 	m_nHashCode_Style_Radio			= ::rtl::OUString::createFromAscii( ATTRIBUTE_ITEMSTYLE_RADIO ).hashCode();
197 	m_nHashCode_Style_Auto			= ::rtl::OUString::createFromAscii( ATTRIBUTE_ITEMSTYLE_AUTO ).hashCode();
198 	m_nHashCode_Style_Left			= ::rtl::OUString::createFromAscii( ATTRIBUTE_ITEMSTYLE_LEFT ).hashCode();
199 	m_nHashCode_Style_AutoSize		= ::rtl::OUString::createFromAscii( ATTRIBUTE_ITEMSTYLE_AUTOSIZE ).hashCode();
200 	m_nHashCode_Style_DropDown		= ::rtl::OUString::createFromAscii( ATTRIBUTE_ITEMSTYLE_DROPDOWN ).hashCode();
201 	m_nHashCode_Style_Repeat		= ::rtl::OUString::createFromAscii( ATTRIBUTE_ITEMSTYLE_REPEAT ).hashCode();
202 	m_nHashCode_Style_DropDownOnly	= ::rtl::OUString::createFromAscii( ATTRIBUTE_ITEMSTYLE_DROPDOWNONLY ).hashCode();
203 	m_nHashCode_Style_Text			= ::rtl::OUString::createFromAscii( ATTRIBUTE_ITEMSTYLE_TEXT ).hashCode();
204 	m_nHashCode_Style_Image			= ::rtl::OUString::createFromAscii( ATTRIBUTE_ITEMSTYLE_IMAGE ).hashCode();
205 
206 	m_bToolBarStartFound			= sal_False;
207 	m_bToolBarEndFound				= sal_False;
208 	m_bToolBarItemStartFound		= sal_False;
209 	m_bToolBarSpaceStartFound		= sal_False;
210 	m_bToolBarBreakStartFound		= sal_False;
211 	m_bToolBarSeparatorStartFound	= sal_False;
212 }
213 
~OReadToolBoxDocumentHandler()214 OReadToolBoxDocumentHandler::~OReadToolBoxDocumentHandler()
215 {
216 }
217 
218 // XDocumentHandler
startDocument(void)219 void SAL_CALL OReadToolBoxDocumentHandler::startDocument(void)
220 throw (	SAXException, RuntimeException )
221 {
222 }
223 
endDocument(void)224 void SAL_CALL OReadToolBoxDocumentHandler::endDocument(void)
225 throw(	SAXException, RuntimeException )
226 {
227 	ResetableGuard aGuard( m_aLock );
228 
229 	if (( m_bToolBarStartFound && !m_bToolBarEndFound ) ||
230 		( !m_bToolBarStartFound && m_bToolBarEndFound )		)
231 	{
232 		::rtl::OUString aErrorMessage = getErrorLineString();
233 		aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "No matching start or end element 'toolbar' found!" ));
234 		throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
235 	}
236 }
237 
startElement(const::rtl::OUString & aName,const Reference<XAttributeList> & xAttribs)238 void SAL_CALL OReadToolBoxDocumentHandler::startElement(
239 	const ::rtl::OUString& aName, const Reference< XAttributeList > &xAttribs )
240 throw(	SAXException, RuntimeException )
241 {
242 	ResetableGuard aGuard( m_aLock );
243 
244 	ToolBoxHashMap::const_iterator pToolBoxEntry = m_aToolBoxMap.find( aName ) ;
245 	if ( pToolBoxEntry != m_aToolBoxMap.end() )
246 	{
247 		switch ( pToolBoxEntry->second )
248 		{
249 			case TB_ELEMENT_TOOLBAR:
250 			{
251 				if ( m_bToolBarStartFound )
252 				{
253 					::rtl::OUString aErrorMessage = getErrorLineString();
254 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'toolbar:toolbar' cannot be embedded into 'toolbar:toolbar'!" ));
255 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
256 				}
257 					else
258 					{
259 						// Check if we have a UI name set in our XML file
260 						::rtl::OUString aUIName;
261 						for ( sal_Int16 n = 0; n < xAttribs->getLength(); n++ )
262 					{
263 						pToolBoxEntry = m_aToolBoxMap.find( xAttribs->getNameByIndex( n ) );
264 						if ( pToolBoxEntry != m_aToolBoxMap.end() )
265 						{
266 								switch ( pToolBoxEntry->second )
267 								{
268 									case TB_ATTRIBUTE_UINAME:
269 								aUIName = xAttribs->getValueByIndex( n );
270 									break;
271 										default:
272 											break;
273 								}
274 							}
275 						}
276 
277 							if ( aUIName.getLength() > 0 )
278 							{
279 								// Try to set UI name as a container property
280 								Reference< XPropertySet > xPropSet( m_rItemContainer, UNO_QUERY );
281 								if ( xPropSet.is() )
282 								{
283 									try
284 									{
285 										xPropSet->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UIName" )), makeAny( aUIName ) );
286 									}
287 									catch ( UnknownPropertyException& )
288 									{
289 									}
290 								}
291 							}
292 						}
293 
294 				m_bToolBarStartFound = sal_True;
295 			}
296 			break;
297 
298 			case TB_ELEMENT_TOOLBARITEM:
299 			{
300 				if ( !m_bToolBarStartFound )
301 				{
302 					::rtl::OUString aErrorMessage = getErrorLineString();
303 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'toolbar:toolbaritem' must be embedded into element 'toolbar:toolbar'!" ));
304 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
305 				}
306 
307 				if ( m_bToolBarSeparatorStartFound ||
308 					 m_bToolBarBreakStartFound ||
309 					 m_bToolBarSpaceStartFound ||
310 					 m_bToolBarItemStartFound )
311 				{
312 					::rtl::OUString aErrorMessage = getErrorLineString();
313 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element toolbar:toolbaritem is not a container!" ));
314 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
315 				}
316 
317 				::rtl::OUString aAttribute;
318 				sal_Bool bAttributeURL	= sal_False;
319 
320 				m_bToolBarItemStartFound = sal_True;
321 				::rtl::OUString		aLabel;
322 				::rtl::OUString		aCommandURL;
323 				::rtl::OUString		aHelpURL;
324 				::rtl::OUString		aTooltip;
325 				::rtl::OUString		aBitmapName;
326 				sal_uInt16			nItemBits( 0 );
327 				sal_uInt16			nWidth( 0 );
328 				sal_uInt16			nUserDef( 0 );
329 				sal_Bool			bVisible( sal_True );
330 
331 				for ( sal_Int16 n = 0; n < xAttribs->getLength(); n++ )
332 				{
333 					pToolBoxEntry = m_aToolBoxMap.find( xAttribs->getNameByIndex( n ) );
334 					if ( pToolBoxEntry != m_aToolBoxMap.end() )
335 					{
336 						switch ( pToolBoxEntry->second )
337 						{
338 							case TB_ATTRIBUTE_TEXT:
339 							{
340 								aLabel = xAttribs->getValueByIndex( n );
341 							}
342 							break;
343 
344 							case TB_ATTRIBUTE_BITMAP:
345 							{
346 								aBitmapName = xAttribs->getValueByIndex( n );
347 							}
348 							break;
349 
350 							case TB_ATTRIBUTE_URL:
351 							{
352 								bAttributeURL	= sal_True;
353 								aCommandURL		= xAttribs->getValueByIndex( n ).intern();
354 							}
355 							break;
356 
357 							case TB_ATTRIBUTE_ITEMBITS:
358 							{
359 								nItemBits = (sal_uInt16)(xAttribs->getValueByIndex( n ).toInt32());
360 							}
361 							break;
362 
363 							case TB_ATTRIBUTE_VISIBLE:
364 							{
365 								if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_BOOLEAN_TRUE )) )
366 									bVisible = sal_True;
367 								else if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_BOOLEAN_FALSE )) )
368 									bVisible = sal_False;
369 								else
370 								{
371 									::rtl::OUString aErrorMessage = getErrorLineString();
372 									aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Attribute toolbar:visible must have value 'true' or 'false'!" ));
373 									throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
374 								}
375 							}
376 							break;
377 
378 							case TB_ATTRIBUTE_WIDTH:
379 							{
380 								nWidth = (sal_uInt16)(xAttribs->getValueByIndex( n ).toInt32());
381 							}
382 							break;
383 
384 							case TB_ATTRIBUTE_USER:
385 							{
386 								nUserDef = (sal_uInt16)(xAttribs->getValueByIndex( n ).toInt32());
387 							}
388 							break;
389 
390 							case TB_ATTRIBUTE_HELPID:
391 							{
392 								aHelpURL = xAttribs->getValueByIndex( n );
393 							}
394 							break;
395 
396 							case TB_ATTRIBUTE_TOOLTIP:
397 							{
398 								aTooltip = xAttribs->getValueByIndex( n );
399 							}
400 							break;
401 
402 							case TB_ATTRIBUTE_STYLE:
403 							{
404 								// read space separated item style list
405 								::rtl::OUString aTemp = xAttribs->getValueByIndex( n );
406 								sal_Int32 nIndex = 0;
407 
408 								do
409 								{
410 									::rtl::OUString aToken	= aTemp.getToken( 0, ' ', nIndex );
411 									if ( aToken.getLength() > 0 )
412 									{
413 										sal_Int32 nHashCode = aToken.hashCode();
414 										if ( nHashCode == m_nHashCode_Style_Radio )
415 											nItemBits |= ::com::sun::star::ui::ItemStyle::RADIO_CHECK;
416 										else if ( nHashCode == m_nHashCode_Style_Left )
417 											nItemBits |= ::com::sun::star::ui::ItemStyle::ALIGN_LEFT;
418 										else if ( nHashCode == m_nHashCode_Style_AutoSize )
419 											nItemBits |= ::com::sun::star::ui::ItemStyle::AUTO_SIZE;
420 										else if ( nHashCode == m_nHashCode_Style_DropDown )
421 											nItemBits |= ::com::sun::star::ui::ItemStyle::DROP_DOWN;
422 										else if ( nHashCode == m_nHashCode_Style_Repeat )
423 											nItemBits |= ::com::sun::star::ui::ItemStyle::REPEAT;
424 										else if ( nHashCode == m_nHashCode_Style_DropDownOnly )
425 											nItemBits |= ::com::sun::star::ui::ItemStyle::DROPDOWN_ONLY;
426 										else if ( nHashCode == m_nHashCode_Style_DropDown )
427 											nItemBits |= ::com::sun::star::ui::ItemStyle::DROP_DOWN;
428 										else if ( nHashCode == m_nHashCode_Style_Text )
429 											nItemBits |= ::com::sun::star::ui::ItemStyle::TEXT;
430 										else if ( nHashCode == m_nHashCode_Style_Image )
431 											nItemBits |= ::com::sun::star::ui::ItemStyle::ICON;
432 									}
433 								}
434 								while ( nIndex >= 0 );
435 							}
436 							break;
437 
438 								default:
439 									break;
440 						}
441 					}
442 				} // for
443 
444 				if ( !bAttributeURL )
445 				{
446 					::rtl::OUString aErrorMessage = getErrorLineString();
447 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Required attribute toolbar:url must have a value!" ));
448 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
449 				}
450 
451 				if ( aCommandURL.getLength() > 0 )
452 				{
453 					Sequence< PropertyValue > aToolbarItemProp( 7 );
454 					aToolbarItemProp[0].Name = m_aCommandURL;
455 					aToolbarItemProp[1].Name = m_aHelpURL;
456 					aToolbarItemProp[2].Name = m_aLabel;
457 					aToolbarItemProp[3].Name = m_aType;
458 					aToolbarItemProp[4].Name = m_aStyle;
459 					aToolbarItemProp[5].Name = m_aIsVisible;
460 					aToolbarItemProp[6].Name = m_aTooltip;
461 
462 					aToolbarItemProp[0].Value <<= aCommandURL;
463 					aToolbarItemProp[1].Value <<= aHelpURL;
464 					aToolbarItemProp[2].Value <<= aLabel;
465 					aToolbarItemProp[3].Value = makeAny( ::com::sun::star::ui::ItemType::DEFAULT );
466 					aToolbarItemProp[4].Value <<= nItemBits;
467 					aToolbarItemProp[5].Value <<= bVisible;
468 					aToolbarItemProp[6].Value <<= aTooltip;
469 
470 					m_rItemContainer->insertByIndex( m_rItemContainer->getCount(), makeAny( aToolbarItemProp ) );
471 				}
472 			}
473 			break;
474 
475 			case TB_ELEMENT_TOOLBARSPACE:
476 			{
477 				if ( m_bToolBarSeparatorStartFound ||
478 					 m_bToolBarBreakStartFound ||
479 					 m_bToolBarSpaceStartFound ||
480 					 m_bToolBarItemStartFound )
481 				{
482 					::rtl::OUString aErrorMessage = getErrorLineString();
483 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element toolbar:toolbarspace is not a container!" ));
484 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
485 				}
486 
487 				m_bToolBarSpaceStartFound = sal_True;
488 
489 				Sequence< PropertyValue > aToolbarItemProp( 2 );
490 				aToolbarItemProp[0].Name = m_aCommandURL;
491 				aToolbarItemProp[1].Name = m_aType;
492 
493 				aToolbarItemProp[0].Value <<= rtl::OUString();
494 				aToolbarItemProp[1].Value <<= ::com::sun::star::ui::ItemType::SEPARATOR_SPACE;
495 
496 				m_rItemContainer->insertByIndex( m_rItemContainer->getCount(), makeAny( aToolbarItemProp ) );
497 			}
498 			break;
499 
500 			case TB_ELEMENT_TOOLBARBREAK:
501 			{
502 				if ( m_bToolBarSeparatorStartFound ||
503 					 m_bToolBarBreakStartFound ||
504 					 m_bToolBarSpaceStartFound ||
505 					 m_bToolBarItemStartFound )
506 				{
507 					::rtl::OUString aErrorMessage = getErrorLineString();
508 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element toolbar:toolbarbreak is not a container!" ));
509 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
510 				}
511 
512 				m_bToolBarBreakStartFound = sal_True;
513 
514 				Sequence< PropertyValue > aToolbarItemProp( 2 );
515 				aToolbarItemProp[0].Name = m_aCommandURL;
516 				aToolbarItemProp[1].Name = m_aType;
517 
518 				aToolbarItemProp[0].Value <<= rtl::OUString();
519 				aToolbarItemProp[1].Value <<= ::com::sun::star::ui::ItemType::SEPARATOR_LINEBREAK;
520 
521 				m_rItemContainer->insertByIndex( m_rItemContainer->getCount(), makeAny( aToolbarItemProp ) );
522 			}
523 			break;
524 
525 			case TB_ELEMENT_TOOLBARSEPARATOR:
526 			{
527 				if ( m_bToolBarSeparatorStartFound ||
528 					 m_bToolBarBreakStartFound ||
529 					 m_bToolBarSpaceStartFound ||
530 					 m_bToolBarItemStartFound )
531 				{
532 					::rtl::OUString aErrorMessage = getErrorLineString();
533 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element toolbar:toolbarseparator is not a container!" ));
534 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
535 				}
536 
537 				m_bToolBarSeparatorStartFound = sal_True;
538 
539 				Sequence< PropertyValue > aToolbarItemProp( 2 );
540 				aToolbarItemProp[0].Name = m_aCommandURL;
541 				aToolbarItemProp[1].Name = m_aType;
542 
543 				aToolbarItemProp[0].Value <<= rtl::OUString();
544 				aToolbarItemProp[1].Value <<= ::com::sun::star::ui::ItemType::SEPARATOR_LINE;
545 
546 				m_rItemContainer->insertByIndex( m_rItemContainer->getCount(), makeAny( aToolbarItemProp ) );
547 			}
548 			break;
549 
550 				default:
551 					break;
552 		}
553 	}
554 }
555 
endElement(const::rtl::OUString & aName)556 void SAL_CALL OReadToolBoxDocumentHandler::endElement(const ::rtl::OUString& aName)
557 throw(	SAXException, RuntimeException )
558 {
559 	ResetableGuard aGuard( m_aLock );
560 
561 	ToolBoxHashMap::const_iterator pToolBoxEntry = m_aToolBoxMap.find( aName ) ;
562 	if ( pToolBoxEntry != m_aToolBoxMap.end() )
563 	{
564 		switch ( pToolBoxEntry->second )
565 		{
566 			case TB_ELEMENT_TOOLBAR:
567 			{
568 				if ( !m_bToolBarStartFound )
569 				{
570 					::rtl::OUString aErrorMessage = getErrorLineString();
571 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'toolbar' found, but no start element 'toolbar'" ));
572 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
573 				}
574 
575 				m_bToolBarStartFound = sal_False;
576 			}
577 			break;
578 
579 			case TB_ELEMENT_TOOLBARITEM:
580 			{
581 				if ( !m_bToolBarItemStartFound )
582 				{
583 					::rtl::OUString aErrorMessage = getErrorLineString();
584 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'toolbar:toolbaritem' found, but no start element 'toolbar:toolbaritem'" ));
585 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
586 				}
587 
588 				m_bToolBarItemStartFound = sal_False;
589 			}
590 			break;
591 
592 			case TB_ELEMENT_TOOLBARBREAK:
593 			{
594 				if ( !m_bToolBarBreakStartFound )
595 				{
596 					::rtl::OUString aErrorMessage = getErrorLineString();
597 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'toolbar:toolbarbreak' found, but no start element 'toolbar:toolbarbreak'" ));
598 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
599 				}
600 
601 				m_bToolBarBreakStartFound = sal_False;
602 			}
603 			break;
604 
605 			case TB_ELEMENT_TOOLBARSPACE:
606 			{
607 				if ( !m_bToolBarSpaceStartFound )
608 				{
609 					::rtl::OUString aErrorMessage = getErrorLineString();
610 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'toolbar:toolbarspace' found, but no start element 'toolbar:toolbarspace'" ));
611 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
612 				}
613 
614 				m_bToolBarSpaceStartFound = sal_False;
615 			}
616 			break;
617 
618 			case TB_ELEMENT_TOOLBARSEPARATOR:
619 			{
620 				if ( !m_bToolBarSeparatorStartFound )
621 				{
622 					::rtl::OUString aErrorMessage = getErrorLineString();
623 					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'toolbar:toolbarseparator' found, but no start element 'toolbar:toolbarseparator'" ));
624 					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
625 				}
626 
627 				m_bToolBarSeparatorStartFound = sal_False;
628 			}
629 			break;
630 
631 				default:
632 					break;
633 		}
634 	}
635 }
636 
characters(const::rtl::OUString &)637 void SAL_CALL OReadToolBoxDocumentHandler::characters(const ::rtl::OUString&)
638 throw(	SAXException, RuntimeException )
639 {
640 }
641 
ignorableWhitespace(const::rtl::OUString &)642 void SAL_CALL OReadToolBoxDocumentHandler::ignorableWhitespace(const ::rtl::OUString&)
643 throw(	SAXException, RuntimeException )
644 {
645 }
646 
processingInstruction(const::rtl::OUString &,const::rtl::OUString &)647 void SAL_CALL OReadToolBoxDocumentHandler::processingInstruction(
648 	const ::rtl::OUString& /*aTarget*/, const ::rtl::OUString& /*aData*/ )
649 throw(	SAXException, RuntimeException )
650 {
651 }
652 
setDocumentLocator(const Reference<XLocator> & xLocator)653 void SAL_CALL OReadToolBoxDocumentHandler::setDocumentLocator(
654 	const Reference< XLocator > &xLocator)
655 throw(	SAXException, RuntimeException )
656 {
657 	ResetableGuard aGuard( m_aLock );
658 
659 	m_xLocator = xLocator;
660 }
661 
getErrorLineString()662 ::rtl::OUString OReadToolBoxDocumentHandler::getErrorLineString()
663 {
664 	ResetableGuard aGuard( m_aLock );
665 
666 	char buffer[32];
667 
668 	if ( m_xLocator.is() )
669 	{
670 		snprintf( buffer, sizeof(buffer), "Line: %ld - ", static_cast<long>( m_xLocator->getLineNumber() ));
671 		return ::rtl::OUString::createFromAscii( buffer );
672 	}
673 	else
674 		return ::rtl::OUString();
675 }
676 
677 
678 //_________________________________________________________________________________________________________________
679 //	OWriteToolBoxDocumentHandler
680 //_________________________________________________________________________________________________________________
681 
OWriteToolBoxDocumentHandler(const Reference<XIndexAccess> & rItemAccess,Reference<XDocumentHandler> & rWriteDocumentHandler)682 OWriteToolBoxDocumentHandler::OWriteToolBoxDocumentHandler(
683 	const Reference< XIndexAccess >& rItemAccess,
684 	Reference< XDocumentHandler >& rWriteDocumentHandler ) :
685 	ThreadHelpBase( &Application::GetSolarMutex() ),
686 	m_xWriteDocumentHandler( rWriteDocumentHandler ),
687 	m_rItemAccess( rItemAccess )
688 {
689 	::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
690 	m_xEmptyList		= Reference< XAttributeList >( (XAttributeList *) pList, UNO_QUERY );
691 	m_aAttributeType	= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TYPE_CDATA ));
692 	m_aXMLXlinkNS		= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK_PREFIX ));
693 	m_aXMLToolbarNS		= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_TOOLBAR_PREFIX ));
694 }
695 
~OWriteToolBoxDocumentHandler()696 OWriteToolBoxDocumentHandler::~OWriteToolBoxDocumentHandler()
697 {
698 }
699 
WriteToolBoxDocument()700 void OWriteToolBoxDocumentHandler::WriteToolBoxDocument() throw
701 ( SAXException, RuntimeException )
702 {
703 	ResetableGuard aGuard( m_aLock );
704 
705 	m_xWriteDocumentHandler->startDocument();
706 
707 	// write DOCTYPE line!
708 	Reference< XExtendedDocumentHandler > xExtendedDocHandler( m_xWriteDocumentHandler, UNO_QUERY );
709 	if ( xExtendedDocHandler.is() )
710 	{
711 		xExtendedDocHandler->unknown( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( TOOLBAR_DOCTYPE )) );
712 		m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
713 	}
714 
715 	::rtl::OUString aUIName;
716 	Reference< XPropertySet > xPropSet( m_rItemAccess, UNO_QUERY );
717 	if ( xPropSet.is() )
718 	{
719 		try
720 		{
721 			xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UIName" ))) >>= aUIName;
722 		}
723 		catch ( UnknownPropertyException& )
724 		{
725 		}
726 	}
727 
728 	::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
729 	Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );
730 
731 	pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_TOOLBAR )),
732 						 m_aAttributeType,
733 						 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_TOOLBAR )) );
734 
735 	pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_XLINK )),
736 						 m_aAttributeType,
737 						 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK )) );
738 
739 	if ( aUIName.getLength() > 0 )
740 		pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_UINAME )),
741 							 m_aAttributeType,
742 							 aUIName );
743 
744 	m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBAR )), pList );
745 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
746 
747 	sal_Int32	nItemCount = m_rItemAccess->getCount();
748 	Any			aAny;
749 
750 	for ( sal_Int32 nItemPos = 0; nItemPos < nItemCount; nItemPos++ )
751 	{
752 		Sequence< PropertyValue > aProps;
753 		aAny = m_rItemAccess->getByIndex( nItemPos );
754 		if ( aAny >>= aProps )
755 		{
756 			::rtl::OUString		aCommandURL;
757 			::rtl::OUString		aLabel;
758 			::rtl::OUString		aHelpURL;
759 			::rtl::OUString		aTooltip;
760 			sal_Bool	bVisible( sal_True );
761 			sal_Int16	nType( ::com::sun::star::ui::ItemType::DEFAULT );
762 			sal_Int16	nWidth( 0 );
763 			sal_Int16	nStyle( 0 );
764 
765 			ExtractToolbarParameters( aProps, aCommandURL, aLabel, aHelpURL, aTooltip, nStyle, nWidth, bVisible, nType );
766 			if ( nType == ::com::sun::star::ui::ItemType::DEFAULT )
767 				WriteToolBoxItem( aCommandURL, aLabel, aHelpURL, aTooltip, nStyle, nWidth, bVisible );
768 			else if ( nType == ::com::sun::star::ui::ItemType::SEPARATOR_SPACE )
769 				WriteToolBoxSpace();
770 			else if ( nType == ::com::sun::star::ui::ItemType::SEPARATOR_LINE )
771 				WriteToolBoxSeparator();
772 			else if ( nType == ::com::sun::star::ui::ItemType::SEPARATOR_LINEBREAK )
773 				WriteToolBoxBreak();
774 		}
775 	}
776 
777 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
778 	m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBAR )) );
779 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
780 	m_xWriteDocumentHandler->endDocument();
781 }
782 
783 //_________________________________________________________________________________________________________________
784 //	protected member functions
785 //_________________________________________________________________________________________________________________
786 
WriteToolBoxItem(const::rtl::OUString & rCommandURL,const::rtl::OUString & rLabel,const::rtl::OUString & rHelpURL,const::rtl::OUString & rTooltip,sal_Int16 nStyle,sal_Int16 nWidth,sal_Bool bVisible)787 void OWriteToolBoxDocumentHandler::WriteToolBoxItem(
788 	const ::rtl::OUString& rCommandURL,
789 	const ::rtl::OUString& rLabel,
790 	const ::rtl::OUString& rHelpURL,
791 	const ::rtl::OUString& rTooltip,
792 	sal_Int16	nStyle,
793 	sal_Int16	nWidth,
794 	sal_Bool	bVisible )
795 throw ( SAXException, RuntimeException )
796 {
797 	::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
798 	Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );
799 
800 	if ( m_aAttributeURL.getLength() == 0 )
801 	{
802 		m_aAttributeURL = m_aXMLXlinkNS;
803 		m_aAttributeURL += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_URL ));
804 	}
805 
806 	// save required attribute (URL)
807 	pList->AddAttribute( m_aAttributeURL, m_aAttributeType, rCommandURL );
808 
809 	if ( rLabel.getLength() > 0 )
810 	{
811 		pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TEXT )),
812 							 m_aAttributeType,
813 							 rLabel );
814 	}
815 
816 	if ( bVisible == sal_False )
817 	{
818 		pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_VISIBLE )),
819 							 m_aAttributeType,
820 							 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_BOOLEAN_FALSE )) );
821 	}
822 
823 	if ( rHelpURL.getLength() > 0 )
824 	{
825 		pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_HELPID )),
826 							 m_aAttributeType,
827 							 rHelpURL );
828 	}
829 
830 	if ( rTooltip.getLength() > 0 )
831 	{
832 		pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TOOLTIP )),
833 							 m_aAttributeType,
834 							 rTooltip );
835 	}
836 
837 	if ( nStyle > 0 )
838 	{
839 		rtl::OUString aValue;
840 		ToolboxStyleItem* pStyle = Styles;
841 
842 		for ( sal_Int32 nIndex = 0; nIndex < nStyleItemEntries; ++nIndex, ++pStyle )
843 		{
844 			if ( nStyle & pStyle->nBit )
845 			{
846 				if ( aValue.getLength() )
847 					aValue = aValue.concat( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(" ") ) );
848 				aValue += rtl::OUString::createFromAscii( pStyle->attrName );
849 			}
850 		}
851 		pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_ITEMSTYLE )),
852 							 m_aAttributeType,
853 							 aValue );
854 	}
855 
856 	if ( nWidth > 0 )
857 	{
858 		pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_WIDTH )),
859 							 m_aAttributeType,
860 							 ::rtl::OUString::valueOf( sal_Int32( nWidth )) );
861 	}
862 
863 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
864 	m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARITEM )), xList );
865 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
866 	m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARITEM )) );
867 }
868 
WriteToolBoxSpace()869 void OWriteToolBoxDocumentHandler::WriteToolBoxSpace() throw
870 ( SAXException, RuntimeException )
871 {
872 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
873 	m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARSPACE )), m_xEmptyList );
874 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
875 	m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARSPACE )) );
876 }
877 
WriteToolBoxBreak()878 void OWriteToolBoxDocumentHandler::WriteToolBoxBreak() throw
879 ( SAXException, RuntimeException )
880 {
881 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
882 	m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARBREAK )), m_xEmptyList );
883 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
884 	m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARBREAK )) );
885 }
886 
WriteToolBoxSeparator()887 void OWriteToolBoxDocumentHandler::WriteToolBoxSeparator() throw
888 ( SAXException, RuntimeException )
889 {
890 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
891 	m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARSEPARATOR )), m_xEmptyList );
892 	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
893 	m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARSEPARATOR )) );
894 }
895 
896 } // namespace framework
897