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 // clazy:excludeall=qstring-arg
21 #include "KoPrintingDialog.h"
22 #include "KoPrintingDialog_p.h"
23 #include "KoProgressUpdater.h"
24 
25 //#include <KoZoomHandler.h>
26 //#include <KoShapeManager.h>
27 //#include <KoShape.h>
28 #include <KoProgressBar.h>
29 
30 #include <QApplication>
31 #include <MainDebug.h>
32 #include <klocalizedstring.h>
33 #include <QPainter>
34 #include <QPrinter>
35 #include <QGridLayout>
36 #include <QLabel>
37 #include <QPushButton>
38 #include <QTimer>
39 #include <QDialog>
40 #include <QThread>
41 
42 class PrintDialog : public QDialog {
43 public:
PrintDialog(KoPrintingDialogPrivate * d,QWidget * parent)44     PrintDialog(KoPrintingDialogPrivate *d, QWidget *parent)
45         : QDialog(parent)
46     {
47         setModal(true);
48         QGridLayout *grid = new QGridLayout(this);
49         setLayout(grid);
50 
51         d->pageNumber = new QLabel(this);
52         d->pageNumber->setMinimumWidth(200);
53         grid->addWidget(d->pageNumber, 0, 0, 1, 2);
54         KoProgressBar *bar = new KoProgressBar(this);
55         d->progress = new KoProgressUpdater(bar);
56         grid->addWidget(bar, 1, 0, 1, 2);
57         d->button = new QPushButton(i18n("Stop"), this);
58         grid->addWidget(d->button, 2, 1);
59         grid->setColumnStretch(0, 1);
60     }
61 };
62 
63 
KoPrintingDialog(QWidget * parent,QPrinter::PrinterMode mode)64 KoPrintingDialog::KoPrintingDialog(QWidget *parent, QPrinter::PrinterMode mode)
65     : KoPrintJob(parent),
66       d(new KoPrintingDialogPrivate(this, mode))
67 {
68     d->dialog = new PrintDialog(d, parent);
69 
70     connect(d->button, SIGNAL(released()), this, SLOT(stopPressed())); // clazy:exclude=old-style-connect
71 }
72 
~KoPrintingDialog()73 KoPrintingDialog::~KoPrintingDialog()
74 {
75     d->stopPressed();
76     delete d;
77 }
78 
79 /*
80 void KoPrintingDialog::setShapeManager(KoShapeManager *sm)
81 {
82     d->shapeManager = sm;
83 }
84 
85 KoShapeManager *KoPrintingDialog::shapeManager() const
86 {
87     return d->shapeManager;
88 }
89 */
setPageRange(const QList<int> & pages)90 void KoPrintingDialog::setPageRange(const QList<int> &pages)
91 {
92     if (d->index == 0) // can't change after we started
93         d->pageRange = pages;
94 }
95 
painter() const96 QPainter & KoPrintingDialog::painter() const
97 {
98     if (d->painter == 0) {
99         d->painter = new QPainter(d->printer);
100         d->painter->save(); // state before page preparation (3)
101     }
102     return *d->painter;
103 }
104 
isStopped() const105 bool KoPrintingDialog::isStopped() const
106 {
107     return d->stop;
108 }
109 
110 // Define a printer friendly palette
111 #define VeryLightGray   "#f8f8f8"
112 #define LightLightGray  "#f0f0f0"
113 #define DarkDarkGray    "#b3b3b3"
114 #define VeryDarkGray    "#838383"
115 class PrintPalette {
116 public:
PrintPalette()117     PrintPalette() {
118         orig = QApplication::palette();
119         QPalette palette = orig;
120         // define a palette that works when printing on white paper
121         palette.setColor(QPalette::Window, Qt::white);
122         palette.setColor(QPalette::WindowText, Qt::black);
123         palette.setColor(QPalette::Base, Qt::white);
124         palette.setColor(QPalette::AlternateBase, VeryLightGray);
125         palette.setColor(QPalette::ToolTipBase, Qt::white);
126         palette.setColor(QPalette::ToolTipText, Qt::black);
127         palette.setColor(QPalette::Text, Qt::black);
128         palette.setColor(QPalette::Button, Qt::lightGray);
129         palette.setColor(QPalette::ButtonText, Qt::black);
130         palette.setColor(QPalette::BrightText, Qt::white);
131         palette.setColor(QPalette::Link, Qt::blue);
132         palette.setColor(QPalette::Highlight, Qt::blue);
133         palette.setColor(QPalette::HighlightedText, Qt::white);
134         palette.setColor(QPalette::Light, QColor(VeryLightGray));
135         palette.setColor(QPalette::Midlight, QColor(LightLightGray)); // used for freeDays in gantt chart
136         palette.setColor(QPalette::Dark, QColor(DarkDarkGray));
137         palette.setColor(QPalette::Mid, QColor(VeryDarkGray));
138         palette.setColor(QPalette::Shadow, Qt::black);
139         QApplication::setPalette(palette);
140     }
~PrintPalette()141     ~PrintPalette() {
142         QApplication::setPalette(orig);
143     }
144     QPalette orig;
145 };
146 
147 
startPrinting(RemovePolicy removePolicy)148 void KoPrintingDialog::startPrinting(RemovePolicy removePolicy)
149 {
150     d->removePolicy = removePolicy;
151     d->pages = d->pageRange;
152     if (d->pages.isEmpty()) { // auto-fill from min/max
153         switch (d->printer->printRange()) {
154         case QPrinter::AllPages:
155             for (int i=documentFirstPage(); i <= documentLastPage(); i++)
156                 d->pages.append(i);
157             break;
158         case QPrinter::PageRange:
159             for (int i=d->printer->fromPage(); i <= d->printer->toPage(); i++)
160                 d->pages.append(i);
161             break;
162         case QPrinter::CurrentPage:
163             d->pages.append(documentCurrentPage());
164             break;
165         default:
166             return;
167         }
168     }
169     if (d->pages.isEmpty()) {
170         qWarning(/*30004*/) << "KoPrintingDialog::startPrinting: No pages to print, did you forget to call setPageRange()?";
171         return;
172     }
173 
174     const bool blocking = property("blocking").toBool();
175     const bool noprogressdialog = property("noprogressdialog").toBool();
176     if (d->index == 0 && d->pages.count() > 0 && d->printer) {
177         if (!blocking && !noprogressdialog)
178             d->dialog->show();
179         d->stop = false;
180         delete d->painter;
181         d->painter = 0;
182 //        d->zoomer.setZoom(1.0);
183 //        d->zoomer.setDpi(d->printer->resolution(), d->printer->resolution());
184 
185         if (blocking) {
186             QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
187         }
188         d->progress->start(100, i18n("Printing"));
189 
190         if (d->printer->numCopies() > 1) {
191             QList<int> oldPages = d->pages;
192             if (d->printer->collateCopies()) { // means we print whole doc at once
193                 for (int count = 1; count < d->printer->numCopies(); ++count)
194                     d->pages.append(oldPages);
195             } else {
196                 d->pages.clear();
197                 foreach (int page, oldPages) {
198                     for (int count = 1; count < d->printer->numCopies(); ++count)
199                         d->pages.append(page);
200                 }
201             }
202         }
203         if (d->printer->pageOrder() == QPrinter::LastPageFirst) {
204             const QList<int> pages = d->pages;
205             d->pages.clear();
206             QList<int>::ConstIterator iter = pages.end();
207             do {
208                 --iter;
209                 d->pages << *iter;
210             } while (iter != pages.begin());
211         }
212 
213         PrintPalette p;
214 
215         d->resetValues();
216         foreach (int page, d->pages) {
217             d->index++;
218             d->updaters.append(d->progress->startSubtask()); // one per page
219             d->preparePage(page);
220             d->printPage(page);
221             if (!blocking) {
222                 qApp->processEvents();
223             }
224 
225         }
226         d->painter->end();
227         if (blocking) {
228             printingDone();
229         }
230         else {
231             d->printingDone();
232         }
233         d->stop = true;
234         d->resetValues();
235         if (blocking) {
236             QGuiApplication::restoreOverrideCursor();
237         }
238     }
239 }
240 
printer()241 QPrinter &KoPrintingDialog::printer()
242 {
243     return *d->printer;
244 }
245 
printPage(int,QPainter &)246 void KoPrintingDialog::printPage(int, QPainter &)
247 {
248 }
249 
preparePage(int)250 QRectF KoPrintingDialog::preparePage(int)
251 {
252     return QRectF();
253 }
254 
255 // have to include this because of Q_PRIVATE_SLOT
256 #include <moc_KoPrintingDialog.cpp>
257