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

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

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 12.3 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the examples of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:BSD$
10** You may use this file under the terms of the BSD license as follows:
11**
12** "Redistribution and use in source and binary forms, with or without
13** modification, are permitted provided that the following conditions are
14** met:
15** * Redistributions of source code must retain the above copyright
16** notice, this list of conditions and the following disclaimer.
17** * Redistributions in binary form must reproduce the above copyright
18** notice, this list of conditions and the following disclaimer in
19** the documentation and/or other materials provided with the
20** distribution.
21** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22** the names of its contributors may be used to endorse or promote
23** products derived from this software without specific prior written
24** permission.
25**
26** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41#include <QtGui>
42
43#include "mainwindow.h"
44
45MainWindow::MainWindow(QWidget *parent)
46 : QMainWindow(parent)
47{
48 setupUi(this);
49
50 sampleSizes << 32 << 24 << 16 << 14 << 12 << 8 << 4 << 2 << 1;
51 markedCount = 0;
52 setupFontTree();
53
54 connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
55 connect(fontTree, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
56 this, SLOT(showFont(QTreeWidgetItem*)));
57 connect(fontTree, SIGNAL(itemChanged(QTreeWidgetItem*,int)),
58 this, SLOT(updateStyles(QTreeWidgetItem*,int)));
59
60 fontTree->setItemSelected(fontTree->topLevelItem(0), true);
61 showFont(fontTree->topLevelItem(0));
62}
63
64void MainWindow::setupFontTree()
65{
66 QFontDatabase database;
67 fontTree->setColumnCount(1);
68 fontTree->setHeaderLabels(QStringList() << tr("Font"));
69
70 foreach (QString family, database.families()) {
71 const QStringList styles = database.styles(family);
72 if (styles.isEmpty())
73 continue;
74
75 QTreeWidgetItem *familyItem = new QTreeWidgetItem(fontTree);
76 familyItem->setText(0, family);
77 familyItem->setCheckState(0, Qt::Unchecked);
78
79 foreach (QString style, styles) {
80 QTreeWidgetItem *styleItem = new QTreeWidgetItem(familyItem);
81 styleItem->setText(0, style);
82 styleItem->setCheckState(0, Qt::Unchecked);
83 styleItem->setData(0, Qt::UserRole,
84 QVariant(database.weight(family, style)));
85 styleItem->setData(0, Qt::UserRole + 1,
86 QVariant(database.italic(family, style)));
87 }
88 }
89}
90
91void MainWindow::on_clearAction_triggered()
92{
93 QTreeWidgetItem *currentItem = fontTree->currentItem();
94 foreach (QTreeWidgetItem *item, fontTree->selectedItems())
95 fontTree->setItemSelected(item, false);
96 fontTree->setItemSelected(currentItem, true);
97}
98
99void MainWindow::on_markAction_triggered()
100{
101 markUnmarkFonts(Qt::Checked);
102}
103
104void MainWindow::on_unmarkAction_triggered()
105{
106 markUnmarkFonts(Qt::Unchecked);
107}
108
109void MainWindow::markUnmarkFonts(Qt::CheckState state)
110{
111 QList<QTreeWidgetItem *> items = fontTree->selectedItems();
112 foreach (QTreeWidgetItem *item, items) {
113 if (item->checkState(0) != state)
114 item->setCheckState(0, state);
115 }
116}
117
118void MainWindow::showFont(QTreeWidgetItem *item)
119{
120 if (!item)
121 return;
122
123 QString family;
124 QString style;
125 int weight;
126 bool italic;
127
128 if (item->parent()) {
129 family = item->parent()->text(0);
130 style = item->text(0);
131 weight = item->data(0, Qt::UserRole).toInt();
132 italic = item->data(0, Qt::UserRole + 1).toBool();
133 } else {
134 family = item->text(0);
135 style = item->child(0)->text(0);
136 weight = item->child(0)->data(0, Qt::UserRole).toInt();
137 italic = item->child(0)->data(0, Qt::UserRole + 1).toBool();
138 }
139
140 QString oldText = textEdit->toPlainText().trimmed();
141 bool modified = textEdit->document()->isModified();
142 textEdit->clear();
143 textEdit->document()->setDefaultFont(QFont(family, 32, weight, italic));
144
145 QTextCursor cursor = textEdit->textCursor();
146 QTextBlockFormat blockFormat;
147 blockFormat.setAlignment(Qt::AlignCenter);
148 cursor.insertBlock(blockFormat);
149
150 if (modified)
151 cursor.insertText(QString(oldText));
152 else
153 cursor.insertText(QString("%1 %2").arg(family).arg(style));
154
155 textEdit->document()->setModified(modified);
156}
157
158void MainWindow::updateStyles(QTreeWidgetItem *item, int column)
159{
160 if (!item || column != 0)
161 return;
162
163 Qt::CheckState state = item->checkState(0);
164 QTreeWidgetItem *parent = item->parent();
165
166 if (parent) {
167
168 // Only count style items.
169 if (state == Qt::Checked)
170 ++markedCount;
171 else
172 --markedCount;
173
174 if (state == Qt::Checked &&
175 parent->checkState(0) == Qt::Unchecked) {
176 // Mark parent items when child items are checked.
177 parent->setCheckState(0, Qt::Checked);
178
179 } else if (state == Qt::Unchecked &&
180 parent->checkState(0) == Qt::Checked) {
181
182 bool marked = false;
183 for (int row = 0; row < parent->childCount(); ++row) {
184 if (parent->child(row)->checkState(0) == Qt::Checked) {
185 marked = true;
186 break;
187 }
188 }
189 // Unmark parent items when all child items are unchecked.
190 if (!marked)
191 parent->setCheckState(0, Qt::Unchecked);
192 }
193 } else {
194 int row;
195 int number = 0;
196 for (row = 0; row < item->childCount(); ++row) {
197 if (item->child(row)->checkState(0) == Qt::Checked)
198 ++number;
199 }
200
201 // Mark/unmark all child items when marking/unmarking top-level
202 // items.
203 if (state == Qt::Checked && number == 0) {
204 for (row = 0; row < item->childCount(); ++row) {
205 if (item->child(row)->checkState(0) == Qt::Unchecked)
206 item->child(row)->setCheckState(0, Qt::Checked);
207 }
208 } else if (state == Qt::Unchecked && number > 0) {
209 for (row = 0; row < item->childCount(); ++row) {
210 if (item->child(row)->checkState(0) == Qt::Checked)
211 item->child(row)->setCheckState(0, Qt::Unchecked);
212 }
213 }
214 }
215
216 printAction->setEnabled(markedCount > 0);
217 printPreviewAction->setEnabled(markedCount > 0);
218}
219
220void MainWindow::on_printAction_triggered()
221{
222#if !defined(QT_NO_PRINTER)
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#endif
240}
241
242void MainWindow::printDocument(QPrinter *printer)
243{
244#if !defined(QT_NO_PRINTER)
245 printer->setFromTo(1, pageMap.count());
246
247 QProgressDialog progress(tr("Preparing font samples..."), tr("&Cancel"),
248 0, pageMap.count(), this);
249 progress.setWindowModality(Qt::ApplicationModal);
250 progress.setWindowTitle(tr("Font Sampler"));
251 progress.setMinimum(printer->fromPage() - 1);
252 progress.setMaximum(printer->toPage());
253
254 QPainter painter;
255 painter.begin(printer);
256 bool firstPage = true;
257
258 for (int page = printer->fromPage(); page <= printer->toPage(); ++page) {
259
260 if (!firstPage)
261 printer->newPage();
262
263 qApp->processEvents();
264 if (progress.wasCanceled())
265 break;
266
267 printPage(page - 1, &painter, printer);
268 progress.setValue(page);
269 firstPage = false;
270 }
271
272 painter.end();
273#endif
274}
275
276void MainWindow::on_printPreviewAction_triggered()
277{
278#if !defined(QT_NO_PRINTER)
279 pageMap = currentPageMap();
280
281 if (pageMap.count() == 0)
282 return;
283
284 QPrinter printer(QPrinter::HighResolution);
285 QPrintPreviewDialog preview(&printer, this);
286 connect(&preview, SIGNAL(paintRequested(QPrinter*)),
287 this, SLOT(printDocument(QPrinter*)));
288 preview.exec();
289#endif
290}
291
292QMap<QString, StyleItems> MainWindow::currentPageMap()
293{
294 QMap<QString, StyleItems> pageMap;
295
296 for (int row = 0; row < fontTree->topLevelItemCount(); ++row) {
297 QTreeWidgetItem *familyItem = fontTree->topLevelItem(row);
298 QString family;
299
300 if (familyItem->checkState(0) == Qt::Checked) {
301 family = familyItem->text(0);
302 pageMap[family] = StyleItems();
303 }
304
305 for (int childRow = 0; childRow < familyItem->childCount(); ++childRow) {
306 QTreeWidgetItem *styleItem = familyItem->child(childRow);
307 if (styleItem->checkState(0) == Qt::Checked)
308 pageMap[family].append(styleItem);
309 }
310 }
311
312 return pageMap;
313}
314
315void MainWindow::printPage(int index, QPainter *painter, QPrinter *printer)
316{
317#if !defined(QT_NO_PRINTER)
318 QString family = pageMap.keys()[index];
319 StyleItems items = pageMap[family];
320
321 // Find the dimensions of the text on each page.
322 qreal width = 0.0;
323 qreal height = 0.0;
324 foreach (QTreeWidgetItem *item, items) {
325 QString style = item->text(0);
326 int weight = item->data(0, Qt::UserRole).toInt();
327 bool italic = item->data(0, Qt::UserRole + 1).toBool();
328
329 // Calculate the maximum width and total height of the text.
330 foreach (int size, sampleSizes) {
331 QFont font(family, size, weight, italic);
332 font = QFont(font, painter->device());
333 QFontMetricsF fontMetrics(font);
334 QRectF rect = fontMetrics.boundingRect(
335 QString("%1 %2").arg(family).arg(style));
336 width = qMax(rect.width(), width);
337 height += rect.height();
338 }
339 }
340
341 qreal xScale = printer->pageRect().width() / width;
342 qreal yScale = printer->pageRect().height() / height;
343 qreal scale = qMin(xScale, yScale);
344
345 qreal remainingHeight = printer->pageRect().height()/scale - height;
346 qreal spaceHeight = (remainingHeight/4.0) / (items.count() + 1);
347 qreal interLineHeight = (remainingHeight/4.0) / (sampleSizes.count() * items.count());
348
349 painter->save();
350 painter->translate(printer->pageRect().width()/2.0, printer->pageRect().height()/2.0);
351 painter->scale(scale, scale);
352 painter->setBrush(QBrush(Qt::black));
353
354 qreal x = -width/2.0;
355 qreal y = -height/2.0 - remainingHeight/4.0 + spaceHeight;
356
357 foreach (QTreeWidgetItem *item, items) {
358 QString style = item->text(0);
359 int weight = item->data(0, Qt::UserRole).toInt();
360 bool italic = item->data(0, Qt::UserRole + 1).toBool();
361
362 // Draw each line of text.
363 foreach (int size, sampleSizes) {
364 QFont font(family, size, weight, italic);
365 font = QFont(font, painter->device());
366 QFontMetricsF fontMetrics(font);
367 QRectF rect = fontMetrics.boundingRect(QString("%1 %2").arg(
368 font.family()).arg(style));
369 y += rect.height();
370 painter->setFont(font);
371 painter->drawText(QPointF(x, y),
372 QString("%1 %2").arg(family).arg(style));
373 y += interLineHeight;
374 }
375 y += spaceHeight;
376 }
377
378 painter->restore();
379#endif
380}
Note: See TracBrowser for help on using the repository browser.