LibreOffice Module cui (master)  1
fontsubs.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <sal/config.h>
21 
22 #include <officecfg/Office/Common.hxx>
23 #include <svtools/ctrltool.hxx>
24 #include <vcl/svapp.hxx>
26 #include "fontsubs.hxx"
27 #include <helpids.h>
28 
29 /*********************************************************************/
30 /* */
31 /* TabPage font replacement */
32 /* */
33 /*********************************************************************/
34 
36  : SfxTabPage(pPage, pController, "cui/ui/optfontspage.ui", "OptFontsPage", &rSet)
37  , m_xConfig(new SvtFontSubstConfig)
38  , m_xUseTableCB(m_xBuilder->weld_check_button("usetable"))
39  , m_xFont1CB(m_xBuilder->weld_combo_box("font1"))
40  , m_xFont2CB(m_xBuilder->weld_combo_box("font2"))
41  , m_xApply(m_xBuilder->weld_button("apply"))
42  , m_xDelete(m_xBuilder->weld_button("delete"))
43  , m_xCheckLB(m_xBuilder->weld_tree_view("checklb"))
44  , m_xFontNameLB(m_xBuilder->weld_combo_box("fontname"))
45  , m_xNonPropFontsOnlyCB(m_xBuilder->weld_check_button("nonpropfontonly"))
46  , m_xFontHeightLB(m_xBuilder->weld_combo_box("fontheight"))
47 {
48  m_xFont1CB->make_sorted();
49  m_xFont1CB->set_size_request(1, -1);
50  m_xFont2CB->make_sorted();
51  m_xFont2CB->set_size_request(1, -1);
52  m_sAutomatic = m_xFontNameLB->get_text(0);
53  assert(!m_sAutomatic.isEmpty());
54 
55  m_xCheckLB->set_size_request(m_xCheckLB->get_approximate_digit_width() * 60,
56  m_xCheckLB->get_height_rows(8));
57  m_xCheckLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
58  m_xCheckLB->set_help_id(HID_OFA_FONT_SUBST_CLB);
59  m_xCheckLB->set_selection_mode(SelectionMode::Multiple);
60 
61  setColSizes(m_xCheckLB->get_size_request());
62  m_xCheckLB->connect_size_allocate(LINK(this, SvxFontSubstTabPage, ResizeHdl));
63 
64  m_xCheckLB->set_centered_column(0);
65  m_xCheckLB->set_centered_column(1);
66 
67  Link<weld::ComboBox&,void> aLink2(LINK(this, SvxFontSubstTabPage, SelectComboBoxHdl));
68  Link<weld::Button&,void> aClickLink(LINK(this, SvxFontSubstTabPage, ClickHdl));
69 
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);
77 
78  m_xNonPropFontsOnlyCB->connect_toggled(LINK(this, SvxFontSubstTabPage, NonPropFontsHdl));
79 
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));
91 }
92 
93 IMPL_LINK(SvxFontSubstTabPage, HeaderBarClick, int, nColumn, void)
94 {
95  bool bSortAtoZ = m_xCheckLB->get_sort_order();
96 
97  //set new arrow positions in headerbar
98  if (nColumn == m_xCheckLB->get_sort_column())
99  {
100  bSortAtoZ = !bSortAtoZ;
101  m_xCheckLB->set_sort_order(bSortAtoZ);
102  }
103  else
104  {
105  m_xCheckLB->set_sort_indicator(TRISTATE_INDET, m_xCheckLB->get_sort_column());
106  m_xCheckLB->set_sort_column(nColumn);
107  }
108 
109  if (nColumn != -1)
110  {
111  //sort lists
112  m_xCheckLB->set_sort_indicator(bSortAtoZ ? TRISTATE_TRUE : TRISTATE_FALSE, nColumn);
113  }
114 }
115 
117 {
118  int nW1 = m_xCheckLB->get_pixel_size(m_xCheckLB->get_column_title(2)).Width();
119  int nW2 = m_xCheckLB->get_pixel_size(m_xCheckLB->get_column_title(3)).Width();
120  int nMax = std::max( nW1, nW2 ) + 6; // width of the longest header + a little offset
121  int nMin = m_xCheckLB->get_checkbox_column_width();
122  nMax = std::max(nMax, nMin);
123  const int nDoubleMax = 2*nMax;
124  const int nRest = rSize.Width() - nDoubleMax;
125  std::vector<int> aWidths;
126  aWidths.push_back(nMax);
127  aWidths.push_back(nMax);
128  aWidths.push_back(nRest/2);
129  m_xCheckLB->set_column_fixed_widths(aWidths);
130 }
131 
132 IMPL_LINK(SvxFontSubstTabPage, ResizeHdl, const Size&, rSize, void)
133 {
134  setColSizes(rSize);
135 }
136 
138 {
139 }
140 
141 std::unique_ptr<SfxTabPage> SvxFontSubstTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
142  const SfxItemSet* rAttrSet)
143 {
144  return std::make_unique<SvxFontSubstTabPage>(pPage, pController, *rAttrSet);
145 }
146 
148 {
149  m_xConfig->ClearSubstitutions();// remove all entries
150 
151  m_xConfig->Enable(m_xUseTableCB->get_active());
152 
153  m_xCheckLB->all_foreach([this](weld::TreeIter& rIter) {
154  SubstitutionStruct aAdd;
155  aAdd.sFont = m_xCheckLB->get_text(rIter, 2);
156  aAdd.sReplaceBy = m_xCheckLB->get_text(rIter, 3);
157  aAdd.bReplaceAlways = m_xCheckLB->get_toggle(rIter, 0);
158  aAdd.bReplaceOnScreenOnly = m_xCheckLB->get_toggle(rIter, 1);
159  m_xConfig->AddSubstitution(aAdd);
160  return false;
161  });
162 
163  if(m_xConfig->IsModified())
164  m_xConfig->Commit();
165  m_xConfig->Apply();
166  std::shared_ptr< comphelper::ConfigurationChanges > batch(
168  if (m_xFontHeightLB->get_value_changed_from_saved())
169  officecfg::Office::Common::Font::SourceViewFont::FontHeight::set(
170  static_cast< sal_Int16 >(m_xFontHeightLB->get_active_text().toInt32()),
171  batch);
172  if (m_xNonPropFontsOnlyCB->get_state_changed_from_saved())
173  officecfg::Office::Common::Font::SourceViewFont::
174  NonProportionalFontsOnly::set(
175  m_xNonPropFontsOnlyCB->get_active(), batch);
176  //font name changes cannot be detected by saved values
177  OUString sFontName;
178  if (m_xFontNameLB->get_active() != -1)
179  sFontName = m_xFontNameLB->get_active_text();
180  officecfg::Office::Common::Font::SourceViewFont::FontName::set(
181  std::optional< OUString >(sFontName), batch);
182  batch->commit();
183 
184  return false;
185 }
186 
188 {
189  m_xCheckLB->freeze();
190  m_xCheckLB->clear();
191 
192  m_xFont1CB->freeze();
193  m_xFont1CB->clear();
194  m_xFont2CB->freeze();
195  m_xFont2CB->clear();
196 
198  sal_uInt16 nFontCount = aFntLst.GetFontNameCount();
199  for (sal_uInt16 i = 0; i < nFontCount; ++i)
200  {
201  const FontMetric& rFontMetric = aFntLst.GetFontName(i);
202  m_xFont1CB->append_text(rFontMetric.GetFamilyName());
203  m_xFont2CB->append_text(rFontMetric.GetFamilyName());
204  }
205 
206  m_xFont2CB->thaw();
207  m_xFont1CB->thaw();
208 
209  sal_Int32 nCount = m_xConfig->SubstitutionCount();
210  if (nCount)
211  m_xUseTableCB->set_active(m_xConfig->IsEnabled());
212 
213  std::unique_ptr<weld::TreeIter> xIter(m_xCheckLB->make_iterator());
214  for (sal_Int32 i = 0; i < nCount; ++i)
215  {
216  m_xCheckLB->append(xIter.get());
217  const SubstitutionStruct* pSubs = m_xConfig->GetSubstitution(i);
218  m_xCheckLB->set_toggle(*xIter, pSubs->bReplaceAlways ? TRISTATE_TRUE : TRISTATE_FALSE, 0);
219  m_xCheckLB->set_toggle(*xIter, pSubs->bReplaceOnScreenOnly ? TRISTATE_TRUE : TRISTATE_FALSE, 1);
220  m_xCheckLB->set_text(*xIter, pSubs->sFont, 2);
221  m_xCheckLB->set_text(*xIter, pSubs->sReplaceBy, 3);
222  }
223 
224  m_xCheckLB->thaw();
225 
226  m_xCheckLB->make_sorted();
227  m_xCheckLB->set_sort_column(2);
228  m_xCheckLB->set_sort_indicator(TRISTATE_TRUE, 2);
229 
230  CheckEnable();
231 
232  //fill font name box first
233  m_xNonPropFontsOnlyCB->set_active(
234  officecfg::Office::Common::Font::SourceViewFont::
235  NonProportionalFontsOnly::get());
236  NonPropFontsHdl(*m_xNonPropFontsOnlyCB);
237  OUString sFontName(
238  officecfg::Office::Common::Font::SourceViewFont::FontName::get().
239  value_or(OUString()));
240  if(!sFontName.isEmpty())
241  m_xFontNameLB->set_active_text(sFontName);
242  else
243  m_xFontNameLB->set_active(0);
244  m_xFontHeightLB->set_active_text(
245  OUString::number(
246  officecfg::Office::Common::Font::SourceViewFont::FontHeight::
247  get()));
248  m_xNonPropFontsOnlyCB->save_state();
249  m_xFontHeightLB->save_value();
250 }
251 
252 IMPL_LINK(SvxFontSubstTabPage, ClickHdl, weld::Button&, rButton, void)
253 {
254  SelectHdl(&rButton);
255 }
256 
257 IMPL_LINK(SvxFontSubstTabPage, TreeListBoxSelectHdl, weld::TreeView&, rButton, void)
258 {
259  SelectHdl(&rButton);
260 }
261 
262 IMPL_LINK(SvxFontSubstTabPage, SelectComboBoxHdl, weld::ComboBox&, rBox, void)
263 {
264  SelectHdl(&rBox);
265 }
266 
267 namespace
268 {
269  // search in the "font" column
270  int findText(const weld::TreeView& rTreeView, std::u16string_view rCol)
271  {
272  for (int i = 0, nEntryCount = rTreeView.n_children(); i < nEntryCount; ++i)
273  {
274  if (rTreeView.get_text(i, 3) == rCol)
275  return i;
276  }
277  return -1;
278  }
279 
280  bool findRow(const weld::TreeView& rTreeView, std::u16string_view rCol1, std::u16string_view rCol2)
281  {
282  int nRow = findText(rTreeView, rCol1);
283  if (nRow == -1)
284  return false;
285  return rTreeView.get_text(nRow, 4) == rCol2;
286  }
287 }
288 
290 {
291  if (pWin == m_xApply.get() || pWin == m_xDelete.get())
292  {
293  int nPos = findText(*m_xCheckLB, m_xFont1CB->get_active_text());
294  if (pWin == m_xApply.get())
295  {
296  m_xCheckLB->unselect_all();
297  if (nPos != -1)
298  {
299  // change entry
300  m_xCheckLB->set_text(nPos, m_xFont2CB->get_active_text(), 3);
301  m_xCheckLB->select(nPos);
302  }
303  else
304  {
305  // new entry
306  OUString sFont1 = m_xFont1CB->get_active_text();
307  OUString sFont2 = m_xFont2CB->get_active_text();
308 
309  std::unique_ptr<weld::TreeIter> xIter(m_xCheckLB->make_iterator());
310  m_xCheckLB->append(xIter.get());
311  m_xCheckLB->set_toggle(*xIter, TRISTATE_FALSE, 0);
312  m_xCheckLB->set_toggle(*xIter, TRISTATE_FALSE, 1);
313  m_xCheckLB->set_text(*xIter, sFont1, 2);
314  m_xCheckLB->set_text(*xIter, sFont2, 3);
315  m_xCheckLB->select(*xIter);
316  }
317  }
318  else if (pWin == m_xDelete.get())
319  {
320  m_xCheckLB->remove_selection();
321  }
322  }
323 
324  if (pWin == m_xCheckLB.get())
325  {
326  if (m_xCheckLB->count_selected_rows() == 1)
327  {
328  int nRow = m_xCheckLB->get_selected_index();
329  m_xFont1CB->set_entry_text(m_xCheckLB->get_text(nRow, 2));
330  m_xFont2CB->set_entry_text(m_xCheckLB->get_text(nRow, 3));
331  }
332  }
333 
334  if (pWin == m_xFont1CB.get())
335  {
336  int nPos = findText(*m_xCheckLB, m_xFont1CB->get_active_text());
337 
338  if (nPos != -1)
339  {
340  int nSelectedRow = m_xCheckLB->get_selected_index();
341  if (nPos != nSelectedRow)
342  {
343  m_xCheckLB->unselect_all();
344  m_xCheckLB->select(nPos);
345  }
346  }
347  }
348 
349  CheckEnable();
350 }
351 
352 IMPL_LINK(SvxFontSubstTabPage, NonPropFontsHdl, weld::ToggleButton&, rBox, void)
353 {
354  OUString sFontName = m_xFontNameLB->get_active_text();
355  bool bNonPropOnly = rBox.get_active();
356  m_xFontNameLB->clear();
358  m_xFontNameLB->append_text(m_sAutomatic);
359  sal_uInt16 nFontCount = aFntLst.GetFontNameCount();
360  for(sal_uInt16 nFont = 0; nFont < nFontCount; nFont++)
361  {
362  const FontMetric& rFontMetric = aFntLst.GetFontName( nFont );
363  if(!bNonPropOnly || rFontMetric.GetPitch() == PITCH_FIXED)
364  m_xFontNameLB->append_text(rFontMetric.GetFamilyName());
365  }
366  m_xFontNameLB->set_active_text(sFontName);
367 }
368 
370 {
371  bool bEnableAll = m_xUseTableCB->get_active();
372  m_xCheckLB->set_sensitive(bEnableAll);
373  if (bEnableAll)
374  {
375  bool bApply, bDelete;
376 
377  int nEntry = m_xCheckLB->get_selected_index();
378 
379  // because of OS/2 optimization error (Bug #56267) a bit more intricate:
380  if (m_xFont1CB->get_active_text().isEmpty() || m_xFont2CB->get_active_text().isEmpty())
381  bApply = false;
382  else if (m_xFont1CB->get_active_text() == m_xFont2CB->get_active_text())
383  bApply = false;
384  else if (findRow(*m_xCheckLB, m_xFont1CB->get_active_text(), m_xFont2CB->get_active_text()))
385  bApply = false;
386  else if (nEntry != -1 && m_xCheckLB->count_selected_rows() != 1)
387  bApply = false;
388  else
389  bApply = true;
390 
391  bDelete = nEntry != -1;
392 
393  m_xApply->set_sensitive(bApply);
394  m_xDelete->set_sensitive(bDelete);
395  }
396 
397  if (bEnableAll)
398  {
399  if (!m_xCheckLB->get_sensitive())
400  {
401  m_xCheckLB->set_sensitive(true);
402  SelectHdl(m_xFont1CB.get());
403  }
404  }
405  else
406  {
407  if (m_xCheckLB->get_sensitive())
408  {
409  m_xCheckLB->set_sensitive(false);
410  m_xCheckLB->unselect_all();
411  }
412  }
413 }
414 
415 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const OUString & GetFamilyName() const
std::unique_ptr< weld::ComboBox > m_xFontHeightLB
Definition: fontsubs.hxx:39
TRISTATE_TRUE
std::unique_ptr< weld::Button > m_xDelete
Definition: fontsubs.hxx:35
std::unique_ptr< weld::ComboBox > m_xFont1CB
Definition: fontsubs.hxx:32
#define HID_OFA_FONT_SUBST_CLB
Definition: helpids.h:22
virtual bool FillItemSet(SfxItemSet *rSet) override
Definition: fontsubs.cxx:147
static OutputDevice * GetDefaultDevice()
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
std::unique_ptr< weld::ComboBox > m_xFontNameLB
Definition: fontsubs.hxx:37
int nCount
virtual int n_children() const =0
std::unique_ptr< weld::TreeView > m_xCheckLB
Definition: fontsubs.hxx:36
static std::shared_ptr< ConfigurationChanges > create(css::uno::Reference< css::uno::XComponentContext > const &context=comphelper::getProcessComponentContext())
TRISTATE_INDET
OUString m_sAutomatic
Definition: fontsubs.hxx:28
const FontMetric & GetFontName(size_t nFont) const
FontPitch GetPitch()
int i
PITCH_FIXED
std::unique_ptr< SvtFontSubstConfig > m_xConfig
Definition: fontsubs.hxx:29
TRISTATE_FALSE
tools::Long Width() const
virtual OUString get_text(int row, int col=-1) const =0
SvxFontSubstTabPage(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet &rSet)
Definition: fontsubs.cxx:35
std::unique_ptr< weld::CheckButton > m_xUseTableCB
Definition: fontsubs.hxx:31
void setColSizes(const Size &rSize)
Definition: fontsubs.cxx:116
size_t GetFontNameCount() const
static std::unique_ptr< SfxTabPage > Create(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet *rAttrSet)
Definition: fontsubs.cxx:141
std::unique_ptr< weld::ComboBox > m_xFont2CB
Definition: fontsubs.hxx:33
std::unique_ptr< weld::CheckButton > m_xNonPropFontsOnlyCB
Definition: fontsubs.hxx:38
virtual ~SvxFontSubstTabPage() override
Definition: fontsubs.cxx:137
std::unique_ptr< weld::Button > m_xApply
Definition: fontsubs.hxx:34
void SelectHdl(const weld::Widget *pWidget)
Definition: fontsubs.cxx:289
IMPL_LINK(SvxFontSubstTabPage, HeaderBarClick, int, nColumn, void)
Definition: fontsubs.cxx:93
virtual void Reset(const SfxItemSet *rSet) override
Definition: fontsubs.cxx:187
sal_uInt16 nPos