Use bodyDisposition
[kdepim.git] / ktnef / attachpropertydialog.cpp
blob9961b5432d44dffb8301836d735245e2e5357fe4
1 /*
2 This file is part of KTnef.
4 Copyright (C) 2002 Michael Goffioul <kdeprint@swing.be>
5 Copyright (c) 2012 Allen Winter <winter@kde.org>
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software Foundation,
14 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
17 #include "attachpropertydialog.h"
18 #include "qwmf.h"
20 #include <KTNEF/KTNEFAttach>
21 #include <KTNEF/KTNEFProperty>
22 #include <KTNEF/KTNEFPropertySet>
23 #include <KTNEF/KTNEFDefs>
25 #include "ktnef_debug.h"
26 #include <KLocalizedString>
27 #include <KMessageBox>
29 #include <QBuffer>
30 #include <QDataStream>
31 #include <QTreeWidget>
32 #include <KSharedConfig>
33 #include <QMimeDatabase>
34 #include <QMimeType>
35 #include <KConfigGroup>
36 #include <QDialogButtonBox>
37 #include <QPushButton>
38 #include <QVBoxLayout>
39 #include <QFileDialog>
41 AttachPropertyDialog::AttachPropertyDialog(QWidget *parent)
42 : QDialog(parent),
43 mAttach(0)
45 QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close);
46 QVBoxLayout *mainLayout = new QVBoxLayout;
47 setLayout(mainLayout);
48 QPushButton *user1Button = new QPushButton;
49 buttonBox->addButton(user1Button, QDialogButtonBox::ActionRole);
50 connect(buttonBox, &QDialogButtonBox::rejected, this, &AttachPropertyDialog::reject);
51 buttonBox->button(QDialogButtonBox::Close)->setDefault(true);
52 user1Button->setText(i18n("Save..."));
53 setModal(true);
54 QWidget *mainWidget = new QWidget(this);
55 mUI.setupUi(mainWidget);
56 mUI.mProperties->setHeaderHidden(true);
57 connect(user1Button, &QPushButton::clicked, this, &AttachPropertyDialog::slotSave);
58 readConfig();
59 mainLayout->addWidget(mainWidget);
60 mainLayout->addWidget(buttonBox);
63 AttachPropertyDialog::~AttachPropertyDialog()
65 writeConfig();
68 void AttachPropertyDialog::readConfig()
70 KConfigGroup group(KSharedConfig::openConfig(), "AttachPropertyDialog");
71 const QSize size = group.readEntry("Size", QSize(500, 400));
72 if (size.isValid()) {
73 resize(size);
77 void AttachPropertyDialog::writeConfig()
79 KConfigGroup group(KSharedConfig::openConfig(), "AttachPropertyDialog");
80 group.writeEntry("Size", size());
81 group.sync();
84 void AttachPropertyDialog::setAttachment(KTNEFAttach *attach)
86 QString s = attach->fileName().isEmpty() ?
87 attach->name() :
88 attach->fileName();
89 mUI.mFilename->setText(QLatin1String("<b>") + s + QLatin1String("</b>"));
90 setWindowTitle(i18nc("@title:window", "Properties for Attachment %1", s));
91 mUI.mDisplay->setText(attach->displayName());
92 mUI.mMime->setText(attach->mimeTag());
93 s.setNum(attach->size());
94 s.append(i18n(" bytes"));
95 mUI.mSize->setText(s);
96 QMimeDatabase db;
97 QMimeType mimetype = db.mimeTypeForName(attach->mimeTag());
98 QPixmap pix = loadRenderingPixmap(attach, qApp->palette().color(QPalette::Background));
99 if (!pix.isNull()) {
100 mUI.mIcon->setPixmap(pix);
101 } else {
102 mUI.mIcon->setPixmap(mimetype.iconName());
104 mUI.mDescription->setText(mimetype.comment());
105 s.setNum(attach->index());
106 mUI.mIndex->setText(s);
108 formatPropertySet(attach, mUI.mProperties);
109 mAttach = attach;
112 void AttachPropertyDialog::slotSave()
114 if (saveProperty(mUI.mProperties, mAttach, this)) {
115 accept();
119 void AttachPropertyDialog::formatProperties(const QMap<int, KTNEFProperty *> &props, QTreeWidget *lv,
120 QTreeWidgetItem *item, const QString &prefix)
122 QMap<int, KTNEFProperty *>::ConstIterator end(props.constEnd());
123 for (QMap<int, KTNEFProperty *>::ConstIterator it = props.begin(); it != end; ++it) {
124 QTreeWidgetItem *newItem = 0;
125 if (lv) {
126 newItem = new QTreeWidgetItem(lv, QStringList((*it)->keyString()));
127 } else if (item) {
128 newItem = new QTreeWidgetItem(item, QStringList((*it)->keyString()));
129 } else {
130 qCWarning(KTNEFAPPS_LOG) << "formatProperties() called with no listview and no item";
131 return;
134 QVariant value = (*it)->value();
135 if (value.type() == QVariant::List) {
136 newItem->setExpanded(true);
137 newItem->setText(0,
138 newItem->text(0) +
139 QLatin1String(" [") + QString::number(value.toList().count()) + QLatin1Char(']'));
140 int i = 0;
141 QList<QVariant>::ConstIterator litEnd = value.toList().constEnd();
142 for (QList<QVariant>::ConstIterator lit = value.toList().constBegin();
143 lit != litEnd; ++lit, ++i) {
144 new QTreeWidgetItem(newItem,
145 QStringList()
146 << QLatin1Char('[') + QString::number(i) + QLatin1Char(']')
147 << QString(KTNEFProperty::formatValue(*lit)));
149 } else if (value.type() == QVariant::DateTime) {
150 newItem->setText(1, value.toDateTime().toString());
151 } else {
152 newItem->setText(1, (*it)->valueString());
153 newItem->setText(2, prefix + QLatin1Char('_') + QString::number(it.key()));
158 void AttachPropertyDialog::formatPropertySet(KTNEFPropertySet *pSet, QTreeWidget *lv)
160 formatProperties(pSet->properties(), lv, 0, QStringLiteral("prop"));
161 QTreeWidgetItem *item =
162 new QTreeWidgetItem(lv,
163 QStringList(i18nc("@label", "TNEF Attributes")));
164 item->setExpanded(true);
165 formatProperties(pSet->attributes(), 0, item, QStringLiteral("attr"));
168 bool AttachPropertyDialog::saveProperty(QTreeWidget *lv, KTNEFPropertySet *pSet, QWidget *parent)
170 QList<QTreeWidgetItem *> list = lv->selectedItems();
171 if (list.isEmpty() || !list.first()) {
172 KMessageBox::error(
173 parent,
174 i18nc("@info",
175 "Must select an item first."));
176 return false;
179 QTreeWidgetItem *item = list.first();
180 if (item->text(2).isEmpty()) {
181 KMessageBox::error(
182 parent,
183 i18nc("@info",
184 "The selected item cannot be saved because it has an empty tag."));
185 } else {
186 QString tag = item->text(2);
187 int key = tag.midRef(5).toInt();
188 QVariant prop = (tag.startsWith(QStringLiteral("attr_")) ?
189 pSet->attribute(key) :
190 pSet->property(key));
191 QString filename = QFileDialog::getSaveFileName(parent, QString(), tag, QString());
192 if (!filename.isEmpty()) {
193 QFile f(filename);
194 if (f.open(QIODevice::WriteOnly)) {
195 switch (prop.type()) {
196 case QVariant::ByteArray:
197 f.write(prop.toByteArray().data(), prop.toByteArray().size());
198 break;
199 default: {
200 QTextStream t(&f);
201 t << prop.toString();
202 break;
205 f.close();
206 } else {
207 KMessageBox::error(
208 parent,
209 i18nc("@info",
210 "Unable to open file for writing, check file permissions."));
214 return true;
217 QPixmap AttachPropertyDialog::loadRenderingPixmap(KTNEFPropertySet *pSet, const QColor &bgColor)
219 QPixmap pix;
220 QVariant rendData = pSet->attribute(attATTACHRENDDATA);
221 QVariant wmf = pSet->attribute(attATTACHMETAFILE);
223 if (!rendData.isNull() && !wmf.isNull()) {
224 // Get rendering size
225 QByteArray qb = rendData.toByteArray();
226 QBuffer rendBuffer(&qb);
227 rendBuffer.open(QIODevice::ReadOnly);
228 QDataStream rendStream(&rendBuffer);
229 rendStream.setByteOrder(QDataStream::LittleEndian);
230 quint16 type, w, h;
231 rendStream >> type >> w >> w; // read type and skip 4 bytes
232 rendStream >> w >> h;
233 rendBuffer.close();
235 if (type == 1 && w > 0 && h > 0) {
236 // Load WMF data
237 QWinMetaFile wmfLoader;
238 QByteArray qb = wmf.toByteArray();
239 QBuffer wmfBuffer(&qb);
240 wmfBuffer.open(QIODevice::ReadOnly);
241 if (wmfLoader.load(wmfBuffer)) {
242 pix.scaled(w, h, Qt::KeepAspectRatio);
243 pix.fill(bgColor);
244 wmfLoader.paint(&pix);
246 wmfBuffer.close();
249 return pix;