LibreOffice Module framework (master) 1
menudocumenthandler.cxx
Go to the documentation of this file.
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 <sal/macros.h>
21#include <rtl/ref.hxx>
22#include <rtl/ustrbuf.hxx>
23
25
26#include <com/sun/star/xml/sax/SAXException.hpp>
27#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
28#include <com/sun/star/lang/XSingleComponentFactory.hpp>
29#include <com/sun/star/ui/ItemType.hpp>
30#include <com/sun/star/ui/ItemStyle.hpp>
31#include <com/sun/star/beans/PropertyValue.hpp>
32
36
37#ifdef ATTRIBUTE_HELPID
38#undef ATTRIBUTE_HELPID
39#endif
40
41constexpr OUStringLiteral XMLNS_MENU = u"http://openoffice.org/2001/menu";
42
43constexpr OUStringLiteral ELEMENT_MENUBAR = u"http://openoffice.org/2001/menu^menubar";
44constexpr OUStringLiteral ELEMENT_MENU = u"http://openoffice.org/2001/menu^menu";
45constexpr OUStringLiteral ELEMENT_MENUPOPUP = u"http://openoffice.org/2001/menu^menupopup";
46constexpr OUStringLiteral ELEMENT_MENUITEM = u"http://openoffice.org/2001/menu^menuitem";
47constexpr OUStringLiteral ELEMENT_MENUSEPARATOR = u"http://openoffice.org/2001/menu^menuseparator";
48
49constexpr OUStringLiteral ELEMENT_NS_MENUBAR = u"menu:menubar";
50constexpr OUStringLiteral ELEMENT_NS_MENU = u"menu:menu";
51constexpr OUStringLiteral ELEMENT_NS_MENUPOPUP = u"menu:menupopup";
52constexpr OUStringLiteral ELEMENT_NS_MENUITEM = u"menu:menuitem";
53constexpr OUStringLiteral ELEMENT_NS_MENUSEPARATOR = u"menu:menuseparator";
54
55constexpr OUStringLiteral ATTRIBUTE_ID = u"http://openoffice.org/2001/menu^id";
56constexpr OUStringLiteral ATTRIBUTE_LABEL = u"http://openoffice.org/2001/menu^label";
57constexpr OUStringLiteral ATTRIBUTE_HELPID = u"http://openoffice.org/2001/menu^helpid";
58constexpr OUStringLiteral ATTRIBUTE_STYLE = u"http://openoffice.org/2001/menu^style";
59
60constexpr OUStringLiteral ATTRIBUTE_NS_ID = u"menu:id";
61constexpr OUStringLiteral ATTRIBUTE_NS_LABEL = u"menu:label";
62constexpr OUStringLiteral ATTRIBUTE_NS_HELPID = u"menu:helpid";
63constexpr OUStringLiteral ATTRIBUTE_NS_STYLE = u"menu:style";
64
65constexpr OUStringLiteral ATTRIBUTE_XMLNS_MENU = u"xmlns:menu";
66
67constexpr OUStringLiteral MENUBAR_DOCTYPE = u"<!DOCTYPE menu:menubar PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\" \"menubar.dtd\">";
68
69#define ATTRIBUTE_ITEMSTYLE_TEXT "text"
70#define ATTRIBUTE_ITEMSTYLE_IMAGE "image"
71#define ATTRIBUTE_ITEMSTYLE_RADIO "radio"
72
73// Property names of a menu/menu item ItemDescriptor
74constexpr OUStringLiteral ITEM_DESCRIPTOR_COMMANDURL = u"CommandURL";
75constexpr OUStringLiteral ITEM_DESCRIPTOR_HELPURL = u"HelpURL";
76constexpr OUStringLiteral ITEM_DESCRIPTOR_CONTAINER = u"ItemDescriptorContainer";
77constexpr OUStringLiteral ITEM_DESCRIPTOR_LABEL = u"Label";
78constexpr OUStringLiteral ITEM_DESCRIPTOR_TYPE = u"Type";
79constexpr OUStringLiteral ITEM_DESCRIPTOR_STYLE = u"Style";
80
81// using namespaces
82
83using namespace ::com::sun::star::uno;
84using namespace ::com::sun::star::lang;
85using namespace ::com::sun::star::beans;
86using namespace ::com::sun::star::xml::sax;
87using namespace ::com::sun::star::container;
88using namespace ::com::sun::star::ui;
89
90namespace framework
91{
92
93namespace {
94
95struct MenuStyleItem
96{
97 sal_Int16 nBit;
98 const char* attrName;
99};
100
101}
102
103const MenuStyleItem MenuItemStyles[ ] = {
104 { css::ui::ItemStyle::ICON, ATTRIBUTE_ITEMSTYLE_IMAGE },
105 { css::ui::ItemStyle::TEXT, ATTRIBUTE_ITEMSTYLE_TEXT },
106 { css::ui::ItemStyle::RADIO_CHECK, ATTRIBUTE_ITEMSTYLE_RADIO }
107};
108
110
111static void ExtractMenuParameters( const Sequence< PropertyValue >& rProp,
112 OUString& rCommandURL,
113 OUString& rLabel,
114 OUString& rHelpURL,
115 Reference< XIndexAccess >& rSubMenu,
116 sal_Int16& rType,
117 sal_Int16& rStyle )
118{
119 for ( const PropertyValue& p : rProp )
120 {
121 if ( p.Name == ITEM_DESCRIPTOR_COMMANDURL )
122 {
123 p.Value >>= rCommandURL;
124 }
125 else if ( p.Name == ITEM_DESCRIPTOR_HELPURL )
126 {
127 p.Value >>= rHelpURL;
128 }
129 else if ( p.Name == ITEM_DESCRIPTOR_CONTAINER )
130 {
131 p.Value >>= rSubMenu;
132 }
133 else if ( p.Name == ITEM_DESCRIPTOR_LABEL )
134 {
135 p.Value >>= rLabel;
136 }
137 else if ( p.Name == ITEM_DESCRIPTOR_TYPE )
138 {
139 p.Value >>= rType;
140 }
141 else if ( p.Name == ITEM_DESCRIPTOR_STYLE )
142 {
143 p.Value >>= rStyle;
144 }
145 }
146}
147
148// Base class implementation
149
152 m_aLabel( ITEM_DESCRIPTOR_LABEL ),
153 m_aContainer( ITEM_DESCRIPTOR_CONTAINER ),
154 m_aHelpURL( ITEM_DESCRIPTOR_HELPURL ),
155 m_aCommandURL( ITEM_DESCRIPTOR_COMMANDURL ),
156 m_aStyle( ITEM_DESCRIPTOR_STYLE )
157{
158}
159
161{
162}
163
165 const OUString& )
166{
167}
168
170 const OUString& /*aTarget*/, const OUString& /*aData*/ )
171{
172}
173
175 const Reference< XLocator > &xLocator)
176{
177 m_xLocator = xLocator;
178}
179
181{
182 if ( m_xLocator.is() )
183 return "Line: " + OUString::number( m_xLocator->getLineNumber() ) + " - ";
184 else
185 return OUString();
186}
187
189 Sequence< PropertyValue > &rProps, const OUString &rCommandURL,
190 const OUString &rHelpId, const OUString &rLabel, sal_Int16 nItemStyleBits )
191{
192 auto pProps = rProps.getArray();
193
194 pProps[0].Name = m_aCommandURL;
195 pProps[1].Name = m_aHelpURL;
196 pProps[2].Name = m_aContainer;
197 pProps[3].Name = m_aLabel;
198 pProps[4].Name = m_aStyle;
199 pProps[5].Name = m_aType;
200
201 // Common values
202 pProps[0].Value <<= rCommandURL;
203 pProps[1].Value <<= rHelpId;
204 pProps[2].Value <<= Reference< XIndexContainer >();
205 pProps[3].Value <<= rLabel;
206 pProps[4].Value <<= nItemStyleBits;
207 pProps[5].Value <<= css::ui::ItemType::DEFAULT;
208}
209
211 const Reference< XIndexContainer >& rMenuBarContainer )
212: m_nElementDepth( 0 ),
213 m_eReaderMode( ReaderMode::None ),
214 m_xMenuBarContainer( rMenuBarContainer ),
215 m_xContainerFactory( rMenuBarContainer, UNO_QUERY )
216{
217}
218
220{
221}
222
224{
225}
226
228{
229 if ( m_nElementDepth > 0 )
230 {
231 OUString aErrorMessage = getErrorLineString() +
232 "A closing element is missing!";
233 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
234 }
235}
236
238 const OUString& aName, const Reference< XAttributeList > &xAttrList )
239{
241 {
243 m_xReader->startElement( aName, xAttrList );
244 }
245 else
246 {
247 if ( aName == ELEMENT_MENUBAR )
248 {
251 }
252 else if ( aName == ELEMENT_MENUPOPUP )
253 {
256 }
258 m_xReader->startDocument();
259 }
260}
261
262void SAL_CALL OReadMenuDocumentHandler::characters(const OUString&)
263{
264}
265
266void SAL_CALL OReadMenuDocumentHandler::endElement( const OUString& aName )
267{
269 return;
270
272 m_xReader->endElement( aName );
273 if ( 0 != m_nElementDepth )
274 return;
275
276 m_xReader->endDocument();
277 m_xReader.clear();
279 {
280 OUString aErrorMessage = getErrorLineString() +
281 "closing element menubar expected!";
282 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
283 }
285 {
286 OUString aErrorMessage = getErrorLineString() +
287 "closing element menupopup expected!";
288 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
289 }
291}
292
294 const Reference< XIndexContainer >& rMenuBarContainer,
295 const Reference< XSingleComponentFactory >& rFactory )
296: m_nElementDepth( 0 ),
297 m_bMenuMode( false ),
298 m_xMenuBarContainer( rMenuBarContainer ),
299 m_xContainerFactory( rFactory )
300{
301}
302
304{
305}
306
308{
309}
310
312{
313}
314
316 const OUString& rName, const Reference< XAttributeList > &xAttrList )
317{
318 if ( m_bMenuMode )
319 {
321 m_xReader->startElement( rName, xAttrList );
322 }
323 else if ( rName == ELEMENT_MENU )
324 {
326
327 OUString aHelpId;
328 OUString aCommandId;
329 OUString aLabel;
330 sal_Int16 nItemBits(0);
331
332 m_bMenuMode = true;
333
334 // Container must be factory to create sub container
335 Reference< XComponentContext > xComponentContext(
337
338 Reference< XIndexContainer > xSubItemContainer;
339 if ( m_xContainerFactory.is() )
340 xSubItemContainer.set( m_xContainerFactory->createInstanceWithContext( xComponentContext ), UNO_QUERY );
341
342 if ( xSubItemContainer.is() )
343 {
344 // read attributes for menu
345 for ( sal_Int16 i=0; i< xAttrList->getLength(); i++ )
346 {
347 OUString aName = xAttrList->getNameByIndex( i );
348 const OUString aValue = xAttrList->getValueByIndex( i );
349 if ( aName == ATTRIBUTE_ID )
350 aCommandId = aValue;
351 else if ( aName == ATTRIBUTE_LABEL )
352 aLabel = aValue;
353 else if ( aName == ATTRIBUTE_HELPID )
354 aHelpId = aValue;
355 else if ( aName == ATTRIBUTE_STYLE )
356 {
357 sal_Int32 nIndex = 0;
358 do
359 {
360 OUString aToken = aValue.getToken( 0, '+', nIndex );
361 if ( !aToken.isEmpty() )
362 {
363 if ( aToken == ATTRIBUTE_ITEMSTYLE_TEXT )
364 nItemBits |= css::ui::ItemStyle::TEXT;
365 else if ( aToken == ATTRIBUTE_ITEMSTYLE_IMAGE )
366 nItemBits |= css::ui::ItemStyle::ICON;
367 else if ( aToken == ATTRIBUTE_ITEMSTYLE_RADIO )
368 nItemBits |= css::ui::ItemStyle::RADIO_CHECK;
369 }
370 }
371 while ( nIndex >= 0 );
372 }
373 }
374
375 if ( !aCommandId.isEmpty() )
376 {
377 Sequence< PropertyValue > aSubMenuProp( 6 );
378 initPropertyCommon( aSubMenuProp, aCommandId, aHelpId, aLabel, nItemBits );
379 aSubMenuProp.getArray()[2].Value <<= xSubItemContainer;
380
381 m_xMenuBarContainer->insertByIndex( m_xMenuBarContainer->getCount(), Any( aSubMenuProp ) );
382 }
383 else
384 {
385 OUString aErrorMessage = getErrorLineString() +
386 "attribute id for element menu required!";
387 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
388 }
389
390 m_xReader.set( new OReadMenuHandler( xSubItemContainer, m_xContainerFactory ));
391 m_xReader->startDocument();
392 }
393 }
394 else
395 {
396 OUString aErrorMessage = getErrorLineString() +
397 "element menu expected!";
398 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
399 }
400}
401
402void SAL_CALL OReadMenuBarHandler::characters(const OUString&)
403{
404}
405
406void OReadMenuBarHandler::endElement( const OUString& aName )
407{
408 if ( !m_bMenuMode )
409 return;
410
412 if ( 0 == m_nElementDepth )
413 {
414 m_xReader->endDocument();
415 m_xReader.clear();
416 m_bMenuMode = false;
417 if ( aName != ELEMENT_MENU )
418 {
419 OUString aErrorMessage = getErrorLineString() +
420 "closing element menu expected!";
421 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
422 }
423 }
424 else
425 m_xReader->endElement( aName );
426}
427
429 const Reference< XIndexContainer >& rMenuContainer,
430 const Reference< XSingleComponentFactory >& rFactory ) :
431 m_nElementDepth( 0 ),
432 m_bMenuPopupMode( false ),
433 m_xMenuContainer( rMenuContainer ),
434 m_xContainerFactory( rFactory )
435{
436}
437
439{
440}
441
443{
444}
445
447{
448}
449
451 const OUString& aName, const Reference< XAttributeList > &xAttrList )
452{
453 if ( m_bMenuPopupMode )
454 {
456 m_xReader->startElement( aName, xAttrList );
457 }
458 else if ( aName == ELEMENT_MENUPOPUP )
459 {
461 m_bMenuPopupMode = true;
463 m_xReader->startDocument();
464 }
465 else
466 {
467 OUString aErrorMessage = getErrorLineString() +
468 "unknown element found!";
469 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
470 }
471}
472
473void SAL_CALL OReadMenuHandler::characters(const OUString&)
474{
475}
476
477void SAL_CALL OReadMenuHandler::endElement( const OUString& aName )
478{
479 if ( !m_bMenuPopupMode )
480 return;
481
483 if ( 0 == m_nElementDepth )
484 {
485 m_xReader->endDocument();
486 m_xReader.clear();
487 m_bMenuPopupMode = false;
488 if ( aName != ELEMENT_MENUPOPUP )
489 {
490 OUString aErrorMessage = getErrorLineString() +
491 "closing element menupopup expected!";
492 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
493 }
494 }
495 else
496 m_xReader->endElement( aName );
497}
498
500 const Reference< XIndexContainer >& rMenuContainer,
501 const Reference< XSingleComponentFactory >& rFactory ) :
502 m_nElementDepth( 0 ),
503 m_bMenuMode( false ),
504 m_xMenuContainer( rMenuContainer ),
505 m_xContainerFactory( rFactory ),
507 m_nNextElementExpected( ELEM_CLOSE_NONE )
508{
509}
510
512{
513}
514
516{
517}
518
520{
521}
522
524 const OUString& rName, const Reference< XAttributeList > &xAttrList )
525{
527
528 if ( m_bMenuMode )
529 m_xReader->startElement( rName, xAttrList );
530 else if ( rName == ELEMENT_MENU )
531 {
532 OUString aHelpId;
533 OUString aCommandId;
534 OUString aLabel;
535 sal_Int16 nItemBits(0);
536
537 m_bMenuMode = true;
538
539 // Container must be factory to create sub container
540 Reference< XIndexContainer > xSubItemContainer;
541 if ( m_xContainerFactory.is() )
542 xSubItemContainer.set( m_xContainerFactory->createInstanceWithContext( m_xComponentContext ), UNO_QUERY );
543
544 // read attributes for menu
545 for ( sal_Int16 i=0; i< xAttrList->getLength(); i++ )
546 {
547 OUString aName = xAttrList->getNameByIndex( i );
548 const OUString aValue = xAttrList->getValueByIndex( i );
549 if ( aName == ATTRIBUTE_ID )
550 aCommandId = aValue;
551 else if ( aName == ATTRIBUTE_LABEL )
552 aLabel = aValue;
553 else if ( aName == ATTRIBUTE_HELPID )
554 aHelpId = aValue;
555 else if ( aName == ATTRIBUTE_STYLE )
556 {
557 sal_Int32 nIndex = 0;
558 do
559 {
560 OUString aToken = aValue.getToken( 0, '+', nIndex );
561 if ( !aToken.isEmpty() )
562 {
563 if ( aToken == ATTRIBUTE_ITEMSTYLE_TEXT )
564 nItemBits |= css::ui::ItemStyle::TEXT;
565 else if ( aToken == ATTRIBUTE_ITEMSTYLE_IMAGE )
566 nItemBits |= css::ui::ItemStyle::ICON;
567 else if ( aToken == ATTRIBUTE_ITEMSTYLE_RADIO )
568 nItemBits |= css::ui::ItemStyle::RADIO_CHECK;
569 }
570 }
571 while ( nIndex >= 0 );
572 }
573
574 }
575
576 if ( !aCommandId.isEmpty() )
577 {
578 Sequence< PropertyValue > aSubMenuProp( 6 );
579 initPropertyCommon( aSubMenuProp, aCommandId, aHelpId, aLabel, nItemBits );
580 aSubMenuProp.getArray()[2].Value <<= xSubItemContainer;
581
582 m_xMenuContainer->insertByIndex( m_xMenuContainer->getCount(), Any( aSubMenuProp ) );
583 }
584 else
585 {
586 OUString aErrorMessage = getErrorLineString() +
587 "attribute id for element menu required!";
588 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
589 }
590
591 m_xReader.set( new OReadMenuHandler( xSubItemContainer, m_xContainerFactory ));
592 m_xReader->startDocument();
593 }
594 else if ( rName == ELEMENT_MENUITEM )
595 {
596 OUString aHelpId;
597 OUString aCommandId;
598 OUString aLabel;
599 sal_Int16 nItemBits(0);
600 // read attributes for menu item
601 for ( sal_Int16 i=0; i< xAttrList->getLength(); i++ )
602 {
603 OUString aName = xAttrList->getNameByIndex( i );
604 const OUString aValue = xAttrList->getValueByIndex( i );
605 if ( aName == ATTRIBUTE_ID )
606 aCommandId = aValue;
607 else if ( aName == ATTRIBUTE_LABEL )
608 aLabel = aValue;
609 else if ( aName == ATTRIBUTE_HELPID )
610 aHelpId = aValue;
611 else if ( aName == ATTRIBUTE_STYLE )
612 {
613 sal_Int32 nIndex = 0;
614 do
615 {
616 OUString aToken = aValue.getToken( 0, '+', nIndex );
617 if ( !aToken.isEmpty() )
618 {
619 if ( aToken == ATTRIBUTE_ITEMSTYLE_TEXT )
620 nItemBits |= css::ui::ItemStyle::TEXT;
621 else if ( aToken == ATTRIBUTE_ITEMSTYLE_IMAGE )
622 nItemBits |= css::ui::ItemStyle::ICON;
623 else if ( aToken == ATTRIBUTE_ITEMSTYLE_RADIO )
624 nItemBits |= css::ui::ItemStyle::RADIO_CHECK;
625 }
626 }
627 while ( nIndex >= 0 );
628 }
629
630 }
631
632 if ( !aCommandId.isEmpty() )
633 {
634 Sequence< PropertyValue > aMenuItem( 6 );
635 initPropertyCommon( aMenuItem, aCommandId, aHelpId, aLabel, nItemBits );
636 aMenuItem.getArray()[2].Value <<= Reference< XIndexContainer >();
637
638 m_xMenuContainer->insertByIndex( m_xMenuContainer->getCount(), Any( aMenuItem ) );
639 }
640
642 }
643 else if ( rName == ELEMENT_MENUSEPARATOR )
644 {
645 Sequence< PropertyValue > aMenuSeparator{ comphelper::makePropertyValue(
646 ITEM_DESCRIPTOR_TYPE, css::ui::ItemType::SEPARATOR_LINE) };
647
648 m_xMenuContainer->insertByIndex( m_xMenuContainer->getCount(), Any( aMenuSeparator ) );
649
651 }
652 else
653 {
654 OUString aErrorMessage = getErrorLineString() +
655 "unknown element found!";
656 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
657 }
658}
659
660void SAL_CALL OReadMenuPopupHandler::characters(const OUString&)
661{
662}
663
664void SAL_CALL OReadMenuPopupHandler::endElement( const OUString& aName )
665{
667 if ( m_bMenuMode )
668 {
669 if ( 0 == m_nElementDepth )
670 {
671 m_xReader->endDocument();
672 m_xReader.clear();
673 m_bMenuMode = false;
674 if ( aName != ELEMENT_MENU )
675 {
676 OUString aErrorMessage = getErrorLineString() +
677 "closing element menu expected!";
678 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
679 }
680 }
681 else
682 m_xReader->endElement( aName );
683 }
684 else
685 {
687 {
688 if ( aName != ELEMENT_MENUITEM )
689 {
690 OUString aErrorMessage = getErrorLineString() +
691 "closing element menuitem expected!";
692 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
693 }
694 }
696 {
698 {
699 OUString aErrorMessage = getErrorLineString() +
700 "closing element menuseparator expected!";
701 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
702 }
703 }
704
706 }
707}
708
709// --------------------------------- Write XML ---------------------------------
710
712 const Reference< XIndexAccess >& rMenuBarContainer,
713 const Reference< XDocumentHandler >& rDocumentHandler,
714 bool bIsMenuBar ) :
715 m_xMenuBarContainer( rMenuBarContainer ),
716 m_xWriteDocumentHandler( rDocumentHandler ),
717 m_bIsMenuBar( bIsMenuBar )
718{
719 m_xEmptyList = new ::comphelper::AttributeList;
720}
721
723{
724}
725
727{
728 rtl::Reference<::comphelper::AttributeList> pList = new ::comphelper::AttributeList;
729
730 m_xWriteDocumentHandler->startDocument();
731
732 // write DOCTYPE line!
733 Reference< XExtendedDocumentHandler > xExtendedDocHandler( m_xWriteDocumentHandler, UNO_QUERY );
734 if ( m_bIsMenuBar /*FIXME*/ && xExtendedDocHandler.is() )
735 {
736 xExtendedDocHandler->unknown( MENUBAR_DOCTYPE );
737 m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
738 }
739
740 pList->AddAttribute( ATTRIBUTE_XMLNS_MENU,
741 XMLNS_MENU );
742
743 if ( m_bIsMenuBar ) //FIXME
744 pList->AddAttribute( ATTRIBUTE_NS_ID,
745 "menubar" );
746
747 OUString aRootElement;
748 if ( m_bIsMenuBar )
749 aRootElement = ELEMENT_NS_MENUBAR;
750 else
751 aRootElement = ELEMENT_NS_MENUPOPUP;
752 m_xWriteDocumentHandler->startElement( aRootElement, pList );
753 m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
754
756
757 m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
758 m_xWriteDocumentHandler->endElement( aRootElement );
759 m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
760 m_xWriteDocumentHandler->endDocument();
761}
762
763void OWriteMenuDocumentHandler::WriteMenu( const Reference< XIndexAccess >& rMenuContainer )
764{
765 sal_Int32 nItemCount = rMenuContainer->getCount();
766 bool bSeparator = false;
767 Any aAny;
768
769 for ( sal_Int32 nItemPos = 0; nItemPos < nItemCount; nItemPos++ )
770 {
771 Sequence< PropertyValue > aProps;
772 aAny = rMenuContainer->getByIndex( nItemPos );
773 if ( aAny >>= aProps )
774 {
775 OUString aCommandURL;
776 OUString aLabel;
777 OUString aHelpURL;
778 sal_Int16 nType( css::ui::ItemType::DEFAULT );
779 sal_Int16 nItemBits( 0 );
780 Reference< XIndexAccess > xSubMenu;
781
782 ExtractMenuParameters( aProps, aCommandURL, aLabel, aHelpURL, xSubMenu, nType, nItemBits );
783 if ( xSubMenu.is() )
784 {
785 if ( !aCommandURL.isEmpty() )
786 {
787 rtl::Reference<::comphelper::AttributeList> pListMenu = new ::comphelper::AttributeList;
788
789 pListMenu->AddAttribute( ATTRIBUTE_NS_ID,
790 aCommandURL );
791
792 if ( !aLabel.isEmpty() )
793 pListMenu->AddAttribute( ATTRIBUTE_NS_LABEL,
794 aLabel );
795
796 m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
797 m_xWriteDocumentHandler->startElement( ELEMENT_NS_MENU, pListMenu );
798 m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
800 m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
801
802 WriteMenu( xSubMenu );
803
804 m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
806 m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
808 m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
809 bSeparator = false;
810 }
811 }
812 else
813 {
814 if ( nType == css::ui::ItemType::DEFAULT )
815 {
816 if ( !aCommandURL.isEmpty() )
817 {
818 bSeparator = false;
819 WriteMenuItem( aCommandURL, aLabel, aHelpURL, nItemBits );
820 }
821 }
822 else if ( !bSeparator )
823 {
824 // Don't write two separators together
826 bSeparator = true;
827 }
828 }
829 }
830 }
831}
832
833void OWriteMenuDocumentHandler::WriteMenuItem( const OUString& aCommandURL, const OUString& aLabel, const OUString& aHelpURL, sal_Int16 nStyle )
834{
835 rtl::Reference<::comphelper::AttributeList> pList = new ::comphelper::AttributeList;
836
837 pList->AddAttribute( ATTRIBUTE_NS_ID,
838 aCommandURL );
839
840 if ( !aHelpURL.isEmpty() )
841 {
842 pList->AddAttribute( ATTRIBUTE_NS_HELPID,
843 aHelpURL );
844 }
845
846 if ( !aLabel.isEmpty() )
847 {
848 pList->AddAttribute( ATTRIBUTE_NS_LABEL,
849 aLabel );
850 }
851 if ( nStyle > 0 )
852 {
853 OUStringBuffer aValue;
854 const MenuStyleItem* pStyle = MenuItemStyles;
855
856 for ( sal_Int32 nIndex = 0; nIndex < nMenuStyleItemEntries; ++nIndex, ++pStyle )
857 {
858 if ( nStyle & pStyle->nBit )
859 {
860 if ( !aValue.isEmpty() )
861 aValue.append("+");
862 aValue.appendAscii( pStyle->attrName );
863 }
864 }
865 pList->AddAttribute( ATTRIBUTE_NS_STYLE,
866 aValue.makeStringAndClear() );
867 }
868
869 m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
870 m_xWriteDocumentHandler->startElement( ELEMENT_NS_MENUITEM, pList );
871 m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
873}
874
876{
877 m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
879 m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
881}
882
883} // namespace framework
884
885/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
uno::Type m_aType
css::uno::Reference< css::lang::XSingleComponentFactory > m_xContainerFactory
virtual void SAL_CALL characters(const OUString &aChars) override
virtual void SAL_CALL startDocument() override
virtual void SAL_CALL endElement(const OUString &aName) override
virtual void SAL_CALL startElement(const OUString &aName, const css::uno::Reference< css::xml::sax::XAttributeList > &xAttribs) override
virtual void SAL_CALL endDocument() override
css::uno::Reference< css::container::XIndexContainer > m_xMenuBarContainer
OReadMenuBarHandler(const css::uno::Reference< css::container::XIndexContainer > &rMenuBarContainer, const css::uno::Reference< css::lang::XSingleComponentFactory > &rContainerFactory)
virtual void SAL_CALL startDocument() override
css::uno::Reference< css::lang::XSingleComponentFactory > m_xContainerFactory
virtual void SAL_CALL startElement(const OUString &aName, const css::uno::Reference< css::xml::sax::XAttributeList > &xAttribs) override
virtual void SAL_CALL characters(const OUString &aChars) override
virtual void SAL_CALL endDocument() override
OReadMenuDocumentHandler(const css::uno::Reference< css::container::XIndexContainer > &rItemContainer)
virtual void SAL_CALL endElement(const OUString &aName) override
css::uno::Reference< css::container::XIndexContainer > m_xMenuBarContainer
virtual void SAL_CALL startElement(const OUString &aName, const css::uno::Reference< css::xml::sax::XAttributeList > &xAttribs) override
virtual void SAL_CALL characters(const OUString &aChars) override
virtual void SAL_CALL startDocument() override
css::uno::Reference< css::lang::XSingleComponentFactory > m_xContainerFactory
OReadMenuHandler(const css::uno::Reference< css::container::XIndexContainer > &rMenuContainer, const css::uno::Reference< css::lang::XSingleComponentFactory > &rContainerFactory)
virtual void SAL_CALL endDocument() override
virtual void SAL_CALL endElement(const OUString &aName) override
css::uno::Reference< css::container::XIndexContainer > m_xMenuContainer
virtual void SAL_CALL characters(const OUString &aChars) override
css::uno::Reference< css::uno::XComponentContext > m_xComponentContext
virtual void SAL_CALL startElement(const OUString &aName, const css::uno::Reference< css::xml::sax::XAttributeList > &xAttribs) override
virtual void SAL_CALL endDocument() override
virtual void SAL_CALL startDocument() override
virtual void SAL_CALL endElement(const OUString &aName) override
OReadMenuPopupHandler(const css::uno::Reference< css::container::XIndexContainer > &rMenuContainer, const css::uno::Reference< css::lang::XSingleComponentFactory > &rContainerFactory)
css::uno::Reference< css::container::XIndexContainer > m_xMenuContainer
css::uno::Reference< css::lang::XSingleComponentFactory > m_xContainerFactory
void WriteMenu(const css::uno::Reference< css::container::XIndexAccess > &rSubMenuContainer)
css::uno::Reference< css::xml::sax::XDocumentHandler > m_xWriteDocumentHandler
void WriteMenuItem(const OUString &aCommandURL, const OUString &aLabel, const OUString &aHelpURL, sal_Int16 nStyle)
css::uno::Reference< css::xml::sax::XAttributeList > m_xEmptyList
OWriteMenuDocumentHandler(const css::uno::Reference< css::container::XIndexAccess > &rMenuBarContainer, const css::uno::Reference< css::xml::sax::XDocumentHandler > &rDocumentHandler, bool bIsMenuBar)
css::uno::Reference< css::container::XIndexAccess > m_xMenuBarContainer
virtual void SAL_CALL setDocumentLocator(const css::uno::Reference< css::xml::sax::XLocator > &xLocator) override
virtual void SAL_CALL ignorableWhitespace(const OUString &aWhitespaces) override
void initPropertyCommon(css::uno::Sequence< css::beans::PropertyValue > &rProps, const OUString &rCommandURL, const OUString &rHelpId, const OUString &rLabel, sal_Int16 nItemStyleBits)
css::uno::Reference< css::xml::sax::XDocumentHandler > m_xReader
virtual void SAL_CALL processingInstruction(const OUString &aTarget, const OUString &aData) override
css::uno::Reference< css::xml::sax::XLocator > m_xLocator
Reference< XComponentContext > const m_xComponentContext
float u
sal_Int32 nIndex
OUString aName
void * p
#define SAL_N_ELEMENTS(arr)
sal_Int16 nBit
constexpr OUStringLiteral ELEMENT_MENU
#define ATTRIBUTE_ITEMSTYLE_RADIO
#define ATTRIBUTE_ITEMSTYLE_TEXT
constexpr OUStringLiteral ITEM_DESCRIPTOR_STYLE
constexpr OUStringLiteral ELEMENT_NS_MENUPOPUP
constexpr OUStringLiteral ELEMENT_MENUSEPARATOR
constexpr OUStringLiteral ITEM_DESCRIPTOR_COMMANDURL
constexpr OUStringLiteral ITEM_DESCRIPTOR_TYPE
constexpr OUStringLiteral ATTRIBUTE_STYLE
constexpr OUStringLiteral ATTRIBUTE_LABEL
constexpr OUStringLiteral ATTRIBUTE_NS_HELPID
constexpr OUStringLiteral ELEMENT_NS_MENUSEPARATOR
constexpr OUStringLiteral ATTRIBUTE_ID
constexpr OUStringLiteral ATTRIBUTE_HELPID
constexpr OUStringLiteral ELEMENT_MENUPOPUP
#define ATTRIBUTE_ITEMSTYLE_IMAGE
const char * attrName
constexpr OUStringLiteral MENUBAR_DOCTYPE
constexpr OUStringLiteral ITEM_DESCRIPTOR_HELPURL
constexpr OUStringLiteral ATTRIBUTE_NS_STYLE
constexpr OUStringLiteral ELEMENT_NS_MENUITEM
constexpr OUStringLiteral ATTRIBUTE_NS_ID
constexpr OUStringLiteral ATTRIBUTE_XMLNS_MENU
constexpr OUStringLiteral ITEM_DESCRIPTOR_LABEL
constexpr OUStringLiteral ELEMENT_MENUITEM
constexpr OUStringLiteral ELEMENT_NS_MENUBAR
constexpr OUStringLiteral ATTRIBUTE_NS_LABEL
constexpr OUStringLiteral ELEMENT_MENUBAR
constexpr OUStringLiteral XMLNS_MENU
constexpr OUStringLiteral ITEM_DESCRIPTOR_CONTAINER
constexpr OUStringLiteral ELEMENT_NS_MENU
Reference< XComponentContext > getProcessComponentContext()
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
constexpr OUStringLiteral ITEM_DESCRIPTOR_STYLE
constexpr OUStringLiteral ITEM_DESCRIPTOR_COMMANDURL
sal_Int32 const nMenuStyleItemEntries
constexpr OUStringLiteral ITEM_DESCRIPTOR_LABEL
constexpr OUStringLiteral ITEM_DESCRIPTOR_TYPE
constexpr OUStringLiteral ITEM_DESCRIPTOR_HELPURL
const MenuStyleItem MenuItemStyles[]
static void ExtractMenuParameters(const Sequence< PropertyValue > &rProp, OUString &rCommandURL, OUString &rLabel, OUString &rHelpURL, Reference< XIndexAccess > &rSubMenu, sal_Int16 &rType, sal_Int16 &rStyle)
int i
None
QPRO_FUNC_TYPE nType
OUString aLabel