QClipboard Class Reference

#include <qclipboard.h>

Inheritance diagram for QClipboard:

Inheritance graph
[legend]
Collaboration diagram for QClipboard:

Collaboration graph
[legend]
List of all members.

Detailed Description

The QClipboard class provides access to the window system clipboard.

The clipboard offers a simple mechanism to copy and paste data between applications.

QClipboard supports the same data types that QDrag does, and uses similar mechanisms. For advanced clipboard usage read {Drag and Drop}.

There is a single QClipboard object in an application, accessible as QApplication::clipboard().

Example:

        QClipboard *clipboard = QApplication::clipboard();
        QString originalText = clipboard->text();
        ...
        clipboard->setText(newText);

QClipboard features some convenience functions to access common data types: setText() allows the exchange of Unicode text and setPixmap() and setImage() allows the exchange of QPixmaps and QImages between applications. The setMimeData() function is the ultimate in flexibility: it allows you to add any QMimeData into the clipboard. There are corresponding getters for each of these, e.g. text(), image() and pixmap(). You can clear the clipboard by calling clear().

\list \i The X11 Window System has the concept of a separate selection and clipboard. When text is selected, it is immediately available as the global mouse selection. The global mouse selection may later be copied to the clipboard. By convention, the middle mouse button is used to paste the global mouse selection. \i X11 also has the concept of ownership; if you change the selection within a window, X11 will only notify the owner and the previous owner of the change, i.e. it will not notify all applications that the selection or clipboard data changed. \i Lastly, the X11 clipboard is event driven, i.e. the clipboard will not function properly if the event loop is not running. Similarly, it is recommended that the contents of the clipboard are stored or retrieved in direct response to user-input events, e.g. mouse button or key presses and releases. You should not store or retrieve the clipboard contents in response to timer or non-user-input events. \endlist @section Notes for Mac OS X Users Mac OS X supports a separate find buffer that holds the current search string in Find operations. This find clipboard can be accessed by specifying the FindBuffer mode. @section Notes for Windows and Mac OS X Users \list \i Windows and Mac OS X do not support the global mouse selection; they only supports the global clipboard, i.e. they only add text to the clipboard when an explicit copy or cut is made. \i Windows and Mac OS X does not have the concept of ownership; the clipboard is a fully global resource so all applications are notified of changes. \endlist \sa QApplication Definition at line 42 of file qclipboard.h.

Public Types

enum  Mode

Signals

void changed (QClipboard::Mode mode)
void selectionChanged ()
void findBufferChanged ()
void dataChanged ()

Public Member Functions

void clear (Mode mode=Clipboard)
bool supportsSelection () const
bool supportsFindBuffer () const
bool ownsSelection () const
bool ownsClipboard () const
bool ownsFindBuffer () const
QString text (Mode mode=Clipboard) const
QString text (QString &subtype, Mode mode=Clipboard) const
void setText (const QString &, Mode mode=Clipboard)
const QMimeDatamimeData (Mode mode=Clipboard) const
void setMimeData (QMimeData *data, Mode mode=Clipboard)
QImage image (Mode mode=Clipboard) const
QPixmap pixmap (Mode mode=Clipboard) const
void setImage (const QImage &, Mode mode=Clipboard)
void setPixmap (const QPixmap &, Mode mode=Clipboard)

Protected Member Functions

void connectNotify (const char *)
bool event (QEvent *)

Private Slots

void ownerDestroyed ()

Private Member Functions

 QClipboard (QObject *parent)
 ~QClipboard ()
bool supportsMode (Mode mode) const
bool ownsMode (Mode mode) const
void emitChanged (Mode mode)

Friends

class QApplication
class QApplicationPrivate
class QBaseApplication
class QDragManager
class QMimeSource


Member Enumeration Documentation

enum QClipboard::Mode

clipboard mode

This enum type is used to control which part of the system clipboard is used by QClipboard::data(), QClipboard::setData() and related functions.

Clipboard indicates that data should be stored and retrieved from the global clipboard.

Selection indicates that data should be stored and retrieved from the global mouse selection. Support for Selection is provided only on systems with a global mouse selection (e.g. X11).

FindBuffer indicates that data should be stored and retrieved from the Find buffer. This mode is used for holding search strings on Mac OS X.

LastMode

See also:
QClipboard::supportsSelection()

Definition at line 51 of file qclipboard.h.

00051 { Clipboard, Selection, FindBuffer, LastMode = FindBuffer };


Constructor & Destructor Documentation

QClipboard::QClipboard ( QObject parent  )  [private]

Definition at line 132 of file qclipboard.cpp.

00133     : QObject(*new QClipboardPrivate, parent)
00134 {
00135     // nothing
00136 }

QClipboard::~QClipboard (  )  [private]

Definition at line 147 of file qclipboard.cpp.

00148 {
00149 }


Member Function Documentation

void QClipboard::clear ( Mode  mode = Clipboard  ) 

Clear the clipboard contents.

The mode argument is used to control which part of the system clipboard is used. If mode is QClipboard::Clipboard, this function clears the the global clipboard contents. If mode is QClipboard::Selection, this function clears the global mouse selection contents. If mode is QClipboard::FindBuffer, this function clears the search string buffer.

See also:
QClipboard::Mode, supportsSelection()

Definition at line 322 of file qclipboard_x11.cpp.

References setMimeData().

00323 {
00324     setMimeData(0, mode);
00325 }

Here is the call graph for this function:

bool QClipboard::supportsSelection (  )  const

Returns true if the clipboard supports mouse selection; otherwise returns false.

Definition at line 484 of file qclipboard.cpp.

References Selection, and supportsMode().

Referenced by QTextControlPrivate::setClipboardSelection().

00485 {
00486     return supportsMode(Selection);
00487 }

Here is the call graph for this function:

bool QClipboard::supportsFindBuffer (  )  const

Returns true if the clipboard supports a separate search buffer; otherwise returns false.

Definition at line 493 of file qclipboard.cpp.

References FindBuffer, and supportsMode().

00494 {
00495     return supportsMode(FindBuffer);
00496 }

Here is the call graph for this function:

bool QClipboard::ownsSelection (  )  const

Returns true if this clipboard object owns the mouse selection data; otherwise returns false.

Definition at line 511 of file qclipboard.cpp.

References ownsMode(), and Selection.

00512 {
00513     return ownsMode(Selection);
00514 }

Here is the call graph for this function:

bool QClipboard::ownsClipboard (  )  const

Returns true if this clipboard object owns the clipboard data; otherwise returns false.

Definition at line 502 of file qclipboard.cpp.

References Clipboard, and ownsMode().

00503 {
00504     return ownsMode(Clipboard);
00505 }

Here is the call graph for this function:

bool QClipboard::ownsFindBuffer (  )  const

Since:
4.2
Returns true if this clipboard object owns the find buffer data; otherwise returns false.

Definition at line 522 of file qclipboard.cpp.

References FindBuffer, and ownsMode().

00523 {
00524     return ownsMode(FindBuffer);
00525 }

Here is the call graph for this function:

QString QClipboard::text ( Mode  mode = Clipboard  )  const

Returns the clipboard text as plain text, or an empty string if the clipboard does not contain any text.

The mode argument is used to control which part of the system clipboard is used. If mode is QClipboard::Clipboard, the text is retrieved from the global clipboard. If mode is QClipboard::Selection, the text is retrieved from the global mouse selection. If mode is QClipboard::FindBuffer, the text is retrieved from the search string buffer.

See also:
setText(), data()

Definition at line 274 of file qclipboard.cpp.

References data, and mimeData().

Referenced by QLineEdit::createStandardContextMenu(), and setText().

00275 {
00276     const QMimeData *data = mimeData(mode);
00277     return data ? data->text() : QString();
00278 }

Here is the call graph for this function:

QString QClipboard::text ( QString subtype,
Mode  mode = Clipboard 
) const

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. Returns the clipboard text in subtype subtype, or an empty string if the clipboard does not contain any text. If subtype is null, any subtype is acceptable, and subtype is set to the chosen subtype.

The mode argument is used to control which part of the system clipboard is used. If mode is QClipboard::Clipboard, the text is retrieved from the global clipboard. If mode is QClipboard::Selection, the text is retrieved from the global mouse selection.

Common values for subtype are "plain" and "html".

See also:
setText(), data()

Definition at line 237 of file qclipboard.cpp.

References QString::at(), data, QString::fromUtf8(), i, QString::isEmpty(), and mimeData().

00238 {
00239     const QMimeData *data = mimeData(mode);
00240     if (!data)
00241         return QString();
00242     if (subtype.isEmpty()) {
00243         QStringList formats = data->formats();
00244         if (formats.contains(QLatin1String("text/plain")))
00245             subtype = QLatin1String("plain");
00246         else {
00247             for (int i = 0; i < formats.size(); ++i)
00248                 if (formats.at(i).startsWith(QLatin1String("text/"))) {
00249                     subtype = formats.at(i).mid(5);
00250                     break;
00251                 }
00252         }
00253     }
00254     if (subtype.isEmpty())
00255         return QString();
00256     if (subtype == QLatin1String("plain"))
00257         return data->text();
00258     return QString::fromUtf8(data->data(QLatin1String("text/") + subtype));
00259 }

Here is the call graph for this function:

void QClipboard::setText ( const QString text,
Mode  mode = Clipboard 
)

Copies text into the clipboard as plain text.

The mode argument is used to control which part of the system clipboard is used. If mode is QClipboard::Clipboard, the text is stored in the global clipboard. If mode is QClipboard::Selection, the text is stored in the global mouse selection. If mode is QClipboard::FindBuffer, the text is stored in the search string buffer.

See also:
text(), setData()

Definition at line 292 of file qclipboard.cpp.

References data, setMimeData(), and text().

Referenced by Q3TextEdit::copy(), QLineEditPrivate::copy(), SourceTextEdit::copySelection(), QAbstractItemView::keyPressEvent(), and MainWindow::updateClipboard().

00293 {
00294     QMimeData *data = new QMimeData;
00295     data->setText(text);
00296     setMimeData(data, mode);
00297 }

Here is the call graph for this function:

const QMimeData * QClipboard::mimeData ( Mode  mode = Clipboard  )  const

Returns a reference to a QMimeData representation of the current clipboard data.

The mode argument is used to control which part of the system clipboard is used. If mode is QClipboard::Clipboard, the data is retrieved from the global clipboard. If mode is QClipboard::Selection, the data is retrieved from the global mouse selection. If mode is QClipboard::FindBuffer, the data is retrieved from the search string buffer.

The text(), image(), and pixmap() functions are simpler wrappers for retrieving text, image, and pixmap data.

See also:
setMimeData()

Definition at line 1112 of file qclipboard_x11.cpp.

References Clipboard, clipboard_watcher, clipboardData(), d, qWarning(), Selection, selection_watcher, selectionData(), QObject::startTimer(), timer_event_clear, and timer_id.

Referenced by QTextControl::canPaste(), image(), QTextControlPrivate::mouseReleaseEvent(), QTextControl::paste(), pixmap(), and text().

01113 {
01114     QClipboardData *d = 0;
01115     switch (mode) {
01116     case Selection:
01117         d = selectionData();
01118         break;
01119     case Clipboard:
01120         d = clipboardData();
01121         break;
01122     default:
01123         qWarning("QClipboard::mimeData: unsupported mode '%d'", mode);
01124         return 0;
01125     }
01126 
01127     if (! d->source() && ! timer_event_clear) {
01128         if (mode == Selection) {
01129             if (! selection_watcher)
01130                 selection_watcher = new QClipboardWatcher(mode);
01131             d->setSource(selection_watcher);
01132         } else {
01133             if (! clipboard_watcher)
01134                 clipboard_watcher = new QClipboardWatcher(mode);
01135             d->setSource(clipboard_watcher);
01136         }
01137 
01138         if (! timer_id) {
01139             // start a zero timer - we will clear cached data when the timer
01140             // times out, which will be the next time we hit the event loop...
01141             // that way, the data is cached long enough for calls within a single
01142             // loop/function, but the data doesn't linger around in case the selection
01143             // changes
01144             QClipboard *that = ((QClipboard *) this);
01145             timer_id = that->startTimer(0);
01146         }
01147     }
01148 
01149     return d->source();
01150 }

Here is the call graph for this function:

void QClipboard::setMimeData ( QMimeData src,
Mode  mode = Clipboard 
)

Sets the clipboard data to src. Ownership of the data is transferred to the clipboard. If you want to remove the data either call clear() or call setData() again with new data.

The mode argument is used to control which part of the system clipboard is used. If mode is QClipboard::Clipboard, the data is stored in the global clipboard. If mode is QClipboard::Selection, the data is stored in the global mouse selection. If mode is QClipboard::FindBuffer, the data is stored in the search string buffer.

The setText(), setImage() and setPixmap() functions are simpler wrappers for setting text, image and pixmap data respectively.

See also:
data()

Definition at line 1153 of file qclipboard_x11.cpp.

References ATOM, Clipboard, clipboardData(), d, QApplication::desktop(), emitChanged(), QWidget::internalWinId(), owner, qWarning(), Selection, selectionData(), setupOwner(), X11, and XNone.

Referenced by QTextControlPrivate::_q_copyLink(), clear(), QTextControl::copy(), QTextControlPrivate::setClipboardSelection(), setImage(), setPixmap(), and setText().

01154 {
01155     Atom atom, sentinel_atom;
01156     QClipboardData *d;
01157     switch (mode) {
01158     case Selection:
01159         atom = XA_PRIMARY;
01160         sentinel_atom = ATOM(_QT_SELECTION_SENTINEL);
01161         d = selectionData();
01162         break;
01163 
01164     case Clipboard:
01165         atom = ATOM(CLIPBOARD);
01166         sentinel_atom = ATOM(_QT_CLIPBOARD_SENTINEL);
01167         d = clipboardData();
01168         break;
01169 
01170     default:
01171         qWarning("QClipboard::setMimeData: unsupported mode '%d'", mode);
01172         return;
01173     }
01174 
01175     Display *dpy = X11->display;
01176     Window newOwner;
01177 
01178     if (! src) { // no data, clear clipboard contents
01179         newOwner = XNone;
01180         d->clear();
01181     } else {
01182         setupOwner();
01183 
01184         newOwner = owner->internalWinId();
01185 
01186         d->setSource(src);
01187         d->timestamp = X11->time;
01188     }
01189 
01190     Window prevOwner = XGetSelectionOwner(dpy, atom);
01191     // use X11->time, since d->timestamp == CurrentTime when clearing
01192     XSetSelectionOwner(dpy, atom, newOwner, X11->time);
01193 
01194     if (mode == Selection)
01195         emitChanged(QClipboard::Selection);
01196     else
01197         emitChanged(QClipboard::Clipboard);
01198 
01199     if (XGetSelectionOwner(dpy, atom) != newOwner) {
01200         qWarning("QClipboard::setData: Cannot set X11 selection owner for %s",
01201                  X11->xdndAtomToString(atom).data());
01202         d->clear();
01203         return;
01204     }
01205 
01206     // Signal to other Qt processes that the selection has changed
01207     Window owners[2];
01208     owners[0] = newOwner;
01209     owners[1] = prevOwner;
01210     XChangeProperty(dpy, QApplication::desktop()->screen(0)->internalWinId(),
01211                      sentinel_atom, XA_WINDOW, 32, PropModeReplace,
01212                      (unsigned char*)&owners, 2);
01213 }

Here is the call graph for this function:

QImage QClipboard::image ( Mode  mode = Clipboard  )  const

Returns the clipboard image, or returns a null image if the clipboard does not contain an image or if it contains an image in an unsupported image format.

The mode argument is used to control which part of the system clipboard is used. If mode is QClipboard::Clipboard, the image is retrieved from the global clipboard. If mode is QClipboard::Selection, the image is retrieved from the global mouse selection.

See also:
setImage() pixmap() data(), QImage::isNull()

Definition at line 312 of file qclipboard.cpp.

References data, and mimeData().

Referenced by setImage().

00313 {
00314     const QMimeData *data = mimeData(mode);
00315     if (!data)
00316         return QImage();
00317     return qvariant_cast<QImage>(data->imageData());
00318 }

Here is the call graph for this function:

QPixmap QClipboard::pixmap ( Mode  mode = Clipboard  )  const

Returns the clipboard pixmap, or null if the clipboard does not contain a pixmap. Note that this can lose information. For example, if the image is 24-bit and the display is 8-bit, the result is converted to 8 bits, and if the image has an alpha channel, the result just has a mask.

The mode argument is used to control which part of the system clipboard is used. If mode is QClipboard::Clipboard, the pixmap is retrieved from the global clipboard. If mode is QClipboard::Selection, the pixmap is retrieved from the global mouse selection.

See also:
setPixmap() image() data() QPixmap::convertFromImage()

Definition at line 361 of file qclipboard.cpp.

References data, and mimeData().

Referenced by setPixmap().

00362 {
00363     const QMimeData *data = mimeData(mode);
00364     return data ? qvariant_cast<QPixmap>(data->imageData()) : QPixmap();
00365 }

Here is the call graph for this function:

void QClipboard::setImage ( const QImage image,
Mode  mode = Clipboard 
)

Copies the image into the clipboard.

The mode argument is used to control which part of the system clipboard is used. If mode is QClipboard::Clipboard, the image is stored in the global clipboard. If mode is QClipboard::Selection, the data is stored in the global mouse selection.

This is shorthand for:

        QMimeData *data = new QMimeData;
        data->setImageData(image);
        clipboard->setMimeData(data, mode);

See also:
image(), setPixmap() setData()

Definition at line 339 of file qclipboard.cpp.

References data, image(), and setMimeData().

00340 {
00341     QMimeData *data = new QMimeData;
00342     data->setImageData(image);
00343     setMimeData(data, mode);
00344 }

Here is the call graph for this function:

void QClipboard::setPixmap ( const QPixmap pixmap,
Mode  mode = Clipboard 
)

Copies pixmap into the clipboard. Note that this is slower than setImage() because it needs to convert the QPixmap to a QImage first.

The mode argument is used to control which part of the system clipboard is used. If mode is QClipboard::Clipboard, the pixmap is stored in the global clipboard. If mode is QClipboard::Selection, the pixmap is stored in the global mouse selection.

See also:
pixmap() setImage() setData()

Definition at line 380 of file qclipboard.cpp.

References data, pixmap(), and setMimeData().

Referenced by QPixelTool::copyToClipboard().

00381 {
00382     QMimeData *data = new QMimeData;
00383     data->setImageData(pixmap);
00384     setMimeData(data, mode);
00385 }

Here is the call graph for this function:

void QClipboard::changed ( QClipboard::Mode  mode  )  [signal]

Since:
4.2
This signal is emitted when the data for the given clipboard mode is changed.

See also:
dataChanged(), selectionChanged(), findBufferChanged()

Referenced by emitChanged().

void QClipboard::selectionChanged (  )  [signal]

This signal is emitted when the selection is changed. This only applies to windowing systems that support selections, e.g. X11. Windows and Mac OS X don't support selections.

See also:
dataChanged(), findBufferChanged(), changed()

Referenced by emitChanged().

void QClipboard::findBufferChanged (  )  [signal]

Since:
4.2
This signal is emitted when the find buffer is changed. This only applies to Mac OS X.

See also:
dataChanged(), selectionChanged(), changed()

Referenced by emitChanged().

void QClipboard::dataChanged (  )  [signal]

This signal is emitted when the clipboard data is changed.

See also:
findBufferChanged(), selectionChanged(), changed()

Referenced by emitChanged().

void QClipboard::ownerDestroyed (  )  [private, slot]

Definition at line 681 of file qclipboard_x11.cpp.

00682 { }

void QClipboard::connectNotify ( const char *   )  [protected, virtual]

This virtual function is called when something has been connected to signal in this object.

If you want to compare signal with a specific signal, use QLatin1String and the SIGNAL() macro as follows:

        if (QLatin1String(signal) == SIGNAL(valueChanged(int))) {
            // signal is valueChanged(int)
        }

If the signal contains multiple parameters or parameters that contain spaces, call QMetaObject::normalizedSignature() on the result of the SIGNAL() macro.

Warning:
This function violates the object-oriented principle of modularity. However, it might be useful when you need to perform expensive initialization only if something is connected to a signal.
See also:
connect(), disconnectNotify()

Reimplemented from QObject.

Definition at line 688 of file qclipboard_x11.cpp.

00689 { }

bool QClipboard::event ( QEvent e  )  [protected, virtual]

Reimplemented from QObject.

Definition at line 694 of file qclipboard_x11.cpp.

References ATOM, QClipboardData::clear(), QApplication::clipboard(), Clipboard, QEvent::Clipboard, clipboard_watcher, clipboardData(), d, data, QByteArray::data(), DEBUG, emitChanged(), QObject::event(), incr_timer_id, QWidget::internalWinId(), QObject::killTimer(), pending_clipboard_changed, pending_selection_changed, pending_timer_id, QObject::property(), qt_xclb_incr_timeout(), qWarning(), requestor, Selection, selection_watcher, selectionData(), send_selection(), send_targets_selection(), QByteArray::size(), QObject::startTimer(), QEvent::Timer, timer_event_clear, timer_id, QEvent::type(), waiting_for_data, X11, and XNone.

00695 {
00696     if (e->type() == QEvent::Timer) {
00697         QTimerEvent *te = (QTimerEvent *) e;
00698 
00699         if (waiting_for_data) // should never happen
00700             return false;
00701 
00702         if (te->timerId() == timer_id) {
00703             killTimer(timer_id);
00704             timer_id = 0;
00705 
00706             timer_event_clear = true;
00707             if (selection_watcher) // clear selection
00708                 selectionData()->clear();
00709             if (clipboard_watcher) // clear clipboard
00710                 clipboardData()->clear();
00711             timer_event_clear = false;
00712 
00713             return true;
00714         } else if (te->timerId() == pending_timer_id) {
00715             // I hate klipper
00716             killTimer(pending_timer_id);
00717             pending_timer_id = 0;
00718 
00719             if (pending_clipboard_changed) {
00720                 pending_clipboard_changed = false;
00721                 clipboardData()->clear();
00722                 emitChanged(QClipboard::Clipboard);
00723             }
00724             if (pending_selection_changed) {
00725                 pending_selection_changed = false;
00726                 selectionData()->clear();
00727                 emitChanged(QClipboard::Selection);
00728             }
00729 
00730             return true;
00731         } else if (te->timerId() == incr_timer_id) {
00732             killTimer(incr_timer_id);
00733             incr_timer_id = 0;
00734 
00735             qt_xclb_incr_timeout();
00736 
00737             return true;
00738         } else {
00739             return QObject::event(e);
00740         }
00741     } else if (e->type() != QEvent::Clipboard) {
00742         return QObject::event(e);
00743     }
00744 
00745     XEvent *xevent = (XEvent *)(((QClipboardEvent *)e)->data());
00746     Display *dpy = X11->display;
00747 
00748     if (!xevent)
00749         return true;
00750 
00751     switch (xevent->type) {
00752 
00753     case SelectionClear:
00754         // new selection owner
00755         if (xevent->xselectionclear.selection == XA_PRIMARY) {
00756             QClipboardData *d = selectionData();
00757 
00758             // ignore the event if it was generated before we gained selection ownership
00759             if (d->timestamp != CurrentTime && xevent->xselectionclear.time < d->timestamp)
00760                 break;
00761 
00762             DEBUG("QClipboard: new selection owner 0x%lx at time %lx (ours %lx)",
00763                   XGetSelectionOwner(dpy, XA_PRIMARY),
00764                   xevent->xselectionclear.time, d->timestamp);
00765 
00766             if (! waiting_for_data) {
00767                 d->clear();
00768                 emitChanged(QClipboard::Selection);
00769             } else {
00770                 pending_selection_changed = true;
00771                 if (! pending_timer_id)
00772                     pending_timer_id = QApplication::clipboard()->startTimer(0);
00773             }
00774         } else if (xevent->xselectionclear.selection == ATOM(CLIPBOARD)) {
00775             QClipboardData *d = clipboardData();
00776 
00777             // ignore the event if it was generated before we gained selection ownership
00778             if (d->timestamp != CurrentTime && xevent->xselectionclear.time < d->timestamp)
00779                 break;
00780 
00781             DEBUG("QClipboard: new clipboard owner 0x%lx at time %lx (%lx)",
00782                   XGetSelectionOwner(dpy, ATOM(CLIPBOARD)),
00783                   xevent->xselectionclear.time, d->timestamp);
00784 
00785             if (! waiting_for_data) {
00786                 d->clear();
00787                 emitChanged(QClipboard::Clipboard);
00788             } else {
00789                 pending_clipboard_changed = true;
00790                 if (! pending_timer_id)
00791                     pending_timer_id = QApplication::clipboard()->startTimer(0);
00792             }
00793         } else {
00794             qWarning("QClipboard: Unknown SelectionClear event received");
00795             return false;
00796         }
00797         break;
00798 
00799     case SelectionNotify:
00800         /*
00801           Something has delivered data to us, but this was not caught
00802           by QClipboardWatcher::getDataInFormat()
00803 
00804           Just skip the event to prevent Bad Things (tm) from
00805           happening later on...
00806         */
00807         break;
00808 
00809     case SelectionRequest:
00810         {
00811             // someone wants our data
00812             XSelectionRequestEvent *req = &xevent->xselectionrequest;
00813 
00814             if (requestor && req->requestor == requestor->internalWinId())
00815                 break;
00816 
00817             XEvent event;
00818             event.xselection.type      = SelectionNotify;
00819             event.xselection.display   = req->display;
00820             event.xselection.requestor = req->requestor;
00821             event.xselection.selection = req->selection;
00822             event.xselection.target    = req->target;
00823             event.xselection.property  = XNone;
00824             event.xselection.time      = req->time;
00825 
00826             DEBUG("QClipboard: SelectionRequest from %lx\n"
00827                   "    selection 0x%lx (%s) target 0x%lx (%s)",
00828                   req->requestor,
00829                   req->selection,
00830                   X11->xdndAtomToString(req->selection).data(),
00831                   req->target,
00832                   X11->xdndAtomToString(req->target).data());
00833 
00834             QClipboardData *d;
00835             if (req->selection == XA_PRIMARY) {
00836                 d = selectionData();
00837             } else if (req->selection == ATOM(CLIPBOARD)) {
00838                 d = clipboardData();
00839             } else {
00840                 qWarning("QClipboard: Unknown selection '%lx'", req->selection);
00841                 XSendEvent(dpy, req->requestor, False, NoEventMask, &event);
00842                 break;
00843             }
00844 
00845             if (! d->source()) {
00846                 qWarning("QClipboard: Cannot transfer data, no data available");
00847                 XSendEvent(dpy, req->requestor, False, NoEventMask, &event);
00848                 break;
00849             }
00850 
00851             DEBUG("QClipboard: SelectionRequest at time %lx (ours %lx)",
00852                   req->time, d->timestamp);
00853 
00854             if (d->timestamp == CurrentTime // we don't own the selection anymore
00855                 || (req->time != CurrentTime && req->time < d->timestamp)) {
00856                 DEBUG("QClipboard: SelectionRequest too old");
00857                 XSendEvent(dpy, req->requestor, False, NoEventMask, &event);
00858                 break;
00859             }
00860 
00861             Atom xa_targets = ATOM(TARGETS);
00862             Atom xa_multiple = ATOM(MULTIPLE);
00863             Atom xa_timestamp = ATOM(TIMESTAMP);
00864 
00865             struct AtomPair { Atom target; Atom property; } *multi = 0;
00866             Atom multi_type = XNone;
00867             int multi_format = 0;
00868             int nmulti = 0;
00869             int imulti = -1;
00870             bool multi_writeback = false;
00871 
00872             if (req->target == xa_multiple) {
00873                 QByteArray multi_data;
00874                 if (req->property == XNone
00875                     || !X11->clipboardReadProperty(req->requestor, req->property, false, &multi_data,
00876                                                    0, &multi_type, &multi_format, 0)
00877                     || multi_format != 32) {
00878                     // MULTIPLE property not formatted correctly
00879                     XSendEvent(dpy, req->requestor, False, NoEventMask, &event);
00880                     break;
00881                 }
00882                 nmulti = multi_data.size()/sizeof(*multi);
00883                 multi = new AtomPair[nmulti];
00884                 memcpy(multi,multi_data.data(),multi_data.size());
00885                 imulti = 0;
00886             }
00887 
00888             for (; imulti < nmulti; ++imulti) {
00889                 Atom target;
00890                 Atom property;
00891 
00892                 if (multi) {
00893                     target = multi[imulti].target;
00894                     property = multi[imulti].property;
00895                 } else {
00896                     target = req->target;
00897                     property = req->property;
00898                     if (property == XNone) // obsolete client
00899                         property = target;
00900                 }
00901 
00902                 Atom ret = XNone;
00903                 if (target == XNone || property == XNone) {
00904                     ;
00905                 } else if (target == xa_timestamp) {
00906                     if (d->timestamp != CurrentTime) {
00907                         XChangeProperty(dpy, req->requestor, property, xa_timestamp, 32,
00908                                         PropModeReplace, (uchar *) &d->timestamp, 1);
00909                         ret = property;
00910                     } else {
00911                         qWarning("QClipboard: Invalid data timestamp");
00912                     }
00913                 } else if (target == xa_targets) {
00914                     ret = send_targets_selection(d, req->requestor, property);
00915                 } else {
00916                     ret = send_selection(d, target, req->requestor, property);
00917                 }
00918 
00919                 if (nmulti > 0) {
00920                     if (ret == XNone) {
00921                         multi[imulti].property = XNone;
00922                         multi_writeback = true;
00923                     }
00924                 } else {
00925                     event.xselection.property = ret;
00926                     break;
00927                 }
00928             }
00929 
00930             if (nmulti > 0) {
00931                 if (multi_writeback) {
00932                     // according to ICCCM 2.6.2 says to put None back
00933                     // into the original property on the requestor window
00934                     XChangeProperty(dpy, req->requestor, req->property, multi_type, 32,
00935                                     PropModeReplace, (uchar *) multi, nmulti * 2);
00936                 }
00937 
00938                 delete [] multi;
00939                 event.xselection.property = req->property;
00940             }
00941 
00942             // send selection notify to requestor
00943             XSendEvent(dpy, req->requestor, False, NoEventMask, &event);
00944 
00945             DEBUG("QClipboard: SelectionNotify to 0x%lx\n"
00946                   "    property 0x%lx (%s)",
00947                   req->requestor, event.xselection.property,
00948                   X11->xdndAtomToString(event.xselection.property).data());
00949         }
00950         break;
00951     }
00952 
00953     return true;
00954 }

Here is the call graph for this function:

bool QClipboard::supportsMode ( Mode  mode  )  const [private]

Definition at line 328 of file qclipboard_x11.cpp.

References Clipboard, and Selection.

Referenced by supportsFindBuffer(), and supportsSelection().

00329 {
00330     return (mode == Clipboard || mode == Selection);
00331 }

bool QClipboard::ownsMode ( Mode  mode  )  const [private]

Definition at line 333 of file qclipboard_x11.cpp.

References Clipboard, clipboardData(), Selection, selectionData(), and QClipboardData::timestamp.

Referenced by ownsClipboard(), ownsFindBuffer(), and ownsSelection().

00334 {
00335     if (mode == Clipboard)
00336         return clipboardData()->timestamp != CurrentTime;
00337     else if(mode == Selection)
00338         return selectionData()->timestamp != CurrentTime;
00339     else
00340         return false;
00341 }

Here is the call graph for this function:

void QClipboard::emitChanged ( Mode  mode  )  [private]

Definition at line 542 of file qclipboard.cpp.

References changed(), Clipboard, dataChanged(), emit, FindBuffer, findBufferChanged(), Selection, and selectionChanged().

Referenced by event(), and setMimeData().

00543 {
00544     switch (mode) {
00545         case Clipboard:
00546             emit dataChanged();
00547         break;
00548         case Selection:
00549             emit selectionChanged();
00550         break;
00551         case FindBuffer:
00552             emit findBufferChanged();
00553         break;
00554         default:
00555         break;
00556         emit changed(mode);
00557     }
00558 }


Friends And Related Function Documentation

friend class QApplication [friend]

Reimplemented from QObject.

Definition at line 90 of file qclipboard.h.

friend class QApplicationPrivate [friend]

Reimplemented from QObject.

Definition at line 91 of file qclipboard.h.

friend class QBaseApplication [friend]

Definition at line 92 of file qclipboard.h.

friend class QDragManager [friend]

Definition at line 93 of file qclipboard.h.

friend class QMimeSource [friend]

Definition at line 94 of file qclipboard.h.


The documentation for this class was generated from the following files:
Generated on Thu Mar 15 16:59:50 2007 for Qt 4.2 User's Guide by  doxygen 1.5.1