File indexing completed on 2024-04-28 05:11:30
0001 /* 0002 SPDX-FileCopyrightText: 2003 Cornelius Schumacher <schumacher@kde.org> 0003 SPDX-FileCopyrightText: 2005 Reinhold Kainhofer <reinhold@kainhofer.com> 0004 SPDX-FileCopyrightText: 2005 Rafal Rzepecki <divide@users.sourceforge.net> 0005 SPDX-FileCopyrightText: 2010 Bertjan Broeksema <broeksema@kde.org> 0006 SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com> 0007 0008 SPDX-License-Identifier: GPL-2.0-or-later WITH Qt-Commercial-exception-1.0 0009 0010 NOTE: May, 2010. Extracted this code from 0011 kdepim/incidenceeditors/editorattachments.{h,cpp} 0012 */ 0013 0014 #include <config-enterprise.h> 0015 0016 #include "attachmenticonview.h" 0017 0018 #include <KIconLoader> 0019 #include <KUrlMimeData> 0020 #include <QDir> 0021 #include <QTemporaryFile> 0022 0023 #include <KIconEngine> 0024 #include <QDrag> 0025 #include <QKeyEvent> 0026 #include <QMimeData> 0027 #include <QMimeDatabase> 0028 0029 using namespace IncidenceEditorNG; 0030 0031 AttachmentIconItem::AttachmentIconItem(const KCalendarCore::Attachment &att, QListWidget *parent) 0032 : QListWidgetItem(parent) 0033 { 0034 if (!att.isEmpty()) { 0035 mAttachment = att; 0036 } else { 0037 // for the enterprise, inline attachments are the default 0038 #if KDEPIM_ENTERPRISE_BUILD 0039 mAttachment = KCalendarCore::Attachment(QByteArray()); // use the non-uri constructor 0040 // as we want inline by default 0041 #else 0042 mAttachment = KCalendarCore::Attachment(QString()); 0043 #endif 0044 } 0045 readAttachment(); 0046 setFlags(flags() | Qt::ItemIsDragEnabled); 0047 } 0048 0049 AttachmentIconItem::~AttachmentIconItem() = default; 0050 0051 KCalendarCore::Attachment AttachmentIconItem::attachment() const 0052 { 0053 return mAttachment; 0054 } 0055 0056 const QString AttachmentIconItem::uri() const 0057 { 0058 return mAttachment.uri(); 0059 } 0060 0061 const QString AttachmentIconItem::savedUri() const 0062 { 0063 return mSaveUri; 0064 } 0065 0066 void AttachmentIconItem::setUri(const QString &uri) 0067 { 0068 mSaveUri = uri; 0069 mAttachment.setUri(mSaveUri); 0070 readAttachment(); 0071 } 0072 0073 void AttachmentIconItem::setData(const QByteArray &data) 0074 { 0075 mAttachment.setDecodedData(data); 0076 readAttachment(); 0077 } 0078 0079 const QString AttachmentIconItem::mimeType() const 0080 { 0081 return mAttachment.mimeType(); 0082 } 0083 0084 void AttachmentIconItem::setMimeType(const QString &mime) 0085 { 0086 mAttachment.setMimeType(mime); 0087 readAttachment(); 0088 } 0089 0090 const QString AttachmentIconItem::label() const 0091 { 0092 return mAttachment.label(); 0093 } 0094 0095 void AttachmentIconItem::setLabel(const QString &description) 0096 { 0097 if (mAttachment.label() == description) { 0098 return; 0099 } 0100 mAttachment.setLabel(description); 0101 readAttachment(); 0102 } 0103 0104 bool AttachmentIconItem::isBinary() const 0105 { 0106 return mAttachment.isBinary(); 0107 } 0108 0109 QPixmap AttachmentIconItem::icon() const 0110 { 0111 QMimeDatabase db; 0112 return icon(db.mimeTypeForName(mAttachment.mimeType()), mAttachment.uri(), mAttachment.isBinary()); 0113 } 0114 0115 QPixmap AttachmentIconItem::icon(const QMimeType &mimeType, const QString &uri, bool binary) 0116 { 0117 const QString iconStr = mimeType.iconName(); 0118 QStringList overlays; 0119 if (!uri.isEmpty() && !binary) { 0120 overlays << QStringLiteral("emblem-link"); 0121 } 0122 return QIcon(new KIconEngine(iconStr, KIconLoader::global(), overlays)).pixmap(KIconLoader::SizeSmallMedium, KIconLoader::SizeSmallMedium); 0123 } 0124 0125 void AttachmentIconItem::readAttachment() 0126 { 0127 setText(mAttachment.label()); 0128 setFlags(flags() | Qt::ItemIsEditable); 0129 0130 QMimeDatabase db; 0131 if (mAttachment.mimeType().isEmpty() || !(db.mimeTypeForName(mAttachment.mimeType()).isValid())) { 0132 QMimeType mimeType; 0133 if (mAttachment.isUri()) { 0134 mimeType = db.mimeTypeForUrl(QUrl(mAttachment.uri())); 0135 } else { 0136 mimeType = db.mimeTypeForData(mAttachment.decodedData()); 0137 } 0138 mAttachment.setMimeType(mimeType.name()); 0139 } 0140 0141 setIcon(icon()); 0142 } 0143 0144 AttachmentIconView::AttachmentIconView(QWidget *parent) 0145 : QListWidget(parent) 0146 { 0147 setMovement(Static); 0148 setAcceptDrops(true); 0149 setSelectionMode(ExtendedSelection); 0150 setSelectionRectVisible(false); 0151 setIconSize(QSize(KIconLoader::SizeLarge, KIconLoader::SizeLarge)); 0152 setFlow(LeftToRight); 0153 setWrapping(true); 0154 #ifndef QT_NO_DRAGANDDROP 0155 setDragDropMode(DragDrop); 0156 setDragEnabled(true); 0157 #endif 0158 setEditTriggers(EditKeyPressed); 0159 setContextMenuPolicy(Qt::CustomContextMenu); 0160 } 0161 0162 QUrl AttachmentIconItem::tempFileForAttachment() 0163 { 0164 if (mTempFile.isValid()) { 0165 return mTempFile; 0166 } 0167 QTemporaryFile *file = nullptr; 0168 0169 QMimeDatabase db; 0170 QStringList patterns = db.mimeTypeForName(mAttachment.mimeType()).globPatterns(); 0171 0172 if (!patterns.empty()) { 0173 file = new QTemporaryFile(QDir::tempPath() + QLatin1StringView("/attachementview_XXXXX") + patterns.first().remove(QLatin1Char('*'))); 0174 } else { 0175 file = new QTemporaryFile(); 0176 } 0177 file->setParent(listWidget()); 0178 0179 file->setAutoRemove(true); 0180 file->open(); 0181 // read-only not to give the idea that it could be written to 0182 file->setPermissions(QFile::ReadUser); 0183 file->write(QByteArray::fromBase64(mAttachment.data())); 0184 mTempFile = QUrl::fromLocalFile(file->fileName()); 0185 file->close(); 0186 return mTempFile; 0187 } 0188 0189 QMimeData *AttachmentIconView::mimeData(const QList<QListWidgetItem *> &items) const // clazy:exclude=function-args-by-ref 0190 { 0191 // create a list of the URL:s that we want to drag 0192 QList<QUrl> urls; 0193 QStringList labels; 0194 for (QListWidgetItem *it : items) { 0195 if (it->isSelected()) { 0196 auto item = static_cast<AttachmentIconItem *>(it); 0197 if (item->isBinary()) { 0198 urls.append(item->tempFileForAttachment()); 0199 } else { 0200 urls.append(QUrl(item->uri())); 0201 } 0202 labels.append(QString::fromLatin1(QUrl::toPercentEncoding(item->label()))); 0203 } 0204 } 0205 if (selectionMode() == NoSelection) { 0206 auto item = static_cast<AttachmentIconItem *>(currentItem()); 0207 if (item) { 0208 urls.append(QUrl(item->uri())); 0209 labels.append(QString::fromLatin1(QUrl::toPercentEncoding(item->label()))); 0210 } 0211 } 0212 0213 QMap<QString, QString> metadata; 0214 metadata[QStringLiteral("labels")] = labels.join(QLatin1Char(':')); 0215 0216 auto mimeData = new QMimeData; 0217 mimeData->setUrls(urls); 0218 KUrlMimeData::setMetaData(metadata, mimeData); 0219 return mimeData; 0220 } 0221 0222 QMimeData *AttachmentIconView::mimeData() const 0223 { 0224 return mimeData(selectedItems()); 0225 } 0226 0227 void AttachmentIconView::startDrag(Qt::DropActions supportedActions) 0228 { 0229 Q_UNUSED(supportedActions) 0230 #ifndef QT_NO_DRAGANDDROP 0231 QPixmap pixmap; 0232 if (selectedItems().size() > 1) { 0233 pixmap = KIconLoader::global()->loadIcon(QStringLiteral("mail-attachment"), KIconLoader::Desktop); 0234 } 0235 if (pixmap.isNull()) { 0236 pixmap = static_cast<AttachmentIconItem *>(currentItem())->icon(); 0237 } 0238 0239 const QPoint hotspot(pixmap.width() / 2, pixmap.height() / 2); 0240 0241 auto drag = new QDrag(this); 0242 drag->setMimeData(mimeData()); 0243 0244 drag->setPixmap(pixmap); 0245 drag->setHotSpot(hotspot); 0246 drag->exec(Qt::CopyAction); 0247 #endif 0248 } 0249 0250 void AttachmentIconView::keyPressEvent(QKeyEvent *event) 0251 { 0252 if ((event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) && currentItem() && state() != EditingState) { 0253 Q_EMIT itemDoubleClicked(currentItem()); // ugly, but itemActivated() also includes single click 0254 return; 0255 } 0256 QListWidget::keyPressEvent(event); 0257 } 0258 0259 #include "moc_attachmenticonview.cpp"