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

Generated by: LCOV version 1.11