File indexing completed on 2024-05-12 16:46:09
0001 /*************************************************************************** 0002 Copyright (C) 2017 Robby Stephenson <robby@periapsis.org> 0003 ***************************************************************************/ 0004 0005 /*************************************************************************** 0006 * * 0007 * This program is free software; you can redistribute it and/or * 0008 * modify it under the terms of the GNU General Public License as * 0009 * published by the Free Software Foundation; either version 2 of * 0010 * the License or (at your option) version 3 or any later version * 0011 * accepted by the membership of KDE e.V. (or its successor approved * 0012 * by the membership of KDE e.V.), which shall act as a proxy * 0013 * defined in Section 14 of version 3 of the license. * 0014 * * 0015 * This program is distributed in the hope that it will be useful, * 0016 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0018 * GNU General Public License for more details. * 0019 * * 0020 * You should have received a copy of the GNU General Public License * 0021 * along with this program. If not, see <http://www.gnu.org/licenses/>. * 0022 * * 0023 ***************************************************************************/ 0024 0025 #include "imagejob.h" 0026 #include "../tellico_debug.h" 0027 0028 #include <KLocalizedString> 0029 0030 #include <QTimer> 0031 #include <QFileInfo> 0032 #include <QBuffer> 0033 #include <QImageReader> 0034 0035 using Tellico::ImageJob; 0036 0037 ImageJob::ImageJob(const QUrl& url_, const QString& id_, bool quiet_) : KIO::Job() 0038 , m_url(url_), m_id(id_), m_linkOnly(false), m_quiet(quiet_) { 0039 QTimer::singleShot(0, this, &ImageJob::slotStart); 0040 } 0041 0042 ImageJob::~ImageJob() { 0043 } 0044 0045 QString ImageJob::errorString() const { 0046 // by default, KIO::Job returns an error string depending on the error code and 0047 // using errorText() as a url or file name. Instead, just set a full error text and use it 0048 return errorText(); 0049 } 0050 0051 const Tellico::Data::Image& ImageJob::image() const { 0052 return m_image; 0053 } 0054 0055 void ImageJob::setLinkOnly(bool linkOnly_) { 0056 m_linkOnly = linkOnly_; 0057 } 0058 0059 void ImageJob::setReferrer(const QUrl& referrer_) { 0060 m_referrer = referrer_; 0061 } 0062 0063 void ImageJob::slotStart() { 0064 if(!m_url.isValid()) { 0065 setError(KIO::ERR_MALFORMED_URL); 0066 emitResult(); 0067 } else if(m_url.isLocalFile()) { 0068 const QString fileName = m_url.toLocalFile(); 0069 if(!QFileInfo(fileName).isReadable()) { 0070 setError(KIO::ERR_CANNOT_OPEN_FOR_READING); 0071 setErrorText(i18n("Tellico is unable to load the image - %1.", fileName)); 0072 } else { 0073 m_image = Data::Image(fileName, m_id); 0074 if(m_image.isNull()) { 0075 setError(KIO::ERR_UNKNOWN); 0076 m_image = Data::Image::null; 0077 } 0078 if(m_linkOnly) { 0079 m_image.setLinkOnly(true); 0080 m_image.setID(m_url.url()); 0081 } 0082 } 0083 emitResult(); 0084 } else { 0085 KIO::JobFlags flags = KIO::DefaultFlags; 0086 if(m_quiet) { 0087 flags |= KIO::HideProgressInfo; 0088 } 0089 // non-local valid url 0090 // KIO::storedGet seems to handle Content-Encoding: gzip ok 0091 KIO::StoredTransferJob* getJob = KIO::storedGet(m_url, KIO::NoReload, flags); 0092 QObject::connect(getJob, &KJob::result, this, &ImageJob::getJobResult); 0093 if(!m_referrer.isEmpty()) { 0094 getJob->addMetaData(QStringLiteral("referrer"), m_referrer.url()); 0095 } 0096 addSubjob(getJob); 0097 // don't emit result, it will be taken care of by the subjob handling 0098 } 0099 } 0100 0101 void ImageJob::getJobResult(KJob* job_) { 0102 KIO::StoredTransferJob* getJob = qobject_cast<KIO::StoredTransferJob*>(job_); 0103 if(!getJob || getJob->error()) { 0104 // error handling for subjob is handled by KCompositeJob 0105 setErrorText(i18n("Tellico is unable to load the image - %1.", m_url.toDisplayString())); 0106 return; 0107 } 0108 0109 // If we used the Image() c'tor that take a bytearray of data, I'm not sure how to 0110 // figure out the image format directly. Instead, write into a buffer and use QImageReader 0111 QByteArray data = getJob->data(); 0112 QBuffer buffer(&data); 0113 buffer.open(QIODevice::ReadOnly); 0114 m_image = Data::Image(data, QString::fromLatin1(QImageReader::imageFormat(&buffer)), m_id); 0115 if(m_image.isNull()) { 0116 setError(KIO::ERR_UNKNOWN); 0117 m_image = Data::Image::null; 0118 } else { 0119 // if we can't write the input format, then change to one we can 0120 m_image.setFormat(Data::Image::outputFormat(m_image.format())); 0121 if(m_id.isEmpty()) { 0122 m_image.calculateID(); 0123 } 0124 if(m_linkOnly) { 0125 m_image.setLinkOnly(true); 0126 m_image.setID(m_url.url()); 0127 } 0128 } 0129 emitResult(); 0130 }