source: trunk/doc/html/dnd.html@ 208

Last change on this file since 208 was 190, checked in by rudi, 14 years ago

reference documentation added

File size: 16.9 KB
Line 
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
2<!-- /home/espenr/tmp/qt-3.3.8-espenr-2499/qt-x11-free-3.3.8/doc/dnd.doc:36 -->
3<html>
4<head>
5<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
6<title>Drag and Drop</title>
7<style type="text/css"><!--
8fn { margin-left: 1cm; text-indent: -1cm; }
9a:link { color: #004faf; text-decoration: none }
10a:visited { color: #672967; text-decoration: none }
11body { background: #ffffff; color: black; }
12--></style>
13</head>
14<body>
15
16<table border="0" cellpadding="0" cellspacing="0" width="100%">
17<tr bgcolor="#E5E5E5">
18<td valign=center>
19 <a href="index.html">
20<font color="#004faf">Home</font></a>
21 | <a href="classes.html">
22<font color="#004faf">All&nbsp;Classes</font></a>
23 | <a href="mainclasses.html">
24<font color="#004faf">Main&nbsp;Classes</font></a>
25 | <a href="annotated.html">
26<font color="#004faf">Annotated</font></a>
27 | <a href="groups.html">
28<font color="#004faf">Grouped&nbsp;Classes</font></a>
29 | <a href="functions.html">
30<font color="#004faf">Functions</font></a>
31</td>
32<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>
33
34
35
36<p> Drag and drop provides a simple visual mechanism which users can use
37to transfer information between and within applications. (In the
38literature this is referred to as a "direct manipulation model".) Drag
39and drop is similar in function to the clipboard's cut-and-paste
40mechanism.
41<p> <!-- toc -->
42<ul>
43<li><a href="#1"> Dragging
44</a>
45<li><a href="#2"> Dropping
46</a>
47<li><a href="#3"> The Clipboard
48</a>
49<li><a href="#4"> Drag and Drop Actions
50</a>
51<li><a href="#5"> Adding New Drag and Drop Types
52</a>
53<li><a href="#6"> Advanced Drag-and-Drop
54</a>
55<li><a href="#7"> Inter-operating with Other Applications
56</a>
57</ul>
58<!-- endtoc -->
59
60<p> For drag and drop examples see (in increasing order of
61sophistication): <tt>qt/examples/iconview/simple_dd</tt>, <tt>qt/examples/dragdrop</tt> and <tt>qt/examples/fileiconview</tt>. See also the
62<a href="qtextedit.html">QTextEdit</a> widget source code.
63<p> <h2> Dragging
64</h2>
65<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">QDragObject</a>
66subclass appropriate for your media, such as <a href="qtextdrag.html">QTextDrag</a> for text and
67<a href="qimagedrag.html">QImageDrag</a> for images. Then call the drag() method. This is all you
68need for simple dragging of existing types.
69<p> For example, to start dragging some text from a widget:
70<pre>
71void MyWidget::startDrag()
72{
73 <a href="qdragobject.html">QDragObject</a> *d = new <a href="qtextdrag.html">QTextDrag</a>( myHighlightedText(), this );
74 d-&gt;<a href="qdragobject.html#dragCopy">dragCopy</a>();
75 // do NOT delete d.
76}
77</pre>
78
79<p> Note that the QDragObject is not deleted after the drag. The
80QDragObject needs to persist after the drag is apparently finished
81since it may still be communicating with another process. Eventually
82Qt will delete the object. If the widget owning the drag object is
83deleted before then, any pending drop will be canceled and the drag
84object deleted. For this reason, you should be careful what the object
85references.
86<p> <h2> Dropping
87</h2>
88<a name="2"></a><p> To be able to receive media dropped on a widget, call
89<a href="qwidget.html#setAcceptDrops">setAcceptDrops(TRUE)</a>
90for the widget (e.g. in its constructor), and override the
91event handler methods
92<a href="qwidget.html#dragEnterEvent">dragEnterEvent()</a> and
93<a href="qwidget.html#dropEvent">dropEvent()</a>.
94For more sophisticated applications overriding
95<a href="qwidget.html#dragMoveEvent">dragMoveEvent()</a> and
96<a href="qwidget.html#dragLeaveEvent">dragLeaveEvent()</a> will also be
97necessary.
98<p> For example, to accept text and image drops:
99<pre>
100MyWidget::MyWidget(...) :
101 <a href="qwidget.html">QWidget</a>(...)
102{
103 ...
104 setAcceptDrops(TRUE);
105}
106
107void MyWidget::dragEnterEvent(QDragEnterEvent* event)
108{
109 event-&gt;accept(
110 QTextDrag::<a href="qtextdrag.html#canDecode">canDecode</a>(event) ||
111 QImageDrag::<a href="qimagedrag.html#canDecode">canDecode</a>(event)
112 );
113}
114
115void MyWidget::dropEvent(QDropEvent* event)
116{
117 <a href="qimage.html">QImage</a> image;
118 <a href="qstring.html">QString</a> text;
119
120 if ( QImageDrag::<a href="qimagedrag.html#decode">decode</a>(event, image) ) {
121 insertImageAt(image, event-&gt;pos());
122 } else if ( QTextDrag::<a href="qtextdrag.html#decode">decode</a>(event, text) ) {
123 insertTextAt(text, event-&gt;pos());
124 }
125}
126</pre>
127
128<p> <h2> The Clipboard
129</h2>
130<a name="3"></a><p> The <a href="qdragobject.html">QDragObject</a>, <a href="qdragenterevent.html">QDragEnterEvent</a>, <a href="qdragmoveevent.html">QDragMoveEvent</a>, and <a href="qdropevent.html">QDropEvent</a>
131classes are all subclasses of QMimeSource: the class of objects which
132provide typed information. If you base your data transfers on
133QDragObject, you not only get drag-and-drop, but you also get
134traditional cut-and-paste for free. The <a href="qclipboard.html">QClipboard</a> has two functions:
135<pre>
136 setData(QMimeSource*)
137 <a href="qmimesource.html">QMimeSource</a>* data()const
138</pre>
139
140With these functions you can trivially put your drag-and-drop oriented
141information on the clipboard:
142<pre>
143void MyWidget::copy()
144{
145 QApplication::<a href="qapplication.html#clipboard">clipboard</a>()-&gt;setData(
146 new <a href="qtextdrag.html">QTextDrag</a>(myHighlightedText()) );
147}
148
149void MyWidget::paste()
150{
151 <a href="qstring.html">QString</a> text;
152 if ( QTextDrag::<a href="qtextdrag.html#decode">decode</a>(QApplication::<a href="qapplication.html#clipboard">clipboard</a>()-&gt;data(), text) )
153 insertText( text );
154}
155</pre>
156
157You can even use <a href="qdragobject.html">QDragObject</a> subclasses as part of file IO. For
158example, if your application has a subclass of QDragObject that
159encodes CAD designs in DXF format, your saving and loading code might
160be:
161<pre>
162void MyWidget::save()
163{
164 <a href="qfile.html">QFile</a> out(current_file_name);
165 if ( out.<a href="qfile.html#open">open</a>(IO_WriteOnly) ) {
166 MyCadDrag tmp(current_design);
167 out.<a href="qiodevice.html#writeBlock">writeBlock</a>( tmp-&gt;encodedData( "image/x-dxf" ) );
168 }
169}
170
171void MyWidget::load()
172{
173 <a href="qfile.html">QFile</a> in(current_file_name);
174 if ( in.<a href="qfile.html#open">open</a>(IO_ReadOnly) ) {
175 if ( !MyCadDrag::decode(in.<a href="qiodevice.html#readAll">readAll</a>(), current_design) ) {
176 QMessageBox::<a href="qmessagebox.html#warning">warning</a>( this, "Format error",
177 tr("The file \"%1\" is not in any supported format")
178 .arg(current_file_name)
179 );
180 }
181 }
182}
183</pre>
184
185Note how the <a href="qdragobject.html">QDragObject</a> subclass is called "MyCadDrag", not
186"MyDxfDrag": because in the future you might extend it to provide
187DXF, DWG, SVF, WMF, or even <a href="qpicture.html">QPicture</a> data to other applications.
188<p> <h2> Drag and Drop Actions
189</h2>
190<a name="4"></a><p> In the simpler cases, the target of a drag-and-drop receives a copy of
191the data being dragged and the source decides whether to delete the
192original. This is the "Copy" action in <a href="qdropevent.html">QDropEvent</a>. The target may also
193choose to understand other actions, specifically the Move and Link
194actions. If the target understands the Move action, <em>the target</em> is responsible for both the copy and delete operations and
195the source will not attempt to delete the data itself. If the target
196understands the Link, it stores its own reference to the original
197information, and again the source does not delete the original. The
198most common use of drag-and-drop actions is when performing a Move
199within the same widget: see the <a href="#advanced">Advanced
200Drag-and-Drop</a> section below.
201<p> The other major use of drag actions is when using a reference type
202such as text/uri-list, where the dragged data are actually references
203to files or objects.
204<p> <h2> Adding New Drag and Drop Types
205</h2>
206<a name="5"></a><p> As suggested in the DXF example above, drag-and-drop is not limited to
207text and images. Any information can be dragged and dropped. To drag
208information between applications, the applications must be able to
209indicate to each other which data formats they can accept and which
210they can produce. This is achieved using <a href="http://www.rfc-editor.org/rfc/rfc1341.txt">MIME types</a>: the drag
211source provides a list of MIME types that it can produce (ordered from
212most appropriate to least appropriate), and the drop target chooses
213which of those it can accept. For example, <a href="qtextdrag.html">QTextDrag</a> provides support
214for the "<tt>text/plain</tt>" MIME type (ordinary unformatted text), and
215the Unicode formats "<tt>text/utf16</tt>" and "<tt>text/utf8</tt>"; <a href="qimagedrag.html">QImageDrag</a>
216provides for "<tt>image/*</tt>", where <tt>*</tt> is any image format that
217<a href="qimageio.html">QImageIO</a> supports; and the <a href="quridrag.html">QUriDrag</a> subclass provides
218"<tt>text/uri-list</tt>", a standard format for transferring a list of
219filenames (or URLs).
220<p> To implement drag-and-drop of some type of information for which there
221is no available <a href="qdragobject.html">QDragObject</a> subclass, the first and most important
222step is to look for existing formats that are appropriate: the
223Internet 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
224list of MIME media types</a> at the Information Sciences Institute
225(<a href="http://www.isi.edu">ISI</a>). Using standard MIME types
226maximizes the inter-operability of your application with other
227software now and in the future.
228<p> To support an additional media type, subclass either QDragObject or
229<a href="qstoreddrag.html">QStoredDrag</a>. Subclass QDragObject when you need to provide support for
230multiple media types. Subclass the simpler QStoredDrag when one type
231is sufficient.
232<p> Subclasses of QDragObject will override the
233<a href="qmimesource.html#format">const char* format(int i) const</a> and
234<a href="qmimesource.html#encodedData">QByteArray encodedData(const char* mimetype) const</a>
235members, and provide a set-method to encode the media data and static
236members canDecode() and decode() to decode incoming data, similar to
237<a href="qimagedrag.html#canDecode">bool canDecode(QMimeSource*) const</a> and
238<a href="qimagedrag.html#decode">QByteArray decode(QMimeSource*) const</a>
239of <a href="qimagedrag.html">QImageDrag</a>.
240Of course, you can provide drag-only or drop-only support for a media
241type by omitting some of these methods.
242<p> Subclasses of QStoredDrag provide a set-method to encode the media
243data and the same static members canDecode() and decode() to decode
244incoming data.
245<p> <a name="advanced"></a>
246<h2> Advanced Drag-and-Drop
247</h2>
248<a name="6"></a><p> In the clipboard model, the user can <em>cut</em> or <em>copy</em> the source
249information, then later paste it. Similarly in the drag-and-drop
250model, the user can drag a <em>copy</em> of the information or they can drag
251the information itself to a new place (<em>moving</em> it). The
252drag-and-drop model however has an additional complication for the
253programmer: the program doesn't know whether the user wants to cut or
254copy until the drop (paste) is done! For dragging between
255applications, it makes no difference, but for dragging within an
256application, the application must take a little extra care not to
257tread on its own feet. For example, to drag text around in a document,
258the drag start point and the drop event might look like this:
259<p> <pre>
260void MyEditor::startDrag()
261{
262 <a href="qdragobject.html">QDragObject</a> *d = new <a href="qtextdrag.html">QTextDrag</a>(myHighlightedText(), this);
263 if ( d-&gt;<a href="qdragobject.html#drag">drag</a>() &amp;&amp; d-&gt;<a href="qdragobject.html#target">target</a>() != this )
264 cutMyHighlightedText();
265}
266
267void MyEditor::dropEvent(QDropEvent* event)
268{
269 <a href="qstring.html">QString</a> text;
270
271 if ( QTextDrag::<a href="qtextdrag.html#decode">decode</a>(event, text) ) {
272 if ( event-&gt;source() == this &amp;&amp; event-&gt;action() == QDropEvent::Move ) {
273 // Careful not to tread on my own feet
274 event-&gt;acceptAction();
275 moveMyHighlightedTextTo(event-&gt;pos());
276 } else {
277 pasteTextAt(text, event-&gt;pos());
278 }
279 }
280}
281</pre>
282
283<p> Some widgets are more specific than just a "yes" or "no" response when
284data is dragged onto them. For example, a CAD program might only
285accept drops of text onto text objects in the view. In these cases,
286the <a href="qwidget.html#dragMoveEvent">dragMoveEvent()</a> is used and
287an <em>area</em> is given for which the drag is accepted or ignored:
288<pre>
289void MyWidget::dragMoveEvent(QDragMoveEvent* event)
290{
291 if ( QTextDrag::<a href="qtextdrag.html#canDecode">canDecode</a>(event) ) {
292 MyCadItem* item = findMyItemAt(event-&gt;pos());
293 if ( item )
294 event-&gt;accept();
295 }
296}
297</pre>
298
299If the computations to find objects are particularly slow, you might
300achieve improved performance if you tell the system an area for which
301you promise the acceptance persists:
302<pre>
303void MyWidget::dragMoveEvent(QDragMoveEvent* event)
304{
305 if ( QTextDrag::<a href="qtextdrag.html#canDecode">canDecode</a>(event) ) {
306 MyCadItem* item = findMyItemAt(event-&gt;pos());
307 if ( item ) {
308 <a href="qrect.html">QRect</a> r = item-&gt;areaRelativeToMeClippedByAnythingInTheWay();
309 if ( item-&gt;type() == MyTextType )
310 event-&gt;accept( r );
311 else
312 event-&gt;ignore( r );
313 }
314 }
315}
316</pre>
317
318<p> The dragMoveEvent() can also be used if you need to give visual
319feedback as the drag progresses, to start timers, to scroll the
320window, or whatever is appropriate (don't forget to stop the scrolling
321and timers in a dragLeaveEvent() though).
322<p> The <a href="qapplication.html">QApplication</a> object (available as the <tt>qApp</tt> global) also
323provides some drag and drop related functions:
324<a href="qapplication.html#setStartDragTime">QApplication::setStartDragTime</a>(),
325<a href="qapplication.html#setStartDragDistance">QApplication::setStartDragDistance</a>(), and their corresponding
326getters, <a href="qapplication.html#startDragTime">QApplication::startDragTime</a>() and
327<a href="qapplication.html#startDragDistance">QApplication::startDragDistance</a>().
328<p> <h2> Inter-operating with Other Applications
329</h2>
330<a name="7"></a><p> On X11, the public <a class="r"
331href="http://www.newplanetsoftware.com/xdnd/">XDND protocol</a> is
332used, while on Windows Qt uses the OLE standard, and Qt/Mac uses the
333Carbon Drag Manager. On X11, XDND uses MIME, so no translation is
334necessary. The Qt API is the same regardless of the platform. On
335Windows, MIME-aware applications can communicate by using clipboard
336format names that are MIME types. Already some Windows applications
337use MIME naming conventions for their clipboard formats. Internally,
338Qt has facilities for translating proprietary clipboard formats to and
339from MIME types. This interface will be made public at some time, but
340if you need to do such translations now, contact your Qt Technical
341Support service.
342<p> On X11, Qt also supports drops via the <a href="motif-extension.html#Motif">Motif</a> Drag&amp;Drop Protocol. The
343implementation incorporates some code that was originally written by
344Daniel Dardailler, and adapted for Qt by Matt Koss &lt;koss@napri.sk&gt;
345and Trolltech. Here is the original copyright notice:
346<p>
347<p> Copyright 1996 Daniel Dardailler.
348<p> Permission to use, copy, modify, distribute, and sell this software
349for any purpose is hereby granted without fee, provided that the above
350copyright notice appear in all copies and that both that copyright
351notice and this permission notice appear in supporting documentation,
352and that the name of Daniel Dardailler not be used in advertising or
353publicity pertaining to distribution of the software without specific,
354written prior permission. Daniel Dardailler makes no representations
355about the suitability of this software for any purpose. It is
356provided "as is" without express or implied warranty.
357<p> Modifications Copyright 1999 Matt Koss, under the same license as
358above.
359<p>
360<!-- eof -->
361<p><address><hr><div align=center>
362<table width=100% cellspacing=0 border=0><tr>
363<td>Copyright &copy; 2007
364<a href="troll.html">Trolltech</a><td align=center><a href="trademarks.html">Trademarks</a>
365<td align=right><div align=right>Qt 3.3.8</div>
366</table></div></address></body>
367</html>
Note: See TracBrowser for help on using the repository browser.