1 /* ============================================================
2  *
3  * This file is a part of KDE project
4  *
5  *
6  * Date        : 2011-04-12
7  * Description : A KIPI Plugin to export albums to rajce.net
8  *
9  * Copyright (C) 2011 by Lukas Krejci <krejci.l at centrum dot cz>
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 "rajcewidget.h"
24 
25 // Qt includes
26 
27 #include <QLabel>
28 #include <QSpinBox>
29 #include <QCheckBox>
30 #include <QGroupBox>
31 #include <QButtonGroup>
32 #include <QRadioButton>
33 #include <QProgressBar>
34 #include <QGridLayout>
35 #include <QHBoxLayout>
36 #include <QVBoxLayout>
37 #include <QDialog>
38 #include <QComboBox>
39 #include <QApplication>
40 #include <QStyle>
41 
42 // KDE includes
43 
44 #include <klocalizedstring.h>
45 #include <kconfig.h>
46 #include <kconfiggroup.h>
47 
48 // Libkipi includes
49 
50 #include <KIPI/Interface>
51 #include <KIPI/UploadWidget>
52 
53 // Local includes
54 
55 #include "rajcesession.h"
56 #include "newalbumdialog.h"
57 #include "kpimageslist.h"
58 #include "kpsettingswidget.h"
59 #include "kplogindialog.h"
60 
61 namespace KIPIRajcePlugin
62 {
63 
RajceWidget(KIPI::Interface * const interface,const QString & tmpFolder,QWidget * const parent)64 RajceWidget::RajceWidget(KIPI::Interface* const interface, const QString& tmpFolder, QWidget* const parent)
65     : KPSettingsWidget(parent, interface, QString::fromLatin1("Rajce.net"))
66 {
67     m_lastLoggedInState           = false;
68     m_session                     = new RajceSession(this, tmpFolder);
69 
70     m_uploadingPhotos = false;
71     m_albumsCoB       = getAlbumsCoB();
72     m_dimensionSpB    = getDimensionSpB();
73     m_imageQualitySpB = getImgQualitySpB();
74     m_newAlbumBtn     = getNewAlbmBtn();
75     m_reloadAlbumsBtn = getReloadBtn();
76     m_progressBar     = progressBar();
77     m_imgList         = imagesList();
78     m_changeUserBtn   = getChangeUserBtn();
79 
80     getUploadBox()->hide();
81     getSizeBox()->hide();
82 
83     updateLabels();
84 
85     // ------------------------------------------------------------------------
86 
87     connect(m_session, SIGNAL(busyStarted(uint)),
88             this, SLOT(progressStarted(uint)));
89 
90     connect(m_session, SIGNAL(busyFinished(uint)),
91             this, SLOT(progressFinished(uint)));
92 
93     connect(m_session, SIGNAL(busyProgress(uint,uint)),
94             this, SLOT(progressChange(uint,uint)));
95 
96     connect(m_changeUserBtn, SIGNAL(clicked()),
97             this, SLOT(changeUserClicked()));
98 
99     connect(m_newAlbumBtn, SIGNAL(clicked()),
100             this, SLOT(createAlbum()));
101 
102     connect(m_reloadAlbumsBtn, SIGNAL(clicked()),
103             this, SLOT(loadAlbums()));
104 
105     connect(m_albumsCoB, SIGNAL(currentIndexChanged(QString)),
106             this, SLOT(selectedAlbumChanged(QString)));
107 }
108 
updateLabels(const QString &,const QString &)109 void RajceWidget::updateLabels(const QString&, const QString&)
110 {
111     bool loggedIn = !m_session->state().sessionToken().isEmpty();
112 
113     if (loggedIn != m_lastLoggedInState)
114     {
115         m_lastLoggedInState = loggedIn;
116         emit loginStatusChanged(loggedIn);
117     }
118 
119     QString username = loggedIn ? m_session->state().username() : QString::fromLatin1("");
120     QString nickname = loggedIn ? m_session->state().nickname() : i18n("Not logged in");
121 
122     getUserNameLabel()->setText(QString::fromLatin1("<b>%2</b> <small>%1</small>").arg(username, nickname));
123 
124     QString link = loggedIn
125         ? QString::fromLatin1("<b><h2><a href='http://") + m_session->state().nickname() +
126         QString::fromLatin1(".rajce.net'>"
127         "<font color=\"#9ACD32\">Rajce.net</font>"
128         "</a></h2></b>")
129         : QString::fromLatin1("<b><h2><a href='http://www.rajce.net'>"
130         "<font color=\"#9ACD32\">Rajce.net</font>"
131         "</a></h2></b>");
132 
133     getHeaderLbl()->setText(link);
134 
135     disconnect(m_albumsCoB, SIGNAL(currentIndexChanged(QString)),
136                this, SLOT(selectedAlbumChanged(QString)));
137 
138     m_albumsCoB->clear();
139     Album album;
140     int   selIdx = 0, i = 0;
141 
142     foreach(album, m_session->state().albums())
143     {
144         m_albumsCoB->addItem(album.name, QVariant::fromValue(album));
145 
146         if (m_currentAlbumName == album.name)
147         {
148             selIdx = i;
149         }
150 
151         ++i;
152     }
153 
154     if (!m_currentAlbumName.isEmpty())
155     {
156         m_albumsCoB->setCurrentIndex(selIdx);
157     }
158 
159     connect(m_albumsCoB, SIGNAL(currentIndexChanged(QString)),
160             this, SLOT(selectedAlbumChanged(QString)));
161 
162     unsigned max = m_session->state().maxHeight();
163     max          = max > m_session->state().maxWidth() ? max
164                                                        : m_session->state().maxWidth();
165     m_dimensionSpB->setMaximum(max);
166 
167     if (m_dimensionSpB->value() == 0)
168     {
169         m_dimensionSpB->setValue(max);
170     }
171 
172     m_newAlbumBtn->setEnabled(loggedIn);
173     m_albumsCoB->setEnabled(loggedIn);
174     m_reloadAlbumsBtn->setEnabled(loggedIn);
175     m_dimensionSpB->setEnabled(loggedIn);
176     m_imageQualitySpB->setEnabled(loggedIn);
177 
178     if (m_session->state().lastErrorCode() != 0)
179     {
180         m_progressBar->setVisible(true);
181 
182         switch (m_session->state().lastErrorCode())
183         {
184             case UnknownError:                   m_progressBar->setFormat(i18n("Unknown error"));                  break;
185             case InvalidCommand:                 m_progressBar->setFormat(i18n("Invalid command"));                break;
186             case InvalidCredentials:             m_progressBar->setFormat(i18n("Invalid login name or password")); break;
187             case InvalidSessionToken:            m_progressBar->setFormat(i18n("Session expired"));                break;
188             case InvalidOrRepeatedColumnName:                                                                      break;
189             case InvalidAlbumId:                 m_progressBar->setFormat(i18n("Unknown album"));                  break;
190             case AlbumDoesntExistOrNoPrivileges: m_progressBar->setFormat(i18n("Unknown album"));                  break;
191             case InvalidAlbumToken:              m_progressBar->setFormat(i18n("Failed to open album"));           break;
192             case AlbumNameEmpty:                 m_progressBar->setFormat(i18n("The album name cannot be empty")); break;
193             case FailedToCreateAlbum:            m_progressBar->setFormat(i18n("Failed to create album"));         break;
194             case AlbumDoesntExist:               m_progressBar->setFormat(i18n("Album does not exist"));           break;
195             case UnknownApplication:                                                                               break;
196             case InvalidApplicationKey:                                                                            break;
197             case FileNotAttached:                m_progressBar->setFormat(i18n("File upload failed"));             break;
198             case NewerVersionExists:                                                                               break;
199             case SavingFileFailed:               m_progressBar->setFormat(i18n("File upload failed"));             break;
200             case UnsupportedFileExtension:       m_progressBar->setFormat(i18n("Unsupported file extension"));     break;
201             case UnknownClientVersion:                                                                             break;
202             case NonexistentTarget:                                                                                break;
203             default:                                                                                               break;
204         }
205 
206         QPalette palette = m_progressBar->palette();
207         palette.setColor(QPalette::Active, QPalette::Window, Qt::darkRed);
208         m_progressBar->setPalette(palette);
209     }
210 }
211 
reactivate()212 void RajceWidget::reactivate()
213 {
214     m_imgList->listView()->clear();
215     m_imgList->loadImagesFromCurrentSelection();
216     m_session->clearLastError();
217     updateLabels();
218 }
219 
progressChange(unsigned,unsigned int percent)220 void RajceWidget::progressChange(unsigned /*commandType*/, unsigned int percent)
221 {
222     if (m_uploadingPhotos)
223     {
224         unsigned idx  = m_currentUploadImage - m_uploadQueue.begin() - 1;
225         float perc    = (float)idx / m_uploadQueue.size();
226         perc         += (float)percent / 100 / m_uploadQueue.size();
227         percent       = perc * 100;
228     }
229 
230     m_progressBar->setValue(percent);
231 }
232 
progressFinished(unsigned)233 void RajceWidget::progressFinished(unsigned)
234 {
235     if (m_uploadingPhotos)
236     {
237         unsigned idx = m_currentUploadImage - m_uploadQueue.begin();
238         float perc   = (float)idx / m_uploadQueue.size();
239 
240         m_progressBar->setValue(perc * 100);
241     }
242     else
243     {
244         m_progressBar->setVisible(false);
245         _setEnabled(true);
246         updateLabels();
247     }
248 }
249 
progressStarted(unsigned commandType)250 void RajceWidget::progressStarted(unsigned commandType)
251 {
252     QString text;
253 
254 /*
255     enum RajceCommandType
256     {
257         Login = 0,
258         Logout,
259         ListAlbums,
260         CreateAlbum,
261         OpenAlbum,
262         CloseAlbum,
263         AddPhoto
264     };
265 */
266 
267     switch(commandType)
268     {
269         case Login:       text = i18n("Logging in %v%");     break;
270         case Logout:      text = i18n("Logging out %v%");    break;
271         case ListAlbums:  text = i18n("Loading albums %v%"); break;
272         case CreateAlbum: text = i18n("Creating album %v%"); break;
273         case OpenAlbum:   text = i18n("Opening album %v%");  break;
274         case CloseAlbum:  text = i18n("Closing album %v%");  break;
275         case AddPhoto:    text = i18n("Adding photos %v%");  break;
276     }
277 
278     if (!m_uploadingPhotos)
279     {
280         m_progressBar->setValue(0);
281     }
282 
283     m_progressBar->setFormat(text);
284     m_progressBar->setVisible(true);
285     _setEnabled(false);
286 }
287 
changeUserClicked()288 void RajceWidget::changeUserClicked()
289 {
290     KIPIPlugins::KPLoginDialog* const dlg = new KIPIPlugins::KPLoginDialog(this, QString::fromLatin1("Rajce.net"));
291 
292     if (dlg->exec() == QDialog::Accepted)
293     {
294         m_session->clearLastError();
295 
296         connect(m_session, SIGNAL(busyFinished(uint)),
297                 this, SLOT(loadAlbums()));
298 
299         m_session->login(dlg->login(), dlg->password());
300     }
301 
302     delete dlg;
303 }
304 
loadAlbums()305 void RajceWidget::loadAlbums()
306 {
307     disconnect(m_session, SIGNAL(busyFinished(uint)),
308                this, SLOT(loadAlbums()));
309 
310     m_session->loadAlbums();
311 }
312 
createAlbum()313 void RajceWidget::createAlbum()
314 {
315     NewAlbumDialog* const dlg = new NewAlbumDialog(this);
316 
317     if (dlg->exec() == QDialog::Accepted)
318     {
319         m_session->clearLastError();
320 
321         connect(m_session, SIGNAL(busyFinished(uint)),
322                 this, SLOT(loadAlbums()));
323 
324         m_session->createAlbum(dlg->albumName(), dlg->albumDescription(), dlg->albumVisible());
325     }
326 
327     delete dlg;
328 }
329 
startUpload()330 void RajceWidget::startUpload()
331 {
332     m_session->clearLastError();
333     _setEnabled(false);
334 
335     m_uploadQueue.clear();
336 
337     foreach(const QUrl& image, m_imgList->imageUrls(true))
338     {
339         QString imagePath = image.toLocalFile();
340         m_uploadQueue.append(imagePath);
341     }
342 
343     if (m_uploadQueue.isEmpty())
344     {
345         _setEnabled(true);
346         return;
347     }
348 
349     connect(m_session, SIGNAL(busyFinished(uint)),
350             this, SLOT(startUploadAfterAlbumOpened()));
351 
352     QString albumName = m_albumsCoB->currentText();
353     Album album;
354 
355     foreach(Album a, m_session->state().albums())
356     {
357         if (a.name == albumName)
358         {
359             album = a;
360             break;
361         }
362     }
363 
364     if (album.name == albumName)
365     {
366         m_session->openAlbum(album);
367     }
368 }
369 
startUploadAfterAlbumOpened()370 void RajceWidget::startUploadAfterAlbumOpened()
371 {
372     disconnect(m_session, SIGNAL(busyFinished(uint)),
373                this, SLOT(startUploadAfterAlbumOpened()));
374 
375     connect(m_session, SIGNAL(busyFinished(uint)),
376             this, SLOT(uploadNext()));
377 
378     m_uploadingPhotos    = true;
379     m_progressBar->setValue(0);
380     progressStarted(AddPhoto);
381     m_currentUploadImage = m_uploadQueue.begin();
382     uploadNext();
383 }
384 
closeAlbum()385 void RajceWidget::closeAlbum()
386 {
387     _setEnabled(true);
388 
389     disconnect(m_session, SIGNAL(busyFinished(uint)),
390                this, SLOT(closeAlbum()));
391 
392     m_uploadQueue.clear();
393     m_progressBar->setVisible(false);
394 
395     m_uploadingPhotos = false;
396 }
397 
uploadNext()398 void RajceWidget::uploadNext()
399 {
400     QList<QString>::Iterator tmp = m_currentUploadImage;
401 
402     if (m_currentUploadImage == m_uploadQueue.end())
403     {
404         m_imgList->processed(QUrl::fromLocalFile(*(--tmp)), (m_session->state().lastErrorCode() == 0));
405         cancelUpload();
406         return;
407     }
408 
409     if (m_currentUploadImage != m_uploadQueue.begin())
410     {
411         m_imgList->processed(QUrl::fromLocalFile(*(--tmp)), (m_session->state().lastErrorCode() == 0));
412     }
413 
414     m_imgList->processing(QUrl::fromLocalFile(*m_currentUploadImage));
415 
416     QString currentPhoto = *m_currentUploadImage;
417     ++m_currentUploadImage;
418 
419     unsigned dimension   = m_dimensionSpB->value();
420     int jpgQuality       = m_imageQualitySpB->value();
421 
422     m_session->uploadPhoto(currentPhoto, dimension, jpgQuality);
423 }
424 
cancelUpload()425 void RajceWidget::cancelUpload()
426 {
427     if (m_uploadingPhotos && m_currentUploadImage != m_uploadQueue.begin() &&
428         m_currentUploadImage != m_uploadQueue.end())
429     {
430         m_imgList->processed(QUrl::fromLocalFile(*m_currentUploadImage), false);
431     }
432 
433     disconnect(m_session, SIGNAL(busyFinished(uint)),
434                this, SLOT(uploadNext()));
435 
436     connect(m_session, SIGNAL(busyFinished(uint)),
437             this, SLOT(closeAlbum()));
438 
439     m_session->cancelCurrentCommand();
440     m_session->closeAlbum();
441     m_uploadQueue.clear();
442 }
443 
selectedAlbumChanged(const QString & newName)444 void RajceWidget::selectedAlbumChanged(const QString& newName)
445 {
446     m_currentAlbumName = newName;
447 }
448 
_setEnabled(bool enabled)449 void RajceWidget::_setEnabled(bool enabled)
450 {
451     m_changeUserBtn->setEnabled(enabled);
452     m_newAlbumBtn->setEnabled(enabled);
453     m_albumsCoB->setEnabled(enabled);
454     m_reloadAlbumsBtn->setEnabled(enabled);
455     m_dimensionSpB->setEnabled(enabled);
456     m_imageQualitySpB->setEnabled(enabled);
457     emit loginStatusChanged(enabled);
458 }
459 
readSettings()460 void RajceWidget::readSettings()
461 {
462     KConfig config(QString::fromLatin1("kipirc"));
463     KConfigGroup grp = config.group("RajceExport Settings");
464 
465     SessionState state;
466 
467     state.sessionToken() = grp.readEntry("token");
468     state.username()     = grp.readEntry("username");
469     state.nickname()     = grp.readEntry("nickname");
470     m_currentAlbumName   = grp.readEntry("album");
471     state.maxHeight()    = grp.readEntry("maxHeight",    1200);
472     state.maxWidth()     = grp.readEntry("maxWidth",     1200);
473     state.imageQuality() = grp.readEntry("imageQuality", 85);
474 
475     m_session->init(state);
476 
477     if (!m_session->state().sessionToken().isEmpty())
478     {
479         m_session->loadAlbums();
480     }
481 }
482 
writeSettings()483 void RajceWidget::writeSettings()
484 {
485     KConfig config(QString::fromLatin1("kipirc"));
486     KConfigGroup grp          = config.group("RajceExport Settings");
487     const SessionState& state = m_session->state();
488 
489     grp.writeEntry("token",        state.sessionToken());
490     grp.writeEntry("username",     state.username());
491     grp.writeEntry("nickname",     state.nickname());
492     grp.writeEntry("album",        m_currentAlbumName);
493     grp.writeEntry("maxWidth",     state.maxWidth());
494     grp.writeEntry("maxHeight",    state.maxHeight());
495     grp.writeEntry("imageQuality", state.imageQuality());
496 }
497 
498 } // namespace KIPIRajcePlugin
499