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