LCOV - code coverage report
Current view: top level - framework/source/uielement - addonstoolbarmanager.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 116 228 50.9 %
Date: 2014-04-11 Functions: 10 25 40.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             : #include <uielement/addonstoolbarmanager.hxx>
      21             : #include <uielement/toolbarmerger.hxx>
      22             : 
      23             : #include <uielement/generictoolbarcontroller.hxx>
      24             : #include "services.h"
      25             : #include <framework/imageproducer.hxx>
      26             : #include <framework/sfxhelperfunctions.hxx>
      27             : #include <classes/fwkresid.hxx>
      28             : #include <classes/resource.hrc>
      29             : #include <framework/addonsoptions.hxx>
      30             : #include <uielement/comboboxtoolbarcontroller.hxx>
      31             : #include <uielement/imagebuttontoolbarcontroller.hxx>
      32             : #include <uielement/togglebuttontoolbarcontroller.hxx>
      33             : #include <uielement/buttontoolbarcontroller.hxx>
      34             : #include <uielement/spinfieldtoolbarcontroller.hxx>
      35             : #include <uielement/edittoolbarcontroller.hxx>
      36             : #include <uielement/dropdownboxtoolbarcontroller.hxx>
      37             : 
      38             : #include <com/sun/star/ui/ItemType.hpp>
      39             : #include <com/sun/star/frame/ModuleManager.hpp>
      40             : #include <com/sun/star/frame/XToolbarController.hpp>
      41             : #include <com/sun/star/frame/XDispatchProvider.hpp>
      42             : #include <com/sun/star/lang/XServiceInfo.hpp>
      43             : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      44             : #include <com/sun/star/frame/XLayoutManager.hpp>
      45             : #include <com/sun/star/ui/DockingArea.hpp>
      46             : #include <com/sun/star/lang/XMultiComponentFactory.hpp>
      47             : #include <comphelper/processfactory.hxx>
      48             : #include <svtools/imgdef.hxx>
      49             : #include <svtools/toolboxcontroller.hxx>
      50             : #include <toolkit/helper/vclunohelper.hxx>
      51             : 
      52             : #include <svtools/miscopt.hxx>
      53             : #include <vcl/svapp.hxx>
      54             : #include <vcl/menu.hxx>
      55             : #include <vcl/syswin.hxx>
      56             : #include <vcl/taskpanelist.hxx>
      57             : #include <vcl/toolbox.hxx>
      58             : #include <vcl/settings.hxx>
      59             : 
      60             : //  namespaces
      61             : 
      62             : using namespace ::com::sun::star;
      63             : using namespace ::com::sun::star::awt;
      64             : using namespace ::com::sun::star::beans;
      65             : using namespace ::com::sun::star::uno;
      66             : using namespace ::com::sun::star::lang;
      67             : using namespace ::com::sun::star::frame;
      68             : using namespace ::com::sun::star::util;
      69             : using namespace ::com::sun::star::container;
      70             : using namespace ::com::sun::star::ui;
      71             : 
      72             : namespace framework
      73             : {
      74             : 
      75             : static const char   TOOLBOXITEM_SEPARATOR_STR[] = "private:separator";
      76             : 
      77        1731 : AddonsToolBarManager::AddonsToolBarManager( const Reference< XComponentContext >& rxContext,
      78             :                                 const Reference< XFrame >& rFrame,
      79             :                                 const OUString& rResourceName,
      80             :                                 ToolBox* pToolBar ) :
      81        1731 :     ToolBarManager( rxContext, rFrame, rResourceName, pToolBar )
      82             : {
      83        1731 :     m_pToolBar->SetMenuType( TOOLBOX_MENUTYPE_CLIPPEDITEMS );
      84        1731 :     m_pToolBar->SetSelectHdl( LINK( this, AddonsToolBarManager, Select) );
      85        1731 :     m_pToolBar->SetActivateHdl( LINK( this, AddonsToolBarManager, Activate) );
      86        1731 :     m_pToolBar->SetDeactivateHdl( LINK( this, AddonsToolBarManager, Deactivate) );
      87        1731 :     m_pToolBar->SetClickHdl( LINK( this, AddonsToolBarManager, Click ) );
      88        1731 :     m_pToolBar->SetDoubleClickHdl( LINK( this, AddonsToolBarManager, DoubleClick ) );
      89        1731 :     m_pToolBar->SetCommandHdl( LINK( this, AddonsToolBarManager, Command ) );
      90        1731 :     m_pToolBar->SetStateChangedHdl( LINK( this, AddonsToolBarManager, StateChanged ) );
      91        1731 :     m_pToolBar->SetDataChangedHdl( LINK( this, AddonsToolBarManager, DataChanged ) );
      92        1731 : }
      93             : 
      94        3460 : AddonsToolBarManager::~AddonsToolBarManager()
      95             : {
      96        3460 : }
      97             : 
      98       17310 : static bool IsCorrectContext( const OUString& rModuleIdentifier, const OUString& aContextList )
      99             : {
     100       17310 :     if ( aContextList.isEmpty() )
     101           0 :         return true;
     102             : 
     103       17310 :     if ( !rModuleIdentifier.isEmpty() )
     104             :     {
     105       17310 :         sal_Int32 nIndex = aContextList.indexOf( rModuleIdentifier );
     106       17310 :         return ( nIndex >= 0 );
     107             :     }
     108             : 
     109           0 :     return false;
     110             : }
     111             : 
     112           0 : static Image RetrieveImage( Reference< com::sun::star::frame::XFrame >& rFrame,
     113             :                             const OUString& aImageId,
     114             :                             const OUString& aURL,
     115             :                             bool bBigImage
     116             : )
     117             : {
     118           0 :     Image aImage;
     119             : 
     120           0 :     if ( !aImageId.isEmpty() )
     121             :     {
     122           0 :         aImage = framework::AddonsOptions().GetImageFromURL( aImageId, bBigImage );
     123           0 :         if ( !!aImage )
     124           0 :             return aImage;
     125             :         else
     126           0 :             aImage = GetImageFromURL( rFrame, aImageId, bBigImage );
     127           0 :         if ( !!aImage )
     128           0 :             return aImage;
     129             :     }
     130             : 
     131           0 :     aImage = framework::AddonsOptions().GetImageFromURL( aURL, bBigImage );
     132           0 :     if ( !aImage )
     133           0 :         aImage = GetImageFromURL( rFrame, aImageId, bBigImage );
     134             : 
     135           0 :     return aImage;
     136             : }
     137             : 
     138             : // XComponent
     139        1730 : void SAL_CALL AddonsToolBarManager::dispose() throw( RuntimeException, std::exception )
     140             : {
     141        1730 :     Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );
     142             : 
     143             :     {
     144             :         // Remove addon specific data from toolbar items.
     145        1730 :         SolarMutexGuard g;
     146       19030 :         for ( sal_uInt16 n = 0; n < m_pToolBar->GetItemCount(); n++ )
     147             :         {
     148       17300 :             sal_uInt16 nId( m_pToolBar->GetItemId( n ) );
     149             : 
     150       17300 :             if ( nId > 0 )
     151             :             {
     152       17300 :                 AddonsParams* pRuntimeItemData = (AddonsParams*)m_pToolBar->GetItemData( nId );
     153       17300 :                 if ( pRuntimeItemData )
     154       17300 :                     delete pRuntimeItemData;
     155       17300 :                 m_pToolBar->SetItemData( nId, NULL );
     156             :             }
     157        1730 :         }
     158             :     }
     159             : 
     160             :     // Base class will destroy our m_pToolBar member
     161        1730 :     ToolBarManager::dispose();
     162        1730 : }
     163             : 
     164           0 : bool AddonsToolBarManager::MenuItemAllowed( sal_uInt16 nId ) const
     165             : {
     166           0 :     if (( nId == MENUITEM_TOOLBAR_VISIBLEBUTTON ) ||
     167             :         ( nId == MENUITEM_TOOLBAR_CUSTOMIZETOOLBAR ))
     168           0 :         return false;
     169             :     else
     170           0 :         return true;
     171             : }
     172             : 
     173           0 : void AddonsToolBarManager::RefreshImages()
     174             : {
     175           0 :     bool  bBigImages( SvtMiscOptions().AreCurrentSymbolsLarge() );
     176           0 :     for ( sal_uInt16 nPos = 0; nPos < m_pToolBar->GetItemCount(); nPos++ )
     177             :     {
     178           0 :         sal_uInt16 nId( m_pToolBar->GetItemId( nPos ) );
     179             : 
     180           0 :         if ( nId > 0 )
     181             :         {
     182           0 :             OUString aCommandURL = m_pToolBar->GetItemCommand( nId );
     183           0 :             OUString aImageId;
     184           0 :             AddonsParams* pRuntimeItemData = (AddonsParams*)m_pToolBar->GetItemData( nId );
     185           0 :             if ( pRuntimeItemData )
     186           0 :                 aImageId  = pRuntimeItemData->aImageId;
     187             : 
     188             :             m_pToolBar->SetItemImage(
     189             :                 nId,
     190             :                 RetrieveImage( m_xFrame, aImageId, aCommandURL, bBigImages )
     191           0 :             );
     192             :         }
     193             :     }
     194           0 :     m_pToolBar->SetToolboxButtonSize( bBigImages ? TOOLBOX_BUTTONSIZE_LARGE : TOOLBOX_BUTTONSIZE_SMALL );
     195           0 :     ::Size aSize = m_pToolBar->CalcWindowSizePixel();
     196           0 :     m_pToolBar->SetOutputSizePixel( aSize );
     197           0 : }
     198             : 
     199        1731 : void AddonsToolBarManager::FillToolbar( const Sequence< Sequence< PropertyValue > >& rAddonToolbar )
     200             : {
     201        1731 :     SolarMutexGuard g;
     202             : 
     203        1731 :     if ( m_bDisposed )
     204        1731 :         return;
     205             : 
     206        1731 :     sal_uInt16 nId( 1 );
     207             : 
     208        1731 :     RemoveControllers();
     209             : 
     210        1731 :     m_pToolBar->Clear();
     211        1731 :     m_aControllerMap.clear();
     212             : 
     213        3462 :     OUString aModuleIdentifier;
     214             :     try
     215             :     {
     216        1731 :         Reference< XModuleManager2 > xModuleManager = ModuleManager::create( m_xContext );
     217        1731 :         aModuleIdentifier = xModuleManager->identify( m_xFrame );
     218             :     }
     219           0 :     catch ( const Exception& )
     220             :     {
     221             :     }
     222             : 
     223        1731 :     sal_uInt32  nElements( 0 );
     224        1731 :     bool    bAppendSeparator( false );
     225        3462 :     Reference< XWindow > xToolbarWindow = VCLUnoHelper::GetInterface( m_pToolBar );
     226       19041 :     for ( sal_uInt32 n = 0; n < (sal_uInt32)rAddonToolbar.getLength(); n++ )
     227             :     {
     228       17310 :         OUString   aURL;
     229       34620 :         OUString   aTitle;
     230       34620 :         OUString   aImageId;
     231       34620 :         OUString   aContext;
     232       34620 :         OUString   aTarget;
     233       34620 :         OUString   aControlType;
     234       17310 :         sal_uInt16      nWidth( 0 );
     235             : 
     236       17310 :         const Sequence< PropertyValue >& rSeq = rAddonToolbar[n];
     237             : 
     238       17310 :         ToolBarMerger::ConvertSequenceToValues( rSeq, aURL, aTitle, aImageId, aTarget, aContext, aControlType, nWidth );
     239             : 
     240       17310 :         if ( IsCorrectContext( aModuleIdentifier, aContext ))
     241             :         {
     242       17310 :             if ( aURL == TOOLBOXITEM_SEPARATOR_STR )
     243             :             {
     244           0 :                 sal_uInt16 nCount = m_pToolBar->GetItemCount();
     245           0 :                 if ( nCount > 0 && ( m_pToolBar->GetItemType( nCount-1 ) != TOOLBOXITEM_SEPARATOR ) && nElements > 0 )
     246             :                 {
     247           0 :                     nElements = 0;
     248           0 :                     m_pToolBar->InsertSeparator();
     249             :                 }
     250             :             }
     251             :             else
     252             :             {
     253       17310 :                 sal_uInt16 nCount = m_pToolBar->GetItemCount();
     254       17310 :                 if ( bAppendSeparator && nCount > 0 && ( m_pToolBar->GetItemType( nCount-1 ) != TOOLBOXITEM_SEPARATOR ))
     255             :                 {
     256             :                     // We have to append a separator first if the last item is not a separator
     257           0 :                     m_pToolBar->InsertSeparator();
     258             :                 }
     259       17310 :                 bAppendSeparator = false;
     260             : 
     261       17310 :                 m_pToolBar->InsertItem( nId, aTitle );
     262             : 
     263             :                 // don't setup images yet, AddonsToolbarWrapper::populateImages does that.
     264             : 
     265             :                 // Create TbRuntimeItemData to hold additional information we will need in the future
     266       17310 :                 AddonsParams* pRuntimeItemData = new AddonsParams;
     267       17310 :                 pRuntimeItemData->aImageId  = aImageId;
     268       17310 :                 pRuntimeItemData->aTarget   = aTarget;
     269       17310 :                 m_pToolBar->SetItemData( nId, pRuntimeItemData );
     270       17310 :                 m_pToolBar->SetItemCommand( nId, aURL );
     271             : 
     272       17310 :                 Reference< XStatusListener > xController;
     273             : 
     274       17310 :                 bool bMustBeInit( true );
     275             : 
     276             :                 // Support external toolbar controller for add-ons!
     277       34620 :                 if ( m_xToolbarControllerFactory.is() &&
     278       17310 :                      m_xToolbarControllerFactory->hasController( aURL, m_aModuleIdentifier ))
     279             :                 {
     280           0 :                     Sequence< Any > aArgs(5);
     281           0 :                     PropertyValue   aPropValue;
     282             : 
     283           0 :                     aPropValue.Name     = "ModuleIdentifier";
     284           0 :                     aPropValue.Value    <<= m_aModuleIdentifier;
     285           0 :                     aArgs[0] <<= aPropValue;
     286           0 :                     aPropValue.Name     = "Frame";
     287           0 :                     aPropValue.Value    <<= m_xFrame;
     288           0 :                     aArgs[1] <<= aPropValue;
     289           0 :                     aPropValue.Name     = "ServiceManager";
     290           0 :                     aPropValue.Value    <<= Reference<XMultiServiceFactory>(m_xContext->getServiceManager(), UNO_QUERY_THROW);
     291           0 :                     aArgs[2] <<= aPropValue;
     292           0 :                     aPropValue.Name     = "ParentWindow";
     293           0 :                     aPropValue.Value    <<= xToolbarWindow;
     294           0 :                     aArgs[3] <<= aPropValue;
     295           0 :                     aPropValue.Name     = "ItemId";
     296           0 :                     aPropValue.Value    = makeAny( sal_Int32( nId ));
     297           0 :                     aArgs[4] <<= aPropValue;
     298             : 
     299             :                     try
     300             :                     {
     301           0 :                         xController = Reference< XStatusListener >( m_xToolbarControllerFactory->createInstanceWithArgumentsAndContext(
     302           0 :                                                                         aURL, aArgs, m_xContext ),
     303           0 :                                                                     UNO_QUERY );
     304             :                     }
     305           0 :                     catch ( uno::Exception& )
     306             :                     {
     307             :                     }
     308           0 :                     bMustBeInit = false; // factory called init already!
     309             :                 }
     310             :                 else
     311             :                 {
     312       17310 :                     ::cppu::OWeakObject* pController = 0;
     313             : 
     314       17310 :                     pController = ToolBarMerger::CreateController( m_xContext, m_xFrame, m_pToolBar, aURL, nId, nWidth, aControlType );
     315       17310 :                     xController = Reference< XStatusListener >( pController, UNO_QUERY );
     316             :                 }
     317             : 
     318             :                 // insert controller to the map
     319       17310 :                 m_aControllerMap[nId] = xController;
     320             : 
     321       34620 :                 Reference< XInitialization > xInit( xController, UNO_QUERY );
     322       17310 :                 if ( xInit.is() && bMustBeInit )
     323             :                 {
     324       17310 :                     PropertyValue aPropValue;
     325       34620 :                     Sequence< Any > aArgs( 3 );
     326       17310 :                     aPropValue.Name = "Frame";
     327       17310 :                     aPropValue.Value <<= m_xFrame;
     328       17310 :                     aArgs[0] <<= aPropValue;
     329       17310 :                     aPropValue.Name = "CommandURL";
     330       17310 :                     aPropValue.Value <<= aURL;
     331       17310 :                     aArgs[1] <<= aPropValue;
     332       17310 :                     aPropValue.Name = "ServiceManager";
     333       17310 :                     aPropValue.Value <<= Reference<XMultiServiceFactory>(m_xContext->getServiceManager(), UNO_QUERY_THROW);
     334       17310 :                     aArgs[2] <<= aPropValue;
     335             :                     try
     336             :                     {
     337       17310 :                         xInit->initialize( aArgs );
     338             :                     }
     339           0 :                     catch ( const uno::Exception& )
     340             :                     {
     341       17310 :                     }
     342             :                 }
     343             : 
     344             :                 // Request a item window from the toolbar controller and set it at the VCL toolbar
     345       34620 :                 Reference< XToolbarController > xTbxController( xController, UNO_QUERY );
     346       17310 :                 if ( xTbxController.is() && xToolbarWindow.is() )
     347             :                 {
     348       17310 :                     Reference< XWindow > xWindow = xTbxController->createItemWindow( xToolbarWindow );
     349       17310 :                     if ( xWindow.is() )
     350             :                     {
     351           0 :                         Window* pItemWin = VCLUnoHelper::GetWindow( xWindow );
     352           0 :                         if ( pItemWin )
     353             :                         {
     354           0 :                             WindowType nType = pItemWin->GetType();
     355           0 :                             if ( nType == WINDOW_LISTBOX || nType == WINDOW_MULTILISTBOX || nType == WINDOW_COMBOBOX )
     356           0 :                                 pItemWin->SetAccessibleName( m_pToolBar->GetItemText( nId ) );
     357           0 :                             m_pToolBar->SetItemWindow( nId, pItemWin );
     358             :                         }
     359       17310 :                     }
     360             :                 }
     361             : 
     362             :                 // Notify controller implementation to its listeners. Controller is now useable from outside.
     363       34620 :                 Reference< XUpdatable > xUpdatable( xController, UNO_QUERY );
     364       17310 :                 if ( xUpdatable.is() )
     365             :                 {
     366             :                     try
     367             :                     {
     368       17310 :                         xUpdatable->update();
     369             :                     }
     370           0 :                     catch ( const uno::Exception& )
     371             :                     {
     372             :                     }
     373             :                 }
     374             : 
     375       17310 :                 ++nId;
     376       34620 :                 ++nElements;
     377             :             }
     378             :         }
     379       17310 :     }
     380             : 
     381        3462 :     AddFrameActionListener();
     382             : }
     383             : 
     384           0 : IMPL_LINK_NOARG(AddonsToolBarManager, Click)
     385             : {
     386           0 :     if ( m_bDisposed )
     387           0 :         return 1;
     388             : 
     389           0 :     sal_uInt16 nId( m_pToolBar->GetCurItemId() );
     390           0 :     ToolBarControllerMap::const_iterator pIter = m_aControllerMap.find( nId );
     391           0 :     if ( pIter != m_aControllerMap.end() )
     392             :     {
     393           0 :         Reference< XToolbarController > xController( pIter->second, UNO_QUERY );
     394             : 
     395           0 :         if ( xController.is() )
     396           0 :             xController->click();
     397             :     }
     398             : 
     399           0 :     return 1;
     400             : }
     401             : 
     402           0 : IMPL_LINK_NOARG(AddonsToolBarManager, DoubleClick)
     403             : {
     404           0 :     if ( m_bDisposed )
     405           0 :         return 1;
     406             : 
     407           0 :     sal_uInt16 nId( m_pToolBar->GetCurItemId() );
     408           0 :     ToolBarControllerMap::const_iterator pIter = m_aControllerMap.find( nId );
     409           0 :     if ( pIter != m_aControllerMap.end() )
     410             :     {
     411           0 :         Reference< XToolbarController > xController( pIter->second, UNO_QUERY );
     412             : 
     413           0 :         if ( xController.is() )
     414           0 :             xController->doubleClick();
     415             :     }
     416             : 
     417           0 :     return 1;
     418             : }
     419             : 
     420           0 : IMPL_LINK_NOARG(AddonsToolBarManager, Command)
     421             : {
     422           0 :     SolarMutexGuard g;
     423             : 
     424           0 :     if ( m_bDisposed )
     425           0 :         return 1;
     426             : 
     427           0 :     return 0;
     428             : }
     429             : 
     430           0 : IMPL_LINK_NOARG(AddonsToolBarManager, Select)
     431             : {
     432           0 :     if ( m_bDisposed )
     433           0 :         return 1;
     434             : 
     435           0 :     sal_Int16   nKeyModifier( (sal_Int16)m_pToolBar->GetModifier() );
     436           0 :     sal_uInt16      nId( m_pToolBar->GetCurItemId() );
     437           0 :     ToolBarControllerMap::const_iterator pIter = m_aControllerMap.find( nId );
     438           0 :     if ( pIter != m_aControllerMap.end() )
     439             :     {
     440           0 :         Reference< XToolbarController > xController( pIter->second, UNO_QUERY );
     441             : 
     442           0 :         if ( xController.is() )
     443           0 :             xController->execute( nKeyModifier );
     444             :     }
     445             : 
     446           0 :     return 1;
     447             : }
     448             : 
     449           0 : IMPL_LINK_NOARG(AddonsToolBarManager, Activate)
     450             : {
     451           0 :     return 1;
     452             : }
     453             : 
     454           0 : IMPL_LINK_NOARG(AddonsToolBarManager, Deactivate)
     455             : {
     456           0 :     return 1;
     457             : }
     458             : 
     459        4874 : IMPL_LINK( AddonsToolBarManager, StateChanged, StateChangedType*, pStateChangedType )
     460             : {
     461        2437 :     if ( *pStateChangedType == STATE_CHANGE_CONTROLBACKGROUND )
     462             :     {
     463           0 :         CheckAndUpdateImages();
     464             :     }
     465        2437 :     return 1;
     466             : }
     467             : 
     468           4 : IMPL_LINK( AddonsToolBarManager, DataChanged, DataChangedEvent*, pDataChangedEvent  )
     469             : {
     470           4 :     if ((( pDataChangedEvent->GetType() == DATACHANGED_SETTINGS )   ||
     471           4 :         (  pDataChangedEvent->GetType() == DATACHANGED_DISPLAY  ))  &&
     472           2 :         ( pDataChangedEvent->GetFlags() & SETTINGS_STYLE        ))
     473             :     {
     474           0 :         CheckAndUpdateImages();
     475             :     }
     476             : 
     477          22 :     for ( sal_uInt16 nPos = 0; nPos < m_pToolBar->GetItemCount(); ++nPos )
     478             :     {
     479          20 :         const sal_uInt16 nId = m_pToolBar->GetItemId(nPos);
     480          20 :         Window* pWindow = m_pToolBar->GetItemWindow( nId );
     481          20 :         if ( pWindow )
     482             :         {
     483           2 :             const DataChangedEvent& rDCEvt( *pDataChangedEvent );
     484           2 :             pWindow->DataChanged( rDCEvt );
     485             :         }
     486             :     }
     487             : 
     488           2 :     return 1;
     489             : }
     490             : 
     491             : }
     492             : 
     493             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10