update dev300-m58
[ooovba.git] / dbaccess / source / ui / control / dbtreelistbox.cxx
blob52886cf3c0ed8e6faf6be293b694f306cc7064ee
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: 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"
36 #endif
37 #ifndef _DBU_RESOURCE_HRC_
38 #include "dbu_resource.hrc"
39 #endif
40 #ifndef DBACCESS_UI_BROWSER_ID_HXX
41 #include "browserids.hxx"
42 #endif
43 #ifndef _DBAUI_LISTVIEWITEMS_HXX_
44 #include "listviewitems.hxx"
45 #endif
46 #ifndef _DBACCESS_UI_CALLBACKS_HXX_
47 #include "callbacks.hxx"
48 #endif
50 #ifndef _COM_SUN_STAR_DATATRANSFER_DND_XDRAGGESTURELISTENER_HDL_
51 #include <com/sun/star/datatransfer/dnd/XDragGestureListener.hdl>
52 #endif
53 #ifndef _COM_SUN_STAR_DATATRANSFER_DND_XDRAGGESTURERECOGNIZER_HPP_
54 #include <com/sun/star/datatransfer/dnd/XDragGestureRecognizer.hpp>
55 #endif
56 #ifndef _COM_SUN_STAR_UI_XCONTEXTMENUINTERCEPTOR_HPP_
57 #include <com/sun/star/ui/XContextMenuInterceptor.hpp>
58 #endif
59 #include <com/sun/star/frame/XFrame.hpp>
60 #ifndef _COM_SUN_STAR_UTIL_URL_HPP_
61 #include <com/sun/star/util/URL.hpp>
62 #endif
63 #ifndef _CPPUHELPER_IMPLBASE1_HXX_
64 #include <cppuhelper/implbase1.hxx>
65 #endif
66 #ifndef _CPPUHELPER_INTERFACECONTAINER_HXX_
67 #include <cppuhelper/interfacecontainer.hxx>
68 #endif
69 #ifndef _SV_HELP_HXX
70 #include <vcl/help.hxx>
71 #endif
72 #ifndef _DBAUI_TABLETREE_HRC_
73 #include "tabletree.hrc"
74 #endif
75 #ifndef DBAUI_ICONTROLLER_HXX
76 #include "IController.hxx"
77 #endif
78 #ifndef __FRAMEWORK_HELPER_ACTIONTRIGGERHELPER_HXX_
79 #include <framework/actiontriggerhelper.hxx>
80 #endif
81 #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
82 #include <toolkit/helper/vclunohelper.hxx>
83 #endif
84 #include <framework/imageproducer.hxx>
85 #include <vcl/svapp.hxx>
86 #include <memory>
88 // .........................................................................
89 namespace dbaui
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)
114 ,m_xORB(_rxORB)
116 DBG_CTOR(DBTreeListBox,NULL);
117 init();
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)
126 ,m_xORB(_rxORB)
128 DBG_CTOR(DBTreeListBox,NULL);
129 init();
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;
159 if ( pChilds )
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 ) )
169 // found
170 break;
172 pEntry = NULL;
176 return 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() )
213 m_aTimer.Stop();
216 // -------------------------------------------------------------------------
217 void DBTreeListBox::implStartSelectionTimer()
219 implStopSelectionTimer();
220 m_aTimer.Start();
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);
245 else
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 );
254 // redraw the entry
255 GetModel()->InvalidateEntry( pEntry );
256 return 0L;
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 );
270 // ehm - why?
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());
301 return nDropOption;
304 pParent = pDroppedEntry ? GetParent(pDroppedEntry) : NULL;
305 while ( pParent && pParent != m_pDragedEntry )
306 pParent = GetParent(pParent);
309 if ( !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());
323 return nDropOption;
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
346 EndSelection();
351 // -------------------------------------------------------------------------
352 void DBTreeListBox::RequestHelp( const HelpEvent& rHEvt )
354 if ( !m_pActionListener )
356 SvTreeListBox::RequestHelp( rHEvt );
357 return;
360 if( rHEvt.GetMode() & HELPMODE_QUICK )
362 Point aPos( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ));
363 SvLBoxEntry* pEntry = GetEntry( aPos );
364 if( pEntry )
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 );
374 return;
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)
391 switch(eFunc)
393 case KEYFUNC_CUT:
394 bHandled = ( m_aCutHandler.IsSet() && !m_aSelectedEntries.empty() );
395 if ( bHandled )
396 m_aCutHandler.Call( NULL );
397 break;
398 case KEYFUNC_COPY:
399 bHandled = ( m_aCopyHandler.IsSet() && !m_aSelectedEntries.empty() );
400 if ( bHandled )
401 m_aCopyHandler.Call( NULL );
402 break;
403 case KEYFUNC_PASTE:
404 bHandled = ( m_aPasteHandler.IsSet() && !m_aSelectedEntries.empty() );
405 if ( bHandled )
406 m_aPasteHandler.Call( NULL );
407 break;
408 case KEYFUNC_DELETE:
409 bHandled = ( m_aDeleteHandler.IsSet() && !m_aSelectedEntries.empty() );
410 if ( bHandled )
411 m_aDeleteHandler.Call( NULL );
412 break;
413 default:
414 break;
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"
430 // and
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
439 // applications.
441 // 2002-12-02 - 105831 - fs@openoffice.org
444 if ( !bHandled )
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
473 return nResult == 0;
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);
489 return 0;
492 //------------------------------------------------------------------------------
493 IMPL_LINK( DBTreeListBox, ScrollDownHdl, SvTreeListBox*, /*pBox*/ )
495 scrollWindow(this,m_aMousePos,sal_False);
496 return 0;
498 // -----------------------------------------------------------------------------
499 namespace
501 void lcl_enableEntries( PopupMenu* _pPopup, IController& _rController )
503 if ( !_pPopup )
504 return;
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);
513 if ( pSubPopUp )
515 lcl_enableEntries( pSubPopUp, _rController );
516 _pPopup->EnableItem(nId,pSubPopUp->HasValidEntries());
518 else
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 // -----------------------------------------------------------------------------
534 namespace
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 )
543 continue;
545 USHORT nId = _rMenu.GetItemId(pos);
546 String aCommand = _rMenu.GetItemCommand( nId );
547 PopupMenu* pPopup = _rMenu.GetPopupMenu( nId );
548 if ( pPopup )
550 lcl_adjustMenuItemIDs( *pPopup, _rCommandController );
551 continue;
552 } // if ( pPopup )
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 )
581 continue;
583 USHORT nId = _rMenu.GetItemId(pos);
584 String aCommand = _rMenu.GetItemCommand( nId );
585 PopupMenu* pPopup = _rMenu.GetPopupMenu( nId );
586 if ( pPopup )
588 lcl_insertMenuItemImages( *pPopup, _rCommandController );
589 continue;
590 } // if ( pPopup )
592 if ( xFrame.is() )
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
603 public:
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);
614 protected:
615 virtual ~SelectionSupplier()
619 private:
620 Any m_aSelection;
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)
633 return m_aSelection;
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() );
663 // set images
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() )
685 continue;
689 ContextMenuInterceptorAction eAction = xInterceptor->notifyContextMenuExecute( aEvent );
690 switch ( eAction )
692 case ContextMenuInterceptorAction_CANCELLED:
693 return NULL;
695 case ContextMenuInterceptorAction_EXECUTE_MODIFIED:
696 bModifiedMenu = true;
697 bAskInterceptors = false;
698 break;
700 case ContextMenuInterceptorAction_CONTINUE_MODIFIED:
701 bModifiedMenu = true;
702 bAskInterceptors = true;
703 break;
705 default:
706 DBG_ERROR( "DBTreeListBox::CreateContextMenu: unexpected return value of the interceptor call!" );
708 case ContextMenuInterceptorAction_IGNORED:
709 break;
712 catch( const DisposedException& e )
714 if ( e.Context == xInterceptor )
715 aIter.remove();
719 if ( bModifiedMenu )
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 );
749 return 0L;
751 // -----------------------------------------------------------------------------
752 void DBTreeListBox::StateChanged( StateChangedType nStateChange )
754 if ( nStateChange == STATE_CHANGE_VISIBLE )
755 implStopSelectionTimer();
757 // .........................................................................
758 } // namespace dbaui
759 // .........................................................................