Qt 4.8
qxlibmime.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the plugins of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qxlibmime.h"
43 
44 #include "qxlibstatic.h"
45 #include "qxlibscreen.h"
46 
47 #include <QtCore/QTextCodec>
48 #include <QtGui/QImageWriter>
49 #include <QtCore/QBuffer>
50 
53 { }
54 
56 {}
57 
58 
59 
60 
61 
63 {
64  if (!a) return 0;
65 
66  if (a == XA_STRING || a == QXlibStatic::atom(QXlibStatic::UTF8_STRING)) {
67  return "text/plain"; // some Xdnd clients are dumb
68  }
69  char *atom = XGetAtomName(display, a);
70  QString result = QString::fromLatin1(atom);
71  XFree(atom);
72  return result;
73 }
74 
76 {
77  if (mimeType.isEmpty())
78  return 0;
79  return XInternAtom(display, mimeType.toLatin1().constData(), False);
80 }
81 
83 {
85  if (a) {
86  QString atomName = mimeAtomToString(display, a);
87  formats.append(atomName);
88 
89  // special cases for string type
91  || a == XA_STRING
94  formats.append(QLatin1String("text/plain"));
95 
96  // special cases for uris
97  if (atomName == QLatin1String("text/x-moz-url"))
98  formats.append(QLatin1String("text/uri-list"));
99 
100  // special case for images
101  if (a == XA_PIXMAP)
102  formats.append(QLatin1String("image/ppm"));
103  }
104  return formats;
105 }
106 
107 bool QXlibMime::mimeDataForAtom(Display *display, Atom a, QMimeData *mimeData, QByteArray *data, Atom *atomFormat, int *dataFormat)
108 {
109  bool ret = false;
110  *atomFormat = a;
111  *dataFormat = 8;
112  QString atomName = mimeAtomToString(display, a);
113  if (QInternalMimeData::hasFormatHelper(atomName, mimeData)) {
114  *data = QInternalMimeData::renderDataHelper(atomName, mimeData);
115  if (atomName == QLatin1String("application/x-color"))
116  *dataFormat = 16;
117  ret = true;
118  } else {
120  || a == XA_STRING
123  && QInternalMimeData::hasFormatHelper(QLatin1String("text/plain"), mimeData)) {
125  *data = QInternalMimeData::renderDataHelper(QLatin1String("text/plain"), mimeData);
126  ret = true;
127  } else if (a == XA_STRING) {
129  QLatin1String("text/plain"), mimeData)).toLocal8Bit();
130  ret = true;
131  } else if (a == QXlibStatic::atom(QXlibStatic::TEXT)
133  // the ICCCM states that TEXT and COMPOUND_TEXT are in the
134  // encoding of choice, so we choose the encoding of the locale
136  QLatin1String("text/plain"), mimeData)).toLocal8Bit();
137  char *list[] = { strData.data(), NULL };
138 
139  XICCEncodingStyle style = (a == QXlibStatic::atom(QXlibStatic::COMPOUND_TEXT))
140  ? XCompoundTextStyle : XStdICCTextStyle;
141  XTextProperty textprop;
142  if (list[0] != NULL
143  && XmbTextListToTextProperty(display, list, 1, style,
144  &textprop) == Success) {
145  *atomFormat = textprop.encoding;
146  *dataFormat = textprop.format;
147  *data = QByteArray((const char *) textprop.value, textprop.nitems * textprop.format / 8);
148  ret = true;
149 
150  XFree(textprop.value);
151  }
152  }
153  } else if (atomName == QLatin1String("text/x-moz-url") &&
154  QInternalMimeData::hasFormatHelper(QLatin1String("text/uri-list"), mimeData)) {
156  QLatin1String("text/uri-list"), mimeData).split('\n').first();
157  QString mozUri = QString::fromLatin1(uri, uri.size());
158  mozUri += QLatin1Char('\n');
159  *data = QByteArray(reinterpret_cast<const char *>(mozUri.utf16()), mozUri.length() * 2);
160  ret = true;
161  } else if ((a == XA_PIXMAP || a == XA_BITMAP) && mimeData->hasImage()) {
162  ret = true;
163  }
164  }
165  return ret && data != 0;
166 }
167 
169 {
170  QList<Atom> atoms;
171  atoms.append(mimeStringToAtom(display, format));
172 
173  // special cases for strings
174  if (format == QLatin1String("text/plain")) {
176  atoms.append(XA_STRING);
179  }
180 
181  // special cases for uris
182  if (format == QLatin1String("text/uri-list")) {
183  atoms.append(mimeStringToAtom(display,QLatin1String("text/x-moz-url")));
184  }
185 
186  //special cases for images
187  if (format == QLatin1String("image/ppm"))
188  atoms.append(XA_PIXMAP);
189  if (format == QLatin1String("image/pbm"))
190  atoms.append(XA_BITMAP);
191 
192  return atoms;
193 }
194 
196 {
197  QString atomName = mimeAtomToString(display,a);
198  if (atomName == format)
199  return data;
200 
201  if (!encoding.isEmpty()
202  && atomName == format + QLatin1String(";charset=") + QString::fromLatin1(encoding)) {
203 
204  if (requestedType == QVariant::String) {
206  if (codec)
207  return codec->toUnicode(data);
208  }
209 
210  return data;
211  }
212 
213  // special cases for string types
214  if (format == QLatin1String("text/plain")) {
216  return QString::fromUtf8(data);
217  if (a == XA_STRING)
218  return QString::fromLatin1(data);
221  // #### might be wrong for COMPUND_TEXT
222  return QString::fromLocal8Bit(data, data.size());
223  }
224 
225  // special case for uri types
226  if (format == QLatin1String("text/uri-list")) {
227  if (atomName == QLatin1String("text/x-moz-url")) {
228  // we expect this as utf16 <url><space><title>
229  // the first part is a url that should only contain ascci char
230  // so it should be safe to check that the second char is 0
231  // to verify that it is utf16
232  if (data.size() > 1 && data.at(1) == 0)
233  return QString::fromRawData((const QChar *)data.constData(),
234  data.size() / 2).split(QLatin1Char('\n')).first().toLatin1();
235  }
236  }
237 
238  // special cas for images
239  if (format == QLatin1String("image/ppm")) {
240  if (a == XA_PIXMAP && data.size() == sizeof(Pixmap)) {
241  Pixmap xpm = *((Pixmap*)data.data());
242  if (!xpm)
243  return QByteArray();
244  Window root;
245  int x;
246  int y;
247  uint width;
248  uint height;
249  uint border_width;
250  uint depth;
251 
252  XGetGeometry(display, xpm, &root, &x, &y, &width, &height, &border_width, &depth);
253  XImage *ximg = XGetImage(display,xpm,x,y,width,height,AllPlanes,depth==1 ? XYPixmap : ZPixmap);
255  XDestroyImage(ximg);
256 
257  QImageWriter imageWriter;
258  imageWriter.setFormat("PPMRAW");
259  QBuffer buf;
261  imageWriter.setDevice(&buf);
262  imageWriter.write(qimg);
263  return buf.buffer();
264  }
265  }
266  return QVariant();
267 }
268 
269 Atom QXlibMime::mimeAtomForFormat(Display *display, const QString &format, QVariant::Type requestedType, const QList<Atom> &atoms, QByteArray *requestedEncoding)
270 {
271  requestedEncoding->clear();
272 
273  // find matches for string types
274  if (format == QLatin1String("text/plain")) {
281  if (atoms.contains(XA_STRING))
282  return XA_STRING;
283  }
284 
285  // find matches for uri types
286  if (format == QLatin1String("text/uri-list")) {
287  Atom a = mimeStringToAtom(display,format);
288  if (a && atoms.contains(a))
289  return a;
290  a = mimeStringToAtom(display,QLatin1String("text/x-moz-url"));
291  if (a && atoms.contains(a))
292  return a;
293  }
294 
295  // find match for image
296  if (format == QLatin1String("image/ppm")) {
297  if (atoms.contains(XA_PIXMAP))
298  return XA_PIXMAP;
299  }
300 
301  // for string/text requests try to use a format with a well-defined charset
302  // first to avoid encoding problems
303  if (requestedType == QVariant::String
304  && format.startsWith(QLatin1String("text/"))
305  && !format.contains(QLatin1String("charset="))) {
306 
307  QString formatWithCharset = format;
308  formatWithCharset.append(QLatin1String(";charset=utf-8"));
309 
310  Atom a = mimeStringToAtom(display,formatWithCharset);
311  if (a && atoms.contains(a)) {
312  *requestedEncoding = "utf-8";
313  return a;
314  }
315  }
316 
317  Atom a = mimeStringToAtom(display,format);
318  if (a && atoms.contains(a))
319  return a;
320 
321  return 0;
322 }
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
QBool contains(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.h:904
static QString fromLocal8Bit(const char *, int size=-1)
Returns a QString initialized with the first size characters of the 8-bit string str.
Definition: qstring.cpp:4245
char * data()
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:429
static QString mimeAtomToString(Display *display, Atom a)
Definition: qxlibmime.cpp:62
bool open(OpenMode openMode)
Reimplemented Function
Definition: qbuffer.cpp:338
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
Definition: qstring.cpp:3734
static bool mimeDataForAtom(Display *display, Atom a, QMimeData *mimeData, QByteArray *data, Atom *atomFormat, int *dataFormat)
Definition: qxlibmime.cpp:107
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
long ASN1_INTEGER_get ASN1_INTEGER * a
QByteArray data(const QString &mimetype) const
Returns the data stored in the object in the format described by the MIME type specified by mimeType...
Definition: qmimedata.cpp:524
The QBuffer class provides a QIODevice interface for a QByteArray.
Definition: qbuffer.h:57
The QString class provides a Unicode character string.
Definition: qstring.h:83
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
static QString fromRawData(const QChar *, int size)
Constructs a QString that uses the first size Unicode characters in the array unicode.
Definition: qstring.cpp:7673
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
Q_GUI_EXPORT EGLDisplay display()
Definition: qegl.cpp:589
QBool contains(const T &t) const
Returns true if the list contains an occurrence of value; otherwise returns false.
Definition: qlist.h:880
QByteArray & buffer()
Returns a reference to the QBuffer&#39;s internal buffer.
Definition: qbuffer.cpp:271
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
The QImageWriter class provides a format independent interface for writing images to files or other d...
Definition: qimagewriter.h:59
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
static QString fromUtf8(const char *, int size=-1)
Returns a QString initialized with the first size bytes of the UTF-8 string str.
Definition: qstring.cpp:4302
QStringList formats() const
Returns a list of formats supported by the object.
Definition: qdnd.cpp:351
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:87
unsigned int uint
Definition: qglobal.h:996
static bool hasFormatHelper(const QString &mimeType, const QMimeData *data)
Definition: qdnd.cpp:428
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal...
Definition: qstring.h:654
static QTextCodec * codec(MYSQL *mysql)
Definition: qsql_mysql.cpp:220
Type
This enum type defines the types of variable that a QVariant can contain.
Definition: qvariant.h:95
static void split(QT_FT_Vector *b)
static QStringList mimeFormatsForAtom(Display *display, Atom a)
Definition: qxlibmime.cpp:82
QByteArray toLatin1() const Q_REQUIRED_RESULT
Returns a Latin-1 representation of the string as a QByteArray.
Definition: qstring.cpp:3993
The QMimeData class provides a container for data that records information about its MIME type...
Definition: qmimedata.h:57
QByteArray toLocal8Bit() const Q_REQUIRED_RESULT
Returns the local 8-bit representation of the string as a QByteArray.
Definition: qstring.cpp:4049
static QByteArray renderDataHelper(const QString &mimeType, const QMimeData *data)
Definition: qdnd.cpp:447
static Atom atom(X11Atom atom)
T & first()
Returns a reference to the first item in the list.
Definition: qlist.h:282
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
bool hasImage() const
Returns true if the object can return an image; otherwise returns false.
Definition: qmimedata.cpp:471
static QVariant mimeConvertToFormat(Display *display, Atom a, const QByteArray &data, const QString &format, QVariant::Type requestedType, const QByteArray &encoding)
Definition: qxlibmime.cpp:195
QString toUnicode(const QByteArray &) const
Converts a from the encoding of this codec to Unicode, and returns the result in a QString...
QList< QByteArray > split(char sep) const
Splits the byte array into subarrays wherever sep occurs, and returns the list of those arrays...
void setDevice(QIODevice *device)
Sets QImageWriter&#39;s device to device.
static Atom mimeStringToAtom(Display *display, const QString &mimeType)
Definition: qxlibmime.cpp:75
struct _XDisplay Display
Definition: qwindowdefs.h:115
QString & append(QChar c)
Definition: qstring.cpp:1777
static QString fromLatin1(const char *, int size=-1)
Returns a QString initialized with the first size characters of the Latin-1 string str...
Definition: qstring.cpp:4188
static QList< Atom > mimeAtomsForFormat(Display *display, const QString &format)
Definition: qxlibmime.cpp:168
static QTextCodec * codecForName(const QByteArray &name)
Searches all installed QTextCodec objects and returns the one which best matches name; the match is c...
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
static QImage qimageFromXImage(XImage *xi)
void setFormat(const QByteArray &format)
Sets the format QImageWriter will use when writing images, to format.
bool isEmpty() const
Returns true if the byte array has size 0; otherwise returns false.
Definition: qbytearray.h:421
static Atom mimeAtomForFormat(Display *display, const QString &format, QVariant::Type requestedType, const QList< Atom > &atoms, QByteArray *requestedEncoding)
Definition: qxlibmime.cpp:269
The QTextCodec class provides conversions between text encodings.
Definition: qtextcodec.h:62
char at(int i) const
Returns the character at index position i in the byte array.
Definition: qbytearray.h:413
bool write(const QImage &image)
Writes the image image to the assigned device or file name.
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
void clear()
Clears the contents of the byte array and makes it empty.
The QList class is a template class that provides lists.
Definition: qdatastream.h:62