summaryrefslogtreecommitdiffstats
path: root/tqtinterface/qt4/src/kernel/tqdragobject.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tqtinterface/qt4/src/kernel/tqdragobject.cpp')
-rw-r--r--tqtinterface/qt4/src/kernel/tqdragobject.cpp3378
1 files changed, 3378 insertions, 0 deletions
diff --git a/tqtinterface/qt4/src/kernel/tqdragobject.cpp b/tqtinterface/qt4/src/kernel/tqdragobject.cpp
new file mode 100644
index 0000000..6e58f84
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqdragobject.cpp
@@ -0,0 +1,3378 @@
+#include "tqtglobaldefines.h"
+
+// #ifdef USE_QT4
+#if 0
+
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3Support module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplatformdefs.h"
+
+#ifndef QT_NO_MIME
+
+#include "tqdragobject.h"
+#include "qpixmap.h"
+#include "qevent.h"
+#include "qfile.h"
+#include "qtextcodec.h"
+#include "qapplication.h"
+#include "qpoint.h"
+#include "qwidget.h"
+#include "qbuffer.h"
+#include "qimagereader.h"
+#include "qimagewriter.h"
+#include "qimage.h"
+#include "qregexp.h"
+#include "qdir.h"
+#include "qdrag.h"
+#include "tqstrlist.h"
+#include "tqcstring.h"
+
+// #include <private/qobject_p.h>
+
+#include <ctype.h>
+#if defined(Q_OS_WINCE)
+#include <winsock.h>
+#include "qfunctions_wince.h"
+#endif
+
+QT_BEGIN_NAMESPACE
+
+static QWidget *last_target = 0;
+
+class QDragMime;
+
+class TQDragObjectPrivate : public TQObjectPrivate
+{
+ Q_DECLARE_PUBLIC(TQDragObject)
+public:
+ TQDragObjectPrivate(): hot(0,0),pm_cursor(0) {}
+ QPixmap pixmap;
+ QPoint hot;
+ // store default cursors
+ QPixmap *pm_cursor;
+};
+
+class TQTextDragPrivate : public TQDragObjectPrivate
+{
+ Q_DECLARE_PUBLIC(TQTextDrag)
+public:
+ TQTextDragPrivate() { setSubType(QLatin1String("plain")); }
+ void setSubType(const QString & st) {
+ subtype = st;
+ fmt = "text/" + subtype.toLatin1();
+ }
+
+ QString txt;
+ QString subtype;
+ QByteArray fmt;
+};
+
+class TQStoredDragPrivate : public TQDragObjectPrivate
+{
+ Q_DECLARE_PUBLIC(TQStoredDrag)
+public:
+ TQStoredDragPrivate() {}
+ const char* fmt;
+ QByteArray enc;
+};
+
+class TQImageDragPrivate : public TQDragObjectPrivate
+{
+ Q_DECLARE_PUBLIC(TQImageDrag)
+public:
+ TQImage img;
+ QList<QByteArray> ofmts;
+};
+
+class QDragMime : public QMimeData
+{
+public:
+ QDragMime(TQDragObject *parent) : QMimeData(), dragObject(parent) { }
+ ~QDragMime();
+
+ QByteArray data(const QString &mimetype) const;
+ bool hasFormat(const QString &mimetype) const;
+ QStringList formats() const;
+
+ QPointer<TQDragObject> dragObject;
+};
+
+QDragMime::~QDragMime()
+{
+ delete dragObject;
+}
+QByteArray QDragMime::data(const QString &mimetype) const
+{
+ return dragObject->encodedData(mimetype.latin1());
+}
+
+bool QDragMime::hasFormat(const QString &mimetype) const
+{
+ return dragObject->provides(mimetype.latin1());
+}
+
+QStringList QDragMime::formats() const
+{
+ int i = 0;
+ const char *format;
+ QStringList f;
+ while ((format = dragObject->format(i))) {
+ f.append(QLatin1String(format));
+ ++i;
+ }
+ return f;
+}
+
+/*!
+ Constructs a drag object called \a name with a parent \a
+ dragSource.
+
+ Note that the drag object will be deleted when the \a dragSource is
+ deleted.
+*/
+
+TQDragObject::TQDragObject(QWidget * dragSource, const char * name)
+ :TQObject(*(new TQDragObjectPrivate), dragSource)
+{
+ setObjectName(QLatin1String(name));
+}
+
+/*! \internal */
+TQDragObject::TQDragObject(TQDragObjectPrivate &dd, QWidget *dragSource)
+ :TQObject(dd, dragSource)
+{
+}
+
+/*!
+ Destroys the drag object, canceling any drag and drop operation in
+ which it is involved.
+*/
+
+TQDragObject::~TQDragObject()
+{
+}
+
+#ifndef QT_NO_DRAGANDDROP
+/*!
+ Set the pixmap, \a pm, to display while dragging the object. The
+ platform-specific implementation will use this where it can - so
+ provide a small masked pixmap, and do not assume that the user
+ will actually see it.
+
+ The \a hotspot is the point on (or off) the pixmap that should be
+ under the cursor as it is dragged. It is relative to the top-left
+ pixel of the pixmap.
+
+ \warning We have seen problems with drag cursors on different
+ graphics hardware and driver software on Windows. Setting the
+ graphics acceleration in the display settings down one tick solved
+ the problems in all cases.
+*/
+void TQDragObject::setPixmap(QPixmap pm, const QPoint& hotspot)
+{
+ Q_D(TQDragObject);
+ d->pixmap = pm;
+ d->hot = hotspot;
+}
+
+/*!
+ \overload
+
+ Uses a hotspot that positions the pixmap below and to the right of
+ the mouse pointer. This allows the user to clearly see the point
+ on the window where they are dragging the data.
+*/
+void TQDragObject::setPixmap(QPixmap pm)
+{
+ setPixmap(pm,QPoint(-10, -10));
+}
+
+/*!
+ Returns the currently set pixmap, or a null pixmap if none is set.
+
+ \sa QPixmap::isNull()
+*/
+QPixmap TQDragObject::pixmap() const
+{
+ return d_func()->pixmap;
+}
+
+/*!
+ Returns the currently set pixmap hotspot.
+
+ \sa setPixmap()
+*/
+QPoint TQDragObject::pixmapHotSpot() const
+{
+ return d_func()->hot;
+}
+
+/*!
+ Starts a drag operation using the contents of this object, using
+ DragDefault mode.
+
+ The function returns true if the caller should delete the original
+ copy of the dragged data (but see target()); otherwise returns
+ false.
+
+ If the drag contains \e references to information (e.g. file names
+ in a TQUriDrag are references) then the return value should always
+ be ignored, as the target is expected to directly manipulate the
+ content referred to by the drag object. On X11 the return value should
+ always be correct anyway, but on Windows this is not necessarily
+ the case; e.g. the file manager starts a background process to
+ move files, so the source \e{must not} delete the files!
+
+ Note that on Windows the drag operation will start a blocking modal
+ event loop that will not dispatch any QTimers.
+*/
+bool TQDragObject::drag()
+{
+ return drag(DragDefault);
+}
+
+/*!
+ After the drag completes, this function will return the QWidget
+ which received the drop, or 0 if the data was dropped on another
+ application.
+
+ This can be useful for detecting the case where drag and drop is
+ to and from the same widget.
+*/
+QWidget *TQDragObject::target()
+{
+ return last_target;
+}
+
+/*!
+ Starts a drag operation using the contents of this object, using
+ \c DragMove mode. Be sure to read the constraints described in
+ drag().
+
+ Returns true if the data was dragged as a \e move, indicating that
+ the caller should remove the original source of the data (the drag
+ object must continue to have a copy); otherwise returns false.
+
+ \sa drag() dragCopy() dragLink()
+*/
+bool TQDragObject::dragMove()
+{
+ return drag(DragMove);
+}
+
+
+/*!
+ Starts a drag operation using the contents of this object, using
+ \c DragCopy mode. Be sure to read the constraints described in
+ drag().
+
+ \sa drag() dragMove() dragLink()
+*/
+void TQDragObject::dragCopy()
+{
+ (void)drag(DragCopy);
+}
+
+/*!
+ Starts a drag operation using the contents of this object, using
+ \c DragLink mode. Be sure to read the constraints described in
+ drag().
+
+ \sa drag() dragCopy() dragMove()
+*/
+void TQDragObject::dragLink()
+{
+ (void)drag(DragLink);
+}
+
+
+/*!
+ \enum TQDragObject::DragMode
+
+ This enum describes the possible drag modes.
+
+ \value DragDefault The mode is determined heuristically.
+ \value DragCopy The data is copied.
+ \value DragMove The data is moved.
+ \value DragLink The data is linked.
+ \value DragCopyOrMove The user chooses the mode by using the
+ \key{Shift} key to switch from the default
+ copy mode to move mode.
+*/
+
+
+/*!
+ \overload
+ Starts a drag operation using the contents of this object.
+
+ At this point, the object becomes owned by Qt, not the
+ application. You should not delete the drag object or anything it
+ references. The actual transfer of data to the target application
+ will be done during future event processing - after that time the
+ drag object will be deleted.
+
+ Returns true if the dragged data was dragged as a \e move,
+ indicating that the caller should remove the original source of
+ the data (the drag object must continue to have a copy); otherwise
+ returns false.
+
+ The \a mode specifies the drag mode (see
+ \l{TQDragObject::DragMode}.) Normally one of the simpler drag(),
+ dragMove(), or dragCopy() functions would be used instead.
+*/
+bool TQDragObject::drag(DragMode mode)
+{
+ Q_D(TQDragObject);
+ QDragMime *data = new QDragMime(this);
+ int i = 0;
+ const char *fmt;
+ while ((fmt = format(i))) {
+ data->setData(QLatin1String(fmt), encodedData(fmt));
+ ++i;
+ }
+
+ QDrag *drag = new QDrag(qobject_cast<QWidget *>(parent()));
+ drag->setMimeData(data);
+ drag->setPixmap(d->pixmap);
+ drag->setHotSpot(d->hot);
+
+ Qt::DropActions allowedOps;
+ Qt::DropAction defaultOp = Qt::IgnoreAction;
+ switch(mode) {
+ default:
+ case DragDefault:
+ case DragCopyOrMove:
+ allowedOps = Qt::CopyAction|Qt::MoveAction;
+ defaultOp = Qt::IgnoreAction;
+ break;
+ case DragCopy:
+ allowedOps = Qt::CopyAction;
+ defaultOp = Qt::CopyAction;
+ break;
+ case DragMove:
+ allowedOps = Qt::MoveAction;
+ defaultOp = Qt::MoveAction;
+ break;
+ case DragLink:
+ allowedOps = Qt::LinkAction;
+ defaultOp = Qt::LinkAction;
+ break;
+ }
+ bool retval = (drag->exec(allowedOps, defaultOp) == Qt::MoveAction);
+ last_target = drag->target();
+
+ return retval;
+}
+
+#endif
+
+
+/*!
+ Returns a pointer to the widget where this object originated (the drag
+ source).
+*/
+
+QWidget * TQDragObject::source()
+{
+ if (parent() && parent()->isWidgetType())
+ return (QWidget *)parent();
+ else
+ return 0;
+}
+
+
+/*!
+ \class TQDragObject
+
+ \brief The TQDragObject class encapsulates MIME-based data
+ transfer.
+
+ \compat
+
+ TQDragObject is the base class for all data that needs to be
+ transferred between and within applications, both for drag and
+ drop and for the clipboard.
+
+ See the \link dnd.html Drag and drop documentation\endlink for an
+ overview of how to provide drag and drop in your application.
+
+ See the QClipboard documentation for an overview of how to provide
+ cut and paste in your application.
+
+ The drag() function is used to start a drag operation. You can
+ specify the \l DragMode in the call or use one of the convenience
+ functions dragCopy(), dragMove(), or dragLink(). The drag source
+ where the data originated is retrieved with source(). If the data
+ was dropped on a widget within the application, target() will
+ return a pointer to that widget. Specify the pixmap to display
+ during the drag with setPixmap().
+*/
+
+static
+void stripws(QByteArray& s)
+{
+ int f;
+ while ((f = s.indexOf(' ')) >= 0)
+ s.remove(f,1);
+}
+
+/*!
+ \class TQTextDrag
+
+ \brief The TQTextDrag class is a drag and drop object for
+ transferring plain and Unicode text.
+
+ \compat
+
+ Plain text is passed in a QString which may contain multiple lines
+ (i.e. may contain newline characters). The drag target will receive
+ the newlines according to the runtime environment, e.g. LF on Unix,
+ and CRLF on Windows.
+
+ Qt provides no built-in mechanism for delivering only a single-line.
+
+ For more information about drag and drop, see the TQDragObject class
+ and the \link dnd.html drag and drop documentation\endlink.
+*/
+
+
+/*!
+ Constructs a text drag object with the given \a name, and sets its data
+ to \a text. The \a dragSource is the widget that the drag operation started
+ from.
+*/
+
+TQTextDrag::TQTextDrag(const QString &text, QWidget * dragSource, const char * name)
+ : TQDragObject(*new TQTextDragPrivate, dragSource)
+{
+ setObjectName(QLatin1String(name));
+ setText(text);
+}
+
+
+/*!
+ Constructs a default text drag object with the given \a name.
+ The \a dragSource is the widget that the drag operation started from.
+*/
+
+TQTextDrag::TQTextDrag(QWidget * dragSource, const char * name)
+ : TQDragObject(*(new TQTextDragPrivate), dragSource)
+{
+ setObjectName(QLatin1String(name));
+}
+
+/*! \internal */
+TQTextDrag::TQTextDrag(TQTextDragPrivate &dd, QWidget *dragSource)
+ : TQDragObject(dd, dragSource)
+{
+
+}
+
+/*!
+ Destroys the text drag object.
+*/
+TQTextDrag::~TQTextDrag()
+{
+
+}
+
+/*!
+ \fn void TQTextDrag::setSubtype(const QString &subtype)
+
+ Sets the MIME \a subtype of the text being dragged. The default subtype
+ is "plain", so the default MIME type of the text is "text/plain".
+ You might use this to declare that the text is "text/html" by calling
+ setSubtype("html").
+*/
+void TQTextDrag::setSubtype(const QString & st)
+{
+ d_func()->setSubType(st);
+}
+
+/*!
+ Sets the \a text to be dragged. You will need to call this if you did
+ not pass the text during construction.
+*/
+void TQTextDrag::setText(const QString &text)
+{
+ d_func()->txt = text;
+}
+
+
+/*!
+ \reimp
+*/
+const char * TQTextDrag::format(int i) const
+{
+ if (i > 0)
+ return 0;
+ return d_func()->fmt.constData();
+}
+
+QTextCodec* qt_findcharset(const QByteArray& mimetype)
+{
+ int i=mimetype.indexOf("charset=");
+ if (i >= 0) {
+ QByteArray cs = mimetype.mid(i+8);
+ stripws(cs);
+ i = cs.indexOf(';');
+ if (i >= 0)
+ cs = cs.left(i);
+ // May return 0 if unknown charset
+ return QTextCodec::codecForName(cs);
+ }
+ // no charset=, use locale
+ return QTextCodec::codecForName("utf-8");
+}
+
+static QTextCodec *codecForHTML(const QByteArray &ba)
+{
+ // determine charset
+ int mib = 0;
+ int pos;
+ QTextCodec *c = 0;
+
+ if (ba.size() > 1 && (((uchar)ba[0] == 0xfe && (uchar)ba[1] == 0xff)
+ || ((uchar)ba[0] == 0xff && (uchar)ba[1] == 0xfe))) {
+ mib = 1015; // utf16
+ } else if (ba.size() > 2
+ && (uchar)ba[0] == 0xef
+ && (uchar)ba[1] == 0xbb
+ && (uchar)ba[2] == 0xbf) {
+ mib = 106; // utf-8
+ } else {
+ pos = 0;
+ while ((pos = ba.indexOf('<', pos)) != -1) {
+ int end = ba.indexOf('>', pos+1);
+ if (end == -1)
+ break;
+ const QString str(QString::fromLatin1(ba.mid(pos, end-pos)));
+ if (str.contains(QLatin1String("meta http-equiv="), Qt::CaseInsensitive)) {
+ pos = str.indexOf(QLatin1String("charset="), 0, Qt::CaseInsensitive) + int(strlen("charset="));
+ if (pos != -1) {
+ int pos2 = ba.indexOf('\"', pos+1);
+ QByteArray cs = ba.mid(pos, pos2-pos);
+ c = QTextCodec::codecForName(cs);
+ if (c)
+ return c;
+ }
+ }
+ pos = end;
+ }
+ }
+ if (mib)
+ c = QTextCodec::codecForMib(mib);
+
+ return c;
+}
+
+static
+QTextCodec* findcodec(const QMimeSource* e)
+{
+ QTextCodec* r = 0;
+ const char* f;
+ int i;
+ for (i=0; (f=e->format(i)); i++) {
+ bool html = !qstrnicmp(f, "text/html", 9);
+ if (html)
+ r = codecForHTML(e->encodedData(f));
+ if (!r)
+ r = qt_findcharset(QByteArray(f).toLower());
+ if (r)
+ return r;
+ }
+ return 0;
+}
+
+
+
+/*!
+ \reimp
+*/
+QByteArray TQTextDrag::encodedData(const char* mime) const
+{
+ Q_D(const TQTextDrag);
+ if (mime != d->fmt)
+ return QByteArray();
+ return d->txt.toUtf8();
+}
+
+/*!
+ \fn bool TQTextDrag::canDecode(const QMimeSource *source)
+
+ Returns true if the information in the MIME \a source can be decoded
+ into a QString; otherwise returns false.
+
+ \sa decode()
+*/
+bool TQTextDrag::canDecode(const QMimeSource* e)
+{
+ const char* f;
+ for (int i=0; (f=e->format(i)); i++) {
+ if (0==qstrnicmp(f,"text/",5)) {
+ return findcodec(e) != 0;
+ }
+ }
+ return false;
+}
+
+/*!
+ \fn bool TQTextDrag::decode(const QMimeSource *source, QString &string, QString &subtype)
+
+ \overload
+
+ Attempts to decode the dropped information in the MIME \a source into
+ the \a string given.
+ Returns true if successful; otherwise returns false. If \a subtype
+ is null, any text subtype is accepted; otherwise only the
+ specified \a subtype is accepted.
+
+ \sa canDecode()
+*/
+bool TQTextDrag::decode(const QMimeSource* e, QString& str, QString& subtype)
+{
+ if(!e)
+ return false;
+
+ const char* mime;
+ for (int i=0; (mime = e->format(i)); i++) {
+ if (0==qstrnicmp(mime,"text/",5)) {
+ QByteArray m(mime);
+ m = m.toLower();
+ int semi = m.indexOf(';');
+ if (semi < 0)
+ semi = m.length();
+ QString foundst(QString::fromLatin1(m.mid(5,semi-5)));
+ if (subtype.isNull() || foundst == subtype) {
+ bool html = !qstrnicmp(mime, "text/html", 9);
+ QTextCodec* codec = 0;
+ if (html)
+ // search for the charset tag in the HTML
+ codec = codecForHTML(e->encodedData(mime));
+ if (!codec)
+ codec = qt_findcharset(m);
+ if (codec) {
+ QByteArray payload;
+
+ payload = e->encodedData(mime);
+ if (payload.size()) {
+ int l;
+ if (codec->mibEnum() != 1015) {
+ // length is at NUL or payload.size()
+ l = 0;
+ while (l < (int)payload.size() && payload[l])
+ l++;
+ } else {
+ l = payload.size();
+ }
+
+ str = codec->toUnicode(payload,l);
+
+ if (subtype.isNull())
+ subtype = foundst;
+
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+}
+
+/*!
+ \fn bool TQTextDrag::decode(const QMimeSource *source, QString &string)
+
+ Attempts to decode the dropped information in the MIME \a source into
+ the \a string given.
+ Returns true if successful; otherwise returns false.
+
+ \sa canDecode()
+*/
+bool TQTextDrag::decode(const QMimeSource* e, QString& str)
+{
+ QString st;
+ return decode(e, str, st);
+}
+
+
+/*
+ TQImageDrag could use an internal MIME type for communicating QPixmaps
+ and TQImages rather than always converting to raw data. This is available
+ for that purpose and others. It is not currently used.
+*/
+
+/*!
+ \class TQImageDrag
+
+ \brief The TQImageDrag class provides a drag and drop object for
+ transferring images.
+
+ \compat
+
+ Images are offered to the receiving application in multiple
+ formats, determined by Qt's output formats.
+*/
+
+/*!
+ Constructs an image drag object with the given \a name, and sets its
+ data to \a image. The \a dragSource is the widget that the drag operation
+ started from.
+*/
+
+TQImageDrag::TQImageDrag(TQImage image,
+ QWidget * dragSource, const char * name)
+ : TQDragObject(*(new TQImageDragPrivate), dragSource)
+{
+ setObjectName(QLatin1String(name));
+ setImage(image);
+}
+
+/*!
+ Constructs a default image drag object with the given \a name.
+ The \a dragSource is the widget that the drag operation started from.
+*/
+
+TQImageDrag::TQImageDrag(QWidget * dragSource, const char * name)
+ : TQDragObject(*(new TQImageDragPrivate), dragSource)
+{
+ setObjectName(QLatin1String(name));
+}
+
+/*! \internal */
+TQImageDrag::TQImageDrag(TQImageDragPrivate &dd, QWidget *dragSource)
+ : TQDragObject(dd, dragSource)
+{
+}
+
+/*!
+ Destroys the image drag object.
+*/
+
+TQImageDrag::~TQImageDrag()
+{
+ // nothing
+}
+
+
+/*!
+ Sets the \a image to be dragged. You will need to call this if you did
+ not pass the image during construction.
+*/
+void TQImageDrag::setImage(TQImage image)
+{
+ Q_D(TQImageDrag);
+ d->img = image;
+ QList<QByteArray> formats = QImageWriter::supportedImageFormats();
+ formats.removeAll("PBM"); // remove non-raw PPM
+ if (image.depth()!=32) {
+ // BMP better than PPM for paletted images
+ if (formats.removeAll("BMP")) // move to front
+ formats.insert(0,"BMP");
+ }
+ // PNG is best of all
+ if (formats.removeAll("PNG")) // move to front
+ formats.insert(0,"PNG");
+
+ for(int i = 0; i < formats.count(); i++) {
+ QByteArray format("image/");
+ format += formats.at(i);
+ format = format.toLower();
+ if (format == "image/pbmraw")
+ format = "image/ppm";
+ d->ofmts.append(format);
+ }
+ d->ofmts.append("application/x-qt-image");
+}
+
+/*!
+ \reimp
+*/
+const char * TQImageDrag::format(int i) const
+{
+ Q_D(const TQImageDrag);
+ return i < d->ofmts.count() ? d->ofmts.at(i).data() : 0;
+}
+
+/*!
+ \reimp
+*/
+QByteArray TQImageDrag::encodedData(const char* fmt) const
+{
+ Q_D(const TQImageDrag);
+ QString imgFormat(fmt);
+ if (imgFormat == QLatin1String("application/x-qt-image"))
+ imgFormat = QLatin1String("image/PNG");
+
+ if (imgFormat.startsWith("image/")){
+ QByteArray f(imgFormat.mid(6).toAscii());
+ QByteArray dat;
+ QBuffer w(&dat);
+ w.open(QIODevice::WriteOnly);
+ QImageWriter writer(&w, f.toUpper());
+ if (!writer.write(d->img))
+ return QByteArray();
+ w.close();
+ return dat;
+ } else {
+ return QByteArray();
+ }
+}
+
+/*!
+ \fn bool TQImageDrag::canDecode(const QMimeSource *source)
+
+ Returns true if the information in the MIME \a source can be decoded
+ into an image; otherwise returns false.
+
+ \sa decode()
+*/
+bool TQImageDrag::canDecode(const QMimeSource* e)
+{
+ return e->provides("application/x-qt-image");
+}
+
+/*!
+ \fn bool TQImageDrag::decode(const QMimeSource *source, QImage &image)
+
+ Decode the dropped information in the MIME \a source into the \a image.
+ Returns true if successful; otherwise returns false.
+
+ \sa canDecode()
+*/
+bool TQImageDrag::decode(const QMimeSource* e, QImage& img)
+{
+ if (!e)
+ return false;
+
+ QByteArray payload = e->encodedData("application/x-qt-image");
+ if (payload.isEmpty())
+ return false;
+
+ img.loadFromData(payload);
+ if (img.isNull())
+ return false;
+
+ return true;
+}
+
+/*!
+ \fn bool TQImageDrag::decode(const QMimeSource *source, QPixmap &pixmap)
+
+ \overload
+
+ Decodes the dropped information in the MIME \a source into the \a pixmap.
+ Returns true if successful; otherwise returns false.
+
+ This is a convenience function that converts the information to a QPixmap
+ via a QImage.
+
+ \sa canDecode()
+*/
+bool TQImageDrag::decode(const QMimeSource* e, QPixmap& pm)
+{
+ if (!e)
+ return false;
+
+ QImage img;
+ // We avoid dither, since the image probably came from this display
+ if (decode(e, img)) {
+ pm = QPixmap::fromImage(img, Qt::AvoidDither);
+ if (pm.isNull())
+ return false;
+
+ return true;
+ }
+ return false;
+}
+
+
+
+
+/*!
+ \class TQStoredDrag
+ \brief The TQStoredDrag class provides a simple stored-value drag object for arbitrary MIME data.
+
+ \compat
+
+ When a block of data has only one representation, you can use a
+ TQStoredDrag to hold it.
+
+ For more information about drag and drop, see the TQDragObject
+ class and the \link dnd.html drag and drop documentation\endlink.
+*/
+
+/*!
+ Constructs a TQStoredDrag. The \a dragSource and \a name are passed
+ to the TQDragObject constructor, and the format is set to \a
+ mimeType.
+
+ The data will be unset. Use setEncodedData() to set it.
+*/
+TQStoredDrag::TQStoredDrag(const char* mimeType, QWidget * dragSource, const char * name) :
+ TQDragObject(*new TQStoredDragPrivate, dragSource)
+{
+ Q_D(TQStoredDrag);
+ setObjectName(QLatin1String(name));
+ d->fmt = qstrdup(mimeType);
+}
+
+/*! \internal */
+TQStoredDrag::TQStoredDrag(TQStoredDragPrivate &dd, const char* mimeType, QWidget * dragSource)
+ : TQDragObject(dd, dragSource)
+{
+ d_func()->fmt = qstrdup(mimeType);
+}
+
+/*!
+ Destroys the drag object.
+*/
+TQStoredDrag::~TQStoredDrag()
+{
+ delete [] (char*)d_func()->fmt;
+}
+
+/*!
+ \reimp
+*/
+const char * TQStoredDrag::format(int i) const
+{
+ if (i==0)
+ return d_func()->fmt;
+ else
+ return 0;
+}
+
+
+/*!
+ \fn void TQStoredDrag::setEncodedData(const QByteArray &data)
+
+ Sets the encoded \a data of this drag object. The encoded data is
+ delivered to drop sites; it must be in a strictly defined and portable
+ format.
+
+ The drag object can't be dropped (by the user) until this function
+ has been called.
+*/
+
+void TQStoredDrag::setEncodedData(const QByteArray & encodedData)
+{
+ d_func()->enc = encodedData;
+}
+
+/*!
+ \fn QByteArray TQStoredDrag::encodedData(const char *format) const
+
+ Returns the stored data in the \a format given.
+
+ \sa setEncodedData()
+*/
+QByteArray TQStoredDrag::encodedData(const char* m) const
+{
+ if (!qstricmp(m, d_func()->fmt))
+ return d_func()->enc;
+ else
+ return QByteArray();
+}
+
+
+/*!
+ \class TQUriDrag
+ \brief The TQUriDrag class provides a drag object for a list of URI references.
+
+ \compat
+
+ URIs are a useful way to refer to files that may be distributed
+ across multiple machines. A URI will often refer to a file on a
+ machine local to both the drag source and the drop target, so the
+ URI can be equivalent to passing a file name but is more
+ extensible.
+
+ Use URIs in Unicode form so that the user can comfortably edit and
+ view them. For use in HTTP or other protocols, use the correctly
+ escaped ASCII form.
+
+ You can convert a list of file names to file URIs using
+ setFileNames(), or into human-readable form with setUnicodeUris().
+
+ Static functions are provided to convert between filenames and
+ URIs; e.g. uriToLocalFile() and localFileToUri(). Static functions
+ are also provided to convert URIs to and from human-readable form;
+ e.g. uriToUnicodeUri() and unicodeUriToUri().
+ You can also decode URIs from a MIME source into a list with
+ decodeLocalFiles() and decodeToUnicodeUris().
+*/
+
+/*!
+ Constructs an object to drag the list of \a uris.
+ The \a dragSource and \a name are passed to the TQStoredDrag constructor.
+
+ Note that URIs are always in escaped UTF8 encoding.
+*/
+TQUriDrag::TQUriDrag(const TQStrList &uris, QWidget * dragSource, const char * name) :
+ TQStoredDrag("text/uri-list", dragSource)
+{
+ setObjectName(QLatin1String(name));
+ setUris(uris);
+}
+
+/*!
+ Constructs an object to drag with the given \a name.
+ You must call setUris() before you start the drag().
+ Both the \a dragSource and the \a name are passed to the TQStoredDrag
+ constructor.
+*/
+TQUriDrag::TQUriDrag(QWidget * dragSource, const char * name) :
+ TQStoredDrag("text/uri-list", dragSource)
+{
+ setObjectName(QLatin1String(name));
+}
+#endif
+
+/*!
+ Destroys the URI drag object.
+*/
+TQUriDrag::~TQUriDrag()
+{
+}
+
+/*!
+ \fn void TQUriDrag::setUris(const QList<QByteArray> &list)
+
+ Changes the \a list of URIs to be dragged.
+
+ Note that URIs are always in escaped UTF8 encoding.
+*/
+void TQUriDrag::setUris(const QList<QByteArray> &uris)
+{
+ QByteArray a;
+ int c = 0;
+ int i;
+ int count = uris.count();
+ for (i = 0; i < count; ++i)
+ c += uris.at(i).size() + 2; //length + \r\n
+ a.reserve(c+1);
+ for (i = 0; i < count; ++i) {
+ a.append(uris.at(i));
+ a.append("\r\n");
+ }
+ a[c] = 0;
+ setEncodedData(a);
+}
+
+
+/*!
+ \fn bool TQUriDrag::canDecode(const QMimeSource *source)
+
+ Returns true if decode() can decode the MIME \a source; otherwise
+ returns false.
+*/
+bool TQUriDrag::canDecode(const QMimeSource* e)
+{
+ return e->provides("text/uri-list");
+}
+
+/*!
+ \fn bool TQUriDrag::decode(const QMimeSource* source, TQStrList& list)
+
+ Decodes URIs from the MIME \a source, placing the result in the \a list.
+ The list is cleared before any items are inserted.
+
+ Returns true if the MIME \a source contained a valid list of URIs;
+ otherwise returns false.
+*/
+bool TQUriDrag::decode(const QMimeSource* e, TQStrList& l)
+{
+ QByteArray payload = e->encodedData("text/uri-list");
+ if (payload.size()) {
+ l.clear();
+ l.setAutoDelete(true);
+ uint c=0;
+ const char* data = payload.data();
+ while ((int)c < payload.size() && data[c]) {
+ uint f = c;
+ // Find line end
+ while ((int)c < payload.size() && data[c] && data[c]!='\r'
+ && data[c] != '\n')
+ c++;
+ TQCString s(data+f,c-f+1);
+ if (s[0] != '#') // non-comment?
+ l.append(s);
+ // Skip junk
+ while ((int)c < payload.size() && data[c] &&
+ (data[c]=='\n' || data[c]=='\r'))
+ c++;
+ }
+ return true;
+ }
+ return false;
+}
+
+static uint htod(int h)
+{
+ if (isdigit(h))
+ return h - '0';
+ return tolower(h) - 'a' + 10;
+}
+
+/*!
+ \fn TQUriDrag::setFilenames(const QStringList &list)
+
+ \obsolete
+
+ Sets the filename's in the drag object to those in the given \a
+ list.
+
+ Use setFileNames() instead.
+*/
+
+/*!
+ \fn void TQUriDrag::setFileNames(const QStringList &filenames)
+
+ Sets the URIs to be local file URIs equivalent to the \a filenames.
+
+ \sa localFileToUri(), setUris()
+*/
+void TQUriDrag::setFileNames(const QStringList & fnames)
+{
+ QList<QByteArray> uris;
+ for (QStringList::ConstIterator i = fnames.begin();
+ i != fnames.end(); ++i) {
+ QByteArray fileUri = localFileToUri(*i);
+ if (!fileUri.isEmpty())
+ uris.append(fileUri);
+ }
+
+ setUris(uris);
+}
+
+/*!
+ \fn void TQUriDrag::setFileNames(const QString &name)
+ \fn void TQUriDrag::setFilenames(const QString &name)
+
+ Same as setFileNames(QStringList(\a name)).
+*/
+
+/*!
+ \fn void TQUriDrag::setUnicodeUris(const QStringList &list)
+
+ Sets the URIs in the \a list to be Unicode URIs (only useful for
+ displaying to humans).
+
+ \sa localFileToUri(), setUris()
+*/
+void TQUriDrag::setUnicodeUris(const QStringList & uuris)
+{
+ QList<QByteArray> uris;
+ for (int i = 0; i < uuris.count(); ++i)
+ uris.append(unicodeUriToUri(uuris.at(i)));
+ setUris(uris);
+}
+
+/*!
+ \fn QByteArray TQUriDrag::unicodeUriToUri(const QString &string)
+
+ Returns the URI equivalent of the Unicode URI given in the \a string
+ (only useful for displaying to humans).
+
+ \sa uriToLocalFile()
+*/
+QByteArray TQUriDrag::unicodeUriToUri(const QString& uuri)
+{
+ QByteArray utf8 = uuri.toUtf8();
+ QByteArray escutf8;
+ int n = utf8.length();
+ bool isFile = uuri.startsWith(QLatin1String("file://"));
+ for (int i=0; i<n; i++) {
+ if ((utf8[i] >= 'a' && utf8[i] <= 'z')
+ || utf8[i] == '/'
+ || (utf8[i] >= '0' && utf8[i] <= '9')
+ || (utf8[i] >= 'A' && utf8[i] <= 'Z')
+
+ || utf8[i] == '-' || utf8[i] == '_'
+ || utf8[i] == '.' || utf8[i] == '!'
+ || utf8[i] == '~' || utf8[i] == '*'
+ || utf8[i] == '(' || utf8[i] == ')'
+ || utf8[i] == '\''
+
+ // Allow this through, so that all URI-references work.
+ || (!isFile && utf8[i] == '#')
+
+ || utf8[i] == ';'
+ || utf8[i] == '?' || utf8[i] == ':'
+ || utf8[i] == '@' || utf8[i] == '&'
+ || utf8[i] == '=' || utf8[i] == '+'
+ || utf8[i] == '$' || utf8[i] == ',')
+ {
+ escutf8 += utf8[i];
+ } else {
+ // Everything else is escaped as %HH
+ QString s;
+ s.sprintf("%%%02x",(uchar)utf8[i]);
+ escutf8 += s.latin1();
+ }
+ }
+ return escutf8;
+}
+
+/*!
+ Returns the URI equivalent to the absolute local \a filename.
+
+ \sa uriToLocalFile()
+*/
+QByteArray TQUriDrag::localFileToUri(const QString& filename)
+{
+ QString r = filename;
+
+ //check that it is an absolute file
+ if (QDir::isRelativePath(r))
+ return QByteArray();
+#ifdef Q_WS_WIN
+
+
+ bool hasHost = false;
+ // convert form network path
+ if (r.left(2) == QLatin1String("\\\\") || r.left(2) == QLatin1String("//")) {
+ r.remove(0, 2);
+ hasHost = true;
+ }
+
+ // Slosh -> Slash
+ int slosh;
+ while ((slosh=r.indexOf(QLatin1Char('\\'))) >= 0) {
+ r[slosh] = QLatin1Char('/');
+ }
+
+ // Drive
+ if (r[0] != QLatin1Char('/') && !hasHost)
+ r.insert(0,QLatin1Char('/'));
+
+#endif
+#if defined (Q_WS_X11) && 0
+ // URL without the hostname is considered to be errorneous by XDnD.
+ // See: http://www.newplanetsoftware.com/xdnd/dragging_files.html
+ // This feature is not active because this would break dnd between old and new qt apps.
+ char hostname[257];
+ if (gethostname(hostname, 255) == 0) {
+ hostname[256] = '\0';
+ r.prepend(QString::fromLatin1(hostname));
+ }
+#endif
+ return unicodeUriToUri(QLatin1String("file://") + r);
+}
+
+/*!
+ \fn QString TQUriDrag::uriToUnicodeUri(const char *string)
+
+ Returns the Unicode URI (only useful for displaying to humans)
+ equivalent of the URI given in the \a string.
+
+ Note that URIs are always in escaped UTF8 encoding.
+
+ \sa localFileToUri()
+*/
+QString TQUriDrag::uriToUnicodeUri(const char* uri)
+{
+ QByteArray utf8;
+
+ while (*uri) {
+ switch (*uri) {
+ case '%': {
+ uint ch = (uchar) uri[1];
+ if (ch && uri[2]) {
+ ch = htod(ch) * 16 + htod((uchar) uri[2]);
+ utf8 += (char) ch;
+ uri += 2;
+ }
+ }
+ break;
+ default:
+ utf8 += *uri;
+ }
+ ++uri;
+ }
+
+ return QString::fromUtf8(utf8);
+}
+
+/*!
+ \fn QString TQUriDrag::uriToLocalFile(const char *string)
+
+ Returns the name of a local file equivalent to the URI given in the
+ \a string, or an empty string if it does not refer to a local file.
+
+ Note that URIs are always in escaped UTF8 encoding.
+
+ \sa localFileToUri()
+*/
+QString TQUriDrag::uriToLocalFile(const char* uri)
+{
+ QString file;
+
+ if (!uri)
+ return file;
+ if (0==qstrnicmp(uri,"file:/",6)) // It is a local file uri
+ uri += 6;
+ else if (QString::fromLatin1(uri).indexOf(QLatin1String(":/")) != -1) // It is a different scheme uri
+ return file;
+
+ bool local = uri[0] != '/' || (uri[0] != '\0' && uri[1] == '/');
+#ifdef Q_WS_X11
+ // do we have a hostname?
+ if (!local && uri[0] == '/' && uri[2] != '/') {
+ // then move the pointer to after the 'hostname/' part of the uri
+ const char* hostname_end = strchr(uri+1, '/');
+ if (hostname_end != NULL) {
+ char hostname[257];
+ if (gethostname(hostname, 255) == 0) {
+ hostname[256] = '\0';
+ if (qstrncmp(uri+1, hostname, hostname_end - (uri+1)) == 0) {
+ uri = hostname_end + 1; // point after the slash
+ local = true;
+ }
+ }
+ }
+ }
+#endif
+ if (local) {
+ file = uriToUnicodeUri(uri);
+ if (uri[1] == '/') {
+ file.remove((uint)0,1);
+ } else {
+ file.insert(0, QLatin1Char('/'));
+ }
+#ifdef Q_WS_WIN
+ if (file.length() > 2 && file[0] == QLatin1Char('/') && file[2] == QLatin1Char('|')) {
+ file[2] = QLatin1Char(':');
+ file.remove(0,1);
+ } else if (file.length() > 2 && file[0] == QLatin1Char('/') && file[1].isLetter() && file[2] == QLatin1Char(':')) {
+ file.remove(0, 1);
+ }
+ // Leave slash as slashes.
+#endif
+ }
+#ifdef Q_WS_WIN
+ else {
+ file = uriToUnicodeUri(uri);
+ // convert to network path
+ file.insert(1, QLatin1Char('/')); // leave as forward slashes
+ }
+#endif
+
+ return file;
+}
+
+/*!
+ \fn bool TQUriDrag::decodeLocalFiles(const QMimeSource *source, QStringList &list)
+
+ Decodes URIs from the MIME \a source, converting them to local filenames
+ where possible, and places them in the \a list (which is first cleared).
+
+ Returns true if the MIME \a source contained a valid list of URIs;
+ otherwise returns false. The list will be empty if no URIs referred to
+ local files.
+*/
+bool TQUriDrag::decodeLocalFiles(const QMimeSource* e, QStringList& l)
+{
+ TQStrList u;
+ if (!decode(e, u))
+ return false;
+
+ l.clear();
+ for (uint i = 0; i < u.count(); ++i) {
+ QString lf = uriToLocalFile(u.at(i));
+ if (!lf.isEmpty())
+ l.append(lf);
+ }
+ return true;
+}
+
+/*!
+ \fn bool TQUriDrag::decodeToUnicodeUris(const QMimeSource *source, QStringList &list)
+
+ Decodes URIs from the MIME \a source, converting them to Unicode URIs
+ (only useful for displaying to humans), and places them in the \a list
+ (which is first cleared).
+
+ Returns true if the MIME \a source contained a valid list of URIs;
+ otherwise returns false.
+*/
+bool TQUriDrag::decodeToUnicodeUris(const QMimeSource* e, QStringList& l)
+{
+ TQStrList u;
+ if (!decode(e, u))
+ return false;
+
+ l.clear();
+ for (uint i = 0; i < u.count(); ++i)
+ l.append(uriToUnicodeUri(u.at(i)));
+
+ return true;
+}
+
+/*!
+ \class TQColorDrag
+
+ \brief The TQColorDrag class provides a drag and drop object for
+ transferring colors between widgets.
+
+ \compat
+
+ This class provides a drag object which can be used to transfer data
+ about colors for drag and drop and in the clipboard. For example, it
+ is used in QColorDialog.
+
+ The color is set in the constructor but can be changed with
+ setColor().
+
+ For more information about drag and drop, see the TQDragObject class
+ and the \link dnd.html drag and drop documentation\endlink.
+*/
+
+/*!
+ Constructs a color drag object with the given \a col. Passes \a
+ dragsource and \a name to the TQStoredDrag constructor.
+*/
+
+TQColorDrag::TQColorDrag(const QColor &col, QWidget *dragsource, const char *name)
+ : TQStoredDrag("application/x-color", dragsource)
+{
+ setObjectName(QLatin1String(name));
+ setColor(col);
+}
+
+/*!
+ Constructs a color drag object with a white color. Passes \a
+ dragsource and \a name to the TQStoredDrag constructor.
+*/
+
+TQColorDrag::TQColorDrag(QWidget *dragsource, const char *name)
+ : TQStoredDrag("application/x-color", dragsource)
+{
+ setObjectName(QLatin1String(name));
+ setColor(Qt::white);
+}
+
+/*!
+ \fn void TQColorDrag::setColor(const QColor &color)
+
+ Sets the \a color of the color drag.
+*/
+
+void TQColorDrag::setColor(const QColor &col)
+{
+ short r = (col.red() << 8) | col.red();
+ short g = (col.green() << 8) | col.green();
+ short b = (col.blue() << 8) | col.blue();
+
+ // make sure we transmit data in network order
+ r = htons(r);
+ g = htons(g);
+ b = htons(b);
+
+ ushort rgba[4] = {
+ r, g, b,
+ 0xffff // Alpha not supported yet.
+ };
+ QByteArray data;
+ data.resize(sizeof(rgba));
+ memcpy(data.data(), rgba, sizeof(rgba));
+ setEncodedData(data);
+}
+
+/*!
+ \fn bool TQColorDrag::canDecode(QMimeSource *source)
+
+ Returns true if the color drag object can decode the MIME \a source;
+ otherwise returns false.
+*/
+
+bool TQColorDrag::canDecode(QMimeSource *e)
+{
+ return e->provides("application/x-color");
+}
+
+/*!
+ \fn bool TQColorDrag::decode(QMimeSource *source, QColor &color)
+
+ Decodes the MIME \a source, and sets the decoded values to the
+ given \a color. Returns true if the decoding is successful.
+ Returns false if the size of the encoded data is not the
+ expected size.
+*/
+
+bool TQColorDrag::decode(QMimeSource *e, QColor &col)
+{
+ QByteArray data = e->encodedData("application/x-color");
+ ushort rgba[4];
+ if (data.size() != sizeof(rgba))
+ return false;
+
+ memcpy(rgba, data.constData(), sizeof(rgba));
+
+ short r = rgba[0];
+ short g = rgba[1];
+ short b = rgba[2];
+ short a = rgba[3];
+
+ // data is in network order
+ r = ntohs(r);
+ g = ntohs(g);
+ b = ntohs(b);
+ a = ntohs(a);
+
+ r = (r >> 8) & 0xff;
+ g = (g >> 8) & 0xff;
+ b = (b >> 8) & 0xff;
+ a = (a >> 8) & 0xff;
+
+ col.setRgb(r, g, b, a);
+ return true;
+}
+
+QT_END_NAMESPACE
+
+#else // USE_QT4
+
+/****************************************************************************
+**
+** Implementation of Drag and Drop support
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqplatformdefs.h"
+
+// POSIX Large File Support redefines open -> open64
+#if defined(open)
+# undef open
+#endif
+
+#ifndef TQT_NO_MIME
+
+#include "tqdragobject.h"
+#include "tqtextcodec.h"
+#include "tqapplication.h"
+#include "tqpoint.h"
+#include "tqwidget.h"
+#include "tqbuffer.h"
+#include "tqgif.h"
+#include "tqregexp.h"
+#include "tqdir.h"
+#include <ctype.h>
+
+// both a struct for storing stuff in and a wrapper to avoid polluting
+// the name space
+
+class TQDragObjectData
+{
+public:
+ TQDragObjectData(): hot(0,0) {}
+ TQPixmap pixmap;
+ TQPoint hot;
+ // store default cursors
+ TQPixmap *pm_cursor;
+};
+
+static TQWidget* last_target;
+
+/*!
+ After the drag completes, this function will return the TQWidget
+ which received the drop, or 0 if the data was dropped on another
+ application.
+
+ This can be useful for detecting the case where drag and drop is
+ to and from the same widget.
+*/
+TQWidget * TQDragObject::target()
+{
+ return last_target;
+}
+
+/*!
+ \internal
+ Sets the target.
+*/
+void TQDragObject::setTarget(QWidget* t)
+{
+ last_target = TQT_TQWIDGET(t);
+}
+
+class TQStoredDragData
+{
+public:
+ TQStoredDragData() {}
+ const char* fmt;
+ TQByteArray enc;
+};
+
+
+// These pixmaps approximate the images in the Windows User Interface Guidelines.
+
+// XPM
+
+static const char * const move_xpm[] = {
+"11 20 3 1",
+". c None",
+#if defined(TQ_WS_WIN)
+"a c #000000",
+"X c #FFFFFF", // Windows cursor is traditionally white
+#else
+"a c #FFFFFF",
+"X c #000000", // X11 cursor is traditionally black
+#endif
+"aa.........",
+"aXa........",
+"aXXa.......",
+"aXXXa......",
+"aXXXXa.....",
+"aXXXXXa....",
+"aXXXXXXa...",
+"aXXXXXXXa..",
+"aXXXXXXXXa.",
+"aXXXXXXXXXa",
+"aXXXXXXaaaa",
+"aXXXaXXa...",
+"aXXaaXXa...",
+"aXa..aXXa..",
+"aa...aXXa..",
+"a.....aXXa.",
+"......aXXa.",
+".......aXXa",
+".......aXXa",
+"........aa."};
+
+/* XPM */
+static const char * const copy_xpm[] = {
+"24 30 3 1",
+". c None",
+"a c #000000",
+"X c #FFFFFF",
+#if defined(TQ_WS_WIN) // Windows cursor is traditionally white
+"aa......................",
+"aXa.....................",
+"aXXa....................",
+"aXXXa...................",
+"aXXXXa..................",
+"aXXXXXa.................",
+"aXXXXXXa................",
+"aXXXXXXXa...............",
+"aXXXXXXXXa..............",
+"aXXXXXXXXXa.............",
+"aXXXXXXaaaa.............",
+"aXXXaXXa................",
+"aXXaaXXa................",
+"aXa..aXXa...............",
+"aa...aXXa...............",
+"a.....aXXa..............",
+"......aXXa..............",
+".......aXXa.............",
+".......aXXa.............",
+"........aa...aaaaaaaaaaa",
+#else
+"XX......................",
+"XaX.....................",
+"XaaX....................",
+"XaaaX...................",
+"XaaaaX..................",
+"XaaaaaX.................",
+"XaaaaaaX................",
+"XaaaaaaaX...............",
+"XaaaaaaaaX..............",
+"XaaaaaaaaaX.............",
+"XaaaaaaXXXX.............",
+"XaaaXaaX................",
+"XaaXXaaX................",
+"XaX..XaaX...............",
+"XX...XaaX...............",
+"X.....XaaX..............",
+"......XaaX..............",
+".......XaaX.............",
+".......XaaX.............",
+"........XX...aaaaaaaaaaa",
+#endif
+".............aXXXXXXXXXa",
+".............aXXXXXXXXXa",
+".............aXXXXaXXXXa",
+".............aXXXXaXXXXa",
+".............aXXaaaaaXXa",
+".............aXXXXaXXXXa",
+".............aXXXXaXXXXa",
+".............aXXXXXXXXXa",
+".............aXXXXXXXXXa",
+".............aaaaaaaaaaa"};
+
+/* XPM */
+static const char * const link_xpm[] = {
+"24 30 3 1",
+". c None",
+"a c #000000",
+"X c #FFFFFF",
+#if defined(TQ_WS_WIN) // Windows cursor is traditionally white
+"aa......................",
+"aXa.....................",
+"aXXa....................",
+"aXXXa...................",
+"aXXXXa..................",
+"aXXXXXa.................",
+"aXXXXXXa................",
+"aXXXXXXXa...............",
+"aXXXXXXXXa..............",
+"aXXXXXXXXXa.............",
+"aXXXXXXaaaa.............",
+"aXXXaXXa................",
+"aXXaaXXa................",
+"aXa..aXXa...............",
+"aa...aXXa...............",
+"a.....aXXa..............",
+"......aXXa..............",
+".......aXXa.............",
+".......aXXa.............",
+"........aa...aaaaaaaaaaa",
+#else
+"XX......................",
+"XaX.....................",
+"XaaX....................",
+"XaaaX...................",
+"XaaaaX..................",
+"XaaaaaX.................",
+"XaaaaaaX................",
+"XaaaaaaaX...............",
+"XaaaaaaaaX..............",
+"XaaaaaaaaaX.............",
+"XaaaaaaXXXX.............",
+"XaaaXaaX................",
+"XaaXXaaX................",
+"XaX..XaaX...............",
+"XX...XaaX...............",
+"X.....XaaX..............",
+"......XaaX..............",
+".......XaaX.............",
+".......XaaX.............",
+"........XX...aaaaaaaaaaa",
+#endif
+".............aXXXXXXXXXa",
+".............aXXXaaaaXXa",
+".............aXXXXaaaXXa",
+".............aXXXaaaaXXa",
+".............aXXaaaXaXXa",
+".............aXXaaXXXXXa",
+".............aXXaXXXXXXa",
+".............aXXXaXXXXXa",
+".............aXXXXXXXXXa",
+".............aaaaaaaaaaa"};
+
+#ifndef TQT_NO_DRAGANDDROP
+
+// the universe's only drag manager
+TQDragManager * qt_dnd_manager = 0;
+
+
+TQDragManager::TQDragManager()
+ : TQObject( TQT_TQOBJECT(tqApp), "global drag manager" )
+{
+ n_cursor = 3;
+ pm_cursor = new TQPixmap[n_cursor];
+ pm_cursor[0] = TQPixmap((const char **)move_xpm);
+ pm_cursor[1] = TQPixmap((const char **)copy_xpm);
+ pm_cursor[2] = TQPixmap((const char **)link_xpm);
+#if defined(TQ_WS_X11)
+ createCursors(); // Xcursors cache can hold only 8 bitmaps (4 cursors)
+#endif
+ object = 0;
+ dragSource = 0;
+ dropWidget = 0;
+ if ( !qt_dnd_manager )
+ qt_dnd_manager = this;
+ beingCancelled = FALSE;
+ restoreCursor = FALSE;
+ willDrop = FALSE;
+}
+
+
+TQDragManager::~TQDragManager()
+{
+#ifndef TQT_NO_CURSOR
+ if ( restoreCursor )
+ TQApplication::restoreOverrideCursor();
+#endif
+ qt_dnd_manager = 0;
+ delete [] pm_cursor;
+}
+
+#endif
+
+
+/*!
+ Constructs a drag object called \a name, which is a child of \a
+ dragSource.
+
+ Note that the drag object will be deleted when \a dragSource is
+ deleted.
+*/
+
+TQDragObject::TQDragObject( QWidget * dragSource, const char * name )
+ : TQObject( TQT_TQOBJECT(dragSource), name )
+{
+ d = new TQDragObjectData();
+ d->pm_cursor = 0;
+#ifndef TQT_NO_DRAGANDDROP
+ if ( !qt_dnd_manager && tqApp )
+ (void)new TQDragManager();
+#endif
+}
+
+
+/*!
+ Destroys the drag object, canceling any drag and drop operation in
+ which it is involved, and frees up the storage used.
+*/
+
+TQDragObject::~TQDragObject()
+{
+#ifndef TQT_NO_DRAGANDDROP
+ if ( qt_dnd_manager && qt_dnd_manager->object == this )
+ qt_dnd_manager->cancel( FALSE );
+ if ( d->pm_cursor ) {
+ for ( int i = 0; i < qt_dnd_manager->n_cursor; i++ )
+ qt_dnd_manager->pm_cursor[i] = d->pm_cursor[i];
+ delete [] d->pm_cursor;
+ }
+#endif
+ delete d;
+}
+
+#ifndef TQT_NO_DRAGANDDROP
+/*!
+ Set the pixmap \a pm to display while dragging the object. The
+ platform-specific implementation will use this where it can - so
+ provide a small masked pixmap, and do not assume that the user
+ will actually see it. For example, cursors on Windows 95 are of
+ limited size.
+
+ The \a hotspot is the point on (or off) the pixmap that should be
+ under the cursor as it is dragged. It is relative to the top-left
+ pixel of the pixmap.
+
+ \warning We have seen problems with drag cursors on different
+ graphics hardware and driver software on Windows. Setting the
+ graphics acceleration in the display settings down one tick solved
+ the problems in all cases.
+*/
+void TQDragObject::setPixmap(QPixmap pm, const QPoint& hotspot)
+{
+ d->pixmap = pm;
+ d->hot = hotspot;
+ if ( qt_dnd_manager && qt_dnd_manager->object == this )
+ qt_dnd_manager->updatePixmap();
+}
+
+/*!
+ \overload
+ Uses a hotspot that positions the pixmap below and to the right of
+ the mouse pointer. This allows the user to clearly see the point
+ on the window which they are dragging the data onto.
+*/
+void TQDragObject::setPixmap(QPixmap pm)
+{
+ setPixmap(pm,TQPoint(-10, -10));
+}
+
+/*!
+ Returns the currently set pixmap (which \link TQPixmap::isNull()
+ isNull()\endlink if none is set).
+*/
+TQPixmap TQDragObject::pixmap() const
+{
+ return d->pixmap;
+}
+
+/*!
+ Returns the currently set pixmap hotspot.
+*/
+TQPoint TQDragObject::pixmapHotSpot() const
+{
+ return d->hot;
+}
+
+#if 0
+
+// ## reevaluate for TQt 4
+/*!
+ Set the \a cursor used when dragging in mode \a m.
+ Note: X11 only allow bitmaps for cursors.
+*/
+void TQDragObject::setCursor( DragMode m, const TQPixmap &cursor )
+{
+ if ( d->pm_cursor == 0 ) {
+ // safe default cursors
+ d->pm_cursor = new TQPixmap[qt_dnd_manager->n_cursor];
+ for ( int i = 0; i < qt_dnd_manager->n_cursor; i++ )
+ d->pm_cursor[i] = qt_dnd_manager->pm_cursor[i];
+ }
+
+ int index;
+ switch ( m ) {
+ case DragCopy:
+ index = 1;
+ break;
+ case DragLink:
+ index = 2;
+ break;
+ default:
+ index = 0;
+ break;
+ }
+
+ // override default cursor
+ for ( index = 0; index < qt_dnd_manager->n_cursor; index++ )
+ qt_dnd_manager->pm_cursor[index] = cursor;
+}
+
+/*!
+ Returns the cursor used when dragging in mode \a m, or null if no cursor
+ has been set for that mode.
+*/
+TQPixmap *TQDragObject::cursor( DragMode m ) const
+{
+ if ( !d->pm_cursor )
+ return 0;
+
+ int index;
+ switch ( m ) {
+ case DragCopy:
+ index = 1;
+ break;
+ case DragLink:
+ index = 2;
+ break;
+ default:
+ index = 0;
+ break;
+ }
+
+ return qt_dnd_manager->pm_cursor+index;
+}
+
+#endif // 0
+
+/*!
+ Starts a drag operation using the contents of this object, using
+ DragDefault mode.
+
+ The function returns TRUE if the caller should delete the original
+ copy of the dragged data (but see target()); otherwise returns
+ FALSE.
+
+ If the drag tqcontains \e references to information (e.g. file names
+ in a TQUriDrag are references) then the return value should always
+ be ignored, as the target is expected to manipulate the
+ referred-to content directly. On X11 the return value should
+ always be correct anyway, but on Windows this is not necessarily
+ the case (e.g. the file manager starts a background process to
+ move files, so the source \e{must not} delete the files!)
+*/
+bool TQDragObject::drag()
+{
+ return drag( DragDefault );
+}
+
+
+/*!
+ Starts a drag operation using the contents of this object, using
+ \c DragMove mode. Be sure to read the constraints described in
+ drag().
+
+ \sa drag() dragCopy() dragLink()
+*/
+bool TQDragObject::dragMove()
+{
+ return drag( DragMove );
+}
+
+
+/*!
+ Starts a drag operation using the contents of this object, using
+ \c DragCopy mode. Be sure to read the constraints described in
+ drag().
+
+ \sa drag() dragMove() dragLink()
+*/
+void TQDragObject::dragCopy()
+{
+ (void)drag( DragCopy );
+}
+
+/*!
+ Starts a drag operation using the contents of this object, using
+ \c DragLink mode. Be sure to read the constraints described in
+ drag().
+
+ \sa drag() dragCopy() dragMove()
+*/
+void TQDragObject::dragLink()
+{
+ (void)drag( DragLink );
+}
+
+
+/*!
+ \enum TQDragObject::DragMode
+
+ This enum describes the possible drag modes.
+
+ \value DragDefault The mode is determined heuristically.
+ \value DragCopy The data is copied, never moved.
+ \value DragMove The data is moved, if dragged at all.
+ \value DragLink The data is linked, if dragged at all.
+ \value DragCopyOrMove The user chooses the mode by using a
+ control key to switch from the default.
+*/
+
+
+/*!
+ \overload
+ Starts a drag operation using the contents of this object.
+
+ At this point, the object becomes owned by TQt, not the
+ application. You should not delete the drag object or anything it
+ references. The actual transfer of data to the target application
+ will be done during future event processing - after that time the
+ drag object will be deleted.
+
+ Returns TRUE if the dragged data was dragged as a \e move,
+ indicating that the caller should remove the original source of
+ the data (the drag object must continue to have a copy); otherwise
+ returns FALSE.
+
+ The \a mode specifies the drag mode (see
+ \l{TQDragObject::DragMode}.) Normally one of the simpler drag(),
+ dragMove(), or dragCopy() functions would be used instead.
+*/
+bool TQDragObject::drag( DragMode mode )
+{
+ if ( qt_dnd_manager )
+ return qt_dnd_manager->drag( this, mode );
+ else
+ return FALSE;
+}
+
+#endif
+
+
+/*!
+ Returns a pointer to the drag source where this object originated.
+*/
+
+TQWidget * TQDragObject::source()
+{
+ if ( tqparent() && tqparent()->isWidgetType() )
+ return (TQWidget *)tqparent();
+ else
+ return 0;
+}
+
+
+/*!
+ \class TQDragObject tqdragobject.h
+
+ \brief The TQDragObject class encapsulates MIME-based data
+ transfer.
+
+ \ingroup draganddrop
+
+ TQDragObject is the base class for all data that needs to be
+ transferred between and within applications, both for drag and
+ drop and for the \link tqclipboard.html clipboard\endlink.
+
+ See the \link dnd.html Drag-and-drop documentation\endlink for an
+ overview of how to provide drag and drop in your application.
+
+ See the TQClipboard documentation for an overview of how to provide
+ cut-and-paste in your application.
+
+ The drag() function is used to start a drag operation. You can
+ specify the \l DragMode in the call or use one of the convenience
+ functions dragCopy(), dragMove() or dragLink(). The drag source
+ where the data originated is retrieved with source(). If the data
+ was dropped on a widget within the application, target() will
+ return a pointer to that widget. Specify the pixmap to display
+ during the drag with setPixmap().
+*/
+
+static
+void stripws(TQCString& s)
+{
+ int f;
+ while ( (f=s.tqfind(' ')) >= 0 )
+ s.remove(f,1);
+}
+
+static
+const char * staticCharset(int i)
+{
+ static TQCString localcharset;
+
+ switch ( i ) {
+ case 0:
+ return "UTF-8";
+ case 1:
+ return "ISO-10646-UCS-2";
+ case 2:
+ return ""; // in the 3rd place - some Xdnd targets might only look at 3
+ case 3:
+ if ( localcharset.isNull() ) {
+ TQTextCodec *localCodec = TQTextCodec::codecForLocale();
+ if ( localCodec ) {
+ localcharset = localCodec->name();
+ localcharset = localcharset.lower();
+ stripws(localcharset);
+ } else {
+ localcharset = "";
+ }
+ }
+ return localcharset;
+ }
+ return 0;
+}
+
+
+class TQTextDragPrivate {
+public:
+ TQTextDragPrivate();
+
+ enum { nfmt=4 };
+
+ TQString txt;
+ TQCString fmt[nfmt];
+ TQCString subtype;
+
+ void setSubType(const TQCString & st)
+ {
+ subtype = st.lower();
+ for ( int i=0; i<nfmt; i++ ) {
+ fmt[i] = "text/";
+ fmt[i].append(subtype);
+ TQCString cs = staticCharset(i);
+ if ( !cs.isEmpty() ) {
+ fmt[i].append(";charset=");
+ fmt[i].append(cs);
+ }
+ }
+ }
+};
+
+inline TQTextDragPrivate::TQTextDragPrivate()
+{
+ setSubType("plain");
+}
+
+/*!
+ Sets the MIME subtype of the text being dragged to \a st. The
+ default subtype is "plain", so the default MIME type of the text
+ is "text/plain". You might use this to declare that the text is
+ "text/html" by calling setSubtype("html").
+*/
+void TQTextDrag::setSubtype( const TQCString & st)
+{
+ d->setSubType(st);
+}
+
+/*!
+ \class TQTextDrag tqdragobject.h
+
+ \brief The TQTextDrag class is a drag and drop object for
+ transferring plain and Unicode text.
+
+ \ingroup draganddrop
+
+ Plain text is passed in a TQString which may contain multiple lines
+ (i.e. may contain newline characters). The drag target will receive
+ the newlines according to the runtime environment, e.g. LF on Unix,
+ and CRLF on Windows.
+
+ TQt provides no built-in mechanism for delivering only a single-line.
+
+ For more information about drag and drop, see the TQDragObject class
+ and the \link dnd.html drag and drop documentation\endlink.
+*/
+
+
+/*!
+ Constructs a text drag object and sets its data to \a text. \a
+ dragSource must be the drag source; \a name is the object name.
+*/
+
+TQTextDrag::TQTextDrag( const TQString &text,
+ TQWidget * dragSource, const char * name )
+ : TQDragObject( dragSource, name )
+{
+ d = new TQTextDragPrivate;
+ setText( text );
+}
+
+
+/*!
+ Constructs a default text drag object. \a dragSource must be the
+ drag source; \a name is the object name.
+*/
+
+TQTextDrag::TQTextDrag( TQWidget * dragSource, const char * name )
+ : TQDragObject( dragSource, name )
+{
+ d = new TQTextDragPrivate;
+}
+
+
+/*!
+ Destroys the text drag object and frees up all allocated
+ resources.
+*/
+TQTextDrag::~TQTextDrag()
+{
+ delete d;
+}
+
+
+/*!
+ Sets the text to be dragged to \a text. You will need to call this
+ if you did not pass the text during construction.
+*/
+void TQTextDrag::setText( const TQString &text )
+{
+ d->txt = text;
+}
+
+
+/*!
+ \reimp
+*/
+const char * TQTextDrag::format(int i) const
+{
+ if ( i >= d->nfmt )
+ return 0;
+ return d->fmt[i];
+}
+
+TQTextCodec* qt_tqfindcharset(const TQCString& mimetype)
+{
+ int i=mimetype.tqfind("charset=");
+ if ( i >= 0 ) {
+ TQCString cs = mimetype.mid(i+8);
+ stripws(cs);
+ i = cs.tqfind(';');
+ if ( i >= 0 )
+ cs = cs.left(i);
+ // win98 often has charset=utf16, and we need to get the correct codec for
+ // it to be able to get Unicode text drops.
+ if ( cs == "utf16" )
+ cs = "ISO-10646-UCS-2";
+ // May return 0 if unknown charset
+ return TQTextCodec::codecForName(cs);
+ }
+ // no charset=, use locale
+ return TQTextCodec::codecForLocale();
+}
+
+static TQTextCodec *codecForHTML(const TQCString &ba)
+{
+ // determine charset
+ int mib = 0;
+ int pos;
+ TQTextCodec *c = 0;
+
+ if (ba.size() > 1 && (((uchar)ba[0] == 0xfe && (uchar)ba[1] == 0xff)
+ || ((uchar)ba[0] == 0xff && (uchar)ba[1] == 0xfe))) {
+ mib = 1000; // utf16
+ } else if (ba.size() > 2
+ && (uchar)ba[0] == 0xef
+ && (uchar)ba[1] == 0xbb
+ && (uchar)ba[2] == 0xbf) {
+ mib = 106; // utf-8
+ } else {
+ pos = 0;
+ while ((pos = ba.tqfind("<meta http-equiv=", pos, FALSE)) != -1) {
+ int end = ba.tqfind('>', pos+1);
+ if (end == -1)
+ break;
+ pos = ba.tqfind("charset=", pos, FALSE) + (int)strlen("charset=");
+ if (pos != -1 && pos < end) {
+ int pos2 = ba.tqfind('\"', pos+1);
+ TQCString cs = ba.mid(pos, pos2-pos);
+ c = TQTextCodec::codecForName(cs);
+ if (c)
+ return c;
+ }
+ pos = end;
+ }
+ }
+ if (mib)
+ c = TQTextCodec::codecForMib(mib);
+
+ return c;
+}
+
+static
+TQTextCodec* tqfindcodec(const TQMimeSource* e)
+{
+ TQTextCodec* r = 0;
+ const char* f;
+ int i;
+ for ( i=0; (f=e->format(i)); i++ ) {
+ bool html = !qstrnicmp(f, "text/html", 9);
+ if (html)
+ r = codecForHTML(TQCString(e->tqencodedData(f)));
+ if (!r)
+ r = qt_tqfindcharset(TQCString(f).lower());
+ if (r)
+ return r;
+ }
+ return 0;
+}
+
+
+
+/*!
+ \reimp
+*/
+TQByteArray TQTextDrag::tqencodedData(const char* mime) const
+{
+ TQCString r;
+ if ( 0==qstrnicmp(mime,"text/",5) ) {
+ TQCString m(mime);
+ m = m.lower();
+ TQTextCodec *codec = qt_tqfindcharset(m);
+ if ( !codec )
+ return r;
+ TQString text( d->txt );
+#if defined(TQ_WS_WIN)
+ int index = text.tqfind( TQString::tqfromLatin1("\r\n"), 0 );
+ while ( index != -1 ) {
+ text.tqreplace( index, 2, TQChar('\n') );
+ index = text.tqfind( "\r\n", index );
+ }
+#endif
+ r = codec->fromUnicode(text);
+ if (!codec || codec->mibEnum() != 1000) {
+ // Don't include NUL in size (TQCString::resize() adds NUL)
+#if defined(TQ_WS_WIN)
+ // This is needed to ensure the \0 isn't lost on Windows 95
+ if ( qWinVersion() & TQt::WV_DOS_based )
+ ((TQByteArray&)r).resize(r.length()+1);
+ else
+#endif
+ ((TQByteArray&)r).resize(r.length());
+ }
+ }
+ return r;
+}
+
+/*!
+ Returns TRUE if the information in \a e can be decoded into a
+ TQString; otherwise returns FALSE.
+
+ \sa decode()
+*/
+bool TQTextDrag::canDecode( const TQMimeSource* e )
+{
+ const char* f;
+ for (int i=0; (f=e->format(i)); i++) {
+ if ( 0==qstrnicmp(f,"text/",5) ) {
+ return tqfindcodec(e) != 0;
+ }
+ }
+ return 0;
+}
+
+/*!
+ \overload
+
+ Attempts to decode the dropped information in \a e into \a str.
+ Returns TRUE if successful; otherwise returns FALSE. If \a subtype
+ is null, any text subtype is accepted; otherwise only the
+ specified \a subtype is accepted.
+
+ \sa canDecode()
+*/
+bool TQTextDrag::decode( const TQMimeSource* e, TQString& str, TQCString& subtype )
+{
+ if(!e)
+ return FALSE;
+
+ if ( e->cacheType == TQMimeSource::Text ) {
+ str = *e->cache.txt.str;
+ subtype = *e->cache.txt.subtype;
+ return TRUE;
+ }
+
+ const char* mime;
+ for (int i=0; (mime = e->format(i)); i++) {
+ if ( 0==qstrnicmp(mime,"text/",5) ) {
+ TQCString m(mime);
+ m = m.lower();
+ int semi = m.tqfind(';');
+ if ( semi < 0 )
+ semi = m.length();
+ TQCString foundst = m.mid(5,semi-5);
+ if ( subtype.isNull() || foundst == subtype ) {
+ bool html = !qstrnicmp(mime, "text/html", 9);
+ TQTextCodec* codec = 0;
+ if (html) {
+ TQByteArray bytes = e->tqencodedData(mime);
+ // search for the charset tag in the HTML
+ codec = codecForHTML(TQCString(bytes.data(), bytes.size()));
+ }
+ if (!codec)
+ codec = qt_tqfindcharset(m);
+ if ( codec ) {
+ TQByteArray payload;
+
+ payload = e->tqencodedData(mime);
+ if ( payload.size() ) {
+ int l;
+ if ( codec->mibEnum() != 1000) {
+ // length is at NUL or payload.size()
+ l = 0;
+ while ( l < (int)payload.size() && payload[l] )
+ l++;
+ } else {
+ l = payload.size();
+ }
+
+ str = codec->toUnicode(payload,l);
+
+ if ( subtype.isNull() )
+ subtype = foundst;
+
+ TQMimeSource *m = (TQMimeSource*)e;
+ m->clearCache();
+ m->cacheType = TQMimeSource::Text;
+ m->cache.txt.str = new TQString( str );
+ m->cache.txt.subtype = new TQCString( subtype );
+
+ return TRUE;
+ }
+ }
+ }
+ }
+ }
+ return FALSE;
+}
+
+/*!
+ Attempts to decode the dropped information in \a e into \a str.
+ Returns TRUE if successful; otherwise returns FALSE.
+
+ \sa canDecode()
+*/
+bool TQTextDrag::decode( const TQMimeSource* e, TQString& str )
+{
+ TQCString st;
+ return decode(e,str,st);
+}
+
+
+/*
+ TQImageDrag could use an internal MIME type for communicating TQPixmaps
+ and TQImages rather than always converting to raw data. This is available
+ for that purpose and others. It is not currently used.
+*/
+class TQImageDragData
+{
+public:
+};
+
+
+/*!
+ \class TQImageDrag tqdragobject.h
+
+ \brief The TQImageDrag class provides a drag and drop object for
+ transferring images.
+
+ \ingroup draganddrop
+
+ Images are offered to the receiving application in multiple
+ formats, determined by TQt's \link TQImage::outputFormats() output
+ formats\endlink.
+
+ For more information about drag and drop, see the TQDragObject
+ class and the \link dnd.html drag and drop documentation\endlink.
+*/
+
+/*!
+ Constructs an image drag object and sets its data to \a image. \a
+ dragSource must be the drag source; \a name is the object name.
+*/
+
+TQImageDrag::TQImageDrag( QImage image,
+ QWidget * dragSource, const char * name )
+ : TQDragObject( dragSource, name ),
+ d(0)
+{
+ setImage( image );
+}
+
+/*!
+ Constructs a default image drag object. \a dragSource must be the
+ drag source; \a name is the object name.
+*/
+
+TQImageDrag::TQImageDrag( QWidget * dragSource, const char * name )
+ : TQDragObject( dragSource, name ),
+ d(0)
+{
+}
+
+
+/*!
+ Destroys the image drag object and frees up all allocated
+ resources.
+*/
+
+TQImageDrag::~TQImageDrag()
+{
+ // nothing
+}
+
+
+/*!
+ Sets the image to be dragged to \a image. You will need to call
+ this if you did not pass the image during construction.
+*/
+void TQImageDrag::setImage( QImage image )
+{
+ img = image; // ### detach?
+ ofmts = TQImage::outputFormats();
+ ofmts.remove("PBM"); // remove non-raw PPM
+ if ( image.depth()!=32 ) {
+ // BMP better than PPM for paletted images
+ if ( ofmts.remove("BMP") ) // move to front
+ ofmts.insert(0,"BMP");
+ }
+ // PNG is best of all
+ if ( ofmts.remove("PNG") ) // move to front
+ ofmts.insert(0,"PNG");
+
+ if(cacheType == TQMimeSource::NoCache) { //cache it
+ cacheType = TQMimeSource::Graphics;
+ cache.gfx.img = new TQImage( img );
+ cache.gfx.pix = 0;
+ }
+}
+
+/*!
+ \reimp
+*/
+const char * TQImageDrag::format(int i) const
+{
+ if ( i < (int)ofmts.count() ) {
+ static TQCString str;
+ str.sprintf("image/%s",(((TQImageDrag*)this)->ofmts).at(i));
+ str = str.lower();
+ if ( str == "image/pbmraw" )
+ str = "image/ppm";
+ return str;
+ } else {
+ return 0;
+ }
+}
+
+/*!
+ \reimp
+*/
+TQByteArray TQImageDrag::tqencodedData(const char* fmt) const
+{
+ if ( qstrnicmp( fmt, "image/", 6 )==0 ) {
+ TQCString f = fmt+6;
+ TQByteArray data;
+ TQBuffer w( data );
+ w.open( IO_WriteOnly );
+ TQImageIO io( &w, f.upper() );
+ io.setImage( img );
+ if ( !io.write() )
+ return TQByteArray();
+ w.close();
+ return data;
+ } else {
+ return TQByteArray();
+ }
+}
+
+/*!
+ Returns TRUE if the information in mime source \a e can be decoded
+ into an image; otherwise returns FALSE.
+
+ \sa decode()
+*/
+bool TQImageDrag::canDecode( const TQMimeSource* e ) {
+ TQStrList fileFormats = TQImageIO::inputFormats();
+
+ fileFormats.first();
+ while ( fileFormats.current()) {
+ TQCString format = fileFormats.current();
+ TQCString type = "image/" + format.lower();
+ if ( e->provides(type.data()))
+ return TRUE;
+ fileFormats.next();
+ }
+
+ return FALSE;
+}
+
+/*!
+ Attempts to decode the dropped information in mime source \a e
+ into \a img. Returns TRUE if successful; otherwise returns FALSE.
+
+ \sa canDecode()
+*/
+bool TQImageDrag::decode( const TQMimeSource* e, QImage& img )
+{
+ if ( !e )
+ return FALSE;
+ if ( e->cacheType == TQMimeSource::Graphics ) {
+ img = *e->cache.gfx.img;
+ return TRUE;
+ }
+
+ TQByteArray payload;
+ TQStrList fileFormats = TQImageIO::inputFormats();
+ // PNG is best of all
+ if ( fileFormats.remove("PNG") ) // move to front
+ fileFormats.insert(0,"PNG");
+ fileFormats.first();
+ while ( fileFormats.current() ) {
+ TQCString format = fileFormats.current();
+ fileFormats.next();
+
+ TQCString type = "image/" + format.lower();
+ if ( ! e->provides( type.data() ) ) continue;
+ payload = e->tqencodedData( type.data() );
+ if ( !payload.isEmpty() )
+ break;
+ }
+
+ if ( payload.isEmpty() )
+ return FALSE;
+
+ img.loadFromData(payload);
+ if ( img.isNull() )
+ return FALSE;
+ TQMimeSource *m = (TQMimeSource*)e;
+ m->clearCache();
+ m->cacheType = TQMimeSource::Graphics;
+ m->cache.gfx.img = new TQImage( img );
+ m->cache.gfx.pix = 0;
+ return TRUE;
+}
+
+/*!
+ \overload
+
+ Attempts to decode the dropped information in mime source \a e
+ into pixmap \a pm. Returns TRUE if successful; otherwise returns
+ FALSE.
+
+ This is a convenience function that converts to a TQPixmap via a
+ TQImage.
+
+ \sa canDecode()
+*/
+bool TQImageDrag::decode( const TQMimeSource* e, QPixmap& pm )
+{
+ if ( !e )
+ return FALSE;
+
+ if ( e->cacheType == TQMimeSource::Graphics && e->cache.gfx.pix) {
+ pm = *e->cache.gfx.pix;
+ return TRUE;
+ }
+
+ TQImage img;
+ // We avoid dither, since the image probably came from this display
+ if ( decode( e, img ) ) {
+ if ( !pm.convertFromImage( img, Qt::AvoidDither ) )
+ return FALSE;
+ // decode initialized the cache for us
+
+ TQMimeSource *m = (TQMimeSource*)e;
+ m->cache.gfx.pix = new TQPixmap( pm );
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+
+
+/*!
+ \class TQStoredDrag tqdragobject.h
+ \brief The TQStoredDrag class provides a simple stored-value drag object for arbitrary MIME data.
+
+ \ingroup draganddrop
+
+ When a block of data has only one representation, you can use a
+ TQStoredDrag to hold it.
+
+ For more information about drag and drop, see the TQDragObject
+ class and the \link dnd.html drag and drop documentation\endlink.
+*/
+
+/*!
+ Constructs a TQStoredDrag. The \a dragSource and \a name are passed
+ to the TQDragObject constructor, and the format is set to \a
+ mimeType.
+
+ The data will be unset. Use setEncodedData() to set it.
+*/
+TQStoredDrag::TQStoredDrag( const char* mimeType, QWidget * dragSource, const char * name ) :
+ TQDragObject(dragSource,name)
+{
+ d = new TQStoredDragData();
+ d->fmt = qstrdup(mimeType);
+}
+
+/*!
+ Destroys the drag object and frees up all allocated resources.
+*/
+TQStoredDrag::~TQStoredDrag()
+{
+ delete [] (char*)d->fmt;
+ delete d;
+}
+
+/*!
+ \reimp
+*/
+const char * TQStoredDrag::format(int i) const
+{
+ if ( i==0 )
+ return d->fmt;
+ else
+ return 0;
+}
+
+
+/*!
+ Sets the encoded data of this drag object to \a tqencodedData. The
+ encoded data is what's delivered to the drop sites. It must be in
+ a strictly defined and portable format.
+
+ The drag object can't be dropped (by the user) until this function
+ has been called.
+*/
+
+void TQStoredDrag::setEncodedData( const TQByteArray & tqencodedData )
+{
+ d->enc = tqencodedData.copy();
+}
+
+/*!
+ Returns the stored data. \a m tqcontains the data's format.
+
+ \sa setEncodedData()
+*/
+TQByteArray TQStoredDrag::tqencodedData(const char* m) const
+{
+ if ( !qstricmp(m,d->fmt) )
+ return d->enc;
+ else
+ return TQByteArray();
+}
+
+
+/*!
+ \class TQUriDrag tqdragobject.h
+ \brief The TQUriDrag class provides a drag object for a list of URI references.
+
+ \ingroup draganddrop
+
+ URIs are a useful way to refer to files that may be distributed
+ across multiple machines. A URI will often refer to a file on a
+ machine local to both the drag source and the drop target, so the
+ URI can be equivalent to passing a file name but is more
+ extensible.
+
+ Use URIs in Unicode form so that the user can comfortably edit and
+ view them. For use in HTTP or other protocols, use the correctly
+ escaped ASCII form.
+
+ You can convert a list of file names to file URIs using
+ setFileNames(), or into human-readble form with setUnicodeUris().
+
+ Static functions are provided to convert between filenames and
+ URIs, e.g. uriToLocalFile() and localFileToUri(), and to and from
+ human-readable form, e.g. uriToUnicodeUri(), tqunicodeUriToUri().
+ You can also decode URIs from a mimesource into a list with
+ decodeLocalFiles() and decodeToUnicodeUris().
+*/
+
+/*!
+ Constructs an object to drag the list of URIs in \a uris. The \a
+ dragSource and \a name arguments are passed on to TQStoredDrag.
+ Note that URIs are always in escaped UTF8 encoding.
+*/
+TQUriDrag::TQUriDrag( TQStrList uris,
+ TQWidget * dragSource, const char * name ) :
+ TQStoredDrag( "text/uri-list", dragSource, name )
+{
+ setUris(uris);
+}
+
+/*!
+ Constructs an object to drag. You must call setUris() before you
+ start the drag(). Passes \a dragSource and \a name to the
+ TQStoredDrag constructor.
+*/
+TQUriDrag::TQUriDrag( TQWidget * dragSource, const char * name ) :
+ TQStoredDrag( "text/uri-list", dragSource, name )
+{
+}
+
+/*!
+ Destroys the object.
+*/
+TQUriDrag::~TQUriDrag()
+{
+}
+
+/*!
+ Changes the list of \a uris to be dragged.
+
+ Note that URIs are always in escaped UTF8 encoding.
+*/
+void TQUriDrag::setUris( TQStrList uris )
+{
+ TQByteArray a;
+ int c=0;
+ for ( const char* s = uris.first(); s; s = uris.next() ) {
+ int l = tqstrlen(s);
+ a.resize(c+l+2);
+ memcpy(a.data()+c,s,l);
+ memcpy(a.data()+c+l,"\r\n",2);
+ c+=l+2;
+ }
+ a.resize(c+1);
+ a[c] = 0;
+ setEncodedData(a);
+}
+
+
+/*!
+ Returns TRUE if decode() would be able to decode \a e; otherwise
+ returns FALSE.
+*/
+bool TQUriDrag::canDecode( const TQMimeSource* e )
+{
+ return e->provides( "text/uri-list" );
+}
+
+/*!
+ Decodes URIs from \a e, placing the result in \a l (which is first
+ cleared).
+
+ Returns TRUE if \a e contained a valid list of URIs; otherwise
+ returns FALSE.
+*/
+bool TQUriDrag::decode( const TQMimeSource* e, TQStrList& l )
+{
+ TQByteArray payload = e->tqencodedData( "text/uri-list" );
+ if ( payload.size() ) {
+ l.clear();
+ l.setAutoDelete(TRUE);
+ uint c=0;
+ const char* d = payload.data();
+ while (c < payload.size() && d[c]) {
+ uint f = c;
+ // Find line end
+ while (c < payload.size() && d[c] && d[c]!='\r'
+ && d[c] != '\n')
+ c++;
+ TQCString s(d+f,c-f+1);
+ if ( s[0] != '#' ) // non-comment?
+ l.append( s );
+ // Skip junk
+ while (c < payload.size() && d[c] &&
+ (d[c]=='\n' || d[c]=='\r'))
+ c++;
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static uint htod( int h )
+{
+ if ( isdigit(h) )
+ return h - '0';
+ return tolower( h ) - 'a' + 10;
+}
+
+/*!
+ \fn TQUriDrag::setFilenames( const TQStringList & )
+ \obsolete
+
+ Use setFileNames() instead (notice the N).
+*/
+
+/*!
+ Sets the URIs to be the local-file URIs equivalent to \a fnames.
+
+ \sa localFileToUri(), setUris()
+*/
+void TQUriDrag::setFileNames( const TQStringList & fnames )
+{
+ TQStrList uris;
+ for ( TQStringList::ConstIterator i = fnames.begin();
+ i != fnames.end(); ++i ) {
+ TQCString fileUri = localFileToUri(*i);
+ if (!fileUri.isEmpty())
+ uris.append(fileUri);
+ }
+ setUris( uris );
+}
+
+/*!
+ Sets the URIs in \a uuris to be the Unicode URIs (only useful for
+ displaying to humans).
+
+ \sa localFileToUri(), setUris()
+*/
+void TQUriDrag::setUnicodeUris( const TQStringList & uuris )
+{
+ TQStrList uris;
+ for ( TQStringList::ConstIterator i = uuris.begin();
+ i != uuris.end(); ++i )
+ uris.append( tqunicodeUriToUri(*i) );
+ setUris( uris );
+}
+
+/*!
+ Returns the URI equivalent of the Unicode URI given in \a uuri
+ (only useful for displaying to humans).
+
+ \sa uriToLocalFile()
+*/
+TQCString TQUriDrag::tqunicodeUriToUri(const TQString& uuri)
+{
+ TQCString utf8 = uuri.utf8();
+ TQCString escutf8;
+ int n = utf8.length();
+ bool isFile = uuri.startsWith("file://");
+ for (int i=0; i<n; i++) {
+ if ( (utf8[i] >= 'a' && utf8[i] <= 'z')
+ || utf8[i] == '/'
+ || (utf8[i] >= '0' && utf8[i] <= '9')
+ || (utf8[i] >= 'A' && utf8[i] <= 'Z')
+
+ || utf8[i] == '-' || utf8[i] == '_'
+ || utf8[i] == '.' || utf8[i] == '!'
+ || utf8[i] == '~' || utf8[i] == '*'
+ || utf8[i] == '(' || utf8[i] == ')'
+ || utf8[i] == '\''
+
+ // Allow this through, so that all URI-references work.
+ || (!isFile && utf8[i] == '#')
+
+ || utf8[i] == ';'
+ || utf8[i] == '?' || utf8[i] == ':'
+ || utf8[i] == '@' || utf8[i] == '&'
+ || utf8[i] == '=' || utf8[i] == '+'
+ || utf8[i] == '$' || utf8[i] == ',' )
+ {
+ escutf8 += utf8[i];
+ } else {
+ // Everything else is escaped as %HH
+ TQCString s(4);
+ s.sprintf("%%%02x",(uchar)utf8[i]);
+ escutf8 += s;
+ }
+ }
+ return escutf8;
+}
+
+/*!
+ Returns the URI equivalent to the absolute local file \a filename.
+
+ \sa uriToLocalFile()
+*/
+TQCString TQUriDrag::localFileToUri(const TQString& filename)
+{
+ TQString r = filename;
+
+ //check that it is an absolute file
+ if (TQDir::isRelativePath(r))
+ return TQCString();
+
+#ifdef TQ_WS_WIN
+
+
+ bool hasHost = FALSE;
+ // convert form network path
+ if (r.left(2) == "\\\\" || r.left(2) == "//") {
+ r.remove(0, 2);
+ hasHost = TRUE;
+ }
+
+ // Slosh -> Slash
+ int slosh;
+ while ( (slosh=r.tqfind('\\')) >= 0 ) {
+ r[slosh] = '/';
+ }
+
+ // Drive
+ if ( r[0] != '/' && !hasHost)
+ r.insert(0,'/');
+
+#endif
+#if defined ( TQ_WS_X11 ) && 0
+ // URL without the hostname is considered to be errorneous by XDnD.
+ // See: http://www.newplanetsoftware.com/xdnd/dragging_files.html
+ // This feature is not active because this would break dnd between old and new qt apps.
+ char hostname[257];
+ if ( gethostname( hostname, 255 ) == 0 ) {
+ hostname[256] = '\0';
+ r.prepend( TQString::tqfromLatin1( hostname ) );
+ }
+#endif
+ return tqunicodeUriToUri(TQString("file://" + r));
+}
+
+/*!
+ Returns the Unicode URI (only useful for displaying to humans)
+ equivalent of \a uri.
+
+ Note that URIs are always in escaped UTF8 encoding.
+
+ \sa localFileToUri()
+*/
+TQString TQUriDrag::uriToUnicodeUri(const char* uri)
+{
+ TQCString utf8;
+
+ while (*uri) {
+ switch (*uri) {
+ case '%': {
+ uint ch = (uchar) uri[1];
+ if ( ch && uri[2] ) {
+ ch = htod( ch ) * 16 + htod( (uchar) uri[2] );
+ utf8 += (char) ch;
+ uri += 2;
+ }
+ }
+ break;
+ default:
+ utf8 += *uri;
+ }
+ ++uri;
+ }
+
+ return TQString::fromUtf8(utf8);
+}
+
+/*!
+ Returns the name of a local file equivalent to \a uri or a null
+ string if \a uri is not a local file.
+
+ Note that URIs are always in escaped UTF8 encoding.
+
+ \sa localFileToUri()
+*/
+TQString TQUriDrag::uriToLocalFile(const char* uri)
+{
+ TQString file;
+
+ if (!uri)
+ return file;
+ if (0==qstrnicmp(uri,"file:/",6)) // It is a local file uri
+ uri += 6;
+ else if (TQString(uri).tqfind(":/") != -1) // It is a different scheme uri
+ return file;
+
+ bool local = uri[0] != '/' || ( uri[0] != '\0' && uri[1] == '/' );
+#ifdef TQ_WS_X11
+ // do we have a hostname?
+ if ( !local && uri[0] == '/' && uri[2] != '/' ) {
+ // then move the pointer to after the 'hostname/' part of the uri
+ const char* hostname_end = strchr( uri+1, '/' );
+ if ( hostname_end != NULL ) {
+ char hostname[ 257 ];
+ if ( gethostname( hostname, 255 ) == 0 ) {
+ hostname[ 256 ] = '\0';
+ if ( tqstrncmp( uri+1, hostname, hostname_end - ( uri+1 )) == 0 ) {
+ uri = hostname_end + 1; // point after the slash
+ local = TRUE;
+ }
+ }
+ }
+ }
+#endif
+ if ( local ) {
+ file = uriToUnicodeUri(uri);
+ if ( uri[1] == '/' ) {
+ file.remove((uint)0,1);
+ } else {
+ file.insert(0,'/');
+ }
+#ifdef TQ_WS_WIN
+ if ( file.length() > 2 && file[0] == '/' && file[2] == '|' ) {
+ file[2] = ':';
+ file.remove(0,1);
+ } else if (file.length() > 2 && file[0] == '/' && file[1].isLetter() && file[2] == ':') {
+ file.remove(0, 1);
+ }
+ // Leave slash as slashes.
+#endif
+ }
+#ifdef TQ_WS_WIN
+ else {
+ file = uriToUnicodeUri(uri);
+ // convert to network path
+ file.insert(1, '/'); // leave as forward slashes
+ }
+#endif
+
+ return file;
+}
+
+/*!
+ Decodes URIs from the mime source event \a e, converts them to
+ local files if they refer to local files, and places them in \a l
+ (which is first cleared).
+
+ Returns TRUE if \e contained a valid list of URIs; otherwise
+ returns FALSE. The list will be empty if no URIs were local files.
+*/
+bool TQUriDrag::decodeLocalFiles( const TQMimeSource* e, TQStringList& l )
+{
+ TQStrList u;
+ if ( !decode( e, u ) )
+ return FALSE;
+
+ l.clear();
+ for (const char* s=u.first(); s; s=u.next()) {
+ TQString lf = uriToLocalFile(s);
+ if ( !lf.isNull() )
+ l.append( lf );
+ }
+ return TRUE;
+}
+
+/*!
+ Decodes URIs from the mime source event \a e, converts them to
+ Unicode URIs (only useful for displaying to humans), placing them
+ in \a l (which is first cleared).
+
+ Returns TRUE if \e contained a valid list of URIs; otherwise
+ returns FALSE.
+*/
+bool TQUriDrag::decodeToUnicodeUris( const TQMimeSource* e, TQStringList& l )
+{
+ TQStrList u;
+ if ( !decode( e, u ) )
+ return FALSE;
+
+ l.clear();
+ for (const char* s=u.first(); s; s=u.next())
+ l.append( uriToUnicodeUri(s) );
+
+ return TRUE;
+}
+
+
+#ifndef TQT_NO_DRAGANDDROP
+/*!
+ If the source of the drag operation is a widget in this
+ application, this function returns that source, otherwise it
+ returns 0. The source of the operation is the first parameter to
+ drag object subclasses.
+
+ This is useful if your widget needs special behavior when dragging
+ to itself, etc.
+
+ See TQDragObject::TQDragObject() and subclasses.
+*/
+TQWidget* TQDropEvent::source() const
+{
+ return qt_dnd_manager ? qt_dnd_manager->dragSource : 0;
+}
+#endif
+
+/*!
+ \class TQColorDrag tqdragobject.h
+
+ \brief The TQColorDrag class provides a drag and drop object for
+ transferring colors.
+
+ \ingroup draganddrop
+
+ This class provides a drag object which can be used to transfer data
+ about colors for drag and drop and in the clipboard. For example, it
+ is used in TQColorDialog.
+
+ The color is set in the constructor but can be changed with
+ setColor().
+
+ For more information about drag and drop, see the TQDragObject class
+ and the \link dnd.html drag and drop documentation\endlink.
+*/
+
+/*!
+ Constructs a color drag object with the color \a col. Passes \a
+ dragsource and \a name to the TQStoredDrag constructor.
+*/
+
+TQColorDrag::TQColorDrag( const TQColor &col, TQWidget *dragsource, const char *name )
+ : TQStoredDrag( "application/x-color", dragsource, name )
+{
+ setColor( col );
+}
+
+/*!
+ Constructs a color drag object with a white color. Passes \a
+ dragsource and \a name to the TQStoredDrag constructor.
+*/
+
+TQColorDrag::TQColorDrag( TQWidget *dragsource, const char *name )
+ : TQStoredDrag( "application/x-color", dragsource, name )
+{
+ setColor( TQt::white );
+}
+
+/*!
+ Sets the color of the color drag to \a col.
+*/
+
+void TQColorDrag::setColor( const TQColor &col )
+{
+ short r = (col.red() << 8) | col.red();
+ short g = (col.green() << 8) | col.green();
+ short b = (col.blue() << 8) | col.blue();
+
+ // make sure we transmit data in network order
+ r = htons(r);
+ g = htons(g);
+ b = htons(b);
+
+ ushort rgba[4] = {
+ r, g, b,
+ 0xffff // Alpha not supported yet.
+ };
+ TQByteArray data(sizeof(rgba));
+ memcpy(data.data(), rgba, sizeof(rgba));
+ setEncodedData(data);
+}
+
+/*!
+ Returns TRUE if the color drag object can decode the mime source
+ \a e; otherwise returns FALSE.
+*/
+
+bool TQColorDrag::canDecode( TQMimeSource *e )
+{
+ return e->provides( "application/x-color" );
+}
+
+/*!
+ Decodes the mime source \a e and sets the decoded values to \a
+ col.
+*/
+
+bool TQColorDrag::decode( TQMimeSource *e, TQColor &col )
+{
+ TQByteArray data = e->tqencodedData("application/x-color");
+ ushort rgba[4];
+ if (data.size() != sizeof(rgba))
+ return FALSE;
+
+ memcpy(rgba, data.data(), sizeof(rgba));
+
+ short r = rgba[0];
+ short g = rgba[1];
+ short b = rgba[2];
+
+ // data is in network order
+ r = ntohs(r);
+ g = ntohs(g);
+ b = ntohs(b);
+
+ r = (r >> 8) & 0xff;
+ g = (g >> 8) & 0xff;
+ b = (b >> 8) & 0xff;
+
+ col.setRgb(r, g, b);
+ return TRUE;
+}
+
+#endif // TQT_NO_MIME
+
+#endif // USE_QT4 \ No newline at end of file