source: trunk/examples/painting/fontsampler/mainwindow.cpp@ 516

Last change on this file since 516 was 516, checked in by Dmitry A. Kuminov, 15 years ago

examples: Added #ifndef QT_NO_PRINTER around QPrinter-related parts to some examples to make them build on platforms with no printer support.

File size: 12.2 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information (qt-info@nokia.com)
5**
6** This file is part of the examples of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at qt-sales@nokia.com.
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include <QtGui>
43
44#include "mainwindow.h"
45
46MainWindow::MainWindow(QWidget *parent)
47 : QMainWindow(parent)
48{
49 setupUi(this);
50
51 sampleSizes << 32 << 24 << 16 << 14 << 12 << 8 << 4 << 2 << 1;
52 markedCount = 0;
53 setupFontTree();
54
55 connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
56 connect(fontTree, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
57 this, SLOT(showFont(QTreeWidgetItem *)));
58 connect(fontTree, SIGNAL(itemChanged(QTreeWidgetItem *, int)),
59 this, SLOT(updateStyles(QTreeWidgetItem *, int)));
60
61 fontTree->setItemSelected(fontTree->topLevelItem(0), true);
62 showFont(fontTree->topLevelItem(0));
63}
64
65void MainWindow::setupFontTree()
66{
67 QFontDatabase database;
68 fontTree->setColumnCount(1);
69 fontTree->setHeaderLabels(QStringList() << tr("Font"));
70
71 foreach (QString family, database.families()) {
72 const QStringList styles = database.styles(family);
73 if (styles.isEmpty())
74 continue;
75
76 QTreeWidgetItem *familyItem = new QTreeWidgetItem(fontTree);
77 familyItem->setText(0, family);
78 familyItem->setCheckState(0, Qt::Unchecked);
79
80 foreach (QString style, styles) {
81 QTreeWidgetItem *styleItem = new QTreeWidgetItem(familyItem);
82 styleItem->setText(0, style);
83 styleItem->setCheckState(0, Qt::Unchecked);
84 styleItem->setData(0, Qt::UserRole,
85 QVariant(database.weight(family, style)));
86 styleItem->setData(0, Qt::UserRole + 1,
87 QVariant(database.italic(family, style)));
88 }
89 }
90}
91
92void MainWindow::on_clearAction_triggered()
93{
94 QTreeWidgetItem *currentItem = fontTree->currentItem();
95 foreach (QTreeWidgetItem *item, fontTree->selectedItems())
96 fontTree->setItemSelected(item, false);
97 fontTree->setItemSelected(currentItem, true);
98}
99
100void MainWindow::on_markAction_triggered()
101{
102 markUnmarkFonts(Qt::Checked);
103}
104
105void MainWindow::on_unmarkAction_triggered()
106{
107 markUnmarkFonts(Qt::Unchecked);
108}
109
110void MainWindow::markUnmarkFonts(Qt::CheckState state)
111{
112 QList<QTreeWidgetItem *> items = fontTree->selectedItems();
113 foreach (QTreeWidgetItem *item, items) {
114 if (item->checkState(0) != state)
115 item->setCheckState(0, state);
116 }
117}
118
119void MainWindow::showFont(QTreeWidgetItem *item)
120{
121 if (!item)
122 return;
123
124 QString family;
125 QString style;
126 int weight;
127 bool italic;
128
129 if (item->parent()) {
130 family = item->parent()->text(0);
131 style = item->text(0);
132 weight = item->data(0, Qt::UserRole).toInt();
133 italic = item->data(0, Qt::UserRole + 1).toBool();
134 } else {
135 family = item->text(0);
136 style = item->child(0)->text(0);
137 weight = item->child(0)->data(0, Qt::UserRole).toInt();
138 italic = item->child(0)->data(0, Qt::UserRole + 1).toBool();
139 }
140
141 QString oldText = textEdit->toPlainText().trimmed();
142 bool modified = textEdit->document()->isModified();
143 textEdit->clear();
144 textEdit->document()->setDefaultFont(QFont(family, 32, weight, italic));
145
146 QTextCursor cursor = textEdit->textCursor();
147 QTextBlockFormat blockFormat;
148 blockFormat.setAlignment(Qt::AlignCenter);
149 cursor.insertBlock(blockFormat);
150
151 if (modified)
152 cursor.insertText(QString(oldText));
153 else
154 cursor.insertText(QString("%1 %2").arg(family).arg(style));
155
156 textEdit->document()->setModified(modified);
157}
158
159void MainWindow::updateStyles(QTreeWidgetItem *item, int column)
160{
161 if (!item || column != 0)
162 return;
163
164 Qt::CheckState state = item->checkState(0);
165 QTreeWidgetItem *parent = item->parent();
166
167 if (parent) {
168
169 // Only count style items.
170 if (state == Qt::Checked)
171 ++markedCount;
172 else
173 --markedCount;
174
175 if (state == Qt::Checked &&
176 parent->checkState(0) == Qt::Unchecked) {
177 // Mark parent items when child items are checked.
178 parent->setCheckState(0, Qt::Checked);
179
180 } else if (state == Qt::Unchecked &&
181 parent->checkState(0) == Qt::Checked) {
182
183 bool marked = false;
184 for (int row = 0; row < parent->childCount(); ++row) {
185 if (parent->child(row)->checkState(0) == Qt::Checked) {
186 marked = true;
187 break;
188 }
189 }
190 // Unmark parent items when all child items are unchecked.
191 if (!marked)
192 parent->setCheckState(0, Qt::Unchecked);
193 }
194 } else {
195 int row;
196 int number = 0;
197 for (row = 0; row < item->childCount(); ++row) {
198 if (item->child(row)->checkState(0) == Qt::Checked)
199 ++number;
200 }
201
202 // Mark/unmark all child items when marking/unmarking top-level
203 // items.
204 if (state == Qt::Checked && number == 0) {
205 for (row = 0; row < item->childCount(); ++row) {
206 if (item->child(row)->checkState(0) == Qt::Unchecked)
207 item->child(row)->setCheckState(0, Qt::Checked);
208 }
209 } else if (state == Qt::Unchecked && number > 0) {
210 for (row = 0; row < item->childCount(); ++row) {
211 if (item->child(row)->checkState(0) == Qt::Checked)
212 item->child(row)->setCheckState(0, Qt::Unchecked);
213 }
214 }
215 }
216
217 printAction->setEnabled(markedCount > 0);
218 printPreviewAction->setEnabled(markedCount > 0);
219}
220
221void MainWindow::on_printAction_triggered()
222{
223#if !defined(QT_NO_PRINTER)
224 pageMap = currentPageMap();
225
226 if (pageMap.count() == 0)
227 return;
228
229 QPrinter printer(QPrinter::HighResolution);
230 QPrintDialog dialog(&printer, this);
231 if (dialog.exec() != QDialog::Accepted)
232 return;
233
234 int from = printer.fromPage();
235 int to = printer.toPage();
236 if (from <= 0 && to <= 0)
237 printer.setFromTo(1, pageMap.keys().count());
238
239 printDocument(&printer);
240#endif
241}
242
243void MainWindow::printDocument(QPrinter *printer)
244{
245#if !defined(QT_NO_PRINTER)
246 printer->setFromTo(1, pageMap.count());
247
248 QProgressDialog progress(tr("Preparing font samples..."), tr("&Cancel"),
249 0, pageMap.count(), this);
250 progress.setWindowModality(Qt::ApplicationModal);
251 progress.setWindowTitle(tr("Font Sampler"));
252 progress.setMinimum(printer->fromPage() - 1);
253 progress.setMaximum(printer->toPage());
254
255 QPainter painter;
256 painter.begin(printer);
257 bool firstPage = true;
258
259 for (int page = printer->fromPage(); page <= printer->toPage(); ++page) {
260
261 if (!firstPage)
262 printer->newPage();
263
264 qApp->processEvents();
265 if (progress.wasCanceled())
266 break;
267
268 printPage(page - 1, &painter, printer);
269 progress.setValue(page);
270 firstPage = false;
271 }
272
273 painter.end();
274#endif
275}
276
277void MainWindow::on_printPreviewAction_triggered()
278{
279#if !defined(QT_NO_PRINTER)
280 pageMap = currentPageMap();
281
282 if (pageMap.count() == 0)
283 return;
284
285 QPrinter printer(QPrinter::HighResolution);
286 QPrintPreviewDialog preview(&printer, this);
287 connect(&preview, SIGNAL(paintRequested(QPrinter *)),
288 this, SLOT(printDocument(QPrinter *)));
289 preview.exec();
290#endif
291}
292
293QMap<QString, StyleItems> MainWindow::currentPageMap()
294{
295 QMap<QString, StyleItems> pageMap;
296
297 for (int row = 0; row < fontTree->topLevelItemCount(); ++row) {
298 QTreeWidgetItem *familyItem = fontTree->topLevelItem(row);
299 QString family;
300
301 if (familyItem->checkState(0) == Qt::Checked) {
302 family = familyItem->text(0);
303 pageMap[family] = StyleItems();
304 }
305
306 for (int childRow = 0; childRow < familyItem->childCount(); ++childRow) {
307 QTreeWidgetItem *styleItem = familyItem->child(childRow);
308 if (styleItem->checkState(0) == Qt::Checked)
309 pageMap[family].append(styleItem);
310 }
311 }
312
313 return pageMap;
314}
315
316void MainWindow::printPage(int index, QPainter *painter, QPrinter *printer)
317{
318#if !defined(QT_NO_PRINTER)
319 QString family = pageMap.keys()[index];
320 StyleItems items = pageMap[family];
321
322 // Find the dimensions of the text on each page.
323 qreal width = 0.0;
324 qreal height = 0.0;
325 foreach (QTreeWidgetItem *item, items) {
326 QString style = item->text(0);
327 int weight = item->data(0, Qt::UserRole).toInt();
328 bool italic = item->data(0, Qt::UserRole + 1).toBool();
329
330 // Calculate the maximum width and total height of the text.
331 foreach (int size, sampleSizes) {
332 QFont font(family, size, weight, italic);
333 font = QFont(font, painter->device());
334 QFontMetricsF fontMetrics(font);
335 QRectF rect = fontMetrics.boundingRect(
336 QString("%1 %2").arg(family).arg(style));
337 width = qMax(rect.width(), width);
338 height += rect.height();
339 }
340 }
341
342 qreal xScale = printer->pageRect().width() / width;
343 qreal yScale = printer->pageRect().height() / height;
344 qreal scale = qMin(xScale, yScale);
345
346 qreal remainingHeight = printer->pageRect().height()/scale - height;
347 qreal spaceHeight = (remainingHeight/4.0) / (items.count() + 1);
348 qreal interLineHeight = (remainingHeight/4.0) / (sampleSizes.count() * items.count());
349
350 painter->save();
351 painter->translate(printer->pageRect().width()/2.0, printer->pageRect().height()/2.0);
352 painter->scale(scale, scale);
353 painter->setBrush(QBrush(Qt::black));
354
355 qreal x = -width/2.0;
356 qreal y = -height/2.0 - remainingHeight/4.0 + spaceHeight;
357
358 foreach (QTreeWidgetItem *item, items) {
359 QString style = item->text(0);
360 int weight = item->data(0, Qt::UserRole).toInt();
361 bool italic = item->data(0, Qt::UserRole + 1).toBool();
362
363 // Draw each line of text.
364 foreach (int size, sampleSizes) {
365 QFont font(family, size, weight, italic);
366 font = QFont(font, painter->device());
367 QFontMetricsF fontMetrics(font);
368 QRectF rect = fontMetrics.boundingRect(QString("%1 %2").arg(
369 font.family()).arg(style));
370 y += rect.height();
371 painter->setFont(font);
372 painter->drawText(QPointF(x, y),
373 QString("%1 %2").arg(family).arg(style));
374 y += interLineHeight;
375 }
376 y += spaceHeight;
377 }
378
379 painter->restore();
380#endif
381}
Note: See TracBrowser for help on using the repository browser.