~elopio/gallery-app/revert_workaround-1302706-click_toolbar_button_failure

« back to all changes in this revision

Viewing changes to src/photoeditor/photo-data.cpp

  • Committer: Leo Arias
  • Date: 2015-05-15 08:05:23 UTC
  • mfrom: (954.1.241 gallery-app)
  • Revision ID: leo.arias@canonical.com-20150515080523-i2of3vr8h7dioj59
Now the toolbar object is not needed at all.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2011-2014 Canonical Ltd
 
3
 *
 
4
 * This program is free software: you can redistribute it and/or modify
 
5
 * it under the terms of the GNU General Public License version 3 as
 
6
 * published by the Free Software Foundation.
 
7
 *
 
8
 * This program is distributed in the hope that it will be useful,
 
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
 * GNU General Public License for more details.
 
12
 *
 
13
 * You should have received a copy of the GNU General Public License
 
14
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
15
 *
 
16
 * Authors:
 
17
 * Jim Nelson <jim@yorba.org>
 
18
 * Lucas Beeler <lucas@yorba.org>
 
19
 * Charles Lindsay <chaz@yorba.org>
 
20
 * Eric Gregory <eric@yorba.org>
 
21
 * Clint Rogers <clinton@yorba.org>
 
22
 * Ugo Riboni <ugo.riboni@canonical.com>
 
23
 */
 
24
 
 
25
#include "photo-data.h"
 
26
#include "photo-edit-command.h"
 
27
#include "photo-edit-thread.h"
 
28
 
 
29
// medialoader
 
30
#include "photo-metadata.h"
 
31
 
 
32
// util
 
33
#include "imaging.h"
 
34
 
 
35
#include <QApplication>
 
36
#include <QDebug>
 
37
#include <QDir>
 
38
#include <QFileInfo>
 
39
#include <QImage>
 
40
#include <QImageReader>
 
41
#include <QImageWriter>
 
42
#include <QStack>
 
43
#include <QStandardPaths>
 
44
 
 
45
/*!
 
46
 * \brief Photo::isValid
 
47
 * \param file
 
48
 * \return
 
49
 */
 
50
bool PhotoData::isValid(const QFileInfo& file)
 
51
{
 
52
    QImageReader reader(file.filePath());
 
53
    QByteArray format = reader.format();
 
54
 
 
55
    if (QString(format).toLower() == "tiff") {
 
56
        // QImageReader.canRead() will detect some raw files as readable TIFFs,
 
57
        // though QImage will fail to load them.
 
58
        QString extension = file.suffix().toLower();
 
59
        if (extension != "tiff" && extension != "tif")
 
60
            return false;
 
61
    }
 
62
 
 
63
    PhotoMetadata* tmp = PhotoMetadata::fromFile(file);
 
64
    if (tmp == NULL)
 
65
        return false;
 
66
 
 
67
    delete tmp;
 
68
    return reader.canRead() &&
 
69
            QImageWriter::supportedImageFormats().contains(reader.format());
 
70
}
 
71
 
 
72
/*!
 
73
 * \brief Photo::Photo
 
74
 * \param file
 
75
 */
 
76
PhotoData::PhotoData()
 
77
    : QObject(),
 
78
    m_editThread(0),
 
79
    m_busy(false),
 
80
    m_orientation(TOP_LEFT_ORIGIN)
 
81
{
 
82
}
 
83
 
 
84
void PhotoData::setPath(QString path)
 
85
{
 
86
    if (QFileInfo(path).absoluteFilePath() != m_file.absoluteFilePath()) {
 
87
        QFileInfo newFile(path);
 
88
        if (newFile.exists() && newFile.isFile()) {
 
89
            QByteArray format = QImageReader(newFile.absoluteFilePath()).format();
 
90
            m_fileFormat = QString(format).toLower();
 
91
            if (m_fileFormat == "jpg") // Why does Qt expose two different names here?
 
92
                m_fileFormat = "jpeg";
 
93
 
 
94
            m_file = newFile;
 
95
            Q_EMIT pathChanged();
 
96
 
 
97
            if (fileFormatHasMetadata()) {
 
98
                PhotoMetadata* metadata = PhotoMetadata::fromFile(newFile.absoluteFilePath());
 
99
                m_orientation = metadata->orientation();
 
100
                delete metadata;
 
101
                Q_EMIT orientationChanged();
 
102
            }
 
103
        }
 
104
    }
 
105
}
 
106
 
 
107
QString PhotoData::path() const
 
108
{
 
109
    return m_file.absoluteFilePath();
 
110
}
 
111
 
 
112
QFileInfo PhotoData::file() const
 
113
{
 
114
    return m_file;
 
115
}
 
116
 
 
117
/*!
 
118
 * \brief Photo::~Photo
 
119
 */
 
120
PhotoData::~PhotoData()
 
121
{
 
122
    if (m_editThread) {
 
123
        m_editThread->wait();
 
124
        finishEditing();
 
125
    }
 
126
}
 
127
 
 
128
/*!
 
129
 * \brief Photo::orientation
 
130
 * \return
 
131
 */
 
132
Orientation PhotoData::orientation() const
 
133
{  
 
134
    return m_orientation;
 
135
}
 
136
 
 
137
void PhotoData::refreshFromDisk()
 
138
{
 
139
    if (fileFormatHasMetadata()) {
 
140
        PhotoMetadata* metadata = PhotoMetadata::fromFile(m_file.absoluteFilePath());
 
141
        qDebug() << "Refreshing orient." << m_orientation << "to" << metadata->orientation();
 
142
        m_orientation = metadata->orientation();
 
143
        delete metadata;
 
144
        Q_EMIT orientationChanged();
 
145
    }
 
146
 
 
147
    Q_EMIT dataChanged();
 
148
}
 
149
 
 
150
/*!
 
151
 * \brief Photo::rotateRight
 
152
 */
 
153
void PhotoData::rotateRight()
 
154
{
 
155
    Orientation current = fileFormatHasOrientation() ? orientation() :
 
156
                                                       TOP_LEFT_ORIGIN;
 
157
    Orientation rotated = OrientationCorrection::rotateOrientation(current,
 
158
                                                                   false);
 
159
    qDebug() << " Rotate from orientation " << current << "to" << rotated;
 
160
 
 
161
    PhotoEditCommand command;
 
162
    command.type = EDIT_ROTATE;
 
163
    command.orientation = rotated;
 
164
    asyncEdit(command);
 
165
}
 
166
 
 
167
/*!
 
168
 * \brief Photo::autoEnhance
 
169
 */
 
170
void PhotoData::autoEnhance()
 
171
{
 
172
    PhotoEditCommand command;
 
173
    command.type = EDIT_ENHANCE;
 
174
    asyncEdit(command);
 
175
}
 
176
 
 
177
/*!
 
178
 * \brief Photo::exposureCompensation Changes the brightnes of the image
 
179
 * \param value Value for the compensation. -1.0 moves the image into total black.
 
180
 * +1.0 to total white. 0.0 leaves it as it is.
 
181
 */
 
182
void PhotoData::exposureCompensation(qreal value)
 
183
{
 
184
    PhotoEditCommand command;
 
185
    command.type = EDIT_COMPENSATE_EXPOSURE;
 
186
    command.exposureCompensation = value;
 
187
    asyncEdit(command);
 
188
}
 
189
 
 
190
/*!
 
191
 * \brief Photo::crop
 
192
 * Specify all coords in [0.0, 1.0], where 1.0 is the full size of the image.
 
193
 * They will be clamped to this range if you don't.
 
194
 * \param vrect the rectangle specifying the region to be cropped
 
195
 */
 
196
void PhotoData::crop(QVariant vrect)
 
197
{
 
198
    PhotoEditCommand command;
 
199
    command.type = EDIT_CROP;
 
200
    command.crop_rectangle = vrect.toRectF();
 
201
    asyncEdit(command);
 
202
}
 
203
 
 
204
/*!
 
205
 * \brief Photo::asyncEdit does edit the photo according to the given command
 
206
 * in a background thread.
 
207
 * \param The command defining the edit operation to perform.
 
208
 */
 
209
void PhotoData::asyncEdit(const PhotoEditCommand& command)
 
210
{
 
211
    if (m_busy) {
 
212
        qWarning() << "Can't start edit operation while another one is running.";
 
213
        return;
 
214
    }
 
215
    m_busy = true;
 
216
    Q_EMIT busyChanged();
 
217
    m_editThread = new PhotoEditThread(this, command);
 
218
    connect(m_editThread, SIGNAL(finished()), this, SLOT(finishEditing()));
 
219
    m_editThread->start();
 
220
}
 
221
 
 
222
/*!
 
223
 * \brief Photo::finishEditing do all the updates once the editing is done
 
224
 */
 
225
void PhotoData::finishEditing()
 
226
{
 
227
    if (!m_editThread || m_editThread->isRunning())
 
228
        return;
 
229
 
 
230
    m_editThread->deleteLater();
 
231
    m_editThread = 0;
 
232
    m_busy = false;
 
233
 
 
234
    refreshFromDisk();
 
235
 
 
236
    Q_EMIT busyChanged();
 
237
    Q_EMIT editFinished();
 
238
}
 
239
 
 
240
/*!
 
241
 * \brief Photo::fileFormat returns the file format as QString
 
242
 * \return
 
243
 */
 
244
const QString &PhotoData::fileFormat() const
 
245
{
 
246
    return m_fileFormat;
 
247
}
 
248
 
 
249
/*!
 
250
 * \brief Photo::fileFormatHasMetadata
 
251
 * \return
 
252
 */
 
253
bool PhotoData::fileFormatHasMetadata() const
 
254
{
 
255
    return (m_fileFormat == "jpeg" || m_fileFormat == "tiff" ||
 
256
            m_fileFormat == "png");
 
257
}
 
258
 
 
259
/*!
 
260
 * \brief Photo::fileFormatHasOrientation
 
261
 * \return
 
262
 */
 
263
bool PhotoData::fileFormatHasOrientation() const
 
264
{
 
265
    return (m_fileFormat == "jpeg");
 
266
}
 
267
 
 
268
/*!
 
269
 * \brief Photo::busy return true if there is an editing operation in progress
 
270
 * \return
 
271
 */
 
272
bool PhotoData::busy() const
 
273
{
 
274
    return m_busy;
 
275
}