Update ooo320-m1
[ooovba.git] / sfx2 / source / menu / mnuitem.cxx
blob1974c4e59a8b8a0b45bd242584265883e869f61c
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: mnuitem.cxx,v $
10 * $Revision: 1.24 $
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"
34 #ifdef SOLARIS
35 // HACK: prevent conflict between STLPORT and Workshop headers on Solaris 8
36 #include <ctime>
37 #endif
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>
48 #endif
49 #include <com/sun/star/util/XURLTransformer.hpp>
50 #ifndef _UNOTOOLS_PROCESSFACTORY_HXX
51 #include <comphelper/processfactory.hxx>
52 #endif
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>
59 #ifndef GCC
60 #endif
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>
68 #include "idpool.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>
78 #include "imgmgr.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
92 USHORT nSlot;
93 SfxEnumItem *pItem;
94 SfxBindings* pBindings;
96 protected:
97 virtual void Select();
99 public:
100 SfxEnumMenu( USHORT nSlot, SfxBindings* pBind, const SfxEnumItem &rItem );
101 ~SfxEnumMenu();
104 //=========================================================================
106 SfxEnumMenu::SfxEnumMenu( USHORT nSlotId, SfxBindings* pBind, const SfxEnumItem &rItem ):
107 nSlot( nSlotId ),
108 pItem( (SfxEnumItem*) rItem.Clone() ),
109 pBindings( pBind )
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()
120 delete pItem;
123 //-------------------------------------------------------------------------
125 void SfxEnumMenu::Select()
127 pItem->SetValue( GetCurItemId()-1 );
128 pBindings->GetDispatcher()->Execute( nSlot,
129 SFX_CALLMODE_ASYNCHRON|SFX_CALLMODE_RECORD,
130 pItem, 0L, 0L );
133 //--------------------------------------------------------------------
135 void SfxMenuControl::SetOwnMenu( SfxVirtualMenu* pMenu )
137 pOwnMenu = pMenu;
138 if ( pSubMenu )
139 pSubMenu->SetParentMenu( pMenu );
143 //--------------------------------------------------------------------
145 // binds the instance to the specified id and assignes the title
147 void SfxMenuControl::Bind(
148 SfxVirtualMenu* pOwn,
149 USHORT nSlotId,
150 const String& rTitle,
151 const String &rHelpText,
152 SfxBindings &rBindings )
154 DBG_MEMTEST();
156 aTitle = rTitle;
157 aHelpText = rHelpText;
158 pOwnMenu = pOwn;
159 pSubMenu = 0;
160 if ( pOwn )
161 SfxControllerItem::Bind(nSlotId, &rBindings);
162 else
163 SetId( nSlotId );
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,
175 USHORT nSlotId,
176 SfxVirtualMenu& rMenu,
177 const String& rTitle,
178 const String &rHelpText,
179 SfxBindings &rBindings )
181 DBG_MEMTEST();
182 SetId( nSlotId );
183 SetBindings(rBindings);
184 pOwnMenu = pOwn;
185 pSubMenu = &rMenu;
186 aTitle = rTitle;
187 aHelpText = rHelpText;
190 //--------------------------------------------------------------------
192 // ctor for explicit registration
194 SfxMenuControl::SfxMenuControl( BOOL bShowStrings )
195 : pOwnMenu(0),
196 pSubMenu(0),
197 b_ShowStrings(bShowStrings)
199 DBG_MEMTEST();
202 //--------------------------------------------------------------------
204 // ctor for array
206 SfxMenuControl::SfxMenuControl():
207 pOwnMenu(0),
208 pSubMenu(0),
209 b_ShowStrings(FALSE)
211 DBG_MEMTEST();
214 //--------------------------------------------------------------------
216 SfxMenuControl::SfxMenuControl(USHORT nSlotId, SfxBindings& rBindings):
217 SfxControllerItem(nSlotId, rBindings),
218 pOwnMenu(0),
219 pSubMenu(0),
220 b_ShowStrings(FALSE)
222 DBG_MEMTEST();
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.
228 UnBind();
232 //--------------------------------------------------------------------
234 // dtor
236 SfxMenuControl::~SfxMenuControl()
238 if ( SfxMacroConfig::IsMacroSlot( GetId() ) )
239 SFX_APP()->GetMacroConfig()->ReleaseSlotId(GetId());
240 delete pSubMenu;
243 void SfxMenuControl::RemovePopup()
245 DELETEZ( pSubMenu );
248 //--------------------------------------------------------------------
250 // changes the state in the virtual menu
252 void SfxMenuControl::StateChanged
254 USHORT nSID,
255 SfxItemState eState,
256 const SfxPoolItem* pState
259 (void)nSID; //unused
260 DBG_MEMTEST();
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
269 #ifdef UNIX
270 if (nSID == SID_PASTE)
271 pOwnMenu->EnableItem( GetId(), TRUE );
272 else
273 #endif
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
281 if ( !bIsObjMenu )
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() );
291 return;
294 // ggf. das alte Enum-Menu entfernen/loeschen
295 //! delete pOwnMenu->GetMenu().ChangePopupMenu( GetId(), 0 );
297 bool bCheck = false;
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));
320 aEntry += ' ';
321 aEntry += aStr.Copy(4);
322 aStr = aEntry;
324 else if ( aStr.CompareToAscii("($2)",4) == COMPARE_EQUAL )
326 String aEntry(SfxResId(STR_CLOSEDOC_ANDRETURN));
327 aEntry += aStr.Copy(4);
328 aStr = aEntry;
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 ) );
342 #endif
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);
371 if ( aSlotType )
373 SfxApplication *pApp = SFX_APP();
374 SfxDispatcher *pDisp = rBindings.GetDispatcher_Impl();
375 SfxModule *pMod = pDisp ? SfxModule::GetActiveModule( pDisp->GetFrame() ) :0;
376 if ( pMod )
378 SfxMenuCtrlFactArr_Impl *pFactories = pMod->GetMenuCtrlFactories_Impl();
379 if ( pFactories )
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 );
398 return 0;
401 BOOL SfxMenuControl::IsSpecialControl( USHORT nId, SfxModule* pMod )
403 TypeId aSlotType = SFX_SLOTPOOL().GetSlotType( nId );
404 if ( aSlotType )
406 if ( pMod )
408 SfxMenuCtrlFactArr_Impl *pFactories = pMod->GetMenuCtrlFactories_Impl();
409 if ( pFactories )
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) ) )
416 return TRUE;
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) ) )
426 return TRUE;
428 return 0;
431 //--------------------------------------------------------------------
433 PopupMenu* SfxMenuControl::GetPopup () const
435 if (GetPopupMenu())
436 return (PopupMenu*)GetPopupMenu()->GetSVMenu();
437 else
438 return 0;
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 );
461 if( pMenu )
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()
471 delete pMenu;
474 IMPL_LINK( SfxAppMenuControl_Impl, Activate, Menu *, pActMenu )
476 if ( 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 );
511 if ( !!aImage )
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 );
523 if ( !!aImage )
524 pActMenu->SetItemImage( nItemId, aImage );
527 else
528 pActMenu->SetItemImage( nItemId, Image() );
533 return TRUE;
536 return FALSE;
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);
551 UnBind();
552 pUnoCtrl = new SfxUnoControllerItem( this, rBindings, rCmd );
553 pUnoCtrl->acquire();
554 pUnoCtrl->GetNewDispatch();
557 SfxUnoMenuControl::~SfxUnoMenuControl()
559 pUnoCtrl->UnBind();
560 pUnoCtrl->release();
563 void SfxUnoMenuControl::Select()
565 pUnoCtrl->Execute();