File indexing completed on 2025-01-05 03:53:31
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2012-02-02 0007 * Description : a tool to export items to ImageShack web service 0008 * 0009 * SPDX-FileCopyrightText: 2012 by Dodon Victor <dodonvictor at gmail dot com> 0010 * SPDX-FileCopyrightText: 2013-2018 by Caulier Gilles <caulier dot gilles at gmail dot com> 0011 * 0012 * SPDX-License-Identifier: GPL-2.0-or-later 0013 * 0014 * ============================================================ */ 0015 0016 #include "imageshackwindow.h" 0017 0018 // Qt includes 0019 0020 #include <QWindow> 0021 #include <QButtonGroup> 0022 #include <QCheckBox> 0023 #include <QCloseEvent> 0024 #include <QDialog> 0025 #include <QFileInfo> 0026 #include <QGridLayout> 0027 #include <QHBoxLayout> 0028 #include <QLineEdit> 0029 #include <QPointer> 0030 #include <QPushButton> 0031 #include <QRadioButton> 0032 #include <QSpinBox> 0033 #include <QVBoxLayout> 0034 #include <QApplication> 0035 #include <QIcon> 0036 #include <QMenu> 0037 #include <QComboBox> 0038 #include <QMessageBox> 0039 #include <QTimer> 0040 0041 // KDE includes 0042 0043 #include <klocalizedstring.h> 0044 #include <ksharedconfig.h> 0045 #include <kconfiggroup.h> 0046 0047 // Local includes 0048 0049 #include "digikam_debug.h" 0050 #include "imageshacksession.h" 0051 #include "imageshackwidget_p.h" 0052 #include "imageshacktalker.h" 0053 #include "dprogresswdg.h" 0054 #include "wslogindialog.h" 0055 #include "imageshacknewalbumdlg.h" 0056 0057 namespace DigikamGenericImageShackPlugin 0058 { 0059 0060 class Q_DECL_HIDDEN ImageShackWindow::Private 0061 { 0062 public: 0063 0064 explicit Private() 0065 { 0066 imagesCount = 0; 0067 imagesTotal = 0; 0068 session = nullptr; 0069 widget = nullptr; 0070 talker = nullptr; 0071 albumDlg = nullptr; 0072 iface = nullptr; 0073 } 0074 0075 unsigned int imagesCount; 0076 unsigned int imagesTotal; 0077 QString newAlbmTitle; 0078 0079 QList<QUrl> transferQueue; 0080 0081 ImageShackSession* session; 0082 ImageShackWidget* widget; 0083 ImageShackTalker* talker; 0084 0085 ImageShackNewAlbumDlg* albumDlg; 0086 0087 DInfoInterface* iface; 0088 }; 0089 0090 ImageShackWindow::ImageShackWindow(DInfoInterface* const iface, 0091 QWidget* const /*parent*/) 0092 : WSToolDialog(nullptr, QLatin1String("ImageShack Dialog")), 0093 d(new Private) 0094 { 0095 d->session = new ImageShackSession(); 0096 d->iface = iface; 0097 d->widget = new ImageShackWidget(this, 0098 d->session, 0099 d->iface, 0100 QLatin1String("ImageShack")); 0101 d->widget->setMinimumSize(700, 500); 0102 0103 setMainWidget(d->widget); 0104 setWindowTitle(i18nc("@title:window", "Export to ImageShack")); 0105 setModal(false); 0106 0107 d->albumDlg = new ImageShackNewAlbumDlg(this, QLatin1String("ImageShack")); 0108 0109 connect(d->widget->d->chgRegCodeBtn, SIGNAL(clicked(bool)), 0110 this, SLOT(slotChangeRegistrantionCode())); 0111 0112 startButton()->setText(i18nc("@action:button", "Upload")); 0113 startButton()->setToolTip(i18nc("@info:tooltip, button", "Start upload to ImageShack web service")); 0114 startButton()->setEnabled(false); 0115 0116 connect(d->widget->d->imgList, SIGNAL(signalImageListChanged()), 0117 this, SLOT(slotImageListChanged())); 0118 0119 // ----------------------------------------------------------- 0120 0121 connect(this, SIGNAL(signalBusy(bool)), 0122 this, SLOT(slotBusy(bool))); 0123 0124 d->talker = new ImageShackTalker(d->session); 0125 0126 connect(d->talker, SIGNAL(signalBusy(bool)), 0127 this, SLOT(slotBusy(bool))); 0128 0129 connect(d->talker, SIGNAL(signalJobInProgress(int,int,QString)), 0130 this, SLOT(slotJobInProgress(int,int,QString))); 0131 0132 connect(d->talker, SIGNAL(signalLoginDone(int,QString)), 0133 this, SLOT(slotLoginDone(int,QString))); 0134 0135 connect(d->talker, SIGNAL(signalGetGalleriesDone(int,QString)), 0136 this, SLOT(slotGetGalleriesDone(int,QString))); 0137 0138 connect(d->talker, SIGNAL(signalUpdateGalleries(QStringList,QStringList)), 0139 d->widget, SLOT(slotGetGalleries(QStringList,QStringList))); 0140 0141 connect(d->talker, SIGNAL(signalAddPhotoDone(int,QString)), 0142 this, SLOT(slotAddPhotoDone(int,QString))); 0143 0144 connect(d->widget, SIGNAL(signalReloadGalleries()), 0145 this, SLOT(slotGetGalleries())); 0146 0147 connect(startButton(), SIGNAL(clicked()), 0148 this, SLOT(slotStartTransfer())); 0149 0150 connect(this, SIGNAL(finished(int)), 0151 this, SLOT(slotFinished())); 0152 0153 connect(this, SIGNAL(cancelClicked()), 0154 this, SLOT(slotCancelClicked())); 0155 0156 connect(d->widget->getNewAlbmBtn(), SIGNAL(clicked()), 0157 this, SLOT(slotNewAlbumRequest())); 0158 0159 readSettings(); 0160 0161 QTimer::singleShot(20, this, SLOT(authenticate())); 0162 } 0163 0164 ImageShackWindow::~ImageShackWindow() 0165 { 0166 delete d->session; 0167 delete d; 0168 } 0169 0170 void ImageShackWindow::slotImageListChanged() 0171 { 0172 startButton()->setEnabled(!d->widget->d->imgList->imageUrls().isEmpty()); 0173 } 0174 0175 void ImageShackWindow::slotFinished() 0176 { 0177 saveSettings(); 0178 d->widget->d->progressBar->progressCompleted(); 0179 d->widget->d->imgList->listView()->clear(); 0180 } 0181 0182 void ImageShackWindow::closeEvent(QCloseEvent* e) 0183 { 0184 if (!e) 0185 { 0186 return; 0187 } 0188 0189 slotFinished(); 0190 e->accept(); 0191 } 0192 0193 void ImageShackWindow::readSettings() 0194 { 0195 KSharedConfigPtr config = KSharedConfig::openConfig(); 0196 KConfigGroup group = config->group(QLatin1String("ImageShack Settings")); 0197 0198 if (group.readEntry("Private", false)) 0199 { 0200 d->widget->d->privateImagesChb->setChecked(true); 0201 } 0202 0203 if (group.readEntry("Rembar", false)) 0204 { 0205 d->widget->d->remBarChb->setChecked(true); 0206 } 0207 else 0208 { 0209 d->widget->d->remBarChb->setChecked(false); 0210 } 0211 } 0212 0213 void ImageShackWindow::saveSettings() 0214 { 0215 KSharedConfigPtr config = KSharedConfig::openConfig(); 0216 KConfigGroup group = config->group(QLatin1String("ImageShack Settings")); 0217 0218 group.writeEntry("Private", d->widget->d->privateImagesChb->isChecked()); 0219 group.writeEntry("Rembar", d->widget->d->remBarChb->isChecked()); 0220 } 0221 0222 void ImageShackWindow::slotStartTransfer() 0223 { 0224 d->widget->d->imgList->clearProcessedStatus(); 0225 d->transferQueue = d->widget->d->imgList->imageUrls(); 0226 0227 if (d->transferQueue.isEmpty()) 0228 { 0229 return; 0230 } 0231 0232 qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Transfer started!"; 0233 0234 d->imagesTotal = d->transferQueue.count(); 0235 d->imagesCount = 0; 0236 0237 d->widget->d->progressBar->setFormat(i18n("%v / %m")); 0238 d->widget->d->progressBar->setMaximum(d->imagesTotal); 0239 d->widget->d->progressBar->setValue(0); 0240 d->widget->d->progressBar->setVisible(true); 0241 d->widget->d->progressBar->progressScheduled(i18n("Image Shack Export"), false, true); 0242 d->widget->d->progressBar->progressThumbnailChanged( 0243 QIcon::fromTheme(QLatin1String("dk-imageshack")).pixmap(22, 22)); 0244 0245 uploadNextItem(); 0246 } 0247 0248 void ImageShackWindow::slotCancelClicked() 0249 { 0250 d->talker->cancel(); 0251 d->transferQueue.clear(); 0252 d->widget->d->imgList->cancelProcess(); 0253 d->widget->d->progressBar->setVisible(false); 0254 d->widget->d->progressBar->progressCompleted(); 0255 } 0256 0257 void ImageShackWindow::slotChangeRegistrantionCode() 0258 { 0259 qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Change registration code"; 0260 authenticate(); 0261 } 0262 0263 void ImageShackWindow::authenticate() 0264 { 0265 Q_EMIT signalBusy(true); 0266 d->widget->progressBar()->show(); 0267 d->widget->d->progressBar->setValue(0); 0268 d->widget->d->progressBar->setMaximum(4); 0269 d->widget->progressBar()->setFormat(i18n("Authenticating...")); 0270 0271 WSLoginDialog* const dlg = new WSLoginDialog(this, QLatin1String("ImageShack")); 0272 0273 if (dlg->exec() == QDialog::Accepted) 0274 { 0275 d->session->setEmail(dlg->login()); 0276 d->session->setPassword(dlg->password()); 0277 d->talker->authenticate(); 0278 } 0279 } 0280 0281 void ImageShackWindow::slotBusy(bool val) 0282 { 0283 if (val) 0284 { 0285 setCursor(Qt::WaitCursor); 0286 d->widget->d->chgRegCodeBtn->setEnabled(false); 0287 startButton()->setEnabled(false); 0288 setRejectButtonMode(QDialogButtonBox::Cancel); 0289 } 0290 else 0291 { 0292 setCursor(Qt::ArrowCursor); 0293 d->widget->d->chgRegCodeBtn->setEnabled(true); 0294 startButton()->setEnabled(d->session->loggedIn() && 0295 !d->widget->imagesList()->imageUrls().isEmpty()); 0296 setRejectButtonMode(QDialogButtonBox::Close); 0297 } 0298 } 0299 0300 void ImageShackWindow::slotJobInProgress(int step, int maxStep, const QString& format) 0301 { 0302 if (maxStep > 0) 0303 { 0304 d->widget->d->progressBar->setMaximum(maxStep); 0305 } 0306 0307 d->widget->d->progressBar->setValue(step); 0308 0309 if (!format.isEmpty()) 0310 { 0311 d->widget->d->progressBar->setFormat(format); 0312 } 0313 } 0314 0315 void ImageShackWindow::slotLoginDone(int errCode, const QString& errMsg) 0316 { 0317 d->widget->updateLabels(); 0318 0319 if (!errCode && d->session->loggedIn()) 0320 { 0321 d->session->saveSettings(); 0322 startButton()->setEnabled(!d->widget->imagesList()->imageUrls().isEmpty()); 0323 d->talker->getGalleries(); 0324 } 0325 else 0326 { 0327 QMessageBox::critical(this, QString(), i18n("Login failed: %1\n", errMsg)); 0328 startButton()->setEnabled(false); 0329 d->widget->d->progressBar->setVisible(false); 0330 slotBusy(false); 0331 } 0332 } 0333 0334 void ImageShackWindow::slotGetGalleriesDone(int errCode, const QString& errMsg) 0335 { 0336 slotBusy(false); 0337 d->widget->d->progressBar->setVisible(false); 0338 0339 if (errCode) 0340 { 0341 QMessageBox::critical(this, QString(), i18n("Failed to get galleries list: %1\n", errMsg)); 0342 } 0343 } 0344 0345 void ImageShackWindow::uploadNextItem() 0346 { 0347 if (d->transferQueue.isEmpty()) 0348 { 0349 d->widget->d->progressBar->hide(); 0350 return; 0351 } 0352 0353 d->widget->d->imgList->processing(d->transferQueue.first()); 0354 QString imgPath = d->transferQueue.first().toLocalFile(); 0355 0356 d->widget->d->progressBar->setMaximum(d->imagesTotal); 0357 d->widget->d->progressBar->setValue(d->imagesCount); 0358 0359 QMap<QString, QString> opts; 0360 0361 if (d->widget->d->privateImagesChb->isChecked()) 0362 { 0363 opts[QLatin1String("public")] = QLatin1String("no"); 0364 } 0365 0366 if (d->widget->d->remBarChb->isChecked()) 0367 { 0368 opts[QLatin1String("rembar")] = QLatin1String("yes"); 0369 } 0370 0371 // tags 0372 if (!d->widget->d->tagsFld->text().isEmpty()) 0373 { 0374 QString str = d->widget->d->tagsFld->text(); 0375 QStringList tagsList; 0376 tagsList = str.split(QRegularExpression(QLatin1String("\\W+")), QT_SKIP_EMPTY_PARTS); 0377 opts[QLatin1String("tags")] = tagsList.join(QLatin1Char(',')); 0378 } 0379 0380 opts[QLatin1String("auth_token")] = d->session->authToken(); 0381 0382 int gidx = d->widget->d->galleriesCob->currentIndex(); 0383 0384 qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Album ID is "<< d->widget->d->galleriesCob->itemData(gidx).toString(); 0385 0386 switch (gidx) 0387 { 0388 case 0: 0389 d->talker->uploadItem(imgPath, opts); 0390 break; 0391 case 1: 0392 opts[QLatin1String("album")] = d->newAlbmTitle; 0393 d->talker->uploadItemToGallery(imgPath, d->newAlbmTitle, opts); 0394 break; 0395 default: 0396 opts[QLatin1String("album")] = d->widget->d->galleriesCob->itemData(gidx).toString(); 0397 d->talker->uploadItemToGallery(imgPath, d->widget->d->galleriesCob->itemData(gidx).toString(), opts); 0398 } 0399 } 0400 0401 void ImageShackWindow::slotAddPhotoDone(int errCode, const QString& errMsg) 0402 { 0403 d->widget->d->imgList->processed(d->transferQueue.first(), (errCode == 0)); 0404 0405 if (!errCode) 0406 { 0407 d->widget->imagesList()->removeItemByUrl(d->transferQueue.first()); 0408 d->transferQueue.removeFirst(); 0409 d->imagesCount++; 0410 } 0411 else 0412 { 0413 if (QMessageBox::question(this, i18nc("@title:window", "Uploading Failed"), 0414 i18n("Failed to upload photo into ImageShack: %1\n" 0415 "Do you want to continue?", errMsg)) 0416 != QMessageBox::Yes) 0417 { 0418 d->widget->d->progressBar->setVisible(false); 0419 d->transferQueue.clear(); 0420 return; 0421 } 0422 } 0423 0424 uploadNextItem(); 0425 } 0426 0427 void ImageShackWindow::slotGetGalleries() 0428 { 0429 d->widget->d->progressBar->setVisible(true); 0430 d->talker->getGalleries(); 0431 } 0432 0433 void ImageShackWindow::slotNewAlbumRequest() 0434 { 0435 if (d->albumDlg->exec() == QDialog::Accepted) 0436 { 0437 d->newAlbmTitle = d->albumDlg->getAlbumTitle(); 0438 } 0439 } 0440 0441 } // namespace DigikamGenericImageShackPlugin 0442 0443 #include "moc_imageshackwindow.cpp"