From 9237a905fa5f2b67db73c15847eff203a258c2b4 Mon Sep 17 00:00:00 2001 From: Caolán McNamara Date: Mon, 10 Sep 2018 17:19:19 +0100 Subject: weld SvxCharNamePage Change-Id: Ia54a5ac4fe4a11b7c03508c336193bb52c616e7f --- svtools/source/control/ctrlbox.cxx | 490 +++++++++++++++++++++++++++++++++++++ 1 file changed, 490 insertions(+) (limited to 'svtools/source') diff --git a/svtools/source/control/ctrlbox.cxx b/svtools/source/control/ctrlbox.cxx index 20da4fc8d25e..33355147da99 100644 --- a/svtools/source/control/ctrlbox.cxx +++ b/svtools/source/control/ctrlbox.cxx @@ -1222,6 +1222,161 @@ void FontStyleBox::Fill( const OUString& rName, const FontList* pList ) } } +SvtFontStyleBox::SvtFontStyleBox(std::unique_ptr p) + : m_xComboBox(std::move(p)) +{ + //Use the standard texts to get an optimal size and stick to that size. + //That should stop the character dialog dancing around. + auto nMaxLen = m_xComboBox->get_pixel_size(SvtResId(STR_SVT_STYLE_LIGHT)).Width(); + nMaxLen = std::max(nMaxLen, m_xComboBox->get_pixel_size(SvtResId(STR_SVT_STYLE_LIGHT_ITALIC)).Width()); + nMaxLen = std::max(nMaxLen, m_xComboBox->get_pixel_size(SvtResId(STR_SVT_STYLE_NORMAL)).Width()); + nMaxLen = std::max(nMaxLen, m_xComboBox->get_pixel_size(SvtResId(STR_SVT_STYLE_NORMAL_ITALIC)).Width()); + nMaxLen = std::max(nMaxLen, m_xComboBox->get_pixel_size(SvtResId(STR_SVT_STYLE_BOLD)).Width()); + nMaxLen = std::max(nMaxLen, m_xComboBox->get_pixel_size(SvtResId(STR_SVT_STYLE_BOLD_ITALIC)).Width()); + nMaxLen = std::max(nMaxLen, m_xComboBox->get_pixel_size(SvtResId(STR_SVT_STYLE_BLACK)).Width()); + nMaxLen = std::max(nMaxLen, m_xComboBox->get_pixel_size(SvtResId(STR_SVT_STYLE_BLACK_ITALIC)).Width()); + m_xComboBox->set_entry_width_chars(std::ceil(nMaxLen / m_xComboBox->get_approximate_digit_width())); +} + +void SvtFontStyleBox::Fill( const OUString& rName, const FontList* pList ) +{ + m_xComboBox->freeze(); + OUString aOldText = m_xComboBox->get_active_text(); + int nPos = m_xComboBox->get_active(); + m_xComboBox->clear(); + + // does a font with this name already exist? + sal_Handle hFontMetric = pList->GetFirstFontMetric( rName ); + if ( hFontMetric ) + { + OUString aStyleText; + FontWeight eLastWeight = WEIGHT_DONTKNOW; + FontItalic eLastItalic = ITALIC_NONE; + FontWidth eLastWidth = WIDTH_DONTKNOW; + bool bNormal = false; + bool bItalic = false; + bool bBold = false; + bool bBoldItalic = false; + bool bInsert = false; + FontMetric aFontMetric; + while ( hFontMetric ) + { + aFontMetric = FontList::GetFontMetric( hFontMetric ); + + FontWeight eWeight = aFontMetric.GetWeight(); + FontItalic eItalic = aFontMetric.GetItalic(); + FontWidth eWidth = aFontMetric.GetWidthType(); + // Only if the attributes are different, we insert the + // Font to avoid double Entries in different languages + if ( (eWeight != eLastWeight) || (eItalic != eLastItalic) || + (eWidth != eLastWidth) ) + { + if ( bInsert ) + m_xComboBox->append_text(aStyleText); + + if ( eWeight <= WEIGHT_NORMAL ) + { + if ( eItalic != ITALIC_NONE ) + bItalic = true; + else + bNormal = true; + } + else + { + if ( eItalic != ITALIC_NONE ) + bBoldItalic = true; + else + bBold = true; + } + + // For wrong StyleNames we replace this with the correct once + aStyleText = pList->GetStyleName( aFontMetric ); + bInsert = m_xComboBox->find_text(aStyleText) == -1; + if ( !bInsert ) + { + aStyleText = pList->GetStyleName( eWeight, eItalic ); + bInsert = m_xComboBox->find_text(aStyleText) == -1; + } + + eLastWeight = eWeight; + eLastItalic = eItalic; + eLastWidth = eWidth; + } + else + { + if ( bInsert ) + { + // If we have two names for the same attributes + // we prefer the translated standard names + const OUString& rAttrStyleText = pList->GetStyleName( eWeight, eItalic ); + if (rAttrStyleText != aStyleText) + { + OUString aTempStyleText = pList->GetStyleName( aFontMetric ); + if (rAttrStyleText == aTempStyleText) + aStyleText = rAttrStyleText; + bInsert = m_xComboBox->find_text(aStyleText) == -1; + } + } + } + + if ( !bItalic && (aStyleText == pList->GetItalicStr()) ) + bItalic = true; + else if ( !bBold && (aStyleText == pList->GetBoldStr()) ) + bBold = true; + else if ( !bBoldItalic && (aStyleText == pList->GetBoldItalicStr()) ) + bBoldItalic = true; + + hFontMetric = FontList::GetNextFontMetric( hFontMetric ); + } + + if ( bInsert ) + m_xComboBox->append_text(aStyleText); + + // certain style as copy + if ( bNormal ) + { + if ( !bItalic ) + m_xComboBox->append_text(pList->GetItalicStr()); + if ( !bBold ) + m_xComboBox->append_text(pList->GetBoldStr()); + } + if ( !bBoldItalic ) + { + if ( bNormal || bItalic || bBold ) + m_xComboBox->append_text(pList->GetBoldItalicStr()); + } + if (!aOldText.isEmpty()) + { + int nFound = m_xComboBox->find_text(aOldText); + if (nFound != -1) + m_xComboBox->set_active(nFound); + else + { + if (nPos >= m_xComboBox->get_count()) + m_xComboBox->set_active(0); + else + m_xComboBox->set_active(nPos); + } + } + } + else + { + // insert standard styles if no font + m_xComboBox->append_text(pList->GetNormalStr()); + m_xComboBox->append_text(pList->GetItalicStr()); + m_xComboBox->append_text(pList->GetBoldStr()); + m_xComboBox->append_text(pList->GetBoldItalicStr()); + if (!aOldText.isEmpty()) + { + if (nPos >= m_xComboBox->get_count()) + m_xComboBox->set_active(0); + else + m_xComboBox->set_active(nPos); + } + } + m_xComboBox->thaw(); +} + FontSizeBox::FontSizeBox( vcl::Window* pParent, WinBits nWinSize ) : MetricBox( pParent, nWinSize ) { @@ -1543,6 +1698,341 @@ sal_Int64 FontSizeBox::GetValueFromStringUnit(const OUString& rStr, FieldUnit eO return MetricBox::GetValueFromStringUnit( rStr, eOutUnit ); } +SvtFontSizeBox::SvtFontSizeBox(std::unique_ptr p) + : pFontList(nullptr) + , nSavedValue(0) + , nMin(20) + , nMax(9999) + , eUnit(FUNIT_POINT) + , nDecimalDigits(1) + , nRelMin(0) + , nRelMax(0) + , nRelStep(0) + , nPtRelMin(0) + , nPtRelMax(0) + , nPtRelStep(0) + , bRelativeMode(false) + , bRelative(false) + , bPtRelative(false) + , bStdSize(false) + , m_xComboBox(std::move(p)) +{ + m_xComboBox->set_entry_width_chars(std::ceil(m_xComboBox->get_pixel_size(format_number(105)).Width() / + m_xComboBox->get_approximate_digit_width())); + m_xComboBox->connect_focus_out(LINK(this, SvtFontSizeBox, ReformatHdl)); + m_xComboBox->connect_changed(LINK(this, SvtFontSizeBox, ModifyHdl)); +} + +IMPL_LINK_NOARG(SvtFontSizeBox, ReformatHdl, weld::Widget&, void) +{ + FontSizeNames aFontSizeNames(Application::GetSettings().GetUILanguageTag().getLanguageType()); + if (!bRelativeMode || !aFontSizeNames.IsEmpty()) + { + if (aFontSizeNames.Name2Size(m_xComboBox->get_active_text()) != 0) + return; + } + + set_value(get_value()); +} + +IMPL_LINK(SvtFontSizeBox, ModifyHdl, weld::ComboBoxText&, rBox, void) +{ + if (bRelativeMode) + { + OUString aStr = comphelper::string::stripStart(rBox.get_active_text(), ' '); + + bool bNewMode = bRelative; + bool bOldPtRelMode = bPtRelative; + + if ( bRelative ) + { + bPtRelative = false; + const sal_Unicode* pStr = aStr.getStr(); + while ( *pStr ) + { + if ( ((*pStr < '0') || (*pStr > '9')) && (*pStr != '%') && !unicode::isSpace(*pStr) ) + { + if ( ('-' == *pStr || '+' == *pStr) && !bPtRelative ) + bPtRelative = true; + else if ( bPtRelative && 'p' == *pStr && 't' == *++pStr ) + ; + else + { + bNewMode = false; + break; + } + } + pStr++; + } + } + else if (!aStr.isEmpty()) + { + if ( -1 != aStr.indexOf('%') ) + { + bNewMode = true; + bPtRelative = false; + } + + if ( '-' == aStr[0] || '+' == aStr[0] ) + { + bNewMode = true; + bPtRelative = true; + } + } + + if ( bNewMode != bRelative || bPtRelative != bOldPtRelMode ) + SetRelative( bNewMode ); + } + m_aChangeHdl.Call(rBox); +} + +void SvtFontSizeBox::Fill( const FontMetric* pFontMetric, const FontList* pList ) +{ + // remember for relative mode + pFontList = pList; + + // no font sizes need to be set for relative mode + if ( bRelative ) + return; + + // query font sizes + const sal_IntPtr* pTempAry; + const sal_IntPtr* pAry = nullptr; + + if( pFontMetric ) + { + aFontMetric = *pFontMetric; + pAry = pList->GetSizeAry( *pFontMetric ); + } + else + { + pAry = FontList::GetStdSizeAry(); + } + + // first insert font size names (for simplified/traditional chinese) + FontSizeNames aFontSizeNames( Application::GetSettings().GetUILanguageTag().getLanguageType() ); + if ( pAry == FontList::GetStdSizeAry() ) + { + // for standard sizes we don't need to bother + if (bStdSize && m_xComboBox->get_count() && aFontSizeNames.IsEmpty()) + return; + bStdSize = true; + } + else + bStdSize = false; + + int nSelectionStart, nSelectionEnd; + m_xComboBox->get_entry_selection_bounds(nSelectionStart, nSelectionEnd); + OUString aStr = m_xComboBox->get_active_text(); + + m_xComboBox->freeze(); + m_xComboBox->clear(); + int nPos = 0; + + if ( !aFontSizeNames.IsEmpty() ) + { + if ( pAry == FontList::GetStdSizeAry() ) + { + // for scalable fonts all font size names + sal_uLong nCount = aFontSizeNames.Count(); + for( sal_uLong i = 0; i < nCount; i++ ) + { + OUString aSizeName = aFontSizeNames.GetIndexName( i ); + sal_IntPtr nSize = aFontSizeNames.GetIndexSize( i ); + OUString sId(OUString::number(-nSize)); // mark as special + m_xComboBox->insert(nPos, sId, aSizeName); + nPos++; + } + } + else + { + // for fixed size fonts only selectable font size names + pTempAry = pAry; + while ( *pTempAry ) + { + OUString aSizeName = aFontSizeNames.Size2Name( *pTempAry ); + if ( !aSizeName.isEmpty() ) + { + OUString sId(OUString::number(-(*pTempAry))); // mark as special + m_xComboBox->insert(nPos, sId, aSizeName); + nPos++; + } + pTempAry++; + } + } + } + + // then insert numerical font size values + pTempAry = pAry; + while (*pTempAry) + { + InsertValue(*pTempAry); + ++pTempAry; + } + + m_xComboBox->set_entry_text(aStr); + m_xComboBox->select_entry_region(nSelectionStart, nSelectionEnd); + m_xComboBox->thaw(); +} + +void SvtFontSizeBox::EnableRelativeMode( sal_uInt16 nNewMin, sal_uInt16 nNewMax, sal_uInt16 nStep ) +{ + bRelativeMode = true; + nRelMin = nNewMin; + nRelMax = nNewMax; + nRelStep = nStep; + SetUnit(FUNIT_POINT); +} + +void SvtFontSizeBox::EnablePtRelativeMode( short nNewMin, short nNewMax, short nStep ) +{ + bRelativeMode = true; + nPtRelMin = nNewMin; + nPtRelMax = nNewMax; + nPtRelStep = nStep; + SetUnit(FUNIT_POINT); +} + +void SvtFontSizeBox::InsertValue(int i) +{ + OUString sNumber(OUString::number(i)); + m_xComboBox->append(sNumber, format_number(i)); +} + +void SvtFontSizeBox::SetRelative( bool bNewRelative ) +{ + if ( !bRelativeMode ) + return; + + int nSelectionStart, nSelectionEnd; + m_xComboBox->get_entry_selection_bounds(nSelectionStart, nSelectionEnd); + OUString aStr = comphelper::string::stripStart(m_xComboBox->get_active_text(), ' '); + + if (bNewRelative) + { + bRelative = true; + bStdSize = false; + + m_xComboBox->clear(); + + if (bPtRelative) + { + SetDecimalDigits( 1 ); + SetRange(nPtRelMin, nPtRelMax); + SetUnit(FUNIT_POINT); + + short i = nPtRelMin, n = 0; + // JP 30.06.98: more than 100 values are not useful + while ( i <= nPtRelMax && n++ < 100 ) + { + InsertValue( i ); + i = i + nPtRelStep; + } + } + else + { + SetDecimalDigits(0); + SetRange(nRelMin, nRelMax); + SetUnit(FUNIT_PERCENT); + + sal_uInt16 i = nRelMin; + while ( i <= nRelMax ) + { + InsertValue( i ); + i = i + nRelStep; + } + } + } + else + { + if (pFontList) + m_xComboBox->clear(); + bRelative = bPtRelative = false; + SetDecimalDigits(1); + SetRange(20, 9999); + SetUnit(FUNIT_POINT); + if ( pFontList) + Fill( &aFontMetric, pFontList ); + } + + m_xComboBox->set_entry_text(aStr); + m_xComboBox->select_entry_region(nSelectionStart, nSelectionEnd); +} + +OUString SvtFontSizeBox::format_number(int nValue) const +{ + OUString sRet; + + //pawn percent off to icu to decide whether percent is separated from its number for this locale + if (eUnit == FUNIT_PERCENT) + { + double fValue = nValue; + fValue /= weld::SpinButton::Power10(nDecimalDigits); + sRet = unicode::formatPercent(fValue, Application::GetSettings().GetUILanguageTag()); + } + else + { + const SvtSysLocale aSysLocale; + const LocaleDataWrapper& rLocaleData = aSysLocale.GetLocaleData(); + sRet = rLocaleData.getNum(nValue, nDecimalDigits, true, false); + if (eUnit != FUNIT_NONE && eUnit != FUNIT_DEGREE) + sRet += " "; + assert(eUnit != FUNIT_PERCENT); + sRet += weld::MetricSpinButton::MetricToString(eUnit); + } + + if (bRelativeMode && bPtRelative && (0 <= nValue) && !sRet.isEmpty()) + sRet = "+" + sRet; + + return sRet; +} + +void SvtFontSizeBox::SetValue(int nNewValue, FieldUnit eInUnit) +{ + auto nTempValue = MetricField::ConvertValue(nNewValue, 0, GetDecimalDigits(), eInUnit, GetUnit()); + if (!bRelative) + { + FontSizeNames aFontSizeNames(Application::GetSettings().GetUILanguageTag().getLanguageType()); + // conversion loses precision; however font sizes should + // never have a problem with that + OUString aName = aFontSizeNames.Size2Name(nTempValue); + if (!aName.isEmpty() && m_xComboBox->find_text(aName) != -1) + { + m_xComboBox->set_active_text(aName); + return; + } + } + OUString aResult = format_number(nTempValue); + const int nFound = m_xComboBox->find_text(aResult); + if (nFound != -1) + m_xComboBox->set_active(nFound); + else + m_xComboBox->set_entry_text(aResult); +} + +void SvtFontSizeBox::set_value(int nNewValue) +{ + SetValue(nNewValue, eUnit); +} + +int SvtFontSizeBox::get_value() const +{ + OUString aStr = m_xComboBox->get_active_text(); + if (!bRelative) + { + FontSizeNames aFontSizeNames(Application::GetSettings().GetUILanguageTag().getLanguageType()); + auto nValue = aFontSizeNames.Name2Size(aStr); + if (nValue) + return MetricField::ConvertValue(nValue, 0, GetDecimalDigits(), GetUnit(), GetUnit()); + } + + const SvtSysLocale aSysLocale; + const LocaleDataWrapper& rLocaleData = aSysLocale.GetLocaleData(); + double fResult(0.0); + MetricFormatter::TextToValue(aStr, fResult, 0, GetDecimalDigits(), rLocaleData, GetUnit()); + return fResult; +} + SvxBorderLineStyle SvtLineListBox::GetSelectEntryStyle() const { if (m_xLineSet->IsNoSelection()) -- cgit