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

Generated by: LCOV version 1.10