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