dswindow.cpp 9.85 KB
Newer Older
1
2
3
/* ============================================================
 *
 * This file is a part of kipi-plugins project
4
 * http://www.digikam.org
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 *
 * Date        : 2010-11-29
 * Description : a kipi plugin to export images to Debian Screenshots
 *
 * Copyright (C) 2010 by Pau Garcia i Quiles <pgquiles at elpauer dot org>
 *
 * This program is free software; you can redistribute it
 * and/or modify it under the terms of the GNU General
 * Public License as published by the Free Software Foundation;
 * either version 2, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * ============================================================ */

#include "dswindow.moc"

// Qt includes
Gilles Caulier's avatar
polish    
Gilles Caulier committed
26

27
28
29
30
31
#include <QFileInfo>
#include <QCloseEvent>
#include <QImageReader>

// KDE includes
Gilles Caulier's avatar
polish    
Gilles Caulier committed
32

33
34
35
36
37
#include <kmenu.h>
#include <klineedit.h>
#include <kcombobox.h>
#include <kpushbutton.h>
#include <kmessagebox.h>
38
39
40
#include <kdebug.h>

// LibKDcraw includes
Gilles Caulier's avatar
polish    
Gilles Caulier committed
41

42
43
44
#include <libkdcraw/kdcraw.h>

// LibKIPI includes
Gilles Caulier's avatar
polish    
Gilles Caulier committed
45

Gilles Caulier's avatar
Gilles Caulier committed
46
#include "kpimageslist.h"
47
#include "kpaboutdata.h"
Gilles Caulier's avatar
Gilles Caulier committed
48
#include "kpmetadata.h"
49
#include "kpprogresswidget.h"
50
51

// Local includes
Gilles Caulier's avatar
polish    
Gilles Caulier committed
52

53
54
55
56
57
58
#include "dstalker.h"
#include "dswidget.h"

namespace KIPIDebianScreenshotsPlugin
{

Gilles Caulier's avatar
polish    
Gilles Caulier committed
59
static int maxWidth  = 800;
60
61
static int maxHeight = 600;

Gilles Caulier's avatar
Gilles Caulier committed
62
63
DsWindow::DsWindow(Interface* const interface, const QString& tmpFolder, QWidget* const /*parent*/)
    : KPToolDialog(0),
Gilles Caulier's avatar
polish    
Gilles Caulier committed
64
      m_uploadEnabled(false),
65
66
67
      m_imagesCount(0),
      m_imagesTotal(0),
//      m_talker(new DsTalker(this)),
Gilles Caulier's avatar
polish    
Gilles Caulier committed
68
69
      m_tmpDir(tmpFolder),
      m_interface(interface)
70
71
72
73
74
75
76
{
    m_tmpPath.clear();
//    m_tmpDir      = tmpFolder;
//    m_interface   = interface;
//    m_imagesCount = 0;
//    m_imagesTotal = 0;
    m_talker = new DsTalker(this);
77
    m_widget = new DsWidget(this);
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

    setMainWidget(m_widget);
    setWindowIcon(KIcon("debianscreenshots"));
    setButtons(Help|User1|Close);
    setDefaultButton(Close);
    setModal(false);

    setWindowTitle(i18n("Export to Debian Screenshots"));
    setButtonGuiItem(User1,
                     KGuiItem(i18n("Start Upload"), "network-workgroup",
                              i18n("Start upload to Debian Screenshots")));
    enableButton(User1, false); // Disable until package and version data have been fulfilled
    m_widget->setMinimumSize(700, 500);

    // ------------------------------------------------------------------------

Laurent Montel's avatar
Laurent Montel committed
94
95
    connect(m_widget->m_imgList, SIGNAL(signalImageListChanged()),
            this, SLOT(slotMaybeEnableUser1()) );
96

Gilles Caulier's avatar
polish    
Gilles Caulier committed
97
98
    connect(m_widget, SIGNAL(requiredPackageInfoAvailable(bool)),
            this, SLOT(slotRequiredPackageInfoAvailableReceived(bool)));
99

Laurent Montel's avatar
Laurent Montel committed
100
101
    connect(this, SIGNAL(user1Clicked()),
            this, SLOT(slotStartTransfer()) );
102

103
104
105
    connect(m_widget->progressBar(), SIGNAL(signalProgressCanceled()),
            this, SLOT(slotStopAndCloseProgressBar()));

106
107
    // ------------------------------------------------------------------------

Gilles Caulier's avatar
Gilles Caulier committed
108
109
110
111
112
    KPAboutData* about = new KPAboutData(ki18n("Debian Screenshots Export"), 0,
                             KAboutData::License_GPL,
                             ki18n("A Kipi plugin to export an image collection "
                                   "to the Debian Screenshots web site."),
                              ki18n("(c) 2010, Pau Garcia i Quiles\n"));
113

Gilles Caulier's avatar
Gilles Caulier committed
114
    about->addAuthor(ki18n("Pau Garcia i Quiles"), ki18n("Author and maintainer"),
Gilles Caulier's avatar
Gilles Caulier committed
115
                     "pgquiles at elpauer dot org");
116

Gilles Caulier's avatar
Gilles Caulier committed
117
118
    about->handbookEntry = QString("debianscreenshots");
    setAboutData(about);
119

Gilles Caulier's avatar
Gilles Caulier committed
120
    // ------------------------------------------------------------------------
121
122
123
124
125
126
127
128
129

    connect(m_talker, SIGNAL(signalAddScreenshotDone(int,QString)),
            this, SLOT(slotAddScreenshotDone(int,QString)));
}

DsWindow::~DsWindow()
{
}

130
131
132
133
134
135
136
137
138
void DsWindow::slotStopAndCloseProgressBar()
{
    m_transferQueue.clear();
    m_widget->m_imgList->cancelProcess();
    m_widget->imagesList()->listView()->clear();
    m_widget->progressBar()->progressCompleted();
    done(Close);
}

139
140
141
142
143
void DsWindow::slotButtonClicked(int button)
{
    switch (button)
    {
        case Close:
Gilles Caulier's avatar
polish    
Gilles Caulier committed
144
        {
145
146
147
            if (m_widget->progressBar()->isHidden())
            {
                m_widget->imagesList()->listView()->clear();
148
                m_widget->progressBar()->progressCompleted();
149
150
151
152
153
                done(Close);
            }
            else // cancel login/transfer
            {
                m_transferQueue.clear();
Gilles Caulier's avatar
Gilles Caulier committed
154
                m_widget->m_imgList->cancelProcess();
155
                m_widget->progressBar()->hide();
156
                m_widget->progressBar()->progressCompleted();
157
158
            }
            break;
Gilles Caulier's avatar
polish    
Gilles Caulier committed
159
        }
160
        case User1:
Gilles Caulier's avatar
polish    
Gilles Caulier committed
161
        {
162
163
            slotStartTransfer();
            break;
Gilles Caulier's avatar
polish    
Gilles Caulier committed
164
        }
165
        default:
Gilles Caulier's avatar
polish    
Gilles Caulier committed
166
        {
167
             KDialog::slotButtonClicked(button);
Andi Clemens's avatar
Andi Clemens committed
168
             break;
Gilles Caulier's avatar
polish    
Gilles Caulier committed
169
        }
170
171
172
173
174
175
176
177
178
    }
}

void DsWindow::reactivate()
{
    m_widget->imagesList()->loadImagesFromCurrentSelection();
    show();
}

Gilles Caulier's avatar
polish    
Gilles Caulier committed
179
void DsWindow::closeEvent(QCloseEvent* e)
180
181
182
183
184
185
186
187
188
189
190
191
{
    if (!e) return;

    m_widget->imagesList()->listView()->clear();
    e->accept();
}

void DsWindow::slotStartTransfer()
{
    m_widget->m_imgList->clearProcessedStatus();
    m_transferQueue = m_widget->m_imgList->imageUrls();

Gilles Caulier's avatar
polish    
Gilles Caulier committed
192
193
    if (m_transferQueue.isEmpty())
    {
194
195
196
197
198
199
200
201
202
203
        return;
    }

    m_imagesTotal = m_transferQueue.count();
    m_imagesCount = 0;

    m_widget->progressBar()->setFormat(i18n("%v / %m"));
    m_widget->progressBar()->setMaximum(m_imagesTotal);
    m_widget->progressBar()->setValue(0);
    m_widget->progressBar()->show();
204
205
    m_widget->progressBar()->progressScheduled(i18n("Debian Screenshots export"), true, true);
    m_widget->progressBar()->progressThumbnailChanged(KIcon("kipi").pixmap(22, 22));
206
207
208
209
210
211
212

    uploadNextPhoto();
}

bool DsWindow::prepareImageForUpload(const QString& imgPath, MassageType massage)
{
    QImage image;
Gilles Caulier's avatar
polish    
Gilles Caulier committed
213
214
    if ( massage == DsWindow::ImageIsRaw )
    {
215
216
        kDebug() << "Get RAW preview " << imgPath;
        KDcrawIface::KDcraw::loadDcrawPreview(image, imgPath);
Gilles Caulier's avatar
polish    
Gilles Caulier committed
217
218
219
    }
    else
    {
220
221
222
223
        image.load(imgPath);
    }

    // rescale image if required
Gilles Caulier's avatar
polish    
Gilles Caulier committed
224
225
    if ( massage == DsWindow::ResizeRequired )
    {
226
227
228
229
        kDebug() << "Resizing image";
        image = image.scaled(maxWidth, maxHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation);
    }

Gilles Caulier's avatar
polish    
Gilles Caulier committed
230
231
    if ( image.isNull() )
    {
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
        return false;
    }

    // get temporary file name
    m_tmpPath = m_tmpDir + QFileInfo(imgPath).baseName().trimmed() + ".png";

    kDebug() << "Saving to temp file: " << m_tmpPath;
    image.save(m_tmpPath, "PNG");

    return true;
}

void DsWindow::uploadNextPhoto()
{
    if (m_transferQueue.isEmpty())
    {
        m_widget->progressBar()->hide();
        return;
    }

    m_widget->m_imgList->processing(m_transferQueue.first());
    QString imgPath = m_transferQueue.first().toLocalFile();

    m_widget->progressBar()->setMaximum(m_imagesTotal);
    m_widget->progressBar()->setValue(m_imagesCount);

    // screenshots.debian.net only accepts PNG images, 800x600 max
    MassageType massageRequired = DsWindow::None;

    // check if format is PNG
    QImageReader imgReader(imgPath);
    QByteArray imgFormat = imgReader.format();
Gilles Caulier's avatar
polish    
Gilles Caulier committed
264
265
    if( QString::compare(QString(imgFormat), QString("PNG"), Qt::CaseInsensitive) != 0 )
    {
266
267
268
269
270
        massageRequired = DsWindow::NotPNG;
    }

    // check if image > 800x600
    QImage img = imgReader.read();
Gilles Caulier's avatar
polish    
Gilles Caulier committed
271
272
    if( (img.width() > maxWidth) || (img.height() > maxHeight) )
    {
273
274
275
276
        massageRequired = DsWindow::ResizeRequired;
    }

    // check if we have to RAW file -> use preview image then
Gilles Caulier's avatar
Gilles Caulier committed
277
    if( KPMetadata::isRawFile(imgPath) )
Gilles Caulier's avatar
polish    
Gilles Caulier committed
278
    {
279
280
281
282
283
284
285
286
287
288
289
        massageRequired = DsWindow::ImageIsRaw;
    }

    bool res;
    if (massageRequired)
    {
        if (!prepareImageForUpload(imgPath, massageRequired))
        {
            slotAddScreenshotDone(666, i18n("Cannot open file"));
            return;
        }
Gilles Caulier's avatar
polish    
Gilles Caulier committed
290
291
292
        res = m_talker->addScreenshot(m_tmpPath, m_widget->m_pkgLineEdit->text(),
                                      m_widget->m_versionsComboBox->currentText(),
                                      m_widget->m_descriptionLineEdit->text());
293
294
295
296
    }
    else
    {
        m_tmpPath.clear();
Gilles Caulier's avatar
polish    
Gilles Caulier committed
297
298
299
        res = m_talker->addScreenshot(imgPath, m_widget->m_pkgLineEdit->text(), 
                                      m_widget->m_versionsComboBox->currentText(),
                                      m_widget->m_descriptionLineEdit->text());
300
301
    }

Gilles Caulier's avatar
polish    
Gilles Caulier committed
302
303
    if (!res)
    {
304
305
306
307
308
309
310
311
        slotAddScreenshotDone(666, i18n("Cannot open file"));
        return;
    }
}

void DsWindow::slotAddScreenshotDone(int errCode, const QString& errMsg)
{
    // Remove temporary file if it was used
Gilles Caulier's avatar
polish    
Gilles Caulier committed
312
313
    if (!m_tmpPath.isEmpty())
    {
314
315
316
317
        QFile::remove(m_tmpPath);
        m_tmpPath.clear();
    }

Gilles Caulier's avatar
Gilles Caulier committed
318
    m_widget->m_imgList->processed(m_transferQueue.first(), (errCode == 0));
319

Gilles Caulier's avatar
polish    
Gilles Caulier committed
320
321
    if (errCode == 0)
    {
322
323
        m_transferQueue.pop_front();
        m_imagesCount++;
Gilles Caulier's avatar
polish    
Gilles Caulier committed
324
325
326
    }
    else
    {
327
        if (KMessageBox::warningContinueCancel(this,
Gilles Caulier's avatar
Gilles Caulier committed
328
                         i18n("Failed to upload photo to Debian Screenshots: %1\n"
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
                              "Do you want to continue?", errMsg))
                         != KMessageBox::Continue)
        {
            m_widget->progressBar()->hide();
            m_transferQueue.clear();
            return;
        }
    }

    uploadNextPhoto();
}

void DsWindow::slotMaybeEnableUser1()
{
    enableButton(User1, !(m_widget->m_imgList->imageUrls().isEmpty()) && m_uploadEnabled );
}

Gilles Caulier's avatar
polish    
Gilles Caulier committed
346
347
void DsWindow::slotRequiredPackageInfoAvailableReceived(bool enabled)
{
348
349
350
351
352
353
354
    m_uploadEnabled = enabled; // Save the all-data-completed status to be able to enable the upload
                               // button later in case the image list is empty at the moment

    slotMaybeEnableUser1();
}

} // namespace KIPIDebianScreenshotsPlugin