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"