1 /* ============================================================
2 *
3 * This file is a part of kipi-plugins project
4 *
5 *
6 * Date : 2012-02-02
7 * Description : a plugin to export photos or videos to ImageShack web service
8 *
9 * Copyright (C) 2012 Dodon Victor <dodonvictor at gmail dot com>
10 *
11 * This program is free software; you can redistribute it
12 * and/or modify it under the terms of the GNU General
13 * Public License as published by the Free Software Foundation;
14 * either version 2, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * ============================================================ */
22
23 #include "imageshackwindow.h"
24
25 // Qt includes
26
27 #include <QWindow>
28 #include <QButtonGroup>
29 #include <QCheckBox>
30 #include <QCloseEvent>
31 #include <QDialog>
32 #include <QFileInfo>
33 #include <QGridLayout>
34 #include <QHBoxLayout>
35 #include <QLineEdit>
36 #include <QPlainTextEdit>
37 #include <QPointer>
38 #include <QPushButton>
39 #include <QRadioButton>
40 #include <QSpinBox>
41 #include <QVBoxLayout>
42 #include <QApplication>
43 #include <QIcon>
44 #include <QMenu>
45 #include <QComboBox>
46 #include <QMessageBox>
47 #include <QTimer>
48
49 // KDE includes
50
51 #include <kconfig.h>
52 #include <klocalizedstring.h>
53 #include <kwindowconfig.h>
54
55 // Libkipi includes
56
57 #include <KIPI/Interface>
58
59 // Local includes
60
61 #include "kipiplugins_debug.h"
62 #include "imageshack.h"
63 #include "imageshackwidget.h"
64 #include "imageshacktalker.h"
65 #include "kpaboutdata.h"
66 #include "kpimageslist.h"
67 #include "kpprogresswidget.h"
68 #include "kplogindialog.h"
69 #include "newalbumdlg.h"
70
71 namespace KIPIImageshackPlugin
72 {
73
ImageshackWindow(QWidget * const parent,Imageshack * const imghack)74 ImageshackWindow::ImageshackWindow(QWidget* const parent, Imageshack* const imghack)
75 : KPToolDialog(parent)
76 {
77 m_imageshack = imghack;
78 m_widget = new ImageshackWidget(this, imghack, iface(), QString::fromLatin1("ImageShack"));
79 m_widget->setMinimumSize(700, 500);
80 setMainWidget(m_widget);
81 setWindowTitle(i18n("Export to Imageshack"));
82 setModal(true);
83
84 m_albumDlg = new NewAlbumDlg(this, QString::fromLatin1("ImageShack"));
85
86 connect(m_widget->m_chgRegCodeBtn, SIGNAL(clicked(bool)),
87 this, SLOT(slotChangeRegistrantionCode()));
88
89 startButton()->setText(i18n("Upload"));
90 startButton()->setToolTip(i18n("Start upload to Imageshack web service"));
91
92 startButton()->setEnabled(false);
93
94 connect(m_widget->m_imgList, SIGNAL(signalImageListChanged()),
95 this, SLOT(slotImageListChanged()));
96
97 // About data
98 KPAboutData* const about = new KPAboutData(ki18n("Imageshack Export"),
99 ki18n("A tool to export images to Imageshack web service."),
100 ki18n("(c) 2012, Dodon Victor\n"));
101
102 about->addAuthor(ki18n("Dodon Victor").toString(),
103 ki18n("Author").toString(),
104 QString::fromLatin1("dodonvictor at gmail dot com"));
105
106 about->setHandbookEntry(QString::fromLatin1("tool-imageshackexport"));
107 setAboutData(about);
108
109 // -----------------------------------------------------------
110
111 connect(this, SIGNAL(signalBusy(bool)),
112 this, SLOT(slotBusy(bool)));
113
114 m_talker = new ImageshackTalker(imghack);
115
116 connect(m_talker, SIGNAL(signalBusy(bool)),
117 this, SLOT(slotBusy(bool)));
118
119 connect(m_talker, SIGNAL(signalJobInProgress(int,int,QString)),
120 this, SLOT(slotJobInProgress(int,int,QString)));
121
122 connect(m_talker, SIGNAL(signalLoginDone(int,QString)),
123 this, SLOT(slotLoginDone(int,QString)));
124
125 connect(m_talker, SIGNAL(signalGetGalleriesDone(int,QString)),
126 this, SLOT(slotGetGalleriesDone(int,QString)));
127
128 connect(m_talker, SIGNAL(signalUpdateGalleries(QStringList,QStringList)),
129 m_widget, SLOT(slotGetGalleries(QStringList,QStringList)));
130
131 connect(m_talker, SIGNAL(signalAddPhotoDone(int,QString)),
132 this, SLOT(slotAddPhotoDone(int,QString)));
133
134 connect(m_widget, SIGNAL(signalReloadGalleries()),
135 this, SLOT(slotGetGalleries()));
136
137 connect(startButton(), SIGNAL(clicked()),
138 this, SLOT(slotStartTransfer()));
139
140 connect(this, SIGNAL(finished(int)),
141 this, SLOT(slotFinished()));
142
143 connect(this, SIGNAL(cancelClicked()),
144 this, SLOT(slotCancelClicked()));
145
146 connect(m_widget->getNewAlbmBtn(),SIGNAL(clicked()),
147 this,SLOT(slotNewAlbumRequest()));
148
149 readSettings();
150
151 QTimer::singleShot(20, this, SLOT(authenticate()));
152 }
153
~ImageshackWindow()154 ImageshackWindow::~ImageshackWindow()
155 {
156 }
157
slotImageListChanged()158 void ImageshackWindow::slotImageListChanged()
159 {
160 startButton()->setEnabled(!m_widget->m_imgList->imageUrls().isEmpty());
161 }
162
slotFinished()163 void ImageshackWindow::slotFinished()
164 {
165 saveSettings();
166 m_widget->m_progressBar->progressCompleted();
167 m_widget->m_imgList->listView()->clear();
168 }
169
closeEvent(QCloseEvent * e)170 void ImageshackWindow::closeEvent(QCloseEvent* e)
171 {
172 if (!e)
173 {
174 return;
175 }
176
177 slotFinished();
178 e->accept();
179 }
180
readSettings()181 void ImageshackWindow::readSettings()
182 {
183 winId();
184 KConfig config(QString::fromLatin1("kipirc"));
185 KConfigGroup group = config.group("Imageshack Settings");
186 KWindowConfig::restoreWindowSize(windowHandle(), group);
187 resize(windowHandle()->size());
188
189 if (group.readEntry("Private", false))
190 {
191 m_widget->m_privateImagesChb->setChecked(true);
192 }
193
194 if (group.readEntry("Rembar", false))
195 {
196 m_widget->m_remBarChb->setChecked(true);
197 }
198 else
199 {
200 m_widget->m_remBarChb->setChecked(false);
201 }
202 }
203
saveSettings()204 void ImageshackWindow::saveSettings()
205 {
206 KConfig config(QString::fromLatin1("kipirc"));
207 KConfigGroup group = config.group("Imageshack Settings");
208 KWindowConfig::saveWindowSize(windowHandle(), group);
209
210 group.writeEntry("Private", m_widget->m_privateImagesChb->isChecked());
211 group.writeEntry("Rembar", m_widget->m_remBarChb->isChecked());
212 group.sync();
213 }
214
slotStartTransfer()215 void ImageshackWindow::slotStartTransfer()
216 {
217 m_widget->m_imgList->clearProcessedStatus();
218 m_transferQueue = m_widget->m_imgList->imageUrls();
219
220 if (m_transferQueue.isEmpty())
221 {
222 return;
223 }
224
225 qCDebug(KIPIPLUGINS_LOG) << "Transfer started!";
226
227 m_imagesTotal = m_transferQueue.count();
228 m_imagesCount = 0;
229
230 m_widget->m_progressBar->setFormat(i18n("%v / %m"));
231 m_widget->m_progressBar->setMaximum(m_imagesTotal);
232 m_widget->m_progressBar->setValue(0);
233 m_widget->m_progressBar->setVisible(true);
234 m_widget->m_progressBar->progressScheduled(i18n("Image Shack Export"), false, true);
235 m_widget->m_progressBar->progressThumbnailChanged(QIcon(QLatin1String(":/icons/kipi-icon.svg")).pixmap(22, 22));
236
237 uploadNextItem();
238 }
239
slotCancelClicked()240 void ImageshackWindow::slotCancelClicked()
241 {
242 m_talker->cancel();
243 m_transferQueue.clear();
244 m_widget->m_imgList->cancelProcess();
245 m_widget->m_progressBar->setVisible(false);
246 m_widget->m_progressBar->progressCompleted();
247 }
248
slotChangeRegistrantionCode()249 void ImageshackWindow::slotChangeRegistrantionCode()
250 {
251 qCDebug(KIPIPLUGINS_LOG) << "Change registration code";
252 authenticate();
253 }
254
authenticate()255 void ImageshackWindow::authenticate()
256 {
257 emit signalBusy(true);
258 m_widget->progressBar()->show();
259 m_widget->m_progressBar->setValue(0);
260 m_widget->m_progressBar->setMaximum(4);
261 m_widget->progressBar()->setFormat(i18n("Authenticating..."));
262
263 KIPIPlugins::KPLoginDialog* const dlg = new KIPIPlugins::KPLoginDialog(this, QString::fromLatin1("ImageShack"));
264
265 if (dlg->exec() == QDialog::Accepted)
266 {
267 m_imageshack->setEmail(dlg->login());
268 m_imageshack->setPassword(dlg->password());
269 m_talker->authenticate();
270 }
271 }
272
slotBusy(bool val)273 void ImageshackWindow::slotBusy(bool val)
274 {
275 if (val)
276 {
277 setCursor(Qt::WaitCursor);
278 m_widget->m_chgRegCodeBtn->setEnabled(false);
279 startButton()->setEnabled(false);
280 setRejectButtonMode(QDialogButtonBox::Cancel);
281 }
282 else
283 {
284 setCursor(Qt::ArrowCursor);
285 m_widget->m_chgRegCodeBtn->setEnabled(true);
286 startButton()->setEnabled(m_imageshack->loggedIn() &&
287 !m_widget->imagesList()->imageUrls().isEmpty());
288 setRejectButtonMode(QDialogButtonBox::Close);
289 }
290 }
291
slotJobInProgress(int step,int maxStep,const QString & format)292 void ImageshackWindow::slotJobInProgress(int step, int maxStep, const QString &format)
293 {
294 if (maxStep > 0)
295 {
296 m_widget->m_progressBar->setMaximum(maxStep);
297 }
298 m_widget->m_progressBar->setValue(step);
299
300 if (!format.isEmpty())
301 {
302 m_widget->m_progressBar->setFormat(format);
303 }
304 }
305
slotLoginDone(int errCode,const QString & errMsg)306 void ImageshackWindow::slotLoginDone(int errCode, const QString& errMsg)
307 {
308 m_widget->updateLabels();
309
310 if (!errCode && m_imageshack->loggedIn())
311 {
312 m_imageshack->saveSettings();
313 startButton()->setEnabled(!m_widget->imagesList()->imageUrls().isEmpty());
314 m_talker->getGalleries();
315 }
316 else
317 {
318 QMessageBox::critical(this, QString(), i18n("Login failed: %1\n", errMsg));
319 startButton()->setEnabled(false);
320 m_widget->m_progressBar->setVisible(false);
321 slotBusy(false);
322 }
323 }
324
slotGetGalleriesDone(int errCode,const QString & errMsg)325 void ImageshackWindow::slotGetGalleriesDone(int errCode, const QString &errMsg)
326 {
327 slotBusy(false);
328 m_widget->m_progressBar->setVisible(false);
329
330 if (errCode)
331 {
332 QMessageBox::critical(this, QString(), i18n("Failed to get galleries list: %1\n", errMsg));
333 }
334 }
335
uploadNextItem()336 void ImageshackWindow::uploadNextItem()
337 {
338 if (m_transferQueue.empty())
339 {
340 m_widget->m_progressBar->hide();
341 return;
342 }
343
344 m_widget->m_imgList->processing(m_transferQueue.first());
345 QString imgPath = m_transferQueue.first().toLocalFile();
346
347 m_widget->m_progressBar->setMaximum(m_imagesTotal);
348 m_widget->m_progressBar->setValue(m_imagesCount);
349
350 QMap<QString, QString> opts;
351
352 if (m_widget->m_privateImagesChb->isChecked())
353 {
354 opts[QString::fromLatin1("public")] = QString::fromLatin1("no");
355 }
356
357 if (m_widget->m_remBarChb->isChecked())
358 {
359 opts[QString::fromLatin1("rembar")] = QString::fromLatin1("yes");
360 }
361
362 // tags
363 if (!m_widget->m_tagsFld->text().isEmpty())
364 {
365 QString str = m_widget->m_tagsFld->text();
366 QStringList tagsList;
367 tagsList = str.split(QRegExp(QString::fromLatin1("\\W+")), QString::SkipEmptyParts);
368 opts[QString::fromLatin1("tags")] = tagsList.join(QString::fromLatin1(","));
369 }
370
371 opts[QString::fromLatin1("auth_token")] = m_imageshack->authToken();
372
373 int gidx = m_widget->m_galleriesCob->currentIndex();
374
375 qCDebug(KIPIPLUGINS_LOG) << "Album ID is "<< m_widget->m_galleriesCob->itemData(gidx).toString();
376
377 switch(gidx)
378 {
379 case 0:
380 m_talker->uploadItem(imgPath, opts);
381 break;
382 case 1:
383 opts[QString::fromLatin1("album")] = m_newAlbmTitle;
384 m_talker->uploadItemToGallery(imgPath, m_newAlbmTitle, opts);
385 break;
386 default:
387 opts[QString::fromLatin1("album")] = m_widget->m_galleriesCob->itemData(gidx).toString();
388 m_talker->uploadItemToGallery(imgPath, m_widget->m_galleriesCob->itemData(gidx).toString(), opts);
389 }
390 }
391
slotAddPhotoDone(int errCode,const QString & errMsg)392 void ImageshackWindow::slotAddPhotoDone(int errCode, const QString& errMsg)
393 {
394 m_widget->m_imgList->processed(m_transferQueue.first(), (errCode == 0));
395
396 if (!errCode)
397 {
398 m_widget->imagesList()->removeItemByUrl(m_transferQueue.first());
399 m_transferQueue.pop_front();
400 m_imagesCount++;
401 }
402 else
403 {
404 if (QMessageBox::question(this, i18n("Uploading Failed"),
405 i18n("Failed to upload photo into Imageshack: %1\n"
406 "Do you want to continue?", errMsg))
407 != QMessageBox::Yes)
408 {
409 m_widget->m_progressBar->setVisible(false);
410 m_transferQueue.clear();
411 return;
412 }
413 }
414
415 uploadNextItem();
416 }
417
slotGetGalleries()418 void ImageshackWindow::slotGetGalleries()
419 {
420 m_widget->m_progressBar->setVisible(true);
421 m_talker->getGalleries();
422 }
423
slotNewAlbumRequest()424 void ImageshackWindow::slotNewAlbumRequest()
425 {
426 if (m_albumDlg->exec() == QDialog::Accepted)
427 {
428 m_newAlbmTitle = m_albumDlg->getAlbumTitle();
429 }
430 }
431
432 } // namespace KIPIImageshackPlugin
433