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