1 /* This file is part of the KDE project
2 * Copyright (C) 2012 Boudewijn Rempt <boud@valdyas.org>
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 as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19 #include "RecentImageImageProvider.h"
20 #include <QFile>
21 #include <QDir>
22 #include <QProcess>
23 #include <QApplication>
24 #include <QImage>
25 #include <QImageReader>
26 #include <QPainter>
27
28 #include <KoStore.h>
29 #include <KoDocument.h>
30 #include <KoPart.h>
31
RecentImageImageProvider()32 RecentImageImageProvider::RecentImageImageProvider()
33 : QQuickImageProvider(QQuickImageProvider::Image)
34 {
35 }
36
requestImage(const QString & id,QSize * size,const QSize & requestedSize)37 QImage RecentImageImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
38 {
39 int width = 512;
40 int height = 512;
41 if(id.endsWith(QLatin1String("odt"), Qt::CaseInsensitive) ||
42 id.endsWith(QLatin1String("doc"), Qt::CaseInsensitive) ||
43 id.endsWith(QLatin1String("docx"), Qt::CaseInsensitive)) {
44 width *= 0.72413793;
45 } else {
46 height *= 0.72413793;
47 }
48
49 if (size) {
50 *size = QSize(width, height);
51 }
52
53 QSize sz(requestedSize.width() > 0 ? requestedSize.width() : width,
54 requestedSize.height() > 0 ? requestedSize.height() : height);
55
56 QFile f(id);
57 QImage thumbnail(sz, QImage::Format_ARGB32_Premultiplied);
58 thumbnail.fill(Qt::white);
59
60 if (f.exists()) {
61 // try to use any embedded thumbnail
62 KoStore *store = KoStore::createStore(id, KoStore::Read);
63
64 bool thumbnailFound = false;
65 if (store &&
66 // ODF thumbnail?
67 (store->open(QLatin1String("Thumbnails/thumbnail.png")) ||
68 // old KOffice/Calligra thumbnail?
69 store->open(QLatin1String("preview.png")) ||
70 // OOXML?
71 store->open(QLatin1String("docProps/thumbnail.jpeg")))) {
72 // Hooray! No long delay for the user...
73 const QByteArray thumbnailData = store->read(store->size());
74
75 QImage thumbnailImage;
76 if (thumbnailImage.loadFromData(thumbnailData) ){//&&
77 //thumbnailImage.width() >= width && thumbnailImage.height() >= height) {
78 // put a white background behind the thumbnail
79 // as lots of old(?) OOo files have thumbnails with transparent background
80 thumbnail = QImage(thumbnailImage.size(), QImage::Format_RGB32);
81 thumbnail.fill(QColor(Qt::white).rgb());
82 QPainter p(&thumbnail);
83 p.drawImage(QPoint(0, 0), thumbnailImage);
84 p.end();
85 thumbnail = thumbnail.scaled(sz, Qt::KeepAspectRatio, Qt::SmoothTransformation);
86 delete store;
87 thumbnailFound = true;
88 }
89 }
90
91 if(!thumbnailFound) {
92 // load document and render the thumbnail ourselves
93 QProcess thumbnailer;
94 QString thumbnailerProgram = QString("%1%2calligrageminithumbnailhelper").arg(qApp->applicationDirPath()).arg(QDir::separator());
95 QStringList arguments;
96 arguments << "--in" << id;
97 QString thumbFile = id;
98 thumbFile.replace("/", "-").replace("\\", "-");
99 thumbFile.prepend(QDir::separator()).prepend(QDir::tempPath());
100 thumbFile.append(".png");
101 arguments << "--out" << thumbFile;
102 arguments << "--width" << QString::number(sz.width());
103 arguments << "--height" << QString::number(sz.height());
104 bool fileExists = QFile::exists(thumbFile);
105 if(!fileExists)
106 thumbnailer.start(thumbnailerProgram, arguments);
107 if(fileExists || thumbnailer.waitForFinished(3000)) {
108 thumbnail.load(thumbFile);
109 thumbnail = thumbnail.scaled(sz, Qt::KeepAspectRatio, Qt::SmoothTransformation);
110 }
111 else {
112 // some error, final failure...
113 qDebug() << "Failed completely to find a preview for" << id;
114 }
115 }
116 }
117 return thumbnail;
118 }
119