File indexing completed on 2025-01-05 03:53:32
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2016-06-06 0007 * Description : a tool to export images to Imgur web service 0008 * 0009 * SPDX-FileCopyrightText: 2010-2012 by Marius Orcsik <marius at habarnam dot ro> 0010 * SPDX-FileCopyrightText: 2016 by Fabian Vogt <fabian at ritter dash vogt dot de> 0011 * SPDX-FileCopyrightText: 2013-2020 by Caulier Gilles <caulier dot gilles at gmail dot com> 0012 * 0013 * SPDX-License-Identifier: GPL-2.0-or-later 0014 * 0015 * ============================================================ */ 0016 0017 #include "imgurwindow.h" 0018 0019 // Qt includes 0020 0021 #include <QDesktopServices> 0022 #include <QInputDialog> 0023 #include <QCloseEvent> 0024 #include <QMessageBox> 0025 #include <QBoxLayout> 0026 #include <QWindow> 0027 0028 // KDE includes 0029 0030 #include <klocalizedstring.h> 0031 #include <ksharedconfig.h> 0032 #include <kconfiggroup.h> 0033 0034 // Local includes 0035 0036 #include "digikam_debug.h" 0037 #include "digikam_version.h" 0038 0039 namespace DigikamGenericImgUrPlugin 0040 { 0041 0042 class Q_DECL_HIDDEN ImgurWindow::Private 0043 { 0044 public: 0045 0046 explicit Private() 0047 : list (nullptr), 0048 api (nullptr), 0049 forgetButton (nullptr), 0050 uploadAnonButton (nullptr), 0051 userLabel (nullptr) 0052 { 0053 } 0054 0055 ImgurImagesList* list; 0056 ImgurTalker* api; 0057 QPushButton* forgetButton; 0058 QPushButton* uploadAnonButton; 0059 QLabel* userLabel; 0060 0061 /// Contains the imgur username if API authorized, else is null. 0062 QString username; 0063 }; 0064 0065 ImgurWindow::ImgurWindow(DInfoInterface* const iface, QWidget* const /*parent*/) 0066 : WSToolDialog(nullptr, QLatin1String("Imgur Dialog")), 0067 d (new Private) 0068 { 0069 d->api = new ImgurTalker(this); 0070 0071 // Connect API signals 0072 0073 connect(d->api, &ImgurTalker::signalAuthorized, 0074 this, &ImgurWindow::slotApiAuthorized); 0075 0076 connect(d->api, &ImgurTalker::signalAuthError, 0077 this, &ImgurWindow::slotApiAuthError); 0078 0079 connect(d->api, &ImgurTalker::signalProgress, 0080 this, &ImgurWindow::slotApiProgress); 0081 0082 connect(d->api, &ImgurTalker::signalRequestPin, 0083 this, &ImgurWindow::slotApiRequestPin); 0084 0085 connect(d->api, &ImgurTalker::signalSuccess, 0086 this, &ImgurWindow::slotApiSuccess); 0087 0088 connect(d->api, &ImgurTalker::signalError, 0089 this, &ImgurWindow::slotApiError); 0090 0091 connect(d->api, &ImgurTalker::signalBusy, 0092 this, &ImgurWindow::slotApiBusy); 0093 0094 // | List | Auth | 0095 0096 auto* const mainLayout = new QHBoxLayout; 0097 auto* const mainWidget = new QWidget(this); 0098 mainWidget->setLayout(mainLayout); 0099 this->setMainWidget(mainWidget); 0100 0101 d->list = new ImgurImagesList; 0102 d->list->setIface(iface); 0103 d->list->loadImagesFromCurrentSelection(); 0104 mainLayout->addWidget(d->list); 0105 0106 /* 0107 * | Logged in as: | 0108 * | <Not logged in> | 0109 * | Forget | 0110 */ 0111 auto* const userLabelLabel = new QLabel(i18n("Logged in as:")); 0112 userLabelLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); 0113 userLabelLabel->setAlignment(Qt::AlignHCenter | Qt::AlignTop); 0114 0115 // Label set in readSettings(). 0116 0117 d->userLabel = new QLabel; 0118 d->userLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); 0119 d->userLabel->setAlignment(Qt::AlignHCenter | Qt::AlignTop); 0120 0121 d->forgetButton = new QPushButton(i18n("Forget")); 0122 0123 auto* const authLayout = new QVBoxLayout; 0124 mainLayout->addLayout(authLayout); 0125 authLayout->addWidget(userLabelLabel); 0126 authLayout->addWidget(d->userLabel); 0127 authLayout->addWidget(d->forgetButton); 0128 authLayout->insertStretch(-1, 1); 0129 0130 // Add anonymous upload button 0131 0132 d->uploadAnonButton = new QPushButton(i18n("Upload Anonymously")); 0133 addButton(d->uploadAnonButton, QDialogButtonBox::ApplyRole); 0134 0135 // Connect UI signals 0136 0137 connect(d->forgetButton, &QPushButton::clicked, 0138 this, &ImgurWindow::slotForgetButtonClicked); 0139 0140 connect(startButton(), &QPushButton::clicked, 0141 this, &ImgurWindow::slotUpload); 0142 0143 connect(d->uploadAnonButton, &QPushButton::clicked, 0144 this, &ImgurWindow::slotAnonUpload); 0145 0146 connect(this, &ImgurWindow::finished, 0147 this, &ImgurWindow::slotFinished); 0148 0149 connect(this, &ImgurWindow::cancelClicked, 0150 this, &ImgurWindow::slotCancel); 0151 0152 setWindowTitle(i18nc("@title:window", "Export to imgur.com")); 0153 setModal(false); 0154 0155 startButton()->setText(i18nc("@action:button", "Upload")); 0156 startButton()->setToolTip(i18nc("@info:tooltip, button", "Start upload to Imgur")); 0157 startButton()->setEnabled(true); 0158 0159 // Only used if not overwritten by readSettings() 0160 0161 resize(650, 320); 0162 readSettings(); 0163 } 0164 0165 ImgurWindow::~ImgurWindow() 0166 { 0167 saveSettings(); 0168 delete d; 0169 } 0170 0171 void ImgurWindow::setItemsList(const QList<QUrl>& urls) 0172 { 0173 d->list->slotAddImages(urls); 0174 } 0175 0176 void ImgurWindow::reactivate() 0177 { 0178 d->list->loadImagesFromCurrentSelection(); 0179 show(); 0180 } 0181 0182 void ImgurWindow::slotForgetButtonClicked() 0183 { 0184 d->api->getAuth().unlink(); 0185 0186 slotApiAuthorized(false, {}); 0187 } 0188 0189 void ImgurWindow::slotUpload() 0190 { 0191 QList<const ImgurImageListViewItem*> pending = d->list->getPendingItems(); 0192 0193 for (const auto& item : qAsConst(pending)) 0194 { 0195 ImgurTalkerAction action; 0196 action.type = ImgurTalkerActionType::IMG_UPLOAD; 0197 action.upload.imgpath = item->url().toLocalFile(); 0198 action.upload.title = item->Title(); 0199 action.upload.description = item->Description(); 0200 0201 d->api->queueWork(action); 0202 } 0203 } 0204 0205 void ImgurWindow::slotAnonUpload() 0206 { 0207 QList<const ImgurImageListViewItem*> pending = d->list->getPendingItems(); 0208 0209 for (const auto& item : qAsConst(pending)) 0210 { 0211 ImgurTalkerAction action; 0212 action.type = ImgurTalkerActionType::ANON_IMG_UPLOAD; 0213 action.upload.imgpath = item->url().toLocalFile(); 0214 action.upload.title = item->Title(); 0215 action.upload.description = item->Description(); 0216 0217 d->api->queueWork(action); 0218 } 0219 } 0220 0221 void ImgurWindow::slotFinished() 0222 { 0223 saveSettings(); 0224 } 0225 0226 void ImgurWindow::slotCancel() 0227 { 0228 d->api->cancelAllWork(); 0229 } 0230 0231 void ImgurWindow::slotApiAuthorized(bool success, const QString& username) 0232 { 0233 if (success) 0234 { 0235 d->username = username; 0236 d->userLabel->setText(d->username); 0237 d->forgetButton->setEnabled(true); 0238 return; 0239 } 0240 0241 d->username = QString(); 0242 d->userLabel->setText(i18n("<i>Not logged in</i>")); 0243 d->forgetButton->setEnabled(false); 0244 } 0245 0246 void ImgurWindow::slotApiAuthError(const QString& msg) 0247 { 0248 QMessageBox::critical(this, 0249 i18nc("@title:window", "Authorization Failed"), 0250 i18n("Failed to log into Imgur: %1\n", msg)); 0251 } 0252 0253 void ImgurWindow::slotApiProgress(unsigned int /*percent*/, const ImgurTalkerAction& action) 0254 { 0255 d->list->processing(QUrl::fromLocalFile(action.upload.imgpath)); 0256 } 0257 0258 void ImgurWindow::slotApiRequestPin(const QUrl& url) 0259 { 0260 QDesktopServices::openUrl(url); 0261 } 0262 0263 void ImgurWindow::slotApiSuccess(const ImgurTalkerResult& result) 0264 { 0265 d->list->slotSuccess(result); 0266 } 0267 0268 void ImgurWindow::slotApiError(const QString& msg, const ImgurTalkerAction& action) 0269 { 0270 d->list->processed(QUrl::fromLocalFile(action.upload.imgpath), false); 0271 0272 // 1 here because the current item is still in the queue. 0273 0274 if (d->api->workQueueLength() <= 1) 0275 { 0276 QMessageBox::critical(this, 0277 i18nc("@title:window", "Uploading Failed"), 0278 i18n("Failed to upload photo to Imgur: %1\n", msg)); 0279 return; 0280 } 0281 0282 QMessageBox::StandardButton cont = 0283 QMessageBox::question(this, 0284 i18nc("@title:window", "Uploading Failed"), 0285 i18n("Failed to upload photo to Imgur: %1\n" 0286 "Do you want to continue?", msg)); 0287 0288 if (cont != QMessageBox::Yes) 0289 { 0290 d->api->cancelAllWork(); 0291 } 0292 } 0293 0294 void ImgurWindow::slotApiBusy(bool busy) 0295 { 0296 setCursor(busy ? Qt::WaitCursor : Qt::ArrowCursor); 0297 startButton()->setEnabled(!busy); 0298 } 0299 0300 void ImgurWindow::closeEvent(QCloseEvent* e) 0301 { 0302 if (!e) 0303 { 0304 return; 0305 } 0306 0307 slotFinished(); 0308 e->accept(); 0309 } 0310 0311 void ImgurWindow::readSettings() 0312 { 0313 KSharedConfigPtr config = KSharedConfig::openConfig(); 0314 KConfigGroup groupAuth = config->group(QLatin1String("Imgur Auth")); 0315 d->username = groupAuth.readEntry("username", QString()); 0316 slotApiAuthorized(!d->username.isEmpty(), d->username); 0317 } 0318 0319 void ImgurWindow::saveSettings() 0320 { 0321 KSharedConfigPtr config = KSharedConfig::openConfig(); 0322 KConfigGroup groupAuth = config->group(QLatin1String("Imgur Auth")); 0323 groupAuth.writeEntry("username", d->username); 0324 } 0325 0326 } // namespace DigikamGenericImgUrPlugin 0327 0328 #include "moc_imgurwindow.cpp"