summaryrefslogtreecommitdiffstats
path: root/cui/source/options/fontsubs.cxx
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--cui/source/options/fontsubs.cxx405
1 files changed, 405 insertions, 0 deletions
diff --git a/cui/source/options/fontsubs.cxx b/cui/source/options/fontsubs.cxx
new file mode 100644
index 000000000..93c8b03d9
--- /dev/null
+++ b/cui/source/options/fontsubs.cxx
@@ -0,0 +1,405 @@
+/* -*- 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 <officecfg/Office/Common.hxx>
+#include <svtools/ctrltool.hxx>
+#include <vcl/svapp.hxx>
+#include <svtools/fontsubstconfig.hxx>
+#include "fontsubs.hxx"
+#include <helpids.h>
+
+/*********************************************************************/
+/* */
+/* TabPage font replacement */
+/* */
+/*********************************************************************/
+
+SvxFontSubstTabPage::SvxFontSubstTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optfontspage.ui", "OptFontsPage", &rSet)
+ , m_xUseTableCB(m_xBuilder->weld_check_button("usetable"))
+ , m_xFont1CB(m_xBuilder->weld_combo_box("font1"))
+ , m_xFont2CB(m_xBuilder->weld_combo_box("font2"))
+ , m_xApply(m_xBuilder->weld_button("apply"))
+ , m_xDelete(m_xBuilder->weld_button("delete"))
+ , m_xCheckLB(m_xBuilder->weld_tree_view("checklb"))
+ , m_xFontNameLB(m_xBuilder->weld_combo_box("fontname"))
+ , m_xNonPropFontsOnlyCB(m_xBuilder->weld_check_button("nonpropfontonly"))
+ , m_xFontHeightLB(m_xBuilder->weld_combo_box("fontheight"))
+{
+ m_xFont1CB->make_sorted();
+ m_xFont1CB->set_size_request(1, -1);
+ m_xFont2CB->make_sorted();
+ m_xFont2CB->set_size_request(1, -1);
+ m_sAutomatic = m_xFontNameLB->get_text(0);
+ assert(!m_sAutomatic.isEmpty());
+
+ m_xCheckLB->set_size_request(m_xCheckLB->get_approximate_digit_width() * 60,
+ m_xCheckLB->get_height_rows(8));
+ m_xCheckLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
+ m_xCheckLB->set_help_id(HID_OFA_FONT_SUBST_CLB);
+ m_xCheckLB->set_selection_mode(SelectionMode::Multiple);
+
+ setColSizes(m_xCheckLB->get_size_request());
+ m_xCheckLB->connect_size_allocate(LINK(this, SvxFontSubstTabPage, ResizeHdl));
+
+ m_xCheckLB->set_centered_column(0);
+ m_xCheckLB->set_centered_column(1);
+
+ Link<weld::ComboBox&,void> aLink2(LINK(this, SvxFontSubstTabPage, SelectComboBoxHdl));
+ Link<weld::Button&,void> aClickLink(LINK(this, SvxFontSubstTabPage, ClickHdl));
+
+ m_xCheckLB->connect_changed(LINK(this, SvxFontSubstTabPage, TreeListBoxSelectHdl));
+ m_xCheckLB->connect_column_clicked(LINK(this, SvxFontSubstTabPage, HeaderBarClick));
+ m_xUseTableCB->connect_toggled(LINK(this, SvxFontSubstTabPage, ToggleHdl));
+ m_xFont1CB->connect_changed(aLink2);
+ m_xFont2CB->connect_changed(aLink2);
+ m_xApply->connect_clicked(aClickLink);
+ m_xDelete->connect_clicked(aClickLink);
+
+ m_xNonPropFontsOnlyCB->connect_toggled(LINK(this, SvxFontSubstTabPage, NonPropFontsHdl));
+
+ sal_uInt16 nHeight;
+ for(nHeight = 6; nHeight <= 16; nHeight++)
+ m_xFontHeightLB->append_text(OUString::number(nHeight));
+ for(nHeight = 18; nHeight <= 28; nHeight+= 2)
+ m_xFontHeightLB->append_text(OUString::number(nHeight));
+ for(nHeight = 32; nHeight <= 48; nHeight+= 4)
+ m_xFontHeightLB->append_text(OUString::number(nHeight));
+ for(nHeight = 54; nHeight <= 72; nHeight+= 6)
+ m_xFontHeightLB->append_text(OUString::number(nHeight));
+ for(nHeight = 80; nHeight <= 96; nHeight+= 8)
+ m_xFontHeightLB->append_text(OUString::number(nHeight));
+}
+
+IMPL_LINK(SvxFontSubstTabPage, HeaderBarClick, int, nColumn, void)
+{
+ bool bSortAtoZ = m_xCheckLB->get_sort_order();
+
+ //set new arrow positions in headerbar
+ if (nColumn == m_xCheckLB->get_sort_column())
+ {
+ bSortAtoZ = !bSortAtoZ;
+ m_xCheckLB->set_sort_order(bSortAtoZ);
+ }
+ else
+ {
+ m_xCheckLB->set_sort_indicator(TRISTATE_INDET, m_xCheckLB->get_sort_column());
+ m_xCheckLB->set_sort_column(nColumn);
+ }
+
+ if (nColumn != -1)
+ {
+ //sort lists
+ m_xCheckLB->set_sort_indicator(bSortAtoZ ? TRISTATE_TRUE : TRISTATE_FALSE, nColumn);
+ }
+}
+
+void SvxFontSubstTabPage::setColSizes(const Size& rSize)
+{
+ int nW1 = m_xCheckLB->get_pixel_size(m_xCheckLB->get_column_title(2)).Width();
+ int nW2 = m_xCheckLB->get_pixel_size(m_xCheckLB->get_column_title(3)).Width();
+ int nMax = std::max( nW1, nW2 ) + 6; // width of the longest header + a little offset
+ int nMin = m_xCheckLB->get_checkbox_column_width();
+ nMax = std::max(nMax, nMin);
+ const int nDoubleMax = 2*nMax;
+ const int nRest = rSize.Width() - nDoubleMax;
+ std::vector<int> aWidths { nMax, nMax, nRest/2 };
+ m_xCheckLB->set_column_fixed_widths(aWidths);
+}
+
+IMPL_LINK(SvxFontSubstTabPage, ResizeHdl, const Size&, rSize, void)
+{
+ setColSizes(rSize);
+}
+
+SvxFontSubstTabPage::~SvxFontSubstTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SvxFontSubstTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxFontSubstTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool SvxFontSubstTabPage::FillItemSet( SfxItemSet* )
+{
+ std::vector<SubstitutionStruct> aNewFontSubs;
+
+ m_xCheckLB->all_foreach([this, &aNewFontSubs](weld::TreeIter& rIter) {
+ SubstitutionStruct aAdd;
+ aAdd.sFont = m_xCheckLB->get_text(rIter, 2);
+ aAdd.sReplaceBy = m_xCheckLB->get_text(rIter, 3);
+ aAdd.bReplaceAlways = m_xCheckLB->get_toggle(rIter, 0);
+ aAdd.bReplaceOnScreenOnly = m_xCheckLB->get_toggle(rIter, 1);
+ aNewFontSubs.push_back(aAdd);
+ return false;
+ });
+
+ svtools::SetFontSubstitutions(m_xUseTableCB->get_active(), aNewFontSubs);
+ svtools::ApplyFontSubstitutionsToVcl();
+
+ std::shared_ptr< comphelper::ConfigurationChanges > batch(
+ comphelper::ConfigurationChanges::create());
+ if (m_xFontHeightLB->get_value_changed_from_saved())
+ officecfg::Office::Common::Font::SourceViewFont::FontHeight::set(
+ static_cast< sal_Int16 >(m_xFontHeightLB->get_active_text().toInt32()),
+ batch);
+ if (m_xNonPropFontsOnlyCB->get_state_changed_from_saved())
+ officecfg::Office::Common::Font::SourceViewFont::
+ NonProportionalFontsOnly::set(
+ m_xNonPropFontsOnlyCB->get_active(), batch);
+ //font name changes cannot be detected by saved values
+ OUString sFontName;
+ if (m_xFontNameLB->get_active() != -1)
+ sFontName = m_xFontNameLB->get_active_text();
+ officecfg::Office::Common::Font::SourceViewFont::FontName::set(
+ std::optional< OUString >(sFontName), batch);
+ batch->commit();
+
+ return false;
+}
+
+void SvxFontSubstTabPage::Reset( const SfxItemSet* )
+{
+ m_xCheckLB->freeze();
+ m_xCheckLB->clear();
+
+ m_xFont1CB->freeze();
+ m_xFont1CB->clear();
+ m_xFont2CB->freeze();
+ m_xFont2CB->clear();
+
+ FontList aFntLst(Application::GetDefaultDevice());
+ sal_uInt16 nFontCount = aFntLst.GetFontNameCount();
+ for (sal_uInt16 i = 0; i < nFontCount; ++i)
+ {
+ const FontMetric& rFontMetric = aFntLst.GetFontName(i);
+ m_xFont1CB->append_text(rFontMetric.GetFamilyName());
+ m_xFont2CB->append_text(rFontMetric.GetFamilyName());
+ }
+
+ m_xFont2CB->thaw();
+ m_xFont1CB->thaw();
+
+ m_xUseTableCB->set_active(svtools::IsFontSubstitutionsEnabled());
+
+ std::vector<SubstitutionStruct> aFontSubs = svtools::GetFontSubstitutions();
+ std::unique_ptr<weld::TreeIter> xIter(m_xCheckLB->make_iterator());
+ for (auto const & sub: aFontSubs)
+ {
+ m_xCheckLB->append(xIter.get());
+ m_xCheckLB->set_toggle(*xIter, sub.bReplaceAlways ? TRISTATE_TRUE : TRISTATE_FALSE, 0);
+ m_xCheckLB->set_toggle(*xIter, sub.bReplaceOnScreenOnly ? TRISTATE_TRUE : TRISTATE_FALSE, 1);
+ m_xCheckLB->set_text(*xIter, sub.sFont, 2);
+ m_xCheckLB->set_text(*xIter, sub.sReplaceBy, 3);
+ }
+
+ m_xCheckLB->thaw();
+
+ m_xCheckLB->make_sorted();
+ m_xCheckLB->set_sort_column(2);
+ m_xCheckLB->set_sort_indicator(TRISTATE_TRUE, 2);
+
+ SelectHdl(m_xFont1CB.get());
+
+ //fill font name box first
+ m_xNonPropFontsOnlyCB->set_active(
+ officecfg::Office::Common::Font::SourceViewFont::
+ NonProportionalFontsOnly::get());
+ NonPropFontsHdl(*m_xNonPropFontsOnlyCB);
+ OUString sFontName(
+ officecfg::Office::Common::Font::SourceViewFont::FontName::get().
+ value_or(OUString()));
+ if(!sFontName.isEmpty())
+ m_xFontNameLB->set_active_text(sFontName);
+ else
+ m_xFontNameLB->set_active(0);
+ m_xFontHeightLB->set_active_text(
+ OUString::number(
+ officecfg::Office::Common::Font::SourceViewFont::FontHeight::
+ get()));
+ m_xNonPropFontsOnlyCB->save_state();
+ m_xFontHeightLB->save_value();
+}
+
+IMPL_LINK(SvxFontSubstTabPage, ToggleHdl, weld::Toggleable&, rButton, void)
+{
+ SelectHdl(&rButton);
+}
+
+IMPL_LINK(SvxFontSubstTabPage, ClickHdl, weld::Button&, rButton, void)
+{
+ SelectHdl(&rButton);
+}
+
+IMPL_LINK(SvxFontSubstTabPage, TreeListBoxSelectHdl, weld::TreeView&, rButton, void)
+{
+ SelectHdl(&rButton);
+}
+
+IMPL_LINK(SvxFontSubstTabPage, SelectComboBoxHdl, weld::ComboBox&, rBox, void)
+{
+ SelectHdl(&rBox);
+}
+
+namespace
+{
+ // search in the "font" column
+ int findText(const weld::TreeView& rTreeView, std::u16string_view rCol)
+ {
+ for (int i = 0, nEntryCount = rTreeView.n_children(); i < nEntryCount; ++i)
+ {
+ if (rTreeView.get_text(i, 2) == rCol)
+ return i;
+ }
+ return -1;
+ }
+
+ bool findRow(const weld::TreeView& rTreeView, std::u16string_view rCol1, std::u16string_view rCol2)
+ {
+ int nRow = findText(rTreeView, rCol1);
+ if (nRow == -1)
+ return false;
+ return rTreeView.get_text(nRow, 3) == rCol2;
+ }
+}
+
+void SvxFontSubstTabPage::SelectHdl(const weld::Widget* pWin)
+{
+ if (pWin == m_xApply.get() || pWin == m_xDelete.get())
+ {
+ int nPos = findText(*m_xCheckLB, m_xFont1CB->get_active_text());
+ if (pWin == m_xApply.get())
+ {
+ m_xCheckLB->unselect_all();
+ if (nPos != -1)
+ {
+ // change entry
+ m_xCheckLB->set_text(nPos, m_xFont2CB->get_active_text(), 3);
+ m_xCheckLB->select(nPos);
+ }
+ else
+ {
+ // new entry
+ OUString sFont1 = m_xFont1CB->get_active_text();
+ OUString sFont2 = m_xFont2CB->get_active_text();
+
+ std::unique_ptr<weld::TreeIter> xIter(m_xCheckLB->make_iterator());
+ m_xCheckLB->append(xIter.get());
+ m_xCheckLB->set_toggle(*xIter, TRISTATE_FALSE, 0);
+ m_xCheckLB->set_toggle(*xIter, TRISTATE_FALSE, 1);
+ m_xCheckLB->set_text(*xIter, sFont1, 2);
+ m_xCheckLB->set_text(*xIter, sFont2, 3);
+ m_xCheckLB->select(*xIter);
+ }
+ }
+ else if (pWin == m_xDelete.get())
+ {
+ m_xCheckLB->remove_selection();
+ }
+ }
+
+ if (pWin == m_xCheckLB.get())
+ {
+ const int nSelectedRowCount = m_xCheckLB->count_selected_rows();
+ if (nSelectedRowCount == 1)
+ {
+ int nRow = m_xCheckLB->get_selected_index();
+ m_xFont1CB->set_entry_text(m_xCheckLB->get_text(nRow, 2));
+ m_xFont2CB->set_entry_text(m_xCheckLB->get_text(nRow, 3));
+ }
+ else if (nSelectedRowCount > 1)
+ {
+ m_xFont1CB->set_entry_text(OUString());
+ m_xFont2CB->set_entry_text(OUString());
+ }
+ }
+
+ if (pWin == m_xFont1CB.get())
+ {
+ int nPos = findText(*m_xCheckLB, m_xFont1CB->get_active_text());
+
+ if (nPos != -1)
+ {
+ int nSelectedRow = m_xCheckLB->get_selected_index();
+ if (nPos != nSelectedRow)
+ {
+ m_xCheckLB->unselect_all();
+ m_xCheckLB->select(nPos);
+ }
+ }
+ else
+ m_xCheckLB->unselect_all();
+ }
+
+ CheckEnable();
+}
+
+IMPL_LINK(SvxFontSubstTabPage, NonPropFontsHdl, weld::Toggleable&, rBox, void)
+{
+ OUString sFontName = m_xFontNameLB->get_active_text();
+ bool bNonPropOnly = rBox.get_active();
+ m_xFontNameLB->clear();
+ FontList aFntLst( Application::GetDefaultDevice() );
+ m_xFontNameLB->append_text(m_sAutomatic);
+ sal_uInt16 nFontCount = aFntLst.GetFontNameCount();
+ for(sal_uInt16 nFont = 0; nFont < nFontCount; nFont++)
+ {
+ const FontMetric& rFontMetric = aFntLst.GetFontName( nFont );
+ if(!bNonPropOnly || rFontMetric.GetPitch() == PITCH_FIXED)
+ m_xFontNameLB->append_text(rFontMetric.GetFamilyName());
+ }
+ m_xFontNameLB->set_active_text(sFontName);
+}
+
+void SvxFontSubstTabPage::CheckEnable()
+{
+ bool bEnableAll = m_xUseTableCB->get_active();
+ m_xCheckLB->set_sensitive(bEnableAll);
+ m_xFont1CB->set_sensitive(bEnableAll);
+ m_xFont2CB->set_sensitive(bEnableAll);
+
+ bool bApply = bEnableAll, bDelete = bEnableAll;
+
+ if (bEnableAll)
+ {
+ int nEntry = m_xCheckLB->get_selected_index();
+
+ if (m_xFont1CB->get_active_text().isEmpty() || m_xFont2CB->get_active_text().isEmpty())
+ bApply = false;
+ else if (m_xFont1CB->get_active_text() == m_xFont2CB->get_active_text())
+ bApply = false;
+ else if (findRow(*m_xCheckLB, m_xFont1CB->get_active_text(), m_xFont2CB->get_active_text()))
+ bApply = false;
+ else if (nEntry != -1 && m_xCheckLB->count_selected_rows() != 1)
+ bApply = false;
+ else
+ bApply = true;
+
+ bDelete = nEntry != -1;
+ }
+
+ m_xApply->set_sensitive(bApply);
+ m_xDelete->set_sensitive(bDelete);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */