xref: /trunk/main/sfx2/source/menu/mnumgr.cxx (revision 79aad27f)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sfx2.hxx"
26 
27 #include <com/sun/star/embed/VerbDescriptor.hpp>
28 #include <com/sun/star/embed/VerbAttributes.hpp>
29 #include <com/sun/star/container/XNamed.hpp>
30 
31 #ifdef SOLARIS
32 // HACK: prevent conflict between STLPORT and Workshop headers on Solaris 8
33 #include <ctime>
34 #endif
35 
36 #include <string> 	// HACK: prevent conflict between STLPORT and Workshop headers
37 #include <cstdarg>	// std::va_list
38 
39 #ifndef _POINTR_HXX //autogen
40 #include <vcl/pointr.hxx>
41 #endif
42 #ifndef GCC
43 #endif
44 
45 #include <unotools/streamwrap.hxx>
46 #include <sfx2/objsh.hxx>
47 #include <framework/menuconfiguration.hxx>
48 #include <framework/addonmenu.hxx>
49 #include <comphelper/processfactory.hxx>
50 #include <unotools/ucbstreamhelper.hxx>
51 #include <unotools/lingucfg.hxx>
52 #include <tools/urlobj.hxx>
53 #include <unotools/pathoptions.hxx>
54 #include <svl/stritem.hxx>
55 #include <toolkit/helper/vclunohelper.hxx>
56 #include <osl/file.hxx>
57 #include <vcl/graph.hxx>
58 #include <svtools/filter.hxx>
59 #include <svl/lngmisc.hxx>
60 
61 #include <sfx2/mnumgr.hxx>
62 
63 #define _SVSTDARR_USHORTS
64 #include <svl/svstdarr.hxx>
65 #include <svtools/menuoptions.hxx>
66 
67 #include "virtmenu.hxx"
68 #include <sfx2/msg.hxx>
69 #include <sfx2/dispatch.hxx>
70 #include <sfx2/minstack.hxx>
71 #include <sfx2/app.hxx>
72 #include "sfxtypes.hxx"
73 #include <sfx2/bindings.hxx>
74 #include "mnucfga.hxx"
75 #include "sfx2/sfxresid.hxx"
76 #include <sfx2/msgpool.hxx>
77 #include <sfx2/sfx.hrc>
78 #include "menu.hrc"
79 #include <sfx2/viewfrm.hxx>
80 #include <sfx2/viewsh.hxx>
81 #include <sfx2/objface.hxx>
82 #include "thessubmenu.hxx"
83 
84 
85 static const sal_uInt16 nCompatVersion = 4;
86 static const sal_uInt16 nVersion = 5;
87 
88 // static member initialization
89 PopupMenu * SfxPopupMenuManager::pStaticThesSubMenu = NULL;
90 
91 using namespace com::sun::star;
92 
93 //=========================================================================
94 
95 DECL_PTRSTACK(SfxMenuCfgItemArrStack, SfxMenuCfgItemArr*, 4, 4 );
96 
97 //-------------------------------------------------------------------------
98 
TryToHideDisabledEntries_Impl(Menu * pMenu)99 void TryToHideDisabledEntries_Impl( Menu* pMenu )
100 {
101 	DBG_ASSERT( pMenu, "invalid menu" );
102 	if( SvtMenuOptions().IsEntryHidingEnabled() == sal_False )
103 	{
104 		pMenu->SetMenuFlags( pMenu->GetMenuFlags() | MENU_FLAG_HIDEDISABLEDENTRIES );
105 	}
106 }
107 
108 //-------------------------------------------------------------------------
109 
SfxMenuManager(const ResId & rResId,SfxBindings & rBindings)110 SfxMenuManager::SfxMenuManager( const ResId& rResId, SfxBindings &rBindings )
111 :   pMenu(0),
112     pOldMenu(0),
113     pBindings(&rBindings),
114     pResMgr(rResId.GetResMgr()),
115     nType( rResId.GetId() )
116 {
117 	bAddClipboardFuncs = sal_False;
118 	DBG_MEMTEST();
119 }
120 
121 //--------------------------------------------------------------------
122 
~SfxMenuManager()123 SfxMenuManager::~SfxMenuManager()
124 {
125 	DBG_MEMTEST();
126 	pBindings->ENTERREGISTRATIONS();
127 	delete pMenu;
128 	pBindings->LEAVEREGISTRATIONS();
129 }
130 
131 //--------------------------------------------------------------------
132 
Construct(SfxVirtualMenu & rMenu)133 void SfxMenuManager::Construct( SfxVirtualMenu& rMenu )
134 {
135 	DBG_MEMTEST();
136 	pMenu = &rMenu;
137 
138 	// set the handlers
139 	Menu *pSvMenu = pMenu->GetSVMenu();
140 	pSvMenu->SetSelectHdl( LINK(this, SfxMenuManager, Select) );
141 	TryToHideDisabledEntries_Impl( pSvMenu );
142 }
143 
144 //-------------------------------------------------------------------------
InsertVerbs_Impl(SfxBindings * pBindings,const com::sun::star::uno::Sequence<com::sun::star::embed::VerbDescriptor> & aVerbs,Menu * pMenu)145 void InsertVerbs_Impl( SfxBindings* pBindings, const com::sun::star::uno::Sequence < com::sun::star::embed::VerbDescriptor >& aVerbs, Menu* pMenu )
146 {
147     SfxViewShell *pView = pBindings->GetDispatcher()->GetFrame()->GetViewShell();
148     if ( pView && aVerbs.getLength() )
149     {
150         SfxObjectShell* pDoc = pView->GetObjectShell();
151         pMenu->InsertSeparator();
152         sal_uInt16 nr=0;
153         for ( sal_uInt16 n = 0; n < aVerbs.getLength(); ++n )
154         {
155             // check for ReadOnly verbs
156             if ( pDoc->IsReadOnly() && !(aVerbs[n].VerbAttributes & embed::VerbAttributes::MS_VERBATTR_NEVERDIRTIES) )
157                 continue;
158 
159             // check for verbs that shouldn't appear in the menu
160             if ( !(aVerbs[n].VerbAttributes & embed::VerbAttributes::MS_VERBATTR_ONCONTAINERMENU) )
161                 continue;
162 
163             // neue Id vergeben
164             sal_uInt16 nId = SID_VERB_START + nr++;
165             DBG_ASSERT(nId <= SID_VERB_END, "Zuviele Verben!");
166             if ( nId > SID_VERB_END )
167                 break;
168 
169             // einf"ugen
170             pMenu->InsertItem( nId, aVerbs[n].VerbName );
171         }
172     }
173 }
174 
175 
176 //--------------------------------------------------------------------
177 
178 
lcl_GetImageFromPngUrl(const::rtl::OUString & rFileUrl)179 static Image lcl_GetImageFromPngUrl( const ::rtl::OUString &rFileUrl )
180 {
181     Image aRes;
182 
183     ::rtl::OUString aTmp;
184     osl::FileBase::getSystemPathFromFileURL( rFileUrl, aTmp );
185 
186     Graphic aGraphic;
187     const String aFilterName( RTL_CONSTASCII_USTRINGPARAM( IMP_PNG ) );
188     if( GRFILTER_OK == GraphicFilter::LoadGraphic( aTmp, aFilterName, aGraphic ) )
189     {
190         aRes = Image( aGraphic.GetBitmapEx() );
191     }
192     return aRes;
193 }
194 
195 
InsertThesaurusSubmenu_Impl(SfxBindings * pBindings,Menu * pSVMenu)196 PopupMenu* InsertThesaurusSubmenu_Impl( SfxBindings* pBindings, Menu* pSVMenu )
197 {
198     //
199     // build thesaurus sub menu if look-up string is available
200     //
201     PopupMenu* pThesSubMenu = 0;
202     SfxPoolItem *pItem = 0;
203     pBindings->QueryState( SID_THES, pItem );
204     String aThesLookUpStr;
205     SfxStringItem *pStrItem = dynamic_cast< SfxStringItem * >(pItem);
206     xub_StrLen nDelimPos = STRING_LEN;
207     if (pStrItem)
208     {
209         aThesLookUpStr = pStrItem->GetValue();
210         nDelimPos = aThesLookUpStr.SearchBackward( '#' );
211     }
212     if (aThesLookUpStr.Len() > 0 && nDelimPos != STRING_NOTFOUND)
213     {
214         // get synonym list for sub menu
215         std::vector< ::rtl::OUString > aSynonyms;
216         SfxThesSubMenuHelper aHelper;
217         ::rtl::OUString aText( aHelper.GetText( aThesLookUpStr, nDelimPos ) );
218         lang::Locale aLocale;
219         aHelper.GetLocale( aLocale, aThesLookUpStr, nDelimPos );
220         const bool bHasMoreSynonyms = aHelper.GetMeanings( aSynonyms, aText, aLocale, 7 /*max number of synonyms to retrieve*/ );
221         (void) bHasMoreSynonyms;
222 
223         pThesSubMenu = new PopupMenu;
224         pThesSubMenu->SetMenuFlags(MENU_FLAG_NOAUTOMNEMONICS);
225         const size_t nNumSynonyms = aSynonyms.size();
226         if (nNumSynonyms > 0)
227         {
228             SvtLinguConfig aCfg;
229             const bool bHC = Application::GetSettings().GetStyleSettings().GetHighContrastMode();
230 
231             Image aImage;
232             String sThesImplName( aHelper.GetThesImplName( aLocale ) );
233             ::rtl::OUString aSynonymsImageUrl( aCfg.GetSynonymsContextImage( sThesImplName, bHC ) );
234             if (sThesImplName.Len() > 0 && aSynonymsImageUrl.getLength() > 0)
235                 aImage = Image( lcl_GetImageFromPngUrl( aSynonymsImageUrl ) );
236 
237             for (sal_uInt16 i = 0; (size_t)i < nNumSynonyms; ++i)
238             {
239                 //! item ids should start with values > 0, since 0 has special meaning
240                 const sal_uInt16 nId = i + 1;
241 
242                 String aItemText( linguistic::GetThesaurusReplaceText( aSynonyms[i] ) );
243                 pThesSubMenu->InsertItem( nId, aItemText );
244                 ::rtl::OUString aCmd( ::rtl::OUString::createFromAscii( ".uno:ThesaurusFromContext?WordReplace:string=" ) );
245                 aCmd += aItemText;
246                 pThesSubMenu->SetItemCommand( nId, aCmd );
247 
248                 if (aSynonymsImageUrl.getLength() > 0)
249                     pThesSubMenu->SetItemImage( nId, aImage );
250             }
251         }
252         else // nNumSynonyms == 0
253         {
254             const String aItemText( SfxResId( STR_MENU_NO_SYNONYM_FOUND ) );
255             pThesSubMenu->InsertItem( 1, aItemText, MIB_NOSELECT );
256         }
257         pThesSubMenu->InsertSeparator();
258         const String sThesaurus( SfxResId( STR_MENU_THESAURUS ) );
259         pThesSubMenu->InsertItem( 100, sThesaurus );
260         pThesSubMenu->SetItemCommand( 100, ::rtl::OUString::createFromAscii( ".uno:ThesaurusDialog" ) );
261 
262         pSVMenu->InsertSeparator();
263         const String sSynonyms( SfxResId( STR_MENU_SYNONYMS ) );
264         pSVMenu->InsertItem( SID_THES, sSynonyms );
265         pSVMenu->SetPopupMenu( SID_THES, pThesSubMenu );
266     }
267 
268     return pThesSubMenu;
269 }
270 
271 
272 //--------------------------------------------------------------------
273 
UseDefault()274 void SfxMenuManager::UseDefault()
275 {
276 	DBG_MEMTEST();
277 
278 	SFX_APP();
279 	SfxVirtualMenu *pOldVirtMenu=0;
280 	if (pMenu)
281 	{
282 		pOldVirtMenu = pMenu;
283 		pBindings->ENTERREGISTRATIONS();
284 	}
285 
286 	SfxVirtualMenu *pVMenu = 0;
287 	{
288 		ResId aResId(GetType(),*pResMgr);
289 		aResId.SetRT(RSC_MENU);
290 		Menu *pSVMenu = new PopupMenu( aResId );
291         //SfxMenuManager::EraseItemCmds( pSVMenu ); // Remove .uno cmds to be compatible with 6.0/src641
292 
293 		if ( bAddClipboardFuncs )
294 		{
295 			sal_uInt16 n, nCount = pSVMenu->GetItemCount();
296 			for ( n=0; n<nCount; n++ )
297 			{
298 				sal_uInt16 nId = pSVMenu->GetItemId( n );
299 				if ( nId == SID_COPY || nId == SID_CUT || nId == SID_PASTE )
300 					break;
301 			}
302 
303 			if ( n == nCount )
304 			{
305 				PopupMenu aPop( SfxResId( MN_CLIPBOARDFUNCS ) );
306 				nCount = aPop.GetItemCount();
307 				pSVMenu->InsertSeparator();
308 				for ( n=0; n<nCount; n++ )
309 				{
310 					sal_uInt16 nId = aPop.GetItemId( n );
311 					pSVMenu->InsertItem( nId, aPop.GetItemText( nId ), aPop.GetItemBits( nId ) );
312 				}
313 			}
314 		}
315 
316 		pVMenu = new SfxVirtualMenu( pSVMenu, sal_False, *pBindings, sal_True, sal_True );
317 	}
318 
319 	Construct(*pVMenu);
320 	if (pOldVirtMenu)
321 	{
322 		delete pOldVirtMenu;
323 		pBindings->LEAVEREGISTRATIONS();
324 	}
325 }
326 
327 // ------------------------------------------------------------------------
328 
329 // executes the function for the selected item
IMPL_LINK(SfxMenuManager,Select,Menu *,pSelMenu)330 IMPL_LINK( SfxMenuManager, Select, Menu *, pSelMenu )
331 {
332 	DBG_MEMTEST();
333 
334 	sal_uInt16 nId = (sal_uInt16) pSelMenu->GetCurItemId();
335 	String aCommand = pSelMenu->GetItemCommand( nId );
336     if ( !aCommand.Len() && pBindings )
337     {
338         const SfxSlot* pSlot = SfxSlotPool::GetSlotPool( pBindings->GetDispatcher()->GetFrame() ).GetSlot( nId );
339         if ( pSlot && pSlot->pUnoName )
340         {
341             aCommand = DEFINE_CONST_UNICODE(".uno:");
342             aCommand += String::CreateFromAscii( pSlot->GetUnoName() );
343         }
344     }
345 
346 	if ( aCommand.Len() )
347 	{
348 		pBindings->ExecuteCommand_Impl( aCommand );
349 	}
350 	else if ( pBindings->IsBound(nId) )
351 		// normal function
352 		pBindings->Execute( nId );
353 	else
354 		// special menu function
355 		pBindings->GetDispatcher_Impl()->Execute( nId );
356 
357 	return sal_True;
358 }
359 
360 //--------------------------------------------------------------------
361 
Construct_Impl(Menu * pSVMenu,sal_Bool bWithHelp)362 void SfxMenuManager::Construct_Impl( Menu* pSVMenu, sal_Bool bWithHelp )
363 {
364 	SfxVirtualMenu *pOldVirtMenu=0;
365 	if ( pMenu )
366 	{
367 		// Es wird umkonfiguriert
368 		pOldVirtMenu = pMenu;
369 		pBindings->ENTERREGISTRATIONS();
370 	}
371 
372 	TryToHideDisabledEntries_Impl( pSVMenu );
373     SfxVirtualMenu *pVMenu = new SfxVirtualMenu( pSVMenu, bWithHelp, *pBindings, sal_True );
374 	Construct(*pVMenu);
375 
376 	if ( pOldVirtMenu )
377 	{
378 		delete pOldVirtMenu;
379 		pBindings->LEAVEREGISTRATIONS();
380 	}
381 }
382 
383 //--------------------------------------------------------------------
384 
385 // don't insert Popups into ConfigManager, they are not configurable at the moment !
SfxPopupMenuManager(const ResId & rResId,SfxBindings & rBindings)386 SfxPopupMenuManager::SfxPopupMenuManager(const ResId& rResId, SfxBindings &rBindings )
387     : SfxMenuManager( rResId, rBindings )
388 	, pSVMenu( NULL )
389 {
390 	DBG_MEMTEST();
391 }
392 
~SfxPopupMenuManager()393 SfxPopupMenuManager::~SfxPopupMenuManager()
394 {
395 }
396 
397 //-------------------------------------------------------------------------
398 
RemoveDisabledEntries()399 void SfxPopupMenuManager::RemoveDisabledEntries()
400 {
401 	if ( pSVMenu )
402 		TryToHideDisabledEntries_Impl( pSVMenu );
403 }
404 
405 //--------------------------------------------------------------------
406 
Execute(const Point & rPos,Window * pWindow)407 sal_uInt16 SfxPopupMenuManager::Execute( const Point& rPos, Window* pWindow )
408 {
409 	DBG_MEMTEST();
410     sal_uInt16 nVal = ( (PopupMenu*) GetMenu()->GetSVMenu() )->Execute( pWindow, rPos );
411     delete pStaticThesSubMenu;  pStaticThesSubMenu = NULL;
412 	return nVal;
413 }
414 
415 //--------------------------------------------------------------------
416 
IMPL_LINK_INLINE_START(SfxPopupMenuManager,SelectHdl,void *,EMPTYARG)417 IMPL_LINK_INLINE_START( SfxPopupMenuManager, SelectHdl, void *, EMPTYARG )
418 {
419 	return 1;
420 }
IMPL_LINK_INLINE_END(SfxPopupMenuManager,SelectHdl,void *,EMPTYARG)421 IMPL_LINK_INLINE_END( SfxPopupMenuManager, SelectHdl, void *, EMPTYARG )
422 
423 
424 //--------------------------------------------------------------------
425 
426 sal_uInt16 SfxPopupMenuManager::Execute( const Point& rPoint, Window* pWindow, va_list pArgs, const SfxPoolItem *pArg1 )
427 {
428 	DBG_MEMTEST();
429 
430 	PopupMenu* pPopMenu = ( (PopupMenu*)GetMenu()->GetSVMenu() );
431 	pPopMenu->SetSelectHdl( LINK( this, SfxPopupMenuManager, SelectHdl ) );
432     sal_uInt16 nId = pPopMenu->Execute( pWindow, rPoint );
433 	pPopMenu->SetSelectHdl( Link() );
434 
435 	if ( nId )
436         GetBindings().GetDispatcher()->_Execute( nId, SFX_CALLMODE_RECORD, pArgs, pArg1 );
437 
438 	return nId;
439 }
440 
441 //--------------------------------------------------------------------
442 
Execute(const Point & rPoint,Window * pWindow,const SfxPoolItem * pArg1,...)443 sal_uInt16 SfxPopupMenuManager::Execute( const Point& rPoint, Window* pWindow, const SfxPoolItem *pArg1, ... )
444 {
445 	DBG_MEMTEST();
446 
447 	va_list pArgs;
448 	va_start(pArgs, pArg1);
449 
450     return (Execute( rPoint, pWindow, pArgs, pArg1 ));
451 }
452 
453 //-------------------------------------------------------------------------
454 
StartInsert()455 void SfxPopupMenuManager::StartInsert()
456 {
457 	ResId aResId(GetType(),*pResMgr);
458 	aResId.SetRT(RSC_MENU);
459 	pSVMenu = new PopupMenu( aResId );
460 	TryToHideDisabledEntries_Impl( pSVMenu );
461 }
462 
463 //-------------------------------------------------------------------------
464 
EndInsert()465 void SfxPopupMenuManager::EndInsert()
466 {
467 	pBindings->ENTERREGISTRATIONS();
468 	pMenu = new SfxVirtualMenu( pSVMenu, sal_False, *pBindings, sal_True, sal_True );
469 	Construct( *pMenu );
470 	pBindings->LEAVEREGISTRATIONS();
471 }
472 
473 //-------------------------------------------------------------------------
474 
InsertSeparator(sal_uInt16 nPos)475 void SfxPopupMenuManager::InsertSeparator( sal_uInt16 nPos )
476 {
477 	pSVMenu->InsertSeparator( nPos );
478 }
479 
480 //-------------------------------------------------------------------------
481 
InsertItem(sal_uInt16 nId,const String & rName,MenuItemBits nBits,const rtl::OString & rHelpId,sal_uInt16 nPos)482 void SfxPopupMenuManager::InsertItem( sal_uInt16 nId, const String& rName, MenuItemBits nBits, const rtl::OString& rHelpId, sal_uInt16 nPos )
483 {
484 	pSVMenu->InsertItem( nId, rName, nBits,nPos );
485 	pSVMenu->SetHelpId( nId, rHelpId );
486 }
487 
488 //-------------------------------------------------------------------------
489 
RemoveItem(sal_uInt16 nId)490 void SfxPopupMenuManager::RemoveItem( sal_uInt16 nId )
491 {
492 	pSVMenu->RemoveItem( nId );
493 }
494 
495 //-------------------------------------------------------------------------
496 
CheckItem(sal_uInt16 nId,sal_Bool bCheck)497 void SfxPopupMenuManager::CheckItem( sal_uInt16 nId, sal_Bool bCheck )
498 {
499 	pSVMenu->CheckItem( nId, bCheck );
500 }
501 
AddClipboardFunctions()502 void SfxPopupMenuManager::AddClipboardFunctions()
503 {
504 	bAddClipboardFuncs = sal_True;
505 }
506 
SfxMenuManager(Menu * pMenuArg,SfxBindings & rBindings)507 SfxMenuManager::SfxMenuManager( Menu* pMenuArg, SfxBindings &rBindings )
508 :   pMenu(0),
509     pOldMenu(0),
510     pBindings(&rBindings),
511     pResMgr(NULL),
512     nType(0)
513 {
514     bAddClipboardFuncs = sal_False;
515     SfxVirtualMenu* pVMenu = new SfxVirtualMenu( pMenuArg, sal_False, rBindings, sal_True, sal_True );
516     Construct(*pVMenu);
517 }
518 
SfxPopupMenuManager(PopupMenu * pMenuArg,SfxBindings & rBindings)519 SfxPopupMenuManager::SfxPopupMenuManager( PopupMenu* pMenuArg, SfxBindings& rBindings )
520     : SfxMenuManager( pMenuArg, rBindings )
521     , pSVMenu( pMenuArg )
522 {
523 }
524 
Popup(const ResId & rResId,SfxViewFrame * pFrame,const Point & rPoint,Window * pWindow)525 SfxPopupMenuManager* SfxPopupMenuManager::Popup( const ResId& rResId, SfxViewFrame* pFrame,const Point& rPoint, Window* pWindow )
526 {
527 	PopupMenu *pSVMenu = new PopupMenu( rResId );
528     sal_uInt16 n, nCount = pSVMenu->GetItemCount();
529     for ( n=0; n<nCount; n++ )
530     {
531         sal_uInt16 nId = pSVMenu->GetItemId( n );
532         if ( nId == SID_COPY || nId == SID_CUT || nId == SID_PASTE )
533             break;
534     }
535 
536     PopupMenu* pThesSubMenu = InsertThesaurusSubmenu_Impl( &pFrame->GetBindings(), pSVMenu );
537     // #i107205# (see comment in header file)
538     pStaticThesSubMenu = pThesSubMenu;
539 
540     if ( n == nCount )
541     {
542         PopupMenu aPop( SfxResId( MN_CLIPBOARDFUNCS ) );
543         nCount = aPop.GetItemCount();
544         pSVMenu->InsertSeparator();
545         for ( n=0; n<nCount; n++ )
546         {
547             sal_uInt16 nId = aPop.GetItemId( n );
548             pSVMenu->InsertItem( nId, aPop.GetItemText( nId ), aPop.GetItemBits( nId ) );
549             pSVMenu->SetHelpId( nId, aPop.GetHelpId( nId ));
550         }
551     }
552 
553     InsertVerbs_Impl( &pFrame->GetBindings(), pFrame->GetViewShell()->GetVerbs(), pSVMenu );
554     Menu* pMenu = NULL;
555     ::com::sun::star::ui::ContextMenuExecuteEvent aEvent;
556     aEvent.SourceWindow = VCLUnoHelper::GetInterface( pWindow );
557     aEvent.ExecutePosition.X = rPoint.X();
558     aEvent.ExecutePosition.Y = rPoint.Y();
559     ::rtl::OUString sDummyMenuName;
560     if ( pFrame->GetViewShell()->TryContextMenuInterception( *pSVMenu, sDummyMenuName, pMenu, aEvent ) )
561     {
562         if ( pMenu )
563         {
564             delete pSVMenu;
565             pSVMenu = (PopupMenu*) pMenu;
566         }
567 
568 		SfxPopupMenuManager* aMgr = new SfxPopupMenuManager( pSVMenu, pFrame->GetBindings());
569 		aMgr->RemoveDisabledEntries();
570 		return aMgr;
571     }
572 
573 	return 0;
574 }
575 
576 
ExecutePopup(const ResId & rResId,SfxViewFrame * pFrame,const Point & rPoint,Window * pWindow)577 void SfxPopupMenuManager::ExecutePopup( const ResId& rResId, SfxViewFrame* pFrame, const Point& rPoint, Window* pWindow )
578 {
579     PopupMenu *pSVMenu = new PopupMenu( rResId );
580     sal_uInt16 n, nCount = pSVMenu->GetItemCount();
581     for ( n=0; n<nCount; n++ )
582     {
583         sal_uInt16 nId = pSVMenu->GetItemId( n );
584         if ( nId == SID_COPY || nId == SID_CUT || nId == SID_PASTE )
585             break;
586     }
587 
588     PopupMenu* pThesSubMenu = InsertThesaurusSubmenu_Impl( &pFrame->GetBindings(), pSVMenu );
589 
590     if ( n == nCount )
591     {
592         PopupMenu aPop( SfxResId( MN_CLIPBOARDFUNCS ) );
593         nCount = aPop.GetItemCount();
594         pSVMenu->InsertSeparator();
595         for ( n=0; n<nCount; n++ )
596         {
597             sal_uInt16 nId = aPop.GetItemId( n );
598             pSVMenu->InsertItem( nId, aPop.GetItemText( nId ), aPop.GetItemBits( nId ) );
599             pSVMenu->SetHelpId( nId, aPop.GetHelpId( nId ));
600         }
601     }
602 
603     InsertVerbs_Impl( &pFrame->GetBindings(), pFrame->GetViewShell()->GetVerbs(), pSVMenu );
604     Menu* pMenu = NULL;
605     ::com::sun::star::ui::ContextMenuExecuteEvent aEvent;
606     aEvent.SourceWindow = VCLUnoHelper::GetInterface( pWindow );
607     aEvent.ExecutePosition.X = rPoint.X();
608     aEvent.ExecutePosition.Y = rPoint.Y();
609     ::rtl::OUString sDummyMenuName;
610     if ( pFrame->GetViewShell()->TryContextMenuInterception( *pSVMenu, sDummyMenuName, pMenu, aEvent ) )
611     {
612         if ( pMenu )
613         {
614             delete pSVMenu;
615             pSVMenu = (PopupMenu*) pMenu;
616         }
617 
618 		SfxPopupMenuManager aPop( pSVMenu, pFrame->GetBindings() );
619 		aPop.RemoveDisabledEntries();
620 		aPop.Execute( rPoint, pWindow );
621 
622         // #i112646 avoid crash when context menu is closed.
623         // the (manually inserted) sub-menu needs to be destroyed before
624         // aPop gets destroyed.
625         delete pThesSubMenu;
626         pThesSubMenu = 0;
627     }
628 
629     delete pThesSubMenu;
630 }
631 
GetSVMenu()632 Menu* SfxPopupMenuManager::GetSVMenu()
633 {
634 	return (Menu*) GetMenu()->GetSVMenu();
635 }
636 
637