source: extensions/digikam_export/piwigoexport/piwigowindow.cpp @ 7173

Last change on this file since 7173 was 4874, checked in by fcoiffie, 15 years ago

[digikam_export] Removal of all useless and commented code

  • Temporary files are removed
  • Warnings correction
  • Selected 'thumbnail size' is stored in the configuration file
File size: 19.4 KB
Line 
1/* ============================================================
2 *
3 * This file is a part of kipi-plugins project
4 * http://www.kipi-plugins.org
5 *
6 * Date        : 2010-01-07
7 * Description : a plugin to export to a remote Piwigo server.
8 *
9 * Copyright (C) 2003-2005 by Renchi Raju <renchi dot raju at gmail dot com>
10 * Copyright (C) 2006 by Colin Guthrie <kde@colin.guthr.ie>
11 * Copyright (C) 2006-2009 by Gilles Caulier <caulier dot gilles at gmail dot com>
12 * Copyright (C) 2008 by Andrea Diamantini <adjam7 at gmail dot com>
13 * Copyright (C) 2010 by Frederic Coiffier <frederic dot coiffier at free dot com>
14 *
15 * This program is free software; you can redistribute it
16 * and/or modify it under the terms of the GNU General
17 * Public License as published by the Free Software Foundation;
18 * either version 2, or (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23 * GNU General Public License for more details.
24 *
25 * ============================================================ */
26
27#include "piwigowindow.h"
28#include "piwigowindow.moc"
29
30// Qt includes
31
32#include <QCheckBox>
33#include <QDialog>
34#include <QFileInfo>
35#include <QGroupBox>
36#include <QPushButton>
37#include <QSpinBox>
38#include <Qt>
39#include <QTreeWidgetItem>
40#include <QPointer>
41#include <QHBoxLayout>
42#include <QVBoxLayout>
43
44// KDE includes
45
46#include <kaboutdata.h>
47#include <kapplication.h>
48#include <kconfig.h>
49#include <kdebug.h>
50#include <khelpmenu.h>
51#include <kicon.h>
52#include <klocale.h>
53#include <kmenu.h>
54#include <kmessagebox.h>
55#include <kpushbutton.h>
56#include <krun.h>
57#include <ktoolinvocation.h>
58#include <kurllabel.h>
59#include <kstandarddirs.h>
60
61// LibKIPI includes
62
63#include <libkipi/interface.h>
64
65// Local includes
66
67#include "piwigos.h"
68#include "piwigoconfig.h"
69#include "piwigoitem.h"
70#include "piwigotalker.h"
71#include "imagedialog.h"
72#include "kpaboutdata.h"
73
74namespace KIPIPiwigoExportPlugin
75{
76
77class PiwigoWindow::Private
78{
79public:
80
81    Private(PiwigoWindow* parent);
82
83    QWidget*               widget;
84
85    QTreeWidget*           albumView;
86
87    QPushButton*           addPhotoBtn;
88
89    QCheckBox*             captTitleCheckBox;
90    QCheckBox*             captDescrCheckBox;
91    QCheckBox*             resizeCheckBox;
92
93    QSpinBox*              dimensionSpinBox;
94    QSpinBox*              thumbDimensionSpinBox;
95
96    QHash<QString, GAlbum> albumDict;
97
98    KUrlLabel*             logo;
99};
100
101PiwigoWindow::Private::Private(PiwigoWindow* parent)
102{
103    widget = new QWidget(parent);
104    parent->setMainWidget(widget);
105    parent->setModal(false);
106
107    QHBoxLayout *hlay = new QHBoxLayout(widget);
108
109    // ---------------------------------------------------------------------------
110
111    logo = new KUrlLabel;
112    logo->setText(QString());
113    logo->setUrl("http://piwigo.org");
114    logo->setPixmap(QPixmap(KStandardDirs::locate("data", "kipiplugin_piwigoexport/pics/piwigo_logo.png")));
115    logo->setAlignment(Qt::AlignLeft);
116
117    // ---------------------------------------------------------------------------
118
119    albumView = new QTreeWidget;
120    QStringList labels;
121    labels << i18n("Albums");
122    albumView->setHeaderLabels(labels);
123
124    // ---------------------------------------------------------------------------
125
126    QFrame *optionFrame = new QFrame;
127    QVBoxLayout *vlay   = new QVBoxLayout();
128
129    addPhotoBtn = new QPushButton;
130    addPhotoBtn->setText(i18n("&Add Selected Photos"));
131    addPhotoBtn->setIcon(KIcon("list-add"));
132    addPhotoBtn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
133    addPhotoBtn->setEnabled(false);
134
135    QGroupBox *optionsBox = new QGroupBox(i18n("Override Default Options"));
136    QVBoxLayout *vlay2    = new QVBoxLayout();
137
138    captTitleCheckBox     = new QCheckBox(optionsBox);
139    captTitleCheckBox->setText(i18n("EXIF Comment (instead of file name) sets Title"));
140
141    captDescrCheckBox     = new QCheckBox(optionsBox);
142    captDescrCheckBox->setText(i18n("EXIF Comment (instead of file name) sets Comment"));
143
144    resizeCheckBox        = new QCheckBox(optionsBox);
145    resizeCheckBox->setText(i18n("Resize photos before uploading"));
146
147    QHBoxLayout *hlay2    = new QHBoxLayout;
148    QLabel *resizeLabel   = new QLabel(i18n("Maximum dimension:"));
149
150    dimensionSpinBox      = new QSpinBox;
151    dimensionSpinBox->setRange(1,1600);
152    dimensionSpinBox->setValue(600);
153
154    QHBoxLayout *hlay3    = new QHBoxLayout;
155    QLabel *resizeThumbLabel= new QLabel(i18n("Maximum thumbnail dimension:"));
156
157    thumbDimensionSpinBox = new QSpinBox;
158    thumbDimensionSpinBox->setRange(32,800);
159    thumbDimensionSpinBox->setValue(128);
160
161    captTitleCheckBox->setChecked(true);
162    captDescrCheckBox->setChecked(false);
163    resizeCheckBox->setChecked(false);
164    dimensionSpinBox->setEnabled(false);
165    thumbDimensionSpinBox->setEnabled(true);
166
167    // ---------------------------------------------------------------------------
168
169    hlay2->addWidget(resizeLabel);
170    hlay2->addWidget(dimensionSpinBox);
171    hlay2->setSpacing(KDialog::spacingHint());
172    hlay2->setMargin(KDialog::spacingHint());
173
174    // ---------------------------------------------------------------------------
175
176    hlay3->addWidget(resizeThumbLabel);
177    hlay3->addWidget(thumbDimensionSpinBox);
178    hlay3->setSpacing(KDialog::spacingHint());
179    hlay3->setMargin(KDialog::spacingHint());
180
181    // ---------------------------------------------------------------------------
182
183    vlay2->addWidget(captTitleCheckBox);
184    vlay2->addWidget(captDescrCheckBox);
185    vlay2->addWidget(resizeCheckBox);
186    vlay2->addLayout(hlay2);
187    vlay2->addLayout(hlay3);
188    vlay2->setSpacing(KDialog::spacingHint());
189    vlay2->setMargin(KDialog::spacingHint());
190
191    optionsBox->setLayout(vlay2);
192
193    // ---------------------------------------------------------------------------
194
195    vlay->addWidget(addPhotoBtn);
196    vlay->addWidget(optionsBox);
197    vlay->setSpacing(KDialog::spacingHint());
198    vlay->setMargin(KDialog::spacingHint());
199
200    optionFrame->setLayout(vlay);
201
202    // ---------------------------------------------------------------------------
203
204    hlay->addWidget(logo);
205    hlay->addWidget(albumView);
206    hlay->addWidget(optionFrame);
207    hlay->setSpacing(KDialog::spacingHint());
208    hlay->setMargin(KDialog::spacingHint());
209
210    widget->setLayout(hlay);
211}
212
213// --------------------------------------------------------------------------------------------------------------
214
215PiwigoWindow::PiwigoWindow(KIPI::Interface* interface, QWidget *parent, Piwigo* pPiwigo)
216        : KDialog(parent),
217        m_interface(interface),
218        mpPiwigo(pPiwigo),
219        d(new Private(this))
220{
221    setWindowTitle( i18n("Piwigo Export") );
222    setButtons( KDialog::Close | KDialog::User1 | KDialog::Help);
223    setModal(false);
224
225    // About data.
226    m_about = new KIPIPlugins::KPAboutData(ki18n("Piwigo Export"),
227                                           0,
228                                           KAboutData::License_GPL,
229                                           ki18n("A Kipi plugin to export image collections to a remote Piwigo server."),
230                                           ki18n("(c) 2003-2005, Renchi Raju\n"
231                                                 "(c) 2006-2007, Colin Guthrie\n"
232                                                 "(c) 2006-2009, Gilles Caulier\n"
233                                                 "(c) 2008, Andrea Diamantini\n"
234                                                 "(c) 2010, Frédéric Coiffier\n"));
235
236    m_about->addAuthor(ki18n("Renchi Raju"), ki18n("Author"),
237                       "renchi dot raju at gmail dot com");
238
239    m_about->addAuthor(ki18n("Colin Guthrie"), ki18n("Maintainer"),
240                       "kde at colin dot guthr dot ie");
241
242    m_about->addAuthor(ki18n("Andrea Diamantini"), ki18n("Developer"),
243                       "adjam7 at gmail dot com");
244
245    m_about->addAuthor(ki18n("Gilles Caulier"), ki18n("Developer"),
246                       "caulier dot gilles at gmail dot com");
247
248    m_about->addAuthor(ki18n("Frédéric Coiffier"), ki18n("Developer"),
249                       "fcoiffie at gmail dot com");
250
251    // help button
252
253    disconnect(this, SIGNAL(helpClicked()),
254               this, SLOT(slotHelp()));
255
256    KHelpMenu *helpMenu = new KHelpMenu(this, m_about, false);
257    helpMenu->menu()->removeAction(helpMenu->menu()->actions().first());
258    QAction *handbook   = new QAction(i18n("Handbook"), this);
259    connect(handbook, SIGNAL(triggered(bool)),
260            this, SLOT(slotHelp()));
261    helpMenu->menu()->insertAction(helpMenu->menu()->actions().first(), handbook);
262    button(Help)->setMenu(helpMenu->menu());
263
264    // User1 Button : to conf piwigo settings
265    KPushButton *confButton = button( User1 );
266    confButton->setText( i18n("Settings") );
267    confButton->setIcon( KIcon("configure") );
268    connect(confButton, SIGNAL(clicked()),
269            this, SLOT(slotSettings() ) );
270
271    // we need to let m_talker work..
272    m_talker = new PiwigoTalker(d->widget);
273
274    // setting progressDlg and its numeric hints
275    m_progressDlg = new QProgressDialog(this);
276    m_progressDlg->setModal(true);
277    m_progressDlg->setAutoReset(true);
278    m_progressDlg->setAutoClose(true);
279    m_uploadCount = 0;
280    m_uploadTotal = 0;
281    mpUploadList  = new QStringList;
282
283    // connect functions
284    connectSignals();
285
286    // read Settings
287    readSettings();
288
289    slotDoLogin();
290}
291
292PiwigoWindow::~PiwigoWindow()
293{
294    // write config
295    KConfig config("kipirc");
296    KConfigGroup group = config.group("PiwigoSync Galleries");
297
298    group.writeEntry("Resize",          d->resizeCheckBox->isChecked());
299    group.writeEntry("Set title",       d->captTitleCheckBox->isChecked());
300    group.writeEntry("Set description", d->captDescrCheckBox->isChecked());
301    group.writeEntry("Maximum Width",   d->dimensionSpinBox->value());
302    group.writeEntry("Thumbnail Width", d->thumbDimensionSpinBox->value());
303
304    delete m_talker;
305
306    delete mpUploadList;
307    delete m_about;
308
309    delete d;
310}
311
312void PiwigoWindow::connectSignals()
313{
314    connect(d->albumView, SIGNAL(itemSelectionChanged()),
315            this , SLOT( slotAlbumSelected() ) );
316
317    connect(d->addPhotoBtn, SIGNAL(clicked()),
318            this, SLOT(slotAddPhoto()));
319
320    connect(d->resizeCheckBox, SIGNAL(stateChanged(int)),
321            this, SLOT(slotEnableSpinBox(int)));
322
323    connect(d->logo, SIGNAL(leftClickedUrl(const QString&)),
324            this, SLOT(slotProcessUrl(const QString&)));
325
326    connect(m_progressDlg, SIGNAL( canceled() ),
327            this, SLOT( slotAddPhotoCancel() ));
328
329    connect(m_talker, SIGNAL(signalError(const QString&)),
330            this, SLOT(slotError(const QString&)));
331
332    connect(m_talker, SIGNAL(signalBusy(bool)),
333            this, SLOT(slotBusy(bool)));
334
335    connect(m_talker, SIGNAL(signalLoginFailed(const QString&)),
336            this, SLOT(slotLoginFailed(const QString&)));
337
338    connect(m_talker, SIGNAL(signalAlbums(const QList<GAlbum>&)),
339            this, SLOT(slotAlbums(const QList<GAlbum>&)));
340
341    connect(m_talker, SIGNAL(signalAddPhotoSucceeded()),
342            this, SLOT(slotAddPhotoSucceeded()));
343
344    connect(m_talker, SIGNAL(signalAddPhotoFailed(const QString&)),
345            this, SLOT(slotAddPhotoFailed(const QString&)));
346}
347
348void PiwigoWindow::slotProcessUrl(const QString& url)
349{
350    KToolInvocation::self()->invokeBrowser(url);
351}
352
353void PiwigoWindow::readSettings()
354{
355    // read Config
356    KConfig config("kipirc");
357    KConfigGroup group = config.group("PiwigoSync Galleries");
358
359    if (group.readEntry("Resize", false)) {
360        d->resizeCheckBox->setChecked(true);
361        d->dimensionSpinBox->setEnabled(true);
362        d->dimensionSpinBox->setValue(group.readEntry("Maximum Width", 600));
363    } else {
364        d->resizeCheckBox->setChecked(false);
365        d->dimensionSpinBox->setEnabled(false);
366    }
367
368    if (group.readEntry("Set title", true))
369        d->captTitleCheckBox->setChecked(true);
370    else
371        d->captTitleCheckBox->setChecked(false);
372
373    if (group.readEntry("Set description", false))
374        d->captDescrCheckBox->setChecked(true);
375    else
376        d->captDescrCheckBox->setChecked(false);
377
378
379    d->thumbDimensionSpinBox->setValue(group.readEntry("Thumbnail Width", 128));
380}
381
382void PiwigoWindow::slotHelp()
383{
384    KToolInvocation::invokeHelp("piwigoexport", "kipi-plugins");
385}
386
387void PiwigoWindow::slotDoLogin()
388{
389    KUrl url(mpPiwigo->url());
390    if (url.protocol().isEmpty()) {
391        url.setProtocol("http");
392        url.setHost(mpPiwigo->url());
393    }
394
395    if (!url.url().endsWith(QLatin1String(".php"))) {
396        url.addPath("ws.php");
397    }
398
399    // If we've done something clever, save it back to the piwigo.
400    if (mpPiwigo->url() != url.url()) {
401        mpPiwigo->setUrl(url.url());
402        mpPiwigo->save();
403    }
404
405    m_talker->login(url.url(), mpPiwigo->username(), mpPiwigo->password());
406}
407
408void PiwigoWindow::slotLoginFailed(const QString& msg)
409{
410    if (KMessageBox::warningYesNo(this,
411                                  i18n("Failed to login into remote piwigo. ")
412                                  + msg
413                                  + i18n("\nDo you want to check your settings and try again?"))
414            != KMessageBox::Yes) {
415        close();
416        return;
417    }
418
419    QPointer<PiwigoEdit> configDlg = new PiwigoEdit(kapp->activeWindow(), mpPiwigo, i18n("Edit Piwigo Data") );
420    if ( configDlg->exec() != QDialog::Accepted ) {
421        delete configDlg;
422        return;
423    }
424    slotDoLogin();
425    delete configDlg;
426}
427
428void PiwigoWindow::slotBusy(bool val)
429{
430    if (val) {
431        setCursor(Qt::WaitCursor);
432        d->addPhotoBtn->setEnabled(false);
433    } else {
434        setCursor(Qt::ArrowCursor);
435        bool loggedIn = m_talker->loggedIn();
436        d->addPhotoBtn->setEnabled(loggedIn && d->albumView->currentItem());
437    }
438}
439
440void PiwigoWindow::slotError(const QString& msg)
441{
442    m_progressDlg->hide();
443    KMessageBox::error(this, msg);
444}
445
446void PiwigoWindow::slotAlbums(const QList<GAlbum>& albumList)
447{
448    d->albumDict.clear();
449    d->albumView->clear();
450
451    // album work list
452    QList<GAlbum> workList(albumList);
453    QList<QTreeWidgetItem *> parentItemList;
454
455    // fill QTreeWidget
456    while ( !workList.isEmpty() ) {
457        // the album to work on
458        GAlbum album = workList.takeFirst();
459
460        int parentRefNum = album.parent_ref_num;
461        if ( parentRefNum == -1 ) {
462            QTreeWidgetItem *item = new QTreeWidgetItem();
463            item->setText(0, cleanName(album.name) );
464            item->setIcon(0, KIcon("inode-directory") );
465            item->setData(1, Qt::UserRole, QVariant(album.ref_num) );
466            item->setText(2, i18n("Album") );
467
468            kDebug() << "Top : " << album.name << " " << album.ref_num << "\n";
469
470            d->albumView->addTopLevelItem(item);
471            d->albumDict.insert(album.name, album);
472            parentItemList << item;
473        } else {
474            QTreeWidgetItem *parentItem = 0;
475            bool found                  = false;
476            int i                       = 0;
477
478            while ( !found && i < parentItemList.size() ) {
479                parentItem = parentItemList.at(i);
480
481                if (parentItem && (parentItem->data(1, Qt::UserRole).toInt() == parentRefNum)) {
482                    QTreeWidgetItem *item = new QTreeWidgetItem(parentItem);
483                    item->setText(0, cleanName(album.name) );
484                    item->setIcon(0, KIcon("inode-directory") );
485                    item->setData(1, Qt::UserRole, album.ref_num );
486                    item->setText(2, i18n("Album") );
487
488                    parentItem->addChild(item);
489                    d->albumDict.insert(album.name, album);
490                    parentItemList << item;
491                    found = true;
492                }
493                i++;
494            }
495        }
496    }
497}
498
499void PiwigoWindow::slotAlbumSelected()
500{
501    QTreeWidgetItem* item = d->albumView->currentItem();
502
503    // stop loading if user clicked an image
504    if ( item->text(2) == i18n("Image") )
505        return;
506
507    if (!item) {
508        d->addPhotoBtn->setEnabled(false);
509    } else {
510        kDebug() << "Album selected\n";
511
512        int albumId = item->data(1, Qt::UserRole).toInt();
513        kDebug() << albumId << "\n";
514        if (m_talker->loggedIn() && albumId ) {
515            d->addPhotoBtn->setEnabled(true);
516        } else {
517            d->addPhotoBtn->setEnabled(false);
518        }
519    }
520}
521
522void PiwigoWindow::slotAddPhoto()
523{
524    KUrl::List *urls = new KUrl::List(m_interface->currentSelection().images());
525
526    if (urls == NULL || urls->isEmpty()) {
527        KMessageBox::error(this, i18n("Nothing to upload - please select photos to upload."));
528        return;
529    }
530
531    for (KUrl::List::iterator it = urls->begin(); it != urls->end(); ++it) {
532        mpUploadList->append( (*it).path() );
533    }
534
535    m_uploadTotal = mpUploadList->count();
536    m_progressDlg->reset();
537    m_progressDlg->setMaximum(m_uploadTotal);
538    m_uploadCount = 0;
539    slotAddPhotoNext();
540}
541
542void PiwigoWindow::slotAddPhotoNext()
543{
544    if ( mpUploadList->isEmpty() ) {
545        m_progressDlg->reset();
546        m_progressDlg->hide();
547        return;
548    }
549
550    QTreeWidgetItem* item = d->albumView->currentItem();
551    int column            = d->albumView->currentColumn();
552    QString albumTitle    = item->text(column);
553    const GAlbum& album   = d->albumDict.value(albumTitle);
554    QString photoPath     = mpUploadList->takeFirst();
555    QString photoName     = QFileInfo(photoPath).baseName();
556    bool res              = m_talker->addPhoto(album.ref_num, photoPath, photoName,
557                            d->captTitleCheckBox->isChecked(),
558                            d->captDescrCheckBox->isChecked(),
559                            d->resizeCheckBox->isChecked(),
560                            d->dimensionSpinBox->value(),
561                            d->thumbDimensionSpinBox->value() );
562
563    if (!res) {
564        slotAddPhotoFailed( "" );
565        return;
566    }
567
568    m_progressDlg->setLabelText( i18n("Uploading file ") +  KUrl(photoPath).fileName() );
569
570    if (m_progressDlg->isHidden())
571        m_progressDlg->show();
572}
573
574void PiwigoWindow::slotAddPhotoSucceeded()
575{
576    m_uploadCount++;
577    m_progressDlg->setValue(m_uploadCount);
578    slotAddPhotoNext();
579}
580
581void PiwigoWindow::slotAddPhotoFailed(const QString& msg)
582{
583    m_progressDlg->reset();
584    m_progressDlg->hide();
585
586    if (KMessageBox::warningContinueCancel(this,
587                                           i18n("Failed to upload photo into "
588                                                "remote piwigo. ")
589                                           + msg
590                                           + i18n("\nDo you want to continue?"))
591            != KMessageBox::Continue) {
592    } else {
593        slotAddPhotoNext();
594    }
595}
596
597void PiwigoWindow::slotAddPhotoCancel()
598{
599    m_progressDlg->reset();
600    m_progressDlg->hide();
601    m_talker->cancel();
602}
603
604void PiwigoWindow::slotEnableSpinBox(int n)
605{
606    bool b;
607    switch (n) {
608    case 0:
609        b = false;
610        break;
611    case 1:
612    case 2:
613        b = true;
614        break;
615    default:
616        b = false;
617    }
618    d->dimensionSpinBox->setEnabled(b);
619}
620
621void PiwigoWindow::slotSettings()
622{
623    // TODO: reload albumlist if OK slot used.
624    QPointer<PiwigoEdit> dlg = new PiwigoEdit(kapp->activeWindow(), mpPiwigo, i18n("Edit Piwigo Data") );
625    if ( dlg->exec() == QDialog::Accepted ) {
626        slotDoLogin();
627    }
628    delete dlg;
629}
630
631
632QString PiwigoWindow::cleanName(const QString& str)
633{
634    QString plain = str;
635    plain.replace("&lt;", "<");
636    plain.replace("&gt;", ">");
637    plain.replace("&quot;", "\"");
638    plain.replace("&amp;", "&");
639
640    return plain;
641}
642
643} // namespace KIPIPiwigoExportPlugin
Note: See TracBrowser for help on using the repository browser.