1 /* ============================================================
2  *
3  * This file is a part of digiKam project
4  * https://www.digikam.org
5  *
6  * Date        : 2003-11-03
7  * Description : a tool to create calendar.
8  *
9  * Copyright (C) 2003-2005 by Renchi Raju <renchi dot raju at gmail dot com>
10  * Copyright (C) 2006      by Tom Albers <tomalbers at kde dot nl>
11  * Copyright (C) 2007-2008 by Orgad Shaneh <orgads at gmail dot com>
12  * Copyright (C) 2011      by Andi Clemens <andi dot clemens at googlemail dot com>
13  * Copyright (C) 2012      by Angelo Naselli <anaselli at linux dot it>
14  * Copyright (C) 2012-2021 by Gilles Caulier <caulier dot gilles at gmail dot com>
15  *
16  * This program is free software; you can redistribute it
17  * and/or modify it under the terms of the GNU General
18  * Public License as published by the Free Software Foundation;
19  * either version 2, or (at your option) any later version.
20  *
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  * GNU General Public License for more details.
25  *
26  * ============================================================ */
27 
28 #include "calwizard.h"
29 
30 // Qt includes
31 
32 #include <QIcon>
33 #include <QDate>
34 #include <QPrintDialog>
35 #include <QPrinter>
36 #include <QStringList>
37 #include <QMenu>
38 #include <QLocale>
39 #include <QPushButton>
40 
41 // KDE includes
42 
43 #include <klocalizedstring.h>
44 
45 // Local includes
46 
47 #include "digikam_config.h"
48 #include "calintropage.h"
49 #include "calprinter.h"
50 #include "calsettings.h"
51 #include "calsystem.h"
52 #include "caltemplate.h"
53 #include "digikam_debug.h"
54 #include "ui_calevents.h"
55 #include "ui_calprogress.h"
56 
57 namespace DigikamGenericCalendarPlugin
58 {
59 
60 class Q_DECL_HIDDEN CalWizard::Private
61 {
62 public:
63 
Private()64     explicit Private()
65       : iface         (nullptr),
66         introPage     (nullptr),
67         cSettings     (nullptr),
68         wTemplate     (nullptr),
69         wPrintLabel   (nullptr),
70         wFinish       (nullptr),
71         wTemplatePage (nullptr),
72         wPrintPage    (nullptr),
73         wFinishPage   (nullptr),
74 
75 #ifdef HAVE_KCALENDAR
76 
77         wEvents       (nullptr),
78         wEventsPage   (nullptr),
79 
80 #endif
81 
82         printer       (nullptr),
83         printThread   (nullptr)
84     {
85     }
86 
87     DInfoInterface*  iface;
88     CalIntroPage*    introPage;
89     CalSettings*     cSettings;
90     CalTemplate*     wTemplate;
91     Ui::CalEvents    calEventsUI;
92     Ui::CalProgress  calProgressUI;
93 
94     QLabel*          wPrintLabel;
95     QWidget*         wFinish;
96 
97     DWizardPage*     wTemplatePage;
98     DWizardPage*     wPrintPage;
99     DWizardPage*     wFinishPage;
100 
101 #ifdef HAVE_KCALENDAR
102 
103     QWidget*         wEvents;
104     DWizardPage*     wEventsPage;
105 
106 #endif
107 
108     QPrinter*        printer;
109 
110     CalPrinter*      printThread;
111 
112     QMap<int, QUrl>  months;
113 };
114 
CalWizard(QWidget * const parent,DInfoInterface * const iface)115 CalWizard::CalWizard(QWidget* const parent, DInfoInterface* const iface)
116     : DWizardDlg(parent, QLatin1String("Calendar Dialog")),
117       d(new Private)
118 {
119     setWindowTitle(i18n("Create Calendar"));
120     d->iface         = iface;
121     d->cSettings     = CalSettings::instance(this);
122     d->introPage     = new CalIntroPage(this, i18n("Welcome to Calendar Tool"));
123 
124     // ---------------------------------------------------------------
125 
126     d->wTemplate     = new CalTemplate(d->iface->currentSelectedItems(), this);
127     d->wTemplatePage = new DWizardPage(this, i18n("Create Template for Calendar"));
128     d->wTemplatePage->setPageWidget(d->wTemplate);
129     d->wTemplatePage->setLeftBottomPix(QIcon::fromTheme(QLatin1String("resource-calendar-insert")));
130 
131     // ---------------------------------------------------------------
132 
133 #ifdef HAVE_KCALENDAR
134 
135     d->wEvents     = new QWidget(this);
136     d->calEventsUI.setupUi(d->wEvents);
137     d->wEventsPage = new DWizardPage(this, i18n("Choose events to show on the Calendar"));
138     d->wEventsPage->setPageWidget(d->wEvents);
139     d->wEventsPage->setLeftBottomPix(QIcon::fromTheme(QLatin1String("text-vcalendar")));
140 
141 #endif
142 
143     // ---------------------------------------------------------------
144 
145     d->wPrintLabel = new QLabel(this);
146     d->wPrintLabel->setIndent(20);
147     d->wPrintLabel->setWordWrap(true);
148     d->wPrintPage  = new DWizardPage(this, i18n("Print Calendar"));
149     d->wPrintPage->setPageWidget(d->wPrintLabel);
150     d->wPrintPage->setLeftBottomPix(QIcon::fromTheme(QLatin1String("document-print")));
151 
152     // ---------------------------------------------------------------
153 
154     d->wFinish     = new QWidget(this);
155     d->calProgressUI.setupUi(d->wFinish);
156     d->wFinishPage = new DWizardPage(this, i18n("Printing in Progress"));
157     d->wFinishPage->setPageWidget(d->wFinish);
158     d->wFinishPage->setLeftBottomPix(QIcon::fromTheme(QLatin1String("system-run")));
159 
160     // ---------------------------------------------------------------
161 
162 #ifdef HAVE_KCALENDAR
163 
164     d->calEventsUI.ohUrlRequester->setFileDlgFilter(i18nc("@info: open file filters", "Calendar Data File (*.ics)"));
165     d->calEventsUI.ohUrlRequester->setFileDlgTitle(i18n("Select Calendar Data File"));
166     d->calEventsUI.ohUrlRequester->setFileDlgMode(QFileDialog::ExistingFile);
167 
168     d->calEventsUI.fhUrlRequester->setFileDlgFilter(i18nc("@info: open file filters", "Calendar Data File (*.ics)"));
169     d->calEventsUI.fhUrlRequester->setFileDlgTitle(i18n("Select Calendar Data File"));
170     d->calEventsUI.fhUrlRequester->setFileDlgMode(QFileDialog::ExistingFile);
171 
172 #endif
173 
174     // ------------------------------------------
175 
176     d->printThread = nullptr;
177     d->printer     = nullptr;
178 
179     connect(this, SIGNAL(currentIdChanged(int)),
180             this, SLOT(slotPageSelected(int)));
181 }
182 
~CalWizard()183 CalWizard::~CalWizard()
184 {
185     if (d->printThread)
186     {
187         d->printThread->cancel();
188         d->printThread->wait();
189         delete d->printThread;
190     }
191 
192     delete d->printer;
193     delete d;
194 }
195 
iface() const196 DInfoInterface* CalWizard::iface() const
197 {
198     return d->iface;
199 }
200 
slotPageSelected(int curr)201 void CalWizard::slotPageSelected(int curr)
202 {
203     DWizardPage* const current = dynamic_cast<DWizardPage*>(page(curr));
204 
205     if (current == d->wPrintPage)
206     {
207         d->months.clear();
208         QUrl        image;
209         QString     month;
210         QStringList printList;
211         QDate       date = CalSystem().date(d->cSettings->year(), 1, 1);
212 
213         for (int i = 1 ; i <= CalSystem().monthsInYear(date) ; ++i)
214         {
215             month = QLocale().standaloneMonthName(i, QLocale::LongFormat);
216             image = d->cSettings->image(i);
217 
218             if (!image.isEmpty())
219             {
220                 d->months.insert(i, image);
221                 printList.append(month);
222             }
223         }
224 
225         if (d->months.isEmpty())
226         {
227             d->wPrintLabel->setText(QLatin1String("<qt>") +
228                                   i18n("No valid images selected for months<br/>"
229                                        "Click Back to select images") + QLatin1String("</qt>"));
230             d->wFinishPage->setComplete(false);
231         }
232         else
233         {
234             int year = d->cSettings->year();
235 
236             QString extra;
237 
238             if ((CalSystem().month(QDate::currentDate()) >= 6    &&
239                  CalSystem().year(QDate::currentDate()) == year) ||
240                  CalSystem().year(QDate::currentDate()) > year)
241             {
242                 extra = QLatin1String("<br/><br/><b>") +
243                         i18n("Please note that you are making a "
244                              "calendar for<br/>the current year or a year in the "
245                              "past.") + QLatin1String("</b>");
246             }
247 
248             QString year_locale = QLocale().toString(date, QLatin1String("yyyy"));
249 
250             d->wPrintLabel->setText(i18n("Click Next to start Printing<br/><br/>"
251                                        "Following months will be printed for year %1:<br/>", year_locale)
252                                     + printList.join(QLatin1String(" - ")) + extra);
253             d->wPrintLabel->setTextFormat(Qt::RichText);
254 
255             d->wFinishPage->setComplete(true);
256         }
257     }
258 
259     else if (current == d->wFinishPage)
260     {
261         d->calProgressUI.finishLabel->clear();
262         d->calProgressUI.currentProgress->reset();
263         d->calProgressUI.totalProgress->reset();
264 
265         button(QWizard::BackButton)->setEnabled(false);
266         button(QWizard::NextButton)->setEnabled(false);
267 
268         // Set printer settings ---------------------------------------
269 
270         if (!d->printer)
271         {
272             d->printer = new QPrinter(d->cSettings->resolution());
273         }
274 
275         CalParams& params = d->cSettings->params;
276 
277         // Orientation
278 
279         switch (params.imgPos)
280         {
281             case (CalParams::Top):
282                 d->printer->setOrientation(QPrinter::Portrait);
283                 break;
284 
285             default:
286                 d->printer->setOrientation(QPrinter::Landscape);
287                 break;
288         }
289 
290         qCDebug(DIGIKAM_DPLUGIN_GENERIC_LOG) << "printing...";
291 
292         // PageSize
293 
294         d->printer->setPageSize(QPageSize(params.pageSize));
295 
296         QPrintDialog* const printDialog = new QPrintDialog(d->printer, this);
297         printDialog->setWindowTitle(i18n("Print Calendar"));
298 
299         if (printDialog->exec() == QDialog::Accepted)
300         {
301             print();
302         }
303         else
304         {
305             d->calProgressUI.finishLabel->setText(i18n("Printing Cancelled"));
306             button(QWizard::BackButton)->setEnabled(true);
307         }
308 
309         delete printDialog;
310     }
311 }
312 
print()313 void CalWizard::print()
314 {
315     d->calProgressUI.totalProgress->setMaximum(d->months.count());
316     d->calProgressUI.totalProgress->setValue(0);
317     d->calProgressUI.totalProgress->progressScheduled(i18n("Create calendar"), false, true);
318     d->calProgressUI.totalProgress->progressThumbnailChanged(QIcon::fromTheme(QLatin1String("view-calendar")).pixmap(22, 22));
319 
320     if (d->printThread)
321     {
322         d->printThread->cancel();
323         d->printThread->wait();
324         delete d->printThread;
325     }
326 
327     d->cSettings->clearSpecial();
328 
329 #ifdef HAVE_KCALENDAR
330 
331     d->cSettings->loadSpecial(QUrl::fromLocalFile(d->calEventsUI.ohUrlRequester->lineEdit()->text()), Qt::red);
332     d->cSettings->loadSpecial(QUrl::fromLocalFile(d->calEventsUI.fhUrlRequester->lineEdit()->text()), Qt::darkGreen);
333 
334 #endif
335 
336     d->printThread = new CalPrinter(d->printer, d->months, this);
337 
338     connect(d->printThread, SIGNAL(pageChanged(int)),
339             this, SLOT(updatePage(int)));
340 
341     connect(d->printThread, SIGNAL(pageChanged(int)),
342             d->calProgressUI.totalProgress, SLOT(setValue(int)));
343 
344     connect(d->printThread, SIGNAL(totalBlocks(int)),
345             d->calProgressUI.currentProgress, SLOT(setMaximum(int)));
346 
347     connect(d->printThread, SIGNAL(blocksFinished(int)),
348             d->calProgressUI.currentProgress, SLOT(setValue(int)));
349 
350     d->calProgressUI.totalProgress->setMaximum(d->months.count());
351     d->printThread->start();
352 }
353 
updatePage(int page)354 void CalWizard::updatePage(int page)
355 {
356     const int year = d->cSettings->year();
357     QDate date(year, 1, 1);
358 
359     if (page >= d->months.count())
360     {
361         printComplete();
362         return;
363     }
364 
365     int month = d->months.keys().at(page);
366 
367     d->calProgressUI.finishLabel->setText(i18n("Printing calendar page for %1 of %2",
368                                           QLocale().standaloneMonthName(month, QLocale::LongFormat),
369                                           QLocale().toString(date, QLatin1String("yyyy"))));
370 }
371 
printComplete()372 void CalWizard::printComplete()
373 {
374     d->calProgressUI.totalProgress->progressCompleted();
375     button(QWizard::BackButton)->setEnabled(true);
376     button(QWizard::NextButton)->setEnabled(true);
377     d->calProgressUI.finishLabel->setText(i18n("Printing Complete"));
378 }
379 
380 } // Namespace Digikam
381