LCOV - code coverage report
Current view: top level - sw/source/uibase/sidebar - ThemePanel.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 1 255 0.4 %
Date: 2015-06-13 12:38:46 Functions: 2 35 5.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             : 
      11             : #include <sal/config.h>
      12             : 
      13             : #include "ThemePanel.hxx"
      14             : 
      15             : #include <swtypes.hxx>
      16             : #include <cmdid.h>
      17             : 
      18             : #include <tools/helpers.hxx>
      19             : 
      20             : #include <svl/intitem.hxx>
      21             : #include <svx/svxids.hrc>
      22             : #include <svx/dlgutil.hxx>
      23             : #include <svx/rulritem.hxx>
      24             : 
      25             : #include <sfx2/sidebar/ControlFactory.hxx>
      26             : #include <sfx2/dispatch.hxx>
      27             : #include <sfx2/bindings.hxx>
      28             : #include <sfx2/viewsh.hxx>
      29             : #include <sfx2/objsh.hxx>
      30             : 
      31             : #include <com/sun/star/frame/XController.hpp>
      32             : #include <com/sun/star/frame/XModel.hpp>
      33             : #include <com/sun/star/frame/DocumentTemplates.hpp>
      34             : #include <com/sun/star/frame/XDocumentTemplates.hpp>
      35             : #include <com/sun/star/document/XUndoManagerSupplier.hpp>
      36             : 
      37             : #include <editeng/fontitem.hxx>
      38             : #include <editeng/boxitem.hxx>
      39             : #include <editeng/borderline.hxx>
      40             : #include "charatr.hxx"
      41             : #include "charfmt.hxx"
      42             : #include "docstyle.hxx"
      43             : #include "fmtcol.hxx"
      44             : #include "format.hxx"
      45             : 
      46             : namespace
      47             : {
      48             : 
      49           0 : class FontSet
      50             : {
      51             : public:
      52             :     OUString maName;
      53             :     OUString msMonoFont;
      54             :     OUString msHeadingFont;
      55             :     OUString msBaseFont;
      56             : };
      57             : 
      58           0 : class ColorSet
      59             : {
      60             : public:
      61             :     OUString maName;
      62             :     Color maColors[10];
      63             : };
      64             : 
      65             : class ColorVariable
      66             : {
      67             : public:
      68             :     long mnIndex;
      69             :     Color maColor;
      70             :     sal_Int16 mnTintShade;
      71             : 
      72           0 :     ColorVariable()
      73             :         : mnIndex(-1)
      74             :         , maColor()
      75           0 :         , mnTintShade()
      76           0 :     {}
      77             : 
      78           0 :     ColorVariable(long nIndex, sal_Int16 nTintShade = 0)
      79             :         : mnIndex(nIndex)
      80             :         , maColor()
      81           0 :         , mnTintShade(nTintShade)
      82           0 :     {}
      83             : };
      84             : 
      85           0 : class StyleRedefinition
      86             : {
      87             :     ColorVariable maVariable;
      88             : 
      89             : public:
      90             :     OUString maElementName;
      91             : 
      92             : public:
      93           0 :     explicit StyleRedefinition(const OUString& aElementName)
      94           0 :         : maElementName(aElementName)
      95           0 :     {}
      96             : 
      97           0 :     void setColorVariable(ColorVariable aVariable)
      98             :     {
      99           0 :         maVariable = aVariable;
     100           0 :     }
     101             : 
     102           0 :     Color getColor(ColorSet& rColorSet)
     103             :     {
     104           0 :         Color aColor;
     105           0 :         if (maVariable.mnIndex > -1)
     106             :         {
     107           0 :             aColor.SetColor(rColorSet.maColors[maVariable.mnIndex].GetColor());
     108           0 :             if (maVariable.mnTintShade < 0)
     109             :             {
     110           0 :                 double fFactor = std::abs(maVariable.mnTintShade) / 10000.0;
     111           0 :                 aColor.SetRed(MinMax(aColor.GetRed() + (fFactor * (255.0 - aColor.GetRed())), 0, 255));
     112           0 :                 aColor.SetGreen(MinMax(aColor.GetGreen() + (fFactor * (255.0 - aColor.GetGreen())), 0, 255));
     113           0 :                 aColor.SetBlue(MinMax(aColor.GetBlue() + (fFactor * (255.0 - aColor.GetBlue())), 0, 255));
     114             :             }
     115           0 :             else if (maVariable.mnTintShade > 0)
     116             :             {
     117           0 :                 double fFactor = 1.0 - std::abs(maVariable.mnTintShade) / 10000.0;
     118           0 :                 aColor.SetRed(MinMax(aColor.GetRed() * fFactor, 0, 255));
     119           0 :                 aColor.SetGreen(MinMax(aColor.GetGreen() * fFactor, 0, 255));
     120           0 :                 aColor.SetBlue(MinMax(aColor.GetBlue() * fFactor, 0, 255));
     121             :             }
     122             :         }
     123             :         else
     124             :         {
     125           0 :             aColor.SetColor(maVariable.maColor.GetColor());
     126             :         }
     127           0 :         return aColor;
     128             :     }
     129             : };
     130             : 
     131           0 : class StyleSet
     132             : {
     133             :     OUString maName;
     134             :     std::vector<StyleRedefinition> maStyles;
     135             : 
     136             : public:
     137           0 :     explicit StyleSet(const OUString& aName)
     138             :         : maName(aName)
     139           0 :         , maStyles()
     140           0 :     {}
     141             : 
     142           0 :     void add(StyleRedefinition aRedefinition)
     143             :     {
     144           0 :         maStyles.push_back(aRedefinition);
     145           0 :     }
     146             : 
     147           0 :     StyleRedefinition* get(const OUString& aString)
     148             :     {
     149           0 :         for (size_t i = 0; i < maStyles.size(); i++)
     150             :         {
     151           0 :             if (maStyles[i].maElementName == aString)
     152             :             {
     153           0 :                 return &maStyles[i];
     154             :             }
     155             :         }
     156           0 :         return nullptr;
     157             :     }
     158             : };
     159             : 
     160           0 : StyleSet setupThemes()
     161             : {
     162           0 :     StyleSet aSet("Default");
     163             : 
     164             :     {
     165           0 :         StyleRedefinition aRedefinition("Heading 1");
     166           0 :         aRedefinition.setColorVariable(ColorVariable(0, 4000));
     167           0 :         aSet.add(aRedefinition);
     168             :     }
     169             : 
     170             :     {
     171           0 :         StyleRedefinition aRedefinition("Heading 2");
     172           0 :         aRedefinition.setColorVariable(ColorVariable(0, 2500));
     173           0 :         aSet.add(aRedefinition);
     174             :     }
     175             : 
     176             :     {
     177           0 :         StyleRedefinition aRedefinition("Heading 3");
     178           0 :         aRedefinition.setColorVariable(ColorVariable(0, 1000));
     179           0 :         aSet.add(aRedefinition);
     180             :     }
     181             : 
     182             :     {
     183           0 :         StyleRedefinition aRedefinition("Heading 4");
     184           0 :         aRedefinition.setColorVariable(ColorVariable(0));
     185           0 :         aSet.add(aRedefinition);
     186             :     }
     187             : 
     188             :     {
     189           0 :         StyleRedefinition aRedefinition("Heading 5");
     190           0 :         aRedefinition.setColorVariable(ColorVariable(0, -500));
     191           0 :         aSet.add(aRedefinition);
     192             :     }
     193             : 
     194             :     {
     195           0 :         StyleRedefinition aRedefinition("Heading 6");
     196           0 :         aRedefinition.setColorVariable(ColorVariable(0, -1000));
     197           0 :         aSet.add(aRedefinition);
     198             :     }
     199             : 
     200             :     {
     201           0 :         StyleRedefinition aRedefinition("Heading 7");
     202           0 :         aRedefinition.setColorVariable(ColorVariable(0, -1500));
     203           0 :         aSet.add(aRedefinition);
     204             :     }
     205             : 
     206             :     {
     207           0 :         StyleRedefinition aRedefinition("Heading 8");
     208           0 :         aRedefinition.setColorVariable(ColorVariable(0, -2000));
     209           0 :         aSet.add(aRedefinition);
     210             :     }
     211             : 
     212             :     {
     213           0 :         StyleRedefinition aRedefinition("Heading 9");
     214           0 :         aRedefinition.setColorVariable(ColorVariable(0, -2500));
     215           0 :         aSet.add(aRedefinition);
     216             :     }
     217             : 
     218             :     {
     219           0 :         StyleRedefinition aRedefinition("Heading 10");
     220           0 :         aRedefinition.setColorVariable(ColorVariable(0, -3000));
     221           0 :         aSet.add(aRedefinition);
     222             :     }
     223             : 
     224           0 :     return aSet;
     225             : }
     226             : 
     227           0 : void changeFont(SwFormat* pFormat, SwDocStyleSheet* pStyle, FontSet& rFontSet)
     228             : {
     229           0 :     bool bChanged = false;
     230             : 
     231           0 :     if (pStyle->GetName() != "Default Style" && pFormat->GetAttrSet().GetItem(RES_CHRATR_FONT, false) == nullptr)
     232             :     {
     233           0 :         return;
     234             :     }
     235             : 
     236           0 :     SvxFontItem aFontItem(static_cast<const SvxFontItem&>(pFormat->GetFont(false)));
     237             : 
     238           0 :     FontPitch ePitch = aFontItem.GetPitch();
     239             : 
     240           0 :     if (ePitch == PITCH_FIXED)
     241             :     {
     242           0 :         aFontItem.SetFamilyName(rFontSet.msMonoFont);
     243           0 :         bChanged = true;
     244             :     }
     245             :     else
     246             :     {
     247           0 :         if (pStyle->GetName() == "Heading")
     248             :         {
     249           0 :             aFontItem.SetFamilyName(rFontSet.msHeadingFont);
     250           0 :             bChanged = true;
     251             :         }
     252             :         else
     253             :         {
     254           0 :             aFontItem.SetFamilyName(rFontSet.msBaseFont);
     255           0 :             bChanged = true;
     256             :         }
     257             :     }
     258             : 
     259           0 :     if (bChanged)
     260             :     {
     261           0 :         pFormat->SetFormatAttr(aFontItem);
     262           0 :     }
     263             : }
     264             : 
     265             : /*void changeBorder(SwTextFormatColl* pCollection, SwDocStyleSheet* pStyle, StyleSet& rStyleSet)
     266             : {
     267             :     if (pStyle->GetName() == "Heading")
     268             :     {
     269             :         SvxBoxItem aBoxItem(pCollection->GetBox());
     270             :         editeng::SvxBorderLine aBorderLine;
     271             :         aBorderLine.SetWidth(40); //20 = 1pt
     272             :         aBorderLine.SetColor(rColorSet.mBaseColors[0]);
     273             :         aBoxItem.SetLine(&aBorderLine, SvxBoxItemLine::BOTTOM);
     274             : 
     275             :         pCollection->SetFormatAttr(aBoxItem);
     276             :     }
     277             : }*/
     278             : 
     279           0 : void changeColor(SwTextFormatColl* pCollection, ColorSet& rColorSet, StyleRedefinition* pRedefinition)
     280             : {
     281           0 :     Color aColor = pRedefinition->getColor(rColorSet);
     282             : 
     283           0 :     SvxColorItem aColorItem(pCollection->GetColor());
     284           0 :     aColorItem.SetValue(aColor);
     285           0 :     pCollection->SetFormatAttr(aColorItem);
     286           0 : }
     287             : 
     288           0 : std::vector<FontSet> initFontSets()
     289             : {
     290           0 :     std::vector<FontSet> aFontSets;
     291             :     {
     292           0 :         FontSet aFontSet;
     293           0 :         aFontSet.maName = "Liberation Family";
     294           0 :         aFontSet.msHeadingFont = "Liberation Sans";
     295           0 :         aFontSet.msBaseFont = "Liberation Serif";
     296           0 :         aFontSet.msMonoFont = "Liberation Mono";
     297           0 :         aFontSets.push_back(aFontSet);
     298             :     }
     299             :     {
     300           0 :         FontSet aFontSet;
     301           0 :         aFontSet.maName = "DejaVu Family";
     302           0 :         aFontSet.msHeadingFont = "DejaVu Sans";
     303           0 :         aFontSet.msBaseFont = "DejaVu Serif";
     304           0 :         aFontSet.msMonoFont = "DejaVu Sans Mono";
     305           0 :         aFontSets.push_back(aFontSet);
     306             :     }
     307             :     {
     308           0 :         FontSet aFontSet;
     309           0 :         aFontSet.maName = "Croscore Modern";
     310           0 :         aFontSet.msHeadingFont = "Caladea";
     311           0 :         aFontSet.msBaseFont = "Carlito";
     312           0 :         aFontSet.msMonoFont = "Liberation Mono";
     313           0 :         aFontSets.push_back(aFontSet);
     314             :     }
     315             :     {
     316           0 :         FontSet aFontSet;
     317           0 :         aFontSet.maName = "Carlito";
     318           0 :         aFontSet.msHeadingFont = "Carlito";
     319           0 :         aFontSet.msBaseFont = "Carlito";
     320           0 :         aFontSet.msMonoFont = "Liberation Mono";
     321           0 :         aFontSets.push_back(aFontSet);
     322             :     }
     323             :     {
     324           0 :         FontSet aFontSet;
     325           0 :         aFontSet.maName = "Source Sans Family";
     326           0 :         aFontSet.msHeadingFont = "Source Sans Pro";
     327           0 :         aFontSet.msBaseFont = "Source Sans Pro";
     328           0 :         aFontSet.msMonoFont = "Source Code Pro";
     329           0 :         aFontSets.push_back(aFontSet);
     330             :     }
     331             :     {
     332           0 :         FontSet aFontSet;
     333           0 :         aFontSet.maName = "Source Sans Family 2";
     334           0 :         aFontSet.msHeadingFont = "Source Sans Pro";
     335           0 :         aFontSet.msBaseFont = "Source Sans Pro Light";
     336           0 :         aFontSet.msMonoFont = "Source Code Pro";
     337           0 :         aFontSets.push_back(aFontSet);
     338             :     }
     339             :     {
     340           0 :         FontSet aFontSet;
     341           0 :         aFontSet.maName = "Libertine Family";
     342           0 :         aFontSet.msHeadingFont = "Linux Biolinum G";
     343           0 :         aFontSet.msBaseFont = "Linux Libertine G";
     344           0 :         aFontSet.msMonoFont = "Liberation Mono";
     345           0 :         aFontSets.push_back(aFontSet);
     346             :     }
     347             :     {
     348           0 :         FontSet aFontSet;
     349           0 :         aFontSet.maName = "Open Sans";
     350           0 :         aFontSet.msHeadingFont = "Open Sans";
     351           0 :         aFontSet.msBaseFont = "Open Sans";
     352           0 :         aFontSet.msMonoFont = "Droid Sans Mono";
     353           0 :         aFontSets.push_back(aFontSet);
     354             :     }
     355             :     {
     356           0 :         FontSet aFontSet;
     357           0 :         aFontSet.maName = "Droid Sans";
     358           0 :         aFontSet.msHeadingFont = "Droid Sans";
     359           0 :         aFontSet.msBaseFont = "Droid Sans";
     360           0 :         aFontSet.msMonoFont = "Droid Sans Mono";
     361           0 :         aFontSets.push_back(aFontSet);
     362             :     }
     363           0 :     return aFontSets;
     364             : }
     365             : 
     366           0 : FontSet getFontSet(const OUString& rFontVariant, std::vector<FontSet>& aFontSets)
     367             : {
     368           0 :     for (size_t i = 0; i < aFontSets.size(); ++i)
     369             :     {
     370           0 :         if (aFontSets[i].maName == rFontVariant)
     371           0 :             return aFontSets[i];
     372             :     }
     373           0 :     return aFontSets[0];
     374             : }
     375             : 
     376           0 : std::vector<ColorSet> initColorSets()
     377             : {
     378           0 :     std::vector<ColorSet> aColorSets;
     379             :     {
     380           0 :         ColorSet aColorSet;
     381           0 :         aColorSet.maName = "Default";
     382           0 :         aColorSet.maColors[0] = Color(0x00, 0x00, 0x00);
     383           0 :         aColorSets.push_back(aColorSet);
     384             :     }
     385             :     {
     386           0 :         ColorSet aColorSet;
     387           0 :         aColorSet.maName = "Red";
     388           0 :         aColorSet.maColors[0] = Color(0xa4, 0x00, 0x00);
     389           0 :         aColorSets.push_back(aColorSet);
     390             :     }
     391             :     {
     392           0 :         ColorSet aColorSet;
     393           0 :         aColorSet.maName = "Green";
     394           0 :         aColorSet.maColors[0] = Color(0x00, 0xa4, 0x00);
     395           0 :         aColorSets.push_back(aColorSet);
     396             :     }
     397             :     {
     398           0 :         ColorSet aColorSet;
     399           0 :         aColorSet.maName = "Blue";
     400           0 :         aColorSet.maColors[0] = Color(0x00, 0x00, 0xa4);
     401           0 :         aColorSets.push_back(aColorSet);
     402             :     }
     403             :     {
     404           0 :         ColorSet aColorSet;
     405           0 :         aColorSet.maName = "Sky";
     406           0 :         aColorSet.maColors[0] = Color(0x72, 0x9f, 0xcf);
     407           0 :         aColorSets.push_back(aColorSet);
     408             :     }
     409             : 
     410           0 :     return aColorSets;
     411             : }
     412             : 
     413           0 : ColorSet getColorSet(const OUString& rColorVariant, std::vector<ColorSet>& aColorSets)
     414             : {
     415           0 :     for (size_t i = 0; i < aColorSets.size(); ++i)
     416             :     {
     417           0 :         if (aColorSets[i].maName == rColorVariant)
     418           0 :             return aColorSets[i];
     419             :     }
     420           0 :     return aColorSets[0];
     421             : }
     422             : 
     423           0 : void applyTheme(SfxStyleSheetBasePool* pPool, const OUString& sFontSetName, const OUString& sColorSetName, StyleSet& rStyleSet)
     424             : {
     425             :     SwDocStyleSheet* pStyle;
     426             : 
     427           0 :     std::vector<FontSet> aFontSets = initFontSets();
     428           0 :     FontSet aFontSet = getFontSet(sFontSetName, aFontSets);
     429             : 
     430           0 :     std::vector<ColorSet> aColorSets = initColorSets();
     431           0 :     ColorSet aColorSet = getColorSet(sColorSetName, aColorSets);
     432             : 
     433           0 :     pPool->SetSearchMask(SFX_STYLE_FAMILY_PARA, SFXSTYLEBIT_ALL);
     434           0 :     pStyle = static_cast<SwDocStyleSheet*>(pPool->First());
     435             : 
     436           0 :     while (pStyle)
     437             :     {
     438           0 :         SwTextFormatColl* pCollection = pStyle->GetCollection();
     439             : 
     440           0 :         changeFont(pCollection, pStyle, aFontSet);
     441             : 
     442           0 :         StyleRedefinition* pRedefinition = rStyleSet.get(pStyle->GetName());
     443             : 
     444           0 :         if (pRedefinition)
     445             :         {
     446           0 :             changeColor(pCollection, aColorSet, pRedefinition);
     447             :         }
     448             : 
     449           0 :         pStyle = static_cast<SwDocStyleSheet*>(pPool->Next());
     450             :     }
     451             : 
     452           0 :     pPool->SetSearchMask(SFX_STYLE_FAMILY_CHAR, SFXSTYLEBIT_ALL);
     453           0 :     pStyle = static_cast<SwDocStyleSheet*>(pPool->First());
     454             : 
     455           0 :     while (pStyle)
     456             :     {
     457           0 :         SwCharFormat* pCharFormat = pStyle->GetCharFormat();
     458             : 
     459           0 :         changeFont(static_cast<SwFormat*>(pCharFormat), pStyle, aFontSet);
     460             : 
     461           0 :         pStyle = static_cast<SwDocStyleSheet*>(pPool->Next());
     462           0 :     }
     463           0 : }
     464             : 
     465             : } // end anonymous namespace
     466             : 
     467             : namespace sw { namespace sidebar {
     468             : 
     469           0 : VclPtr<vcl::Window> ThemePanel::Create (vcl::Window* pParent,
     470             :                                         const css::uno::Reference<css::frame::XFrame>& rxFrame,
     471             :                                         SfxBindings* pBindings)
     472             : {
     473           0 :     if (pParent == NULL)
     474           0 :         throw css::lang::IllegalArgumentException("no parent Window given to PagePropertyPanel::Create", NULL, 0);
     475           0 :     if (!rxFrame.is())
     476           0 :         throw css::lang::IllegalArgumentException("no XFrame given to PagePropertyPanel::Create", NULL, 1);
     477           0 :     if (pBindings == NULL)
     478           0 :         throw css::lang::IllegalArgumentException("no SfxBindings given to PagePropertyPanel::Create", NULL, 2);
     479             : 
     480           0 :     return VclPtr<ThemePanel>::Create(pParent, rxFrame, pBindings);
     481             : }
     482             : 
     483           0 : ThemePanel::ThemePanel(vcl::Window* pParent,
     484             :                                const css::uno::Reference<css::frame::XFrame>& rxFrame,
     485             :                                SfxBindings* pBindings)
     486             :     : PanelLayout(pParent, "ThemePanel", "modules/swriter/ui/sidebartheme.ui", rxFrame)
     487           0 :     , mpBindings(pBindings)
     488             : {
     489           0 :     get(mpListBoxFonts,  "listbox_fonts");
     490           0 :     get(mpListBoxColors, "listbox_colors");
     491           0 :     get(mpApplyButton,   "apply");
     492             : 
     493           0 :     mpApplyButton->SetClickHdl(LINK(this, ThemePanel, ClickHdl));
     494           0 :     mpListBoxFonts->SetDoubleClickHdl(LINK(this, ThemePanel, ClickHdl));
     495           0 :     mpListBoxColors->SetDoubleClickHdl(LINK(this, ThemePanel, ClickHdl));
     496             : 
     497           0 :     std::vector<FontSet> aFontSets = initFontSets();
     498           0 :     for (size_t i = 0; i < aFontSets.size(); ++i)
     499             :     {
     500           0 :         mpListBoxFonts->InsertEntry(aFontSets[i].maName);
     501             :     }
     502             : 
     503           0 :     std::vector<ColorSet> aColorSets = initColorSets();
     504           0 :     for (size_t i = 0; i < aColorSets.size(); ++i)
     505             :     {
     506           0 :         mpListBoxColors->InsertEntry(aColorSets[i].maName);
     507           0 :     }
     508           0 : }
     509             : 
     510           0 : ThemePanel::~ThemePanel()
     511             : {
     512           0 :     disposeOnce();
     513           0 : }
     514             : 
     515           0 : void ThemePanel::dispose()
     516             : {
     517           0 :     mpListBoxFonts.clear();
     518           0 :     mpListBoxColors.clear();
     519           0 :     mpApplyButton.clear();
     520             : 
     521           0 :     PanelLayout::dispose();
     522           0 : }
     523             : 
     524           0 : IMPL_LINK_NOARG(ThemePanel, ClickHdl)
     525             : {
     526           0 :     SwDocShell* pDocSh = static_cast<SwDocShell*>(SfxObjectShell::Current());
     527           0 :     if (pDocSh)
     528             :     {
     529           0 :         OUString sEntryFonts = mpListBoxFonts->GetSelectEntry();
     530           0 :         OUString sEntryColors = mpListBoxColors->GetSelectEntry();
     531             : 
     532           0 :         StyleSet aStyleSet = setupThemes();
     533             : 
     534           0 :         applyTheme(pDocSh->GetStyleSheetPool(), sEntryFonts, sEntryColors, aStyleSet);
     535             :     }
     536           0 :     return 1;
     537             : }
     538             : 
     539           0 : void ThemePanel::NotifyItemUpdate(const sal_uInt16 /*nSId*/,
     540             :                                          const SfxItemState /*eState*/,
     541             :                                          const SfxPoolItem* /*pState*/,
     542             :                                          const bool /*bIsEnabled*/)
     543             : {
     544           0 : }
     545             : 
     546         177 : }} // end of namespace ::sw::sidebar
     547             : 
     548             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11