LCOV - code coverage report
Current view: top level - include/vcl - builder.hxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 41 53 77.4 %
Date: 2015-06-13 12:38:46 Functions: 62 577 10.7 %
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             : 
      10             : #ifndef INCLUDED_VCL_BUILDER_HXX
      11             : #define INCLUDED_VCL_BUILDER_HXX
      12             : 
      13             : #include <typeinfo>
      14             : #include <osl/module.hxx>
      15             : #include <sal/log.hxx>
      16             : #include <tools/resmgr.hxx>
      17             : #include <tools/fldunit.hxx>
      18             : #include <vcl/dllapi.h>
      19             : #include <vcl/window.hxx>
      20             : #include <vcl/vclptr.hxx>
      21             : #include <map>
      22             : #include <set>
      23             : #include <stack>
      24             : #include <vector>
      25             : #ifdef check
      26             : #  //some problem with MacOSX and a check define
      27             : #  undef check
      28             : #endif
      29             : #include <boost/ptr_container/ptr_map.hpp>
      30             : 
      31             : #include <com/sun/star/frame/XFrame.hpp>
      32             : #include <com/sun/star/uno/XComponentContext.hpp>
      33             : 
      34             : class ListBox;
      35             : class NumericFormatter;
      36             : class PopupMenu;
      37             : class ScrollBar;
      38             : class Slider;
      39             : class DateField;
      40             : class TimeField;
      41             : class VclExpander;
      42             : class VclMultiLineEdit;
      43             : namespace xmlreader { class XmlReader; }
      44             : 
      45             : class VCL_DLLPUBLIC VclBuilder
      46             : {
      47             : public:
      48             :     typedef std::map<OString, OString> stringmap;
      49             :     /// These functions create a new widget with parent @pParent and return it in @rRet
      50             :     typedef void (*customMakeWidget)(VclPtr<vcl::Window> &rRet, VclPtr<vcl::Window> &pParent, stringmap &rVec);
      51             : 
      52             : public:
      53             :                     VclBuilder(
      54             :                             vcl::Window *pParent,
      55             :                             const OUString& sUIRootDir,
      56             :                             const OUString& sUIFile,
      57             :                             const OString& sID = OString(),
      58             :                             const css::uno::Reference<css::frame::XFrame> &rFrame = css::uno::Reference<css::frame::XFrame>());
      59             :                     ~VclBuilder();
      60             : 
      61             :     ///releases references and disposes all children.
      62             :     void disposeBuilder();
      63             : 
      64             :     //sID must exist and be of type T
      65             :     template <typename T> T* get(VclPtr<T>& ret, const OString& sID);
      66             : 
      67             :     //sID may not exist, but must be of type T if it does
      68             :     template <typename T /*= vcl::Window if we had c++11*/> T* get(const OString& sID);
      69             : 
      70             :     vcl::Window*    get_widget_root();
      71             : 
      72             :     PopupMenu*      get_menu(PopupMenu*& ret, const OString& sID);
      73             : 
      74             :     //sID may not exist
      75             :     PopupMenu*      get_menu(const OString& sID);
      76             : 
      77             :     //given an sID return the response value for that widget
      78             :     short           get_response(const vcl::Window *pWindow) const;
      79             : 
      80             :     OString         get_by_window(const vcl::Window *pWindow) const;
      81             :     void            delete_by_window(vcl::Window *pWindow);
      82             : 
      83             :     //release ownership of pWindow, i.e. don't delete it
      84             :     void            drop_ownership(const vcl::Window *pWindow);
      85             : 
      86             :     //apply the properties of rProps to pWindow
      87             :     static void     set_properties(vcl::Window *pWindow, const stringmap &rProps);
      88             : 
      89             :     //Convert _ gtk markup to ~ vcl markup
      90             :     static          OString convertMnemonicMarkup(const OString &rIn);
      91             : 
      92             :     static OString  extractCustomProperty(stringmap &rMap);
      93             :     static FieldUnit detectUnit(OString const&);
      94             : 
      95             :     static bool     extractDropdown(stringmap &rMap);
      96             : 
      97             :     //add a default value of 25 width-chars to a map if width-chars not set
      98             :     static void     ensureDefaultWidthChars(VclBuilder::stringmap &rMap);
      99             : 
     100             :     //see m_aDeferredProperties, you need this for toplevel dialogs
     101             :     //which build themselves from their ctor. The properties on
     102             :     //the top level are stored in m_aDeferredProperties and need
     103             :     //to be applied post ctor
     104             :     void            setDeferredProperties();
     105             : 
     106             :     //Helpers to retrofit all the existing code to the builder
     107             :     static void     reorderWithinParent(std::vector< vcl::Window*>& rChilds, bool bIsButtonBox);
     108             :     static void     reorderWithinParent(vcl::Window &rWindow, sal_uInt16 nNewPosition);
     109             : 
     110             :     /// Get label of the command (like of .uno:Save) from the description service
     111             :     static          OUString getCommandLabel(const OUString& rCommand, const css::uno::Reference<css::uno::XComponentContext>& rContext, const OUString& rModuleId);
     112             : 
     113             :     /// Get image of the command (like of .uno:Save) from the description service
     114             :     static Image    getCommandImage(
     115             :                         const OUString& rCommand,
     116             :                         bool bLarge,
     117             :                         const css::uno::Reference<css::uno::XComponentContext>& rContext,
     118             :                         const css::uno::Reference<css::frame::XFrame>& rFrame,
     119             :                         const OUString& rModuleId );
     120             : 
     121           0 :     css::uno::Reference<css::frame::XFrame> getFrame() { return m_xFrame; }
     122             : 
     123             : private:
     124             :     VclBuilder(const VclBuilder&) SAL_DELETED_FUNCTION;
     125             :     VclBuilder& operator=(const VclBuilder&) SAL_DELETED_FUNCTION;
     126             : 
     127             :     typedef boost::ptr_map<OUString, osl::Module> ModuleMap;
     128             : 
     129             :     //We store these until the builder is deleted, that way we can use the
     130             :     //ui-previewer on custom widgets and guarantee the modules they are from
     131             :     //exist for the duration of the dialog
     132             :     ModuleMap       m_aModuleMap;
     133             : 
     134             :     //If the toplevel window has any properties which need to be set on it,
     135             :     //but the toplevel is the owner of the builder, then its ctor
     136             :     //has not been completed during the building, so properties for it
     137             :     //are collected here and need to be set afterwards, e.g. during
     138             :     //Show or Execute
     139             :     stringmap       m_aDeferredProperties;
     140             : 
     141             :     struct PackingData
     142             :     {
     143             :         bool m_bVerticalOrient;
     144             :         sal_Int32 m_nPosition;
     145       25204 :         PackingData(bool bVerticalOrient = false, sal_Int32 nPosition = -1)
     146             :             : m_bVerticalOrient(bVerticalOrient)
     147       25204 :             , m_nPosition(nPosition)
     148             :         {
     149       25204 :         }
     150             :     };
     151             : 
     152      133056 :     struct WinAndId
     153             :     {
     154             :         OString m_sID;
     155             :         VclPtr<vcl::Window> m_pWindow;
     156             :         short m_nResponseId;
     157             :         PackingData m_aPackingData;
     158       24546 :         WinAndId(const OString &rId, vcl::Window *pWindow, bool bVertical)
     159             :             : m_sID(rId)
     160             :             , m_pWindow(pWindow)
     161             :             , m_nResponseId(RET_CANCEL)
     162       24546 :             , m_aPackingData(bVertical)
     163             :         {
     164       24546 :         }
     165             :     };
     166             :     std::vector<WinAndId> m_aChildren;
     167             : 
     168           3 :     struct MenuAndId
     169             :     {
     170             :         OString m_sID;
     171             :         PopupMenu *m_pMenu;
     172           1 :         MenuAndId(const OString &rId, PopupMenu *pMenu)
     173             :             : m_sID(rId)
     174           1 :             , m_pMenu(pMenu)
     175             :         {
     176           1 :         }
     177             :     };
     178             :     std::vector<MenuAndId> m_aMenus;
     179             : 
     180        4414 :     struct StringPair
     181             :     {
     182             :         OString m_sID;
     183             :         OString m_sValue;
     184        1140 :         StringPair(const OString &rId, const OString &rValue)
     185             :             : m_sID(rId)
     186        1140 :             , m_sValue(rValue)
     187             :         {
     188        1140 :         }
     189             :     };
     190             : 
     191             :     typedef StringPair RadioButtonGroupMap;
     192             : 
     193          57 :     struct ButtonImageWidgetMap
     194             :     {
     195             :         OString m_sID;
     196             :         OString m_sValue;
     197             :         bool m_bRadio;
     198           9 :         ButtonImageWidgetMap(const OString &rId, const OString &rValue, bool bRadio)
     199             :             : m_sID(rId)
     200             :             , m_sValue(rValue)
     201           9 :             , m_bRadio(bRadio)
     202             :         {
     203           9 :         }
     204             :     };
     205             : 
     206             :     typedef StringPair TextBufferMap;
     207             :     typedef StringPair WidgetAdjustmentMap;
     208             :     typedef StringPair ButtonMenuMap;
     209             :     typedef StringPair MnemonicWidgetMap;
     210             : 
     211           0 :     struct ComboBoxModelMap
     212             :     {
     213             :         OString m_sID;
     214             :         OString m_sValue;
     215             :         sal_Int32 m_nActiveId;
     216           0 :         ComboBoxModelMap(const OString &rId, const OString &rValue, sal_Int32 nActiveId)
     217             :             : m_sID(rId)
     218             :             , m_sValue(rValue)
     219           0 :             , m_nActiveId(nActiveId)
     220             :         {
     221           0 :         }
     222             :     };
     223             : 
     224           0 :     struct ListStore
     225             :     {
     226             :         typedef std::vector<OString> row;
     227             :         std::vector<row> m_aEntries;
     228             :     };
     229             : 
     230             :     const ListStore* get_model_by_name(const OString& sID) const;
     231             :     static void     mungeModel(ListBox &rTarget, const ListStore &rStore, sal_uInt16 nActiveId);
     232             : 
     233             :     typedef stringmap TextBuffer;
     234             :     const TextBuffer*
     235             :                     get_buffer_by_name(const OString& sID) const;
     236             : 
     237             :     static void     mungeTextBuffer(VclMultiLineEdit &rTarget, const TextBuffer &rTextBuffer);
     238             : 
     239             :     typedef stringmap Adjustment;
     240             :     const Adjustment* get_adjustment_by_name(const OString& sID) const;
     241             : 
     242             :     static void     mungeAdjustment(NumericFormatter &rTarget, const Adjustment &rAdjustment);
     243             :     static void     mungeAdjustment(DateField &rTarget, const Adjustment &rAdjustment);
     244             :     static void     mungeAdjustment(TimeField &rTarget, const Adjustment &rAdjustment);
     245             :     static void     mungeAdjustment(ScrollBar &rTarget, const Adjustment &rAdjustment);
     246             :     static void     mungeAdjustment(Slider &rTarget, const Adjustment &rAdjustment);
     247             : 
     248             :     typedef std::map<OString, OString> WidgetTranslations;
     249             :     typedef std::map<OString, WidgetTranslations> Translations;
     250             : 
     251           0 :     struct stockinfo
     252             :     {
     253             :         OString m_sStock;
     254             :         int m_nSize;
     255           0 :         stockinfo() : m_nSize(4) {}
     256             :     };
     257             : 
     258             :     typedef std::map<OString, stockinfo> StockMap;
     259             : 
     260        1017 :     struct SizeGroup
     261             :     {
     262             :         OString m_sID;
     263             :         std::vector<OString> m_aWidgets;
     264             :         stringmap m_aProperties;
     265         339 :         SizeGroup(const OString &rId)
     266         339 :             : m_sID(rId)
     267             :         {
     268         339 :         }
     269             :     };
     270             : 
     271             :     typedef std::map< VclPtr<vcl::Window>, stringmap> AtkMap;
     272             : 
     273        1638 :     struct ParserState
     274             :     {
     275             :         std::vector<RadioButtonGroupMap> m_aGroupMaps;
     276             : 
     277             :         std::vector<ComboBoxModelMap> m_aModelMaps;
     278             :         std::map<OString, ListStore> m_aModels;
     279             : 
     280             :         std::vector<TextBufferMap> m_aTextBufferMaps;
     281             :         std::map<OString, TextBuffer> m_aTextBuffers;
     282             : 
     283             :         std::vector<WidgetAdjustmentMap> m_aNumericFormatterAdjustmentMaps;
     284             :         std::vector<WidgetAdjustmentMap> m_aTimeFormatterAdjustmentMaps;
     285             :         std::vector<WidgetAdjustmentMap> m_aDateFormatterAdjustmentMaps;
     286             :         std::vector<WidgetAdjustmentMap> m_aScrollAdjustmentMaps;
     287             :         std::vector<WidgetAdjustmentMap> m_aSliderAdjustmentMaps;
     288             : 
     289             :         std::map<OString, Adjustment> m_aAdjustments;
     290             : 
     291             :         std::vector<ButtonImageWidgetMap> m_aButtonImageWidgetMaps;
     292             :         StockMap m_aStockMap;
     293             : 
     294             :         std::vector<ButtonMenuMap> m_aButtonMenuMaps;
     295             : 
     296             :         Translations m_aTranslations;
     297             : 
     298             :         std::map< VclPtr<vcl::Window>, VclPtr<vcl::Window> > m_aRedundantParentWidgets;
     299             : 
     300             :         std::vector<SizeGroup> m_aSizeGroups;
     301             : 
     302             :         AtkMap m_aAtkInfo;
     303             : 
     304             :         std::vector<MnemonicWidgetMap> m_aMnemonicWidgetMaps;
     305             : 
     306             :         std::vector< VclPtr<VclExpander> > m_aExpanderWidgets;
     307             : 
     308             :         sal_uInt16 m_nLastToolbarId;
     309             : 
     310             :         ParserState();
     311             :     };
     312             : 
     313             :     void        loadTranslations(const LanguageTag &rLanguageTag, const OUString &rUri);
     314             :     OString     getTranslation(const OString &rId, const OString &rProperty) const;
     315             : 
     316             :     OString     m_sID;
     317             :     OString     m_sHelpRoot;
     318             :     ResHookProc m_pStringReplace;
     319             :     VclPtr<vcl::Window> m_pParent;
     320             :     bool        m_bToplevelHasDeferredInit;
     321             :     bool        m_bToplevelHasDeferredProperties;
     322             :     bool        m_bToplevelParentFound;
     323             :     ParserState *m_pParserState;
     324             : 
     325             :     vcl::Window *get_by_name(const OString& sID);
     326             :     void        delete_by_name(const OString& sID);
     327             : 
     328             :     class sortIntoBestTabTraversalOrder
     329             :         : public std::binary_function<const vcl::Window*, const vcl::Window*, bool>
     330             :     {
     331             :     public:
     332       24548 :                 sortIntoBestTabTraversalOrder(VclBuilder *pBuilder)
     333       24548 :                     : m_pBuilder(pBuilder) {}
     334             : 
     335             :         bool    operator()(const vcl::Window *pA, const vcl::Window *pB) const;
     336             : 
     337             :     private:
     338             :         VclBuilder *m_pBuilder;
     339             :     };
     340             : 
     341             :     /// XFrame to be able to extract labels and other properties of the UNO commands (like of .uno:Bold).
     342             :     css::uno::Reference<css::frame::XFrame> m_xFrame;
     343             : 
     344             : private:
     345             :     VclPtr<vcl::Window> insertObject(vcl::Window *pParent,
     346             :                     const OString &rClass, const OString &rID,
     347             :                     stringmap &rProps, stringmap &rPangoAttributes,
     348             :                     stringmap &rAtkProps);
     349             : 
     350             :     VclPtr<vcl::Window> makeObject(vcl::Window *pParent,
     351             :                     const OString &rClass, const OString &rID,
     352             :                     stringmap &rVec);
     353             : 
     354             :     void        connectNumericFormatterAdjustment(const OString &id, const OString &rAdjustment);
     355             :     void        connectTimeFormatterAdjustment(const OString &id, const OString &rAdjustment);
     356             :     void        connectDateFormatterAdjustment(const OString &id, const OString &rAdjustment);
     357             : 
     358             :     bool        extractGroup(const OString &id, stringmap &rVec);
     359             :     bool        extractModel(const OString &id, stringmap &rVec);
     360             :     bool        extractBuffer(const OString &id, stringmap &rVec);
     361             :     static bool extractAdjustmentToMap(const OString &id, stringmap &rVec, std::vector<WidgetAdjustmentMap>& rAdjustmentMap);
     362             :     bool        extractButtonImage(const OString &id, stringmap &rMap, bool bRadio);
     363             :     bool        extractStock(const OString &id, stringmap &rMap);
     364             :     void        extractMnemonicWidget(const OString &id, stringmap &rMap);
     365             : 
     366             :     void        handleTranslations(xmlreader::XmlReader &reader);
     367             : 
     368             :     void        handleChild(vcl::Window *pParent, xmlreader::XmlReader &reader);
     369             :     VclPtr<vcl::Window> handleObject(vcl::Window *pParent, xmlreader::XmlReader &reader);
     370             :     void        handlePacking(vcl::Window *pCurrent, vcl::Window *pParent, xmlreader::XmlReader &reader);
     371             :     void        applyPackingProperty(vcl::Window *pCurrent, vcl::Window *pParent, xmlreader::XmlReader &reader);
     372             :     void        collectProperty(xmlreader::XmlReader &reader, const OString &rID, stringmap &rVec);
     373             :     static void collectPangoAttribute(xmlreader::XmlReader &reader, stringmap &rMap);
     374             :     static void collectAtkAttribute(xmlreader::XmlReader &reader, stringmap &rMap);
     375             :     static void collectAccelerator(xmlreader::XmlReader &reader, stringmap &rMap);
     376             : 
     377             :     void        insertMenuObject(
     378             :                    PopupMenu *pParent,
     379             :                    const OString &rClass,
     380             :                    const OString &rID,
     381             :                    stringmap &rProps,
     382             :                    stringmap &rAccels);
     383             : 
     384             :     void        handleMenuChild(PopupMenu *pParent, xmlreader::XmlReader &reader);
     385             :     void        handleMenuObject(PopupMenu *pParent, xmlreader::XmlReader &reader);
     386             : 
     387             :     void        handleListStore(xmlreader::XmlReader &reader, const OString &rID);
     388             :     void        handleRow(xmlreader::XmlReader &reader, const OString &rID, sal_Int32 nRowIndex);
     389             :     void        handleAdjustment(const OString &rID, stringmap &rProperties);
     390             :     void        handleTextBuffer(const OString &rID, stringmap &rProperties);
     391             :     void        handleTabChild(vcl::Window *pParent, xmlreader::XmlReader &reader);
     392             :     void        handleMenu(xmlreader::XmlReader &reader, const OString &rID);
     393             :     std::vector<OString> handleItems(xmlreader::XmlReader &reader, const OString &rID);
     394             : 
     395             :     void        handleSizeGroup(xmlreader::XmlReader &reader, const OString &rID);
     396             : 
     397             :     void        handleAtkObject(xmlreader::XmlReader &reader, const OString &rID, vcl::Window *pWindow);
     398             : 
     399             :     void        handleActionWidget(xmlreader::XmlReader &reader);
     400             : 
     401             :     PackingData get_window_packing_data(const vcl::Window *pWindow) const;
     402             :     void        set_window_packing_position(const vcl::Window *pWindow, sal_Int32 nPosition);
     403             : 
     404             :     static vcl::Window* prepareWidgetOwnScrolling(vcl::Window *pParent, WinBits &rWinStyle);
     405             :     void        cleanupWidgetOwnScrolling(vcl::Window *pScrollParent, vcl::Window *pWindow, stringmap &rMap);
     406             : 
     407             :     void        set_response(const OString& sID, short nResponse);
     408             : };
     409             : 
     410             : template <typename T>
     411       10000 : inline T* VclBuilder::get(VclPtr<T>& ret, const OString& sID)
     412             : {
     413       10000 :     vcl::Window *w = get_by_name(sID);
     414             :     SAL_WARN_IF(!w, "vcl.layout", "widget \"" << sID.getStr() << "\" not found in .ui");
     415             :     SAL_WARN_IF(!dynamic_cast<T*>(w),
     416             :        "vcl.layout", ".ui widget \"" << sID.getStr() << "\" needs to correspond to vcl type " << typeid(T).name());
     417             :     assert(w);
     418             :     assert(dynamic_cast<T*>(w));
     419       10000 :     ret = static_cast<T*>(w);
     420       10000 :     return ret.get();
     421             : }
     422             : 
     423             : //sID may not exist, but must be of type T if it does
     424             : template <typename T /*= vcl::Window if we had c++11*/>
     425        4349 : inline T* VclBuilder::get(const OString& sID)
     426             : {
     427        4349 :     vcl::Window *w = get_by_name(sID);
     428             :     SAL_WARN_IF(w && !dynamic_cast<T*>(w),
     429             :         "vcl.layout", ".ui widget \"" << sID.getStr() << "\" needs to correspond to vcl type " << typeid(T).name());
     430             :     assert(!w || dynamic_cast<T*>(w));
     431        4349 :     return static_cast<T*>(w);
     432             : }
     433             : 
     434             : inline PopupMenu* VclBuilder::get_menu(PopupMenu*& ret, const OString& sID)
     435             : {
     436             :     ret = get_menu(sID);
     437             :     SAL_WARN_IF(!ret, "vcl.layout", "menu \"" << sID.getStr() << "\" not found in .ui");
     438             :     assert(ret);
     439             :     return ret;
     440             : }
     441             : 
     442             : //helper baseclass to ease retro fitting dialogs/tabpages that load a resource
     443             : //to load a .ui file instead
     444             : //
     445             : //vcl requires the Window Children of a Parent Window to be destroyed before
     446             : //the Parent Window.  VclBuilderContainer owns the VclBuilder which owns the
     447             : //Children Window. So the VclBuilderContainer dtor must be called before
     448             : //the Parent Window dtor.
     449             : //
     450             : //i.e.  class Dialog : public SystemWindow, public VclBuilderContainer
     451             : //not   class Dialog : public VclBuilderContainer, public SystemWindow
     452             : //
     453             : //With the new 'dispose' framework, it is necessary to force the builder
     454             : //dispose before the Window dispose; so a Dialog::dispose() method would
     455             : //finish: disposeBuilder(); SystemWindow::dispose() to capture this ordering.
     456             : 
     457             : class VCL_DLLPUBLIC VclBuilderContainer
     458             : {
     459             : public:
     460             :                     VclBuilderContainer();
     461             :     virtual         ~VclBuilderContainer();
     462             :     void            disposeBuilder();
     463             : 
     464             :     static OUString getUIRootDir();
     465           0 :     bool            hasBuilder() const { return m_pUIBuilder != NULL; }
     466             : 
     467           0 :     css::uno::Reference<css::frame::XFrame> getFrame() { return m_pUIBuilder->getFrame(); }
     468             : 
     469       10000 :     template <typename T> T* get(VclPtr<T>& ret, const OString& sID)
     470             :     {
     471       10000 :         return m_pUIBuilder->get<T>(ret, sID);
     472             :     }
     473          19 :     template <typename T /*= vcl::Window if we had c++11*/> T* get(const OString & sID)
     474             :     {
     475          19 :         return m_pUIBuilder->get<T>(sID);
     476             :     }
     477             :     PopupMenu* get_menu(PopupMenu*& ret, const OString & sID)
     478             :     {
     479             :         return m_pUIBuilder->get_menu(ret, sID);
     480             :     }
     481           0 :     PopupMenu* get_menu(const OString & sID)
     482             :     {
     483           0 :         return m_pUIBuilder->get_menu(sID);
     484             :     }
     485       39734 :     void setDeferredProperties()
     486             :     {
     487       39734 :         if (!m_pUIBuilder)
     488       79398 :             return;
     489          70 :         m_pUIBuilder->setDeferredProperties();
     490             :     }
     491             : 
     492             : protected:
     493             :     VclBuilder *m_pUIBuilder;
     494             : };
     495             : 
     496             : /*
     497             :  * @return true if rValue is "True", "true", "1", etc.
     498             :  */
     499             : bool VCL_DLLPUBLIC toBool(const OString &rValue);
     500             : 
     501             : #endif
     502             : 
     503             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11