1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: mnumgr.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sfx2.hxx"
33 #include <com/sun/star/embed/VerbDescriptor.hpp>
34 #include <com/sun/star/embed/VerbAttributes.hpp>
37 // HACK: prevent conflict between STLPORT and Workshop headers on Solaris 8
41 #include <string> // HACK: prevent conflict between STLPORT and Workshop headers
42 #include <cstdarg> // std::va_list
44 #ifndef _POINTR_HXX //autogen
45 #include <vcl/pointr.hxx>
50 #include <unotools/streamwrap.hxx>
51 #include <sfx2/objsh.hxx>
52 #include <framework/menuconfiguration.hxx>
53 #include <framework/addonmenu.hxx>
54 #include <comphelper/processfactory.hxx>
55 #include <unotools/ucbstreamhelper.hxx>
56 #include <tools/urlobj.hxx>
57 #include <svtools/pathoptions.hxx>
58 #include <toolkit/helper/vclunohelper.hxx>
60 #include <sfx2/mnumgr.hxx>
62 #define _SVSTDARR_USHORTS
63 #include <svtools/svstdarr.hxx>
64 #include <svtools/menuoptions.hxx>
66 #include "virtmenu.hxx"
67 #include <sfx2/msg.hxx>
68 #include <sfx2/dispatch.hxx>
69 #include <sfx2/minstack.hxx>
70 #include <sfx2/app.hxx>
71 #include "sfxtypes.hxx"
72 #include <sfx2/bindings.hxx>
73 #include "mnucfga.hxx"
74 #include "sfxresid.hxx"
75 #include <sfx2/macrconf.hxx>
76 #include <sfx2/msgpool.hxx>
77 #include <sfx2/sfx.hrc>
79 #include <sfx2/viewfrm.hxx>
80 #include <sfx2/viewsh.hxx>
81 #include <sfx2/objface.hxx>
83 static const USHORT nCompatVersion
= 4;
84 static const USHORT nVersion
= 5;
86 using namespace com::sun::star
;
88 //=========================================================================
90 DECL_PTRSTACK(SfxMenuCfgItemArrStack
, SfxMenuCfgItemArr
*, 4, 4 );
92 //-------------------------------------------------------------------------
94 void TryToHideDisabledEntries_Impl( Menu
* pMenu
)
96 DBG_ASSERT( pMenu
, "invalid menu" );
97 if( SvtMenuOptions().IsEntryHidingEnabled() == sal_False
)
99 pMenu
->SetMenuFlags( pMenu
->GetMenuFlags() | MENU_FLAG_HIDEDISABLEDENTRIES
);
103 //-------------------------------------------------------------------------
105 SfxMenuManager::SfxMenuManager( const ResId
& rResId
, SfxBindings
&rBindings
)
108 pBindings(&rBindings
),
109 pResMgr(rResId
.GetResMgr()),
110 nType( rResId
.GetId() )
112 bAddClipboardFuncs
= FALSE
;
116 //--------------------------------------------------------------------
118 SfxMenuManager::~SfxMenuManager()
121 pBindings
->ENTERREGISTRATIONS();
123 pBindings
->LEAVEREGISTRATIONS();
126 //--------------------------------------------------------------------
128 void SfxMenuManager::Construct( SfxVirtualMenu
& rMenu
)
134 Menu
*pSvMenu
= pMenu
->GetSVMenu();
135 pSvMenu
->SetSelectHdl( LINK(this, SfxMenuManager
, Select
) );
136 TryToHideDisabledEntries_Impl( pSvMenu
);
139 //-------------------------------------------------------------------------
140 void InsertVerbs_Impl( SfxBindings
* pBindings
, const com::sun::star::uno::Sequence
< com::sun::star::embed::VerbDescriptor
>& aVerbs
, Menu
* pMenu
)
142 SfxViewShell
*pView
= pBindings
->GetDispatcher()->GetFrame()->GetViewShell();
143 if ( pView
&& aVerbs
.getLength() )
145 SfxObjectShell
* pDoc
= pView
->GetObjectShell();
146 pMenu
->InsertSeparator();
148 for ( USHORT n
= 0; n
< aVerbs
.getLength(); ++n
)
150 // check for ReadOnly verbs
151 if ( pDoc
->IsReadOnly() && !(aVerbs
[n
].VerbAttributes
& embed::VerbAttributes::MS_VERBATTR_NEVERDIRTIES
) )
154 // check for verbs that shouldn't appear in the menu
155 if ( !(aVerbs
[n
].VerbAttributes
& embed::VerbAttributes::MS_VERBATTR_ONCONTAINERMENU
) )
159 USHORT nId
= SID_VERB_START
+ nr
++;
160 DBG_ASSERT(nId
<= SID_VERB_END
, "Zuviele Verben!");
161 if ( nId
> SID_VERB_END
)
165 pMenu
->InsertItem( nId
, aVerbs
[n
].VerbName
);
166 pMenu
->SetHelpId( nId
, (ULONG
) nId
);
173 //--------------------------------------------------------------------
175 void SfxMenuManager::UseDefault()
180 SfxVirtualMenu
*pOldVirtMenu
=0;
183 pOldVirtMenu
= pMenu
;
184 pBindings
->ENTERREGISTRATIONS();
187 SfxVirtualMenu
*pVMenu
= 0;
189 ResId
aResId(GetType(),*pResMgr
);
190 aResId
.SetRT(RSC_MENU
);
191 Menu
*pSVMenu
= new PopupMenu( aResId
);
192 //SfxMenuManager::EraseItemCmds( pSVMenu ); // Remove .uno cmds to be compatible with 6.0/src641
194 if ( bAddClipboardFuncs
)
196 USHORT n
, nCount
= pSVMenu
->GetItemCount();
197 for ( n
=0; n
<nCount
; n
++ )
199 USHORT nId
= pSVMenu
->GetItemId( n
);
200 if ( nId
== SID_COPY
|| nId
== SID_CUT
|| nId
== SID_PASTE
)
206 PopupMenu
aPop( SfxResId( MN_CLIPBOARDFUNCS
) );
207 nCount
= aPop
.GetItemCount();
208 pSVMenu
->InsertSeparator();
209 for ( n
=0; n
<nCount
; n
++ )
211 USHORT nId
= aPop
.GetItemId( n
);
212 pSVMenu
->InsertItem( nId
, aPop
.GetItemText( nId
), aPop
.GetItemBits( nId
) );
217 pVMenu
= new SfxVirtualMenu( pSVMenu
, FALSE
, *pBindings
, TRUE
, TRUE
);
224 pBindings
->LEAVEREGISTRATIONS();
228 // ------------------------------------------------------------------------
230 // executes the function for the selected item
231 IMPL_LINK( SfxMenuManager
, Select
, Menu
*, pSelMenu
)
235 USHORT nId
= (USHORT
) pSelMenu
->GetCurItemId();
236 String aCommand
= pSelMenu
->GetItemCommand( nId
);
237 if ( !aCommand
.Len() && pBindings
)
239 const SfxSlot
* pSlot
= SfxSlotPool::GetSlotPool( pBindings
->GetDispatcher()->GetFrame() ).GetSlot( nId
);
240 if ( pSlot
&& pSlot
->pUnoName
)
242 aCommand
= DEFINE_CONST_UNICODE(".uno:");
243 aCommand
+= String::CreateFromAscii( pSlot
->GetUnoName() );
247 if ( aCommand
.Len() )
249 pBindings
->ExecuteCommand_Impl( aCommand
);
251 else if ( pBindings
->IsBound(nId
) )
253 pBindings
->Execute( nId
);
255 // special menu function
256 pBindings
->GetDispatcher_Impl()->Execute( nId
);
261 //--------------------------------------------------------------------
263 void SfxMenuManager::Construct_Impl( Menu
* pSVMenu
, BOOL bWithHelp
)
265 SfxVirtualMenu
*pOldVirtMenu
=0;
268 // Es wird umkonfiguriert
269 pOldVirtMenu
= pMenu
;
270 pBindings
->ENTERREGISTRATIONS();
273 TryToHideDisabledEntries_Impl( pSVMenu
);
274 SfxVirtualMenu
*pVMenu
= new SfxVirtualMenu( pSVMenu
, bWithHelp
, *pBindings
, TRUE
);
280 pBindings
->LEAVEREGISTRATIONS();
284 //--------------------------------------------------------------------
286 // don't insert Popups into ConfigManager, they are not configurable at the moment !
287 SfxPopupMenuManager::SfxPopupMenuManager(const ResId
& rResId
, SfxBindings
&rBindings
)
288 : SfxMenuManager( rResId
, rBindings
)
294 SfxPopupMenuManager::~SfxPopupMenuManager()
298 //-------------------------------------------------------------------------
300 void SfxPopupMenuManager::RemoveDisabledEntries()
303 TryToHideDisabledEntries_Impl( pSVMenu
);
306 //--------------------------------------------------------------------
308 USHORT
SfxPopupMenuManager::Execute( const Point
& rPos
, Window
* pWindow
)
311 return ( (PopupMenu
*) GetMenu()->GetSVMenu() )->Execute( pWindow
, rPos
);
314 //--------------------------------------------------------------------
316 IMPL_LINK_INLINE_START( SfxPopupMenuManager
, SelectHdl
, void *, EMPTYARG
)
320 IMPL_LINK_INLINE_END( SfxPopupMenuManager
, SelectHdl
, void *, EMPTYARG
)
323 //--------------------------------------------------------------------
325 USHORT
SfxPopupMenuManager::Execute( const Point
& rPoint
, Window
* pWindow
, va_list pArgs
, const SfxPoolItem
*pArg1
)
329 PopupMenu
* pPopMenu
= ( (PopupMenu
*)GetMenu()->GetSVMenu() );
330 pPopMenu
->SetSelectHdl( LINK( this, SfxPopupMenuManager
, SelectHdl
) );
331 USHORT nId
= pPopMenu
->Execute( pWindow
, rPoint
);
332 pPopMenu
->SetSelectHdl( Link() );
335 GetBindings().GetDispatcher()->_Execute( nId
, SFX_CALLMODE_RECORD
, pArgs
, pArg1
);
340 //--------------------------------------------------------------------
342 USHORT
SfxPopupMenuManager::Execute( const Point
& rPoint
, Window
* pWindow
, const SfxPoolItem
*pArg1
, ... )
347 va_start(pArgs
, pArg1
);
349 return (Execute( rPoint
, pWindow
, pArgs
, pArg1
));
352 //-------------------------------------------------------------------------
354 void SfxPopupMenuManager::StartInsert()
356 ResId
aResId(GetType(),*pResMgr
);
357 aResId
.SetRT(RSC_MENU
);
358 pSVMenu
= new PopupMenu( aResId
);
359 TryToHideDisabledEntries_Impl( pSVMenu
);
362 //-------------------------------------------------------------------------
364 void SfxPopupMenuManager::EndInsert()
366 pBindings
->ENTERREGISTRATIONS();
367 pMenu
= new SfxVirtualMenu( pSVMenu
, FALSE
, *pBindings
, TRUE
, TRUE
);
369 pBindings
->LEAVEREGISTRATIONS();
372 //-------------------------------------------------------------------------
374 void SfxPopupMenuManager::InsertSeparator( USHORT nPos
)
376 pSVMenu
->InsertSeparator( nPos
);
379 //-------------------------------------------------------------------------
381 void SfxPopupMenuManager::InsertItem( USHORT nId
, const String
& rName
, MenuItemBits nBits
, USHORT nPos
)
383 pSVMenu
->InsertItem( nId
, rName
, nBits
,nPos
);
384 pSVMenu
->SetHelpId( nId
, (ULONG
) nId
);
387 //-------------------------------------------------------------------------
389 void SfxPopupMenuManager::RemoveItem( USHORT nId
)
391 pSVMenu
->RemoveItem( nId
);
394 //-------------------------------------------------------------------------
396 void SfxPopupMenuManager::CheckItem( USHORT nId
, BOOL bCheck
)
398 pSVMenu
->CheckItem( nId
, bCheck
);
401 void SfxPopupMenuManager::AddClipboardFunctions()
403 bAddClipboardFuncs
= TRUE
;
406 SfxMenuManager::SfxMenuManager( Menu
* pMenuArg
, SfxBindings
&rBindings
)
409 pBindings(&rBindings
),
413 bAddClipboardFuncs
= FALSE
;
414 SfxVirtualMenu
* pVMenu
= new SfxVirtualMenu( pMenuArg
, FALSE
, rBindings
, TRUE
, TRUE
);
418 SfxPopupMenuManager::SfxPopupMenuManager( PopupMenu
* pMenuArg
, SfxBindings
& rBindings
)
419 : SfxMenuManager( pMenuArg
, rBindings
)
420 , pSVMenu( pMenuArg
)
424 SfxPopupMenuManager
* SfxPopupMenuManager::Popup( const ResId
& rResId
, SfxViewFrame
* pFrame
,const Point
& rPoint
, Window
* pWindow
)
426 PopupMenu
*pSVMenu
= new PopupMenu( rResId
);
427 USHORT n
, nCount
= pSVMenu
->GetItemCount();
428 for ( n
=0; n
<nCount
; n
++ )
430 USHORT nId
= pSVMenu
->GetItemId( n
);
431 if ( nId
== SID_COPY
|| nId
== SID_CUT
|| nId
== SID_PASTE
)
437 PopupMenu
aPop( SfxResId( MN_CLIPBOARDFUNCS
) );
438 nCount
= aPop
.GetItemCount();
439 pSVMenu
->InsertSeparator();
440 for ( n
=0; n
<nCount
; n
++ )
442 USHORT nId
= aPop
.GetItemId( n
);
443 pSVMenu
->InsertItem( nId
, aPop
.GetItemText( nId
), aPop
.GetItemBits( nId
) );
444 pSVMenu
->SetHelpId( nId
, aPop
.GetHelpId( nId
));
448 InsertVerbs_Impl( &pFrame
->GetBindings(), pFrame
->GetViewShell()->GetVerbs(), pSVMenu
);
450 ::com::sun::star::ui::ContextMenuExecuteEvent aEvent
;
451 aEvent
.SourceWindow
= VCLUnoHelper::GetInterface( pWindow
);
452 aEvent
.ExecutePosition
.X
= rPoint
.X();
453 aEvent
.ExecutePosition
.Y
= rPoint
.Y();
454 ::rtl::OUString sDummyMenuName
;
455 if ( pFrame
->GetViewShell()->TryContextMenuInterception( *pSVMenu
, sDummyMenuName
, pMenu
, aEvent
) )
460 pSVMenu
= (PopupMenu
*) pMenu
;
463 SfxPopupMenuManager
* aMgr
= new SfxPopupMenuManager( pSVMenu
, pFrame
->GetBindings());
464 aMgr
->RemoveDisabledEntries();
470 void SfxPopupMenuManager::ExecutePopup( const ResId
& rResId
, SfxViewFrame
* pFrame
, const Point
& rPoint
, Window
* pWindow
)
472 PopupMenu
*pSVMenu
= new PopupMenu( rResId
);
473 USHORT n
, nCount
= pSVMenu
->GetItemCount();
474 for ( n
=0; n
<nCount
; n
++ )
476 USHORT nId
= pSVMenu
->GetItemId( n
);
477 if ( nId
== SID_COPY
|| nId
== SID_CUT
|| nId
== SID_PASTE
)
483 PopupMenu
aPop( SfxResId( MN_CLIPBOARDFUNCS
) );
484 nCount
= aPop
.GetItemCount();
485 pSVMenu
->InsertSeparator();
486 for ( n
=0; n
<nCount
; n
++ )
488 USHORT nId
= aPop
.GetItemId( n
);
489 pSVMenu
->InsertItem( nId
, aPop
.GetItemText( nId
), aPop
.GetItemBits( nId
) );
490 pSVMenu
->SetHelpId( nId
, aPop
.GetHelpId( nId
));
494 InsertVerbs_Impl( &pFrame
->GetBindings(), pFrame
->GetViewShell()->GetVerbs(), pSVMenu
);
496 ::com::sun::star::ui::ContextMenuExecuteEvent aEvent
;
497 aEvent
.SourceWindow
= VCLUnoHelper::GetInterface( pWindow
);
498 aEvent
.ExecutePosition
.X
= rPoint
.X();
499 aEvent
.ExecutePosition
.Y
= rPoint
.Y();
500 ::rtl::OUString sDummyMenuName
;
501 if ( pFrame
->GetViewShell()->TryContextMenuInterception( *pSVMenu
, sDummyMenuName
, pMenu
, aEvent
) )
506 pSVMenu
= (PopupMenu
*) pMenu
;
509 SfxPopupMenuManager
aPop( pSVMenu
, pFrame
->GetBindings() );
510 aPop
.RemoveDisabledEntries();
511 aPop
.Execute( rPoint
, pWindow
);
515 Menu
* SfxPopupMenuManager::GetSVMenu()
517 return (Menu
*) GetMenu()->GetSVMenu();