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