You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
368 lines
17 KiB
368 lines
17 KiB
13 years ago
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||
|
<!-- /home/espenr/tmp/qt-3.3.8-espenr-2499/qt-x11-free-3.3.8/doc/dnd.doc:36 -->
|
||
|
<html>
|
||
|
<head>
|
||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||
|
<title>Drag and Drop</title>
|
||
|
<style type="text/css"><!--
|
||
|
fn { margin-left: 1cm; text-indent: -1cm; }
|
||
|
a:link { color: #004faf; text-decoration: none }
|
||
|
a:visited { color: #672967; text-decoration: none }
|
||
|
body { background: #ffffff; color: black; }
|
||
|
--></style>
|
||
|
</head>
|
||
|
<body>
|
||
|
|
||
|
<table border="0" cellpadding="0" cellspacing="0" width="100%">
|
||
|
<tr bgcolor="#E5E5E5">
|
||
|
<td valign=center>
|
||
|
<a href="index.html">
|
||
|
<font color="#004faf">Home</font></a>
|
||
|
| <a href="classes.html">
|
||
|
<font color="#004faf">All Classes</font></a>
|
||
|
| <a href="mainclasses.html">
|
||
|
<font color="#004faf">Main Classes</font></a>
|
||
|
| <a href="annotated.html">
|
||
|
<font color="#004faf">Annotated</font></a>
|
||
|
| <a href="groups.html">
|
||
|
<font color="#004faf">Grouped Classes</font></a>
|
||
|
| <a href="functions.html">
|
||
|
<font color="#004faf">Functions</font></a>
|
||
|
</td>
|
||
|
<td align="right" valign="center"><img src="logo32.png" align="right" width="64" height="32" border="0"></td></tr></table><h1 align=center>Drag and Drop</h1>
|
||
|
|
||
|
|
||
|
|
||
|
<p> Drag and drop provides a simple visual mechanism which users can use
|
||
|
to transfer information between and within applications. (In the
|
||
|
literature this is referred to as a "direct manipulation model".) Drag
|
||
|
and drop is similar in function to the clipboard's cut-and-paste
|
||
|
mechanism.
|
||
|
<p> <!-- toc -->
|
||
|
<ul>
|
||
|
<li><a href="#1"> Dragging
|
||
|
</a>
|
||
|
<li><a href="#2"> Dropping
|
||
|
</a>
|
||
|
<li><a href="#3"> The Clipboard
|
||
|
</a>
|
||
|
<li><a href="#4"> Drag and Drop Actions
|
||
|
</a>
|
||
|
<li><a href="#5"> Adding New Drag and Drop Types
|
||
|
</a>
|
||
|
<li><a href="#6"> Advanced Drag-and-Drop
|
||
|
</a>
|
||
|
<li><a href="#7"> Inter-operating with Other Applications
|
||
|
</a>
|
||
|
</ul>
|
||
|
<!-- endtoc -->
|
||
|
|
||
|
<p> For drag and drop examples see (in increasing order of
|
||
|
sophistication): <tt>qt/examples/iconview/simple_dd</tt>, <tt>qt/examples/dragdrop</tt> and <tt>qt/examples/fileiconview</tt>. See also the
|
||
|
<a href="qtextedit.html">TQTextEdit</a> widget source code.
|
||
|
<p> <h2> Dragging
|
||
|
</h2>
|
||
|
<a name="1"></a><p> To start a drag, for example in a <a href="qwidget.html#mouseMoveEvent">mouse motion event</a>, create an object of the <a href="qdragobject.html">TQDragObject</a>
|
||
|
subclass appropriate for your media, such as <a href="qtextdrag.html">TQTextDrag</a> for text and
|
||
|
<a href="qimagedrag.html">TQImageDrag</a> for images. Then call the drag() method. This is all you
|
||
|
need for simple dragging of existing types.
|
||
|
<p> For example, to start dragging some text from a widget:
|
||
|
<pre>
|
||
|
void MyWidget::startDrag()
|
||
|
{
|
||
|
<a href="qdragobject.html">TQDragObject</a> *d = new <a href="qtextdrag.html">TQTextDrag</a>( myHighlightedText(), this );
|
||
|
d-><a href="qdragobject.html#dragCopy">dragCopy</a>();
|
||
|
// do NOT delete d.
|
||
|
}
|
||
|
</pre>
|
||
|
|
||
|
<p> Note that the TQDragObject is not deleted after the drag. The
|
||
|
TQDragObject needs to persist after the drag is apparently finished
|
||
|
since it may still be communicating with another process. Eventually
|
||
|
TQt will delete the object. If the widget owning the drag object is
|
||
|
deleted before then, any pending drop will be canceled and the drag
|
||
|
object deleted. For this reason, you should be careful what the object
|
||
|
references.
|
||
|
<p> <h2> Dropping
|
||
|
</h2>
|
||
|
<a name="2"></a><p> To be able to receive media dropped on a widget, call
|
||
|
<a href="qwidget.html#setAcceptDrops">setAcceptDrops(TRUE)</a>
|
||
|
for the widget (e.g. in its constructor), and override the
|
||
|
event handler methods
|
||
|
<a href="qwidget.html#dragEnterEvent">dragEnterEvent()</a> and
|
||
|
<a href="qwidget.html#dropEvent">dropEvent()</a>.
|
||
|
For more sophisticated applications overriding
|
||
|
<a href="qwidget.html#dragMoveEvent">dragMoveEvent()</a> and
|
||
|
<a href="qwidget.html#dragLeaveEvent">dragLeaveEvent()</a> will also be
|
||
|
necessary.
|
||
|
<p> For example, to accept text and image drops:
|
||
|
<pre>
|
||
|
MyWidget::MyWidget(...) :
|
||
|
<a href="qwidget.html">TQWidget</a>(...)
|
||
|
{
|
||
|
...
|
||
|
setAcceptDrops(TRUE);
|
||
|
}
|
||
|
|
||
|
void MyWidget::dragEnterEvent(TQDragEnterEvent* event)
|
||
|
{
|
||
|
event->accept(
|
||
|
TQTextDrag::<a href="qtextdrag.html#canDecode">canDecode</a>(event) ||
|
||
|
TQImageDrag::<a href="qimagedrag.html#canDecode">canDecode</a>(event)
|
||
|
);
|
||
|
}
|
||
|
|
||
|
void MyWidget::dropEvent(TQDropEvent* event)
|
||
|
{
|
||
|
<a href="qimage.html">TQImage</a> image;
|
||
|
<a href="qstring.html">TQString</a> text;
|
||
|
|
||
|
if ( TQImageDrag::<a href="qimagedrag.html#decode">decode</a>(event, image) ) {
|
||
|
insertImageAt(image, event->pos());
|
||
|
} else if ( TQTextDrag::<a href="qtextdrag.html#decode">decode</a>(event, text) ) {
|
||
|
insertTextAt(text, event->pos());
|
||
|
}
|
||
|
}
|
||
|
</pre>
|
||
|
|
||
|
<p> <h2> The Clipboard
|
||
|
</h2>
|
||
|
<a name="3"></a><p> The <a href="qdragobject.html">TQDragObject</a>, <a href="qdragenterevent.html">TQDragEnterEvent</a>, <a href="qdragmoveevent.html">TQDragMoveEvent</a>, and <a href="qdropevent.html">TQDropEvent</a>
|
||
|
classes are all subclasses of TQMimeSource: the class of objects which
|
||
|
provide typed information. If you base your data transfers on
|
||
|
TQDragObject, you not only get drag-and-drop, but you also get
|
||
|
traditional cut-and-paste for free. The <a href="qclipboard.html">TQClipboard</a> has two functions:
|
||
|
<pre>
|
||
|
setData(TQMimeSource*)
|
||
|
<a href="qmimesource.html">TQMimeSource</a>* data()const
|
||
|
</pre>
|
||
|
|
||
|
With these functions you can trivially put your drag-and-drop oriented
|
||
|
information on the clipboard:
|
||
|
<pre>
|
||
|
void MyWidget::copy()
|
||
|
{
|
||
|
TQApplication::<a href="qapplication.html#clipboard">clipboard</a>()->setData(
|
||
|
new <a href="qtextdrag.html">TQTextDrag</a>(myHighlightedText()) );
|
||
|
}
|
||
|
|
||
|
void MyWidget::paste()
|
||
|
{
|
||
|
<a href="qstring.html">TQString</a> text;
|
||
|
if ( TQTextDrag::<a href="qtextdrag.html#decode">decode</a>(TQApplication::<a href="qapplication.html#clipboard">clipboard</a>()->data(), text) )
|
||
|
insertText( text );
|
||
|
}
|
||
|
</pre>
|
||
|
|
||
|
You can even use <a href="qdragobject.html">TQDragObject</a> subclasses as part of file IO. For
|
||
|
example, if your application has a subclass of TQDragObject that
|
||
|
encodes CAD designs in DXF format, your saving and loading code might
|
||
|
be:
|
||
|
<pre>
|
||
|
void MyWidget::save()
|
||
|
{
|
||
|
<a href="qfile.html">TQFile</a> out(current_file_name);
|
||
|
if ( out.<a href="qfile.html#open">open</a>(IO_WriteOnly) ) {
|
||
|
MyCadDrag tmp(current_design);
|
||
|
out.<a href="qiodevice.html#writeBlock">writeBlock</a>( tmp->encodedData( "image/x-dxf" ) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void MyWidget::load()
|
||
|
{
|
||
|
<a href="qfile.html">TQFile</a> in(current_file_name);
|
||
|
if ( in.<a href="qfile.html#open">open</a>(IO_ReadOnly) ) {
|
||
|
if ( !MyCadDrag::decode(in.<a href="qiodevice.html#readAll">readAll</a>(), current_design) ) {
|
||
|
TQMessageBox::<a href="qmessagebox.html#warning">warning</a>( this, "Format error",
|
||
|
tr("The file \"%1\" is not in any supported format")
|
||
|
.arg(current_file_name)
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
</pre>
|
||
|
|
||
|
Note how the <a href="qdragobject.html">TQDragObject</a> subclass is called "MyCadDrag", not
|
||
|
"MyDxfDrag": because in the future you might extend it to provide
|
||
|
DXF, DWG, SVF, WMF, or even <a href="qpicture.html">TQPicture</a> data to other applications.
|
||
|
<p> <h2> Drag and Drop Actions
|
||
|
</h2>
|
||
|
<a name="4"></a><p> In the simpler cases, the target of a drag-and-drop receives a copy of
|
||
|
the data being dragged and the source decides whether to delete the
|
||
|
original. This is the "Copy" action in <a href="qdropevent.html">TQDropEvent</a>. The target may also
|
||
|
choose to understand other actions, specifically the Move and Link
|
||
|
actions. If the target understands the Move action, <em>the target</em> is responsible for both the copy and delete operations and
|
||
|
the source will not attempt to delete the data itself. If the target
|
||
|
understands the Link, it stores its own reference to the original
|
||
|
information, and again the source does not delete the original. The
|
||
|
most common use of drag-and-drop actions is when performing a Move
|
||
|
within the same widget: see the <a href="#advanced">Advanced
|
||
|
Drag-and-Drop</a> section below.
|
||
|
<p> The other major use of drag actions is when using a reference type
|
||
|
such as text/uri-list, where the dragged data are actually references
|
||
|
to files or objects.
|
||
|
<p> <h2> Adding New Drag and Drop Types
|
||
|
</h2>
|
||
|
<a name="5"></a><p> As suggested in the DXF example above, drag-and-drop is not limited to
|
||
|
text and images. Any information can be dragged and dropped. To drag
|
||
|
information between applications, the applications must be able to
|
||
|
indicate to each other which data formats they can accept and which
|
||
|
they can produce. This is achieved using <a href="http://www.rfc-editor.org/rfc/rfc1341.txt">MIME types</a>: the drag
|
||
|
source provides a list of MIME types that it can produce (ordered from
|
||
|
most appropriate to least appropriate), and the drop target chooses
|
||
|
which of those it can accept. For example, <a href="qtextdrag.html">TQTextDrag</a> provides support
|
||
|
for the "<tt>text/plain</tt>" MIME type (ordinary unformatted text), and
|
||
|
the Unicode formats "<tt>text/utf16</tt>" and "<tt>text/utf8</tt>"; <a href="qimagedrag.html">TQImageDrag</a>
|
||
|
provides for "<tt>image/*</tt>", where <tt>*</tt> is any image format that
|
||
|
<a href="qimageio.html">TQImageIO</a> supports; and the <a href="quridrag.html">TQUriDrag</a> subclass provides
|
||
|
"<tt>text/uri-list</tt>", a standard format for transferring a list of
|
||
|
filenames (or URLs).
|
||
|
<p> To implement drag-and-drop of some type of information for which there
|
||
|
is no available <a href="qdragobject.html">TQDragObject</a> subclass, the first and most important
|
||
|
step is to look for existing formats that are appropriate: the
|
||
|
Internet Assigned Numbers Authority (<a href="http://www.iana.org">IANA</a>) provides a <a href="http://www.isi.edu/in-notes/iana/assignments/media-types/">hierarchical
|
||
|
list of MIME media types</a> at the Information Sciences Institute
|
||
|
(<a href="http://www.isi.edu">ISI</a>). Using standard MIME types
|
||
|
maximizes the inter-operability of your application with other
|
||
|
software now and in the future.
|
||
|
<p> To support an additional media type, subclass either TQDragObject or
|
||
|
<a href="qstoreddrag.html">TQStoredDrag</a>. Subclass TQDragObject when you need to provide support for
|
||
|
multiple media types. Subclass the simpler TQStoredDrag when one type
|
||
|
is sufficient.
|
||
|
<p> Subclasses of TQDragObject will override the
|
||
|
<a href="qmimesource.html#format">const char* format(int i) const</a> and
|
||
|
<a href="qmimesource.html#encodedData">TQByteArray encodedData(const char* mimetype) const</a>
|
||
|
members, and provide a set-method to encode the media data and static
|
||
|
members canDecode() and decode() to decode incoming data, similar to
|
||
|
<a href="qimagedrag.html#canDecode">bool canDecode(TQMimeSource*) const</a> and
|
||
|
<a href="qimagedrag.html#decode">TQByteArray decode(TQMimeSource*) const</a>
|
||
|
of <a href="qimagedrag.html">TQImageDrag</a>.
|
||
|
Of course, you can provide drag-only or drop-only support for a media
|
||
|
type by omitting some of these methods.
|
||
|
<p> Subclasses of TQStoredDrag provide a set-method to encode the media
|
||
|
data and the same static members canDecode() and decode() to decode
|
||
|
incoming data.
|
||
|
<p> <a name="advanced"></a>
|
||
|
<h2> Advanced Drag-and-Drop
|
||
|
</h2>
|
||
|
<a name="6"></a><p> In the clipboard model, the user can <em>cut</em> or <em>copy</em> the source
|
||
|
information, then later paste it. Similarly in the drag-and-drop
|
||
|
model, the user can drag a <em>copy</em> of the information or they can drag
|
||
|
the information itself to a new place (<em>moving</em> it). The
|
||
|
drag-and-drop model however has an additional complication for the
|
||
|
programmer: the program doesn't know whether the user wants to cut or
|
||
|
copy until the drop (paste) is done! For dragging between
|
||
|
applications, it makes no difference, but for dragging within an
|
||
|
application, the application must take a little extra care not to
|
||
|
tread on its own feet. For example, to drag text around in a document,
|
||
|
the drag start point and the drop event might look like this:
|
||
|
<p> <pre>
|
||
|
void MyEditor::startDrag()
|
||
|
{
|
||
|
<a href="qdragobject.html">TQDragObject</a> *d = new <a href="qtextdrag.html">TQTextDrag</a>(myHighlightedText(), this);
|
||
|
if ( d-><a href="qdragobject.html#drag">drag</a>() && d-><a href="qdragobject.html#target">target</a>() != this )
|
||
|
cutMyHighlightedText();
|
||
|
}
|
||
|
|
||
|
void MyEditor::dropEvent(TQDropEvent* event)
|
||
|
{
|
||
|
<a href="qstring.html">TQString</a> text;
|
||
|
|
||
|
if ( TQTextDrag::<a href="qtextdrag.html#decode">decode</a>(event, text) ) {
|
||
|
if ( event->source() == this && event->action() == TQDropEvent::Move ) {
|
||
|
// Careful not to tread on my own feet
|
||
|
event->acceptAction();
|
||
|
moveMyHighlightedTextTo(event->pos());
|
||
|
} else {
|
||
|
pasteTextAt(text, event->pos());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
</pre>
|
||
|
|
||
|
<p> Some widgets are more specific than just a "yes" or "no" response when
|
||
|
data is dragged onto them. For example, a CAD program might only
|
||
|
accept drops of text onto text objects in the view. In these cases,
|
||
|
the <a href="qwidget.html#dragMoveEvent">dragMoveEvent()</a> is used and
|
||
|
an <em>area</em> is given for which the drag is accepted or ignored:
|
||
|
<pre>
|
||
|
void MyWidget::dragMoveEvent(TQDragMoveEvent* event)
|
||
|
{
|
||
|
if ( TQTextDrag::<a href="qtextdrag.html#canDecode">canDecode</a>(event) ) {
|
||
|
MyCadItem* item = findMyItemAt(event->pos());
|
||
|
if ( item )
|
||
|
event->accept();
|
||
|
}
|
||
|
}
|
||
|
</pre>
|
||
|
|
||
|
If the computations to find objects are particularly slow, you might
|
||
|
achieve improved performance if you tell the system an area for which
|
||
|
you promise the acceptance persists:
|
||
|
<pre>
|
||
|
void MyWidget::dragMoveEvent(TQDragMoveEvent* event)
|
||
|
{
|
||
|
if ( TQTextDrag::<a href="qtextdrag.html#canDecode">canDecode</a>(event) ) {
|
||
|
MyCadItem* item = findMyItemAt(event->pos());
|
||
|
if ( item ) {
|
||
|
<a href="qrect.html">TQRect</a> r = item->areaRelativeToMeClippedByAnythingInTheWay();
|
||
|
if ( item->type() == MyTextType )
|
||
|
event->accept( r );
|
||
|
else
|
||
|
event->ignore( r );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
</pre>
|
||
|
|
||
|
<p> The dragMoveEvent() can also be used if you need to give visual
|
||
|
feedback as the drag progresses, to start timers, to scroll the
|
||
|
window, or whatever is appropriate (don't forget to stop the scrolling
|
||
|
and timers in a dragLeaveEvent() though).
|
||
|
<p> The <a href="qapplication.html">TQApplication</a> object (available as the <tt>qApp</tt> global) also
|
||
|
provides some drag and drop related functions:
|
||
|
<a href="qapplication.html#setStartDragTime">TQApplication::setStartDragTime</a>(),
|
||
|
<a href="qapplication.html#setStartDragDistance">TQApplication::setStartDragDistance</a>(), and their corresponding
|
||
|
getters, <a href="qapplication.html#startDragTime">TQApplication::startDragTime</a>() and
|
||
|
<a href="qapplication.html#startDragDistance">TQApplication::startDragDistance</a>().
|
||
|
<p> <h2> Inter-operating with Other Applications
|
||
|
</h2>
|
||
|
<a name="7"></a><p> On X11, the public <a class="r"
|
||
|
href="http://www.newplanetsoftware.com/xdnd/">XDND protocol</a> is
|
||
|
used, while on Windows TQt uses the OLE standard, and TQt/Mac uses the
|
||
|
Carbon Drag Manager. On X11, XDND uses MIME, so no translation is
|
||
|
necessary. The TQt API is the same regardless of the platform. On
|
||
|
Windows, MIME-aware applications can communicate by using clipboard
|
||
|
format names that are MIME types. Already some Windows applications
|
||
|
use MIME naming conventions for their clipboard formats. Internally,
|
||
|
TQt has facilities for translating proprietary clipboard formats to and
|
||
|
from MIME types. This interface will be made public at some time, but
|
||
|
if you need to do such translations now, contact your TQt Technical
|
||
|
Support service.
|
||
|
<p> On X11, TQt also supports drops via the <a href="motif-extension.html#Motif">Motif</a> Drag&Drop Protocol. The
|
||
|
implementation incorporates some code that was originally written by
|
||
|
Daniel Dardailler, and adapted for TQt by Matt Koss <koss@napri.sk>
|
||
|
and Trolltech. Here is the original copyright notice:
|
||
|
<p>
|
||
|
<p> Copyright 1996 Daniel Dardailler.
|
||
|
<p> Permission to use, copy, modify, distribute, and sell this software
|
||
|
for any purpose is hereby granted without fee, provided that the above
|
||
|
copyright notice appear in all copies and that both that copyright
|
||
|
notice and this permission notice appear in supporting documentation,
|
||
|
and that the name of Daniel Dardailler not be used in advertising or
|
||
|
publicity pertaining to distribution of the software without specific,
|
||
|
written prior permission. Daniel Dardailler makes no representations
|
||
|
about the suitability of this software for any purpose. It is
|
||
|
provided "as is" without express or implied warranty.
|
||
|
<p> Modifications Copyright 1999 Matt Koss, under the same license as
|
||
|
above.
|
||
|
<p>
|
||
|
<!-- eof -->
|
||
|
<p><address><hr><div align=center>
|
||
|
<table width=100% cellspacing=0 border=0><tr>
|
||
|
<td>Copyright © 2007
|
||
|
<a href="troll.html">Trolltech</a><td align=center><a href="trademarks.html">Trademarks</a>
|
||
|
<td align=right><div align=right>TQt 3.3.8</div>
|
||
|
</table></div></address></body>
|
||
|
</html>
|