summaryrefslogtreecommitdiffstats
path: root/doc/dnd.doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc/dnd.doc')
-rw-r--r--doc/dnd.doc383
1 files changed, 383 insertions, 0 deletions
diff --git a/doc/dnd.doc b/doc/dnd.doc
new file mode 100644
index 000000000..9bddd90ea
--- /dev/null
+++ b/doc/dnd.doc
@@ -0,0 +1,383 @@
+/****************************************************************************
+**
+** Drag and drop documentation
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the Qt 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 Qt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing retquirements 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.QPL
+** included in the packaging of this file. Licensees holding valid Qt
+** Commercial licenses may use this file in accordance with the Qt
+** 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.
+**
+**********************************************************************/
+
+/*!
+\page dnd.html
+
+\title Drag and Drop
+
+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.
+
+\tableofcontents
+
+For drag and drop examples see (in increasing order of
+sophistication): \c qt/examples/iconview/simple_dd, \c
+qt/examples/dragdrop and \c qt/examples/fileiconview. See also the
+QTextEdit widget source code.
+
+
+\section1 Dragging
+
+To start a drag, for example in a \link QWidget::mouseMoveEvent()
+mouse motion event\endlink, create an object of the QDragObject
+subclass appropriate for your media, such as QTextDrag for text and
+QImageDrag for images. Then call the drag() method. This is all you
+need for simple dragging of existing types.
+
+For example, to start dragging some text from a widget:
+\code
+void MyWidget::startDrag()
+{
+ QDragObject *d = new QTextDrag( myHighlightedText(), this );
+ d->dragCopy();
+ // do NOT delete d.
+}
+\endcode
+
+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.
+
+\section1 Dropping
+
+To be able to receive media dropped on a widget, call
+\link QWidget::setAcceptDrops() setAcceptDrops(TRUE)\endlink
+for the widget (e.g. in its constructor), and override the
+event handler methods
+\link QWidget::dragEnterEvent() dragEnterEvent()\endlink and
+\link QWidget::dropEvent() dropEvent()\endlink.
+For more sophisticated applications overriding
+\link QWidget::dragMoveEvent() dragMoveEvent()\endlink and
+\link QWidget::dragLeaveEvent() dragLeaveEvent()\endlink will also be
+necessary.
+
+For example, to accept text and image drops:
+\code
+MyWidget::MyWidget(...) :
+ QWidget(...)
+{
+ ...
+ setAcceptDrops(TRUE);
+}
+
+void MyWidget::dragEnterEvent(QDragEnterEvent* event)
+{
+ event->accept(
+ QTextDrag::canDecode(event) ||
+ QImageDrag::canDecode(event)
+ );
+}
+
+void MyWidget::dropEvent(QDropEvent* event)
+{
+ QImage image;
+ QString text;
+
+ if ( QImageDrag::decode(event, image) ) {
+ insertImageAt(image, event->pos());
+ } else if ( QTextDrag::decode(event, text) ) {
+ insertTextAt(text, event->pos());
+ }
+}
+\endcode
+
+\section1 The Clipboard
+
+The QDragObject, QDragEnterEvent, QDragMoveEvent, and QDropEvent
+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 QClipboard has two functions:
+\code
+ setData(QMimeSource*)
+ QMimeSource* data()const
+\endcode
+With these functions you can trivially put your drag-and-drop oriented
+information on the clipboard:
+\code
+void MyWidget::copy()
+{
+ QApplication::clipboard()->setData(
+ new QTextDrag(myHighlightedText()) );
+}
+
+void MyWidget::paste()
+{
+ QString text;
+ if ( QTextDrag::decode(QApplication::clipboard()->data(), text) )
+ insertText( text );
+}
+\endcode
+You can even use QDragObject 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:
+\code
+void MyWidget::save()
+{
+ QFile out(current_file_name);
+ if ( out.open(IO_WriteOnly) ) {
+ MyCadDrag tmp(current_design);
+ out.writeBlock( tmp->encodedData( "image/x-dxf" ) );
+ }
+}
+
+void MyWidget::load()
+{
+ QFile in(current_file_name);
+ if ( in.open(IO_ReadOnly) ) {
+ if ( !MyCadDrag::decode(in.readAll(), current_design) ) {
+ QMessageBox::warning( this, "Format error",
+ tr("The file \"%1\" is not in any supported format")
+ .arg(current_file_name)
+ );
+ }
+ }
+}
+\endcode
+Note how the QDragObject subclass is called "MyCadDrag", not
+"MyDxfDrag": because in the future you might extend it to provide
+DXF, DWG, SVF, WMF, or even QPicture data to other applications.
+
+\section1 Drag and Drop Actions
+
+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 QDropEvent. The target may also
+choose to understand other actions, specifically the Move and Link
+actions. If the target understands the Move action, \e{the
+target} 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 \link #advanced Advanced
+Drag-and-Drop\endlink section below.
+
+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.
+
+\section1 Adding New Drag and Drop Types
+
+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 \link
+http://www.rfc-editor.org/rfc/rfc1341.txt MIME types\endlink: 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, QTextDrag provides support
+for the "\c{text/plain}" MIME type (ordinary unformatted text), and
+the Unicode formats "\c{text/utf16}" and "\c{text/utf8}"; QImageDrag
+provides for "\c{image/*}", where \c{*} is any image format that
+\l QImageIO supports; and the QUriDrag subclass provides
+"\c{text/uri-list}", a standard format for transferring a list of
+filenames (or URLs).
+
+To implement drag-and-drop of some type of information for which there
+is no available QDragObject subclass, the first and most important
+step is to look for existing formats that are appropriate: the
+Internet Assigned Numbers Authority (\link http://www.iana.org
+IANA\endlink) provides a \link
+http://www.isi.edu/in-notes/iana/assignments/media-types/ hierarchical
+list of MIME media types\endlink at the Information Sciences Institute
+(\link http://www.isi.edu ISI\endlink). Using standard MIME types
+maximizes the inter-operability of your application with other
+software now and in the future.
+
+To support an additional media type, subclass either QDragObject or
+QStoredDrag. Subclass QDragObject when you need to provide support for
+multiple media types. Subclass the simpler QStoredDrag when one type
+is sufficient.
+
+Subclasses of QDragObject will override the
+\link QDragObject::format()
+const char* format(int i) const
+\endlink and
+\link QDragObject::encodedData()
+QByteArray encodedData(const char* mimetype) const
+\endlink
+members, and provide a set-method to encode the media data and static
+members canDecode() and decode() to decode incoming data, similar to
+\link QImageDrag::canDecode()
+bool canDecode(QMimeSource*) const
+\endlink and
+\link QImageDrag::decode()
+QByteArray decode(QMimeSource*) const
+\endlink
+of QImageDrag.
+Of course, you can provide drag-only or drop-only support for a media
+type by omitting some of these methods.
+
+Subclasses of QStoredDrag provide a set-method to encode the media
+data and the same static members canDecode() and decode() to decode
+incoming data.
+
+\target advanced
+\section1 Advanced Drag-and-Drop
+
+In the clipboard model, the user can \e cut or \e copy the source
+information, then later paste it. Similarly in the drag-and-drop
+model, the user can drag a \e copy of the information or they can drag
+the information itself to a new place (\e moving 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:
+
+\code
+void MyEditor::startDrag()
+{
+ QDragObject *d = new QTextDrag(myHighlightedText(), this);
+ if ( d->drag() && d->target() != this )
+ cutMyHighlightedText();
+}
+
+void MyEditor::dropEvent(QDropEvent* event)
+{
+ QString text;
+
+ if ( QTextDrag::decode(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());
+ }
+ }
+}
+\endcode
+
+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 \link QWidget::dragMoveEvent() dragMoveEvent()\endlink is used and
+an \e area is given for which the drag is accepted or ignored:
+\code
+void MyWidget::dragMoveEvent(QDragMoveEvent* event)
+{
+ if ( QTextDrag::canDecode(event) ) {
+ MyCadItem* item = findMyItemAt(event->pos());
+ if ( item )
+ event->accept();
+ }
+}
+\endcode
+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:
+\code
+void MyWidget::dragMoveEvent(QDragMoveEvent* event)
+{
+ if ( QTextDrag::canDecode(event) ) {
+ MyCadItem* item = findMyItemAt(event->pos());
+ if ( item ) {
+ QRect r = item->areaRelativeToMeClippedByAnythingInTheWay();
+ if ( item->type() == MyTextType )
+ event->accept( r );
+ else
+ event->ignore( r );
+ }
+ }
+}
+\endcode
+
+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).
+
+The QApplication object (available as the \c qApp global) also
+provides some drag and drop related functions:
+\l{QApplication::setStartDragTime()},
+\l{QApplication::setStartDragDistance()}, and their corresponding
+getters, \l{QApplication::startDragTime()} and
+\l{QApplication::startDragDistance()}.
+
+\section1 Inter-operating with Other Applications
+
+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.
+
+On X11, Qt also supports drops via the Motif 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:
+
+\legalese
+
+Copyright 1996 Daniel Dardailler.
+
+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.
+
+Modifications Copyright 1999 Matt Koss, under the same license as
+above.
+
+*/ // NOTE: That notice is from qmotifdnd_x11.cpp.