LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/dbaccess/source/ui/control - dbtreelistbox.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 75 324 23.1 %
Date: 2013-07-09 Functions: 17 48 35.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      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 .
      18             :  */
      19             : 
      20             : 
      21             : #include "dbtreelistbox.hxx"
      22             : #include "dbu_resource.hrc"
      23             : #include "browserids.hxx"
      24             : #include "listviewitems.hxx"
      25             : #include "callbacks.hxx"
      26             : 
      27             : #include <com/sun/star/datatransfer/dnd/XDragGestureListener.hpp>
      28             : #include <com/sun/star/datatransfer/dnd/XDragGestureRecognizer.hpp>
      29             : #include <com/sun/star/ui/XContextMenuInterceptor.hpp>
      30             : #include <com/sun/star/frame/XFrame.hpp>
      31             : #include <com/sun/star/util/URL.hpp>
      32             : #include <cppuhelper/implbase1.hxx>
      33             : #include <cppuhelper/interfacecontainer.hxx>
      34             : #include <vcl/help.hxx>
      35             : #include <dbaccess/IController.hxx>
      36             : #include <framework/actiontriggerhelper.hxx>
      37             : #include <toolkit/helper/vclunohelper.hxx>
      38             : #include <framework/imageproducer.hxx>
      39             : #include <vcl/svapp.hxx>
      40             : #include "svtools/treelistentry.hxx"
      41             : 
      42             : #include <memory>
      43             : 
      44             : // .........................................................................
      45             : namespace dbaui
      46             : {
      47             : // .........................................................................
      48             : 
      49             : using namespace ::com::sun::star;
      50             : using namespace ::com::sun::star::uno;
      51             : using namespace ::com::sun::star::beans;
      52             : using namespace ::com::sun::star::lang;
      53             : using namespace ::com::sun::star::datatransfer;
      54             : using namespace ::com::sun::star::frame;
      55             : using namespace ::com::sun::star::ui;
      56             : using namespace ::com::sun::star::view;
      57             : 
      58             : DBG_NAME(DBTreeListBox)
      59             : #define SPACEBETWEENENTRIES     4
      60             : //========================================================================
      61             : // class DBTreeListBox
      62             : //========================================================================
      63             : //------------------------------------------------------------------------
      64           1 : DBTreeListBox::DBTreeListBox( Window* pParent, WinBits nWinStyle ,sal_Bool _bHandleEnterKey)
      65             :     :SvTreeListBox(pParent,nWinStyle)
      66             :     ,m_pDragedEntry(NULL)
      67             :     ,m_pActionListener(NULL)
      68             :     ,m_pContextMenuProvider( NULL )
      69           1 :     ,m_bHandleEnterKey(_bHandleEnterKey)
      70             : {
      71             :     DBG_CTOR(DBTreeListBox,NULL);
      72           1 :     init();
      73           1 : }
      74             : // -----------------------------------------------------------------------------
      75           0 : DBTreeListBox::DBTreeListBox( Window* pParent, const ResId& rResId,sal_Bool _bHandleEnterKey)
      76             :     :SvTreeListBox(pParent,rResId)
      77             :     ,m_pDragedEntry(NULL)
      78             :     ,m_pActionListener(NULL)
      79             :     ,m_pContextMenuProvider( NULL )
      80           0 :     ,m_bHandleEnterKey(_bHandleEnterKey)
      81             : {
      82             :     DBG_CTOR(DBTreeListBox,NULL);
      83           0 :     init();
      84           0 : }
      85             : // -----------------------------------------------------------------------------
      86           1 : void DBTreeListBox::init()
      87             : {
      88           1 :     sal_uInt16 nSize = SPACEBETWEENENTRIES;
      89           1 :     SetSpaceBetweenEntries(nSize);
      90             : 
      91           1 :     m_aTimer.SetTimeout(900);
      92           1 :     m_aTimer.SetTimeoutHdl(LINK(this, DBTreeListBox, OnTimeOut));
      93             : 
      94           1 :     m_aScrollHelper.setUpScrollMethod( LINK(this, DBTreeListBox, ScrollUpHdl) );
      95           1 :     m_aScrollHelper.setDownScrollMethod( LINK(this, DBTreeListBox, ScrollDownHdl) );
      96             : 
      97           1 :     SetNodeDefaultImages( );
      98             : 
      99           1 :     EnableContextMenuHandling();
     100             : 
     101           1 :     SetStyle( GetStyle() | WB_QUICK_SEARCH );
     102           1 : }
     103             : //------------------------------------------------------------------------
     104           3 : DBTreeListBox::~DBTreeListBox()
     105             : {
     106             :     DBG_DTOR(DBTreeListBox,NULL);
     107           1 :     implStopSelectionTimer();
     108           2 : }
     109             : //------------------------------------------------------------------------
     110           4 : SvTreeListEntry* DBTreeListBox::GetEntryPosByName( const String& aName, SvTreeListEntry* pStart, const IEntryFilter* _pFilter ) const
     111             : {
     112           4 :     SvTreeList* myModel = GetModel();
     113             :     std::pair<SvTreeListEntries::iterator,SvTreeListEntries::iterator> aIters =
     114           4 :         myModel->GetChildIterators(pStart);
     115             : 
     116           4 :     SvTreeListEntry* pEntry = NULL;
     117           4 :     SvTreeListEntries::iterator it = aIters.first, itEnd = aIters.second;
     118           5 :     for (; it != itEnd; ++it)
     119             :     {
     120           3 :         pEntry = &(*it);
     121             :         const SvLBoxString* pItem = static_cast<const SvLBoxString*>(
     122           3 :             pEntry->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
     123             : 
     124           3 :         if (pItem && pItem->GetText().equals(aName))
     125             :         {
     126           2 :             if (!_pFilter || _pFilter->includeEntry(pEntry))
     127             :                 // found
     128           2 :                 break;
     129             :         }
     130           1 :         pEntry = NULL;
     131             :     }
     132             : 
     133           4 :     return pEntry;
     134             : }
     135             : 
     136             : // -------------------------------------------------------------------------
     137           0 : void DBTreeListBox::EnableExpandHandler(SvTreeListEntry* _pEntry)
     138             : {
     139           0 :     LINK(this, DBTreeListBox, OnResetEntry).Call(_pEntry);
     140           0 : }
     141             : 
     142             : // -------------------------------------------------------------------------
     143           1 : void DBTreeListBox::RequestingChildren( SvTreeListEntry* pParent )
     144             : {
     145           1 :     if (m_aPreExpandHandler.IsSet())
     146             :     {
     147           1 :         if (!m_aPreExpandHandler.Call(pParent))
     148             :         {
     149             :             // an error occurred. The method calling us will reset the entry flags, so it can't be expanded again.
     150             :             // But we want that the user may do a second try (i.e. because he misstypes a password in this try), so
     151             :             // we have to reset these flags controlling the expand ability
     152           0 :             PostUserEvent(LINK(this, DBTreeListBox, OnResetEntry), pParent);
     153             :         }
     154             :     }
     155           1 : }
     156             : 
     157             : // -------------------------------------------------------------------------
     158           4 : void DBTreeListBox::InitEntry(SvTreeListEntry* _pEntry, const OUString& aStr, const Image& _rCollEntryBmp, const Image& _rExpEntryBmp, SvLBoxButtonKind eButtonKind)
     159             : {
     160           4 :     SvTreeListBox::InitEntry( _pEntry, aStr, _rCollEntryBmp,_rExpEntryBmp, eButtonKind);
     161           4 :     SvLBoxItem* pTextItem(_pEntry->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
     162           4 :     SvLBoxString* pString = new OBoldListboxString( _pEntry, 0, aStr );
     163           4 :     _pEntry->ReplaceItem( pString,_pEntry->GetPos(pTextItem));
     164           4 : }
     165             : 
     166             : // -------------------------------------------------------------------------
     167           6 : void DBTreeListBox::implStopSelectionTimer()
     168             : {
     169           6 :     if ( m_aTimer.IsActive() )
     170           2 :         m_aTimer.Stop();
     171           6 : }
     172             : 
     173             : // -------------------------------------------------------------------------
     174           3 : void DBTreeListBox::implStartSelectionTimer()
     175             : {
     176           3 :     implStopSelectionTimer();
     177           3 :     m_aTimer.Start();
     178           3 : }
     179             : 
     180             : // -----------------------------------------------------------------------------
     181             : 
     182           1 : void DBTreeListBox::DeselectHdl()
     183             : {
     184           1 :     m_aSelectedEntries.erase( GetHdlEntry() );
     185           1 :     SvTreeListBox::DeselectHdl();
     186           1 :     implStartSelectionTimer();
     187           1 : }
     188             : // -------------------------------------------------------------------------
     189           2 : void DBTreeListBox::SelectHdl()
     190             : {
     191           2 :     m_aSelectedEntries.insert( GetHdlEntry() );
     192           2 :     SvTreeListBox::SelectHdl();
     193           2 :     implStartSelectionTimer();
     194           2 : }
     195             : 
     196             : // -------------------------------------------------------------------------
     197           0 : void DBTreeListBox::MouseButtonDown( const MouseEvent& rMEvt )
     198             : {
     199           0 :     sal_Bool bHitEmptySpace = (NULL == GetEntry(rMEvt.GetPosPixel(), sal_True));
     200           0 :     if (bHitEmptySpace && (rMEvt.GetClicks() == 2) && rMEvt.IsMod1())
     201           0 :         Control::MouseButtonDown(rMEvt);
     202             :     else
     203           0 :         SvTreeListBox::MouseButtonDown(rMEvt);
     204           0 : }
     205             : 
     206             : // -------------------------------------------------------------------------
     207           0 : IMPL_LINK(DBTreeListBox, OnResetEntry, SvTreeListEntry*, pEntry)
     208             : {
     209             :     // set the flag which allows if the entry can be expanded
     210           0 :     pEntry->SetFlags( (pEntry->GetFlags() & ~(SV_ENTRYFLAG_NO_NODEBMP | SV_ENTRYFLAG_HAD_CHILDREN)) | SV_ENTRYFLAG_CHILDREN_ON_DEMAND );
     211             :     // redraw the entry
     212           0 :     GetModel()->InvalidateEntry( pEntry );
     213           0 :     return 0L;
     214             : }
     215             : // -----------------------------------------------------------------------------
     216           7 : void DBTreeListBox::ModelHasEntryInvalidated( SvTreeListEntry* _pEntry )
     217             : {
     218           7 :     SvTreeListBox::ModelHasEntryInvalidated( _pEntry );
     219             : 
     220           7 :     SvTreeListEntry* pLBEntry = static_cast<SvTreeListEntry*>(_pEntry);
     221           7 :     if (m_aSelectedEntries.find(pLBEntry) != m_aSelectedEntries.end())
     222             :     {
     223           1 :         SvLBoxItem* pTextItem = pLBEntry->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING);
     224           1 :         if ( pTextItem && !static_cast< OBoldListboxString* >( pTextItem )->isEmphasized() )
     225             :         {
     226           0 :             implStopSelectionTimer();
     227           0 :             m_aSelectedEntries.erase(pLBEntry);
     228             :                 // ehm - why?
     229             :         }
     230             :     }
     231           7 : }
     232             : // -------------------------------------------------------------------------
     233           0 : void DBTreeListBox::ModelHasRemoved( SvTreeListEntry* _pEntry )
     234             : {
     235           0 :     SvTreeListBox::ModelHasRemoved(_pEntry);
     236           0 :     SvTreeListEntry* pLBEntry = static_cast<SvTreeListEntry*>(_pEntry);
     237           0 :     if (m_aSelectedEntries.find(pLBEntry) != m_aSelectedEntries.end())
     238             :     {
     239           0 :         implStopSelectionTimer();
     240           0 :         m_aSelectedEntries.erase(pLBEntry);
     241             :     }
     242           0 : }
     243             : 
     244             : // -------------------------------------------------------------------------
     245           0 : sal_Int8 DBTreeListBox::AcceptDrop( const AcceptDropEvent& _rEvt )
     246             : {
     247           0 :     sal_Int8 nDropOption = DND_ACTION_NONE;
     248           0 :     if ( m_pActionListener )
     249             :     {
     250           0 :         SvTreeListEntry* pDroppedEntry = GetEntry(_rEvt.maPosPixel);
     251             :         // check if drag is on child entry, which is not allowed
     252           0 :         SvTreeListEntry* pParent = NULL;
     253           0 :         if ( _rEvt.mnAction & DND_ACTION_MOVE )
     254             :         {
     255           0 :             if ( !m_pDragedEntry ) // no entry to move
     256             :             {
     257           0 :                 nDropOption = m_pActionListener->queryDrop( _rEvt, GetDataFlavorExVector() );
     258           0 :                 m_aMousePos = _rEvt.maPosPixel;
     259           0 :                 m_aScrollHelper.scroll(m_aMousePos,GetOutputSizePixel());
     260           0 :                 return nDropOption;
     261             :             }
     262             : 
     263           0 :             pParent = pDroppedEntry ? GetParent(pDroppedEntry) : NULL;
     264           0 :             while ( pParent && pParent != m_pDragedEntry )
     265           0 :                 pParent = GetParent(pParent);
     266             :         }
     267             : 
     268           0 :         if ( !pParent )
     269             :         {
     270           0 :             nDropOption = m_pActionListener->queryDrop( _rEvt, GetDataFlavorExVector() );
     271             :             // check if move is allowed
     272           0 :             if ( nDropOption & DND_ACTION_MOVE )
     273             :             {
     274           0 :                 if ( m_pDragedEntry == pDroppedEntry || GetEntryPosByName(GetEntryText(m_pDragedEntry),pDroppedEntry) )
     275           0 :                     nDropOption = nDropOption & ~DND_ACTION_MOVE;//DND_ACTION_NONE;
     276             :             }
     277           0 :             m_aMousePos = _rEvt.maPosPixel;
     278           0 :             m_aScrollHelper.scroll(m_aMousePos,GetOutputSizePixel());
     279             :         }
     280             :     }
     281             : 
     282           0 :     return nDropOption;
     283             : }
     284             : 
     285             : // -------------------------------------------------------------------------
     286           0 : sal_Int8 DBTreeListBox::ExecuteDrop( const ExecuteDropEvent& _rEvt )
     287             : {
     288           0 :     if ( m_pActionListener )
     289           0 :         return m_pActionListener->executeDrop( _rEvt );
     290             : 
     291           0 :     return DND_ACTION_NONE;
     292             : }
     293             : 
     294             : // -------------------------------------------------------------------------
     295           0 : void DBTreeListBox::StartDrag( sal_Int8 _nAction, const Point& _rPosPixel )
     296             : {
     297           0 :     if ( m_pActionListener )
     298             :     {
     299           0 :         m_pDragedEntry = GetEntry(_rPosPixel);
     300           0 :         if ( m_pDragedEntry && m_pActionListener->requestDrag( _nAction, _rPosPixel ) )
     301             :         {
     302             :             // if the (asynchronous) drag started, stop the selection timer
     303           0 :             implStopSelectionTimer();
     304             :             // and stop selecting entries by simply moving the mouse
     305           0 :             EndSelection();
     306             :         }
     307             :     }
     308           0 : }
     309             : 
     310             : // -------------------------------------------------------------------------
     311           0 : void DBTreeListBox::RequestHelp( const HelpEvent& rHEvt )
     312             : {
     313           0 :     if ( !m_pActionListener )
     314             :     {
     315           0 :         SvTreeListBox::RequestHelp( rHEvt );
     316           0 :         return;
     317             :     }
     318             : 
     319           0 :     if( rHEvt.GetMode() & HELPMODE_QUICK )
     320             :     {
     321           0 :         Point aPos( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ));
     322           0 :         SvTreeListEntry* pEntry = GetEntry( aPos );
     323           0 :         if( pEntry )
     324             :         {
     325           0 :             OUString sQuickHelpText;
     326           0 :             if ( m_pActionListener->requestQuickHelp( pEntry, sQuickHelpText ) )
     327             :             {
     328           0 :                 Size aSize( GetOutputSizePixel().Width(), GetEntryHeight() );
     329           0 :                 Rectangle aScreenRect( OutputToScreenPixel( GetEntryPosition( pEntry ) ), aSize );
     330             : 
     331             :                 Help::ShowQuickHelp( this, aScreenRect,
     332           0 :                                      sQuickHelpText, QUICKHELP_LEFT | QUICKHELP_VCENTER );
     333           0 :                 return;
     334           0 :             }
     335             :         }
     336             :     }
     337             : 
     338           0 :     SvTreeListBox::RequestHelp( rHEvt );
     339             : }
     340             : 
     341             : // -----------------------------------------------------------------------------
     342           0 : void DBTreeListBox::KeyInput( const KeyEvent& rKEvt )
     343             : {
     344           0 :     KeyFuncType eFunc = rKEvt.GetKeyCode().GetFunction();
     345           0 :     sal_uInt16      nCode = rKEvt.GetKeyCode().GetCode();
     346           0 :     sal_Bool bHandled = sal_False;
     347             : 
     348           0 :     if(eFunc != KEYFUNC_DONTKNOW)
     349             :     {
     350           0 :         switch(eFunc)
     351             :         {
     352             :             case KEYFUNC_CUT:
     353           0 :                 bHandled = ( m_aCutHandler.IsSet() && !m_aSelectedEntries.empty() );
     354           0 :                 if ( bHandled )
     355           0 :                     m_aCutHandler.Call( NULL );
     356           0 :                 break;
     357             :             case KEYFUNC_COPY:
     358           0 :                 bHandled = ( m_aCopyHandler.IsSet() && !m_aSelectedEntries.empty() );
     359           0 :                 if ( bHandled )
     360           0 :                     m_aCopyHandler.Call( NULL );
     361           0 :                 break;
     362             :             case KEYFUNC_PASTE:
     363           0 :                 bHandled = ( m_aPasteHandler.IsSet() && !m_aSelectedEntries.empty() );
     364           0 :                 if ( bHandled )
     365           0 :                     m_aPasteHandler.Call( NULL );
     366           0 :                 break;
     367             :             case KEYFUNC_DELETE:
     368           0 :                 bHandled = ( m_aDeleteHandler.IsSet() && !m_aSelectedEntries.empty() );
     369           0 :                 if ( bHandled )
     370           0 :                     m_aDeleteHandler.Call( NULL );
     371           0 :                 break;
     372             :             default:
     373           0 :                 break;
     374             :         }
     375             :     }
     376             : 
     377           0 :     if ( KEY_RETURN == nCode )
     378             :     {
     379           0 :         bHandled = m_bHandleEnterKey;
     380           0 :         if ( m_aEnterKeyHdl.IsSet() )
     381           0 :             m_aEnterKeyHdl.Call(this);
     382             :         // this is a HACK. If the data source browser is opened in the "beamer", while the main frame
     383             :         // contains a writer document, then pressing enter in the DSB would be rerouted to the writer
     384             :         // document if we would not do this hack here.
     385             :         // The problem is that the Writer uses RETURN as _accelerator_ (which is quite weird itself),
     386             :         // so the SFX framework is _obligated_ to pass it to the Writer if nobody else handled it. There
     387             :         // is no chance to distinguish between
     388             :         //   "accelerators which are to be executed if the main document has the focus"
     389             :         // and
     390             :         //   "accelerators which are always to be executed"
     391             :         //
     392             :         // Thus we cannot prevent the handling of this key in the writer without declaring the key event
     393             :         // as "handled" herein.
     394             :         //
     395             :         // The bad thing about this approach is that it does not scale. Every other accelerator which
     396             :         // is used by the document will raise a similar bug once somebody discovers it.
     397             :         // If this is the case, we should discuss a real solution with the framework (SFX) and the
     398             :         // applications.
     399             :     }
     400             : 
     401           0 :     if ( !bHandled )
     402           0 :         SvTreeListBox::KeyInput(rKEvt);
     403           0 : }
     404             : // -----------------------------------------------------------------------------
     405           0 : sal_Bool DBTreeListBox::EditingEntry( SvTreeListEntry* pEntry, Selection& /*_aSelection*/)
     406             : {
     407           0 :     return m_aEditingHandler.Call(pEntry) != 0;
     408             : }
     409             : // -----------------------------------------------------------------------------
     410           0 : sal_Bool DBTreeListBox::EditedEntry( SvTreeListEntry* pEntry, const OUString& rNewText )
     411             : {
     412           0 :     DBTreeEditedEntry aEntry;
     413           0 :     aEntry.pEntry = pEntry;
     414           0 :     aEntry.aNewText = rNewText;
     415           0 :     if(m_aEditedHandler.Call(&aEntry) != 0)
     416             :     {
     417           0 :         implStopSelectionTimer();
     418           0 :         m_aSelectedEntries.erase( pEntry );
     419             :     }
     420           0 :     SetEntryText(pEntry,aEntry.aNewText);
     421             : 
     422           0 :     return sal_False;  // we never want that the base change our text
     423             : }
     424             : 
     425             : // -----------------------------------------------------------------------------
     426           0 : sal_Bool DBTreeListBox::DoubleClickHdl()
     427             : {
     428           0 :     long nResult = aDoubleClickHdl.Call( this );
     429             :     // continue default processing if the DoubleClickHandler didn't handle it
     430           0 :     return nResult == 0;
     431             : }
     432             : 
     433             : // -----------------------------------------------------------------------------
     434           0 : void scrollWindow(DBTreeListBox* _pListBox, const Point& _rPos,sal_Bool _bUp)
     435             : {
     436           0 :     SvTreeListEntry* pEntry = _pListBox->GetEntry( _rPos );
     437           0 :     if( pEntry && pEntry != _pListBox->Last() )
     438             :     {
     439           0 :         _pListBox->ScrollOutputArea( _bUp ? -1 : 1 );
     440             :     }
     441           0 : }
     442             : // -----------------------------------------------------------------------------
     443           0 : IMPL_LINK( DBTreeListBox, ScrollUpHdl, SvTreeListBox*, /*pBox*/ )
     444             : {
     445           0 :     scrollWindow(this,m_aMousePos,sal_True);
     446           0 :     return 0;
     447             : }
     448             : 
     449             : //------------------------------------------------------------------------------
     450           0 : IMPL_LINK( DBTreeListBox, ScrollDownHdl, SvTreeListBox*, /*pBox*/ )
     451             : {
     452           0 :     scrollWindow(this,m_aMousePos,sal_False);
     453           0 :     return 0;
     454             : }
     455             : // -----------------------------------------------------------------------------
     456             : namespace
     457             : {
     458           0 :     void lcl_enableEntries( PopupMenu* _pPopup, IController& _rController )
     459             :     {
     460           0 :         if ( !_pPopup )
     461           0 :             return;
     462             : 
     463           0 :         sal_uInt16 nCount = _pPopup->GetItemCount();
     464           0 :         for (sal_uInt16 i=0; i < nCount; ++i)
     465             :         {
     466           0 :             if ( _pPopup->GetItemType(i) != MENUITEM_SEPARATOR )
     467             :             {
     468           0 :                 sal_uInt16 nId = _pPopup->GetItemId(i);
     469           0 :                 PopupMenu* pSubPopUp = _pPopup->GetPopupMenu(nId);
     470           0 :                 if ( pSubPopUp )
     471             :                 {
     472           0 :                     lcl_enableEntries( pSubPopUp, _rController );
     473           0 :                     _pPopup->EnableItem(nId,pSubPopUp->HasValidEntries());
     474             :                 }
     475             :                 else
     476             :                 {
     477           0 :                     OUString sCommandURL( _pPopup->GetItemCommand( nId ) );
     478           0 :                     bool bEnabled =  sCommandURL.isEmpty()
     479           0 :                                   ? _rController.isCommandEnabled( nId )
     480           0 :                                   : _rController.isCommandEnabled( sCommandURL );
     481           0 :                     _pPopup->EnableItem( nId, bEnabled );
     482             :                 }
     483             :             }
     484             :         }
     485             : 
     486           0 :         _pPopup->RemoveDisabledEntries();
     487             :     }
     488             : }
     489             : 
     490             : // -----------------------------------------------------------------------------
     491             : namespace
     492             : {
     493           0 :     void lcl_adjustMenuItemIDs( Menu& _rMenu, IController& _rCommandController )
     494             :     {
     495           0 :         sal_uInt16 nCount = _rMenu.GetItemCount();
     496           0 :         for ( sal_uInt16 pos = 0; pos < nCount; ++pos )
     497             :         {
     498             :             // do not adjust separators
     499           0 :             if ( _rMenu.GetItemType( pos ) == MENUITEM_SEPARATOR )
     500           0 :                 continue;
     501             : 
     502           0 :             sal_uInt16 nId = _rMenu.GetItemId(pos);
     503           0 :             String aCommand = _rMenu.GetItemCommand( nId );
     504           0 :             PopupMenu* pPopup = _rMenu.GetPopupMenu( nId );
     505           0 :             if ( pPopup )
     506             :             {
     507           0 :                 lcl_adjustMenuItemIDs( *pPopup, _rCommandController );
     508           0 :                 continue;
     509             :             }
     510             : 
     511           0 :             const sal_uInt16 nCommandId = _rCommandController.registerCommandURL( aCommand );
     512             :             _rMenu.InsertItem( nCommandId, _rMenu.GetItemText( nId ), _rMenu.GetItemImage( nId ),
     513           0 :                 _rMenu.GetItemBits( nId ), OString(), pos );
     514             : 
     515             :             // more things to preserve:
     516             :             // - the help command
     517           0 :             OUString sHelpURL = _rMenu.GetHelpCommand( nId );
     518           0 :             if ( !sHelpURL.isEmpty() )
     519           0 :                 _rMenu.SetHelpCommand(  nCommandId, sHelpURL  );
     520             : 
     521             :             // remove the "old" item
     522           0 :             _rMenu.RemoveItem( pos+1 );
     523           0 :         }
     524           0 :     }
     525           0 :     void lcl_insertMenuItemImages( Menu& _rMenu, IController& _rCommandController )
     526             :     {
     527           0 :         uno::Reference< frame::XController > xController = _rCommandController.getXController();
     528           0 :         uno::Reference< frame::XFrame> xFrame;
     529           0 :         if ( xController.is() )
     530           0 :             xFrame = xController->getFrame();
     531           0 :         sal_uInt16 nCount = _rMenu.GetItemCount();
     532           0 :         for ( sal_uInt16 pos = 0; pos < nCount; ++pos )
     533             :         {
     534             :             // do not adjust separators
     535           0 :             if ( _rMenu.GetItemType( pos ) == MENUITEM_SEPARATOR )
     536           0 :                 continue;
     537             : 
     538           0 :             sal_uInt16 nId = _rMenu.GetItemId(pos);
     539           0 :             String aCommand = _rMenu.GetItemCommand( nId );
     540           0 :             PopupMenu* pPopup = _rMenu.GetPopupMenu( nId );
     541           0 :             if ( pPopup )
     542             :             {
     543           0 :                 lcl_insertMenuItemImages( *pPopup, _rCommandController );
     544           0 :                 continue;
     545             :             }
     546             : 
     547           0 :             if ( xFrame.is() )
     548           0 :                 _rMenu.SetItemImage(nId,framework::GetImageFromURL(xFrame,aCommand,sal_False));
     549           0 :         }
     550           0 :     }
     551             :     // =========================================================================
     552             :     // = SelectionSupplier
     553             :     // =========================================================================
     554             :     typedef ::cppu::WeakImplHelper1 <   XSelectionSupplier
     555             :                                     >   SelectionSupplier_Base;
     556             :     class SelectionSupplier : public SelectionSupplier_Base
     557             :     {
     558             :     public:
     559           0 :         SelectionSupplier( const Any& _rSelection )
     560           0 :             :m_aSelection( _rSelection )
     561             :         {
     562           0 :         }
     563             : 
     564             :         virtual ::sal_Bool SAL_CALL select( const Any& xSelection ) throw (IllegalArgumentException, RuntimeException);
     565             :         virtual Any SAL_CALL getSelection(  ) throw (RuntimeException);
     566             :         virtual void SAL_CALL addSelectionChangeListener( const Reference< XSelectionChangeListener >& xListener ) throw (RuntimeException);
     567             :         virtual void SAL_CALL removeSelectionChangeListener( const Reference< XSelectionChangeListener >& xListener ) throw (RuntimeException);
     568             : 
     569             :     protected:
     570           0 :         virtual ~SelectionSupplier()
     571           0 :         {
     572           0 :         }
     573             : 
     574             :     private:
     575             :         Any m_aSelection;
     576             :     };
     577             : 
     578             :     //--------------------------------------------------------------------
     579           0 :     ::sal_Bool SAL_CALL SelectionSupplier::select( const Any& /*_Selection*/ ) throw (IllegalArgumentException, RuntimeException)
     580             :     {
     581           0 :         throw IllegalArgumentException();
     582             :         // API bug: this should be a NoSupportException
     583             :     }
     584             : 
     585             :     //--------------------------------------------------------------------
     586           0 :     Any SAL_CALL SelectionSupplier::getSelection(  ) throw (RuntimeException)
     587             :     {
     588           0 :         return m_aSelection;
     589             :     }
     590             : 
     591             :     //--------------------------------------------------------------------
     592           0 :     void SAL_CALL SelectionSupplier::addSelectionChangeListener( const Reference< XSelectionChangeListener >& /*_Listener*/ ) throw (RuntimeException)
     593             :     {
     594             :         OSL_FAIL( "SelectionSupplier::removeSelectionChangeListener: no support!" );
     595             :         // API bug: this should be a NoSupportException
     596           0 :     }
     597             : 
     598             :     //--------------------------------------------------------------------
     599           0 :     void SAL_CALL SelectionSupplier::removeSelectionChangeListener( const Reference< XSelectionChangeListener >& /*_Listener*/ ) throw (RuntimeException)
     600             :     {
     601             :         OSL_FAIL( "SelectionSupplier::removeSelectionChangeListener: no support!" );
     602             :         // API bug: this should be a NoSupportException
     603           0 :     }
     604             : }
     605             : 
     606             : // -----------------------------------------------------------------------------
     607           0 : PopupMenu* DBTreeListBox::CreateContextMenu( void )
     608             : {
     609           0 :     ::std::auto_ptr< PopupMenu > pContextMenu;
     610             : 
     611           0 :     if ( !m_pContextMenuProvider )
     612           0 :         return pContextMenu.release();
     613             : 
     614             :     // the basic context menu
     615           0 :     pContextMenu.reset( m_pContextMenuProvider->getContextMenu( *this ) );
     616             :     // disable what is not available currently
     617           0 :     lcl_enableEntries( pContextMenu.get(), m_pContextMenuProvider->getCommandController() );
     618             :     // set images
     619           0 :     lcl_insertMenuItemImages( *pContextMenu, m_pContextMenuProvider->getCommandController() );
     620             :     // allow context menu interception
     621           0 :     ::cppu::OInterfaceContainerHelper* pInterceptors = m_pContextMenuProvider->getContextMenuInterceptors();
     622           0 :     if ( !pInterceptors || !pInterceptors->getLength() )
     623           0 :         return pContextMenu.release();
     624             : 
     625           0 :     ContextMenuExecuteEvent aEvent;
     626           0 :     aEvent.SourceWindow = VCLUnoHelper::GetInterface( this );
     627           0 :     aEvent.ExecutePosition.X = -1;
     628           0 :     aEvent.ExecutePosition.Y = -1;
     629           0 :     aEvent.ActionTriggerContainer = ::framework::ActionTriggerHelper::CreateActionTriggerContainerFromMenu(
     630           0 :         pContextMenu.get(), 0 );
     631           0 :     aEvent.Selection = new SelectionSupplier( m_pContextMenuProvider->getCurrentSelection( *this ) );
     632             : 
     633           0 :     ::cppu::OInterfaceIteratorHelper aIter( *pInterceptors );
     634           0 :     bool bModifiedMenu = false;
     635           0 :     bool bAskInterceptors = true;
     636           0 :     while ( aIter.hasMoreElements() && bAskInterceptors )
     637             :     {
     638           0 :         Reference< XContextMenuInterceptor > xInterceptor( aIter.next(), UNO_QUERY );
     639           0 :         if ( !xInterceptor.is() )
     640           0 :             continue;
     641             : 
     642             :         try
     643             :         {
     644           0 :             ContextMenuInterceptorAction eAction = xInterceptor->notifyContextMenuExecute( aEvent );
     645           0 :             switch ( eAction )
     646             :             {
     647             :                 case ContextMenuInterceptorAction_CANCELLED:
     648           0 :                     return NULL;
     649             : 
     650             :                 case ContextMenuInterceptorAction_EXECUTE_MODIFIED:
     651           0 :                     bModifiedMenu = true;
     652           0 :                     bAskInterceptors = false;
     653           0 :                     break;
     654             : 
     655             :                 case ContextMenuInterceptorAction_CONTINUE_MODIFIED:
     656           0 :                     bModifiedMenu = true;
     657           0 :                     bAskInterceptors = true;
     658           0 :                     break;
     659             : 
     660             :                 default:
     661             :                     OSL_FAIL( "DBTreeListBox::CreateContextMenu: unexpected return value of the interceptor call!" );
     662             : 
     663             :                 case ContextMenuInterceptorAction_IGNORED:
     664           0 :                     break;
     665             :             }
     666             :         }
     667           0 :         catch( const DisposedException& e )
     668             :         {
     669           0 :             if ( e.Context == xInterceptor )
     670           0 :                 aIter.remove();
     671             :         }
     672           0 :     }
     673             : 
     674           0 :     if ( bModifiedMenu )
     675             :     {
     676             :         // the interceptor(s) modified the menu description => create a new PopupMenu
     677           0 :         PopupMenu* pModifiedMenu = new PopupMenu;
     678             :         ::framework::ActionTriggerHelper::CreateMenuFromActionTriggerContainer(
     679           0 :             pModifiedMenu, aEvent.ActionTriggerContainer );
     680           0 :         aEvent.ActionTriggerContainer.clear();
     681           0 :         pContextMenu.reset( pModifiedMenu );
     682             : 
     683             :         // the interceptors only know command URLs, but our menus primarily work
     684             :         // with IDs -> we need to translate the commands to IDs
     685           0 :         lcl_adjustMenuItemIDs( *pModifiedMenu, m_pContextMenuProvider->getCommandController() );
     686             :     }
     687             : 
     688           0 :     return pContextMenu.release();
     689             : }
     690             : 
     691             : // -----------------------------------------------------------------------------
     692           0 : void DBTreeListBox::ExcecuteContextMenuAction( sal_uInt16 _nSelectedPopupEntry )
     693             : {
     694           0 :     if ( m_pContextMenuProvider && _nSelectedPopupEntry )
     695           0 :         m_pContextMenuProvider->getCommandController().executeChecked( _nSelectedPopupEntry, Sequence< PropertyValue >() );
     696           0 : }
     697             : 
     698             : // -----------------------------------------------------------------------------
     699           2 : IMPL_LINK(DBTreeListBox, OnTimeOut, void*, /*EMPTY_ARG*/)
     700             : {
     701           1 :     implStopSelectionTimer();
     702             : 
     703           1 :     m_aSelChangeHdl.Call( NULL );
     704           1 :     return 0L;
     705             : }
     706             : // -----------------------------------------------------------------------------
     707           3 : void DBTreeListBox::StateChanged( StateChangedType nStateChange )
     708             : {
     709           3 :     if ( nStateChange == STATE_CHANGE_VISIBLE )
     710           1 :         implStopSelectionTimer();
     711           3 : }
     712             : // .........................................................................
     713          12 : }   // namespace dbaui
     714             : // .........................................................................
     715             : 
     716             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10