File indexing completed on 2025-01-05 03:53:24
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2013-11-18 0007 * Description : a tool to export images to Dropbox web service 0008 * 0009 * SPDX-FileCopyrightText: 2013 by Pankaj Kumar <me at panks dot me> 0010 * SPDX-FileCopyrightText: 2013-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0011 * 0012 * SPDX-License-Identifier: GPL-2.0-or-later 0013 * 0014 * ============================================================ */ 0015 0016 #include "dbwindow.h" 0017 0018 // Qt includes 0019 0020 #include <QWindow> 0021 #include <QSpinBox> 0022 #include <QCheckBox> 0023 #include <QMessageBox> 0024 #include <QCloseEvent> 0025 0026 // KDE includes 0027 0028 #include <klocalizedstring.h> 0029 #include <ksharedconfig.h> 0030 #include <kconfiggroup.h> 0031 0032 // Local includes 0033 0034 #include "digikam_debug.h" 0035 #include "ditemslist.h" 0036 #include "digikam_version.h" 0037 #include "dbtalker.h" 0038 #include "dbitem.h" 0039 #include "dbnewalbumdlg.h" 0040 #include "dbwidget.h" 0041 0042 namespace DigikamGenericDropBoxPlugin 0043 { 0044 0045 class Q_DECL_HIDDEN DBWindow::Private 0046 { 0047 public: 0048 0049 explicit Private() 0050 { 0051 imagesCount = 0; 0052 imagesTotal = 0; 0053 widget = nullptr; 0054 albumDlg = nullptr; 0055 talker = nullptr; 0056 } 0057 0058 unsigned int imagesCount; 0059 unsigned int imagesTotal; 0060 0061 DBWidget* widget; 0062 DBNewAlbumDlg* albumDlg; 0063 DBTalker* talker; 0064 0065 QString currentAlbumName; 0066 QList<QUrl> transferQueue; 0067 }; 0068 0069 DBWindow::DBWindow(DInfoInterface* const iface, QWidget* const /*parent*/) 0070 : WSToolDialog(nullptr, QLatin1String("Dropbox Export Dialog")), 0071 d (new Private) 0072 { 0073 d->widget = new DBWidget(this, iface, QLatin1String("Dropbox")); 0074 d->widget->imagesList()->setIface(iface); 0075 0076 setMainWidget(d->widget); 0077 setModal(false); 0078 setWindowTitle(i18nc("@title:window", "Export to Dropbox")); 0079 0080 startButton()->setText(i18nc("@action:button", "Start Upload")); 0081 startButton()->setToolTip(i18nc("@info:tooltip, button", "Start upload to Dropbox")); 0082 0083 d->widget->setMinimumSize(700, 500); 0084 0085 connect(d->widget->imagesList(), SIGNAL(signalImageListChanged()), 0086 this, SLOT(slotImageListChanged())); 0087 0088 connect(d->widget->getChangeUserBtn(), SIGNAL(clicked()), 0089 this, SLOT(slotUserChangeRequest())); 0090 0091 connect(d->widget->getNewAlbmBtn(), SIGNAL(clicked()), 0092 this, SLOT(slotNewAlbumRequest())); 0093 0094 connect(d->widget->getReloadBtn(), SIGNAL(clicked()), 0095 this, SLOT(slotReloadAlbumsRequest())); 0096 0097 connect(startButton(), SIGNAL(clicked()), 0098 this, SLOT(slotStartTransfer())); 0099 0100 d->albumDlg = new DBNewAlbumDlg(this, QLatin1String("Dropbox")); 0101 0102 d->talker = new DBTalker(this); 0103 0104 connect(d->talker, SIGNAL(signalBusy(bool)), 0105 this, SLOT(slotBusy(bool))); 0106 0107 connect(d->talker, SIGNAL(signalLinkingFailed()), 0108 this, SLOT(slotSignalLinkingFailed())); 0109 0110 connect(d->talker, SIGNAL(signalLinkingSucceeded()), 0111 this, SLOT(slotSignalLinkingSucceeded())); 0112 0113 connect(d->talker, SIGNAL(signalSetUserName(QString)), 0114 this, SLOT(slotSetUserName(QString))); 0115 0116 connect(d->talker, SIGNAL(signalListAlbumsFailed(QString)), 0117 this, SLOT(slotListAlbumsFailed(QString))); 0118 0119 connect(d->talker, SIGNAL(signalListAlbumsDone(QList<QPair<QString,QString> >)), // krazy:exclude=normalize 0120 this, SLOT(slotListAlbumsDone(QList<QPair<QString,QString> >))); // krazy:exclude=normalize 0121 0122 connect(d->talker, SIGNAL(signalCreateFolderFailed(QString)), 0123 this, SLOT(slotCreateFolderFailed(QString))); 0124 0125 connect(d->talker, SIGNAL(signalCreateFolderSucceeded()), 0126 this, SLOT(slotCreateFolderSucceeded())); 0127 0128 connect(d->talker, SIGNAL(signalAddPhotoFailed(QString)), 0129 this, SLOT(slotAddPhotoFailed(QString))); 0130 0131 connect(d->talker, SIGNAL(signalAddPhotoSucceeded()), 0132 this, SLOT(slotAddPhotoSucceeded())); 0133 0134 connect(this, SIGNAL(finished(int)), 0135 this, SLOT(slotFinished())); 0136 0137 readSettings(); 0138 buttonStateChange(false); 0139 0140 d->talker->link(); 0141 } 0142 0143 DBWindow::~DBWindow() 0144 { 0145 delete d->talker; 0146 delete d; 0147 } 0148 0149 void DBWindow::setItemsList(const QList<QUrl>& urls) 0150 { 0151 d->widget->imagesList()->slotAddImages(urls); 0152 } 0153 0154 void DBWindow::reactivate() 0155 { 0156 d->widget->imagesList()->loadImagesFromCurrentSelection(); 0157 d->widget->progressBar()->hide(); 0158 0159 show(); 0160 } 0161 0162 void DBWindow::readSettings() 0163 { 0164 KSharedConfigPtr config = KSharedConfig::openConfig(); 0165 KConfigGroup grp = config->group(QLatin1String("Dropbox Settings")); 0166 d->currentAlbumName = grp.readEntry("Current Album", QString()); 0167 0168 if (grp.readEntry("Resize", false)) 0169 { 0170 d->widget->getResizeCheckBox()->setChecked(true); 0171 d->widget->getDimensionSpB()->setEnabled(true); 0172 } 0173 else 0174 { 0175 d->widget->getResizeCheckBox()->setChecked(false); 0176 d->widget->getDimensionSpB()->setEnabled(false); 0177 } 0178 0179 d->widget->getOriginalCheckBox()->setChecked(grp.readEntry("Upload Original", false)); 0180 d->widget->getDimensionSpB()->setValue(grp.readEntry("Maximum Width", 1600)); 0181 d->widget->getImgQualitySpB()->setValue(grp.readEntry("Image Quality", 90)); 0182 } 0183 0184 void DBWindow::writeSettings() 0185 { 0186 KSharedConfigPtr config = KSharedConfig::openConfig(); 0187 KConfigGroup grp = config->group(QLatin1String("Dropbox Settings")); 0188 0189 grp.writeEntry("Current Album", d->currentAlbumName); 0190 grp.writeEntry("Resize", d->widget->getResizeCheckBox()->isChecked()); 0191 grp.writeEntry("Upload Original", d->widget->getOriginalCheckBox()->isChecked()); 0192 grp.writeEntry("Maximum Width", d->widget->getDimensionSpB()->value()); 0193 grp.writeEntry("Image Quality", d->widget->getImgQualitySpB()->value()); 0194 } 0195 0196 void DBWindow::slotSetUserName(const QString& msg) 0197 { 0198 d->widget->updateLabels(msg, QLatin1String("")); 0199 } 0200 0201 void DBWindow::slotListAlbumsDone(const QList<QPair<QString, QString> >& list) 0202 { 0203 d->widget->getAlbumsCoB()->clear(); 0204 qCDebug(DIGIKAM_WEBSERVICES_LOG) << "slotListAlbumsDone:" << list.size(); 0205 0206 for (int i = 0 ; i < list.size() ; ++i) 0207 { 0208 d->widget->getAlbumsCoB()->addItem( 0209 QIcon::fromTheme(QLatin1String("system-users")), 0210 list.value(i).second, list.value(i).first); 0211 0212 if (d->currentAlbumName == list.value(i).first) 0213 { 0214 d->widget->getAlbumsCoB()->setCurrentIndex(i); 0215 } 0216 } 0217 0218 buttonStateChange(true); 0219 d->talker->getUserName(); 0220 } 0221 0222 void DBWindow::slotBusy(bool val) 0223 { 0224 if (val) 0225 { 0226 setCursor(Qt::WaitCursor); 0227 d->widget->getChangeUserBtn()->setEnabled(false); 0228 buttonStateChange(false); 0229 } 0230 else 0231 { 0232 setCursor(Qt::ArrowCursor); 0233 d->widget->getChangeUserBtn()->setEnabled(true); 0234 buttonStateChange(true); 0235 } 0236 } 0237 0238 void DBWindow::slotStartTransfer() 0239 { 0240 d->widget->imagesList()->clearProcessedStatus(); 0241 0242 if (d->widget->imagesList()->imageUrls().isEmpty()) 0243 { 0244 QMessageBox::critical(this, i18nc("@title:window", "Error"), 0245 i18n("No image selected. Please select which images should be uploaded.")); 0246 return; 0247 } 0248 0249 if (!(d->talker->authenticated())) 0250 { 0251 if (QMessageBox::question(this, i18nc("@title:window", "Login Failed"), 0252 i18n("Authentication failed. Do you want to try again?")) 0253 == QMessageBox::Yes) 0254 { 0255 d->talker->link(); 0256 return; 0257 } 0258 else 0259 { 0260 return; 0261 } 0262 } 0263 0264 d->transferQueue = d->widget->imagesList()->imageUrls(); 0265 0266 if (d->transferQueue.isEmpty()) 0267 { 0268 return; 0269 } 0270 0271 d->currentAlbumName = d->widget->getAlbumsCoB()->itemData(d->widget->getAlbumsCoB()->currentIndex()).toString(); 0272 0273 d->imagesTotal = d->transferQueue.count(); 0274 d->imagesCount = 0; 0275 0276 d->widget->progressBar()->setFormat(i18n("%v / %m")); 0277 d->widget->progressBar()->setMaximum(d->imagesTotal); 0278 d->widget->progressBar()->setValue(0); 0279 d->widget->progressBar()->show(); 0280 d->widget->progressBar()->progressScheduled(i18n("Dropbox export"), true, true); 0281 d->widget->progressBar()->progressThumbnailChanged( 0282 QIcon::fromTheme(QLatin1String("dk-dropbox")).pixmap(22, 22)); 0283 0284 uploadNextPhoto(); 0285 } 0286 0287 void DBWindow::uploadNextPhoto() 0288 { 0289 qCDebug(DIGIKAM_WEBSERVICES_LOG) << "uploadNextPhoto:" << d->transferQueue.count(); 0290 0291 if (d->transferQueue.isEmpty()) 0292 { 0293 qCDebug(DIGIKAM_WEBSERVICES_LOG) << "empty"; 0294 d->widget->progressBar()->progressCompleted(); 0295 return; 0296 } 0297 0298 QString imgPath = d->transferQueue.first().toLocalFile(); 0299 QString temp = d->currentAlbumName + QLatin1Char('/'); 0300 0301 bool res = d->talker->addPhoto(imgPath, 0302 temp, 0303 d->widget->getOriginalCheckBox()->isChecked(), 0304 d->widget->getResizeCheckBox()->isChecked(), 0305 d->widget->getDimensionSpB()->value(), 0306 d->widget->getImgQualitySpB()->value()); 0307 0308 if (!res) 0309 { 0310 slotAddPhotoFailed(QLatin1String("")); 0311 return; 0312 } 0313 } 0314 0315 void DBWindow::slotAddPhotoFailed(const QString& msg) 0316 { 0317 if (QMessageBox::question(this, i18nc("@title:window", "Uploading Failed"), 0318 i18n("Failed to upload photo to Dropbox." 0319 "\n%1\n" 0320 "Do you want to continue?", msg)) 0321 != QMessageBox::Yes) 0322 { 0323 d->transferQueue.clear(); 0324 d->widget->progressBar()->hide(); 0325 } 0326 else 0327 { 0328 d->transferQueue.removeFirst(); 0329 d->imagesTotal--; 0330 d->widget->progressBar()->setMaximum(d->imagesTotal); 0331 d->widget->progressBar()->setValue(d->imagesCount); 0332 uploadNextPhoto(); 0333 } 0334 } 0335 0336 void DBWindow::slotAddPhotoSucceeded() 0337 { 0338 // Remove photo uploaded from the list 0339 d->widget->imagesList()->removeItemByUrl(d->transferQueue.first()); 0340 d->transferQueue.removeFirst(); 0341 d->imagesCount++; 0342 d->widget->progressBar()->setMaximum(d->imagesTotal); 0343 d->widget->progressBar()->setValue(d->imagesCount); 0344 uploadNextPhoto(); 0345 } 0346 0347 void DBWindow::slotImageListChanged() 0348 { 0349 startButton()->setEnabled(!(d->widget->imagesList()->imageUrls().isEmpty())); 0350 } 0351 0352 void DBWindow::slotNewAlbumRequest() 0353 { 0354 if (d->albumDlg->exec() == QDialog::Accepted) 0355 { 0356 DBFolder newFolder; 0357 d->albumDlg->getFolderTitle(newFolder); 0358 qCDebug(DIGIKAM_WEBSERVICES_LOG) << "slotNewAlbumRequest:" << newFolder.title; 0359 d->currentAlbumName = d->widget->getAlbumsCoB()->itemData(d->widget->getAlbumsCoB()->currentIndex()).toString(); 0360 d->currentAlbumName = d->currentAlbumName + newFolder.title; 0361 d->talker->createFolder(d->currentAlbumName); 0362 } 0363 } 0364 0365 void DBWindow::slotReloadAlbumsRequest() 0366 { 0367 d->talker->listFolders(); 0368 } 0369 0370 void DBWindow::slotSignalLinkingFailed() 0371 { 0372 slotSetUserName(QLatin1String("")); 0373 d->widget->getAlbumsCoB()->clear(); 0374 0375 if (QMessageBox::question(this, i18nc("@title:window", "Login Failed"), 0376 i18n("Authentication failed. Do you want to try again?")) 0377 == QMessageBox::Yes) 0378 { 0379 d->talker->link(); 0380 } 0381 } 0382 0383 void DBWindow::slotSignalLinkingSucceeded() 0384 { 0385 d->talker->listFolders(); 0386 } 0387 0388 void DBWindow::slotListAlbumsFailed(const QString& msg) 0389 { 0390 QMessageBox::critical(this, QString(), i18n("Dropbox call failed:\n%1", msg)); 0391 } 0392 0393 void DBWindow::slotCreateFolderFailed(const QString& msg) 0394 { 0395 QMessageBox::critical(this, QString(), i18n("Dropbox call failed:\n%1", msg)); 0396 } 0397 0398 void DBWindow::slotCreateFolderSucceeded() 0399 { 0400 d->talker->listFolders(); 0401 } 0402 0403 void DBWindow::slotTransferCancel() 0404 { 0405 d->transferQueue.clear(); 0406 d->widget->progressBar()->hide(); 0407 d->talker->cancel(); 0408 } 0409 0410 void DBWindow::slotUserChangeRequest() 0411 { 0412 slotSetUserName(QLatin1String("")); 0413 d->widget->getAlbumsCoB()->clear(); 0414 d->talker->unLink(); 0415 d->talker->link(); 0416 } 0417 0418 void DBWindow::buttonStateChange(bool state) 0419 { 0420 d->widget->getNewAlbmBtn()->setEnabled(state); 0421 d->widget->getReloadBtn()->setEnabled(state); 0422 startButton()->setEnabled(state); 0423 } 0424 0425 void DBWindow::slotFinished() 0426 { 0427 writeSettings(); 0428 d->widget->imagesList()->listView()->clear(); 0429 } 0430 0431 void DBWindow::closeEvent(QCloseEvent* e) 0432 { 0433 if (!e) 0434 { 0435 return; 0436 } 0437 0438 slotFinished(); 0439 e->accept(); 0440 } 0441 0442 } // namespace DigikamGenericDropBoxPlugin 0443 0444 #include "moc_dbwindow.cpp"