1*6d739b60SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*6d739b60SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*6d739b60SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*6d739b60SAndrew Rist  * distributed with this work for additional information
6*6d739b60SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*6d739b60SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*6d739b60SAndrew Rist  * "License"); you may not use this file except in compliance
9*6d739b60SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*6d739b60SAndrew Rist  *
11*6d739b60SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*6d739b60SAndrew Rist  *
13*6d739b60SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*6d739b60SAndrew Rist  * software distributed under the License is distributed on an
15*6d739b60SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*6d739b60SAndrew Rist  * KIND, either express or implied.  See the License for the
17*6d739b60SAndrew Rist  * specific language governing permissions and limitations
18*6d739b60SAndrew Rist  * under the License.
19*6d739b60SAndrew Rist  *
20*6d739b60SAndrew Rist  *************************************************************/
21*6d739b60SAndrew Rist 
22*6d739b60SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_framework.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <uielement/menubarmerger.hxx>
28cdf0e10cSrcweir #include <framework/addonsoptions.hxx>
29cdf0e10cSrcweir 
30cdf0e10cSrcweir using namespace ::com::sun::star;
31cdf0e10cSrcweir 
32cdf0e10cSrcweir static const char SEPARATOR_STRING[]               = "private:separator";
33cdf0e10cSrcweir static const sal_uInt32 SEPARATOR_STRING_LEN       = 17;
34cdf0e10cSrcweir 
35cdf0e10cSrcweir static const char MERGECOMMAND_ADDAFTER[]          = "AddAfter";
36cdf0e10cSrcweir static const sal_uInt32 MERGECOMMAND_ADDAFTER_LEN  = 8;
37cdf0e10cSrcweir static const char MERGECOMMAND_ADDBEFORE[]         = "AddBefore";
38cdf0e10cSrcweir static const sal_uInt32 MERGECOMMAND_ADDBEFORE_LEN = 9;
39cdf0e10cSrcweir static const char MERGECOMMAND_REPLACE[]           = "Replace";
40cdf0e10cSrcweir static const sal_uInt32 MERGECOMMAND_REPLACE_LEN   = 7;
41cdf0e10cSrcweir static const char MERGECOMMAND_REMOVE[]            = "Remove";
42cdf0e10cSrcweir static const sal_uInt32 MERGECOMMAND_REMOVE_LEN    = 6;
43cdf0e10cSrcweir 
44cdf0e10cSrcweir static const char MERGEFALLBACK_ADDPATH[]           = "AddPath";
45cdf0e10cSrcweir static const char MERGEFALLBACK_ADDPATH_LEN         = 7;
46cdf0e10cSrcweir static const char MERGEFALLBACK_IGNORE[]            = "Ignore";
47cdf0e10cSrcweir static const char MERGEFALLBACK_IGNORE_LEN          = 6;
48cdf0e10cSrcweir 
49cdf0e10cSrcweir 
50cdf0e10cSrcweir namespace framework
51cdf0e10cSrcweir {
52cdf0e10cSrcweir 
53cdf0e10cSrcweir /**
54cdf0e10cSrcweir  Check whether a module identifier is part of a context
55cdf0e10cSrcweir  defined by a colon separated list of module identifier.
56cdf0e10cSrcweir 
57cdf0e10cSrcweir  @param
58cdf0e10cSrcweir      rContext
59cdf0e10cSrcweir 
60cdf0e10cSrcweir      Describes a context string list where all contexts
61cdf0e10cSrcweir      are delimited by a colon. For more information about
62cdf0e10cSrcweir      the module identifier used as context strings see the
63cdf0e10cSrcweir      IDL description of com::sun::star::frame::XModuleManager
64cdf0e10cSrcweir 
65cdf0e10cSrcweir   @param
66cdf0e10cSrcweir      rModuleIdentifier
67cdf0e10cSrcweir 
68cdf0e10cSrcweir      A string describing a module identifier. See IDL
69cdf0e10cSrcweir      description of com::sun::star::frame::XModuleManager.
70cdf0e10cSrcweir 
71cdf0e10cSrcweir */
IsCorrectContext(const::rtl::OUString & rContext,const::rtl::OUString & rModuleIdentifier)72cdf0e10cSrcweir bool MenuBarMerger::IsCorrectContext( const ::rtl::OUString& rContext, const ::rtl::OUString& rModuleIdentifier )
73cdf0e10cSrcweir {
74cdf0e10cSrcweir     return (( rContext.getLength() == 0 ) || ( rContext.indexOf( rModuleIdentifier ) >= 0 ));
75cdf0e10cSrcweir }
76cdf0e10cSrcweir 
RetrieveReferencePath(const::rtl::OUString & rReferencePathString,::std::vector<::rtl::OUString> & rReferencePath)77cdf0e10cSrcweir void MenuBarMerger::RetrieveReferencePath(
78cdf0e10cSrcweir     const ::rtl::OUString& rReferencePathString,
79cdf0e10cSrcweir     ::std::vector< ::rtl::OUString >& rReferencePath )
80cdf0e10cSrcweir {
81cdf0e10cSrcweir     const sal_Char aDelimiter = '\\';
82cdf0e10cSrcweir 
83cdf0e10cSrcweir     rReferencePath.clear();
84cdf0e10cSrcweir     sal_Int32 nIndex( 0 );
85cdf0e10cSrcweir 	do
86cdf0e10cSrcweir 	{
87cdf0e10cSrcweir         ::rtl::OUString aToken = rReferencePathString.getToken( 0, aDelimiter, nIndex );
88cdf0e10cSrcweir         if ( aToken.getLength() > 0 )
89cdf0e10cSrcweir             rReferencePath.push_back( aToken );
90cdf0e10cSrcweir     }
91cdf0e10cSrcweir 	while ( nIndex >= 0 );
92cdf0e10cSrcweir }
93cdf0e10cSrcweir 
FindReferencePath(const::std::vector<::rtl::OUString> & rReferencePath,Menu * pMenu)94cdf0e10cSrcweir ReferencePathInfo MenuBarMerger::FindReferencePath(
95cdf0e10cSrcweir     const ::std::vector< ::rtl::OUString >& rReferencePath,
96cdf0e10cSrcweir     Menu* pMenu )
97cdf0e10cSrcweir {
98cdf0e10cSrcweir     sal_uInt32       i( 0 );
99cdf0e10cSrcweir     const sal_uInt32 nCount( rReferencePath.size() );
100cdf0e10cSrcweir     Menu*            pCurrMenu( pMenu );
101cdf0e10cSrcweir     RPResultInfo     eResult( RP_OK );
102cdf0e10cSrcweir 
103cdf0e10cSrcweir     sal_Int32  nLevel( - 1 );
104cdf0e10cSrcweir     sal_uInt16 nPos( MENU_ITEM_NOTFOUND );
105cdf0e10cSrcweir     do
106cdf0e10cSrcweir     {
107cdf0e10cSrcweir         ++nLevel;
108cdf0e10cSrcweir         ::rtl::OUString aCmd( rReferencePath[i] );
109cdf0e10cSrcweir 
110cdf0e10cSrcweir         if ( i == nCount-1 )
111cdf0e10cSrcweir         {
112cdf0e10cSrcweir             // Check last reference path element. Must be a leave (menu item).
113cdf0e10cSrcweir             sal_uInt16 nTmpPos = FindMenuItem( aCmd, pCurrMenu );
114cdf0e10cSrcweir             if ( nTmpPos != MENU_ITEM_NOTFOUND )
115cdf0e10cSrcweir                 nPos = nTmpPos;
116cdf0e10cSrcweir             eResult = ( nTmpPos != MENU_ITEM_NOTFOUND ) ? RP_OK : RP_MENUITEM_NOT_FOUND;
117cdf0e10cSrcweir         }
118cdf0e10cSrcweir         else
119cdf0e10cSrcweir         {
120cdf0e10cSrcweir             // Check reference path element. Must be a node (popup menu)!
121cdf0e10cSrcweir             sal_uInt16 nTmpPos = FindMenuItem( aCmd, pCurrMenu );
122cdf0e10cSrcweir             if ( nTmpPos != MENU_ITEM_NOTFOUND )
123cdf0e10cSrcweir             {
124cdf0e10cSrcweir                 sal_uInt16 nItemId = pCurrMenu->GetItemId( nTmpPos );
125cdf0e10cSrcweir                 Menu* pTmpMenu     = pCurrMenu->GetPopupMenu( nItemId );
126cdf0e10cSrcweir                 if ( pTmpMenu != 0 )
127cdf0e10cSrcweir                     pCurrMenu = pTmpMenu;
128cdf0e10cSrcweir                 else
129cdf0e10cSrcweir                 {
130cdf0e10cSrcweir                     nPos    = nTmpPos;
131cdf0e10cSrcweir                     eResult = RP_MENUITEM_INSTEAD_OF_POPUPMENU_FOUND;
132cdf0e10cSrcweir                 }
133cdf0e10cSrcweir             }
134cdf0e10cSrcweir             else
135cdf0e10cSrcweir                 eResult = RP_POPUPMENU_NOT_FOUND;
136cdf0e10cSrcweir         }
137cdf0e10cSrcweir         i++;
138cdf0e10cSrcweir     }
139cdf0e10cSrcweir     while (( pCurrMenu != 0 ) && ( i < nCount ) && ( eResult == RP_OK ));
140cdf0e10cSrcweir 
141cdf0e10cSrcweir     ReferencePathInfo aResult;
142cdf0e10cSrcweir     aResult.pPopupMenu = pCurrMenu;
143cdf0e10cSrcweir     aResult.nPos       = nPos;
144cdf0e10cSrcweir     aResult.nLevel     = nLevel;
145cdf0e10cSrcweir     aResult.eResult    = eResult;
146cdf0e10cSrcweir 
147cdf0e10cSrcweir     return aResult;
148cdf0e10cSrcweir }
149cdf0e10cSrcweir 
FindMenuItem(const::rtl::OUString & rCmd,Menu * pCurrMenu)150cdf0e10cSrcweir sal_uInt16 MenuBarMerger::FindMenuItem( const ::rtl::OUString& rCmd, Menu* pCurrMenu )
151cdf0e10cSrcweir {
152cdf0e10cSrcweir     for ( sal_uInt16 i = 0; i < pCurrMenu->GetItemCount(); i++ )
153cdf0e10cSrcweir     {
154cdf0e10cSrcweir         const sal_uInt16 nItemId = pCurrMenu->GetItemId( i );
155cdf0e10cSrcweir         if ( nItemId > 0 )
156cdf0e10cSrcweir         {
157cdf0e10cSrcweir             if ( rCmd == ::rtl::OUString( pCurrMenu->GetItemCommand( nItemId )))
158cdf0e10cSrcweir                 return i;
159cdf0e10cSrcweir         }
160cdf0e10cSrcweir     }
161cdf0e10cSrcweir 
162cdf0e10cSrcweir     return MENU_ITEM_NOTFOUND;
163cdf0e10cSrcweir }
164cdf0e10cSrcweir 
CreateSubMenu(Menu * pSubMenu,sal_uInt16 & nItemId,const::rtl::OUString & rModuleIdentifier,const AddonMenuContainer & rAddonSubMenu)165cdf0e10cSrcweir bool MenuBarMerger::CreateSubMenu(
166cdf0e10cSrcweir     Menu*                     pSubMenu,
167cdf0e10cSrcweir     sal_uInt16&               nItemId,
168cdf0e10cSrcweir     const ::rtl::OUString&    rModuleIdentifier,
169cdf0e10cSrcweir     const AddonMenuContainer& rAddonSubMenu )
170cdf0e10cSrcweir {
171cdf0e10cSrcweir     const sal_uInt32 nSize = rAddonSubMenu.size();
172cdf0e10cSrcweir     for ( sal_uInt32 i = 0; i < nSize; i++ )
173cdf0e10cSrcweir     {
174cdf0e10cSrcweir         const AddonMenuItem& rMenuItem = rAddonSubMenu[i];
175cdf0e10cSrcweir 
176cdf0e10cSrcweir         if ( IsCorrectContext( rMenuItem.aContext, rModuleIdentifier ))
177cdf0e10cSrcweir         {
178cdf0e10cSrcweir             if ( rMenuItem.aURL.equalsAsciiL( SEPARATOR_STRING, SEPARATOR_STRING_LEN ))
179cdf0e10cSrcweir             {
180cdf0e10cSrcweir                 pSubMenu->InsertSeparator( MENU_APPEND );
181cdf0e10cSrcweir             }
182cdf0e10cSrcweir             else
183cdf0e10cSrcweir             {
184cdf0e10cSrcweir                 pSubMenu->InsertItem( nItemId, rMenuItem.aTitle, 0, MENU_APPEND );
185cdf0e10cSrcweir                 pSubMenu->SetItemCommand( nItemId, rMenuItem.aURL );
186cdf0e10cSrcweir                 if ( !rMenuItem.aSubMenu.empty() )
187cdf0e10cSrcweir                 {
188cdf0e10cSrcweir                     PopupMenu* pPopupMenu = new PopupMenu();
189cdf0e10cSrcweir                     pSubMenu->SetPopupMenu( nItemId, pPopupMenu );
190cdf0e10cSrcweir                     ++nItemId;
191cdf0e10cSrcweir 
192cdf0e10cSrcweir                     CreateSubMenu( pPopupMenu, nItemId, rModuleIdentifier, rMenuItem.aSubMenu );
193cdf0e10cSrcweir                 }
194cdf0e10cSrcweir                 else
195cdf0e10cSrcweir                     ++nItemId;
196cdf0e10cSrcweir             }
197cdf0e10cSrcweir         }
198cdf0e10cSrcweir     }
199cdf0e10cSrcweir 
200cdf0e10cSrcweir     return true;
201cdf0e10cSrcweir }
202cdf0e10cSrcweir 
MergeMenuItems(Menu * pMenu,sal_uInt16 nPos,sal_uInt16 nModIndex,sal_uInt16 & nItemId,const::rtl::OUString & rModuleIdentifier,const AddonMenuContainer & rAddonMenuItems)203cdf0e10cSrcweir bool MenuBarMerger::MergeMenuItems(
204cdf0e10cSrcweir     Menu*                     pMenu,
205cdf0e10cSrcweir     sal_uInt16                nPos,
206cdf0e10cSrcweir     sal_uInt16                nModIndex,
207cdf0e10cSrcweir     sal_uInt16&               nItemId,
208cdf0e10cSrcweir     const ::rtl::OUString&    rModuleIdentifier,
209cdf0e10cSrcweir     const AddonMenuContainer& rAddonMenuItems )
210cdf0e10cSrcweir {
211cdf0e10cSrcweir     sal_uInt16       nIndex( 0 );
212cdf0e10cSrcweir     const sal_uInt32 nSize = rAddonMenuItems.size();
213cdf0e10cSrcweir     for ( sal_uInt32 i = 0; i < nSize; i++ )
214cdf0e10cSrcweir     {
215cdf0e10cSrcweir         const AddonMenuItem& rMenuItem = rAddonMenuItems[i];
216cdf0e10cSrcweir 
217cdf0e10cSrcweir         if ( IsCorrectContext( rMenuItem.aContext, rModuleIdentifier ))
218cdf0e10cSrcweir         {
219cdf0e10cSrcweir             if ( rMenuItem.aURL.equalsAsciiL( SEPARATOR_STRING, SEPARATOR_STRING_LEN ))
220cdf0e10cSrcweir             {
221cdf0e10cSrcweir                 pMenu->InsertSeparator( nPos+nModIndex+nIndex );
222cdf0e10cSrcweir             }
223cdf0e10cSrcweir             else
224cdf0e10cSrcweir             {
225cdf0e10cSrcweir                 pMenu->InsertItem( nItemId, rMenuItem.aTitle, 0, nPos+nModIndex+nIndex );
226cdf0e10cSrcweir                 pMenu->SetItemCommand( nItemId, rMenuItem.aURL );
227cdf0e10cSrcweir                 if ( !rMenuItem.aSubMenu.empty() )
228cdf0e10cSrcweir                 {
229cdf0e10cSrcweir                     PopupMenu* pSubMenu = new PopupMenu();
230cdf0e10cSrcweir                     pMenu->SetPopupMenu( nItemId, pSubMenu );
231cdf0e10cSrcweir                     ++nItemId;
232cdf0e10cSrcweir 
233cdf0e10cSrcweir                     CreateSubMenu( pSubMenu, nItemId, rModuleIdentifier, rMenuItem.aSubMenu );
234cdf0e10cSrcweir                 }
235cdf0e10cSrcweir                 else
236cdf0e10cSrcweir                     ++nItemId;
237cdf0e10cSrcweir             }
238cdf0e10cSrcweir             ++nIndex;
239cdf0e10cSrcweir         }
240cdf0e10cSrcweir     }
241cdf0e10cSrcweir 
242cdf0e10cSrcweir     return true;
243cdf0e10cSrcweir }
244cdf0e10cSrcweir 
ReplaceMenuItem(Menu * pMenu,sal_uInt16 nPos,sal_uInt16 & rItemId,const::rtl::OUString & rModuleIdentifier,const AddonMenuContainer & rAddonMenuItems)245cdf0e10cSrcweir bool MenuBarMerger::ReplaceMenuItem(
246cdf0e10cSrcweir     Menu*                     pMenu,
247cdf0e10cSrcweir     sal_uInt16                nPos,
248cdf0e10cSrcweir     sal_uInt16&               rItemId,
249cdf0e10cSrcweir     const ::rtl::OUString&    rModuleIdentifier,
250cdf0e10cSrcweir     const AddonMenuContainer& rAddonMenuItems )
251cdf0e10cSrcweir {
252cdf0e10cSrcweir     // There is no replace available. Therfore we first have to
253cdf0e10cSrcweir     // remove the old menu entry,
254cdf0e10cSrcweir     pMenu->RemoveItem( nPos );
255cdf0e10cSrcweir 
256cdf0e10cSrcweir     return MergeMenuItems( pMenu, nPos, 0, rItemId, rModuleIdentifier, rAddonMenuItems );
257cdf0e10cSrcweir }
258cdf0e10cSrcweir 
RemoveMenuItems(Menu * pMenu,sal_uInt16 nPos,const::rtl::OUString & rMergeCommandParameter)259cdf0e10cSrcweir bool MenuBarMerger::RemoveMenuItems(
260cdf0e10cSrcweir     Menu*                     pMenu,
261cdf0e10cSrcweir     sal_uInt16                nPos,
262cdf0e10cSrcweir     const ::rtl::OUString&    rMergeCommandParameter )
263cdf0e10cSrcweir {
264cdf0e10cSrcweir     const sal_uInt16 nParam( sal_uInt16( rMergeCommandParameter.toInt32() ));
265cdf0e10cSrcweir     sal_uInt16       nCount( 1 );
266cdf0e10cSrcweir 
267cdf0e10cSrcweir     nCount = std::max( nParam, nCount );
268cdf0e10cSrcweir 
269cdf0e10cSrcweir     sal_uInt16 i = 0;
270cdf0e10cSrcweir     while (( nPos < pMenu->GetItemCount() ) && ( i < nCount ))
271cdf0e10cSrcweir     {
272cdf0e10cSrcweir         pMenu->RemoveItem( nPos );
273cdf0e10cSrcweir         ++i;
274cdf0e10cSrcweir     }
275cdf0e10cSrcweir 
276cdf0e10cSrcweir     return true;
277cdf0e10cSrcweir }
278cdf0e10cSrcweir 
ProcessMergeOperation(Menu * pMenu,sal_uInt16 nPos,sal_uInt16 & nItemId,const::rtl::OUString & rMergeCommand,const::rtl::OUString & rMergeCommandParameter,const::rtl::OUString & rModuleIdentifier,const AddonMenuContainer & rAddonMenuItems)279cdf0e10cSrcweir bool MenuBarMerger::ProcessMergeOperation(
280cdf0e10cSrcweir     Menu*                     pMenu,
281cdf0e10cSrcweir     sal_uInt16                nPos,
282cdf0e10cSrcweir     sal_uInt16&               nItemId,
283cdf0e10cSrcweir     const ::rtl::OUString&    rMergeCommand,
284cdf0e10cSrcweir     const ::rtl::OUString&    rMergeCommandParameter,
285cdf0e10cSrcweir     const ::rtl::OUString&    rModuleIdentifier,
286cdf0e10cSrcweir     const AddonMenuContainer& rAddonMenuItems )
287cdf0e10cSrcweir {
288cdf0e10cSrcweir     sal_uInt16 nModIndex( 0 );
289cdf0e10cSrcweir 
290cdf0e10cSrcweir     if ( rMergeCommand.equalsAsciiL( MERGECOMMAND_ADDBEFORE, MERGECOMMAND_ADDBEFORE_LEN ))
291cdf0e10cSrcweir     {
292cdf0e10cSrcweir         nModIndex = 0;
293cdf0e10cSrcweir         return MergeMenuItems( pMenu, nPos, nModIndex, nItemId, rModuleIdentifier, rAddonMenuItems );
294cdf0e10cSrcweir     }
295cdf0e10cSrcweir     else if ( rMergeCommand.equalsAsciiL( MERGECOMMAND_ADDAFTER, MERGECOMMAND_ADDAFTER_LEN ))
296cdf0e10cSrcweir     {
297cdf0e10cSrcweir         nModIndex = 1;
298cdf0e10cSrcweir         return MergeMenuItems( pMenu, nPos, nModIndex, nItemId, rModuleIdentifier, rAddonMenuItems );
299cdf0e10cSrcweir     }
300cdf0e10cSrcweir     else if ( rMergeCommand.equalsAsciiL( MERGECOMMAND_REPLACE, MERGECOMMAND_REPLACE_LEN ))
301cdf0e10cSrcweir     {
302cdf0e10cSrcweir         return ReplaceMenuItem( pMenu, nPos, nItemId, rModuleIdentifier, rAddonMenuItems );
303cdf0e10cSrcweir     }
304cdf0e10cSrcweir     else if ( rMergeCommand.equalsAsciiL( MERGECOMMAND_REMOVE, MERGECOMMAND_REMOVE_LEN ))
305cdf0e10cSrcweir     {
306cdf0e10cSrcweir         return RemoveMenuItems( pMenu, nPos, rMergeCommandParameter );
307cdf0e10cSrcweir     }
308cdf0e10cSrcweir 
309cdf0e10cSrcweir     return false;
310cdf0e10cSrcweir }
311cdf0e10cSrcweir 
ProcessFallbackOperation(const ReferencePathInfo & aRefPathInfo,sal_uInt16 & rItemId,const::rtl::OUString & rMergeCommand,const::rtl::OUString & rMergeFallback,const::std::vector<::rtl::OUString> & rReferencePath,const::rtl::OUString & rModuleIdentifier,const AddonMenuContainer & rAddonMenuItems)312cdf0e10cSrcweir bool MenuBarMerger::ProcessFallbackOperation(
313cdf0e10cSrcweir     const ReferencePathInfo&                aRefPathInfo,
314cdf0e10cSrcweir     sal_uInt16&                             rItemId,
315cdf0e10cSrcweir     const ::rtl::OUString&                  rMergeCommand,
316cdf0e10cSrcweir     const ::rtl::OUString&                  rMergeFallback,
317cdf0e10cSrcweir     const ::std::vector< ::rtl::OUString >& rReferencePath,
318cdf0e10cSrcweir     const ::rtl::OUString&                  rModuleIdentifier,
319cdf0e10cSrcweir     const AddonMenuContainer&               rAddonMenuItems )
320cdf0e10cSrcweir {
321cdf0e10cSrcweir     if (( rMergeFallback.equalsAsciiL( MERGEFALLBACK_IGNORE, MERGEFALLBACK_IGNORE_LEN )) ||
322cdf0e10cSrcweir         ( rMergeCommand.equalsAsciiL(  MERGECOMMAND_REPLACE, MERGECOMMAND_REPLACE_LEN )) ||
323cdf0e10cSrcweir         ( rMergeCommand.equalsAsciiL(  MERGECOMMAND_REMOVE, MERGECOMMAND_REMOVE_LEN   )) )
324cdf0e10cSrcweir     {
325cdf0e10cSrcweir         return true;
326cdf0e10cSrcweir     }
327cdf0e10cSrcweir     else if ( rMergeFallback.equalsAsciiL( MERGEFALLBACK_ADDPATH, MERGEFALLBACK_ADDPATH_LEN ))
328cdf0e10cSrcweir     {
329cdf0e10cSrcweir         Menu*            pCurrMenu( aRefPathInfo.pPopupMenu );
330cdf0e10cSrcweir         sal_Int32        nLevel( aRefPathInfo.nLevel );
331cdf0e10cSrcweir         const sal_Int32  nSize( rReferencePath.size() );
332cdf0e10cSrcweir         bool             bFirstLevel( true );
333cdf0e10cSrcweir 
334cdf0e10cSrcweir         while ( nLevel < nSize )
335cdf0e10cSrcweir         {
336cdf0e10cSrcweir             if ( nLevel == nSize-1 )
337cdf0e10cSrcweir             {
338cdf0e10cSrcweir                 const sal_uInt32 nCount = rAddonMenuItems.size();
339cdf0e10cSrcweir                 for ( sal_uInt32 i = 0; i < nCount; ++i )
340cdf0e10cSrcweir                 {
341cdf0e10cSrcweir                     const AddonMenuItem& rMenuItem = rAddonMenuItems[i];
342cdf0e10cSrcweir                     if ( IsCorrectContext( rMenuItem.aContext, rModuleIdentifier ))
343cdf0e10cSrcweir                     {
344cdf0e10cSrcweir                         if ( rMenuItem.aURL.equalsAsciiL( SEPARATOR_STRING, SEPARATOR_STRING_LEN ))
345cdf0e10cSrcweir                             pCurrMenu->InsertSeparator( MENU_APPEND );
346cdf0e10cSrcweir                         else
347cdf0e10cSrcweir                         {
348cdf0e10cSrcweir                             pCurrMenu->InsertItem( rItemId, rMenuItem.aTitle, 0, MENU_APPEND );
349cdf0e10cSrcweir                             pCurrMenu->SetItemCommand( rItemId, rMenuItem.aURL );
350cdf0e10cSrcweir                             ++rItemId;
351cdf0e10cSrcweir                         }
352cdf0e10cSrcweir                     }
353cdf0e10cSrcweir                 }
354cdf0e10cSrcweir             }
355cdf0e10cSrcweir             else
356cdf0e10cSrcweir             {
357cdf0e10cSrcweir                 const ::rtl::OUString aCmd( rReferencePath[nLevel] );
358cdf0e10cSrcweir 
359cdf0e10cSrcweir                 sal_uInt16 nInsPos( MENU_APPEND );
360cdf0e10cSrcweir                 PopupMenu* pPopupMenu( new PopupMenu );
361cdf0e10cSrcweir 
362cdf0e10cSrcweir                 if ( bFirstLevel && ( aRefPathInfo.eResult == RP_MENUITEM_INSTEAD_OF_POPUPMENU_FOUND ))
363cdf0e10cSrcweir                 {
364cdf0e10cSrcweir                     // special case: menu item without popup
365cdf0e10cSrcweir                     nInsPos = aRefPathInfo.nPos;
366cdf0e10cSrcweir                     sal_uInt16 nSetItemId = pCurrMenu->GetItemId( nInsPos );
367cdf0e10cSrcweir                     pCurrMenu->SetItemCommand( nSetItemId, aCmd );
368cdf0e10cSrcweir                     pCurrMenu->SetPopupMenu( nSetItemId, pPopupMenu );
369cdf0e10cSrcweir                 }
370cdf0e10cSrcweir                 else
371cdf0e10cSrcweir                 {
372cdf0e10cSrcweir                     // normal case: insert a new item with popup
373cdf0e10cSrcweir                     pCurrMenu->InsertItem( rItemId, ::rtl::OUString(), 0, MENU_APPEND );
374cdf0e10cSrcweir                     pCurrMenu->SetItemCommand( rItemId, aCmd );
375cdf0e10cSrcweir                     pCurrMenu->SetPopupMenu( rItemId, pPopupMenu );
376cdf0e10cSrcweir                 }
377cdf0e10cSrcweir 
378cdf0e10cSrcweir                 pCurrMenu = pPopupMenu;
379cdf0e10cSrcweir                 ++rItemId;
380cdf0e10cSrcweir                 bFirstLevel = false;
381cdf0e10cSrcweir             }
382cdf0e10cSrcweir             ++nLevel;
383cdf0e10cSrcweir         }
384cdf0e10cSrcweir         return true;
385cdf0e10cSrcweir     }
386cdf0e10cSrcweir 
387cdf0e10cSrcweir     return false;
388cdf0e10cSrcweir }
389cdf0e10cSrcweir 
GetMenuEntry(const uno::Sequence<beans::PropertyValue> & rAddonMenuEntry,AddonMenuItem & rAddonMenuItem)390cdf0e10cSrcweir void MenuBarMerger::GetMenuEntry(
391cdf0e10cSrcweir     const uno::Sequence< beans::PropertyValue >& rAddonMenuEntry,
392cdf0e10cSrcweir     AddonMenuItem&                               rAddonMenuItem )
393cdf0e10cSrcweir {
394cdf0e10cSrcweir 	// Reset submenu member
395cdf0e10cSrcweir     rAddonMenuItem.aSubMenu.clear();
396cdf0e10cSrcweir 
397cdf0e10cSrcweir 	for ( sal_Int32 i = 0; i < rAddonMenuEntry.getLength(); i++ )
398cdf0e10cSrcweir 	{
399cdf0e10cSrcweir         ::rtl::OUString aMenuEntryPropName = rAddonMenuEntry[i].Name;
400cdf0e10cSrcweir 		if ( aMenuEntryPropName.equalsAsciiL( ADDONSMENUITEM_STRING_URL, ADDONSMENUITEM_URL_LEN ))
401cdf0e10cSrcweir 			rAddonMenuEntry[i].Value >>= rAddonMenuItem.aURL;
402cdf0e10cSrcweir 		else if ( aMenuEntryPropName.equalsAsciiL( ADDONSMENUITEM_STRING_TITLE, ADDONSMENUITEM_TITLE_LEN ))
403cdf0e10cSrcweir 			rAddonMenuEntry[i].Value >>= rAddonMenuItem.aTitle;
404cdf0e10cSrcweir 		else if ( aMenuEntryPropName.equalsAsciiL( ADDONSMENUITEM_STRING_TARGET, ADDONSMENUITEM_TARGET_LEN ))
405cdf0e10cSrcweir 			rAddonMenuEntry[i].Value >>= rAddonMenuItem.aTarget;
406cdf0e10cSrcweir 		else if ( aMenuEntryPropName.equalsAsciiL( ADDONSMENUITEM_STRING_SUBMENU, ADDONSMENUITEM_SUBMENU_LEN ))
407cdf0e10cSrcweir         {
408cdf0e10cSrcweir             uno::Sequence< uno::Sequence< beans::PropertyValue > > aSubMenu;
409cdf0e10cSrcweir             rAddonMenuEntry[i].Value >>= aSubMenu;
410cdf0e10cSrcweir             GetSubMenu( aSubMenu, rAddonMenuItem.aSubMenu );
411cdf0e10cSrcweir         }
412cdf0e10cSrcweir 		else if ( aMenuEntryPropName.equalsAsciiL( ADDONSMENUITEM_STRING_CONTEXT, ADDONSMENUITEM_CONTEXT_LEN ))
413cdf0e10cSrcweir 			rAddonMenuEntry[i].Value >>= rAddonMenuItem.aContext;
414cdf0e10cSrcweir 		else if ( aMenuEntryPropName.equalsAsciiL( ADDONSMENUITEM_STRING_IMAGEIDENTIFIER, ADDONSMENUITEM_IMAGEIDENTIFIER_LEN ))
415cdf0e10cSrcweir 			rAddonMenuEntry[i].Value >>= rAddonMenuItem.aImageId;
416cdf0e10cSrcweir 	}
417cdf0e10cSrcweir }
418cdf0e10cSrcweir 
GetSubMenu(const uno::Sequence<uno::Sequence<beans::PropertyValue>> & rSubMenuEntries,AddonMenuContainer & rSubMenu)419cdf0e10cSrcweir void MenuBarMerger::GetSubMenu(
420cdf0e10cSrcweir     const uno::Sequence< uno::Sequence< beans::PropertyValue > >& rSubMenuEntries,
421cdf0e10cSrcweir     AddonMenuContainer&                                           rSubMenu )
422cdf0e10cSrcweir {
423cdf0e10cSrcweir     rSubMenu.clear();
424cdf0e10cSrcweir 
425cdf0e10cSrcweir     const sal_Int32 nCount = rSubMenuEntries.getLength();
426cdf0e10cSrcweir     rSubMenu.reserve(rSubMenu.size() + nCount);
427cdf0e10cSrcweir     for ( sal_Int32 i = 0; i < nCount; i++ )
428cdf0e10cSrcweir     {
429cdf0e10cSrcweir         const uno::Sequence< beans::PropertyValue >& rMenuEntry = rSubMenuEntries[ i ];
430cdf0e10cSrcweir 
431cdf0e10cSrcweir         AddonMenuItem aMenuItem;
432cdf0e10cSrcweir         GetMenuEntry( rMenuEntry, aMenuItem );
433cdf0e10cSrcweir         rSubMenu.push_back( aMenuItem );
434cdf0e10cSrcweir     }
435cdf0e10cSrcweir }
436cdf0e10cSrcweir 
437cdf0e10cSrcweir } // namespace framework
438