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