1 /* ============================================================
2 *
3 * This file is a part of KDE project
4 *
5 *
6 * Date : 2008-01-11
7 * Description : a kipi plugin to print images
8 *
9 * Copyright 2008-2012 by Angelo Naselli <anaselli at linux dot it>
10 *
11 * This program is free software; you can redistribute it
12 * and/or modify it under the terms of the GNU General
13 * Public License as published by the Free Software Foundation;
14 * either version 2, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * ============================================================ */
22
23 #include "wizard.h"
24
25 // C++ includes
26
27 #include <memory>
28
29 // Qt includes
30
31 #include <QFileInfo>
32 #include <QFileDialog>
33 #include <QPainter>
34 #include <QPalette>
35 #include <QtGlobal>
36 #include <QPrinter>
37 #include <QPrintDialog>
38 #include <QPageSetupDialog>
39 #include <QPrinterInfo>
40 #include <QProgressDialog>
41 #include <QDomDocument>
42 #include <QContextMenuEvent>
43 #include <QXmlStreamWriter>
44 #include <QXmlStreamAttributes>
45 #include <QStringRef>
46 #include <QStandardPaths>
47 #include <QMenu>
48 #include <QIcon>
49 #include <QLocale>
50 #include <QMessageBox>
51
52 // KDE includes
53
54 #include <kconfigdialogmanager.h>
55 #include <kconfig.h>
56 #include <kconfiggroup.h>
57 #include <kdesktopfile.h>
58 #include <klocalizedstring.h>
59
60 // Libkipi includes
61
62 #include <KIPI/ImageCollectionSelector>
63 #include <KIPI/Interface>
64
65 // Local includes
66
67 #include "kpwizardpage.h"
68 #include "kpimageslist.h"
69 #include "kpimageinfo.h"
70 #include "kpaboutdata.h"
71 #include "tphoto.h"
72 #include "utils.h"
73 #include "templateicon.h"
74 #include "customdlg.h"
75 #include "ui_croppage.h"
76 #include "ui_photopage.h"
77 #include "kipiplugins_debug.h"
78
79 namespace KIPIPrintImagesPlugin
80 {
81
82 template <class Ui_Class>
83
84 class WizardUI : public QWidget, public Ui_Class
85 {
86 public:
87
WizardUI(QWidget * const parent)88 WizardUI(QWidget* const parent)
89 : QWidget(parent)
90 {
91 this->setupUi(this);
92 layout()->setContentsMargins(QMargins());
93 }
94 };
95
96 typedef WizardUI<Ui_PhotoPage> PhotoUI;
97 typedef WizardUI<Ui_CropPage> CropUI;
98
99 class WizardPage : public KPWizardPage
100 {
101 public:
102
WizardPage(KPWizardDialog * const dialog,const QString & title,QWidget * const ui)103 WizardPage(KPWizardDialog* const dialog, const QString& title, QWidget* const ui)
104 : KPWizardPage(dialog, title)
105 {
106 setPageWidget(ui);
107 setShowLeftView(false);
108 }
109 };
110
111 typedef WizardPage PhotoPage;
112 typedef WizardPage CropPage;
113
114 // ---------------------------------------------------------------------------
115
116 // some title name definitions (managed by translators)
117 const char* photoPageName = I18N_NOOP("Select page layout");
118 const char* cropPageName = I18N_NOOP("Crop photos");
119 // custom page layout
120 const char* customPageLayoutName = I18N_NOOP("Custom");
121
122 // Wizard implementation
123 struct Wizard::Private
124 {
125 PhotoPage* m_photoPage;
126 CropPage* m_cropPage;
127
128 PhotoUI* m_photoUi;
129 CropUI* m_cropUi;
130
131 ImageCollectionSelector* m_collectionSelector;
132
133 // Page Size in mm
134 QSizeF m_pageSize;
135 QList<TPhoto*> m_photos;
136 QList<TPhotoSize*> m_photoSizes;
137 int m_infopageCurrentPhoto;
138 int m_currentPreviewPage;
139 int m_currentCropPhoto;
140 bool m_cancelPrinting;
141 QString m_tempPath;
142 QStringList m_gimpFiles;
143 QString m_savedPhotoSize;
144
145 //QPrintDialog* m_printDialog;
146 QPageSetupDialog* m_pDlg;
147 QPrinter* m_printer;
148 QList<QPrinterInfo> m_printerList;
149 KPImagesList* m_imagesFilesListBox;
150 };
151
Wizard(QWidget * const parent)152 Wizard::Wizard(QWidget* const parent)
153 : KPWizardDialog(parent),
154 d(new Private)
155 {
156 //d->m_printDialog = 0;
157 d->m_pDlg = nullptr;
158 d->m_printer = nullptr;
159 d->m_infopageCurrentPhoto = 0;
160
161 // Caption
162 setWindowTitle(i18n("Print assistant"));
163
164 // About data
165 KPAboutData* const about = new KPAboutData(ki18n("Print assistant"),
166 ki18n("A tool to print images"),
167 ki18n("(c) 2003-2004, Todd Shoemaker\n"
168 "(c) 2007-2013, Angelo Naselli"));
169
170 about->addAuthor(ki18n("Todd Shoemaker").toString(),
171 ki18n("Author").toString(),
172 QLatin1String("todd@theshoemakers.net"));
173
174 about->addAuthor(ki18n("Angelo Naselli").toString(),
175 ki18n("Developer").toString(),
176 QLatin1String("anaselli@linux.it"));
177
178 about->addAuthor(ki18n("Andreas Trink").toString(),
179 ki18n("Contributor").toString(),
180 QLatin1String("atrink@nociaro.org"));
181
182 about->setHandbookEntry(QLatin1String("tool-printwizard"));
183 setAboutData(about);
184
185 d->m_photoUi = new PhotoUI(this);
186 d->m_photoPage = new PhotoPage(this, i18n(photoPageName), d->m_photoUi);
187
188 d->m_cropUi = new CropUI(this);
189 d->m_cropPage = new CropPage(this, i18n(cropPageName), d->m_cropUi) ;
190
191 //TODO
192 d->m_pageSize = QSizeF(-1, -1); // select a different page to force a refresh in initPhotoSizes.
193
194 QList<QPrinterInfo>::iterator it;
195 d->m_printerList = QPrinterInfo::availablePrinters();
196 qCDebug(KIPIPLUGINS_LOG) << " printers: " << d->m_printerList.count();
197 //d->m_photoPage->m_printer_choice->setInsertPolicy(QComboBox::InsertAtTop/*QComboBox::InsertAlphabetically*/);
198
199 for (it = d->m_printerList.begin(); it != d->m_printerList.end(); ++it)
200 {
201 qCDebug(KIPIPLUGINS_LOG) << " printer: " << it->printerName();
202 d->m_photoUi->m_printer_choice->addItem(it->printerName());
203 }
204
205 // selected page
206 connect(this, SIGNAL(currentIdChanged(int)),
207 this, SLOT(pageChanged(int)));
208
209 // cancel button
210 connect(button(QWizard::CancelButton), SIGNAL(clicked()),
211 this, SLOT(reject()));
212
213 // caption information
214 connect(d->m_photoUi->m_captions, SIGNAL(activated(QString)),
215 this, SLOT(captionChanged(QString)));
216
217 connect(d->m_photoUi->m_FreeCaptionFormat , SIGNAL(editingFinished()),
218 this, SLOT(infopage_updateCaptions()));
219
220 connect(d->m_photoUi->m_sameCaption , SIGNAL(stateChanged(int)),
221 this, SLOT(infopage_updateCaptions()));
222
223 connect(d->m_photoUi->m_font_name , SIGNAL(currentFontChanged(QFont)),
224 this, SLOT(infopage_updateCaptions()));
225
226 connect(d->m_photoUi->m_font_size , SIGNAL(valueChanged(int)),
227 this, SLOT(infopage_updateCaptions()));
228
229 connect(d->m_photoUi->m_font_color , SIGNAL(signalColorSelected(QColor)),
230 this, SLOT(infopage_updateCaptions()));
231
232 connect(d->m_photoUi->m_setDefault , SIGNAL(clicked()),
233 this, SLOT(saveCaptionSettings()));
234
235 // printer
236 connect(d->m_photoUi->m_printer_choice, SIGNAL(activated(QString)),
237 this, SLOT(outputChanged(QString)));
238
239 connect(d->m_photoUi->BtnPreviewPageUp, SIGNAL(clicked()),
240 this, SLOT(BtnPreviewPageUp_clicked()));
241
242 connect(d->m_photoUi->BtnPreviewPageDown, SIGNAL(clicked()),
243 this, SLOT(BtnPreviewPageDown_clicked()));
244
245 connect(d->m_photoUi->ListPhotoSizes, SIGNAL(currentRowChanged(int)),
246 this, SLOT(ListPhotoSizes_selected()));
247
248 connect(d->m_cropUi->BtnCropPrev, SIGNAL(clicked()),
249 this, SLOT(BtnCropPrev_clicked()));
250
251 connect(d->m_cropUi->BtnCropNext, SIGNAL(clicked()),
252 this, SLOT(BtnCropNext_clicked()));
253
254 connect(d->m_cropUi->BtnCropRotateRight, SIGNAL(clicked()),
255 this, SLOT(BtnCropRotateRight_clicked()));
256
257 connect(d->m_cropUi->BtnCropRotateLeft, SIGNAL(clicked()),
258 this, SLOT(BtnCropRotateLeft_clicked()));
259
260 // don't crop
261 connect(d->m_cropUi->m_disableCrop, SIGNAL(stateChanged(int)),
262 this, SLOT(crop_selection(int)));
263
264 // remove a page
265 connect(this, SIGNAL(pageRemoved(int)),
266 this, SLOT(slotPageRemoved(int)));
267
268 connect(d->m_photoUi->m_pagesetup, SIGNAL(clicked()),
269 this, SLOT(pagesetupclicked()));
270
271 // save JPG as
272 connect ( d->m_cropUi->BtnSaveAs, SIGNAL (clicked()),
273 this, SLOT (BtnSaveAs_clicked()) );
274
275
276 if (d->m_photoUi->mPrintList->layout())
277 {
278 delete d->m_photoUi->mPrintList->layout();
279 }
280
281 QVBoxLayout* printListLayout = new QVBoxLayout;
282 printListLayout->setContentsMargins(QMargins());
283 printListLayout->setSpacing(0);
284
285 d->m_imagesFilesListBox = new KPImagesList(d->m_photoUi->mPrintList, 32);
286 d->m_imagesFilesListBox->setAllowDuplicate(true);
287 d->m_imagesFilesListBox->setControlButtons(KPImagesList::Add |
288 KPImagesList::Remove |
289 KPImagesList::MoveUp |
290 KPImagesList::MoveDown |
291 KPImagesList::Clear |
292 KPImagesList::Save |
293 KPImagesList::Load);
294 d->m_imagesFilesListBox->setControlButtonsPlacement(KPImagesList::ControlButtonsAbove);
295 d->m_imagesFilesListBox->enableDragAndDrop(false);
296
297 d->m_cropUi->BtnCropRotateRight->setIcon(QIcon::fromTheme(QLatin1String("object-rotate-right")).pixmap(16, 16));
298 d->m_cropUi->BtnCropRotateLeft->setIcon(QIcon::fromTheme(QLatin1String("object-rotate-left")).pixmap(16, 16));
299
300 printListLayout->addWidget(d->m_imagesFilesListBox);
301 d->m_photoUi->mPrintList->setLayout(printListLayout);
302
303 d->m_photoUi->BmpFirstPagePreview->setAlignment(Qt::AlignHCenter);
304
305 connect(d->m_imagesFilesListBox, SIGNAL(signalMoveDownItem()),
306 this, SLOT(BtnPrintOrderDown_clicked()));
307
308 connect(d->m_imagesFilesListBox, SIGNAL(signalMoveUpItem()),
309 this, SLOT(BtnPrintOrderUp_clicked()));
310
311 connect(d->m_imagesFilesListBox, SIGNAL(signalAddItems(QList<QUrl>)),
312 this, SLOT(slotAddItems(QList<QUrl>)));
313
314 connect(d->m_imagesFilesListBox, SIGNAL(signalRemovingItem(KIPIPlugins::KPImagesListViewItem*)),
315 this, SLOT(slotRemovingItem(KIPIPlugins::KPImagesListViewItem*)));
316
317 connect(d->m_imagesFilesListBox, SIGNAL(signalItemClicked(QTreeWidgetItem*)),
318 this, SLOT(imageSelected(QTreeWidgetItem*)));
319
320 connect(d->m_imagesFilesListBox, SIGNAL(signalContextMenuRequested()),
321 this, SLOT(slotContextMenuRequested()));
322
323 // Save item list => we catch the signal to add our PA attributes and elements Image children
324 connect(d->m_imagesFilesListBox, SIGNAL(signalXMLSaveItem(QXmlStreamWriter&,KIPIPlugins::KPImagesListViewItem*)),
325 this, SLOT(slotXMLSaveItem(QXmlStreamWriter&,KIPIPlugins::KPImagesListViewItem*)));
326
327 // Save item list => we catch the signal to add our PA elements (not per image)
328 connect(d->m_imagesFilesListBox, SIGNAL(signalXMLCustomElements(QXmlStreamWriter&)),
329 this, SLOT(slotXMLCustomElement(QXmlStreamWriter&)));
330
331 connect(d->m_imagesFilesListBox, SIGNAL(signalXMLLoadImageElement(QXmlStreamReader&)),
332 this, SLOT(slotXMLLoadElement(QXmlStreamReader&)));
333
334 connect(d->m_imagesFilesListBox, SIGNAL(signalXMLCustomElements(QXmlStreamReader&)),
335 this, SLOT(slotXMLCustomElement(QXmlStreamReader&)));
336
337 // To get rid of icons that sometime are not shown
338 d->m_photoUi->BtnPreviewPageUp->setIcon(QIcon::fromTheme(QLatin1String("go-next")).pixmap(16, 16));
339 d->m_photoUi->BtnPreviewPageDown->setIcon(QIcon::fromTheme(QLatin1String("go-previous")).pixmap(16, 16));
340
341 //arrow-up-double
342 d->m_currentPreviewPage = 0;
343 d->m_currentCropPhoto = 0;
344 d->m_cancelPrinting = false;
345 }
346
~Wizard()347 Wizard::~Wizard()
348 {
349 // TODO private object could be deleted inside private destructor
350 delete d->m_pDlg;
351 delete d->m_printer;
352
353 for (int i = 0; i < d->m_photos.count(); ++i)
354 delete d->m_photos.at(i);
355
356 d->m_photos.clear();
357 delete d;
358 }
359
360 // create a MxN grid of photos, fitting on the page
createPhotoGrid(TPhotoSize * p,int pageWidth,int pageHeight,int rows,int columns,TemplateIcon * iconpreview)361 void createPhotoGrid(TPhotoSize* p, int pageWidth, int pageHeight, int rows, int columns, TemplateIcon* iconpreview)
362 {
363 int MARGIN = (int)(((double)pageWidth + (double)pageHeight) / 2.0 * 0.04 + 0.5);
364 int GAP = MARGIN / 4;
365 int photoWidth = (pageWidth - (MARGIN * 2) - ((columns - 1) * GAP)) / columns;
366 int photoHeight = (pageHeight - (MARGIN * 2) - ((rows - 1) * GAP)) / rows;
367 int row = 0;
368
369 for (int y = MARGIN; row < rows && y < pageHeight - MARGIN; y += photoHeight + GAP)
370 {
371 int col = 0;
372
373 for (int x = MARGIN; col < columns && x < pageWidth - MARGIN; x += photoWidth + GAP)
374 {
375 p->layouts.append(new QRect(x, y, photoWidth, photoHeight));
376 iconpreview->fillRect(x, y, photoWidth, photoHeight, Qt::color1);
377 col++;
378 }
379
380 row++;
381 }
382 }
383
print(const QList<QUrl> & fileList,const QString & tempPath)384 void Wizard::print(const QList<QUrl>& fileList, const QString& tempPath)
385 {
386 for (int i = 0; i < d->m_photos.count(); ++i)
387 delete d->m_photos.at(i);
388
389 d->m_photos.clear();
390 //d->m_photoPage->m_PictureInfo->setRowCount(fileList.count());
391
392 for (int i = 0; i < fileList.count(); ++i)
393 {
394 TPhoto* const photo = new TPhoto(150);
395 photo->filename = fileList[i];
396 photo->first = true;
397 d->m_photos.append(photo);
398 }
399
400 d->m_tempPath = tempPath;
401 d->m_cropUi->BtnCropPrev->setEnabled(false);
402
403 if (d->m_photos.count() == 1)
404 d->m_cropUi->BtnCropNext->setEnabled(false);
405
406 emit currentIdChanged(d->m_photoPage->id());
407 }
408
parseTemplateFile(const QString & fn,const QSizeF & pageSize)409 void Wizard::parseTemplateFile(const QString& fn, const QSizeF& pageSize)
410 {
411 QDomDocument doc(QLatin1String("mydocument"));
412 qCDebug(KIPIPLUGINS_LOG) << " XXX: " << fn;
413
414 if (fn.isEmpty())
415 {
416 return;
417 }
418
419 QFile file(fn);
420
421 if (!file.open(QIODevice::ReadOnly))
422 return;
423
424 if (!doc.setContent(&file))
425 {
426 file.close();
427 return;
428 }
429
430 file.close();
431
432 TPhotoSize* p = nullptr;
433
434 // print out the element names of all elements that are direct children
435 // of the outermost element.
436 QDomElement docElem = doc.documentElement();
437 qCDebug(KIPIPLUGINS_LOG) << docElem.tagName(); // the node really is an element.
438
439 QSizeF size;
440 QString unit;
441 int scaleValue;
442 QDomNode n = docElem.firstChild();
443
444 while (!n.isNull())
445 {
446 size = QSizeF(0, 0);
447 scaleValue = 10; // 0.1 mm
448 QDomElement e = n.toElement(); // try to convert the node to an element.
449
450 if (!e.isNull())
451 {
452 if (e.tagName() == QLatin1String("paper"))
453 {
454 size = QSizeF(e.attribute(QLatin1String("width"), QLatin1String("0")).toFloat(),
455 e.attribute(QLatin1String("height"), QLatin1String("0")).toFloat());
456 unit = e.attribute(QLatin1String("unit"), QLatin1String("mm"));
457
458 qCDebug(KIPIPLUGINS_LOG) << e.tagName() << QLatin1String(" name=") << e.attribute(QLatin1String("name"), QLatin1String("??"))
459 << " size= " << size
460 << " unit= " << unit;
461
462 if (size == QSizeF(0.0, 0.0) && size == pageSize)
463 {
464 // skipping templates without page size since pageSize is not set
465 n = n.nextSibling();
466 continue;
467 }
468 else if (unit != QLatin1String("mm") && size != QSizeF(0.0, 0.0)) // "cm", "inches" or "inch"
469 {
470 // convert to mm
471 if (unit == QLatin1String("inches") || unit == QLatin1String("inch"))
472 {
473 size *= 25.4;
474 scaleValue = 1000;
475 qCDebug(KIPIPLUGINS_LOG) << "template size " << size << " page size " << pageSize;
476 }
477 else if (unit == QLatin1String("cm"))
478 {
479 size *= 10;
480 scaleValue = 100;
481 qCDebug(KIPIPLUGINS_LOG) << "template size " << size << " page size " << pageSize;
482 }
483 else
484 {
485 qCWarning(KIPIPLUGINS_LOG) << "Wrong unit " << unit << " skipping layout";
486 n = n.nextSibling();
487 continue;
488 }
489 }
490
491 static const float round_value = 0.01F;
492
493 if (size == QSizeF(0, 0))
494 {
495 size = pageSize;
496 unit = QLatin1String("mm");
497 }
498 else if (pageSize != QSizeF(0, 0) &&
499 (size.height() > (pageSize.height() + round_value) ||
500 size.width() > (pageSize.width() + round_value)))
501 {
502 qCDebug(KIPIPLUGINS_LOG) << "skipping size " << size << " page size " << pageSize;
503 // skipping layout it can't fit
504 n = n.nextSibling();
505 continue;
506 }
507
508 // Next templates are good
509 qCDebug(KIPIPLUGINS_LOG) << "layout size " << size << " page size " << pageSize;
510 QDomNode np = e.firstChild();
511
512 while (!np.isNull())
513 {
514 QDomElement ep = np.toElement(); // try to convert the node to an element.
515
516 if (!ep.isNull())
517 {
518 if (ep.tagName() == QLatin1String("template"))
519 {
520 p = new TPhotoSize;
521 QSizeF sizeManaged;
522
523 // set page size
524 if (pageSize == QSizeF(0, 0))
525 {
526 sizeManaged = size * scaleValue;
527 }
528 else if (unit == QLatin1String("inches") || unit == QLatin1String("inch"))
529 {
530 sizeManaged = pageSize * scaleValue / 25.4;
531 }
532 else
533 {
534 sizeManaged = pageSize * 10;
535 }
536
537 p->layouts.append(new QRect(0, 0, (int)sizeManaged.width(), (int)sizeManaged.height()));
538 // create a small preview of the template
539 // TODO check if iconsize here is useless
540 TemplateIcon iconpreview(80, sizeManaged.toSize());
541 iconpreview.begin();
542
543 QString desktopFileName = ep.attribute(QLatin1String("name"), QLatin1String("XXX")) +
544 QLatin1String(".desktop");
545
546 QDir dir(QStandardPaths::locate(QStandardPaths::GenericDataLocation,
547 QLatin1String("kipiplugin_printimages/templates"),
548 QStandardPaths::LocateDirectory));
549 const QStringList list = dir.entryList(QStringList() << desktopFileName);
550
551 qCDebug(KIPIPLUGINS_LOG) << "Template desktop files list: " << list;
552
553 QStringList::ConstIterator it = list.constBegin();
554 QStringList::ConstIterator end = list.constEnd();
555
556 if (it != end)
557 {
558 p->label = KDesktopFile(dir.absolutePath() + QLatin1String("/") + *it).readName();
559 }
560 else
561 {
562 p->label = ep.attribute(QLatin1String("name"), QLatin1String("XXX"));
563 qCWarning(KIPIPLUGINS_LOG) << "missed template translation " << desktopFileName;
564 }
565
566 p->dpi = ep.attribute(QLatin1String("dpi"), QLatin1String("0")).toInt();
567 p->autoRotate = (ep.attribute(QLatin1String("autorotate"), QLatin1String("false")) == QLatin1String("true")) ? true : false;
568 QDomNode nt = ep.firstChild();
569
570 while (!nt.isNull())
571 {
572 QDomElement et = nt.toElement(); // try to convert the node to an element.
573
574 if (!et.isNull())
575 {
576 if (et.tagName() == QLatin1String("photo"))
577 {
578 float value = et.attribute(QLatin1String("width"), QLatin1String("0")).toFloat();
579 int width = (int)((value == 0 ? size.width() : value) * scaleValue);
580 value = et.attribute(QLatin1String("height"), QLatin1String("0")).toFloat();
581 int height = (int)((value == 0 ? size.height() : value) * scaleValue);
582 int photoX = (int)((et.attribute(QLatin1String("x"), QLatin1String("0")).toFloat() * scaleValue));
583 int photoY = (int)((et.attribute(QLatin1String("y"), QLatin1String("0")).toFloat() * scaleValue));
584 p->layouts.append(new QRect(photoX, photoY, width, height));
585 iconpreview.fillRect(photoX, photoY, width, height, Qt::color1);
586 }
587 else if (et.tagName() == QLatin1String("photogrid"))
588 {
589 float value = et.attribute(QLatin1String("pageWidth"), QLatin1String("0")).toFloat();
590 int pageWidth = (int)((value == 0 ? size.width() : value) * scaleValue);
591 value = et.attribute(QLatin1String("pageHeight"), QLatin1String("0")).toFloat();
592 int pageHeight = (int)((value == 0 ? size.height() : value) * scaleValue);
593 int rows = et.attribute(QLatin1String("rows"), QLatin1String("0")).toInt();
594 int columns = et.attribute(QLatin1String("columns"), QLatin1String("0")).toInt();
595
596 if (rows > 0 && columns > 0)
597 {
598 createPhotoGrid(p, pageWidth, pageHeight, rows, columns, &iconpreview);
599 }
600 else
601 {
602 qCWarning(KIPIPLUGINS_LOG) << " Wrong grid configuration, rows " << rows << ", columns " << columns;
603 }
604 }
605 else
606 {
607 qCDebug(KIPIPLUGINS_LOG) << " " << et.tagName();
608 }
609 }
610
611 nt = nt.nextSibling();
612 }
613
614 iconpreview.end();
615 p->icon = iconpreview.getIcon();
616 d->m_photoSizes.append(p);
617 }
618 else
619 {
620 qCDebug(KIPIPLUGINS_LOG) << "? " << ep.tagName() << " attr=" << ep.attribute(QLatin1String("name"), QLatin1String("??"));
621 }
622 }
623
624 np = np.nextSibling();
625 }
626 }
627 else
628 {
629 qCDebug(KIPIPLUGINS_LOG) << "??" << e.tagName() << " name=" << e.attribute(QLatin1String("name"), QLatin1String("??"));
630 }
631 }
632
633 n = n.nextSibling();
634 }
635 }
636
initPhotoSizes(const QSizeF & pageSize)637 void Wizard::initPhotoSizes(const QSizeF& pageSize)
638 {
639 qCDebug(KIPIPLUGINS_LOG) << "New page size " << pageSize
640 << ", old page size " << d->m_pageSize;
641
642 // don't refresh anything if we haven't changed page sizes.
643 if (pageSize == d->m_pageSize)
644 return;
645
646 d->m_pageSize = pageSize;
647
648 // cleaning m_pageSize memory before invoking clear()
649 for (int i = 0; i < d->m_photoSizes.count(); ++i)
650 delete d->m_photoSizes.at(i);
651
652 d->m_photoSizes.clear();
653
654 // get template-files and parse them
655
656 QDir dir(QStandardPaths::locate(QStandardPaths::GenericDataLocation,
657 QLatin1String("kipiplugin_printimages/templates"),
658 QStandardPaths::LocateDirectory));
659 const QStringList list = dir.entryList(QStringList() << QLatin1String("*.xml"));
660
661 qCDebug(KIPIPLUGINS_LOG) << "Template XML files list: " << list;
662
663 foreach(const QString& fn, list)
664 {
665 parseTemplateFile(dir.absolutePath() + QLatin1String("/") + fn, pageSize);
666 }
667
668 qCDebug(KIPIPLUGINS_LOG) << "d->m_photoSizes.count()=" << d->m_photoSizes.count();
669 qCDebug(KIPIPLUGINS_LOG) << "d->m_photoSizes.isEmpty()=" << d->m_photoSizes.isEmpty();
670
671 if (d->m_photoSizes.isEmpty())
672 {
673 qCDebug(KIPIPLUGINS_LOG) << "Empty photoSize-list, create default size\n";
674 // There is no valid page size yet. Create a default page (B10) to prevent crashes.
675 TPhotoSize* const p = new TPhotoSize;
676 p->dpi = 0;
677 p->autoRotate = false;
678 p->label = i18n("Unsupported Paper Size");
679 // page size: B10 (32 x 45 mm)
680 p->layouts.append(new QRect(0, 0, 3200, 4500));
681 p->layouts.append(new QRect(0, 0, 3200, 4500));
682 // add to the list
683 d->m_photoSizes.append(p);
684 }
685
686 // load the photo sizes into the listbox
687 d->m_photoUi->ListPhotoSizes->blockSignals(true);
688 d->m_photoUi->ListPhotoSizes->clear();
689 QList<TPhotoSize*>::iterator it;
690
691 for (it = d->m_photoSizes.begin(); it != d->m_photoSizes.end(); ++it)
692 {
693 TPhotoSize* const s = static_cast<TPhotoSize*>(*it);
694
695 if (s)
696 {
697 QListWidgetItem* const pWItem = new QListWidgetItem(s->label);
698 pWItem->setIcon(s->icon);
699 d->m_photoUi->ListPhotoSizes->addItem(pWItem);
700 }
701 }
702
703 // Adding custom choice
704 QListWidgetItem* const pWItem = new QListWidgetItem(i18n(customPageLayoutName));
705
706 //TODO FREE STYLE ICON
707 TemplateIcon ti(80, pageSize.toSize());
708 ti.begin();
709 QPainter& painter = ti.getPainter();
710 painter.setPen(Qt::color1);
711 painter.drawText(painter.viewport(), Qt::AlignCenter, i18n("Custom layout"));
712 ti.end();
713
714 pWItem->setIcon(ti.getIcon());
715 d->m_photoUi->ListPhotoSizes->addItem(pWItem);
716 d->m_photoUi->ListPhotoSizes->blockSignals(false);
717 d->m_photoUi->ListPhotoSizes->setCurrentRow(0, QItemSelectionModel::Select);
718 }
719
getMaxDPI(const QList<TPhoto * > & photos,const QList<QRect * > & layouts,int current)720 double getMaxDPI(const QList<TPhoto*>& photos, const QList<QRect*>& layouts, /*unsigned*/ int current)
721 {
722 Q_ASSERT(layouts.count() > 1);
723
724 QList<QRect*>::const_iterator it = layouts.begin();
725 QRect* layout = static_cast<QRect*>(*it);
726 double maxDPI = 0.0;
727
728 for (; current < photos.count(); ++current)
729 {
730 TPhoto* const photo = photos.at(current);
731 double dpi = ((double) photo->cropRegion.width() + (double) photo->cropRegion.height()) /
732 (((double) layout->width() / 1000.0) + ((double) layout->height() / 1000.0));
733
734 if (dpi > maxDPI)
735 maxDPI = dpi;
736
737 // iterate to the next position
738 ++it;
739 layout = (it == layouts.end()) ? nullptr : static_cast<QRect*>(*it);
740
741 if (layout == nullptr)
742 {
743 break;
744 }
745 }
746
747 return maxDPI;
748 }
749
getLayout(int photoIndex) const750 QRect* Wizard::getLayout(int photoIndex) const
751 {
752 TPhotoSize* const s = d->m_photoSizes.at(d->m_photoUi->ListPhotoSizes->currentRow());
753
754 // how many photos would actually be printed, including copies?
755 int photoCount = (photoIndex + 1);
756
757 // how many pages? Recall that the first layout item is the paper size
758 int photosPerPage = s->layouts.count() - 1;
759 int remainder = photoCount % photosPerPage;
760 int retVal = remainder;
761
762 if (remainder == 0)
763 retVal = photosPerPage;
764
765 return s->layouts.at(retVal);
766 }
767
getPageCount() const768 int Wizard::getPageCount() const
769 {
770 int pageCount = 0;
771 int photoCount = d->m_photos.count();
772
773 if (photoCount > 0)
774 {
775 // get the selected layout
776 TPhotoSize* const s = d->m_photoSizes.at(d->m_photoUi->ListPhotoSizes->currentRow());
777
778 // how many pages? Recall that the first layout item is the paper size
779 int photosPerPage = s->layouts.count() - 1;
780 int remainder = photoCount % photosPerPage;
781 int emptySlots = 0;
782
783 if (remainder > 0)
784 emptySlots = photosPerPage - remainder;
785
786 pageCount = photoCount / photosPerPage;
787
788 if (emptySlots > 0)
789 pageCount++;
790 }
791
792 return pageCount;
793 }
794
795 const float FONT_HEIGHT_RATIO = 0.8F;
796
printCaption(QPainter & p,TPhoto * const photo,int captionW,int captionH,const QString & caption)797 void Wizard::printCaption(QPainter& p, TPhoto* const photo, int captionW, int captionH, const QString& caption)
798 {
799 // PENDING anaselli TPhoto*photo will be needed to add a per photo caption management
800 QStringList captionByLines;
801
802 int captionIndex = 0;
803
804 while (captionIndex < caption.length())
805 {
806 QString newLine;
807 bool breakLine = false; // End Of Line found
808 int currIndex; // Caption QString current index
809
810 // Check minimal lines dimension
811 //TODO fix length, maybe useless
812 int captionLineLocalLength = 40;
813
814 for (currIndex = captionIndex; currIndex < caption.length() && !breakLine; ++currIndex)
815 {
816 if (caption[currIndex] == QLatin1Char('\n') || caption[currIndex].isSpace())
817 breakLine = true;
818 }
819
820 if (captionLineLocalLength <= (currIndex - captionIndex))
821 captionLineLocalLength = (currIndex - captionIndex);
822
823 breakLine = false;
824
825 for (currIndex = captionIndex;
826 (currIndex <= captionIndex + captionLineLocalLength) && (currIndex < caption.length()) && !breakLine;
827 ++currIndex)
828 {
829 breakLine = (caption[currIndex] == QLatin1Char('\n')) ? true : false;
830
831 if (breakLine)
832 newLine.append(QLatin1Char(' '));
833 else
834 newLine.append(caption[currIndex]);
835 }
836
837 captionIndex = currIndex; // The line is ended
838
839 if (captionIndex != caption.length())
840 {
841 while (!newLine.endsWith(QLatin1Char(' ')))
842 {
843 newLine.truncate(newLine.length() - 1);
844 captionIndex--;
845 }
846 }
847
848 captionByLines.prepend(newLine.trimmed());
849 }
850
851 QFont font(photo->pCaptionInfo->m_caption_font);
852 font.setStyleHint(QFont::SansSerif);
853 font.setPixelSize((int)(captionH * FONT_HEIGHT_RATIO));
854 font.setWeight(QFont::Normal);
855
856 QFontMetrics fm(font);
857 int pixelsHigh = fm.height();
858
859 p.setFont(font);
860 p.setPen(photo->pCaptionInfo->m_caption_color);
861 qCDebug(KIPIPLUGINS_LOG) << "Number of lines " << (int) captionByLines.count() ;
862
863 // Now draw the caption
864 // TODO allow printing captions per photo and on top, bottom and vertically
865 for (int lineNumber = 0; lineNumber < (int) captionByLines.count(); ++lineNumber)
866 {
867 if (lineNumber > 0)
868 p.translate(0, - (int)(pixelsHigh));
869
870 QRect r(0, 0, captionW, captionH);
871 //TODO anaselli check if ok
872 p.drawText(r, Qt::AlignLeft, captionByLines[lineNumber], &r);
873 }
874 }
875
captionFormatter(TPhoto * const photo) const876 QString Wizard::captionFormatter(TPhoto* const photo) const
877 {
878 if (!photo->pCaptionInfo)
879 return QString();
880
881 QString format;
882
883 switch (photo->pCaptionInfo->m_caption_type)
884 {
885 case CaptionInfo::FileNames:
886 format = QLatin1String("%f");
887 break;
888 case CaptionInfo::ExifDateTime:
889 format = QLatin1String("%d");
890 break;
891 case CaptionInfo::Comment:
892 format = QLatin1String("%c");
893 break;
894 case CaptionInfo::Free:
895 format = photo->pCaptionInfo->m_caption_text;
896 break;
897 default:
898 qCWarning(KIPIPLUGINS_LOG) << "UNKNOWN caption type " << photo->pCaptionInfo->m_caption_type;
899 break;
900 }
901
902 QFileInfo fi(photo->filename.toLocalFile());
903 QString resolution;
904 QSize imageSize;
905
906 if (photo->metaIface())
907 {
908 imageSize = photo->metaIface()->getImageDimensions();
909 }
910
911 if (imageSize.isValid())
912 {
913 resolution = QString::fromUtf8("%1x%2").arg(imageSize.width()).arg(imageSize.height());
914 }
915
916 format.replace(QLatin1String("\\n"), QLatin1String("\n"));
917
918 // %f filename
919 // %c comment
920 // %d date-time
921 // %t exposure time
922 // %i iso
923 // %r resolution
924 // %a aperture
925 // %l focal length
926
927 KPImageInfo info(photo->filename);
928 format.replace(QString::fromUtf8("%r"), resolution);
929 format.replace(QString::fromUtf8("%f"), fi.fileName());
930 format.replace(QString::fromUtf8("%c"), info.description());
931 format.replace(QString::fromUtf8("%d"), QLocale().toString(info.date(), QLocale::ShortFormat));
932
933 if (photo->metaIface())
934 {
935 format.replace(QString::fromUtf8("%t"), photo->metaIface()->getExifTagString(QLatin1String("Exif.Photo.ExposureTime")));
936 format.replace(QString::fromUtf8("%i"), photo->metaIface()->getExifTagString(QLatin1String("Exif.Photo.ISOSpeedRatings")));
937 format.replace(QString::fromUtf8("%a"), photo->metaIface()->getExifTagString(QLatin1String("Exif.Photo.FNumber")));
938 format.replace(QString::fromUtf8("%l"), photo->metaIface()->getExifTagString(QLatin1String("Exif.Photo.FocalLength")));
939 }
940 else
941 {
942 format.replace(QString::fromUtf8("%t"), QLatin1String(""));
943 format.replace(QString::fromUtf8("%i"), QLatin1String(""));
944 format.replace(QString::fromUtf8("%a"), QLatin1String(""));
945 format.replace(QString::fromUtf8("%l"), QLatin1String(""));
946 }
947
948 return format;
949 }
950
paintOnePage(QPainter & p,const QList<TPhoto * > & photos,const QList<QRect * > & layouts,int & current,bool cropDisabled,bool useThumbnails)951 bool Wizard::paintOnePage(QPainter& p, const QList<TPhoto*>& photos, const QList<QRect*>& layouts,
952 int& current, bool cropDisabled, bool useThumbnails)
953 {
954 Q_ASSERT(layouts.count() > 1);
955
956 if (photos.count() == 0)
957 return true; // no photos => last photo
958
959 QList<QRect*>::const_iterator it = layouts.begin();
960 QRect* const srcPage = static_cast<QRect*>(*it);
961 ++it;
962 QRect* layout = static_cast<QRect*>(*it);
963
964 // scale the page size to best fit the painter
965 // size the rectangle based on the minimum image dimension
966 int destW = p.window().width();
967 int destH = p.window().height();
968 int srcW = srcPage->width();
969 int srcH = srcPage->height();
970
971 if (destW < destH)
972 {
973 destH = NINT((double) destW * ((double) srcH / (double) srcW));
974
975 if (destH > p.window().height())
976 {
977 destH = p.window().height();
978 destW = NINT((double) destH * ((double) srcW / (double) srcH));
979 }
980 }
981 else
982 {
983 destW = NINT((double) destH * ((double) srcW / (double) srcH));
984
985 if (destW > p.window().width())
986 {
987 destW = p.window().width();
988 destH = NINT((double) destW * ((double) srcH / (double) srcW));
989 }
990 }
991
992 double xRatio = (double) destW / (double) srcPage->width();
993 double yRatio = (double) destH / (double) srcPage->height();
994 int left = (p.window().width() - destW) / 2;
995 int top = (p.window().height() - destH) / 2;
996
997 // FIXME: may not want to erase the background page
998 p.eraseRect(left, top,
999 NINT((double) srcPage->width() * xRatio),
1000 NINT((double) srcPage->height() * yRatio));
1001
1002 for (; current < photos.count(); ++current)
1003 {
1004 TPhoto* const photo = photos.at(current);
1005 // crop
1006 QImage img;
1007
1008 if (useThumbnails)
1009 img = photo->thumbnail().toImage();
1010 else
1011 img = photo->loadPhoto();
1012
1013 // next, do we rotate?
1014 if (photo->rotation != 0)
1015 {
1016 // rotate
1017 QMatrix matrix;
1018 matrix.rotate(photo->rotation);
1019 img = img.transformed(matrix);
1020 }
1021
1022 if (useThumbnails)
1023 {
1024 // scale the crop region to thumbnail coords
1025 double xRatio = 0.0;
1026 double yRatio = 0.0;
1027
1028 if (photo->thumbnail().width() != 0)
1029 xRatio = (double) photo->thumbnail().width() / (double) photo->width();
1030
1031 if (photo->thumbnail().height() != 0)
1032 yRatio = (double) photo->thumbnail().height() / (double) photo->height();
1033
1034 int x1 = NINT((double) photo->cropRegion.left() * xRatio);
1035 int y1 = NINT((double) photo->cropRegion.top() * yRatio);
1036 int w = NINT((double) photo->cropRegion.width() * xRatio);
1037 int h = NINT((double) photo->cropRegion.height() * yRatio);
1038 img = img.copy(QRect(x1, y1, w, h));
1039 }
1040 else if (!cropDisabled) //d->m_cropUi->m_disableCrop->isChecked() )
1041 {
1042 img = img.copy(photo->cropRegion);
1043 }
1044
1045 int x1 = NINT((double) layout->left() * xRatio);
1046 int y1 = NINT((double) layout->top() * yRatio);
1047 int w = NINT((double) layout->width() * xRatio);
1048 int h = NINT((double) layout->height() * yRatio);
1049
1050 QRect rectViewPort = p.viewport();
1051 QRect newRectViewPort = QRect(x1 + left, y1 + top, w, h);
1052 QSize imageSize = img.size();
1053
1054 // qCDebug(KIPIPLUGINS_LOG) << "Image " << photo->filename << " size " << imageSize;
1055 // qCDebug(KIPIPLUGINS_LOG) << "viewport size " << newRectViewPort.size();
1056
1057 QPoint point;
1058
1059 if (cropDisabled) //->m_cropPage->m_disableCrop->isChecked() )
1060 {
1061 imageSize.scale(newRectViewPort.size(), Qt::KeepAspectRatio);
1062 int spaceLeft = (newRectViewPort.width() - imageSize.width()) / 2;
1063 int spaceTop = (newRectViewPort.height() - imageSize.height()) / 2;
1064 p.setViewport(spaceLeft + newRectViewPort.x(), spaceTop + newRectViewPort.y(), imageSize.width(), imageSize.height());
1065 point = QPoint(newRectViewPort.x() + spaceLeft + imageSize.width(), newRectViewPort.y() + spaceTop + imageSize.height());
1066 }
1067 else
1068 {
1069 p.setViewport(newRectViewPort);
1070 point = QPoint(x1 + left + w, y1 + top + w);
1071 }
1072
1073 QRect rectWindow = p.window();
1074 p.setWindow(img.rect());
1075 p.drawImage(0, 0, img);
1076 p.setViewport(rectViewPort);
1077 p.setWindow(rectWindow);
1078 p.setBrushOrigin(point);
1079
1080 if (photo->pCaptionInfo && photo->pCaptionInfo->m_caption_type != CaptionInfo::NoCaptions)
1081 {
1082 p.save();
1083 QString caption;
1084 caption = captionFormatter(photo);
1085 qCDebug(KIPIPLUGINS_LOG) << "Caption " << caption ;
1086
1087 // draw the text at (0,0), but we will translate and rotate the world
1088 // before drawing so the text will be in the correct location
1089 // next, do we rotate?
1090 int captionW = w - 2;
1091 double ratio = photo->pCaptionInfo->m_caption_size * 0.01;
1092 int captionH = (int)(qMin(w, h) * ratio);
1093 int exifOrientation = MetadataProcessor::NORMAL;
1094 int orientatation = photo->rotation;
1095
1096 if (photo->metaIface())
1097 {
1098 exifOrientation = photo->metaIface()->getImageOrientation();
1099 }
1100
1101 // ROT_90_HFLIP .. ROT_270
1102
1103 if (exifOrientation == MetadataProcessor::ROT_90_HFLIP ||
1104 exifOrientation == MetadataProcessor::ROT_90 ||
1105 exifOrientation == MetadataProcessor::ROT_90_VFLIP ||
1106 exifOrientation == MetadataProcessor::ROT_270)
1107 {
1108 orientatation = (photo->rotation + 270) % 360; // -90 degrees
1109 }
1110
1111 if (orientatation == 90 || orientatation == 270)
1112 {
1113 captionW = h;
1114 }
1115
1116 p.rotate(orientatation);
1117 qCDebug(KIPIPLUGINS_LOG) << "rotation " << photo->rotation << " orientation " << orientatation ;
1118 int tx = left;
1119 int ty = top;
1120
1121 switch (orientatation)
1122 {
1123 case 0 :
1124 {
1125 tx += x1 + 1;
1126 ty += y1 + (h - captionH - 1);
1127 break;
1128 }
1129 case 90 :
1130 {
1131 tx = top + y1 + 1;
1132 ty = -left - x1 - captionH - 1;
1133 break;
1134 }
1135 case 180 :
1136 {
1137 tx = -left - x1 - w + 1;
1138 ty = -top - y1 - (captionH + 1);
1139 break;
1140 }
1141 case 270 :
1142 {
1143 tx = -top - y1 - h + 1;
1144 ty = left + x1 + (w - captionH) - 1;
1145 break;
1146 }
1147 }
1148 p.translate(tx, ty);
1149 printCaption(p, photo, captionW, captionH, caption);
1150 p.restore();
1151 } // caption
1152
1153 // iterate to the next position
1154 ++it;
1155 layout = it == layouts.end() ? nullptr : static_cast<QRect*>(*it);
1156
1157 if (layout == nullptr)
1158 {
1159 current++;
1160 break;
1161 }
1162 }
1163
1164 // did we print the last photo?
1165 return (current < photos.count());
1166 }
1167
updateCropFrame(TPhoto * const photo,int photoIndex)1168 void Wizard::updateCropFrame(TPhoto* const photo, int photoIndex)
1169 {
1170 TPhotoSize* const s = d->m_photoSizes.at(d->m_photoUi->ListPhotoSizes->currentRow());
1171 d->m_cropUi->cropFrame->init(photo, getLayout(photoIndex)->width(), getLayout(photoIndex)->height(), s->autoRotate);
1172 d->m_cropUi->LblCropPhoto->setText(i18n("Photo %1 of %2", photoIndex + 1, QString::number(d->m_photos.count())));
1173 }
1174
1175 // update the pages to be printed and preview first/last pages
previewPhotos()1176 void Wizard::previewPhotos()
1177 {
1178 //Change cursor to waitCursor during transition
1179 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
1180
1181 // get the selected layout
1182 int curr = d->m_photoUi->ListPhotoSizes->currentRow();
1183 TPhotoSize* const s = d->m_photoSizes.at(curr);
1184 int photoCount = d->m_photos.count();
1185 int emptySlots = 0;
1186 int pageCount = 0;
1187 int photosPerPage = 0;
1188
1189 if (photoCount > 0)
1190 {
1191 // how many pages? Recall that the first layout item is the paper size
1192 photosPerPage = s->layouts.count() - 1;
1193 int remainder = photoCount % photosPerPage;
1194
1195 if (remainder > 0)
1196 emptySlots = photosPerPage - remainder;
1197
1198 pageCount = photoCount / photosPerPage;
1199
1200 if (emptySlots > 0)
1201 pageCount++;
1202 }
1203
1204 d->m_photoUi->LblPhotoCount->setText(QString::number(photoCount));
1205 d->m_photoUi->LblSheetsPrinted->setText(QString::number(pageCount));
1206 d->m_photoUi->LblEmptySlots->setText(QString::number(emptySlots));
1207
1208 // photo previews
1209 // preview the first page.
1210 // find the first page of photos
1211 int count = 0;
1212 int page = 0;
1213 int current = 0;
1214 QList<TPhoto*>::iterator it;
1215
1216 for (it = d->m_photos.begin(); it != d->m_photos.end(); ++it)
1217 {
1218 TPhoto* const photo = static_cast<TPhoto*>(*it);
1219
1220 if (page == d->m_currentPreviewPage)
1221 {
1222 photo->cropRegion.setRect(-1, -1, -1, -1);
1223 photo->rotation = 0;
1224 int w = s->layouts.at(count + 1)->width();
1225 int h = s->layouts.at(count + 1)->height();
1226 d->m_cropUi->cropFrame->init(photo, w, h, s->autoRotate, false);
1227 }
1228
1229 count++;
1230
1231 if (count >= photosPerPage)
1232 {
1233 if (page == d->m_currentPreviewPage)
1234 break;
1235
1236 page++;
1237 current += photosPerPage;
1238 count = 0;
1239 }
1240 }
1241
1242 // send this photo list to the painter
1243 if (photoCount > 0)
1244 {
1245 QImage img(d->m_photoUi->BmpFirstPagePreview->size(), QImage::Format_ARGB32_Premultiplied);
1246 QPainter p(&img);
1247 p.setCompositionMode(QPainter::CompositionMode_Clear);
1248 //p.setCompositionMode(QPainter::CompositionMode_Destination );
1249 p.fillRect(img.rect(), Qt::color0); //Qt::transparent );
1250 p.setCompositionMode(QPainter::CompositionMode_SourceOver);
1251 paintOnePage(p, d->m_photos, s->layouts, current, d->m_cropUi->m_disableCrop->isChecked(), true);
1252 p.end();
1253
1254 d->m_photoUi->BmpFirstPagePreview->clear();
1255 d->m_photoUi->BmpFirstPagePreview->setPixmap(QPixmap::fromImage(img));
1256 d->m_photoUi->LblPreview->setText(i18n("Page %1 of %2", d->m_currentPreviewPage + 1, getPageCount()));
1257 }
1258 else
1259 {
1260 d->m_photoUi->BmpFirstPagePreview->clear();
1261 d->m_photoUi->LblPreview->clear();
1262 // d->m_photoUi->BmpFirstPagePreview->setPixmap ( QPixmap() );
1263 d->m_photoUi->LblPreview->setText(i18n("Page %1 of %2", 0, 0));
1264 }
1265
1266 manageBtnPreviewPage();
1267 d->m_photoUi->update();
1268 QApplication::restoreOverrideCursor();
1269 }
1270
manageBtnPreviewPage()1271 void Wizard::manageBtnPreviewPage()
1272 {
1273 if (d->m_photos.empty())
1274 {
1275 d->m_photoUi->BtnPreviewPageDown->setEnabled(false);
1276 d->m_photoUi->BtnPreviewPageUp->setEnabled(false);
1277 }
1278 else
1279 {
1280 d->m_photoUi->BtnPreviewPageDown->setEnabled(true);
1281 d->m_photoUi->BtnPreviewPageUp->setEnabled(true);
1282
1283 if (d->m_currentPreviewPage == 0)
1284 {
1285 d->m_photoUi->BtnPreviewPageDown->setEnabled(false);
1286 }
1287
1288 if ((d->m_currentPreviewPage + 1) == getPageCount())
1289 {
1290 d->m_photoUi->BtnPreviewPageUp->setEnabled(false);
1291 }
1292 }
1293 }
1294
infopage_setCaptionButtons()1295 void Wizard::infopage_setCaptionButtons()
1296 {
1297 if (d->m_photos.size())
1298 {
1299 TPhoto* const pPhoto = d->m_photos.at(d->m_infopageCurrentPhoto);
1300
1301 if (pPhoto && !d->m_photoUi->m_sameCaption->isChecked())
1302 {
1303 infopage_blockCaptionButtons();
1304
1305 if (pPhoto->pCaptionInfo)
1306 {
1307 d->m_photoUi->m_font_color->setColor(pPhoto->pCaptionInfo->m_caption_color);
1308 d->m_photoUi->m_font_size->setValue(pPhoto->pCaptionInfo->m_caption_size);
1309 d->m_photoUi->m_font_name->setCurrentFont(pPhoto->pCaptionInfo->m_caption_font);
1310 d->m_photoUi->m_captions->setCurrentIndex(int(pPhoto->pCaptionInfo->m_caption_type));
1311 d->m_photoUi->m_FreeCaptionFormat->setText(pPhoto->pCaptionInfo->m_caption_text);
1312 enableCaptionGroup(d->m_photoUi->m_captions->currentText());
1313 }
1314 else
1315 {
1316 infopage_readCaptionSettings();
1317 captionChanged(d->m_photoUi->m_captions->currentText());
1318 }
1319
1320 infopage_blockCaptionButtons(false);
1321 }
1322 }
1323 }
1324
slotXMLCustomElement(QXmlStreamWriter & xmlWriter)1325 void Wizard::slotXMLCustomElement(QXmlStreamWriter& xmlWriter)
1326 {
1327 qCDebug(KIPIPLUGINS_LOG) << " invoked " ;
1328 xmlWriter.writeStartElement(QLatin1String("pa_layout"));
1329 xmlWriter.writeAttribute(QLatin1String("Printer"), d->m_photoUi->m_printer_choice->currentText());
1330 xmlWriter.writeAttribute(QLatin1String("PageSize"), QString::fromUtf8("%1").arg(d->m_printer->paperSize()));
1331 xmlWriter.writeAttribute(QLatin1String("PhotoSize"), d->m_photoUi->ListPhotoSizes->currentItem()->text());
1332 xmlWriter.writeEndElement(); // pa_layout
1333 }
1334
slotXMLSaveItem(QXmlStreamWriter & xmlWriter,KIPIPlugins::KPImagesListViewItem * item)1335 void Wizard::slotXMLSaveItem(QXmlStreamWriter& xmlWriter, KIPIPlugins::KPImagesListViewItem* item)
1336 {
1337 if (d->m_photos.size())
1338 {
1339 int itemIndex = d->m_imagesFilesListBox->listView()->indexFromItem(item).row();
1340 TPhoto* const pPhoto = d->m_photos[itemIndex];
1341 // TODO anaselli: first and copies could be removed since they are not useful any more
1342 xmlWriter.writeAttribute(QLatin1String("first"), QString::fromUtf8("%1").arg(pPhoto->first));
1343 xmlWriter.writeAttribute(QLatin1String("copies"), QString::fromUtf8("%1").arg(pPhoto->first ? pPhoto->copies : 0));
1344
1345 // additional info (caption... etc)
1346 if (pPhoto->pCaptionInfo)
1347 {
1348 xmlWriter.writeStartElement(QLatin1String("pa_caption"));
1349 xmlWriter.writeAttribute(QLatin1String("type"), QString::fromUtf8("%1").arg(pPhoto->pCaptionInfo->m_caption_type));
1350 xmlWriter.writeAttribute(QLatin1String("font"), pPhoto->pCaptionInfo->m_caption_font.toString());
1351 xmlWriter.writeAttribute(QLatin1String("size"), QString::fromUtf8("%1").arg(pPhoto->pCaptionInfo->m_caption_size));
1352 xmlWriter.writeAttribute(QLatin1String("color"), pPhoto->pCaptionInfo->m_caption_color.name());
1353 xmlWriter.writeAttribute(QLatin1String("text"), pPhoto->pCaptionInfo->m_caption_text);
1354 xmlWriter.writeEndElement(); // pa_caption
1355 }
1356 }
1357 }
1358
slotXMLCustomElement(QXmlStreamReader & xmlReader)1359 void Wizard::slotXMLCustomElement(QXmlStreamReader& xmlReader)
1360 {
1361 qCDebug(KIPIPLUGINS_LOG) << " invoked " << xmlReader.name();
1362
1363 while (!xmlReader.atEnd())
1364 {
1365 if (xmlReader.isStartElement() && xmlReader.name() == QLatin1String("pa_layout"))
1366 {
1367 bool ok;
1368 QXmlStreamAttributes attrs = xmlReader.attributes();
1369 // get value of each attribute from QXmlStreamAttributes
1370 QStringRef attr = attrs.value(QLatin1String("Printer"));
1371
1372 if (!attr.isEmpty())
1373 {
1374 qCDebug(KIPIPLUGINS_LOG) << " found " << attr.toString();
1375 int index = d->m_photoUi->m_printer_choice->findText(attr.toString());
1376
1377 if (index != -1)
1378 {
1379 d->m_photoUi->m_printer_choice->setCurrentIndex(index);
1380 }
1381
1382 outputChanged(d->m_photoUi->m_printer_choice->currentText());
1383 }
1384
1385 attr = attrs.value(QLatin1String("PageSize"));
1386
1387 if (!attr.isEmpty())
1388 {
1389 qCDebug(KIPIPLUGINS_LOG) << " found " << attr.toString();
1390 QPrinter::PaperSize paperSize = (QPrinter::PaperSize)attr.toString().toInt(&ok);
1391 d->m_printer->setPaperSize(paperSize);
1392 }
1393
1394 attr = attrs.value(QLatin1String("PhotoSize"));
1395
1396 if (!attr.isEmpty())
1397 {
1398 qCDebug(KIPIPLUGINS_LOG) << " found " << attr.toString();
1399 d->m_savedPhotoSize = attr.toString();
1400 }
1401 }
1402
1403 xmlReader.readNext();
1404 }
1405
1406 // reset preview page number
1407 d->m_currentPreviewPage = 0;
1408 initPhotoSizes(d->m_printer->paperSize(QPrinter::Millimeter));
1409 QList<QListWidgetItem*> list = d->m_photoUi->ListPhotoSizes->findItems(d->m_savedPhotoSize, Qt::MatchExactly);
1410
1411 if (list.count())
1412 {
1413 qCDebug(KIPIPLUGINS_LOG) << " PhotoSize " << list[0]->text();
1414 d->m_photoUi->ListPhotoSizes->setCurrentItem(list[0]);
1415 }
1416 else
1417 {
1418 d->m_photoUi->ListPhotoSizes->setCurrentRow(0);
1419 }
1420
1421 previewPhotos();
1422 }
1423
slotXMLLoadElement(QXmlStreamReader & xmlReader)1424 void Wizard::slotXMLLoadElement(QXmlStreamReader& xmlReader)
1425 {
1426 if (d->m_photos.size())
1427 {
1428 // read image is the last.
1429 TPhoto* const pPhoto = d->m_photos[d->m_photos.size()-1];
1430 qCDebug(KIPIPLUGINS_LOG) << " invoked " << xmlReader.name();
1431
1432 while (xmlReader.readNextStartElement())
1433 {
1434 qCDebug(KIPIPLUGINS_LOG) << pPhoto->filename << " " << xmlReader.name();
1435
1436 if (xmlReader.name() == QLatin1String("pa_caption"))
1437 {
1438 d->m_photoUi->m_sameCaption->blockSignals(true);
1439 d->m_photoUi->m_sameCaption->setCheckState( Qt::Unchecked );
1440 d->m_photoUi->m_sameCaption->blockSignals(false);
1441
1442 //useless this item has been added now
1443 if (pPhoto->pCaptionInfo)
1444 delete pPhoto->pCaptionInfo;
1445
1446 pPhoto->pCaptionInfo = new CaptionInfo();
1447 // get all attributes and its value of a tag in attrs variable.
1448 QXmlStreamAttributes attrs = xmlReader.attributes();
1449 // get value of each attribute from QXmlStreamAttributes
1450 QStringRef attr = attrs.value(QLatin1String("type"));
1451 bool ok;
1452
1453 if (!attr.isEmpty())
1454 {
1455 qCDebug(KIPIPLUGINS_LOG) << " found " << attr.toString();
1456 pPhoto->pCaptionInfo->m_caption_type = (CaptionInfo::AvailableCaptions)attr.toString().toInt(&ok);
1457 }
1458
1459 attr = attrs.value(QLatin1String("font"));
1460
1461 if (!attr.isEmpty())
1462 {
1463 qCDebug(KIPIPLUGINS_LOG) << " found " << attr.toString();
1464 pPhoto->pCaptionInfo->m_caption_font.fromString(attr.toString());
1465 }
1466
1467 attr = attrs.value(QLatin1String("color"));
1468
1469 if (!attr.isEmpty())
1470 {
1471 qCDebug(KIPIPLUGINS_LOG) << " found " << attr.toString();
1472 pPhoto->pCaptionInfo->m_caption_color.setNamedColor(attr.toString());
1473 }
1474
1475 attr = attrs.value(QLatin1String("size"));
1476
1477 if (!attr.isEmpty())
1478 {
1479 qCDebug(KIPIPLUGINS_LOG) << " found " << attr.toString();
1480 pPhoto->pCaptionInfo->m_caption_size = attr.toString().toInt(&ok);
1481 }
1482
1483 attr = attrs.value(QLatin1String("text"));
1484
1485 if (!attr.isEmpty())
1486 {
1487 qCDebug(KIPIPLUGINS_LOG) << " found " << attr.toString();
1488 pPhoto->pCaptionInfo->m_caption_text = attr.toString();
1489 }
1490
1491 infopage_setCaptionButtons();
1492 }
1493 }
1494 }
1495 }
1496
slotContextMenuRequested()1497 void Wizard::slotContextMenuRequested()
1498 {
1499 if (d->m_photos.size())
1500 {
1501 int itemIndex = d->m_imagesFilesListBox->listView()->currentIndex().row();
1502 d->m_imagesFilesListBox->listView()->blockSignals(true);
1503 QMenu menu(d->m_imagesFilesListBox->listView());
1504 QAction* const action = menu.addAction(i18n("Add again"));
1505
1506 connect(action, SIGNAL(triggered()),
1507 this , SLOT(increaseCopies()));
1508
1509 TPhoto* const pPhoto = d->m_photos[itemIndex];
1510 qCDebug(KIPIPLUGINS_LOG) << " copies " << pPhoto->copies << " first " << pPhoto->first;
1511
1512 if (pPhoto->copies > 1 || !pPhoto->first)
1513 {
1514 QAction* const actionr = menu.addAction(i18n("Remove"));
1515
1516 connect(actionr, SIGNAL(triggered()),
1517 this, SLOT(decreaseCopies()));
1518 }
1519
1520 menu.exec(QCursor::pos());
1521 d->m_imagesFilesListBox->listView()->blockSignals(false);
1522 }
1523 }
1524
imageSelected(QTreeWidgetItem * item)1525 void Wizard::imageSelected(QTreeWidgetItem* item)
1526 {
1527 KPImagesListViewItem* const l_item = dynamic_cast<KPImagesListViewItem*>(item);
1528
1529 if (!l_item)
1530 return;
1531
1532 int itemIndex = d->m_imagesFilesListBox->listView()->indexFromItem(l_item).row();
1533
1534 qCDebug(KIPIPLUGINS_LOG) << " current row now is " << itemIndex;
1535 d->m_infopageCurrentPhoto = itemIndex;
1536
1537 infopage_setCaptionButtons();
1538 }
1539
decreaseCopies()1540 void Wizard::decreaseCopies()
1541 {
1542 if (d->m_photos.size())
1543 {
1544 KPImagesListViewItem* const item = dynamic_cast<KPImagesListViewItem* >(d->m_imagesFilesListBox->listView()->currentItem());
1545
1546 if (!item)
1547 return;
1548
1549 qCDebug(KIPIPLUGINS_LOG) << " Removing a copy of " << item->url();
1550 d->m_imagesFilesListBox->slotRemoveItems();
1551 }
1552 }
1553
slotRemovingItem(KIPIPlugins::KPImagesListViewItem * item)1554 void Wizard::slotRemovingItem(KIPIPlugins::KPImagesListViewItem* item)
1555 {
1556 if (item)
1557 {
1558 int itemIndex = d->m_imagesFilesListBox->listView()->indexFromItem(item).row();
1559
1560 if (d->m_photos.size() && itemIndex >= 0)
1561 {
1562 /// Debug data: found and copies
1563 bool found = false;
1564 int copies = 0;
1565
1566 d->m_imagesFilesListBox->blockSignals(true);
1567 TPhoto* const pPhotoToRemove = d->m_photos.at(itemIndex);
1568
1569 // photo to be removed could be:
1570 // 1) unique => just remove it
1571 // 2) first of n, =>
1572 // search another with the same url
1573 // and set it a first and with a count to n-1 then remove it
1574 // 3) one of n, search the first one and set count to n-1 then remove it
1575 if (pPhotoToRemove && pPhotoToRemove->first)
1576 {
1577 if (pPhotoToRemove->copies > 0)
1578 {
1579 for (int i = 0; i < d->m_photos.count() && !found; ++i)
1580 {
1581 TPhoto* const pCurrentPhoto = d->m_photos.at(i);
1582
1583 if (pCurrentPhoto && pCurrentPhoto->filename == pPhotoToRemove->filename)
1584 {
1585 pCurrentPhoto->copies = pPhotoToRemove->copies - 1;
1586 copies = pCurrentPhoto->copies;
1587 pCurrentPhoto->first = true;
1588 found = true;
1589 }
1590 }
1591 }
1592 // otherwise it's unique
1593 }
1594 else if (pPhotoToRemove)
1595 {
1596 for (int i = 0; i < d->m_photos.count() && !found; ++i)
1597 {
1598 TPhoto* const pCurrentPhoto = d->m_photos.at(i);
1599
1600 if (pCurrentPhoto && pCurrentPhoto->filename == pPhotoToRemove->filename && pCurrentPhoto->first)
1601 {
1602 pCurrentPhoto->copies--;
1603 copies = pCurrentPhoto->copies;
1604 found = true;
1605 }
1606 }
1607 }
1608 else
1609 {
1610 qCDebug(KIPIPLUGINS_LOG) << " NULL TPhoto object ";
1611 return;
1612 }
1613
1614 if (pPhotoToRemove)
1615 {
1616 qCDebug(KIPIPLUGINS_LOG) << "Removed fileName: " << pPhotoToRemove->filename.fileName() << " copy number " << copies;
1617 }
1618
1619 d->m_photos.removeAt(itemIndex);
1620 delete pPhotoToRemove;
1621
1622 d->m_imagesFilesListBox->blockSignals(false);
1623 previewPhotos();
1624 }
1625
1626 if (d->m_photos.empty())
1627 {
1628 // No photos => disabling next button (e.g. crop page)
1629 d->m_photoPage->setComplete(false);
1630 }
1631 }
1632 }
1633
slotAddItems(const QList<QUrl> & list)1634 void Wizard::slotAddItems(const QList<QUrl>& list)
1635 {
1636 if (list.count() == 0)
1637 {
1638 return;
1639 }
1640
1641 QList<QUrl> urls;
1642 d->m_imagesFilesListBox->blockSignals(true);
1643
1644 for (QList<QUrl>::ConstIterator it = list.constBegin(); it != list.constEnd(); ++it)
1645 {
1646 QUrl imageUrl = *it;
1647
1648 // Check if the new item already exist in the list.
1649 bool found = false;
1650
1651 for (int i = 0; i < d->m_photos.count() && !found; ++i)
1652 {
1653 TPhoto* const pCurrentPhoto = d->m_photos.at(i);
1654
1655 if (pCurrentPhoto && pCurrentPhoto->filename == imageUrl && pCurrentPhoto->first)
1656 {
1657 pCurrentPhoto->copies++;
1658 found = true;
1659 TPhoto* const pPhoto = new TPhoto(*pCurrentPhoto);
1660 pPhoto->first = false;
1661 d->m_photos.append(pPhoto);
1662 qCDebug(KIPIPLUGINS_LOG) << "Added fileName: " << pPhoto->filename.fileName() << " copy number " << pCurrentPhoto->copies;
1663 }
1664 }
1665
1666 if (!found)
1667 {
1668 TPhoto* const pPhoto = new TPhoto(150);
1669 pPhoto->filename = *it;
1670 pPhoto->first = true;
1671 d->m_photos.append(pPhoto);
1672 qCDebug(KIPIPLUGINS_LOG) << "Added new fileName: " << pPhoto->filename.fileName();
1673 }
1674 }
1675
1676 d->m_imagesFilesListBox->blockSignals(false);
1677 infopage_updateCaptions();
1678 //previewPhotos();
1679
1680 if (d->m_photos.size())
1681 {
1682 d->m_photoPage->setComplete(true);
1683 }
1684 }
1685
increaseCopies()1686 void Wizard::increaseCopies()
1687 {
1688 if (d->m_photos.size())
1689 {
1690 QList<QUrl> list;
1691 KPImagesListViewItem* const item = dynamic_cast<KPImagesListViewItem* >(d->m_imagesFilesListBox->listView()->currentItem());
1692
1693 if (!item)
1694 return;
1695
1696 list.append(item->url());
1697 qCDebug(KIPIPLUGINS_LOG) << " Adding a copy of " << item->url();
1698 d->m_imagesFilesListBox->slotAddImages(list);
1699 }
1700 }
1701
pageChanged(int curr)1702 void Wizard::pageChanged(int curr)
1703 {
1704 QWizardPage* const current = page(curr);
1705
1706 if (!current) return;
1707
1708 QWizardPage* const before = visitedPages().isEmpty() ? nullptr : page(visitedPages().last());
1709
1710 //Change cursor to waitCursor during transition
1711 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
1712
1713 if (before)
1714 {
1715 saveSettings(before->title());
1716 qCDebug(KIPIPLUGINS_LOG) << " before " << before->title();
1717 }
1718
1719 qCDebug(KIPIPLUGINS_LOG) << " current " << current->title();
1720
1721 if (current->title() == i18n(photoPageName))
1722 {
1723 // readSettings only the first time
1724 if (!before)
1725 readSettings(current->title());
1726
1727 // set to first photo
1728 d->m_infopageCurrentPhoto = 0;
1729 d->m_imagesFilesListBox->listView()->clear();
1730 QList<QUrl> list;
1731
1732 for (int i = 0; i < d->m_photos.count();++i)
1733 {
1734 TPhoto* const pCurrentPhoto = d->m_photos.at(i);
1735
1736 if (pCurrentPhoto)
1737 {
1738 list.push_back(pCurrentPhoto->filename);
1739 }
1740 }
1741
1742 d->m_imagesFilesListBox->blockSignals(true);
1743 d->m_imagesFilesListBox->slotAddImages(list);
1744 d->m_imagesFilesListBox->listView()->setCurrentItem(d->m_imagesFilesListBox->listView()->itemAt(0, 0));
1745 d->m_imagesFilesListBox->blockSignals(false);
1746 d->m_photoUi->LblPhotoCount->setText(QString::number(d->m_photos.count()));
1747
1748 // PhotoPage
1749 initPhotoSizes(d->m_printer->paperSize(QPrinter::Millimeter));
1750 // restore photoSize
1751
1752 if (before && d->m_savedPhotoSize == i18n(customPageLayoutName))
1753 {
1754 d->m_photoUi->ListPhotoSizes->setCurrentRow(0);
1755 }
1756 else
1757 {
1758 QList<QListWidgetItem*> list = d->m_photoUi->ListPhotoSizes->findItems(d->m_savedPhotoSize, Qt::MatchExactly);
1759
1760 if (list.count())
1761 d->m_photoUi->ListPhotoSizes->setCurrentItem(list[0]);
1762 else
1763 d->m_photoUi->ListPhotoSizes->setCurrentRow(0);
1764 }
1765
1766 // update captions only the first time to avoid missing old changes when
1767 // back to this page
1768 if (!before)
1769 infopage_updateCaptions();
1770
1771 // reset preview page number
1772 d->m_currentPreviewPage = 0;
1773 // create our photo sizes list
1774 previewPhotos();
1775 }
1776 else if (current->title() == i18n(cropPageName))
1777 {
1778 readSettings(current->title());
1779 d->m_currentCropPhoto = 0;
1780
1781 if (d->m_photos.size())
1782 {
1783 TPhoto* const photo = d->m_photos[d->m_currentCropPhoto];
1784 setBtnCropEnabled();
1785 this->update();
1786 updateCropFrame(photo, d->m_currentCropPhoto);
1787 }
1788 else
1789 {
1790 // NOTE it should not pass here
1791 qCDebug(KIPIPLUGINS_LOG) << "Not any photos selected cropping is disabled";
1792 }
1793 }
1794
1795 QApplication::restoreOverrideCursor();
1796 }
1797
outputChanged(const QString & text)1798 void Wizard::outputChanged(const QString& text)
1799 {
1800 if (text == i18n("Print to PDF") ||
1801 text == i18n("Print to JPG") ||
1802 text == i18n("Print to gimp"))
1803 {
1804 delete d->m_printer;
1805
1806 d->m_printer = new QPrinter();
1807 d->m_printer->setOutputFormat(QPrinter::PdfFormat);
1808 }
1809 else // real printer
1810 {
1811 QList<QPrinterInfo>::iterator it;
1812 //m_printerList = QPrinterInfo::availablePrinters ();
1813
1814 for (it = d->m_printerList.begin(); it != d->m_printerList.end(); ++it)
1815 {
1816 if (it->printerName() == text)
1817 {
1818 qCDebug(KIPIPLUGINS_LOG) << "Chosen printer: " << it->printerName();
1819 delete d->m_printer;
1820 d->m_printer = new QPrinter(*it);
1821 }
1822 }
1823
1824 //d->m_printer->setPrinterName(text);
1825 d->m_printer->setOutputFormat(QPrinter::NativeFormat);
1826 }
1827
1828 //default no margins
1829 d->m_printer->setFullPage(true);
1830 d->m_printer->setPageMargins(0, 0, 0, 0, QPrinter::Millimeter);
1831 }
1832
updateCaption(TPhoto * pPhoto)1833 void Wizard::updateCaption(TPhoto* pPhoto)
1834 {
1835 if (pPhoto)
1836 {
1837 if (!pPhoto->pCaptionInfo && d->m_photoUi->m_captions->currentIndex() != CaptionInfo::NoCaptions)
1838 {
1839 pPhoto->pCaptionInfo = new CaptionInfo();
1840 }
1841 else if (pPhoto->pCaptionInfo && d->m_photoUi->m_captions->currentIndex() == CaptionInfo::NoCaptions)
1842 {
1843 delete pPhoto->pCaptionInfo;
1844 pPhoto->pCaptionInfo = nullptr;
1845 }
1846
1847 if (pPhoto->pCaptionInfo)
1848 {
1849 pPhoto->pCaptionInfo->m_caption_color = d->m_photoUi->m_font_color->color();
1850 pPhoto->pCaptionInfo->m_caption_size = d->m_photoUi->m_font_size->value();
1851 pPhoto->pCaptionInfo->m_caption_font = d->m_photoUi->m_font_name->currentFont();
1852 pPhoto->pCaptionInfo->m_caption_type = (CaptionInfo::AvailableCaptions)d->m_photoUi->m_captions->currentIndex();
1853 pPhoto->pCaptionInfo->m_caption_text = d->m_photoUi->m_FreeCaptionFormat->text();
1854 }
1855 }
1856 }
1857
infopage_updateCaptions()1858 void Wizard::infopage_updateCaptions()
1859 {
1860 if (d->m_photos.size())
1861 {
1862 if (d->m_photoUi->m_sameCaption->isChecked())
1863 {
1864 QList<TPhoto*>::iterator it;
1865
1866 for (it = d->m_photos.begin(); it != d->m_photos.end(); ++it)
1867 {
1868 TPhoto* const pPhoto = static_cast<TPhoto*>(*it);
1869 updateCaption(pPhoto);
1870 }
1871 }
1872 else
1873 {
1874 QList <QTreeWidgetItem*> list = d->m_imagesFilesListBox->listView()->selectedItems();
1875
1876 foreach(QTreeWidgetItem* const item, list)
1877 {
1878 KPImagesListViewItem* const lvItem = dynamic_cast<KPImagesListViewItem*>(item);
1879
1880 if (item)
1881 {
1882 int itemIndex = d->m_imagesFilesListBox->listView()->indexFromItem(lvItem).row();
1883 TPhoto* const pPhoto = d->m_photos.at(itemIndex);
1884 updateCaption(pPhoto);
1885 }
1886 }
1887 }
1888 }
1889
1890 // create our photo sizes list
1891 previewPhotos();
1892 }
1893
enableCaptionGroup(const QString & text)1894 void Wizard::enableCaptionGroup(const QString& text)
1895 {
1896 bool fontSettingsEnabled;
1897
1898 if (text == i18n("No captions"))
1899 {
1900 fontSettingsEnabled = false;
1901 d->m_photoUi->m_FreeCaptionFormat->setEnabled(false);
1902 d->m_photoUi->m_free_label->setEnabled(false);
1903 }
1904 else if (text == i18n("Free"))
1905 {
1906 fontSettingsEnabled = true;
1907 d->m_photoUi->m_FreeCaptionFormat->setEnabled(true);
1908 d->m_photoUi->m_free_label->setEnabled(true);
1909 }
1910 else
1911 {
1912 fontSettingsEnabled = true;
1913 d->m_photoUi->m_FreeCaptionFormat->setEnabled(false);
1914 d->m_photoUi->m_free_label->setEnabled(false);
1915 }
1916
1917 d->m_photoUi->m_font_name->setEnabled(fontSettingsEnabled);
1918 d->m_photoUi->m_font_size->setEnabled(fontSettingsEnabled);
1919 d->m_photoUi->m_font_color->setEnabled(fontSettingsEnabled);
1920 }
1921
captionChanged(const QString & text)1922 void Wizard::captionChanged(const QString& text)
1923 {
1924 enableCaptionGroup(text);
1925 infopage_updateCaptions();
1926 }
1927
BtnCropRotateLeft_clicked()1928 void Wizard::BtnCropRotateLeft_clicked()
1929 {
1930 // by definition, the cropRegion should be set by now,
1931 // which means that after our rotation it will become invalid,
1932 // so we will initialize it to -2 in an awful hack (this
1933 // tells the cropFrame to reset the crop region, but don't
1934 // automagically rotate the image to fit.
1935 TPhoto* const photo = d->m_photos[d->m_currentCropPhoto];
1936 photo->cropRegion = QRect(-2, -2, -2, -2);
1937 photo->rotation = (photo->rotation - 90) % 360;
1938
1939 updateCropFrame(photo, d->m_currentCropPhoto);
1940 }
1941
BtnCropRotateRight_clicked()1942 void Wizard::BtnCropRotateRight_clicked()
1943 {
1944 // by definition, the cropRegion should be set by now,
1945 // which means that after our rotation it will become invalid,
1946 // so we will initialize it to -2 in an awful hack (this
1947 // tells the cropFrame to reset the crop region, but don't
1948 // automagically rotate the image to fit.
1949 TPhoto* const photo = d->m_photos[d->m_currentCropPhoto];
1950 photo->cropRegion = QRect(-2, -2, -2, -2);
1951 photo->rotation = (photo->rotation + 90) % 360;
1952
1953 updateCropFrame(photo, d->m_currentCropPhoto);
1954 }
1955
setBtnCropEnabled()1956 void Wizard::setBtnCropEnabled()
1957 {
1958 if (d->m_currentCropPhoto == 0)
1959 d->m_cropUi->BtnCropPrev->setEnabled(false);
1960 else
1961 d->m_cropUi->BtnCropPrev->setEnabled(true);
1962
1963 if (d->m_currentCropPhoto == (int) d->m_photos.count() - 1)
1964 d->m_cropUi->BtnCropNext->setEnabled(false);
1965 else
1966 d->m_cropUi->BtnCropNext->setEnabled(true);
1967 }
1968
BtnCropNext_clicked()1969 void Wizard::BtnCropNext_clicked()
1970 {
1971 TPhoto* const photo = d->m_photos[++d->m_currentCropPhoto];
1972 setBtnCropEnabled();
1973
1974 if (!photo)
1975 {
1976 d->m_currentCropPhoto = d->m_photos.count() - 1;
1977 return;
1978 }
1979
1980 updateCropFrame(photo, d->m_currentCropPhoto);
1981 }
1982
BtnCropPrev_clicked()1983 void Wizard::BtnCropPrev_clicked()
1984 {
1985 TPhoto* const photo = d->m_photos[--d->m_currentCropPhoto];
1986
1987 setBtnCropEnabled();
1988
1989 if (!photo)
1990 {
1991 d->m_currentCropPhoto = 0;
1992 return;
1993 }
1994
1995 updateCropFrame(photo, d->m_currentCropPhoto);
1996 }
1997
BtnPrintOrderUp_clicked()1998 void Wizard::BtnPrintOrderUp_clicked()
1999 {
2000 d->m_imagesFilesListBox->blockSignals(true);
2001 int currentIndex = d->m_imagesFilesListBox->listView()->currentIndex().row();
2002
2003 qCDebug(KIPIPLUGINS_LOG) << "Moved photo " << currentIndex << " to " << currentIndex + 1;
2004
2005 d->m_photos.swap(currentIndex, currentIndex + 1);
2006 d->m_imagesFilesListBox->blockSignals(false);
2007 previewPhotos();
2008 }
2009
ListPhotoSizes_selected()2010 void Wizard::ListPhotoSizes_selected()
2011 {
2012 TPhotoSize* s = nullptr;
2013 QSizeF size, sizeManaged;
2014
2015 // TODO FREE STYLE
2016 // check if layout is managed by templates or free one
2017 // get the selected layout
2018 int curr = d->m_photoUi->ListPhotoSizes->currentRow();
2019 QListWidgetItem* item = d->m_photoUi->ListPhotoSizes->item(curr);
2020
2021 // if custom page layout we launch a dialog to choose what kind
2022 if (item->text() == i18n(customPageLayoutName))
2023 {
2024 // check if a custom layout has already been added
2025 if (curr >= 0 && curr < d->m_photoSizes.size())
2026 {
2027 s = d->m_photoSizes.at(curr);
2028 d->m_photoSizes.removeAt(curr);
2029 delete s;
2030 s = nullptr;
2031 }
2032
2033 CustomLayoutDlg custDlg(this);
2034 custDlg.readSettings();
2035 custDlg.exec();
2036 custDlg.saveSettings();
2037
2038 // get parameters from dialog
2039 size = d->m_pageSize;
2040 int scaleValue = 10; // 0.1 mm
2041
2042 // convert to mm
2043 if (custDlg.m_photoUnits->currentText() == i18n("inches"))
2044 {
2045 size /= 25.4;
2046 scaleValue = 1000;
2047 }
2048 else if (custDlg.m_photoUnits->currentText() == i18n("cm"))
2049 {
2050 size /= 10;
2051 scaleValue = 100;
2052 }
2053
2054 sizeManaged = size * scaleValue;
2055
2056 s = new TPhotoSize;
2057 TemplateIcon iconpreview(80, sizeManaged.toSize());
2058 iconpreview.begin();
2059
2060 if (custDlg.m_photoGridCheck->isChecked())
2061 {
2062 // custom photo grid
2063 int rows = custDlg.m_gridRows->value();
2064 int columns = custDlg.m_gridColumns->value();
2065
2066 s->layouts.append(new QRect(0, 0, (int)sizeManaged.width(), (int)sizeManaged.height()));
2067 s->autoRotate = custDlg.m_autorotate->isChecked();
2068 s->label = item->text();
2069 s->dpi = 0;
2070
2071 int pageWidth = (int)(size.width()) * scaleValue;
2072 int pageHeight = (int)(size.height()) * scaleValue;
2073 createPhotoGrid(s, pageWidth, pageHeight, rows, columns, &iconpreview);
2074 }
2075 else if (custDlg.m_fitAsManyCheck->isChecked())
2076 {
2077 int width = custDlg.m_photoWidth->value();
2078 int height = custDlg.m_photoHeight->value();
2079
2080 //photo size must be less than page size
2081 static const float round_value = 0.01F;
2082
2083 if ((height > (size.height() + round_value) || width > (size.width() + round_value)))
2084 {
2085 qCDebug(KIPIPLUGINS_LOG) << "photo size " << QSize(width, height) << "> page size " << size;
2086 delete s;
2087 s = nullptr;
2088 }
2089 else
2090 {
2091 // fit as many photos of given size as possible
2092 s->layouts.append(new QRect(0, 0, (int)sizeManaged.width(), (int)sizeManaged.height()));
2093 s->autoRotate = custDlg.m_autorotate->isChecked();
2094 s->label = item->text();
2095 s->dpi = 0;
2096 int nColumns = int(size.width() / width);
2097 int nRows = int(size.height() / height);
2098 int spareWidth = int(size.width()) % width;
2099
2100 // check if there's no room left to separate photos
2101 if (nColumns > 1 && spareWidth == 0)
2102 {
2103 nColumns -= 1;
2104 spareWidth = width;
2105 }
2106
2107 int spareHeight = int(size.height()) % height;
2108
2109 // check if there's no room left to separate photos
2110 if (nRows > 1 && spareHeight == 0)
2111 {
2112 nRows -= 1;
2113 spareHeight = height;
2114 }
2115
2116 if (nRows > 0 && nColumns > 0)
2117 {
2118 // n photos => dx1, photo1, dx2, photo2,... photoN, dxN+1
2119 int dx = spareWidth * scaleValue / (nColumns + 1);
2120 int dy = spareHeight * scaleValue / (nRows + 1);
2121 int photoX = 0;
2122 int photoY = 0;
2123 width *= scaleValue;
2124 height *= scaleValue;
2125
2126 for (int row = 0; row < nRows; ++row)
2127 {
2128 photoY = dy * (row + 1) + (row * height);
2129
2130 for (int col = 0; col < nColumns; ++col)
2131 {
2132 photoX = dx * (col + 1) + (col * width);
2133 qCDebug(KIPIPLUGINS_LOG) << "photo at P(" << photoX << ", " << photoY << ") size(" << width << ", " << height;
2134
2135 s->layouts.append(new QRect(photoX, photoY,
2136 width, height));
2137 iconpreview.fillRect(photoX, photoY, width, height, Qt::color1);
2138 }
2139 }
2140 }
2141 else
2142 {
2143 qCDebug(KIPIPLUGINS_LOG) << "I can't go on, rows " << nRows << "> columns " << nColumns;
2144 delete s;
2145 s = nullptr;
2146 }
2147 }
2148 }
2149 else
2150 {
2151 // Atckin's layout
2152 }
2153
2154 // TODO not for Atckin's layout
2155 iconpreview.end();
2156
2157 if (s)
2158 {
2159 s->icon = iconpreview.getIcon();
2160 d->m_photoSizes.append(s);
2161 }
2162 }
2163 else
2164 {
2165 s = d->m_photoSizes.at(curr);
2166 }
2167
2168 if (!s)
2169 {
2170 // change position to top
2171 d->m_photoUi->ListPhotoSizes->blockSignals(true);
2172 d->m_photoUi->ListPhotoSizes->setCurrentRow(0, QItemSelectionModel::Select);
2173 d->m_photoUi->ListPhotoSizes->blockSignals(false);
2174 }
2175
2176 // reset preview page number
2177 d->m_currentPreviewPage = 0;
2178 previewPhotos();
2179 }
2180
BtnPrintOrderDown_clicked()2181 void Wizard::BtnPrintOrderDown_clicked()
2182 {
2183 d->m_imagesFilesListBox->blockSignals(true);
2184 int currentIndex = d->m_imagesFilesListBox->listView()->currentIndex().row();
2185
2186 qCDebug(KIPIPLUGINS_LOG) << "Moved photo " << currentIndex - 1 << " to " << currentIndex;
2187
2188 d->m_photos.swap(currentIndex, currentIndex - 1);
2189 d->m_imagesFilesListBox->blockSignals(false);
2190 previewPhotos();
2191 }
2192
BtnPreviewPageDown_clicked()2193 void Wizard::BtnPreviewPageDown_clicked()
2194 {
2195 if (d->m_currentPreviewPage == 0)
2196 return;
2197
2198 d->m_currentPreviewPage--;
2199 previewPhotos();
2200 }
2201
BtnPreviewPageUp_clicked()2202 void Wizard::BtnPreviewPageUp_clicked()
2203 {
2204 if (d->m_currentPreviewPage == getPageCount() - 1)
2205 return;
2206
2207 d->m_currentPreviewPage++;
2208 previewPhotos();
2209 }
2210
BtnSaveAs_clicked()2211 void Wizard::BtnSaveAs_clicked()
2212 {
2213 qCDebug(KIPIPLUGINS_LOG) << "Save As Clicked";
2214 KConfig config ( QLatin1String("kipirc") );
2215 KConfigGroup group = config.group( QLatin1String( "PrintAssistant" ) );
2216 QUrl outputPath; // force to get current directory as default
2217 outputPath = QUrl(group.readPathEntry( "OutputPath", outputPath.url() ));
2218 QString filename = QFileDialog::getSaveFileName(qApp->activeWindow(), i18n("Output Path"), QLatin1String(".jpeg") );
2219 d->m_cropUi->m_fileName->setText(filename);
2220 }
2221
saveSettings(const QString & pageName)2222 void Wizard::saveSettings(const QString& pageName)
2223 {
2224 qCDebug(KIPIPLUGINS_LOG) << pageName;
2225
2226 // Save the current settings
2227 KConfig config(QLatin1String("kipirc"));
2228 KConfigGroup group = config.group(QLatin1String("PrintAssistant"));
2229
2230 if (pageName == i18n(photoPageName))
2231 {
2232 group.writeEntry(QLatin1String("Printer"), d->m_photoUi->m_printer_choice->currentText());
2233 // PhotoPage
2234 // photo size
2235 d->m_savedPhotoSize = d->m_photoUi->ListPhotoSizes->currentItem()->text();
2236 group.writeEntry(QLatin1String("PhotoSize"), d->m_savedPhotoSize);
2237 group.writeEntry(QLatin1String("IconSize"), d->m_photoUi->ListPhotoSizes->iconSize());
2238 }
2239 else if (pageName == i18n(cropPageName))
2240 {
2241 // CropPage
2242 if (d->m_photoUi->m_printer_choice->currentText() == i18n("Print to JPG"))
2243 {
2244 // output path
2245 QString outputPath = d->m_cropUi->m_fileName->text();
2246 group.writePathEntry(QLatin1String("OutputPath"), outputPath);
2247 }
2248 }
2249 }
2250
infopage_readCaptionSettings()2251 void Wizard::infopage_readCaptionSettings()
2252 {
2253 KConfig config(QLatin1String("kipirc"));
2254 KConfigGroup group = config.group(QLatin1String("PrintAssistant"));
2255
2256 // image captions
2257 d->m_photoUi->m_captions->setCurrentIndex(group.readEntry(QLatin1String("Captions"), 0));
2258 // caption color
2259 QColor defColor(Qt::yellow);
2260 QColor color = group.readEntry(QLatin1String("CaptionColor"), defColor);
2261 d->m_photoUi->m_font_color->setColor(color);
2262 // caption font
2263 QFont defFont(QLatin1String("Sans Serif"));
2264 QFont font = group.readEntry(QLatin1String("CaptionFont"), defFont);
2265 d->m_photoUi->m_font_name->setCurrentFont(font.family());
2266 // caption size
2267 int fontSize = group.readEntry(QLatin1String("CaptionSize"), 4);
2268 d->m_photoUi->m_font_size->setValue(fontSize);
2269 // free caption
2270 QString captionTxt = group.readEntry(QLatin1String("FreeCaption"));
2271 d->m_photoUi->m_FreeCaptionFormat->setText(captionTxt);
2272 }
2273
readSettings(const QString & pageName)2274 void Wizard::readSettings(const QString& pageName)
2275 {
2276 KConfig config(QLatin1String("kipirc"));
2277 KConfigGroup group = config.group(QLatin1String("PrintAssistant"));
2278
2279 qCDebug(KIPIPLUGINS_LOG) << pageName;
2280
2281 if (pageName == i18n(photoPageName))
2282 {
2283 // InfoPage
2284 QString printerName = group.readEntry("Printer", i18n("Print to PDF"));
2285 int index = d->m_photoUi->m_printer_choice->findText(printerName);
2286
2287 if (index != -1)
2288 {
2289 d->m_photoUi->m_printer_choice->setCurrentIndex(index);
2290 }
2291
2292 // init QPrinter
2293 outputChanged(d->m_photoUi->m_printer_choice->currentText());
2294
2295 QSize iconSize = group.readEntry("IconSize", QSize(24, 24));
2296 d->m_photoUi->ListPhotoSizes->setIconSize(iconSize);
2297
2298 // photo size
2299 d->m_savedPhotoSize = group.readEntry("PhotoSize");
2300 //caption
2301 initPhotoSizes(d->m_printer->paperSize(QPrinter::Millimeter));
2302 infopage_readCaptionSettings();
2303
2304 bool same_to_all = group.readEntry("SameCaptionToAll", 0) == 1;
2305 d->m_photoUi->m_sameCaption->setChecked(same_to_all);
2306 //enable right caption stuff
2307 captionChanged(d->m_photoUi->m_captions->currentText());
2308 }
2309 else if (pageName == i18n(cropPageName))
2310 {
2311 // CropPage
2312 if (d->m_photoUi->m_printer_choice->currentText() == i18n("Print to JPG"))
2313 {
2314 // set the last output path
2315 QUrl outputPath; // force to get current directory as default
2316 outputPath = QUrl(group.readPathEntry("OutputPath", outputPath.url()));
2317
2318 d->m_cropUi->m_fileName->setVisible(true);
2319 d->m_cropUi->m_fileName->setEnabled(true);
2320 d->m_cropUi->m_fileName->setText(outputPath.path());
2321 d->m_cropUi->BtnSaveAs->setVisible(true);
2322
2323 }
2324 else
2325 {
2326
2327 d->m_cropUi->m_fileName->setVisible(false);
2328 d->m_cropUi->BtnSaveAs->setVisible(false);
2329
2330 }
2331 }
2332 }
2333
printPhotos(const QList<TPhoto * > & photos,const QList<QRect * > & layouts,QPrinter & printer)2334 void Wizard::printPhotos(const QList<TPhoto*>& photos, const QList<QRect*>& layouts, QPrinter& printer)
2335 {
2336 d->m_cancelPrinting = false;
2337 QProgressDialog pbar(this);
2338 pbar.setRange(0, photos.count());
2339 QApplication::processEvents();
2340
2341 QPainter p;
2342 p.begin(&printer);
2343
2344 int current = 0;
2345 bool printing = true;
2346
2347 while (printing)
2348 {
2349 printing = paintOnePage(p, photos, layouts, current, d->m_cropUi->m_disableCrop->isChecked());
2350
2351 if (printing)
2352 printer.newPage();
2353
2354 pbar.setValue(current);
2355 QApplication::processEvents();
2356
2357 if (d->m_cancelPrinting)
2358 {
2359 printer.abort();
2360 return;
2361 }
2362 }
2363 p.end();
2364 }
2365
printPhotosToFile(const QList<TPhoto * > & photos,const QString & baseFilename,TPhotoSize * const layouts)2366 QStringList Wizard::printPhotosToFile(const QList<TPhoto*>& photos, const QString& baseFilename, TPhotoSize* const layouts)
2367 {
2368 Q_ASSERT(layouts->layouts.count() > 1);
2369
2370 d->m_cancelPrinting = false;
2371 QProgressDialog pbar(this);
2372 pbar.setRange(0, photos.count());
2373
2374 QApplication::processEvents();
2375
2376 int current = 0;
2377 int pageCount = 1;
2378 bool printing = true;
2379 QStringList files;
2380
2381 QRect* const srcPage = layouts->layouts.at(0);
2382
2383 while (printing)
2384 {
2385 // make a pixmap to save to file. Make it just big enough to show the
2386 // highest-dpi image on the page without losing data.
2387 double dpi = layouts->dpi;
2388
2389 if (dpi == 0.0)
2390 dpi = getMaxDPI(photos, layouts->layouts, current) * 1.1;
2391
2392 //int w = NINT(srcPage->width() / 1000.0 * dpi);
2393 //int h = NINT(srcPage->height() / 1000.0 * dpi);
2394 int w = NINT(srcPage->width());
2395 int h = NINT(srcPage->height());
2396
2397 QPixmap pixmap(w, h);
2398 QPainter painter;
2399 painter.begin(&pixmap);
2400
2401 // save this page out to file
2402 QFileInfo fi(baseFilename);
2403 QString ext = fi.completeSuffix(); // ext = ".jpeg"
2404 if (ext.isEmpty()) ext = QLatin1String(".jpeg");
2405 QString name = fi.baseName();
2406 QString path = fi.absolutePath();
2407
2408 QString filename = path + QLatin1String("/") + name + QLatin1String("_") + QString::number(pageCount) + QLatin1String(".") + ext;
2409 bool saveFile = true;
2410
2411 if (QFile::exists(filename))
2412 {
2413 int result = QMessageBox::question(this, i18n("Overwrite File"),
2414 i18n("The following file will be overwritten. Are you sure you want to overwrite it?") +
2415 QLatin1String("\n\n") + filename,
2416 QMessageBox::StandardButtons(QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel),
2417 QMessageBox::No);
2418
2419 if (result == QMessageBox::No)
2420 {
2421 saveFile = false;
2422 }
2423 else if (result == QMessageBox::Cancel)
2424 {
2425 break;
2426 }
2427 }
2428
2429 printing = paintOnePage(painter, photos, layouts->layouts, current, d->m_cropUi->m_disableCrop->isChecked());
2430 painter.end();
2431
2432 if (saveFile)
2433 {
2434 files.append(filename);
2435
2436 if (!pixmap.save(filename,nullptr,100))
2437 {
2438 QMessageBox::information(this, QString(), i18n("Could not save file, please check your output entry."));
2439 break;
2440 }
2441 }
2442
2443 pageCount++;
2444 pbar.setValue(current);
2445 QApplication::processEvents();
2446
2447 if (d->m_cancelPrinting)
2448 break;
2449 }
2450
2451 return files;
2452 }
2453
removeGimpFiles()2454 void Wizard::removeGimpFiles()
2455 {
2456 for (QStringList::ConstIterator it = d->m_gimpFiles.constBegin(); it != d->m_gimpFiles.constEnd(); ++it)
2457 {
2458 if (QFile::exists(*it))
2459 {
2460 if (QFile::remove(*it) == false)
2461 {
2462 QMessageBox::information(this, QString(), i18n("Could not remove the GIMP's temporary files."));
2463 break;
2464 }
2465 }
2466 }
2467 }
2468
2469 //TODO not needed at the moment maybe we can remove it
slotPageRemoved(int id)2470 void Wizard::slotPageRemoved(int id)
2471 {
2472 qCDebug(KIPIPLUGINS_LOG) << page(id)->title();
2473 }
2474
crop_selection(int)2475 void Wizard::crop_selection(int)
2476 {
2477 d->m_cropUi->cropFrame->drawCropRectangle(!d->m_cropUi->m_disableCrop->isChecked());
2478 update();
2479 }
2480
2481 // this is called when Cancel is clicked.
reject()2482 void Wizard::reject()
2483 {
2484 d->m_cancelPrinting = true;
2485
2486 if (d->m_gimpFiles.count() > 0)
2487 removeGimpFiles();
2488
2489 QDialog::reject();
2490 }
2491
accept()2492 void Wizard::accept()
2493 {
2494 if (d->m_photos.empty())
2495 {
2496 KPWizardDialog::reject();
2497 return;
2498 }
2499
2500 // set the default crop regions if not already set
2501 TPhotoSize* const s = d->m_photoSizes.at(d->m_photoUi->ListPhotoSizes->currentRow());
2502 QList<TPhoto*>::iterator it;
2503 int i = 0;
2504
2505 for (it = d->m_photos.begin(); it != d->m_photos.end(); ++it)
2506 {
2507 TPhoto* const photo = static_cast<TPhoto* >(*it);
2508
2509 if (photo && photo->cropRegion == QRect(-1, -1, -1, -1))
2510 d->m_cropUi->cropFrame->init(photo, getLayout(i)->width(), getLayout(i)->height(), s->autoRotate);
2511
2512 i++;
2513 }
2514
2515 if (d->m_photoUi->m_printer_choice->currentText() != i18n("Print to JPG") &&
2516 d->m_photoUi->m_printer_choice->currentText() != i18n("Print to gimp"))
2517 {
2518 // tell him again!
2519 d->m_printer->setFullPage(true);
2520
2521 qreal left, top, right, bottom;
2522 d->m_printer->getPageMargins(&left, &top, &right, &bottom, QPrinter::Millimeter);
2523
2524 qCDebug(KIPIPLUGINS_LOG) << "Margins before print dialog: left " << left
2525 << " right " << right << " top " << top << " bottom " << bottom;
2526 qCDebug(KIPIPLUGINS_LOG) << "(1) paper page " << d->m_printer->paperSize() << " size " << d->m_printer->paperSize(QPrinter::Millimeter);
2527
2528 QPrinter::PaperSize paperSize = d->m_printer->paperSize();
2529
2530 QPrintDialog* const dialog = new QPrintDialog(d->m_printer, this);
2531 dialog->setWindowTitle(i18n("Print assistant"));
2532
2533 qCDebug(KIPIPLUGINS_LOG) << "(2) paper page " << dialog->printer()->paperSize() << " size " << dialog->printer()->paperSize(QPrinter::Millimeter);
2534
2535 bool wantToPrint = (dialog->exec() == QDialog::Accepted);
2536
2537 if (!wantToPrint)
2538 {
2539 KPWizardDialog::accept();
2540 return;
2541 }
2542
2543 qCDebug(KIPIPLUGINS_LOG) << "(3) paper page " << dialog->printer()->paperSize() << " size " << dialog->printer()->paperSize(QPrinter::Millimeter);
2544
2545 // Why paperSize changes if printer properties is not pressed?
2546 if (paperSize != d->m_printer->paperSize())
2547 d->m_printer->setPaperSize(paperSize);
2548
2549 qCDebug(KIPIPLUGINS_LOG) << "(4) paper page " << dialog->printer()->paperSize() << " size " << dialog->printer()->paperSize(QPrinter::Millimeter);
2550
2551 dialog->printer()->getPageMargins(&left, &top, &right, &bottom, QPrinter::Millimeter);
2552
2553 qCDebug(KIPIPLUGINS_LOG) << "Dialog exit, new margins: left " << left
2554 << " right " << right << " top " << top << " bottom " << bottom;
2555
2556 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
2557 printPhotos(d->m_photos, s->layouts, *d->m_printer);
2558 QApplication::restoreOverrideCursor();
2559 }
2560 else if (d->m_photoUi->m_printer_choice->currentText() == i18n("Print to gimp"))
2561 {
2562 // now output the items
2563 QString path = d->m_tempPath;
2564
2565 if (!checkTempPath(this, path))
2566 return;
2567
2568 path = path + QLatin1String("kipi_tmp_");
2569
2570 if (d->m_gimpFiles.count() > 0)
2571 removeGimpFiles();
2572
2573 d->m_gimpFiles = printPhotosToFile(d->m_photos, path, s);
2574 QStringList args;
2575 QString prog = QLatin1String("gimp-remote");
2576
2577 for (QStringList::ConstIterator it = d->m_gimpFiles.constBegin(); it != d->m_gimpFiles.constEnd(); ++it)
2578 args << (*it);
2579
2580 if (!launchExternalApp(prog, args))
2581 {
2582 QMessageBox::information(this, QString(),
2583 i18n("There was an error launching the GIMP. Please make sure it is properly installed."));
2584 return;
2585 }
2586 }
2587 else if (d->m_photoUi->m_printer_choice->currentText() == i18n("Print to JPG"))
2588 {
2589 // now output the items
2590 //TODO manage URL
2591 QString path = d->m_cropUi->m_fileName->text();
2592
2593 if (path.isEmpty())
2594 {
2595 QMessageBox::information(this, QString(), i18n("Empty output path."));
2596 return;
2597 }
2598
2599 qCDebug(KIPIPLUGINS_LOG) << path;
2600 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
2601 printPhotosToFile(d->m_photos, path, s);
2602 QApplication::restoreOverrideCursor();
2603 }
2604
2605 saveSettings(currentPage()->title());
2606 KPWizardDialog::accept();
2607 }
2608
pagesetupdialogexit()2609 void Wizard::pagesetupdialogexit()
2610 {
2611 QPrinter* const printer = d->m_pDlg->printer();
2612
2613 qCDebug(KIPIPLUGINS_LOG) << "Dialog exit, new size " << printer->paperSize(QPrinter::Millimeter)
2614 << " internal size " << d->m_printer->paperSize(QPrinter::Millimeter);
2615
2616 qreal left, top, right, bottom;
2617 d->m_printer->getPageMargins(&left, &top, &right, &bottom, QPrinter::Millimeter);
2618
2619 qCDebug(KIPIPLUGINS_LOG) << "Dialog exit, new margins: left " << left
2620 << " right " << right << " top " << top << " bottom " << bottom;
2621
2622 // next should be useless invoke once changing wizard page
2623 //initPhotoSizes ( d->m_printer.paperSize(QPrinter::Millimeter));
2624
2625 // d->m_pageSize = d->m_printer.paperSize(QPrinter::Millimeter);
2626 #ifdef NOT_YET
2627 qCDebug(KIPIPLUGINS_LOG) << " dialog exited num of copies: " << printer->numCopies()
2628 << " inside: " << d->m_printer->numCopies();
2629
2630 qCDebug(KIPIPLUGINS_LOG) << " dialog exited from : " << printer->fromPage()
2631 << " to: " << d->m_printer->toPage();
2632 #endif
2633 }
2634
pagesetupclicked()2635 void Wizard::pagesetupclicked()
2636 {
2637 delete d->m_pDlg;
2638 d->m_pDlg = new QPageSetupDialog(d->m_printer, this);
2639 // TODO next line should work but it doesn't because of a QT bug
2640 //d->m_pDlg->open(this, SLOT(pagesetupdialogexit()));
2641 int ret = d->m_pDlg->exec();
2642
2643 if (ret == QDialog::Accepted)
2644 {
2645 pagesetupdialogexit();
2646 }
2647
2648 // FIX page size dialog and preview PhotoPage
2649 initPhotoSizes(d->m_printer->paperSize(QPrinter::Millimeter));
2650
2651 // restore photoSize
2652 if (d->m_savedPhotoSize == i18n(customPageLayoutName))
2653 {
2654 d->m_photoUi->ListPhotoSizes->setCurrentRow(0);
2655 }
2656 else
2657 {
2658 QList<QListWidgetItem*> list = d->m_photoUi->ListPhotoSizes->findItems(d->m_savedPhotoSize, Qt::MatchExactly);
2659
2660 if (list.count())
2661 d->m_photoUi->ListPhotoSizes->setCurrentItem(list[0]);
2662 else
2663 d->m_photoUi->ListPhotoSizes->setCurrentRow(0);
2664 }
2665
2666 // create our photo sizes list
2667 previewPhotos();
2668 }
2669
infopage_blockCaptionButtons(bool block)2670 void Wizard::infopage_blockCaptionButtons(bool block)
2671 {
2672 d->m_photoUi->m_captions->blockSignals(block);
2673 d->m_photoUi->m_free_label->blockSignals(block);
2674 d->m_photoUi->m_sameCaption->blockSignals(block);
2675 d->m_photoUi->m_font_name->blockSignals(block);
2676 d->m_photoUi->m_font_size->blockSignals(block);
2677 d->m_photoUi->m_font_color->blockSignals(block);
2678 }
2679
saveCaptionSettings()2680 void Wizard::saveCaptionSettings()
2681 {
2682 // Save the current settings
2683 KConfig config(QLatin1String("kipirc"));
2684 KConfigGroup group = config.group(QLatin1String("PrintAssistant"));
2685 // image captions
2686 group.writeEntry(QLatin1String("Captions"), d->m_photoUi->m_captions->currentIndex());
2687 // caption color
2688 group.writeEntry(QLatin1String("CaptionColor"), d->m_photoUi->m_font_color->color());
2689 // caption font
2690 group.writeEntry(QLatin1String("CaptionFont"), QFont(d->m_photoUi->m_font_name->currentFont()));
2691 // caption size
2692 group.writeEntry(QLatin1String("CaptionSize"), d->m_photoUi->m_font_size->value());
2693 // free caption
2694 group.writeEntry(QLatin1String("FreeCaption"), d->m_photoUi->m_FreeCaptionFormat->text());
2695 // same to all
2696 group.writeEntry(QLatin1String("SameCaptionToAll"), (d->m_photoUi->m_sameCaption->isChecked() ? 1 : 0));
2697 }
2698
2699 } // namespace KIPIPrintImagesPlugin
2700