1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "dbtreelistbox.hxx"
21 #include "dbu_resource.hrc"
22 #include "browserids.hxx"
23 #include "listviewitems.hxx"
24 #include "callbacks.hxx"
26 #include <com/sun/star/datatransfer/dnd/XDragGestureListener.hpp>
27 #include <com/sun/star/datatransfer/dnd/XDragGestureRecognizer.hpp>
28 #include <com/sun/star/ui/XContextMenuInterceptor.hpp>
29 #include <com/sun/star/frame/XFrame.hpp>
30 #include <com/sun/star/util/URL.hpp>
31 #include <cppuhelper/implbase1.hxx>
32 #include <cppuhelper/interfacecontainer.hxx>
33 #include <vcl/help.hxx>
34 #include <dbaccess/IController.hxx>
35 #include <framework/actiontriggerhelper.hxx>
36 #include <toolkit/helper/vclunohelper.hxx>
37 #include <framework/imageproducer.hxx>
38 #include <vcl/svapp.hxx>
39 #include "svtools/treelistentry.hxx"
46 using namespace ::com::sun::star
;
47 using namespace ::com::sun::star::uno
;
48 using namespace ::com::sun::star::beans
;
49 using namespace ::com::sun::star::lang
;
50 using namespace ::com::sun::star::datatransfer
;
51 using namespace ::com::sun::star::frame
;
52 using namespace ::com::sun::star::ui
;
53 using namespace ::com::sun::star::view
;
55 #define SPACEBETWEENENTRIES 4
56 // class DBTreeListBox
57 DBTreeListBox::DBTreeListBox( vcl::Window
* pParent
, WinBits nWinStyle
,bool _bHandleEnterKey
)
58 :SvTreeListBox(pParent
,nWinStyle
)
60 ,m_pActionListener(NULL
)
61 ,m_pContextMenuProvider( NULL
)
62 ,m_bHandleEnterKey(_bHandleEnterKey
)
67 void DBTreeListBox::init()
69 sal_uInt16 nSize
= SPACEBETWEENENTRIES
;
70 SetSpaceBetweenEntries(nSize
);
72 m_aTimer
.SetTimeout(900);
73 m_aTimer
.SetTimeoutHdl(LINK(this, DBTreeListBox
, OnTimeOut
));
75 m_aScrollHelper
.setUpScrollMethod( LINK(this, DBTreeListBox
, ScrollUpHdl
) );
76 m_aScrollHelper
.setDownScrollMethod( LINK(this, DBTreeListBox
, ScrollDownHdl
) );
78 SetNodeDefaultImages( );
80 EnableContextMenuHandling();
82 SetStyle( GetStyle() | WB_QUICK_SEARCH
);
85 DBTreeListBox::~DBTreeListBox()
90 void DBTreeListBox::dispose()
92 implStopSelectionTimer();
93 SvTreeListBox::dispose();
96 SvTreeListEntry
* DBTreeListBox::GetEntryPosByName( const OUString
& aName
, SvTreeListEntry
* pStart
, const IEntryFilter
* _pFilter
) const
98 SvTreeList
* myModel
= GetModel();
99 std::pair
<SvTreeListEntries::iterator
,SvTreeListEntries::iterator
> aIters
=
100 myModel
->GetChildIterators(pStart
);
102 SvTreeListEntry
* pEntry
= NULL
;
103 SvTreeListEntries::iterator it
= aIters
.first
, itEnd
= aIters
.second
;
104 for (; it
!= itEnd
; ++it
)
107 const SvLBoxString
* pItem
= static_cast<const SvLBoxString
*>(
108 pEntry
->GetFirstItem(SV_ITEM_ID_LBOXSTRING
));
110 if (pItem
&& pItem
->GetText().equals(aName
))
112 if (!_pFilter
|| _pFilter
->includeEntry(pEntry
))
122 void DBTreeListBox::EnableExpandHandler(SvTreeListEntry
* _pEntry
)
124 LINK(this, DBTreeListBox
, OnResetEntry
).Call(_pEntry
);
127 void DBTreeListBox::RequestingChildren( SvTreeListEntry
* pParent
)
129 if (m_aPreExpandHandler
.IsSet())
131 if (!m_aPreExpandHandler
.Call(pParent
))
133 // an error occurred. The method calling us will reset the entry flags, so it can't be expanded again.
134 // But we want that the user may do a second try (i.e. because he misstypes a password in this try), so
135 // we have to reset these flags controlling the expand ability
136 PostUserEvent(LINK(this, DBTreeListBox
, OnResetEntry
), pParent
, true);
141 void DBTreeListBox::InitEntry(SvTreeListEntry
* _pEntry
, const OUString
& aStr
, const Image
& _rCollEntryBmp
, const Image
& _rExpEntryBmp
, SvLBoxButtonKind eButtonKind
)
143 SvTreeListBox::InitEntry( _pEntry
, aStr
, _rCollEntryBmp
,_rExpEntryBmp
, eButtonKind
);
144 SvLBoxItem
* pTextItem(_pEntry
->GetFirstItem(SV_ITEM_ID_LBOXSTRING
));
145 SvLBoxString
* pString
= new OBoldListboxString( _pEntry
, 0, aStr
);
146 _pEntry
->ReplaceItem( pString
,_pEntry
->GetPos(pTextItem
));
149 void DBTreeListBox::implStopSelectionTimer()
151 if ( m_aTimer
.IsActive() )
155 void DBTreeListBox::implStartSelectionTimer()
157 implStopSelectionTimer();
161 void DBTreeListBox::DeselectHdl()
163 m_aSelectedEntries
.erase( GetHdlEntry() );
164 SvTreeListBox::DeselectHdl();
165 implStartSelectionTimer();
168 void DBTreeListBox::SelectHdl()
170 m_aSelectedEntries
.insert( GetHdlEntry() );
171 SvTreeListBox::SelectHdl();
172 implStartSelectionTimer();
175 void DBTreeListBox::MouseButtonDown( const MouseEvent
& rMEvt
)
177 bool bHitEmptySpace
= (NULL
== GetEntry(rMEvt
.GetPosPixel(), true));
178 if (bHitEmptySpace
&& (rMEvt
.GetClicks() == 2) && rMEvt
.IsMod1())
179 Control::MouseButtonDown(rMEvt
);
181 SvTreeListBox::MouseButtonDown(rMEvt
);
184 IMPL_LINK(DBTreeListBox
, OnResetEntry
, SvTreeListEntry
*, pEntry
)
186 // set the flag which allows if the entry can be expanded
187 pEntry
->SetFlags( (pEntry
->GetFlags() & ~SvTLEntryFlags(SvTLEntryFlags::NO_NODEBMP
| SvTLEntryFlags::HAD_CHILDREN
)) | SvTLEntryFlags::CHILDREN_ON_DEMAND
);
189 GetModel()->InvalidateEntry( pEntry
);
193 void DBTreeListBox::ModelHasEntryInvalidated( SvTreeListEntry
* _pEntry
)
195 SvTreeListBox::ModelHasEntryInvalidated( _pEntry
);
197 SvTreeListEntry
* pLBEntry
= static_cast<SvTreeListEntry
*>(_pEntry
);
198 if (m_aSelectedEntries
.find(pLBEntry
) != m_aSelectedEntries
.end())
200 SvLBoxItem
* pTextItem
= pLBEntry
->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING
);
201 if ( pTextItem
&& !static_cast< OBoldListboxString
* >( pTextItem
)->isEmphasized() )
203 implStopSelectionTimer();
204 m_aSelectedEntries
.erase(pLBEntry
);
210 void DBTreeListBox::ModelHasRemoved( SvTreeListEntry
* _pEntry
)
212 SvTreeListBox::ModelHasRemoved(_pEntry
);
213 SvTreeListEntry
* pLBEntry
= static_cast<SvTreeListEntry
*>(_pEntry
);
214 if (m_aSelectedEntries
.find(pLBEntry
) != m_aSelectedEntries
.end())
216 implStopSelectionTimer();
217 m_aSelectedEntries
.erase(pLBEntry
);
221 sal_Int8
DBTreeListBox::AcceptDrop( const AcceptDropEvent
& _rEvt
)
223 sal_Int8 nDropOption
= DND_ACTION_NONE
;
224 if ( m_pActionListener
)
226 SvTreeListEntry
* pDroppedEntry
= GetEntry(_rEvt
.maPosPixel
);
227 // check if drag is on child entry, which is not allowed
228 SvTreeListEntry
* pParent
= NULL
;
229 if ( _rEvt
.mnAction
& DND_ACTION_MOVE
)
231 if ( !m_pDragedEntry
) // no entry to move
233 nDropOption
= m_pActionListener
->queryDrop( _rEvt
, GetDataFlavorExVector() );
234 m_aMousePos
= _rEvt
.maPosPixel
;
235 m_aScrollHelper
.scroll(m_aMousePos
,GetOutputSizePixel());
239 pParent
= pDroppedEntry
? GetParent(pDroppedEntry
) : NULL
;
240 while ( pParent
&& pParent
!= m_pDragedEntry
)
241 pParent
= GetParent(pParent
);
246 nDropOption
= m_pActionListener
->queryDrop( _rEvt
, GetDataFlavorExVector() );
247 // check if move is allowed
248 if ( nDropOption
& DND_ACTION_MOVE
)
250 if ( m_pDragedEntry
== pDroppedEntry
|| GetEntryPosByName(GetEntryText(m_pDragedEntry
),pDroppedEntry
) )
251 nDropOption
= nDropOption
& ~DND_ACTION_MOVE
;//DND_ACTION_NONE;
253 m_aMousePos
= _rEvt
.maPosPixel
;
254 m_aScrollHelper
.scroll(m_aMousePos
,GetOutputSizePixel());
261 sal_Int8
DBTreeListBox::ExecuteDrop( const ExecuteDropEvent
& _rEvt
)
263 if ( m_pActionListener
)
264 return m_pActionListener
->executeDrop( _rEvt
);
266 return DND_ACTION_NONE
;
269 void DBTreeListBox::StartDrag( sal_Int8 _nAction
, const Point
& _rPosPixel
)
271 if ( m_pActionListener
)
273 m_pDragedEntry
= GetEntry(_rPosPixel
);
274 if ( m_pDragedEntry
&& m_pActionListener
->requestDrag( _nAction
, _rPosPixel
) )
276 // if the (asynchronous) drag started, stop the selection timer
277 implStopSelectionTimer();
278 // and stop selecting entries by simply moving the mouse
284 void DBTreeListBox::RequestHelp( const HelpEvent
& rHEvt
)
286 if ( !m_pActionListener
)
288 SvTreeListBox::RequestHelp( rHEvt
);
292 if( rHEvt
.GetMode() & HelpEventMode::QUICK
)
294 Point
aPos( ScreenToOutputPixel( rHEvt
.GetMousePosPixel() ));
295 SvTreeListEntry
* pEntry
= GetEntry( aPos
);
298 OUString sQuickHelpText
;
299 if ( m_pActionListener
->requestQuickHelp( pEntry
, sQuickHelpText
) )
301 Size
aSize( GetOutputSizePixel().Width(), GetEntryHeight() );
302 Rectangle
aScreenRect( OutputToScreenPixel( GetEntryPosition( pEntry
) ), aSize
);
304 Help::ShowQuickHelp( this, aScreenRect
,
305 sQuickHelpText
, QuickHelpFlags::Left
| QuickHelpFlags::VCenter
);
311 SvTreeListBox::RequestHelp( rHEvt
);
314 void DBTreeListBox::KeyInput( const KeyEvent
& rKEvt
)
316 KeyFuncType eFunc
= rKEvt
.GetKeyCode().GetFunction();
317 sal_uInt16 nCode
= rKEvt
.GetKeyCode().GetCode();
318 bool bHandled
= false;
320 if(eFunc
!= KeyFuncType::DONTKNOW
)
324 case KeyFuncType::CUT
:
325 bHandled
= ( m_aCutHandler
.IsSet() && !m_aSelectedEntries
.empty() );
327 m_aCutHandler
.Call( NULL
);
329 case KeyFuncType::COPY
:
330 bHandled
= ( m_aCopyHandler
.IsSet() && !m_aSelectedEntries
.empty() );
332 m_aCopyHandler
.Call( NULL
);
334 case KeyFuncType::PASTE
:
335 bHandled
= ( m_aPasteHandler
.IsSet() && !m_aSelectedEntries
.empty() );
337 m_aPasteHandler
.Call( NULL
);
339 case KeyFuncType::DELETE
:
340 bHandled
= ( m_aDeleteHandler
.IsSet() && !m_aSelectedEntries
.empty() );
342 m_aDeleteHandler
.Call( NULL
);
349 if ( KEY_RETURN
== nCode
)
351 bHandled
= m_bHandleEnterKey
;
352 if ( m_aEnterKeyHdl
.IsSet() )
353 m_aEnterKeyHdl
.Call(this);
354 // this is a HACK. If the data source browser is opened in the "beamer", while the main frame
356 // contains a writer document, then pressing enter in the DSB would be rerouted to the writer
358 // document if we would not do this hack here.
359 // The problem is that the Writer uses RETURN as _accelerator_ (which is quite weird itself),
361 // so the SFX framework is _obligated_ to pass it to the Writer if nobody else handled it. There
363 // is no chance to distinguish between
364 // "accelerators which are to be executed if the main document has the focus"
366 // "accelerators which are always to be executed"
368 // Thus we cannot prevent the handling of this key in the writer without declaring the key event
369 // as "handled" herein.
371 // The bad thing about this approach is that it does not scale. Every other accelerator which
372 // is used by the document will raise a similar bug once somebody discovers it.
373 // If this is the case, we should discuss a real solution with the framework (SFX) and the
378 SvTreeListBox::KeyInput(rKEvt
);
381 bool DBTreeListBox::EditingEntry( SvTreeListEntry
* pEntry
, Selection
& /*_aSelection*/)
383 return m_aEditingHandler
.Call(pEntry
) != 0;
386 bool DBTreeListBox::EditedEntry( SvTreeListEntry
* pEntry
, const OUString
& rNewText
)
388 DBTreeEditedEntry aEntry
;
389 aEntry
.pEntry
= pEntry
;
390 aEntry
.aNewText
= rNewText
;
391 if(m_aEditedHandler
.Call(&aEntry
) != 0)
393 implStopSelectionTimer();
394 m_aSelectedEntries
.erase( pEntry
);
396 SetEntryText(pEntry
,aEntry
.aNewText
);
398 return false; // we never want that the base change our text
401 bool DBTreeListBox::DoubleClickHdl()
403 long nResult
= aDoubleClickHdl
.Call( this );
404 // continue default processing if the DoubleClickHandler didn't handle it
408 void scrollWindow(DBTreeListBox
* _pListBox
, const Point
& _rPos
,bool _bUp
)
410 SvTreeListEntry
* pEntry
= _pListBox
->GetEntry( _rPos
);
411 if( pEntry
&& pEntry
!= _pListBox
->Last() )
413 _pListBox
->ScrollOutputArea( _bUp
? -1 : 1 );
417 IMPL_LINK( DBTreeListBox
, ScrollUpHdl
, SvTreeListBox
*, /*pBox*/ )
419 scrollWindow(this,m_aMousePos
,true);
423 IMPL_LINK( DBTreeListBox
, ScrollDownHdl
, SvTreeListBox
*, /*pBox*/ )
425 scrollWindow(this,m_aMousePos
,false);
431 void lcl_enableEntries( PopupMenu
* _pPopup
, IController
& _rController
)
436 sal_uInt16 nCount
= _pPopup
->GetItemCount();
437 for (sal_uInt16 i
=0; i
< nCount
; ++i
)
439 if ( _pPopup
->GetItemType(i
) != MenuItemType::SEPARATOR
)
441 sal_uInt16 nId
= _pPopup
->GetItemId(i
);
442 PopupMenu
* pSubPopUp
= _pPopup
->GetPopupMenu(nId
);
445 lcl_enableEntries( pSubPopUp
, _rController
);
446 _pPopup
->EnableItem(nId
,pSubPopUp
->HasValidEntries());
450 OUString
sCommandURL( _pPopup
->GetItemCommand( nId
) );
451 bool bEnabled
= sCommandURL
.isEmpty()
452 ? _rController
.isCommandEnabled( nId
)
453 : _rController
.isCommandEnabled( sCommandURL
);
454 _pPopup
->EnableItem( nId
, bEnabled
);
459 _pPopup
->RemoveDisabledEntries();
465 void lcl_adjustMenuItemIDs( Menu
& _rMenu
, IController
& _rCommandController
)
467 sal_uInt16 nCount
= _rMenu
.GetItemCount();
468 for ( sal_uInt16 pos
= 0; pos
< nCount
; ++pos
)
470 // do not adjust separators
471 if ( _rMenu
.GetItemType( pos
) == MenuItemType::SEPARATOR
)
474 sal_uInt16 nId
= _rMenu
.GetItemId(pos
);
475 OUString aCommand
= _rMenu
.GetItemCommand( nId
);
476 PopupMenu
* pPopup
= _rMenu
.GetPopupMenu( nId
);
479 lcl_adjustMenuItemIDs( *pPopup
, _rCommandController
);
483 const sal_uInt16 nCommandId
= _rCommandController
.registerCommandURL( aCommand
);
484 _rMenu
.InsertItem( nCommandId
, _rMenu
.GetItemText( nId
), _rMenu
.GetItemImage( nId
),
485 _rMenu
.GetItemBits( nId
), OString(), pos
);
487 // more things to preserve:
488 // - the help command
489 OUString sHelpURL
= _rMenu
.GetHelpCommand( nId
);
490 if ( !sHelpURL
.isEmpty() )
491 _rMenu
.SetHelpCommand( nCommandId
, sHelpURL
);
493 // remove the "old" item
494 _rMenu
.RemoveItem( pos
+1 );
497 void lcl_insertMenuItemImages( Menu
& _rMenu
, IController
& _rCommandController
)
499 uno::Reference
< frame::XController
> xController
= _rCommandController
.getXController();
500 uno::Reference
< frame::XFrame
> xFrame
;
501 if ( xController
.is() )
502 xFrame
= xController
->getFrame();
503 sal_uInt16 nCount
= _rMenu
.GetItemCount();
504 for ( sal_uInt16 pos
= 0; pos
< nCount
; ++pos
)
506 // do not adjust separators
507 if ( _rMenu
.GetItemType( pos
) == MenuItemType::SEPARATOR
)
510 sal_uInt16 nId
= _rMenu
.GetItemId(pos
);
511 OUString aCommand
= _rMenu
.GetItemCommand( nId
);
512 PopupMenu
* pPopup
= _rMenu
.GetPopupMenu( nId
);
515 lcl_insertMenuItemImages( *pPopup
, _rCommandController
);
520 _rMenu
.SetItemImage(nId
,framework::GetImageFromURL(xFrame
,aCommand
,false));
524 typedef ::cppu::WeakImplHelper1
< XSelectionSupplier
525 > SelectionSupplier_Base
;
526 class SelectionSupplier
: public SelectionSupplier_Base
529 SelectionSupplier( const Any
& _rSelection
)
530 :m_aSelection( _rSelection
)
534 virtual sal_Bool SAL_CALL
select( const Any
& xSelection
) throw (IllegalArgumentException
, RuntimeException
, std::exception
) SAL_OVERRIDE
;
535 virtual Any SAL_CALL
getSelection( ) throw (RuntimeException
, std::exception
) SAL_OVERRIDE
;
536 virtual void SAL_CALL
addSelectionChangeListener( const Reference
< XSelectionChangeListener
>& xListener
) throw (RuntimeException
, std::exception
) SAL_OVERRIDE
;
537 virtual void SAL_CALL
removeSelectionChangeListener( const Reference
< XSelectionChangeListener
>& xListener
) throw (RuntimeException
, std::exception
) SAL_OVERRIDE
;
540 virtual ~SelectionSupplier()
548 sal_Bool SAL_CALL
SelectionSupplier::select( const Any
& /*_Selection*/ ) throw (IllegalArgumentException
, RuntimeException
, std::exception
)
550 throw IllegalArgumentException();
551 // API bug: this should be a NoSupportException
554 Any SAL_CALL
SelectionSupplier::getSelection( ) throw (RuntimeException
, std::exception
)
559 void SAL_CALL
SelectionSupplier::addSelectionChangeListener( const Reference
< XSelectionChangeListener
>& /*_Listener*/ ) throw (RuntimeException
, std::exception
)
561 OSL_FAIL( "SelectionSupplier::removeSelectionChangeListener: no support!" );
562 // API bug: this should be a NoSupportException
565 void SAL_CALL
SelectionSupplier::removeSelectionChangeListener( const Reference
< XSelectionChangeListener
>& /*_Listener*/ ) throw (RuntimeException
, std::exception
)
567 OSL_FAIL( "SelectionSupplier::removeSelectionChangeListener: no support!" );
568 // API bug: this should be a NoSupportException
572 PopupMenu
* DBTreeListBox::CreateContextMenu()
574 ::std::unique_ptr
< PopupMenu
> pContextMenu
;
576 if ( !m_pContextMenuProvider
)
577 return pContextMenu
.release();
579 // the basic context menu
580 pContextMenu
.reset( m_pContextMenuProvider
->getContextMenu( *this ) );
581 // disable what is not available currently
582 lcl_enableEntries( pContextMenu
.get(), m_pContextMenuProvider
->getCommandController() );
584 lcl_insertMenuItemImages( *pContextMenu
, m_pContextMenuProvider
->getCommandController() );
585 // allow context menu interception
586 ::cppu::OInterfaceContainerHelper
* pInterceptors
= m_pContextMenuProvider
->getContextMenuInterceptors();
587 if ( !pInterceptors
|| !pInterceptors
->getLength() )
588 return pContextMenu
.release();
590 ContextMenuExecuteEvent aEvent
;
591 aEvent
.SourceWindow
= VCLUnoHelper::GetInterface( this );
592 aEvent
.ExecutePosition
.X
= -1;
593 aEvent
.ExecutePosition
.Y
= -1;
594 aEvent
.ActionTriggerContainer
= ::framework::ActionTriggerHelper::CreateActionTriggerContainerFromMenu(
595 pContextMenu
.get(), 0 );
596 aEvent
.Selection
= new SelectionSupplier( m_pContextMenuProvider
->getCurrentSelection( *this ) );
598 ::cppu::OInterfaceIteratorHelper
aIter( *pInterceptors
);
599 bool bModifiedMenu
= false;
600 bool bAskInterceptors
= true;
601 while ( aIter
.hasMoreElements() && bAskInterceptors
)
603 Reference
< XContextMenuInterceptor
> xInterceptor( aIter
.next(), UNO_QUERY
);
604 if ( !xInterceptor
.is() )
609 ContextMenuInterceptorAction eAction
= xInterceptor
->notifyContextMenuExecute( aEvent
);
612 case ContextMenuInterceptorAction_CANCELLED
:
615 case ContextMenuInterceptorAction_EXECUTE_MODIFIED
:
616 bModifiedMenu
= true;
617 bAskInterceptors
= false;
620 case ContextMenuInterceptorAction_CONTINUE_MODIFIED
:
621 bModifiedMenu
= true;
622 bAskInterceptors
= true;
626 OSL_FAIL( "DBTreeListBox::CreateContextMenu: unexpected return value of the interceptor call!" );
628 case ContextMenuInterceptorAction_IGNORED
:
632 catch( const DisposedException
& e
)
634 if ( e
.Context
== xInterceptor
)
641 // the interceptor(s) modified the menu description => create a new PopupMenu
642 PopupMenu
* pModifiedMenu
= new PopupMenu
;
643 ::framework::ActionTriggerHelper::CreateMenuFromActionTriggerContainer(
644 pModifiedMenu
, aEvent
.ActionTriggerContainer
);
645 aEvent
.ActionTriggerContainer
.clear();
646 pContextMenu
.reset( pModifiedMenu
);
648 // the interceptors only know command URLs, but our menus primarily work
649 // with IDs -> we need to translate the commands to IDs
650 lcl_adjustMenuItemIDs( *pModifiedMenu
, m_pContextMenuProvider
->getCommandController() );
653 return pContextMenu
.release();
656 void DBTreeListBox::ExcecuteContextMenuAction( sal_uInt16 _nSelectedPopupEntry
)
658 if ( m_pContextMenuProvider
&& _nSelectedPopupEntry
)
659 m_pContextMenuProvider
->getCommandController().executeChecked( _nSelectedPopupEntry
, Sequence
< PropertyValue
>() );
662 IMPL_LINK_NOARG_TYPED(DBTreeListBox
, OnTimeOut
, Timer
*, void)
664 implStopSelectionTimer();
666 m_aSelChangeHdl
.Call( NULL
);
669 void DBTreeListBox::StateChanged( StateChangedType nStateChange
)
671 if ( nStateChange
== StateChangedType::Visible
)
672 implStopSelectionTimer();
677 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */