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