diff options
Diffstat (limited to 'doc/html/dnd.html')
-rw-r--r-- | doc/html/dnd.html | 367 |
1 files changed, 367 insertions, 0 deletions
diff --git a/doc/html/dnd.html b/doc/html/dnd.html new file mode 100644 index 0000000..3c0e064 --- /dev/null +++ b/doc/html/dnd.html @@ -0,0 +1,367 @@ +<!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">QTextEdit</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">QDragObject</a> +subclass appropriate for your media, such as <a href="qtextdrag.html">QTextDrag</a> for text and +<a href="qimagedrag.html">QImageDrag</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">QDragObject</a> *d = new <a href="qtextdrag.html">QTextDrag</a>( myHighlightedText(), this ); + d-><a href="qdragobject.html#dragCopy">dragCopy</a>(); + // do NOT delete d. +} +</pre> + +<p> Note that the QDragObject is not deleted after the drag. The +QDragObject needs to persist after the drag is apparently finished +since it may still be communicating with another process. Eventually +Qt 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">QWidget</a>(...) +{ + ... + setAcceptDrops(TRUE); +} + +void MyWidget::dragEnterEvent(QDragEnterEvent* event) +{ + event->accept( + QTextDrag::<a href="qtextdrag.html#canDecode">canDecode</a>(event) || + QImageDrag::<a href="qimagedrag.html#canDecode">canDecode</a>(event) + ); +} + +void MyWidget::dropEvent(QDropEvent* event) +{ + <a href="qimage.html">QImage</a> image; + <a href="qstring.html">QString</a> text; + + if ( QImageDrag::<a href="qimagedrag.html#decode">decode</a>(event, image) ) { + insertImageAt(image, event->pos()); + } else if ( QTextDrag::<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">QDragObject</a>, <a href="qdragenterevent.html">QDragEnterEvent</a>, <a href="qdragmoveevent.html">QDragMoveEvent</a>, and <a href="qdropevent.html">QDropEvent</a> +classes are all subclasses of QMimeSource: the class of objects which +provide typed information. If you base your data transfers on +QDragObject, you not only get drag-and-drop, but you also get +traditional cut-and-paste for free. The <a href="qclipboard.html">QClipboard</a> has two functions: +<pre> + setData(QMimeSource*) + <a href="qmimesource.html">QMimeSource</a>* data()const +</pre> + +With these functions you can trivially put your drag-and-drop oriented +information on the clipboard: +<pre> +void MyWidget::copy() +{ + QApplication::<a href="qapplication.html#clipboard">clipboard</a>()->setData( + new <a href="qtextdrag.html">QTextDrag</a>(myHighlightedText()) ); +} + +void MyWidget::paste() +{ + <a href="qstring.html">QString</a> text; + if ( QTextDrag::<a href="qtextdrag.html#decode">decode</a>(QApplication::<a href="qapplication.html#clipboard">clipboard</a>()->data(), text) ) + insertText( text ); +} +</pre> + +You can even use <a href="qdragobject.html">QDragObject</a> subclasses as part of file IO. For +example, if your application has a subclass of QDragObject that +encodes CAD designs in DXF format, your saving and loading code might +be: +<pre> +void MyWidget::save() +{ + <a href="qfile.html">QFile</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">QFile</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) ) { + QMessageBox::<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">QDragObject</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">QPicture</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">QDropEvent</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">QTextDrag</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">QImageDrag</a> +provides for "<tt>image/*</tt>", where <tt>*</tt> is any image format that +<a href="qimageio.html">QImageIO</a> supports; and the <a href="quridrag.html">QUriDrag</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">QDragObject</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 QDragObject or +<a href="qstoreddrag.html">QStoredDrag</a>. Subclass QDragObject when you need to provide support for +multiple media types. Subclass the simpler QStoredDrag when one type +is sufficient. +<p> Subclasses of QDragObject will override the +<a href="qmimesource.html#format">const char* format(int i) const</a> and +<a href="qmimesource.html#encodedData">QByteArray 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(QMimeSource*) const</a> and +<a href="qimagedrag.html#decode">QByteArray decode(QMimeSource*) const</a> +of <a href="qimagedrag.html">QImageDrag</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 QStoredDrag 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">QDragObject</a> *d = new <a href="qtextdrag.html">QTextDrag</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(QDropEvent* event) +{ + <a href="qstring.html">QString</a> text; + + if ( QTextDrag::<a href="qtextdrag.html#decode">decode</a>(event, text) ) { + if ( event->source() == this && event->action() == QDropEvent::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(QDragMoveEvent* event) +{ + if ( QTextDrag::<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(QDragMoveEvent* event) +{ + if ( QTextDrag::<a href="qtextdrag.html#canDecode">canDecode</a>(event) ) { + MyCadItem* item = findMyItemAt(event->pos()); + if ( item ) { + <a href="qrect.html">QRect</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">QApplication</a> object (available as the <tt>qApp</tt> global) also +provides some drag and drop related functions: +<a href="qapplication.html#setStartDragTime">QApplication::setStartDragTime</a>(), +<a href="qapplication.html#setStartDragDistance">QApplication::setStartDragDistance</a>(), and their corresponding +getters, <a href="qapplication.html#startDragTime">QApplication::startDragTime</a>() and +<a href="qapplication.html#startDragDistance">QApplication::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 Qt uses the OLE standard, and Qt/Mac uses the +Carbon Drag Manager. On X11, XDND uses MIME, so no translation is +necessary. The Qt 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, +Qt 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 Qt Technical +Support service. +<p> On X11, Qt 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 Qt 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>Qt 3.3.8</div> +</table></div></address></body> +</html> |