1 /* This file is part of the KDE project
2  * Copyright (C) 2007, 2009 Thomas Zander <zander@kde.org>
3  * Copyright (C) 2011 Boudewijn Rempt <boud@kde.org>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB.  If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20 #ifndef KoPrintingDialog_p_h
21 #define KoPrintingDialog_p_h
22 
23 #include "KoPrintingDialog.h"
24 #include "KoProgressUpdater.h"
25 
26 #include <KoZoomHandler.h>
27 #include <KoShapeManager.h>
28 #include <KoShape.h>
29 #include <KoUpdater.h>
30 
31 #include <QCoreApplication>
32 #include <MainDebug.h>
33 #include <klocalizedstring.h>
34 #include <QPainter>
35 #include <QPrinter>
36 #include <QGridLayout>
37 #include <QLabel>
38 #include <QPushButton>
39 #include <QTimer>
40 #include <QDialog>
41 #include <QThread>
42 
43 
44 class KoPrintingDialogPrivate {
45 public:
KoPrintingDialogPrivate(KoPrintingDialog * dia)46     explicit KoPrintingDialogPrivate(KoPrintingDialog *dia)
47         : parent(dia),
48           stop(true),
49           shapeManager(0),
50           painter(0),
51           printer(new QPrinter()),
52           index(0),
53           progress(0),
54           dialog(0),
55           removePolicy(KoPrintJob::DoNotDelete)
56     {
57     }
58 
~KoPrintingDialogPrivate()59     ~KoPrintingDialogPrivate() {
60         stop = true;
61         delete progress;
62         if (painter && painter->isActive()) {
63             painter->end();
64         }
65 
66         updaters.clear();
67 
68         delete printer;
69         delete dialog;
70     }
71 
preparePage(const QVariant & page)72     void preparePage(const QVariant &page) {
73         const int pageNumber = page.toInt();
74 
75         QPointer<KoUpdater> updater = updaters.at(index - 1);
76 
77         if (painter) {
78             painter->save(); // state before page preparation
79         }
80 
81         QRectF clipRect;
82 
83         if (! stop) {
84             clipRect = parent->preparePage(pageNumber);
85         }
86 
87         updater->setProgress(45);
88 
89         if (!painter) {
90             // force the painter to be created *after* the preparePage since the page
91             // size may have been updated there and that doesn't work with the first page
92             painter = new QPainter(printer);
93             painter->save(); // state before page preparation (2)
94         }
95         if (index > 1)
96             printer->newPage();
97         if (clipRect.isValid()) // make sure the clipRect is done *after* the newPage. Required for printPreview
98             painter->setClipRect(clipRect);
99         updater->setProgress(55);
100         painter->save(); // state after page preparation
101 
102         QList<KoShape*> shapes = parent->shapesOnPage(pageNumber);
103         if (shapes.isEmpty()) {
104             debugMain << "Printing page" << pageNumber << "I notice there are no shapes on this page";
105         } else {
106             const int progressPart = 45 / shapes.count();
107             foreach(KoShape *shape, shapes) {
108                 debugMain << "Calling waitUntilReady on shape;" << shape;
109                 if(! stop)
110                     shape->waitUntilReady(zoomer);
111                 debugMain << "done";
112                 updater->setProgress(updater->progress() + progressPart);
113             }
114         }
115         updater->setProgress(100);
116     }
117 
resetValues()118     void resetValues() {
119         index = 0;
120         updaters.clear();
121         if (painter && painter->isActive())
122             painter->end();
123         delete painter;
124         painter = 0;
125         stop = false;
126     }
127 
printPage(const QVariant & page)128     void printPage(const QVariant &page) {
129         painter->restore(); // state after page preparation
130         painter->save();
131         parent->printPage(page.toInt(), *painter);
132         painter->restore();
133         if (!stop && shapeManager) {
134             shapeManager->paint(*painter, zoomer, true);
135         }
136         painter->restore(); // state before page preparation
137 
138         if (parent->property("blocking").toBool()) {
139             return;
140         }
141     }
142 
printingDone()143     void printingDone() {
144 
145         // printing done!
146         painter->end();
147         progress->cancel();
148         parent->printingDone();
149         pageNumber->setText(i18n("Printing done"));
150         button->setText(i18n("Close"));
151         stop = true;
152         QTimer::singleShot(1200, dialog, SLOT(accept()));
153         if (removePolicy == KoPrintJob::DeleteWhenDone) {
154             parent->deleteLater();
155         }
156         else {
157             resetValues();
158         }
159 
160     }
161 
stopPressed()162     void stopPressed() {
163         if (stop) { // pressed a second time.
164             dialog->done(0);
165             return;
166         }
167         stop = true;
168         progress->cancel();
169         parent->printingDone();
170         pageNumber->setText(i18n("Stopped"));
171         QTimer::singleShot(1200, dialog, SLOT(accept()));
172         if (removePolicy == KoPrintJob::DeleteWhenDone)
173             parent->deleteLater();
174         else
175             resetValues();
176     }
177 
178     KoPrintingDialog *parent;
179     KoZoomHandler zoomer;
180 
181     volatile bool stop;
182     KoShapeManager *shapeManager;
183     QPainter *painter;
184     QPrinter *printer;
185     int index; // index in the pages list.
186     KoProgressUpdater *progress;
187     QLabel *pageNumber;
188     QPushButton *button;
189     QList<int> pageRange; ///< user requested list of pages
190     QList<int> pages; ///< effective list of pages
191     QList< QPointer<KoUpdater> > updaters;
192     QDialog *dialog;
193     KoPrintJob::RemovePolicy removePolicy;
194 };
195 
196 #endif
197