File indexing completed on 2025-01-05 03:53:45

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2017-06-27
0007  * Description : page visualizing photos user choosing to upload and
0008  *               user albums list to upload photos to. Creating new album
0009  *               is also available on this page.
0010  *
0011  * SPDX-FileCopyrightText: 2017-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0012  * SPDX-FileCopyrightText: 2018      by Thanh Trung Dinh <dinhthanhtrung1996 at gmail dot com>
0013  *
0014  * SPDX-License-Identifier: GPL-2.0-or-later
0015  *
0016  * ============================================================ */
0017 
0018 #include "wsimagespage.h"
0019 
0020 // Qt includes
0021 
0022 #include <QIcon>
0023 #include <QPixmap>
0024 #include <QLabel>
0025 #include <QHBoxLayout>
0026 #include <QPushButton>
0027 #include <QMessageBox>
0028 #include <QApplication>
0029 
0030 // KDE includes
0031 
0032 #include <klocalizedstring.h>
0033 
0034 // Local includes
0035 
0036 #include "digikam_debug.h"
0037 #include "dlayoutbox.h"
0038 #include "ditemslist.h"
0039 #include "wswizard.h"
0040 #include "wsnewalbumdialog.h"
0041 
0042 namespace DigikamGenericUnifiedPlugin
0043 {
0044 
0045 class Q_DECL_HIDDEN WSImagesPage::Private
0046 {
0047 public:
0048 
0049     explicit Private(QWizard* const dialog)
0050       : imageList(0),
0051         albumView(0),
0052         newAlbumBtn(0),
0053         reloadAlbumsBtn(0),
0054         wizard(0),
0055         iface(0),
0056         wsAuth(0)
0057     {
0058         wizard = dynamic_cast<WSWizard*>(dialog);
0059 
0060         if (wizard)
0061         {
0062             iface  = wizard->iface();
0063             wsAuth = wizard->wsAuth();
0064         }
0065     }
0066 
0067     DItemsList*      imageList;
0068 
0069     QTreeWidget*      albumView;
0070     QString           currentAlbumId;
0071     QPushButton*      newAlbumBtn;
0072     QPushButton*      reloadAlbumsBtn;
0073 
0074     WSWizard*         wizard;
0075     DInfoInterface*   iface;
0076     WSAuthentication* wsAuth;
0077 };
0078 
0079 WSImagesPage::WSImagesPage(QWizard* const dialog, const QString& title)
0080     : DWizardPage(dialog, title),
0081       d(new Private(dialog))
0082 {
0083     DHBox* const hbox       = new DHBox(this);
0084 
0085     /* --------------------
0086      * Widget for Images list
0087      */
0088 
0089     DVBox* const vboxImage  = new DVBox(hbox);
0090     QLabel* const descImage = new QLabel(vboxImage);
0091     descImage->setText(i18n("<h3>This view lists all items to export.</h3>"));
0092 
0093     d->imageList            = new DItemsList(vboxImage);
0094     d->imageList->setObjectName(QLatin1String("WebService ImagesList"));
0095     d->imageList->setControlButtonsPlacement(DItemsList::ControlButtonsBelow);
0096 
0097     connect(d->imageList, SIGNAL(signalImageListChanged()),
0098             this, SIGNAL(completeChanged()));
0099 
0100     /* --------------------
0101      * User albums list
0102      */
0103 
0104     DVBox* const vboxAlbum  = new DVBox(hbox);
0105 
0106     QLabel* const descAlbum = new QLabel(vboxAlbum);
0107     descAlbum->setText(i18n("<h3>This view lists user albums.</h3>"));
0108 
0109     d->albumView            = new QTreeWidget(vboxAlbum);
0110     d->albumView->setHeaderLabel(QLatin1String(""));
0111 
0112     DHBox* const buttonBox  = new DHBox(vboxAlbum);
0113 
0114     // Disable New Album button for now, because creating album on facebook is encountering a strange error
0115     d->newAlbumBtn          = new QPushButton(QLatin1String("New Album"), buttonBox);
0116     //d->newAlbumBtn->setDisabled(true);
0117 
0118     d->reloadAlbumsBtn      = new QPushButton(QLatin1String("Reload"), buttonBox);
0119 
0120     connect(d->newAlbumBtn, SIGNAL(clicked()),
0121             d->wsAuth, SLOT(slotNewAlbumRequest()));
0122 
0123     connect(d->reloadAlbumsBtn, SIGNAL(clicked()),
0124             this, SIGNAL(signalListAlbumsRequest()));
0125 
0126     connect(this, SIGNAL(signalListAlbumsRequest()),
0127             d->wsAuth, SLOT(slotListAlbumsRequest()));
0128 
0129     connect(d->wsAuth, SIGNAL(signalCreateAlbumDone(int,QString,QString)),
0130             this, SLOT(slotCreateAlbumDone(int,QString,QString)));
0131 
0132     connect(d->wsAuth, SIGNAL(signalListAlbumsDone(QMap<QString,AlbumSimplified>,QStringList,QString)),
0133             this, SLOT(slotListAlbumsDone(QMap<QString,AlbumSimplified>,QStringList,QString)));
0134 
0135     /* --------------------
0136      * General settings for imagespage
0137      */
0138 
0139     hbox->setStretchFactor(vboxImage, 2);
0140     hbox->setStretchFactor(vboxAlbum, 1);
0141 
0142     setPageWidget(hbox);
0143     setLeftBottomPix(QIcon::fromTheme(QLatin1String("image-stack")));
0144 }
0145 
0146 WSImagesPage::~WSImagesPage()
0147 {
0148     delete d;
0149 }
0150 
0151 void WSImagesPage::setItemsList(const QList<QUrl>& urls)
0152 {
0153     d->imageList->slotAddImages(urls);
0154 }
0155 
0156 void WSImagesPage::setCurrentAlbumId(const QString& currentAlbumId)
0157 {
0158     d->currentAlbumId = currentAlbumId;
0159     d->wizard->settings()->currentAlbumId = currentAlbumId;
0160 }
0161 
0162 void WSImagesPage::initializePage()
0163 {
0164     d->imageList->setIface(d->iface);
0165     d->imageList->listView()->clear();
0166 
0167     // List current albums in user account
0168     Q_EMIT signalListAlbumsRequest();
0169 }
0170 
0171 bool WSImagesPage::validatePage()
0172 {
0173     /* If user album is not empty, get id for album to upload photos from currentItem on the list.
0174      * Otherwise, set album id as empty string and uploading to empty album will be handled in
0175      * specific talker of each web service
0176      */
0177     if (d->albumView->currentItem())
0178     {
0179         setCurrentAlbumId(d->albumView->currentItem()->data(0, Qt::AccessibleDescriptionRole).toString());
0180     }
0181     else
0182     {
0183         setCurrentAlbumId(QLatin1String(""));
0184     }
0185 
0186     if (d->imageList->imageUrls().isEmpty())
0187     {
0188         return false;
0189     }
0190 
0191     d->wizard->settings()->inputImages = d->imageList->imageUrls();
0192 
0193     return true;
0194 }
0195 
0196 bool WSImagesPage::isComplete() const
0197 {
0198     return (!d->imageList->imageUrls().isEmpty());
0199 }
0200 
0201 void WSImagesPage::addChildToTreeView(QTreeWidgetItem* const parent,
0202                                       const QMap<QString, AlbumSimplified>& albumTree,
0203                                       const QStringList& childrenAlbums)
0204 {
0205     if (childrenAlbums.isEmpty())
0206     {
0207         return;
0208     }
0209 
0210     Q_FOREACH (const QString& albumId, childrenAlbums)
0211     {
0212         QTreeWidgetItem* const item = new QTreeWidgetItem(parent);
0213         item->setText(0, albumTree[albumId].title);
0214         item->setData(0, Qt::AccessibleDescriptionRole, albumId);
0215 
0216         /* Verify if album is editable. If yes, let it enable on view for albums list and
0217          * add a description for that. Otherwise, disable it and add description.
0218          *
0219          * However, in case of Facebook, GET album may return False for uploadable, but
0220          * indeed we can still upload to it.
0221          *
0222          * Hence, this functionality needs a more particular solution.
0223          */
0224         if (albumTree[albumId].uploadable)
0225         {
0226             item->setWhatsThis(0, QLatin1String("Albums that can be uploaded."));
0227         }
0228         else
0229         {
0230             // item->setDisabled(true);
0231             item->setWhatsThis(0, QLatin1String("Albums that cannot be uploaded."));
0232         }
0233 
0234         /*
0235          * Condition to call setCurrentItem for QTreeWidget is tested here to assure that after clicking on Reload, currentItem still points
0236          * to the same album as before
0237          */
0238         if (albumId == d->currentAlbumId)
0239         {
0240             d->albumView->setCurrentItem(item);
0241         }
0242 
0243         addChildToTreeView(item, albumTree, albumTree[albumId].childrenIDs);
0244     }
0245 }
0246 
0247 void WSImagesPage::slotListAlbumsDone(const QMap<QString, AlbumSimplified>& albumTree,
0248                                       const QStringList& rootAlbums,
0249                                       const QString& currentAlbumId)
0250 {
0251     d->albumView->clear();
0252 
0253     if (rootAlbums.isEmpty() || albumTree.isEmpty())
0254     {
0255         qCDebug(DIGIKAM_WEBSERVICES_LOG) << "WARNING: albums list is empty";
0256         return;
0257     }
0258 
0259     if (currentAlbumId.isEmpty())
0260     {
0261         d->currentAlbumId = rootAlbums.first();
0262     }
0263     else
0264     {
0265         d->currentAlbumId = currentAlbumId;
0266     }
0267 
0268     Q_FOREACH (const QString& albumId, rootAlbums)
0269     {
0270         QTreeWidgetItem* const item = new QTreeWidgetItem(d->albumView);
0271         item->setText(0, albumTree[albumId].title);
0272         item->setData(0, Qt::AccessibleDescriptionRole, albumId); // set ID hidden, so that we can use it for uploading photos to album
0273 
0274         /* Verify if album is editable. If yes, let it enable on view for albums list and
0275          * add a description for that. Otherwise, disable it and add description.
0276          *
0277          * However, in case of Facebook, GET album may return False for uploadable, but
0278          * indeed we can still upload to it.
0279          *
0280          * Hence, this functionality needs a more particular solution.
0281          */
0282         if (albumTree[albumId].uploadable)
0283         {
0284             item->setWhatsThis(0, QLatin1String("Albums that can be uploaded."));
0285         }
0286         else
0287         {
0288             // item->setDisabled(true);
0289             item->setWhatsThis(0, QLatin1String("Albums that cannot be uploaded."));
0290         }
0291 
0292         /*
0293          * Condition to call setCurrentItem for QTreeWidget is tested here to assure that after clicking on Reload, currentItem still points
0294          * to the same album as before
0295          */
0296         if (d->currentAlbumId == albumId)
0297         {
0298             d->albumView->setCurrentItem(item);
0299         }
0300 
0301         addChildToTreeView(item, albumTree, albumTree[albumId].childrenIDs);
0302     }
0303 }
0304 
0305 void WSImagesPage::slotCreateAlbumDone(int errCode, const QString& errMsg, const QString& newAlbumId)
0306 {
0307     if (errCode != 0)
0308     {
0309         QMessageBox::critical(QApplication::activeWindow(),
0310                               i18nc("@title:window", "%1 - Create Album Failed",  d->wsAuth->webserviceName()),
0311                               i18n("Code: %1. %2", errCode, errMsg));
0312         return;
0313     }
0314 
0315     // Pre-set currentAlbumId so that after refreshing, new album will be pre-selected
0316     setCurrentAlbumId(newAlbumId);
0317 
0318     // We need to refresh albums view
0319     Q_EMIT signalListAlbumsRequest();
0320 }
0321 
0322 } // namespace DigikamGenericUnifiedPlugin
0323 
0324 #include "moc_wsimagespage.cpp"