Qt 4.8
qmime_win.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 QtGui module 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 "qmime.h"
43 
44 #include "qimagereader.h"
45 #include "qimagewriter.h"
46 #include "qdatastream.h"
47 #include "qbuffer.h"
48 #include "qt_windows.h"
49 #include "qapplication_p.h"
50 #include "qtextcodec.h"
51 #include "qregexp.h"
52 #include "qalgorithms.h"
53 #include "qmap.h"
54 #include "qdnd_p.h"
55 #include <shlobj.h>
56 #include "qurl.h"
57 #include "qvariant.h"
58 #include "qtextdocument.h"
59 #include "qdir.h"
60 
61 #if defined(Q_OS_WINCE)
62 #include "qguifunctions_wince.h"
63 #endif
64 
66 
67 #ifndef QT_NO_IMAGEFORMAT_BMP
68 #ifndef CF_DIBV5
69 #define CF_DIBV5 17
70 #endif
71 /* The MSVC compilers allows multi-byte characters, that has the behavior of
72  * that each character gets shifted into position. 0x73524742 below is for MSVC
73  * equivalent to doing 'sRGB', but this does of course not work
74  * on conformant C++ compilers. */
75 #define BMP_LCS_sRGB 0x73524742
76 #define BMP_LCS_GM_IMAGES 0x00000004L
77 
78 struct _CIEXYZ {
80 };
81 
82 struct _CIEXYZTRIPLE {
83  _CIEXYZ ciexyzRed, ciexyzGreen, ciexyzBlue;
84 };
85 
87  DWORD bV5Size;
88  LONG bV5Width;
89  LONG bV5Height;
90  WORD bV5Planes;
93  DWORD bV5SizeImage;
96  DWORD bV5ClrUsed;
98  DWORD bV5RedMask;
99  DWORD bV5GreenMask;
100  DWORD bV5BlueMask;
102  DWORD bV5CSType;
104  DWORD bV5GammaRed;
107  DWORD bV5Intent;
110  DWORD bV5Reserved;
111 };
112 static const int BMP_BITFIELDS = 3;
113 
114 extern bool qt_read_dib(QDataStream&, QImage&); // qimage.cpp
115 extern bool qt_write_dib(QDataStream&, QImage); // qimage.cpp
116 static bool qt_write_dibv5(QDataStream &s, QImage image);
117 static bool qt_read_dibv5(QDataStream &s, QImage &image);
118 #endif
119 
120 //#define QMIME_DEBUG
121 
122 
123 // helpers for using global memory
124 
125 static int getCf(const FORMATETC &formatetc)
126 {
127  return formatetc.cfFormat;
128 }
129 
130 static FORMATETC setCf(int cf)
131 {
132  FORMATETC formatetc;
133  formatetc.cfFormat = cf;
134  formatetc.dwAspect = DVASPECT_CONTENT;
135  formatetc.lindex = -1;
136  formatetc.ptd = NULL;
137  formatetc.tymed = TYMED_HGLOBAL;
138  return formatetc;
139 }
140 
141 static bool setData(const QByteArray &data, STGMEDIUM *pmedium)
142 {
143  HGLOBAL hData = GlobalAlloc(0, data.size());
144  if (!hData)
145  return false;
146 
147  void *out = GlobalLock(hData);
148  memcpy(out, data.data(), data.size());
149  GlobalUnlock(hData);
150  pmedium->tymed = TYMED_HGLOBAL;
151  pmedium->hGlobal = hData;
152  pmedium->pUnkForRelease = 0;
153  return true;
154 }
155 
156 static QByteArray getData(int cf, IDataObject *pDataObj)
157 {
159  FORMATETC formatetc = setCf(cf);
160  STGMEDIUM s;
161  if (pDataObj->GetData(&formatetc, &s) == S_OK) {
162  DWORD * val = (DWORD*)GlobalLock(s.hGlobal);
163  data = QByteArray::fromRawData((char*)val, GlobalSize(s.hGlobal));
164  data.detach();
165  GlobalUnlock(s.hGlobal);
166  ReleaseStgMedium(&s);
167  } else {
168  //Try reading IStream data
169  formatetc.tymed = TYMED_ISTREAM;
170  if (pDataObj->GetData(&formatetc, &s) == S_OK) {
171  char szBuffer[4096];
172  ULONG actualRead = 0;
173  LARGE_INTEGER pos = {{0, 0}};
174  //Move to front (can fail depending on the data model implemented)
175  HRESULT hr = s.pstm->Seek(pos, STREAM_SEEK_SET, NULL);
176  while(SUCCEEDED(hr)){
177  hr = s.pstm->Read(szBuffer, sizeof(szBuffer), &actualRead);
178  if (SUCCEEDED(hr) && actualRead > 0) {
179  data += QByteArray::fromRawData(szBuffer, actualRead);
180  }
181  if (actualRead != sizeof(szBuffer))
182  break;
183  }
184  data.detach();
185  ReleaseStgMedium(&s);
186  }
187  }
188  return data;
189 }
190 
191 static bool canGetData(int cf, IDataObject * pDataObj)
192 {
193  FORMATETC formatetc = setCf(cf);
194  if (pDataObj->QueryGetData(&formatetc) != S_OK){
195  formatetc.tymed = TYMED_ISTREAM;
196  return pDataObj->QueryGetData(&formatetc) == S_OK;
197  }
198  return true;
199 }
200 
202 {
203 public:
205  ~QWindowsMimeList();
206  void addWindowsMime(QWindowsMime * mime);
207  void removeWindowsMime(QWindowsMime * mime);
208  QList<QWindowsMime*> windowsMimes();
209 
210 private:
211  void init();
214 };
215 
216 Q_GLOBAL_STATIC(QWindowsMimeList, theMimeList);
217 
218 
265 {
266  theMimeList()->addWindowsMime(this);
267 }
268 
274 {
275  theMimeList()->removeWindowsMime(this);
276 }
277 
278 
284 {
285  int f = RegisterClipboardFormat(reinterpret_cast<const wchar_t *> (mime.utf16()));
286  if (!f)
287  qErrnoWarning("QWindowsMime::registerMimeType: Failed to register clipboard format");
288 
289  return f;
290 }
291 
292 
356 {
357  QList<QWindowsMime*> mimes = theMimeList()->windowsMimes();
358  for (int i=mimes.size()-1; i>=0; --i) {
359  if (mimes.at(i)->canConvertFromMime(formatetc, mimeData))
360  return mimes.at(i);
361  }
362  return 0;
363 }
364 
365 QWindowsMime *QWindowsMime::converterToMime(const QString &mimeType, IDataObject *pDataObj)
366 {
367  QList<QWindowsMime*> mimes = theMimeList()->windowsMimes();
368  for (int i=mimes.size()-1; i>=0; --i) {
369  if (mimes.at(i)->canConvertToMime(mimeType, pDataObj))
370  return mimes.at(i);
371  }
372  return 0;
373 }
374 
376 {
377  QList<QWindowsMime*> mimes = theMimeList()->windowsMimes();
378  QVector<FORMATETC> formatics;
379  formatics.reserve(20);
380 #ifndef QT_NO_DRAGANDDROP
381  QStringList formats = QInternalMimeData::formatsHelper(mimeData);
382  for (int f=0; f<formats.size(); ++f) {
383  for (int i=mimes.size()-1; i>=0; --i)
384  formatics += mimes.at(i)->formatsForMime(formats.at(f), mimeData);
385  }
386 #else
387  Q_UNUSED(mimeData);
388 #endif //QT_NO_DRAGANDDROP
389  return formatics;
390 }
391 
393 {
394  QList<QWindowsMime*> mimes = theMimeList()->windowsMimes();
395  QStringList formats;
396  LPENUMFORMATETC FAR fmtenum;
397  HRESULT hr = pDataObj->EnumFormatEtc(DATADIR_GET, &fmtenum);
398 
399  if (hr == NOERROR) {
400  FORMATETC fmtetc;
401  while (S_OK == fmtenum->Next(1, &fmtetc, 0)) {
402 #if defined(QMIME_DEBUG) && !defined(Q_OS_WINCE)
403  qDebug("QWindowsMime::allMimesForFormats()");
404  wchar_t buf[256] = {0};
405  GetClipboardFormatName(fmtetc.cfFormat, buf, 255);
406  qDebug("CF = %d : %s", fmtetc.cfFormat, QString::fromWCharArray(buf));
407 #endif
408  for (int i=mimes.size()-1; i>=0; --i) {
409  QString format = mimes.at(i)->mimeForFormat(fmtetc);
410  if (!format.isEmpty() && !formats.contains(format)) {
411  formats += format;
412  }
413  }
414  // as documented in MSDN to avoid possible memleak
415  if (fmtetc.ptd)
416  CoTaskMemFree(fmtetc.ptd);
417  }
418  fmtenum->Release();
419  }
420 
421  return formats;
422 }
423 
424 
426 {
427 public:
428  bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const;
429  QVariant convertToMime(const QString &mime, LPDATAOBJECT pDataObj, QVariant::Type preferredType) const;
430  QString mimeForFormat(const FORMATETC &formatetc) const;
431  bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const;
432  bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM *pmedium) const;
433  QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const;
434 };
435 
436 bool QWindowsMimeText::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
437 {
438  int cf = getCf(formatetc);
439  return (cf == CF_UNICODETEXT || cf == CF_TEXT) && mimeData->hasText();
440 }
441 
442 /*
443 text/plain is defined as using CRLF, but so many programs don't,
444 and programmers just look for '\n' in strings.
445 Windows really needs CRLF, so we ensure it here.
446 */
447 bool QWindowsMimeText::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM *pmedium) const
448 {
449  if (canConvertFromMime(formatetc, mimeData)) {
451  int cf = getCf(formatetc);
452  if (cf == CF_TEXT) {
453  data = mimeData->text().toLocal8Bit();
454  // Anticipate required space for CRLFs at 1/40
455  int maxsize=data.size()+data.size()/40+3;
456  QByteArray r(maxsize, '\0');
457  char* o = r.data();
458  const char* d = data.data();
459  const int s = data.size();
460  bool cr=false;
461  int j=0;
462  for (int i=0; i<s; i++) {
463  char c = d[i];
464  if (c=='\r')
465  cr=true;
466  else {
467  if (c=='\n') {
468  if (!cr)
469  o[j++]='\r';
470  }
471  cr=false;
472  }
473  o[j++]=c;
474  if (j+3 >= maxsize) {
475  maxsize += maxsize/4;
476  r.resize(maxsize);
477  o = r.data();
478  }
479  }
480  o[j]=0;
481  return setData(r, pmedium);
482  } else if (cf == CF_UNICODETEXT) {
483  QString str = mimeData->text();
484  const QChar *u = str.unicode();
485  QString res;
486  const int s = str.length();
487  int maxsize = s + s/40 + 3;
488  res.resize(maxsize);
489  int ri = 0;
490  bool cr = false;
491  for (int i=0; i < s; ++i) {
492  if (*u == QLatin1Char('\r'))
493  cr = true;
494  else {
495  if (*u == QLatin1Char('\n') && !cr)
496  res[ri++] = QLatin1Char('\r');
497  cr = false;
498  }
499  res[ri++] = *u;
500  if (ri+3 >= maxsize) {
501  maxsize += maxsize/4;
502  res.resize(maxsize);
503  }
504  ++u;
505  }
506  res.truncate(ri);
507  const int byteLength = res.length() * sizeof(ushort);
508  QByteArray r(byteLength + 2, '\0');
509  memcpy(r.data(), res.unicode(), byteLength);
510  r[byteLength] = 0;
511  r[byteLength+1] = 0;
512  return setData(r, pmedium);
513  }
514  }
515  return false;
516 }
517 
518 bool QWindowsMimeText::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
519 {
520  return mimeType.startsWith(QLatin1String("text/plain"))
521  && (canGetData(CF_UNICODETEXT, pDataObj)
522  || canGetData(CF_TEXT, pDataObj));
523 }
524 
526 {
527  int cf = getCf(formatetc);
528  if (cf == CF_UNICODETEXT || cf == CF_TEXT)
529  return QLatin1String("text/plain");
530  return QString();
531 }
532 
533 
535 {
536  QVector<FORMATETC> formatics;
537  if (mimeType.startsWith(QLatin1String("text/plain")) && mimeData->hasText()) {
538  formatics += setCf(CF_UNICODETEXT);
539  formatics += setCf(CF_TEXT);
540  }
541  return formatics;
542 }
543 
544 QVariant QWindowsMimeText::convertToMime(const QString &mime, LPDATAOBJECT pDataObj, QVariant::Type preferredType) const
545 {
546  QVariant ret;
547 
548  if (canConvertToMime(mime, pDataObj)) {
549  QString str;
550  QByteArray data = getData(CF_UNICODETEXT, pDataObj);
551  if (!data.isEmpty()) {
552  str = QString::fromWCharArray((const wchar_t *)data.data());
553  str.replace(QLatin1String("\r\n"), QLatin1String("\n"));
554  } else {
555  data = getData(CF_TEXT, pDataObj);
556  if (!data.isEmpty()) {
557  const char* d = data.data();
558  const int s = qstrlen(d);
559  QByteArray r(data.size()+1, '\0');
560  char* o = r.data();
561  int j=0;
562  for (int i=0; i<s; i++) {
563  char c = d[i];
564  if (c!='\r')
565  o[j++]=c;
566  }
567  o[j]=0;
568  str = QString::fromLocal8Bit(r);
569  }
570  }
571  if (preferredType == QVariant::String)
572  ret = str;
573  else
574  ret = str.toUtf8();
575  }
576 
577  return ret;
578 }
579 
581 {
582 public:
583  QWindowsMimeURI();
584  bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const;
585  QVariant convertToMime(const QString &mime, LPDATAOBJECT pDataObj, QVariant::Type preferredType) const;
586  QString mimeForFormat(const FORMATETC &formatetc) const;
587  bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const;
588  bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM *pmedium) const;
589  QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const;
590 private:
591  int CF_INETURL_W; // wide char version
593 };
594 
596 {
597  CF_INETURL_W = QWindowsMime::registerMimeType(QLatin1String("UniformResourceLocatorW"));
598  CF_INETURL = QWindowsMime::registerMimeType(QLatin1String("UniformResourceLocator"));
599 }
600 
601 bool QWindowsMimeURI::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
602 {
603  if (getCf(formatetc) == CF_HDROP) {
604  QList<QUrl> urls = mimeData->urls();
605  for (int i=0; i<urls.size(); i++) {
606  if (!urls.at(i).toLocalFile().isEmpty())
607  return true;
608  }
609  }
610  return (getCf(formatetc) == CF_INETURL_W || getCf(formatetc) == CF_INETURL) && mimeData->hasFormat(QLatin1String("text/uri-list"));
611 }
612 
613 bool QWindowsMimeURI::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM *pmedium) const
614 {
615  if (canConvertFromMime(formatetc, mimeData)) {
616  if (getCf(formatetc) == CF_HDROP) {
617  QList<QUrl> urls = mimeData->urls();
618  QStringList fileNames;
619  int size = sizeof(DROPFILES)+2;
620  for (int i=0; i<urls.size(); i++) {
622  if (!fn.isEmpty()) {
623  size += sizeof(ushort) * (fn.length() + 1);
624  fileNames.append(fn);
625  }
626  }
627 
628  QByteArray result(size, '\0');
629  DROPFILES* d = (DROPFILES*)result.data();
630  d->pFiles = sizeof(DROPFILES);
631  GetCursorPos(&d->pt); // try
632  d->fNC = true;
633  char* files = ((char*)d) + d->pFiles;
634 
635  d->fWide = true;
636  wchar_t* f = (wchar_t*)files;
637  for (int i=0; i<fileNames.size(); i++) {
638  int l = fileNames.at(i).length();
639  memcpy(f, fileNames.at(i).utf16(), l * sizeof(ushort));
640  f += l;
641  *f++ = 0;
642  }
643  *f = 0;
644 
645  return setData(result, pmedium);
646  } else if (getCf(formatetc) == CF_INETURL_W) {
647  QList<QUrl> urls = mimeData->urls();
648  QByteArray result;
649  if (!urls.isEmpty()) {
650  QString url = urls.at(0).toString();
651  result = QByteArray((const char *)url.utf16(), url.length() * sizeof(ushort));
652  }
653  result.append('\0');
654  result.append('\0');
655  return setData(result, pmedium);
656  } else if (getCf(formatetc) == CF_INETURL) {
657  QList<QUrl> urls = mimeData->urls();
658  QByteArray result;
659  if (!urls.isEmpty())
660  result = urls.at(0).toString().toLocal8Bit();
661  return setData(result, pmedium);
662  }
663  }
664 
665  return false;
666 }
667 
668 bool QWindowsMimeURI::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
669 {
670  return mimeType == QLatin1String("text/uri-list")
671  && (canGetData(CF_HDROP, pDataObj) || canGetData(CF_INETURL_W, pDataObj) || canGetData(CF_INETURL, pDataObj));
672 }
673 
675 {
676  QString format;
677  if (getCf(formatetc) == CF_HDROP || getCf(formatetc) == CF_INETURL_W || getCf(formatetc) == CF_INETURL)
678  format = QLatin1String("text/uri-list");
679  return format;
680 }
681 
683 {
684  QVector<FORMATETC> formatics;
685  if (mimeType == QLatin1String("text/uri-list")) {
686  if (canConvertFromMime(setCf(CF_HDROP), mimeData))
687  formatics += setCf(CF_HDROP);
688  if (canConvertFromMime(setCf(CF_INETURL_W), mimeData))
689  formatics += setCf(CF_INETURL_W);
690  if (canConvertFromMime(setCf(CF_INETURL), mimeData))
691  formatics += setCf(CF_INETURL);
692  }
693  return formatics;
694 }
695 
696 QVariant QWindowsMimeURI::convertToMime(const QString &mimeType, LPDATAOBJECT pDataObj, QVariant::Type preferredType) const
697 {
698  if (mimeType == QLatin1String("text/uri-list")) {
699  if (canGetData(CF_HDROP, pDataObj)) {
700  QByteArray texturi;
701  QList<QVariant> urls;
702 
703  QByteArray data = getData(CF_HDROP, pDataObj);
704  if (data.isEmpty())
705  return QVariant();
706 
707  LPDROPFILES hdrop = (LPDROPFILES)data.data();
708  if (hdrop->fWide) {
709  const wchar_t* filesw = (const wchar_t *)(data.data() + hdrop->pFiles);
710  int i = 0;
711  while (filesw[i]) {
712  QString fileurl = QString::fromWCharArray(filesw + i);
713  urls += QUrl::fromLocalFile(fileurl);
714  i += fileurl.length()+1;
715  }
716  } else {
717  const char* files = (const char *)data.data() + hdrop->pFiles;
718  int i=0;
719  while (files[i]) {
721  i += int(strlen(files+i))+1;
722  }
723  }
724 
725  if (preferredType == QVariant::Url && urls.size() == 1)
726  return urls.at(0);
727  else if (!urls.isEmpty())
728  return urls;
729  } else if (canGetData(CF_INETURL_W, pDataObj)) {
730  QByteArray data = getData(CF_INETURL_W, pDataObj);
731  if (data.isEmpty())
732  return QVariant();
733  return QUrl(QString::fromWCharArray((const wchar_t *)data.constData()));
734  } else if (canGetData(CF_INETURL, pDataObj)) {
735  QByteArray data = getData(CF_INETURL, pDataObj);
736  if (data.isEmpty())
737  return QVariant();
738  return QUrl(QString::fromLocal8Bit(data.constData()));
739  }
740  }
741  return QVariant();
742 }
743 
745 {
746 public:
748 
749  // for converting from Qt
750  bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const;
751  bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const;
752  QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const;
753 
754  // for converting to Qt
755  bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const;
756  QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const;
757  QString mimeForFormat(const FORMATETC &formatetc) const;
758 
759 private:
760  int CF_HTML;
761 };
762 
764 {
765  CF_HTML = QWindowsMime::registerMimeType(QLatin1String("HTML Format"));
766 }
767 
769 {
770  QVector<FORMATETC> formatetcs;
771  if (mimeType == QLatin1String("text/html") && (!mimeData->html().isEmpty()))
772  formatetcs += setCf(CF_HTML);
773  return formatetcs;
774 }
775 
777 {
778  if (getCf(formatetc) == CF_HTML)
779  return QLatin1String("text/html");
780  return QString();
781 }
782 
783 bool QWindowsMimeHtml::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
784 {
785  return mimeType == QLatin1String("text/html") && canGetData(CF_HTML, pDataObj);
786 }
787 
788 
789 bool QWindowsMimeHtml::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
790 {
791  return getCf(formatetc) == CF_HTML && (!mimeData->html().isEmpty());
792 }
793 
794 /*
795 The windows HTML clipboard format is as follows (xxxxxxxxxx is a 10 integer number giving the positions
796 in bytes). Charset used is mostly utf8, but can be different, ie. we have to look for the <meta> charset tag
797 
798  Version: 1.0
799  StartHTML:xxxxxxxxxx
800  EndHTML:xxxxxxxxxx
801  StartFragment:xxxxxxxxxx
802  EndFragment:xxxxxxxxxx
803  ...html...
804 
805 */
806 QVariant QWindowsMimeHtml::convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const
807 {
808  Q_UNUSED(preferredType);
809  QVariant result;
810  if (canConvertToMime(mime, pDataObj)) {
811  QByteArray html = getData(CF_HTML, pDataObj);
812 #ifdef QMIME_DEBUG
813  qDebug("QWindowsMimeHtml::convertToMime");
814  qDebug("raw :");
815  qDebug(html);
816 #endif
817  int start = html.indexOf("StartFragment:");
818  int end = html.indexOf("EndFragment:");
819 
820  if (start != -1) {
821  int startOffset = start + 14;
822  int i = startOffset;
823  while (html.at(i) != '\r' && html.at(i) != '\n')
824  ++i;
825  QByteArray bytecount = html.mid(startOffset, i - startOffset);
826  start = bytecount.toInt();
827  }
828 
829  if (end != -1) {
830  int endOffset = end + 12;
831  int i = endOffset ;
832  while (html.at(i) != '\r' && html.at(i) != '\n')
833  ++i;
834  QByteArray bytecount = html.mid(endOffset , i - endOffset);
835  end = bytecount.toInt();
836  }
837 
838  if (end > start && start > 0) {
839  html = "<!--StartFragment-->" + html.mid(start, end - start);
840  html += "<!--EndFragment-->";
841  html.replace('\r', "");
842  result = QString::fromUtf8(html);
843  }
844  }
845  return result;
846 }
847 
848 bool QWindowsMimeHtml::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const
849 {
850  if (canConvertFromMime(formatetc, mimeData)) {
851  QByteArray data = mimeData->html().toUtf8();
852  QByteArray result =
853  "Version:1.0\r\n" // 0-12
854  "StartHTML:0000000105\r\n" // 13-35
855  "EndHTML:0000000000\r\n" // 36-55
856  "StartFragment:0000000000\r\n" // 58-86
857  "EndFragment:0000000000\r\n\r\n"; // 87-105
858 
859  if (data.indexOf("<!--StartFragment-->") == -1)
860  result += "<!--StartFragment-->";
861  result += data;
862  if (data.indexOf("<!--EndFragment-->") == -1)
863  result += "<!--EndFragment-->";
864 
865  // set the correct number for EndHTML
866  QByteArray pos = QString::number(result.size()).toLatin1();
867  memcpy((char *)(result.data() + 53 - pos.length()), pos.constData(), pos.length());
868 
869  // set correct numbers for StartFragment and EndFragment
870  pos = QString::number(result.indexOf("<!--StartFragment-->") + 20).toLatin1();
871  memcpy((char *)(result.data() + 79 - pos.length()), pos.constData(), pos.length());
872  pos = QString::number(result.indexOf("<!--EndFragment-->")).toLatin1();
873  memcpy((char *)(result.data() + 103 - pos.length()), pos.constData(), pos.length());
874 
875  return setData(result, pmedium);
876  }
877  return false;
878 }
879 
880 
881 #ifndef QT_NO_IMAGEFORMAT_BMP
883 {
884 public:
886  // for converting from Qt
887  bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const;
888  bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const;
889  QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const;
890 
891  // for converting to Qt
892  bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const;
893  QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const;
894  QString mimeForFormat(const FORMATETC &formatetc) const;
895 private:
896  bool hasOriginalDIBV5(IDataObject *pDataObj) const;
897  UINT CF_PNG;
898 };
899 
901 {
902  CF_PNG = RegisterClipboardFormat(L"PNG");
903 }
904 
906 {
907  QVector<FORMATETC> formatetcs;
908  if (mimeData->hasImage() && mimeType == QLatin1String("application/x-qt-image")) {
909  //add DIBV5 if image has alpha channel
910  QImage image = qvariant_cast<QImage>(mimeData->imageData());
911  if (!image.isNull() && image.hasAlphaChannel())
912  formatetcs += setCf(CF_DIBV5);
913  formatetcs += setCf(CF_DIB);
914  }
915  return formatetcs;
916 }
917 
919 {
920  int cf = getCf(formatetc);
921  if (cf == CF_DIB || cf == CF_DIBV5 || cf == int(CF_PNG))
922  return QLatin1String("application/x-qt-image");
923  return QString();
924 }
925 
926 bool QWindowsMimeImage::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
927 {
928  if ((mimeType == QLatin1String("application/x-qt-image")) &&
929  (canGetData(CF_DIB, pDataObj) || canGetData(CF_PNG, pDataObj)))
930  return true;
931  return false;
932 }
933 
934 bool QWindowsMimeImage::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
935 {
936  int cf = getCf(formatetc);
937  if (mimeData->hasImage()) {
938  if (cf == CF_DIB)
939  return true;
940  else if (cf == CF_DIBV5) {
941  //support DIBV5 conversion only if the image has alpha channel
942  QImage image = qvariant_cast<QImage>(mimeData->imageData());
943  if (!image.isNull() && image.hasAlphaChannel())
944  return true;
945  }
946  }
947  return false;
948 }
949 
950 bool QWindowsMimeImage::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const
951 {
952  int cf = getCf(formatetc);
953  if ((cf == CF_DIB || cf == CF_DIBV5) && mimeData->hasImage()) {
954  QImage img = qvariant_cast<QImage>(mimeData->imageData());
955  if (img.isNull())
956  return false;
957  QByteArray ba;
959  s.setByteOrder(QDataStream::LittleEndian);// Intel byte order ####
960  if (cf == CF_DIB) {
961  if (img.format() > QImage::Format_ARGB32)
963  if (qt_write_dib(s, img))
964  return setData(ba, pmedium);
965  } else {
966  if (qt_write_dibv5(s, img))
967  return setData(ba, pmedium);
968  }
969  }
970  return false;
971 }
972 
973 bool QWindowsMimeImage::hasOriginalDIBV5(IDataObject *pDataObj) const
974 {
975  bool isSynthesized = true;
976  IEnumFORMATETC *pEnum =NULL;
977  HRESULT res = pDataObj->EnumFormatEtc(1, &pEnum);
978  if (res == S_OK && pEnum) {
979  FORMATETC fc;
980  while ((res = pEnum->Next(1, &fc, 0)) == S_OK) {
981  if (fc.ptd)
982  CoTaskMemFree(fc.ptd);
983  if (fc.cfFormat == CF_DIB)
984  break;
985  else if (fc.cfFormat == CF_DIBV5) {
986  isSynthesized = false;
987  break;
988  }
989  }
990  pEnum->Release();
991  }
992  return !isSynthesized;
993 }
994 
995 QVariant QWindowsMimeImage::convertToMime(const QString &mimeType, IDataObject *pDataObj, QVariant::Type preferredType) const
996 {
997  Q_UNUSED(preferredType);
998  QVariant result;
999  if (mimeType != QLatin1String("application/x-qt-image"))
1000  return result;
1001  //Try to convert from a format which has more data
1002  //DIBV5, use only if its is not synthesized
1003  if (canGetData(CF_DIBV5, pDataObj) && hasOriginalDIBV5(pDataObj)) {
1004  QImage img;
1005  QByteArray data = getData(CF_DIBV5, pDataObj);
1006  QDataStream s(&data, QIODevice::ReadOnly);
1008  if (qt_read_dibv5(s, img)) { // #### supports only 32bit DIBV5
1009  return img;
1010  }
1011  }
1012  //PNG, MS Office place this (undocumented)
1013  if (canGetData(CF_PNG, pDataObj)) {
1014  QImage img;
1015  QByteArray data = getData(CF_PNG, pDataObj);
1016  if (img.loadFromData(data, "PNG")) {
1017  return img;
1018  }
1019  }
1020  //Fallback to DIB
1021  if (canGetData(CF_DIB, pDataObj)) {
1022  QImage img;
1023  QByteArray data = getData(CF_DIB, pDataObj);
1024  QDataStream s(&data, QIODevice::ReadOnly);
1025  s.setByteOrder(QDataStream::LittleEndian);// Intel byte order ####
1026  if (qt_read_dib(s, img)) { // ##### encaps "-14"
1027  return img;
1028  }
1029  }
1030  // Failed
1031  return result;
1032 }
1033 #endif
1034 
1036 {
1037 public:
1038  QBuiltInMimes();
1039 
1040  // for converting from Qt
1041  bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const;
1042  bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const;
1043  QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const;
1044 
1045  // for converting to Qt
1046  bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const;
1047  QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const;
1048  QString mimeForFormat(const FORMATETC &formatetc) const;
1049 
1050 private:
1053 };
1054 
1056 : QWindowsMime()
1057 {
1058  outFormats.insert(QWindowsMime::registerMimeType(QLatin1String("application/x-color")), QLatin1String("application/x-color"));
1059  inFormats.insert(QWindowsMime::registerMimeType(QLatin1String("application/x-color")), QLatin1String("application/x-color"));
1060 }
1061 
1062 bool QBuiltInMimes::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
1063 {
1064  // really check
1065  return formatetc.tymed & TYMED_HGLOBAL
1066  && outFormats.contains(formatetc.cfFormat)
1067  && mimeData->formats().contains(outFormats.value(formatetc.cfFormat));
1068 }
1069 
1070 bool QBuiltInMimes::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const
1071 {
1072  if (canConvertFromMime(formatetc, mimeData)) {
1073  QByteArray data;
1074  if (outFormats.value(getCf(formatetc)) == QLatin1String("text/html")) {
1075  // text/html is in wide chars on windows (compatible with mozillia)
1076  QString html = mimeData->html();
1077  // same code as in the text converter up above
1078  const QChar *u = html.unicode();
1079  QString res;
1080  const int s = html.length();
1081  int maxsize = s + s/40 + 3;
1082  res.resize(maxsize);
1083  int ri = 0;
1084  bool cr = false;
1085  for (int i=0; i < s; ++i) {
1086  if (*u == QLatin1Char('\r'))
1087  cr = true;
1088  else {
1089  if (*u == QLatin1Char('\n') && !cr)
1090  res[ri++] = QLatin1Char('\r');
1091  cr = false;
1092  }
1093  res[ri++] = *u;
1094  if (ri+3 >= maxsize) {
1095  maxsize += maxsize/4;
1096  res.resize(maxsize);
1097  }
1098  ++u;
1099  }
1100  res.truncate(ri);
1101  const int byteLength = res.length() * sizeof(ushort);
1102  QByteArray r(byteLength + 2, '\0');
1103  memcpy(r.data(), res.unicode(), byteLength);
1104  r[byteLength] = 0;
1105  r[byteLength+1] = 0;
1106  data = r;
1107  } else {
1108 #ifndef QT_NO_DRAGANDDROP
1109  data = QInternalMimeData::renderDataHelper(outFormats.value(getCf(formatetc)), mimeData);
1110 #endif //QT_NO_DRAGANDDROP
1111  }
1112  return setData(data, pmedium);
1113  }
1114  return false;
1115 }
1116 
1118 {
1119  QVector<FORMATETC> formatetcs;
1120  if (!outFormats.keys(mimeType).isEmpty() && mimeData->formats().contains(mimeType))
1121  formatetcs += setCf(outFormats.key(mimeType));
1122  return formatetcs;
1123 }
1124 
1125 bool QBuiltInMimes::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
1126 {
1127  return (!inFormats.keys(mimeType).isEmpty())
1128  && canGetData(inFormats.key(mimeType), pDataObj);
1129 }
1130 
1131 QVariant QBuiltInMimes::convertToMime(const QString &mimeType, IDataObject *pDataObj, QVariant::Type preferredType) const
1132 {
1133  QVariant val;
1134  if (canConvertToMime(mimeType, pDataObj)) {
1135  QByteArray data = getData(inFormats.key(mimeType), pDataObj);
1136  if (!data.isEmpty()) {
1137 #ifdef QMIME_DEBUG
1138  qDebug("QBuiltInMimes::convertToMime()");
1139 #endif
1140  if (mimeType == QLatin1String("text/html") && preferredType == QVariant::String) {
1141  // text/html is in wide chars on windows (compatible with Mozilla)
1142  val = QString::fromWCharArray((const wchar_t *)data.data());
1143  } else {
1144  val = data; // it should be enough to return the data and let QMimeData do the rest.
1145  }
1146  }
1147  }
1148  return val;
1149 }
1150 
1152 {
1153  return inFormats.value(getCf(formatetc));
1154 }
1155 
1156 
1158 {
1159 public:
1160 
1161  QLastResortMimes();
1162  // for converting from Qt
1163  bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const;
1164  bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const;
1165  QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const;
1166 
1167  // for converting to Qt
1168  bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const;
1169  QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const;
1170  QString mimeForFormat(const FORMATETC &formatetc) const;
1171 
1172 private:
1176 };
1177 
1180 
1182 {
1183  //MIME Media-Types
1184  if (!ianaTypes.size()) {
1185  ianaTypes.append(QLatin1String("application/"));
1186  ianaTypes.append(QLatin1String("audio/"));
1187  ianaTypes.append(QLatin1String("example/"));
1188  ianaTypes.append(QLatin1String("image/"));
1189  ianaTypes.append(QLatin1String("message/"));
1190  ianaTypes.append(QLatin1String("model/"));
1191  ianaTypes.append(QLatin1String("multipart/"));
1192  ianaTypes.append(QLatin1String("text/"));
1193  ianaTypes.append(QLatin1String("video/"));
1194  }
1195  //Types handled by other classes
1196  if (!excludeList.size()) {
1197  excludeList.append(QLatin1String("HTML Format"));
1198  excludeList.append(QLatin1String("UniformResourceLocator"));
1199  excludeList.append(QLatin1String("text/html"));
1200  excludeList.append(QLatin1String("text/plain"));
1201  excludeList.append(QLatin1String("text/uri-list"));
1202  excludeList.append(QLatin1String("application/x-qt-image"));
1203  excludeList.append(QLatin1String("application/x-color"));
1204  }
1205 }
1206 
1207 bool QLastResortMimes::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
1208 {
1209  // really check
1210 #ifndef QT_NO_DRAGANDDROP
1211  return formatetc.tymed & TYMED_HGLOBAL
1212  && (formats.contains(formatetc.cfFormat)
1213  && QInternalMimeData::hasFormatHelper(formats.value(formatetc.cfFormat), mimeData));
1214 #else
1215  Q_UNUSED(mimeData);
1216  Q_UNUSED(formatetc);
1217  return formatetc.tymed & TYMED_HGLOBAL
1218  && formats.contains(formatetc.cfFormat);
1219 #endif //QT_NO_DRAGANDDROP
1220 }
1221 
1222 bool QLastResortMimes::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const
1223 {
1224 #ifndef QT_NO_DRAGANDDROP
1225  return canConvertFromMime(formatetc, mimeData)
1226  && setData(QInternalMimeData::renderDataHelper(formats.value(getCf(formatetc)), mimeData), pmedium);
1227 #else
1228  Q_UNUSED(mimeData);
1229  Q_UNUSED(formatetc);
1230  Q_UNUSED(pmedium);
1231  return false;
1232 #endif //QT_NO_DRAGANDDROP
1233 }
1234 
1235 QVector<FORMATETC> QLastResortMimes::formatsForMime(const QString &mimeType, const QMimeData * /*mimeData*/) const
1236 {
1237  QVector<FORMATETC> formatetcs;
1238  if (!formats.keys(mimeType).isEmpty()) {
1239  formatetcs += setCf(formats.key(mimeType));
1240  } else if (!excludeList.contains(mimeType, Qt::CaseInsensitive)){
1241  // register any other available formats
1242  int cf = QWindowsMime::registerMimeType(mimeType);
1243  QLastResortMimes *that = const_cast<QLastResortMimes *>(this);
1244  that->formats.insert(cf, mimeType);
1245  formatetcs += setCf(cf);
1246  }
1247  return formatetcs;
1248 }
1249 static const char x_qt_windows_mime[] = "application/x-qt-windows-mime;value=\"";
1250 
1251 static bool isCustomMimeType(const QString &mimeType)
1252 {
1254 }
1255 
1256 static QString customMimeType(const QString &mimeType)
1257 {
1258  int len = sizeof(x_qt_windows_mime) - 1;
1259  int n = mimeType.lastIndexOf(QLatin1Char('\"'))-len;
1260  return mimeType.mid(len, n);
1261 }
1262 
1263 bool QLastResortMimes::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
1264 {
1265  if (isCustomMimeType(mimeType)) {
1266  QString clipFormat = customMimeType(mimeType);
1267  int cf = RegisterClipboardFormat(reinterpret_cast<const wchar_t *> (clipFormat.utf16()));
1268  return canGetData(cf, pDataObj);
1269  } else if (formats.keys(mimeType).isEmpty()) {
1270  // if it is not in there then register it an see if we can get it
1271  int cf = QWindowsMime::registerMimeType(mimeType);
1272  return canGetData(cf, pDataObj);
1273  } else {
1274  return canGetData(formats.key(mimeType), pDataObj);
1275  }
1276  return false;
1277 }
1278 
1279 QVariant QLastResortMimes::convertToMime(const QString &mimeType, IDataObject *pDataObj, QVariant::Type preferredType) const
1280 {
1281  Q_UNUSED(preferredType);
1282  QVariant val;
1283  if (canConvertToMime(mimeType, pDataObj)) {
1284  QByteArray data;
1285  if (isCustomMimeType(mimeType)) {
1286  QString clipFormat = customMimeType(mimeType);
1287  int cf = RegisterClipboardFormat(reinterpret_cast<const wchar_t *> (clipFormat.utf16()));
1288  data = getData(cf, pDataObj);
1289  } else if (formats.keys(mimeType).isEmpty()) {
1290  int cf = QWindowsMime::registerMimeType(mimeType);
1291  data = getData(cf, pDataObj);
1292  } else {
1293  data = getData(formats.key(mimeType), pDataObj);
1294  }
1295  if (!data.isEmpty())
1296  val = data; // it should be enough to return the data and let QMimeData do the rest.
1297  }
1298  return val;
1299 }
1300 
1302 {
1303  QString format = formats.value(getCf(formatetc));
1304  if (!format.isEmpty())
1305  return format;
1306 
1307  wchar_t buffer[256];
1308  int len = GetClipboardFormatName(getCf(formatetc), buffer, 256);
1309 
1310  if (len) {
1311  QString clipFormat = QString::fromWCharArray(buffer, len);
1312 #ifndef QT_NO_DRAGANDDROP
1313  if (QInternalMimeData::canReadData(clipFormat))
1314  format = clipFormat;
1315  else if((formatetc.cfFormat >= 0xC000)){
1316  //create the mime as custom. not registered.
1317  if (!excludeList.contains(clipFormat, Qt::CaseInsensitive)) {
1318  //check if this is a mime type
1319  bool ianaType = false;
1320  int sz = ianaTypes.size();
1321  for (int i = 0; i < sz; i++) {
1322  if (clipFormat.startsWith(ianaTypes[i], Qt::CaseInsensitive)) {
1323  ianaType = true;
1324  break;
1325  }
1326  }
1327  if (!ianaType)
1328  format = QLatin1String(x_qt_windows_mime) + clipFormat + QLatin1Char('\"');
1329  else
1330  format = clipFormat;
1331  }
1332  }
1333 #endif //QT_NO_DRAGANDDROP
1334  }
1335 
1336  return format;
1337 }
1338 
1340  : initialized(false)
1341 {
1342 }
1343 
1345 {
1346  while (mimes.size())
1347  delete mimes.first();
1348 }
1349 
1350 
1352 {
1353  if (!initialized) {
1354  initialized = true;
1355 #ifndef QT_NO_IMAGEFORMAT_BMP
1356  new QWindowsMimeImage;
1357 #endif
1358  new QLastResortMimes;
1359  new QWindowsMimeText;
1360  new QWindowsMimeURI;
1361 
1362  new QWindowsMimeHtml;
1363  new QBuiltInMimes;
1364  }
1365 }
1366 
1368 {
1369  init();
1370  mimes.append(mime);
1371 }
1372 
1374 {
1375  init();
1376  mimes.removeAll(mime);
1377 }
1378 
1380 {
1381  init();
1382  return mimes;
1383 }
1384 
1385 #ifndef QT_NO_IMAGEFORMAT_BMP
1386 static bool qt_write_dibv5(QDataStream &s, QImage image)
1387 {
1388  QIODevice* d = s.device();
1389  if (!d->isWritable())
1390  return false;
1391 
1392  //depth will be always 32
1393  int bpl_bmp = image.width()*4;
1394 
1395  BMP_BITMAPV5HEADER bi ={0};
1396  bi.bV5Size = sizeof(BMP_BITMAPV5HEADER);
1397  bi.bV5Width = image.width();
1398  bi.bV5Height = image.height();
1399  bi.bV5Planes = 1;
1400  bi.bV5BitCount = 32;
1401  bi.bV5Compression = BI_BITFIELDS;
1402  bi.bV5SizeImage = bpl_bmp*image.height();
1403  bi.bV5XPelsPerMeter = 0;
1404  bi.bV5YPelsPerMeter = 0;
1405  bi.bV5ClrUsed = 0;
1406  bi.bV5ClrImportant = 0;
1407  bi.bV5BlueMask = 0x000000ff;
1408  bi.bV5GreenMask = 0x0000ff00;
1409  bi.bV5RedMask = 0x00ff0000;
1410  bi.bV5AlphaMask = 0xff000000;
1411  bi.bV5CSType = BMP_LCS_sRGB; //LCS_sRGB
1412  bi.bV5Intent = BMP_LCS_GM_IMAGES; //LCS_GM_IMAGES
1413 
1414  d->write(reinterpret_cast<const char*>(&bi), bi.bV5Size);
1415  if (s.status() != QDataStream::Ok)
1416  return false;
1417 
1418  DWORD colorSpace[3] = {0x00ff0000,0x0000ff00,0x000000ff};
1419  d->write(reinterpret_cast<const char*>(colorSpace), sizeof(colorSpace));
1420  if (s.status() != QDataStream::Ok)
1421  return false;
1422 
1423  if (image.format() != QImage::Format_ARGB32)
1424  image = image.convertToFormat(QImage::Format_ARGB32);
1425 
1426  uchar *buf = new uchar[bpl_bmp];
1427  uchar *b;
1428 
1429  memset(buf, 0, bpl_bmp);
1430  for (int y=image.height()-1; y>=0; y--) {
1431  // write the image bits
1432  QRgb *p = (QRgb *)image.scanLine(y);
1433  QRgb *end = p + image.width();
1434  b = buf;
1435  while (p < end) {
1436  int alpha = qAlpha(*p);
1437  if (alpha) {
1438  *b++ = qBlue(*p);
1439  *b++ = qGreen(*p);
1440  *b++ = qRed(*p);
1441  } else {
1442  //white for fully transparent pixels.
1443  *b++ = 0xff;
1444  *b++ = 0xff;
1445  *b++ = 0xff;
1446  }
1447  *b++ = alpha;
1448  p++;
1449  }
1450  d->write((char*)buf, bpl_bmp);
1451  if (s.status() != QDataStream::Ok) {
1452  delete[] buf;
1453  return false;
1454  }
1455  }
1456  delete[] buf;
1457  return true;
1458 }
1459 
1460 static int calc_shift(int mask)
1461 {
1462  int result = 0;
1463  while (!(mask & 1)) {
1464  result++;
1465  mask >>= 1;
1466  }
1467  return result;
1468 }
1469 
1470 //Supports only 32 bit DIBV5
1471 static bool qt_read_dibv5(QDataStream &s, QImage &image)
1472 {
1473  BMP_BITMAPV5HEADER bi;
1474  QIODevice* d = s.device();
1475  if (d->atEnd())
1476  return false;
1477 
1478  d->read((char *)&bi, sizeof(bi)); // read BITMAPV5HEADER header
1479  if (s.status() != QDataStream::Ok)
1480  return false;
1481 
1482  int nbits = bi.bV5BitCount;
1483  int comp = bi.bV5Compression;
1484  if (nbits != 32 || bi.bV5Planes != 1 || comp != BMP_BITFIELDS)
1485  return false; //Unsupported DIBV5 format
1486 
1487  int w = bi.bV5Width, h = bi.bV5Height;
1488  int red_mask = bi.bV5RedMask;
1489  int green_mask = bi.bV5GreenMask;
1490  int blue_mask = bi.bV5BlueMask;
1491  int alpha_mask = bi.bV5AlphaMask;
1492  int red_shift = 0;
1493  int green_shift = 0;
1494  int blue_shift = 0;
1495  int alpha_shift = 0;
1497 
1498  if (bi.bV5Height < 0)
1499  h = -h; // support images with negative height
1500  if (image.size() != QSize(w, h) || image.format() != format) {
1501  image = QImage(w, h, format);
1502  if (image.isNull()) // could not create image
1503  return false;
1504  }
1505  image.setDotsPerMeterX(bi.bV5XPelsPerMeter);
1506  image.setDotsPerMeterY(bi.bV5YPelsPerMeter);
1507  // read color table
1508  DWORD colorSpace[3];
1509  if (d->read((char *)colorSpace, sizeof(colorSpace)) != sizeof(colorSpace))
1510  return false;
1511 
1512  red_shift = calc_shift(red_mask);
1513  green_shift = calc_shift(green_mask);
1514  blue_shift = calc_shift(blue_mask);
1515  if (alpha_mask) {
1516  alpha_shift = calc_shift(alpha_mask);
1517  }
1518 
1519  int bpl = image.bytesPerLine();
1520  uchar *data = image.bits();
1521  register QRgb *p;
1522  QRgb *end;
1523  uchar *buf24 = new uchar[bpl];
1524  int bpl24 = ((w*nbits+31)/32)*4;
1525  uchar *b;
1526  unsigned int c;
1527 
1528  while (--h >= 0) {
1529  p = (QRgb *)(data + h*bpl);
1530  end = p + w;
1531  if (d->read((char *)buf24,bpl24) != bpl24)
1532  break;
1533  b = buf24;
1534  while (p < end) {
1535  c = *b | (*(b+1))<<8 | (*(b+2))<<16 | (*(b+3))<<24;
1536  *p++ = qRgba(((c & red_mask) >> red_shift) ,
1537  ((c & green_mask) >> green_shift),
1538  ((c & blue_mask) >> blue_shift),
1539  ((c & alpha_mask) >> alpha_shift));
1540  b += 4;
1541  }
1542  }
1543  delete[] buf24;
1544 
1545  if (bi.bV5Height < 0) {
1546  // Flip the image
1547  uchar *buf = new uchar[bpl];
1548  h = -bi.bV5Height;
1549  for (int y = 0; y < h/2; ++y) {
1550  memcpy(buf, data + y*bpl, bpl);
1551  memcpy(data + y*bpl, data + (h-y-1)*bpl, bpl);
1552  memcpy(data + (h-y-1)*bpl, buf, bpl);
1553  }
1554  delete [] buf;
1555  }
1556 
1557  return true;
1558 }
1559 
1560 #endif
1561 
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qstring.cpp:6448
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
static QString fromWCharArray(const wchar_t *, int size=-1)
Returns a copy of the string, where the encoding of string depends on the size of wchar...
Definition: qstring.cpp:1019
The QWindowsMime class maps open-standard MIME to Window Clipboard formats.
Definition: qmime.h:79
double d
Definition: qnumeric_p.h:62
Status status() const
Returns the status of the data stream.
bool qt_write_dib(QDataStream &, QImage)
static QString customMimeType(const QString &mimeType)
Definition: qmime_win.cpp:1256
bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
Returns true if the converter can convert from the mimeData to the format specified in formatetc...
Definition: qmime_win.cpp:1062
Format
The following image formats are available in Qt.
Definition: qimage.h:91
unsigned int QRgb
Definition: qrgb.h:53
virtual ~QWindowsMime()
Destroys a conversion object, removing it from the global list of available converters.
Definition: qmime_win.cpp:273
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
unsigned char c[8]
Definition: qnumeric_p.h:62
static int getCf(const FORMATETC &formatetc)
Definition: qmime_win.cpp:125
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
virtual QStringList formats() const
Returns a list of formats supported by the object.
Definition: qmimedata.cpp:579
const Key key(const T &value) const
Returns the first key with value value.
Definition: qmap.h:844
char * data()
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:429
QVector< FORMATETC > formatsForMime(const QString &mimeType, const QMimeData *mimeData) const
Returns a QVector of FORMATETC structures representing the different windows clipboard formats that c...
Definition: qmime_win.cpp:534
bool isWritable() const
Returns true if data can be written to the device; otherwise returns false.
Definition: qiodevice.cpp:558
QString toString(FormattingOptions options=None) const
Returns the human-displayable string representation of the URL.
Definition: qurl.cpp:5896
static QStringList excludeList
Definition: qmime_win.cpp:1175
Q_GUI_EXPORT_INLINE int qAlpha(QRgb rgb)
Definition: qrgb.h:66
QByteArray & append(char c)
Appends the character ch to this byte array.
static QStringList allMimesForFormats(IDataObject *pDataObj)
Definition: qmime_win.cpp:392
static bool qt_write_dibv5(QDataStream &s, QImage image)
Definition: qmime_win.cpp:1386
QMap< int, QString > inFormats
Definition: qmime_win.cpp:1052
QByteArray toUtf8() const Q_REQUIRED_RESULT
Returns a UTF-8 representation of the string as a QByteArray.
Definition: qstring.cpp:4074
_CIEXYZ ciexyzRed
Definition: qmime_win.cpp:83
bool isNull() const
Returns true if it is a null image, otherwise returns false.
Definition: qimage.cpp:1542
QString & replace(int i, int len, QChar after)
Definition: qstring.cpp:2005
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
static QStringList ianaTypes
Definition: qmime_win.cpp:1174
static QStringList formatsHelper(const QMimeData *data)
Definition: qdnd.cpp:414
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
#define BMP_LCS_GM_IMAGES
Definition: qmime_win.cpp:76
const char * mime
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 isCustomMimeType(const QString &mimeType)
Definition: qmime_win.cpp:1251
bool hasAlphaChannel() const
Returns true if the image has a format that respects the alpha channel, otherwise returns false...
Definition: qimage.cpp:6495
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
int bytesPerLine() const
Returns the number of bytes per image scanline.
Definition: qimage.cpp:1812
quint16 u
struct tagFORMATETC FORMATETC
Definition: qmime.h:66
bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
Returns true if the converter can convert to the mimeType from the available formats in pDataObj...
Definition: qmime_win.cpp:926
bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
Returns true if the converter can convert to the mimeType from the available formats in pDataObj...
Definition: qmime_win.cpp:783
The QUrl class provides a convenient interface for working with URLs.
Definition: qurl.h:61
The QString class provides a Unicode character string.
Definition: qstring.h:83
QString mimeForFormat(const FORMATETC &formatetc) const
Returns the mime type that will be created form the format specified in formatetc, or an empty string if this converter does not support formatetc.
Definition: qmime_win.cpp:776
The QVector class is a template class that provides a dynamic array.
Definition: qdatastream.h:64
virtual bool atEnd() const
Returns true if the current read and write position is at the end of the device (i.e.
Definition: qiodevice.cpp:711
QList< QWindowsMime * > mimes
Definition: qmime_win.cpp:213
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
Format format() const
Returns the format of the image.
Definition: qimage.cpp:2305
QVector< FORMATETC > formatsForMime(const QString &mimeType, const QMimeData *mimeData) const
Returns a QVector of FORMATETC structures representing the different windows clipboard formats that c...
Definition: qmime_win.cpp:1235
QWindowsMime()
Constructs a new conversion object, adding it to the globally accessed list of available converters...
Definition: qmime_win.cpp:264
bool isEmpty() const
Returns true if the list contains no items; otherwise returns false.
Definition: qlist.h:152
Q_GUI_EXPORT_INLINE int qRed(QRgb rgb)
Definition: qrgb.h:57
bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
Returns true if the converter can convert to the mimeType from the available formats in pDataObj...
Definition: qmime_win.cpp:518
qint64 read(char *data, qint64 maxlen)
Reads at most maxSize bytes from the device into data, and returns the number of bytes read...
Definition: qiodevice.cpp:791
virtual QVector< FORMATETC > formatsForMime(const QString &mimeType, const QMimeData *mimeData) const =0
Returns a QVector of FORMATETC structures representing the different windows clipboard formats that c...
Q_CORE_EXPORT void qDebug(const char *,...)
QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const
Returns a QVariant containing the converted data for mimeType from pDataObj.
Definition: qmime_win.cpp:1279
QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const
Returns a QVariant containing the converted data for mimeType from pDataObj.
Definition: qmime_win.cpp:1131
unsigned char uchar
Definition: qglobal.h:994
bool hasOriginalDIBV5(IDataObject *pDataObj) const
Definition: qmime_win.cpp:973
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
long ciexyzX
Definition: qmime_win.cpp:79
static FORMATETC setCf(int cf)
Definition: qmime_win.cpp:130
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
QMap< int, QString > outFormats
Definition: qmime_win.cpp:1051
Q_GUI_EXPORT_INLINE QRgb qRgba(int r, int g, int b, int a)
Definition: qrgb.h:72
QVariant convertToMime(const QString &mime, LPDATAOBJECT pDataObj, QVariant::Type preferredType) const
Definition: qmime_win.cpp:696
bool qt_read_dib(QDataStream &, QImage &)
void truncate(int pos)
Truncates the string at the given position index.
Definition: qstring.cpp:4603
QString text() const
Returns a plain text (MIME type text/plain) representation of the data.
Definition: qmimedata.cpp:364
int size() const
Returns the number of characters in this string.
Definition: qstring.h:102
const QChar * unicode() const
Returns a &#39;\0&#39;-terminated Unicode representation of the string.
Definition: qstring.h:706
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
static bool init
static bool setData(const QByteArray &data, STGMEDIUM *pmedium)
Definition: qmime_win.cpp:141
bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
Returns true if the converter can convert from the mimeData to the format specified in formatetc...
Definition: qmime_win.cpp:436
QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const
Returns a QVariant containing the converted data for mimeType from pDataObj.
Definition: qmime_win.cpp:806
const T value(const Key &key) const
Returns the value associated with the key key.
Definition: qmap.h:499
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
QString html() const
Returns a string if the data stored in the object is HTML (MIME type text/html); otherwise returns an...
Definition: qmimedata.cpp:400
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
static QByteArray fromRawData(const char *, int size)
Constructs a QByteArray that uses the first size bytes of the data array.
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
long ciexyzY
Definition: qmime_win.cpp:79
virtual QString mimeForFormat(const FORMATETC &formatetc) const =0
Returns the mime type that will be created form the format specified in formatetc, or an empty string if this converter does not support formatetc.
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:87
QVector< FORMATETC > formatsForMime(const QString &mimeType, const QMimeData *mimeData) const
Returns a QVector of FORMATETC structures representing the different windows clipboard formats that c...
Definition: qmime_win.cpp:905
static const char * data(const QByteArray &arr)
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
QString mimeForFormat(const FORMATETC &formatetc) const
Returns the mime type that will be created form the format specified in formatetc, or an empty string if this converter does not support formatetc.
Definition: qmime_win.cpp:1301
Type
This enum type defines the types of variable that a QVariant can contain.
Definition: qvariant.h:95
bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
Returns true if the converter can convert from the mimeData to the format specified in formatetc...
Definition: qmime_win.cpp:1207
struct tagSTGMEDIUM STGMEDIUM
Definition: qmime.h:67
QBool contains(const QString &str, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the list contains the string str; otherwise returns false.
Definition: qstringlist.h:172
QList< QUrl > urls() const
Returns a list of URLs contained within the MIME data object.
Definition: qmimedata.cpp:310
bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
Returns true if the converter can convert to the mimeType from the available formats in pDataObj...
Definition: qmime_win.cpp:1125
void setByteOrder(ByteOrder)
Sets the serialization byte order to bo.
QList< Key > keys() const
Returns a list containing all the keys in the map in ascending order.
Definition: qmap.h:818
void setDotsPerMeterY(int)
Sets the number of pixels that fit vertically in a physical meter, to y.
Definition: qimage.cpp:5667
bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
Returns true if the converter can convert to the mimeType from the available formats in pDataObj...
Definition: qmime_win.cpp:668
The QMimeData class provides a container for data that records information about its MIME type...
Definition: qmimedata.h:57
QByteArray mid(int index, int len=-1) const
Returns a byte array containing len bytes from this byte array, starting at position pos...
QString toLocalFile() const
Returns the path of this URL formatted as a local file path.
Definition: qurl.cpp:6412
int indexOf(char c, int from=0) const
Returns the index position of the first occurrence of the character ch in the byte array...
QByteArray toLocal8Bit() const Q_REQUIRED_RESULT
Returns the local 8-bit representation of the string as a QByteArray.
Definition: qstring.cpp:4049
Q_GUI_EXPORT_INLINE int qBlue(QRgb rgb)
Definition: qrgb.h:63
static int calc_shift(int mask)
Definition: qmime_win.cpp:1460
static QByteArray renderDataHelper(const QString &mimeType, const QMimeData *data)
Definition: qdnd.cpp:447
bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM *pmedium) const
Convert the mimeData to the format specified in formatetc.
Definition: qmime_win.cpp:613
static bool canReadData(const QString &mimeType)
Definition: qdnd.cpp:408
QSize size() const
Returns the size of the image, i.
Definition: qimage.cpp:1587
int length() const
Same as size().
Definition: qbytearray.h:356
void resize(int size)
Sets the size of the string to size characters.
Definition: qstring.cpp:1353
T & first()
Returns a reference to the first item in the list.
Definition: qlist.h:282
void addWindowsMime(QWindowsMime *mime)
Definition: qmime_win.cpp:1367
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
QVariant imageData() const
Returns a QVariant storing a QImage if the object can return an image; otherwise returns a null varia...
Definition: qmimedata.cpp:442
bool hasImage() const
Returns true if the object can return an image; otherwise returns false.
Definition: qmimedata.cpp:471
QString mid(int position, int n=-1) const Q_REQUIRED_RESULT
Returns a string that contains n characters of this string, starting at the specified position index...
Definition: qstring.cpp:3706
Q_GLOBAL_STATIC(QWindowsMimeList, theMimeList)
virtual bool hasFormat(const QString &mimetype) const
Returns true if the object can return data for the MIME type specified by mimeType; otherwise returns...
Definition: qmimedata.cpp:563
uchar * bits()
Returns a pointer to the first pixel data.
Definition: qimage.cpp:1946
QVector< FORMATETC > formatsForMime(const QString &mimeType, const QMimeData *mimeData) const
Returns a QVector of FORMATETC structures representing the different windows clipboard formats that c...
Definition: qmime_win.cpp:768
QString mimeForFormat(const FORMATETC &formatetc) const
Returns the mime type that will be created form the format specified in formatetc, or an empty string if this converter does not support formatetc.
Definition: qmime_win.cpp:674
uint qstrlen(const char *str)
Definition: qbytearray.h:79
long HRESULT
bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
Returns true if the converter can convert to the mimeType from the available formats in pDataObj...
Definition: qmime_win.cpp:1263
int width() const
Returns the width of the image.
Definition: qimage.cpp:1557
bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM *pmedium) const
Convert the mimeData to the format specified in formatetc.
Definition: qmime_win.cpp:848
QImage convertToFormat(Format f, Qt::ImageConversionFlags flags=Qt::AutoColor) const Q_REQUIRED_RESULT
Returns a copy of the image in the given format.
Definition: qimage.cpp:3966
virtual bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const =0
Returns true if the converter can convert from the mimeData to the format specified in formatetc...
bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM *pmedium) const
Convert the mimeData to the format specified in formatetc.
Definition: qmime_win.cpp:1222
static QWindowsMime * converterFromMime(const FORMATETC &formatetc, const QMimeData *mimeData)
Definition: qmime_win.cpp:355
QIODevice * device() const
Returns the I/O device currently set, or 0 if no device is currently set.
Definition: qdatastream.h:206
bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM *pmedium) const
Convert the mimeData to the format specified in formatetc.
Definition: qmime_win.cpp:950
static int registerMimeType(const QString &mime)
Registers the MIME type mime, and returns an ID number identifying the format on Windows.
Definition: qmime_win.cpp:283
void setDotsPerMeterX(int)
Sets the number of pixels that fit horizontally in a physical meter, to x.
Definition: qimage.cpp:5645
QVector< FORMATETC > formatsForMime(const QString &mimeType, const QMimeData *mimeData) const
Returns a QVector of FORMATETC structures representing the different windows clipboard formats that c...
Definition: qmime_win.cpp:682
QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const
Returns a QVariant containing the converted data for mimeType from pDataObj.
Definition: qmime_win.cpp:995
unsigned short ushort
Definition: qglobal.h:995
QList< QWindowsMime * > windowsMimes()
Definition: qmime_win.cpp:1379
int lastIndexOf(QChar c, int from=-1, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.cpp:3000
iterator insert(const Key &key, const T &value)
Inserts a new item with the key key and a value of value.
Definition: qmap.h:559
int toInt(bool *ok=0, int base=10) const
Returns the byte array converted to an int using base base, which is 10 by default and must be betwee...
bool hasText() const
Returns true if the object can return plain text (MIME type text/plain); otherwise returns false...
Definition: qmimedata.cpp:389
virtual bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const =0
Returns true if the converter can convert to the mimeType from the available formats in pDataObj...
#define CF_DIBV5
Definition: qmime_win.cpp:69
void resize(int size)
Sets the size of the byte array to size bytes.
int size() const
Returns the number of items in the list.
Definition: qlist.h:137
bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM *pmedium) const
Convert the mimeData to the format specified in formatetc.
Definition: qmime_win.cpp:1070
static const char x_qt_windows_mime[]
Definition: qmime_win.cpp:1249
static QWindowsMime * converterToMime(const QString &mimeType, IDataObject *pDataObj)
Definition: qmime_win.cpp:365
QFactoryLoader * l
_CIEXYZTRIPLE bV5Endpoints
Definition: qmime_win.cpp:103
bool contains(const Key &key) const
Returns true if the map contains an item with key key; otherwise returns false.
Definition: qmap.h:553
int height() const
Returns the height of the image.
Definition: qimage.cpp:1572
T qvariant_cast(const QVariant &)
Definition: qvariant.h:571
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
static const int BMP_BITFIELDS
Definition: qmime_win.cpp:112
QVector< FORMATETC > formatsForMime(const QString &mimeType, const QMimeData *mimeData) const
Returns a QVector of FORMATETC structures representing the different windows clipboard formats that c...
Definition: qmime_win.cpp:1117
long ciexyzZ
Definition: qmime_win.cpp:79
Q_GUI_EXPORT_INLINE int qGreen(QRgb rgb)
Definition: qrgb.h:60
bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
Returns true if the converter can convert from the mimeData to the format specified in formatetc...
Definition: qmime_win.cpp:601
void removeWindowsMime(QWindowsMime *mime)
Definition: qmime_win.cpp:1373
static QUrl fromLocalFile(const QString &localfile)
Returns a QUrl representation of localFile, interpreted as a local file.
Definition: qurl.cpp:6374
QByteArray & replace(int index, int len, const char *s)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool isEmpty() const
Returns true if the byte array has size 0; otherwise returns false.
Definition: qbytearray.h:421
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
Returns true if the converter can convert from the mimeData to the format specified in formatetc...
Definition: qmime_win.cpp:934
The QDataStream class provides serialization of binary data to a QIODevice.
Definition: qdatastream.h:71
void reserve(int size)
Attempts to allocate memory for at least size elements.
Definition: qvector.h:339
QVariant convertToMime(const QString &mime, LPDATAOBJECT pDataObj, QVariant::Type preferredType) const
Definition: qmime_win.cpp:544
QString mimeForFormat(const FORMATETC &formatetc) const
Returns the mime type that will be created form the format specified in formatetc, or an empty string if this converter does not support formatetc.
Definition: qmime_win.cpp:918
QMap< int, QString > formats
Definition: qmime_win.cpp:1173
bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
Returns true if the converter can convert from the mimeData to the format specified in formatetc...
Definition: qmime_win.cpp:789
qint64 write(const char *data, qint64 len)
Writes at most maxSize bytes of data from data to the device.
Definition: qiodevice.cpp:1342
bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM *pmedium) const
Convert the mimeData to the format specified in formatetc.
Definition: qmime_win.cpp:447
char at(int i) const
Returns the character at index position i in the byte array.
Definition: qbytearray.h:413
static const KeyPair *const end
The QIODevice class is the base interface class of all I/O devices in Qt.
Definition: qiodevice.h:66
static QString toNativeSeparators(const QString &pathName)
Returns pathName with the &#39;/&#39; separators converted to separators that are appropriate for the underly...
Definition: qdir.cpp:812
QString mimeForFormat(const FORMATETC &formatetc) const
Returns the mime type that will be created form the format specified in formatetc, or an empty string if this converter does not support formatetc.
Definition: qmime_win.cpp:1151
#define BMP_LCS_sRGB
Definition: qmime_win.cpp:75
QString mimeForFormat(const FORMATETC &formatetc) const
Returns the mime type that will be created form the format specified in formatetc, or an empty string if this converter does not support formatetc.
Definition: qmime_win.cpp:525
#define CF_HDROP
static QVector< FORMATETC > allFormatsForMime(const QMimeData *mimeData)
Definition: qmime_win.cpp:375
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
void detach()
Definition: qbytearray.h:435
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
uchar * scanLine(int)
Returns a pointer to the pixel data at the scanline with index i.
Definition: qimage.cpp:1886
static QByteArray getData(int cf, IDataObject *pDataObj)
Definition: qmime_win.cpp:156
bool loadFromData(const uchar *buf, int len, const char *format=0)
Loads an image from the first len bytes of the given binary data.
Definition: qimage.cpp:5275
static bool canGetData(int cf, IDataObject *pDataObj)
Definition: qmime_win.cpp:191
The QList class is a template class that provides lists.
Definition: qdatastream.h:62
const ushort * utf16() const
Returns the QString as a &#39;\0\&#39;-terminated array of unsigned shorts.
Definition: qstring.cpp:5290
void qErrnoWarning(const char *msg,...)
Definition: qglobal.cpp:2954
int removeAll(const T &t)
Removes all occurrences of value in the list and returns the number of entries removed.
Definition: qlist.h:770
static bool qt_read_dibv5(QDataStream &s, QImage &image)
Definition: qmime_win.cpp:1471