1 /*
2     SPDX-FileCopyrightText: 2016 Kai Uwe Broulik <kde@privat.broulik.de>
3 
4     SPDX-License-Identifier: LGPL-2.1-or-later
5 */
6 
7 #include "thumbnailer.h"
8 
9 #include <KIO/PreviewJob>
10 
11 #include <QApplication>
12 #include <QClipboard>
13 #include <QIcon>
14 #include <QMenu>
15 #include <QMimeData>
16 #include <QQuickItem>
17 #include <QQuickWindow>
18 #include <QTimer>
19 
20 #include <KFileItemListProperties>
21 #include <KLocalizedString>
22 #include <KPropertiesDialog>
23 #include <KProtocolManager>
24 #include <KUrlMimeData>
25 
26 #include <KIO/OpenFileManagerWindowJob>
27 
Thumbnailer(QObject * parent)28 Thumbnailer::Thumbnailer(QObject *parent)
29     : QObject(parent)
30 {
31 }
32 
33 Thumbnailer::~Thumbnailer() = default;
34 
classBegin()35 void Thumbnailer::classBegin()
36 {
37 }
38 
componentComplete()39 void Thumbnailer::componentComplete()
40 {
41     m_inited = true;
42     generatePreview();
43 }
44 
url() const45 QUrl Thumbnailer::url() const
46 {
47     return m_url;
48 }
49 
setUrl(const QUrl & url)50 void Thumbnailer::setUrl(const QUrl &url)
51 {
52     if (m_url != url) {
53         m_url = url;
54         emit urlChanged();
55 
56         generatePreview();
57     }
58 }
59 
size() const60 QSize Thumbnailer::size() const
61 {
62     return m_size;
63 }
64 
setSize(const QSize & size)65 void Thumbnailer::setSize(const QSize &size)
66 {
67     if (m_size != size) {
68         m_size = size;
69         emit sizeChanged();
70 
71         generatePreview();
72     }
73 }
74 
busy() const75 bool Thumbnailer::busy() const
76 {
77     return m_busy;
78 }
79 
hasPreview() const80 bool Thumbnailer::hasPreview() const
81 {
82     return !m_pixmap.isNull();
83 }
84 
pixmap() const85 QPixmap Thumbnailer::pixmap() const
86 {
87     return m_pixmap;
88 }
89 
pixmapSize() const90 QSize Thumbnailer::pixmapSize() const
91 {
92     return m_pixmap.size();
93 }
94 
iconName() const95 QString Thumbnailer::iconName() const
96 {
97     return m_iconName;
98 }
99 
menuVisible() const100 bool Thumbnailer::menuVisible() const
101 {
102     return m_menuVisible;
103 }
104 
generatePreview()105 void Thumbnailer::generatePreview()
106 {
107     if (!m_inited) {
108         return;
109     }
110 
111     if (!m_url.isValid() || !m_url.isLocalFile() || !m_size.isValid() || m_size.isEmpty()) {
112         return;
113     }
114 
115     auto maxSize = qMax(m_size.width(), m_size.height());
116     KIO::PreviewJob *job = KIO::filePreview(KFileItemList({KFileItem(m_url)}), QSize(maxSize, maxSize));
117     job->setScaleType(KIO::PreviewJob::Scaled);
118     job->setIgnoreMaximumSize(true);
119 
120     connect(job, &KIO::PreviewJob::gotPreview, this, [this](const KFileItem &item, const QPixmap &preview) {
121         Q_UNUSED(item);
122         m_pixmap = preview;
123         emit pixmapChanged();
124 
125         if (!m_iconName.isEmpty()) {
126             m_iconName.clear();
127             emit iconNameChanged();
128         }
129     });
130 
131     connect(job, &KIO::PreviewJob::failed, this, [this](const KFileItem &item) {
132         m_pixmap = QPixmap();
133         emit pixmapChanged();
134 
135         const QString &iconName = item.determineMimeType().iconName();
136         if (m_iconName != iconName) {
137             m_iconName = iconName;
138             emit iconNameChanged();
139         }
140     });
141 
142     connect(job, &KJob::result, this, [this] {
143         m_busy = false;
144         emit busyChanged();
145     });
146 
147     m_busy = true;
148     emit busyChanged();
149 
150     job->start();
151 }
152