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

Last change on this file since 5 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 12.1 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 pageMap = currentPageMap();
224
225 if (pageMap.count() == 0)
226 return;
227
228 QPrinter printer(QPrinter::HighResolution);
229 QPrintDialog dialog(&printer, this);
230 if (dialog.exec() != QDialog::Accepted)
231 return;
232
233 int from = printer.fromPage();
234 int to = printer.toPage();
235 if (from <= 0 && to <= 0)
236 printer.setFromTo(1, pageMap.keys().count());
237
238 printDocument(&printer);
239}
240
241void MainWindow::printDocument(QPrinter *printer)
242{
243 printer->setFromTo(1, pageMap.count());
244
245 QProgressDialog progress(tr("Preparing font samples..."), tr("&Cancel"),
246 0, pageMap.count(), this);
247 progress.setWindowModality(Qt::ApplicationModal);
248 progress.setWindowTitle(tr("Font Sampler"));
249 progress.setMinimum(printer->fromPage() - 1);
250 progress.setMaximum(printer->toPage());
251
252 QPainter painter;
253 painter.begin(printer);
254 bool firstPage = true;
255
256 for (int page = printer->fromPage(); page <= printer->toPage(); ++page) {
257
258 if (!firstPage)
259 printer->newPage();
260
261 qApp->processEvents();
262 if (progress.wasCanceled())
263 break;
264
265 printPage(page - 1, &painter, printer);
266 progress.setValue(page);
267 firstPage = false;
268 }
269
270 painter.end();
271}
272
273void MainWindow::on_printPreviewAction_triggered()
274{
275 pageMap = currentPageMap();
276
277 if (pageMap.count() == 0)
278 return;
279
280 QPrinter printer(QPrinter::HighResolution);
281 QPrintPreviewDialog preview(&printer, this);
282 connect(&preview, SIGNAL(paintRequested(QPrinter *)),
283 this, SLOT(printDocument(QPrinter *)));
284 preview.exec();
285}
286
287QMap<QString, StyleItems> MainWindow::currentPageMap()
288{
289 QMap<QString, StyleItems> pageMap;
290
291 for (int row = 0; row < fontTree->topLevelItemCount(); ++row) {
292 QTreeWidgetItem *familyItem = fontTree->topLevelItem(row);
293 QString family;
294
295 if (familyItem->checkState(0) == Qt::Checked) {
296 family = familyItem->text(0);
297 pageMap[family] = StyleItems();
298 }
299
300 for (int childRow = 0; childRow < familyItem->childCount(); ++childRow) {
301 QTreeWidgetItem *styleItem = familyItem->child(childRow);
302 if (styleItem->checkState(0) == Qt::Checked)
303 pageMap[family].append(styleItem);
304 }
305 }
306
307 return pageMap;
308}
309
310void MainWindow::printPage(int index, QPainter *painter, QPrinter *printer)
311{
312 QString family = pageMap.keys()[index];
313 StyleItems items = pageMap[family];
314
315 // Find the dimensions of the text on each page.
316 qreal width = 0.0;
317 qreal height = 0.0;
318 foreach (QTreeWidgetItem *item, items) {
319 QString style = item->text(0);
320 int weight = item->data(0, Qt::UserRole).toInt();
321 bool italic = item->data(0, Qt::UserRole + 1).toBool();
322
323 // Calculate the maximum width and total height of the text.
324 foreach (int size, sampleSizes) {
325 QFont font(family, size, weight, italic);
326 font = QFont(font, painter->device());
327 QFontMetricsF fontMetrics(font);
328 QRectF rect = fontMetrics.boundingRect(
329 QString("%1 %2").arg(family).arg(style));
330 width = qMax(rect.width(), width);
331 height += rect.height();
332 }
333 }
334
335 qreal xScale = printer->pageRect().width() / width;
336 qreal yScale = printer->pageRect().height() / height;
337 qreal scale = qMin(xScale, yScale);
338
339 qreal remainingHeight = printer->pageRect().height()/scale - height;
340 qreal spaceHeight = (remainingHeight/4.0) / (items.count() + 1);
341 qreal interLineHeight = (remainingHeight/4.0) / (sampleSizes.count() * items.count());
342
343 painter->save();
344 painter->translate(printer->pageRect().width()/2.0, printer->pageRect().height()/2.0);
345 painter->scale(scale, scale);
346 painter->setBrush(QBrush(Qt::black));
347
348 qreal x = -width/2.0;
349 qreal y = -height/2.0 - remainingHeight/4.0 + spaceHeight;
350
351 foreach (QTreeWidgetItem *item, items) {
352 QString style = item->text(0);
353 int weight = item->data(0, Qt::UserRole).toInt();
354 bool italic = item->data(0, Qt::UserRole + 1).toBool();
355
356 // Draw each line of text.
357 foreach (int size, sampleSizes) {
358 QFont font(family, size, weight, italic);
359 font = QFont(font, painter->device());
360 QFontMetricsF fontMetrics(font);
361 QRectF rect = fontMetrics.boundingRect(QString("%1 %2").arg(
362 font.family()).arg(style));
363 y += rect.height();
364 painter->setFont(font);
365 painter->drawText(QPointF(x, y),
366 QString("%1 %2").arg(family).arg(style));
367 y += interLineHeight;
368 }
369 y += spaceHeight;
370 }
371
372 painter->restore();
373}
Note: See TracBrowser for help on using the repository browser.