File indexing completed on 2025-01-05 03:53:43
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2005-17-06 0007 * Description : a tool to export images to Smugmug web service 0008 * 0009 * SPDX-FileCopyrightText: 2005-2008 by Vardhman Jain <vardhman at gmail dot com> 0010 * SPDX-FileCopyrightText: 2008-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0011 * SPDX-FileCopyrightText: 2008-2009 by Luka Renko <lure at kubuntu dot org> 0012 * 0013 * SPDX-License-Identifier: GPL-2.0-or-later 0014 * 0015 * ============================================================ */ 0016 0017 #include "smugwindow.h" 0018 0019 // Qt includes 0020 0021 #include <QWindow> 0022 #include <QFileInfo> 0023 #include <QPointer> 0024 #include <QSpinBox> 0025 #include <QCheckBox> 0026 #include <QGroupBox> 0027 #include <QMenu> 0028 #include <QComboBox> 0029 #include <QPushButton> 0030 #include <QMessageBox> 0031 #include <QApplication> 0032 0033 // KDE includes 0034 0035 #include <klocalizedstring.h> 0036 #include <ksharedconfig.h> 0037 #include <kconfiggroup.h> 0038 0039 // Local includes 0040 0041 #include "digikam_debug.h" 0042 #include "ditemslist.h" 0043 #include "wstoolutils.h" 0044 #include "digikam_version.h" 0045 #include "dprogresswdg.h" 0046 #include "dmetadata.h" 0047 #include "previewloadthread.h" 0048 #include "smugtalker.h" 0049 #include "smugwidget.h" 0050 #include "smugnewalbumdlg.h" 0051 0052 namespace DigikamGenericSmugPlugin 0053 { 0054 0055 class Q_DECL_HIDDEN SmugWindow::Private 0056 { 0057 public: 0058 0059 explicit Private() 0060 : import (false), 0061 imagesCount (0), 0062 imagesTotal (0), 0063 anonymousImport (false), 0064 currentAlbumID (0), 0065 currentTmplID (0), 0066 currentCategoryID(0), 0067 loginDlg (nullptr), 0068 talker (nullptr), 0069 widget (nullptr), 0070 albumDlg (nullptr), 0071 iface (nullptr) 0072 { 0073 } 0074 0075 bool import; 0076 unsigned int imagesCount; 0077 unsigned int imagesTotal; 0078 QString tmpDir; 0079 QString tmpPath; 0080 0081 bool anonymousImport; 0082 QString anonymousNick; 0083 QString email; 0084 QString password; 0085 qint64 currentAlbumID; 0086 QString currentAlbumKey; 0087 qint64 currentTmplID; 0088 qint64 currentCategoryID; 0089 0090 WSLoginDialog* loginDlg; 0091 0092 QList<QUrl> transferQueue; 0093 0094 SmugTalker* talker; 0095 SmugWidget* widget; 0096 SmugNewAlbumDlg* albumDlg; 0097 0098 DInfoInterface* iface; 0099 }; 0100 0101 SmugWindow::SmugWindow(DInfoInterface* const iface, 0102 QWidget* const /*parent*/, 0103 bool import, 0104 const QString& /*nickName*/) 0105 : WSToolDialog(nullptr, QString::fromLatin1("Smug %1 Dialog").arg(import ? QLatin1String("Import") 0106 : QLatin1String("Export"))), 0107 d (new Private) 0108 { 0109 d->tmpPath.clear(); 0110 d->tmpDir = WSToolUtils::makeTemporaryDir("smug").absolutePath() + QLatin1Char('/');; 0111 d->import = import; 0112 d->iface = iface; 0113 d->widget = new SmugWidget(this, iface, import); 0114 0115 setMainWidget(d->widget); 0116 setModal(false); 0117 0118 if (import) 0119 { 0120 setWindowTitle(i18nc("@title:window", "Import from SmugMug Web Service")); 0121 0122 startButton()->setText(i18nc("@action:button", "Start Download")); 0123 startButton()->setToolTip(i18nc("@info:tooltip, button", "Start download from SmugMug web service")); 0124 0125 d->widget->setMinimumSize(300, 400); 0126 } 0127 else 0128 { 0129 setWindowTitle(i18nc("@title:window", "Export to SmugMug Web Service")); 0130 0131 startButton()->setText(i18nc("@action:button", "Start Upload")); 0132 startButton()->setToolTip(i18nc("@info:tooltip, button", "Start upload to SmugMug web service")); 0133 0134 d->widget->setMinimumSize(700, 500); 0135 } 0136 0137 connect(d->widget, SIGNAL(signalUserChangeRequest(bool)), 0138 this, SLOT(slotUserChangeRequest(bool)) ); 0139 0140 connect(d->widget->m_imgList, SIGNAL(signalImageListChanged()), 0141 this, SLOT(slotImageListChanged()) ); 0142 0143 connect(d->widget->m_reloadAlbumsBtn, SIGNAL(clicked()), 0144 this, SLOT(slotReloadAlbumsRequest()) ); 0145 0146 connect(d->widget->m_newAlbumBtn, SIGNAL(clicked()), 0147 this, SLOT(slotNewAlbumRequest()) ); 0148 0149 connect(startButton(), &QPushButton::clicked, 0150 this, &SmugWindow::slotStartTransfer); 0151 0152 connect(this, &WSToolDialog::cancelClicked, 0153 this, &SmugWindow::slotCancelClicked); 0154 0155 connect(this, &QDialog::finished, 0156 this, &SmugWindow::slotDialogFinished); 0157 0158 // ------------------------------------------------------------------------ 0159 0160 /* This is deprecated because we know use O2 to login 0161 0162 if (nickName.isEmpty()) 0163 { 0164 d->loginDlg = new WSLoginDialog(this, 0165 i18n("<qt>Enter the <b>email address</b> and <b>password</b> for your " 0166 "<a href=\"http://www.smugmug.com\">SmugMug</a> account</qt>")); // krazy:exclude=insecurenet 0167 } 0168 */ 0169 0170 // ------------------------------------------------------------------------ 0171 0172 d->albumDlg = new SmugNewAlbumDlg(this); 0173 0174 /* Categories are deprecated 0175 0176 connect(d->albumDlg->categoryCombo(), SIGNAL(currentIndexChanged(int)), 0177 this, SLOT(slotCategorySelectionChanged(int))); 0178 0179 connect(d->albumDlg->templateCombo(), SIGNAL(currentIndexChanged(int)), 0180 this, SLOT(slotTemplateSelectionChanged(int))); 0181 */ 0182 0183 // ------------------------------------------------------------------------ 0184 0185 d->talker = new SmugTalker(d->iface, this); 0186 0187 connect(d->talker, SIGNAL(signalBusy(bool)), 0188 this, SLOT(slotBusy(bool))); 0189 0190 connect(d->talker, SIGNAL(signalLoginProgress(int,int,QString)), 0191 this, SLOT(slotLoginProgress(int,int,QString))); 0192 0193 connect(d->talker, SIGNAL(signalLoginDone(int,QString)), 0194 this, SLOT(slotLoginDone(int,QString))); 0195 0196 connect(d->talker, SIGNAL(signalAddPhotoDone(int,QString)), 0197 this, SLOT(slotAddPhotoDone(int,QString))); 0198 0199 connect(d->talker, SIGNAL(signalGetPhotoDone(int,QString,QByteArray)), 0200 this, SLOT(slotGetPhotoDone(int,QString,QByteArray))); 0201 0202 connect(d->talker, SIGNAL(signalCreateAlbumDone(int,QString,qint64,QString)), 0203 this, SLOT(slotCreateAlbumDone(int,QString,qint64,QString))); 0204 0205 connect(d->talker, SIGNAL(signalListAlbumsDone(int,QString,QList<SmugAlbum>)), 0206 this, SLOT(slotListAlbumsDone(int,QString,QList<SmugAlbum>))); 0207 0208 connect(d->talker, SIGNAL(signalListPhotosDone(int,QString,QList<SmugPhoto>)), 0209 this, SLOT(slotListPhotosDone(int,QString,QList<SmugPhoto>))); 0210 0211 connect(d->talker, SIGNAL(signalListAlbumTmplDone(int,QString,QList<SmugAlbumTmpl>)), 0212 this, SLOT(slotListAlbumTmplDone(int,QString,QList<SmugAlbumTmpl>))); 0213 0214 /* Categories deprecated in API v2 0215 0216 connect(d->talker, SIGNAL(signalListCategoriesDone(int,QString,QList<SmugCategory>)), 0217 this, SLOT(slotListCategoriesDone(int,QString,QList<SmugCategory>))); 0218 0219 connect(d->talker, SIGNAL(signalListSubCategoriesDone(int,QString,QList<SmugCategory>)), 0220 this, SLOT(slotListSubCategoriesDone(int,QString,QList<SmugCategory>))); 0221 */ 0222 0223 connect(d->widget->progressBar(), SIGNAL(signalProgressCanceled()), 0224 this, SLOT(slotStopAndCloseProgressBar())); 0225 0226 // ------------------------------------------------------------------------ 0227 0228 readSettings(); 0229 0230 qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Calling Login method"; 0231 buttonStateChange(d->talker->loggedIn()); 0232 0233 authenticate(); 0234 0235 // if (!nickName.isEmpty()) 0236 // { 0237 // qCDebug(DIGIKAM_WEBSERVICES_LOG) << "login with nickname"; 0238 // authenticateWithNickName(nickName); 0239 // } 0240 // else 0241 // { 0242 // if (d->import) 0243 // { 0244 // // if no e-mail, switch to anonymous login 0245 // if (d->anonymousImport || d->email.isEmpty()) 0246 // { 0247 // d->anonymousImport = true; 0248 // authenticate(); 0249 // } 0250 // else 0251 // { 0252 // authenticate(d->email, d->password); 0253 // } 0254 // 0255 // d->widget->setAnonymous(d->anonymousImport); 0256 // } 0257 // else 0258 // { 0259 // // export cannot login anonymously: pop-up login window` 0260 // if (d->email.isEmpty()) 0261 // slotUserChangeRequest(false); 0262 // else 0263 // authenticate(d->email, d->password); 0264 // } 0265 // } 0266 } 0267 0268 SmugWindow::~SmugWindow() 0269 { 0270 WSToolUtils::removeTemporaryDir("smug"); 0271 0272 delete d->talker; 0273 delete d; 0274 } 0275 0276 void SmugWindow::closeEvent(QCloseEvent* e) 0277 { 0278 if (!e) 0279 { 0280 return; 0281 } 0282 0283 slotDialogFinished(); 0284 e->accept(); 0285 } 0286 0287 void SmugWindow::slotDialogFinished() 0288 { 0289 slotCancelClicked(); 0290 0291 /* We should not logout without user consent 0292 0293 if (d->talker->loggedIn()) 0294 { 0295 d->talker->logout(); 0296 } 0297 */ 0298 0299 writeSettings(); 0300 d->widget->imagesList()->listView()->clear(); 0301 } 0302 0303 void SmugWindow::setUiInProgressState(bool inProgress) 0304 { 0305 setRejectButtonMode(inProgress ? QDialogButtonBox::Cancel 0306 : QDialogButtonBox::Close); 0307 0308 if (inProgress) 0309 { 0310 d->widget->progressBar()->show(); 0311 } 0312 else 0313 { 0314 d->widget->progressBar()->hide(); 0315 d->widget->progressBar()->progressCompleted(); 0316 } 0317 } 0318 0319 void SmugWindow::slotCancelClicked() 0320 { 0321 d->talker->cancel(); 0322 d->transferQueue.clear(); 0323 d->widget->m_imgList->cancelProcess(); 0324 setUiInProgressState(false); 0325 } 0326 0327 void SmugWindow::slotStopAndCloseProgressBar() 0328 { 0329 slotCancelClicked(); 0330 0331 writeSettings(); 0332 d->widget->imagesList()->listView()->clear(); 0333 reject(); 0334 } 0335 0336 void SmugWindow::reactivate() 0337 { 0338 d->widget->imagesList()->loadImagesFromCurrentSelection(); 0339 show(); 0340 } 0341 0342 void SmugWindow::authenticate() 0343 { 0344 setUiInProgressState(true); 0345 d->widget->progressBar()->setFormat(QString()); 0346 0347 d->talker->login(); 0348 } 0349 0350 void SmugWindow::readSettings() 0351 { 0352 KSharedConfigPtr config = KSharedConfig::openConfig(); 0353 KConfigGroup grp = config->group(QLatin1String("Smug Settings")); 0354 d->anonymousImport = grp.readEntry("AnonymousImport", true); 0355 d->email = grp.readEntry("Email"); 0356 d->password = grp.readEntry("Password"); 0357 d->currentAlbumID = grp.readEntry("Current Album", -1); 0358 d->currentAlbumKey = grp.readEntry("Current Key"); 0359 0360 if (grp.readEntry("Resize", false)) 0361 { 0362 d->widget->m_resizeChB->setChecked(true); 0363 d->widget->m_dimensionSpB->setEnabled(true); 0364 d->widget->m_imageQualitySpB->setEnabled(true); 0365 } 0366 else 0367 { 0368 d->widget->m_resizeChB->setChecked(false); 0369 d->widget->m_dimensionSpB->setEnabled(false); 0370 d->widget->m_imageQualitySpB->setEnabled(false); 0371 } 0372 0373 d->widget->m_dimensionSpB->setValue(grp.readEntry("Maximum Width", 1600)); 0374 d->widget->m_imageQualitySpB->setValue(grp.readEntry("Image Quality", 85)); 0375 } 0376 0377 void SmugWindow::writeSettings() 0378 { 0379 KSharedConfigPtr config = KSharedConfig::openConfig(); 0380 KConfigGroup grp = config->group(QLatin1String("Smug Settings")); 0381 grp.writeEntry("AnonymousImport", d->anonymousImport); 0382 grp.writeEntry("Email", d->email); 0383 grp.writeEntry("Password", d->password); 0384 grp.writeEntry("Current Album", d->currentAlbumID); 0385 grp.writeEntry("Current Key", d->currentAlbumKey); 0386 grp.writeEntry("Resize", d->widget->m_resizeChB->isChecked()); 0387 grp.writeEntry("Maximum Width", d->widget->m_dimensionSpB->value()); 0388 grp.writeEntry("Image Quality", d->widget->m_imageQualitySpB->value()); 0389 } 0390 0391 void SmugWindow::slotLoginProgress(int step, int maxStep, const QString& label) 0392 { 0393 DProgressWdg* const progressBar = d->widget->progressBar(); 0394 0395 if (!label.isEmpty()) 0396 { 0397 progressBar->setFormat(label); 0398 } 0399 0400 if (maxStep > 0) 0401 { 0402 progressBar->setMaximum(maxStep); 0403 } 0404 0405 progressBar->setValue(step); 0406 } 0407 0408 void SmugWindow::slotLoginDone(int errCode, const QString& errMsg) 0409 { 0410 setUiInProgressState(false); 0411 0412 buttonStateChange(d->talker->loggedIn()); 0413 SmugUser user = d->talker->getUser(); 0414 d->widget->updateLabels(user.email, user.displayName, user.nickName); 0415 d->widget->m_albumsCoB->clear(); 0416 0417 if ((errCode == 0) && d->talker->loggedIn()) 0418 { 0419 if (d->import) 0420 { 0421 d->anonymousImport = d->widget->isAnonymous(); 0422 0423 // anonymous: list albums after login only if nick is not empty 0424 0425 QString nick = d->widget->getNickName(); 0426 0427 if (!nick.isEmpty() || !d->anonymousImport) 0428 { 0429 d->talker->listAlbums(nick); 0430 } 0431 } 0432 else 0433 { 0434 // get albums from current user 0435 0436 d->talker->listAlbums(); 0437 } 0438 } 0439 else 0440 { 0441 QMessageBox::critical(QApplication::activeWindow(), i18nc("@title:window", "Error"), i18n("SmugMug call failed: %1\n", errMsg)); 0442 } 0443 } 0444 0445 void SmugWindow::slotListAlbumsDone(int errCode, const QString& errMsg, 0446 const QList <SmugAlbum>& albumsList) 0447 { 0448 if (errCode != 0) 0449 { 0450 QMessageBox::critical(QApplication::activeWindow(), i18nc("@title:window", "Error"), i18n("SmugMug call failed: %1\n", errMsg)); 0451 return; 0452 } 0453 0454 d->widget->m_albumsCoB->clear(); 0455 0456 for (int i = 0 ; i < albumsList.size() ; ++i) 0457 { 0458 QString albumIcon; 0459 0460 if (!albumsList.at(i).password.isEmpty()) 0461 { 0462 albumIcon = QLatin1String("folder-locked"); 0463 } 0464 else if (albumsList.at(i).isPublic) 0465 { 0466 albumIcon = QLatin1String("folder-image"); 0467 } 0468 else 0469 { 0470 albumIcon = QLatin1String("folder"); 0471 } 0472 0473 QString data = QString::fromLatin1("%1:%2").arg(albumsList.at(i).id).arg(albumsList.at(i).key); 0474 d->widget->m_albumsCoB->addItem(QIcon::fromTheme(albumIcon), albumsList.at(i).title, data); 0475 0476 if (d->currentAlbumID == albumsList.at(i).id) 0477 { 0478 d->widget->m_albumsCoB->setCurrentIndex(i); 0479 } 0480 } 0481 } 0482 0483 void SmugWindow::slotListPhotosDone(int errCode, const QString& errMsg, 0484 const QList <SmugPhoto>& photosList) 0485 { 0486 if (errCode != 0) 0487 { 0488 QMessageBox::critical(QApplication::activeWindow(), i18nc("@title:window", "Error"), i18n("SmugMug call failed: %1\n", errMsg)); 0489 return; 0490 } 0491 0492 d->transferQueue.clear(); 0493 0494 for (int i = 0 ; i < photosList.size() ; ++i) 0495 { 0496 d->transferQueue.append(QUrl(photosList.at(i).originalURL)); 0497 } 0498 0499 if (d->transferQueue.isEmpty()) 0500 { 0501 return; 0502 } 0503 0504 d->imagesTotal = d->transferQueue.count(); 0505 d->imagesCount = 0; 0506 0507 d->widget->progressBar()->setMaximum(d->imagesTotal); 0508 d->widget->progressBar()->setValue(0); 0509 0510 // start download with first photo in queue 0511 0512 downloadNextPhoto(); 0513 } 0514 0515 void SmugWindow::slotListAlbumTmplDone(int errCode, const QString& errMsg, 0516 const QList <SmugAlbumTmpl>& albumTList) 0517 { 0518 // always put at least default <none> subcategory 0519 0520 d->albumDlg->templateCombo()->clear(); 0521 d->albumDlg->templateCombo()->addItem(i18n("<none>"), 0); 0522 0523 if (errCode != 0) 0524 { 0525 QMessageBox::critical(QApplication::activeWindow(), i18nc("@title:window", "Error"), i18n("SmugMug call failed: %1\n", errMsg)); 0526 return; 0527 } 0528 0529 for (int i = 0 ; i < albumTList.size() ; ++i) 0530 { 0531 QString albumIcon; 0532 0533 if (!albumTList.at(i).password.isEmpty()) 0534 { 0535 albumIcon = QLatin1String("folder-locked"); 0536 } 0537 else if (albumTList.at(i).isPublic) 0538 { 0539 albumIcon = QLatin1String("folder-image"); 0540 } 0541 else 0542 { 0543 albumIcon = QLatin1String("folder"); 0544 } 0545 0546 d->albumDlg->templateCombo()->addItem(QIcon::fromTheme(albumIcon), albumTList.at(i).name, albumTList.at(i).id); 0547 0548 if (d->currentTmplID == albumTList.at(i).id) 0549 { 0550 d->albumDlg->templateCombo()->setCurrentIndex(i+1); 0551 } 0552 } 0553 0554 d->currentTmplID = d->albumDlg->templateCombo()->itemData(d->albumDlg->templateCombo()->currentIndex()).toLongLong(); 0555 0556 /* Categories now are deprecated in API v2 0557 d->talker->listCategories(); 0558 */ 0559 } 0560 0561 /* Categories now are deprecated in API v2 0562 0563 void SmugWindow::slotListCategoriesDone(int errCode, 0564 const QString& errMsg, 0565 const QList <SmugCategory>& categoriesList) 0566 { 0567 if (errCode != 0) 0568 { 0569 QMessageBox::critical(QApplication::activeWindow(), i18nc("@title:window", "Error"), i18n("SmugMug call failed: %1\n", errMsg)); 0570 return; 0571 } 0572 0573 d->albumDlg->categoryCombo()->clear(); 0574 0575 for (int i = 0; i < categoriesList.size(); ++i) 0576 { 0577 d->albumDlg->categoryCombo()->addItem( 0578 categoriesList.at(i).name, 0579 categoriesList.at(i).id); 0580 0581 if (d->currentCategoryID == categoriesList.at(i).id) 0582 d->albumDlg->categoryCombo()->setCurrentIndex(i); 0583 } 0584 0585 d->currentCategoryID = d->albumDlg->categoryCombo()->itemData( 0586 d->albumDlg->categoryCombo()->currentIndex()).toLongLong(); 0587 d->talker->listSubCategories(d->currentCategoryID); 0588 } 0589 0590 void SmugWindow::slotListSubCategoriesDone(int errCode, 0591 const QString& errMsg, 0592 const QList <SmugCategory>& categoriesList) 0593 { 0594 // always put at least default <none> subcategory 0595 d->albumDlg->subCategoryCombo()->clear(); 0596 d->albumDlg->subCategoryCombo()->addItem(i18n("<none>"), 0); 0597 0598 if (errCode != 0) 0599 { 0600 QMessageBox::critical(QApplication::activeWindow(), i18nc("@title:window", "Error"), 0601 i18n("SmugMug call failed: %1\n", errMsg)); 0602 return; 0603 } 0604 0605 for (int i = 0; i < categoriesList.size(); ++i) 0606 { 0607 d->albumDlg->subCategoryCombo()->addItem( 0608 categoriesList.at(i).name, 0609 categoriesList.at(i).id); 0610 } 0611 } 0612 */ 0613 0614 void SmugWindow::slotTemplateSelectionChanged(int index) 0615 { 0616 if (index < 0) 0617 { 0618 return; 0619 } 0620 0621 d->currentTmplID = d->albumDlg->templateCombo()->itemData(index).toLongLong(); 0622 0623 // if template is selected, then disable Security & Privacy 0624 0625 d->albumDlg->privateGroupBox()->setEnabled(d->currentTmplID == 0); 0626 } 0627 0628 /* Categories now are deprecated in API v2 0629 0630 void SmugWindow::slotCategorySelectionChanged(int index) 0631 { 0632 if (index < 0) 0633 return; 0634 0635 // subcategories are per category -> reload 0636 d->currentCategoryID = d->albumDlg->categoryCombo()->itemData(index).toLongLong(); 0637 d->talker->listSubCategories(d->currentCategoryID); 0638 } 0639 */ 0640 0641 void SmugWindow::buttonStateChange(bool state) 0642 { 0643 d->widget->m_newAlbumBtn->setEnabled(state); 0644 d->widget->m_reloadAlbumsBtn->setEnabled(state); 0645 startButton()->setEnabled(state); 0646 } 0647 0648 void SmugWindow::slotBusy(bool val) 0649 { 0650 if (val) 0651 { 0652 setCursor(Qt::WaitCursor); 0653 d->widget->m_changeUserBtn->setEnabled(false); 0654 buttonStateChange(false); 0655 } 0656 else 0657 { 0658 setCursor(Qt::ArrowCursor); 0659 d->widget->m_changeUserBtn->setEnabled(!d->widget->isAnonymous()); 0660 buttonStateChange(d->talker->loggedIn()); 0661 } 0662 } 0663 0664 void SmugWindow::slotUserChangeRequest(bool /*anonymous*/) 0665 { 0666 qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Slot Change User Request"; 0667 0668 QPointer<QMessageBox> warn = new QMessageBox(QMessageBox::Warning, 0669 i18nc("@title:window", "Warning"), 0670 i18n("You will be logged out of your account, " 0671 "click \"Continue\" to authenticate for another account."), 0672 QMessageBox::Yes | QMessageBox::No); 0673 0674 (warn->button(QMessageBox::Yes))->setText(i18nc("@action:button", "Continue")); 0675 (warn->button(QMessageBox::No))->setText(i18nc("@action:button", "Cancel")); 0676 0677 if (warn->exec() == QMessageBox::Yes) 0678 { 0679 // Unlink user account and wait active until really logged out 0680 0681 d->talker->logout(); 0682 0683 while (d->talker->loggedIn()); 0684 0685 // Re-login 0686 0687 authenticate(); 0688 } 0689 0690 delete warn; 0691 0692 /* 0693 if (anonymous) 0694 { 0695 authenticate(); 0696 } 0697 else 0698 { 0699 // fill in current email and password 0700 0701 d->loginDlg->setLogin(d->email); 0702 d->loginDlg->setPassword(d->password); 0703 0704 if (d->loginDlg->exec()) 0705 { 0706 d->email = d->loginDlg->login(); 0707 d->password = d->loginDlg->password(); 0708 authenticate(d->email, d->password); 0709 } 0710 } 0711 */ 0712 } 0713 0714 void SmugWindow::slotReloadAlbumsRequest() 0715 { 0716 if (d->import) 0717 { 0718 d->talker->listAlbums(d->widget->getNickName()); 0719 } 0720 else 0721 { 0722 // get albums for current user 0723 0724 d->talker->listAlbums(); 0725 } 0726 } 0727 0728 void SmugWindow::slotNewAlbumRequest() 0729 { 0730 qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Slot New Album Request"; 0731 0732 // get list of album templates from SmugMug to fill in dialog 0733 0734 d->talker->listAlbumTmpl(); 0735 0736 if (d->albumDlg->exec() == QDialog::Accepted) 0737 { 0738 qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Calling New Album method"; 0739 d->currentTmplID = d->albumDlg->templateCombo()->itemData( 0740 d->albumDlg->templateCombo()->currentIndex()).toLongLong(); 0741 0742 /* Categories are deprecated 0743 d->currentCategoryID = d->albumDlg->categoryCombo()->itemData( 0744 d->albumDlg->categoryCombo()->currentIndex()).toLongLong(); 0745 */ 0746 0747 SmugAlbum newAlbum; 0748 d->albumDlg->getAlbumProperties(newAlbum); 0749 d->talker->createAlbum(newAlbum); 0750 } 0751 } 0752 0753 void SmugWindow::slotStartTransfer() 0754 { 0755 qCDebug(DIGIKAM_WEBSERVICES_LOG) << "slotStartTransfer invoked"; 0756 0757 if (d->import) 0758 { 0759 d->widget->progressBar()->setFormat(i18n("%v / %m")); 0760 d->widget->progressBar()->setMaximum(0); 0761 d->widget->progressBar()->setValue(0); 0762 d->widget->progressBar()->progressScheduled(i18n("SmugMug Import"), true, true); 0763 d->widget->progressBar()->progressThumbnailChanged( 0764 QIcon::fromTheme(QLatin1String("dk-smugmug")).pixmap(22, 22)); 0765 setUiInProgressState(true); 0766 0767 // list photos of the album, then start download 0768 0769 QString dataStr = d->widget->m_albumsCoB->itemData(d->widget->m_albumsCoB->currentIndex()).toString(); 0770 int colonIdx = dataStr.indexOf(QLatin1Char(':')); 0771 qint64 albumID = dataStr.left(colonIdx).toLongLong(); 0772 QString albumKey = dataStr.right(dataStr.length() - colonIdx - 1); 0773 d->talker->listPhotos(albumID, albumKey, 0774 d->widget->getAlbumPassword(), 0775 d->widget->getSitePassword()); 0776 } 0777 else 0778 { 0779 d->widget->m_imgList->clearProcessedStatus(); 0780 d->transferQueue = d->widget->m_imgList->imageUrls(); 0781 0782 if (d->transferQueue.isEmpty()) 0783 { 0784 return; 0785 } 0786 0787 QString data = d->widget->m_albumsCoB->itemData(d->widget->m_albumsCoB->currentIndex()).toString(); 0788 int colonIdx = data.indexOf(QLatin1Char(':')); 0789 d->currentAlbumID = data.left(colonIdx).toLongLong(); 0790 d->currentAlbumKey = data.right(data.length() - colonIdx - 1); 0791 0792 d->imagesTotal = d->transferQueue.count(); 0793 d->imagesCount = 0; 0794 0795 d->widget->progressBar()->setFormat(i18n("%v / %m")); 0796 d->widget->progressBar()->setMaximum(d->imagesTotal); 0797 d->widget->progressBar()->setValue(0); 0798 d->widget->progressBar()->progressScheduled(i18n("SmugMug Export"), true, true); 0799 d->widget->progressBar()->progressThumbnailChanged( 0800 QIcon::fromTheme(QLatin1String("dk-smugmug")).pixmap(22, 22)); 0801 setUiInProgressState(true); 0802 0803 qCDebug(DIGIKAM_WEBSERVICES_LOG) << "d->currentAlbumID" << d->currentAlbumID; 0804 uploadNextPhoto(); 0805 qCDebug(DIGIKAM_WEBSERVICES_LOG) << "slotStartTransfer done"; 0806 } 0807 } 0808 0809 bool SmugWindow::prepareImageForUpload(const QString& imgPath) const 0810 { 0811 QImage image = PreviewLoadThread::loadHighQualitySynchronously(imgPath).copyQImage(); 0812 0813 if (image.isNull()) 0814 { 0815 image.load(imgPath); 0816 } 0817 0818 if (image.isNull()) 0819 { 0820 return false; 0821 } 0822 0823 // get temporary file name 0824 0825 d->tmpPath = d->tmpDir + QFileInfo(imgPath).baseName().trimmed() + QLatin1String(".jpg"); 0826 0827 // rescale image if requested 0828 0829 int maxDim = d->widget->m_dimensionSpB->value(); 0830 0831 if (d->widget->m_resizeChB->isChecked() && 0832 ((image.width() > maxDim) || (image.height() > maxDim))) 0833 { 0834 qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Resizing to " << maxDim; 0835 image = image.scaled(maxDim, maxDim, Qt::KeepAspectRatio, 0836 Qt::SmoothTransformation); 0837 } 0838 0839 qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Saving to temp file: " << d->tmpPath; 0840 image.save(d->tmpPath, "JPEG", d->widget->m_imageQualitySpB->value()); 0841 0842 // copy meta-data to temporary image 0843 0844 QScopedPointer<DMetadata> meta(new DMetadata); 0845 0846 if (meta->load(imgPath)) 0847 { 0848 meta->setItemDimensions(image.size()); 0849 meta->setItemOrientation(MetaEngine::ORIENTATION_NORMAL); 0850 meta->setMetadataWritingMode((int)DMetadata::WRITE_TO_FILE_ONLY); 0851 meta->save(d->tmpPath, true); 0852 } 0853 0854 return true; 0855 } 0856 0857 void SmugWindow::uploadNextPhoto() 0858 { 0859 if (d->transferQueue.isEmpty()) 0860 { 0861 setUiInProgressState(false); 0862 return; 0863 } 0864 0865 d->widget->m_imgList->processing(d->transferQueue.first()); 0866 0867 QUrl imgPath = d->transferQueue.first(); 0868 DItemInfo info(d->iface->itemInfo(imgPath)); 0869 0870 d->widget->progressBar()->setMaximum(d->imagesTotal); 0871 d->widget->progressBar()->setValue(d->imagesCount); 0872 0873 bool res; 0874 0875 if (d->widget->m_resizeChB->isChecked()) 0876 { 0877 if (!prepareImageForUpload(imgPath.toLocalFile())) 0878 { 0879 slotAddPhotoDone(666, i18n("Cannot open file")); 0880 return; 0881 } 0882 0883 res = d->talker->addPhoto(d->tmpPath, d->currentAlbumID, d->currentAlbumKey, info.comment()); 0884 } 0885 else 0886 { 0887 d->tmpPath.clear(); 0888 res = d->talker->addPhoto(imgPath.toLocalFile(), d->currentAlbumID, d->currentAlbumKey, info.comment()); 0889 } 0890 0891 if (!res) 0892 { 0893 slotAddPhotoDone(666, i18n("Cannot open file")); 0894 return; 0895 } 0896 } 0897 0898 void SmugWindow::slotAddPhotoDone(int errCode, const QString& errMsg) 0899 { 0900 // Remove temporary file if it was used 0901 0902 if (!d->tmpPath.isEmpty()) 0903 { 0904 QFile::remove(d->tmpPath); 0905 d->tmpPath.clear(); 0906 } 0907 0908 d->widget->m_imgList->processed(d->transferQueue.first(), (errCode == 0)); 0909 0910 if (errCode == 0) 0911 { 0912 d->transferQueue.removeFirst(); 0913 d->imagesCount++; 0914 } 0915 else 0916 { 0917 if (QMessageBox::question(this, i18nc("@title:window", "Uploading Failed"), 0918 i18n("Failed to upload photo to SmugMug." 0919 "\n%1\n" 0920 "Do you want to continue?", errMsg)) 0921 != QMessageBox::Yes) 0922 { 0923 setUiInProgressState(false); 0924 d->transferQueue.clear(); 0925 return; 0926 } 0927 } 0928 0929 uploadNextPhoto(); 0930 } 0931 0932 void SmugWindow::downloadNextPhoto() 0933 { 0934 if (d->transferQueue.isEmpty()) 0935 { 0936 setUiInProgressState(false); 0937 return; 0938 } 0939 0940 d->widget->progressBar()->setMaximum(d->imagesTotal); 0941 d->widget->progressBar()->setValue(d->imagesCount); 0942 0943 QString imgPath = d->transferQueue.first().url(); 0944 0945 d->talker->getPhoto(imgPath); 0946 } 0947 0948 void SmugWindow::slotGetPhotoDone(int errCode, 0949 const QString& errMsg, 0950 const QByteArray& photoData) 0951 { 0952 QString imgPath = d->widget->getDestinationPath() + QLatin1Char('/') 0953 + d->transferQueue.first().fileName(); 0954 0955 qCDebug(DIGIKAM_WEBSERVICES_LOG) << imgPath; 0956 0957 if (errCode == 0) 0958 { 0959 QString errText; 0960 QFile imgFile(imgPath); 0961 0962 if (!imgFile.open(QIODevice::WriteOnly)) 0963 { 0964 errText = imgFile.errorString(); 0965 } 0966 else if (imgFile.write(photoData) != photoData.size()) 0967 { 0968 errText = imgFile.errorString(); 0969 } 0970 else 0971 { 0972 imgFile.close(); 0973 Q_EMIT updateHostApp(QUrl::fromLocalFile(imgPath)); 0974 } 0975 0976 if (errText.isEmpty()) 0977 { 0978 d->transferQueue.removeFirst(); 0979 d->imagesCount++; 0980 } 0981 else 0982 { 0983 if (QMessageBox::question(this, i18nc("@title:window", "Processing Failed"), 0984 i18n("Failed to save photo: %1\n" 0985 "Do you want to continue?", errText)) 0986 != QMessageBox::Yes) 0987 { 0988 d->transferQueue.clear(); 0989 setUiInProgressState(false); 0990 return; 0991 } 0992 } 0993 } 0994 else 0995 { 0996 if (QMessageBox::question(this, i18nc("@title:window", "Processing Failed"), 0997 i18n("Failed to download photo: %1\n" 0998 "Do you want to continue?", errMsg)) 0999 != QMessageBox::Yes) 1000 { 1001 d->transferQueue.clear(); 1002 setUiInProgressState(false); 1003 return; 1004 } 1005 } 1006 1007 downloadNextPhoto(); 1008 } 1009 1010 void SmugWindow::slotCreateAlbumDone(int errCode, 1011 const QString& errMsg, 1012 qint64 newAlbumID, 1013 const QString& newAlbumKey) 1014 { 1015 if (errCode != 0) 1016 { 1017 QMessageBox::critical(QApplication::activeWindow(), i18nc("@title:window", "Error"), i18n("SmugMug call failed: %1\n", errMsg)); 1018 return; 1019 } 1020 1021 // reload album list and automatically select new album 1022 1023 d->currentAlbumID = newAlbumID; 1024 d->currentAlbumKey = newAlbumKey; 1025 d->talker->listAlbums(); 1026 } 1027 1028 void SmugWindow::slotImageListChanged() 1029 { 1030 startButton()->setEnabled(!(d->widget->m_imgList->imageUrls().isEmpty())); 1031 } 1032 1033 } // namespace DigikamGenericSmugPlugin 1034 1035 #include "moc_smugwindow.cpp"