1 /* ============================================================
2 *
3 * This file is a part of KDE project
4 *
5 *
6 * Date : 2010-11-15
7 * Description : a kipi plugin to export images to Yandex.Fotki web service
8 *
9 * Copyright (C) 2010 by Roman Tsisyk <roman at tsisyk dot com>
10 *
11 * GUI based on PicasaWeb KIPI Plugin
12 * Copyright (C) 2005-2008 by Vardhman Jain <vardhman at gmail dot com>
13 * Copyright (C) 2008-2018 by Gilles Caulier <caulier dot gilles at gmail dot com>
14 * Copyright (C) 2009 by Luka Renko <lure at kubuntu dot org>
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 "yfwindow.h"
29
30 // Qt includes
31
32 #include <QButtonGroup>
33 #include <QCheckBox>
34 #include <QCloseEvent>
35 #include <QFileInfo>
36 #include <QGridLayout>
37 #include <QGroupBox>
38 #include <QHBoxLayout>
39 #include <QLabel>
40 #include <QProgressBar>
41 #include <QRadioButton>
42 #include <QSpinBox>
43 #include <QVBoxLayout>
44 #include <QMenu>
45 #include <QComboBox>
46 #include <QApplication>
47 #include <QMessageBox>
48
49 // KDE includes
50
51 #include <kconfig.h>
52 #include <kconfiggroup.h>
53 #include <klocalizedstring.h>
54
55 // Libkipi includes
56
57 #include <KIPI/Interface>
58 #include <KIPI/UploadWidget>
59 #include <KIPI/ImageCollection>
60
61 // Local includes
62
63 #include "kpaboutdata.h"
64 #include "kpimageinfo.h"
65 #include "kpversion.h"
66 #include "kpimageslist.h"
67 #include "yftalker.h"
68 #include "yfalbumdialog.h"
69 #include "kipiplugins_debug.h"
70 #include "kputil.h"
71 #include "kplogindialog.h"
72 #include "yfwidget.h"
73
74 using namespace KIPI;
75
76 namespace KIPIYandexFotkiPlugin
77 {
78
79 /*
80 * This tag added to our images after uploading to Fotki web service
81 */
82 const char* YandexFotkiWindow::XMP_SERVICE_ID = "Xmp.kipi.yandexGPhotoId";
83
YandexFotkiWindow(bool import,QWidget * const parent)84 YandexFotkiWindow::YandexFotkiWindow(bool import, QWidget* const parent)
85 : KPToolDialog(parent)
86 {
87 m_import = import;
88 m_tmpDir = makeTemporaryDir("yandexfotki").absolutePath() + QLatin1Char('/');
89 m_widget = new YandexFotkiWidget(this, iface(), QString::fromLatin1("Yandex.Fotki"));
90
91 m_loginLabel = m_widget->getUserNameLabel();
92 m_headerLabel = m_widget->getHeaderLbl();
93 m_changeUserButton = m_widget->getChangeUserBtn();
94 m_newAlbumButton = m_widget->getNewAlbmBtn();
95 m_reloadAlbumsButton = m_widget->getReloadBtn();
96 m_albumsCombo = m_widget->getAlbumsCoB();
97 m_resizeCheck = m_widget->getResizeCheckBox();
98 m_dimensionSpin = m_widget->getDimensionSpB();
99 m_imageQualitySpin = m_widget->getImgQualitySpB();
100 m_imgList = m_widget->imagesList();
101 m_progressBar = m_widget->progressBar();
102 m_accessCombo = m_widget->m_accessCombo;
103 m_hideOriginalCheck = m_widget->m_hideOriginalCheck;
104 m_disableCommentsCheck = m_widget->m_disableCommentsCheck;
105 m_adultCheck = m_widget->m_adultCheck;
106 m_policyGroup = m_widget->m_policyGroup;
107 m_albumsBox = m_widget->getAlbumBox();
108 m_meta = nullptr;
109
110 if (iface())
111 {
112 m_meta = iface()->createMetadataProcessor();
113 }
114
115 connect(m_changeUserButton, SIGNAL(clicked()),
116 this, SLOT(slotChangeUserClicked()));
117
118 connect(m_newAlbumButton, SIGNAL(clicked()),
119 this, SLOT(slotNewAlbumRequest()) );
120
121
122 connect(m_reloadAlbumsButton, SIGNAL(clicked()),
123 this, SLOT(slotReloadAlbumsRequest()) );
124
125 setMainWidget(m_widget);
126 m_widget->setMinimumSize(800, 600);
127
128 KPAboutData* const about = new KPAboutData(ki18n("Yandex.Fotki Plugin"),
129 ki18n("A tool to export image collections to "
130 "Yandex.Fotki web service."),
131 ki18n("(c) 2007-2009, Vardhman Jain\n"
132 "(c) 2008-2015, Gilles Caulier\n"
133 "(c) 2009, Luka Renko\n"
134 "(c) 2010, Roman Tsisyk"));
135
136 about->addAuthor(ki18n( "Roman Tsisyk" ).toString(),
137 ki18n("Author").toString(),
138 QString::fromLatin1("roman at tsisyk dot com"));
139
140 about->setHandbookEntry(QString::fromLatin1("tool-yandexfotkiexport"));
141 setAboutData(about);
142
143 // -- UI slots -----------------------------------------------------------------------
144
145 connect(startButton(), &QPushButton::clicked,
146 this, &YandexFotkiWindow::slotStartTransfer);
147
148 connect(this, &KPToolDialog::cancelClicked,
149 this, &YandexFotkiWindow::slotCancelClicked);
150
151 connect(this, &QDialog::finished,
152 this, &YandexFotkiWindow::slotFinished);
153
154 // -- Talker slots -------------------------------------------------------------------
155
156 connect(&m_talker, SIGNAL(signalError()),
157 this, SLOT(slotError()));
158
159 connect(&m_talker, SIGNAL(signalGetSessionDone()),
160 this, SLOT(slotGetSessionDone()));
161
162 connect(&m_talker, SIGNAL(signalGetTokenDone()),
163 this, SLOT(slotGetTokenDone()));
164
165 connect(&m_talker, SIGNAL(signalGetServiceDone()),
166 this, SLOT(slotGetServiceDone()));
167
168 connect(&m_talker, SIGNAL(signalListAlbumsDone(QList<YandexFotkiAlbum>)),
169 this, SLOT(slotListAlbumsDone(QList<YandexFotkiAlbum>)));
170
171 connect(&m_talker, SIGNAL(signalListPhotosDone(QList<YandexFotkiPhoto>)),
172 this, SLOT(slotListPhotosDone(QList<YandexFotkiPhoto>)));
173
174 connect(&m_talker, SIGNAL(signalUpdatePhotoDone(YandexFotkiPhoto&)),
175 this, SLOT(slotUpdatePhotoDone(YandexFotkiPhoto&)));
176
177 connect(&m_talker, SIGNAL(signalUpdateAlbumDone()),
178 this, SLOT(slotUpdateAlbumDone()));
179
180 // read settings from file
181 readSettings();
182 }
183
~YandexFotkiWindow()184 YandexFotkiWindow::~YandexFotkiWindow()
185 {
186 reset();
187 }
188
reactivate()189 void YandexFotkiWindow::reactivate()
190 {
191 m_imgList->loadImagesFromCurrentSelection();
192
193 reset();
194 authenticate(false);
195 show();
196 }
197
reset()198 void YandexFotkiWindow::reset()
199 {
200 m_talker.reset();
201 updateControls(true);
202 updateLabels();
203 }
204
updateControls(bool val)205 void YandexFotkiWindow::updateControls(bool val)
206 {
207 if (val)
208 {
209 if (m_talker.isAuthenticated())
210 {
211 m_albumsBox->setEnabled(true);
212 startButton()->setEnabled(true);
213 }
214 else
215 {
216 m_albumsBox->setEnabled(false);
217 startButton()->setEnabled(false);
218 }
219
220 m_changeUserButton->setEnabled(true);
221 setCursor(Qt::ArrowCursor);
222
223 setRejectButtonMode(QDialogButtonBox::Close);
224 }
225 else
226 {
227 setCursor(Qt::WaitCursor);
228 m_albumsBox->setEnabled(false);
229 m_changeUserButton->setEnabled(false);
230 startButton()->setEnabled(false);
231
232 setRejectButtonMode(QDialogButtonBox::Cancel);
233 }
234 }
235
updateLabels()236 void YandexFotkiWindow::updateLabels()
237 {
238 QString urltext;
239 QString logintext;
240
241 if (m_talker.isAuthenticated())
242 {
243 logintext = m_talker.login();
244 urltext = YandexFotkiTalker::USERPAGE_URL.arg(m_talker.login());
245 m_albumsBox->setEnabled(true);
246 }
247 else
248 {
249 logintext = i18n("Unauthorized");
250 urltext = YandexFotkiTalker::USERPAGE_DEFAULT_URL;
251 m_albumsCombo->clear();
252 }
253
254 m_loginLabel->setText(QString::fromLatin1("<b>%1</b>").arg(logintext));
255 m_headerLabel->setText(QString::fromLatin1(
256 "<b><h2><a href=\"%1\">"
257 "<font color=\"#ff000a\">%2</font>"
258 "<font color=\"black\">%3</font>"
259 "<font color=\"#009d00\">%4</font>"
260 "</a></h2></b>")
261 .arg(urltext)
262 .arg(i18nc("Yandex.Fotki", "Y"))
263 .arg(i18nc("Yandex.Fotki", "andex."))
264 .arg(i18nc("Yandex.Fotki", "Fotki")));
265 }
266
readSettings()267 void YandexFotkiWindow::readSettings()
268 {
269 KConfig config(QString::fromLatin1("kipirc"));
270 KConfigGroup grp = config.group("YandexFotki Settings");
271
272 m_talker.setLogin(grp.readEntry("login", ""));
273 // don't store tokens in plaintext
274 //m_talker.setToken(grp.readEntry("token", ""));
275
276 if (grp.readEntry("Resize", false))
277 {
278 m_resizeCheck->setChecked(true);
279 m_dimensionSpin->setEnabled(true);
280 m_imageQualitySpin->setEnabled(true);
281 }
282 else
283 {
284 m_resizeCheck->setChecked(false);
285 m_dimensionSpin->setEnabled(false);
286 m_imageQualitySpin->setEnabled(false);
287 }
288
289 m_dimensionSpin->setValue(grp.readEntry("Maximum Width", 1600));
290 m_imageQualitySpin->setValue(grp.readEntry("Image Quality", 85));
291 m_policyGroup->button(grp.readEntry("Sync policy", 0))->setChecked(true);
292 }
293
writeSettings()294 void YandexFotkiWindow::writeSettings()
295 {
296 KConfig config(QString::fromLatin1("kipirc"));
297 KConfigGroup grp = config.group("YandexFotki Settings");
298
299 grp.writeEntry("token", m_talker.token());
300 // don't store tokens in plaintext
301 //grp.writeEntry("login", m_talker.login());
302
303 grp.writeEntry("Resize", m_resizeCheck->isChecked());
304 grp.writeEntry("Maximum Width", m_dimensionSpin->value());
305 grp.writeEntry("Image Quality", m_imageQualitySpin->value());
306 grp.writeEntry("Sync policy", m_policyGroup->checkedId());
307 }
308
slotChangeUserClicked()309 void YandexFotkiWindow::slotChangeUserClicked()
310 {
311 // force authenticate window
312 authenticate(true);
313 }
314
closeEvent(QCloseEvent * e)315 void YandexFotkiWindow::closeEvent(QCloseEvent* e)
316 {
317 if (!e)
318 {
319 return;
320 }
321
322 slotFinished();
323 e->accept();
324 }
325
slotFinished()326 void YandexFotkiWindow::slotFinished()
327 {
328 writeSettings();
329 reset();
330 }
331
slotCancelClicked()332 void YandexFotkiWindow::slotCancelClicked()
333 {
334 m_talker.cancel();
335 updateControls(true);
336 }
337
338 /*
339 void YandexFotkiWindow::cancelProcessing()
340 {
341 m_talker.cancel();
342 m_transferQueue.clear();
343 m_imgList->processed(false);
344 progressBar()->hide();
345 }
346 */
347
authenticate(bool forceAuthWindow)348 void YandexFotkiWindow::authenticate(bool forceAuthWindow)
349 {
350 // update credentials
351 if (forceAuthWindow || m_talker.login().isNull() || m_talker.password().isNull())
352 {
353 KPLoginDialog* const dlg = new KPLoginDialog(this, QString::fromLatin1("Yandex.Fotki"), m_talker.login(), QString());
354
355 if (dlg->exec() == QDialog::Accepted)
356 {
357 m_talker.setLogin(dlg->login());
358 m_talker.setPassword(dlg->password());
359 }
360 else
361 {
362 // don't change anything
363 return;
364 }
365
366 delete dlg;
367 }
368
369 /*else
370 {
371 qCDebug(KIPIPLUGINS_LOG) << "Checking old token...";
372 m_talker.checkToken();
373 return;
374 }
375 */
376
377 // if new credentials non-empty, authenticate
378 if (!m_talker.login().isEmpty() && !m_talker.password().isEmpty())
379 {
380 // cancel all tasks first
381 reset();
382
383 // start authentication chain
384 updateControls(false);
385 m_talker.getService();
386 }
387 else
388 {
389 // we don't have valid credentials, so cancel all transfers and reset
390 reset();
391 }
392
393 /*
394 progressBar()->show();
395 progressBar()->setFormat("");
396 */
397 }
398
slotListPhotosDone(const QList<YandexFotkiPhoto> & photosList)399 void YandexFotkiWindow::slotListPhotosDone(const QList <YandexFotkiPhoto>& photosList)
400 {
401 if (m_import)
402 {
403 slotListPhotosDoneForDownload(photosList);
404 }
405 else
406 {
407 slotListPhotosDoneForUpload(photosList);
408 }
409 }
410
slotListPhotosDoneForDownload(const QList<YandexFotkiPhoto> & photosList)411 void YandexFotkiWindow::slotListPhotosDoneForDownload(const QList <YandexFotkiPhoto>& photosList)
412 {
413 Q_UNUSED(photosList);
414 updateControls(true);
415 }
416
slotListPhotosDoneForUpload(const QList<YandexFotkiPhoto> & photosList)417 void YandexFotkiWindow::slotListPhotosDoneForUpload(const QList <YandexFotkiPhoto>& photosList)
418 {
419 updateControls(true);
420
421 QMap<QString, int> dups;
422 int i = 0;
423
424 foreach(const YandexFotkiPhoto& photo, photosList)
425 {
426 dups.insert(photo.urn(), i);
427 i++;
428 }
429
430 YandexFotkiWidget::UpdatePolicy policy = static_cast<YandexFotkiWidget::UpdatePolicy>(m_policyGroup->checkedId());
431 const YandexFotkiPhoto::Access access = static_cast<YandexFotkiPhoto::Access>(
432 m_accessCombo->itemData(m_accessCombo->currentIndex()).toInt());
433
434 qCDebug(KIPIPLUGINS_LOG) << "";
435 qCDebug(KIPIPLUGINS_LOG) << "----";
436 m_transferQueue.clear();
437
438 foreach(const QUrl& url, m_imgList->imageUrls(true))
439 {
440 KPImageInfo info(url);
441
442 // check if photo alredy uploaded
443
444 int oldPhotoId = -1;
445
446 if (m_meta && m_meta->load(url))
447 {
448 QString localId = m_meta->getXmpTagString(QLatin1String(XMP_SERVICE_ID));
449 oldPhotoId = dups.value(localId, -1);
450 }
451
452 // get tags
453 QStringList tags = info.tagsPath();
454 bool updateFile = true;
455
456 QSet<QString> oldtags;
457
458 if (oldPhotoId != -1)
459 {
460 if (policy == YandexFotkiWidget::UpdatePolicy::POLICY_SKIP)
461 {
462 qCDebug(KIPIPLUGINS_LOG) << "SKIP: " << url;
463 continue;
464 }
465
466 // old photo copy
467 m_transferQueue.push(photosList[oldPhotoId]);
468
469 if (policy == YandexFotkiWidget::UpdatePolicy::POLICY_UPDATE_MERGE)
470 {
471 foreach(const QString& t, m_transferQueue.top().tags)
472 {
473 oldtags.insert(t);
474 }
475 }
476
477 if (policy != YandexFotkiWidget::UpdatePolicy::POLICY_ADDNEW)
478 {
479 updateFile = false;
480 }
481 }
482 else
483 {
484 // empty photo
485 m_transferQueue.push(YandexFotkiPhoto());
486 }
487
488 YandexFotkiPhoto& photo = m_transferQueue.top();
489 // TODO: updateFile is not used
490 photo.setOriginalUrl(url.toLocalFile());
491 photo.setTitle(info.name());
492 photo.setSummary(info.description());
493 photo.setAccess(access);
494 photo.setHideOriginal(m_hideOriginalCheck->isChecked());
495 photo.setDisableComments(m_disableCommentsCheck->isChecked());
496
497 // adult flag can't be removed, API restrictions
498 if (!photo.isAdult())
499 photo.setAdult(m_adultCheck->isChecked());
500
501 foreach(const QString& t, tags)
502 {
503 if (!oldtags.contains(t))
504 {
505 photo.tags.append(t);
506 }
507 }
508
509 if (updateFile)
510 {
511 qCDebug(KIPIPLUGINS_LOG) << "METADATA + IMAGE: " << url;
512 }
513 else
514 {
515 qCDebug(KIPIPLUGINS_LOG) << "METADATA: " << url;
516 }
517 }
518
519 if (m_transferQueue.isEmpty())
520 {
521 return; // nothing to do
522 }
523
524 qCDebug(KIPIPLUGINS_LOG) << "----";
525 qCDebug(KIPIPLUGINS_LOG) << "";
526
527 updateControls(false);
528 updateNextPhoto();
529 }
530
updateNextPhoto()531 void YandexFotkiWindow::updateNextPhoto()
532 {
533 // select only one image from stack
534 while (!m_transferQueue.isEmpty())
535 {
536 YandexFotkiPhoto& photo = m_transferQueue.top();
537
538 if (!photo.originalUrl().isNull())
539 {
540 QImage image;
541
542 if (iface())
543 {
544 image = iface()->preview(QUrl::fromLocalFile(photo.originalUrl()));
545 }
546
547 if (image.isNull())
548 {
549 image.load(photo.originalUrl());
550 }
551
552 photo.setLocalUrl(m_tmpDir + QFileInfo(photo.originalUrl())
553 .baseName()
554 .trimmed() + QString::fromLatin1(".jpg"));
555
556 bool prepared = false;
557
558 if (!image.isNull())
559 {
560 // get temporary file name
561
562 // rescale image if requested
563 int maxDim = m_dimensionSpin->value();
564
565 if (m_resizeCheck->isChecked() && (image.width() > maxDim || image.height() > maxDim))
566 {
567 qCDebug(KIPIPLUGINS_LOG) << "Resizing to " << maxDim;
568 image = image.scaled(maxDim, maxDim, Qt::KeepAspectRatio,
569 Qt::SmoothTransformation);
570 }
571
572 // copy meta data to temporary image
573
574 if (image.save(photo.localUrl(), "JPEG", m_imageQualitySpin->value()))
575 {
576 if (m_meta && m_meta->load(QUrl::fromLocalFile(photo.originalUrl())))
577 {
578 m_meta->setImageDimensions(image.size());
579 m_meta->setImageOrientation(MetadataProcessor::NORMAL);
580 m_meta->setImageProgramId(QString::fromLatin1("Kipi-plugins"), kipipluginsVersion());
581 m_meta->save(QUrl::fromLocalFile(photo.localUrl()), true);
582 prepared = true;
583 }
584 }
585 }
586
587 if (!prepared)
588 {
589 if (QMessageBox::question(this, i18n("Processing Failed"),
590 i18n("Failed to prepare image %1\n"
591 "Do you want to continue?", photo.originalUrl()))
592 != QMessageBox::Yes)
593 {
594 // stop uploading
595 m_transferQueue.clear();
596 continue;
597 }
598 else
599 {
600 m_transferQueue.pop();
601 continue;
602 }
603 }
604 }
605
606 const YandexFotkiAlbum& album = m_talker.albums().at(m_albumsCombo->currentIndex());
607
608 qCDebug(KIPIPLUGINS_LOG) << photo.originalUrl();
609
610 m_talker.updatePhoto(photo, album);
611
612 return;
613 }
614
615 updateControls(true);
616
617 QMessageBox::information(this, QString(), i18n("Images have been uploaded"));
618 return;
619 }
620
slotNewAlbumRequest()621 void YandexFotkiWindow::slotNewAlbumRequest()
622 {
623 YandexFotkiAlbum album;
624 QPointer<YandexFotkiAlbumDialog> dlg = new YandexFotkiAlbumDialog(this, album);
625
626 if (dlg->exec() == QDialog::Accepted)
627 {
628 updateControls(false);
629 m_talker.updateAlbum(album);
630 }
631
632 delete dlg;
633 }
634
slotReloadAlbumsRequest()635 void YandexFotkiWindow::slotReloadAlbumsRequest()
636 {
637 updateControls(false);
638 m_talker.listAlbums();
639 }
640
slotStartTransfer()641 void YandexFotkiWindow::slotStartTransfer()
642 {
643 qCDebug(KIPIPLUGINS_LOG) << "slotStartTransfer invoked";
644
645 if (m_albumsCombo->currentIndex() == -1 || m_albumsCombo->count() == 0)
646 {
647 QMessageBox::information(this, QString(), i18n("Please select album first"));
648 return;
649 }
650
651 // TODO: import support
652 if (!m_import)
653 {
654 // list photos of the album, then start upload
655 const YandexFotkiAlbum& album = m_talker.albums().at(m_albumsCombo->currentIndex());
656
657 qCDebug(KIPIPLUGINS_LOG) << "Album selected" << album;
658
659 updateControls(false);
660 m_talker.listPhotos(album);
661 }
662 }
663
slotError()664 void YandexFotkiWindow::slotError()
665 {
666 switch (m_talker.state())
667 {
668 case YandexFotkiTalker::STATE_GETSESSION_ERROR:
669 QMessageBox::critical(this, QString(), i18n("Session error"));
670 break;
671 case YandexFotkiTalker::STATE_GETTOKEN_ERROR:
672 QMessageBox::critical(this, QString(), i18n("Token error"));
673 break;
674 case YandexFotkiTalker::STATE_INVALID_CREDENTIALS:
675 QMessageBox::critical(this, QString(), i18n("Invalid credentials"));
676 // authenticate(true);
677 break;
678 case YandexFotkiTalker::STATE_GETSERVICE_ERROR:
679 QMessageBox::critical(this, QString(), i18n("Cannot get service document"));
680 break;
681 /*
682 case YandexFotkiTalker::STATE_CHECKTOKEN_INVALID:
683 // remove old expired token
684 qCDebug(KIPIPLUGINS_LOG) << "CheckToken invalid";
685 m_talker.setToken(QString());
686 // don't say anything, simple show new auth window
687 authenticate(true);
688 break;
689 */
690 case YandexFotkiTalker::STATE_LISTALBUMS_ERROR:
691 m_albumsCombo->clear();
692 QMessageBox::critical(this, QString(), i18n("Cannot list albums"));
693 break;
694 case YandexFotkiTalker::STATE_LISTPHOTOS_ERROR:
695 QMessageBox::critical(this, QString(), i18n("Cannot list photos"));
696 break;
697 case YandexFotkiTalker::STATE_UPDATEALBUM_ERROR:
698 QMessageBox::critical(this, QString(), i18n("Cannot update album info"));
699 break;
700 case YandexFotkiTalker::STATE_UPDATEPHOTO_FILE_ERROR:
701 case YandexFotkiTalker::STATE_UPDATEPHOTO_INFO_ERROR:
702 qCDebug(KIPIPLUGINS_LOG) << "UpdatePhotoError";
703
704 if (QMessageBox::question(this, i18n("Uploading Failed"),
705 i18n("Failed to upload image %1\n"
706 "Do you want to continue?",
707 m_transferQueue.top().originalUrl()))
708 != QMessageBox::Yes)
709 {
710 // clear upload stack
711 m_transferQueue.clear();
712 }
713 else
714 {
715 // cancel current operation
716 m_talker.cancel();
717 // remove only bad image
718 m_transferQueue.pop();
719 // and try next
720 updateNextPhoto();
721 return;
722 }
723 break;
724 default:
725 qCDebug(KIPIPLUGINS_LOG) << "Unhandled error" << m_talker.state();
726 QMessageBox::critical(this, QString(), i18n("Unknown error"));
727 }
728
729 // cancel current operation
730 m_talker.cancel();
731 updateControls(true);
732 }
733
slotGetServiceDone()734 void YandexFotkiWindow::slotGetServiceDone()
735 {
736 qCDebug(KIPIPLUGINS_LOG) << "GetService Done";
737 m_talker.getSession();
738 }
739
slotGetSessionDone()740 void YandexFotkiWindow::slotGetSessionDone()
741 {
742 qCDebug(KIPIPLUGINS_LOG) << "GetSession Done";
743 m_talker.getToken();
744 }
745
slotGetTokenDone()746 void YandexFotkiWindow::slotGetTokenDone()
747 {
748 updateLabels();
749 slotReloadAlbumsRequest();
750 }
751
slotListAlbumsDone(const QList<YandexFotkiAlbum> & albumsList)752 void YandexFotkiWindow::slotListAlbumsDone(const QList<YandexFotkiAlbum>& albumsList)
753 {
754 m_albumsCombo->clear();
755
756 foreach(const YandexFotkiAlbum& album, albumsList)
757 {
758 QString albumIcon;
759
760 if (album.isProtected())
761 {
762 albumIcon = QString::fromLatin1("folder-locked");
763 }
764 else
765 {
766 albumIcon = QString::fromLatin1("folder-image");
767 }
768
769 m_albumsCombo->addItem(QIcon::fromTheme(albumIcon), album.toString());
770 }
771
772 m_albumsCombo->setEnabled(true);
773 updateControls(true);
774 }
775
slotUpdatePhotoDone(YandexFotkiPhoto & photo)776 void YandexFotkiWindow::slotUpdatePhotoDone(YandexFotkiPhoto& photo)
777 {
778 qCDebug(KIPIPLUGINS_LOG) << "photoUploaded" << photo;
779
780 if (m_meta && m_meta->supportXmp() && m_meta->canWriteXmp(QUrl::fromLocalFile(photo.originalUrl())) &&
781 m_meta->load(QUrl::fromLocalFile(photo.originalUrl())))
782 {
783 // ignore errors here
784 if (m_meta->setXmpTagString(QLatin1String(XMP_SERVICE_ID), photo.urn()) &&
785 m_meta->save(QUrl::fromLocalFile(photo.originalUrl())))
786 {
787 qCDebug(KIPIPLUGINS_LOG) << "MARK: " << photo.originalUrl();
788 }
789 }
790
791 m_transferQueue.pop();
792 updateNextPhoto();
793 }
794
slotUpdateAlbumDone()795 void YandexFotkiWindow::slotUpdateAlbumDone()
796 {
797 qCDebug(KIPIPLUGINS_LOG) << "Album created";
798 m_albumsCombo->clear();
799 m_talker.listAlbums();
800 }
801
802 } // namespace KIPIYandexFotkiPlugin
803