examples/painting/fontsampler/mainwindow.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 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:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include <QtGui>
       
    43 
       
    44 #include "mainwindow.h"
       
    45 
       
    46 MainWindow::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 
       
    65 void 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 
       
    92 void 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 
       
   100 void MainWindow::on_markAction_triggered()
       
   101 {
       
   102     markUnmarkFonts(Qt::Checked);
       
   103 }
       
   104 
       
   105 void MainWindow::on_unmarkAction_triggered()
       
   106 {
       
   107     markUnmarkFonts(Qt::Unchecked);
       
   108 }
       
   109 
       
   110 void 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 
       
   119 void 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 
       
   159 void 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 
       
   221 void 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 
       
   241 void 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 
       
   273 void 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 
       
   287 QMap<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 
       
   310 void 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 }