1 /* ============================================================
2 *
3 * This file is a part of KDE project
4 *
5 *
6 * Date : 2013-11-18
7 * Description : a kipi plugin to export images to Dropbox web service
8 *
9 * Copyright (C) 2013 by Pankaj Kumar <me at panks dot me>
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 "dbwindow.h"
24
25 // Qt includes
26
27 #include <QWindow>
28 #include <QSpinBox>
29 #include <QCheckBox>
30 #include <QMessageBox>
31 #include <QCloseEvent>
32
33 // KDE includes
34
35 #include <klocalizedstring.h>
36 #include <kconfig.h>
37 #include <kwindowconfig.h>
38
39 // Libkipi includes
40
41 #include <KIPI/Interface>
42
43 // Local includes
44
45 #include "kipiplugins_debug.h"
46 #include "kpimageslist.h"
47 #include "kpaboutdata.h"
48 #include "kpimageinfo.h"
49 #include "kpversion.h"
50 #include "kpprogresswidget.h"
51 #include "dbtalker.h"
52 #include "dbitem.h"
53 #include "dbalbum.h"
54 #include "dbwidget.h"
55
56 namespace KIPIDropboxPlugin
57 {
58
DBWindow(const QString & tmpFolder,QWidget * const)59 DBWindow::DBWindow(const QString& tmpFolder, QWidget* const /*parent*/)
60 : KPToolDialog(nullptr)
61 {
62 m_tmp = tmpFolder;
63 m_imagesCount = 0;
64 m_imagesTotal = 0;
65
66 m_widget = new DropboxWidget(this, iface(), QLatin1String("Dropbox"));
67 setMainWidget(m_widget);
68 setWindowIcon(QIcon::fromTheme(QLatin1String("kipi-dropbox")));
69 setModal(false);
70 setWindowTitle(i18n("Export to Dropbox"));
71
72 startButton()->setText(i18n("Start Upload"));
73 startButton()->setToolTip(i18n("Start upload to Dropbox"));
74
75 m_widget->setMinimumSize(700, 500);
76
77 connect(m_widget->imagesList(), SIGNAL(signalImageListChanged()),
78 this, SLOT(slotImageListChanged()));
79
80 connect(m_widget->getChangeUserBtn(), SIGNAL(clicked()),
81 this, SLOT(slotUserChangeRequest()));
82
83 connect(m_widget->getNewAlbmBtn(), SIGNAL(clicked()),
84 this, SLOT(slotNewAlbumRequest()));
85
86 connect(m_widget->getReloadBtn(), SIGNAL(clicked()),
87 this, SLOT(slotReloadAlbumsRequest()));
88
89 connect(startButton(), SIGNAL(clicked()),
90 this, SLOT(slotStartTransfer()));
91
92 KPAboutData* const about = new KPAboutData(ki18n("Dropbox Export"),
93 ki18n("A tool to export images "
94 "to Dropbox"),
95 ki18n("(c) 2013, Saurabh Patel"));
96
97 about->addAuthor(ki18n("Saurabh Patel").toString(),
98 ki18n("Author").toString(),
99 QLatin1String("saurabhpatel7717 at gmail dot com"));
100
101 about->setHandbookEntry(QLatin1String("tool-dropboxexport"));
102 setAboutData(about);
103
104 //-------------------------------------------------------------------------
105
106 m_albumDlg = new DBNewAlbum(this, QLatin1String("Dropbox"));
107
108 //-------------------------------------------------------------------------
109
110 m_talker = new DBTalker(this);
111
112 connect(m_talker,SIGNAL(signalBusy(bool)),
113 this,SLOT(slotBusy(bool)));
114
115 connect(m_talker,SIGNAL(signalLinkingFailed()),
116 this,SLOT(slotSignalLinkingFailed()));
117
118 connect(m_talker,SIGNAL(signalLinkingSucceeded()),
119 this,SLOT(slotSignalLinkingSucceeded()));
120
121 connect(m_talker,SIGNAL(signalSetUserName(QString)),
122 this,SLOT(slotSetUserName(QString)));
123
124 connect(m_talker,SIGNAL(signalListAlbumsFailed(QString)),
125 this,SLOT(slotListAlbumsFailed(QString)));
126
127 connect(m_talker,SIGNAL(signalListAlbumsDone(QList<QPair<QString,QString> >)),
128 this,SLOT(slotListAlbumsDone(QList<QPair<QString,QString> >)));
129
130 connect(m_talker,SIGNAL(signalCreateFolderFailed(QString)),
131 this,SLOT(slotCreateFolderFailed(QString)));
132
133 connect(m_talker,SIGNAL(signalCreateFolderSucceeded()),
134 this,SLOT(slotCreateFolderSucceeded()));
135
136 connect(m_talker,SIGNAL(signalAddPhotoFailed(QString)),
137 this,SLOT(slotAddPhotoFailed(QString)));
138
139 connect(m_talker,SIGNAL(signalAddPhotoSucceeded()),
140 this,SLOT(slotAddPhotoSucceeded()));
141
142 connect(this, SIGNAL(finished(int)),
143 this, SLOT(slotFinished()));
144
145 readSettings();
146 buttonStateChange(false);
147
148 m_talker->link();
149 }
150
~DBWindow()151 DBWindow::~DBWindow()
152 {
153 delete m_widget;
154 delete m_albumDlg;
155 delete m_talker;
156 }
157
reactivate()158 void DBWindow::reactivate()
159 {
160 m_widget->imagesList()->loadImagesFromCurrentSelection();
161 m_widget->progressBar()->hide();
162
163 show();
164 }
165
readSettings()166 void DBWindow::readSettings()
167 {
168 KConfig config(QLatin1String("kipirc"));
169 KConfigGroup grp = config.group("Dropbox Settings");
170
171 m_currentAlbumName = grp.readEntry("Current Album",QString());
172
173 if (grp.readEntry("Resize", false))
174 {
175 m_widget->getResizeCheckBox()->setChecked(true);
176 m_widget->getDimensionSpB()->setEnabled(true);
177 m_widget->getImgQualitySpB()->setEnabled(true);
178 }
179 else
180 {
181 m_widget->getResizeCheckBox()->setChecked(false);
182 m_widget->getDimensionSpB()->setEnabled(false);
183 m_widget->getImgQualitySpB()->setEnabled(false);
184 }
185
186 m_widget->getDimensionSpB()->setValue(grp.readEntry("Maximum Width", 1600));
187 m_widget->getImgQualitySpB()->setValue(grp.readEntry("Image Quality", 90));
188
189 winId();
190 KConfigGroup dialogGroup = config.group("Dropbox Export Dialog");
191 KWindowConfig::restoreWindowSize(windowHandle(), dialogGroup);
192 resize(windowHandle()->size());
193 }
194
writeSettings()195 void DBWindow::writeSettings()
196 {
197 KConfig config(QLatin1String("kipirc"));
198 KConfigGroup grp = config.group("Dropbox Settings");
199
200 grp.writeEntry("Current Album", m_currentAlbumName);
201 grp.writeEntry("Resize", m_widget->getResizeCheckBox()->isChecked());
202 grp.writeEntry("Maximum Width", m_widget->getDimensionSpB()->value());
203 grp.writeEntry("Image Quality", m_widget->getImgQualitySpB()->value());
204
205 KConfigGroup dialogGroup = config.group("Dropbox Export Dialog");
206 KWindowConfig::saveWindowSize(windowHandle(), dialogGroup);
207
208 config.sync();
209 }
210
slotSetUserName(const QString & msg)211 void DBWindow::slotSetUserName(const QString& msg)
212 {
213 m_widget->updateLabels(msg, QLatin1String(""));
214 }
215
slotListAlbumsDone(const QList<QPair<QString,QString>> & list)216 void DBWindow::slotListAlbumsDone(const QList<QPair<QString,QString> >& list)
217 {
218 m_widget->getAlbumsCoB()->clear();
219 qCDebug(KIPIPLUGINS_LOG) << "slotListAlbumsDone:" << list.size();
220
221 for(int i = 0 ; i < list.size() ; i++)
222 {
223 m_widget->getAlbumsCoB()->addItem(
224 QIcon::fromTheme(QLatin1String("system-users")),
225 list.value(i).second, list.value(i).first);
226
227 if (m_currentAlbumName == list.value(i).first)
228 {
229 m_widget->getAlbumsCoB()->setCurrentIndex(i);
230 }
231 }
232
233 buttonStateChange(true);
234 m_talker->getUserName();
235 }
236
slotBusy(bool val)237 void DBWindow::slotBusy(bool val)
238 {
239 if (val)
240 {
241 setCursor(Qt::WaitCursor);
242 m_widget->getChangeUserBtn()->setEnabled(false);
243 buttonStateChange(false);
244 }
245 else
246 {
247 setCursor(Qt::ArrowCursor);
248 m_widget->getChangeUserBtn()->setEnabled(true);
249 buttonStateChange(true);
250 }
251 }
252
slotStartTransfer()253 void DBWindow::slotStartTransfer()
254 {
255 m_widget->imagesList()->clearProcessedStatus();
256
257 if (m_widget->imagesList()->imageUrls().isEmpty())
258 {
259 QMessageBox::critical(this, i18nc("@title:window", "Error"),
260 i18n("No image selected. Please select which images should be uploaded."));
261 return;
262 }
263
264 if (!(m_talker->authenticated()))
265 {
266 if (QMessageBox::question(this, i18n("Login Failed"),
267 i18n("Authentication failed. Do you want to try again?"))
268 == QMessageBox::Yes)
269 {
270 m_talker->link();
271 return;
272 }
273 else
274 {
275 return;
276 }
277 }
278
279 m_transferQueue = m_widget->imagesList()->imageUrls();
280
281 if (m_transferQueue.isEmpty())
282 {
283 return;
284 }
285
286 m_currentAlbumName = m_widget->getAlbumsCoB()->itemData(m_widget->getAlbumsCoB()->currentIndex()).toString();
287
288 m_imagesTotal = m_transferQueue.count();
289 m_imagesCount = 0;
290
291 m_widget->progressBar()->setFormat(i18n("%v / %m"));
292 m_widget->progressBar()->setMaximum(m_imagesTotal);
293 m_widget->progressBar()->setValue(0);
294 m_widget->progressBar()->show();
295 m_widget->progressBar()->progressScheduled(i18n("Dropbox export"), true, true);
296 m_widget->progressBar()->progressThumbnailChanged(
297 QIcon(QLatin1String(":/icons/kipi-icon.svg")).pixmap(22, 22));
298
299 uploadNextPhoto();
300 }
301
uploadNextPhoto()302 void DBWindow::uploadNextPhoto()
303 {
304 qCDebug(KIPIPLUGINS_LOG) << "uploadNextPhoto:" << m_transferQueue.count();
305
306 if (m_transferQueue.isEmpty())
307 {
308 qCDebug(KIPIPLUGINS_LOG) << "empty";
309 m_widget->progressBar()->progressCompleted();
310 return;
311 }
312
313 QString imgPath = m_transferQueue.first().toLocalFile();
314 QString temp = m_currentAlbumName + QLatin1String("/");
315
316 bool res = m_talker->addPhoto(imgPath,temp,m_widget->getResizeCheckBox()->isChecked(),m_widget->getDimensionSpB()->value(),
317 m_widget->getImgQualitySpB()->value());
318
319 if (!res)
320 {
321 slotAddPhotoFailed(QLatin1String(""));
322 return;
323 }
324 }
325
slotAddPhotoFailed(const QString & msg)326 void DBWindow::slotAddPhotoFailed(const QString& msg)
327 {
328 if (QMessageBox::question(this, i18n("Uploading Failed"),
329 i18n("Failed to upload photo to Dropbox."
330 "\n%1\n"
331 "Do you want to continue?", msg))
332 != QMessageBox::Yes)
333 {
334 m_transferQueue.clear();
335 m_widget->progressBar()->hide();
336 }
337 else
338 {
339 m_transferQueue.pop_front();
340 m_imagesTotal--;
341 m_widget->progressBar()->setMaximum(m_imagesTotal);
342 m_widget->progressBar()->setValue(m_imagesCount);
343 uploadNextPhoto();
344 }
345 }
346
slotAddPhotoSucceeded()347 void DBWindow::slotAddPhotoSucceeded()
348 {
349 // Remove photo uploaded from the list
350 m_widget->imagesList()->removeItemByUrl(m_transferQueue.first());
351 m_transferQueue.pop_front();
352 m_imagesCount++;
353 m_widget->progressBar()->setMaximum(m_imagesTotal);
354 m_widget->progressBar()->setValue(m_imagesCount);
355 uploadNextPhoto();
356 }
357
slotImageListChanged()358 void DBWindow::slotImageListChanged()
359 {
360 startButton()->setEnabled(!(m_widget->imagesList()->imageUrls().isEmpty()));
361 }
362
slotNewAlbumRequest()363 void DBWindow::slotNewAlbumRequest()
364 {
365 if (m_albumDlg->exec() == QDialog::Accepted)
366 {
367 DBFolder newFolder;
368 m_albumDlg->getFolderTitle(newFolder);
369 qCDebug(KIPIPLUGINS_LOG) << "slotNewAlbumRequest:" << newFolder.title;
370 m_currentAlbumName = m_widget->getAlbumsCoB()->itemData(m_widget->getAlbumsCoB()->currentIndex()).toString();
371 QString temp = m_currentAlbumName + newFolder.title;
372 m_talker->createFolder(temp);
373 }
374 }
375
slotReloadAlbumsRequest()376 void DBWindow::slotReloadAlbumsRequest()
377 {
378 m_talker->listFolders();
379 }
380
slotSignalLinkingFailed()381 void DBWindow::slotSignalLinkingFailed()
382 {
383 slotSetUserName(QLatin1String(""));
384 m_widget->getAlbumsCoB()->clear();
385
386 if (QMessageBox::question(this, i18n("Login Failed"),
387 i18n("Authentication failed. Do you want to try again?"))
388 == QMessageBox::Yes)
389 {
390 m_talker->link();
391 }
392 }
393
slotSignalLinkingSucceeded()394 void DBWindow::slotSignalLinkingSucceeded()
395 {
396 m_talker->listFolders();
397 }
398
slotListAlbumsFailed(const QString & msg)399 void DBWindow::slotListAlbumsFailed(const QString& msg)
400 {
401 QMessageBox::critical(this, QString(), i18n("Dropbox call failed:\n%1", msg));
402 }
403
slotCreateFolderFailed(const QString & msg)404 void DBWindow::slotCreateFolderFailed(const QString& msg)
405 {
406 QMessageBox::critical(this, QString(), i18n("Dropbox call failed:\n%1", msg));
407 }
408
slotCreateFolderSucceeded()409 void DBWindow::slotCreateFolderSucceeded()
410 {
411 m_talker->listFolders();
412 }
413
slotTransferCancel()414 void DBWindow::slotTransferCancel()
415 {
416 m_transferQueue.clear();
417 m_widget->progressBar()->hide();
418 m_talker->cancel();
419 }
420
slotUserChangeRequest()421 void DBWindow::slotUserChangeRequest()
422 {
423 slotSetUserName(QLatin1String(""));
424 m_widget->getAlbumsCoB()->clear();
425 m_talker->unLink();
426 m_talker->link();
427 }
428
buttonStateChange(bool state)429 void DBWindow::buttonStateChange(bool state)
430 {
431 m_widget->getNewAlbmBtn()->setEnabled(state);
432 m_widget->getReloadBtn()->setEnabled(state);
433 startButton()->setEnabled(state);
434 }
435
slotFinished()436 void DBWindow::slotFinished()
437 {
438 writeSettings();
439 m_widget->imagesList()->listView()->clear();
440 }
441
closeEvent(QCloseEvent * e)442 void DBWindow::closeEvent(QCloseEvent* e)
443 {
444 if (!e)
445 {
446 return;
447 }
448
449 slotFinished();
450 e->accept();
451 }
452
453 } // namespace KIPIDropboxPlugin
454