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 #ifdef SOLARIS
28 // HACK: prevent conflict between STLPORT and Workshop headers on Solaris 8
29 #include <ctime>
30 #endif
31
32 #include <string> // HACK: prevent conflict between STLPORT and Workshop includes
33 #include <com/sun/star/uno/Reference.h>
34 #include <com/sun/star/frame/XDispatch.hpp>
35 #include <com/sun/star/frame/XDispatchProvider.hpp>
36 #include <com/sun/star/frame/XFrame.hpp>
37 #include <com/sun/star/util/URL.hpp>
38 #include <com/sun/star/beans/PropertyValue.hpp>
39 #ifndef _UNOTOOLS_PROCESSFACTORY_HXX
40 #include <comphelper/processfactory.hxx>
41 #endif
42 #include <com/sun/star/util/XURLTransformer.hpp>
43 #ifndef _UNOTOOLS_PROCESSFACTORY_HXX
44 #include <comphelper/processfactory.hxx>
45 #endif
46 #include <tools/urlobj.hxx>
47 #include <svl/eitem.hxx>
48 #include <svl/stritem.hxx>
49 #include <svtools/imagemgr.hxx>
50 #include <svtools/menuoptions.hxx>
51 #include <framework/menuconfiguration.hxx>
52 #ifndef GCC
53 #endif
54
55 #include <sfx2/app.hxx>
56 #include <sfx2/sfx.hrc>
57 #include <sfx2/msgpool.hxx>
58 #include <sfx2/msg.hxx>
59 #include <sfx2/bindings.hxx>
60 #include <sfx2/dispatch.hxx>
61 #include "idpool.hxx"
62 #include "sfxtypes.hxx"
63 #include "virtmenu.hxx"
64 #include <sfx2/mnuitem.hxx>
65 #include <sfx2/tbxctrl.hxx>
66 #include "arrdecl.hxx"
67 #include <sfx2/module.hxx>
68 #include <sfx2/unoctitm.hxx>
69 #include <sfx2/viewfrm.hxx>
70 #include "sfx2/imgmgr.hxx"
71 #include "sfx2/imagemgr.hxx"
72 #include "sfx2/sfxresid.hxx"
73 #include "../doc/doc.hrc"
74
75 using namespace ::com::sun::star::uno;
76 using namespace ::com::sun::star::frame;
77 using namespace ::com::sun::star::beans;
78 using namespace ::com::sun::star::util;
79
80 //====================================================================
81
82 class SfxEnumMenu: public PopupMenu
83 {
84 sal_uInt16 nSlot;
85 SfxEnumItem *pItem;
86 SfxBindings* pBindings;
87
88 protected:
89 virtual void Select();
90
91 public:
92 SfxEnumMenu( sal_uInt16 nSlot, SfxBindings* pBind, const SfxEnumItem &rItem );
93 ~SfxEnumMenu();
94 };
95
96 //=========================================================================
97
SfxEnumMenu(sal_uInt16 nSlotId,SfxBindings * pBind,const SfxEnumItem & rItem)98 SfxEnumMenu::SfxEnumMenu( sal_uInt16 nSlotId, SfxBindings* pBind, const SfxEnumItem &rItem ):
99 nSlot( nSlotId ),
100 pItem( (SfxEnumItem*) rItem.Clone() ),
101 pBindings( pBind )
102 {
103 for ( sal_uInt16 nVal = 0; nVal < pItem->GetValueCount(); ++nVal )
104 InsertItem( nVal+1, pItem->GetValueTextByPos(nVal) );
105 CheckItem( pItem->GetValue() + 1, sal_True );
106 }
107
108 //-------------------------------------------------------------------------
109
~SfxEnumMenu()110 SfxEnumMenu::~SfxEnumMenu()
111 {
112 delete pItem;
113 }
114
115 //-------------------------------------------------------------------------
116
Select()117 void SfxEnumMenu::Select()
118 {
119 pItem->SetValue( GetCurItemId()-1 );
120 pBindings->GetDispatcher()->Execute( nSlot,
121 SFX_CALLMODE_ASYNCHRON|SFX_CALLMODE_RECORD,
122 pItem, 0L, 0L );
123 }
124
125 //--------------------------------------------------------------------
126
SetOwnMenu(SfxVirtualMenu * pMenu)127 void SfxMenuControl::SetOwnMenu( SfxVirtualMenu* pMenu )
128 {
129 pOwnMenu = pMenu;
130 if ( pSubMenu )
131 pSubMenu->SetParentMenu( pMenu );
132 }
133
134
135 //--------------------------------------------------------------------
136
137 // binds the instance to the specified id and assignes the title
138
Bind(SfxVirtualMenu * pOwn,sal_uInt16 nSlotId,const String & rTitle,const String & rHelpText,SfxBindings & rBindings)139 void SfxMenuControl::Bind(
140 SfxVirtualMenu* pOwn,
141 sal_uInt16 nSlotId,
142 const String& rTitle,
143 const String &rHelpText,
144 SfxBindings &rBindings )
145 {
146 DBG_MEMTEST();
147
148 aTitle = rTitle;
149 aHelpText = rHelpText;
150 pOwnMenu = pOwn;
151 pSubMenu = 0;
152 if ( pOwn )
153 SfxControllerItem::Bind(nSlotId, &rBindings);
154 else
155 SetId( nSlotId );
156
157 DBG( CheckConfigure_Impl(SFX_SLOT_MENUCONFIG) );
158 }
159
160
161 //--------------------------------------------------------------------
162
163 // binds the item to the specified menu and assignes the title
164
Bind(SfxVirtualMenu * pOwn,sal_uInt16 nSlotId,SfxVirtualMenu & rMenu,const String & rTitle,const String & rHelpText,SfxBindings & rBindings)165 void SfxMenuControl::Bind(
166 SfxVirtualMenu* pOwn,
167 sal_uInt16 nSlotId,
168 SfxVirtualMenu& rMenu,
169 const String& rTitle,
170 const String &rHelpText,
171 SfxBindings &rBindings )
172 {
173 DBG_MEMTEST();
174 SetId( nSlotId );
175 SetBindings(rBindings);
176 pOwnMenu = pOwn;
177 pSubMenu = &rMenu;
178 aTitle = rTitle;
179 aHelpText = rHelpText;
180 }
181
182 //--------------------------------------------------------------------
183
184 // ctor for explicit registration
185
SfxMenuControl(sal_Bool bShowStrings)186 SfxMenuControl::SfxMenuControl( sal_Bool bShowStrings )
187 : pOwnMenu(0),
188 pSubMenu(0),
189 b_ShowStrings(bShowStrings)
190 {
191 DBG_MEMTEST();
192 }
193
194 //--------------------------------------------------------------------
195
196 // ctor for array
197
SfxMenuControl()198 SfxMenuControl::SfxMenuControl():
199 pOwnMenu(0),
200 pSubMenu(0),
201 b_ShowStrings(sal_False)
202 {
203 DBG_MEMTEST();
204 }
205
206 //--------------------------------------------------------------------
207
SfxMenuControl(sal_uInt16 nSlotId,SfxBindings & rBindings)208 SfxMenuControl::SfxMenuControl(sal_uInt16 nSlotId, SfxBindings& rBindings):
209 SfxControllerItem(nSlotId, rBindings),
210 pOwnMenu(0),
211 pSubMenu(0),
212 b_ShowStrings(sal_False)
213 {
214 DBG_MEMTEST();
215
216 // Dieser Ctor soll es erm"oglichen, w"ahrend der Konstruktion schon
217 // auf die Bindings zur"uckgreifen zu k"onnen, aber gebunden wird
218 // wie immer erst sp"ater. Anwendung z.B. wenn im ctor der abgeleiteten
219 // Klasse z.B. ein StatusForwarder erzeugt werden soll.
220 UnBind();
221 }
222
223
224 //--------------------------------------------------------------------
225
226 // dtor
227
~SfxMenuControl()228 SfxMenuControl::~SfxMenuControl()
229 {
230 delete pSubMenu;
231 }
232
RemovePopup()233 void SfxMenuControl::RemovePopup()
234 {
235 DELETEZ( pSubMenu );
236 }
237
238 //--------------------------------------------------------------------
239
240 // changes the state in the virtual menu
241
StateChanged(sal_uInt16 nSID,SfxItemState eState,const SfxPoolItem * pState)242 void SfxMenuControl::StateChanged
243 (
244 sal_uInt16 nSID,
245 SfxItemState eState,
246 const SfxPoolItem* pState
247 )
248 {
249 (void)nSID; //unused
250 DBG_MEMTEST();
251 DBG_ASSERT( nSID == GetId(), "strange SID" );
252 DBG_ASSERT( pOwnMenu != 0, "setting state to dangling SfxMenuControl" );
253
254 bool bIsObjMenu =
255 GetId() >= SID_OBJECTMENU0 && GetId() < SID_OBJECTMENU_LAST;
256
257 // enabled/disabled-Flag pauschal korrigieren
258
259 #ifdef UNIX
260 if (nSID == SID_PASTE)
261 pOwnMenu->EnableItem( GetId(), sal_True );
262 else
263 #endif
264 pOwnMenu->EnableItem( GetId(), bIsObjMenu
265 ? 0 != pOwnMenu->GetSVMenu()->GetPopupMenu( GetId() )
266 : eState != SFX_ITEM_DISABLED );
267
268 if ( eState != SFX_ITEM_AVAILABLE )
269 {
270 // checken nur bei nicht-Object-Menus
271 if ( !bIsObjMenu )
272 pOwnMenu->CheckItem( GetId(), sal_False );
273
274 // SetItemText flackert in MenuBar insbes. unter OS/2 (Bug #20658)
275 if ( // !bIsObjMenu && nicht wegen "Format/Datenbank"
276 pOwnMenu->GetSVMenu()->GetItemText( GetId() ) != GetTitle() )
277 {
278 DBG_WARNING("Title of menu item changed - please check if this needs correction!");
279 // pOwnMenu->SetItemText( GetId(), GetTitle() );
280 }
281 return;
282 }
283
284 // ggf. das alte Enum-Menu entfernen/loeschen
285 //! delete pOwnMenu->GetMenu().ChangePopupMenu( GetId(), 0 );
286
287 bool bCheck = false;
288 if ( pState->ISA(SfxBoolItem) )
289 {
290 // BoolItem fuer checken
291 DBG_ASSERT( GetId() < SID_OBJECTMENU0 || GetId() > SID_OBJECTMENU_LAST,
292 "SfxBoolItem not allowed for SID_OBJECTMENUx" );
293 bCheck = ((const SfxBoolItem*)pState)->GetValue();
294 Menu* pMenu = pOwnMenu->GetSVMenu();
295 pMenu->SetItemBits( GetId() , pMenu->GetItemBits( GetId() ) | MIB_CHECKABLE);
296 }
297 else if ( pState->ISA(SfxEnumItemInterface) &&
298 ((SfxEnumItemInterface *)pState)->HasBoolValue() )
299 {
300 // EnumItem wie Bool behandeln
301 DBG_ASSERT( GetId() < SID_OBJECTMENU0 || GetId() > SID_OBJECTMENU_LAST,
302 "SfxEnumItem not allowed for SID_OBJECTMENUx" );
303 bCheck = ((SfxEnumItemInterface *)pState)->GetBoolValue();
304 Menu* pMenu = pOwnMenu->GetSVMenu();
305 pMenu->SetItemBits( GetId() , pMenu->GetItemBits( GetId() ) | MIB_CHECKABLE);
306 }
307 else if ( ( b_ShowStrings || bIsObjMenu ) && pState->ISA(SfxStringItem) )
308 {
309 // MenuText aus SfxStringItem holen
310 String aStr( ((const SfxStringItem*)pState)->GetValue() );
311 if ( aStr.CompareToAscii("($1)",4) == COMPARE_EQUAL )
312 {
313 String aEntry(SfxResId(STR_UPDATEDOC));
314 aEntry += ' ';
315 aEntry += aStr.Copy(4);
316 aStr = aEntry;
317 }
318 else if ( aStr.CompareToAscii("($2)",4) == COMPARE_EQUAL )
319 {
320 String aEntry(SfxResId(STR_CLOSEDOC_ANDRETURN));
321 aEntry += aStr.Copy(4);
322 aStr = aEntry;
323 }
324
325 pOwnMenu->SetItemText( GetId(), aStr );
326 }
327
328 #ifdef enum_item_menu_ok
329 else if ( aType == TYPE(SfxEnumItem) )
330 {
331 DBG_ASSERT( GetId() < SID_OBJECTMENU0 || GetId() > SID_OBJECTMENU_LAST,
332 "SfxEnumItem not allowed for SID_OBJECTMENUx" );
333 pOwnMenu->GetMenu().ChangePopupMenu( GetId(), &GetBindings(),
334 new SfxEnumMenu( GetId(), *(const SfxEnumItem*)pState ) );
335 }
336 #endif
337
338 pOwnMenu->CheckItem( GetId(), bCheck );
339 }
340
341 //--------------------------------------------------------------------
342
CreateImpl(sal_uInt16,Menu &,SfxBindings &)343 SfxMenuControl* SfxMenuControl::CreateImpl( sal_uInt16 /*nId*/, Menu& /*rMenu*/, SfxBindings& /*rBindings*/ )
344 {
345 return new SfxMenuControl( sal_True );
346 }
347
348 //--------------------------------------------------------------------
349
RegisterControl(sal_uInt16 nSlotId,SfxModule * pMod)350 void SfxMenuControl::RegisterControl( sal_uInt16 nSlotId, SfxModule *pMod )
351 {
352 RegisterMenuControl( pMod, new SfxMenuCtrlFactory(
353 SfxMenuControl::CreateImpl, TYPE(SfxStringItem), nSlotId ) );
354 }
355
356 //--------------------------------------------------------------------
RegisterMenuControl(SfxModule * pMod,SfxMenuCtrlFactory * pFact)357 void SfxMenuControl::RegisterMenuControl(SfxModule* pMod, SfxMenuCtrlFactory* pFact)
358 {
359 SFX_APP()->RegisterMenuControl_Impl( pMod, pFact );
360 }
361
CreateControl(sal_uInt16 nId,Menu & rMenu,SfxBindings & rBindings)362 SfxMenuControl* SfxMenuControl::CreateControl( sal_uInt16 nId, Menu &rMenu, SfxBindings &rBindings )
363 {
364 TypeId aSlotType = SFX_SLOTPOOL().GetSlotType(nId);
365 if ( aSlotType )
366 {
367 SfxApplication *pApp = SFX_APP();
368 SfxDispatcher *pDisp = rBindings.GetDispatcher_Impl();
369 SfxModule *pMod = pDisp ? SfxModule::GetActiveModule( pDisp->GetFrame() ) :0;
370 if ( pMod )
371 {
372 SfxMenuCtrlFactArr_Impl *pFactories = pMod->GetMenuCtrlFactories_Impl();
373 if ( pFactories )
374 {
375 SfxMenuCtrlFactArr_Impl &rFactories = *pFactories;
376 for ( sal_uInt16 nFactory = 0; nFactory < rFactories.Count(); ++nFactory )
377 if ( rFactories[nFactory]->nTypeId == aSlotType &&
378 ( ( rFactories[nFactory]->nSlotId == 0 ) ||
379 ( rFactories[nFactory]->nSlotId == nId) ) )
380 return rFactories[nFactory]->pCtor( nId, rMenu, rBindings );
381 }
382 }
383
384 SfxMenuCtrlFactArr_Impl &rFactories = pApp->GetMenuCtrlFactories_Impl();
385
386 for ( sal_uInt16 nFactory = 0; nFactory < rFactories.Count(); ++nFactory )
387 if ( rFactories[nFactory]->nTypeId == aSlotType &&
388 ( ( rFactories[nFactory]->nSlotId == 0 ) ||
389 ( rFactories[nFactory]->nSlotId == nId) ) )
390 return rFactories[nFactory]->pCtor( nId, rMenu, rBindings );
391 }
392 return 0;
393 }
394
IsSpecialControl(sal_uInt16 nId,SfxModule * pMod)395 sal_Bool SfxMenuControl::IsSpecialControl( sal_uInt16 nId, SfxModule* pMod )
396 {
397 TypeId aSlotType = SFX_SLOTPOOL().GetSlotType( nId );
398 if ( aSlotType )
399 {
400 if ( pMod )
401 {
402 SfxMenuCtrlFactArr_Impl *pFactories = pMod->GetMenuCtrlFactories_Impl();
403 if ( pFactories )
404 {
405 SfxMenuCtrlFactArr_Impl &rFactories = *pFactories;
406 for ( sal_uInt16 nFactory = 0; nFactory < rFactories.Count(); ++nFactory )
407 if ( rFactories[nFactory]->nTypeId == aSlotType &&
408 ( ( rFactories[nFactory]->nSlotId == 0 ) ||
409 ( rFactories[nFactory]->nSlotId == nId) ) )
410 return sal_True;
411 }
412 }
413
414 SfxMenuCtrlFactArr_Impl &rFactories = SFX_APP()->GetMenuCtrlFactories_Impl();
415
416 for ( sal_uInt16 nFactory = 0; nFactory < rFactories.Count(); ++nFactory )
417 if ( rFactories[nFactory]->nTypeId == aSlotType &&
418 ( ( rFactories[nFactory]->nSlotId == 0 ) ||
419 ( rFactories[nFactory]->nSlotId == nId) ) )
420 return sal_True;
421 }
422 return 0;
423 }
424
425 //--------------------------------------------------------------------
426
GetPopup() const427 PopupMenu* SfxMenuControl::GetPopup () const
428 {
429 if (GetPopupMenu())
430 return (PopupMenu*)GetPopupMenu()->GetSVMenu();
431 else
432 return 0;
433 }
434
435 long Select_Impl( void* pHdl, void* pVoid );
436
437 SFX_IMPL_MENU_CONTROL( SfxAppMenuControl_Impl, SfxStringItem );
438
SfxAppMenuControl_Impl(sal_uInt16 nPos,Menu & rMenu,SfxBindings & rBindings)439 SfxAppMenuControl_Impl::SfxAppMenuControl_Impl(
440 sal_uInt16 nPos, Menu& rMenu, SfxBindings& rBindings )
441 : SfxMenuControl( nPos, rBindings ), pMenu(0)
442 {
443 String aText = rMenu.GetItemText( nPos );
444
445 // Determine the current background color setting for menus
446 const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
447 m_nSymbolsStyle = rSettings.GetSymbolsStyle();
448 m_bWasHiContrastMode = rSettings.GetHighContrastMode();
449 m_bShowMenuImages = rSettings.GetUseImagesInMenus();
450
451 Reference<com::sun::star::lang::XMultiServiceFactory> aXMultiServiceFactory(::comphelper::getProcessServiceFactory());
452 ::framework::MenuConfiguration aConf( aXMultiServiceFactory );
453 Reference<com::sun::star::frame::XFrame> aXFrame( GetBindings().GetDispatcher_Impl()->GetFrame()->GetFrame().GetFrameInterface() );
454 pMenu = aConf.CreateBookmarkMenu( aXFrame, GetId() == SID_NEWDOCDIRECT ? BOOKMARK_NEWMENU : BOOKMARK_WIZARDMENU );
455 if( pMenu )
456 {
457 pMenu->SetSelectHdl( Link( &(this->GetBindings()), Select_Impl ) );
458 pMenu->SetActivateHdl( LINK(this, SfxAppMenuControl_Impl, Activate) );
459 rMenu.SetPopupMenu( nPos, pMenu );
460 }
461 }
462
~SfxAppMenuControl_Impl()463 SfxAppMenuControl_Impl::~SfxAppMenuControl_Impl()
464 {
465 delete pMenu;
466 }
467
IMPL_LINK(SfxAppMenuControl_Impl,Activate,Menu *,pActMenu)468 IMPL_LINK( SfxAppMenuControl_Impl, Activate, Menu *, pActMenu )
469 {
470 if ( pActMenu )
471 {
472 const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
473 sal_uIntPtr nSymbolsStyle = rSettings.GetSymbolsStyle();
474 sal_Bool bIsHiContrastMode = rSettings.GetHighContrastMode();
475 sal_Bool bShowMenuImages = rSettings.GetUseImagesInMenus();
476
477 if (( nSymbolsStyle != m_nSymbolsStyle ) ||
478 ( bIsHiContrastMode != m_bWasHiContrastMode ) ||
479 ( bShowMenuImages != m_bShowMenuImages ))
480 {
481 m_nSymbolsStyle = nSymbolsStyle;
482 m_bWasHiContrastMode = bIsHiContrastMode;
483 m_bShowMenuImages = bShowMenuImages;
484
485 sal_uInt16 nCount = pActMenu->GetItemCount();
486 for ( sal_uInt16 nSVPos = 0; nSVPos < nCount; nSVPos++ )
487 {
488 sal_uInt16 nItemId = pActMenu->GetItemId( nSVPos );
489 if ( pActMenu->GetItemType( nSVPos ) != MENUITEM_SEPARATOR )
490 {
491 if ( bShowMenuImages )
492 {
493 sal_Bool bImageSet = sal_False;
494 ::rtl::OUString aImageId;
495 ::framework::MenuConfiguration::Attributes* pMenuAttributes =
496 (::framework::MenuConfiguration::Attributes*)pMenu->GetUserValue( nItemId );
497
498 if ( pMenuAttributes )
499 aImageId = pMenuAttributes->aImageId; // Retrieve image id from menu attributes
500
501 if ( aImageId.getLength() > 0 )
502 {
503 Reference< ::com::sun::star::frame::XFrame > xFrame;
504 Image aImage = GetImage( xFrame, aImageId, sal_False, bIsHiContrastMode );
505 if ( !!aImage )
506 {
507 bImageSet = sal_True;
508 pActMenu->SetItemImage( nItemId, aImage );
509 }
510 }
511
512 String aCmd( pActMenu->GetItemCommand( nItemId ) );
513 if ( !bImageSet && aCmd.Len() )
514 {
515 Image aImage = SvFileInformationManager::GetImage(
516 INetURLObject(aCmd), sal_False, bIsHiContrastMode );
517 if ( !!aImage )
518 pActMenu->SetItemImage( nItemId, aImage );
519 }
520 }
521 else
522 pActMenu->SetItemImage( nItemId, Image() );
523 }
524 }
525 }
526
527 return sal_True;
528 }
529
530 return sal_False;
531 }
532
CreateControl(const String & rCmd,sal_uInt16 nId,Menu & rMenu,SfxBindings & rBindings,SfxVirtualMenu * pVirt)533 SfxUnoMenuControl* SfxMenuControl::CreateControl( const String& rCmd,
534 sal_uInt16 nId, Menu& rMenu, SfxBindings &rBindings, SfxVirtualMenu* pVirt )
535 {
536 return new SfxUnoMenuControl( rCmd, nId, rMenu, rBindings, pVirt );
537 }
538
CreateControl(const String & rCmd,sal_uInt16 nId,Menu & rMenu,const String & sItemText,const String & sHelpText,SfxBindings & rBindings,SfxVirtualMenu * pVirt)539 SfxUnoMenuControl* SfxMenuControl::CreateControl( const String& rCmd,
540 sal_uInt16 nId, Menu& rMenu, const String& sItemText, const String& sHelpText,
541 SfxBindings& rBindings, SfxVirtualMenu* pVirt)
542 {
543 return new SfxUnoMenuControl( rCmd, nId, rMenu, sItemText, sHelpText, rBindings, pVirt);
544 }
545
SfxUnoMenuControl(const String & rCmd,sal_uInt16 nSlotId,Menu & rMenu,SfxBindings & rBindings,SfxVirtualMenu * pVirt)546 SfxUnoMenuControl::SfxUnoMenuControl( const String& rCmd, sal_uInt16 nSlotId,
547 Menu& rMenu, SfxBindings& rBindings, SfxVirtualMenu* pVirt )
548 : SfxMenuControl( nSlotId, rBindings )
549 {
550 Bind( pVirt, nSlotId, rMenu.GetItemText(nSlotId),
551 rMenu.GetHelpText(nSlotId), rBindings);
552 UnBind();
553 pUnoCtrl = new SfxUnoControllerItem( this, rBindings, rCmd );
554 pUnoCtrl->acquire();
555 pUnoCtrl->GetNewDispatch();
556 }
557
SfxUnoMenuControl(const String & rCmd,sal_uInt16 nSlotId,Menu &,const String & rItemText,const String & rHelpText,SfxBindings & rBindings,SfxVirtualMenu * pVirt)558 SfxUnoMenuControl::SfxUnoMenuControl(
559 const String& rCmd, sal_uInt16 nSlotId, Menu& /*rMenu*/,
560 const String& rItemText, const String& rHelpText,
561 SfxBindings& rBindings, SfxVirtualMenu* pVirt)
562 : SfxMenuControl( nSlotId, rBindings )
563 {
564 Bind( pVirt, nSlotId, rItemText, rHelpText, rBindings);
565 UnBind();
566 pUnoCtrl = new SfxUnoControllerItem( this, rBindings, rCmd );
567 pUnoCtrl->acquire();
568 pUnoCtrl->GetNewDispatch();
569 }
570
~SfxUnoMenuControl()571 SfxUnoMenuControl::~SfxUnoMenuControl()
572 {
573 pUnoCtrl->UnBind();
574 pUnoCtrl->release();
575 }
576
Select()577 void SfxUnoMenuControl::Select()
578 {
579 pUnoCtrl->Execute();
580 }
581
Select_Impl(void *,void * pVoid)582 long Select_Impl( void* /*pHdl*/, void* pVoid )
583 {
584 Menu* pMenu = (Menu*)pVoid;
585 String aURL( pMenu->GetItemCommand( pMenu->GetCurItemId() ) );
586
587 if( !aURL.Len() )
588 return 0;
589
590 Reference < ::com::sun::star::frame::XFramesSupplier > xDesktop =
591 Reference < ::com::sun::star::frame::XFramesSupplier >( ::comphelper::getProcessServiceFactory()->createInstance(
592 DEFINE_CONST_UNICODE("com.sun.star.frame.Desktop") ), UNO_QUERY );
593 Reference < ::com::sun::star::frame::XFrame > xFrame( xDesktop, UNO_QUERY );
594
595 URL aTargetURL;
596 aTargetURL.Complete = aURL;
597 Reference < XURLTransformer > xTrans( ::comphelper::getProcessServiceFactory()->createInstance(
598 rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer" )),
599 UNO_QUERY );
600 xTrans->parseStrict( aTargetURL );
601
602 Reference < XDispatchProvider > xProv( xFrame, UNO_QUERY );
603 Reference < XDispatch > xDisp;
604 if ( xProv.is() )
605 {
606 if ( aTargetURL.Protocol.compareToAscii("slot:") == COMPARE_EQUAL )
607 xDisp = xProv->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
608 else
609 {
610 ::rtl::OUString aTargetFrame( ::rtl::OUString::createFromAscii( "_blank" ) );
611 ::framework::MenuConfiguration::Attributes* pMenuAttributes =
612 (::framework::MenuConfiguration::Attributes*)pMenu->GetUserValue( pMenu->GetCurItemId() );
613
614 if ( pMenuAttributes )
615 aTargetFrame = pMenuAttributes->aTargetFrame;
616
617 xDisp = xProv->queryDispatch( aTargetURL, aTargetFrame , 0 );
618 }
619 }
620
621 if ( xDisp.is() )
622 {
623 SfxAppMenuControl_Impl::ExecuteInfo* pExecuteInfo = new SfxAppMenuControl_Impl::ExecuteInfo;
624 pExecuteInfo->xDispatch = xDisp;
625 pExecuteInfo->aTargetURL = aTargetURL;
626 pExecuteInfo->aArgs = Sequence< PropertyValue >();
627 Application::PostUserEvent( STATIC_LINK( 0, SfxAppMenuControl_Impl, ExecuteHdl_Impl), pExecuteInfo );
628 }
629
630 return sal_True;
631 }
632
633
IMPL_STATIC_LINK_NOINSTANCE(SfxAppMenuControl_Impl,ExecuteHdl_Impl,ExecuteInfo *,pExecuteInfo)634 IMPL_STATIC_LINK_NOINSTANCE( SfxAppMenuControl_Impl, ExecuteHdl_Impl, ExecuteInfo*, pExecuteInfo )
635 {
636 pExecuteInfo->xDispatch->dispatch( pExecuteInfo->aTargetURL, pExecuteInfo->aArgs );
637 delete pExecuteInfo;
638 return 0;
639 }
640