Incidenceeditor

attachmenticonview.cpp
1/*
2 SPDX-FileCopyrightText: 2003 Cornelius Schumacher <schumacher@kde.org>
3 SPDX-FileCopyrightText: 2005 Reinhold Kainhofer <reinhold@kainhofer.com>
4 SPDX-FileCopyrightText: 2005 Rafal Rzepecki <divide@users.sourceforge.net>
5 SPDX-FileCopyrightText: 2010 Bertjan Broeksema <broeksema@kde.org>
6 SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
7
8 SPDX-License-Identifier: GPL-2.0-or-later WITH Qt-Commercial-exception-1.0
9
10 NOTE: May, 2010. Extracted this code from
11 kdepim/incidenceeditors/editorattachments.{h,cpp}
12*/
13
14#include <config-enterprise.h>
15
16#include "attachmenticonview.h"
17
18#include <KIconLoader>
19#include <KIconUtils>
20#include <KUrlMimeData>
21#include <QDir>
22#include <QTemporaryFile>
23
24#include <QDrag>
25#include <QKeyEvent>
26#include <QMimeData>
27#include <QMimeDatabase>
28using namespace Qt::Literals::StringLiterals;
29using namespace IncidenceEditorNG;
30
31AttachmentIconItem::AttachmentIconItem(const KCalendarCore::Attachment &att, QListWidget *parent)
32 : QListWidgetItem(parent)
33{
34 if (!att.isEmpty()) {
35 mAttachment = att;
36 } else {
37 // for the enterprise, inline attachments are the default
38#if KDEPIM_ENTERPRISE_BUILD
39 mAttachment = KCalendarCore::Attachment(QByteArray()); // use the non-uri constructor
40 // as we want inline by default
41#else
42 mAttachment = KCalendarCore::Attachment(QString());
43#endif
44 }
45 readAttachment();
47}
48
49AttachmentIconItem::~AttachmentIconItem() = default;
50
51KCalendarCore::Attachment AttachmentIconItem::attachment() const
52{
53 return mAttachment;
54}
55
56const QString AttachmentIconItem::uri() const
57{
58 return mAttachment.uri();
59}
60
61const QString AttachmentIconItem::savedUri() const
62{
63 return mSaveUri;
64}
65
66void AttachmentIconItem::setUri(const QString &uri)
67{
68 mSaveUri = uri;
69 mAttachment.setUri(mSaveUri);
70 readAttachment();
71}
72
73void AttachmentIconItem::setData(const QByteArray &data)
74{
75 mAttachment.setDecodedData(data);
76 readAttachment();
77}
78
79const QString AttachmentIconItem::mimeType() const
80{
81 return mAttachment.mimeType();
82}
83
84void AttachmentIconItem::setMimeType(const QString &mime)
85{
86 mAttachment.setMimeType(mime);
87 readAttachment();
88}
89
90const QString AttachmentIconItem::label() const
91{
92 return mAttachment.label();
93}
94
95void AttachmentIconItem::setLabel(const QString &description)
96{
97 if (mAttachment.label() == description) {
98 return;
99 }
100 mAttachment.setLabel(description);
101 readAttachment();
102}
103
104bool AttachmentIconItem::isBinary() const
105{
106 return mAttachment.isBinary();
107}
108
109QIcon AttachmentIconItem::icon() const
110{
111 QMimeDatabase db;
112 return icon(db.mimeTypeForName(mAttachment.mimeType()), mAttachment.uri(), mAttachment.isBinary());
113}
114
115QIcon AttachmentIconItem::icon(const QMimeType &mimeType, const QString &uri, bool binary)
116{
117 const QString iconStr = mimeType.iconName();
118 QStringList overlays;
119 if (!uri.isEmpty() && !binary) {
120 overlays << QStringLiteral("emblem-link");
121 }
122
123 return KIconUtils::addOverlays(QIcon::fromTheme(iconStr), overlays);
124}
125
126void AttachmentIconItem::readAttachment()
127{
128 setText(mAttachment.label());
130
131 QMimeDatabase db;
132 if (mAttachment.mimeType().isEmpty() || !(db.mimeTypeForName(mAttachment.mimeType()).isValid())) {
134 if (mAttachment.isUri()) {
135 mimeType = db.mimeTypeForUrl(QUrl(mAttachment.uri()));
136 } else {
137 mimeType = db.mimeTypeForData(mAttachment.decodedData());
138 }
139 mAttachment.setMimeType(mimeType.name());
140 }
141
142 setIcon(icon());
143}
144
145AttachmentIconView::AttachmentIconView(QWidget *parent)
146 : QListWidget(parent)
147{
148 setMovement(Static);
149 setAcceptDrops(true);
150 setSelectionMode(ExtendedSelection);
151 setSelectionRectVisible(false);
153 setFlow(LeftToRight);
154 setWrapping(true);
155#ifndef QT_NO_DRAGANDDROP
156 setDragDropMode(DragDrop);
157 setDragEnabled(true);
158#endif
159 setEditTriggers(EditKeyPressed);
160 setContextMenuPolicy(Qt::CustomContextMenu);
161}
162
163QUrl AttachmentIconItem::tempFileForAttachment()
164{
165 if (mTempFile.isValid()) {
166 return mTempFile;
167 }
168 QTemporaryFile *file = nullptr;
169
170 QMimeDatabase db;
171 QStringList patterns = db.mimeTypeForName(mAttachment.mimeType()).globPatterns();
172
173 if (!patterns.empty()) {
174 file = new QTemporaryFile(QDir::tempPath() + "/attachementview_XXXXX"_L1 + patterns.first().remove(QLatin1Char('*')));
175 } else {
176 file = new QTemporaryFile();
177 }
178 file->setParent(listWidget());
179
180 file->setAutoRemove(true);
181 file->open();
182 // read-only not to give the idea that it could be written to
184 file->write(QByteArray::fromBase64(mAttachment.data()));
185 mTempFile = QUrl::fromLocalFile(file->fileName());
186 file->close();
187 return mTempFile;
188}
189
190QMimeData *AttachmentIconView::mimeData(const QList<QListWidgetItem *> &items) const // clazy:exclude=function-args-by-ref
191{
192 // create a list of the URL:s that we want to drag
193 QList<QUrl> urls;
194 QStringList labels;
195 for (QListWidgetItem *it : items) {
196 if (it->isSelected()) {
197 auto item = static_cast<AttachmentIconItem *>(it);
198 if (item->isBinary()) {
199 urls.append(item->tempFileForAttachment());
200 } else {
201 urls.append(QUrl(item->uri()));
202 }
203 labels.append(QString::fromLatin1(QUrl::toPercentEncoding(item->label())));
204 }
205 }
206 if (selectionMode() == NoSelection) {
207 auto item = static_cast<AttachmentIconItem *>(currentItem());
208 if (item) {
209 urls.append(QUrl(item->uri()));
210 labels.append(QString::fromLatin1(QUrl::toPercentEncoding(item->label())));
211 }
212 }
213
214 QMap<QString, QString> metadata;
215 metadata[QStringLiteral("labels")] = labels.join(QLatin1Char(':'));
216
217 auto mimeData = new QMimeData;
218 mimeData->setUrls(urls);
219 KUrlMimeData::setMetaData(metadata, mimeData);
220 return mimeData;
221}
222
223QMimeData *AttachmentIconView::mimeData() const
224{
225 return mimeData(selectedItems());
226}
227
228void AttachmentIconView::startDrag(Qt::DropActions supportedActions)
229{
230 Q_UNUSED(supportedActions)
231#ifndef QT_NO_DRAGANDDROP
232 QPixmap pixmap;
233 if (selectedItems().size() > 1) {
234 pixmap = QIcon::fromTheme(QStringLiteral("mail-attachment")).pixmap(64);
235 }
236 if (pixmap.isNull()) {
237 pixmap = static_cast<AttachmentIconItem *>(currentItem())->icon().pixmap(64);
238 }
239
240 const QPoint hotspot(pixmap.width() / 2, pixmap.height() / 2);
241
242 auto drag = new QDrag(this);
243 drag->setMimeData(mimeData());
244
245 drag->setPixmap(pixmap);
246 drag->setHotSpot(hotspot);
247 drag->exec(Qt::CopyAction);
248#endif
249}
250
251void AttachmentIconView::keyPressEvent(QKeyEvent *event)
252{
253 if ((event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) && currentItem() && state() != EditingState) {
254 Q_EMIT itemDoubleClicked(currentItem()); // ugly, but itemActivated() also includes single click
255 return;
256 }
258}
259
260#include "moc_attachmenticonview.cpp"
QByteArray decodedData() const
QString mimeType() const
void setDecodedData(const QByteArray &data)
QByteArray data() const
void setUri(const QString &uri)
void setMimeType(const QString &mime)
void setLabel(const QString &label)
KCALUTILS_EXPORT QString mimeType()
KCRASH_EXPORT void setFlags(KCrash::CrashFlags flags)
QIcon addOverlays(const QIcon &icon, const QHash< Qt::Corner, QIcon > &overlays)
KCOREADDONS_EXPORT void setMetaData(const MetaDataMap &metaData, QMimeData *mimeData)
virtual void keyPressEvent(QKeyEvent *event) override
State state() const const
QByteArray fromBase64(const QByteArray &base64, Base64Options options)
QString tempPath()
virtual bool setPermissions(Permissions permissions) override
virtual void close() override
QPixmap pixmap(QWindow *window, const QSize &size, Mode mode, State state) const const
QIcon fromTheme(const QString &name)
qint64 write(const QByteArray &data)
void append(QList< T > &&value)
bool empty() const const
T & first()
QListWidgetItem * currentItem() const const
virtual bool event(QEvent *e) override
void itemDoubleClicked(QListWidgetItem *item)
QList< QListWidgetItem * > selectedItems() const const
virtual QVariant data(int role) const const
Qt::ItemFlags flags() const const
QListWidget * listWidget() const const
void setFlags(Qt::ItemFlags flags)
void setIcon(const QIcon &icon)
void setText(const QString &text)
void setUrls(const QList< QUrl > &urls)
QMimeType mimeTypeForData(QIODevice *device) const const
QMimeType mimeTypeForName(const QString &nameOrAlias) const const
QMimeType mimeTypeForUrl(const QUrl &url) const const
bool isValid() const const
Q_EMITQ_EMIT
void setParent(QObject *parent)
QString fromLatin1(QByteArrayView str)
bool isEmpty() const const
QString join(QChar separator) const const
CustomContextMenu
typedef DropActions
ItemIsDragEnabled
Key_Return
virtual QString fileName() const const override
void setAutoRemove(bool b)
QUrl fromLocalFile(const QString &localFile)
bool isValid() const const
QByteArray toPercentEncoding(const QString &input, const QByteArray &exclude, const QByteArray &include)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Oct 11 2024 12:16:44 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.