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: dbtreelistbox.cxx,v $
10 * $Revision: 1.20.26.1 $
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_dbaccess.hxx"
34 #ifndef DBAUI_DBTREELISTBOX_HXX
35 #include "dbtreelistbox.hxx"
37 #ifndef _DBU_RESOURCE_HRC_
38 #include "dbu_resource.hrc"
40 #ifndef DBACCESS_UI_BROWSER_ID_HXX
41 #include "browserids.hxx"
43 #ifndef _DBAUI_LISTVIEWITEMS_HXX_
44 #include "listviewitems.hxx"
46 #ifndef _DBACCESS_UI_CALLBACKS_HXX_
47 #include "callbacks.hxx"
50 #ifndef _COM_SUN_STAR_DATATRANSFER_DND_XDRAGGESTURELISTENER_HDL_
51 #include <com/sun/star/datatransfer/dnd/XDragGestureListener.hdl>
53 #ifndef _COM_SUN_STAR_DATATRANSFER_DND_XDRAGGESTURERECOGNIZER_HPP_
54 #include <com/sun/star/datatransfer/dnd/XDragGestureRecognizer.hpp>
56 #ifndef _COM_SUN_STAR_UI_XCONTEXTMENUINTERCEPTOR_HPP_
57 #include <com/sun/star/ui/XContextMenuInterceptor.hpp>
59 #include <com/sun/star/frame/XFrame.hpp>
60 #ifndef _COM_SUN_STAR_UTIL_URL_HPP_
61 #include <com/sun/star/util/URL.hpp>
63 #ifndef _CPPUHELPER_IMPLBASE1_HXX_
64 #include <cppuhelper/implbase1.hxx>
66 #ifndef _CPPUHELPER_INTERFACECONTAINER_HXX_
67 #include <cppuhelper/interfacecontainer.hxx>
70 #include <vcl/help.hxx>
72 #ifndef _DBAUI_TABLETREE_HRC_
73 #include "tabletree.hrc"
75 #ifndef DBAUI_ICONTROLLER_HXX
76 #include "IController.hxx"
78 #ifndef __FRAMEWORK_HELPER_ACTIONTRIGGERHELPER_HXX_
79 #include <framework/actiontriggerhelper.hxx>
81 #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
82 #include <toolkit/helper/vclunohelper.hxx>
84 #include <framework/imageproducer.hxx>
85 #include <vcl/svapp.hxx>
88 // .........................................................................
91 // .........................................................................
93 using namespace ::com::sun::star
;
94 using namespace ::com::sun::star::uno
;
95 using namespace ::com::sun::star::beans
;
96 using namespace ::com::sun::star::lang
;
97 using namespace ::com::sun::star::datatransfer
;
98 using namespace ::com::sun::star::frame
;
99 using namespace ::com::sun::star::ui
;
100 using namespace ::com::sun::star::view
;
102 DBG_NAME(DBTreeListBox
)
103 #define SPACEBETWEENENTRIES 4
104 //========================================================================
105 // class DBTreeListBox
106 //========================================================================
107 //------------------------------------------------------------------------
108 DBTreeListBox::DBTreeListBox( Window
* pParent
, const Reference
< XMultiServiceFactory
>& _rxORB
, WinBits nWinStyle
,sal_Bool _bHandleEnterKey
)
109 :SvTreeListBox(pParent
,nWinStyle
)
110 ,m_pDragedEntry(NULL
)
111 ,m_pActionListener(NULL
)
112 ,m_pContextMenuProvider( NULL
)
113 ,m_bHandleEnterKey(_bHandleEnterKey
)
116 DBG_CTOR(DBTreeListBox
,NULL
);
119 // -----------------------------------------------------------------------------
120 DBTreeListBox::DBTreeListBox( Window
* pParent
, const Reference
< XMultiServiceFactory
>& _rxORB
, const ResId
& rResId
,sal_Bool _bHandleEnterKey
)
121 :SvTreeListBox(pParent
,rResId
)
122 ,m_pDragedEntry(NULL
)
123 ,m_pActionListener(NULL
)
124 ,m_pContextMenuProvider( NULL
)
125 ,m_bHandleEnterKey(_bHandleEnterKey
)
128 DBG_CTOR(DBTreeListBox
,NULL
);
131 // -----------------------------------------------------------------------------
132 void DBTreeListBox::init()
134 USHORT nSize
= SPACEBETWEENENTRIES
;
135 SetSpaceBetweenEntries(nSize
);
137 m_aTimer
.SetTimeout(900);
138 m_aTimer
.SetTimeoutHdl(LINK(this, DBTreeListBox
, OnTimeOut
));
140 m_aScrollHelper
.setUpScrollMethod( LINK(this, DBTreeListBox
, ScrollUpHdl
) );
141 m_aScrollHelper
.setDownScrollMethod( LINK(this, DBTreeListBox
, ScrollDownHdl
) );
143 SetNodeDefaultImages( );
145 EnableContextMenuHandling();
147 //------------------------------------------------------------------------
148 DBTreeListBox::~DBTreeListBox()
150 DBG_DTOR(DBTreeListBox
,NULL
);
151 implStopSelectionTimer();
153 //------------------------------------------------------------------------
154 SvLBoxEntry
* DBTreeListBox::GetEntryPosByName( const String
& aName
, SvLBoxEntry
* pStart
, const IEntryFilter
* _pFilter
) const
156 SvLBoxTreeList
* myModel
= GetModel();
157 SvTreeEntryList
* pChilds
= myModel
->GetChildList(pStart
);
158 SvLBoxEntry
* pEntry
= NULL
;
161 ULONG nCount
= pChilds
->Count();
162 for (ULONG i
=0; i
< nCount
; ++i
)
164 pEntry
= static_cast<SvLBoxEntry
*>(pChilds
->GetObject(i
));
165 SvLBoxString
* pItem
= (SvLBoxString
*)(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXSTRING
));
166 if ( pItem
->GetText().Equals(aName
) )
168 if ( !_pFilter
|| _pFilter
->includeEntry( pEntry
) )
179 // -------------------------------------------------------------------------
180 void DBTreeListBox::EnableExpandHandler(SvLBoxEntry
* _pEntry
)
182 LINK(this, DBTreeListBox
, OnResetEntry
).Call(_pEntry
);
185 // -------------------------------------------------------------------------
186 void DBTreeListBox::RequestingChilds( SvLBoxEntry
* pParent
)
188 if (m_aPreExpandHandler
.IsSet())
190 if (!m_aPreExpandHandler
.Call(pParent
))
192 // an error occured. The method calling us will reset the entry flags, so it can't be expanded again.
193 // But we want that the user may do a second try (i.e. because he misstypes a password in this try), so
194 // we have to reset these flags controlling the expand ability
195 PostUserEvent(LINK(this, DBTreeListBox
, OnResetEntry
), pParent
);
200 // -------------------------------------------------------------------------
201 void DBTreeListBox::InitEntry( SvLBoxEntry
* _pEntry
, const XubString
& aStr
, const Image
& _rCollEntryBmp
, const Image
& _rExpEntryBmp
, SvLBoxButtonKind eButtonKind
)
203 SvTreeListBox::InitEntry( _pEntry
, aStr
, _rCollEntryBmp
,_rExpEntryBmp
, eButtonKind
);
204 SvLBoxItem
* pTextItem(_pEntry
->GetFirstItem(SV_ITEM_ID_LBOXSTRING
));
205 SvLBoxString
* pString
= new OBoldListboxString( _pEntry
, 0, aStr
);
206 _pEntry
->ReplaceItem( pString
,_pEntry
->GetPos(pTextItem
));
209 // -------------------------------------------------------------------------
210 void DBTreeListBox::implStopSelectionTimer()
212 if ( m_aTimer
.IsActive() )
216 // -------------------------------------------------------------------------
217 void DBTreeListBox::implStartSelectionTimer()
219 implStopSelectionTimer();
223 // -----------------------------------------------------------------------------
225 void DBTreeListBox::DeselectHdl()
227 m_aSelectedEntries
.erase( GetHdlEntry() );
228 SvTreeListBox::DeselectHdl();
229 implStartSelectionTimer();
231 // -------------------------------------------------------------------------
232 void DBTreeListBox::SelectHdl()
234 m_aSelectedEntries
.insert( GetHdlEntry() );
235 SvTreeListBox::SelectHdl();
236 implStartSelectionTimer();
239 // -------------------------------------------------------------------------
240 void DBTreeListBox::MouseButtonDown( const MouseEvent
& rMEvt
)
242 sal_Bool bHitEmptySpace
= (NULL
== GetEntry(rMEvt
.GetPosPixel(), sal_True
));
243 if (bHitEmptySpace
&& (rMEvt
.GetClicks() == 2) && rMEvt
.IsMod1())
244 Control::MouseButtonDown(rMEvt
);
246 SvTreeListBox::MouseButtonDown(rMEvt
);
249 // -------------------------------------------------------------------------
250 IMPL_LINK(DBTreeListBox
, OnResetEntry
, SvLBoxEntry
*, pEntry
)
252 // set the flag which allows if the entry can be expanded
253 pEntry
->SetFlags( (pEntry
->GetFlags() & ~(SV_ENTRYFLAG_NO_NODEBMP
| SV_ENTRYFLAG_HAD_CHILDREN
)) | SV_ENTRYFLAG_CHILDS_ON_DEMAND
);
255 GetModel()->InvalidateEntry( pEntry
);
258 // -----------------------------------------------------------------------------
259 void DBTreeListBox::ModelHasEntryInvalidated( SvListEntry
* _pEntry
)
261 SvTreeListBox::ModelHasEntryInvalidated( _pEntry
);
263 if ( m_aSelectedEntries
.find( _pEntry
) != m_aSelectedEntries
.end() )
265 SvLBoxItem
* pTextItem
= static_cast< SvLBoxEntry
* >( _pEntry
)->GetFirstItem( SV_ITEM_ID_BOLDLBSTRING
);
266 if ( pTextItem
&& !static_cast< OBoldListboxString
* >( pTextItem
)->isEmphasized() )
268 implStopSelectionTimer();
269 m_aSelectedEntries
.erase( _pEntry
);
274 // -------------------------------------------------------------------------
275 void DBTreeListBox::ModelHasRemoved( SvListEntry
* _pEntry
)
277 SvTreeListBox::ModelHasRemoved(_pEntry
);
278 if ( m_aSelectedEntries
.find( _pEntry
) != m_aSelectedEntries
.end() )
280 implStopSelectionTimer();
281 m_aSelectedEntries
.erase( _pEntry
);
285 // -------------------------------------------------------------------------
286 sal_Int8
DBTreeListBox::AcceptDrop( const AcceptDropEvent
& _rEvt
)
288 sal_Int8 nDropOption
= DND_ACTION_NONE
;
289 if ( m_pActionListener
)
291 SvLBoxEntry
* pDroppedEntry
= GetEntry(_rEvt
.maPosPixel
);
292 // check if drag is on child entry, which is not allowed
293 SvLBoxEntry
* pParent
= NULL
;
294 if ( _rEvt
.mnAction
& DND_ACTION_MOVE
)
296 if ( !m_pDragedEntry
) // no entry to move
298 nDropOption
= m_pActionListener
->queryDrop( _rEvt
, GetDataFlavorExVector() );
299 m_aMousePos
= _rEvt
.maPosPixel
;
300 m_aScrollHelper
.scroll(m_aMousePos
,GetOutputSizePixel());
304 pParent
= pDroppedEntry
? GetParent(pDroppedEntry
) : NULL
;
305 while ( pParent
&& pParent
!= m_pDragedEntry
)
306 pParent
= GetParent(pParent
);
311 nDropOption
= m_pActionListener
->queryDrop( _rEvt
, GetDataFlavorExVector() );
312 // check if move is allowed
313 if ( nDropOption
& DND_ACTION_MOVE
)
315 if ( m_pDragedEntry
== pDroppedEntry
|| GetEntryPosByName(GetEntryText(m_pDragedEntry
),pDroppedEntry
) )
316 nDropOption
= nDropOption
& ~DND_ACTION_MOVE
;//DND_ACTION_NONE;
318 m_aMousePos
= _rEvt
.maPosPixel
;
319 m_aScrollHelper
.scroll(m_aMousePos
,GetOutputSizePixel());
326 // -------------------------------------------------------------------------
327 sal_Int8
DBTreeListBox::ExecuteDrop( const ExecuteDropEvent
& _rEvt
)
329 if ( m_pActionListener
)
330 return m_pActionListener
->executeDrop( _rEvt
);
332 return DND_ACTION_NONE
;
335 // -------------------------------------------------------------------------
336 void DBTreeListBox::StartDrag( sal_Int8 _nAction
, const Point
& _rPosPixel
)
338 if ( m_pActionListener
)
340 m_pDragedEntry
= GetEntry(_rPosPixel
);
341 if ( m_pDragedEntry
&& m_pActionListener
->requestDrag( _nAction
, _rPosPixel
) )
343 // if the (asynchronous) drag started, stop the selection timer
344 implStopSelectionTimer();
345 // and stop selecting entries by simply moving the mouse
351 // -------------------------------------------------------------------------
352 void DBTreeListBox::RequestHelp( const HelpEvent
& rHEvt
)
354 if ( !m_pActionListener
)
356 SvTreeListBox::RequestHelp( rHEvt
);
360 if( rHEvt
.GetMode() & HELPMODE_QUICK
)
362 Point
aPos( ScreenToOutputPixel( rHEvt
.GetMousePosPixel() ));
363 SvLBoxEntry
* pEntry
= GetEntry( aPos
);
366 String sQuickHelpText
;
367 if ( m_pActionListener
->requestQuickHelp( pEntry
, sQuickHelpText
) )
369 Size
aSize( GetOutputSizePixel().Width(), GetEntryHeight() );
370 Rectangle
aScreenRect( OutputToScreenPixel( GetEntryPosition( pEntry
) ), aSize
);
372 Help::ShowQuickHelp( this, aScreenRect
,
373 sQuickHelpText
, QUICKHELP_LEFT
| QUICKHELP_VCENTER
);
379 SvTreeListBox::RequestHelp( rHEvt
);
382 // -----------------------------------------------------------------------------
383 void DBTreeListBox::KeyInput( const KeyEvent
& rKEvt
)
385 KeyFuncType eFunc
= rKEvt
.GetKeyCode().GetFunction();
386 USHORT nCode
= rKEvt
.GetKeyCode().GetCode();
387 sal_Bool bHandled
= sal_False
;
389 if(eFunc
!= KEYFUNC_DONTKNOW
)
394 bHandled
= ( m_aCutHandler
.IsSet() && !m_aSelectedEntries
.empty() );
396 m_aCutHandler
.Call( NULL
);
399 bHandled
= ( m_aCopyHandler
.IsSet() && !m_aSelectedEntries
.empty() );
401 m_aCopyHandler
.Call( NULL
);
404 bHandled
= ( m_aPasteHandler
.IsSet() && !m_aSelectedEntries
.empty() );
406 m_aPasteHandler
.Call( NULL
);
409 bHandled
= ( m_aDeleteHandler
.IsSet() && !m_aSelectedEntries
.empty() );
411 m_aDeleteHandler
.Call( NULL
);
418 if ( KEY_RETURN
== nCode
)
420 bHandled
= m_bHandleEnterKey
;
421 if ( m_aEnterKeyHdl
.IsSet() )
422 m_aEnterKeyHdl
.Call(this);
423 // this is a HACK. If the data source browser is opened in the "beamer", while the main frame
424 // contains a writer document, then pressing enter in the DSB would be rerouted to the writer
425 // document if we would not do this hack here.
426 // The problem is that the Writer uses RETURN as _accelerator_ (which is quite weird itself),
427 // so the SFX framework is _obligated_ to pass it to the Writer if nobody else handled it. There
428 // is no chance to distinguish between
429 // "accelerators which are to be executed if the main document has the focus"
431 // "accelerators which are always to be executed"
433 // Thus we cannot prevent the handling of this key in the writer without declaring the key event
434 // as "handled" herein.
436 // The bad thing about this approach is that it does not scale. Every other accelerator which
437 // is used by the document will raise a similar bug once somebody discovers it.
438 // If this is the case, we should discuss a real solution with the framework (SFX) and the
441 // 2002-12-02 - 105831 - fs@openoffice.org
445 SvTreeListBox::KeyInput(rKEvt
);
447 // -----------------------------------------------------------------------------
448 BOOL
DBTreeListBox::EditingEntry( SvLBoxEntry
* pEntry
, Selection
& /*_aSelection*/)
450 return m_aEditingHandler
.Call(pEntry
) != 0;
452 // -----------------------------------------------------------------------------
453 BOOL
DBTreeListBox::EditedEntry( SvLBoxEntry
* pEntry
, const XubString
& rNewText
)
455 DBTreeEditedEntry aEntry
;
456 aEntry
.pEntry
= pEntry
;
457 aEntry
.aNewText
=rNewText
;
458 if(m_aEditedHandler
.Call(&aEntry
) != 0)
460 implStopSelectionTimer();
461 m_aSelectedEntries
.erase( pEntry
);
463 SetEntryText(pEntry
,aEntry
.aNewText
);
465 return FALSE
; // we never want that the base change our text
468 // -----------------------------------------------------------------------------
469 BOOL
DBTreeListBox::DoubleClickHdl()
471 long nResult
= aDoubleClickHdl
.Call( this );
472 // continue default processing if the DoubleClickHandler didn't handle it
476 // -----------------------------------------------------------------------------
477 void scrollWindow(DBTreeListBox
* _pListBox
, const Point
& _rPos
,sal_Bool _bUp
)
479 SvLBoxEntry
* pEntry
= _pListBox
->GetEntry( _rPos
);
480 if( pEntry
&& pEntry
!= _pListBox
->Last() )
482 _pListBox
->ScrollOutputArea( _bUp
? -1 : 1 );
485 // -----------------------------------------------------------------------------
486 IMPL_LINK( DBTreeListBox
, ScrollUpHdl
, SvTreeListBox
*, /*pBox*/ )
488 scrollWindow(this,m_aMousePos
,sal_True
);
492 //------------------------------------------------------------------------------
493 IMPL_LINK( DBTreeListBox
, ScrollDownHdl
, SvTreeListBox
*, /*pBox*/ )
495 scrollWindow(this,m_aMousePos
,sal_False
);
498 // -----------------------------------------------------------------------------
501 void lcl_enableEntries( PopupMenu
* _pPopup
, IController
& _rController
)
506 USHORT nCount
= _pPopup
->GetItemCount();
507 for (USHORT i
=0; i
< nCount
; ++i
)
509 if ( _pPopup
->GetItemType(i
) != MENUITEM_SEPARATOR
)
511 USHORT nId
= _pPopup
->GetItemId(i
);
512 PopupMenu
* pSubPopUp
= _pPopup
->GetPopupMenu(nId
);
515 lcl_enableEntries( pSubPopUp
, _rController
);
516 _pPopup
->EnableItem(nId
,pSubPopUp
->HasValidEntries());
520 ::rtl::OUString
sCommandURL( _pPopup
->GetItemCommand( nId
) );
521 bool bEnabled
= ( sCommandURL
.getLength() )
522 ? _rController
.isCommandEnabled( sCommandURL
)
523 : _rController
.isCommandEnabled( nId
);
524 _pPopup
->EnableItem( nId
, bEnabled
);
529 _pPopup
->RemoveDisabledEntries();
533 // -----------------------------------------------------------------------------
536 void lcl_adjustMenuItemIDs( Menu
& _rMenu
, IController
& _rCommandController
)
538 USHORT nCount
= _rMenu
.GetItemCount();
539 for ( USHORT pos
= 0; pos
< nCount
; ++pos
)
541 // do not adjust separators
542 if ( _rMenu
.GetItemType( pos
) == MENUITEM_SEPARATOR
)
545 USHORT nId
= _rMenu
.GetItemId(pos
);
546 String aCommand
= _rMenu
.GetItemCommand( nId
);
547 PopupMenu
* pPopup
= _rMenu
.GetPopupMenu( nId
);
550 lcl_adjustMenuItemIDs( *pPopup
, _rCommandController
);
554 const USHORT nCommandId
= _rCommandController
.registerCommandURL( aCommand
);
555 _rMenu
.InsertItem( nCommandId
, _rMenu
.GetItemText( nId
), _rMenu
.GetItemImage( nId
),
556 _rMenu
.GetItemBits( nId
), pos
);
558 // more things to preserve:
559 // - the help command
560 ::rtl::OUString sHelpURL
= _rMenu
.GetHelpCommand( nId
);
561 if ( sHelpURL
.getLength() )
562 _rMenu
.SetHelpCommand( nCommandId
, sHelpURL
);
564 // remove the "old" item
565 _rMenu
.RemoveItem( pos
+1 );
568 void lcl_insertMenuItemImages( Menu
& _rMenu
, IController
& _rCommandController
)
570 const StyleSettings
& rSettings
= Application::GetSettings().GetStyleSettings();
571 const BOOL bHiContrast
= rSettings
.GetMenuColor().IsDark();
572 uno::Reference
< frame::XController
> xController
= _rCommandController
.getXController();
573 uno::Reference
< frame::XFrame
> xFrame
;
574 if ( xController
.is() )
575 xFrame
= xController
->getFrame();
576 USHORT nCount
= _rMenu
.GetItemCount();
577 for ( USHORT pos
= 0; pos
< nCount
; ++pos
)
579 // do not adjust separators
580 if ( _rMenu
.GetItemType( pos
) == MENUITEM_SEPARATOR
)
583 USHORT nId
= _rMenu
.GetItemId(pos
);
584 String aCommand
= _rMenu
.GetItemCommand( nId
);
585 PopupMenu
* pPopup
= _rMenu
.GetPopupMenu( nId
);
588 lcl_insertMenuItemImages( *pPopup
, _rCommandController
);
593 _rMenu
.SetItemImage(nId
,framework::GetImageFromURL(xFrame
,aCommand
,FALSE
,bHiContrast
));
596 // =========================================================================
597 // = SelectionSupplier
598 // =========================================================================
599 typedef ::cppu::WeakImplHelper1
< XSelectionSupplier
600 > SelectionSupplier_Base
;
601 class SelectionSupplier
: public SelectionSupplier_Base
604 SelectionSupplier( const Any
& _rSelection
)
605 :m_aSelection( _rSelection
)
609 virtual ::sal_Bool SAL_CALL
select( const Any
& xSelection
) throw (IllegalArgumentException
, RuntimeException
);
610 virtual Any SAL_CALL
getSelection( ) throw (RuntimeException
);
611 virtual void SAL_CALL
addSelectionChangeListener( const Reference
< XSelectionChangeListener
>& xListener
) throw (RuntimeException
);
612 virtual void SAL_CALL
removeSelectionChangeListener( const Reference
< XSelectionChangeListener
>& xListener
) throw (RuntimeException
);
615 virtual ~SelectionSupplier()
623 //--------------------------------------------------------------------
624 ::sal_Bool SAL_CALL
SelectionSupplier::select( const Any
& /*_Selection*/ ) throw (IllegalArgumentException
, RuntimeException
)
626 throw IllegalArgumentException();
627 // API bug: this should be a NoSupportException
630 //--------------------------------------------------------------------
631 Any SAL_CALL
SelectionSupplier::getSelection( ) throw (RuntimeException
)
636 //--------------------------------------------------------------------
637 void SAL_CALL
SelectionSupplier::addSelectionChangeListener( const Reference
< XSelectionChangeListener
>& /*_Listener*/ ) throw (RuntimeException
)
639 OSL_ENSURE( false, "SelectionSupplier::removeSelectionChangeListener: no support!" );
640 // API bug: this should be a NoSupportException
643 //--------------------------------------------------------------------
644 void SAL_CALL
SelectionSupplier::removeSelectionChangeListener( const Reference
< XSelectionChangeListener
>& /*_Listener*/ ) throw (RuntimeException
)
646 OSL_ENSURE( false, "SelectionSupplier::removeSelectionChangeListener: no support!" );
647 // API bug: this should be a NoSupportException
651 // -----------------------------------------------------------------------------
652 PopupMenu
* DBTreeListBox::CreateContextMenu( void )
654 ::std::auto_ptr
< PopupMenu
> pContextMenu
;
656 if ( !m_pContextMenuProvider
)
657 return pContextMenu
.release();
659 // the basic context menu
660 pContextMenu
.reset( m_pContextMenuProvider
->getContextMenu( *this ) );
661 // disable what is not available currently
662 lcl_enableEntries( pContextMenu
.get(), m_pContextMenuProvider
->getCommandController() );
664 lcl_insertMenuItemImages( *pContextMenu
, m_pContextMenuProvider
->getCommandController() );
665 // allow context menu interception
666 ::cppu::OInterfaceContainerHelper
* pInterceptors
= m_pContextMenuProvider
->getContextMenuInterceptors();
667 if ( !pInterceptors
|| !pInterceptors
->getLength() )
668 return pContextMenu
.release();
670 ContextMenuExecuteEvent aEvent
;
671 aEvent
.SourceWindow
= VCLUnoHelper::GetInterface( this );
672 aEvent
.ExecutePosition
.X
= -1;
673 aEvent
.ExecutePosition
.Y
= -1;
674 aEvent
.ActionTriggerContainer
= ::framework::ActionTriggerHelper::CreateActionTriggerContainerFromMenu(
675 m_xORB
, pContextMenu
.get(), 0 );
676 aEvent
.Selection
= new SelectionSupplier( m_pContextMenuProvider
->getCurrentSelection( *this ) );
678 ::cppu::OInterfaceIteratorHelper
aIter( *pInterceptors
);
679 bool bModifiedMenu
= false;
680 bool bAskInterceptors
= true;
681 while ( aIter
.hasMoreElements() && bAskInterceptors
)
683 Reference
< XContextMenuInterceptor
> xInterceptor( aIter
.next(), UNO_QUERY
);
684 if ( !xInterceptor
.is() )
689 ContextMenuInterceptorAction eAction
= xInterceptor
->notifyContextMenuExecute( aEvent
);
692 case ContextMenuInterceptorAction_CANCELLED
:
695 case ContextMenuInterceptorAction_EXECUTE_MODIFIED
:
696 bModifiedMenu
= true;
697 bAskInterceptors
= false;
700 case ContextMenuInterceptorAction_CONTINUE_MODIFIED
:
701 bModifiedMenu
= true;
702 bAskInterceptors
= true;
706 DBG_ERROR( "DBTreeListBox::CreateContextMenu: unexpected return value of the interceptor call!" );
708 case ContextMenuInterceptorAction_IGNORED
:
712 catch( const DisposedException
& e
)
714 if ( e
.Context
== xInterceptor
)
721 // the interceptor(s) modified the menu description => create a new PopupMenu
722 PopupMenu
* pModifiedMenu
= new PopupMenu
;
723 ::framework::ActionTriggerHelper::CreateMenuFromActionTriggerContainer(
724 pModifiedMenu
, aEvent
.ActionTriggerContainer
);
725 aEvent
.ActionTriggerContainer
.clear();
726 pContextMenu
.reset( pModifiedMenu
);
728 // the interceptors only know command URLs, but our menus primarily work
729 // with IDs -> we need to translate the commands to IDs
730 lcl_adjustMenuItemIDs( *pModifiedMenu
, m_pContextMenuProvider
->getCommandController() );
731 } // if ( bModifiedMenu )
733 return pContextMenu
.release();
736 // -----------------------------------------------------------------------------
737 void DBTreeListBox::ExcecuteContextMenuAction( USHORT _nSelectedPopupEntry
)
739 if ( m_pContextMenuProvider
&& _nSelectedPopupEntry
)
740 m_pContextMenuProvider
->getCommandController().executeChecked( _nSelectedPopupEntry
, Sequence
< PropertyValue
>() );
743 // -----------------------------------------------------------------------------
744 IMPL_LINK(DBTreeListBox
, OnTimeOut
, void*, /*EMPTY_ARG*/)
746 implStopSelectionTimer();
748 m_aSelChangeHdl
.Call( NULL
);
751 // -----------------------------------------------------------------------------
752 void DBTreeListBox::StateChanged( StateChangedType nStateChange
)
754 if ( nStateChange
== STATE_CHANGE_VISIBLE
)
755 implStopSelectionTimer();
757 // .........................................................................
759 // .........................................................................