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 #include "KoPrintingDialog.h"
21 #include "KoPrintingDialog_p.h"
22 #include "KoProgressUpdater.h"
23
24 #include <KoZoomHandler.h>
25 #include <KoShapeManager.h>
26 #include <KoShape.h>
27 #include <KoProgressBar.h>
28
29 #include <QCoreApplication>
30 #include <MainDebug.h>
31 #include <klocalizedstring.h>
32 #include <QPainter>
33 #include <QPrinter>
34 #include <QGridLayout>
35 #include <QLabel>
36 #include <QPushButton>
37 #include <QTimer>
38 #include <QDialog>
39 #include <QThread>
40
41 class PrintDialog : public QDialog {
42 public:
PrintDialog(KoPrintingDialogPrivate * d,QWidget * parent)43 PrintDialog(KoPrintingDialogPrivate *d, QWidget *parent)
44 : QDialog(parent)
45 {
46 setModal(true);
47 QGridLayout *grid = new QGridLayout(this);
48 setLayout(grid);
49
50 d->pageNumber = new QLabel(this);
51 d->pageNumber->setMinimumWidth(200);
52 grid->addWidget(d->pageNumber, 0, 0, 1, 2);
53 KoProgressBar *bar = new KoProgressBar(this);
54 d->progress = new KoProgressUpdater(bar);
55 grid->addWidget(bar, 1, 0, 1, 2);
56 d->button = new QPushButton(i18n("Stop"), this);
57 grid->addWidget(d->button, 2, 1);
58 grid->setColumnStretch(0, 1);
59 }
60 };
61
62
KoPrintingDialog(QWidget * parent)63 KoPrintingDialog::KoPrintingDialog(QWidget *parent)
64 : KoPrintJob(parent),
65 d(new KoPrintingDialogPrivate(this))
66 {
67 d->dialog = new PrintDialog(d, parent);
68
69 connect(d->button, SIGNAL(released()), this, SLOT(stopPressed()));
70 }
71
~KoPrintingDialog()72 KoPrintingDialog::~KoPrintingDialog()
73 {
74 d->stopPressed();
75 delete d;
76 }
77
setShapeManager(KoShapeManager * sm)78 void KoPrintingDialog::setShapeManager(KoShapeManager *sm)
79 {
80 d->shapeManager = sm;
81 }
82
shapeManager() const83 KoShapeManager *KoPrintingDialog::shapeManager() const
84 {
85 return d->shapeManager;
86 }
87
setPageRange(const QList<int> & pages)88 void KoPrintingDialog::setPageRange(const QList<int> &pages)
89 {
90 if (d->index == 0) // can't change after we started
91 d->pageRange = pages;
92 }
93
painter() const94 QPainter & KoPrintingDialog::painter() const
95 {
96 if (d->painter == 0) {
97 d->painter = new QPainter(d->printer);
98 d->painter->save(); // state before page preparation (3)
99 }
100 return *d->painter;
101 }
102
isStopped() const103 bool KoPrintingDialog::isStopped() const
104 {
105 return d->stop;
106 }
107
startPrinting(RemovePolicy removePolicy)108 void KoPrintingDialog::startPrinting(RemovePolicy removePolicy)
109 {
110 d->removePolicy = removePolicy;
111 d->pages = d->pageRange;
112 if (d->pages.isEmpty()) { // auto-fill from min/max
113 switch (d->printer->printRange()) {
114 case QPrinter::AllPages:
115 for (int i=documentFirstPage(); i <= documentLastPage(); i++)
116 d->pages.append(i);
117 break;
118 case QPrinter::PageRange:
119 for (int i=d->printer->fromPage(); i <= d->printer->toPage(); i++)
120 d->pages.append(i);
121 break;
122 case QPrinter::CurrentPage:
123 d->pages.append(documentCurrentPage());
124 break;
125 default:
126 return;
127 }
128 }
129 if (d->pages.isEmpty()) {
130 qWarning(/*30004*/) << "KoPrintingDialog::startPrinting: No pages to print, did you forget to call setPageRange()?";
131 return;
132 }
133
134 const bool blocking = property("blocking").toBool();
135 const bool noprogressdialog = property("noprogressdialog").toBool();
136 if (d->index == 0 && d->pages.count() > 0 && d->printer) {
137 if (!blocking && !noprogressdialog)
138 d->dialog->show();
139 d->stop = false;
140 delete d->painter;
141 d->painter = 0;
142 d->zoomer.setZoom( 1.0 );
143 d->zoomer.setDpi( d->printer->resolution(), d->printer->resolution() );
144
145 d->progress->start(100, i18n("Printing"));
146
147 if (d->printer->numCopies() > 1) {
148 QList<int> oldPages = d->pages;
149 if (d->printer->collateCopies()) { // means we print whole doc at once
150 for (int count = 1; count < d->printer->numCopies(); ++count)
151 d->pages.append(oldPages);
152 } else {
153 d->pages.clear();
154 foreach (int page, oldPages) {
155 for (int count = 1; count < d->printer->numCopies(); ++count)
156 d->pages.append(page);
157 }
158 }
159 }
160 if (d->printer->pageOrder() == QPrinter::LastPageFirst) {
161 const QList<int> pages = d->pages;
162 d->pages.clear();
163 QList<int>::ConstIterator iter = pages.end();
164 do {
165 --iter;
166 d->pages << *iter;
167 } while (iter != pages.begin());
168 }
169
170
171 d->resetValues();
172 foreach (int page, d->pages) {
173 d->index++;
174 d->updaters.append(d->progress->startSubtask()); // one per page
175 d->preparePage(page);
176 d->printPage(page);
177 if (!blocking) {
178 qApp->processEvents();
179 }
180
181 }
182 d->painter->end();
183 if (blocking) {
184 printingDone();
185 }
186 else {
187 d->printingDone();
188 }
189 d->stop = true;
190 d->resetValues();
191 }
192 }
193
printer()194 QPrinter &KoPrintingDialog::printer()
195 {
196 return *d->printer;
197 }
198
printPage(int,QPainter &)199 void KoPrintingDialog::printPage(int, QPainter &)
200 {
201 }
202
preparePage(int)203 QRectF KoPrintingDialog::preparePage(int)
204 {
205 return QRectF();
206 }
207
208 // have to include this because of Q_PRIVATE_SLOT
209 #include <moc_KoPrintingDialog.cpp>
210