From 656513d15116a3c6feeadc6a3353a304e0b3ef2b Mon Sep 17 00:00:00 2001 From: Susobhan Ghosh Date: Thu, 26 May 2016 21:05:14 +0530 Subject: tdf#83830: Moved margin preset control to Format Panel Added new margin presets. Change-Id: I65927ebfaf61515cedd76bb85e0a6d543fc16b89 Reviewed-on: https://gerrit.libreoffice.org/25520 Reviewed-by: Katarina Behrens Tested-by: Katarina Behrens --- sw/source/uibase/sidebar/PageFormatPanel.cxx | 152 +++++++++++++++++++++++- sw/source/uibase/sidebar/PageFormatPanel.hxx | 18 ++- sw/source/uibase/sidebar/PageMarginUtils.hxx | 171 +++++++++++++++++++++++++++ sw/uiconfig/swriter/ui/pageformatpanel.ui | 55 +++++++++ 4 files changed, 394 insertions(+), 2 deletions(-) create mode 100644 sw/source/uibase/sidebar/PageMarginUtils.hxx diff --git a/sw/source/uibase/sidebar/PageFormatPanel.cxx b/sw/source/uibase/sidebar/PageFormatPanel.cxx index 824473883c0e..5bf359dc69e1 100644 --- a/sw/source/uibase/sidebar/PageFormatPanel.cxx +++ b/sw/source/uibase/sidebar/PageFormatPanel.cxx @@ -25,6 +25,7 @@ #include #include #include "PageFormatPanel.hxx" +#include "PageMarginUtils.hxx" #include #include #include @@ -61,15 +62,22 @@ PageFormatPanel::PageFormatPanel( maPaperSizeController(SID_ATTR_PAGE_SIZE, *pBindings, *this), maPaperOrientationController(SID_ATTR_PAGE, *pBindings, *this), maMetricController(SID_ATTR_METRIC, *pBindings,*this), + maSwPageLRControl(SID_ATTR_PAGE_LRSPACE, *pBindings, *this), + maSwPageULControl(SID_ATTR_PAGE_ULSPACE, *pBindings, *this), mpPageItem( new SvxPageItem(SID_ATTR_PAGE) ), + mpPageLRMarginItem( new SvxLongLRSpaceItem( 0, 0, SID_ATTR_PAGE_LRSPACE ) ), + mpPageULMarginItem( new SvxLongULSpaceItem( 0, 0, SID_ATTR_PAGE_ULSPACE ) ), meFUnit(GetModuleFieldUnit()), meLastFUnit(GetModuleFieldUnit()), - meUnit() + meUnit(), + aCustomEntry() { get(mpPaperSizeBox, "papersize"); get(mpPaperWidth, "paperwidth"); get(mpPaperHeight, "paperheight"); get(mpPaperOrientation, "paperorientation"); + get(mpMarginSelectBox, "marginLB"); + get(mpCustomEntry, "customlabel"); Initialize(); } @@ -84,10 +92,16 @@ void PageFormatPanel::dispose() mpPaperWidth.disposeAndClear(); mpPaperHeight.disposeAndClear(); mpPaperOrientation.disposeAndClear(); + mpMarginSelectBox.disposeAndClear(); + mpCustomEntry.clear(); maMetricController.dispose(); maPaperOrientationController.dispose(); maPaperSizeController.dispose(); + maSwPageLRControl.dispose(); + maSwPageULControl.dispose(); + mpPageULMarginItem.reset(); + mpPageLRMarginItem.reset(); mpPageItem.reset(); PanelLayout::dispose(); @@ -100,6 +114,7 @@ void PageFormatPanel::Initialize() meUnit = maPaperSizeController.GetCoreMetric(); SetFieldUnit( *mpPaperWidth, meFUnit ); SetFieldUnit( *mpPaperHeight, meFUnit ); + aCustomEntry = mpCustomEntry->GetText(); const SvtOptionsDrawinglayer aDrawinglayerOpt; mpPaperWidth->SetMax(mpPaperWidth->Normalize(aDrawinglayerOpt.GetMaximumPaperWidth()), FUNIT_CM); @@ -111,10 +126,15 @@ void PageFormatPanel::Initialize() mpPaperOrientation->SetSelectHdl( LINK(this, PageFormatPanel, PaperFormatModifyHdl )); mpPaperHeight->SetModifyHdl( LINK(this, PageFormatPanel, PaperSizeModifyHdl )); mpPaperWidth->SetModifyHdl( LINK(this, PageFormatPanel, PaperSizeModifyHdl )); + mpMarginSelectBox->SetSelectHdl( LINK(this, PageFormatPanel, PaperModifyMarginHdl)); mpBindings->Update(SID_ATTR_METRIC); mpBindings->Update(SID_ATTR_PAGE); mpBindings->Update(SID_ATTR_PAGE_SIZE); + mpBindings->Update( SID_ATTR_PAGE_LRSPACE ); + mpBindings->Update( SID_ATTR_PAGE_ULSPACE ); + + UpdateMarginBox(); } void PageFormatPanel::NotifyItemUpdate( @@ -172,6 +192,26 @@ void PageFormatPanel::NotifyItemUpdate( } } break; + case SID_ATTR_PAGE_LRSPACE: + { + if ( eState >= SfxItemState::DEFAULT && + pState && dynamic_cast< const SvxLongLRSpaceItem *>( pState ) != nullptr ) + { + mpPageLRMarginItem.reset( static_cast(pState->Clone()) ); + UpdateMarginBox(); + } + } + break; + case SID_ATTR_PAGE_ULSPACE: + { + if ( eState >= SfxItemState::DEFAULT && + pState && dynamic_cast< const SvxLongULSpaceItem *>( pState ) != nullptr ) + { + mpPageULMarginItem.reset( static_cast(pState->Clone()) ); + UpdateMarginBox(); + } + } + break; default: break; } @@ -197,6 +237,51 @@ IMPL_LINK_NOARG_TYPED(PageFormatPanel, PaperSizeModifyHdl, Edit&, void) mpBindings->GetDispatcher()->ExecuteList(SID_ATTR_PAGE_SIZE, SfxCallMode::RECORD, { &aSizeItem }); } +IMPL_LINK_NOARG_TYPED(PageFormatPanel, PaperModifyMarginHdl, ListBox&, void) +{ + bool bMirrored = false; + bool bApplyNewPageMargins = true; + switch ( mpMarginSelectBox->GetSelectEntryPos() ) + { + case 0: + SetNarrow(mnPageLeftMargin, mnPageRightMargin, mnPageTopMargin, mnPageBottomMargin, bMirrored); + break; + case 1: + SetModerate(mnPageLeftMargin, mnPageRightMargin, mnPageTopMargin, mnPageBottomMargin, bMirrored); + break; + case 2: + SetNormal075(mnPageLeftMargin, mnPageRightMargin, mnPageTopMargin, mnPageBottomMargin, bMirrored); + break; + case 3: + SetNormal100(mnPageLeftMargin, mnPageRightMargin, mnPageTopMargin, mnPageBottomMargin, bMirrored); + break; + case 4: + SetNormal125(mnPageLeftMargin, mnPageRightMargin, mnPageTopMargin, mnPageBottomMargin, bMirrored); + break; + case 5: + SetWide(mnPageLeftMargin, mnPageRightMargin, mnPageTopMargin, mnPageBottomMargin, bMirrored); + break; + case 6: + SetMirrored(mnPageLeftMargin, mnPageRightMargin, mnPageTopMargin, mnPageBottomMargin, bMirrored); + break; + default: + bApplyNewPageMargins = false; + break; + } + + if(bApplyNewPageMargins) + { + ExecuteMarginLRChange( mnPageLeftMargin, mnPageRightMargin ); + ExecuteMarginULChange( mnPageTopMargin, mnPageBottomMargin ); + if(bMirrored != (mpPageItem->GetPageUsage() == SVX_PAGE_MIRROR)) + { + mpPageItem->SetPageUsage( bMirrored ? SVX_PAGE_MIRROR : SVX_PAGE_ALL ); + mpBindings->GetDispatcher()->ExecuteList(SID_ATTR_PAGE, + SfxCallMode::RECORD, { mpPageItem.get() }); + } + } +} + FieldUnit PageFormatPanel::GetCurrentUnit( SfxItemState eState, const SfxPoolItem* pState ) { FieldUnit eUnit = FUNIT_NONE; @@ -228,6 +313,71 @@ FieldUnit PageFormatPanel::GetCurrentUnit( SfxItemState eState, const SfxPoolIte return eUnit; } +void PageFormatPanel::ExecuteMarginLRChange( const long nPageLeftMargin, const long nPageRightMargin ) +{ + mpPageLRMarginItem->SetLeft( nPageLeftMargin ); + mpPageLRMarginItem->SetRight( nPageRightMargin ); + mpBindings->GetDispatcher()->ExecuteList( SID_ATTR_PAGE_LRSPACE, SfxCallMode::RECORD, { mpPageLRMarginItem.get() }); +} + +void PageFormatPanel::ExecuteMarginULChange(const long nPageTopMargin, const long nPageBottomMargin) +{ + mpPageULMarginItem->SetUpper( nPageTopMargin ); + mpPageULMarginItem->SetLower( nPageBottomMargin ); + mpBindings->GetDispatcher()->ExecuteList( SID_ATTR_PAGE_ULSPACE, SfxCallMode::RECORD, { mpPageULMarginItem.get() }); +} + +void PageFormatPanel::UpdateMarginBox() +{ + mnPageLeftMargin = mpPageLRMarginItem->GetLeft(); + mnPageRightMargin = mpPageLRMarginItem->GetRight(); + mnPageTopMargin = mpPageULMarginItem->GetUpper(); + mnPageBottomMargin = mpPageULMarginItem->GetLower(); + + bool bMirrored = (mpPageItem->GetPageUsage() == SVX_PAGE_MIRROR); + if( IsNarrow(mnPageLeftMargin, mnPageRightMargin, mnPageTopMargin, mnPageBottomMargin, bMirrored) ) + { + mpMarginSelectBox->SelectEntryPos(0); + mpMarginSelectBox->RemoveEntry(aCustomEntry); + } + else if( IsModerate(mnPageLeftMargin, mnPageRightMargin, mnPageTopMargin, mnPageBottomMargin, bMirrored) ) + { + mpMarginSelectBox->SelectEntryPos(1); + mpMarginSelectBox->RemoveEntry(aCustomEntry); + } + else if( IsNormal075(mnPageLeftMargin, mnPageRightMargin, mnPageTopMargin, mnPageBottomMargin, bMirrored) ) + { + mpMarginSelectBox->SelectEntryPos(2); + mpMarginSelectBox->RemoveEntry(aCustomEntry); + } + else if( IsNormal100(mnPageLeftMargin, mnPageRightMargin, mnPageTopMargin, mnPageBottomMargin, bMirrored) ) + { + mpMarginSelectBox->SelectEntryPos(3); + mpMarginSelectBox->RemoveEntry(aCustomEntry); + } + else if( IsNormal125(mnPageLeftMargin, mnPageRightMargin, mnPageTopMargin, mnPageBottomMargin, bMirrored) ) + { + mpMarginSelectBox->SelectEntryPos(4); + mpMarginSelectBox->RemoveEntry(aCustomEntry); + } + else if( IsWide(mnPageLeftMargin, mnPageRightMargin, mnPageTopMargin, mnPageBottomMargin, bMirrored) ) + { + mpMarginSelectBox->SelectEntryPos(5); + mpMarginSelectBox->RemoveEntry(aCustomEntry); + } + else if( IsMirrored(mnPageLeftMargin, mnPageRightMargin, mnPageTopMargin, mnPageBottomMargin, bMirrored) ) + { + mpMarginSelectBox->SelectEntryPos(6); + mpMarginSelectBox->RemoveEntry(aCustomEntry); + } + else + { + if(mpMarginSelectBox->GetEntryPos(aCustomEntry) == LISTBOX_ENTRY_NOTFOUND) + mpMarginSelectBox->InsertEntry(aCustomEntry); + mpMarginSelectBox->SelectEntry(aCustomEntry); + } +} + } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/uibase/sidebar/PageFormatPanel.hxx b/sw/source/uibase/sidebar/PageFormatPanel.hxx index e266d96ce0f3..606e01c551bc 100644 --- a/sw/source/uibase/sidebar/PageFormatPanel.hxx +++ b/sw/source/uibase/sidebar/PageFormatPanel.hxx @@ -83,19 +83,35 @@ private: VclPtr mpPaperWidth; VclPtr mpPaperHeight; VclPtr mpPaperOrientation; + VclPtr mpMarginSelectBox; + VclPtr mpCustomEntry; ::sfx2::sidebar::ControllerItem maPaperSizeController; ::sfx2::sidebar::ControllerItem maPaperOrientationController; ::sfx2::sidebar::ControllerItem maMetricController; + ::sfx2::sidebar::ControllerItem maSwPageLRControl; + ::sfx2::sidebar::ControllerItem maSwPageULControl; - ::std::unique_ptr mpPageItem; + ::std::unique_ptr mpPageItem; + ::std::unique_ptr mpPageLRMarginItem; + ::std::unique_ptr mpPageULMarginItem; FieldUnit meFUnit, meLastFUnit; SfxMapUnit meUnit; + long mnPageLeftMargin; + long mnPageRightMargin; + long mnPageTopMargin; + long mnPageBottomMargin; + OUString aCustomEntry; + void Initialize(); + void UpdateMarginBox(); + void ExecuteMarginLRChange( const long nPageLeftMargin, const long nPageRightMargin ); + void ExecuteMarginULChange( const long nPageTopMargin, const long nPageBottomMargin); DECL_LINK_TYPED(PaperFormatModifyHdl, ListBox&, void); DECL_LINK_TYPED(PaperSizeModifyHdl, Edit&, void); + DECL_LINK_TYPED(PaperModifyMarginHdl, ListBox&, void ); }; } } //end of namespace sw::sidebar diff --git a/sw/source/uibase/sidebar/PageMarginUtils.hxx b/sw/source/uibase/sidebar/PageMarginUtils.hxx new file mode 100644 index 000000000000..da8b73cadbed --- /dev/null +++ b/sw/source/uibase/sidebar/PageMarginUtils.hxx @@ -0,0 +1,171 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include +#define SWPAGE_NARROW_VALUE 720 +#define SWPAGE_MODERATE_LR 1080 +#define SWPAGE_NORMAL_VALUE 1136 +#define SWPAGE_WIDE_VALUE1 1440 +#define SWPAGE_WIDE_VALUE2 2880 +#define SWPAGE_WIDE_VALUE3 1800 +#define SWPAGE_UNIT_THRESHOLD 5 + +namespace sw { namespace sidebar{ + +bool IsNarrow( const long nPageLeftMargin, const long nPageRightMargin, + const long nPageTopMargin, const long nPageBottomMargin, bool bMirrored) +{ + return( std::abs(nPageLeftMargin - SWPAGE_NARROW_VALUE) <= SWPAGE_UNIT_THRESHOLD && + std::abs(nPageRightMargin - SWPAGE_NARROW_VALUE) <= SWPAGE_UNIT_THRESHOLD && + std::abs(nPageTopMargin - SWPAGE_NARROW_VALUE) <= SWPAGE_UNIT_THRESHOLD && + std::abs(nPageBottomMargin - SWPAGE_NARROW_VALUE) <= SWPAGE_UNIT_THRESHOLD && + !bMirrored ); +} + +void SetNarrow( long& nPageLeftMargin, long& nPageRightMargin, + long& nPageTopMargin, long& nPageBottomMargin, bool& bMirrored) +{ + nPageLeftMargin = SWPAGE_NARROW_VALUE; + nPageRightMargin = SWPAGE_NARROW_VALUE; + nPageTopMargin = SWPAGE_NARROW_VALUE; + nPageBottomMargin = SWPAGE_NARROW_VALUE; + bMirrored = false; +} + +bool IsModerate( const long nPageLeftMargin, const long nPageRightMargin, + const long nPageTopMargin, const long nPageBottomMargin, bool bMirrored) +{ + return( std::abs(nPageLeftMargin - SWPAGE_MODERATE_LR) <= SWPAGE_UNIT_THRESHOLD && + std::abs(nPageRightMargin - SWPAGE_MODERATE_LR) <= SWPAGE_UNIT_THRESHOLD && + std::abs(nPageTopMargin - SWPAGE_WIDE_VALUE1) <= SWPAGE_UNIT_THRESHOLD && + std::abs(nPageBottomMargin - SWPAGE_WIDE_VALUE1) <= SWPAGE_UNIT_THRESHOLD && + !bMirrored ); +} + +void SetModerate( long& nPageLeftMargin, long& nPageRightMargin, + long& nPageTopMargin, long& nPageBottomMargin, bool& bMirrored) +{ + nPageLeftMargin = SWPAGE_MODERATE_LR; + nPageRightMargin = SWPAGE_MODERATE_LR; + nPageTopMargin = SWPAGE_WIDE_VALUE1; + nPageBottomMargin = SWPAGE_WIDE_VALUE1; + bMirrored = false; +} + +bool IsNormal075( const long nPageLeftMargin, const long nPageRightMargin, + const long nPageTopMargin, const long nPageBottomMargin, bool bMirrored) +{ + return( std::abs(nPageLeftMargin - SWPAGE_NORMAL_VALUE) <= SWPAGE_UNIT_THRESHOLD && + std::abs(nPageRightMargin - SWPAGE_NORMAL_VALUE) <= SWPAGE_UNIT_THRESHOLD && + std::abs(nPageTopMargin - SWPAGE_NORMAL_VALUE) <= SWPAGE_UNIT_THRESHOLD && + std::abs(nPageBottomMargin - SWPAGE_NORMAL_VALUE) <= SWPAGE_UNIT_THRESHOLD && + !bMirrored ); +} + +void SetNormal075( long& nPageLeftMargin, long& nPageRightMargin, + long& nPageTopMargin, long& nPageBottomMargin, bool& bMirrored) +{ + nPageLeftMargin = SWPAGE_NORMAL_VALUE; + nPageRightMargin = SWPAGE_NORMAL_VALUE; + nPageTopMargin = SWPAGE_NORMAL_VALUE; + nPageBottomMargin = SWPAGE_NORMAL_VALUE; + bMirrored = false; +} + +bool IsNormal100( const long nPageLeftMargin, const long nPageRightMargin, + const long nPageTopMargin, const long nPageBottomMargin, bool bMirrored) +{ + return( std::abs(nPageLeftMargin - SWPAGE_WIDE_VALUE1) <= SWPAGE_UNIT_THRESHOLD && + std::abs(nPageRightMargin - SWPAGE_WIDE_VALUE1) <= SWPAGE_UNIT_THRESHOLD && + std::abs(nPageTopMargin - SWPAGE_WIDE_VALUE1) <= SWPAGE_UNIT_THRESHOLD && + std::abs(nPageBottomMargin - SWPAGE_WIDE_VALUE1) <= SWPAGE_UNIT_THRESHOLD && + !bMirrored ); +} + +void SetNormal100( long& nPageLeftMargin, long& nPageRightMargin, + long& nPageTopMargin, long& nPageBottomMargin, bool& bMirrored) +{ + nPageLeftMargin = SWPAGE_WIDE_VALUE1; + nPageRightMargin = SWPAGE_WIDE_VALUE1; + nPageTopMargin = SWPAGE_WIDE_VALUE1; + nPageBottomMargin = SWPAGE_WIDE_VALUE1; + bMirrored = false; +} + +bool IsNormal125( const long nPageLeftMargin, const long nPageRightMargin, + const long nPageTopMargin, const long nPageBottomMargin, bool bMirrored) +{ + return( std::abs(nPageLeftMargin - SWPAGE_WIDE_VALUE3) <= SWPAGE_UNIT_THRESHOLD && + std::abs(nPageRightMargin - SWPAGE_WIDE_VALUE3) <= SWPAGE_UNIT_THRESHOLD && + std::abs(nPageTopMargin - SWPAGE_WIDE_VALUE1) <= SWPAGE_UNIT_THRESHOLD && + std::abs(nPageBottomMargin - SWPAGE_WIDE_VALUE1) <= SWPAGE_UNIT_THRESHOLD && + !bMirrored ); +} + +void SetNormal125( long& nPageLeftMargin, long& nPageRightMargin, + long& nPageTopMargin, long& nPageBottomMargin, bool& bMirrored) +{ + nPageLeftMargin = SWPAGE_WIDE_VALUE3; + nPageRightMargin = SWPAGE_WIDE_VALUE3; + nPageTopMargin = SWPAGE_WIDE_VALUE1; + nPageBottomMargin = SWPAGE_WIDE_VALUE1; + bMirrored = false; +} + +bool IsWide( const long nPageLeftMargin, const long nPageRightMargin, + const long nPageTopMargin, const long nPageBottomMargin, bool bMirrored) +{ + return( std::abs(nPageLeftMargin - SWPAGE_WIDE_VALUE2) <= SWPAGE_UNIT_THRESHOLD && + std::abs(nPageRightMargin - SWPAGE_WIDE_VALUE2) <= SWPAGE_UNIT_THRESHOLD && + std::abs(nPageTopMargin - SWPAGE_WIDE_VALUE1) <= SWPAGE_UNIT_THRESHOLD && + std::abs(nPageBottomMargin - SWPAGE_WIDE_VALUE1) <= SWPAGE_UNIT_THRESHOLD && + !bMirrored ); +} + +void SetWide( long& nPageLeftMargin, long& nPageRightMargin, + long& nPageTopMargin, long& nPageBottomMargin, bool& bMirrored) +{ + nPageLeftMargin = SWPAGE_WIDE_VALUE2; + nPageRightMargin = SWPAGE_WIDE_VALUE2; + nPageTopMargin = SWPAGE_WIDE_VALUE1; + nPageBottomMargin = SWPAGE_WIDE_VALUE1; + bMirrored = false; +} + +bool IsMirrored( const long nPageLeftMargin, const long nPageRightMargin, + const long nPageTopMargin, const long nPageBottomMargin, bool bMirrored) +{ + return( std::abs(nPageLeftMargin - SWPAGE_WIDE_VALUE3) <= SWPAGE_UNIT_THRESHOLD && + std::abs(nPageRightMargin - SWPAGE_WIDE_VALUE1) <= SWPAGE_UNIT_THRESHOLD && + std::abs(nPageTopMargin - SWPAGE_WIDE_VALUE1) <= SWPAGE_UNIT_THRESHOLD && + std::abs(nPageBottomMargin - SWPAGE_WIDE_VALUE1) <= SWPAGE_UNIT_THRESHOLD && + bMirrored ); +} + +void SetMirrored( long& nPageLeftMargin, long& nPageRightMargin, + long& nPageTopMargin, long& nPageBottomMargin, bool& bMirrored) +{ + nPageLeftMargin = SWPAGE_WIDE_VALUE3; + nPageRightMargin = SWPAGE_WIDE_VALUE1; + nPageTopMargin = SWPAGE_WIDE_VALUE1; + nPageBottomMargin = SWPAGE_WIDE_VALUE1; + bMirrored = true; +} +} } + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ \ No newline at end of file diff --git a/sw/uiconfig/swriter/ui/pageformatpanel.ui b/sw/uiconfig/swriter/ui/pageformatpanel.ui index 5d503304bc57..46fc942d14c8 100644 --- a/sw/uiconfig/swriter/ui/pageformatpanel.ui +++ b/sw/uiconfig/swriter/ui/pageformatpanel.ui @@ -12,12 +12,14 @@ False True True + 6 6 6 True False + 1 Size: @@ -31,6 +33,7 @@ True False + 1 Width: @@ -44,6 +47,7 @@ True False + 1 Height: @@ -57,6 +61,7 @@ True False + 1 Orientation: @@ -130,6 +135,56 @@ 1 + + + True + False + 1 + Margin: + + + 0 + 4 + 1 + 1 + + + + + True + False + + Narrow + Moderate + Normal 0.75" + Normal 1" + Normal 1.25" + Wide + Mirrored + + + + 1 + 4 + 1 + 1 + + + + + False + Custom + + + 1 + 5 + 1 + 1 + + + + + 0 -- cgit v1.2.3