1/*
2 This file is part of the KDE libraries
3 SPDX-FileCopyrightText: 1999 Reginald Stadlbauer <reggie@kde.org>
4 SPDX-FileCopyrightText: 1999 Simon Hausmann <hausmann@kde.org>
5 SPDX-FileCopyrightText: 2000 Nicolas Hadacek <haadcek@kde.org>
6 SPDX-FileCopyrightText: 2000 Kurt Granroth <granroth@kde.org>
7 SPDX-FileCopyrightText: 2000 Michael Koch <koch@kde.org>
8 SPDX-FileCopyrightText: 2001 Holger Freyther <freyther@kde.org>
9 SPDX-FileCopyrightText: 2002 Ellis Whitehead <ellis@kde.org>
10 SPDX-FileCopyrightText: 2002 Joseph Wenninger <jowenn@kde.org>
11 SPDX-FileCopyrightText: 2003 Andras Mantia <amantia@kde.org>
12 SPDX-FileCopyrightText: 2005-2006 Hamish Rodda <rodda@kde.org>
13 SPDX-FileCopyrightText: 2007 Clarence Dang <dang@kde.org>
14
15 SPDX-License-Identifier: LGPL-2.0-only
16*/
17
18#include "kfontaction.h"
19
20#include "kselectaction_p.h"
21
22#include <QFontComboBox>
23
24#include <kfontchooser.h>
25
26class KFontActionPrivate : public KSelectActionPrivate
27{
28 Q_DECLARE_PUBLIC(KFontAction)
29
30public:
31 KFontActionPrivate(KFontAction *qq)
32 : KSelectActionPrivate(qq)
33 {
34 }
35
36 void slotFontChanged(const QFont &font)
37 {
38 Q_Q(KFontAction);
39
40 // qCDebug(KWidgetsAddonsLog) << "QFontComboBox - slotFontChanged("
41 // << font.family() << ") settingFont=" << settingFont;
42 if (settingFont) {
43 return;
44 }
45
46 const QString fontFamily = font.family();
47 q->setFont(fontFamily);
48 Q_EMIT q->textTriggered(text: fontFamily);
49
50 // qCDebug(KWidgetsAddonsLog) << "\tslotFontChanged done";
51 }
52
53 int settingFont = 0;
54 QFontComboBox::FontFilters fontFilters = QFontComboBox::AllFonts;
55};
56
57QStringList fontList(const QFontComboBox::FontFilters &fontFilters = QFontComboBox::AllFonts)
58{
59 QStringList families;
60 if (fontFilters == QFontComboBox::AllFonts) {
61 families = QFontDatabase::families();
62 } else {
63 const QFontComboBox::FontFilters scalableMask = (QFontComboBox::ScalableFonts | QFontComboBox::NonScalableFonts);
64 const QFontComboBox::FontFilters spacingMask = (QFontComboBox::ProportionalFonts | QFontComboBox::MonospacedFonts);
65
66 const auto allFamilies = QFontDatabase::families();
67 for (const QString &family : allFamilies) {
68 if ((fontFilters & scalableMask) && (fontFilters & scalableMask) != scalableMask) {
69 if (bool(fontFilters & QFontComboBox::ScalableFonts) != QFontDatabase::isSmoothlyScalable(family)) {
70 continue;
71 }
72 }
73 if ((fontFilters & spacingMask) && (fontFilters & spacingMask) != spacingMask) {
74 if (bool(fontFilters & QFontComboBox::MonospacedFonts) != QFontDatabase::isFixedPitch(family)) {
75 continue;
76 }
77 }
78
79 families << family;
80 }
81 }
82
83 families.sort();
84 return families;
85}
86
87KFontAction::KFontAction(uint fontListCriteria, QObject *parent)
88 : KSelectAction(*new KFontActionPrivate(this), parent)
89{
90 Q_D(KFontAction);
91
92 if (fontListCriteria & KFontChooser::FixedWidthFonts) {
93 d->fontFilters |= QFontComboBox::MonospacedFonts;
94 }
95
96 if (fontListCriteria & KFontChooser::SmoothScalableFonts) {
97 d->fontFilters |= QFontComboBox::ScalableFonts;
98 }
99
100 KSelectAction::setItems(fontList(fontFilters: d->fontFilters));
101 setEditable(true);
102}
103
104KFontAction::KFontAction(QObject *parent)
105 : KSelectAction(*new KFontActionPrivate(this), parent)
106{
107 KSelectAction::setItems(fontList());
108 setEditable(true);
109}
110
111KFontAction::KFontAction(const QString &text, QObject *parent)
112 : KSelectAction(*new KFontActionPrivate(this), parent)
113{
114 setText(text);
115 KSelectAction::setItems(fontList());
116 setEditable(true);
117}
118
119KFontAction::KFontAction(const QIcon &icon, const QString &text, QObject *parent)
120 : KSelectAction(*new KFontActionPrivate(this), parent)
121{
122 setIcon(icon);
123 setText(text);
124 KSelectAction::setItems(fontList());
125 setEditable(true);
126}
127
128KFontAction::~KFontAction() = default;
129
130QString KFontAction::font() const
131{
132 return currentText();
133}
134
135QWidget *KFontAction::createWidget(QWidget *parent)
136{
137 Q_D(KFontAction);
138
139 // qCDebug(KWidgetsAddonsLog) << "KFontAction::createWidget()";
140
141 // This is the visual element on the screen. This method overrides
142 // the KSelectAction one, preventing KSelectAction from creating its
143 // regular KComboBox.
144 QFontComboBox *cb = new QFontComboBox(parent);
145 cb->setFontFilters(d->fontFilters);
146
147 // qCDebug(KWidgetsAddonsLog) << "\tset=" << font();
148 // Do this before connecting the signal so that nothing will fire.
149 cb->setCurrentFont(QFont(font().toLower()));
150 // qCDebug(KWidgetsAddonsLog) << "\tspit back=" << cb->currentFont().family();
151
152 connect(sender: cb, signal: &QFontComboBox::currentFontChanged, context: this, slot: [this](const QFont &ft) {
153 Q_D(KFontAction);
154 d->slotFontChanged(font: ft);
155 });
156 cb->setMinimumWidth(cb->sizeHint().width());
157 return cb;
158}
159
160/*
161 * Maintenance note: Keep in sync with QFontComboBox::setCurrentFont()
162 */
163void KFontAction::setFont(const QString &family)
164{
165 Q_D(KFontAction);
166
167 // qCDebug(KWidgetsAddonsLog) << "KFontAction::setFont(" << family << ")";
168
169 // Suppress triggered(QString) signal and prevent recursive call to ourself.
170 d->settingFont++;
171
172 const auto createdWidgets = this->createdWidgets();
173 for (QWidget *w : createdWidgets) {
174 QFontComboBox *cb = qobject_cast<QFontComboBox *>(object: w);
175 // qCDebug(KWidgetsAddonsLog) << "\tw=" << w << "cb=" << cb;
176
177 if (!cb) {
178 continue;
179 }
180
181 cb->setCurrentFont(QFont(family.toLower()));
182 // qCDebug(KWidgetsAddonsLog) << "\t\tw spit back=" << cb->currentFont().family();
183 }
184
185 d->settingFont--;
186
187 // qCDebug(KWidgetsAddonsLog) << "\tcalling setCurrentAction()";
188
189 QString lowerName = family.toLower();
190 if (setCurrentAction(text: lowerName, cs: Qt::CaseInsensitive)) {
191 return;
192 }
193
194 int i = lowerName.indexOf(s: QLatin1String(" ["));
195 if (i > -1) {
196 lowerName.truncate(pos: i);
197 i = 0;
198 if (setCurrentAction(text: lowerName, cs: Qt::CaseInsensitive)) {
199 return;
200 }
201 }
202
203 lowerName += QLatin1String(" [");
204 if (setCurrentAction(text: lowerName, cs: Qt::CaseInsensitive)) {
205 return;
206 }
207
208 // TODO: Inconsistent state if QFontComboBox::setCurrentFont() succeeded
209 // but setCurrentAction() did not and vice-versa.
210 // qCDebug(KWidgetsAddonsLog) << "Font not found " << family.toLower();
211}
212
213#include "moc_kfontaction.cpp"
214

source code of kwidgetsaddons/src/kfontaction.cpp