1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the examples of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:BSD$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** BSD License Usage |
18 | ** Alternatively, you may use this file under the terms of the BSD license |
19 | ** as follows: |
20 | ** |
21 | ** "Redistribution and use in source and binary forms, with or without |
22 | ** modification, are permitted provided that the following conditions are |
23 | ** met: |
24 | ** * Redistributions of source code must retain the above copyright |
25 | ** notice, this list of conditions and the following disclaimer. |
26 | ** * Redistributions in binary form must reproduce the above copyright |
27 | ** notice, this list of conditions and the following disclaimer in |
28 | ** the documentation and/or other materials provided with the |
29 | ** distribution. |
30 | ** * Neither the name of The Qt Company Ltd nor the names of its |
31 | ** contributors may be used to endorse or promote products derived |
32 | ** from this software without specific prior written permission. |
33 | ** |
34 | ** |
35 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
36 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
37 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
38 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
39 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
40 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
41 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
42 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
43 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
44 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
45 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." |
46 | ** |
47 | ** $QT_END_LICENSE$ |
48 | ** |
49 | ****************************************************************************/ |
50 | |
51 | #include "mainwindow.h" |
52 | #include "characterwidget.h" |
53 | |
54 | #include <QApplication> |
55 | #include <QBoxLayout> |
56 | #include <QCheckBox> |
57 | #include <QClipboard> |
58 | #include <QDesktopWidget> |
59 | #include <QDialog> |
60 | #include <QDialogButtonBox> |
61 | #include <QFontComboBox> |
62 | #include <QLabel> |
63 | #include <QLineEdit> |
64 | #include <QMenuBar> |
65 | #include <QPlainTextEdit> |
66 | #include <QPushButton> |
67 | #include <QScreen> |
68 | #include <QScrollArea> |
69 | #include <QStatusBar> |
70 | #include <QTextStream> |
71 | |
72 | //! [0] |
73 | Q_DECLARE_METATYPE(QFontComboBox::FontFilter) |
74 | |
75 | MainWindow::MainWindow(QWidget *parent) |
76 | : QMainWindow(parent) |
77 | { |
78 | QMenu * = menuBar()->addMenu(title: tr(s: "File" )); |
79 | fileMenu->addAction(text: tr(s: "Quit" ), object: this, slot: &QWidget::close); |
80 | QMenu * = menuBar()->addMenu(title: tr(s: "&Help" )); |
81 | helpMenu->addAction(text: tr(s: "Show Font Info" ), object: this, slot: &MainWindow::showInfo); |
82 | helpMenu->addAction(text: tr(s: "About &Qt" ), qApp, slot: &QApplication::aboutQt); |
83 | |
84 | QWidget *centralWidget = new QWidget; |
85 | |
86 | QLabel *filterLabel = new QLabel(tr(s: "Filter:" )); |
87 | filterCombo = new QComboBox; |
88 | filterCombo->addItem(atext: tr(s: "All" ), auserData: QVariant::fromValue(value: QFontComboBox::AllFonts)); |
89 | filterCombo->addItem(atext: tr(s: "Scalable" ), auserData: QVariant::fromValue(value: QFontComboBox::ScalableFonts)); |
90 | filterCombo->addItem(atext: tr(s: "Monospaced" ), auserData: QVariant::fromValue(value: QFontComboBox::MonospacedFonts)); |
91 | filterCombo->addItem(atext: tr(s: "Proportional" ), auserData: QVariant::fromValue(value: QFontComboBox::ProportionalFonts)); |
92 | filterCombo->setCurrentIndex(0); |
93 | connect(sender: filterCombo, signal: QOverload<int>::of(ptr: &QComboBox::currentIndexChanged), |
94 | receiver: this, slot: &MainWindow::filterChanged); |
95 | |
96 | QLabel *fontLabel = new QLabel(tr(s: "Font:" )); |
97 | fontCombo = new QFontComboBox; |
98 | QLabel *sizeLabel = new QLabel(tr(s: "Size:" )); |
99 | sizeCombo = new QComboBox; |
100 | QLabel *styleLabel = new QLabel(tr(s: "Style:" )); |
101 | styleCombo = new QComboBox; |
102 | QLabel *fontMergingLabel = new QLabel(tr(s: "Automatic Font Merging:" )); |
103 | fontMerging = new QCheckBox; |
104 | fontMerging->setChecked(true); |
105 | |
106 | scrollArea = new QScrollArea; |
107 | characterWidget = new CharacterWidget; |
108 | scrollArea->setWidget(characterWidget); |
109 | //! [0] |
110 | |
111 | //! [1] |
112 | findStyles(font: fontCombo->currentFont()); |
113 | //! [1] |
114 | findSizes(font: fontCombo->currentFont()); |
115 | |
116 | //! [2] |
117 | lineEdit = new QLineEdit; |
118 | lineEdit->setClearButtonEnabled(true); |
119 | #ifndef QT_NO_CLIPBOARD |
120 | QPushButton *clipboardButton = new QPushButton(tr(s: "&To clipboard" )); |
121 | //! [2] |
122 | |
123 | #endif |
124 | |
125 | //! [4] |
126 | connect(sender: fontCombo, signal: &QFontComboBox::currentFontChanged, |
127 | receiver: this, slot: &MainWindow::findStyles); |
128 | connect(sender: fontCombo, signal: &QFontComboBox::currentFontChanged, |
129 | receiver: this, slot: &MainWindow::findSizes); |
130 | connect(sender: fontCombo, signal: &QFontComboBox::currentFontChanged, |
131 | receiver: characterWidget, slot: &CharacterWidget::updateFont); |
132 | connect(sender: sizeCombo, signal: &QComboBox::currentTextChanged, |
133 | receiver: characterWidget, slot: &CharacterWidget::updateSize); |
134 | connect(sender: styleCombo, signal: &QComboBox::currentTextChanged, |
135 | receiver: characterWidget, slot: &CharacterWidget::updateStyle); |
136 | //! [4] //! [5] |
137 | connect(sender: characterWidget, signal: &CharacterWidget::characterSelected, |
138 | receiver: this, slot: &MainWindow::insertCharacter); |
139 | |
140 | #ifndef QT_NO_CLIPBOARD |
141 | connect(sender: clipboardButton, signal: &QAbstractButton::clicked, receiver: this, slot: &MainWindow::updateClipboard); |
142 | #endif |
143 | //! [5] |
144 | connect(sender: fontMerging, signal: &QAbstractButton::toggled, receiver: characterWidget, slot: &CharacterWidget::updateFontMerging); |
145 | |
146 | //! [6] |
147 | QHBoxLayout *controlsLayout = new QHBoxLayout; |
148 | controlsLayout->addWidget(filterLabel); |
149 | controlsLayout->addWidget(filterCombo, stretch: 1); |
150 | controlsLayout->addWidget(fontLabel); |
151 | controlsLayout->addWidget(fontCombo, stretch: 1); |
152 | controlsLayout->addWidget(sizeLabel); |
153 | controlsLayout->addWidget(sizeCombo, stretch: 1); |
154 | controlsLayout->addWidget(styleLabel); |
155 | controlsLayout->addWidget(styleCombo, stretch: 1); |
156 | controlsLayout->addWidget(fontMergingLabel); |
157 | controlsLayout->addWidget(fontMerging, stretch: 1); |
158 | controlsLayout->addStretch(stretch: 1); |
159 | |
160 | QHBoxLayout *lineLayout = new QHBoxLayout; |
161 | lineLayout->addWidget(lineEdit, stretch: 1); |
162 | lineLayout->addSpacing(size: 12); |
163 | #ifndef QT_NO_CLIPBOARD |
164 | lineLayout->addWidget(clipboardButton); |
165 | #endif |
166 | |
167 | QVBoxLayout *centralLayout = new QVBoxLayout; |
168 | centralLayout->addLayout(layout: controlsLayout); |
169 | centralLayout->addWidget(scrollArea, stretch: 1); |
170 | centralLayout->addSpacing(size: 4); |
171 | centralLayout->addLayout(layout: lineLayout); |
172 | centralWidget->setLayout(centralLayout); |
173 | |
174 | setCentralWidget(centralWidget); |
175 | setWindowTitle(tr(s: "Character Map" )); |
176 | } |
177 | //! [6] |
178 | |
179 | //! [7] |
180 | void MainWindow::findStyles(const QFont &font) |
181 | { |
182 | QFontDatabase fontDatabase; |
183 | QString currentItem = styleCombo->currentText(); |
184 | styleCombo->clear(); |
185 | //! [7] |
186 | |
187 | //! [8] |
188 | const QStringList styles = fontDatabase.styles(family: font.family()); |
189 | for (const QString &style : styles) |
190 | styleCombo->addItem(atext: style); |
191 | |
192 | int styleIndex = styleCombo->findText(text: currentItem); |
193 | |
194 | if (styleIndex == -1) |
195 | styleCombo->setCurrentIndex(0); |
196 | else |
197 | styleCombo->setCurrentIndex(styleIndex); |
198 | } |
199 | //! [8] |
200 | |
201 | void MainWindow::filterChanged(int f) |
202 | { |
203 | const QFontComboBox::FontFilter filter = |
204 | qvariant_cast<QFontComboBox::FontFilter>(v: filterCombo->itemData(index: f)); |
205 | fontCombo->setFontFilters(filter); |
206 | statusBar()->showMessage(text: tr(s: "%n font(s) found" , c: nullptr, n: fontCombo->count())); |
207 | } |
208 | |
209 | void MainWindow::findSizes(const QFont &font) |
210 | { |
211 | QFontDatabase fontDatabase; |
212 | QString currentSize = sizeCombo->currentText(); |
213 | |
214 | { |
215 | const QSignalBlocker blocker(sizeCombo); |
216 | // sizeCombo signals are now blocked until end of scope |
217 | sizeCombo->clear(); |
218 | |
219 | if (fontDatabase.isSmoothlyScalable(family: font.family(), style: fontDatabase.styleString(font))) { |
220 | const QList<int> sizes = QFontDatabase::standardSizes(); |
221 | for (const int size : sizes) { |
222 | sizeCombo->addItem(atext: QVariant(size).toString()); |
223 | sizeCombo->setEditable(true); |
224 | } |
225 | |
226 | } else { |
227 | const QList<int> sizes = fontDatabase.smoothSizes(family: font.family(), style: fontDatabase.styleString(font)); |
228 | for (const int size : sizes ) { |
229 | sizeCombo->addItem(atext: QVariant(size).toString()); |
230 | sizeCombo->setEditable(false); |
231 | } |
232 | } |
233 | } |
234 | |
235 | int sizeIndex = sizeCombo->findText(text: currentSize); |
236 | |
237 | if(sizeIndex == -1) |
238 | sizeCombo->setCurrentIndex(qMax(a: 0, b: sizeCombo->count() / 3)); |
239 | else |
240 | sizeCombo->setCurrentIndex(sizeIndex); |
241 | } |
242 | |
243 | //! [9] |
244 | void MainWindow::insertCharacter(const QString &character) |
245 | { |
246 | lineEdit->insert(character); |
247 | } |
248 | //! [9] |
249 | |
250 | //! [10] |
251 | #ifndef QT_NO_CLIPBOARD |
252 | void MainWindow::updateClipboard() |
253 | { |
254 | //! [11] |
255 | QGuiApplication::clipboard()->setText(lineEdit->text(), mode: QClipboard::Clipboard); |
256 | //! [11] |
257 | QGuiApplication::clipboard()->setText(lineEdit->text(), mode: QClipboard::Selection); |
258 | } |
259 | #endif |
260 | |
261 | class FontInfoDialog : public QDialog |
262 | { |
263 | public: |
264 | explicit FontInfoDialog(QWidget *parent = nullptr); |
265 | |
266 | private: |
267 | QString text() const; |
268 | }; |
269 | |
270 | FontInfoDialog::FontInfoDialog(QWidget *parent) : QDialog(parent) |
271 | { |
272 | setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); |
273 | QVBoxLayout *mainLayout = new QVBoxLayout(this); |
274 | QPlainTextEdit *textEdit = new QPlainTextEdit(text(), this); |
275 | textEdit->setReadOnly(true); |
276 | textEdit->setFont(QFontDatabase::systemFont(type: QFontDatabase::FixedFont)); |
277 | mainLayout->addWidget(textEdit); |
278 | QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close, this); |
279 | connect(sender: buttonBox, signal: &QDialogButtonBox::rejected, receiver: this, slot: &QDialog::reject); |
280 | mainLayout->addWidget(buttonBox); |
281 | } |
282 | |
283 | QString FontInfoDialog::text() const |
284 | { |
285 | QString text; |
286 | QTextStream str(&text); |
287 | const QFont defaultFont = QFontDatabase::systemFont(type: QFontDatabase::GeneralFont); |
288 | const QFont fixedFont = QFontDatabase::systemFont(type: QFontDatabase::FixedFont); |
289 | const QFont titleFont = QFontDatabase::systemFont(type: QFontDatabase::TitleFont); |
290 | const QFont smallestReadableFont = QFontDatabase::systemFont(type: QFontDatabase::SmallestReadableFont); |
291 | |
292 | str << "Qt " << QT_VERSION_STR << " on " << QGuiApplication::platformName() |
293 | << ", " << logicalDpiX() << "DPI" ; |
294 | if (!qFuzzyCompare(p1: devicePixelRatioF(), p2: qreal(1))) |
295 | str << ", device pixel ratio: " << devicePixelRatioF(); |
296 | str << "\n\nDefault font : " << defaultFont.family() << ", " << defaultFont.pointSizeF() << "pt\n" |
297 | << "Fixed font : " << fixedFont.family() << ", " << fixedFont.pointSizeF() << "pt\n" |
298 | << "Title font : " << titleFont.family() << ", " << titleFont.pointSizeF() << "pt\n" |
299 | << "Smallest font: " << smallestReadableFont.family() << ", " << smallestReadableFont.pointSizeF() << "pt\n" ; |
300 | |
301 | return text; |
302 | } |
303 | |
304 | void MainWindow::showInfo() |
305 | { |
306 | const QRect screenGeometry = screen()->geometry(); |
307 | FontInfoDialog *dialog = new FontInfoDialog(this); |
308 | dialog->setWindowTitle(tr(s: "Fonts" )); |
309 | dialog->setAttribute(Qt::WA_DeleteOnClose); |
310 | dialog->resize(w: screenGeometry.width() / 4, h: screenGeometry.height() / 4); |
311 | dialog->show(); |
312 | } |
313 | |
314 | //! [10] |
315 | |