Files
odfstudio/cui/source/tabpages/numfmt.cxx
T
Michael Weghorn f1f6a505a0 weld: Pass weld::TextWidget& in text change callback/handler
Switch the weld::Entry and weld::TextView handlers
that are called when the text changes due to user
interaction to pass a weld::TextWidget& param
instead of a weld::Entry& and weld::TextView&
one respectively.
Adjust related methods across the code base accordingly.

This unifies the behavior for both of these
weld::TextWidget subclasses and prepares for
deduplicating the logic and moving it to the
common base class in an upcoming commit.

That will also ensure they stay in sync.
(Change also motivated by the fact that their behavior was
differing before

    Change-Id: I03d2a13cd84d53d806eb9e363f49c4b6be28d938
    Author: Michael Weghorn <m.weghorn@posteo.de>
    Date:   Thu Jul 9 13:08:58 2026 +0200

        tdf#130857 weld: Don't signal about programmatic TextView text change
.)

Change-Id: I5572fc88caf577fae9a23a39f1ec4f2179935a99
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207936
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2026-07-10 18:17:27 +02:00

1739 lines
60 KiB
C++

/* -*- 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 <sal/config.h>
#include <o3tl/safeint.hxx>
#include <o3tl/temporary.hxx>
#include <svl/eitem.hxx>
#include <svl/intitem.hxx>
#include <sfx2/objsh.hxx>
#include <vcl/outdev.hxx>
#include <vcl/weld/Builder.hxx>
#include <i18nlangtag/lang.h>
#include <svx/svxids.hrc>
#include <svtools/colorcfg.hxx>
#include <tools/debug.hxx>
#include <numcategories.hrc>
#include <strings.hrc>
#include <svx/numinf.hxx>
#include <numfmt.hxx>
#include <svx/numfmtsh.hxx>
#include <dialmgr.hxx>
#include <sfx2/basedlgs.hxx>
#include <svx/flagsdef.hxx>
#include <vector>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/frame/XModel3.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <limits>
#include <memory>
using ::com::sun::star::uno::Reference;
using ::com::sun::star::lang::XServiceInfo;
using ::com::sun::star::uno::UNO_QUERY;
#define NUMKEY_UNDEFINED SAL_MAX_UINT32
// static ----------------------------------------------------------------
const WhichRangesContainer SvxNumberFormatTabPage::pRanges(
svl::Items<
SID_ATTR_NUMBERFORMAT_VALUE, SID_ATTR_NUMBERFORMAT_INFO, // 10085 - 10086
SID_ATTR_NUMBERFORMAT_ONE_AREA, SID_ATTR_NUMBERFORMAT_ONE_AREA, // 10580 - 10580
SID_ATTR_NUMBERFORMAT_NOLANGUAGE, SID_ATTR_NUMBERFORMAT_NOLANGUAGE, // 10700 - 10700
SID_ATTR_NUMBERFORMAT_SOURCE, SID_ATTR_NUMBERFORMAT_SOURCE>); // 10932 - 10932
/*************************************************************************
#* Method: SvxNumberPreview
#*------------------------------------------------------------------------
#*
#* Class: SvxNumberPreview
#* Function: Constructor of the class SvxNumberPreview
#* Input: Window, Resource-ID
#* Output: ---
#*
#************************************************************************/
SvxNumberPreview::SvxNumberPreview()
: mnPos(-1)
, mnChar(0x0)
{
}
/*************************************************************************
#* Method: NotifyChange
#*------------------------------------------------------------------------
#*
#* Class: SvxNumberPreview
#* Function: Function for changing the preview string
#* Input: String, color
#* Output: ---
#*
#************************************************************************/
void SvxNumberPreview::NotifyChange( const OUString& rPrevStr,
const Color* pColor )
{
// detect and strip out '*' related placeholders
aPrevStr = rPrevStr;
mnPos = aPrevStr.indexOf( 0x1B );
if ( mnPos != -1 )
{
// Right during user input the star symbol is the very
// last character before the user enters another one.
if (mnPos < aPrevStr.getLength() - 1)
{
mnChar = aPrevStr[ mnPos + 1 ];
// delete placeholder and char to repeat
aPrevStr = aPrevStr.replaceAt( mnPos, 2, u"" );
}
else
{
// delete placeholder
aPrevStr = aPrevStr.replaceAt( mnPos, 1, u"" );
// do not attempt to draw a 0 fill character
mnPos = -1;
}
}
if (pColor)
aPrevCol = *pColor;
else
{
svtools::ColorConfig aColorConfig;
Color aFgColor = aColorConfig.GetColorValue(svtools::FONTCOLOR, false).nColor;
if (aFgColor == COL_AUTO)
{
Color aBgColor = aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor;
aFgColor = aBgColor.IsDark() ? COL_WHITE : COL_BLACK;
}
aPrevCol = aFgColor;
}
Invalidate();
}
/*************************************************************************
#* Method: Paint
#*------------------------------------------------------------------------
#*
#* Class: SvxNumberPreview
#* Function: Function for repainting the window.
#* Input: ---
#* Output: ---
#*
#************************************************************************/
void SvxNumberPreview::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle&)
{
auto popIt = rRenderContext.ScopedPush(vcl::PushFlags::ALL);
svtools::ColorConfig aColorConfig;
Color aBgColor = aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor;
Color aFgColor = aColorConfig.GetColorValue(svtools::FONTCOLOR, false).nColor;
if (aFgColor == COL_AUTO)
aFgColor = aBgColor.IsDark() ? COL_WHITE : COL_BLACK;
rRenderContext.SetBackground(aBgColor);
rRenderContext.SetTextColor(aFgColor);
rRenderContext.Erase();
vcl::Font aDrawFont = rRenderContext.GetFont();
Size aSzWnd(GetOutputSizePixel());
OUString aTmpStr(aPrevStr);
tools::Long nLeadSpace = (aSzWnd.Width() - rRenderContext.GetTextWidth(aTmpStr)) / 2;
aDrawFont.SetTransparent(true);
aDrawFont.SetColor(aPrevCol);
rRenderContext.SetFont(aDrawFont);
if (mnPos != -1)
{
tools::Long nCharWidth = rRenderContext.GetTextWidth(OUString(mnChar));
int nNumCharsToInsert = 0;
if (nCharWidth > 0)
nNumCharsToInsert = nLeadSpace / nCharWidth;
if (nNumCharsToInsert > 0)
{
for (int i = 0; i < nNumCharsToInsert; ++i)
aTmpStr = aTmpStr.replaceAt(mnPos, 0, rtl::OUStringChar(mnChar));
}
}
tools::Long nX = 0;
if (mnPos == -1 && nLeadSpace > 0) //tdf#122120 if it won't fit anyway, then left align it
{
nX = nLeadSpace;
}
Point aPosText(nX, (aSzWnd.Height() - GetTextHeight()) / 2);
rRenderContext.DrawText(aPosText, aTmpStr);
}
// class SvxNumberFormatTabPage ------------------------------------------
SvxNumberFormatTabPage::SvxNumberFormatTabPage(weld::Container* pPage, weld::DialogController* pController,
const SfxItemSet& rCoreAttrs)
: SfxTabPage(pPage, pController, u"cui/ui/numberingformatpage.ui"_ustr, u"NumberingFormatPage"_ustr, &rCoreAttrs)
, nInitFormat(std::numeric_limits<sal_uInt32>::max())
, m_nLbFormatSelPosEdComment(SELPOS_NONE)
, bLegacyAutomaticCurrency(false)
, sAutomaticLangEntry(CuiResId(RID_CUISTR_AUTO_ENTRY))
, m_xCategoryFrame(m_xBuilder->weld_frame(u"categoryframe"_ustr))
, m_xLbCategory(m_xBuilder->weld_tree_view(u"categorylb"_ustr))
, m_xFormatFrame(m_xBuilder->weld_frame(u"formatframe"_ustr))
, m_xLbCurrency(m_xBuilder->weld_combo_box(u"currencylb"_ustr))
, m_xLbFormat(m_xBuilder->weld_tree_view(u"formatlb"_ustr))
, m_xFrameLocale(m_xBuilder->weld_frame(u"localeframe"_ustr))
, m_xCbSourceFormat(m_xBuilder->weld_check_button(u"sourceformat"_ustr))
, m_xOptionsFrame(m_xBuilder->weld_frame(u"options"_ustr))
, m_xFtDecimals(m_xBuilder->weld_label(u"decimalsft"_ustr))
, m_xEdDecimals(m_xBuilder->weld_spin_button(u"decimalsed"_ustr))
, m_xFtDenominator(m_xBuilder->weld_label(u"denominatorft"_ustr))
, m_xEdDenominator(m_xBuilder->weld_spin_button(u"denominatored"_ustr))
, m_xBtnNegRed(m_xBuilder->weld_check_button(u"negnumred"_ustr))
, m_xFtLeadZeroes(m_xBuilder->weld_label(u"leadzerosft"_ustr))
, m_xEdLeadZeroes(m_xBuilder->weld_spin_button(u"leadzerosed"_ustr))
, m_xBtnThousand(m_xBuilder->weld_check_button(u"thousands"_ustr))
, m_xBtnEngineering(m_xBuilder->weld_check_button(u"engineering"_ustr))
, m_xFormatCodeFrame(m_xBuilder->weld_widget(u"formatcode"_ustr))
, m_xEdFormat(m_xBuilder->weld_entry(u"formatted"_ustr))
, m_xIbAdd(m_xBuilder->weld_button(u"add"_ustr))
, m_xIbInfo(m_xBuilder->weld_button(u"edit"_ustr))
, m_xIbRemove(m_xBuilder->weld_button(u"delete"_ustr))
, m_xFtComment(m_xBuilder->weld_label(u"commentft"_ustr))
, m_xEdComment(m_xBuilder->weld_entry(u"commented"_ustr))
, m_xLbLocale(new SvxLanguageBox(m_xBuilder->weld_combo_box(u"localelb"_ustr)))
, m_xWndPreview(new weld::CustomWeld(*m_xBuilder, u"preview"_ustr, m_aWndPreview))
{
for (size_t i = 0; i < std::size(NUM_CATEGORIES); ++i)
m_xLbCategory->append_text(CuiResId(NUM_CATEGORIES[i]));
auto nWidth = m_xLbCategory->get_approximate_digit_width() * 22;
m_xLbCategory->set_size_request(nWidth, m_xLbCategory->get_height_rows(7));
m_xLbFormat->set_size_request(nWidth, m_xLbFormat->get_height_rows(5));
m_xLbCurrency->set_size_request(nWidth, -1); // force using (narrower) width of its LbFormat sibling
// Initially remove the "Automatically" entry.
m_xLbCurrency->set_active(-1); // First ensure that nothing is selected.
sAutomaticCurrencyEntry = m_xLbCurrency->get_text(0);
m_xLbCurrency->remove(0);
Init_Impl();
SetExchangeSupport(); // this page needs ExchangeSupport
nFixedCategory=-1;
}
SvxNumberFormatTabPage::~SvxNumberFormatTabPage()
{
pNumFmtShell.reset();
pNumItem.reset();
m_xWndPreview.reset();
m_xLbLocale.reset();
}
void SvxNumberFormatTabPage::Init_Impl()
{
bNumItemFlag=true;
bOneAreaFlag=false;
m_xIbAdd->set_sensitive(false );
m_xIbRemove->set_sensitive(false );
m_xIbInfo->set_sensitive(false );
m_xEdComment->set_text(m_xLbCategory->get_text(1)); // string for user defined
m_xEdComment->hide();
m_xCbSourceFormat->set_active( false );
m_xCbSourceFormat->set_sensitive(false);
m_xCbSourceFormat->hide();
Link<weld::ItemView&, void> aLink2
= LINK(this, SvxNumberFormatTabPage, SelFormatTreeListBoxHdl_Impl);
Link<weld::ComboBox&,void> aLink3 = LINK(this, SvxNumberFormatTabPage, SelFormatListBoxHdl_Impl);
m_xLbCategory->connect_selection_changed(aLink2);
m_xLbCategory->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
m_xLbFormat->connect_selection_changed(aLink2);
m_xLbFormat->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
m_xLbLocale->connect_changed(aLink3);
m_xLbLocale->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
m_xLbCurrency->connect_changed(aLink3);
m_xLbCurrency->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
m_xCbSourceFormat->connect_toggled(LINK(this, SvxNumberFormatTabPage, SelFormatClickHdl_Impl));
m_xCbSourceFormat->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
Link<weld::SpinButton&,void> aLink = LINK( this, SvxNumberFormatTabPage, OptEditHdl_Impl );
m_xEdDecimals->connect_value_changed(aLink);
m_xEdDecimals->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
m_xEdDenominator->connect_value_changed(aLink);
m_xEdDenominator->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
m_xEdLeadZeroes->connect_value_changed(aLink);
m_xEdLeadZeroes->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
m_xBtnNegRed->connect_toggled(LINK(this, SvxNumberFormatTabPage, OptClickHdl_Impl));
m_xBtnNegRed->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
m_xBtnThousand->connect_toggled(LINK(this, SvxNumberFormatTabPage, OptClickHdl_Impl));
m_xBtnThousand->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
m_xBtnEngineering->connect_toggled(LINK(this, SvxNumberFormatTabPage, OptClickHdl_Impl));
m_xBtnEngineering->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
m_xLbFormat->connect_item_activated(LINK(this, SvxNumberFormatTabPage, DoubleClickHdl_Impl));
m_xEdFormat->connect_changed(LINK(this, SvxNumberFormatTabPage, EditModifyHdl_Impl));
m_xEdFormat->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
m_xIbAdd->connect_clicked(LINK(this, SvxNumberFormatTabPage, ClickHdl_Impl));
m_xIbAdd->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
m_xIbRemove->connect_clicked(LINK(this, SvxNumberFormatTabPage, ClickHdl_Impl));
m_xIbRemove->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
m_xIbInfo->connect_clicked(LINK(this, SvxNumberFormatTabPage, ClickHdl_Impl));
UpdateThousandEngineeringCheckBox();
UpdateDecimalsDenominatorEditBox();
// initialize language ListBox
m_xLbLocale->SetLanguageList(SvxLanguageListFlags::ALL | SvxLanguageListFlags::ONLY_KNOWN,
false, false, false, true, LANGUAGE_SYSTEM,
css::i18n::ScriptType::WEAK);
}
std::unique_ptr<SfxTabPage> SvxNumberFormatTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
const SfxItemSet* rAttrSet )
{
return std::make_unique<SvxNumberFormatTabPage>(pPage, pController, *rAttrSet);
}
/*************************************************************************
#* Method: Reset
#*------------------------------------------------------------------------
#*
#* Class: SvxNumberFormatTabPage
#* Function: The dialog's attributes are reset
#* using the Itemset.
#* Input: SfxItemSet
#* Output: ---
#*
#************************************************************************/
void SvxNumberFormatTabPage::set_active_currency(sal_Int32 nPos)
{
static_assert(SELPOS_NONE == -1, "SELPOS_NONE was -1 at time of writing");
if (nPos == 0 && !bLegacyAutomaticCurrency)
{
// Insert "Automatically" if currently used so it is selectable.
m_xLbCurrency->insert_text(0, sAutomaticCurrencyEntry);
bLegacyAutomaticCurrency = true;
}
if (nPos != -1 && !bLegacyAutomaticCurrency)
--nPos;
m_xLbCurrency->set_active(nPos);
}
sal_uInt32 SvxNumberFormatTabPage::get_active_currency() const
{
static_assert(SELPOS_NONE == -1, "SELPOS_NONE was -1 at time of writing");
sal_Int32 nCurrencyPos = m_xLbCurrency->get_active();
if (nCurrencyPos != -1 && !bLegacyAutomaticCurrency)
++nCurrencyPos;
return nCurrencyPos;
}
void SvxNumberFormatTabPage::Reset( const SfxItemSet* rSet )
{
if(const SfxBoolItem* pBoolLangItem = rSet->GetItemIfSet( SID_ATTR_NUMBERFORMAT_NOLANGUAGE ))
{
if(pBoolLangItem->GetValue())
{
HideLanguage();
}
else
{
HideLanguage(false);
}
}
if (const SvxNumberInfoItem* pItem = rSet->GetItemIfSet(GetWhich(SID_ATTR_NUMBERFORMAT_INFO)))
{
if(pNumItem==nullptr)
{
bNumItemFlag=true;
pNumItem.reset(pItem->Clone());
}
else
{
bNumItemFlag=false;
}
}
else
{
bNumItemFlag=false;
}
if (const SfxBoolItem* pBoolItem = rSet->GetItemIfSet(GetWhich(SID_ATTR_NUMBERFORMAT_ONE_AREA)))
{
bOneAreaFlag= pBoolItem->GetValue();
}
if ( const SfxBoolItem* pBoolItem = rSet->GetItemIfSet( SID_ATTR_NUMBERFORMAT_SOURCE ))
{
m_xCbSourceFormat->set_active(pBoolItem->GetValue());
m_xCbSourceFormat->set_sensitive(true);
m_xCbSourceFormat->show();
}
else
{
bool bInit = false; // set to sal_True for debug test
m_xCbSourceFormat->set_active( bInit );
m_xCbSourceFormat->set_sensitive( bInit );
m_xCbSourceFormat->set_visible( bInit );
}
// pNumItem must have been set from outside!
DBG_ASSERT( pNumItem, "No NumberInfo, no NumberFormatter, goodbye. CRASH. :-(" );
const SfxUInt32Item* pValFmtAttr = nullptr;
if (rSet->GetItemState(GetWhich(SID_ATTR_NUMBERFORMAT_VALUE)) != SfxItemState::INVALID)
pValFmtAttr = GetItem( *rSet, SID_ATTR_NUMBERFORMAT_VALUE );
SvxNumberValueType eValType = pNumItem->GetValueType();
OUString aValString;
double nValDouble = 0;
switch ( eValType )
{
case SvxNumberValueType::String:
aValString = pNumItem->GetValueString();
break;
case SvxNumberValueType::Number:
// #50441# string may be set in addition to the value
aValString = pNumItem->GetValueString();
nValDouble = pNumItem->GetValueDouble();
break;
case SvxNumberValueType::Undefined:
default:
break;
}
pNumFmtShell.reset(); // delete old shell if applicable (== reset)
nInitFormat = pValFmtAttr // memorize init key
? pValFmtAttr->GetValue() // (for FillItemSet())
: std::numeric_limits<sal_uInt32>::max(); // == DONT_KNOW
if ( eValType == SvxNumberValueType::String )
pNumFmtShell.reset( SvxNumberFormatShell::Create(
pNumItem->GetNumberFormatter(),
pValFmtAttr ? nInitFormat : 0,
eValType,
aValString ) );
else
pNumFmtShell.reset( SvxNumberFormatShell::Create(
pNumItem->GetNumberFormatter(),
pValFmtAttr ? nInitFormat : 0,
eValType,
nValDouble,
&aValString ) );
bool bUseStarFormat = false;
if (SfxObjectShell* pDocSh = SfxObjectShell::Current())
{
// is this a calc document
Reference< XServiceInfo > xSI( pDocSh->GetModel(), UNO_QUERY );
if ( xSI.is() )
bUseStarFormat = xSI->supportsService(u"com.sun.star.sheet.SpreadsheetDocument"_ustr);
}
pNumFmtShell->SetUseStarFormat( bUseStarFormat );
FillCurrencyBox();
sal_uInt16 nCatLbSelPos = 0;
LanguageType eLangType = LANGUAGE_DONTKNOW;
pNumFmtShell->GetInitSettings(nCatLbSelPos, eLangType, o3tl::temporary(sal_uInt16{}),
o3tl::temporary(std::vector<OUString>{}),
o3tl::temporary(OUString{}), o3tl::temporary<const Color*>({}));
if (nCatLbSelPos==CAT_CURRENCY)
set_active_currency(pNumFmtShell->GetCurrencySymbol());
nFixedCategory=nCatLbSelPos;
if(bOneAreaFlag)
{
OUString sFixedCategory = m_xLbCategory->get_text(nFixedCategory);
m_xLbCategory->clear();
m_xLbCategory->append_text(sFixedCategory);
SetCategory(0);
}
else
{
SetCategory(nCatLbSelPos );
}
const SfxBoolItem* pAutoEntryAttr = rSet->GetItemIfSet(SID_ATTR_NUMBERFORMAT_ADD_AUTO);
// no_NO is an alias for nb_NO and normally isn't listed, we need it for
// backwards compatibility, but only if the format passed is of
// LanguageType no_NO.
if ( eLangType == LANGUAGE_NORWEGIAN )
{
m_xLbLocale->remove_id(eLangType); // in case we're already called
m_xLbLocale->InsertLanguage( eLangType );
}
m_xLbLocale->set_active_id(eLangType);
if(pAutoEntryAttr)
AddAutomaticLanguage_Impl(eLangType, pAutoEntryAttr->GetValue());
UpdateFormatListBox_Impl(false,true);
//! This spoils everything because it rematches currency formats based on
//! the selected m_xLbCurrency entry instead of the current format.
//! Besides that everything seems to be initialized by now, so why call it?
// SelFormatHdl_Impl(m_xLbCategory.get());
if ( pValFmtAttr )
{
EditHdl_Impl(m_xEdFormat.get()); // UpdateOptions_Impl() as a side effect
}
else // DONT_KNOW
{
// everything disabled except direct input or changing the category
Obstructing();
}
if ( m_xCbSourceFormat->get_active() )
{
// everything disabled except SourceFormat checkbox
EnableBySourceFormat_Impl();
}
}
/*************************************************************************
#* Method: Obstructing
#*------------------------------------------------------------------------
#*
#* Class: SvxNumberFormatTabPage
#* Function: Disable the controls except from changing the category
#* and direct input.
#* Input: ---
#* Output: ---
#*
#************************************************************************/
void SvxNumberFormatTabPage::Obstructing()
{
m_xLbFormat->unselect_all();
m_xLbLocale->set_active(-1);
m_xFrameLocale->set_sensitive(false);
m_xIbAdd->set_sensitive(false );
m_xIbRemove->set_sensitive(false );
m_xIbInfo->set_sensitive(false );
m_xOptionsFrame->set_sensitive(false);
m_xBtnNegRed->set_sensitive(false);
m_xBtnThousand->set_sensitive(false);
m_xBtnEngineering->set_sensitive(false);
m_xFtLeadZeroes->set_sensitive(false);
m_xFtDecimals->set_sensitive(false);
m_xFtDenominator->set_sensitive(false);
m_xEdLeadZeroes->set_sensitive(false);
m_xEdDecimals->set_sensitive(false);
m_xEdDenominator->set_sensitive(false);
m_xEdDecimals->set_text( OUString() );
m_xEdLeadZeroes->set_text( OUString() );
m_xBtnNegRed->set_active( false );
m_xBtnThousand->set_active( false );
m_xBtnEngineering->set_active( false );
m_aWndPreview.NotifyChange( OUString() );
m_xLbCategory->select(0);
m_xEdFormat->set_text( OUString() );
m_xFtComment->set_label( OUString() );
m_xEdComment->set_text(m_xLbCategory->get_text(1)); // string for user defined
m_xEdFormat->grab_focus();
}
/*************************************************************************
#* Enable/Disable dialog parts depending on the value of the SourceFormat
#* checkbox.
#************************************************************************/
void SvxNumberFormatTabPage::EnableBySourceFormat_Impl()
{
bool bEnable = !m_xCbSourceFormat->get_active();
if ( !bEnable )
m_xCbSourceFormat->grab_focus();
m_xCategoryFrame->set_sensitive(bEnable);
m_xFormatFrame->set_sensitive(bEnable);
m_xFrameLocale->set_sensitive(bEnable);
m_xOptionsFrame->set_sensitive(bEnable);
m_xFtDecimals->set_sensitive( bEnable );
m_xEdDecimals->set_sensitive( bEnable );
m_xFtDenominator->set_sensitive( bEnable );
m_xEdDenominator->set_sensitive( bEnable );
m_xFtLeadZeroes->set_sensitive( bEnable );
m_xEdLeadZeroes->set_sensitive( bEnable );
m_xBtnNegRed->set_sensitive( bEnable );
m_xBtnThousand->set_sensitive( bEnable );
m_xBtnEngineering->set_sensitive(bEnable);
m_xFormatCodeFrame->set_sensitive( bEnable );
}
void SvxNumberFormatTabPage::EnableLocaleUi()
{
if (!m_xFrameLocale->get_sensitive())
{
m_xFrameLocale->set_sensitive(true);
m_xLbLocale->set_active_id(pNumFmtShell->GetCurLanguage());
}
}
/*************************************************************************
#* Method: HideLanguage
#*------------------------------------------------------------------------
#*
#* Class: SvxNumberFormatTabPage
#* Function: Hides the Languages and Locales:
#* Input: sal_Bool nFlag
#* Output: ---
#*
#************************************************************************/
void SvxNumberFormatTabPage::HideLanguage(bool bFlag)
{
m_xFrameLocale->set_visible(!bFlag);
}
/*************************************************************************
#* Method: FillItemSet
#*------------------------------------------------------------------------
#*
#* Class: SvxNumberFormatTabPage
#* Function: Adjusts the attributes in the ItemSet,
#* and - if bNumItemFlag is not set - the
#* numItem in the DocShell.
#* Input: SfxItemSet
#* Output: ---
#*
#************************************************************************/
bool SvxNumberFormatTabPage::FillItemSet( SfxItemSet* rCoreAttrs )
{
bool bDataChanged = m_xFrameLocale->get_sensitive() || m_xCbSourceFormat->get_sensitive();
if ( bDataChanged )
{
const SfxItemSet& rMyItemSet = GetItemSet();
TypedWhichId<SfxUInt32Item> nWhich = GetWhich( SID_ATTR_NUMBERFORMAT_VALUE );
SfxItemState eItemState = rMyItemSet.GetItemState( nWhich, false );
// OK chosen - Is format code input entered already taken over?
// If not, simulate Add. Upon syntax error ignore input and prevent Put.
OUString aFormat = m_xEdFormat->get_text();
sal_uInt32 nCurKey = pNumFmtShell->GetCurNumFmtKey();
if ( m_xIbAdd->get_sensitive() || pNumFmtShell->IsTmpCurrencyFormat(aFormat) )
{ // #79599# It is not sufficient to just add the format code (or
// delete it in case of bOneAreaFlag and resulting category change).
// Upon switching tab pages we need all settings to be consistent
// in case this page will be redisplayed later.
bDataChanged = Click_Impl(*m_xIbAdd);
nCurKey = pNumFmtShell->GetCurNumFmtKey();
}
else if(nCurKey == NUMKEY_UNDEFINED)
{ // something went wrong, e.g. in Writer #70281#
pNumFmtShell->FindEntry(aFormat, &nCurKey);
}
// Chosen format:
if ( bDataChanged )
{
bDataChanged = ( nInitFormat != nCurKey );
if (bDataChanged)
{
rCoreAttrs->Put( SfxUInt32Item( nWhich, nCurKey ) );
}
else if(SfxItemState::DEFAULT == eItemState)
{
rCoreAttrs->ClearItem( nWhich );
}
}
// List of changed user defined formats:
std::vector<sal_uInt32> const & aDelFormats = pNumFmtShell->GetUpdateData();
if ( !aDelFormats.empty() )
{
pNumItem->SetDelFormats( std::vector(aDelFormats) );
if(bNumItemFlag)
{
rCoreAttrs->Put( *pNumItem );
}
else
{
SfxObjectShell* pDocSh = SfxObjectShell::Current();
DBG_ASSERT( pDocSh, "DocShell not found!" );
if (pDocSh)
pDocSh->PutItem( *pNumItem );
}
}
// Whether source format is to be taken or not:
if ( m_xCbSourceFormat->get_sensitive() )
{
SfxItemState _eItemState = rMyItemSet.GetItemState( SID_ATTR_NUMBERFORMAT_SOURCE, false );
const SfxBoolItem* pBoolItem =
GetItem( rMyItemSet, SID_ATTR_NUMBERFORMAT_SOURCE );
bool bOld = pBoolItem && pBoolItem->GetValue();
rCoreAttrs->Put( SfxBoolItem( SID_ATTR_NUMBERFORMAT_SOURCE, m_xCbSourceFormat->get_active() ) );
if ( !bDataChanged )
bDataChanged = (bOld != m_xCbSourceFormat->get_active() ||
_eItemState != SfxItemState::SET);
}
// FillItemSet is only called on OK, here we can notify the
// NumberFormatShell that all new user defined formats are valid.
pNumFmtShell->ValidateNewEntries();
if(m_xLbLocale->get_visible() &&
m_xLbLocale->find_text(sAutomaticLangEntry) != -1)
rCoreAttrs->Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_ADD_AUTO,
m_xLbLocale->get_active_text() == sAutomaticLangEntry));
}
return bDataChanged;
}
DeactivateRC SvxNumberFormatTabPage::DeactivatePage( SfxItemSet* _pSet )
{
if ( _pSet )
FillItemSet( _pSet );
return DeactivateRC::LeavePage;
}
void SvxNumberFormatTabPage::FillFormatListBox_Impl( std::vector<OUString>& rEntries )
{
OUString aEntry;
OUString aTmpString;
size_t i = 0;
short nTmpCatPos;
m_xLbFormat->clear();
if (rEntries.empty())
return;
m_xLbFormat->freeze();
if(bOneAreaFlag)
{
nTmpCatPos=nFixedCategory;
}
else
{
nTmpCatPos=m_xLbCategory->get_selected_index();
}
switch (nTmpCatPos)
{
case CAT_ALL:
case CAT_TEXT:
case CAT_NUMBER: i=1;
aEntry=rEntries[0];
if (nTmpCatPos == CAT_TEXT)
aTmpString=aEntry;
else
aTmpString = pNumFmtShell->GetStandardName();
m_xLbFormat->append_text(aTmpString);
break;
default: break;
}
if(pNumFmtShell!=nullptr)
{
for ( ; i < rEntries.size(); ++i )
{
aEntry = rEntries[i];
short aPrivCat = pNumFmtShell->GetCategory4Entry( static_cast<short>(i) );
if(aPrivCat!=CAT_TEXT)
{
const Color* pPreviewColor = nullptr;
OUString aPreviewString( GetExpColorString( pPreviewColor, aEntry, aPrivCat ) );
m_xLbFormat->append_text(aPreviewString);
if (pPreviewColor)
m_xLbFormat->set_font_color(m_xLbFormat->n_children() - 1, *pPreviewColor);
}
else
{
m_xLbFormat->append_text(aEntry);
}
}
}
m_xLbFormat->thaw();
rEntries.clear();
}
/*************************************************************************
#* Method: UpdateOptions_Impl
#*------------------------------------------------------------------------
#*
#* Class: SvxNumberFormatTabPage
#* Function: Adjusts the options attributes
#* depending on the selected format.
#* Input: Flag, whether the category has changed.
#* Output: ---
#*
#************************************************************************/
void SvxNumberFormatTabPage::UpdateOptions_Impl( bool bCheckCatChange /*= sal_False*/ )
{
OUString theFormat = m_xEdFormat->get_text();
sal_Int32 nCurCategory = m_xLbCategory->get_selected_index();
sal_uInt16 nCategory = static_cast<sal_uInt16>(nCurCategory);
sal_uInt16 nDecimals = 0;
sal_uInt16 nZeroes = 0;
bool bNegRed = false;
bool bThousand = false;
sal_Int32 nCurrencyPos = get_active_currency();
if(bOneAreaFlag)
nCurCategory=nFixedCategory;
pNumFmtShell->GetOptions( theFormat,
bThousand, bNegRed,
nDecimals, nZeroes,
nCategory );
bool bDoIt=false;
if(nCategory==CAT_CURRENCY)
{
sal_uInt16 nTstPos=pNumFmtShell->FindCurrencyFormat(theFormat);
if(nCurrencyPos!=static_cast<sal_Int32>(nTstPos) && nTstPos!=sal_uInt16(-1))
{
set_active_currency(nTstPos);
pNumFmtShell->SetCurrencySymbol(nTstPos);
bDoIt=true;
}
}
if ( nCategory != nCurCategory || bDoIt)
{
if ( bCheckCatChange )
{
if(bOneAreaFlag)
SetCategory(0);
else
SetCategory(nCategory );
UpdateFormatListBox_Impl( true, false );
}
}
else if ( m_xLbFormat->n_children() > 0 )
{
sal_uInt32 nCurEntryKey=NUMKEY_UNDEFINED;
if(!pNumFmtShell->FindEntry( m_xEdFormat->get_text(),&nCurEntryKey))
{
m_xLbFormat->unselect_all();
}
}
if(bOneAreaFlag)
{
nCategory=nFixedCategory;
}
UpdateThousandEngineeringCheckBox();
UpdateDecimalsDenominatorEditBox();
switch ( nCategory )
{
case CAT_SCIENTIFIC: // bThousand is for Engineering notation
{
sal_uInt16 nIntDigits = pNumFmtShell->GetFormatIntegerDigits(theFormat);
bThousand = (nIntDigits > 0) && (nIntDigits % 3 == 0);
m_xBtnEngineering->set_sensitive(true);
m_xBtnEngineering->set_active( bThousand );
}
[[fallthrough]];
case CAT_NUMBER:
case CAT_PERCENT:
case CAT_CURRENCY:
case CAT_FRACTION:
case CAT_TIME:
m_xOptionsFrame->set_sensitive(true);
if ( nCategory == CAT_FRACTION )
{
m_xFtDenominator->set_sensitive(true);
m_xEdDenominator->set_sensitive(true);
}
else
{
m_xFtDecimals->set_sensitive(true);
m_xEdDecimals->set_sensitive(true);
}
m_xFtLeadZeroes->set_sensitive( nCategory != CAT_TIME );
m_xEdLeadZeroes->set_sensitive( nCategory != CAT_TIME );
m_xBtnNegRed->set_sensitive(true);
if ( nCategory == CAT_NUMBER && m_xLbFormat->get_selected_index() == 0 )
m_xEdDecimals->set_text( u""_ustr ); //General format tdf#44399
else
if ( nCategory == CAT_FRACTION )
m_xEdDenominator->set_value( nDecimals );
else
m_xEdDecimals->set_value( nDecimals );
if ( nCategory != CAT_TIME )
m_xEdLeadZeroes->set_value( nZeroes );
m_xBtnNegRed->set_active( bNegRed );
if ( nCategory != CAT_SCIENTIFIC )
{
m_xBtnThousand->set_sensitive( nCategory != CAT_TIME
&& !pNumFmtShell->IsNatNum12( theFormat ) );
m_xBtnThousand->set_active( bThousand && nCategory != CAT_TIME );
}
break;
case CAT_ALL:
case CAT_USERDEFINED:
case CAT_TEXT:
case CAT_DATE:
case CAT_BOOLEAN:
default:
m_xOptionsFrame->set_sensitive(false);
m_xFtDecimals->set_sensitive(false);
m_xEdDecimals->set_sensitive(false);
m_xFtDenominator->set_sensitive(false);
m_xEdDenominator->set_sensitive(false);
m_xFtLeadZeroes->set_sensitive(false);
m_xEdLeadZeroes->set_sensitive(false);
m_xBtnNegRed->set_sensitive(false);
m_xBtnThousand->set_sensitive(false);
m_xBtnEngineering->set_sensitive(false);
m_xEdDecimals->set_text( OUString() );
m_xEdLeadZeroes->set_text( OUString() );
m_xBtnNegRed->set_active( false );
m_xBtnThousand->set_active( false );
m_xBtnEngineering->set_active( false );
}
}
/*************************************************************************
#* Method: UpdateFormatListBox_Impl
#*------------------------------------------------------------------------
#*
#* Class: SvxNumberFormatTabPage
#* Function: Updates the format listbox and additionally the
#* string in the editbox is changed depending on
#* the bUpdateEdit flag.
#* Input: Flags for category and editbox.
#* Output: ---
#*
#************************************************************************/
void SvxNumberFormatTabPage::UpdateFormatListBox_Impl
(
bool bCat, // Category or country/language ListBox?
bool bUpdateEdit
)
{
std::vector<OUString> aEntryList;
short nFmtLbSelPos = 0;
short nTmpCatPos;
if(bOneAreaFlag)
{
nTmpCatPos=nFixedCategory;
}
else
{
nTmpCatPos=m_xLbCategory->get_selected_index();
}
if ( bCat )
{
if(nTmpCatPos!=CAT_CURRENCY)
m_xLbCurrency->hide();
else
m_xLbCurrency->show();
pNumFmtShell->CategoryChanged(nTmpCatPos,nFmtLbSelPos, aEntryList);
}
else
pNumFmtShell->LanguageChanged(m_xLbLocale->get_active_id(),
nFmtLbSelPos,aEntryList);
EnableLocaleUi();
if ( (!aEntryList.empty()) && (nFmtLbSelPos != SELPOS_NONE) )
{
if(bUpdateEdit)
{
const OUString& aFormat=aEntryList[nFmtLbSelPos];
m_xEdFormat->set_text(aFormat);
m_xFtComment->set_label(pNumFmtShell->GetComment4Entry(nFmtLbSelPos));
}
if(!bOneAreaFlag || !bCat)
{
FillFormatListBox_Impl( aEntryList );
m_xLbFormat->select(nFmtLbSelPos);
m_xFtComment->set_label(pNumFmtShell->GetComment4Entry(nFmtLbSelPos));
if(pNumFmtShell->GetUserDefined4Entry(nFmtLbSelPos))
{
if(pNumFmtShell->GetComment4Entry(nFmtLbSelPos).isEmpty())
{
m_xFtComment->set_label(m_xLbCategory->get_text(1));
}
}
ChangePreviewText( static_cast<sal_uInt16>(nFmtLbSelPos) );
}
}
else
{
FillFormatListBox_Impl( aEntryList );
if(nFmtLbSelPos != SELPOS_NONE)
{
m_xLbFormat->select(static_cast<sal_uInt16>(nFmtLbSelPos));
m_xFtComment->set_label(pNumFmtShell->GetComment4Entry(nFmtLbSelPos));
if(pNumFmtShell->GetUserDefined4Entry(nFmtLbSelPos))
{
if(pNumFmtShell->GetComment4Entry(nFmtLbSelPos).isEmpty())
{
m_xFtComment->set_label(m_xLbCategory->get_text(1));
}
}
}
else
{
m_xLbFormat->unselect_all();
}
if ( bUpdateEdit )
{
m_xEdFormat->set_text( OUString() );
m_aWndPreview.NotifyChange( OUString() );
}
}
aEntryList.clear();
}
/**
* Change visible checkbox according to category format
* if scientific format "Engineering notation"
* else "Thousands separator"
*/
void SvxNumberFormatTabPage::UpdateThousandEngineeringCheckBox()
{
bool bIsScientific = m_xLbCategory->get_selected_index() == CAT_SCIENTIFIC;
m_xBtnThousand->set_visible( !bIsScientific );
m_xBtnEngineering->set_visible( bIsScientific );
}
/**
* Change visible Edit box and Fixed text according to category format
* if fraction format "Denominator places"
* else "Decimal places"
*/
void SvxNumberFormatTabPage::UpdateDecimalsDenominatorEditBox()
{
bool bIsFraction = m_xLbCategory->get_selected_index() == CAT_FRACTION;
m_xFtDecimals->set_visible( !bIsFraction );
m_xEdDecimals->set_visible( !bIsFraction );
m_xFtDenominator->set_visible( bIsFraction );
m_xEdDenominator->set_visible( bIsFraction );
}
/*************************************************************************
#* Handle: DoubleClickHdl_Impl
#*------------------------------------------------------------------------
#*
#* Class: SvxNumberFormatTabPage
#* Function: On a double click in the format listbox the
#* value is adopted and the OK button pushed.
#* Output: ---
#*
#************************************************************************/
IMPL_LINK_NOARG(SvxNumberFormatTabPage, DoubleClickHdl_Impl, const weld::TreeIter&, bool)
{
SelFormatHdl_Impl(m_xLbFormat.get());
SfxOkDialogController* pController = GetDialogController();
assert(pController);
weld::Button& rOkButton = pController->GetOKButton();
rOkButton.clicked();
return true;
}
/*************************************************************************
#* Method: SelFormatHdl_Impl
#*------------------------------------------------------------------------
#*
#* Class: SvxNumberFormatTabPage
#* Function: Is called when the language, the category or the format
#* is changed. Accordingly the settings are adjusted.
#* Input: Pointer on the Listbox
#* Output: ---
#*
#************************************************************************/
IMPL_LINK(SvxNumberFormatTabPage, SelFormatClickHdl_Impl, weld::Toggleable&, rLb, void)
{
SelFormatHdl_Impl(&rLb);
}
IMPL_LINK(SvxNumberFormatTabPage, SelFormatTreeListBoxHdl_Impl, weld::ItemView&, rLb, void)
{
SelFormatHdl_Impl(&rLb);
}
IMPL_LINK(SvxNumberFormatTabPage, SelFormatListBoxHdl_Impl, weld::ComboBox&, rLb, void)
{
SelFormatHdl_Impl(&rLb);
}
void SvxNumberFormatTabPage::SelFormatHdl_Impl(weld::Widget* pLb)
{
if (m_nLbFormatSelPosEdComment != SELPOS_NONE)
{
// Click handler is called before focus change handler, so finish
// comment editing of previous format, otherwise a new format will have
// the old comment displayed after LostFocusHdl_Impl() is called
// later. Also, clicking into another category invalidates the format
// list and SvxNumberFormatShell::SetComment4Entry() could either
// access a wrong format from aCurEntryList[nEntry] or crash there if
// the new vector has less elements.
LostFocusHdl_Impl(*pLb);
}
if (pLb == m_xCbSourceFormat.get())
{
EnableBySourceFormat_Impl(); // enable/disable everything else
if ( m_xCbSourceFormat->get_active() )
return; // just disabled everything else
// Reinit options enable/disable for current selection.
// Current category may be UserDefined with no format entries defined.
if (m_xLbFormat->get_selected_index() == -1)
pLb = m_xLbCategory.get(); // continue with the current category selected
else
pLb = m_xLbFormat.get(); // continue with the current format selected
}
sal_Int32 nTmpCatPos;
if(bOneAreaFlag)
{
nTmpCatPos=nFixedCategory;
}
else
{
nTmpCatPos=m_xLbCategory->get_selected_index();
}
if (nTmpCatPos==CAT_CURRENCY && pLb == m_xLbCurrency.get())
pNumFmtShell->SetCurrencySymbol(get_active_currency());
// Format-ListBox ----------------------------------------------------
if (pLb == m_xLbFormat.get())
{
int nSelPos = m_xLbFormat->get_selected_index();
short nFmtLbSelPos = static_cast<short>(nSelPos);
OUString aFormat = pNumFmtShell->GetFormat4Entry(nFmtLbSelPos);
OUString aComment = pNumFmtShell->GetComment4Entry(nFmtLbSelPos);
if(pNumFmtShell->GetUserDefined4Entry(nFmtLbSelPos))
{
if(aComment.isEmpty())
{
aComment = m_xLbCategory->get_text(1);
}
}
if ( !aFormat.isEmpty() )
{
if (!m_xEdFormat->has_focus())
m_xEdFormat->set_text( aFormat );
m_xFtComment->set_label(aComment);
ChangePreviewText( static_cast<sal_uInt16>(nSelPos) );
}
EnableLocaleUi();
if ( pNumFmtShell->FindEntry( aFormat) )
{
m_xIbAdd->set_sensitive(false );
bool bIsUserDef=pNumFmtShell->IsUserDefined( aFormat );
m_xIbRemove->set_sensitive(bIsUserDef);
m_xIbInfo->set_sensitive(bIsUserDef);
}
else
{
m_xIbAdd->set_sensitive(true);
m_xIbInfo->set_sensitive(true);
m_xIbRemove->set_sensitive(false );
m_xFtComment->set_label(m_xEdComment->get_text());
}
UpdateOptions_Impl( false );
return;
}
// category-ListBox -------------------------------------------------
if (pLb == m_xLbCategory.get() || pLb == m_xLbCurrency.get())
{
UpdateFormatListBox_Impl( true, true );
EditHdl_Impl( nullptr );
UpdateOptions_Impl( false );
return;
}
// language/country-ListBox ----------------------------------------------
if (pLb == m_xLbLocale->get_widget())
{
UpdateFormatListBox_Impl( false, true );
EditHdl_Impl(m_xEdFormat.get());
return;
}
}
/*************************************************************************
#* Method: ClickHdl_Impl, weld::Button& rIB
#*------------------------------------------------------------------------
#*
#* Class: SvxNumberFormatTabPage
#* Function: Called when the add or delete button is pushed,
#* adjusts the number format list.
#* Input: Toolbox- Button
#* Output: ---
#*
#************************************************************************/
IMPL_LINK( SvxNumberFormatTabPage, ClickHdl_Impl, weld::Button&, rIB, void)
{
Click_Impl(rIB);
}
bool SvxNumberFormatTabPage::Click_Impl(const weld::Button& rIB)
{
sal_uInt8 nReturn = 0;
constexpr sal_uInt8 nReturnChanged = 0x1; // THE boolean return value
constexpr sal_uInt8 nReturnAdded = 0x2; // temp: format added
constexpr sal_uInt8 nReturnOneArea = 0x4; // temp: one area but category changed => ignored
if (&rIB == m_xIbAdd.get())
{ // Also called from FillItemSet() if a temporary currency format has
// to be added, not only if the Add button is enabled.
OUString aFormat = m_xEdFormat->get_text();
std::vector<OUString> aEntryList;
std::vector<OUString> a2EntryList;
sal_uInt16 nCatLbSelPos = 0;
short nFmtLbSelPos = SELPOS_NONE;
sal_Int32 nErrPos=0;
pNumFmtShell->SetCurCurrencyEntry(nullptr);
bool bAdded = pNumFmtShell->AddFormat( aFormat, nErrPos,
nCatLbSelPos, nFmtLbSelPos,
aEntryList);
if ( bAdded )
nReturn |= nReturnChanged | nReturnAdded;
if (m_xEdComment->get_visible())
{
m_xEdFormat->grab_focus();
m_xEdComment->hide();
m_xFtComment->show();
m_xFtComment->set_label(m_xEdComment->get_text());
}
if ( !nErrPos ) // Syntax ok?
{
// May be sorted under a different locale if LCID was parsed.
if (bAdded)
m_xLbLocale->set_active_id(pNumFmtShell->GetCurLanguage());
if (nCatLbSelPos==CAT_CURRENCY)
set_active_currency(pNumFmtShell->GetCurrencySymbol());
if(bOneAreaFlag && (nFixedCategory!=nCatLbSelPos))
{
if(bAdded) aEntryList.clear();
pNumFmtShell->RemoveFormat( aFormat,
nCatLbSelPos,
nFmtLbSelPos,
a2EntryList);
a2EntryList.clear();
m_xEdFormat->grab_focus();
m_xEdFormat->select_region(0, -1);
nReturn |= nReturnOneArea;
}
else
{
if ( bAdded && (nFmtLbSelPos != SELPOS_NONE) )
{
// everything all right
if(bOneAreaFlag) //@@ ???
SetCategory(0);
else
SetCategory(nCatLbSelPos );
FillFormatListBox_Impl( aEntryList );
if (m_xEdComment->get_text()!=m_xLbCategory->get_text(1))
{
pNumFmtShell->SetComment4Entry(nFmtLbSelPos,
m_xEdComment->get_text());
}
else
{
pNumFmtShell->SetComment4Entry(nFmtLbSelPos,
OUString());
}
m_xLbFormat->select(static_cast<sal_uInt16>(nFmtLbSelPos));
m_xEdFormat->set_text( aFormat );
m_xEdComment->set_text(m_xLbCategory->get_text(1)); // String for user defined
ChangePreviewText( static_cast<sal_uInt16>(nFmtLbSelPos) );
}
}
}
else // syntax error
{
m_xEdFormat->grab_focus();
m_xEdFormat->select_region(nErrPos == -1 ? m_xEdFormat->get_text().getLength() : nErrPos, -1);
}
EditHdl_Impl(m_xEdFormat.get());
nReturn = ((nReturn & nReturnOneArea) ? 0 : (nReturn & nReturnChanged));
aEntryList.clear();
a2EntryList.clear();
}
else if (&rIB == m_xIbRemove.get())
{
OUString aFormat = m_xEdFormat->get_text();
std::vector<OUString> aEntryList;
sal_uInt16 nCatLbSelPos = 0;
short nFmtLbSelPos = SELPOS_NONE;
pNumFmtShell->RemoveFormat( aFormat,
nCatLbSelPos,
nFmtLbSelPos,
aEntryList );
m_xEdComment->set_text(m_xLbCategory->get_text(1));
if( nFmtLbSelPos>=0 && o3tl::make_unsigned(nFmtLbSelPos)<aEntryList.size() )
{
aFormat = aEntryList[nFmtLbSelPos];
}
FillFormatListBox_Impl( aEntryList );
if ( nFmtLbSelPos != SELPOS_NONE )
{
if(bOneAreaFlag) //@@ ???
SetCategory(0);
else
SetCategory(nCatLbSelPos );
m_xLbFormat->select(static_cast<sal_uInt16>(nFmtLbSelPos));
m_xEdFormat->set_text( aFormat );
ChangePreviewText( static_cast<sal_uInt16>(nFmtLbSelPos) );
}
else
{
// set to "all/standard"
SetCategory(0);
SelFormatHdl_Impl(m_xLbCategory.get());
}
EditHdl_Impl(m_xEdFormat.get());
aEntryList.clear();
}
else if (&rIB == m_xIbInfo.get())
{
if (!m_xEdComment->get_visible())
{
if (!m_xIbAdd->get_sensitive())
// Editing for existing format.
m_nLbFormatSelPosEdComment = m_xLbFormat->get_selected_index();
m_xEdComment->set_text(m_xFtComment->get_label());
m_xEdComment->show();
m_xFtComment->hide();
m_xEdComment->grab_focus();
}
else
{
m_xEdFormat->grab_focus();
m_xFtComment->set_label( m_xEdComment->get_text());
m_xEdComment->hide();
m_xFtComment->show();
}
}
return nReturn;
}
/*************************************************************************
#* Method: EditHdl_Impl
#*------------------------------------------------------------------------
#*
#* Class: SvxNumberFormatTabPage
#* Function: When the entry in the edit field is changed
#* the preview is updated and
#* Input: Pointer on Editbox
#* Output: ---
#*
#************************************************************************/
IMPL_LINK(SvxNumberFormatTabPage, EditModifyHdl_Impl, weld::TextWidget&, rEdit, void)
{
EditHdl_Impl(&rEdit);
}
void SvxNumberFormatTabPage::EditHdl_Impl(const weld::TextWidget* pEdFormat)
{
sal_uInt32 nCurKey = NUMKEY_UNDEFINED;
if ( m_xEdFormat->get_text().isEmpty() )
{
m_xIbAdd->set_sensitive(false );
m_xIbRemove->set_sensitive(false );
m_xIbInfo->set_sensitive(false );
m_xFtComment->set_label(OUString());
}
else
{
OUString aFormat = m_xEdFormat->get_text();
MakePreviewText( aFormat );
if ( pNumFmtShell->FindEntry( aFormat, &nCurKey ) )
{
m_xIbAdd->set_sensitive(false );
bool bUserDef=pNumFmtShell->IsUserDefined( aFormat );
m_xIbRemove->set_sensitive(bUserDef);
m_xIbInfo->set_sensitive(bUserDef);
if(bUserDef)
{
sal_uInt16 nTmpCurPos=pNumFmtShell->FindCurrencyFormat(aFormat );
if (nTmpCurPos != sal_uInt16(-1))
set_active_currency(nTmpCurPos);
}
short nPosi=pNumFmtShell->GetListPos4Entry( nCurKey, aFormat);
if(nPosi>=0)
m_xLbFormat->select(static_cast<sal_uInt16>(nPosi));
}
else
{
m_xIbAdd->set_sensitive(true);
m_xIbInfo->set_sensitive(true);
m_xIbRemove->set_sensitive(false );
m_xFtComment->set_label(m_xEdComment->get_text());
}
}
if (pEdFormat)
{
pNumFmtShell->SetCurNumFmtKey( nCurKey );
UpdateOptions_Impl( true );
}
}
/*************************************************************************
#* Method: NotifyChange
#*------------------------------------------------------------------------
#*
#* Class: SvxNumberFormatTabPage
#* Function: Does changes in the number attributes.
#* Input: Options- Controls
#* Output: ---
#*
#************************************************************************/
IMPL_LINK(SvxNumberFormatTabPage, OptClickHdl_Impl, weld::Toggleable&, rOptCtrl, void)
{
OptHdl_Impl(&rOptCtrl);
}
IMPL_LINK(SvxNumberFormatTabPage, OptEditHdl_Impl, weld::SpinButton&, rEdit, void)
{
OptHdl_Impl(&rEdit);
}
void SvxNumberFormatTabPage::OptHdl_Impl(const weld::Widget* pOptCtrl)
{
if ( !(pOptCtrl == m_xEdLeadZeroes.get()
|| pOptCtrl == m_xEdDecimals.get()
|| pOptCtrl == m_xEdDenominator.get()
|| pOptCtrl == m_xBtnNegRed.get()
|| pOptCtrl == m_xBtnThousand.get()
|| pOptCtrl == m_xBtnEngineering.get()))
return;
OUString aFormat;
bool bThousand = ( m_xBtnThousand->get_visible() && m_xBtnThousand->get_sensitive() && m_xBtnThousand->get_active() )
|| ( m_xBtnEngineering->get_visible() && m_xBtnEngineering->get_sensitive() && m_xBtnEngineering->get_active() );
bool bNegRed = m_xBtnNegRed->get_sensitive() && m_xBtnNegRed->get_active();
sal_uInt16 nPrecision = (m_xEdDecimals->get_sensitive() && m_xEdDecimals->get_visible())
? static_cast<sal_uInt16>(m_xEdDecimals->get_value())
: ( (m_xEdDenominator->get_sensitive() && m_xEdDenominator->get_visible())
? static_cast<sal_uInt16>(m_xEdDenominator->get_value())
: sal_uInt16(0) );
sal_uInt16 nLeadZeroes = (m_xEdLeadZeroes->get_sensitive())
? static_cast<sal_uInt16>(m_xEdLeadZeroes->get_value())
: sal_uInt16(0);
if ( pNumFmtShell->GetStandardName() == m_xEdFormat->get_text() )
{
m_xEdDecimals->set_value(nPrecision);
}
pNumFmtShell->MakeFormat( aFormat,
bThousand, bNegRed,
nPrecision, nLeadZeroes,
static_cast<sal_uInt16>(m_xLbFormat->get_selected_index()) );
m_xEdFormat->set_text( aFormat );
MakePreviewText( aFormat );
if ( pNumFmtShell->FindEntry( aFormat ) )
{
m_xIbAdd->set_sensitive(false );
bool bUserDef=pNumFmtShell->IsUserDefined( aFormat );
m_xIbRemove->set_sensitive(bUserDef);
m_xIbInfo->set_sensitive(bUserDef);
EditHdl_Impl(m_xEdFormat.get());
}
else
{
EditHdl_Impl( nullptr );
m_xLbFormat->unselect_all();
}
}
/*************************************************************************
#* Method: LostFocusHdl_Impl
#*------------------------------------------------------------------------
#*
#* Class: SvxNumberFormatTabPage
#* Function: Does changes in the number attributes.
#* Input: Options- Controls
#* Output: ---
#*
#************************************************************************/
IMPL_LINK_NOARG(SvxNumberFormatTabPage, LostFocusHdl_Impl, weld::Widget&, void)
{
if (!pNumFmtShell)
return;
const bool bAddSensitive = m_xIbAdd->get_sensitive();
if (bAddSensitive || m_nLbFormatSelPosEdComment != SELPOS_NONE)
// Comment editing was possible.
m_xFtComment->set_label(m_xEdComment->get_text());
m_xEdComment->hide();
m_xFtComment->show();
if (m_nLbFormatSelPosEdComment != SELPOS_NONE)
{
// Save edited comment of existing format.
pNumFmtShell->SetComment4Entry( m_nLbFormatSelPosEdComment, m_xEdComment->get_text());
m_nLbFormatSelPosEdComment = SELPOS_NONE;
}
if (!bAddSensitive)
{
// String for user defined, if present
OUString sEntry = m_xLbCategory->n_children() > 1 ? m_xLbCategory->get_text(1) : OUString();
m_xEdComment->set_text(sEntry);
}
}
/*************************************************************************
#* Method: NotifyChange
#*------------------------------------------------------------------------
#*
#* Class: SvxNumberFormatTabPage
#* Function: Does changes in the number attributes.
#* Input: Options- Controls
#* Output: ---
#*
#************************************************************************/
OUString SvxNumberFormatTabPage::GetExpColorString(
const Color*& rpPreviewColor, const OUString& rFormatStr, short nTmpCatPos)
{
SvxNumValCategory i;
switch (nTmpCatPos)
{
case CAT_ALL: i=SvxNumValCategory::Standard; break;
case CAT_NUMBER: i=SvxNumValCategory::Standard; break;
case CAT_PERCENT: i=SvxNumValCategory::Percent; break;
case CAT_CURRENCY: i=SvxNumValCategory::Currency; break;
case CAT_DATE: i=SvxNumValCategory::Date; break;
case CAT_TIME: i=SvxNumValCategory::Time; break;
case CAT_SCIENTIFIC: i=SvxNumValCategory::Scientific; break;
case CAT_FRACTION: i=SvxNumValCategory::Fraction; break;
case CAT_BOOLEAN: i=SvxNumValCategory::Boolean; break;
case CAT_USERDEFINED: i=SvxNumValCategory::Standard; break;
case CAT_TEXT:
default: i=SvxNumValCategory::NoValue;break;
}
double fVal = fSvxNumValConst[i];
// use lower number for long NatNum12 transliteration
if ( ( CAT_CURRENCY == nTmpCatPos || CAT_NUMBER == nTmpCatPos ) &&
rFormatStr.indexOf("NatNum12") >= 0 )
{
if ( CAT_CURRENCY == nTmpCatPos )
fVal = 1.2;
else
fVal = 100; // show also title case for English: One Hundred
}
OUString aPreviewString;
pNumFmtShell->MakePrevStringFromVal( rFormatStr, aPreviewString, rpPreviewColor, fVal );
return aPreviewString;
}
void SvxNumberFormatTabPage::MakePreviewText( const OUString& rFormat )
{
OUString aPreviewString;
const Color* pPreviewColor = nullptr;
pNumFmtShell->MakePreviewString( rFormat, aPreviewString, pPreviewColor );
m_aWndPreview.NotifyChange( aPreviewString, pPreviewColor );
}
void SvxNumberFormatTabPage::ChangePreviewText( sal_uInt16 nPos )
{
OUString aPreviewString;
const Color* pPreviewColor = nullptr;
pNumFmtShell->FormatChanged( nPos, aPreviewString, pPreviewColor );
m_aWndPreview.NotifyChange( aPreviewString, pPreviewColor );
}
void SvxNumberFormatTabPage::FillCurrencyBox()
{
std::vector<OUString> aList;
sal_uInt16 nSelPos=0;
pNumFmtShell->GetCurrencySymbols(aList, &nSelPos);
m_xLbCurrency->freeze();
m_xLbCurrency->clear();
bLegacyAutomaticCurrency = false;
for (std::vector<OUString>::iterator i = aList.begin() + 1;i != aList.end(); ++i)
m_xLbCurrency->append_text(*i);
m_xLbCurrency->thaw();
set_active_currency(nSelPos);
}
void SvxNumberFormatTabPage::SetCategory(sal_uInt16 nPos)
{
int nCurCategory = m_xLbCategory->get_selected_index();
sal_uInt16 nTmpCatPos;
if (bOneAreaFlag)
{
nTmpCatPos=nFixedCategory;
}
else
{
nTmpCatPos=nPos;
}
if(m_xLbCategory->n_children()==1 || nCurCategory!=nPos)
{
if(nTmpCatPos!=CAT_CURRENCY)
m_xLbCurrency->hide();
else
m_xLbCurrency->show();
}
m_xLbCategory->select(nPos);
}
/* to support Writer text field language handling an
additional entry needs to be inserted into the ListBox
which marks a certain language as automatically detected
Additionally the "Default" language is removed
*/
void SvxNumberFormatTabPage::AddAutomaticLanguage_Impl(LanguageType eAutoLang, bool bSelect)
{
m_xLbLocale->remove_id(LANGUAGE_SYSTEM);
m_xLbLocale->append(eAutoLang, sAutomaticLangEntry);
if (bSelect)
m_xLbLocale->set_active_id(eAutoLang);
}
void SvxNumberFormatTabPage::PageCreated(const SfxAllItemSet& aSet)
{
const SvxNumberInfoItem* pNumberInfoItem = aSet.GetItem<SvxNumberInfoItem>(SID_ATTR_NUMBERFORMAT_INFO, false);
if (pNumberInfoItem && !pNumItem)
pNumItem.reset(pNumberInfoItem->Clone());
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */