printpreview.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** Copyright (C) 2004-2007 Trolltech ASA. All rights reserved.
00004 **
00005 ** This file is part of the demonstration applications of the Qt Toolkit.
00006 **
00007 ** This file may be used under the terms of the GNU General Public
00008 ** License version 2.0 as published by the Free Software Foundation
00009 ** and appearing in the file LICENSE.GPL included in the packaging of
00010 ** this file.  Please review the following information to ensure GNU
00011 ** General Public Licensing requirements will be met:
00012 ** http://www.trolltech.com/products/qt/opensource.html
00013 **
00014 ** If you are unsure which license is appropriate for your use, please
00015 ** review the following information:
00016 ** http://www.trolltech.com/products/qt/licensing.html or contact the
00017 ** sales department at sales@trolltech.com.
00018 **
00019 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00020 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00021 **
00022 ****************************************************************************/
00023 
00024 #include <QAbstractScrollArea>
00025 #include <QPrintDialog>
00026 #include <QPrinter>
00027 #include <QToolBar>
00028 #include <QAction>
00029 #include <QTextFormat>
00030 #include <QMouseEvent>
00031 #include <QTextFrame>
00032 #include <QTextDocument>
00033 #include <QAbstractTextDocumentLayout>
00034 #include <QScrollBar>
00035 #include <QPainter>
00036 #include <QDebug>
00037 #include <QPageSetupDialog>
00038 #include <QStatusBar>
00039 
00040 #include "printpreview.h"
00041 
00042 #ifdef Q_WS_MAC
00043 const QString rsrcPath = ":/images/mac";
00044 #else
00045 const QString rsrcPath = ":/images/win";
00046 #endif
00047 
00048 static inline int inchesToPixels(float inches, QPaintDevice *device)
00049 {
00050     return qRound(inches * device->logicalDpiY());
00051 }
00052 
00053 static inline qreal mmToInches(double mm)
00054 {
00055     return mm*0.039370147;
00056 }
00057 
00058 class PreviewView : public QAbstractScrollArea
00059 {
00060     Q_OBJECT
00061 public:
00062     PreviewView(QTextDocument *document);
00063 
00064     inline void updateLayout() { resizeEvent(0); viewport()->update(); }
00065 
00066 public slots:
00067     void zoomIn();
00068     void zoomOut();
00069 
00070 protected:
00071     virtual void paintEvent(QPaintEvent *e);
00072     virtual void resizeEvent(QResizeEvent *);
00073     virtual void mousePressEvent(QMouseEvent *e);
00074     virtual void mouseMoveEvent(QMouseEvent *e);
00075     virtual void mouseReleaseEvent(QMouseEvent *e);
00076 
00077 private:
00078     void paintPage(QPainter *painter, int page);
00079     QTextDocument *doc;
00080     qreal scale;
00081     int interPageSpacing;
00082     QPoint mousePressPos;
00083     QPoint scrollBarValuesOnMousePress;
00084 };
00085 
00086 PreviewView::PreviewView(QTextDocument *document)
00087 {
00088     verticalScrollBar()->setSingleStep(20);
00089     horizontalScrollBar()->setSingleStep(20);
00090 
00091     viewport()->setBackgroundRole(QPalette::Dark);
00092 
00093     doc = document;
00094     scale = 1.0;
00095     interPageSpacing = 30;
00096 }
00097 
00098 void PreviewView::zoomIn()
00099 {
00100     scale += 0.2;
00101     resizeEvent(0);
00102     viewport()->update();
00103 }
00104 
00105 void PreviewView::zoomOut()
00106 {
00107     scale -= 0.2;
00108     resizeEvent(0);
00109     viewport()->update();
00110 }
00111 
00112 void PreviewView::paintEvent(QPaintEvent *)
00113 {
00114     QPainter p(viewport());
00115 
00116     p.translate(-horizontalScrollBar()->value(), -verticalScrollBar()->value());
00117     p.translate(interPageSpacing, interPageSpacing);
00118 
00119     const int pages = doc->pageCount();
00120     for (int i = 0; i < pages; ++i) {
00121         p.save();
00122         p.scale(scale, scale);
00123 
00124         paintPage(&p, i);
00125 
00126         p.restore();
00127         p.translate(0, interPageSpacing + doc->pageSize().height() * scale);
00128     }
00129 }
00130 
00131 void PreviewView::paintPage(QPainter *painter, int page)
00132 {
00133     const QSizeF pgSize = doc->pageSize();
00134 
00135     QColor col(Qt::black);
00136 
00137     painter->setPen(col);
00138     painter->setBrush(Qt::white);
00139     painter->drawRect(QRectF(QPointF(0, 0), pgSize));
00140     painter->setBrush(Qt::NoBrush);
00141 
00142     col = col.light();
00143     painter->drawLine(QLineF(pgSize.width(), 1, pgSize.width(), pgSize.height() - 1));
00144 
00145     col = col.light();
00146     painter->drawLine(QLineF(pgSize.width(), 2, pgSize.width(), pgSize.height() - 2));
00147 
00148     QRectF docRect(QPointF(0, page * pgSize.height()), pgSize);
00149     QAbstractTextDocumentLayout::PaintContext ctx;
00150     ctx.clip = docRect;
00151 
00152     // don't use the system palette text as default text color, on HP/UX
00153     // for example that's white, and white text on white paper doesn't
00154     // look that nice
00155     ctx.palette.setColor(QPalette::Text, Qt::black);
00156 
00157     painter->translate(0, - page * pgSize.height());
00158     painter->setClipRect(docRect);
00159     doc->documentLayout()->draw(painter, ctx);
00160 }
00161 
00162 void PreviewView::resizeEvent(QResizeEvent *)
00163 {
00164     const QSize viewportSize = viewport()->size();
00165 
00166     QSize docSize;
00167     docSize.setWidth(qRound(doc->pageSize().width() * scale + 2 * interPageSpacing));
00168     const int pageCount = doc->pageCount();
00169     docSize.setHeight(qRound(pageCount * doc->pageSize().height() * scale + (pageCount + 1) * interPageSpacing));
00170 
00171     horizontalScrollBar()->setRange(0, docSize.width() - viewportSize.width());
00172     horizontalScrollBar()->setPageStep(viewportSize.width());
00173 
00174     verticalScrollBar()->setRange(0, docSize.height() - viewportSize.height());
00175     verticalScrollBar()->setPageStep(viewportSize.height());
00176 }
00177 
00178 void PreviewView::mousePressEvent(QMouseEvent *e)
00179 {
00180     mousePressPos = e->pos();
00181     scrollBarValuesOnMousePress.rx() = horizontalScrollBar()->value();
00182     scrollBarValuesOnMousePress.ry() = verticalScrollBar()->value();
00183     e->accept();
00184 }
00185 
00186 void PreviewView::mouseMoveEvent(QMouseEvent *e)
00187 {
00188     if (mousePressPos.isNull()) {
00189         e->ignore();
00190         return;
00191     }
00192 
00193     horizontalScrollBar()->setValue(scrollBarValuesOnMousePress.x() - e->pos().x() + mousePressPos.x());
00194     verticalScrollBar()->setValue(scrollBarValuesOnMousePress.y() - e->pos().y() + mousePressPos.y());
00195     horizontalScrollBar()->update();
00196     verticalScrollBar()->update();
00197     e->accept();
00198 }
00199 
00200 void PreviewView::mouseReleaseEvent(QMouseEvent *e)
00201 {
00202     mousePressPos = QPoint();
00203     e->accept();
00204 }
00205 
00206 PrintPreview::PrintPreview(const QTextDocument *document, QWidget *parent)
00207     : QMainWindow(parent), printer(QPrinter::HighResolution)
00208 {
00209     setWindowTitle(tr("TextEdit Demo - Print Preview"));
00210 
00211     printer.setFullPage(true);
00212     doc = document->clone();
00213 
00214     view = new PreviewView(doc);
00215     setCentralWidget(view);
00216     resize(800, 600);
00217 
00218     doc->setUseDesignMetrics(true);
00219     doc->documentLayout()->setPaintDevice(view->viewport());
00220 
00221     // add a nice 2 cm margin
00222     const qreal margin = inchesToPixels(mmToInches(20), this);
00223     QTextFrameFormat fmt = doc->rootFrame()->frameFormat();
00224     fmt.setMargin(margin);
00225     doc->rootFrame()->setFrameFormat(fmt);
00226 
00227     setup();
00228 
00229     QFont f(doc->defaultFont());
00230     f.setPointSize(10);
00231     doc->setDefaultFont(f);
00232 
00233     QToolBar *tb = addToolBar(tr("Print"));
00234     tb->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
00235 
00236     QAction *a;
00237     a = new QAction(/*QIcon(rsrcPath + "/fileprint.png"),*/ tr("&Print..."), this);
00238     a->setShortcut(Qt::CTRL + Qt::Key_P);
00239     connect(a, SIGNAL(triggered()), this, SLOT(print()));
00240     tb->addAction(a);
00241 
00242     a = new QAction(this);
00243     a->setText(tr("Page Setup..."));
00244     connect(a, SIGNAL(triggered()), this, SLOT(pageSetup()));
00245     tb->addAction(a);
00246 
00247     tb->addSeparator();
00248 
00249     a = new QAction(/*QIcon(rsrcPath + "/zoomin.png"),*/ tr("Zoom In"), this);
00250     connect(a, SIGNAL(triggered()), view, SLOT(zoomIn()));
00251     tb->addAction(a);
00252 
00253     a = new QAction(/*QIcon(rsrcPath + "/zoomout.png"),*/ tr("Zoom Out"), this);
00254     connect(a, SIGNAL(triggered()), view, SLOT(zoomOut()));
00255     tb->addAction(a);
00256 
00257     tb->addSeparator();
00258 
00259     a = new QAction(this);
00260     a->setText(tr("&Close"));
00261     connect(a, SIGNAL(triggered()), this, SLOT(close()));
00262     tb->addAction(a);
00263 
00264     statusBar()->setSizeGripEnabled(true);
00265 }
00266 
00267 void PrintPreview::setup()
00268 {
00269     QSizeF page = printer.pageRect().size();
00270     page.setWidth(page.width() * view->logicalDpiX() / printer.logicalDpiX());
00271     page.setHeight(page.height() * view->logicalDpiY() / printer.logicalDpiY());
00272 
00273     // add a nice 2 cm margin
00274     const qreal margin = inchesToPixels(mmToInches(20), this);
00275     QTextFrameFormat fmt = doc->rootFrame()->frameFormat();
00276     fmt.setMargin(margin);
00277     doc->rootFrame()->setFrameFormat(fmt);
00278 
00279     doc->setPageSize(page);
00280 }
00281 
00282 PrintPreview::~PrintPreview()
00283 {
00284     delete doc;
00285 }
00286 
00287 void PrintPreview::print()
00288 {
00289     QPrintDialog *dlg = new QPrintDialog(&printer, this);
00290     if (dlg->exec() == QDialog::Accepted) {
00291         doc->print(&printer);
00292     }
00293     delete dlg;
00294 }
00295 
00296 void PrintPreview::pageSetup()
00297 {
00298     QPageSetupDialog dlg(&printer, this);
00299     if (dlg.exec() == QDialog::Accepted) {
00300         setup();
00301         view->updateLayout();
00302     }
00303 }
00304 
00305 #include "printpreview.moc"

Generated on Mon Feb 2 00:25:34 2009 for mytetra by  doxygen 1.5.1