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