source: trunk/src/corelib/kernel/qmimedata.cpp@ 747

Last change on this file since 747 was 651, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.2 sources.

File size: 18.5 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtCore module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qmimedata.h"
43
44#include "private/qobject_p.h"
45#include "qurl.h"
46#include "qstringlist.h"
47#include "qtextcodec.h"
48
49QT_BEGIN_NAMESPACE
50
51struct QMimeDataStruct
52{
53 QString format;
54 QVariant data;
55};
56
57class QMimeDataPrivate : public QObjectPrivate
58{
59 Q_DECLARE_PUBLIC(QMimeData)
60public:
61 void removeData(const QString &format);
62 void setData(const QString &format, const QVariant &data);
63 QVariant getData(const QString &format) const;
64
65 QVariant retrieveTypedData(const QString &format, QVariant::Type type) const;
66
67 QList<QMimeDataStruct> dataList;
68};
69
70void QMimeDataPrivate::removeData(const QString &format)
71{
72 for (int i=0; i<dataList.size(); i++) {
73 if (dataList.at(i).format == format) {
74 dataList.removeAt(i);
75 return;
76 }
77 }
78}
79
80void QMimeDataPrivate::setData(const QString &format, const QVariant &data)
81{
82 // remove it first if the format is already here.
83 removeData(format);
84 QMimeDataStruct mimeData;
85 mimeData.format = format;
86 mimeData.data = data;
87 dataList += mimeData;
88}
89
90
91QVariant QMimeDataPrivate::getData(const QString &format) const
92{
93 QVariant data;
94 for (int i=0; i<dataList.size(); i++) {
95 if (dataList.at(i).format == format) {
96 data = dataList.at(i).data;
97 break;
98 }
99 }
100 return data;
101}
102
103QVariant QMimeDataPrivate::retrieveTypedData(const QString &format, QVariant::Type type) const
104{
105 Q_Q(const QMimeData);
106
107 QVariant data = q->retrieveData(format, type);
108 if (data.type() == type || !data.isValid())
109 return data;
110
111 // provide more conversion possiblities than just what QVariant provides
112
113 // URLs can be lists as well...
114 if ((type == QVariant::Url && data.type() == QVariant::List)
115 || (type == QVariant::List && data.type() == QVariant::Url))
116 return data;
117
118 // images and pixmaps are interchangeable
119 if ((type == QVariant::Pixmap && data.type() == QVariant::Image)
120 || (type == QVariant::Image && data.type() == QVariant::Pixmap))
121 return data;
122
123 if (data.type() == QVariant::ByteArray) {
124 // see if we can convert to the requested type
125 switch(type) {
126#ifndef QT_NO_TEXTCODEC
127 case QVariant::String: {
128 const QByteArray ba = data.toByteArray();
129 QTextCodec *codec = QTextCodec::codecForName("utf-8");
130 if (format == QLatin1String("text/html"))
131 codec = QTextCodec::codecForHtml(ba, codec);
132 return codec->toUnicode(ba);
133 }
134#endif // QT_NO_TEXTCODEC
135 case QVariant::Color: {
136 QVariant newData = data;
137 newData.convert(QVariant::Color);
138 return newData;
139 }
140 case QVariant::List: {
141 if (format != QLatin1String("text/uri-list"))
142 break;
143 // fall through
144 }
145 case QVariant::Url: {
146 QByteArray ba = data.toByteArray();
147 // Qt 3.x will send text/uri-list with a trailing
148 // null-terminator (that is *not* sent for any other
149 // text/* mime-type), so chop it off
150 if (ba.endsWith('\0'))
151 ba.chop(1);
152
153 QList<QByteArray> urls = ba.split('\n');
154 QList<QVariant> list;
155 for (int i = 0; i < urls.size(); ++i) {
156 QByteArray ba = urls.at(i).trimmed();
157 if (!ba.isEmpty())
158 list.append(QUrl::fromEncoded(ba));
159 }
160 return list;
161 }
162 default:
163 break;
164 }
165
166 } else if (type == QVariant::ByteArray) {
167
168 // try to convert to bytearray
169 switch(data.type()) {
170 case QVariant::ByteArray:
171 case QVariant::Color:
172 return data.toByteArray();
173 break;
174 case QVariant::String:
175 return data.toString().toUtf8();
176 break;
177 case QVariant::Url:
178 return data.toUrl().toEncoded();
179 break;
180 case QVariant::List: {
181 // has to be list of URLs
182 QByteArray result;
183 QList<QVariant> list = data.toList();
184 for (int i = 0; i < list.size(); ++i) {
185 if (list.at(i).type() == QVariant::Url) {
186 result += list.at(i).toUrl().toEncoded();
187 result += "\r\n";
188 }
189 }
190 if (!result.isEmpty())
191 return result;
192 break;
193 }
194 default:
195 break;
196 }
197 }