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: mnuitem.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"
35 // HACK: prevent conflict between STLPORT and Workshop headers on Solaris 8
39 #include <string> // HACK: prevent conflict between STLPORT and Workshop includes
40 #include <com/sun/star/uno/Reference.h>
41 #include <com/sun/star/frame/XDispatch.hpp>
42 #include <com/sun/star/frame/XDispatchProvider.hpp>
43 #include <com/sun/star/frame/XFrame.hpp>
44 #include <com/sun/star/util/URL.hpp>
45 #include <com/sun/star/beans/PropertyValue.hpp>
46 #ifndef _UNOTOOLS_PROCESSFACTORY_HXX
47 #include <comphelper/processfactory.hxx>
49 #include <com/sun/star/util/XURLTransformer.hpp>
50 #ifndef _UNOTOOLS_PROCESSFACTORY_HXX
51 #include <comphelper/processfactory.hxx>
53 #include <tools/urlobj.hxx>
54 #include <svtools/eitem.hxx>
55 #include <svtools/stritem.hxx>
56 #include <svtools/imagemgr.hxx>
57 #include <svtools/menuoptions.hxx>
58 #include <framework/menuconfiguration.hxx>
62 #include <sfx2/app.hxx>
63 #include <sfx2/sfx.hrc>
64 #include <sfx2/msgpool.hxx>
65 #include <sfx2/msg.hxx>
66 #include <sfx2/bindings.hxx>
67 #include <sfx2/dispatch.hxx>
69 #include "sfxtypes.hxx"
70 #include <sfx2/macrconf.hxx>
71 #include "virtmenu.hxx"
72 #include <sfx2/mnuitem.hxx>
73 #include <sfx2/tbxctrl.hxx>
74 #include "arrdecl.hxx"
75 #include <sfx2/module.hxx>
76 #include <sfx2/unoctitm.hxx>
77 #include <sfx2/viewfrm.hxx>
79 #include "imagemgr.hxx"
80 #include "sfxresid.hxx"
81 #include "../doc/doc.hrc"
83 using namespace ::com::sun::star::uno
;
84 using namespace ::com::sun::star::frame
;
85 using namespace ::com::sun::star::beans
;
86 using namespace ::com::sun::star::util
;
88 //====================================================================
90 class SfxEnumMenu
: public PopupMenu
94 SfxBindings
* pBindings
;
97 virtual void Select();
100 SfxEnumMenu( USHORT nSlot
, SfxBindings
* pBind
, const SfxEnumItem
&rItem
);
104 //=========================================================================
106 SfxEnumMenu::SfxEnumMenu( USHORT nSlotId
, SfxBindings
* pBind
, const SfxEnumItem
&rItem
):
108 pItem( (SfxEnumItem
*) rItem
.Clone() ),
111 for ( USHORT nVal
= 0; nVal
< pItem
->GetValueCount(); ++nVal
)
112 InsertItem( nVal
+1, pItem
->GetValueTextByPos(nVal
) );
113 CheckItem( pItem
->GetValue() + 1, TRUE
);
116 //-------------------------------------------------------------------------
118 SfxEnumMenu::~SfxEnumMenu()
123 //-------------------------------------------------------------------------
125 void SfxEnumMenu::Select()
127 pItem
->SetValue( GetCurItemId()-1 );
128 pBindings
->GetDispatcher()->Execute( nSlot
,
129 SFX_CALLMODE_ASYNCHRON
|SFX_CALLMODE_RECORD
,
133 //--------------------------------------------------------------------
135 void SfxMenuControl::SetOwnMenu( SfxVirtualMenu
* pMenu
)
139 pSubMenu
->SetParentMenu( pMenu
);
143 //--------------------------------------------------------------------
145 // binds the instance to the specified id and assignes the title
147 void SfxMenuControl::Bind(
148 SfxVirtualMenu
* pOwn
,
150 const String
& rTitle
,
151 const String
&rHelpText
,
152 SfxBindings
&rBindings
)
157 aHelpText
= rHelpText
;
161 SfxControllerItem::Bind(nSlotId
, &rBindings
);
165 DBG( CheckConfigure_Impl(SFX_SLOT_MENUCONFIG
) );
169 //--------------------------------------------------------------------
171 // binds the item to the specified menu and assignes the title
173 void SfxMenuControl::Bind(
174 SfxVirtualMenu
* pOwn
,
176 SfxVirtualMenu
& rMenu
,
177 const String
& rTitle
,
178 const String
&rHelpText
,
179 SfxBindings
&rBindings
)
183 SetBindings(rBindings
);
187 aHelpText
= rHelpText
;
190 //--------------------------------------------------------------------
192 // ctor for explicit registration
194 SfxMenuControl::SfxMenuControl( BOOL bShowStrings
)
197 b_ShowStrings(bShowStrings
)
202 //--------------------------------------------------------------------
206 SfxMenuControl::SfxMenuControl():
214 //--------------------------------------------------------------------
216 SfxMenuControl::SfxMenuControl(USHORT nSlotId
, SfxBindings
& rBindings
):
217 SfxControllerItem(nSlotId
, rBindings
),
224 // Dieser Ctor soll es erm"oglichen, w"ahrend der Konstruktion schon
225 // auf die Bindings zur"uckgreifen zu k"onnen, aber gebunden wird
226 // wie immer erst sp"ater. Anwendung z.B. wenn im ctor der abgeleiteten
227 // Klasse z.B. ein StatusForwarder erzeugt werden soll.
232 //--------------------------------------------------------------------
236 SfxMenuControl::~SfxMenuControl()
238 if ( SfxMacroConfig::IsMacroSlot( GetId() ) )
239 SFX_APP()->GetMacroConfig()->ReleaseSlotId(GetId());
243 void SfxMenuControl::RemovePopup()
248 //--------------------------------------------------------------------
250 // changes the state in the virtual menu
252 void SfxMenuControl::StateChanged
256 const SfxPoolItem
* pState
261 DBG_ASSERT( nSID
== GetId(), "strange SID" );
262 DBG_ASSERT( pOwnMenu
!= 0, "setting state to dangling SfxMenuControl" );
264 FASTBOOL bIsObjMenu
=
265 GetId() >= SID_OBJECTMENU0
&& GetId() < SID_OBJECTMENU_LAST
;
267 // enabled/disabled-Flag pauschal korrigieren
270 if (nSID
== SID_PASTE
)
271 pOwnMenu
->EnableItem( GetId(), TRUE
);
274 pOwnMenu
->EnableItem( GetId(), bIsObjMenu
275 ? 0 != pOwnMenu
->GetSVMenu()->GetPopupMenu( GetId() )
276 : eState
!= SFX_ITEM_DISABLED
);
278 if ( eState
!= SFX_ITEM_AVAILABLE
)
280 // checken nur bei nicht-Object-Menus
282 pOwnMenu
->CheckItem( GetId(), FALSE
);
284 // SetItemText flackert in MenuBar insbes. unter OS/2 (Bug #20658)
285 if ( // !bIsObjMenu && nicht wegen "Format/Datenbank"
286 pOwnMenu
->GetSVMenu()->GetItemText( GetId() ) != GetTitle() )
288 DBG_WARNING("Title of menu item changed - please check if this needs correction!");
289 // pOwnMenu->SetItemText( GetId(), GetTitle() );
294 // ggf. das alte Enum-Menu entfernen/loeschen
295 //! delete pOwnMenu->GetMenu().ChangePopupMenu( GetId(), 0 );
298 if ( pState
->ISA(SfxBoolItem
) )
300 // BoolItem fuer checken
301 DBG_ASSERT( GetId() < SID_OBJECTMENU0
|| GetId() > SID_OBJECTMENU_LAST
,
302 "SfxBoolItem not allowed for SID_OBJECTMENUx" );
303 bCheck
= ((const SfxBoolItem
*)pState
)->GetValue();
305 else if ( pState
->ISA(SfxEnumItemInterface
) &&
306 ((SfxEnumItemInterface
*)pState
)->HasBoolValue() )
308 // EnumItem wie Bool behandeln
309 DBG_ASSERT( GetId() < SID_OBJECTMENU0
|| GetId() > SID_OBJECTMENU_LAST
,
310 "SfxEnumItem not allowed for SID_OBJECTMENUx" );
311 bCheck
= ((SfxEnumItemInterface
*)pState
)->GetBoolValue();
313 else if ( ( b_ShowStrings
|| bIsObjMenu
) && pState
->ISA(SfxStringItem
) )
315 // MenuText aus SfxStringItem holen
316 String
aStr( ((const SfxStringItem
*)pState
)->GetValue() );
317 if ( aStr
.CompareToAscii("($1)",4) == COMPARE_EQUAL
)
319 String
aEntry(SfxResId(STR_UPDATEDOC
));
321 aEntry
+= aStr
.Copy(4);
324 else if ( aStr
.CompareToAscii("($2)",4) == COMPARE_EQUAL
)
326 String
aEntry(SfxResId(STR_CLOSEDOC_ANDRETURN
));
327 aEntry
+= aStr
.Copy(4);
331 pOwnMenu
->SetItemText( GetId(), aStr
);
334 #ifdef enum_item_menu_ok
335 else if ( aType
== TYPE(SfxEnumItem
) )
337 DBG_ASSERT( GetId() < SID_OBJECTMENU0
|| GetId() > SID_OBJECTMENU_LAST
,
338 "SfxEnumItem not allowed for SID_OBJECTMENUx" );
339 pOwnMenu
->GetMenu().ChangePopupMenu( GetId(), &GetBindings(),
340 new SfxEnumMenu( GetId(), *(const SfxEnumItem
*)pState
) );
344 pOwnMenu
->CheckItem( GetId(), bCheck
);
347 //--------------------------------------------------------------------
349 SfxMenuControl
* SfxMenuControl::CreateImpl( USHORT
/*nId*/, Menu
& /*rMenu*/, SfxBindings
& /*rBindings*/ )
351 return new SfxMenuControl( TRUE
);
354 //--------------------------------------------------------------------
356 void SfxMenuControl::RegisterControl( USHORT nSlotId
, SfxModule
*pMod
)
358 RegisterMenuControl( pMod
, new SfxMenuCtrlFactory(
359 SfxMenuControl::CreateImpl
, TYPE(SfxStringItem
), nSlotId
) );
362 //--------------------------------------------------------------------
363 void SfxMenuControl::RegisterMenuControl(SfxModule
* pMod
, SfxMenuCtrlFactory
* pFact
)
365 SFX_APP()->RegisterMenuControl_Impl( pMod
, pFact
);
368 SfxMenuControl
* SfxMenuControl::CreateControl( USHORT nId
, Menu
&rMenu
, SfxBindings
&rBindings
)
370 TypeId aSlotType
= SFX_SLOTPOOL().GetSlotType(nId
);
373 SfxApplication
*pApp
= SFX_APP();
374 SfxDispatcher
*pDisp
= rBindings
.GetDispatcher_Impl();
375 SfxModule
*pMod
= pDisp
? SfxModule::GetActiveModule( pDisp
->GetFrame() ) :0;
378 SfxMenuCtrlFactArr_Impl
*pFactories
= pMod
->GetMenuCtrlFactories_Impl();
381 SfxMenuCtrlFactArr_Impl
&rFactories
= *pFactories
;
382 for ( USHORT nFactory
= 0; nFactory
< rFactories
.Count(); ++nFactory
)
383 if ( rFactories
[nFactory
]->nTypeId
== aSlotType
&&
384 ( ( rFactories
[nFactory
]->nSlotId
== 0 ) ||
385 ( rFactories
[nFactory
]->nSlotId
== nId
) ) )
386 return rFactories
[nFactory
]->pCtor( nId
, rMenu
, rBindings
);
390 SfxMenuCtrlFactArr_Impl
&rFactories
= pApp
->GetMenuCtrlFactories_Impl();
392 for ( USHORT nFactory
= 0; nFactory
< rFactories
.Count(); ++nFactory
)
393 if ( rFactories
[nFactory
]->nTypeId
== aSlotType
&&
394 ( ( rFactories
[nFactory
]->nSlotId
== 0 ) ||
395 ( rFactories
[nFactory
]->nSlotId
== nId
) ) )
396 return rFactories
[nFactory
]->pCtor( nId
, rMenu
, rBindings
);
401 BOOL
SfxMenuControl::IsSpecialControl( USHORT nId
, SfxModule
* pMod
)
403 TypeId aSlotType
= SFX_SLOTPOOL().GetSlotType( nId
);
408 SfxMenuCtrlFactArr_Impl
*pFactories
= pMod
->GetMenuCtrlFactories_Impl();
411 SfxMenuCtrlFactArr_Impl
&rFactories
= *pFactories
;
412 for ( USHORT nFactory
= 0; nFactory
< rFactories
.Count(); ++nFactory
)
413 if ( rFactories
[nFactory
]->nTypeId
== aSlotType
&&
414 ( ( rFactories
[nFactory
]->nSlotId
== 0 ) ||
415 ( rFactories
[nFactory
]->nSlotId
== nId
) ) )
420 SfxMenuCtrlFactArr_Impl
&rFactories
= SFX_APP()->GetMenuCtrlFactories_Impl();
422 for ( USHORT nFactory
= 0; nFactory
< rFactories
.Count(); ++nFactory
)
423 if ( rFactories
[nFactory
]->nTypeId
== aSlotType
&&
424 ( ( rFactories
[nFactory
]->nSlotId
== 0 ) ||
425 ( rFactories
[nFactory
]->nSlotId
== nId
) ) )
431 //--------------------------------------------------------------------
433 PopupMenu
* SfxMenuControl::GetPopup () const
436 return (PopupMenu
*)GetPopupMenu()->GetSVMenu();
441 long Select_Impl( void* pHdl
, void* pVoid
);
443 SFX_IMPL_MENU_CONTROL( SfxAppMenuControl_Impl
, SfxStringItem
);
445 SfxAppMenuControl_Impl::SfxAppMenuControl_Impl(
446 USHORT nPos
, Menu
& rMenu
, SfxBindings
& rBindings
)
447 : SfxMenuControl( nPos
, rBindings
), pMenu(0)
449 String aText
= rMenu
.GetItemText( nPos
);
451 // Determine the current background color setting for menus
452 const StyleSettings
& rSettings
= Application::GetSettings().GetStyleSettings();
453 m_nSymbolsStyle
= rSettings
.GetSymbolsStyle();
454 m_bWasHiContrastMode
= rSettings
.GetMenuColor().IsDark();
455 m_bShowMenuImages
= rSettings
.GetUseImagesInMenus();
457 Reference
<com::sun::star::lang::XMultiServiceFactory
> aXMultiServiceFactory(::comphelper::getProcessServiceFactory());
458 ::framework::MenuConfiguration
aConf( aXMultiServiceFactory
);
459 Reference
<com::sun::star::frame::XFrame
> aXFrame( GetBindings().GetDispatcher_Impl()->GetFrame()->GetFrame()->GetFrameInterface() );
460 pMenu
= aConf
.CreateBookmarkMenu( aXFrame
, GetId() == SID_NEWDOCDIRECT
? BOOKMARK_NEWMENU
: BOOKMARK_WIZARDMENU
);
463 pMenu
->SetSelectHdl( Link( &(this->GetBindings()), Select_Impl
) );
464 pMenu
->SetActivateHdl( LINK(this, SfxAppMenuControl_Impl
, Activate
) );
465 rMenu
.SetPopupMenu( nPos
, pMenu
);
469 SfxAppMenuControl_Impl::~SfxAppMenuControl_Impl()
474 IMPL_LINK( SfxAppMenuControl_Impl
, Activate
, Menu
*, pActMenu
)
478 const StyleSettings
& rSettings
= Application::GetSettings().GetStyleSettings();
479 ULONG nSymbolsStyle
= rSettings
.GetSymbolsStyle();
480 BOOL bIsHiContrastMode
= rSettings
.GetMenuColor().IsDark();
481 BOOL bShowMenuImages
= rSettings
.GetUseImagesInMenus();
483 if (( nSymbolsStyle
!= m_nSymbolsStyle
) ||
484 ( bIsHiContrastMode
!= m_bWasHiContrastMode
) ||
485 ( bShowMenuImages
!= m_bShowMenuImages
))
487 m_nSymbolsStyle
= nSymbolsStyle
;
488 m_bWasHiContrastMode
= bIsHiContrastMode
;
489 m_bShowMenuImages
= bShowMenuImages
;
491 USHORT nCount
= pActMenu
->GetItemCount();
492 for ( USHORT nSVPos
= 0; nSVPos
< nCount
; nSVPos
++ )
494 USHORT nItemId
= pActMenu
->GetItemId( nSVPos
);
495 if ( pActMenu
->GetItemType( nSVPos
) != MENUITEM_SEPARATOR
)
497 if ( bShowMenuImages
)
499 sal_Bool bImageSet
= sal_False
;
500 ::rtl::OUString aImageId
;
501 ::framework::MenuConfiguration::Attributes
* pMenuAttributes
=
502 (::framework::MenuConfiguration::Attributes
*)pMenu
->GetUserValue( nItemId
);
504 if ( pMenuAttributes
)
505 aImageId
= pMenuAttributes
->aImageId
; // Retrieve image id from menu attributes
507 if ( aImageId
.getLength() > 0 )
509 Reference
< ::com::sun::star::frame::XFrame
> xFrame
;
510 Image aImage
= GetImage( xFrame
, aImageId
, FALSE
, bIsHiContrastMode
);
513 bImageSet
= sal_True
;
514 pActMenu
->SetItemImage( nItemId
, aImage
);
518 String
aCmd( pActMenu
->GetItemCommand( nItemId
) );
519 if ( !bImageSet
&& aCmd
.Len() )
521 Image aImage
= SvFileInformationManager::GetImage(
522 INetURLObject(aCmd
), FALSE
, bIsHiContrastMode
);
524 pActMenu
->SetItemImage( nItemId
, aImage
);
528 pActMenu
->SetItemImage( nItemId
, Image() );
539 SfxUnoMenuControl
* SfxMenuControl::CreateControl( const String
& rCmd
,
540 USHORT nId
, Menu
& rMenu
, SfxBindings
&rBindings
, SfxVirtualMenu
* pVirt
)
542 return new SfxUnoMenuControl( rCmd
, nId
, rMenu
, rBindings
, pVirt
);
545 SfxUnoMenuControl::SfxUnoMenuControl( const String
& rCmd
, USHORT nSlotId
,
546 Menu
& rMenu
, SfxBindings
& rBindings
, SfxVirtualMenu
* pVirt
)
547 : SfxMenuControl( nSlotId
, rBindings
)
549 Bind( pVirt
, nSlotId
, rMenu
.GetItemText(nSlotId
),
550 rMenu
.GetHelpText(nSlotId
), rBindings
);
552 pUnoCtrl
= new SfxUnoControllerItem( this, rBindings
, rCmd
);
554 pUnoCtrl
->GetNewDispatch();
557 SfxUnoMenuControl::~SfxUnoMenuControl()
563 void SfxUnoMenuControl::Select()