Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / cui / source / options / fontsubs.cxx
blob4cedb534c6f93feb2a7b3317322467d7a08d7124
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include <officecfg/Office/Common.hxx>
23 #include <svtools/ctrltool.hxx>
24 #include <vcl/svapp.hxx>
25 #include <svtools/fontsubstconfig.hxx>
26 #include "fontsubs.hxx"
27 #include <helpids.h>
29 /*********************************************************************/
30 /* */
31 /* TabPage font replacement */
32 /* */
33 /*********************************************************************/
35 SvxFontSubstTabPage::SvxFontSubstTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
36 : SfxTabPage(pPage, pController, "cui/ui/optfontspage.ui", "OptFontsPage", &rSet)
37 , m_xConfig(new SvtFontSubstConfig)
38 , m_bSorted(false)
39 , m_xUseTableCB(m_xBuilder->weld_check_button("usetable"))
40 , m_xFont1CB(m_xBuilder->weld_combo_box("font1"))
41 , m_xFont2CB(m_xBuilder->weld_combo_box("font2"))
42 , m_xApply(m_xBuilder->weld_button("apply"))
43 , m_xDelete(m_xBuilder->weld_button("delete"))
44 , m_xCheckLB(m_xBuilder->weld_tree_view("checklb"))
45 , m_xFontNameLB(m_xBuilder->weld_combo_box("fontname"))
46 , m_xNonPropFontsOnlyCB(m_xBuilder->weld_check_button("nonpropfontonly"))
47 , m_xFontHeightLB(m_xBuilder->weld_combo_box("fontheight"))
49 m_xFont1CB->make_sorted();
50 m_xFont1CB->set_size_request(1, -1);
51 m_xFont2CB->make_sorted();
52 m_xFont2CB->set_size_request(1, -1);
53 m_sAutomatic = m_xFontNameLB->get_text(0);
54 assert(!m_sAutomatic.isEmpty());
56 m_xCheckLB->set_size_request(m_xCheckLB->get_approximate_digit_width() * 80,
57 m_xCheckLB->get_height_rows(10));
58 m_xCheckLB->set_help_id(HID_OFA_FONT_SUBST_CLB);
59 m_xCheckLB->set_selection_mode(SelectionMode::Multiple);
60 m_xCheckLB->set_sort_column(3);
62 setColSizes();
64 m_xCheckLB->set_centered_column(1);
65 m_xCheckLB->set_centered_column(2);
67 Link<weld::ComboBox&,void> aLink2(LINK(this, SvxFontSubstTabPage, SelectComboBoxHdl));
68 Link<weld::Button&,void> aClickLink(LINK(this, SvxFontSubstTabPage, ClickHdl));
70 m_xCheckLB->connect_changed(LINK(this, SvxFontSubstTabPage, TreeListBoxSelectHdl));
71 m_xCheckLB->connect_column_clicked(LINK(this, SvxFontSubstTabPage, HeaderBarClick));
72 m_xUseTableCB->connect_clicked(aClickLink);
73 m_xFont1CB->connect_changed(aLink2);
74 m_xFont2CB->connect_changed(aLink2);
75 m_xApply->connect_clicked(aClickLink);
76 m_xDelete->connect_clicked(aClickLink);
78 m_xNonPropFontsOnlyCB->connect_toggled(LINK(this, SvxFontSubstTabPage, NonPropFontsHdl));
80 sal_uInt16 nHeight;
81 for(nHeight = 6; nHeight <= 16; nHeight++)
82 m_xFontHeightLB->append_text(OUString::number(nHeight));
83 for(nHeight = 18; nHeight <= 28; nHeight+= 2)
84 m_xFontHeightLB->append_text(OUString::number(nHeight));
85 for(nHeight = 32; nHeight <= 48; nHeight+= 4)
86 m_xFontHeightLB->append_text(OUString::number(nHeight));
87 for(nHeight = 54; nHeight <= 72; nHeight+= 6)
88 m_xFontHeightLB->append_text(OUString::number(nHeight));
89 for(nHeight = 80; nHeight <= 96; nHeight+= 8)
90 m_xFontHeightLB->append_text(OUString::number(nHeight));
93 IMPL_LINK(SvxFontSubstTabPage, HeaderBarClick, int, nColumn, void)
95 if (!m_bSorted)
97 m_xCheckLB->make_sorted();
98 m_bSorted = true;
101 bool bSortAtoZ = m_xCheckLB->get_sort_order();
103 //set new arrow positions in headerbar
104 if (nColumn == m_xCheckLB->get_sort_column())
106 bSortAtoZ = !bSortAtoZ;
107 m_xCheckLB->set_sort_order(bSortAtoZ);
109 else
111 m_xCheckLB->set_sort_indicator(TRISTATE_INDET, m_xCheckLB->get_sort_column());
112 m_xCheckLB->set_sort_column(nColumn);
115 if (nColumn != -1)
117 //sort lists
118 m_xCheckLB->set_sort_indicator(bSortAtoZ ? TRISTATE_TRUE : TRISTATE_FALSE, nColumn);
122 void SvxFontSubstTabPage::setColSizes()
124 int nW1 = m_xCheckLB->get_pixel_size(m_xCheckLB->get_column_title(3)).Width();
125 int nW2 = m_xCheckLB->get_pixel_size(m_xCheckLB->get_column_title(4)).Width();
126 int nMax = std::max( nW1, nW2 ) + 6; // width of the longest header + a little offset
127 int nMin = m_xCheckLB->get_checkbox_column_width();
128 nMax = std::max(nMax, nMin);
129 const int nDoubleMax = 2*nMax;
130 const int nRest = m_xCheckLB->get_size_request().Width() - nDoubleMax;
131 std::vector<int> aWidths;
132 aWidths.push_back(1); // just abandon the built-in column for checkbuttons and use another
133 aWidths.push_back(nMax);
134 aWidths.push_back(nMax);
135 aWidths.push_back(nRest/2);
136 m_xCheckLB->set_column_fixed_widths(aWidths);
139 SvxFontSubstTabPage::~SvxFontSubstTabPage()
143 std::unique_ptr<SfxTabPage> SvxFontSubstTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
144 const SfxItemSet* rAttrSet)
146 return std::make_unique<SvxFontSubstTabPage>(pPage, pController, *rAttrSet);
149 bool SvxFontSubstTabPage::FillItemSet( SfxItemSet* )
151 m_xConfig->ClearSubstitutions();// remove all entries
153 m_xConfig->Enable(m_xUseTableCB->get_active());
155 m_xCheckLB->all_foreach([this](weld::TreeIter& rIter) {
156 SubstitutionStruct aAdd;
157 aAdd.sFont = m_xCheckLB->get_text(rIter, 3);
158 aAdd.sReplaceBy = m_xCheckLB->get_text(rIter, 4);
159 aAdd.bReplaceAlways = m_xCheckLB->get_toggle(rIter, 1);
160 aAdd.bReplaceOnScreenOnly = m_xCheckLB->get_toggle(rIter, 2);
161 m_xConfig->AddSubstitution(aAdd);
162 return false;
165 if(m_xConfig->IsModified())
166 m_xConfig->Commit();
167 m_xConfig->Apply();
168 std::shared_ptr< comphelper::ConfigurationChanges > batch(
169 comphelper::ConfigurationChanges::create());
170 if (m_xFontHeightLB->get_value_changed_from_saved())
171 officecfg::Office::Common::Font::SourceViewFont::FontHeight::set(
172 static_cast< sal_Int16 >(m_xFontHeightLB->get_active_text().toInt32()),
173 batch);
174 if (m_xNonPropFontsOnlyCB->get_state_changed_from_saved())
175 officecfg::Office::Common::Font::SourceViewFont::
176 NonProportionalFontsOnly::set(
177 m_xNonPropFontsOnlyCB->get_active(), batch);
178 //font name changes cannot be detected by saved values
179 OUString sFontName;
180 if (m_xFontNameLB->get_active() != -1)
181 sFontName = m_xFontNameLB->get_active_text();
182 officecfg::Office::Common::Font::SourceViewFont::FontName::set(
183 boost::optional< OUString >(sFontName), batch);
184 batch->commit();
186 return false;
189 void SvxFontSubstTabPage::Reset( const SfxItemSet* )
191 m_xCheckLB->freeze();
192 m_xCheckLB->clear();
194 FontList aFntLst(Application::GetDefaultDevice());
195 sal_uInt16 nFontCount = aFntLst.GetFontNameCount();
196 for (sal_uInt16 i = 0; i < nFontCount; ++i)
198 const FontMetric& rFontMetric = aFntLst.GetFontName(i);
199 m_xFont1CB->append_text(rFontMetric.GetFamilyName());
200 m_xFont2CB->append_text(rFontMetric.GetFamilyName());
203 sal_Int32 nCount = m_xConfig->SubstitutionCount();
204 if (nCount)
205 m_xUseTableCB->set_active(m_xConfig->IsEnabled());
207 for (sal_Int32 i = 0; i < nCount; ++i)
209 m_xCheckLB->append();
210 const SubstitutionStruct* pSubs = m_xConfig->GetSubstitution(i);
211 m_xCheckLB->set_toggle(i, pSubs->bReplaceAlways ? TRISTATE_TRUE : TRISTATE_FALSE, 1);
212 m_xCheckLB->set_toggle(i, pSubs->bReplaceOnScreenOnly ? TRISTATE_TRUE : TRISTATE_FALSE, 2);
213 m_xCheckLB->set_text(i, pSubs->sFont, 3);
214 m_xCheckLB->set_text(i, pSubs->sReplaceBy, 4);
217 m_xCheckLB->thaw();
219 CheckEnable();
221 //fill font name box first
222 m_xNonPropFontsOnlyCB->set_active(
223 officecfg::Office::Common::Font::SourceViewFont::
224 NonProportionalFontsOnly::get());
225 NonPropFontsHdl(*m_xNonPropFontsOnlyCB);
226 OUString sFontName(
227 officecfg::Office::Common::Font::SourceViewFont::FontName::get().
228 get_value_or(OUString()));
229 if(!sFontName.isEmpty())
230 m_xFontNameLB->set_active_text(sFontName);
231 else
232 m_xFontNameLB->set_active(0);
233 m_xFontHeightLB->set_active_text(
234 OUString::number(
235 officecfg::Office::Common::Font::SourceViewFont::FontHeight::
236 get()));
237 m_xNonPropFontsOnlyCB->save_state();
238 m_xFontHeightLB->save_value();
241 IMPL_LINK(SvxFontSubstTabPage, ClickHdl, weld::Button&, rButton, void)
243 SelectHdl(&rButton);
246 IMPL_LINK(SvxFontSubstTabPage, TreeListBoxSelectHdl, weld::TreeView&, rButton, void)
248 SelectHdl(&rButton);
251 IMPL_LINK(SvxFontSubstTabPage, SelectComboBoxHdl, weld::ComboBox&, rBox, void)
253 SelectHdl(&rBox);
256 namespace
258 // search in the "font" column
259 int findText(const weld::TreeView& rTreeView, const OUString& rCol)
261 for (int i = 0, nEntryCount = rTreeView.n_children(); i < nEntryCount; ++i)
263 if (rTreeView.get_text(i, 3) == rCol)
264 return i;
266 return -1;
269 bool findRow(const weld::TreeView& rTreeView, const OUString& rCol1, const OUString& rCol2)
271 int nRow = findText(rTreeView, rCol1);
272 if (nRow == -1)
273 return false;
274 return rTreeView.get_text(nRow, 4) == rCol2;
278 void SvxFontSubstTabPage::SelectHdl(const weld::Widget* pWin)
280 if (pWin == m_xApply.get() || pWin == m_xDelete.get())
282 int nPos = findText(*m_xCheckLB, m_xFont1CB->get_active_text());
283 if (pWin == m_xApply.get())
285 if (nPos != -1)
287 // change entry
288 m_xCheckLB->set_text(nPos, m_xFont2CB->get_active_text(), 4);
290 else
292 // new entry
293 OUString sFont1 = m_xFont1CB->get_active_text();
294 OUString sFont2 = m_xFont2CB->get_active_text();
296 nPos = m_xCheckLB->n_children();
297 m_xCheckLB->append();
298 m_xCheckLB->set_toggle(nPos, TRISTATE_FALSE, 1);
299 m_xCheckLB->set_toggle(nPos, TRISTATE_FALSE, 2);
300 m_xCheckLB->set_text(nPos, sFont1, 3);
301 m_xCheckLB->set_text(nPos, sFont2, 4);
304 m_xCheckLB->unselect_all();
305 m_xCheckLB->select(nPos);
307 else if (pWin == m_xDelete.get())
309 m_xCheckLB->remove_selection();
313 if (pWin == m_xCheckLB.get())
315 if (m_xCheckLB->count_selected_rows() == 1)
317 int nRow = m_xCheckLB->get_selected_index();
318 m_xFont1CB->set_entry_text(m_xCheckLB->get_text(nRow, 3));
319 m_xFont2CB->set_entry_text(m_xCheckLB->get_text(nRow, 4));
323 if (pWin == m_xFont1CB.get())
325 int nPos = findText(*m_xCheckLB, m_xFont1CB->get_active_text());
327 if (nPos != -1)
329 int nSelectedRow = m_xCheckLB->get_selected_index();
330 if (nPos != nSelectedRow)
332 m_xCheckLB->unselect_all();
333 m_xCheckLB->select(nPos);
338 CheckEnable();
341 IMPL_LINK(SvxFontSubstTabPage, NonPropFontsHdl, weld::ToggleButton&, rBox, void)
343 OUString sFontName = m_xFontNameLB->get_active_text();
344 bool bNonPropOnly = rBox.get_active();
345 m_xFontNameLB->clear();
346 FontList aFntLst( Application::GetDefaultDevice() );
347 m_xFontNameLB->append_text(m_sAutomatic);
348 sal_uInt16 nFontCount = aFntLst.GetFontNameCount();
349 for(sal_uInt16 nFont = 0; nFont < nFontCount; nFont++)
351 const FontMetric& rFontMetric = aFntLst.GetFontName( nFont );
352 if(!bNonPropOnly || rFontMetric.GetPitch() == PITCH_FIXED)
353 m_xFontNameLB->append_text(rFontMetric.GetFamilyName());
355 m_xFontNameLB->set_active_text(sFontName);
358 void SvxFontSubstTabPage::CheckEnable()
360 bool bEnableAll = m_xUseTableCB->get_active();
361 m_xCheckLB->set_sensitive(bEnableAll);
362 if (bEnableAll)
364 bool bApply, bDelete;
366 int nEntry = m_xCheckLB->get_selected_index();
368 // because of OS/2 optimization error (Bug #56267) a bit more intricate:
369 if (m_xFont1CB->get_active_text().isEmpty() || m_xFont2CB->get_active_text().isEmpty())
370 bApply = false;
371 else if (m_xFont1CB->get_active_text() == m_xFont2CB->get_active_text())
372 bApply = false;
373 else if (findRow(*m_xCheckLB, m_xFont1CB->get_active_text(), m_xFont2CB->get_active_text()))
374 bApply = false;
375 else if (nEntry != -1 && m_xCheckLB->count_selected_rows() != 1)
376 bApply = false;
377 else
378 bApply = true;
380 bDelete = nEntry != -1;
382 m_xApply->set_sensitive(bApply);
383 m_xDelete->set_sensitive(bDelete);
386 if (bEnableAll)
388 if (!m_xCheckLB->get_sensitive())
390 m_xCheckLB->set_sensitive(true);
391 SelectHdl(m_xFont1CB.get());
394 else
396 if (m_xCheckLB->get_sensitive())
398 m_xCheckLB->set_sensitive(false);
399 m_xCheckLB->unselect_all();
404 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */